diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..c8fa860 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,43 @@ +name: Deploy + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: pages-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + # package-lock.json is not committed, so "npm ci" is not an option + - run: npm install + - run: npm run build + - uses: actions/upload-pages-artifact@v3 + with: + path: dist + + deploy: + if: github.event_name != 'pull_request' + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index d94d676..5967f37 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,10 @@ Building static files into `dist/`: npm run build ``` -Copy manually to `docs/` and perform git push to deploy, +# Deployment + +Pushing to `main` builds the site and deploys it to GitHub Pages with the +[Deploy workflow](.github/workflows/deploy.yml). # License diff --git a/docs/.nojekyll b/docs/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 7e1e67d..0000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -install.tactilityproject.org diff --git a/docs/assets/images/favicon.svg b/docs/assets/images/favicon.svg deleted file mode 100644 index 8b6881e..0000000 --- a/docs/assets/images/favicon.svg +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/assets/images/toolbar-logo.svg b/docs/assets/images/toolbar-logo.svg deleted file mode 100644 index 60299eb..0000000 --- a/docs/assets/images/toolbar-logo.svg +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/bundle.js b/docs/bundle.js deleted file mode 100644 index a4f19f1..0000000 --- a/docs/bundle.js +++ /dev/null @@ -1,1779 +0,0 @@ -/******/ (() => { // webpackBootstrap -/******/ "use strict"; -/******/ var __webpack_modules__ = ({ - -/***/ "./assets/images/favicon.svg": -/*!***********************************!*\ - !*** ./assets/images/favicon.svg ***! - \***********************************/ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = __webpack_require__.p + "assets/images/favicon.svg"; - -/***/ }), - -/***/ "./assets/images/toolbar-logo.svg": -/*!****************************************!*\ - !*** ./assets/images/toolbar-logo.svg ***! - \****************************************/ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -module.exports = __webpack_require__.p + "assets/images/toolbar-logo.svg"; - -/***/ }), - -/***/ "./node_modules/css-loader/dist/cjs.js!./src/app.css": -/*!***********************************************************!*\ - !*** ./node_modules/css-loader/dist/cjs.js!./src/app.css ***! - \***********************************************************/ -/***/ ((module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/sourceMaps.js */ "./node_modules/css-loader/dist/runtime/sourceMaps.js"); -/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js"); -/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); -// Imports - - -var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); -// Module -___CSS_LOADER_EXPORT___.push([module.id, `:root { - color-scheme: dark; - --bg: #17181f; - --surface: #21222b; - --surface-raised: #2a2c37; - --border: #363846; - --text: #e8e9f0; - --text-muted: #9a9db0; - --primary: #33bbff; - --primary-contrast: #06202e; - --primary-soft: rgba(51, 187, 255, 0.14); - --secondary: #ee81c3; - --warning: #f5b84a; - --warning-soft: rgba(245, 184, 74, 0.13); - --radius: 14px; - --radius-small: 9px; - --shadow: 0 12px 32px rgba(0, 0, 0, 0.28); -} - -@media (prefers-color-scheme: light) { - :root { - color-scheme: light; - --bg: #f3f4f8; - --surface: #ffffff; - --surface-raised: #f0f1f6; - --border: #dcdee8; - --text: #1c1d26; - --text-muted: #62657a; - --primary: #0b84c6; - --primary-contrast: #ffffff; - --primary-soft: rgba(11, 132, 198, 0.11); - --secondary: #c2408f; - --warning: #a86a00; - --warning-soft: rgba(214, 144, 16, 0.14); - --shadow: 0 10px 28px rgba(30, 34, 60, 0.08); - } -} - -*, *::before, *::after { - box-sizing: border-box; -} - -body { - margin: 0; - background: var(--bg); - color: var(--text); - font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; - font-size: 16px; - line-height: 1.5; - -webkit-font-smoothing: antialiased; -} - -a { - color: var(--primary); - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -button, input { - font: inherit; - color: inherit; -} - -:focus-visible { - outline: 2px solid var(--primary); - outline-offset: 2px; -} - -[hidden] { - display: none !important; -} - -/* Top bar */ - -.topbar { - border-bottom: 1px solid var(--border); - background: var(--surface); -} - -.topbar-inner { - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; - max-width: 1080px; - margin: 0 auto; - padding: 12px 20px; -} - -.brand { - display: flex; - align-items: center; - gap: 10px; - color: var(--text); - font-weight: 650; - font-size: 1.1rem; -} - -.brand:hover { - text-decoration: none; -} - -.brand-sub { - color: var(--text-muted); - font-weight: 400; -} - -.topbar-links { - display: flex; - gap: 20px; - font-size: 0.92rem; -} - -.topbar-links a { - color: var(--text-muted); -} - -.topbar-links a:hover { - color: var(--text); - text-decoration: none; -} - -/* Page */ - -main { - max-width: 1080px; - margin: 0 auto; - padding: 36px 20px 64px; -} - -.intro { - margin-bottom: 28px; -} - -.intro h1 { - margin: 0 0 6px; - font-size: clamp(1.6rem, 3.5vw, 2.1rem); - line-height: 1.2; - letter-spacing: -0.02em; -} - -.intro p { - margin: 0; - color: var(--text-muted); -} - -.layout { - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); - gap: 20px; - align-items: start; -} - -.card { - background: var(--surface); - border: 1px solid var(--border); - border-radius: var(--radius); - box-shadow: var(--shadow); - padding: 22px; -} - -#Details { - position: sticky; - top: 20px; -} - -.card h2 { - display: flex; - align-items: center; - gap: 10px; - margin: 0 0 18px; - font-size: 1.05rem; - font-weight: 600; -} - -.step { - display: inline-grid; - place-items: center; - width: 26px; - height: 26px; - border-radius: 50%; - background: var(--primary-soft); - color: var(--primary); - font-size: 0.85rem; - font-weight: 700; -} - -/* Search */ - -.search { - position: relative; -} - -.search svg { - position: absolute; - top: 50%; - left: 13px; - width: 18px; - height: 18px; - transform: translateY(-50%); - fill: none; - stroke: var(--text-muted); - stroke-width: 2; - stroke-linecap: round; - pointer-events: none; -} - -.search input { - width: 100%; - padding: 11px 14px 11px 40px; - background: var(--surface-raised); - border: 1px solid var(--border); - border-radius: var(--radius-small); -} - -.search input::placeholder { - color: var(--text-muted); -} - -.search input:focus { - outline: none; - border-color: var(--primary); - box-shadow: 0 0 0 3px var(--primary-soft); -} - -.list-status { - margin: 12px 2px 8px; - color: var(--text-muted); - font-size: 0.85rem; -} - -/* Device list */ - -.device-list { - display: flex; - flex-direction: column; - gap: 2px; - max-height: min(56vh, 520px); - margin: 0 -8px; - padding: 0 8px; - overflow-y: auto; - list-style: none; - scrollbar-width: thin; - scrollbar-color: var(--border) transparent; -} - -.device { - display: flex; - align-items: center; - gap: 8px; - width: 100%; - padding: 6px 12px; - background: none; - border: 1px solid transparent; - border-radius: var(--radius-small); - text-align: left; - cursor: pointer; -} - -.device:hover { - background: var(--surface-raised); -} - -.device[aria-pressed="true"] { - background: var(--primary-soft); - border-color: var(--primary); -} - -.device-text { - display: flex; - flex-direction: column; - flex: 1; - min-width: 0; -} - -.device-vendor { - color: var(--text-muted); - font-size: 0.76rem; - line-height: 1.3; -} - -.device-name { - font-weight: 500; - overflow-wrap: anywhere; -} - -.badge { - flex-shrink: 0; - padding: 2px 8px; - border-radius: 999px; - font-size: 0.7rem; - font-weight: 600; - white-space: nowrap; -} - -.badge-accent { - background: color-mix(in srgb, var(--secondary) 16%, transparent); - color: var(--secondary); -} - -.badge-muted { - background: var(--surface-raised); - color: var(--text-muted); -} - -.badge-warning { - background: var(--warning-soft); - color: var(--warning); -} - -/* Details */ - -.empty { - margin: 0; - padding: 36px 0; - color: var(--text-muted); - text-align: center; -} - -.selected-device { - margin-bottom: 18px; -} - -.selected-vendor { - color: var(--text-muted); - font-size: 0.85rem; -} - -.selected-name { - font-size: 1.35rem; - font-weight: 650; - line-height: 1.25; - letter-spacing: -0.01em; -} - -.segmented { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 4px; - padding: 4px; - background: var(--surface-raised); - border: 1px solid var(--border); - border-radius: var(--radius-small); -} - -.segment { - position: relative; - cursor: pointer; -} - -.segment input { - position: absolute; - inset: 0; - margin: 0; - opacity: 0; - cursor: inherit; -} - -.segment-body { - display: flex; - flex-direction: column; - align-items: center; - padding: 7px 10px; - border-radius: 6px; -} - -.segment-title { - font-weight: 600; -} - -.segment-sub { - color: var(--text-muted); - font-size: 0.78rem; -} - -.segment input:checked + .segment-body { - background: var(--surface); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25), inset 0 0 0 1px var(--primary); -} - -.segment input:checked + .segment-body .segment-title { - color: var(--primary); -} - -.segment input:focus-visible + .segment-body { - outline: 2px solid var(--primary); - outline-offset: 2px; -} - -.segment:has(input:disabled) { - cursor: not-allowed; - opacity: 0.45; -} - -.build-details { - min-height: 1.3em; - margin: 10px 2px 16px; - color: var(--text-muted); - font-size: 0.82rem; -} - -/* Notices */ - -.notice { - margin-bottom: 12px; - padding: 12px 14px; - border-left: 3px solid var(--primary); - border-radius: var(--radius-small); - background: var(--primary-soft); - font-size: 0.92rem; -} - -.notice-warning { - border-left-color: var(--warning); - background: var(--warning-soft); -} - -main > .notice { - margin-bottom: 20px; -} - -/* Buttons */ - -esp-web-install-button { - display: block; - margin-top: 18px; -} - -.button-primary { - width: 100%; - padding: 12px 20px; - background: var(--primary); - border: 0; - border-radius: var(--radius-small); - color: var(--primary-contrast); - font-weight: 650; - cursor: pointer; - transition: filter 0.15s, transform 0.05s; -} - -.button-primary:hover { - filter: brightness(1.08); -} - -.button-primary:active { - transform: translateY(1px); -} - -.button-link { - padding: 0; - background: none; - border: 0; - color: var(--primary); - cursor: pointer; -} - -.button-link:hover { - text-decoration: underline; -} - -.install-fallback { - display: block; - color: var(--text-muted); - font-size: 0.92rem; - text-align: center; -} - -@media (max-width: 820px) { - .layout { - grid-template-columns: minmax(0, 1fr); - } - - #Details { - position: static; - } - - .device-list { - max-height: 44vh; - } - - .topbar-links a:first-child { - display: none; - } -} -`, "",{"version":3,"sources":["webpack://./src/app.css"],"names":[],"mappings":"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","sourcesContent":[":root {\n color-scheme: dark;\n --bg: #17181f;\n --surface: #21222b;\n --surface-raised: #2a2c37;\n --border: #363846;\n --text: #e8e9f0;\n --text-muted: #9a9db0;\n --primary: #33bbff;\n --primary-contrast: #06202e;\n --primary-soft: rgba(51, 187, 255, 0.14);\n --secondary: #ee81c3;\n --warning: #f5b84a;\n --warning-soft: rgba(245, 184, 74, 0.13);\n --radius: 14px;\n --radius-small: 9px;\n --shadow: 0 12px 32px rgba(0, 0, 0, 0.28);\n}\n\n@media (prefers-color-scheme: light) {\n :root {\n color-scheme: light;\n --bg: #f3f4f8;\n --surface: #ffffff;\n --surface-raised: #f0f1f6;\n --border: #dcdee8;\n --text: #1c1d26;\n --text-muted: #62657a;\n --primary: #0b84c6;\n --primary-contrast: #ffffff;\n --primary-soft: rgba(11, 132, 198, 0.11);\n --secondary: #c2408f;\n --warning: #a86a00;\n --warning-soft: rgba(214, 144, 16, 0.14);\n --shadow: 0 10px 28px rgba(30, 34, 60, 0.08);\n }\n}\n\n*, *::before, *::after {\n box-sizing: border-box;\n}\n\nbody {\n margin: 0;\n background: var(--bg);\n color: var(--text);\n font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 16px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n}\n\na {\n color: var(--primary);\n text-decoration: none;\n}\n\na:hover {\n text-decoration: underline;\n}\n\nbutton, input {\n font: inherit;\n color: inherit;\n}\n\n:focus-visible {\n outline: 2px solid var(--primary);\n outline-offset: 2px;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/* Top bar */\n\n.topbar {\n border-bottom: 1px solid var(--border);\n background: var(--surface);\n}\n\n.topbar-inner {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n max-width: 1080px;\n margin: 0 auto;\n padding: 12px 20px;\n}\n\n.brand {\n display: flex;\n align-items: center;\n gap: 10px;\n color: var(--text);\n font-weight: 650;\n font-size: 1.1rem;\n}\n\n.brand:hover {\n text-decoration: none;\n}\n\n.brand-sub {\n color: var(--text-muted);\n font-weight: 400;\n}\n\n.topbar-links {\n display: flex;\n gap: 20px;\n font-size: 0.92rem;\n}\n\n.topbar-links a {\n color: var(--text-muted);\n}\n\n.topbar-links a:hover {\n color: var(--text);\n text-decoration: none;\n}\n\n/* Page */\n\nmain {\n max-width: 1080px;\n margin: 0 auto;\n padding: 36px 20px 64px;\n}\n\n.intro {\n margin-bottom: 28px;\n}\n\n.intro h1 {\n margin: 0 0 6px;\n font-size: clamp(1.6rem, 3.5vw, 2.1rem);\n line-height: 1.2;\n letter-spacing: -0.02em;\n}\n\n.intro p {\n margin: 0;\n color: var(--text-muted);\n}\n\n.layout {\n display: grid;\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n gap: 20px;\n align-items: start;\n}\n\n.card {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n box-shadow: var(--shadow);\n padding: 22px;\n}\n\n#Details {\n position: sticky;\n top: 20px;\n}\n\n.card h2 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 18px;\n font-size: 1.05rem;\n font-weight: 600;\n}\n\n.step {\n display: inline-grid;\n place-items: center;\n width: 26px;\n height: 26px;\n border-radius: 50%;\n background: var(--primary-soft);\n color: var(--primary);\n font-size: 0.85rem;\n font-weight: 700;\n}\n\n/* Search */\n\n.search {\n position: relative;\n}\n\n.search svg {\n position: absolute;\n top: 50%;\n left: 13px;\n width: 18px;\n height: 18px;\n transform: translateY(-50%);\n fill: none;\n stroke: var(--text-muted);\n stroke-width: 2;\n stroke-linecap: round;\n pointer-events: none;\n}\n\n.search input {\n width: 100%;\n padding: 11px 14px 11px 40px;\n background: var(--surface-raised);\n border: 1px solid var(--border);\n border-radius: var(--radius-small);\n}\n\n.search input::placeholder {\n color: var(--text-muted);\n}\n\n.search input:focus {\n outline: none;\n border-color: var(--primary);\n box-shadow: 0 0 0 3px var(--primary-soft);\n}\n\n.list-status {\n margin: 12px 2px 8px;\n color: var(--text-muted);\n font-size: 0.85rem;\n}\n\n/* Device list */\n\n.device-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n max-height: min(56vh, 520px);\n margin: 0 -8px;\n padding: 0 8px;\n overflow-y: auto;\n list-style: none;\n scrollbar-width: thin;\n scrollbar-color: var(--border) transparent;\n}\n\n.device {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 12px;\n background: none;\n border: 1px solid transparent;\n border-radius: var(--radius-small);\n text-align: left;\n cursor: pointer;\n}\n\n.device:hover {\n background: var(--surface-raised);\n}\n\n.device[aria-pressed=\"true\"] {\n background: var(--primary-soft);\n border-color: var(--primary);\n}\n\n.device-text {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.device-vendor {\n color: var(--text-muted);\n font-size: 0.76rem;\n line-height: 1.3;\n}\n\n.device-name {\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n\n.badge {\n flex-shrink: 0;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 0.7rem;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.badge-accent {\n background: color-mix(in srgb, var(--secondary) 16%, transparent);\n color: var(--secondary);\n}\n\n.badge-muted {\n background: var(--surface-raised);\n color: var(--text-muted);\n}\n\n.badge-warning {\n background: var(--warning-soft);\n color: var(--warning);\n}\n\n/* Details */\n\n.empty {\n margin: 0;\n padding: 36px 0;\n color: var(--text-muted);\n text-align: center;\n}\n\n.selected-device {\n margin-bottom: 18px;\n}\n\n.selected-vendor {\n color: var(--text-muted);\n font-size: 0.85rem;\n}\n\n.selected-name {\n font-size: 1.35rem;\n font-weight: 650;\n line-height: 1.25;\n letter-spacing: -0.01em;\n}\n\n.segmented {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 4px;\n padding: 4px;\n background: var(--surface-raised);\n border: 1px solid var(--border);\n border-radius: var(--radius-small);\n}\n\n.segment {\n position: relative;\n cursor: pointer;\n}\n\n.segment input {\n position: absolute;\n inset: 0;\n margin: 0;\n opacity: 0;\n cursor: inherit;\n}\n\n.segment-body {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 7px 10px;\n border-radius: 6px;\n}\n\n.segment-title {\n font-weight: 600;\n}\n\n.segment-sub {\n color: var(--text-muted);\n font-size: 0.78rem;\n}\n\n.segment input:checked + .segment-body {\n background: var(--surface);\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25), inset 0 0 0 1px var(--primary);\n}\n\n.segment input:checked + .segment-body .segment-title {\n color: var(--primary);\n}\n\n.segment input:focus-visible + .segment-body {\n outline: 2px solid var(--primary);\n outline-offset: 2px;\n}\n\n.segment:has(input:disabled) {\n cursor: not-allowed;\n opacity: 0.45;\n}\n\n.build-details {\n min-height: 1.3em;\n margin: 10px 2px 16px;\n color: var(--text-muted);\n font-size: 0.82rem;\n}\n\n/* Notices */\n\n.notice {\n margin-bottom: 12px;\n padding: 12px 14px;\n border-left: 3px solid var(--primary);\n border-radius: var(--radius-small);\n background: var(--primary-soft);\n font-size: 0.92rem;\n}\n\n.notice-warning {\n border-left-color: var(--warning);\n background: var(--warning-soft);\n}\n\nmain > .notice {\n margin-bottom: 20px;\n}\n\n/* Buttons */\n\nesp-web-install-button {\n display: block;\n margin-top: 18px;\n}\n\n.button-primary {\n width: 100%;\n padding: 12px 20px;\n background: var(--primary);\n border: 0;\n border-radius: var(--radius-small);\n color: var(--primary-contrast);\n font-weight: 650;\n cursor: pointer;\n transition: filter 0.15s, transform 0.05s;\n}\n\n.button-primary:hover {\n filter: brightness(1.08);\n}\n\n.button-primary:active {\n transform: translateY(1px);\n}\n\n.button-link {\n padding: 0;\n background: none;\n border: 0;\n color: var(--primary);\n cursor: pointer;\n}\n\n.button-link:hover {\n text-decoration: underline;\n}\n\n.install-fallback {\n display: block;\n color: var(--text-muted);\n font-size: 0.92rem;\n text-align: center;\n}\n\n@media (max-width: 820px) {\n .layout {\n grid-template-columns: minmax(0, 1fr);\n }\n\n #Details {\n position: static;\n }\n\n .device-list {\n max-height: 44vh;\n }\n\n .topbar-links a:first-child {\n display: none;\n }\n}\n"],"sourceRoot":""}]); -// Exports -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); - - -/***/ }), - -/***/ "./node_modules/css-loader/dist/runtime/api.js": -/*!*****************************************************!*\ - !*** ./node_modules/css-loader/dist/runtime/api.js ***! - \*****************************************************/ -/***/ ((module) => { - - - -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -module.exports = function (cssWithMappingToString) { - var list = []; - - // return the list of modules as css string - list.toString = function toString() { - return this.map(function (item) { - var content = ""; - var needLayer = typeof item[5] !== "undefined"; - if (item[4]) { - content += "@supports (".concat(item[4], ") {"); - } - if (item[2]) { - content += "@media ".concat(item[2], " {"); - } - if (needLayer) { - content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {"); - } - content += cssWithMappingToString(item); - if (needLayer) { - content += "}"; - } - if (item[2]) { - content += "}"; - } - if (item[4]) { - content += "}"; - } - return content; - }).join(""); - }; - - // import a list of modules into the list - list.i = function i(modules, media, dedupe, supports, layer) { - if (typeof modules === "string") { - modules = [[null, modules, undefined]]; - } - var alreadyImportedModules = {}; - if (dedupe) { - for (var k = 0; k < this.length; k++) { - var id = this[k][0]; - if (id != null) { - alreadyImportedModules[id] = true; - } - } - } - for (var _k = 0; _k < modules.length; _k++) { - var item = [].concat(modules[_k]); - if (dedupe && alreadyImportedModules[item[0]]) { - continue; - } - if (typeof layer !== "undefined") { - if (typeof item[5] === "undefined") { - item[5] = layer; - } else { - item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}"); - item[5] = layer; - } - } - if (media) { - if (!item[2]) { - item[2] = media; - } else { - item[1] = "@media ".concat(item[2], " {").concat(item[1], "}"); - item[2] = media; - } - } - if (supports) { - if (!item[4]) { - item[4] = "".concat(supports); - } else { - item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}"); - item[4] = supports; - } - } - list.push(item); - } - }; - return list; -}; - -/***/ }), - -/***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js": -/*!************************************************************!*\ - !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***! - \************************************************************/ -/***/ ((module) => { - - - -module.exports = function (item) { - var content = item[1]; - var cssMapping = item[3]; - if (!cssMapping) { - return content; - } - if (typeof btoa === "function") { - var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping)))); - var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64); - var sourceMapping = "/*# ".concat(data, " */"); - return [content].concat([sourceMapping]).join("\n"); - } - return [content].join("\n"); -}; - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/connect.js": -/*!****************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/connect.js ***! - \****************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ connect: () => (/* binding */ connect) -/* harmony export */ }); -const connect = async (button) => { - Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_esp-web-tools_dist_components_ew-dialog_js-node_modules_esp-web-tools_di-de8f3a"), __webpack_require__.e("vendors-node_modules_esp-web-tools_dist_install-dialog_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./install-dialog.js */ "./node_modules/esp-web-tools/dist/install-dialog.js")); - let port; - try { - port = await navigator.serial.requestPort(); - } - catch (err) { - if (err.name === "NotFoundError") { - Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_esp-web-tools_dist_components_ew-dialog_js-node_modules_esp-web-tools_di-de8f3a"), __webpack_require__.e("node_modules_esp-web-tools_dist_no-port-picked_index_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./no-port-picked/index */ "./node_modules/esp-web-tools/dist/no-port-picked/index.js")).then((mod) => mod.openNoPortPickedDialog(() => connect(button))); - return; - } - alert(`Error: ${err.message}`); - return; - } - if (!port) { - return; - } - try { - await port.open({ baudRate: 115200, bufferSize: 8192 }); - } - catch (err) { - alert(err.message); - return; - } - const el = document.createElement("ewt-install-dialog"); - el.port = port; - el.manifestPath = button.manifest || button.getAttribute("manifest"); - el.overrides = button.overrides; - el.addEventListener("closed", () => { - port.close(); - }, { once: true }); - document.body.appendChild(el); -}; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/install-button.js": -/*!***********************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/install-button.js ***! - \***********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ InstallButton: () => (/* binding */ InstallButton) -/* harmony export */ }); -/* harmony import */ var _connect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./connect */ "./node_modules/esp-web-tools/dist/connect.js"); - -class InstallButton extends HTMLElement { - connectedCallback() { - if (this.renderRoot) { - return; - } - this.renderRoot = this.attachShadow({ mode: "open" }); - if (!InstallButton.isSupported || !InstallButton.isAllowed) { - this.toggleAttribute("install-unsupported", true); - this.renderRoot.innerHTML = !InstallButton.isAllowed - ? "You can only install ESP devices on HTTPS websites or on the localhost." - : "Your browser does not support installing things on ESP devices. Use Google Chrome or Microsoft Edge."; - return; - } - this.toggleAttribute("install-supported", true); - const slot = document.createElement("slot"); - slot.addEventListener("click", async (ev) => { - ev.preventDefault(); - (0,_connect__WEBPACK_IMPORTED_MODULE_0__.connect)(this); - }); - slot.name = "activate"; - const button = document.createElement("button"); - button.innerText = "Connect"; - slot.append(button); - if ("adoptedStyleSheets" in Document.prototype && - "replaceSync" in CSSStyleSheet.prototype) { - const sheet = new CSSStyleSheet(); - sheet.replaceSync(InstallButton.style); - this.renderRoot.adoptedStyleSheets = [sheet]; - } - else { - const styleSheet = document.createElement("style"); - styleSheet.innerText = InstallButton.style; - this.renderRoot.append(styleSheet); - } - this.renderRoot.append(slot); - } -} -InstallButton.isSupported = "serial" in navigator; -InstallButton.isAllowed = window.isSecureContext; -InstallButton.style = ` - button { - position: relative; - cursor: pointer; - font-size: 14px; - font-weight: 500; - padding: 10px 24px; - color: var(--esp-tools-button-text-color, #fff); - background-color: var(--esp-tools-button-color, #03a9f4); - border: none; - border-radius: var(--esp-tools-button-border-radius, 9999px); - } - button::before { - content: " "; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - opacity: 0.2; - border-radius: var(--esp-tools-button-border-radius, 9999px); - } - button:hover::before { - background-color: rgba(255,255,255,.8); - } - button:focus { - outline: none; - } - button:focus::before { - background-color: white; - } - button:active::before { - background-color: grey; - } - :host([active]) button { - color: rgba(0, 0, 0, 0.38); - background-color: rgba(0, 0, 0, 0.12); - box-shadow: none; - cursor: unset; - pointer-events: none; - } - .hidden { - display: none; - }`; -customElements.define("esp-web-install-button", InstallButton); - - -/***/ }), - -/***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js": -/*!****************************************************************************!*\ - !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***! - \****************************************************************************/ -/***/ ((module) => { - - - -var stylesInDOM = []; -function getIndexByIdentifier(identifier) { - var result = -1; - for (var i = 0; i < stylesInDOM.length; i++) { - if (stylesInDOM[i].identifier === identifier) { - result = i; - break; - } - } - return result; -} -function modulesToDom(list, options) { - var idCountMap = {}; - var identifiers = []; - for (var i = 0; i < list.length; i++) { - var item = list[i]; - var id = options.base ? item[0] + options.base : item[0]; - var count = idCountMap[id] || 0; - var identifier = "".concat(id, " ").concat(count); - idCountMap[id] = count + 1; - var indexByIdentifier = getIndexByIdentifier(identifier); - var obj = { - css: item[1], - media: item[2], - sourceMap: item[3], - supports: item[4], - layer: item[5] - }; - if (indexByIdentifier !== -1) { - stylesInDOM[indexByIdentifier].references++; - stylesInDOM[indexByIdentifier].updater(obj); - } else { - var updater = addElementStyle(obj, options); - options.byIndex = i; - stylesInDOM.splice(i, 0, { - identifier: identifier, - updater: updater, - references: 1 - }); - } - identifiers.push(identifier); - } - return identifiers; -} -function addElementStyle(obj, options) { - var api = options.domAPI(options); - api.update(obj); - var updater = function updater(newObj) { - if (newObj) { - if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) { - return; - } - api.update(obj = newObj); - } else { - api.remove(); - } - }; - return updater; -} -module.exports = function (list, options) { - options = options || {}; - list = list || []; - var lastIdentifiers = modulesToDom(list, options); - return function update(newList) { - newList = newList || []; - for (var i = 0; i < lastIdentifiers.length; i++) { - var identifier = lastIdentifiers[i]; - var index = getIndexByIdentifier(identifier); - stylesInDOM[index].references--; - } - var newLastIdentifiers = modulesToDom(newList, options); - for (var _i = 0; _i < lastIdentifiers.length; _i++) { - var _identifier = lastIdentifiers[_i]; - var _index = getIndexByIdentifier(_identifier); - if (stylesInDOM[_index].references === 0) { - stylesInDOM[_index].updater(); - stylesInDOM.splice(_index, 1); - } - } - lastIdentifiers = newLastIdentifiers; - }; -}; - -/***/ }), - -/***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js": -/*!********************************************************************!*\ - !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***! - \********************************************************************/ -/***/ ((module) => { - - - -var memo = {}; - -/* istanbul ignore next */ -function getTarget(target) { - if (typeof memo[target] === "undefined") { - var styleTarget = document.querySelector(target); - - // Special case to return head of iframe instead of iframe itself - if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) { - try { - // This will throw an exception if access to iframe is blocked - // due to cross-origin restrictions - styleTarget = styleTarget.contentDocument.head; - } catch (e) { - // istanbul ignore next - styleTarget = null; - } - } - memo[target] = styleTarget; - } - return memo[target]; -} - -/* istanbul ignore next */ -function insertBySelector(insert, style) { - var target = getTarget(insert); - if (!target) { - throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); - } - target.appendChild(style); -} -module.exports = insertBySelector; - -/***/ }), - -/***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js": -/*!**********************************************************************!*\ - !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***! - \**********************************************************************/ -/***/ ((module) => { - - - -/* istanbul ignore next */ -function insertStyleElement(options) { - var element = document.createElement("style"); - options.setAttributes(element, options.attributes); - options.insert(element, options.options); - return element; -} -module.exports = insertStyleElement; - -/***/ }), - -/***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js": -/*!**********************************************************************************!*\ - !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***! - \**********************************************************************************/ -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - - - -/* istanbul ignore next */ -function setAttributesWithoutAttributes(styleElement) { - var nonce = true ? __webpack_require__.nc : 0; - if (nonce) { - styleElement.setAttribute("nonce", nonce); - } -} -module.exports = setAttributesWithoutAttributes; - -/***/ }), - -/***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js": -/*!***************************************************************!*\ - !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***! - \***************************************************************/ -/***/ ((module) => { - - - -/* istanbul ignore next */ -function apply(styleElement, options, obj) { - var css = ""; - if (obj.supports) { - css += "@supports (".concat(obj.supports, ") {"); - } - if (obj.media) { - css += "@media ".concat(obj.media, " {"); - } - var needLayer = typeof obj.layer !== "undefined"; - if (needLayer) { - css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {"); - } - css += obj.css; - if (needLayer) { - css += "}"; - } - if (obj.media) { - css += "}"; - } - if (obj.supports) { - css += "}"; - } - var sourceMap = obj.sourceMap; - if (sourceMap && typeof btoa !== "undefined") { - css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */"); - } - - // For old IE - /* istanbul ignore if */ - options.styleTagTransform(css, styleElement, options.options); -} -function removeStyleElement(styleElement) { - // istanbul ignore if - if (styleElement.parentNode === null) { - return false; - } - styleElement.parentNode.removeChild(styleElement); -} - -/* istanbul ignore next */ -function domAPI(options) { - if (typeof document === "undefined") { - return { - update: function update() {}, - remove: function remove() {} - }; - } - var styleElement = options.insertStyleElement(options); - return { - update: function update(obj) { - apply(styleElement, options, obj); - }, - remove: function remove() { - removeStyleElement(styleElement); - } - }; -} -module.exports = domAPI; - -/***/ }), - -/***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js": -/*!*********************************************************************!*\ - !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***! - \*********************************************************************/ -/***/ ((module) => { - - - -/* istanbul ignore next */ -function styleTagTransform(css, styleElement) { - if (styleElement.styleSheet) { - styleElement.styleSheet.cssText = css; - } else { - while (styleElement.firstChild) { - styleElement.removeChild(styleElement.firstChild); - } - styleElement.appendChild(document.createTextNode(css)); - } -} -module.exports = styleTagTransform; - -/***/ }), - -/***/ "./src/app.css": -/*!*********************!*\ - !*** ./src/app.css ***! - \*********************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"); -/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleDomAPI.js */ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"); -/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertBySelector.js */ "./node_modules/style-loader/dist/runtime/insertBySelector.js"); -/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js */ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"); -/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertStyleElement.js */ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"); -/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__); -/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleTagTransform.js */ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"); -/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__); -/* harmony import */ var _node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./app.css */ "./node_modules/css-loader/dist/cjs.js!./src/app.css"); - - - - - - - - - - - -var options = {}; - -options.styleTagTransform = (_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default()); -options.setAttributes = (_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default()); -options.insert = _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head"); -options.domAPI = (_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default()); -options.insertStyleElement = (_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default()); - -var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__["default"], options); - - - - - /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _node_modules_css_loader_dist_cjs_js_app_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined); - - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ id: moduleId, -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = __webpack_modules__; -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/compat get default export */ -/******/ (() => { -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = (module) => { -/******/ var getter = module && module.__esModule ? -/******/ () => (module['default']) : -/******/ () => (module); -/******/ __webpack_require__.d(getter, { a: getter }); -/******/ return getter; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/create fake namespace object */ -/******/ (() => { -/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); -/******/ var leafPrototypes; -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 16: return value when it's Promise-like -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = this(value); -/******/ if(mode & 8) return value; -/******/ if(typeof value === 'object' && value) { -/******/ if((mode & 4) && value.__esModule) return value; -/******/ if((mode & 16) && typeof value.then === 'function') return value; -/******/ } -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ var def = {}; -/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; -/******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) { -/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); -/******/ } -/******/ def['default'] = () => (value); -/******/ __webpack_require__.d(ns, def); -/******/ return ns; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/ensure chunk */ -/******/ (() => { -/******/ __webpack_require__.f = {}; -/******/ // This file contains only the entry chunk. -/******/ // The chunk loading function for additional chunks -/******/ __webpack_require__.e = (chunkId) => { -/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { -/******/ __webpack_require__.f[key](chunkId, promises); -/******/ return promises; -/******/ }, [])); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/get javascript chunk filename */ -/******/ (() => { -/******/ // This function allow to reference async chunks -/******/ __webpack_require__.u = (chunkId) => { -/******/ // return url for filenames based on template -/******/ return "" + chunkId + ".bundle.js"; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/global */ -/******/ (() => { -/******/ __webpack_require__.g = (function() { -/******/ if (typeof globalThis === 'object') return globalThis; -/******/ try { -/******/ return this || new Function('return this')(); -/******/ } catch (e) { -/******/ if (typeof window === 'object') return window; -/******/ } -/******/ })(); -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/load script */ -/******/ (() => { -/******/ var inProgress = {}; -/******/ var dataWebpackPrefix = "Tactility Web Installer:"; -/******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key, chunkId) => { -/******/ if(inProgress[url]) { inProgress[url].push(done); return; } -/******/ var script, needAttach; -/******/ if(key !== undefined) { -/******/ var scripts = document.getElementsByTagName("script"); -/******/ for(var i = 0; i < scripts.length; i++) { -/******/ var s = scripts[i]; -/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; } -/******/ } -/******/ } -/******/ if(!script) { -/******/ needAttach = true; -/******/ script = document.createElement('script'); -/******/ -/******/ script.charset = 'utf-8'; -/******/ script.timeout = 120; -/******/ if (__webpack_require__.nc) { -/******/ script.setAttribute("nonce", __webpack_require__.nc); -/******/ } -/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key); -/******/ -/******/ script.src = url; -/******/ } -/******/ inProgress[url] = [done]; -/******/ var onScriptComplete = (prev, event) => { -/******/ // avoid mem leaks in IE. -/******/ script.onerror = script.onload = null; -/******/ clearTimeout(timeout); -/******/ var doneFns = inProgress[url]; -/******/ delete inProgress[url]; -/******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => (fn(event))); -/******/ if(prev) return prev(event); -/******/ } -/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); -/******/ script.onerror = onScriptComplete.bind(null, script.onerror); -/******/ script.onload = onScriptComplete.bind(null, script.onload); -/******/ needAttach && document.head.appendChild(script); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/publicPath */ -/******/ (() => { -/******/ var scriptUrl; -/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + ""; -/******/ var document = __webpack_require__.g.document; -/******/ if (!scriptUrl && document) { -/******/ if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') -/******/ scriptUrl = document.currentScript.src; -/******/ if (!scriptUrl) { -/******/ var scripts = document.getElementsByTagName("script"); -/******/ if(scripts.length) { -/******/ var i = scripts.length - 1; -/******/ while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src; -/******/ } -/******/ } -/******/ } -/******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration -/******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic. -/******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser"); -/******/ scriptUrl = scriptUrl.replace(/^blob:/, "").replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/"); -/******/ __webpack_require__.p = scriptUrl; -/******/ })(); -/******/ -/******/ /* webpack/runtime/jsonp chunk loading */ -/******/ (() => { -/******/ // no baseURI -/******/ -/******/ // object to store loaded and loading chunks -/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded -/******/ var installedChunks = { -/******/ "main": 0 -/******/ }; -/******/ -/******/ __webpack_require__.f.j = (chunkId, promises) => { -/******/ // JSONP chunk loading for javascript -/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; -/******/ if(installedChunkData !== 0) { // 0 means "already installed". -/******/ -/******/ // a Promise means "currently loading". -/******/ if(installedChunkData) { -/******/ promises.push(installedChunkData[2]); -/******/ } else { -/******/ if(true) { // all chunks have JS -/******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); -/******/ promises.push(installedChunkData[2] = promise); -/******/ -/******/ // start chunk loading -/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId); -/******/ // create error before stack unwound to get useful stacktrace later -/******/ var error = new Error(); -/******/ var loadingEnded = (event) => { -/******/ if(__webpack_require__.o(installedChunks, chunkId)) { -/******/ installedChunkData = installedChunks[chunkId]; -/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined; -/******/ if(installedChunkData) { -/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); -/******/ var realSrc = event && event.target && event.target.src; -/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; -/******/ error.name = 'ChunkLoadError'; -/******/ error.type = errorType; -/******/ error.request = realSrc; -/******/ installedChunkData[1](error); -/******/ } -/******/ } -/******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); -/******/ } -/******/ } -/******/ } -/******/ }; -/******/ -/******/ // no prefetching -/******/ -/******/ // no preloaded -/******/ -/******/ // no HMR -/******/ -/******/ // no HMR manifest -/******/ -/******/ // no on chunks loaded -/******/ -/******/ // install a JSONP callback for chunk loading -/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime] = data; -/******/ // add "moreModules" to the modules object, -/******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0; -/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) var result = runtime(__webpack_require__); -/******/ } -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ for(;i < chunkIds.length; i++) { -/******/ chunkId = chunkIds[i]; -/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ installedChunks[chunkId][0](); -/******/ } -/******/ installedChunks[chunkId] = 0; -/******/ } -/******/ -/******/ } -/******/ -/******/ var chunkLoadingGlobal = self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []; -/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); -/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ })(); -/******/ -/******/ /* webpack/runtime/nonce */ -/******/ (() => { -/******/ __webpack_require__.nc = undefined; -/******/ })(); -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. -(() => { -/*!*********************!*\ - !*** ./src/main.js ***! - \*********************/ -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var esp_web_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! esp-web-tools */ "./node_modules/esp-web-tools/dist/install-button.js"); -/* harmony import */ var _app_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./app.css */ "./src/app.css"); -/* harmony import */ var _assets_images_toolbar_logo_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../assets/images/toolbar-logo.svg */ "./assets/images/toolbar-logo.svg"); -/* harmony import */ var _assets_images_favicon_svg__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../assets/images/favicon.svg */ "./assets/images/favicon.svg"); - - - - - - -const VERSIONS = ['stable', 'unstable']; - -const $ = (id) => document.getElementById(id); - -const state = { - /** version name -> index.json content, or null when it failed to load */ - indexes: {}, - /** merged devices: { id, vendor, name, label, haystack, words, builds: { stable?, unstable? } } */ - devices: [], - selectedId: null, - preferredVersion: 'unstable', - query: '', -}; - -function getCdnUrl(version, path) { - const directory = version === 'unstable' ? 'snapshot' : version; - return `https://cdn.tactilityproject.org/firmware/${directory}/${path}`; -} - -/** Lowercase and strip punctuation, so "tdeck" matches "T-Deck". */ -function squash(text) { - return text.toLowerCase().replace(/[^a-z0-9]+/g, ''); -} - -function fetchIndex(version) { - return fetch(getCdnUrl(version, 'index.json')).then((response) => { - if (!response.ok) { - throw new Error(`HTTP ${response.status}`); - } - return response.json(); - }); -} - -function mergeDevices() { - const byId = new Map(); - for (const version of VERSIONS) { - const index = state.indexes[version]; - if (!index) continue; - for (const build of index.devices) { - let device = byId.get(build.id); - if (!device) { - device = { id: build.id, builds: {} }; - byId.set(build.id, device); - } - device.builds[version] = build; - // Later versions win, so naming follows the newest build - device.vendor = build.vendor; - device.name = build.name; - } - } - - state.devices = [...byId.values()]; - for (const device of state.devices) { - device.showVendor = device.vendor !== device.name; - device.label = device.showVendor ? `${device.vendor} ${device.name}` : device.name; - const text = `${device.label} ${device.id}`; - device.haystack = `${text.toLowerCase()} ${squash(text)}`; - device.words = device.label.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean); - } - state.devices.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base', numeric: true })); -} - -/** - * Whether the token can be split into pieces that are each the start of a word, in word order. - * Makes "m5paper" match "M5Stack PaperS3" and "tdeck" match "T-Deck". - */ -function matchesWordStarts(token, words, firstWord = 0) { - if (token === '') { - return true; - } - for (let i = firstWord; i < words.length; i++) { - const word = words[i]; - // Pieces of a single character only count when they are the entire word, to limit noise - const minLength = Math.min(2, word.length); - for (let length = Math.min(word.length, token.length); length >= minLength; length--) { - if (word.startsWith(token.slice(0, length)) && matchesWordStarts(token.slice(length), words, i + 1)) { - return true; - } - } - } - return false; -} - -function matchesToken(device, token) { - if (device.haystack.includes(token)) { - return true; - } - const squashed = squash(token); - return squashed !== '' && (device.haystack.includes(squashed) || matchesWordStarts(squashed, device.words)); -} - -function getFilteredDevices() { - const tokens = state.query.toLowerCase().split(/\s+/).filter(Boolean); - if (tokens.length === 0) { - return state.devices; - } - return state.devices.filter((device) => tokens.every((token) => matchesToken(device, token))); -} - -function getSelectedDevice() { - return state.devices.find((device) => device.id === state.selectedId) || null; -} - -/** The version to show for a device: the preferred one, or whichever is available. */ -function getActiveVersion(device) { - if (device.builds[state.preferredVersion]) { - return state.preferredVersion; - } - return VERSIONS.find((version) => device.builds[version]); -} - -function createBadge(text, kind) { - const badge = document.createElement('span'); - badge.className = `badge badge-${kind}`; - badge.textContent = text; - return badge; -} - -function renderDeviceList() { - const list = $('DeviceList'); - const status = $('ListStatus'); - const devices = getFilteredDevices(); - list.replaceChildren(); - - for (const device of devices) { - const button = document.createElement('button'); - button.type = 'button'; - button.className = 'device'; - button.dataset.id = device.id; - button.setAttribute('aria-pressed', String(device.id === state.selectedId)); - - const text = document.createElement('span'); - text.className = 'device-text'; - if (device.showVendor) { - const vendor = document.createElement('span'); - vendor.className = 'device-vendor'; - vendor.textContent = device.vendor; - text.append(vendor); - } - const name = document.createElement('span'); - name.className = 'device-name'; - name.textContent = device.name; - text.append(name); - button.append(text); - - if (!device.builds.stable) { - button.append(createBadge('Unstable only', 'accent')); - } else if (!device.builds.unstable) { - button.append(createBadge('Stable only', 'muted')); - } - if (device.builds[getActiveVersion(device)].incubating) { - button.append(createBadge('Incubating', 'warning')); - } - - const item = document.createElement('li'); - item.append(button); - list.append(item); - } - - if (state.devices.length === 0) { - return; // Loading or error state owns the status text - } - if (devices.length === 0) { - status.textContent = `No devices match “${state.query.trim()}”.`; - } else if (devices.length === state.devices.length) { - status.textContent = `${devices.length} supported devices`; - } else { - status.textContent = `${devices.length} of ${state.devices.length} devices`; - } -} - -function createNotice(html, kind) { - const notice = document.createElement('div'); - notice.className = `notice notice-${kind}`; - // Messages come from our own CDN and contain markup such as
- notice.innerHTML = html; - return notice; -} - -function renderVersionLabels() { - for (const version of VERSIONS) { - const index = state.indexes[version]; - document.querySelector(`[data-version-label="${version}"]`).textContent = index ? index.version : 'Unavailable'; - } -} - -function renderDetails() { - const device = getSelectedDevice(); - $('DetailsEmpty').hidden = device !== null; - $('DetailsContent').hidden = device === null; - if (device === null) { - return; - } - - const version = getActiveVersion(device); - const build = device.builds[version]; - const index = state.indexes[version]; - - $('SelectedVendor').textContent = device.showVendor ? device.vendor : ''; - $('SelectedName').textContent = device.name; - - for (const input of document.querySelectorAll('input[name="version"]')) { - const available = Boolean(device.builds[input.value]); - input.disabled = !available; - input.checked = input.value === version; - input.closest('.segment').title = available ? '' : `No ${input.value} build for this device`; - } - - const details = $('VersionDetails'); - details.replaceChildren(); - if (index.created && index.gitCommit) { - const link = document.createElement('a'); - link.href = `https://github.com/ByteWelder/Tactility/commit/${index.gitCommit}`; - link.textContent = index.gitCommit.substring(0, 7); - details.append(`Built on ${new Date(index.created).toLocaleString()} from commit `, link); - } - - const info = $('DeviceInfo'); - info.replaceChildren(); - if (build.incubating) { - info.append(createNotice('This device is incubating. It is not fully implemented!', 'warning')); - } - if (build.warningMessage) { - info.append(createNotice(build.warningMessage, 'warning')); - } - if (build.infoMessage) { - info.append(createNotice(build.infoMessage, 'info')); - } - - $('Installer').manifest = getCdnUrl(version, `${device.id}.json`); -} - -function selectDevice(id) { - state.selectedId = id; - for (const button of document.querySelectorAll('.device')) { - button.setAttribute('aria-pressed', String(button.dataset.id === id)); - } - renderDetails(); - if (getHashDeviceId() !== id) { - // Replace rather than push, so browsing devices doesn't fill up the history - history.replaceState(null, '', `#${encodeURIComponent(id)}`); - } -} - -function getHashDeviceId() { - try { - return decodeURIComponent(location.hash.slice(1)); - } catch (error) { - return ''; - } -} - -/** Select the device from the URL, e.g. https://install.tactilityproject.org/#lilygo-tdeck */ -function selectDeviceFromHash() { - const id = getHashDeviceId(); - if (id === state.selectedId || !state.devices.some((device) => device.id === id)) { - return; - } - if (!getFilteredDevices().some((device) => device.id === id)) { - // Don't leave the linked device hidden behind a search query - state.query = ''; - $('Search').value = ''; - renderDeviceList(); - } - selectDevice(id); - const button = document.querySelector('.device[aria-pressed="true"]'); - if (button) { - button.scrollIntoView({ block: 'nearest' }); - } -} - -function showLoadError() { - const status = $('ListStatus'); - status.textContent = 'Failed to fetch device info. '; - const retry = document.createElement('button'); - retry.type = 'button'; - retry.className = 'button-link'; - retry.textContent = 'Try again'; - retry.addEventListener('click', load); - status.append(retry); -} - -async function load() { - $('ListStatus').textContent = 'Loading devices…'; - const results = await Promise.allSettled(VERSIONS.map(fetchIndex)); - results.forEach((result, i) => { - state.indexes[VERSIONS[i]] = result.status === 'fulfilled' ? result.value : null; - if (result.status === 'rejected') { - console.warn(`Failed to fetch ${VERSIONS[i]} index`, result.reason); - } - }); - - mergeDevices(); - renderVersionLabels(); - if (state.devices.length === 0) { - showLoadError(); - } - renderDeviceList(); - renderDetails(); - selectDeviceFromHash(); -} - -$('NavbarImage').src = _assets_images_toolbar_logo_svg__WEBPACK_IMPORTED_MODULE_2__; -$('UnsupportedNotice').hidden = 'serial' in navigator; - -$('Search').addEventListener('input', (event) => { - state.query = event.target.value; - renderDeviceList(); -}); - -$('Search').addEventListener('keydown', (event) => { - if (event.key === 'Enter') { - const first = getFilteredDevices()[0]; - if (first) { - selectDevice(first.id); - } - } -}); - -$('DeviceList').addEventListener('click', (event) => { - const button = event.target.closest('.device'); - if (button) { - selectDevice(button.dataset.id); - } -}); - -$('VersionOptions').addEventListener('change', (event) => { - state.preferredVersion = event.target.value; - renderDeviceList(); - renderDetails(); -}); - -window.addEventListener('hashchange', selectDeviceFromHash); - -load(); - -})(); - -/******/ })() -; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVuZGxlLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDMEc7QUFDakI7QUFDekYsOEJBQThCLG1GQUEyQixDQUFDLDRGQUFxQztBQUMvRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyw4RUFBOEUsWUFBWSxXQUFXLFlBQVksYUFBYSxhQUFhLFdBQVcsWUFBWSxhQUFhLGFBQWEsYUFBYSxhQUFhLGFBQWEsYUFBYSxXQUFXLFlBQVksYUFBYSxPQUFPLEtBQUssS0FBSyxZQUFZLFdBQVcsWUFBWSxhQUFhLGFBQWEsV0FBVyxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsYUFBYSxhQUFhLGFBQWEsTUFBTSxNQUFNLEtBQUssWUFBWSxPQUFPLEtBQUssVUFBVSxZQUFZLGFBQWEsYUFBYSxXQUFXLFlBQVksYUFBYSxPQUFPLEtBQUssWUFBWSxhQUFhLE9BQU8sS0FBSyxZQUFZLE9BQU8sS0FBSyxVQUFVLFVBQVUsT0FBTyxLQUFLLFlBQVksYUFBYSxPQUFPLEtBQUssWUFBWSxPQUFPLFdBQVcsS0FBSyxZQUFZLGFBQWEsT0FBTyxLQUFLLFVBQVUsWUFBWSxhQUFhLFdBQVcsWUFBWSxXQUFXLFlBQVksT0FBTyxLQUFLLFVBQVUsWUFBWSxXQUFXLFlBQVksYUFBYSxhQUFhLE9BQU8sS0FBSyxZQUFZLE9BQU8sS0FBSyxZQUFZLGFBQWEsT0FBTyxLQUFLLFVBQVUsVUFBVSxZQUFZLE9BQU8sS0FBSyxZQUFZLE9BQU8sS0FBSyxZQUFZLGFBQWEsT0FBTyxXQUFXLEtBQUssWUFBWSxXQUFXLFlBQVksT0FBTyxLQUFLLFlBQVksT0FBTyxLQUFLLFVBQVUsWUFBWSxhQUFhLGFBQWEsT0FBTyxLQUFLLFVBQVUsWUFBWSxPQUFPLEtBQUssVUFBVSxZQUFZLFdBQVcsWUFBWSxPQUFPLEtBQUssWUFBWSxhQUFhLGFBQWEsYUFBYSxXQUFXLE9BQU8sS0FBSyxZQUFZLFdBQVcsTUFBTSxLQUFLLFVBQVUsWUFBWSxXQUFXLFlBQVksYUFBYSxhQUFhLE9BQU8sS0FBSyxZQUFZLGFBQWEsV0FBVyxVQUFVLFlBQVksYUFBYSxhQUFhLGFBQWEsYUFBYSxPQUFPLFdBQVcsS0FBSyxZQUFZLE9BQU8sS0FBSyxZQUFZLFdBQVcsVUFBVSxVQUFVLFVBQVUsWUFBWSxXQUFXLFlBQVksV0FBVyxZQUFZLGFBQWEsT0FBTyxLQUFLLFVBQVUsWUFBWSxhQUFhLGFBQWEsYUFBYSxPQUFPLEtBQUssWUFBWSxPQUFPLEtBQUssVUFBVSxZQUFZLGFBQWEsT0FBTyxLQUFLLFlBQVksYUFBYSxhQUFhLE9BQU8sYUFBYSxNQUFNLFVBQVUsWUFBWSxXQUFXLFlBQVksV0FBVyxVQUFVLFlBQVksYUFBYSxhQUFhLGFBQWEsT0FBTyxLQUFLLFVBQVUsWUFBWSxXQUFXLFVBQVUsWUFBWSxhQUFhLGFBQWEsYUFBYSxhQUFhLFdBQVcsT0FBTyxLQUFLLFlBQVksT0FBTyxLQUFLLFlBQVksYUFBYSxPQUFPLEtBQUssVUFBVSxZQUFZLFdBQVcsVUFBVSxPQUFPLEtBQUssWUFBWSxhQUFhLGFBQWEsT0FBTyxLQUFLLFlBQVksYUFBYSxPQUFPLEtBQUssVUFBVSxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsT0FBTyxLQUFLLFlBQVksYUFBYSxPQUFPLEtBQUssWUFBWSxhQUFhLE9BQU8sS0FBSyxZQUFZLGFBQWEsT0FB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RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsYUFBYTtBQUM5RTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRSxnQkFBZ0I7QUFDdEY7QUFDQSxtQ0FBbUMsMENBQTBDO0FBQzdFOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0RBQW9ELFVBQVU7QUFDOUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyx1QkFBdUI7QUFDbEU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxrQkFBa0I7QUFDbEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEMsYUFBYTtBQUN6RDtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHVCQUF1Qiw0REFBVztBQUNsQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL3NyYy9hcHAuY3NzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL2FwaS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcC13ZWItdG9vbHMvZGlzdC9jb25uZWN0LmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcC13ZWItdG9vbHMvZGlzdC9pbnN0YWxsLWJ1dHRvbi5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vc3JjL2FwcC5jc3M/YTY3MiIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci93ZWJwYWNrL3J1bnRpbWUvY29tcGF0IGdldCBkZWZhdWx0IGV4cG9ydCIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci93ZWJwYWNrL3J1bnRpbWUvY3JlYXRlIGZha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvd2VicGFjay9ydW50aW1lL2Vuc3VyZSBjaHVuayIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci93ZWJwYWNrL3J1bnRpbWUvZ2V0IGphdmFzY3JpcHQgY2h1bmsgZmlsZW5hbWUiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvd2VicGFjay9ydW50aW1lL2dsb2JhbCIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyL3dlYnBhY2svcnVudGltZS9sb2FkIHNjcmlwdCIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyL3dlYnBhY2svcnVudGltZS9wdWJsaWNQYXRoIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyL3dlYnBhY2svcnVudGltZS9qc29ucCBjaHVuayBsb2FkaW5nIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyL3dlYnBhY2svcnVudGltZS9ub25jZSIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL3NyYy9tYWluLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEltcG9ydHNcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fIGZyb20gXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qc1wiO1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyBmcm9tIFwiLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL2FwaS5qc1wiO1xudmFyIF9fX0NTU19MT0FERVJfRVhQT1JUX19fID0gX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fKF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18pO1xuLy8gTW9kdWxlXG5fX19DU1NfTE9BREVSX0VYUE9SVF9fXy5wdXNoKFttb2R1bGUuaWQsIGA6cm9vdCB7XG4gICAgY29sb3Itc2NoZW1lOiBkYXJrO1xuICAgIC0tYmc6ICMxNzE4MWY7XG4gICAgLS1zdXJmYWNlOiAjMjEyMjJiO1xuICAgIC0tc3VyZmFjZS1yYWlzZWQ6ICMyYTJjMzc7XG4gICAgLS1ib3JkZXI6ICMzNjM4NDY7XG4gICAgLS10ZXh0OiAjZThlOWYwO1xuICAgIC0tdGV4dC1tdXRlZDogIzlhOWRiMDtcbiAgICAtLXByaW1hcnk6ICMzM2JiZmY7XG4gICAgLS1wcmltYXJ5LWNvbnRyYXN0OiAjMDYyMDJlO1xuICAgIC0tcHJpbWFyeS1zb2Z0OiByZ2JhKDUxLCAxODcsIDI1NSwgMC4xNCk7XG4gICAgLS1zZWNvbmRhcnk6ICNlZTgxYzM7XG4gICAgLS13YXJuaW5nOiAjZjViODRhO1xuICAgIC0td2FybmluZy1zb2Z0OiByZ2JhKDI0NSwgMTg0LCA3NCwgMC4xMyk7XG4gICAgLS1yYWRpdXM6IDE0cHg7XG4gICAgLS1yYWRpdXMtc21hbGw6IDlweDtcbiAgICAtLXNoYWRvdzogMCAxMnB4IDMycHggcmdiYSgwLCAwLCAwLCAwLjI4KTtcbn1cblxuQG1lZGlhIChwcmVmZXJzLWNvbG9yLXNjaGVtZTogbGlnaHQpIHtcbiAgICA6cm9vdCB7XG4gICAgICAgIGNvbG9yLXNjaGVtZTogbGlnaHQ7XG4gICAgICAgIC0tYmc6ICNmM2Y0Zjg7XG4gICAgICAgIC0tc3VyZmFjZTogI2ZmZmZmZjtcbiAgICAgICAgLS1zdXJmYWNlLXJhaXNlZDogI2YwZjFmNjtcbiAgICAgICAgLS1ib3JkZXI6ICNkY2RlZTg7XG4gICAgICAgIC0tdGV4dDogIzFjMWQyNjtcbiAgICAgICAgLS10ZXh0LW11dGVkOiAjNjI2NTdhO1xuICAgICAgICAtLXByaW1hcnk6ICMwYjg0YzY7XG4gICAgICAgIC0tcHJpbWFyeS1jb250cmFzdDogI2ZmZmZmZjtcbiAgICAgICAgLS1wcmltYXJ5LXNvZnQ6IHJnYmEoMTEsIDEzMiwgMTk4LCAwLjExKTtcbiAgICAgICAgLS1zZWNvbmRhcnk6ICNjMjQwOGY7XG4gICAgICAgIC0td2FybmluZzogI2E4NmEwMDtcbiAgICAgICAgLS13YXJuaW5nLXNvZnQ6IHJnYmEoMjE0LCAxNDQsIDE2LCAwLjE0KTtcbiAgICAgICAgLS1zaGFkb3c6IDAgMTBweCAyOHB4IHJnYmEoMzAsIDM0LCA2MCwgMC4wOCk7XG4gICAgfVxufVxuXG4qLCAqOjpiZWZvcmUsICo6OmFmdGVyIHtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xufVxuXG5ib2R5IHtcbiAgICBtYXJnaW46IDA7XG4gICAgYmFja2dyb3VuZDogdmFyKC0tYmcpO1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0KTtcbiAgICBmb250LWZhbWlseTogc3lzdGVtLXVpLCAtYXBwbGUtc3lzdGVtLCBcIlNlZ29lIFVJXCIsIFJvYm90bywgXCJIZWx2ZXRpY2EgTmV1ZVwiLCBBcmlhbCwgc2Fucy1zZXJpZjtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgbGluZS1oZWlnaHQ6IDEuNTtcbiAgICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcbn1cblxuYSB7XG4gICAgY29sb3I6IHZhcigtLXByaW1hcnkpO1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbn1cblxuYTpob3ZlciB7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7XG59XG5cbmJ1dHRvbiwgaW5wdXQge1xuICAgIGZvbnQ6IGluaGVyaXQ7XG4gICAgY29sb3I6IGluaGVyaXQ7XG59XG5cbjpmb2N1cy12aXNpYmxlIHtcbiAgICBvdXRsaW5lOiAycHggc29saWQgdmFyKC0tcHJpbWFyeSk7XG4gICAgb3V0bGluZS1vZmZzZXQ6IDJweDtcbn1cblxuW2hpZGRlbl0ge1xuICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbn1cblxuLyogVG9wIGJhciAqL1xuXG4udG9wYmFyIHtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcbiAgICBiYWNrZ3JvdW5kOiB2YXIoLS1zdXJmYWNlKTtcbn1cblxuLnRvcGJhci1pbm5lciB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICBnYXA6IDE2cHg7XG4gICAgbWF4LXdpZHRoOiAxMDgwcHg7XG4gICAgbWFyZ2luOiAwIGF1dG87XG4gICAgcGFkZGluZzogMTJweCAyMHB4O1xufVxuXG4uYnJhbmQge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDEwcHg7XG4gICAgY29sb3I6IHZhcigtLXRleHQpO1xuICAgIGZvbnQtd2VpZ2h0OiA2NTA7XG4gICAgZm9udC1zaXplOiAxLjFyZW07XG59XG5cbi5icmFuZDpob3ZlciB7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xufVxuXG4uYnJhbmQtc3ViIHtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG4gICAgZm9udC13ZWlnaHQ6IDQwMDtcbn1cblxuLnRvcGJhci1saW5rcyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBnYXA6IDIwcHg7XG4gICAgZm9udC1zaXplOiAwLjkycmVtO1xufVxuXG4udG9wYmFyLWxpbmtzIGEge1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbn1cblxuLnRvcGJhci1saW5rcyBhOmhvdmVyIHtcbiAgICBjb2xvcjogdmFyKC0tdGV4dCk7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xufVxuXG4vKiBQYWdlICovXG5cbm1haW4ge1xuICAgIG1heC13aWR0aDogMTA4MHB4O1xuICAgIG1hcmdpbjogMCBhdXRvO1xuICAgIHBhZGRpbmc6IDM2cHggMjBweCA2NHB4O1xufVxuXG4uaW50cm8ge1xuICAgIG1hcmdpbi1ib3R0b206IDI4cHg7XG59XG5cbi5pbnRybyBoMSB7XG4gICAgbWFyZ2luOiAwIDAgNnB4O1xuICAgIGZvbnQtc2l6ZTogY2xhbXAoMS42cmVtLCAzLjV2dywgMi4xcmVtKTtcbiAgICBsaW5lLWhlaWdodDogMS4yO1xuICAgIGxldHRlci1zcGFjaW5nOiAtMC4wMmVtO1xufVxuXG4uaW50cm8gcCB7XG4gICAgbWFyZ2luOiAwO1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbn1cblxuLmxheW91dCB7XG4gICAgZGlzcGxheTogZ3JpZDtcbiAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IG1pbm1heCgwLCAxZnIpIG1pbm1heCgwLCAxZnIpO1xuICAgIGdhcDogMjBweDtcbiAgICBhbGlnbi1pdGVtczogc3RhcnQ7XG59XG5cbi5jYXJkIHtcbiAgICBiYWNrZ3JvdW5kOiB2YXIoLS1zdXJmYWNlKTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cyk7XG4gICAgYm94LXNoYWRvdzogdmFyKC0tc2hhZG93KTtcbiAgICBwYWRkaW5nOiAyMnB4O1xufVxuXG4jRGV0YWlscyB7XG4gICAgcG9zaXRpb246IHN0aWNreTtcbiAgICB0b3A6IDIwcHg7XG59XG5cbi5jYXJkIGgyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAxMHB4O1xuICAgIG1hcmdpbjogMCAwIDE4cHg7XG4gICAgZm9udC1zaXplOiAxLjA1cmVtO1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG59XG5cbi5zdGVwIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtZ3JpZDtcbiAgICBwbGFjZS1pdGVtczogY2VudGVyO1xuICAgIHdpZHRoOiAyNnB4O1xuICAgIGhlaWdodDogMjZweDtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeS1zb2Z0KTtcbiAgICBjb2xvcjogdmFyKC0tcHJpbWFyeSk7XG4gICAgZm9udC1zaXplOiAwLjg1cmVtO1xuICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG59XG5cbi8qIFNlYXJjaCAqL1xuXG4uc2VhcmNoIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5zZWFyY2ggc3ZnIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiA1MCU7XG4gICAgbGVmdDogMTNweDtcbiAgICB3aWR0aDogMThweDtcbiAgICBoZWlnaHQ6IDE4cHg7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC01MCUpO1xuICAgIGZpbGw6IG5vbmU7XG4gICAgc3Ryb2tlOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgICBzdHJva2Utd2lkdGg6IDI7XG4gICAgc3Ryb2tlLWxpbmVjYXA6IHJvdW5kO1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuXG4uc2VhcmNoIGlucHV0IHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwYWRkaW5nOiAxMXB4IDE0cHggMTFweCA0MHB4O1xuICAgIGJhY2tncm91bmQ6IHZhcigtLXN1cmZhY2UtcmFpc2VkKTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1zbWFsbCk7XG59XG5cbi5zZWFyY2ggaW5wdXQ6OnBsYWNlaG9sZGVyIHtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG59XG5cbi5zZWFyY2ggaW5wdXQ6Zm9jdXMge1xuICAgIG91dGxpbmU6IG5vbmU7XG4gICAgYm9yZGVyLWNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcbiAgICBib3gtc2hhZG93OiAwIDAgMCAzcHggdmFyKC0tcHJpbWFyeS1zb2Z0KTtcbn1cblxuLmxpc3Qtc3RhdHVzIHtcbiAgICBtYXJnaW46IDEycHggMnB4IDhweDtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG4gICAgZm9udC1zaXplOiAwLjg1cmVtO1xufVxuXG4vKiBEZXZpY2UgbGlzdCAqL1xuXG4uZGV2aWNlLWxpc3Qge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDJweDtcbiAgICBtYXgtaGVpZ2h0OiBtaW4oNTZ2aCwgNTIwcHgpO1xuICAgIG1hcmdpbjogMCAtOHB4O1xuICAgIHBhZGRpbmc6IDAgOHB4O1xuICAgIG92ZXJmbG93LXk6IGF1dG87XG4gICAgbGlzdC1zdHlsZTogbm9uZTtcbiAgICBzY3JvbGxiYXItd2lkdGg6IHRoaW47XG4gICAgc2Nyb2xsYmFyLWNvbG9yOiB2YXIoLS1ib3JkZXIpIHRyYW5zcGFyZW50O1xufVxuXG4uZGV2aWNlIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiA4cHg7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgcGFkZGluZzogNnB4IDEycHg7XG4gICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtc21hbGwpO1xuICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG4uZGV2aWNlOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kOiB2YXIoLS1zdXJmYWNlLXJhaXNlZCk7XG59XG5cbi5kZXZpY2VbYXJpYS1wcmVzc2VkPVwidHJ1ZVwiXSB7XG4gICAgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeS1zb2Z0KTtcbiAgICBib3JkZXItY29sb3I6IHZhcigtLXByaW1hcnkpO1xufVxuXG4uZGV2aWNlLXRleHQge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBmbGV4OiAxO1xuICAgIG1pbi13aWR0aDogMDtcbn1cblxuLmRldmljZS12ZW5kb3Ige1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgICBmb250LXNpemU6IDAuNzZyZW07XG4gICAgbGluZS1oZWlnaHQ6IDEuMztcbn1cblxuLmRldmljZS1uYW1lIHtcbiAgICBmb250LXdlaWdodDogNTAwO1xuICAgIG92ZXJmbG93LXdyYXA6IGFueXdoZXJlO1xufVxuXG4uYmFkZ2Uge1xuICAgIGZsZXgtc2hyaW5rOiAwO1xuICAgIHBhZGRpbmc6IDJweCA4cHg7XG4gICAgYm9yZGVyLXJhZGl1czogOTk5cHg7XG4gICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuXG4uYmFkZ2UtYWNjZW50IHtcbiAgICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tc2Vjb25kYXJ5KSAxNiUsIHRyYW5zcGFyZW50KTtcbiAgICBjb2xvcjogdmFyKC0tc2Vjb25kYXJ5KTtcbn1cblxuLmJhZGdlLW11dGVkIHtcbiAgICBiYWNrZ3JvdW5kOiB2YXIoLS1zdXJmYWNlLXJhaXNlZCk7XG4gICAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xufVxuXG4uYmFkZ2Utd2FybmluZyB7XG4gICAgYmFja2dyb3VuZDogdmFyKC0td2FybmluZy1zb2Z0KTtcbiAgICBjb2xvcjogdmFyKC0td2FybmluZyk7XG59XG5cbi8qIERldGFpbHMgKi9cblxuLmVtcHR5IHtcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMzZweCAwO1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG59XG5cbi5zZWxlY3RlZC1kZXZpY2Uge1xuICAgIG1hcmdpbi1ib3R0b206IDE4cHg7XG59XG5cbi5zZWxlY3RlZC12ZW5kb3Ige1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgICBmb250LXNpemU6IDAuODVyZW07XG59XG5cbi5zZWxlY3RlZC1uYW1lIHtcbiAgICBmb250LXNpemU6IDEuMzVyZW07XG4gICAgZm9udC13ZWlnaHQ6IDY1MDtcbiAgICBsaW5lLWhlaWdodDogMS4yNTtcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTtcbn1cblxuLnNlZ21lbnRlZCB7XG4gICAgZGlzcGxheTogZ3JpZDtcbiAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDFmciAxZnI7XG4gICAgZ2FwOiA0cHg7XG4gICAgcGFkZGluZzogNHB4O1xuICAgIGJhY2tncm91bmQ6IHZhcigtLXN1cmZhY2UtcmFpc2VkKTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1zbWFsbCk7XG59XG5cbi5zZWdtZW50IHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG4uc2VnbWVudCBpbnB1dCB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGluc2V0OiAwO1xuICAgIG1hcmdpbjogMDtcbiAgICBvcGFjaXR5OiAwO1xuICAgIGN1cnNvcjogaW5oZXJpdDtcbn1cblxuLnNlZ21lbnQtYm9keSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgcGFkZGluZzogN3B4IDEwcHg7XG4gICAgYm9yZGVyLXJhZGl1czogNnB4O1xufVxuXG4uc2VnbWVudC10aXRsZSB7XG4gICAgZm9udC13ZWlnaHQ6IDYwMDtcbn1cblxuLnNlZ21lbnQtc3ViIHtcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XG4gICAgZm9udC1zaXplOiAwLjc4cmVtO1xufVxuXG4uc2VnbWVudCBpbnB1dDpjaGVja2VkICsgLnNlZ21lbnQtYm9keSB7XG4gICAgYmFja2dyb3VuZDogdmFyKC0tc3VyZmFjZSk7XG4gICAgYm94LXNoYWRvdzogMCAxcHggNHB4IHJnYmEoMCwgMCwgMCwgMC4yNSksIGluc2V0IDAgMCAwIDFweCB2YXIoLS1wcmltYXJ5KTtcbn1cblxuLnNlZ21lbnQgaW5wdXQ6Y2hlY2tlZCArIC5zZWdtZW50LWJvZHkgLnNlZ21lbnQtdGl0bGUge1xuICAgIGNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcbn1cblxuLnNlZ21lbnQgaW5wdXQ6Zm9jdXMtdmlzaWJsZSArIC5zZWdtZW50LWJvZHkge1xuICAgIG91dGxpbmU6IDJweCBzb2xpZCB2YXIoLS1wcmltYXJ5KTtcbiAgICBvdXRsaW5lLW9mZnNldDogMnB4O1xufVxuXG4uc2VnbWVudDpoYXMoaW5wdXQ6ZGlzYWJsZWQpIHtcbiAgICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xuICAgIG9wYWNpdHk6IDAuNDU7XG59XG5cbi5idWlsZC1kZXRhaWxzIHtcbiAgICBtaW4taGVpZ2h0OiAxLjNlbTtcbiAgICBtYXJnaW46IDEwcHggMnB4IDE2cHg7XG4gICAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xuICAgIGZvbnQtc2l6ZTogMC44MnJlbTtcbn1cblxuLyogTm90aWNlcyAqL1xuXG4ubm90aWNlIHtcbiAgICBtYXJnaW4tYm90dG9tOiAxMnB4O1xuICAgIHBhZGRpbmc6IDEycHggMTRweDtcbiAgICBib3JkZXItbGVmdDogM3B4IHNvbGlkIHZhcigtLXByaW1hcnkpO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1zbWFsbCk7XG4gICAgYmFja2dyb3VuZDogdmFyKC0tcHJpbWFyeS1zb2Z0KTtcbiAgICBmb250LXNpemU6IDAuOTJyZW07XG59XG5cbi5ub3RpY2Utd2FybmluZyB7XG4gICAgYm9yZGVyLWxlZnQtY29sb3I6IHZhcigtLXdhcm5pbmcpO1xuICAgIGJhY2tncm91bmQ6IHZhcigtLXdhcm5pbmctc29mdCk7XG59XG5cbm1haW4gPiAubm90aWNlIHtcbiAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xufVxuXG4vKiBCdXR0b25zICovXG5cbmVzcC13ZWItaW5zdGFsbC1idXR0b24ge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIG1hcmdpbi10b3A6IDE4cHg7XG59XG5cbi5idXR0b24tcHJpbWFyeSB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgcGFkZGluZzogMTJweCAyMHB4O1xuICAgIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnkpO1xuICAgIGJvcmRlcjogMDtcbiAgICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtc21hbGwpO1xuICAgIGNvbG9yOiB2YXIoLS1wcmltYXJ5LWNvbnRyYXN0KTtcbiAgICBmb250LXdlaWdodDogNjUwO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB0cmFuc2l0aW9uOiBmaWx0ZXIgMC4xNXMsIHRyYW5zZm9ybSAwLjA1cztcbn1cblxuLmJ1dHRvbi1wcmltYXJ5OmhvdmVyIHtcbiAgICBmaWx0ZXI6IGJyaWdodG5lc3MoMS4wOCk7XG59XG5cbi5idXR0b24tcHJpbWFyeTphY3RpdmUge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgxcHgpO1xufVxuXG4uYnV0dG9uLWxpbmsge1xuICAgIHBhZGRpbmc6IDA7XG4gICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICBib3JkZXI6IDA7XG4gICAgY29sb3I6IHZhcigtLXByaW1hcnkpO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLmJ1dHRvbi1saW5rOmhvdmVyIHtcbiAgICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTtcbn1cblxuLmluc3RhbGwtZmFsbGJhY2sge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgICBmb250LXNpemU6IDAuOTJyZW07XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xufVxuXG5AbWVkaWEgKG1heC13aWR0aDogODIwcHgpIHtcbiAgICAubGF5b3V0IHtcbiAgICAgICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBtaW5tYXgoMCwgMWZyKTtcbiAgICB9XG5cbiAgICAjRGV0YWlscyB7XG4gICAgICAgIHBvc2l0aW9uOiBzdGF0aWM7XG4gICAgfVxuXG4gICAgLmRldmljZS1saXN0IHtcbiAgICAgICAgbWF4LWhlaWdodDogNDR2aDtcbiAgICB9XG5cbiAgICAudG9wYmFyLWxpbmtzIGE6Zmlyc3QtY2hpbGQge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbn1cbmAsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vc3JjL2FwcC5jc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7SUFDSSxrQkFBa0I7SUFDbEIsYUFBYTtJQUNiLGtCQUFrQjtJQUNsQix5QkFBeUI7SUFDekIsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixxQkFBcUI7SUFDckIsa0JBQWtCO0lBQ2xCLDJCQUEyQjtJQUMzQix3Q0FBd0M7SUFDeEMsb0JBQW9CO0lBQ3BCLGtCQUFrQjtJQUNsQix3Q0FBd0M7SUFDeEMsY0FBYztJQUNkLG1CQUFtQjtJQUNuQix5Q0FBeUM7QUFDN0M7O0FBRUE7SUFDSTtRQUNJLG1CQUFtQjtRQUNuQixhQUFhO1FBQ2Isa0JBQWtCO1FBQ2xCLHlCQUF5QjtRQUN6QixpQkFBaUI7UUFDakIsZUFBZTtRQUNmLHFCQUFxQjtRQUNyQixrQkFBa0I7UUFDbEIsMkJBQTJCO1FB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SSxnQkFBZ0I7SUFDcEI7O0lBRUE7UUFDSSxnQkFBZ0I7SUFDcEI7O0lBRUE7UUFDSSxhQUFhO0lBQ2pCO0FBQ0pcIixcInNvdXJjZXNDb250ZW50XCI6W1wiOnJvb3Qge1xcbiAgICBjb2xvci1zY2hlbWU6IGRhcms7XFxuICAgIC0tYmc6ICMxNzE4MWY7XFxuICAgIC0tc3VyZmFjZTogIzIxMjIyYjtcXG4gICAgLS1zdXJmYWNlLXJhaXNlZDogIzJhMmMzNztcXG4gICAgLS1ib3JkZXI6ICMzNjM4NDY7XFxuICAgIC0tdGV4dDogI2U4ZTlmMDtcXG4gICAgLS10ZXh0LW11dGVkOiAjOWE5ZGIwO1xcbiAgICAtLXByaW1hcnk6ICMzM2JiZmY7XFxuICAgIC0tcHJpbWFyeS1jb250cmFzdDogIzA2MjAyZTtcXG4gICAgLS1wcmltYXJ5LXNvZnQ6IHJnYmEoNTEsIDE4NywgMjU1LCAwLjE0KTtcXG4gICAgLS1zZWNvbmRhcnk6ICNlZTgxYzM7XFxuICAgIC0td2FybmluZzogI2Y1Yjg0YTtcXG4gICAgLS13YXJuaW5nLXNvZnQ6IHJnYmEoMjQ1LCAxODQsIDc0LCAwLjEzKTtcXG4gICAgLS1yYWRpdXM6IDE0cHg7XFxuICAgIC0tcmFkaXVzLXNtYWxsOiA5cHg7XFxuICAgIC0tc2hhZG93OiAwIDEycHggMzJweCByZ2JhKDAsIDAsIDAsIDAuMjgpO1xcbn1cXG5cXG5AbWVkaWEgKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkge1xcbiAgICA6cm9vdCB7XFxuICAgICAgICBjb2xvci1zY2hlbWU6IGxpZ2h0O1xcbiAgICAgICAgLS1iZzogI2YzZjRmODtcXG4gICAgICAgIC0tc3VyZmFjZTogI2ZmZmZmZjtcXG4gICAgICAgIC0tc3VyZmFjZS1yYWlzZWQ6ICNmMGYxZjY7XFxuICAgICAgICAtLWJvcmRlcjogI2RjZGVlODtcXG4gICAgICAgIC0tdGV4dDogIzFjMWQyNjtcXG4gICAgICAgIC0tdGV4dC1tdXRlZDogIzYyNjU3YTtcXG4gICAgICAgIC0tcHJpbWFyeTogIzBiODRjNjtcXG4gICAgICAgIC0tcHJpbWFyeS1jb250cmFzdDogI2ZmZmZmZjtcXG4gICAgICAgIC0tcHJpbWFyeS1zb2Z0OiByZ2JhKDExLCAxMzIsIDE5OCwgMC4xMSk7XFxuICAgICAgICAtLXNlY29uZGFyeTogI2MyNDA4ZjtcXG4gICAgICAgIC0td2FybmluZzogI2E4NmEwMDtcXG4gICAgICAgIC0td2FybmluZy1zb2Z0OiByZ2JhKDIxNCwgMTQ0LCAxNiwgMC4xNCk7XFxuICAgICAgICAtLXNoYWRvdzogMCAxMHB4IDI4cHggcmdiYSgzMCwgMzQsIDYwLCAwLjA4KTtcXG4gICAgfVxcbn1cXG5cXG4qLCAqOjpiZWZvcmUsICo6OmFmdGVyIHtcXG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG59XFxuXFxuYm9keSB7XFxuICAgIG1hcmdpbjogMDtcXG4gICAgYmFja2dyb3VuZDogdmFyKC0tYmcpO1xcbiAgICBjb2xvcjogdmFyKC0tdGV4dCk7XFxuICAgIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWksIC1hcHBsZS1zeXN0ZW0sIFxcXCJTZWdvZSBVSVxcXCIsIFJvYm90bywgXFxcIkhlbHZldGljYSBOZXVlXFxcIiwgQXJpYWwsIHNhbnMtc2VyaWY7XFxuICAgIGZvbnQtc2l6ZTogMTZweDtcXG4gICAgbGluZS1oZWlnaHQ6IDEuNTtcXG4gICAgLXdlYmtpdC1mb250LXNtb290aGluZzogYW50aWFsaWFzZWQ7XFxufVxcblxcbmEge1xcbiAgICBjb2xvcjogdmFyKC0tcHJpbWFyeSk7XFxuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXG59XFxuXFxuYTpob3ZlciB7XFxuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xcbn1cXG5cXG5idXR0b24sIGlucHV0IHtcXG4gICAgZm9udDogaW5oZXJpdDtcXG4gICAgY29sb3I6IGluaGVyaXQ7XFxufVxcblxcbjpmb2N1cy12aXNpYmxlIHtcXG4gICAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLXByaW1hcnkpO1xcbiAgICBvdXRsaW5lLW9mZnNldDogMnB4O1xcbn1cXG5cXG5baGlkZGVuXSB7XFxuICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcXG59XFxuXFxuLyogVG9wIGJhciAqL1xcblxcbi50b3BiYXIge1xcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcXG4gICAgYmFja2dyb3VuZDogdmFyKC0tc3VyZmFjZSk7XFxufVxcblxcbi50b3BiYXItaW5uZXIge1xcbiAgICBkaXNwbGF5OiBmbGV4O1xcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XFxuICAgIGdhcDogMTZweDtcXG4gICAgbWF4LXdpZHRoOiAxMDgwcHg7XFxuICAgIG1hcmdpbjogMCBhdXRvO1xcbiAgICBwYWRkaW5nOiAxMnB4IDIwcHg7XFxufVxcblxcbi5icmFuZCB7XFxuICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuICAgIGdhcDogMTBweDtcXG4gICAgY29sb3I6IHZhcigtLXRleHQpO1xcbiAgICBmb250LXdlaWdodDogNjUwO1xcbiAgICBmb250LXNpemU6IDEuMXJlbTtcXG59XFxuXFxuLmJyYW5kOmhvdmVyIHtcXG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xcbn1cXG5cXG4uYnJhbmQtc3ViIHtcXG4gICAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xcbiAgICBmb250LXdlaWdodDogNDAwO1xcbn1cXG5cXG4udG9wYmFyLWxpbmtzIHtcXG4gICAgZGlzcGxheTogZmxleDtcXG4gICAgZ2FwOiAyMHB4O1xcbiAgICBmb250LXNpemU6IDAuOTJyZW07XFxufVxcblxcbi50b3BiYXItbGlua3MgYSB7XFxuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcXG59XFxuXFxuLnRvcGJhci1saW5rcyBhOmhvdmVyIHtcXG4gICAgY29sb3I6IHZhcigtLXRleHQpO1xcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XFxufVxcblxcbi8qIFBhZ2UgKi9cXG5cXG5tYWluIHtcXG4gICAgbWF4LXdpZHRoOiAxMDgwcHg7XFxuICAgIG1hcmdpbjogMCBhdXRvO1xcbiAgICBwYWRkaW5nOiAzNnB4IDIwcHggNjRweDtcXG59XFxuXFxuLmludHJvIHtcXG4gICAgbWFyZ2luLWJvdHRvbTogMjhweDtcXG59XFxuXFxuLmludHJvIGgxIHtcXG4gICAgbWFyZ2luOiAwIDAgNnB4O1xcbiAgICBmb250LXNpemU6IGNsYW1wKDEuNnJlbSwgMy41dncsIDIuMXJlbSk7XFxuICAgIGxpbmUtaGVpZ2h0OiAxLjI7XFxuICAgIGxldHRlci1zcGFjaW5nOiAtMC4wMmVtO1xcbn1cXG5cXG4uaW50cm8gcCB7XFxuICAgIG1hcmdpbjogMDtcXG4gICAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xcbn1cXG5cXG4ubGF5b3V0IHtcXG4gICAgZGlzcGxheTogZ3JpZDtcXG4gICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBtaW5tYXgoMCwgMWZyKSBtaW5tYXgoMCwgMWZyKTtcXG4gICAgZ2FwOiAyMHB4O1xcbiAgICBhbGlnbi1pdGVtczogc3RhcnQ7XFxufVxcblxcbi5jYXJkIHtcXG4gICAgYmFja2dyb3VuZDogdmFyKC0tc3VyZmFjZSk7XFxuICAgIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWJvcmRlcik7XFxuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cyk7XFxuICAgIGJveC1zaGFkb3c6IHZhcigtLXNoYWRvdyk7XFxuICAgIHBhZGRpbmc6IDIycHg7XFxufVxcblxcbiNEZXRhaWxzIHtcXG4gICAgcG9zaXRpb246IHN0aWNreTtcXG4gICAgdG9wOiAyMHB4O1xcbn1cXG5cXG4uY2FyZCBoMiB7XFxuICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuICAgIGdhcDogMTBweDtcXG4gICAgbWFyZ2luOiAwIDAgMThweDtcXG4gICAgZm9udC1zaXplOiAxLjA1cmVtO1xcbiAgICBmb250LXdlaWdodDogNjAwO1xcbn1cXG5cXG4uc3RlcCB7XFxuICAgIGRpc3BsYXk6IGlubGluZS1ncmlkO1xcbiAgICBwbGFjZS1pdGVtczogY2VudGVyO1xcbiAgICB3aWR0aDogMjZweDtcXG4gICAgaGVpZ2h0OiAyNnB4O1xcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XFxuICAgIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnktc29mdCk7XFxuICAgIGNvbG9yOiB2YXIoLS1wcmltYXJ5KTtcXG4gICAgZm9udC1zaXplOiAwLjg1cmVtO1xcbiAgICBmb250LXdlaWdodDogNzAwO1xcbn1cXG5cXG4vKiBTZWFyY2ggKi9cXG5cXG4uc2VhcmNoIHtcXG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xcbn1cXG5cXG4uc2VhcmNoIHN2ZyB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiA1MCU7XFxuICAgIGxlZnQ6IDEzcHg7XFxuICAgIHdpZHRoOiAxOHB4O1xcbiAgICBoZWlnaHQ6IDE4cHg7XFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXG4gICAgZmlsbDogbm9uZTtcXG4gICAgc3Ryb2tlOiB2YXIoLS10ZXh0LW11dGVkKTtcXG4gICAgc3Ryb2tlLXdpZHRoOiAyO1xcbiAgICBzdHJva2UtbGluZWNhcDogcm91bmQ7XFxuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xcbn1cXG5cXG4uc2VhcmNoIGlucHV0IHtcXG4gICAgd2lkdGg6IDEwMCU7XFxuICAgIHBhZGRpbmc6IDExcHggMTRweCAxMXB4IDQwcHg7XFxuICAgIGJhY2tncm91bmQ6IHZhcigtLXN1cmZhY2UtcmFpc2VkKTtcXG4gICAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tYm9yZGVyKTtcXG4gICAgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzLXNtYWxsKTtcXG59XFxuXFxuLnNlYXJjaCBpbnB1dDo6cGxhY2Vob2xkZXIge1xcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XFxufVxcblxcbi5zZWFyY2ggaW5wdXQ6Zm9jdXMge1xcbiAgICBvdXRsaW5lOiBub25lO1xcbiAgICBib3JkZXItY29sb3I6IHZhcigtLXByaW1hcnkpO1xcbiAgICBib3gtc2hhZG93OiAwIDAgMCAzcHggdmFyKC0tcHJpbWFyeS1zb2Z0KTtcXG59XFxuXFxuLmxpc3Qtc3RhdHVzIHtcXG4gICAgbWFyZ2luOiAxMnB4IDJweCA4cHg7XFxuICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcXG4gICAgZm9udC1zaXplOiAwLjg1cmVtO1xcbn1cXG5cXG4vKiBEZXZpY2UgbGlzdCAqL1xcblxcbi5kZXZpY2UtbGlzdCB7XFxuICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgIGdhcDogMnB4O1xcbiAgICBtYXgtaGVpZ2h0OiBtaW4oNTZ2aCwgNTIwcHgpO1xcbiAgICBtYXJnaW46IDAgLThweDtcXG4gICAgcGFkZGluZzogMCA4cHg7XFxuICAgIG92ZXJmbG93LXk6IGF1dG87XFxuICAgIGxpc3Qtc3R5bGU6IG5vbmU7XFxuICAgIHNjcm9sbGJhci13aWR0aDogdGhpbjtcXG4gICAgc2Nyb2xsYmFyLWNvbG9yOiB2YXIoLS1ib3JkZXIpIHRyYW5zcGFyZW50O1xcbn1cXG5cXG4uZGV2aWNlIHtcXG4gICAgZGlzcGxheTogZmxleDtcXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gICAgZ2FwOiA4cHg7XFxuICAgIHdpZHRoOiAxMDAlO1xcbiAgICBwYWRkaW5nOiA2cHggMTJweDtcXG4gICAgYmFja2dyb3VuZDogbm9uZTtcXG4gICAgYm9yZGVyOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7XFxuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1zbWFsbCk7XFxuICAgIHRleHQtYWxpZ246IGxlZnQ7XFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuXFxuLmRldmljZTpob3ZlciB7XFxuICAgIGJhY2tncm91bmQ6IHZhcigtLXN1cmZhY2UtcmFpc2VkKTtcXG59XFxuXFxuLmRldmljZVthcmlhLXByZXNzZWQ9XFxcInRydWVcXFwiXSB7XFxuICAgIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnktc29mdCk7XFxuICAgIGJvcmRlci1jb2xvcjogdmFyKC0tcHJpbWFyeSk7XFxufVxcblxcbi5kZXZpY2UtdGV4dCB7XFxuICAgIGRpc3BsYXk6IGZsZXg7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgIGZsZXg6IDE7XFxuICAgIG1pbi13aWR0aDogMDtcXG59XFxuXFxuLmRldmljZS12ZW5kb3Ige1xcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XFxuICAgIGZvbnQtc2l6ZTogMC43NnJlbTtcXG4gICAgbGluZS1oZWlnaHQ6IDEuMztcXG59XFxuXFxuLmRldmljZS1uYW1lIHtcXG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcXG4gICAgb3ZlcmZsb3ctd3JhcDogYW55d2hlcmU7XFxufVxcblxcbi5iYWRnZSB7XFxuICAgIGZsZXgtc2hyaW5rOiAwO1xcbiAgICBwYWRkaW5nOiAycHggOHB4O1xcbiAgICBib3JkZXItcmFkaXVzOiA5OTlweDtcXG4gICAgZm9udC1zaXplOiAwLjdyZW07XFxuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XFxuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxufVxcblxcbi5iYWRnZS1hY2NlbnQge1xcbiAgICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tc2Vjb25kYXJ5KSAxNiUsIHRyYW5zcGFyZW50KTtcXG4gICAgY29sb3I6IHZhcigtLXNlY29uZGFyeSk7XFxufVxcblxcbi5iYWRnZS1tdXRlZCB7XFxuICAgIGJhY2tncm91bmQ6IHZhcigtLXN1cmZhY2UtcmFpc2VkKTtcXG4gICAgY29sb3I6IHZhcigtLXRleHQtbXV0ZWQpO1xcbn1cXG5cXG4uYmFkZ2Utd2FybmluZyB7XFxuICAgIGJhY2tncm91bmQ6IHZhcigtLXdhcm5pbmctc29mdCk7XFxuICAgIGNvbG9yOiB2YXIoLS13YXJuaW5nKTtcXG59XFxuXFxuLyogRGV0YWlscyAqL1xcblxcbi5lbXB0eSB7XFxuICAgIG1hcmdpbjogMDtcXG4gICAgcGFkZGluZzogMzZweCAwO1xcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XFxuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcXG59XFxuXFxuLnNlbGVjdGVkLWRldmljZSB7XFxuICAgIG1hcmdpbi1ib3R0b206IDE4cHg7XFxufVxcblxcbi5zZWxlY3RlZC12ZW5kb3Ige1xcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XFxuICAgIGZvbnQtc2l6ZTogMC44NXJlbTtcXG59XFxuXFxuLnNlbGVjdGVkLW5hbWUge1xcbiAgICBmb250LXNpemU6IDEuMzVyZW07XFxuICAgIGZvbnQtd2VpZ2h0OiA2NTA7XFxuICAgIGxpbmUtaGVpZ2h0OiAxLjI1O1xcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTtcXG59XFxuXFxuLnNlZ21lbnRlZCB7XFxuICAgIGRpc3BsYXk6IGdyaWQ7XFxuICAgIGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjtcXG4gICAgZ2FwOiA0cHg7XFxuICAgIHBhZGRpbmc6IDRweDtcXG4gICAgYmFja2dyb3VuZDogdmFyKC0tc3VyZmFjZS1yYWlzZWQpO1xcbiAgICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZXIpO1xcbiAgICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtc21hbGwpO1xcbn1cXG5cXG4uc2VnbWVudCB7XFxuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG5cXG4uc2VnbWVudCBpbnB1dCB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgaW5zZXQ6IDA7XFxuICAgIG1hcmdpbjogMDtcXG4gICAgb3BhY2l0eTogMDtcXG4gICAgY3Vyc29yOiBpbmhlcml0O1xcbn1cXG5cXG4uc2VnbWVudC1ib2R5IHtcXG4gICAgZGlzcGxheTogZmxleDtcXG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gICAgcGFkZGluZzogN3B4IDEwcHg7XFxuICAgIGJvcmRlci1yYWRpdXM6IDZweDtcXG59XFxuXFxuLnNlZ21lbnQtdGl0bGUge1xcbiAgICBmb250LXdlaWdodDogNjAwO1xcbn1cXG5cXG4uc2VnbWVudC1zdWIge1xcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XFxuICAgIGZvbnQtc2l6ZTogMC43OHJlbTtcXG59XFxuXFxuLnNlZ21lbnQgaW5wdXQ6Y2hlY2tlZCArIC5zZWdtZW50LWJvZHkge1xcbiAgICBiYWNrZ3JvdW5kOiB2YXIoLS1zdXJmYWNlKTtcXG4gICAgYm94LXNoYWRvdzogMCAxcHggNHB4IHJnYmEoMCwgMCwgMCwgMC4yNSksIGluc2V0IDAgMCAwIDFweCB2YXIoLS1wcmltYXJ5KTtcXG59XFxuXFxuLnNlZ21lbnQgaW5wdXQ6Y2hlY2tlZCArIC5zZWdtZW50LWJvZHkgLnNlZ21lbnQtdGl0bGUge1xcbiAgICBjb2xvcjogdmFyKC0tcHJpbWFyeSk7XFxufVxcblxcbi5zZWdtZW50IGlucHV0OmZvY3VzLXZpc2libGUgKyAuc2VnbWVudC1ib2R5IHtcXG4gICAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLXByaW1hcnkpO1xcbiAgICBvdXRsaW5lLW9mZnNldDogMnB4O1xcbn1cXG5cXG4uc2VnbWVudDpoYXMoaW5wdXQ6ZGlzYWJsZWQpIHtcXG4gICAgY3Vyc29yOiBub3QtYWxsb3dlZDtcXG4gICAgb3BhY2l0eTogMC40NTtcXG59XFxuXFxuLmJ1aWxkLWRldGFpbHMge1xcbiAgICBtaW4taGVpZ2h0OiAxLjNlbTtcXG4gICAgbWFyZ2luOiAxMHB4IDJweCAxNnB4O1xcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XFxuICAgIGZvbnQtc2l6ZTogMC44MnJlbTtcXG59XFxuXFxuLyogTm90aWNlcyAqL1xcblxcbi5ub3RpY2Uge1xcbiAgICBtYXJnaW4tYm90dG9tOiAxMnB4O1xcbiAgICBwYWRkaW5nOiAxMnB4IDE0cHg7XFxuICAgIGJvcmRlci1sZWZ0OiAzcHggc29saWQgdmFyKC0tcHJpbWFyeSk7XFxuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1zbWFsbCk7XFxuICAgIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnktc29mdCk7XFxuICAgIGZvbnQtc2l6ZTogMC45MnJlbTtcXG59XFxuXFxuLm5vdGljZS13YXJuaW5nIHtcXG4gICAgYm9yZGVyLWxlZnQtY29sb3I6IHZhcigtLXdhcm5pbmcpO1xcbiAgICBiYWNrZ3JvdW5kOiB2YXIoLS13YXJuaW5nLXNvZnQpO1xcbn1cXG5cXG5tYWluID4gLm5vdGljZSB7XFxuICAgIG1hcmdpbi1ib3R0b206IDIwcHg7XFxufVxcblxcbi8qIEJ1dHRvbnMgKi9cXG5cXG5lc3Atd2ViLWluc3RhbGwtYnV0dG9uIHtcXG4gICAgZGlzcGxheTogYmxvY2s7XFxuICAgIG1hcmdpbi10b3A6IDE4cHg7XFxufVxcblxcbi5idXR0b24tcHJpbWFyeSB7XFxuICAgIHdpZHRoOiAxMDAlO1xcbiAgICBwYWRkaW5nOiAxMnB4IDIwcHg7XFxuICAgIGJhY2tncm91bmQ6IHZhcigtLXByaW1hcnkpO1xcbiAgICBib3JkZXI6IDA7XFxuICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1zbWFsbCk7XFxuICAgIGNvbG9yOiB2YXIoLS1wcmltYXJ5LWNvbnRyYXN0KTtcXG4gICAgZm9udC13ZWlnaHQ6IDY1MDtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbiAgICB0cmFuc2l0aW9uOiBmaWx0ZXIgMC4xNXMsIHRyYW5zZm9ybSAwLjA1cztcXG59XFxuXFxuLmJ1dHRvbi1wcmltYXJ5OmhvdmVyIHtcXG4gICAgZmlsdGVyOiBicmlnaHRuZXNzKDEuMDgpO1xcbn1cXG5cXG4uYnV0dG9uLXByaW1hcnk6YWN0aXZlIHtcXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDFweCk7XFxufVxcblxcbi5idXR0b24tbGluayB7XFxuICAgIHBhZGRpbmc6IDA7XFxuICAgIGJhY2tncm91bmQ6IG5vbmU7XFxuICAgIGJvcmRlcjogMDtcXG4gICAgY29sb3I6IHZhcigtLXByaW1hcnkpO1xcbiAgICBjdXJzb3I6IHBvaW50ZXI7XFxufVxcblxcbi5idXR0b24tbGluazpob3ZlciB7XFxuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xcbn1cXG5cXG4uaW5zdGFsbC1mYWxsYmFjayB7XFxuICAgIGRpc3BsYXk6IGJsb2NrO1xcbiAgICBjb2xvcjogdmFyKC0tdGV4dC1tdXRlZCk7XFxuICAgIGZvbnQtc2l6ZTogMC45MnJlbTtcXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xcbn1cXG5cXG5AbWVkaWEgKG1heC13aWR0aDogODIwcHgpIHtcXG4gICAgLmxheW91dCB7XFxuICAgICAgICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IG1pbm1heCgwLCAxZnIpO1xcbiAgICB9XFxuXFxuICAgICNEZXRhaWxzIHtcXG4gICAgICAgIHBvc2l0aW9uOiBzdGF0aWM7XFxuICAgIH1cXG5cXG4gICAgLmRldmljZS1saXN0IHtcXG4gICAgICAgIG1heC1oZWlnaHQ6IDQ0dmg7XFxuICAgIH1cXG5cXG4gICAgLnRvcGJhci1saW5rcyBhOmZpcnN0LWNoaWxkIHtcXG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XFxuICAgIH1cXG59XFxuXCJdLFwic291cmNlUm9vdFwiOlwiXCJ9XSk7XG4vLyBFeHBvcnRzXG5leHBvcnQgZGVmYXVsdCBfX19DU1NfTE9BREVSX0VYUE9SVF9fXztcbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vKlxuICBNSVQgTGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuICBBdXRob3IgVG9iaWFzIEtvcHBlcnMgQHNva3JhXG4qL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3NzV2l0aE1hcHBpbmdUb1N0cmluZykge1xuICB2YXIgbGlzdCA9IFtdO1xuXG4gIC8vIHJldHVybiB0aGUgbGlzdCBvZiBtb2R1bGVzIGFzIGNzcyBzdHJpbmdcbiAgbGlzdC50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgdmFyIGNvbnRlbnQgPSBcIlwiO1xuICAgICAgdmFyIG5lZWRMYXllciA9IHR5cGVvZiBpdGVtWzVdICE9PSBcInVuZGVmaW5lZFwiO1xuICAgICAgaWYgKGl0ZW1bNF0pIHtcbiAgICAgICAgY29udGVudCArPSBcIkBzdXBwb3J0cyAoXCIuY29uY2F0KGl0ZW1bNF0sIFwiKSB7XCIpO1xuICAgICAgfVxuICAgICAgaWYgKGl0ZW1bMl0pIHtcbiAgICAgICAgY29udGVudCArPSBcIkBtZWRpYSBcIi5jb25jYXQoaXRlbVsyXSwgXCIge1wiKTtcbiAgICAgIH1cbiAgICAgIGlmIChuZWVkTGF5ZXIpIHtcbiAgICAgICAgY29udGVudCArPSBcIkBsYXllclwiLmNvbmNhdChpdGVtWzVdLmxlbmd0aCA+IDAgPyBcIiBcIi5jb25jYXQoaXRlbVs1XSkgOiBcIlwiLCBcIiB7XCIpO1xuICAgICAgfVxuICAgICAgY29udGVudCArPSBjc3NXaXRoTWFwcGluZ1RvU3RyaW5nKGl0ZW0pO1xuICAgICAgaWYgKG5lZWRMYXllcikge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuICAgICAgaWYgKGl0ZW1bMl0pIHtcbiAgICAgICAgY29udGVudCArPSBcIn1cIjtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVtWzRdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJ9XCI7XG4gICAgICB9XG4gICAgICByZXR1cm4gY29udGVudDtcbiAgICB9KS5qb2luKFwiXCIpO1xuICB9O1xuXG4gIC8vIGltcG9ydCBhIGxpc3Qgb2YgbW9kdWxlcyBpbnRvIHRoZSBsaXN0XG4gIGxpc3QuaSA9IGZ1bmN0aW9uIGkobW9kdWxlcywgbWVkaWEsIGRlZHVwZSwgc3VwcG9ydHMsIGxheWVyKSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGVzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBtb2R1bGVzID0gW1tudWxsLCBtb2R1bGVzLCB1bmRlZmluZWRdXTtcbiAgICB9XG4gICAgdmFyIGFscmVhZHlJbXBvcnRlZE1vZHVsZXMgPSB7fTtcbiAgICBpZiAoZGVkdXBlKSB7XG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IHRoaXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgdmFyIGlkID0gdGhpc1trXVswXTtcbiAgICAgICAgaWYgKGlkICE9IG51bGwpIHtcbiAgICAgICAgICBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2lkXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZm9yICh2YXIgX2sgPSAwOyBfayA8IG1vZHVsZXMubGVuZ3RoOyBfaysrKSB7XG4gICAgICB2YXIgaXRlbSA9IFtdLmNvbmNhdChtb2R1bGVzW19rXSk7XG4gICAgICBpZiAoZGVkdXBlICYmIGFscmVhZHlJbXBvcnRlZE1vZHVsZXNbaXRlbVswXV0pIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGxheWVyICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIGlmICh0eXBlb2YgaXRlbVs1XSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgIGl0ZW1bNV0gPSBsYXllcjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpdGVtWzFdID0gXCJAbGF5ZXJcIi5jb25jYXQoaXRlbVs1XS5sZW5ndGggPiAwID8gXCIgXCIuY29uY2F0KGl0ZW1bNV0pIDogXCJcIiwgXCIge1wiKS5jb25jYXQoaXRlbVsxXSwgXCJ9XCIpO1xuICAgICAgICAgIGl0ZW1bNV0gPSBsYXllcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1lZGlhKSB7XG4gICAgICAgIGlmICghaXRlbVsyXSkge1xuICAgICAgICAgIGl0ZW1bMl0gPSBtZWRpYTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpdGVtWzFdID0gXCJAbWVkaWEgXCIuY29uY2F0KGl0ZW1bMl0sIFwiIHtcIikuY29uY2F0KGl0ZW1bMV0sIFwifVwiKTtcbiAgICAgICAgICBpdGVtWzJdID0gbWVkaWE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChzdXBwb3J0cykge1xuICAgICAgICBpZiAoIWl0ZW1bNF0pIHtcbiAgICAgICAgICBpdGVtWzRdID0gXCJcIi5jb25jYXQoc3VwcG9ydHMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW1bMV0gPSBcIkBzdXBwb3J0cyAoXCIuY29uY2F0KGl0ZW1bNF0sIFwiKSB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVs0XSA9IHN1cHBvcnRzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBsaXN0LnB1c2goaXRlbSk7XG4gICAgfVxuICB9O1xuICByZXR1cm4gbGlzdDtcbn07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgdmFyIGNvbnRlbnQgPSBpdGVtWzFdO1xuICB2YXIgY3NzTWFwcGluZyA9IGl0ZW1bM107XG4gIGlmICghY3NzTWFwcGluZykge1xuICAgIHJldHVybiBjb250ZW50O1xuICB9XG4gIGlmICh0eXBlb2YgYnRvYSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgdmFyIGJhc2U2NCA9IGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KGNzc01hcHBpbmcpKSkpO1xuICAgIHZhciBkYXRhID0gXCJzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxcIi5jb25jYXQoYmFzZTY0KTtcbiAgICB2YXIgc291cmNlTWFwcGluZyA9IFwiLyojIFwiLmNvbmNhdChkYXRhLCBcIiAqL1wiKTtcbiAgICByZXR1cm4gW2NvbnRlbnRdLmNvbmNhdChbc291cmNlTWFwcGluZ10pLmpvaW4oXCJcXG5cIik7XG4gIH1cbiAgcmV0dXJuIFtjb250ZW50XS5qb2luKFwiXFxuXCIpO1xufTsiLCJleHBvcnQgY29uc3QgY29ubmVjdCA9IGFzeW5jIChidXR0b24pID0+IHtcbiAgICBpbXBvcnQoXCIuL2luc3RhbGwtZGlhbG9nLmpzXCIpO1xuICAgIGxldCBwb3J0O1xuICAgIHRyeSB7XG4gICAgICAgIHBvcnQgPSBhd2FpdCBuYXZpZ2F0b3Iuc2VyaWFsLnJlcXVlc3RQb3J0KCk7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKGVyci5uYW1lID09PSBcIk5vdEZvdW5kRXJyb3JcIikge1xuICAgICAgICAgICAgaW1wb3J0KFwiLi9uby1wb3J0LXBpY2tlZC9pbmRleFwiKS50aGVuKChtb2QpID0+IG1vZC5vcGVuTm9Qb3J0UGlja2VkRGlhbG9nKCgpID0+IGNvbm5lY3QoYnV0dG9uKSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGFsZXJ0KGBFcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXBvcnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBwb3J0Lm9wZW4oeyBiYXVkUmF0ZTogMTE1MjAwLCBidWZmZXJTaXplOiA4MTkyIH0pO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGFsZXJ0KGVyci5tZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJld3QtaW5zdGFsbC1kaWFsb2dcIik7XG4gICAgZWwucG9ydCA9IHBvcnQ7XG4gICAgZWwubWFuaWZlc3RQYXRoID0gYnV0dG9uLm1hbmlmZXN0IHx8IGJ1dHRvbi5nZXRBdHRyaWJ1dGUoXCJtYW5pZmVzdFwiKTtcbiAgICBlbC5vdmVycmlkZXMgPSBidXR0b24ub3ZlcnJpZGVzO1xuICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoXCJjbG9zZWRcIiwgKCkgPT4ge1xuICAgICAgICBwb3J0LmNsb3NlKCk7XG4gICAgfSwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZWwpO1xufTtcbiIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tIFwiLi9jb25uZWN0XCI7XG5leHBvcnQgY2xhc3MgSW5zdGFsbEJ1dHRvbiBleHRlbmRzIEhUTUxFbGVtZW50IHtcbiAgICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICAgICAgaWYgKHRoaXMucmVuZGVyUm9vdCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVuZGVyUm9vdCA9IHRoaXMuYXR0YWNoU2hhZG93KHsgbW9kZTogXCJvcGVuXCIgfSk7XG4gICAgICAgIGlmICghSW5zdGFsbEJ1dHRvbi5pc1N1cHBvcnRlZCB8fCAhSW5zdGFsbEJ1dHRvbi5pc0FsbG93ZWQpIHtcbiAgICAgICAgICAgIHRoaXMudG9nZ2xlQXR0cmlidXRlKFwiaW5zdGFsbC11bnN1cHBvcnRlZFwiLCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyUm9vdC5pbm5lckhUTUwgPSAhSW5zdGFsbEJ1dHRvbi5pc0FsbG93ZWRcbiAgICAgICAgICAgICAgICA/IFwiPHNsb3QgbmFtZT0nbm90LWFsbG93ZWQnPllvdSBjYW4gb25seSBpbnN0YWxsIEVTUCBkZXZpY2VzIG9uIEhUVFBTIHdlYnNpdGVzIG9yIG9uIHRoZSBsb2NhbGhvc3QuPC9zbG90PlwiXG4gICAgICAgICAgICAgICAgOiBcIjxzbG90IG5hbWU9J3Vuc3VwcG9ydGVkJz5Zb3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBpbnN0YWxsaW5nIHRoaW5ncyBvbiBFU1AgZGV2aWNlcy4gVXNlIEdvb2dsZSBDaHJvbWUgb3IgTWljcm9zb2Z0IEVkZ2UuPC9zbG90PlwiO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudG9nZ2xlQXR0cmlidXRlKFwiaW5zdGFsbC1zdXBwb3J0ZWRcIiwgdHJ1ZSk7XG4gICAgICAgIGNvbnN0IHNsb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2xvdFwiKTtcbiAgICAgICAgc2xvdC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgYXN5bmMgKGV2KSA9PiB7XG4gICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgY29ubmVjdCh0aGlzKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNsb3QubmFtZSA9IFwiYWN0aXZhdGVcIjtcbiAgICAgICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImJ1dHRvblwiKTtcbiAgICAgICAgYnV0dG9uLmlubmVyVGV4dCA9IFwiQ29ubmVjdFwiO1xuICAgICAgICBzbG90LmFwcGVuZChidXR0b24pO1xuICAgICAgICBpZiAoXCJhZG9wdGVkU3R5bGVTaGVldHNcIiBpbiBEb2N1bWVudC5wcm90b3R5cGUgJiZcbiAgICAgICAgICAgIFwicmVwbGFjZVN5bmNcIiBpbiBDU1NTdHlsZVNoZWV0LnByb3RvdHlwZSkge1xuICAgICAgICAgICAgY29uc3Qgc2hlZXQgPSBuZXcgQ1NTU3R5bGVTaGVldCgpO1xuICAgICAgICAgICAgc2hlZXQucmVwbGFjZVN5bmMoSW5zdGFsbEJ1dHRvbi5zdHlsZSk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlclJvb3QuYWRvcHRlZFN0eWxlU2hlZXRzID0gW3NoZWV0XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHN0eWxlU2hlZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XG4gICAgICAgICAgICBzdHlsZVNoZWV0LmlubmVyVGV4dCA9IEluc3RhbGxCdXR0b24uc3R5bGU7XG4gICAgICAgICAgICB0aGlzLnJlbmRlclJvb3QuYXBwZW5kKHN0eWxlU2hlZXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVuZGVyUm9vdC5hcHBlbmQoc2xvdCk7XG4gICAgfVxufVxuSW5zdGFsbEJ1dHRvbi5pc1N1cHBvcnRlZCA9IFwic2VyaWFsXCIgaW4gbmF2aWdhdG9yO1xuSW5zdGFsbEJ1dHRvbi5pc0FsbG93ZWQgPSB3aW5kb3cuaXNTZWN1cmVDb250ZXh0O1xuSW5zdGFsbEJ1dHRvbi5zdHlsZSA9IGBcbiAgYnV0dG9uIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBmb250LXdlaWdodDogNTAwO1xuICAgIHBhZGRpbmc6IDEwcHggMjRweDtcbiAgICBjb2xvcjogdmFyKC0tZXNwLXRvb2xzLWJ1dHRvbi10ZXh0LWNvbG9yLCAjZmZmKTtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1lc3AtdG9vbHMtYnV0dG9uLWNvbG9yLCAjMDNhOWY0KTtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYm9yZGVyLXJhZGl1czogdmFyKC0tZXNwLXRvb2xzLWJ1dHRvbi1ib3JkZXItcmFkaXVzLCA5OTk5cHgpO1xuICB9XG4gIGJ1dHRvbjo6YmVmb3JlIHtcbiAgICBjb250ZW50OiBcIiBcIjtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHJpZ2h0OiAwO1xuICAgIG9wYWNpdHk6IDAuMjtcbiAgICBib3JkZXItcmFkaXVzOiB2YXIoLS1lc3AtdG9vbHMtYnV0dG9uLWJvcmRlci1yYWRpdXMsIDk5OTlweCk7XG4gIH1cbiAgYnV0dG9uOmhvdmVyOjpiZWZvcmUge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjU1LDI1NSwyNTUsLjgpO1xuICB9XG4gIGJ1dHRvbjpmb2N1cyB7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgfVxuICBidXR0b246Zm9jdXM6OmJlZm9yZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG4gIH1cbiAgYnV0dG9uOmFjdGl2ZTo6YmVmb3JlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiBncmV5O1xuICB9XG4gIDpob3N0KFthY3RpdmVdKSBidXR0b24ge1xuICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMzgpO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC4xMik7XG4gICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICBjdXJzb3I6IHVuc2V0O1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICB9XG4gIC5oaWRkZW4ge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1gO1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKFwiZXNwLXdlYi1pbnN0YWxsLWJ1dHRvblwiLCBJbnN0YWxsQnV0dG9uKTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgc3R5bGVzSW5ET00gPSBbXTtcbmZ1bmN0aW9uIGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpIHtcbiAgdmFyIHJlc3VsdCA9IC0xO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0eWxlc0luRE9NLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHN0eWxlc0luRE9NW2ldLmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHtcbiAgICAgIHJlc3VsdCA9IGk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIG1vZHVsZXNUb0RvbShsaXN0LCBvcHRpb25zKSB7XG4gIHZhciBpZENvdW50TWFwID0ge307XG4gIHZhciBpZGVudGlmaWVycyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV07XG4gICAgdmFyIGlkID0gb3B0aW9ucy5iYXNlID8gaXRlbVswXSArIG9wdGlvbnMuYmFzZSA6IGl0ZW1bMF07XG4gICAgdmFyIGNvdW50ID0gaWRDb3VudE1hcFtpZF0gfHwgMDtcbiAgICB2YXIgaWRlbnRpZmllciA9IFwiXCIuY29uY2F0KGlkLCBcIiBcIikuY29uY2F0KGNvdW50KTtcbiAgICBpZENvdW50TWFwW2lkXSA9IGNvdW50ICsgMTtcbiAgICB2YXIgaW5kZXhCeUlkZW50aWZpZXIgPSBnZXRJbmRleEJ5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAgICB2YXIgb2JqID0ge1xuICAgICAgY3NzOiBpdGVtWzFdLFxuICAgICAgbWVkaWE6IGl0ZW1bMl0sXG4gICAgICBzb3VyY2VNYXA6IGl0ZW1bM10sXG4gICAgICBzdXBwb3J0czogaXRlbVs0XSxcbiAgICAgIGxheWVyOiBpdGVtWzVdXG4gICAgfTtcbiAgICBpZiAoaW5kZXhCeUlkZW50aWZpZXIgIT09IC0xKSB7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleEJ5SWRlbnRpZmllcl0ucmVmZXJlbmNlcysrO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhCeUlkZW50aWZpZXJdLnVwZGF0ZXIob2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHVwZGF0ZXIgPSBhZGRFbGVtZW50U3R5bGUob2JqLCBvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMuYnlJbmRleCA9IGk7XG4gICAgICBzdHlsZXNJbkRPTS5zcGxpY2UoaSwgMCwge1xuICAgICAgICBpZGVudGlmaWVyOiBpZGVudGlmaWVyLFxuICAgICAgICB1cGRhdGVyOiB1cGRhdGVyLFxuICAgICAgICByZWZlcmVuY2VzOiAxXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWRlbnRpZmllcnMucHVzaChpZGVudGlmaWVyKTtcbiAgfVxuICByZXR1cm4gaWRlbnRpZmllcnM7XG59XG5mdW5jdGlvbiBhZGRFbGVtZW50U3R5bGUob2JqLCBvcHRpb25zKSB7XG4gIHZhciBhcGkgPSBvcHRpb25zLmRvbUFQSShvcHRpb25zKTtcbiAgYXBpLnVwZGF0ZShvYmopO1xuICB2YXIgdXBkYXRlciA9IGZ1bmN0aW9uIHVwZGF0ZXIobmV3T2JqKSB7XG4gICAgaWYgKG5ld09iaikge1xuICAgICAgaWYgKG5ld09iai5jc3MgPT09IG9iai5jc3MgJiYgbmV3T2JqLm1lZGlhID09PSBvYmoubWVkaWEgJiYgbmV3T2JqLnNvdXJjZU1hcCA9PT0gb2JqLnNvdXJjZU1hcCAmJiBuZXdPYmouc3VwcG9ydHMgPT09IG9iai5zdXBwb3J0cyAmJiBuZXdPYmoubGF5ZXIgPT09IG9iai5sYXllcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhcGkudXBkYXRlKG9iaiA9IG5ld09iaik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwaS5yZW1vdmUoKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiB1cGRhdGVyO1xufVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobGlzdCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgbGlzdCA9IGxpc3QgfHwgW107XG4gIHZhciBsYXN0SWRlbnRpZmllcnMgPSBtb2R1bGVzVG9Eb20obGlzdCwgb3B0aW9ucyk7XG4gIHJldHVybiBmdW5jdGlvbiB1cGRhdGUobmV3TGlzdCkge1xuICAgIG5ld0xpc3QgPSBuZXdMaXN0IHx8IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaWRlbnRpZmllciA9IGxhc3RJZGVudGlmaWVyc1tpXTtcbiAgICAgIHZhciBpbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhdLnJlZmVyZW5jZXMtLTtcbiAgICB9XG4gICAgdmFyIG5ld0xhc3RJZGVudGlmaWVycyA9IG1vZHVsZXNUb0RvbShuZXdMaXN0LCBvcHRpb25zKTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgX2krKykge1xuICAgICAgdmFyIF9pZGVudGlmaWVyID0gbGFzdElkZW50aWZpZXJzW19pXTtcbiAgICAgIHZhciBfaW5kZXggPSBnZXRJbmRleEJ5SWRlbnRpZmllcihfaWRlbnRpZmllcik7XG4gICAgICBpZiAoc3R5bGVzSW5ET01bX2luZGV4XS5yZWZlcmVuY2VzID09PSAwKSB7XG4gICAgICAgIHN0eWxlc0luRE9NW19pbmRleF0udXBkYXRlcigpO1xuICAgICAgICBzdHlsZXNJbkRPTS5zcGxpY2UoX2luZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGFzdElkZW50aWZpZXJzID0gbmV3TGFzdElkZW50aWZpZXJzO1xuICB9O1xufTsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIG1lbW8gPSB7fTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBnZXRUYXJnZXQodGFyZ2V0KSB7XG4gIGlmICh0eXBlb2YgbWVtb1t0YXJnZXRdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdmFyIHN0eWxlVGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0YXJnZXQpO1xuXG4gICAgLy8gU3BlY2lhbCBjYXNlIHRvIHJldHVybiBoZWFkIG9mIGlmcmFtZSBpbnN0ZWFkIG9mIGlmcmFtZSBpdHNlbGZcbiAgICBpZiAod2luZG93LkhUTUxJRnJhbWVFbGVtZW50ICYmIHN0eWxlVGFyZ2V0IGluc3RhbmNlb2Ygd2luZG93LkhUTUxJRnJhbWVFbGVtZW50KSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFjY2VzcyB0byBpZnJhbWUgaXMgYmxvY2tlZFxuICAgICAgICAvLyBkdWUgdG8gY3Jvc3Mtb3JpZ2luIHJlc3RyaWN0aW9uc1xuICAgICAgICBzdHlsZVRhcmdldCA9IHN0eWxlVGFyZ2V0LmNvbnRlbnREb2N1bWVudC5oZWFkO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpc3RhbmJ1bCBpZ25vcmUgbmV4dFxuICAgICAgICBzdHlsZVRhcmdldCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIG1lbW9bdGFyZ2V0XSA9IHN0eWxlVGFyZ2V0O1xuICB9XG4gIHJldHVybiBtZW1vW3RhcmdldF07XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gaW5zZXJ0QnlTZWxlY3RvcihpbnNlcnQsIHN0eWxlKSB7XG4gIHZhciB0YXJnZXQgPSBnZXRUYXJnZXQoaW5zZXJ0KTtcbiAgaWYgKCF0YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCBmaW5kIGEgc3R5bGUgdGFyZ2V0LiBUaGlzIHByb2JhYmx5IG1lYW5zIHRoYXQgdGhlIHZhbHVlIGZvciB0aGUgJ2luc2VydCcgcGFyYW1ldGVyIGlzIGludmFsaWQuXCIpO1xuICB9XG4gIHRhcmdldC5hcHBlbmRDaGlsZChzdHlsZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluc2VydEJ5U2VsZWN0b3I7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gaW5zZXJ0U3R5bGVFbGVtZW50KG9wdGlvbnMpIHtcbiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XG4gIG9wdGlvbnMuc2V0QXR0cmlidXRlcyhlbGVtZW50LCBvcHRpb25zLmF0dHJpYnV0ZXMpO1xuICBvcHRpb25zLmluc2VydChlbGVtZW50LCBvcHRpb25zLm9wdGlvbnMpO1xuICByZXR1cm4gZWxlbWVudDtcbn1cbm1vZHVsZS5leHBvcnRzID0gaW5zZXJ0U3R5bGVFbGVtZW50OyIsIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIHNldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcyhzdHlsZUVsZW1lbnQpIHtcbiAgdmFyIG5vbmNlID0gdHlwZW9mIF9fd2VicGFja19ub25jZV9fICE9PSBcInVuZGVmaW5lZFwiID8gX193ZWJwYWNrX25vbmNlX18gOiBudWxsO1xuICBpZiAobm9uY2UpIHtcbiAgICBzdHlsZUVsZW1lbnQuc2V0QXR0cmlidXRlKFwibm9uY2VcIiwgbm9uY2UpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHNldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlczsiLCJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBhcHBseShzdHlsZUVsZW1lbnQsIG9wdGlvbnMsIG9iaikge1xuICB2YXIgY3NzID0gXCJcIjtcbiAgaWYgKG9iai5zdXBwb3J0cykge1xuICAgIGNzcyArPSBcIkBzdXBwb3J0cyAoXCIuY29uY2F0KG9iai5zdXBwb3J0cywgXCIpIHtcIik7XG4gIH1cbiAgaWYgKG9iai5tZWRpYSkge1xuICAgIGNzcyArPSBcIkBtZWRpYSBcIi5jb25jYXQob2JqLm1lZGlhLCBcIiB7XCIpO1xuICB9XG4gIHZhciBuZWVkTGF5ZXIgPSB0eXBlb2Ygb2JqLmxheWVyICE9PSBcInVuZGVmaW5lZFwiO1xuICBpZiAobmVlZExheWVyKSB7XG4gICAgY3NzICs9IFwiQGxheWVyXCIuY29uY2F0KG9iai5sYXllci5sZW5ndGggPiAwID8gXCIgXCIuY29uY2F0KG9iai5sYXllcikgOiBcIlwiLCBcIiB7XCIpO1xuICB9XG4gIGNzcyArPSBvYmouY3NzO1xuICBpZiAobmVlZExheWVyKSB7XG4gICAgY3NzICs9IFwifVwiO1xuICB9XG4gIGlmIChvYmoubWVkaWEpIHtcbiAgICBjc3MgKz0gXCJ9XCI7XG4gIH1cbiAgaWYgKG9iai5zdXBwb3J0cykge1xuICAgIGNzcyArPSBcIn1cIjtcbiAgfVxuICB2YXIgc291cmNlTWFwID0gb2JqLnNvdXJjZU1hcDtcbiAgaWYgKHNvdXJjZU1hcCAmJiB0eXBlb2YgYnRvYSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIGNzcyArPSBcIlxcbi8qIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIuY29uY2F0KGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSksIFwiICovXCIpO1xuICB9XG5cbiAgLy8gRm9yIG9sZCBJRVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgICovXG4gIG9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0oY3NzLCBzdHlsZUVsZW1lbnQsIG9wdGlvbnMub3B0aW9ucyk7XG59XG5mdW5jdGlvbiByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KSB7XG4gIC8vIGlzdGFuYnVsIGlnbm9yZSBpZlxuICBpZiAoc3R5bGVFbGVtZW50LnBhcmVudE5vZGUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc3R5bGVFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50KTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBkb21BUEkob3B0aW9ucykge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKCkge30sXG4gICAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHt9XG4gICAgfTtcbiAgfVxuICB2YXIgc3R5bGVFbGVtZW50ID0gb3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQob3B0aW9ucyk7XG4gIHJldHVybiB7XG4gICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUob2JqKSB7XG4gICAgICBhcHBseShzdHlsZUVsZW1lbnQsIG9wdGlvbnMsIG9iaik7XG4gICAgfSxcbiAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHtcbiAgICAgIHJlbW92ZVN0eWxlRWxlbWVudChzdHlsZUVsZW1lbnQpO1xuICAgIH1cbiAgfTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZG9tQVBJOyIsIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIHN0eWxlVGFnVHJhbnNmb3JtKGNzcywgc3R5bGVFbGVtZW50KSB7XG4gIGlmIChzdHlsZUVsZW1lbnQuc3R5bGVTaGVldCkge1xuICAgIHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSBjc3M7XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKSB7XG4gICAgICBzdHlsZUVsZW1lbnQucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50LmZpcnN0Q2hpbGQpO1xuICAgIH1cbiAgICBzdHlsZUVsZW1lbnQuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKSk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gc3R5bGVUYWdUcmFuc2Zvcm07IiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2FwcC5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcbm9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9hcHAuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbi8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG5fX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBfX3dlYnBhY2tfbW9kdWxlc19fO1xuXG4iLCIvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuX193ZWJwYWNrX3JlcXVpcmVfXy5uID0gKG1vZHVsZSkgPT4ge1xuXHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cblx0XHQoKSA9PiAobW9kdWxlWydkZWZhdWx0J10pIDpcblx0XHQoKSA9PiAobW9kdWxlKTtcblx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgeyBhOiBnZXR0ZXIgfSk7XG5cdHJldHVybiBnZXR0ZXI7XG59OyIsInZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiA/IChvYmopID0+IChPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKSkgOiAob2JqKSA9PiAob2JqLl9fcHJvdG9fXyk7XG52YXIgbGVhZlByb3RvdHlwZXM7XG4vLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3Rcbi8vIG1vZGUgJiAxOiB2YWx1ZSBpcyBhIG1vZHVsZSBpZCwgcmVxdWlyZSBpdFxuLy8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4vLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3Rcbi8vIG1vZGUgJiAxNjogcmV0dXJuIHZhbHVlIHdoZW4gaXQncyBQcm9taXNlLWxpa2Vcbi8vIG1vZGUgJiA4fDE6IGJlaGF2ZSBsaWtlIHJlcXVpcmVcbl9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG5cdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IHRoaXModmFsdWUpO1xuXHRpZihtb2RlICYgOCkgcmV0dXJuIHZhbHVlO1xuXHRpZih0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlKSB7XG5cdFx0aWYoKG1vZGUgJiA0KSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG5cdFx0aWYoKG1vZGUgJiAxNikgJiYgdHlwZW9mIHZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbicpIHJldHVybiB2YWx1ZTtcblx0fVxuXHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIobnMpO1xuXHR2YXIgZGVmID0ge307XG5cdGxlYWZQcm90b3R5cGVzID0gbGVhZlByb3RvdHlwZXMgfHwgW251bGwsIGdldFByb3RvKHt9KSwgZ2V0UHJvdG8oW10pLCBnZXRQcm90byhnZXRQcm90byldO1xuXHRmb3IodmFyIGN1cnJlbnQgPSBtb2RlICYgMiAmJiB2YWx1ZTsgdHlwZW9mIGN1cnJlbnQgPT0gJ29iamVjdCcgJiYgIX5sZWFmUHJvdG90eXBlcy5pbmRleE9mKGN1cnJlbnQpOyBjdXJyZW50ID0gZ2V0UHJvdG8oY3VycmVudCkpIHtcblx0XHRPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhjdXJyZW50KS5mb3JFYWNoKChrZXkpID0+IChkZWZba2V5XSA9ICgpID0+ICh2YWx1ZVtrZXldKSkpO1xuXHR9XG5cdGRlZlsnZGVmYXVsdCddID0gKCkgPT4gKHZhbHVlKTtcblx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBkZWYpO1xuXHRyZXR1cm4gbnM7XG59OyIsIi8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb25zIGZvciBoYXJtb255IGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uZCA9IChleHBvcnRzLCBkZWZpbml0aW9uKSA9PiB7XG5cdGZvcih2YXIga2V5IGluIGRlZmluaXRpb24pIHtcblx0XHRpZihfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZGVmaW5pdGlvbiwga2V5KSAmJiAhX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIGtleSkpIHtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBrZXksIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBkZWZpbml0aW9uW2tleV0gfSk7XG5cdFx0fVxuXHR9XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18uZiA9IHt9O1xuLy8gVGhpcyBmaWxlIGNvbnRhaW5zIG9ubHkgdGhlIGVudHJ5IGNodW5rLlxuLy8gVGhlIGNodW5rIGxvYWRpbmcgZnVuY3Rpb24gZm9yIGFkZGl0aW9uYWwgY2h1bmtzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmUgPSAoY2h1bmtJZCkgPT4ge1xuXHRyZXR1cm4gUHJvbWlzZS5hbGwoT2JqZWN0LmtleXMoX193ZWJwYWNrX3JlcXVpcmVfXy5mKS5yZWR1Y2UoKHByb21pc2VzLCBrZXkpID0+IHtcblx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmZba2V5XShjaHVua0lkLCBwcm9taXNlcyk7XG5cdFx0cmV0dXJuIHByb21pc2VzO1xuXHR9LCBbXSkpO1xufTsiLCIvLyBUaGlzIGZ1bmN0aW9uIGFsbG93IHRvIHJlZmVyZW5jZSBhc3luYyBjaHVua3Ncbl9fd2VicGFja19yZXF1aXJlX18udSA9IChjaHVua0lkKSA9PiB7XG5cdC8vIHJldHVybiB1cmwgZm9yIGZpbGVuYW1lcyBiYXNlZCBvbiB0ZW1wbGF0ZVxuXHRyZXR1cm4gXCJcIiArIGNodW5rSWQgKyBcIi5idW5kbGUuanNcIjtcbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5nID0gKGZ1bmN0aW9uKCkge1xuXHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnKSByZXR1cm4gZ2xvYmFsVGhpcztcblx0dHJ5IHtcblx0XHRyZXR1cm4gdGhpcyB8fCBuZXcgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JykgcmV0dXJuIHdpbmRvdztcblx0fVxufSkoKTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwidmFyIGluUHJvZ3Jlc3MgPSB7fTtcbnZhciBkYXRhV2VicGFja1ByZWZpeCA9IFwiVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXI6XCI7XG4vLyBsb2FkU2NyaXB0IGZ1bmN0aW9uIHRvIGxvYWQgYSBzY3JpcHQgdmlhIHNjcmlwdCB0YWdcbl9fd2VicGFja19yZXF1aXJlX18ubCA9ICh1cmwsIGRvbmUsIGtleSwgY2h1bmtJZCkgPT4ge1xuXHRpZihpblByb2dyZXNzW3VybF0pIHsgaW5Qcm9ncmVzc1t1cmxdLnB1c2goZG9uZSk7IHJldHVybjsgfVxuXHR2YXIgc2NyaXB0LCBuZWVkQXR0YWNoO1xuXHRpZihrZXkgIT09IHVuZGVmaW5lZCkge1xuXHRcdHZhciBzY3JpcHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzY3JpcHRcIik7XG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHNjcmlwdHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBzID0gc2NyaXB0c1tpXTtcblx0XHRcdGlmKHMuZ2V0QXR0cmlidXRlKFwic3JjXCIpID09IHVybCB8fCBzLmdldEF0dHJpYnV0ZShcImRhdGEtd2VicGFja1wiKSA9PSBkYXRhV2VicGFja1ByZWZpeCArIGtleSkgeyBzY3JpcHQgPSBzOyBicmVhazsgfVxuXHRcdH1cblx0fVxuXHRpZighc2NyaXB0KSB7XG5cdFx0bmVlZEF0dGFjaCA9IHRydWU7XG5cdFx0c2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cblx0XHRzY3JpcHQuY2hhcnNldCA9ICd1dGYtOCc7XG5cdFx0c2NyaXB0LnRpbWVvdXQgPSAxMjA7XG5cdFx0aWYgKF9fd2VicGFja19yZXF1aXJlX18ubmMpIHtcblx0XHRcdHNjcmlwdC5zZXRBdHRyaWJ1dGUoXCJub25jZVwiLCBfX3dlYnBhY2tfcmVxdWlyZV9fLm5jKTtcblx0XHR9XG5cdFx0c2NyaXB0LnNldEF0dHJpYnV0ZShcImRhdGEtd2VicGFja1wiLCBkYXRhV2VicGFja1ByZWZpeCArIGtleSk7XG5cblx0XHRzY3JpcHQuc3JjID0gdXJsO1xuXHR9XG5cdGluUHJvZ3Jlc3NbdXJsXSA9IFtkb25lXTtcblx0dmFyIG9uU2NyaXB0Q29tcGxldGUgPSAocHJldiwgZXZlbnQpID0+IHtcblx0XHQvLyBhdm9pZCBtZW0gbGVha3MgaW4gSUUuXG5cdFx0c2NyaXB0Lm9uZXJyb3IgPSBzY3JpcHQub25sb2FkID0gbnVsbDtcblx0XHRjbGVhclRpbWVvdXQodGltZW91dCk7XG5cdFx0dmFyIGRvbmVGbnMgPSBpblByb2dyZXNzW3VybF07XG5cdFx0ZGVsZXRlIGluUHJvZ3Jlc3NbdXJsXTtcblx0XHRzY3JpcHQucGFyZW50Tm9kZSAmJiBzY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzY3JpcHQpO1xuXHRcdGRvbmVGbnMgJiYgZG9uZUZucy5mb3JFYWNoKChmbikgPT4gKGZuKGV2ZW50KSkpO1xuXHRcdGlmKHByZXYpIHJldHVybiBwcmV2KGV2ZW50KTtcblx0fVxuXHR2YXIgdGltZW91dCA9IHNldFRpbWVvdXQob25TY3JpcHRDb21wbGV0ZS5iaW5kKG51bGwsIHVuZGVmaW5lZCwgeyB0eXBlOiAndGltZW91dCcsIHRhcmdldDogc2NyaXB0IH0pLCAxMjAwMDApO1xuXHRzY3JpcHQub25lcnJvciA9IG9uU2NyaXB0Q29tcGxldGUuYmluZChudWxsLCBzY3JpcHQub25lcnJvcik7XG5cdHNjcmlwdC5vbmxvYWQgPSBvblNjcmlwdENvbXBsZXRlLmJpbmQobnVsbCwgc2NyaXB0Lm9ubG9hZCk7XG5cdG5lZWRBdHRhY2ggJiYgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xufTsiLCIvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSAoZXhwb3J0cykgPT4ge1xuXHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcblx0fVxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xufTsiLCJ2YXIgc2NyaXB0VXJsO1xuaWYgKF9fd2VicGFja19yZXF1aXJlX18uZy5pbXBvcnRTY3JpcHRzKSBzY3JpcHRVcmwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLmcubG9jYXRpb24gKyBcIlwiO1xudmFyIGRvY3VtZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXy5nLmRvY3VtZW50O1xuaWYgKCFzY3JpcHRVcmwgJiYgZG9jdW1lbnQpIHtcblx0aWYgKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQgJiYgZG9jdW1lbnQuY3VycmVudFNjcmlwdC50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdTQ1JJUFQnKVxuXHRcdHNjcmlwdFVybCA9IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjO1xuXHRpZiAoIXNjcmlwdFVybCkge1xuXHRcdHZhciBzY3JpcHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzY3JpcHRcIik7XG5cdFx0aWYoc2NyaXB0cy5sZW5ndGgpIHtcblx0XHRcdHZhciBpID0gc2NyaXB0cy5sZW5ndGggLSAxO1xuXHRcdFx0d2hpbGUgKGkgPiAtMSAmJiAoIXNjcmlwdFVybCB8fCAhL15odHRwKHM/KTovLnRlc3Qoc2NyaXB0VXJsKSkpIHNjcmlwdFVybCA9IHNjcmlwdHNbaS0tXS5zcmM7XG5cdFx0fVxuXHR9XG59XG4vLyBXaGVuIHN1cHBvcnRpbmcgYnJvd3NlcnMgd2hlcmUgYW4gYXV0b21hdGljIHB1YmxpY1BhdGggaXMgbm90IHN1cHBvcnRlZCB5b3UgbXVzdCBzcGVjaWZ5IGFuIG91dHB1dC5wdWJsaWNQYXRoIG1hbnVhbGx5IHZpYSBjb25maWd1cmF0aW9uXG4vLyBvciBwYXNzIGFuIGVtcHR5IHN0cmluZyAoXCJcIikgYW5kIHNldCB0aGUgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gdmFyaWFibGUgZnJvbSB5b3VyIGNvZGUgdG8gdXNlIHlvdXIgb3duIGxvZ2ljLlxuaWYgKCFzY3JpcHRVcmwpIHRocm93IG5ldyBFcnJvcihcIkF1dG9tYXRpYyBwdWJsaWNQYXRoIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyXCIpO1xuc2NyaXB0VXJsID0gc2NyaXB0VXJsLnJlcGxhY2UoL15ibG9iOi8sIFwiXCIpLnJlcGxhY2UoLyMuKiQvLCBcIlwiKS5yZXBsYWNlKC9cXD8uKiQvLCBcIlwiKS5yZXBsYWNlKC9cXC9bXlxcL10rJC8sIFwiL1wiKTtcbl9fd2VicGFja19yZXF1aXJlX18ucCA9IHNjcmlwdFVybDsiLCIvLyBubyBiYXNlVVJJXG5cbi8vIG9iamVjdCB0byBzdG9yZSBsb2FkZWQgYW5kIGxvYWRpbmcgY2h1bmtzXG4vLyB1bmRlZmluZWQgPSBjaHVuayBub3QgbG9hZGVkLCBudWxsID0gY2h1bmsgcHJlbG9hZGVkL3ByZWZldGNoZWRcbi8vIFtyZXNvbHZlLCByZWplY3QsIFByb21pc2VdID0gY2h1bmsgbG9hZGluZywgMCA9IGNodW5rIGxvYWRlZFxudmFyIGluc3RhbGxlZENodW5rcyA9IHtcblx0XCJtYWluXCI6IDBcbn07XG5cbl9fd2VicGFja19yZXF1aXJlX18uZi5qID0gKGNodW5rSWQsIHByb21pc2VzKSA9PiB7XG5cdFx0Ly8gSlNPTlAgY2h1bmsgbG9hZGluZyBmb3IgamF2YXNjcmlwdFxuXHRcdHZhciBpbnN0YWxsZWRDaHVua0RhdGEgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLm8oaW5zdGFsbGVkQ2h1bmtzLCBjaHVua0lkKSA/IGluc3RhbGxlZENodW5rc1tjaHVua0lkXSA6IHVuZGVmaW5lZDtcblx0XHRpZihpbnN0YWxsZWRDaHVua0RhdGEgIT09IDApIHsgLy8gMCBtZWFucyBcImFscmVhZHkgaW5zdGFsbGVkXCIuXG5cblx0XHRcdC8vIGEgUHJvbWlzZSBtZWFucyBcImN1cnJlbnRseSBsb2FkaW5nXCIuXG5cdFx0XHRpZihpbnN0YWxsZWRDaHVua0RhdGEpIHtcblx0XHRcdFx0cHJvbWlzZXMucHVzaChpbnN0YWxsZWRDaHVua0RhdGFbMl0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYodHJ1ZSkgeyAvLyBhbGwgY2h1bmtzIGhhdmUgSlNcblx0XHRcdFx0XHQvLyBzZXR1cCBQcm9taXNlIGluIGNodW5rIGNhY2hlXG5cdFx0XHRcdFx0dmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiAoaW5zdGFsbGVkQ2h1bmtEYXRhID0gaW5zdGFsbGVkQ2h1bmtzW2NodW5rSWRdID0gW3Jlc29sdmUsIHJlamVjdF0pKTtcblx0XHRcdFx0XHRwcm9taXNlcy5wdXNoKGluc3RhbGxlZENodW5rRGF0YVsyXSA9IHByb21pc2UpO1xuXG5cdFx0XHRcdFx0Ly8gc3RhcnQgY2h1bmsgbG9hZGluZ1xuXHRcdFx0XHRcdHZhciB1cmwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBfX3dlYnBhY2tfcmVxdWlyZV9fLnUoY2h1bmtJZCk7XG5cdFx0XHRcdFx0Ly8gY3JlYXRlIGVycm9yIGJlZm9yZSBzdGFjayB1bndvdW5kIHRvIGdldCB1c2VmdWwgc3RhY2t0cmFjZSBsYXRlclxuXHRcdFx0XHRcdHZhciBlcnJvciA9IG5ldyBFcnJvcigpO1xuXHRcdFx0XHRcdHZhciBsb2FkaW5nRW5kZWQgPSAoZXZlbnQpID0+IHtcblx0XHRcdFx0XHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhpbnN0YWxsZWRDaHVua3MsIGNodW5rSWQpKSB7XG5cdFx0XHRcdFx0XHRcdGluc3RhbGxlZENodW5rRGF0YSA9IGluc3RhbGxlZENodW5rc1tjaHVua0lkXTtcblx0XHRcdFx0XHRcdFx0aWYoaW5zdGFsbGVkQ2h1bmtEYXRhICE9PSAwKSBpbnN0YWxsZWRDaHVua3NbY2h1bmtJZF0gPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdGlmKGluc3RhbGxlZENodW5rRGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciBlcnJvclR5cGUgPSBldmVudCAmJiAoZXZlbnQudHlwZSA9PT0gJ2xvYWQnID8gJ21pc3NpbmcnIDogZXZlbnQudHlwZSk7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIHJlYWxTcmMgPSBldmVudCAmJiBldmVudC50YXJnZXQgJiYgZXZlbnQudGFyZ2V0LnNyYztcblx0XHRcdFx0XHRcdFx0XHRlcnJvci5tZXNzYWdlID0gJ0xvYWRpbmcgY2h1bmsgJyArIGNodW5rSWQgKyAnIGZhaWxlZC5cXG4oJyArIGVycm9yVHlwZSArICc6ICcgKyByZWFsU3JjICsgJyknO1xuXHRcdFx0XHRcdFx0XHRcdGVycm9yLm5hbWUgPSAnQ2h1bmtMb2FkRXJyb3InO1xuXHRcdFx0XHRcdFx0XHRcdGVycm9yLnR5cGUgPSBlcnJvclR5cGU7XG5cdFx0XHRcdFx0XHRcdFx0ZXJyb3IucmVxdWVzdCA9IHJlYWxTcmM7XG5cdFx0XHRcdFx0XHRcdFx0aW5zdGFsbGVkQ2h1bmtEYXRhWzFdKGVycm9yKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5sKHVybCwgbG9hZGluZ0VuZGVkLCBcImNodW5rLVwiICsgY2h1bmtJZCwgY2h1bmtJZCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG59O1xuXG4vLyBubyBwcmVmZXRjaGluZ1xuXG4vLyBubyBwcmVsb2FkZWRcblxuLy8gbm8gSE1SXG5cbi8vIG5vIEhNUiBtYW5pZmVzdFxuXG4vLyBubyBvbiBjaHVua3MgbG9hZGVkXG5cbi8vIGluc3RhbGwgYSBKU09OUCBjYWxsYmFjayBmb3IgY2h1bmsgbG9hZGluZ1xudmFyIHdlYnBhY2tKc29ucENhbGxiYWNrID0gKHBhcmVudENodW5rTG9hZGluZ0Z1bmN0aW9uLCBkYXRhKSA9PiB7XG5cdHZhciBbY2h1bmtJZHMsIG1vcmVNb2R1bGVzLCBydW50aW1lXSA9IGRhdGE7XG5cdC8vIGFkZCBcIm1vcmVNb2R1bGVzXCIgdG8gdGhlIG1vZHVsZXMgb2JqZWN0LFxuXHQvLyB0aGVuIGZsYWcgYWxsIFwiY2h1bmtJZHNcIiBhcyBsb2FkZWQgYW5kIGZpcmUgY2FsbGJhY2tcblx0dmFyIG1vZHVsZUlkLCBjaHVua0lkLCBpID0gMDtcblx0aWYoY2h1bmtJZHMuc29tZSgoaWQpID0+IChpbnN0YWxsZWRDaHVua3NbaWRdICE9PSAwKSkpIHtcblx0XHRmb3IobW9kdWxlSWQgaW4gbW9yZU1vZHVsZXMpIHtcblx0XHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhtb3JlTW9kdWxlcywgbW9kdWxlSWQpKSB7XG5cdFx0XHRcdF9fd2VicGFja19yZXF1aXJlX18ubVttb2R1bGVJZF0gPSBtb3JlTW9kdWxlc1ttb2R1bGVJZF07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmKHJ1bnRpbWUpIHZhciByZXN1bHQgPSBydW50aW1lKF9fd2VicGFja19yZXF1aXJlX18pO1xuXHR9XG5cdGlmKHBhcmVudENodW5rTG9hZGluZ0Z1bmN0aW9uKSBwYXJlbnRDaHVua0xvYWRpbmdGdW5jdGlvbihkYXRhKTtcblx0Zm9yKDtpIDwgY2h1bmtJZHMubGVuZ3RoOyBpKyspIHtcblx0XHRjaHVua0lkID0gY2h1bmtJZHNbaV07XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGluc3RhbGxlZENodW5rcywgY2h1bmtJZCkgJiYgaW5zdGFsbGVkQ2h1bmtzW2NodW5rSWRdKSB7XG5cdFx0XHRpbnN0YWxsZWRDaHVua3NbY2h1bmtJZF1bMF0oKTtcblx0XHR9XG5cdFx0aW5zdGFsbGVkQ2h1bmtzW2NodW5rSWRdID0gMDtcblx0fVxuXG59XG5cbnZhciBjaHVua0xvYWRpbmdHbG9iYWwgPSBzZWxmW1wid2VicGFja0NodW5rVGFjdGlsaXR5X1dlYl9JbnN0YWxsZXJcIl0gPSBzZWxmW1wid2VicGFja0NodW5rVGFjdGlsaXR5X1dlYl9JbnN0YWxsZXJcIl0gfHwgW107XG5jaHVua0xvYWRpbmdHbG9iYWwuZm9yRWFjaCh3ZWJwYWNrSnNvbnBDYWxsYmFjay5iaW5kKG51bGwsIDApKTtcbmNodW5rTG9hZGluZ0dsb2JhbC5wdXNoID0gd2VicGFja0pzb25wQ2FsbGJhY2suYmluZChudWxsLCBjaHVua0xvYWRpbmdHbG9iYWwucHVzaC5iaW5kKGNodW5rTG9hZGluZ0dsb2JhbCkpOyIsIl9fd2VicGFja19yZXF1aXJlX18ubmMgPSB1bmRlZmluZWQ7IiwiaW1wb3J0ICdlc3Atd2ViLXRvb2xzJztcbmltcG9ydCAnLi9hcHAuY3NzJztcblxuaW1wb3J0IHRvb2xiYXJMb2dvIGZyb20gJy4uL2Fzc2V0cy9pbWFnZXMvdG9vbGJhci1sb2dvLnN2Zyc7XG5pbXBvcnQgJy4uL2Fzc2V0cy9pbWFnZXMvZmF2aWNvbi5zdmcnO1xuXG5jb25zdCBWRVJTSU9OUyA9IFsnc3RhYmxlJywgJ3Vuc3RhYmxlJ107XG5cbmNvbnN0ICQgPSAoaWQpID0+IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTtcblxuY29uc3Qgc3RhdGUgPSB7XG4gICAgLyoqIHZlcnNpb24gbmFtZSAtPiBpbmRleC5qc29uIGNvbnRlbnQsIG9yIG51bGwgd2hlbiBpdCBmYWlsZWQgdG8gbG9hZCAqL1xuICAgIGluZGV4ZXM6IHt9LFxuICAgIC8qKiBtZXJnZWQgZGV2aWNlczogeyBpZCwgdmVuZG9yLCBuYW1lLCBsYWJlbCwgaGF5c3RhY2ssIHdvcmRzLCBidWlsZHM6IHsgc3RhYmxlPywgdW5zdGFibGU/IH0gfSAqL1xuICAgIGRldmljZXM6IFtdLFxuICAgIHNlbGVjdGVkSWQ6IG51bGwsXG4gICAgcHJlZmVycmVkVmVyc2lvbjogJ3Vuc3RhYmxlJyxcbiAgICBxdWVyeTogJycsXG59O1xuXG5mdW5jdGlvbiBnZXRDZG5VcmwodmVyc2lvbiwgcGF0aCkge1xuICAgIGNvbnN0IGRpcmVjdG9yeSA9IHZlcnNpb24gPT09ICd1bnN0YWJsZScgPyAnc25hcHNob3QnIDogdmVyc2lvbjtcbiAgICByZXR1cm4gYGh0dHBzOi8vY2RuLnRhY3RpbGl0eXByb2plY3Qub3JnL2Zpcm13YXJlLyR7ZGlyZWN0b3J5fS8ke3BhdGh9YDtcbn1cblxuLyoqIExvd2VyY2FzZSBhbmQgc3RyaXAgcHVuY3R1YXRpb24sIHNvIFwidGRlY2tcIiBtYXRjaGVzIFwiVC1EZWNrXCIuICovXG5mdW5jdGlvbiBzcXVhc2godGV4dCkge1xuICAgIHJldHVybiB0ZXh0LnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvW15hLXowLTldKy9nLCAnJyk7XG59XG5cbmZ1bmN0aW9uIGZldGNoSW5kZXgodmVyc2lvbikge1xuICAgIHJldHVybiBmZXRjaChnZXRDZG5VcmwodmVyc2lvbiwgJ2luZGV4Lmpzb24nKSkudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIG1lcmdlRGV2aWNlcygpIHtcbiAgICBjb25zdCBieUlkID0gbmV3IE1hcCgpO1xuICAgIGZvciAoY29uc3QgdmVyc2lvbiBvZiBWRVJTSU9OUykge1xuICAgICAgICBjb25zdCBpbmRleCA9IHN0YXRlLmluZGV4ZXNbdmVyc2lvbl07XG4gICAgICAgIGlmICghaW5kZXgpIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKGNvbnN0IGJ1aWxkIG9mIGluZGV4LmRldmljZXMpIHtcbiAgICAgICAgICAgIGxldCBkZXZpY2UgPSBieUlkLmdldChidWlsZC5pZCk7XG4gICAgICAgICAgICBpZiAoIWRldmljZSkge1xuICAgICAgICAgICAgICAgIGRldmljZSA9IHsgaWQ6IGJ1aWxkLmlkLCBidWlsZHM6IHt9IH07XG4gICAgICAgICAgICAgICAgYnlJZC5zZXQoYnVpbGQuaWQsIGRldmljZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZXZpY2UuYnVpbGRzW3ZlcnNpb25dID0gYnVpbGQ7XG4gICAgICAgICAgICAvLyBMYXRlciB2ZXJzaW9ucyB3aW4sIHNvIG5hbWluZyBmb2xsb3dzIHRoZSBuZXdlc3QgYnVpbGRcbiAgICAgICAgICAgIGRldmljZS52ZW5kb3IgPSBidWlsZC52ZW5kb3I7XG4gICAgICAgICAgICBkZXZpY2UubmFtZSA9IGJ1aWxkLm5hbWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0ZS5kZXZpY2VzID0gWy4uLmJ5SWQudmFsdWVzKCldO1xuICAgIGZvciAoY29uc3QgZGV2aWNlIG9mIHN0YXRlLmRldmljZXMpIHtcbiAgICAgICAgZGV2aWNlLnNob3dWZW5kb3IgPSBkZXZpY2UudmVuZG9yICE9PSBkZXZpY2UubmFtZTtcbiAgICAgICAgZGV2aWNlLmxhYmVsID0gZGV2aWNlLnNob3dWZW5kb3IgPyBgJHtkZXZpY2UudmVuZG9yfSAke2RldmljZS5uYW1lfWAgOiBkZXZpY2UubmFtZTtcbiAgICAgICAgY29uc3QgdGV4dCA9IGAke2RldmljZS5sYWJlbH0gJHtkZXZpY2UuaWR9YDtcbiAgICAgICAgZGV2aWNlLmhheXN0YWNrID0gYCR7dGV4dC50b0xvd2VyQ2FzZSgpfSAke3NxdWFzaCh0ZXh0KX1gO1xuICAgICAgICBkZXZpY2Uud29yZHMgPSBkZXZpY2UubGFiZWwudG9Mb3dlckNhc2UoKS5zcGxpdCgvW15hLXowLTldKy8pLmZpbHRlcihCb29sZWFuKTtcbiAgICB9XG4gICAgc3RhdGUuZGV2aWNlcy5zb3J0KChhLCBiKSA9PiBhLmxhYmVsLmxvY2FsZUNvbXBhcmUoYi5sYWJlbCwgdW5kZWZpbmVkLCB7IHNlbnNpdGl2aXR5OiAnYmFzZScsIG51bWVyaWM6IHRydWUgfSkpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIHRva2VuIGNhbiBiZSBzcGxpdCBpbnRvIHBpZWNlcyB0aGF0IGFyZSBlYWNoIHRoZSBzdGFydCBvZiBhIHdvcmQsIGluIHdvcmQgb3JkZXIuXG4gKiBNYWtlcyBcIm01cGFwZXJcIiBtYXRjaCBcIk01U3RhY2sgUGFwZXJTM1wiIGFuZCBcInRkZWNrXCIgbWF0Y2ggXCJULURlY2tcIi5cbiAqL1xuZnVuY3Rpb24gbWF0Y2hlc1dvcmRTdGFydHModG9rZW4sIHdvcmRzLCBmaXJzdFdvcmQgPSAwKSB7XG4gICAgaWYgKHRva2VuID09PSAnJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IGZpcnN0V29yZDsgaSA8IHdvcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHdvcmQgPSB3b3Jkc1tpXTtcbiAgICAgICAgLy8gUGllY2VzIG9mIGEgc2luZ2xlIGNoYXJhY3RlciBvbmx5IGNvdW50IHdoZW4gdGhleSBhcmUgdGhlIGVudGlyZSB3b3JkLCB0byBsaW1pdCBub2lzZVxuICAgICAgICBjb25zdCBtaW5MZW5ndGggPSBNYXRoLm1pbigyLCB3b3JkLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGxlbmd0aCA9IE1hdGgubWluKHdvcmQubGVuZ3RoLCB0b2tlbi5sZW5ndGgpOyBsZW5ndGggPj0gbWluTGVuZ3RoOyBsZW5ndGgtLSkge1xuICAgICAgICAgICAgaWYgKHdvcmQuc3RhcnRzV2l0aCh0b2tlbi5zbGljZSgwLCBsZW5ndGgpKSAmJiBtYXRjaGVzV29yZFN0YXJ0cyh0b2tlbi5zbGljZShsZW5ndGgpLCB3b3JkcywgaSArIDEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBtYXRjaGVzVG9rZW4oZGV2aWNlLCB0b2tlbikge1xuICAgIGlmIChkZXZpY2UuaGF5c3RhY2suaW5jbHVkZXModG9rZW4pKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBzcXVhc2hlZCA9IHNxdWFzaCh0b2tlbik7XG4gICAgcmV0dXJuIHNxdWFzaGVkICE9PSAnJyAmJiAoZGV2aWNlLmhheXN0YWNrLmluY2x1ZGVzKHNxdWFzaGVkKSB8fCBtYXRjaGVzV29yZFN0YXJ0cyhzcXVhc2hlZCwgZGV2aWNlLndvcmRzKSk7XG59XG5cbmZ1bmN0aW9uIGdldEZpbHRlcmVkRGV2aWNlcygpIHtcbiAgICBjb25zdCB0b2tlbnMgPSBzdGF0ZS5xdWVyeS50b0xvd2VyQ2FzZSgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKEJvb2xlYW4pO1xuICAgIGlmICh0b2tlbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBzdGF0ZS5kZXZpY2VzO1xuICAgIH1cbiAgICByZXR1cm4gc3RhdGUuZGV2aWNlcy5maWx0ZXIoKGRldmljZSkgPT4gdG9rZW5zLmV2ZXJ5KCh0b2tlbikgPT4gbWF0Y2hlc1Rva2VuKGRldmljZSwgdG9rZW4pKSk7XG59XG5cbmZ1bmN0aW9uIGdldFNlbGVjdGVkRGV2aWNlKCkge1xuICAgIHJldHVybiBzdGF0ZS5kZXZpY2VzLmZpbmQoKGRldmljZSkgPT4gZGV2aWNlLmlkID09PSBzdGF0ZS5zZWxlY3RlZElkKSB8fCBudWxsO1xufVxuXG4vKiogVGhlIHZlcnNpb24gdG8gc2hvdyBmb3IgYSBkZXZpY2U6IHRoZSBwcmVmZXJyZWQgb25lLCBvciB3aGljaGV2ZXIgaXMgYXZhaWxhYmxlLiAqL1xuZnVuY3Rpb24gZ2V0QWN0aXZlVmVyc2lvbihkZXZpY2UpIHtcbiAgICBpZiAoZGV2aWNlLmJ1aWxkc1tzdGF0ZS5wcmVmZXJyZWRWZXJzaW9uXSkge1xuICAgICAgICByZXR1cm4gc3RhdGUucHJlZmVycmVkVmVyc2lvbjtcbiAgICB9XG4gICAgcmV0dXJuIFZFUlNJT05TLmZpbmQoKHZlcnNpb24pID0+IGRldmljZS5idWlsZHNbdmVyc2lvbl0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVCYWRnZSh0ZXh0LCBraW5kKSB7XG4gICAgY29uc3QgYmFkZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgYmFkZ2UuY2xhc3NOYW1lID0gYGJhZGdlIGJhZGdlLSR7a2luZH1gO1xuICAgIGJhZGdlLnRleHRDb250ZW50ID0gdGV4dDtcbiAgICByZXR1cm4gYmFkZ2U7XG59XG5cbmZ1bmN0aW9uIHJlbmRlckRldmljZUxpc3QoKSB7XG4gICAgY29uc3QgbGlzdCA9ICQoJ0RldmljZUxpc3QnKTtcbiAgICBjb25zdCBzdGF0dXMgPSAkKCdMaXN0U3RhdHVzJyk7XG4gICAgY29uc3QgZGV2aWNlcyA9IGdldEZpbHRlcmVkRGV2aWNlcygpO1xuICAgIGxpc3QucmVwbGFjZUNoaWxkcmVuKCk7XG5cbiAgICBmb3IgKGNvbnN0IGRldmljZSBvZiBkZXZpY2VzKSB7XG4gICAgICAgIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICBidXR0b24udHlwZSA9ICdidXR0b24nO1xuICAgICAgICBidXR0b24uY2xhc3NOYW1lID0gJ2RldmljZSc7XG4gICAgICAgIGJ1dHRvbi5kYXRhc2V0LmlkID0gZGV2aWNlLmlkO1xuICAgICAgICBidXR0b24uc2V0QXR0cmlidXRlKCdhcmlhLXByZXNzZWQnLCBTdHJpbmcoZGV2aWNlLmlkID09PSBzdGF0ZS5zZWxlY3RlZElkKSk7XG5cbiAgICAgICAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgdGV4dC5jbGFzc05hbWUgPSAnZGV2aWNlLXRleHQnO1xuICAgICAgICBpZiAoZGV2aWNlLnNob3dWZW5kb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IHZlbmRvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICAgIHZlbmRvci5jbGFzc05hbWUgPSAnZGV2aWNlLXZlbmRvcic7XG4gICAgICAgICAgICB2ZW5kb3IudGV4dENvbnRlbnQgPSBkZXZpY2UudmVuZG9yO1xuICAgICAgICAgICAgdGV4dC5hcHBlbmQodmVuZG9yKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICBuYW1lLmNsYXNzTmFtZSA9ICdkZXZpY2UtbmFtZSc7XG4gICAgICAgIG5hbWUudGV4dENvbnRlbnQgPSBkZXZpY2UubmFtZTtcbiAgICAgICAgdGV4dC5hcHBlbmQobmFtZSk7XG4gICAgICAgIGJ1dHRvbi5hcHBlbmQodGV4dCk7XG5cbiAgICAgICAgaWYgKCFkZXZpY2UuYnVpbGRzLnN0YWJsZSkge1xuICAgICAgICAgICAgYnV0dG9uLmFwcGVuZChjcmVhdGVCYWRnZSgnVW5zdGFibGUgb25seScsICdhY2NlbnQnKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoIWRldmljZS5idWlsZHMudW5zdGFibGUpIHtcbiAgICAgICAgICAgIGJ1dHRvbi5hcHBlbmQoY3JlYXRlQmFkZ2UoJ1N0YWJsZSBvbmx5JywgJ211dGVkJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZXZpY2UuYnVpbGRzW2dldEFjdGl2ZVZlcnNpb24oZGV2aWNlKV0uaW5jdWJhdGluZykge1xuICAgICAgICAgICAgYnV0dG9uLmFwcGVuZChjcmVhdGVCYWRnZSgnSW5jdWJhdGluZycsICd3YXJuaW5nJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXRlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7XG4gICAgICAgIGl0ZW0uYXBwZW5kKGJ1dHRvbik7XG4gICAgICAgIGxpc3QuYXBwZW5kKGl0ZW0pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5kZXZpY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm47IC8vIExvYWRpbmcgb3IgZXJyb3Igc3RhdGUgb3ducyB0aGUgc3RhdHVzIHRleHRcbiAgICB9XG4gICAgaWYgKGRldmljZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHN0YXR1cy50ZXh0Q29udGVudCA9IGBObyBkZXZpY2VzIG1hdGNoIOKAnCR7c3RhdGUucXVlcnkudHJpbSgpfeKAnS5gO1xuICAgIH0gZWxzZSBpZiAoZGV2aWNlcy5sZW5ndGggPT09IHN0YXRlLmRldmljZXMubGVuZ3RoKSB7XG4gICAgICAgIHN0YXR1cy50ZXh0Q29udGVudCA9IGAke2RldmljZXMubGVuZ3RofSBzdXBwb3J0ZWQgZGV2aWNlc2A7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdHVzLnRleHRDb250ZW50ID0gYCR7ZGV2aWNlcy5sZW5ndGh9IG9mICR7c3RhdGUuZGV2aWNlcy5sZW5ndGh9IGRldmljZXNgO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlTm90aWNlKGh0bWwsIGtpbmQpIHtcbiAgICBjb25zdCBub3RpY2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub3RpY2UuY2xhc3NOYW1lID0gYG5vdGljZSBub3RpY2UtJHtraW5kfWA7XG4gICAgLy8gTWVzc2FnZXMgY29tZSBmcm9tIG91ciBvd24gQ0ROIGFuZCBjb250YWluIG1hcmt1cCBzdWNoIGFzIDxici8+XG4gICAgbm90aWNlLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIG5vdGljZTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyVmVyc2lvbkxhYmVscygpIHtcbiAgICBmb3IgKGNvbnN0IHZlcnNpb24gb2YgVkVSU0lPTlMpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBzdGF0ZS5pbmRleGVzW3ZlcnNpb25dO1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBbZGF0YS12ZXJzaW9uLWxhYmVsPVwiJHt2ZXJzaW9ufVwiXWApLnRleHRDb250ZW50ID0gaW5kZXggPyBpbmRleC52ZXJzaW9uIDogJ1VuYXZhaWxhYmxlJztcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlbmRlckRldGFpbHMoKSB7XG4gICAgY29uc3QgZGV2aWNlID0gZ2V0U2VsZWN0ZWREZXZpY2UoKTtcbiAgICAkKCdEZXRhaWxzRW1wdHknKS5oaWRkZW4gPSBkZXZpY2UgIT09IG51bGw7XG4gICAgJCgnRGV0YWlsc0NvbnRlbnQnKS5oaWRkZW4gPSBkZXZpY2UgPT09IG51bGw7XG4gICAgaWYgKGRldmljZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdmVyc2lvbiA9IGdldEFjdGl2ZVZlcnNpb24oZGV2aWNlKTtcbiAgICBjb25zdCBidWlsZCA9IGRldmljZS5idWlsZHNbdmVyc2lvbl07XG4gICAgY29uc3QgaW5kZXggPSBzdGF0ZS5pbmRleGVzW3ZlcnNpb25dO1xuXG4gICAgJCgnU2VsZWN0ZWRWZW5kb3InKS50ZXh0Q29udGVudCA9IGRldmljZS5zaG93VmVuZG9yID8gZGV2aWNlLnZlbmRvciA6ICcnO1xuICAgICQoJ1NlbGVjdGVkTmFtZScpLnRleHRDb250ZW50ID0gZGV2aWNlLm5hbWU7XG5cbiAgICBmb3IgKGNvbnN0IGlucHV0IG9mIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W25hbWU9XCJ2ZXJzaW9uXCJdJykpIHtcbiAgICAgICAgY29uc3QgYXZhaWxhYmxlID0gQm9vbGVhbihkZXZpY2UuYnVpbGRzW2lucHV0LnZhbHVlXSk7XG4gICAgICAgIGlucHV0LmRpc2FibGVkID0gIWF2YWlsYWJsZTtcbiAgICAgICAgaW5wdXQuY2hlY2tlZCA9IGlucHV0LnZhbHVlID09PSB2ZXJzaW9uO1xuICAgICAgICBpbnB1dC5jbG9zZXN0KCcuc2VnbWVudCcpLnRpdGxlID0gYXZhaWxhYmxlID8gJycgOiBgTm8gJHtpbnB1dC52YWx1ZX0gYnVpbGQgZm9yIHRoaXMgZGV2aWNlYDtcbiAgICB9XG5cbiAgICBjb25zdCBkZXRhaWxzID0gJCgnVmVyc2lvbkRldGFpbHMnKTtcbiAgICBkZXRhaWxzLnJlcGxhY2VDaGlsZHJlbigpO1xuICAgIGlmIChpbmRleC5jcmVhdGVkICYmIGluZGV4LmdpdENvbW1pdCkge1xuICAgICAgICBjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgICAgICBsaW5rLmhyZWYgPSBgaHR0cHM6Ly9naXRodWIuY29tL0J5dGVXZWxkZXIvVGFjdGlsaXR5L2NvbW1pdC8ke2luZGV4LmdpdENvbW1pdH1gO1xuICAgICAgICBsaW5rLnRleHRDb250ZW50ID0gaW5kZXguZ2l0Q29tbWl0LnN1YnN0cmluZygwLCA3KTtcbiAgICAgICAgZGV0YWlscy5hcHBlbmQoYEJ1aWx0IG9uICR7bmV3IERhdGUoaW5kZXguY3JlYXRlZCkudG9Mb2NhbGVTdHJpbmcoKX0gZnJvbSBjb21taXQgYCwgbGluayk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5mbyA9ICQoJ0RldmljZUluZm8nKTtcbiAgICBpbmZvLnJlcGxhY2VDaGlsZHJlbigpO1xuICAgIGlmIChidWlsZC5pbmN1YmF0aW5nKSB7XG4gICAgICAgIGluZm8uYXBwZW5kKGNyZWF0ZU5vdGljZSgnVGhpcyBkZXZpY2UgaXMgaW5jdWJhdGluZy4gSXQgaXMgbm90IGZ1bGx5IGltcGxlbWVudGVkIScsICd3YXJuaW5nJykpO1xuICAgIH1cbiAgICBpZiAoYnVpbGQud2FybmluZ01lc3NhZ2UpIHtcbiAgICAgICAgaW5mby5hcHBlbmQoY3JlYXRlTm90aWNlKGJ1aWxkLndhcm5pbmdNZXNzYWdlLCAnd2FybmluZycpKTtcbiAgICB9XG4gICAgaWYgKGJ1aWxkLmluZm9NZXNzYWdlKSB7XG4gICAgICAgIGluZm8uYXBwZW5kKGNyZWF0ZU5vdGljZShidWlsZC5pbmZvTWVzc2FnZSwgJ2luZm8nKSk7XG4gICAgfVxuXG4gICAgJCgnSW5zdGFsbGVyJykubWFuaWZlc3QgPSBnZXRDZG5VcmwodmVyc2lvbiwgYCR7ZGV2aWNlLmlkfS5qc29uYCk7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdERldmljZShpZCkge1xuICAgIHN0YXRlLnNlbGVjdGVkSWQgPSBpZDtcbiAgICBmb3IgKGNvbnN0IGJ1dHRvbiBvZiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZGV2aWNlJykpIHtcbiAgICAgICAgYnV0dG9uLnNldEF0dHJpYnV0ZSgnYXJpYS1wcmVzc2VkJywgU3RyaW5nKGJ1dHRvbi5kYXRhc2V0LmlkID09PSBpZCkpO1xuICAgIH1cbiAgICByZW5kZXJEZXRhaWxzKCk7XG4gICAgaWYgKGdldEhhc2hEZXZpY2VJZCgpICE9PSBpZCkge1xuICAgICAgICAvLyBSZXBsYWNlIHJhdGhlciB0aGFuIHB1c2gsIHNvIGJyb3dzaW5nIGRldmljZXMgZG9lc24ndCBmaWxsIHVwIHRoZSBoaXN0b3J5XG4gICAgICAgIGhpc3RvcnkucmVwbGFjZVN0YXRlKG51bGwsICcnLCBgIyR7ZW5jb2RlVVJJQ29tcG9uZW50KGlkKX1gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldEhhc2hEZXZpY2VJZCgpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGxvY2F0aW9uLmhhc2guc2xpY2UoMSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG59XG5cbi8qKiBTZWxlY3QgdGhlIGRldmljZSBmcm9tIHRoZSBVUkwsIGUuZy4gaHR0cHM6Ly9pbnN0YWxsLnRhY3RpbGl0eXByb2plY3Qub3JnLyNsaWx5Z28tdGRlY2sgKi9cbmZ1bmN0aW9uIHNlbGVjdERldmljZUZyb21IYXNoKCkge1xuICAgIGNvbnN0IGlkID0gZ2V0SGFzaERldmljZUlkKCk7XG4gICAgaWYgKGlkID09PSBzdGF0ZS5zZWxlY3RlZElkIHx8ICFzdGF0ZS5kZXZpY2VzLnNvbWUoKGRldmljZSkgPT4gZGV2aWNlLmlkID09PSBpZCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIWdldEZpbHRlcmVkRGV2aWNlcygpLnNvbWUoKGRldmljZSkgPT4gZGV2aWNlLmlkID09PSBpZCkpIHtcbiAgICAgICAgLy8gRG9uJ3QgbGVhdmUgdGhlIGxpbmtlZCBkZXZpY2UgaGlkZGVuIGJlaGluZCBhIHNlYXJjaCBxdWVyeVxuICAgICAgICBzdGF0ZS5xdWVyeSA9ICcnO1xuICAgICAgICAkKCdTZWFyY2gnKS52YWx1ZSA9ICcnO1xuICAgICAgICByZW5kZXJEZXZpY2VMaXN0KCk7XG4gICAgfVxuICAgIHNlbGVjdERldmljZShpZCk7XG4gICAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmRldmljZVthcmlhLXByZXNzZWQ9XCJ0cnVlXCJdJyk7XG4gICAgaWYgKGJ1dHRvbikge1xuICAgICAgICBidXR0b24uc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogJ25lYXJlc3QnIH0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc2hvd0xvYWRFcnJvcigpIHtcbiAgICBjb25zdCBzdGF0dXMgPSAkKCdMaXN0U3RhdHVzJyk7XG4gICAgc3RhdHVzLnRleHRDb250ZW50ID0gJ0ZhaWxlZCB0byBmZXRjaCBkZXZpY2UgaW5mby4gJztcbiAgICBjb25zdCByZXRyeSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgIHJldHJ5LnR5cGUgPSAnYnV0dG9uJztcbiAgICByZXRyeS5jbGFzc05hbWUgPSAnYnV0dG9uLWxpbmsnO1xuICAgIHJldHJ5LnRleHRDb250ZW50ID0gJ1RyeSBhZ2Fpbic7XG4gICAgcmV0cnkuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsb2FkKTtcbiAgICBzdGF0dXMuYXBwZW5kKHJldHJ5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbG9hZCgpIHtcbiAgICAkKCdMaXN0U3RhdHVzJykudGV4dENvbnRlbnQgPSAnTG9hZGluZyBkZXZpY2Vz4oCmJztcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFZFUlNJT05TLm1hcChmZXRjaEluZGV4KSk7XG4gICAgcmVzdWx0cy5mb3JFYWNoKChyZXN1bHQsIGkpID0+IHtcbiAgICAgICAgc3RhdGUuaW5kZXhlc1tWRVJTSU9OU1tpXV0gPSByZXN1bHQuc3RhdHVzID09PSAnZnVsZmlsbGVkJyA/IHJlc3VsdC52YWx1ZSA6IG51bGw7XG4gICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSAncmVqZWN0ZWQnKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYEZhaWxlZCB0byBmZXRjaCAke1ZFUlNJT05TW2ldfSBpbmRleGAsIHJlc3VsdC5yZWFzb24pO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBtZXJnZURldmljZXMoKTtcbiAgICByZW5kZXJWZXJzaW9uTGFiZWxzKCk7XG4gICAgaWYgKHN0YXRlLmRldmljZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHNob3dMb2FkRXJyb3IoKTtcbiAgICB9XG4gICAgcmVuZGVyRGV2aWNlTGlzdCgpO1xuICAgIHJlbmRlckRldGFpbHMoKTtcbiAgICBzZWxlY3REZXZpY2VGcm9tSGFzaCgpO1xufVxuXG4kKCdOYXZiYXJJbWFnZScpLnNyYyA9IHRvb2xiYXJMb2dvO1xuJCgnVW5zdXBwb3J0ZWROb3RpY2UnKS5oaWRkZW4gPSAnc2VyaWFsJyBpbiBuYXZpZ2F0b3I7XG5cbiQoJ1NlYXJjaCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKGV2ZW50KSA9PiB7XG4gICAgc3RhdGUucXVlcnkgPSBldmVudC50YXJnZXQudmFsdWU7XG4gICAgcmVuZGVyRGV2aWNlTGlzdCgpO1xufSk7XG5cbiQoJ1NlYXJjaCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoZXZlbnQpID0+IHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRW50ZXInKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gZ2V0RmlsdGVyZWREZXZpY2VzKClbMF07XG4gICAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICAgICAgc2VsZWN0RGV2aWNlKGZpcnN0LmlkKTtcbiAgICAgICAgfVxuICAgIH1cbn0pO1xuXG4kKCdEZXZpY2VMaXN0JykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHtcbiAgICBjb25zdCBidXR0b24gPSBldmVudC50YXJnZXQuY2xvc2VzdCgnLmRldmljZScpO1xuICAgIGlmIChidXR0b24pIHtcbiAgICAgICAgc2VsZWN0RGV2aWNlKGJ1dHRvbi5kYXRhc2V0LmlkKTtcbiAgICB9XG59KTtcblxuJCgnVmVyc2lvbk9wdGlvbnMnKS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICBzdGF0ZS5wcmVmZXJyZWRWZXJzaW9uID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHJlbmRlckRldmljZUxpc3QoKTtcbiAgICByZW5kZXJEZXRhaWxzKCk7XG59KTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCBzZWxlY3REZXZpY2VGcm9tSGFzaCk7XG5cbmxvYWQoKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index b361844..0000000 --- a/docs/index.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - Tactility Web Installer - - - - -
-
- - - Tactility Web Installer - - -
-
- -
-
-

Install Tactility on your device

-

Connect your ESP32 device over USB, pick it from the list and flash it straight from the browser.

-
- - - -
-
-

1Choose your device

- - - -

Loading devices…

-
    -
    - -
    -

    2Pick a version and install

    - -

    Select a device to continue.

    - - -
    -
    -
    - - - diff --git a/docs/node_modules_esp-web-tools_dist_no-port-picked_index_js.bundle.js b/docs/node_modules_esp-web-tools_dist_no-port-picked_index_js.bundle.js deleted file mode 100644 index 82a8528..0000000 --- a/docs/node_modules_esp-web-tools_dist_no-port-picked_index_js.bundle.js +++ /dev/null @@ -1,250 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esp-web-tools_dist_no-port-picked_index_js"],{ - -/***/ "./node_modules/esp-web-tools/dist/no-port-picked/index.js": -/*!*****************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/no-port-picked/index.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ openNoPortPickedDialog: () => (/* binding */ openNoPortPickedDialog) -/* harmony export */ }); -/* harmony import */ var _no_port_picked_dialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./no-port-picked-dialog */ "./node_modules/esp-web-tools/dist/no-port-picked/no-port-picked-dialog.js"); - -const openNoPortPickedDialog = async (doTryAgain) => { - const dialog = document.createElement("ewt-no-port-picked-dialog"); - dialog.doTryAgain = doTryAgain; - document.body.append(dialog); - return true; -}; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/no-port-picked/no-port-picked-dialog.js": -/*!*********************************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/no-port-picked/no-port-picked-dialog.js ***! - \*********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _components_ew_dialog__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/ew-dialog */ "./node_modules/esp-web-tools/dist/components/ew-dialog.js"); -/* harmony import */ var _components_ew_text_button__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/ew-text-button */ "./node_modules/esp-web-tools/dist/components/ew-text-button.js"); -/* harmony import */ var _styles__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../styles */ "./node_modules/esp-web-tools/dist/styles.js"); -/* harmony import */ var _util_get_operating_system__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/get-operating-system */ "./node_modules/esp-web-tools/dist/util/get-operating-system.js"); - - - - - - - -const cloudDownload = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - - - -`; -let EwtNoPortPickedDialog = class EwtNoPortPickedDialog extends lit__WEBPACK_IMPORTED_MODULE_0__.LitElement { - render() { - const OS = (0,_util_get_operating_system__WEBPACK_IMPORTED_MODULE_5__.getOperatingSystem)(); - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - -
    No port selected
    -
    -
    - If you didn't select a port because you didn't see your device - listed, try the following steps: -
    -
      -
    1. - Make sure that the device is connected to this computer (the one - that runs the browser that shows this website) -
    2. -
    3. - Most devices have a tiny light when it is powered on. If yours has - one, make sure it is on. -
    4. -
    5. - Make sure that the USB cable you use can be used for data and is - not a power-only cable. -
    6. - ${OS === "Linux" - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    7. - If you are using a Linux flavor, make sure that your user is - part of the dialout group so it has permission - to access the device. - sudo usermod -a -G dialout YourUserName - You may need to log out & back in or reboot to activate the - new group access. -
    8. - ` - : ""} -
    9. - Make sure you have the right drivers installed. Below are the - drivers for common chips used in ESP devices: -
        -
      • - CP2102 drivers: - Windows & Mac -
      • -
      • - CH342, CH343, CH9102 drivers: - Windows, - Mac -
        - (download via blue button with ${cloudDownload} icon) -
      • -
      • - CH340, CH341 drivers: - Windows, - Mac -
        - (download via blue button with ${cloudDownload} icon) -
      • -
      -
    10. -
    -
    -
    - ${this.doTryAgain - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - Cancel - - Try Again - - ` - : (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - Close - `} -
    -
    - `; - } - tryAgain() { - var _a; - this.close(); - (_a = this.doTryAgain) === null || _a === void 0 ? void 0 : _a.call(this); - } - close() { - this.shadowRoot.querySelector("ew-dialog").close(); - } - async _handleClose() { - this.parentNode.removeChild(this); - } -}; -EwtNoPortPickedDialog.styles = [ - _styles__WEBPACK_IMPORTED_MODULE_4__.dialogStyles, - (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) ` - li + li, - li > ul { - margin-top: 8px; - } - ul, - ol { - margin-bottom: 0; - padding-left: 1.5em; - } - li code.block { - display: block; - margin: 0.5em 0; - } - `, -]; -EwtNoPortPickedDialog = (0,tslib__WEBPACK_IMPORTED_MODULE_6__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.customElement)("ewt-no-port-picked-dialog") -], EwtNoPortPickedDialog); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/get-operating-system.js": -/*!**********************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/get-operating-system.js ***! - \**********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ getOperatingSystem: () => (/* binding */ getOperatingSystem) -/* harmony export */ }); -// From https://stackoverflow.com/a/38241481 -const getOperatingSystem = () => { - var _a, _b; - const userAgent = window.navigator.userAgent; - const platform = - // @ts-expect-error - ((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgentData) === null || _b === void 0 ? void 0 : _b.platform) || window.navigator.platform; - const macosPlatforms = ["macOS", "Macintosh", "MacIntel", "MacPPC", "Mac68K"]; - const windowsPlatforms = ["Win32", "Win64", "Windows", "WinCE"]; - const iosPlatforms = ["iPhone", "iPad", "iPod"]; - if (macosPlatforms.indexOf(platform) !== -1) { - return "Mac OS"; - } - else if (iosPlatforms.indexOf(platform) !== -1) { - return "iOS"; - } - else if (windowsPlatforms.indexOf(platform) !== -1) { - return "Windows"; - } - else if (/Android/.test(userAgent)) { - return "Android"; - } - else if (/Linux/.test(platform)) { - return "Linux"; - } - return null; -}; - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcC13ZWItdG9vbHNfZGlzdF9uby1wb3J0LXBpY2tlZF9pbmRleF9qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBaUM7QUFDMUI7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDTm1DO0FBQ2M7QUFDQztBQUNqQjtBQUNLO0FBQ0c7QUFDeUI7QUFDbEUsc0JBQXNCLHdDQUFHO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qix1QkFBdUI7QUFDL0M7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRUFBZ0UsMkNBQVU7QUFDMUU7QUFDQSxtQkFBbUIsOEVBQWtCO0FBQ3JDLGVBQWUseUNBQUk7QUFDbkIsZ0NBQWdDLGtCQUFrQjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZCxjQUFjLHlDQUFJO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELGVBQWU7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQsZUFBZTtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1osY0FBYyx5Q0FBSTtBQUNsQix5Q0FBeUMsV0FBVztBQUNwRCx5Q0FBeUMsY0FBYztBQUN2RDtBQUNBO0FBQ0E7QUFDQSxjQUFjLHlDQUFJO0FBQ2xCLHlDQUF5QyxXQUFXO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksaURBQVk7QUFDaEIsSUFBSSx3Q0FBRztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixpREFBVTtBQUNsQyxJQUFJLGdFQUFhO0FBQ2pCOzs7Ozs7Ozs7Ozs7Ozs7QUNuS0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L25vLXBvcnQtcGlja2VkL2luZGV4LmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcC13ZWItdG9vbHMvZGlzdC9uby1wb3J0LXBpY2tlZC9uby1wb3J0LXBpY2tlZC1kaWFsb2cuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L3V0aWwvZ2V0LW9wZXJhdGluZy1zeXN0ZW0uanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwiLi9uby1wb3J0LXBpY2tlZC1kaWFsb2dcIjtcbmV4cG9ydCBjb25zdCBvcGVuTm9Qb3J0UGlja2VkRGlhbG9nID0gYXN5bmMgKGRvVHJ5QWdhaW4pID0+IHtcbiAgICBjb25zdCBkaWFsb2cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZXd0LW5vLXBvcnQtcGlja2VkLWRpYWxvZ1wiKTtcbiAgICBkaWFsb2cuZG9UcnlBZ2FpbiA9IGRvVHJ5QWdhaW47XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoZGlhbG9nKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4iLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBMaXRFbGVtZW50LCBodG1sLCBjc3MsIHN2ZyB9IGZyb20gXCJsaXRcIjtcbmltcG9ydCB7IGN1c3RvbUVsZW1lbnQgfSBmcm9tIFwibGl0L2RlY29yYXRvcnMuanNcIjtcbmltcG9ydCBcIi4uL2NvbXBvbmVudHMvZXctZGlhbG9nXCI7XG5pbXBvcnQgXCIuLi9jb21wb25lbnRzL2V3LXRleHQtYnV0dG9uXCI7XG5pbXBvcnQgeyBkaWFsb2dTdHlsZXMgfSBmcm9tIFwiLi4vc3R5bGVzXCI7XG5pbXBvcnQgeyBnZXRPcGVyYXRpbmdTeXN0ZW0gfSBmcm9tIFwiLi4vdXRpbC9nZXQtb3BlcmF0aW5nLXN5c3RlbVwiO1xuY29uc3QgY2xvdWREb3dubG9hZCA9IHN2ZyBgXG4gIDxzdmdcbiAgICB2ZXJzaW9uPVwiMS4xXCJcbiAgICBpZD1cIkNhcGFfMVwiXG4gICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCJcbiAgICB4PVwiMHB4XCJcbiAgICB5PVwiMHB4XCJcbiAgICB2aWV3Qm94PVwiMCAwIDUxMC4zMjIgNTEwLjMyMlwiXG4gICAgeG1sOnNwYWNlPVwicHJlc2VydmVcIlxuICAgIHN0eWxlPVwid2lkdGg6IDI4cHg7IHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XCJcbiAgPlxuICAgIDxnPlxuICAgICAgPHBhdGhcbiAgICAgICAgc3R5bGU9XCJmaWxsOmN1cnJlbnRDb2xvcjtcIlxuICAgICAgICBkPVwiTTQyOS4wNjQsMTU5LjUwNWMwLTAuMTUxLDAuMDg2LTEuMDU3LDAuMDg2LTEuMDU3YzAtNzUuMjgyLTYxLjI2MS0xMzYuNTIxLTEzNi41NDMtMTM2LjUyMSAgICBjLTUyLjI0NCwwLTk3Ljg2NywzMC41ODctMTIwLjc1Myw3Ni4zMzljLTExLjY3LTkuMDgxLTI1LjEwOC0xNS42ODItNDAuMjczLTE1LjY4MmMtMzcuMTY2LDAtNjcuMzg3LDMwLjE5OS02Ny4zODcsNjcuMzg3ICAgIGMwLDAsMC40NTMsMy4yNzksMC43OTgsNS44MjRDMjcuMDUsMTY4LjcxNiwwLDIwMy40MjMsMCwyNDQuNTE2YzAsMjUuMzg5LDkuOTAxLDQ5LjI2OCwyNy44NDgsNjcuMTcxICAgIGMxNy45NjgsMTcuOTksNDEuODA0LDI3Ljg2OSw2Ny4xOTMsMjcuODY5aDEzMC4yNDR2NDYuODNoLTU0LjY2bDk3LjY5NCwxMDIuMDA4bDk1LjYwMi0xMDIuMDA4aC01NC42NnYtNDYuODNINDE5LjI1ICAgIGM1MC4xNzQsMCw5MS4wNzItNDAuODU1LDkxLjA3Mi05MC45ODZDNTEwLjMsMjAxLjgyNyw0NzQuNDI4LDE2NC42MzksNDI5LjA2NCwxNTkuNTA1eiBNNDE5LjIwNywzMTIuNzQ0SDMwOS4yNnYtNTUuNTQ1aC04My45NzUgICAgdjU1LjU0NUg5NS4wMTljLTE4LjE4NCwwLTM1LjMzMy03LjA3NS00OC4yMTEtMTkuOTk2Yy0xMi44NzgtMTIuODc4LTE5Ljk1My0zMC4wMDUtMTkuOTUzLTQ4LjE4OSAgICBjMC0zMi42OCwyMy4yMS02MC44MDgsNTUuMjY0LTY2Ljk1NmwxMi41MTEtMi4zOTRsLTIuMDkyLTE0LjQzMWwtMS40ODgtMTAuNzg1YzAtMjIuMzQ3LDE4LjE4NC00MC41MSw0MC41MzEtNDAuNTEgICAgYzEzLjI2NiwwLDI1LjY5MSw2LjUxNCwzMy4zMDUsMTcuNDA4bDE1LjIyOSwyMS44NzNsOC41Mi0yNS4zMDNjMTUuMDEzLTQ0LjY1Miw1Ni43OTYtNzQuNjU2LDEwMy45MDYtNzQuNjU2ICAgIGM2MC41MDYsMCwxMDkuNzA5LDQ5LjIwMywxMDkuNzA5LDEwOS42NDRsLTEuMzM3LDI1LjcxMmwxNS4xMjEsMC4zMDJsMy4xNDktMC4wODZjMzUuNDE5LDAsNjQuMjE2LDI4Ljc5Nyw2NC4yMTYsNjQuMjE2ICAgIEM0ODMuNDAxLDI4My45NjksNDU0LjYwNCwzMTIuNzQ0LDQxOS4yMDcsMzEyLjc0NHpcIlxuICAgICAgLz5cbiAgICA8L2c+XG4gIDwvc3ZnPlxuYDtcbmxldCBFd3ROb1BvcnRQaWNrZWREaWFsb2cgPSBjbGFzcyBFd3ROb1BvcnRQaWNrZWREaWFsb2cgZXh0ZW5kcyBMaXRFbGVtZW50IHtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IE9TID0gZ2V0T3BlcmF0aW5nU3lzdGVtKCk7XG4gICAgICAgIHJldHVybiBodG1sIGBcbiAgICAgIDxldy1kaWFsb2cgb3BlbiBAY2xvc2VkPSR7dGhpcy5faGFuZGxlQ2xvc2V9PlxuICAgICAgICA8ZGl2IHNsb3Q9XCJoZWFkbGluZVwiPk5vIHBvcnQgc2VsZWN0ZWQ8L2Rpdj5cbiAgICAgICAgPGRpdiBzbG90PVwiY29udGVudFwiPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICBJZiB5b3UgZGlkbid0IHNlbGVjdCBhIHBvcnQgYmVjYXVzZSB5b3UgZGlkbid0IHNlZSB5b3VyIGRldmljZVxuICAgICAgICAgICAgbGlzdGVkLCB0cnkgdGhlIGZvbGxvd2luZyBzdGVwczpcbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8b2w+XG4gICAgICAgICAgICA8bGk+XG4gICAgICAgICAgICAgIE1ha2Ugc3VyZSB0aGF0IHRoZSBkZXZpY2UgaXMgY29ubmVjdGVkIHRvIHRoaXMgY29tcHV0ZXIgKHRoZSBvbmVcbiAgICAgICAgICAgICAgdGhhdCBydW5zIHRoZSBicm93c2VyIHRoYXQgc2hvd3MgdGhpcyB3ZWJzaXRlKVxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAgTW9zdCBkZXZpY2VzIGhhdmUgYSB0aW55IGxpZ2h0IHdoZW4gaXQgaXMgcG93ZXJlZCBvbi4gSWYgeW91cnMgaGFzXG4gICAgICAgICAgICAgIG9uZSwgbWFrZSBzdXJlIGl0IGlzIG9uLlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAgTWFrZSBzdXJlIHRoYXQgdGhlIFVTQiBjYWJsZSB5b3UgdXNlIGNhbiBiZSB1c2VkIGZvciBkYXRhIGFuZCBpc1xuICAgICAgICAgICAgICBub3QgYSBwb3dlci1vbmx5IGNhYmxlLlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICR7T1MgPT09IFwiTGludXhcIlxuICAgICAgICAgICAgPyBodG1sIGBcbiAgICAgICAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAgICAgICAgSWYgeW91IGFyZSB1c2luZyBhIExpbnV4IGZsYXZvciwgbWFrZSBzdXJlIHRoYXQgeW91ciB1c2VyIGlzXG4gICAgICAgICAgICAgICAgICAgIHBhcnQgb2YgdGhlIDxjb2RlPmRpYWxvdXQ8L2NvZGU+IGdyb3VwIHNvIGl0IGhhcyBwZXJtaXNzaW9uXG4gICAgICAgICAgICAgICAgICAgIHRvIGFjY2VzcyB0aGUgZGV2aWNlLlxuICAgICAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImJsb2NrXCJcbiAgICAgICAgICAgICAgICAgICAgICA+c3VkbyB1c2VybW9kIC1hIC1HIGRpYWxvdXQgWW91clVzZXJOYW1lPC9jb2RlXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgWW91IG1heSBuZWVkIHRvIGxvZyBvdXQgJiBiYWNrIGluIG9yIHJlYm9vdCB0byBhY3RpdmF0ZSB0aGVcbiAgICAgICAgICAgICAgICAgICAgbmV3IGdyb3VwIGFjY2Vzcy5cbiAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgYFxuICAgICAgICAgICAgOiBcIlwifVxuICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICBNYWtlIHN1cmUgeW91IGhhdmUgdGhlIHJpZ2h0IGRyaXZlcnMgaW5zdGFsbGVkLiBCZWxvdyBhcmUgdGhlXG4gICAgICAgICAgICAgIGRyaXZlcnMgZm9yIGNvbW1vbiBjaGlwcyB1c2VkIGluIEVTUCBkZXZpY2VzOlxuICAgICAgICAgICAgICA8dWw+XG4gICAgICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICAgICAgQ1AyMTAyIGRyaXZlcnM6XG4gICAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgICBocmVmPVwiaHR0cHM6Ly93d3cuc2lsYWJzLmNvbS9kZXZlbG9wZXJzL3VzYi10by11YXJ0LWJyaWRnZS12Y3AtZHJpdmVyc1wiXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgICAgIHJlbD1cIm5vb3BlbmVyXCJcbiAgICAgICAgICAgICAgICAgICAgPldpbmRvd3MgJiBNYWM8L2FcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAgICAgIENIMzQyLCBDSDM0MywgQ0g5MTAyIGRyaXZlcnM6XG4gICAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgICBocmVmPVwiaHR0cHM6Ly93d3cud2NoLmNuL2Rvd25sb2Fkcy9DSDM0M1NFUl9aSVAuaHRtbFwiXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgICAgIHJlbD1cIm5vb3BlbmVyXCJcbiAgICAgICAgICAgICAgICAgICAgPldpbmRvd3M8L2FcbiAgICAgICAgICAgICAgICAgID4sXG4gICAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgICBocmVmPVwiaHR0cHM6Ly93d3cud2NoLmNuL2Rvd25sb2Fkcy9DSDM0WFNFUl9NQUNfWklQLmh0bWxcIlxuICAgICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgICAgICByZWw9XCJub29wZW5lclwiXG4gICAgICAgICAgICAgICAgICAgID5NYWM8L2FcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxiciAvPlxuICAgICAgICAgICAgICAgICAgKGRvd25sb2FkIHZpYSBibHVlIGJ1dHRvbiB3aXRoICR7Y2xvdWREb3dubG9hZH0gaWNvbilcbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAgICAgIENIMzQwLCBDSDM0MSBkcml2ZXJzOlxuICAgICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICAgaHJlZj1cImh0dHBzOi8vd3d3LndjaC5jbi9kb3dubG9hZHMvQ0gzNDFTRVJfWklQLmh0bWxcIlxuICAgICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgICAgICByZWw9XCJub29wZW5lclwiXG4gICAgICAgICAgICAgICAgICAgID5XaW5kb3dzPC9hXG4gICAgICAgICAgICAgICAgICA+LFxuICAgICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICAgaHJlZj1cImh0dHBzOi8vd3d3LndjaC5jbi9kb3dubG9hZHMvQ0gzNDFTRVJfTUFDX1pJUC5odG1sXCJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgICAgICAgcmVsPVwibm9vcGVuZXJcIlxuICAgICAgICAgICAgICAgICAgICA+TWFjPC9hXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8YnIgLz5cbiAgICAgICAgICAgICAgICAgIChkb3dubG9hZCB2aWEgYmx1ZSBidXR0b24gd2l0aCAke2Nsb3VkRG93bmxvYWR9IGljb24pXG4gICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgPC9vbD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgc2xvdD1cImFjdGlvbnNcIj5cbiAgICAgICAgICAke3RoaXMuZG9UcnlBZ2FpblxuICAgICAgICAgICAgPyBodG1sIGBcbiAgICAgICAgICAgICAgICA8ZXctdGV4dC1idXR0b24gQGNsaWNrPSR7dGhpcy5jbG9zZX0+Q2FuY2VsPC9ldy10ZXh0LWJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8ZXctdGV4dC1idXR0b24gQGNsaWNrPSR7dGhpcy50cnlBZ2Fpbn0+XG4gICAgICAgICAgICAgICAgICBUcnkgQWdhaW5cbiAgICAgICAgICAgICAgICA8L2V3LXRleHQtYnV0dG9uPlxuICAgICAgICAgICAgICBgXG4gICAgICAgICAgICA6IGh0bWwgYFxuICAgICAgICAgICAgICAgIDxldy10ZXh0LWJ1dHRvbiBAY2xpY2s9JHt0aGlzLmNsb3NlfT5DbG9zZTwvZXctdGV4dC1idXR0b24+XG4gICAgICAgICAgICAgIGB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9ldy1kaWFsb2c+XG4gICAgYDtcbiAgICB9XG4gICAgdHJ5QWdhaW4oKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAoX2EgPSB0aGlzLmRvVHJ5QWdhaW4pID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jYWxsKHRoaXMpO1xuICAgIH1cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoXCJldy1kaWFsb2dcIikuY2xvc2UoKTtcbiAgICB9XG4gICAgYXN5bmMgX2hhbmRsZUNsb3NlKCkge1xuICAgICAgICB0aGlzLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcyk7XG4gICAgfVxufTtcbkV3dE5vUG9ydFBpY2tlZERpYWxvZy5zdHlsZXMgPSBbXG4gICAgZGlhbG9nU3R5bGVzLFxuICAgIGNzcyBgXG4gICAgICBsaSArIGxpLFxuICAgICAgbGkgPiB1bCB7XG4gICAgICAgIG1hcmdpbi10b3A6IDhweDtcbiAgICAgIH1cbiAgICAgIHVsLFxuICAgICAgb2wge1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAwO1xuICAgICAgICBwYWRkaW5nLWxlZnQ6IDEuNWVtO1xuICAgICAgfVxuICAgICAgbGkgY29kZS5ibG9jayB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICBtYXJnaW46IDAuNWVtIDA7XG4gICAgICB9XG4gICAgYCxcbl07XG5Fd3ROb1BvcnRQaWNrZWREaWFsb2cgPSBfX2RlY29yYXRlKFtcbiAgICBjdXN0b21FbGVtZW50KFwiZXd0LW5vLXBvcnQtcGlja2VkLWRpYWxvZ1wiKVxuXSwgRXd0Tm9Qb3J0UGlja2VkRGlhbG9nKTtcbiIsIi8vIEZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM4MjQxNDgxXG5leHBvcnQgY29uc3QgZ2V0T3BlcmF0aW5nU3lzdGVtID0gKCkgPT4ge1xuICAgIHZhciBfYSwgX2I7XG4gICAgY29uc3QgdXNlckFnZW50ID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgY29uc3QgcGxhdGZvcm0gPSBcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgKChfYiA9IChfYSA9IHdpbmRvdy5uYXZpZ2F0b3IpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS51c2VyQWdlbnREYXRhKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IucGxhdGZvcm0pIHx8IHdpbmRvdy5uYXZpZ2F0b3IucGxhdGZvcm07XG4gICAgY29uc3QgbWFjb3NQbGF0Zm9ybXMgPSBbXCJtYWNPU1wiLCBcIk1hY2ludG9zaFwiLCBcIk1hY0ludGVsXCIsIFwiTWFjUFBDXCIsIFwiTWFjNjhLXCJdO1xuICAgIGNvbnN0IHdpbmRvd3NQbGF0Zm9ybXMgPSBbXCJXaW4zMlwiLCBcIldpbjY0XCIsIFwiV2luZG93c1wiLCBcIldpbkNFXCJdO1xuICAgIGNvbnN0IGlvc1BsYXRmb3JtcyA9IFtcImlQaG9uZVwiLCBcImlQYWRcIiwgXCJpUG9kXCJdO1xuICAgIGlmIChtYWNvc1BsYXRmb3Jtcy5pbmRleE9mKHBsYXRmb3JtKSAhPT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIFwiTWFjIE9TXCI7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlvc1BsYXRmb3Jtcy5pbmRleE9mKHBsYXRmb3JtKSAhPT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIFwiaU9TXCI7XG4gICAgfVxuICAgIGVsc2UgaWYgKHdpbmRvd3NQbGF0Zm9ybXMuaW5kZXhPZihwbGF0Zm9ybSkgIT09IC0xKSB7XG4gICAgICAgIHJldHVybiBcIldpbmRvd3NcIjtcbiAgICB9XG4gICAgZWxzZSBpZiAoL0FuZHJvaWQvLnRlc3QodXNlckFnZW50KSkge1xuICAgICAgICByZXR1cm4gXCJBbmRyb2lkXCI7XG4gICAgfVxuICAgIGVsc2UgaWYgKC9MaW51eC8udGVzdChwbGF0Zm9ybSkpIHtcbiAgICAgICAgcmV0dXJuIFwiTGludXhcIjtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32_js.bundle.js deleted file mode 100644 index fc46365..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32_js.bundle.js +++ /dev/null @@ -1,205 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32.js": -/*!******************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32.js ***! - \******************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32ROM: () => (/* binding */ ESP32ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32"; - this.IMAGE_CHIP_ID = 0; - this.EFUSE_RD_REG_BASE = 0x3ff5a000; - this.DR_REG_SYSCON_BASE = 0x3ff66000; - this.UART_CLKDIV_REG = 0x3ff40014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x60000078; - this.XTAL_CLK_DIVIDER = 1; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0x1000; - this.SPI_REG_BASE = 0x3ff42000; - this.SPI_USR_OFFS = 0x1c; - this.SPI_USR1_OFFS = 0x20; - this.SPI_USR2_OFFS = 0x24; - this.SPI_W0_OFFS = 0x80; - this.SPI_MOSI_DLEN_OFFS = 0x28; - this.SPI_MISO_DLEN_OFFS = 0x2c; - } - async readEfuse(loader, offset) { - const addr = this.EFUSE_RD_REG_BASE + 4 * offset; - loader.debug("Read efuse " + addr); - return await loader.readReg(addr); - } - async getPkgVersion(loader) { - const word3 = await this.readEfuse(loader, 3); - let pkgVersion = (word3 >> 9) & 0x07; - pkgVersion += ((word3 >> 2) & 0x1) << 3; - return pkgVersion; - } - async getChipRevision(loader) { - const word3 = await this.readEfuse(loader, 3); - const word5 = await this.readEfuse(loader, 5); - const apbCtlDate = await loader.readReg(this.DR_REG_SYSCON_BASE + 0x7c); - const revBit0 = (word3 >> 15) & 0x1; - const revBit1 = (word5 >> 20) & 0x1; - const revBit2 = (apbCtlDate >> 31) & 0x1; - if (revBit0 != 0) { - if (revBit1 != 0) { - if (revBit2 != 0) { - return 3; - } - else { - return 2; - } - } - else { - return 1; - } - } - return 0; - } - async getChipDescription(loader) { - const chipDesc = [ - "ESP32-D0WDQ6", - "ESP32-D0WD", - "ESP32-D2WD", - "", - "ESP32-U4WDH", - "ESP32-PICO-D4", - "ESP32-PICO-V3-02", - ]; - let chipName = ""; - const pkgVersion = await this.getPkgVersion(loader); - const chipRevision = await this.getChipRevision(loader); - const rev3 = chipRevision == 3; - const single_core = (await this.readEfuse(loader, 3)) & (1 << 0); - if (single_core != 0) { - chipDesc[0] = "ESP32-S0WDQ6"; - chipDesc[1] = "ESP32-S0WD"; - } - if (rev3) { - chipDesc[5] = "ESP32-PICO-V3"; - } - if (pkgVersion >= 0 && pkgVersion <= 6) { - chipName = chipDesc[pkgVersion]; - } - else { - chipName = "Unknown ESP32"; - } - if (rev3 && (pkgVersion === 0 || pkgVersion === 1)) { - chipName += "-V3"; - } - return chipName + " (revision " + chipRevision + ")"; - } - async getChipFeatures(loader) { - const features = ["Wi-Fi"]; - const word3 = await this.readEfuse(loader, 3); - const chipVerDisBt = word3 & (1 << 1); - if (chipVerDisBt === 0) { - features.push(" BT"); - } - const chipVerDisAppCpu = word3 & (1 << 0); - if (chipVerDisAppCpu !== 0) { - features.push(" Single Core"); - } - else { - features.push(" Dual Core"); - } - const chipCpuFreqRated = word3 & (1 << 13); - if (chipCpuFreqRated !== 0) { - const chipCpuFreqLow = word3 & (1 << 12); - if (chipCpuFreqLow !== 0) { - features.push(" 160MHz"); - } - else { - features.push(" 240MHz"); - } - } - const pkgVersion = await this.getPkgVersion(loader); - if ([2, 4, 5, 6].indexOf(pkgVersion) !== -1) { - features.push(" Embedded Flash"); - } - if (pkgVersion === 6) { - features.push(" Embedded PSRAM"); - } - const word4 = await this.readEfuse(loader, 4); - const adcVref = (word4 >> 8) & 0x1f; - if (adcVref !== 0) { - features.push(" VRef calibration in efuse"); - } - const blk3PartRes = (word3 >> 14) & 0x1; - if (blk3PartRes !== 0) { - features.push(" BLK3 partially reserved"); - } - const word6 = await this.readEfuse(loader, 6); - const codingScheme = word6 & 0x3; - const codingSchemeArr = ["None", "3/4", "Repeat (UNSUPPORTED)", "Invalid"]; - features.push(" Coding Scheme " + codingSchemeArr[codingScheme]); - return features; - } - async getCrystalFreq(loader) { - const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK; - const etsXtal = (loader.transport.baudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; - let normXtal; - if (etsXtal > 33) { - normXtal = 40; - } - else { - normXtal = 26; - } - if (Math.abs(normXtal - etsXtal) > 1) { - loader.info("WARNING: Unsupported crystal in use"); - } - return normXtal; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await this.readEfuse(loader, 1); - mac0 = mac0 >>> 0; - let mac1 = await this.readEfuse(loader, 2); - mac1 = mac1 >>> 0; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJfanMuYnVuZGxlLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBQStCO0FBQ3hCLHVCQUF1Qix3Q0FBRztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3B0b29sLWpzL2xpYi90YXJnZXRzL2VzcDMyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJPTSB9IGZyb20gXCIuL3JvbS5qc1wiO1xuZXhwb3J0IGNsYXNzIEVTUDMyUk9NIGV4dGVuZHMgUk9NIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5DSElQX05BTUUgPSBcIkVTUDMyXCI7XG4gICAgICAgIHRoaXMuSU1BR0VfQ0hJUF9JRCA9IDA7XG4gICAgICAgIHRoaXMuRUZVU0VfUkRfUkVHX0JBU0UgPSAweDNmZjVhMDAwO1xuICAgICAgICB0aGlzLkRSX1JFR19TWVNDT05fQkFTRSA9IDB4M2ZmNjYwMDA7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfUkVHID0gMHgzZmY0MDAxNDtcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9NQVNLID0gMHhmZmZmZjtcbiAgICAgICAgdGhpcy5VQVJUX0RBVEVfUkVHX0FERFIgPSAweDYwMDAwMDc4O1xuICAgICAgICB0aGlzLlhUQUxfQ0xLX0RJVklERVIgPSAxO1xuICAgICAgICB0aGlzLkZMQVNIX1NJWkVTID0ge1xuICAgICAgICAgICAgXCIxTUJcIjogMHgwMCxcbiAgICAgICAgICAgIFwiMk1CXCI6IDB4MTAsXG4gICAgICAgICAgICBcIjRNQlwiOiAweDIwLFxuICAgICAgICAgICAgXCI4TUJcIjogMHgzMCxcbiAgICAgICAgICAgIFwiMTZNQlwiOiAweDQwLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLkZMQVNIX1dSSVRFX1NJWkUgPSAweDQwMDtcbiAgICAgICAgdGhpcy5CT09UTE9BREVSX0ZMQVNIX09GRlNFVCA9IDB4MTAwMDtcbiAgICAgICAgdGhpcy5TUElfUkVHX0JBU0UgPSAweDNmZjQyMDAwO1xuICAgICAgICB0aGlzLlNQSV9VU1JfT0ZGUyA9IDB4MWM7XG4gICAgICAgIHRoaXMuU1BJX1VTUjFfT0ZGUyA9IDB4MjA7XG4gICAgICAgIHRoaXMuU1BJX1VTUjJfT0ZGUyA9IDB4MjQ7XG4gICAgICAgIHRoaXMuU1BJX1cwX09GRlMgPSAweDgwO1xuICAgICAgICB0aGlzLlNQSV9NT1NJX0RMRU5fT0ZGUyA9IDB4Mjg7XG4gICAgICAgIHRoaXMuU1BJX01JU09fRExFTl9PRkZTID0gMHgyYztcbiAgICB9XG4gICAgYXN5bmMgcmVhZEVmdXNlKGxvYWRlciwgb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IGFkZHIgPSB0aGlzLkVGVVNFX1JEX1JFR19CQVNFICsgNCAqIG9mZnNldDtcbiAgICAgICAgbG9hZGVyLmRlYnVnKFwiUmVhZCBlZnVzZSBcIiArIGFkZHIpO1xuICAgICAgICByZXR1cm4gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgfVxuICAgIGFzeW5jIGdldFBrZ1ZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IHdvcmQzID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCAzKTtcbiAgICAgICAgbGV0IHBrZ1ZlcnNpb24gPSAod29yZDMgPj4gOSkgJiAweDA3O1xuICAgICAgICBwa2dWZXJzaW9uICs9ICgod29yZDMgPj4gMikgJiAweDEpIDw8IDM7XG4gICAgICAgIHJldHVybiBwa2dWZXJzaW9uO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwUmV2aXNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IHdvcmQzID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCAzKTtcbiAgICAgICAgY29uc3Qgd29yZDUgPSBhd2FpdCB0aGlzLnJlYWRFZnVzZShsb2FkZXIsIDUpO1xuICAgICAgICBjb25zdCBhcGJDdGxEYXRlID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5EUl9SRUdfU1lTQ09OX0JBU0UgKyAweDdjKTtcbiAgICAgICAgY29uc3QgcmV2Qml0MCA9ICh3b3JkMyA+PiAxNSkgJiAweDE7XG4gICAgICAgIGNvbnN0IHJldkJpdDEgPSAod29yZDUgPj4gMjApICYgMHgxO1xuICAgICAgICBjb25zdCByZXZCaXQyID0gKGFwYkN0bERhdGUgPj4gMzEpICYgMHgxO1xuICAgICAgICBpZiAocmV2Qml0MCAhPSAwKSB7XG4gICAgICAgICAgICBpZiAocmV2Qml0MSAhPSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJldkJpdDIgIT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwRGVzY3JpcHRpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGNoaXBEZXNjID0gW1xuICAgICAgICAgICAgXCJFU1AzMi1EMFdEUTZcIixcbiAgICAgICAgICAgIFwiRVNQMzItRDBXRFwiLFxuICAgICAgICAgICAgXCJFU1AzMi1EMldEXCIsXG4gICAgICAgICAgICBcIlwiLFxuICAgICAgICAgICAgXCJFU1AzMi1VNFdESFwiLFxuICAgICAgICAgICAgXCJFU1AzMi1QSUNPLUQ0XCIsXG4gICAgICAgICAgICBcIkVTUDMyLVBJQ08tVjMtMDJcIixcbiAgICAgICAgXTtcbiAgICAgICAgbGV0IGNoaXBOYW1lID0gXCJcIjtcbiAgICAgICAgY29uc3QgcGtnVmVyc2lvbiA9IGF3YWl0IHRoaXMuZ2V0UGtnVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICBjb25zdCBjaGlwUmV2aXNpb24gPSBhd2FpdCB0aGlzLmdldENoaXBSZXZpc2lvbihsb2FkZXIpO1xuICAgICAgICBjb25zdCByZXYzID0gY2hpcFJldmlzaW9uID09IDM7XG4gICAgICAgIGNvbnN0IHNpbmdsZV9jb3JlID0gKGF3YWl0IHRoaXMucmVhZEVmdXNlKGxvYWRlciwgMykpICYgKDEgPDwgMCk7XG4gICAgICAgIGlmIChzaW5nbGVfY29yZSAhPSAwKSB7XG4gICAgICAgICAgICBjaGlwRGVzY1swXSA9IFwiRVNQMzItUzBXRFE2XCI7XG4gICAgICAgICAgICBjaGlwRGVzY1sxXSA9IFwiRVNQMzItUzBXRFwiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXYzKSB7XG4gICAgICAgICAgICBjaGlwRGVzY1s1XSA9IFwiRVNQMzItUElDTy1WM1wiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwa2dWZXJzaW9uID49IDAgJiYgcGtnVmVyc2lvbiA8PSA2KSB7XG4gICAgICAgICAgICBjaGlwTmFtZSA9IGNoaXBEZXNjW3BrZ1ZlcnNpb25dO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2hpcE5hbWUgPSBcIlVua25vd24gRVNQMzJcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmV2MyAmJiAocGtnVmVyc2lvbiA9PT0gMCB8fCBwa2dWZXJzaW9uID09PSAxKSkge1xuICAgICAgICAgICAgY2hpcE5hbWUgKz0gXCItVjNcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hpcE5hbWUgKyBcIiAocmV2aXNpb24gXCIgKyBjaGlwUmV2aXNpb24gKyBcIilcIjtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcEZlYXR1cmVzKGxvYWRlcikge1xuICAgICAgICBjb25zdCBmZWF0dXJlcyA9IFtcIldpLUZpXCJdO1xuICAgICAgICBjb25zdCB3b3JkMyA9IGF3YWl0IHRoaXMucmVhZEVmdXNlKGxvYWRlciwgMyk7XG4gICAgICAgIGNvbnN0IGNoaXBWZXJEaXNCdCA9IHdvcmQzICYgKDEgPDwgMSk7XG4gICAgICAgIGlmIChjaGlwVmVyRGlzQnQgPT09IDApIHtcbiAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goXCIgQlRcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hpcFZlckRpc0FwcENwdSA9IHdvcmQzICYgKDEgPDwgMCk7XG4gICAgICAgIGlmIChjaGlwVmVyRGlzQXBwQ3B1ICE9PSAwKSB7XG4gICAgICAgICAgICBmZWF0dXJlcy5wdXNoKFwiIFNpbmdsZSBDb3JlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZmVhdHVyZXMucHVzaChcIiBEdWFsIENvcmVcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hpcENwdUZyZXFSYXRlZCA9IHdvcmQzICYgKDEgPDwgMTMpO1xuICAgICAgICBpZiAoY2hpcENwdUZyZXFSYXRlZCAhPT0gMCkge1xuICAgICAgICAgICAgY29uc3QgY2hpcENwdUZyZXFMb3cgPSB3b3JkMyAmICgxIDw8IDEyKTtcbiAgICAgICAgICAgIGlmIChjaGlwQ3B1RnJlcUxvdyAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goXCIgMTYwTUh6XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZmVhdHVyZXMucHVzaChcIiAyNDBNSHpcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGtnVmVyc2lvbiA9IGF3YWl0IHRoaXMuZ2V0UGtnVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICBpZiAoWzIsIDQsIDUsIDZdLmluZGV4T2YocGtnVmVyc2lvbikgIT09IC0xKSB7XG4gICAgICAgICAgICBmZWF0dXJlcy5wdXNoKFwiIEVtYmVkZGVkIEZsYXNoXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwa2dWZXJzaW9uID09PSA2KSB7XG4gICAgICAgICAgICBmZWF0dXJlcy5wdXNoKFwiIEVtYmVkZGVkIFBTUkFNXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdvcmQ0ID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCA0KTtcbiAgICAgICAgY29uc3QgYWRjVnJlZiA9ICh3b3JkNCA+PiA4KSAmIDB4MWY7XG4gICAgICAgIGlmIChhZGNWcmVmICE9PSAwKSB7XG4gICAgICAgICAgICBmZWF0dXJlcy5wdXNoKFwiIFZSZWYgY2FsaWJyYXRpb24gaW4gZWZ1c2VcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYmxrM1BhcnRSZXMgPSAod29yZDMgPj4gMTQpICYgMHgxO1xuICAgICAgICBpZiAoYmxrM1BhcnRSZXMgIT09IDApIHtcbiAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goXCIgQkxLMyBwYXJ0aWFsbHkgcmVzZXJ2ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd29yZDYgPSBhd2FpdCB0aGlzLnJlYWRFZnVzZShsb2FkZXIsIDYpO1xuICAgICAgICBjb25zdCBjb2RpbmdTY2hlbWUgPSB3b3JkNiAmIDB4MztcbiAgICAgICAgY29uc3QgY29kaW5nU2NoZW1lQXJyID0gW1wiTm9uZVwiLCBcIjMvNFwiLCBcIlJlcGVhdCAoVU5TVVBQT1JURUQpXCIsIFwiSW52YWxpZFwiXTtcbiAgICAgICAgZmVhdHVyZXMucHVzaChcIiBDb2RpbmcgU2NoZW1lIFwiICsgY29kaW5nU2NoZW1lQXJyW2NvZGluZ1NjaGVtZV0pO1xuICAgICAgICByZXR1cm4gZmVhdHVyZXM7XG4gICAgfVxuICAgIGFzeW5jIGdldENyeXN0YWxGcmVxKGxvYWRlcikge1xuICAgICAgICBjb25zdCB1YXJ0RGl2ID0gKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuVUFSVF9DTEtESVZfUkVHKSkgJiB0aGlzLlVBUlRfQ0xLRElWX01BU0s7XG4gICAgICAgIGNvbnN0IGV0c1h0YWwgPSAobG9hZGVyLnRyYW5zcG9ydC5iYXVkcmF0ZSAqIHVhcnREaXYpIC8gMTAwMDAwMCAvIHRoaXMuWFRBTF9DTEtfRElWSURFUjtcbiAgICAgICAgbGV0IG5vcm1YdGFsO1xuICAgICAgICBpZiAoZXRzWHRhbCA+IDMzKSB7XG4gICAgICAgICAgICBub3JtWHRhbCA9IDQwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbm9ybVh0YWwgPSAyNjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTWF0aC5hYnMobm9ybVh0YWwgLSBldHNYdGFsKSA+IDEpIHtcbiAgICAgICAgICAgIGxvYWRlci5pbmZvKFwiV0FSTklORzogVW5zdXBwb3J0ZWQgY3J5c3RhbCBpbiB1c2VcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5vcm1YdGFsO1xuICAgIH1cbiAgICBfZDJoKGQpIHtcbiAgICAgICAgY29uc3QgaCA9ICgrZCkudG9TdHJpbmcoMTYpO1xuICAgICAgICByZXR1cm4gaC5sZW5ndGggPT09IDEgPyBcIjBcIiArIGggOiBoO1xuICAgIH1cbiAgICBhc3luYyByZWFkTWFjKGxvYWRlcikge1xuICAgICAgICBsZXQgbWFjMCA9IGF3YWl0IHRoaXMucmVhZEVmdXNlKGxvYWRlciwgMSk7XG4gICAgICAgIG1hYzAgPSBtYWMwID4+PiAwO1xuICAgICAgICBsZXQgbWFjMSA9IGF3YWl0IHRoaXMucmVhZEVmdXNlKGxvYWRlciwgMik7XG4gICAgICAgIG1hYzEgPSBtYWMxID4+PiAwO1xuICAgICAgICBjb25zdCBtYWMgPSBuZXcgVWludDhBcnJheSg2KTtcbiAgICAgICAgbWFjWzBdID0gKG1hYzEgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbMV0gPSBtYWMxICYgMHhmZjtcbiAgICAgICAgbWFjWzJdID0gKG1hYzAgPj4gMjQpICYgMHhmZjtcbiAgICAgICAgbWFjWzNdID0gKG1hYzAgPj4gMTYpICYgMHhmZjtcbiAgICAgICAgbWFjWzRdID0gKG1hYzAgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbNV0gPSBtYWMwICYgMHhmZjtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9kMmgobWFjWzBdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzFdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzJdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzNdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzRdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzVdKSk7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32c2_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32c2_js.bundle.js deleted file mode 100644 index 1dbe003..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32c2_js.bundle.js +++ /dev/null @@ -1,282 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32c2_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32c2.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32c2.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32C2ROM: () => (/* binding */ ESP32C2ROM) -/* harmony export */ }); -/* harmony import */ var _esp32c3_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./esp32c3.js */ "./node_modules/esptool-js/lib/targets/esp32c3.js"); - -class ESP32C2ROM extends _esp32c3_js__WEBPACK_IMPORTED_MODULE_0__.ESP32C3ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-C2"; - this.IMAGE_CHIP_ID = 12; - this.EFUSE_BASE = 0x60008800; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x040; - this.UART_CLKDIV_REG = 0x60000014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x6000007c; - this.XTAL_CLK_DIVIDER = 1; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.SPI_REG_BASE = 0x60002000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - } - async getPkgVersion(loader) { - const numWord = 1; - const block1Addr = this.EFUSE_BASE + 0x040; - const addr = block1Addr + 4 * numWord; - const word3 = await loader.readReg(addr); - const pkgVersion = (word3 >> 22) & 0x07; - return pkgVersion; - } - async getChipRevision(loader) { - const block1Addr = this.EFUSE_BASE + 0x040; - const numWord = 1; - const pos = 20; - const addr = block1Addr + 4 * numWord; - const ret = ((await loader.readReg(addr)) & (0x03 << pos)) >> pos; - return ret; - } - async getChipDescription(loader) { - let desc; - const pkgVer = await this.getPkgVersion(loader); - if (pkgVer === 0 || pkgVer === 1) { - desc = "ESP32-C2"; - } - else { - desc = "unknown ESP32-C2"; - } - const chip_rev = await this.getChipRevision(loader); - desc += " (revision " + chip_rev + ")"; - return desc; - } - async getChipFeatures(loader) { - return ["Wi-Fi", "BLE"]; - } - async getCrystalFreq(loader) { - const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK; - const etsXtal = (loader.transport.baudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; - let normXtal; - if (etsXtal > 33) { - normXtal = 40; - } - else { - normXtal = 26; - } - if (Math.abs(normXtal - etsXtal) > 1) { - loader.info("WARNING: Unsupported crystal in use"); - } - return normXtal; - } - async changeBaudRate(loader) { - const rom_with_26M_XTAL = await this.getCrystalFreq(loader); - if (rom_with_26M_XTAL === 26) { - loader.changeBaud(); - } - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/targets/esp32c3.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32c3.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32C3ROM: () => (/* binding */ ESP32C3ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32C3ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-C3"; - this.IMAGE_CHIP_ID = 5; - this.EFUSE_BASE = 0x60008800; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.UART_CLKDIV_REG = 0x3ff40014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x6000007c; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.SPI_REG_BASE = 0x60002000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - } - async getPkgVersion(loader) { - const numWord = 3; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const word3 = await loader.readReg(addr); - const pkgVersion = (word3 >> 21) & 0x07; - return pkgVersion; - } - async getChipRevision(loader) { - const block1Addr = this.EFUSE_BASE + 0x044; - const numWord = 3; - const pos = 18; - const addr = block1Addr + 4 * numWord; - const ret = ((await loader.readReg(addr)) & (0x7 << pos)) >> pos; - return ret; - } - async getChipDescription(loader) { - let desc; - const pkgVer = await this.getPkgVersion(loader); - if (pkgVer === 0) { - desc = "ESP32-C3"; - } - else { - desc = "unknown ESP32-C3"; - } - const chip_rev = await this.getChipRevision(loader); - desc += " (revision " + chip_rev + ")"; - return desc; - } - async getFlashCap(loader) { - const numWord = 3; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const registerValue = await loader.readReg(addr); - const flashCap = (registerValue >> 27) & 0x07; - return flashCap; - } - async getFlashVendor(loader) { - const numWord = 4; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const registerValue = await loader.readReg(addr); - const vendorId = (registerValue >> 0) & 0x07; - const vendorMap = { - 1: "XMC", - 2: "GD", - 3: "FM", - 4: "TT", - 5: "ZBIT", - }; - return vendorMap[vendorId] || ""; - } - async getChipFeatures(loader) { - const features = ["Wi-Fi", "BLE"]; - const flashMap = { - 0: null, - 1: "Embedded Flash 4MB", - 2: "Embedded Flash 2MB", - 3: "Embedded Flash 1MB", - 4: "Embedded Flash 8MB", - }; - const flashCap = await this.getFlashCap(loader); - const flashVendor = await this.getFlashVendor(loader); - const flash = flashMap[flashCap]; - const flashDescription = flash !== undefined ? flash : "Unknown Embedded Flash"; - if (flash !== null) { - features.push(`${flashDescription} (${flashVendor})`); - } - return features; - } - async getCrystalFreq(loader) { - return 40; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJjMl9qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBMEM7QUFDbkMseUJBQXlCLG1EQUFVO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FDakgrQjtBQUN4Qix5QkFBeUIsd0NBQUc7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixrQkFBa0IsR0FBRyxZQUFZO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3B0b29sLWpzL2xpYi90YXJnZXRzL2VzcDMyYzIuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwdG9vbC1qcy9saWIvdGFyZ2V0cy9lc3AzMmMzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVTUDMyQzNST00gfSBmcm9tIFwiLi9lc3AzMmMzLmpzXCI7XG5leHBvcnQgY2xhc3MgRVNQMzJDMlJPTSBleHRlbmRzIEVTUDMyQzNST00ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLkNISVBfTkFNRSA9IFwiRVNQMzItQzJcIjtcbiAgICAgICAgdGhpcy5JTUFHRV9DSElQX0lEID0gMTI7XG4gICAgICAgIHRoaXMuRUZVU0VfQkFTRSA9IDB4NjAwMDg4MDA7XG4gICAgICAgIHRoaXMuTUFDX0VGVVNFX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQwO1xuICAgICAgICB0aGlzLlVBUlRfQ0xLRElWX1JFRyA9IDB4NjAwMDAwMTQ7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfTUFTSyA9IDB4ZmZmZmY7XG4gICAgICAgIHRoaXMuVUFSVF9EQVRFX1JFR19BRERSID0gMHg2MDAwMDA3YztcbiAgICAgICAgdGhpcy5YVEFMX0NMS19ESVZJREVSID0gMTtcbiAgICAgICAgdGhpcy5GTEFTSF9XUklURV9TSVpFID0gMHg0MDA7XG4gICAgICAgIHRoaXMuQk9PVExPQURFUl9GTEFTSF9PRkZTRVQgPSAwO1xuICAgICAgICB0aGlzLkZMQVNIX1NJWkVTID0ge1xuICAgICAgICAgICAgXCIxTUJcIjogMHgwMCxcbiAgICAgICAgICAgIFwiMk1CXCI6IDB4MTAsXG4gICAgICAgICAgICBcIjRNQlwiOiAweDIwLFxuICAgICAgICAgICAgXCI4TUJcIjogMHgzMCxcbiAgICAgICAgICAgIFwiMTZNQlwiOiAweDQwLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLlNQSV9SRUdfQkFTRSA9IDB4NjAwMDIwMDA7XG4gICAgICAgIHRoaXMuU1BJX1VTUl9PRkZTID0gMHgxODtcbiAgICAgICAgdGhpcy5TUElfVVNSMV9PRkZTID0gMHgxYztcbiAgICAgICAgdGhpcy5TUElfVVNSMl9PRkZTID0gMHgyMDtcbiAgICAgICAgdGhpcy5TUElfTU9TSV9ETEVOX09GRlMgPSAweDI0O1xuICAgICAgICB0aGlzLlNQSV9NSVNPX0RMRU5fT0ZGUyA9IDB4Mjg7XG4gICAgICAgIHRoaXMuU1BJX1cwX09GRlMgPSAweDU4O1xuICAgIH1cbiAgICBhc3luYyBnZXRQa2dWZXJzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMTtcbiAgICAgICAgY29uc3QgYmxvY2sxQWRkciA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQwO1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCB3b3JkMyA9IGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpO1xuICAgICAgICBjb25zdCBwa2dWZXJzaW9uID0gKHdvcmQzID4+IDIyKSAmIDB4MDc7XG4gICAgICAgIHJldHVybiBwa2dWZXJzaW9uO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwUmV2aXNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGJsb2NrMUFkZHIgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0MDtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDE7XG4gICAgICAgIGNvbnN0IHBvcyA9IDIwO1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCByZXQgPSAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpKSAmICgweDAzIDw8IHBvcykpID4+IHBvcztcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcERlc2NyaXB0aW9uKGxvYWRlcikge1xuICAgICAgICBsZXQgZGVzYztcbiAgICAgICAgY29uc3QgcGtnVmVyID0gYXdhaXQgdGhpcy5nZXRQa2dWZXJzaW9uKGxvYWRlcik7XG4gICAgICAgIGlmIChwa2dWZXIgPT09IDAgfHwgcGtnVmVyID09PSAxKSB7XG4gICAgICAgICAgICBkZXNjID0gXCJFU1AzMi1DMlwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVzYyA9IFwidW5rbm93biBFU1AzMi1DMlwiO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaXBfcmV2ID0gYXdhaXQgdGhpcy5nZXRDaGlwUmV2aXNpb24obG9hZGVyKTtcbiAgICAgICAgZGVzYyArPSBcIiAocmV2aXNpb24gXCIgKyBjaGlwX3JldiArIFwiKVwiO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcEZlYXR1cmVzKGxvYWRlcikge1xuICAgICAgICByZXR1cm4gW1wiV2ktRmlcIiwgXCJCTEVcIl07XG4gICAgfVxuICAgIGFzeW5jIGdldENyeXN0YWxGcmVxKGxvYWRlcikge1xuICAgICAgICBjb25zdCB1YXJ0RGl2ID0gKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuVUFSVF9DTEtESVZfUkVHKSkgJiB0aGlzLlVBUlRfQ0xLRElWX01BU0s7XG4gICAgICAgIGNvbnN0IGV0c1h0YWwgPSAobG9hZGVyLnRyYW5zcG9ydC5iYXVkcmF0ZSAqIHVhcnREaXYpIC8gMTAwMDAwMCAvIHRoaXMuWFRBTF9DTEtfRElWSURFUjtcbiAgICAgICAgbGV0IG5vcm1YdGFsO1xuICAgICAgICBpZiAoZXRzWHRhbCA+IDMzKSB7XG4gICAgICAgICAgICBub3JtWHRhbCA9IDQwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbm9ybVh0YWwgPSAyNjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTWF0aC5hYnMobm9ybVh0YWwgLSBldHNYdGFsKSA+IDEpIHtcbiAgICAgICAgICAgIGxvYWRlci5pbmZvKFwiV0FSTklORzogVW5zdXBwb3J0ZWQgY3J5c3RhbCBpbiB1c2VcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5vcm1YdGFsO1xuICAgIH1cbiAgICBhc3luYyBjaGFuZ2VCYXVkUmF0ZShsb2FkZXIpIHtcbiAgICAgICAgY29uc3Qgcm9tX3dpdGhfMjZNX1hUQUwgPSBhd2FpdCB0aGlzLmdldENyeXN0YWxGcmVxKGxvYWRlcik7XG4gICAgICAgIGlmIChyb21fd2l0aF8yNk1fWFRBTCA9PT0gMjYpIHtcbiAgICAgICAgICAgIGxvYWRlci5jaGFuZ2VCYXVkKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2QyaChkKSB7XG4gICAgICAgIGNvbnN0IGggPSAoK2QpLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgcmV0dXJuIGgubGVuZ3RoID09PSAxID8gXCIwXCIgKyBoIDogaDtcbiAgICB9XG4gICAgYXN5bmMgcmVhZE1hYyhsb2FkZXIpIHtcbiAgICAgICAgbGV0IG1hYzAgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcpO1xuICAgICAgICBtYWMwID0gbWFjMCA+Pj4gMDtcbiAgICAgICAgbGV0IG1hYzEgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcgKyA0KTtcbiAgICAgICAgbWFjMSA9IChtYWMxID4+PiAwKSAmIDB4MDAwMGZmZmY7XG4gICAgICAgIGNvbnN0IG1hYyA9IG5ldyBVaW50OEFycmF5KDYpO1xuICAgICAgICBtYWNbMF0gPSAobWFjMSA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1sxXSA9IG1hYzEgJiAweGZmO1xuICAgICAgICBtYWNbMl0gPSAobWFjMCA+PiAyNCkgJiAweGZmO1xuICAgICAgICBtYWNbM10gPSAobWFjMCA+PiAxNikgJiAweGZmO1xuICAgICAgICBtYWNbNF0gPSAobWFjMCA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1s1XSA9IG1hYzAgJiAweGZmO1xuICAgICAgICByZXR1cm4gKHRoaXMuX2QyaChtYWNbMF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMV0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMl0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbM10pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNV0pKTtcbiAgICB9XG4gICAgZ2V0RXJhc2VTaXplKG9mZnNldCwgc2l6ZSkge1xuICAgICAgICByZXR1cm4gc2l6ZTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBST00gfSBmcm9tIFwiLi9yb20uanNcIjtcbmV4cG9ydCBjbGFzcyBFU1AzMkMzUk9NIGV4dGVuZHMgUk9NIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5DSElQX05BTUUgPSBcIkVTUDMyLUMzXCI7XG4gICAgICAgIHRoaXMuSU1BR0VfQ0hJUF9JRCA9IDU7XG4gICAgICAgIHRoaXMuRUZVU0VfQkFTRSA9IDB4NjAwMDg4MDA7XG4gICAgICAgIHRoaXMuTUFDX0VGVVNFX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICB0aGlzLlVBUlRfQ0xLRElWX1JFRyA9IDB4M2ZmNDAwMTQ7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfTUFTSyA9IDB4ZmZmZmY7XG4gICAgICAgIHRoaXMuVUFSVF9EQVRFX1JFR19BRERSID0gMHg2MDAwMDA3YztcbiAgICAgICAgdGhpcy5GTEFTSF9XUklURV9TSVpFID0gMHg0MDA7XG4gICAgICAgIHRoaXMuQk9PVExPQURFUl9GTEFTSF9PRkZTRVQgPSAwO1xuICAgICAgICB0aGlzLkZMQVNIX1NJWkVTID0ge1xuICAgICAgICAgICAgXCIxTUJcIjogMHgwMCxcbiAgICAgICAgICAgIFwiMk1CXCI6IDB4MTAsXG4gICAgICAgICAgICBcIjRNQlwiOiAweDIwLFxuICAgICAgICAgICAgXCI4TUJcIjogMHgzMCxcbiAgICAgICAgICAgIFwiMTZNQlwiOiAweDQwLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLlNQSV9SRUdfQkFTRSA9IDB4NjAwMDIwMDA7XG4gICAgICAgIHRoaXMuU1BJX1VTUl9PRkZTID0gMHgxODtcbiAgICAgICAgdGhpcy5TUElfVVNSMV9PRkZTID0gMHgxYztcbiAgICAgICAgdGhpcy5TUElfVVNSMl9PRkZTID0gMHgyMDtcbiAgICAgICAgdGhpcy5TUElfTU9TSV9ETEVOX09GRlMgPSAweDI0O1xuICAgICAgICB0aGlzLlNQSV9NSVNPX0RMRU5fT0ZGUyA9IDB4Mjg7XG4gICAgICAgIHRoaXMuU1BJX1cwX09GRlMgPSAweDU4O1xuICAgIH1cbiAgICBhc3luYyBnZXRQa2dWZXJzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMztcbiAgICAgICAgY29uc3QgYmxvY2sxQWRkciA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCB3b3JkMyA9IGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpO1xuICAgICAgICBjb25zdCBwa2dWZXJzaW9uID0gKHdvcmQzID4+IDIxKSAmIDB4MDc7XG4gICAgICAgIHJldHVybiBwa2dWZXJzaW9uO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwUmV2aXNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGJsb2NrMUFkZHIgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDM7XG4gICAgICAgIGNvbnN0IHBvcyA9IDE4O1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCByZXQgPSAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpKSAmICgweDcgPDwgcG9zKSkgPj4gcG9zO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwRGVzY3JpcHRpb24obG9hZGVyKSB7XG4gICAgICAgIGxldCBkZXNjO1xuICAgICAgICBjb25zdCBwa2dWZXIgPSBhd2FpdCB0aGlzLmdldFBrZ1ZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgaWYgKHBrZ1ZlciA9PT0gMCkge1xuICAgICAgICAgICAgZGVzYyA9IFwiRVNQMzItQzNcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlc2MgPSBcInVua25vd24gRVNQMzItQzNcIjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGlwX3JldiA9IGF3YWl0IHRoaXMuZ2V0Q2hpcFJldmlzaW9uKGxvYWRlcik7XG4gICAgICAgIGRlc2MgKz0gXCIgKHJldmlzaW9uIFwiICsgY2hpcF9yZXYgKyBcIilcIjtcbiAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgfVxuICAgIGFzeW5jIGdldEZsYXNoQ2FwKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMztcbiAgICAgICAgY29uc3QgYmxvY2sxQWRkciA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCByZWdpc3RlclZhbHVlID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgICAgIGNvbnN0IGZsYXNoQ2FwID0gKHJlZ2lzdGVyVmFsdWUgPj4gMjcpICYgMHgwNztcbiAgICAgICAgcmV0dXJuIGZsYXNoQ2FwO1xuICAgIH1cbiAgICBhc3luYyBnZXRGbGFzaFZlbmRvcihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDQ7XG4gICAgICAgIGNvbnN0IGJsb2NrMUFkZHIgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgY29uc3QgYWRkciA9IGJsb2NrMUFkZHIgKyA0ICogbnVtV29yZDtcbiAgICAgICAgY29uc3QgcmVnaXN0ZXJWYWx1ZSA9IGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpO1xuICAgICAgICBjb25zdCB2ZW5kb3JJZCA9IChyZWdpc3RlclZhbHVlID4+IDApICYgMHgwNztcbiAgICAgICAgY29uc3QgdmVuZG9yTWFwID0ge1xuICAgICAgICAgICAgMTogXCJYTUNcIixcbiAgICAgICAgICAgIDI6IFwiR0RcIixcbiAgICAgICAgICAgIDM6IFwiRk1cIixcbiAgICAgICAgICAgIDQ6IFwiVFRcIixcbiAgICAgICAgICAgIDU6IFwiWkJJVFwiLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdmVuZG9yTWFwW3ZlbmRvcklkXSB8fCBcIlwiO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwRmVhdHVyZXMobG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGZlYXR1cmVzID0gW1wiV2ktRmlcIiwgXCJCTEVcIl07XG4gICAgICAgIGNvbnN0IGZsYXNoTWFwID0ge1xuICAgICAgICAgICAgMDogbnVsbCxcbiAgICAgICAgICAgIDE6IFwiRW1iZWRkZWQgRmxhc2ggNE1CXCIsXG4gICAgICAgICAgICAyOiBcIkVtYmVkZGVkIEZsYXNoIDJNQlwiLFxuICAgICAgICAgICAgMzogXCJFbWJlZGRlZCBGbGFzaCAxTUJcIixcbiAgICAgICAgICAgIDQ6IFwiRW1iZWRkZWQgRmxhc2ggOE1CXCIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGZsYXNoQ2FwID0gYXdhaXQgdGhpcy5nZXRGbGFzaENhcChsb2FkZXIpO1xuICAgICAgICBjb25zdCBmbGFzaFZlbmRvciA9IGF3YWl0IHRoaXMuZ2V0Rmxhc2hWZW5kb3IobG9hZGVyKTtcbiAgICAgICAgY29uc3QgZmxhc2ggPSBmbGFzaE1hcFtmbGFzaENhcF07XG4gICAgICAgIGNvbnN0IGZsYXNoRGVzY3JpcHRpb24gPSBmbGFzaCAhPT0gdW5kZWZpbmVkID8gZmxhc2ggOiBcIlVua25vd24gRW1iZWRkZWQgRmxhc2hcIjtcbiAgICAgICAgaWYgKGZsYXNoICE9PSBudWxsKSB7XG4gICAgICAgICAgICBmZWF0dXJlcy5wdXNoKGAke2ZsYXNoRGVzY3JpcHRpb259ICgke2ZsYXNoVmVuZG9yfSlgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmVhdHVyZXM7XG4gICAgfVxuICAgIGFzeW5jIGdldENyeXN0YWxGcmVxKGxvYWRlcikge1xuICAgICAgICByZXR1cm4gNDA7XG4gICAgfVxuICAgIF9kMmgoZCkge1xuICAgICAgICBjb25zdCBoID0gKCtkKS50b1N0cmluZygxNik7XG4gICAgICAgIHJldHVybiBoLmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgaCA6IGg7XG4gICAgfVxuICAgIGFzeW5jIHJlYWRNYWMobG9hZGVyKSB7XG4gICAgICAgIGxldCBtYWMwID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHKTtcbiAgICAgICAgbWFjMCA9IG1hYzAgPj4+IDA7XG4gICAgICAgIGxldCBtYWMxID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHICsgNCk7XG4gICAgICAgIG1hYzEgPSAobWFjMSA+Pj4gMCkgJiAweDAwMDBmZmZmO1xuICAgICAgICBjb25zdCBtYWMgPSBuZXcgVWludDhBcnJheSg2KTtcbiAgICAgICAgbWFjWzBdID0gKG1hYzEgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbMV0gPSBtYWMxICYgMHhmZjtcbiAgICAgICAgbWFjWzJdID0gKG1hYzAgPj4gMjQpICYgMHhmZjtcbiAgICAgICAgbWFjWzNdID0gKG1hYzAgPj4gMTYpICYgMHhmZjtcbiAgICAgICAgbWFjWzRdID0gKG1hYzAgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbNV0gPSBtYWMwICYgMHhmZjtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9kMmgobWFjWzBdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzFdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzJdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzNdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzRdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzVdKSk7XG4gICAgfVxuICAgIGdldEVyYXNlU2l6ZShvZmZzZXQsIHNpemUpIHtcbiAgICAgICAgcmV0dXJuIHNpemU7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32c3_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32c3_js.bundle.js deleted file mode 100644 index c5eea1e..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32c3_js.bundle.js +++ /dev/null @@ -1,153 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32c3_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32c3.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32c3.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32C3ROM: () => (/* binding */ ESP32C3ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32C3ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-C3"; - this.IMAGE_CHIP_ID = 5; - this.EFUSE_BASE = 0x60008800; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.UART_CLKDIV_REG = 0x3ff40014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x6000007c; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.SPI_REG_BASE = 0x60002000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - } - async getPkgVersion(loader) { - const numWord = 3; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const word3 = await loader.readReg(addr); - const pkgVersion = (word3 >> 21) & 0x07; - return pkgVersion; - } - async getChipRevision(loader) { - const block1Addr = this.EFUSE_BASE + 0x044; - const numWord = 3; - const pos = 18; - const addr = block1Addr + 4 * numWord; - const ret = ((await loader.readReg(addr)) & (0x7 << pos)) >> pos; - return ret; - } - async getChipDescription(loader) { - let desc; - const pkgVer = await this.getPkgVersion(loader); - if (pkgVer === 0) { - desc = "ESP32-C3"; - } - else { - desc = "unknown ESP32-C3"; - } - const chip_rev = await this.getChipRevision(loader); - desc += " (revision " + chip_rev + ")"; - return desc; - } - async getFlashCap(loader) { - const numWord = 3; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const registerValue = await loader.readReg(addr); - const flashCap = (registerValue >> 27) & 0x07; - return flashCap; - } - async getFlashVendor(loader) { - const numWord = 4; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const registerValue = await loader.readReg(addr); - const vendorId = (registerValue >> 0) & 0x07; - const vendorMap = { - 1: "XMC", - 2: "GD", - 3: "FM", - 4: "TT", - 5: "ZBIT", - }; - return vendorMap[vendorId] || ""; - } - async getChipFeatures(loader) { - const features = ["Wi-Fi", "BLE"]; - const flashMap = { - 0: null, - 1: "Embedded Flash 4MB", - 2: "Embedded Flash 2MB", - 3: "Embedded Flash 1MB", - 4: "Embedded Flash 8MB", - }; - const flashCap = await this.getFlashCap(loader); - const flashVendor = await this.getFlashVendor(loader); - const flash = flashMap[flashCap]; - const flashDescription = flash !== undefined ? flash : "Unknown Embedded Flash"; - if (flash !== null) { - features.push(`${flashDescription} (${flashVendor})`); - } - return features; - } - async getCrystalFreq(loader) { - return 40; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJjM19qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBK0I7QUFDeEIseUJBQXlCLHdDQUFHO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsa0JBQWtCLEdBQUcsWUFBWTtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwdG9vbC1qcy9saWIvdGFyZ2V0cy9lc3AzMmMzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJPTSB9IGZyb20gXCIuL3JvbS5qc1wiO1xuZXhwb3J0IGNsYXNzIEVTUDMyQzNST00gZXh0ZW5kcyBST00ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLkNISVBfTkFNRSA9IFwiRVNQMzItQzNcIjtcbiAgICAgICAgdGhpcy5JTUFHRV9DSElQX0lEID0gNTtcbiAgICAgICAgdGhpcy5FRlVTRV9CQVNFID0gMHg2MDAwODgwMDtcbiAgICAgICAgdGhpcy5NQUNfRUZVU0VfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfUkVHID0gMHgzZmY0MDAxNDtcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9NQVNLID0gMHhmZmZmZjtcbiAgICAgICAgdGhpcy5VQVJUX0RBVEVfUkVHX0FERFIgPSAweDYwMDAwMDdjO1xuICAgICAgICB0aGlzLkZMQVNIX1dSSVRFX1NJWkUgPSAweDQwMDtcbiAgICAgICAgdGhpcy5CT09UTE9BREVSX0ZMQVNIX09GRlNFVCA9IDA7XG4gICAgICAgIHRoaXMuRkxBU0hfU0laRVMgPSB7XG4gICAgICAgICAgICBcIjFNQlwiOiAweDAwLFxuICAgICAgICAgICAgXCIyTUJcIjogMHgxMCxcbiAgICAgICAgICAgIFwiNE1CXCI6IDB4MjAsXG4gICAgICAgICAgICBcIjhNQlwiOiAweDMwLFxuICAgICAgICAgICAgXCIxNk1CXCI6IDB4NDAsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuU1BJX1JFR19CQVNFID0gMHg2MDAwMjAwMDtcbiAgICAgICAgdGhpcy5TUElfVVNSX09GRlMgPSAweDE4O1xuICAgICAgICB0aGlzLlNQSV9VU1IxX09GRlMgPSAweDFjO1xuICAgICAgICB0aGlzLlNQSV9VU1IyX09GRlMgPSAweDIwO1xuICAgICAgICB0aGlzLlNQSV9NT1NJX0RMRU5fT0ZGUyA9IDB4MjQ7XG4gICAgICAgIHRoaXMuU1BJX01JU09fRExFTl9PRkZTID0gMHgyODtcbiAgICAgICAgdGhpcy5TUElfVzBfT0ZGUyA9IDB4NTg7XG4gICAgfVxuICAgIGFzeW5jIGdldFBrZ1ZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSAzO1xuICAgICAgICBjb25zdCBibG9jazFBZGRyID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIGNvbnN0IGFkZHIgPSBibG9jazFBZGRyICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHdvcmQzID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgICAgIGNvbnN0IHBrZ1ZlcnNpb24gPSAod29yZDMgPj4gMjEpICYgMHgwNztcbiAgICAgICAgcmV0dXJuIHBrZ1ZlcnNpb247XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBSZXZpc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgYmxvY2sxQWRkciA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMztcbiAgICAgICAgY29uc3QgcG9zID0gMTg7XG4gICAgICAgIGNvbnN0IGFkZHIgPSBibG9jazFBZGRyICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHJldCA9ICgoYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcikpICYgKDB4NyA8PCBwb3MpKSA+PiBwb3M7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBEZXNjcmlwdGlvbihsb2FkZXIpIHtcbiAgICAgICAgbGV0IGRlc2M7XG4gICAgICAgIGNvbnN0IHBrZ1ZlciA9IGF3YWl0IHRoaXMuZ2V0UGtnVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICBpZiAocGtnVmVyID09PSAwKSB7XG4gICAgICAgICAgICBkZXNjID0gXCJFU1AzMi1DM1wiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVzYyA9IFwidW5rbm93biBFU1AzMi1DM1wiO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaXBfcmV2ID0gYXdhaXQgdGhpcy5nZXRDaGlwUmV2aXNpb24obG9hZGVyKTtcbiAgICAgICAgZGVzYyArPSBcIiAocmV2aXNpb24gXCIgKyBjaGlwX3JldiArIFwiKVwiO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG4gICAgYXN5bmMgZ2V0Rmxhc2hDYXAobG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSAzO1xuICAgICAgICBjb25zdCBibG9jazFBZGRyID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIGNvbnN0IGFkZHIgPSBibG9jazFBZGRyICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHJlZ2lzdGVyVmFsdWUgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKTtcbiAgICAgICAgY29uc3QgZmxhc2hDYXAgPSAocmVnaXN0ZXJWYWx1ZSA+PiAyNykgJiAweDA3O1xuICAgICAgICByZXR1cm4gZmxhc2hDYXA7XG4gICAgfVxuICAgIGFzeW5jIGdldEZsYXNoVmVuZG9yKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gNDtcbiAgICAgICAgY29uc3QgYmxvY2sxQWRkciA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCByZWdpc3RlclZhbHVlID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgICAgIGNvbnN0IHZlbmRvcklkID0gKHJlZ2lzdGVyVmFsdWUgPj4gMCkgJiAweDA3O1xuICAgICAgICBjb25zdCB2ZW5kb3JNYXAgPSB7XG4gICAgICAgICAgICAxOiBcIlhNQ1wiLFxuICAgICAgICAgICAgMjogXCJHRFwiLFxuICAgICAgICAgICAgMzogXCJGTVwiLFxuICAgICAgICAgICAgNDogXCJUVFwiLFxuICAgICAgICAgICAgNTogXCJaQklUXCIsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB2ZW5kb3JNYXBbdmVuZG9ySWRdIHx8IFwiXCI7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBGZWF0dXJlcyhsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgZmVhdHVyZXMgPSBbXCJXaS1GaVwiLCBcIkJMRVwiXTtcbiAgICAgICAgY29uc3QgZmxhc2hNYXAgPSB7XG4gICAgICAgICAgICAwOiBudWxsLFxuICAgICAgICAgICAgMTogXCJFbWJlZGRlZCBGbGFzaCA0TUJcIixcbiAgICAgICAgICAgIDI6IFwiRW1iZWRkZWQgRmxhc2ggMk1CXCIsXG4gICAgICAgICAgICAzOiBcIkVtYmVkZGVkIEZsYXNoIDFNQlwiLFxuICAgICAgICAgICAgNDogXCJFbWJlZGRlZCBGbGFzaCA4TUJcIixcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZmxhc2hDYXAgPSBhd2FpdCB0aGlzLmdldEZsYXNoQ2FwKGxvYWRlcik7XG4gICAgICAgIGNvbnN0IGZsYXNoVmVuZG9yID0gYXdhaXQgdGhpcy5nZXRGbGFzaFZlbmRvcihsb2FkZXIpO1xuICAgICAgICBjb25zdCBmbGFzaCA9IGZsYXNoTWFwW2ZsYXNoQ2FwXTtcbiAgICAgICAgY29uc3QgZmxhc2hEZXNjcmlwdGlvbiA9IGZsYXNoICE9PSB1bmRlZmluZWQgPyBmbGFzaCA6IFwiVW5rbm93biBFbWJlZGRlZCBGbGFzaFwiO1xuICAgICAgICBpZiAoZmxhc2ggIT09IG51bGwpIHtcbiAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goYCR7Zmxhc2hEZXNjcmlwdGlvbn0gKCR7Zmxhc2hWZW5kb3J9KWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmZWF0dXJlcztcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q3J5c3RhbEZyZXEobG9hZGVyKSB7XG4gICAgICAgIHJldHVybiA0MDtcbiAgICB9XG4gICAgX2QyaChkKSB7XG4gICAgICAgIGNvbnN0IGggPSAoK2QpLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgcmV0dXJuIGgubGVuZ3RoID09PSAxID8gXCIwXCIgKyBoIDogaDtcbiAgICB9XG4gICAgYXN5bmMgcmVhZE1hYyhsb2FkZXIpIHtcbiAgICAgICAgbGV0IG1hYzAgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcpO1xuICAgICAgICBtYWMwID0gbWFjMCA+Pj4gMDtcbiAgICAgICAgbGV0IG1hYzEgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcgKyA0KTtcbiAgICAgICAgbWFjMSA9IChtYWMxID4+PiAwKSAmIDB4MDAwMGZmZmY7XG4gICAgICAgIGNvbnN0IG1hYyA9IG5ldyBVaW50OEFycmF5KDYpO1xuICAgICAgICBtYWNbMF0gPSAobWFjMSA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1sxXSA9IG1hYzEgJiAweGZmO1xuICAgICAgICBtYWNbMl0gPSAobWFjMCA+PiAyNCkgJiAweGZmO1xuICAgICAgICBtYWNbM10gPSAobWFjMCA+PiAxNikgJiAweGZmO1xuICAgICAgICBtYWNbNF0gPSAobWFjMCA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1s1XSA9IG1hYzAgJiAweGZmO1xuICAgICAgICByZXR1cm4gKHRoaXMuX2QyaChtYWNbMF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMV0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMl0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbM10pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNV0pKTtcbiAgICB9XG4gICAgZ2V0RXJhc2VTaXplKG9mZnNldCwgc2l6ZSkge1xuICAgICAgICByZXR1cm4gc2l6ZTtcbiAgICB9XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32c5_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32c5_js.bundle.js deleted file mode 100644 index 5227d0b..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32c5_js.bundle.js +++ /dev/null @@ -1,259 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32c5_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32c5.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32c5.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32C5ROM: () => (/* binding */ ESP32C5ROM) -/* harmony export */ }); -/* harmony import */ var _esp32c6__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./esp32c6 */ "./node_modules/esptool-js/lib/targets/esp32c6.js"); - -class ESP32C5ROM extends _esp32c6__WEBPACK_IMPORTED_MODULE_0__.ESP32C6ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-C5"; - this.IMAGE_CHIP_ID = 23; - this.BOOTLOADER_FLASH_OFFSET = 0x2000; - this.EFUSE_BASE = 0x600b4800; - this.EFUSE_BLOCK1_ADDR = this.EFUSE_BASE + 0x044; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.UART_CLKDIV_REG = 0x60000014; - this.EFUSE_RD_REG_BASE = this.EFUSE_BASE + 0x030; // BLOCK0 read base address - this.EFUSE_PURPOSE_KEY0_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY0_SHIFT = 24; - this.EFUSE_PURPOSE_KEY1_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY1_SHIFT = 28; - this.EFUSE_PURPOSE_KEY2_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY2_SHIFT = 0; - this.EFUSE_PURPOSE_KEY3_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY3_SHIFT = 4; - this.EFUSE_PURPOSE_KEY4_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY4_SHIFT = 8; - this.EFUSE_PURPOSE_KEY5_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY5_SHIFT = 12; - this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = this.EFUSE_RD_REG_BASE; - this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = 1 << 20; - this.EFUSE_SPI_BOOT_CRYPT_CNT_REG = this.EFUSE_BASE + 0x034; - this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK = 0x7 << 18; - this.EFUSE_SECURE_BOOT_EN_REG = this.EFUSE_BASE + 0x038; - this.EFUSE_SECURE_BOOT_EN_MASK = 1 << 20; - this.IROM_MAP_START = 0x42000000; - this.IROM_MAP_END = 0x42800000; - this.DROM_MAP_START = 0x42800000; - this.DROM_MAP_END = 0x43000000; - this.PCR_SYSCLK_CONF_REG = 0x60096110; - this.PCR_SYSCLK_XTAL_FREQ_V = 0x7f << 24; - this.PCR_SYSCLK_XTAL_FREQ_S = 24; - this.XTAL_CLK_DIVIDER = 1; - this.UARTDEV_BUF_NO = 0x4085f51c; // Variable in ROM .bss which indicates the port in use - // Magic value for ESP32C5 - this.CHIP_DETECT_MAGIC_VALUE = [0x1101406f, 0x63e1406f, 0x5fd1406f]; - this.FLASH_FREQUENCY = { - "80m": 0xf, - "40m": 0x0, - "20m": 0x2, - }; - this.MEMORY_MAP = [ - [0x00000000, 0x00010000, "PADDING"], - [0x42800000, 0x43000000, "DROM"], - [0x40800000, 0x40860000, "DRAM"], - [0x40800000, 0x40860000, "BYTE_ACCESSIBLE"], - [0x4003a000, 0x40040000, "DROM_MASK"], - [0x40000000, 0x4003a000, "IROM_MASK"], - [0x42000000, 0x42800000, "IROM"], - [0x40800000, 0x40860000, "IRAM"], - [0x50000000, 0x50004000, "RTC_IRAM"], - [0x50000000, 0x50004000, "RTC_DRAM"], - [0x600fe000, 0x60100000, "MEM_INTERNAL2"], - ]; - this.UF2_FAMILY_ID = 0xf71c0343; - this.EFUSE_MAX_KEY = 5; - this.KEY_PURPOSES = { - 0: "USER/EMPTY", - 1: "ECDSA_KEY", - 2: "XTS_AES_256_KEY_1", - 3: "XTS_AES_256_KEY_2", - 4: "XTS_AES_128_KEY", - 5: "HMAC_DOWN_ALL", - 6: "HMAC_DOWN_JTAG", - 7: "HMAC_DOWN_DIGITAL_SIGNATURE", - 8: "HMAC_UP", - 9: "SECURE_BOOT_DIGEST0", - 10: "SECURE_BOOT_DIGEST1", - 11: "SECURE_BOOT_DIGEST2", - 12: "KM_INIT_KEY", - }; - } - async getPkgVersion(loader) { - const numWord = 2; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 26) & 0x07; - } - async getMinorChipVersion(loader) { - const numWord = 2; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 0) & 0x0f; - } - async getMajorChipVersion(loader) { - const numWord = 2; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 4) & 0x03; - } - async getChipDescription(loader) { - const pkgVer = await this.getPkgVersion(loader); - let desc; - if (pkgVer === 0) { - desc = "ESP32-C5"; - } - else { - desc = "unknown ESP32-C5"; - } - const majorRev = await this.getMajorChipVersion(loader); - const minorRev = await this.getMinorChipVersion(loader); - return `${desc} (revision v${majorRev}.${minorRev})`; - } - async getChipFeatures(loader) { - return ["Wi-Fi 6 (dual-band)", "BT 5 (LE)"]; - } - async getCrystalFreq(loader) { - // The crystal detection algorithm of ESP32/ESP8266 - // works for ESP32-C5 as well. - const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK; - const etsXtal = (loader.transport.baudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; - let normXtal; - if (etsXtal > 45) { - normXtal = 48; - } - else if (etsXtal > 33) { - normXtal = 40; - } - else { - normXtal = 26; - } - if (Math.abs(normXtal - etsXtal) > 1) { - loader.info("WARNING: Unsupported crystal in use"); - } - return normXtal; - } - async getCrystalFreqRomExpect(loader) { - return (((await loader.readReg(this.PCR_SYSCLK_CONF_REG)) & this.PCR_SYSCLK_XTAL_FREQ_V) >> this.PCR_SYSCLK_XTAL_FREQ_S); - } -} - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/targets/esp32c6.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32c6.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32C6ROM: () => (/* binding */ ESP32C6ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32C6ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-C6"; - this.IMAGE_CHIP_ID = 13; - this.EFUSE_BASE = 0x600b0800; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.UART_CLKDIV_REG = 0x3ff40014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x6000007c; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.SPI_REG_BASE = 0x60002000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - } - async getPkgVersion(loader) { - const numWord = 3; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const word3 = await loader.readReg(addr); - const pkgVersion = (word3 >> 21) & 0x07; - return pkgVersion; - } - async getChipRevision(loader) { - const block1Addr = this.EFUSE_BASE + 0x044; - const numWord = 3; - const pos = 18; - const addr = block1Addr + 4 * numWord; - const ret = ((await loader.readReg(addr)) & (0x7 << pos)) >> pos; - return ret; - } - async getChipDescription(loader) { - let desc; - const pkgVer = await this.getPkgVersion(loader); - if (pkgVer === 0) { - desc = "ESP32-C6"; - } - else { - desc = "unknown ESP32-C6"; - } - const chipRev = await this.getChipRevision(loader); - desc += " (revision " + chipRev + ")"; - return desc; - } - async getChipFeatures(loader) { - return ["Wi-Fi 6", "BT 5", "IEEE802.15.4"]; - } - async getCrystalFreq(loader) { - return 40; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJjNV9qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBdUM7QUFDaEMseUJBQXlCLGdEQUFVO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRDtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLE1BQU0sYUFBYSxTQUFTLEdBQUcsU0FBUztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ2hJK0I7QUFDeEIseUJBQXlCLHdDQUFHO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3RhcmdldHMvZXNwMzJjNS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3B0b29sLWpzL2xpYi90YXJnZXRzL2VzcDMyYzYuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRVNQMzJDNlJPTSB9IGZyb20gXCIuL2VzcDMyYzZcIjtcbmV4cG9ydCBjbGFzcyBFU1AzMkM1Uk9NIGV4dGVuZHMgRVNQMzJDNlJPTSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuQ0hJUF9OQU1FID0gXCJFU1AzMi1DNVwiO1xuICAgICAgICB0aGlzLklNQUdFX0NISVBfSUQgPSAyMztcbiAgICAgICAgdGhpcy5CT09UTE9BREVSX0ZMQVNIX09GRlNFVCA9IDB4MjAwMDtcbiAgICAgICAgdGhpcy5FRlVTRV9CQVNFID0gMHg2MDBiNDgwMDtcbiAgICAgICAgdGhpcy5FRlVTRV9CTE9DSzFfQUREUiA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICB0aGlzLk1BQ19FRlVTRV9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9SRUcgPSAweDYwMDAwMDE0O1xuICAgICAgICB0aGlzLkVGVVNFX1JEX1JFR19CQVNFID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwMzA7IC8vIEJMT0NLMCByZWFkIGJhc2UgYWRkcmVzc1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMF9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMF9TSElGVCA9IDI0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMV9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMV9TSElGVCA9IDI4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMl9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMl9TSElGVCA9IDA7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkzX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4Mzg7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkzX1NISUZUID0gNDtcbiAgICAgICAgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTRfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgzODtcbiAgICAgICAgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTRfU0hJRlQgPSA4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZNV9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZNV9TSElGVCA9IDEyO1xuICAgICAgICB0aGlzLkVGVVNFX0RJU19ET1dOTE9BRF9NQU5VQUxfRU5DUllQVF9SRUcgPSB0aGlzLkVGVVNFX1JEX1JFR19CQVNFO1xuICAgICAgICB0aGlzLkVGVVNFX0RJU19ET1dOTE9BRF9NQU5VQUxfRU5DUllQVCA9IDEgPDwgMjA7XG4gICAgICAgIHRoaXMuRUZVU0VfU1BJX0JPT1RfQ1JZUFRfQ05UX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDM0O1xuICAgICAgICB0aGlzLkVGVVNFX1NQSV9CT09UX0NSWVBUX0NOVF9NQVNLID0gMHg3IDw8IDE4O1xuICAgICAgICB0aGlzLkVGVVNFX1NFQ1VSRV9CT09UX0VOX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDM4O1xuICAgICAgICB0aGlzLkVGVVNFX1NFQ1VSRV9CT09UX0VOX01BU0sgPSAxIDw8IDIwO1xuICAgICAgICB0aGlzLklST01fTUFQX1NUQVJUID0gMHg0MjAwMDAwMDtcbiAgICAgICAgdGhpcy5JUk9NX01BUF9FTkQgPSAweDQyODAwMDAwO1xuICAgICAgICB0aGlzLkRST01fTUFQX1NUQVJUID0gMHg0MjgwMDAwMDtcbiAgICAgICAgdGhpcy5EUk9NX01BUF9FTkQgPSAweDQzMDAwMDAwO1xuICAgICAgICB0aGlzLlBDUl9TWVNDTEtfQ09ORl9SRUcgPSAweDYwMDk2MTEwO1xuICAgICAgICB0aGlzLlBDUl9TWVNDTEtfWFRBTF9GUkVRX1YgPSAweDdmIDw8IDI0O1xuICAgICAgICB0aGlzLlBDUl9TWVNDTEtfWFRBTF9GUkVRX1MgPSAyNDtcbiAgICAgICAgdGhpcy5YVEFMX0NMS19ESVZJREVSID0gMTtcbiAgICAgICAgdGhpcy5VQVJUREVWX0JVRl9OTyA9IDB4NDA4NWY1MWM7IC8vIFZhcmlhYmxlIGluIFJPTSAuYnNzIHdoaWNoIGluZGljYXRlcyB0aGUgcG9ydCBpbiB1c2VcbiAgICAgICAgLy8gTWFnaWMgdmFsdWUgZm9yIEVTUDMyQzVcbiAgICAgICAgdGhpcy5DSElQX0RFVEVDVF9NQUdJQ19WQUxVRSA9IFsweDExMDE0MDZmLCAweDYzZTE0MDZmLCAweDVmZDE0MDZmXTtcbiAgICAgICAgdGhpcy5GTEFTSF9GUkVRVUVOQ1kgPSB7XG4gICAgICAgICAgICBcIjgwbVwiOiAweGYsXG4gICAgICAgICAgICBcIjQwbVwiOiAweDAsXG4gICAgICAgICAgICBcIjIwbVwiOiAweDIsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuTUVNT1JZX01BUCA9IFtcbiAgICAgICAgICAgIFsweDAwMDAwMDAwLCAweDAwMDEwMDAwLCBcIlBBRERJTkdcIl0sXG4gICAgICAgICAgICBbMHg0MjgwMDAwMCwgMHg0MzAwMDAwMCwgXCJEUk9NXCJdLFxuICAgICAgICAgICAgWzB4NDA4MDAwMDAsIDB4NDA4NjAwMDAsIFwiRFJBTVwiXSxcbiAgICAgICAgICAgIFsweDQwODAwMDAwLCAweDQwODYwMDAwLCBcIkJZVEVfQUNDRVNTSUJMRVwiXSxcbiAgICAgICAgICAgIFsweDQwMDNhMDAwLCAweDQwMDQwMDAwLCBcIkRST01fTUFTS1wiXSxcbiAgICAgICAgICAgIFsweDQwMDAwMDAwLCAweDQwMDNhMDAwLCBcIklST01fTUFTS1wiXSxcbiAgICAgICAgICAgIFsweDQyMDAwMDAwLCAweDQyODAwMDAwLCBcIklST01cIl0sXG4gICAgICAgICAgICBbMHg0MDgwMDAwMCwgMHg0MDg2MDAwMCwgXCJJUkFNXCJdLFxuICAgICAgICAgICAgWzB4NTAwMDAwMDAsIDB4NTAwMDQwMDAsIFwiUlRDX0lSQU1cIl0sXG4gICAgICAgICAgICBbMHg1MDAwMDAwMCwgMHg1MDAwNDAwMCwgXCJSVENfRFJBTVwiXSxcbiAgICAgICAgICAgIFsweDYwMGZlMDAwLCAweDYwMTAwMDAwLCBcIk1FTV9JTlRFUk5BTDJcIl0sXG4gICAgICAgIF07XG4gICAgICAgIHRoaXMuVUYyX0ZBTUlMWV9JRCA9IDB4ZjcxYzAzNDM7XG4gICAgICAgIHRoaXMuRUZVU0VfTUFYX0tFWSA9IDU7XG4gICAgICAgIHRoaXMuS0VZX1BVUlBPU0VTID0ge1xuICAgICAgICAgICAgMDogXCJVU0VSL0VNUFRZXCIsXG4gICAgICAgICAgICAxOiBcIkVDRFNBX0tFWVwiLFxuICAgICAgICAgICAgMjogXCJYVFNfQUVTXzI1Nl9LRVlfMVwiLFxuICAgICAgICAgICAgMzogXCJYVFNfQUVTXzI1Nl9LRVlfMlwiLFxuICAgICAgICAgICAgNDogXCJYVFNfQUVTXzEyOF9LRVlcIixcbiAgICAgICAgICAgIDU6IFwiSE1BQ19ET1dOX0FMTFwiLFxuICAgICAgICAgICAgNjogXCJITUFDX0RPV05fSlRBR1wiLFxuICAgICAgICAgICAgNzogXCJITUFDX0RPV05fRElHSVRBTF9TSUdOQVRVUkVcIixcbiAgICAgICAgICAgIDg6IFwiSE1BQ19VUFwiLFxuICAgICAgICAgICAgOTogXCJTRUNVUkVfQk9PVF9ESUdFU1QwXCIsXG4gICAgICAgICAgICAxMDogXCJTRUNVUkVfQk9PVF9ESUdFU1QxXCIsXG4gICAgICAgICAgICAxMTogXCJTRUNVUkVfQk9PVF9ESUdFU1QyXCIsXG4gICAgICAgICAgICAxMjogXCJLTV9JTklUX0tFWVwiLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBhc3luYyBnZXRQa2dWZXJzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMjtcbiAgICAgICAgcmV0dXJuICgoYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5FRlVTRV9CTE9DSzFfQUREUiArIDQgKiBudW1Xb3JkKSkgPj4gMjYpICYgMHgwNztcbiAgICB9XG4gICAgYXN5bmMgZ2V0TWlub3JDaGlwVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDI7XG4gICAgICAgIHJldHVybiAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRUZVU0VfQkxPQ0sxX0FERFIgKyA0ICogbnVtV29yZCkpID4+IDApICYgMHgwZjtcbiAgICB9XG4gICAgYXN5bmMgZ2V0TWFqb3JDaGlwVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDI7XG4gICAgICAgIHJldHVybiAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRUZVU0VfQkxPQ0sxX0FERFIgKyA0ICogbnVtV29yZCkpID4+IDQpICYgMHgwMztcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcERlc2NyaXB0aW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBwa2dWZXIgPSBhd2FpdCB0aGlzLmdldFBrZ1ZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgbGV0IGRlc2M7XG4gICAgICAgIGlmIChwa2dWZXIgPT09IDApIHtcbiAgICAgICAgICAgIGRlc2MgPSBcIkVTUDMyLUM1XCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZXNjID0gXCJ1bmtub3duIEVTUDMyLUM1XCI7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWFqb3JSZXYgPSBhd2FpdCB0aGlzLmdldE1ham9yQ2hpcFZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgY29uc3QgbWlub3JSZXYgPSBhd2FpdCB0aGlzLmdldE1pbm9yQ2hpcFZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgcmV0dXJuIGAke2Rlc2N9IChyZXZpc2lvbiB2JHttYWpvclJldn0uJHttaW5vclJldn0pYDtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcEZlYXR1cmVzKGxvYWRlcikge1xuICAgICAgICByZXR1cm4gW1wiV2ktRmkgNiAoZHVhbC1iYW5kKVwiLCBcIkJUIDUgKExFKVwiXTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q3J5c3RhbEZyZXEobG9hZGVyKSB7XG4gICAgICAgIC8vIFRoZSBjcnlzdGFsIGRldGVjdGlvbiBhbGdvcml0aG0gb2YgRVNQMzIvRVNQODI2NlxuICAgICAgICAvLyB3b3JrcyBmb3IgRVNQMzItQzUgYXMgd2VsbC5cbiAgICAgICAgY29uc3QgdWFydERpdiA9IChhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLlVBUlRfQ0xLRElWX1JFRykpICYgdGhpcy5VQVJUX0NMS0RJVl9NQVNLO1xuICAgICAgICBjb25zdCBldHNYdGFsID0gKGxvYWRlci50cmFuc3BvcnQuYmF1ZHJhdGUgKiB1YXJ0RGl2KSAvIDEwMDAwMDAgLyB0aGlzLlhUQUxfQ0xLX0RJVklERVI7XG4gICAgICAgIGxldCBub3JtWHRhbDtcbiAgICAgICAgaWYgKGV0c1h0YWwgPiA0NSkge1xuICAgICAgICAgICAgbm9ybVh0YWwgPSA0ODtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldHNYdGFsID4gMzMpIHtcbiAgICAgICAgICAgIG5vcm1YdGFsID0gNDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBub3JtWHRhbCA9IDI2O1xuICAgICAgICB9XG4gICAgICAgIGlmIChNYXRoLmFicyhub3JtWHRhbCAtIGV0c1h0YWwpID4gMSkge1xuICAgICAgICAgICAgbG9hZGVyLmluZm8oXCJXQVJOSU5HOiBVbnN1cHBvcnRlZCBjcnlzdGFsIGluIHVzZVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbm9ybVh0YWw7XG4gICAgfVxuICAgIGFzeW5jIGdldENyeXN0YWxGcmVxUm9tRXhwZWN0KGxvYWRlcikge1xuICAgICAgICByZXR1cm4gKCgoYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5QQ1JfU1lTQ0xLX0NPTkZfUkVHKSkgJiB0aGlzLlBDUl9TWVNDTEtfWFRBTF9GUkVRX1YpID4+IHRoaXMuUENSX1NZU0NMS19YVEFMX0ZSRVFfUyk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgUk9NIH0gZnJvbSBcIi4vcm9tLmpzXCI7XG5leHBvcnQgY2xhc3MgRVNQMzJDNlJPTSBleHRlbmRzIFJPTSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuQ0hJUF9OQU1FID0gXCJFU1AzMi1DNlwiO1xuICAgICAgICB0aGlzLklNQUdFX0NISVBfSUQgPSAxMztcbiAgICAgICAgdGhpcy5FRlVTRV9CQVNFID0gMHg2MDBiMDgwMDtcbiAgICAgICAgdGhpcy5NQUNfRUZVU0VfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfUkVHID0gMHgzZmY0MDAxNDtcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9NQVNLID0gMHhmZmZmZjtcbiAgICAgICAgdGhpcy5VQVJUX0RBVEVfUkVHX0FERFIgPSAweDYwMDAwMDdjO1xuICAgICAgICB0aGlzLkZMQVNIX1dSSVRFX1NJWkUgPSAweDQwMDtcbiAgICAgICAgdGhpcy5CT09UTE9BREVSX0ZMQVNIX09GRlNFVCA9IDA7XG4gICAgICAgIHRoaXMuRkxBU0hfU0laRVMgPSB7XG4gICAgICAgICAgICBcIjFNQlwiOiAweDAwLFxuICAgICAgICAgICAgXCIyTUJcIjogMHgxMCxcbiAgICAgICAgICAgIFwiNE1CXCI6IDB4MjAsXG4gICAgICAgICAgICBcIjhNQlwiOiAweDMwLFxuICAgICAgICAgICAgXCIxNk1CXCI6IDB4NDAsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuU1BJX1JFR19CQVNFID0gMHg2MDAwMjAwMDtcbiAgICAgICAgdGhpcy5TUElfVVNSX09GRlMgPSAweDE4O1xuICAgICAgICB0aGlzLlNQSV9VU1IxX09GRlMgPSAweDFjO1xuICAgICAgICB0aGlzLlNQSV9VU1IyX09GRlMgPSAweDIwO1xuICAgICAgICB0aGlzLlNQSV9NT1NJX0RMRU5fT0ZGUyA9IDB4MjQ7XG4gICAgICAgIHRoaXMuU1BJX01JU09fRExFTl9PRkZTID0gMHgyODtcbiAgICAgICAgdGhpcy5TUElfVzBfT0ZGUyA9IDB4NTg7XG4gICAgfVxuICAgIGFzeW5jIGdldFBrZ1ZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSAzO1xuICAgICAgICBjb25zdCBibG9jazFBZGRyID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIGNvbnN0IGFkZHIgPSBibG9jazFBZGRyICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHdvcmQzID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgICAgIGNvbnN0IHBrZ1ZlcnNpb24gPSAod29yZDMgPj4gMjEpICYgMHgwNztcbiAgICAgICAgcmV0dXJuIHBrZ1ZlcnNpb247XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBSZXZpc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgYmxvY2sxQWRkciA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMztcbiAgICAgICAgY29uc3QgcG9zID0gMTg7XG4gICAgICAgIGNvbnN0IGFkZHIgPSBibG9jazFBZGRyICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHJldCA9ICgoYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcikpICYgKDB4NyA8PCBwb3MpKSA+PiBwb3M7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBEZXNjcmlwdGlvbihsb2FkZXIpIHtcbiAgICAgICAgbGV0IGRlc2M7XG4gICAgICAgIGNvbnN0IHBrZ1ZlciA9IGF3YWl0IHRoaXMuZ2V0UGtnVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICBpZiAocGtnVmVyID09PSAwKSB7XG4gICAgICAgICAgICBkZXNjID0gXCJFU1AzMi1DNlwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVzYyA9IFwidW5rbm93biBFU1AzMi1DNlwiO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaXBSZXYgPSBhd2FpdCB0aGlzLmdldENoaXBSZXZpc2lvbihsb2FkZXIpO1xuICAgICAgICBkZXNjICs9IFwiIChyZXZpc2lvbiBcIiArIGNoaXBSZXYgKyBcIilcIjtcbiAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBGZWF0dXJlcyhsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuIFtcIldpLUZpIDZcIiwgXCJCVCA1XCIsIFwiSUVFRTgwMi4xNS40XCJdO1xuICAgIH1cbiAgICBhc3luYyBnZXRDcnlzdGFsRnJlcShsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuIDQwO1xuICAgIH1cbiAgICBfZDJoKGQpIHtcbiAgICAgICAgY29uc3QgaCA9ICgrZCkudG9TdHJpbmcoMTYpO1xuICAgICAgICByZXR1cm4gaC5sZW5ndGggPT09IDEgPyBcIjBcIiArIGggOiBoO1xuICAgIH1cbiAgICBhc3luYyByZWFkTWFjKGxvYWRlcikge1xuICAgICAgICBsZXQgbWFjMCA9IGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuTUFDX0VGVVNFX1JFRyk7XG4gICAgICAgIG1hYzAgPSBtYWMwID4+PiAwO1xuICAgICAgICBsZXQgbWFjMSA9IGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuTUFDX0VGVVNFX1JFRyArIDQpO1xuICAgICAgICBtYWMxID0gKG1hYzEgPj4+IDApICYgMHgwMDAwZmZmZjtcbiAgICAgICAgY29uc3QgbWFjID0gbmV3IFVpbnQ4QXJyYXkoNik7XG4gICAgICAgIG1hY1swXSA9IChtYWMxID4+IDgpICYgMHhmZjtcbiAgICAgICAgbWFjWzFdID0gbWFjMSAmIDB4ZmY7XG4gICAgICAgIG1hY1syXSA9IChtYWMwID4+IDI0KSAmIDB4ZmY7XG4gICAgICAgIG1hY1szXSA9IChtYWMwID4+IDE2KSAmIDB4ZmY7XG4gICAgICAgIG1hY1s0XSA9IChtYWMwID4+IDgpICYgMHhmZjtcbiAgICAgICAgbWFjWzVdID0gbWFjMCAmIDB4ZmY7XG4gICAgICAgIHJldHVybiAodGhpcy5fZDJoKG1hY1swXSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1sxXSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1syXSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1szXSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1s0XSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1s1XSkpO1xuICAgIH1cbiAgICBnZXRFcmFzZVNpemUob2Zmc2V0LCBzaXplKSB7XG4gICAgICAgIHJldHVybiBzaXplO1xuICAgIH1cbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32c61_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32c61_js.bundle.js deleted file mode 100644 index 9576732..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32c61_js.bundle.js +++ /dev/null @@ -1,252 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32c61_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32c6.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32c6.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32C6ROM: () => (/* binding */ ESP32C6ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32C6ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-C6"; - this.IMAGE_CHIP_ID = 13; - this.EFUSE_BASE = 0x600b0800; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.UART_CLKDIV_REG = 0x3ff40014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x6000007c; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.SPI_REG_BASE = 0x60002000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - } - async getPkgVersion(loader) { - const numWord = 3; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const word3 = await loader.readReg(addr); - const pkgVersion = (word3 >> 21) & 0x07; - return pkgVersion; - } - async getChipRevision(loader) { - const block1Addr = this.EFUSE_BASE + 0x044; - const numWord = 3; - const pos = 18; - const addr = block1Addr + 4 * numWord; - const ret = ((await loader.readReg(addr)) & (0x7 << pos)) >> pos; - return ret; - } - async getChipDescription(loader) { - let desc; - const pkgVer = await this.getPkgVersion(loader); - if (pkgVer === 0) { - desc = "ESP32-C6"; - } - else { - desc = "unknown ESP32-C6"; - } - const chipRev = await this.getChipRevision(loader); - desc += " (revision " + chipRev + ")"; - return desc; - } - async getChipFeatures(loader) { - return ["Wi-Fi 6", "BT 5", "IEEE802.15.4"]; - } - async getCrystalFreq(loader) { - return 40; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/targets/esp32c61.js": -/*!*********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32c61.js ***! - \*********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32C61ROM: () => (/* binding */ ESP32C61ROM) -/* harmony export */ }); -/* harmony import */ var _esp32c6__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./esp32c6 */ "./node_modules/esptool-js/lib/targets/esp32c6.js"); - -class ESP32C61ROM extends _esp32c6__WEBPACK_IMPORTED_MODULE_0__.ESP32C6ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-C61"; - this.IMAGE_CHIP_ID = 20; - this.CHIP_DETECT_MAGIC_VALUE = [0x33f0206f, 0x2421606f]; - this.UART_DATE_REG_ADDR = 0x60000000 + 0x7c; - this.EFUSE_BASE = 0x600b4800; - this.EFUSE_BLOCK1_ADDR = this.EFUSE_BASE + 0x044; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.EFUSE_RD_REG_BASE = this.EFUSE_BASE + 0x030; // BLOCK0 read base address - this.EFUSE_PURPOSE_KEY0_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY0_SHIFT = 0; - this.EFUSE_PURPOSE_KEY1_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY1_SHIFT = 4; - this.EFUSE_PURPOSE_KEY2_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY2_SHIFT = 8; - this.EFUSE_PURPOSE_KEY3_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY3_SHIFT = 12; - this.EFUSE_PURPOSE_KEY4_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY4_SHIFT = 16; - this.EFUSE_PURPOSE_KEY5_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY5_SHIFT = 20; - this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = this.EFUSE_RD_REG_BASE; - this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = 1 << 20; - this.EFUSE_SPI_BOOT_CRYPT_CNT_REG = this.EFUSE_BASE + 0x030; - this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK = 0x7 << 23; - this.EFUSE_SECURE_BOOT_EN_REG = this.EFUSE_BASE + 0x034; - this.EFUSE_SECURE_BOOT_EN_MASK = 1 << 26; - this.FLASH_FREQUENCY = { - "80m": 0xf, - "40m": 0x0, - "20m": 0x2, - }; - this.MEMORY_MAP = [ - [0x00000000, 0x00010000, "PADDING"], - [0x41800000, 0x42000000, "DROM"], - [0x40800000, 0x40860000, "DRAM"], - [0x40800000, 0x40860000, "BYTE_ACCESSIBLE"], - [0x4004ac00, 0x40050000, "DROM_MASK"], - [0x40000000, 0x4004ac00, "IROM_MASK"], - [0x41000000, 0x41800000, "IROM"], - [0x40800000, 0x40860000, "IRAM"], - [0x50000000, 0x50004000, "RTC_IRAM"], - [0x50000000, 0x50004000, "RTC_DRAM"], - [0x600fe000, 0x60100000, "MEM_INTERNAL2"], - ]; - this.UF2_FAMILY_ID = 0x77d850c4; - this.EFUSE_MAX_KEY = 5; - this.KEY_PURPOSES = { - 0: "USER/EMPTY", - 1: "ECDSA_KEY", - 2: "XTS_AES_256_KEY_1", - 3: "XTS_AES_256_KEY_2", - 4: "XTS_AES_128_KEY", - 5: "HMAC_DOWN_ALL", - 6: "HMAC_DOWN_JTAG", - 7: "HMAC_DOWN_DIGITAL_SIGNATURE", - 8: "HMAC_UP", - 9: "SECURE_BOOT_DIGEST0", - 10: "SECURE_BOOT_DIGEST1", - 11: "SECURE_BOOT_DIGEST2", - 12: "KM_INIT_KEY", - 13: "XTS_AES_256_KEY_1_PSRAM", - 14: "XTS_AES_256_KEY_2_PSRAM", - 15: "XTS_AES_128_KEY_PSRAM", - }; - } - async getPkgVersion(loader) { - const numWord = 2; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 26) & 0x07; - } - async getMinorChipVersion(loader) { - const numWord = 2; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 0) & 0x0f; - } - async getMajorChipVersion(loader) { - const numWord = 2; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 4) & 0x03; - } - async getChipDescription(loader) { - const pkgVer = await this.getPkgVersion(loader); - let desc; - if (pkgVer === 0) { - desc = "ESP32-C61"; - } - else { - desc = "unknown ESP32-C61"; - } - const majorRev = await this.getMajorChipVersion(loader); - const minorRev = await this.getMinorChipVersion(loader); - return `${desc} (revision v${majorRev}.${minorRev})`; - } - async getChipFeatures(loader) { - return ["WiFi 6", "BT 5"]; - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJjNjFfanMuYnVuZGxlLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBQStCO0FBQ3hCLHlCQUF5Qix3Q0FBRztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7QUM5RnVDO0FBQ2hDLDBCQUEwQixnREFBVTtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwREFBMEQ7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixNQUFNLGFBQWEsU0FBUyxHQUFHLFNBQVM7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3RhcmdldHMvZXNwMzJjNi5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3B0b29sLWpzL2xpYi90YXJnZXRzL2VzcDMyYzYxLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJPTSB9IGZyb20gXCIuL3JvbS5qc1wiO1xuZXhwb3J0IGNsYXNzIEVTUDMyQzZST00gZXh0ZW5kcyBST00ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLkNISVBfTkFNRSA9IFwiRVNQMzItQzZcIjtcbiAgICAgICAgdGhpcy5JTUFHRV9DSElQX0lEID0gMTM7XG4gICAgICAgIHRoaXMuRUZVU0VfQkFTRSA9IDB4NjAwYjA4MDA7XG4gICAgICAgIHRoaXMuTUFDX0VGVVNFX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICB0aGlzLlVBUlRfQ0xLRElWX1JFRyA9IDB4M2ZmNDAwMTQ7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfTUFTSyA9IDB4ZmZmZmY7XG4gICAgICAgIHRoaXMuVUFSVF9EQVRFX1JFR19BRERSID0gMHg2MDAwMDA3YztcbiAgICAgICAgdGhpcy5GTEFTSF9XUklURV9TSVpFID0gMHg0MDA7XG4gICAgICAgIHRoaXMuQk9PVExPQURFUl9GTEFTSF9PRkZTRVQgPSAwO1xuICAgICAgICB0aGlzLkZMQVNIX1NJWkVTID0ge1xuICAgICAgICAgICAgXCIxTUJcIjogMHgwMCxcbiAgICAgICAgICAgIFwiMk1CXCI6IDB4MTAsXG4gICAgICAgICAgICBcIjRNQlwiOiAweDIwLFxuICAgICAgICAgICAgXCI4TUJcIjogMHgzMCxcbiAgICAgICAgICAgIFwiMTZNQlwiOiAweDQwLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLlNQSV9SRUdfQkFTRSA9IDB4NjAwMDIwMDA7XG4gICAgICAgIHRoaXMuU1BJX1VTUl9PRkZTID0gMHgxODtcbiAgICAgICAgdGhpcy5TUElfVVNSMV9PRkZTID0gMHgxYztcbiAgICAgICAgdGhpcy5TUElfVVNSMl9PRkZTID0gMHgyMDtcbiAgICAgICAgdGhpcy5TUElfTU9TSV9ETEVOX09GRlMgPSAweDI0O1xuICAgICAgICB0aGlzLlNQSV9NSVNPX0RMRU5fT0ZGUyA9IDB4Mjg7XG4gICAgICAgIHRoaXMuU1BJX1cwX09GRlMgPSAweDU4O1xuICAgIH1cbiAgICBhc3luYyBnZXRQa2dWZXJzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMztcbiAgICAgICAgY29uc3QgYmxvY2sxQWRkciA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCB3b3JkMyA9IGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpO1xuICAgICAgICBjb25zdCBwa2dWZXJzaW9uID0gKHdvcmQzID4+IDIxKSAmIDB4MDc7XG4gICAgICAgIHJldHVybiBwa2dWZXJzaW9uO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwUmV2aXNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGJsb2NrMUFkZHIgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDM7XG4gICAgICAgIGNvbnN0IHBvcyA9IDE4O1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCByZXQgPSAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpKSAmICgweDcgPDwgcG9zKSkgPj4gcG9zO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwRGVzY3JpcHRpb24obG9hZGVyKSB7XG4gICAgICAgIGxldCBkZXNjO1xuICAgICAgICBjb25zdCBwa2dWZXIgPSBhd2FpdCB0aGlzLmdldFBrZ1ZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgaWYgKHBrZ1ZlciA9PT0gMCkge1xuICAgICAgICAgICAgZGVzYyA9IFwiRVNQMzItQzZcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlc2MgPSBcInVua25vd24gRVNQMzItQzZcIjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGlwUmV2ID0gYXdhaXQgdGhpcy5nZXRDaGlwUmV2aXNpb24obG9hZGVyKTtcbiAgICAgICAgZGVzYyArPSBcIiAocmV2aXNpb24gXCIgKyBjaGlwUmV2ICsgXCIpXCI7XG4gICAgICAgIHJldHVybiBkZXNjO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwRmVhdHVyZXMobG9hZGVyKSB7XG4gICAgICAgIHJldHVybiBbXCJXaS1GaSA2XCIsIFwiQlQgNVwiLCBcIklFRUU4MDIuMTUuNFwiXTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q3J5c3RhbEZyZXEobG9hZGVyKSB7XG4gICAgICAgIHJldHVybiA0MDtcbiAgICB9XG4gICAgX2QyaChkKSB7XG4gICAgICAgIGNvbnN0IGggPSAoK2QpLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgcmV0dXJuIGgubGVuZ3RoID09PSAxID8gXCIwXCIgKyBoIDogaDtcbiAgICB9XG4gICAgYXN5bmMgcmVhZE1hYyhsb2FkZXIpIHtcbiAgICAgICAgbGV0IG1hYzAgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcpO1xuICAgICAgICBtYWMwID0gbWFjMCA+Pj4gMDtcbiAgICAgICAgbGV0IG1hYzEgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcgKyA0KTtcbiAgICAgICAgbWFjMSA9IChtYWMxID4+PiAwKSAmIDB4MDAwMGZmZmY7XG4gICAgICAgIGNvbnN0IG1hYyA9IG5ldyBVaW50OEFycmF5KDYpO1xuICAgICAgICBtYWNbMF0gPSAobWFjMSA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1sxXSA9IG1hYzEgJiAweGZmO1xuICAgICAgICBtYWNbMl0gPSAobWFjMCA+PiAyNCkgJiAweGZmO1xuICAgICAgICBtYWNbM10gPSAobWFjMCA+PiAxNikgJiAweGZmO1xuICAgICAgICBtYWNbNF0gPSAobWFjMCA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1s1XSA9IG1hYzAgJiAweGZmO1xuICAgICAgICByZXR1cm4gKHRoaXMuX2QyaChtYWNbMF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMV0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMl0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbM10pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNV0pKTtcbiAgICB9XG4gICAgZ2V0RXJhc2VTaXplKG9mZnNldCwgc2l6ZSkge1xuICAgICAgICByZXR1cm4gc2l6ZTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBFU1AzMkM2Uk9NIH0gZnJvbSBcIi4vZXNwMzJjNlwiO1xuZXhwb3J0IGNsYXNzIEVTUDMyQzYxUk9NIGV4dGVuZHMgRVNQMzJDNlJPTSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuQ0hJUF9OQU1FID0gXCJFU1AzMi1DNjFcIjtcbiAgICAgICAgdGhpcy5JTUFHRV9DSElQX0lEID0gMjA7XG4gICAgICAgIHRoaXMuQ0hJUF9ERVRFQ1RfTUFHSUNfVkFMVUUgPSBbMHgzM2YwMjA2ZiwgMHgyNDIxNjA2Zl07XG4gICAgICAgIHRoaXMuVUFSVF9EQVRFX1JFR19BRERSID0gMHg2MDAwMDAwMCArIDB4N2M7XG4gICAgICAgIHRoaXMuRUZVU0VfQkFTRSA9IDB4NjAwYjQ4MDA7XG4gICAgICAgIHRoaXMuRUZVU0VfQkxPQ0sxX0FERFIgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgdGhpcy5NQUNfRUZVU0VfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIHRoaXMuRUZVU0VfUkRfUkVHX0JBU0UgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDAzMDsgLy8gQkxPQ0swIHJlYWQgYmFzZSBhZGRyZXNzXG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkwX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MzQ7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkwX1NISUZUID0gMDtcbiAgICAgICAgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTFfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgzNDtcbiAgICAgICAgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTFfU0hJRlQgPSA0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMl9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMl9TSElGVCA9IDg7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkzX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MzQ7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkzX1NISUZUID0gMTI7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVk0X1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MzQ7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVk0X1NISUZUID0gMTY7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVk1X1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MzQ7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVk1X1NISUZUID0gMjA7XG4gICAgICAgIHRoaXMuRUZVU0VfRElTX0RPV05MT0FEX01BTlVBTF9FTkNSWVBUX1JFRyA9IHRoaXMuRUZVU0VfUkRfUkVHX0JBU0U7XG4gICAgICAgIHRoaXMuRUZVU0VfRElTX0RPV05MT0FEX01BTlVBTF9FTkNSWVBUID0gMSA8PCAyMDtcbiAgICAgICAgdGhpcy5FRlVTRV9TUElfQk9PVF9DUllQVF9DTlRfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwMzA7XG4gICAgICAgIHRoaXMuRUZVU0VfU1BJX0JPT1RfQ1JZUFRfQ05UX01BU0sgPSAweDcgPDwgMjM7XG4gICAgICAgIHRoaXMuRUZVU0VfU0VDVVJFX0JPT1RfRU5fUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwMzQ7XG4gICAgICAgIHRoaXMuRUZVU0VfU0VDVVJFX0JPT1RfRU5fTUFTSyA9IDEgPDwgMjY7XG4gICAgICAgIHRoaXMuRkxBU0hfRlJFUVVFTkNZID0ge1xuICAgICAgICAgICAgXCI4MG1cIjogMHhmLFxuICAgICAgICAgICAgXCI0MG1cIjogMHgwLFxuICAgICAgICAgICAgXCIyMG1cIjogMHgyLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLk1FTU9SWV9NQVAgPSBbXG4gICAgICAgICAgICBbMHgwMDAwMDAwMCwgMHgwMDAxMDAwMCwgXCJQQURESU5HXCJdLFxuICAgICAgICAgICAgWzB4NDE4MDAwMDAsIDB4NDIwMDAwMDAsIFwiRFJPTVwiXSxcbiAgICAgICAgICAgIFsweDQwODAwMDAwLCAweDQwODYwMDAwLCBcIkRSQU1cIl0sXG4gICAgICAgICAgICBbMHg0MDgwMDAwMCwgMHg0MDg2MDAwMCwgXCJCWVRFX0FDQ0VTU0lCTEVcIl0sXG4gICAgICAgICAgICBbMHg0MDA0YWMwMCwgMHg0MDA1MDAwMCwgXCJEUk9NX01BU0tcIl0sXG4gICAgICAgICAgICBbMHg0MDAwMDAwMCwgMHg0MDA0YWMwMCwgXCJJUk9NX01BU0tcIl0sXG4gICAgICAgICAgICBbMHg0MTAwMDAwMCwgMHg0MTgwMDAwMCwgXCJJUk9NXCJdLFxuICAgICAgICAgICAgWzB4NDA4MDAwMDAsIDB4NDA4NjAwMDAsIFwiSVJBTVwiXSxcbiAgICAgICAgICAgIFsweDUwMDAwMDAwLCAweDUwMDA0MDAwLCBcIlJUQ19JUkFNXCJdLFxuICAgICAgICAgICAgWzB4NTAwMDAwMDAsIDB4NTAwMDQwMDAsIFwiUlRDX0RSQU1cIl0sXG4gICAgICAgICAgICBbMHg2MDBmZTAwMCwgMHg2MDEwMDAwMCwgXCJNRU1fSU5URVJOQUwyXCJdLFxuICAgICAgICBdO1xuICAgICAgICB0aGlzLlVGMl9GQU1JTFlfSUQgPSAweDc3ZDg1MGM0O1xuICAgICAgICB0aGlzLkVGVVNFX01BWF9LRVkgPSA1O1xuICAgICAgICB0aGlzLktFWV9QVVJQT1NFUyA9IHtcbiAgICAgICAgICAgIDA6IFwiVVNFUi9FTVBUWVwiLFxuICAgICAgICAgICAgMTogXCJFQ0RTQV9LRVlcIixcbiAgICAgICAgICAgIDI6IFwiWFRTX0FFU18yNTZfS0VZXzFcIixcbiAgICAgICAgICAgIDM6IFwiWFRTX0FFU18yNTZfS0VZXzJcIixcbiAgICAgICAgICAgIDQ6IFwiWFRTX0FFU18xMjhfS0VZXCIsXG4gICAgICAgICAgICA1OiBcIkhNQUNfRE9XTl9BTExcIixcbiAgICAgICAgICAgIDY6IFwiSE1BQ19ET1dOX0pUQUdcIixcbiAgICAgICAgICAgIDc6IFwiSE1BQ19ET1dOX0RJR0lUQUxfU0lHTkFUVVJFXCIsXG4gICAgICAgICAgICA4OiBcIkhNQUNfVVBcIixcbiAgICAgICAgICAgIDk6IFwiU0VDVVJFX0JPT1RfRElHRVNUMFwiLFxuICAgICAgICAgICAgMTA6IFwiU0VDVVJFX0JPT1RfRElHRVNUMVwiLFxuICAgICAgICAgICAgMTE6IFwiU0VDVVJFX0JPT1RfRElHRVNUMlwiLFxuICAgICAgICAgICAgMTI6IFwiS01fSU5JVF9LRVlcIixcbiAgICAgICAgICAgIDEzOiBcIlhUU19BRVNfMjU2X0tFWV8xX1BTUkFNXCIsXG4gICAgICAgICAgICAxNDogXCJYVFNfQUVTXzI1Nl9LRVlfMl9QU1JBTVwiLFxuICAgICAgICAgICAgMTU6IFwiWFRTX0FFU18xMjhfS0VZX1BTUkFNXCIsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGFzeW5jIGdldFBrZ1ZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSAyO1xuICAgICAgICByZXR1cm4gKChhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLkVGVVNFX0JMT0NLMV9BRERSICsgNCAqIG51bVdvcmQpKSA+PiAyNikgJiAweDA3O1xuICAgIH1cbiAgICBhc3luYyBnZXRNaW5vckNoaXBWZXJzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMjtcbiAgICAgICAgcmV0dXJuICgoYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5FRlVTRV9CTE9DSzFfQUREUiArIDQgKiBudW1Xb3JkKSkgPj4gMCkgJiAweDBmO1xuICAgIH1cbiAgICBhc3luYyBnZXRNYWpvckNoaXBWZXJzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMjtcbiAgICAgICAgcmV0dXJuICgoYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5FRlVTRV9CTE9DSzFfQUREUiArIDQgKiBudW1Xb3JkKSkgPj4gNCkgJiAweDAzO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwRGVzY3JpcHRpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IHBrZ1ZlciA9IGF3YWl0IHRoaXMuZ2V0UGtnVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICBsZXQgZGVzYztcbiAgICAgICAgaWYgKHBrZ1ZlciA9PT0gMCkge1xuICAgICAgICAgICAgZGVzYyA9IFwiRVNQMzItQzYxXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZXNjID0gXCJ1bmtub3duIEVTUDMyLUM2MVwiO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1ham9yUmV2ID0gYXdhaXQgdGhpcy5nZXRNYWpvckNoaXBWZXJzaW9uKGxvYWRlcik7XG4gICAgICAgIGNvbnN0IG1pbm9yUmV2ID0gYXdhaXQgdGhpcy5nZXRNaW5vckNoaXBWZXJzaW9uKGxvYWRlcik7XG4gICAgICAgIHJldHVybiBgJHtkZXNjfSAocmV2aXNpb24gdiR7bWFqb3JSZXZ9LiR7bWlub3JSZXZ9KWA7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBGZWF0dXJlcyhsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuIFtcIldpRmkgNlwiLCBcIkJUIDVcIl07XG4gICAgfVxuICAgIGFzeW5jIHJlYWRNYWMobG9hZGVyKSB7XG4gICAgICAgIGxldCBtYWMwID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHKTtcbiAgICAgICAgbWFjMCA9IG1hYzAgPj4+IDA7XG4gICAgICAgIGxldCBtYWMxID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHICsgNCk7XG4gICAgICAgIG1hYzEgPSAobWFjMSA+Pj4gMCkgJiAweDAwMDBmZmZmO1xuICAgICAgICBjb25zdCBtYWMgPSBuZXcgVWludDhBcnJheSg2KTtcbiAgICAgICAgbWFjWzBdID0gKG1hYzEgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbMV0gPSBtYWMxICYgMHhmZjtcbiAgICAgICAgbWFjWzJdID0gKG1hYzAgPj4gMjQpICYgMHhmZjtcbiAgICAgICAgbWFjWzNdID0gKG1hYzAgPj4gMTYpICYgMHhmZjtcbiAgICAgICAgbWFjWzRdID0gKG1hYzAgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbNV0gPSBtYWMwICYgMHhmZjtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9kMmgobWFjWzBdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzFdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzJdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzNdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzRdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzVdKSk7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32c6_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32c6_js.bundle.js deleted file mode 100644 index 803f1f4..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32c6_js.bundle.js +++ /dev/null @@ -1,115 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32c6_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32c6.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32c6.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32C6ROM: () => (/* binding */ ESP32C6ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32C6ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-C6"; - this.IMAGE_CHIP_ID = 13; - this.EFUSE_BASE = 0x600b0800; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.UART_CLKDIV_REG = 0x3ff40014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x6000007c; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.SPI_REG_BASE = 0x60002000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - } - async getPkgVersion(loader) { - const numWord = 3; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const word3 = await loader.readReg(addr); - const pkgVersion = (word3 >> 21) & 0x07; - return pkgVersion; - } - async getChipRevision(loader) { - const block1Addr = this.EFUSE_BASE + 0x044; - const numWord = 3; - const pos = 18; - const addr = block1Addr + 4 * numWord; - const ret = ((await loader.readReg(addr)) & (0x7 << pos)) >> pos; - return ret; - } - async getChipDescription(loader) { - let desc; - const pkgVer = await this.getPkgVersion(loader); - if (pkgVer === 0) { - desc = "ESP32-C6"; - } - else { - desc = "unknown ESP32-C6"; - } - const chipRev = await this.getChipRevision(loader); - desc += " (revision " + chipRev + ")"; - return desc; - } - async getChipFeatures(loader) { - return ["Wi-Fi 6", "BT 5", "IEEE802.15.4"]; - } - async getCrystalFreq(loader) { - return 40; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJjNl9qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBK0I7QUFDeEIseUJBQXlCLHdDQUFHO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3RhcmdldHMvZXNwMzJjNi5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBST00gfSBmcm9tIFwiLi9yb20uanNcIjtcbmV4cG9ydCBjbGFzcyBFU1AzMkM2Uk9NIGV4dGVuZHMgUk9NIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5DSElQX05BTUUgPSBcIkVTUDMyLUM2XCI7XG4gICAgICAgIHRoaXMuSU1BR0VfQ0hJUF9JRCA9IDEzO1xuICAgICAgICB0aGlzLkVGVVNFX0JBU0UgPSAweDYwMGIwODAwO1xuICAgICAgICB0aGlzLk1BQ19FRlVTRV9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9SRUcgPSAweDNmZjQwMDE0O1xuICAgICAgICB0aGlzLlVBUlRfQ0xLRElWX01BU0sgPSAweGZmZmZmO1xuICAgICAgICB0aGlzLlVBUlRfREFURV9SRUdfQUREUiA9IDB4NjAwMDAwN2M7XG4gICAgICAgIHRoaXMuRkxBU0hfV1JJVEVfU0laRSA9IDB4NDAwO1xuICAgICAgICB0aGlzLkJPT1RMT0FERVJfRkxBU0hfT0ZGU0VUID0gMDtcbiAgICAgICAgdGhpcy5GTEFTSF9TSVpFUyA9IHtcbiAgICAgICAgICAgIFwiMU1CXCI6IDB4MDAsXG4gICAgICAgICAgICBcIjJNQlwiOiAweDEwLFxuICAgICAgICAgICAgXCI0TUJcIjogMHgyMCxcbiAgICAgICAgICAgIFwiOE1CXCI6IDB4MzAsXG4gICAgICAgICAgICBcIjE2TUJcIjogMHg0MCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5TUElfUkVHX0JBU0UgPSAweDYwMDAyMDAwO1xuICAgICAgICB0aGlzLlNQSV9VU1JfT0ZGUyA9IDB4MTg7XG4gICAgICAgIHRoaXMuU1BJX1VTUjFfT0ZGUyA9IDB4MWM7XG4gICAgICAgIHRoaXMuU1BJX1VTUjJfT0ZGUyA9IDB4MjA7XG4gICAgICAgIHRoaXMuU1BJX01PU0lfRExFTl9PRkZTID0gMHgyNDtcbiAgICAgICAgdGhpcy5TUElfTUlTT19ETEVOX09GRlMgPSAweDI4O1xuICAgICAgICB0aGlzLlNQSV9XMF9PRkZTID0gMHg1ODtcbiAgICB9XG4gICAgYXN5bmMgZ2V0UGtnVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDM7XG4gICAgICAgIGNvbnN0IGJsb2NrMUFkZHIgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgY29uc3QgYWRkciA9IGJsb2NrMUFkZHIgKyA0ICogbnVtV29yZDtcbiAgICAgICAgY29uc3Qgd29yZDMgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKTtcbiAgICAgICAgY29uc3QgcGtnVmVyc2lvbiA9ICh3b3JkMyA+PiAyMSkgJiAweDA3O1xuICAgICAgICByZXR1cm4gcGtnVmVyc2lvbjtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcFJldmlzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBibG9jazFBZGRyID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSAzO1xuICAgICAgICBjb25zdCBwb3MgPSAxODtcbiAgICAgICAgY29uc3QgYWRkciA9IGJsb2NrMUFkZHIgKyA0ICogbnVtV29yZDtcbiAgICAgICAgY29uc3QgcmV0ID0gKChhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKSkgJiAoMHg3IDw8IHBvcykpID4+IHBvcztcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcERlc2NyaXB0aW9uKGxvYWRlcikge1xuICAgICAgICBsZXQgZGVzYztcbiAgICAgICAgY29uc3QgcGtnVmVyID0gYXdhaXQgdGhpcy5nZXRQa2dWZXJzaW9uKGxvYWRlcik7XG4gICAgICAgIGlmIChwa2dWZXIgPT09IDApIHtcbiAgICAgICAgICAgIGRlc2MgPSBcIkVTUDMyLUM2XCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZXNjID0gXCJ1bmtub3duIEVTUDMyLUM2XCI7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hpcFJldiA9IGF3YWl0IHRoaXMuZ2V0Q2hpcFJldmlzaW9uKGxvYWRlcik7XG4gICAgICAgIGRlc2MgKz0gXCIgKHJldmlzaW9uIFwiICsgY2hpcFJldiArIFwiKVwiO1xuICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcEZlYXR1cmVzKGxvYWRlcikge1xuICAgICAgICByZXR1cm4gW1wiV2ktRmkgNlwiLCBcIkJUIDVcIiwgXCJJRUVFODAyLjE1LjRcIl07XG4gICAgfVxuICAgIGFzeW5jIGdldENyeXN0YWxGcmVxKGxvYWRlcikge1xuICAgICAgICByZXR1cm4gNDA7XG4gICAgfVxuICAgIF9kMmgoZCkge1xuICAgICAgICBjb25zdCBoID0gKCtkKS50b1N0cmluZygxNik7XG4gICAgICAgIHJldHVybiBoLmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgaCA6IGg7XG4gICAgfVxuICAgIGFzeW5jIHJlYWRNYWMobG9hZGVyKSB7XG4gICAgICAgIGxldCBtYWMwID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHKTtcbiAgICAgICAgbWFjMCA9IG1hYzAgPj4+IDA7XG4gICAgICAgIGxldCBtYWMxID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHICsgNCk7XG4gICAgICAgIG1hYzEgPSAobWFjMSA+Pj4gMCkgJiAweDAwMDBmZmZmO1xuICAgICAgICBjb25zdCBtYWMgPSBuZXcgVWludDhBcnJheSg2KTtcbiAgICAgICAgbWFjWzBdID0gKG1hYzEgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbMV0gPSBtYWMxICYgMHhmZjtcbiAgICAgICAgbWFjWzJdID0gKG1hYzAgPj4gMjQpICYgMHhmZjtcbiAgICAgICAgbWFjWzNdID0gKG1hYzAgPj4gMTYpICYgMHhmZjtcbiAgICAgICAgbWFjWzRdID0gKG1hYzAgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbNV0gPSBtYWMwICYgMHhmZjtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9kMmgobWFjWzBdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzFdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzJdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzNdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzRdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzVdKSk7XG4gICAgfVxuICAgIGdldEVyYXNlU2l6ZShvZmZzZXQsIHNpemUpIHtcbiAgICAgICAgcmV0dXJuIHNpemU7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32h2_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32h2_js.bundle.js deleted file mode 100644 index 187444b..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32h2_js.bundle.js +++ /dev/null @@ -1,100 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32h2_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32h2.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32h2.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32H2ROM: () => (/* binding */ ESP32H2ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32H2ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-H2"; - this.IMAGE_CHIP_ID = 16; - this.EFUSE_BASE = 0x60008800; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.UART_CLKDIV_REG = 0x3ff40014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x6000007c; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0x0; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.SPI_REG_BASE = 0x60002000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - this.USB_RAM_BLOCK = 0x800; - this.UARTDEV_BUF_NO_USB = 3; - this.UARTDEV_BUF_NO = 0x3fcef14c; - } - async getChipDescription(loader) { - return this.CHIP_NAME; - } - async getChipFeatures(loader) { - return ["BLE", "IEEE802.15.4"]; - } - async getCrystalFreq(loader) { - // ESP32H2 XTAL is fixed to 32MHz - return 32; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async postConnect(loader) { - const bufNo = (await loader.readReg(this.UARTDEV_BUF_NO)) & 0xff; - loader.debug("In _post_connect " + bufNo); - if (bufNo == this.UARTDEV_BUF_NO_USB) { - loader.ESP_RAM_BLOCK = this.USB_RAM_BLOCK; - } - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJoMl9qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBK0I7QUFDeEIseUJBQXlCLHdDQUFHO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3RhcmdldHMvZXNwMzJoMi5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBST00gfSBmcm9tIFwiLi9yb20uanNcIjtcbmV4cG9ydCBjbGFzcyBFU1AzMkgyUk9NIGV4dGVuZHMgUk9NIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5DSElQX05BTUUgPSBcIkVTUDMyLUgyXCI7XG4gICAgICAgIHRoaXMuSU1BR0VfQ0hJUF9JRCA9IDE2O1xuICAgICAgICB0aGlzLkVGVVNFX0JBU0UgPSAweDYwMDA4ODAwO1xuICAgICAgICB0aGlzLk1BQ19FRlVTRV9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9SRUcgPSAweDNmZjQwMDE0O1xuICAgICAgICB0aGlzLlVBUlRfQ0xLRElWX01BU0sgPSAweGZmZmZmO1xuICAgICAgICB0aGlzLlVBUlRfREFURV9SRUdfQUREUiA9IDB4NjAwMDAwN2M7XG4gICAgICAgIHRoaXMuRkxBU0hfV1JJVEVfU0laRSA9IDB4NDAwO1xuICAgICAgICB0aGlzLkJPT1RMT0FERVJfRkxBU0hfT0ZGU0VUID0gMHgwO1xuICAgICAgICB0aGlzLkZMQVNIX1NJWkVTID0ge1xuICAgICAgICAgICAgXCIxTUJcIjogMHgwMCxcbiAgICAgICAgICAgIFwiMk1CXCI6IDB4MTAsXG4gICAgICAgICAgICBcIjRNQlwiOiAweDIwLFxuICAgICAgICAgICAgXCI4TUJcIjogMHgzMCxcbiAgICAgICAgICAgIFwiMTZNQlwiOiAweDQwLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLlNQSV9SRUdfQkFTRSA9IDB4NjAwMDIwMDA7XG4gICAgICAgIHRoaXMuU1BJX1VTUl9PRkZTID0gMHgxODtcbiAgICAgICAgdGhpcy5TUElfVVNSMV9PRkZTID0gMHgxYztcbiAgICAgICAgdGhpcy5TUElfVVNSMl9PRkZTID0gMHgyMDtcbiAgICAgICAgdGhpcy5TUElfTU9TSV9ETEVOX09GRlMgPSAweDI0O1xuICAgICAgICB0aGlzLlNQSV9NSVNPX0RMRU5fT0ZGUyA9IDB4Mjg7XG4gICAgICAgIHRoaXMuU1BJX1cwX09GRlMgPSAweDU4O1xuICAgICAgICB0aGlzLlVTQl9SQU1fQkxPQ0sgPSAweDgwMDtcbiAgICAgICAgdGhpcy5VQVJUREVWX0JVRl9OT19VU0IgPSAzO1xuICAgICAgICB0aGlzLlVBUlRERVZfQlVGX05PID0gMHgzZmNlZjE0YztcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcERlc2NyaXB0aW9uKGxvYWRlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5DSElQX05BTUU7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBGZWF0dXJlcyhsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuIFtcIkJMRVwiLCBcIklFRUU4MDIuMTUuNFwiXTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q3J5c3RhbEZyZXEobG9hZGVyKSB7XG4gICAgICAgIC8vIEVTUDMySDIgWFRBTCBpcyBmaXhlZCB0byAzMk1IelxuICAgICAgICByZXR1cm4gMzI7XG4gICAgfVxuICAgIF9kMmgoZCkge1xuICAgICAgICBjb25zdCBoID0gKCtkKS50b1N0cmluZygxNik7XG4gICAgICAgIHJldHVybiBoLmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgaCA6IGg7XG4gICAgfVxuICAgIGFzeW5jIHBvc3RDb25uZWN0KGxvYWRlcikge1xuICAgICAgICBjb25zdCBidWZObyA9IChhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLlVBUlRERVZfQlVGX05PKSkgJiAweGZmO1xuICAgICAgICBsb2FkZXIuZGVidWcoXCJJbiBfcG9zdF9jb25uZWN0IFwiICsgYnVmTm8pO1xuICAgICAgICBpZiAoYnVmTm8gPT0gdGhpcy5VQVJUREVWX0JVRl9OT19VU0IpIHtcbiAgICAgICAgICAgIGxvYWRlci5FU1BfUkFNX0JMT0NLID0gdGhpcy5VU0JfUkFNX0JMT0NLO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHJlYWRNYWMobG9hZGVyKSB7XG4gICAgICAgIGxldCBtYWMwID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHKTtcbiAgICAgICAgbWFjMCA9IG1hYzAgPj4+IDA7XG4gICAgICAgIGxldCBtYWMxID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHICsgNCk7XG4gICAgICAgIG1hYzEgPSAobWFjMSA+Pj4gMCkgJiAweDAwMDBmZmZmO1xuICAgICAgICBjb25zdCBtYWMgPSBuZXcgVWludDhBcnJheSg2KTtcbiAgICAgICAgbWFjWzBdID0gKG1hYzEgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbMV0gPSBtYWMxICYgMHhmZjtcbiAgICAgICAgbWFjWzJdID0gKG1hYzAgPj4gMjQpICYgMHhmZjtcbiAgICAgICAgbWFjWzNdID0gKG1hYzAgPj4gMTYpICYgMHhmZjtcbiAgICAgICAgbWFjWzRdID0gKG1hYzAgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbNV0gPSBtYWMwICYgMHhmZjtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9kMmgobWFjWzBdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzFdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzJdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzNdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzRdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzVdKSk7XG4gICAgfVxuICAgIGdldEVyYXNlU2l6ZShvZmZzZXQsIHNpemUpIHtcbiAgICAgICAgcmV0dXJuIHNpemU7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32s2_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32s2_js.bundle.js deleted file mode 100644 index 19a51b5..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32s2_js.bundle.js +++ /dev/null @@ -1,259 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32s2_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32s2.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32s2.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32S2ROM: () => (/* binding */ ESP32S2ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32S2ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-S2"; - this.IMAGE_CHIP_ID = 2; - this.IROM_MAP_START = 0x40080000; - this.IROM_MAP_END = 0x40b80000; - this.DROM_MAP_START = 0x3f000000; - this.DROM_MAP_END = 0x3f3f0000; - this.CHIP_DETECT_MAGIC_VALUE = [0x000007c6]; - this.SPI_REG_BASE = 0x3f402000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - this.SPI_ADDR_REG_MSB = false; - this.MAC_EFUSE_REG = 0x3f41a044; // ESP32-S2 has special block for MAC efuses - this.UART_CLKDIV_REG = 0x3f400014; - this.SUPPORTS_ENCRYPTED_FLASH = true; - this.FLASH_ENCRYPTED_WRITE_ALIGN = 16; - // todo: use espefuse APIs to get this info - this.EFUSE_BASE = 0x3f41a000; - this.EFUSE_RD_REG_BASE = this.EFUSE_BASE + 0x030; // BLOCK0 read base address - this.EFUSE_BLOCK1_ADDR = this.EFUSE_BASE + 0x044; - this.EFUSE_BLOCK2_ADDR = this.EFUSE_BASE + 0x05c; - this.EFUSE_PURPOSE_KEY0_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY0_SHIFT = 24; - this.EFUSE_PURPOSE_KEY1_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY1_SHIFT = 28; - this.EFUSE_PURPOSE_KEY2_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY2_SHIFT = 0; - this.EFUSE_PURPOSE_KEY3_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY3_SHIFT = 4; - this.EFUSE_PURPOSE_KEY4_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY4_SHIFT = 8; - this.EFUSE_PURPOSE_KEY5_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY5_SHIFT = 12; - this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = this.EFUSE_RD_REG_BASE; - this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = 1 << 19; - this.EFUSE_SPI_BOOT_CRYPT_CNT_REG = this.EFUSE_BASE + 0x034; - this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK = 0x7 << 18; - this.EFUSE_SECURE_BOOT_EN_REG = this.EFUSE_BASE + 0x038; - this.EFUSE_SECURE_BOOT_EN_MASK = 1 << 20; - this.EFUSE_RD_REPEAT_DATA3_REG = this.EFUSE_BASE + 0x3c; - this.EFUSE_RD_REPEAT_DATA3_REG_FLASH_TYPE_MASK = 1 << 9; - this.PURPOSE_VAL_XTS_AES256_KEY_1 = 2; - this.PURPOSE_VAL_XTS_AES256_KEY_2 = 3; - this.PURPOSE_VAL_XTS_AES128_KEY = 4; - this.UARTDEV_BUF_NO = 0x3ffffd14; // Variable in ROM .bss which indicates the port in use - this.UARTDEV_BUF_NO_USB_OTG = 2; // Value of the above indicating that USB-OTG is in use - this.USB_RAM_BLOCK = 0x800; // Max block size USB-OTG is used - this.GPIO_STRAP_REG = 0x3f404038; - this.GPIO_STRAP_SPI_BOOT_MASK = 1 << 3; // Not download mode - this.GPIO_STRAP_VDDSPI_MASK = 1 << 4; - this.RTC_CNTL_OPTION1_REG = 0x3f408128; - this.RTC_CNTL_FORCE_DOWNLOAD_BOOT_MASK = 0x1; // Is download mode forced over USB? - this.RTCCNTL_BASE_REG = 0x3f408000; - this.RTC_CNTL_WDTCONFIG0_REG = this.RTCCNTL_BASE_REG + 0x0094; - this.RTC_CNTL_WDTCONFIG1_REG = this.RTCCNTL_BASE_REG + 0x0098; - this.RTC_CNTL_WDTWPROTECT_REG = this.RTCCNTL_BASE_REG + 0x00ac; - this.RTC_CNTL_WDT_WKEY = 0x50d83aa1; - this.MEMORY_MAP = [ - [0x00000000, 0x00010000, "PADDING"], - [0x3f000000, 0x3ff80000, "DROM"], - [0x3f500000, 0x3ff80000, "EXTRAM_DATA"], - [0x3ff9e000, 0x3ffa0000, "RTC_DRAM"], - [0x3ff9e000, 0x40000000, "BYTE_ACCESSIBLE"], - [0x3ff9e000, 0x40072000, "MEM_INTERNAL"], - [0x3ffb0000, 0x40000000, "DRAM"], - [0x40000000, 0x4001a100, "IROM_MASK"], - [0x40020000, 0x40070000, "IRAM"], - [0x40070000, 0x40072000, "RTC_IRAM"], - [0x40080000, 0x40800000, "IROM"], - [0x50000000, 0x50002000, "RTC_DATA"], - ]; - this.EFUSE_VDD_SPI_REG = this.EFUSE_BASE + 0x34; - this.VDD_SPI_XPD = 1 << 4; - this.VDD_SPI_TIEH = 1 << 5; - this.VDD_SPI_FORCE = 1 << 6; - this.UF2_FAMILY_ID = 0xbfdd4eee; - this.EFUSE_MAX_KEY = 5; - this.KEY_PURPOSES = { - 0: "USER/EMPTY", - 1: "RESERVED", - 2: "XTS_AES_256_KEY_1", - 3: "XTS_AES_256_KEY_2", - 4: "XTS_AES_128_KEY", - 5: "HMAC_DOWN_ALL", - 6: "HMAC_DOWN_JTAG", - 7: "HMAC_DOWN_DIGITAL_SIGNATURE", - 8: "HMAC_UP", - 9: "SECURE_BOOT_DIGEST0", - 10: "SECURE_BOOT_DIGEST1", - 11: "SECURE_BOOT_DIGEST2", - }; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x60000078; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0x1000; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - } - async getPkgVersion(loader) { - const numWord = 4; - const addr = this.EFUSE_BLOCK1_ADDR + 4 * numWord; - const word = await loader.readReg(addr); - const pkgVersion = (word >> 0) & 0x0f; - return pkgVersion; - } - async getMinorChipVersion(loader) { - const hiNumWord = 3; - const hi = ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * hiNumWord)) >> 20) & 0x01; - const lowNumWord = 4; - const low = ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * lowNumWord)) >> 4) & 0x07; - return (hi << 3) + low; - } - async getMajorChipVersion(loader) { - const numWord = 3; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 18) & 0x03; - } - async getFlashVersion(loader) { - const numWord = 3; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 21) & 0x0f; - } - async getChipDescription(loader) { - const chipDesc = { - 0: "ESP32-S2", - 1: "ESP32-S2FH2", - 2: "ESP32-S2FH4", - 102: "ESP32-S2FNR2", - 100: "ESP32-S2R2", - }; - const chipIndex = (await this.getFlashCap(loader)) + (await this.getPsramCap(loader)) * 100; - const majorRev = await this.getMajorChipVersion(loader); - const minorRev = await this.getMinorChipVersion(loader); - return `${chipDesc[chipIndex] || "unknown ESP32-S2"} (revision v${majorRev}.${minorRev})`; - } - async getFlashCap(loader) { - return await this.getFlashVersion(loader); - } - async getPsramVersion(loader) { - const numWord = 3; - const addr = this.EFUSE_BLOCK1_ADDR + 4 * numWord; - const registerValue = await loader.readReg(addr); - const psramCap = (registerValue >> 28) & 0x0f; - return psramCap; - } - async getPsramCap(loader) { - return await this.getPsramVersion(loader); - } - async getBlock2Version(loader) { - const numWord = 4; - const addr = this.EFUSE_BLOCK2_ADDR + 4 * numWord; - const registerValue = await loader.readReg(addr); - const block2Ver = (registerValue >> 4) & 0x07; - return block2Ver; - } - async getChipFeatures(loader) { - const features = ["Wi-Fi"]; - const flashMap = { - 0: "No Embedded Flash", - 1: "Embedded Flash 2MB", - 2: "Embedded Flash 4MB", - }; - const flashCap = await this.getFlashCap(loader); - const flashDescription = flashMap[flashCap] || "Unknown Embedded Flash"; - features.push(flashDescription); - const psramMap = { - 0: "No Embedded Flash", - 1: "Embedded PSRAM 2MB", - 2: "Embedded PSRAM 4MB", - }; - const psramCap = await this.getPsramCap(loader); - const psramDescription = psramMap[psramCap] || "Unknown Embedded PSRAM"; - features.push(psramDescription); - const block2VersionMap = { - 0: "No calibration in BLK2 of efuse", - 1: "ADC and temperature sensor calibration in BLK2 of efuse V1", - 2: "ADC and temperature sensor calibration in BLK2 of efuse V2", - }; - const block2Ver = await this.getBlock2Version(loader); - const block2VersionDescription = block2VersionMap[block2Ver] || "Unknown Calibration in BLK2"; - features.push(block2VersionDescription); - return features; - } - async getCrystalFreq(loader) { - return 40; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } - async usingUsbOtg(loader) { - const uartNo = (await loader.readReg(this.UARTDEV_BUF_NO)) & 0xff; - return uartNo === this.UARTDEV_BUF_NO_USB_OTG; - } - async postConnect(loader) { - const usingUsbOtg = await this.usingUsbOtg(loader); - loader.debug("In _post_connect using USB OTG ?" + usingUsbOtg); - if (usingUsbOtg) { - loader.ESP_RAM_BLOCK = this.USB_RAM_BLOCK; - } - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJzMl9qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBK0I7QUFDeEIseUJBQXlCLHdDQUFHO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRDtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyx5Q0FBeUM7QUFDekMsb0NBQW9DO0FBQ3BDO0FBQ0EsZ0RBQWdEO0FBQ2hEO0FBQ0E7QUFDQSxzREFBc0Q7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLDJDQUEyQyxhQUFhLFNBQVMsR0FBRyxTQUFTO0FBQy9GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3B0b29sLWpzL2xpYi90YXJnZXRzL2VzcDMyczIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUk9NIH0gZnJvbSBcIi4vcm9tLmpzXCI7XG5leHBvcnQgY2xhc3MgRVNQMzJTMlJPTSBleHRlbmRzIFJPTSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuQ0hJUF9OQU1FID0gXCJFU1AzMi1TMlwiO1xuICAgICAgICB0aGlzLklNQUdFX0NISVBfSUQgPSAyO1xuICAgICAgICB0aGlzLklST01fTUFQX1NUQVJUID0gMHg0MDA4MDAwMDtcbiAgICAgICAgdGhpcy5JUk9NX01BUF9FTkQgPSAweDQwYjgwMDAwO1xuICAgICAgICB0aGlzLkRST01fTUFQX1NUQVJUID0gMHgzZjAwMDAwMDtcbiAgICAgICAgdGhpcy5EUk9NX01BUF9FTkQgPSAweDNmM2YwMDAwO1xuICAgICAgICB0aGlzLkNISVBfREVURUNUX01BR0lDX1ZBTFVFID0gWzB4MDAwMDA3YzZdO1xuICAgICAgICB0aGlzLlNQSV9SRUdfQkFTRSA9IDB4M2Y0MDIwMDA7XG4gICAgICAgIHRoaXMuU1BJX1VTUl9PRkZTID0gMHgxODtcbiAgICAgICAgdGhpcy5TUElfVVNSMV9PRkZTID0gMHgxYztcbiAgICAgICAgdGhpcy5TUElfVVNSMl9PRkZTID0gMHgyMDtcbiAgICAgICAgdGhpcy5TUElfTU9TSV9ETEVOX09GRlMgPSAweDI0O1xuICAgICAgICB0aGlzLlNQSV9NSVNPX0RMRU5fT0ZGUyA9IDB4Mjg7XG4gICAgICAgIHRoaXMuU1BJX1cwX09GRlMgPSAweDU4O1xuICAgICAgICB0aGlzLlNQSV9BRERSX1JFR19NU0IgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5NQUNfRUZVU0VfUkVHID0gMHgzZjQxYTA0NDsgLy8gRVNQMzItUzIgaGFzIHNwZWNpYWwgYmxvY2sgZm9yIE1BQyBlZnVzZXNcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9SRUcgPSAweDNmNDAwMDE0O1xuICAgICAgICB0aGlzLlNVUFBPUlRTX0VOQ1JZUFRFRF9GTEFTSCA9IHRydWU7XG4gICAgICAgIHRoaXMuRkxBU0hfRU5DUllQVEVEX1dSSVRFX0FMSUdOID0gMTY7XG4gICAgICAgIC8vIHRvZG86IHVzZSBlc3BlZnVzZSBBUElzIHRvIGdldCB0aGlzIGluZm9cbiAgICAgICAgdGhpcy5FRlVTRV9CQVNFID0gMHgzZjQxYTAwMDtcbiAgICAgICAgdGhpcy5FRlVTRV9SRF9SRUdfQkFTRSA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDMwOyAvLyBCTE9DSzAgcmVhZCBiYXNlIGFkZHJlc3NcbiAgICAgICAgdGhpcy5FRlVTRV9CTE9DSzFfQUREUiA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICB0aGlzLkVGVVNFX0JMT0NLMl9BRERSID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNWM7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkwX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MzQ7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkwX1NISUZUID0gMjQ7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkxX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MzQ7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkxX1NISUZUID0gMjg7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkyX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4Mzg7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkyX1NISUZUID0gMDtcbiAgICAgICAgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTNfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgzODtcbiAgICAgICAgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTNfU0hJRlQgPSA0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZNF9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZNF9TSElGVCA9IDg7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVk1X1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4Mzg7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVk1X1NISUZUID0gMTI7XG4gICAgICAgIHRoaXMuRUZVU0VfRElTX0RPV05MT0FEX01BTlVBTF9FTkNSWVBUX1JFRyA9IHRoaXMuRUZVU0VfUkRfUkVHX0JBU0U7XG4gICAgICAgIHRoaXMuRUZVU0VfRElTX0RPV05MT0FEX01BTlVBTF9FTkNSWVBUID0gMSA8PCAxOTtcbiAgICAgICAgdGhpcy5FRlVTRV9TUElfQk9PVF9DUllQVF9DTlRfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwMzQ7XG4gICAgICAgIHRoaXMuRUZVU0VfU1BJX0JPT1RfQ1JZUFRfQ05UX01BU0sgPSAweDcgPDwgMTg7XG4gICAgICAgIHRoaXMuRUZVU0VfU0VDVVJFX0JPT1RfRU5fUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwMzg7XG4gICAgICAgIHRoaXMuRUZVU0VfU0VDVVJFX0JPT1RfRU5fTUFTSyA9IDEgPDwgMjA7XG4gICAgICAgIHRoaXMuRUZVU0VfUkRfUkVQRUFUX0RBVEEzX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4M2M7XG4gICAgICAgIHRoaXMuRUZVU0VfUkRfUkVQRUFUX0RBVEEzX1JFR19GTEFTSF9UWVBFX01BU0sgPSAxIDw8IDk7XG4gICAgICAgIHRoaXMuUFVSUE9TRV9WQUxfWFRTX0FFUzI1Nl9LRVlfMSA9IDI7XG4gICAgICAgIHRoaXMuUFVSUE9TRV9WQUxfWFRTX0FFUzI1Nl9LRVlfMiA9IDM7XG4gICAgICAgIHRoaXMuUFVSUE9TRV9WQUxfWFRTX0FFUzEyOF9LRVkgPSA0O1xuICAgICAgICB0aGlzLlVBUlRERVZfQlVGX05PID0gMHgzZmZmZmQxNDsgLy8gVmFyaWFibGUgaW4gUk9NIC5ic3Mgd2hpY2ggaW5kaWNhdGVzIHRoZSBwb3J0IGluIHVzZVxuICAgICAgICB0aGlzLlVBUlRERVZfQlVGX05PX1VTQl9PVEcgPSAyOyAvLyBWYWx1ZSBvZiB0aGUgYWJvdmUgaW5kaWNhdGluZyB0aGF0IFVTQi1PVEcgaXMgaW4gdXNlXG4gICAgICAgIHRoaXMuVVNCX1JBTV9CTE9DSyA9IDB4ODAwOyAvLyBNYXggYmxvY2sgc2l6ZSBVU0ItT1RHIGlzIHVzZWRcbiAgICAgICAgdGhpcy5HUElPX1NUUkFQX1JFRyA9IDB4M2Y0MDQwMzg7XG4gICAgICAgIHRoaXMuR1BJT19TVFJBUF9TUElfQk9PVF9NQVNLID0gMSA8PCAzOyAvLyBOb3QgZG93bmxvYWQgbW9kZVxuICAgICAgICB0aGlzLkdQSU9fU1RSQVBfVkREU1BJX01BU0sgPSAxIDw8IDQ7XG4gICAgICAgIHRoaXMuUlRDX0NOVExfT1BUSU9OMV9SRUcgPSAweDNmNDA4MTI4O1xuICAgICAgICB0aGlzLlJUQ19DTlRMX0ZPUkNFX0RPV05MT0FEX0JPT1RfTUFTSyA9IDB4MTsgLy8gSXMgZG93bmxvYWQgbW9kZSBmb3JjZWQgb3ZlciBVU0I/XG4gICAgICAgIHRoaXMuUlRDQ05UTF9CQVNFX1JFRyA9IDB4M2Y0MDgwMDA7XG4gICAgICAgIHRoaXMuUlRDX0NOVExfV0RUQ09ORklHMF9SRUcgPSB0aGlzLlJUQ0NOVExfQkFTRV9SRUcgKyAweDAwOTQ7XG4gICAgICAgIHRoaXMuUlRDX0NOVExfV0RUQ09ORklHMV9SRUcgPSB0aGlzLlJUQ0NOVExfQkFTRV9SRUcgKyAweDAwOTg7XG4gICAgICAgIHRoaXMuUlRDX0NOVExfV0RUV1BST1RFQ1RfUkVHID0gdGhpcy5SVENDTlRMX0JBU0VfUkVHICsgMHgwMGFjO1xuICAgICAgICB0aGlzLlJUQ19DTlRMX1dEVF9XS0VZID0gMHg1MGQ4M2FhMTtcbiAgICAgICAgdGhpcy5NRU1PUllfTUFQID0gW1xuICAgICAgICAgICAgWzB4MDAwMDAwMDAsIDB4MDAwMTAwMDAsIFwiUEFERElOR1wiXSxcbiAgICAgICAgICAgIFsweDNmMDAwMDAwLCAweDNmZjgwMDAwLCBcIkRST01cIl0sXG4gICAgICAgICAgICBbMHgzZjUwMDAwMCwgMHgzZmY4MDAwMCwgXCJFWFRSQU1fREFUQVwiXSxcbiAgICAgICAgICAgIFsweDNmZjllMDAwLCAweDNmZmEwMDAwLCBcIlJUQ19EUkFNXCJdLFxuICAgICAgICAgICAgWzB4M2ZmOWUwMDAsIDB4NDAwMDAwMDAsIFwiQllURV9BQ0NFU1NJQkxFXCJdLFxuICAgICAgICAgICAgWzB4M2ZmOWUwMDAsIDB4NDAwNzIwMDAsIFwiTUVNX0lOVEVSTkFMXCJdLFxuICAgICAgICAgICAgWzB4M2ZmYjAwMDAsIDB4NDAwMDAwMDAsIFwiRFJBTVwiXSxcbiAgICAgICAgICAgIFsweDQwMDAwMDAwLCAweDQwMDFhMTAwLCBcIklST01fTUFTS1wiXSxcbiAgICAgICAgICAgIFsweDQwMDIwMDAwLCAweDQwMDcwMDAwLCBcIklSQU1cIl0sXG4gICAgICAgICAgICBbMHg0MDA3MDAwMCwgMHg0MDA3MjAwMCwgXCJSVENfSVJBTVwiXSxcbiAgICAgICAgICAgIFsweDQwMDgwMDAwLCAweDQwODAwMDAwLCBcIklST01cIl0sXG4gICAgICAgICAgICBbMHg1MDAwMDAwMCwgMHg1MDAwMjAwMCwgXCJSVENfREFUQVwiXSxcbiAgICAgICAgXTtcbiAgICAgICAgdGhpcy5FRlVTRV9WRERfU1BJX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MzQ7XG4gICAgICAgIHRoaXMuVkREX1NQSV9YUEQgPSAxIDw8IDQ7XG4gICAgICAgIHRoaXMuVkREX1NQSV9USUVIID0gMSA8PCA1O1xuICAgICAgICB0aGlzLlZERF9TUElfRk9SQ0UgPSAxIDw8IDY7XG4gICAgICAgIHRoaXMuVUYyX0ZBTUlMWV9JRCA9IDB4YmZkZDRlZWU7XG4gICAgICAgIHRoaXMuRUZVU0VfTUFYX0tFWSA9IDU7XG4gICAgICAgIHRoaXMuS0VZX1BVUlBPU0VTID0ge1xuICAgICAgICAgICAgMDogXCJVU0VSL0VNUFRZXCIsXG4gICAgICAgICAgICAxOiBcIlJFU0VSVkVEXCIsXG4gICAgICAgICAgICAyOiBcIlhUU19BRVNfMjU2X0tFWV8xXCIsXG4gICAgICAgICAgICAzOiBcIlhUU19BRVNfMjU2X0tFWV8yXCIsXG4gICAgICAgICAgICA0OiBcIlhUU19BRVNfMTI4X0tFWVwiLFxuICAgICAgICAgICAgNTogXCJITUFDX0RPV05fQUxMXCIsXG4gICAgICAgICAgICA2OiBcIkhNQUNfRE9XTl9KVEFHXCIsXG4gICAgICAgICAgICA3OiBcIkhNQUNfRE9XTl9ESUdJVEFMX1NJR05BVFVSRVwiLFxuICAgICAgICAgICAgODogXCJITUFDX1VQXCIsXG4gICAgICAgICAgICA5OiBcIlNFQ1VSRV9CT09UX0RJR0VTVDBcIixcbiAgICAgICAgICAgIDEwOiBcIlNFQ1VSRV9CT09UX0RJR0VTVDFcIixcbiAgICAgICAgICAgIDExOiBcIlNFQ1VSRV9CT09UX0RJR0VTVDJcIixcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9NQVNLID0gMHhmZmZmZjtcbiAgICAgICAgdGhpcy5VQVJUX0RBVEVfUkVHX0FERFIgPSAweDYwMDAwMDc4O1xuICAgICAgICB0aGlzLkZMQVNIX1dSSVRFX1NJWkUgPSAweDQwMDtcbiAgICAgICAgdGhpcy5CT09UTE9BREVSX0ZMQVNIX09GRlNFVCA9IDB4MTAwMDtcbiAgICAgICAgdGhpcy5GTEFTSF9TSVpFUyA9IHtcbiAgICAgICAgICAgIFwiMU1CXCI6IDB4MDAsXG4gICAgICAgICAgICBcIjJNQlwiOiAweDEwLFxuICAgICAgICAgICAgXCI0TUJcIjogMHgyMCxcbiAgICAgICAgICAgIFwiOE1CXCI6IDB4MzAsXG4gICAgICAgICAgICBcIjE2TUJcIjogMHg0MCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0UGtnVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDQ7XG4gICAgICAgIGNvbnN0IGFkZHIgPSB0aGlzLkVGVVNFX0JMT0NLMV9BRERSICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHdvcmQgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKTtcbiAgICAgICAgY29uc3QgcGtnVmVyc2lvbiA9ICh3b3JkID4+IDApICYgMHgwZjtcbiAgICAgICAgcmV0dXJuIHBrZ1ZlcnNpb247XG4gICAgfVxuICAgIGFzeW5jIGdldE1pbm9yQ2hpcFZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGhpTnVtV29yZCA9IDM7XG4gICAgICAgIGNvbnN0IGhpID0gKChhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLkVGVVNFX0JMT0NLMV9BRERSICsgNCAqIGhpTnVtV29yZCkpID4+IDIwKSAmIDB4MDE7XG4gICAgICAgIGNvbnN0IGxvd051bVdvcmQgPSA0O1xuICAgICAgICBjb25zdCBsb3cgPSAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRUZVU0VfQkxPQ0sxX0FERFIgKyA0ICogbG93TnVtV29yZCkpID4+IDQpICYgMHgwNztcbiAgICAgICAgcmV0dXJuIChoaSA8PCAzKSArIGxvdztcbiAgICB9XG4gICAgYXN5bmMgZ2V0TWFqb3JDaGlwVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDM7XG4gICAgICAgIHJldHVybiAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRUZVU0VfQkxPQ0sxX0FERFIgKyA0ICogbnVtV29yZCkpID4+IDE4KSAmIDB4MDM7XG4gICAgfVxuICAgIGFzeW5jIGdldEZsYXNoVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDM7XG4gICAgICAgIHJldHVybiAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRUZVU0VfQkxPQ0sxX0FERFIgKyA0ICogbnVtV29yZCkpID4+IDIxKSAmIDB4MGY7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBEZXNjcmlwdGlvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgY2hpcERlc2MgPSB7XG4gICAgICAgICAgICAwOiBcIkVTUDMyLVMyXCIsXG4gICAgICAgICAgICAxOiBcIkVTUDMyLVMyRkgyXCIsXG4gICAgICAgICAgICAyOiBcIkVTUDMyLVMyRkg0XCIsXG4gICAgICAgICAgICAxMDI6IFwiRVNQMzItUzJGTlIyXCIsXG4gICAgICAgICAgICAxMDA6IFwiRVNQMzItUzJSMlwiLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjaGlwSW5kZXggPSAoYXdhaXQgdGhpcy5nZXRGbGFzaENhcChsb2FkZXIpKSArIChhd2FpdCB0aGlzLmdldFBzcmFtQ2FwKGxvYWRlcikpICogMTAwO1xuICAgICAgICBjb25zdCBtYWpvclJldiA9IGF3YWl0IHRoaXMuZ2V0TWFqb3JDaGlwVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICBjb25zdCBtaW5vclJldiA9IGF3YWl0IHRoaXMuZ2V0TWlub3JDaGlwVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICByZXR1cm4gYCR7Y2hpcERlc2NbY2hpcEluZGV4XSB8fCBcInVua25vd24gRVNQMzItUzJcIn0gKHJldmlzaW9uIHYke21ham9yUmV2fS4ke21pbm9yUmV2fSlgO1xuICAgIH1cbiAgICBhc3luYyBnZXRGbGFzaENhcChsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0Rmxhc2hWZXJzaW9uKGxvYWRlcik7XG4gICAgfVxuICAgIGFzeW5jIGdldFBzcmFtVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDM7XG4gICAgICAgIGNvbnN0IGFkZHIgPSB0aGlzLkVGVVNFX0JMT0NLMV9BRERSICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHJlZ2lzdGVyVmFsdWUgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKTtcbiAgICAgICAgY29uc3QgcHNyYW1DYXAgPSAocmVnaXN0ZXJWYWx1ZSA+PiAyOCkgJiAweDBmO1xuICAgICAgICByZXR1cm4gcHNyYW1DYXA7XG4gICAgfVxuICAgIGFzeW5jIGdldFBzcmFtQ2FwKGxvYWRlcikge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5nZXRQc3JhbVZlcnNpb24obG9hZGVyKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0QmxvY2syVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDQ7XG4gICAgICAgIGNvbnN0IGFkZHIgPSB0aGlzLkVGVVNFX0JMT0NLMl9BRERSICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHJlZ2lzdGVyVmFsdWUgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKTtcbiAgICAgICAgY29uc3QgYmxvY2syVmVyID0gKHJlZ2lzdGVyVmFsdWUgPj4gNCkgJiAweDA3O1xuICAgICAgICByZXR1cm4gYmxvY2syVmVyO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwRmVhdHVyZXMobG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGZlYXR1cmVzID0gW1wiV2ktRmlcIl07XG4gICAgICAgIGNvbnN0IGZsYXNoTWFwID0ge1xuICAgICAgICAgICAgMDogXCJObyBFbWJlZGRlZCBGbGFzaFwiLFxuICAgICAgICAgICAgMTogXCJFbWJlZGRlZCBGbGFzaCAyTUJcIixcbiAgICAgICAgICAgIDI6IFwiRW1iZWRkZWQgRmxhc2ggNE1CXCIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGZsYXNoQ2FwID0gYXdhaXQgdGhpcy5nZXRGbGFzaENhcChsb2FkZXIpO1xuICAgICAgICBjb25zdCBmbGFzaERlc2NyaXB0aW9uID0gZmxhc2hNYXBbZmxhc2hDYXBdIHx8IFwiVW5rbm93biBFbWJlZGRlZCBGbGFzaFwiO1xuICAgICAgICBmZWF0dXJlcy5wdXNoKGZsYXNoRGVzY3JpcHRpb24pO1xuICAgICAgICBjb25zdCBwc3JhbU1hcCA9IHtcbiAgICAgICAgICAgIDA6IFwiTm8gRW1iZWRkZWQgRmxhc2hcIixcbiAgICAgICAgICAgIDE6IFwiRW1iZWRkZWQgUFNSQU0gMk1CXCIsXG4gICAgICAgICAgICAyOiBcIkVtYmVkZGVkIFBTUkFNIDRNQlwiLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwc3JhbUNhcCA9IGF3YWl0IHRoaXMuZ2V0UHNyYW1DYXAobG9hZGVyKTtcbiAgICAgICAgY29uc3QgcHNyYW1EZXNjcmlwdGlvbiA9IHBzcmFtTWFwW3BzcmFtQ2FwXSB8fCBcIlVua25vd24gRW1iZWRkZWQgUFNSQU1cIjtcbiAgICAgICAgZmVhdHVyZXMucHVzaChwc3JhbURlc2NyaXB0aW9uKTtcbiAgICAgICAgY29uc3QgYmxvY2syVmVyc2lvbk1hcCA9IHtcbiAgICAgICAgICAgIDA6IFwiTm8gY2FsaWJyYXRpb24gaW4gQkxLMiBvZiBlZnVzZVwiLFxuICAgICAgICAgICAgMTogXCJBREMgYW5kIHRlbXBlcmF0dXJlIHNlbnNvciBjYWxpYnJhdGlvbiBpbiBCTEsyIG9mIGVmdXNlIFYxXCIsXG4gICAgICAgICAgICAyOiBcIkFEQyBhbmQgdGVtcGVyYXR1cmUgc2Vuc29yIGNhbGlicmF0aW9uIGluIEJMSzIgb2YgZWZ1c2UgVjJcIixcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYmxvY2syVmVyID0gYXdhaXQgdGhpcy5nZXRCbG9jazJWZXJzaW9uKGxvYWRlcik7XG4gICAgICAgIGNvbnN0IGJsb2NrMlZlcnNpb25EZXNjcmlwdGlvbiA9IGJsb2NrMlZlcnNpb25NYXBbYmxvY2syVmVyXSB8fCBcIlVua25vd24gQ2FsaWJyYXRpb24gaW4gQkxLMlwiO1xuICAgICAgICBmZWF0dXJlcy5wdXNoKGJsb2NrMlZlcnNpb25EZXNjcmlwdGlvbik7XG4gICAgICAgIHJldHVybiBmZWF0dXJlcztcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q3J5c3RhbEZyZXEobG9hZGVyKSB7XG4gICAgICAgIHJldHVybiA0MDtcbiAgICB9XG4gICAgX2QyaChkKSB7XG4gICAgICAgIGNvbnN0IGggPSAoK2QpLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgcmV0dXJuIGgubGVuZ3RoID09PSAxID8gXCIwXCIgKyBoIDogaDtcbiAgICB9XG4gICAgYXN5bmMgcmVhZE1hYyhsb2FkZXIpIHtcbiAgICAgICAgbGV0IG1hYzAgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcpO1xuICAgICAgICBtYWMwID0gbWFjMCA+Pj4gMDtcbiAgICAgICAgbGV0IG1hYzEgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcgKyA0KTtcbiAgICAgICAgbWFjMSA9IChtYWMxID4+PiAwKSAmIDB4MDAwMGZmZmY7XG4gICAgICAgIGNvbnN0IG1hYyA9IG5ldyBVaW50OEFycmF5KDYpO1xuICAgICAgICBtYWNbMF0gPSAobWFjMSA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1sxXSA9IG1hYzEgJiAweGZmO1xuICAgICAgICBtYWNbMl0gPSAobWFjMCA+PiAyNCkgJiAweGZmO1xuICAgICAgICBtYWNbM10gPSAobWFjMCA+PiAxNikgJiAweGZmO1xuICAgICAgICBtYWNbNF0gPSAobWFjMCA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1s1XSA9IG1hYzAgJiAweGZmO1xuICAgICAgICByZXR1cm4gKHRoaXMuX2QyaChtYWNbMF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMV0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMl0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbM10pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNV0pKTtcbiAgICB9XG4gICAgZ2V0RXJhc2VTaXplKG9mZnNldCwgc2l6ZSkge1xuICAgICAgICByZXR1cm4gc2l6ZTtcbiAgICB9XG4gICAgYXN5bmMgdXNpbmdVc2JPdGcobG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IHVhcnRObyA9IChhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLlVBUlRERVZfQlVGX05PKSkgJiAweGZmO1xuICAgICAgICByZXR1cm4gdWFydE5vID09PSB0aGlzLlVBUlRERVZfQlVGX05PX1VTQl9PVEc7XG4gICAgfVxuICAgIGFzeW5jIHBvc3RDb25uZWN0KGxvYWRlcikge1xuICAgICAgICBjb25zdCB1c2luZ1VzYk90ZyA9IGF3YWl0IHRoaXMudXNpbmdVc2JPdGcobG9hZGVyKTtcbiAgICAgICAgbG9hZGVyLmRlYnVnKFwiSW4gX3Bvc3RfY29ubmVjdCB1c2luZyBVU0IgT1RHID9cIiArIHVzaW5nVXNiT3RnKTtcbiAgICAgICAgaWYgKHVzaW5nVXNiT3RnKSB7XG4gICAgICAgICAgICBsb2FkZXIuRVNQX1JBTV9CTE9DSyA9IHRoaXMuVVNCX1JBTV9CTE9DSztcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp32s3_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp32s3_js.bundle.js deleted file mode 100644 index 994397f..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp32s3_js.bundle.js +++ /dev/null @@ -1,221 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp32s3_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32s3.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32s3.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32S3ROM: () => (/* binding */ ESP32S3ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32S3ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-S3"; - this.IMAGE_CHIP_ID = 9; - this.EFUSE_BASE = 0x60007000; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.EFUSE_BLOCK1_ADDR = this.EFUSE_BASE + 0x44; - this.EFUSE_BLOCK2_ADDR = this.EFUSE_BASE + 0x5c; - this.UART_CLKDIV_REG = 0x60000014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x60000080; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0x0; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.SPI_REG_BASE = 0x60002000; - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - this.USB_RAM_BLOCK = 0x800; - this.UARTDEV_BUF_NO_USB = 3; - this.UARTDEV_BUF_NO = 0x3fcef14c; - } - async getChipDescription(loader) { - const majorRev = await this.getMajorChipVersion(loader); - const minorRev = await this.getMinorChipVersion(loader); - const pkgVersion = await this.getPkgVersion(loader); - const chipName = { - 0: "ESP32-S3 (QFN56)", - 1: "ESP32-S3-PICO-1 (LGA56)", - }; - return `${chipName[pkgVersion] || "unknown ESP32-S3"} (revision v${majorRev}.${minorRev})`; - } - async getPkgVersion(loader) { - const numWord = 3; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 21) & 0x07; - } - async getRawMinorChipVersion(loader) { - const hiNumWord = 5; - const hi = ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * hiNumWord)) >> 23) & 0x01; - const lowNumWord = 3; - const low = ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * lowNumWord)) >> 18) & 0x07; - return (hi << 3) + low; - } - async getMinorChipVersion(loader) { - const minorRaw = await this.getRawMinorChipVersion(loader); - if (await this.isEco0(loader, minorRaw)) { - return 0; - } - return this.getRawMinorChipVersion(loader); - } - async getRawMajorChipVersion(loader) { - const numWord = 5; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 24) & 0x03; - } - async getMajorChipVersion(loader) { - const minorRaw = await this.getRawMinorChipVersion(loader); - if (await this.isEco0(loader, minorRaw)) { - return 0; - } - return this.getRawMajorChipVersion(loader); - } - async getBlkVersionMajor(loader) { - const numWord = 4; - return ((await loader.readReg(this.EFUSE_BLOCK2_ADDR + 4 * numWord)) >> 0) & 0x03; - } - async getBlkVersionMinor(loader) { - const numWord = 3; - return ((await loader.readReg(this.EFUSE_BLOCK1_ADDR + 4 * numWord)) >> 24) & 0x07; - } - async isEco0(loader, minorRaw) { - // Workaround: The major version field was allocated to other purposes - // when block version is v1.1. - // Luckily only chip v0.0 have this kind of block version and efuse usage. - return ((minorRaw & 0x7) === 0 && - (await this.getBlkVersionMajor(loader)) === 1 && - (await this.getBlkVersionMinor(loader)) === 1); - } - async getFlashCap(loader) { - const numWord = 3; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const registerValue = await loader.readReg(addr); - const flashCap = (registerValue >> 27) & 0x07; - return flashCap; - } - async getFlashVendor(loader) { - const numWord = 4; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const registerValue = await loader.readReg(addr); - const vendorId = (registerValue >> 0) & 0x07; - const vendorMap = { - 1: "XMC", - 2: "GD", - 3: "FM", - 4: "TT", - 5: "BY", - }; - return vendorMap[vendorId] || ""; - } - async getPsramCap(loader) { - const numWord = 4; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const registerValue = await loader.readReg(addr); - const psramCap = (registerValue >> 3) & 0x03; - return psramCap; - } - async getPsramVendor(loader) { - const numWord = 4; - const block1Addr = this.EFUSE_BASE + 0x044; - const addr = block1Addr + 4 * numWord; - const registerValue = await loader.readReg(addr); - const vendorId = (registerValue >> 7) & 0x03; - const vendorMap = { - 1: "AP_3v3", - 2: "AP_1v8", - }; - return vendorMap[vendorId] || ""; - } - async getChipFeatures(loader) { - const features = ["Wi-Fi", "BLE"]; - const flashMap = { - 0: null, - 1: "Embedded Flash 8MB", - 2: "Embedded Flash 4MB", - }; - const flashCap = await this.getFlashCap(loader); - const flashVendor = await this.getFlashVendor(loader); - const flash = flashMap[flashCap]; - const flashDescription = flash !== undefined ? flash : "Unknown Embedded Flash"; - if (flash !== null) { - features.push(`${flashDescription} (${flashVendor})`); - } - const psramMap = { - 0: null, - 1: "Embedded PSRAM 8MB", - 2: "Embedded PSRAM 2MB", - }; - const psramCap = await this.getPsramCap(loader); - const psramVendor = await this.getPsramVendor(loader); - const psram = psramMap[psramCap]; - const psramDescription = psram !== undefined ? psram : "Unknown Embedded PSRAM"; - if (psram !== null) { - features.push(`${psramDescription} (${psramVendor})`); - } - return features; - } - async getCrystalFreq(loader) { - return 40; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async postConnect(loader) { - const bufNo = (await loader.readReg(this.UARTDEV_BUF_NO)) & 0xff; - loader.debug("In _post_connect " + bufNo); - if (bufNo == this.UARTDEV_BUF_NO_USB) { - loader.ESP_RAM_BLOCK = this.USB_RAM_BLOCK; - } - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwMzJzM19qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBK0I7QUFDeEIseUJBQXlCLHdDQUFHO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQiw0Q0FBNEMsYUFBYSxTQUFTLEdBQUcsU0FBUztBQUNoRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLGtCQUFrQixHQUFHLFlBQVk7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixrQkFBa0IsR0FBRyxZQUFZO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3RhcmdldHMvZXNwMzJzMy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBST00gfSBmcm9tIFwiLi9yb20uanNcIjtcbmV4cG9ydCBjbGFzcyBFU1AzMlMzUk9NIGV4dGVuZHMgUk9NIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5DSElQX05BTUUgPSBcIkVTUDMyLVMzXCI7XG4gICAgICAgIHRoaXMuSU1BR0VfQ0hJUF9JRCA9IDk7XG4gICAgICAgIHRoaXMuRUZVU0VfQkFTRSA9IDB4NjAwMDcwMDA7XG4gICAgICAgIHRoaXMuTUFDX0VGVVNFX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICB0aGlzLkVGVVNFX0JMT0NLMV9BRERSID0gdGhpcy5FRlVTRV9CQVNFICsgMHg0NDtcbiAgICAgICAgdGhpcy5FRlVTRV9CTE9DSzJfQUREUiA9IHRoaXMuRUZVU0VfQkFTRSArIDB4NWM7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfUkVHID0gMHg2MDAwMDAxNDtcbiAgICAgICAgdGhpcy5VQVJUX0NMS0RJVl9NQVNLID0gMHhmZmZmZjtcbiAgICAgICAgdGhpcy5VQVJUX0RBVEVfUkVHX0FERFIgPSAweDYwMDAwMDgwO1xuICAgICAgICB0aGlzLkZMQVNIX1dSSVRFX1NJWkUgPSAweDQwMDtcbiAgICAgICAgdGhpcy5CT09UTE9BREVSX0ZMQVNIX09GRlNFVCA9IDB4MDtcbiAgICAgICAgdGhpcy5GTEFTSF9TSVpFUyA9IHtcbiAgICAgICAgICAgIFwiMU1CXCI6IDB4MDAsXG4gICAgICAgICAgICBcIjJNQlwiOiAweDEwLFxuICAgICAgICAgICAgXCI0TUJcIjogMHgyMCxcbiAgICAgICAgICAgIFwiOE1CXCI6IDB4MzAsXG4gICAgICAgICAgICBcIjE2TUJcIjogMHg0MCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5TUElfUkVHX0JBU0UgPSAweDYwMDAyMDAwO1xuICAgICAgICB0aGlzLlNQSV9VU1JfT0ZGUyA9IDB4MTg7XG4gICAgICAgIHRoaXMuU1BJX1VTUjFfT0ZGUyA9IDB4MWM7XG4gICAgICAgIHRoaXMuU1BJX1VTUjJfT0ZGUyA9IDB4MjA7XG4gICAgICAgIHRoaXMuU1BJX01PU0lfRExFTl9PRkZTID0gMHgyNDtcbiAgICAgICAgdGhpcy5TUElfTUlTT19ETEVOX09GRlMgPSAweDI4O1xuICAgICAgICB0aGlzLlNQSV9XMF9PRkZTID0gMHg1ODtcbiAgICAgICAgdGhpcy5VU0JfUkFNX0JMT0NLID0gMHg4MDA7XG4gICAgICAgIHRoaXMuVUFSVERFVl9CVUZfTk9fVVNCID0gMztcbiAgICAgICAgdGhpcy5VQVJUREVWX0JVRl9OTyA9IDB4M2ZjZWYxNGM7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBEZXNjcmlwdGlvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbWFqb3JSZXYgPSBhd2FpdCB0aGlzLmdldE1ham9yQ2hpcFZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgY29uc3QgbWlub3JSZXYgPSBhd2FpdCB0aGlzLmdldE1pbm9yQ2hpcFZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgY29uc3QgcGtnVmVyc2lvbiA9IGF3YWl0IHRoaXMuZ2V0UGtnVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICBjb25zdCBjaGlwTmFtZSA9IHtcbiAgICAgICAgICAgIDA6IFwiRVNQMzItUzMgKFFGTjU2KVwiLFxuICAgICAgICAgICAgMTogXCJFU1AzMi1TMy1QSUNPLTEgKExHQTU2KVwiLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gYCR7Y2hpcE5hbWVbcGtnVmVyc2lvbl0gfHwgXCJ1bmtub3duIEVTUDMyLVMzXCJ9IChyZXZpc2lvbiB2JHttYWpvclJldn0uJHttaW5vclJldn0pYDtcbiAgICB9XG4gICAgYXN5bmMgZ2V0UGtnVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDM7XG4gICAgICAgIHJldHVybiAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRUZVU0VfQkxPQ0sxX0FERFIgKyA0ICogbnVtV29yZCkpID4+IDIxKSAmIDB4MDc7XG4gICAgfVxuICAgIGFzeW5jIGdldFJhd01pbm9yQ2hpcFZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGhpTnVtV29yZCA9IDU7XG4gICAgICAgIGNvbnN0IGhpID0gKChhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLkVGVVNFX0JMT0NLMV9BRERSICsgNCAqIGhpTnVtV29yZCkpID4+IDIzKSAmIDB4MDE7XG4gICAgICAgIGNvbnN0IGxvd051bVdvcmQgPSAzO1xuICAgICAgICBjb25zdCBsb3cgPSAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRUZVU0VfQkxPQ0sxX0FERFIgKyA0ICogbG93TnVtV29yZCkpID4+IDE4KSAmIDB4MDc7XG4gICAgICAgIHJldHVybiAoaGkgPDwgMykgKyBsb3c7XG4gICAgfVxuICAgIGFzeW5jIGdldE1pbm9yQ2hpcFZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG1pbm9yUmF3ID0gYXdhaXQgdGhpcy5nZXRSYXdNaW5vckNoaXBWZXJzaW9uKGxvYWRlcik7XG4gICAgICAgIGlmIChhd2FpdCB0aGlzLmlzRWNvMChsb2FkZXIsIG1pbm9yUmF3KSkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UmF3TWlub3JDaGlwVmVyc2lvbihsb2FkZXIpO1xuICAgIH1cbiAgICBhc3luYyBnZXRSYXdNYWpvckNoaXBWZXJzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gNTtcbiAgICAgICAgcmV0dXJuICgoYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5FRlVTRV9CTE9DSzFfQUREUiArIDQgKiBudW1Xb3JkKSkgPj4gMjQpICYgMHgwMztcbiAgICB9XG4gICAgYXN5bmMgZ2V0TWFqb3JDaGlwVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbWlub3JSYXcgPSBhd2FpdCB0aGlzLmdldFJhd01pbm9yQ2hpcFZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgaWYgKGF3YWl0IHRoaXMuaXNFY28wKGxvYWRlciwgbWlub3JSYXcpKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5nZXRSYXdNYWpvckNoaXBWZXJzaW9uKGxvYWRlcik7XG4gICAgfVxuICAgIGFzeW5jIGdldEJsa1ZlcnNpb25NYWpvcihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDQ7XG4gICAgICAgIHJldHVybiAoKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRUZVU0VfQkxPQ0syX0FERFIgKyA0ICogbnVtV29yZCkpID4+IDApICYgMHgwMztcbiAgICB9XG4gICAgYXN5bmMgZ2V0QmxrVmVyc2lvbk1pbm9yKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMztcbiAgICAgICAgcmV0dXJuICgoYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5FRlVTRV9CTE9DSzFfQUREUiArIDQgKiBudW1Xb3JkKSkgPj4gMjQpICYgMHgwNztcbiAgICB9XG4gICAgYXN5bmMgaXNFY28wKGxvYWRlciwgbWlub3JSYXcpIHtcbiAgICAgICAgLy8gV29ya2Fyb3VuZDogVGhlIG1ham9yIHZlcnNpb24gZmllbGQgd2FzIGFsbG9jYXRlZCB0byBvdGhlciBwdXJwb3Nlc1xuICAgICAgICAvLyB3aGVuIGJsb2NrIHZlcnNpb24gaXMgdjEuMS5cbiAgICAgICAgLy8gTHVja2lseSBvbmx5IGNoaXAgdjAuMCBoYXZlIHRoaXMga2luZCBvZiBibG9jayB2ZXJzaW9uIGFuZCBlZnVzZSB1c2FnZS5cbiAgICAgICAgcmV0dXJuICgobWlub3JSYXcgJiAweDcpID09PSAwICYmXG4gICAgICAgICAgICAoYXdhaXQgdGhpcy5nZXRCbGtWZXJzaW9uTWFqb3IobG9hZGVyKSkgPT09IDEgJiZcbiAgICAgICAgICAgIChhd2FpdCB0aGlzLmdldEJsa1ZlcnNpb25NaW5vcihsb2FkZXIpKSA9PT0gMSk7XG4gICAgfVxuICAgIGFzeW5jIGdldEZsYXNoQ2FwKGxvYWRlcikge1xuICAgICAgICBjb25zdCBudW1Xb3JkID0gMztcbiAgICAgICAgY29uc3QgYmxvY2sxQWRkciA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICBjb25zdCBhZGRyID0gYmxvY2sxQWRkciArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCByZWdpc3RlclZhbHVlID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgICAgIGNvbnN0IGZsYXNoQ2FwID0gKHJlZ2lzdGVyVmFsdWUgPj4gMjcpICYgMHgwNztcbiAgICAgICAgcmV0dXJuIGZsYXNoQ2FwO1xuICAgIH1cbiAgICBhc3luYyBnZXRGbGFzaFZlbmRvcihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDQ7XG4gICAgICAgIGNvbnN0IGJsb2NrMUFkZHIgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgY29uc3QgYWRkciA9IGJsb2NrMUFkZHIgKyA0ICogbnVtV29yZDtcbiAgICAgICAgY29uc3QgcmVnaXN0ZXJWYWx1ZSA9IGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpO1xuICAgICAgICBjb25zdCB2ZW5kb3JJZCA9IChyZWdpc3RlclZhbHVlID4+IDApICYgMHgwNztcbiAgICAgICAgY29uc3QgdmVuZG9yTWFwID0ge1xuICAgICAgICAgICAgMTogXCJYTUNcIixcbiAgICAgICAgICAgIDI6IFwiR0RcIixcbiAgICAgICAgICAgIDM6IFwiRk1cIixcbiAgICAgICAgICAgIDQ6IFwiVFRcIixcbiAgICAgICAgICAgIDU6IFwiQllcIixcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHZlbmRvck1hcFt2ZW5kb3JJZF0gfHwgXCJcIjtcbiAgICB9XG4gICAgYXN5bmMgZ2V0UHNyYW1DYXAobG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSA0O1xuICAgICAgICBjb25zdCBibG9jazFBZGRyID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIGNvbnN0IGFkZHIgPSBibG9jazFBZGRyICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHJlZ2lzdGVyVmFsdWUgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKTtcbiAgICAgICAgY29uc3QgcHNyYW1DYXAgPSAocmVnaXN0ZXJWYWx1ZSA+PiAzKSAmIDB4MDM7XG4gICAgICAgIHJldHVybiBwc3JhbUNhcDtcbiAgICB9XG4gICAgYXN5bmMgZ2V0UHNyYW1WZW5kb3IobG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSA0O1xuICAgICAgICBjb25zdCBibG9jazFBZGRyID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwNDQ7XG4gICAgICAgIGNvbnN0IGFkZHIgPSBibG9jazFBZGRyICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHJlZ2lzdGVyVmFsdWUgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKTtcbiAgICAgICAgY29uc3QgdmVuZG9ySWQgPSAocmVnaXN0ZXJWYWx1ZSA+PiA3KSAmIDB4MDM7XG4gICAgICAgIGNvbnN0IHZlbmRvck1hcCA9IHtcbiAgICAgICAgICAgIDE6IFwiQVBfM3YzXCIsXG4gICAgICAgICAgICAyOiBcIkFQXzF2OFwiLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdmVuZG9yTWFwW3ZlbmRvcklkXSB8fCBcIlwiO1xuICAgIH1cbiAgICBhc3luYyBnZXRDaGlwRmVhdHVyZXMobG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IGZlYXR1cmVzID0gW1wiV2ktRmlcIiwgXCJCTEVcIl07XG4gICAgICAgIGNvbnN0IGZsYXNoTWFwID0ge1xuICAgICAgICAgICAgMDogbnVsbCxcbiAgICAgICAgICAgIDE6IFwiRW1iZWRkZWQgRmxhc2ggOE1CXCIsXG4gICAgICAgICAgICAyOiBcIkVtYmVkZGVkIEZsYXNoIDRNQlwiLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBmbGFzaENhcCA9IGF3YWl0IHRoaXMuZ2V0Rmxhc2hDYXAobG9hZGVyKTtcbiAgICAgICAgY29uc3QgZmxhc2hWZW5kb3IgPSBhd2FpdCB0aGlzLmdldEZsYXNoVmVuZG9yKGxvYWRlcik7XG4gICAgICAgIGNvbnN0IGZsYXNoID0gZmxhc2hNYXBbZmxhc2hDYXBdO1xuICAgICAgICBjb25zdCBmbGFzaERlc2NyaXB0aW9uID0gZmxhc2ggIT09IHVuZGVmaW5lZCA/IGZsYXNoIDogXCJVbmtub3duIEVtYmVkZGVkIEZsYXNoXCI7XG4gICAgICAgIGlmIChmbGFzaCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgZmVhdHVyZXMucHVzaChgJHtmbGFzaERlc2NyaXB0aW9ufSAoJHtmbGFzaFZlbmRvcn0pYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHNyYW1NYXAgPSB7XG4gICAgICAgICAgICAwOiBudWxsLFxuICAgICAgICAgICAgMTogXCJFbWJlZGRlZCBQU1JBTSA4TUJcIixcbiAgICAgICAgICAgIDI6IFwiRW1iZWRkZWQgUFNSQU0gMk1CXCIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHBzcmFtQ2FwID0gYXdhaXQgdGhpcy5nZXRQc3JhbUNhcChsb2FkZXIpO1xuICAgICAgICBjb25zdCBwc3JhbVZlbmRvciA9IGF3YWl0IHRoaXMuZ2V0UHNyYW1WZW5kb3IobG9hZGVyKTtcbiAgICAgICAgY29uc3QgcHNyYW0gPSBwc3JhbU1hcFtwc3JhbUNhcF07XG4gICAgICAgIGNvbnN0IHBzcmFtRGVzY3JpcHRpb24gPSBwc3JhbSAhPT0gdW5kZWZpbmVkID8gcHNyYW0gOiBcIlVua25vd24gRW1iZWRkZWQgUFNSQU1cIjtcbiAgICAgICAgaWYgKHBzcmFtICE9PSBudWxsKSB7XG4gICAgICAgICAgICBmZWF0dXJlcy5wdXNoKGAke3BzcmFtRGVzY3JpcHRpb259ICgke3BzcmFtVmVuZG9yfSlgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmVhdHVyZXM7XG4gICAgfVxuICAgIGFzeW5jIGdldENyeXN0YWxGcmVxKGxvYWRlcikge1xuICAgICAgICByZXR1cm4gNDA7XG4gICAgfVxuICAgIF9kMmgoZCkge1xuICAgICAgICBjb25zdCBoID0gKCtkKS50b1N0cmluZygxNik7XG4gICAgICAgIHJldHVybiBoLmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgaCA6IGg7XG4gICAgfVxuICAgIGFzeW5jIHBvc3RDb25uZWN0KGxvYWRlcikge1xuICAgICAgICBjb25zdCBidWZObyA9IChhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLlVBUlRERVZfQlVGX05PKSkgJiAweGZmO1xuICAgICAgICBsb2FkZXIuZGVidWcoXCJJbiBfcG9zdF9jb25uZWN0IFwiICsgYnVmTm8pO1xuICAgICAgICBpZiAoYnVmTm8gPT0gdGhpcy5VQVJUREVWX0JVRl9OT19VU0IpIHtcbiAgICAgICAgICAgIGxvYWRlci5FU1BfUkFNX0JMT0NLID0gdGhpcy5VU0JfUkFNX0JMT0NLO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHJlYWRNYWMobG9hZGVyKSB7XG4gICAgICAgIGxldCBtYWMwID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHKTtcbiAgICAgICAgbWFjMCA9IG1hYzAgPj4+IDA7XG4gICAgICAgIGxldCBtYWMxID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcodGhpcy5NQUNfRUZVU0VfUkVHICsgNCk7XG4gICAgICAgIG1hYzEgPSAobWFjMSA+Pj4gMCkgJiAweDAwMDBmZmZmO1xuICAgICAgICBjb25zdCBtYWMgPSBuZXcgVWludDhBcnJheSg2KTtcbiAgICAgICAgbWFjWzBdID0gKG1hYzEgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbMV0gPSBtYWMxICYgMHhmZjtcbiAgICAgICAgbWFjWzJdID0gKG1hYzAgPj4gMjQpICYgMHhmZjtcbiAgICAgICAgbWFjWzNdID0gKG1hYzAgPj4gMTYpICYgMHhmZjtcbiAgICAgICAgbWFjWzRdID0gKG1hYzAgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbNV0gPSBtYWMwICYgMHhmZjtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9kMmgobWFjWzBdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzFdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzJdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzNdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzRdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzVdKSk7XG4gICAgfVxuICAgIGdldEVyYXNlU2l6ZShvZmZzZXQsIHNpemUpIHtcbiAgICAgICAgcmV0dXJuIHNpemU7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_esp8266_js.bundle.js b/docs/node_modules_esptool-js_lib_targets_esp8266_js.bundle.js deleted file mode 100644 index e4515ff..0000000 --- a/docs/node_modules_esptool-js_lib_targets_esp8266_js.bundle.js +++ /dev/null @@ -1,138 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_esp8266_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp8266.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp8266.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP8266ROM: () => (/* binding */ ESP8266ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP8266ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP8266"; - this.CHIP_DETECT_MAGIC_VALUE = [0xfff0c101]; - this.EFUSE_RD_REG_BASE = 0x3ff00050; - this.UART_CLKDIV_REG = 0x60000014; - this.UART_CLKDIV_MASK = 0xfffff; - this.XTAL_CLK_DIVIDER = 2; - this.FLASH_WRITE_SIZE = 0x4000; - // NOT IMPLEMENTED, SETTING EMPTY VALUE - this.BOOTLOADER_FLASH_OFFSET = 0; - this.UART_DATE_REG_ADDR = 0; - this.FLASH_SIZES = { - "512KB": 0x00, - "256KB": 0x10, - "1MB": 0x20, - "2MB": 0x30, - "4MB": 0x40, - "2MB-c1": 0x50, - "4MB-c1": 0x60, - "8MB": 0x80, - "16MB": 0x90, - }; - this.SPI_REG_BASE = 0x60000200; - this.SPI_USR_OFFS = 0x1c; - this.SPI_USR1_OFFS = 0x20; - this.SPI_USR2_OFFS = 0x24; - this.SPI_MOSI_DLEN_OFFS = 0; // not in esp8266 - this.SPI_MISO_DLEN_OFFS = 0; // not in esp8266 - this.SPI_W0_OFFS = 0x40; - this.getChipFeatures = async (loader) => { - const features = ["WiFi"]; - if ((await this.getChipDescription(loader)) == "ESP8285") - features.push("Embedded Flash"); - return features; - }; - } - async readEfuse(loader, offset) { - const addr = this.EFUSE_RD_REG_BASE + 4 * offset; - loader.debug("Read efuse " + addr); - return await loader.readReg(addr); - } - async getChipDescription(loader) { - const efuse3 = await this.readEfuse(loader, 2); - const efuse0 = await this.readEfuse(loader, 0); - const is8285 = ((efuse0 & (1 << 4)) | (efuse3 & (1 << 16))) != 0; // One or the other efuse bit is set for ESP8285 - return is8285 ? "ESP8285" : "ESP8266EX"; - } - async getCrystalFreq(loader) { - const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK; - const etsXtal = (loader.transport.baudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; - let normXtal; - if (etsXtal > 33) { - normXtal = 40; - } - else { - normXtal = 26; - } - if (Math.abs(normXtal - etsXtal) > 1) { - loader.info("WARNING: Detected crystal freq " + - etsXtal + - "MHz is quite different to normalized freq " + - normXtal + - "MHz. Unsupported crystal in use?"); - } - return normXtal; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await this.readEfuse(loader, 0); - mac0 = mac0 >>> 0; - let mac1 = await this.readEfuse(loader, 1); - mac1 = mac1 >>> 0; - let mac3 = await this.readEfuse(loader, 3); - mac3 = mac3 >>> 0; - const mac = new Uint8Array(6); - if (mac3 != 0) { - mac[0] = (mac3 >> 16) & 0xff; - mac[1] = (mac3 >> 8) & 0xff; - mac[2] = mac3 & 0xff; - } - else if (((mac1 >> 16) & 0xff) == 0) { - mac[0] = 0x18; - mac[1] = 0xfe; - mac[2] = 0x34; - } - else if (((mac1 >> 16) & 0xff) == 1) { - mac[0] = 0xac; - mac[1] = 0xd0; - mac[2] = 0x74; - } - else { - loader.error("Unknown OUI"); - } - mac[3] = (mac1 >> 8) & 0xff; - mac[4] = mac1 & 0xff; - mac[5] = (mac0 >> 24) & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZV9tb2R1bGVzX2VzcHRvb2wtanNfbGliX3RhcmdldHNfZXNwODI2Nl9qcy5idW5kbGUuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBK0I7QUFDeEIseUJBQXlCLHdDQUFHO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQyxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRUFBMEU7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3B0b29sLWpzL2xpYi90YXJnZXRzL2VzcDgyNjYuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUk9NIH0gZnJvbSBcIi4vcm9tLmpzXCI7XG5leHBvcnQgY2xhc3MgRVNQODI2NlJPTSBleHRlbmRzIFJPTSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuQ0hJUF9OQU1FID0gXCJFU1A4MjY2XCI7XG4gICAgICAgIHRoaXMuQ0hJUF9ERVRFQ1RfTUFHSUNfVkFMVUUgPSBbMHhmZmYwYzEwMV07XG4gICAgICAgIHRoaXMuRUZVU0VfUkRfUkVHX0JBU0UgPSAweDNmZjAwMDUwO1xuICAgICAgICB0aGlzLlVBUlRfQ0xLRElWX1JFRyA9IDB4NjAwMDAwMTQ7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfTUFTSyA9IDB4ZmZmZmY7XG4gICAgICAgIHRoaXMuWFRBTF9DTEtfRElWSURFUiA9IDI7XG4gICAgICAgIHRoaXMuRkxBU0hfV1JJVEVfU0laRSA9IDB4NDAwMDtcbiAgICAgICAgLy8gTk9UIElNUExFTUVOVEVELCBTRVRUSU5HIEVNUFRZIFZBTFVFXG4gICAgICAgIHRoaXMuQk9PVExPQURFUl9GTEFTSF9PRkZTRVQgPSAwO1xuICAgICAgICB0aGlzLlVBUlRfREFURV9SRUdfQUREUiA9IDA7XG4gICAgICAgIHRoaXMuRkxBU0hfU0laRVMgPSB7XG4gICAgICAgICAgICBcIjUxMktCXCI6IDB4MDAsXG4gICAgICAgICAgICBcIjI1NktCXCI6IDB4MTAsXG4gICAgICAgICAgICBcIjFNQlwiOiAweDIwLFxuICAgICAgICAgICAgXCIyTUJcIjogMHgzMCxcbiAgICAgICAgICAgIFwiNE1CXCI6IDB4NDAsXG4gICAgICAgICAgICBcIjJNQi1jMVwiOiAweDUwLFxuICAgICAgICAgICAgXCI0TUItYzFcIjogMHg2MCxcbiAgICAgICAgICAgIFwiOE1CXCI6IDB4ODAsXG4gICAgICAgICAgICBcIjE2TUJcIjogMHg5MCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5TUElfUkVHX0JBU0UgPSAweDYwMDAwMjAwO1xuICAgICAgICB0aGlzLlNQSV9VU1JfT0ZGUyA9IDB4MWM7XG4gICAgICAgIHRoaXMuU1BJX1VTUjFfT0ZGUyA9IDB4MjA7XG4gICAgICAgIHRoaXMuU1BJX1VTUjJfT0ZGUyA9IDB4MjQ7XG4gICAgICAgIHRoaXMuU1BJX01PU0lfRExFTl9PRkZTID0gMDsgLy8gbm90IGluIGVzcDgyNjZcbiAgICAgICAgdGhpcy5TUElfTUlTT19ETEVOX09GRlMgPSAwOyAvLyBub3QgaW4gZXNwODI2NlxuICAgICAgICB0aGlzLlNQSV9XMF9PRkZTID0gMHg0MDtcbiAgICAgICAgdGhpcy5nZXRDaGlwRmVhdHVyZXMgPSBhc3luYyAobG9hZGVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmZWF0dXJlcyA9IFtcIldpRmlcIl07XG4gICAgICAgICAgICBpZiAoKGF3YWl0IHRoaXMuZ2V0Q2hpcERlc2NyaXB0aW9uKGxvYWRlcikpID09IFwiRVNQODI4NVwiKVxuICAgICAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goXCJFbWJlZGRlZCBGbGFzaFwiKTtcbiAgICAgICAgICAgIHJldHVybiBmZWF0dXJlcztcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgcmVhZEVmdXNlKGxvYWRlciwgb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IGFkZHIgPSB0aGlzLkVGVVNFX1JEX1JFR19CQVNFICsgNCAqIG9mZnNldDtcbiAgICAgICAgbG9hZGVyLmRlYnVnKFwiUmVhZCBlZnVzZSBcIiArIGFkZHIpO1xuICAgICAgICByZXR1cm4gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBEZXNjcmlwdGlvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgZWZ1c2UzID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCAyKTtcbiAgICAgICAgY29uc3QgZWZ1c2UwID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCAwKTtcbiAgICAgICAgY29uc3QgaXM4Mjg1ID0gKChlZnVzZTAgJiAoMSA8PCA0KSkgfCAoZWZ1c2UzICYgKDEgPDwgMTYpKSkgIT0gMDsgLy8gT25lIG9yIHRoZSBvdGhlciBlZnVzZSBiaXQgaXMgc2V0IGZvciBFU1A4Mjg1XG4gICAgICAgIHJldHVybiBpczgyODUgPyBcIkVTUDgyODVcIiA6IFwiRVNQODI2NkVYXCI7XG4gICAgfVxuICAgIGFzeW5jIGdldENyeXN0YWxGcmVxKGxvYWRlcikge1xuICAgICAgICBjb25zdCB1YXJ0RGl2ID0gKGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuVUFSVF9DTEtESVZfUkVHKSkgJiB0aGlzLlVBUlRfQ0xLRElWX01BU0s7XG4gICAgICAgIGNvbnN0IGV0c1h0YWwgPSAobG9hZGVyLnRyYW5zcG9ydC5iYXVkcmF0ZSAqIHVhcnREaXYpIC8gMTAwMDAwMCAvIHRoaXMuWFRBTF9DTEtfRElWSURFUjtcbiAgICAgICAgbGV0IG5vcm1YdGFsO1xuICAgICAgICBpZiAoZXRzWHRhbCA+IDMzKSB7XG4gICAgICAgICAgICBub3JtWHRhbCA9IDQwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbm9ybVh0YWwgPSAyNjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTWF0aC5hYnMobm9ybVh0YWwgLSBldHNYdGFsKSA+IDEpIHtcbiAgICAgICAgICAgIGxvYWRlci5pbmZvKFwiV0FSTklORzogRGV0ZWN0ZWQgY3J5c3RhbCBmcmVxIFwiICtcbiAgICAgICAgICAgICAgICBldHNYdGFsICtcbiAgICAgICAgICAgICAgICBcIk1IeiBpcyBxdWl0ZSBkaWZmZXJlbnQgdG8gbm9ybWFsaXplZCBmcmVxIFwiICtcbiAgICAgICAgICAgICAgICBub3JtWHRhbCArXG4gICAgICAgICAgICAgICAgXCJNSHouIFVuc3VwcG9ydGVkIGNyeXN0YWwgaW4gdXNlP1wiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbm9ybVh0YWw7XG4gICAgfVxuICAgIF9kMmgoZCkge1xuICAgICAgICBjb25zdCBoID0gKCtkKS50b1N0cmluZygxNik7XG4gICAgICAgIHJldHVybiBoLmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgaCA6IGg7XG4gICAgfVxuICAgIGFzeW5jIHJlYWRNYWMobG9hZGVyKSB7XG4gICAgICAgIGxldCBtYWMwID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCAwKTtcbiAgICAgICAgbWFjMCA9IG1hYzAgPj4+IDA7XG4gICAgICAgIGxldCBtYWMxID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCAxKTtcbiAgICAgICAgbWFjMSA9IG1hYzEgPj4+IDA7XG4gICAgICAgIGxldCBtYWMzID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCAzKTtcbiAgICAgICAgbWFjMyA9IG1hYzMgPj4+IDA7XG4gICAgICAgIGNvbnN0IG1hYyA9IG5ldyBVaW50OEFycmF5KDYpO1xuICAgICAgICBpZiAobWFjMyAhPSAwKSB7XG4gICAgICAgICAgICBtYWNbMF0gPSAobWFjMyA+PiAxNikgJiAweGZmO1xuICAgICAgICAgICAgbWFjWzFdID0gKG1hYzMgPj4gOCkgJiAweGZmO1xuICAgICAgICAgICAgbWFjWzJdID0gbWFjMyAmIDB4ZmY7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoKChtYWMxID4+IDE2KSAmIDB4ZmYpID09IDApIHtcbiAgICAgICAgICAgIG1hY1swXSA9IDB4MTg7XG4gICAgICAgICAgICBtYWNbMV0gPSAweGZlO1xuICAgICAgICAgICAgbWFjWzJdID0gMHgzNDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICgoKG1hYzEgPj4gMTYpICYgMHhmZikgPT0gMSkge1xuICAgICAgICAgICAgbWFjWzBdID0gMHhhYztcbiAgICAgICAgICAgIG1hY1sxXSA9IDB4ZDA7XG4gICAgICAgICAgICBtYWNbMl0gPSAweDc0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbG9hZGVyLmVycm9yKFwiVW5rbm93biBPVUlcIik7XG4gICAgICAgIH1cbiAgICAgICAgbWFjWzNdID0gKG1hYzEgPj4gOCkgJiAweGZmO1xuICAgICAgICBtYWNbNF0gPSBtYWMxICYgMHhmZjtcbiAgICAgICAgbWFjWzVdID0gKG1hYzAgPj4gMjQpICYgMHhmZjtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9kMmgobWFjWzBdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzFdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzJdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzNdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzRdKSArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICB0aGlzLl9kMmgobWFjWzVdKSk7XG4gICAgfVxuICAgIGdldEVyYXNlU2l6ZShvZmZzZXQsIHNpemUpIHtcbiAgICAgICAgcmV0dXJuIHNpemU7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32_json.bundle.js deleted file mode 100644 index ca64ed2..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32.json": -/*!*******************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32.json ***! - \*******************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1074521580,"text":"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","text_start":1074520064,"data":"DMD8P+znC0B/6AtAZ+0LQAbpC0Cf6AtABukLQGXpC0CC6gtA9OoLQJ3qC0CV5wtAGuoLQHTqC0CI6QtAGOsLQLDpC0AY6wtAbegLQMroC0AG6QtAZekLQIXoC0DI6wtAKe0LQLjmC0BL7QtAuOYLQLjmC0C45gtAuOYLQLjmC0C45gtAuOYLQLjmC0Bv6wtAuOYLQEnsC0Ap7QtA","data_start":1073605544,"bss_start":1073528832}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c2_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c2_json.bundle.js deleted file mode 100644 index f1a12b9..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c2_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c2_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c2.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c2.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1077413304,"text":"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","text_start":1077411840,"data":"DEDKP+AIOEAsCThAhAk4QFIKOEC+CjhAbAo4QKgHOEAOCjhATgo4QJgJOEBYBzhAzAk4QFgHOEC6CDhA/gg4QCwJOECECThAzAg4QBIIOEBCCDhAyAg4QBYNOEAsCThA1gs4QMoMOECkBjhA9Aw4QKQGOECkBjhApAY4QKQGOECkBjhApAY4QKQGOECkBjhAcgs4QKQGOEDyCzhAygw4QA==","data_start":1070295976,"bss_start":1070219264}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c3_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c3_json.bundle.js deleted file mode 100644 index e0380f9..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c3_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c3_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c3.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c3.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1077413584,"text":"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","text_start":1077411840,"data":"GEDIP8AKOEAQCzhAaAs4QDYMOECiDDhAUAw4QHIJOEDyCzhAMgw4QHwLOEAiCThAsAs4QCIJOECaCjhA4Ao4QBALOEBoCzhArAo4QNYJOEAgCjhAqAo4QPoOOEAQCzhAug04QLIOOEBiCDhA2g44QGIIOEBiCDhAYgg4QGIIOEBiCDhAYgg4QGIIOEBiCDhAVg04QGIIOEDYDThAsg44QA==","data_start":1070164916,"bss_start":1070088192}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c5_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c5_json.bundle.js deleted file mode 100644 index fb66cbd..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c5_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c5_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c5.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c5.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1082132164,"text":"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","text_start":1082130432,"data":"FACEQG4KgEC+CoBAFguAQOQLgEBQDIBA/guAQDoJgECgC4BA4AuAQCoLgEDqCIBAXguAQOoIgEBICoBAjgqAQL4KgEAWC4BAWgqAQJ4JgEDOCYBAVgqAQKgOgEC+CoBAaA2AQGAOgEAqCIBAiA6AQCoIgEAqCIBAKgiAQCoIgEAqCIBAKgiAQCoIgEAqCIBABA2AQCoIgECGDYBAYA6AQA==","data_start":1082469296,"bss_start":1082392576}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c61_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c61_json.bundle.js deleted file mode 100644 index a6f6769..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c61_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c61_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c61.json": -/*!**********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c61.json ***! - \**********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1082132164,"text":"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","text_start":1082130432,"data":"FECAQHQKgEDECoBAHAuAQOoLgEBWDIBABAyAQEAJgECmC4BA5guAQDALgEDwCIBAZAuAQPAIgEBOCoBAlAqAQMQKgEAcC4BAYAqAQKQJgEDUCYBAXAqAQK4OgEDECoBAbg2AQGYOgEAwCIBAjg6AQDAIgEAwCIBAMAiAQDAIgEAwCIBAMAiAQDAIgEAwCIBACg2AQDAIgECMDYBAZg6AQA==","data_start":1082223536,"bss_start":1082146816}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c6_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c6_json.bundle.js deleted file mode 100644 index 210c628..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c6_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c6_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c6.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c6.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1082132164,"text":"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","text_start":1082130432,"data":"FACEQHIKgEDCCoBAGguAQOgLgEBUDIBAAgyAQD4JgECkC4BA5AuAQC4LgEDuCIBAYguAQO4IgEBMCoBAkgqAQMIKgEAaC4BAXgqAQKIJgEDSCYBAWgqAQKwOgEDCCoBAbA2AQGQOgEAuCIBAjA6AQC4IgEAuCIBALgiAQC4IgEAuCIBALgiAQC4IgEAuCIBACA2AQC4IgECKDYBAZA6AQA==","data_start":1082469296,"bss_start":1082392576}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32h2_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32h2_json.bundle.js deleted file mode 100644 index e46b9be..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32h2_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32h2_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32h2.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32h2.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1082132164,"text":"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","text_start":1082130432,"data":"FACDQHIKgEDCCoBAGguAQOgLgEBUDIBAAgyAQD4JgECkC4BA5AuAQC4LgEDuCIBAYguAQO4IgEBMCoBAkgqAQMIKgEAaC4BAXgqAQKIJgEDSCYBAWgqAQKwOgEDCCoBAbA2AQGQOgEAuCIBAjA6AQC4IgEAuCIBALgiAQC4IgEAuCIBALgiAQC4IgEAuCIBACA2AQC4IgECKDYBAZA6AQA==","data_start":1082403760,"bss_start":1082327040}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32p4_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32p4_json.bundle.js deleted file mode 100644 index f6427b6..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32p4_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32p4_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32p4.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32p4.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1341195918,"text":"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","text_start":1341194240,"data":"EAD1TwYK8U9WCvFPrgrxT4QL8U/wC/FPngvxT9QI8U9AC/FPgAvxT8IK8U+ECPFP9grxT4QI8U/gCfFPJgrxT1YK8U+uCvFP8gnxTzgJ8U9oCfFP7gnxT0AO8U9WCvFPCA3xTwAO8U/EB/FPJA7xT8QH8U/EB/FPxAfxT8QH8U/EB/FPxAfxT8QH8U/EB/FPpAzxT8QH8U8mDfFPAA7xTw==","data_start":1341533100,"bss_start":1341456384}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s2_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s2_json.bundle.js deleted file mode 100644 index 8e8a3c0..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s2_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s2_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32s2.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32s2.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1073907716,"text":"CAAAYBwAAGBIAP0/EAAAYDZBACH7/8AgADgCQfr/wCAAKAQgIJSc4kH4/0YEAAw4MIgBwCAAqAiIBKCgdOAIAAsiZgLohvT/IfH/wCAAOQId8AAA7Cv+P2Sr/T+EgAAAQEAAAKTr/T/wK/4/NkEAsfn/IKB0EBEgJQgBlhoGgfb/kqEBkJkRmpjAIAC4CZHz/6CgdJqIwCAAkhgAkJD0G8nAwPTAIADCWACam8AgAKJJAMAgAJIYAIHq/5CQ9ICA9IeZR4Hl/5KhAZCZEZqYwCAAyAmh5f+x4/+HnBfGAQB86Ica3sYIAMAgAIkKwCAAuQlGAgDAIAC5CsAgAIkJkdf/mogMCcAgAJJYAB3wAABUIEA/VDBAPzZBAJH9/8AgAIgJgIAkVkj/kfr/wCAAiAmAgCRWSP8d8AAAACwgQD8AIEA/AAAACDZBABARIKX8/yH6/wwIwCAAgmIAkfr/gfj/wCAAkmgAwCAAmAhWef/AIACIAnzygCIwICAEHfAAAAAAQDZBABARIOX7/xZq/4Hs/5H7/8AgAJJoAMAgAJgIVnn/HfAAAFiA/T////8ABCBAPzZBACH8/zhCFoMGEBEgZfj/FvoFDPgMBDeoDZgigJkQgqABkEiDQEB0EBEgJfr/EBEgJfP/iCIMG0CYEZCrAcwUgKsBse3/sJkQsez/wCAAkmsAkc7/wCAAomkAwCAAqAlWev8cCQwaQJqDkDPAmog5QokiHfAAAHDi+j8IIEA/hGIBQKRiAUA2YQAQESBl7f8x+f+9Aa0Dgfr/4AgATQoMEuzqiAGSogCQiBCJARARIOXx/5Hy/6CiAcAgAIgJoIggwCAAiQm4Aa0Dge7/4AgAoCSDHfAAAP8PAAA2QQCBxf8MGZJIADCcQZkokfv/ORgpODAwtJoiKjMwPEEMAilYOUgQESAl+P8tCowaIqDFHfAAAMxxAUA2QQBBtv9YNFAzYxZjBFgUWlNQXEFGAQAQESDl7P+IRKYYBIgkh6XvEBEgJeX/Fmr/qBTNA70CgfH/4AgAoKB0jEpSoMRSZAVYFDpVWRRYNDBVwFk0HfAA+Pz/P0QA/T9MAP0/ADIBQOwxAUAwMwFANmEAfMitAoeTLTH3/8YFAKgDDBwQsSCB9//gCACBK/+iAQCICOAIAKgDgfP/4AgA5hrcxgoAAABmAyYMA80BDCsyYQCB7v/gCACYAYHo/zeZDagIZhoIMeb/wCAAokMAmQgd8EAA/T8AAP0/jDEBQDZBACH8/4Hc/8gCqAix+v+B+//gCAAMCIkCHfBgLwFANkEAgf7/4AgAggoYDAmCyP4MEoApkx3w+Cv+P/Qr/j8YAEw/jABMP//z//82QQAQESDl/P8WWgSh+P+ICrzYgff/mAi8abH2/3zMwCAAiAuQkBTAiBCQiCDAIACJC4gKsfH/DDpgqhHAIACYC6CIEKHu/6CZEJCIIMAgAIkLHfAoKwFANkEAEBEgZff/vBqR0f+ICRuoqQmR0P8MCoqZIkkAgsjBDBmAqYOggHTMiqKvQKoiIJiTjPkQESAl8v/GAQCtAoHv/+AIAB3wNkEAoqDAEBEg5fr/HfAAADZBAIKgwK0Ch5IRoqDbEBEgZfn/oqDcRgQAAAAAgqDbh5IIEBEgJfj/oqDdEBEgpff/HfA2QQA6MsYCAKICACLCARARIKX7/zeS8B3wAAAAbFIAQIxyAUCMUgBADFMAQDYhIaLREIH6/+AIAEYLAAAADBRARBFAQ2PNBL0BrQKB9f/gCACgoHT8Ws0EELEgotEQgfH/4AgASiJAM8BWA/0iogsQIrAgoiCy0RCB7P/gCACtAhwLEBEgpff/LQOGAAAioGMd8AAAQCsBQDZBABARICXl/4y6gYj/iAiMSBARICXi/wwKgfj/4AgAHfAAAIQyAUC08QBAkDIBQMDxAEA2QQAQESDl4f+smjFc/4ziqAOB9//gCACiogDGBgAAAKKiAIH0/+AIAKgDgfP/4AgARgUAAAAsCoyCgfD/4AgAhgEAAIHs/+AIAB3w8CsBQDZBIWKhB8BmERpmWQYMBWLREK0FUmYaEBEgZfn/DBhAiBFHuAJGRACtBoG1/+AIAIYzAACSpB1Qc8DgmREamUB3Y4kJzQe9ASCiIIGu/+AIAJKkHeCZERqZoKB0iAmMigwIgmYWfQiGFQCSpB3gmREamYkJEBEgpeL/vQetARARICXm/xARIKXh/80HELEgYKYggZ3/4AgAkqQd4JkRGpmICXAigHBVgDe1tJKhB8CZERqZmAmAdcCXtwJG3f+G5/8MCIJGbKKkGxCqoIHM/+AIAFYK/7KiC6IGbBC7sBARICWiAPfqEvZHD7KiDRC7sHq7oksAG3eG8f9867eawWZHCIImGje4Aoe1nCKiCxAisGC2IK0CgX3/4AgAEBEgJdj/rQIcCxARIKXb/xARICXX/wwaEBEgpef/HfAAAP0/T0hBSfwr/j9sgAJASDwBQDyDAkAIAAhgEIACQAwAAGA4QEA///8AACiBQD+MgAAAEEAAAAAs/j8QLP4/fJBAP/+P//+AkEA/hJBAP3iQQD9QAP0/VAD9P1ws/j8UAABg8P//APwr/j9YAP0/cID9P1zyAECI2ABA0PEAQKTxAEDUMgFAWDIBQKDkAEAEcAFAAHUBQIBJAUDoNQFA7DsBQIAAAUCYIAFA7HABQGxxAUAMcQFAhCkBQHh2AUDgdwFAlHYBQAAwAEBoAAFANsEAIcz/DAopoYHm/+AIABARIGW7/xbqBDHz/kHy/sAgACgDUfL+KQTAIAAoBWHs/qKgZCkGYe7+YCIQYqQAYCIgwCAAKQWB2P/gCABIBHzCQCIQDCRAIiDAIAApA4YBAEkCSyLGAQAhsv8xs/8MBDcy7RARIOXB/wxLosEoEBEgZcX/IqEBEBEgpcD/QfH9kCIRKiTAIABJAjGo/yHZ/TJiABARICWy/xY6BiGd/sGd/qgCDCuBn/7gCAAMnDwLDAqBuv/gCACxnv8MDAyagbj/4AgAoqIAgTL/4AgAsZn/qAJSoAGBs//gCACoAoEp/+AIAKgCgbD/4AgAMZP/wCAAKANQIiDAIAApAwYKAACxj//NCgxagab/4AgAMYz/UqEBwCAAKAMsClAiIMAgACkDgRv/4AgAgaH/4AgAIYX/wCAAKALMuhzDMCIQIsL4DBMgo4MMC4Ga/+AIAPF+/wwdDByyoAHioQBA3REAzBGAuwGioACBk//gCAAhef9RCf4qRGLVK8YWAAAAAMAgADIHADAwdBbzBKKiAMAgACJHAIH9/uAIAKKiccCqEYF+/+AIAIGF/+AIAHFo/3zowCAAOAeir/+AMxAQqgHAIAA5B4F+/+AIAIF+/+AIAK0CgX3/4AgAcVD+wCAAKAQWsvkMB8AgADgEDBLAIAB5BCJBHCIDAQwoeYEiQR2CUQ8cN3cSIxxHdxIkZpImIgMDcgMCgCIRcCIgZkIXKCPAIAAoAimBxgIAABwihgAAAAzCIlEPEBEg5aT/sqAIosEcEBEgZaj/cgMDIgMCgHcRIHcgIUD/ICD0d7IaoqDAEBEgJaP/oqDuEBEgpaL/EBEgZaH/Btj/IgMBHEgnODf2IhsG9wAiwi8gIHS2QgJGJgCBMv+AIqAoAqACAAAAIsL+ICB0HCgnuAJG7QCBLP+AIqAoAqACAILCMICAdLZYxIbnACxJDAgioMCXFwKG5QCJgQxyfQitBxARIKWb/60HEBEgJZv/EBEg5Zn/EBEgZZn/DIuiwRwLIhARIOWc/1Yy/YYvAAwSVhc1wsEQvQetB4Eu/+AIAFYaNLKgDKLBEBARIGWa/wauAAAADBJWtzKBJ//gCAAGKwAmhwYMEobGAAAAeCMoMyCHIICAtFa4/hARIGVt/yp3nBqG9/8AoKxBgRz/4AgAVhr9ItLwIKfAzCIGmwAAoID0Vhj+hgQAoKD1icGBFP/gCACIwVbK+oAiwAwYAIgRIKfAJzjhhgMAoKxBgQv/4AgAVvr4ItLwIKfAVqL+RooAAAwIIqDAJocChqgADAgtCMamACa39YZ8AAwSJrcChqAAuDOoI3KgABARICWR/6Ang8abAAwZZrddeEMgqREMCCKgwne6AkaZALhTqCOSYQ4QESAlZ/+Y4QwCoJKDhg0ADBlmtzF4QyCpEQwIIqDCd7oCRo4AKDO4U6gjIHeCmeEQESAlZP8hVv0MCJjhiWIi0it5IqCYgy0JxoEAkVD9DAiiCQAioMaHmgJGgACII3LH8CKgwHeYAShZDAiSoO9GAgCKo6IKGBuIoJkwdyjycgMFggMEgHcRgHcgggMGAIgRcIggcgMHgHcBgHcgcJnAcqDBDAiQJ5PGbABxOP0ioMaSBwCNCRZZGpg3DAgioMiHGQIGZgAoV5JHAEZhAByJDAgMEpcXAgZhAPhz6GPYU8hDuDOoIwwHgbH+4AgAjQqgJ4MGWgAMEiZHAkZVAJGX/oGX/sAgAHgJQCIRgHcQIHcgqCPAIAB5CZGS/gwLwCAAeAmAdxAgdyDAIAB5CZGO/sAgAHgJgHcQIHcgwCAAeQmRiv7AIAB4CYB3ECAnIMAgACkJgZX+4AgABh8AcKA0DAgioMCHGgLGPABwtEGLk30KfPwGDgAAqDmZ4bnBydGBhP7gCACY4bjBKCmIGagJyNGAghAmAg3AIADYCiAsMNAiECCIIMAgAIkKG3eSyRC3N8RGgf9mRwLGf/8MCCKgwIYmAAwSJrcCxiEAIWj+iFN4I4kCIWf+eQIMAgYdALFj/gwI2AsMGnLH8J0ILQjQKoNwmpMgmRAioMaHmWDBXf6NCegMIqDJdz5TcPAUIqDAVq8ELQmGAgAAKpOYaUsimQidCiD+wCqNdzLtFsnY+QyJC0Zh/wAMEmaHFyFN/ogCjBiCoMgMB3kCIUn+eQIMEoAngwwIRgEAAAwIIqD/IKB0gmEMEBEgZWL/iMGAoHQQESClYf8QESBlYP9WArUiAwEcJyc3HvYyAobQ/iLC/SAgdAz3J7cCBs3+cTb+cCKgKAKgAgByoNJ3El9yoNR3kgIGIQDGxf4AAHgzOCMQESAlT/+NClZqsKKiccCqEYnBgTD+4AgAISj+kSn+wCAAKAKIwSC0NcAiEZAiECC7IHC7gq0IMLvCgTb+4AgAoqPogST+4AgARrH+AADYU8hDuDOoIxARIGVs/4as/rIDAyIDAoC7ESC7ILLL8KLDGBARIOU3/8al/gAAIgMDcgMCgCIRcCIggST+4AgAcZD8IsLwiDeAImMWUqeIF4qCgIxBhgIAicEQESAlI/+CIQySJwSmGQSYJ5eo6RARICUb/xZq/6gXzQKywxiBFP7gCACMOjKgxDlXOBcqMzkXODcgI8ApN4EO/uAIAIaI/gAAIgMDggMCcsMYgCIRODWAIiAiwvBWwwn2UgKGJQAioMlGKgAx7P2BbvzoAymR4IjAiUGIJq0Jh7IBDDqZ4anR6cEQESBlGv+o0YHj/ejBqQGh4v3dCL0HwsEk8sEQicGB9f3gCAC4Js0KqJGY4aC7wLkmoCLAuAOqd6hBiMGquwwKuQPAqYOAu8Cg0HTMmuLbgK0N4KmDFuoBrQiJwZnhydEQESDlJf+IwZjhyNGJA0YBAAAADBydDIyyODWMc8A/McAzwJaz9daMACKgxylVhlP+AFaslCg1FlKUIqDIxvr/KCNWopMQESAlTP+ionHAqhGBvP3gCAAQESAlM/+Bzv3gCABGRv4AKDMWMpEQESClSf+io+iBs/3gCAAQESDlMP/gAgAGPv4AEBEgJTD/HfAAADZBAJ0CgqDAKAOHmQ/MMgwShgcADAIpA3zihg8AJhIHJiIYhgMAAACCoNuAKSOHmSoMIikDfPJGCAAAACKg3CeZCgwSKQMtCAYEAAAAgqDdfPKHmQYMEikDIqDbHfAAAA==","text_start":1073905664,"data":"WAD9P0uLAkDdiwJA8pACQGaMAkD+iwJAZowCQMWMAkDejQJAUY4CQPmNAkDVigJAd40CQNCNAkDojAJAdI4CQBCNAkB0jgJAy4sCQCqMAkBmjAJAxYwCQOOLAkAXiwJAN48CQKqQAkDqiQJA0ZACQOqJAkDqiQJA6okCQOqJAkDqiQJA6okCQOqJAkDqiQJA1I4CQOqJAkDJjwJAqpACQA==","data_start":1073622012,"bss_start":1073545216}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s3_json.bundle.js b/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s3_json.bundle.js deleted file mode 100644 index e583e69..0000000 --- a/docs/node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s3_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s3_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32s3.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32s3.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1077381760,"text":"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","text_start":1077379072,"data":"XADKP16ON0AzjzdAR5Q3QL2PN0BTjzdAvY83QB2QN0A6kTdArJE3QFWRN0DpjTdA0JA3QCyRN0BAkDdA0JE3QGiQN0DQkTdAIY83QH6PN0C9jzdAHZA3QDmPN0AqjjdAkJI3QA2UN0AAjTdALZQ3QACNN0AAjTdAAI03QACNN0AAjTdAAI03QACNN0AAjTdAKpI3QACNN0AlkzdADZQ3QAQInwAAAAAAAAAYAQQIBQAAAAAAAAAIAQQIBgAAAAAAAAAAAQQIIQAAAAAAIAAAEQQI3AAAAAAAIAAAEQQIDAAAAAAAIAAAAQQIEgAAAAAAIAAAESAoDAAQAQAA","data_start":1070279676,"bss_start":1070202880}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/docs/vendors-node_modules_esp-web-tools_dist_components_ew-dialog_js-node_modules_esp-web-tools_di-de8f3a.bundle.js b/docs/vendors-node_modules_esp-web-tools_dist_components_ew-dialog_js-node_modules_esp-web-tools_di-de8f3a.bundle.js deleted file mode 100644 index 4fc6bf8..0000000 --- a/docs/vendors-node_modules_esp-web-tools_dist_components_ew-dialog_js-node_modules_esp-web-tools_di-de8f3a.bundle.js +++ /dev/null @@ -1,7367 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["vendors-node_modules_esp-web-tools_dist_components_ew-dialog_js-node_modules_esp-web-tools_di-de8f3a"],{ - -/***/ "./node_modules/@lit/reactive-element/development/css-tag.js": -/*!*******************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/css-tag.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ CSSResult: () => (/* binding */ CSSResult), -/* harmony export */ adoptStyles: () => (/* binding */ adoptStyles), -/* harmony export */ css: () => (/* binding */ css), -/* harmony export */ getCompatibleStyle: () => (/* binding */ getCompatibleStyle), -/* harmony export */ supportsAdoptingStyleSheets: () => (/* binding */ supportsAdoptingStyleSheets), -/* harmony export */ unsafeCSS: () => (/* binding */ unsafeCSS) -/* harmony export */ }); -/** - * @license - * Copyright 2019 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -const NODE_MODE = false; -// Allows minifiers to rename references to globalThis -const global = globalThis; -/** - * Whether the current browser supports `adoptedStyleSheets`. - */ -const supportsAdoptingStyleSheets = global.ShadowRoot && - (global.ShadyCSS === undefined || global.ShadyCSS.nativeShadow) && - 'adoptedStyleSheets' in Document.prototype && - 'replace' in CSSStyleSheet.prototype; -const constructionToken = Symbol(); -const cssTagCache = new WeakMap(); -/** - * A container for a string of CSS text, that may be used to create a CSSStyleSheet. - * - * CSSResult is the return value of `css`-tagged template literals and - * `unsafeCSS()`. In order to ensure that CSSResults are only created via the - * `css` tag and `unsafeCSS()`, CSSResult cannot be constructed directly. - */ -class CSSResult { - constructor(cssText, strings, safeToken) { - // This property needs to remain unminified. - this['_$cssResult$'] = true; - if (safeToken !== constructionToken) { - throw new Error('CSSResult is not constructable. Use `unsafeCSS` or `css` instead.'); - } - this.cssText = cssText; - this._strings = strings; - } - // This is a getter so that it's lazy. In practice, this means stylesheets - // are not created until the first element instance is made. - get styleSheet() { - // If `supportsAdoptingStyleSheets` is true then we assume CSSStyleSheet is - // constructable. - let styleSheet = this._styleSheet; - const strings = this._strings; - if (supportsAdoptingStyleSheets && styleSheet === undefined) { - const cacheable = strings !== undefined && strings.length === 1; - if (cacheable) { - styleSheet = cssTagCache.get(strings); - } - if (styleSheet === undefined) { - (this._styleSheet = styleSheet = new CSSStyleSheet()).replaceSync(this.cssText); - if (cacheable) { - cssTagCache.set(strings, styleSheet); - } - } - } - return styleSheet; - } - toString() { - return this.cssText; - } -} -const textFromCSSResult = (value) => { - // This property needs to remain unminified. - if (value['_$cssResult$'] === true) { - return value.cssText; - } - else if (typeof value === 'number') { - return value; - } - else { - throw new Error(`Value passed to 'css' function must be a 'css' function result: ` + - `${value}. Use 'unsafeCSS' to pass non-literal values, but take care ` + - `to ensure page security.`); - } -}; -/** - * Wrap a value for interpolation in a {@linkcode css} tagged template literal. - * - * This is unsafe because untrusted CSS text can be used to phone home - * or exfiltrate data to an attacker controlled site. Take care to only use - * this with trusted input. - */ -const unsafeCSS = (value) => new CSSResult(typeof value === 'string' ? value : String(value), undefined, constructionToken); -/** - * A template literal tag which can be used with LitElement's - * {@linkcode LitElement.styles} property to set element styles. - * - * For security reasons, only literal string values and number may be used in - * embedded expressions. To incorporate non-literal values {@linkcode unsafeCSS} - * may be used inside an expression. - */ -const css = (strings, ...values) => { - const cssText = strings.length === 1 - ? strings[0] - : values.reduce((acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1], strings[0]); - return new CSSResult(cssText, strings, constructionToken); -}; -/** - * Applies the given styles to a `shadowRoot`. When Shadow DOM is - * available but `adoptedStyleSheets` is not, styles are appended to the - * `shadowRoot` to [mimic the native feature](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/adoptedStyleSheets). - * Note, when shimming is used, any styles that are subsequently placed into - * the shadowRoot should be placed *before* any shimmed adopted styles. This - * will match spec behavior that gives adopted sheets precedence over styles in - * shadowRoot. - */ -const adoptStyles = (renderRoot, styles) => { - if (supportsAdoptingStyleSheets) { - renderRoot.adoptedStyleSheets = styles.map((s) => s instanceof CSSStyleSheet ? s : s.styleSheet); - } - else { - for (const s of styles) { - const style = document.createElement('style'); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const nonce = global['litNonce']; - if (nonce !== undefined) { - style.setAttribute('nonce', nonce); - } - style.textContent = s.cssText; - renderRoot.appendChild(style); - } - } -}; -const cssResultFromStyleSheet = (sheet) => { - let cssText = ''; - for (const rule of sheet.cssRules) { - cssText += rule.cssText; - } - return unsafeCSS(cssText); -}; -const getCompatibleStyle = supportsAdoptingStyleSheets || - (NODE_MODE && global.CSSStyleSheet === undefined) - ? (s) => s - : (s) => s instanceof CSSStyleSheet ? cssResultFromStyleSheet(s) : s; -//# sourceMappingURL=css-tag.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/base.js": -/*!***************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/base.js ***! - \***************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ desc: () => (/* binding */ desc) -/* harmony export */ }); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/** - * Wraps up a few best practices when returning a property descriptor from a - * decorator. - * - * Marks the defined property as configurable, and enumerable, and handles - * the case where we have a busted Reflect.decorate zombiefill (e.g. in Angular - * apps). - * - * @internal - */ -const desc = (obj, name, descriptor) => { - // For backwards compatibility, we keep them configurable and enumerable. - descriptor.configurable = true; - descriptor.enumerable = true; - if ( - // We check for Reflect.decorate each time, in case the zombiefill - // is applied via lazy loading some Angular code. - Reflect.decorate && - typeof name !== 'object') { - // If we're called as a legacy decorator, and Reflect.decorate is present - // then we have no guarantees that the returned descriptor will be - // defined on the class, so we must apply it directly ourselves. - Object.defineProperty(obj, name, descriptor); - } - return descriptor; -}; -//# sourceMappingURL=base.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/custom-element.js": -/*!*************************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/custom-element.js ***! - \*************************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ customElement: () => (/* binding */ customElement) -/* harmony export */ }); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/** - * Class decorator factory that defines the decorated class as a custom element. - * - * ```js - * @customElement('my-element') - * class MyElement extends LitElement { - * render() { - * return html``; - * } - * } - * ``` - * @category Decorator - * @param tagName The tag name of the custom element to define. - */ -const customElement = (tagName) => (classOrTarget, context) => { - if (context !== undefined) { - context.addInitializer(() => { - customElements.define(tagName, classOrTarget); - }); - } - else { - customElements.define(tagName, classOrTarget); - } -}; -//# sourceMappingURL=custom-element.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/event-options.js": -/*!************************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/event-options.js ***! - \************************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ eventOptions: () => (/* binding */ eventOptions) -/* harmony export */ }); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/** - * Adds event listener options to a method used as an event listener in a - * lit-html template. - * - * @param options An object that specifies event listener options as accepted by - * `EventTarget#addEventListener` and `EventTarget#removeEventListener`. - * - * Current browsers support the `capture`, `passive`, and `once` options. See: - * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters - * - * ```ts - * class MyElement { - * clicked = false; - * - * render() { - * return html` - *
    - * - *
    - * `; - * } - * - * @eventOptions({capture: true}) - * _onClick(e) { - * this.clicked = true; - * } - * } - * ``` - * @category Decorator - */ -function eventOptions(options) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return ((protoOrValue, nameOrContext) => { - const method = typeof protoOrValue === 'function' - ? protoOrValue - : protoOrValue[nameOrContext]; - Object.assign(method, options); - }); -} -//# sourceMappingURL=event-options.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/property.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/property.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ property: () => (/* binding */ property), -/* harmony export */ standardProperty: () => (/* binding */ standardProperty) -/* harmony export */ }); -/* harmony import */ var _reactive_element_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../reactive-element.js */ "./node_modules/@lit/reactive-element/development/reactive-element.js"); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/* - * IMPORTANT: For compatibility with tsickle and the Closure JS compiler, all - * property decorators (but not class decorators) in this file that have - * an @ExportDecoratedItems annotation must be defined as a regular function, - * not an arrow function. - */ - -const DEV_MODE = true; -let issueWarning; -if (DEV_MODE) { - // Ensure warnings are issued only 1x, even if multiple versions of Lit - // are loaded. - globalThis.litIssuedWarnings ??= new Set(); - /** - * Issue a warning if we haven't already, based either on `code` or `warning`. - * Warnings are disabled automatically only by `warning`; disabling via `code` - * can be done by users. - */ - issueWarning = (code, warning) => { - warning += ` See https://lit.dev/msg/${code} for more information.`; - if (!globalThis.litIssuedWarnings.has(warning) && - !globalThis.litIssuedWarnings.has(code)) { - console.warn(warning); - globalThis.litIssuedWarnings.add(warning); - } - }; -} -const legacyProperty = (options, proto, name) => { - const hasOwnProperty = proto.hasOwnProperty(name); - proto.constructor.createProperty(name, options); - // For accessors (which have a descriptor on the prototype) we need to - // return a descriptor, otherwise TypeScript overwrites the descriptor we - // define in createProperty() with the original descriptor. We don't do this - // for fields, which don't have a descriptor, because this could overwrite - // descriptor defined by other decorators. - return hasOwnProperty - ? Object.getOwnPropertyDescriptor(proto, name) - : undefined; -}; -// This is duplicated from a similar variable in reactive-element.ts, but -// actually makes sense to have this default defined with the decorator, so -// that different decorators could have different defaults. -const defaultPropertyDeclaration = { - attribute: true, - type: String, - converter: _reactive_element_js__WEBPACK_IMPORTED_MODULE_0__.defaultConverter, - reflect: false, - hasChanged: _reactive_element_js__WEBPACK_IMPORTED_MODULE_0__.notEqual, -}; -/** - * Wraps a class accessor or setter so that `requestUpdate()` is called with the - * property name and old value when the accessor is set. - */ -const standardProperty = (options = defaultPropertyDeclaration, target, context) => { - const { kind, metadata } = context; - if (DEV_MODE && metadata == null) { - issueWarning('missing-class-metadata', `The class ${target} is missing decorator metadata. This ` + - `could mean that you're using a compiler that supports decorators ` + - `but doesn't support decorator metadata, such as TypeScript 5.1. ` + - `Please update your compiler.`); - } - // Store the property options - let properties = globalThis.litPropertyMetadata.get(metadata); - if (properties === undefined) { - globalThis.litPropertyMetadata.set(metadata, (properties = new Map())); - } - if (kind === 'setter') { - options = Object.create(options); - options.wrapped = true; - } - properties.set(context.name, options); - if (kind === 'accessor') { - // Standard decorators cannot dynamically modify the class, so we can't - // replace a field with accessors. The user must use the new `accessor` - // keyword instead. - const { name } = context; - return { - set(v) { - const oldValue = target.get.call(this); - target.set.call(this, v); - this.requestUpdate(name, oldValue, options); - }, - init(v) { - if (v !== undefined) { - this._$changeProperty(name, undefined, options, v); - } - return v; - }, - }; - } - else if (kind === 'setter') { - const { name } = context; - return function (value) { - const oldValue = this[name]; - target.call(this, value); - this.requestUpdate(name, oldValue, options); - }; - } - throw new Error(`Unsupported decorator location: ${kind}`); -}; -/** - * A class field or accessor decorator which creates a reactive property that - * reflects a corresponding attribute value. When a decorated property is set - * the element will update and render. A {@linkcode PropertyDeclaration} may - * optionally be supplied to configure property features. - * - * This decorator should only be used for public fields. As public fields, - * properties should be considered as primarily settable by element users, - * either via attribute or the property itself. - * - * Generally, properties that are changed by the element should be private or - * protected fields and should use the {@linkcode state} decorator. - * - * However, sometimes element code does need to set a public property. This - * should typically only be done in response to user interaction, and an event - * should be fired informing the user; for example, a checkbox sets its - * `checked` property when clicked and fires a `changed` event. Mutating public - * properties should typically not be done for non-primitive (object or array) - * properties. In other cases when an element needs to manage state, a private - * property decorated via the {@linkcode state} decorator should be used. When - * needed, state properties can be initialized via public properties to - * facilitate complex interactions. - * - * ```ts - * class MyElement { - * @property({ type: Boolean }) - * clicked = false; - * } - * ``` - * @category Decorator - * @ExportDecoratedItems - */ -function property(options) { - return (protoOrTarget, nameOrContext - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ) => { - return (typeof nameOrContext === 'object' - ? standardProperty(options, protoOrTarget, nameOrContext) - : legacyProperty(options, protoOrTarget, nameOrContext)); - }; -} -//# sourceMappingURL=property.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/query-all.js": -/*!********************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/query-all.js ***! - \********************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ queryAll: () => (/* binding */ queryAll) -/* harmony export */ }); -/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base.js */ "./node_modules/@lit/reactive-element/development/decorators/base.js"); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Shared fragment used to generate empty NodeLists when a render root is -// undefined -let fragment; -/** - * A property decorator that converts a class property into a getter - * that executes a querySelectorAll on the element's renderRoot. - * - * @param selector A DOMString containing one or more selectors to match. - * - * See: - * https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll - * - * ```ts - * class MyElement { - * @queryAll('div') - * divs: NodeListOf; - * - * render() { - * return html` - *
    - *
    - * `; - * } - * } - * ``` - * @category Decorator - */ -function queryAll(selector) { - return ((obj, name) => { - return (0,_base_js__WEBPACK_IMPORTED_MODULE_0__.desc)(obj, name, { - get() { - const container = this.renderRoot ?? (fragment ??= document.createDocumentFragment()); - return container.querySelectorAll(selector); - }, - }); - }); -} -//# sourceMappingURL=query-all.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/query-assigned-elements.js": -/*!**********************************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/query-assigned-elements.js ***! - \**********************************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ queryAssignedElements: () => (/* binding */ queryAssignedElements) -/* harmony export */ }); -/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base.js */ "./node_modules/@lit/reactive-element/development/decorators/base.js"); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * A property decorator that converts a class property into a getter that - * returns the `assignedElements` of the given `slot`. Provides a declarative - * way to use - * [`HTMLSlotElement.assignedElements`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedElements). - * - * Can be passed an optional {@linkcode QueryAssignedElementsOptions} object. - * - * Example usage: - * ```ts - * class MyElement { - * @queryAssignedElements({ slot: 'list' }) - * listItems!: Array; - * @queryAssignedElements() - * unnamedSlotEls!: Array; - * - * render() { - * return html` - * - * - * `; - * } - * } - * ``` - * - * Note, the type of this property should be annotated as `Array`. - * - * @category Decorator - */ -function queryAssignedElements(options) { - return ((obj, name) => { - const { slot, selector } = options ?? {}; - const slotSelector = `slot${slot ? `[name=${slot}]` : ':not([name])'}`; - return (0,_base_js__WEBPACK_IMPORTED_MODULE_0__.desc)(obj, name, { - get() { - const slotEl = this.renderRoot?.querySelector(slotSelector); - const elements = slotEl?.assignedElements(options) ?? []; - return (selector === undefined - ? elements - : elements.filter((node) => node.matches(selector))); - }, - }); - }); -} -//# sourceMappingURL=query-assigned-elements.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/query-assigned-nodes.js": -/*!*******************************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/query-assigned-nodes.js ***! - \*******************************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ queryAssignedNodes: () => (/* binding */ queryAssignedNodes) -/* harmony export */ }); -/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base.js */ "./node_modules/@lit/reactive-element/development/decorators/base.js"); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * A property decorator that converts a class property into a getter that - * returns the `assignedNodes` of the given `slot`. - * - * Can be passed an optional {@linkcode QueryAssignedNodesOptions} object. - * - * Example usage: - * ```ts - * class MyElement { - * @queryAssignedNodes({slot: 'list', flatten: true}) - * listItems!: Array; - * - * render() { - * return html` - * - * `; - * } - * } - * ``` - * - * Note the type of this property should be annotated as `Array`. Use the - * queryAssignedElements decorator to list only elements, and optionally filter - * the element list using a CSS selector. - * - * @category Decorator - */ -function queryAssignedNodes(options) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return ((obj, name) => { - const { slot } = options ?? {}; - const slotSelector = `slot${slot ? `[name=${slot}]` : ':not([name])'}`; - return (0,_base_js__WEBPACK_IMPORTED_MODULE_0__.desc)(obj, name, { - get() { - const slotEl = this.renderRoot?.querySelector(slotSelector); - return (slotEl?.assignedNodes(options) ?? []); - }, - }); - }); -} -//# sourceMappingURL=query-assigned-nodes.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/query-async.js": -/*!**********************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/query-async.js ***! - \**********************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ queryAsync: () => (/* binding */ queryAsync) -/* harmony export */ }); -/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base.js */ "./node_modules/@lit/reactive-element/development/decorators/base.js"); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -// Note, in the future, we may extend this decorator to support the use case -// where the queried element may need to do work to become ready to interact -// with (e.g. load some implementation code). If so, we might elect to -// add a second argument defining a function that can be run to make the -// queried element loaded/updated/ready. -/** - * A property decorator that converts a class property into a getter that - * returns a promise that resolves to the result of a querySelector on the - * element's renderRoot done after the element's `updateComplete` promise - * resolves. When the queried property may change with element state, this - * decorator can be used instead of requiring users to await the - * `updateComplete` before accessing the property. - * - * @param selector A DOMString containing one or more selectors to match. - * - * See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector - * - * ```ts - * class MyElement { - * @queryAsync('#first') - * first: Promise; - * - * render() { - * return html` - *
    - *
    - * `; - * } - * } - * - * // external usage - * async doSomethingWithFirst() { - * (await aMyElement.first).doSomething(); - * } - * ``` - * @category Decorator - */ -function queryAsync(selector) { - return ((obj, name) => { - return (0,_base_js__WEBPACK_IMPORTED_MODULE_0__.desc)(obj, name, { - async get() { - await this.updateComplete; - return this.renderRoot?.querySelector(selector) ?? null; - }, - }); - }); -} -//# sourceMappingURL=query-async.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/query.js": -/*!****************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/query.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ query: () => (/* binding */ query) -/* harmony export */ }); -/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base.js */ "./node_modules/@lit/reactive-element/development/decorators/base.js"); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -const DEV_MODE = true; -let issueWarning; -if (DEV_MODE) { - // Ensure warnings are issued only 1x, even if multiple versions of Lit - // are loaded. - globalThis.litIssuedWarnings ??= new Set(); - /** - * Issue a warning if we haven't already, based either on `code` or `warning`. - * Warnings are disabled automatically only by `warning`; disabling via `code` - * can be done by users. - */ - issueWarning = (code, warning) => { - warning += code - ? ` See https://lit.dev/msg/${code} for more information.` - : ''; - if (!globalThis.litIssuedWarnings.has(warning) && - !globalThis.litIssuedWarnings.has(code)) { - console.warn(warning); - globalThis.litIssuedWarnings.add(warning); - } - }; -} -/** - * A property decorator that converts a class property into a getter that - * executes a querySelector on the element's renderRoot. - * - * @param selector A DOMString containing one or more selectors to match. - * @param cache An optional boolean which when true performs the DOM query only - * once and caches the result. - * - * See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector - * - * ```ts - * class MyElement { - * @query('#first') - * first: HTMLDivElement; - * - * render() { - * return html` - *
    - *
    - * `; - * } - * } - * ``` - * @category Decorator - */ -function query(selector, cache) { - return ((protoOrTarget, nameOrContext, descriptor) => { - const doQuery = (el) => { - const result = (el.renderRoot?.querySelector(selector) ?? null); - if (DEV_MODE && result === null && cache && !el.hasUpdated) { - const name = typeof nameOrContext === 'object' - ? nameOrContext.name - : nameOrContext; - issueWarning('', `@query'd field ${JSON.stringify(String(name))} with the 'cache' ` + - `flag set for selector '${selector}' has been accessed before ` + - `the first update and returned null. This is expected if the ` + - `renderRoot tree has not been provided beforehand (e.g. via ` + - `Declarative Shadow DOM). Therefore the value hasn't been cached.`); - } - // TODO: if we want to allow users to assert that the query will never - // return null, we need a new option and to throw here if the result - // is null. - return result; - }; - if (cache) { - // Accessors to wrap from either: - // 1. The decorator target, in the case of standard decorators - // 2. The property descriptor, in the case of experimental decorators - // on auto-accessors. - // 3. Functions that access our own cache-key property on the instance, - // in the case of experimental decorators on fields. - const { get, set } = typeof nameOrContext === 'object' - ? protoOrTarget - : descriptor ?? - (() => { - const key = DEV_MODE - ? Symbol(`${String(nameOrContext)} (@query() cache)`) - : Symbol(); - return { - get() { - return this[key]; - }, - set(v) { - this[key] = v; - }, - }; - })(); - return (0,_base_js__WEBPACK_IMPORTED_MODULE_0__.desc)(protoOrTarget, nameOrContext, { - get() { - let result = get.call(this); - if (result === undefined) { - result = doQuery(this); - if (result !== null || this.hasUpdated) { - set.call(this, result); - } - } - return result; - }, - }); - } - else { - // This object works as the return type for both standard and - // experimental decorators. - return (0,_base_js__WEBPACK_IMPORTED_MODULE_0__.desc)(protoOrTarget, nameOrContext, { - get() { - return doQuery(this); - }, - }); - } - }); -} -//# sourceMappingURL=query.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/decorators/state.js": -/*!****************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/decorators/state.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ state: () => (/* binding */ state) -/* harmony export */ }); -/* harmony import */ var _property_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./property.js */ "./node_modules/@lit/reactive-element/development/decorators/property.js"); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/* - * IMPORTANT: For compatibility with tsickle and the Closure JS compiler, all - * property decorators (but not class decorators) in this file that have - * an @ExportDecoratedItems annotation must be defined as a regular function, - * not an arrow function. - */ - -/** - * Declares a private or protected reactive property that still triggers - * updates to the element when it changes. It does not reflect from the - * corresponding attribute. - * - * Properties declared this way must not be used from HTML or HTML templating - * systems, they're solely for properties internal to the element. These - * properties may be renamed by optimization tools like closure compiler. - * @category Decorator - */ -function state(options) { - return (0,_property_js__WEBPACK_IMPORTED_MODULE_0__.property)({ - ...options, - // Add both `state` and `attribute` because we found a third party - // controller that is keying off of PropertyOptions.state to determine - // whether a field is a private internal property or not. - state: true, - attribute: false, - }); -} -//# sourceMappingURL=state.js.map - -/***/ }), - -/***/ "./node_modules/@lit/reactive-element/development/reactive-element.js": -/*!****************************************************************************!*\ - !*** ./node_modules/@lit/reactive-element/development/reactive-element.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ CSSResult: () => (/* reexport safe */ _css_tag_js__WEBPACK_IMPORTED_MODULE_0__.CSSResult), -/* harmony export */ ReactiveElement: () => (/* binding */ ReactiveElement), -/* harmony export */ adoptStyles: () => (/* reexport safe */ _css_tag_js__WEBPACK_IMPORTED_MODULE_0__.adoptStyles), -/* harmony export */ css: () => (/* reexport safe */ _css_tag_js__WEBPACK_IMPORTED_MODULE_0__.css), -/* harmony export */ defaultConverter: () => (/* binding */ defaultConverter), -/* harmony export */ getCompatibleStyle: () => (/* reexport safe */ _css_tag_js__WEBPACK_IMPORTED_MODULE_0__.getCompatibleStyle), -/* harmony export */ notEqual: () => (/* binding */ notEqual), -/* harmony export */ supportsAdoptingStyleSheets: () => (/* reexport safe */ _css_tag_js__WEBPACK_IMPORTED_MODULE_0__.supportsAdoptingStyleSheets), -/* harmony export */ unsafeCSS: () => (/* reexport safe */ _css_tag_js__WEBPACK_IMPORTED_MODULE_0__.unsafeCSS) -/* harmony export */ }); -/* harmony import */ var _css_tag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./css-tag.js */ "./node_modules/@lit/reactive-element/development/css-tag.js"); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/** - * Use this module if you want to create your own base class extending - * {@link ReactiveElement}. - * @packageDocumentation - */ - -// In the Node build, this import will be injected by Rollup: -// import {HTMLElement, customElements} from '@lit-labs/ssr-dom-shim'; - -// TODO (justinfagnani): Add `hasOwn` here when we ship ES2022 -const { is, defineProperty, getOwnPropertyDescriptor, getOwnPropertyNames, getOwnPropertySymbols, getPrototypeOf, } = Object; -const NODE_MODE = false; -// Lets a minifier replace globalThis references with a minified name -const global = globalThis; -if (NODE_MODE) { - global.customElements ??= customElements; -} -const DEV_MODE = true; -let issueWarning; -const trustedTypes = global - .trustedTypes; -// Temporary workaround for https://crbug.com/993268 -// Currently, any attribute starting with "on" is considered to be a -// TrustedScript source. Such boolean attributes must be set to the equivalent -// trusted emptyScript value. -const emptyStringForBooleanAttribute = trustedTypes - ? trustedTypes.emptyScript - : ''; -const polyfillSupport = DEV_MODE - ? global.reactiveElementPolyfillSupportDevMode - : global.reactiveElementPolyfillSupport; -if (DEV_MODE) { - // Ensure warnings are issued only 1x, even if multiple versions of Lit - // are loaded. - global.litIssuedWarnings ??= new Set(); - /** - * Issue a warning if we haven't already, based either on `code` or `warning`. - * Warnings are disabled automatically only by `warning`; disabling via `code` - * can be done by users. - */ - issueWarning = (code, warning) => { - warning += ` See https://lit.dev/msg/${code} for more information.`; - if (!global.litIssuedWarnings.has(warning) && - !global.litIssuedWarnings.has(code)) { - console.warn(warning); - global.litIssuedWarnings.add(warning); - } - }; - queueMicrotask(() => { - issueWarning('dev-mode', `Lit is in dev mode. Not recommended for production!`); - // Issue polyfill support warning. - if (global.ShadyDOM?.inUse && polyfillSupport === undefined) { - issueWarning('polyfill-support-missing', `Shadow DOM is being polyfilled via \`ShadyDOM\` but ` + - `the \`polyfill-support\` module has not been loaded.`); - } - }); -} -/** - * Useful for visualizing and logging insights into what the Lit template system is doing. - * - * Compiled out of prod mode builds. - */ -const debugLogEvent = DEV_MODE - ? (event) => { - const shouldEmit = global - .emitLitDebugLogEvents; - if (!shouldEmit) { - return; - } - global.dispatchEvent(new CustomEvent('lit-debug', { - detail: event, - })); - } - : undefined; -/* - * When using Closure Compiler, JSCompiler_renameProperty(property, object) is - * replaced at compile time by the munged name for object[property]. We cannot - * alias this function, so we have to use a small shim that has the same - * behavior when not compiling. - */ -/*@__INLINE__*/ -const JSCompiler_renameProperty = (prop, _obj) => prop; -const defaultConverter = { - toAttribute(value, type) { - switch (type) { - case Boolean: - value = value ? emptyStringForBooleanAttribute : null; - break; - case Object: - case Array: - // if the value is `null` or `undefined` pass this through - // to allow removing/no change behavior. - value = value == null ? value : JSON.stringify(value); - break; - } - return value; - }, - fromAttribute(value, type) { - let fromValue = value; - switch (type) { - case Boolean: - fromValue = value !== null; - break; - case Number: - fromValue = value === null ? null : Number(value); - break; - case Object: - case Array: - // Do *not* generate exception when invalid JSON is set as elements - // don't normally complain on being mis-configured. - // TODO(sorvell): Do generate exception in *dev mode*. - try { - // Assert to adhere to Bazel's "must type assert JSON parse" rule. - fromValue = JSON.parse(value); - } - catch (e) { - fromValue = null; - } - break; - } - return fromValue; - }, -}; -/** - * Change function that returns true if `value` is different from `oldValue`. - * This method is used as the default for a property's `hasChanged` function. - */ -const notEqual = (value, old) => !is(value, old); -const defaultPropertyDeclaration = { - attribute: true, - type: String, - converter: defaultConverter, - reflect: false, - useDefault: false, - hasChanged: notEqual, -}; -// Ensure metadata is enabled. TypeScript does not polyfill -// Symbol.metadata, so we must ensure that it exists. -Symbol.metadata ??= Symbol('metadata'); -// Map from a class's metadata object to property options -// Note that we must use nullish-coalescing assignment so that we only use one -// map even if we load multiple version of this module. -global.litPropertyMetadata ??= new WeakMap(); -/** - * Base element class which manages element properties and attributes. When - * properties change, the `update` method is asynchronously called. This method - * should be supplied by subclasses to render updates as desired. - * @noInheritDoc - */ -class ReactiveElement -// In the Node build, this `extends` clause will be substituted with -// `(globalThis.HTMLElement ?? HTMLElement)`. -// -// This way, we will first prefer any global `HTMLElement` polyfill that the -// user has assigned, and then fall back to the `HTMLElement` shim which has -// been imported (see note at the top of this file about how this import is -// generated by Rollup). Note that the `HTMLElement` variable has been -// shadowed by this import, so it no longer refers to the global. - extends HTMLElement { - /** - * Adds an initializer function to the class that is called during instance - * construction. - * - * This is useful for code that runs against a `ReactiveElement` - * subclass, such as a decorator, that needs to do work for each - * instance, such as setting up a `ReactiveController`. - * - * ```ts - * const myDecorator = (target: typeof ReactiveElement, key: string) => { - * target.addInitializer((instance: ReactiveElement) => { - * // This is run during construction of the element - * new MyController(instance); - * }); - * } - * ``` - * - * Decorating a field will then cause each instance to run an initializer - * that adds a controller: - * - * ```ts - * class MyElement extends LitElement { - * @myDecorator foo; - * } - * ``` - * - * Initializers are stored per-constructor. Adding an initializer to a - * subclass does not add it to a superclass. Since initializers are run in - * constructors, initializers will run in order of the class hierarchy, - * starting with superclasses and progressing to the instance's class. - * - * @nocollapse - */ - static addInitializer(initializer) { - this.__prepare(); - (this._initializers ??= []).push(initializer); - } - /** - * Returns a list of attributes corresponding to the registered properties. - * @nocollapse - * @category attributes - */ - static get observedAttributes() { - // Ensure we've created all properties - this.finalize(); - // this.__attributeToPropertyMap is only undefined after finalize() in - // ReactiveElement itself. ReactiveElement.observedAttributes is only - // accessed with ReactiveElement as the receiver when a subclass or mixin - // calls super.observedAttributes - return (this.__attributeToPropertyMap && [...this.__attributeToPropertyMap.keys()]); - } - /** - * Creates a property accessor on the element prototype if one does not exist - * and stores a {@linkcode PropertyDeclaration} for the property with the - * given options. The property setter calls the property's `hasChanged` - * property option or uses a strict identity check to determine whether or not - * to request an update. - * - * This method may be overridden to customize properties; however, - * when doing so, it's important to call `super.createProperty` to ensure - * the property is setup correctly. This method calls - * `getPropertyDescriptor` internally to get a descriptor to install. - * To customize what properties do when they are get or set, override - * `getPropertyDescriptor`. To customize the options for a property, - * implement `createProperty` like this: - * - * ```ts - * static createProperty(name, options) { - * options = Object.assign(options, {myOption: true}); - * super.createProperty(name, options); - * } - * ``` - * - * @nocollapse - * @category properties - */ - static createProperty(name, options = defaultPropertyDeclaration) { - // If this is a state property, force the attribute to false. - if (options.state) { - options.attribute = false; - } - this.__prepare(); - // Whether this property is wrapping accessors. - // Helps control the initial value change and reflection logic. - if (this.prototype.hasOwnProperty(name)) { - options = Object.create(options); - options.wrapped = true; - } - this.elementProperties.set(name, options); - if (!options.noAccessor) { - const key = DEV_MODE - ? // Use Symbol.for in dev mode to make it easier to maintain state - // when doing HMR. - Symbol.for(`${String(name)} (@property() cache)`) - : Symbol(); - const descriptor = this.getPropertyDescriptor(name, key, options); - if (descriptor !== undefined) { - defineProperty(this.prototype, name, descriptor); - } - } - } - /** - * Returns a property descriptor to be defined on the given named property. - * If no descriptor is returned, the property will not become an accessor. - * For example, - * - * ```ts - * class MyElement extends LitElement { - * static getPropertyDescriptor(name, key, options) { - * const defaultDescriptor = - * super.getPropertyDescriptor(name, key, options); - * const setter = defaultDescriptor.set; - * return { - * get: defaultDescriptor.get, - * set(value) { - * setter.call(this, value); - * // custom action. - * }, - * configurable: true, - * enumerable: true - * } - * } - * } - * ``` - * - * @nocollapse - * @category properties - */ - static getPropertyDescriptor(name, key, options) { - const { get, set } = getOwnPropertyDescriptor(this.prototype, name) ?? { - get() { - return this[key]; - }, - set(v) { - this[key] = v; - }, - }; - if (DEV_MODE && get == null) { - if ('value' in (getOwnPropertyDescriptor(this.prototype, name) ?? {})) { - throw new Error(`Field ${JSON.stringify(String(name))} on ` + - `${this.name} was declared as a reactive property ` + - `but it's actually declared as a value on the prototype. ` + - `Usually this is due to using @property or @state on a method.`); - } - issueWarning('reactive-property-without-getter', `Field ${JSON.stringify(String(name))} on ` + - `${this.name} was declared as a reactive property ` + - `but it does not have a getter. This will be an error in a ` + - `future version of Lit.`); - } - return { - get, - set(value) { - const oldValue = get?.call(this); - set?.call(this, value); - this.requestUpdate(name, oldValue, options); - }, - configurable: true, - enumerable: true, - }; - } - /** - * Returns the property options associated with the given property. - * These options are defined with a `PropertyDeclaration` via the `properties` - * object or the `@property` decorator and are registered in - * `createProperty(...)`. - * - * Note, this method should be considered "final" and not overridden. To - * customize the options for a given property, override - * {@linkcode createProperty}. - * - * @nocollapse - * @final - * @category properties - */ - static getPropertyOptions(name) { - return this.elementProperties.get(name) ?? defaultPropertyDeclaration; - } - /** - * Initializes static own properties of the class used in bookkeeping - * for element properties, initializers, etc. - * - * Can be called multiple times by code that needs to ensure these - * properties exist before using them. - * - * This method ensures the superclass is finalized so that inherited - * property metadata can be copied down. - * @nocollapse - */ - static __prepare() { - if (this.hasOwnProperty(JSCompiler_renameProperty('elementProperties', this))) { - // Already prepared - return; - } - // Finalize any superclasses - const superCtor = getPrototypeOf(this); - superCtor.finalize(); - // Create own set of initializers for this class if any exist on the - // superclass and copy them down. Note, for a small perf boost, avoid - // creating initializers unless needed. - if (superCtor._initializers !== undefined) { - this._initializers = [...superCtor._initializers]; - } - // Initialize elementProperties from the superclass - this.elementProperties = new Map(superCtor.elementProperties); - } - /** - * Finishes setting up the class so that it's ready to be registered - * as a custom element and instantiated. - * - * This method is called by the ReactiveElement.observedAttributes getter. - * If you override the observedAttributes getter, you must either call - * super.observedAttributes to trigger finalization, or call finalize() - * yourself. - * - * @nocollapse - */ - static finalize() { - if (this.hasOwnProperty(JSCompiler_renameProperty('finalized', this))) { - return; - } - this.finalized = true; - this.__prepare(); - // Create properties from the static properties block: - if (this.hasOwnProperty(JSCompiler_renameProperty('properties', this))) { - const props = this.properties; - const propKeys = [ - ...getOwnPropertyNames(props), - ...getOwnPropertySymbols(props), - ]; - for (const p of propKeys) { - this.createProperty(p, props[p]); - } - } - // Create properties from standard decorator metadata: - const metadata = this[Symbol.metadata]; - if (metadata !== null) { - const properties = litPropertyMetadata.get(metadata); - if (properties !== undefined) { - for (const [p, options] of properties) { - this.elementProperties.set(p, options); - } - } - } - // Create the attribute-to-property map - this.__attributeToPropertyMap = new Map(); - for (const [p, options] of this.elementProperties) { - const attr = this.__attributeNameForProperty(p, options); - if (attr !== undefined) { - this.__attributeToPropertyMap.set(attr, p); - } - } - this.elementStyles = this.finalizeStyles(this.styles); - if (DEV_MODE) { - if (this.hasOwnProperty('createProperty')) { - issueWarning('no-override-create-property', 'Overriding ReactiveElement.createProperty() is deprecated. ' + - 'The override will not be called with standard decorators'); - } - if (this.hasOwnProperty('getPropertyDescriptor')) { - issueWarning('no-override-get-property-descriptor', 'Overriding ReactiveElement.getPropertyDescriptor() is deprecated. ' + - 'The override will not be called with standard decorators'); - } - } - } - /** - * Takes the styles the user supplied via the `static styles` property and - * returns the array of styles to apply to the element. - * Override this method to integrate into a style management system. - * - * Styles are deduplicated preserving the _last_ instance in the list. This - * is a performance optimization to avoid duplicated styles that can occur - * especially when composing via subclassing. The last item is kept to try - * to preserve the cascade order with the assumption that it's most important - * that last added styles override previous styles. - * - * @nocollapse - * @category styles - */ - static finalizeStyles(styles) { - const elementStyles = []; - if (Array.isArray(styles)) { - // Dedupe the flattened array in reverse order to preserve the last items. - // Casting to Array works around TS error that - // appears to come from trying to flatten a type CSSResultArray. - const set = new Set(styles.flat(Infinity).reverse()); - // Then preserve original order by adding the set items in reverse order. - for (const s of set) { - elementStyles.unshift((0,_css_tag_js__WEBPACK_IMPORTED_MODULE_0__.getCompatibleStyle)(s)); - } - } - else if (styles !== undefined) { - elementStyles.push((0,_css_tag_js__WEBPACK_IMPORTED_MODULE_0__.getCompatibleStyle)(styles)); - } - return elementStyles; - } - /** - * Returns the property name for the given attribute `name`. - * @nocollapse - */ - static __attributeNameForProperty(name, options) { - const attribute = options.attribute; - return attribute === false - ? undefined - : typeof attribute === 'string' - ? attribute - : typeof name === 'string' - ? name.toLowerCase() - : undefined; - } - constructor() { - super(); - this.__instanceProperties = undefined; - /** - * True if there is a pending update as a result of calling `requestUpdate()`. - * Should only be read. - * @category updates - */ - this.isUpdatePending = false; - /** - * Is set to `true` after the first update. The element code cannot assume - * that `renderRoot` exists before the element `hasUpdated`. - * @category updates - */ - this.hasUpdated = false; - /** - * Name of currently reflecting property - */ - this.__reflectingProperty = null; - this.__initialize(); - } - /** - * Internal only override point for customizing work done when elements - * are constructed. - */ - __initialize() { - this.__updatePromise = new Promise((res) => (this.enableUpdating = res)); - this._$changedProperties = new Map(); - // This enqueues a microtask that must run before the first update, so it - // must be called before requestUpdate() - this.__saveInstanceProperties(); - // ensures first update will be caught by an early access of - // `updateComplete` - this.requestUpdate(); - this.constructor._initializers?.forEach((i) => i(this)); - } - /** - * Registers a `ReactiveController` to participate in the element's reactive - * update cycle. The element automatically calls into any registered - * controllers during its lifecycle callbacks. - * - * If the element is connected when `addController()` is called, the - * controller's `hostConnected()` callback will be immediately called. - * @category controllers - */ - addController(controller) { - (this.__controllers ??= new Set()).add(controller); - // If a controller is added after the element has been connected, - // call hostConnected. Note, re-using existence of `renderRoot` here - // (which is set in connectedCallback) to avoid the need to track a - // first connected state. - if (this.renderRoot !== undefined && this.isConnected) { - controller.hostConnected?.(); - } - } - /** - * Removes a `ReactiveController` from the element. - * @category controllers - */ - removeController(controller) { - this.__controllers?.delete(controller); - } - /** - * Fixes any properties set on the instance before upgrade time. - * Otherwise these would shadow the accessor and break these properties. - * The properties are stored in a Map which is played back after the - * constructor runs. - */ - __saveInstanceProperties() { - const instanceProperties = new Map(); - const elementProperties = this.constructor - .elementProperties; - for (const p of elementProperties.keys()) { - if (this.hasOwnProperty(p)) { - instanceProperties.set(p, this[p]); - delete this[p]; - } - } - if (instanceProperties.size > 0) { - this.__instanceProperties = instanceProperties; - } - } - /** - * Returns the node into which the element should render and by default - * creates and returns an open shadowRoot. Implement to customize where the - * element's DOM is rendered. For example, to render into the element's - * childNodes, return `this`. - * - * @return Returns a node into which to render. - * @category rendering - */ - createRenderRoot() { - const renderRoot = this.shadowRoot ?? - this.attachShadow(this.constructor.shadowRootOptions); - (0,_css_tag_js__WEBPACK_IMPORTED_MODULE_0__.adoptStyles)(renderRoot, this.constructor.elementStyles); - return renderRoot; - } - /** - * On first connection, creates the element's renderRoot, sets up - * element styling, and enables updating. - * @category lifecycle - */ - connectedCallback() { - // Create renderRoot before controllers `hostConnected` - this.renderRoot ??= - this.createRenderRoot(); - this.enableUpdating(true); - this.__controllers?.forEach((c) => c.hostConnected?.()); - } - /** - * Note, this method should be considered final and not overridden. It is - * overridden on the element instance with a function that triggers the first - * update. - * @category updates - */ - enableUpdating(_requestedUpdate) { } - /** - * Allows for `super.disconnectedCallback()` in extensions while - * reserving the possibility of making non-breaking feature additions - * when disconnecting at some point in the future. - * @category lifecycle - */ - disconnectedCallback() { - this.__controllers?.forEach((c) => c.hostDisconnected?.()); - } - /** - * Synchronizes property values when attributes change. - * - * Specifically, when an attribute is set, the corresponding property is set. - * You should rarely need to implement this callback. If this method is - * overridden, `super.attributeChangedCallback(name, _old, value)` must be - * called. - * - * See [responding to attribute changes](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#responding_to_attribute_changes) - * on MDN for more information about the `attributeChangedCallback`. - * @category attributes - */ - attributeChangedCallback(name, _old, value) { - this._$attributeToProperty(name, value); - } - __propertyToAttribute(name, value) { - const elemProperties = this.constructor.elementProperties; - const options = elemProperties.get(name); - const attr = this.constructor.__attributeNameForProperty(name, options); - if (attr !== undefined && options.reflect === true) { - const converter = options.converter?.toAttribute !== - undefined - ? options.converter - : defaultConverter; - const attrValue = converter.toAttribute(value, options.type); - if (DEV_MODE && - this.constructor.enabledWarnings.includes('migration') && - attrValue === undefined) { - issueWarning('undefined-attribute-value', `The attribute value for the ${name} property is ` + - `undefined on element ${this.localName}. The attribute will be ` + - `removed, but in the previous version of \`ReactiveElement\`, ` + - `the attribute would not have changed.`); - } - // Track if the property is being reflected to avoid - // setting the property again via `attributeChangedCallback`. Note: - // 1. this takes advantage of the fact that the callback is synchronous. - // 2. will behave incorrectly if multiple attributes are in the reaction - // stack at time of calling. However, since we process attributes - // in `update` this should not be possible (or an extreme corner case - // that we'd like to discover). - // mark state reflecting - this.__reflectingProperty = name; - if (attrValue == null) { - this.removeAttribute(attr); - } - else { - this.setAttribute(attr, attrValue); - } - // mark state not reflecting - this.__reflectingProperty = null; - } - } - /** @internal */ - _$attributeToProperty(name, value) { - const ctor = this.constructor; - // Note, hint this as an `AttributeMap` so closure clearly understands - // the type; it has issues with tracking types through statics - const propName = ctor.__attributeToPropertyMap.get(name); - // Use tracking info to avoid reflecting a property value to an attribute - // if it was just set because the attribute changed. - if (propName !== undefined && this.__reflectingProperty !== propName) { - const options = ctor.getPropertyOptions(propName); - const converter = typeof options.converter === 'function' - ? { fromAttribute: options.converter } - : options.converter?.fromAttribute !== undefined - ? options.converter - : defaultConverter; - // mark state reflecting - this.__reflectingProperty = propName; - this[propName] = - converter.fromAttribute(value, options.type) ?? - this.__defaultValues?.get(propName) ?? - // eslint-disable-next-line @typescript-eslint/no-explicit-any - null; - // mark state not reflecting - this.__reflectingProperty = null; - } - } - /** - * Requests an update which is processed asynchronously. This should be called - * when an element should update based on some state not triggered by setting - * a reactive property. In this case, pass no arguments. It should also be - * called when manually implementing a property setter. In this case, pass the - * property `name` and `oldValue` to ensure that any configured property - * options are honored. - * - * @param name name of requesting property - * @param oldValue old value of requesting property - * @param options property options to use instead of the previously - * configured options - * @category updates - */ - requestUpdate(name, oldValue, options) { - // If we have a property key, perform property update steps. - if (name !== undefined) { - if (DEV_MODE && name instanceof Event) { - issueWarning(``, `The requestUpdate() method was called with an Event as the property name. This is probably a mistake caused by binding this.requestUpdate as an event listener. Instead bind a function that will call it with no arguments: () => this.requestUpdate()`); - } - const ctor = this.constructor; - const newValue = this[name]; - options ??= ctor.getPropertyOptions(name); - const changed = (options.hasChanged ?? notEqual)(newValue, oldValue) || - // When there is no change, check a corner case that can occur when - // 1. there's a initial value which was not reflected - // 2. the property is subsequently set to this value. - // For example, `prop: {useDefault: true, reflect: true}` - // and el.prop = 'foo'. This should be considered a change if the - // attribute is not set because we will now reflect the property to the attribute. - (options.useDefault && - options.reflect && - newValue === this.__defaultValues?.get(name) && - !this.hasAttribute(ctor.__attributeNameForProperty(name, options))); - if (changed) { - this._$changeProperty(name, oldValue, options); - } - else { - // Abort the request if the property should not be considered changed. - return; - } - } - if (this.isUpdatePending === false) { - this.__updatePromise = this.__enqueueUpdate(); - } - } - /** - * @internal - */ - _$changeProperty(name, oldValue, { useDefault, reflect, wrapped }, initializeValue) { - // Record default value when useDefault is used. This allows us to - // restore this value when the attribute is removed. - if (useDefault && !(this.__defaultValues ??= new Map()).has(name)) { - this.__defaultValues.set(name, initializeValue ?? oldValue ?? this[name]); - // if this is not wrapping an accessor, it must be an initial setting - // and in this case we do not want to record the change or reflect. - if (wrapped !== true || initializeValue !== undefined) { - return; - } - } - // TODO (justinfagnani): Create a benchmark of Map.has() + Map.set( - // vs just Map.set() - if (!this._$changedProperties.has(name)) { - // On the initial change, the old value should be `undefined`, except - // with `useDefault` - if (!this.hasUpdated && !useDefault) { - oldValue = undefined; - } - this._$changedProperties.set(name, oldValue); - } - // Add to reflecting properties set. - // Note, it's important that every change has a chance to add the - // property to `__reflectingProperties`. This ensures setting - // attribute + property reflects correctly. - if (reflect === true && this.__reflectingProperty !== name) { - (this.__reflectingProperties ??= new Set()).add(name); - } - } - /** - * Sets up the element to asynchronously update. - */ - async __enqueueUpdate() { - this.isUpdatePending = true; - try { - // Ensure any previous update has resolved before updating. - // This `await` also ensures that property changes are batched. - await this.__updatePromise; - } - catch (e) { - // Refire any previous errors async so they do not disrupt the update - // cycle. Errors are refired so developers have a chance to observe - // them, and this can be done by implementing - // `window.onunhandledrejection`. - Promise.reject(e); - } - const result = this.scheduleUpdate(); - // If `scheduleUpdate` returns a Promise, we await it. This is done to - // enable coordinating updates with a scheduler. Note, the result is - // checked to avoid delaying an additional microtask unless we need to. - if (result != null) { - await result; - } - return !this.isUpdatePending; - } - /** - * Schedules an element update. You can override this method to change the - * timing of updates by returning a Promise. The update will await the - * returned Promise, and you should resolve the Promise to allow the update - * to proceed. If this method is overridden, `super.scheduleUpdate()` - * must be called. - * - * For instance, to schedule updates to occur just before the next frame: - * - * ```ts - * override protected async scheduleUpdate(): Promise { - * await new Promise((resolve) => requestAnimationFrame(() => resolve())); - * super.scheduleUpdate(); - * } - * ``` - * @category updates - */ - scheduleUpdate() { - const result = this.performUpdate(); - if (DEV_MODE && - this.constructor.enabledWarnings.includes('async-perform-update') && - typeof result?.then === - 'function') { - issueWarning('async-perform-update', `Element ${this.localName} returned a Promise from performUpdate(). ` + - `This behavior is deprecated and will be removed in a future ` + - `version of ReactiveElement.`); - } - return result; - } - /** - * Performs an element update. Note, if an exception is thrown during the - * update, `firstUpdated` and `updated` will not be called. - * - * Call `performUpdate()` to immediately process a pending update. This should - * generally not be needed, but it can be done in rare cases when you need to - * update synchronously. - * - * @category updates - */ - performUpdate() { - // Abort any update if one is not pending when this is called. - // This can happen if `performUpdate` is called early to "flush" - // the update. - if (!this.isUpdatePending) { - return; - } - debugLogEvent?.({ kind: 'update' }); - if (!this.hasUpdated) { - // Create renderRoot before first update. This occurs in `connectedCallback` - // but is done here to support out of tree calls to `enableUpdating`/`performUpdate`. - this.renderRoot ??= - this.createRenderRoot(); - if (DEV_MODE) { - // Produce warning if any reactive properties on the prototype are - // shadowed by class fields. Instance fields set before upgrade are - // deleted by this point, so any own property is caused by class field - // initialization in the constructor. - const ctor = this.constructor; - const shadowedProperties = [...ctor.elementProperties.keys()].filter((p) => this.hasOwnProperty(p) && p in getPrototypeOf(this)); - if (shadowedProperties.length) { - throw new Error(`The following properties on element ${this.localName} will not ` + - `trigger updates as expected because they are set using class ` + - `fields: ${shadowedProperties.join(', ')}. ` + - `Native class fields and some compiled output will overwrite ` + - `accessors used for detecting changes. See ` + - `https://lit.dev/msg/class-field-shadowing ` + - `for more information.`); - } - } - // Mixin instance properties once, if they exist. - if (this.__instanceProperties) { - // TODO (justinfagnani): should we use the stored value? Could a new value - // have been set since we stored the own property value? - for (const [p, value] of this.__instanceProperties) { - this[p] = value; - } - this.__instanceProperties = undefined; - } - // Trigger initial value reflection and populate the initial - // `changedProperties` map, but only for the case of properties created - // via `createProperty` on accessors, which will not have already - // populated the `changedProperties` map since they are not set. - // We can't know if these accessors had initializers, so we just set - // them anyway - a difference from experimental decorators on fields and - // standard decorators on auto-accessors. - // For context see: - // https://github.com/lit/lit/pull/4183#issuecomment-1711959635 - const elementProperties = this.constructor - .elementProperties; - if (elementProperties.size > 0) { - for (const [p, options] of elementProperties) { - const { wrapped } = options; - const value = this[p]; - if (wrapped === true && - !this._$changedProperties.has(p) && - value !== undefined) { - this._$changeProperty(p, undefined, options, value); - } - } - } - } - let shouldUpdate = false; - const changedProperties = this._$changedProperties; - try { - shouldUpdate = this.shouldUpdate(changedProperties); - if (shouldUpdate) { - this.willUpdate(changedProperties); - this.__controllers?.forEach((c) => c.hostUpdate?.()); - this.update(changedProperties); - } - else { - this.__markUpdated(); - } - } - catch (e) { - // Prevent `firstUpdated` and `updated` from running when there's an - // update exception. - shouldUpdate = false; - // Ensure element can accept additional updates after an exception. - this.__markUpdated(); - throw e; - } - // The update is no longer considered pending and further updates are now allowed. - if (shouldUpdate) { - this._$didUpdate(changedProperties); - } - } - /** - * Invoked before `update()` to compute values needed during the update. - * - * Implement `willUpdate` to compute property values that depend on other - * properties and are used in the rest of the update process. - * - * ```ts - * willUpdate(changedProperties) { - * // only need to check changed properties for an expensive computation. - * if (changedProperties.has('firstName') || changedProperties.has('lastName')) { - * this.sha = computeSHA(`${this.firstName} ${this.lastName}`); - * } - * } - * - * render() { - * return html`SHA: ${this.sha}`; - * } - * ``` - * - * @category updates - */ - willUpdate(_changedProperties) { } - // Note, this is an override point for polyfill-support. - // @internal - _$didUpdate(changedProperties) { - this.__controllers?.forEach((c) => c.hostUpdated?.()); - if (!this.hasUpdated) { - this.hasUpdated = true; - this.firstUpdated(changedProperties); - } - this.updated(changedProperties); - if (DEV_MODE && - this.isUpdatePending && - this.constructor.enabledWarnings.includes('change-in-update')) { - issueWarning('change-in-update', `Element ${this.localName} scheduled an update ` + - `(generally because a property was set) ` + - `after an update completed, causing a new update to be scheduled. ` + - `This is inefficient and should be avoided unless the next update ` + - `can only be scheduled as a side effect of the previous update.`); - } - } - __markUpdated() { - this._$changedProperties = new Map(); - this.isUpdatePending = false; - } - /** - * Returns a Promise that resolves when the element has completed updating. - * The Promise value is a boolean that is `true` if the element completed the - * update without triggering another update. The Promise result is `false` if - * a property was set inside `updated()`. If the Promise is rejected, an - * exception was thrown during the update. - * - * To await additional asynchronous work, override the `getUpdateComplete` - * method. For example, it is sometimes useful to await a rendered element - * before fulfilling this Promise. To do this, first await - * `super.getUpdateComplete()`, then any subsequent state. - * - * @return A promise of a boolean that resolves to true if the update completed - * without triggering another update. - * @category updates - */ - get updateComplete() { - return this.getUpdateComplete(); - } - /** - * Override point for the `updateComplete` promise. - * - * It is not safe to override the `updateComplete` getter directly due to a - * limitation in TypeScript which means it is not possible to call a - * superclass getter (e.g. `super.updateComplete.then(...)`) when the target - * language is ES5 (https://github.com/microsoft/TypeScript/issues/338). - * This method should be overridden instead. For example: - * - * ```ts - * class MyElement extends LitElement { - * override async getUpdateComplete() { - * const result = await super.getUpdateComplete(); - * await this._myChild.updateComplete; - * return result; - * } - * } - * ``` - * - * @return A promise of a boolean that resolves to true if the update completed - * without triggering another update. - * @category updates - */ - getUpdateComplete() { - return this.__updatePromise; - } - /** - * Controls whether or not `update()` should be called when the element requests - * an update. By default, this method always returns `true`, but this can be - * customized to control when to update. - * - * @param _changedProperties Map of changed properties with old values - * @category updates - */ - shouldUpdate(_changedProperties) { - return true; - } - /** - * Updates the element. This method reflects property values to attributes. - * It can be overridden to render and keep updated element DOM. - * Setting properties inside this method will *not* trigger - * another update. - * - * @param _changedProperties Map of changed properties with old values - * @category updates - */ - update(_changedProperties) { - // The forEach() expression will only run when __reflectingProperties is - // defined, and it returns undefined, setting __reflectingProperties to - // undefined - this.__reflectingProperties &&= this.__reflectingProperties.forEach((p) => this.__propertyToAttribute(p, this[p])); - this.__markUpdated(); - } - /** - * Invoked whenever the element is updated. Implement to perform - * post-updating tasks via DOM APIs, for example, focusing an element. - * - * Setting properties inside this method will trigger the element to update - * again after this update cycle completes. - * - * @param _changedProperties Map of changed properties with old values - * @category updates - */ - updated(_changedProperties) { } - /** - * Invoked when the element is first updated. Implement to perform one time - * work on the element after update. - * - * ```ts - * firstUpdated() { - * this.renderRoot.getElementById('my-text-area').focus(); - * } - * ``` - * - * Setting properties inside this method will trigger the element to update - * again after this update cycle completes. - * - * @param _changedProperties Map of changed properties with old values - * @category updates - */ - firstUpdated(_changedProperties) { } -} -/** - * Memoized list of all element styles. - * Created lazily on user subclasses when finalizing the class. - * @nocollapse - * @category styles - */ -ReactiveElement.elementStyles = []; -/** - * Options used when calling `attachShadow`. Set this property to customize - * the options for the shadowRoot; for example, to create a closed - * shadowRoot: `{mode: 'closed'}`. - * - * Note, these options are used in `createRenderRoot`. If this method - * is customized, options should be respected if possible. - * @nocollapse - * @category rendering - */ -ReactiveElement.shadowRootOptions = { mode: 'open' }; -// Assigned here to work around a jscompiler bug with static fields -// when compiling to ES5. -// https://github.com/google/closure-compiler/issues/3177 -ReactiveElement[JSCompiler_renameProperty('elementProperties', ReactiveElement)] = new Map(); -ReactiveElement[JSCompiler_renameProperty('finalized', ReactiveElement)] = new Map(); -// Apply polyfills if available -polyfillSupport?.({ ReactiveElement }); -// Dev mode warnings... -if (DEV_MODE) { - // Default warning set. - ReactiveElement.enabledWarnings = [ - 'change-in-update', - 'async-perform-update', - ]; - const ensureOwnWarnings = function (ctor) { - if (!ctor.hasOwnProperty(JSCompiler_renameProperty('enabledWarnings', ctor))) { - ctor.enabledWarnings = ctor.enabledWarnings.slice(); - } - }; - ReactiveElement.enableWarning = function (warning) { - ensureOwnWarnings(this); - if (!this.enabledWarnings.includes(warning)) { - this.enabledWarnings.push(warning); - } - }; - ReactiveElement.disableWarning = function (warning) { - ensureOwnWarnings(this); - const i = this.enabledWarnings.indexOf(warning); - if (i >= 0) { - this.enabledWarnings.splice(i, 1); - } - }; -} -// IMPORTANT: do not change the property name or the assignment expression. -// This line will be used in regexes to search for ReactiveElement usage. -(global.reactiveElementVersions ??= []).push('2.1.0'); -if (DEV_MODE && global.reactiveElementVersions.length > 1) { - queueMicrotask(() => { - issueWarning('multiple-versions', `Multiple versions of Lit loaded. Loading multiple versions ` + - `is not recommended.`); - }); -} -//# sourceMappingURL=reactive-element.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/button/internal/button.js": -/*!**************************************************************!*\ - !*** ./node_modules/@material/web/button/internal/button.js ***! - \**************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Button: () => (/* binding */ Button) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var _focus_md_focus_ring_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../focus/md-focus-ring.js */ "./node_modules/@material/web/focus/md-focus-ring.js"); -/* harmony import */ var _ripple_ripple_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../ripple/ripple.js */ "./node_modules/@material/web/ripple/ripple.js"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../internal/aria/delegate.js */ "./node_modules/@material/web/internal/aria/delegate.js"); -/* harmony import */ var _internal_controller_form_submitter_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../internal/controller/form-submitter.js */ "./node_modules/@material/web/internal/controller/form-submitter.js"); -/* harmony import */ var _internal_events_form_label_activation_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../internal/events/form-label-activation.js */ "./node_modules/@material/web/internal/events/form-label-activation.js"); -/* harmony import */ var _labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../labs/behaviors/element-internals.js */ "./node_modules/@material/web/labs/behaviors/element-internals.js"); -/** - * @license - * Copyright 2019 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - - - - - -// Separate variable needed for closure. -const buttonBaseClass = (0,_internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_4__.mixinDelegatesAria)((0,_labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_7__.mixinElementInternals)(lit__WEBPACK_IMPORTED_MODULE_2__.LitElement)); -/** - * A button component. - */ -class Button extends buttonBaseClass { - get name() { - return this.getAttribute('name') ?? ''; - } - set name(name) { - this.setAttribute('name', name); - } - /** - * The associated form element with which this element's value will submit. - */ - get form() { - return this[_labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_7__.internals].form; - } - constructor() { - super(); - /** - * Whether or not the button is disabled. - */ - this.disabled = false; - /** - * Whether or not the button is "soft-disabled" (disabled but still - * focusable). - * - * Use this when a button needs increased visibility when disabled. See - * https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_disabled_controls - * for more guidance on when this is needed. - */ - this.softDisabled = false; - /** - * The URL that the link button points to. - */ - this.href = ''; - /** - * The filename to use when downloading the linked resource. - * If not specified, the browser will determine a filename. - * This is only applicable when the button is used as a link (`href` is set). - */ - this.download = ''; - /** - * Where to display the linked `href` URL for a link button. Common options - * include `_blank` to open in a new tab. - */ - this.target = ''; - /** - * Whether to render the icon at the inline end of the label rather than the - * inline start. - * - * _Note:_ Link buttons cannot have trailing icons. - */ - this.trailingIcon = false; - /** - * Whether to display the icon or not. - */ - this.hasIcon = false; - /** - * The default behavior of the button. May be "button", "reset", or "submit" - * (default). - */ - this.type = 'submit'; - /** - * The value added to a form with the button's name when the button submits a - * form. - */ - this.value = ''; - if (!lit__WEBPACK_IMPORTED_MODULE_2__.isServer) { - this.addEventListener('click', this.handleClick.bind(this)); - } - } - focus() { - this.buttonElement?.focus(); - } - blur() { - this.buttonElement?.blur(); - } - render() { - // Link buttons may not be disabled - const isRippleDisabled = !this.href && (this.disabled || this.softDisabled); - const buttonOrLink = this.href ? this.renderLink() : this.renderButton(); - // TODO(b/310046938): due to a limitation in focus ring/ripple, we can't use - // the same ID for different elements, so we change the ID instead. - const buttonId = this.href ? 'link' : 'button'; - return (0,lit__WEBPACK_IMPORTED_MODULE_2__.html) ` - ${this.renderElevationOrOutline?.()} -
    - - - ${buttonOrLink} - `; - } - renderButton() { - // Needed for closure conformance - const { ariaLabel, ariaHasPopup, ariaExpanded } = this; - return (0,lit__WEBPACK_IMPORTED_MODULE_2__.html) ``; - } - renderLink() { - // Needed for closure conformance - const { ariaLabel, ariaHasPopup, ariaExpanded } = this; - return (0,lit__WEBPACK_IMPORTED_MODULE_2__.html) `${this.renderContent()} - `; - } - renderContent() { - const icon = (0,lit__WEBPACK_IMPORTED_MODULE_2__.html) ``; - return (0,lit__WEBPACK_IMPORTED_MODULE_2__.html) ` - - ${this.trailingIcon ? lit__WEBPACK_IMPORTED_MODULE_2__.nothing : icon} - - ${this.trailingIcon ? icon : lit__WEBPACK_IMPORTED_MODULE_2__.nothing} - `; - } - handleClick(event) { - // If the button is soft-disabled, we need to explicitly prevent the click - // from propagating to other event listeners as well as prevent the default - // action. - if (!this.href && this.softDisabled) { - event.stopImmediatePropagation(); - event.preventDefault(); - return; - } - if (!(0,_internal_events_form_label_activation_js__WEBPACK_IMPORTED_MODULE_6__.isActivationClick)(event) || !this.buttonElement) { - return; - } - this.focus(); - (0,_internal_events_form_label_activation_js__WEBPACK_IMPORTED_MODULE_6__.dispatchActivationClick)(this.buttonElement); - } - handleSlotChange() { - this.hasIcon = this.assignedIcons.length > 0; - } -} -(() => { - (0,_internal_controller_form_submitter_js__WEBPACK_IMPORTED_MODULE_5__.setupFormSubmitter)(Button); -})(); -/** @nocollapse */ -Button.formAssociated = true; -/** @nocollapse */ -Button.shadowRootOptions = { - mode: 'open', - delegatesFocus: true, -}; -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, reflect: true }) -], Button.prototype, "disabled", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'soft-disabled', reflect: true }) -], Button.prototype, "softDisabled", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)() -], Button.prototype, "href", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)() -], Button.prototype, "download", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)() -], Button.prototype, "target", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'trailing-icon', reflect: true }) -], Button.prototype, "trailingIcon", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'has-icon', reflect: true }) -], Button.prototype, "hasIcon", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)() -], Button.prototype, "type", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ reflect: true }) -], Button.prototype, "value", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.query)('.button') -], Button.prototype, "buttonElement", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.queryAssignedElements)({ slot: 'icon', flatten: true }) -], Button.prototype, "assignedIcons", void 0); -//# sourceMappingURL=button.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/button/internal/shared-styles.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@material/web/button/internal/shared-styles.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./button/internal/shared-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end);box-sizing:border-box;cursor:pointer;display:inline-flex;gap:8px;min-height:var(--_container-height);outline:none;padding-block:calc((var(--_container-height) - max(var(--_label-text-line-height),var(--_icon-size)))/2);padding-inline-start:var(--_leading-space);padding-inline-end:var(--_trailing-space);place-content:center;place-items:center;position:relative;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);text-overflow:ellipsis;text-wrap:nowrap;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0);vertical-align:top;--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}md-focus-ring{--md-focus-ring-shape-start-start: var(--_container-shape-start-start);--md-focus-ring-shape-start-end: var(--_container-shape-start-end);--md-focus-ring-shape-end-end: var(--_container-shape-end-end);--md-focus-ring-shape-end-start: var(--_container-shape-end-start)}:host(:is([disabled],[soft-disabled])){cursor:default;pointer-events:none}.button{border-radius:inherit;cursor:inherit;display:inline-flex;align-items:center;justify-content:center;border:none;outline:none;-webkit-appearance:none;vertical-align:middle;background:rgba(0,0,0,0);text-decoration:none;min-width:calc(64px - var(--_leading-space) - var(--_trailing-space));width:100%;z-index:0;height:100%;font:inherit;color:var(--_label-text-color);padding:0;gap:inherit;text-transform:inherit}.button::-moz-focus-inner{padding:0;border:0}:host(:hover) .button{color:var(--_hover-label-text-color)}:host(:focus-within) .button{color:var(--_focus-label-text-color)}:host(:active) .button{color:var(--_pressed-label-text-color)}.background{background-color:var(--_container-color);border-radius:inherit;inset:0;position:absolute}.label{overflow:hidden}:is(.button,.label,.label slot),.label ::slotted(*){text-overflow:inherit}:host(:is([disabled],[soft-disabled])) .label{color:var(--_disabled-label-text-color);opacity:var(--_disabled-label-text-opacity)}:host(:is([disabled],[soft-disabled])) .background{background-color:var(--_disabled-container-color);opacity:var(--_disabled-container-opacity)}@media(forced-colors: active){.background{border:1px solid CanvasText}:host(:is([disabled],[soft-disabled])){--_disabled-icon-color: GrayText;--_disabled-icon-opacity: 1;--_disabled-container-opacity: 1;--_disabled-label-text-color: GrayText;--_disabled-label-text-opacity: 1}}:host([has-icon]:not([trailing-icon])){padding-inline-start:var(--_with-leading-icon-leading-space);padding-inline-end:var(--_with-leading-icon-trailing-space)}:host([has-icon][trailing-icon]){padding-inline-start:var(--_with-trailing-icon-leading-space);padding-inline-end:var(--_with-trailing-icon-trailing-space)}::slotted([slot=icon]){display:inline-flex;position:relative;writing-mode:horizontal-tb;fill:currentColor;flex-shrink:0;color:var(--_icon-color);font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size)}:host(:hover) ::slotted([slot=icon]){color:var(--_hover-icon-color)}:host(:focus-within) ::slotted([slot=icon]){color:var(--_focus-icon-color)}:host(:active) ::slotted([slot=icon]){color:var(--_pressed-icon-color)}:host(:is([disabled],[soft-disabled])) ::slotted([slot=icon]){color:var(--_disabled-icon-color);opacity:var(--_disabled-icon-opacity)}.touch{position:absolute;top:50%;height:48px;left:0;right:0;transform:translateY(-50%)}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--_container-height))/2) 0}:host([touch-target=none]) .touch{display:none} -`; -//# sourceMappingURL=shared-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/button/internal/text-button.js": -/*!*******************************************************************!*\ - !*** ./node_modules/@material/web/button/internal/text-button.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ TextButton: () => (/* binding */ TextButton) -/* harmony export */ }); -/* harmony import */ var _button_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./button.js */ "./node_modules/@material/web/button/internal/button.js"); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * A text button component. - */ -class TextButton extends _button_js__WEBPACK_IMPORTED_MODULE_0__.Button { -} -//# sourceMappingURL=text-button.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/button/internal/text-styles.js": -/*!*******************************************************************!*\ - !*** ./node_modules/@material/web/button/internal/text-styles.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./button/internal/text-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{--_container-height: var(--md-text-button-container-height, 40px);--_disabled-label-text-color: var(--md-text-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-text-button-disabled-label-text-opacity, 0.38);--_focus-label-text-color: var(--md-text-button-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-label-text-color: var(--md-text-button-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-text-button-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-text-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-text-button-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-font: var(--md-text-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-text-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-text-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-text-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-label-text-color: var(--md-text-button-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-color: var(--md-text-button-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-text-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-text-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-text-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-text-button-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-icon-color: var(--md-text-button-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-color: var(--md-text-button-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-text-button-icon-size, 18px);--_pressed-icon-color: var(--md-text-button-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-text-button-container-shape-start-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-text-button-container-shape-start-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-text-button-container-shape-end-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-text-button-container-shape-end-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-text-button-leading-space, 12px);--_trailing-space: var(--md-text-button-trailing-space, 12px);--_with-leading-icon-leading-space: var(--md-text-button-with-leading-icon-leading-space, 12px);--_with-leading-icon-trailing-space: var(--md-text-button-with-leading-icon-trailing-space, 16px);--_with-trailing-icon-leading-space: var(--md-text-button-with-trailing-icon-leading-space, 16px);--_with-trailing-icon-trailing-space: var(--md-text-button-with-trailing-icon-trailing-space, 12px);--_container-color: none;--_disabled-container-color: none;--_disabled-container-opacity: 0} -`; -//# sourceMappingURL=text-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/dialog/internal/animations.js": -/*!******************************************************************!*\ - !*** ./node_modules/@material/web/dialog/internal/animations.js ***! - \******************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ DIALOG_DEFAULT_CLOSE_ANIMATION: () => (/* binding */ DIALOG_DEFAULT_CLOSE_ANIMATION), -/* harmony export */ DIALOG_DEFAULT_OPEN_ANIMATION: () => (/* binding */ DIALOG_DEFAULT_OPEN_ANIMATION) -/* harmony export */ }); -/* harmony import */ var _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../internal/motion/animation.js */ "./node_modules/@material/web/internal/motion/animation.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * The default dialog open animation. - */ -const DIALOG_DEFAULT_OPEN_ANIMATION = { - dialog: [ - [ - // Dialog slide down - [{ 'transform': 'translateY(-50px)' }, { 'transform': 'translateY(0)' }], - { duration: 500, easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_0__.EASING.EMPHASIZED }, - ], - ], - scrim: [ - [ - // Scrim fade in - [{ 'opacity': 0 }, { 'opacity': 0.32 }], - { duration: 500, easing: 'linear' }, - ], - ], - container: [ - [ - // Container fade in - [{ 'opacity': 0 }, { 'opacity': 1 }], - { duration: 50, easing: 'linear', pseudoElement: '::before' }, - ], - [ - // Container grow - // Note: current spec says to grow from 0dp->100% and shrink from - // 100%->35%. We change this to 35%->100% to simplify the animation that - // is supposed to clip content as it grows. From 0dp it's possible to see - // text/actions appear before the container has fully grown. - [{ 'height': '35%' }, { 'height': '100%' }], - { duration: 500, easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_0__.EASING.EMPHASIZED, pseudoElement: '::before' }, - ], - ], - headline: [ - [ - // Headline fade in - [{ 'opacity': 0 }, { 'opacity': 0, offset: 0.2 }, { 'opacity': 1 }], - { duration: 250, easing: 'linear', fill: 'forwards' }, - ], - ], - content: [ - [ - // Content fade in - [{ 'opacity': 0 }, { 'opacity': 0, offset: 0.2 }, { 'opacity': 1 }], - { duration: 250, easing: 'linear', fill: 'forwards' }, - ], - ], - actions: [ - [ - // Actions fade in - [{ 'opacity': 0 }, { 'opacity': 0, offset: 0.5 }, { 'opacity': 1 }], - { duration: 300, easing: 'linear', fill: 'forwards' }, - ], - ], -}; -/** - * The default dialog close animation. - */ -const DIALOG_DEFAULT_CLOSE_ANIMATION = { - dialog: [ - [ - // Dialog slide up - [{ 'transform': 'translateY(0)' }, { 'transform': 'translateY(-50px)' }], - { duration: 150, easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_0__.EASING.EMPHASIZED_ACCELERATE }, - ], - ], - scrim: [ - [ - // Scrim fade out - [{ 'opacity': 0.32 }, { 'opacity': 0 }], - { duration: 150, easing: 'linear' }, - ], - ], - container: [ - [ - // Container shrink - [{ 'height': '100%' }, { 'height': '35%' }], - { - duration: 150, - easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_0__.EASING.EMPHASIZED_ACCELERATE, - pseudoElement: '::before', - }, - ], - [ - // Container fade out - [{ 'opacity': '1' }, { 'opacity': '0' }], - { delay: 100, duration: 50, easing: 'linear', pseudoElement: '::before' }, - ], - ], - headline: [ - [ - // Headline fade out - [{ 'opacity': 1 }, { 'opacity': 0 }], - { duration: 100, easing: 'linear', fill: 'forwards' }, - ], - ], - content: [ - [ - // Content fade out - [{ 'opacity': 1 }, { 'opacity': 0 }], - { duration: 100, easing: 'linear', fill: 'forwards' }, - ], - ], - actions: [ - [ - // Actions fade out - [{ 'opacity': 1 }, { 'opacity': 0 }], - { duration: 100, easing: 'linear', fill: 'forwards' }, - ], - ], -}; -//# sourceMappingURL=animations.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/dialog/internal/dialog-styles.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@material/web/dialog/internal/dialog-styles.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./dialog/internal/dialog-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{border-start-start-radius:var(--md-dialog-container-shape-start-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-start-end-radius:var(--md-dialog-container-shape-start-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-end-radius:var(--md-dialog-container-shape-end-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-start-radius:var(--md-dialog-container-shape-end-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));display:contents;margin:auto;max-height:min(560px,100% - 48px);max-width:min(560px,100% - 48px);min-height:140px;min-width:280px;position:fixed;height:fit-content;width:fit-content}dialog{background:rgba(0,0,0,0);border:none;border-radius:inherit;flex-direction:column;height:inherit;margin:inherit;max-height:inherit;max-width:inherit;min-height:inherit;min-width:inherit;outline:none;overflow:visible;padding:0;width:inherit}dialog[open]{display:flex}::backdrop{background:none}.scrim{background:var(--md-sys-color-scrim, #000);display:none;inset:0;opacity:32%;pointer-events:none;position:fixed;z-index:1}:host([open]) .scrim{display:flex}h2{all:unset;align-self:stretch}.headline{align-items:center;color:var(--md-dialog-headline-color, var(--md-sys-color-on-surface, #1d1b20));display:flex;flex-direction:column;font-family:var(--md-dialog-headline-font, var(--md-sys-typescale-headline-small-font, var(--md-ref-typeface-brand, Roboto)));font-size:var(--md-dialog-headline-size, var(--md-sys-typescale-headline-small-size, 1.5rem));line-height:var(--md-dialog-headline-line-height, var(--md-sys-typescale-headline-small-line-height, 2rem));font-weight:var(--md-dialog-headline-weight, var(--md-sys-typescale-headline-small-weight, var(--md-ref-typeface-weight-regular, 400)));position:relative}slot[name=headline]::slotted(*){align-items:center;align-self:stretch;box-sizing:border-box;display:flex;gap:8px;padding:24px 24px 0}.icon{display:flex}slot[name=icon]::slotted(*){color:var(--md-dialog-icon-color, var(--md-sys-color-secondary, #625b71));fill:currentColor;font-size:var(--md-dialog-icon-size, 24px);margin-top:24px;height:var(--md-dialog-icon-size, 24px);width:var(--md-dialog-icon-size, 24px)}.has-icon slot[name=headline]::slotted(*){justify-content:center;padding-top:16px}.scrollable slot[name=headline]::slotted(*){padding-bottom:16px}.scrollable.has-headline slot[name=content]::slotted(*){padding-top:8px}.container{border-radius:inherit;display:flex;flex-direction:column;flex-grow:1;overflow:hidden;position:relative;transform-origin:top}.container::before{background:var(--md-dialog-container-color, var(--md-sys-color-surface-container-high, #ece6f0));border-radius:inherit;content:"";inset:0;position:absolute}.scroller{display:flex;flex:1;flex-direction:column;overflow:hidden;z-index:1}.scrollable .scroller{overflow-y:scroll}.content{color:var(--md-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-dialog-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-dialog-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-dialog-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));flex:1;font-weight:var(--md-dialog-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)));height:min-content;position:relative}slot[name=content]::slotted(*){box-sizing:border-box;padding:24px}.anchor{position:absolute}.top.anchor{top:0}.bottom.anchor{bottom:0}.actions{position:relative}slot[name=actions]::slotted(*){box-sizing:border-box;display:flex;gap:8px;justify-content:flex-end;padding:16px 24px 24px}.has-actions slot[name=content]::slotted(*){padding-bottom:8px}md-divider{display:none;position:absolute}.has-headline.show-top-divider .headline md-divider,.has-actions.show-bottom-divider .actions md-divider{display:flex}.headline md-divider{bottom:0}.actions md-divider{top:0}@media(forced-colors: active){dialog{outline:2px solid WindowText}} -`; -//# sourceMappingURL=dialog-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/dialog/internal/dialog.js": -/*!**************************************************************!*\ - !*** ./node_modules/@material/web/dialog/internal/dialog.js ***! - \**************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Dialog: () => (/* binding */ Dialog) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var _divider_divider_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../divider/divider.js */ "./node_modules/@material/web/divider/divider.js"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lit/directives/class-map.js */ "./node_modules/lit/directives/class-map.js"); -/* harmony import */ var _internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../internal/aria/delegate.js */ "./node_modules/@material/web/internal/aria/delegate.js"); -/* harmony import */ var _internal_events_redispatch_event_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../internal/events/redispatch-event.js */ "./node_modules/@material/web/internal/events/redispatch-event.js"); -/* harmony import */ var _animations_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./animations.js */ "./node_modules/@material/web/dialog/internal/animations.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - - - - -// Separate variable needed for closure. -const dialogBaseClass = (0,_internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_4__.mixinDelegatesAria)(lit__WEBPACK_IMPORTED_MODULE_1__.LitElement); -/** - * A dialog component. - * - * @fires open {Event} Dispatched when the dialog is opening before any animations. - * @fires opened {Event} Dispatched when the dialog has opened after any animations. - * @fires close {Event} Dispatched when the dialog is closing before any animations. - * @fires closed {Event} Dispatched when the dialog has closed after any animations. - * @fires cancel {Event} Dispatched when the dialog has been canceled by clicking - * on the scrim or pressing Escape. - */ -class Dialog extends dialogBaseClass { - // We do not use `delegatesFocus: true` due to a Chromium bug with - // selecting text. - // See https://bugs.chromium.org/p/chromium/issues/detail?id=950357 - /** - * Opens the dialog when set to `true` and closes it when set to `false`. - */ - get open() { - return this.isOpen; - } - set open(open) { - if (open === this.isOpen) { - return; - } - this.isOpen = open; - if (open) { - this.setAttribute('open', ''); - this.show(); - } - else { - this.removeAttribute('open'); - this.close(); - } - } - constructor() { - super(); - /** - * Skips the opening and closing animations. - */ - this.quick = false; - /** - * Gets or sets the dialog's return value, usually to indicate which button - * a user pressed to close it. - * - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/returnValue - */ - this.returnValue = ''; - /** - * Disables focus trapping, which by default keeps keyboard Tab navigation - * within the dialog. - * - * When disabled, after focusing the last element of a dialog, pressing Tab - * again will release focus from the window back to the browser (such as the - * URL bar). - * - * Focus trapping is recommended for accessibility, and should not typically - * be disabled. Only turn this off if the use case of a dialog is more - * accessible without focus trapping. - */ - this.noFocusTrap = false; - /** - * Gets the opening animation for a dialog. Set to a new function to customize - * the animation. - */ - this.getOpenAnimation = () => _animations_js__WEBPACK_IMPORTED_MODULE_6__.DIALOG_DEFAULT_OPEN_ANIMATION; - /** - * Gets the closing animation for a dialog. Set to a new function to customize - * the animation. - */ - this.getCloseAnimation = () => _animations_js__WEBPACK_IMPORTED_MODULE_6__.DIALOG_DEFAULT_CLOSE_ANIMATION; - this.isOpen = false; - this.isOpening = false; - this.isConnectedPromise = this.getIsConnectedPromise(); - this.isAtScrollTop = false; - this.isAtScrollBottom = false; - this.nextClickIsFromContent = false; - // Dialogs should not be SSR'd while open, so we can just use runtime checks. - this.hasHeadline = false; - this.hasActions = false; - this.hasIcon = false; - // See https://bugs.chromium.org/p/chromium/issues/detail?id=1512224 - // Chrome v120 has a bug where escape keys do not trigger cancels. If we get - // a dialog "close" event that is triggered without a "cancel" after an escape - // keydown, then we need to manually trigger our closing logic. - // - // This bug occurs when pressing escape to close a dialog without first - // interacting with the dialog's content. - // - // Cleanup tracking: - // https://github.com/material-components/material-web/issues/5330 - // This can be removed when full CloseWatcher support added and the above bug - // in Chromium is fixed to fire 'cancel' with one escape press and close with - // multiple. - this.escapePressedWithoutCancel = false; - // This TreeWalker is used to walk through a dialog's children to find - // focusable elements. TreeWalker is faster than `querySelectorAll('*')`. - // We check for isServer because there isn't a "document" during an SSR - // run. - this.treewalker = lit__WEBPACK_IMPORTED_MODULE_1__.isServer - ? null - : document.createTreeWalker(this, NodeFilter.SHOW_ELEMENT); - if (!lit__WEBPACK_IMPORTED_MODULE_1__.isServer) { - this.addEventListener('submit', this.handleSubmit); - } - } - /** - * Opens the dialog and fires a cancelable `open` event. After a dialog's - * animation, an `opened` event is fired. - * - * Add an `autofocus` attribute to a child of the dialog that should - * receive focus after opening. - * - * @return A Promise that resolves after the animation is finished and the - * `opened` event was fired. - */ - async show() { - this.isOpening = true; - // Dialogs can be opened before being attached to the DOM, so we need to - // wait until we're connected before calling `showModal()`. - await this.isConnectedPromise; - await this.updateComplete; - const dialog = this.dialog; - // Check if already opened or if `dialog.close()` was called while awaiting. - if (dialog.open || !this.isOpening) { - this.isOpening = false; - return; - } - const preventOpen = !this.dispatchEvent(new Event('open', { cancelable: true })); - if (preventOpen) { - this.open = false; - this.isOpening = false; - return; - } - // All Material dialogs are modal. - dialog.showModal(); - this.open = true; - // Reset scroll position if re-opening a dialog with the same content. - if (this.scroller) { - this.scroller.scrollTop = 0; - } - // Native modal dialogs ignore autofocus and instead force focus to the - // first focusable child. Override this behavior if there is a child with - // an autofocus attribute. - this.querySelector('[autofocus]')?.focus(); - await this.animateDialog(this.getOpenAnimation()); - this.dispatchEvent(new Event('opened')); - this.isOpening = false; - } - /** - * Closes the dialog and fires a cancelable `close` event. After a dialog's - * animation, a `closed` event is fired. - * - * @param returnValue A return value usually indicating which button was used - * to close a dialog. If a dialog is canceled by clicking the scrim or - * pressing Escape, it will not change the return value after closing. - * @return A Promise that resolves after the animation is finished and the - * `closed` event was fired. - */ - async close(returnValue = this.returnValue) { - this.isOpening = false; - if (!this.isConnected) { - // Disconnected dialogs do not fire close events or animate. - this.open = false; - return; - } - await this.updateComplete; - const dialog = this.dialog; - // Check if already closed or if `dialog.show()` was called while awaiting. - if (!dialog.open || this.isOpening) { - this.open = false; - return; - } - const prevReturnValue = this.returnValue; - this.returnValue = returnValue; - const preventClose = !this.dispatchEvent(new Event('close', { cancelable: true })); - if (preventClose) { - this.returnValue = prevReturnValue; - return; - } - await this.animateDialog(this.getCloseAnimation()); - dialog.close(returnValue); - this.open = false; - this.dispatchEvent(new Event('closed')); - } - connectedCallback() { - super.connectedCallback(); - this.isConnectedPromiseResolve(); - } - disconnectedCallback() { - super.disconnectedCallback(); - this.isConnectedPromise = this.getIsConnectedPromise(); - } - render() { - const scrollable = this.open && !(this.isAtScrollTop && this.isAtScrollBottom); - const classes = { - 'has-headline': this.hasHeadline, - 'has-actions': this.hasActions, - 'has-icon': this.hasIcon, - 'scrollable': scrollable, - 'show-top-divider': scrollable && !this.isAtScrollTop, - 'show-bottom-divider': scrollable && !this.isAtScrollBottom, - }; - // The focus trap sentinels are only added after the dialog opens, since - // dialog.showModal() will try to autofocus them, even with tabindex="-1". - const showFocusTrap = this.open && !this.noFocusTrap; - const focusTrap = (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) ` - - `; - const { ariaLabel } = this; - return (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) ` -
    - - ${showFocusTrap ? focusTrap : lit__WEBPACK_IMPORTED_MODULE_1__.nothing} -
    -
    - -

    - -

    - -
    -
    -
    -
    - -
    -
    -
    -
    - - -
    -
    - ${showFocusTrap ? focusTrap : lit__WEBPACK_IMPORTED_MODULE_1__.nothing} -
    - `; - } - firstUpdated() { - this.intersectionObserver = new IntersectionObserver((entries) => { - for (const entry of entries) { - this.handleAnchorIntersection(entry); - } - }, { root: this.scroller }); - this.intersectionObserver.observe(this.topAnchor); - this.intersectionObserver.observe(this.bottomAnchor); - } - handleDialogClick() { - if (this.nextClickIsFromContent) { - // Avoid doing a layout calculation below if we know the click came from - // content. - this.nextClickIsFromContent = false; - return; - } - // Click originated on the backdrop. Native ``s will not cancel, - // but Material dialogs do. - const preventDefault = !this.dispatchEvent(new Event('cancel', { cancelable: true })); - if (preventDefault) { - return; - } - this.close(); - } - handleContentClick() { - this.nextClickIsFromContent = true; - } - handleSubmit(event) { - const form = event.target; - const { submitter } = event; - if (form.getAttribute('method') !== 'dialog' || !submitter) { - return; - } - // Close reason is the submitter's value attribute, or the dialog's - // `returnValue` if there is no attribute. - this.close(submitter.getAttribute('value') ?? this.returnValue); - } - handleCancel(event) { - if (event.target !== this.dialog) { - // Ignore any cancel events dispatched by content. - return; - } - this.escapePressedWithoutCancel = false; - const preventDefault = !(0,_internal_events_redispatch_event_js__WEBPACK_IMPORTED_MODULE_5__.redispatchEvent)(this, event); - // We always prevent default on the original dialog event since we'll - // animate closing it before it actually closes. - event.preventDefault(); - if (preventDefault) { - return; - } - this.close(); - } - handleClose() { - if (!this.escapePressedWithoutCancel) { - return; - } - this.escapePressedWithoutCancel = false; - this.dialog?.dispatchEvent(new Event('cancel', { cancelable: true })); - } - handleKeydown(event) { - if (event.key !== 'Escape') { - return; - } - // An escape key was pressed. If a "close" event fires next without a - // "cancel" event first, then we know we're in the Chrome v120 bug. - this.escapePressedWithoutCancel = true; - // Wait a full task for the cancel/close event listeners to fire, then - // reset the flag. - setTimeout(() => { - this.escapePressedWithoutCancel = false; - }); - } - async animateDialog(animation) { - // Always cancel the previous animations. Animations can include `fill` - // modes that need to be cleared when `quick` is toggled. If not, content - // that faded out will remain hidden when a `quick` dialog re-opens after - // previously opening and closing without `quick`. - this.cancelAnimations?.abort(); - this.cancelAnimations = new AbortController(); - if (this.quick) { - return; - } - const { dialog, scrim, container, headline, content, actions } = this; - if (!dialog || !scrim || !container || !headline || !content || !actions) { - return; - } - const { container: containerAnimate, dialog: dialogAnimate, scrim: scrimAnimate, headline: headlineAnimate, content: contentAnimate, actions: actionsAnimate, } = animation; - const elementAndAnimation = [ - [dialog, dialogAnimate ?? []], - [scrim, scrimAnimate ?? []], - [container, containerAnimate ?? []], - [headline, headlineAnimate ?? []], - [content, contentAnimate ?? []], - [actions, actionsAnimate ?? []], - ]; - const animations = []; - for (const [element, animation] of elementAndAnimation) { - for (const animateArgs of animation) { - const animation = element.animate(...animateArgs); - this.cancelAnimations.signal.addEventListener('abort', () => { - animation.cancel(); - }); - animations.push(animation); - } - } - await Promise.all(animations.map((animation) => animation.finished.catch(() => { - // Ignore intentional AbortErrors when calling `animation.cancel()`. - }))); - } - handleHeadlineChange(event) { - const slot = event.target; - this.hasHeadline = slot.assignedElements().length > 0; - } - handleActionsChange(event) { - const slot = event.target; - this.hasActions = slot.assignedElements().length > 0; - } - handleIconChange(event) { - const slot = event.target; - this.hasIcon = slot.assignedElements().length > 0; - } - handleAnchorIntersection(entry) { - const { target, isIntersecting } = entry; - if (target === this.topAnchor) { - this.isAtScrollTop = isIntersecting; - } - if (target === this.bottomAnchor) { - this.isAtScrollBottom = isIntersecting; - } - } - getIsConnectedPromise() { - return new Promise((resolve) => { - this.isConnectedPromiseResolve = resolve; - }); - } - handleFocusTrapFocus(event) { - const [firstFocusableChild, lastFocusableChild] = this.getFirstAndLastFocusableChildren(); - if (!firstFocusableChild || !lastFocusableChild) { - // When a dialog does not have focusable children, the dialog itself - // receives focus. - this.dialog?.focus(); - return; - } - // To determine which child to focus, we need to know which focus trap - // received focus... - const isFirstFocusTrap = event.target === this.firstFocusTrap; - const isLastFocusTrap = !isFirstFocusTrap; - // ...and where the focus came from (what was previously focused). - const focusCameFromFirstChild = event.relatedTarget === firstFocusableChild; - const focusCameFromLastChild = event.relatedTarget === lastFocusableChild; - // Although this is a focus trap, focus can come from outside the trap. - // This can happen when elements are programmatically `focus()`'d. It also - // happens when focus leaves and returns to the window, such as clicking on - // the browser's URL bar and pressing Tab, or switching focus between - // iframes. - const focusCameFromOutsideDialog = !focusCameFromFirstChild && !focusCameFromLastChild; - // Focus the dialog's first child when we reach the end of the dialog and - // focus is moving forward. Or, when focus is moving forwards into the - // dialog from outside of the window. - const shouldFocusFirstChild = (isLastFocusTrap && focusCameFromLastChild) || - (isFirstFocusTrap && focusCameFromOutsideDialog); - if (shouldFocusFirstChild) { - firstFocusableChild.focus(); - return; - } - // Focus the dialog's last child when we reach the beginning of the dialog - // and focus is moving backward. Or, when focus is moving backwards into the - // dialog from outside of the window. - const shouldFocusLastChild = (isFirstFocusTrap && focusCameFromFirstChild) || - (isLastFocusTrap && focusCameFromOutsideDialog); - if (shouldFocusLastChild) { - lastFocusableChild.focus(); - return; - } - // The booleans above are verbose for readability, but code executation - // won't actually reach here. - } - getFirstAndLastFocusableChildren() { - if (!this.treewalker) { - return [null, null]; - } - let firstFocusableChild = null; - let lastFocusableChild = null; - // Reset the current node back to the root host element. - this.treewalker.currentNode = this.treewalker.root; - while (this.treewalker.nextNode()) { - // Cast as Element since the TreeWalker filter only accepts Elements. - const nextChild = this.treewalker.currentNode; - if (!isFocusable(nextChild)) { - continue; - } - if (!firstFocusableChild) { - firstFocusableChild = nextChild; - } - lastFocusableChild = nextChild; - } - // We set lastFocusableChild immediately after finding a - // firstFocusableChild, which means the pair is either both null or both - // non-null. Cast since TypeScript does not recognize this. - return [firstFocusableChild, lastFocusableChild]; - } -} -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean }) -], Dialog.prototype, "open", null); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean }) -], Dialog.prototype, "quick", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ attribute: false }) -], Dialog.prototype, "returnValue", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)() -], Dialog.prototype, "type", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean, attribute: 'no-focus-trap' }) -], Dialog.prototype, "noFocusTrap", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('dialog') -], Dialog.prototype, "dialog", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.scrim') -], Dialog.prototype, "scrim", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.container') -], Dialog.prototype, "container", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.headline') -], Dialog.prototype, "headline", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.content') -], Dialog.prototype, "content", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.actions') -], Dialog.prototype, "actions", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Dialog.prototype, "isAtScrollTop", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Dialog.prototype, "isAtScrollBottom", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.scroller') -], Dialog.prototype, "scroller", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.top.anchor') -], Dialog.prototype, "topAnchor", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.bottom.anchor') -], Dialog.prototype, "bottomAnchor", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.focus-trap') -], Dialog.prototype, "firstFocusTrap", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Dialog.prototype, "hasHeadline", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Dialog.prototype, "hasActions", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_7__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Dialog.prototype, "hasIcon", void 0); -function isFocusable(element) { - // Check if the element is a known built-in focusable element: - // - and with `href` attributes. - // - Form controls that are not disabled. - // - `contenteditable` elements. - // - Anything with a non-negative `tabindex`. - const knownFocusableElements = ':is(button,input,select,textarea,object,:is(a,area)[href],[tabindex],[contenteditable=true])'; - const notDisabled = ':not(:disabled,[disabled])'; - const notNegativeTabIndex = ':not([tabindex^="-"])'; - if (element.matches(knownFocusableElements + notDisabled + notNegativeTabIndex)) { - return true; - } - const isCustomElement = element.localName.includes('-'); - if (!isCustomElement) { - return false; - } - // If a custom element does not have a tabindex, it may still be focusable - // if it delegates focus with a shadow root. We also need to check again if - // the custom element is a disabled form control. - if (!element.matches(notDisabled)) { - return false; - } - return element.shadowRoot?.delegatesFocus ?? false; -} -//# sourceMappingURL=dialog.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/divider/divider.js": -/*!*******************************************************!*\ - !*** ./node_modules/@material/web/divider/divider.js ***! - \*******************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ MdDivider: () => (/* binding */ MdDivider) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _internal_divider_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./internal/divider.js */ "./node_modules/@material/web/divider/internal/divider.js"); -/* harmony import */ var _internal_divider_styles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal/divider-styles.js */ "./node_modules/@material/web/divider/internal/divider-styles.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - -/** - * @summary A divider is a thin line that groups content in lists and - * containers. - * - * @description Dividers can reinforce tapability, such as when used to separate - * list items or define tappable regions in an accordion. - * - * @final - * @suppress {visibility} - */ -let MdDivider = class MdDivider extends _internal_divider_js__WEBPACK_IMPORTED_MODULE_1__.Divider { -}; -MdDivider.styles = [_internal_divider_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles]; -MdDivider = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__.customElement)('md-divider') -], MdDivider); - -//# sourceMappingURL=divider.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/divider/internal/divider-styles.js": -/*!***********************************************************************!*\ - !*** ./node_modules/@material/web/divider/internal/divider-styles.js ***! - \***********************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./divider/internal/divider-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{box-sizing:border-box;color:var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));display:flex;height:var(--md-divider-thickness, 1px);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:"";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}} -`; -//# sourceMappingURL=divider-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/divider/internal/divider.js": -/*!****************************************************************!*\ - !*** ./node_modules/@material/web/divider/internal/divider.js ***! - \****************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Divider: () => (/* binding */ Divider) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - -/** - * A divider component. - */ -class Divider extends lit__WEBPACK_IMPORTED_MODULE_0__.LitElement { - constructor() { - super(...arguments); - /** - * Indents the divider with equal padding on both sides. - */ - this.inset = false; - /** - * Indents the divider with padding on the leading side. - */ - this.insetStart = false; - /** - * Indents the divider with padding on the trailing side. - */ - this.insetEnd = false; - } -} -(0,tslib__WEBPACK_IMPORTED_MODULE_2__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true }) -], Divider.prototype, "inset", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_2__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true, attribute: 'inset-start' }) -], Divider.prototype, "insetStart", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_2__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true, attribute: 'inset-end' }) -], Divider.prototype, "insetEnd", void 0); -//# sourceMappingURL=divider.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/focus/internal/focus-ring-styles.js": -/*!************************************************************************!*\ - !*** ./node_modules/@material/web/focus/internal/focus-ring-styles.js ***! - \************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./focus/internal/focus-ring-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{animation-delay:0s,calc(var(--md-focus-ring-duration, 600ms)*.25);animation-duration:calc(var(--md-focus-ring-duration, 600ms)*.25),calc(var(--md-focus-ring-duration, 600ms)*.75);animation-timing-function:cubic-bezier(0.2, 0, 0, 1);box-sizing:border-box;color:var(--md-focus-ring-color, var(--md-sys-color-secondary, #625b71));display:none;pointer-events:none;position:absolute}:host([visible]){display:flex}:host(:not([inward])){animation-name:outward-grow,outward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));inset:calc(-1*var(--md-focus-ring-outward-offset, 2px));outline:var(--md-focus-ring-width, 3px) solid currentColor}:host([inward]){animation-name:inward-grow,inward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border:var(--md-focus-ring-width, 3px) solid currentColor;inset:var(--md-focus-ring-inward-offset, 0px)}@keyframes outward-grow{from{outline-width:0}to{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes outward-shrink{from{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-grow{from{border-width:0}to{border-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-shrink{from{border-width:var(--md-focus-ring-active-width, 8px)}}@media(prefers-reduced-motion){:host{animation:none}} -`; -//# sourceMappingURL=focus-ring-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/focus/internal/focus-ring.js": -/*!*****************************************************************!*\ - !*** ./node_modules/@material/web/focus/internal/focus-ring.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ FocusRing: () => (/* binding */ FocusRing) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _internal_controller_attachable_controller_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../internal/controller/attachable-controller.js */ "./node_modules/@material/web/internal/controller/attachable-controller.js"); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - -/** - * Events that the focus ring listens to. - */ -const EVENTS = ['focusin', 'focusout', 'pointerdown']; -/** - * A focus ring component. - * - * @fires visibility-changed {Event} Fired whenever `visible` changes. - */ -class FocusRing extends lit__WEBPACK_IMPORTED_MODULE_0__.LitElement { - constructor() { - super(...arguments); - /** - * Makes the focus ring visible. - */ - this.visible = false; - /** - * Makes the focus ring animate inwards instead of outwards. - */ - this.inward = false; - this.attachableController = new _internal_controller_attachable_controller_js__WEBPACK_IMPORTED_MODULE_2__.AttachableController(this, this.onControlChange.bind(this)); - } - get htmlFor() { - return this.attachableController.htmlFor; - } - set htmlFor(htmlFor) { - this.attachableController.htmlFor = htmlFor; - } - get control() { - return this.attachableController.control; - } - set control(control) { - this.attachableController.control = control; - } - attach(control) { - this.attachableController.attach(control); - } - detach() { - this.attachableController.detach(); - } - connectedCallback() { - super.connectedCallback(); - // Needed for VoiceOver, which will create a "group" if the element is a - // sibling to other content. - this.setAttribute('aria-hidden', 'true'); - } - /** @private */ - handleEvent(event) { - if (event[HANDLED_BY_FOCUS_RING]) { - // This ensures the focus ring does not activate when multiple focus rings - // are used within a single component. - return; - } - switch (event.type) { - default: - return; - case 'focusin': - this.visible = this.control?.matches(':focus-visible') ?? false; - break; - case 'focusout': - case 'pointerdown': - this.visible = false; - break; - } - event[HANDLED_BY_FOCUS_RING] = true; - } - onControlChange(prev, next) { - if (lit__WEBPACK_IMPORTED_MODULE_0__.isServer) - return; - for (const event of EVENTS) { - prev?.removeEventListener(event, this); - next?.addEventListener(event, this); - } - } - update(changed) { - if (changed.has('visible')) { - // This logic can be removed once the `:has` selector has been introduced - // to Firefox. This is necessary to allow correct submenu styles. - this.dispatchEvent(new Event('visibility-changed')); - } - super.update(changed); - } -} -(0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true }) -], FocusRing.prototype, "visible", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true }) -], FocusRing.prototype, "inward", void 0); -const HANDLED_BY_FOCUS_RING = Symbol('handledByFocusRing'); -//# sourceMappingURL=focus-ring.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/focus/md-focus-ring.js": -/*!***********************************************************!*\ - !*** ./node_modules/@material/web/focus/md-focus-ring.js ***! - \***********************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ MdFocusRing: () => (/* binding */ MdFocusRing) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _internal_focus_ring_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./internal/focus-ring.js */ "./node_modules/@material/web/focus/internal/focus-ring.js"); -/* harmony import */ var _internal_focus_ring_styles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal/focus-ring-styles.js */ "./node_modules/@material/web/focus/internal/focus-ring-styles.js"); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - -/** - * TODO(b/267336424): add docs - * - * @final - * @suppress {visibility} - */ -let MdFocusRing = class MdFocusRing extends _internal_focus_ring_js__WEBPACK_IMPORTED_MODULE_1__.FocusRing { -}; -MdFocusRing.styles = [_internal_focus_ring_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles]; -MdFocusRing = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__.customElement)('md-focus-ring') -], MdFocusRing); - -//# sourceMappingURL=md-focus-ring.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/internal/aria/aria.js": -/*!**********************************************************!*\ - !*** ./node_modules/@material/web/internal/aria/aria.js ***! - \**********************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ARIA_ATTRIBUTES: () => (/* binding */ ARIA_ATTRIBUTES), -/* harmony export */ ARIA_PROPERTIES: () => (/* binding */ ARIA_PROPERTIES), -/* harmony export */ ariaPropertyToAttribute: () => (/* binding */ ariaPropertyToAttribute), -/* harmony export */ isAriaAttribute: () => (/* binding */ isAriaAttribute) -/* harmony export */ }); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * Accessibility Object Model reflective aria properties. - */ -const ARIA_PROPERTIES = [ - 'role', - 'ariaAtomic', - 'ariaAutoComplete', - 'ariaBusy', - 'ariaChecked', - 'ariaColCount', - 'ariaColIndex', - 'ariaColSpan', - 'ariaCurrent', - 'ariaDisabled', - 'ariaExpanded', - 'ariaHasPopup', - 'ariaHidden', - 'ariaInvalid', - 'ariaKeyShortcuts', - 'ariaLabel', - 'ariaLevel', - 'ariaLive', - 'ariaModal', - 'ariaMultiLine', - 'ariaMultiSelectable', - 'ariaOrientation', - 'ariaPlaceholder', - 'ariaPosInSet', - 'ariaPressed', - 'ariaReadOnly', - 'ariaRequired', - 'ariaRoleDescription', - 'ariaRowCount', - 'ariaRowIndex', - 'ariaRowSpan', - 'ariaSelected', - 'ariaSetSize', - 'ariaSort', - 'ariaValueMax', - 'ariaValueMin', - 'ariaValueNow', - 'ariaValueText', -]; -/** - * Accessibility Object Model aria attributes. - */ -const ARIA_ATTRIBUTES = ARIA_PROPERTIES.map(ariaPropertyToAttribute); -/** - * Checks if an attribute is one of the AOM aria attributes. - * - * @example - * isAriaAttribute('aria-label'); // true - * - * @param attribute The attribute to check. - * @return True if the attribute is an aria attribute, or false if not. - */ -function isAriaAttribute(attribute) { - return ARIA_ATTRIBUTES.includes(attribute); -} -/** - * Converts an AOM aria property into its corresponding attribute. - * - * @example - * ariaPropertyToAttribute('ariaLabel'); // 'aria-label' - * - * @param property The aria property. - * @return The aria attribute. - */ -function ariaPropertyToAttribute(property) { - return property - .replace('aria', 'aria-') - // IDREF attributes also include an "Element" or "Elements" suffix - .replace(/Elements?/g, '') - .toLowerCase(); -} -//# sourceMappingURL=aria.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/internal/aria/delegate.js": -/*!**************************************************************!*\ - !*** ./node_modules/@material/web/internal/aria/delegate.js ***! - \**************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ mixinDelegatesAria: () => (/* binding */ mixinDelegatesAria) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var _aria_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./aria.js */ "./node_modules/@material/web/internal/aria/aria.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - -// Private symbols -const privateIgnoreAttributeChangesFor = Symbol('privateIgnoreAttributeChangesFor'); -/** - * Mixes in aria delegation for elements that delegate focus and aria to inner - * shadow root elements. - * - * This mixin fixes invalid aria announcements with shadow roots, caused by - * duplicate aria attributes on both the host and the inner shadow root element. - * - * Note: this mixin **does not yet support** ID reference attributes, such as - * `aria-labelledby` or `aria-controls`. - * - * @example - * ```ts - * class MyButton extends mixinDelegatesAria(LitElement) { - * static shadowRootOptions = {mode: 'open', delegatesFocus: true}; - * - * render() { - * return html` - * - * `; - * } - * } - * ``` - * ```html - * +1 - * ``` - * - * Use `ARIAMixinStrict` for lit analyzer strict types, such as the "role" - * attribute. - * - * @example - * ```ts - * return html` - * - * `; - * ``` - * - * In the future, updates to the Accessibility Object Model (AOM) will provide - * built-in aria delegation features that will replace this mixin. - * - * @param base The class to mix functionality into. - * @return The provided class with aria delegation mixed in. - */ -function mixinDelegatesAria(base) { - var _a; - if (lit__WEBPACK_IMPORTED_MODULE_0__.isServer) { - // Don't shift attributes when running with lit-ssr. The SSR renderer - // implements a subset of DOM APIs, including the methods this mixin - // overrides, causing errors. We don't need to shift on the server anyway - // since elements will shift attributes immediately once they hydrate. - return base; - } - class WithDelegatesAriaElement extends base { - constructor() { - super(...arguments); - this[_a] = new Set(); - } - attributeChangedCallback(name, oldValue, newValue) { - if (!(0,_aria_js__WEBPACK_IMPORTED_MODULE_1__.isAriaAttribute)(name)) { - super.attributeChangedCallback(name, oldValue, newValue); - return; - } - if (this[privateIgnoreAttributeChangesFor].has(name)) { - return; - } - // Don't trigger another `attributeChangedCallback` once we remove the - // aria attribute from the host. We check the explicit name of the - // attribute to ignore since `attributeChangedCallback` can be called - // multiple times out of an expected order when hydrating an element with - // multiple attributes. - this[privateIgnoreAttributeChangesFor].add(name); - this.removeAttribute(name); - this[privateIgnoreAttributeChangesFor].delete(name); - const dataProperty = ariaAttributeToDataProperty(name); - if (newValue === null) { - delete this.dataset[dataProperty]; - } - else { - this.dataset[dataProperty] = newValue; - } - this.requestUpdate(ariaAttributeToDataProperty(name), oldValue); - } - getAttribute(name) { - if ((0,_aria_js__WEBPACK_IMPORTED_MODULE_1__.isAriaAttribute)(name)) { - return super.getAttribute(ariaAttributeToDataAttribute(name)); - } - return super.getAttribute(name); - } - removeAttribute(name) { - super.removeAttribute(name); - if ((0,_aria_js__WEBPACK_IMPORTED_MODULE_1__.isAriaAttribute)(name)) { - super.removeAttribute(ariaAttributeToDataAttribute(name)); - // Since `aria-*` attributes are already removed`, we need to request - // an update because `attributeChangedCallback` will not be called. - this.requestUpdate(); - } - } - } - _a = privateIgnoreAttributeChangesFor; - setupDelegatesAriaProperties(WithDelegatesAriaElement); - return WithDelegatesAriaElement; -} -/** - * Overrides the constructor's native `ARIAMixin` properties to ensure that - * aria properties reflect the values that were shifted to a data attribute. - * - * @param ctor The `ReactiveElement` constructor to patch. - */ -function setupDelegatesAriaProperties(ctor) { - for (const ariaProperty of _aria_js__WEBPACK_IMPORTED_MODULE_1__.ARIA_PROPERTIES) { - // The casing between ariaProperty and the dataProperty may be different. - // ex: aria-haspopup -> ariaHasPopup - const ariaAttribute = (0,_aria_js__WEBPACK_IMPORTED_MODULE_1__.ariaPropertyToAttribute)(ariaProperty); - // ex: aria-haspopup -> data-aria-haspopup - const dataAttribute = ariaAttributeToDataAttribute(ariaAttribute); - // ex: aria-haspopup -> dataset.ariaHaspopup - const dataProperty = ariaAttributeToDataProperty(ariaAttribute); - // Call `ReactiveElement.createProperty()` so that the `aria-*` and `data-*` - // attributes are added to the `static observedAttributes` array. This - // triggers `attributeChangedCallback` for the delegates aria mixin to - // handle. - ctor.createProperty(ariaProperty, { - attribute: ariaAttribute, - noAccessor: true, - }); - ctor.createProperty(Symbol(dataAttribute), { - attribute: dataAttribute, - noAccessor: true, - }); - // Re-define the `ARIAMixin` properties to handle data attribute shifting. - // It is safe to use `Object.defineProperty` here because the properties - // are native and not renamed. - // tslint:disable-next-line:ban-unsafe-reflection - Object.defineProperty(ctor.prototype, ariaProperty, { - configurable: true, - enumerable: true, - get() { - return this.dataset[dataProperty] ?? null; - }, - set(value) { - const prevValue = this.dataset[dataProperty] ?? null; - if (value === prevValue) { - return; - } - if (value === null) { - delete this.dataset[dataProperty]; - } - else { - this.dataset[dataProperty] = value; - } - this.requestUpdate(ariaProperty, prevValue); - }, - }); - } -} -function ariaAttributeToDataAttribute(ariaAttribute) { - // aria-haspopup -> data-aria-haspopup - return `data-${ariaAttribute}`; -} -function ariaAttributeToDataProperty(ariaAttribute) { - // aria-haspopup -> dataset.ariaHaspopup - return ariaAttribute.replace(/-\w/, (dashLetter) => dashLetter[1].toUpperCase()); -} -//# sourceMappingURL=delegate.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/internal/controller/attachable-controller.js": -/*!*********************************************************************************!*\ - !*** ./node_modules/@material/web/internal/controller/attachable-controller.js ***! - \*********************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ AttachableController: () => (/* binding */ AttachableController) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * A key to retrieve an `Attachable` element's `AttachableController` from a - * global `MutationObserver`. - */ -const ATTACHABLE_CONTROLLER = Symbol('attachableController'); -let FOR_ATTRIBUTE_OBSERVER; -if (!lit__WEBPACK_IMPORTED_MODULE_0__.isServer) { - /** - * A global `MutationObserver` that reacts to `for` attribute changes on - * `Attachable` elements. If the `for` attribute changes, the controller will - * re-attach to the new referenced element. - */ - FOR_ATTRIBUTE_OBSERVER = new MutationObserver((records) => { - for (const record of records) { - // When a control's `for` attribute changes, inform its - // `AttachableController` to update to a new control. - record.target[ATTACHABLE_CONTROLLER]?.hostConnected(); - } - }); -} -/** - * A controller that provides an implementation for `Attachable` elements. - * - * @example - * ```ts - * class MyElement extends LitElement implements Attachable { - * get control() { return this.attachableController.control; } - * - * private readonly attachableController = new AttachableController( - * this, - * (previousControl, newControl) => { - * previousControl?.removeEventListener('click', this.handleClick); - * newControl?.addEventListener('click', this.handleClick); - * } - * ); - * - * // Implement remaining `Attachable` properties/methods that call the - * // controller's properties/methods. - * } - * ``` - */ -class AttachableController { - get htmlFor() { - return this.host.getAttribute('for'); - } - set htmlFor(htmlFor) { - if (htmlFor === null) { - this.host.removeAttribute('for'); - } - else { - this.host.setAttribute('for', htmlFor); - } - } - get control() { - if (this.host.hasAttribute('for')) { - if (!this.htmlFor || !this.host.isConnected) { - return null; - } - return this.host.getRootNode().querySelector(`#${this.htmlFor}`); - } - return this.currentControl || this.host.parentElement; - } - set control(control) { - if (control) { - this.attach(control); - } - else { - this.detach(); - } - } - /** - * Creates a new controller for an `Attachable` element. - * - * @param host The `Attachable` element. - * @param onControlChange A callback with two parameters for the previous and - * next control. An `Attachable` element may perform setup or teardown - * logic whenever the control changes. - */ - constructor(host, onControlChange) { - this.host = host; - this.onControlChange = onControlChange; - this.currentControl = null; - host.addController(this); - host[ATTACHABLE_CONTROLLER] = this; - FOR_ATTRIBUTE_OBSERVER?.observe(host, { attributeFilter: ['for'] }); - } - attach(control) { - if (control === this.currentControl) { - return; - } - this.setCurrentControl(control); - // When imperatively attaching, remove the `for` attribute so - // that the attached control is used instead of a referenced one. - this.host.removeAttribute('for'); - } - detach() { - this.setCurrentControl(null); - // When imperatively detaching, add an empty `for=""` attribute. This will - // ensure the control is `null` rather than the `parentElement`. - this.host.setAttribute('for', ''); - } - /** @private */ - hostConnected() { - this.setCurrentControl(this.control); - } - /** @private */ - hostDisconnected() { - this.setCurrentControl(null); - } - setCurrentControl(control) { - this.onControlChange(this.currentControl, control); - this.currentControl = control; - } -} -//# sourceMappingURL=attachable-controller.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/internal/controller/form-submitter.js": -/*!**************************************************************************!*\ - !*** ./node_modules/@material/web/internal/controller/form-submitter.js ***! - \**************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ setupFormSubmitter: () => (/* binding */ setupFormSubmitter) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var _labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../labs/behaviors/element-internals.js */ "./node_modules/@material/web/labs/behaviors/element-internals.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - -/** - * Sets up an element's constructor to enable form submission. The element - * instance should be form associated and have a `type` property. - * - * A click listener is added to each element instance. If the click is not - * default prevented, it will submit the element's form, if any. - * - * @example - * ```ts - * class MyElement extends mixinElementInternals(LitElement) { - * static { - * setupFormSubmitter(MyElement); - * } - * - * static formAssociated = true; - * - * type: FormSubmitterType = 'submit'; - * } - * ``` - * - * @param ctor The form submitter element's constructor. - */ -function setupFormSubmitter(ctor) { - if (lit__WEBPACK_IMPORTED_MODULE_0__.isServer) { - return; - } - ctor.addInitializer((instance) => { - const submitter = instance; - submitter.addEventListener('click', async (event) => { - const { type, [_labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_1__.internals]: elementInternals } = submitter; - const { form } = elementInternals; - if (!form || type === 'button') { - return; - } - // Wait a full task for event bubbling to complete. - await new Promise((resolve) => { - setTimeout(resolve); - }); - if (event.defaultPrevented) { - return; - } - if (type === 'reset') { - form.reset(); - return; - } - // form.requestSubmit(submitter) does not work with form associated custom - // elements. This patches the dispatched submit event to add the correct - // `submitter`. - // See https://github.com/WICG/webcomponents/issues/814 - form.addEventListener('submit', (submitEvent) => { - Object.defineProperty(submitEvent, 'submitter', { - configurable: true, - enumerable: true, - get: () => submitter, - }); - }, { capture: true, once: true }); - elementInternals.setFormValue(submitter.value); - form.requestSubmit(); - }); - }); -} -//# sourceMappingURL=form-submitter.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/internal/events/form-label-activation.js": -/*!*****************************************************************************!*\ - !*** ./node_modules/@material/web/internal/events/form-label-activation.js ***! - \*****************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ dispatchActivationClick: () => (/* binding */ dispatchActivationClick), -/* harmony export */ isActivationClick: () => (/* binding */ isActivationClick) -/* harmony export */ }); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * Dispatches a click event to the given element that triggers a native action, - * but is not composed and therefore is not seen outside the element. - * - * This is useful for responding to an external click event on the host element - * that should trigger an internal action like a button click. - * - * Note, a helper is provided because setting this up correctly is a bit tricky. - * In particular, calling `click` on an element creates a composed event, which - * is not desirable, and a manually dispatched event must specifically be a - * `MouseEvent` to trigger a native action. - * - * @example - * hostClickListener = (event: MouseEvent) { - * if (isActivationClick(event)) { - * this.dispatchActivationClick(this.buttonElement); - * } - * } - * - */ -function dispatchActivationClick(element) { - const event = new MouseEvent('click', { bubbles: true }); - element.dispatchEvent(event); - return event; -} -/** - * Returns true if the click event should trigger an activation behavior. The - * behavior is defined by the element and is whatever it should do when - * clicked. - * - * Typically when an element needs to handle a click, the click is generated - * from within the element and an event listener within the element implements - * the needed behavior; however, it's possible to fire a click directly - * at the element that the element should handle. This method helps - * distinguish these "external" clicks. - * - * An "external" click can be triggered in a number of ways: via a click - * on an associated label for a form associated element, calling - * `element.click()`, or calling - * `element.dispatchEvent(new MouseEvent('click', ...))`. - * - * Also works around Firefox issue - * https://bugzilla.mozilla.org/show_bug.cgi?id=1804576 by squelching - * events for a microtask after called. - * - * @example - * hostClickListener = (event: MouseEvent) { - * if (isActivationClick(event)) { - * this.dispatchActivationClick(this.buttonElement); - * } - * } - * - */ -function isActivationClick(event) { - // Event must start at the event target. - if (event.currentTarget !== event.target) { - return false; - } - // Event must not be retargeted from shadowRoot. - if (event.composedPath()[0] !== event.target) { - return false; - } - // Target must not be disabled; this should only occur for a synthetically - // dispatched click. - if (event.target.disabled) { - return false; - } - // This is an activation if the event should not be squelched. - return !squelchEvent(event); -} -// TODO(https://bugzilla.mozilla.org/show_bug.cgi?id=1804576) -// Remove when Firefox bug is addressed. -function squelchEvent(event) { - const squelched = isSquelchingEvents; - if (squelched) { - event.preventDefault(); - event.stopImmediatePropagation(); - } - squelchEventsForMicrotask(); - return squelched; -} -// Ignore events for one microtask only. -let isSquelchingEvents = false; -async function squelchEventsForMicrotask() { - isSquelchingEvents = true; - // Need to pause for just one microtask. - // tslint:disable-next-line - await null; - isSquelchingEvents = false; -} -//# sourceMappingURL=form-label-activation.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/internal/events/redispatch-event.js": -/*!************************************************************************!*\ - !*** ./node_modules/@material/web/internal/events/redispatch-event.js ***! - \************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ redispatchEvent: () => (/* binding */ redispatchEvent) -/* harmony export */ }); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * Re-dispatches an event from the provided element. - * - * This function is useful for forwarding non-composed events, such as `change` - * events. - * - * @example - * class MyInput extends LitElement { - * render() { - * return html``; - * } - * - * protected redispatchEvent(event: Event) { - * redispatchEvent(this, event); - * } - * } - * - * @param element The element to dispatch the event from. - * @param event The event to re-dispatch. - * @return Whether or not the event was dispatched (if cancelable). - */ -function redispatchEvent(element, event) { - // For bubbling events in SSR light DOM (or composed), stop their propagation - // and dispatch the copy. - if (event.bubbles && (!element.shadowRoot || event.composed)) { - event.stopPropagation(); - } - const copy = Reflect.construct(event.constructor, [event.type, event]); - const dispatched = element.dispatchEvent(copy); - if (!dispatched) { - event.preventDefault(); - } - return dispatched; -} -//# sourceMappingURL=redispatch-event.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/internal/motion/animation.js": -/*!*****************************************************************!*\ - !*** ./node_modules/@material/web/internal/motion/animation.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EASING: () => (/* binding */ EASING), -/* harmony export */ createAnimationSignal: () => (/* binding */ createAnimationSignal), -/* harmony export */ createThrottle: () => (/* binding */ createThrottle), -/* harmony export */ msFromTimeCSSValue: () => (/* binding */ msFromTimeCSSValue) -/* harmony export */ }); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * Easing functions to use for web animations. - * - * **NOTE:** `EASING.EMPHASIZED` is approximated with unknown accuracy. - * - * TODO(b/241113345): replace with tokens - */ -const EASING = { - STANDARD: 'cubic-bezier(0.2, 0, 0, 1)', - STANDARD_ACCELERATE: 'cubic-bezier(.3,0,1,1)', - STANDARD_DECELERATE: 'cubic-bezier(0,0,0,1)', - EMPHASIZED: 'cubic-bezier(.3,0,0,1)', - EMPHASIZED_ACCELERATE: 'cubic-bezier(.3,0,.8,.15)', - EMPHASIZED_DECELERATE: 'cubic-bezier(.05,.7,.1,1)', -}; -/** - * Creates an `AnimationSignal` that can be used to cancel a previous task. - * - * @example - * class MyClass { - * private labelAnimationSignal = createAnimationSignal(); - * - * private async animateLabel() { - * // Start of the task. Previous tasks will be canceled. - * const signal = this.labelAnimationSignal.start(); - * - * // Do async work... - * if (signal.aborted) { - * // Use AbortSignal to check if a request was made to abort after some - * // asynchronous work. - * return; - * } - * - * const animation = this.animate(...); - * // Add event listeners to be notified when the task should be canceled. - * signal.addEventListener('abort', () => { - * animation.cancel(); - * }); - * - * animation.addEventListener('finish', () => { - * // Tell the signal that the current task is finished. - * this.labelAnimationSignal.finish(); - * }); - * } - * } - * - * @return An `AnimationSignal`. - */ -function createAnimationSignal() { - // The current animation's AbortController - let animationAbortController = null; - return { - start() { - // Tell the previous animation to cancel. - animationAbortController?.abort(); - // Set up a new AbortController for the current animation. - animationAbortController = new AbortController(); - // Provide the AbortSignal so that the caller can check aborted status - // and add listeners. - return animationAbortController.signal; - }, - finish() { - animationAbortController = null; - }, - }; -} -/** - * Returns a function which can be used to throttle function calls - * mapped to a key via a given function that should produce a promise that - * determines the throttle amount (defaults to requestAnimationFrame). - */ -function createThrottle() { - const stack = new Set(); - return async (key = '', cb, timeout = async () => { - await new Promise(requestAnimationFrame); - }) => { - if (!stack.has(key)) { - stack.add(key); - await timeout(); - if (stack.has(key)) { - stack.delete(key); - cb(); - } - } - }; -} -/** - * Parses an number in milliseconds from a css time value - */ -function msFromTimeCSSValue(value) { - const match = value.trim().match(/([\d.]+)(\s*s$)?/); - const time = match?.[1]; - const seconds = match?.[2]; - return Number(time ?? 0) * (seconds ? 1000 : 1); -} -//# sourceMappingURL=animation.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/labs/behaviors/element-internals.js": -/*!************************************************************************!*\ - !*** ./node_modules/@material/web/labs/behaviors/element-internals.js ***! - \************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ internals: () => (/* binding */ internals), -/* harmony export */ mixinElementInternals: () => (/* binding */ mixinElementInternals) -/* harmony export */ }); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * A unique symbol used for protected access to an instance's - * `ElementInternals`. - * - * @example - * ```ts - * class MyElement extends mixinElementInternals(LitElement) { - * constructor() { - * super(); - * this[internals].role = 'button'; - * } - * } - * ``` - */ -const internals = Symbol('internals'); -// Private symbols -const privateInternals = Symbol('privateInternals'); -/** - * Mixes in an attached `ElementInternals` instance. - * - * This mixin is only needed when other shared code needs access to a - * component's `ElementInternals`, such as form-associated mixins. - * - * @param base The class to mix functionality into. - * @return The provided class with `WithElementInternals` mixed in. - */ -function mixinElementInternals(base) { - class WithElementInternalsElement extends base { - get [internals]() { - // Create internals in getter so that it can be used in methods called on - // construction in `ReactiveElement`, such as `requestUpdate()`. - if (!this[privateInternals]) { - // Cast needed for closure - this[privateInternals] = this.attachInternals(); - } - return this[privateInternals]; - } - } - return WithElementInternalsElement; -} -//# sourceMappingURL=element-internals.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/ripple/internal/ripple-styles.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@material/web/ripple/internal/ripple-styles.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./ripple/internal/ripple-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{display:flex;margin:auto;pointer-events:none}:host([disabled]){display:none}@media(forced-colors: active){:host{display:none}}:host,.surface{border-radius:inherit;position:absolute;inset:0;overflow:hidden}.surface{-webkit-tap-highlight-color:rgba(0,0,0,0)}.surface::before,.surface::after{content:"";opacity:0;position:absolute}.surface::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));inset:0;transition:opacity 15ms linear,background-color 15ms linear}.surface::after{background:radial-gradient(closest-side, var(--md-ripple-pressed-color, var(--md-sys-color-on-surface, #1d1b20)) max(100% - 70px, 65%), transparent 100%);transform-origin:center center;transition:opacity 375ms linear}.hovered::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-ripple-hover-opacity, 0.08)}.pressed::after{opacity:var(--md-ripple-pressed-opacity, 0.12);transition-duration:105ms} -`; -//# sourceMappingURL=ripple-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/ripple/internal/ripple.js": -/*!**************************************************************!*\ - !*** ./node_modules/@material/web/ripple/internal/ripple.js ***! - \**************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Ripple: () => (/* binding */ Ripple) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lit/directives/class-map.js */ "./node_modules/lit/directives/class-map.js"); -/* harmony import */ var _internal_controller_attachable_controller_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../internal/controller/attachable-controller.js */ "./node_modules/@material/web/internal/controller/attachable-controller.js"); -/* harmony import */ var _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../internal/motion/animation.js */ "./node_modules/@material/web/internal/motion/animation.js"); -/** - * @license - * Copyright 2022 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - - -const PRESS_GROW_MS = 450; -const MINIMUM_PRESS_MS = 225; -const INITIAL_ORIGIN_SCALE = 0.2; -const PADDING = 10; -const SOFT_EDGE_MINIMUM_SIZE = 75; -const SOFT_EDGE_CONTAINER_RATIO = 0.35; -const PRESS_PSEUDO = '::after'; -const ANIMATION_FILL = 'forwards'; -/** - * Interaction states for the ripple. - * - * On Touch: - * - `INACTIVE -> TOUCH_DELAY -> WAITING_FOR_CLICK -> INACTIVE` - * - `INACTIVE -> TOUCH_DELAY -> HOLDING -> WAITING_FOR_CLICK -> INACTIVE` - * - * On Mouse or Pen: - * - `INACTIVE -> WAITING_FOR_CLICK -> INACTIVE` - */ -var State; -(function (State) { - /** - * Initial state of the control, no touch in progress. - * - * Transitions: - * - on touch down: transition to `TOUCH_DELAY`. - * - on mouse down: transition to `WAITING_FOR_CLICK`. - */ - State[State["INACTIVE"] = 0] = "INACTIVE"; - /** - * Touch down has been received, waiting to determine if it's a swipe or - * scroll. - * - * Transitions: - * - on touch up: begin press; transition to `WAITING_FOR_CLICK`. - * - on cancel: transition to `INACTIVE`. - * - after `TOUCH_DELAY_MS`: begin press; transition to `HOLDING`. - */ - State[State["TOUCH_DELAY"] = 1] = "TOUCH_DELAY"; - /** - * A touch has been deemed to be a press - * - * Transitions: - * - on up: transition to `WAITING_FOR_CLICK`. - */ - State[State["HOLDING"] = 2] = "HOLDING"; - /** - * The user touch has finished, transition into rest state. - * - * Transitions: - * - on click end press; transition to `INACTIVE`. - */ - State[State["WAITING_FOR_CLICK"] = 3] = "WAITING_FOR_CLICK"; -})(State || (State = {})); -/** - * Events that the ripple listens to. - */ -const EVENTS = [ - 'click', - 'contextmenu', - 'pointercancel', - 'pointerdown', - 'pointerenter', - 'pointerleave', - 'pointerup', -]; -/** - * Delay reacting to touch so that we do not show the ripple for a swipe or - * scroll interaction. - */ -const TOUCH_DELAY_MS = 150; -/** - * Used to detect if HCM is active. Events do not process during HCM when the - * ripple is not displayed. - */ -const FORCED_COLORS = lit__WEBPACK_IMPORTED_MODULE_0__.isServer - ? null - : window.matchMedia('(forced-colors: active)'); -/** - * A ripple component. - */ -class Ripple extends lit__WEBPACK_IMPORTED_MODULE_0__.LitElement { - constructor() { - super(...arguments); - /** - * Disables the ripple. - */ - this.disabled = false; - this.hovered = false; - this.pressed = false; - this.rippleSize = ''; - this.rippleScale = ''; - this.initialSize = 0; - this.state = State.INACTIVE; - this.checkBoundsAfterContextMenu = false; - this.attachableController = new _internal_controller_attachable_controller_js__WEBPACK_IMPORTED_MODULE_3__.AttachableController(this, this.onControlChange.bind(this)); - } - get htmlFor() { - return this.attachableController.htmlFor; - } - set htmlFor(htmlFor) { - this.attachableController.htmlFor = htmlFor; - } - get control() { - return this.attachableController.control; - } - set control(control) { - this.attachableController.control = control; - } - attach(control) { - this.attachableController.attach(control); - } - detach() { - this.attachableController.detach(); - } - connectedCallback() { - super.connectedCallback(); - // Needed for VoiceOver, which will create a "group" if the element is a - // sibling to other content. - this.setAttribute('aria-hidden', 'true'); - } - render() { - const classes = { - 'hovered': this.hovered, - 'pressed': this.pressed, - }; - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `
    `; - } - update(changedProps) { - if (changedProps.has('disabled') && this.disabled) { - this.hovered = false; - this.pressed = false; - } - super.update(changedProps); - } - /** - * TODO(b/269799771): make private - * @private only public for slider - */ - handlePointerenter(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.hovered = true; - } - /** - * TODO(b/269799771): make private - * @private only public for slider - */ - handlePointerleave(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.hovered = false; - // release a held mouse or pen press that moves outside the element - if (this.state !== State.INACTIVE) { - this.endPressAnimation(); - } - } - handlePointerup(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - if (this.state === State.HOLDING) { - this.state = State.WAITING_FOR_CLICK; - return; - } - if (this.state === State.TOUCH_DELAY) { - this.state = State.WAITING_FOR_CLICK; - this.startPressAnimation(this.rippleStartEvent); - return; - } - } - async handlePointerdown(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.rippleStartEvent = event; - if (!this.isTouch(event)) { - this.state = State.WAITING_FOR_CLICK; - this.startPressAnimation(event); - return; - } - // after a longpress contextmenu event, an extra `pointerdown` can be - // dispatched to the pressed element. Check that the down is within - // bounds of the element in this case. - if (this.checkBoundsAfterContextMenu && !this.inBounds(event)) { - return; - } - this.checkBoundsAfterContextMenu = false; - // Wait for a hold after touch delay - this.state = State.TOUCH_DELAY; - await new Promise((resolve) => { - setTimeout(resolve, TOUCH_DELAY_MS); - }); - if (this.state !== State.TOUCH_DELAY) { - return; - } - this.state = State.HOLDING; - this.startPressAnimation(event); - } - handleClick() { - // Click is a MouseEvent in Firefox and Safari, so we cannot use - // `shouldReactToEvent` - if (this.disabled) { - return; - } - if (this.state === State.WAITING_FOR_CLICK) { - this.endPressAnimation(); - return; - } - if (this.state === State.INACTIVE) { - // keyboard synthesized click event - this.startPressAnimation(); - this.endPressAnimation(); - } - } - handlePointercancel(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.endPressAnimation(); - } - handleContextmenu() { - if (this.disabled) { - return; - } - this.checkBoundsAfterContextMenu = true; - this.endPressAnimation(); - } - determineRippleSize() { - const { height, width } = this.getBoundingClientRect(); - const maxDim = Math.max(height, width); - const softEdgeSize = Math.max(SOFT_EDGE_CONTAINER_RATIO * maxDim, SOFT_EDGE_MINIMUM_SIZE); - const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE); - const hypotenuse = Math.sqrt(width ** 2 + height ** 2); - const maxRadius = hypotenuse + PADDING; - this.initialSize = initialSize; - this.rippleScale = `${(maxRadius + softEdgeSize) / initialSize}`; - this.rippleSize = `${initialSize}px`; - } - getNormalizedPointerEventCoords(pointerEvent) { - const { scrollX, scrollY } = window; - const { left, top } = this.getBoundingClientRect(); - const documentX = scrollX + left; - const documentY = scrollY + top; - const { pageX, pageY } = pointerEvent; - return { x: pageX - documentX, y: pageY - documentY }; - } - getTranslationCoordinates(positionEvent) { - const { height, width } = this.getBoundingClientRect(); - // end in the center - const endPoint = { - x: (width - this.initialSize) / 2, - y: (height - this.initialSize) / 2, - }; - let startPoint; - if (positionEvent instanceof PointerEvent) { - startPoint = this.getNormalizedPointerEventCoords(positionEvent); - } - else { - startPoint = { - x: width / 2, - y: height / 2, - }; - } - // center around start point - startPoint = { - x: startPoint.x - this.initialSize / 2, - y: startPoint.y - this.initialSize / 2, - }; - return { startPoint, endPoint }; - } - startPressAnimation(positionEvent) { - if (!this.mdRoot) { - return; - } - this.pressed = true; - this.growAnimation?.cancel(); - this.determineRippleSize(); - const { startPoint, endPoint } = this.getTranslationCoordinates(positionEvent); - const translateStart = `${startPoint.x}px, ${startPoint.y}px`; - const translateEnd = `${endPoint.x}px, ${endPoint.y}px`; - this.growAnimation = this.mdRoot.animate({ - top: [0, 0], - left: [0, 0], - height: [this.rippleSize, this.rippleSize], - width: [this.rippleSize, this.rippleSize], - transform: [ - `translate(${translateStart}) scale(1)`, - `translate(${translateEnd}) scale(${this.rippleScale})`, - ], - }, { - pseudoElement: PRESS_PSEUDO, - duration: PRESS_GROW_MS, - easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_4__.EASING.STANDARD, - fill: ANIMATION_FILL, - }); - } - async endPressAnimation() { - this.rippleStartEvent = undefined; - this.state = State.INACTIVE; - const animation = this.growAnimation; - let pressAnimationPlayState = Infinity; - if (typeof animation?.currentTime === 'number') { - pressAnimationPlayState = animation.currentTime; - } - else if (animation?.currentTime) { - pressAnimationPlayState = animation.currentTime.to('ms').value; - } - if (pressAnimationPlayState >= MINIMUM_PRESS_MS) { - this.pressed = false; - return; - } - await new Promise((resolve) => { - setTimeout(resolve, MINIMUM_PRESS_MS - pressAnimationPlayState); - }); - if (this.growAnimation !== animation) { - // A new press animation was started. The old animation was canceled and - // should not finish the pressed state. - return; - } - this.pressed = false; - } - /** - * Returns `true` if - * - the ripple element is enabled - * - the pointer is primary for the input type - * - the pointer is the pointer that started the interaction, or will start - * the interaction - * - the pointer is a touch, or the pointer state has the primary button - * held, or the pointer is hovering - */ - shouldReactToEvent(event) { - if (this.disabled || !event.isPrimary) { - return false; - } - if (this.rippleStartEvent && - this.rippleStartEvent.pointerId !== event.pointerId) { - return false; - } - if (event.type === 'pointerenter' || event.type === 'pointerleave') { - return !this.isTouch(event); - } - const isPrimaryButton = event.buttons === 1; - return this.isTouch(event) || isPrimaryButton; - } - /** - * Check if the event is within the bounds of the element. - * - * This is only needed for the "stuck" contextmenu longpress on Chrome. - */ - inBounds({ x, y }) { - const { top, left, bottom, right } = this.getBoundingClientRect(); - return x >= left && x <= right && y >= top && y <= bottom; - } - isTouch({ pointerType }) { - return pointerType === 'touch'; - } - /** @private */ - async handleEvent(event) { - if (FORCED_COLORS?.matches) { - // Skip event logic since the ripple is `display: none`. - return; - } - switch (event.type) { - case 'click': - this.handleClick(); - break; - case 'contextmenu': - this.handleContextmenu(); - break; - case 'pointercancel': - this.handlePointercancel(event); - break; - case 'pointerdown': - await this.handlePointerdown(event); - break; - case 'pointerenter': - this.handlePointerenter(event); - break; - case 'pointerleave': - this.handlePointerleave(event); - break; - case 'pointerup': - this.handlePointerup(event); - break; - default: - break; - } - } - onControlChange(prev, next) { - if (lit__WEBPACK_IMPORTED_MODULE_0__.isServer) - return; - for (const event of EVENTS) { - prev?.removeEventListener(event, this); - next?.addEventListener(event, this); - } - } -} -(0,tslib__WEBPACK_IMPORTED_MODULE_5__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true }) -], Ripple.prototype, "disabled", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_5__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], Ripple.prototype, "hovered", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_5__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], Ripple.prototype, "pressed", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_5__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.query)('.surface') -], Ripple.prototype, "mdRoot", void 0); -//# sourceMappingURL=ripple.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/ripple/ripple.js": -/*!*****************************************************!*\ - !*** ./node_modules/@material/web/ripple/ripple.js ***! - \*****************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ MdRipple: () => (/* binding */ MdRipple) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _internal_ripple_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./internal/ripple.js */ "./node_modules/@material/web/ripple/internal/ripple.js"); -/* harmony import */ var _internal_ripple_styles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal/ripple-styles.js */ "./node_modules/@material/web/ripple/internal/ripple-styles.js"); -/** - * @license - * Copyright 2022 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - -/** - * @summary Ripples, also known as state layers, are visual indicators used to - * communicate the status of a component or interactive element. - * - * @description A state layer is a semi-transparent covering on an element that - * indicates its state. State layers provide a systematic approach to - * visualizing states by using opacity. A layer can be applied to an entire - * element or in a circular shape and only one state layer can be applied at a - * given time. - * - * @final - * @suppress {visibility} - */ -let MdRipple = class MdRipple extends _internal_ripple_js__WEBPACK_IMPORTED_MODULE_1__.Ripple { -}; -MdRipple.styles = [_internal_ripple_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles]; -MdRipple = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__.customElement)('md-ripple') -], MdRipple); - -//# sourceMappingURL=ripple.js.map - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-dialog.js": -/*!*****************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-dialog.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwDialog: () => (/* binding */ EwDialog) -/* harmony export */ }); -/* harmony import */ var _material_web_dialog_internal_dialog_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/dialog/internal/dialog.js */ "./node_modules/@material/web/dialog/internal/dialog.js"); -/* harmony import */ var _material_web_dialog_internal_dialog_styles_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/dialog/internal/dialog-styles.js */ "./node_modules/@material/web/dialog/internal/dialog-styles.js"); - - -class EwDialog extends _material_web_dialog_internal_dialog_js__WEBPACK_IMPORTED_MODULE_0__.Dialog { -} -EwDialog.styles = [_material_web_dialog_internal_dialog_styles_js__WEBPACK_IMPORTED_MODULE_1__.styles]; -customElements.define("ew-dialog", EwDialog); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-text-button.js": -/*!**********************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-text-button.js ***! - \**********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwTextButton: () => (/* binding */ EwTextButton) -/* harmony export */ }); -/* harmony import */ var _material_web_button_internal_shared_styles_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/button/internal/shared-styles.js */ "./node_modules/@material/web/button/internal/shared-styles.js"); -/* harmony import */ var _material_web_button_internal_text_button_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/button/internal/text-button.js */ "./node_modules/@material/web/button/internal/text-button.js"); -/* harmony import */ var _material_web_button_internal_text_styles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material/web/button/internal/text-styles.js */ "./node_modules/@material/web/button/internal/text-styles.js"); - - - -class EwTextButton extends _material_web_button_internal_text_button_js__WEBPACK_IMPORTED_MODULE_1__.TextButton { -} -EwTextButton.styles = [_material_web_button_internal_shared_styles_js__WEBPACK_IMPORTED_MODULE_0__.styles, _material_web_button_internal_text_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles]; -customElements.define("ew-text-button", EwTextButton); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/styles.js": -/*!***************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/styles.js ***! - \***************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ dialogStyles: () => (/* binding */ dialogStyles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); - -// We set font-size to 16px and all the mdc typography styles -// because it defaults to rem, which means that the font-size -// of the host website would influence the ESP Web Tools dialog. -const dialogStyles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) ` - :host { - --roboto-font: Roboto, system-ui; - --text-color: rgba(0, 0, 0, 0.6); - --danger-color: #db4437; - - --md-sys-color-primary: #03a9f4; - --md-sys-color-on-primary: #fff; - --md-ref-typeface-brand: var(--roboto-font); - --md-ref-typeface-plain: var(--roboto-font); - - --md-sys-color-surface: #fff; - --md-sys-color-surface-container: #fff; - --md-sys-color-surface-container-high: #fff; - --md-sys-color-surface-container-highest: #f5f5f5; - --md-sys-color-secondary-container: #e0e0e0; - - --md-sys-typescale-headline-font: var(--roboto-font); - --md-sys-typescale-title-font: var(--roboto-font); - } - - a { - color: var(--md-sys-color-primary); - } -`; - - -/***/ }), - -/***/ "./node_modules/lit-element/development/lit-element.js": -/*!*************************************************************!*\ - !*** ./node_modules/lit-element/development/lit-element.js ***! - \*************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ CSSResult: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.CSSResult), -/* harmony export */ LitElement: () => (/* binding */ LitElement), -/* harmony export */ ReactiveElement: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.ReactiveElement), -/* harmony export */ _$LE: () => (/* binding */ _$LE), -/* harmony export */ _$LH: () => (/* reexport safe */ lit_html__WEBPACK_IMPORTED_MODULE_1__._$LH), -/* harmony export */ adoptStyles: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.adoptStyles), -/* harmony export */ css: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.css), -/* harmony export */ defaultConverter: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.defaultConverter), -/* harmony export */ getCompatibleStyle: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.getCompatibleStyle), -/* harmony export */ html: () => (/* reexport safe */ lit_html__WEBPACK_IMPORTED_MODULE_1__.html), -/* harmony export */ mathml: () => (/* reexport safe */ lit_html__WEBPACK_IMPORTED_MODULE_1__.mathml), -/* harmony export */ noChange: () => (/* reexport safe */ lit_html__WEBPACK_IMPORTED_MODULE_1__.noChange), -/* harmony export */ notEqual: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.notEqual), -/* harmony export */ nothing: () => (/* reexport safe */ lit_html__WEBPACK_IMPORTED_MODULE_1__.nothing), -/* harmony export */ render: () => (/* reexport safe */ lit_html__WEBPACK_IMPORTED_MODULE_1__.render), -/* harmony export */ supportsAdoptingStyleSheets: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.supportsAdoptingStyleSheets), -/* harmony export */ svg: () => (/* reexport safe */ lit_html__WEBPACK_IMPORTED_MODULE_1__.svg), -/* harmony export */ unsafeCSS: () => (/* reexport safe */ _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.unsafeCSS) -/* harmony export */ }); -/* harmony import */ var _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @lit/reactive-element */ "./node_modules/@lit/reactive-element/development/reactive-element.js"); -/* harmony import */ var lit_html__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit-html */ "./node_modules/lit-html/development/lit-html.js"); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/** - * The main LitElement module, which defines the {@linkcode LitElement} base - * class and related APIs. - * - * LitElement components can define a template and a set of observed - * properties. Changing an observed property triggers a re-render of the - * element. - * - * Import {@linkcode LitElement} and {@linkcode html} from this module to - * create a component: - * - * ```js - * import {LitElement, html} from 'lit-element'; - * - * class MyElement extends LitElement { - * - * // Declare observed properties - * static get properties() { - * return { - * adjective: {} - * } - * } - * - * constructor() { - * this.adjective = 'awesome'; - * } - * - * // Define the element's template - * render() { - * return html`

    your ${adjective} template here

    `; - * } - * } - * - * customElements.define('my-element', MyElement); - * ``` - * - * `LitElement` extends {@linkcode ReactiveElement} and adds lit-html - * templating. The `ReactiveElement` class is provided for users that want to - * build their own custom element base classes that don't use lit-html. - * - * @packageDocumentation - */ - - - - -/* - * When using Closure Compiler, JSCompiler_renameProperty(property, object) is - * replaced at compile time by the munged name for object[property]. We cannot - * alias this function, so we have to use a small shim that has the same - * behavior when not compiling. - */ -/*@__INLINE__*/ -const JSCompiler_renameProperty = (prop, _obj) => prop; -const DEV_MODE = true; -// Allows minifiers to rename references to globalThis -const global = globalThis; -let issueWarning; -if (DEV_MODE) { - // Ensure warnings are issued only 1x, even if multiple versions of Lit - // are loaded. - global.litIssuedWarnings ??= new Set(); - /** - * Issue a warning if we haven't already, based either on `code` or `warning`. - * Warnings are disabled automatically only by `warning`; disabling via `code` - * can be done by users. - */ - issueWarning = (code, warning) => { - warning += ` See https://lit.dev/msg/${code} for more information.`; - if (!global.litIssuedWarnings.has(warning) && - !global.litIssuedWarnings.has(code)) { - console.warn(warning); - global.litIssuedWarnings.add(warning); - } - }; -} -/** - * Base element class that manages element properties and attributes, and - * renders a lit-html template. - * - * To define a component, subclass `LitElement` and implement a - * `render` method to provide the component's template. Define properties - * using the {@linkcode LitElement.properties properties} property or the - * {@linkcode property} decorator. - */ -class LitElement extends _lit_reactive_element__WEBPACK_IMPORTED_MODULE_0__.ReactiveElement { - constructor() { - super(...arguments); - /** - * @category rendering - */ - this.renderOptions = { host: this }; - this.__childPart = undefined; - } - /** - * @category rendering - */ - createRenderRoot() { - const renderRoot = super.createRenderRoot(); - // When adoptedStyleSheets are shimmed, they are inserted into the - // shadowRoot by createRenderRoot. Adjust the renderBefore node so that - // any styles in Lit content render before adoptedStyleSheets. This is - // important so that adoptedStyleSheets have precedence over styles in - // the shadowRoot. - this.renderOptions.renderBefore ??= renderRoot.firstChild; - return renderRoot; - } - /** - * Updates the element. This method reflects property values to attributes - * and calls `render` to render DOM via lit-html. Setting properties inside - * this method will *not* trigger another update. - * @param changedProperties Map of changed properties with old values - * @category updates - */ - update(changedProperties) { - // Setting properties in `render` should not trigger an update. Since - // updates are allowed after super.update, it's important to call `render` - // before that. - const value = this.render(); - if (!this.hasUpdated) { - this.renderOptions.isConnected = this.isConnected; - } - super.update(changedProperties); - this.__childPart = (0,lit_html__WEBPACK_IMPORTED_MODULE_1__.render)(value, this.renderRoot, this.renderOptions); - } - /** - * Invoked when the component is added to the document's DOM. - * - * In `connectedCallback()` you should setup tasks that should only occur when - * the element is connected to the document. The most common of these is - * adding event listeners to nodes external to the element, like a keydown - * event handler added to the window. - * - * ```ts - * connectedCallback() { - * super.connectedCallback(); - * addEventListener('keydown', this._handleKeydown); - * } - * ``` - * - * Typically, anything done in `connectedCallback()` should be undone when the - * element is disconnected, in `disconnectedCallback()`. - * - * @category lifecycle - */ - connectedCallback() { - super.connectedCallback(); - this.__childPart?.setConnected(true); - } - /** - * Invoked when the component is removed from the document's DOM. - * - * This callback is the main signal to the element that it may no longer be - * used. `disconnectedCallback()` should ensure that nothing is holding a - * reference to the element (such as event listeners added to nodes external - * to the element), so that it is free to be garbage collected. - * - * ```ts - * disconnectedCallback() { - * super.disconnectedCallback(); - * window.removeEventListener('keydown', this._handleKeydown); - * } - * ``` - * - * An element may be re-connected after being disconnected. - * - * @category lifecycle - */ - disconnectedCallback() { - super.disconnectedCallback(); - this.__childPart?.setConnected(false); - } - /** - * Invoked on each update to perform rendering tasks. This method may return - * any value renderable by lit-html's `ChildPart` - typically a - * `TemplateResult`. Setting properties inside this method will *not* trigger - * the element to update. - * @category rendering - */ - render() { - return lit_html__WEBPACK_IMPORTED_MODULE_1__.noChange; - } -} -// This property needs to remain unminified. -LitElement['_$litElement$'] = true; -/** - * Ensure this class is marked as `finalized` as an optimization ensuring - * it will not needlessly try to `finalize`. - * - * Note this property name is a string to prevent breaking Closure JS Compiler - * optimizations. See @lit/reactive-element for more information. - */ -LitElement[JSCompiler_renameProperty('finalized', LitElement)] = true; -// Install hydration if available -global.litElementHydrateSupport?.({ LitElement }); -// Apply polyfills if available -const polyfillSupport = DEV_MODE - ? global.litElementPolyfillSupportDevMode - : global.litElementPolyfillSupport; -polyfillSupport?.({ LitElement }); -/** - * END USERS SHOULD NOT RELY ON THIS OBJECT. - * - * Private exports for use by other Lit packages, not intended for use by - * external users. - * - * We currently do not make a mangled rollup build of the lit-ssr code. In order - * to keep a number of (otherwise private) top-level exports mangled in the - * client side code, we export a _$LE object containing those members (or - * helper methods for accessing private fields of those members), and then - * re-export them for use in lit-ssr. This keeps lit-ssr agnostic to whether the - * client-side code is being used in `dev` mode or `prod` mode. - * - * This has a unique name, to disambiguate it from private exports in - * lit-html, since this module re-exports all of lit-html. - * - * @private - */ -const _$LE = { - _$attributeToProperty: (el, name, value) => { - // eslint-disable-next-line - el._$attributeToProperty(name, value); - }, - // eslint-disable-next-line - _$changedProperties: (el) => el._$changedProperties, -}; -// IMPORTANT: do not change the property name or the assignment expression. -// This line will be used in regexes to search for LitElement usage. -(global.litElementVersions ??= []).push('4.2.0'); -if (DEV_MODE && global.litElementVersions.length > 1) { - queueMicrotask(() => { - issueWarning('multiple-versions', `Multiple versions of Lit loaded. Loading multiple versions ` + - `is not recommended.`); - }); -} -//# sourceMappingURL=lit-element.js.map - -/***/ }), - -/***/ "./node_modules/lit-html/development/directive.js": -/*!********************************************************!*\ - !*** ./node_modules/lit-html/development/directive.js ***! - \********************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Directive: () => (/* binding */ Directive), -/* harmony export */ PartType: () => (/* binding */ PartType), -/* harmony export */ directive: () => (/* binding */ directive) -/* harmony export */ }); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -const PartType = { - ATTRIBUTE: 1, - CHILD: 2, - PROPERTY: 3, - BOOLEAN_ATTRIBUTE: 4, - EVENT: 5, - ELEMENT: 6, -}; -/** - * Creates a user-facing directive function from a Directive class. This - * function has the same parameters as the directive's render() method. - */ -const directive = (c) => (...values) => ({ - // This property needs to remain unminified. - ['_$litDirective$']: c, - values, -}); -/** - * Base class for creating custom directives. Users should extend this class, - * implement `render` and/or `update`, and then pass their subclass to - * `directive`. - */ -class Directive { - constructor(_partInfo) { } - // See comment in Disconnectable interface for why this is a getter - get _$isConnected() { - return this._$parent._$isConnected; - } - /** @internal */ - _$initialize(part, parent, attributeIndex) { - this.__part = part; - this._$parent = parent; - this.__attributeIndex = attributeIndex; - } - /** @internal */ - _$resolve(part, props) { - return this.update(part, props); - } - update(_part, props) { - return this.render(...props); - } -} -//# sourceMappingURL=directive.js.map - -/***/ }), - -/***/ "./node_modules/lit-html/development/directives/class-map.js": -/*!*******************************************************************!*\ - !*** ./node_modules/lit-html/development/directives/class-map.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ classMap: () => (/* binding */ classMap) -/* harmony export */ }); -/* harmony import */ var _lit_html_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../lit-html.js */ "./node_modules/lit-html/development/lit-html.js"); -/* harmony import */ var _directive_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../directive.js */ "./node_modules/lit-html/development/directive.js"); -/** - * @license - * Copyright 2018 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - - -class ClassMapDirective extends _directive_js__WEBPACK_IMPORTED_MODULE_1__.Directive { - constructor(partInfo) { - super(partInfo); - if (partInfo.type !== _directive_js__WEBPACK_IMPORTED_MODULE_1__.PartType.ATTRIBUTE || - partInfo.name !== 'class' || - partInfo.strings?.length > 2) { - throw new Error('`classMap()` can only be used in the `class` attribute ' + - 'and must be the only part in the attribute.'); - } - } - render(classInfo) { - // Add spaces to ensure separation from static classes - return (' ' + - Object.keys(classInfo) - .filter((key) => classInfo[key]) - .join(' ') + - ' '); - } - update(part, [classInfo]) { - // Remember dynamic classes on the first render - if (this._previousClasses === undefined) { - this._previousClasses = new Set(); - if (part.strings !== undefined) { - this._staticClasses = new Set(part.strings - .join(' ') - .split(/\s/) - .filter((s) => s !== '')); - } - for (const name in classInfo) { - if (classInfo[name] && !this._staticClasses?.has(name)) { - this._previousClasses.add(name); - } - } - return this.render(classInfo); - } - const classList = part.element.classList; - // Remove old classes that no longer apply - for (const name of this._previousClasses) { - if (!(name in classInfo)) { - classList.remove(name); - this._previousClasses.delete(name); - } - } - // Add or remove classes based on their classMap value - for (const name in classInfo) { - // We explicitly want a loose truthy check of `value` because it seems - // more convenient that '' and 0 are skipped. - const value = !!classInfo[name]; - if (value !== this._previousClasses.has(name) && - !this._staticClasses?.has(name)) { - if (value) { - classList.add(name); - this._previousClasses.add(name); - } - else { - classList.remove(name); - this._previousClasses.delete(name); - } - } - } - return _lit_html_js__WEBPACK_IMPORTED_MODULE_0__.noChange; - } -} -/** - * A directive that applies dynamic CSS classes. - * - * This must be used in the `class` attribute and must be the only part used in - * the attribute. It takes each property in the `classInfo` argument and adds - * the property name to the element's `classList` if the property value is - * truthy; if the property value is falsy, the property name is removed from - * the element's `class`. - * - * For example `{foo: bar}` applies the class `foo` if the value of `bar` is - * truthy. - * - * @param classInfo - */ -const classMap = (0,_directive_js__WEBPACK_IMPORTED_MODULE_1__.directive)(ClassMapDirective); -//# sourceMappingURL=class-map.js.map - -/***/ }), - -/***/ "./node_modules/lit-html/development/is-server.js": -/*!********************************************************!*\ - !*** ./node_modules/lit-html/development/is-server.js ***! - \********************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ isServer: () => (/* binding */ isServer) -/* harmony export */ }); -/** - * @license - * Copyright 2022 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -/** - * @fileoverview - * - * This file exports a boolean const whose value will depend on what environment - * the module is being imported from. - */ -const NODE_MODE = false; -/** - * A boolean that will be `true` in server environments like Node, and `false` - * in browser environments. Note that your server environment or toolchain must - * support the `"node"` export condition for this to be `true`. - * - * This can be used when authoring components to change behavior based on - * whether or not the component is executing in an SSR context. - */ -const isServer = NODE_MODE; -//# sourceMappingURL=is-server.js.map - -/***/ }), - -/***/ "./node_modules/lit-html/development/lit-html.js": -/*!*******************************************************!*\ - !*** ./node_modules/lit-html/development/lit-html.js ***! - \*******************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ _$LH: () => (/* binding */ _$LH), -/* harmony export */ html: () => (/* binding */ html), -/* harmony export */ mathml: () => (/* binding */ mathml), -/* harmony export */ noChange: () => (/* binding */ noChange), -/* harmony export */ nothing: () => (/* binding */ nothing), -/* harmony export */ render: () => (/* binding */ render), -/* harmony export */ svg: () => (/* binding */ svg) -/* harmony export */ }); -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -const DEV_MODE = true; -const ENABLE_EXTRA_SECURITY_HOOKS = true; -const ENABLE_SHADYDOM_NOPATCH = true; -const NODE_MODE = false; -// Allows minifiers to rename references to globalThis -const global = globalThis; -/** - * Useful for visualizing and logging insights into what the Lit template system is doing. - * - * Compiled out of prod mode builds. - */ -const debugLogEvent = DEV_MODE - ? (event) => { - const shouldEmit = global - .emitLitDebugLogEvents; - if (!shouldEmit) { - return; - } - global.dispatchEvent(new CustomEvent('lit-debug', { - detail: event, - })); - } - : undefined; -// Used for connecting beginRender and endRender events when there are nested -// renders when errors are thrown preventing an endRender event from being -// called. -let debugLogRenderId = 0; -let issueWarning; -if (DEV_MODE) { - global.litIssuedWarnings ??= new Set(); - /** - * Issue a warning if we haven't already, based either on `code` or `warning`. - * Warnings are disabled automatically only by `warning`; disabling via `code` - * can be done by users. - */ - issueWarning = (code, warning) => { - warning += code - ? ` See https://lit.dev/msg/${code} for more information.` - : ''; - if (!global.litIssuedWarnings.has(warning) && - !global.litIssuedWarnings.has(code)) { - console.warn(warning); - global.litIssuedWarnings.add(warning); - } - }; - queueMicrotask(() => { - issueWarning('dev-mode', `Lit is in dev mode. Not recommended for production!`); - }); -} -const wrap = ENABLE_SHADYDOM_NOPATCH && - global.ShadyDOM?.inUse && - global.ShadyDOM?.noPatch === true - ? global.ShadyDOM.wrap - : (node) => node; -const trustedTypes = global.trustedTypes; -/** - * Our TrustedTypePolicy for HTML which is declared using the html template - * tag function. - * - * That HTML is a developer-authored constant, and is parsed with innerHTML - * before any untrusted expressions have been mixed in. Therefor it is - * considered safe by construction. - */ -const policy = trustedTypes - ? trustedTypes.createPolicy('lit-html', { - createHTML: (s) => s, - }) - : undefined; -const identityFunction = (value) => value; -const noopSanitizer = (_node, _name, _type) => identityFunction; -/** Sets the global sanitizer factory. */ -const setSanitizer = (newSanitizer) => { - if (!ENABLE_EXTRA_SECURITY_HOOKS) { - return; - } - if (sanitizerFactoryInternal !== noopSanitizer) { - throw new Error(`Attempted to overwrite existing lit-html security policy.` + - ` setSanitizeDOMValueFactory should be called at most once.`); - } - sanitizerFactoryInternal = newSanitizer; -}; -/** - * Only used in internal tests, not a part of the public API. - */ -const _testOnlyClearSanitizerFactoryDoNotCallOrElse = () => { - sanitizerFactoryInternal = noopSanitizer; -}; -const createSanitizer = (node, name, type) => { - return sanitizerFactoryInternal(node, name, type); -}; -// Added to an attribute name to mark the attribute as bound so we can find -// it easily. -const boundAttributeSuffix = '$lit$'; -// This marker is used in many syntactic positions in HTML, so it must be -// a valid element name and attribute name. We don't support dynamic names (yet) -// but this at least ensures that the parse tree is closer to the template -// intention. -const marker = `lit$${Math.random().toFixed(9).slice(2)}$`; -// String used to tell if a comment is a marker comment -const markerMatch = '?' + marker; -// Text used to insert a comment marker node. We use processing instruction -// syntax because it's slightly smaller, but parses as a comment node. -const nodeMarker = `<${markerMatch}>`; -const d = NODE_MODE && global.document === undefined - ? { - createTreeWalker() { - return {}; - }, - } - : document; -// Creates a dynamic marker. We never have to search for these in the DOM. -const createMarker = () => d.createComment(''); -const isPrimitive = (value) => value === null || (typeof value != 'object' && typeof value != 'function'); -const isArray = Array.isArray; -const isIterable = (value) => isArray(value) || - // eslint-disable-next-line @typescript-eslint/no-explicit-any - typeof value?.[Symbol.iterator] === 'function'; -const SPACE_CHAR = `[ \t\n\f\r]`; -const ATTR_VALUE_CHAR = `[^ \t\n\f\r"'\`<>=]`; -const NAME_CHAR = `[^\\s"'>=/]`; -// These regexes represent the five parsing states that we care about in the -// Template's HTML scanner. They match the *end* of the state they're named -// after. -// Depending on the match, we transition to a new state. If there's no match, -// we stay in the same state. -// Note that the regexes are stateful. We utilize lastIndex and sync it -// across the multiple regexes used. In addition to the five regexes below -// we also dynamically create a regex to find the matching end tags for raw -// text elements. -/** - * End of text is: `<` followed by: - * (comment start) or (tag) or (dynamic tag binding) - */ -const textEndRegex = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g; -const COMMENT_START = 1; -const TAG_NAME = 2; -const DYNAMIC_TAG_NAME = 3; -const commentEndRegex = /-->/g; -/** - * Comments not started with - * - * image - *
    Overline
    - *
    Headline
    - * Supporting text - * Trailing - * image - *
    - * ``` - * - * When wrapping ``, forward the available slots to use the same slot - * structure for the wrapping component (this is what `` does). - * - * @example - * ```html - * - * - * - * - * - * - * - * - * - * ``` - * - * @final - * @suppress {visibility} - */ -let MdItem = class MdItem extends _internal_item_js__WEBPACK_IMPORTED_MODULE_1__.Item { -}; -MdItem.styles = [_internal_item_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles]; -MdItem = (0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__.customElement)('md-item') -], MdItem); - -//# sourceMappingURL=item.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/list/internal/list-controller.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@material/web/list/internal/list-controller.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ListController: () => (/* binding */ ListController), -/* harmony export */ NavigableKeys: () => (/* binding */ NavigableKeys) -/* harmony export */ }); -/* harmony import */ var _list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./list-navigation-helpers.js */ "./node_modules/@material/web/list/internal/list-navigation-helpers.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -// TODO: move this file to List and make List use this -/** - * Default keys that trigger navigation. - */ -// tslint:disable:enforce-name-casing Following Enum style -const NavigableKeys = { - ArrowDown: 'ArrowDown', - ArrowLeft: 'ArrowLeft', - ArrowUp: 'ArrowUp', - ArrowRight: 'ArrowRight', - Home: 'Home', - End: 'End', -}; -/** - * A controller that handles list keyboard navigation and item management. - */ -class ListController { - constructor(config) { - /** - * Handles keyboard navigation. Should be bound to the node that will act as - * the List. - */ - this.handleKeydown = (event) => { - const key = event.key; - if (event.defaultPrevented || !this.isNavigableKey(key)) { - return; - } - // do not use this.items directly in upcoming calculations so we don't - // re-query the DOM unnecessarily - const items = this.items; - if (!items.length) { - return; - } - const activeItemRecord = (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.getActiveItem)(items, this.isActivatable); - event.preventDefault(); - const isRtl = this.isRtl(); - const inlinePrevious = isRtl - ? NavigableKeys.ArrowRight - : NavigableKeys.ArrowLeft; - const inlineNext = isRtl - ? NavigableKeys.ArrowLeft - : NavigableKeys.ArrowRight; - let nextActiveItem = null; - switch (key) { - // Activate the next item - case NavigableKeys.ArrowDown: - case inlineNext: - nextActiveItem = (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.activateNextItem)(items, activeItemRecord, this.isActivatable, this.wrapNavigation()); - break; - // Activate the previous item - case NavigableKeys.ArrowUp: - case inlinePrevious: - nextActiveItem = (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.activatePreviousItem)(items, activeItemRecord, this.isActivatable, this.wrapNavigation()); - break; - // Activate the first item - case NavigableKeys.Home: - nextActiveItem = (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.activateFirstItem)(items, this.isActivatable); - break; - // Activate the last item - case NavigableKeys.End: - nextActiveItem = (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.activateLastItem)(items, this.isActivatable); - break; - default: - break; - } - if (nextActiveItem && - activeItemRecord && - activeItemRecord.item !== nextActiveItem) { - // If a new item was activated, remove the tabindex of the previous - // activated item. - activeItemRecord.item.tabIndex = -1; - } - }; - /** - * Listener to be bound to the `deactivate-items` item event. - */ - this.onDeactivateItems = () => { - const items = this.items; - for (const item of items) { - this.deactivateItem(item); - } - }; - /** - * Listener to be bound to the `request-activation` item event.. - */ - this.onRequestActivation = (event) => { - this.onDeactivateItems(); - const target = event.target; - this.activateItem(target); - target.focus(); - }; - /** - * Listener to be bound to the `slotchange` event for the slot that renders - * the items. - */ - this.onSlotchange = () => { - const items = this.items; - // Whether we have encountered an item that has been activated - let encounteredActivated = false; - for (const item of items) { - const isActivated = !item.disabled && item.tabIndex > -1; - if (isActivated && !encounteredActivated) { - encounteredActivated = true; - item.tabIndex = 0; - continue; - } - // Deactivate the rest including disabled - item.tabIndex = -1; - } - if (encounteredActivated) { - return; - } - const firstActivatableItem = (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.getFirstActivatableItem)(items, this.isActivatable); - if (!firstActivatableItem) { - return; - } - firstActivatableItem.tabIndex = 0; - }; - const { isItem, getPossibleItems, isRtl, deactivateItem, activateItem, isNavigableKey, isActivatable, wrapNavigation, } = config; - this.isItem = isItem; - this.getPossibleItems = getPossibleItems; - this.isRtl = isRtl; - this.deactivateItem = deactivateItem; - this.activateItem = activateItem; - this.isNavigableKey = isNavigableKey; - this.isActivatable = isActivatable; - this.wrapNavigation = wrapNavigation ?? (() => true); - } - /** - * The items being managed by the list. Additionally, attempts to see if the - * object has a sub-item in the `.item` property. - */ - get items() { - const maybeItems = this.getPossibleItems(); - const items = []; - for (const itemOrParent of maybeItems) { - const isItem = this.isItem(itemOrParent); - // if the item is a list item, add it to the list of items - if (isItem) { - items.push(itemOrParent); - continue; - } - // If the item exposes an `item` property check if it is a list item. - const subItem = itemOrParent.item; - if (subItem && this.isItem(subItem)) { - items.push(subItem); - } - } - return items; - } - /** - * Activates the next item in the list. If at the end of the list, the first - * item will be activated. - * - * @return The activated list item or `null` if there are no items. - */ - activateNextItem() { - const items = this.items; - const activeItemRecord = (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.getActiveItem)(items, this.isActivatable); - if (activeItemRecord) { - activeItemRecord.item.tabIndex = -1; - } - return (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.activateNextItem)(items, activeItemRecord, this.isActivatable, this.wrapNavigation()); - } - /** - * Activates the previous item in the list. If at the start of the list, the - * last item will be activated. - * - * @return The activated list item or `null` if there are no items. - */ - activatePreviousItem() { - const items = this.items; - const activeItemRecord = (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.getActiveItem)(items, this.isActivatable); - if (activeItemRecord) { - activeItemRecord.item.tabIndex = -1; - } - return (0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_0__.activatePreviousItem)(items, activeItemRecord, this.isActivatable, this.wrapNavigation()); - } -} -//# sourceMappingURL=list-controller.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/list/internal/list-navigation-helpers.js": -/*!*****************************************************************************!*\ - !*** ./node_modules/@material/web/list/internal/list-navigation-helpers.js ***! - \*****************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ activateFirstItem: () => (/* binding */ activateFirstItem), -/* harmony export */ activateLastItem: () => (/* binding */ activateLastItem), -/* harmony export */ activateNextItem: () => (/* binding */ activateNextItem), -/* harmony export */ activatePreviousItem: () => (/* binding */ activatePreviousItem), -/* harmony export */ createDeactivateItemsEvent: () => (/* binding */ createDeactivateItemsEvent), -/* harmony export */ createRequestActivationEvent: () => (/* binding */ createRequestActivationEvent), -/* harmony export */ deactivateActiveItem: () => (/* binding */ deactivateActiveItem), -/* harmony export */ getActiveItem: () => (/* binding */ getActiveItem), -/* harmony export */ getFirstActivatableItem: () => (/* binding */ getFirstActivatableItem), -/* harmony export */ getLastActivatableItem: () => (/* binding */ getLastActivatableItem), -/* harmony export */ getNextItem: () => (/* binding */ getNextItem), -/* harmony export */ getPrevItem: () => (/* binding */ getPrevItem) -/* harmony export */ }); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * Activates the first non-disabled item of a given array of items. - * - * @param items {Array} The items from which to activate the - * first item. - * @param isActivatable Function to determine if an item can be activated. - * Defaults to non-disabled items. - */ -function activateFirstItem(items, isActivatable = (isItemNotDisabled)) { - // NOTE: These selector functions are static and not on the instance such - // that multiple operations can be chained and we do not have to re-query - // the DOM - const firstItem = getFirstActivatableItem(items, isActivatable); - if (firstItem) { - firstItem.tabIndex = 0; - firstItem.focus(); - } - return firstItem; -} -/** - * Activates the last non-disabled item of a given array of items. - * - * @param items {Array} The items from which to activate the - * last item. - * @param isActivatable Function to determine if an item can be activated. - * Defaults to non-disabled items. - * @nocollapse - */ -function activateLastItem(items, isActivatable = (isItemNotDisabled)) { - const lastItem = getLastActivatableItem(items, isActivatable); - if (lastItem) { - lastItem.tabIndex = 0; - lastItem.focus(); - } - return lastItem; -} -/** - * Deactivates the currently active item of a given array of items. - * - * @param items {Array} The items from which to deactivate the - * active item. - * @param isActivatable Function to determine if an item can be activated. - * Defaults to non-disabled items. - * @return A record of the deleselcted activated item including the item and - * the index of the item or `null` if none are deactivated. - * @nocollapse - */ -function deactivateActiveItem(items, isActivatable = (isItemNotDisabled)) { - const activeItem = getActiveItem(items, isActivatable); - if (activeItem) { - activeItem.item.tabIndex = -1; - } - return activeItem; -} -/** - * Retrieves the first activated item of a given array of items. - * - * @param items {Array} The items to search. - * @param isActivatable Function to determine if an item can be activated. - * Defaults to non-disabled items. - * @return A record of the first activated item including the item and the - * index of the item or `null` if none are activated. - * @nocollapse - */ -function getActiveItem(items, isActivatable = (isItemNotDisabled)) { - for (let i = 0; i < items.length; i++) { - const item = items[i]; - if (item.tabIndex === 0 && isActivatable(item)) { - return { - item, - index: i, - }; - } - } - return null; -} -/** - * Retrieves the first non-disabled item of a given array of items. This - * the first item that is not disabled. - * - * @param items {Array} The items to search. - * @param isActivatable Function to determine if an item can be activated. - * Defaults to non-disabled items. - * @return The first activatable item or `null` if none are activatable. - * @nocollapse - */ -function getFirstActivatableItem(items, isActivatable = (isItemNotDisabled)) { - for (const item of items) { - if (isActivatable(item)) { - return item; - } - } - return null; -} -/** - * Retrieves the last non-disabled item of a given array of items. - * - * @param items {Array} The items to search. - * @param isActivatable Function to determine if an item can be activated. - * Defaults to non-disabled items. - * @return The last activatable item or `null` if none are activatable. - * @nocollapse - */ -function getLastActivatableItem(items, isActivatable = (isItemNotDisabled)) { - for (let i = items.length - 1; i >= 0; i--) { - const item = items[i]; - if (isActivatable(item)) { - return item; - } - } - return null; -} -/** - * Retrieves the next non-disabled item of a given array of items. - * - * @param items {Array} The items to search. - * @param index {{index: number}} The index to search from. - * @param isActivatable Function to determine if an item can be activated. - * Defaults to non-disabled items. - * @param wrap If true, then the next item at the end of the list is the first - * item. Defaults to true. - * @return The next activatable item or `null` if none are activatable. - */ -function getNextItem(items, index, isActivatable = (isItemNotDisabled), wrap = true) { - for (let i = 1; i < items.length; i++) { - const nextIndex = (i + index) % items.length; - if (nextIndex < index && !wrap) { - // Return if the index loops back to the beginning and not wrapping. - return null; - } - const item = items[nextIndex]; - if (isActivatable(item)) { - return item; - } - } - return items[index] ? items[index] : null; -} -/** - * Retrieves the previous non-disabled item of a given array of items. - * - * @param items {Array} The items to search. - * @param index {{index: number}} The index to search from. - * @param isActivatable Function to determine if an item can be activated. - * Defaults to non-disabled items. - * @param wrap If true, then the previous item at the beginning of the list is - * the last item. Defaults to true. - * @return The previous activatable item or `null` if none are activatable. - */ -function getPrevItem(items, index, isActivatable = (isItemNotDisabled), wrap = true) { - for (let i = 1; i < items.length; i++) { - const prevIndex = (index - i + items.length) % items.length; - if (prevIndex > index && !wrap) { - // Return if the index loops back to the end and not wrapping. - return null; - } - const item = items[prevIndex]; - if (isActivatable(item)) { - return item; - } - } - return items[index] ? items[index] : null; -} -/** - * Activates the next item and focuses it. If nothing is currently activated, - * activates the first item. - */ -function activateNextItem(items, activeItemRecord, isActivatable = (isItemNotDisabled), wrap = true) { - if (activeItemRecord) { - const next = getNextItem(items, activeItemRecord.index, isActivatable, wrap); - if (next) { - next.tabIndex = 0; - next.focus(); - } - return next; - } - else { - return activateFirstItem(items, isActivatable); - } -} -/** - * Activates the previous item and focuses it. If nothing is currently - * activated, activates the last item. - */ -function activatePreviousItem(items, activeItemRecord, isActivatable = (isItemNotDisabled), wrap = true) { - if (activeItemRecord) { - const prev = getPrevItem(items, activeItemRecord.index, isActivatable, wrap); - if (prev) { - prev.tabIndex = 0; - prev.focus(); - } - return prev; - } - else { - return activateLastItem(items, isActivatable); - } -} -/** - * Creates an event that requests the parent md-list to deactivate all other - * items. - */ -function createDeactivateItemsEvent() { - return new Event('deactivate-items', { bubbles: true, composed: true }); -} -/** - * Creates an event that requests the menu to set `tabindex=0` on the item and - * focus it. We use this pattern because List keeps track of what element is - * active in the List by maintaining tabindex. We do not want list items - * to set tabindex on themselves or focus themselves so that we can organize all - * that logic in the parent List and Menus, and list item stays as dumb as - * possible. - */ -function createRequestActivationEvent() { - return new Event('request-activation', { bubbles: true, composed: true }); -} -/** - * The default `isActivatable` function, which checks if an item is not - * disabled. - * - * @param item The item to check. - * @return true if `item.disabled` is `false. - */ -function isItemNotDisabled(item) { - return !item.disabled; -} -//# sourceMappingURL=list-navigation-helpers.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/list/internal/list-styles.js": -/*!*****************************************************************!*\ - !*** ./node_modules/@material/web/list/internal/list-styles.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./list/internal/list-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{background:var(--md-list-container-color, var(--md-sys-color-surface, #fef7ff));color:unset;display:flex;flex-direction:column;outline:none;padding:8px 0;position:relative} -`; -//# sourceMappingURL=list-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/list/internal/list.js": -/*!**********************************************************!*\ - !*** ./node_modules/@material/web/list/internal/list.js ***! - \**********************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ List: () => (/* binding */ List) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _list_controller_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./list-controller.js */ "./node_modules/@material/web/list/internal/list-controller.js"); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - -const NAVIGABLE_KEY_SET = new Set(Object.values(_list_controller_js__WEBPACK_IMPORTED_MODULE_2__.NavigableKeys)); -// tslint:disable-next-line:enforce-comments-on-exported-symbols -class List extends lit__WEBPACK_IMPORTED_MODULE_0__.LitElement { - /** @export */ - get items() { - return this.listController.items; - } - constructor() { - super(); - this.listController = new _list_controller_js__WEBPACK_IMPORTED_MODULE_2__.ListController({ - isItem: (item) => item.hasAttribute('md-list-item'), - getPossibleItems: () => this.slotItems, - isRtl: () => getComputedStyle(this).direction === 'rtl', - deactivateItem: (item) => { - item.tabIndex = -1; - }, - activateItem: (item) => { - item.tabIndex = 0; - }, - isNavigableKey: (key) => NAVIGABLE_KEY_SET.has(key), - isActivatable: (item) => !item.disabled && item.type !== 'text', - }); - this.internals = - // Cast needed for closure - this.attachInternals(); - if (!lit__WEBPACK_IMPORTED_MODULE_0__.isServer) { - this.internals.role = 'list'; - this.addEventListener('keydown', this.listController.handleKeydown); - } - } - render() { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - - `; - } - /** - * Activates the next item in the list. If at the end of the list, the first - * item will be activated. - * - * @return The activated list item or `null` if there are no items. - */ - activateNextItem() { - return this.listController.activateNextItem(); - } - /** - * Activates the previous item in the list. If at the start of the list, the - * last item will be activated. - * - * @return The activated list item or `null` if there are no items. - */ - activatePreviousItem() { - return this.listController.activatePreviousItem(); - } -} -(0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.queryAssignedElements)({ flatten: true }) -], List.prototype, "slotItems", void 0); -//# sourceMappingURL=list.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/list/internal/listitem/list-item-styles.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@material/web/list/internal/listitem/list-item-styles.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./list/internal/listitem/list-item-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{display:flex;-webkit-tap-highlight-color:rgba(0,0,0,0);--md-ripple-hover-color: var(--md-list-item-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-hover-opacity: var(--md-list-item-hover-state-layer-opacity, 0.08);--md-ripple-pressed-color: var(--md-list-item-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-pressed-opacity: var(--md-list-item-pressed-state-layer-opacity, 0.12)}:host(:is([type=button]:not([disabled]),[type=link])){cursor:pointer}md-focus-ring{z-index:1;--md-focus-ring-shape: 8px}a,button,li{background:none;border:none;cursor:inherit;padding:0;margin:0;text-align:unset;text-decoration:none}.list-item{border-radius:inherit;display:flex;flex:1;max-width:inherit;min-width:inherit;outline:none;-webkit-tap-highlight-color:rgba(0,0,0,0);width:100%}.list-item.interactive{cursor:pointer}.list-item.disabled{opacity:var(--md-list-item-disabled-opacity, 0.3);pointer-events:none}[slot=container]{pointer-events:none}md-ripple{border-radius:inherit}md-item{border-radius:inherit;flex:1;height:100%;color:var(--md-list-item-label-text-color, var(--md-sys-color-on-surface, #1d1b20));font-family:var(--md-list-item-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-list-item-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));line-height:var(--md-list-item-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));font-weight:var(--md-list-item-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));min-height:var(--md-list-item-one-line-container-height, 56px);padding-top:var(--md-list-item-top-space, 12px);padding-bottom:var(--md-list-item-bottom-space, 12px);padding-inline-start:var(--md-list-item-leading-space, 16px);padding-inline-end:var(--md-list-item-trailing-space, 16px)}md-item[multiline]{min-height:var(--md-list-item-two-line-container-height, 72px)}[slot=supporting-text]{color:var(--md-list-item-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-list-item-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-list-item-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-list-item-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));font-weight:var(--md-list-item-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)))}[slot=trailing-supporting-text]{color:var(--md-list-item-trailing-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-list-item-trailing-supporting-text-font, var(--md-sys-typescale-label-small-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-list-item-trailing-supporting-text-size, var(--md-sys-typescale-label-small-size, 0.6875rem));line-height:var(--md-list-item-trailing-supporting-text-line-height, var(--md-sys-typescale-label-small-line-height, 1rem));font-weight:var(--md-list-item-trailing-supporting-text-weight, var(--md-sys-typescale-label-small-weight, var(--md-ref-typeface-weight-medium, 500)))}:is([slot=start],[slot=end])::slotted(*){fill:currentColor}[slot=start]{color:var(--md-list-item-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f))}[slot=end]{color:var(--md-list-item-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f))}@media(forced-colors: active){.disabled slot{color:GrayText}.list-item.disabled{color:GrayText;opacity:1}} -`; -//# sourceMappingURL=list-item-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/list/internal/listitem/list-item.js": -/*!************************************************************************!*\ - !*** ./node_modules/@material/web/list/internal/listitem/list-item.js ***! - \************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ListItemEl: () => (/* binding */ ListItemEl) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var _focus_md_focus_ring_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../focus/md-focus-ring.js */ "./node_modules/@material/web/focus/md-focus-ring.js"); -/* harmony import */ var _labs_item_item_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../labs/item/item.js */ "./node_modules/@material/web/labs/item/item.js"); -/* harmony import */ var _ripple_ripple_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../ripple/ripple.js */ "./node_modules/@material/web/ripple/ripple.js"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lit/directives/class-map.js */ "./node_modules/lit/directives/class-map.js"); -/* harmony import */ var lit_static_html_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lit/static-html.js */ "./node_modules/lit/static-html.js"); -/* harmony import */ var _internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../internal/aria/delegate.js */ "./node_modules/@material/web/internal/aria/delegate.js"); -/* harmony import */ var _list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../list-navigation-helpers.js */ "./node_modules/@material/web/list/internal/list-navigation-helpers.js"); -/** - * @license - * Copyright 2022 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - - - - - - -// Separate variable needed for closure. -const listItemBaseClass = (0,_internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_7__.mixinDelegatesAria)(lit__WEBPACK_IMPORTED_MODULE_3__.LitElement); -/** - * @fires request-activation {Event} Requests the list to set `tabindex=0` on - * the item and focus it. --bubbles --composed - */ -class ListItemEl extends listItemBaseClass { - constructor() { - super(...arguments); - /** - * Disables the item and makes it non-selectable and non-interactive. - */ - this.disabled = false; - /** - * Sets the behavior of the list item, defaults to "text". Change to "link" or - * "button" for interactive items. - */ - this.type = 'text'; - /** - * READONLY. Sets the `md-list-item` attribute on the element. - */ - this.isListItem = true; - /** - * Sets the underlying `HTMLAnchorElement`'s `href` resource attribute. - */ - this.href = ''; - /** - * Sets the underlying `HTMLAnchorElement`'s `target` attribute when `href` is - * set. - */ - this.target = ''; - } - get isDisabled() { - return this.disabled && this.type !== 'link'; - } - willUpdate(changed) { - if (this.href) { - this.type = 'link'; - } - super.willUpdate(changed); - } - render() { - return this.renderListItem((0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` - -
    - ${this.renderRipple()} ${this.renderFocusRing()} -
    - - - ${this.renderBody()} -
    - `); - } - /** - * Renders the root list item. - * - * @param content the child content of the list item. - */ - renderListItem(content) { - const isAnchor = this.type === 'link'; - let tag; - switch (this.type) { - case 'link': - tag = (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_6__.literal) `a`; - break; - case 'button': - tag = (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_6__.literal) `button`; - break; - default: - case 'text': - tag = (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_6__.literal) `li`; - break; - } - const isInteractive = this.type !== 'text'; - // TODO(b/265339866): announce "button"/"link" inside of a list item. Until - // then all are "listitem" roles for correct announcement. - const target = isAnchor && !!this.target ? this.target : lit__WEBPACK_IMPORTED_MODULE_3__.nothing; - return (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_6__.html) ` - <${tag} - id="item" - tabindex="${this.isDisabled || !isInteractive ? -1 : 0}" - ?disabled=${this.isDisabled} - role="listitem" - aria-selected=${this.ariaSelected || lit__WEBPACK_IMPORTED_MODULE_3__.nothing} - aria-checked=${this.ariaChecked || lit__WEBPACK_IMPORTED_MODULE_3__.nothing} - aria-expanded=${this.ariaExpanded || lit__WEBPACK_IMPORTED_MODULE_3__.nothing} - aria-haspopup=${this.ariaHasPopup || lit__WEBPACK_IMPORTED_MODULE_3__.nothing} - class="list-item ${(0,lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_5__.classMap)(this.getRenderClasses())}" - href=${this.href || lit__WEBPACK_IMPORTED_MODULE_3__.nothing} - target=${target} - @focus=${this.onFocus} - >${content} - `; - } - /** - * Handles rendering of the ripple element. - */ - renderRipple() { - if (this.type === 'text') { - return lit__WEBPACK_IMPORTED_MODULE_3__.nothing; - } - return (0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` `; - } - /** - * Handles rendering of the focus ring. - */ - renderFocusRing() { - if (this.type === 'text') { - return lit__WEBPACK_IMPORTED_MODULE_3__.nothing; - } - return (0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` `; - } - onFocusRingVisibilityChanged(e) { } - /** - * Classes applied to the list item root. - */ - getRenderClasses() { - return { 'disabled': this.isDisabled }; - } - /** - * Handles rendering the headline and supporting text. - */ - renderBody() { - return (0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` - - - - - - `; - } - onFocus() { - if (this.tabIndex !== -1) { - return; - } - // Handles the case where the user clicks on the element and then tabs. - this.dispatchEvent((0,_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_8__.createRequestActivationEvent)()); - } - focus() { - // TODO(b/300334509): needed for some cases where delegatesFocus doesn't - // work programmatically like in FF and select-option - this.listItemRoot?.focus(); - } - click() { - if (!this.listItemRoot) { - // If the element has not finished rendering, call super to ensure click - // events are dispatched. - super.click(); - return; - } - // Forward click to the element to ensure link
    .click() works correctly. - this.listItemRoot.click(); - } -} -/** @nocollapse */ -ListItemEl.shadowRootOptions = { - ...lit__WEBPACK_IMPORTED_MODULE_3__.LitElement.shadowRootOptions, - delegatesFocus: true, -}; -(0,tslib__WEBPACK_IMPORTED_MODULE_9__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)({ type: Boolean, reflect: true }) -], ListItemEl.prototype, "disabled", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_9__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)({ reflect: true }) -], ListItemEl.prototype, "type", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_9__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)({ type: Boolean, attribute: 'md-list-item', reflect: true }) -], ListItemEl.prototype, "isListItem", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_9__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)() -], ListItemEl.prototype, "href", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_9__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)() -], ListItemEl.prototype, "target", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_9__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.query)('.list-item') -], ListItemEl.prototype, "listItemRoot", void 0); -//# sourceMappingURL=list-item.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/menu/internal/controllers/menuItemController.js": -/*!************************************************************************************!*\ - !*** ./node_modules/@material/web/menu/internal/controllers/menuItemController.js ***! - \************************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ MenuItemController: () => (/* binding */ MenuItemController) -/* harmony export */ }); -/* harmony import */ var _shared_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shared.js */ "./node_modules/@material/web/menu/internal/controllers/shared.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * A controller that provides most functionality of an element that implements - * the MenuItem interface. - */ -class MenuItemController { - /** - * @param host The MenuItem in which to attach this controller to. - * @param config The object that configures this controller's behavior. - */ - constructor(host, config) { - this.host = host; - this.internalTypeaheadText = null; - /** - * Bind this click listener to the interactive element. Handles closing the - * menu. - */ - this.onClick = () => { - if (this.host.keepOpen) - return; - this.host.dispatchEvent((0,_shared_js__WEBPACK_IMPORTED_MODULE_0__.createDefaultCloseMenuEvent)(this.host, { - kind: _shared_js__WEBPACK_IMPORTED_MODULE_0__.CloseReason.CLICK_SELECTION, - })); - }; - /** - * Bind this click listener to the interactive element. Handles closing the - * menu. - */ - this.onKeydown = (event) => { - // Check if the interactive element is an anchor tag. If so, click it. - if (this.host.href && event.code === 'Enter') { - const interactiveElement = this.getInteractiveElement(); - if (interactiveElement instanceof HTMLAnchorElement) { - interactiveElement.click(); - } - } - if (event.defaultPrevented) - return; - // If the host has keepOpen = true we should ignore clicks & Space/Enter, - // however we always maintain the ability to close a menu with a explicit - // `escape` keypress. - const keyCode = event.code; - if (this.host.keepOpen && keyCode !== 'Escape') - return; - if ((0,_shared_js__WEBPACK_IMPORTED_MODULE_0__.isClosableKey)(keyCode)) { - event.preventDefault(); - this.host.dispatchEvent((0,_shared_js__WEBPACK_IMPORTED_MODULE_0__.createDefaultCloseMenuEvent)(this.host, { - kind: _shared_js__WEBPACK_IMPORTED_MODULE_0__.CloseReason.KEYDOWN, - key: keyCode, - })); - } - }; - this.getHeadlineElements = config.getHeadlineElements; - this.getSupportingTextElements = config.getSupportingTextElements; - this.getDefaultElements = config.getDefaultElements; - this.getInteractiveElement = config.getInteractiveElement; - this.host.addController(this); - } - /** - * The text that is selectable via typeahead. If not set, defaults to the - * innerText of the item slotted into the `"headline"` slot, and if there are - * no slotted elements into headline, then it checks the _default_ slot, and - * then the `"supporting-text"` slot if nothing is in _default_. - */ - get typeaheadText() { - if (this.internalTypeaheadText !== null) { - return this.internalTypeaheadText; - } - const headlineElements = this.getHeadlineElements(); - const textParts = []; - headlineElements.forEach((headlineElement) => { - if (headlineElement.textContent && headlineElement.textContent.trim()) { - textParts.push(headlineElement.textContent.trim()); - } - }); - // If there are no headline elements, check the default slot's text content - if (textParts.length === 0) { - this.getDefaultElements().forEach((defaultElement) => { - if (defaultElement.textContent && defaultElement.textContent.trim()) { - textParts.push(defaultElement.textContent.trim()); - } - }); - } - // If there are no headline nor default slot elements, check the - //supporting-text slot's text content - if (textParts.length === 0) { - this.getSupportingTextElements().forEach((supportingTextElement) => { - if (supportingTextElement.textContent && - supportingTextElement.textContent.trim()) { - textParts.push(supportingTextElement.textContent.trim()); - } - }); - } - return textParts.join(' '); - } - /** - * The recommended tag name to render as the list item. - */ - get tagName() { - const type = this.host.type; - switch (type) { - case 'link': - return 'a'; - case 'button': - return 'button'; - default: - case 'menuitem': - case 'option': - return 'li'; - } - } - /** - * The recommended role of the menu item. - */ - get role() { - return this.host.type === 'option' ? 'option' : 'menuitem'; - } - hostConnected() { - this.host.toggleAttribute('md-menu-item', true); - } - hostUpdate() { - if (this.host.href) { - this.host.type = 'link'; - } - } - /** - * Use to set the typeaheadText when it changes. - */ - setTypeaheadText(text) { - this.internalTypeaheadText = text; - } -} -//# sourceMappingURL=menuItemController.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/menu/internal/controllers/shared.js": -/*!************************************************************************!*\ - !*** ./node_modules/@material/web/menu/internal/controllers/shared.js ***! - \************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ CloseReason: () => (/* binding */ CloseReason), -/* harmony export */ FocusState: () => (/* binding */ FocusState), -/* harmony export */ KeydownCloseKey: () => (/* binding */ KeydownCloseKey), -/* harmony export */ NavigableKey: () => (/* binding */ NavigableKey), -/* harmony export */ SelectionKey: () => (/* binding */ SelectionKey), -/* harmony export */ createActivateTypeaheadEvent: () => (/* binding */ createActivateTypeaheadEvent), -/* harmony export */ createCloseMenuEvent: () => (/* binding */ createCloseMenuEvent), -/* harmony export */ createCloseOnFocusoutEvent: () => (/* binding */ createCloseOnFocusoutEvent), -/* harmony export */ createDeactivateTypeaheadEvent: () => (/* binding */ createDeactivateTypeaheadEvent), -/* harmony export */ createDefaultCloseMenuEvent: () => (/* binding */ createDefaultCloseMenuEvent), -/* harmony export */ createStayOpenOnFocusoutEvent: () => (/* binding */ createStayOpenOnFocusoutEvent), -/* harmony export */ isClosableKey: () => (/* binding */ isClosableKey), -/* harmony export */ isElementInSubtree: () => (/* binding */ isElementInSubtree), -/* harmony export */ isSelectableKey: () => (/* binding */ isSelectableKey) -/* harmony export */ }); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * Creates an event that closes any parent menus. - */ -function createCloseMenuEvent(initiator, reason) { - return new CustomEvent('close-menu', { - bubbles: true, - composed: true, - detail: { initiator, reason, itemPath: [initiator] }, - }); -} -/** - * Creates an event that signals to the menu that it should stay open on the - * focusout event. - */ -function createStayOpenOnFocusoutEvent() { - return new Event('stay-open-on-focusout', { bubbles: true, composed: true }); -} -/** - * Creates an event that signals to the menu that it should close open on the - * focusout event. - */ -function createCloseOnFocusoutEvent() { - return new Event('close-on-focusout', { bubbles: true, composed: true }); -} -/** - * Creates a default close menu event used by md-menu. - */ -const createDefaultCloseMenuEvent = (createCloseMenuEvent); -/** - * Creates an event that requests the given item be selected. - */ -function createDeactivateTypeaheadEvent() { - return new Event('deactivate-typeahead', { bubbles: true, composed: true }); -} -/** - * Creates an event that requests the typeahead functionality of containing menu - * be activated. - */ -function createActivateTypeaheadEvent() { - return new Event('activate-typeahead', { bubbles: true, composed: true }); -} -/** - * Keys that are used to navigate menus. - */ -// tslint:disable-next-line:enforce-name-casing We are mimicking enum style -const NavigableKey = { - UP: 'ArrowUp', - DOWN: 'ArrowDown', - RIGHT: 'ArrowRight', - LEFT: 'ArrowLeft', -}; -/** - * Keys that are used for selection in menus. - */ -// tslint:disable-next-line:enforce-name-casing We are mimicking enum style -const SelectionKey = { - SPACE: 'Space', - ENTER: 'Enter', -}; -/** - * Default close `Reason` kind values. - */ -// tslint:disable-next-line:enforce-name-casing We are mimicking enum style -const CloseReason = { - CLICK_SELECTION: 'click-selection', - KEYDOWN: 'keydown', -}; -/** - * Keys that can close menus. - */ -// tslint:disable-next-line:enforce-name-casing We are mimicking enum style -const KeydownCloseKey = { - ESCAPE: 'Escape', - SPACE: SelectionKey.SPACE, - ENTER: SelectionKey.ENTER, -}; -/** - * Determines whether the given key code is a key code that should close the - * menu. - * - * @param code The KeyboardEvent code to check. - * @return Whether or not the key code is in the predetermined list to close the - * menu. - */ -function isClosableKey(code) { - return Object.values(KeydownCloseKey).some((value) => value === code); -} -/** - * Determines whether the given key code is a key code that should select a menu - * item. - * - * @param code They KeyboardEvent code to check. - * @return Whether or not the key code is in the predetermined list to select a - * menu item. - */ -function isSelectableKey(code) { - return Object.values(SelectionKey).some((value) => value === code); -} -/** - * Determines whether a target element is contained inside another element's - * composed tree. - * - * @param target The potential contained element. - * @param container The potential containing element of the target. - * @returns Whether the target element is contained inside the container's - * composed subtree - */ -function isElementInSubtree(target, container) { - // Dispatch a composed, bubbling event to check its path to see if the - // newly-focused element is contained in container's subtree - const focusEv = new Event('md-contains', { bubbles: true, composed: true }); - let composedPath = []; - const listener = (ev) => { - composedPath = ev.composedPath(); - }; - container.addEventListener('md-contains', listener); - target.dispatchEvent(focusEv); - container.removeEventListener('md-contains', listener); - const isContained = composedPath.length > 0; - return isContained; -} -/** - * Element to focus on when menu is first opened. - */ -// tslint:disable-next-line:enforce-name-casing We are mimicking enum style -const FocusState = { - NONE: 'none', - LIST_ROOT: 'list-root', - FIRST_ITEM: 'first-item', - LAST_ITEM: 'last-item', -}; -//# sourceMappingURL=shared.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/menu/internal/controllers/surfacePositionController.js": -/*!*******************************************************************************************!*\ - !*** ./node_modules/@material/web/menu/internal/controllers/surfacePositionController.js ***! - \*******************************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Corner: () => (/* binding */ Corner), -/* harmony export */ SurfacePositionController: () => (/* binding */ SurfacePositionController) -/* harmony export */ }); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * An enum of supported Menu corners - */ -// tslint:disable-next-line:enforce-name-casing We are mimicking enum style -const Corner = { - END_START: 'end-start', - END_END: 'end-end', - START_START: 'start-start', - START_END: 'start-end', -}; -/** - * Given a surface, an anchor, corners, and some options, this surface will - * calculate the position of a surface to align the two given corners and keep - * the surface inside the window viewport. It also provides a StyleInfo map that - * can be applied to the surface to handle visiblility and position. - */ -class SurfacePositionController { - /** - * @param host The host to connect the controller to. - * @param getProperties A function that returns the properties for the - * controller. - */ - constructor(host, getProperties) { - this.host = host; - this.getProperties = getProperties; - // The current styles to apply to the surface. - this.surfaceStylesInternal = { - 'display': 'none', - }; - // Previous values stored for change detection. Open change detection is - // calculated separately so initialize it here. - this.lastValues = { - isOpen: false, - }; - this.host.addController(this); - } - /** - * The StyleInfo map to apply to the surface via Lit's stylemap - */ - get surfaceStyles() { - return this.surfaceStylesInternal; - } - /** - * Calculates the surface's new position required so that the surface's - * `surfaceCorner` aligns to the anchor's `anchorCorner` while keeping the - * surface inside the window viewport. This positioning also respects RTL by - * checking `getComputedStyle()` on the surface element. - */ - async position() { - const { surfaceEl, anchorEl, anchorCorner: anchorCornerRaw, surfaceCorner: surfaceCornerRaw, positioning, xOffset, yOffset, disableBlockFlip, disableInlineFlip, repositionStrategy, } = this.getProperties(); - const anchorCorner = anchorCornerRaw.toLowerCase().trim(); - const surfaceCorner = surfaceCornerRaw.toLowerCase().trim(); - if (!surfaceEl || !anchorEl) { - return; - } - // Store these before we potentially resize the window with the next set of - // lines - const windowInnerWidth = window.innerWidth; - const windowInnerHeight = window.innerHeight; - const div = document.createElement('div'); - div.style.opacity = '0'; - div.style.position = 'fixed'; - div.style.display = 'block'; - div.style.inset = '0'; - document.body.appendChild(div); - const scrollbarTestRect = div.getBoundingClientRect(); - div.remove(); - // Calculate the widths of the scrollbars in the inline and block directions - // to account for window-relative calculations. - const blockScrollbarHeight = window.innerHeight - scrollbarTestRect.bottom; - const inlineScrollbarWidth = window.innerWidth - scrollbarTestRect.right; - // Paint the surface transparently so that we can get the position and the - // rect info of the surface. - this.surfaceStylesInternal = { - 'display': 'block', - 'opacity': '0', - }; - // Wait for it to be visible. - this.host.requestUpdate(); - await this.host.updateComplete; - // Safari has a bug that makes popovers render incorrectly if the node is - // made visible + Animation Frame before calling showPopover(). - // https://bugs.webkit.org/show_bug.cgi?id=264069 - // also the cast is required due to differing TS types in Google and OSS. - if (surfaceEl.popover && - surfaceEl.isConnected) { - surfaceEl.showPopover(); - } - const surfaceRect = surfaceEl.getSurfacePositionClientRect - ? surfaceEl.getSurfacePositionClientRect() - : surfaceEl.getBoundingClientRect(); - const anchorRect = anchorEl.getSurfacePositionClientRect - ? anchorEl.getSurfacePositionClientRect() - : anchorEl.getBoundingClientRect(); - const [surfaceBlock, surfaceInline] = surfaceCorner.split('-'); - const [anchorBlock, anchorInline] = anchorCorner.split('-'); - // LTR depends on the direction of the SURFACE not the anchor. - const isLTR = getComputedStyle(surfaceEl).direction === 'ltr'; - /* - * For more on inline and block dimensions, see MDN article: - * https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_values - * - * ┌───── inline/blockDocumentOffset inlineScrollbarWidth - * │ │ │ - * │ ┌─▼─────┐ │Document - * │ ┌┼───────┴──────────────────────────────┼────────┐ - * │ ││ │ │ - * └──► ││ ┌───── inline/blockWindowOffset │ │ - * ││ │ │ ▼ │ - * ││ │ ┌─▼───┐ Window┌┐ │ - * └┤ │ ┌┼─────┴───────────────────────┼│ │ - * │ │ ││ ││ │ - * │ └──► ││ ┌──inline/blockAnchorOffset││ │ - * │ ││ │ │ ││ │ - * │ └┤ │ ┌──▼───┐ ││ │ - * │ │ │ ┌┼──────┤ ││ │ - * │ │ └─►│Anchor│ ││ │ - * │ │ └┴──────┘ ││ │ - * │ │ ││ │ - * │ │ ┌───────────────────────┼┼────┐ │ - * │ │ │ Surface ││ │ │ - * │ │ │ ││ │ │ - * │ │ │ ││ │ │ - * │ │ │ ││ │ │ - * │ │ │ ││ │ │ - * │ ┌┼─────┼───────────────────────┼│ │ │ - * │ ┌─►┴──────┼────────────────────────┘ ├┐ │ - * │ │ │ inline/blockOOBCorrection ││ │ - * │ │ │ │ ││ │ - * │ │ │ ├──►├│ │ - * │ │ │ │ ││ │ - * │ │ └────────────────────────┐▼───┼┘ │ - * │ blockScrollbarHeight └────┘ │ - * │ │ - * └───────────────────────────────────────────────┘ - */ - // Calculate the block positioning properties - let { blockInset, blockOutOfBoundsCorrection, surfaceBlockProperty } = this.calculateBlock({ - surfaceRect, - anchorRect, - anchorBlock, - surfaceBlock, - yOffset, - positioning, - windowInnerHeight, - blockScrollbarHeight, - }); - // If the surface should be out of bounds in the block direction, flip the - // surface and anchor corner block values and recalculate - if (blockOutOfBoundsCorrection && !disableBlockFlip) { - const flippedSurfaceBlock = surfaceBlock === 'start' ? 'end' : 'start'; - const flippedAnchorBlock = anchorBlock === 'start' ? 'end' : 'start'; - const flippedBlock = this.calculateBlock({ - surfaceRect, - anchorRect, - anchorBlock: flippedAnchorBlock, - surfaceBlock: flippedSurfaceBlock, - yOffset, - positioning, - windowInnerHeight, - blockScrollbarHeight, - }); - // In the case that the flipped verion would require less out of bounds - // correcting, use the flipped corner block values - if (blockOutOfBoundsCorrection > flippedBlock.blockOutOfBoundsCorrection) { - blockInset = flippedBlock.blockInset; - blockOutOfBoundsCorrection = flippedBlock.blockOutOfBoundsCorrection; - surfaceBlockProperty = flippedBlock.surfaceBlockProperty; - } - } - // Calculate the inline positioning properties - let { inlineInset, inlineOutOfBoundsCorrection, surfaceInlineProperty } = this.calculateInline({ - surfaceRect, - anchorRect, - anchorInline, - surfaceInline, - xOffset, - positioning, - isLTR, - windowInnerWidth, - inlineScrollbarWidth, - }); - // If the surface should be out of bounds in the inline direction, flip the - // surface and anchor corner inline values and recalculate - if (inlineOutOfBoundsCorrection && !disableInlineFlip) { - const flippedSurfaceInline = surfaceInline === 'start' ? 'end' : 'start'; - const flippedAnchorInline = anchorInline === 'start' ? 'end' : 'start'; - const flippedInline = this.calculateInline({ - surfaceRect, - anchorRect, - anchorInline: flippedAnchorInline, - surfaceInline: flippedSurfaceInline, - xOffset, - positioning, - isLTR, - windowInnerWidth, - inlineScrollbarWidth, - }); - // In the case that the flipped verion would require less out of bounds - // correcting, use the flipped corner inline values - if (Math.abs(inlineOutOfBoundsCorrection) > - Math.abs(flippedInline.inlineOutOfBoundsCorrection)) { - inlineInset = flippedInline.inlineInset; - inlineOutOfBoundsCorrection = flippedInline.inlineOutOfBoundsCorrection; - surfaceInlineProperty = flippedInline.surfaceInlineProperty; - } - } - // If we are simply repositioning the surface back inside the viewport, - // subtract the out of bounds correction values from the positioning. - if (repositionStrategy === 'move') { - blockInset = blockInset - blockOutOfBoundsCorrection; - inlineInset = inlineInset - inlineOutOfBoundsCorrection; - } - this.surfaceStylesInternal = { - 'display': 'block', - 'opacity': '1', - [surfaceBlockProperty]: `${blockInset}px`, - [surfaceInlineProperty]: `${inlineInset}px`, - }; - // In the case that we are resizing the surface to stay inside the viewport - // we need to set height and width on the surface. - if (repositionStrategy === 'resize') { - // Add a height property to the styles if there is block height correction - if (blockOutOfBoundsCorrection) { - this.surfaceStylesInternal['height'] = `${surfaceRect.height - blockOutOfBoundsCorrection}px`; - } - // Add a width property to the styles if there is block height correction - if (inlineOutOfBoundsCorrection) { - this.surfaceStylesInternal['width'] = `${surfaceRect.width - inlineOutOfBoundsCorrection}px`; - } - } - this.host.requestUpdate(); - } - /** - * Calculates the css property, the inset, and the out of bounds correction - * for the surface in the block direction. - */ - calculateBlock(config) { - const { surfaceRect, anchorRect, anchorBlock, surfaceBlock, yOffset, positioning, windowInnerHeight, blockScrollbarHeight, } = config; - // We use number booleans to multiply values rather than `if` / ternary - // statements because it _heavily_ cuts down on nesting and readability - const relativeToWindow = positioning === 'fixed' || positioning === 'document' ? 1 : 0; - const relativeToDocument = positioning === 'document' ? 1 : 0; - const isSurfaceBlockStart = surfaceBlock === 'start' ? 1 : 0; - const isSurfaceBlockEnd = surfaceBlock === 'end' ? 1 : 0; - const isOneBlockEnd = anchorBlock !== surfaceBlock ? 1 : 0; - // Whether or not to apply the height of the anchor - const blockAnchorOffset = isOneBlockEnd * anchorRect.height + yOffset; - // The absolute block position of the anchor relative to window - const blockTopLayerOffset = isSurfaceBlockStart * anchorRect.top + - isSurfaceBlockEnd * - (windowInnerHeight - anchorRect.bottom - blockScrollbarHeight); - const blockDocumentOffset = isSurfaceBlockStart * window.scrollY - isSurfaceBlockEnd * window.scrollY; - // If the surface's block would be out of bounds of the window, move it back - // in - const blockOutOfBoundsCorrection = Math.abs(Math.min(0, windowInnerHeight - - blockTopLayerOffset - - blockAnchorOffset - - surfaceRect.height)); - // The block logical value of the surface - const blockInset = relativeToWindow * blockTopLayerOffset + - relativeToDocument * blockDocumentOffset + - blockAnchorOffset; - const surfaceBlockProperty = surfaceBlock === 'start' ? 'inset-block-start' : 'inset-block-end'; - return { blockInset, blockOutOfBoundsCorrection, surfaceBlockProperty }; - } - /** - * Calculates the css property, the inset, and the out of bounds correction - * for the surface in the inline direction. - */ - calculateInline(config) { - const { isLTR: isLTRBool, surfaceInline, anchorInline, anchorRect, surfaceRect, xOffset, positioning, windowInnerWidth, inlineScrollbarWidth, } = config; - // We use number booleans to multiply values rather than `if` / ternary - // statements because it _heavily_ cuts down on nesting and readability - const relativeToWindow = positioning === 'fixed' || positioning === 'document' ? 1 : 0; - const relativeToDocument = positioning === 'document' ? 1 : 0; - const isLTR = isLTRBool ? 1 : 0; - const isRTL = isLTRBool ? 0 : 1; - const isSurfaceInlineStart = surfaceInline === 'start' ? 1 : 0; - const isSurfaceInlineEnd = surfaceInline === 'end' ? 1 : 0; - const isOneInlineEnd = anchorInline !== surfaceInline ? 1 : 0; - // Whether or not to apply the width of the anchor - const inlineAnchorOffset = isOneInlineEnd * anchorRect.width + xOffset; - // The inline position of the anchor relative to window in LTR - const inlineTopLayerOffsetLTR = isSurfaceInlineStart * anchorRect.left + - isSurfaceInlineEnd * - (windowInnerWidth - anchorRect.right - inlineScrollbarWidth); - // The inline position of the anchor relative to window in RTL - const inlineTopLayerOffsetRTL = isSurfaceInlineStart * - (windowInnerWidth - anchorRect.right - inlineScrollbarWidth) + - isSurfaceInlineEnd * anchorRect.left; - // The inline position of the anchor relative to window - const inlineTopLayerOffset = isLTR * inlineTopLayerOffsetLTR + isRTL * inlineTopLayerOffsetRTL; - // The inline position of the anchor relative to window in LTR - const inlineDocumentOffsetLTR = isSurfaceInlineStart * window.scrollX - - isSurfaceInlineEnd * window.scrollX; - // The inline position of the anchor relative to window in RTL - const inlineDocumentOffsetRTL = isSurfaceInlineEnd * window.scrollX - - isSurfaceInlineStart * window.scrollX; - // The inline position of the anchor relative to window - const inlineDocumentOffset = isLTR * inlineDocumentOffsetLTR + isRTL * inlineDocumentOffsetRTL; - // If the surface's inline would be out of bounds of the window, move it - // back in - const inlineOutOfBoundsCorrection = Math.abs(Math.min(0, windowInnerWidth - - inlineTopLayerOffset - - inlineAnchorOffset - - surfaceRect.width)); - // The inline logical value of the surface - const inlineInset = relativeToWindow * inlineTopLayerOffset + - inlineAnchorOffset + - relativeToDocument * inlineDocumentOffset; - let surfaceInlineProperty = surfaceInline === 'start' ? 'inset-inline-start' : 'inset-inline-end'; - // There are cases where the element is RTL but the root of the page is not. - // In these cases we want to not use logical properties. - if (positioning === 'document' || positioning === 'fixed') { - if ((surfaceInline === 'start' && isLTRBool) || - (surfaceInline === 'end' && !isLTRBool)) { - surfaceInlineProperty = 'left'; - } - else { - surfaceInlineProperty = 'right'; - } - } - return { - inlineInset, - inlineOutOfBoundsCorrection, - surfaceInlineProperty, - }; - } - hostUpdate() { - this.onUpdate(); - } - hostUpdated() { - this.onUpdate(); - } - /** - * Checks whether the properties passed into the controller have changed since - * the last positioning. If so, it will reposition if the surface is open or - * close it if the surface should close. - */ - async onUpdate() { - const props = this.getProperties(); - let hasChanged = false; - for (const [key, value] of Object.entries(props)) { - // tslint:disable-next-line - hasChanged = hasChanged || value !== this.lastValues[key]; - if (hasChanged) - break; - } - const openChanged = this.lastValues.isOpen !== props.isOpen; - const hasAnchor = !!props.anchorEl; - const hasSurface = !!props.surfaceEl; - if (hasChanged && hasAnchor && hasSurface) { - // Only update isOpen, because if it's closed, we do not want to waste - // time on a useless reposition calculation. So save the other "dirty" - // values until next time it opens. - this.lastValues.isOpen = props.isOpen; - if (props.isOpen) { - // We are going to do a reposition, so save the prop values for future - // dirty checking. - this.lastValues = props; - await this.position(); - props.onOpen(); - } - else if (openChanged) { - await props.beforeClose(); - this.close(); - props.onClose(); - } - } - } - /** - * Hides the surface. - */ - close() { - this.surfaceStylesInternal = { - 'display': 'none', - }; - this.host.requestUpdate(); - const surfaceEl = this.getProperties().surfaceEl; - // The following type casts are required due to differing TS types in Google - // and open source. - if (surfaceEl?.popover && - surfaceEl?.isConnected) { - surfaceEl.hidePopover(); - } - } -} -//# sourceMappingURL=surfacePositionController.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/menu/internal/controllers/typeaheadController.js": -/*!*************************************************************************************!*\ - !*** ./node_modules/@material/web/menu/internal/controllers/typeaheadController.js ***! - \*************************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ TYPEAHEAD_RECORD: () => (/* binding */ TYPEAHEAD_RECORD), -/* harmony export */ TypeaheadController: () => (/* binding */ TypeaheadController) -/* harmony export */ }); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * Indicies to access the TypeaheadRecord tuple type. - */ -const TYPEAHEAD_RECORD = { - INDEX: 0, - ITEM: 1, - TEXT: 2, -}; -/** - * This controller listens to `keydown` events and searches the header text of - * an array of `MenuItem`s with the corresponding entered keys within the buffer - * time and activates the item. - * - * @example - * ```ts - * const typeaheadController = new TypeaheadController(() => ({ - * typeaheadBufferTime: 50, - * getItems: () => Array.from(document.querySelectorAll('md-menu-item')) - * })); - * html` - *
    - * - * Apple - *
    - *
    - * - * - * - * - * - *
    - * `; - * ``` - */ -class TypeaheadController { - /** - * @param getProperties A function that returns the options of the typeahead - * controller: - * - * { - * getItems: A function that returns an array of menu items to be searched. - * typeaheadBufferTime: The maximum time between each keystroke to keep the - * current type buffer alive. - * } - */ - constructor(getProperties) { - this.getProperties = getProperties; - /** - * Array of tuples that helps with indexing. - */ - this.typeaheadRecords = []; - /** - * Currently-typed text since last buffer timeout - */ - this.typaheadBuffer = ''; - /** - * The timeout id from the current buffer's setTimeout - */ - this.cancelTypeaheadTimeout = 0; - /** - * If we are currently "typing" - */ - this.isTypingAhead = false; - /** - * The record of the last active item. - */ - this.lastActiveRecord = null; - /** - * Apply this listener to the element that will receive `keydown` events that - * should trigger this controller. - * - * @param event The native browser `KeyboardEvent` from the `keydown` event. - */ - this.onKeydown = (event) => { - if (this.isTypingAhead) { - this.typeahead(event); - } - else { - this.beginTypeahead(event); - } - }; - /** - * Ends the current typeahead and clears the buffer. - */ - this.endTypeahead = () => { - this.isTypingAhead = false; - this.typaheadBuffer = ''; - this.typeaheadRecords = []; - }; - } - get items() { - return this.getProperties().getItems(); - } - get active() { - return this.getProperties().active; - } - /** - * Sets up typingahead - */ - beginTypeahead(event) { - if (!this.active) { - return; - } - // We don't want to typeahead if the _beginning_ of the typeahead is a menu - // navigation, or a selection. We will handle "Space" only if it's in the - // middle of a typeahead - if (event.code === 'Space' || - event.code === 'Enter' || - event.code.startsWith('Arrow') || - event.code === 'Escape') { - return; - } - this.isTypingAhead = true; - // Generates the record array data structure which is the index, the element - // and a normalized header. - this.typeaheadRecords = this.items.map((el, index) => [ - index, - el, - el.typeaheadText.trim().toLowerCase(), - ]); - this.lastActiveRecord = - this.typeaheadRecords.find((record) => record[TYPEAHEAD_RECORD.ITEM].tabIndex === 0) ?? null; - if (this.lastActiveRecord) { - this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].tabIndex = -1; - } - this.typeahead(event); - } - /** - * Performs the typeahead. Based on the normalized items and the current text - * buffer, finds the _next_ item with matching text and activates it. - * - * @example - * - * items: Apple, Banana, Olive, Orange, Cucumber - * buffer: '' - * user types: o - * - * activates Olive - * - * @example - * - * items: Apple, Banana, Olive (active), Orange, Cucumber - * buffer: 'o' - * user types: l - * - * activates Olive - * - * @example - * - * items: Apple, Banana, Olive (active), Orange, Cucumber - * buffer: '' - * user types: o - * - * activates Orange - * - * @example - * - * items: Apple, Banana, Olive, Orange (active), Cucumber - * buffer: '' - * user types: o - * - * activates Olive - */ - typeahead(event) { - if (event.defaultPrevented) - return; - clearTimeout(this.cancelTypeaheadTimeout); - // Stop typingahead if one of the navigation or selection keys (except for - // Space) are pressed - if (event.code === 'Enter' || - event.code.startsWith('Arrow') || - event.code === 'Escape') { - this.endTypeahead(); - if (this.lastActiveRecord) { - this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].tabIndex = -1; - } - return; - } - // If Space is pressed, prevent it from selecting and closing the menu - if (event.code === 'Space') { - event.preventDefault(); - } - // Start up a new keystroke buffer timeout - this.cancelTypeaheadTimeout = setTimeout(this.endTypeahead, this.getProperties().typeaheadBufferTime); - this.typaheadBuffer += event.key.toLowerCase(); - const lastActiveIndex = this.lastActiveRecord - ? this.lastActiveRecord[TYPEAHEAD_RECORD.INDEX] - : -1; - const numRecords = this.typeaheadRecords.length; - /** - * Sorting function that will resort the items starting with the given index - * - * @example - * - * this.typeaheadRecords = - * 0: [0, , 'apple'] - * 1: [1, , 'apricot'] - * 2: [2, , 'banana'] - * 3: [3, , 'olive'] <-- lastActiveIndex - * 4: [4, , 'orange'] - * 5: [5, , 'strawberry'] - * - * this.typeaheadRecords.sort((a,b) => rebaseIndexOnActive(a) - * - rebaseIndexOnActive(b)) === - * 0: [3, , 'olive'] <-- lastActiveIndex - * 1: [4, , 'orange'] - * 2: [5, , 'strawberry'] - * 3: [0, , 'apple'] - * 4: [1, , 'apricot'] - * 5: [2, , 'banana'] - */ - const rebaseIndexOnActive = (record) => { - return ((record[TYPEAHEAD_RECORD.INDEX] + numRecords - lastActiveIndex) % - numRecords); - }; - // records filtered and sorted / rebased around the last active index - const matchingRecords = this.typeaheadRecords - .filter((record) => !record[TYPEAHEAD_RECORD.ITEM].disabled && - record[TYPEAHEAD_RECORD.TEXT].startsWith(this.typaheadBuffer)) - .sort((a, b) => rebaseIndexOnActive(a) - rebaseIndexOnActive(b)); - // Just leave if there's nothing that matches. Native select will just - // choose the first thing that starts with the next letter in the alphabet - // but that's out of scope and hard to localize - if (matchingRecords.length === 0) { - clearTimeout(this.cancelTypeaheadTimeout); - if (this.lastActiveRecord) { - this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].tabIndex = -1; - } - this.endTypeahead(); - return; - } - const isNewQuery = this.typaheadBuffer.length === 1; - let nextRecord; - // This is likely the case that someone is trying to "tab" through different - // entries that start with the same letter - if (this.lastActiveRecord === matchingRecords[0] && isNewQuery) { - nextRecord = matchingRecords[1] ?? matchingRecords[0]; - } - else { - nextRecord = matchingRecords[0]; - } - if (this.lastActiveRecord) { - this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].tabIndex = -1; - } - this.lastActiveRecord = nextRecord; - nextRecord[TYPEAHEAD_RECORD.ITEM].tabIndex = 0; - nextRecord[TYPEAHEAD_RECORD.ITEM].focus(); - return; - } -} -//# sourceMappingURL=typeaheadController.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/menu/internal/menu-styles.js": -/*!*****************************************************************!*\ - !*** ./node_modules/@material/web/menu/internal/menu-styles.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./menu/internal/menu-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{--md-elevation-level: var(--md-menu-container-elevation, 2);--md-elevation-shadow-color: var(--md-menu-container-shadow-color, var(--md-sys-color-shadow, #000));min-width:112px;color:unset;display:contents}md-focus-ring{--md-focus-ring-shape: var(--md-menu-container-shape, var(--md-sys-shape-corner-extra-small, 4px))}.menu{border-radius:var(--md-menu-container-shape, var(--md-sys-shape-corner-extra-small, 4px));display:none;inset:auto;border:none;padding:0px;overflow:visible;background-color:rgba(0,0,0,0);color:inherit;opacity:0;z-index:20;position:absolute;user-select:none;max-height:inherit;height:inherit;min-width:inherit;max-width:inherit;scrollbar-width:inherit}.menu::backdrop{display:none}.fixed{position:fixed}.items{display:block;list-style-type:none;margin:0;outline:none;box-sizing:border-box;background-color:var(--md-menu-container-color, var(--md-sys-color-surface-container, #f3edf7));height:inherit;max-height:inherit;overflow:auto;min-width:inherit;max-width:inherit;border-radius:inherit;scrollbar-width:inherit}.item-padding{padding-block:var(--md-menu-top-space, 8px) var(--md-menu-bottom-space, 8px)}.has-overflow:not([popover]) .items{overflow:visible}.has-overflow.animating .items,.animating .items{overflow:hidden}.has-overflow.animating .items{pointer-events:none}.animating ::slotted(.md-menu-hidden){opacity:0}slot{display:block;height:inherit;max-height:inherit}::slotted(:is(md-divider,[role=separator])){margin:8px 0}@media(forced-colors: active){.menu{border-style:solid;border-color:CanvasText;border-width:1px}} -`; -//# sourceMappingURL=menu-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/menu/internal/menu.js": -/*!**********************************************************!*\ - !*** ./node_modules/@material/web/menu/internal/menu.js ***! - \**********************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Corner: () => (/* reexport safe */ _controllers_surfacePositionController_js__WEBPACK_IMPORTED_MODULE_10__.Corner), -/* harmony export */ DEFAULT_TYPEAHEAD_BUFFER_TIME: () => (/* binding */ DEFAULT_TYPEAHEAD_BUFFER_TIME), -/* harmony export */ Menu: () => (/* binding */ Menu) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var _elevation_elevation_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../elevation/elevation.js */ "./node_modules/@material/web/elevation/elevation.js"); -/* harmony import */ var _focus_md_focus_ring_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../focus/md-focus-ring.js */ "./node_modules/@material/web/focus/md-focus-ring.js"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lit/directives/class-map.js */ "./node_modules/lit/directives/class-map.js"); -/* harmony import */ var lit_directives_style_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lit/directives/style-map.js */ "./node_modules/lit/directives/style-map.js"); -/* harmony import */ var _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../internal/motion/animation.js */ "./node_modules/@material/web/internal/motion/animation.js"); -/* harmony import */ var _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../list/internal/list-controller.js */ "./node_modules/@material/web/list/internal/list-controller.js"); -/* harmony import */ var _list_internal_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../list/internal/list-navigation-helpers.js */ "./node_modules/@material/web/list/internal/list-navigation-helpers.js"); -/* harmony import */ var _controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./controllers/shared.js */ "./node_modules/@material/web/menu/internal/controllers/shared.js"); -/* harmony import */ var _controllers_surfacePositionController_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./controllers/surfacePositionController.js */ "./node_modules/@material/web/menu/internal/controllers/surfacePositionController.js"); -/* harmony import */ var _controllers_typeaheadController_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./controllers/typeaheadController.js */ "./node_modules/@material/web/menu/internal/controllers/typeaheadController.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - - - - - - - - - - -/** - * The default value for the typeahead buffer time in Milliseconds. - */ -const DEFAULT_TYPEAHEAD_BUFFER_TIME = 200; -const submenuNavKeys = new Set([ - _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.NavigableKeys.ArrowDown, - _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.NavigableKeys.ArrowUp, - _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.NavigableKeys.Home, - _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.NavigableKeys.End, -]); -const menuNavKeys = new Set([ - _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.NavigableKeys.ArrowLeft, - _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.NavigableKeys.ArrowRight, - ...submenuNavKeys, -]); -/** - * Gets the currently focused element on the page. - * - * @param activeDoc The document or shadowroot from which to start the search. - * Defaults to `window.document` - * @return Returns the currently deeply focused element or `null` if none. - */ -function getFocusedElement(activeDoc = document) { - let activeEl = activeDoc.activeElement; - // Check for activeElement in the case that an element with a shadow root host - // is currently focused. - while (activeEl && activeEl?.shadowRoot?.activeElement) { - activeEl = activeEl.shadowRoot.activeElement; - } - return activeEl; -} -/** - * @fires opening {Event} Fired before the opening animation begins - * @fires opened {Event} Fired once the menu is open, after any animations - * @fires closing {Event} Fired before the closing animation begins - * @fires closed {Event} Fired once the menu is closed, after any animations - */ -class Menu extends lit__WEBPACK_IMPORTED_MODULE_2__.LitElement { - /** - * Whether the menu is animating upwards or downwards when opening. This is - * helpful for calculating some animation calculations. - */ - get openDirection() { - const menuCornerBlock = this.menuCorner.split('-')[0]; - return menuCornerBlock === 'start' ? 'DOWN' : 'UP'; - } - /** - * The element which the menu should align to. If `anchor` is set to a - * non-empty idref string, then `anchorEl` will resolve to the element with - * the given id in the same root node. Otherwise, `null`. - */ - get anchorElement() { - if (this.anchor) { - return this.getRootNode().querySelector(`#${this.anchor}`); - } - return this.currentAnchorElement; - } - set anchorElement(element) { - this.currentAnchorElement = element; - this.requestUpdate('anchorElement'); - } - constructor() { - super(); - /** - * The ID of the element in the same root node in which the menu should align - * to. Overrides setting `anchorElement = elementReference`. - * - * __NOTE__: anchor or anchorElement must either be an HTMLElement or resolve - * to an HTMLElement in order for menu to open. - */ - this.anchor = ''; - /** - * Whether the positioning algorithm should calculate relative to the parent - * of the anchor element (`absolute`), relative to the window (`fixed`), or - * relative to the document (`document`). `popover` will use the popover API - * to render the menu in the top-layer. If your browser does not support the - * popover API, it will fall back to `fixed`. - * - * __Examples for `position = 'fixed'`:__ - * - * - If there is no `position:relative` in the given parent tree and the - * surface is `position:absolute` - * - If the surface is `position:fixed` - * - If the surface is in the "top layer" - * - The anchor and the surface do not share a common `position:relative` - * ancestor - * - * When using `positioning=fixed`, in most cases, the menu should position - * itself above most other `position:absolute` or `position:fixed` elements - * when placed inside of them. e.g. using a menu inside of an `md-dialog`. - * - * __NOTE__: Fixed menus will not scroll with the page and will be fixed to - * the window instead. - * - * __Examples for `position = 'document'`:__ - * - * - There is no parent that creates a relative positioning context e.g. - * `position: relative`, `position: absolute`, `transform: translate(x, y)`, - * etc. - * - You put the effort into hoisting the menu to the top of the DOM like the - * end of the `` to render over everything or in a top-layer. - * - You are reusing a single `md-menu` element that dynamically renders - * content. - * - * __Examples for `position = 'popover'`:__ - * - * - Your browser supports `popover`. - * - Most cases. Once popover is in browsers, this will become the default. - */ - this.positioning = 'absolute'; - /** - * Skips the opening and closing animations. - */ - this.quick = false; - /** - * Displays overflow content like a submenu. Not required in most cases when - * using `positioning="popover"`. - * - * __NOTE__: This may cause adverse effects if you set - * `md-menu {max-height:...}` - * and have items overflowing items in the "y" direction. - */ - this.hasOverflow = false; - /** - * Opens the menu and makes it visible. Alternative to the `.show()` and - * `.close()` methods - */ - this.open = false; - /** - * Offsets the menu's inline alignment from the anchor by the given number in - * pixels. This value is direction aware and will follow the LTR / RTL - * direction. - * - * e.g. LTR: positive -> right, negative -> left - * RTL: positive -> left, negative -> right - */ - this.xOffset = 0; - /** - * Offsets the menu's block alignment from the anchor by the given number in - * pixels. - * - * e.g. positive -> down, negative -> up - */ - this.yOffset = 0; - /** - * Disable the `flip` behavior that usually happens on the horizontal axis - * when the surface would render outside the viewport. - */ - this.noHorizontalFlip = false; - /** - * Disable the `flip` behavior that usually happens on the vertical axis when - * the surface would render outside the viewport. - */ - this.noVerticalFlip = false; - /** - * The max time between the keystrokes of the typeahead menu behavior before - * it clears the typeahead buffer. - */ - this.typeaheadDelay = DEFAULT_TYPEAHEAD_BUFFER_TIME; - /** - * The corner of the anchor which to align the menu in the standard logical - * property style of - e.g. `'end-start'`. - * - * NOTE: This value may not be respected by the menu positioning algorithm - * if the menu would render outisde the viewport. - * Use `no-horizontal-flip` or `no-vertical-flip` to force the usage of the value - */ - this.anchorCorner = _controllers_surfacePositionController_js__WEBPACK_IMPORTED_MODULE_10__.Corner.END_START; - /** - * The corner of the menu which to align the anchor in the standard logical - * property style of - e.g. `'start-start'`. - * - * NOTE: This value may not be respected by the menu positioning algorithm - * if the menu would render outisde the viewport. - * Use `no-horizontal-flip` or `no-vertical-flip` to force the usage of the value - */ - this.menuCorner = _controllers_surfacePositionController_js__WEBPACK_IMPORTED_MODULE_10__.Corner.START_START; - /** - * Keeps the user clicks outside the menu. - * - * NOTE: clicking outside may still cause focusout to close the menu so see - * `stayOpenOnFocusout`. - */ - this.stayOpenOnOutsideClick = false; - /** - * Keeps the menu open when focus leaves the menu's composed subtree. - * - * NOTE: Focusout behavior will stop propagation of the focusout event. Set - * this property to true to opt-out of menu's focusout handling altogether. - */ - this.stayOpenOnFocusout = false; - /** - * After closing, does not restore focus to the last focused element before - * the menu was opened. - */ - this.skipRestoreFocus = false; - /** - * The element that should be focused by default once opened. - * - * NOTE: When setting default focus to 'LIST_ROOT', remember to change - * `tabindex` to `0` and change md-menu's display to something other than - * `display: contents` when necessary. - */ - this.defaultFocus = _controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.FocusState.FIRST_ITEM; - /** - * Turns off navigation wrapping. By default, navigating past the end of the - * menu items will wrap focus back to the beginning and vice versa. Use this - * for ARIA patterns that do not wrap focus, like combobox. - */ - this.noNavigationWrap = false; - this.typeaheadActive = true; - /** - * Whether or not the current menu is a submenu and should not handle specific - * navigation keys. - * - * @export - */ - this.isSubmenu = false; - /** - * The event path of the last window pointerdown event. - */ - this.pointerPath = []; - /** - * Whether or not the menu is repositoining due to window / document resize - */ - this.isRepositioning = false; - this.openCloseAnimationSignal = (0,_internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_6__.createAnimationSignal)(); - this.listController = new _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.ListController({ - isItem: (maybeItem) => { - return maybeItem.hasAttribute('md-menu-item'); - }, - getPossibleItems: () => this.slotItems, - isRtl: () => getComputedStyle(this).direction === 'rtl', - deactivateItem: (item) => { - item.selected = false; - item.tabIndex = -1; - }, - activateItem: (item) => { - item.selected = true; - item.tabIndex = 0; - }, - isNavigableKey: (key) => { - if (!this.isSubmenu) { - return menuNavKeys.has(key); - } - const isRtl = getComputedStyle(this).direction === 'rtl'; - // we want md-submenu to handle the submenu's left/right arrow exit - // key so it can close the menu instead of navigate the list. - // Therefore we need to include all keys but left/right arrow close - // key - const arrowOpen = isRtl - ? _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.NavigableKeys.ArrowLeft - : _list_internal_list_controller_js__WEBPACK_IMPORTED_MODULE_7__.NavigableKeys.ArrowRight; - if (key === arrowOpen) { - return true; - } - return submenuNavKeys.has(key); - }, - wrapNavigation: () => !this.noNavigationWrap, - }); - /** - * The element that was focused before the menu opened. - */ - this.lastFocusedElement = null; - /** - * Handles typeahead navigation through the menu. - */ - this.typeaheadController = new _controllers_typeaheadController_js__WEBPACK_IMPORTED_MODULE_11__.TypeaheadController(() => { - return { - getItems: () => this.items, - typeaheadBufferTime: this.typeaheadDelay, - active: this.typeaheadActive, - }; - }); - this.currentAnchorElement = null; - this.internals = - // Cast needed for closure - this.attachInternals(); - /** - * Handles positioning the surface and aligning it to the anchor as well as - * keeping it in the viewport. - */ - this.menuPositionController = new _controllers_surfacePositionController_js__WEBPACK_IMPORTED_MODULE_10__.SurfacePositionController(this, () => { - return { - anchorCorner: this.anchorCorner, - surfaceCorner: this.menuCorner, - surfaceEl: this.surfaceEl, - anchorEl: this.anchorElement, - positioning: this.positioning === 'popover' ? 'document' : this.positioning, - isOpen: this.open, - xOffset: this.xOffset, - yOffset: this.yOffset, - disableBlockFlip: this.noVerticalFlip, - disableInlineFlip: this.noHorizontalFlip, - onOpen: this.onOpened, - beforeClose: this.beforeClose, - onClose: this.onClosed, - // We can't resize components that have overflow like menus with - // submenus because the overflow-y will show menu items / content - // outside the bounds of the menu. Popover API fixes this because each - // submenu is hoisted to the top-layer and are not considered overflow - // content. - repositionStrategy: this.hasOverflow && this.positioning !== 'popover' - ? 'move' - : 'resize', - }; - }); - this.onWindowResize = () => { - if (this.isRepositioning || - (this.positioning !== 'document' && - this.positioning !== 'fixed' && - this.positioning !== 'popover')) { - return; - } - this.isRepositioning = true; - this.reposition(); - this.isRepositioning = false; - }; - this.handleFocusout = async (event) => { - const anchorEl = this.anchorElement; - // Do not close if we focused out by clicking on the anchor element. We - // can't assume anchor buttons can be the related target because of iOS does - // not focus buttons. - if (this.stayOpenOnFocusout || - !this.open || - this.pointerPath.includes(anchorEl)) { - return; - } - if (event.relatedTarget) { - // Don't close the menu if we are switching focus between menu, - // md-menu-item, and md-list or if the anchor was click focused, but check - // if length of pointerPath is 0 because that means something was at least - // clicked (shift+tab case). - if ((0,_controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.isElementInSubtree)(event.relatedTarget, this) || - (this.pointerPath.length !== 0 && - (0,_controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.isElementInSubtree)(event.relatedTarget, anchorEl))) { - return; - } - } - else if (this.pointerPath.includes(this)) { - // If menu tabindex == -1 and the user clicks on the menu or a divider, we - // want to keep the menu open. - return; - } - const oldRestoreFocus = this.skipRestoreFocus; - // allow focus to continue to the next focused object rather than returning - this.skipRestoreFocus = true; - this.close(); - // await for close - await this.updateComplete; - // return to previous behavior - this.skipRestoreFocus = oldRestoreFocus; - }; - /** - * Saves the last focused element focuses the new element based on - * `defaultFocus`, and animates open. - */ - this.onOpened = async () => { - this.lastFocusedElement = getFocusedElement(); - const items = this.items; - const activeItemRecord = (0,_list_internal_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_8__.getActiveItem)(items); - if (activeItemRecord && this.defaultFocus !== _controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.FocusState.NONE) { - activeItemRecord.item.tabIndex = -1; - } - let animationAborted = !this.quick; - if (this.quick) { - this.dispatchEvent(new Event('opening')); - } - else { - animationAborted = !!(await this.animateOpen()); - } - // This must come after the opening animation or else it may focus one of - // the items before the animation has begun and causes the list to slide - // (block-padding-of-the-menu)px at the end of the animation - switch (this.defaultFocus) { - case _controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.FocusState.FIRST_ITEM: - const first = (0,_list_internal_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_8__.getFirstActivatableItem)(items); - if (first) { - first.tabIndex = 0; - first.focus(); - await first.updateComplete; - } - break; - case _controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.FocusState.LAST_ITEM: - const last = (0,_list_internal_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_8__.getLastActivatableItem)(items); - if (last) { - last.tabIndex = 0; - last.focus(); - await last.updateComplete; - } - break; - case _controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.FocusState.LIST_ROOT: - this.focus(); - break; - default: - case _controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.FocusState.NONE: - // Do nothing. - break; - } - if (!animationAborted) { - this.dispatchEvent(new Event('opened')); - } - }; - /** - * Animates closed. - */ - this.beforeClose = async () => { - this.open = false; - if (!this.skipRestoreFocus) { - this.lastFocusedElement?.focus?.(); - } - if (!this.quick) { - await this.animateClose(); - } - }; - /** - * Focuses the last focused element. - */ - this.onClosed = () => { - if (this.quick) { - this.dispatchEvent(new Event('closing')); - this.dispatchEvent(new Event('closed')); - } - }; - this.onWindowPointerdown = (event) => { - this.pointerPath = event.composedPath(); - }; - /** - * We cannot listen to window click because Safari on iOS will not bubble a - * click event on window if the item clicked is not a "clickable" item such as - * - */ - this.onDocumentClick = (event) => { - if (!this.open) { - return; - } - const path = event.composedPath(); - if (!this.stayOpenOnOutsideClick && - !path.includes(this) && - !path.includes(this.anchorElement)) { - this.open = false; - } - }; - if (!lit__WEBPACK_IMPORTED_MODULE_2__.isServer) { - this.internals.role = 'menu'; - this.addEventListener('keydown', this.handleKeydown); - // Capture so that we can grab the event before it reaches the menu item - // istelf. Specifically useful for the case where typeahead encounters a - // space and we don't want the menu item to close the menu. - this.addEventListener('keydown', this.captureKeydown, { capture: true }); - this.addEventListener('focusout', this.handleFocusout); - } - } - /** - * The menu items associated with this menu. The items must be `MenuItem`s and - * have both the `md-menu-item` and `md-list-item` attributes. - */ - get items() { - return this.listController.items; - } - willUpdate(changed) { - if (!changed.has('open')) { - return; - } - if (this.open) { - this.removeAttribute('aria-hidden'); - return; - } - this.setAttribute('aria-hidden', 'true'); - } - update(changed) { - if (changed.has('open')) { - if (this.open) { - this.setUpGlobalEventListeners(); - } - else { - this.cleanUpGlobalEventListeners(); - } - } - // Firefox does not support popover. Fall-back to using fixed. - if (changed.has('positioning') && - this.positioning === 'popover' && - // type required for Google JS conformance - !this.showPopover) { - this.positioning = 'fixed'; - } - super.update(changed); - } - connectedCallback() { - super.connectedCallback(); - if (this.open) { - this.setUpGlobalEventListeners(); - } - } - disconnectedCallback() { - super.disconnectedCallback(); - this.cleanUpGlobalEventListeners(); - } - getBoundingClientRect() { - if (!this.surfaceEl) { - return super.getBoundingClientRect(); - } - return this.surfaceEl.getBoundingClientRect(); - } - getClientRects() { - if (!this.surfaceEl) { - return super.getClientRects(); - } - return this.surfaceEl.getClientRects(); - } - render() { - return this.renderSurface(); - } - /** - * Renders the positionable surface element and its contents. - */ - renderSurface() { - return (0,lit__WEBPACK_IMPORTED_MODULE_2__.html) ` - - `; - } - /** - * Renders the menu items' slot - */ - renderMenuItems() { - return (0,lit__WEBPACK_IMPORTED_MODULE_2__.html) ``; - } - /** - * Renders the elevation component. - */ - renderElevation() { - return (0,lit__WEBPACK_IMPORTED_MODULE_2__.html) ``; - } - getSurfaceClasses() { - return { - open: this.open, - fixed: this.positioning === 'fixed', - 'has-overflow': this.hasOverflow, - }; - } - captureKeydown(event) { - if (event.target === this && - !event.defaultPrevented && - (0,_controllers_shared_js__WEBPACK_IMPORTED_MODULE_9__.isClosableKey)(event.code)) { - event.preventDefault(); - this.close(); - } - this.typeaheadController.onKeydown(event); - } - /** - * Performs the opening animation: - * - * https://direct.googleplex.com/#/spec/295000003+271060003 - * - * @return A promise that resolve to `true` if the animation was aborted, - * `false` if it was not aborted. - */ - async animateOpen() { - const surfaceEl = this.surfaceEl; - const slotEl = this.slotEl; - if (!surfaceEl || !slotEl) - return true; - const openDirection = this.openDirection; - this.dispatchEvent(new Event('opening')); - // needs to be imperative because we don't want to mix animation and Lit - // render timing - surfaceEl.classList.toggle('animating', true); - const signal = this.openCloseAnimationSignal.start(); - const height = surfaceEl.offsetHeight; - const openingUpwards = openDirection === 'UP'; - const children = this.items; - const FULL_DURATION = 500; - const SURFACE_OPACITY_DURATION = 50; - const ITEM_OPACITY_DURATION = 250; - // We want to fit every child fade-in animation within the full duration of - // the animation. - const DELAY_BETWEEN_ITEMS = (FULL_DURATION - ITEM_OPACITY_DURATION) / children.length; - const surfaceHeightAnimation = surfaceEl.animate([{ height: '0px' }, { height: `${height}px` }], { - duration: FULL_DURATION, - easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_6__.EASING.EMPHASIZED, - }); - // When we are opening upwards, we want to make sure the last item is always - // in view, so we need to translate it upwards the opposite direction of the - // height animation - const upPositionCorrectionAnimation = slotEl.animate([ - { transform: openingUpwards ? `translateY(-${height}px)` : '' }, - { transform: '' }, - ], { duration: FULL_DURATION, easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_6__.EASING.EMPHASIZED }); - const surfaceOpacityAnimation = surfaceEl.animate([{ opacity: 0 }, { opacity: 1 }], SURFACE_OPACITY_DURATION); - const childrenAnimations = []; - for (let i = 0; i < children.length; i++) { - // If we are animating upwards, then reverse the children list. - const directionalIndex = openingUpwards ? children.length - 1 - i : i; - const child = children[directionalIndex]; - const animation = child.animate([{ opacity: 0 }, { opacity: 1 }], { - duration: ITEM_OPACITY_DURATION, - delay: DELAY_BETWEEN_ITEMS * i, - }); - // Make them all initially hidden and then clean up at the end of each - // animation. - child.classList.toggle('md-menu-hidden', true); - animation.addEventListener('finish', () => { - child.classList.toggle('md-menu-hidden', false); - }); - childrenAnimations.push([child, animation]); - } - let resolveAnimation = (value) => { }; - const animationFinished = new Promise((resolve) => { - resolveAnimation = resolve; - }); - signal.addEventListener('abort', () => { - surfaceHeightAnimation.cancel(); - upPositionCorrectionAnimation.cancel(); - surfaceOpacityAnimation.cancel(); - childrenAnimations.forEach(([child, animation]) => { - child.classList.toggle('md-menu-hidden', false); - animation.cancel(); - }); - resolveAnimation(true); - }); - surfaceHeightAnimation.addEventListener('finish', () => { - surfaceEl.classList.toggle('animating', false); - this.openCloseAnimationSignal.finish(); - resolveAnimation(false); - }); - return await animationFinished; - } - /** - * Performs the closing animation: - * - * https://direct.googleplex.com/#/spec/295000003+271060003 - */ - animateClose() { - let resolve; - // This promise blocks the surface position controller from setting - // display: none on the surface which will interfere with this animation. - const animationEnded = new Promise((res) => { - resolve = res; - }); - const surfaceEl = this.surfaceEl; - const slotEl = this.slotEl; - if (!surfaceEl || !slotEl) { - resolve(false); - return animationEnded; - } - const openDirection = this.openDirection; - const closingDownwards = openDirection === 'UP'; - this.dispatchEvent(new Event('closing')); - // needs to be imperative because we don't want to mix animation and Lit - // render timing - surfaceEl.classList.toggle('animating', true); - const signal = this.openCloseAnimationSignal.start(); - const height = surfaceEl.offsetHeight; - const children = this.items; - const FULL_DURATION = 150; - const SURFACE_OPACITY_DURATION = 50; - // The surface fades away at the very end - const SURFACE_OPACITY_DELAY = FULL_DURATION - SURFACE_OPACITY_DURATION; - const ITEM_OPACITY_DURATION = 50; - const ITEM_OPACITY_INITIAL_DELAY = 50; - const END_HEIGHT_PERCENTAGE = 0.35; - // We want to fit every child fade-out animation within the full duration of - // the animation. - const DELAY_BETWEEN_ITEMS = (FULL_DURATION - ITEM_OPACITY_INITIAL_DELAY - ITEM_OPACITY_DURATION) / - children.length; - // The mock has the animation shrink to 35% - const surfaceHeightAnimation = surfaceEl.animate([ - { height: `${height}px` }, - { height: `${height * END_HEIGHT_PERCENTAGE}px` }, - ], { - duration: FULL_DURATION, - easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_6__.EASING.EMPHASIZED_ACCELERATE, - }); - // When we are closing downwards, we want to make sure the last item is - // always in view, so we need to translate it upwards the opposite direction - // of the height animation - const downPositionCorrectionAnimation = slotEl.animate([ - { transform: '' }, - { - transform: closingDownwards - ? `translateY(-${height * (1 - END_HEIGHT_PERCENTAGE)}px)` - : '', - }, - ], { duration: FULL_DURATION, easing: _internal_motion_animation_js__WEBPACK_IMPORTED_MODULE_6__.EASING.EMPHASIZED_ACCELERATE }); - const surfaceOpacityAnimation = surfaceEl.animate([{ opacity: 1 }, { opacity: 0 }], { duration: SURFACE_OPACITY_DURATION, delay: SURFACE_OPACITY_DELAY }); - const childrenAnimations = []; - for (let i = 0; i < children.length; i++) { - // If the animation is closing upwards, then reverse the list of - // children so that we animate in the opposite direction. - const directionalIndex = closingDownwards ? i : children.length - 1 - i; - const child = children[directionalIndex]; - const animation = child.animate([{ opacity: 1 }, { opacity: 0 }], { - duration: ITEM_OPACITY_DURATION, - delay: ITEM_OPACITY_INITIAL_DELAY + DELAY_BETWEEN_ITEMS * i, - }); - // Make sure the items stay hidden at the end of each child animation. - // We clean this up at the end of the overall animation. - animation.addEventListener('finish', () => { - child.classList.toggle('md-menu-hidden', true); - }); - childrenAnimations.push([child, animation]); - } - signal.addEventListener('abort', () => { - surfaceHeightAnimation.cancel(); - downPositionCorrectionAnimation.cancel(); - surfaceOpacityAnimation.cancel(); - childrenAnimations.forEach(([child, animation]) => { - animation.cancel(); - child.classList.toggle('md-menu-hidden', false); - }); - resolve(false); - }); - surfaceHeightAnimation.addEventListener('finish', () => { - surfaceEl.classList.toggle('animating', false); - childrenAnimations.forEach(([child]) => { - child.classList.toggle('md-menu-hidden', false); - }); - this.openCloseAnimationSignal.finish(); - this.dispatchEvent(new Event('closed')); - resolve(true); - }); - return animationEnded; - } - handleKeydown(event) { - // At any key event, the pointer interaction is done so we need to clear our - // cached pointerpath. This handles the case where the user clicks on the - // anchor, and then hits shift+tab - this.pointerPath = []; - this.listController.handleKeydown(event); - } - setUpGlobalEventListeners() { - document.addEventListener('click', this.onDocumentClick, { capture: true }); - window.addEventListener('pointerdown', this.onWindowPointerdown); - document.addEventListener('resize', this.onWindowResize, { passive: true }); - window.addEventListener('resize', this.onWindowResize, { passive: true }); - } - cleanUpGlobalEventListeners() { - document.removeEventListener('click', this.onDocumentClick, { - capture: true, - }); - window.removeEventListener('pointerdown', this.onWindowPointerdown); - document.removeEventListener('resize', this.onWindowResize); - window.removeEventListener('resize', this.onWindowResize); - } - onCloseMenu() { - this.close(); - } - onDeactivateItems(event) { - event.stopPropagation(); - this.listController.onDeactivateItems(); - } - onRequestActivation(event) { - event.stopPropagation(); - this.listController.onRequestActivation(event); - } - handleDeactivateTypeahead(event) { - // stopPropagation so that this does not deactivate any typeaheads in menus - // nested above it e.g. md-sub-menu - event.stopPropagation(); - this.typeaheadActive = false; - } - handleActivateTypeahead(event) { - // stopPropagation so that this does not activate any typeaheads in menus - // nested above it e.g. md-sub-menu - event.stopPropagation(); - this.typeaheadActive = true; - } - handleStayOpenOnFocusout(event) { - event.stopPropagation(); - this.stayOpenOnFocusout = true; - } - handleCloseOnFocusout(event) { - event.stopPropagation(); - this.stayOpenOnFocusout = false; - } - close() { - this.open = false; - const maybeSubmenu = this.slotItems; - maybeSubmenu.forEach((item) => { - item.close?.(); - }); - } - show() { - this.open = true; - } - /** - * Activates the next item in the menu. If at the end of the menu, the first - * item will be activated. - * - * @return The activated menu item or `null` if there are no items. - */ - activateNextItem() { - return this.listController.activateNextItem() ?? null; - } - /** - * Activates the previous item in the menu. If at the start of the menu, the - * last item will be activated. - * - * @return The activated menu item or `null` if there are no items. - */ - activatePreviousItem() { - return this.listController.activatePreviousItem() ?? null; - } - /** - * Repositions the menu if it is open. - * - * Useful for the case where document or window-positioned menus have their - * anchors moved while open. - */ - reposition() { - if (this.open) { - this.menuPositionController.position(); - } - } -} -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.query)('.menu') -], Menu.prototype, "surfaceEl", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.query)('slot') -], Menu.prototype, "slotEl", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)() -], Menu.prototype, "anchor", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)() -], Menu.prototype, "positioning", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean }) -], Menu.prototype, "quick", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'has-overflow' }) -], Menu.prototype, "hasOverflow", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, reflect: true }) -], Menu.prototype, "open", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Number, attribute: 'x-offset' }) -], Menu.prototype, "xOffset", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Number, attribute: 'y-offset' }) -], Menu.prototype, "yOffset", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'no-horizontal-flip' }) -], Menu.prototype, "noHorizontalFlip", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'no-vertical-flip' }) -], Menu.prototype, "noVerticalFlip", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Number, attribute: 'typeahead-delay' }) -], Menu.prototype, "typeaheadDelay", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ attribute: 'anchor-corner' }) -], Menu.prototype, "anchorCorner", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ attribute: 'menu-corner' }) -], Menu.prototype, "menuCorner", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'stay-open-on-outside-click' }) -], Menu.prototype, "stayOpenOnOutsideClick", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'stay-open-on-focusout' }) -], Menu.prototype, "stayOpenOnFocusout", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'skip-restore-focus' }) -], Menu.prototype, "skipRestoreFocus", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ attribute: 'default-focus' }) -], Menu.prototype, "defaultFocus", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.property)({ type: Boolean, attribute: 'no-navigation-wrap' }) -], Menu.prototype, "noNavigationWrap", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.queryAssignedElements)({ flatten: true }) -], Menu.prototype, "slotItems", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_12__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_3__.state)() -], Menu.prototype, "typeaheadActive", void 0); -//# sourceMappingURL=menu.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/menu/internal/menuitem/menu-item-styles.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@material/web/menu/internal/menuitem/menu-item-styles.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./menu/internal/menuitem/menu-item-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{display:flex;--md-ripple-hover-color: var(--md-menu-item-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-hover-opacity: var(--md-menu-item-hover-state-layer-opacity, 0.08);--md-ripple-pressed-color: var(--md-menu-item-pressed-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--md-ripple-pressed-opacity: var(--md-menu-item-pressed-state-layer-opacity, 0.12)}:host([disabled]){opacity:var(--md-menu-item-disabled-opacity, 0.3);pointer-events:none}md-focus-ring{z-index:1;--md-focus-ring-shape: 8px}a,button,li{background:none;border:none;padding:0;margin:0;text-align:unset;text-decoration:none}.list-item{border-radius:inherit;display:flex;flex:1;max-width:inherit;min-width:inherit;outline:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.list-item:not(.disabled){cursor:pointer}[slot=container]{pointer-events:none}md-ripple{border-radius:inherit}md-item{border-radius:inherit;flex:1;color:var(--md-menu-item-label-text-color, var(--md-sys-color-on-surface, #1d1b20));font-family:var(--md-menu-item-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-menu-item-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));line-height:var(--md-menu-item-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));font-weight:var(--md-menu-item-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));min-height:var(--md-menu-item-one-line-container-height, 56px);padding-top:var(--md-menu-item-top-space, 12px);padding-bottom:var(--md-menu-item-bottom-space, 12px);padding-inline-start:var(--md-menu-item-leading-space, 16px);padding-inline-end:var(--md-menu-item-trailing-space, 16px)}md-item[multiline]{min-height:var(--md-menu-item-two-line-container-height, 72px)}[slot=supporting-text]{color:var(--md-menu-item-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-menu-item-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-menu-item-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-menu-item-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));font-weight:var(--md-menu-item-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)))}[slot=trailing-supporting-text]{color:var(--md-menu-item-trailing-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-menu-item-trailing-supporting-text-font, var(--md-sys-typescale-label-small-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-menu-item-trailing-supporting-text-size, var(--md-sys-typescale-label-small-size, 0.6875rem));line-height:var(--md-menu-item-trailing-supporting-text-line-height, var(--md-sys-typescale-label-small-line-height, 1rem));font-weight:var(--md-menu-item-trailing-supporting-text-weight, var(--md-sys-typescale-label-small-weight, var(--md-ref-typeface-weight-medium, 500)))}:is([slot=start],[slot=end])::slotted(*){fill:currentColor}[slot=start]{color:var(--md-menu-item-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f))}[slot=end]{color:var(--md-menu-item-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f))}.list-item{background-color:var(--md-menu-item-container-color, transparent)}.list-item.selected{background-color:var(--md-menu-item-selected-container-color, var(--md-sys-color-secondary-container, #e8def8))}.selected:not(.disabled) ::slotted(*){color:var(--md-menu-item-selected-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b))}@media(forced-colors: active){:host([disabled]),:host([disabled]) slot{color:GrayText;opacity:1}.list-item{position:relative}.list-item.selected::before{content:"";position:absolute;inset:0;box-sizing:border-box;border-radius:inherit;pointer-events:none;border:3px double CanvasText}} -`; -//# sourceMappingURL=menu-item-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/menu/menu.js": -/*!*************************************************!*\ - !*** ./node_modules/@material/web/menu/menu.js ***! - \*************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ CloseReason: () => (/* reexport safe */ _internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_3__.CloseReason), -/* harmony export */ Corner: () => (/* reexport safe */ _internal_menu_js__WEBPACK_IMPORTED_MODULE_1__.Corner), -/* harmony export */ FocusState: () => (/* reexport safe */ _internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_3__.FocusState), -/* harmony export */ MdMenu: () => (/* binding */ MdMenu) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _internal_menu_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./internal/menu.js */ "./node_modules/@material/web/menu/internal/menu.js"); -/* harmony import */ var _internal_menu_styles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal/menu-styles.js */ "./node_modules/@material/web/menu/internal/menu-styles.js"); -/* harmony import */ var _internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./internal/controllers/shared.js */ "./node_modules/@material/web/menu/internal/controllers/shared.js"); -/** - * @license - * Copyright 2022 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - - -/** - * @summary Menus display a list of choices on a temporary surface. - * - * @description - * Menus appear when users interact with a button, action, or other control. - * - * They can be opened from a variety of elements, most commonly icon buttons, - * buttons, and text fields. - * - * md-menu listens for the `close-menu` and `deselect-items` events. - * - * - `close-menu` closes the menu when dispatched from a child element. - * - `deselect-items` deselects all of its immediate menu-item children. - * - * @example - * ```html - *
    - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    - * ``` - * - * @final - * @suppress {visibility} - */ -let MdMenu = class MdMenu extends _internal_menu_js__WEBPACK_IMPORTED_MODULE_1__.Menu { -}; -MdMenu.styles = [_internal_menu_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles]; -MdMenu = (0,tslib__WEBPACK_IMPORTED_MODULE_4__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_0__.customElement)('md-menu') -], MdMenu); - -//# sourceMappingURL=menu.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/progress/internal/circular-progress-styles.js": -/*!**********************************************************************************!*\ - !*** ./node_modules/@material/web/progress/internal/circular-progress-styles.js ***! - \**********************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./progress/internal/circular-progress-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{--_active-indicator-color: var(--md-circular-progress-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_active-indicator-width: var(--md-circular-progress-active-indicator-width, 10);--_four-color-active-indicator-four-color: var(--md-circular-progress-four-color-active-indicator-four-color, var(--md-sys-color-tertiary-container, #ffd8e4));--_four-color-active-indicator-one-color: var(--md-circular-progress-four-color-active-indicator-one-color, var(--md-sys-color-primary, #6750a4));--_four-color-active-indicator-three-color: var(--md-circular-progress-four-color-active-indicator-three-color, var(--md-sys-color-tertiary, #7d5260));--_four-color-active-indicator-two-color: var(--md-circular-progress-four-color-active-indicator-two-color, var(--md-sys-color-primary-container, #eaddff));--_size: var(--md-circular-progress-size, 48px);display:inline-flex;vertical-align:middle;width:var(--_size);height:var(--_size);position:relative;align-items:center;justify-content:center;contain:strict;content-visibility:auto}.progress{flex:1;align-self:stretch;margin:4px}.progress,.spinner,.left,.right,.circle,svg,.track,.active-track{position:absolute;inset:0}svg{transform:rotate(-90deg)}circle{cx:50%;cy:50%;r:calc(50%*(1 - var(--_active-indicator-width)/100));stroke-width:calc(var(--_active-indicator-width)*1%);stroke-dasharray:100;fill:rgba(0,0,0,0)}.active-track{transition:stroke-dashoffset 500ms cubic-bezier(0, 0, 0.2, 1);stroke:var(--_active-indicator-color)}.track{stroke:rgba(0,0,0,0)}.progress.indeterminate{animation:linear infinite linear-rotate;animation-duration:1568.2352941176ms}.spinner{animation:infinite both rotate-arc;animation-duration:5332ms;animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1)}.left{overflow:hidden;inset:0 50% 0 0}.right{overflow:hidden;inset:0 0 0 50%}.circle{box-sizing:border-box;border-radius:50%;border:solid calc(var(--_active-indicator-width)/100*(var(--_size) - 8px));border-color:var(--_active-indicator-color) var(--_active-indicator-color) rgba(0,0,0,0) rgba(0,0,0,0);animation:expand-arc;animation-iteration-count:infinite;animation-fill-mode:both;animation-duration:1333ms,5332ms;animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1)}.four-color .circle{animation-name:expand-arc,four-color}.left .circle{rotate:135deg;inset:0 -100% 0 0}.right .circle{rotate:100deg;inset:0 0 0 -100%;animation-delay:-666.5ms,0ms}@media(forced-colors: active){.active-track{stroke:CanvasText}.circle{border-color:CanvasText CanvasText Canvas Canvas}}@keyframes expand-arc{0%{transform:rotate(265deg)}50%{transform:rotate(130deg)}100%{transform:rotate(265deg)}}@keyframes rotate-arc{12.5%{transform:rotate(135deg)}25%{transform:rotate(270deg)}37.5%{transform:rotate(405deg)}50%{transform:rotate(540deg)}62.5%{transform:rotate(675deg)}75%{transform:rotate(810deg)}87.5%{transform:rotate(945deg)}100%{transform:rotate(1080deg)}}@keyframes linear-rotate{to{transform:rotate(360deg)}}@keyframes four-color{0%{border-top-color:var(--_four-color-active-indicator-one-color);border-right-color:var(--_four-color-active-indicator-one-color)}15%{border-top-color:var(--_four-color-active-indicator-one-color);border-right-color:var(--_four-color-active-indicator-one-color)}25%{border-top-color:var(--_four-color-active-indicator-two-color);border-right-color:var(--_four-color-active-indicator-two-color)}40%{border-top-color:var(--_four-color-active-indicator-two-color);border-right-color:var(--_four-color-active-indicator-two-color)}50%{border-top-color:var(--_four-color-active-indicator-three-color);border-right-color:var(--_four-color-active-indicator-three-color)}65%{border-top-color:var(--_four-color-active-indicator-three-color);border-right-color:var(--_four-color-active-indicator-three-color)}75%{border-top-color:var(--_four-color-active-indicator-four-color);border-right-color:var(--_four-color-active-indicator-four-color)}90%{border-top-color:var(--_four-color-active-indicator-four-color);border-right-color:var(--_four-color-active-indicator-four-color)}100%{border-top-color:var(--_four-color-active-indicator-one-color);border-right-color:var(--_four-color-active-indicator-one-color)}} -`; -//# sourceMappingURL=circular-progress-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/progress/internal/circular-progress.js": -/*!***************************************************************************!*\ - !*** ./node_modules/@material/web/progress/internal/circular-progress.js ***! - \***************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ CircularProgress: () => (/* binding */ CircularProgress) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var _progress_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./progress.js */ "./node_modules/@material/web/progress/internal/progress.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - -/** - * A circular progress component. - */ -class CircularProgress extends _progress_js__WEBPACK_IMPORTED_MODULE_1__.Progress { - renderIndicator() { - if (this.indeterminate) { - return this.renderIndeterminateContainer(); - } - return this.renderDeterminateContainer(); - } - // Determinate mode is rendered with an svg so the progress arc can be - // easily animated via stroke-dashoffset. - renderDeterminateContainer() { - const dashOffset = (1 - this.value / this.max) * 100; - // note, dash-array/offset are relative to Setting `pathLength` but - // Chrome seems to render this inaccurately and using a large viewbox helps. - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - - - - `; - } - // Indeterminate mode rendered with 2 bordered-divs. The borders are - // clipped into half circles by their containers. The divs are then carefully - // animated to produce changes to the spinner arc size. - // This approach has 4.5x the FPS of rendering via svg on Chrome 111. - // See https://lit.dev/playground/#gist=febb773565272f75408ab06a0eb49746. - renderIndeterminateContainer() { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `
    -
    -
    -
    -
    -
    -
    -
    `; - } -} -//# sourceMappingURL=circular-progress.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/progress/internal/progress.js": -/*!******************************************************************!*\ - !*** ./node_modules/@material/web/progress/internal/progress.js ***! - \******************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Progress: () => (/* binding */ Progress) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lit/directives/class-map.js */ "./node_modules/lit/directives/class-map.js"); -/* harmony import */ var _internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../internal/aria/delegate.js */ "./node_modules/@material/web/internal/aria/delegate.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - -// Separate variable needed for closure. -const progressBaseClass = (0,_internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_3__.mixinDelegatesAria)(lit__WEBPACK_IMPORTED_MODULE_0__.LitElement); -/** - * A progress component. - */ -class Progress extends progressBaseClass { - constructor() { - super(...arguments); - /** - * Progress to display, a fraction between 0 and `max`. - */ - this.value = 0; - /** - * Maximum progress to display, defaults to 1. - */ - this.max = 1; - /** - * Whether or not to display indeterminate progress, which gives no indication - * to how long an activity will take. - */ - this.indeterminate = false; - /** - * Whether or not to render indeterminate mode using 4 colors instead of one. - */ - this.fourColor = false; - } - render() { - // Needed for closure conformance - const { ariaLabel } = this; - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    ${this.renderIndicator()}
    - `; - } - getRenderClasses() { - return { - 'indeterminate': this.indeterminate, - 'four-color': this.fourColor, - }; - } -} -(0,tslib__WEBPACK_IMPORTED_MODULE_4__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Number }) -], Progress.prototype, "value", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_4__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Number }) -], Progress.prototype, "max", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_4__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean }) -], Progress.prototype, "indeterminate", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_4__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, attribute: 'four-color' }) -], Progress.prototype, "fourColor", void 0); -//# sourceMappingURL=progress.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/select/internal/filled-select-styles.js": -/*!****************************************************************************!*\ - !*** ./node_modules/@material/web/select/internal/filled-select-styles.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./select/internal/filled-select-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{--_text-field-active-indicator-color: var(--md-filled-select-text-field-active-indicator-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-active-indicator-height: var(--md-filled-select-text-field-active-indicator-height, 1px);--_text-field-container-color: var(--md-filled-select-text-field-container-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_text-field-disabled-active-indicator-color: var(--md-filled-select-text-field-disabled-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-active-indicator-height: var(--md-filled-select-text-field-disabled-active-indicator-height, 1px);--_text-field-disabled-active-indicator-opacity: var(--md-filled-select-text-field-disabled-active-indicator-opacity, 0.38);--_text-field-disabled-container-color: var(--md-filled-select-text-field-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-container-opacity: var(--md-filled-select-text-field-disabled-container-opacity, 0.04);--_text-field-disabled-input-text-color: var(--md-filled-select-text-field-disabled-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-input-text-opacity: var(--md-filled-select-text-field-disabled-input-text-opacity, 0.38);--_text-field-disabled-label-text-color: var(--md-filled-select-text-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-label-text-opacity: var(--md-filled-select-text-field-disabled-label-text-opacity, 0.38);--_text-field-disabled-leading-icon-color: var(--md-filled-select-text-field-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-leading-icon-opacity: var(--md-filled-select-text-field-disabled-leading-icon-opacity, 0.38);--_text-field-disabled-supporting-text-color: var(--md-filled-select-text-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-supporting-text-opacity: var(--md-filled-select-text-field-disabled-supporting-text-opacity, 0.38);--_text-field-disabled-trailing-icon-color: var(--md-filled-select-text-field-disabled-trailing-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-disabled-trailing-icon-opacity: var(--md-filled-select-text-field-disabled-trailing-icon-opacity, 0.38);--_text-field-error-active-indicator-color: var(--md-filled-select-text-field-error-active-indicator-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-active-indicator-color: var(--md-filled-select-text-field-error-focus-active-indicator-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-input-text-color: var(--md-filled-select-text-field-error-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-focus-label-text-color: var(--md-filled-select-text-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-leading-icon-color: var(--md-filled-select-text-field-error-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-focus-supporting-text-color: var(--md-filled-select-text-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-focus-trailing-icon-color: var(--md-filled-select-text-field-error-focus-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_text-field-error-hover-active-indicator-color: var(--md-filled-select-text-field-error-hover-active-indicator-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-hover-input-text-color: var(--md-filled-select-text-field-error-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-hover-label-text-color: var(--md-filled-select-text-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-hover-leading-icon-color: var(--md-filled-select-text-field-error-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-hover-state-layer-color: var(--md-filled-select-text-field-error-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-hover-state-layer-opacity: var(--md-filled-select-text-field-error-hover-state-layer-opacity, 0.08);--_text-field-error-hover-supporting-text-color: var(--md-filled-select-text-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-hover-trailing-icon-color: var(--md-filled-select-text-field-error-hover-trailing-icon-color, var(--md-sys-color-on-error-container, #410e0b));--_text-field-error-input-text-color: var(--md-filled-select-text-field-error-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-error-label-text-color: var(--md-filled-select-text-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-leading-icon-color: var(--md-filled-select-text-field-error-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-error-supporting-text-color: var(--md-filled-select-text-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_text-field-error-trailing-icon-color: var(--md-filled-select-text-field-error-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_text-field-focus-active-indicator-color: var(--md-filled-select-text-field-focus-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_text-field-focus-active-indicator-height: var(--md-filled-select-text-field-focus-active-indicator-height, 3px);--_text-field-focus-input-text-color: var(--md-filled-select-text-field-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-focus-label-text-color: var(--md-filled-select-text-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_text-field-focus-leading-icon-color: var(--md-filled-select-text-field-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-focus-supporting-text-color: var(--md-filled-select-text-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-focus-trailing-icon-color: var(--md-filled-select-text-field-focus-trailing-icon-color, var(--md-sys-color-primary, #6750a4));--_text-field-hover-active-indicator-color: var(--md-filled-select-text-field-hover-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-active-indicator-height: var(--md-filled-select-text-field-hover-active-indicator-height, 1px);--_text-field-hover-input-text-color: var(--md-filled-select-text-field-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-label-text-color: var(--md-filled-select-text-field-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-leading-icon-color: var(--md-filled-select-text-field-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-hover-state-layer-color: var(--md-filled-select-text-field-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-hover-state-layer-opacity: var(--md-filled-select-text-field-hover-state-layer-opacity, 0.08);--_text-field-hover-supporting-text-color: var(--md-filled-select-text-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-hover-trailing-icon-color: var(--md-filled-select-text-field-hover-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-input-text-color: var(--md-filled-select-text-field-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_text-field-input-text-font: var(--md-filled-select-text-field-input-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-input-text-line-height: var(--md-filled-select-text-field-input-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_text-field-input-text-size: var(--md-filled-select-text-field-input-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_text-field-input-text-weight: var(--md-filled-select-text-field-input-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-label-text-color: var(--md-filled-select-text-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-label-text-font: var(--md-filled-select-text-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-label-text-line-height: var(--md-filled-select-text-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_text-field-label-text-populated-line-height: var(--md-filled-select-text-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_text-field-label-text-populated-size: var(--md-filled-select-text-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_text-field-label-text-size: var(--md-filled-select-text-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_text-field-label-text-weight: var(--md-filled-select-text-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-leading-icon-color: var(--md-filled-select-text-field-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-leading-icon-size: var(--md-filled-select-text-field-leading-icon-size, 24px);--_text-field-supporting-text-color: var(--md-filled-select-text-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-supporting-text-font: var(--md-filled-select-text-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_text-field-supporting-text-line-height: var(--md-filled-select-text-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_text-field-supporting-text-size: var(--md-filled-select-text-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_text-field-supporting-text-weight: var(--md-filled-select-text-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_text-field-trailing-icon-color: var(--md-filled-select-text-field-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_text-field-trailing-icon-size: var(--md-filled-select-text-field-trailing-icon-size, 24px);--_text-field-container-shape-start-start: var(--md-filled-select-text-field-container-shape-start-start, var(--md-filled-select-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_text-field-container-shape-start-end: var(--md-filled-select-text-field-container-shape-start-end, var(--md-filled-select-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_text-field-container-shape-end-end: var(--md-filled-select-text-field-container-shape-end-end, var(--md-filled-select-text-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--_text-field-container-shape-end-start: var(--md-filled-select-text-field-container-shape-end-start, var(--md-filled-select-text-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--md-filled-field-active-indicator-color: var(--_text-field-active-indicator-color);--md-filled-field-active-indicator-height: var(--_text-field-active-indicator-height);--md-filled-field-container-color: var(--_text-field-container-color);--md-filled-field-container-shape-end-end: var(--_text-field-container-shape-end-end);--md-filled-field-container-shape-end-start: var(--_text-field-container-shape-end-start);--md-filled-field-container-shape-start-end: var(--_text-field-container-shape-start-end);--md-filled-field-container-shape-start-start: var(--_text-field-container-shape-start-start);--md-filled-field-content-color: var(--_text-field-input-text-color);--md-filled-field-content-font: var(--_text-field-input-text-font);--md-filled-field-content-line-height: var(--_text-field-input-text-line-height);--md-filled-field-content-size: var(--_text-field-input-text-size);--md-filled-field-content-weight: var(--_text-field-input-text-weight);--md-filled-field-disabled-active-indicator-color: var(--_text-field-disabled-active-indicator-color);--md-filled-field-disabled-active-indicator-height: var(--_text-field-disabled-active-indicator-height);--md-filled-field-disabled-active-indicator-opacity: var(--_text-field-disabled-active-indicator-opacity);--md-filled-field-disabled-container-color: var(--_text-field-disabled-container-color);--md-filled-field-disabled-container-opacity: var(--_text-field-disabled-container-opacity);--md-filled-field-disabled-content-color: var(--_text-field-disabled-input-text-color);--md-filled-field-disabled-content-opacity: var(--_text-field-disabled-input-text-opacity);--md-filled-field-disabled-label-text-color: var(--_text-field-disabled-label-text-color);--md-filled-field-disabled-label-text-opacity: var(--_text-field-disabled-label-text-opacity);--md-filled-field-disabled-leading-content-color: var(--_text-field-disabled-leading-icon-color);--md-filled-field-disabled-leading-content-opacity: var(--_text-field-disabled-leading-icon-opacity);--md-filled-field-disabled-supporting-text-color: var(--_text-field-disabled-supporting-text-color);--md-filled-field-disabled-supporting-text-opacity: var(--_text-field-disabled-supporting-text-opacity);--md-filled-field-disabled-trailing-content-color: var(--_text-field-disabled-trailing-icon-color);--md-filled-field-disabled-trailing-content-opacity: var(--_text-field-disabled-trailing-icon-opacity);--md-filled-field-error-active-indicator-color: var(--_text-field-error-active-indicator-color);--md-filled-field-error-content-color: var(--_text-field-error-input-text-color);--md-filled-field-error-focus-active-indicator-color: var(--_text-field-error-focus-active-indicator-color);--md-filled-field-error-focus-content-color: var(--_text-field-error-focus-input-text-color);--md-filled-field-error-focus-label-text-color: var(--_text-field-error-focus-label-text-color);--md-filled-field-error-focus-leading-content-color: var(--_text-field-error-focus-leading-icon-color);--md-filled-field-error-focus-supporting-text-color: var(--_text-field-error-focus-supporting-text-color);--md-filled-field-error-focus-trailing-content-color: var(--_text-field-error-focus-trailing-icon-color);--md-filled-field-error-hover-active-indicator-color: var(--_text-field-error-hover-active-indicator-color);--md-filled-field-error-hover-content-color: var(--_text-field-error-hover-input-text-color);--md-filled-field-error-hover-label-text-color: var(--_text-field-error-hover-label-text-color);--md-filled-field-error-hover-leading-content-color: var(--_text-field-error-hover-leading-icon-color);--md-filled-field-error-hover-state-layer-color: var(--_text-field-error-hover-state-layer-color);--md-filled-field-error-hover-state-layer-opacity: var(--_text-field-error-hover-state-layer-opacity);--md-filled-field-error-hover-supporting-text-color: var(--_text-field-error-hover-supporting-text-color);--md-filled-field-error-hover-trailing-content-color: var(--_text-field-error-hover-trailing-icon-color);--md-filled-field-error-label-text-color: var(--_text-field-error-label-text-color);--md-filled-field-error-leading-content-color: var(--_text-field-error-leading-icon-color);--md-filled-field-error-supporting-text-color: var(--_text-field-error-supporting-text-color);--md-filled-field-error-trailing-content-color: var(--_text-field-error-trailing-icon-color);--md-filled-field-focus-active-indicator-color: var(--_text-field-focus-active-indicator-color);--md-filled-field-focus-active-indicator-height: var(--_text-field-focus-active-indicator-height);--md-filled-field-focus-content-color: var(--_text-field-focus-input-text-color);--md-filled-field-focus-label-text-color: var(--_text-field-focus-label-text-color);--md-filled-field-focus-leading-content-color: var(--_text-field-focus-leading-icon-color);--md-filled-field-focus-supporting-text-color: var(--_text-field-focus-supporting-text-color);--md-filled-field-focus-trailing-content-color: var(--_text-field-focus-trailing-icon-color);--md-filled-field-hover-active-indicator-color: var(--_text-field-hover-active-indicator-color);--md-filled-field-hover-active-indicator-height: var(--_text-field-hover-active-indicator-height);--md-filled-field-hover-content-color: var(--_text-field-hover-input-text-color);--md-filled-field-hover-label-text-color: var(--_text-field-hover-label-text-color);--md-filled-field-hover-leading-content-color: var(--_text-field-hover-leading-icon-color);--md-filled-field-hover-state-layer-color: var(--_text-field-hover-state-layer-color);--md-filled-field-hover-state-layer-opacity: var(--_text-field-hover-state-layer-opacity);--md-filled-field-hover-supporting-text-color: var(--_text-field-hover-supporting-text-color);--md-filled-field-hover-trailing-content-color: var(--_text-field-hover-trailing-icon-color);--md-filled-field-label-text-color: var(--_text-field-label-text-color);--md-filled-field-label-text-font: var(--_text-field-label-text-font);--md-filled-field-label-text-line-height: var(--_text-field-label-text-line-height);--md-filled-field-label-text-populated-line-height: var(--_text-field-label-text-populated-line-height);--md-filled-field-label-text-populated-size: var(--_text-field-label-text-populated-size);--md-filled-field-label-text-size: var(--_text-field-label-text-size);--md-filled-field-label-text-weight: var(--_text-field-label-text-weight);--md-filled-field-leading-content-color: var(--_text-field-leading-icon-color);--md-filled-field-supporting-text-color: var(--_text-field-supporting-text-color);--md-filled-field-supporting-text-font: var(--_text-field-supporting-text-font);--md-filled-field-supporting-text-line-height: var(--_text-field-supporting-text-line-height);--md-filled-field-supporting-text-size: var(--_text-field-supporting-text-size);--md-filled-field-supporting-text-weight: var(--_text-field-supporting-text-weight);--md-filled-field-trailing-content-color: var(--_text-field-trailing-icon-color)}[has-start] .icon.leading{font-size:var(--_text-field-leading-icon-size);height:var(--_text-field-leading-icon-size);width:var(--_text-field-leading-icon-size)}.icon.trailing{font-size:var(--_text-field-trailing-icon-size);height:var(--_text-field-trailing-icon-size);width:var(--_text-field-trailing-icon-size)} -`; -//# sourceMappingURL=filled-select-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/select/internal/filled-select.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@material/web/select/internal/filled-select.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ FilledSelect: () => (/* binding */ FilledSelect) -/* harmony export */ }); -/* harmony import */ var _field_filled_field_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../field/filled-field.js */ "./node_modules/@material/web/field/filled-field.js"); -/* harmony import */ var lit_static_html_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/static-html.js */ "./node_modules/lit/static-html.js"); -/* harmony import */ var _select_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./select.js */ "./node_modules/@material/web/select/internal/select.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - -// tslint:disable-next-line:enforce-comments-on-exported-symbols -class FilledSelect extends _select_js__WEBPACK_IMPORTED_MODULE_2__.Select { - constructor() { - super(...arguments); - this.fieldTag = (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_1__.literal) `md-filled-field`; - } -} -//# sourceMappingURL=filled-select.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/select/internal/select.js": -/*!**************************************************************!*\ - !*** ./node_modules/@material/web/select/internal/select.js ***! - \**************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Select: () => (/* binding */ Select) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var _menu_menu_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../menu/menu.js */ "./node_modules/@material/web/menu/menu.js"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lit/directives/class-map.js */ "./node_modules/lit/directives/class-map.js"); -/* harmony import */ var lit_directives_style_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lit/directives/style-map.js */ "./node_modules/lit/directives/style-map.js"); -/* harmony import */ var lit_static_html_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lit/static-html.js */ "./node_modules/lit/static-html.js"); -/* harmony import */ var _internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../internal/aria/delegate.js */ "./node_modules/@material/web/internal/aria/delegate.js"); -/* harmony import */ var _internal_events_redispatch_event_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../internal/events/redispatch-event.js */ "./node_modules/@material/web/internal/events/redispatch-event.js"); -/* harmony import */ var _labs_behaviors_constraint_validation_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../labs/behaviors/constraint-validation.js */ "./node_modules/@material/web/labs/behaviors/constraint-validation.js"); -/* harmony import */ var _labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../labs/behaviors/element-internals.js */ "./node_modules/@material/web/labs/behaviors/element-internals.js"); -/* harmony import */ var _labs_behaviors_form_associated_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../labs/behaviors/form-associated.js */ "./node_modules/@material/web/labs/behaviors/form-associated.js"); -/* harmony import */ var _labs_behaviors_on_report_validity_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../labs/behaviors/on-report-validity.js */ "./node_modules/@material/web/labs/behaviors/on-report-validity.js"); -/* harmony import */ var _labs_behaviors_validators_select_validator_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../labs/behaviors/validators/select-validator.js */ "./node_modules/@material/web/labs/behaviors/validators/select-validator.js"); -/* harmony import */ var _list_internal_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../list/internal/list-navigation-helpers.js */ "./node_modules/@material/web/list/internal/list-navigation-helpers.js"); -/* harmony import */ var _menu_internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../menu/internal/controllers/shared.js */ "./node_modules/@material/web/menu/internal/controllers/shared.js"); -/* harmony import */ var _menu_internal_controllers_typeaheadController_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../menu/internal/controllers/typeaheadController.js */ "./node_modules/@material/web/menu/internal/controllers/typeaheadController.js"); -/* harmony import */ var _menu_internal_menu_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../menu/internal/menu.js */ "./node_modules/@material/web/menu/internal/menu.js"); -/* harmony import */ var _shared_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./shared.js */ "./node_modules/@material/web/select/internal/shared.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -var _a; - - - - - - - - - - - - - - - - - - - -const VALUE = Symbol('value'); -// Separate variable needed for closure. -const selectBaseClass = (0,_internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_6__.mixinDelegatesAria)((0,_labs_behaviors_on_report_validity_js__WEBPACK_IMPORTED_MODULE_11__.mixinOnReportValidity)((0,_labs_behaviors_constraint_validation_js__WEBPACK_IMPORTED_MODULE_8__.mixinConstraintValidation)((0,_labs_behaviors_form_associated_js__WEBPACK_IMPORTED_MODULE_10__.mixinFormAssociated)((0,_labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_9__.mixinElementInternals)(lit__WEBPACK_IMPORTED_MODULE_1__.LitElement))))); -/** - * @fires change {Event} The native `change` event on - * [``](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event) - * --bubbles - * @fires input {InputEvent} The native `input` event on - * [``](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event) - * --bubbles --composed - * @fires opening {Event} Fired when the select's menu is about to open. - * @fires opened {Event} Fired when the select's menu has finished animations - * and opened. - * @fires closing {Event} Fired when the select's menu is about to close. - * @fires closed {Event} Fired when the select's menu has finished animations - * and closed. - */ -class Select extends selectBaseClass { - /** - * The value of the currently selected option. - * - * Note: For SSR, set `[selected]` on the requested option and `displayText` - * rather than setting `value` setting `value` will incur a DOM query. - */ - get value() { - return this[VALUE]; - } - set value(value) { - if (lit__WEBPACK_IMPORTED_MODULE_1__.isServer) - return; - this.lastUserSetValue = value; - this.select(value); - } - get options() { - // NOTE: this does a DOM query. - return (this.menu?.items ?? []); - } - /** - * The index of the currently selected option. - * - * Note: For SSR, set `[selected]` on the requested option and `displayText` - * rather than setting `selectedIndex` setting `selectedIndex` will incur a - * DOM query. - */ - get selectedIndex() { - // tslint:disable-next-line:enforce-name-casing - const [_option, index] = (this.getSelectedOptions() ?? [])[0] ?? []; - return index ?? -1; - } - set selectedIndex(index) { - this.lastUserSetSelectedIndex = index; - this.selectIndex(index); - } - /** - * Returns an array of selected options. - * - * NOTE: md-select only supports single selection. - */ - get selectedOptions() { - return (this.getSelectedOptions() ?? []).map(([option]) => option); - } - get hasError() { - return this.error || this.nativeError; - } - constructor() { - super(); - /** - * Opens the menu synchronously with no animation. - */ - this.quick = false; - /** - * Whether or not the select is required. - */ - this.required = false; - /** - * The error message that replaces supporting text when `error` is true. If - * `errorText` is an empty string, then the supporting text will continue to - * show. - * - * This error message overrides the error message displayed by - * `reportValidity()`. - */ - this.errorText = ''; - /** - * The floating label for the field. - */ - this.label = ''; - /** - * Disables the asterisk on the floating label, when the select is - * required. - */ - this.noAsterisk = false; - /** - * Conveys additional information below the select, such as how it should - * be used. - */ - this.supportingText = ''; - /** - * Gets or sets whether or not the select is in a visually invalid state. - * - * This error state overrides the error state controlled by - * `reportValidity()`. - */ - this.error = false; - /** - * Whether or not the underlying md-menu should be position: fixed to display - * in a top-level manner, or position: absolute. - * - * position:fixed is useful for cases where select is inside of another - * element with stacking context and hidden overflows such as `md-dialog`. - */ - this.menuPositioning = 'popover'; - /** - * Clamps the menu-width to the width of the select. - */ - this.clampMenuWidth = false; - /** - * The max time between the keystrokes of the typeahead select / menu behavior - * before it clears the typeahead buffer. - */ - this.typeaheadDelay = _menu_internal_menu_js__WEBPACK_IMPORTED_MODULE_16__.DEFAULT_TYPEAHEAD_BUFFER_TIME; - /** - * Whether or not the text field has a leading icon. Used for SSR. - */ - this.hasLeadingIcon = false; - /** - * Text to display in the field. Only set for SSR. - */ - this.displayText = ''; - /** - * Whether the menu should be aligned to the start or the end of the select's - * textbox. - */ - this.menuAlign = 'start'; - this[_a] = ''; - /** - * Used for initializing select when the user sets the `value` directly. - */ - this.lastUserSetValue = null; - /** - * Used for initializing select when the user sets the `selectedIndex` - * directly. - */ - this.lastUserSetSelectedIndex = null; - /** - * Used for `input` and `change` event change detection. - */ - this.lastSelectedOption = null; - // tslint:disable-next-line:enforce-name-casing - this.lastSelectedOptionRecords = []; - /** - * Whether or not a native error has been reported via `reportValidity()`. - */ - this.nativeError = false; - /** - * The validation message displayed from a native error via - * `reportValidity()`. - */ - this.nativeErrorText = ''; - this.focused = false; - this.open = false; - this.defaultFocus = _menu_internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_14__.FocusState.NONE; - // Have to keep track of previous open because it's state and private and thus - // cannot be tracked in PropertyValues map. - this.prevOpen = this.open; - this.selectWidth = 0; - if (lit__WEBPACK_IMPORTED_MODULE_1__.isServer) { - return; - } - this.addEventListener('focus', this.handleFocus.bind(this)); - this.addEventListener('blur', this.handleBlur.bind(this)); - } - /** - * Selects an option given the value of the option, and updates MdSelect's - * value. - */ - select(value) { - const optionToSelect = this.options.find((option) => option.value === value); - if (optionToSelect) { - this.selectItem(optionToSelect); - } - } - /** - * Selects an option given the index of the option, and updates MdSelect's - * value. - */ - selectIndex(index) { - const optionToSelect = this.options[index]; - if (optionToSelect) { - this.selectItem(optionToSelect); - } - } - /** - * Reset the select to its default value. - */ - reset() { - for (const option of this.options) { - option.selected = option.hasAttribute('selected'); - } - this.updateValueAndDisplayText(); - this.nativeError = false; - this.nativeErrorText = ''; - } - [(_a = VALUE, _labs_behaviors_on_report_validity_js__WEBPACK_IMPORTED_MODULE_11__.onReportValidity)](invalidEvent) { - // Prevent default pop-up behavior. - invalidEvent?.preventDefault(); - const prevMessage = this.getErrorText(); - this.nativeError = !!invalidEvent; - this.nativeErrorText = this.validationMessage; - if (prevMessage === this.getErrorText()) { - this.field?.reannounceError(); - } - } - update(changed) { - // In SSR the options will be ready to query, so try to figure out what - // the value and display text should be. - if (!this.hasUpdated) { - this.initUserSelection(); - } - // We have just opened the menu. - // We are only able to check for the select's rect in `update()` instead of - // having to wait for `updated()` because the menu can never be open on - // first render since it is not settable and Lit SSR does not support click - // events which would open the menu. - if (this.prevOpen !== this.open && this.open) { - const selectRect = this.getBoundingClientRect(); - this.selectWidth = selectRect.width; - } - this.prevOpen = this.open; - super.update(changed); - } - render() { - return (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) ` - - ${this.renderField()} ${this.renderMenu()} - - `; - } - async firstUpdated(changed) { - await this.menu?.updateComplete; - // If this has been handled on update already due to SSR, try again. - if (!this.lastSelectedOptionRecords.length) { - this.initUserSelection(); - } - // Case for when the DOM is streaming, there are no children, and a child - // has [selected] set on it, we need to wait for DOM to render something. - if (!this.lastSelectedOptionRecords.length && - !lit__WEBPACK_IMPORTED_MODULE_1__.isServer && - !this.options.length) { - setTimeout(() => { - this.updateValueAndDisplayText(); - }); - } - super.firstUpdated(changed); - } - getRenderClasses() { - return { - 'disabled': this.disabled, - 'error': this.error, - 'open': this.open, - }; - } - renderField() { - const ariaLabel = this.ariaLabel || this.label; - return (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_5__.html) ` - <${this.fieldTag} - aria-haspopup="listbox" - role="combobox" - part="field" - id="field" - tabindex=${this.disabled ? '-1' : '0'} - aria-label=${ariaLabel || lit__WEBPACK_IMPORTED_MODULE_1__.nothing} - aria-describedby="description" - aria-expanded=${this.open ? 'true' : 'false'} - aria-controls="listbox" - class="field" - label=${this.label} - ?no-asterisk=${this.noAsterisk} - .focused=${this.focused || this.open} - .populated=${!!this.displayText} - .disabled=${this.disabled} - .required=${this.required} - .error=${this.hasError} - ?has-start=${this.hasLeadingIcon} - has-end - supporting-text=${this.supportingText} - error-text=${this.getErrorText()} - @keydown=${this.handleKeydown} - @click=${this.handleClick}> - ${this.renderFieldContent()} -
    - `; - } - renderFieldContent() { - return [ - this.renderLeadingIcon(), - this.renderLabel(), - this.renderTrailingIcon(), - ]; - } - renderLeadingIcon() { - return (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) ` - - - - `; - } - renderTrailingIcon() { - return (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) ` - - - - - - - - - `; - } - renderLabel() { - // need to render   so that line-height can apply and give it a - // non-zero height - return (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) `
    ${this.displayText || (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) ` `}
    `; - } - renderMenu() { - const ariaLabel = this.label || this.ariaLabel; - return (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) ``; - } - renderMenuContent() { - return (0,lit__WEBPACK_IMPORTED_MODULE_1__.html) ``; - } - /** - * Handles opening the select on keydown and typahead selection when the menu - * is closed. - */ - handleKeydown(event) { - if (this.open || this.disabled || !this.menu) { - return; - } - const typeaheadController = this.menu.typeaheadController; - const isOpenKey = event.code === 'Space' || - event.code === 'ArrowDown' || - event.code === 'ArrowUp' || - event.code === 'End' || - event.code === 'Home' || - event.code === 'Enter'; - // Do not open if currently typing ahead because the user may be typing the - // spacebar to match a word with a space - if (!typeaheadController.isTypingAhead && isOpenKey) { - event.preventDefault(); - this.open = true; - // https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/#kbd_label - switch (event.code) { - case 'Space': - case 'ArrowDown': - case 'Enter': - // We will handle focusing last selected item in this.handleOpening() - this.defaultFocus = _menu_internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_14__.FocusState.NONE; - break; - case 'End': - this.defaultFocus = _menu_internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_14__.FocusState.LAST_ITEM; - break; - case 'ArrowUp': - case 'Home': - this.defaultFocus = _menu_internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_14__.FocusState.FIRST_ITEM; - break; - default: - break; - } - return; - } - const isPrintableKey = event.key.length === 1; - // Handles typing ahead when the menu is closed by delegating the event to - // the underlying menu's typeaheadController - if (isPrintableKey) { - typeaheadController.onKeydown(event); - event.preventDefault(); - const { lastActiveRecord } = typeaheadController; - if (!lastActiveRecord) { - return; - } - this.labelEl?.setAttribute?.('aria-live', 'polite'); - const hasChanged = this.selectItem(lastActiveRecord[_menu_internal_controllers_typeaheadController_js__WEBPACK_IMPORTED_MODULE_15__.TYPEAHEAD_RECORD.ITEM]); - if (hasChanged) { - this.dispatchInteractionEvents(); - } - } - } - handleClick() { - this.open = !this.open; - } - handleFocus() { - this.focused = true; - } - handleBlur() { - this.focused = false; - } - /** - * Handles closing the menu when the focus leaves the select's subtree. - */ - handleFocusout(event) { - // Don't close the menu if we are switching focus between menu, - // select-option, and field - if (event.relatedTarget && (0,_menu_internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_14__.isElementInSubtree)(event.relatedTarget, this)) { - return; - } - this.open = false; - } - /** - * Gets a list of all selected select options as a list item record array. - * - * @return An array of selected list option records. - */ - getSelectedOptions() { - if (!this.menu) { - this.lastSelectedOptionRecords = []; - return null; - } - const items = this.menu.items; - this.lastSelectedOptionRecords = (0,_shared_js__WEBPACK_IMPORTED_MODULE_17__.getSelectedItems)(items); - return this.lastSelectedOptionRecords; - } - async getUpdateComplete() { - await this.menu?.updateComplete; - return super.getUpdateComplete(); - } - /** - * Gets the selected options from the DOM, and updates the value and display - * text to the first selected option's value and headline respectively. - * - * @return Whether or not the selected option has changed since last update. - */ - updateValueAndDisplayText() { - const selectedOptions = this.getSelectedOptions() ?? []; - // Used to determine whether or not we need to fire an input / change event - // which fire whenever the option element changes (value or selectedIndex) - // on user interaction. - let hasSelectedOptionChanged = false; - if (selectedOptions.length) { - const [firstSelectedOption] = selectedOptions[0]; - hasSelectedOptionChanged = - this.lastSelectedOption !== firstSelectedOption; - this.lastSelectedOption = firstSelectedOption; - this[VALUE] = firstSelectedOption.value; - this.displayText = firstSelectedOption.displayText; - } - else { - hasSelectedOptionChanged = this.lastSelectedOption !== null; - this.lastSelectedOption = null; - this[VALUE] = ''; - this.displayText = ''; - } - return hasSelectedOptionChanged; - } - /** - * Focuses and activates the last selected item upon opening, and resets other - * active items. - */ - async handleOpening(e) { - this.labelEl?.removeAttribute?.('aria-live'); - this.redispatchEvent(e); - // FocusState.NONE means we want to handle focus ourselves and focus the - // last selected item. - if (this.defaultFocus !== _menu_internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_14__.FocusState.NONE) { - return; - } - const items = this.menu.items; - const activeItem = (0,_list_internal_list_navigation_helpers_js__WEBPACK_IMPORTED_MODULE_13__.getActiveItem)(items)?.item; - let [selectedItem] = this.lastSelectedOptionRecords[0] ?? [null]; - // This is true if the user keys through the list but clicks out of the menu - // thus no close-menu event is fired by an item and we can't clean up in - // handleCloseMenu. - if (activeItem && activeItem !== selectedItem) { - activeItem.tabIndex = -1; - } - // in the case that nothing is selected, focus the first item - selectedItem = selectedItem ?? items[0]; - if (selectedItem) { - selectedItem.tabIndex = 0; - selectedItem.focus(); - } - } - redispatchEvent(e) { - (0,_internal_events_redispatch_event_js__WEBPACK_IMPORTED_MODULE_7__.redispatchEvent)(this, e); - } - handleClosed(e) { - this.open = false; - this.redispatchEvent(e); - } - /** - * Determines the reason for closing, and updates the UI accordingly. - */ - handleCloseMenu(event) { - const reason = event.detail.reason; - const item = event.detail.itemPath[0]; - this.open = false; - let hasChanged = false; - if (reason.kind === 'click-selection') { - hasChanged = this.selectItem(item); - } - else if (reason.kind === 'keydown' && (0,_menu_internal_controllers_shared_js__WEBPACK_IMPORTED_MODULE_14__.isSelectableKey)(reason.key)) { - hasChanged = this.selectItem(item); - } - else { - // This can happen on ESC being pressed - item.tabIndex = -1; - item.blur(); - } - // Dispatch interaction events since selection has been made via keyboard - // or mouse. - if (hasChanged) { - this.dispatchInteractionEvents(); - } - } - /** - * Selects a given option, deselects other options, and updates the UI. - * - * @return Whether the last selected option has changed. - */ - selectItem(item) { - const selectedOptions = this.getSelectedOptions() ?? []; - selectedOptions.forEach(([option]) => { - if (item !== option) { - option.selected = false; - } - }); - item.selected = true; - return this.updateValueAndDisplayText(); - } - /** - * Handles updating selection when an option element requests selection via - * property / attribute change. - */ - handleRequestSelection(event) { - const requestingOptionEl = event.target; - // No-op if this item is already selected. - if (this.lastSelectedOptionRecords.some(([option]) => option === requestingOptionEl)) { - return; - } - this.selectItem(requestingOptionEl); - } - /** - * Handles updating selection when an option element requests deselection via - * property / attribute change. - */ - handleRequestDeselection(event) { - const requestingOptionEl = event.target; - // No-op if this item is not even in the list of tracked selected items. - if (!this.lastSelectedOptionRecords.some(([option]) => option === requestingOptionEl)) { - return; - } - this.updateValueAndDisplayText(); - } - /** - * Attempts to initialize the selected option from user-settable values like - * SSR, setting `value`, or `selectedIndex` at startup. - */ - initUserSelection() { - // User has set `.value` directly, but internals have not yet booted up. - if (this.lastUserSetValue && !this.lastSelectedOptionRecords.length) { - this.select(this.lastUserSetValue); - // User has set `.selectedIndex` directly, but internals have not yet - // booted up. - } - else if (this.lastUserSetSelectedIndex !== null && - !this.lastSelectedOptionRecords.length) { - this.selectIndex(this.lastUserSetSelectedIndex); - // Regular boot up! - } - else { - this.updateValueAndDisplayText(); - } - } - handleIconChange() { - this.hasLeadingIcon = this.leadingIcons.length > 0; - } - /** - * Dispatches the `input` and `change` events. - */ - dispatchInteractionEvents() { - this.dispatchEvent(new Event('input', { bubbles: true, composed: true })); - this.dispatchEvent(new Event('change', { bubbles: true })); - } - getErrorText() { - return this.error ? this.errorText : this.nativeErrorText; - } - [_labs_behaviors_form_associated_js__WEBPACK_IMPORTED_MODULE_10__.getFormValue]() { - return this.value; - } - formResetCallback() { - this.reset(); - } - formStateRestoreCallback(state) { - this.value = state; - } - click() { - this.field?.click(); - } - [_labs_behaviors_constraint_validation_js__WEBPACK_IMPORTED_MODULE_8__.createValidator]() { - return new _labs_behaviors_validators_select_validator_js__WEBPACK_IMPORTED_MODULE_12__.SelectValidator(() => this); - } - [_labs_behaviors_constraint_validation_js__WEBPACK_IMPORTED_MODULE_8__.getValidityAnchor]() { - return this.field; - } -} -/** @nocollapse */ -Select.shadowRootOptions = { - ...lit__WEBPACK_IMPORTED_MODULE_1__.LitElement.shadowRootOptions, - delegatesFocus: true, -}; -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean }) -], Select.prototype, "quick", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean }) -], Select.prototype, "required", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: String, attribute: 'error-text' }) -], Select.prototype, "errorText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)() -], Select.prototype, "label", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean, attribute: 'no-asterisk' }) -], Select.prototype, "noAsterisk", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: String, attribute: 'supporting-text' }) -], Select.prototype, "supportingText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean, reflect: true }) -], Select.prototype, "error", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ attribute: 'menu-positioning' }) -], Select.prototype, "menuPositioning", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean, attribute: 'clamp-menu-width' }) -], Select.prototype, "clampMenuWidth", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Number, attribute: 'typeahead-delay' }) -], Select.prototype, "typeaheadDelay", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Boolean, attribute: 'has-leading-icon' }) -], Select.prototype, "hasLeadingIcon", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ attribute: 'display-text' }) -], Select.prototype, "displayText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ attribute: 'menu-align' }) -], Select.prototype, "menuAlign", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)() -], Select.prototype, "value", null); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.property)({ type: Number, attribute: 'selected-index' }) -], Select.prototype, "selectedIndex", null); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Select.prototype, "nativeError", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Select.prototype, "nativeErrorText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Select.prototype, "focused", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Select.prototype, "open", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.state)() -], Select.prototype, "defaultFocus", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('.field') -], Select.prototype, "field", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('md-menu') -], Select.prototype, "menu", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.query)('#label') -], Select.prototype, "labelEl", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_18__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_2__.queryAssignedElements)({ slot: 'leading-icon', flatten: true }) -], Select.prototype, "leadingIcons", void 0); -//# sourceMappingURL=select.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/select/internal/selectoption/select-option.js": -/*!**********************************************************************************!*\ - !*** ./node_modules/@material/web/select/internal/selectoption/select-option.js ***! - \**********************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ SelectOptionEl: () => (/* binding */ SelectOptionEl) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var _focus_md_focus_ring_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../focus/md-focus-ring.js */ "./node_modules/@material/web/focus/md-focus-ring.js"); -/* harmony import */ var _labs_item_item_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../labs/item/item.js */ "./node_modules/@material/web/labs/item/item.js"); -/* harmony import */ var _ripple_ripple_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../ripple/ripple.js */ "./node_modules/@material/web/ripple/ripple.js"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lit/directives/class-map.js */ "./node_modules/lit/directives/class-map.js"); -/* harmony import */ var _internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../internal/aria/delegate.js */ "./node_modules/@material/web/internal/aria/delegate.js"); -/* harmony import */ var _selectOptionController_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./selectOptionController.js */ "./node_modules/@material/web/select/internal/selectoption/selectOptionController.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - - - - - -// Separate variable needed for closure. -const selectOptionBaseClass = (0,_internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_6__.mixinDelegatesAria)(lit__WEBPACK_IMPORTED_MODULE_3__.LitElement); -/** - * @fires close-menu {CustomEvent<{initiator: SelectOption, reason: Reason, itemPath: SelectOption[]}>} - * Closes the encapsulating menu on closable interaction. --bubbles --composed - * @fires request-selection {Event} Requests the parent md-select to select this - * element (and deselect others if single-selection) when `selected` changed to - * `true`. --bubbles --composed - * @fires request-deselection {Event} Requests the parent md-select to deselect - * this element when `selected` changed to `false`. --bubbles --composed - */ -class SelectOptionEl extends selectOptionBaseClass { - constructor() { - super(...arguments); - /** - * Disables the item and makes it non-selectable and non-interactive. - */ - this.disabled = false; - /** - * READONLY: self-identifies as a menu item and sets its identifying attribute - */ - this.isMenuItem = true; - /** - * Sets the item in the selected visual state when a submenu is opened. - */ - this.selected = false; - /** - * Form value of the option. - */ - this.value = ''; - this.type = 'option'; - this.selectOptionController = new _selectOptionController_js__WEBPACK_IMPORTED_MODULE_7__.SelectOptionController(this, { - getHeadlineElements: () => { - return this.headlineElements; - }, - getSupportingTextElements: () => { - return this.supportingTextElements; - }, - getDefaultElements: () => { - return this.defaultElements; - }, - getInteractiveElement: () => this.listItemRoot, - }); - } - /** - * The text that is selectable via typeahead. If not set, defaults to the - * innerText of the item slotted into the `"headline"` slot. - */ - get typeaheadText() { - return this.selectOptionController.typeaheadText; - } - set typeaheadText(text) { - this.selectOptionController.setTypeaheadText(text); - } - /** - * The text that is displayed in the select field when selected. If not set, - * defaults to the textContent of the item slotted into the `"headline"` slot. - */ - get displayText() { - return this.selectOptionController.displayText; - } - set displayText(text) { - this.selectOptionController.setDisplayText(text); - } - render() { - return this.renderListItem((0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` - -
    - ${this.renderRipple()} ${this.renderFocusRing()} -
    - - - ${this.renderBody()} -
    - `); - } - /** - * Renders the root list item. - * - * @param content the child content of the list item. - */ - renderListItem(content) { - return (0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` -
  • ${content}
  • - `; - } - /** - * Handles rendering of the ripple element. - */ - renderRipple() { - return (0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` `; - } - /** - * Handles rendering of the focus ring. - */ - renderFocusRing() { - return (0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` `; - } - /** - * Classes applied to the list item root. - */ - getRenderClasses() { - return { - 'disabled': this.disabled, - 'selected': this.selected, - }; - } - /** - * Handles rendering the headline and supporting text. - */ - renderBody() { - return (0,lit__WEBPACK_IMPORTED_MODULE_3__.html) ` - - - - - - `; - } - focus() { - // TODO(b/300334509): needed for some cases where delegatesFocus doesn't - // work programmatically like in FF and select-option - this.listItemRoot?.focus(); - } -} -/** @nocollapse */ -SelectOptionEl.shadowRootOptions = { - ...lit__WEBPACK_IMPORTED_MODULE_3__.LitElement.shadowRootOptions, - delegatesFocus: true, -}; -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)({ type: Boolean, reflect: true }) -], SelectOptionEl.prototype, "disabled", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)({ type: Boolean, attribute: 'md-menu-item', reflect: true }) -], SelectOptionEl.prototype, "isMenuItem", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)({ type: Boolean }) -], SelectOptionEl.prototype, "selected", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)() -], SelectOptionEl.prototype, "value", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.query)('.list-item') -], SelectOptionEl.prototype, "listItemRoot", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.queryAssignedElements)({ slot: 'headline' }) -], SelectOptionEl.prototype, "headlineElements", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.queryAssignedElements)({ slot: 'supporting-text' }) -], SelectOptionEl.prototype, "supportingTextElements", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.queryAssignedNodes)({ slot: '' }) -], SelectOptionEl.prototype, "defaultElements", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)({ attribute: 'typeahead-text' }) -], SelectOptionEl.prototype, "typeaheadText", null); -(0,tslib__WEBPACK_IMPORTED_MODULE_8__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_4__.property)({ attribute: 'display-text' }) -], SelectOptionEl.prototype, "displayText", null); -//# sourceMappingURL=select-option.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/select/internal/selectoption/selectOptionController.js": -/*!*******************************************************************************************!*\ - !*** ./node_modules/@material/web/select/internal/selectoption/selectOptionController.js ***! - \*******************************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ SelectOptionController: () => (/* binding */ SelectOptionController), -/* harmony export */ createRequestDeselectionEvent: () => (/* binding */ createRequestDeselectionEvent), -/* harmony export */ createRequestSelectionEvent: () => (/* binding */ createRequestSelectionEvent) -/* harmony export */ }); -/* harmony import */ var _menu_internal_controllers_menuItemController_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../menu/internal/controllers/menuItemController.js */ "./node_modules/@material/web/menu/internal/controllers/menuItemController.js"); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * Creates an event fired by a SelectOption to request selection from md-select. - * Typically fired after `selected` changes from `false` to `true`. - */ -function createRequestSelectionEvent() { - return new Event('request-selection', { - bubbles: true, - composed: true, - }); -} -/** - * Creates an event fired by a SelectOption to request deselection from - * md-select. Typically fired after `selected` changes from `true` to `false`. - */ -function createRequestDeselectionEvent() { - return new Event('request-deselection', { - bubbles: true, - composed: true, - }); -} -/** - * A controller that provides most functionality and md-select compatibility for - * an element that implements the SelectOption interface. - */ -class SelectOptionController { - /** - * The recommended role of the select option. - */ - get role() { - return this.menuItemController.role; - } - /** - * The text that is selectable via typeahead. If not set, defaults to the - * innerText of the item slotted into the `"headline"` slot, and if there are - * no slotted elements into headline, then it checks the _default_ slot, and - * then the `"supporting-text"` slot if nothing is in _default_. - */ - get typeaheadText() { - return this.menuItemController.typeaheadText; - } - setTypeaheadText(text) { - this.menuItemController.setTypeaheadText(text); - } - /** - * The text that is displayed in the select field when selected. If not set, - * defaults to the textContent of the item slotted into the `"headline"` slot, - * and if there are no slotted elements into headline, then it checks the - * _default_ slot, and then the `"supporting-text"` slot if nothing is in - * _default_. - */ - get displayText() { - if (this.internalDisplayText !== null) { - return this.internalDisplayText; - } - return this.menuItemController.typeaheadText; - } - setDisplayText(text) { - this.internalDisplayText = text; - } - /** - * @param host The SelectOption in which to attach this controller to. - * @param config The object that configures this controller's behavior. - */ - constructor(host, config) { - this.host = host; - this.internalDisplayText = null; - this.firstUpdate = true; - /** - * Bind this click listener to the interactive element. Handles closing the - * menu. - */ - this.onClick = () => { - this.menuItemController.onClick(); - }; - /** - * Bind this click listener to the interactive element. Handles closing the - * menu. - */ - this.onKeydown = (e) => { - this.menuItemController.onKeydown(e); - }; - this.lastSelected = this.host.selected; - this.menuItemController = new _menu_internal_controllers_menuItemController_js__WEBPACK_IMPORTED_MODULE_0__.MenuItemController(host, config); - host.addController(this); - } - hostUpdate() { - if (this.lastSelected !== this.host.selected) { - this.host.ariaSelected = this.host.selected ? 'true' : 'false'; - } - } - hostUpdated() { - // Do not dispatch event on first update / boot-up. - if (this.lastSelected !== this.host.selected && !this.firstUpdate) { - // This section is really useful for when the user sets selected on the - // option programmatically. Most other cases (click and keyboard) are - // handled by md-select because it needs to coordinate the - // single-selection behavior. - if (this.host.selected) { - this.host.dispatchEvent(createRequestSelectionEvent()); - } - else { - this.host.dispatchEvent(createRequestDeselectionEvent()); - } - } - this.lastSelected = this.host.selected; - this.firstUpdate = false; - } -} -//# sourceMappingURL=selectOptionController.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/select/internal/shared-styles.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@material/web/select/internal/shared-styles.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./select/internal/shared-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{color:unset;min-width:210px;display:flex}.field{cursor:default;outline:none}.select{position:relative;flex-direction:column}.icon.trailing svg,.icon ::slotted(*){fill:currentColor}.icon ::slotted(*){width:inherit;height:inherit;font-size:inherit}.icon slot{display:flex;height:100%;width:100%;align-items:center;justify-content:center}.icon.trailing :is(.up,.down){opacity:0;transition:opacity 75ms linear 75ms}.select:not(.open) .down,.select.open .up{opacity:1}.field,.select,md-menu{min-width:inherit;width:inherit;max-width:inherit;display:flex}md-menu{min-width:var(--__menu-min-width);max-width:var(--__menu-max-width, inherit)}.menu-wrapper{width:0px;height:0px;max-width:inherit}md-menu ::slotted(:not[disabled]){cursor:pointer}.field,.select{width:100%}:host{display:inline-flex}:host([disabled]){pointer-events:none} -`; -//# sourceMappingURL=shared-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/select/internal/shared.js": -/*!**************************************************************!*\ - !*** ./node_modules/@material/web/select/internal/shared.js ***! - \**************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ getSelectedItems: () => (/* binding */ getSelectedItems) -/* harmony export */ }); -/** - * @license - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -/** - * Given a list of select options, this function will return an array of - * SelectOptionRecords that are selected. - * - * @return An array of SelectOptionRecords describing the options that are - * selected. - */ -function getSelectedItems(items) { - const selectedItemRecords = []; - for (let i = 0; i < items.length; i++) { - const item = items[i]; - if (item.selected) { - selectedItemRecords.push([item, i]); - } - } - return selectedItemRecords; -} -//# sourceMappingURL=shared.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/textfield/internal/filled-styles.js": -/*!************************************************************************!*\ - !*** ./node_modules/@material/web/textfield/internal/filled-styles.js ***! - \************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./textfield/internal/filled-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{--_active-indicator-color: var(--md-filled-text-field-active-indicator-color, var(--md-sys-color-on-surface-variant, #49454f));--_active-indicator-height: var(--md-filled-text-field-active-indicator-height, 1px);--_caret-color: var(--md-filled-text-field-caret-color, var(--md-sys-color-primary, #6750a4));--_container-color: var(--md-filled-text-field-container-color, var(--md-sys-color-surface-container-highest, #e6e0e9));--_disabled-active-indicator-color: var(--md-filled-text-field-disabled-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-active-indicator-height: var(--md-filled-text-field-disabled-active-indicator-height, 1px);--_disabled-active-indicator-opacity: var(--md-filled-text-field-disabled-active-indicator-opacity, 0.38);--_disabled-container-color: var(--md-filled-text-field-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-opacity: var(--md-filled-text-field-disabled-container-opacity, 0.04);--_disabled-input-text-color: var(--md-filled-text-field-disabled-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-input-text-opacity: var(--md-filled-text-field-disabled-input-text-opacity, 0.38);--_disabled-label-text-color: var(--md-filled-text-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-text-field-disabled-label-text-opacity, 0.38);--_disabled-leading-icon-color: var(--md-filled-text-field-disabled-leading-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-icon-opacity: var(--md-filled-text-field-disabled-leading-icon-opacity, 0.38);--_disabled-supporting-text-color: var(--md-filled-text-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-supporting-text-opacity: var(--md-filled-text-field-disabled-supporting-text-opacity, 0.38);--_disabled-trailing-icon-color: var(--md-filled-text-field-disabled-trailing-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-trailing-icon-opacity: var(--md-filled-text-field-disabled-trailing-icon-opacity, 0.38);--_error-active-indicator-color: var(--md-filled-text-field-error-active-indicator-color, var(--md-sys-color-error, #b3261e));--_error-focus-active-indicator-color: var(--md-filled-text-field-error-focus-active-indicator-color, var(--md-sys-color-error, #b3261e));--_error-focus-caret-color: var(--md-filled-text-field-error-focus-caret-color, var(--md-sys-color-error, #b3261e));--_error-focus-input-text-color: var(--md-filled-text-field-error-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-focus-label-text-color: var(--md-filled-text-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-leading-icon-color: var(--md-filled-text-field-error-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-focus-supporting-text-color: var(--md-filled-text-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-trailing-icon-color: var(--md-filled-text-field-error-focus-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_error-hover-active-indicator-color: var(--md-filled-text-field-error-hover-active-indicator-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-input-text-color: var(--md-filled-text-field-error-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-label-text-color: var(--md-filled-text-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-leading-icon-color: var(--md-filled-text-field-error-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-hover-state-layer-color: var(--md-filled-text-field-error-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-state-layer-opacity: var(--md-filled-text-field-error-hover-state-layer-opacity, 0.08);--_error-hover-supporting-text-color: var(--md-filled-text-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-hover-trailing-icon-color: var(--md-filled-text-field-error-hover-trailing-icon-color, var(--md-sys-color-on-error-container, #410e0b));--_error-input-text-color: var(--md-filled-text-field-error-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_error-label-text-color: var(--md-filled-text-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_error-leading-icon-color: var(--md-filled-text-field-error-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-supporting-text-color: var(--md-filled-text-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-trailing-icon-color: var(--md-filled-text-field-error-trailing-icon-color, var(--md-sys-color-error, #b3261e));--_focus-active-indicator-color: var(--md-filled-text-field-focus-active-indicator-color, var(--md-sys-color-primary, #6750a4));--_focus-active-indicator-height: var(--md-filled-text-field-focus-active-indicator-height, 3px);--_focus-input-text-color: var(--md-filled-text-field-focus-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_focus-label-text-color: var(--md-filled-text-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_focus-leading-icon-color: var(--md-filled-text-field-focus-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-supporting-text-color: var(--md-filled-text-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-trailing-icon-color: var(--md-filled-text-field-focus-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-active-indicator-color: var(--md-filled-text-field-hover-active-indicator-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-active-indicator-height: var(--md-filled-text-field-hover-active-indicator-height, 1px);--_hover-input-text-color: var(--md-filled-text-field-hover-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-filled-text-field-hover-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-leading-icon-color: var(--md-filled-text-field-hover-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-state-layer-color: var(--md-filled-text-field-hover-state-layer-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-state-layer-opacity: var(--md-filled-text-field-hover-state-layer-opacity, 0.08);--_hover-supporting-text-color: var(--md-filled-text-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-trailing-icon-color: var(--md-filled-text-field-hover-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-color: var(--md-filled-text-field-input-text-color, var(--md-sys-color-on-surface, #1d1b20));--_input-text-font: var(--md-filled-text-field-input-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_input-text-line-height: var(--md-filled-text-field-input-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_input-text-placeholder-color: var(--md-filled-text-field-input-text-placeholder-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-prefix-color: var(--md-filled-text-field-input-text-prefix-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-size: var(--md-filled-text-field-input-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_input-text-suffix-color: var(--md-filled-text-field-input-text-suffix-color, var(--md-sys-color-on-surface-variant, #49454f));--_input-text-weight: var(--md-filled-text-field-input-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_label-text-color: var(--md-filled-text-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-font: var(--md-filled-text-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-text-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_label-text-populated-line-height: var(--md-filled-text-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_label-text-populated-size: var(--md-filled-text-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_label-text-size: var(--md-filled-text-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_label-text-weight: var(--md-filled-text-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_leading-icon-color: var(--md-filled-text-field-leading-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_leading-icon-size: var(--md-filled-text-field-leading-icon-size, 24px);--_supporting-text-color: var(--md-filled-text-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_supporting-text-font: var(--md-filled-text-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_supporting-text-line-height: var(--md-filled-text-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_supporting-text-size: var(--md-filled-text-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_supporting-text-weight: var(--md-filled-text-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_trailing-icon-color: var(--md-filled-text-field-trailing-icon-color, var(--md-sys-color-on-surface-variant, #49454f));--_trailing-icon-size: var(--md-filled-text-field-trailing-icon-size, 24px);--_container-shape-start-start: var(--md-filled-text-field-container-shape-start-start, var(--md-filled-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-start-end: var(--md-filled-text-field-container-shape-start-end, var(--md-filled-text-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-end: var(--md-filled-text-field-container-shape-end-end, var(--md-filled-text-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--_container-shape-end-start: var(--md-filled-text-field-container-shape-end-start, var(--md-filled-text-field-container-shape, var(--md-sys-shape-corner-none, 0px)));--_icon-input-space: var(--md-filled-text-field-icon-input-space, 16px);--_leading-space: var(--md-filled-text-field-leading-space, 16px);--_trailing-space: var(--md-filled-text-field-trailing-space, 16px);--_top-space: var(--md-filled-text-field-top-space, 16px);--_bottom-space: var(--md-filled-text-field-bottom-space, 16px);--_input-text-prefix-trailing-space: var(--md-filled-text-field-input-text-prefix-trailing-space, 2px);--_input-text-suffix-leading-space: var(--md-filled-text-field-input-text-suffix-leading-space, 2px);--_with-label-top-space: var(--md-filled-text-field-with-label-top-space, 8px);--_with-label-bottom-space: var(--md-filled-text-field-with-label-bottom-space, 8px);--_focus-caret-color: var(--md-filled-text-field-focus-caret-color, var(--md-sys-color-primary, #6750a4));--_with-leading-icon-leading-space: var(--md-filled-text-field-with-leading-icon-leading-space, 12px);--_with-trailing-icon-trailing-space: var(--md-filled-text-field-with-trailing-icon-trailing-space, 12px);--md-filled-field-active-indicator-color: var(--_active-indicator-color);--md-filled-field-active-indicator-height: var(--_active-indicator-height);--md-filled-field-bottom-space: var(--_bottom-space);--md-filled-field-container-color: var(--_container-color);--md-filled-field-container-shape-end-end: var(--_container-shape-end-end);--md-filled-field-container-shape-end-start: var(--_container-shape-end-start);--md-filled-field-container-shape-start-end: var(--_container-shape-start-end);--md-filled-field-container-shape-start-start: var(--_container-shape-start-start);--md-filled-field-content-color: var(--_input-text-color);--md-filled-field-content-font: var(--_input-text-font);--md-filled-field-content-line-height: var(--_input-text-line-height);--md-filled-field-content-size: var(--_input-text-size);--md-filled-field-content-space: var(--_icon-input-space);--md-filled-field-content-weight: var(--_input-text-weight);--md-filled-field-disabled-active-indicator-color: var(--_disabled-active-indicator-color);--md-filled-field-disabled-active-indicator-height: var(--_disabled-active-indicator-height);--md-filled-field-disabled-active-indicator-opacity: var(--_disabled-active-indicator-opacity);--md-filled-field-disabled-container-color: var(--_disabled-container-color);--md-filled-field-disabled-container-opacity: var(--_disabled-container-opacity);--md-filled-field-disabled-content-color: var(--_disabled-input-text-color);--md-filled-field-disabled-content-opacity: var(--_disabled-input-text-opacity);--md-filled-field-disabled-label-text-color: var(--_disabled-label-text-color);--md-filled-field-disabled-label-text-opacity: var(--_disabled-label-text-opacity);--md-filled-field-disabled-leading-content-color: var(--_disabled-leading-icon-color);--md-filled-field-disabled-leading-content-opacity: var(--_disabled-leading-icon-opacity);--md-filled-field-disabled-supporting-text-color: var(--_disabled-supporting-text-color);--md-filled-field-disabled-supporting-text-opacity: var(--_disabled-supporting-text-opacity);--md-filled-field-disabled-trailing-content-color: var(--_disabled-trailing-icon-color);--md-filled-field-disabled-trailing-content-opacity: var(--_disabled-trailing-icon-opacity);--md-filled-field-error-active-indicator-color: var(--_error-active-indicator-color);--md-filled-field-error-content-color: var(--_error-input-text-color);--md-filled-field-error-focus-active-indicator-color: var(--_error-focus-active-indicator-color);--md-filled-field-error-focus-content-color: var(--_error-focus-input-text-color);--md-filled-field-error-focus-label-text-color: var(--_error-focus-label-text-color);--md-filled-field-error-focus-leading-content-color: var(--_error-focus-leading-icon-color);--md-filled-field-error-focus-supporting-text-color: var(--_error-focus-supporting-text-color);--md-filled-field-error-focus-trailing-content-color: var(--_error-focus-trailing-icon-color);--md-filled-field-error-hover-active-indicator-color: var(--_error-hover-active-indicator-color);--md-filled-field-error-hover-content-color: var(--_error-hover-input-text-color);--md-filled-field-error-hover-label-text-color: var(--_error-hover-label-text-color);--md-filled-field-error-hover-leading-content-color: var(--_error-hover-leading-icon-color);--md-filled-field-error-hover-state-layer-color: var(--_error-hover-state-layer-color);--md-filled-field-error-hover-state-layer-opacity: var(--_error-hover-state-layer-opacity);--md-filled-field-error-hover-supporting-text-color: var(--_error-hover-supporting-text-color);--md-filled-field-error-hover-trailing-content-color: var(--_error-hover-trailing-icon-color);--md-filled-field-error-label-text-color: var(--_error-label-text-color);--md-filled-field-error-leading-content-color: var(--_error-leading-icon-color);--md-filled-field-error-supporting-text-color: var(--_error-supporting-text-color);--md-filled-field-error-trailing-content-color: var(--_error-trailing-icon-color);--md-filled-field-focus-active-indicator-color: var(--_focus-active-indicator-color);--md-filled-field-focus-active-indicator-height: var(--_focus-active-indicator-height);--md-filled-field-focus-content-color: var(--_focus-input-text-color);--md-filled-field-focus-label-text-color: var(--_focus-label-text-color);--md-filled-field-focus-leading-content-color: var(--_focus-leading-icon-color);--md-filled-field-focus-supporting-text-color: var(--_focus-supporting-text-color);--md-filled-field-focus-trailing-content-color: var(--_focus-trailing-icon-color);--md-filled-field-hover-active-indicator-color: var(--_hover-active-indicator-color);--md-filled-field-hover-active-indicator-height: var(--_hover-active-indicator-height);--md-filled-field-hover-content-color: var(--_hover-input-text-color);--md-filled-field-hover-label-text-color: var(--_hover-label-text-color);--md-filled-field-hover-leading-content-color: var(--_hover-leading-icon-color);--md-filled-field-hover-state-layer-color: var(--_hover-state-layer-color);--md-filled-field-hover-state-layer-opacity: var(--_hover-state-layer-opacity);--md-filled-field-hover-supporting-text-color: var(--_hover-supporting-text-color);--md-filled-field-hover-trailing-content-color: var(--_hover-trailing-icon-color);--md-filled-field-label-text-color: var(--_label-text-color);--md-filled-field-label-text-font: var(--_label-text-font);--md-filled-field-label-text-line-height: var(--_label-text-line-height);--md-filled-field-label-text-populated-line-height: var(--_label-text-populated-line-height);--md-filled-field-label-text-populated-size: var(--_label-text-populated-size);--md-filled-field-label-text-size: var(--_label-text-size);--md-filled-field-label-text-weight: var(--_label-text-weight);--md-filled-field-leading-content-color: var(--_leading-icon-color);--md-filled-field-leading-space: var(--_leading-space);--md-filled-field-supporting-text-color: var(--_supporting-text-color);--md-filled-field-supporting-text-font: var(--_supporting-text-font);--md-filled-field-supporting-text-line-height: var(--_supporting-text-line-height);--md-filled-field-supporting-text-size: var(--_supporting-text-size);--md-filled-field-supporting-text-weight: var(--_supporting-text-weight);--md-filled-field-top-space: var(--_top-space);--md-filled-field-trailing-content-color: var(--_trailing-icon-color);--md-filled-field-trailing-space: var(--_trailing-space);--md-filled-field-with-label-bottom-space: var(--_with-label-bottom-space);--md-filled-field-with-label-top-space: var(--_with-label-top-space);--md-filled-field-with-leading-content-leading-space: var(--_with-leading-icon-leading-space);--md-filled-field-with-trailing-content-trailing-space: var(--_with-trailing-icon-trailing-space)} -`; -//# sourceMappingURL=filled-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/textfield/internal/filled-text-field.js": -/*!****************************************************************************!*\ - !*** ./node_modules/@material/web/textfield/internal/filled-text-field.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ FilledTextField: () => (/* binding */ FilledTextField) -/* harmony export */ }); -/* harmony import */ var _field_filled_field_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../field/filled-field.js */ "./node_modules/@material/web/field/filled-field.js"); -/* harmony import */ var lit_static_html_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/static-html.js */ "./node_modules/lit/static-html.js"); -/* harmony import */ var _text_field_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./text-field.js */ "./node_modules/@material/web/textfield/internal/text-field.js"); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - -/** - * A filled text field component. - */ -class FilledTextField extends _text_field_js__WEBPACK_IMPORTED_MODULE_2__.TextField { - constructor() { - super(...arguments); - this.fieldTag = (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_1__.literal) `md-filled-field`; - } -} -//# sourceMappingURL=filled-text-field.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/textfield/internal/shared-styles.js": -/*!************************************************************************!*\ - !*** ./node_modules/@material/web/textfield/internal/shared-styles.js ***! - \************************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styles: () => (/* binding */ styles) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/** - * @license - * Copyright 2024 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -// Generated stylesheet for ./textfield/internal/shared-styles.css. - -const styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) `:host{display:inline-flex;outline:none;resize:both;text-align:start;-webkit-tap-highlight-color:rgba(0,0,0,0)}.text-field,.field{width:100%}.text-field{display:inline-flex}.field{cursor:text}.disabled .field{cursor:default}.text-field,.textarea .field{resize:inherit}slot[name=container]{border-radius:inherit}.icon{color:currentColor;display:flex;align-items:center;justify-content:center;fill:currentColor;position:relative}.icon ::slotted(*){display:flex;position:absolute}[has-start] .icon.leading{font-size:var(--_leading-icon-size);height:var(--_leading-icon-size);width:var(--_leading-icon-size)}[has-end] .icon.trailing{font-size:var(--_trailing-icon-size);height:var(--_trailing-icon-size);width:var(--_trailing-icon-size)}.input-wrapper{display:flex}.input-wrapper>*{all:inherit;padding:0}.input{caret-color:var(--_caret-color);overflow-x:hidden;text-align:inherit}.input::placeholder{color:currentColor;opacity:1}.input::-webkit-calendar-picker-indicator{display:none}.input::-webkit-search-decoration,.input::-webkit-search-cancel-button{display:none}@media(forced-colors: active){.input{background:none}}.no-spinner .input::-webkit-inner-spin-button,.no-spinner .input::-webkit-outer-spin-button{display:none}.no-spinner .input[type=number]{-moz-appearance:textfield}:focus-within .input{caret-color:var(--_focus-caret-color)}.error:focus-within .input{caret-color:var(--_error-focus-caret-color)}.text-field:not(.disabled) .prefix{color:var(--_input-text-prefix-color)}.text-field:not(.disabled) .suffix{color:var(--_input-text-suffix-color)}.text-field:not(.disabled) .input::placeholder{color:var(--_input-text-placeholder-color)}.prefix,.suffix{text-wrap:nowrap;width:min-content}.prefix{padding-inline-end:var(--_input-text-prefix-trailing-space)}.suffix{padding-inline-start:var(--_input-text-suffix-leading-space)} -`; -//# sourceMappingURL=shared-styles.js.map - -/***/ }), - -/***/ "./node_modules/@material/web/textfield/internal/text-field.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@material/web/textfield/internal/text-field.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ TextField: () => (/* binding */ TextField) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var lit_directives_class_map_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lit/directives/class-map.js */ "./node_modules/lit/directives/class-map.js"); -/* harmony import */ var lit_directives_live_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lit/directives/live.js */ "./node_modules/lit/directives/live.js"); -/* harmony import */ var lit_directives_style_map_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lit/directives/style-map.js */ "./node_modules/lit/directives/style-map.js"); -/* harmony import */ var lit_static_html_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lit/static-html.js */ "./node_modules/lit/static-html.js"); -/* harmony import */ var _internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../internal/aria/delegate.js */ "./node_modules/@material/web/internal/aria/delegate.js"); -/* harmony import */ var _internal_controller_string_converter_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../internal/controller/string-converter.js */ "./node_modules/@material/web/internal/controller/string-converter.js"); -/* harmony import */ var _internal_events_redispatch_event_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../internal/events/redispatch-event.js */ "./node_modules/@material/web/internal/events/redispatch-event.js"); -/* harmony import */ var _labs_behaviors_constraint_validation_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../labs/behaviors/constraint-validation.js */ "./node_modules/@material/web/labs/behaviors/constraint-validation.js"); -/* harmony import */ var _labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../labs/behaviors/element-internals.js */ "./node_modules/@material/web/labs/behaviors/element-internals.js"); -/* harmony import */ var _labs_behaviors_form_associated_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../labs/behaviors/form-associated.js */ "./node_modules/@material/web/labs/behaviors/form-associated.js"); -/* harmony import */ var _labs_behaviors_on_report_validity_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../labs/behaviors/on-report-validity.js */ "./node_modules/@material/web/labs/behaviors/on-report-validity.js"); -/* harmony import */ var _labs_behaviors_validators_text_field_validator_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../labs/behaviors/validators/text-field-validator.js */ "./node_modules/@material/web/labs/behaviors/validators/text-field-validator.js"); -/** - * @license - * Copyright 2021 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - - - - - - - - - - - - - - - -// Separate variable needed for closure. -const textFieldBaseClass = (0,_internal_aria_delegate_js__WEBPACK_IMPORTED_MODULE_6__.mixinDelegatesAria)((0,_labs_behaviors_on_report_validity_js__WEBPACK_IMPORTED_MODULE_12__.mixinOnReportValidity)((0,_labs_behaviors_constraint_validation_js__WEBPACK_IMPORTED_MODULE_9__.mixinConstraintValidation)((0,_labs_behaviors_form_associated_js__WEBPACK_IMPORTED_MODULE_11__.mixinFormAssociated)((0,_labs_behaviors_element_internals_js__WEBPACK_IMPORTED_MODULE_10__.mixinElementInternals)(lit__WEBPACK_IMPORTED_MODULE_0__.LitElement))))); -/** - * A text field component. - * - * @fires select {Event} The native `select` event on - * [``](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select_event) - * --bubbles - * @fires change {Event} The native `change` event on - * [``](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event) - * --bubbles - * @fires input {InputEvent} The native `input` event on - * [``](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event) - * --bubbles --composed - */ -class TextField extends textFieldBaseClass { - constructor() { - super(...arguments); - /** - * Gets or sets whether or not the text field is in a visually invalid state. - * - * This error state overrides the error state controlled by - * `reportValidity()`. - */ - this.error = false; - /** - * The error message that replaces supporting text when `error` is true. If - * `errorText` is an empty string, then the supporting text will continue to - * show. - * - * This error message overrides the error message displayed by - * `reportValidity()`. - */ - this.errorText = ''; - /** - * The floating Material label of the textfield component. It informs the user - * about what information is requested for a text field. It is aligned with - * the input text, is always visible, and it floats when focused or when text - * is entered into the textfield. This label also sets accessibilty labels, - * but the accessible label is overriden by `aria-label`. - * - * Learn more about floating labels from the Material Design guidelines: - * https://m3.material.io/components/text-fields/guidelines - */ - this.label = ''; - /** - * Disables the asterisk on the floating label, when the text field is - * required. - */ - this.noAsterisk = false; - /** - * Indicates that the user must specify a value for the input before the - * owning form can be submitted and will render an error state when - * `reportValidity()` is invoked when value is empty. Additionally the - * floating label will render an asterisk `"*"` when true. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/required - */ - this.required = false; - /** - * The current value of the text field. It is always a string. - */ - this.value = ''; - /** - * An optional prefix to display before the input value. - */ - this.prefixText = ''; - /** - * An optional suffix to display after the input value. - */ - this.suffixText = ''; - /** - * Whether or not the text field has a leading icon. Used for SSR. - */ - this.hasLeadingIcon = false; - /** - * Whether or not the text field has a trailing icon. Used for SSR. - */ - this.hasTrailingIcon = false; - /** - * Conveys additional information below the text field, such as how it should - * be used. - */ - this.supportingText = ''; - /** - * Override the input text CSS `direction`. Useful for RTL languages that use - * LTR notation for fractions. - */ - this.textDirection = ''; - /** - * The number of rows to display for a `type="textarea"` text field. - * Defaults to 2. - */ - this.rows = 2; - /** - * The number of cols to display for a `type="textarea"` text field. - * Defaults to 20. - */ - this.cols = 20; - // properties - this.inputMode = ''; - /** - * Defines the greatest value in the range of permitted values. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#max - */ - this.max = ''; - /** - * The maximum number of characters a user can enter into the text field. Set - * to -1 for none. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#maxlength - */ - this.maxLength = -1; - /** - * Defines the most negative value in the range of permitted values. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#min - */ - this.min = ''; - /** - * The minimum number of characters a user can enter into the text field. Set - * to -1 for none. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#minlength - */ - this.minLength = -1; - /** - * When true, hide the spinner for `type="number"` text fields. - */ - this.noSpinner = false; - /** - * A regular expression that the text field's value must match to pass - * constraint validation. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#pattern - */ - this.pattern = ''; - /** - * Defines the text displayed in the textfield when it has no value. Provides - * a brief hint to the user as to the expected type of data that should be - * entered into the control. Unlike `label`, the placeholder is not visible - * and does not float when the textfield has a value. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/placeholder - */ - this.placeholder = ''; - /** - * Indicates whether or not a user should be able to edit the text field's - * value. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#readonly - */ - this.readOnly = false; - /** - * Indicates that input accepts multiple email addresses. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email#multiple - */ - this.multiple = false; - /** - * Returns or sets the element's step attribute, which works with min and max - * to limit the increments at which a numeric or date-time value can be set. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#step - */ - this.step = ''; - /** - * The `` type to use, defaults to "text". The type greatly changes how - * the text field behaves. - * - * Text fields support a limited number of `` types: - * - * - text - * - textarea - * - email - * - number - * - password - * - search - * - tel - * - url - * - * See - * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types - * for more details on each input type. - */ - this.type = 'text'; - /** - * Describes what, if any, type of autocomplete functionality the input - * should provide. - * - * https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete - */ - this.autocomplete = ''; - /** - * Returns true when the text field has been interacted with. Native - * validation errors only display in response to user interactions. - */ - this.dirty = false; - this.focused = false; - /** - * Whether or not a native error has been reported via `reportValidity()`. - */ - this.nativeError = false; - /** - * The validation message displayed from a native error via - * `reportValidity()`. - */ - this.nativeErrorText = ''; - } - /** - * Gets or sets the direction in which selection occurred. - */ - get selectionDirection() { - return this.getInputOrTextarea().selectionDirection; - } - set selectionDirection(value) { - this.getInputOrTextarea().selectionDirection = value; - } - /** - * Gets or sets the end position or offset of a text selection. - */ - get selectionEnd() { - return this.getInputOrTextarea().selectionEnd; - } - set selectionEnd(value) { - this.getInputOrTextarea().selectionEnd = value; - } - /** - * Gets or sets the starting position or offset of a text selection. - */ - get selectionStart() { - return this.getInputOrTextarea().selectionStart; - } - set selectionStart(value) { - this.getInputOrTextarea().selectionStart = value; - } - /** - * The text field's value as a number. - */ - get valueAsNumber() { - const input = this.getInput(); - if (!input) { - return NaN; - } - return input.valueAsNumber; - } - set valueAsNumber(value) { - const input = this.getInput(); - if (!input) { - return; - } - input.valueAsNumber = value; - this.value = input.value; - } - /** - * The text field's value as a Date. - */ - get valueAsDate() { - const input = this.getInput(); - if (!input) { - return null; - } - return input.valueAsDate; - } - set valueAsDate(value) { - const input = this.getInput(); - if (!input) { - return; - } - input.valueAsDate = value; - this.value = input.value; - } - get hasError() { - return this.error || this.nativeError; - } - /** - * Selects all the text in the text field. - * - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select - */ - select() { - this.getInputOrTextarea().select(); - } - setRangeText(...args) { - // Calling setRangeText with 1 vs 3-4 arguments has different behavior. - // Use spread syntax and type casting to ensure correct usage. - this.getInputOrTextarea().setRangeText(...args); - this.value = this.getInputOrTextarea().value; - } - /** - * Sets the start and end positions of a selection in the text field. - * - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange - * - * @param start The offset into the text field for the start of the selection. - * @param end The offset into the text field for the end of the selection. - * @param direction The direction in which the selection is performed. - */ - setSelectionRange(start, end, direction) { - this.getInputOrTextarea().setSelectionRange(start, end, direction); - } - /** - * Shows the browser picker for an input element of type "date", "time", etc. - * - * For a full list of supported types, see: - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/showPicker#browser_compatibility - * - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/showPicker - */ - showPicker() { - const input = this.getInput(); - if (!input) { - return; - } - input.showPicker(); - } - /** - * Decrements the value of a numeric type text field by `step` or `n` `step` - * number of times. - * - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/stepDown - * - * @param stepDecrement The number of steps to decrement, defaults to 1. - */ - stepDown(stepDecrement) { - const input = this.getInput(); - if (!input) { - return; - } - input.stepDown(stepDecrement); - this.value = input.value; - } - /** - * Increments the value of a numeric type text field by `step` or `n` `step` - * number of times. - * - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/stepUp - * - * @param stepIncrement The number of steps to increment, defaults to 1. - */ - stepUp(stepIncrement) { - const input = this.getInput(); - if (!input) { - return; - } - input.stepUp(stepIncrement); - this.value = input.value; - } - /** - * Reset the text field to its default value. - */ - reset() { - this.dirty = false; - this.value = this.getAttribute('value') ?? ''; - this.nativeError = false; - this.nativeErrorText = ''; - } - attributeChangedCallback(attribute, newValue, oldValue) { - if (attribute === 'value' && this.dirty) { - // After user input, changing the value attribute no longer updates the - // text field's value (until reset). This matches native behavior. - return; - } - super.attributeChangedCallback(attribute, newValue, oldValue); - } - render() { - const classes = { - 'disabled': this.disabled, - 'error': !this.disabled && this.hasError, - 'textarea': this.type === 'textarea', - 'no-spinner': this.noSpinner, - }; - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${this.renderField()} - - `; - } - updated(changedProperties) { - // Keep changedProperties arg so that subclasses may call it - // If a property such as `type` changes and causes the internal - // value to change without dispatching an event, re-sync it. - const value = this.getInputOrTextarea().value; - if (this.value !== value) { - // Note this is typically inefficient in updated() since it schedules - // another update. However, it is needed for the to fully render - // before checking its value. - this.value = value; - } - } - renderField() { - return (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_5__.html) `<${this.fieldTag} - class="field" - count=${this.value.length} - ?disabled=${this.disabled} - ?error=${this.hasError} - error-text=${this.getErrorText()} - ?focused=${this.focused} - ?has-end=${this.hasTrailingIcon} - ?has-start=${this.hasLeadingIcon} - label=${this.label} - ?no-asterisk=${this.noAsterisk} - max=${this.maxLength} - ?populated=${!!this.value} - ?required=${this.required} - ?resizable=${this.type === 'textarea'} - supporting-text=${this.supportingText} - > - ${this.renderLeadingIcon()} - ${this.renderInputOrTextarea()} - ${this.renderTrailingIcon()} -
    - - `; - } - renderLeadingIcon() { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - - - `; - } - renderTrailingIcon() { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - - - `; - } - renderInputOrTextarea() { - const style = { 'direction': this.textDirection }; - const ariaLabel = this.ariaLabel || this.label || lit__WEBPACK_IMPORTED_MODULE_0__.nothing; - // lit-anaylzer `autocomplete` types are too strict - // tslint:disable-next-line:no-any - const autocomplete = this.autocomplete; - // These properties may be set to null if the attribute is removed, and - // `null > -1` is incorrectly `true`. - const hasMaxLength = (this.maxLength ?? -1) > -1; - const hasMinLength = (this.minLength ?? -1) > -1; - if (this.type === 'textarea') { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - `; - } - const prefix = this.renderPrefix(); - const suffix = this.renderSuffix(); - // TODO(b/243805848): remove `as unknown as number` and `as any` once lit - // analyzer is fixed - // tslint:disable-next-line:no-any - const inputMode = this.inputMode; - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - ${prefix} - - ${suffix} -
    - `; - } - renderPrefix() { - return this.renderAffix(this.prefixText, /* isSuffix */ false); - } - renderSuffix() { - return this.renderAffix(this.suffixText, /* isSuffix */ true); - } - renderAffix(text, isSuffix) { - if (!text) { - return lit__WEBPACK_IMPORTED_MODULE_0__.nothing; - } - const classes = { - 'suffix': isSuffix, - 'prefix': !isSuffix, - }; - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `${text}`; - } - getErrorText() { - return this.error ? this.errorText : this.nativeErrorText; - } - handleFocusChange() { - // When calling focus() or reportValidity() during change, it's possible - // for blur to be called after the new focus event. Rather than set - // `this.focused` to true/false on focus/blur, we always set it to whether - // or not the input itself is focused. - this.focused = this.inputOrTextarea?.matches(':focus') ?? false; - } - handleInput(event) { - this.dirty = true; - this.value = event.target.value; - } - redispatchEvent(event) { - (0,_internal_events_redispatch_event_js__WEBPACK_IMPORTED_MODULE_8__.redispatchEvent)(this, event); - } - getInputOrTextarea() { - if (!this.inputOrTextarea) { - // If the input is not yet defined, synchronously render. - // e.g. - // const textField = document.createElement('md-outlined-text-field'); - // document.body.appendChild(textField); - // textField.focus(); // synchronously render - this.connectedCallback(); - this.scheduleUpdate(); - } - if (this.isUpdatePending) { - // If there are pending updates, synchronously perform them. This ensures - // that constraint validation properties (like `required`) are synced - // before interacting with input APIs that depend on them. - this.scheduleUpdate(); - } - return this.inputOrTextarea; - } - getInput() { - if (this.type === 'textarea') { - return null; - } - return this.getInputOrTextarea(); - } - handleIconChange() { - this.hasLeadingIcon = this.leadingIcons.length > 0; - this.hasTrailingIcon = this.trailingIcons.length > 0; - } - [_labs_behaviors_form_associated_js__WEBPACK_IMPORTED_MODULE_11__.getFormValue]() { - return this.value; - } - formResetCallback() { - this.reset(); - } - formStateRestoreCallback(state) { - this.value = state; - } - focus() { - // Required for the case that the user slots a focusable element into the - // leading icon slot such as an iconbutton due to how delegatesFocus works. - this.getInputOrTextarea().focus(); - } - [_labs_behaviors_constraint_validation_js__WEBPACK_IMPORTED_MODULE_9__.createValidator]() { - return new _labs_behaviors_validators_text_field_validator_js__WEBPACK_IMPORTED_MODULE_13__.TextFieldValidator(() => ({ - state: this, - renderedControl: this.inputOrTextarea, - })); - } - [_labs_behaviors_constraint_validation_js__WEBPACK_IMPORTED_MODULE_9__.getValidityAnchor]() { - return this.inputOrTextarea; - } - [_labs_behaviors_on_report_validity_js__WEBPACK_IMPORTED_MODULE_12__.onReportValidity](invalidEvent) { - // Prevent default pop-up behavior. - invalidEvent?.preventDefault(); - const prevMessage = this.getErrorText(); - this.nativeError = !!invalidEvent; - this.nativeErrorText = this.validationMessage; - if (prevMessage === this.getErrorText()) { - this.field?.reannounceError(); - } - } -} -/** @nocollapse */ -TextField.shadowRootOptions = { - ...lit__WEBPACK_IMPORTED_MODULE_0__.LitElement.shadowRootOptions, - delegatesFocus: true, -}; -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true }) -], TextField.prototype, "error", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ attribute: 'error-text' }) -], TextField.prototype, "errorText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], TextField.prototype, "label", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, attribute: 'no-asterisk' }) -], TextField.prototype, "noAsterisk", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true }) -], TextField.prototype, "required", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], TextField.prototype, "value", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ attribute: 'prefix-text' }) -], TextField.prototype, "prefixText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ attribute: 'suffix-text' }) -], TextField.prototype, "suffixText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, attribute: 'has-leading-icon' }) -], TextField.prototype, "hasLeadingIcon", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, attribute: 'has-trailing-icon' }) -], TextField.prototype, "hasTrailingIcon", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ attribute: 'supporting-text' }) -], TextField.prototype, "supportingText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ attribute: 'text-direction' }) -], TextField.prototype, "textDirection", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Number }) -], TextField.prototype, "rows", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Number }) -], TextField.prototype, "cols", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ reflect: true }) -], TextField.prototype, "inputMode", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], TextField.prototype, "max", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Number }) -], TextField.prototype, "maxLength", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], TextField.prototype, "min", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Number }) -], TextField.prototype, "minLength", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, attribute: 'no-spinner' }) -], TextField.prototype, "noSpinner", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], TextField.prototype, "pattern", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ reflect: true, converter: _internal_controller_string_converter_js__WEBPACK_IMPORTED_MODULE_7__.stringConverter }) -], TextField.prototype, "placeholder", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true }) -], TextField.prototype, "readOnly", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ type: Boolean, reflect: true }) -], TextField.prototype, "multiple", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], TextField.prototype, "step", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ reflect: true }) -], TextField.prototype, "type", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)({ reflect: true }) -], TextField.prototype, "autocomplete", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], TextField.prototype, "dirty", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], TextField.prototype, "focused", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], TextField.prototype, "nativeError", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], TextField.prototype, "nativeErrorText", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.query)('.input') -], TextField.prototype, "inputOrTextarea", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.query)('.field') -], TextField.prototype, "field", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.queryAssignedElements)({ slot: 'leading-icon' }) -], TextField.prototype, "leadingIcons", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_14__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.queryAssignedElements)({ slot: 'trailing-icon' }) -], TextField.prototype, "trailingIcons", void 0); -//# sourceMappingURL=text-field.js.map - -/***/ }), - -/***/ "./node_modules/atob-lite/atob-browser.js": -/*!************************************************!*\ - !*** ./node_modules/atob-lite/atob-browser.js ***! - \************************************************/ -/***/ ((module) => { - -module.exports = function _atob(str) { - return atob(str) -} - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-checkbox.js": -/*!*******************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-checkbox.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwCheckbox: () => (/* binding */ EwCheckbox) -/* harmony export */ }); -/* harmony import */ var _material_web_checkbox_internal_checkbox_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/checkbox/internal/checkbox.js */ "./node_modules/@material/web/checkbox/internal/checkbox.js"); -/* harmony import */ var _material_web_checkbox_internal_checkbox_styles_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/checkbox/internal/checkbox-styles.js */ "./node_modules/@material/web/checkbox/internal/checkbox-styles.js"); - - -class EwCheckbox extends _material_web_checkbox_internal_checkbox_js__WEBPACK_IMPORTED_MODULE_0__.Checkbox { -} -EwCheckbox.styles = [_material_web_checkbox_internal_checkbox_styles_js__WEBPACK_IMPORTED_MODULE_1__.styles]; -customElements.define("ew-checkbox", EwCheckbox); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-circular-progress.js": -/*!****************************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-circular-progress.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwCircularProgress: () => (/* binding */ EwCircularProgress) -/* harmony export */ }); -/* harmony import */ var _material_web_progress_internal_circular_progress_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/progress/internal/circular-progress.js */ "./node_modules/@material/web/progress/internal/circular-progress.js"); -/* harmony import */ var _material_web_progress_internal_circular_progress_styles_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/progress/internal/circular-progress-styles.js */ "./node_modules/@material/web/progress/internal/circular-progress-styles.js"); - - -class EwCircularProgress extends _material_web_progress_internal_circular_progress_js__WEBPACK_IMPORTED_MODULE_0__.CircularProgress { -} -EwCircularProgress.styles = [_material_web_progress_internal_circular_progress_styles_js__WEBPACK_IMPORTED_MODULE_1__.styles]; -customElements.define("ew-circular-progress", EwCircularProgress); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-divider.js": -/*!******************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-divider.js ***! - \******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwDivider: () => (/* binding */ EwDivider) -/* harmony export */ }); -/* harmony import */ var _material_web_divider_internal_divider_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/divider/internal/divider.js */ "./node_modules/@material/web/divider/internal/divider.js"); -/* harmony import */ var _material_web_divider_internal_divider_styles_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/divider/internal/divider-styles.js */ "./node_modules/@material/web/divider/internal/divider-styles.js"); - - -class EwDivider extends _material_web_divider_internal_divider_js__WEBPACK_IMPORTED_MODULE_0__.Divider { -} -EwDivider.styles = [_material_web_divider_internal_divider_styles_js__WEBPACK_IMPORTED_MODULE_1__.styles]; -customElements.define("ew-divider", EwDivider); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-filled-select.js": -/*!************************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-filled-select.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwFilledSelect: () => (/* binding */ EwFilledSelect) -/* harmony export */ }); -/* harmony import */ var _material_web_select_internal_filled_select_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/select/internal/filled-select.js */ "./node_modules/@material/web/select/internal/filled-select.js"); -/* harmony import */ var _material_web_select_internal_filled_select_styles_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/select/internal/filled-select-styles.js */ "./node_modules/@material/web/select/internal/filled-select-styles.js"); -/* harmony import */ var _material_web_select_internal_shared_styles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material/web/select/internal/shared-styles.js */ "./node_modules/@material/web/select/internal/shared-styles.js"); - - - -class EwFilledSelect extends _material_web_select_internal_filled_select_js__WEBPACK_IMPORTED_MODULE_0__.FilledSelect { -} -EwFilledSelect.styles = [_material_web_select_internal_shared_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles, _material_web_select_internal_filled_select_styles_js__WEBPACK_IMPORTED_MODULE_1__.styles]; -customElements.define("ew-filled-select", EwFilledSelect); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-filled-text-field.js": -/*!****************************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-filled-text-field.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwFilledTextField: () => (/* binding */ EwFilledTextField) -/* harmony export */ }); -/* harmony import */ var _material_web_textfield_internal_filled_styles_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/textfield/internal/filled-styles.js */ "./node_modules/@material/web/textfield/internal/filled-styles.js"); -/* harmony import */ var _material_web_textfield_internal_filled_text_field_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/textfield/internal/filled-text-field.js */ "./node_modules/@material/web/textfield/internal/filled-text-field.js"); -/* harmony import */ var _material_web_textfield_internal_shared_styles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material/web/textfield/internal/shared-styles.js */ "./node_modules/@material/web/textfield/internal/shared-styles.js"); -/* harmony import */ var lit_static_html_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lit/static-html.js */ "./node_modules/lit/static-html.js"); - - - - -class EwFilledTextField extends _material_web_textfield_internal_filled_text_field_js__WEBPACK_IMPORTED_MODULE_1__.FilledTextField { - constructor() { - super(...arguments); - this.fieldTag = (0,lit_static_html_js__WEBPACK_IMPORTED_MODULE_3__.literal) `md-filled-field`; - } -} -EwFilledTextField.styles = [_material_web_textfield_internal_shared_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles, _material_web_textfield_internal_filled_styles_js__WEBPACK_IMPORTED_MODULE_0__.styles]; -customElements.define("ew-filled-text-field", EwFilledTextField); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-icon-button.js": -/*!**********************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-icon-button.js ***! - \**********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwIconButton: () => (/* binding */ EwIconButton) -/* harmony export */ }); -/* harmony import */ var _material_web_iconbutton_internal_icon_button_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/iconbutton/internal/icon-button.js */ "./node_modules/@material/web/iconbutton/internal/icon-button.js"); -/* harmony import */ var _material_web_iconbutton_internal_shared_styles_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/iconbutton/internal/shared-styles.js */ "./node_modules/@material/web/iconbutton/internal/shared-styles.js"); -/* harmony import */ var _material_web_iconbutton_internal_standard_styles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @material/web/iconbutton/internal/standard-styles.js */ "./node_modules/@material/web/iconbutton/internal/standard-styles.js"); - - - -class EwIconButton extends _material_web_iconbutton_internal_icon_button_js__WEBPACK_IMPORTED_MODULE_0__.IconButton { -} -EwIconButton.styles = [_material_web_iconbutton_internal_shared_styles_js__WEBPACK_IMPORTED_MODULE_1__.styles, _material_web_iconbutton_internal_standard_styles_js__WEBPACK_IMPORTED_MODULE_2__.styles]; -customElements.define("ew-icon-button", EwIconButton); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-list-item.js": -/*!********************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-list-item.js ***! - \********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwListItem: () => (/* binding */ EwListItem) -/* harmony export */ }); -/* harmony import */ var _material_web_list_internal_listitem_list_item_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/list/internal/listitem/list-item.js */ "./node_modules/@material/web/list/internal/listitem/list-item.js"); -/* harmony import */ var _material_web_list_internal_listitem_list_item_styles_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/list/internal/listitem/list-item-styles.js */ "./node_modules/@material/web/list/internal/listitem/list-item-styles.js"); - - -class EwListItem extends _material_web_list_internal_listitem_list_item_js__WEBPACK_IMPORTED_MODULE_0__.ListItemEl { -} -EwListItem.styles = [_material_web_list_internal_listitem_list_item_styles_js__WEBPACK_IMPORTED_MODULE_1__.styles]; -customElements.define("ew-list-item", EwListItem); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-list.js": -/*!***************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-list.js ***! - \***************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwList: () => (/* binding */ EwList) -/* harmony export */ }); -/* harmony import */ var _material_web_list_internal_list_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/list/internal/list.js */ "./node_modules/@material/web/list/internal/list.js"); -/* harmony import */ var _material_web_list_internal_list_styles_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/list/internal/list-styles.js */ "./node_modules/@material/web/list/internal/list-styles.js"); - - -class EwList extends _material_web_list_internal_list_js__WEBPACK_IMPORTED_MODULE_0__.List { -} -EwList.styles = [_material_web_list_internal_list_styles_js__WEBPACK_IMPORTED_MODULE_1__.styles]; -customElements.define("ew-list", EwList); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ew-select-option.js": -/*!************************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ew-select-option.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwSelectOption: () => (/* binding */ EwSelectOption) -/* harmony export */ }); -/* harmony import */ var _material_web_menu_internal_menuitem_menu_item_styles_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @material/web/menu/internal/menuitem/menu-item-styles.js */ "./node_modules/@material/web/menu/internal/menuitem/menu-item-styles.js"); -/* harmony import */ var _material_web_select_internal_selectoption_select_option_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @material/web/select/internal/selectoption/select-option.js */ "./node_modules/@material/web/select/internal/selectoption/select-option.js"); - - -class EwSelectOption extends _material_web_select_internal_selectoption_select_option_js__WEBPACK_IMPORTED_MODULE_1__.SelectOptionEl { -} -EwSelectOption.styles = [_material_web_menu_internal_menuitem_menu_item_styles_js__WEBPACK_IMPORTED_MODULE_0__.styles]; -customElements.define("ew-select-option", EwSelectOption); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/ewt-console.js": -/*!*******************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/ewt-console.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwtConsole: () => (/* binding */ EwtConsole) -/* harmony export */ }); -/* harmony import */ var _util_console_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/console-color */ "./node_modules/esp-web-tools/dist/util/console-color.js"); -/* harmony import */ var _util_sleep__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/sleep */ "./node_modules/esp-web-tools/dist/util/sleep.js"); -/* harmony import */ var _util_line_break_transformer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/line-break-transformer */ "./node_modules/esp-web-tools/dist/util/line-break-transformer.js"); -/* harmony import */ var _util_timestamp_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/timestamp-transformer */ "./node_modules/esp-web-tools/dist/util/timestamp-transformer.js"); - - - - -class EwtConsole extends HTMLElement { - constructor() { - super(...arguments); - this.allowInput = true; - } - logs() { - var _a; - return ((_a = this._console) === null || _a === void 0 ? void 0 : _a.logs()) || ""; - } - connectedCallback() { - if (this._console) { - return; - } - const shadowRoot = this.attachShadow({ mode: "open" }); - shadowRoot.innerHTML = ` - -
    - ${this.allowInput - ? `
    - > - -
    - ` - : ""} - `; - this._console = new _util_console_color__WEBPACK_IMPORTED_MODULE_0__.ColoredConsole(this.shadowRoot.querySelector("div")); - if (this.allowInput) { - const input = this.shadowRoot.querySelector("input"); - this.addEventListener("click", () => { - var _a; - // Only focus input if user didn't select some text - if (((_a = getSelection()) === null || _a === void 0 ? void 0 : _a.toString()) === "") { - input.focus(); - } - }); - input.addEventListener("keydown", (ev) => { - if (ev.key === "Enter") { - ev.preventDefault(); - ev.stopPropagation(); - this._sendCommand(); - } - }); - } - const abortController = new AbortController(); - const connection = this._connect(abortController.signal); - this._cancelConnection = () => { - abortController.abort(); - return connection; - }; - } - async _connect(abortSignal) { - this.logger.debug("Starting console read loop"); - try { - await this.port - .readable.pipeThrough(new TextDecoderStream(), { - signal: abortSignal, - }) - .pipeThrough(new TransformStream(new _util_line_break_transformer__WEBPACK_IMPORTED_MODULE_2__.LineBreakTransformer())) - .pipeThrough(new TransformStream(new _util_timestamp_transformer__WEBPACK_IMPORTED_MODULE_3__.TimestampTransformer())) - .pipeTo(new WritableStream({ - write: (chunk) => { - this._console.addLine(chunk.replace("\r", "")); - }, - })); - if (!abortSignal.aborted) { - this._console.addLine(""); - this._console.addLine(""); - this._console.addLine("Terminal disconnected"); - } - } - catch (e) { - this._console.addLine(""); - this._console.addLine(""); - this._console.addLine(`Terminal disconnected: ${e}`); - } - finally { - await (0,_util_sleep__WEBPACK_IMPORTED_MODULE_1__.sleep)(100); - this.logger.debug("Finished console read loop"); - } - } - async _sendCommand() { - const input = this.shadowRoot.querySelector("input"); - const command = input.value; - const encoder = new TextEncoder(); - const writer = this.port.writable.getWriter(); - await writer.write(encoder.encode(command + "\r\n")); - this._console.addLine(`> ${command}\r\n`); - input.value = ""; - input.focus(); - try { - writer.releaseLock(); - } - catch (err) { - console.error("Ignoring release lock error", err); - } - } - async disconnect() { - if (this._cancelConnection) { - await this._cancelConnection(); - this._cancelConnection = undefined; - } - } - async reset() { - this.logger.debug("Triggering reset"); - await this.port.setSignals({ - dataTerminalReady: false, - requestToSend: true, - }); - await (0,_util_sleep__WEBPACK_IMPORTED_MODULE_1__.sleep)(250); - await this.port.setSignals({ - dataTerminalReady: false, - requestToSend: false, - }); - await (0,_util_sleep__WEBPACK_IMPORTED_MODULE_1__.sleep)(250); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } -} -customElements.define("ewt-console", EwtConsole); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/components/svg.js": -/*!***********************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/components/svg.js ***! - \***********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ closeIcon: () => (/* binding */ closeIcon), -/* harmony export */ listItemConsole: () => (/* binding */ listItemConsole), -/* harmony export */ listItemEraseUserData: () => (/* binding */ listItemEraseUserData), -/* harmony export */ listItemFundDevelopment: () => (/* binding */ listItemFundDevelopment), -/* harmony export */ listItemHomeAssistant: () => (/* binding */ listItemHomeAssistant), -/* harmony export */ listItemInstallIcon: () => (/* binding */ listItemInstallIcon), -/* harmony export */ listItemVisitDevice: () => (/* binding */ listItemVisitDevice), -/* harmony export */ listItemWifi: () => (/* binding */ listItemWifi), -/* harmony export */ refreshIcon: () => (/* binding */ refreshIcon) -/* harmony export */ }); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); - -const closeIcon = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; -const refreshIcon = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; -const listItemInstallIcon = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; -const listItemWifi = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; -const listItemConsole = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; -const listItemVisitDevice = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; -const listItemHomeAssistant = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; -const listItemEraseUserData = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; -const listItemFundDevelopment = (0,lit__WEBPACK_IMPORTED_MODULE_0__.svg) ` - - - -`; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/flash.js": -/*!**************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/flash.js ***! - \**************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ flash: () => (/* binding */ flash) -/* harmony export */ }); -/* harmony import */ var esptool_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! esptool-js */ "./node_modules/esptool-js/lib/index.js"); -/* harmony import */ var _util_reset__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/reset */ "./node_modules/esp-web-tools/dist/util/reset.js"); - - -const flash = async (onEvent, port, manifestPath, manifest, eraseFirst) => { - let build; - let chipFamily; - const fireStateEvent = (stateUpdate) => onEvent({ - ...stateUpdate, - manifest, - build, - chipFamily, - }); - const transport = new esptool_js__WEBPACK_IMPORTED_MODULE_0__.Transport(port); - const esploader = new esptool_js__WEBPACK_IMPORTED_MODULE_0__.ESPLoader({ - transport, - baudrate: 115200, - romBaudrate: 115200, - enableTracing: false, - }); - // For debugging - window.esploader = esploader; - fireStateEvent({ - state: "initializing" /* FlashStateType.INITIALIZING */, - message: "Initializing...", - details: { done: false }, - }); - try { - await esploader.main(); - await esploader.flashId(); - } - catch (err) { - console.error(err); - fireStateEvent({ - state: "error" /* FlashStateType.ERROR */, - message: "Failed to initialize. Try resetting your device or holding the BOOT button while clicking INSTALL.", - details: { error: "failed_initialize" /* FlashError.FAILED_INITIALIZING */, details: err }, - }); - await (0,_util_reset__WEBPACK_IMPORTED_MODULE_1__.hardReset)(transport); - await transport.disconnect(); - return; - } - chipFamily = esploader.chip.CHIP_NAME; - fireStateEvent({ - state: "initializing" /* FlashStateType.INITIALIZING */, - message: `Initialized. Found ${chipFamily}`, - details: { done: true }, - }); - build = manifest.builds.find((b) => b.chipFamily === chipFamily); - if (!build) { - fireStateEvent({ - state: "error" /* FlashStateType.ERROR */, - message: `Your ${chipFamily} board is not supported.`, - details: { error: "not_supported" /* FlashError.NOT_SUPPORTED */, details: chipFamily }, - }); - await (0,_util_reset__WEBPACK_IMPORTED_MODULE_1__.hardReset)(transport); - await transport.disconnect(); - return; - } - fireStateEvent({ - state: "preparing" /* FlashStateType.PREPARING */, - message: "Preparing installation...", - details: { done: false }, - }); - const manifestURL = new URL(manifestPath, location.toString()).toString(); - const filePromises = build.parts.map(async (part) => { - const url = new URL(part.path, manifestURL).toString(); - const resp = await fetch(url); - if (!resp.ok) { - throw new Error(`Downlading firmware ${part.path} failed: ${resp.status}`); - } - const reader = new FileReader(); - const blob = await resp.blob(); - return new Promise((resolve) => { - reader.addEventListener("load", () => resolve(reader.result)); - reader.readAsBinaryString(blob); - }); - }); - const fileArray = []; - let totalSize = 0; - for (let part = 0; part < filePromises.length; part++) { - try { - const data = await filePromises[part]; - fileArray.push({ data, address: build.parts[part].offset }); - totalSize += data.length; - } - catch (err) { - fireStateEvent({ - state: "error" /* FlashStateType.ERROR */, - message: err.message, - details: { - error: "failed_firmware_download" /* FlashError.FAILED_FIRMWARE_DOWNLOAD */, - details: err.message, - }, - }); - await (0,_util_reset__WEBPACK_IMPORTED_MODULE_1__.hardReset)(transport); - await transport.disconnect(); - return; - } - } - fireStateEvent({ - state: "preparing" /* FlashStateType.PREPARING */, - message: "Installation prepared", - details: { done: true }, - }); - if (eraseFirst) { - fireStateEvent({ - state: "erasing" /* FlashStateType.ERASING */, - message: "Erasing device...", - details: { done: false }, - }); - await esploader.eraseFlash(); - fireStateEvent({ - state: "erasing" /* FlashStateType.ERASING */, - message: "Device erased", - details: { done: true }, - }); - } - fireStateEvent({ - state: "writing" /* FlashStateType.WRITING */, - message: `Writing progress: 0%`, - details: { - bytesTotal: totalSize, - bytesWritten: 0, - percentage: 0, - }, - }); - let totalWritten = 0; - try { - await esploader.writeFlash({ - fileArray, - flashSize: "keep", - flashMode: "keep", - flashFreq: "keep", - eraseAll: false, - compress: true, - // report progress - reportProgress: (fileIndex, written, total) => { - const uncompressedWritten = (written / total) * fileArray[fileIndex].data.length; - const newPct = Math.floor(((totalWritten + uncompressedWritten) / totalSize) * 100); - // we're done with this file - if (written === total) { - totalWritten += uncompressedWritten; - return; - } - fireStateEvent({ - state: "writing" /* FlashStateType.WRITING */, - message: `Writing progress: ${newPct}%`, - details: { - bytesTotal: totalSize, - bytesWritten: totalWritten + written, - percentage: newPct, - }, - }); - }, - }); - } - catch (err) { - fireStateEvent({ - state: "error" /* FlashStateType.ERROR */, - message: err.message, - details: { error: "write_failed" /* FlashError.WRITE_FAILED */, details: err }, - }); - await (0,_util_reset__WEBPACK_IMPORTED_MODULE_1__.hardReset)(transport); - await transport.disconnect(); - return; - } - fireStateEvent({ - state: "writing" /* FlashStateType.WRITING */, - message: "Writing complete", - details: { - bytesTotal: totalSize, - bytesWritten: totalWritten, - percentage: 100, - }, - }); - await (0,_util_reset__WEBPACK_IMPORTED_MODULE_1__.hardReset)(transport); - console.log("DISCONNECT"); - await transport.disconnect(); - fireStateEvent({ - state: "finished" /* FlashStateType.FINISHED */, - message: "All done!", - }); -}; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/install-dialog.js": -/*!***********************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/install-dialog.js ***! - \***********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ EwtInstallDialog: () => (/* binding */ EwtInstallDialog) -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _components_ew_text_button__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/ew-text-button */ "./node_modules/esp-web-tools/dist/components/ew-text-button.js"); -/* harmony import */ var _components_ew_list__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/ew-list */ "./node_modules/esp-web-tools/dist/components/ew-list.js"); -/* harmony import */ var _components_ew_list_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/ew-list-item */ "./node_modules/esp-web-tools/dist/components/ew-list-item.js"); -/* harmony import */ var _components_ew_divider__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/ew-divider */ "./node_modules/esp-web-tools/dist/components/ew-divider.js"); -/* harmony import */ var _components_ew_checkbox__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/ew-checkbox */ "./node_modules/esp-web-tools/dist/components/ew-checkbox.js"); -/* harmony import */ var _components_ewt_console__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/ewt-console */ "./node_modules/esp-web-tools/dist/components/ewt-console.js"); -/* harmony import */ var _components_ew_dialog__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/ew-dialog */ "./node_modules/esp-web-tools/dist/components/ew-dialog.js"); -/* harmony import */ var _components_ew_icon_button__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/ew-icon-button */ "./node_modules/esp-web-tools/dist/components/ew-icon-button.js"); -/* harmony import */ var _components_ew_filled_text_field__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/ew-filled-text-field */ "./node_modules/esp-web-tools/dist/components/ew-filled-text-field.js"); -/* harmony import */ var _components_ew_filled_select__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/ew-filled-select */ "./node_modules/esp-web-tools/dist/components/ew-filled-select.js"); -/* harmony import */ var _components_ew_select_option__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/ew-select-option */ "./node_modules/esp-web-tools/dist/components/ew-select-option.js"); -/* harmony import */ var _pages_ewt_page_progress__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./pages/ewt-page-progress */ "./node_modules/esp-web-tools/dist/pages/ewt-page-progress.js"); -/* harmony import */ var _pages_ewt_page_message__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./pages/ewt-page-message */ "./node_modules/esp-web-tools/dist/pages/ewt-page-message.js"); -/* harmony import */ var _components_svg__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./components/svg */ "./node_modules/esp-web-tools/dist/components/svg.js"); -/* harmony import */ var improv_wifi_serial_sdk_dist_serial__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! improv-wifi-serial-sdk/dist/serial */ "./node_modules/improv-wifi-serial-sdk/dist/serial.js"); -/* harmony import */ var improv_wifi_serial_sdk_dist_const__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! improv-wifi-serial-sdk/dist/const */ "./node_modules/improv-wifi-serial-sdk/dist/const.js"); -/* harmony import */ var _flash__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./flash */ "./node_modules/esp-web-tools/dist/flash.js"); -/* harmony import */ var _util_file_download__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./util/file-download */ "./node_modules/esp-web-tools/dist/util/file-download.js"); -/* harmony import */ var _util_fire_event__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./util/fire-event */ "./node_modules/esp-web-tools/dist/util/fire-event.js"); -/* harmony import */ var _util_sleep__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./util/sleep */ "./node_modules/esp-web-tools/dist/util/sleep.js"); -/* harmony import */ var _util_manifest__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./util/manifest */ "./node_modules/esp-web-tools/dist/util/manifest.js"); -/* harmony import */ var _styles__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./styles */ "./node_modules/esp-web-tools/dist/styles.js"); -/* harmony import */ var _version__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./version */ "./node_modules/esp-web-tools/dist/version.js"); - - - - - - - - - - - - - - - - - - - - - - - - - - -console.log(`ESP Web Tools ${_version__WEBPACK_IMPORTED_MODULE_24__.version} by Open Home Foundation; https://esphome.github.io/esp-web-tools/`); -const ERROR_ICON = "⚠️"; -const OK_ICON = "🎉"; -class EwtInstallDialog extends lit__WEBPACK_IMPORTED_MODULE_0__.LitElement { - constructor() { - super(...arguments); - this.logger = console; - this._state = "DASHBOARD"; - this._installErase = false; - this._installConfirmed = false; - this._provisionForce = false; - this._wasProvisioned = false; - this._busy = false; - // Name of Ssid. Null = other - this._selectedSsid = null; - this._bodyOverflow = null; - this._handleDisconnect = () => { - this._state = "ERROR"; - this._error = "Disconnected"; - }; - } - render() { - if (!this.port) { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ``; - } - let heading; - let content; - let allowClosing = false; - // During installation phase we temporarily remove the client - if (this._client === undefined && - this._state !== "INSTALL" && - this._state !== "LOGS") { - if (this._error) { - [heading, content] = this._renderError(this._error); - } - else { - content = this._renderProgress("Connecting"); - } - } - else if (this._state === "INSTALL") { - [heading, content, allowClosing] = this._renderInstall(); - } - else if (this._state === "ASK_ERASE") { - [heading, content] = this._renderAskErase(); - } - else if (this._state === "ERROR") { - [heading, content] = this._renderError(this._error); - } - else if (this._state === "DASHBOARD") { - [heading, content, allowClosing] = this._client - ? this._renderDashboard() - : this._renderDashboardNoImprov(); - } - else if (this._state === "PROVISION") { - [heading, content] = this._renderProvision(); - } - else if (this._state === "LOGS") { - [heading, content] = this._renderLogs(); - } - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${heading ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `
    ${heading}
    ` : ""} - ${allowClosing - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.closeIcon} - - ` - : ""} - ${content} -
    - `; - } - _renderProgress(label, progress) { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - `; - } - _renderError(label) { - const heading = "Error"; - const content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - -
    - Close -
    - `; - return [heading, content]; - } - _renderDashboard() { - const heading = this._manifest.name; - let content; - let allowClosing = true; - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - - -
    Connected to ${this._info.name}
    -
    - ${this._info.firmware} ${this._info.version} - (${this._info.chipFamily}) -
    -
    - ${!this._isSameVersion - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - { - if (this._isSameFirmware) { - this._startInstall(false); - } - else if (this._manifest.new_install_prompt_erase) { - this._state = "ASK_ERASE"; - } - else { - this._startInstall(true); - } - }} - > - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemInstallIcon} -
    - ${!this._isSameFirmware - ? `Install ${this._manifest.name}` - : `Update ${this._manifest.name}`} -
    -
    - ` - : ""} - ${this._client.nextUrl === undefined - ? "" - : (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemVisitDevice} -
    Visit Device
    -
    - `} - ${!this._manifest.home_assistant_domain || - this._client.state !== improv_wifi_serial_sdk_dist_const__WEBPACK_IMPORTED_MODULE_17__.ImprovSerialCurrentState.PROVISIONED - ? "" - : (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemHomeAssistant} -
    Add to Home Assistant
    -
    - `} - { - this._state = "PROVISION"; - if (this._client.state === improv_wifi_serial_sdk_dist_const__WEBPACK_IMPORTED_MODULE_17__.ImprovSerialCurrentState.PROVISIONED) { - this._provisionForce = true; - } - }} - > - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemWifi} -
    - ${this._client.state === improv_wifi_serial_sdk_dist_const__WEBPACK_IMPORTED_MODULE_17__.ImprovSerialCurrentState.READY - ? "Connect to Wi-Fi" - : "Change Wi-Fi"} -
    -
    - { - const client = this._client; - if (client) { - await this._closeClientWithoutEvents(client); - await (0,_util_sleep__WEBPACK_IMPORTED_MODULE_21__.sleep)(100); - } - // Also set `null` back to undefined. - this._client = undefined; - this._state = "LOGS"; - }} - > - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemConsole} -
    Logs & Console
    -
    - ${this._isSameFirmware && this._manifest.funding_url - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemFundDevelopment} -
    Fund Development
    -
    - ` - : ""} - ${this._isSameVersion - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - this._startInstall(true)} - > - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemEraseUserData} -
    Erase User Data
    -
    - ` - : ""} -
    -
    - `; - return [heading, content, allowClosing]; - } - _renderDashboardNoImprov() { - const heading = this._manifest.name; - let content; - let allowClosing = true; - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - - { - if (this._manifest.new_install_prompt_erase) { - this._state = "ASK_ERASE"; - } - else { - // Default is to erase a device that does not support Improv Serial - this._startInstall(true); - } - }} - > - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemInstallIcon} -
    ${`Install ${this._manifest.name}`}
    -
    - { - // Also set `null` back to undefined. - this._client = undefined; - this._state = "LOGS"; - }} - > - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemConsole} -
    Logs & Console
    -
    -
    -
    - `; - return [heading, content, allowClosing]; - } - _renderProvision() { - var _a; - let heading = "Configure Wi-Fi"; - let content; - if (this._busy) { - return [ - heading, - this._renderProgress(this._ssids === undefined - ? "Scanning for networks" - : "Trying to connect"), - ]; - } - if (!this._provisionForce && - this._client.state === improv_wifi_serial_sdk_dist_const__WEBPACK_IMPORTED_MODULE_17__.ImprovSerialCurrentState.PROVISIONED) { - heading = undefined; - const showSetupLinks = !this._wasProvisioned && - (this._client.nextUrl !== undefined || - "home_assistant_domain" in this._manifest); - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - - ${showSetupLinks - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${this._client.nextUrl === undefined - ? "" - : (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - { - this._state = "DASHBOARD"; - }} - > - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemVisitDevice} -
    Visit Device
    -
    - `} - ${!this._manifest.home_assistant_domain - ? "" - : (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - { - this._state = "DASHBOARD"; - }} - > - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.listItemHomeAssistant} -
    Add to Home Assistant
    -
    - `} - { - this._state = "DASHBOARD"; - }} - > -
    -
    Skip
    -
    -
    - ` - : ""} -
    - - ${!showSetupLinks - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - { - this._state = "DASHBOARD"; - }} - > - Continue - -
    - ` - : ""} - `; - } - else { - let error; - switch (this._client.error) { - case 3 /* ImprovSerialErrorState.UNABLE_TO_CONNECT */: - error = "Unable to connect"; - break; - case 254 /* ImprovSerialErrorState.TIMEOUT */: - error = "Timeout"; - break; - case 0 /* ImprovSerialErrorState.NO_ERROR */: - // Happens when list SSIDs not supported. - case 2 /* ImprovSerialErrorState.UNKNOWN_RPC_COMMAND */: - break; - default: - error = `Unknown error (${this._client.error})`; - } - const selectedSsid = (_a = this._ssids) === null || _a === void 0 ? void 0 : _a.find((info) => info.name === this._selectedSsid); - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${_components_svg__WEBPACK_IMPORTED_MODULE_15__.refreshIcon} - -
    -
    Connect your device to the network to start using it.
    - ${error ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `

    ${error}

    ` : ""} - ${this._ssids !== null - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - { - const index = ev.target.selectedIndex; - // The "Join Other" item is always the last item. - this._selectedSsid = - index === this._ssids.length - ? null - : this._ssids[index].name; - }} - > - ${this._ssids.map((info) => (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ${info.name} - - `)} - - - Join other… - - - ` - : ""} - ${ - // Show input box if command not supported or "Join Other" selected - !selectedSsid - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ` - : ""} - ${!selectedSsid || selectedSsid.secured - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - ` - : ""} -
    -
    - { - this._state = "DASHBOARD"; - }} - > - ${this._installState && this._installErase ? "Skip" : "Back"} - - Connect -
    - `; - } - return [heading, content]; - } - _renderAskErase() { - const heading = "Erase device"; - const content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    -
    - Do you want to erase the device before installing - ${this._manifest.name}? All data on the device will be lost. -
    - -
    -
    - { - this._state = "DASHBOARD"; - }} - > - Back - - { - const checkbox = this.shadowRoot.querySelector("ew-checkbox"); - this._startInstall(checkbox.checked); - }} - > - Next - -
    - `; - return [heading, content]; - } - _renderInstall() { - let heading; - let content; - const allowClosing = false; - const isUpdate = !this._installErase && this._isSameFirmware; - if (!this._installConfirmed && this._isSameVersion) { - heading = "Erase User Data"; - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - Do you want to reset your device and erase all user data from your - device? -
    -
    - - Erase User Data - -
    - `; - } - else if (!this._installConfirmed) { - heading = "Confirm Installation"; - const action = isUpdate ? "update to" : "install"; - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - ${isUpdate - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `Your device is running - ${this._info.firmware} ${this._info.version}.

    ` - : ""} - Do you want to ${action} - ${this._manifest.name} ${this._manifest.version}? - ${this._installErase - ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `

    All data on the device will be erased.` - : ""} -
    -
    - { - this._state = "DASHBOARD"; - }} - > - Back - - - Install - -
    - `; - } - else if (!this._installState || - this._installState.state === "initializing" /* FlashStateType.INITIALIZING */ || - this._installState.state === "preparing" /* FlashStateType.PREPARING */) { - heading = "Installing"; - content = this._renderProgress("Preparing installation"); - } - else if (this._installState.state === "erasing" /* FlashStateType.ERASING */) { - heading = "Installing"; - content = this._renderProgress("Erasing"); - } - else if (this._installState.state === "writing" /* FlashStateType.WRITING */ || - // When we're finished, keep showing this screen with 100% written - // until Improv is initialized / not detected. - (this._installState.state === "finished" /* FlashStateType.FINISHED */ && - this._client === undefined)) { - heading = "Installing"; - let percentage; - let undeterminateLabel; - if (this._installState.state === "finished" /* FlashStateType.FINISHED */) { - // We're done writing and detecting improv, show spinner - undeterminateLabel = "Wrapping up"; - } - else if (this._installState.details.percentage < 4) { - // We're writing the firmware under 4%, show spinner or else we don't show any pixels - undeterminateLabel = "Installing"; - } - else { - // We're writing the firmware over 4%, show progress bar - percentage = this._installState.details.percentage; - } - content = this._renderProgress((0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - ${undeterminateLabel ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `${undeterminateLabel}
    ` : ""} -
    - This will take - ${this._installState.chipFamily === "ESP8266" - ? "a minute" - : "2 minutes"}.
    - Keep this page visible to prevent slow down - `, percentage); - } - else if (this._installState.state === "finished" /* FlashStateType.FINISHED */) { - heading = undefined; - const supportsImprov = this._client !== null; - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - - -
    - { - this._state = - supportsImprov && this._installErase - ? "PROVISION" - : "DASHBOARD"; - }} - > - Next - -
    - `; - } - else if (this._installState.state === "error" /* FlashStateType.ERROR */) { - heading = "Installation failed"; - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` - -
    - { - this._initialize(); - this._state = "DASHBOARD"; - }} - > - Back - -
    - `; - } - return [heading, content, allowClosing]; - } - _renderLogs() { - let heading = `Logs`; - let content; - content = (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - -
    -
    - { - await this.shadowRoot.querySelector("ewt-console").reset(); - }} - > - Reset Device - - { - (0,_util_file_download__WEBPACK_IMPORTED_MODULE_19__.textDownload)(this.shadowRoot.querySelector("ewt-console").logs(), `esp-web-tools-logs.txt`); - this.shadowRoot.querySelector("ewt-console").reset(); - }} - > - Download Logs - - { - await this.shadowRoot.querySelector("ewt-console").disconnect(); - this._state = "DASHBOARD"; - this._initialize(); - }} - > - Back - -
    - `; - return [heading, content]; - } - willUpdate(changedProps) { - if (!changedProps.has("_state")) { - return; - } - // Clear errors when changing between pages unless we change - // to the error page. - if (this._state !== "ERROR") { - this._error = undefined; - } - // Scan for SSIDs on provision - if (this._state === "PROVISION") { - this._updateSsids(); - } - else { - // Reset this value if we leave provisioning. - this._provisionForce = false; - } - if (this._state === "INSTALL") { - this._installConfirmed = false; - this._installState = undefined; - } - } - async _updateSsids(tries = 0) { - const oldSsids = this._ssids; - this._ssids = undefined; - this._busy = true; - let ssids; - try { - ssids = await this._client.scan(); - } - catch (err) { - // When we fail while loading, pick "Join other" - if (this._ssids === undefined) { - this._ssids = null; - this._selectedSsid = null; - } - this._busy = false; - return; - } - // We will retry a few times if we don't get any results - if (ssids.length === 0 && tries < 3) { - console.log("SCHEDULE RETRY", tries); - setTimeout(() => this._updateSsids(tries + 1), 1000); - return; - } - if (oldSsids) { - // If we had a previous list, ensure the selection is still valid - if (this._selectedSsid && - !ssids.find((s) => s.name === this._selectedSsid)) { - this._selectedSsid = ssids[0].name; - } - } - else { - this._selectedSsid = ssids.length ? ssids[0].name : null; - } - this._ssids = ssids; - this._busy = false; - } - firstUpdated(changedProps) { - super.firstUpdated(changedProps); - this._bodyOverflow = document.body.style.overflow; - document.body.style.overflow = "hidden"; - this._initialize(); - } - updated(changedProps) { - super.updated(changedProps); - if (changedProps.has("_state")) { - this.setAttribute("state", this._state); - } - if (this._state !== "PROVISION") { - return; - } - if (changedProps.has("_selectedSsid") && this._selectedSsid === null) { - // If we pick "Join other", select SSID input. - this._focusFormElement("ew-filled-text-field[name=ssid]"); - } - else if (changedProps.has("_ssids")) { - // Form is shown when SSIDs are loaded/marked not supported - this._focusFormElement(); - } - } - _focusFormElement(selector = "ew-filled-text-field, ew-filled-select") { - const formEl = this.shadowRoot.querySelector(selector); - if (formEl) { - formEl.updateComplete.then(() => setTimeout(() => formEl.focus(), 100)); - } - } - async _initialize(justInstalled = false) { - if (this.port.readable === null || this.port.writable === null) { - this._state = "ERROR"; - this._error = - "Serial port is not readable/writable. Close any other application using it and try again."; - return; - } - try { - this._manifest = await (0,_util_manifest__WEBPACK_IMPORTED_MODULE_22__.downloadManifest)(this.manifestPath); - } - catch (err) { - this._state = "ERROR"; - this._error = "Failed to download manifest"; - return; - } - if (this._manifest.new_install_improv_wait_time === 0) { - this._client = null; - return; - } - const client = new improv_wifi_serial_sdk_dist_serial__WEBPACK_IMPORTED_MODULE_16__.ImprovSerial(this.port, this.logger); - client.addEventListener("state-changed", () => { - this.requestUpdate(); - }); - client.addEventListener("error-changed", () => this.requestUpdate()); - try { - // If a device was just installed, give new firmware 10 seconds (overridable) to - // format the rest of the flash and do other stuff. - const timeout = !justInstalled - ? 1000 - : this._manifest.new_install_improv_wait_time !== undefined - ? this._manifest.new_install_improv_wait_time * 1000 - : 10000; - this._info = await client.initialize(timeout); - this._client = client; - client.addEventListener("disconnect", this._handleDisconnect); - } - catch (err) { - // Clear old value - this._info = undefined; - if (err instanceof improv_wifi_serial_sdk_dist_const__WEBPACK_IMPORTED_MODULE_17__.PortNotReady) { - this._state = "ERROR"; - this._error = - "Serial port is not ready. Close any other application using it and try again."; - } - else { - this._client = null; // not supported - this.logger.error("Improv initialization failed.", err); - } - } - } - _startInstall(erase) { - this._state = "INSTALL"; - this._installErase = erase; - this._installConfirmed = false; - } - async _confirmInstall() { - this._installConfirmed = true; - this._installState = undefined; - if (this._client) { - await this._closeClientWithoutEvents(this._client); - } - this._client = undefined; - // Close port. ESPLoader likes opening it. - await this.port.close(); - (0,_flash__WEBPACK_IMPORTED_MODULE_18__.flash)((state) => { - this._installState = state; - if (state.state === "finished" /* FlashStateType.FINISHED */) { - (0,_util_sleep__WEBPACK_IMPORTED_MODULE_21__.sleep)(100) - // Flashing closes the port - .then(() => this.port.open({ baudRate: 115200, bufferSize: 8192 })) - .then(() => this._initialize(true)) - .then(() => this.requestUpdate()); - } - else if (state.state === "error" /* FlashStateType.ERROR */) { - (0,_util_sleep__WEBPACK_IMPORTED_MODULE_21__.sleep)(100) - // Flashing closes the port - .then(() => this.port.open({ baudRate: 115200, bufferSize: 8192 })); - } - }, this.port, this.manifestPath, this._manifest, this._installErase); - } - async _doProvision() { - var _a; - this._busy = true; - this._wasProvisioned = - this._client.state === improv_wifi_serial_sdk_dist_const__WEBPACK_IMPORTED_MODULE_17__.ImprovSerialCurrentState.PROVISIONED; - const ssid = this._selectedSsid === null - ? this.shadowRoot.querySelector("ew-filled-text-field[name=ssid]").value - : this._selectedSsid; - const password = ((_a = this.shadowRoot.querySelector("ew-filled-text-field[name=password]")) === null || _a === void 0 ? void 0 : _a.value) || ""; - try { - await this._client.provision(ssid, password, 30000); - } - catch (err) { - return; - } - finally { - this._busy = false; - this._provisionForce = false; - } - } - _closeDialog() { - this.shadowRoot.querySelector("ew-dialog").close(); - } - async _handleClose() { - if (this._client) { - await this._closeClientWithoutEvents(this._client); - } - (0,_util_fire_event__WEBPACK_IMPORTED_MODULE_20__.fireEvent)(this, "closed"); - document.body.style.overflow = this._bodyOverflow; - this.parentNode.removeChild(this); - } - /** - * Return if the device runs same firmware as manifest. - */ - get _isSameFirmware() { - var _a; - return !this._info - ? false - : ((_a = this.overrides) === null || _a === void 0 ? void 0 : _a.checkSameFirmware) - ? this.overrides.checkSameFirmware(this._manifest, this._info) - : this._info.firmware === this._manifest.name; - } - /** - * Return if the device runs same firmware and version as manifest. - */ - get _isSameVersion() { - return (this._isSameFirmware && this._info.version === this._manifest.version); - } - async _closeClientWithoutEvents(client) { - client.removeEventListener("disconnect", this._handleDisconnect); - await client.close(); - } - _preventDefault(ev) { - ev.preventDefault(); - } -} -EwtInstallDialog.styles = [ - _styles__WEBPACK_IMPORTED_MODULE_23__.dialogStyles, - (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) ` - :host { - --mdc-dialog-max-width: 390px; - } - div[slot="headline"] { - padding-right: 48px; - } - ew-icon-button[slot="headline"] { - position: absolute; - right: 4px; - top: 8px; - } - ew-icon-button[slot="headline"] svg { - padding: 8px; - color: var(--text-color); - } - .dialog-nav svg { - color: var(--text-color); - } - .table-row { - display: flex; - } - .table-row.last { - margin-bottom: 16px; - } - .table-row svg { - width: 20px; - margin-right: 8px; - } - ew-filled-text-field, - ew-filled-select { - display: block; - margin-top: 16px; - } - label.formfield { - display: inline-flex; - align-items: center; - padding-right: 8px; - } - ew-list { - margin: 0 -24px; - padding: 0; - } - ew-list-item svg { - height: 24px; - } - ewt-page-message + ew-list { - padding-top: 16px; - } - .fake-icon { - width: 24px; - } - .error { - color: var(--danger-color); - } - .danger { - --mdc-theme-primary: var(--danger-color); - --mdc-theme-secondary: var(--danger-color); - --md-sys-color-primary: var(--danger-color); - --md-sys-color-on-surface: var(--danger-color); - } - button.link { - background: none; - color: inherit; - border: none; - padding: 0; - font: inherit; - text-align: left; - text-decoration: underline; - cursor: pointer; - } - :host([state="LOGS"]) ew-dialog { - max-width: 90vw; - max-height: 90vh; - } - ewt-console { - width: calc(80vw - 48px); - height: calc(90vh - 168px); - } - `, -]; -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_client", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_state", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_installErase", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_installConfirmed", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_installState", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_provisionForce", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_error", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_busy", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_ssids", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_25__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.state)() -], EwtInstallDialog.prototype, "_selectedSsid", void 0); -customElements.define("ewt-install-dialog", EwtInstallDialog); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/pages/ewt-page-message.js": -/*!*******************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/pages/ewt-page-message.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); - - - -class EwtPageMessage extends lit__WEBPACK_IMPORTED_MODULE_0__.LitElement { - render() { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    ${this.icon}
    - ${this.label} - `; - } -} -EwtPageMessage.styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) ` - :host { - display: flex; - flex-direction: column; - text-align: center; - } - .icon { - font-size: 50px; - line-height: 80px; - color: black; - } - `; -(0,tslib__WEBPACK_IMPORTED_MODULE_2__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], EwtPageMessage.prototype, "icon", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_2__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], EwtPageMessage.prototype, "label", void 0); -customElements.define("ewt-page-message", EwtPageMessage); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/pages/ewt-page-progress.js": -/*!********************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/pages/ewt-page-progress.js ***! - \********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs"); -/* harmony import */ var lit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit */ "./node_modules/lit/index.js"); -/* harmony import */ var lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lit/decorators.js */ "./node_modules/lit/decorators.js"); -/* harmony import */ var _components_ew_circular_progress__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/ew-circular-progress */ "./node_modules/esp-web-tools/dist/components/ew-circular-progress.js"); - - - - -class EwtPageProgress extends lit__WEBPACK_IMPORTED_MODULE_0__.LitElement { - render() { - return (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) ` -
    - - ${this.progress !== undefined ? (0,lit__WEBPACK_IMPORTED_MODULE_0__.html) `
    ${this.progress}%
    ` : ""} -
    - ${this.label} - `; - } -} -EwtPageProgress.styles = (0,lit__WEBPACK_IMPORTED_MODULE_0__.css) ` - :host { - display: flex; - flex-direction: column; - text-align: center; - } - ew-circular-progress { - margin-bottom: 16px; - } - `; -(0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], EwtPageProgress.prototype, "label", void 0); -(0,tslib__WEBPACK_IMPORTED_MODULE_3__.__decorate)([ - (0,lit_decorators_js__WEBPACK_IMPORTED_MODULE_1__.property)() -], EwtPageProgress.prototype, "progress", void 0); -customElements.define("ewt-page-progress", EwtPageProgress); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/console-color.js": -/*!***************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/console-color.js ***! - \***************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ColoredConsole: () => (/* binding */ ColoredConsole), -/* harmony export */ coloredConsoleStyles: () => (/* binding */ coloredConsoleStyles) -/* harmony export */ }); -class ColoredConsole { - constructor(targetElement) { - this.targetElement = targetElement; - this.state = { - bold: false, - italic: false, - underline: false, - strikethrough: false, - foregroundColor: null, - backgroundColor: null, - carriageReturn: false, - lines: [], - secret: false, - }; - } - logs() { - return this.targetElement.innerText; - } - processLine(line) { - // @ts-expect-error - const re = /(?:\033|\\033)(?:\[(.*?)[@-~]|\].*?(?:\007|\033\\))/g; - let i = 0; - const lineSpan = document.createElement("span"); - lineSpan.classList.add("line"); - const addSpan = (content) => { - if (content === "") - return; - const span = document.createElement("span"); - if (this.state.bold) - span.classList.add("log-bold"); - if (this.state.italic) - span.classList.add("log-italic"); - if (this.state.underline) - span.classList.add("log-underline"); - if (this.state.strikethrough) - span.classList.add("log-strikethrough"); - if (this.state.secret) - span.classList.add("log-secret"); - if (this.state.foregroundColor !== null) - span.classList.add(`log-fg-${this.state.foregroundColor}`); - if (this.state.backgroundColor !== null) - span.classList.add(`log-bg-${this.state.backgroundColor}`); - span.appendChild(document.createTextNode(content)); - lineSpan.appendChild(span); - if (this.state.secret) { - const redacted = document.createElement("span"); - redacted.classList.add("log-secret-redacted"); - redacted.appendChild(document.createTextNode("[redacted]")); - lineSpan.appendChild(redacted); - } - }; - while (true) { - const match = re.exec(line); - if (match === null) - break; - const j = match.index; - addSpan(line.substring(i, j)); - i = j + match[0].length; - if (match[1] === undefined) - continue; - for (const colorCode of match[1].split(";")) { - switch (parseInt(colorCode)) { - case 0: - // reset - this.state.bold = false; - this.state.italic = false; - this.state.underline = false; - this.state.strikethrough = false; - this.state.foregroundColor = null; - this.state.backgroundColor = null; - this.state.secret = false; - break; - case 1: - this.state.bold = true; - break; - case 3: - this.state.italic = true; - break; - case 4: - this.state.underline = true; - break; - case 5: - this.state.secret = true; - break; - case 6: - this.state.secret = false; - break; - case 9: - this.state.strikethrough = true; - break; - case 22: - this.state.bold = false; - break; - case 23: - this.state.italic = false; - break; - case 24: - this.state.underline = false; - break; - case 29: - this.state.strikethrough = false; - break; - case 30: - this.state.foregroundColor = "black"; - break; - case 31: - this.state.foregroundColor = "red"; - break; - case 32: - this.state.foregroundColor = "green"; - break; - case 33: - this.state.foregroundColor = "yellow"; - break; - case 34: - this.state.foregroundColor = "blue"; - break; - case 35: - this.state.foregroundColor = "magenta"; - break; - case 36: - this.state.foregroundColor = "cyan"; - break; - case 37: - this.state.foregroundColor = "white"; - break; - case 39: - this.state.foregroundColor = null; - break; - case 41: - this.state.backgroundColor = "red"; - break; - case 42: - this.state.backgroundColor = "green"; - break; - case 43: - this.state.backgroundColor = "yellow"; - break; - case 44: - this.state.backgroundColor = "blue"; - break; - case 45: - this.state.backgroundColor = "magenta"; - break; - case 46: - this.state.backgroundColor = "cyan"; - break; - case 47: - this.state.backgroundColor = "white"; - break; - case 40: - case 49: - this.state.backgroundColor = null; - break; - } - } - } - addSpan(line.substring(i)); - return lineSpan; - } - processLines() { - const atBottom = this.targetElement.scrollTop > - this.targetElement.scrollHeight - this.targetElement.offsetHeight - 50; - const prevCarriageReturn = this.state.carriageReturn; - const fragment = document.createDocumentFragment(); - if (this.state.lines.length == 0) { - return; - } - for (const line of this.state.lines) { - if (this.state.carriageReturn && line !== "\n") { - if (fragment.childElementCount) { - fragment.removeChild(fragment.lastChild); - } - } - fragment.appendChild(this.processLine(line)); - this.state.carriageReturn = line.includes("\r"); - } - if (prevCarriageReturn && this.state.lines[0] !== "\n") { - this.targetElement.replaceChild(fragment, this.targetElement.lastChild); - } - else { - this.targetElement.appendChild(fragment); - } - this.state.lines = []; - // Keep scroll at bottom - if (atBottom) { - this.targetElement.scrollTop = this.targetElement.scrollHeight; - } - } - addLine(line) { - // Processing of lines is deferred for performance reasons - if (this.state.lines.length == 0) { - setTimeout(() => this.processLines(), 0); - } - this.state.lines.push(line); - } -} -const coloredConsoleStyles = ` - .log { - flex: 1; - background-color: #1c1c1c; - font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, - monospace; - font-size: 12px; - padding: 16px; - overflow: auto; - line-height: 1.45; - border-radius: 3px; - white-space: pre-wrap; - overflow-wrap: break-word; - color: #ddd; - } - - .log-bold { - font-weight: bold; - } - .log-italic { - font-style: italic; - } - .log-underline { - text-decoration: underline; - } - .log-strikethrough { - text-decoration: line-through; - } - .log-underline.log-strikethrough { - text-decoration: underline line-through; - } - .log-secret { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - } - .log-secret-redacted { - opacity: 0; - width: 1px; - font-size: 1px; - } - .log-fg-black { - color: rgb(128, 128, 128); - } - .log-fg-red { - color: rgb(255, 0, 0); - } - .log-fg-green { - color: rgb(0, 255, 0); - } - .log-fg-yellow { - color: rgb(255, 255, 0); - } - .log-fg-blue { - color: rgb(0, 0, 255); - } - .log-fg-magenta { - color: rgb(255, 0, 255); - } - .log-fg-cyan { - color: rgb(0, 255, 255); - } - .log-fg-white { - color: rgb(187, 187, 187); - } - .log-bg-black { - background-color: rgb(0, 0, 0); - } - .log-bg-red { - background-color: rgb(255, 0, 0); - } - .log-bg-green { - background-color: rgb(0, 255, 0); - } - .log-bg-yellow { - background-color: rgb(255, 255, 0); - } - .log-bg-blue { - background-color: rgb(0, 0, 255); - } - .log-bg-magenta { - background-color: rgb(255, 0, 255); - } - .log-bg-cyan { - background-color: rgb(0, 255, 255); - } - .log-bg-white { - background-color: rgb(255, 255, 255); - } -`; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/file-download.js": -/*!***************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/file-download.js ***! - \***************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ fileDownload: () => (/* binding */ fileDownload), -/* harmony export */ textDownload: () => (/* binding */ textDownload) -/* harmony export */ }); -const fileDownload = (href, filename = "") => { - const a = document.createElement("a"); - a.target = "_blank"; - a.href = href; - a.download = filename; - document.body.appendChild(a); - a.dispatchEvent(new MouseEvent("click")); - document.body.removeChild(a); -}; -const textDownload = (text, filename = "") => { - const blob = new Blob([text], { type: "text/plain" }); - const url = URL.createObjectURL(blob); - fileDownload(url, filename); - setTimeout(() => URL.revokeObjectURL(url), 0); -}; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/fire-event.js": -/*!************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/fire-event.js ***! - \************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ fireEvent: () => (/* binding */ fireEvent) -/* harmony export */ }); -const fireEvent = (eventTarget, type, -// @ts-ignore -detail, options) => { - options = options || {}; - const event = new CustomEvent(type, { - bubbles: options.bubbles === undefined ? true : options.bubbles, - cancelable: Boolean(options.cancelable), - composed: options.composed === undefined ? true : options.composed, - detail, - }); - eventTarget.dispatchEvent(event); -}; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/line-break-transformer.js": -/*!************************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/line-break-transformer.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ LineBreakTransformer: () => (/* binding */ LineBreakTransformer) -/* harmony export */ }); -class LineBreakTransformer { - constructor() { - this.chunks = ""; - } - transform(chunk, controller) { - // Append new chunks to existing chunks. - this.chunks += chunk; - // For each line breaks in chunks, send the parsed lines out. - const lines = this.chunks.split(/\r?\n/); - this.chunks = lines.pop(); - lines.forEach((line) => controller.enqueue(line + "\r\n")); - } - flush(controller) { - // When the stream is closed, flush any remaining chunks out. - controller.enqueue(this.chunks); - } -} - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/manifest.js": -/*!**********************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/manifest.js ***! - \**********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ downloadManifest: () => (/* binding */ downloadManifest) -/* harmony export */ }); -const downloadManifest = async (manifestPath) => { - const manifestURL = new URL(manifestPath, location.toString()).toString(); - const resp = await fetch(manifestURL); - const manifest = await resp.json(); - if ("new_install_skip_erase" in manifest) { - console.warn('Manifest option "new_install_skip_erase" is deprecated. Use "new_install_prompt_erase" instead.'); - if (manifest.new_install_skip_erase) { - manifest.new_install_prompt_erase = true; - } - } - return manifest; -}; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/reset.js": -/*!*******************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/reset.js ***! - \*******************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ hardReset: () => (/* binding */ hardReset) -/* harmony export */ }); -/* harmony import */ var _sleep__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sleep */ "./node_modules/esp-web-tools/dist/util/sleep.js"); - -const hardReset = async (transport) => { - console.log("Triggering reset"); - await transport.device.setSignals({ - dataTerminalReady: false, - requestToSend: true, - }); - await (0,_sleep__WEBPACK_IMPORTED_MODULE_0__.sleep)(250); - await transport.device.setSignals({ - dataTerminalReady: false, - requestToSend: false, - }); - await (0,_sleep__WEBPACK_IMPORTED_MODULE_0__.sleep)(250); - await new Promise((resolve) => setTimeout(resolve, 1000)); -}; - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/sleep.js": -/*!*******************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/sleep.js ***! - \*******************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ sleep: () => (/* binding */ sleep) -/* harmony export */ }); -const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time)); - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/util/timestamp-transformer.js": -/*!***********************************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/util/timestamp-transformer.js ***! - \***********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ TimestampTransformer: () => (/* binding */ TimestampTransformer) -/* harmony export */ }); -class TimestampTransformer { - transform(chunk, controller) { - const date = new Date(); - const h = date.getHours().toString().padStart(2, "0"); - const m = date.getMinutes().toString().padStart(2, "0"); - const s = date.getSeconds().toString().padStart(2, "0"); - controller.enqueue(`[${h}:${m}:${s}]${chunk}`); - } -} - - -/***/ }), - -/***/ "./node_modules/esp-web-tools/dist/version.js": -/*!****************************************************!*\ - !*** ./node_modules/esp-web-tools/dist/version.js ***! - \****************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ version: () => (/* binding */ version) -/* harmony export */ }); -const version = "10.1.1"; - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/esploader.js": -/*!**************************************************!*\ - !*** ./node_modules/esptool-js/lib/esploader.js ***! - \**************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESPLoader: () => (/* binding */ ESPLoader) -/* harmony export */ }); -/* harmony import */ var _types_error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./types/error.js */ "./node_modules/esptool-js/lib/types/error.js"); -/* harmony import */ var pako__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pako */ "./node_modules/pako/dist/pako.esm.mjs"); -/* harmony import */ var _webserial_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webserial.js */ "./node_modules/esptool-js/lib/webserial.js"); -/* harmony import */ var _reset_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./reset.js */ "./node_modules/esptool-js/lib/reset.js"); -/* harmony import */ var _stubFlasher_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./stubFlasher.js */ "./node_modules/esptool-js/lib/stubFlasher.js"); -/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util.js */ "./node_modules/esptool-js/lib/util.js"); - - - - - - -/** - * Return the chip ROM based on the given magic number - * @param {number} magic - magic hex number to select ROM. - * @returns {ROM} The chip ROM class related to given magic hex number. - */ -async function magic2Chip(magic) { - switch (magic) { - case 0x00f01d83: { - const { ESP32ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32.js */ "./node_modules/esptool-js/lib/targets/esp32.js")); - return new ESP32ROM(); - } - case 0xc21e06f: - case 0x6f51306f: - case 0x7c41a06f: { - const { ESP32C2ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32c2_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32c2.js */ "./node_modules/esptool-js/lib/targets/esp32c2.js")); - return new ESP32C2ROM(); - } - case 0x6921506f: - case 0x1b31506f: - case 0x4881606f: - case 0x4361606f: { - const { ESP32C3ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32c3_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32c3.js */ "./node_modules/esptool-js/lib/targets/esp32c3.js")); - return new ESP32C3ROM(); - } - case 0x2ce0806f: { - const { ESP32C6ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32c6_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32c6.js */ "./node_modules/esptool-js/lib/targets/esp32c6.js")); - return new ESP32C6ROM(); - } - case 0x2421606f: - case 0x33f0206f: - case 0x4f81606f: { - const { ESP32C61ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32c61_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32c61.js */ "./node_modules/esptool-js/lib/targets/esp32c61.js")); - return new ESP32C61ROM(); - } - case 0x1101406f: - case 0x63e1406f: - case 0x5fd1406f: { - const { ESP32C5ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32c5_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32c5.js */ "./node_modules/esptool-js/lib/targets/esp32c5.js")); - return new ESP32C5ROM(); - } - case 0xd7b73e80: { - const { ESP32H2ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32h2_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32h2.js */ "./node_modules/esptool-js/lib/targets/esp32h2.js")); - return new ESP32H2ROM(); - } - case 0x09: { - const { ESP32S3ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32s3_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32s3.js */ "./node_modules/esptool-js/lib/targets/esp32s3.js")); - return new ESP32S3ROM(); - } - case 0x000007c6: { - const { ESP32S2ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp32s2_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32s2.js */ "./node_modules/esptool-js/lib/targets/esp32s2.js")); - return new ESP32S2ROM(); - } - case 0xfff0c101: { - const { ESP8266ROM } = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_esp8266_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp8266.js */ "./node_modules/esptool-js/lib/targets/esp8266.js")); - return new ESP8266ROM(); - } - case 0x0: - case 0x0addbad0: - case 0x7039ad9: { - const { ESP32P4ROM } = await __webpack_require__.e(/*! import() */ "vendors-node_modules_esptool-js_lib_targets_esp32p4_js").then(__webpack_require__.bind(__webpack_require__, /*! ./targets/esp32p4.js */ "./node_modules/esptool-js/lib/targets/esp32p4.js")); - return new ESP32P4ROM(); - } - default: - return null; - } -} -class ESPLoader { - /** - * Create a new ESPLoader to perform serial communication - * such as read/write flash memory and registers using a LoaderOptions object. - * @param {LoaderOptions} options - LoaderOptions object argument for ESPLoader. - * ``` - * const myLoader = new ESPLoader({ transport: Transport, baudrate: number, terminal?: IEspLoaderTerminal }); - * ``` - */ - constructor(options) { - var _a, _b, _c, _d, _e, _f, _g, _h; - this.ESP_RAM_BLOCK = 0x1800; - this.ESP_FLASH_BEGIN = 0x02; - this.ESP_FLASH_DATA = 0x03; - this.ESP_FLASH_END = 0x04; - this.ESP_MEM_BEGIN = 0x05; - this.ESP_MEM_END = 0x06; - this.ESP_MEM_DATA = 0x07; - this.ESP_WRITE_REG = 0x09; - this.ESP_READ_REG = 0x0a; - this.ESP_SPI_ATTACH = 0x0d; - this.ESP_CHANGE_BAUDRATE = 0x0f; - this.ESP_FLASH_DEFL_BEGIN = 0x10; - this.ESP_FLASH_DEFL_DATA = 0x11; - this.ESP_FLASH_DEFL_END = 0x12; - this.ESP_SPI_FLASH_MD5 = 0x13; - // Only Stub supported commands - this.ESP_ERASE_FLASH = 0xd0; - this.ESP_ERASE_REGION = 0xd1; - this.ESP_READ_FLASH = 0xd2; - this.ESP_RUN_USER_CODE = 0xd3; - this.ESP_IMAGE_MAGIC = 0xe9; - this.ESP_CHECKSUM_MAGIC = 0xef; - // Response code(s) sent by ROM - this.ROM_INVALID_RECV_MSG = 0x05; // response if an invalid message is received - this.DEFAULT_TIMEOUT = 3000; - this.ERASE_REGION_TIMEOUT_PER_MB = 30000; - this.ERASE_WRITE_TIMEOUT_PER_MB = 40000; - this.MD5_TIMEOUT_PER_MB = 8000; - this.CHIP_ERASE_TIMEOUT = 120000; - this.FLASH_READ_TIMEOUT = 100000; - this.MAX_TIMEOUT = this.CHIP_ERASE_TIMEOUT * 2; - this.CHIP_DETECT_MAGIC_REG_ADDR = 0x40001000; - this.DETECTED_FLASH_SIZES = { - 0x12: "256KB", - 0x13: "512KB", - 0x14: "1MB", - 0x15: "2MB", - 0x16: "4MB", - 0x17: "8MB", - 0x18: "16MB", - }; - this.DETECTED_FLASH_SIZES_NUM = { - 0x12: 256, - 0x13: 512, - 0x14: 1024, - 0x15: 2048, - 0x16: 4096, - 0x17: 8192, - 0x18: 16384, - }; - this.USB_JTAG_SERIAL_PID = 0x1001; - this.romBaudrate = 115200; - this.debugLogging = false; - this.syncStubDetected = false; - /** - * Get flash size bytes from flash size string. - * @param {string} flashSize Flash Size string - * @returns {number} Flash size bytes - */ - this.flashSizeBytes = function (flashSize) { - let flashSizeB = -1; - if (flashSize.indexOf("KB") !== -1) { - flashSizeB = parseInt(flashSize.slice(0, flashSize.indexOf("KB"))) * 1024; - } - else if (flashSize.indexOf("MB") !== -1) { - flashSizeB = parseInt(flashSize.slice(0, flashSize.indexOf("MB"))) * 1024 * 1024; - } - return flashSizeB; - }; - this.IS_STUB = false; - this.FLASH_WRITE_SIZE = 0x4000; - this.transport = options.transport; - this.baudrate = options.baudrate; - this.resetConstructors = { - classicReset: (transport, resetDelay) => new _reset_js__WEBPACK_IMPORTED_MODULE_3__.ClassicReset(transport, resetDelay), - customReset: (transport, sequenceString) => new _reset_js__WEBPACK_IMPORTED_MODULE_3__.CustomReset(transport, sequenceString), - hardReset: (transport, usingUsbOtg) => new _reset_js__WEBPACK_IMPORTED_MODULE_3__.HardReset(transport, usingUsbOtg), - usbJTAGSerialReset: (transport) => new _reset_js__WEBPACK_IMPORTED_MODULE_3__.UsbJtagSerialReset(transport), - }; - if (options.serialOptions) { - this.serialOptions = options.serialOptions; - } - if (options.romBaudrate) { - this.romBaudrate = options.romBaudrate; - } - if (options.terminal) { - this.terminal = options.terminal; - this.terminal.clean(); - } - if (typeof options.debugLogging !== "undefined") { - this.debugLogging = options.debugLogging; - } - if (options.port) { - this.transport = new _webserial_js__WEBPACK_IMPORTED_MODULE_2__.Transport(options.port); - } - if (typeof options.enableTracing !== "undefined") { - this.transport.tracing = options.enableTracing; - } - if ((_a = options.resetConstructors) === null || _a === void 0 ? void 0 : _a.classicReset) { - this.resetConstructors.classicReset = (_b = options.resetConstructors) === null || _b === void 0 ? void 0 : _b.classicReset; - } - if ((_c = options.resetConstructors) === null || _c === void 0 ? void 0 : _c.customReset) { - this.resetConstructors.customReset = (_d = options.resetConstructors) === null || _d === void 0 ? void 0 : _d.customReset; - } - if ((_e = options.resetConstructors) === null || _e === void 0 ? void 0 : _e.hardReset) { - this.resetConstructors.hardReset = (_f = options.resetConstructors) === null || _f === void 0 ? void 0 : _f.hardReset; - } - if ((_g = options.resetConstructors) === null || _g === void 0 ? void 0 : _g.usbJTAGSerialReset) { - this.resetConstructors.usbJTAGSerialReset = (_h = options.resetConstructors) === null || _h === void 0 ? void 0 : _h.usbJTAGSerialReset; - } - this.info("esptool.js"); - this.info("Serial port " + this.transport.getInfo()); - } - _sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); - } - /** - * Write to ESP Loader constructor's terminal with or without new line. - * @param {string} str - String to write. - * @param {boolean} withNewline - Add new line at the end ? - */ - write(str, withNewline = true) { - if (this.terminal) { - if (withNewline) { - this.terminal.writeLine(str); - } - else { - this.terminal.write(str); - } - } - else { - // eslint-disable-next-line no-console - console.log(str); - } - } - /** - * Write error message to ESP Loader constructor's terminal with or without new line. - * @param {string} str - String to write. - * @param {boolean} withNewline - Add new line at the end ? - */ - error(str, withNewline = true) { - this.write(`Error: ${str}`, withNewline); - } - /** - * Write information message to ESP Loader constructor's terminal with or without new line. - * @param {string} str - String to write. - * @param {boolean} withNewline - Add new line at the end ? - */ - info(str, withNewline = true) { - this.write(str, withNewline); - } - /** - * Write debug message to ESP Loader constructor's terminal with or without new line. - * @param {string} str - String to write. - * @param {boolean} withNewline - Add new line at the end ? - */ - debug(str, withNewline = true) { - if (this.debugLogging) { - this.write(`Debug: ${str}`, withNewline); - } - } - /** - * Convert short integer to byte array - * @param {number} i - Number to convert. - * @returns {Uint8Array} Byte array. - */ - _shortToBytearray(i) { - return new Uint8Array([i & 0xff, (i >> 8) & 0xff]); - } - /** - * Convert an integer to byte array - * @param {number} i - Number to convert. - * @returns {ROM} The chip ROM class related to given magic hex number. - */ - _intToByteArray(i) { - return new Uint8Array([i & 0xff, (i >> 8) & 0xff, (i >> 16) & 0xff, (i >> 24) & 0xff]); - } - /** - * Convert a byte array to short integer. - * @param {number} i - Number to convert. - * @param {number} j - Number to convert. - * @returns {number} Return a short integer number. - */ - _byteArrayToShort(i, j) { - return i | (j >> 8); - } - /** - * Convert a byte array to integer. - * @param {number} i - Number to convert. - * @param {number} j - Number to convert. - * @param {number} k - Number to convert. - * @param {number} l - Number to convert. - * @returns {number} Return a integer number. - */ - _byteArrayToInt(i, j, k, l) { - return i | (j << 8) | (k << 16) | (l << 24); - } - /** - * Append a buffer array after another buffer array - * @param {ArrayBuffer} buffer1 - First array buffer. - * @param {ArrayBuffer} buffer2 - magic hex number to select ROM. - * @returns {ArrayBufferLike} Return an array buffer. - */ - _appendBuffer(buffer1, buffer2) { - const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); - tmp.set(new Uint8Array(buffer1), 0); - tmp.set(new Uint8Array(buffer2), buffer1.byteLength); - return tmp.buffer; - } - /** - * Append a buffer array after another buffer array - * @param {Uint8Array} arr1 - First array buffer. - * @param {Uint8Array} arr2 - magic hex number to select ROM. - * @returns {Uint8Array} Return a 8 bit unsigned array. - */ - _appendArray(arr1, arr2) { - const c = new Uint8Array(arr1.length + arr2.length); - c.set(arr1, 0); - c.set(arr2, arr1.length); - return c; - } - /** - * Convert a unsigned 8 bit integer array to byte string. - * @param {Uint8Array} u8Array - magic hex number to select ROM. - * @returns {string} Return the equivalent string. - */ - ui8ToBstr(u8Array) { - let bStr = ""; - for (let i = 0; i < u8Array.length; i++) { - bStr += String.fromCharCode(u8Array[i]); - } - return bStr; - } - /** - * Convert a byte string to unsigned 8 bit integer array. - * @param {string} bStr - binary string input - * @returns {Uint8Array} Return a 8 bit unsigned integer array. - */ - bstrToUi8(bStr) { - const u8Array = new Uint8Array(bStr.length); - for (let i = 0; i < bStr.length; i++) { - u8Array[i] = bStr.charCodeAt(i); - } - return u8Array; - } - /** - * Flush the serial input by raw read with 200 ms timeout. - */ - async flushInput() { - try { - await this.transport.flushInput(); - } - catch (e) { - this.error(e.message); - } - } - /** - * Use the device serial port read function with given timeout to create a valid packet. - * @param {number} op Operation number - * @param {number} timeout timeout number in milliseconds - * @returns {[number, Uint8Array]} valid response packet. - */ - async readPacket(op = null, timeout = this.DEFAULT_TIMEOUT) { - // Check up-to next 100 packets for valid response packet - for (let i = 0; i < 100; i++) { - const { value: p } = await this.transport.read(timeout).next(); - if (!p || p.length < 8) { - continue; - } - const resp = p[0]; - if (resp !== 1) { - continue; - } - const opRet = p[1]; - const val = this._byteArrayToInt(p[4], p[5], p[6], p[7]); - const data = p.slice(8); - if (resp == 1) { - if (op == null || opRet == op) { - return [val, data]; - } - else if (data[0] != 0 && data[1] == this.ROM_INVALID_RECV_MSG) { - await this.flushInput(); - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("unsupported command error"); - } - } - } - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("invalid response"); - } - /** - * Write a serial command to the chip - * @param {number} op - Operation number - * @param {Uint8Array} data - Unsigned 8 bit array - * @param {number} chk - channel number - * @param {boolean} waitResponse - wait for response ? - * @param {number} timeout - timeout number in milliseconds - * @returns {Promise<[number, Uint8Array]>} Return a number and a 8 bit unsigned integer array. - */ - async command(op = null, data = new Uint8Array(0), chk = 0, waitResponse = true, timeout = this.DEFAULT_TIMEOUT) { - if (op != null) { - if (this.transport.tracing) { - this.transport.trace(`command op:0x${op.toString(16).padStart(2, "0")} data len=${data.length} wait_response=${waitResponse ? 1 : 0} timeout=${(timeout / 1000).toFixed(3)} data=${this.transport.hexConvert(data)}`); - } - const pkt = new Uint8Array(8 + data.length); - pkt[0] = 0x00; - pkt[1] = op; - pkt[2] = this._shortToBytearray(data.length)[0]; - pkt[3] = this._shortToBytearray(data.length)[1]; - pkt[4] = this._intToByteArray(chk)[0]; - pkt[5] = this._intToByteArray(chk)[1]; - pkt[6] = this._intToByteArray(chk)[2]; - pkt[7] = this._intToByteArray(chk)[3]; - let i; - for (i = 0; i < data.length; i++) { - pkt[8 + i] = data[i]; - } - await this.transport.write(pkt); - } - if (!waitResponse) { - return [0, new Uint8Array(0)]; - } - return this.readPacket(op, timeout); - } - /** - * Read a register from chip. - * @param {number} addr - Register address number - * @param {number} timeout - Timeout in milliseconds (Default: 3000ms) - * @returns {number} - Command number value - */ - async readReg(addr, timeout = this.DEFAULT_TIMEOUT) { - const pkt = this._intToByteArray(addr); - const val = await this.command(this.ESP_READ_REG, pkt, undefined, undefined, timeout); - return val[0]; - } - /** - * Write a number value to register address in chip. - * @param {number} addr - Register address number - * @param {number} value - Number value to write in register - * @param {number} mask - Hex number for mask - * @param {number} delayUs Delay number - * @param {number} delayAfterUs Delay after previous delay - */ - async writeReg(addr, value, mask = 0xffffffff, delayUs = 0, delayAfterUs = 0) { - let pkt = this._appendArray(this._intToByteArray(addr), this._intToByteArray(value)); - pkt = this._appendArray(pkt, this._intToByteArray(mask)); - pkt = this._appendArray(pkt, this._intToByteArray(delayUs)); - if (delayAfterUs > 0) { - pkt = this._appendArray(pkt, this._intToByteArray(this.chip.UART_DATE_REG_ADDR)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, this._intToByteArray(delayAfterUs)); - } - await this.checkCommand("write target memory", this.ESP_WRITE_REG, pkt); - } - /** - * Sync chip by sending sync command. - * @returns {[number, Uint8Array]} Command result - */ - async sync() { - this.debug("Sync"); - const cmd = new Uint8Array(36); - let i; - cmd[0] = 0x07; - cmd[1] = 0x07; - cmd[2] = 0x12; - cmd[3] = 0x20; - for (i = 0; i < 32; i++) { - cmd[4 + i] = 0x55; - } - try { - let resp = await this.command(0x08, cmd, undefined, undefined, 100); - // ROM bootloaders send some non-zero "val" response. The flasher stub sends 0. - // If we receive 0 then it probably indicates that the chip wasn't or couldn't be - // reset properly and esptool is talking to the flasher stub. - this.syncStubDetected = resp[0] === 0; - for (let i = 0; i < 7; i++) { - resp = await this.command(); - this.syncStubDetected = this.syncStubDetected && resp[0] === 0; - } - return resp; - } - catch (e) { - this.debug("Sync err " + e); - throw e; - } - } - /** - * Attempt to connect to the chip by sending a reset sequence and later a sync command. - * @param {string} mode - Reset mode to use - * @param {ResetStrategy} resetStrategy - Reset strategy class to use for connect - * @returns {string} - Returns 'success' or 'error' message. - */ - async _connectAttempt(mode = "default_reset", resetStrategy) { - this.debug("_connect_attempt " + mode); - if (resetStrategy) { - await resetStrategy.reset(); - } - const waitingBytes = this.transport.inWaiting(); - const readBytes = await this.transport.newRead(waitingBytes > 0 ? waitingBytes : 1, this.DEFAULT_TIMEOUT); - const binaryString = Array.from(readBytes, (byte) => String.fromCharCode(byte)).join(""); - const regex = /boot:(0x[0-9a-fA-F]+)(.*waiting for download)?/; - const match = binaryString.match(regex); - let bootLogDetected = false, bootMode = "", downloadMode = false; - if (match) { - bootLogDetected = true; - bootMode = match[1]; - downloadMode = !!match[2]; - } - let lastError = ""; - for (let i = 0; i < 5; i++) { - try { - this.debug(`Sync connect attempt ${i}`); - const resp = await this.sync(); - this.debug(resp[0].toString()); - return "success"; - } - catch (error) { - this.debug(`Error at sync ${error}`); - if (error instanceof Error) { - lastError = error.message; - } - else if (typeof error === "string") { - lastError = error; - } - else { - lastError = JSON.stringify(error); - } - } - } - if (bootLogDetected) { - lastError = `Wrong boot mode detected (${bootMode}). - This chip needs to be in download mode.`; - if (downloadMode) { - lastError = `Download mode successfully detected, but getting no sync reply: - The serial TX path seems to be down.`; - } - } - return lastError; - } - /** - * Constructs a sequence of reset strategies based on the OS, - * used ESP chip, external settings, and environment variables. - * Returns a tuple of one or more reset strategies to be tried sequentially. - * @param {string} mode - Reset mode to use - * @returns {ResetStrategy[]} - Array of reset strategies - */ - constructResetSequence(mode) { - if (mode !== "no_reset") { - if (mode === "usb_reset" || this.transport.getPid() === this.USB_JTAG_SERIAL_PID) { - // Custom reset sequence, which is required when the device - // is connecting via its USB-JTAG-Serial peripheral - if (this.resetConstructors.usbJTAGSerialReset) { - this.debug("using USB JTAG Serial Reset"); - return [this.resetConstructors.usbJTAGSerialReset(this.transport)]; - } - } - else { - const DEFAULT_RESET_DELAY = 50; - const EXTRA_DELAY = DEFAULT_RESET_DELAY + 500; - if (this.resetConstructors.classicReset) { - this.debug("using Classic Serial Reset"); - return [ - this.resetConstructors.classicReset(this.transport, DEFAULT_RESET_DELAY), - this.resetConstructors.classicReset(this.transport, EXTRA_DELAY), - ]; - } - } - } - return []; - } - /** - * Perform a connection to chip. - * @param {string} mode - Reset mode to use. Example: 'default_reset' | 'no_reset' - * @param {number} attempts - Number of connection attempts - * @param {boolean} detecting - Detect the connected chip - */ - async connect(mode = "default_reset", attempts = 7, detecting = true) { - let resp; - this.info("Connecting...", false); - await this.transport.connect(this.romBaudrate, this.serialOptions); - const resetSequences = this.constructResetSequence(mode); - for (let i = 0; i < attempts; i++) { - const resetSequence = resetSequences.length > 0 ? resetSequences[i % resetSequences.length] : null; - resp = await this._connectAttempt(mode, resetSequence); - if (resp === "success") { - break; - } - } - if (resp !== "success") { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("Failed to connect with the device"); - } - this.debug("Connect attempt successful."); - this.info("\n\r", false); - if (detecting) { - const chipMagicValue = (await this.readReg(this.CHIP_DETECT_MAGIC_REG_ADDR)) >>> 0; - this.debug("Chip Magic " + chipMagicValue.toString(16)); - const chip = await magic2Chip(chipMagicValue); - if (this.chip === null) { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError(`Unexpected CHIP magic value ${chipMagicValue}. Failed to autodetect chip type.`); - } - else { - this.chip = chip; - } - } - } - /** - * Connect and detect the existing chip. - * @param {string} mode Reset mode to use for connection. - */ - async detectChip(mode = "default_reset") { - await this.connect(mode); - this.info("Detecting chip type... ", false); - if (this.chip != null) { - this.info(this.chip.CHIP_NAME); - } - else { - this.info("unknown!"); - } - } - /** - * Execute the command and check the command response. - * @param {string} opDescription Command operation description. - * @param {number} op Command operation number - * @param {Uint8Array} data Command value - * @param {number} chk Checksum to use - * @param {number} timeout TImeout number in milliseconds (ms) - * @returns {number} Command result - */ - async checkCommand(opDescription = "", op = null, data = new Uint8Array(0), chk = 0, timeout = this.DEFAULT_TIMEOUT) { - this.debug("check_command " + opDescription); - const resp = await this.command(op, data, chk, undefined, timeout); - if (resp[1].length > 4) { - return resp[1]; - } - else { - return resp[0]; - } - } - /** - * Start downloading an application image to RAM - * @param {number} size Image size number - * @param {number} blocks Number of data blocks - * @param {number} blocksize Size of each data block - * @param {number} offset Image offset number - */ - async memBegin(size, blocks, blocksize, offset) { - /* XXX: Add check to ensure that STUB is not getting overwritten */ - if (this.IS_STUB) { - const loadStart = offset; - const loadEnd = offset + size; - const stub = await (0,_stubFlasher_js__WEBPACK_IMPORTED_MODULE_4__.getStubJsonByChipName)(this.chip.CHIP_NAME); - if (stub) { - const areasToCheck = [ - [stub.bss_start || stub.data_start, stub.data_start + stub.decodedData.length], - [stub.text_start, stub.text_start + stub.decodedText.length], - ]; - for (const [stubStart, stubEnd] of areasToCheck) { - if (loadStart < stubEnd && loadEnd > stubStart) { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError(`Software loader is resident at 0x${stubStart.toString(16).padStart(8, "0")}-0x${stubEnd - .toString(16) - .padStart(8, "0")}. - Can't load binary at overlapping address range 0x${loadStart.toString(16).padStart(8, "0")}-0x${loadEnd - .toString(16) - .padStart(8, "0")}. - Either change binary loading address, or use the no-stub option to disable the software loader.`); - } - } - } - } - this.debug("mem_begin " + size + " " + blocks + " " + blocksize + " " + offset.toString(16)); - let pkt = this._appendArray(this._intToByteArray(size), this._intToByteArray(blocks)); - pkt = this._appendArray(pkt, this._intToByteArray(blocksize)); - pkt = this._appendArray(pkt, this._intToByteArray(offset)); - await this.checkCommand("enter RAM download mode", this.ESP_MEM_BEGIN, pkt); - } - /** - * Get the checksum for given unsigned 8-bit array - * @param {Uint8Array} data Unsigned 8-bit integer array - * @param {number} state Initial checksum - * @returns {number} - Array checksum - */ - checksum(data, state = this.ESP_CHECKSUM_MAGIC) { - for (let i = 0; i < data.length; i++) { - state ^= data[i]; - } - return state; - } - /** - * Send a block of image to RAM - * @param {Uint8Array} buffer Unsigned 8-bit array - * @param {number} seq Sequence number - */ - async memBlock(buffer, seq) { - let pkt = this._appendArray(this._intToByteArray(buffer.length), this._intToByteArray(seq)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, buffer); - const checksum = this.checksum(buffer); - await this.checkCommand("write to target RAM", this.ESP_MEM_DATA, pkt, checksum); - } - /** - * Leave RAM download mode and run application - * @param {number} entrypoint - Entrypoint number - */ - async memFinish(entrypoint) { - const isEntry = entrypoint === 0 ? 1 : 0; - const pkt = this._appendArray(this._intToByteArray(isEntry), this._intToByteArray(entrypoint)); - await this.checkCommand("leave RAM download mode", this.ESP_MEM_END, pkt, undefined, 200); // XXX: handle non-stub with diff timeout - } - /** - * Configure SPI flash pins - * @param {number} hspiArg - Argument for SPI attachment - */ - async flashSpiAttach(hspiArg) { - const pkt = this._intToByteArray(hspiArg); - await this.checkCommand("configure SPI flash pins", this.ESP_SPI_ATTACH, pkt); - } - /** - * Scale timeouts which are size-specific. - * @param {number} secondsPerMb Seconds per megabytes as number - * @param {number} sizeBytes Size bytes number - * @returns {number} - Scaled timeout for specified size. - */ - timeoutPerMb(secondsPerMb, sizeBytes) { - const result = secondsPerMb * (sizeBytes / 1000000); - if (result < 3000) { - return 3000; - } - else { - return result; - } - } - /** - * Start downloading to Flash (performs an erase) - * @param {number} size Size to erase - * @param {number} offset Offset to erase - * @returns {number} Number of blocks (of size self.FLASH_WRITE_SIZE) to write. - */ - async flashBegin(size, offset) { - const numBlocks = Math.floor((size + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE); - const eraseSize = this.chip.getEraseSize(offset, size); - const d = new Date(); - const t1 = d.getTime(); - let timeout = 3000; - if (this.IS_STUB == false) { - timeout = this.timeoutPerMb(this.ERASE_REGION_TIMEOUT_PER_MB, size); - } - this.debug("flash begin " + eraseSize + " " + numBlocks + " " + this.FLASH_WRITE_SIZE + " " + offset + " " + size); - let pkt = this._appendArray(this._intToByteArray(eraseSize), this._intToByteArray(numBlocks)); - pkt = this._appendArray(pkt, this._intToByteArray(this.FLASH_WRITE_SIZE)); - pkt = this._appendArray(pkt, this._intToByteArray(offset)); - if (this.IS_STUB == false) { - pkt = this._appendArray(pkt, this._intToByteArray(0)); // XXX: Support encrypted - } - await this.checkCommand("enter Flash download mode", this.ESP_FLASH_BEGIN, pkt, undefined, timeout); - const t2 = d.getTime(); - if (size != 0 && this.IS_STUB == false) { - this.info("Took " + (t2 - t1) / 1000 + "." + ((t2 - t1) % 1000) + "s to erase flash block"); - } - return numBlocks; - } - /** - * Start downloading compressed data to Flash (performs an erase) - * @param {number} size Write size - * @param {number} compsize Compressed size - * @param {number} offset Offset for write - * @returns {number} Returns number of blocks (size self.FLASH_WRITE_SIZE) to write. - */ - async flashDeflBegin(size, compsize, offset) { - const numBlocks = Math.floor((compsize + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE); - const eraseBlocks = Math.floor((size + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE); - const d = new Date(); - const t1 = d.getTime(); - let writeSize, timeout; - if (this.IS_STUB) { - writeSize = size; - timeout = this.DEFAULT_TIMEOUT; - } - else { - writeSize = eraseBlocks * this.FLASH_WRITE_SIZE; - timeout = this.timeoutPerMb(this.ERASE_REGION_TIMEOUT_PER_MB, writeSize); - } - this.info("Compressed " + size + " bytes to " + compsize + "..."); - let pkt = this._appendArray(this._intToByteArray(writeSize), this._intToByteArray(numBlocks)); - pkt = this._appendArray(pkt, this._intToByteArray(this.FLASH_WRITE_SIZE)); - pkt = this._appendArray(pkt, this._intToByteArray(offset)); - if ((this.chip.CHIP_NAME === "ESP32-S2" || - this.chip.CHIP_NAME === "ESP32-S3" || - this.chip.CHIP_NAME === "ESP32-C3" || - this.chip.CHIP_NAME === "ESP32-C2") && - this.IS_STUB === false) { - pkt = this._appendArray(pkt, this._intToByteArray(0)); - } - await this.checkCommand("enter compressed flash mode", this.ESP_FLASH_DEFL_BEGIN, pkt, undefined, timeout); - const t2 = d.getTime(); - if (size != 0 && this.IS_STUB === false) { - this.info("Took " + (t2 - t1) / 1000 + "." + ((t2 - t1) % 1000) + "s to erase flash block"); - } - return numBlocks; - } - /** - * Write block to flash, retry if fail - * @param {Uint8Array} data Unsigned 8-bit array data. - * @param {number} seq Sequence number - * @param {number} timeout Timeout in milliseconds (ms) - */ - async flashBlock(data, seq, timeout) { - let pkt = this._appendArray(this._intToByteArray(data.length), this._intToByteArray(seq)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, data); - const checksum = this.checksum(data); - await this.checkCommand("write to target Flash after seq " + seq, this.ESP_FLASH_DATA, pkt, checksum, timeout); - } - /** - * Write block to flash, send compressed, retry if fail - * @param {Uint8Array} data Unsigned int 8-bit array data to write - * @param {number} seq Sequence number - * @param {number} timeout Timeout in milliseconds (ms) - */ - async flashDeflBlock(data, seq, timeout) { - let pkt = this._appendArray(this._intToByteArray(data.length), this._intToByteArray(seq)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, data); - const checksum = this.checksum(data); - this.debug("flash_defl_block " + data[0].toString(16) + " " + data[1].toString(16)); - await this.checkCommand("write compressed data to flash after seq " + seq, this.ESP_FLASH_DEFL_DATA, pkt, checksum, timeout); - } - /** - * Leave flash mode and run/reboot - * @param {boolean} reboot Reboot after leaving flash mode ? - */ - async flashFinish(reboot = false) { - const val = reboot ? 0 : 1; - const pkt = this._intToByteArray(val); - await this.checkCommand("leave Flash mode", this.ESP_FLASH_END, pkt); - } - /** - * Leave compressed flash mode and run/reboot - * @param {boolean} reboot Reboot after leaving flash mode ? - */ - async flashDeflFinish(reboot = false) { - const val = reboot ? 0 : 1; - const pkt = this._intToByteArray(val); - await this.checkCommand("leave compressed flash mode", this.ESP_FLASH_DEFL_END, pkt); - } - /** - * Run an arbitrary SPI flash command. - * - * This function uses the "USR_COMMAND" functionality in the ESP - * SPI hardware, rather than the precanned commands supported by - * hardware. So the value of spiflashCommand is an actual command - * byte, sent over the wire. - * - * After writing command byte, writes 'data' to MOSI and then - * reads back 'readBits' of reply on MISO. Result is a number. - * @param {number} spiflashCommand Command to execute in SPI - * @param {Uint8Array} data Data to send - * @param {number} readBits Number of bits to read - * @returns {number} Register SPI_W0_REG value - */ - async runSpiflashCommand(spiflashCommand, data, readBits) { - // SPI_USR register flags - const SPI_USR_COMMAND = 1 << 31; - const SPI_USR_MISO = 1 << 28; - const SPI_USR_MOSI = 1 << 27; - // SPI registers, base address differs ESP32* vs 8266 - const base = this.chip.SPI_REG_BASE; - const SPI_CMD_REG = base + 0x00; - const SPI_USR_REG = base + this.chip.SPI_USR_OFFS; - const SPI_USR1_REG = base + this.chip.SPI_USR1_OFFS; - const SPI_USR2_REG = base + this.chip.SPI_USR2_OFFS; - const SPI_W0_REG = base + this.chip.SPI_W0_OFFS; - let setDataLengths; - if (this.chip.SPI_MOSI_DLEN_OFFS != null) { - setDataLengths = async (mosiBits, misoBits) => { - const SPI_MOSI_DLEN_REG = base + this.chip.SPI_MOSI_DLEN_OFFS; - const SPI_MISO_DLEN_REG = base + this.chip.SPI_MISO_DLEN_OFFS; - if (mosiBits > 0) { - await this.writeReg(SPI_MOSI_DLEN_REG, mosiBits - 1); - } - if (misoBits > 0) { - await this.writeReg(SPI_MISO_DLEN_REG, misoBits - 1); - } - }; - } - else { - setDataLengths = async (mosiBits, misoBits) => { - const SPI_DATA_LEN_REG = SPI_USR1_REG; - const SPI_MOSI_BITLEN_S = 17; - const SPI_MISO_BITLEN_S = 8; - const mosiMask = mosiBits === 0 ? 0 : mosiBits - 1; - const misoMask = misoBits === 0 ? 0 : misoBits - 1; - const val = (misoMask << SPI_MISO_BITLEN_S) | (mosiMask << SPI_MOSI_BITLEN_S); - await this.writeReg(SPI_DATA_LEN_REG, val); - }; - } - const SPI_CMD_USR = 1 << 18; - const SPI_USR2_COMMAND_LEN_SHIFT = 28; - if (readBits > 32) { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("Reading more than 32 bits back from a SPI flash operation is unsupported"); - } - if (data.length > 64) { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("Writing more than 64 bytes of data with one SPI command is unsupported"); - } - const dataBits = data.length * 8; - const oldSpiUsr = await this.readReg(SPI_USR_REG); - const oldSpiUsr2 = await this.readReg(SPI_USR2_REG); - let flags = SPI_USR_COMMAND; - let i; - if (readBits > 0) { - flags |= SPI_USR_MISO; - } - if (dataBits > 0) { - flags |= SPI_USR_MOSI; - } - await setDataLengths(dataBits, readBits); - await this.writeReg(SPI_USR_REG, flags); - let val = (7 << SPI_USR2_COMMAND_LEN_SHIFT) | spiflashCommand; - await this.writeReg(SPI_USR2_REG, val); - if (dataBits == 0) { - await this.writeReg(SPI_W0_REG, 0); - } - else { - if (data.length % 4 != 0) { - const padding = new Uint8Array(data.length % 4); - data = this._appendArray(data, padding); - } - let nextReg = SPI_W0_REG; - for (i = 0; i < data.length - 4; i += 4) { - val = this._byteArrayToInt(data[i], data[i + 1], data[i + 2], data[i + 3]); - await this.writeReg(nextReg, val); - nextReg += 4; - } - } - await this.writeReg(SPI_CMD_REG, SPI_CMD_USR); - for (i = 0; i < 10; i++) { - val = (await this.readReg(SPI_CMD_REG)) & SPI_CMD_USR; - if (val == 0) { - break; - } - } - if (i === 10) { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("SPI command did not complete in time"); - } - const stat = await this.readReg(SPI_W0_REG); - await this.writeReg(SPI_USR_REG, oldSpiUsr); - await this.writeReg(SPI_USR2_REG, oldSpiUsr2); - return stat; - } - /** - * Read flash id by executing the SPIFLASH_RDID flash command. - * @returns {Promise} Register SPI_W0_REG value - */ - async readFlashId() { - const SPIFLASH_RDID = 0x9f; - const pkt = new Uint8Array(0); - return await this.runSpiflashCommand(SPIFLASH_RDID, pkt, 24); - } - /** - * Execute the erase flash command - * @returns {Promise} Erase flash command result - */ - async eraseFlash() { - this.info("Erasing flash (this may take a while)..."); - let d = new Date(); - const t1 = d.getTime(); - const ret = await this.checkCommand("erase flash", this.ESP_ERASE_FLASH, undefined, undefined, this.CHIP_ERASE_TIMEOUT); - d = new Date(); - const t2 = d.getTime(); - this.info("Chip erase completed successfully in " + (t2 - t1) / 1000 + "s"); - return ret; - } - /** - * Convert a number or unsigned 8-bit array to hex string - * @param {number | Uint8Array } buffer Data to convert to hex string. - * @returns {string} A hex string - */ - toHex(buffer) { - return Array.prototype.map.call(buffer, (x) => ("00" + x.toString(16)).slice(-2)).join(""); - } - /** - * Calculate the MD5 Checksum command - * @param {number} addr Address number - * @param {number} size Package size - * @returns {string} MD5 Checksum string - */ - async flashMd5sum(addr, size) { - const timeout = this.timeoutPerMb(this.MD5_TIMEOUT_PER_MB, size); - let pkt = this._appendArray(this._intToByteArray(addr), this._intToByteArray(size)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - pkt = this._appendArray(pkt, this._intToByteArray(0)); - let res = await this.checkCommand("calculate md5sum", this.ESP_SPI_FLASH_MD5, pkt, undefined, timeout); - if (res instanceof Uint8Array && res.length > 16) { - res = res.slice(0, 16); - } - const strmd5 = this.toHex(res); - return strmd5; - } - async readFlash(addr, size, onPacketReceived = null) { - let pkt = this._appendArray(this._intToByteArray(addr), this._intToByteArray(size)); - pkt = this._appendArray(pkt, this._intToByteArray(0x1000)); - pkt = this._appendArray(pkt, this._intToByteArray(1024)); - const res = await this.checkCommand("read flash", this.ESP_READ_FLASH, pkt); - if (res != 0) { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("Failed to read memory: " + res); - } - let resp = new Uint8Array(0); - while (resp.length < size) { - const { value: packet } = await this.transport.read(this.FLASH_READ_TIMEOUT).next(); - if (packet instanceof Uint8Array) { - if (packet.length > 0) { - resp = this._appendArray(resp, packet); - await this.transport.write(this._intToByteArray(resp.length)); - if (onPacketReceived) { - onPacketReceived(packet, resp.length, size); - } - } - } - else { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("Failed to read memory: " + packet); - } - } - return resp; - } - /** - * Upload the flasher ROM bootloader (flasher stub) to the chip. - * @returns {ROM} The Chip ROM - */ - async runStub() { - if (this.syncStubDetected) { - this.info("Stub is already running. No upload is necessary."); - return this.chip; - } - this.info("Uploading stub..."); - const stubFlasher = await (0,_stubFlasher_js__WEBPACK_IMPORTED_MODULE_4__.getStubJsonByChipName)(this.chip.CHIP_NAME); - if (stubFlasher === undefined) { - this.debug("Error loading Stub json"); - throw new Error("Error loading Stub json"); - } - const stub = [stubFlasher.decodedText, stubFlasher.decodedData]; - for (let i = 0; i < stub.length; i++) { - if (stub[i]) { - const offs = i === 0 ? stubFlasher.text_start : stubFlasher.data_start; - const length = stub[i].length; - const blocks = Math.floor((length + this.ESP_RAM_BLOCK - 1) / this.ESP_RAM_BLOCK); - await this.memBegin(length, blocks, this.ESP_RAM_BLOCK, offs); - for (let seq = 0; seq < blocks; seq++) { - const fromOffs = seq * this.ESP_RAM_BLOCK; - const toOffs = fromOffs + this.ESP_RAM_BLOCK; - await this.memBlock(stub[i].slice(fromOffs, toOffs), seq); - } - } - } - this.info("Running stub..."); - await this.memFinish(stubFlasher.entry); - const { value: packetResult } = await this.transport.read(this.DEFAULT_TIMEOUT).next(); - const packetStr = String.fromCharCode(...packetResult); - if (packetStr !== "OHAI") { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError(`Failed to start stub. Unexpected response ${packetStr}`); - } - this.info("Stub running..."); - this.IS_STUB = true; - return this.chip; - } - /** - * Change the chip baudrate. - */ - async changeBaud() { - this.info("Changing baudrate to " + this.baudrate); - const secondArg = this.IS_STUB ? this.romBaudrate : 0; - const pkt = this._appendArray(this._intToByteArray(this.baudrate), this._intToByteArray(secondArg)); - await this.command(this.ESP_CHANGE_BAUDRATE, pkt); - this.info("Changed"); - await this.transport.disconnect(); - await this._sleep(50); - await this.transport.connect(this.baudrate, this.serialOptions); - } - /** - * Execute the main function of ESPLoader. - * @param {string} mode Reset mode to use - * @returns {string} chip ROM - */ - async main(mode = "default_reset") { - await this.detectChip(mode); - const chip = await this.chip.getChipDescription(this); - this.info("Chip is " + chip); - this.info("Features: " + (await this.chip.getChipFeatures(this))); - this.info("Crystal is " + (await this.chip.getCrystalFreq(this)) + "MHz"); - this.info("MAC: " + (await this.chip.readMac(this))); - await this.chip.readMac(this); - if (typeof this.chip.postConnect != "undefined") { - await this.chip.postConnect(this); - } - await this.runStub(); - if (this.romBaudrate !== this.baudrate) { - await this.changeBaud(); - } - return chip; - } - /** - * Parse a given flash size string to a number - * @param {string} flsz Flash size to request - * @returns {number} Flash size number - */ - parseFlashSizeArg(flsz) { - if (typeof this.chip.FLASH_SIZES[flsz] === "undefined") { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("Flash size " + flsz + " is not supported by this chip type. Supported sizes: " + this.chip.FLASH_SIZES); - } - return this.chip.FLASH_SIZES[flsz]; - } - /** - * Update the image flash parameters with given arguments. - * @param {string} image binary image as string - * @param {number} address flash address number - * @param {string} flashSize Flash size string - * @param {string} flashMode Flash mode string - * @param {string} flashFreq Flash frequency string - * @returns {string} modified image string - */ - _updateImageFlashParams(image, address, flashSize, flashMode, flashFreq) { - this.debug("_update_image_flash_params " + flashSize + " " + flashMode + " " + flashFreq); - if (image.length < 8) { - return image; - } - if (address != this.chip.BOOTLOADER_FLASH_OFFSET) { - return image; - } - if (flashSize === "keep" && flashMode === "keep" && flashFreq === "keep") { - this.info("Not changing the image"); - return image; - } - const magic = parseInt(image[0]); - let aFlashMode = parseInt(image[2]); - const flashSizeFreq = parseInt(image[3]); - if (magic !== this.ESP_IMAGE_MAGIC) { - this.info("Warning: Image file at 0x" + - address.toString(16) + - " doesn't look like an image file, so not changing any flash settings."); - return image; - } - /* XXX: Yet to implement actual image verification */ - if (flashMode !== "keep") { - const flashModes = { qio: 0, qout: 1, dio: 2, dout: 3 }; - aFlashMode = flashModes[flashMode]; - } - let aFlashFreq = flashSizeFreq & 0x0f; - if (flashFreq !== "keep") { - const flashFreqs = { "40m": 0, "26m": 1, "20m": 2, "80m": 0xf }; - aFlashFreq = flashFreqs[flashFreq]; - } - let aFlashSize = flashSizeFreq & 0xf0; - if (flashSize !== "keep") { - aFlashSize = this.parseFlashSizeArg(flashSize); - } - const flashParams = (aFlashMode << 8) | (aFlashFreq + aFlashSize); - this.info("Flash params set to " + flashParams.toString(16)); - if (parseInt(image[2]) !== aFlashMode << 8) { - image = image.substring(0, 2) + (aFlashMode << 8).toString() + image.substring(2 + 1); - } - if (parseInt(image[3]) !== aFlashFreq + aFlashSize) { - image = image.substring(0, 3) + (aFlashFreq + aFlashSize).toString() + image.substring(3 + 1); - } - return image; - } - /** - * Write set of file images into given address based on given FlashOptions object. - * @param {FlashOptions} options FlashOptions to configure how and what to write into flash. - */ - async writeFlash(options) { - this.debug("EspLoader program"); - if (options.flashSize !== "keep") { - const flashEnd = this.flashSizeBytes(options.flashSize); - for (let i = 0; i < options.fileArray.length; i++) { - if (options.fileArray[i].data.length + options.fileArray[i].address > flashEnd) { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError(`File ${i + 1} doesn't fit in the available flash`); - } - } - } - if (this.IS_STUB === true && options.eraseAll === true) { - await this.eraseFlash(); - } - let image, address; - for (let i = 0; i < options.fileArray.length; i++) { - this.debug("Data Length " + options.fileArray[i].data.length); - image = options.fileArray[i].data; - this.debug("Image Length " + image.length); - if (image.length === 0) { - this.debug("Warning: File is empty"); - continue; - } - image = this.ui8ToBstr((0,_util_js__WEBPACK_IMPORTED_MODULE_5__.padTo)(this.bstrToUi8(image), 4)); - address = options.fileArray[i].address; - image = this._updateImageFlashParams(image, address, options.flashSize, options.flashMode, options.flashFreq); - let calcmd5 = null; - if (options.calculateMD5Hash) { - calcmd5 = options.calculateMD5Hash(image); - this.debug("Image MD5 " + calcmd5); - } - const uncsize = image.length; - let blocks; - if (options.compress) { - const uncimage = this.bstrToUi8(image); - image = this.ui8ToBstr((0,pako__WEBPACK_IMPORTED_MODULE_1__.deflate)(uncimage, { level: 9 })); - blocks = await this.flashDeflBegin(uncsize, image.length, address); - } - else { - blocks = await this.flashBegin(uncsize, address); - } - let seq = 0; - let bytesSent = 0; - const totalBytes = image.length; - if (options.reportProgress) - options.reportProgress(i, 0, totalBytes); - let d = new Date(); - const t1 = d.getTime(); - let timeout = 5000; - // Create a decompressor to keep track of the size of uncompressed data - // to be written in each chunk. - const inflate = new pako__WEBPACK_IMPORTED_MODULE_1__.Inflate({ chunkSize: 1 }); - let totalLenUncompressed = 0; - inflate.onData = function (chunk) { - totalLenUncompressed += chunk.byteLength; - }; - while (image.length > 0) { - this.debug("Write loop " + address + " " + seq + " " + blocks); - this.info("Writing at 0x" + - (address + totalLenUncompressed).toString(16) + - "... (" + - Math.floor((100 * (seq + 1)) / blocks) + - "%)"); - const block = this.bstrToUi8(image.slice(0, this.FLASH_WRITE_SIZE)); - if (options.compress) { - const lenUncompressedPrevious = totalLenUncompressed; - inflate.push(block, false); - const blockUncompressed = totalLenUncompressed - lenUncompressedPrevious; - let blockTimeout = 3000; - if (this.timeoutPerMb(this.ERASE_WRITE_TIMEOUT_PER_MB, blockUncompressed) > 3000) { - blockTimeout = this.timeoutPerMb(this.ERASE_WRITE_TIMEOUT_PER_MB, blockUncompressed); - } - if (this.IS_STUB === false) { - // ROM code writes block to flash before ACKing - timeout = blockTimeout; - } - await this.flashDeflBlock(block, seq, timeout); - if (this.IS_STUB) { - // Stub ACKs when block is received, then writes to flash while receiving the block after it - timeout = blockTimeout; - } - } - else { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("Yet to handle Non Compressed writes"); - } - bytesSent += block.length; - image = image.slice(this.FLASH_WRITE_SIZE, image.length); - seq++; - if (options.reportProgress) - options.reportProgress(i, bytesSent, totalBytes); - } - if (this.IS_STUB) { - await this.readReg(this.CHIP_DETECT_MAGIC_REG_ADDR, timeout); - } - d = new Date(); - const t = d.getTime() - t1; - if (options.compress) { - this.info("Wrote " + - uncsize + - " bytes (" + - bytesSent + - " compressed) at 0x" + - address.toString(16) + - " in " + - t / 1000 + - " seconds."); - } - if (calcmd5) { - const res = await this.flashMd5sum(address, uncsize); - if (new String(res).valueOf() != new String(calcmd5).valueOf()) { - this.info("File md5: " + calcmd5); - this.info("Flash md5: " + res); - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("MD5 of file does not match data in flash!"); - } - else { - this.info("Hash of data verified."); - } - } - } - this.info("Leaving..."); - if (this.IS_STUB) { - await this.flashBegin(0, 0); - if (options.compress) { - await this.flashDeflFinish(); - } - else { - await this.flashFinish(); - } - } - } - /** - * Read SPI flash manufacturer and device id. - */ - async flashId() { - this.debug("flash_id"); - const flashid = await this.readFlashId(); - this.info("Manufacturer: " + (flashid & 0xff).toString(16)); - const flidLowbyte = (flashid >> 16) & 0xff; - this.info("Device: " + ((flashid >> 8) & 0xff).toString(16) + flidLowbyte.toString(16)); - this.info("Detected flash size: " + this.DETECTED_FLASH_SIZES[flidLowbyte]); - } - async getFlashSize() { - this.debug("flash_id"); - const flashid = await this.readFlashId(); - const flidLowbyte = (flashid >> 16) & 0xff; - return this.DETECTED_FLASH_SIZES_NUM[flidLowbyte]; - } - /** - * Soft reset the device chip. Soft reset with run user code is the closest. - * @param {boolean} stayInBootloader Flag to indicate if to stay in bootloader - */ - async softReset(stayInBootloader) { - if (!this.IS_STUB) { - if (stayInBootloader) { - return; // ROM bootloader is already in bootloader! - } - // "run user code" is as close to a soft reset as we can do - await this.flashBegin(0, 0); - await this.flashFinish(false); - } - else if (this.chip.CHIP_NAME != "ESP8266") { - throw new _types_error_js__WEBPACK_IMPORTED_MODULE_0__.ESPError("Soft resetting is currently only supported on ESP8266"); - } - else { - if (stayInBootloader) { - // soft resetting from the stub loader - // will re-load the ROM bootloader - await this.flashBegin(0, 0); - await this.flashFinish(true); - } - else { - // running user code from stub loader requires some hacks - // in the stub loader - await this.command(this.ESP_RUN_USER_CODE, undefined, undefined, false); - } - } - } - /** - * Execute this function to execute after operation reset functions. - * @param {After} mode After operation mode. Default is 'hard_reset'. - * @param { boolean } usingUsbOtg For 'hard_reset' to specify if using USB-OTG - */ - async after(mode = "hard_reset", usingUsbOtg) { - switch (mode) { - case "hard_reset": - if (this.resetConstructors.hardReset) { - this.info("Hard resetting via RTS pin..."); - const hardReset = this.resetConstructors.hardReset(this.transport, usingUsbOtg); - await hardReset.reset(); - } - break; - case "soft_reset": - this.info("Soft resetting..."); - await this.softReset(false); - break; - case "no_reset_stub": - this.info("Staying in flasher stub."); - break; - default: - this.info("Staying in bootloader."); - if (this.IS_STUB) { - this.softReset(true); - } - break; - } - } -} - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/index.js": -/*!**********************************************!*\ - !*** ./node_modules/esptool-js/lib/index.js ***! - \**********************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ClassicReset: () => (/* reexport safe */ _reset_js__WEBPACK_IMPORTED_MODULE_1__.ClassicReset), -/* harmony export */ CustomReset: () => (/* reexport safe */ _reset_js__WEBPACK_IMPORTED_MODULE_1__.CustomReset), -/* harmony export */ ESPLoader: () => (/* reexport safe */ _esploader_js__WEBPACK_IMPORTED_MODULE_0__.ESPLoader), -/* harmony export */ HardReset: () => (/* reexport safe */ _reset_js__WEBPACK_IMPORTED_MODULE_1__.HardReset), -/* harmony export */ ROM: () => (/* reexport safe */ _targets_rom_js__WEBPACK_IMPORTED_MODULE_2__.ROM), -/* harmony export */ Transport: () => (/* reexport safe */ _webserial_js__WEBPACK_IMPORTED_MODULE_3__.Transport), -/* harmony export */ UsbJtagSerialReset: () => (/* reexport safe */ _reset_js__WEBPACK_IMPORTED_MODULE_1__.UsbJtagSerialReset), -/* harmony export */ decodeBase64Data: () => (/* reexport safe */ _stubFlasher_js__WEBPACK_IMPORTED_MODULE_4__.decodeBase64Data), -/* harmony export */ getStubJsonByChipName: () => (/* reexport safe */ _stubFlasher_js__WEBPACK_IMPORTED_MODULE_4__.getStubJsonByChipName), -/* harmony export */ validateCustomResetStringSequence: () => (/* reexport safe */ _reset_js__WEBPACK_IMPORTED_MODULE_1__.validateCustomResetStringSequence) -/* harmony export */ }); -/* harmony import */ var _esploader_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./esploader.js */ "./node_modules/esptool-js/lib/esploader.js"); -/* harmony import */ var _reset_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./reset.js */ "./node_modules/esptool-js/lib/reset.js"); -/* harmony import */ var _targets_rom_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./targets/rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); -/* harmony import */ var _webserial_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./webserial.js */ "./node_modules/esptool-js/lib/webserial.js"); -/* harmony import */ var _stubFlasher_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./stubFlasher.js */ "./node_modules/esptool-js/lib/stubFlasher.js"); - - - - - - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/reset.js": -/*!**********************************************!*\ - !*** ./node_modules/esptool-js/lib/reset.js ***! - \**********************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ClassicReset: () => (/* binding */ ClassicReset), -/* harmony export */ CustomReset: () => (/* binding */ CustomReset), -/* harmony export */ HardReset: () => (/* binding */ HardReset), -/* harmony export */ UsbJtagSerialReset: () => (/* binding */ UsbJtagSerialReset), -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), -/* harmony export */ validateCustomResetStringSequence: () => (/* binding */ validateCustomResetStringSequence) -/* harmony export */ }); -/** - * Sleep for ms milliseconds - * @param {number} ms Milliseconds to wait - * @returns {Promise} - */ -function sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} -/** - * Execute a classic set of commands that will reset the chip. - * - * Commands (e.g. R0) are defined by a code (R) and an argument (0). - * - * The commands are: - * - * D: setDTR - 1=True / 0=False - * - * R: setRTS - 1=True / 0=False - * - * W: Wait (time delay) - positive integer number (miliseconds) - * - * "D0|R1|W100|D1|R0|W50|D0" represents the classic reset strategy - * @param {Transport} transport Transport class to perform serial communication. - * @param {number} resetDelay Delay in milliseconds for reset. - */ -class ClassicReset { - constructor(transport, resetDelay) { - this.resetDelay = resetDelay; - this.transport = transport; - } - async reset() { - await this.transport.setDTR(false); - await this.transport.setRTS(true); - await sleep(100); - await this.transport.setDTR(true); - await this.transport.setRTS(false); - await sleep(this.resetDelay); - await this.transport.setDTR(false); - } -} -/** - * Execute a set of commands for USB JTAG serial reset. - * - * Commands (e.g. R0) are defined by a code (R) and an argument (0). - * - * The commands are: - * - * D: setDTR - 1=True / 0=False - * - * R: setRTS - 1=True / 0=False - * - * W: Wait (time delay) - positive integer number (miliseconds) - * @param {Transport} transport Transport class to perform serial communication. - */ -class UsbJtagSerialReset { - constructor(transport) { - this.transport = transport; - } - async reset() { - await this.transport.setRTS(false); - await this.transport.setDTR(false); - await sleep(100); - await this.transport.setDTR(true); - await this.transport.setRTS(false); - await sleep(100); - await this.transport.setRTS(true); - await this.transport.setDTR(false); - await this.transport.setRTS(true); - await sleep(100); - await this.transport.setRTS(false); - await this.transport.setDTR(false); - } -} -/** - * Execute a set of commands that will hard reset the chip. - * - * Commands (e.g. R0) are defined by a code (R) and an argument (0). - * - * The commands are: - * - * D: setDTR - 1=True / 0=False - * - * R: setRTS - 1=True / 0=False - * - * W: Wait (time delay) - positive integer number (miliseconds) - * @param {Transport} transport Transport class to perform serial communication. - * @param {boolean} usingUsbOtg is it using USB-OTG ? - */ -class HardReset { - constructor(transport, usingUsbOtg = false) { - this.transport = transport; - this.usingUsbOtg = usingUsbOtg; - this.transport = transport; - } - async reset() { - if (this.usingUsbOtg) { - await sleep(200); - await this.transport.setRTS(false); - await sleep(200); - } - else { - await sleep(100); - await this.transport.setRTS(false); - } - } -} -/** - * Validate a sequence string based on the following format: - * - * Commands (e.g. R0) are defined by a code (R) and an argument (0). - * - * The commands are: - * - * D: setDTR - 1=True / 0=False - * - * R: setRTS - 1=True / 0=False - * - * W: Wait (time delay) - positive integer number (miliseconds) - * @param {string} seqStr Sequence string to validate - * @returns {boolean} Is the sequence string valid ? - */ -function validateCustomResetStringSequence(seqStr) { - const commands = ["D", "R", "W"]; - const commandsList = seqStr.split("|"); - for (const cmd of commandsList) { - const code = cmd[0]; - const arg = cmd.slice(1); - if (!commands.includes(code)) { - return false; // Invalid command code - } - if (code === "D" || code === "R") { - if (arg !== "0" && arg !== "1") { - return false; // Invalid argument for D and R commands - } - } - else if (code === "W") { - const delay = parseInt(arg); - if (isNaN(delay) || delay <= 0) { - return false; // Invalid argument for W command - } - } - } - return true; // All commands are valid -} -/** - * Custom reset strategy defined with a string. - * - * The sequenceString input string consists of individual commands divided by "|". - * - * Commands (e.g. R0) are defined by a code (R) and an argument (0). - * - * The commands are: - * - * D: setDTR - 1=True / 0=False - * - * R: setRTS - 1=True / 0=False - * - * W: Wait (time delay) - positive integer number (miliseconds) - * - * "D0|R1|W100|D1|R0|W50|D0" represents the classic reset strategy - * @param {Transport} transport Transport class to perform serial communication. - * @param {string} sequenceString Custom string sequence for reset strategy - */ -class CustomReset { - constructor(transport, sequenceString) { - this.transport = transport; - this.sequenceString = sequenceString; - this.transport = transport; - } - async reset() { - const resetDictionary = { - D: async (arg) => await this.transport.setDTR(arg), - R: async (arg) => await this.transport.setRTS(arg), - W: async (delay) => await sleep(delay), - }; - try { - const isValidSequence = validateCustomResetStringSequence(this.sequenceString); - if (!isValidSequence) { - return; - } - const cmds = this.sequenceString.split("|"); - for (const cmd of cmds) { - const cmdKey = cmd[0]; - const cmdVal = cmd.slice(1); - if (cmdKey === "W") { - await resetDictionary["W"](Number(cmdVal)); - } - else if (cmdKey === "D" || cmdKey === "R") { - await resetDictionary[cmdKey](cmdVal === "1"); - } - } - } - catch (error) { - throw new Error("Invalid custom reset sequence"); - } - } -} -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ ClassicReset, CustomReset, HardReset, UsbJtagSerialReset, validateCustomResetStringSequence }); - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/stubFlasher.js": -/*!****************************************************!*\ - !*** ./node_modules/esptool-js/lib/stubFlasher.js ***! - \****************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ decodeBase64Data: () => (/* binding */ decodeBase64Data), -/* harmony export */ getStubJsonByChipName: () => (/* binding */ getStubJsonByChipName) -/* harmony export */ }); -/* harmony import */ var atob_lite__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! atob-lite */ "./node_modules/atob-lite/atob-browser.js"); -/* harmony import */ var atob_lite__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(atob_lite__WEBPACK_IMPORTED_MODULE_0__); - -/** - * Import flash stub json for the given chip name. - * @param {string} chipName Name of chip to obtain flasher stub - * @returns {Stub} Stub information and decoded text and data - */ -async function getStubJsonByChipName(chipName) { - let jsonStub; - switch (chipName) { - case "ESP32": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32.json", 19)); - break; - case "ESP32-C2": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c2_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32c2.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c2.json", 19)); - break; - case "ESP32-C3": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c3_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32c3.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c3.json", 19)); - break; - case "ESP32-C5": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c5_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32c5.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c5.json", 19)); - break; - case "ESP32-C6": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c6_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32c6.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c6.json", 19)); - break; - case "ESP32-C61": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32c61_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32c61.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32c61.json", 19)); - break; - case "ESP32-H2": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32h2_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32h2.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32h2.json", 19)); - break; - case "ESP32-P4": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32p4_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32p4.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32p4.json", 19)); - break; - case "ESP32-S2": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s2_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32s2.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32s2.json", 19)); - break; - case "ESP32-S3": - jsonStub = await __webpack_require__.e(/*! import() */ "node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_32s3_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_32s3.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_32s3.json", 19)); - break; - case "ESP8266": - jsonStub = await __webpack_require__.e(/*! import() */ "vendors-node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_8266_json").then(__webpack_require__.t.bind(__webpack_require__, /*! ./targets/stub_flasher/stub_flasher_8266.json */ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_8266.json", 19)); - break; - } - if (jsonStub) { - return { - bss_start: jsonStub.bss_start, - data: jsonStub.data, - data_start: jsonStub.data_start, - entry: jsonStub.entry, - text: jsonStub.text, - text_start: jsonStub.text_start, - decodedData: decodeBase64Data(jsonStub.data), - decodedText: decodeBase64Data(jsonStub.text), - }; - } - return; -} -/** - * Convert a base 64 string to Uint8Array. - * @param {string} dataStr Base64 String to decode - * @returns {Uint8Array} Decoded Uint8Array - */ -function decodeBase64Data(dataStr) { - const decoded = atob_lite__WEBPACK_IMPORTED_MODULE_0___default()(dataStr); - const chardata = decoded.split("").map(function (x) { - return x.charCodeAt(0); - }); - return new Uint8Array(chardata); -} - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/targets/rom.js": -/*!****************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/rom.js ***! - \****************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ROM: () => (/* binding */ ROM) -/* harmony export */ }); -/** - * Represents a chip ROM with basic registers field and abstract functions. - */ -class ROM { - /** - * Get the chip erase size. - * @param {number} offset - Offset to start erase. - * @param {number} size - Size to erase. - * @returns {number} The erase size of the chip as number. - */ - getEraseSize(offset, size) { - return size; - } -} - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/types/error.js": -/*!****************************************************!*\ - !*** ./node_modules/esptool-js/lib/types/error.js ***! - \****************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESPError: () => (/* binding */ ESPError), -/* harmony export */ TimeoutError: () => (/* binding */ TimeoutError) -/* harmony export */ }); -/** - * Represents a Espressif chip error. - */ -class ESPError extends Error { -} -/** - * Represents a Espressif timeout chip error. - */ -class TimeoutError extends ESPError { -} - - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/util.js": -/*!*********************************************!*\ - !*** ./node_modules/esptool-js/lib/util.js ***! - \*********************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ padTo: () => (/* binding */ padTo) -/* harmony export */ }); -/** - * Pad to the next alignment boundary - * @param {Uint8Array} data Uint8Array data to pad - * @param {number} alignment Alignment boundary to fulfill - * @param {number} padCharacter Character to fill with - * @returns {Uint8Array} Padded UInt8Array image - */ -function padTo(data, alignment, padCharacter = 0xff) { - const padMod = data.length % alignment; - if (padMod !== 0) { - const padding = new Uint8Array(alignment - padMod).fill(padCharacter); - const paddedData = new Uint8Array(data.length + padding.length); - paddedData.set(data); - paddedData.set(padding, data.length); - return paddedData; - } - return data; -} - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/webserial.js": -/*!**************************************************!*\ - !*** ./node_modules/esptool-js/lib/webserial.js ***! - \**************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Transport: () => (/* binding */ Transport) -/* harmony export */ }); -/* global SerialPort, ParityType, FlowControlType */ -/** - * Wrapper class around Webserial API to communicate with the serial device. - * @param {typeof import("w3c-web-serial").SerialPort} device - Requested device prompted by the browser. - * - * ``` - * const port = await navigator.serial.requestPort(); - * ``` - */ -class Transport { - constructor(device, tracing = false, enableSlipReader = true) { - this.device = device; - this.tracing = tracing; - this.slipReaderEnabled = false; - this.baudrate = 0; - this.traceLog = ""; - this.lastTraceTime = Date.now(); - this.buffer = new Uint8Array(0); - this.SLIP_END = 0xc0; - this.SLIP_ESC = 0xdb; - this.SLIP_ESC_END = 0xdc; - this.SLIP_ESC_ESC = 0xdd; - this._DTR_state = false; - this.slipReaderEnabled = enableSlipReader; - } - /** - * Request the serial device vendor ID and Product ID as string. - * @returns {string} Return the device VendorID and ProductID from SerialPortInfo as formatted string. - */ - getInfo() { - const info = this.device.getInfo(); - return info.usbVendorId && info.usbProductId - ? `WebSerial VendorID 0x${info.usbVendorId.toString(16)} ProductID 0x${info.usbProductId.toString(16)}` - : ""; - } - /** - * Request the serial device product id from SerialPortInfo. - * @returns {number | undefined} Return the product ID. - */ - getPid() { - return this.device.getInfo().usbProductId; - } - /** - * Format received or sent data for tracing output. - * @param {string} message Message to format as trace line. - */ - trace(message) { - const delta = Date.now() - this.lastTraceTime; - const prefix = `TRACE ${delta.toFixed(3)}`; - const traceMessage = `${prefix} ${message}`; - console.log(traceMessage); - this.traceLog += traceMessage + "\n"; - } - async returnTrace() { - try { - await navigator.clipboard.writeText(this.traceLog); - console.log("Text copied to clipboard!"); - } - catch (err) { - console.error("Failed to copy text:", err); - } - } - hexify(s) { - return Array.from(s) - .map((byte) => byte.toString(16).padStart(2, "0")) - .join("") - .padEnd(16, " "); - } - hexConvert(uint8Array, autoSplit = true) { - if (autoSplit && uint8Array.length > 16) { - let result = ""; - let s = uint8Array; - while (s.length > 0) { - const line = s.slice(0, 16); - const asciiLine = String.fromCharCode(...line) - .split("") - .map((c) => (c === " " || (c >= " " && c <= "~" && c !== " ") ? c : ".")) - .join(""); - s = s.slice(16); - result += `\n ${this.hexify(line.slice(0, 8))} ${this.hexify(line.slice(8))} | ${asciiLine}`; - } - return result; - } - else { - return this.hexify(uint8Array); - } - } - /** - * Format data packet using the Serial Line Internet Protocol (SLIP). - * @param {Uint8Array} data Binary unsigned 8 bit array data to format. - * @returns {Uint8Array} Formatted unsigned 8 bit data array. - */ - slipWriter(data) { - const outData = []; - outData.push(0xc0); - for (let i = 0; i < data.length; i++) { - if (data[i] === 0xdb) { - outData.push(0xdb, 0xdd); - } - else if (data[i] === 0xc0) { - outData.push(0xdb, 0xdc); - } - else { - outData.push(data[i]); - } - } - outData.push(0xc0); - return new Uint8Array(outData); - } - /** - * Write binary data to device using the WebSerial device writable stream. - * @param {Uint8Array} data 8 bit unsigned data array to write to device. - */ - async write(data) { - const outData = this.slipWriter(data); - if (this.device.writable) { - const writer = this.device.writable.getWriter(); - if (this.tracing) { - console.log("Write bytes"); - this.trace(`Write ${outData.length} bytes: ${this.hexConvert(outData)}`); - } - await writer.write(outData); - writer.releaseLock(); - } - } - /** - * Append a buffer array after another buffer array - * @param {Uint8Array} arr1 - First array buffer. - * @param {Uint8Array} arr2 - magic hex number to select ROM. - * @returns {Uint8Array} Return a 8 bit unsigned array. - */ - appendArray(arr1, arr2) { - const combined = new Uint8Array(arr1.length + arr2.length); - combined.set(arr1); - combined.set(arr2, arr1.length); - return combined; - } - // Asynchronous generator to yield incoming data chunks - async *readLoop(timeout) { - if (!this.reader) - return; - try { - while (true) { - const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Read timeout exceeded")), timeout)); - // Await the race between the timeout and the reader read - const result = await Promise.race([this.reader.read(), timeoutPromise]); - // If a timeout occurs, result will be null; otherwise, it will have { value, done } - if (result === null) - break; - const { value, done } = result; - if (done || !value) - break; - yield value; // Yield each data chunk - } - } - catch (error) { - console.error("Error reading from serial port:", error); - } - finally { - this.buffer = new Uint8Array(0); - } - } - // Read a specific number of bytes - async newRead(numBytes, timeout) { - if (this.buffer.length >= numBytes) { - const output = this.buffer.slice(0, numBytes); - this.buffer = this.buffer.slice(numBytes); // Remove the returned data from buffer - return output; - } - while (this.buffer.length < numBytes) { - const readLoop = this.readLoop(timeout); - const { value, done } = await readLoop.next(); - if (done || !value) { - break; - } - // Append the newly read data to the buffer - this.buffer = this.appendArray(this.buffer, value); - } - // Return as much data as possible - const output = this.buffer.slice(0, numBytes); - this.buffer = this.buffer.slice(numBytes); - return output; - } - async flushInput() { - var _a; - if (this.reader && !(await this.reader.closed)) { - await this.reader.cancel(); - this.reader.releaseLock(); - this.reader = (_a = this.device.readable) === null || _a === void 0 ? void 0 : _a.getReader(); - } - } - async flushOutput() { - var _a, _b; - this.buffer = new Uint8Array(0); - await ((_a = this.device.writable) === null || _a === void 0 ? void 0 : _a.getWriter().close()); - (_b = this.device.writable) === null || _b === void 0 ? void 0 : _b.getWriter().releaseLock(); - } - // `inWaiting` returns the count of bytes in the buffer - inWaiting() { - return this.buffer.length; - } - /** - * Detect if the data read from device is a Fatal or Guru meditation error. - * @param {Uint8Array} input Data read from device - */ - detectPanicHandler(input) { - const guruMeditationRegex = /G?uru Meditation Error: (?:Core \d panic'ed \(([a-zA-Z ]*)\))?/; - const fatalExceptionRegex = /F?atal exception \(\d+\): (?:([a-zA-Z ]*)?.*epc)?/; - const inputString = new TextDecoder("utf-8").decode(input); - const match = inputString.match(guruMeditationRegex) || inputString.match(fatalExceptionRegex); - if (match) { - const cause = match[1] || match[2]; - const msg = `Guru Meditation Error detected${cause ? ` (${cause})` : ""}`; - throw new Error(msg); - } - } - /** - * Take a data array and return the first well formed packet after - * replacing the escape sequence. Reads at least 8 bytes. - * @param {number} timeout Timeout read data. - * @yields {Uint8Array} Formatted packet using SLIP escape sequences. - */ - async *read(timeout) { - var _a; - if (!this.reader) { - this.reader = (_a = this.device.readable) === null || _a === void 0 ? void 0 : _a.getReader(); - } - let partialPacket = null; - let isEscaping = false; - let successfulSlip = false; - while (true) { - const waitingBytes = this.inWaiting(); - const readBytes = await this.newRead(waitingBytes > 0 ? waitingBytes : 1, timeout); - if (!readBytes || readBytes.length === 0) { - const msg = partialPacket === null - ? successfulSlip - ? "Serial data stream stopped: Possible serial noise or corruption." - : "No serial data received." - : `Packet content transfer stopped`; - this.trace(msg); - throw new Error(msg); - } - this.trace(`Read ${readBytes.length} bytes: ${this.hexConvert(readBytes)}`); - let i = 0; // Track position in readBytes - while (i < readBytes.length) { - const byte = readBytes[i++]; - if (partialPacket === null) { - if (byte === this.SLIP_END) { - partialPacket = new Uint8Array(0); // Start of a new packet - } - else { - this.trace(`Read invalid data: ${this.hexConvert(readBytes)}`); - const remainingData = await this.newRead(this.inWaiting(), timeout); - this.trace(`Remaining data in serial buffer: ${this.hexConvert(remainingData)}`); - this.detectPanicHandler(new Uint8Array([...readBytes, ...(remainingData || [])])); - throw new Error(`Invalid head of packet (0x${byte.toString(16)}): Possible serial noise or corruption.`); - } - } - else if (isEscaping) { - isEscaping = false; - if (byte === this.SLIP_ESC_END) { - partialPacket = this.appendArray(partialPacket, new Uint8Array([this.SLIP_END])); - } - else if (byte === this.SLIP_ESC_ESC) { - partialPacket = this.appendArray(partialPacket, new Uint8Array([this.SLIP_ESC])); - } - else { - this.trace(`Read invalid data: ${this.hexConvert(readBytes)}`); - const remainingData = await this.newRead(this.inWaiting(), timeout); - this.trace(`Remaining data in serial buffer: ${this.hexConvert(remainingData)}`); - this.detectPanicHandler(new Uint8Array([...readBytes, ...(remainingData || [])])); - throw new Error(`Invalid SLIP escape (0xdb, 0x${byte.toString(16)})`); - } - } - else if (byte === this.SLIP_ESC) { - isEscaping = true; - } - else if (byte === this.SLIP_END) { - this.trace(`Received full packet: ${this.hexConvert(partialPacket)}`); - this.buffer = this.appendArray(this.buffer, readBytes.slice(i)); - yield partialPacket; - partialPacket = null; - successfulSlip = true; - } - else { - partialPacket = this.appendArray(partialPacket, new Uint8Array([byte])); - } - } - } - } - /** - * Read from serial device without slip formatting. - * @yields {Uint8Array} The next number in the Fibonacci sequence. - */ - async *rawRead() { - if (!this.reader) - return; - try { - while (true) { - const { value, done } = await this.reader.read(); - if (done || !value) - break; - if (this.tracing) { - console.log("Raw Read bytes"); - this.trace(`Read ${value.length} bytes: ${this.hexConvert(value)}`); - } - yield value; // Yield each data chunk - } - } - catch (error) { - console.error("Error reading from serial port:", error); - } - finally { - this.buffer = new Uint8Array(0); - } - } - /** - * Send the RequestToSend (RTS) signal to given state - * # True for EN=LOW, chip in reset and False EN=HIGH, chip out of reset - * @param {boolean} state Boolean state to set the signal - */ - async setRTS(state) { - await this.device.setSignals({ requestToSend: state }); - // # Work-around for adapters on Windows using the usbser.sys driver: - // # generate a dummy change to DTR so that the set-control-line-state - // # request is sent with the updated RTS state and the same DTR state - // Referenced to esptool.py - await this.setDTR(this._DTR_state); - } - /** - * Send the dataTerminalReady (DTS) signal to given state - * # True for IO0=LOW, chip in reset and False IO0=HIGH - * @param {boolean} state Boolean state to set the signal - */ - async setDTR(state) { - this._DTR_state = state; - await this.device.setSignals({ dataTerminalReady: state }); - } - /** - * Connect to serial device using the Webserial open method. - * @param {number} baud Number baud rate for serial connection. Default is 115200. - * @param {typeof import("w3c-web-serial").SerialOptions} serialOptions Serial Options for WebUSB SerialPort class. - */ - async connect(baud = 115200, serialOptions = {}) { - var _a; - await this.device.open({ - baudRate: baud, - dataBits: serialOptions === null || serialOptions === void 0 ? void 0 : serialOptions.dataBits, - stopBits: serialOptions === null || serialOptions === void 0 ? void 0 : serialOptions.stopBits, - bufferSize: serialOptions === null || serialOptions === void 0 ? void 0 : serialOptions.bufferSize, - parity: serialOptions === null || serialOptions === void 0 ? void 0 : serialOptions.parity, - flowControl: serialOptions === null || serialOptions === void 0 ? void 0 : serialOptions.flowControl, - }); - this.baudrate = baud; - this.reader = (_a = this.device.readable) === null || _a === void 0 ? void 0 : _a.getReader(); - } - async sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); - } - /** - * Wait for a given timeout ms for serial device unlock. - * @param {number} timeout Timeout time in milliseconds (ms) to sleep - */ - async waitForUnlock(timeout) { - while ((this.device.readable && this.device.readable.locked) || - (this.device.writable && this.device.writable.locked)) { - await this.sleep(timeout); - } - } - /** - * Disconnect from serial device by running SerialPort.close() after streams unlock. - */ - async disconnect() { - var _a, _b; - if ((_a = this.device.readable) === null || _a === void 0 ? void 0 : _a.locked) { - await ((_b = this.reader) === null || _b === void 0 ? void 0 : _b.cancel()); - } - await this.waitForUnlock(400); - await this.device.close(); - this.reader = undefined; - } -} - - - -/***/ }), - -/***/ "./node_modules/improv-wifi-serial-sdk/dist/const.js": -/*!***********************************************************!*\ - !*** ./node_modules/improv-wifi-serial-sdk/dist/const.js ***! - \***********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ERROR_MSGS: () => (/* binding */ ERROR_MSGS), -/* harmony export */ ImprovSerialCurrentState: () => (/* binding */ ImprovSerialCurrentState), -/* harmony export */ ImprovSerialMessageType: () => (/* binding */ ImprovSerialMessageType), -/* harmony export */ PortNotReady: () => (/* binding */ PortNotReady), -/* harmony export */ SERIAL_PACKET_HEADER: () => (/* binding */ SERIAL_PACKET_HEADER) -/* harmony export */ }); -const SERIAL_PACKET_HEADER = [ - "I".charCodeAt(0), - "M".charCodeAt(0), - "P".charCodeAt(0), - "R".charCodeAt(0), - "O".charCodeAt(0), - "V".charCodeAt(0), - 1, // protocol version -]; -var ImprovSerialMessageType; -(function (ImprovSerialMessageType) { - ImprovSerialMessageType[ImprovSerialMessageType["CURRENT_STATE"] = 1] = "CURRENT_STATE"; - ImprovSerialMessageType[ImprovSerialMessageType["ERROR_STATE"] = 2] = "ERROR_STATE"; - ImprovSerialMessageType[ImprovSerialMessageType["RPC"] = 3] = "RPC"; - ImprovSerialMessageType[ImprovSerialMessageType["RPC_RESULT"] = 4] = "RPC_RESULT"; -})(ImprovSerialMessageType || (ImprovSerialMessageType = {})); -var ImprovSerialCurrentState; -(function (ImprovSerialCurrentState) { - ImprovSerialCurrentState[ImprovSerialCurrentState["READY"] = 2] = "READY"; - ImprovSerialCurrentState[ImprovSerialCurrentState["PROVISIONING"] = 3] = "PROVISIONING"; - ImprovSerialCurrentState[ImprovSerialCurrentState["PROVISIONED"] = 4] = "PROVISIONED"; -})(ImprovSerialCurrentState || (ImprovSerialCurrentState = {})); -const ERROR_MSGS = { - 0x00: "NO_ERROR", - 0x01: "INVALID_RPC_PACKET", - 0x02: "UNKNOWN_RPC_COMMAND", - 0x03: "UNABLE_TO_CONNECT", - 0xfe: "TIMEOUT", - 0xff: "UNKNOWN_ERROR", -}; -class PortNotReady extends Error { - constructor() { - super("Port is not ready"); - } -} - - -/***/ }), - -/***/ "./node_modules/improv-wifi-serial-sdk/dist/serial.js": -/*!************************************************************!*\ - !*** ./node_modules/improv-wifi-serial-sdk/dist/serial.js ***! - \************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ImprovSerial: () => (/* binding */ ImprovSerial) -/* harmony export */ }); -/* harmony import */ var _const_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./const.js */ "./node_modules/improv-wifi-serial-sdk/dist/const.js"); -/* harmony import */ var _util_sleep__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/sleep */ "./node_modules/improv-wifi-serial-sdk/dist/util/sleep.js"); -/* harmony import */ var _util_hex_formatter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/hex-formatter */ "./node_modules/improv-wifi-serial-sdk/dist/util/hex-formatter.js"); - - - -class ImprovSerial extends EventTarget { - constructor(port, logger) { - super(); - this.port = port; - this.logger = logger; - this.error = 0 /* ImprovSerialErrorState.NO_ERROR */; - if (port.readable === null) { - throw new Error("Port is not readable"); - } - if (port.writable === null) { - throw new Error("Port is not writable"); - } - } - /** - * Detect Improv Serial, fetch the state and return the next URL if provisioned. - * @param timeout Timeout in ms to wait for the device to respond. Default to 1000ms. - */ - async initialize(timeout = 1000) { - this.logger.log("Initializing Improv Serial"); - this._processInput(); - // To give the input processing time to start. - await (0,_util_sleep__WEBPACK_IMPORTED_MODULE_1__.sleep)(1000); - if (this._reader === undefined) { - throw new _const_js__WEBPACK_IMPORTED_MODULE_0__.PortNotReady(); - } - try { - await new Promise(async (resolve, reject) => { - setTimeout(() => reject(new Error("Improv Wi-Fi Serial not detected")), timeout); - await this.requestCurrentState(); - resolve(undefined); - }); - await this.requestInfo(); - } - catch (err) { - await this.close(); - throw err; - } - return this.info; - } - async close() { - if (!this._reader) { - return; - } - await new Promise((resolve) => { - this._reader.cancel(); - this.addEventListener("disconnect", resolve, { once: true }); - }); - } - /** - * This command will trigger at least one packet, - * the Current State and if already provisioned, - * the same response you would get if device provisioning - * was successful (see below). - */ - async requestCurrentState() { - // Request current state and wait for 5s - let rpcResult; - try { - await new Promise(async (resolve, reject) => { - this.addEventListener("state-changed", resolve, { once: true }); - const cleanupAndReject = (err) => { - this.removeEventListener("state-changed", resolve); - reject(err); - }; - rpcResult = this._sendRPCWithResponse(2 /* ImprovSerialRPCCommand.REQUEST_CURRENT_STATE */, []); - rpcResult.catch(cleanupAndReject); - }); - } - catch (err) { - this._rpcFeedback = undefined; - throw new Error(`Error fetching current state: ${err}`); - } - // Only if we are provisioned will we get an rpc result - if (this.state !== _const_js__WEBPACK_IMPORTED_MODULE_0__.ImprovSerialCurrentState.PROVISIONED) { - this._rpcFeedback = undefined; - return; - } - const data = await rpcResult; - this.nextUrl = data[0]; - } - async requestInfo(timeout) { - const response = await this._sendRPCWithResponse(3 /* ImprovSerialRPCCommand.REQUEST_INFO */, [], timeout); - this.info = { - firmware: response[0], - version: response[1], - name: response[3], - chipFamily: response[2], - }; - } - async provision(ssid, password, timeout) { - const encoder = new TextEncoder(); - const ssidEncoded = encoder.encode(ssid); - const pwEncoded = encoder.encode(password); - const data = [ - ssidEncoded.length, - ...ssidEncoded, - pwEncoded.length, - ...pwEncoded, - ]; - const response = await this._sendRPCWithResponse(1 /* ImprovSerialRPCCommand.SEND_WIFI_SETTINGS */, data, timeout); - this.nextUrl = response[0]; - } - async scan() { - const results = await this._sendRPCWithMultipleResponses(4 /* ImprovSerialRPCCommand.REQUEST_WIFI_NETWORKS */, []); - const ssids = results.map(([name, rssi, secured]) => ({ - name, - rssi: parseInt(rssi), - secured: secured === "YES", - })); - ssids.sort((a, b) => a.name.toLocaleLowerCase().localeCompare(b.name.toLocaleLowerCase())); - return ssids; - } - _sendRPC(command, data) { - this.writePacketToStream(_const_js__WEBPACK_IMPORTED_MODULE_0__.ImprovSerialMessageType.RPC, [ - command, - data.length, - ...data, - ]); - } - async _sendRPCWithResponse(command, data, timeout) { - // Commands that receive feedback will finish when either - // the state changes or the error code becomes not 0. - if (this._rpcFeedback) { - throw new Error("Only 1 RPC command that requires feedback can be active"); - } - return await this._awaitRPCResultWithTimeout(new Promise((resolve, reject) => { - this._rpcFeedback = { command, resolve, reject }; - this._sendRPC(command, data); - }), timeout); - } - async _sendRPCWithMultipleResponses(command, data, timeout) { - // Commands that receive multiple feedbacks will finish when either - // the state changes or the error code becomes not 0. - if (this._rpcFeedback) { - throw new Error("Only 1 RPC command that requires feedback can be active"); - } - return await this._awaitRPCResultWithTimeout(new Promise((resolve, reject) => { - this._rpcFeedback = { - command, - resolve, - reject, - receivedData: [], - }; - this._sendRPC(command, data); - }), timeout); - } - async _awaitRPCResultWithTimeout(sendRPCPromise, timeout) { - if (!timeout) { - return await sendRPCPromise; - } - return await new Promise((resolve, reject) => { - const timeoutRPC = setTimeout(() => this._setError(254 /* ImprovSerialErrorState.TIMEOUT */), timeout); - sendRPCPromise.finally(() => clearTimeout(timeoutRPC)); - sendRPCPromise.then(resolve, reject); - }); - } - async _processInput() { - // read the data from serial port. - // current state, error state, rpc result - this.logger.debug("Starting read loop"); - this._reader = this.port.readable.getReader(); - try { - let line = []; - // undefined = not sure if improv packet - let isImprov; - // length of improv bytes that we expect - let improvLength = 0; - while (true) { - const { value, done } = await this._reader.read(); - if (done) { - break; - } - if (!value || value.length === 0) { - continue; - } - for (const byte of value) { - if (isImprov === false) { - // When it wasn't an improv line, discard everything unti we find new line char - if (byte === 10) { - isImprov = undefined; - } - continue; - } - if (isImprov === true) { - line.push(byte); - if (line.length === improvLength) { - this._handleIncomingPacket(line); - isImprov = undefined; - line = []; - } - continue; - } - if (byte === 10) { - line = []; - continue; - } - line.push(byte); - if (line.length !== 9) { - continue; - } - // Check if it's improv - isImprov = String.fromCharCode(...line.slice(0, 6)) === "IMPROV"; - if (!isImprov) { - line = []; - continue; - } - // Format: - // I M P R O V - // Once we have 9 bytes, we can check if it's an improv packet - // and extract how much more we need to fetch. - const packetLength = line[8]; - improvLength = 9 + packetLength + 1; // header + data length + checksum - } - } - } - catch (err) { - this.logger.error("Error while reading serial port", err); - } - finally { - this._reader.releaseLock(); - this._reader = undefined; - } - this.logger.debug("Finished read loop"); - this.dispatchEvent(new Event("disconnect")); - } - _handleIncomingPacket(line) { - const payload = line.slice(6); - const version = payload[0]; - const packetType = payload[1]; - const packetLength = payload[2]; - const data = payload.slice(3, 3 + packetLength); - this.logger.debug("PROCESS", { - version, - packetType, - packetLength, - data: (0,_util_hex_formatter__WEBPACK_IMPORTED_MODULE_2__.hexFormatter)(data), - }); - if (version !== 1) { - this.logger.error("Received unsupported version", version); - return; - } - // Verify checksum - let packetChecksum = payload[3 + packetLength]; - let calculatedChecksum = 0; - for (let i = 0; i < line.length - 1; i++) { - calculatedChecksum += line[i]; - } - calculatedChecksum = calculatedChecksum & 0xff; - if (calculatedChecksum !== packetChecksum) { - this.logger.error(`Received invalid checksum ${packetChecksum}. Expected ${calculatedChecksum}`); - return; - } - if (packetType === _const_js__WEBPACK_IMPORTED_MODULE_0__.ImprovSerialMessageType.CURRENT_STATE) { - this.state = data[0]; - this.dispatchEvent(new CustomEvent("state-changed", { - detail: this.state, - })); - } - else if (packetType === _const_js__WEBPACK_IMPORTED_MODULE_0__.ImprovSerialMessageType.ERROR_STATE) { - this._setError(data[0]); - } - else if (packetType === _const_js__WEBPACK_IMPORTED_MODULE_0__.ImprovSerialMessageType.RPC_RESULT) { - if (!this._rpcFeedback) { - this.logger.error("Received result while not waiting for one"); - return; - } - const rpcCommand = data[0]; - if (rpcCommand !== this._rpcFeedback.command) { - this.logger.error(`Received result for command ${rpcCommand} but expected ${this._rpcFeedback.command}`); - return; - } - // Chop off rpc command and checksum - const result = []; - const totalLength = data[1]; - let idx = 2; - while (idx < 2 + totalLength) { - result.push(String.fromCodePoint(...data.slice(idx + 1, idx + data[idx] + 1))); - idx += data[idx] + 1; - } - if ("receivedData" in this._rpcFeedback) { - if (result.length > 0) { - this._rpcFeedback.receivedData.push(result); - } - else { - // Result of 0 means we're done. - this._rpcFeedback.resolve(this._rpcFeedback.receivedData); - this._rpcFeedback = undefined; - } - } - else { - this._rpcFeedback.resolve(result); - this._rpcFeedback = undefined; - } - } - else { - this.logger.error("Unable to handle packet", payload); - } - } - /** - * Add header + checksum and write packet to stream - */ - async writePacketToStream(type, data) { - const payload = new Uint8Array([ - ..._const_js__WEBPACK_IMPORTED_MODULE_0__.SERIAL_PACKET_HEADER, - type, - data.length, - ...data, - 0, - 0, // Will be newline - ]); - // Calculate checksum - payload[payload.length - 2] = - payload.reduce((sum, cur) => sum + cur, 0) & 0xff; - payload[payload.length - 1] = 10; // Newline - this.logger.debug("Writing to stream:", (0,_util_hex_formatter__WEBPACK_IMPORTED_MODULE_2__.hexFormatter)(new Array(...payload))); - const writer = this.port.writable.getWriter(); - await writer.write(payload); - try { - writer.releaseLock(); - } - catch (err) { - console.error("Ignoring release lock error", err); - } - } - // Error is either received from device or is a timeout - _setError(error) { - this.error = error; - if (error > 0 && this._rpcFeedback) { - this._rpcFeedback.reject(_const_js__WEBPACK_IMPORTED_MODULE_0__.ERROR_MSGS[error] || `UNKNOWN_ERROR (${error})`); - this._rpcFeedback = undefined; - } - this.dispatchEvent(new CustomEvent("error-changed", { - detail: this.error, - })); - } -} - - -/***/ }), - -/***/ "./node_modules/improv-wifi-serial-sdk/dist/util/hex-formatter.js": -/*!************************************************************************!*\ - !*** ./node_modules/improv-wifi-serial-sdk/dist/util/hex-formatter.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ hexFormatter: () => (/* binding */ hexFormatter) -/* harmony export */ }); -/* harmony import */ var _to_hex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./to-hex */ "./node_modules/improv-wifi-serial-sdk/dist/util/to-hex.js"); - -const hexFormatter = (bytes) => "[" + bytes.map((value) => (0,_to_hex__WEBPACK_IMPORTED_MODULE_0__.toHex)(value)).join(", ") + "]"; - - -/***/ }), - -/***/ "./node_modules/improv-wifi-serial-sdk/dist/util/sleep.js": -/*!****************************************************************!*\ - !*** ./node_modules/improv-wifi-serial-sdk/dist/util/sleep.js ***! - \****************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ sleep: () => (/* binding */ sleep) -/* harmony export */ }); -const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); - - -/***/ }), - -/***/ "./node_modules/improv-wifi-serial-sdk/dist/util/to-hex.js": -/*!*****************************************************************!*\ - !*** ./node_modules/improv-wifi-serial-sdk/dist/util/to-hex.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ toHex: () => (/* binding */ toHex) -/* harmony export */ }); -const toHex = (value, size = 2) => { - let hex = value.toString(16).toUpperCase(); - if (hex.startsWith("-")) { - return "-0x" + hex.substring(1).padStart(size, "0"); - } - else { - return "0x" + hex.padStart(size, "0"); - } -}; - - -/***/ }), - -/***/ "./node_modules/lit-html/development/directive-helpers.js": -/*!****************************************************************!*\ - !*** ./node_modules/lit-html/development/directive-helpers.js ***! - \****************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ TemplateResultType: () => (/* binding */ TemplateResultType), -/* harmony export */ clearPart: () => (/* binding */ clearPart), -/* harmony export */ getCommittedValue: () => (/* binding */ getCommittedValue), -/* harmony export */ getDirectiveClass: () => (/* binding */ getDirectiveClass), -/* harmony export */ insertPart: () => (/* binding */ insertPart), -/* harmony export */ isCompiledTemplateResult: () => (/* binding */ isCompiledTemplateResult), -/* harmony export */ isDirectiveResult: () => (/* binding */ isDirectiveResult), -/* harmony export */ isPrimitive: () => (/* binding */ isPrimitive), -/* harmony export */ isSingleExpression: () => (/* binding */ isSingleExpression), -/* harmony export */ isTemplateResult: () => (/* binding */ isTemplateResult), -/* harmony export */ removePart: () => (/* binding */ removePart), -/* harmony export */ setChildPartValue: () => (/* binding */ setChildPartValue), -/* harmony export */ setCommittedValue: () => (/* binding */ setCommittedValue) -/* harmony export */ }); -/* harmony import */ var _lit_html_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lit-html.js */ "./node_modules/lit-html/development/lit-html.js"); -/** - * @license - * Copyright 2020 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - -const { _ChildPart: ChildPart } = _lit_html_js__WEBPACK_IMPORTED_MODULE_0__._$LH; -const ENABLE_SHADYDOM_NOPATCH = true; -const wrap = ENABLE_SHADYDOM_NOPATCH && - window.ShadyDOM?.inUse && - window.ShadyDOM?.noPatch === true - ? window.ShadyDOM.wrap - : (node) => node; -/** - * Tests if a value is a primitive value. - * - * See https://tc39.github.io/ecma262/#sec-typeof-operator - */ -const isPrimitive = (value) => value === null || (typeof value != 'object' && typeof value != 'function'); -const TemplateResultType = { - HTML: 1, - SVG: 2, - MATHML: 3, -}; -/** - * Tests if a value is a TemplateResult or a CompiledTemplateResult. - */ -const isTemplateResult = (value, type) => type === undefined - ? // This property needs to remain unminified. - value?.['_$litType$'] !== undefined - : value?.['_$litType$'] === type; -/** - * Tests if a value is a CompiledTemplateResult. - */ -const isCompiledTemplateResult = (value) => { - return value?.['_$litType$']?.h != null; -}; -/** - * Tests if a value is a DirectiveResult. - */ -const isDirectiveResult = (value) => -// This property needs to remain unminified. -value?.['_$litDirective$'] !== undefined; -/** - * Retrieves the Directive class for a DirectiveResult - */ -const getDirectiveClass = (value) => -// This property needs to remain unminified. -value?.['_$litDirective$']; -/** - * Tests whether a part has only a single-expression with no strings to - * interpolate between. - * - * Only AttributePart and PropertyPart can have multiple expressions. - * Multi-expression parts have a `strings` property and single-expression - * parts do not. - */ -const isSingleExpression = (part) => part.strings === undefined; -const createMarker = () => document.createComment(''); -/** - * Inserts a ChildPart into the given container ChildPart's DOM, either at the - * end of the container ChildPart, or before the optional `refPart`. - * - * This does not add the part to the containerPart's committed value. That must - * be done by callers. - * - * @param containerPart Part within which to add the new ChildPart - * @param refPart Part before which to add the new ChildPart; when omitted the - * part added to the end of the `containerPart` - * @param part Part to insert, or undefined to create a new part - */ -const insertPart = (containerPart, refPart, part) => { - const container = wrap(containerPart._$startNode).parentNode; - const refNode = refPart === undefined ? containerPart._$endNode : refPart._$startNode; - if (part === undefined) { - const startNode = wrap(container).insertBefore(createMarker(), refNode); - const endNode = wrap(container).insertBefore(createMarker(), refNode); - part = new ChildPart(startNode, endNode, containerPart, containerPart.options); - } - else { - const endNode = wrap(part._$endNode).nextSibling; - const oldParent = part._$parent; - const parentChanged = oldParent !== containerPart; - if (parentChanged) { - part._$reparentDisconnectables?.(containerPart); - // Note that although `_$reparentDisconnectables` updates the part's - // `_$parent` reference after unlinking from its current parent, that - // method only exists if Disconnectables are present, so we need to - // unconditionally set it here - part._$parent = containerPart; - // Since the _$isConnected getter is somewhat costly, only - // read it once we know the subtree has directives that need - // to be notified - let newConnectionState; - if (part._$notifyConnectionChanged !== undefined && - (newConnectionState = containerPart._$isConnected) !== - oldParent._$isConnected) { - part._$notifyConnectionChanged(newConnectionState); - } - } - if (endNode !== refNode || parentChanged) { - let start = part._$startNode; - while (start !== endNode) { - const n = wrap(start).nextSibling; - wrap(container).insertBefore(start, refNode); - start = n; - } - } - } - return part; -}; -/** - * Sets the value of a Part. - * - * Note that this should only be used to set/update the value of user-created - * parts (i.e. those created using `insertPart`); it should not be used - * by directives to set the value of the directive's container part. Directives - * should return a value from `update`/`render` to update their part state. - * - * For directives that require setting their part value asynchronously, they - * should extend `AsyncDirective` and call `this.setValue()`. - * - * @param part Part to set - * @param value Value to set - * @param index For `AttributePart`s, the index to set - * @param directiveParent Used internally; should not be set by user - */ -const setChildPartValue = (part, value, directiveParent = part) => { - part._$setValue(value, directiveParent); - return part; -}; -// A sentinel value that can never appear as a part value except when set by -// live(). Used to force a dirty-check to fail and cause a re-render. -const RESET_VALUE = {}; -/** - * Sets the committed value of a ChildPart directly without triggering the - * commit stage of the part. - * - * This is useful in cases where a directive needs to update the part such - * that the next update detects a value change or not. When value is omitted, - * the next update will be guaranteed to be detected as a change. - * - * @param part - * @param value - */ -const setCommittedValue = (part, value = RESET_VALUE) => (part._$committedValue = value); -/** - * Returns the committed value of a ChildPart. - * - * The committed value is used for change detection and efficient updates of - * the part. It can differ from the value set by the template or directive in - * cases where the template value is transformed before being committed. - * - * - `TemplateResult`s are committed as a `TemplateInstance` - * - Iterables are committed as `Array` - * - All other types are committed as the template value or value returned or - * set by a directive. - * - * @param part - */ -const getCommittedValue = (part) => part._$committedValue; -/** - * Removes a ChildPart from the DOM, including any of its content. - * - * @param part The Part to remove - */ -const removePart = (part) => { - part._$notifyConnectionChanged?.(false, true); - let start = part._$startNode; - const end = wrap(part._$endNode).nextSibling; - while (start !== end) { - const n = wrap(start).nextSibling; - wrap(start).remove(); - start = n; - } -}; -const clearPart = (part) => { - part._$clear(); -}; -//# sourceMappingURL=directive-helpers.js.map - -/***/ }), - -/***/ "./node_modules/lit-html/development/directives/live.js": -/*!**************************************************************!*\ - !*** ./node_modules/lit-html/development/directives/live.js ***! - \**************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ live: () => (/* binding */ live) -/* harmony export */ }); -/* harmony import */ var _lit_html_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../lit-html.js */ "./node_modules/lit-html/development/lit-html.js"); -/* harmony import */ var _directive_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../directive.js */ "./node_modules/lit-html/development/directive.js"); -/* harmony import */ var _directive_helpers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../directive-helpers.js */ "./node_modules/lit-html/development/directive-helpers.js"); -/** - * @license - * Copyright 2020 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - - - -class LiveDirective extends _directive_js__WEBPACK_IMPORTED_MODULE_1__.Directive { - constructor(partInfo) { - super(partInfo); - if (!(partInfo.type === _directive_js__WEBPACK_IMPORTED_MODULE_1__.PartType.PROPERTY || - partInfo.type === _directive_js__WEBPACK_IMPORTED_MODULE_1__.PartType.ATTRIBUTE || - partInfo.type === _directive_js__WEBPACK_IMPORTED_MODULE_1__.PartType.BOOLEAN_ATTRIBUTE)) { - throw new Error('The `live` directive is not allowed on child or event bindings'); - } - if (!(0,_directive_helpers_js__WEBPACK_IMPORTED_MODULE_2__.isSingleExpression)(partInfo)) { - throw new Error('`live` bindings can only contain a single expression'); - } - } - render(value) { - return value; - } - update(part, [value]) { - if (value === _lit_html_js__WEBPACK_IMPORTED_MODULE_0__.noChange || value === _lit_html_js__WEBPACK_IMPORTED_MODULE_0__.nothing) { - return value; - } - const element = part.element; - const name = part.name; - if (part.type === _directive_js__WEBPACK_IMPORTED_MODULE_1__.PartType.PROPERTY) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if (value === element[name]) { - return _lit_html_js__WEBPACK_IMPORTED_MODULE_0__.noChange; - } - } - else if (part.type === _directive_js__WEBPACK_IMPORTED_MODULE_1__.PartType.BOOLEAN_ATTRIBUTE) { - if (!!value === element.hasAttribute(name)) { - return _lit_html_js__WEBPACK_IMPORTED_MODULE_0__.noChange; - } - } - else if (part.type === _directive_js__WEBPACK_IMPORTED_MODULE_1__.PartType.ATTRIBUTE) { - if (element.getAttribute(name) === String(value)) { - return _lit_html_js__WEBPACK_IMPORTED_MODULE_0__.noChange; - } - } - // Resets the part's value, causing its dirty-check to fail so that it - // always sets the value. - (0,_directive_helpers_js__WEBPACK_IMPORTED_MODULE_2__.setCommittedValue)(part); - return value; - } -} -/** - * Checks binding values against live DOM values, instead of previously bound - * values, when determining whether to update the value. - * - * This is useful for cases where the DOM value may change from outside of - * lit-html, such as with a binding to an `` element's `value` property, - * a content editable elements text, or to a custom element that changes it's - * own properties or attributes. - * - * In these cases if the DOM value changes, but the value set through lit-html - * bindings hasn't, lit-html won't know to update the DOM value and will leave - * it alone. If this is not what you want--if you want to overwrite the DOM - * value with the bound value no matter what--use the `live()` directive: - * - * ```js - * html`` - * ``` - * - * `live()` performs a strict equality check against the live DOM value, and if - * the new value is equal to the live value, does nothing. This means that - * `live()` should not be used when the binding will cause a type conversion. If - * you use `live()` with an attribute binding, make sure that only strings are - * passed in, or the binding will update every render. - */ -const live = (0,_directive_js__WEBPACK_IMPORTED_MODULE_1__.directive)(LiveDirective); -//# sourceMappingURL=live.js.map - -/***/ }), - -/***/ "./node_modules/lit-html/development/directives/style-map.js": -/*!*******************************************************************!*\ - !*** ./node_modules/lit-html/development/directives/style-map.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styleMap: () => (/* binding */ styleMap) -/* harmony export */ }); -/* harmony import */ var _lit_html_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../lit-html.js */ "./node_modules/lit-html/development/lit-html.js"); -/* harmony import */ var _directive_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../directive.js */ "./node_modules/lit-html/development/directive.js"); -/** - * @license - * Copyright 2018 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ - - -const important = 'important'; -// The leading space is important -const importantFlag = ' !' + important; -// How many characters to remove from a value, as a negative number -const flagTrim = 0 - importantFlag.length; -class StyleMapDirective extends _directive_js__WEBPACK_IMPORTED_MODULE_1__.Directive { - constructor(partInfo) { - super(partInfo); - if (partInfo.type !== _directive_js__WEBPACK_IMPORTED_MODULE_1__.PartType.ATTRIBUTE || - partInfo.name !== 'style' || - partInfo.strings?.length > 2) { - throw new Error('The `styleMap` directive must be used in the `style` attribute ' + - 'and must be the only part in the attribute.'); - } - } - render(styleInfo) { - return Object.keys(styleInfo).reduce((style, prop) => { - const value = styleInfo[prop]; - if (value == null) { - return style; - } - // Convert property names from camel-case to dash-case, i.e.: - // `backgroundColor` -> `background-color` - // Vendor-prefixed names need an extra `-` appended to front: - // `webkitAppearance` -> `-webkit-appearance` - // Exception is any property name containing a dash, including - // custom properties; we assume these are already dash-cased i.e.: - // `--my-button-color` --> `--my-button-color` - prop = prop.includes('-') - ? prop - : prop - .replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, '-$&') - .toLowerCase(); - return style + `${prop}:${value};`; - }, ''); - } - update(part, [styleInfo]) { - const { style } = part.element; - if (this._previousStyleProperties === undefined) { - this._previousStyleProperties = new Set(Object.keys(styleInfo)); - return this.render(styleInfo); - } - // Remove old properties that no longer exist in styleInfo - for (const name of this._previousStyleProperties) { - // If the name isn't in styleInfo or it's null/undefined - if (styleInfo[name] == null) { - this._previousStyleProperties.delete(name); - if (name.includes('-')) { - style.removeProperty(name); - } - else { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - style[name] = null; - } - } - } - // Add or update properties - for (const name in styleInfo) { - const value = styleInfo[name]; - if (value != null) { - this._previousStyleProperties.add(name); - const isImportant = typeof value === 'string' && value.endsWith(importantFlag); - if (name.includes('-') || isImportant) { - style.setProperty(name, isImportant - ? value.slice(0, flagTrim) - : value, isImportant ? important : ''); - } - else { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - style[name] = value; - } - } - } - return _lit_html_js__WEBPACK_IMPORTED_MODULE_0__.noChange; - } -} -/** - * A directive that applies CSS properties to an element. - * - * `styleMap` can only be used in the `style` attribute and must be the only - * expression in the attribute. It takes the property names in the - * {@link StyleInfo styleInfo} object and adds the properties to the inline - * style of the element. - * - * Property names with dashes (`-`) are assumed to be valid CSS - * property names and set on the element's style object using `setProperty()`. - * Names without dashes are assumed to be camelCased JavaScript property names - * and set on the element's style object using property assignment, allowing the - * style object to translate JavaScript-style names to CSS property names. - * - * For example `styleMap({backgroundColor: 'red', 'border-top': '5px', '--size': - * '0'})` sets the `background-color`, `border-top` and `--size` properties. - * - * @param styleInfo - * @see {@link https://lit.dev/docs/templates/directives/#stylemap styleMap code samples on Lit.dev} - */ -const styleMap = (0,_directive_js__WEBPACK_IMPORTED_MODULE_1__.directive)(StyleMapDirective); -//# sourceMappingURL=style-map.js.map - -/***/ }), - -/***/ "./node_modules/lit-html/development/static.js": -/*!*****************************************************!*\ - !*** ./node_modules/lit-html/development/static.js ***! - \*****************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ html: () => (/* binding */ html), -/* harmony export */ literal: () => (/* binding */ literal), -/* harmony export */ mathml: () => (/* binding */ mathml), -/* harmony export */ svg: () => (/* binding */ svg), -/* harmony export */ unsafeStatic: () => (/* binding */ unsafeStatic), -/* harmony export */ withStatic: () => (/* binding */ withStatic) -/* harmony export */ }); -/* harmony import */ var _lit_html_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lit-html.js */ "./node_modules/lit-html/development/lit-html.js"); -/** - * @license - * Copyright 2020 Google LLC - * SPDX-License-Identifier: BSD-3-Clause - */ -// Any new exports need to be added to the export statement in -// `packages/lit/src/index.all.ts`. - -/** - * Prevents JSON injection attacks. - * - * The goals of this brand: - * 1) fast to check - * 2) code is small on the wire - * 3) multiple versions of Lit in a single page will all produce mutually - * interoperable StaticValues - * 4) normal JSON.parse (without an unusual reviver) can not produce a - * StaticValue - * - * Symbols satisfy (1), (2), and (4). We use Symbol.for to satisfy (3), but - * we don't care about the key, so we break ties via (2) and use the empty - * string. - */ -const brand = Symbol.for(''); -/** Safely extracts the string part of a StaticValue. */ -const unwrapStaticValue = (value) => { - if (value?.r !== brand) { - return undefined; - } - return value?.['_$litStatic$']; -}; -/** - * Wraps a string so that it behaves like part of the static template - * strings instead of a dynamic value. - * - * Users must take care to ensure that adding the static string to the template - * results in well-formed HTML, or else templates may break unexpectedly. - * - * Note that this function is unsafe to use on untrusted content, as it will be - * directly parsed into HTML. Do not pass user input to this function - * without sanitizing it. - * - * Static values can be changed, but they will cause a complete re-render - * since they effectively create a new template. - */ -const unsafeStatic = (value) => ({ - ['_$litStatic$']: value, - r: brand, -}); -const textFromStatic = (value) => { - if (value['_$litStatic$'] !== undefined) { - return value['_$litStatic$']; - } - else { - throw new Error(`Value passed to 'literal' function must be a 'literal' result: ${value}. Use 'unsafeStatic' to pass non-literal values, but - take care to ensure page security.`); - } -}; -/** - * Tags a string literal so that it behaves like part of the static template - * strings instead of a dynamic value. - * - * The only values that may be used in template expressions are other tagged - * `literal` results or `unsafeStatic` values (note that untrusted content - * should never be passed to `unsafeStatic`). - * - * Users must take care to ensure that adding the static string to the template - * results in well-formed HTML, or else templates may break unexpectedly. - * - * Static values can be changed, but they will cause a complete re-render since - * they effectively create a new template. - */ -const literal = (strings, ...values) => ({ - ['_$litStatic$']: values.reduce((acc, v, idx) => acc + textFromStatic(v) + strings[idx + 1], strings[0]), - r: brand, -}); -const stringsCache = new Map(); -/** - * Wraps a lit-html template tag (`html` or `svg`) to add static value support. - */ -const withStatic = (coreTag) => (strings, ...values) => { - const l = values.length; - let staticValue; - let dynamicValue; - const staticStrings = []; - const dynamicValues = []; - let i = 0; - let hasStatics = false; - let s; - while (i < l) { - s = strings[i]; - // Collect any unsafeStatic values, and their following template strings - // so that we treat a run of template strings and unsafe static values as - // a single template string. - while (i < l && - ((dynamicValue = values[i]), - (staticValue = unwrapStaticValue(dynamicValue))) !== undefined) { - s += staticValue + strings[++i]; - hasStatics = true; - } - // If the last value is static, we don't need to push it. - if (i !== l) { - dynamicValues.push(dynamicValue); - } - staticStrings.push(s); - i++; - } - // If the last value isn't static (which would have consumed the last - // string), then we need to add the last string. - if (i === l) { - staticStrings.push(strings[l]); - } - if (hasStatics) { - const key = staticStrings.join('$$lit$$'); - strings = stringsCache.get(key); - if (strings === undefined) { - // Beware: in general this pattern is unsafe, and doing so may bypass - // lit's security checks and allow an attacker to execute arbitrary - // code and inject arbitrary content. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - staticStrings.raw = staticStrings; - stringsCache.set(key, (strings = staticStrings)); - } - values = dynamicValues; - } - return coreTag(strings, ...values); -}; -/** - * Interprets a template literal as an HTML template that can efficiently - * render to and update a container. - * - * Includes static value support from `lit-html/static.js`. - */ -const html = withStatic(_lit_html_js__WEBPACK_IMPORTED_MODULE_0__.html); -/** - * Interprets a template literal as an SVG template that can efficiently - * render to and update a container. - * - * Includes static value support from `lit-html/static.js`. - */ -const svg = withStatic(_lit_html_js__WEBPACK_IMPORTED_MODULE_0__.svg); -/** - * Interprets a template literal as MathML fragment that can efficiently render - * to and update a container. - * - * Includes static value support from `lit-html/static.js`. - */ -const mathml = withStatic(_lit_html_js__WEBPACK_IMPORTED_MODULE_0__.mathml); -//# sourceMappingURL=static.js.map - -/***/ }), - -/***/ "./node_modules/lit/directives/live.js": -/*!*********************************************!*\ - !*** ./node_modules/lit/directives/live.js ***! - \*********************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ live: () => (/* reexport safe */ lit_html_directives_live_js__WEBPACK_IMPORTED_MODULE_0__.live) -/* harmony export */ }); -/* harmony import */ var lit_html_directives_live_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit-html/directives/live.js */ "./node_modules/lit-html/development/directives/live.js"); - -//# sourceMappingURL=live.js.map - - -/***/ }), - -/***/ "./node_modules/lit/directives/style-map.js": -/*!**************************************************!*\ - !*** ./node_modules/lit/directives/style-map.js ***! - \**************************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ styleMap: () => (/* reexport safe */ lit_html_directives_style_map_js__WEBPACK_IMPORTED_MODULE_0__.styleMap) -/* harmony export */ }); -/* harmony import */ var lit_html_directives_style_map_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit-html/directives/style-map.js */ "./node_modules/lit-html/development/directives/style-map.js"); - -//# sourceMappingURL=style-map.js.map - - -/***/ }), - -/***/ "./node_modules/lit/static-html.js": -/*!*****************************************!*\ - !*** ./node_modules/lit/static-html.js ***! - \*****************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ html: () => (/* reexport safe */ lit_html_static_js__WEBPACK_IMPORTED_MODULE_0__.html), -/* harmony export */ literal: () => (/* reexport safe */ lit_html_static_js__WEBPACK_IMPORTED_MODULE_0__.literal), -/* harmony export */ mathml: () => (/* reexport safe */ lit_html_static_js__WEBPACK_IMPORTED_MODULE_0__.mathml), -/* harmony export */ svg: () => (/* reexport safe */ lit_html_static_js__WEBPACK_IMPORTED_MODULE_0__.svg), -/* harmony export */ unsafeStatic: () => (/* reexport safe */ lit_html_static_js__WEBPACK_IMPORTED_MODULE_0__.unsafeStatic), -/* harmony export */ withStatic: () => (/* reexport safe */ lit_html_static_js__WEBPACK_IMPORTED_MODULE_0__.withStatic) -/* harmony export */ }); -/* harmony import */ var lit_html_static_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lit-html/static.js */ "./node_modules/lit-html/development/static.js"); - -//# sourceMappingURL=static-html.js.map - - -/***/ }), - -/***/ "./node_modules/pako/dist/pako.esm.mjs": -/*!*********************************************!*\ - !*** ./node_modules/pako/dist/pako.esm.mjs ***! - \*********************************************/ -/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Deflate: () => (/* binding */ Deflate_1), -/* harmony export */ Inflate: () => (/* binding */ Inflate_1), -/* harmony export */ constants: () => (/* binding */ constants_1), -/* harmony export */ "default": () => (/* binding */ pako), -/* harmony export */ deflate: () => (/* binding */ deflate_1), -/* harmony export */ deflateRaw: () => (/* binding */ deflateRaw_1), -/* harmony export */ gzip: () => (/* binding */ gzip_1), -/* harmony export */ inflate: () => (/* binding */ inflate_1), -/* harmony export */ inflateRaw: () => (/* binding */ inflateRaw_1), -/* harmony export */ ungzip: () => (/* binding */ ungzip_1) -/* harmony export */ }); - -/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */ -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -/* eslint-disable space-unary-ops */ - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - - -//const Z_FILTERED = 1; -//const Z_HUFFMAN_ONLY = 2; -//const Z_RLE = 3; -const Z_FIXED$1 = 4; -//const Z_DEFAULT_STRATEGY = 0; - -/* Possible values of the data_type field (though see inflate()) */ -const Z_BINARY = 0; -const Z_TEXT = 1; -//const Z_ASCII = 1; // = Z_TEXT -const Z_UNKNOWN$1 = 2; - -/*============================================================================*/ - - -function zero$1(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } } - -// From zutil.h - -const STORED_BLOCK = 0; -const STATIC_TREES = 1; -const DYN_TREES = 2; -/* The three kinds of block type */ - -const MIN_MATCH$1 = 3; -const MAX_MATCH$1 = 258; -/* The minimum and maximum match lengths */ - -// From deflate.h -/* =========================================================================== - * Internal compression state. - */ - -const LENGTH_CODES$1 = 29; -/* number of length codes, not counting the special END_BLOCK code */ - -const LITERALS$1 = 256; -/* number of literal bytes 0..255 */ - -const L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1; -/* number of Literal or Length codes, including the END_BLOCK code */ - -const D_CODES$1 = 30; -/* number of distance codes */ - -const BL_CODES$1 = 19; -/* number of codes used to transfer the bit lengths */ - -const HEAP_SIZE$1 = 2 * L_CODES$1 + 1; -/* maximum heap size */ - -const MAX_BITS$1 = 15; -/* All codes must not exceed MAX_BITS bits */ - -const Buf_size = 16; -/* size of bit buffer in bi_buf */ - - -/* =========================================================================== - * Constants - */ - -const MAX_BL_BITS = 7; -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -const END_BLOCK = 256; -/* end of block literal code */ - -const REP_3_6 = 16; -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -const REPZ_3_10 = 17; -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -const REPZ_11_138 = 18; -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -/* eslint-disable comma-spacing,array-bracket-spacing */ -const extra_lbits = /* extra bits for each length code */ - new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]); - -const extra_dbits = /* extra bits for each distance code */ - new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]); - -const extra_blbits = /* extra bits for each bit length code */ - new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]); - -const bl_order = - new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]); -/* eslint-enable comma-spacing,array-bracket-spacing */ - -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -// We pre-fill arrays with 0 to avoid uninitialized gaps - -const DIST_CODE_LEN = 512; /* see definition of array dist_code below */ - -// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 -const static_ltree = new Array((L_CODES$1 + 2) * 2); -zero$1(static_ltree); -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -const static_dtree = new Array(D_CODES$1 * 2); -zero$1(static_dtree); -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -const _dist_code = new Array(DIST_CODE_LEN); -zero$1(_dist_code); -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -const _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1); -zero$1(_length_code); -/* length code for each normalized match length (0 == MIN_MATCH) */ - -const base_length = new Array(LENGTH_CODES$1); -zero$1(base_length); -/* First normalized length for each code (0 = MIN_MATCH) */ - -const base_dist = new Array(D_CODES$1); -zero$1(base_dist); -/* First normalized distance for each code (0 = distance of 1) */ - - -function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { - - this.static_tree = static_tree; /* static tree or NULL */ - this.extra_bits = extra_bits; /* extra bits for each code or NULL */ - this.extra_base = extra_base; /* base index for extra_bits */ - this.elems = elems; /* max number of elements in the tree */ - this.max_length = max_length; /* max bit length for the codes */ - - // show if `static_tree` has data or dummy - needed for monomorphic objects - this.has_stree = static_tree && static_tree.length; -} - - -let static_l_desc; -let static_d_desc; -let static_bl_desc; - - -function TreeDesc(dyn_tree, stat_desc) { - this.dyn_tree = dyn_tree; /* the dynamic tree */ - this.max_code = 0; /* largest code with non zero frequency */ - this.stat_desc = stat_desc; /* the corresponding static tree */ -} - - - -const d_code = (dist) => { - - return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; -}; - - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -const put_short = (s, w) => { -// put_byte(s, (uch)((w) & 0xff)); -// put_byte(s, (uch)((ush)(w) >> 8)); - s.pending_buf[s.pending++] = (w) & 0xff; - s.pending_buf[s.pending++] = (w >>> 8) & 0xff; -}; - - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -const send_bits = (s, value, length) => { - - if (s.bi_valid > (Buf_size - length)) { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - put_short(s, s.bi_buf); - s.bi_buf = value >> (Buf_size - s.bi_valid); - s.bi_valid += length - Buf_size; - } else { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - s.bi_valid += length; - } -}; - - -const send_code = (s, c, tree) => { - - send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); -}; - - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -const bi_reverse = (code, len) => { - - let res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; -}; - - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -const bi_flush = (s) => { - - if (s.bi_valid === 16) { - put_short(s, s.bi_buf); - s.bi_buf = 0; - s.bi_valid = 0; - - } else if (s.bi_valid >= 8) { - s.pending_buf[s.pending++] = s.bi_buf & 0xff; - s.bi_buf >>= 8; - s.bi_valid -= 8; - } -}; - - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -const gen_bitlen = (s, desc) => { -// deflate_state *s; -// tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const max_code = desc.max_code; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const extra = desc.stat_desc.extra_bits; - const base = desc.stat_desc.extra_base; - const max_length = desc.stat_desc.max_length; - let h; /* heap index */ - let n, m; /* iterate over the tree elements */ - let bits; /* bit length */ - let xbits; /* extra bits */ - let f; /* frequency */ - let overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS$1; bits++) { - s.bl_count[bits] = 0; - } - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ - - for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1]/*.Len*/ = bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) { continue; } /* not a leaf node */ - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) { - xbits = extra[n - base]; - } - f = tree[n * 2]/*.Freq*/; - s.opt_len += f * (bits + xbits); - if (has_stree) { - s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); - } - } - if (overflow === 0) { return; } - - // Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) { bits--; } - s.bl_count[bits]--; /* move one leaf down the tree */ - s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > max_code) { continue; } - if (tree[m * 2 + 1]/*.Len*/ !== bits) { - // Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; - tree[m * 2 + 1]/*.Len*/ = bits; - } - n--; - } - } -}; - - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -const gen_codes = (tree, max_code, bl_count) => { -// ct_data *tree; /* the tree to decorate */ -// int max_code; /* largest code with non zero frequency */ -// ushf *bl_count; /* number of codes at each bit length */ - - const next_code = new Array(MAX_BITS$1 + 1); /* next code value for each bit length */ - let code = 0; /* running code value */ - let bits; /* bit index */ - let n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS$1; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - //Assert (code + bl_count[MAX_BITS]-1 == (1< { - - let n; /* iterates over tree elements */ - let bits; /* bit counter */ - let length; /* length value */ - let code; /* code value */ - let dist; /* distance index */ - const bl_count = new Array(MAX_BITS$1 + 1); - /* number of codes at each bit length for an optimal tree */ - - // do check in _tr_init() - //if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -/*#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif*/ - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES$1 - 1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = code; - } - } - //Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length - 1] = code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES$1; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code[256 + dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS$1; bits++) { - bl_count[bits] = 0; - } - - n = 0; - while (n <= 143) { - static_ltree[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - while (n <= 255) { - static_ltree[n * 2 + 1]/*.Len*/ = 9; - n++; - bl_count[9]++; - } - while (n <= 279) { - static_ltree[n * 2 + 1]/*.Len*/ = 7; - n++; - bl_count[7]++; - } - while (n <= 287) { - static_ltree[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes(static_ltree, L_CODES$1 + 1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES$1; n++) { - static_dtree[n * 2 + 1]/*.Len*/ = 5; - static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5); - } - - // Now data ready and we can init static trees - static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS$1 + 1, L_CODES$1, MAX_BITS$1); - static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES$1, MAX_BITS$1); - static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS); - - //static_init_done = true; -}; - - -/* =========================================================================== - * Initialize a new block. - */ -const init_block = (s) => { - - let n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES$1; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < D_CODES$1; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < BL_CODES$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } - - s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; - s.opt_len = s.static_len = 0; - s.sym_next = s.matches = 0; -}; - - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -const bi_windup = (s) => -{ - if (s.bi_valid > 8) { - put_short(s, s.bi_buf); - } else if (s.bi_valid > 0) { - //put_byte(s, (Byte)s->bi_buf); - s.pending_buf[s.pending++] = s.bi_buf; - } - s.bi_buf = 0; - s.bi_valid = 0; -}; - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -const smaller = (tree, n, m, depth) => { - - const _n2 = n * 2; - const _m2 = m * 2; - return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || - (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); -}; - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -const pqdownheap = (s, tree, k) => { -// deflate_state *s; -// ct_data *tree; /* the tree to restore */ -// int k; /* node to move down */ - - const v = s.heap[k]; - let j = k << 1; /* left son of k */ - while (j <= s.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s.heap_len && - smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s.heap[j], s.depth)) { break; } - - /* Exchange v with the smallest son */ - s.heap[k] = s.heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s.heap[k] = v; -}; - - -// inlined manually -// const SMALLEST = 1; - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -const compress_block = (s, ltree, dtree) => { -// deflate_state *s; -// const ct_data *ltree; /* literal tree */ -// const ct_data *dtree; /* distance tree */ - - let dist; /* distance of matched string */ - let lc; /* match length or unmatched char (if dist == 0) */ - let sx = 0; /* running index in sym_buf */ - let code; /* the code to send */ - let extra; /* number of extra bits to send */ - - if (s.sym_next !== 0) { - do { - dist = s.pending_buf[s.sym_buf + sx++] & 0xff; - dist += (s.pending_buf[s.sym_buf + sx++] & 0xff) << 8; - lc = s.pending_buf[s.sym_buf + sx++]; - if (dist === 0) { - send_code(s, lc, ltree); /* send a literal byte */ - //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS$1 + 1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra !== 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - //Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra !== 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - //Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s.sym_next); - } - - send_code(s, END_BLOCK, ltree); -}; - - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -const build_tree = (s, desc) => { -// deflate_state *s; -// tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const elems = desc.stat_desc.elems; - let n, m; /* iterate over heap elements */ - let max_code = -1; /* largest code with non zero frequency */ - let node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s.heap_len = 0; - s.heap_max = HEAP_SIZE$1; - - for (n = 0; n < elems; n++) { - if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; - - } else { - tree[n * 2 + 1]/*.Len*/ = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[node * 2]/*.Freq*/ = 1; - s.depth[node] = 0; - s.opt_len--; - - if (has_stree) { - s.static_len -= stree[node * 2 + 1]/*.Len*/; - } - /* node is 0 or 1 so it does not have extra bits */ - } - desc.max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - //pqremove(s, tree, n); /* n = node of least frequency */ - /*** pqremove ***/ - n = s.heap[1/*SMALLEST*/]; - s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; - pqdownheap(s, tree, 1/*SMALLEST*/); - /***/ - - m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - - s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ - s.heap[--s.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; - s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; - tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - - /* and insert the new node in the heap */ - s.heap[1/*SMALLEST*/] = node++; - pqdownheap(s, tree, 1/*SMALLEST*/); - - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes(tree, max_code, s.bl_count); -}; - - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -const scan_tree = (s, tree, max_code) => { -// deflate_state *s; -// ct_data *tree; /* the tree to be scanned */ -// int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - s.bl_tree[curlen * 2]/*.Freq*/ += count; - - } else if (curlen !== 0) { - - if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } - s.bl_tree[REP_3_6 * 2]/*.Freq*/++; - - } else if (count <= 10) { - s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; - - } else { - s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; - } - - count = 0; - prevlen = curlen; - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } -}; - - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -const send_tree = (s, tree, max_code) => { -// deflate_state *s; -// ct_data *tree; /* the tree to be scanned */ -// int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); - - } else if (curlen !== 0) { - if (curlen !== prevlen) { - send_code(s, curlen, s.bl_tree); - count--; - } - //Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s.bl_tree); - send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s.bl_tree); - send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s.bl_tree); - send_bits(s, count - 11, 7); - } - - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } -}; - - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -const build_bl_tree = (s) => { - - let max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, s.dyn_ltree, s.l_desc.max_code); - scan_tree(s, s.dyn_dtree, s.d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, s.bl_desc); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) { - if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { - break; - } - } - /* Update opt_len to include the bit length tree and counts */ - s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - // s->opt_len, s->static_len)); - - return max_blindex; -}; - - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -const send_all_trees = (s, lcodes, dcodes, blcodes) => { -// deflate_state *s; -// int lcodes, dcodes, blcodes; /* number of codes for each tree */ - - let rank; /* index in bl_order */ - - //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - // "too many codes"); - //Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); - } - //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ - //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ - //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -}; - - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -const detect_data_type = (s) => { - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - let block_mask = 0xf3ffc07f; - let n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>>= 1) { - if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { - return Z_BINARY; - } - } - - /* Check for textual ("allow-listed") bytes. */ - if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || - s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - for (n = 32; n < LITERALS$1; n++) { - if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - } - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -}; - - -let static_init_done = false; - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -const _tr_init$1 = (s) => -{ - - if (!static_init_done) { - tr_static_init(); - static_init_done = true; - } - - s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); - s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); - s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); - - s.bi_buf = 0; - s.bi_valid = 0; - - /* Initialize the first block of the first file: */ - init_block(s); -}; - - -/* =========================================================================== - * Send a stored block - */ -const _tr_stored_block$1 = (s, buf, stored_len, last) => { -//DeflateState *s; -//charf *buf; /* input block */ -//ulg stored_len; /* length of input block */ -//int last; /* one if this is the last block for a file */ - - send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, stored_len); - put_short(s, ~stored_len); - if (stored_len) { - s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending); - } - s.pending += stored_len; -}; - - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -const _tr_align$1 = (s) => { - send_bits(s, STATIC_TREES << 1, 3); - send_code(s, END_BLOCK, static_ltree); - bi_flush(s); -}; - - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -const _tr_flush_block$1 = (s, buf, stored_len, last) => { -//DeflateState *s; -//charf *buf; /* input block, or NULL if too old */ -//ulg stored_len; /* length of input block */ -//int last; /* one if this is the last block for a file */ - - let opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - let max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s.level > 0) { - - /* Check if the file is binary or text */ - if (s.strm.data_type === Z_UNKNOWN$1) { - s.strm.data_type = detect_data_type(s); - } - - /* Construct the literal and distance trees */ - build_tree(s, s.l_desc); - // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - - build_tree(s, s.d_desc); - // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s.opt_len + 3 + 7) >>> 3; - static_lenb = (s.static_len + 3 + 7) >>> 3; - - // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - // s->sym_next / 3)); - - if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } - - } else { - // Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { - /* 4: two words for the lengths */ - - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block$1(s, buf, stored_len, last); - - } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) { - - send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); - compress_block(s, static_ltree, static_dtree); - - } else { - send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); - send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); - compress_block(s, s.dyn_ltree, s.dyn_dtree); - } - // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); - } - // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - // s->compressed_len-7*last)); -}; - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -const _tr_tally$1 = (s, dist, lc) => { -// deflate_state *s; -// unsigned dist; /* distance of matched string */ -// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - - s.pending_buf[s.sym_buf + s.sym_next++] = dist; - s.pending_buf[s.sym_buf + s.sym_next++] = dist >> 8; - s.pending_buf[s.sym_buf + s.sym_next++] = lc; - if (dist === 0) { - /* lc is the unmatched char */ - s.dyn_ltree[lc * 2]/*.Freq*/++; - } else { - s.matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - //Assert((ush)dist < (ush)MAX_DIST(s) && - // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s.dyn_ltree[(_length_code[lc] + LITERALS$1 + 1) * 2]/*.Freq*/++; - s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; - } - - return (s.sym_next === s.sym_end); -}; - -var _tr_init_1 = _tr_init$1; -var _tr_stored_block_1 = _tr_stored_block$1; -var _tr_flush_block_1 = _tr_flush_block$1; -var _tr_tally_1 = _tr_tally$1; -var _tr_align_1 = _tr_align$1; - -var trees = { - _tr_init: _tr_init_1, - _tr_stored_block: _tr_stored_block_1, - _tr_flush_block: _tr_flush_block_1, - _tr_tally: _tr_tally_1, - _tr_align: _tr_align_1 -}; - -// Note: adler32 takes 12% for level 0 and 2% for level 6. -// It isn't worth it to make additional optimizations as in original. -// Small size is preferable. - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const adler32 = (adler, buf, len, pos) => { - let s1 = (adler & 0xffff) |0, - s2 = ((adler >>> 16) & 0xffff) |0, - n = 0; - - while (len !== 0) { - // Set limit ~ twice less than 5552, to keep - // s2 in 31-bits, because we force signed ints. - // in other case %= will fail. - n = len > 2000 ? 2000 : len; - len -= n; - - do { - s1 = (s1 + buf[pos++]) |0; - s2 = (s2 + s1) |0; - } while (--n); - - s1 %= 65521; - s2 %= 65521; - } - - return (s1 | (s2 << 16)) |0; -}; - - -var adler32_1 = adler32; - -// Note: we can't get significant speed boost here. -// So write code to minimize size - no pregenerated tables -// and array tools dependencies. - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -// Use ordinary array, since untyped makes no boost here -const makeTable = () => { - let c, table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - table[n] = c; - } - - return table; -}; - -// Create table on load. Just 255 signed longs. Not a problem. -const crcTable = new Uint32Array(makeTable()); - - -const crc32 = (crc, buf, len, pos) => { - const t = crcTable; - const end = pos + len; - - crc ^= -1; - - for (let i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; - } - - return (crc ^ (-1)); // >>> 0; -}; - - -var crc32_1 = crc32; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -var messages = { - 2: 'need dictionary', /* Z_NEED_DICT 2 */ - 1: 'stream end', /* Z_STREAM_END 1 */ - 0: '', /* Z_OK 0 */ - '-1': 'file error', /* Z_ERRNO (-1) */ - '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ - '-3': 'data error', /* Z_DATA_ERROR (-3) */ - '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ - '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ - '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -var constants$2 = { - - /* Allowed flush values; see deflate() and inflate() below for details */ - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - //Z_VERSION_ERROR: -6, - - /* compression levels */ - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - - - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - - /* Possible values of the data_type field (though see inflate()) */ - Z_BINARY: 0, - Z_TEXT: 1, - //Z_ASCII: 1, // = Z_TEXT (deprecated) - Z_UNKNOWN: 2, - - /* The deflate compression method */ - Z_DEFLATED: 8 - //Z_NULL: null // Use -1 or null inline, depending on var type -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const { _tr_init, _tr_stored_block, _tr_flush_block, _tr_tally, _tr_align } = trees; - - - - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH: Z_NO_FLUSH$2, Z_PARTIAL_FLUSH, Z_FULL_FLUSH: Z_FULL_FLUSH$1, Z_FINISH: Z_FINISH$3, Z_BLOCK: Z_BLOCK$1, - Z_OK: Z_OK$3, Z_STREAM_END: Z_STREAM_END$3, Z_STREAM_ERROR: Z_STREAM_ERROR$2, Z_DATA_ERROR: Z_DATA_ERROR$2, Z_BUF_ERROR: Z_BUF_ERROR$1, - Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1, - Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED, Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1, - Z_UNKNOWN, - Z_DEFLATED: Z_DEFLATED$2 -} = constants$2; - -/*============================================================================*/ - - -const MAX_MEM_LEVEL = 9; -/* Maximum value for memLevel in deflateInit2 */ -const MAX_WBITS$1 = 15; -/* 32K LZ77 window */ -const DEF_MEM_LEVEL = 8; - - -const LENGTH_CODES = 29; -/* number of length codes, not counting the special END_BLOCK code */ -const LITERALS = 256; -/* number of literal bytes 0..255 */ -const L_CODES = LITERALS + 1 + LENGTH_CODES; -/* number of Literal or Length codes, including the END_BLOCK code */ -const D_CODES = 30; -/* number of distance codes */ -const BL_CODES = 19; -/* number of codes used to transfer the bit lengths */ -const HEAP_SIZE = 2 * L_CODES + 1; -/* maximum heap size */ -const MAX_BITS = 15; -/* All codes must not exceed MAX_BITS bits */ - -const MIN_MATCH = 3; -const MAX_MATCH = 258; -const MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); - -const PRESET_DICT = 0x20; - -const INIT_STATE = 42; /* zlib header -> BUSY_STATE */ -//#ifdef GZIP -const GZIP_STATE = 57; /* gzip header -> BUSY_STATE | EXTRA_STATE */ -//#endif -const EXTRA_STATE = 69; /* gzip extra block -> NAME_STATE */ -const NAME_STATE = 73; /* gzip file name -> COMMENT_STATE */ -const COMMENT_STATE = 91; /* gzip comment -> HCRC_STATE */ -const HCRC_STATE = 103; /* gzip header CRC -> BUSY_STATE */ -const BUSY_STATE = 113; /* deflate -> FINISH_STATE */ -const FINISH_STATE = 666; /* stream complete */ - -const BS_NEED_MORE = 1; /* block not completed, need more input or more output */ -const BS_BLOCK_DONE = 2; /* block flush performed */ -const BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ -const BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ - -const OS_CODE = 0x03; // Unix :) . Don't detect, use this default. - -const err = (strm, errorCode) => { - strm.msg = messages[errorCode]; - return errorCode; -}; - -const rank = (f) => { - return ((f) * 2) - ((f) > 4 ? 9 : 0); -}; - -const zero = (buf) => { - let len = buf.length; while (--len >= 0) { buf[len] = 0; } -}; - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -const slide_hash = (s) => { - let n, m; - let p; - let wsize = s.w_size; - - n = s.hash_size; - p = n; - do { - m = s.head[--p]; - s.head[p] = (m >= wsize ? m - wsize : 0); - } while (--n); - n = wsize; -//#ifndef FASTEST - p = n; - do { - m = s.prev[--p]; - s.prev[p] = (m >= wsize ? m - wsize : 0); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -//#endif -}; - -/* eslint-disable new-cap */ -let HASH_ZLIB = (s, prev, data) => ((prev << s.hash_shift) ^ data) & s.hash_mask; -// This hash causes less collisions, https://github.com/nodeca/pako/issues/135 -// But breaks binary compatibility -//let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask; -let HASH = HASH_ZLIB; - - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -const flush_pending = (strm) => { - const s = strm.state; - - //_tr_flush_bits(s); - let len = s.pending; - if (len > strm.avail_out) { - len = strm.avail_out; - } - if (len === 0) { return; } - - strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out); - strm.next_out += len; - s.pending_out += len; - strm.total_out += len; - strm.avail_out -= len; - s.pending -= len; - if (s.pending === 0) { - s.pending_out = 0; - } -}; - - -const flush_block_only = (s, last) => { - _tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); - s.block_start = s.strstart; - flush_pending(s.strm); -}; - - -const put_byte = (s, b) => { - s.pending_buf[s.pending++] = b; -}; - - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -const putShortMSB = (s, b) => { - - // put_byte(s, (Byte)(b >> 8)); -// put_byte(s, (Byte)(b & 0xff)); - s.pending_buf[s.pending++] = (b >>> 8) & 0xff; - s.pending_buf[s.pending++] = b & 0xff; -}; - - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->input buffer and copying from it. - * (See also flush_pending()). - */ -const read_buf = (strm, buf, start, size) => { - - let len = strm.avail_in; - - if (len > size) { len = size; } - if (len === 0) { return 0; } - - strm.avail_in -= len; - - // zmemcpy(buf, strm->next_in, len); - buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start); - if (strm.state.wrap === 1) { - strm.adler = adler32_1(strm.adler, buf, len, start); - } - - else if (strm.state.wrap === 2) { - strm.adler = crc32_1(strm.adler, buf, len, start); - } - - strm.next_in += len; - strm.total_in += len; - - return len; -}; - - -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -const longest_match = (s, cur_match) => { - - let chain_length = s.max_chain_length; /* max hash chain length */ - let scan = s.strstart; /* current string */ - let match; /* matched string */ - let len; /* length of current match */ - let best_len = s.prev_length; /* best match length so far */ - let nice_match = s.nice_match; /* stop if match long enough */ - const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; - - const _win = s.window; // shortcut - - const wmask = s.w_mask; - const prev = s.prev; - - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - - const strend = s.strstart + MAX_MATCH; - let scan_end1 = _win[scan + best_len - 1]; - let scan_end = _win[scan + best_len]; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s.prev_length >= s.good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if (nice_match > s.lookahead) { nice_match = s.lookahead; } - - // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - // Assert(cur_match < s->strstart, "no future"); - match = cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ - - if (_win[match + best_len] !== scan_end || - _win[match + best_len - 1] !== scan_end1 || - _win[match] !== _win[scan] || - _win[++match] !== _win[scan + 1]) { - continue; - } - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - // Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - /*jshint noempty:false*/ - } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - scan < strend); - - // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - s.match_start = cur_match; - best_len = len; - if (len >= nice_match) { - break; - } - scan_end1 = _win[scan + best_len - 1]; - scan_end = _win[scan + best_len]; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); - - if (best_len <= s.lookahead) { - return best_len; - } - return s.lookahead; -}; - - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -const fill_window = (s) => { - - const _w_size = s.w_size; - let n, more, str; - - //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = s.window_size - s.lookahead - s.strstart; - - // JS ints have 32 bit, block below not needed - /* Deal with !@#$% 64K limit: */ - //if (sizeof(int) <= 2) { - // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - // more = wsize; - // - // } else if (more == (unsigned)(-1)) { - // /* Very unlikely, but possible on 16 bit machine if - // * strstart == 0 && lookahead == 1 (input done a byte at time) - // */ - // more--; - // } - //} - - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { - - s.window.set(s.window.subarray(_w_size, _w_size + _w_size - more), 0); - s.match_start -= _w_size; - s.strstart -= _w_size; - /* we now have strstart >= MAX_DIST */ - s.block_start -= _w_size; - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - slide_hash(s); - more += _w_size; - } - if (s.strm.avail_in === 0) { - break; - } - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - //Assert(more >= 2, "more < 2"); - n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); - s.lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s.lookahead + s.insert >= MIN_MATCH) { - str = s.strstart - s.insert; - s.ins_h = s.window[str]; - - /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + 1]); -//#if MIN_MATCH != 3 -// Call update_hash() MIN_MATCH-3 more times -//#endif - while (s.insert) { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = str; - str++; - s.insert--; - if (s.lookahead + s.insert < MIN_MATCH) { - break; - } - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ -// if (s.high_water < s.window_size) { -// const curr = s.strstart + s.lookahead; -// let init = 0; -// -// if (s.high_water < curr) { -// /* Previous high water mark below current data -- zero WIN_INIT -// * bytes or up to end of window, whichever is less. -// */ -// init = s.window_size - curr; -// if (init > WIN_INIT) -// init = WIN_INIT; -// zmemzero(s->window + curr, (unsigned)init); -// s->high_water = curr + init; -// } -// else if (s->high_water < (ulg)curr + WIN_INIT) { -// /* High water mark at or above current data, but below current data -// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up -// * to end of window, whichever is less. -// */ -// init = (ulg)curr + WIN_INIT - s->high_water; -// if (init > s->window_size - s->high_water) -// init = s->window_size - s->high_water; -// zmemzero(s->window + s->high_water, (unsigned)init); -// s->high_water += init; -// } -// } -// -// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, -// "not enough room for search"); -}; - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ -const deflate_stored = (s, flush) => { - - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - let min_block = s.pending_buf_size - 5 > s.w_size ? s.w_size : s.pending_buf_size - 5; - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - let len, left, have, last = 0; - let used = s.strm.avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = 65535/* MAX_STORED */; /* maximum deflate stored block length */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - if (s.strm.avail_out < have) { /* need room for header */ - break; - } - /* maximum stored block length that will fit in avail_out: */ - have = s.strm.avail_out - have; - left = s.strstart - s.block_start; /* bytes left in window */ - if (len > left + s.strm.avail_in) { - len = left + s.strm.avail_in; /* limit len to the input */ - } - if (len > have) { - len = have; /* limit len to the output */ - } - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len === 0 && flush !== Z_FINISH$3) || - flush === Z_NO_FLUSH$2 || - len !== left + s.strm.avail_in)) { - break; - } - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush === Z_FINISH$3 && len === left + s.strm.avail_in ? 1 : 0; - _tr_stored_block(s, 0, 0, last); - - /* Replace the lengths in the dummy stored block with len. */ - s.pending_buf[s.pending - 4] = len; - s.pending_buf[s.pending - 3] = len >> 8; - s.pending_buf[s.pending - 2] = ~len; - s.pending_buf[s.pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s.strm); - -//#ifdef ZLIB_DEBUG -// /* Update debugging counts for the data about to be copied. */ -// s->compressed_len += len << 3; -// s->bits_sent += len << 3; -//#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) { - left = len; - } - //zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s.strm.output.set(s.window.subarray(s.block_start, s.block_start + left), s.strm.next_out); - s.strm.next_out += left; - s.strm.avail_out -= left; - s.strm.total_out += left; - s.block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s.strm, s.strm.output, s.strm.next_out, len); - s.strm.next_out += len; - s.strm.avail_out -= len; - s.strm.total_out += len; - } - } while (last === 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s.strm.avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s.w_size) { /* supplant the previous history */ - s.matches = 2; /* clear hash */ - //zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s.window.set(s.strm.input.subarray(s.strm.next_in - s.w_size, s.strm.next_in), 0); - s.strstart = s.w_size; - s.insert = s.strstart; - } - else { - if (s.window_size - s.strstart <= used) { - /* Slide the window down. */ - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - //zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s.window.set(s.strm.input.subarray(s.strm.next_in - used, s.strm.next_in), s.strstart); - s.strstart += used; - s.insert += used > s.w_size - s.insert ? s.w_size - s.insert : used; - } - s.block_start = s.strstart; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* If the last block was written to next_out, then done. */ - if (last) { - return BS_FINISH_DONE; - } - - /* If flushing and all input has been consumed, then done. */ - if (flush !== Z_NO_FLUSH$2 && flush !== Z_FINISH$3 && - s.strm.avail_in === 0 && s.strstart === s.block_start) { - return BS_BLOCK_DONE; - } - - /* Fill the window with any remaining input. */ - have = s.window_size - s.strstart; - if (s.strm.avail_in > have && s.block_start >= s.w_size) { - /* Slide the window down. */ - s.block_start -= s.w_size; - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - have += s.w_size; /* more space now */ - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - if (have > s.strm.avail_in) { - have = s.strm.avail_in; - } - if (have) { - read_buf(s.strm, s.window, s.strstart, have); - s.strstart += have; - s.insert += have > s.w_size - s.insert ? s.w_size - s.insert : have; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = s.pending_buf_size - have > 65535/* MAX_STORED */ ? 65535/* MAX_STORED */ : s.pending_buf_size - have; - min_block = have > s.w_size ? s.w_size : have; - left = s.strstart - s.block_start; - if (left >= min_block || - ((left || flush === Z_FINISH$3) && flush !== Z_NO_FLUSH$2 && - s.strm.avail_in === 0 && left <= have)) { - len = left > have ? have : left; - last = flush === Z_FINISH$3 && s.strm.avail_in === 0 && - len === left ? 1 : 0; - _tr_stored_block(s, s.block_start, len, last); - s.block_start += len; - flush_pending(s.strm); - } - - /* We've done all we can with the available input and output. */ - return last ? BS_FINISH_STARTED : BS_NEED_MORE; -}; - - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -const deflate_fast = (s, flush) => { - - let hash_head; /* head of the hash chain */ - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { - break; /* flush the current block */ - } - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } - if (s.match_length >= MIN_MATCH) { - // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - - /*** _tr_tally_dist(s, s.strstart - s.match_start, - s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { - s.match_length--; /* string at strstart already in table */ - do { - s.strstart++; - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s.match_length !== 0); - s.strstart++; - } else - { - s.strstart += s.match_length; - s.match_length = 0; - s.ins_h = s.window[s.strstart]; - /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + 1]); - -//#if MIN_MATCH != 3 -// Call UPDATE_HASH() MIN_MATCH-3 more times -//#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s.window[s.strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -}; - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -const deflate_slow = (s, flush) => { - - let hash_head; /* head of hash chain */ - let bflush; /* set if current block must be flushed */ - - let max_insert; - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - */ - s.prev_length = s.match_length; - s.prev_match = s.match_start; - s.match_length = MIN_MATCH - 1; - - if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && - s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - - if (s.match_length <= 5 && - (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s.match_length = MIN_MATCH - 1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { - max_insert = s.strstart + s.lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - //check_match(s, s.strstart-1, s.prev_match, s.prev_length); - - /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, - s.prev_length - MIN_MATCH, bflush);***/ - bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s.lookahead -= s.prev_length - 1; - s.prev_length -= 2; - do { - if (++s.strstart <= max_insert) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - } while (--s.prev_length !== 0); - s.match_available = 0; - s.match_length = MIN_MATCH - 1; - s.strstart++; - - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - } else if (s.match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart - 1]); - - if (bflush) { - /*** FLUSH_BLOCK_ONLY(s, 0) ***/ - flush_block_only(s, false); - /***/ - } - s.strstart++; - s.lookahead--; - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s.match_available = 1; - s.strstart++; - s.lookahead--; - } - } - //Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s.match_available) { - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart - 1]); - - s.match_available = 0; - } - s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - return BS_BLOCK_DONE; -}; - - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -const deflate_rle = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - let prev; /* byte at distance one to match */ - let scan, strend; /* scan goes up to strend for length of run */ - - const _win = s.window; - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s.lookahead <= MAX_MATCH) { - fill_window(s); - if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s.match_length = 0; - if (s.lookahead >= MIN_MATCH && s.strstart > 0) { - scan = s.strstart - 1; - prev = _win[scan]; - if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { - strend = s.strstart + MAX_MATCH; - do { - /*jshint noempty:false*/ - } while (prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - scan < strend); - s.match_length = MAX_MATCH - (strend - scan); - if (s.match_length > s.lookahead) { - s.match_length = s.lookahead; - } - } - //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s.match_length >= MIN_MATCH) { - //check_match(s, s.strstart, s.strstart - 1, s.match_length); - - /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - s.strstart += s.match_length; - s.match_length = 0; - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -}; - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -const deflate_huff = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s.lookahead === 0) { - fill_window(s); - if (s.lookahead === 0) { - if (flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s.match_length = 0; - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -}; - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -function Config(good_length, max_lazy, nice_length, max_chain, func) { - - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; -} - -const configuration_table = [ - /* good lazy nice chain */ - new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ - new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ - new Config(4, 5, 16, 8, deflate_fast), /* 2 */ - new Config(4, 6, 32, 32, deflate_fast), /* 3 */ - - new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ - new Config(8, 16, 32, 32, deflate_slow), /* 5 */ - new Config(8, 16, 128, 128, deflate_slow), /* 6 */ - new Config(8, 32, 128, 256, deflate_slow), /* 7 */ - new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ - new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ -]; - - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -const lm_init = (s) => { - - s.window_size = 2 * s.w_size; - - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - - /* Set the default configuration parameters: - */ - s.max_lazy_match = configuration_table[s.level].max_lazy; - s.good_match = configuration_table[s.level].good_length; - s.nice_match = configuration_table[s.level].nice_length; - s.max_chain_length = configuration_table[s.level].max_chain; - - s.strstart = 0; - s.block_start = 0; - s.lookahead = 0; - s.insert = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - s.ins_h = 0; -}; - - -function DeflateState() { - this.strm = null; /* pointer back to this zlib stream */ - this.status = 0; /* as the name implies */ - this.pending_buf = null; /* output still pending */ - this.pending_buf_size = 0; /* size of pending_buf */ - this.pending_out = 0; /* next pending byte to output to the stream */ - this.pending = 0; /* nb of bytes in the pending buffer */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.gzhead = null; /* gzip header information to write */ - this.gzindex = 0; /* where in extra, name, or comment */ - this.method = Z_DEFLATED$2; /* can only be DEFLATED */ - this.last_flush = -1; /* value of flush param for previous deflate call */ - - this.w_size = 0; /* LZ77 window size (32K by default) */ - this.w_bits = 0; /* log2(w_size) (8..16) */ - this.w_mask = 0; /* w_size - 1 */ - - this.window = null; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. - */ - - this.window_size = 0; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - this.prev = null; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - this.head = null; /* Heads of the hash chains or NIL. */ - - this.ins_h = 0; /* hash index of string to be inserted */ - this.hash_size = 0; /* number of elements in hash table */ - this.hash_bits = 0; /* log2(hash_size) */ - this.hash_mask = 0; /* hash_size-1 */ - - this.hash_shift = 0; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - this.block_start = 0; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - this.match_length = 0; /* length of best match */ - this.prev_match = 0; /* previous match */ - this.match_available = 0; /* set if previous match exists */ - this.strstart = 0; /* start of string to insert */ - this.match_start = 0; /* start of matching string */ - this.lookahead = 0; /* number of valid bytes ahead in window */ - - this.prev_length = 0; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - this.max_chain_length = 0; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - this.max_lazy_match = 0; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ - // That's alias to max_lazy_match, don't use directly - //this.max_insert_length = 0; - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - this.level = 0; /* compression level (1..9) */ - this.strategy = 0; /* favor or force Huffman coding*/ - - this.good_match = 0; - /* Use a faster search when the previous match is longer than this */ - - this.nice_match = 0; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - - /* Didn't use ct_data typedef below to suppress compiler warning */ - - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - // Use flat array of DOUBLE size, with interleaved fata, - // because JS does not support effective - this.dyn_ltree = new Uint16Array(HEAP_SIZE * 2); - this.dyn_dtree = new Uint16Array((2 * D_CODES + 1) * 2); - this.bl_tree = new Uint16Array((2 * BL_CODES + 1) * 2); - zero(this.dyn_ltree); - zero(this.dyn_dtree); - zero(this.bl_tree); - - this.l_desc = null; /* desc. for literal tree */ - this.d_desc = null; /* desc. for distance tree */ - this.bl_desc = null; /* desc. for bit length tree */ - - //ush bl_count[MAX_BITS+1]; - this.bl_count = new Uint16Array(MAX_BITS + 1); - /* number of codes at each bit length for an optimal tree */ - - //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = new Uint16Array(2 * L_CODES + 1); /* heap used to build the Huffman trees */ - zero(this.heap); - - this.heap_len = 0; /* number of elements in the heap */ - this.heap_max = 0; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - this.depth = new Uint16Array(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; - zero(this.depth); - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - this.sym_buf = 0; /* buffer for distances and literals/lengths */ - - this.lit_bufsize = 0; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - this.sym_next = 0; /* running index in sym_buf */ - this.sym_end = 0; /* symbol table full when sym_next reaches this */ - - this.opt_len = 0; /* bit length of current block with optimal trees */ - this.static_len = 0; /* bit length of current block with static trees */ - this.matches = 0; /* number of string matches in current block */ - this.insert = 0; /* bytes at end of window left to insert */ - - - this.bi_buf = 0; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - this.bi_valid = 0; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - // Used for window memory init. We safely ignore it for JS. That makes - // sense only for pointers and memory check tools. - //this.high_water = 0; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ -} - - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -const deflateStateCheck = (strm) => { - - if (!strm) { - return 1; - } - const s = strm.state; - if (!s || s.strm !== strm || (s.status !== INIT_STATE && -//#ifdef GZIP - s.status !== GZIP_STATE && -//#endif - s.status !== EXTRA_STATE && - s.status !== NAME_STATE && - s.status !== COMMENT_STATE && - s.status !== HCRC_STATE && - s.status !== BUSY_STATE && - s.status !== FINISH_STATE)) { - return 1; - } - return 0; -}; - - -const deflateResetKeep = (strm) => { - - if (deflateStateCheck(strm)) { - return err(strm, Z_STREAM_ERROR$2); - } - - strm.total_in = strm.total_out = 0; - strm.data_type = Z_UNKNOWN; - - const s = strm.state; - s.pending = 0; - s.pending_out = 0; - - if (s.wrap < 0) { - s.wrap = -s.wrap; - /* was made negative by deflate(..., Z_FINISH); */ - } - s.status = -//#ifdef GZIP - s.wrap === 2 ? GZIP_STATE : -//#endif - s.wrap ? INIT_STATE : BUSY_STATE; - strm.adler = (s.wrap === 2) ? - 0 // crc32(0, Z_NULL, 0) - : - 1; // adler32(0, Z_NULL, 0) - s.last_flush = -2; - _tr_init(s); - return Z_OK$3; -}; - - -const deflateReset = (strm) => { - - const ret = deflateResetKeep(strm); - if (ret === Z_OK$3) { - lm_init(strm.state); - } - return ret; -}; - - -const deflateSetHeader = (strm, head) => { - - if (deflateStateCheck(strm) || strm.state.wrap !== 2) { - return Z_STREAM_ERROR$2; - } - strm.state.gzhead = head; - return Z_OK$3; -}; - - -const deflateInit2 = (strm, level, method, windowBits, memLevel, strategy) => { - - if (!strm) { // === Z_NULL - return Z_STREAM_ERROR$2; - } - let wrap = 1; - - if (level === Z_DEFAULT_COMPRESSION$1) { - level = 6; - } - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } - - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } - - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits === 8 && wrap !== 1)) { - return err(strm, Z_STREAM_ERROR$2); - } - - - if (windowBits === 8) { - windowBits = 9; - } - /* until 256-byte window bug fixed */ - - const s = new DeflateState(); - - strm.state = s; - s.strm = strm; - s.status = INIT_STATE; /* to pass state test in deflateReset() */ - - s.wrap = wrap; - s.gzhead = null; - s.w_bits = windowBits; - s.w_size = 1 << s.w_bits; - s.w_mask = s.w_size - 1; - - s.hash_bits = memLevel + 7; - s.hash_size = 1 << s.hash_bits; - s.hash_mask = s.hash_size - 1; - s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); - - s.window = new Uint8Array(s.w_size * 2); - s.head = new Uint16Array(s.hash_size); - s.prev = new Uint16Array(s.w_size); - - // Don't need mem init magic for JS. - //s.high_water = 0; /* nothing written to s->window yet */ - - s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n-2) bits have been written, just - * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 - * symbols are written.) The closest the writing gets to what is unread is - * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s.pending_buf_size = s.lit_bufsize * 4; - s.pending_buf = new Uint8Array(s.pending_buf_size); - - // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) - //s->sym_buf = s->pending_buf + s->lit_bufsize; - s.sym_buf = s.lit_bufsize; - - //s->sym_end = (s->lit_bufsize - 1) * 3; - s.sym_end = (s.lit_bufsize - 1) * 3; - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s.level = level; - s.strategy = strategy; - s.method = method; - - return deflateReset(strm); -}; - -const deflateInit = (strm, level) => { - - return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1); -}; - - -/* ========================================================================= */ -const deflate$2 = (strm, flush) => { - - if (deflateStateCheck(strm) || flush > Z_BLOCK$1 || flush < 0) { - return strm ? err(strm, Z_STREAM_ERROR$2) : Z_STREAM_ERROR$2; - } - - const s = strm.state; - - if (!strm.output || - (strm.avail_in !== 0 && !strm.input) || - (s.status === FINISH_STATE && flush !== Z_FINISH$3)) { - return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$2); - } - - const old_flush = s.last_flush; - s.last_flush = flush; - - /* Flush as much pending output as possible */ - if (s.pending !== 0) { - flush_pending(strm); - if (strm.avail_out === 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s.last_flush = -1; - return Z_OK$3; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && - flush !== Z_FINISH$3) { - return err(strm, Z_BUF_ERROR$1); - } - - /* User must not provide more input after the first FINISH: */ - if (s.status === FINISH_STATE && strm.avail_in !== 0) { - return err(strm, Z_BUF_ERROR$1); - } - - /* Write the header */ - if (s.status === INIT_STATE && s.wrap === 0) { - s.status = BUSY_STATE; - } - if (s.status === INIT_STATE) { - /* zlib header */ - let header = (Z_DEFLATED$2 + ((s.w_bits - 8) << 4)) << 8; - let level_flags = -1; - - if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { - level_flags = 0; - } else if (s.level < 6) { - level_flags = 1; - } else if (s.level === 6) { - level_flags = 2; - } else { - level_flags = 3; - } - header |= (level_flags << 6); - if (s.strstart !== 0) { header |= PRESET_DICT; } - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s.strstart !== 0) { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - strm.adler = 1; // adler32(0L, Z_NULL, 0); - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } -//#ifdef GZIP - if (s.status === GZIP_STATE) { - /* gzip header */ - strm.adler = 0; //crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (!s.gzhead) { // s->gzhead == Z_NULL - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } - else { - put_byte(s, (s.gzhead.text ? 1 : 0) + - (s.gzhead.hcrc ? 2 : 0) + - (!s.gzhead.extra ? 0 : 4) + - (!s.gzhead.name ? 0 : 8) + - (!s.gzhead.comment ? 0 : 16) - ); - put_byte(s, s.gzhead.time & 0xff); - put_byte(s, (s.gzhead.time >> 8) & 0xff); - put_byte(s, (s.gzhead.time >> 16) & 0xff); - put_byte(s, (s.gzhead.time >> 24) & 0xff); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, s.gzhead.os & 0xff); - if (s.gzhead.extra && s.gzhead.extra.length) { - put_byte(s, s.gzhead.extra.length & 0xff); - put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); - } - if (s.gzhead.hcrc) { - strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending, 0); - } - s.gzindex = 0; - s.status = EXTRA_STATE; - } - } - if (s.status === EXTRA_STATE) { - if (s.gzhead.extra/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let left = (s.gzhead.extra.length & 0xffff) - s.gzindex; - while (s.pending + left > s.pending_buf_size) { - let copy = s.pending_buf_size - s.pending; - // zmemcpy(s.pending_buf + s.pending, - // s.gzhead.extra + s.gzindex, copy); - s.pending_buf.set(s.gzhead.extra.subarray(s.gzindex, s.gzindex + copy), s.pending); - s.pending = s.pending_buf_size; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex += copy; - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - left -= copy; - } - // JS specific: s.gzhead.extra may be TypedArray or Array for backward compatibility - // TypedArray.slice and TypedArray.from don't exist in IE10-IE11 - let gzhead_extra = new Uint8Array(s.gzhead.extra); - // zmemcpy(s->pending_buf + s->pending, - // s->gzhead->extra + s->gzindex, left); - s.pending_buf.set(gzhead_extra.subarray(s.gzindex, s.gzindex + left), s.pending); - s.pending += left; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = NAME_STATE; - } - if (s.status === NAME_STATE) { - if (s.gzhead.name/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.name.length) { - val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = COMMENT_STATE; - } - if (s.status === COMMENT_STATE) { - if (s.gzhead.comment/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.comment.length) { - val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - } - s.status = HCRC_STATE; - } - if (s.status === HCRC_STATE) { - if (s.gzhead.hcrc) { - if (s.pending + 2 > s.pending_buf_size) { - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - strm.adler = 0; //crc32(0L, Z_NULL, 0); - } - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } -//#endif - - /* Start a new block or continue the current one. - */ - if (strm.avail_in !== 0 || s.lookahead !== 0 || - (flush !== Z_NO_FLUSH$2 && s.status !== FINISH_STATE)) { - let bstate = s.level === 0 ? deflate_stored(s, flush) : - s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s.strategy === Z_RLE ? deflate_rle(s, flush) : - configuration_table[s.level].func(s, flush); - - if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { - s.status = FINISH_STATE; - } - if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { - if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR next call, see above */ - } - return Z_OK$3; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate === BS_BLOCK_DONE) { - if (flush === Z_PARTIAL_FLUSH) { - _tr_align(s); - } - else if (flush !== Z_BLOCK$1) { /* FULL_FLUSH or SYNC_FLUSH */ - - _tr_stored_block(s, 0, 0, false); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush === Z_FULL_FLUSH$1) { - /*** CLEAR_HASH(s); ***/ /* forget history */ - zero(s.head); // Fill with NIL (= 0); - - if (s.lookahead === 0) { - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - } - } - flush_pending(strm); - if (strm.avail_out === 0) { - s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK$3; - } - } - } - - if (flush !== Z_FINISH$3) { return Z_OK$3; } - if (s.wrap <= 0) { return Z_STREAM_END$3; } - - /* Write the trailer */ - if (s.wrap === 2) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - put_byte(s, (strm.adler >> 16) & 0xff); - put_byte(s, (strm.adler >> 24) & 0xff); - put_byte(s, strm.total_in & 0xff); - put_byte(s, (strm.total_in >> 8) & 0xff); - put_byte(s, (strm.total_in >> 16) & 0xff); - put_byte(s, (strm.total_in >> 24) & 0xff); - } - else - { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s.wrap > 0) { s.wrap = -s.wrap; } - /* write the trailer only once! */ - return s.pending !== 0 ? Z_OK$3 : Z_STREAM_END$3; -}; - - -const deflateEnd = (strm) => { - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR$2; - } - - const status = strm.state.status; - - strm.state = null; - - return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$2) : Z_OK$3; -}; - - -/* ========================================================================= - * Initializes the compression dictionary from the given byte - * sequence without producing any compressed output. - */ -const deflateSetDictionary = (strm, dictionary) => { - - let dictLength = dictionary.length; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR$2; - } - - const s = strm.state; - const wrap = s.wrap; - - if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { - return Z_STREAM_ERROR$2; - } - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap === 1) { - /* adler32(strm->adler, dictionary, dictLength); */ - strm.adler = adler32_1(strm.adler, dictionary, dictLength, 0); - } - - s.wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s.w_size) { - if (wrap === 0) { /* already empty otherwise */ - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - /* use the tail */ - // dictionary = dictionary.slice(dictLength - s.w_size); - let tmpDict = new Uint8Array(s.w_size); - tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0); - dictionary = tmpDict; - dictLength = s.w_size; - } - /* insert dictionary into window and hash */ - const avail = strm.avail_in; - const next = strm.next_in; - const input = strm.input; - strm.avail_in = dictLength; - strm.next_in = 0; - strm.input = dictionary; - fill_window(s); - while (s.lookahead >= MIN_MATCH) { - let str = s.strstart; - let n = s.lookahead - (MIN_MATCH - 1); - do { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - - s.head[s.ins_h] = str; - str++; - } while (--n); - s.strstart = str; - s.lookahead = MIN_MATCH - 1; - fill_window(s); - } - s.strstart += s.lookahead; - s.block_start = s.strstart; - s.insert = s.lookahead; - s.lookahead = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - strm.next_in = next; - strm.input = input; - strm.avail_in = avail; - s.wrap = wrap; - return Z_OK$3; -}; - - -var deflateInit_1 = deflateInit; -var deflateInit2_1 = deflateInit2; -var deflateReset_1 = deflateReset; -var deflateResetKeep_1 = deflateResetKeep; -var deflateSetHeader_1 = deflateSetHeader; -var deflate_2$1 = deflate$2; -var deflateEnd_1 = deflateEnd; -var deflateSetDictionary_1 = deflateSetDictionary; -var deflateInfo = 'pako deflate (from Nodeca project)'; - -/* Not implemented -module.exports.deflateBound = deflateBound; -module.exports.deflateCopy = deflateCopy; -module.exports.deflateGetDictionary = deflateGetDictionary; -module.exports.deflateParams = deflateParams; -module.exports.deflatePending = deflatePending; -module.exports.deflatePrime = deflatePrime; -module.exports.deflateTune = deflateTune; -*/ - -var deflate_1$2 = { - deflateInit: deflateInit_1, - deflateInit2: deflateInit2_1, - deflateReset: deflateReset_1, - deflateResetKeep: deflateResetKeep_1, - deflateSetHeader: deflateSetHeader_1, - deflate: deflate_2$1, - deflateEnd: deflateEnd_1, - deflateSetDictionary: deflateSetDictionary_1, - deflateInfo: deflateInfo -}; - -const _has = (obj, key) => { - return Object.prototype.hasOwnProperty.call(obj, key); -}; - -var assign = function (obj /*from1, from2, from3, ...*/) { - const sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - const source = sources.shift(); - if (!source) { continue; } - - if (typeof source !== 'object') { - throw new TypeError(source + 'must be non-object'); - } - - for (const p in source) { - if (_has(source, p)) { - obj[p] = source[p]; - } - } - } - - return obj; -}; - - -// Join array of chunks to single array. -var flattenChunks = (chunks) => { - // calculate data length - let len = 0; - - for (let i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - - // join chunks - const result = new Uint8Array(len); - - for (let i = 0, pos = 0, l = chunks.length; i < l; i++) { - let chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - - return result; -}; - -var common = { - assign: assign, - flattenChunks: flattenChunks -}; - -// String encode/decode helpers - - -// Quick check if we can use fast array to bin string conversion -// -// - apply(Array) can fail on Android 2.2 -// - apply(Uint8Array) can fail on iOS 5.1 Safari -// -let STR_APPLY_UIA_OK = true; - -try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; } - - -// Table with utf8 lengths (calculated by first byte of sequence) -// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, -// because max possible codepoint is 0x10ffff -const _utf8len = new Uint8Array(256); -for (let q = 0; q < 256; q++) { - _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); -} -_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start - - -// convert string to array (typed, when possible) -var string2buf = (str) => { - if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) { - return new TextEncoder().encode(str); - } - - let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; - } - - // allocate buffer - buf = new Uint8Array(buf_len); - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xC0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xE0 | (c >>> 12); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | (c >>> 12 & 0x3f); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } - } - - return buf; -}; - -// Helper -const buf2binstring = (buf, len) => { - // On Chrome, the arguments in a function call that are allowed is `65534`. - // If the length of the buffer is smaller than that, we can use this optimization, - // otherwise we will take a slower path. - if (len < 65534) { - if (buf.subarray && STR_APPLY_UIA_OK) { - return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len)); - } - } - - let result = ''; - for (let i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); - } - return result; -}; - - -// convert array to string -var buf2string = (buf, max) => { - const len = max || buf.length; - - if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) { - return new TextDecoder().decode(buf.subarray(0, max)); - } - - let i, out; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - const utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len;) { - let c = buf[i++]; - // quick process ascii - if (c < 0x80) { utf16buf[out++] = c; continue; } - - let c_len = _utf8len[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - - // terminated by end of string? - if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } - - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } - } - - return buf2binstring(utf16buf, out); -}; - - -// Calculate max possible position in utf8 buffer, -// that will not break sequence. If that's not possible -// - (very small limits) return max size as is. -// -// buf[] - utf8 bytes array -// max - length limit (mandatory); -var utf8border = (buf, max) => { - - max = max || buf.length; - if (max > buf.length) { max = buf.length; } - - // go back from last position, until start of sequence found - let pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - - // Very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { return max; } - - // If we came to start of buffer - that means buffer is too small, - // return max too. - if (pos === 0) { return max; } - - return (pos + _utf8len[buf[pos]] > max) ? pos : max; -}; - -var strings = { - string2buf: string2buf, - buf2string: buf2string, - utf8border: utf8border -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -function ZStream() { - /* next input byte */ - this.input = null; // JS specific, because we have no pointers - this.next_in = 0; - /* number of bytes available at input */ - this.avail_in = 0; - /* total number of input bytes read so far */ - this.total_in = 0; - /* next output byte should be put there */ - this.output = null; // JS specific, because we have no pointers - this.next_out = 0; - /* remaining free space at output */ - this.avail_out = 0; - /* total number of bytes output so far */ - this.total_out = 0; - /* last error message, NULL if no error */ - this.msg = ''/*Z_NULL*/; - /* not visible by applications */ - this.state = null; - /* best guess about the data type: binary or text */ - this.data_type = 2/*Z_UNKNOWN*/; - /* adler32 value of the uncompressed data */ - this.adler = 0; -} - -var zstream = ZStream; - -const toString$1 = Object.prototype.toString; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH: Z_NO_FLUSH$1, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH: Z_FINISH$2, - Z_OK: Z_OK$2, Z_STREAM_END: Z_STREAM_END$2, - Z_DEFAULT_COMPRESSION, - Z_DEFAULT_STRATEGY, - Z_DEFLATED: Z_DEFLATED$1 -} = constants$2; - -/* ===========================================================================*/ - - -/** - * class Deflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[deflate]], - * [[deflateRaw]] and [[gzip]]. - **/ - -/* internal - * Deflate.chunks -> Array - * - * Chunks of output data, if [[Deflate#onData]] not overridden. - **/ - -/** - * Deflate.result -> Uint8Array - * - * Compressed result, generated by default [[Deflate#onData]] - * and [[Deflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Deflate#push]] with `Z_FINISH` / `true` param). - **/ - -/** - * Deflate.err -> Number - * - * Error code after deflate finished. 0 (Z_OK) on success. - * You will not need it in real life, because deflate errors - * are possible only on wrong options or bad `onData` / `onEnd` - * custom handlers. - **/ - -/** - * Deflate.msg -> String - * - * Error message, if [[Deflate.err]] != 0 - **/ - - -/** - * new Deflate(options) - * - options (Object): zlib deflate options. - * - * Creates new deflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `level` - * - `windowBits` - * - `memLevel` - * - `strategy` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw deflate - * - `gzip` (Boolean) - create gzip wrapper - * - `header` (Object) - custom header for gzip - * - `text` (Boolean) - true if compressed data believed to be text - * - `time` (Number) - modification time, unix timestamp - * - `os` (Number) - operation system code - * - `extra` (Array) - array of bytes with extra data (max 65536) - * - `name` (String) - file name (binary string) - * - `comment` (String) - comment (binary string) - * - `hcrc` (Boolean) - true if header crc should be added - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const deflate = new pako.Deflate({ level: 3}); - * - * deflate.push(chunk1, false); - * deflate.push(chunk2, true); // true -> last chunk - * - * if (deflate.err) { throw new Error(deflate.err); } - * - * console.log(deflate.result); - * ``` - **/ -function Deflate$1(options) { - this.options = common.assign({ - level: Z_DEFAULT_COMPRESSION, - method: Z_DEFLATED$1, - chunkSize: 16384, - windowBits: 15, - memLevel: 8, - strategy: Z_DEFAULT_STRATEGY - }, options || {}); - - let opt = this.options; - - if (opt.raw && (opt.windowBits > 0)) { - opt.windowBits = -opt.windowBits; - } - - else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { - opt.windowBits += 16; - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream(); - this.strm.avail_out = 0; - - let status = deflate_1$2.deflateInit2( - this.strm, - opt.level, - opt.method, - opt.windowBits, - opt.memLevel, - opt.strategy - ); - - if (status !== Z_OK$2) { - throw new Error(messages[status]); - } - - if (opt.header) { - deflate_1$2.deflateSetHeader(this.strm, opt.header); - } - - if (opt.dictionary) { - let dict; - // Convert data if needed - if (typeof opt.dictionary === 'string') { - // If we need to compress text, change encoding to utf8. - dict = strings.string2buf(opt.dictionary); - } else if (toString$1.call(opt.dictionary) === '[object ArrayBuffer]') { - dict = new Uint8Array(opt.dictionary); - } else { - dict = opt.dictionary; - } - - status = deflate_1$2.deflateSetDictionary(this.strm, dict); - - if (status !== Z_OK$2) { - throw new Error(messages[status]); - } - - this._dict_set = true; - } -} - -/** - * Deflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be - * converted to utf8 byte sequence. - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with - * new compressed chunks. Returns `true` on success. The last data block must - * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending - * buffers and call [[Deflate#onEnd]]. - * - * On fail call [[Deflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ -Deflate$1.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - let status, _flush_mode; - - if (this.ended) { return false; } - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$2 : Z_NO_FLUSH$1; - - // Convert data if needed - if (typeof data === 'string') { - // If we need to compress text, change encoding to utf8. - strm.input = strings.string2buf(data); - } else if (toString$1.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - // Make sure avail_out > 6 to avoid repeating markers - if ((_flush_mode === Z_SYNC_FLUSH || _flush_mode === Z_FULL_FLUSH) && strm.avail_out <= 6) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - status = deflate_1$2.deflate(strm, _flush_mode); - - // Ended => flush and finish - if (status === Z_STREAM_END$2) { - if (strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - } - status = deflate_1$2.deflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === Z_OK$2; - } - - // Flush if out buffer full - if (strm.avail_out === 0) { - this.onData(strm.output); - continue; - } - - // Flush if requested and has data - if (_flush_mode > 0 && strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - if (strm.avail_in === 0) break; - } - - return true; -}; - - -/** - * Deflate#onData(chunk) -> Void - * - chunk (Uint8Array): output data. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ -Deflate$1.prototype.onData = function (chunk) { - this.chunks.push(chunk); -}; - - -/** - * Deflate#onEnd(status) -> Void - * - status (Number): deflate status. 0 (Z_OK) on success, - * other if not. - * - * Called once after you tell deflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ -Deflate$1.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$2) { - this.result = common.flattenChunks(this.chunks); - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; -}; - - -/** - * deflate(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * Compress `data` with deflate algorithm and `options`. - * - * Supported options are: - * - * - level - * - windowBits - * - memLevel - * - strategy - * - dictionary - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]); - * - * console.log(pako.deflate(data)); - * ``` - **/ -function deflate$1(input, options) { - const deflator = new Deflate$1(options); - - deflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (deflator.err) { throw deflator.msg || messages[deflator.err]; } - - return deflator.result; -} - - -/** - * deflateRaw(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ -function deflateRaw$1(input, options) { - options = options || {}; - options.raw = true; - return deflate$1(input, options); -} - - -/** - * gzip(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but create gzip wrapper instead of - * deflate one. - **/ -function gzip$1(input, options) { - options = options || {}; - options.gzip = true; - return deflate$1(input, options); -} - - -var Deflate_1$1 = Deflate$1; -var deflate_2 = deflate$1; -var deflateRaw_1$1 = deflateRaw$1; -var gzip_1$1 = gzip$1; -var constants$1 = constants$2; - -var deflate_1$1 = { - Deflate: Deflate_1$1, - deflate: deflate_2, - deflateRaw: deflateRaw_1$1, - gzip: gzip_1$1, - constants: constants$1 -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -// See state defs from inflate.js -const BAD$1 = 16209; /* got a data error -- remain here until reset */ -const TYPE$1 = 16191; /* i: waiting for type bits, including last-flag bit */ - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state.mode === LEN - strm.avail_in >= 6 - strm.avail_out >= 258 - start >= strm.avail_out - state.bits < 8 - - On return, state.mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm.avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm.avail_out >= 258 for each loop to avoid checking for - output space. - */ -var inffast = function inflate_fast(strm, start) { - let _in; /* local strm.input */ - let last; /* have enough input while in < last */ - let _out; /* local strm.output */ - let beg; /* inflate()'s initial strm.output */ - let end; /* while out < end, enough space available */ -//#ifdef INFLATE_STRICT - let dmax; /* maximum distance from zlib header */ -//#endif - let wsize; /* window size or zero if not using window */ - let whave; /* valid bytes in the window */ - let wnext; /* window write index */ - // Use `s_window` instead `window`, avoid conflict with instrumentation tools - let s_window; /* allocated sliding window, if wsize != 0 */ - let hold; /* local strm.hold */ - let bits; /* local strm.bits */ - let lcode; /* local strm.lencode */ - let dcode; /* local strm.distcode */ - let lmask; /* mask for first level of length codes */ - let dmask; /* mask for first level of distance codes */ - let here; /* retrieved table entry */ - let op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - let len; /* match length, unused bytes */ - let dist; /* match distance */ - let from; /* where to copy match from */ - let from_source; - - - let input, output; // JS specific, because we have no pointers - - /* copy state to local variables */ - const state = strm.state; - //here = state.here; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); -//#ifdef INFLATE_STRICT - dmax = state.dmax; -//#endif - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - - here = lcode[hold & lmask]; - - dolen: - for (;;) { // Goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - if (op === 0) { /* literal */ - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - output[_out++] = here & 0xffff/*here.val*/; - } - else if (op & 16) { /* length base */ - len = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & ((1 << op) - 1); - hold >>>= op; - bits -= op; - } - //Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - - dodist: - for (;;) { // goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - - if (op & 16) { /* distance base */ - dist = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & ((1 << op) - 1); -//#ifdef INFLATE_STRICT - if (dist > dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1; - break top; - } -//#endif - hold >>>= op; - bits -= op; - //Tracevv((stderr, "inflate: distance %u\n", dist)); - op = _out - beg; /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1; - break top; - } - -// (!) This block is disabled in zlib defaults, -// don't enable it for binary compatibility -//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR -// if (len <= op - whave) { -// do { -// output[_out++] = 0; -// } while (--len); -// continue top; -// } -// len -= op - whave; -// do { -// output[_out++] = 0; -// } while (--op > whave); -// if (op === 0) { -// from = _out - dist; -// do { -// output[_out++] = output[from++]; -// } while (--len); -// continue top; -// } -//#endif - } - from = 0; // window index - from_source = s_window; - if (wnext === 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } - else { - from = _out - dist; /* copy direct from output */ - do { /* minimum length is three */ - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } - else if ((op & 64) === 0) { /* 2nd level distance code */ - here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dodist; - } - else { - strm.msg = 'invalid distance code'; - state.mode = BAD$1; - break top; - } - - break; // need to emulate goto via "continue" - } - } - else if ((op & 64) === 0) { /* 2nd level length code */ - here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dolen; - } - else if (op & 32) { /* end-of-block */ - //Tracevv((stderr, "inflate: end of block\n")); - state.mode = TYPE$1; - break top; - } - else { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$1; - break top; - } - - break; // need to emulate goto via "continue" - } - } while (_in < last && _out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - - /* update state and return */ - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); - strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); - state.hold = hold; - state.bits = bits; - return; -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const MAXBITS = 15; -const ENOUGH_LENS$1 = 852; -const ENOUGH_DISTS$1 = 592; -//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - -const CODES$1 = 0; -const LENS$1 = 1; -const DISTS$1 = 2; - -const lbase = new Uint16Array([ /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 -]); - -const lext = new Uint8Array([ /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 -]); - -const dbase = new Uint16Array([ /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 -]); - -const dext = new Uint8Array([ /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 -]); - -const inflate_table = (type, lens, lens_index, codes, table, table_index, work, opts) => -{ - const bits = opts.bits; - //here = opts.here; /* table entry for duplication */ - - let len = 0; /* a code's length in bits */ - let sym = 0; /* index of code symbols */ - let min = 0, max = 0; /* minimum and maximum code lengths */ - let root = 0; /* number of index bits for root table */ - let curr = 0; /* number of index bits for current table */ - let drop = 0; /* code bits to drop for sub-table */ - let left = 0; /* number of prefix codes available */ - let used = 0; /* code entries in table used */ - let huff = 0; /* Huffman code */ - let incr; /* for incrementing code, index */ - let fill; /* index for replicating entries */ - let low; /* low bits for current root entry */ - let mask; /* mask for low root bits */ - let next; /* next available space in table */ - let base = null; /* base value table to use */ -// let shoextra; /* extra bits table to use */ - let match; /* use base and extra for symbol >= match */ - const count = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ - const offs = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ - let extra = null; - - let here_bits, here_op, here_val; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - - /* bound code lengths, force root to be within code lengths */ - root = bits; - for (max = MAXBITS; max >= 1; max--) { - if (count[max] !== 0) { break; } - } - if (root > max) { - root = max; - } - if (max === 0) { /* no symbols to code at all */ - //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ - //table.bits[opts.table_index] = 1; //here.bits = (var char)1; - //table.val[opts.table_index++] = 0; //here.val = (var short)0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - - //table.op[opts.table_index] = 64; - //table.bits[opts.table_index] = 1; - //table.val[opts.table_index++] = 0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - opts.bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { break; } - } - if (root < min) { - root = min; - } - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } /* over-subscribed */ - } - if (left > 0 && (type === CODES$1 || max !== 1)) { - return -1; /* incomplete set */ - } - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) { - offs[len + 1] = offs[len] + count[len]; - } - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - // poor man optimization - use if-else instead of switch, - // to avoid deopts in old v8 - if (type === CODES$1) { - base = extra = work; /* dummy value--not used */ - match = 20; - - } else if (type === LENS$1) { - base = lbase; - extra = lext; - match = 257; - - } else { /* DISTS */ - base = dbase; - extra = dext; - match = 0; - } - - /* initialize opts for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = table_index; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = -1; /* trigger new sub-table when len > root */ - used = 1 << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type === LENS$1 && used > ENOUGH_LENS$1) || - (type === DISTS$1 && used > ENOUGH_DISTS$1)) { - return 1; - } - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here_bits = len - drop; - if (work[sym] + 1 < match) { - here_op = 0; - here_val = work[sym]; - } - else if (work[sym] >= match) { - here_op = extra[work[sym] - match]; - here_val = base[work[sym] - match]; - } - else { - here_op = 32 + 64; /* end of block */ - here_val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1 << (len - drop); - fill = 1 << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; - } while (fill !== 0); - - /* backwards increment the len-bit code huff */ - incr = 1 << (len - 1); - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--count[len] === 0) { - if (len === max) { break; } - len = lens[lens_index + work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) !== low) { - /* if first time, transition to sub-tables */ - if (drop === 0) { - drop = root; - } - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { break; } - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1 << curr; - if ((type === LENS$1 && used > ENOUGH_LENS$1) || - (type === DISTS$1 && used > ENOUGH_DISTS$1)) { - return 1; - } - - /* point entry in root table to sub-table */ - low = huff & mask; - /*table.op[low] = curr; - table.bits[low] = root; - table.val[low] = next - opts.table_index;*/ - table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff !== 0) { - //table.op[next + huff] = 64; /* invalid code marker */ - //table.bits[next + huff] = len - drop; - //table.val[next + huff] = 0; - table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; - } - - /* set return parameters */ - //opts.table_index += used; - opts.bits = root; - return 0; -}; - - -var inftrees = inflate_table; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - - - - - - -const CODES = 0; -const LENS = 1; -const DISTS = 2; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_FINISH: Z_FINISH$1, Z_BLOCK, Z_TREES, - Z_OK: Z_OK$1, Z_STREAM_END: Z_STREAM_END$1, Z_NEED_DICT: Z_NEED_DICT$1, Z_STREAM_ERROR: Z_STREAM_ERROR$1, Z_DATA_ERROR: Z_DATA_ERROR$1, Z_MEM_ERROR: Z_MEM_ERROR$1, Z_BUF_ERROR, - Z_DEFLATED -} = constants$2; - - -/* STATES ====================================================================*/ -/* ===========================================================================*/ - - -const HEAD = 16180; /* i: waiting for magic header */ -const FLAGS = 16181; /* i: waiting for method and flags (gzip) */ -const TIME = 16182; /* i: waiting for modification time (gzip) */ -const OS = 16183; /* i: waiting for extra flags and operating system (gzip) */ -const EXLEN = 16184; /* i: waiting for extra length (gzip) */ -const EXTRA = 16185; /* i: waiting for extra bytes (gzip) */ -const NAME = 16186; /* i: waiting for end of file name (gzip) */ -const COMMENT = 16187; /* i: waiting for end of comment (gzip) */ -const HCRC = 16188; /* i: waiting for header crc (gzip) */ -const DICTID = 16189; /* i: waiting for dictionary check value */ -const DICT = 16190; /* waiting for inflateSetDictionary() call */ -const TYPE = 16191; /* i: waiting for type bits, including last-flag bit */ -const TYPEDO = 16192; /* i: same, but skip check to exit inflate on new block */ -const STORED = 16193; /* i: waiting for stored size (length and complement) */ -const COPY_ = 16194; /* i/o: same as COPY below, but only first time in */ -const COPY = 16195; /* i/o: waiting for input or output to copy stored block */ -const TABLE = 16196; /* i: waiting for dynamic block table lengths */ -const LENLENS = 16197; /* i: waiting for code length code lengths */ -const CODELENS = 16198; /* i: waiting for length/lit and distance code lengths */ -const LEN_ = 16199; /* i: same as LEN below, but only first time in */ -const LEN = 16200; /* i: waiting for length/lit/eob code */ -const LENEXT = 16201; /* i: waiting for length extra bits */ -const DIST = 16202; /* i: waiting for distance code */ -const DISTEXT = 16203; /* i: waiting for distance extra bits */ -const MATCH = 16204; /* o: waiting for output space to copy string */ -const LIT = 16205; /* o: waiting for output space to write literal */ -const CHECK = 16206; /* i: waiting for 32-bit check value */ -const LENGTH = 16207; /* i: waiting for 32-bit length (gzip) */ -const DONE = 16208; /* finished check, done -- remain here until reset */ -const BAD = 16209; /* got a data error -- remain here until reset */ -const MEM = 16210; /* got an inflate() memory error -- remain here until reset */ -const SYNC = 16211; /* looking for synchronization bytes to restart inflate() */ - -/* ===========================================================================*/ - - - -const ENOUGH_LENS = 852; -const ENOUGH_DISTS = 592; -//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - -const MAX_WBITS = 15; -/* 32K LZ77 window */ -const DEF_WBITS = MAX_WBITS; - - -const zswap32 = (q) => { - - return (((q >>> 24) & 0xff) + - ((q >>> 8) & 0xff00) + - ((q & 0xff00) << 8) + - ((q & 0xff) << 24)); -}; - - -function InflateState() { - this.strm = null; /* pointer back to this zlib stream */ - this.mode = 0; /* current inflate mode */ - this.last = false; /* true if processing last block */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - this.havedict = false; /* true if dictionary provided */ - this.flags = 0; /* gzip header method and flags (0 if zlib), or - -1 if raw or no header yet */ - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ - this.check = 0; /* protected copy of check value */ - this.total = 0; /* protected copy of output count */ - // TODO: may be {} - this.head = null; /* where to save gzip header information */ - - /* sliding window */ - this.wbits = 0; /* log base 2 of requested window size */ - this.wsize = 0; /* window size or zero if not using window */ - this.whave = 0; /* valid bytes in the window */ - this.wnext = 0; /* window write index */ - this.window = null; /* allocated sliding window, if needed */ - - /* bit accumulator */ - this.hold = 0; /* input bit accumulator */ - this.bits = 0; /* number of bits in "in" */ - - /* for string and stored block copying */ - this.length = 0; /* literal or length of data to copy */ - this.offset = 0; /* distance back to copy string from */ - - /* for table and code decoding */ - this.extra = 0; /* extra bits needed */ - - /* fixed and dynamic code tables */ - this.lencode = null; /* starting table for length/literal codes */ - this.distcode = null; /* starting table for distance codes */ - this.lenbits = 0; /* index bits for lencode */ - this.distbits = 0; /* index bits for distcode */ - - /* dynamic table building */ - this.ncode = 0; /* number of code length code lengths */ - this.nlen = 0; /* number of length code lengths */ - this.ndist = 0; /* number of distance code lengths */ - this.have = 0; /* number of code lengths in lens[] */ - this.next = null; /* next available space in codes[] */ - - this.lens = new Uint16Array(320); /* temporary storage for code lengths */ - this.work = new Uint16Array(288); /* work area for code table building */ - - /* - because we don't have pointers in js, we use lencode and distcode directly - as buffers so we don't need codes - */ - //this.codes = new Int32Array(ENOUGH); /* space for code tables */ - this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ - this.distdyn = null; /* dynamic table for distance codes (JS specific) */ - this.sane = 0; /* if false, allow invalid distance too far */ - this.back = 0; /* bits back of last unprocessed length/lit */ - this.was = 0; /* initial length of match */ -} - - -const inflateStateCheck = (strm) => { - - if (!strm) { - return 1; - } - const state = strm.state; - if (!state || state.strm !== strm || - state.mode < HEAD || state.mode > SYNC) { - return 1; - } - return 0; -}; - - -const inflateResetKeep = (strm) => { - - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } - const state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ''; /*Z_NULL*/ - if (state.wrap) { /* to support ill-conceived Java test suite */ - strm.adler = state.wrap & 1; - } - state.mode = HEAD; - state.last = 0; - state.havedict = 0; - state.flags = -1; - state.dmax = 32768; - state.head = null/*Z_NULL*/; - state.hold = 0; - state.bits = 0; - //state.lencode = state.distcode = state.next = state.codes; - state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS); - state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS); - - state.sane = 1; - state.back = -1; - //Tracev((stderr, "inflate: reset\n")); - return Z_OK$1; -}; - - -const inflateReset = (strm) => { - - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } - const state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep(strm); - -}; - - -const inflateReset2 = (strm, windowBits) => { - let wrap; - - /* get the state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } - const state = strm.state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; - if (windowBits < 48) { - windowBits &= 15; - } - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR$1; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - - /* update state and reset the rest of it */ - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset(strm); -}; - - -const inflateInit2 = (strm, windowBits) => { - - if (!strm) { return Z_STREAM_ERROR$1; } - //strm.msg = Z_NULL; /* in case we return an error */ - - const state = new InflateState(); - - //if (state === Z_NULL) return Z_MEM_ERROR; - //Tracev((stderr, "inflate: allocated\n")); - strm.state = state; - state.strm = strm; - state.window = null/*Z_NULL*/; - state.mode = HEAD; /* to pass state test in inflateReset2() */ - const ret = inflateReset2(strm, windowBits); - if (ret !== Z_OK$1) { - strm.state = null/*Z_NULL*/; - } - return ret; -}; - - -const inflateInit = (strm) => { - - return inflateInit2(strm, DEF_WBITS); -}; - - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -let virgin = true; - -let lenfix, distfix; // We have no pointers in JS, so keep tables separate - - -const fixedtables = (state) => { - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - lenfix = new Int32Array(512); - distfix = new Int32Array(32); - - /* literal/length table */ - let sym = 0; - while (sym < 144) { state.lens[sym++] = 8; } - while (sym < 256) { state.lens[sym++] = 9; } - while (sym < 280) { state.lens[sym++] = 7; } - while (sym < 288) { state.lens[sym++] = 8; } - - inftrees(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); - - /* distance table */ - sym = 0; - while (sym < 32) { state.lens[sym++] = 5; } - - inftrees(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); - - /* do this just once */ - virgin = false; - } - - state.lencode = lenfix; - state.lenbits = 9; - state.distcode = distfix; - state.distbits = 5; -}; - - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -const updatewindow = (strm, src, end, copy) => { - - let dist; - const state = strm.state; - - /* if it hasn't been done already, allocate space for the window */ - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - - state.window = new Uint8Array(state.wsize); - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state.wsize) { - state.window.set(src.subarray(end - state.wsize, end), 0); - state.wnext = 0; - state.whave = state.wsize; - } - else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - //zmemcpy(state->window + state->wnext, end - copy, dist); - state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext); - copy -= dist; - if (copy) { - //zmemcpy(state->window, end - copy, copy); - state.window.set(src.subarray(end - copy, end), 0); - state.wnext = copy; - state.whave = state.wsize; - } - else { - state.wnext += dist; - if (state.wnext === state.wsize) { state.wnext = 0; } - if (state.whave < state.wsize) { state.whave += dist; } - } - } - return 0; -}; - - -const inflate$2 = (strm, flush) => { - - let state; - let input, output; // input/output buffers - let next; /* next input INDEX */ - let put; /* next output INDEX */ - let have, left; /* available input and output */ - let hold; /* bit buffer */ - let bits; /* bits in bit buffer */ - let _in, _out; /* save starting available input and output */ - let copy; /* number of stored or match bytes to copy */ - let from; /* where to copy match bytes from */ - let from_source; - let here = 0; /* current decoding table entry */ - let here_bits, here_op, here_val; // paked "here" denormalized (JS specific) - //let last; /* parent table entry */ - let last_bits, last_op, last_val; // paked "last" denormalized (JS specific) - let len; /* length to copy for repeats, bits to drop */ - let ret; /* return code */ - const hbuf = new Uint8Array(4); /* buffer for gzip header crc calculation */ - let opts; - - let n; // temporary variable for NEED_BITS - - const order = /* permutation of code lengths */ - new Uint8Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]); - - - if (inflateStateCheck(strm) || !strm.output || - (!strm.input && strm.avail_in !== 0)) { - return Z_STREAM_ERROR$1; - } - - state = strm.state; - if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ - - - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - _in = have; - _out = left; - ret = Z_OK$1; - - inf_leave: // goto emulation - for (;;) { - switch (state.mode) { - case HEAD: - if (state.wrap === 0) { - state.mode = TYPEDO; - break; - } - //=== NEEDBITS(16); - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ - if (state.wbits === 0) { - state.wbits = 15; - } - state.check = 0/*crc32(0L, Z_NULL, 0)*/; - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1(state.check, hbuf, 2, 0); - //===// - - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = FLAGS; - break; - } - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || /* check if zlib header allowed */ - (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { - strm.msg = 'incorrect header check'; - state.mode = BAD; - break; - } - if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { - strm.msg = 'unknown compression method'; - state.mode = BAD; - break; - } - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - len = (hold & 0x0f)/*BITS(4)*/ + 8; - if (state.wbits === 0) { - state.wbits = len; - } - if (len > 15 || len > state.wbits) { - strm.msg = 'invalid window size'; - state.mode = BAD; - break; - } - - // !!! pako patch. Force use `options.windowBits` if passed. - // Required to always use max window size by default. - state.dmax = 1 << state.wbits; - //state.dmax = 1 << len; - - state.flags = 0; /* indicate zlib header */ - //Tracev((stderr, "inflate: zlib header ok\n")); - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = hold & 0x200 ? DICTID : TYPE; - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - break; - case FLAGS: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.flags = hold; - if ((state.flags & 0xff) !== Z_DEFLATED) { - strm.msg = 'unknown compression method'; - state.mode = BAD; - break; - } - if (state.flags & 0xe000) { - strm.msg = 'unknown header flags set'; - state.mode = BAD; - break; - } - if (state.head) { - state.head.text = ((hold >> 8) & 1); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = TIME; - /* falls through */ - case TIME: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.time = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC4(state.check, hold) - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - hbuf[2] = (hold >>> 16) & 0xff; - hbuf[3] = (hold >>> 24) & 0xff; - state.check = crc32_1(state.check, hbuf, 4, 0); - //=== - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = OS; - /* falls through */ - case OS: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.xflags = (hold & 0xff); - state.head.os = (hold >> 8); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = EXLEN; - /* falls through */ - case EXLEN: - if (state.flags & 0x0400) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - else if (state.head) { - state.head.extra = null/*Z_NULL*/; - } - state.mode = EXTRA; - /* falls through */ - case EXTRA: - if (state.flags & 0x0400) { - copy = state.length; - if (copy > have) { copy = have; } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - // Use untyped array for more convenient processing later - state.head.extra = new Uint8Array(state.head.extra_len); - } - state.head.extra.set( - input.subarray( - next, - // extra field is limited to 65536 bytes - // - no need for additional size check - next + copy - ), - /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ - len - ); - //zmemcpy(state.head.extra + len, next, - // len + copy > state.head.extra_max ? - // state.head.extra_max - len : copy); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { break inf_leave; } - } - state.length = 0; - state.mode = NAME; - /* falls through */ - case NAME: - if (state.flags & 0x0800) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - // TODO: 2 or 1 bytes? - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.name_max*/)) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT; - /* falls through */ - case COMMENT: - if (state.flags & 0x1000) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.comm_max*/)) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC; - /* falls through */ - case HCRC: - if (state.flags & 0x0200) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.check & 0xffff)) { - strm.msg = 'header crc mismatch'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - if (state.head) { - state.head.hcrc = ((state.flags >> 9) & 1); - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE; - break; - case DICTID: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - strm.adler = state.check = zswap32(hold); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = DICT; - /* falls through */ - case DICT: - if (state.havedict === 0) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - return Z_NEED_DICT$1; - } - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = TYPE; - /* falls through */ - case TYPE: - if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } - /* falls through */ - case TYPEDO: - if (state.last) { - //--- BYTEBITS() ---// - hold >>>= bits & 7; - bits -= bits & 7; - //---// - state.mode = CHECK; - break; - } - //=== NEEDBITS(3); */ - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.last = (hold & 0x01)/*BITS(1)*/; - //--- DROPBITS(1) ---// - hold >>>= 1; - bits -= 1; - //---// - - switch ((hold & 0x03)/*BITS(2)*/) { - case 0: /* stored block */ - //Tracev((stderr, "inflate: stored block%s\n", - // state.last ? " (last)" : "")); - state.mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - //Tracev((stderr, "inflate: fixed codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = LEN_; /* decode codes */ - if (flush === Z_TREES) { - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break inf_leave; - } - break; - case 2: /* dynamic block */ - //Tracev((stderr, "inflate: dynamic codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = TABLE; - break; - case 3: - strm.msg = 'invalid block type'; - state.mode = BAD; - } - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break; - case STORED: - //--- BYTEBITS() ---// /* go to byte boundary */ - hold >>>= bits & 7; - bits -= bits & 7; - //---// - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { - strm.msg = 'invalid stored block lengths'; - state.mode = BAD; - break; - } - state.length = hold & 0xffff; - //Tracev((stderr, "inflate: stored length %u\n", - // state.length)); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = COPY_; - if (flush === Z_TREES) { break inf_leave; } - /* falls through */ - case COPY_: - state.mode = COPY; - /* falls through */ - case COPY: - copy = state.length; - if (copy) { - if (copy > have) { copy = have; } - if (copy > left) { copy = left; } - if (copy === 0) { break inf_leave; } - //--- zmemcpy(put, next, copy); --- - output.set(input.subarray(next, next + copy), put); - //---// - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - //Tracev((stderr, "inflate: stored end\n")); - state.mode = TYPE; - break; - case TABLE: - //=== NEEDBITS(14); */ - while (bits < 14) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// -//#ifndef PKZIP_BUG_WORKAROUND - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = 'too many length or distance symbols'; - state.mode = BAD; - break; - } -//#endif - //Tracev((stderr, "inflate: table sizes ok\n")); - state.have = 0; - state.mode = LENLENS; - /* falls through */ - case LENLENS: - while (state.have < state.ncode) { - //=== NEEDBITS(3); - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - // We have separate tables & no pointers. 2 commented lines below not needed. - //state.next = state.codes; - //state.lencode = state.next; - // Switch to use dynamic table - state.lencode = state.lendyn; - state.lenbits = 7; - - opts = { bits: state.lenbits }; - ret = inftrees(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - - if (ret) { - strm.msg = 'invalid code lengths set'; - state.mode = BAD; - break; - } - //Tracev((stderr, "inflate: code lengths ok\n")); - state.have = 0; - state.mode = CODELENS; - /* falls through */ - case CODELENS: - while (state.have < state.nlen + state.ndist) { - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_val < 16) { - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.lens[state.have++] = here_val; - } - else { - if (here_val === 16) { - //=== NEEDBITS(here.bits + 2); - n = here_bits + 2; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - if (state.have === 0) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 0x03);//BITS(2); - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - } - else if (here_val === 17) { - //=== NEEDBITS(here.bits + 3); - n = here_bits + 3; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 3 + (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - else { - //=== NEEDBITS(here.bits + 7); - n = here_bits + 7; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 11 + (hold & 0x7f);//BITS(7); - //--- DROPBITS(7) ---// - hold >>>= 7; - bits -= 7; - //---// - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - - /* handle error breaks in while */ - if (state.mode === BAD) { break; } - - /* check for end-of-block code (better have one) */ - if (state.lens[256] === 0) { - strm.msg = 'invalid code -- missing end-of-block'; - state.mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state.lenbits = 9; - - opts = { bits: state.lenbits }; - ret = inftrees(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.lenbits = opts.bits; - // state.lencode = state.next; - - if (ret) { - strm.msg = 'invalid literal/lengths set'; - state.mode = BAD; - break; - } - - state.distbits = 6; - //state.distcode.copy(state.codes); - // Switch to use dynamic table - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inftrees(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.distbits = opts.bits; - // state.distcode = state.next; - - if (ret) { - strm.msg = 'invalid distances set'; - state.mode = BAD; - break; - } - //Tracev((stderr, 'inflate: codes ok\n')); - state.mode = LEN_; - if (flush === Z_TREES) { break inf_leave; } - /* falls through */ - case LEN_: - state.mode = LEN; - /* falls through */ - case LEN: - if (have >= 6 && left >= 258) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - inffast(strm, _out); - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - if (state.mode === TYPE) { - state.back = -1; - } - break; - } - state.back = 0; - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if (here_bits <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_op && (here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - state.mode = LIT; - break; - } - if (here_op & 32) { - //Tracevv((stderr, "inflate: end of block\n")); - state.back = -1; - state.mode = TYPE; - break; - } - if (here_op & 64) { - strm.msg = 'invalid literal/length code'; - state.mode = BAD; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT; - /* falls through */ - case LENEXT: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //Tracevv((stderr, "inflate: length %u\n", state.length)); - state.was = state.length; - state.mode = DIST; - /* falls through */ - case DIST: - for (;;) { - here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if ((here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - if (here_op & 64) { - strm.msg = 'invalid distance code'; - state.mode = BAD; - break; - } - state.offset = here_val; - state.extra = (here_op) & 15; - state.mode = DISTEXT; - /* falls through */ - case DISTEXT: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } -//#ifdef INFLATE_STRICT - if (state.offset > state.dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break; - } -//#endif - //Tracevv((stderr, "inflate: distance %u\n", state.offset)); - state.mode = MATCH; - /* falls through */ - case MATCH: - if (left === 0) { break inf_leave; } - copy = _out - left; - if (state.offset > copy) { /* copy from window */ - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break; - } -// (!) This block is disabled in zlib defaults, -// don't enable it for binary compatibility -//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR -// Trace((stderr, "inflate.c too far\n")); -// copy -= state.whave; -// if (copy > state.length) { copy = state.length; } -// if (copy > left) { copy = left; } -// left -= copy; -// state.length -= copy; -// do { -// output[put++] = 0; -// } while (--copy); -// if (state.length === 0) { state.mode = LEN; } -// break; -//#endif - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } - else { - from = state.wnext - copy; - } - if (copy > state.length) { copy = state.length; } - from_source = state.window; - } - else { /* copy from output */ - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { copy = left; } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { state.mode = LEN; } - break; - case LIT: - if (left === 0) { break inf_leave; } - output[put++] = state.length; - left--; - state.mode = LEN; - break; - case CHECK: - if (state.wrap) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - // Use '|' instead of '+' to make sure that result is signed - hold |= input[next++] << bits; - bits += 8; - } - //===// - _out -= left; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = - /*UPDATE_CHECK(state.check, put - _out, _out);*/ - (state.flags ? crc32_1(state.check, output, _out, put - _out) : adler32_1(state.check, output, _out, put - _out)); - - } - _out = left; - // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too - if ((state.wrap & 4) && (state.flags ? hold : zswap32(hold)) !== state.check) { - strm.msg = 'incorrect data check'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: check matches trailer\n")); - } - state.mode = LENGTH; - /* falls through */ - case LENGTH: - if (state.wrap && state.flags) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.total & 0xffffffff)) { - strm.msg = 'incorrect length check'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: length matches trailer\n")); - } - state.mode = DONE; - /* falls through */ - case DONE: - ret = Z_STREAM_END$1; - break inf_leave; - case BAD: - ret = Z_DATA_ERROR$1; - break inf_leave; - case MEM: - return Z_MEM_ERROR$1; - case SYNC: - /* falls through */ - default: - return Z_STREAM_ERROR$1; - } - } - - // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - - if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && - (state.mode < CHECK || flush !== Z_FINISH$1))) { - if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) ; - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = /*UPDATE_CHECK(state.check, strm.next_out - _out, _out);*/ - (state.flags ? crc32_1(state.check, output, _out, strm.next_out - _out) : adler32_1(state.check, output, _out, strm.next_out - _out)); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + - (state.mode === TYPE ? 128 : 0) + - (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); - if (((_in === 0 && _out === 0) || flush === Z_FINISH$1) && ret === Z_OK$1) { - ret = Z_BUF_ERROR; - } - return ret; -}; - - -const inflateEnd = (strm) => { - - if (inflateStateCheck(strm)) { - return Z_STREAM_ERROR$1; - } - - let state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK$1; -}; - - -const inflateGetHeader = (strm, head) => { - - /* check state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } - const state = strm.state; - if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR$1; } - - /* save header structure */ - state.head = head; - head.done = false; - return Z_OK$1; -}; - - -const inflateSetDictionary = (strm, dictionary) => { - const dictLength = dictionary.length; - - let state; - let dictid; - let ret; - - /* check state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; } - state = strm.state; - - if (state.wrap !== 0 && state.mode !== DICT) { - return Z_STREAM_ERROR$1; - } - - /* check for correct dictionary identifier */ - if (state.mode === DICT) { - dictid = 1; /* adler32(0, null, 0)*/ - /* dictid = adler32(dictid, dictionary, dictLength); */ - dictid = adler32_1(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR$1; - } - } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM; - return Z_MEM_ERROR$1; - } - state.havedict = 1; - // Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK$1; -}; - - -var inflateReset_1 = inflateReset; -var inflateReset2_1 = inflateReset2; -var inflateResetKeep_1 = inflateResetKeep; -var inflateInit_1 = inflateInit; -var inflateInit2_1 = inflateInit2; -var inflate_2$1 = inflate$2; -var inflateEnd_1 = inflateEnd; -var inflateGetHeader_1 = inflateGetHeader; -var inflateSetDictionary_1 = inflateSetDictionary; -var inflateInfo = 'pako inflate (from Nodeca project)'; - -/* Not implemented -module.exports.inflateCodesUsed = inflateCodesUsed; -module.exports.inflateCopy = inflateCopy; -module.exports.inflateGetDictionary = inflateGetDictionary; -module.exports.inflateMark = inflateMark; -module.exports.inflatePrime = inflatePrime; -module.exports.inflateSync = inflateSync; -module.exports.inflateSyncPoint = inflateSyncPoint; -module.exports.inflateUndermine = inflateUndermine; -module.exports.inflateValidate = inflateValidate; -*/ - -var inflate_1$2 = { - inflateReset: inflateReset_1, - inflateReset2: inflateReset2_1, - inflateResetKeep: inflateResetKeep_1, - inflateInit: inflateInit_1, - inflateInit2: inflateInit2_1, - inflate: inflate_2$1, - inflateEnd: inflateEnd_1, - inflateGetHeader: inflateGetHeader_1, - inflateSetDictionary: inflateSetDictionary_1, - inflateInfo: inflateInfo -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -function GZheader() { - /* true if compressed data believed to be text */ - this.text = 0; - /* modification time */ - this.time = 0; - /* extra flags (not used when writing a gzip file) */ - this.xflags = 0; - /* operating system */ - this.os = 0; - /* pointer to extra field or Z_NULL if none */ - this.extra = null; - /* extra field length (valid if extra != Z_NULL) */ - this.extra_len = 0; // Actually, we don't need it in JS, - // but leave for few code modifications - - // - // Setup limits is not necessary because in js we should not preallocate memory - // for inflate use constant limit in 65536 bytes - // - - /* space at extra (only when reading header) */ - // this.extra_max = 0; - /* pointer to zero-terminated file name or Z_NULL */ - this.name = ''; - /* space at name (only when reading header) */ - // this.name_max = 0; - /* pointer to zero-terminated comment or Z_NULL */ - this.comment = ''; - /* space at comment (only when reading header) */ - // this.comm_max = 0; - /* true if there was or will be a header crc */ - this.hcrc = 0; - /* true when done reading gzip header (not used when writing a gzip file) */ - this.done = false; -} - -var gzheader = GZheader; - -const toString = Object.prototype.toString; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH, Z_FINISH, - Z_OK, Z_STREAM_END, Z_NEED_DICT, Z_STREAM_ERROR, Z_DATA_ERROR, Z_MEM_ERROR -} = constants$2; - -/* ===========================================================================*/ - - -/** - * class Inflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[inflate]] - * and [[inflateRaw]]. - **/ - -/* internal - * inflate.chunks -> Array - * - * Chunks of output data, if [[Inflate#onData]] not overridden. - **/ - -/** - * Inflate.result -> Uint8Array|String - * - * Uncompressed result, generated by default [[Inflate#onData]] - * and [[Inflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Inflate#push]] with `Z_FINISH` / `true` param). - **/ - -/** - * Inflate.err -> Number - * - * Error code after inflate finished. 0 (Z_OK) on success. - * Should be checked if broken data possible. - **/ - -/** - * Inflate.msg -> String - * - * Error message, if [[Inflate.err]] != 0 - **/ - - -/** - * new Inflate(options) - * - options (Object): zlib inflate options. - * - * Creates new inflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `windowBits` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw inflate - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * By default, when no options set, autodetect deflate/gzip data format via - * wrapper header. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const inflate = new pako.Inflate({ level: 3}); - * - * inflate.push(chunk1, false); - * inflate.push(chunk2, true); // true -> last chunk - * - * if (inflate.err) { throw new Error(inflate.err); } - * - * console.log(inflate.result); - * ``` - **/ -function Inflate$1(options) { - this.options = common.assign({ - chunkSize: 1024 * 64, - windowBits: 15, - to: '' - }, options || {}); - - const opt = this.options; - - // Force window size for `raw` data, if not set directly, - // because we have no header for autodetect. - if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { opt.windowBits = -15; } - } - - // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate - if ((opt.windowBits >= 0) && (opt.windowBits < 16) && - !(options && options.windowBits)) { - opt.windowBits += 32; - } - - // Gzip header has no info about windows size, we can do autodetect only - // for deflate. So, if window size not set, force it to max when gzip possible - if ((opt.windowBits > 15) && (opt.windowBits < 48)) { - // bit 3 (16) -> gzipped data - // bit 4 (32) -> autodetect gzip/deflate - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream(); - this.strm.avail_out = 0; - - let status = inflate_1$2.inflateInit2( - this.strm, - opt.windowBits - ); - - if (status !== Z_OK) { - throw new Error(messages[status]); - } - - this.header = new gzheader(); - - inflate_1$2.inflateGetHeader(this.strm, this.header); - - // Setup dictionary - if (opt.dictionary) { - // Convert data if needed - if (typeof opt.dictionary === 'string') { - opt.dictionary = strings.string2buf(opt.dictionary); - } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { //In raw mode we need to set the dictionary early - status = inflate_1$2.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== Z_OK) { - throw new Error(messages[status]); - } - } - } -} - -/** - * Inflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer): input data - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE - * flush modes. See constants. Skipped or `false` means Z_NO_FLUSH, - * `true` means Z_FINISH. - * - * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with - * new output chunks. Returns `true` on success. If end of stream detected, - * [[Inflate#onEnd]] will be called. - * - * `flush_mode` is not needed for normal operation, because end of stream - * detected automatically. You may try to use it for advanced things, but - * this functionality was not tested. - * - * On fail call [[Inflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ -Inflate$1.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - const dictionary = this.options.dictionary; - let status, _flush_mode, last_avail_out; - - if (this.ended) return false; - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH; - - // Convert data if needed - if (toString.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - status = inflate_1$2.inflate(strm, _flush_mode); - - if (status === Z_NEED_DICT && dictionary) { - status = inflate_1$2.inflateSetDictionary(strm, dictionary); - - if (status === Z_OK) { - status = inflate_1$2.inflate(strm, _flush_mode); - } else if (status === Z_DATA_ERROR) { - // Replace code with more verbose - status = Z_NEED_DICT; - } - } - - // Skip snyc markers if more data follows and not raw mode - while (strm.avail_in > 0 && - status === Z_STREAM_END && - strm.state.wrap > 0 && - data[strm.next_in] !== 0) - { - inflate_1$2.inflateReset(strm); - status = inflate_1$2.inflate(strm, _flush_mode); - } - - switch (status) { - case Z_STREAM_ERROR: - case Z_DATA_ERROR: - case Z_NEED_DICT: - case Z_MEM_ERROR: - this.onEnd(status); - this.ended = true; - return false; - } - - // Remember real `avail_out` value, because we may patch out buffer content - // to align utf8 strings boundaries. - last_avail_out = strm.avail_out; - - if (strm.next_out) { - if (strm.avail_out === 0 || status === Z_STREAM_END) { - - if (this.options.to === 'string') { - - let next_out_utf8 = strings.utf8border(strm.output, strm.next_out); - - let tail = strm.next_out - next_out_utf8; - let utf8str = strings.buf2string(strm.output, next_out_utf8); - - // move tail & realign counters - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0); - - this.onData(utf8str); - - } else { - this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out)); - } - } - } - - // Must repeat iteration if out buffer is full - if (status === Z_OK && last_avail_out === 0) continue; - - // Finalize if end of stream reached. - if (status === Z_STREAM_END) { - status = inflate_1$2.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return true; - } - - if (strm.avail_in === 0) break; - } - - return true; -}; - - -/** - * Inflate#onData(chunk) -> Void - * - chunk (Uint8Array|String): output data. When string output requested, - * each chunk will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ -Inflate$1.prototype.onData = function (chunk) { - this.chunks.push(chunk); -}; - - -/** - * Inflate#onEnd(status) -> Void - * - status (Number): inflate status. 0 (Z_OK) on success, - * other if not. - * - * Called either after you tell inflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ -Inflate$1.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK) { - if (this.options.to === 'string') { - this.result = this.chunks.join(''); - } else { - this.result = common.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; -}; - - -/** - * inflate(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Decompress `data` with inflate/ungzip and `options`. Autodetect - * format via wrapper header by default. That's why we don't provide - * separate `ungzip` method. - * - * Supported options are: - * - * - windowBits - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * - * ##### Example: - * - * ```javascript - * const pako = require('pako'); - * const input = pako.deflate(new Uint8Array([1,2,3,4,5,6,7,8,9])); - * let output; - * - * try { - * output = pako.inflate(input); - * } catch (err) { - * console.log(err); - * } - * ``` - **/ -function inflate$1(input, options) { - const inflator = new Inflate$1(options); - - inflator.push(input); - - // That will never happens, if you don't cheat with options :) - if (inflator.err) throw inflator.msg || messages[inflator.err]; - - return inflator.result; -} - - -/** - * inflateRaw(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * The same as [[inflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ -function inflateRaw$1(input, options) { - options = options || {}; - options.raw = true; - return inflate$1(input, options); -} - - -/** - * ungzip(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Just shortcut to [[inflate]], because it autodetects format - * by header.content. Done for convenience. - **/ - - -var Inflate_1$1 = Inflate$1; -var inflate_2 = inflate$1; -var inflateRaw_1$1 = inflateRaw$1; -var ungzip$1 = inflate$1; -var constants = constants$2; - -var inflate_1$1 = { - Inflate: Inflate_1$1, - inflate: inflate_2, - inflateRaw: inflateRaw_1$1, - ungzip: ungzip$1, - constants: constants -}; - -const { Deflate, deflate, deflateRaw, gzip } = deflate_1$1; - -const { Inflate, inflate, inflateRaw, ungzip } = inflate_1$1; - - - -var Deflate_1 = Deflate; -var deflate_1 = deflate; -var deflateRaw_1 = deflateRaw; -var gzip_1 = gzip; -var Inflate_1 = Inflate; -var inflate_1 = inflate; -var inflateRaw_1 = inflateRaw; -var ungzip_1 = ungzip; -var constants_1 = constants$2; - -var pako = { - Deflate: Deflate_1, - deflate: deflate_1, - deflateRaw: deflateRaw_1, - gzip: gzip_1, - Inflate: Inflate_1, - inflate: inflate_1, - inflateRaw: inflateRaw_1, - ungzip: ungzip_1, - constants: constants_1 -}; - - - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVuZG9ycy1ub2RlX21vZHVsZXNfZXNwLXdlYi10b29sc19kaXN0X2luc3RhbGwtZGlhbG9nX2pzLmJ1bmRsZS5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUMwQjtBQUNuQixlQUFlLHdDQUFHLFFBQVEsa0hBQWtILDhHQUE4RywwR0FBMEcsOEdBQThHLG9CQUFvQiwrQ0FBK0Msa0JBQWtCLG1CQUFtQiw4Q0FBOEMsMENBQTBDLGVBQWUsa0JBQWtCLGVBQWUsOEJBQThCLG1FQUFtRSxjQUFjLFlBQVksWUFBWSxXQUFXLE1BQU0sZ0JBQWdCLFlBQVksU0FBUyxVQUFVLGFBQWEsa0JBQWtCLFdBQVcsVUFBVSxlQUFlLGlDQUFpQyxZQUFZLFdBQVcsV0FBVyxzQkFBc0IsYUFBYSxZQUFZLHFCQUFxQixtQkFBbUIsa0JBQWtCLFdBQVcsMkJBQTJCLFFBQVEsa0JBQWtCLHFCQUFxQixzQkFBc0IsU0FBUywrRkFBK0YsbUJBQW1CLG1EQUFtRCxzQkFBc0IsWUFBWSxtR0FBbUcsa0JBQWtCLFVBQVUsK0JBQStCLHNDQUFzQyxrRUFBa0UscUJBQXFCLHlDQUF5QyxVQUFVLCtCQUErQixrRUFBa0UsbUJBQW1CLFVBQVUsNEZBQTRGLGlEQUFpRCxZQUFZLGdEQUFnRCw2R0FBNkcsOEVBQThFLDhHQUE4RyxrRkFBa0Ysb0JBQW9CLG1IQUFtSCx1RkFBdUYsMEhBQTBILDJGQUEyRixNQUFNLGtGQUFrRiwwQ0FBMEMseUNBQXlDLFlBQVksV0FBVyxxQ0FBcUMsVUFBVSxXQUFXLFdBQVcsb0NBQW9DLFdBQVcsTUFBTSx5QkFBeUIsMERBQTBELDBCQUEwQiwyREFBMkQsZ0JBQWdCLHlCQUF5QiwwREFBMEQsMEJBQTBCLDJEQUEyRCw4Q0FBOEMseURBQXlELDBEQUEwRCxzQkFBc0Isd0RBQXdELHFCQUFxQiwwREFBMEQsd0RBQXdELHVCQUF1Qix5QkFBeUIsb0NBQW9DLDBDQUEwQyxzQ0FBc0MsS0FBSyxTQUFTLHdC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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQix5Q0FBUTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixJQUFJLFlBQVk7QUFDakMsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELDREQUFTO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVCxLQUFLLElBQUksaUJBQWlCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxJQUFJLGlCQUFpQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNPO0FBQ1AsK0NBQStDLCtCQUErQjtBQUM5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUCw2Q0FBNkMsK0JBQStCO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0EsK0NBQStDLCtCQUErQjtBQUM5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLCtLQUErSztBQUMvTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLCtEQUErRDtBQUM3RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxrRUFBa0U7QUFDaEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsV0FBVztBQUNsRCx3Q0FBd0MsWUFBWTtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwREFBMEQsZ0RBQWdEO0FBQzFHO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxnREFBZ0Q7QUFDekc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHFIQUFxSDtBQUNySTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isd0lBQXdJO0FBQ3hKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ3pZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsMkJBQTJCO0FBQ3hFO0FBQ0EsNkNBQTZDLDJCQUEyQjtBQUN4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7OztBQy9STztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQLG9DQUFvQyxvQkFBb0I7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7QUNkTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ1hPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7QUNoQk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQ7QUFDOUQ7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkM7QUFDM0M7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNtRDtBQUNlO0FBQ2M7QUFDaEYsNEJBQTRCLG9EQUFTO0FBQ3JDO0FB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R0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUEsZUFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCOztBQUU3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHVCQUF1Qjs7QUFFdkIsdUNBQXVDOztBQUV2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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Q0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9COztBQUVwQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQ7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCO0FBQzNCLDJCQUEyQjs7QUFFM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUIsOEJBQThCO0FBQzlCLDhCQUE4QjtBQUM5Qiw4QkFBOEI7QUFDOUIsOEJBQThCO0FBQzlCO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0EsOEJBQThCO0FBQzlCLDhCQUE4QjtBQUM5Qiw4QkFBOEI7QUFDOUI7QUFDQSw4QkFBOEI7QUFDOUIsOEJBQThCO0FBQzlCLDhCQUE4QjtBQUM5Qiw4QkFBOEI7QUFDOUIsOEJBQThCO0FBQzlCLDhCQUE4QjtBQUM5Qiw4QkFBOEI7QUFDOUIsOEJBQThCO0FBQzlCLDhCQUE4QjtBQUM5QjtBQUNBLDhCQUE4QjtBQUM5Qiw4QkFBOEI7QUFDOUIsOEJBQThCO0FBQzlCOzs7QUFHQSxxQkFBcUI7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7O0FBRVo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRDtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtB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QUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxRQUFRLHFDQUFxQzs7QUFFN0MsUUFBUSx1Q0FBdUM7Ozs7QUFJL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRXlPIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9jaGVja2JveC9pbnRlcm5hbC9jaGVja2JveC1zdHlsZXMuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9jaGVja2JveC9pbnRlcm5hbC9jaGVja2JveC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2VsZXZhdGlvbi9lbGV2YXRpb24uanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9lbGV2YXRpb24vaW50ZXJuYWwvZWxldmF0aW9uLXN0eWxlcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2VsZXZhdGlvbi9pbnRlcm5hbC9lbGV2YXRpb24uanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9maWVsZC9maWxsZWQtZmllbGQuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9maWVsZC9pbnRlcm5hbC9maWVsZC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2ZpZWxkL2ludGVybmFsL2ZpbGxlZC1maWVsZC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2ZpZWxkL2ludGVybmFsL2ZpbGxlZC1zdHlsZXMuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9maWVsZC9pbnRlcm5hbC9zaGFyZWQtc3R5bGVzLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvaWNvbmJ1dHRvbi9pbnRlcm5hbC9pY29uLWJ1dHRvbi5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2ljb25idXR0b24vaW50ZXJuYWwvc2hhcmVkLXN0eWxlcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2ljb25idXR0b24vaW50ZXJuYWwvc3RhbmRhcmQtc3R5bGVzLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvaW50ZXJuYWwvY29udHJvbGxlci9pcy1ydGwuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9pbnRlcm5hbC9jb250cm9sbGVyL3N0cmluZy1jb252ZXJ0ZXIuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9sYWJzL2JlaGF2aW9ycy9jb25zdHJhaW50LXZhbGlkYXRpb24uanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9sYWJzL2JlaGF2aW9ycy9mb3JtLWFzc29jaWF0ZWQuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9sYWJzL2JlaGF2aW9ycy9vbi1yZXBvcnQtdmFsaWRpdHkuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9sYWJzL2JlaGF2aW9ycy92YWxpZGF0b3JzL2NoZWNrYm94LXZhbGlkYXRvci5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2xhYnMvYmVoYXZpb3JzL3ZhbGlkYXRvcnMvc2VsZWN0LXZhbGlkYXRvci5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2xhYnMvYmVoYXZpb3JzL3ZhbGlkYXRvcnMvdGV4dC1maWVsZC12YWxpZGF0b3IuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9sYWJzL2JlaGF2aW9ycy92YWxpZGF0b3JzL3ZhbGlkYXRvci5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2xhYnMvaXRlbS9pbnRlcm5hbC9pdGVtLXN0eWxlcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2xhYnMvaXRlbS9pbnRlcm5hbC9pdGVtLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvbGFicy9pdGVtL2l0ZW0uanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9saXN0L2ludGVybmFsL2xpc3QtY29udHJvbGxlci5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL2xpc3QvaW50ZXJuYWwvbGlzdC1uYXZpZ2F0aW9uLWhlbHBlcnMuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9saXN0L2ludGVybmFsL2xpc3Qtc3R5bGVzLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvbGlzdC9pbnRlcm5hbC9saXN0LmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvbGlzdC9pbnRlcm5hbC9saXN0aXRlbS9saXN0LWl0ZW0tc3R5bGVzLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvbGlzdC9pbnRlcm5hbC9saXN0aXRlbS9saXN0LWl0ZW0uanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9tZW51L2ludGVybmFsL2NvbnRyb2xsZXJzL21lbnVJdGVtQ29udHJvbGxlci5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL21lbnUvaW50ZXJuYWwvY29udHJvbGxlcnMvc2hhcmVkLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvbWVudS9pbnRlcm5hbC9jb250cm9sbGVycy9zdXJmYWNlUG9zaXRpb25Db250cm9sbGVyLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvbWVudS9pbnRlcm5hbC9jb250cm9sbGVycy90eXBlYWhlYWRDb250cm9sbGVyLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvbWVudS9pbnRlcm5hbC9tZW51LXN0eWxlcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL21lbnUvaW50ZXJuYWwvbWVudS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL21lbnUvaW50ZXJuYWwvbWVudWl0ZW0vbWVudS1pdGVtLXN0eWxlcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL21lbnUvbWVudS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL3Byb2dyZXNzL2ludGVybmFsL2NpcmN1bGFyLXByb2dyZXNzLXN0eWxlcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL3Byb2dyZXNzL2ludGVybmFsL2NpcmN1bGFyLXByb2dyZXNzLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvcHJvZ3Jlc3MvaW50ZXJuYWwvcHJvZ3Jlc3MuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9zZWxlY3QvaW50ZXJuYWwvZmlsbGVkLXNlbGVjdC1zdHlsZXMuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9zZWxlY3QvaW50ZXJuYWwvZmlsbGVkLXNlbGVjdC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL3NlbGVjdC9pbnRlcm5hbC9zZWxlY3QuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9zZWxlY3QvaW50ZXJuYWwvc2VsZWN0b3B0aW9uL3NlbGVjdC1vcHRpb24uanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9zZWxlY3QvaW50ZXJuYWwvc2VsZWN0b3B0aW9uL3NlbGVjdE9wdGlvbkNvbnRyb2xsZXIuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi9zZWxlY3QvaW50ZXJuYWwvc2hhcmVkLXN0eWxlcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL3NlbGVjdC9pbnRlcm5hbC9zaGFyZWQuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvQG1hdGVyaWFsL3dlYi90ZXh0ZmllbGQvaW50ZXJuYWwvZmlsbGVkLXN0eWxlcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL3RleHRmaWVsZC9pbnRlcm5hbC9maWxsZWQtdGV4dC1maWVsZC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9AbWF0ZXJpYWwvd2ViL3RleHRmaWVsZC9pbnRlcm5hbC9zaGFyZWQtc3R5bGVzLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL0BtYXRlcmlhbC93ZWIvdGV4dGZpZWxkL2ludGVybmFsL3RleHQtZmllbGQuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvYXRvYi1saXRlL2F0b2ItYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvY29tcG9uZW50cy9ldy1jaGVja2JveC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvY29tcG9uZW50cy9ldy1jaXJjdWxhci1wcm9ncmVzcy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvY29tcG9uZW50cy9ldy1kaXZpZGVyLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcC13ZWItdG9vbHMvZGlzdC9jb21wb25lbnRzL2V3LWZpbGxlZC1zZWxlY3QuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L2NvbXBvbmVudHMvZXctZmlsbGVkLXRleHQtZmllbGQuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L2NvbXBvbmVudHMvZXctaWNvbi1idXR0b24uanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L2NvbXBvbmVudHMvZXctbGlzdC1pdGVtLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcC13ZWItdG9vbHMvZGlzdC9jb21wb25lbnRzL2V3LWxpc3QuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L2NvbXBvbmVudHMvZXctc2VsZWN0LW9wdGlvbi5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvY29tcG9uZW50cy9ld3QtY29uc29sZS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvY29tcG9uZW50cy9zdmcuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L2ZsYXNoLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcC13ZWItdG9vbHMvZGlzdC9pbnN0YWxsLWRpYWxvZy5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvcGFnZXMvZXd0LXBhZ2UtbWVzc2FnZS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvcGFnZXMvZXd0LXBhZ2UtcHJvZ3Jlc3MuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L3V0aWwvY29uc29sZS1jb2xvci5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvdXRpbC9maWxlLWRvd25sb2FkLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcC13ZWItdG9vbHMvZGlzdC91dGlsL2ZpcmUtZXZlbnQuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L3V0aWwvbGluZS1icmVhay10cmFuc2Zvcm1lci5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvdXRpbC9tYW5pZmVzdC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvdXRpbC9yZXNldC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvdXRpbC9zbGVlcC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3Atd2ViLXRvb2xzL2Rpc3QvdXRpbC90aW1lc3RhbXAtdHJhbnNmb3JtZXIuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwLXdlYi10b29scy9kaXN0L3ZlcnNpb24uanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwdG9vbC1qcy9saWIvZXNwbG9hZGVyLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL2luZGV4LmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3Jlc2V0LmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3N0dWJGbGFzaGVyLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3RhcmdldHMvcm9tLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3R5cGVzL2Vycm9yLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3V0aWwuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvZXNwdG9vbC1qcy9saWIvd2Vic2VyaWFsLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2ltcHJvdi13aWZpLXNlcmlhbC1zZGsvZGlzdC9jb25zdC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9pbXByb3Ytd2lmaS1zZXJpYWwtc2RrL2Rpc3Qvc2VyaWFsLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2ltcHJvdi13aWZpLXNlcmlhbC1zZGsvZGlzdC91dGlsL2hleC1mb3JtYXR0ZXIuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvaW1wcm92LXdpZmktc2VyaWFsLXNkay9kaXN0L3V0aWwvc2xlZXAuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvaW1wcm92LXdpZmktc2VyaWFsLXNkay9kaXN0L3V0aWwvdG8taGV4LmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2xpdC1odG1sL2RldmVsb3BtZW50L2RpcmVjdGl2ZS1oZWxwZXJzLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2xpdC1odG1sL2RldmVsb3BtZW50L2RpcmVjdGl2ZXMvbGl2ZS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9saXQtaHRtbC9kZXZlbG9wbWVudC9kaXJlY3RpdmVzL3N0eWxlLW1hcC5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9saXQtaHRtbC9kZXZlbG9wbWVudC9zdGF0aWMuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvbGl0L2RpcmVjdGl2ZXMvbGl2ZS5qcyIsIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9saXQvZGlyZWN0aXZlcy9zdHlsZS1tYXAuanMiLCJ3ZWJwYWNrOi8vVGFjdGlsaXR5IFdlYiBJbnN0YWxsZXIvLi9ub2RlX21vZHVsZXMvbGl0L3N0YXRpYy1odG1sLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL3Bha28vZGlzdC9wYWtvLmVzbS5tanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLy8gR2VuZXJhdGVkIHN0eWxlc2hlZXQgZm9yIC4vY2hlY2tib3gvaW50ZXJuYWwvY2hlY2tib3gtc3R5bGVzLmNzcy5cbmltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5leHBvcnQgY29uc3Qgc3R5bGVzID0gY3NzIGA6aG9zdHtib3JkZXItc3RhcnQtc3RhcnQtcmFkaXVzOnZhcigtLW1kLWNoZWNrYm94LWNvbnRhaW5lci1zaGFwZS1zdGFydC1zdGFydCwgdmFyKC0tbWQtY2hlY2tib3gtY29udGFpbmVyLXNoYXBlLCAycHgpKTtib3JkZXItc3RhcnQtZW5kLXJhZGl1czp2YXIoLS1tZC1jaGVja2JveC1jb250YWluZXItc2hhcGUtc3RhcnQtZW5kLCB2YXIoLS1tZC1jaGVja2JveC1jb250YWluZXItc2hhcGUsIDJweCkpO2JvcmRlci1lbmQtZW5kLXJhZGl1czp2YXIoLS1tZC1jaGVja2JveC1jb250YWluZXItc2hhcGUtZW5kLWVuZCwgdmFyKC0tbWQtY2hlY2tib3gtY29udGFpbmVyLXNoYXBlLCAycHgpKTtib3JkZXItZW5kLXN0YXJ0LXJhZGl1czp2YXIoLS1tZC1jaGVja2JveC1jb250YWluZXItc2hhcGUtZW5kLXN0YXJ0LCB2YXIoLS1tZC1jaGVja2JveC1jb250YWluZXItc2hhcGUsIDJweCkpO2Rpc3BsYXk6aW5saW5lLWZsZXg7aGVpZ2h0OnZhcigtLW1kLWNoZWNrYm94LWNvbnRhaW5lci1zaXplLCAxOHB4KTtwb3NpdGlvbjpyZWxhdGl2ZTt2ZXJ0aWNhbC1hbGlnbjp0b3A7d2lkdGg6dmFyKC0tbWQtY2hlY2tib3gtY29udGFpbmVyLXNpemUsIDE4cHgpOy13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjpyZ2JhKDAsMCwwLDApO2N1cnNvcjpwb2ludGVyfTpob3N0KFtkaXNhYmxlZF0pe2N1cnNvcjpkZWZhdWx0fTpob3N0KFt0b3VjaC10YXJnZXQ9d3JhcHBlcl0pe21hcmdpbjptYXgoMHB4LCg0OHB4IC0gdmFyKC0tbWQtY2hlY2tib3gtY29udGFpbmVyLXNpemUsIDE4cHgpKS8yKX1tZC1mb2N1cy1yaW5ne2hlaWdodDo0NHB4O2luc2V0OnVuc2V0O3dpZHRoOjQ0cHh9aW5wdXR7YXBwZWFyYW5jZTpub25lO2hlaWdodDo0OHB4O21hcmdpbjowO29wYWNpdHk6MDtvdXRsaW5lOm5vbmU7cG9zaXRpb246YWJzb2x1dGU7d2lkdGg6NDhweDt6LWluZGV4OjE7Y3Vyc29yOmluaGVyaXR9Omhvc3QoW3RvdWNoLXRhcmdldD1ub25lXSkgaW5wdXR7aGVpZ2h0OjEwMCU7d2lkdGg6MTAwJX0uY29udGFpbmVye2JvcmRlci1yYWRpdXM6aW5oZXJpdDtkaXNwbGF5OmZsZXg7aGVpZ2h0OjEwMCU7cGxhY2UtY29udGVudDpjZW50ZXI7cGxhY2UtaXRlbXM6Y2VudGVyO3Bvc2l0aW9uOnJlbGF0aXZlO3dpZHRoOjEwMCV9Lm91dGxpbmUsLmJhY2tncm91bmQsLmljb257aW5zZXQ6MDtwb3NpdGlvbjphYnNvbHV0ZX0ub3V0bGluZSwuYmFja2dyb3VuZHtib3JkZXItcmFkaXVzOmluaGVyaXR9Lm91dGxpbmV7Ym9yZGVyLWNvbG9yOnZhcigtLW1kLWNoZWNrYm94LW91dGxpbmUtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTtib3JkZXItc3R5bGU6c29saWQ7Ym9yZGVyLXdpZHRoOnZhcigtLW1kLWNoZWNrYm94LW91dGxpbmUtd2lkdGgsIDJweCk7Ym94LXNpemluZzpib3JkZXItYm94fS5iYWNrZ3JvdW5ke2JhY2tncm91bmQtY29sb3I6dmFyKC0tbWQtY2hlY2tib3gtc2VsZWN0ZWQtY29udGFpbmVyLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItcHJpbWFyeSwgIzY3NTBhNCkpfS5iYWNrZ3JvdW5kLC5pY29ue29wYWNpdHk6MDt0cmFuc2l0aW9uLWR1cmF0aW9uOjE1MG1zLDUwbXM7dHJhbnNpdGlvbi1wcm9wZXJ0eTp0cmFuc2Zvcm0sb3BhY2l0eTt0cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvbjpjdWJpYy1iZXppZXIoMC4zLCAwLCAwLjgsIDAuMTUpLGxpbmVhcjt0cmFuc2Zvcm06c2NhbGUoMC42KX06d2hlcmUoLnNlbGVjdGVkKSA6aXMoLmJhY2tncm91bmQsLmljb24pe29wYWNpdHk6MTt0cmFuc2l0aW9uLWR1cmF0aW9uOjM1MG1zLDUwbXM7dHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246Y3ViaWMtYmV6aWVyKDAuMDUsIDAuNywgMC4xLCAxKSxsaW5lYXI7dHJhbnNmb3JtOnNjYWxlKDEpfW1kLXJpcHBsZXtib3JkZXItcmFkaXVzOnZhcigtLW1kLWNoZWNrYm94LXN0YXRlLWxheWVyLXNoYXBlLCB2YXIoLS1tZC1zeXMtc2hhcGUtY29ybmVyLWZ1bGwsIDk5OTlweCkpO2hlaWdodDp2YXIoLS1tZC1jaGVja2JveC1zdGF0ZS1sYXllci1zaXplLCA0MHB4KTtpbnNldDp1bnNldDt3aWR0aDp2YXIoLS1tZC1jaGVja2JveC1zdGF0ZS1sYXllci1zaXplLCA0MHB4KTstLW1kLXJpcHBsZS1ob3Zlci1jb2xvcjogdmFyKC0tbWQtY2hlY2tib3gtaG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1tZC1yaXBwbGUtaG92ZXItb3BhY2l0eTogdmFyKC0tbWQtY2hlY2tib3gtaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4wOCk7LS1tZC1yaXBwbGUtcHJlc3NlZC1jb2xvcjogdmFyKC0tbWQtY2hlY2tib3gtcHJlc3NlZC1zdGF0ZS1sYXllci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLW1kLXJpcHBsZS1wcmVzc2VkLW9wYWNpdHk6IHZhcigtLW1kLWNoZWNrYm94LXByZXNzZWQtc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4xMil9LnNlbGVjdGVkIG1kLXJpcHBsZXstLW1kLXJpcHBsZS1ob3Zlci1jb2xvcjogdmFyKC0tbWQtY2hlY2tib3gtc2VsZWN0ZWQtaG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1wcmltYXJ5LCAjNjc1MGE0KSk7LS1tZC1yaXBwbGUtaG92ZXItb3BhY2l0eTogdmFyKC0tbWQtY2hlY2tib3gtc2VsZWN0ZWQtaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4wOCk7LS1tZC1yaXBwbGUtcHJlc3NlZC1jb2xvcjogdmFyKC0tbWQtY2hlY2tib3gtc2VsZWN0ZWQtcHJlc3NlZC1zdGF0ZS1sYXllci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLW1kLXJpcHBsZS1wcmVzc2VkLW9wYWNpdHk6IHZhcigtLW1kLWNoZWNrYm94LXNlbGVjdGVkLXByZXNzZWQtc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4xMil9Lmljb257ZmlsbDp2YXIoLS1tZC1jaGVja2JveC1zZWxlY3RlZC1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tcHJpbWFyeSwgI2ZmZikpO2hlaWdodDp2YXIoLS1tZC1jaGVja2JveC1pY29uLXNpemUsIDE4cHgpO3dpZHRoOnZhcigtLW1kLWNoZWNrYm94LWljb24tc2l6ZSwgMThweCl9Lm1hcmsuc2hvcnR7aGVpZ2h0OjJweDt0cmFuc2l0aW9uLXByb3BlcnR5OnRyYW5zZm9ybSxoZWlnaHQ7d2lkdGg6MnB4fS5tYXJrLmxvbmd7aGVpZ2h0OjJweDt0cmFuc2l0aW9uLXByb3BlcnR5OnRyYW5zZm9ybSx3aWR0aDt3aWR0aDoxMHB4fS5tYXJre2FuaW1hdGlvbi1kdXJhdGlvbjoxNTBtczthbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOmN1YmljLWJlemllcigwLjMsIDAsIDAuOCwgMC4xNSk7dHJhbnNpdGlvbi1kdXJhdGlvbjoxNTBtczt0cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvbjpjdWJpYy1iZXppZXIoMC4zLCAwLCAwLjgsIDAuMTUpfS5zZWxlY3RlZCAubWFya3thbmltYXRpb24tZHVyYXRpb246MzUwbXM7YW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjpjdWJpYy1iZXppZXIoMC4wNSwgMC43LCAwLjEsIDEpO3RyYW5zaXRpb24tZHVyYXRpb246MzUwbXM7dHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246Y3ViaWMtYmV6aWVyKDAuMDUsIDAuNywgMC4xLCAxKX0uY2hlY2tlZCAubWFyaywucHJldi1jaGVja2VkLnVuc2VsZWN0ZWQgLm1hcmt7dHJhbnNmb3JtOnNjYWxlWSgtMSkgdHJhbnNsYXRlKDdweCwgLTE0cHgpIHJvdGF0ZSg0NWRlZyl9LmNoZWNrZWQgLm1hcmsuc2hvcnQsLnByZXYtY2hlY2tlZC51bnNlbGVjdGVkIC5tYXJrLnNob3J0e2hlaWdodDo1LjY1Njg1NDI0OTVweH0uY2hlY2tlZCAubWFyay5sb25nLC5wcmV2LWNoZWNrZWQudW5zZWxlY3RlZCAubWFyay5sb25ne3dpZHRoOjExLjMxMzcwODQ5OXB4fS5pbmRldGVybWluYXRlIC5tYXJrLC5wcmV2LWluZGV0ZXJtaW5hdGUudW5zZWxlY3RlZCAubWFya3t0cmFuc2Zvcm06c2NhbGVZKC0xKSB0cmFuc2xhdGUoNHB4LCAtMTBweCkgcm90YXRlKDBkZWcpfS5wcmV2LXVuc2VsZWN0ZWQgLm1hcmt7dHJhbnNpdGlvbi1wcm9wZXJ0eTpub25lfS5wcmV2LXVuc2VsZWN0ZWQuY2hlY2tlZCAubWFyay5sb25ne2FuaW1hdGlvbi1uYW1lOnByZXYtdW5zZWxlY3RlZC10by1jaGVja2VkfUBrZXlmcmFtZXMgcHJldi11bnNlbGVjdGVkLXRvLWNoZWNrZWR7ZnJvbXt3aWR0aDowfX06d2hlcmUoOmhvdmVyKSAub3V0bGluZXtib3JkZXItY29sb3I6dmFyKC0tbWQtY2hlY2tib3gtaG92ZXItb3V0bGluZS1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTtib3JkZXItd2lkdGg6dmFyKC0tbWQtY2hlY2tib3gtaG92ZXItb3V0bGluZS13aWR0aCwgMnB4KX06d2hlcmUoOmhvdmVyKSAuYmFja2dyb3VuZHtiYWNrZ3JvdW5kOnZhcigtLW1kLWNoZWNrYm94LXNlbGVjdGVkLWhvdmVyLWNvbnRhaW5lci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKX06d2hlcmUoOmhvdmVyKSAuaWNvbntmaWxsOnZhcigtLW1kLWNoZWNrYm94LXNlbGVjdGVkLWhvdmVyLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1wcmltYXJ5LCAjZmZmKSl9OndoZXJlKDpmb2N1cy13aXRoaW4pIC5vdXRsaW5le2JvcmRlci1jb2xvcjp2YXIoLS1tZC1jaGVja2JveC1mb2N1cy1vdXRsaW5lLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpO2JvcmRlci13aWR0aDp2YXIoLS1tZC1jaGVja2JveC1mb2N1cy1vdXRsaW5lLXdpZHRoLCAycHgpfTp3aGVyZSg6Zm9jdXMtd2l0aGluKSAuYmFja2dyb3VuZHtiYWNrZ3JvdW5kOnZhcigtLW1kLWNoZWNrYm94LXNlbGVjdGVkLWZvY3VzLWNvbnRhaW5lci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKX06d2hlcmUoOmZvY3VzLXdpdGhpbikgLmljb257ZmlsbDp2YXIoLS1tZC1jaGVja2JveC1zZWxlY3RlZC1mb2N1cy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tcHJpbWFyeSwgI2ZmZikpfTp3aGVyZSg6YWN0aXZlKSAub3V0bGluZXtib3JkZXItY29sb3I6dmFyKC0tbWQtY2hlY2tib3gtcHJlc3NlZC1vdXRsaW5lLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpO2JvcmRlci13aWR0aDp2YXIoLS1tZC1jaGVja2JveC1wcmVzc2VkLW91dGxpbmUtd2lkdGgsIDJweCl9OndoZXJlKDphY3RpdmUpIC5iYWNrZ3JvdW5ke2JhY2tncm91bmQ6dmFyKC0tbWQtY2hlY2tib3gtc2VsZWN0ZWQtcHJlc3NlZC1jb250YWluZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1wcmltYXJ5LCAjNjc1MGE0KSl9OndoZXJlKDphY3RpdmUpIC5pY29ue2ZpbGw6dmFyKC0tbWQtY2hlY2tib3gtc2VsZWN0ZWQtcHJlc3NlZC1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tcHJpbWFyeSwgI2ZmZikpfTp3aGVyZSguZGlzYWJsZWQsLnByZXYtZGlzYWJsZWQpIDppcyguYmFja2dyb3VuZCwuaWNvbiwubWFyayl7YW5pbWF0aW9uLWR1cmF0aW9uOjBzO3RyYW5zaXRpb24tZHVyYXRpb246MHN9OndoZXJlKC5kaXNhYmxlZCkgLm91dGxpbmV7Ym9yZGVyLWNvbG9yOnZhcigtLW1kLWNoZWNrYm94LWRpc2FibGVkLW91dGxpbmUtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7Ym9yZGVyLXdpZHRoOnZhcigtLW1kLWNoZWNrYm94LWRpc2FibGVkLW91dGxpbmUtd2lkdGgsIDJweCk7b3BhY2l0eTp2YXIoLS1tZC1jaGVja2JveC1kaXNhYmxlZC1jb250YWluZXItb3BhY2l0eSwgMC4zOCl9OndoZXJlKC5zZWxlY3RlZC5kaXNhYmxlZCkgLm91dGxpbmV7dmlzaWJpbGl0eTpoaWRkZW59OndoZXJlKC5zZWxlY3RlZC5kaXNhYmxlZCkgLmJhY2tncm91bmR7YmFja2dyb3VuZDp2YXIoLS1tZC1jaGVja2JveC1zZWxlY3RlZC1kaXNhYmxlZC1jb250YWluZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7b3BhY2l0eTp2YXIoLS1tZC1jaGVja2JveC1zZWxlY3RlZC1kaXNhYmxlZC1jb250YWluZXItb3BhY2l0eSwgMC4zOCl9OndoZXJlKC5kaXNhYmxlZCkgLmljb257ZmlsbDp2YXIoLS1tZC1jaGVja2JveC1zZWxlY3RlZC1kaXNhYmxlZC1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itc3VyZmFjZSwgI2ZlZjdmZikpfUBtZWRpYShmb3JjZWQtY29sb3JzOiBhY3RpdmUpey5iYWNrZ3JvdW5ke2JhY2tncm91bmQtY29sb3I6Q2FudmFzVGV4dH0uc2VsZWN0ZWQuZGlzYWJsZWQgLmJhY2tncm91bmR7YmFja2dyb3VuZC1jb2xvcjpHcmF5VGV4dDtvcGFjaXR5OjF9Lm91dGxpbmV7Ym9yZGVyLWNvbG9yOkNhbnZhc1RleHR9LmRpc2FibGVkIC5vdXRsaW5le2JvcmRlci1jb2xvcjpHcmF5VGV4dDtvcGFjaXR5OjF9Lmljb257ZmlsbDpDYW52YXN9fVxuYDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoZWNrYm94LXN0eWxlcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgJy4uLy4uL2ZvY3VzL21kLWZvY3VzLXJpbmcuanMnO1xuaW1wb3J0ICcuLi8uLi9yaXBwbGUvcmlwcGxlLmpzJztcbmltcG9ydCB7IGh0bWwsIGlzU2VydmVyLCBMaXRFbGVtZW50LCBub3RoaW5nIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IHByb3BlcnR5LCBxdWVyeSwgc3RhdGUgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5pbXBvcnQgeyBjbGFzc01hcCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL2NsYXNzLW1hcC5qcyc7XG5pbXBvcnQgeyBtaXhpbkRlbGVnYXRlc0FyaWEgfSBmcm9tICcuLi8uLi9pbnRlcm5hbC9hcmlhL2RlbGVnYXRlLmpzJztcbmltcG9ydCB7IGRpc3BhdGNoQWN0aXZhdGlvbkNsaWNrLCBpc0FjdGl2YXRpb25DbGljaywgfSBmcm9tICcuLi8uLi9pbnRlcm5hbC9ldmVudHMvZm9ybS1sYWJlbC1hY3RpdmF0aW9uLmpzJztcbmltcG9ydCB7IHJlZGlzcGF0Y2hFdmVudCB9IGZyb20gJy4uLy4uL2ludGVybmFsL2V2ZW50cy9yZWRpc3BhdGNoLWV2ZW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZVZhbGlkYXRvciwgZ2V0VmFsaWRpdHlBbmNob3IsIG1peGluQ29uc3RyYWludFZhbGlkYXRpb24sIH0gZnJvbSAnLi4vLi4vbGFicy9iZWhhdmlvcnMvY29uc3RyYWludC12YWxpZGF0aW9uLmpzJztcbmltcG9ydCB7IG1peGluRWxlbWVudEludGVybmFscyB9IGZyb20gJy4uLy4uL2xhYnMvYmVoYXZpb3JzL2VsZW1lbnQtaW50ZXJuYWxzLmpzJztcbmltcG9ydCB7IGdldEZvcm1TdGF0ZSwgZ2V0Rm9ybVZhbHVlLCBtaXhpbkZvcm1Bc3NvY2lhdGVkLCB9IGZyb20gJy4uLy4uL2xhYnMvYmVoYXZpb3JzL2Zvcm0tYXNzb2NpYXRlZC5qcyc7XG5pbXBvcnQgeyBDaGVja2JveFZhbGlkYXRvciB9IGZyb20gJy4uLy4uL2xhYnMvYmVoYXZpb3JzL3ZhbGlkYXRvcnMvY2hlY2tib3gtdmFsaWRhdG9yLmpzJztcbi8vIFNlcGFyYXRlIHZhcmlhYmxlIG5lZWRlZCBmb3IgY2xvc3VyZS5cbmNvbnN0IGNoZWNrYm94QmFzZUNsYXNzID0gbWl4aW5EZWxlZ2F0ZXNBcmlhKG1peGluQ29uc3RyYWludFZhbGlkYXRpb24obWl4aW5Gb3JtQXNzb2NpYXRlZChtaXhpbkVsZW1lbnRJbnRlcm5hbHMoTGl0RWxlbWVudCkpKSk7XG4vKipcbiAqIEEgY2hlY2tib3ggY29tcG9uZW50LlxuICpcbiAqXG4gKiBAZmlyZXMgY2hhbmdlIHtFdmVudH0gVGhlIG5hdGl2ZSBgY2hhbmdlYCBldmVudCBvblxuICogW2A8aW5wdXQ+YF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxFbGVtZW50L2NoYW5nZV9ldmVudClcbiAqIC0tYnViYmxlc1xuICogQGZpcmVzIGlucHV0IHtJbnB1dEV2ZW50fSBUaGUgbmF0aXZlIGBpbnB1dGAgZXZlbnQgb25cbiAqIFtgPGlucHV0PmBdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MRWxlbWVudC9pbnB1dF9ldmVudClcbiAqIC0tYnViYmxlcyAtLWNvbXBvc2VkXG4gKi9cbmV4cG9ydCBjbGFzcyBDaGVja2JveCBleHRlbmRzIGNoZWNrYm94QmFzZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSBjaGVja2JveCBpcyBzZWxlY3RlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciBvciBub3QgdGhlIGNoZWNrYm94IGlzIGluZGV0ZXJtaW5hdGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9pbnB1dC9jaGVja2JveCNpbmRldGVybWluYXRlX3N0YXRlX2NoZWNrYm94ZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5kZXRlcm1pbmF0ZSA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hlbiB0cnVlLCByZXF1aXJlIHRoZSBjaGVja2JveCB0byBiZSBzZWxlY3RlZCB3aGVuIHBhcnRpY2lwYXRpbmcgaW5cbiAgICAgICAgICogZm9ybSBzdWJtaXNzaW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvaW5wdXQvY2hlY2tib3gjdmFsaWRhdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZXF1aXJlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIG9mIHRoZSBjaGVja2JveCB0aGF0IGlzIHN1Ym1pdHRlZCB3aXRoIGEgZm9ybSB3aGVuIHNlbGVjdGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvaW5wdXQvY2hlY2tib3gjdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudmFsdWUgPSAnb24nO1xuICAgICAgICB0aGlzLnByZXZDaGVja2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHJldkRpc2FibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHJldkluZGV0ZXJtaW5hdGUgPSBmYWxzZTtcbiAgICAgICAgaWYgKCFpc1NlcnZlcikge1xuICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNBY3RpdmF0aW9uQ2xpY2soZXZlbnQpIHx8ICF0aGlzLmlucHV0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1cygpO1xuICAgICAgICAgICAgICAgIGRpc3BhdGNoQWN0aXZhdGlvbkNsaWNrKHRoaXMuaW5wdXQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdXBkYXRlKGNoYW5nZWQpIHtcbiAgICAgICAgaWYgKGNoYW5nZWQuaGFzKCdjaGVja2VkJykgfHxcbiAgICAgICAgICAgIGNoYW5nZWQuaGFzKCdkaXNhYmxlZCcpIHx8XG4gICAgICAgICAgICBjaGFuZ2VkLmhhcygnaW5kZXRlcm1pbmF0ZScpKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZDaGVja2VkID0gY2hhbmdlZC5nZXQoJ2NoZWNrZWQnKSA/PyB0aGlzLmNoZWNrZWQ7XG4gICAgICAgICAgICB0aGlzLnByZXZEaXNhYmxlZCA9IGNoYW5nZWQuZ2V0KCdkaXNhYmxlZCcpID8/IHRoaXMuZGlzYWJsZWQ7XG4gICAgICAgICAgICB0aGlzLnByZXZJbmRldGVybWluYXRlID1cbiAgICAgICAgICAgICAgICBjaGFuZ2VkLmdldCgnaW5kZXRlcm1pbmF0ZScpID8/IHRoaXMuaW5kZXRlcm1pbmF0ZTtcbiAgICAgICAgfVxuICAgICAgICBzdXBlci51cGRhdGUoY2hhbmdlZCk7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgcHJldk5vbmUgPSAhdGhpcy5wcmV2Q2hlY2tlZCAmJiAhdGhpcy5wcmV2SW5kZXRlcm1pbmF0ZTtcbiAgICAgICAgY29uc3QgcHJldkNoZWNrZWQgPSB0aGlzLnByZXZDaGVja2VkICYmICF0aGlzLnByZXZJbmRldGVybWluYXRlO1xuICAgICAgICBjb25zdCBwcmV2SW5kZXRlcm1pbmF0ZSA9IHRoaXMucHJldkluZGV0ZXJtaW5hdGU7XG4gICAgICAgIGNvbnN0IGlzQ2hlY2tlZCA9IHRoaXMuY2hlY2tlZCAmJiAhdGhpcy5pbmRldGVybWluYXRlO1xuICAgICAgICBjb25zdCBpc0luZGV0ZXJtaW5hdGUgPSB0aGlzLmluZGV0ZXJtaW5hdGU7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5lckNsYXNzZXMgPSBjbGFzc01hcCh7XG4gICAgICAgICAgICAnZGlzYWJsZWQnOiB0aGlzLmRpc2FibGVkLFxuICAgICAgICAgICAgJ3NlbGVjdGVkJzogaXNDaGVja2VkIHx8IGlzSW5kZXRlcm1pbmF0ZSxcbiAgICAgICAgICAgICd1bnNlbGVjdGVkJzogIWlzQ2hlY2tlZCAmJiAhaXNJbmRldGVybWluYXRlLFxuICAgICAgICAgICAgJ2NoZWNrZWQnOiBpc0NoZWNrZWQsXG4gICAgICAgICAgICAnaW5kZXRlcm1pbmF0ZSc6IGlzSW5kZXRlcm1pbmF0ZSxcbiAgICAgICAgICAgICdwcmV2LXVuc2VsZWN0ZWQnOiBwcmV2Tm9uZSxcbiAgICAgICAgICAgICdwcmV2LWNoZWNrZWQnOiBwcmV2Q2hlY2tlZCxcbiAgICAgICAgICAgICdwcmV2LWluZGV0ZXJtaW5hdGUnOiBwcmV2SW5kZXRlcm1pbmF0ZSxcbiAgICAgICAgICAgICdwcmV2LWRpc2FibGVkJzogdGhpcy5wcmV2RGlzYWJsZWQsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBOZWVkZWQgZm9yIGNsb3N1cmUgY29uZm9ybWFuY2VcbiAgICAgICAgY29uc3QgeyBhcmlhTGFiZWwsIGFyaWFJbnZhbGlkIH0gPSB0aGlzO1xuICAgICAgICAvLyBOb3RlOiA8aW5wdXQ+IG5lZWRzIHRvIGJlIHJlbmRlcmVkIGJlZm9yZSB0aGUgPHN2Zz4gZm9yXG4gICAgICAgIC8vIGZvcm0ucmVwb3J0VmFsaWRpdHkoKSB0byB3b3JrIGluIENocm9tZS5cbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPGRpdiBjbGFzcz1cImNvbnRhaW5lciAke2NvbnRhaW5lckNsYXNzZXN9XCI+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgaWQ9XCJpbnB1dFwiXG4gICAgICAgICAgYXJpYS1jaGVja2VkPSR7aXNJbmRldGVybWluYXRlID8gJ21peGVkJyA6IG5vdGhpbmd9XG4gICAgICAgICAgYXJpYS1sYWJlbD0ke2FyaWFMYWJlbCB8fCBub3RoaW5nfVxuICAgICAgICAgIGFyaWEtaW52YWxpZD0ke2FyaWFJbnZhbGlkIHx8IG5vdGhpbmd9XG4gICAgICAgICAgP2Rpc2FibGVkPSR7dGhpcy5kaXNhYmxlZH1cbiAgICAgICAgICA/cmVxdWlyZWQ9JHt0aGlzLnJlcXVpcmVkfVxuICAgICAgICAgIC5pbmRldGVybWluYXRlPSR7dGhpcy5pbmRldGVybWluYXRlfVxuICAgICAgICAgIC5jaGVja2VkPSR7dGhpcy5jaGVja2VkfVxuICAgICAgICAgIEBpbnB1dD0ke3RoaXMuaGFuZGxlSW5wdXR9XG4gICAgICAgICAgQGNoYW5nZT0ke3RoaXMuaGFuZGxlQ2hhbmdlfSAvPlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJvdXRsaW5lXCI+PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJiYWNrZ3JvdW5kXCI+PC9kaXY+XG4gICAgICAgIDxtZC1mb2N1cy1yaW5nIHBhcnQ9XCJmb2N1cy1yaW5nXCIgZm9yPVwiaW5wdXRcIj48L21kLWZvY3VzLXJpbmc+XG4gICAgICAgIDxtZC1yaXBwbGUgZm9yPVwiaW5wdXRcIiA/ZGlzYWJsZWQ9JHt0aGlzLmRpc2FibGVkfT48L21kLXJpcHBsZT5cbiAgICAgICAgPHN2ZyBjbGFzcz1cImljb25cIiB2aWV3Qm94PVwiMCAwIDE4IDE4XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgPHJlY3QgY2xhc3M9XCJtYXJrIHNob3J0XCIgLz5cbiAgICAgICAgICA8cmVjdCBjbGFzcz1cIm1hcmsgbG9uZ1wiIC8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgICB9XG4gICAgaGFuZGxlSW5wdXQoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgICAgICB0aGlzLmNoZWNrZWQgPSB0YXJnZXQuY2hlY2tlZDtcbiAgICAgICAgdGhpcy5pbmRldGVybWluYXRlID0gdGFyZ2V0LmluZGV0ZXJtaW5hdGU7XG4gICAgICAgIC8vIDxpbnB1dD4gJ2lucHV0JyBldmVudCBidWJibGVzIGFuZCBpcyBjb21wb3NlZCwgZG9uJ3QgcmUtZGlzcGF0Y2ggaXQuXG4gICAgfVxuICAgIGhhbmRsZUNoYW5nZShldmVudCkge1xuICAgICAgICAvLyA8aW5wdXQ+ICdjaGFuZ2UnIGV2ZW50IGlzIG5vdCBjb21wb3NlZCwgcmUtZGlzcGF0Y2ggaXQuXG4gICAgICAgIHJlZGlzcGF0Y2hFdmVudCh0aGlzLCBldmVudCk7XG4gICAgfVxuICAgIFtnZXRGb3JtVmFsdWVdKCkge1xuICAgICAgICBpZiAoIXRoaXMuY2hlY2tlZCB8fCB0aGlzLmluZGV0ZXJtaW5hdGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cbiAgICBbZ2V0Rm9ybVN0YXRlXSgpIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZyh0aGlzLmNoZWNrZWQpO1xuICAgIH1cbiAgICBmb3JtUmVzZXRDYWxsYmFjaygpIHtcbiAgICAgICAgLy8gVGhlIGNoZWNrZWQgcHJvcGVydHkgZG9lcyBub3QgcmVmbGVjdCwgc28gdGhlIG9yaWdpbmFsIGF0dHJpYnV0ZSBzZXQgYnlcbiAgICAgICAgLy8gdGhlIHVzZXIgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIGRlZmF1bHQgdmFsdWUuXG4gICAgICAgIHRoaXMuY2hlY2tlZCA9IHRoaXMuaGFzQXR0cmlidXRlKCdjaGVja2VkJyk7XG4gICAgfVxuICAgIGZvcm1TdGF0ZVJlc3RvcmVDYWxsYmFjayhzdGF0ZSkge1xuICAgICAgICB0aGlzLmNoZWNrZWQgPSBzdGF0ZSA9PT0gJ3RydWUnO1xuICAgIH1cbiAgICBbY3JlYXRlVmFsaWRhdG9yXSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBDaGVja2JveFZhbGlkYXRvcigoKSA9PiB0aGlzKTtcbiAgICB9XG4gICAgW2dldFZhbGlkaXR5QW5jaG9yXSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQ7XG4gICAgfVxufVxuLyoqIEBub2NvbGxhcHNlICovXG5DaGVja2JveC5zaGFkb3dSb290T3B0aW9ucyA9IHtcbiAgICAuLi5MaXRFbGVtZW50LnNoYWRvd1Jvb3RPcHRpb25zLFxuICAgIGRlbGVnYXRlc0ZvY3VzOiB0cnVlLFxufTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiB9KVxuXSwgQ2hlY2tib3gucHJvdG90eXBlLCBcImNoZWNrZWRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiB9KVxuXSwgQ2hlY2tib3gucHJvdG90eXBlLCBcImluZGV0ZXJtaW5hdGVcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiB9KVxuXSwgQ2hlY2tib3gucHJvdG90eXBlLCBcInJlcXVpcmVkXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBDaGVja2JveC5wcm90b3R5cGUsIFwidmFsdWVcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIENoZWNrYm94LnByb3RvdHlwZSwgXCJwcmV2Q2hlY2tlZFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgQ2hlY2tib3gucHJvdG90eXBlLCBcInByZXZEaXNhYmxlZFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgQ2hlY2tib3gucHJvdG90eXBlLCBcInByZXZJbmRldGVybWluYXRlXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBxdWVyeSgnaW5wdXQnKVxuXSwgQ2hlY2tib3gucHJvdG90eXBlLCBcImlucHV0XCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGVja2JveC5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBjdXN0b21FbGVtZW50IH0gZnJvbSAnbGl0L2RlY29yYXRvcnMuanMnO1xuaW1wb3J0IHsgRWxldmF0aW9uIH0gZnJvbSAnLi9pbnRlcm5hbC9lbGV2YXRpb24uanMnO1xuaW1wb3J0IHsgc3R5bGVzIH0gZnJvbSAnLi9pbnRlcm5hbC9lbGV2YXRpb24tc3R5bGVzLmpzJztcbi8qKlxuICogVGhlIGA8bWQtZWxldmF0aW9uPmAgY3VzdG9tIGVsZW1lbnQgd2l0aCBkZWZhdWx0IHN0eWxlcy5cbiAqXG4gKiBFbGV2YXRpb24gaXMgdGhlIHJlbGF0aXZlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHN1cmZhY2VzIGFsb25nIHRoZSB6LWF4aXMuXG4gKlxuICogQGZpbmFsXG4gKiBAc3VwcHJlc3Mge3Zpc2liaWxpdHl9XG4gKi9cbmxldCBNZEVsZXZhdGlvbiA9IGNsYXNzIE1kRWxldmF0aW9uIGV4dGVuZHMgRWxldmF0aW9uIHtcbn07XG5NZEVsZXZhdGlvbi5zdHlsZXMgPSBbc3R5bGVzXTtcbk1kRWxldmF0aW9uID0gX19kZWNvcmF0ZShbXG4gICAgY3VzdG9tRWxlbWVudCgnbWQtZWxldmF0aW9uJylcbl0sIE1kRWxldmF0aW9uKTtcbmV4cG9ydCB7IE1kRWxldmF0aW9uIH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lbGV2YXRpb24uanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLy8gR2VuZXJhdGVkIHN0eWxlc2hlZXQgZm9yIC4vZWxldmF0aW9uL2ludGVybmFsL2VsZXZhdGlvbi1zdHlsZXMuY3NzLlxuaW1wb3J0IHsgY3NzIH0gZnJvbSAnbGl0JztcbmV4cG9ydCBjb25zdCBzdHlsZXMgPSBjc3MgYDpob3N0LC5zaGFkb3csLnNoYWRvdzo6YmVmb3JlLC5zaGFkb3c6OmFmdGVye2JvcmRlci1yYWRpdXM6aW5oZXJpdDtpbnNldDowO3Bvc2l0aW9uOmFic29sdXRlO3RyYW5zaXRpb24tZHVyYXRpb246aW5oZXJpdDt0cmFuc2l0aW9uLXByb3BlcnR5OmluaGVyaXQ7dHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246aW5oZXJpdH06aG9zdHtkaXNwbGF5OmZsZXg7cG9pbnRlci1ldmVudHM6bm9uZTt0cmFuc2l0aW9uLXByb3BlcnR5OmJveC1zaGFkb3csb3BhY2l0eX0uc2hhZG93OjpiZWZvcmUsLnNoYWRvdzo6YWZ0ZXJ7Y29udGVudDpcIlwiO3RyYW5zaXRpb24tcHJvcGVydHk6Ym94LXNoYWRvdyxvcGFjaXR5Oy0tX2xldmVsOiB2YXIoLS1tZC1lbGV2YXRpb24tbGV2ZWwsIDApOy0tX3NoYWRvdy1jb2xvcjogdmFyKC0tbWQtZWxldmF0aW9uLXNoYWRvdy1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXNoYWRvdywgIzAwMCkpfS5zaGFkb3c6OmJlZm9yZXtib3gtc2hhZG93OjBweCBjYWxjKDFweCooY2xhbXAoMCx2YXIoLS1fbGV2ZWwpLDEpICsgY2xhbXAoMCx2YXIoLS1fbGV2ZWwpIC0gMywxKSArIDIqY2xhbXAoMCx2YXIoLS1fbGV2ZWwpIC0gNCwxKSkpIGNhbGMoMXB4KigyKmNsYW1wKDAsdmFyKC0tX2xldmVsKSwxKSArIGNsYW1wKDAsdmFyKC0tX2xldmVsKSAtIDIsMSkgKyBjbGFtcCgwLHZhcigtLV9sZXZlbCkgLSA0LDEpKSkgMHB4IHZhcigtLV9zaGFkb3ctY29sb3IpO29wYWNpdHk6LjN9LnNoYWRvdzo6YWZ0ZXJ7Ym94LXNoYWRvdzowcHggY2FsYygxcHgqKGNsYW1wKDAsdmFyKC0tX2xldmVsKSwxKSArIGNsYW1wKDAsdmFyKC0tX2xldmVsKSAtIDEsMSkgKyAyKmNsYW1wKDAsdmFyKC0tX2xldmVsKSAtIDIsMykpKSBjYWxjKDFweCooMypjbGFtcCgwLHZhcigtLV9sZXZlbCksMikgKyAyKmNsYW1wKDAsdmFyKC0tX2xldmVsKSAtIDIsMykpKSBjYWxjKDFweCooY2xhbXAoMCx2YXIoLS1fbGV2ZWwpLDQpICsgMipjbGFtcCgwLHZhcigtLV9sZXZlbCkgLSA0LDEpKSkgdmFyKC0tX3NoYWRvdy1jb2xvcik7b3BhY2l0eTouMTV9XG5gO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZWxldmF0aW9uLXN0eWxlcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBodG1sLCBMaXRFbGVtZW50IH0gZnJvbSAnbGl0Jztcbi8qKlxuICogQSBjb21wb25lbnQgZm9yIGVsZXZhdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIEVsZXZhdGlvbiBleHRlbmRzIExpdEVsZW1lbnQge1xuICAgIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgICAgICBzdXBlci5jb25uZWN0ZWRDYWxsYmFjaygpO1xuICAgICAgICAvLyBOZWVkZWQgZm9yIFZvaWNlT3Zlciwgd2hpY2ggd2lsbCBjcmVhdGUgYSBcImdyb3VwXCIgaWYgdGhlIGVsZW1lbnQgaXMgYVxuICAgICAgICAvLyBzaWJsaW5nIHRvIG90aGVyIGNvbnRlbnQuXG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYDxzcGFuIGNsYXNzPVwic2hhZG93XCI+PC9zcGFuPmA7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZWxldmF0aW9uLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGN1c3RvbUVsZW1lbnQgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5pbXBvcnQgeyBGaWxsZWRGaWVsZCB9IGZyb20gJy4vaW50ZXJuYWwvZmlsbGVkLWZpZWxkLmpzJztcbmltcG9ydCB7IHN0eWxlcyBhcyBmaWxsZWRTdHlsZXMgfSBmcm9tICcuL2ludGVybmFsL2ZpbGxlZC1zdHlsZXMuanMnO1xuaW1wb3J0IHsgc3R5bGVzIGFzIHNoYXJlZFN0eWxlcyB9IGZyb20gJy4vaW50ZXJuYWwvc2hhcmVkLXN0eWxlcy5qcyc7XG4vKipcbiAqIFRPRE8oYi8yMjg1MjU3OTcpOiBhZGQgZG9jc1xuICogQGZpbmFsXG4gKiBAc3VwcHJlc3Mge3Zpc2liaWxpdHl9XG4gKi9cbmxldCBNZEZpbGxlZEZpZWxkID0gY2xhc3MgTWRGaWxsZWRGaWVsZCBleHRlbmRzIEZpbGxlZEZpZWxkIHtcbn07XG5NZEZpbGxlZEZpZWxkLnN0eWxlcyA9IFtzaGFyZWRTdHlsZXMsIGZpbGxlZFN0eWxlc107XG5NZEZpbGxlZEZpZWxkID0gX19kZWNvcmF0ZShbXG4gICAgY3VzdG9tRWxlbWVudCgnbWQtZmlsbGVkLWZpZWxkJylcbl0sIE1kRmlsbGVkRmllbGQpO1xuZXhwb3J0IHsgTWRGaWxsZWRGaWVsZCB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmlsbGVkLWZpZWxkLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIxIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGh0bWwsIExpdEVsZW1lbnQsIG5vdGhpbmcsIHJlbmRlciwgfSBmcm9tICdsaXQnO1xuaW1wb3J0IHsgcHJvcGVydHksIHF1ZXJ5LCBxdWVyeUFzc2lnbmVkRWxlbWVudHMsIHN0YXRlIH0gZnJvbSAnbGl0L2RlY29yYXRvcnMuanMnO1xuaW1wb3J0IHsgY2xhc3NNYXAgfSBmcm9tICdsaXQvZGlyZWN0aXZlcy9jbGFzcy1tYXAuanMnO1xuaW1wb3J0IHsgRUFTSU5HIH0gZnJvbSAnLi4vLi4vaW50ZXJuYWwvbW90aW9uL2FuaW1hdGlvbi5qcyc7XG4vKipcbiAqIEEgZmllbGQgY29tcG9uZW50LlxuICovXG5leHBvcnQgY2xhc3MgRmllbGQgZXh0ZW5kcyBMaXRFbGVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVycm9yID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZm9jdXNlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxhYmVsID0gJyc7XG4gICAgICAgIHRoaXMubm9Bc3RlcmlzayA9IGZhbHNlO1xuICAgICAgICB0aGlzLnBvcHVsYXRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlcXVpcmVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVzaXphYmxlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3VwcG9ydGluZ1RleHQgPSAnJztcbiAgICAgICAgdGhpcy5lcnJvclRleHQgPSAnJztcbiAgICAgICAgdGhpcy5jb3VudCA9IC0xO1xuICAgICAgICB0aGlzLm1heCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciBvciBub3QgdGhlIGZpZWxkIGhhcyBsZWFkaW5nIGNvbnRlbnQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmhhc1N0YXJ0ID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgZmllbGQgaGFzIHRyYWlsaW5nIGNvbnRlbnQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmhhc0VuZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmlzQW5pbWF0aW5nID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGVuIHNldCB0byB0cnVlLCB0aGUgZXJyb3IgdGV4dCdzIGByb2xlPVwiYWxlcnRcImAgd2lsbCBiZSByZW1vdmVkLCB0aGVuXG4gICAgICAgICAqIHJlLWFkZGVkIGFmdGVyIGFuIGFuaW1hdGlvbiBmcmFtZS4gVGhpcyB3aWxsIHJlLWFubm91bmNlIGFuIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgICogdG8gc2NyZWVuIHJlYWRlcnMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnJlZnJlc2hFcnJvckFsZXJ0ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZGlzYWJsZVRyYW5zaXRpb25zID0gZmFsc2U7XG4gICAgfVxuICAgIGdldCBjb3VudGVyVGV4dCgpIHtcbiAgICAgICAgLy8gQ291bnQgYW5kIG1heCBhcmUgdHlwZWQgYXMgbnVtYmVyLCBidXQgY2FuIGJlIHNldCB0byBudWxsIHdoZW4gTGl0IHJlbW92ZXNcbiAgICAgICAgLy8gdGhlaXIgYXR0cmlidXRlcy4gVGhlc2UgZ2V0dGVycyBjb2VyY2UgYmFjayB0byBhIG51bWJlciBmb3IgY2FsY3VsYXRpb25zLlxuICAgICAgICBjb25zdCBjb3VudEFzTnVtYmVyID0gdGhpcy5jb3VudCA/PyAtMTtcbiAgICAgICAgY29uc3QgbWF4QXNOdW1iZXIgPSB0aGlzLm1heCA/PyAtMTtcbiAgICAgICAgLy8gQ291bnRlciBkb2VzIG5vdCBzaG93IGlmIGNvdW50IGlzIG5lZ2F0aXZlLCBvciBtYXggaXMgbmVnYXRpdmUgb3IgMC5cbiAgICAgICAgaWYgKGNvdW50QXNOdW1iZXIgPCAwIHx8IG1heEFzTnVtYmVyIDw9IDApIHtcbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYCR7Y291bnRBc051bWJlcn0gLyAke21heEFzTnVtYmVyfWA7XG4gICAgfVxuICAgIGdldCBzdXBwb3J0aW5nT3JFcnJvclRleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yICYmIHRoaXMuZXJyb3JUZXh0ID8gdGhpcy5lcnJvclRleHQgOiB0aGlzLnN1cHBvcnRpbmdUZXh0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZS1hbm5vdW5jZXMgdGhlIGZpZWxkJ3MgZXJyb3Igc3VwcG9ydGluZyB0ZXh0IHRvIHNjcmVlbiByZWFkZXJzLlxuICAgICAqXG4gICAgICogRXJyb3IgdGV4dCBhbm5vdW5jZXMgdG8gc2NyZWVuIHJlYWRlcnMgYW55dGltZSBpdCBpcyB2aXNpYmxlIGFuZCBjaGFuZ2VzLlxuICAgICAqIFVzZSB0aGUgbWV0aG9kIHRvIHJlLWFubm91bmNlIHRoZSBtZXNzYWdlIHdoZW4gdGhlIHRleHQgaGFzIG5vdCBjaGFuZ2VkLFxuICAgICAqIGJ1dCBhbm5vdW5jZW1lbnQgaXMgc3RpbGwgbmVlZGVkIChzdWNoIGFzIGZvciBgcmVwb3J0VmFsaWRpdHkoKWApLlxuICAgICAqL1xuICAgIHJlYW5ub3VuY2VFcnJvcigpIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoRXJyb3JBbGVydCA9IHRydWU7XG4gICAgfVxuICAgIHVwZGF0ZShwcm9wcykge1xuICAgICAgICAvLyBDbGllbnQtc2lkZSBwcm9wZXJ0eSB1cGRhdGVzXG4gICAgICAgIGNvbnN0IGlzRGlzYWJsZWRDaGFuZ2luZyA9IHByb3BzLmhhcygnZGlzYWJsZWQnKSAmJiBwcm9wcy5nZXQoJ2Rpc2FibGVkJykgIT09IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGlzRGlzYWJsZWRDaGFuZ2luZykge1xuICAgICAgICAgICAgdGhpcy5kaXNhYmxlVHJhbnNpdGlvbnMgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdoZW4gZGlzYWJsaW5nLCByZW1vdmUgZm9jdXMgc3R5bGVzIGlmIGZvY3VzZWQuXG4gICAgICAgIGlmICh0aGlzLmRpc2FibGVkICYmIHRoaXMuZm9jdXNlZCkge1xuICAgICAgICAgICAgcHJvcHMuc2V0KCdmb2N1c2VkJywgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmZvY3VzZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBBbmltYXRlIGlmIGZvY3VzZWQgb3IgcG9wdWxhdGVkIGNoYW5nZS5cbiAgICAgICAgdGhpcy5hbmltYXRlTGFiZWxJZk5lZWRlZCh7XG4gICAgICAgICAgICB3YXNGb2N1c2VkOiBwcm9wcy5nZXQoJ2ZvY3VzZWQnKSxcbiAgICAgICAgICAgIHdhc1BvcHVsYXRlZDogcHJvcHMuZ2V0KCdwb3B1bGF0ZWQnKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHN1cGVyLnVwZGF0ZShwcm9wcyk7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgZmxvYXRpbmdMYWJlbCA9IHRoaXMucmVuZGVyTGFiZWwoLyppc0Zsb2F0aW5nKi8gdHJ1ZSk7XG4gICAgICAgIGNvbnN0IHJlc3RpbmdMYWJlbCA9IHRoaXMucmVuZGVyTGFiZWwoLyppc0Zsb2F0aW5nKi8gZmFsc2UpO1xuICAgICAgICBjb25zdCBvdXRsaW5lID0gdGhpcy5yZW5kZXJPdXRsaW5lPy4oZmxvYXRpbmdMYWJlbCk7XG4gICAgICAgIGNvbnN0IGNsYXNzZXMgPSB7XG4gICAgICAgICAgICAnZGlzYWJsZWQnOiB0aGlzLmRpc2FibGVkLFxuICAgICAgICAgICAgJ2Rpc2FibGUtdHJhbnNpdGlvbnMnOiB0aGlzLmRpc2FibGVUcmFuc2l0aW9ucyxcbiAgICAgICAgICAgICdlcnJvcic6IHRoaXMuZXJyb3IgJiYgIXRoaXMuZGlzYWJsZWQsXG4gICAgICAgICAgICAnZm9jdXNlZCc6IHRoaXMuZm9jdXNlZCxcbiAgICAgICAgICAgICd3aXRoLXN0YXJ0JzogdGhpcy5oYXNTdGFydCxcbiAgICAgICAgICAgICd3aXRoLWVuZCc6IHRoaXMuaGFzRW5kLFxuICAgICAgICAgICAgJ3BvcHVsYXRlZCc6IHRoaXMucG9wdWxhdGVkLFxuICAgICAgICAgICAgJ3Jlc2l6YWJsZSc6IHRoaXMucmVzaXphYmxlLFxuICAgICAgICAgICAgJ3JlcXVpcmVkJzogdGhpcy5yZXF1aXJlZCxcbiAgICAgICAgICAgICduby1sYWJlbCc6ICF0aGlzLmxhYmVsLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8ZGl2IGNsYXNzPVwiZmllbGQgJHtjbGFzc01hcChjbGFzc2VzKX1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRhaW5lci1vdmVyZmxvd1wiPlxuICAgICAgICAgICR7dGhpcy5yZW5kZXJCYWNrZ3JvdW5kPy4oKX1cbiAgICAgICAgICA8c2xvdCBuYW1lPVwiY29udGFpbmVyXCI+PC9zbG90PlxuICAgICAgICAgICR7dGhpcy5yZW5kZXJTdGF0ZUxheWVyPy4oKX0gJHt0aGlzLnJlbmRlckluZGljYXRvcj8uKCl9ICR7b3V0bGluZX1cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhcnRcIj5cbiAgICAgICAgICAgICAgPHNsb3QgbmFtZT1cInN0YXJ0XCI+PC9zbG90PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWlkZGxlXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC13cmFwcGVyXCI+XG4gICAgICAgICAgICAgICAgJHtyZXN0aW5nTGFiZWx9ICR7b3V0bGluZSA/IG5vdGhpbmcgOiBmbG9hdGluZ0xhYmVsfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICA8c2xvdD48L3Nsb3Q+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW5kXCI+XG4gICAgICAgICAgICAgIDxzbG90IG5hbWU9XCJlbmRcIj48L3Nsb3Q+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgICR7dGhpcy5yZW5kZXJTdXBwb3J0aW5nVGV4dCgpfVxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgICB9XG4gICAgdXBkYXRlZChjaGFuZ2VkKSB7XG4gICAgICAgIGlmIChjaGFuZ2VkLmhhcygnc3VwcG9ydGluZ1RleHQnKSB8fFxuICAgICAgICAgICAgY2hhbmdlZC5oYXMoJ2Vycm9yVGV4dCcpIHx8XG4gICAgICAgICAgICBjaGFuZ2VkLmhhcygnY291bnQnKSB8fFxuICAgICAgICAgICAgY2hhbmdlZC5oYXMoJ21heCcpKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNsb3R0ZWRBcmlhRGVzY3JpYmVkQnkoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5yZWZyZXNoRXJyb3JBbGVydCkge1xuICAgICAgICAgICAgLy8gVGhlIHBhc3QgcmVuZGVyIGN5Y2xlIHJlbW92ZWQgdGhlIHJvbGU9XCJhbGVydFwiIGZyb20gdGhlIGVycm9yIG1lc3NhZ2UuXG4gICAgICAgICAgICAvLyBSZS1hZGQgaXQgYWZ0ZXIgYW4gYW5pbWF0aW9uIGZyYW1lIHRvIHJlLWFubm91bmNlIHRoZSBlcnJvci5cbiAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWZyZXNoRXJyb3JBbGVydCA9IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZGlzYWJsZVRyYW5zaXRpb25zKSB7XG4gICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZVRyYW5zaXRpb25zID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZW5kZXJTdXBwb3J0aW5nVGV4dCgpIHtcbiAgICAgICAgY29uc3QgeyBzdXBwb3J0aW5nT3JFcnJvclRleHQsIGNvdW50ZXJUZXh0IH0gPSB0aGlzO1xuICAgICAgICBpZiAoIXN1cHBvcnRpbmdPckVycm9yVGV4dCAmJiAhY291bnRlclRleHQpIHtcbiAgICAgICAgICAgIHJldHVybiBub3RoaW5nO1xuICAgICAgICB9XG4gICAgICAgIC8vIEFsd2F5cyByZW5kZXIgdGhlIHN1cHBvcnRpbmcgdGV4dCBzcGFuIHNvIHRoYXQgb3VyIGBzcGFjZS1hcm91bmRgXG4gICAgICAgIC8vIGNvbnRhaW5lciBwdXRzIHRoZSBjb3VudGVyIGF0IHRoZSBlbmQuXG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gaHRtbCBgPHNwYW4+JHtzdXBwb3J0aW5nT3JFcnJvclRleHR9PC9zcGFuPmA7XG4gICAgICAgIC8vIENvbmRpdGlvbmFsbHkgcmVuZGVyIGNvdW50ZXIgc28gd2UgZG9uJ3QgcmVuZGVyIHRoZSBleHRyYSBgZ2FwYC5cbiAgICAgICAgLy8gVE9ETyhiLzI0NDQ3MzQzNSk6IGFkZCBhcmlhLWxhYmVsIGFuZCBhbm5vdW5jZW1lbnRzXG4gICAgICAgIGNvbnN0IGVuZCA9IGNvdW50ZXJUZXh0XG4gICAgICAgICAgICA/IGh0bWwgYDxzcGFuIGNsYXNzPVwiY291bnRlclwiPiR7Y291bnRlclRleHR9PC9zcGFuPmBcbiAgICAgICAgICAgIDogbm90aGluZztcbiAgICAgICAgLy8gQW5ub3VuY2UgaWYgdGhlcmUgaXMgYW4gZXJyb3IgYW5kIGVycm9yIHRleHQgdmlzaWJsZS5cbiAgICAgICAgLy8gSWYgcmVmcmVzaEVycm9yQWxlcnQgaXMgdHJ1ZSwgZG8gbm90IGFubm91bmNlLiBUaGlzIHdpbGwgcmVtb3ZlIHRoZVxuICAgICAgICAvLyByb2xlPVwiYWxlcnRcIiBhdHRyaWJ1dGUuIEFub3RoZXIgcmVuZGVyIGN5Y2xlIHdpbGwgaGFwcGVuIGFmdGVyIGFuXG4gICAgICAgIC8vIGFuaW1hdGlvbiBmcmFtZSB0byByZS1hZGQgdGhlIHJvbGUuXG4gICAgICAgIGNvbnN0IHNob3VsZEVycm9yQW5ub3VuY2UgPSB0aGlzLmVycm9yICYmIHRoaXMuZXJyb3JUZXh0ICYmICF0aGlzLnJlZnJlc2hFcnJvckFsZXJ0O1xuICAgICAgICBjb25zdCByb2xlID0gc2hvdWxkRXJyb3JBbm5vdW5jZSA/ICdhbGVydCcgOiBub3RoaW5nO1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8ZGl2IGNsYXNzPVwic3VwcG9ydGluZy10ZXh0XCIgcm9sZT0ke3JvbGV9PiR7c3RhcnR9JHtlbmR9PC9kaXY+XG4gICAgICA8c2xvdFxuICAgICAgICBuYW1lPVwiYXJpYS1kZXNjcmliZWRieVwiXG4gICAgICAgIEBzbG90Y2hhbmdlPSR7dGhpcy51cGRhdGVTbG90dGVkQXJpYURlc2NyaWJlZEJ5fT48L3Nsb3Q+XG4gICAgYDtcbiAgICB9XG4gICAgdXBkYXRlU2xvdHRlZEFyaWFEZXNjcmliZWRCeSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHRoaXMuc2xvdHRlZEFyaWFEZXNjcmliZWRCeSkge1xuICAgICAgICAgICAgcmVuZGVyKGh0bWwgYCR7dGhpcy5zdXBwb3J0aW5nT3JFcnJvclRleHR9ICR7dGhpcy5jb3VudGVyVGV4dH1gLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdoaWRkZW4nLCAnJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVuZGVyTGFiZWwoaXNGbG9hdGluZykge1xuICAgICAgICBpZiAoIXRoaXMubGFiZWwpIHtcbiAgICAgICAgICAgIHJldHVybiBub3RoaW5nO1xuICAgICAgICB9XG4gICAgICAgIGxldCB2aXNpYmxlO1xuICAgICAgICBpZiAoaXNGbG9hdGluZykge1xuICAgICAgICAgICAgLy8gRmxvYXRpbmcgbGFiZWwgaXMgdmlzaWJsZSB3aGVuIGZvY3VzZWQvcG9wdWxhdGVkIG9yIHdoZW4gYW5pbWF0aW5nLlxuICAgICAgICAgICAgdmlzaWJsZSA9IHRoaXMuZm9jdXNlZCB8fCB0aGlzLnBvcHVsYXRlZCB8fCB0aGlzLmlzQW5pbWF0aW5nO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gUmVzdGluZyBsYWJlbCBpcyB2aXNpYmxlIHdoZW4gdW5mb2N1c2VkLiBJdCBpcyBuZXZlciB2aXNpYmxlIHdoaWxlXG4gICAgICAgICAgICAvLyBhbmltYXRpbmcuXG4gICAgICAgICAgICB2aXNpYmxlID0gIXRoaXMuZm9jdXNlZCAmJiAhdGhpcy5wb3B1bGF0ZWQgJiYgIXRoaXMuaXNBbmltYXRpbmc7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IHtcbiAgICAgICAgICAgICdoaWRkZW4nOiAhdmlzaWJsZSxcbiAgICAgICAgICAgICdmbG9hdGluZyc6IGlzRmxvYXRpbmcsXG4gICAgICAgICAgICAncmVzdGluZyc6ICFpc0Zsb2F0aW5nLFxuICAgICAgICB9O1xuICAgICAgICAvLyBBZGQgJyonIGlmIGEgbGFiZWwgaXMgcHJlc2VudCBhbmQgdGhlIGZpZWxkIGlzIHJlcXVpcmVkXG4gICAgICAgIGNvbnN0IGxhYmVsVGV4dCA9IGAke3RoaXMubGFiZWx9JHt0aGlzLnJlcXVpcmVkICYmICF0aGlzLm5vQXN0ZXJpc2sgPyAnKicgOiAnJ31gO1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8c3BhbiBjbGFzcz1cImxhYmVsICR7Y2xhc3NNYXAoY2xhc3Nlcyl9XCIgYXJpYS1oaWRkZW49JHshdmlzaWJsZX1cbiAgICAgICAgPiR7bGFiZWxUZXh0fTwvc3BhblxuICAgICAgPlxuICAgIGA7XG4gICAgfVxuICAgIGFuaW1hdGVMYWJlbElmTmVlZGVkKHsgd2FzRm9jdXNlZCwgd2FzUG9wdWxhdGVkLCB9KSB7XG4gICAgICAgIGlmICghdGhpcy5sYWJlbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHdhc0ZvY3VzZWQgPz89IHRoaXMuZm9jdXNlZDtcbiAgICAgICAgd2FzUG9wdWxhdGVkID8/PSB0aGlzLnBvcHVsYXRlZDtcbiAgICAgICAgY29uc3Qgd2FzRmxvYXRpbmcgPSB3YXNGb2N1c2VkIHx8IHdhc1BvcHVsYXRlZDtcbiAgICAgICAgY29uc3Qgc2hvdWxkQmVGbG9hdGluZyA9IHRoaXMuZm9jdXNlZCB8fCB0aGlzLnBvcHVsYXRlZDtcbiAgICAgICAgaWYgKHdhc0Zsb2F0aW5nID09PSBzaG91bGRCZUZsb2F0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pc0FuaW1hdGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMubGFiZWxBbmltYXRpb24/LmNhbmNlbCgpO1xuICAgICAgICAvLyBPbmx5IG9uZSBsYWJlbCBpcyB2aXNpYmxlIGF0IGEgdGltZSBmb3IgY2xlYXJlciB0ZXh0IHJlbmRlcmluZy5cbiAgICAgICAgLy8gVGhlIGZsb2F0aW5nIGxhYmVsIGlzIHZpc2libGUgYW5kIHVzZWQgZHVyaW5nIGFuaW1hdGlvbi4gQXQgdGhlIGVuZCBvZlxuICAgICAgICAvLyB0aGUgYW5pbWF0aW9uLCBpdCB3aWxsIGVpdGhlciByZW1haW4gdmlzaWJsZSAoaWYgZmxvYXRpbmcpIG9yIGhpZGUgYW5kXG4gICAgICAgIC8vIHRoZSByZXN0aW5nIGxhYmVsIHdpbGwgYmUgc2hvd24uXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFdlIGRvbid0IHVzZSBmb3J3YXJkIGZpbGxpbmcgYmVjYXVzZSBpZiB0aGUgZGltZW5zaW9ucyBvZiB0aGUgdGV4dCBmaWVsZFxuICAgICAgICAvLyBjaGFuZ2UgKGxlYWRpbmcgaWNvbiByZW1vdmVkLCBkZW5zaXR5IGNoYW5nZXMsIGV0YyksIHRoZW4gdGhlIGFuaW1hdGlvblxuICAgICAgICAvLyB3aWxsIGJlIGluYWNjdXJhdGUuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFJlLWNhbGN1bGF0aW5nIHRoZSBhbmltYXRpb24gZWFjaCB0aW1lIHdpbGwgcHJldmVudCBhbnkgdmlzdWFsIGdsaXRjaGVzXG4gICAgICAgIC8vIGZyb20gYXBwZWFyaW5nLlxuICAgICAgICAvLyBUT0RPKGIvMjQxMTEzMzQ1KTogdXNlIGFuaW1hdGlvbiB0b2tlbnNcbiAgICAgICAgdGhpcy5sYWJlbEFuaW1hdGlvbiA9IHRoaXMuZmxvYXRpbmdMYWJlbEVsPy5hbmltYXRlKHRoaXMuZ2V0TGFiZWxLZXlmcmFtZXMoKSwgeyBkdXJhdGlvbjogMTUwLCBlYXNpbmc6IEVBU0lORy5TVEFOREFSRCB9KTtcbiAgICAgICAgdGhpcy5sYWJlbEFuaW1hdGlvbj8uYWRkRXZlbnRMaXN0ZW5lcignZmluaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgLy8gQXQgdGhlIGVuZCBvZiB0aGUgYW5pbWF0aW9uLCB1cGRhdGUgdGhlIHZpc2libGUgbGFiZWwuXG4gICAgICAgICAgICB0aGlzLmlzQW5pbWF0aW5nID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBnZXRMYWJlbEtleWZyYW1lcygpIHtcbiAgICAgICAgY29uc3QgeyBmbG9hdGluZ0xhYmVsRWwsIHJlc3RpbmdMYWJlbEVsIH0gPSB0aGlzO1xuICAgICAgICBpZiAoIWZsb2F0aW5nTGFiZWxFbCB8fCAhcmVzdGluZ0xhYmVsRWwpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHg6IGZsb2F0aW5nWCwgeTogZmxvYXRpbmdZLCBoZWlnaHQ6IGZsb2F0aW5nSGVpZ2h0LCB9ID0gZmxvYXRpbmdMYWJlbEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb25zdCB7IHg6IHJlc3RpbmdYLCB5OiByZXN0aW5nWSwgaGVpZ2h0OiByZXN0aW5nSGVpZ2h0LCB9ID0gcmVzdGluZ0xhYmVsRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IGZsb2F0aW5nU2Nyb2xsV2lkdGggPSBmbG9hdGluZ0xhYmVsRWwuc2Nyb2xsV2lkdGg7XG4gICAgICAgIGNvbnN0IHJlc3RpbmdTY3JvbGxXaWR0aCA9IHJlc3RpbmdMYWJlbEVsLnNjcm9sbFdpZHRoO1xuICAgICAgICAvLyBTY2FsZSBieSB3aWR0aCByYXRpbyBpbnN0ZWFkIG9mIGZvbnQgc2l6ZSBzaW5jZSBsZXR0ZXItc3BhY2luZyB3aWxsIHNjYWxlXG4gICAgICAgIC8vIGluY29ycmVjdGx5LiBVc2luZyB0aGUgd2lkdGggd2UgY2FuIGJldHRlciBhcHByb3hpbWF0ZSB0aGUgYWRqdXN0ZWRcbiAgICAgICAgLy8gc2NhbGUgYW5kIGNvbXBlbnNhdGUgZm9yIHRyYWNraW5nIGFuZCBvdmVyZmxvdy5cbiAgICAgICAgLy8gKHVzZSBzY3JvbGxXaWR0aCBpbnN0ZWFkIG9mIHdpZHRoIHRvIGFjY291bnQgZm9yIGNsaXBwZWQgbGFiZWxzKVxuICAgICAgICBjb25zdCBzY2FsZSA9IHJlc3RpbmdTY3JvbGxXaWR0aCAvIGZsb2F0aW5nU2Nyb2xsV2lkdGg7XG4gICAgICAgIGNvbnN0IHhEZWx0YSA9IHJlc3RpbmdYIC0gZmxvYXRpbmdYO1xuICAgICAgICAvLyBUaGUgbGluZS1oZWlnaHQgb2YgdGhlIHJlc3RpbmcgYW5kIGZsb2F0aW5nIGxhYmVsIGFyZSBkaWZmZXJlbnQuIFdoZW5cbiAgICAgICAgLy8gd2UgbW92ZSB0aGUgZmxvYXRpbmcgbGFiZWwgZG93biB0byB0aGUgcmVzdGluZyBsYWJlbCdzIHBvc2l0aW9uLCBpdCB3b24ndFxuICAgICAgICAvLyBleGFjdGx5IG1hdGNoIGJlY2F1c2Ugb2YgdGhpcy4gV2UgbmVlZCB0byBhZGp1c3QgYnkgaGFsZiBvZiB3aGF0IHRoZVxuICAgICAgICAvLyBmaW5hbCBzY2FsZWQgZmxvYXRpbmcgbGFiZWwncyBoZWlnaHQgd2lsbCBiZS5cbiAgICAgICAgY29uc3QgeURlbHRhID0gcmVzdGluZ1kgLVxuICAgICAgICAgICAgZmxvYXRpbmdZICtcbiAgICAgICAgICAgIE1hdGgucm91bmQoKHJlc3RpbmdIZWlnaHQgLSBmbG9hdGluZ0hlaWdodCAqIHNjYWxlKSAvIDIpO1xuICAgICAgICAvLyBDcmVhdGUgdGhlIHR3byB0cmFuc2Zvcm1zOiBmbG9hdGluZyB0byByZXN0aW5nICh1c2luZyB0aGUgY2FsY3VsYXRpb25zXG4gICAgICAgIC8vIGFib3ZlKSwgYW5kIHJlc3RpbmcgdG8gZmxvYXRpbmcgKHJlLXNldHRpbmcgdGhlIHRyYW5zZm9ybSB0byBpbml0aWFsXG4gICAgICAgIC8vIHZhbHVlcykuXG4gICAgICAgIGNvbnN0IHJlc3RUcmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgke3hEZWx0YX1weCkgdHJhbnNsYXRlWSgke3lEZWx0YX1weCkgc2NhbGUoJHtzY2FsZX0pYDtcbiAgICAgICAgY29uc3QgZmxvYXRUcmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgwKSB0cmFuc2xhdGVZKDApIHNjYWxlKDEpYDtcbiAgICAgICAgLy8gQ29uc3RyYWluIHRoZSBmbG9hdGluZyBsYWJlbHMgd2lkdGggdG8gYSBzY2FsZWQgcGVyY2VudGFnZSBvZiB0aGVcbiAgICAgICAgLy8gcmVzdGluZyBsYWJlbCdzIHdpZHRoLiBUaGlzIHdpbGwgcHJldmVudCBsb25nIGNsaXBwZWQgbGFiZWxzIGZyb21cbiAgICAgICAgLy8gb3ZlcmZsb3dpbmcgdGhlIGNvbnRhaW5lci5cbiAgICAgICAgY29uc3QgcmVzdGluZ0NsaWVudFdpZHRoID0gcmVzdGluZ0xhYmVsRWwuY2xpZW50V2lkdGg7XG4gICAgICAgIGNvbnN0IGlzUmVzdGluZ0NsaXBwZWQgPSByZXN0aW5nU2Nyb2xsV2lkdGggPiByZXN0aW5nQ2xpZW50V2lkdGg7XG4gICAgICAgIGNvbnN0IHdpZHRoID0gaXNSZXN0aW5nQ2xpcHBlZCA/IGAke3Jlc3RpbmdDbGllbnRXaWR0aCAvIHNjYWxlfXB4YCA6ICcnO1xuICAgICAgICBpZiAodGhpcy5mb2N1c2VkIHx8IHRoaXMucG9wdWxhdGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIHsgdHJhbnNmb3JtOiByZXN0VHJhbnNmb3JtLCB3aWR0aCB9LFxuICAgICAgICAgICAgICAgIHsgdHJhbnNmb3JtOiBmbG9hdFRyYW5zZm9ybSwgd2lkdGggfSxcbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiBmbG9hdFRyYW5zZm9ybSwgd2lkdGggfSxcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiByZXN0VHJhbnNmb3JtLCB3aWR0aCB9LFxuICAgICAgICBdO1xuICAgIH1cbiAgICBnZXRTdXJmYWNlUG9zaXRpb25DbGllbnRSZWN0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250YWluZXJFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4gfSlcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJkaXNhYmxlZFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuIH0pXG5dLCBGaWVsZC5wcm90b3R5cGUsIFwiZXJyb3JcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiB9KVxuXSwgRmllbGQucHJvdG90eXBlLCBcImZvY3VzZWRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KClcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJsYWJlbFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICduby1hc3RlcmlzaycgfSlcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJub0FzdGVyaXNrXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4gfSlcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJwb3B1bGF0ZWRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiB9KVxuXSwgRmllbGQucHJvdG90eXBlLCBcInJlcXVpcmVkXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4gfSlcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJyZXNpemFibGVcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgYXR0cmlidXRlOiAnc3VwcG9ydGluZy10ZXh0JyB9KVxuXSwgRmllbGQucHJvdG90eXBlLCBcInN1cHBvcnRpbmdUZXh0XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IGF0dHJpYnV0ZTogJ2Vycm9yLXRleHQnIH0pXG5dLCBGaWVsZC5wcm90b3R5cGUsIFwiZXJyb3JUZXh0XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IE51bWJlciB9KVxuXSwgRmllbGQucHJvdG90eXBlLCBcImNvdW50XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IE51bWJlciB9KVxuXSwgRmllbGQucHJvdG90eXBlLCBcIm1heFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdoYXMtc3RhcnQnIH0pXG5dLCBGaWVsZC5wcm90b3R5cGUsIFwiaGFzU3RhcnRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnaGFzLWVuZCcgfSlcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJoYXNFbmRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5QXNzaWduZWRFbGVtZW50cyh7IHNsb3Q6ICdhcmlhLWRlc2NyaWJlZGJ5JyB9KVxuXSwgRmllbGQucHJvdG90eXBlLCBcInNsb3R0ZWRBcmlhRGVzY3JpYmVkQnlcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJpc0FuaW1hdGluZ1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgRmllbGQucHJvdG90eXBlLCBcInJlZnJlc2hFcnJvckFsZXJ0XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBGaWVsZC5wcm90b3R5cGUsIFwiZGlzYWJsZVRyYW5zaXRpb25zXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBxdWVyeSgnLmxhYmVsLmZsb2F0aW5nJylcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJmbG9hdGluZ0xhYmVsRWxcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5KCcubGFiZWwucmVzdGluZycpXG5dLCBGaWVsZC5wcm90b3R5cGUsIFwicmVzdGluZ0xhYmVsRWxcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5KCcuY29udGFpbmVyJylcbl0sIEZpZWxkLnByb3RvdHlwZSwgXCJjb250YWluZXJFbFwiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmllbGQuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuaW1wb3J0IHsgaHRtbCB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBGaWVsZCB9IGZyb20gJy4vZmllbGQuanMnO1xuLyoqXG4gKiBBIGZpbGxlZCBmaWVsZCBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWxsZWRGaWVsZCBleHRlbmRzIEZpZWxkIHtcbiAgICByZW5kZXJCYWNrZ3JvdW5kKCkge1xuICAgICAgICByZXR1cm4gaHRtbCBgIDxkaXYgY2xhc3M9XCJiYWNrZ3JvdW5kXCI+PC9kaXY+IGA7XG4gICAgfVxuICAgIHJlbmRlclN0YXRlTGF5ZXIoKSB7XG4gICAgICAgIHJldHVybiBodG1sIGAgPGRpdiBjbGFzcz1cInN0YXRlLWxheWVyXCI+PC9kaXY+IGA7XG4gICAgfVxuICAgIHJlbmRlckluZGljYXRvcigpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYDxkaXYgY2xhc3M9XCJhY3RpdmUtaW5kaWNhdG9yXCI+PC9kaXY+YDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maWxsZWQtZmllbGQuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLy8gR2VuZXJhdGVkIHN0eWxlc2hlZXQgZm9yIC4vZmllbGQvaW50ZXJuYWwvZmlsbGVkLXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgQGxheWVyIHN0eWxlc3s6aG9zdHstLV9hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2FjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtYWN0aXZlLWluZGljYXRvci1oZWlnaHQsIDFweCk7LS1fYm90dG9tLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtYm90dG9tLXNwYWNlLCAxNnB4KTstLV9jb250YWluZXItY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1jb250YWluZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1zdXJmYWNlLWNvbnRhaW5lci1oaWdoZXN0LCAjZTZlMGU5KSk7LS1fY29udGVudC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWNvbnRlbnQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fY29udGVudC1mb250OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtY29udGVudC1mb250LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2UtZm9udCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXBsYWluLCBSb2JvdG8pKSk7LS1fY29udGVudC1saW5lLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWNvbnRlbnQtbGluZS1oZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1saW5lLWhlaWdodCwgMS41cmVtKSk7LS1fY29udGVudC1zaXplOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtY29udGVudC1zaXplLCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2Utc2l6ZSwgMXJlbSkpOy0tX2NvbnRlbnQtc3BhY2U6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1jb250ZW50LXNwYWNlLCAxNnB4KTstLV9jb250ZW50LXdlaWdodDogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWNvbnRlbnQtd2VpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2Utd2VpZ2h0LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2Utd2VpZ2h0LXJlZ3VsYXIsIDQwMCkpKTstLV9kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0LCAxcHgpOy0tX2Rpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3Itb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3Itb3BhY2l0eSwgMC4zOCk7LS1fZGlzYWJsZWQtY29udGFpbmVyLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtY29udGFpbmVyLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Rpc2FibGVkLWNvbnRhaW5lci1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtY29udGFpbmVyLW9wYWNpdHksIDAuMDQpOy0tX2Rpc2FibGVkLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Rpc2FibGVkLWNvbnRlbnQtb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWNvbnRlbnQtb3BhY2l0eSwgMC4zOCk7LS1fZGlzYWJsZWQtbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWxhYmVsLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fZGlzYWJsZWQtbGFiZWwtdGV4dC1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtbGFiZWwtdGV4dC1vcGFjaXR5LCAwLjM4KTstLV9kaXNhYmxlZC1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1sZWFkaW5nLWNvbnRlbnQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fZGlzYWJsZWQtbGVhZGluZy1jb250ZW50LW9wYWNpdHk6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1sZWFkaW5nLWNvbnRlbnQtb3BhY2l0eSwgMC4zOCk7LS1fZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Rpc2FibGVkLXN1cHBvcnRpbmctdGV4dC1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LW9wYWNpdHksIDAuMzgpOy0tX2Rpc2FibGVkLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC10cmFpbGluZy1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Rpc2FibGVkLXRyYWlsaW5nLWNvbnRlbnQtb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLXRyYWlsaW5nLWNvbnRlbnQtb3BhY2l0eSwgMC4zOCk7LS1fZXJyb3ItYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX2Vycm9yLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Vycm9yLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV9lcnJvci1mb2N1cy1jb250ZW50LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZXJyb3ItZm9jdXMtY29udGVudC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2Vycm9yLWZvY3VzLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV9lcnJvci1mb2N1cy1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1sZWFkaW5nLWNvbnRlbnQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9lcnJvci1mb2N1cy1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX2Vycm9yLWZvY3VzLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy10cmFpbGluZy1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV9lcnJvci1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZXJyb3ItaG92ZXItYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLWVycm9yLWNvbnRhaW5lciwgIzQxMGUwYikpOy0tX2Vycm9yLWhvdmVyLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1ob3Zlci1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Vycm9yLWhvdmVyLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1ob3Zlci1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tZXJyb3ItY29udGFpbmVyLCAjNDEwZTBiKSk7LS1fZXJyb3ItaG92ZXItbGVhZGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZXJyb3ItaG92ZXItbGVhZGluZy1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fZXJyb3ItaG92ZXItc3RhdGUtbGF5ZXItY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZXJyb3ItaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4wOCk7LS1fZXJyb3ItaG92ZXItc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZXJyb3ItaG92ZXItc3VwcG9ydGluZy10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV9lcnJvci1ob3Zlci10cmFpbGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZXJyb3ItaG92ZXItdHJhaWxpbmctY29udGVudC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLWVycm9yLWNvbnRhaW5lciwgIzQxMGUwYikpOy0tX2Vycm9yLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV9lcnJvci1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1sZWFkaW5nLWNvbnRlbnQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX2Vycm9yLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1lcnJvci10cmFpbGluZy1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV9mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV9mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0LCAzcHgpOy0tX2ZvY3VzLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1mb2N1cy1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2ZvY3VzLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1mb2N1cy1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItcHJpbWFyeSwgIzY3NTBhNCkpOy0tX2ZvY3VzLWxlYWRpbmctY29udGVudC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWZvY3VzLWxlYWRpbmctY29udGVudC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2ZvY3VzLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWZvY3VzLXN1cHBvcnRpbmctdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2ZvY3VzLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1mb2N1cy10cmFpbGluZy1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1faG92ZXItYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1faG92ZXItYWN0aXZlLWluZGljYXRvci1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCwgMXB4KTstLV9ob3Zlci1jb250ZW50LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtaG92ZXItY29udGVudC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9ob3Zlci1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtaG92ZXItbGFiZWwtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2hvdmVyLWxlYWRpbmctY29udGVudC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLWxlYWRpbmctY29udGVudC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2hvdmVyLXN0YXRlLWxheWVyLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtaG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1faG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHksIDAuMDgpOy0tX2hvdmVyLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLXN1cHBvcnRpbmctdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2hvdmVyLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1ob3Zlci10cmFpbGluZy1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWxhYmVsLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9sYWJlbC10ZXh0LWZvbnQ6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LWZvbnQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1mb250LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2UtcGxhaW4sIFJvYm90bykpKTstLV9sYWJlbC10ZXh0LWxpbmUtaGVpZ2h0OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtbGFiZWwtdGV4dC1saW5lLWhlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLWxpbmUtaGVpZ2h0LCAxLjVyZW0pKTstLV9sYWJlbC10ZXh0LXBvcHVsYXRlZC1saW5lLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWxhYmVsLXRleHQtcG9wdWxhdGVkLWxpbmUtaGVpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktc21hbGwtbGluZS1oZWlnaHQsIDFyZW0pKTstLV9sYWJlbC10ZXh0LXBvcHVsYXRlZC1zaXplOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtbGFiZWwtdGV4dC1wb3B1bGF0ZWQtc2l6ZSwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LXNtYWxsLXNpemUsIDAuNzVyZW0pKTstLV9sYWJlbC10ZXh0LXNpemU6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LXNpemUsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1zaXplLCAxcmVtKSk7LS1fbGFiZWwtdGV4dC13ZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LXdlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLXdlaWdodCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXdlaWdodC1yZWd1bGFyLCA0MDApKSk7LS1fbGVhZGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtbGVhZGluZy1jb250ZW50LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fbGVhZGluZy1zcGFjZTogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWxlYWRpbmctc3BhY2UsIDE2cHgpOy0tX3N1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLXN1cHBvcnRpbmctdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX3N1cHBvcnRpbmctdGV4dC1mb250OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LWZvbnQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1zbWFsbC1mb250LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2UtcGxhaW4sIFJvYm90bykpKTstLV9zdXBwb3J0aW5nLXRleHQtbGVhZGluZy1zcGFjZTogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLXN1cHBvcnRpbmctdGV4dC1sZWFkaW5nLXNwYWNlLCAxNnB4KTstLV9zdXBwb3J0aW5nLXRleHQtbGluZS1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1zdXBwb3J0aW5nLXRleHQtbGluZS1oZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1zbWFsbC1saW5lLWhlaWdodCwgMXJlbSkpOy0tX3N1cHBvcnRpbmctdGV4dC1zaXplOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXNpemUsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1zbWFsbC1zaXplLCAwLjc1cmVtKSk7LS1fc3VwcG9ydGluZy10ZXh0LXRvcC1zcGFjZTogdmFyKC0tbWQtZmlsbGVkLWZpZWxkLXN1cHBvcnRpbmctdGV4dC10b3Atc3BhY2UsIDRweCk7LS1fc3VwcG9ydGluZy10ZXh0LXRyYWlsaW5nLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXRyYWlsaW5nLXNwYWNlLCAxNnB4KTstLV9zdXBwb3J0aW5nLXRleHQtd2VpZ2h0OiB2YXIoLS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXdlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LXNtYWxsLXdlaWdodCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXdlaWdodC1yZWd1bGFyLCA0MDApKSk7LS1fdG9wLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtdG9wLXNwYWNlLCAxNnB4KTstLV90cmFpbGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtdHJhaWxpbmctY29udGVudC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX3RyYWlsaW5nLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtdHJhaWxpbmctc3BhY2UsIDE2cHgpOy0tX3dpdGgtbGFiZWwtYm90dG9tLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtd2l0aC1sYWJlbC1ib3R0b20tc3BhY2UsIDhweCk7LS1fd2l0aC1sYWJlbC10b3Atc3BhY2U6IHZhcigtLW1kLWZpbGxlZC1maWVsZC13aXRoLWxhYmVsLXRvcC1zcGFjZSwgOHB4KTstLV93aXRoLWxlYWRpbmctY29udGVudC1sZWFkaW5nLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtd2l0aC1sZWFkaW5nLWNvbnRlbnQtbGVhZGluZy1zcGFjZSwgMTJweCk7LS1fd2l0aC10cmFpbGluZy1jb250ZW50LXRyYWlsaW5nLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtd2l0aC10cmFpbGluZy1jb250ZW50LXRyYWlsaW5nLXNwYWNlLCAxMnB4KTstLV9jb250YWluZXItc2hhcGUtc3RhcnQtc3RhcnQ6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1jb250YWluZXItc2hhcGUtc3RhcnQtc3RhcnQsIHZhcigtLW1kLWZpbGxlZC1maWVsZC1jb250YWluZXItc2hhcGUsIHZhcigtLW1kLXN5cy1zaGFwZS1jb3JuZXItZXh0cmEtc21hbGwsIDRweCkpKTstLV9jb250YWluZXItc2hhcGUtc3RhcnQtZW5kOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLXNoYXBlLXN0YXJ0LWVuZCwgdmFyKC0tbWQtZmlsbGVkLWZpZWxkLWNvbnRhaW5lci1zaGFwZSwgdmFyKC0tbWQtc3lzLXNoYXBlLWNvcm5lci1leHRyYS1zbWFsbCwgNHB4KSkpOy0tX2NvbnRhaW5lci1zaGFwZS1lbmQtZW5kOiB2YXIoLS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLXNoYXBlLWVuZC1lbmQsIHZhcigtLW1kLWZpbGxlZC1maWVsZC1jb250YWluZXItc2hhcGUsIHZhcigtLW1kLXN5cy1zaGFwZS1jb3JuZXItbm9uZSwgMHB4KSkpOy0tX2NvbnRhaW5lci1zaGFwZS1lbmQtc3RhcnQ6IHZhcigtLW1kLWZpbGxlZC1maWVsZC1jb250YWluZXItc2hhcGUtZW5kLXN0YXJ0LCB2YXIoLS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLXNoYXBlLCB2YXIoLS1tZC1zeXMtc2hhcGUtY29ybmVyLW5vbmUsIDBweCkpKX0uYmFja2dyb3VuZCwuc3RhdGUtbGF5ZXJ7Ym9yZGVyLXJhZGl1czppbmhlcml0O2luc2V0OjA7cG9pbnRlci1ldmVudHM6bm9uZTtwb3NpdGlvbjphYnNvbHV0ZX0uYmFja2dyb3VuZHtiYWNrZ3JvdW5kOnZhcigtLV9jb250YWluZXItY29sb3IpfS5zdGF0ZS1sYXllcnt2aXNpYmlsaXR5OmhpZGRlbn0uZmllbGQ6bm90KC5kaXNhYmxlZCk6aG92ZXIgLnN0YXRlLWxheWVye3Zpc2liaWxpdHk6dmlzaWJsZX0ubGFiZWwuZmxvYXRpbmd7cG9zaXRpb246YWJzb2x1dGU7dG9wOnZhcigtLV93aXRoLWxhYmVsLXRvcC1zcGFjZSl9LmZpZWxkOm5vdCgud2l0aC1zdGFydCkgLmxhYmVsLXdyYXBwZXJ7bWFyZ2luLWlubGluZS1zdGFydDp2YXIoLS1fbGVhZGluZy1zcGFjZSl9LmZpZWxkOm5vdCgud2l0aC1lbmQpIC5sYWJlbC13cmFwcGVye21hcmdpbi1pbmxpbmUtZW5kOnZhcigtLV90cmFpbGluZy1zcGFjZSl9LmFjdGl2ZS1pbmRpY2F0b3J7aW5zZXQ6YXV0byAwIDAgMDtwb2ludGVyLWV2ZW50czpub25lO3Bvc2l0aW9uOmFic29sdXRlO3dpZHRoOjEwMCU7ei1pbmRleDoxfS5hY3RpdmUtaW5kaWNhdG9yOjpiZWZvcmUsLmFjdGl2ZS1pbmRpY2F0b3I6OmFmdGVye2JvcmRlci1ib3R0b206dmFyKC0tX2FjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0KSBzb2xpZCB2YXIoLS1fYWN0aXZlLWluZGljYXRvci1jb2xvcik7aW5zZXQ6YXV0byAwIDAgMDtjb250ZW50OlwiXCI7cG9zaXRpb246YWJzb2x1dGU7d2lkdGg6MTAwJX0uYWN0aXZlLWluZGljYXRvcjo6YWZ0ZXJ7b3BhY2l0eTowO3RyYW5zaXRpb246b3BhY2l0eSAxNTBtcyBjdWJpYy1iZXppZXIoMC4yLCAwLCAwLCAxKX0uZm9jdXNlZCAuYWN0aXZlLWluZGljYXRvcjo6YWZ0ZXJ7b3BhY2l0eToxfS5maWVsZDpub3QoLndpdGgtc3RhcnQpIC5jb250ZW50IDo6c2xvdHRlZCgqKXtwYWRkaW5nLWlubGluZS1zdGFydDp2YXIoLS1fbGVhZGluZy1zcGFjZSl9LmZpZWxkOm5vdCgud2l0aC1lbmQpIC5jb250ZW50IDo6c2xvdHRlZCgqKXtwYWRkaW5nLWlubGluZS1lbmQ6dmFyKC0tX3RyYWlsaW5nLXNwYWNlKX0uZmllbGQ6bm90KC5uby1sYWJlbCkgLmNvbnRlbnQgOjpzbG90dGVkKDpub3QodGV4dGFyZWEpKXtwYWRkaW5nLWJvdHRvbTp2YXIoLS1fd2l0aC1sYWJlbC1ib3R0b20tc3BhY2UpO3BhZGRpbmctdG9wOmNhbGModmFyKC0tX3dpdGgtbGFiZWwtdG9wLXNwYWNlKSArIHZhcigtLV9sYWJlbC10ZXh0LXBvcHVsYXRlZC1saW5lLWhlaWdodCkpfS5maWVsZDpub3QoLm5vLWxhYmVsKSAuY29udGVudCA6OnNsb3R0ZWQodGV4dGFyZWEpe21hcmdpbi1ib3R0b206dmFyKC0tX3dpdGgtbGFiZWwtYm90dG9tLXNwYWNlKTttYXJnaW4tdG9wOmNhbGModmFyKC0tX3dpdGgtbGFiZWwtdG9wLXNwYWNlKSArIHZhcigtLV9sYWJlbC10ZXh0LXBvcHVsYXRlZC1saW5lLWhlaWdodCkpfTpob3ZlciAuYWN0aXZlLWluZGljYXRvcjo6YmVmb3Jle2JvcmRlci1ib3R0b20tY29sb3I6dmFyKC0tX2hvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IpO2JvcmRlci1ib3R0b20td2lkdGg6dmFyKC0tX2hvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0KX0uYWN0aXZlLWluZGljYXRvcjo6YWZ0ZXJ7Ym9yZGVyLWJvdHRvbS1jb2xvcjp2YXIoLS1fZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvcik7Ym9yZGVyLWJvdHRvbS13aWR0aDp2YXIoLS1fZm9jdXMtYWN0aXZlLWluZGljYXRvci1oZWlnaHQpfTpob3ZlciAuc3RhdGUtbGF5ZXJ7YmFja2dyb3VuZDp2YXIoLS1faG92ZXItc3RhdGUtbGF5ZXItY29sb3IpO29wYWNpdHk6dmFyKC0tX2hvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHkpfS5kaXNhYmxlZCAuYWN0aXZlLWluZGljYXRvcjo6YmVmb3Jle2JvcmRlci1ib3R0b20tY29sb3I6dmFyKC0tX2Rpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IpO2JvcmRlci1ib3R0b20td2lkdGg6dmFyKC0tX2Rpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0KTtvcGFjaXR5OnZhcigtLV9kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLW9wYWNpdHkpfS5kaXNhYmxlZCAuYmFja2dyb3VuZHtiYWNrZ3JvdW5kOnZhcigtLV9kaXNhYmxlZC1jb250YWluZXItY29sb3IpO29wYWNpdHk6dmFyKC0tX2Rpc2FibGVkLWNvbnRhaW5lci1vcGFjaXR5KX0uZXJyb3IgLmFjdGl2ZS1pbmRpY2F0b3I6OmJlZm9yZXtib3JkZXItYm90dG9tLWNvbG9yOnZhcigtLV9lcnJvci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKX0uZXJyb3I6aG92ZXIgLmFjdGl2ZS1pbmRpY2F0b3I6OmJlZm9yZXtib3JkZXItYm90dG9tLWNvbG9yOnZhcigtLV9lcnJvci1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKX0uZXJyb3I6aG92ZXIgLnN0YXRlLWxheWVye2JhY2tncm91bmQ6dmFyKC0tX2Vycm9yLWhvdmVyLXN0YXRlLWxheWVyLWNvbG9yKTtvcGFjaXR5OnZhcigtLV9lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5KX0uZXJyb3IgLmFjdGl2ZS1pbmRpY2F0b3I6OmFmdGVye2JvcmRlci1ib3R0b20tY29sb3I6dmFyKC0tX2Vycm9yLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IpfS5yZXNpemFibGUgLmNvbnRhaW5lcntib3R0b206dmFyKC0tX2ZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0KTtjbGlwLXBhdGg6aW5zZXQodmFyKC0tX2ZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0KSAwIDAgMCl9LnJlc2l6YWJsZSAuY29udGFpbmVyPip7dG9wOnZhcigtLV9mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCl9fUBsYXllciBoY217QG1lZGlhKGZvcmNlZC1jb2xvcnM6IGFjdGl2ZSl7LmRpc2FibGVkIC5hY3RpdmUtaW5kaWNhdG9yOjpiZWZvcmV7Ym9yZGVyLWNvbG9yOkdyYXlUZXh0O29wYWNpdHk6MX19fVxuYDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpbGxlZC1zdHlsZXMuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLy8gR2VuZXJhdGVkIHN0eWxlc2hlZXQgZm9yIC4vZmllbGQvaW50ZXJuYWwvc2hhcmVkLXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgOmhvc3R7ZGlzcGxheTppbmxpbmUtZmxleDtyZXNpemU6Ym90aH0uZmllbGR7ZGlzcGxheTpmbGV4O2ZsZXg6MTtmbGV4LWRpcmVjdGlvbjpjb2x1bW47d3JpdGluZy1tb2RlOmhvcml6b250YWwtdGI7bWF4LXdpZHRoOjEwMCV9LmNvbnRhaW5lci1vdmVyZmxvd3tib3JkZXItc3RhcnQtc3RhcnQtcmFkaXVzOnZhcigtLV9jb250YWluZXItc2hhcGUtc3RhcnQtc3RhcnQpO2JvcmRlci1zdGFydC1lbmQtcmFkaXVzOnZhcigtLV9jb250YWluZXItc2hhcGUtc3RhcnQtZW5kKTtib3JkZXItZW5kLWVuZC1yYWRpdXM6dmFyKC0tX2NvbnRhaW5lci1zaGFwZS1lbmQtZW5kKTtib3JkZXItZW5kLXN0YXJ0LXJhZGl1czp2YXIoLS1fY29udGFpbmVyLXNoYXBlLWVuZC1zdGFydCk7ZGlzcGxheTpmbGV4O2hlaWdodDoxMDAlO3Bvc2l0aW9uOnJlbGF0aXZlfS5jb250YWluZXJ7YWxpZ24taXRlbXM6Y2VudGVyO2JvcmRlci1yYWRpdXM6aW5oZXJpdDtkaXNwbGF5OmZsZXg7ZmxleDoxO21heC1oZWlnaHQ6MTAwJTttaW4taGVpZ2h0OjEwMCU7bWluLXdpZHRoOm1pbi1jb250ZW50O3Bvc2l0aW9uOnJlbGF0aXZlfS5maWVsZCwuY29udGFpbmVyLW92ZXJmbG93e3Jlc2l6ZTppbmhlcml0fS5yZXNpemFibGU6bm90KC5kaXNhYmxlZCkgLmNvbnRhaW5lcntyZXNpemU6aW5oZXJpdDtvdmVyZmxvdzpoaWRkZW59LmRpc2FibGVke3BvaW50ZXItZXZlbnRzOm5vbmV9c2xvdFtuYW1lPWNvbnRhaW5lcl17Ym9yZGVyLXJhZGl1czppbmhlcml0fXNsb3RbbmFtZT1jb250YWluZXJdOjpzbG90dGVkKCope2JvcmRlci1yYWRpdXM6aW5oZXJpdDtpbnNldDowO3BvaW50ZXItZXZlbnRzOm5vbmU7cG9zaXRpb246YWJzb2x1dGV9QGxheWVyIHN0eWxlc3suc3RhcnQsLm1pZGRsZSwuZW5ke2Rpc3BsYXk6ZmxleDtib3gtc2l6aW5nOmJvcmRlci1ib3g7aGVpZ2h0OjEwMCU7cG9zaXRpb246cmVsYXRpdmV9LnN0YXJ0e2NvbG9yOnZhcigtLV9sZWFkaW5nLWNvbnRlbnQtY29sb3IpfS5lbmR7Y29sb3I6dmFyKC0tX3RyYWlsaW5nLWNvbnRlbnQtY29sb3IpfS5zdGFydCwuZW5ke2FsaWduLWl0ZW1zOmNlbnRlcjtqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyfS53aXRoLXN0YXJ0IC5zdGFydHttYXJnaW4taW5saW5lOnZhcigtLV93aXRoLWxlYWRpbmctY29udGVudC1sZWFkaW5nLXNwYWNlKSB2YXIoLS1fY29udGVudC1zcGFjZSl9LndpdGgtZW5kIC5lbmR7bWFyZ2luLWlubGluZTp2YXIoLS1fY29udGVudC1zcGFjZSkgdmFyKC0tX3dpdGgtdHJhaWxpbmctY29udGVudC10cmFpbGluZy1zcGFjZSl9Lm1pZGRsZXthbGlnbi1pdGVtczpzdHJldGNoO2FsaWduLXNlbGY6YmFzZWxpbmU7ZmxleDoxfS5jb250ZW50e2NvbG9yOnZhcigtLV9jb250ZW50LWNvbG9yKTtkaXNwbGF5OmZsZXg7ZmxleDoxO29wYWNpdHk6MDt0cmFuc2l0aW9uOm9wYWNpdHkgODNtcyBjdWJpYy1iZXppZXIoMC4yLCAwLCAwLCAxKX0ubm8tbGFiZWwgLmNvbnRlbnQsLmZvY3VzZWQgLmNvbnRlbnQsLnBvcHVsYXRlZCAuY29udGVudHtvcGFjaXR5OjE7dHJhbnNpdGlvbi1kZWxheTo2N21zfTppcyguZGlzYWJsZWQsLmRpc2FibGUtdHJhbnNpdGlvbnMpIC5jb250ZW50e3RyYW5zaXRpb246bm9uZX0uY29udGVudCA6OnNsb3R0ZWQoKil7YWxsOnVuc2V0O2NvbG9yOmN1cnJlbnRDb2xvcjtmb250LWZhbWlseTp2YXIoLS1fY29udGVudC1mb250KTtmb250LXNpemU6dmFyKC0tX2NvbnRlbnQtc2l6ZSk7bGluZS1oZWlnaHQ6dmFyKC0tX2NvbnRlbnQtbGluZS1oZWlnaHQpO2ZvbnQtd2VpZ2h0OnZhcigtLV9jb250ZW50LXdlaWdodCk7d2lkdGg6MTAwJTtvdmVyZmxvdy13cmFwOnJldmVydDt3aGl0ZS1zcGFjZTpyZXZlcnR9LmNvbnRlbnQgOjpzbG90dGVkKDpub3QodGV4dGFyZWEpKXtwYWRkaW5nLXRvcDp2YXIoLS1fdG9wLXNwYWNlKTtwYWRkaW5nLWJvdHRvbTp2YXIoLS1fYm90dG9tLXNwYWNlKX0uY29udGVudCA6OnNsb3R0ZWQodGV4dGFyZWEpe21hcmdpbi10b3A6dmFyKC0tX3RvcC1zcGFjZSk7bWFyZ2luLWJvdHRvbTp2YXIoLS1fYm90dG9tLXNwYWNlKX06aG92ZXIgLmNvbnRlbnR7Y29sb3I6dmFyKC0tX2hvdmVyLWNvbnRlbnQtY29sb3IpfTpob3ZlciAuc3RhcnR7Y29sb3I6dmFyKC0tX2hvdmVyLWxlYWRpbmctY29udGVudC1jb2xvcil9OmhvdmVyIC5lbmR7Y29sb3I6dmFyKC0tX2hvdmVyLXRyYWlsaW5nLWNvbnRlbnQtY29sb3IpfS5mb2N1c2VkIC5jb250ZW50e2NvbG9yOnZhcigtLV9mb2N1cy1jb250ZW50LWNvbG9yKX0uZm9jdXNlZCAuc3RhcnR7Y29sb3I6dmFyKC0tX2ZvY3VzLWxlYWRpbmctY29udGVudC1jb2xvcil9LmZvY3VzZWQgLmVuZHtjb2xvcjp2YXIoLS1fZm9jdXMtdHJhaWxpbmctY29udGVudC1jb2xvcil9LmRpc2FibGVkIC5jb250ZW50e2NvbG9yOnZhcigtLV9kaXNhYmxlZC1jb250ZW50LWNvbG9yKX0uZGlzYWJsZWQubm8tbGFiZWwgLmNvbnRlbnQsLmRpc2FibGVkLmZvY3VzZWQgLmNvbnRlbnQsLmRpc2FibGVkLnBvcHVsYXRlZCAuY29udGVudHtvcGFjaXR5OnZhcigtLV9kaXNhYmxlZC1jb250ZW50LW9wYWNpdHkpfS5kaXNhYmxlZCAuc3RhcnR7Y29sb3I6dmFyKC0tX2Rpc2FibGVkLWxlYWRpbmctY29udGVudC1jb2xvcik7b3BhY2l0eTp2YXIoLS1fZGlzYWJsZWQtbGVhZGluZy1jb250ZW50LW9wYWNpdHkpfS5kaXNhYmxlZCAuZW5ke2NvbG9yOnZhcigtLV9kaXNhYmxlZC10cmFpbGluZy1jb250ZW50LWNvbG9yKTtvcGFjaXR5OnZhcigtLV9kaXNhYmxlZC10cmFpbGluZy1jb250ZW50LW9wYWNpdHkpfS5lcnJvciAuY29udGVudHtjb2xvcjp2YXIoLS1fZXJyb3ItY29udGVudC1jb2xvcil9LmVycm9yIC5zdGFydHtjb2xvcjp2YXIoLS1fZXJyb3ItbGVhZGluZy1jb250ZW50LWNvbG9yKX0uZXJyb3IgLmVuZHtjb2xvcjp2YXIoLS1fZXJyb3ItdHJhaWxpbmctY29udGVudC1jb2xvcil9LmVycm9yOmhvdmVyIC5jb250ZW50e2NvbG9yOnZhcigtLV9lcnJvci1ob3Zlci1jb250ZW50LWNvbG9yKX0uZXJyb3I6aG92ZXIgLnN0YXJ0e2NvbG9yOnZhcigtLV9lcnJvci1ob3Zlci1sZWFkaW5nLWNvbnRlbnQtY29sb3IpfS5lcnJvcjpob3ZlciAuZW5ke2NvbG9yOnZhcigtLV9lcnJvci1ob3Zlci10cmFpbGluZy1jb250ZW50LWNvbG9yKX0uZXJyb3IuZm9jdXNlZCAuY29udGVudHtjb2xvcjp2YXIoLS1fZXJyb3ItZm9jdXMtY29udGVudC1jb2xvcil9LmVycm9yLmZvY3VzZWQgLnN0YXJ0e2NvbG9yOnZhcigtLV9lcnJvci1mb2N1cy1sZWFkaW5nLWNvbnRlbnQtY29sb3IpfS5lcnJvci5mb2N1c2VkIC5lbmR7Y29sb3I6dmFyKC0tX2Vycm9yLWZvY3VzLXRyYWlsaW5nLWNvbnRlbnQtY29sb3IpfX1AbGF5ZXIgaGNte0BtZWRpYShmb3JjZWQtY29sb3JzOiBhY3RpdmUpey5kaXNhYmxlZCA6aXMoLnN0YXJ0LC5jb250ZW50LC5lbmQpe2NvbG9yOkdyYXlUZXh0O29wYWNpdHk6MX19fUBsYXllciBzdHlsZXN7LmxhYmVse2JveC1zaXppbmc6Ym9yZGVyLWJveDtjb2xvcjp2YXIoLS1fbGFiZWwtdGV4dC1jb2xvcik7b3ZlcmZsb3c6aGlkZGVuO21heC13aWR0aDoxMDAlO3RleHQtb3ZlcmZsb3c6ZWxsaXBzaXM7d2hpdGUtc3BhY2U6bm93cmFwO3otaW5kZXg6MTtmb250LWZhbWlseTp2YXIoLS1fbGFiZWwtdGV4dC1mb250KTtmb250LXNpemU6dmFyKC0tX2xhYmVsLXRleHQtc2l6ZSk7bGluZS1oZWlnaHQ6dmFyKC0tX2xhYmVsLXRleHQtbGluZS1oZWlnaHQpO2ZvbnQtd2VpZ2h0OnZhcigtLV9sYWJlbC10ZXh0LXdlaWdodCk7d2lkdGg6bWluLWNvbnRlbnR9LmxhYmVsLXdyYXBwZXJ7aW5zZXQ6MDtwb2ludGVyLWV2ZW50czpub25lO3Bvc2l0aW9uOmFic29sdXRlfS5sYWJlbC5yZXN0aW5ne3Bvc2l0aW9uOmFic29sdXRlO3RvcDp2YXIoLS1fdG9wLXNwYWNlKX0ubGFiZWwuZmxvYXRpbmd7Zm9udC1zaXplOnZhcigtLV9sYWJlbC10ZXh0LXBvcHVsYXRlZC1zaXplKTtsaW5lLWhlaWdodDp2YXIoLS1fbGFiZWwtdGV4dC1wb3B1bGF0ZWQtbGluZS1oZWlnaHQpO3RyYW5zZm9ybS1vcmlnaW46dG9wIGxlZnR9LmxhYmVsLmhpZGRlbntvcGFjaXR5OjB9Lm5vLWxhYmVsIC5sYWJlbHtkaXNwbGF5Om5vbmV9LmxhYmVsLXdyYXBwZXJ7aW5zZXQ6MDtwb3NpdGlvbjphYnNvbHV0ZTt0ZXh0LWFsaWduOmluaXRpYWx9OmhvdmVyIC5sYWJlbHtjb2xvcjp2YXIoLS1faG92ZXItbGFiZWwtdGV4dC1jb2xvcil9LmZvY3VzZWQgLmxhYmVse2NvbG9yOnZhcigtLV9mb2N1cy1sYWJlbC10ZXh0LWNvbG9yKX0uZGlzYWJsZWQgLmxhYmVse2NvbG9yOnZhcigtLV9kaXNhYmxlZC1sYWJlbC10ZXh0LWNvbG9yKX0uZGlzYWJsZWQgLmxhYmVsOm5vdCguaGlkZGVuKXtvcGFjaXR5OnZhcigtLV9kaXNhYmxlZC1sYWJlbC10ZXh0LW9wYWNpdHkpfS5lcnJvciAubGFiZWx7Y29sb3I6dmFyKC0tX2Vycm9yLWxhYmVsLXRleHQtY29sb3IpfS5lcnJvcjpob3ZlciAubGFiZWx7Y29sb3I6dmFyKC0tX2Vycm9yLWhvdmVyLWxhYmVsLXRleHQtY29sb3IpfS5lcnJvci5mb2N1c2VkIC5sYWJlbHtjb2xvcjp2YXIoLS1fZXJyb3ItZm9jdXMtbGFiZWwtdGV4dC1jb2xvcil9fUBsYXllciBoY217QG1lZGlhKGZvcmNlZC1jb2xvcnM6IGFjdGl2ZSl7LmRpc2FibGVkIC5sYWJlbDpub3QoLmhpZGRlbil7Y29sb3I6R3JheVRleHQ7b3BhY2l0eToxfX19QGxheWVyIHN0eWxlc3suc3VwcG9ydGluZy10ZXh0e2NvbG9yOnZhcigtLV9zdXBwb3J0aW5nLXRleHQtY29sb3IpO2Rpc3BsYXk6ZmxleDtmb250LWZhbWlseTp2YXIoLS1fc3VwcG9ydGluZy10ZXh0LWZvbnQpO2ZvbnQtc2l6ZTp2YXIoLS1fc3VwcG9ydGluZy10ZXh0LXNpemUpO2xpbmUtaGVpZ2h0OnZhcigtLV9zdXBwb3J0aW5nLXRleHQtbGluZS1oZWlnaHQpO2ZvbnQtd2VpZ2h0OnZhcigtLV9zdXBwb3J0aW5nLXRleHQtd2VpZ2h0KTtnYXA6MTZweDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjtwYWRkaW5nLWlubGluZS1zdGFydDp2YXIoLS1fc3VwcG9ydGluZy10ZXh0LWxlYWRpbmctc3BhY2UpO3BhZGRpbmctaW5saW5lLWVuZDp2YXIoLS1fc3VwcG9ydGluZy10ZXh0LXRyYWlsaW5nLXNwYWNlKTtwYWRkaW5nLXRvcDp2YXIoLS1fc3VwcG9ydGluZy10ZXh0LXRvcC1zcGFjZSl9LnN1cHBvcnRpbmctdGV4dCA6bnRoLWNoaWxkKDIpe2ZsZXgtc2hyaW5rOjB9OmhvdmVyIC5zdXBwb3J0aW5nLXRleHR7Y29sb3I6dmFyKC0tX2hvdmVyLXN1cHBvcnRpbmctdGV4dC1jb2xvcil9LmZvY3VzIC5zdXBwb3J0aW5nLXRleHR7Y29sb3I6dmFyKC0tX2ZvY3VzLXN1cHBvcnRpbmctdGV4dC1jb2xvcil9LmRpc2FibGVkIC5zdXBwb3J0aW5nLXRleHR7Y29sb3I6dmFyKC0tX2Rpc2FibGVkLXN1cHBvcnRpbmctdGV4dC1jb2xvcik7b3BhY2l0eTp2YXIoLS1fZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LW9wYWNpdHkpfS5lcnJvciAuc3VwcG9ydGluZy10ZXh0e2NvbG9yOnZhcigtLV9lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3IpfS5lcnJvcjpob3ZlciAuc3VwcG9ydGluZy10ZXh0e2NvbG9yOnZhcigtLV9lcnJvci1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3IpfS5lcnJvci5mb2N1cyAuc3VwcG9ydGluZy10ZXh0e2NvbG9yOnZhcigtLV9lcnJvci1mb2N1cy1zdXBwb3J0aW5nLXRleHQtY29sb3IpfX1AbGF5ZXIgaGNte0BtZWRpYShmb3JjZWQtY29sb3JzOiBhY3RpdmUpey5kaXNhYmxlZCAuc3VwcG9ydGluZy10ZXh0e2NvbG9yOkdyYXlUZXh0O29wYWNpdHk6MX19fVxuYDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNoYXJlZC1zdHlsZXMuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuaW1wb3J0IHsgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0ICcuLi8uLi9mb2N1cy9tZC1mb2N1cy1yaW5nLmpzJztcbmltcG9ydCAnLi4vLi4vcmlwcGxlL3JpcHBsZS5qcyc7XG5pbXBvcnQgeyBodG1sLCBpc1NlcnZlciwgTGl0RWxlbWVudCwgbm90aGluZyB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBwcm9wZXJ0eSwgc3RhdGUgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5pbXBvcnQgeyBjbGFzc01hcCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL2NsYXNzLW1hcC5qcyc7XG5pbXBvcnQgeyBsaXRlcmFsLCBodG1sIGFzIHN0YXRpY0h0bWwgfSBmcm9tICdsaXQvc3RhdGljLWh0bWwuanMnO1xuaW1wb3J0IHsgbWl4aW5EZWxlZ2F0ZXNBcmlhIH0gZnJvbSAnLi4vLi4vaW50ZXJuYWwvYXJpYS9kZWxlZ2F0ZS5qcyc7XG5pbXBvcnQgeyBzZXR1cEZvcm1TdWJtaXR0ZXIsIH0gZnJvbSAnLi4vLi4vaW50ZXJuYWwvY29udHJvbGxlci9mb3JtLXN1Ym1pdHRlci5qcyc7XG5pbXBvcnQgeyBpc1J0bCB9IGZyb20gJy4uLy4uL2ludGVybmFsL2NvbnRyb2xsZXIvaXMtcnRsLmpzJztcbmltcG9ydCB7IGludGVybmFscywgbWl4aW5FbGVtZW50SW50ZXJuYWxzLCB9IGZyb20gJy4uLy4uL2xhYnMvYmVoYXZpb3JzL2VsZW1lbnQtaW50ZXJuYWxzLmpzJztcbi8vIFNlcGFyYXRlIHZhcmlhYmxlIG5lZWRlZCBmb3IgY2xvc3VyZS5cbmNvbnN0IGljb25CdXR0b25CYXNlQ2xhc3MgPSBtaXhpbkRlbGVnYXRlc0FyaWEobWl4aW5FbGVtZW50SW50ZXJuYWxzKExpdEVsZW1lbnQpKTtcbi8qKlxuICogQSBidXR0b24gZm9yIHJlbmRlcmluZyBpY29ucy5cbiAqXG4gKiBAZmlyZXMgaW5wdXQge0lucHV0RXZlbnR9IERpc3BhdGNoZWQgd2hlbiBhIHRvZ2dsZSBidXR0b24gdG9nZ2xlcyAtLWJ1YmJsZXNcbiAqIC0tY29tcG9zZWRcbiAqIEBmaXJlcyBjaGFuZ2Uge0V2ZW50fSBEaXNwYXRjaGVkIHdoZW4gYSB0b2dnbGUgYnV0dG9uIHRvZ2dsZXMgLS1idWJibGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBJY29uQnV0dG9uIGV4dGVuZHMgaWNvbkJ1dHRvbkJhc2VDbGFzcyB7XG4gICAgZ2V0IG5hbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgnbmFtZScpID8/ICcnO1xuICAgIH1cbiAgICBzZXQgbmFtZShuYW1lKSB7XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCduYW1lJywgbmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhc3NvY2lhdGVkIGZvcm0gZWxlbWVudCB3aXRoIHdoaWNoIHRoaXMgZWxlbWVudCdzIHZhbHVlIHdpbGwgc3VibWl0LlxuICAgICAqL1xuICAgIGdldCBmb3JtKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbHNdLmZvcm07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsYWJlbHMgdGhpcyBlbGVtZW50IGlzIGFzc29jaWF0ZWQgd2l0aC5cbiAgICAgKi9cbiAgICBnZXQgbGFiZWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbHNdLmxhYmVscztcbiAgICB9XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlcyB0aGUgaWNvbiBidXR0b24gYW5kIG1ha2VzIGl0IG5vbi1pbnRlcmFjdGl2ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFwiU29mdC1kaXNhYmxlc1wiIHRoZSBpY29uIGJ1dHRvbiAoZGlzYWJsZWQgYnV0IHN0aWxsIGZvY3VzYWJsZSkuXG4gICAgICAgICAqXG4gICAgICAgICAqIFVzZSB0aGlzIHdoZW4gYW4gaWNvbiBidXR0b24gbmVlZHMgaW5jcmVhc2VkIHZpc2liaWxpdHkgd2hlbiBkaXNhYmxlZC4gU2VlXG4gICAgICAgICAqIGh0dHBzOi8vd3d3LnczLm9yZy9XQUkvQVJJQS9hcGcvcHJhY3RpY2VzL2tleWJvYXJkLWludGVyZmFjZS8ja2JkX2Rpc2FibGVkX2NvbnRyb2xzXG4gICAgICAgICAqIGZvciBtb3JlIGd1aWRhbmNlIG9uIHdoZW4gdGhpcyBpcyBuZWVkZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnNvZnREaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogRmxpcHMgdGhlIGljb24gaWYgaXQgaXMgaW4gYW4gUlRMIGNvbnRleHQgYXQgc3RhcnR1cC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZmxpcEljb25JblJ0bCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2V0cyB0aGUgdW5kZXJseWluZyBgSFRNTEFuY2hvckVsZW1lbnRgJ3MgYGhyZWZgIHJlc291cmNlIGF0dHJpYnV0ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaHJlZiA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGZpbGVuYW1lIHRvIHVzZSB3aGVuIGRvd25sb2FkaW5nIHRoZSBsaW5rZWQgcmVzb3VyY2UuXG4gICAgICAgICAqIElmIG5vdCBzcGVjaWZpZWQsIHRoZSBicm93c2VyIHdpbGwgZGV0ZXJtaW5lIGEgZmlsZW5hbWUuXG4gICAgICAgICAqIFRoaXMgaXMgb25seSBhcHBsaWNhYmxlIHdoZW4gdGhlIGljb24gYnV0dG9uIGlzIHVzZWQgYXMgYSBsaW5rIChgaHJlZmAgaXMgc2V0KS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZG93bmxvYWQgPSAnJztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldHMgdGhlIHVuZGVybHlpbmcgYEhUTUxBbmNob3JFbGVtZW50YCdzIGB0YXJnZXRgIGF0dHJpYnV0ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gJyc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYGFyaWEtbGFiZWxgIG9mIHRoZSBidXR0b24gd2hlbiB0aGUgYnV0dG9uIGlzIHRvZ2dsZWFibGUgYW5kIHNlbGVjdGVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hcmlhTGFiZWxTZWxlY3RlZCA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hlbiB0cnVlLCB0aGUgYnV0dG9uIHdpbGwgdG9nZ2xlIGJldHdlZW4gc2VsZWN0ZWQgYW5kIHVuc2VsZWN0ZWRcbiAgICAgICAgICogc3RhdGVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnRvZ2dsZSA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2V0cyB0aGUgc2VsZWN0ZWQgc3RhdGUuIFdoZW4gZmFsc2UsIGRpc3BsYXlzIHRoZSBkZWZhdWx0IGljb24uIFdoZW4gdHJ1ZSxcbiAgICAgICAgICogZGlzcGxheXMgdGhlIHNlbGVjdGVkIGljb24sIG9yIHRoZSBkZWZhdWx0IGljb24gSWYgbm8gYHNsb3Q9XCJzZWxlY3RlZFwiYFxuICAgICAgICAgKiBpY29uIGlzIHByb3ZpZGVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgdGhlIGJ1dHRvbi4gTWF5IGJlIFwiYnV0dG9uXCIsIFwicmVzZXRcIiwgb3IgXCJzdWJtaXRcIlxuICAgICAgICAgKiAoZGVmYXVsdCkuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnR5cGUgPSAnc3VibWl0JztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSBhZGRlZCB0byBhIGZvcm0gd2l0aCB0aGUgYnV0dG9uJ3MgbmFtZSB3aGVuIHRoZSBidXR0b24gc3VibWl0cyBhXG4gICAgICAgICAqIGZvcm0uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnZhbHVlID0gJyc7XG4gICAgICAgIHRoaXMuZmxpcEljb24gPSBpc1J0bCh0aGlzLCB0aGlzLmZsaXBJY29uSW5SdGwpO1xuICAgICAgICBpZiAoIWlzU2VydmVyKSB7XG4gICAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aWxsVXBkYXRlKCkge1xuICAgICAgICAvLyBMaW5rIGJ1dHRvbnMgY2Fubm90IGJlIGRpc2FibGVkIG9yIHNvZnQtZGlzYWJsZWQuXG4gICAgICAgIGlmICh0aGlzLmhyZWYpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc29mdERpc2FibGVkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCB0YWcgPSB0aGlzLmhyZWYgPyBsaXRlcmFsIGBkaXZgIDogbGl0ZXJhbCBgYnV0dG9uYDtcbiAgICAgICAgLy8gTmVlZGVkIGZvciBjbG9zdXJlIGNvbmZvcm1hbmNlXG4gICAgICAgIGNvbnN0IHsgYXJpYUxhYmVsLCBhcmlhSGFzUG9wdXAsIGFyaWFFeHBhbmRlZCB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgaGFzVG9nZ2xlZEFyaWFMYWJlbCA9IGFyaWFMYWJlbCAmJiB0aGlzLmFyaWFMYWJlbFNlbGVjdGVkO1xuICAgICAgICBjb25zdCBhcmlhUHJlc3NlZFZhbHVlID0gIXRoaXMudG9nZ2xlID8gbm90aGluZyA6IHRoaXMuc2VsZWN0ZWQ7XG4gICAgICAgIGxldCBhcmlhTGFiZWxWYWx1ZSA9IG5vdGhpbmc7XG4gICAgICAgIGlmICghdGhpcy5ocmVmKSB7XG4gICAgICAgICAgICBhcmlhTGFiZWxWYWx1ZSA9XG4gICAgICAgICAgICAgICAgaGFzVG9nZ2xlZEFyaWFMYWJlbCAmJiB0aGlzLnNlbGVjdGVkXG4gICAgICAgICAgICAgICAgICAgID8gdGhpcy5hcmlhTGFiZWxTZWxlY3RlZFxuICAgICAgICAgICAgICAgICAgICA6IGFyaWFMYWJlbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RhdGljSHRtbCBgPCR7dGFnfVxuICAgICAgICBjbGFzcz1cImljb24tYnV0dG9uICR7Y2xhc3NNYXAodGhpcy5nZXRSZW5kZXJDbGFzc2VzKCkpfVwiXG4gICAgICAgIGlkPVwiYnV0dG9uXCJcbiAgICAgICAgYXJpYS1sYWJlbD1cIiR7YXJpYUxhYmVsVmFsdWUgfHwgbm90aGluZ31cIlxuICAgICAgICBhcmlhLWhhc3BvcHVwPVwiJHsoIXRoaXMuaHJlZiAmJiBhcmlhSGFzUG9wdXApIHx8IG5vdGhpbmd9XCJcbiAgICAgICAgYXJpYS1leHBhbmRlZD1cIiR7KCF0aGlzLmhyZWYgJiYgYXJpYUV4cGFuZGVkKSB8fCBub3RoaW5nfVwiXG4gICAgICAgIGFyaWEtcHJlc3NlZD1cIiR7YXJpYVByZXNzZWRWYWx1ZX1cIlxuICAgICAgICBhcmlhLWRpc2FibGVkPSR7KCF0aGlzLmhyZWYgJiYgdGhpcy5zb2Z0RGlzYWJsZWQpIHx8IG5vdGhpbmd9XG4gICAgICAgID9kaXNhYmxlZD1cIiR7IXRoaXMuaHJlZiAmJiB0aGlzLmRpc2FibGVkfVwiXG4gICAgICAgIEBjbGljaz1cIiR7dGhpcy5oYW5kbGVDbGlja09uQ2hpbGR9XCI+XG4gICAgICAgICR7dGhpcy5yZW5kZXJGb2N1c1JpbmcoKX1cbiAgICAgICAgJHt0aGlzLnJlbmRlclJpcHBsZSgpfVxuICAgICAgICAkeyF0aGlzLnNlbGVjdGVkID8gdGhpcy5yZW5kZXJJY29uKCkgOiBub3RoaW5nfVxuICAgICAgICAke3RoaXMuc2VsZWN0ZWQgPyB0aGlzLnJlbmRlclNlbGVjdGVkSWNvbigpIDogbm90aGluZ31cbiAgICAgICAgJHt0aGlzLmhyZWYgPyB0aGlzLnJlbmRlckxpbmsoKSA6IHRoaXMucmVuZGVyVG91Y2hUYXJnZXQoKX1cbiAgPC8ke3RhZ30+YDtcbiAgICB9XG4gICAgcmVuZGVyTGluaygpIHtcbiAgICAgICAgLy8gTmVlZGVkIGZvciBjbG9zdXJlIGNvbmZvcm1hbmNlXG4gICAgICAgIGNvbnN0IHsgYXJpYUxhYmVsIH0gPSB0aGlzO1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8YVxuICAgICAgICBjbGFzcz1cImxpbmtcIlxuICAgICAgICBpZD1cImxpbmtcIlxuICAgICAgICBocmVmPVwiJHt0aGlzLmhyZWZ9XCJcbiAgICAgICAgZG93bmxvYWQ9XCIke3RoaXMuZG93bmxvYWQgfHwgbm90aGluZ31cIlxuICAgICAgICB0YXJnZXQ9XCIke3RoaXMudGFyZ2V0IHx8IG5vdGhpbmd9XCJcbiAgICAgICAgYXJpYS1sYWJlbD1cIiR7YXJpYUxhYmVsIHx8IG5vdGhpbmd9XCI+XG4gICAgICAgICR7dGhpcy5yZW5kZXJUb3VjaFRhcmdldCgpfVxuICAgICAgPC9hPlxuICAgIGA7XG4gICAgfVxuICAgIGdldFJlbmRlckNsYXNzZXMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAnZmxpcC1pY29uJzogdGhpcy5mbGlwSWNvbixcbiAgICAgICAgICAgICdzZWxlY3RlZCc6IHRoaXMudG9nZ2xlICYmIHRoaXMuc2VsZWN0ZWQsXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJlbmRlckljb24oKSB7XG4gICAgICAgIHJldHVybiBodG1sIGA8c3BhbiBjbGFzcz1cImljb25cIj48c2xvdD48L3Nsb3Q+PC9zcGFuPmA7XG4gICAgfVxuICAgIHJlbmRlclNlbGVjdGVkSWNvbigpIHtcbiAgICAgICAgLy8gVXNlIGRlZmF1bHQgc2xvdCBhcyBmYWxsYmFjayB0byBub3QgcmVxdWlyZSBzcGVjaWZ5aW5nIG11bHRpcGxlIGljb25zXG4gICAgICAgIHJldHVybiBodG1sIGA8c3BhbiBjbGFzcz1cImljb24gaWNvbi0tc2VsZWN0ZWRcIlxuICAgICAgPjxzbG90IG5hbWU9XCJzZWxlY3RlZFwiPjxzbG90Pjwvc2xvdD48L3Nsb3RcbiAgICA+PC9zcGFuPmA7XG4gICAgfVxuICAgIHJlbmRlclRvdWNoVGFyZ2V0KCkge1xuICAgICAgICByZXR1cm4gaHRtbCBgPHNwYW4gY2xhc3M9XCJ0b3VjaFwiPjwvc3Bhbj5gO1xuICAgIH1cbiAgICByZW5kZXJGb2N1c1JpbmcoKSB7XG4gICAgICAgIC8vIFRPRE8oYi8zMTAwNDY5MzgpOiB1c2UgdGhlIHNhbWUgaWQgZm9yIGJvdGggZWxlbWVudHNcbiAgICAgICAgcmV0dXJuIGh0bWwgYDxtZC1mb2N1cy1yaW5nXG4gICAgICBwYXJ0PVwiZm9jdXMtcmluZ1wiXG4gICAgICBmb3I9JHt0aGlzLmhyZWYgPyAnbGluaycgOiAnYnV0dG9uJ30+PC9tZC1mb2N1cy1yaW5nPmA7XG4gICAgfVxuICAgIHJlbmRlclJpcHBsZSgpIHtcbiAgICAgICAgY29uc3QgaXNSaXBwbGVEaXNhYmxlZCA9ICF0aGlzLmhyZWYgJiYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5zb2Z0RGlzYWJsZWQpO1xuICAgICAgICAvLyBUT0RPKGIvMzEwMDQ2OTM4KTogdXNlIHRoZSBzYW1lIGlkIGZvciBib3RoIGVsZW1lbnRzXG4gICAgICAgIHJldHVybiBodG1sIGA8bWQtcmlwcGxlXG4gICAgICBmb3I9JHt0aGlzLmhyZWYgPyAnbGluaycgOiBub3RoaW5nfVxuICAgICAgP2Rpc2FibGVkPVwiJHtpc1JpcHBsZURpc2FibGVkfVwiPjwvbWQtcmlwcGxlPmA7XG4gICAgfVxuICAgIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgICAgICB0aGlzLmZsaXBJY29uID0gaXNSdGwodGhpcywgdGhpcy5mbGlwSWNvbkluUnRsKTtcbiAgICAgICAgc3VwZXIuY29ubmVjdGVkQ2FsbGJhY2soKTtcbiAgICB9XG4gICAgLyoqIEhhbmRsZXMgYSBjbGljayBvbiB0aGlzIGVsZW1lbnQuICovXG4gICAgaGFuZGxlQ2xpY2soZXZlbnQpIHtcbiAgICAgICAgLy8gSWYgdGhlIGljb24gYnV0dG9uIGlzIHNvZnQtZGlzYWJsZWQsIHdlIG5lZWQgdG8gZXhwbGljaXRseSBwcmV2ZW50IHRoZVxuICAgICAgICAvLyBjbGljayBmcm9tIHByb3BhZ2F0aW5nIHRvIG90aGVyIGV2ZW50IGxpc3RlbmVycyBhcyB3ZWxsIGFzIHByZXZlbnQgdGhlXG4gICAgICAgIC8vIGRlZmF1bHQgYWN0aW9uLlxuICAgICAgICBpZiAoIXRoaXMuaHJlZiAmJiB0aGlzLnNvZnREaXNhYmxlZCkge1xuICAgICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgYSBjbGljayBvbiB0aGUgY2hpbGQgPGRpdj4gb3IgPGJ1dHRvbj4gZWxlbWVudCB3aXRoaW4gdGhpc1xuICAgICAqIGVsZW1lbnQncyBzaGFkb3cgRE9NLlxuICAgICAqL1xuICAgIGFzeW5jIGhhbmRsZUNsaWNrT25DaGlsZChldmVudCkge1xuICAgICAgICAvLyBBbGxvdyB0aGUgZXZlbnQgdG8gcHJvcGFnYXRlXG4gICAgICAgIGF3YWl0IDA7XG4gICAgICAgIGlmICghdGhpcy50b2dnbGUgfHxcbiAgICAgICAgICAgIHRoaXMuZGlzYWJsZWQgfHxcbiAgICAgICAgICAgIHRoaXMuc29mdERpc2FibGVkIHx8XG4gICAgICAgICAgICBldmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZWxlY3RlZCA9ICF0aGlzLnNlbGVjdGVkO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IElucHV0RXZlbnQoJ2lucHV0JywgeyBidWJibGVzOiB0cnVlLCBjb21wb3NlZDogdHJ1ZSB9KSk7XG4gICAgICAgIC8vIEJ1YmJsZXMgYnV0IGRvZXMgbm90IGNvbXBvc2UgdG8gbWltaWMgbmF0aXZlIGJyb3dzZXIgPGlucHV0PiAmIDxzZWxlY3Q+XG4gICAgICAgIC8vIEFkZGl0aW9uYWxseSwgbmF0aXZlIGNoYW5nZSBldmVudCBpcyBub3QgYW4gSW5wdXRFdmVudC5cbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnY2hhbmdlJywgeyBidWJibGVzOiB0cnVlIH0pKTtcbiAgICB9XG59XG4oKCkgPT4ge1xuICAgIHNldHVwRm9ybVN1Ym1pdHRlcihJY29uQnV0dG9uKTtcbn0pKCk7XG4vKiogQG5vY29sbGFwc2UgKi9cbkljb25CdXR0b24uZm9ybUFzc29jaWF0ZWQgPSB0cnVlO1xuLyoqIEBub2NvbGxhcHNlICovXG5JY29uQnV0dG9uLnNoYWRvd1Jvb3RPcHRpb25zID0ge1xuICAgIG1vZGU6ICdvcGVuJyxcbiAgICBkZWxlZ2F0ZXNGb2N1czogdHJ1ZSxcbn07XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4sIHJlZmxlY3Q6IHRydWUgfSlcbl0sIEljb25CdXR0b24ucHJvdG90eXBlLCBcImRpc2FibGVkXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ3NvZnQtZGlzYWJsZWQnLCByZWZsZWN0OiB0cnVlIH0pXG5dLCBJY29uQnV0dG9uLnByb3RvdHlwZSwgXCJzb2Z0RGlzYWJsZWRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnZmxpcC1pY29uLWluLXJ0bCcgfSlcbl0sIEljb25CdXR0b24ucHJvdG90eXBlLCBcImZsaXBJY29uSW5SdGxcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KClcbl0sIEljb25CdXR0b24ucHJvdG90eXBlLCBcImhyZWZcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KClcbl0sIEljb25CdXR0b24ucHJvdG90eXBlLCBcImRvd25sb2FkXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBJY29uQnV0dG9uLnByb3RvdHlwZSwgXCJ0YXJnZXRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgYXR0cmlidXRlOiAnYXJpYS1sYWJlbC1zZWxlY3RlZCcgfSlcbl0sIEljb25CdXR0b24ucHJvdG90eXBlLCBcImFyaWFMYWJlbFNlbGVjdGVkXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4gfSlcbl0sIEljb25CdXR0b24ucHJvdG90eXBlLCBcInRvZ2dsZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCByZWZsZWN0OiB0cnVlIH0pXG5dLCBJY29uQnV0dG9uLnByb3RvdHlwZSwgXCJzZWxlY3RlZFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoKVxuXSwgSWNvbkJ1dHRvbi5wcm90b3R5cGUsIFwidHlwZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyByZWZsZWN0OiB0cnVlIH0pXG5dLCBJY29uQnV0dG9uLnByb3RvdHlwZSwgXCJ2YWx1ZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgSWNvbkJ1dHRvbi5wcm90b3R5cGUsIFwiZmxpcEljb25cIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWljb24tYnV0dG9uLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8vIEdlbmVyYXRlZCBzdHlsZXNoZWV0IGZvciAuL2ljb25idXR0b24vaW50ZXJuYWwvc2hhcmVkLXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgOmhvc3R7ZGlzcGxheTppbmxpbmUtZmxleDtvdXRsaW5lOm5vbmU7LXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOnJnYmEoMCwwLDAsMCk7aGVpZ2h0OnZhcigtLV9jb250YWluZXItaGVpZ2h0KTt3aWR0aDp2YXIoLS1fY29udGFpbmVyLXdpZHRoKTtqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyfTpob3N0KFt0b3VjaC10YXJnZXQ9d3JhcHBlcl0pe21hcmdpbjptYXgoMHB4LCg0OHB4IC0gdmFyKC0tX2NvbnRhaW5lci1oZWlnaHQpKS8yKSBtYXgoMHB4LCg0OHB4IC0gdmFyKC0tX2NvbnRhaW5lci13aWR0aCkpLzIpfW1kLWZvY3VzLXJpbmd7LS1tZC1mb2N1cy1yaW5nLXNoYXBlLXN0YXJ0LXN0YXJ0OiB2YXIoLS1fY29udGFpbmVyLXNoYXBlLXN0YXJ0LXN0YXJ0KTstLW1kLWZvY3VzLXJpbmctc2hhcGUtc3RhcnQtZW5kOiB2YXIoLS1fY29udGFpbmVyLXNoYXBlLXN0YXJ0LWVuZCk7LS1tZC1mb2N1cy1yaW5nLXNoYXBlLWVuZC1lbmQ6IHZhcigtLV9jb250YWluZXItc2hhcGUtZW5kLWVuZCk7LS1tZC1mb2N1cy1yaW5nLXNoYXBlLWVuZC1zdGFydDogdmFyKC0tX2NvbnRhaW5lci1zaGFwZS1lbmQtc3RhcnQpfTpob3N0KDppcyhbZGlzYWJsZWRdLFtzb2Z0LWRpc2FibGVkXSkpe3BvaW50ZXItZXZlbnRzOm5vbmV9Lmljb24tYnV0dG9ue3BsYWNlLWl0ZW1zOmNlbnRlcjtiYWNrZ3JvdW5kOm5vbmU7Ym9yZGVyOm5vbmU7Ym94LXNpemluZzpib3JkZXItYm94O2N1cnNvcjpwb2ludGVyO2Rpc3BsYXk6ZmxleDtwbGFjZS1jb250ZW50OmNlbnRlcjtvdXRsaW5lOm5vbmU7cGFkZGluZzowO3Bvc2l0aW9uOnJlbGF0aXZlO3RleHQtZGVjb3JhdGlvbjpub25lO3VzZXItc2VsZWN0Om5vbmU7ei1pbmRleDowO2ZsZXg6MTtib3JkZXItc3RhcnQtc3RhcnQtcmFkaXVzOnZhcigtLV9jb250YWluZXItc2hhcGUtc3RhcnQtc3RhcnQpO2JvcmRlci1zdGFydC1lbmQtcmFkaXVzOnZhcigtLV9jb250YWluZXItc2hhcGUtc3RhcnQtZW5kKTtib3JkZXItZW5kLXN0YXJ0LXJhZGl1czp2YXIoLS1fY29udGFpbmVyLXNoYXBlLWVuZC1zdGFydCk7Ym9yZGVyLWVuZC1lbmQtcmFkaXVzOnZhcigtLV9jb250YWluZXItc2hhcGUtZW5kLWVuZCl9Lmljb24gOjpzbG90dGVkKCope2ZvbnQtc2l6ZTp2YXIoLS1faWNvbi1zaXplKTtoZWlnaHQ6dmFyKC0tX2ljb24tc2l6ZSk7d2lkdGg6dmFyKC0tX2ljb24tc2l6ZSk7Zm9udC13ZWlnaHQ6aW5oZXJpdH1tZC1yaXBwbGV7ei1pbmRleDotMTtib3JkZXItc3RhcnQtc3RhcnQtcmFkaXVzOnZhcigtLV9jb250YWluZXItc2hhcGUtc3RhcnQtc3RhcnQpO2JvcmRlci1zdGFydC1lbmQtcmFkaXVzOnZhcigtLV9jb250YWluZXItc2hhcGUtc3RhcnQtZW5kKTtib3JkZXItZW5kLXN0YXJ0LXJhZGl1czp2YXIoLS1fY29udGFpbmVyLXNoYXBlLWVuZC1zdGFydCk7Ym9yZGVyLWVuZC1lbmQtcmFkaXVzOnZhcigtLV9jb250YWluZXItc2hhcGUtZW5kLWVuZCl9LmZsaXAtaWNvbiAuaWNvbnt0cmFuc2Zvcm06c2NhbGVYKC0xKX0uaWNvbntkaXNwbGF5OmlubGluZS1mbGV4fS5saW5re2Rpc3BsYXk6Z3JpZDtoZWlnaHQ6MTAwJTtvdXRsaW5lOm5vbmU7cGxhY2UtaXRlbXM6Y2VudGVyO3Bvc2l0aW9uOmFic29sdXRlO3dpZHRoOjEwMCV9LnRvdWNoe3Bvc2l0aW9uOmFic29sdXRlO2hlaWdodDptYXgoNDhweCwxMDAlKTt3aWR0aDptYXgoNDhweCwxMDAlKX06aG9zdChbdG91Y2gtdGFyZ2V0PW5vbmVdKSAudG91Y2h7ZGlzcGxheTpub25lfUBtZWRpYShmb3JjZWQtY29sb3JzOiBhY3RpdmUpezpob3N0KDppcyhbZGlzYWJsZWRdLFtzb2Z0LWRpc2FibGVkXSkpey0tX2Rpc2FibGVkLWljb24tY29sb3I6IEdyYXlUZXh0Oy0tX2Rpc2FibGVkLWljb24tb3BhY2l0eTogMX19XG5gO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2hhcmVkLXN0eWxlcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG4vLyBHZW5lcmF0ZWQgc3R5bGVzaGVldCBmb3IgLi9pY29uYnV0dG9uL2ludGVybmFsL3N0YW5kYXJkLXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgOmhvc3R7LS1fZGlzYWJsZWQtaWNvbi1jb2xvcjogdmFyKC0tbWQtaWNvbi1idXR0b24tZGlzYWJsZWQtaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9kaXNhYmxlZC1pY29uLW9wYWNpdHk6IHZhcigtLW1kLWljb24tYnV0dG9uLWRpc2FibGVkLWljb24tb3BhY2l0eSwgMC4zOCk7LS1faWNvbi1zaXplOiB2YXIoLS1tZC1pY29uLWJ1dHRvbi1pY29uLXNpemUsIDI0cHgpOy0tX3NlbGVjdGVkLWZvY3VzLWljb24tY29sb3I6IHZhcigtLW1kLWljb24tYnV0dG9uLXNlbGVjdGVkLWZvY3VzLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1wcmltYXJ5LCAjNjc1MGE0KSk7LS1fc2VsZWN0ZWQtaG92ZXItaWNvbi1jb2xvcjogdmFyKC0tbWQtaWNvbi1idXR0b24tc2VsZWN0ZWQtaG92ZXItaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV9zZWxlY3RlZC1ob3Zlci1zdGF0ZS1sYXllci1jb2xvcjogdmFyKC0tbWQtaWNvbi1idXR0b24tc2VsZWN0ZWQtaG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1wcmltYXJ5LCAjNjc1MGE0KSk7LS1fc2VsZWN0ZWQtaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eTogdmFyKC0tbWQtaWNvbi1idXR0b24tc2VsZWN0ZWQtaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4wOCk7LS1fc2VsZWN0ZWQtaWNvbi1jb2xvcjogdmFyKC0tbWQtaWNvbi1idXR0b24tc2VsZWN0ZWQtaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV9zZWxlY3RlZC1wcmVzc2VkLWljb24tY29sb3I6IHZhcigtLW1kLWljb24tYnV0dG9uLXNlbGVjdGVkLXByZXNzZWQtaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV9zZWxlY3RlZC1wcmVzc2VkLXN0YXRlLWxheWVyLWNvbG9yOiB2YXIoLS1tZC1pY29uLWJ1dHRvbi1zZWxlY3RlZC1wcmVzc2VkLXN0YXRlLWxheWVyLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItcHJpbWFyeSwgIzY3NTBhNCkpOy0tX3NlbGVjdGVkLXByZXNzZWQtc3RhdGUtbGF5ZXItb3BhY2l0eTogdmFyKC0tbWQtaWNvbi1idXR0b24tc2VsZWN0ZWQtcHJlc3NlZC1zdGF0ZS1sYXllci1vcGFjaXR5LCAwLjEyKTstLV9zdGF0ZS1sYXllci1oZWlnaHQ6IHZhcigtLW1kLWljb24tYnV0dG9uLXN0YXRlLWxheWVyLWhlaWdodCwgNDBweCk7LS1fc3RhdGUtbGF5ZXItc2hhcGU6IHZhcigtLW1kLWljb24tYnV0dG9uLXN0YXRlLWxheWVyLXNoYXBlLCB2YXIoLS1tZC1zeXMtc2hhcGUtY29ybmVyLWZ1bGwsIDk5OTlweCkpOy0tX3N0YXRlLWxheWVyLXdpZHRoOiB2YXIoLS1tZC1pY29uLWJ1dHRvbi1zdGF0ZS1sYXllci13aWR0aCwgNDBweCk7LS1fZm9jdXMtaWNvbi1jb2xvcjogdmFyKC0tbWQtaWNvbi1idXR0b24tZm9jdXMtaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2hvdmVyLWljb24tY29sb3I6IHZhcigtLW1kLWljb24tYnV0dG9uLWhvdmVyLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9ob3Zlci1zdGF0ZS1sYXllci1jb2xvcjogdmFyKC0tbWQtaWNvbi1idXR0b24taG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5OiB2YXIoLS1tZC1pY29uLWJ1dHRvbi1ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5LCAwLjA4KTstLV9pY29uLWNvbG9yOiB2YXIoLS1tZC1pY29uLWJ1dHRvbi1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fcHJlc3NlZC1pY29uLWNvbG9yOiB2YXIoLS1tZC1pY29uLWJ1dHRvbi1wcmVzc2VkLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9wcmVzc2VkLXN0YXRlLWxheWVyLWNvbG9yOiB2YXIoLS1tZC1pY29uLWJ1dHRvbi1wcmVzc2VkLXN0YXRlLWxheWVyLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fcHJlc3NlZC1zdGF0ZS1sYXllci1vcGFjaXR5OiB2YXIoLS1tZC1pY29uLWJ1dHRvbi1wcmVzc2VkLXN0YXRlLWxheWVyLW9wYWNpdHksIDAuMTIpOy0tX2NvbnRhaW5lci1zaGFwZS1zdGFydC1zdGFydDogMDstLV9jb250YWluZXItc2hhcGUtc3RhcnQtZW5kOiAwOy0tX2NvbnRhaW5lci1zaGFwZS1lbmQtZW5kOiAwOy0tX2NvbnRhaW5lci1zaGFwZS1lbmQtc3RhcnQ6IDA7LS1fY29udGFpbmVyLWhlaWdodDogMDstLV9jb250YWluZXItd2lkdGg6IDA7aGVpZ2h0OnZhcigtLV9zdGF0ZS1sYXllci1oZWlnaHQpO3dpZHRoOnZhcigtLV9zdGF0ZS1sYXllci13aWR0aCl9Omhvc3QoW3RvdWNoLXRhcmdldD13cmFwcGVyXSl7bWFyZ2luOm1heCgwcHgsKDQ4cHggLSB2YXIoLS1fc3RhdGUtbGF5ZXItaGVpZ2h0KSkvMikgbWF4KDBweCwoNDhweCAtIHZhcigtLV9zdGF0ZS1sYXllci13aWR0aCkpLzIpfW1kLWZvY3VzLXJpbmd7LS1tZC1mb2N1cy1yaW5nLXNoYXBlLXN0YXJ0LXN0YXJ0OiB2YXIoLS1fc3RhdGUtbGF5ZXItc2hhcGUpOy0tbWQtZm9jdXMtcmluZy1zaGFwZS1zdGFydC1lbmQ6IHZhcigtLV9zdGF0ZS1sYXllci1zaGFwZSk7LS1tZC1mb2N1cy1yaW5nLXNoYXBlLWVuZC1lbmQ6IHZhcigtLV9zdGF0ZS1sYXllci1zaGFwZSk7LS1tZC1mb2N1cy1yaW5nLXNoYXBlLWVuZC1zdGFydDogdmFyKC0tX3N0YXRlLWxheWVyLXNoYXBlKX0uc3RhbmRhcmR7YmFja2dyb3VuZC1jb2xvcjpyZ2JhKDAsMCwwLDApO2NvbG9yOnZhcigtLV9pY29uLWNvbG9yKTstLW1kLXJpcHBsZS1ob3Zlci1jb2xvcjogdmFyKC0tX2hvdmVyLXN0YXRlLWxheWVyLWNvbG9yKTstLW1kLXJpcHBsZS1ob3Zlci1vcGFjaXR5OiB2YXIoLS1faG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSk7LS1tZC1yaXBwbGUtcHJlc3NlZC1jb2xvcjogdmFyKC0tX3ByZXNzZWQtc3RhdGUtbGF5ZXItY29sb3IpOy0tbWQtcmlwcGxlLXByZXNzZWQtb3BhY2l0eTogdmFyKC0tX3ByZXNzZWQtc3RhdGUtbGF5ZXItb3BhY2l0eSl9LnN0YW5kYXJkOmhvdmVye2NvbG9yOnZhcigtLV9ob3Zlci1pY29uLWNvbG9yKX0uc3RhbmRhcmQ6Zm9jdXN7Y29sb3I6dmFyKC0tX2ZvY3VzLWljb24tY29sb3IpfS5zdGFuZGFyZDphY3RpdmV7Y29sb3I6dmFyKC0tX3ByZXNzZWQtaWNvbi1jb2xvcil9LnN0YW5kYXJkOmlzKDpkaXNhYmxlZCxbYXJpYS1kaXNhYmxlZD10cnVlXSl7Y29sb3I6dmFyKC0tX2Rpc2FibGVkLWljb24tY29sb3IpfW1kLXJpcHBsZXtib3JkZXItcmFkaXVzOnZhcigtLV9zdGF0ZS1sYXllci1zaGFwZSl9LnN0YW5kYXJkOmlzKDpkaXNhYmxlZCxbYXJpYS1kaXNhYmxlZD10cnVlXSl7b3BhY2l0eTp2YXIoLS1fZGlzYWJsZWQtaWNvbi1vcGFjaXR5KX0uc2VsZWN0ZWR7LS1tZC1yaXBwbGUtaG92ZXItY29sb3I6IHZhcigtLV9zZWxlY3RlZC1ob3Zlci1zdGF0ZS1sYXllci1jb2xvcik7LS1tZC1yaXBwbGUtaG92ZXItb3BhY2l0eTogdmFyKC0tX3NlbGVjdGVkLWhvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHkpOy0tbWQtcmlwcGxlLXByZXNzZWQtY29sb3I6IHZhcigtLV9zZWxlY3RlZC1wcmVzc2VkLXN0YXRlLWxheWVyLWNvbG9yKTstLW1kLXJpcHBsZS1wcmVzc2VkLW9wYWNpdHk6IHZhcigtLV9zZWxlY3RlZC1wcmVzc2VkLXN0YXRlLWxheWVyLW9wYWNpdHkpfS5zZWxlY3RlZDpub3QoOmRpc2FibGVkLFthcmlhLWRpc2FibGVkPXRydWVdKXtjb2xvcjp2YXIoLS1fc2VsZWN0ZWQtaWNvbi1jb2xvcil9LnNlbGVjdGVkOm5vdCg6ZGlzYWJsZWQsW2FyaWEtZGlzYWJsZWQ9dHJ1ZV0pOmhvdmVye2NvbG9yOnZhcigtLV9zZWxlY3RlZC1ob3Zlci1pY29uLWNvbG9yKX0uc2VsZWN0ZWQ6bm90KDpkaXNhYmxlZCxbYXJpYS1kaXNhYmxlZD10cnVlXSk6Zm9jdXN7Y29sb3I6dmFyKC0tX3NlbGVjdGVkLWZvY3VzLWljb24tY29sb3IpfS5zZWxlY3RlZDpub3QoOmRpc2FibGVkLFthcmlhLWRpc2FibGVkPXRydWVdKTphY3RpdmV7Y29sb3I6dmFyKC0tX3NlbGVjdGVkLXByZXNzZWQtaWNvbi1jb2xvcil9XG5gO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RhbmRhcmQtc3R5bGVzLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgaW4gYSByaWdodC10by1sZWZ0IGRpcmVjdGlvbi5cbiAqXG4gKiBAcGFyYW0gZWwgRWxlbWVudCB0byBkZXRlcm1pbmUgZGlyZWN0aW9uIGZyb21cbiAqIEBwYXJhbSBzaG91bGRDaGVjayBPcHRpb25hbC4gSWYgYGZhbHNlYCwgcmV0dXJuIGBmYWxzZWAgd2l0aG91dCBjaGVja2luZ1xuICogICAgIGRpcmVjdGlvbi4gRGV0ZXJtaW5pbmcgdGhlIGRpcmVjdGlvbiBvZiBgZWxgIGlzIHNvbWV3aGF0IGV4cGVuc2l2ZSwgc29cbiAqICAgICB0aGlzIHBhcmFtZXRlciBjYW4gYmUgdXNlZCBhcyBhIGNvbmRpdGlvbmFsIGd1YXJkLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1J0bChlbCwgc2hvdWxkQ2hlY2sgPSB0cnVlKSB7XG4gICAgcmV0dXJuIChzaG91bGRDaGVjayAmJlxuICAgICAgICBnZXRDb21wdXRlZFN0eWxlKGVsKS5nZXRQcm9wZXJ0eVZhbHVlKCdkaXJlY3Rpb24nKS50cmltKCkgPT09ICdydGwnKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXJ0bC5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5leHBvcnQgY29uc3Qgc3RyaW5nQ29udmVydGVyID0ge1xuICAgIGZyb21BdHRyaWJ1dGUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID8/ICcnO1xuICAgIH0sXG4gICAgdG9BdHRyaWJ1dGUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlIHx8IG51bGw7XG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdHJpbmctY29udmVydGVyLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IGlzU2VydmVyIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IGludGVybmFscyB9IGZyb20gJy4vZWxlbWVudC1pbnRlcm5hbHMuanMnO1xuLyoqXG4gKiBBIHN5bWJvbCBwcm9wZXJ0eSB1c2VkIHRvIGNyZWF0ZSBhIGNvbnN0cmFpbnQgdmFsaWRhdGlvbiBgVmFsaWRhdG9yYC5cbiAqIFJlcXVpcmVkIGZvciBhbGwgYG1peGluQ29uc3RyYWludFZhbGlkYXRpb24oKWAgZWxlbWVudHMuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVWYWxpZGF0b3IgPSBTeW1ib2woJ2NyZWF0ZVZhbGlkYXRvcicpO1xuLyoqXG4gKiBBIHN5bWJvbCBwcm9wZXJ0eSB1c2VkIHRvIHJldHVybiBhbiBhbmNob3IgZm9yIGNvbnN0cmFpbnQgdmFsaWRhdGlvbiBwb3B1cHMuXG4gKiBSZXF1aXJlZCBmb3IgYWxsIGBtaXhpbkNvbnN0cmFpbnRWYWxpZGF0aW9uKClgIGVsZW1lbnRzLlxuICovXG5leHBvcnQgY29uc3QgZ2V0VmFsaWRpdHlBbmNob3IgPSBTeW1ib2woJ2dldFZhbGlkaXR5QW5jaG9yJyk7XG4vLyBQcml2YXRlIHN5bWJvbCBtZW1iZXJzLCB1c2VkIHRvIGF2b2lkIG5hbWUgY2xhc2hpbmcuXG5jb25zdCBwcml2YXRlVmFsaWRhdG9yID0gU3ltYm9sKCdwcml2YXRlVmFsaWRhdG9yJyk7XG5jb25zdCBwcml2YXRlU3luY1ZhbGlkaXR5ID0gU3ltYm9sKCdwcml2YXRlU3luY1ZhbGlkaXR5Jyk7XG5jb25zdCBwcml2YXRlQ3VzdG9tVmFsaWRhdGlvbk1lc3NhZ2UgPSBTeW1ib2woJ3ByaXZhdGVDdXN0b21WYWxpZGF0aW9uTWVzc2FnZScpO1xuLyoqXG4gKiBNaXhlcyBpbiBjb25zdHJhaW50IHZhbGlkYXRpb24gQVBJcyBmb3IgYW4gZWxlbWVudC5cbiAqXG4gKiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9Db25zdHJhaW50X3ZhbGlkYXRpb25cbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogSW1wbGVtZW50YXRpb25zIG11c3QgcHJvdmlkZSBhIHZhbGlkYXRvciB0byBjYWNoZSBhbmQgY29tcHV0ZSBpdHMgdmFsaWRpdHksXG4gKiBhbG9uZyB3aXRoIGEgc2hhZG93IHJvb3QgZWxlbWVudCB0byBhbmNob3IgdmFsaWRhdGlvbiBwb3B1cHMgdG8uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBjb25zdCBiYXNlQ2xhc3MgPSBtaXhpbkNvbnN0cmFpbnRWYWxpZGF0aW9uKFxuICogICBtaXhpbkZvcm1Bc3NvY2lhdGVkKG1peGluRWxlbWVudEludGVybmFscyhMaXRFbGVtZW50KSlcbiAqICk7XG4gKlxuICogY2xhc3MgTXlDaGVja2JveCBleHRlbmRzIGJhc2VDbGFzcyB7XG4gKiAgIFxcQHByb3BlcnR5KHt0eXBlOiBCb29sZWFufSkgY2hlY2tlZCA9IGZhbHNlO1xuICogICBcXEBwcm9wZXJ0eSh7dHlwZTogQm9vbGVhbn0pIHJlcXVpcmVkID0gZmFsc2U7XG4gKlxuICogICBbY3JlYXRlVmFsaWRhdG9yXSgpIHtcbiAqICAgICByZXR1cm4gbmV3IENoZWNrYm94VmFsaWRhdG9yKCgpID0+IHRoaXMpO1xuICogICB9XG4gKlxuICogICBbZ2V0VmFsaWRpdHlBbmNob3JdKCkge1xuICogICAgIHJldHVybiB0aGlzLnJlbmRlclJvb3QucXVlcnlTZWxlY3RvcignLnJvb3QnKTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIGJhc2UgVGhlIGNsYXNzIHRvIG1peCBmdW5jdGlvbmFsaXR5IGludG8uXG4gKiBAcmV0dXJuIFRoZSBwcm92aWRlZCBjbGFzcyB3aXRoIGBDb25zdHJhaW50VmFsaWRhdGlvbmAgbWl4ZWQgaW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaXhpbkNvbnN0cmFpbnRWYWxpZGF0aW9uKGJhc2UpIHtcbiAgICB2YXIgX2E7XG4gICAgY2xhc3MgQ29uc3RyYWludFZhbGlkYXRpb25FbGVtZW50IGV4dGVuZHMgYmFzZSB7XG4gICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogTmVlZGVkIGZvciBTYWZhcmksIHNlZSBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjYxNDMyXG4gICAgICAgICAgICAgKiBSZXBsYWNlIHdpdGggdGhpc1tpbnRlcm5hbHNdLnZhbGlkaXR5LmN1c3RvbUVycm9yIHdoZW4gcmVzb2x2ZWQuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXNbX2FdID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHZhbGlkaXR5KCkge1xuICAgICAgICAgICAgdGhpc1twcml2YXRlU3luY1ZhbGlkaXR5XSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxzXS52YWxpZGl0eTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgdmFsaWRhdGlvbk1lc3NhZ2UoKSB7XG4gICAgICAgICAgICB0aGlzW3ByaXZhdGVTeW5jVmFsaWRpdHldKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbHNdLnZhbGlkYXRpb25NZXNzYWdlO1xuICAgICAgICB9XG4gICAgICAgIGdldCB3aWxsVmFsaWRhdGUoKSB7XG4gICAgICAgICAgICB0aGlzW3ByaXZhdGVTeW5jVmFsaWRpdHldKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbHNdLndpbGxWYWxpZGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBjaGVja1ZhbGlkaXR5KCkge1xuICAgICAgICAgICAgdGhpc1twcml2YXRlU3luY1ZhbGlkaXR5XSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxzXS5jaGVja1ZhbGlkaXR5KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVwb3J0VmFsaWRpdHkoKSB7XG4gICAgICAgICAgICB0aGlzW3ByaXZhdGVTeW5jVmFsaWRpdHldKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tpbnRlcm5hbHNdLnJlcG9ydFZhbGlkaXR5KCk7XG4gICAgICAgIH1cbiAgICAgICAgc2V0Q3VzdG9tVmFsaWRpdHkoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXNbcHJpdmF0ZUN1c3RvbVZhbGlkYXRpb25NZXNzYWdlXSA9IGVycm9yO1xuICAgICAgICAgICAgdGhpc1twcml2YXRlU3luY1ZhbGlkaXR5XSgpO1xuICAgICAgICB9XG4gICAgICAgIHJlcXVlc3RVcGRhdGUobmFtZSwgb2xkVmFsdWUsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHN1cGVyLnJlcXVlc3RVcGRhdGUobmFtZSwgb2xkVmFsdWUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpc1twcml2YXRlU3luY1ZhbGlkaXR5XSgpO1xuICAgICAgICB9XG4gICAgICAgIGZpcnN0VXBkYXRlZChjaGFuZ2VkKSB7XG4gICAgICAgICAgICBzdXBlci5maXJzdFVwZGF0ZWQoY2hhbmdlZCk7XG4gICAgICAgICAgICAvLyBTeW5jIHRoZSB2YWxpZGl0eSBhZ2FpbiB3aGVuIHRoZSBlbGVtZW50IGZpcnN0IHJlbmRlcnMsIHNpbmNlIHRoZVxuICAgICAgICAgICAgLy8gdmFsaWRpdHkgYW5jaG9yIGlzIG5vdyBhdmFpbGFibGUuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gRWxlbWVudHMgdGhhdCBgZGVsZWdhdGVzRm9jdXM6IHRydWVgIHRvIGFuIGA8aW5wdXQ+YCB3aWxsIHRocm93IGFuXG4gICAgICAgICAgICAvLyBlcnJvciBpbiBDaHJvbWUgYW5kIFNhZmFyaSB3aGVuIGEgZm9ybSB0cmllcyB0byBzdWJtaXQgb3IgY2FsbFxuICAgICAgICAgICAgLy8gYGZvcm0ucmVwb3J0VmFsaWRpdHkoKWA6XG4gICAgICAgICAgICAvLyBcIkFuIGludmFsaWQgZm9ybSBjb250cm9sIHdpdGggbmFtZT0nJyBpcyBub3QgZm9jdXNhYmxlXCJcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBUaGUgdmFsaWRpdHkgYW5jaG9yIE1VU1QgYmUgcHJvdmlkZWQgaW4gYGludGVybmFscy5zZXRWYWxpZGl0eSgpYCBhbmRcbiAgICAgICAgICAgIC8vIE1VU1QgYmUgdGhlIGA8aW5wdXQ+YCBlbGVtZW50IHJlbmRlcmVkLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2xpdC5kZXYvcGxheWdyb3VuZC8jZ2lzdD02YzI2ZTQxOGUwMDEwZjdhNWFhYzE1MDA1Y2RlOGJkZVxuICAgICAgICAgICAgLy8gZm9yIGEgcmVwcm9kdWN0aW9uLlxuICAgICAgICAgICAgdGhpc1twcml2YXRlU3luY1ZhbGlkaXR5XSgpO1xuICAgICAgICB9XG4gICAgICAgIFsoX2EgPSBwcml2YXRlQ3VzdG9tVmFsaWRhdGlvbk1lc3NhZ2UsIHByaXZhdGVTeW5jVmFsaWRpdHkpXSgpIHtcbiAgICAgICAgICAgIGlmIChpc1NlcnZlcikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGhpc1twcml2YXRlVmFsaWRhdG9yXSkge1xuICAgICAgICAgICAgICAgIHRoaXNbcHJpdmF0ZVZhbGlkYXRvcl0gPSB0aGlzW2NyZWF0ZVZhbGlkYXRvcl0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHsgdmFsaWRpdHksIHZhbGlkYXRpb25NZXNzYWdlOiBub25DdXN0b21WYWxpZGF0aW9uTWVzc2FnZSB9ID0gdGhpc1twcml2YXRlVmFsaWRhdG9yXS5nZXRWYWxpZGl0eSgpO1xuICAgICAgICAgICAgY29uc3QgY3VzdG9tRXJyb3IgPSAhIXRoaXNbcHJpdmF0ZUN1c3RvbVZhbGlkYXRpb25NZXNzYWdlXTtcbiAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRpb25NZXNzYWdlID0gdGhpc1twcml2YXRlQ3VzdG9tVmFsaWRhdGlvbk1lc3NhZ2VdIHx8IG5vbkN1c3RvbVZhbGlkYXRpb25NZXNzYWdlO1xuICAgICAgICAgICAgdGhpc1tpbnRlcm5hbHNdLnNldFZhbGlkaXR5KHsgLi4udmFsaWRpdHksIGN1c3RvbUVycm9yIH0sIHZhbGlkYXRpb25NZXNzYWdlLCB0aGlzW2dldFZhbGlkaXR5QW5jaG9yXSgpID8/IHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgW2NyZWF0ZVZhbGlkYXRvcl0oKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltcGxlbWVudCBbY3JlYXRlVmFsaWRhdG9yXScpO1xuICAgICAgICB9XG4gICAgICAgIFtnZXRWYWxpZGl0eUFuY2hvcl0oKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltcGxlbWVudCBbZ2V0VmFsaWRpdHlBbmNob3JdJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIENvbnN0cmFpbnRWYWxpZGF0aW9uRWxlbWVudDtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0cmFpbnQtdmFsaWRhdGlvbi5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBwcm9wZXJ0eSB9IGZyb20gJ2xpdC9kZWNvcmF0b3JzLmpzJztcbmltcG9ydCB7IGludGVybmFscyB9IGZyb20gJy4vZWxlbWVudC1pbnRlcm5hbHMuanMnO1xuLyoqXG4gKiBBIHN5bWJvbCBwcm9wZXJ0eSB0byByZXRyaWV2ZSB0aGUgZm9ybSB2YWx1ZSBmb3IgYW4gZWxlbWVudC5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEZvcm1WYWx1ZSA9IFN5bWJvbCgnZ2V0Rm9ybVZhbHVlJyk7XG4vKipcbiAqIEEgc3ltYm9sIHByb3BlcnR5IHRvIHJldHJpZXZlIHRoZSBmb3JtIHN0YXRlIGZvciBhbiBlbGVtZW50LlxuICovXG5leHBvcnQgY29uc3QgZ2V0Rm9ybVN0YXRlID0gU3ltYm9sKCdnZXRGb3JtU3RhdGUnKTtcbi8qKlxuICogTWl4ZXMgaW4gZm9ybS1hc3NvY2lhdGVkIGJlaGF2aW9yIGZvciBhIGNsYXNzLiBUaGlzIGFsbG93cyBhbiBlbGVtZW50IHRvIGFkZFxuICogdmFsdWVzIHRvIGA8Zm9ybT5gIGVsZW1lbnRzLlxuICpcbiAqIEltcGxlbWVudGluZyBjbGFzc2VzIHNob3VsZCBwcm92aWRlIGEgYFtmb3JtVmFsdWVdYCB0byByZXR1cm4gdGhlIGN1cnJlbnRcbiAqIHZhbHVlIG9mIHRoZSBlbGVtZW50LCBhcyB3ZWxsIGFzIHJlc2V0IGFuZCByZXN0b3JlIGNhbGxiYWNrcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGNvbnN0IGJhc2UgPSBtaXhpbkZvcm1Bc3NvY2lhdGVkKG1peGluRWxlbWVudEludGVybmFscyhMaXRFbGVtZW50KSk7XG4gKlxuICogY2xhc3MgTXlDb250cm9sIGV4dGVuZHMgYmFzZSB7XG4gKiAgIFxcQHByb3BlcnR5KClcbiAqICAgdmFsdWUgPSAnJztcbiAqXG4gKiAgIG92ZXJyaWRlIFtnZXRGb3JtVmFsdWVdKCkge1xuICogICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICogICB9XG4gKlxuICogICBvdmVycmlkZSBmb3JtUmVzZXRDYWxsYmFjaygpIHtcbiAqICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSB0aGlzLmdldEF0dHJpYnV0ZSgndmFsdWUnKTtcbiAqICAgICB0aGlzLnZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICogICB9XG4gKlxuICogICBvdmVycmlkZSBmb3JtU3RhdGVSZXN0b3JlQ2FsbGJhY2soc3RhdGU6IHN0cmluZykge1xuICogICAgIHRoaXMudmFsdWUgPSBzdGF0ZTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogRWxlbWVudHMgbWF5IG9wdGlvbmFsbHkgcHJvdmlkZSBhIGBbZm9ybVN0YXRlXWAgaWYgdGhlaXIgdmFsdWVzIGRvIG5vdFxuICogcmVwcmVzZW50IHRoZSBzdGF0ZSBvZiB0aGUgY29tcG9uZW50LlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogY29uc3QgYmFzZSA9IG1peGluRm9ybUFzc29jaWF0ZWQobWl4aW5FbGVtZW50SW50ZXJuYWxzKExpdEVsZW1lbnQpKTtcbiAqXG4gKiBjbGFzcyBNeUNoZWNrYm94IGV4dGVuZHMgYmFzZSB7XG4gKiAgIFxcQHByb3BlcnR5KClcbiAqICAgdmFsdWUgPSAnb24nO1xuICpcbiAqICAgXFxAcHJvcGVydHkoe3R5cGU6IEJvb2xlYW59KVxuICogICBjaGVja2VkID0gZmFsc2U7XG4gKlxuICogICBvdmVycmlkZSBbZ2V0Rm9ybVZhbHVlXSgpIHtcbiAqICAgICByZXR1cm4gdGhpcy5jaGVja2VkID8gdGhpcy52YWx1ZSA6IG51bGw7XG4gKiAgIH1cbiAqXG4gKiAgIG92ZXJyaWRlIFtnZXRGb3JtU3RhdGVdKCkge1xuICogICAgIHJldHVybiBTdHJpbmcodGhpcy5jaGVja2VkKTtcbiAqICAgfVxuICpcbiAqICAgb3ZlcnJpZGUgZm9ybVJlc2V0Q2FsbGJhY2soKSB7XG4gKiAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gdGhpcy5oYXNBdHRyaWJ1dGUoJ2NoZWNrZWQnKTtcbiAqICAgICB0aGlzLmNoZWNrZWQgPSBkZWZhdWx0VmFsdWU7XG4gKiAgIH1cbiAqXG4gKiAgIG92ZXJyaWRlIGZvcm1TdGF0ZVJlc3RvcmVDYWxsYmFjayhzdGF0ZTogc3RyaW5nKSB7XG4gKiAgICAgdGhpcy5jaGVja2VkID0gQm9vbGVhbihzdGF0ZSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIElNUE9SVEFOVDogUmVxdWlyZXMgZGVjbGFyZXMgZm9yIGxpdC1hbmFseXplclxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBjb25zdCBiYXNlID0gbWl4aW5Gb3JtQXNzb2NpYXRlZChtaXhpbkVsZW1lbnRJbnRlcm5hbHMoTGl0RWxlbWVudCkpO1xuICogY2xhc3MgTXlDb250cm9sIGV4dGVuZHMgYmFzZSB7XG4gKiAgIC8vIFdyaXRhYmxlIG1peGluIHByb3BlcnRpZXMgZm9yIGxpdC1odG1sIGJpbmRpbmcsIG5lZWRlZCBmb3IgbGl0LWFuYWx5emVyXG4gKiAgIGRlY2xhcmUgZGlzYWJsZWQ6IGJvb2xlYW47XG4gKiAgIGRlY2xhcmUgbmFtZTogc3RyaW5nO1xuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIGJhc2UgVGhlIGNsYXNzIHRvIG1peCBmdW5jdGlvbmFsaXR5IGludG8uIFRoZSBiYXNlIGNsYXNzIG11c3QgdXNlXG4gKiAgICAgYG1peGluRWxlbWVudEludGVybmFscygpYC5cbiAqIEByZXR1cm4gVGhlIHByb3ZpZGVkIGNsYXNzIHdpdGggYEZvcm1Bc3NvY2lhdGVkYCBtaXhlZCBpbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1peGluRm9ybUFzc29jaWF0ZWQoYmFzZSkge1xuICAgIGNsYXNzIEZvcm1Bc3NvY2lhdGVkRWxlbWVudCBleHRlbmRzIGJhc2Uge1xuICAgICAgICBnZXQgZm9ybSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW2ludGVybmFsc10uZm9ybTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGFiZWxzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbaW50ZXJuYWxzXS5sYWJlbHM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVXNlIEBwcm9wZXJ0eSBmb3IgdGhlIGBuYW1lYCBhbmQgYGRpc2FibGVkYCBwcm9wZXJ0aWVzIHRvIGFkZCB0aGVtIHRvIHRoZVxuICAgICAgICAvLyBgb2JzZXJ2ZWRBdHRyaWJ1dGVzYCBhcnJheSBhbmQgdHJpZ2dlciBgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKClgLlxuICAgICAgICAvL1xuICAgICAgICAvLyBXZSBkb24ndCB1c2UgTGl0J3MgZGVmYXVsdCBnZXR0ZXIvc2V0dGVyIChgbm9BY2Nlc3NvcjogdHJ1ZWApIGJlY2F1c2VcbiAgICAgICAgLy8gdGhlIGF0dHJpYnV0ZXMgbmVlZCB0byBiZSB1cGRhdGVkIHN5bmNocm9ub3VzbHkgdG8gd29yayB3aXRoIHN5bmNocm9ub3VzXG4gICAgICAgIC8vIGZvcm0gQVBJcywgYW5kIExpdCB1cGRhdGVzIGF0dHJpYnV0ZXMgYXN5bmMgYnkgZGVmYXVsdC5cbiAgICAgICAgZ2V0IG5hbWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoJ25hbWUnKSA/PyAnJztcbiAgICAgICAgfVxuICAgICAgICBzZXQgbmFtZShuYW1lKSB7XG4gICAgICAgICAgICAvLyBOb3RlOiBzZXR0aW5nIG5hbWUgdG8gbnVsbCBvciBlbXB0eSBkb2VzIG5vdCByZW1vdmUgdGhlIGF0dHJpYnV0ZS5cbiAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCduYW1lJywgbmFtZSk7XG4gICAgICAgICAgICAvLyBXZSBkb24ndCBuZWVkIHRvIGNhbGwgYHJlcXVlc3RVcGRhdGUoKWAgc2luY2UgaXQncyBjYWxsZWQgc3luY2hyb25vdXNseVxuICAgICAgICAgICAgLy8gaW4gYGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygpYC5cbiAgICAgICAgfVxuICAgICAgICBnZXQgZGlzYWJsZWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGRpc2FibGVkKGRpc2FibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnRvZ2dsZUF0dHJpYnV0ZSgnZGlzYWJsZWQnLCBkaXNhYmxlZCk7XG4gICAgICAgICAgICAvLyBXZSBkb24ndCBuZWVkIHRvIGNhbGwgYHJlcXVlc3RVcGRhdGUoKWAgc2luY2UgaXQncyBjYWxsZWQgc3luY2hyb25vdXNseVxuICAgICAgICAgICAgLy8gaW4gYGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygpYC5cbiAgICAgICAgfVxuICAgICAgICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgb2xkLCB2YWx1ZSkge1xuICAgICAgICAgICAgLy8gTWFudWFsbHkgYHJlcXVlc3RVcGRhdGUoKWAgZm9yIGBuYW1lYCBhbmQgYGRpc2FibGVkYCB3aGVuIHRoZWlyXG4gICAgICAgICAgICAvLyBhdHRyaWJ1dGUgb3IgcHJvcGVydHkgY2hhbmdlcy5cbiAgICAgICAgICAgIC8vIFRoZSBwcm9wZXJ0aWVzIHVwZGF0ZSB0aGVpciBhdHRyaWJ1dGVzLCBzbyB0aGlzIGNhbGxiYWNrIGlzIGludm9rZWRcbiAgICAgICAgICAgIC8vIGltbWVkaWF0ZWx5IHdoZW4gdGhlIHByb3BlcnRpZXMgYXJlIHNldC4gV2UgY2FsbCBgcmVxdWVzdFVwZGF0ZSgpYCBoZXJlXG4gICAgICAgICAgICAvLyBpbnN0ZWFkIG9mIGxldHRpbmcgTGl0IHNldCB0aGUgcHJvcGVydGllcyBmcm9tIHRoZSBhdHRyaWJ1dGUgY2hhbmdlLlxuICAgICAgICAgICAgLy8gVGhhdCB3b3VsZCBjYXVzZSB0aGUgcHJvcGVydGllcyB0byByZS1zZXQgdGhlIGF0dHJpYnV0ZSBhbmQgaW52b2tlIHRoaXNcbiAgICAgICAgICAgIC8vIGNhbGxiYWNrIGFnYWluIGluIGEgbG9vcC4gVGhpcyBsZWFkcyB0byBzdGFsZSBzdGF0ZSB3aGVuIExpdCB0cmllcyB0b1xuICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIGlmIGEgcHJvcGVydHkgY2hhbmdlZCBvciBub3QuXG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gJ25hbWUnIHx8IG5hbWUgPT09ICdkaXNhYmxlZCcpIHtcbiAgICAgICAgICAgICAgICAvLyBEaXNhYmxlZCdzIHZhbHVlIGlzIG9ubHkgZmFsc2UgaWYgdGhlIGF0dHJpYnV0ZSBpcyBtaXNzaW5nIGFuZCBudWxsLlxuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gbmFtZSA9PT0gJ2Rpc2FibGVkJyA/IG9sZCAhPT0gbnVsbCA6IG9sZDtcbiAgICAgICAgICAgICAgICAvLyBUcmlnZ2VyIGEgbGl0IHVwZGF0ZSB3aGVuIHRoZSBhdHRyaWJ1dGUgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RVcGRhdGUobmFtZSwgb2xkVmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBvbGQsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXF1ZXN0VXBkYXRlKG5hbWUsIG9sZFZhbHVlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBzdXBlci5yZXF1ZXN0VXBkYXRlKG5hbWUsIG9sZFZhbHVlLCBvcHRpb25zKTtcbiAgICAgICAgICAgIC8vIElmIGFueSBwcm9wZXJ0aWVzIGNoYW5nZSwgdXBkYXRlIHRoZSBmb3JtIHZhbHVlLCB3aGljaCBtYXkgaGF2ZSBjaGFuZ2VkXG4gICAgICAgICAgICAvLyBhcyB3ZWxsLlxuICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBmb3JtIHZhbHVlIHN5bmNocm9ub3VzbHkgaW4gYHJlcXVlc3RVcGRhdGUoKWAgcmF0aGVyIHRoYW5cbiAgICAgICAgICAgIC8vIGB1cGRhdGUoKWAgb3IgYHVwZGF0ZWQoKWAsIHdoaWNoIGFyZSBhc3luYy4gVGhpcyBpcyBuZWNlc3NhcnkgdG8gZW5zdXJlXG4gICAgICAgICAgICAvLyB0aGF0IGZvcm0gZGF0YSBpcyB1cGRhdGVkIGluIHRpbWUgZm9yIHN5bmNocm9ub3VzIGV2ZW50IGxpc3RlbmVycy5cbiAgICAgICAgICAgIHRoaXNbaW50ZXJuYWxzXS5zZXRGb3JtVmFsdWUodGhpc1tnZXRGb3JtVmFsdWVdKCksIHRoaXNbZ2V0Rm9ybVN0YXRlXSgpKTtcbiAgICAgICAgfVxuICAgICAgICBbZ2V0Rm9ybVZhbHVlXSgpIHtcbiAgICAgICAgICAgIC8vIENsb3N1cmUgZG9lcyBub3QgYWxsb3cgYWJzdHJhY3Qgc3ltYm9sIG1lbWJlcnMsIHNvIGEgZGVmYXVsdFxuICAgICAgICAgICAgLy8gaW1wbGVtZW50YXRpb24gaXMgbmVlZGVkLlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbXBsZW1lbnQgW2dldEZvcm1WYWx1ZV0nKTtcbiAgICAgICAgfVxuICAgICAgICBbZ2V0Rm9ybVN0YXRlXSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW2dldEZvcm1WYWx1ZV0oKTtcbiAgICAgICAgfVxuICAgICAgICBmb3JtRGlzYWJsZWRDYWxsYmFjayhkaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5kaXNhYmxlZCA9IGRpc2FibGVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKiBAbm9jb2xsYXBzZSAqL1xuICAgIEZvcm1Bc3NvY2lhdGVkRWxlbWVudC5mb3JtQXNzb2NpYXRlZCA9IHRydWU7XG4gICAgX19kZWNvcmF0ZShbXG4gICAgICAgIHByb3BlcnR5KHsgbm9BY2Nlc3NvcjogdHJ1ZSB9KVxuICAgIF0sIEZvcm1Bc3NvY2lhdGVkRWxlbWVudC5wcm90b3R5cGUsIFwibmFtZVwiLCBudWxsKTtcbiAgICBfX2RlY29yYXRlKFtcbiAgICAgICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBub0FjY2Vzc29yOiB0cnVlIH0pXG4gICAgXSwgRm9ybUFzc29jaWF0ZWRFbGVtZW50LnByb3RvdHlwZSwgXCJkaXNhYmxlZFwiLCBudWxsKTtcbiAgICByZXR1cm4gRm9ybUFzc29jaWF0ZWRFbGVtZW50O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Zm9ybS1hc3NvY2lhdGVkLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IGlzU2VydmVyIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IGludGVybmFscyB9IGZyb20gJy4vZWxlbWVudC1pbnRlcm5hbHMuanMnO1xuLyoqXG4gKiBBIHN5bWJvbCBwcm9wZXJ0eSB1c2VkIGZvciBhIGNhbGxiYWNrIHdoZW4gdmFsaWRpdHkgaGFzIGJlZW4gcmVwb3J0ZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBvblJlcG9ydFZhbGlkaXR5ID0gU3ltYm9sKCdvblJlcG9ydFZhbGlkaXR5Jyk7XG4vLyBQcml2YXRlIHN5bWJvbCBtZW1iZXJzLCB1c2VkIHRvIGF2b2lkIG5hbWUgY2xhc2hpbmcuXG5jb25zdCBwcml2YXRlQ2xlYW51cEZvcm1MaXN0ZW5lcnMgPSBTeW1ib2woJ3ByaXZhdGVDbGVhbnVwRm9ybUxpc3RlbmVycycpO1xuY29uc3QgcHJpdmF0ZURvTm90UmVwb3J0SW52YWxpZCA9IFN5bWJvbCgncHJpdmF0ZURvTm90UmVwb3J0SW52YWxpZCcpO1xuY29uc3QgcHJpdmF0ZUlzU2VsZlJlcG9ydGluZ1ZhbGlkaXR5ID0gU3ltYm9sKCdwcml2YXRlSXNTZWxmUmVwb3J0aW5nVmFsaWRpdHknKTtcbmNvbnN0IHByaXZhdGVDYWxsT25SZXBvcnRWYWxpZGl0eSA9IFN5bWJvbCgncHJpdmF0ZUNhbGxPblJlcG9ydFZhbGlkaXR5Jyk7XG4vKipcbiAqIE1peGVzIGluIGEgY2FsbGJhY2sgZm9yIGNvbnN0cmFpbnQgdmFsaWRhdGlvbiB3aGVuIHZhbGlkaXR5IHNob3VsZCBiZVxuICogc3R5bGVkIGFuZCByZXBvcnRlZCB0byB0aGUgdXNlci5cbiAqXG4gKiBUaGlzIGlzIGNvbW1vbmx5IHVzZWQgaW4gdGV4dC1maWVsZC1saWtlIGNvbnRyb2xzIHRoYXQgZGlzcGxheSBlcnJvciBzdHlsZXNcbiAqIGFuZCBlcnJvciBtZXNzYWdlcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGNvbnN0IGJhc2VDbGFzcyA9IG1peGluT25SZXBvcnRWYWxpZGl0eShcbiAqICAgbWl4aW5Db25zdHJhaW50VmFsaWRhdGlvbihcbiAqICAgICBtaXhpbkZvcm1Bc3NvY2lhdGVkKG1peGluRWxlbWVudEludGVybmFscyhMaXRFbGVtZW50KSksXG4gKiAgICksXG4gKiApO1xuICpcbiAqIGNsYXNzIE15RmllbGQgZXh0ZW5kcyBiYXNlQ2xhc3Mge1xuICogICBcXEBwcm9wZXJ0eSh7dHlwZTogQm9vbGVhbn0pIGVycm9yID0gZmFsc2U7XG4gKiAgIFxcQHByb3BlcnR5KCkgZXJyb3JNZXNzYWdlID0gJyc7XG4gKlxuICogICBbb25SZXBvcnRWYWxpZGl0eV0oaW52YWxpZEV2ZW50OiBFdmVudCB8IG51bGwpIHtcbiAqICAgICB0aGlzLmVycm9yID0gISFpbnZhbGlkRXZlbnQ7XG4gKiAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSB0aGlzLnZhbGlkYXRpb25NZXNzYWdlO1xuICpcbiAqICAgICAvLyBPcHRpb25hbGx5IHByZXZlbnQgcGxhdGZvcm0gcG9wdXAgZnJvbSBkaXNwbGF5aW5nXG4gKiAgICAgaW52YWxpZEV2ZW50Py5wcmV2ZW50RGVmYXVsdCgpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gYmFzZSBUaGUgY2xhc3MgdG8gbWl4IGZ1bmN0aW9uYWxpdHkgaW50by5cbiAqIEByZXR1cm4gVGhlIHByb3ZpZGVkIGNsYXNzIHdpdGggYE9uUmVwb3J0VmFsaWRpdHlgIG1peGVkIGluLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWl4aW5PblJlcG9ydFZhbGlkaXR5KGJhc2UpIHtcbiAgICB2YXIgX2EsIF9iLCBfYztcbiAgICBjbGFzcyBPblJlcG9ydFZhbGlkaXR5RWxlbWVudCBleHRlbmRzIGJhc2Uge1xuICAgICAgICAvLyBNaXhpbnMgbXVzdCBoYXZlIGEgY29uc3RydWN0b3Igd2l0aCBgLi4uYXJnczogYW55W11gXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgICAgY29uc3RydWN0b3IoLi4uYXJncykge1xuICAgICAgICAgICAgc3VwZXIoLi4uYXJncyk7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFVzZWQgdG8gY2xlYW4gdXAgZXZlbnQgbGlzdGVuZXJzIHdoZW4gYSBuZXcgZm9ybSBpcyBhc3NvY2lhdGVkLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzW19hXSA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVXNlZCB0byBkZXRlcm1pbmUgaWYgYW4gaW52YWxpZCBldmVudCBzaG91bGQgcmVwb3J0IHZhbGlkaXR5LiBJbnZhbGlkXG4gICAgICAgICAgICAgKiBldmVudHMgZnJvbSBgY2hlY2tWYWxpZGl0eSgpYCBkbyBub3QgdHJpZ2dlciByZXBvcnRpbmcuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXNbX2JdID0gZmFsc2U7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFVzZWQgdG8gZGV0ZXJtaW5lIGlmIHRoZSBjb250cm9sIGlzIHJlcG9ydGluZyB2YWxpZGl0eSBmcm9tIGl0c2VsZiwgb3JcbiAgICAgICAgICAgICAqIGlmIGEgYDxmb3JtPmAgaXMgY2F1c2luZyB0aGUgdmFsaWRpdHkgcmVwb3J0LiBGb3JtcyBoYXZlIGRpZmZlcmVudFxuICAgICAgICAgICAgICogY29udHJvbCBmb2N1c2luZyBiZWhhdmlvci5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpc1tfY10gPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChpc1NlcnZlcikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignaW52YWxpZCcsIChpbnZhbGlkRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBMaXN0ZW4gZm9yIGludmFsaWQgZXZlbnRzIGRpc3BhdGNoZWQgYnkgYSBgPGZvcm0+YCB3aGVuIGl0IHRyaWVzIHRvXG4gICAgICAgICAgICAgICAgLy8gc3VibWl0IGFuZCB0aGUgZWxlbWVudCBpcyBpbnZhbGlkLiBXZSBpZ25vcmUgZXZlbnRzIGRpc3BhdGNoZWQgd2hlblxuICAgICAgICAgICAgICAgIC8vIGNhbGxpbmcgYGNoZWNrVmFsaWRpdHkoKWAgYXMgd2VsbCBhcyB1bnRydXN0ZWQgZXZlbnRzLCBzaW5jZSB0aGVcbiAgICAgICAgICAgICAgICAvLyBgcmVwb3J0VmFsaWRpdHkoKWAgYW5kIGA8Zm9ybT5gLWRpc3BhdGNoZWQgZXZlbnRzIGFyZSBhbHdheXNcbiAgICAgICAgICAgICAgICAvLyB0cnVzdGVkLlxuICAgICAgICAgICAgICAgIGlmICh0aGlzW3ByaXZhdGVEb05vdFJlcG9ydEludmFsaWRdIHx8ICFpbnZhbGlkRXZlbnQuaXNUcnVzdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdpbnZhbGlkJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIG5vcm1hbCBidWJibGluZyBwaGFzZSBldmVudCBsaXN0ZW5lci4gQnkgYWRkaW5nIGl0IGhlcmUsIHdlXG4gICAgICAgICAgICAgICAgICAgIC8vIGVuc3VyZSBpdCdzIHRoZSBsYXN0IGV2ZW50IGxpc3RlbmVyIHRoYXQgaXMgY2FsbGVkIGR1cmluZyB0aGVcbiAgICAgICAgICAgICAgICAgICAgLy8gYnViYmxpbmcgcGhhc2UuXG4gICAgICAgICAgICAgICAgICAgIHRoaXNbcHJpdmF0ZUNhbGxPblJlcG9ydFZhbGlkaXR5XShpbnZhbGlkRXZlbnQpO1xuICAgICAgICAgICAgICAgIH0sIHsgb25jZTogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAvLyBMaXN0ZW4gZHVyaW5nIHRoZSBjYXB0dXJlIHBoYXNlLCB3aGljaCB3aWxsIGhhcHBlbiBiZWZvcmUgdGhlXG4gICAgICAgICAgICAgICAgLy8gYnViYmxpbmcgcGhhc2UuIFRoYXQgd2F5LCB3ZSBjYW4gYWRkIGEgZmluYWwgZXZlbnQgbGlzdGVuZXIgdGhhdFxuICAgICAgICAgICAgICAgIC8vIHdpbGwgcnVuIGFmdGVyIG90aGVyIGV2ZW50IGxpc3RlbmVycywgYW5kIHdlIGNhbiBjaGVjayBpZiBpdCB3YXNcbiAgICAgICAgICAgICAgICAvLyBkZWZhdWx0IHByZXZlbnRlZC4gVGhpcyB3b3JrcyBiZWNhdXNlIGludmFsaWQgZG9lcyBub3QgYnViYmxlLlxuICAgICAgICAgICAgICAgIGNhcHR1cmU6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjaGVja1ZhbGlkaXR5KCkge1xuICAgICAgICAgICAgdGhpc1twcml2YXRlRG9Ob3RSZXBvcnRJbnZhbGlkXSA9IHRydWU7XG4gICAgICAgICAgICBjb25zdCB2YWxpZCA9IHN1cGVyLmNoZWNrVmFsaWRpdHkoKTtcbiAgICAgICAgICAgIHRoaXNbcHJpdmF0ZURvTm90UmVwb3J0SW52YWxpZF0gPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiB2YWxpZDtcbiAgICAgICAgfVxuICAgICAgICByZXBvcnRWYWxpZGl0eSgpIHtcbiAgICAgICAgICAgIHRoaXNbcHJpdmF0ZUlzU2VsZlJlcG9ydGluZ1ZhbGlkaXR5XSA9IHRydWU7XG4gICAgICAgICAgICBjb25zdCB2YWxpZCA9IHN1cGVyLnJlcG9ydFZhbGlkaXR5KCk7XG4gICAgICAgICAgICAvLyBDb25zdHJ1Y3RvcidzIGludmFsaWQgbGlzdGVuZXIgd2lsbCBoYW5kbGUgcmVwb3J0aW5nIGludmFsaWQgZXZlbnRzLlxuICAgICAgICAgICAgaWYgKHZhbGlkKSB7XG4gICAgICAgICAgICAgICAgdGhpc1twcml2YXRlQ2FsbE9uUmVwb3J0VmFsaWRpdHldKG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpc1twcml2YXRlSXNTZWxmUmVwb3J0aW5nVmFsaWRpdHldID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4gdmFsaWQ7XG4gICAgICAgIH1cbiAgICAgICAgWyhfYSA9IHByaXZhdGVDbGVhbnVwRm9ybUxpc3RlbmVycywgX2IgPSBwcml2YXRlRG9Ob3RSZXBvcnRJbnZhbGlkLCBfYyA9IHByaXZhdGVJc1NlbGZSZXBvcnRpbmdWYWxpZGl0eSwgcHJpdmF0ZUNhbGxPblJlcG9ydFZhbGlkaXR5KV0oaW52YWxpZEV2ZW50KSB7XG4gICAgICAgICAgICAvLyBTaW5jZSBpbnZhbGlkIGV2ZW50cyBkbyBub3QgYnViYmxlIHRvIHBhcmVudCBsaXN0ZW5lcnMsIGFuZCBiZWNhdXNlXG4gICAgICAgICAgICAvLyBvdXIgaW52YWxpZCBsaXN0ZW5lcnMgYXJlIGFkZGVkIGxhemlseSBhZnRlciBvdGhlciBsaXN0ZW5lcnMsIHdlIGNhblxuICAgICAgICAgICAgLy8gcmVsaWFibHkgcmVhZCBgZGVmYXVsdFByZXZlbnRlZGAgc3luY2hyb25vdXNseSB3aXRob3V0IHdvcnJ5aW5nXG4gICAgICAgICAgICAvLyBhYm91dCB3YWl0aW5nIGZvciBhbm90aGVyIGxpc3RlbmVyIHRoYXQgY291bGQgY2FuY2VsIGl0LlxuICAgICAgICAgICAgY29uc3Qgd2FzQ2FuY2VsZWQgPSBpbnZhbGlkRXZlbnQ/LmRlZmF1bHRQcmV2ZW50ZWQ7XG4gICAgICAgICAgICBpZiAod2FzQ2FuY2VsZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzW29uUmVwb3J0VmFsaWRpdHldKGludmFsaWRFdmVudCk7XG4gICAgICAgICAgICAvLyBJZiBhbiBpbXBsZW1lbnRhdGlvbiBjYWxscyBpbnZhbGlkRXZlbnQucHJldmVudERlZmF1bHQoKSB0byBzdG9wIHRoZVxuICAgICAgICAgICAgLy8gcGxhdGZvcm0gcG9wdXAgZnJvbSBkaXNwbGF5aW5nLCBmb2N1c2luZyBpcyBhbHNvIHByZXZlbnRlZCwgc28gd2UgbmVlZFxuICAgICAgICAgICAgLy8gdG8gbWFudWFsbHkgZm9jdXMuXG4gICAgICAgICAgICBjb25zdCBpbXBsZW1lbnRhdGlvbkNhbmNlbGVkRm9jdXMgPSAhd2FzQ2FuY2VsZWQgJiYgaW52YWxpZEV2ZW50Py5kZWZhdWx0UHJldmVudGVkO1xuICAgICAgICAgICAgaWYgKCFpbXBsZW1lbnRhdGlvbkNhbmNlbGVkRm9jdXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBUaGUgY29udHJvbCBzaG91bGQgYmUgZm9jdXNlZCB3aGVuOlxuICAgICAgICAgICAgLy8gLSBgY29udHJvbC5yZXBvcnRWYWxpZGl0eSgpYCBpcyBjYWxsZWQgKHNlbGYtcmVwb3J0aW5nKS5cbiAgICAgICAgICAgIC8vIC0gYSBmb3JtIGlzIHJlcG9ydGluZyB2YWxpZGl0eSBmb3IgaXRzIGNvbnRyb2xzIGFuZCB0aGlzIGlzIHRoZSBmaXJzdFxuICAgICAgICAgICAgLy8gICBpbnZhbGlkIGNvbnRyb2wuXG4gICAgICAgICAgICBpZiAodGhpc1twcml2YXRlSXNTZWxmUmVwb3J0aW5nVmFsaWRpdHldIHx8XG4gICAgICAgICAgICAgICAgaXNGaXJzdEludmFsaWRDb250cm9sSW5Gb3JtKHRoaXNbaW50ZXJuYWxzXS5mb3JtLCB0aGlzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBbb25SZXBvcnRWYWxpZGl0eV0oaW52YWxpZEV2ZW50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltcGxlbWVudCBbb25SZXBvcnRWYWxpZGl0eV0nKTtcbiAgICAgICAgfVxuICAgICAgICBmb3JtQXNzb2NpYXRlZENhbGxiYWNrKGZvcm0pIHtcbiAgICAgICAgICAgIC8vIGNhbid0IHVzZSBzdXBlci5mb3JtQXNzb2NpYXRlZENhbGxiYWNrPy4oKSBkdWUgdG8gY2xvc3VyZVxuICAgICAgICAgICAgaWYgKHN1cGVyLmZvcm1Bc3NvY2lhdGVkQ2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICBzdXBlci5mb3JtQXNzb2NpYXRlZENhbGxiYWNrKGZvcm0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ2xlYW4gdXAgcHJldmlvdXMgZm9ybSBsaXN0ZW5lcnMuXG4gICAgICAgICAgICB0aGlzW3ByaXZhdGVDbGVhbnVwRm9ybUxpc3RlbmVyc10uYWJvcnQoKTtcbiAgICAgICAgICAgIGlmICghZm9ybSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXNbcHJpdmF0ZUNsZWFudXBGb3JtTGlzdGVuZXJzXSA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICAgICAgICAgIC8vIEFkZCBhIGxpc3RlbmVyIHRoYXQgZmlyZXMgd2hlbiB0aGUgZm9ybSBydW5zIGNvbnN0cmFpbnQgdmFsaWRhdGlvbiBhbmRcbiAgICAgICAgICAgIC8vIHRoZSBjb250cm9sIGlzIHZhbGlkLCBzbyB0aGF0IGl0IG1heSByZW1vdmUgaXRzIGVycm9yIHN0eWxlcy5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBUaGlzIGhhcHBlbnMgb24gYGZvcm0ucmVwb3J0VmFsaWRpdHkoKWAgYW5kIGBmb3JtLnJlcXVlc3RTdWJtaXQoKWBcbiAgICAgICAgICAgIC8vIChib3RoIHdoZW4gdGhlIHN1Ym1pdCBmYWlscyBhbmQgcGFzc2VzKS5cbiAgICAgICAgICAgIGFkZEZvcm1SZXBvcnRWYWxpZExpc3RlbmVyKHRoaXMsIGZvcm0sICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzW3ByaXZhdGVDYWxsT25SZXBvcnRWYWxpZGl0eV0obnVsbCk7XG4gICAgICAgICAgICB9LCB0aGlzW3ByaXZhdGVDbGVhbnVwRm9ybUxpc3RlbmVyc10uc2lnbmFsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gT25SZXBvcnRWYWxpZGl0eUVsZW1lbnQ7XG59XG4vKipcbiAqIEFkZCBhIGxpc3RlbmVyIHRoYXQgZmlyZXMgd2hlbiBhIGZvcm0gcnVucyBjb25zdHJhaW50IHZhbGlkYXRpb24gb24gYSBjb250cm9sXG4gKiBhbmQgaXQgaXMgdmFsaWQuIFRoaXMgaXMgbmVlZGVkIHRvIGNsZWFyIHByZXZpb3VzbHkgaW52YWxpZCBzdHlsZXMuXG4gKlxuICogQHBhcmFtIGNvbnRyb2wgVGhlIGNvbnRyb2wgb2YgdGhlIGZvcm0gdG8gbGlzdGVuIGZvciB2YWxpZCBldmVudHMuXG4gKiBAcGFyYW0gZm9ybSBUaGUgY29udHJvbCdzIGZvcm0gdGhhdCBjYW4gcnVuIGNvbnN0cmFpbnQgdmFsaWRhdGlvbi5cbiAqIEBwYXJhbSBvbkNvbnRyb2xWYWxpZCBBIGxpc3RlbmVyIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIGZvcm0gcnVucyBjb25zdHJhaW50XG4gKiAgICAgdmFsaWRhdGlvbiBhbmQgdGhlIGNvbnRyb2wgaXMgdmFsaWQuXG4gKiBAcGFyYW0gY2xlYW51cCBBIGNsZWFudXAgc2lnbmFsIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG4gKi9cbmZ1bmN0aW9uIGFkZEZvcm1SZXBvcnRWYWxpZExpc3RlbmVyKGNvbnRyb2wsIGZvcm0sIG9uQ29udHJvbFZhbGlkLCBjbGVhbnVwKSB7XG4gICAgY29uc3QgdmFsaWRhdGVIb29rcyA9IGdldEZvcm1WYWxpZGF0ZUhvb2tzKGZvcm0pO1xuICAgIC8vIFdoZW4gYSBmb3JtIHZhbGlkYXRlcyBpdHMgY29udHJvbHMsIGNoZWNrIGlmIGFuIGludmFsaWQgZXZlbnQgaXMgZGlzcGF0Y2hlZFxuICAgIC8vIG9uIHRoZSBjb250cm9sLiBJZiBpdCBpcyBub3QsIHRoZW4gaW5mb3JtIHRoZSBjb250cm9sIHRvIHJlcG9ydCBpdHMgdmFsaWRcbiAgICAvLyBzdGF0ZS5cbiAgICBsZXQgY29udHJvbEZpcmVkSW52YWxpZCA9IGZhbHNlO1xuICAgIGxldCBjbGVhbnVwSW52YWxpZExpc3RlbmVyO1xuICAgIGxldCBpc05leHRTdWJtaXRGcm9tSG9vayA9IGZhbHNlO1xuICAgIHZhbGlkYXRlSG9va3MuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JlJywgKCkgPT4ge1xuICAgICAgICBpc05leHRTdWJtaXRGcm9tSG9vayA9IHRydWU7XG4gICAgICAgIGNsZWFudXBJbnZhbGlkTGlzdGVuZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICAgIGNvbnRyb2xGaXJlZEludmFsaWQgPSBmYWxzZTtcbiAgICAgICAgY29udHJvbC5hZGRFdmVudExpc3RlbmVyKCdpbnZhbGlkJywgKCkgPT4ge1xuICAgICAgICAgICAgY29udHJvbEZpcmVkSW52YWxpZCA9IHRydWU7XG4gICAgICAgIH0sIHtcbiAgICAgICAgICAgIHNpZ25hbDogY2xlYW51cEludmFsaWRMaXN0ZW5lci5zaWduYWwsXG4gICAgICAgIH0pO1xuICAgIH0sIHsgc2lnbmFsOiBjbGVhbnVwIH0pO1xuICAgIHZhbGlkYXRlSG9va3MuYWRkRXZlbnRMaXN0ZW5lcignYWZ0ZXInLCAoKSA9PiB7XG4gICAgICAgIGlzTmV4dFN1Ym1pdEZyb21Ib29rID0gZmFsc2U7XG4gICAgICAgIGNsZWFudXBJbnZhbGlkTGlzdGVuZXI/LmFib3J0KCk7XG4gICAgICAgIGlmIChjb250cm9sRmlyZWRJbnZhbGlkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb25Db250cm9sVmFsaWQoKTtcbiAgICB9LCB7IHNpZ25hbDogY2xlYW51cCB9KTtcbiAgICAvLyBUaGUgYWJvdmUgaG9va3MgaGFuZGxlIGltcGVyYXRpdmVseSBzdWJtaXR0aW5nIHRoZSBmb3JtLCBidXQgbm90XG4gICAgLy8gZGVjbGFyYXRpdmVseSBzdWJtaXR0aW5nIHRoZSBmb3JtLiBUaGlzIGhhcHBlbnMgd2hlbjpcbiAgICAvLyAxLiBBIG5vbi1jdXN0b20gZWxlbWVudCBgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCI+YCBpcyBjbGlja2VkLlxuICAgIC8vIDIuIEVudGVyIGlzIHByZXNzZWQgb24gYSBub24tY3VzdG9tIGVsZW1lbnQgdGV4dCBlZGl0YWJsZSBgPGlucHV0PmAuXG4gICAgZm9ybS5hZGRFdmVudExpc3RlbmVyKCdzdWJtaXQnLCAoKSA9PiB7XG4gICAgICAgIC8vIFRoaXMgc3VibWl0IHdhcyBmcm9tIGBmb3JtLnJlcXVlc3RTdWJtaXQoKWAsIHdoaWNoIGFscmVhZHkgY2FsbHMgdGhlXG4gICAgICAgIC8vIGxpc3RlbmVyLlxuICAgICAgICBpZiAoaXNOZXh0U3VibWl0RnJvbUhvb2spIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBvbkNvbnRyb2xWYWxpZCgpO1xuICAgIH0sIHtcbiAgICAgICAgc2lnbmFsOiBjbGVhbnVwLFxuICAgIH0pO1xuICAgIC8vIE5vdGU6IGl0IGlzIGEga25vd24gbGltaXRhdGlvbiB0aGF0IHdlIGNhbm5vdCBkZXRlY3QgaWYgYSBmb3JtIHRyaWVzIHRvXG4gICAgLy8gc3VibWl0IGRlY2xhcmF0aXZlbHksIGJ1dCBmYWlscyB0byBkbyBzbyBiZWNhdXNlIGFuIHVucmVsYXRlZCBzaWJsaW5nXG4gICAgLy8gY29udHJvbCBmYWlsZWQgaXRzIGNvbnN0cmFpbnQgdmFsaWRhdGlvbi5cbiAgICAvL1xuICAgIC8vIFNpbmNlIHdlIGNhbm5vdCBkZXRlY3Qgd2hlbiB0aGF0IGhhcHBlbnMsIGEgcHJldmlvdXNseSBpbnZhbGlkIGNvbnRyb2wgbWF5XG4gICAgLy8gbm90IGNsZWFyIGl0cyBlcnJvciBzdHlsaW5nIHdoZW4gaXQgYmVjb21lcyB2YWxpZCBhZ2Fpbi5cbiAgICAvL1xuICAgIC8vIFRvIHdvcmsgYXJvdW5kIHRoaXMsIGNhbGwgYGZvcm0ucmVwb3J0VmFsaWRpdHkoKWAgd2hlbiBzdWJtaXR0aW5nIGEgZm9ybVxuICAgIC8vIGRlY2xhcmF0aXZlbHkuIFRoaXMgY2FuIGJlIGRvd24gb24gdGhlIGA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIj5gJ3MgY2xpY2sgb3JcbiAgICAvLyB0aGUgdGV4dCBlZGl0YWJsZSBgPGlucHV0PmAncyAnRW50ZXInIGtleWRvd24uXG59XG5jb25zdCBGT1JNX1ZBTElEQVRFX0hPT0tTID0gbmV3IFdlYWtNYXAoKTtcbi8qKlxuICogR2V0IGEgaG9va3MgYEV2ZW50VGFyZ2V0YCB0aGF0IGRpc3BhdGNoZXMgJ2JlZm9yZScgYW5kICdhZnRlcicgZXZlbnRzIHRoYXRcbiAqIGZpcmUgYmVmb3JlIGEgZm9ybSBydW5zIGNvbnN0cmFpbnQgdmFsaWRhdGlvbiBhbmQgaW1tZWRpYXRlbHkgYWZ0ZXIgaXRcbiAqIGZpbmlzaGVzIHJ1bm5pbmcgY29uc3RyYWludCB2YWxpZGF0aW9uIG9uIGl0cyBjb250cm9scy5cbiAqXG4gKiBUaGlzIGhhcHBlbnMgZHVyaW5nIGBmb3JtLnJlcG9ydFZhbGlkaXR5KClgIGFuZCBgZm9ybS5yZXF1ZXN0U3VibWl0KClgLlxuICpcbiAqIEBwYXJhbSBmb3JtIFRoZSBmb3JtIHRvIGdldCBvciBzZXQgdXAgaG9va3MgZm9yLlxuICogQHJldHVybiBBIGhvb2tzIGBFdmVudFRhcmdldGAgdG8gYWRkIGxpc3RlbmVycyB0by5cbiAqL1xuZnVuY3Rpb24gZ2V0Rm9ybVZhbGlkYXRlSG9va3MoZm9ybSkge1xuICAgIGlmICghRk9STV9WQUxJREFURV9IT09LUy5oYXMoZm9ybSkpIHtcbiAgICAgICAgLy8gUGF0Y2ggZm9ybSBtZXRob2RzIHRvIGFkZCBldmVudCBsaXN0ZW5lciBob29rcy4gVGhlc2UgYXJlIG5lZWRlZCB0byByZWFjdFxuICAgICAgICAvLyB0byBmb3JtIGJlaGF2aW9ycyB0aGF0IGRvIG5vdCBkaXNwYXRjaCBldmVudHMsIHN1Y2ggYXMgYSBmb3JtIGFza2luZyBpdHNcbiAgICAgICAgLy8gY29udHJvbHMgdG8gcmVwb3J0IHRoZWlyIHZhbGlkaXR5LlxuICAgICAgICAvL1xuICAgICAgICAvLyBXZSBzaG91bGQgb25seSBwYXRjaCB0aGUgbWV0aG9kcyBvbmNlLCBzaW5jZSBtdWx0aXBsZSBjb250cm9scyBhbmQgb3RoZXJcbiAgICAgICAgLy8gZm9yY2VzIG1heSB3YW50IHRvIHBhdGNoIHRoaXMgbWV0aG9kLiBXZSBjYW5ub3QgcmVsaWFibHkgY2xlYW4gaXQgdXAgaWZcbiAgICAgICAgLy8gdGhlcmUgYXJlIG11bHRpcGxlIHBhdGNoZWQgYW5kIHJlLXBhdGNoZWQgbWV0aG9kcyByZWZlcnJpbmcgaG9sZGluZ1xuICAgICAgICAvLyByZWZlcmVuY2VzIHRvIGVhY2ggb3RoZXIuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEluc3RlYWQsIHdlIG5ldmVyIGNsZWFuIHVwIHRoZSBwYXRjaCBidXQgYWRkIGFuZCBjbGVhbiB1cCBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgLy8gYWRkZWQgdG8gdGhlIGhvb2tzIGFmdGVyIHRoZSBwYXRjaC5cbiAgICAgICAgY29uc3QgaG9va3MgPSBuZXcgRXZlbnRUYXJnZXQoKTtcbiAgICAgICAgRk9STV9WQUxJREFURV9IT09LUy5zZXQoZm9ybSwgaG9va3MpO1xuICAgICAgICAvLyBBZGQgaG9va3MgdG8gc3VwcG9ydCBub3RpZnlpbmcgYmVmb3JlIGFuZCBhZnRlciBhIGZvcm0gaGFzIHJ1biBjb25zdHJhaW50XG4gICAgICAgIC8vIHZhbGlkYXRpb24gb24gaXRzIGNvbnRyb2xzLlxuICAgICAgICAvLyBOb3RlOiBgZm9ybS5zdWJtaXQoKWAgZG9lcyBub3QgcnVuIGNvbnN0cmFpbnQgdmFsaWRhdGlvbiBwZXIgc3BlYy5cbiAgICAgICAgZm9yIChjb25zdCBtZXRob2ROYW1lIG9mIFsncmVwb3J0VmFsaWRpdHknLCAncmVxdWVzdFN1Ym1pdCddKSB7XG4gICAgICAgICAgICBjb25zdCBzdXBlck1ldGhvZCA9IGZvcm1bbWV0aG9kTmFtZV07XG4gICAgICAgICAgICBmb3JtW21ldGhvZE5hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGhvb2tzLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdiZWZvcmUnKSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5hcHBseShzdXBlck1ldGhvZCwgdGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICBob29rcy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnYWZ0ZXInKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIEZPUk1fVkFMSURBVEVfSE9PS1MuZ2V0KGZvcm0pO1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYSBjb250cm9sIGlzIHRoZSBmaXJzdCBpbnZhbGlkIGNvbnRyb2wgaW4gYSBmb3JtLlxuICpcbiAqIEBwYXJhbSBmb3JtIFRoZSBjb250cm9sJ3MgZm9ybS4gV2hlbiBgbnVsbGAsIHRoZSBjb250cm9sIGRvZXNuJ3QgaGF2ZSBhIGZvcm1cbiAqICAgICBhbmQgdGhlIG1ldGhvZCByZXR1cm5zIHRydWUuXG4gKiBAcGFyYW0gY29udHJvbCBUaGUgY29udHJvbCB0byBjaGVjay5cbiAqIEByZXR1cm4gVHJ1ZSBpZiB0aGVyZSBpcyBubyBmb3JtIG9yIGlmIHRoZSBjb250cm9sIGlzIHRoZSBmb3JtJ3MgZmlyc3RcbiAqICAgICBpbnZhbGlkIGNvbnRyb2wuXG4gKi9cbmZ1bmN0aW9uIGlzRmlyc3RJbnZhbGlkQ29udHJvbEluRm9ybShmb3JtLCBjb250cm9sKSB7XG4gICAgaWYgKCFmb3JtKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBsZXQgZmlyc3RJbnZhbGlkQ29udHJvbDtcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZm9ybS5lbGVtZW50cykge1xuICAgICAgICBpZiAoZWxlbWVudC5tYXRjaGVzKCc6aW52YWxpZCcpKSB7XG4gICAgICAgICAgICBmaXJzdEludmFsaWRDb250cm9sID0gZWxlbWVudDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmaXJzdEludmFsaWRDb250cm9sID09PSBjb250cm9sO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b24tcmVwb3J0LXZhbGlkaXR5LmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdG9yLmpzJztcbi8qKlxuICogQSB2YWxpZGF0b3IgdGhhdCBwcm92aWRlcyBjb25zdHJhaW50IHZhbGlkYXRpb24gdGhhdCBlbXVsYXRlc1xuICogYDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIj5gIHZhbGlkYXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBDaGVja2JveFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvciB7XG4gICAgY29tcHV0ZVZhbGlkaXR5KHN0YXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5jaGVja2JveENvbnRyb2wpIHtcbiAgICAgICAgICAgIC8vIExhemlseSBjcmVhdGUgdGhlIHBsYXRmb3JtIGlucHV0XG4gICAgICAgICAgICB0aGlzLmNoZWNrYm94Q29udHJvbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgICAgICAgICB0aGlzLmNoZWNrYm94Q29udHJvbC50eXBlID0gJ2NoZWNrYm94JztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrYm94Q29udHJvbC5jaGVja2VkID0gc3RhdGUuY2hlY2tlZDtcbiAgICAgICAgdGhpcy5jaGVja2JveENvbnRyb2wucmVxdWlyZWQgPSBzdGF0ZS5yZXF1aXJlZDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkaXR5OiB0aGlzLmNoZWNrYm94Q29udHJvbC52YWxpZGl0eSxcbiAgICAgICAgICAgIHZhbGlkYXRpb25NZXNzYWdlOiB0aGlzLmNoZWNrYm94Q29udHJvbC52YWxpZGF0aW9uTWVzc2FnZSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZXF1YWxzKHByZXYsIG5leHQpIHtcbiAgICAgICAgcmV0dXJuIHByZXYuY2hlY2tlZCA9PT0gbmV4dC5jaGVja2VkICYmIHByZXYucmVxdWlyZWQgPT09IG5leHQucmVxdWlyZWQ7XG4gICAgfVxuICAgIGNvcHkoeyBjaGVja2VkLCByZXF1aXJlZCB9KSB7XG4gICAgICAgIHJldHVybiB7IGNoZWNrZWQsIHJlcXVpcmVkIH07XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2hlY2tib3gtdmFsaWRhdG9yLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IGh0bWwsIHJlbmRlciB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tICcuL3ZhbGlkYXRvci5qcyc7XG4vKipcbiAqIEEgdmFsaWRhdG9yIHRoYXQgcHJvdmlkZXMgY29uc3RyYWludCB2YWxpZGF0aW9uIHRoYXQgZW11bGF0ZXMgYDxzZWxlY3Q+YFxuICogdmFsaWRhdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlbGVjdFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvciB7XG4gICAgY29tcHV0ZVZhbGlkaXR5KHN0YXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5zZWxlY3RDb250cm9sKSB7XG4gICAgICAgICAgICAvLyBMYXppbHkgY3JlYXRlIHRoZSBwbGF0Zm9ybSBzZWxlY3RcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0Q29udHJvbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NlbGVjdCcpO1xuICAgICAgICB9XG4gICAgICAgIHJlbmRlcihodG1sIGA8b3B0aW9uIHZhbHVlPSR7c3RhdGUudmFsdWV9Pjwvb3B0aW9uPmAsIHRoaXMuc2VsZWN0Q29udHJvbCk7XG4gICAgICAgIHRoaXMuc2VsZWN0Q29udHJvbC52YWx1ZSA9IHN0YXRlLnZhbHVlO1xuICAgICAgICB0aGlzLnNlbGVjdENvbnRyb2wucmVxdWlyZWQgPSBzdGF0ZS5yZXF1aXJlZDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkaXR5OiB0aGlzLnNlbGVjdENvbnRyb2wudmFsaWRpdHksXG4gICAgICAgICAgICB2YWxpZGF0aW9uTWVzc2FnZTogdGhpcy5zZWxlY3RDb250cm9sLnZhbGlkYXRpb25NZXNzYWdlLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBlcXVhbHMocHJldiwgbmV4dCkge1xuICAgICAgICByZXR1cm4gcHJldi52YWx1ZSA9PT0gbmV4dC52YWx1ZSAmJiBwcmV2LnJlcXVpcmVkID09PSBuZXh0LnJlcXVpcmVkO1xuICAgIH1cbiAgICBjb3B5KHsgdmFsdWUsIHJlcXVpcmVkIH0pIHtcbiAgICAgICAgcmV0dXJuIHsgdmFsdWUsIHJlcXVpcmVkIH07XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VsZWN0LXZhbGlkYXRvci5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBWYWxpZGF0b3IgfSBmcm9tICcuL3ZhbGlkYXRvci5qcyc7XG4vKipcbiAqIEEgdmFsaWRhdG9yIHRoYXQgcHJvdmlkZXMgY29uc3RyYWludCB2YWxpZGF0aW9uIHRoYXQgZW11bGF0ZXMgYDxpbnB1dD5gIGFuZFxuICogYDx0ZXh0YXJlYT5gIHZhbGlkYXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0RmllbGRWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3Ige1xuICAgIGNvbXB1dGVWYWxpZGl0eSh7IHN0YXRlLCByZW5kZXJlZENvbnRyb2wgfSkge1xuICAgICAgICBsZXQgaW5wdXRPclRleHRBcmVhID0gcmVuZGVyZWRDb250cm9sO1xuICAgICAgICBpZiAoaXNJbnB1dFN0YXRlKHN0YXRlKSAmJiAhaW5wdXRPclRleHRBcmVhKSB7XG4gICAgICAgICAgICAvLyBHZXQgY2FjaGVkIDxpbnB1dD4gb3IgY3JlYXRlIGl0LlxuICAgICAgICAgICAgaW5wdXRPclRleHRBcmVhID0gdGhpcy5pbnB1dENvbnRyb2wgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgIC8vIENhY2hlIHRoZSA8aW5wdXQ+IHRvIHJlLXVzZSBpdCBuZXh0IHRpbWUuXG4gICAgICAgICAgICB0aGlzLmlucHV0Q29udHJvbCA9IGlucHV0T3JUZXh0QXJlYTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghaW5wdXRPclRleHRBcmVhKSB7XG4gICAgICAgICAgICAvLyBHZXQgY2FjaGVkIDx0ZXh0YXJlYT4gb3IgY3JlYXRlIGl0LlxuICAgICAgICAgICAgaW5wdXRPclRleHRBcmVhID1cbiAgICAgICAgICAgICAgICB0aGlzLnRleHRBcmVhQ29udHJvbCB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xuICAgICAgICAgICAgLy8gQ2FjaGUgdGhlIDx0ZXh0YXJlYT4gdG8gcmUtdXNlIGl0IG5leHQgdGltZS5cbiAgICAgICAgICAgIHRoaXMudGV4dEFyZWFDb250cm9sID0gaW5wdXRPclRleHRBcmVhO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNldCB0aGlzIHZhcmlhYmxlIHNvIHdlIGNhbiBjaGVjayBpdCBmb3IgaW5wdXQtc3BlY2lmaWMgcHJvcGVydGllcy5cbiAgICAgICAgY29uc3QgaW5wdXQgPSBpc0lucHV0U3RhdGUoc3RhdGUpXG4gICAgICAgICAgICA/IGlucHV0T3JUZXh0QXJlYVxuICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAvLyBTZXQgaW5wdXQncyBcInR5cGVcIiBmaXJzdCwgc2luY2UgdGhpcyBjYW4gY2hhbmdlIHRoZSBvdGhlciBwcm9wZXJ0aWVzXG4gICAgICAgIGlmIChpbnB1dCkge1xuICAgICAgICAgICAgaW5wdXQudHlwZSA9IHN0YXRlLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0T3JUZXh0QXJlYS52YWx1ZSAhPT0gc3RhdGUudmFsdWUpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgcHJvZ3JhbW1hdGljYWxseSBzZXQgdGhlIHZhbHVlIGlmIHRoZXJlJ3MgYSBkaWZmZXJlbmNlLiBXaGVuIHVzaW5nXG4gICAgICAgICAgICAvLyB0aGUgcmVuZGVyZWQgY29udHJvbCwgdGhlIHZhbHVlIHdpbGwgYWx3YXlzIGJlIHVwIHRvIGRhdGUuIFNldHRpbmcgdGhlXG4gICAgICAgICAgICAvLyBwcm9wZXJ0eSAoZXZlbiBpZiBpdCdzIHRoZSBzYW1lIHN0cmluZykgd2lsbCByZXNldCB0aGUgaW50ZXJuYWwgPGlucHV0PlxuICAgICAgICAgICAgLy8gZGlydHkgZmxhZywgbWFraW5nIG1pbmxlbmd0aCBhbmQgbWF4bGVuZ3RoIHZhbGlkYXRpb24gcmVzZXQuXG4gICAgICAgICAgICBpbnB1dE9yVGV4dEFyZWEudmFsdWUgPSBzdGF0ZS52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dE9yVGV4dEFyZWEucmVxdWlyZWQgPSBzdGF0ZS5yZXF1aXJlZDtcbiAgICAgICAgLy8gVGhlIGZvbGxvd2luZyBJRExBdHRyaWJ1dGUgcHJvcGVydGllcyB3aWxsIGFsd2F5cyBoeWRyYXRlIGFuIGF0dHJpYnV0ZSxcbiAgICAgICAgLy8gZXZlbiBpZiBzZXQgdG8gYSB0aGUgZGVmYXVsdCB2YWx1ZSAoJycgb3IgLTEpLiBUaGUgcHJlc2VuY2Ugb2YgdGhlXG4gICAgICAgIC8vIGF0dHJpYnV0ZSB0cmlnZ2VycyBjb25zdHJhaW50IHZhbGlkYXRpb24sIHNvIHdlIG11c3QgcmVtb3ZlIHRoZSBhdHRyaWJ1dGVcbiAgICAgICAgLy8gd2hlbiBlbXB0eS5cbiAgICAgICAgaWYgKGlucHV0KSB7XG4gICAgICAgICAgICBjb25zdCBpbnB1dFN0YXRlID0gc3RhdGU7XG4gICAgICAgICAgICBpZiAoaW5wdXRTdGF0ZS5wYXR0ZXJuKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQucGF0dGVybiA9IGlucHV0U3RhdGUucGF0dGVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlucHV0LnJlbW92ZUF0dHJpYnV0ZSgncGF0dGVybicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlucHV0U3RhdGUubWluKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQubWluID0gaW5wdXRTdGF0ZS5taW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5yZW1vdmVBdHRyaWJ1dGUoJ21pbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlucHV0U3RhdGUubWF4KSB7XG4gICAgICAgICAgICAgICAgaW5wdXQubWF4ID0gaW5wdXRTdGF0ZS5tYXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5yZW1vdmVBdHRyaWJ1dGUoJ21heCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlucHV0U3RhdGUuc3RlcCkge1xuICAgICAgICAgICAgICAgIGlucHV0LnN0ZXAgPSBpbnB1dFN0YXRlLnN0ZXA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5yZW1vdmVBdHRyaWJ1dGUoJ3N0ZXAnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBVc2UgLTEgdG8gcmVwcmVzZW50IG5vIG1pbmxlbmd0aCBhbmQgbWF4bGVuZ3RoLCB3aGljaCBpcyB3aGF0IHRoZVxuICAgICAgICAvLyBwbGF0Zm9ybSBpbnB1dCByZXR1cm5zLiBIb3dldmVyLCBpdCB3aWxsIHRocm93IGFuIGVycm9yIGlmIHlvdSB0cnkgdG9cbiAgICAgICAgLy8gbWFudWFsbHkgc2V0IGl0IHRvIC0xLlxuICAgICAgICAvL1xuICAgICAgICAvLyBXaGlsZSB0aGUgdHlwZSBpcyBgbnVtYmVyYCwgaXQgbWF5IGFjdHVhbGx5IGJlIGBudWxsYCBhdCBydW50aW1lLlxuICAgICAgICAvLyBgbnVsbCA+IC0xYCBpcyB0cnVlIHNpbmNlIGBudWxsYCBjb2VyY2VzIHRvIGAwYCwgc28gd2UgZGVmYXVsdCBudWxsIGFuZFxuICAgICAgICAvLyB1bmRlZmluZWQgdG8gLTEuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFdlIHNldCBhdHRyaWJ1dGVzIGluc3RlYWQgb2YgcHJvcGVydGllcyBzaW5jZSBzZXR0aW5nIGEgcHJvcGVydHkgbWF5XG4gICAgICAgIC8vIHRocm93IGFuIG91dCBvZiBib3VuZHMgZXJyb3IgaW4gcmVsYXRpb24gdG8gdGhlIG90aGVyIHByb3BlcnR5LlxuICAgICAgICAvLyBBdHRyaWJ1dGVzIHdpbGwgbm90IHRocm93IGVycm9ycyB3aGlsZSB0aGUgc3RhdGUgaXMgdXBkYXRpbmcuXG4gICAgICAgIGlmICgoc3RhdGUubWluTGVuZ3RoID8/IC0xKSA+IC0xKSB7XG4gICAgICAgICAgICBpbnB1dE9yVGV4dEFyZWEuc2V0QXR0cmlidXRlKCdtaW5sZW5ndGgnLCBTdHJpbmcoc3RhdGUubWluTGVuZ3RoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbnB1dE9yVGV4dEFyZWEucmVtb3ZlQXR0cmlidXRlKCdtaW5sZW5ndGgnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKHN0YXRlLm1heExlbmd0aCA/PyAtMSkgPiAtMSkge1xuICAgICAgICAgICAgaW5wdXRPclRleHRBcmVhLnNldEF0dHJpYnV0ZSgnbWF4bGVuZ3RoJywgU3RyaW5nKHN0YXRlLm1heExlbmd0aCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5wdXRPclRleHRBcmVhLnJlbW92ZUF0dHJpYnV0ZSgnbWF4bGVuZ3RoJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbGlkaXR5OiBpbnB1dE9yVGV4dEFyZWEudmFsaWRpdHksXG4gICAgICAgICAgICB2YWxpZGF0aW9uTWVzc2FnZTogaW5wdXRPclRleHRBcmVhLnZhbGlkYXRpb25NZXNzYWdlLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBlcXVhbHMoeyBzdGF0ZTogcHJldiB9LCB7IHN0YXRlOiBuZXh0IH0pIHtcbiAgICAgICAgLy8gQ2hlY2sgc2hhcmVkIGlucHV0IGFuZCB0ZXh0YXJlYSBwcm9wZXJ0aWVzXG4gICAgICAgIGNvbnN0IGlucHV0T3JUZXh0QXJlYUVxdWFsID0gcHJldi50eXBlID09PSBuZXh0LnR5cGUgJiZcbiAgICAgICAgICAgIHByZXYudmFsdWUgPT09IG5leHQudmFsdWUgJiZcbiAgICAgICAgICAgIHByZXYucmVxdWlyZWQgPT09IG5leHQucmVxdWlyZWQgJiZcbiAgICAgICAgICAgIHByZXYubWluTGVuZ3RoID09PSBuZXh0Lm1pbkxlbmd0aCAmJlxuICAgICAgICAgICAgcHJldi5tYXhMZW5ndGggPT09IG5leHQubWF4TGVuZ3RoO1xuICAgICAgICBpZiAoIWlzSW5wdXRTdGF0ZShwcmV2KSB8fCAhaXNJbnB1dFN0YXRlKG5leHQpKSB7XG4gICAgICAgICAgICAvLyBCb3RoIGFyZSB0ZXh0YXJlYXMsIGFsbCByZWxldmFudCBwcm9wZXJ0aWVzIGFyZSBlcXVhbC5cbiAgICAgICAgICAgIHJldHVybiBpbnB1dE9yVGV4dEFyZWFFcXVhbDtcbiAgICAgICAgfVxuICAgICAgICAvLyBDaGVjayBhZGRpdGlvbmFsIGlucHV0LXNwZWNpZmljIHByb3BlcnRpZXMuXG4gICAgICAgIHJldHVybiAoaW5wdXRPclRleHRBcmVhRXF1YWwgJiZcbiAgICAgICAgICAgIHByZXYucGF0dGVybiA9PT0gbmV4dC5wYXR0ZXJuICYmXG4gICAgICAgICAgICBwcmV2Lm1pbiA9PT0gbmV4dC5taW4gJiZcbiAgICAgICAgICAgIHByZXYubWF4ID09PSBuZXh0Lm1heCAmJlxuICAgICAgICAgICAgcHJldi5zdGVwID09PSBuZXh0LnN0ZXApO1xuICAgIH1cbiAgICBjb3B5KHsgc3RhdGUgfSkge1xuICAgICAgICAvLyBEb24ndCBob2xkIGEgcmVmZXJlbmNlIHRvIHRoZSByZW5kZXJlZCBjb250cm9sIHdoZW4gY29weWluZyBzaW5jZSB3ZVxuICAgICAgICAvLyBkb24ndCB1c2UgaXQgd2hlbiBjaGVja2luZyBpZiB0aGUgc3RhdGUgY2hhbmdlZC5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXRlOiBpc0lucHV0U3RhdGUoc3RhdGUpXG4gICAgICAgICAgICAgICAgPyB0aGlzLmNvcHlJbnB1dChzdGF0ZSlcbiAgICAgICAgICAgICAgICA6IHRoaXMuY29weVRleHRBcmVhKHN0YXRlKSxcbiAgICAgICAgICAgIHJlbmRlcmVkQ29udHJvbDogbnVsbCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY29weUlucHV0KHN0YXRlKSB7XG4gICAgICAgIGNvbnN0IHsgdHlwZSwgcGF0dGVybiwgbWluLCBtYXgsIHN0ZXAgfSA9IHN0YXRlO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4udGhpcy5jb3B5U2hhcmVkU3RhdGUoc3RhdGUpLFxuICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgIHBhdHRlcm4sXG4gICAgICAgICAgICBtaW4sXG4gICAgICAgICAgICBtYXgsXG4gICAgICAgICAgICBzdGVwLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjb3B5VGV4dEFyZWEoc3RhdGUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLnRoaXMuY29weVNoYXJlZFN0YXRlKHN0YXRlKSxcbiAgICAgICAgICAgIHR5cGU6IHN0YXRlLnR5cGUsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGNvcHlTaGFyZWRTdGF0ZSh7IHZhbHVlLCByZXF1aXJlZCwgbWluTGVuZ3RoLCBtYXhMZW5ndGgsIH0pIHtcbiAgICAgICAgcmV0dXJuIHsgdmFsdWUsIHJlcXVpcmVkLCBtaW5MZW5ndGgsIG1heExlbmd0aCB9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIGlzSW5wdXRTdGF0ZShzdGF0ZSkge1xuICAgIHJldHVybiBzdGF0ZS50eXBlICE9PSAndGV4dGFyZWEnO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGV4dC1maWVsZC12YWxpZGF0b3IuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLyoqXG4gKiBBIGNsYXNzIHRoYXQgY29tcHV0ZXMgYW5kIGNhY2hlcyBgVmFsaWRpdHlTdGF0ZUZsYWdzYCBmb3IgYSBjb21wb25lbnQgd2l0aFxuICogYSBnaXZlbiBgU3RhdGVgIGludGVyZmFjZS5cbiAqXG4gKiBDYWNoZWQgcGVyZm9ybWFuY2UgYmVmb3JlIGNvbXB1dGluZyB2YWxpZGl0eSBpcyBpbXBvcnRhbnQgc2luY2UgY29uc3RyYWludFxuICogdmFsaWRhdGlvbiBtdXN0IGJlIGNoZWNrZWQgZnJlcXVlbnRseSBhbmQgc3luY2hyb25vdXNseSB3aGVuIHByb3BlcnRpZXNcbiAqIGNoYW5nZS5cbiAqXG4gKiBAdGVtcGxhdGUgU3RhdGUgVGhlIGV4cGVjdGVkIGludGVyZmFjZSBvZiBwcm9wZXJ0aWVzIHJlbGV2YW50IHRvIGNvbnN0cmFpbnRcbiAqICAgICB2YWxpZGF0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdG9yIHtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHZhbGlkYXRvci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBnZXRDdXJyZW50U3RhdGUgQSBjYWxsYmFjayB0aGF0IHJldHVybnMgdGhlIGN1cnJlbnQgc3RhdGUgb2ZcbiAgICAgKiAgICAgY29uc3RyYWludCB2YWxpZGF0aW9uLXJlbGF0ZWQgcHJvcGVydGllcy5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihnZXRDdXJyZW50U3RhdGUpIHtcbiAgICAgICAgdGhpcy5nZXRDdXJyZW50U3RhdGUgPSBnZXRDdXJyZW50U3RhdGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY3VycmVudCB2YWxpZGl0eSBzdGF0ZSBhbmQgbWVzc2FnZS4gVGhpcyBpcyBjYWNoZWQgYW5kIHJldHVybnMgaWZcbiAgICAgICAgICogY29uc3RyYWludCB2YWxpZGF0aW9uIHN0YXRlIGRvZXMgbm90IGNoYW5nZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY3VycmVudFZhbGlkaXR5ID0ge1xuICAgICAgICAgICAgdmFsaWRpdHk6IHt9LFxuICAgICAgICAgICAgdmFsaWRhdGlvbk1lc3NhZ2U6ICcnLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGBWYWxpZGl0eVN0YXRlRmxhZ3NgIGFuZCB2YWxpZGF0aW9uIG1lc3NhZ2UgZm9yIHRoZVxuICAgICAqIHZhbGlkYXRvci5cbiAgICAgKlxuICAgICAqIElmIHRoZSBjb25zdHJhaW50IHZhbGlkYXRpb24gc3RhdGUgaGFzIG5vdCBjaGFuZ2VkLCB0aGlzIHdpbGwgcmV0dXJuIGFcbiAgICAgKiBjYWNoZWQgcmVzdWx0LiBUaGlzIGlzIGltcG9ydGFudCBzaW5jZSBgZ2V0VmFsaWRpdHkoKWAgY2FuIGJlIGNhbGxlZFxuICAgICAqIGZyZXF1ZW50bHkgaW4gcmVzcG9uc2UgdG8gc3luY2hyb25vdXMgcHJvcGVydHkgY2hhbmdlcy5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsaWRpdHkgYW5kIHZhbGlkYXRpb24gbWVzc2FnZS5cbiAgICAgKi9cbiAgICBnZXRWYWxpZGl0eSgpIHtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLmdldEN1cnJlbnRTdGF0ZSgpO1xuICAgICAgICBjb25zdCBoYXNTdGF0ZUNoYW5nZWQgPSAhdGhpcy5wcmV2U3RhdGUgfHwgIXRoaXMuZXF1YWxzKHRoaXMucHJldlN0YXRlLCBzdGF0ZSk7XG4gICAgICAgIGlmICghaGFzU3RhdGVDaGFuZ2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50VmFsaWRpdHk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyB2YWxpZGl0eSwgdmFsaWRhdGlvbk1lc3NhZ2UgfSA9IHRoaXMuY29tcHV0ZVZhbGlkaXR5KHN0YXRlKTtcbiAgICAgICAgdGhpcy5wcmV2U3RhdGUgPSB0aGlzLmNvcHkoc3RhdGUpO1xuICAgICAgICB0aGlzLmN1cnJlbnRWYWxpZGl0eSA9IHtcbiAgICAgICAgICAgIHZhbGlkYXRpb25NZXNzYWdlLFxuICAgICAgICAgICAgdmFsaWRpdHk6IHtcbiAgICAgICAgICAgICAgICAvLyBDaGFuZ2UgYW55IGBWYWxpZGl0eVN0YXRlYCBpbnN0YW5jZXMgaW50byBgVmFsaWRpdHlTdGF0ZUZsYWdzYCBzaW5jZVxuICAgICAgICAgICAgICAgIC8vIGBWYWxpZGl0eVN0YXRlYCBjYW5ub3QgYmUgZWFzaWx5IGB7Li4uc3ByZWFkfWAuXG4gICAgICAgICAgICAgICAgYmFkSW5wdXQ6IHZhbGlkaXR5LmJhZElucHV0LFxuICAgICAgICAgICAgICAgIGN1c3RvbUVycm9yOiB2YWxpZGl0eS5jdXN0b21FcnJvcixcbiAgICAgICAgICAgICAgICBwYXR0ZXJuTWlzbWF0Y2g6IHZhbGlkaXR5LnBhdHRlcm5NaXNtYXRjaCxcbiAgICAgICAgICAgICAgICByYW5nZU92ZXJmbG93OiB2YWxpZGl0eS5yYW5nZU92ZXJmbG93LFxuICAgICAgICAgICAgICAgIHJhbmdlVW5kZXJmbG93OiB2YWxpZGl0eS5yYW5nZVVuZGVyZmxvdyxcbiAgICAgICAgICAgICAgICBzdGVwTWlzbWF0Y2g6IHZhbGlkaXR5LnN0ZXBNaXNtYXRjaCxcbiAgICAgICAgICAgICAgICB0b29Mb25nOiB2YWxpZGl0eS50b29Mb25nLFxuICAgICAgICAgICAgICAgIHRvb1Nob3J0OiB2YWxpZGl0eS50b29TaG9ydCxcbiAgICAgICAgICAgICAgICB0eXBlTWlzbWF0Y2g6IHZhbGlkaXR5LnR5cGVNaXNtYXRjaCxcbiAgICAgICAgICAgICAgICB2YWx1ZU1pc3Npbmc6IHZhbGlkaXR5LnZhbHVlTWlzc2luZyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRWYWxpZGl0eTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD12YWxpZGF0b3IuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLy8gR2VuZXJhdGVkIHN0eWxlc2hlZXQgZm9yIC4vbGFicy9pdGVtL2ludGVybmFsL2l0ZW0tc3R5bGVzLmNzcy5cbmltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5leHBvcnQgY29uc3Qgc3R5bGVzID0gY3NzIGA6aG9zdHtjb2xvcjp2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCk7Zm9udC1mYW1pbHk6dmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLWZvbnQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS1wbGFpbiwgUm9ib3RvKSk7Zm9udC1zaXplOnZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1zaXplLCAxcmVtKTtmb250LXdlaWdodDp2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2Utd2VpZ2h0LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2Utd2VpZ2h0LXJlZ3VsYXIsIDQwMCkpO2xpbmUtaGVpZ2h0OnZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1saW5lLWhlaWdodCwgMS41cmVtKTthbGlnbi1pdGVtczpjZW50ZXI7Ym94LXNpemluZzpib3JkZXItYm94O2Rpc3BsYXk6ZmxleDtnYXA6MTZweDttaW4taGVpZ2h0OjU2cHg7b3ZlcmZsb3c6aGlkZGVuO3BhZGRpbmc6MTJweCAxNnB4O3Bvc2l0aW9uOnJlbGF0aXZlO3RleHQtb3ZlcmZsb3c6ZWxsaXBzaXN9Omhvc3QoW211bHRpbGluZV0pe21pbi1oZWlnaHQ6NzJweH1bbmFtZT1vdmVybGluZV17Y29sb3I6dmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0Zik7Zm9udC1mYW1pbHk6dmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1sYWJlbC1zbWFsbC1mb250LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2UtcGxhaW4sIFJvYm90bykpO2ZvbnQtc2l6ZTp2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWxhYmVsLXNtYWxsLXNpemUsIDAuNjg3NXJlbSk7Zm9udC13ZWlnaHQ6dmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1sYWJlbC1zbWFsbC13ZWlnaHQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS13ZWlnaHQtbWVkaXVtLCA1MDApKTtsaW5lLWhlaWdodDp2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWxhYmVsLXNtYWxsLWxpbmUtaGVpZ2h0LCAxcmVtKX1bbmFtZT1zdXBwb3J0aW5nLXRleHRde2NvbG9yOnZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpO2ZvbnQtZmFtaWx5OnZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1tZWRpdW0tZm9udCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXBsYWluLCBSb2JvdG8pKTtmb250LXNpemU6dmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LW1lZGl1bS1zaXplLCAwLjg3NXJlbSk7Zm9udC13ZWlnaHQ6dmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LW1lZGl1bS13ZWlnaHQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS13ZWlnaHQtcmVndWxhciwgNDAwKSk7bGluZS1oZWlnaHQ6dmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LW1lZGl1bS1saW5lLWhlaWdodCwgMS4yNXJlbSl9W25hbWU9dHJhaWxpbmctc3VwcG9ydGluZy10ZXh0XXtjb2xvcjp2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKTtmb250LWZhbWlseTp2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWxhYmVsLXNtYWxsLWZvbnQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS1wbGFpbiwgUm9ib3RvKSk7Zm9udC1zaXplOnZhcigtLW1kLXN5cy10eXBlc2NhbGUtbGFiZWwtc21hbGwtc2l6ZSwgMC42ODc1cmVtKTtmb250LXdlaWdodDp2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWxhYmVsLXNtYWxsLXdlaWdodCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXdlaWdodC1tZWRpdW0sIDUwMCkpO2xpbmUtaGVpZ2h0OnZhcigtLW1kLXN5cy10eXBlc2NhbGUtbGFiZWwtc21hbGwtbGluZS1oZWlnaHQsIDFyZW0pfVtuYW1lPWNvbnRhaW5lcl06OnNsb3R0ZWQoKil7aW5zZXQ6MDtwb3NpdGlvbjphYnNvbHV0ZX0uZGVmYXVsdC1zbG90e2Rpc3BsYXk6aW5saW5lfS5kZWZhdWx0LXNsb3QsLnRleHQgOjpzbG90dGVkKCope292ZXJmbG93OmhpZGRlbjt0ZXh0LW92ZXJmbG93OmVsbGlwc2lzfS50ZXh0e2Rpc3BsYXk6ZmxleDtmbGV4OjE7ZmxleC1kaXJlY3Rpb246Y29sdW1uO292ZXJmbG93OmhpZGRlbn1cbmA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pdGVtLXN0eWxlcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBodG1sLCBMaXRFbGVtZW50IH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IHByb3BlcnR5LCBxdWVyeUFsbCB9IGZyb20gJ2xpdC9kZWNvcmF0b3JzLmpzJztcbi8qKlxuICogQW4gaXRlbSBsYXlvdXQgY29tcG9uZW50LlxuICovXG5leHBvcnQgY2xhc3MgSXRlbSBleHRlbmRzIExpdEVsZW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogT25seSBuZWVkZWQgZm9yIFNTUi5cbiAgICAgICAgICpcbiAgICAgICAgICogQWRkIHRoaXMgYXR0cmlidXRlIHdoZW4gYW4gaXRlbSBoYXMgdHdvIGxpbmVzIHRvIGF2b2lkIGEgRmxhc2ggT2YgVW5zdHlsZWRcbiAgICAgICAgICogQ29udGVudC4gVGhpcyBhdHRyaWJ1dGUgaXMgbm90IG5lZWRlZCBmb3Igc2luZ2xlIGxpbmUgaXRlbXMgb3IgaXRlbXMgd2l0aFxuICAgICAgICAgKiB0aHJlZSBvciBtb3JlIGxpbmVzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5tdWx0aWxpbmUgPSBmYWxzZTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8c2xvdCBuYW1lPVwiY29udGFpbmVyXCI+PC9zbG90PlxuICAgICAgPHNsb3QgY2xhc3M9XCJub24tdGV4dFwiIG5hbWU9XCJzdGFydFwiPjwvc2xvdD5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0XCI+XG4gICAgICAgIDxzbG90IG5hbWU9XCJvdmVybGluZVwiIEBzbG90Y2hhbmdlPSR7dGhpcy5oYW5kbGVUZXh0U2xvdENoYW5nZX0+PC9zbG90PlxuICAgICAgICA8c2xvdFxuICAgICAgICAgIGNsYXNzPVwiZGVmYXVsdC1zbG90XCJcbiAgICAgICAgICBAc2xvdGNoYW5nZT0ke3RoaXMuaGFuZGxlVGV4dFNsb3RDaGFuZ2V9Pjwvc2xvdD5cbiAgICAgICAgPHNsb3QgbmFtZT1cImhlYWRsaW5lXCIgQHNsb3RjaGFuZ2U9JHt0aGlzLmhhbmRsZVRleHRTbG90Q2hhbmdlfT48L3Nsb3Q+XG4gICAgICAgIDxzbG90XG4gICAgICAgICAgbmFtZT1cInN1cHBvcnRpbmctdGV4dFwiXG4gICAgICAgICAgQHNsb3RjaGFuZ2U9JHt0aGlzLmhhbmRsZVRleHRTbG90Q2hhbmdlfT48L3Nsb3Q+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxzbG90IGNsYXNzPVwibm9uLXRleHRcIiBuYW1lPVwidHJhaWxpbmctc3VwcG9ydGluZy10ZXh0XCI+PC9zbG90PlxuICAgICAgPHNsb3QgY2xhc3M9XCJub24tdGV4dFwiIG5hbWU9XCJlbmRcIj48L3Nsb3Q+XG4gICAgYDtcbiAgICB9XG4gICAgaGFuZGxlVGV4dFNsb3RDaGFuZ2UoKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIHRoZXJlJ3MgbW9yZSB0aGFuIG9uZSB0ZXh0IHNsb3Qgd2l0aCBjb250ZW50LiBJZiBzbywgdGhlIGl0ZW0gaXNcbiAgICAgICAgLy8gbXVsdGlsaW5lLCB3aGljaCBoYXMgYSBkaWZmZXJlbnQgbWluLWhlaWdodCB0aGFuIHNpbmdsZSBsaW5lIGl0ZW1zLlxuICAgICAgICBsZXQgaXNNdWx0aWxpbmUgPSBmYWxzZTtcbiAgICAgICAgbGV0IHNsb3RzV2l0aENvbnRlbnQgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IHNsb3Qgb2YgdGhpcy50ZXh0U2xvdHMpIHtcbiAgICAgICAgICAgIGlmIChzbG90SGFzQ29udGVudChzbG90KSkge1xuICAgICAgICAgICAgICAgIHNsb3RzV2l0aENvbnRlbnQgKz0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzbG90c1dpdGhDb250ZW50ID4gMSkge1xuICAgICAgICAgICAgICAgIGlzTXVsdGlsaW5lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm11bHRpbGluZSA9IGlzTXVsdGlsaW5lO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgcmVmbGVjdDogdHJ1ZSB9KVxuXSwgSXRlbS5wcm90b3R5cGUsIFwibXVsdGlsaW5lXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBxdWVyeUFsbCgnLnRleHQgc2xvdCcpXG5dLCBJdGVtLnByb3RvdHlwZSwgXCJ0ZXh0U2xvdHNcIiwgdm9pZCAwKTtcbmZ1bmN0aW9uIHNsb3RIYXNDb250ZW50KHNsb3QpIHtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygc2xvdC5hc3NpZ25lZE5vZGVzKHsgZmxhdHRlbjogdHJ1ZSB9KSkge1xuICAgICAgICAvLyBBc3N1bWUgdGhlcmUncyBjb250ZW50IGlmIHRoZXJlJ3MgYW4gZWxlbWVudCBzbG90dGVkIGluXG4gICAgICAgIGNvbnN0IGlzRWxlbWVudCA9IG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFO1xuICAgICAgICAvLyBJZiB0aGVyZSdzIG9ubHkgdGV4dCBub2RlcyBmb3IgdGhlIGRlZmF1bHQgc2xvdCwgY2hlY2sgaWYgdGhlcmUnc1xuICAgICAgICAvLyBub24td2hpdGVzcGFjZS5cbiAgICAgICAgY29uc3QgaXNUZXh0V2l0aENvbnRlbnQgPSBub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSAmJiBub2RlLnRleHRDb250ZW50Py5tYXRjaCgvXFxTLyk7XG4gICAgICAgIGlmIChpc0VsZW1lbnQgfHwgaXNUZXh0V2l0aENvbnRlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWl0ZW0uanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuaW1wb3J0IHsgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgY3VzdG9tRWxlbWVudCB9IGZyb20gJ2xpdC9kZWNvcmF0b3JzLmpzJztcbmltcG9ydCB7IEl0ZW0gfSBmcm9tICcuL2ludGVybmFsL2l0ZW0uanMnO1xuaW1wb3J0IHsgc3R5bGVzIH0gZnJvbSAnLi9pbnRlcm5hbC9pdGVtLXN0eWxlcy5qcyc7XG4vKipcbiAqIEFuIGl0ZW0gbGF5b3V0IGNvbXBvbmVudCB0aGF0IGNhbiBiZSB1c2VkIGluc2lkZSBsaXN0IGl0ZW1zIHRvIGdpdmUgdGhlbVxuICogdGhlaXIgY3VzdG9taXphYmxlIHN0cnVjdHVyZS5cbiAqXG4gKiBgPG1kLWl0ZW0+YCBkb2VzIG5vdCBoYXZlIGFueSBmdW5jdGlvbmFsaXR5LCB3aGljaCBtdXN0IGJlIGFkZGVkIGJ5IHRoZVxuICogY29tcG9uZW50IHVzaW5nIGl0LlxuICpcbiAqIEFsbCB0ZXh0IHdpbGwgd3JhcCB1bmxlc3MgYHdoaXRlLXNwYWNlOiBub3dyYXBgIGlzIHNldCBvbiB0aGUgaXRlbSBvciBhbnkgb2ZcbiAqIGl0cyBjaGlsZHJlbi5cbiAqXG4gKiBTbG90cyBhdmFpbGFibGU6XG4gKiAtIGA8ZGVmYXVsdD5gOiBUaGUgaGVhZGxpbmUsIG9yIGN1c3RvbSBjb250ZW50LlxuICogLSBgaGVhZGxpbmVgOiBUaGUgZmlyc3QgbGluZS5cbiAqIC0gYHN1cHBvcnRpbmctdGV4dGA6IFN1cHBvcnRpbmcgdGV4dCBsaW5lcyB1bmRlcm5lYXRoIHRoZSBoZWFkbGluZS5cbiAqIC0gYHRyYWlsaW5nLXN1cHBvcnRpbmctdGV4dGA6IEEgc21hbGwgdGV4dCBzbmlwcGV0IGF0IHRoZSBlbmQgb2YgdGhlIGl0ZW0uXG4gKiAtIGBzdGFydGA6IEFueSBsZWFkaW5nIGNvbnRlbnQsIHN1Y2ggYXMgaWNvbnMsIGF2YXRhcnMsIG9yIGNoZWNrYm94ZXMuXG4gKiAtIGBlbmRgOiBBbnkgdHJhaWxpbmcgY29udGVudCwgc3VjaCBhcyBpY29ucyBhbmQgYnV0dG9ucy5cbiAqIC0gYGNvbnRhaW5lcmA6IEJhY2tncm91bmQgY29udGFpbmVyIGNvbnRlbnQsIGludGVuZGVkIGZvciBhZGRpbmcgYWRkaXRpb25hbFxuICogICAgIHN0eWxlcywgc3VjaCBhcyByaXBwbGVzIG9yIGZvY3VzIHJpbmdzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8bWQtaXRlbT5TaW5nbGUgbGluZTwvbWQtaXRlbT5cbiAqXG4gKiA8bWQtaXRlbT5cbiAqICAgPGRpdiBjbGFzcz1cImN1c3RvbS1jb250ZW50XCI+Li4uPC9kaXY+XG4gKiA8L21kLWl0ZW0+XG4gKlxuICogPCEtLSBDbGFzc2ljIDEgdG8gMysgbGluZSBsaXN0IGl0ZW1zIC0tPlxuICogPG1kLWl0ZW0+XG4gKiAgIDxtZC1pY29uIHNsb3Q9XCJzdGFydFwiPmltYWdlPC9tZC1pY29uPlxuICogICA8ZGl2IHNsb3Q9XCJvdmVybGluZVwiPk92ZXJsaW5lPC9kaXY+XG4gKiAgIDxkaXYgc2xvdD1cImhlYWRsaW5lXCI+SGVhZGxpbmU8L2Rpdj5cbiAqICAgPGRpdj1cInN1cHBvcnRpbmctdGV4dFwiPlN1cHBvcnRpbmcgdGV4dDwvZGl2PlxuICogICA8ZGl2PVwidHJhaWxpbmctc3VwcG9ydGluZy10ZXh0XCI+VHJhaWxpbmc8L2Rpdj5cbiAqICAgPG1kLWljb24gc2xvdD1cImVuZFwiPmltYWdlPC9tZC1pY29uPlxuICogPC9tZC1pdGVtPlxuICogYGBgXG4gKlxuICogV2hlbiB3cmFwcGluZyBgPG1kLWl0ZW0+YCwgZm9yd2FyZCB0aGUgYXZhaWxhYmxlIHNsb3RzIHRvIHVzZSB0aGUgc2FtZSBzbG90XG4gKiBzdHJ1Y3R1cmUgZm9yIHRoZSB3cmFwcGluZyBjb21wb25lbnQgKHRoaXMgaXMgd2hhdCBgPG1kLWxpc3QtaXRlbT5gIGRvZXMpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8bWQtaXRlbT5cbiAqICAgPHNsb3Q+PC9zbG90PlxuICogICA8c2xvdCBuYW1lPVwib3ZlcmxpbmVcIiBzbG90PVwib3ZlcmxpbmVcIj48L3Nsb3Q+XG4gKiAgIDxzbG90IG5hbWU9XCJoZWFkbGluZVwiIHNsb3Q9XCJoZWFkbGluZVwiPjwvc2xvdD5cbiAqICAgPHNsb3QgbmFtZT1cInN1cHBvcnRpbmctdGV4dFwiIHNsb3Q9XCJzdXBwb3J0aW5nLXRleHRcIj48L3Nsb3Q+XG4gKiAgIDxzbG90IG5hbWU9XCJ0cmFpbGluZy1zdXBwb3J0aW5nLXRleHRcIlxuICogICAgICAgc2xvdD1cInRyYWlsaW5nLXN1cHBvcnRpbmctdGV4dFwiPjwvc2xvdD5cbiAqICAgPHNsb3QgbmFtZT1cInN0YXJ0XCIgc2xvdD1cInN0YXJ0XCI+PC9zbG90PlxuICogICA8c2xvdCBuYW1lPVwiZW5kXCIgc2xvdD1cImVuZFwiPjwvc2xvdD5cbiAqIDwvbWQtaXRlbT5cbiAqIGBgYFxuICpcbiAqIEBmaW5hbFxuICogQHN1cHByZXNzIHt2aXNpYmlsaXR5fVxuICovXG5sZXQgTWRJdGVtID0gY2xhc3MgTWRJdGVtIGV4dGVuZHMgSXRlbSB7XG59O1xuTWRJdGVtLnN0eWxlcyA9IFtzdHlsZXNdO1xuTWRJdGVtID0gX19kZWNvcmF0ZShbXG4gICAgY3VzdG9tRWxlbWVudCgnbWQtaXRlbScpXG5dLCBNZEl0ZW0pO1xuZXhwb3J0IHsgTWRJdGVtIH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pdGVtLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IGFjdGl2YXRlRmlyc3RJdGVtLCBhY3RpdmF0ZUxhc3RJdGVtLCBhY3RpdmF0ZU5leHRJdGVtLCBhY3RpdmF0ZVByZXZpb3VzSXRlbSwgZ2V0QWN0aXZlSXRlbSwgZ2V0Rmlyc3RBY3RpdmF0YWJsZUl0ZW0sIH0gZnJvbSAnLi9saXN0LW5hdmlnYXRpb24taGVscGVycy5qcyc7XG4vLyBUT0RPOiBtb3ZlIHRoaXMgZmlsZSB0byBMaXN0IGFuZCBtYWtlIExpc3QgdXNlIHRoaXNcbi8qKlxuICogRGVmYXVsdCBrZXlzIHRoYXQgdHJpZ2dlciBuYXZpZ2F0aW9uLlxuICovXG4vLyB0c2xpbnQ6ZGlzYWJsZTplbmZvcmNlLW5hbWUtY2FzaW5nIEZvbGxvd2luZyBFbnVtIHN0eWxlXG5leHBvcnQgY29uc3QgTmF2aWdhYmxlS2V5cyA9IHtcbiAgICBBcnJvd0Rvd246ICdBcnJvd0Rvd24nLFxuICAgIEFycm93TGVmdDogJ0Fycm93TGVmdCcsXG4gICAgQXJyb3dVcDogJ0Fycm93VXAnLFxuICAgIEFycm93UmlnaHQ6ICdBcnJvd1JpZ2h0JyxcbiAgICBIb21lOiAnSG9tZScsXG4gICAgRW5kOiAnRW5kJyxcbn07XG4vKipcbiAqIEEgY29udHJvbGxlciB0aGF0IGhhbmRsZXMgbGlzdCBrZXlib2FyZCBuYXZpZ2F0aW9uIGFuZCBpdGVtIG1hbmFnZW1lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBMaXN0Q29udHJvbGxlciB7XG4gICAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIYW5kbGVzIGtleWJvYXJkIG5hdmlnYXRpb24uIFNob3VsZCBiZSBib3VuZCB0byB0aGUgbm9kZSB0aGF0IHdpbGwgYWN0IGFzXG4gICAgICAgICAqIHRoZSBMaXN0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oYW5kbGVLZXlkb3duID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBldmVudC5rZXk7XG4gICAgICAgICAgICBpZiAoZXZlbnQuZGVmYXVsdFByZXZlbnRlZCB8fCAhdGhpcy5pc05hdmlnYWJsZUtleShrZXkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG8gbm90IHVzZSB0aGlzLml0ZW1zIGRpcmVjdGx5IGluIHVwY29taW5nIGNhbGN1bGF0aW9ucyBzbyB3ZSBkb24ndFxuICAgICAgICAgICAgLy8gcmUtcXVlcnkgdGhlIERPTSB1bm5lY2Vzc2FyaWx5XG4gICAgICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXM7XG4gICAgICAgICAgICBpZiAoIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUl0ZW1SZWNvcmQgPSBnZXRBY3RpdmVJdGVtKGl0ZW1zLCB0aGlzLmlzQWN0aXZhdGFibGUpO1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGNvbnN0IGlzUnRsID0gdGhpcy5pc1J0bCgpO1xuICAgICAgICAgICAgY29uc3QgaW5saW5lUHJldmlvdXMgPSBpc1J0bFxuICAgICAgICAgICAgICAgID8gTmF2aWdhYmxlS2V5cy5BcnJvd1JpZ2h0XG4gICAgICAgICAgICAgICAgOiBOYXZpZ2FibGVLZXlzLkFycm93TGVmdDtcbiAgICAgICAgICAgIGNvbnN0IGlubGluZU5leHQgPSBpc1J0bFxuICAgICAgICAgICAgICAgID8gTmF2aWdhYmxlS2V5cy5BcnJvd0xlZnRcbiAgICAgICAgICAgICAgICA6IE5hdmlnYWJsZUtleXMuQXJyb3dSaWdodDtcbiAgICAgICAgICAgIGxldCBuZXh0QWN0aXZlSXRlbSA9IG51bGw7XG4gICAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgICAgIC8vIEFjdGl2YXRlIHRoZSBuZXh0IGl0ZW1cbiAgICAgICAgICAgICAgICBjYXNlIE5hdmlnYWJsZUtleXMuQXJyb3dEb3duOlxuICAgICAgICAgICAgICAgIGNhc2UgaW5saW5lTmV4dDpcbiAgICAgICAgICAgICAgICAgICAgbmV4dEFjdGl2ZUl0ZW0gPSBhY3RpdmF0ZU5leHRJdGVtKGl0ZW1zLCBhY3RpdmVJdGVtUmVjb3JkLCB0aGlzLmlzQWN0aXZhdGFibGUsIHRoaXMud3JhcE5hdmlnYXRpb24oKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIC8vIEFjdGl2YXRlIHRoZSBwcmV2aW91cyBpdGVtXG4gICAgICAgICAgICAgICAgY2FzZSBOYXZpZ2FibGVLZXlzLkFycm93VXA6XG4gICAgICAgICAgICAgICAgY2FzZSBpbmxpbmVQcmV2aW91czpcbiAgICAgICAgICAgICAgICAgICAgbmV4dEFjdGl2ZUl0ZW0gPSBhY3RpdmF0ZVByZXZpb3VzSXRlbShpdGVtcywgYWN0aXZlSXRlbVJlY29yZCwgdGhpcy5pc0FjdGl2YXRhYmxlLCB0aGlzLndyYXBOYXZpZ2F0aW9uKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAvLyBBY3RpdmF0ZSB0aGUgZmlyc3QgaXRlbVxuICAgICAgICAgICAgICAgIGNhc2UgTmF2aWdhYmxlS2V5cy5Ib21lOlxuICAgICAgICAgICAgICAgICAgICBuZXh0QWN0aXZlSXRlbSA9IGFjdGl2YXRlRmlyc3RJdGVtKGl0ZW1zLCB0aGlzLmlzQWN0aXZhdGFibGUpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAvLyBBY3RpdmF0ZSB0aGUgbGFzdCBpdGVtXG4gICAgICAgICAgICAgICAgY2FzZSBOYXZpZ2FibGVLZXlzLkVuZDpcbiAgICAgICAgICAgICAgICAgICAgbmV4dEFjdGl2ZUl0ZW0gPSBhY3RpdmF0ZUxhc3RJdGVtKGl0ZW1zLCB0aGlzLmlzQWN0aXZhdGFibGUpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZXh0QWN0aXZlSXRlbSAmJlxuICAgICAgICAgICAgICAgIGFjdGl2ZUl0ZW1SZWNvcmQgJiZcbiAgICAgICAgICAgICAgICBhY3RpdmVJdGVtUmVjb3JkLml0ZW0gIT09IG5leHRBY3RpdmVJdGVtKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgYSBuZXcgaXRlbSB3YXMgYWN0aXZhdGVkLCByZW1vdmUgdGhlIHRhYmluZGV4IG9mIHRoZSBwcmV2aW91c1xuICAgICAgICAgICAgICAgIC8vIGFjdGl2YXRlZCBpdGVtLlxuICAgICAgICAgICAgICAgIGFjdGl2ZUl0ZW1SZWNvcmQuaXRlbS50YWJJbmRleCA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogTGlzdGVuZXIgdG8gYmUgYm91bmQgdG8gdGhlIGBkZWFjdGl2YXRlLWl0ZW1zYCBpdGVtIGV2ZW50LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbkRlYWN0aXZhdGVJdGVtcyA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5pdGVtcztcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVhY3RpdmF0ZUl0ZW0oaXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBMaXN0ZW5lciB0byBiZSBib3VuZCB0byB0aGUgYHJlcXVlc3QtYWN0aXZhdGlvbmAgaXRlbSBldmVudC4uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uUmVxdWVzdEFjdGl2YXRpb24gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMub25EZWFjdGl2YXRlSXRlbXMoKTtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVJdGVtKHRhcmdldCk7XG4gICAgICAgICAgICB0YXJnZXQuZm9jdXMoKTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIExpc3RlbmVyIHRvIGJlIGJvdW5kIHRvIHRoZSBgc2xvdGNoYW5nZWAgZXZlbnQgZm9yIHRoZSBzbG90IHRoYXQgcmVuZGVyc1xuICAgICAgICAgKiB0aGUgaXRlbXMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uU2xvdGNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5pdGVtcztcbiAgICAgICAgICAgIC8vIFdoZXRoZXIgd2UgaGF2ZSBlbmNvdW50ZXJlZCBhbiBpdGVtIHRoYXQgaGFzIGJlZW4gYWN0aXZhdGVkXG4gICAgICAgICAgICBsZXQgZW5jb3VudGVyZWRBY3RpdmF0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzQWN0aXZhdGVkID0gIWl0ZW0uZGlzYWJsZWQgJiYgaXRlbS50YWJJbmRleCA+IC0xO1xuICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2YXRlZCAmJiAhZW5jb3VudGVyZWRBY3RpdmF0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZW5jb3VudGVyZWRBY3RpdmF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBpdGVtLnRhYkluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIERlYWN0aXZhdGUgdGhlIHJlc3QgaW5jbHVkaW5nIGRpc2FibGVkXG4gICAgICAgICAgICAgICAgaXRlbS50YWJJbmRleCA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGVuY291bnRlcmVkQWN0aXZhdGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZmlyc3RBY3RpdmF0YWJsZUl0ZW0gPSBnZXRGaXJzdEFjdGl2YXRhYmxlSXRlbShpdGVtcywgdGhpcy5pc0FjdGl2YXRhYmxlKTtcbiAgICAgICAgICAgIGlmICghZmlyc3RBY3RpdmF0YWJsZUl0ZW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaXJzdEFjdGl2YXRhYmxlSXRlbS50YWJJbmRleCA9IDA7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHsgaXNJdGVtLCBnZXRQb3NzaWJsZUl0ZW1zLCBpc1J0bCwgZGVhY3RpdmF0ZUl0ZW0sIGFjdGl2YXRlSXRlbSwgaXNOYXZpZ2FibGVLZXksIGlzQWN0aXZhdGFibGUsIHdyYXBOYXZpZ2F0aW9uLCB9ID0gY29uZmlnO1xuICAgICAgICB0aGlzLmlzSXRlbSA9IGlzSXRlbTtcbiAgICAgICAgdGhpcy5nZXRQb3NzaWJsZUl0ZW1zID0gZ2V0UG9zc2libGVJdGVtcztcbiAgICAgICAgdGhpcy5pc1J0bCA9IGlzUnRsO1xuICAgICAgICB0aGlzLmRlYWN0aXZhdGVJdGVtID0gZGVhY3RpdmF0ZUl0ZW07XG4gICAgICAgIHRoaXMuYWN0aXZhdGVJdGVtID0gYWN0aXZhdGVJdGVtO1xuICAgICAgICB0aGlzLmlzTmF2aWdhYmxlS2V5ID0gaXNOYXZpZ2FibGVLZXk7XG4gICAgICAgIHRoaXMuaXNBY3RpdmF0YWJsZSA9IGlzQWN0aXZhdGFibGU7XG4gICAgICAgIHRoaXMud3JhcE5hdmlnYXRpb24gPSB3cmFwTmF2aWdhdGlvbiA/PyAoKCkgPT4gdHJ1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpdGVtcyBiZWluZyBtYW5hZ2VkIGJ5IHRoZSBsaXN0LiBBZGRpdGlvbmFsbHksIGF0dGVtcHRzIHRvIHNlZSBpZiB0aGVcbiAgICAgKiBvYmplY3QgaGFzIGEgc3ViLWl0ZW0gaW4gdGhlIGAuaXRlbWAgcHJvcGVydHkuXG4gICAgICovXG4gICAgZ2V0IGl0ZW1zKCkge1xuICAgICAgICBjb25zdCBtYXliZUl0ZW1zID0gdGhpcy5nZXRQb3NzaWJsZUl0ZW1zKCk7XG4gICAgICAgIGNvbnN0IGl0ZW1zID0gW107XG4gICAgICAgIGZvciAoY29uc3QgaXRlbU9yUGFyZW50IG9mIG1heWJlSXRlbXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzSXRlbSA9IHRoaXMuaXNJdGVtKGl0ZW1PclBhcmVudCk7XG4gICAgICAgICAgICAvLyBpZiB0aGUgaXRlbSBpcyBhIGxpc3QgaXRlbSwgYWRkIGl0IHRvIHRoZSBsaXN0IG9mIGl0ZW1zXG4gICAgICAgICAgICBpZiAoaXNJdGVtKSB7XG4gICAgICAgICAgICAgICAgaXRlbXMucHVzaChpdGVtT3JQYXJlbnQpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gSWYgdGhlIGl0ZW0gZXhwb3NlcyBhbiBgaXRlbWAgcHJvcGVydHkgY2hlY2sgaWYgaXQgaXMgYSBsaXN0IGl0ZW0uXG4gICAgICAgICAgICBjb25zdCBzdWJJdGVtID0gaXRlbU9yUGFyZW50Lml0ZW07XG4gICAgICAgICAgICBpZiAoc3ViSXRlbSAmJiB0aGlzLmlzSXRlbShzdWJJdGVtKSkge1xuICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goc3ViSXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBY3RpdmF0ZXMgdGhlIG5leHQgaXRlbSBpbiB0aGUgbGlzdC4gSWYgYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCwgdGhlIGZpcnN0XG4gICAgICogaXRlbSB3aWxsIGJlIGFjdGl2YXRlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gVGhlIGFjdGl2YXRlZCBsaXN0IGl0ZW0gb3IgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBpdGVtcy5cbiAgICAgKi9cbiAgICBhY3RpdmF0ZU5leHRJdGVtKCkge1xuICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXM7XG4gICAgICAgIGNvbnN0IGFjdGl2ZUl0ZW1SZWNvcmQgPSBnZXRBY3RpdmVJdGVtKGl0ZW1zLCB0aGlzLmlzQWN0aXZhdGFibGUpO1xuICAgICAgICBpZiAoYWN0aXZlSXRlbVJlY29yZCkge1xuICAgICAgICAgICAgYWN0aXZlSXRlbVJlY29yZC5pdGVtLnRhYkluZGV4ID0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjdGl2YXRlTmV4dEl0ZW0oaXRlbXMsIGFjdGl2ZUl0ZW1SZWNvcmQsIHRoaXMuaXNBY3RpdmF0YWJsZSwgdGhpcy53cmFwTmF2aWdhdGlvbigpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWN0aXZhdGVzIHRoZSBwcmV2aW91cyBpdGVtIGluIHRoZSBsaXN0LiBJZiBhdCB0aGUgc3RhcnQgb2YgdGhlIGxpc3QsIHRoZVxuICAgICAqIGxhc3QgaXRlbSB3aWxsIGJlIGFjdGl2YXRlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gVGhlIGFjdGl2YXRlZCBsaXN0IGl0ZW0gb3IgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBpdGVtcy5cbiAgICAgKi9cbiAgICBhY3RpdmF0ZVByZXZpb3VzSXRlbSgpIHtcbiAgICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zO1xuICAgICAgICBjb25zdCBhY3RpdmVJdGVtUmVjb3JkID0gZ2V0QWN0aXZlSXRlbShpdGVtcywgdGhpcy5pc0FjdGl2YXRhYmxlKTtcbiAgICAgICAgaWYgKGFjdGl2ZUl0ZW1SZWNvcmQpIHtcbiAgICAgICAgICAgIGFjdGl2ZUl0ZW1SZWNvcmQuaXRlbS50YWJJbmRleCA9IC0xO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY3RpdmF0ZVByZXZpb3VzSXRlbShpdGVtcywgYWN0aXZlSXRlbVJlY29yZCwgdGhpcy5pc0FjdGl2YXRhYmxlLCB0aGlzLndyYXBOYXZpZ2F0aW9uKCkpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpc3QtY29udHJvbGxlci5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG4vKipcbiAqIEFjdGl2YXRlcyB0aGUgZmlyc3Qgbm9uLWRpc2FibGVkIGl0ZW0gb2YgYSBnaXZlbiBhcnJheSBvZiBpdGVtcy5cbiAqXG4gKiBAcGFyYW0gaXRlbXMge0FycmF5PExpc3RJdGVtPn0gVGhlIGl0ZW1zIGZyb20gd2hpY2ggdG8gYWN0aXZhdGUgdGhlXG4gKiAgICAgZmlyc3QgaXRlbS5cbiAqIEBwYXJhbSBpc0FjdGl2YXRhYmxlIEZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiBhbiBpdGVtIGNhbiBiZSAgYWN0aXZhdGVkLlxuICogICAgIERlZmF1bHRzIHRvIG5vbi1kaXNhYmxlZCBpdGVtcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFjdGl2YXRlRmlyc3RJdGVtKGl0ZW1zLCBpc0FjdGl2YXRhYmxlID0gKGlzSXRlbU5vdERpc2FibGVkKSkge1xuICAgIC8vIE5PVEU6IFRoZXNlIHNlbGVjdG9yIGZ1bmN0aW9ucyBhcmUgc3RhdGljIGFuZCBub3Qgb24gdGhlIGluc3RhbmNlIHN1Y2hcbiAgICAvLyB0aGF0IG11bHRpcGxlIG9wZXJhdGlvbnMgY2FuIGJlIGNoYWluZWQgYW5kIHdlIGRvIG5vdCBoYXZlIHRvIHJlLXF1ZXJ5XG4gICAgLy8gdGhlIERPTVxuICAgIGNvbnN0IGZpcnN0SXRlbSA9IGdldEZpcnN0QWN0aXZhdGFibGVJdGVtKGl0ZW1zLCBpc0FjdGl2YXRhYmxlKTtcbiAgICBpZiAoZmlyc3RJdGVtKSB7XG4gICAgICAgIGZpcnN0SXRlbS50YWJJbmRleCA9IDA7XG4gICAgICAgIGZpcnN0SXRlbS5mb2N1cygpO1xuICAgIH1cbiAgICByZXR1cm4gZmlyc3RJdGVtO1xufVxuLyoqXG4gKiBBY3RpdmF0ZXMgdGhlIGxhc3Qgbm9uLWRpc2FibGVkIGl0ZW0gb2YgYSBnaXZlbiBhcnJheSBvZiBpdGVtcy5cbiAqXG4gKiBAcGFyYW0gaXRlbXMge0FycmF5PExpc3RJdGVtPn0gVGhlIGl0ZW1zIGZyb20gd2hpY2ggdG8gYWN0aXZhdGUgdGhlXG4gKiAgICAgbGFzdCBpdGVtLlxuICogQHBhcmFtIGlzQWN0aXZhdGFibGUgRnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGlmIGFuIGl0ZW0gY2FuIGJlICBhY3RpdmF0ZWQuXG4gKiAgICAgRGVmYXVsdHMgdG8gbm9uLWRpc2FibGVkIGl0ZW1zLlxuICogQG5vY29sbGFwc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFjdGl2YXRlTGFzdEl0ZW0oaXRlbXMsIGlzQWN0aXZhdGFibGUgPSAoaXNJdGVtTm90RGlzYWJsZWQpKSB7XG4gICAgY29uc3QgbGFzdEl0ZW0gPSBnZXRMYXN0QWN0aXZhdGFibGVJdGVtKGl0ZW1zLCBpc0FjdGl2YXRhYmxlKTtcbiAgICBpZiAobGFzdEl0ZW0pIHtcbiAgICAgICAgbGFzdEl0ZW0udGFiSW5kZXggPSAwO1xuICAgICAgICBsYXN0SXRlbS5mb2N1cygpO1xuICAgIH1cbiAgICByZXR1cm4gbGFzdEl0ZW07XG59XG4vKipcbiAqIERlYWN0aXZhdGVzIHRoZSBjdXJyZW50bHkgYWN0aXZlIGl0ZW0gb2YgYSBnaXZlbiBhcnJheSBvZiBpdGVtcy5cbiAqXG4gKiBAcGFyYW0gaXRlbXMge0FycmF5PExpc3RJdGVtPn0gVGhlIGl0ZW1zIGZyb20gd2hpY2ggdG8gZGVhY3RpdmF0ZSB0aGVcbiAqICAgICBhY3RpdmUgaXRlbS5cbiAqIEBwYXJhbSBpc0FjdGl2YXRhYmxlIEZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiBhbiBpdGVtIGNhbiBiZSAgYWN0aXZhdGVkLlxuICogICAgIERlZmF1bHRzIHRvIG5vbi1kaXNhYmxlZCBpdGVtcy5cbiAqIEByZXR1cm4gQSByZWNvcmQgb2YgdGhlIGRlbGVzZWxjdGVkIGFjdGl2YXRlZCBpdGVtIGluY2x1ZGluZyB0aGUgaXRlbSBhbmRcbiAqICAgICB0aGUgaW5kZXggb2YgdGhlIGl0ZW0gb3IgYG51bGxgIGlmIG5vbmUgYXJlIGRlYWN0aXZhdGVkLlxuICogQG5vY29sbGFwc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlYWN0aXZhdGVBY3RpdmVJdGVtKGl0ZW1zLCBpc0FjdGl2YXRhYmxlID0gKGlzSXRlbU5vdERpc2FibGVkKSkge1xuICAgIGNvbnN0IGFjdGl2ZUl0ZW0gPSBnZXRBY3RpdmVJdGVtKGl0ZW1zLCBpc0FjdGl2YXRhYmxlKTtcbiAgICBpZiAoYWN0aXZlSXRlbSkge1xuICAgICAgICBhY3RpdmVJdGVtLml0ZW0udGFiSW5kZXggPSAtMTtcbiAgICB9XG4gICAgcmV0dXJuIGFjdGl2ZUl0ZW07XG59XG4vKipcbiAqIFJldHJpZXZlcyB0aGUgZmlyc3QgYWN0aXZhdGVkIGl0ZW0gb2YgYSBnaXZlbiBhcnJheSBvZiBpdGVtcy5cbiAqXG4gKiBAcGFyYW0gaXRlbXMge0FycmF5PExpc3RJdGVtPn0gVGhlIGl0ZW1zIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSBpc0FjdGl2YXRhYmxlIEZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiBhbiBpdGVtIGNhbiBiZSAgYWN0aXZhdGVkLlxuICogICAgIERlZmF1bHRzIHRvIG5vbi1kaXNhYmxlZCBpdGVtcy5cbiAqIEByZXR1cm4gQSByZWNvcmQgb2YgdGhlIGZpcnN0IGFjdGl2YXRlZCBpdGVtIGluY2x1ZGluZyB0aGUgaXRlbSBhbmQgdGhlXG4gKiAgICAgaW5kZXggb2YgdGhlIGl0ZW0gb3IgYG51bGxgIGlmIG5vbmUgYXJlIGFjdGl2YXRlZC5cbiAqIEBub2NvbGxhcHNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY3RpdmVJdGVtKGl0ZW1zLCBpc0FjdGl2YXRhYmxlID0gKGlzSXRlbU5vdERpc2FibGVkKSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zW2ldO1xuICAgICAgICBpZiAoaXRlbS50YWJJbmRleCA9PT0gMCAmJiBpc0FjdGl2YXRhYmxlKGl0ZW0pKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGZpcnN0IG5vbi1kaXNhYmxlZCBpdGVtIG9mIGEgZ2l2ZW4gYXJyYXkgb2YgaXRlbXMuIFRoaXNcbiAqIHRoZSBmaXJzdCBpdGVtIHRoYXQgaXMgbm90IGRpc2FibGVkLlxuICpcbiAqIEBwYXJhbSBpdGVtcyB7QXJyYXk8TGlzdEl0ZW0+fSBUaGUgaXRlbXMgdG8gc2VhcmNoLlxuICogQHBhcmFtIGlzQWN0aXZhdGFibGUgRnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGlmIGFuIGl0ZW0gY2FuIGJlICBhY3RpdmF0ZWQuXG4gKiAgICAgRGVmYXVsdHMgdG8gbm9uLWRpc2FibGVkIGl0ZW1zLlxuICogQHJldHVybiBUaGUgZmlyc3QgYWN0aXZhdGFibGUgaXRlbSBvciBgbnVsbGAgaWYgbm9uZSBhcmUgYWN0aXZhdGFibGUuXG4gKiBAbm9jb2xsYXBzZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmlyc3RBY3RpdmF0YWJsZUl0ZW0oaXRlbXMsIGlzQWN0aXZhdGFibGUgPSAoaXNJdGVtTm90RGlzYWJsZWQpKSB7XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7XG4gICAgICAgIGlmIChpc0FjdGl2YXRhYmxlKGl0ZW0pKSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbi8qKlxuICogUmV0cmlldmVzIHRoZSBsYXN0IG5vbi1kaXNhYmxlZCBpdGVtIG9mIGEgZ2l2ZW4gYXJyYXkgb2YgaXRlbXMuXG4gKlxuICogQHBhcmFtIGl0ZW1zIHtBcnJheTxMaXN0SXRlbT59IFRoZSBpdGVtcyB0byBzZWFyY2guXG4gKiBAcGFyYW0gaXNBY3RpdmF0YWJsZSBGdW5jdGlvbiB0byBkZXRlcm1pbmUgaWYgYW4gaXRlbSBjYW4gYmUgIGFjdGl2YXRlZC5cbiAqICAgICBEZWZhdWx0cyB0byBub24tZGlzYWJsZWQgaXRlbXMuXG4gKiBAcmV0dXJuIFRoZSBsYXN0IGFjdGl2YXRhYmxlIGl0ZW0gb3IgYG51bGxgIGlmIG5vbmUgYXJlIGFjdGl2YXRhYmxlLlxuICogQG5vY29sbGFwc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExhc3RBY3RpdmF0YWJsZUl0ZW0oaXRlbXMsIGlzQWN0aXZhdGFibGUgPSAoaXNJdGVtTm90RGlzYWJsZWQpKSB7XG4gICAgZm9yIChsZXQgaSA9IGl0ZW1zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1tpXTtcbiAgICAgICAgaWYgKGlzQWN0aXZhdGFibGUoaXRlbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIG5leHQgbm9uLWRpc2FibGVkIGl0ZW0gb2YgYSBnaXZlbiBhcnJheSBvZiBpdGVtcy5cbiAqXG4gKiBAcGFyYW0gaXRlbXMge0FycmF5PExpc3RJdGVtPn0gVGhlIGl0ZW1zIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSBpbmRleCB7e2luZGV4OiBudW1iZXJ9fSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcGFyYW0gaXNBY3RpdmF0YWJsZSBGdW5jdGlvbiB0byBkZXRlcm1pbmUgaWYgYW4gaXRlbSBjYW4gYmUgIGFjdGl2YXRlZC5cbiAqICAgICBEZWZhdWx0cyB0byBub24tZGlzYWJsZWQgaXRlbXMuXG4gKiBAcGFyYW0gd3JhcCBJZiB0cnVlLCB0aGVuIHRoZSBuZXh0IGl0ZW0gYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCBpcyB0aGUgZmlyc3RcbiAqICAgICBpdGVtLiBEZWZhdWx0cyB0byB0cnVlLlxuICogQHJldHVybiBUaGUgbmV4dCBhY3RpdmF0YWJsZSBpdGVtIG9yIGBudWxsYCBpZiBub25lIGFyZSBhY3RpdmF0YWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE5leHRJdGVtKGl0ZW1zLCBpbmRleCwgaXNBY3RpdmF0YWJsZSA9IChpc0l0ZW1Ob3REaXNhYmxlZCksIHdyYXAgPSB0cnVlKSB7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuZXh0SW5kZXggPSAoaSArIGluZGV4KSAlIGl0ZW1zLmxlbmd0aDtcbiAgICAgICAgaWYgKG5leHRJbmRleCA8IGluZGV4ICYmICF3cmFwKSB7XG4gICAgICAgICAgICAvLyBSZXR1cm4gaWYgdGhlIGluZGV4IGxvb3BzIGJhY2sgdG8gdGhlIGJlZ2lubmluZyBhbmQgbm90IHdyYXBwaW5nLlxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zW25leHRJbmRleF07XG4gICAgICAgIGlmIChpc0FjdGl2YXRhYmxlKGl0ZW0pKSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXNbaW5kZXhdID8gaXRlbXNbaW5kZXhdIDogbnVsbDtcbn1cbi8qKlxuICogUmV0cmlldmVzIHRoZSBwcmV2aW91cyBub24tZGlzYWJsZWQgaXRlbSBvZiBhIGdpdmVuIGFycmF5IG9mIGl0ZW1zLlxuICpcbiAqIEBwYXJhbSBpdGVtcyB7QXJyYXk8TGlzdEl0ZW0+fSBUaGUgaXRlbXMgdG8gc2VhcmNoLlxuICogQHBhcmFtIGluZGV4IHt7aW5kZXg6IG51bWJlcn19IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqIEBwYXJhbSBpc0FjdGl2YXRhYmxlIEZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiBhbiBpdGVtIGNhbiBiZSAgYWN0aXZhdGVkLlxuICogICAgIERlZmF1bHRzIHRvIG5vbi1kaXNhYmxlZCBpdGVtcy5cbiAqIEBwYXJhbSB3cmFwIElmIHRydWUsIHRoZW4gdGhlIHByZXZpb3VzIGl0ZW0gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdCBpc1xuICogICAgIHRoZSBsYXN0IGl0ZW0uIERlZmF1bHRzIHRvIHRydWUuXG4gKiBAcmV0dXJuIFRoZSBwcmV2aW91cyBhY3RpdmF0YWJsZSBpdGVtIG9yIGBudWxsYCBpZiBub25lIGFyZSBhY3RpdmF0YWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFByZXZJdGVtKGl0ZW1zLCBpbmRleCwgaXNBY3RpdmF0YWJsZSA9IChpc0l0ZW1Ob3REaXNhYmxlZCksIHdyYXAgPSB0cnVlKSB7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBwcmV2SW5kZXggPSAoaW5kZXggLSBpICsgaXRlbXMubGVuZ3RoKSAlIGl0ZW1zLmxlbmd0aDtcbiAgICAgICAgaWYgKHByZXZJbmRleCA+IGluZGV4ICYmICF3cmFwKSB7XG4gICAgICAgICAgICAvLyBSZXR1cm4gaWYgdGhlIGluZGV4IGxvb3BzIGJhY2sgdG8gdGhlIGVuZCBhbmQgbm90IHdyYXBwaW5nLlxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zW3ByZXZJbmRleF07XG4gICAgICAgIGlmIChpc0FjdGl2YXRhYmxlKGl0ZW0pKSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXNbaW5kZXhdID8gaXRlbXNbaW5kZXhdIDogbnVsbDtcbn1cbi8qKlxuICogQWN0aXZhdGVzIHRoZSBuZXh0IGl0ZW0gYW5kIGZvY3VzZXMgaXQuIElmIG5vdGhpbmcgaXMgY3VycmVudGx5IGFjdGl2YXRlZCxcbiAqIGFjdGl2YXRlcyB0aGUgZmlyc3QgaXRlbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFjdGl2YXRlTmV4dEl0ZW0oaXRlbXMsIGFjdGl2ZUl0ZW1SZWNvcmQsIGlzQWN0aXZhdGFibGUgPSAoaXNJdGVtTm90RGlzYWJsZWQpLCB3cmFwID0gdHJ1ZSkge1xuICAgIGlmIChhY3RpdmVJdGVtUmVjb3JkKSB7XG4gICAgICAgIGNvbnN0IG5leHQgPSBnZXROZXh0SXRlbShpdGVtcywgYWN0aXZlSXRlbVJlY29yZC5pbmRleCwgaXNBY3RpdmF0YWJsZSwgd3JhcCk7XG4gICAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgICAgICBuZXh0LnRhYkluZGV4ID0gMDtcbiAgICAgICAgICAgIG5leHQuZm9jdXMoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV4dDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBhY3RpdmF0ZUZpcnN0SXRlbShpdGVtcywgaXNBY3RpdmF0YWJsZSk7XG4gICAgfVxufVxuLyoqXG4gKiBBY3RpdmF0ZXMgdGhlIHByZXZpb3VzIGl0ZW0gYW5kIGZvY3VzZXMgaXQuIElmIG5vdGhpbmcgaXMgY3VycmVudGx5XG4gKiBhY3RpdmF0ZWQsIGFjdGl2YXRlcyB0aGUgbGFzdCBpdGVtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWN0aXZhdGVQcmV2aW91c0l0ZW0oaXRlbXMsIGFjdGl2ZUl0ZW1SZWNvcmQsIGlzQWN0aXZhdGFibGUgPSAoaXNJdGVtTm90RGlzYWJsZWQpLCB3cmFwID0gdHJ1ZSkge1xuICAgIGlmIChhY3RpdmVJdGVtUmVjb3JkKSB7XG4gICAgICAgIGNvbnN0IHByZXYgPSBnZXRQcmV2SXRlbShpdGVtcywgYWN0aXZlSXRlbVJlY29yZC5pbmRleCwgaXNBY3RpdmF0YWJsZSwgd3JhcCk7XG4gICAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgICAgICBwcmV2LnRhYkluZGV4ID0gMDtcbiAgICAgICAgICAgIHByZXYuZm9jdXMoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJldjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBhY3RpdmF0ZUxhc3RJdGVtKGl0ZW1zLCBpc0FjdGl2YXRhYmxlKTtcbiAgICB9XG59XG4vKipcbiAqIENyZWF0ZXMgYW4gZXZlbnQgdGhhdCByZXF1ZXN0cyB0aGUgcGFyZW50IG1kLWxpc3QgdG8gZGVhY3RpdmF0ZSBhbGwgb3RoZXJcbiAqIGl0ZW1zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRGVhY3RpdmF0ZUl0ZW1zRXZlbnQoKSB7XG4gICAgcmV0dXJuIG5ldyBFdmVudCgnZGVhY3RpdmF0ZS1pdGVtcycsIHsgYnViYmxlczogdHJ1ZSwgY29tcG9zZWQ6IHRydWUgfSk7XG59XG4vKipcbiAqIENyZWF0ZXMgYW4gZXZlbnQgdGhhdCByZXF1ZXN0cyB0aGUgbWVudSB0byBzZXQgYHRhYmluZGV4PTBgIG9uIHRoZSBpdGVtIGFuZFxuICogZm9jdXMgaXQuIFdlIHVzZSB0aGlzIHBhdHRlcm4gYmVjYXVzZSBMaXN0IGtlZXBzIHRyYWNrIG9mIHdoYXQgZWxlbWVudCBpc1xuICogYWN0aXZlIGluIHRoZSBMaXN0IGJ5IG1haW50YWluaW5nIHRhYmluZGV4LiBXZSBkbyBub3Qgd2FudCBsaXN0IGl0ZW1zXG4gKiB0byBzZXQgdGFiaW5kZXggb24gdGhlbXNlbHZlcyBvciBmb2N1cyB0aGVtc2VsdmVzIHNvIHRoYXQgd2UgY2FuIG9yZ2FuaXplIGFsbFxuICogdGhhdCBsb2dpYyBpbiB0aGUgcGFyZW50IExpc3QgYW5kIE1lbnVzLCBhbmQgbGlzdCBpdGVtIHN0YXlzIGFzIGR1bWIgYXNcbiAqIHBvc3NpYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVxdWVzdEFjdGl2YXRpb25FdmVudCgpIHtcbiAgICByZXR1cm4gbmV3IEV2ZW50KCdyZXF1ZXN0LWFjdGl2YXRpb24nLCB7IGJ1YmJsZXM6IHRydWUsIGNvbXBvc2VkOiB0cnVlIH0pO1xufVxuLyoqXG4gKiBUaGUgZGVmYXVsdCBgaXNBY3RpdmF0YWJsZWAgZnVuY3Rpb24sIHdoaWNoIGNoZWNrcyBpZiBhbiBpdGVtIGlzIG5vdFxuICogZGlzYWJsZWQuXG4gKlxuICogQHBhcmFtIGl0ZW0gVGhlIGl0ZW0gdG8gY2hlY2suXG4gKiBAcmV0dXJuIHRydWUgaWYgYGl0ZW0uZGlzYWJsZWRgIGlzIGBmYWxzZS5cbiAqL1xuZnVuY3Rpb24gaXNJdGVtTm90RGlzYWJsZWQoaXRlbSkge1xuICAgIHJldHVybiAhaXRlbS5kaXNhYmxlZDtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpc3QtbmF2aWdhdGlvbi1oZWxwZXJzLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8vIEdlbmVyYXRlZCBzdHlsZXNoZWV0IGZvciAuL2xpc3QvaW50ZXJuYWwvbGlzdC1zdHlsZXMuY3NzLlxuaW1wb3J0IHsgY3NzIH0gZnJvbSAnbGl0JztcbmV4cG9ydCBjb25zdCBzdHlsZXMgPSBjc3MgYDpob3N0e2JhY2tncm91bmQ6dmFyKC0tbWQtbGlzdC1jb250YWluZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1zdXJmYWNlLCAjZmVmN2ZmKSk7Y29sb3I6dW5zZXQ7ZGlzcGxheTpmbGV4O2ZsZXgtZGlyZWN0aW9uOmNvbHVtbjtvdXRsaW5lOm5vbmU7cGFkZGluZzo4cHggMDtwb3NpdGlvbjpyZWxhdGl2ZX1cbmA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saXN0LXN0eWxlcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBodG1sLCBpc1NlcnZlciwgTGl0RWxlbWVudCB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBxdWVyeUFzc2lnbmVkRWxlbWVudHMgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5pbXBvcnQgeyBMaXN0Q29udHJvbGxlciwgTmF2aWdhYmxlS2V5cyB9IGZyb20gJy4vbGlzdC1jb250cm9sbGVyLmpzJztcbmNvbnN0IE5BVklHQUJMRV9LRVlfU0VUID0gbmV3IFNldChPYmplY3QudmFsdWVzKE5hdmlnYWJsZUtleXMpKTtcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTplbmZvcmNlLWNvbW1lbnRzLW9uLWV4cG9ydGVkLXN5bWJvbHNcbmV4cG9ydCBjbGFzcyBMaXN0IGV4dGVuZHMgTGl0RWxlbWVudCB7XG4gICAgLyoqIEBleHBvcnQgKi9cbiAgICBnZXQgaXRlbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RDb250cm9sbGVyLml0ZW1zO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5saXN0Q29udHJvbGxlciA9IG5ldyBMaXN0Q29udHJvbGxlcih7XG4gICAgICAgICAgICBpc0l0ZW06IChpdGVtKSA9PiBpdGVtLmhhc0F0dHJpYnV0ZSgnbWQtbGlzdC1pdGVtJyksXG4gICAgICAgICAgICBnZXRQb3NzaWJsZUl0ZW1zOiAoKSA9PiB0aGlzLnNsb3RJdGVtcyxcbiAgICAgICAgICAgIGlzUnRsOiAoKSA9PiBnZXRDb21wdXRlZFN0eWxlKHRoaXMpLmRpcmVjdGlvbiA9PT0gJ3J0bCcsXG4gICAgICAgICAgICBkZWFjdGl2YXRlSXRlbTogKGl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICBpdGVtLnRhYkluZGV4ID0gLTE7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0aXZhdGVJdGVtOiAoaXRlbSkgPT4ge1xuICAgICAgICAgICAgICAgIGl0ZW0udGFiSW5kZXggPSAwO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlzTmF2aWdhYmxlS2V5OiAoa2V5KSA9PiBOQVZJR0FCTEVfS0VZX1NFVC5oYXMoa2V5KSxcbiAgICAgICAgICAgIGlzQWN0aXZhdGFibGU6IChpdGVtKSA9PiAhaXRlbS5kaXNhYmxlZCAmJiBpdGVtLnR5cGUgIT09ICd0ZXh0JyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxzID0gXG4gICAgICAgIC8vIENhc3QgbmVlZGVkIGZvciBjbG9zdXJlXG4gICAgICAgIHRoaXMuYXR0YWNoSW50ZXJuYWxzKCk7XG4gICAgICAgIGlmICghaXNTZXJ2ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuaW50ZXJuYWxzLnJvbGUgPSAnbGlzdCc7XG4gICAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmxpc3RDb250cm9sbGVyLmhhbmRsZUtleWRvd24pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPHNsb3RcbiAgICAgICAgQGRlYWN0aXZhdGUtaXRlbXM9JHt0aGlzLmxpc3RDb250cm9sbGVyLm9uRGVhY3RpdmF0ZUl0ZW1zfVxuICAgICAgICBAcmVxdWVzdC1hY3RpdmF0aW9uPSR7dGhpcy5saXN0Q29udHJvbGxlci5vblJlcXVlc3RBY3RpdmF0aW9ufVxuICAgICAgICBAc2xvdGNoYW5nZT0ke3RoaXMubGlzdENvbnRyb2xsZXIub25TbG90Y2hhbmdlfT5cbiAgICAgIDwvc2xvdD5cbiAgICBgO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBY3RpdmF0ZXMgdGhlIG5leHQgaXRlbSBpbiB0aGUgbGlzdC4gSWYgYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCwgdGhlIGZpcnN0XG4gICAgICogaXRlbSB3aWxsIGJlIGFjdGl2YXRlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gVGhlIGFjdGl2YXRlZCBsaXN0IGl0ZW0gb3IgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBpdGVtcy5cbiAgICAgKi9cbiAgICBhY3RpdmF0ZU5leHRJdGVtKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5saXN0Q29udHJvbGxlci5hY3RpdmF0ZU5leHRJdGVtKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFjdGl2YXRlcyB0aGUgcHJldmlvdXMgaXRlbSBpbiB0aGUgbGlzdC4gSWYgYXQgdGhlIHN0YXJ0IG9mIHRoZSBsaXN0LCB0aGVcbiAgICAgKiBsYXN0IGl0ZW0gd2lsbCBiZSBhY3RpdmF0ZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIFRoZSBhY3RpdmF0ZWQgbGlzdCBpdGVtIG9yIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gaXRlbXMuXG4gICAgICovXG4gICAgYWN0aXZhdGVQcmV2aW91c0l0ZW0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RDb250cm9sbGVyLmFjdGl2YXRlUHJldmlvdXNJdGVtKCk7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgcXVlcnlBc3NpZ25lZEVsZW1lbnRzKHsgZmxhdHRlbjogdHJ1ZSB9KVxuXSwgTGlzdC5wcm90b3R5cGUsIFwic2xvdEl0ZW1zXCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saXN0LmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8vIEdlbmVyYXRlZCBzdHlsZXNoZWV0IGZvciAuL2xpc3QvaW50ZXJuYWwvbGlzdGl0ZW0vbGlzdC1pdGVtLXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgOmhvc3R7ZGlzcGxheTpmbGV4Oy13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjpyZ2JhKDAsMCwwLDApOy0tbWQtcmlwcGxlLWhvdmVyLWNvbG9yOiB2YXIoLS1tZC1saXN0LWl0ZW0taG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1tZC1yaXBwbGUtaG92ZXItb3BhY2l0eTogdmFyKC0tbWQtbGlzdC1pdGVtLWhvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHksIDAuMDgpOy0tbWQtcmlwcGxlLXByZXNzZWQtY29sb3I6IHZhcigtLW1kLWxpc3QtaXRlbS1wcmVzc2VkLXN0YXRlLWxheWVyLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tbWQtcmlwcGxlLXByZXNzZWQtb3BhY2l0eTogdmFyKC0tbWQtbGlzdC1pdGVtLXByZXNzZWQtc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4xMil9Omhvc3QoOmlzKFt0eXBlPWJ1dHRvbl06bm90KFtkaXNhYmxlZF0pLFt0eXBlPWxpbmtdKSl7Y3Vyc29yOnBvaW50ZXJ9bWQtZm9jdXMtcmluZ3t6LWluZGV4OjE7LS1tZC1mb2N1cy1yaW5nLXNoYXBlOiA4cHh9YSxidXR0b24sbGl7YmFja2dyb3VuZDpub25lO2JvcmRlcjpub25lO2N1cnNvcjppbmhlcml0O3BhZGRpbmc6MDttYXJnaW46MDt0ZXh0LWFsaWduOnVuc2V0O3RleHQtZGVjb3JhdGlvbjpub25lfS5saXN0LWl0ZW17Ym9yZGVyLXJhZGl1czppbmhlcml0O2Rpc3BsYXk6ZmxleDtmbGV4OjE7bWF4LXdpZHRoOmluaGVyaXQ7bWluLXdpZHRoOmluaGVyaXQ7b3V0bGluZTpub25lOy13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjpyZ2JhKDAsMCwwLDApO3dpZHRoOjEwMCV9Lmxpc3QtaXRlbS5pbnRlcmFjdGl2ZXtjdXJzb3I6cG9pbnRlcn0ubGlzdC1pdGVtLmRpc2FibGVke29wYWNpdHk6dmFyKC0tbWQtbGlzdC1pdGVtLWRpc2FibGVkLW9wYWNpdHksIDAuMyk7cG9pbnRlci1ldmVudHM6bm9uZX1bc2xvdD1jb250YWluZXJde3BvaW50ZXItZXZlbnRzOm5vbmV9bWQtcmlwcGxle2JvcmRlci1yYWRpdXM6aW5oZXJpdH1tZC1pdGVte2JvcmRlci1yYWRpdXM6aW5oZXJpdDtmbGV4OjE7aGVpZ2h0OjEwMCU7Y29sb3I6dmFyKC0tbWQtbGlzdC1pdGVtLWxhYmVsLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7Zm9udC1mYW1pbHk6dmFyKC0tbWQtbGlzdC1pdGVtLWxhYmVsLXRleHQtZm9udCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLWZvbnQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS1wbGFpbiwgUm9ib3RvKSkpO2ZvbnQtc2l6ZTp2YXIoLS1tZC1saXN0LWl0ZW0tbGFiZWwtdGV4dC1zaXplLCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2Utc2l6ZSwgMXJlbSkpO2xpbmUtaGVpZ2h0OnZhcigtLW1kLWxpc3QtaXRlbS1sYWJlbC10ZXh0LWxpbmUtaGVpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2UtbGluZS1oZWlnaHQsIDEuNXJlbSkpO2ZvbnQtd2VpZ2h0OnZhcigtLW1kLWxpc3QtaXRlbS1sYWJlbC10ZXh0LXdlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLXdlaWdodCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXdlaWdodC1yZWd1bGFyLCA0MDApKSk7bWluLWhlaWdodDp2YXIoLS1tZC1saXN0LWl0ZW0tb25lLWxpbmUtY29udGFpbmVyLWhlaWdodCwgNTZweCk7cGFkZGluZy10b3A6dmFyKC0tbWQtbGlzdC1pdGVtLXRvcC1zcGFjZSwgMTJweCk7cGFkZGluZy1ib3R0b206dmFyKC0tbWQtbGlzdC1pdGVtLWJvdHRvbS1zcGFjZSwgMTJweCk7cGFkZGluZy1pbmxpbmUtc3RhcnQ6dmFyKC0tbWQtbGlzdC1pdGVtLWxlYWRpbmctc3BhY2UsIDE2cHgpO3BhZGRpbmctaW5saW5lLWVuZDp2YXIoLS1tZC1saXN0LWl0ZW0tdHJhaWxpbmctc3BhY2UsIDE2cHgpfW1kLWl0ZW1bbXVsdGlsaW5lXXttaW4taGVpZ2h0OnZhcigtLW1kLWxpc3QtaXRlbS10d28tbGluZS1jb250YWluZXItaGVpZ2h0LCA3MnB4KX1bc2xvdD1zdXBwb3J0aW5nLXRleHRde2NvbG9yOnZhcigtLW1kLWxpc3QtaXRlbS1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTtmb250LWZhbWlseTp2YXIoLS1tZC1saXN0LWl0ZW0tc3VwcG9ydGluZy10ZXh0LWZvbnQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1tZWRpdW0tZm9udCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXBsYWluLCBSb2JvdG8pKSk7Zm9udC1zaXplOnZhcigtLW1kLWxpc3QtaXRlbS1zdXBwb3J0aW5nLXRleHQtc2l6ZSwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LW1lZGl1bS1zaXplLCAwLjg3NXJlbSkpO2xpbmUtaGVpZ2h0OnZhcigtLW1kLWxpc3QtaXRlbS1zdXBwb3J0aW5nLXRleHQtbGluZS1oZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1tZWRpdW0tbGluZS1oZWlnaHQsIDEuMjVyZW0pKTtmb250LXdlaWdodDp2YXIoLS1tZC1saXN0LWl0ZW0tc3VwcG9ydGluZy10ZXh0LXdlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LW1lZGl1bS13ZWlnaHQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS13ZWlnaHQtcmVndWxhciwgNDAwKSkpfVtzbG90PXRyYWlsaW5nLXN1cHBvcnRpbmctdGV4dF17Y29sb3I6dmFyKC0tbWQtbGlzdC1pdGVtLXRyYWlsaW5nLXN1cHBvcnRpbmctdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpO2ZvbnQtZmFtaWx5OnZhcigtLW1kLWxpc3QtaXRlbS10cmFpbGluZy1zdXBwb3J0aW5nLXRleHQtZm9udCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1sYWJlbC1zbWFsbC1mb250LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2UtcGxhaW4sIFJvYm90bykpKTtmb250LXNpemU6dmFyKC0tbWQtbGlzdC1pdGVtLXRyYWlsaW5nLXN1cHBvcnRpbmctdGV4dC1zaXplLCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWxhYmVsLXNtYWxsLXNpemUsIDAuNjg3NXJlbSkpO2xpbmUtaGVpZ2h0OnZhcigtLW1kLWxpc3QtaXRlbS10cmFpbGluZy1zdXBwb3J0aW5nLXRleHQtbGluZS1oZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtbGFiZWwtc21hbGwtbGluZS1oZWlnaHQsIDFyZW0pKTtmb250LXdlaWdodDp2YXIoLS1tZC1saXN0LWl0ZW0tdHJhaWxpbmctc3VwcG9ydGluZy10ZXh0LXdlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1sYWJlbC1zbWFsbC13ZWlnaHQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS13ZWlnaHQtbWVkaXVtLCA1MDApKSl9OmlzKFtzbG90PXN0YXJ0XSxbc2xvdD1lbmRdKTo6c2xvdHRlZCgqKXtmaWxsOmN1cnJlbnRDb2xvcn1bc2xvdD1zdGFydF17Y29sb3I6dmFyKC0tbWQtbGlzdC1pdGVtLWxlYWRpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpfVtzbG90PWVuZF17Y29sb3I6dmFyKC0tbWQtbGlzdC1pdGVtLXRyYWlsaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKX1AbWVkaWEoZm9yY2VkLWNvbG9yczogYWN0aXZlKXsuZGlzYWJsZWQgc2xvdHtjb2xvcjpHcmF5VGV4dH0ubGlzdC1pdGVtLmRpc2FibGVke2NvbG9yOkdyYXlUZXh0O29wYWNpdHk6MX19XG5gO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGlzdC1pdGVtLXN0eWxlcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgJy4uLy4uLy4uL2ZvY3VzL21kLWZvY3VzLXJpbmcuanMnO1xuaW1wb3J0ICcuLi8uLi8uLi9sYWJzL2l0ZW0vaXRlbS5qcyc7XG5pbXBvcnQgJy4uLy4uLy4uL3JpcHBsZS9yaXBwbGUuanMnO1xuaW1wb3J0IHsgaHRtbCwgTGl0RWxlbWVudCwgbm90aGluZyB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBwcm9wZXJ0eSwgcXVlcnkgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5pbXBvcnQgeyBjbGFzc01hcCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL2NsYXNzLW1hcC5qcyc7XG5pbXBvcnQgeyBsaXRlcmFsLCBodG1sIGFzIHN0YXRpY0h0bWwgfSBmcm9tICdsaXQvc3RhdGljLWh0bWwuanMnO1xuaW1wb3J0IHsgbWl4aW5EZWxlZ2F0ZXNBcmlhIH0gZnJvbSAnLi4vLi4vLi4vaW50ZXJuYWwvYXJpYS9kZWxlZ2F0ZS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVSZXF1ZXN0QWN0aXZhdGlvbkV2ZW50LCB9IGZyb20gJy4uL2xpc3QtbmF2aWdhdGlvbi1oZWxwZXJzLmpzJztcbi8vIFNlcGFyYXRlIHZhcmlhYmxlIG5lZWRlZCBmb3IgY2xvc3VyZS5cbmNvbnN0IGxpc3RJdGVtQmFzZUNsYXNzID0gbWl4aW5EZWxlZ2F0ZXNBcmlhKExpdEVsZW1lbnQpO1xuLyoqXG4gKiBAZmlyZXMgcmVxdWVzdC1hY3RpdmF0aW9uIHtFdmVudH0gUmVxdWVzdHMgdGhlIGxpc3QgdG8gc2V0IGB0YWJpbmRleD0wYCBvblxuICogdGhlIGl0ZW0gYW5kIGZvY3VzIGl0LiAtLWJ1YmJsZXMgLS1jb21wb3NlZFxuICovXG5leHBvcnQgY2xhc3MgTGlzdEl0ZW1FbCBleHRlbmRzIGxpc3RJdGVtQmFzZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERpc2FibGVzIHRoZSBpdGVtIGFuZCBtYWtlcyBpdCBub24tc2VsZWN0YWJsZSBhbmQgbm9uLWludGVyYWN0aXZlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2V0cyB0aGUgYmVoYXZpb3Igb2YgdGhlIGxpc3QgaXRlbSwgZGVmYXVsdHMgdG8gXCJ0ZXh0XCIuIENoYW5nZSB0byBcImxpbmtcIiBvclxuICAgICAgICAgKiBcImJ1dHRvblwiIGZvciBpbnRlcmFjdGl2ZSBpdGVtcy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudHlwZSA9ICd0ZXh0JztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJFQURPTkxZLiBTZXRzIHRoZSBgbWQtbGlzdC1pdGVtYCBhdHRyaWJ1dGUgb24gdGhlIGVsZW1lbnQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzTGlzdEl0ZW0gPSB0cnVlO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2V0cyB0aGUgdW5kZXJseWluZyBgSFRNTEFuY2hvckVsZW1lbnRgJ3MgYGhyZWZgIHJlc291cmNlIGF0dHJpYnV0ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaHJlZiA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2V0cyB0aGUgdW5kZXJseWluZyBgSFRNTEFuY2hvckVsZW1lbnRgJ3MgYHRhcmdldGAgYXR0cmlidXRlIHdoZW4gYGhyZWZgIGlzXG4gICAgICAgICAqIHNldC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gJyc7XG4gICAgfVxuICAgIGdldCBpc0Rpc2FibGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kaXNhYmxlZCAmJiB0aGlzLnR5cGUgIT09ICdsaW5rJztcbiAgICB9XG4gICAgd2lsbFVwZGF0ZShjaGFuZ2VkKSB7XG4gICAgICAgIGlmICh0aGlzLmhyZWYpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9ICdsaW5rJztcbiAgICAgICAgfVxuICAgICAgICBzdXBlci53aWxsVXBkYXRlKGNoYW5nZWQpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbmRlckxpc3RJdGVtKGh0bWwgYFxuICAgICAgPG1kLWl0ZW0+XG4gICAgICAgIDxkaXYgc2xvdD1cImNvbnRhaW5lclwiPlxuICAgICAgICAgICR7dGhpcy5yZW5kZXJSaXBwbGUoKX0gJHt0aGlzLnJlbmRlckZvY3VzUmluZygpfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNsb3QgbmFtZT1cInN0YXJ0XCIgc2xvdD1cInN0YXJ0XCI+PC9zbG90PlxuICAgICAgICA8c2xvdCBuYW1lPVwiZW5kXCIgc2xvdD1cImVuZFwiPjwvc2xvdD5cbiAgICAgICAgJHt0aGlzLnJlbmRlckJvZHkoKX1cbiAgICAgIDwvbWQtaXRlbT5cbiAgICBgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVycyB0aGUgcm9vdCBsaXN0IGl0ZW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUgY2hpbGQgY29udGVudCBvZiB0aGUgbGlzdCBpdGVtLlxuICAgICAqL1xuICAgIHJlbmRlckxpc3RJdGVtKGNvbnRlbnQpIHtcbiAgICAgICAgY29uc3QgaXNBbmNob3IgPSB0aGlzLnR5cGUgPT09ICdsaW5rJztcbiAgICAgICAgbGV0IHRhZztcbiAgICAgICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2xpbmsnOlxuICAgICAgICAgICAgICAgIHRhZyA9IGxpdGVyYWwgYGFgO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnYnV0dG9uJzpcbiAgICAgICAgICAgICAgICB0YWcgPSBsaXRlcmFsIGBidXR0b25gO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGNhc2UgJ3RleHQnOlxuICAgICAgICAgICAgICAgIHRhZyA9IGxpdGVyYWwgYGxpYDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpc0ludGVyYWN0aXZlID0gdGhpcy50eXBlICE9PSAndGV4dCc7XG4gICAgICAgIC8vIFRPRE8oYi8yNjUzMzk4NjYpOiBhbm5vdW5jZSBcImJ1dHRvblwiL1wibGlua1wiIGluc2lkZSBvZiBhIGxpc3QgaXRlbS4gVW50aWxcbiAgICAgICAgLy8gdGhlbiBhbGwgYXJlIFwibGlzdGl0ZW1cIiByb2xlcyBmb3IgY29ycmVjdCBhbm5vdW5jZW1lbnQuXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGlzQW5jaG9yICYmICEhdGhpcy50YXJnZXQgPyB0aGlzLnRhcmdldCA6IG5vdGhpbmc7XG4gICAgICAgIHJldHVybiBzdGF0aWNIdG1sIGBcbiAgICAgIDwke3RhZ31cbiAgICAgICAgaWQ9XCJpdGVtXCJcbiAgICAgICAgdGFiaW5kZXg9XCIke3RoaXMuaXNEaXNhYmxlZCB8fCAhaXNJbnRlcmFjdGl2ZSA/IC0xIDogMH1cIlxuICAgICAgICA/ZGlzYWJsZWQ9JHt0aGlzLmlzRGlzYWJsZWR9XG4gICAgICAgIHJvbGU9XCJsaXN0aXRlbVwiXG4gICAgICAgIGFyaWEtc2VsZWN0ZWQ9JHt0aGlzLmFyaWFTZWxlY3RlZCB8fCBub3RoaW5nfVxuICAgICAgICBhcmlhLWNoZWNrZWQ9JHt0aGlzLmFyaWFDaGVja2VkIHx8IG5vdGhpbmd9XG4gICAgICAgIGFyaWEtZXhwYW5kZWQ9JHt0aGlzLmFyaWFFeHBhbmRlZCB8fCBub3RoaW5nfVxuICAgICAgICBhcmlhLWhhc3BvcHVwPSR7dGhpcy5hcmlhSGFzUG9wdXAgfHwgbm90aGluZ31cbiAgICAgICAgY2xhc3M9XCJsaXN0LWl0ZW0gJHtjbGFzc01hcCh0aGlzLmdldFJlbmRlckNsYXNzZXMoKSl9XCJcbiAgICAgICAgaHJlZj0ke3RoaXMuaHJlZiB8fCBub3RoaW5nfVxuICAgICAgICB0YXJnZXQ9JHt0YXJnZXR9XG4gICAgICAgIEBmb2N1cz0ke3RoaXMub25Gb2N1c31cbiAgICAgID4ke2NvbnRlbnR9PC8ke3RhZ30+XG4gICAgYDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlcyByZW5kZXJpbmcgb2YgdGhlIHJpcHBsZSBlbGVtZW50LlxuICAgICAqL1xuICAgIHJlbmRlclJpcHBsZSgpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICByZXR1cm4gbm90aGluZztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaHRtbCBgIDxtZC1yaXBwbGVcbiAgICAgIHBhcnQ9XCJyaXBwbGVcIlxuICAgICAgZm9yPVwiaXRlbVwiXG4gICAgICA/ZGlzYWJsZWQ9JHt0aGlzLmlzRGlzYWJsZWR9PjwvbWQtcmlwcGxlPmA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgcmVuZGVyaW5nIG9mIHRoZSBmb2N1cyByaW5nLlxuICAgICAqL1xuICAgIHJlbmRlckZvY3VzUmluZygpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICByZXR1cm4gbm90aGluZztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaHRtbCBgIDxtZC1mb2N1cy1yaW5nXG4gICAgICBAdmlzaWJpbGl0eS1jaGFuZ2VkPSR7dGhpcy5vbkZvY3VzUmluZ1Zpc2liaWxpdHlDaGFuZ2VkfVxuICAgICAgcGFydD1cImZvY3VzLXJpbmdcIlxuICAgICAgZm9yPVwiaXRlbVwiXG4gICAgICBpbndhcmQ+PC9tZC1mb2N1cy1yaW5nPmA7XG4gICAgfVxuICAgIG9uRm9jdXNSaW5nVmlzaWJpbGl0eUNoYW5nZWQoZSkgeyB9XG4gICAgLyoqXG4gICAgICogQ2xhc3NlcyBhcHBsaWVkIHRvIHRoZSBsaXN0IGl0ZW0gcm9vdC5cbiAgICAgKi9cbiAgICBnZXRSZW5kZXJDbGFzc2VzKCkge1xuICAgICAgICByZXR1cm4geyAnZGlzYWJsZWQnOiB0aGlzLmlzRGlzYWJsZWQgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlcyByZW5kZXJpbmcgdGhlIGhlYWRsaW5lIGFuZCBzdXBwb3J0aW5nIHRleHQuXG4gICAgICovXG4gICAgcmVuZGVyQm9keSgpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPHNsb3Q+PC9zbG90PlxuICAgICAgPHNsb3QgbmFtZT1cIm92ZXJsaW5lXCIgc2xvdD1cIm92ZXJsaW5lXCI+PC9zbG90PlxuICAgICAgPHNsb3QgbmFtZT1cImhlYWRsaW5lXCIgc2xvdD1cImhlYWRsaW5lXCI+PC9zbG90PlxuICAgICAgPHNsb3QgbmFtZT1cInN1cHBvcnRpbmctdGV4dFwiIHNsb3Q9XCJzdXBwb3J0aW5nLXRleHRcIj48L3Nsb3Q+XG4gICAgICA8c2xvdFxuICAgICAgICBuYW1lPVwidHJhaWxpbmctc3VwcG9ydGluZy10ZXh0XCJcbiAgICAgICAgc2xvdD1cInRyYWlsaW5nLXN1cHBvcnRpbmctdGV4dFwiPjwvc2xvdD5cbiAgICBgO1xuICAgIH1cbiAgICBvbkZvY3VzKCkge1xuICAgICAgICBpZiAodGhpcy50YWJJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBIYW5kbGVzIHRoZSBjYXNlIHdoZXJlIHRoZSB1c2VyIGNsaWNrcyBvbiB0aGUgZWxlbWVudCBhbmQgdGhlbiB0YWJzLlxuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY3JlYXRlUmVxdWVzdEFjdGl2YXRpb25FdmVudCgpKTtcbiAgICB9XG4gICAgZm9jdXMoKSB7XG4gICAgICAgIC8vIFRPRE8oYi8zMDAzMzQ1MDkpOiBuZWVkZWQgZm9yIHNvbWUgY2FzZXMgd2hlcmUgZGVsZWdhdGVzRm9jdXMgZG9lc24ndFxuICAgICAgICAvLyB3b3JrIHByb2dyYW1tYXRpY2FsbHkgbGlrZSBpbiBGRiBhbmQgc2VsZWN0LW9wdGlvblxuICAgICAgICB0aGlzLmxpc3RJdGVtUm9vdD8uZm9jdXMoKTtcbiAgICB9XG4gICAgY2xpY2soKSB7XG4gICAgICAgIGlmICghdGhpcy5saXN0SXRlbVJvb3QpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBlbGVtZW50IGhhcyBub3QgZmluaXNoZWQgcmVuZGVyaW5nLCBjYWxsIHN1cGVyIHRvIGVuc3VyZSBjbGlja1xuICAgICAgICAgICAgLy8gZXZlbnRzIGFyZSBkaXNwYXRjaGVkLlxuICAgICAgICAgICAgc3VwZXIuY2xpY2soKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3J3YXJkIGNsaWNrIHRvIHRoZSBlbGVtZW50IHRvIGVuc3VyZSBsaW5rIDxhPi5jbGljaygpIHdvcmtzIGNvcnJlY3RseS5cbiAgICAgICAgdGhpcy5saXN0SXRlbVJvb3QuY2xpY2soKTtcbiAgICB9XG59XG4vKiogQG5vY29sbGFwc2UgKi9cbkxpc3RJdGVtRWwuc2hhZG93Um9vdE9wdGlvbnMgPSB7XG4gICAgLi4uTGl0RWxlbWVudC5zaGFkb3dSb290T3B0aW9ucyxcbiAgICBkZWxlZ2F0ZXNGb2N1czogdHJ1ZSxcbn07XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4sIHJlZmxlY3Q6IHRydWUgfSlcbl0sIExpc3RJdGVtRWwucHJvdG90eXBlLCBcImRpc2FibGVkXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHJlZmxlY3Q6IHRydWUgfSlcbl0sIExpc3RJdGVtRWwucHJvdG90eXBlLCBcInR5cGVcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnbWQtbGlzdC1pdGVtJywgcmVmbGVjdDogdHJ1ZSB9KVxuXSwgTGlzdEl0ZW1FbC5wcm90b3R5cGUsIFwiaXNMaXN0SXRlbVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoKVxuXSwgTGlzdEl0ZW1FbC5wcm90b3R5cGUsIFwiaHJlZlwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoKVxuXSwgTGlzdEl0ZW1FbC5wcm90b3R5cGUsIFwidGFyZ2V0XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBxdWVyeSgnLmxpc3QtaXRlbScpXG5dLCBMaXN0SXRlbUVsLnByb3RvdHlwZSwgXCJsaXN0SXRlbVJvb3RcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpc3QtaXRlbS5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBDbG9zZVJlYXNvbiwgY3JlYXRlRGVmYXVsdENsb3NlTWVudUV2ZW50LCBpc0Nsb3NhYmxlS2V5LCB9IGZyb20gJy4vc2hhcmVkLmpzJztcbi8qKlxuICogQSBjb250cm9sbGVyIHRoYXQgcHJvdmlkZXMgbW9zdCBmdW5jdGlvbmFsaXR5IG9mIGFuIGVsZW1lbnQgdGhhdCBpbXBsZW1lbnRzXG4gKiB0aGUgTWVudUl0ZW0gaW50ZXJmYWNlLlxuICovXG5leHBvcnQgY2xhc3MgTWVudUl0ZW1Db250cm9sbGVyIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gaG9zdCBUaGUgTWVudUl0ZW0gaW4gd2hpY2ggdG8gYXR0YWNoIHRoaXMgY29udHJvbGxlciB0by5cbiAgICAgKiBAcGFyYW0gY29uZmlnIFRoZSBvYmplY3QgdGhhdCBjb25maWd1cmVzIHRoaXMgY29udHJvbGxlcidzIGJlaGF2aW9yLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGhvc3QsIGNvbmZpZykge1xuICAgICAgICB0aGlzLmhvc3QgPSBob3N0O1xuICAgICAgICB0aGlzLmludGVybmFsVHlwZWFoZWFkVGV4dCA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBCaW5kIHRoaXMgY2xpY2sgbGlzdGVuZXIgdG8gdGhlIGludGVyYWN0aXZlIGVsZW1lbnQuIEhhbmRsZXMgY2xvc2luZyB0aGVcbiAgICAgICAgICogbWVudS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub25DbGljayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmhvc3Qua2VlcE9wZW4pXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgdGhpcy5ob3N0LmRpc3BhdGNoRXZlbnQoY3JlYXRlRGVmYXVsdENsb3NlTWVudUV2ZW50KHRoaXMuaG9zdCwge1xuICAgICAgICAgICAgICAgIGtpbmQ6IENsb3NlUmVhc29uLkNMSUNLX1NFTEVDVElPTixcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEJpbmQgdGhpcyBjbGljayBsaXN0ZW5lciB0byB0aGUgaW50ZXJhY3RpdmUgZWxlbWVudC4gSGFuZGxlcyBjbG9zaW5nIHRoZVxuICAgICAgICAgKiBtZW51LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbktleWRvd24gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBpbnRlcmFjdGl2ZSBlbGVtZW50IGlzIGFuIGFuY2hvciB0YWcuIElmIHNvLCBjbGljayBpdC5cbiAgICAgICAgICAgIGlmICh0aGlzLmhvc3QuaHJlZiAmJiBldmVudC5jb2RlID09PSAnRW50ZXInKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW50ZXJhY3RpdmVFbGVtZW50ID0gdGhpcy5nZXRJbnRlcmFjdGl2ZUVsZW1lbnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJhY3RpdmVFbGVtZW50IGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3RpdmVFbGVtZW50LmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGhvc3QgaGFzIGtlZXBPcGVuID0gdHJ1ZSB3ZSBzaG91bGQgaWdub3JlIGNsaWNrcyAmIFNwYWNlL0VudGVyLFxuICAgICAgICAgICAgLy8gaG93ZXZlciB3ZSBhbHdheXMgbWFpbnRhaW4gdGhlIGFiaWxpdHkgdG8gY2xvc2UgYSBtZW51IHdpdGggYSBleHBsaWNpdFxuICAgICAgICAgICAgLy8gYGVzY2FwZWAga2V5cHJlc3MuXG4gICAgICAgICAgICBjb25zdCBrZXlDb2RlID0gZXZlbnQuY29kZTtcbiAgICAgICAgICAgIGlmICh0aGlzLmhvc3Qua2VlcE9wZW4gJiYga2V5Q29kZSAhPT0gJ0VzY2FwZScpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgaWYgKGlzQ2xvc2FibGVLZXkoa2V5Q29kZSkpIHtcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuaG9zdC5kaXNwYXRjaEV2ZW50KGNyZWF0ZURlZmF1bHRDbG9zZU1lbnVFdmVudCh0aGlzLmhvc3QsIHtcbiAgICAgICAgICAgICAgICAgICAga2luZDogQ2xvc2VSZWFzb24uS0VZRE9XTixcbiAgICAgICAgICAgICAgICAgICAga2V5OiBrZXlDb2RlLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRIZWFkbGluZUVsZW1lbnRzID0gY29uZmlnLmdldEhlYWRsaW5lRWxlbWVudHM7XG4gICAgICAgIHRoaXMuZ2V0U3VwcG9ydGluZ1RleHRFbGVtZW50cyA9IGNvbmZpZy5nZXRTdXBwb3J0aW5nVGV4dEVsZW1lbnRzO1xuICAgICAgICB0aGlzLmdldERlZmF1bHRFbGVtZW50cyA9IGNvbmZpZy5nZXREZWZhdWx0RWxlbWVudHM7XG4gICAgICAgIHRoaXMuZ2V0SW50ZXJhY3RpdmVFbGVtZW50ID0gY29uZmlnLmdldEludGVyYWN0aXZlRWxlbWVudDtcbiAgICAgICAgdGhpcy5ob3N0LmFkZENvbnRyb2xsZXIodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0ZXh0IHRoYXQgaXMgc2VsZWN0YWJsZSB2aWEgdHlwZWFoZWFkLiBJZiBub3Qgc2V0LCBkZWZhdWx0cyB0byB0aGVcbiAgICAgKiBpbm5lclRleHQgb2YgdGhlIGl0ZW0gc2xvdHRlZCBpbnRvIHRoZSBgXCJoZWFkbGluZVwiYCBzbG90LCBhbmQgaWYgdGhlcmUgYXJlXG4gICAgICogbm8gc2xvdHRlZCBlbGVtZW50cyBpbnRvIGhlYWRsaW5lLCB0aGVuIGl0IGNoZWNrcyB0aGUgX2RlZmF1bHRfIHNsb3QsIGFuZFxuICAgICAqIHRoZW4gdGhlIGBcInN1cHBvcnRpbmctdGV4dFwiYCBzbG90IGlmIG5vdGhpbmcgaXMgaW4gX2RlZmF1bHRfLlxuICAgICAqL1xuICAgIGdldCB0eXBlYWhlYWRUZXh0KCkge1xuICAgICAgICBpZiAodGhpcy5pbnRlcm5hbFR5cGVhaGVhZFRleHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmludGVybmFsVHlwZWFoZWFkVGV4dDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoZWFkbGluZUVsZW1lbnRzID0gdGhpcy5nZXRIZWFkbGluZUVsZW1lbnRzKCk7XG4gICAgICAgIGNvbnN0IHRleHRQYXJ0cyA9IFtdO1xuICAgICAgICBoZWFkbGluZUVsZW1lbnRzLmZvckVhY2goKGhlYWRsaW5lRWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGhlYWRsaW5lRWxlbWVudC50ZXh0Q29udGVudCAmJiBoZWFkbGluZUVsZW1lbnQudGV4dENvbnRlbnQudHJpbSgpKSB7XG4gICAgICAgICAgICAgICAgdGV4dFBhcnRzLnB1c2goaGVhZGxpbmVFbGVtZW50LnRleHRDb250ZW50LnRyaW0oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbm8gaGVhZGxpbmUgZWxlbWVudHMsIGNoZWNrIHRoZSBkZWZhdWx0IHNsb3QncyB0ZXh0IGNvbnRlbnRcbiAgICAgICAgaWYgKHRleHRQYXJ0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0RGVmYXVsdEVsZW1lbnRzKCkuZm9yRWFjaCgoZGVmYXVsdEVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdEVsZW1lbnQudGV4dENvbnRlbnQgJiYgZGVmYXVsdEVsZW1lbnQudGV4dENvbnRlbnQudHJpbSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHRQYXJ0cy5wdXNoKGRlZmF1bHRFbGVtZW50LnRleHRDb250ZW50LnRyaW0oKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgdGhlcmUgYXJlIG5vIGhlYWRsaW5lIG5vciBkZWZhdWx0IHNsb3QgZWxlbWVudHMsIGNoZWNrIHRoZVxuICAgICAgICAvL3N1cHBvcnRpbmctdGV4dCBzbG90J3MgdGV4dCBjb250ZW50XG4gICAgICAgIGlmICh0ZXh0UGFydHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmdldFN1cHBvcnRpbmdUZXh0RWxlbWVudHMoKS5mb3JFYWNoKChzdXBwb3J0aW5nVGV4dEVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoc3VwcG9ydGluZ1RleHRFbGVtZW50LnRleHRDb250ZW50ICYmXG4gICAgICAgICAgICAgICAgICAgIHN1cHBvcnRpbmdUZXh0RWxlbWVudC50ZXh0Q29udGVudC50cmltKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dFBhcnRzLnB1c2goc3VwcG9ydGluZ1RleHRFbGVtZW50LnRleHRDb250ZW50LnRyaW0oKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRleHRQYXJ0cy5qb2luKCcgJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvbW1lbmRlZCB0YWcgbmFtZSB0byByZW5kZXIgYXMgdGhlIGxpc3QgaXRlbS5cbiAgICAgKi9cbiAgICBnZXQgdGFnTmFtZSgpIHtcbiAgICAgICAgY29uc3QgdHlwZSA9IHRoaXMuaG9zdC50eXBlO1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2xpbmsnOlxuICAgICAgICAgICAgICAgIHJldHVybiAnYSc7XG4gICAgICAgICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICAgICAgICAgIHJldHVybiAnYnV0dG9uJztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBjYXNlICdtZW51aXRlbSc6XG4gICAgICAgICAgICBjYXNlICdvcHRpb24nOlxuICAgICAgICAgICAgICAgIHJldHVybiAnbGknO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWNvbW1lbmRlZCByb2xlIG9mIHRoZSBtZW51IGl0ZW0uXG4gICAgICovXG4gICAgZ2V0IHJvbGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhvc3QudHlwZSA9PT0gJ29wdGlvbicgPyAnb3B0aW9uJyA6ICdtZW51aXRlbSc7XG4gICAgfVxuICAgIGhvc3RDb25uZWN0ZWQoKSB7XG4gICAgICAgIHRoaXMuaG9zdC50b2dnbGVBdHRyaWJ1dGUoJ21kLW1lbnUtaXRlbScsIHRydWUpO1xuICAgIH1cbiAgICBob3N0VXBkYXRlKCkge1xuICAgICAgICBpZiAodGhpcy5ob3N0LmhyZWYpIHtcbiAgICAgICAgICAgIHRoaXMuaG9zdC50eXBlID0gJ2xpbmsnO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVzZSB0byBzZXQgdGhlIHR5cGVhaGVhZFRleHQgd2hlbiBpdCBjaGFuZ2VzLlxuICAgICAqL1xuICAgIHNldFR5cGVhaGVhZFRleHQodGV4dCkge1xuICAgICAgICB0aGlzLmludGVybmFsVHlwZWFoZWFkVGV4dCA9IHRleHQ7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVudUl0ZW1Db250cm9sbGVyLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8qKlxuICogQ3JlYXRlcyBhbiBldmVudCB0aGF0IGNsb3NlcyBhbnkgcGFyZW50IG1lbnVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2xvc2VNZW51RXZlbnQoaW5pdGlhdG9yLCByZWFzb24pIHtcbiAgICByZXR1cm4gbmV3IEN1c3RvbUV2ZW50KCdjbG9zZS1tZW51Jywge1xuICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICBjb21wb3NlZDogdHJ1ZSxcbiAgICAgICAgZGV0YWlsOiB7IGluaXRpYXRvciwgcmVhc29uLCBpdGVtUGF0aDogW2luaXRpYXRvcl0gfSxcbiAgICB9KTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhbiBldmVudCB0aGF0IHNpZ25hbHMgdG8gdGhlIG1lbnUgdGhhdCBpdCBzaG91bGQgc3RheSBvcGVuIG9uIHRoZVxuICogZm9jdXNvdXQgZXZlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTdGF5T3Blbk9uRm9jdXNvdXRFdmVudCgpIHtcbiAgICByZXR1cm4gbmV3IEV2ZW50KCdzdGF5LW9wZW4tb24tZm9jdXNvdXQnLCB7IGJ1YmJsZXM6IHRydWUsIGNvbXBvc2VkOiB0cnVlIH0pO1xufVxuLyoqXG4gKiBDcmVhdGVzIGFuIGV2ZW50IHRoYXQgc2lnbmFscyB0byB0aGUgbWVudSB0aGF0IGl0IHNob3VsZCBjbG9zZSBvcGVuIG9uIHRoZVxuICogZm9jdXNvdXQgZXZlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDbG9zZU9uRm9jdXNvdXRFdmVudCgpIHtcbiAgICByZXR1cm4gbmV3IEV2ZW50KCdjbG9zZS1vbi1mb2N1c291dCcsIHsgYnViYmxlczogdHJ1ZSwgY29tcG9zZWQ6IHRydWUgfSk7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBkZWZhdWx0IGNsb3NlIG1lbnUgZXZlbnQgdXNlZCBieSBtZC1tZW51LlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRGVmYXVsdENsb3NlTWVudUV2ZW50ID0gKGNyZWF0ZUNsb3NlTWVudUV2ZW50KTtcbi8qKlxuICogQ3JlYXRlcyBhbiBldmVudCB0aGF0IHJlcXVlc3RzIHRoZSBnaXZlbiBpdGVtIGJlIHNlbGVjdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRGVhY3RpdmF0ZVR5cGVhaGVhZEV2ZW50KCkge1xuICAgIHJldHVybiBuZXcgRXZlbnQoJ2RlYWN0aXZhdGUtdHlwZWFoZWFkJywgeyBidWJibGVzOiB0cnVlLCBjb21wb3NlZDogdHJ1ZSB9KTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhbiBldmVudCB0aGF0IHJlcXVlc3RzIHRoZSB0eXBlYWhlYWQgZnVuY3Rpb25hbGl0eSBvZiBjb250YWluaW5nIG1lbnVcbiAqIGJlIGFjdGl2YXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFjdGl2YXRlVHlwZWFoZWFkRXZlbnQoKSB7XG4gICAgcmV0dXJuIG5ldyBFdmVudCgnYWN0aXZhdGUtdHlwZWFoZWFkJywgeyBidWJibGVzOiB0cnVlLCBjb21wb3NlZDogdHJ1ZSB9KTtcbn1cbi8qKlxuICogS2V5cyB0aGF0IGFyZSB1c2VkIHRvIG5hdmlnYXRlIG1lbnVzLlxuICovXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZW5mb3JjZS1uYW1lLWNhc2luZyBXZSBhcmUgbWltaWNraW5nIGVudW0gc3R5bGVcbmV4cG9ydCBjb25zdCBOYXZpZ2FibGVLZXkgPSB7XG4gICAgVVA6ICdBcnJvd1VwJyxcbiAgICBET1dOOiAnQXJyb3dEb3duJyxcbiAgICBSSUdIVDogJ0Fycm93UmlnaHQnLFxuICAgIExFRlQ6ICdBcnJvd0xlZnQnLFxufTtcbi8qKlxuICogS2V5cyB0aGF0IGFyZSB1c2VkIGZvciBzZWxlY3Rpb24gaW4gbWVudXMuXG4gKi9cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTplbmZvcmNlLW5hbWUtY2FzaW5nIFdlIGFyZSBtaW1pY2tpbmcgZW51bSBzdHlsZVxuZXhwb3J0IGNvbnN0IFNlbGVjdGlvbktleSA9IHtcbiAgICBTUEFDRTogJ1NwYWNlJyxcbiAgICBFTlRFUjogJ0VudGVyJyxcbn07XG4vKipcbiAqIERlZmF1bHQgY2xvc2UgYFJlYXNvbmAga2luZCB2YWx1ZXMuXG4gKi9cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTplbmZvcmNlLW5hbWUtY2FzaW5nIFdlIGFyZSBtaW1pY2tpbmcgZW51bSBzdHlsZVxuZXhwb3J0IGNvbnN0IENsb3NlUmVhc29uID0ge1xuICAgIENMSUNLX1NFTEVDVElPTjogJ2NsaWNrLXNlbGVjdGlvbicsXG4gICAgS0VZRE9XTjogJ2tleWRvd24nLFxufTtcbi8qKlxuICogS2V5cyB0aGF0IGNhbiBjbG9zZSBtZW51cy5cbiAqL1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmVuZm9yY2UtbmFtZS1jYXNpbmcgV2UgYXJlIG1pbWlja2luZyBlbnVtIHN0eWxlXG5leHBvcnQgY29uc3QgS2V5ZG93bkNsb3NlS2V5ID0ge1xuICAgIEVTQ0FQRTogJ0VzY2FwZScsXG4gICAgU1BBQ0U6IFNlbGVjdGlvbktleS5TUEFDRSxcbiAgICBFTlRFUjogU2VsZWN0aW9uS2V5LkVOVEVSLFxufTtcbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiBrZXkgY29kZSBpcyBhIGtleSBjb2RlIHRoYXQgc2hvdWxkIGNsb3NlIHRoZVxuICogbWVudS5cbiAqXG4gKiBAcGFyYW0gY29kZSBUaGUgS2V5Ym9hcmRFdmVudCBjb2RlIHRvIGNoZWNrLlxuICogQHJldHVybiBXaGV0aGVyIG9yIG5vdCB0aGUga2V5IGNvZGUgaXMgaW4gdGhlIHByZWRldGVybWluZWQgbGlzdCB0byBjbG9zZSB0aGVcbiAqIG1lbnUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Nsb3NhYmxlS2V5KGNvZGUpIHtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhLZXlkb3duQ2xvc2VLZXkpLnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSA9PT0gY29kZSk7XG59XG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciB0aGUgZ2l2ZW4ga2V5IGNvZGUgaXMgYSBrZXkgY29kZSB0aGF0IHNob3VsZCBzZWxlY3QgYSBtZW51XG4gKiBpdGVtLlxuICpcbiAqIEBwYXJhbSBjb2RlIFRoZXkgS2V5Ym9hcmRFdmVudCBjb2RlIHRvIGNoZWNrLlxuICogQHJldHVybiBXaGV0aGVyIG9yIG5vdCB0aGUga2V5IGNvZGUgaXMgaW4gdGhlIHByZWRldGVybWluZWQgbGlzdCB0byBzZWxlY3QgYVxuICogbWVudSBpdGVtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTZWxlY3RhYmxlS2V5KGNvZGUpIHtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhTZWxlY3Rpb25LZXkpLnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSA9PT0gY29kZSk7XG59XG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIHRhcmdldCBlbGVtZW50IGlzIGNvbnRhaW5lZCBpbnNpZGUgYW5vdGhlciBlbGVtZW50J3NcbiAqIGNvbXBvc2VkIHRyZWUuXG4gKlxuICogQHBhcmFtIHRhcmdldCBUaGUgcG90ZW50aWFsIGNvbnRhaW5lZCBlbGVtZW50LlxuICogQHBhcmFtIGNvbnRhaW5lciBUaGUgcG90ZW50aWFsIGNvbnRhaW5pbmcgZWxlbWVudCBvZiB0aGUgdGFyZ2V0LlxuICogQHJldHVybnMgV2hldGhlciB0aGUgdGFyZ2V0IGVsZW1lbnQgaXMgY29udGFpbmVkIGluc2lkZSB0aGUgY29udGFpbmVyJ3NcbiAqIGNvbXBvc2VkIHN1YnRyZWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRWxlbWVudEluU3VidHJlZSh0YXJnZXQsIGNvbnRhaW5lcikge1xuICAgIC8vIERpc3BhdGNoIGEgY29tcG9zZWQsIGJ1YmJsaW5nIGV2ZW50IHRvIGNoZWNrIGl0cyBwYXRoIHRvIHNlZSBpZiB0aGVcbiAgICAvLyBuZXdseS1mb2N1c2VkIGVsZW1lbnQgaXMgY29udGFpbmVkIGluIGNvbnRhaW5lcidzIHN1YnRyZWVcbiAgICBjb25zdCBmb2N1c0V2ID0gbmV3IEV2ZW50KCdtZC1jb250YWlucycsIHsgYnViYmxlczogdHJ1ZSwgY29tcG9zZWQ6IHRydWUgfSk7XG4gICAgbGV0IGNvbXBvc2VkUGF0aCA9IFtdO1xuICAgIGNvbnN0IGxpc3RlbmVyID0gKGV2KSA9PiB7XG4gICAgICAgIGNvbXBvc2VkUGF0aCA9IGV2LmNvbXBvc2VkUGF0aCgpO1xuICAgIH07XG4gICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ21kLWNvbnRhaW5zJywgbGlzdGVuZXIpO1xuICAgIHRhcmdldC5kaXNwYXRjaEV2ZW50KGZvY3VzRXYpO1xuICAgIGNvbnRhaW5lci5yZW1vdmVFdmVudExpc3RlbmVyKCdtZC1jb250YWlucycsIGxpc3RlbmVyKTtcbiAgICBjb25zdCBpc0NvbnRhaW5lZCA9IGNvbXBvc2VkUGF0aC5sZW5ndGggPiAwO1xuICAgIHJldHVybiBpc0NvbnRhaW5lZDtcbn1cbi8qKlxuICogRWxlbWVudCB0byBmb2N1cyBvbiB3aGVuIG1lbnUgaXMgZmlyc3Qgb3BlbmVkLlxuICovXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZW5mb3JjZS1uYW1lLWNhc2luZyBXZSBhcmUgbWltaWNraW5nIGVudW0gc3R5bGVcbmV4cG9ydCBjb25zdCBGb2N1c1N0YXRlID0ge1xuICAgIE5PTkU6ICdub25lJyxcbiAgICBMSVNUX1JPT1Q6ICdsaXN0LXJvb3QnLFxuICAgIEZJUlNUX0lURU06ICdmaXJzdC1pdGVtJyxcbiAgICBMQVNUX0lURU06ICdsYXN0LWl0ZW0nLFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNoYXJlZC5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG4vKipcbiAqIEFuIGVudW0gb2Ygc3VwcG9ydGVkIE1lbnUgY29ybmVyc1xuICovXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZW5mb3JjZS1uYW1lLWNhc2luZyBXZSBhcmUgbWltaWNraW5nIGVudW0gc3R5bGVcbmV4cG9ydCBjb25zdCBDb3JuZXIgPSB7XG4gICAgRU5EX1NUQVJUOiAnZW5kLXN0YXJ0JyxcbiAgICBFTkRfRU5EOiAnZW5kLWVuZCcsXG4gICAgU1RBUlRfU1RBUlQ6ICdzdGFydC1zdGFydCcsXG4gICAgU1RBUlRfRU5EOiAnc3RhcnQtZW5kJyxcbn07XG4vKipcbiAqIEdpdmVuIGEgc3VyZmFjZSwgYW4gYW5jaG9yLCBjb3JuZXJzLCBhbmQgc29tZSBvcHRpb25zLCB0aGlzIHN1cmZhY2Ugd2lsbFxuICogY2FsY3VsYXRlIHRoZSBwb3NpdGlvbiBvZiBhIHN1cmZhY2UgdG8gYWxpZ24gdGhlIHR3byBnaXZlbiBjb3JuZXJzIGFuZCBrZWVwXG4gKiB0aGUgc3VyZmFjZSBpbnNpZGUgdGhlIHdpbmRvdyB2aWV3cG9ydC4gSXQgYWxzbyBwcm92aWRlcyBhIFN0eWxlSW5mbyBtYXAgdGhhdFxuICogY2FuIGJlIGFwcGxpZWQgdG8gdGhlIHN1cmZhY2UgdG8gaGFuZGxlIHZpc2libGlsaXR5IGFuZCBwb3NpdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFN1cmZhY2VQb3NpdGlvbkNvbnRyb2xsZXIge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBob3N0IFRoZSBob3N0IHRvIGNvbm5lY3QgdGhlIGNvbnRyb2xsZXIgdG8uXG4gICAgICogQHBhcmFtIGdldFByb3BlcnRpZXMgQSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHByb3BlcnRpZXMgZm9yIHRoZVxuICAgICAqIGNvbnRyb2xsZXIuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoaG9zdCwgZ2V0UHJvcGVydGllcykge1xuICAgICAgICB0aGlzLmhvc3QgPSBob3N0O1xuICAgICAgICB0aGlzLmdldFByb3BlcnRpZXMgPSBnZXRQcm9wZXJ0aWVzO1xuICAgICAgICAvLyBUaGUgY3VycmVudCBzdHlsZXMgdG8gYXBwbHkgdG8gdGhlIHN1cmZhY2UuXG4gICAgICAgIHRoaXMuc3VyZmFjZVN0eWxlc0ludGVybmFsID0ge1xuICAgICAgICAgICAgJ2Rpc3BsYXknOiAnbm9uZScsXG4gICAgICAgIH07XG4gICAgICAgIC8vIFByZXZpb3VzIHZhbHVlcyBzdG9yZWQgZm9yIGNoYW5nZSBkZXRlY3Rpb24uIE9wZW4gY2hhbmdlIGRldGVjdGlvbiBpc1xuICAgICAgICAvLyBjYWxjdWxhdGVkIHNlcGFyYXRlbHkgc28gaW5pdGlhbGl6ZSBpdCBoZXJlLlxuICAgICAgICB0aGlzLmxhc3RWYWx1ZXMgPSB7XG4gICAgICAgICAgICBpc09wZW46IGZhbHNlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhvc3QuYWRkQ29udHJvbGxlcih0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIFN0eWxlSW5mbyBtYXAgdG8gYXBwbHkgdG8gdGhlIHN1cmZhY2UgdmlhIExpdCdzIHN0eWxlbWFwXG4gICAgICovXG4gICAgZ2V0IHN1cmZhY2VTdHlsZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN1cmZhY2VTdHlsZXNJbnRlcm5hbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgc3VyZmFjZSdzIG5ldyBwb3NpdGlvbiByZXF1aXJlZCBzbyB0aGF0IHRoZSBzdXJmYWNlJ3NcbiAgICAgKiBgc3VyZmFjZUNvcm5lcmAgYWxpZ25zIHRvIHRoZSBhbmNob3IncyBgYW5jaG9yQ29ybmVyYCB3aGlsZSBrZWVwaW5nIHRoZVxuICAgICAqIHN1cmZhY2UgaW5zaWRlIHRoZSB3aW5kb3cgdmlld3BvcnQuIFRoaXMgcG9zaXRpb25pbmcgYWxzbyByZXNwZWN0cyBSVEwgYnlcbiAgICAgKiBjaGVja2luZyBgZ2V0Q29tcHV0ZWRTdHlsZSgpYCBvbiB0aGUgc3VyZmFjZSBlbGVtZW50LlxuICAgICAqL1xuICAgIGFzeW5jIHBvc2l0aW9uKCkge1xuICAgICAgICBjb25zdCB7IHN1cmZhY2VFbCwgYW5jaG9yRWwsIGFuY2hvckNvcm5lcjogYW5jaG9yQ29ybmVyUmF3LCBzdXJmYWNlQ29ybmVyOiBzdXJmYWNlQ29ybmVyUmF3LCBwb3NpdGlvbmluZywgeE9mZnNldCwgeU9mZnNldCwgZGlzYWJsZUJsb2NrRmxpcCwgZGlzYWJsZUlubGluZUZsaXAsIHJlcG9zaXRpb25TdHJhdGVneSwgfSA9IHRoaXMuZ2V0UHJvcGVydGllcygpO1xuICAgICAgICBjb25zdCBhbmNob3JDb3JuZXIgPSBhbmNob3JDb3JuZXJSYXcudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gICAgICAgIGNvbnN0IHN1cmZhY2VDb3JuZXIgPSBzdXJmYWNlQ29ybmVyUmF3LnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICAgICAgICBpZiAoIXN1cmZhY2VFbCB8fCAhYW5jaG9yRWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBTdG9yZSB0aGVzZSBiZWZvcmUgd2UgcG90ZW50aWFsbHkgcmVzaXplIHRoZSB3aW5kb3cgd2l0aCB0aGUgbmV4dCBzZXQgb2ZcbiAgICAgICAgLy8gbGluZXNcbiAgICAgICAgY29uc3Qgd2luZG93SW5uZXJXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgICAgICBjb25zdCB3aW5kb3dJbm5lckhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICAgICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGRpdi5zdHlsZS5vcGFjaXR5ID0gJzAnO1xuICAgICAgICBkaXYuc3R5bGUucG9zaXRpb24gPSAnZml4ZWQnO1xuICAgICAgICBkaXYuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIGRpdi5zdHlsZS5pbnNldCA9ICcwJztcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkaXYpO1xuICAgICAgICBjb25zdCBzY3JvbGxiYXJUZXN0UmVjdCA9IGRpdi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgZGl2LnJlbW92ZSgpO1xuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIHdpZHRocyBvZiB0aGUgc2Nyb2xsYmFycyBpbiB0aGUgaW5saW5lIGFuZCBibG9jayBkaXJlY3Rpb25zXG4gICAgICAgIC8vIHRvIGFjY291bnQgZm9yIHdpbmRvdy1yZWxhdGl2ZSBjYWxjdWxhdGlvbnMuXG4gICAgICAgIGNvbnN0IGJsb2NrU2Nyb2xsYmFySGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0IC0gc2Nyb2xsYmFyVGVzdFJlY3QuYm90dG9tO1xuICAgICAgICBjb25zdCBpbmxpbmVTY3JvbGxiYXJXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoIC0gc2Nyb2xsYmFyVGVzdFJlY3QucmlnaHQ7XG4gICAgICAgIC8vIFBhaW50IHRoZSBzdXJmYWNlIHRyYW5zcGFyZW50bHkgc28gdGhhdCB3ZSBjYW4gZ2V0IHRoZSBwb3NpdGlvbiBhbmQgdGhlXG4gICAgICAgIC8vIHJlY3QgaW5mbyBvZiB0aGUgc3VyZmFjZS5cbiAgICAgICAgdGhpcy5zdXJmYWNlU3R5bGVzSW50ZXJuYWwgPSB7XG4gICAgICAgICAgICAnZGlzcGxheSc6ICdibG9jaycsXG4gICAgICAgICAgICAnb3BhY2l0eSc6ICcwJyxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gV2FpdCBmb3IgaXQgdG8gYmUgdmlzaWJsZS5cbiAgICAgICAgdGhpcy5ob3N0LnJlcXVlc3RVcGRhdGUoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5ob3N0LnVwZGF0ZUNvbXBsZXRlO1xuICAgICAgICAvLyBTYWZhcmkgaGFzIGEgYnVnIHRoYXQgbWFrZXMgcG9wb3ZlcnMgcmVuZGVyIGluY29ycmVjdGx5IGlmIHRoZSBub2RlIGlzXG4gICAgICAgIC8vIG1hZGUgdmlzaWJsZSArIEFuaW1hdGlvbiBGcmFtZSBiZWZvcmUgY2FsbGluZyBzaG93UG9wb3ZlcigpLlxuICAgICAgICAvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjY0MDY5XG4gICAgICAgIC8vIGFsc28gdGhlIGNhc3QgaXMgcmVxdWlyZWQgZHVlIHRvIGRpZmZlcmluZyBUUyB0eXBlcyBpbiBHb29nbGUgYW5kIE9TUy5cbiAgICAgICAgaWYgKHN1cmZhY2VFbC5wb3BvdmVyICYmXG4gICAgICAgICAgICBzdXJmYWNlRWwuaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIHN1cmZhY2VFbC5zaG93UG9wb3ZlcigpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN1cmZhY2VSZWN0ID0gc3VyZmFjZUVsLmdldFN1cmZhY2VQb3NpdGlvbkNsaWVudFJlY3RcbiAgICAgICAgICAgID8gc3VyZmFjZUVsLmdldFN1cmZhY2VQb3NpdGlvbkNsaWVudFJlY3QoKVxuICAgICAgICAgICAgOiBzdXJmYWNlRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IGFuY2hvclJlY3QgPSBhbmNob3JFbC5nZXRTdXJmYWNlUG9zaXRpb25DbGllbnRSZWN0XG4gICAgICAgICAgICA/IGFuY2hvckVsLmdldFN1cmZhY2VQb3NpdGlvbkNsaWVudFJlY3QoKVxuICAgICAgICAgICAgOiBhbmNob3JFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgY29uc3QgW3N1cmZhY2VCbG9jaywgc3VyZmFjZUlubGluZV0gPSBzdXJmYWNlQ29ybmVyLnNwbGl0KCctJyk7XG4gICAgICAgIGNvbnN0IFthbmNob3JCbG9jaywgYW5jaG9ySW5saW5lXSA9IGFuY2hvckNvcm5lci5zcGxpdCgnLScpO1xuICAgICAgICAvLyBMVFIgZGVwZW5kcyBvbiB0aGUgZGlyZWN0aW9uIG9mIHRoZSBTVVJGQUNFIG5vdCB0aGUgYW5jaG9yLlxuICAgICAgICBjb25zdCBpc0xUUiA9IGdldENvbXB1dGVkU3R5bGUoc3VyZmFjZUVsKS5kaXJlY3Rpb24gPT09ICdsdHInO1xuICAgICAgICAvKlxuICAgICAgICAgKiBGb3IgbW9yZSBvbiBpbmxpbmUgYW5kIGJsb2NrIGRpbWVuc2lvbnMsIHNlZSBNRE4gYXJ0aWNsZTpcbiAgICAgICAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0NTU19sb2dpY2FsX3Byb3BlcnRpZXNfYW5kX3ZhbHVlc1xuICAgICAgICAgKlxuICAgICAgICAgKiDilIzilIDilIDilIDilIDilIAgaW5saW5lL2Jsb2NrRG9jdW1lbnRPZmZzZXQgIGlubGluZVNjcm9sbGJhcldpZHRoXG4gICAgICAgICAqIOKUgiAgICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJcbiAgICAgICAgICog4pSCICAgICDilIzilIDilrzilIDilIDilIDilIDilIDilJAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJEb2N1bWVudFxuICAgICAgICAgKiDilIIgICAg4pSM4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS04pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQXG4gICAgICAgICAqIOKUgiAgICDilILilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAg4pSCXG4gICAgICAgICAqIOKUlOKUgOKUgOKWuiDilILilIIg4pSM4pSA4pSA4pSA4pSA4pSAIGlubGluZS9ibG9ja1dpbmRvd09mZnNldCAgICAgIOKUgiAgICAgICAg4pSCXG4gICAgICAgICAqICAgICAg4pSC4pSCIOKUgiAgICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8ICAgICAgICDilIJcbiAgICAgICAgICogICAgICDilILilIIg4pSCICAgICDilIzilIDilrzilIDilIDilIDilJAgICAgICAgICAgICAgICAgIFdpbmRvd+KUjOKUkCAgICAgICAg4pSCXG4gICAgICAgICAqICAgICAg4pSU4pSkIOKUgiAgICDilIzilLzilIDilIDilIDilIDilIDilLTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilLzilIIgICAgICAgIOKUglxuICAgICAgICAgKiAgICAgICDilIIg4pSCICAgIOKUguKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSC4pSCICAgICAgICDilIJcbiAgICAgICAgICogICAgICAg4pSCIOKUlOKUgOKUgOKWuiDilILilIIgIOKUjOKUgOKUgGlubGluZS9ibG9ja0FuY2hvck9mZnNldOKUguKUgiAgICAgICAg4pSCXG4gICAgICAgICAqICAgICAgIOKUgiAgICAgIOKUguKUgiAg4pSCICAgICDilIIgICAgICAgICAgICAgICAgICAgIOKUguKUgiAgICAgICAg4pSCXG4gICAgICAgICAqICAgICAgIOKUgiAgICAgIOKUlOKUpCAg4pSCICDilIzilIDilIDilrzilIDilIDilIDilJAgICAgICAgICAgICAgICAg4pSC4pSCICAgICAgICDilIJcbiAgICAgICAgICogICAgICAg4pSCICAgICAgIOKUgiAg4pSCIOKUjOKUvOKUgOKUgOKUgOKUgOKUgOKUgOKUpCAgICAgICAgICAgICAgICDilILilIIgICAgICAgIOKUglxuICAgICAgICAgKiAgICAgICDilIIgICAgICAg4pSCICDilJTilIDilrrilIJBbmNob3LilIIgICAgICAgICAgICAgICAg4pSC4pSCICAgICAgICDilIJcbiAgICAgICAgICogICAgICAg4pSCICAgICAgIOKUgiAgICDilJTilLTilIDilIDilIDilIDilIDilIDilJggICAgICAgICAgICAgICAg4pSC4pSCICAgICAgICDilIJcbiAgICAgICAgICogICAgICAg4pSCICAgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSC4pSCICAgICAgICDilIJcbiAgICAgICAgICogICAgICAg4pSCICAgICAgIOKUgiAgICAg4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS84pS84pSA4pSA4pSA4pSA4pSQICAg4pSCXG4gICAgICAgICAqICAgICAgIOKUgiAgICAgICDilIIgICAgIOKUgiBTdXJmYWNlICAgICAgICAgICAgICAg4pSC4pSCICAgIOKUgiAgIOKUglxuICAgICAgICAgKiAgICAgICDilIIgICAgICAg4pSCICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgIOKUguKUgiAgICDilIIgICDilIJcbiAgICAgICAgICogICAgICAg4pSCICAgICAgIOKUgiAgICAg4pSCICAgICAgICAgICAgICAgICAgICAgICDilILilIIgICAg4pSCICAg4pSCXG4gICAgICAgICAqICAgICAgIOKUgiAgICAgICDilIIgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAg4pSC4pSCICAgIOKUgiAgIOKUglxuICAgICAgICAgKiAgICAgICDilIIgICAgICAg4pSCICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgIOKUguKUgiAgICDilIIgICDilIJcbiAgICAgICAgICogICAgICAg4pSCICAgICAg4pSM4pS84pSA4pSA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS84pSCICAgIOKUgiAgIOKUglxuICAgICAgICAgKiAgICAgICDilIIgICDilIzilIDilrrilLTilIDilIDilIDilIDilIDilIDilLzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJggICAg4pSc4pSQICDilIJcbiAgICAgICAgICogICAgICAg4pSCICAg4pSCICAgICAgICAg4pSCIGlubGluZS9ibG9ja09PQkNvcnJlY3Rpb24gICDilILilIIgIOKUglxuICAgICAgICAgKiAgICAgICDilIIgICDilIIgICAgICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAg4pSCICAg4pSC4pSCICDilIJcbiAgICAgICAgICogICAgICAg4pSCICAg4pSCICAgICAgICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgIOKUnOKUgOKUgOKWuuKUnOKUgiAg4pSCXG4gICAgICAgICAqICAgICAgIOKUgiAgIOKUgiAgICAgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICDilIIgICDilILilIIgIOKUglxuICAgICAgICAgKiAgICAgICDilIIgICDilIIgICAgICAgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJDilrzilIDilIDilIDilLzilJggIOKUglxuICAgICAgICAgKiAgICAgICDilIIgIGJsb2NrU2Nyb2xsYmFySGVpZ2h0ICAgICAgICAgICAgICAgIOKUlOKUgOKUgOKUgOKUgOKUmCAgIOKUglxuICAgICAgICAgKiAgICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUglxuICAgICAgICAgKiAgICAgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJhcbiAgICAgICAgICovXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgYmxvY2sgcG9zaXRpb25pbmcgcHJvcGVydGllc1xuICAgICAgICBsZXQgeyBibG9ja0luc2V0LCBibG9ja091dE9mQm91bmRzQ29ycmVjdGlvbiwgc3VyZmFjZUJsb2NrUHJvcGVydHkgfSA9IHRoaXMuY2FsY3VsYXRlQmxvY2soe1xuICAgICAgICAgICAgc3VyZmFjZVJlY3QsXG4gICAgICAgICAgICBhbmNob3JSZWN0LFxuICAgICAgICAgICAgYW5jaG9yQmxvY2ssXG4gICAgICAgICAgICBzdXJmYWNlQmxvY2ssXG4gICAgICAgICAgICB5T2Zmc2V0LFxuICAgICAgICAgICAgcG9zaXRpb25pbmcsXG4gICAgICAgICAgICB3aW5kb3dJbm5lckhlaWdodCxcbiAgICAgICAgICAgIGJsb2NrU2Nyb2xsYmFySGVpZ2h0LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gSWYgdGhlIHN1cmZhY2Ugc2hvdWxkIGJlIG91dCBvZiBib3VuZHMgaW4gdGhlIGJsb2NrIGRpcmVjdGlvbiwgZmxpcCB0aGVcbiAgICAgICAgLy8gc3VyZmFjZSBhbmQgYW5jaG9yIGNvcm5lciBibG9jayB2YWx1ZXMgYW5kIHJlY2FsY3VsYXRlXG4gICAgICAgIGlmIChibG9ja091dE9mQm91bmRzQ29ycmVjdGlvbiAmJiAhZGlzYWJsZUJsb2NrRmxpcCkge1xuICAgICAgICAgICAgY29uc3QgZmxpcHBlZFN1cmZhY2VCbG9jayA9IHN1cmZhY2VCbG9jayA9PT0gJ3N0YXJ0JyA/ICdlbmQnIDogJ3N0YXJ0JztcbiAgICAgICAgICAgIGNvbnN0IGZsaXBwZWRBbmNob3JCbG9jayA9IGFuY2hvckJsb2NrID09PSAnc3RhcnQnID8gJ2VuZCcgOiAnc3RhcnQnO1xuICAgICAgICAgICAgY29uc3QgZmxpcHBlZEJsb2NrID0gdGhpcy5jYWxjdWxhdGVCbG9jayh7XG4gICAgICAgICAgICAgICAgc3VyZmFjZVJlY3QsXG4gICAgICAgICAgICAgICAgYW5jaG9yUmVjdCxcbiAgICAgICAgICAgICAgICBhbmNob3JCbG9jazogZmxpcHBlZEFuY2hvckJsb2NrLFxuICAgICAgICAgICAgICAgIHN1cmZhY2VCbG9jazogZmxpcHBlZFN1cmZhY2VCbG9jayxcbiAgICAgICAgICAgICAgICB5T2Zmc2V0LFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uaW5nLFxuICAgICAgICAgICAgICAgIHdpbmRvd0lubmVySGVpZ2h0LFxuICAgICAgICAgICAgICAgIGJsb2NrU2Nyb2xsYmFySGVpZ2h0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBJbiB0aGUgY2FzZSB0aGF0IHRoZSBmbGlwcGVkIHZlcmlvbiB3b3VsZCByZXF1aXJlIGxlc3Mgb3V0IG9mIGJvdW5kc1xuICAgICAgICAgICAgLy8gY29ycmVjdGluZywgdXNlIHRoZSBmbGlwcGVkIGNvcm5lciBibG9jayB2YWx1ZXNcbiAgICAgICAgICAgIGlmIChibG9ja091dE9mQm91bmRzQ29ycmVjdGlvbiA+IGZsaXBwZWRCbG9jay5ibG9ja091dE9mQm91bmRzQ29ycmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGJsb2NrSW5zZXQgPSBmbGlwcGVkQmxvY2suYmxvY2tJbnNldDtcbiAgICAgICAgICAgICAgICBibG9ja091dE9mQm91bmRzQ29ycmVjdGlvbiA9IGZsaXBwZWRCbG9jay5ibG9ja091dE9mQm91bmRzQ29ycmVjdGlvbjtcbiAgICAgICAgICAgICAgICBzdXJmYWNlQmxvY2tQcm9wZXJ0eSA9IGZsaXBwZWRCbG9jay5zdXJmYWNlQmxvY2tQcm9wZXJ0eTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGlubGluZSBwb3NpdGlvbmluZyBwcm9wZXJ0aWVzXG4gICAgICAgIGxldCB7IGlubGluZUluc2V0LCBpbmxpbmVPdXRPZkJvdW5kc0NvcnJlY3Rpb24sIHN1cmZhY2VJbmxpbmVQcm9wZXJ0eSB9ID0gdGhpcy5jYWxjdWxhdGVJbmxpbmUoe1xuICAgICAgICAgICAgc3VyZmFjZVJlY3QsXG4gICAgICAgICAgICBhbmNob3JSZWN0LFxuICAgICAgICAgICAgYW5jaG9ySW5saW5lLFxuICAgICAgICAgICAgc3VyZmFjZUlubGluZSxcbiAgICAgICAgICAgIHhPZmZzZXQsXG4gICAgICAgICAgICBwb3NpdGlvbmluZyxcbiAgICAgICAgICAgIGlzTFRSLFxuICAgICAgICAgICAgd2luZG93SW5uZXJXaWR0aCxcbiAgICAgICAgICAgIGlubGluZVNjcm9sbGJhcldpZHRoLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gSWYgdGhlIHN1cmZhY2Ugc2hvdWxkIGJlIG91dCBvZiBib3VuZHMgaW4gdGhlIGlubGluZSBkaXJlY3Rpb24sIGZsaXAgdGhlXG4gICAgICAgIC8vIHN1cmZhY2UgYW5kIGFuY2hvciBjb3JuZXIgaW5saW5lIHZhbHVlcyBhbmQgcmVjYWxjdWxhdGVcbiAgICAgICAgaWYgKGlubGluZU91dE9mQm91bmRzQ29ycmVjdGlvbiAmJiAhZGlzYWJsZUlubGluZUZsaXApIHtcbiAgICAgICAgICAgIGNvbnN0IGZsaXBwZWRTdXJmYWNlSW5saW5lID0gc3VyZmFjZUlubGluZSA9PT0gJ3N0YXJ0JyA/ICdlbmQnIDogJ3N0YXJ0JztcbiAgICAgICAgICAgIGNvbnN0IGZsaXBwZWRBbmNob3JJbmxpbmUgPSBhbmNob3JJbmxpbmUgPT09ICdzdGFydCcgPyAnZW5kJyA6ICdzdGFydCc7XG4gICAgICAgICAgICBjb25zdCBmbGlwcGVkSW5saW5lID0gdGhpcy5jYWxjdWxhdGVJbmxpbmUoe1xuICAgICAgICAgICAgICAgIHN1cmZhY2VSZWN0LFxuICAgICAgICAgICAgICAgIGFuY2hvclJlY3QsXG4gICAgICAgICAgICAgICAgYW5jaG9ySW5saW5lOiBmbGlwcGVkQW5jaG9ySW5saW5lLFxuICAgICAgICAgICAgICAgIHN1cmZhY2VJbmxpbmU6IGZsaXBwZWRTdXJmYWNlSW5saW5lLFxuICAgICAgICAgICAgICAgIHhPZmZzZXQsXG4gICAgICAgICAgICAgICAgcG9zaXRpb25pbmcsXG4gICAgICAgICAgICAgICAgaXNMVFIsXG4gICAgICAgICAgICAgICAgd2luZG93SW5uZXJXaWR0aCxcbiAgICAgICAgICAgICAgICBpbmxpbmVTY3JvbGxiYXJXaWR0aCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gSW4gdGhlIGNhc2UgdGhhdCB0aGUgZmxpcHBlZCB2ZXJpb24gd291bGQgcmVxdWlyZSBsZXNzIG91dCBvZiBib3VuZHNcbiAgICAgICAgICAgIC8vIGNvcnJlY3RpbmcsIHVzZSB0aGUgZmxpcHBlZCBjb3JuZXIgaW5saW5lIHZhbHVlc1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKGlubGluZU91dE9mQm91bmRzQ29ycmVjdGlvbikgPlxuICAgICAgICAgICAgICAgIE1hdGguYWJzKGZsaXBwZWRJbmxpbmUuaW5saW5lT3V0T2ZCb3VuZHNDb3JyZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgIGlubGluZUluc2V0ID0gZmxpcHBlZElubGluZS5pbmxpbmVJbnNldDtcbiAgICAgICAgICAgICAgICBpbmxpbmVPdXRPZkJvdW5kc0NvcnJlY3Rpb24gPSBmbGlwcGVkSW5saW5lLmlubGluZU91dE9mQm91bmRzQ29ycmVjdGlvbjtcbiAgICAgICAgICAgICAgICBzdXJmYWNlSW5saW5lUHJvcGVydHkgPSBmbGlwcGVkSW5saW5lLnN1cmZhY2VJbmxpbmVQcm9wZXJ0eTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB3ZSBhcmUgc2ltcGx5IHJlcG9zaXRpb25pbmcgdGhlIHN1cmZhY2UgYmFjayBpbnNpZGUgdGhlIHZpZXdwb3J0LFxuICAgICAgICAvLyBzdWJ0cmFjdCB0aGUgb3V0IG9mIGJvdW5kcyBjb3JyZWN0aW9uIHZhbHVlcyBmcm9tIHRoZSBwb3NpdGlvbmluZy5cbiAgICAgICAgaWYgKHJlcG9zaXRpb25TdHJhdGVneSA9PT0gJ21vdmUnKSB7XG4gICAgICAgICAgICBibG9ja0luc2V0ID0gYmxvY2tJbnNldCAtIGJsb2NrT3V0T2ZCb3VuZHNDb3JyZWN0aW9uO1xuICAgICAgICAgICAgaW5saW5lSW5zZXQgPSBpbmxpbmVJbnNldCAtIGlubGluZU91dE9mQm91bmRzQ29ycmVjdGlvbjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN1cmZhY2VTdHlsZXNJbnRlcm5hbCA9IHtcbiAgICAgICAgICAgICdkaXNwbGF5JzogJ2Jsb2NrJyxcbiAgICAgICAgICAgICdvcGFjaXR5JzogJzEnLFxuICAgICAgICAgICAgW3N1cmZhY2VCbG9ja1Byb3BlcnR5XTogYCR7YmxvY2tJbnNldH1weGAsXG4gICAgICAgICAgICBbc3VyZmFjZUlubGluZVByb3BlcnR5XTogYCR7aW5saW5lSW5zZXR9cHhgLFxuICAgICAgICB9O1xuICAgICAgICAvLyBJbiB0aGUgY2FzZSB0aGF0IHdlIGFyZSByZXNpemluZyB0aGUgc3VyZmFjZSB0byBzdGF5IGluc2lkZSB0aGUgdmlld3BvcnRcbiAgICAgICAgLy8gd2UgbmVlZCB0byBzZXQgaGVpZ2h0IGFuZCB3aWR0aCBvbiB0aGUgc3VyZmFjZS5cbiAgICAgICAgaWYgKHJlcG9zaXRpb25TdHJhdGVneSA9PT0gJ3Jlc2l6ZScpIHtcbiAgICAgICAgICAgIC8vIEFkZCBhIGhlaWdodCBwcm9wZXJ0eSB0byB0aGUgc3R5bGVzIGlmIHRoZXJlIGlzIGJsb2NrIGhlaWdodCBjb3JyZWN0aW9uXG4gICAgICAgICAgICBpZiAoYmxvY2tPdXRPZkJvdW5kc0NvcnJlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN1cmZhY2VTdHlsZXNJbnRlcm5hbFsnaGVpZ2h0J10gPSBgJHtzdXJmYWNlUmVjdC5oZWlnaHQgLSBibG9ja091dE9mQm91bmRzQ29ycmVjdGlvbn1weGA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBBZGQgYSB3aWR0aCBwcm9wZXJ0eSB0byB0aGUgc3R5bGVzIGlmIHRoZXJlIGlzIGJsb2NrIGhlaWdodCBjb3JyZWN0aW9uXG4gICAgICAgICAgICBpZiAoaW5saW5lT3V0T2ZCb3VuZHNDb3JyZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdXJmYWNlU3R5bGVzSW50ZXJuYWxbJ3dpZHRoJ10gPSBgJHtzdXJmYWNlUmVjdC53aWR0aCAtIGlubGluZU91dE9mQm91bmRzQ29ycmVjdGlvbn1weGA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ob3N0LnJlcXVlc3RVcGRhdGUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgY3NzIHByb3BlcnR5LCB0aGUgaW5zZXQsIGFuZCB0aGUgb3V0IG9mIGJvdW5kcyBjb3JyZWN0aW9uXG4gICAgICogZm9yIHRoZSBzdXJmYWNlIGluIHRoZSBibG9jayBkaXJlY3Rpb24uXG4gICAgICovXG4gICAgY2FsY3VsYXRlQmxvY2soY29uZmlnKSB7XG4gICAgICAgIGNvbnN0IHsgc3VyZmFjZVJlY3QsIGFuY2hvclJlY3QsIGFuY2hvckJsb2NrLCBzdXJmYWNlQmxvY2ssIHlPZmZzZXQsIHBvc2l0aW9uaW5nLCB3aW5kb3dJbm5lckhlaWdodCwgYmxvY2tTY3JvbGxiYXJIZWlnaHQsIH0gPSBjb25maWc7XG4gICAgICAgIC8vIFdlIHVzZSBudW1iZXIgYm9vbGVhbnMgdG8gbXVsdGlwbHkgdmFsdWVzIHJhdGhlciB0aGFuIGBpZmAgLyB0ZXJuYXJ5XG4gICAgICAgIC8vIHN0YXRlbWVudHMgYmVjYXVzZSBpdCBfaGVhdmlseV8gY3V0cyBkb3duIG9uIG5lc3RpbmcgYW5kIHJlYWRhYmlsaXR5XG4gICAgICAgIGNvbnN0IHJlbGF0aXZlVG9XaW5kb3cgPSBwb3NpdGlvbmluZyA9PT0gJ2ZpeGVkJyB8fCBwb3NpdGlvbmluZyA9PT0gJ2RvY3VtZW50JyA/IDEgOiAwO1xuICAgICAgICBjb25zdCByZWxhdGl2ZVRvRG9jdW1lbnQgPSBwb3NpdGlvbmluZyA9PT0gJ2RvY3VtZW50JyA/IDEgOiAwO1xuICAgICAgICBjb25zdCBpc1N1cmZhY2VCbG9ja1N0YXJ0ID0gc3VyZmFjZUJsb2NrID09PSAnc3RhcnQnID8gMSA6IDA7XG4gICAgICAgIGNvbnN0IGlzU3VyZmFjZUJsb2NrRW5kID0gc3VyZmFjZUJsb2NrID09PSAnZW5kJyA/IDEgOiAwO1xuICAgICAgICBjb25zdCBpc09uZUJsb2NrRW5kID0gYW5jaG9yQmxvY2sgIT09IHN1cmZhY2VCbG9jayA/IDEgOiAwO1xuICAgICAgICAvLyBXaGV0aGVyIG9yIG5vdCB0byBhcHBseSB0aGUgaGVpZ2h0IG9mIHRoZSBhbmNob3JcbiAgICAgICAgY29uc3QgYmxvY2tBbmNob3JPZmZzZXQgPSBpc09uZUJsb2NrRW5kICogYW5jaG9yUmVjdC5oZWlnaHQgKyB5T2Zmc2V0O1xuICAgICAgICAvLyBUaGUgYWJzb2x1dGUgYmxvY2sgcG9zaXRpb24gb2YgdGhlIGFuY2hvciByZWxhdGl2ZSB0byB3aW5kb3dcbiAgICAgICAgY29uc3QgYmxvY2tUb3BMYXllck9mZnNldCA9IGlzU3VyZmFjZUJsb2NrU3RhcnQgKiBhbmNob3JSZWN0LnRvcCArXG4gICAgICAgICAgICBpc1N1cmZhY2VCbG9ja0VuZCAqXG4gICAgICAgICAgICAgICAgKHdpbmRvd0lubmVySGVpZ2h0IC0gYW5jaG9yUmVjdC5ib3R0b20gLSBibG9ja1Njcm9sbGJhckhlaWdodCk7XG4gICAgICAgIGNvbnN0IGJsb2NrRG9jdW1lbnRPZmZzZXQgPSBpc1N1cmZhY2VCbG9ja1N0YXJ0ICogd2luZG93LnNjcm9sbFkgLSBpc1N1cmZhY2VCbG9ja0VuZCAqIHdpbmRvdy5zY3JvbGxZO1xuICAgICAgICAvLyBJZiB0aGUgc3VyZmFjZSdzIGJsb2NrIHdvdWxkIGJlIG91dCBvZiBib3VuZHMgb2YgdGhlIHdpbmRvdywgbW92ZSBpdCBiYWNrXG4gICAgICAgIC8vIGluXG4gICAgICAgIGNvbnN0IGJsb2NrT3V0T2ZCb3VuZHNDb3JyZWN0aW9uID0gTWF0aC5hYnMoTWF0aC5taW4oMCwgd2luZG93SW5uZXJIZWlnaHQgLVxuICAgICAgICAgICAgYmxvY2tUb3BMYXllck9mZnNldCAtXG4gICAgICAgICAgICBibG9ja0FuY2hvck9mZnNldCAtXG4gICAgICAgICAgICBzdXJmYWNlUmVjdC5oZWlnaHQpKTtcbiAgICAgICAgLy8gVGhlIGJsb2NrIGxvZ2ljYWwgdmFsdWUgb2YgdGhlIHN1cmZhY2VcbiAgICAgICAgY29uc3QgYmxvY2tJbnNldCA9IHJlbGF0aXZlVG9XaW5kb3cgKiBibG9ja1RvcExheWVyT2Zmc2V0ICtcbiAgICAgICAgICAgIHJlbGF0aXZlVG9Eb2N1bWVudCAqIGJsb2NrRG9jdW1lbnRPZmZzZXQgK1xuICAgICAgICAgICAgYmxvY2tBbmNob3JPZmZzZXQ7XG4gICAgICAgIGNvbnN0IHN1cmZhY2VCbG9ja1Byb3BlcnR5ID0gc3VyZmFjZUJsb2NrID09PSAnc3RhcnQnID8gJ2luc2V0LWJsb2NrLXN0YXJ0JyA6ICdpbnNldC1ibG9jay1lbmQnO1xuICAgICAgICByZXR1cm4geyBibG9ja0luc2V0LCBibG9ja091dE9mQm91bmRzQ29ycmVjdGlvbiwgc3VyZmFjZUJsb2NrUHJvcGVydHkgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgY3NzIHByb3BlcnR5LCB0aGUgaW5zZXQsIGFuZCB0aGUgb3V0IG9mIGJvdW5kcyBjb3JyZWN0aW9uXG4gICAgICogZm9yIHRoZSBzdXJmYWNlIGluIHRoZSBpbmxpbmUgZGlyZWN0aW9uLlxuICAgICAqL1xuICAgIGNhbGN1bGF0ZUlubGluZShjb25maWcpIHtcbiAgICAgICAgY29uc3QgeyBpc0xUUjogaXNMVFJCb29sLCBzdXJmYWNlSW5saW5lLCBhbmNob3JJbmxpbmUsIGFuY2hvclJlY3QsIHN1cmZhY2VSZWN0LCB4T2Zmc2V0LCBwb3NpdGlvbmluZywgd2luZG93SW5uZXJXaWR0aCwgaW5saW5lU2Nyb2xsYmFyV2lkdGgsIH0gPSBjb25maWc7XG4gICAgICAgIC8vIFdlIHVzZSBudW1iZXIgYm9vbGVhbnMgdG8gbXVsdGlwbHkgdmFsdWVzIHJhdGhlciB0aGFuIGBpZmAgLyB0ZXJuYXJ5XG4gICAgICAgIC8vIHN0YXRlbWVudHMgYmVjYXVzZSBpdCBfaGVhdmlseV8gY3V0cyBkb3duIG9uIG5lc3RpbmcgYW5kIHJlYWRhYmlsaXR5XG4gICAgICAgIGNvbnN0IHJlbGF0aXZlVG9XaW5kb3cgPSBwb3NpdGlvbmluZyA9PT0gJ2ZpeGVkJyB8fCBwb3NpdGlvbmluZyA9PT0gJ2RvY3VtZW50JyA/IDEgOiAwO1xuICAgICAgICBjb25zdCByZWxhdGl2ZVRvRG9jdW1lbnQgPSBwb3NpdGlvbmluZyA9PT0gJ2RvY3VtZW50JyA/IDEgOiAwO1xuICAgICAgICBjb25zdCBpc0xUUiA9IGlzTFRSQm9vbCA/IDEgOiAwO1xuICAgICAgICBjb25zdCBpc1JUTCA9IGlzTFRSQm9vbCA/IDAgOiAxO1xuICAgICAgICBjb25zdCBpc1N1cmZhY2VJbmxpbmVTdGFydCA9IHN1cmZhY2VJbmxpbmUgPT09ICdzdGFydCcgPyAxIDogMDtcbiAgICAgICAgY29uc3QgaXNTdXJmYWNlSW5saW5lRW5kID0gc3VyZmFjZUlubGluZSA9PT0gJ2VuZCcgPyAxIDogMDtcbiAgICAgICAgY29uc3QgaXNPbmVJbmxpbmVFbmQgPSBhbmNob3JJbmxpbmUgIT09IHN1cmZhY2VJbmxpbmUgPyAxIDogMDtcbiAgICAgICAgLy8gV2hldGhlciBvciBub3QgdG8gYXBwbHkgdGhlIHdpZHRoIG9mIHRoZSBhbmNob3JcbiAgICAgICAgY29uc3QgaW5saW5lQW5jaG9yT2Zmc2V0ID0gaXNPbmVJbmxpbmVFbmQgKiBhbmNob3JSZWN0LndpZHRoICsgeE9mZnNldDtcbiAgICAgICAgLy8gVGhlIGlubGluZSBwb3NpdGlvbiBvZiB0aGUgYW5jaG9yIHJlbGF0aXZlIHRvIHdpbmRvdyBpbiBMVFJcbiAgICAgICAgY29uc3QgaW5saW5lVG9wTGF5ZXJPZmZzZXRMVFIgPSBpc1N1cmZhY2VJbmxpbmVTdGFydCAqIGFuY2hvclJlY3QubGVmdCArXG4gICAgICAgICAgICBpc1N1cmZhY2VJbmxpbmVFbmQgKlxuICAgICAgICAgICAgICAgICh3aW5kb3dJbm5lcldpZHRoIC0gYW5jaG9yUmVjdC5yaWdodCAtIGlubGluZVNjcm9sbGJhcldpZHRoKTtcbiAgICAgICAgLy8gVGhlIGlubGluZSBwb3NpdGlvbiBvZiB0aGUgYW5jaG9yIHJlbGF0aXZlIHRvIHdpbmRvdyBpbiBSVExcbiAgICAgICAgY29uc3QgaW5saW5lVG9wTGF5ZXJPZmZzZXRSVEwgPSBpc1N1cmZhY2VJbmxpbmVTdGFydCAqXG4gICAgICAgICAgICAod2luZG93SW5uZXJXaWR0aCAtIGFuY2hvclJlY3QucmlnaHQgLSBpbmxpbmVTY3JvbGxiYXJXaWR0aCkgK1xuICAgICAgICAgICAgaXNTdXJmYWNlSW5saW5lRW5kICogYW5jaG9yUmVjdC5sZWZ0O1xuICAgICAgICAvLyBUaGUgaW5saW5lIHBvc2l0aW9uIG9mIHRoZSBhbmNob3IgcmVsYXRpdmUgdG8gd2luZG93XG4gICAgICAgIGNvbnN0IGlubGluZVRvcExheWVyT2Zmc2V0ID0gaXNMVFIgKiBpbmxpbmVUb3BMYXllck9mZnNldExUUiArIGlzUlRMICogaW5saW5lVG9wTGF5ZXJPZmZzZXRSVEw7XG4gICAgICAgIC8vIFRoZSBpbmxpbmUgcG9zaXRpb24gb2YgdGhlIGFuY2hvciByZWxhdGl2ZSB0byB3aW5kb3cgaW4gTFRSXG4gICAgICAgIGNvbnN0IGlubGluZURvY3VtZW50T2Zmc2V0TFRSID0gaXNTdXJmYWNlSW5saW5lU3RhcnQgKiB3aW5kb3cuc2Nyb2xsWCAtXG4gICAgICAgICAgICBpc1N1cmZhY2VJbmxpbmVFbmQgKiB3aW5kb3cuc2Nyb2xsWDtcbiAgICAgICAgLy8gVGhlIGlubGluZSBwb3NpdGlvbiBvZiB0aGUgYW5jaG9yIHJlbGF0aXZlIHRvIHdpbmRvdyBpbiBSVExcbiAgICAgICAgY29uc3QgaW5saW5lRG9jdW1lbnRPZmZzZXRSVEwgPSBpc1N1cmZhY2VJbmxpbmVFbmQgKiB3aW5kb3cuc2Nyb2xsWCAtXG4gICAgICAgICAgICBpc1N1cmZhY2VJbmxpbmVTdGFydCAqIHdpbmRvdy5zY3JvbGxYO1xuICAgICAgICAvLyBUaGUgaW5saW5lIHBvc2l0aW9uIG9mIHRoZSBhbmNob3IgcmVsYXRpdmUgdG8gd2luZG93XG4gICAgICAgIGNvbnN0IGlubGluZURvY3VtZW50T2Zmc2V0ID0gaXNMVFIgKiBpbmxpbmVEb2N1bWVudE9mZnNldExUUiArIGlzUlRMICogaW5saW5lRG9jdW1lbnRPZmZzZXRSVEw7XG4gICAgICAgIC8vIElmIHRoZSBzdXJmYWNlJ3MgaW5saW5lIHdvdWxkIGJlIG91dCBvZiBib3VuZHMgb2YgdGhlIHdpbmRvdywgbW92ZSBpdFxuICAgICAgICAvLyBiYWNrIGluXG4gICAgICAgIGNvbnN0IGlubGluZU91dE9mQm91bmRzQ29ycmVjdGlvbiA9IE1hdGguYWJzKE1hdGgubWluKDAsIHdpbmRvd0lubmVyV2lkdGggLVxuICAgICAgICAgICAgaW5saW5lVG9wTGF5ZXJPZmZzZXQgLVxuICAgICAgICAgICAgaW5saW5lQW5jaG9yT2Zmc2V0IC1cbiAgICAgICAgICAgIHN1cmZhY2VSZWN0LndpZHRoKSk7XG4gICAgICAgIC8vIFRoZSBpbmxpbmUgbG9naWNhbCB2YWx1ZSBvZiB0aGUgc3VyZmFjZVxuICAgICAgICBjb25zdCBpbmxpbmVJbnNldCA9IHJlbGF0aXZlVG9XaW5kb3cgKiBpbmxpbmVUb3BMYXllck9mZnNldCArXG4gICAgICAgICAgICBpbmxpbmVBbmNob3JPZmZzZXQgK1xuICAgICAgICAgICAgcmVsYXRpdmVUb0RvY3VtZW50ICogaW5saW5lRG9jdW1lbnRPZmZzZXQ7XG4gICAgICAgIGxldCBzdXJmYWNlSW5saW5lUHJvcGVydHkgPSBzdXJmYWNlSW5saW5lID09PSAnc3RhcnQnID8gJ2luc2V0LWlubGluZS1zdGFydCcgOiAnaW5zZXQtaW5saW5lLWVuZCc7XG4gICAgICAgIC8vIFRoZXJlIGFyZSBjYXNlcyB3aGVyZSB0aGUgZWxlbWVudCBpcyBSVEwgYnV0IHRoZSByb290IG9mIHRoZSBwYWdlIGlzIG5vdC5cbiAgICAgICAgLy8gSW4gdGhlc2UgY2FzZXMgd2Ugd2FudCB0byBub3QgdXNlIGxvZ2ljYWwgcHJvcGVydGllcy5cbiAgICAgICAgaWYgKHBvc2l0aW9uaW5nID09PSAnZG9jdW1lbnQnIHx8IHBvc2l0aW9uaW5nID09PSAnZml4ZWQnKSB7XG4gICAgICAgICAgICBpZiAoKHN1cmZhY2VJbmxpbmUgPT09ICdzdGFydCcgJiYgaXNMVFJCb29sKSB8fFxuICAgICAgICAgICAgICAgIChzdXJmYWNlSW5saW5lID09PSAnZW5kJyAmJiAhaXNMVFJCb29sKSkge1xuICAgICAgICAgICAgICAgIHN1cmZhY2VJbmxpbmVQcm9wZXJ0eSA9ICdsZWZ0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHN1cmZhY2VJbmxpbmVQcm9wZXJ0eSA9ICdyaWdodCc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlubGluZUluc2V0LFxuICAgICAgICAgICAgaW5saW5lT3V0T2ZCb3VuZHNDb3JyZWN0aW9uLFxuICAgICAgICAgICAgc3VyZmFjZUlubGluZVByb3BlcnR5LFxuICAgICAgICB9O1xuICAgIH1cbiAgICBob3N0VXBkYXRlKCkge1xuICAgICAgICB0aGlzLm9uVXBkYXRlKCk7XG4gICAgfVxuICAgIGhvc3RVcGRhdGVkKCkge1xuICAgICAgICB0aGlzLm9uVXBkYXRlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBwcm9wZXJ0aWVzIHBhc3NlZCBpbnRvIHRoZSBjb250cm9sbGVyIGhhdmUgY2hhbmdlZCBzaW5jZVxuICAgICAqIHRoZSBsYXN0IHBvc2l0aW9uaW5nLiBJZiBzbywgaXQgd2lsbCByZXBvc2l0aW9uIGlmIHRoZSBzdXJmYWNlIGlzIG9wZW4gb3JcbiAgICAgKiBjbG9zZSBpdCBpZiB0aGUgc3VyZmFjZSBzaG91bGQgY2xvc2UuXG4gICAgICovXG4gICAgYXN5bmMgb25VcGRhdGUoKSB7XG4gICAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5nZXRQcm9wZXJ0aWVzKCk7XG4gICAgICAgIGxldCBoYXNDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzKSkge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG4gICAgICAgICAgICBoYXNDaGFuZ2VkID0gaGFzQ2hhbmdlZCB8fCB2YWx1ZSAhPT0gdGhpcy5sYXN0VmFsdWVzW2tleV07XG4gICAgICAgICAgICBpZiAoaGFzQ2hhbmdlZClcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcGVuQ2hhbmdlZCA9IHRoaXMubGFzdFZhbHVlcy5pc09wZW4gIT09IHByb3BzLmlzT3BlbjtcbiAgICAgICAgY29uc3QgaGFzQW5jaG9yID0gISFwcm9wcy5hbmNob3JFbDtcbiAgICAgICAgY29uc3QgaGFzU3VyZmFjZSA9ICEhcHJvcHMuc3VyZmFjZUVsO1xuICAgICAgICBpZiAoaGFzQ2hhbmdlZCAmJiBoYXNBbmNob3IgJiYgaGFzU3VyZmFjZSkge1xuICAgICAgICAgICAgLy8gT25seSB1cGRhdGUgaXNPcGVuLCBiZWNhdXNlIGlmIGl0J3MgY2xvc2VkLCB3ZSBkbyBub3Qgd2FudCB0byB3YXN0ZVxuICAgICAgICAgICAgLy8gdGltZSBvbiBhIHVzZWxlc3MgcmVwb3NpdGlvbiBjYWxjdWxhdGlvbi4gU28gc2F2ZSB0aGUgb3RoZXIgXCJkaXJ0eVwiXG4gICAgICAgICAgICAvLyB2YWx1ZXMgdW50aWwgbmV4dCB0aW1lIGl0IG9wZW5zLlxuICAgICAgICAgICAgdGhpcy5sYXN0VmFsdWVzLmlzT3BlbiA9IHByb3BzLmlzT3BlbjtcbiAgICAgICAgICAgIGlmIChwcm9wcy5pc09wZW4pIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBhcmUgZ29pbmcgdG8gZG8gYSByZXBvc2l0aW9uLCBzbyBzYXZlIHRoZSBwcm9wIHZhbHVlcyBmb3IgZnV0dXJlXG4gICAgICAgICAgICAgICAgLy8gZGlydHkgY2hlY2tpbmcuXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0VmFsdWVzID0gcHJvcHM7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wb3NpdGlvbigpO1xuICAgICAgICAgICAgICAgIHByb3BzLm9uT3BlbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAob3BlbkNoYW5nZWQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBwcm9wcy5iZWZvcmVDbG9zZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICBwcm9wcy5vbkNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZXMgdGhlIHN1cmZhY2UuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHRoaXMuc3VyZmFjZVN0eWxlc0ludGVybmFsID0ge1xuICAgICAgICAgICAgJ2Rpc3BsYXknOiAnbm9uZScsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaG9zdC5yZXF1ZXN0VXBkYXRlKCk7XG4gICAgICAgIGNvbnN0IHN1cmZhY2VFbCA9IHRoaXMuZ2V0UHJvcGVydGllcygpLnN1cmZhY2VFbDtcbiAgICAgICAgLy8gVGhlIGZvbGxvd2luZyB0eXBlIGNhc3RzIGFyZSByZXF1aXJlZCBkdWUgdG8gZGlmZmVyaW5nIFRTIHR5cGVzIGluIEdvb2dsZVxuICAgICAgICAvLyBhbmQgb3BlbiBzb3VyY2UuXG4gICAgICAgIGlmIChzdXJmYWNlRWw/LnBvcG92ZXIgJiZcbiAgICAgICAgICAgIHN1cmZhY2VFbD8uaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIHN1cmZhY2VFbC5oaWRlUG9wb3ZlcigpO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3VyZmFjZVBvc2l0aW9uQ29udHJvbGxlci5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG4vKipcbiAqIEluZGljaWVzIHRvIGFjY2VzcyB0aGUgVHlwZWFoZWFkUmVjb3JkIHR1cGxlIHR5cGUuXG4gKi9cbmV4cG9ydCBjb25zdCBUWVBFQUhFQURfUkVDT1JEID0ge1xuICAgIElOREVYOiAwLFxuICAgIElURU06IDEsXG4gICAgVEVYVDogMixcbn07XG4vKipcbiAqIFRoaXMgY29udHJvbGxlciBsaXN0ZW5zIHRvIGBrZXlkb3duYCBldmVudHMgYW5kIHNlYXJjaGVzIHRoZSBoZWFkZXIgdGV4dCBvZlxuICogYW4gYXJyYXkgb2YgYE1lbnVJdGVtYHMgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBlbnRlcmVkIGtleXMgd2l0aGluIHRoZSBidWZmZXJcbiAqIHRpbWUgYW5kIGFjdGl2YXRlcyB0aGUgaXRlbS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGNvbnN0IHR5cGVhaGVhZENvbnRyb2xsZXIgPSBuZXcgVHlwZWFoZWFkQ29udHJvbGxlcigoKSA9PiAoe1xuICogICB0eXBlYWhlYWRCdWZmZXJUaW1lOiA1MCxcbiAqICAgZ2V0SXRlbXM6ICgpID0+IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnbWQtbWVudS1pdGVtJykpXG4gKiB9KSk7XG4gKiBodG1sYFxuICogICA8ZGl2XG4gKiAgICAgICBAa2V5ZG93bj0ke3R5cGVhaGVhZENvbnRyb2xsZXIub25LZXlkb3dufVxuICogICAgICAgdGFiaW5kZXg9XCIwXCJcbiAqICAgICAgIGNsYXNzPVwiYWN0aXZlSXRlbVRleHRcIj5cbiAqICAgICA8IS0tIGZvY3VzYWJsZSBlbGVtZW50IHRoYXQgd2lsbCByZWNlaXZlIGtleWRvd24gZXZlbnRzIC0tPlxuICogICAgIEFwcGxlXG4gKiAgIDwvZGl2PlxuICogICA8ZGl2PlxuICogICAgIDxtZC1tZW51LWl0ZW0gYWN0aXZlIGhlYWRlcj1cIkFwcGxlXCI+PC9tZC1tZW51LWl0ZW0+XG4gKiAgICAgPG1kLW1lbnUtaXRlbSBoZWFkZXI9XCJBcHJpY290XCI+PC9tZC1tZW51LWl0ZW0+XG4gKiAgICAgPG1kLW1lbnUtaXRlbSBoZWFkZXI9XCJCYW5hbmFcIj48L21kLW1lbnUtaXRlbT5cbiAqICAgICA8bWQtbWVudS1pdGVtIGhlYWRlcj1cIk9saXZlXCI+PC9tZC1tZW51LWl0ZW0+XG4gKiAgICAgPG1kLW1lbnUtaXRlbSBoZWFkZXI9XCJPcmFuZ2VcIj48L21kLW1lbnUtaXRlbT5cbiAqICAgPC9kaXY+XG4gKiBgO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBUeXBlYWhlYWRDb250cm9sbGVyIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZ2V0UHJvcGVydGllcyBBIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgb3B0aW9ucyBvZiB0aGUgdHlwZWFoZWFkXG4gICAgICogY29udHJvbGxlcjpcbiAgICAgKlxuICAgICAqIHtcbiAgICAgKiAgIGdldEl0ZW1zOiBBIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhbiBhcnJheSBvZiBtZW51IGl0ZW1zIHRvIGJlIHNlYXJjaGVkLlxuICAgICAqICAgdHlwZWFoZWFkQnVmZmVyVGltZTogVGhlIG1heGltdW0gdGltZSBiZXR3ZWVuIGVhY2gga2V5c3Ryb2tlIHRvIGtlZXAgdGhlXG4gICAgICogICAgICAgY3VycmVudCB0eXBlIGJ1ZmZlciBhbGl2ZS5cbiAgICAgKiB9XG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZ2V0UHJvcGVydGllcykge1xuICAgICAgICB0aGlzLmdldFByb3BlcnRpZXMgPSBnZXRQcm9wZXJ0aWVzO1xuICAgICAgICAvKipcbiAgICAgICAgICogQXJyYXkgb2YgdHVwbGVzIHRoYXQgaGVscHMgd2l0aCBpbmRleGluZy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudHlwZWFoZWFkUmVjb3JkcyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ3VycmVudGx5LXR5cGVkIHRleHQgc2luY2UgbGFzdCBidWZmZXIgdGltZW91dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy50eXBhaGVhZEJ1ZmZlciA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWVvdXQgaWQgZnJvbSB0aGUgY3VycmVudCBidWZmZXIncyBzZXRUaW1lb3V0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmNhbmNlbFR5cGVhaGVhZFRpbWVvdXQgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgd2UgYXJlIGN1cnJlbnRseSBcInR5cGluZ1wiXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzVHlwaW5nQWhlYWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSByZWNvcmQgb2YgdGhlIGxhc3QgYWN0aXZlIGl0ZW0uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmxhc3RBY3RpdmVSZWNvcmQgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgICogQXBwbHkgdGhpcyBsaXN0ZW5lciB0byB0aGUgZWxlbWVudCB0aGF0IHdpbGwgcmVjZWl2ZSBga2V5ZG93bmAgZXZlbnRzIHRoYXRcbiAgICAgICAgICogc2hvdWxkIHRyaWdnZXIgdGhpcyBjb250cm9sbGVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZXZlbnQgVGhlIG5hdGl2ZSBicm93c2VyIGBLZXlib2FyZEV2ZW50YCBmcm9tIHRoZSBga2V5ZG93bmAgZXZlbnQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uS2V5ZG93biA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNUeXBpbmdBaGVhZCkge1xuICAgICAgICAgICAgICAgIHRoaXMudHlwZWFoZWFkKGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuYmVnaW5UeXBlYWhlYWQoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogRW5kcyB0aGUgY3VycmVudCB0eXBlYWhlYWQgYW5kIGNsZWFycyB0aGUgYnVmZmVyLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5lbmRUeXBlYWhlYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmlzVHlwaW5nQWhlYWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudHlwYWhlYWRCdWZmZXIgPSAnJztcbiAgICAgICAgICAgIHRoaXMudHlwZWFoZWFkUmVjb3JkcyA9IFtdO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBnZXQgaXRlbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFByb3BlcnRpZXMoKS5nZXRJdGVtcygpO1xuICAgIH1cbiAgICBnZXQgYWN0aXZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQcm9wZXJ0aWVzKCkuYWN0aXZlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHVwIHR5cGluZ2FoZWFkXG4gICAgICovXG4gICAgYmVnaW5UeXBlYWhlYWQoZXZlbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gdHlwZWFoZWFkIGlmIHRoZSBfYmVnaW5uaW5nXyBvZiB0aGUgdHlwZWFoZWFkIGlzIGEgbWVudVxuICAgICAgICAvLyBuYXZpZ2F0aW9uLCBvciBhIHNlbGVjdGlvbi4gV2Ugd2lsbCBoYW5kbGUgXCJTcGFjZVwiIG9ubHkgaWYgaXQncyBpbiB0aGVcbiAgICAgICAgLy8gbWlkZGxlIG9mIGEgdHlwZWFoZWFkXG4gICAgICAgIGlmIChldmVudC5jb2RlID09PSAnU3BhY2UnIHx8XG4gICAgICAgICAgICBldmVudC5jb2RlID09PSAnRW50ZXInIHx8XG4gICAgICAgICAgICBldmVudC5jb2RlLnN0YXJ0c1dpdGgoJ0Fycm93JykgfHxcbiAgICAgICAgICAgIGV2ZW50LmNvZGUgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pc1R5cGluZ0FoZWFkID0gdHJ1ZTtcbiAgICAgICAgLy8gR2VuZXJhdGVzIHRoZSByZWNvcmQgYXJyYXkgZGF0YSBzdHJ1Y3R1cmUgd2hpY2ggaXMgdGhlIGluZGV4LCB0aGUgZWxlbWVudFxuICAgICAgICAvLyBhbmQgYSBub3JtYWxpemVkIGhlYWRlci5cbiAgICAgICAgdGhpcy50eXBlYWhlYWRSZWNvcmRzID0gdGhpcy5pdGVtcy5tYXAoKGVsLCBpbmRleCkgPT4gW1xuICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIGVsLnR5cGVhaGVhZFRleHQudHJpbSgpLnRvTG93ZXJDYXNlKCksXG4gICAgICAgIF0pO1xuICAgICAgICB0aGlzLmxhc3RBY3RpdmVSZWNvcmQgPVxuICAgICAgICAgICAgdGhpcy50eXBlYWhlYWRSZWNvcmRzLmZpbmQoKHJlY29yZCkgPT4gcmVjb3JkW1RZUEVBSEVBRF9SRUNPUkQuSVRFTV0udGFiSW5kZXggPT09IDApID8/IG51bGw7XG4gICAgICAgIGlmICh0aGlzLmxhc3RBY3RpdmVSZWNvcmQpIHtcbiAgICAgICAgICAgIHRoaXMubGFzdEFjdGl2ZVJlY29yZFtUWVBFQUhFQURfUkVDT1JELklURU1dLnRhYkluZGV4ID0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50eXBlYWhlYWQoZXZlbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyB0aGUgdHlwZWFoZWFkLiBCYXNlZCBvbiB0aGUgbm9ybWFsaXplZCBpdGVtcyBhbmQgdGhlIGN1cnJlbnQgdGV4dFxuICAgICAqIGJ1ZmZlciwgZmluZHMgdGhlIF9uZXh0XyBpdGVtIHdpdGggbWF0Y2hpbmcgdGV4dCBhbmQgYWN0aXZhdGVzIGl0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGl0ZW1zOiBBcHBsZSwgQmFuYW5hLCBPbGl2ZSwgT3JhbmdlLCBDdWN1bWJlclxuICAgICAqIGJ1ZmZlcjogJydcbiAgICAgKiB1c2VyIHR5cGVzOiBvXG4gICAgICpcbiAgICAgKiBhY3RpdmF0ZXMgT2xpdmVcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBpdGVtczogQXBwbGUsIEJhbmFuYSwgT2xpdmUgKGFjdGl2ZSksIE9yYW5nZSwgQ3VjdW1iZXJcbiAgICAgKiBidWZmZXI6ICdvJ1xuICAgICAqIHVzZXIgdHlwZXM6IGxcbiAgICAgKlxuICAgICAqIGFjdGl2YXRlcyBPbGl2ZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGl0ZW1zOiBBcHBsZSwgQmFuYW5hLCBPbGl2ZSAoYWN0aXZlKSwgT3JhbmdlLCBDdWN1bWJlclxuICAgICAqIGJ1ZmZlcjogJydcbiAgICAgKiB1c2VyIHR5cGVzOiBvXG4gICAgICpcbiAgICAgKiBhY3RpdmF0ZXMgT3JhbmdlXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogaXRlbXM6IEFwcGxlLCBCYW5hbmEsIE9saXZlLCBPcmFuZ2UgKGFjdGl2ZSksIEN1Y3VtYmVyXG4gICAgICogYnVmZmVyOiAnJ1xuICAgICAqIHVzZXIgdHlwZXM6IG9cbiAgICAgKlxuICAgICAqIGFjdGl2YXRlcyBPbGl2ZVxuICAgICAqL1xuICAgIHR5cGVhaGVhZChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuZGVmYXVsdFByZXZlbnRlZClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuY2FuY2VsVHlwZWFoZWFkVGltZW91dCk7XG4gICAgICAgIC8vIFN0b3AgdHlwaW5nYWhlYWQgaWYgb25lIG9mIHRoZSBuYXZpZ2F0aW9uIG9yIHNlbGVjdGlvbiBrZXlzIChleGNlcHQgZm9yXG4gICAgICAgIC8vIFNwYWNlKSBhcmUgcHJlc3NlZFxuICAgICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0VudGVyJyB8fFxuICAgICAgICAgICAgZXZlbnQuY29kZS5zdGFydHNXaXRoKCdBcnJvdycpIHx8XG4gICAgICAgICAgICBldmVudC5jb2RlID09PSAnRXNjYXBlJykge1xuICAgICAgICAgICAgdGhpcy5lbmRUeXBlYWhlYWQoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmxhc3RBY3RpdmVSZWNvcmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RBY3RpdmVSZWNvcmRbVFlQRUFIRUFEX1JFQ09SRC5JVEVNXS50YWJJbmRleCA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIFNwYWNlIGlzIHByZXNzZWQsIHByZXZlbnQgaXQgZnJvbSBzZWxlY3RpbmcgYW5kIGNsb3NpbmcgdGhlIG1lbnVcbiAgICAgICAgaWYgKGV2ZW50LmNvZGUgPT09ICdTcGFjZScpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU3RhcnQgdXAgYSBuZXcga2V5c3Ryb2tlIGJ1ZmZlciB0aW1lb3V0XG4gICAgICAgIHRoaXMuY2FuY2VsVHlwZWFoZWFkVGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5lbmRUeXBlYWhlYWQsIHRoaXMuZ2V0UHJvcGVydGllcygpLnR5cGVhaGVhZEJ1ZmZlclRpbWUpO1xuICAgICAgICB0aGlzLnR5cGFoZWFkQnVmZmVyICs9IGV2ZW50LmtleS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBjb25zdCBsYXN0QWN0aXZlSW5kZXggPSB0aGlzLmxhc3RBY3RpdmVSZWNvcmRcbiAgICAgICAgICAgID8gdGhpcy5sYXN0QWN0aXZlUmVjb3JkW1RZUEVBSEVBRF9SRUNPUkQuSU5ERVhdXG4gICAgICAgICAgICA6IC0xO1xuICAgICAgICBjb25zdCBudW1SZWNvcmRzID0gdGhpcy50eXBlYWhlYWRSZWNvcmRzLmxlbmd0aDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNvcnRpbmcgZnVuY3Rpb24gdGhhdCB3aWxsIHJlc29ydCB0aGUgaXRlbXMgc3RhcnRpbmcgd2l0aCB0aGUgZ2l2ZW4gaW5kZXhcbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogdGhpcy50eXBlYWhlYWRSZWNvcmRzID1cbiAgICAgICAgICogMDogWzAsIDxyZWZlcmVuY2U+LCAnYXBwbGUnXVxuICAgICAgICAgKiAxOiBbMSwgPHJlZmVyZW5jZT4sICdhcHJpY290J11cbiAgICAgICAgICogMjogWzIsIDxyZWZlcmVuY2U+LCAnYmFuYW5hJ11cbiAgICAgICAgICogMzogWzMsIDxyZWZlcmVuY2U+LCAnb2xpdmUnXSA8LS0gbGFzdEFjdGl2ZUluZGV4XG4gICAgICAgICAqIDQ6IFs0LCA8cmVmZXJlbmNlPiwgJ29yYW5nZSddXG4gICAgICAgICAqIDU6IFs1LCA8cmVmZXJlbmNlPiwgJ3N0cmF3YmVycnknXVxuICAgICAgICAgKlxuICAgICAgICAgKiB0aGlzLnR5cGVhaGVhZFJlY29yZHMuc29ydCgoYSxiKSA9PiByZWJhc2VJbmRleE9uQWN0aXZlKGEpXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSByZWJhc2VJbmRleE9uQWN0aXZlKGIpKSA9PT1cbiAgICAgICAgICogMDogWzMsIDxyZWZlcmVuY2U+LCAnb2xpdmUnXSA8LS0gbGFzdEFjdGl2ZUluZGV4XG4gICAgICAgICAqIDE6IFs0LCA8cmVmZXJlbmNlPiwgJ29yYW5nZSddXG4gICAgICAgICAqIDI6IFs1LCA8cmVmZXJlbmNlPiwgJ3N0cmF3YmVycnknXVxuICAgICAgICAgKiAzOiBbMCwgPHJlZmVyZW5jZT4sICdhcHBsZSddXG4gICAgICAgICAqIDQ6IFsxLCA8cmVmZXJlbmNlPiwgJ2Fwcmljb3QnXVxuICAgICAgICAgKiA1OiBbMiwgPHJlZmVyZW5jZT4sICdiYW5hbmEnXVxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgcmViYXNlSW5kZXhPbkFjdGl2ZSA9IChyZWNvcmQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoKHJlY29yZFtUWVBFQUhFQURfUkVDT1JELklOREVYXSArIG51bVJlY29yZHMgLSBsYXN0QWN0aXZlSW5kZXgpICVcbiAgICAgICAgICAgICAgICBudW1SZWNvcmRzKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gcmVjb3JkcyBmaWx0ZXJlZCBhbmQgc29ydGVkIC8gcmViYXNlZCBhcm91bmQgdGhlIGxhc3QgYWN0aXZlIGluZGV4XG4gICAgICAgIGNvbnN0IG1hdGNoaW5nUmVjb3JkcyA9IHRoaXMudHlwZWFoZWFkUmVjb3Jkc1xuICAgICAgICAgICAgLmZpbHRlcigocmVjb3JkKSA9PiAhcmVjb3JkW1RZUEVBSEVBRF9SRUNPUkQuSVRFTV0uZGlzYWJsZWQgJiZcbiAgICAgICAgICAgIHJlY29yZFtUWVBFQUhFQURfUkVDT1JELlRFWFRdLnN0YXJ0c1dpdGgodGhpcy50eXBhaGVhZEJ1ZmZlcikpXG4gICAgICAgICAgICAuc29ydCgoYSwgYikgPT4gcmViYXNlSW5kZXhPbkFjdGl2ZShhKSAtIHJlYmFzZUluZGV4T25BY3RpdmUoYikpO1xuICAgICAgICAvLyBKdXN0IGxlYXZlIGlmIHRoZXJlJ3Mgbm90aGluZyB0aGF0IG1hdGNoZXMuIE5hdGl2ZSBzZWxlY3Qgd2lsbCBqdXN0XG4gICAgICAgIC8vIGNob29zZSB0aGUgZmlyc3QgdGhpbmcgdGhhdCBzdGFydHMgd2l0aCB0aGUgbmV4dCBsZXR0ZXIgaW4gdGhlIGFscGhhYmV0XG4gICAgICAgIC8vIGJ1dCB0aGF0J3Mgb3V0IG9mIHNjb3BlIGFuZCBoYXJkIHRvIGxvY2FsaXplXG4gICAgICAgIGlmIChtYXRjaGluZ1JlY29yZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5jYW5jZWxUeXBlYWhlYWRUaW1lb3V0KTtcbiAgICAgICAgICAgIGlmICh0aGlzLmxhc3RBY3RpdmVSZWNvcmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RBY3RpdmVSZWNvcmRbVFlQRUFIRUFEX1JFQ09SRC5JVEVNXS50YWJJbmRleCA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5lbmRUeXBlYWhlYWQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpc05ld1F1ZXJ5ID0gdGhpcy50eXBhaGVhZEJ1ZmZlci5sZW5ndGggPT09IDE7XG4gICAgICAgIGxldCBuZXh0UmVjb3JkO1xuICAgICAgICAvLyBUaGlzIGlzIGxpa2VseSB0aGUgY2FzZSB0aGF0IHNvbWVvbmUgaXMgdHJ5aW5nIHRvIFwidGFiXCIgdGhyb3VnaCBkaWZmZXJlbnRcbiAgICAgICAgLy8gZW50cmllcyB0aGF0IHN0YXJ0IHdpdGggdGhlIHNhbWUgbGV0dGVyXG4gICAgICAgIGlmICh0aGlzLmxhc3RBY3RpdmVSZWNvcmQgPT09IG1hdGNoaW5nUmVjb3Jkc1swXSAmJiBpc05ld1F1ZXJ5KSB7XG4gICAgICAgICAgICBuZXh0UmVjb3JkID0gbWF0Y2hpbmdSZWNvcmRzWzFdID8/IG1hdGNoaW5nUmVjb3Jkc1swXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG5leHRSZWNvcmQgPSBtYXRjaGluZ1JlY29yZHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubGFzdEFjdGl2ZVJlY29yZCkge1xuICAgICAgICAgICAgdGhpcy5sYXN0QWN0aXZlUmVjb3JkW1RZUEVBSEVBRF9SRUNPUkQuSVRFTV0udGFiSW5kZXggPSAtMTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxhc3RBY3RpdmVSZWNvcmQgPSBuZXh0UmVjb3JkO1xuICAgICAgICBuZXh0UmVjb3JkW1RZUEVBSEVBRF9SRUNPUkQuSVRFTV0udGFiSW5kZXggPSAwO1xuICAgICAgICBuZXh0UmVjb3JkW1RZUEVBSEVBRF9SRUNPUkQuSVRFTV0uZm9jdXMoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXR5cGVhaGVhZENvbnRyb2xsZXIuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLy8gR2VuZXJhdGVkIHN0eWxlc2hlZXQgZm9yIC4vbWVudS9pbnRlcm5hbC9tZW51LXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgOmhvc3R7LS1tZC1lbGV2YXRpb24tbGV2ZWw6IHZhcigtLW1kLW1lbnUtY29udGFpbmVyLWVsZXZhdGlvbiwgMik7LS1tZC1lbGV2YXRpb24tc2hhZG93LWNvbG9yOiB2YXIoLS1tZC1tZW51LWNvbnRhaW5lci1zaGFkb3ctY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1zaGFkb3csICMwMDApKTttaW4td2lkdGg6MTEycHg7Y29sb3I6dW5zZXQ7ZGlzcGxheTpjb250ZW50c31tZC1mb2N1cy1yaW5ney0tbWQtZm9jdXMtcmluZy1zaGFwZTogdmFyKC0tbWQtbWVudS1jb250YWluZXItc2hhcGUsIHZhcigtLW1kLXN5cy1zaGFwZS1jb3JuZXItZXh0cmEtc21hbGwsIDRweCkpfS5tZW51e2JvcmRlci1yYWRpdXM6dmFyKC0tbWQtbWVudS1jb250YWluZXItc2hhcGUsIHZhcigtLW1kLXN5cy1zaGFwZS1jb3JuZXItZXh0cmEtc21hbGwsIDRweCkpO2Rpc3BsYXk6bm9uZTtpbnNldDphdXRvO2JvcmRlcjpub25lO3BhZGRpbmc6MHB4O292ZXJmbG93OnZpc2libGU7YmFja2dyb3VuZC1jb2xvcjpyZ2JhKDAsMCwwLDApO2NvbG9yOmluaGVyaXQ7b3BhY2l0eTowO3otaW5kZXg6MjA7cG9zaXRpb246YWJzb2x1dGU7dXNlci1zZWxlY3Q6bm9uZTttYXgtaGVpZ2h0OmluaGVyaXQ7aGVpZ2h0OmluaGVyaXQ7bWluLXdpZHRoOmluaGVyaXQ7bWF4LXdpZHRoOmluaGVyaXQ7c2Nyb2xsYmFyLXdpZHRoOmluaGVyaXR9Lm1lbnU6OmJhY2tkcm9we2Rpc3BsYXk6bm9uZX0uZml4ZWR7cG9zaXRpb246Zml4ZWR9Lml0ZW1ze2Rpc3BsYXk6YmxvY2s7bGlzdC1zdHlsZS10eXBlOm5vbmU7bWFyZ2luOjA7b3V0bGluZTpub25lO2JveC1zaXppbmc6Ym9yZGVyLWJveDtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLW1kLW1lbnUtY29udGFpbmVyLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itc3VyZmFjZS1jb250YWluZXIsICNmM2VkZjcpKTtoZWlnaHQ6aW5oZXJpdDttYXgtaGVpZ2h0OmluaGVyaXQ7b3ZlcmZsb3c6YXV0bzttaW4td2lkdGg6aW5oZXJpdDttYXgtd2lkdGg6aW5oZXJpdDtib3JkZXItcmFkaXVzOmluaGVyaXQ7c2Nyb2xsYmFyLXdpZHRoOmluaGVyaXR9Lml0ZW0tcGFkZGluZ3twYWRkaW5nLWJsb2NrOnZhcigtLW1kLW1lbnUtdG9wLXNwYWNlLCA4cHgpIHZhcigtLW1kLW1lbnUtYm90dG9tLXNwYWNlLCA4cHgpfS5oYXMtb3ZlcmZsb3c6bm90KFtwb3BvdmVyXSkgLml0ZW1ze292ZXJmbG93OnZpc2libGV9Lmhhcy1vdmVyZmxvdy5hbmltYXRpbmcgLml0ZW1zLC5hbmltYXRpbmcgLml0ZW1ze292ZXJmbG93OmhpZGRlbn0uaGFzLW92ZXJmbG93LmFuaW1hdGluZyAuaXRlbXN7cG9pbnRlci1ldmVudHM6bm9uZX0uYW5pbWF0aW5nIDo6c2xvdHRlZCgubWQtbWVudS1oaWRkZW4pe29wYWNpdHk6MH1zbG90e2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OmluaGVyaXQ7bWF4LWhlaWdodDppbmhlcml0fTo6c2xvdHRlZCg6aXMobWQtZGl2aWRlcixbcm9sZT1zZXBhcmF0b3JdKSl7bWFyZ2luOjhweCAwfUBtZWRpYShmb3JjZWQtY29sb3JzOiBhY3RpdmUpey5tZW51e2JvcmRlci1zdHlsZTpzb2xpZDtib3JkZXItY29sb3I6Q2FudmFzVGV4dDtib3JkZXItd2lkdGg6MXB4fX1cbmA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZW51LXN0eWxlcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgJy4uLy4uL2VsZXZhdGlvbi9lbGV2YXRpb24uanMnO1xuaW1wb3J0ICcuLi8uLi9mb2N1cy9tZC1mb2N1cy1yaW5nLmpzJztcbmltcG9ydCB7IExpdEVsZW1lbnQsIGh0bWwsIGlzU2VydmVyLCBub3RoaW5nIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IHByb3BlcnR5LCBxdWVyeSwgcXVlcnlBc3NpZ25lZEVsZW1lbnRzLCBzdGF0ZSB9IGZyb20gJ2xpdC9kZWNvcmF0b3JzLmpzJztcbmltcG9ydCB7IGNsYXNzTWFwIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvY2xhc3MtbWFwLmpzJztcbmltcG9ydCB7IHN0eWxlTWFwIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvc3R5bGUtbWFwLmpzJztcbmltcG9ydCB7IEVBU0lORywgY3JlYXRlQW5pbWF0aW9uU2lnbmFsIH0gZnJvbSAnLi4vLi4vaW50ZXJuYWwvbW90aW9uL2FuaW1hdGlvbi5qcyc7XG5pbXBvcnQgeyBMaXN0Q29udHJvbGxlciwgTmF2aWdhYmxlS2V5cywgfSBmcm9tICcuLi8uLi9saXN0L2ludGVybmFsL2xpc3QtY29udHJvbGxlci5qcyc7XG5pbXBvcnQgeyBnZXRBY3RpdmVJdGVtLCBnZXRGaXJzdEFjdGl2YXRhYmxlSXRlbSwgZ2V0TGFzdEFjdGl2YXRhYmxlSXRlbSwgfSBmcm9tICcuLi8uLi9saXN0L2ludGVybmFsL2xpc3QtbmF2aWdhdGlvbi1oZWxwZXJzLmpzJztcbmltcG9ydCB7IEZvY3VzU3RhdGUsIGlzQ2xvc2FibGVLZXksIGlzRWxlbWVudEluU3VidHJlZSwgfSBmcm9tICcuL2NvbnRyb2xsZXJzL3NoYXJlZC5qcyc7XG5pbXBvcnQgeyBDb3JuZXIsIFN1cmZhY2VQb3NpdGlvbkNvbnRyb2xsZXIsIH0gZnJvbSAnLi9jb250cm9sbGVycy9zdXJmYWNlUG9zaXRpb25Db250cm9sbGVyLmpzJztcbmltcG9ydCB7IFR5cGVhaGVhZENvbnRyb2xsZXIgfSBmcm9tICcuL2NvbnRyb2xsZXJzL3R5cGVhaGVhZENvbnRyb2xsZXIuanMnO1xuZXhwb3J0IHsgQ29ybmVyIH0gZnJvbSAnLi9jb250cm9sbGVycy9zdXJmYWNlUG9zaXRpb25Db250cm9sbGVyLmpzJztcbi8qKlxuICogVGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSB0eXBlYWhlYWQgYnVmZmVyIHRpbWUgaW4gTWlsbGlzZWNvbmRzLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9UWVBFQUhFQURfQlVGRkVSX1RJTUUgPSAyMDA7XG5jb25zdCBzdWJtZW51TmF2S2V5cyA9IG5ldyBTZXQoW1xuICAgIE5hdmlnYWJsZUtleXMuQXJyb3dEb3duLFxuICAgIE5hdmlnYWJsZUtleXMuQXJyb3dVcCxcbiAgICBOYXZpZ2FibGVLZXlzLkhvbWUsXG4gICAgTmF2aWdhYmxlS2V5cy5FbmQsXG5dKTtcbmNvbnN0IG1lbnVOYXZLZXlzID0gbmV3IFNldChbXG4gICAgTmF2aWdhYmxlS2V5cy5BcnJvd0xlZnQsXG4gICAgTmF2aWdhYmxlS2V5cy5BcnJvd1JpZ2h0LFxuICAgIC4uLnN1Ym1lbnVOYXZLZXlzLFxuXSk7XG4vKipcbiAqIEdldHMgdGhlIGN1cnJlbnRseSBmb2N1c2VkIGVsZW1lbnQgb24gdGhlIHBhZ2UuXG4gKlxuICogQHBhcmFtIGFjdGl2ZURvYyBUaGUgZG9jdW1lbnQgb3Igc2hhZG93cm9vdCBmcm9tIHdoaWNoIHRvIHN0YXJ0IHRoZSBzZWFyY2guXG4gKiAgICBEZWZhdWx0cyB0byBgd2luZG93LmRvY3VtZW50YFxuICogQHJldHVybiBSZXR1cm5zIHRoZSBjdXJyZW50bHkgZGVlcGx5IGZvY3VzZWQgZWxlbWVudCBvciBgbnVsbGAgaWYgbm9uZS5cbiAqL1xuZnVuY3Rpb24gZ2V0Rm9jdXNlZEVsZW1lbnQoYWN0aXZlRG9jID0gZG9jdW1lbnQpIHtcbiAgICBsZXQgYWN0aXZlRWwgPSBhY3RpdmVEb2MuYWN0aXZlRWxlbWVudDtcbiAgICAvLyBDaGVjayBmb3IgYWN0aXZlRWxlbWVudCBpbiB0aGUgY2FzZSB0aGF0IGFuIGVsZW1lbnQgd2l0aCBhIHNoYWRvdyByb290IGhvc3RcbiAgICAvLyBpcyBjdXJyZW50bHkgZm9jdXNlZC5cbiAgICB3aGlsZSAoYWN0aXZlRWwgJiYgYWN0aXZlRWw/LnNoYWRvd1Jvb3Q/LmFjdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgYWN0aXZlRWwgPSBhY3RpdmVFbC5zaGFkb3dSb290LmFjdGl2ZUVsZW1lbnQ7XG4gICAgfVxuICAgIHJldHVybiBhY3RpdmVFbDtcbn1cbi8qKlxuICogQGZpcmVzIG9wZW5pbmcge0V2ZW50fSBGaXJlZCBiZWZvcmUgdGhlIG9wZW5pbmcgYW5pbWF0aW9uIGJlZ2luc1xuICogQGZpcmVzIG9wZW5lZCB7RXZlbnR9IEZpcmVkIG9uY2UgdGhlIG1lbnUgaXMgb3BlbiwgYWZ0ZXIgYW55IGFuaW1hdGlvbnNcbiAqIEBmaXJlcyBjbG9zaW5nIHtFdmVudH0gRmlyZWQgYmVmb3JlIHRoZSBjbG9zaW5nIGFuaW1hdGlvbiBiZWdpbnNcbiAqIEBmaXJlcyBjbG9zZWQge0V2ZW50fSBGaXJlZCBvbmNlIHRoZSBtZW51IGlzIGNsb3NlZCwgYWZ0ZXIgYW55IGFuaW1hdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIE1lbnUgZXh0ZW5kcyBMaXRFbGVtZW50IHtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBtZW51IGlzIGFuaW1hdGluZyB1cHdhcmRzIG9yIGRvd253YXJkcyB3aGVuIG9wZW5pbmcuIFRoaXMgaXNcbiAgICAgKiBoZWxwZnVsIGZvciBjYWxjdWxhdGluZyBzb21lIGFuaW1hdGlvbiBjYWxjdWxhdGlvbnMuXG4gICAgICovXG4gICAgZ2V0IG9wZW5EaXJlY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IG1lbnVDb3JuZXJCbG9jayA9IHRoaXMubWVudUNvcm5lci5zcGxpdCgnLScpWzBdO1xuICAgICAgICByZXR1cm4gbWVudUNvcm5lckJsb2NrID09PSAnc3RhcnQnID8gJ0RPV04nIDogJ1VQJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGVsZW1lbnQgd2hpY2ggdGhlIG1lbnUgc2hvdWxkIGFsaWduIHRvLiBJZiBgYW5jaG9yYCBpcyBzZXQgdG8gYVxuICAgICAqIG5vbi1lbXB0eSBpZHJlZiBzdHJpbmcsIHRoZW4gYGFuY2hvckVsYCB3aWxsIHJlc29sdmUgdG8gdGhlIGVsZW1lbnQgd2l0aFxuICAgICAqIHRoZSBnaXZlbiBpZCBpbiB0aGUgc2FtZSByb290IG5vZGUuIE90aGVyd2lzZSwgYG51bGxgLlxuICAgICAqL1xuICAgIGdldCBhbmNob3JFbGVtZW50KCkge1xuICAgICAgICBpZiAodGhpcy5hbmNob3IpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldFJvb3ROb2RlKCkucXVlcnlTZWxlY3RvcihgIyR7dGhpcy5hbmNob3J9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudEFuY2hvckVsZW1lbnQ7XG4gICAgfVxuICAgIHNldCBhbmNob3JFbGVtZW50KGVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50QW5jaG9yRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgIHRoaXMucmVxdWVzdFVwZGF0ZSgnYW5jaG9yRWxlbWVudCcpO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBJRCBvZiB0aGUgZWxlbWVudCBpbiB0aGUgc2FtZSByb290IG5vZGUgaW4gd2hpY2ggdGhlIG1lbnUgc2hvdWxkIGFsaWduXG4gICAgICAgICAqIHRvLiBPdmVycmlkZXMgc2V0dGluZyBgYW5jaG9yRWxlbWVudCA9IGVsZW1lbnRSZWZlcmVuY2VgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBfX05PVEVfXzogYW5jaG9yIG9yIGFuY2hvckVsZW1lbnQgbXVzdCBlaXRoZXIgYmUgYW4gSFRNTEVsZW1lbnQgb3IgcmVzb2x2ZVxuICAgICAgICAgKiB0byBhbiBIVE1MRWxlbWVudCBpbiBvcmRlciBmb3IgbWVudSB0byBvcGVuLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hbmNob3IgPSAnJztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgdGhlIHBvc2l0aW9uaW5nIGFsZ29yaXRobSBzaG91bGQgY2FsY3VsYXRlIHJlbGF0aXZlIHRvIHRoZSBwYXJlbnRcbiAgICAgICAgICogb2YgdGhlIGFuY2hvciBlbGVtZW50IChgYWJzb2x1dGVgKSwgcmVsYXRpdmUgdG8gdGhlIHdpbmRvdyAoYGZpeGVkYCksIG9yXG4gICAgICAgICAqIHJlbGF0aXZlIHRvIHRoZSBkb2N1bWVudCAoYGRvY3VtZW50YCkuIGBwb3BvdmVyYCB3aWxsIHVzZSB0aGUgcG9wb3ZlciBBUElcbiAgICAgICAgICogdG8gcmVuZGVyIHRoZSBtZW51IGluIHRoZSB0b3AtbGF5ZXIuIElmIHlvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZVxuICAgICAgICAgKiBwb3BvdmVyIEFQSSwgaXQgd2lsbCBmYWxsIGJhY2sgdG8gYGZpeGVkYC5cbiAgICAgICAgICpcbiAgICAgICAgICogX19FeGFtcGxlcyBmb3IgYHBvc2l0aW9uID0gJ2ZpeGVkJ2A6X19cbiAgICAgICAgICpcbiAgICAgICAgICogLSBJZiB0aGVyZSBpcyBubyBgcG9zaXRpb246cmVsYXRpdmVgIGluIHRoZSBnaXZlbiBwYXJlbnQgdHJlZSBhbmQgdGhlXG4gICAgICAgICAqICAgc3VyZmFjZSBpcyBgcG9zaXRpb246YWJzb2x1dGVgXG4gICAgICAgICAqIC0gSWYgdGhlIHN1cmZhY2UgaXMgYHBvc2l0aW9uOmZpeGVkYFxuICAgICAgICAgKiAtIElmIHRoZSBzdXJmYWNlIGlzIGluIHRoZSBcInRvcCBsYXllclwiXG4gICAgICAgICAqIC0gVGhlIGFuY2hvciBhbmQgdGhlIHN1cmZhY2UgZG8gbm90IHNoYXJlIGEgY29tbW9uIGBwb3NpdGlvbjpyZWxhdGl2ZWBcbiAgICAgICAgICogICBhbmNlc3RvclxuICAgICAgICAgKlxuICAgICAgICAgKiBXaGVuIHVzaW5nIGBwb3NpdGlvbmluZz1maXhlZGAsIGluIG1vc3QgY2FzZXMsIHRoZSBtZW51IHNob3VsZCBwb3NpdGlvblxuICAgICAgICAgKiBpdHNlbGYgYWJvdmUgbW9zdCBvdGhlciBgcG9zaXRpb246YWJzb2x1dGVgIG9yIGBwb3NpdGlvbjpmaXhlZGAgZWxlbWVudHNcbiAgICAgICAgICogd2hlbiBwbGFjZWQgaW5zaWRlIG9mIHRoZW0uIGUuZy4gdXNpbmcgYSBtZW51IGluc2lkZSBvZiBhbiBgbWQtZGlhbG9nYC5cbiAgICAgICAgICpcbiAgICAgICAgICogX19OT1RFX186IEZpeGVkIG1lbnVzIHdpbGwgbm90IHNjcm9sbCB3aXRoIHRoZSBwYWdlIGFuZCB3aWxsIGJlIGZpeGVkIHRvXG4gICAgICAgICAqIHRoZSB3aW5kb3cgaW5zdGVhZC5cbiAgICAgICAgICpcbiAgICAgICAgICogX19FeGFtcGxlcyBmb3IgYHBvc2l0aW9uID0gJ2RvY3VtZW50J2A6X19cbiAgICAgICAgICpcbiAgICAgICAgICogLSBUaGVyZSBpcyBubyBwYXJlbnQgdGhhdCBjcmVhdGVzIGEgcmVsYXRpdmUgcG9zaXRpb25pbmcgY29udGV4dCBlLmcuXG4gICAgICAgICAqICAgYHBvc2l0aW9uOiByZWxhdGl2ZWAsIGBwb3NpdGlvbjogYWJzb2x1dGVgLCBgdHJhbnNmb3JtOiB0cmFuc2xhdGUoeCwgeSlgLFxuICAgICAgICAgKiAgIGV0Yy5cbiAgICAgICAgICogLSBZb3UgcHV0IHRoZSBlZmZvcnQgaW50byBob2lzdGluZyB0aGUgbWVudSB0byB0aGUgdG9wIG9mIHRoZSBET00gbGlrZSB0aGVcbiAgICAgICAgICogICBlbmQgb2YgdGhlIGA8Ym9keT5gIHRvIHJlbmRlciBvdmVyIGV2ZXJ5dGhpbmcgb3IgaW4gYSB0b3AtbGF5ZXIuXG4gICAgICAgICAqIC0gWW91IGFyZSByZXVzaW5nIGEgc2luZ2xlIGBtZC1tZW51YCBlbGVtZW50IHRoYXQgZHluYW1pY2FsbHkgcmVuZGVyc1xuICAgICAgICAgKiAgIGNvbnRlbnQuXG4gICAgICAgICAqXG4gICAgICAgICAqIF9fRXhhbXBsZXMgZm9yIGBwb3NpdGlvbiA9ICdwb3BvdmVyJ2A6X19cbiAgICAgICAgICpcbiAgICAgICAgICogLSBZb3VyIGJyb3dzZXIgc3VwcG9ydHMgYHBvcG92ZXJgLlxuICAgICAgICAgKiAtIE1vc3QgY2FzZXMuIE9uY2UgcG9wb3ZlciBpcyBpbiBicm93c2VycywgdGhpcyB3aWxsIGJlY29tZSB0aGUgZGVmYXVsdC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucG9zaXRpb25pbmcgPSAnYWJzb2x1dGUnO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2tpcHMgdGhlIG9wZW5pbmcgYW5kIGNsb3NpbmcgYW5pbWF0aW9ucy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucXVpY2sgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERpc3BsYXlzIG92ZXJmbG93IGNvbnRlbnQgbGlrZSBhIHN1Ym1lbnUuIE5vdCByZXF1aXJlZCBpbiBtb3N0IGNhc2VzIHdoZW5cbiAgICAgICAgICogdXNpbmcgYHBvc2l0aW9uaW5nPVwicG9wb3ZlclwiYC5cbiAgICAgICAgICpcbiAgICAgICAgICogX19OT1RFX186IFRoaXMgbWF5IGNhdXNlIGFkdmVyc2UgZWZmZWN0cyBpZiB5b3Ugc2V0XG4gICAgICAgICAqIGBtZC1tZW51IHttYXgtaGVpZ2h0Oi4uLn1gXG4gICAgICAgICAqIGFuZCBoYXZlIGl0ZW1zIG92ZXJmbG93aW5nIGl0ZW1zIGluIHRoZSBcInlcIiBkaXJlY3Rpb24uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmhhc092ZXJmbG93ID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPcGVucyB0aGUgbWVudSBhbmQgbWFrZXMgaXQgdmlzaWJsZS4gQWx0ZXJuYXRpdmUgdG8gdGhlIGAuc2hvdygpYCBhbmRcbiAgICAgICAgICogYC5jbG9zZSgpYCBtZXRob2RzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9wZW4gPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9mZnNldHMgdGhlIG1lbnUncyBpbmxpbmUgYWxpZ25tZW50IGZyb20gdGhlIGFuY2hvciBieSB0aGUgZ2l2ZW4gbnVtYmVyIGluXG4gICAgICAgICAqIHBpeGVscy4gVGhpcyB2YWx1ZSBpcyBkaXJlY3Rpb24gYXdhcmUgYW5kIHdpbGwgZm9sbG93IHRoZSBMVFIgLyBSVExcbiAgICAgICAgICogZGlyZWN0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBlLmcuIExUUjogcG9zaXRpdmUgLT4gcmlnaHQsIG5lZ2F0aXZlIC0+IGxlZnRcbiAgICAgICAgICogICAgICBSVEw6IHBvc2l0aXZlIC0+IGxlZnQsIG5lZ2F0aXZlIC0+IHJpZ2h0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnhPZmZzZXQgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogT2Zmc2V0cyB0aGUgbWVudSdzIGJsb2NrIGFsaWdubWVudCBmcm9tIHRoZSBhbmNob3IgYnkgdGhlIGdpdmVuIG51bWJlciBpblxuICAgICAgICAgKiBwaXhlbHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIGUuZy4gcG9zaXRpdmUgLT4gZG93biwgbmVnYXRpdmUgLT4gdXBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMueU9mZnNldCA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlIHRoZSBgZmxpcGAgYmVoYXZpb3IgdGhhdCB1c3VhbGx5IGhhcHBlbnMgb24gdGhlIGhvcml6b250YWwgYXhpc1xuICAgICAgICAgKiB3aGVuIHRoZSBzdXJmYWNlIHdvdWxkIHJlbmRlciBvdXRzaWRlIHRoZSB2aWV3cG9ydC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubm9Ib3Jpem9udGFsRmxpcCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGlzYWJsZSB0aGUgYGZsaXBgIGJlaGF2aW9yIHRoYXQgdXN1YWxseSBoYXBwZW5zIG9uIHRoZSB2ZXJ0aWNhbCBheGlzIHdoZW5cbiAgICAgICAgICogdGhlIHN1cmZhY2Ugd291bGQgcmVuZGVyIG91dHNpZGUgdGhlIHZpZXdwb3J0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5ub1ZlcnRpY2FsRmxpcCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG1heCB0aW1lIGJldHdlZW4gdGhlIGtleXN0cm9rZXMgb2YgdGhlIHR5cGVhaGVhZCBtZW51IGJlaGF2aW9yIGJlZm9yZVxuICAgICAgICAgKiBpdCBjbGVhcnMgdGhlIHR5cGVhaGVhZCBidWZmZXIuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnR5cGVhaGVhZERlbGF5ID0gREVGQVVMVF9UWVBFQUhFQURfQlVGRkVSX1RJTUU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29ybmVyIG9mIHRoZSBhbmNob3Igd2hpY2ggdG8gYWxpZ24gdGhlIG1lbnUgaW4gdGhlIHN0YW5kYXJkIGxvZ2ljYWxcbiAgICAgICAgICogcHJvcGVydHkgc3R5bGUgb2YgPGJsb2NrPi08aW5saW5lPiBlLmcuIGAnZW5kLXN0YXJ0J2AuXG4gICAgICAgICAqXG4gICAgICAgICAqIE5PVEU6IFRoaXMgdmFsdWUgbWF5IG5vdCBiZSByZXNwZWN0ZWQgYnkgdGhlIG1lbnUgcG9zaXRpb25pbmcgYWxnb3JpdGhtXG4gICAgICAgICAqIGlmIHRoZSBtZW51IHdvdWxkIHJlbmRlciBvdXRpc2RlIHRoZSB2aWV3cG9ydC5cbiAgICAgICAgICogVXNlIGBuby1ob3Jpem9udGFsLWZsaXBgIG9yIGBuby12ZXJ0aWNhbC1mbGlwYCB0byBmb3JjZSB0aGUgdXNhZ2Ugb2YgdGhlIHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFuY2hvckNvcm5lciA9IENvcm5lci5FTkRfU1RBUlQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29ybmVyIG9mIHRoZSBtZW51IHdoaWNoIHRvIGFsaWduIHRoZSBhbmNob3IgaW4gdGhlIHN0YW5kYXJkIGxvZ2ljYWxcbiAgICAgICAgICogcHJvcGVydHkgc3R5bGUgb2YgPGJsb2NrPi08aW5saW5lPiBlLmcuIGAnc3RhcnQtc3RhcnQnYC5cbiAgICAgICAgICpcbiAgICAgICAgICogTk9URTogVGhpcyB2YWx1ZSBtYXkgbm90IGJlIHJlc3BlY3RlZCBieSB0aGUgbWVudSBwb3NpdGlvbmluZyBhbGdvcml0aG1cbiAgICAgICAgICogaWYgdGhlIG1lbnUgd291bGQgcmVuZGVyIG91dGlzZGUgdGhlIHZpZXdwb3J0LlxuICAgICAgICAgKiBVc2UgYG5vLWhvcml6b250YWwtZmxpcGAgb3IgYG5vLXZlcnRpY2FsLWZsaXBgIHRvIGZvcmNlIHRoZSB1c2FnZSBvZiB0aGUgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubWVudUNvcm5lciA9IENvcm5lci5TVEFSVF9TVEFSVDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXBzIHRoZSB1c2VyIGNsaWNrcyBvdXRzaWRlIHRoZSBtZW51LlxuICAgICAgICAgKlxuICAgICAgICAgKiBOT1RFOiBjbGlja2luZyBvdXRzaWRlIG1heSBzdGlsbCBjYXVzZSBmb2N1c291dCB0byBjbG9zZSB0aGUgbWVudSBzbyBzZWVcbiAgICAgICAgICogYHN0YXlPcGVuT25Gb2N1c291dGAuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnN0YXlPcGVuT25PdXRzaWRlQ2xpY2sgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXBzIHRoZSBtZW51IG9wZW4gd2hlbiBmb2N1cyBsZWF2ZXMgdGhlIG1lbnUncyBjb21wb3NlZCBzdWJ0cmVlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBOT1RFOiBGb2N1c291dCBiZWhhdmlvciB3aWxsIHN0b3AgcHJvcGFnYXRpb24gb2YgdGhlIGZvY3Vzb3V0IGV2ZW50LiBTZXRcbiAgICAgICAgICogdGhpcyBwcm9wZXJ0eSB0byB0cnVlIHRvIG9wdC1vdXQgb2YgbWVudSdzIGZvY3Vzb3V0IGhhbmRsaW5nIGFsdG9nZXRoZXIuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnN0YXlPcGVuT25Gb2N1c291dCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWZ0ZXIgY2xvc2luZywgZG9lcyBub3QgcmVzdG9yZSBmb2N1cyB0byB0aGUgbGFzdCBmb2N1c2VkIGVsZW1lbnQgYmVmb3JlXG4gICAgICAgICAqIHRoZSBtZW51IHdhcyBvcGVuZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnNraXBSZXN0b3JlRm9jdXMgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBlbGVtZW50IHRoYXQgc2hvdWxkIGJlIGZvY3VzZWQgYnkgZGVmYXVsdCBvbmNlIG9wZW5lZC5cbiAgICAgICAgICpcbiAgICAgICAgICogTk9URTogV2hlbiBzZXR0aW5nIGRlZmF1bHQgZm9jdXMgdG8gJ0xJU1RfUk9PVCcsIHJlbWVtYmVyIHRvIGNoYW5nZVxuICAgICAgICAgKiBgdGFiaW5kZXhgIHRvIGAwYCBhbmQgY2hhbmdlIG1kLW1lbnUncyBkaXNwbGF5IHRvIHNvbWV0aGluZyBvdGhlciB0aGFuXG4gICAgICAgICAqIGBkaXNwbGF5OiBjb250ZW50c2Agd2hlbiBuZWNlc3NhcnkuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmRlZmF1bHRGb2N1cyA9IEZvY3VzU3RhdGUuRklSU1RfSVRFTTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFR1cm5zIG9mZiBuYXZpZ2F0aW9uIHdyYXBwaW5nLiBCeSBkZWZhdWx0LCBuYXZpZ2F0aW5nIHBhc3QgdGhlIGVuZCBvZiB0aGVcbiAgICAgICAgICogbWVudSBpdGVtcyB3aWxsIHdyYXAgZm9jdXMgYmFjayB0byB0aGUgYmVnaW5uaW5nIGFuZCB2aWNlIHZlcnNhLiBVc2UgdGhpc1xuICAgICAgICAgKiBmb3IgQVJJQSBwYXR0ZXJucyB0aGF0IGRvIG5vdCB3cmFwIGZvY3VzLCBsaWtlIGNvbWJvYm94LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5ub05hdmlnYXRpb25XcmFwID0gZmFsc2U7XG4gICAgICAgIHRoaXMudHlwZWFoZWFkQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSBjdXJyZW50IG1lbnUgaXMgYSBzdWJtZW51IGFuZCBzaG91bGQgbm90IGhhbmRsZSBzcGVjaWZpY1xuICAgICAgICAgKiBuYXZpZ2F0aW9uIGtleXMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleHBvcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaXNTdWJtZW51ID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZXZlbnQgcGF0aCBvZiB0aGUgbGFzdCB3aW5kb3cgcG9pbnRlcmRvd24gZXZlbnQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnBvaW50ZXJQYXRoID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgbWVudSBpcyByZXBvc2l0b2luaW5nIGR1ZSB0byB3aW5kb3cgLyBkb2N1bWVudCByZXNpemVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaXNSZXBvc2l0aW9uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMub3BlbkNsb3NlQW5pbWF0aW9uU2lnbmFsID0gY3JlYXRlQW5pbWF0aW9uU2lnbmFsKCk7XG4gICAgICAgIHRoaXMubGlzdENvbnRyb2xsZXIgPSBuZXcgTGlzdENvbnRyb2xsZXIoe1xuICAgICAgICAgICAgaXNJdGVtOiAobWF5YmVJdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1heWJlSXRlbS5oYXNBdHRyaWJ1dGUoJ21kLW1lbnUtaXRlbScpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldFBvc3NpYmxlSXRlbXM6ICgpID0+IHRoaXMuc2xvdEl0ZW1zLFxuICAgICAgICAgICAgaXNSdGw6ICgpID0+IGdldENvbXB1dGVkU3R5bGUodGhpcykuZGlyZWN0aW9uID09PSAncnRsJyxcbiAgICAgICAgICAgIGRlYWN0aXZhdGVJdGVtOiAoaXRlbSkgPT4ge1xuICAgICAgICAgICAgICAgIGl0ZW0uc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBpdGVtLnRhYkluZGV4ID0gLTE7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWN0aXZhdGVJdGVtOiAoaXRlbSkgPT4ge1xuICAgICAgICAgICAgICAgIGl0ZW0uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGl0ZW0udGFiSW5kZXggPSAwO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlzTmF2aWdhYmxlS2V5OiAoa2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU3VibWVudSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWVudU5hdktleXMuaGFzKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlzUnRsID0gZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzKS5kaXJlY3Rpb24gPT09ICdydGwnO1xuICAgICAgICAgICAgICAgIC8vIHdlIHdhbnQgbWQtc3VibWVudSB0byBoYW5kbGUgdGhlIHN1Ym1lbnUncyBsZWZ0L3JpZ2h0IGFycm93IGV4aXRcbiAgICAgICAgICAgICAgICAvLyBrZXkgc28gaXQgY2FuIGNsb3NlIHRoZSBtZW51IGluc3RlYWQgb2YgbmF2aWdhdGUgdGhlIGxpc3QuXG4gICAgICAgICAgICAgICAgLy8gVGhlcmVmb3JlIHdlIG5lZWQgdG8gaW5jbHVkZSBhbGwga2V5cyBidXQgbGVmdC9yaWdodCBhcnJvdyBjbG9zZVxuICAgICAgICAgICAgICAgIC8vIGtleVxuICAgICAgICAgICAgICAgIGNvbnN0IGFycm93T3BlbiA9IGlzUnRsXG4gICAgICAgICAgICAgICAgICAgID8gTmF2aWdhYmxlS2V5cy5BcnJvd0xlZnRcbiAgICAgICAgICAgICAgICAgICAgOiBOYXZpZ2FibGVLZXlzLkFycm93UmlnaHQ7XG4gICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gYXJyb3dPcGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gc3VibWVudU5hdktleXMuaGFzKGtleSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgd3JhcE5hdmlnYXRpb246ICgpID0+ICF0aGlzLm5vTmF2aWdhdGlvbldyYXAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGVsZW1lbnQgdGhhdCB3YXMgZm9jdXNlZCBiZWZvcmUgdGhlIG1lbnUgb3BlbmVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sYXN0Rm9jdXNlZEVsZW1lbnQgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgICogSGFuZGxlcyB0eXBlYWhlYWQgbmF2aWdhdGlvbiB0aHJvdWdoIHRoZSBtZW51LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy50eXBlYWhlYWRDb250cm9sbGVyID0gbmV3IFR5cGVhaGVhZENvbnRyb2xsZXIoKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBnZXRJdGVtczogKCkgPT4gdGhpcy5pdGVtcyxcbiAgICAgICAgICAgICAgICB0eXBlYWhlYWRCdWZmZXJUaW1lOiB0aGlzLnR5cGVhaGVhZERlbGF5LFxuICAgICAgICAgICAgICAgIGFjdGl2ZTogdGhpcy50eXBlYWhlYWRBY3RpdmUsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jdXJyZW50QW5jaG9yRWxlbWVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxzID0gXG4gICAgICAgIC8vIENhc3QgbmVlZGVkIGZvciBjbG9zdXJlXG4gICAgICAgIHRoaXMuYXR0YWNoSW50ZXJuYWxzKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIYW5kbGVzIHBvc2l0aW9uaW5nIHRoZSBzdXJmYWNlIGFuZCBhbGlnbmluZyBpdCB0byB0aGUgYW5jaG9yIGFzIHdlbGwgYXNcbiAgICAgICAgICoga2VlcGluZyBpdCBpbiB0aGUgdmlld3BvcnQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm1lbnVQb3NpdGlvbkNvbnRyb2xsZXIgPSBuZXcgU3VyZmFjZVBvc2l0aW9uQ29udHJvbGxlcih0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGFuY2hvckNvcm5lcjogdGhpcy5hbmNob3JDb3JuZXIsXG4gICAgICAgICAgICAgICAgc3VyZmFjZUNvcm5lcjogdGhpcy5tZW51Q29ybmVyLFxuICAgICAgICAgICAgICAgIHN1cmZhY2VFbDogdGhpcy5zdXJmYWNlRWwsXG4gICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuYW5jaG9yRWxlbWVudCxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbmluZzogdGhpcy5wb3NpdGlvbmluZyA9PT0gJ3BvcG92ZXInID8gJ2RvY3VtZW50JyA6IHRoaXMucG9zaXRpb25pbmcsXG4gICAgICAgICAgICAgICAgaXNPcGVuOiB0aGlzLm9wZW4sXG4gICAgICAgICAgICAgICAgeE9mZnNldDogdGhpcy54T2Zmc2V0LFxuICAgICAgICAgICAgICAgIHlPZmZzZXQ6IHRoaXMueU9mZnNldCxcbiAgICAgICAgICAgICAgICBkaXNhYmxlQmxvY2tGbGlwOiB0aGlzLm5vVmVydGljYWxGbGlwLFxuICAgICAgICAgICAgICAgIGRpc2FibGVJbmxpbmVGbGlwOiB0aGlzLm5vSG9yaXpvbnRhbEZsaXAsXG4gICAgICAgICAgICAgICAgb25PcGVuOiB0aGlzLm9uT3BlbmVkLFxuICAgICAgICAgICAgICAgIGJlZm9yZUNsb3NlOiB0aGlzLmJlZm9yZUNsb3NlLFxuICAgICAgICAgICAgICAgIG9uQ2xvc2U6IHRoaXMub25DbG9zZWQsXG4gICAgICAgICAgICAgICAgLy8gV2UgY2FuJ3QgcmVzaXplIGNvbXBvbmVudHMgdGhhdCBoYXZlIG92ZXJmbG93IGxpa2UgbWVudXMgd2l0aFxuICAgICAgICAgICAgICAgIC8vIHN1Ym1lbnVzIGJlY2F1c2UgdGhlIG92ZXJmbG93LXkgd2lsbCBzaG93IG1lbnUgaXRlbXMgLyBjb250ZW50XG4gICAgICAgICAgICAgICAgLy8gb3V0c2lkZSB0aGUgYm91bmRzIG9mIHRoZSBtZW51LiBQb3BvdmVyIEFQSSBmaXhlcyB0aGlzIGJlY2F1c2UgZWFjaFxuICAgICAgICAgICAgICAgIC8vIHN1Ym1lbnUgaXMgaG9pc3RlZCB0byB0aGUgdG9wLWxheWVyIGFuZCBhcmUgbm90IGNvbnNpZGVyZWQgb3ZlcmZsb3dcbiAgICAgICAgICAgICAgICAvLyBjb250ZW50LlxuICAgICAgICAgICAgICAgIHJlcG9zaXRpb25TdHJhdGVneTogdGhpcy5oYXNPdmVyZmxvdyAmJiB0aGlzLnBvc2l0aW9uaW5nICE9PSAncG9wb3ZlcidcbiAgICAgICAgICAgICAgICAgICAgPyAnbW92ZSdcbiAgICAgICAgICAgICAgICAgICAgOiAncmVzaXplJyxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uV2luZG93UmVzaXplID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvc2l0aW9uaW5nIHx8XG4gICAgICAgICAgICAgICAgKHRoaXMucG9zaXRpb25pbmcgIT09ICdkb2N1bWVudCcgJiZcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbmluZyAhPT0gJ2ZpeGVkJyAmJlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uaW5nICE9PSAncG9wb3ZlcicpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5pc1JlcG9zaXRpb25pbmcgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5yZXBvc2l0aW9uKCk7XG4gICAgICAgICAgICB0aGlzLmlzUmVwb3NpdGlvbmluZyA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZUZvY3Vzb3V0ID0gYXN5bmMgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbmNob3JFbCA9IHRoaXMuYW5jaG9yRWxlbWVudDtcbiAgICAgICAgICAgIC8vIERvIG5vdCBjbG9zZSBpZiB3ZSBmb2N1c2VkIG91dCBieSBjbGlja2luZyBvbiB0aGUgYW5jaG9yIGVsZW1lbnQuIFdlXG4gICAgICAgICAgICAvLyBjYW4ndCBhc3N1bWUgYW5jaG9yIGJ1dHRvbnMgY2FuIGJlIHRoZSByZWxhdGVkIHRhcmdldCBiZWNhdXNlIG9mIGlPUyBkb2VzXG4gICAgICAgICAgICAvLyBub3QgZm9jdXMgYnV0dG9ucy5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXlPcGVuT25Gb2N1c291dCB8fFxuICAgICAgICAgICAgICAgICF0aGlzLm9wZW4gfHxcbiAgICAgICAgICAgICAgICB0aGlzLnBvaW50ZXJQYXRoLmluY2x1ZGVzKGFuY2hvckVsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChldmVudC5yZWxhdGVkVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgLy8gRG9uJ3QgY2xvc2UgdGhlIG1lbnUgaWYgd2UgYXJlIHN3aXRjaGluZyBmb2N1cyBiZXR3ZWVuIG1lbnUsXG4gICAgICAgICAgICAgICAgLy8gbWQtbWVudS1pdGVtLCBhbmQgbWQtbGlzdCBvciBpZiB0aGUgYW5jaG9yIHdhcyBjbGljayBmb2N1c2VkLCBidXQgY2hlY2tcbiAgICAgICAgICAgICAgICAvLyBpZiBsZW5ndGggb2YgcG9pbnRlclBhdGggaXMgMCBiZWNhdXNlIHRoYXQgbWVhbnMgc29tZXRoaW5nIHdhcyBhdCBsZWFzdFxuICAgICAgICAgICAgICAgIC8vIGNsaWNrZWQgKHNoaWZ0K3RhYiBjYXNlKS5cbiAgICAgICAgICAgICAgICBpZiAoaXNFbGVtZW50SW5TdWJ0cmVlKGV2ZW50LnJlbGF0ZWRUYXJnZXQsIHRoaXMpIHx8XG4gICAgICAgICAgICAgICAgICAgICh0aGlzLnBvaW50ZXJQYXRoLmxlbmd0aCAhPT0gMCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgaXNFbGVtZW50SW5TdWJ0cmVlKGV2ZW50LnJlbGF0ZWRUYXJnZXQsIGFuY2hvckVsKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMucG9pbnRlclBhdGguaW5jbHVkZXModGhpcykpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBtZW51IHRhYmluZGV4ID09IC0xIGFuZCB0aGUgdXNlciBjbGlja3Mgb24gdGhlIG1lbnUgb3IgYSBkaXZpZGVyLCB3ZVxuICAgICAgICAgICAgICAgIC8vIHdhbnQgdG8ga2VlcCB0aGUgbWVudSBvcGVuLlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG9sZFJlc3RvcmVGb2N1cyA9IHRoaXMuc2tpcFJlc3RvcmVGb2N1cztcbiAgICAgICAgICAgIC8vIGFsbG93IGZvY3VzIHRvIGNvbnRpbnVlIHRvIHRoZSBuZXh0IGZvY3VzZWQgb2JqZWN0IHJhdGhlciB0aGFuIHJldHVybmluZ1xuICAgICAgICAgICAgdGhpcy5za2lwUmVzdG9yZUZvY3VzID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgIC8vIGF3YWl0IGZvciBjbG9zZVxuICAgICAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVDb21wbGV0ZTtcbiAgICAgICAgICAgIC8vIHJldHVybiB0byBwcmV2aW91cyBiZWhhdmlvclxuICAgICAgICAgICAgdGhpcy5za2lwUmVzdG9yZUZvY3VzID0gb2xkUmVzdG9yZUZvY3VzO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogU2F2ZXMgdGhlIGxhc3QgZm9jdXNlZCBlbGVtZW50IGZvY3VzZXMgdGhlIG5ldyBlbGVtZW50IGJhc2VkIG9uXG4gICAgICAgICAqIGBkZWZhdWx0Rm9jdXNgLCBhbmQgYW5pbWF0ZXMgb3Blbi5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub25PcGVuZWQgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmxhc3RGb2N1c2VkRWxlbWVudCA9IGdldEZvY3VzZWRFbGVtZW50KCk7XG4gICAgICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXM7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVJdGVtUmVjb3JkID0gZ2V0QWN0aXZlSXRlbShpdGVtcyk7XG4gICAgICAgICAgICBpZiAoYWN0aXZlSXRlbVJlY29yZCAmJiB0aGlzLmRlZmF1bHRGb2N1cyAhPT0gRm9jdXNTdGF0ZS5OT05FKSB7XG4gICAgICAgICAgICAgICAgYWN0aXZlSXRlbVJlY29yZC5pdGVtLnRhYkluZGV4ID0gLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgYW5pbWF0aW9uQWJvcnRlZCA9ICF0aGlzLnF1aWNrO1xuICAgICAgICAgICAgaWYgKHRoaXMucXVpY2spIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdvcGVuaW5nJykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uQWJvcnRlZCA9ICEhKGF3YWl0IHRoaXMuYW5pbWF0ZU9wZW4oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBUaGlzIG11c3QgY29tZSBhZnRlciB0aGUgb3BlbmluZyBhbmltYXRpb24gb3IgZWxzZSBpdCBtYXkgZm9jdXMgb25lIG9mXG4gICAgICAgICAgICAvLyB0aGUgaXRlbXMgYmVmb3JlIHRoZSBhbmltYXRpb24gaGFzIGJlZ3VuIGFuZCBjYXVzZXMgdGhlIGxpc3QgdG8gc2xpZGVcbiAgICAgICAgICAgIC8vIChibG9jay1wYWRkaW5nLW9mLXRoZS1tZW51KXB4IGF0IHRoZSBlbmQgb2YgdGhlIGFuaW1hdGlvblxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLmRlZmF1bHRGb2N1cykge1xuICAgICAgICAgICAgICAgIGNhc2UgRm9jdXNTdGF0ZS5GSVJTVF9JVEVNOlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaXJzdCA9IGdldEZpcnN0QWN0aXZhdGFibGVJdGVtKGl0ZW1zKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdC50YWJJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdC5mb2N1cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZmlyc3QudXBkYXRlQ29tcGxldGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBGb2N1c1N0YXRlLkxBU1RfSVRFTTpcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGFzdCA9IGdldExhc3RBY3RpdmF0YWJsZUl0ZW0oaXRlbXMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobGFzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdC50YWJJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0LmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBsYXN0LnVwZGF0ZUNvbXBsZXRlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgRm9jdXNTdGF0ZS5MSVNUX1JPT1Q6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjYXNlIEZvY3VzU3RhdGUuTk9ORTpcbiAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90aGluZy5cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWFuaW1hdGlvbkFib3J0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdvcGVuZWQnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbmltYXRlcyBjbG9zZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmJlZm9yZUNsb3NlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vcGVuID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2tpcFJlc3RvcmVGb2N1cykge1xuICAgICAgICAgICAgICAgIHRoaXMubGFzdEZvY3VzZWRFbGVtZW50Py5mb2N1cz8uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMucXVpY2spIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmFuaW1hdGVDbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogRm9jdXNlcyB0aGUgbGFzdCBmb2N1c2VkIGVsZW1lbnQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uQ2xvc2VkID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucXVpY2spIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdjbG9zaW5nJykpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2Nsb3NlZCcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vbldpbmRvd1BvaW50ZXJkb3duID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBvaW50ZXJQYXRoID0gZXZlbnQuY29tcG9zZWRQYXRoKCk7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXZSBjYW5ub3QgbGlzdGVuIHRvIHdpbmRvdyBjbGljayBiZWNhdXNlIFNhZmFyaSBvbiBpT1Mgd2lsbCBub3QgYnViYmxlIGFcbiAgICAgICAgICogY2xpY2sgZXZlbnQgb24gd2luZG93IGlmIHRoZSBpdGVtIGNsaWNrZWQgaXMgbm90IGEgXCJjbGlja2FibGVcIiBpdGVtIHN1Y2ggYXNcbiAgICAgICAgICogPGJvZHk+XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uRG9jdW1lbnRDbGljayA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLm9wZW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBwYXRoID0gZXZlbnQuY29tcG9zZWRQYXRoKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RheU9wZW5Pbk91dHNpZGVDbGljayAmJlxuICAgICAgICAgICAgICAgICFwYXRoLmluY2x1ZGVzKHRoaXMpICYmXG4gICAgICAgICAgICAgICAgIXBhdGguaW5jbHVkZXModGhpcy5hbmNob3JFbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoIWlzU2VydmVyKSB7XG4gICAgICAgICAgICB0aGlzLmludGVybmFscy5yb2xlID0gJ21lbnUnO1xuICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5oYW5kbGVLZXlkb3duKTtcbiAgICAgICAgICAgIC8vIENhcHR1cmUgc28gdGhhdCB3ZSBjYW4gZ3JhYiB0aGUgZXZlbnQgYmVmb3JlIGl0IHJlYWNoZXMgdGhlIG1lbnUgaXRlbVxuICAgICAgICAgICAgLy8gaXN0ZWxmLiBTcGVjaWZpY2FsbHkgdXNlZnVsIGZvciB0aGUgY2FzZSB3aGVyZSB0eXBlYWhlYWQgZW5jb3VudGVycyBhXG4gICAgICAgICAgICAvLyBzcGFjZSBhbmQgd2UgZG9uJ3Qgd2FudCB0aGUgbWVudSBpdGVtIHRvIGNsb3NlIHRoZSBtZW51LlxuICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5jYXB0dXJlS2V5ZG93biwgeyBjYXB0dXJlOiB0cnVlIH0pO1xuICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIHRoaXMuaGFuZGxlRm9jdXNvdXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtZW51IGl0ZW1zIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1lbnUuIFRoZSBpdGVtcyBtdXN0IGJlIGBNZW51SXRlbWBzIGFuZFxuICAgICAqIGhhdmUgYm90aCB0aGUgYG1kLW1lbnUtaXRlbWAgYW5kIGBtZC1saXN0LWl0ZW1gIGF0dHJpYnV0ZXMuXG4gICAgICovXG4gICAgZ2V0IGl0ZW1zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5saXN0Q29udHJvbGxlci5pdGVtcztcbiAgICB9XG4gICAgd2lsbFVwZGF0ZShjaGFuZ2VkKSB7XG4gICAgICAgIGlmICghY2hhbmdlZC5oYXMoJ29wZW4nKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9wZW4pIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKCdhcmlhLWhpZGRlbicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7XG4gICAgfVxuICAgIHVwZGF0ZShjaGFuZ2VkKSB7XG4gICAgICAgIGlmIChjaGFuZ2VkLmhhcygnb3BlbicpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vcGVuKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRVcEdsb2JhbEV2ZW50TGlzdGVuZXJzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFuVXBHbG9iYWxFdmVudExpc3RlbmVycygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEZpcmVmb3ggZG9lcyBub3Qgc3VwcG9ydCBwb3BvdmVyLiBGYWxsLWJhY2sgdG8gdXNpbmcgZml4ZWQuXG4gICAgICAgIGlmIChjaGFuZ2VkLmhhcygncG9zaXRpb25pbmcnKSAmJlxuICAgICAgICAgICAgdGhpcy5wb3NpdGlvbmluZyA9PT0gJ3BvcG92ZXInICYmXG4gICAgICAgICAgICAvLyB0eXBlIHJlcXVpcmVkIGZvciBHb29nbGUgSlMgY29uZm9ybWFuY2VcbiAgICAgICAgICAgICF0aGlzLnNob3dQb3BvdmVyKSB7XG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uaW5nID0gJ2ZpeGVkJztcbiAgICAgICAgfVxuICAgICAgICBzdXBlci51cGRhdGUoY2hhbmdlZCk7XG4gICAgfVxuICAgIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgICAgICBzdXBlci5jb25uZWN0ZWRDYWxsYmFjaygpO1xuICAgICAgICBpZiAodGhpcy5vcGVuKSB7XG4gICAgICAgICAgICB0aGlzLnNldFVwR2xvYmFsRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICAgICAgc3VwZXIuZGlzY29ubmVjdGVkQ2FsbGJhY2soKTtcbiAgICAgICAgdGhpcy5jbGVhblVwR2xvYmFsRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB9XG4gICAgZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkge1xuICAgICAgICBpZiAoIXRoaXMuc3VyZmFjZUVsKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuc3VyZmFjZUVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIH1cbiAgICBnZXRDbGllbnRSZWN0cygpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN1cmZhY2VFbCkge1xuICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuc3VyZmFjZUVsLmdldENsaWVudFJlY3RzKCk7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyU3VyZmFjZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXJzIHRoZSBwb3NpdGlvbmFibGUgc3VyZmFjZSBlbGVtZW50IGFuZCBpdHMgY29udGVudHMuXG4gICAgICovXG4gICAgcmVuZGVyU3VyZmFjZSgpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cIm1lbnUgJHtjbGFzc01hcCh0aGlzLmdldFN1cmZhY2VDbGFzc2VzKCkpfVwiXG4gICAgICAgIHN0eWxlPSR7c3R5bGVNYXAodGhpcy5tZW51UG9zaXRpb25Db250cm9sbGVyLnN1cmZhY2VTdHlsZXMpfVxuICAgICAgICBwb3BvdmVyPSR7dGhpcy5wb3NpdGlvbmluZyA9PT0gJ3BvcG92ZXInID8gJ21hbnVhbCcgOiBub3RoaW5nfT5cbiAgICAgICAgJHt0aGlzLnJlbmRlckVsZXZhdGlvbigpfVxuICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbXNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1wYWRkaW5nXCI+ICR7dGhpcy5yZW5kZXJNZW51SXRlbXMoKX0gPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVycyB0aGUgbWVudSBpdGVtcycgc2xvdFxuICAgICAqL1xuICAgIHJlbmRlck1lbnVJdGVtcygpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYDxzbG90XG4gICAgICBAY2xvc2UtbWVudT0ke3RoaXMub25DbG9zZU1lbnV9XG4gICAgICBAZGVhY3RpdmF0ZS1pdGVtcz0ke3RoaXMub25EZWFjdGl2YXRlSXRlbXN9XG4gICAgICBAcmVxdWVzdC1hY3RpdmF0aW9uPSR7dGhpcy5vblJlcXVlc3RBY3RpdmF0aW9ufVxuICAgICAgQGRlYWN0aXZhdGUtdHlwZWFoZWFkPSR7dGhpcy5oYW5kbGVEZWFjdGl2YXRlVHlwZWFoZWFkfVxuICAgICAgQGFjdGl2YXRlLXR5cGVhaGVhZD0ke3RoaXMuaGFuZGxlQWN0aXZhdGVUeXBlYWhlYWR9XG4gICAgICBAc3RheS1vcGVuLW9uLWZvY3Vzb3V0PSR7dGhpcy5oYW5kbGVTdGF5T3Blbk9uRm9jdXNvdXR9XG4gICAgICBAY2xvc2Utb24tZm9jdXNvdXQ9JHt0aGlzLmhhbmRsZUNsb3NlT25Gb2N1c291dH1cbiAgICAgIEBzbG90Y2hhbmdlPSR7dGhpcy5saXN0Q29udHJvbGxlci5vblNsb3RjaGFuZ2V9Pjwvc2xvdD5gO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXJzIHRoZSBlbGV2YXRpb24gY29tcG9uZW50LlxuICAgICAqL1xuICAgIHJlbmRlckVsZXZhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYDxtZC1lbGV2YXRpb24gcGFydD1cImVsZXZhdGlvblwiPjwvbWQtZWxldmF0aW9uPmA7XG4gICAgfVxuICAgIGdldFN1cmZhY2VDbGFzc2VzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb3BlbjogdGhpcy5vcGVuLFxuICAgICAgICAgICAgZml4ZWQ6IHRoaXMucG9zaXRpb25pbmcgPT09ICdmaXhlZCcsXG4gICAgICAgICAgICAnaGFzLW92ZXJmbG93JzogdGhpcy5oYXNPdmVyZmxvdyxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY2FwdHVyZUtleWRvd24oZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gdGhpcyAmJlxuICAgICAgICAgICAgIWV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgJiZcbiAgICAgICAgICAgIGlzQ2xvc2FibGVLZXkoZXZlbnQuY29kZSkpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50eXBlYWhlYWRDb250cm9sbGVyLm9uS2V5ZG93bihldmVudCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIHRoZSBvcGVuaW5nIGFuaW1hdGlvbjpcbiAgICAgKlxuICAgICAqIGh0dHBzOi8vZGlyZWN0Lmdvb2dsZXBsZXguY29tLyMvc3BlYy8yOTUwMDAwMDMrMjcxMDYwMDAzXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmUgdG8gYHRydWVgIGlmIHRoZSBhbmltYXRpb24gd2FzIGFib3J0ZWQsXG4gICAgICogICAgIGBmYWxzZWAgaWYgaXQgd2FzIG5vdCBhYm9ydGVkLlxuICAgICAqL1xuICAgIGFzeW5jIGFuaW1hdGVPcGVuKCkge1xuICAgICAgICBjb25zdCBzdXJmYWNlRWwgPSB0aGlzLnN1cmZhY2VFbDtcbiAgICAgICAgY29uc3Qgc2xvdEVsID0gdGhpcy5zbG90RWw7XG4gICAgICAgIGlmICghc3VyZmFjZUVsIHx8ICFzbG90RWwpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY29uc3Qgb3BlbkRpcmVjdGlvbiA9IHRoaXMub3BlbkRpcmVjdGlvbjtcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnb3BlbmluZycpKTtcbiAgICAgICAgLy8gbmVlZHMgdG8gYmUgaW1wZXJhdGl2ZSBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG8gbWl4IGFuaW1hdGlvbiBhbmQgTGl0XG4gICAgICAgIC8vIHJlbmRlciB0aW1pbmdcbiAgICAgICAgc3VyZmFjZUVsLmNsYXNzTGlzdC50b2dnbGUoJ2FuaW1hdGluZycsIHRydWUpO1xuICAgICAgICBjb25zdCBzaWduYWwgPSB0aGlzLm9wZW5DbG9zZUFuaW1hdGlvblNpZ25hbC5zdGFydCgpO1xuICAgICAgICBjb25zdCBoZWlnaHQgPSBzdXJmYWNlRWwub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBjb25zdCBvcGVuaW5nVXB3YXJkcyA9IG9wZW5EaXJlY3Rpb24gPT09ICdVUCc7XG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5pdGVtcztcbiAgICAgICAgY29uc3QgRlVMTF9EVVJBVElPTiA9IDUwMDtcbiAgICAgICAgY29uc3QgU1VSRkFDRV9PUEFDSVRZX0RVUkFUSU9OID0gNTA7XG4gICAgICAgIGNvbnN0IElURU1fT1BBQ0lUWV9EVVJBVElPTiA9IDI1MDtcbiAgICAgICAgLy8gV2Ugd2FudCB0byBmaXQgZXZlcnkgY2hpbGQgZmFkZS1pbiBhbmltYXRpb24gd2l0aGluIHRoZSBmdWxsIGR1cmF0aW9uIG9mXG4gICAgICAgIC8vIHRoZSBhbmltYXRpb24uXG4gICAgICAgIGNvbnN0IERFTEFZX0JFVFdFRU5fSVRFTVMgPSAoRlVMTF9EVVJBVElPTiAtIElURU1fT1BBQ0lUWV9EVVJBVElPTikgLyBjaGlsZHJlbi5sZW5ndGg7XG4gICAgICAgIGNvbnN0IHN1cmZhY2VIZWlnaHRBbmltYXRpb24gPSBzdXJmYWNlRWwuYW5pbWF0ZShbeyBoZWlnaHQ6ICcwcHgnIH0sIHsgaGVpZ2h0OiBgJHtoZWlnaHR9cHhgIH1dLCB7XG4gICAgICAgICAgICBkdXJhdGlvbjogRlVMTF9EVVJBVElPTixcbiAgICAgICAgICAgIGVhc2luZzogRUFTSU5HLkVNUEhBU0laRUQsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBXaGVuIHdlIGFyZSBvcGVuaW5nIHVwd2FyZHMsIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHRoZSBsYXN0IGl0ZW0gaXMgYWx3YXlzXG4gICAgICAgIC8vIGluIHZpZXcsIHNvIHdlIG5lZWQgdG8gdHJhbnNsYXRlIGl0IHVwd2FyZHMgdGhlIG9wcG9zaXRlIGRpcmVjdGlvbiBvZiB0aGVcbiAgICAgICAgLy8gaGVpZ2h0IGFuaW1hdGlvblxuICAgICAgICBjb25zdCB1cFBvc2l0aW9uQ29ycmVjdGlvbkFuaW1hdGlvbiA9IHNsb3RFbC5hbmltYXRlKFtcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiBvcGVuaW5nVXB3YXJkcyA/IGB0cmFuc2xhdGVZKC0ke2hlaWdodH1weClgIDogJycgfSxcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiAnJyB9LFxuICAgICAgICBdLCB7IGR1cmF0aW9uOiBGVUxMX0RVUkFUSU9OLCBlYXNpbmc6IEVBU0lORy5FTVBIQVNJWkVEIH0pO1xuICAgICAgICBjb25zdCBzdXJmYWNlT3BhY2l0eUFuaW1hdGlvbiA9IHN1cmZhY2VFbC5hbmltYXRlKFt7IG9wYWNpdHk6IDAgfSwgeyBvcGFjaXR5OiAxIH1dLCBTVVJGQUNFX09QQUNJVFlfRFVSQVRJT04pO1xuICAgICAgICBjb25zdCBjaGlsZHJlbkFuaW1hdGlvbnMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgLy8gSWYgd2UgYXJlIGFuaW1hdGluZyB1cHdhcmRzLCB0aGVuIHJldmVyc2UgdGhlIGNoaWxkcmVuIGxpc3QuXG4gICAgICAgICAgICBjb25zdCBkaXJlY3Rpb25hbEluZGV4ID0gb3BlbmluZ1Vwd2FyZHMgPyBjaGlsZHJlbi5sZW5ndGggLSAxIC0gaSA6IGk7XG4gICAgICAgICAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2RpcmVjdGlvbmFsSW5kZXhdO1xuICAgICAgICAgICAgY29uc3QgYW5pbWF0aW9uID0gY2hpbGQuYW5pbWF0ZShbeyBvcGFjaXR5OiAwIH0sIHsgb3BhY2l0eTogMSB9XSwge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBJVEVNX09QQUNJVFlfRFVSQVRJT04sXG4gICAgICAgICAgICAgICAgZGVsYXk6IERFTEFZX0JFVFdFRU5fSVRFTVMgKiBpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBNYWtlIHRoZW0gYWxsIGluaXRpYWxseSBoaWRkZW4gYW5kIHRoZW4gY2xlYW4gdXAgYXQgdGhlIGVuZCBvZiBlYWNoXG4gICAgICAgICAgICAvLyBhbmltYXRpb24uXG4gICAgICAgICAgICBjaGlsZC5jbGFzc0xpc3QudG9nZ2xlKCdtZC1tZW51LWhpZGRlbicsIHRydWUpO1xuICAgICAgICAgICAgYW5pbWF0aW9uLmFkZEV2ZW50TGlzdGVuZXIoJ2ZpbmlzaCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICBjaGlsZC5jbGFzc0xpc3QudG9nZ2xlKCdtZC1tZW51LWhpZGRlbicsIGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY2hpbGRyZW5BbmltYXRpb25zLnB1c2goW2NoaWxkLCBhbmltYXRpb25dKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzb2x2ZUFuaW1hdGlvbiA9ICh2YWx1ZSkgPT4geyB9O1xuICAgICAgICBjb25zdCBhbmltYXRpb25GaW5pc2hlZCA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlQW5pbWF0aW9uID0gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsICgpID0+IHtcbiAgICAgICAgICAgIHN1cmZhY2VIZWlnaHRBbmltYXRpb24uY2FuY2VsKCk7XG4gICAgICAgICAgICB1cFBvc2l0aW9uQ29ycmVjdGlvbkFuaW1hdGlvbi5jYW5jZWwoKTtcbiAgICAgICAgICAgIHN1cmZhY2VPcGFjaXR5QW5pbWF0aW9uLmNhbmNlbCgpO1xuICAgICAgICAgICAgY2hpbGRyZW5BbmltYXRpb25zLmZvckVhY2goKFtjaGlsZCwgYW5pbWF0aW9uXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTGlzdC50b2dnbGUoJ21kLW1lbnUtaGlkZGVuJywgZmFsc2UpO1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5jYW5jZWwoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVzb2x2ZUFuaW1hdGlvbih0cnVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHN1cmZhY2VIZWlnaHRBbmltYXRpb24uYWRkRXZlbnRMaXN0ZW5lcignZmluaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgc3VyZmFjZUVsLmNsYXNzTGlzdC50b2dnbGUoJ2FuaW1hdGluZycsIGZhbHNlKTtcbiAgICAgICAgICAgIHRoaXMub3BlbkNsb3NlQW5pbWF0aW9uU2lnbmFsLmZpbmlzaCgpO1xuICAgICAgICAgICAgcmVzb2x2ZUFuaW1hdGlvbihmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gYXdhaXQgYW5pbWF0aW9uRmluaXNoZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIHRoZSBjbG9zaW5nIGFuaW1hdGlvbjpcbiAgICAgKlxuICAgICAqIGh0dHBzOi8vZGlyZWN0Lmdvb2dsZXBsZXguY29tLyMvc3BlYy8yOTUwMDAwMDMrMjcxMDYwMDAzXG4gICAgICovXG4gICAgYW5pbWF0ZUNsb3NlKCkge1xuICAgICAgICBsZXQgcmVzb2x2ZTtcbiAgICAgICAgLy8gVGhpcyBwcm9taXNlIGJsb2NrcyB0aGUgc3VyZmFjZSBwb3NpdGlvbiBjb250cm9sbGVyIGZyb20gc2V0dGluZ1xuICAgICAgICAvLyBkaXNwbGF5OiBub25lIG9uIHRoZSBzdXJmYWNlIHdoaWNoIHdpbGwgaW50ZXJmZXJlIHdpdGggdGhpcyBhbmltYXRpb24uXG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbkVuZGVkID0gbmV3IFByb21pc2UoKHJlcykgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZSA9IHJlcztcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1cmZhY2VFbCA9IHRoaXMuc3VyZmFjZUVsO1xuICAgICAgICBjb25zdCBzbG90RWwgPSB0aGlzLnNsb3RFbDtcbiAgICAgICAgaWYgKCFzdXJmYWNlRWwgfHwgIXNsb3RFbCkge1xuICAgICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICByZXR1cm4gYW5pbWF0aW9uRW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3BlbkRpcmVjdGlvbiA9IHRoaXMub3BlbkRpcmVjdGlvbjtcbiAgICAgICAgY29uc3QgY2xvc2luZ0Rvd253YXJkcyA9IG9wZW5EaXJlY3Rpb24gPT09ICdVUCc7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2Nsb3NpbmcnKSk7XG4gICAgICAgIC8vIG5lZWRzIHRvIGJlIGltcGVyYXRpdmUgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIG1peCBhbmltYXRpb24gYW5kIExpdFxuICAgICAgICAvLyByZW5kZXIgdGltaW5nXG4gICAgICAgIHN1cmZhY2VFbC5jbGFzc0xpc3QudG9nZ2xlKCdhbmltYXRpbmcnLCB0cnVlKTtcbiAgICAgICAgY29uc3Qgc2lnbmFsID0gdGhpcy5vcGVuQ2xvc2VBbmltYXRpb25TaWduYWwuc3RhcnQoKTtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gc3VyZmFjZUVsLm9mZnNldEhlaWdodDtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLml0ZW1zO1xuICAgICAgICBjb25zdCBGVUxMX0RVUkFUSU9OID0gMTUwO1xuICAgICAgICBjb25zdCBTVVJGQUNFX09QQUNJVFlfRFVSQVRJT04gPSA1MDtcbiAgICAgICAgLy8gVGhlIHN1cmZhY2UgZmFkZXMgYXdheSBhdCB0aGUgdmVyeSBlbmRcbiAgICAgICAgY29uc3QgU1VSRkFDRV9PUEFDSVRZX0RFTEFZID0gRlVMTF9EVVJBVElPTiAtIFNVUkZBQ0VfT1BBQ0lUWV9EVVJBVElPTjtcbiAgICAgICAgY29uc3QgSVRFTV9PUEFDSVRZX0RVUkFUSU9OID0gNTA7XG4gICAgICAgIGNvbnN0IElURU1fT1BBQ0lUWV9JTklUSUFMX0RFTEFZID0gNTA7XG4gICAgICAgIGNvbnN0IEVORF9IRUlHSFRfUEVSQ0VOVEFHRSA9IDAuMzU7XG4gICAgICAgIC8vIFdlIHdhbnQgdG8gZml0IGV2ZXJ5IGNoaWxkIGZhZGUtb3V0IGFuaW1hdGlvbiB3aXRoaW4gdGhlIGZ1bGwgZHVyYXRpb24gb2ZcbiAgICAgICAgLy8gdGhlIGFuaW1hdGlvbi5cbiAgICAgICAgY29uc3QgREVMQVlfQkVUV0VFTl9JVEVNUyA9IChGVUxMX0RVUkFUSU9OIC0gSVRFTV9PUEFDSVRZX0lOSVRJQUxfREVMQVkgLSBJVEVNX09QQUNJVFlfRFVSQVRJT04pIC9cbiAgICAgICAgICAgIGNoaWxkcmVuLmxlbmd0aDtcbiAgICAgICAgLy8gVGhlIG1vY2sgaGFzIHRoZSBhbmltYXRpb24gc2hyaW5rIHRvIDM1JVxuICAgICAgICBjb25zdCBzdXJmYWNlSGVpZ2h0QW5pbWF0aW9uID0gc3VyZmFjZUVsLmFuaW1hdGUoW1xuICAgICAgICAgICAgeyBoZWlnaHQ6IGAke2hlaWdodH1weGAgfSxcbiAgICAgICAgICAgIHsgaGVpZ2h0OiBgJHtoZWlnaHQgKiBFTkRfSEVJR0hUX1BFUkNFTlRBR0V9cHhgIH0sXG4gICAgICAgIF0sIHtcbiAgICAgICAgICAgIGR1cmF0aW9uOiBGVUxMX0RVUkFUSU9OLFxuICAgICAgICAgICAgZWFzaW5nOiBFQVNJTkcuRU1QSEFTSVpFRF9BQ0NFTEVSQVRFLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gV2hlbiB3ZSBhcmUgY2xvc2luZyBkb3dud2FyZHMsIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHRoZSBsYXN0IGl0ZW0gaXNcbiAgICAgICAgLy8gYWx3YXlzIGluIHZpZXcsIHNvIHdlIG5lZWQgdG8gdHJhbnNsYXRlIGl0IHVwd2FyZHMgdGhlIG9wcG9zaXRlIGRpcmVjdGlvblxuICAgICAgICAvLyBvZiB0aGUgaGVpZ2h0IGFuaW1hdGlvblxuICAgICAgICBjb25zdCBkb3duUG9zaXRpb25Db3JyZWN0aW9uQW5pbWF0aW9uID0gc2xvdEVsLmFuaW1hdGUoW1xuICAgICAgICAgICAgeyB0cmFuc2Zvcm06ICcnIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBjbG9zaW5nRG93bndhcmRzXG4gICAgICAgICAgICAgICAgICAgID8gYHRyYW5zbGF0ZVkoLSR7aGVpZ2h0ICogKDEgLSBFTkRfSEVJR0hUX1BFUkNFTlRBR0UpfXB4KWBcbiAgICAgICAgICAgICAgICAgICAgOiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF0sIHsgZHVyYXRpb246IEZVTExfRFVSQVRJT04sIGVhc2luZzogRUFTSU5HLkVNUEhBU0laRURfQUNDRUxFUkFURSB9KTtcbiAgICAgICAgY29uc3Qgc3VyZmFjZU9wYWNpdHlBbmltYXRpb24gPSBzdXJmYWNlRWwuYW5pbWF0ZShbeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9XSwgeyBkdXJhdGlvbjogU1VSRkFDRV9PUEFDSVRZX0RVUkFUSU9OLCBkZWxheTogU1VSRkFDRV9PUEFDSVRZX0RFTEFZIH0pO1xuICAgICAgICBjb25zdCBjaGlsZHJlbkFuaW1hdGlvbnMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgLy8gSWYgdGhlIGFuaW1hdGlvbiBpcyBjbG9zaW5nIHVwd2FyZHMsIHRoZW4gcmV2ZXJzZSB0aGUgbGlzdCBvZlxuICAgICAgICAgICAgLy8gY2hpbGRyZW4gc28gdGhhdCB3ZSBhbmltYXRlIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24uXG4gICAgICAgICAgICBjb25zdCBkaXJlY3Rpb25hbEluZGV4ID0gY2xvc2luZ0Rvd253YXJkcyA/IGkgOiBjaGlsZHJlbi5sZW5ndGggLSAxIC0gaTtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5bZGlyZWN0aW9uYWxJbmRleF07XG4gICAgICAgICAgICBjb25zdCBhbmltYXRpb24gPSBjaGlsZC5hbmltYXRlKFt7IG9wYWNpdHk6IDEgfSwgeyBvcGFjaXR5OiAwIH1dLCB7XG4gICAgICAgICAgICAgICAgZHVyYXRpb246IElURU1fT1BBQ0lUWV9EVVJBVElPTixcbiAgICAgICAgICAgICAgICBkZWxheTogSVRFTV9PUEFDSVRZX0lOSVRJQUxfREVMQVkgKyBERUxBWV9CRVRXRUVOX0lURU1TICogaSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSBpdGVtcyBzdGF5IGhpZGRlbiBhdCB0aGUgZW5kIG9mIGVhY2ggY2hpbGQgYW5pbWF0aW9uLlxuICAgICAgICAgICAgLy8gV2UgY2xlYW4gdGhpcyB1cCBhdCB0aGUgZW5kIG9mIHRoZSBvdmVyYWxsIGFuaW1hdGlvbi5cbiAgICAgICAgICAgIGFuaW1hdGlvbi5hZGRFdmVudExpc3RlbmVyKCdmaW5pc2gnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2hpbGQuY2xhc3NMaXN0LnRvZ2dsZSgnbWQtbWVudS1oaWRkZW4nLCB0cnVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY2hpbGRyZW5BbmltYXRpb25zLnB1c2goW2NoaWxkLCBhbmltYXRpb25dKTtcbiAgICAgICAgfVxuICAgICAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCAoKSA9PiB7XG4gICAgICAgICAgICBzdXJmYWNlSGVpZ2h0QW5pbWF0aW9uLmNhbmNlbCgpO1xuICAgICAgICAgICAgZG93blBvc2l0aW9uQ29ycmVjdGlvbkFuaW1hdGlvbi5jYW5jZWwoKTtcbiAgICAgICAgICAgIHN1cmZhY2VPcGFjaXR5QW5pbWF0aW9uLmNhbmNlbCgpO1xuICAgICAgICAgICAgY2hpbGRyZW5BbmltYXRpb25zLmZvckVhY2goKFtjaGlsZCwgYW5pbWF0aW9uXSkgPT4ge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5jYW5jZWwoKTtcbiAgICAgICAgICAgICAgICBjaGlsZC5jbGFzc0xpc3QudG9nZ2xlKCdtZC1tZW51LWhpZGRlbicsIGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBzdXJmYWNlSGVpZ2h0QW5pbWF0aW9uLmFkZEV2ZW50TGlzdGVuZXIoJ2ZpbmlzaCcsICgpID0+IHtcbiAgICAgICAgICAgIHN1cmZhY2VFbC5jbGFzc0xpc3QudG9nZ2xlKCdhbmltYXRpbmcnLCBmYWxzZSk7XG4gICAgICAgICAgICBjaGlsZHJlbkFuaW1hdGlvbnMuZm9yRWFjaCgoW2NoaWxkXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTGlzdC50b2dnbGUoJ21kLW1lbnUtaGlkZGVuJywgZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLm9wZW5DbG9zZUFuaW1hdGlvblNpZ25hbC5maW5pc2goKTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2Nsb3NlZCcpKTtcbiAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gYW5pbWF0aW9uRW5kZWQ7XG4gICAgfVxuICAgIGhhbmRsZUtleWRvd24oZXZlbnQpIHtcbiAgICAgICAgLy8gQXQgYW55IGtleSBldmVudCwgdGhlIHBvaW50ZXIgaW50ZXJhY3Rpb24gaXMgZG9uZSBzbyB3ZSBuZWVkIHRvIGNsZWFyIG91clxuICAgICAgICAvLyBjYWNoZWQgcG9pbnRlcnBhdGguIFRoaXMgaGFuZGxlcyB0aGUgY2FzZSB3aGVyZSB0aGUgdXNlciBjbGlja3Mgb24gdGhlXG4gICAgICAgIC8vIGFuY2hvciwgYW5kIHRoZW4gaGl0cyBzaGlmdCt0YWJcbiAgICAgICAgdGhpcy5wb2ludGVyUGF0aCA9IFtdO1xuICAgICAgICB0aGlzLmxpc3RDb250cm9sbGVyLmhhbmRsZUtleWRvd24oZXZlbnQpO1xuICAgIH1cbiAgICBzZXRVcEdsb2JhbEV2ZW50TGlzdGVuZXJzKCkge1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25Eb2N1bWVudENsaWNrLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIHRoaXMub25XaW5kb3dQb2ludGVyZG93bik7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMub25XaW5kb3dSZXNpemUsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMub25XaW5kb3dSZXNpemUsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICB9XG4gICAgY2xlYW5VcEdsb2JhbEV2ZW50TGlzdGVuZXJzKCkge1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25Eb2N1bWVudENsaWNrLCB7XG4gICAgICAgICAgICBjYXB0dXJlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vbldpbmRvd1BvaW50ZXJkb3duKTtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5vbldpbmRvd1Jlc2l6ZSk7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLm9uV2luZG93UmVzaXplKTtcbiAgICB9XG4gICAgb25DbG9zZU1lbnUoKSB7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICB9XG4gICAgb25EZWFjdGl2YXRlSXRlbXMoZXZlbnQpIHtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMubGlzdENvbnRyb2xsZXIub25EZWFjdGl2YXRlSXRlbXMoKTtcbiAgICB9XG4gICAgb25SZXF1ZXN0QWN0aXZhdGlvbihldmVudCkge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgdGhpcy5saXN0Q29udHJvbGxlci5vblJlcXVlc3RBY3RpdmF0aW9uKGV2ZW50KTtcbiAgICB9XG4gICAgaGFuZGxlRGVhY3RpdmF0ZVR5cGVhaGVhZChldmVudCkge1xuICAgICAgICAvLyBzdG9wUHJvcGFnYXRpb24gc28gdGhhdCB0aGlzIGRvZXMgbm90IGRlYWN0aXZhdGUgYW55IHR5cGVhaGVhZHMgaW4gbWVudXNcbiAgICAgICAgLy8gbmVzdGVkIGFib3ZlIGl0IGUuZy4gbWQtc3ViLW1lbnVcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMudHlwZWFoZWFkQWN0aXZlID0gZmFsc2U7XG4gICAgfVxuICAgIGhhbmRsZUFjdGl2YXRlVHlwZWFoZWFkKGV2ZW50KSB7XG4gICAgICAgIC8vIHN0b3BQcm9wYWdhdGlvbiBzbyB0aGF0IHRoaXMgZG9lcyBub3QgYWN0aXZhdGUgYW55IHR5cGVhaGVhZHMgaW4gbWVudXNcbiAgICAgICAgLy8gbmVzdGVkIGFib3ZlIGl0IGUuZy4gbWQtc3ViLW1lbnVcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMudHlwZWFoZWFkQWN0aXZlID0gdHJ1ZTtcbiAgICB9XG4gICAgaGFuZGxlU3RheU9wZW5PbkZvY3Vzb3V0KGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB0aGlzLnN0YXlPcGVuT25Gb2N1c291dCA9IHRydWU7XG4gICAgfVxuICAgIGhhbmRsZUNsb3NlT25Gb2N1c291dChldmVudCkge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgdGhpcy5zdGF5T3Blbk9uRm9jdXNvdXQgPSBmYWxzZTtcbiAgICB9XG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHRoaXMub3BlbiA9IGZhbHNlO1xuICAgICAgICBjb25zdCBtYXliZVN1Ym1lbnUgPSB0aGlzLnNsb3RJdGVtcztcbiAgICAgICAgbWF5YmVTdWJtZW51LmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGl0ZW0uY2xvc2U/LigpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2hvdygpIHtcbiAgICAgICAgdGhpcy5vcGVuID0gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWN0aXZhdGVzIHRoZSBuZXh0IGl0ZW0gaW4gdGhlIG1lbnUuIElmIGF0IHRoZSBlbmQgb2YgdGhlIG1lbnUsIHRoZSBmaXJzdFxuICAgICAqIGl0ZW0gd2lsbCBiZSBhY3RpdmF0ZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIFRoZSBhY3RpdmF0ZWQgbWVudSBpdGVtIG9yIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gaXRlbXMuXG4gICAgICovXG4gICAgYWN0aXZhdGVOZXh0SXRlbSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdENvbnRyb2xsZXIuYWN0aXZhdGVOZXh0SXRlbSgpID8/IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFjdGl2YXRlcyB0aGUgcHJldmlvdXMgaXRlbSBpbiB0aGUgbWVudS4gSWYgYXQgdGhlIHN0YXJ0IG9mIHRoZSBtZW51LCB0aGVcbiAgICAgKiBsYXN0IGl0ZW0gd2lsbCBiZSBhY3RpdmF0ZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIFRoZSBhY3RpdmF0ZWQgbWVudSBpdGVtIG9yIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gaXRlbXMuXG4gICAgICovXG4gICAgYWN0aXZhdGVQcmV2aW91c0l0ZW0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RDb250cm9sbGVyLmFjdGl2YXRlUHJldmlvdXNJdGVtKCkgPz8gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVwb3NpdGlvbnMgdGhlIG1lbnUgaWYgaXQgaXMgb3Blbi5cbiAgICAgKlxuICAgICAqIFVzZWZ1bCBmb3IgdGhlIGNhc2Ugd2hlcmUgZG9jdW1lbnQgb3Igd2luZG93LXBvc2l0aW9uZWQgbWVudXMgaGF2ZSB0aGVpclxuICAgICAqIGFuY2hvcnMgbW92ZWQgd2hpbGUgb3Blbi5cbiAgICAgKi9cbiAgICByZXBvc2l0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5vcGVuKSB7XG4gICAgICAgICAgICB0aGlzLm1lbnVQb3NpdGlvbkNvbnRyb2xsZXIucG9zaXRpb24oKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5KCcubWVudScpXG5dLCBNZW51LnByb3RvdHlwZSwgXCJzdXJmYWNlRWxcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5KCdzbG90Jylcbl0sIE1lbnUucHJvdG90eXBlLCBcInNsb3RFbFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoKVxuXSwgTWVudS5wcm90b3R5cGUsIFwiYW5jaG9yXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBNZW51LnByb3RvdHlwZSwgXCJwb3NpdGlvbmluZ1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuIH0pXG5dLCBNZW51LnByb3RvdHlwZSwgXCJxdWlja1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdoYXMtb3ZlcmZsb3cnIH0pXG5dLCBNZW51LnByb3RvdHlwZSwgXCJoYXNPdmVyZmxvd1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCByZWZsZWN0OiB0cnVlIH0pXG5dLCBNZW51LnByb3RvdHlwZSwgXCJvcGVuXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IE51bWJlciwgYXR0cmlidXRlOiAneC1vZmZzZXQnIH0pXG5dLCBNZW51LnByb3RvdHlwZSwgXCJ4T2Zmc2V0XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IE51bWJlciwgYXR0cmlidXRlOiAneS1vZmZzZXQnIH0pXG5dLCBNZW51LnByb3RvdHlwZSwgXCJ5T2Zmc2V0XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ25vLWhvcml6b250YWwtZmxpcCcgfSlcbl0sIE1lbnUucHJvdG90eXBlLCBcIm5vSG9yaXpvbnRhbEZsaXBcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnbm8tdmVydGljYWwtZmxpcCcgfSlcbl0sIE1lbnUucHJvdG90eXBlLCBcIm5vVmVydGljYWxGbGlwXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IE51bWJlciwgYXR0cmlidXRlOiAndHlwZWFoZWFkLWRlbGF5JyB9KVxuXSwgTWVudS5wcm90b3R5cGUsIFwidHlwZWFoZWFkRGVsYXlcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgYXR0cmlidXRlOiAnYW5jaG9yLWNvcm5lcicgfSlcbl0sIE1lbnUucHJvdG90eXBlLCBcImFuY2hvckNvcm5lclwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyBhdHRyaWJ1dGU6ICdtZW51LWNvcm5lcicgfSlcbl0sIE1lbnUucHJvdG90eXBlLCBcIm1lbnVDb3JuZXJcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnc3RheS1vcGVuLW9uLW91dHNpZGUtY2xpY2snIH0pXG5dLCBNZW51LnByb3RvdHlwZSwgXCJzdGF5T3Blbk9uT3V0c2lkZUNsaWNrXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ3N0YXktb3Blbi1vbi1mb2N1c291dCcgfSlcbl0sIE1lbnUucHJvdG90eXBlLCBcInN0YXlPcGVuT25Gb2N1c291dFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdza2lwLXJlc3RvcmUtZm9jdXMnIH0pXG5dLCBNZW51LnByb3RvdHlwZSwgXCJza2lwUmVzdG9yZUZvY3VzXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IGF0dHJpYnV0ZTogJ2RlZmF1bHQtZm9jdXMnIH0pXG5dLCBNZW51LnByb3RvdHlwZSwgXCJkZWZhdWx0Rm9jdXNcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnbm8tbmF2aWdhdGlvbi13cmFwJyB9KVxuXSwgTWVudS5wcm90b3R5cGUsIFwibm9OYXZpZ2F0aW9uV3JhcFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcXVlcnlBc3NpZ25lZEVsZW1lbnRzKHsgZmxhdHRlbjogdHJ1ZSB9KVxuXSwgTWVudS5wcm90b3R5cGUsIFwic2xvdEl0ZW1zXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBNZW51LnByb3RvdHlwZSwgXCJ0eXBlYWhlYWRBY3RpdmVcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1lbnUuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjQgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLy8gR2VuZXJhdGVkIHN0eWxlc2hlZXQgZm9yIC4vbWVudS9pbnRlcm5hbC9tZW51aXRlbS9tZW51LWl0ZW0tc3R5bGVzLmNzcy5cbmltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5leHBvcnQgY29uc3Qgc3R5bGVzID0gY3NzIGA6aG9zdHtkaXNwbGF5OmZsZXg7LS1tZC1yaXBwbGUtaG92ZXItY29sb3I6IHZhcigtLW1kLW1lbnUtaXRlbS1ob3Zlci1zdGF0ZS1sYXllci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLW1kLXJpcHBsZS1ob3Zlci1vcGFjaXR5OiB2YXIoLS1tZC1tZW51LWl0ZW0taG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4wOCk7LS1tZC1yaXBwbGUtcHJlc3NlZC1jb2xvcjogdmFyKC0tbWQtbWVudS1pdGVtLXByZXNzZWQtc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1tZC1yaXBwbGUtcHJlc3NlZC1vcGFjaXR5OiB2YXIoLS1tZC1tZW51LWl0ZW0tcHJlc3NlZC1zdGF0ZS1sYXllci1vcGFjaXR5LCAwLjEyKX06aG9zdChbZGlzYWJsZWRdKXtvcGFjaXR5OnZhcigtLW1kLW1lbnUtaXRlbS1kaXNhYmxlZC1vcGFjaXR5LCAwLjMpO3BvaW50ZXItZXZlbnRzOm5vbmV9bWQtZm9jdXMtcmluZ3t6LWluZGV4OjE7LS1tZC1mb2N1cy1yaW5nLXNoYXBlOiA4cHh9YSxidXR0b24sbGl7YmFja2dyb3VuZDpub25lO2JvcmRlcjpub25lO3BhZGRpbmc6MDttYXJnaW46MDt0ZXh0LWFsaWduOnVuc2V0O3RleHQtZGVjb3JhdGlvbjpub25lfS5saXN0LWl0ZW17Ym9yZGVyLXJhZGl1czppbmhlcml0O2Rpc3BsYXk6ZmxleDtmbGV4OjE7bWF4LXdpZHRoOmluaGVyaXQ7bWluLXdpZHRoOmluaGVyaXQ7b3V0bGluZTpub25lOy13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjpyZ2JhKDAsMCwwLDApfS5saXN0LWl0ZW06bm90KC5kaXNhYmxlZCl7Y3Vyc29yOnBvaW50ZXJ9W3Nsb3Q9Y29udGFpbmVyXXtwb2ludGVyLWV2ZW50czpub25lfW1kLXJpcHBsZXtib3JkZXItcmFkaXVzOmluaGVyaXR9bWQtaXRlbXtib3JkZXItcmFkaXVzOmluaGVyaXQ7ZmxleDoxO2NvbG9yOnZhcigtLW1kLW1lbnUtaXRlbS1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpO2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lbnUtaXRlbS1sYWJlbC10ZXh0LWZvbnQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1mb250LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2UtcGxhaW4sIFJvYm90bykpKTtmb250LXNpemU6dmFyKC0tbWQtbWVudS1pdGVtLWxhYmVsLXRleHQtc2l6ZSwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLXNpemUsIDFyZW0pKTtsaW5lLWhlaWdodDp2YXIoLS1tZC1tZW51LWl0ZW0tbGFiZWwtdGV4dC1saW5lLWhlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLWxpbmUtaGVpZ2h0LCAxLjVyZW0pKTtmb250LXdlaWdodDp2YXIoLS1tZC1tZW51LWl0ZW0tbGFiZWwtdGV4dC13ZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS13ZWlnaHQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS13ZWlnaHQtcmVndWxhciwgNDAwKSkpO21pbi1oZWlnaHQ6dmFyKC0tbWQtbWVudS1pdGVtLW9uZS1saW5lLWNvbnRhaW5lci1oZWlnaHQsIDU2cHgpO3BhZGRpbmctdG9wOnZhcigtLW1kLW1lbnUtaXRlbS10b3Atc3BhY2UsIDEycHgpO3BhZGRpbmctYm90dG9tOnZhcigtLW1kLW1lbnUtaXRlbS1ib3R0b20tc3BhY2UsIDEycHgpO3BhZGRpbmctaW5saW5lLXN0YXJ0OnZhcigtLW1kLW1lbnUtaXRlbS1sZWFkaW5nLXNwYWNlLCAxNnB4KTtwYWRkaW5nLWlubGluZS1lbmQ6dmFyKC0tbWQtbWVudS1pdGVtLXRyYWlsaW5nLXNwYWNlLCAxNnB4KX1tZC1pdGVtW211bHRpbGluZV17bWluLWhlaWdodDp2YXIoLS1tZC1tZW51LWl0ZW0tdHdvLWxpbmUtY29udGFpbmVyLWhlaWdodCwgNzJweCl9W3Nsb3Q9c3VwcG9ydGluZy10ZXh0XXtjb2xvcjp2YXIoLS1tZC1tZW51LWl0ZW0tc3VwcG9ydGluZy10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7Zm9udC1mYW1pbHk6dmFyKC0tbWQtbWVudS1pdGVtLXN1cHBvcnRpbmctdGV4dC1mb250LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbWVkaXVtLWZvbnQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS1wbGFpbiwgUm9ib3RvKSkpO2ZvbnQtc2l6ZTp2YXIoLS1tZC1tZW51LWl0ZW0tc3VwcG9ydGluZy10ZXh0LXNpemUsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1tZWRpdW0tc2l6ZSwgMC44NzVyZW0pKTtsaW5lLWhlaWdodDp2YXIoLS1tZC1tZW51LWl0ZW0tc3VwcG9ydGluZy10ZXh0LWxpbmUtaGVpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbWVkaXVtLWxpbmUtaGVpZ2h0LCAxLjI1cmVtKSk7Zm9udC13ZWlnaHQ6dmFyKC0tbWQtbWVudS1pdGVtLXN1cHBvcnRpbmctdGV4dC13ZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1tZWRpdW0td2VpZ2h0LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2Utd2VpZ2h0LXJlZ3VsYXIsIDQwMCkpKX1bc2xvdD10cmFpbGluZy1zdXBwb3J0aW5nLXRleHRde2NvbG9yOnZhcigtLW1kLW1lbnUtaXRlbS10cmFpbGluZy1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZW51LWl0ZW0tdHJhaWxpbmctc3VwcG9ydGluZy10ZXh0LWZvbnQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtbGFiZWwtc21hbGwtZm9udCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXBsYWluLCBSb2JvdG8pKSk7Zm9udC1zaXplOnZhcigtLW1kLW1lbnUtaXRlbS10cmFpbGluZy1zdXBwb3J0aW5nLXRleHQtc2l6ZSwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1sYWJlbC1zbWFsbC1zaXplLCAwLjY4NzVyZW0pKTtsaW5lLWhlaWdodDp2YXIoLS1tZC1tZW51LWl0ZW0tdHJhaWxpbmctc3VwcG9ydGluZy10ZXh0LWxpbmUtaGVpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWxhYmVsLXNtYWxsLWxpbmUtaGVpZ2h0LCAxcmVtKSk7Zm9udC13ZWlnaHQ6dmFyKC0tbWQtbWVudS1pdGVtLXRyYWlsaW5nLXN1cHBvcnRpbmctdGV4dC13ZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtbGFiZWwtc21hbGwtd2VpZ2h0LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2Utd2VpZ2h0LW1lZGl1bSwgNTAwKSkpfTppcyhbc2xvdD1zdGFydF0sW3Nsb3Q9ZW5kXSk6OnNsb3R0ZWQoKil7ZmlsbDpjdXJyZW50Q29sb3J9W3Nsb3Q9c3RhcnRde2NvbG9yOnZhcigtLW1kLW1lbnUtaXRlbS1sZWFkaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKX1bc2xvdD1lbmRde2NvbG9yOnZhcigtLW1kLW1lbnUtaXRlbS10cmFpbGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSl9Lmxpc3QtaXRlbXtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLW1kLW1lbnUtaXRlbS1jb250YWluZXItY29sb3IsIHRyYW5zcGFyZW50KX0ubGlzdC1pdGVtLnNlbGVjdGVke2JhY2tncm91bmQtY29sb3I6dmFyKC0tbWQtbWVudS1pdGVtLXNlbGVjdGVkLWNvbnRhaW5lci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXNlY29uZGFyeS1jb250YWluZXIsICNlOGRlZjgpKX0uc2VsZWN0ZWQ6bm90KC5kaXNhYmxlZCkgOjpzbG90dGVkKCope2NvbG9yOnZhcigtLW1kLW1lbnUtaXRlbS1zZWxlY3RlZC1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc2Vjb25kYXJ5LWNvbnRhaW5lciwgIzFkMTkyYikpfUBtZWRpYShmb3JjZWQtY29sb3JzOiBhY3RpdmUpezpob3N0KFtkaXNhYmxlZF0pLDpob3N0KFtkaXNhYmxlZF0pIHNsb3R7Y29sb3I6R3JheVRleHQ7b3BhY2l0eToxfS5saXN0LWl0ZW17cG9zaXRpb246cmVsYXRpdmV9Lmxpc3QtaXRlbS5zZWxlY3RlZDo6YmVmb3Jle2NvbnRlbnQ6XCJcIjtwb3NpdGlvbjphYnNvbHV0ZTtpbnNldDowO2JveC1zaXppbmc6Ym9yZGVyLWJveDtib3JkZXItcmFkaXVzOmluaGVyaXQ7cG9pbnRlci1ldmVudHM6bm9uZTtib3JkZXI6M3B4IGRvdWJsZSBDYW52YXNUZXh0fX1cbmA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZW51LWl0ZW0tc3R5bGVzLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGN1c3RvbUVsZW1lbnQgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5pbXBvcnQgeyBNZW51IH0gZnJvbSAnLi9pbnRlcm5hbC9tZW51LmpzJztcbmltcG9ydCB7IHN0eWxlcyB9IGZyb20gJy4vaW50ZXJuYWwvbWVudS1zdHlsZXMuanMnO1xuZXhwb3J0IHsgQ2xvc2VSZWFzb24sIEZvY3VzU3RhdGUsIH0gZnJvbSAnLi9pbnRlcm5hbC9jb250cm9sbGVycy9zaGFyZWQuanMnO1xuZXhwb3J0IHsgQ29ybmVyIH0gZnJvbSAnLi9pbnRlcm5hbC9tZW51LmpzJztcbi8qKlxuICogQHN1bW1hcnkgTWVudXMgZGlzcGxheSBhIGxpc3Qgb2YgY2hvaWNlcyBvbiBhIHRlbXBvcmFyeSBzdXJmYWNlLlxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogTWVudXMgYXBwZWFyIHdoZW4gdXNlcnMgaW50ZXJhY3Qgd2l0aCBhIGJ1dHRvbiwgYWN0aW9uLCBvciBvdGhlciBjb250cm9sLlxuICpcbiAqIFRoZXkgY2FuIGJlIG9wZW5lZCBmcm9tIGEgdmFyaWV0eSBvZiBlbGVtZW50cywgbW9zdCBjb21tb25seSBpY29uIGJ1dHRvbnMsXG4gKiBidXR0b25zLCBhbmQgdGV4dCBmaWVsZHMuXG4gKlxuICogbWQtbWVudSBsaXN0ZW5zIGZvciB0aGUgYGNsb3NlLW1lbnVgIGFuZCBgZGVzZWxlY3QtaXRlbXNgIGV2ZW50cy5cbiAqXG4gKiAtIGBjbG9zZS1tZW51YCBjbG9zZXMgdGhlIG1lbnUgd2hlbiBkaXNwYXRjaGVkIGZyb20gYSBjaGlsZCBlbGVtZW50LlxuICogLSBgZGVzZWxlY3QtaXRlbXNgIGRlc2VsZWN0cyBhbGwgb2YgaXRzIGltbWVkaWF0ZSBtZW51LWl0ZW0gY2hpbGRyZW4uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGh0bWxcbiAqIDxkaXYgc3R5bGU9XCJwb3NpdGlvbjpyZWxhdGl2ZTtcIj5cbiAqICAgPGJ1dHRvblxuICogICAgICAgaWQ9XCJhbmNob3JcIlxuICogICAgICAgQGNsaWNrPSR7KCkgPT4gdGhpcy5tZW51UmVmLnZhbHVlLnNob3coKX0+XG4gKiAgICAgQ2xpY2sgdG8gb3BlbiBtZW51XG4gKiAgIDwvYnV0dG9uPlxuICogICA8IS0tXG4gKiAgICAgYGhhcy1vdmVyZmxvd2AgaXMgcmVxdWlyZWQgd2hlbiB1c2luZyBhIHN1Ym1lbnUgd2hpY2ggb3ZlcmZsb3dzIHRoZVxuICogICAgIG1lbnUncyBjb250ZW50cy5cbiAqXG4gKiAgICAgQWRkaXRpb25hbGx5LCBgYW5jaG9yYCBpbmdlc3RzIGFuIGlkcmVmIHdoaWNoIGRvIG5vdCBwYXNzIHRocm91Z2ggc2hhZG93XG4gKiAgICAgcm9vdHMuIFlvdSBjYW4gYWxzbyBzZXQgYC5hbmNob3JFbGVtZW50YCB0byBhbiBlbGVtZW50IHJlZmVyZW5jZSBpZlxuICogICAgIG5lY2Vzc2FyeS5cbiAqICAgLS0+XG4gKiAgIDxtZC1tZW51IGFuY2hvcj1cImFuY2hvclwiIGhhcy1vdmVyZmxvdyAke3JlZihtZW51UmVmKX0+XG4gKiAgICAgPG1kLW1lbnUtaXRlbSBoZWFkbGluZT1cIlRoaXMgaXMgYSBoZWFkbGluZVwiPjwvbWQtbWVudS1pdGVtPlxuICogICAgIDxtZC1zdWItbWVudT5cbiAqICAgICAgIDxtZC1tZW51LWl0ZW1cbiAqICAgICAgICAgICBzbG90PVwiaXRlbVwiXG4gKiAgICAgICAgICAgaGVhZGxpbmU9XCJ0aGlzIGlzIGEgc3VibWVudSBpdGVtXCI+XG4gKiAgICAgICA8L21kLW1lbnUtaXRlbT5cbiAqICAgICAgIDxtZC1tZW51IHNsb3Q9XCJtZW51XCI+XG4gKiAgICAgICAgIDxtZC1tZW51LWl0ZW0gaGVhZGxpbmU9XCJUaGlzIGlzIGFuIGl0ZW0gaW5zaWRlIGEgc3VibWVudVwiPlxuICogICAgICAgICA8L21kLW1lbnUtaXRlbT5cbiAqICAgICAgIDwvbWQtbWVudT5cbiAqICAgICA8L21kLXN1Yi1tZW51PlxuICogICA8L21kLW1lbnU+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICpcbiAqIEBmaW5hbFxuICogQHN1cHByZXNzIHt2aXNpYmlsaXR5fVxuICovXG5sZXQgTWRNZW51ID0gY2xhc3MgTWRNZW51IGV4dGVuZHMgTWVudSB7XG59O1xuTWRNZW51LnN0eWxlcyA9IFtzdHlsZXNdO1xuTWRNZW51ID0gX19kZWNvcmF0ZShbXG4gICAgY3VzdG9tRWxlbWVudCgnbWQtbWVudScpXG5dLCBNZE1lbnUpO1xuZXhwb3J0IHsgTWRNZW51IH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZW51LmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8vIEdlbmVyYXRlZCBzdHlsZXNoZWV0IGZvciAuL3Byb2dyZXNzL2ludGVybmFsL2NpcmN1bGFyLXByb2dyZXNzLXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgOmhvc3R7LS1fYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tbWQtY2lyY3VsYXItcHJvZ3Jlc3MtYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV9hY3RpdmUtaW5kaWNhdG9yLXdpZHRoOiB2YXIoLS1tZC1jaXJjdWxhci1wcm9ncmVzcy1hY3RpdmUtaW5kaWNhdG9yLXdpZHRoLCAxMCk7LS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLWZvdXItY29sb3I6IHZhcigtLW1kLWNpcmN1bGFyLXByb2dyZXNzLWZvdXItY29sb3ItYWN0aXZlLWluZGljYXRvci1mb3VyLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItdGVydGlhcnktY29udGFpbmVyLCAjZmZkOGU0KSk7LS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLW9uZS1jb2xvcjogdmFyKC0tbWQtY2lyY3VsYXItcHJvZ3Jlc3MtZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLW9uZS1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV9mb3VyLWNvbG9yLWFjdGl2ZS1pbmRpY2F0b3ItdGhyZWUtY29sb3I6IHZhcigtLW1kLWNpcmN1bGFyLXByb2dyZXNzLWZvdXItY29sb3ItYWN0aXZlLWluZGljYXRvci10aHJlZS1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXRlcnRpYXJ5LCAjN2Q1MjYwKSk7LS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLXR3by1jb2xvcjogdmFyKC0tbWQtY2lyY3VsYXItcHJvZ3Jlc3MtZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLXR3by1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnktY29udGFpbmVyLCAjZWFkZGZmKSk7LS1fc2l6ZTogdmFyKC0tbWQtY2lyY3VsYXItcHJvZ3Jlc3Mtc2l6ZSwgNDhweCk7ZGlzcGxheTppbmxpbmUtZmxleDt2ZXJ0aWNhbC1hbGlnbjptaWRkbGU7d2lkdGg6dmFyKC0tX3NpemUpO2hlaWdodDp2YXIoLS1fc2l6ZSk7cG9zaXRpb246cmVsYXRpdmU7YWxpZ24taXRlbXM6Y2VudGVyO2p1c3RpZnktY29udGVudDpjZW50ZXI7Y29udGFpbjpzdHJpY3Q7Y29udGVudC12aXNpYmlsaXR5OmF1dG99LnByb2dyZXNze2ZsZXg6MTthbGlnbi1zZWxmOnN0cmV0Y2g7bWFyZ2luOjRweH0ucHJvZ3Jlc3MsLnNwaW5uZXIsLmxlZnQsLnJpZ2h0LC5jaXJjbGUsc3ZnLC50cmFjaywuYWN0aXZlLXRyYWNre3Bvc2l0aW9uOmFic29sdXRlO2luc2V0OjB9c3Zne3RyYW5zZm9ybTpyb3RhdGUoLTkwZGVnKX1jaXJjbGV7Y3g6NTAlO2N5OjUwJTtyOmNhbGMoNTAlKigxIC0gdmFyKC0tX2FjdGl2ZS1pbmRpY2F0b3Itd2lkdGgpLzEwMCkpO3N0cm9rZS13aWR0aDpjYWxjKHZhcigtLV9hY3RpdmUtaW5kaWNhdG9yLXdpZHRoKSoxJSk7c3Ryb2tlLWRhc2hhcnJheToxMDA7ZmlsbDpyZ2JhKDAsMCwwLDApfS5hY3RpdmUtdHJhY2t7dHJhbnNpdGlvbjpzdHJva2UtZGFzaG9mZnNldCA1MDBtcyBjdWJpYy1iZXppZXIoMCwgMCwgMC4yLCAxKTtzdHJva2U6dmFyKC0tX2FjdGl2ZS1pbmRpY2F0b3ItY29sb3IpfS50cmFja3tzdHJva2U6cmdiYSgwLDAsMCwwKX0ucHJvZ3Jlc3MuaW5kZXRlcm1pbmF0ZXthbmltYXRpb246bGluZWFyIGluZmluaXRlIGxpbmVhci1yb3RhdGU7YW5pbWF0aW9uLWR1cmF0aW9uOjE1NjguMjM1Mjk0MTE3Nm1zfS5zcGlubmVye2FuaW1hdGlvbjppbmZpbml0ZSBib3RoIHJvdGF0ZS1hcmM7YW5pbWF0aW9uLWR1cmF0aW9uOjUzMzJtczthbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOmN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSl9LmxlZnR7b3ZlcmZsb3c6aGlkZGVuO2luc2V0OjAgNTAlIDAgMH0ucmlnaHR7b3ZlcmZsb3c6aGlkZGVuO2luc2V0OjAgMCAwIDUwJX0uY2lyY2xle2JveC1zaXppbmc6Ym9yZGVyLWJveDtib3JkZXItcmFkaXVzOjUwJTtib3JkZXI6c29saWQgY2FsYyh2YXIoLS1fYWN0aXZlLWluZGljYXRvci13aWR0aCkvMTAwKih2YXIoLS1fc2l6ZSkgLSA4cHgpKTtib3JkZXItY29sb3I6dmFyKC0tX2FjdGl2ZS1pbmRpY2F0b3ItY29sb3IpIHZhcigtLV9hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKSByZ2JhKDAsMCwwLDApIHJnYmEoMCwwLDAsMCk7YW5pbWF0aW9uOmV4cGFuZC1hcmM7YW5pbWF0aW9uLWl0ZXJhdGlvbi1jb3VudDppbmZpbml0ZTthbmltYXRpb24tZmlsbC1tb2RlOmJvdGg7YW5pbWF0aW9uLWR1cmF0aW9uOjEzMzNtcyw1MzMybXM7YW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjpjdWJpYy1iZXppZXIoMC40LCAwLCAwLjIsIDEpfS5mb3VyLWNvbG9yIC5jaXJjbGV7YW5pbWF0aW9uLW5hbWU6ZXhwYW5kLWFyYyxmb3VyLWNvbG9yfS5sZWZ0IC5jaXJjbGV7cm90YXRlOjEzNWRlZztpbnNldDowIC0xMDAlIDAgMH0ucmlnaHQgLmNpcmNsZXtyb3RhdGU6MTAwZGVnO2luc2V0OjAgMCAwIC0xMDAlO2FuaW1hdGlvbi1kZWxheTotNjY2LjVtcywwbXN9QG1lZGlhKGZvcmNlZC1jb2xvcnM6IGFjdGl2ZSl7LmFjdGl2ZS10cmFja3tzdHJva2U6Q2FudmFzVGV4dH0uY2lyY2xle2JvcmRlci1jb2xvcjpDYW52YXNUZXh0IENhbnZhc1RleHQgQ2FudmFzIENhbnZhc319QGtleWZyYW1lcyBleHBhbmQtYXJjezAle3RyYW5zZm9ybTpyb3RhdGUoMjY1ZGVnKX01MCV7dHJhbnNmb3JtOnJvdGF0ZSgxMzBkZWcpfTEwMCV7dHJhbnNmb3JtOnJvdGF0ZSgyNjVkZWcpfX1Aa2V5ZnJhbWVzIHJvdGF0ZS1hcmN7MTIuNSV7dHJhbnNmb3JtOnJvdGF0ZSgxMzVkZWcpfTI1JXt0cmFuc2Zvcm06cm90YXRlKDI3MGRlZyl9MzcuNSV7dHJhbnNmb3JtOnJvdGF0ZSg0MDVkZWcpfTUwJXt0cmFuc2Zvcm06cm90YXRlKDU0MGRlZyl9NjIuNSV7dHJhbnNmb3JtOnJvdGF0ZSg2NzVkZWcpfTc1JXt0cmFuc2Zvcm06cm90YXRlKDgxMGRlZyl9ODcuNSV7dHJhbnNmb3JtOnJvdGF0ZSg5NDVkZWcpfTEwMCV7dHJhbnNmb3JtOnJvdGF0ZSgxMDgwZGVnKX19QGtleWZyYW1lcyBsaW5lYXItcm90YXRle3Rve3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKX19QGtleWZyYW1lcyBmb3VyLWNvbG9yezAle2JvcmRlci10b3AtY29sb3I6dmFyKC0tX2ZvdXItY29sb3ItYWN0aXZlLWluZGljYXRvci1vbmUtY29sb3IpO2JvcmRlci1yaWdodC1jb2xvcjp2YXIoLS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLW9uZS1jb2xvcil9MTUle2JvcmRlci10b3AtY29sb3I6dmFyKC0tX2ZvdXItY29sb3ItYWN0aXZlLWluZGljYXRvci1vbmUtY29sb3IpO2JvcmRlci1yaWdodC1jb2xvcjp2YXIoLS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLW9uZS1jb2xvcil9MjUle2JvcmRlci10b3AtY29sb3I6dmFyKC0tX2ZvdXItY29sb3ItYWN0aXZlLWluZGljYXRvci10d28tY29sb3IpO2JvcmRlci1yaWdodC1jb2xvcjp2YXIoLS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLXR3by1jb2xvcil9NDAle2JvcmRlci10b3AtY29sb3I6dmFyKC0tX2ZvdXItY29sb3ItYWN0aXZlLWluZGljYXRvci10d28tY29sb3IpO2JvcmRlci1yaWdodC1jb2xvcjp2YXIoLS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLXR3by1jb2xvcil9NTAle2JvcmRlci10b3AtY29sb3I6dmFyKC0tX2ZvdXItY29sb3ItYWN0aXZlLWluZGljYXRvci10aHJlZS1jb2xvcik7Ym9yZGVyLXJpZ2h0LWNvbG9yOnZhcigtLV9mb3VyLWNvbG9yLWFjdGl2ZS1pbmRpY2F0b3ItdGhyZWUtY29sb3IpfTY1JXtib3JkZXItdG9wLWNvbG9yOnZhcigtLV9mb3VyLWNvbG9yLWFjdGl2ZS1pbmRpY2F0b3ItdGhyZWUtY29sb3IpO2JvcmRlci1yaWdodC1jb2xvcjp2YXIoLS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLXRocmVlLWNvbG9yKX03NSV7Ym9yZGVyLXRvcC1jb2xvcjp2YXIoLS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLWZvdXItY29sb3IpO2JvcmRlci1yaWdodC1jb2xvcjp2YXIoLS1fZm91ci1jb2xvci1hY3RpdmUtaW5kaWNhdG9yLWZvdXItY29sb3IpfTkwJXtib3JkZXItdG9wLWNvbG9yOnZhcigtLV9mb3VyLWNvbG9yLWFjdGl2ZS1pbmRpY2F0b3ItZm91ci1jb2xvcik7Ym9yZGVyLXJpZ2h0LWNvbG9yOnZhcigtLV9mb3VyLWNvbG9yLWFjdGl2ZS1pbmRpY2F0b3ItZm91ci1jb2xvcil9MTAwJXtib3JkZXItdG9wLWNvbG9yOnZhcigtLV9mb3VyLWNvbG9yLWFjdGl2ZS1pbmRpY2F0b3Itb25lLWNvbG9yKTtib3JkZXItcmlnaHQtY29sb3I6dmFyKC0tX2ZvdXItY29sb3ItYWN0aXZlLWluZGljYXRvci1vbmUtY29sb3IpfX1cbmA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaXJjdWxhci1wcm9ncmVzcy1zdHlsZXMuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuaW1wb3J0IHsgaHRtbCB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBQcm9ncmVzcyB9IGZyb20gJy4vcHJvZ3Jlc3MuanMnO1xuLyoqXG4gKiBBIGNpcmN1bGFyIHByb2dyZXNzIGNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIENpcmN1bGFyUHJvZ3Jlc3MgZXh0ZW5kcyBQcm9ncmVzcyB7XG4gICAgcmVuZGVySW5kaWNhdG9yKCkge1xuICAgICAgICBpZiAodGhpcy5pbmRldGVybWluYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXJJbmRldGVybWluYXRlQ29udGFpbmVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyRGV0ZXJtaW5hdGVDb250YWluZXIoKTtcbiAgICB9XG4gICAgLy8gRGV0ZXJtaW5hdGUgbW9kZSBpcyByZW5kZXJlZCB3aXRoIGFuIHN2ZyBzbyB0aGUgcHJvZ3Jlc3MgYXJjIGNhbiBiZVxuICAgIC8vIGVhc2lseSBhbmltYXRlZCB2aWEgc3Ryb2tlLWRhc2hvZmZzZXQuXG4gICAgcmVuZGVyRGV0ZXJtaW5hdGVDb250YWluZXIoKSB7XG4gICAgICAgIGNvbnN0IGRhc2hPZmZzZXQgPSAoMSAtIHRoaXMudmFsdWUgLyB0aGlzLm1heCkgKiAxMDA7XG4gICAgICAgIC8vIG5vdGUsIGRhc2gtYXJyYXkvb2Zmc2V0IGFyZSByZWxhdGl2ZSB0byBTZXR0aW5nIGBwYXRoTGVuZ3RoYCBidXRcbiAgICAgICAgLy8gQ2hyb21lIHNlZW1zIHRvIHJlbmRlciB0aGlzIGluYWNjdXJhdGVseSBhbmQgdXNpbmcgYSBsYXJnZSB2aWV3Ym94IGhlbHBzLlxuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8c3ZnIHZpZXdCb3g9XCIwIDAgNDgwMCA0ODAwXCI+XG4gICAgICAgIDxjaXJjbGUgY2xhc3M9XCJ0cmFja1wiIHBhdGhMZW5ndGg9XCIxMDBcIj48L2NpcmNsZT5cbiAgICAgICAgPGNpcmNsZVxuICAgICAgICAgIGNsYXNzPVwiYWN0aXZlLXRyYWNrXCJcbiAgICAgICAgICBwYXRoTGVuZ3RoPVwiMTAwXCJcbiAgICAgICAgICBzdHJva2UtZGFzaG9mZnNldD0ke2Rhc2hPZmZzZXR9PjwvY2lyY2xlPlxuICAgICAgPC9zdmc+XG4gICAgYDtcbiAgICB9XG4gICAgLy8gSW5kZXRlcm1pbmF0ZSBtb2RlIHJlbmRlcmVkIHdpdGggMiBib3JkZXJlZC1kaXZzLiBUaGUgYm9yZGVycyBhcmVcbiAgICAvLyBjbGlwcGVkIGludG8gaGFsZiBjaXJjbGVzIGJ5IHRoZWlyIGNvbnRhaW5lcnMuIFRoZSBkaXZzIGFyZSB0aGVuIGNhcmVmdWxseVxuICAgIC8vIGFuaW1hdGVkIHRvIHByb2R1Y2UgY2hhbmdlcyB0byB0aGUgc3Bpbm5lciBhcmMgc2l6ZS5cbiAgICAvLyBUaGlzIGFwcHJvYWNoIGhhcyA0LjV4IHRoZSBGUFMgb2YgcmVuZGVyaW5nIHZpYSBzdmcgb24gQ2hyb21lIDExMS5cbiAgICAvLyBTZWUgaHR0cHM6Ly9saXQuZGV2L3BsYXlncm91bmQvI2dpc3Q9ZmViYjc3MzU2NTI3MmY3NTQwOGFiMDZhMGViNDk3NDYuXG4gICAgcmVuZGVySW5kZXRlcm1pbmF0ZUNvbnRhaW5lcigpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYCA8ZGl2IGNsYXNzPVwic3Bpbm5lclwiPlxuICAgICAgPGRpdiBjbGFzcz1cImxlZnRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNpcmNsZVwiPjwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwicmlnaHRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNpcmNsZVwiPjwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+YDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaXJjdWxhci1wcm9ncmVzcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBodG1sLCBMaXRFbGVtZW50LCBub3RoaW5nIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IHByb3BlcnR5IH0gZnJvbSAnbGl0L2RlY29yYXRvcnMuanMnO1xuaW1wb3J0IHsgY2xhc3NNYXAgfSBmcm9tICdsaXQvZGlyZWN0aXZlcy9jbGFzcy1tYXAuanMnO1xuaW1wb3J0IHsgbWl4aW5EZWxlZ2F0ZXNBcmlhIH0gZnJvbSAnLi4vLi4vaW50ZXJuYWwvYXJpYS9kZWxlZ2F0ZS5qcyc7XG4vLyBTZXBhcmF0ZSB2YXJpYWJsZSBuZWVkZWQgZm9yIGNsb3N1cmUuXG5jb25zdCBwcm9ncmVzc0Jhc2VDbGFzcyA9IG1peGluRGVsZWdhdGVzQXJpYShMaXRFbGVtZW50KTtcbi8qKlxuICogQSBwcm9ncmVzcyBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBQcm9ncmVzcyBleHRlbmRzIHByb2dyZXNzQmFzZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb2dyZXNzIHRvIGRpc3BsYXksIGEgZnJhY3Rpb24gYmV0d2VlbiAwIGFuZCBgbWF4YC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudmFsdWUgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogTWF4aW11bSBwcm9ncmVzcyB0byBkaXNwbGF5LCBkZWZhdWx0cyB0byAxLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5tYXggPSAxO1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciBvciBub3QgdG8gZGlzcGxheSBpbmRldGVybWluYXRlIHByb2dyZXNzLCB3aGljaCBnaXZlcyBubyBpbmRpY2F0aW9uXG4gICAgICAgICAqIHRvIGhvdyBsb25nIGFuIGFjdGl2aXR5IHdpbGwgdGFrZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5kZXRlcm1pbmF0ZSA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciBvciBub3QgdG8gcmVuZGVyIGluZGV0ZXJtaW5hdGUgbW9kZSB1c2luZyA0IGNvbG9ycyBpbnN0ZWFkIG9mIG9uZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZm91ckNvbG9yID0gZmFsc2U7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgLy8gTmVlZGVkIGZvciBjbG9zdXJlIGNvbmZvcm1hbmNlXG4gICAgICAgIGNvbnN0IHsgYXJpYUxhYmVsIH0gPSB0aGlzO1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwicHJvZ3Jlc3MgJHtjbGFzc01hcCh0aGlzLmdldFJlbmRlckNsYXNzZXMoKSl9XCJcbiAgICAgICAgcm9sZT1cInByb2dyZXNzYmFyXCJcbiAgICAgICAgYXJpYS1sYWJlbD1cIiR7YXJpYUxhYmVsIHx8IG5vdGhpbmd9XCJcbiAgICAgICAgYXJpYS12YWx1ZW1pbj1cIjBcIlxuICAgICAgICBhcmlhLXZhbHVlbWF4PSR7dGhpcy5tYXh9XG4gICAgICAgIGFyaWEtdmFsdWVub3c9JHt0aGlzLmluZGV0ZXJtaW5hdGUgPyBub3RoaW5nIDogdGhpcy52YWx1ZX1cbiAgICAgICAgPiR7dGhpcy5yZW5kZXJJbmRpY2F0b3IoKX08L2RpdlxuICAgICAgPlxuICAgIGA7XG4gICAgfVxuICAgIGdldFJlbmRlckNsYXNzZXMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAnaW5kZXRlcm1pbmF0ZSc6IHRoaXMuaW5kZXRlcm1pbmF0ZSxcbiAgICAgICAgICAgICdmb3VyLWNvbG9yJzogdGhpcy5mb3VyQ29sb3IsXG4gICAgICAgIH07XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBOdW1iZXIgfSlcbl0sIFByb2dyZXNzLnByb3RvdHlwZSwgXCJ2YWx1ZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBOdW1iZXIgfSlcbl0sIFByb2dyZXNzLnByb3RvdHlwZSwgXCJtYXhcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiB9KVxuXSwgUHJvZ3Jlc3MucHJvdG90eXBlLCBcImluZGV0ZXJtaW5hdGVcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnZm91ci1jb2xvcicgfSlcbl0sIFByb2dyZXNzLnByb3RvdHlwZSwgXCJmb3VyQ29sb3JcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXByb2dyZXNzLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8vIEdlbmVyYXRlZCBzdHlsZXNoZWV0IGZvciAuL3NlbGVjdC9pbnRlcm5hbC9maWxsZWQtc2VsZWN0LXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgOmhvc3R7LS1fdGV4dC1maWVsZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX3RleHQtZmllbGQtYWN0aXZlLWluZGljYXRvci1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCwgMXB4KTstLV90ZXh0LWZpZWxkLWNvbnRhaW5lci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWNvbnRhaW5lci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXN1cmZhY2UtY29udGFpbmVyLWhpZ2hlc3QsICNlNmUwZTkpKTstLV90ZXh0LWZpZWxkLWRpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX3RleHQtZmllbGQtZGlzYWJsZWQtYWN0aXZlLWluZGljYXRvci1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCwgMXB4KTstLV90ZXh0LWZpZWxkLWRpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3Itb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWRpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3Itb3BhY2l0eSwgMC4zOCk7LS1fdGV4dC1maWVsZC1kaXNhYmxlZC1jb250YWluZXItY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1kaXNhYmxlZC1jb250YWluZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fdGV4dC1maWVsZC1kaXNhYmxlZC1jb250YWluZXItb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWRpc2FibGVkLWNvbnRhaW5lci1vcGFjaXR5LCAwLjA0KTstLV90ZXh0LWZpZWxkLWRpc2FibGVkLWlucHV0LXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1kaXNhYmxlZC1pbnB1dC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX3RleHQtZmllbGQtZGlzYWJsZWQtaW5wdXQtdGV4dC1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZGlzYWJsZWQtaW5wdXQtdGV4dC1vcGFjaXR5LCAwLjM4KTstLV90ZXh0LWZpZWxkLWRpc2FibGVkLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1kaXNhYmxlZC1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX3RleHQtZmllbGQtZGlzYWJsZWQtbGFiZWwtdGV4dC1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZGlzYWJsZWQtbGFiZWwtdGV4dC1vcGFjaXR5LCAwLjM4KTstLV90ZXh0LWZpZWxkLWRpc2FibGVkLWxlYWRpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWRpc2FibGVkLWxlYWRpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV90ZXh0LWZpZWxkLWRpc2FibGVkLWxlYWRpbmctaWNvbi1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZGlzYWJsZWQtbGVhZGluZy1pY29uLW9wYWNpdHksIDAuMzgpOy0tX3RleHQtZmllbGQtZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX3RleHQtZmllbGQtZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LW9wYWNpdHk6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1kaXNhYmxlZC1zdXBwb3J0aW5nLXRleHQtb3BhY2l0eSwgMC4zOCk7LS1fdGV4dC1maWVsZC1kaXNhYmxlZC10cmFpbGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZGlzYWJsZWQtdHJhaWxpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV90ZXh0LWZpZWxkLWRpc2FibGVkLXRyYWlsaW5nLWljb24tb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWRpc2FibGVkLXRyYWlsaW5nLWljb24tb3BhY2l0eSwgMC4zOCk7LS1fdGV4dC1maWVsZC1lcnJvci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZXJyb3ItYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLWVycm9yLCAjYjMyNjFlKSk7LS1fdGV4dC1maWVsZC1lcnJvci1mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZXJyb3ItZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLWVycm9yLCAjYjMyNjFlKSk7LS1fdGV4dC1maWVsZC1lcnJvci1mb2N1cy1pbnB1dC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZXJyb3ItZm9jdXMtaW5wdXQtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV90ZXh0LWZpZWxkLWVycm9yLWZvY3VzLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1lcnJvci1mb2N1cy1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV90ZXh0LWZpZWxkLWVycm9yLWZvY3VzLWxlYWRpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWVycm9yLWZvY3VzLWxlYWRpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX3RleHQtZmllbGQtZXJyb3ItZm9jdXMtc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZXJyb3ItZm9jdXMtc3VwcG9ydGluZy10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV90ZXh0LWZpZWxkLWVycm9yLWZvY3VzLXRyYWlsaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1lcnJvci1mb2N1cy10cmFpbGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV90ZXh0LWZpZWxkLWVycm9yLWhvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1lcnJvci1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tZXJyb3ItY29udGFpbmVyLCAjNDEwZTBiKSk7LS1fdGV4dC1maWVsZC1lcnJvci1ob3Zlci1pbnB1dC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZXJyb3ItaG92ZXItaW5wdXQtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV90ZXh0LWZpZWxkLWVycm9yLWhvdmVyLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1lcnJvci1ob3Zlci1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tZXJyb3ItY29udGFpbmVyLCAjNDEwZTBiKSk7LS1fdGV4dC1maWVsZC1lcnJvci1ob3Zlci1sZWFkaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1lcnJvci1ob3Zlci1sZWFkaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV90ZXh0LWZpZWxkLWVycm9yLWhvdmVyLXN0YXRlLWxheWVyLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZXJyb3ItaG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fdGV4dC1maWVsZC1lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZXJyb3ItaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4wOCk7LS1fdGV4dC1maWVsZC1lcnJvci1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1lcnJvci1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX3RleHQtZmllbGQtZXJyb3ItaG92ZXItdHJhaWxpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWVycm9yLWhvdmVyLXRyYWlsaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1lcnJvci1jb250YWluZXIsICM0MTBlMGIpKTstLV90ZXh0LWZpZWxkLWVycm9yLWlucHV0LXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1lcnJvci1pbnB1dC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX3RleHQtZmllbGQtZXJyb3ItbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWVycm9yLWxhYmVsLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX3RleHQtZmllbGQtZXJyb3ItbGVhZGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZXJyb3ItbGVhZGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fdGV4dC1maWVsZC1lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX3RleHQtZmllbGQtZXJyb3ItdHJhaWxpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWVycm9yLXRyYWlsaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX3RleHQtZmllbGQtZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1wcmltYXJ5LCAjNjc1MGE0KSk7LS1fdGV4dC1maWVsZC1mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0LCAzcHgpOy0tX3RleHQtZmllbGQtZm9jdXMtaW5wdXQtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWZvY3VzLWlucHV0LXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fdGV4dC1maWVsZC1mb2N1cy1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZm9jdXMtbGFiZWwtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV90ZXh0LWZpZWxkLWZvY3VzLWxlYWRpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWZvY3VzLWxlYWRpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX3RleHQtZmllbGQtZm9jdXMtc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZm9jdXMtc3VwcG9ydGluZy10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fdGV4dC1maWVsZC1mb2N1cy10cmFpbGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtZm9jdXMtdHJhaWxpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV90ZXh0LWZpZWxkLWhvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX3RleHQtZmllbGQtaG92ZXItYWN0aXZlLWluZGljYXRvci1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCwgMXB4KTstLV90ZXh0LWZpZWxkLWhvdmVyLWlucHV0LXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1ob3Zlci1pbnB1dC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX3RleHQtZmllbGQtaG92ZXItbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWhvdmVyLWxhYmVsLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fdGV4dC1maWVsZC1ob3Zlci1sZWFkaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1ob3Zlci1sZWFkaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV90ZXh0LWZpZWxkLWhvdmVyLXN0YXRlLWxheWVyLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtaG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fdGV4dC1maWVsZC1ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4wOCk7LS1fdGV4dC1maWVsZC1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV90ZXh0LWZpZWxkLWhvdmVyLXRyYWlsaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1ob3Zlci10cmFpbGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fdGV4dC1maWVsZC1pbnB1dC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtaW5wdXQtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV90ZXh0LWZpZWxkLWlucHV0LXRleHQtZm9udDogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWlucHV0LXRleHQtZm9udCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLWZvbnQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS1wbGFpbiwgUm9ib3RvKSkpOy0tX3RleHQtZmllbGQtaW5wdXQtdGV4dC1saW5lLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWlucHV0LXRleHQtbGluZS1oZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1saW5lLWhlaWdodCwgMS41cmVtKSk7LS1fdGV4dC1maWVsZC1pbnB1dC10ZXh0LXNpemU6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1pbnB1dC10ZXh0LXNpemUsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1zaXplLCAxcmVtKSk7LS1fdGV4dC1maWVsZC1pbnB1dC10ZXh0LXdlaWdodDogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWlucHV0LXRleHQtd2VpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2Utd2VpZ2h0LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2Utd2VpZ2h0LXJlZ3VsYXIsIDQwMCkpKTstLV90ZXh0LWZpZWxkLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fdGV4dC1maWVsZC1sYWJlbC10ZXh0LWZvbnQ6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1sYWJlbC10ZXh0LWZvbnQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1mb250LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2UtcGxhaW4sIFJvYm90bykpKTstLV90ZXh0LWZpZWxkLWxhYmVsLXRleHQtbGluZS1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1sYWJlbC10ZXh0LWxpbmUtaGVpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2UtbGluZS1oZWlnaHQsIDEuNXJlbSkpOy0tX3RleHQtZmllbGQtbGFiZWwtdGV4dC1wb3B1bGF0ZWQtbGluZS1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1sYWJlbC10ZXh0LXBvcHVsYXRlZC1saW5lLWhlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LXNtYWxsLWxpbmUtaGVpZ2h0LCAxcmVtKSk7LS1fdGV4dC1maWVsZC1sYWJlbC10ZXh0LXBvcHVsYXRlZC1zaXplOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtbGFiZWwtdGV4dC1wb3B1bGF0ZWQtc2l6ZSwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LXNtYWxsLXNpemUsIDAuNzVyZW0pKTstLV90ZXh0LWZpZWxkLWxhYmVsLXRleHQtc2l6ZTogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWxhYmVsLXRleHQtc2l6ZSwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLXNpemUsIDFyZW0pKTstLV90ZXh0LWZpZWxkLWxhYmVsLXRleHQtd2VpZ2h0OiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtbGFiZWwtdGV4dC13ZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS13ZWlnaHQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS13ZWlnaHQtcmVndWxhciwgNDAwKSkpOy0tX3RleHQtZmllbGQtbGVhZGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtbGVhZGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fdGV4dC1maWVsZC1sZWFkaW5nLWljb24tc2l6ZTogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWxlYWRpbmctaWNvbi1zaXplLCAyNHB4KTstLV90ZXh0LWZpZWxkLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLXN1cHBvcnRpbmctdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX3RleHQtZmllbGQtc3VwcG9ydGluZy10ZXh0LWZvbnQ6IHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1zdXBwb3J0aW5nLXRleHQtZm9udCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LXNtYWxsLWZvbnQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS1wbGFpbiwgUm9ib3RvKSkpOy0tX3RleHQtZmllbGQtc3VwcG9ydGluZy10ZXh0LWxpbmUtaGVpZ2h0OiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtc3VwcG9ydGluZy10ZXh0LWxpbmUtaGVpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktc21hbGwtbGluZS1oZWlnaHQsIDFyZW0pKTstLV90ZXh0LWZpZWxkLXN1cHBvcnRpbmctdGV4dC1zaXplOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXNpemUsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1zbWFsbC1zaXplLCAwLjc1cmVtKSk7LS1fdGV4dC1maWVsZC1zdXBwb3J0aW5nLXRleHQtd2VpZ2h0OiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXdlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LXNtYWxsLXdlaWdodCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXdlaWdodC1yZWd1bGFyLCA0MDApKSk7LS1fdGV4dC1maWVsZC10cmFpbGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtdHJhaWxpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX3RleHQtZmllbGQtdHJhaWxpbmctaWNvbi1zaXplOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtdHJhaWxpbmctaWNvbi1zaXplLCAyNHB4KTstLV90ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZS1zdGFydC1zdGFydDogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZS1zdGFydC1zdGFydCwgdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZSwgdmFyKC0tbWQtc3lzLXNoYXBlLWNvcm5lci1leHRyYS1zbWFsbCwgNHB4KSkpOy0tX3RleHQtZmllbGQtY29udGFpbmVyLXNoYXBlLXN0YXJ0LWVuZDogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZS1zdGFydC1lbmQsIHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUsIHZhcigtLW1kLXN5cy1zaGFwZS1jb3JuZXItZXh0cmEtc21hbGwsIDRweCkpKTstLV90ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZS1lbmQtZW5kOiB2YXIoLS1tZC1maWxsZWQtc2VsZWN0LXRleHQtZmllbGQtY29udGFpbmVyLXNoYXBlLWVuZC1lbmQsIHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUsIHZhcigtLW1kLXN5cy1zaGFwZS1jb3JuZXItbm9uZSwgMHB4KSkpOy0tX3RleHQtZmllbGQtY29udGFpbmVyLXNoYXBlLWVuZC1zdGFydDogdmFyKC0tbWQtZmlsbGVkLXNlbGVjdC10ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZS1lbmQtc3RhcnQsIHZhcigtLW1kLWZpbGxlZC1zZWxlY3QtdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUsIHZhcigtLW1kLXN5cy1zaGFwZS1jb3JuZXItbm9uZSwgMHB4KSkpOy0tbWQtZmlsbGVkLWZpZWxkLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0OiB2YXIoLS1fdGV4dC1maWVsZC1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCk7LS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1jb250YWluZXItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWNvbnRhaW5lci1zaGFwZS1lbmQtZW5kOiB2YXIoLS1fdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUtZW5kLWVuZCk7LS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLXNoYXBlLWVuZC1zdGFydDogdmFyKC0tX3RleHQtZmllbGQtY29udGFpbmVyLXNoYXBlLWVuZC1zdGFydCk7LS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLXNoYXBlLXN0YXJ0LWVuZDogdmFyKC0tX3RleHQtZmllbGQtY29udGFpbmVyLXNoYXBlLXN0YXJ0LWVuZCk7LS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLXNoYXBlLXN0YXJ0LXN0YXJ0OiB2YXIoLS1fdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUtc3RhcnQtc3RhcnQpOy0tbWQtZmlsbGVkLWZpZWxkLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWlucHV0LXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWNvbnRlbnQtZm9udDogdmFyKC0tX3RleHQtZmllbGQtaW5wdXQtdGV4dC1mb250KTstLW1kLWZpbGxlZC1maWVsZC1jb250ZW50LWxpbmUtaGVpZ2h0OiB2YXIoLS1fdGV4dC1maWVsZC1pbnB1dC10ZXh0LWxpbmUtaGVpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1jb250ZW50LXNpemU6IHZhcigtLV90ZXh0LWZpZWxkLWlucHV0LXRleHQtc2l6ZSk7LS1tZC1maWxsZWQtZmllbGQtY29udGVudC13ZWlnaHQ6IHZhcigtLV90ZXh0LWZpZWxkLWlucHV0LXRleHQtd2VpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tX3RleHQtZmllbGQtZGlzYWJsZWQtYWN0aXZlLWluZGljYXRvci1oZWlnaHQpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3Itb3BhY2l0eTogdmFyKC0tX3RleHQtZmllbGQtZGlzYWJsZWQtYWN0aXZlLWluZGljYXRvci1vcGFjaXR5KTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1jb250YWluZXItY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWRpc2FibGVkLWNvbnRhaW5lci1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtY29udGFpbmVyLW9wYWNpdHk6IHZhcigtLV90ZXh0LWZpZWxkLWRpc2FibGVkLWNvbnRhaW5lci1vcGFjaXR5KTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1jb250ZW50LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1kaXNhYmxlZC1pbnB1dC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1jb250ZW50LW9wYWNpdHk6IHZhcigtLV90ZXh0LWZpZWxkLWRpc2FibGVkLWlucHV0LXRleHQtb3BhY2l0eSk7LS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZGlzYWJsZWQtbGFiZWwtdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtbGFiZWwtdGV4dC1vcGFjaXR5OiB2YXIoLS1fdGV4dC1maWVsZC1kaXNhYmxlZC1sYWJlbC10ZXh0LW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWxlYWRpbmctY29udGVudC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZGlzYWJsZWQtbGVhZGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1sZWFkaW5nLWNvbnRlbnQtb3BhY2l0eTogdmFyKC0tX3RleHQtZmllbGQtZGlzYWJsZWQtbGVhZGluZy1pY29uLW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1zdXBwb3J0aW5nLXRleHQtb3BhY2l0eTogdmFyKC0tX3RleHQtZmllbGQtZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWRpc2FibGVkLXRyYWlsaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLXRyYWlsaW5nLWNvbnRlbnQtb3BhY2l0eTogdmFyKC0tX3RleHQtZmllbGQtZGlzYWJsZWQtdHJhaWxpbmctaWNvbi1vcGFjaXR5KTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1jb250ZW50LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1pbnB1dC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1jb250ZW50LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1mb2N1cy1pbnB1dC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1mb2N1cy1sYWJlbC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWVycm9yLWZvY3VzLWxlYWRpbmctaWNvbi1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZXJyb3ItZm9jdXMtc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1mb2N1cy1zdXBwb3J0aW5nLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWZvY3VzLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWVycm9yLWZvY3VzLXRyYWlsaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWVycm9yLWhvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWVycm9yLWhvdmVyLWlucHV0LXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWVycm9yLWhvdmVyLWxhYmVsLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLWxlYWRpbmctY29udGVudC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZXJyb3ItaG92ZXItbGVhZGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZXJyb3ItaG92ZXItc3RhdGUtbGF5ZXItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHk6IHZhcigtLV90ZXh0LWZpZWxkLWVycm9yLWhvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZXJyb3ItaG92ZXItc3VwcG9ydGluZy10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1ob3Zlci10cmFpbGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1ob3Zlci10cmFpbGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1sYWJlbC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWVycm9yLWxlYWRpbmctaWNvbi1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZXJyb3Itc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWVycm9yLXRyYWlsaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0OiB2YXIoLS1fdGV4dC1maWVsZC1mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCk7LS1tZC1maWxsZWQtZmllbGQtZm9jdXMtY29udGVudC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZm9jdXMtaW5wdXQtdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZm9jdXMtbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZm9jdXMtbGFiZWwtdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZm9jdXMtbGVhZGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1mb2N1cy1sZWFkaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWZvY3VzLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtZm9jdXMtc3VwcG9ydGluZy10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1mb2N1cy10cmFpbGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1mb2N1cy10cmFpbGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tX3RleHQtZmllbGQtaG92ZXItYWN0aXZlLWluZGljYXRvci1oZWlnaHQpOy0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWhvdmVyLWlucHV0LXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWhvdmVyLWxhYmVsLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLWxlYWRpbmctY29udGVudC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtaG92ZXItbGVhZGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1ob3Zlci1zdGF0ZS1sYXllci1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtaG92ZXItc3RhdGUtbGF5ZXItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHk6IHZhcigtLV90ZXh0LWZpZWxkLWhvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtaG92ZXItc3VwcG9ydGluZy10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1ob3Zlci10cmFpbGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1ob3Zlci10cmFpbGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1sYWJlbC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LWZvbnQ6IHZhcigtLV90ZXh0LWZpZWxkLWxhYmVsLXRleHQtZm9udCk7LS1tZC1maWxsZWQtZmllbGQtbGFiZWwtdGV4dC1saW5lLWhlaWdodDogdmFyKC0tX3RleHQtZmllbGQtbGFiZWwtdGV4dC1saW5lLWhlaWdodCk7LS1tZC1maWxsZWQtZmllbGQtbGFiZWwtdGV4dC1wb3B1bGF0ZWQtbGluZS1oZWlnaHQ6IHZhcigtLV90ZXh0LWZpZWxkLWxhYmVsLXRleHQtcG9wdWxhdGVkLWxpbmUtaGVpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LXBvcHVsYXRlZC1zaXplOiB2YXIoLS1fdGV4dC1maWVsZC1sYWJlbC10ZXh0LXBvcHVsYXRlZC1zaXplKTstLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LXNpemU6IHZhcigtLV90ZXh0LWZpZWxkLWxhYmVsLXRleHQtc2l6ZSk7LS1tZC1maWxsZWQtZmllbGQtbGFiZWwtdGV4dC13ZWlnaHQ6IHZhcigtLV90ZXh0LWZpZWxkLWxhYmVsLXRleHQtd2VpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV90ZXh0LWZpZWxkLWxlYWRpbmctaWNvbi1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1fdGV4dC1maWVsZC1zdXBwb3J0aW5nLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLXN1cHBvcnRpbmctdGV4dC1mb250OiB2YXIoLS1fdGV4dC1maWVsZC1zdXBwb3J0aW5nLXRleHQtZm9udCk7LS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LWxpbmUtaGVpZ2h0OiB2YXIoLS1fdGV4dC1maWVsZC1zdXBwb3J0aW5nLXRleHQtbGluZS1oZWlnaHQpOy0tbWQtZmlsbGVkLWZpZWxkLXN1cHBvcnRpbmctdGV4dC1zaXplOiB2YXIoLS1fdGV4dC1maWVsZC1zdXBwb3J0aW5nLXRleHQtc2l6ZSk7LS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXdlaWdodDogdmFyKC0tX3RleHQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXdlaWdodCk7LS1tZC1maWxsZWQtZmllbGQtdHJhaWxpbmctY29udGVudC1jb2xvcjogdmFyKC0tX3RleHQtZmllbGQtdHJhaWxpbmctaWNvbi1jb2xvcil9W2hhcy1zdGFydF0gLmljb24ubGVhZGluZ3tmb250LXNpemU6dmFyKC0tX3RleHQtZmllbGQtbGVhZGluZy1pY29uLXNpemUpO2hlaWdodDp2YXIoLS1fdGV4dC1maWVsZC1sZWFkaW5nLWljb24tc2l6ZSk7d2lkdGg6dmFyKC0tX3RleHQtZmllbGQtbGVhZGluZy1pY29uLXNpemUpfS5pY29uLnRyYWlsaW5ne2ZvbnQtc2l6ZTp2YXIoLS1fdGV4dC1maWVsZC10cmFpbGluZy1pY29uLXNpemUpO2hlaWdodDp2YXIoLS1fdGV4dC1maWVsZC10cmFpbGluZy1pY29uLXNpemUpO3dpZHRoOnZhcigtLV90ZXh0LWZpZWxkLXRyYWlsaW5nLWljb24tc2l6ZSl9XG5gO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmlsbGVkLXNlbGVjdC1zdHlsZXMuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuaW1wb3J0ICcuLi8uLi9maWVsZC9maWxsZWQtZmllbGQuanMnO1xuaW1wb3J0IHsgbGl0ZXJhbCB9IGZyb20gJ2xpdC9zdGF0aWMtaHRtbC5qcyc7XG5pbXBvcnQgeyBTZWxlY3QgfSBmcm9tICcuL3NlbGVjdC5qcyc7XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZW5mb3JjZS1jb21tZW50cy1vbi1leHBvcnRlZC1zeW1ib2xzXG5leHBvcnQgY2xhc3MgRmlsbGVkU2VsZWN0IGV4dGVuZHMgU2VsZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5maWVsZFRhZyA9IGxpdGVyYWwgYG1kLWZpbGxlZC1maWVsZGA7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmlsbGVkLXNlbGVjdC5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG52YXIgX2E7XG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgJy4uLy4uL21lbnUvbWVudS5qcyc7XG5pbXBvcnQgeyBodG1sLCBpc1NlcnZlciwgTGl0RWxlbWVudCwgbm90aGluZyB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBwcm9wZXJ0eSwgcXVlcnksIHF1ZXJ5QXNzaWduZWRFbGVtZW50cywgc3RhdGUgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5pbXBvcnQgeyBjbGFzc01hcCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL2NsYXNzLW1hcC5qcyc7XG5pbXBvcnQgeyBzdHlsZU1hcCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL3N0eWxlLW1hcC5qcyc7XG5pbXBvcnQgeyBodG1sIGFzIHN0YXRpY0h0bWwgfSBmcm9tICdsaXQvc3RhdGljLWh0bWwuanMnO1xuaW1wb3J0IHsgbWl4aW5EZWxlZ2F0ZXNBcmlhIH0gZnJvbSAnLi4vLi4vaW50ZXJuYWwvYXJpYS9kZWxlZ2F0ZS5qcyc7XG5pbXBvcnQgeyByZWRpc3BhdGNoRXZlbnQgfSBmcm9tICcuLi8uLi9pbnRlcm5hbC9ldmVudHMvcmVkaXNwYXRjaC1ldmVudC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVWYWxpZGF0b3IsIGdldFZhbGlkaXR5QW5jaG9yLCBtaXhpbkNvbnN0cmFpbnRWYWxpZGF0aW9uLCB9IGZyb20gJy4uLy4uL2xhYnMvYmVoYXZpb3JzL2NvbnN0cmFpbnQtdmFsaWRhdGlvbi5qcyc7XG5pbXBvcnQgeyBtaXhpbkVsZW1lbnRJbnRlcm5hbHMgfSBmcm9tICcuLi8uLi9sYWJzL2JlaGF2aW9ycy9lbGVtZW50LWludGVybmFscy5qcyc7XG5pbXBvcnQgeyBnZXRGb3JtVmFsdWUsIG1peGluRm9ybUFzc29jaWF0ZWQsIH0gZnJvbSAnLi4vLi4vbGFicy9iZWhhdmlvcnMvZm9ybS1hc3NvY2lhdGVkLmpzJztcbmltcG9ydCB7IG1peGluT25SZXBvcnRWYWxpZGl0eSwgb25SZXBvcnRWYWxpZGl0eSwgfSBmcm9tICcuLi8uLi9sYWJzL2JlaGF2aW9ycy9vbi1yZXBvcnQtdmFsaWRpdHkuanMnO1xuaW1wb3J0IHsgU2VsZWN0VmFsaWRhdG9yIH0gZnJvbSAnLi4vLi4vbGFicy9iZWhhdmlvcnMvdmFsaWRhdG9ycy9zZWxlY3QtdmFsaWRhdG9yLmpzJztcbmltcG9ydCB7IGdldEFjdGl2ZUl0ZW0gfSBmcm9tICcuLi8uLi9saXN0L2ludGVybmFsL2xpc3QtbmF2aWdhdGlvbi1oZWxwZXJzLmpzJztcbmltcG9ydCB7IEZvY3VzU3RhdGUsIGlzRWxlbWVudEluU3VidHJlZSwgaXNTZWxlY3RhYmxlS2V5LCB9IGZyb20gJy4uLy4uL21lbnUvaW50ZXJuYWwvY29udHJvbGxlcnMvc2hhcmVkLmpzJztcbmltcG9ydCB7IFRZUEVBSEVBRF9SRUNPUkQgfSBmcm9tICcuLi8uLi9tZW51L2ludGVybmFsL2NvbnRyb2xsZXJzL3R5cGVhaGVhZENvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHsgREVGQVVMVF9UWVBFQUhFQURfQlVGRkVSX1RJTUUgfSBmcm9tICcuLi8uLi9tZW51L2ludGVybmFsL21lbnUuanMnO1xuaW1wb3J0IHsgZ2V0U2VsZWN0ZWRJdGVtcyB9IGZyb20gJy4vc2hhcmVkLmpzJztcbmNvbnN0IFZBTFVFID0gU3ltYm9sKCd2YWx1ZScpO1xuLy8gU2VwYXJhdGUgdmFyaWFibGUgbmVlZGVkIGZvciBjbG9zdXJlLlxuY29uc3Qgc2VsZWN0QmFzZUNsYXNzID0gbWl4aW5EZWxlZ2F0ZXNBcmlhKG1peGluT25SZXBvcnRWYWxpZGl0eShtaXhpbkNvbnN0cmFpbnRWYWxpZGF0aW9uKG1peGluRm9ybUFzc29jaWF0ZWQobWl4aW5FbGVtZW50SW50ZXJuYWxzKExpdEVsZW1lbnQpKSkpKTtcbi8qKlxuICogQGZpcmVzIGNoYW5nZSB7RXZlbnR9IFRoZSBuYXRpdmUgYGNoYW5nZWAgZXZlbnQgb25cbiAqIFtgPGlucHV0PmBdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MRWxlbWVudC9jaGFuZ2VfZXZlbnQpXG4gKiAtLWJ1YmJsZXNcbiAqIEBmaXJlcyBpbnB1dCB7SW5wdXRFdmVudH0gVGhlIG5hdGl2ZSBgaW5wdXRgIGV2ZW50IG9uXG4gKiBbYDxpbnB1dD5gXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTEVsZW1lbnQvaW5wdXRfZXZlbnQpXG4gKiAtLWJ1YmJsZXMgLS1jb21wb3NlZFxuICogQGZpcmVzIG9wZW5pbmcge0V2ZW50fSBGaXJlZCB3aGVuIHRoZSBzZWxlY3QncyBtZW51IGlzIGFib3V0IHRvIG9wZW4uXG4gKiBAZmlyZXMgb3BlbmVkIHtFdmVudH0gRmlyZWQgd2hlbiB0aGUgc2VsZWN0J3MgbWVudSBoYXMgZmluaXNoZWQgYW5pbWF0aW9uc1xuICogYW5kIG9wZW5lZC5cbiAqIEBmaXJlcyBjbG9zaW5nIHtFdmVudH0gRmlyZWQgd2hlbiB0aGUgc2VsZWN0J3MgbWVudSBpcyBhYm91dCB0byBjbG9zZS5cbiAqIEBmaXJlcyBjbG9zZWQge0V2ZW50fSBGaXJlZCB3aGVuIHRoZSBzZWxlY3QncyBtZW51IGhhcyBmaW5pc2hlZCBhbmltYXRpb25zXG4gKiBhbmQgY2xvc2VkLlxuICovXG5leHBvcnQgY2xhc3MgU2VsZWN0IGV4dGVuZHMgc2VsZWN0QmFzZUNsYXNzIHtcbiAgICAvKipcbiAgICAgKiBUaGUgdmFsdWUgb2YgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBvcHRpb24uXG4gICAgICpcbiAgICAgKiBOb3RlOiBGb3IgU1NSLCBzZXQgYFtzZWxlY3RlZF1gIG9uIHRoZSByZXF1ZXN0ZWQgb3B0aW9uIGFuZCBgZGlzcGxheVRleHRgXG4gICAgICogcmF0aGVyIHRoYW4gc2V0dGluZyBgdmFsdWVgIHNldHRpbmcgYHZhbHVlYCB3aWxsIGluY3VyIGEgRE9NIHF1ZXJ5LlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbVkFMVUVdO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgaWYgKGlzU2VydmVyKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0aGlzLmxhc3RVc2VyU2V0VmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5zZWxlY3QodmFsdWUpO1xuICAgIH1cbiAgICBnZXQgb3B0aW9ucygpIHtcbiAgICAgICAgLy8gTk9URTogdGhpcyBkb2VzIGEgRE9NIHF1ZXJ5LlxuICAgICAgICByZXR1cm4gKHRoaXMubWVudT8uaXRlbXMgPz8gW10pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW5kZXggb2YgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBvcHRpb24uXG4gICAgICpcbiAgICAgKiBOb3RlOiBGb3IgU1NSLCBzZXQgYFtzZWxlY3RlZF1gIG9uIHRoZSByZXF1ZXN0ZWQgb3B0aW9uIGFuZCBgZGlzcGxheVRleHRgXG4gICAgICogcmF0aGVyIHRoYW4gc2V0dGluZyBgc2VsZWN0ZWRJbmRleGAgc2V0dGluZyBgc2VsZWN0ZWRJbmRleGAgd2lsbCBpbmN1ciBhXG4gICAgICogRE9NIHF1ZXJ5LlxuICAgICAqL1xuICAgIGdldCBzZWxlY3RlZEluZGV4KCkge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZW5mb3JjZS1uYW1lLWNhc2luZ1xuICAgICAgICBjb25zdCBbX29wdGlvbiwgaW5kZXhdID0gKHRoaXMuZ2V0U2VsZWN0ZWRPcHRpb25zKCkgPz8gW10pWzBdID8/IFtdO1xuICAgICAgICByZXR1cm4gaW5kZXggPz8gLTE7XG4gICAgfVxuICAgIHNldCBzZWxlY3RlZEluZGV4KGluZGV4KSB7XG4gICAgICAgIHRoaXMubGFzdFVzZXJTZXRTZWxlY3RlZEluZGV4ID0gaW5kZXg7XG4gICAgICAgIHRoaXMuc2VsZWN0SW5kZXgoaW5kZXgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHNlbGVjdGVkIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBOT1RFOiBtZC1zZWxlY3Qgb25seSBzdXBwb3J0cyBzaW5nbGUgc2VsZWN0aW9uLlxuICAgICAqL1xuICAgIGdldCBzZWxlY3RlZE9wdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy5nZXRTZWxlY3RlZE9wdGlvbnMoKSA/PyBbXSkubWFwKChbb3B0aW9uXSkgPT4gb3B0aW9uKTtcbiAgICB9XG4gICAgZ2V0IGhhc0Vycm9yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lcnJvciB8fCB0aGlzLm5hdGl2ZUVycm9yO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9wZW5zIHRoZSBtZW51IHN5bmNocm9ub3VzbHkgd2l0aCBubyBhbmltYXRpb24uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnF1aWNrID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgc2VsZWN0IGlzIHJlcXVpcmVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZXF1aXJlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGVycm9yIG1lc3NhZ2UgdGhhdCByZXBsYWNlcyBzdXBwb3J0aW5nIHRleHQgd2hlbiBgZXJyb3JgIGlzIHRydWUuIElmXG4gICAgICAgICAqIGBlcnJvclRleHRgIGlzIGFuIGVtcHR5IHN0cmluZywgdGhlbiB0aGUgc3VwcG9ydGluZyB0ZXh0IHdpbGwgY29udGludWUgdG9cbiAgICAgICAgICogc2hvdy5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhpcyBlcnJvciBtZXNzYWdlIG92ZXJyaWRlcyB0aGUgZXJyb3IgbWVzc2FnZSBkaXNwbGF5ZWQgYnlcbiAgICAgICAgICogYHJlcG9ydFZhbGlkaXR5KClgLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5lcnJvclRleHQgPSAnJztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBmbG9hdGluZyBsYWJlbCBmb3IgdGhlIGZpZWxkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sYWJlbCA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGlzYWJsZXMgdGhlIGFzdGVyaXNrIG9uIHRoZSBmbG9hdGluZyBsYWJlbCwgd2hlbiB0aGUgc2VsZWN0IGlzXG4gICAgICAgICAqIHJlcXVpcmVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5ub0FzdGVyaXNrID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXlzIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gYmVsb3cgdGhlIHNlbGVjdCwgc3VjaCBhcyBob3cgaXQgc2hvdWxkXG4gICAgICAgICAqIGJlIHVzZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnN1cHBvcnRpbmdUZXh0ID0gJyc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIG9yIHNldHMgd2hldGhlciBvciBub3QgdGhlIHNlbGVjdCBpcyBpbiBhIHZpc3VhbGx5IGludmFsaWQgc3RhdGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoaXMgZXJyb3Igc3RhdGUgb3ZlcnJpZGVzIHRoZSBlcnJvciBzdGF0ZSBjb250cm9sbGVkIGJ5XG4gICAgICAgICAqIGByZXBvcnRWYWxpZGl0eSgpYC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZXJyb3IgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSB1bmRlcmx5aW5nIG1kLW1lbnUgc2hvdWxkIGJlIHBvc2l0aW9uOiBmaXhlZCB0byBkaXNwbGF5XG4gICAgICAgICAqIGluIGEgdG9wLWxldmVsIG1hbm5lciwgb3IgcG9zaXRpb246IGFic29sdXRlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBwb3NpdGlvbjpmaXhlZCBpcyB1c2VmdWwgZm9yIGNhc2VzIHdoZXJlIHNlbGVjdCBpcyBpbnNpZGUgb2YgYW5vdGhlclxuICAgICAgICAgKiBlbGVtZW50IHdpdGggc3RhY2tpbmcgY29udGV4dCBhbmQgaGlkZGVuIG92ZXJmbG93cyBzdWNoIGFzIGBtZC1kaWFsb2dgLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5tZW51UG9zaXRpb25pbmcgPSAncG9wb3Zlcic7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDbGFtcHMgdGhlIG1lbnUtd2lkdGggdG8gdGhlIHdpZHRoIG9mIHRoZSBzZWxlY3QuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmNsYW1wTWVudVdpZHRoID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWF4IHRpbWUgYmV0d2VlbiB0aGUga2V5c3Ryb2tlcyBvZiB0aGUgdHlwZWFoZWFkIHNlbGVjdCAvIG1lbnUgYmVoYXZpb3JcbiAgICAgICAgICogYmVmb3JlIGl0IGNsZWFycyB0aGUgdHlwZWFoZWFkIGJ1ZmZlci5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudHlwZWFoZWFkRGVsYXkgPSBERUZBVUxUX1RZUEVBSEVBRF9CVUZGRVJfVElNRTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSB0ZXh0IGZpZWxkIGhhcyBhIGxlYWRpbmcgaWNvbi4gVXNlZCBmb3IgU1NSLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oYXNMZWFkaW5nSWNvbiA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGV4dCB0byBkaXNwbGF5IGluIHRoZSBmaWVsZC4gT25seSBzZXQgZm9yIFNTUi5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGlzcGxheVRleHQgPSAnJztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgdGhlIG1lbnUgc2hvdWxkIGJlIGFsaWduZWQgdG8gdGhlIHN0YXJ0IG9yIHRoZSBlbmQgb2YgdGhlIHNlbGVjdCdzXG4gICAgICAgICAqIHRleHRib3guXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm1lbnVBbGlnbiA9ICdzdGFydCc7XG4gICAgICAgIHRoaXNbX2FdID0gJyc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBVc2VkIGZvciBpbml0aWFsaXppbmcgc2VsZWN0IHdoZW4gdGhlIHVzZXIgc2V0cyB0aGUgYHZhbHVlYCBkaXJlY3RseS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubGFzdFVzZXJTZXRWYWx1ZSA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBVc2VkIGZvciBpbml0aWFsaXppbmcgc2VsZWN0IHdoZW4gdGhlIHVzZXIgc2V0cyB0aGUgYHNlbGVjdGVkSW5kZXhgXG4gICAgICAgICAqIGRpcmVjdGx5LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sYXN0VXNlclNldFNlbGVjdGVkSW5kZXggPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgICogVXNlZCBmb3IgYGlucHV0YCBhbmQgYGNoYW5nZWAgZXZlbnQgY2hhbmdlIGRldGVjdGlvbi5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkT3B0aW9uID0gbnVsbDtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmVuZm9yY2UtbmFtZS1jYXNpbmdcbiAgICAgICAgdGhpcy5sYXN0U2VsZWN0ZWRPcHRpb25SZWNvcmRzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIG9yIG5vdCBhIG5hdGl2ZSBlcnJvciBoYXMgYmVlbiByZXBvcnRlZCB2aWEgYHJlcG9ydFZhbGlkaXR5KClgLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5uYXRpdmVFcnJvciA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbGlkYXRpb24gbWVzc2FnZSBkaXNwbGF5ZWQgZnJvbSBhIG5hdGl2ZSBlcnJvciB2aWFcbiAgICAgICAgICogYHJlcG9ydFZhbGlkaXR5KClgLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5uYXRpdmVFcnJvclRleHQgPSAnJztcbiAgICAgICAgdGhpcy5mb2N1c2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMub3BlbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLmRlZmF1bHRGb2N1cyA9IEZvY3VzU3RhdGUuTk9ORTtcbiAgICAgICAgLy8gSGF2ZSB0byBrZWVwIHRyYWNrIG9mIHByZXZpb3VzIG9wZW4gYmVjYXVzZSBpdCdzIHN0YXRlIGFuZCBwcml2YXRlIGFuZCB0aHVzXG4gICAgICAgIC8vIGNhbm5vdCBiZSB0cmFja2VkIGluIFByb3BlcnR5VmFsdWVzPHRoaXM+IG1hcC5cbiAgICAgICAgdGhpcy5wcmV2T3BlbiA9IHRoaXMub3BlbjtcbiAgICAgICAgdGhpcy5zZWxlY3RXaWR0aCA9IDA7XG4gICAgICAgIGlmIChpc1NlcnZlcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0aGlzLmhhbmRsZUZvY3VzLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCB0aGlzLmhhbmRsZUJsdXIuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlbGVjdHMgYW4gb3B0aW9uIGdpdmVuIHRoZSB2YWx1ZSBvZiB0aGUgb3B0aW9uLCBhbmQgdXBkYXRlcyBNZFNlbGVjdCdzXG4gICAgICogdmFsdWUuXG4gICAgICovXG4gICAgc2VsZWN0KHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvblRvU2VsZWN0ID0gdGhpcy5vcHRpb25zLmZpbmQoKG9wdGlvbikgPT4gb3B0aW9uLnZhbHVlID09PSB2YWx1ZSk7XG4gICAgICAgIGlmIChvcHRpb25Ub1NlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RJdGVtKG9wdGlvblRvU2VsZWN0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWxlY3RzIGFuIG9wdGlvbiBnaXZlbiB0aGUgaW5kZXggb2YgdGhlIG9wdGlvbiwgYW5kIHVwZGF0ZXMgTWRTZWxlY3Qnc1xuICAgICAqIHZhbHVlLlxuICAgICAqL1xuICAgIHNlbGVjdEluZGV4KGluZGV4KSB7XG4gICAgICAgIGNvbnN0IG9wdGlvblRvU2VsZWN0ID0gdGhpcy5vcHRpb25zW2luZGV4XTtcbiAgICAgICAgaWYgKG9wdGlvblRvU2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdEl0ZW0ob3B0aW9uVG9TZWxlY3QpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc2V0IHRoZSBzZWxlY3QgdG8gaXRzIGRlZmF1bHQgdmFsdWUuXG4gICAgICovXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIHRoaXMub3B0aW9ucykge1xuICAgICAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gb3B0aW9uLmhhc0F0dHJpYnV0ZSgnc2VsZWN0ZWQnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZVZhbHVlQW5kRGlzcGxheVRleHQoKTtcbiAgICAgICAgdGhpcy5uYXRpdmVFcnJvciA9IGZhbHNlO1xuICAgICAgICB0aGlzLm5hdGl2ZUVycm9yVGV4dCA9ICcnO1xuICAgIH1cbiAgICBbKF9hID0gVkFMVUUsIG9uUmVwb3J0VmFsaWRpdHkpXShpbnZhbGlkRXZlbnQpIHtcbiAgICAgICAgLy8gUHJldmVudCBkZWZhdWx0IHBvcC11cCBiZWhhdmlvci5cbiAgICAgICAgaW52YWxpZEV2ZW50Py5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBwcmV2TWVzc2FnZSA9IHRoaXMuZ2V0RXJyb3JUZXh0KCk7XG4gICAgICAgIHRoaXMubmF0aXZlRXJyb3IgPSAhIWludmFsaWRFdmVudDtcbiAgICAgICAgdGhpcy5uYXRpdmVFcnJvclRleHQgPSB0aGlzLnZhbGlkYXRpb25NZXNzYWdlO1xuICAgICAgICBpZiAocHJldk1lc3NhZ2UgPT09IHRoaXMuZ2V0RXJyb3JUZXh0KCkpIHtcbiAgICAgICAgICAgIHRoaXMuZmllbGQ/LnJlYW5ub3VuY2VFcnJvcigpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHVwZGF0ZShjaGFuZ2VkKSB7XG4gICAgICAgIC8vIEluIFNTUiB0aGUgb3B0aW9ucyB3aWxsIGJlIHJlYWR5IHRvIHF1ZXJ5LCBzbyB0cnkgdG8gZmlndXJlIG91dCB3aGF0XG4gICAgICAgIC8vIHRoZSB2YWx1ZSBhbmQgZGlzcGxheSB0ZXh0IHNob3VsZCBiZS5cbiAgICAgICAgaWYgKCF0aGlzLmhhc1VwZGF0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFVzZXJTZWxlY3Rpb24oKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBXZSBoYXZlIGp1c3Qgb3BlbmVkIHRoZSBtZW51LlxuICAgICAgICAvLyBXZSBhcmUgb25seSBhYmxlIHRvIGNoZWNrIGZvciB0aGUgc2VsZWN0J3MgcmVjdCBpbiBgdXBkYXRlKClgIGluc3RlYWQgb2ZcbiAgICAgICAgLy8gaGF2aW5nIHRvIHdhaXQgZm9yIGB1cGRhdGVkKClgIGJlY2F1c2UgdGhlIG1lbnUgY2FuIG5ldmVyIGJlIG9wZW4gb25cbiAgICAgICAgLy8gZmlyc3QgcmVuZGVyIHNpbmNlIGl0IGlzIG5vdCBzZXR0YWJsZSBhbmQgTGl0IFNTUiBkb2VzIG5vdCBzdXBwb3J0IGNsaWNrXG4gICAgICAgIC8vIGV2ZW50cyB3aGljaCB3b3VsZCBvcGVuIHRoZSBtZW51LlxuICAgICAgICBpZiAodGhpcy5wcmV2T3BlbiAhPT0gdGhpcy5vcGVuICYmIHRoaXMub3Blbikge1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0UmVjdCA9IHRoaXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdFdpZHRoID0gc2VsZWN0UmVjdC53aWR0aDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByZXZPcGVuID0gdGhpcy5vcGVuO1xuICAgICAgICBzdXBlci51cGRhdGUoY2hhbmdlZCk7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPHNwYW5cbiAgICAgICAgY2xhc3M9XCJzZWxlY3QgJHtjbGFzc01hcCh0aGlzLmdldFJlbmRlckNsYXNzZXMoKSl9XCJcbiAgICAgICAgQGZvY3Vzb3V0PSR7dGhpcy5oYW5kbGVGb2N1c291dH0+XG4gICAgICAgICR7dGhpcy5yZW5kZXJGaWVsZCgpfSAke3RoaXMucmVuZGVyTWVudSgpfVxuICAgICAgPC9zcGFuPlxuICAgIGA7XG4gICAgfVxuICAgIGFzeW5jIGZpcnN0VXBkYXRlZChjaGFuZ2VkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubWVudT8udXBkYXRlQ29tcGxldGU7XG4gICAgICAgIC8vIElmIHRoaXMgaGFzIGJlZW4gaGFuZGxlZCBvbiB1cGRhdGUgYWxyZWFkeSBkdWUgdG8gU1NSLCB0cnkgYWdhaW4uXG4gICAgICAgIGlmICghdGhpcy5sYXN0U2VsZWN0ZWRPcHRpb25SZWNvcmRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5pbml0VXNlclNlbGVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIENhc2UgZm9yIHdoZW4gdGhlIERPTSBpcyBzdHJlYW1pbmcsIHRoZXJlIGFyZSBubyBjaGlsZHJlbiwgYW5kIGEgY2hpbGRcbiAgICAgICAgLy8gaGFzIFtzZWxlY3RlZF0gc2V0IG9uIGl0LCB3ZSBuZWVkIHRvIHdhaXQgZm9yIERPTSB0byByZW5kZXIgc29tZXRoaW5nLlxuICAgICAgICBpZiAoIXRoaXMubGFzdFNlbGVjdGVkT3B0aW9uUmVjb3Jkcy5sZW5ndGggJiZcbiAgICAgICAgICAgICFpc1NlcnZlciAmJlxuICAgICAgICAgICAgIXRoaXMub3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlVmFsdWVBbmREaXNwbGF5VGV4dCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc3VwZXIuZmlyc3RVcGRhdGVkKGNoYW5nZWQpO1xuICAgIH1cbiAgICBnZXRSZW5kZXJDbGFzc2VzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgJ2Rpc2FibGVkJzogdGhpcy5kaXNhYmxlZCxcbiAgICAgICAgICAgICdlcnJvcic6IHRoaXMuZXJyb3IsXG4gICAgICAgICAgICAnb3Blbic6IHRoaXMub3BlbixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyRmllbGQoKSB7XG4gICAgICAgIGNvbnN0IGFyaWFMYWJlbCA9IHRoaXMuYXJpYUxhYmVsIHx8IHRoaXMubGFiZWw7XG4gICAgICAgIHJldHVybiBzdGF0aWNIdG1sIGBcbiAgICAgIDwke3RoaXMuZmllbGRUYWd9XG4gICAgICAgICAgYXJpYS1oYXNwb3B1cD1cImxpc3Rib3hcIlxuICAgICAgICAgIHJvbGU9XCJjb21ib2JveFwiXG4gICAgICAgICAgcGFydD1cImZpZWxkXCJcbiAgICAgICAgICBpZD1cImZpZWxkXCJcbiAgICAgICAgICB0YWJpbmRleD0ke3RoaXMuZGlzYWJsZWQgPyAnLTEnIDogJzAnfVxuICAgICAgICAgIGFyaWEtbGFiZWw9JHthcmlhTGFiZWwgfHwgbm90aGluZ31cbiAgICAgICAgICBhcmlhLWRlc2NyaWJlZGJ5PVwiZGVzY3JpcHRpb25cIlxuICAgICAgICAgIGFyaWEtZXhwYW5kZWQ9JHt0aGlzLm9wZW4gPyAndHJ1ZScgOiAnZmFsc2UnfVxuICAgICAgICAgIGFyaWEtY29udHJvbHM9XCJsaXN0Ym94XCJcbiAgICAgICAgICBjbGFzcz1cImZpZWxkXCJcbiAgICAgICAgICBsYWJlbD0ke3RoaXMubGFiZWx9XG4gICAgICAgICAgP25vLWFzdGVyaXNrPSR7dGhpcy5ub0FzdGVyaXNrfVxuICAgICAgICAgIC5mb2N1c2VkPSR7dGhpcy5mb2N1c2VkIHx8IHRoaXMub3Blbn1cbiAgICAgICAgICAucG9wdWxhdGVkPSR7ISF0aGlzLmRpc3BsYXlUZXh0fVxuICAgICAgICAgIC5kaXNhYmxlZD0ke3RoaXMuZGlzYWJsZWR9XG4gICAgICAgICAgLnJlcXVpcmVkPSR7dGhpcy5yZXF1aXJlZH1cbiAgICAgICAgICAuZXJyb3I9JHt0aGlzLmhhc0Vycm9yfVxuICAgICAgICAgID9oYXMtc3RhcnQ9JHt0aGlzLmhhc0xlYWRpbmdJY29ufVxuICAgICAgICAgIGhhcy1lbmRcbiAgICAgICAgICBzdXBwb3J0aW5nLXRleHQ9JHt0aGlzLnN1cHBvcnRpbmdUZXh0fVxuICAgICAgICAgIGVycm9yLXRleHQ9JHt0aGlzLmdldEVycm9yVGV4dCgpfVxuICAgICAgICAgIEBrZXlkb3duPSR7dGhpcy5oYW5kbGVLZXlkb3dufVxuICAgICAgICAgIEBjbGljaz0ke3RoaXMuaGFuZGxlQ2xpY2t9PlxuICAgICAgICAgJHt0aGlzLnJlbmRlckZpZWxkQ29udGVudCgpfVxuICAgICAgICAgPGRpdiBpZD1cImRlc2NyaXB0aW9uXCIgc2xvdD1cImFyaWEtZGVzY3JpYmVkYnlcIj48L2Rpdj5cbiAgICAgIDwvJHt0aGlzLmZpZWxkVGFnfT5gO1xuICAgIH1cbiAgICByZW5kZXJGaWVsZENvbnRlbnQoKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICB0aGlzLnJlbmRlckxlYWRpbmdJY29uKCksXG4gICAgICAgICAgICB0aGlzLnJlbmRlckxhYmVsKCksXG4gICAgICAgICAgICB0aGlzLnJlbmRlclRyYWlsaW5nSWNvbigpLFxuICAgICAgICBdO1xuICAgIH1cbiAgICByZW5kZXJMZWFkaW5nSWNvbigpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPHNwYW4gY2xhc3M9XCJpY29uIGxlYWRpbmdcIiBzbG90PVwic3RhcnRcIj5cbiAgICAgICAgPHNsb3QgbmFtZT1cImxlYWRpbmctaWNvblwiIEBzbG90Y2hhbmdlPSR7dGhpcy5oYW5kbGVJY29uQ2hhbmdlfT48L3Nsb3Q+XG4gICAgICA8L3NwYW4+XG4gICAgYDtcbiAgICB9XG4gICAgcmVuZGVyVHJhaWxpbmdJY29uKCkge1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8c3BhbiBjbGFzcz1cImljb24gdHJhaWxpbmdcIiBzbG90PVwiZW5kXCI+XG4gICAgICAgIDxzbG90IG5hbWU9XCJ0cmFpbGluZy1pY29uXCIgQHNsb3RjaGFuZ2U9JHt0aGlzLmhhbmRsZUljb25DaGFuZ2V9PlxuICAgICAgICAgIDxzdmcgaGVpZ2h0PVwiNVwiIHZpZXdCb3g9XCI3IDEwIDEwIDVcIiBmb2N1c2FibGU9XCJmYWxzZVwiPlxuICAgICAgICAgICAgPHBvbHlnb25cbiAgICAgICAgICAgICAgY2xhc3M9XCJkb3duXCJcbiAgICAgICAgICAgICAgc3Ryb2tlPVwibm9uZVwiXG4gICAgICAgICAgICAgIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgICBwb2ludHM9XCI3IDEwIDEyIDE1IDE3IDEwXCI+PC9wb2x5Z29uPlxuICAgICAgICAgICAgPHBvbHlnb25cbiAgICAgICAgICAgICAgY2xhc3M9XCJ1cFwiXG4gICAgICAgICAgICAgIHN0cm9rZT1cIm5vbmVcIlxuICAgICAgICAgICAgICBmaWxsLXJ1bGU9XCJldmVub2RkXCJcbiAgICAgICAgICAgICAgcG9pbnRzPVwiNyAxNSAxMiAxMCAxNyAxNVwiPjwvcG9seWdvbj5cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgPC9zbG90PlxuICAgICAgPC9zcGFuPlxuICAgIGA7XG4gICAgfVxuICAgIHJlbmRlckxhYmVsKCkge1xuICAgICAgICAvLyBuZWVkIHRvIHJlbmRlciAmbmJzcDsgc28gdGhhdCBsaW5lLWhlaWdodCBjYW4gYXBwbHkgYW5kIGdpdmUgaXQgYVxuICAgICAgICAvLyBub24temVybyBoZWlnaHRcbiAgICAgICAgcmV0dXJuIGh0bWwgYDxkaXYgaWQ9XCJsYWJlbFwiPiR7dGhpcy5kaXNwbGF5VGV4dCB8fCBodG1sIGAmbmJzcDtgfTwvZGl2PmA7XG4gICAgfVxuICAgIHJlbmRlck1lbnUoKSB7XG4gICAgICAgIGNvbnN0IGFyaWFMYWJlbCA9IHRoaXMubGFiZWwgfHwgdGhpcy5hcmlhTGFiZWw7XG4gICAgICAgIHJldHVybiBodG1sIGA8ZGl2IGNsYXNzPVwibWVudS13cmFwcGVyXCI+XG4gICAgICA8bWQtbWVudVxuICAgICAgICBpZD1cImxpc3Rib3hcIlxuICAgICAgICAuZGVmYXVsdEZvY3VzPSR7dGhpcy5kZWZhdWx0Rm9jdXN9XG4gICAgICAgIHJvbGU9XCJsaXN0Ym94XCJcbiAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgIGFyaWEtbGFiZWw9JHthcmlhTGFiZWwgfHwgbm90aGluZ31cbiAgICAgICAgc3RheS1vcGVuLW9uLWZvY3Vzb3V0XG4gICAgICAgIHBhcnQ9XCJtZW51XCJcbiAgICAgICAgZXhwb3J0cGFydHM9XCJmb2N1cy1yaW5nOiBtZW51LWZvY3VzLXJpbmdcIlxuICAgICAgICBhbmNob3I9XCJmaWVsZFwiXG4gICAgICAgIHN0eWxlPSR7c3R5bGVNYXAoe1xuICAgICAgICAgICAgJy0tX19tZW51LW1pbi13aWR0aCc6IGAke3RoaXMuc2VsZWN0V2lkdGh9cHhgLFxuICAgICAgICAgICAgJy0tX19tZW51LW1heC13aWR0aCc6IHRoaXMuY2xhbXBNZW51V2lkdGhcbiAgICAgICAgICAgICAgICA/IGAke3RoaXMuc2VsZWN0V2lkdGh9cHhgXG4gICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgIH0pfVxuICAgICAgICBuby1uYXZpZ2F0aW9uLXdyYXBcbiAgICAgICAgLm9wZW49JHt0aGlzLm9wZW59XG4gICAgICAgIC5xdWljaz0ke3RoaXMucXVpY2t9XG4gICAgICAgIC5wb3NpdGlvbmluZz0ke3RoaXMubWVudVBvc2l0aW9uaW5nfVxuICAgICAgICAudHlwZWFoZWFkRGVsYXk9JHt0aGlzLnR5cGVhaGVhZERlbGF5fVxuICAgICAgICAuYW5jaG9yQ29ybmVyPSR7dGhpcy5tZW51QWxpZ24gPT09ICdzdGFydCcgPyAnZW5kLXN0YXJ0JyA6ICdlbmQtZW5kJ31cbiAgICAgICAgLm1lbnVDb3JuZXI9JHt0aGlzLm1lbnVBbGlnbiA9PT0gJ3N0YXJ0JyA/ICdzdGFydC1zdGFydCcgOiAnc3RhcnQtZW5kJ31cbiAgICAgICAgQG9wZW5pbmc9JHt0aGlzLmhhbmRsZU9wZW5pbmd9XG4gICAgICAgIEBvcGVuZWQ9JHt0aGlzLnJlZGlzcGF0Y2hFdmVudH1cbiAgICAgICAgQGNsb3Npbmc9JHt0aGlzLnJlZGlzcGF0Y2hFdmVudH1cbiAgICAgICAgQGNsb3NlZD0ke3RoaXMuaGFuZGxlQ2xvc2VkfVxuICAgICAgICBAY2xvc2UtbWVudT0ke3RoaXMuaGFuZGxlQ2xvc2VNZW51fVxuICAgICAgICBAcmVxdWVzdC1zZWxlY3Rpb249JHt0aGlzLmhhbmRsZVJlcXVlc3RTZWxlY3Rpb259XG4gICAgICAgIEByZXF1ZXN0LWRlc2VsZWN0aW9uPSR7dGhpcy5oYW5kbGVSZXF1ZXN0RGVzZWxlY3Rpb259PlxuICAgICAgICAke3RoaXMucmVuZGVyTWVudUNvbnRlbnQoKX1cbiAgICAgIDwvbWQtbWVudT5cbiAgICA8L2Rpdj5gO1xuICAgIH1cbiAgICByZW5kZXJNZW51Q29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYDxzbG90Pjwvc2xvdD5gO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIG9wZW5pbmcgdGhlIHNlbGVjdCBvbiBrZXlkb3duIGFuZCB0eXBhaGVhZCBzZWxlY3Rpb24gd2hlbiB0aGUgbWVudVxuICAgICAqIGlzIGNsb3NlZC5cbiAgICAgKi9cbiAgICBoYW5kbGVLZXlkb3duKGV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLm9wZW4gfHwgdGhpcy5kaXNhYmxlZCB8fCAhdGhpcy5tZW51KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdHlwZWFoZWFkQ29udHJvbGxlciA9IHRoaXMubWVudS50eXBlYWhlYWRDb250cm9sbGVyO1xuICAgICAgICBjb25zdCBpc09wZW5LZXkgPSBldmVudC5jb2RlID09PSAnU3BhY2UnIHx8XG4gICAgICAgICAgICBldmVudC5jb2RlID09PSAnQXJyb3dEb3duJyB8fFxuICAgICAgICAgICAgZXZlbnQuY29kZSA9PT0gJ0Fycm93VXAnIHx8XG4gICAgICAgICAgICBldmVudC5jb2RlID09PSAnRW5kJyB8fFxuICAgICAgICAgICAgZXZlbnQuY29kZSA9PT0gJ0hvbWUnIHx8XG4gICAgICAgICAgICBldmVudC5jb2RlID09PSAnRW50ZXInO1xuICAgICAgICAvLyBEbyBub3Qgb3BlbiBpZiBjdXJyZW50bHkgdHlwaW5nIGFoZWFkIGJlY2F1c2UgdGhlIHVzZXIgbWF5IGJlIHR5cGluZyB0aGVcbiAgICAgICAgLy8gc3BhY2ViYXIgdG8gbWF0Y2ggYSB3b3JkIHdpdGggYSBzcGFjZVxuICAgICAgICBpZiAoIXR5cGVhaGVhZENvbnRyb2xsZXIuaXNUeXBpbmdBaGVhZCAmJiBpc09wZW5LZXkpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLm9wZW4gPSB0cnVlO1xuICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1dBSS9BUklBL2FwZy9wYXR0ZXJucy9jb21ib2JveC9leGFtcGxlcy9jb21ib2JveC1zZWxlY3Qtb25seS8ja2JkX2xhYmVsXG4gICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LmNvZGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdTcGFjZSc6XG4gICAgICAgICAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgICAgICAgICBjYXNlICdFbnRlcic6XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIHdpbGwgaGFuZGxlIGZvY3VzaW5nIGxhc3Qgc2VsZWN0ZWQgaXRlbSBpbiB0aGlzLmhhbmRsZU9wZW5pbmcoKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHRGb2N1cyA9IEZvY3VzU3RhdGUuTk9ORTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnRW5kJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0Rm9jdXMgPSBGb2N1c1N0YXRlLkxBU1RfSVRFTTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnQXJyb3dVcCc6XG4gICAgICAgICAgICAgICAgY2FzZSAnSG9tZSc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVmYXVsdEZvY3VzID0gRm9jdXNTdGF0ZS5GSVJTVF9JVEVNO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpc1ByaW50YWJsZUtleSA9IGV2ZW50LmtleS5sZW5ndGggPT09IDE7XG4gICAgICAgIC8vIEhhbmRsZXMgdHlwaW5nIGFoZWFkIHdoZW4gdGhlIG1lbnUgaXMgY2xvc2VkIGJ5IGRlbGVnYXRpbmcgdGhlIGV2ZW50IHRvXG4gICAgICAgIC8vIHRoZSB1bmRlcmx5aW5nIG1lbnUncyB0eXBlYWhlYWRDb250cm9sbGVyXG4gICAgICAgIGlmIChpc1ByaW50YWJsZUtleSkge1xuICAgICAgICAgICAgdHlwZWFoZWFkQ29udHJvbGxlci5vbktleWRvd24oZXZlbnQpO1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGNvbnN0IHsgbGFzdEFjdGl2ZVJlY29yZCB9ID0gdHlwZWFoZWFkQ29udHJvbGxlcjtcbiAgICAgICAgICAgIGlmICghbGFzdEFjdGl2ZVJlY29yZCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubGFiZWxFbD8uc2V0QXR0cmlidXRlPy4oJ2FyaWEtbGl2ZScsICdwb2xpdGUnKTtcbiAgICAgICAgICAgIGNvbnN0IGhhc0NoYW5nZWQgPSB0aGlzLnNlbGVjdEl0ZW0obGFzdEFjdGl2ZVJlY29yZFtUWVBFQUhFQURfUkVDT1JELklURU1dKTtcbiAgICAgICAgICAgIGlmIChoYXNDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwYXRjaEludGVyYWN0aW9uRXZlbnRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaGFuZGxlQ2xpY2soKSB7XG4gICAgICAgIHRoaXMub3BlbiA9ICF0aGlzLm9wZW47XG4gICAgfVxuICAgIGhhbmRsZUZvY3VzKCkge1xuICAgICAgICB0aGlzLmZvY3VzZWQgPSB0cnVlO1xuICAgIH1cbiAgICBoYW5kbGVCbHVyKCkge1xuICAgICAgICB0aGlzLmZvY3VzZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBjbG9zaW5nIHRoZSBtZW51IHdoZW4gdGhlIGZvY3VzIGxlYXZlcyB0aGUgc2VsZWN0J3Mgc3VidHJlZS5cbiAgICAgKi9cbiAgICBoYW5kbGVGb2N1c291dChldmVudCkge1xuICAgICAgICAvLyBEb24ndCBjbG9zZSB0aGUgbWVudSBpZiB3ZSBhcmUgc3dpdGNoaW5nIGZvY3VzIGJldHdlZW4gbWVudSxcbiAgICAgICAgLy8gc2VsZWN0LW9wdGlvbiwgYW5kIGZpZWxkXG4gICAgICAgIGlmIChldmVudC5yZWxhdGVkVGFyZ2V0ICYmIGlzRWxlbWVudEluU3VidHJlZShldmVudC5yZWxhdGVkVGFyZ2V0LCB0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlbiA9IGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXRzIGEgbGlzdCBvZiBhbGwgc2VsZWN0ZWQgc2VsZWN0IG9wdGlvbnMgYXMgYSBsaXN0IGl0ZW0gcmVjb3JkIGFycmF5LlxuICAgICAqXG4gICAgICogQHJldHVybiBBbiBhcnJheSBvZiBzZWxlY3RlZCBsaXN0IG9wdGlvbiByZWNvcmRzLlxuICAgICAqL1xuICAgIGdldFNlbGVjdGVkT3B0aW9ucygpIHtcbiAgICAgICAgaWYgKCF0aGlzLm1lbnUpIHtcbiAgICAgICAgICAgIHRoaXMubGFzdFNlbGVjdGVkT3B0aW9uUmVjb3JkcyA9IFtdO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLm1lbnUuaXRlbXM7XG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkT3B0aW9uUmVjb3JkcyA9IGdldFNlbGVjdGVkSXRlbXMoaXRlbXMpO1xuICAgICAgICByZXR1cm4gdGhpcy5sYXN0U2VsZWN0ZWRPcHRpb25SZWNvcmRzO1xuICAgIH1cbiAgICBhc3luYyBnZXRVcGRhdGVDb21wbGV0ZSgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5tZW51Py51cGRhdGVDb21wbGV0ZTtcbiAgICAgICAgcmV0dXJuIHN1cGVyLmdldFVwZGF0ZUNvbXBsZXRlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHNlbGVjdGVkIG9wdGlvbnMgZnJvbSB0aGUgRE9NLCBhbmQgdXBkYXRlcyB0aGUgdmFsdWUgYW5kIGRpc3BsYXlcbiAgICAgKiB0ZXh0IHRvIHRoZSBmaXJzdCBzZWxlY3RlZCBvcHRpb24ncyB2YWx1ZSBhbmQgaGVhZGxpbmUgcmVzcGVjdGl2ZWx5LlxuICAgICAqXG4gICAgICogQHJldHVybiBXaGV0aGVyIG9yIG5vdCB0aGUgc2VsZWN0ZWQgb3B0aW9uIGhhcyBjaGFuZ2VkIHNpbmNlIGxhc3QgdXBkYXRlLlxuICAgICAqL1xuICAgIHVwZGF0ZVZhbHVlQW5kRGlzcGxheVRleHQoKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkT3B0aW9ucyA9IHRoaXMuZ2V0U2VsZWN0ZWRPcHRpb25zKCkgPz8gW107XG4gICAgICAgIC8vIFVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgb3Igbm90IHdlIG5lZWQgdG8gZmlyZSBhbiBpbnB1dCAvIGNoYW5nZSBldmVudFxuICAgICAgICAvLyB3aGljaCBmaXJlIHdoZW5ldmVyIHRoZSBvcHRpb24gZWxlbWVudCBjaGFuZ2VzICh2YWx1ZSBvciBzZWxlY3RlZEluZGV4KVxuICAgICAgICAvLyBvbiB1c2VyIGludGVyYWN0aW9uLlxuICAgICAgICBsZXQgaGFzU2VsZWN0ZWRPcHRpb25DaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGlmIChzZWxlY3RlZE9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBbZmlyc3RTZWxlY3RlZE9wdGlvbl0gPSBzZWxlY3RlZE9wdGlvbnNbMF07XG4gICAgICAgICAgICBoYXNTZWxlY3RlZE9wdGlvbkNoYW5nZWQgPVxuICAgICAgICAgICAgICAgIHRoaXMubGFzdFNlbGVjdGVkT3B0aW9uICE9PSBmaXJzdFNlbGVjdGVkT3B0aW9uO1xuICAgICAgICAgICAgdGhpcy5sYXN0U2VsZWN0ZWRPcHRpb24gPSBmaXJzdFNlbGVjdGVkT3B0aW9uO1xuICAgICAgICAgICAgdGhpc1tWQUxVRV0gPSBmaXJzdFNlbGVjdGVkT3B0aW9uLnZhbHVlO1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5VGV4dCA9IGZpcnN0U2VsZWN0ZWRPcHRpb24uZGlzcGxheVRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBoYXNTZWxlY3RlZE9wdGlvbkNoYW5nZWQgPSB0aGlzLmxhc3RTZWxlY3RlZE9wdGlvbiAhPT0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMubGFzdFNlbGVjdGVkT3B0aW9uID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXNbVkFMVUVdID0gJyc7XG4gICAgICAgICAgICB0aGlzLmRpc3BsYXlUZXh0ID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhc1NlbGVjdGVkT3B0aW9uQ2hhbmdlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRm9jdXNlcyBhbmQgYWN0aXZhdGVzIHRoZSBsYXN0IHNlbGVjdGVkIGl0ZW0gdXBvbiBvcGVuaW5nLCBhbmQgcmVzZXRzIG90aGVyXG4gICAgICogYWN0aXZlIGl0ZW1zLlxuICAgICAqL1xuICAgIGFzeW5jIGhhbmRsZU9wZW5pbmcoZSkge1xuICAgICAgICB0aGlzLmxhYmVsRWw/LnJlbW92ZUF0dHJpYnV0ZT8uKCdhcmlhLWxpdmUnKTtcbiAgICAgICAgdGhpcy5yZWRpc3BhdGNoRXZlbnQoZSk7XG4gICAgICAgIC8vIEZvY3VzU3RhdGUuTk9ORSBtZWFucyB3ZSB3YW50IHRvIGhhbmRsZSBmb2N1cyBvdXJzZWx2ZXMgYW5kIGZvY3VzIHRoZVxuICAgICAgICAvLyBsYXN0IHNlbGVjdGVkIGl0ZW0uXG4gICAgICAgIGlmICh0aGlzLmRlZmF1bHRGb2N1cyAhPT0gRm9jdXNTdGF0ZS5OT05FKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLm1lbnUuaXRlbXM7XG4gICAgICAgIGNvbnN0IGFjdGl2ZUl0ZW0gPSBnZXRBY3RpdmVJdGVtKGl0ZW1zKT8uaXRlbTtcbiAgICAgICAgbGV0IFtzZWxlY3RlZEl0ZW1dID0gdGhpcy5sYXN0U2VsZWN0ZWRPcHRpb25SZWNvcmRzWzBdID8/IFtudWxsXTtcbiAgICAgICAgLy8gVGhpcyBpcyB0cnVlIGlmIHRoZSB1c2VyIGtleXMgdGhyb3VnaCB0aGUgbGlzdCBidXQgY2xpY2tzIG91dCBvZiB0aGUgbWVudVxuICAgICAgICAvLyB0aHVzIG5vIGNsb3NlLW1lbnUgZXZlbnQgaXMgZmlyZWQgYnkgYW4gaXRlbSBhbmQgd2UgY2FuJ3QgY2xlYW4gdXAgaW5cbiAgICAgICAgLy8gaGFuZGxlQ2xvc2VNZW51LlxuICAgICAgICBpZiAoYWN0aXZlSXRlbSAmJiBhY3RpdmVJdGVtICE9PSBzZWxlY3RlZEl0ZW0pIHtcbiAgICAgICAgICAgIGFjdGl2ZUl0ZW0udGFiSW5kZXggPSAtMTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpbiB0aGUgY2FzZSB0aGF0IG5vdGhpbmcgaXMgc2VsZWN0ZWQsIGZvY3VzIHRoZSBmaXJzdCBpdGVtXG4gICAgICAgIHNlbGVjdGVkSXRlbSA9IHNlbGVjdGVkSXRlbSA/PyBpdGVtc1swXTtcbiAgICAgICAgaWYgKHNlbGVjdGVkSXRlbSkge1xuICAgICAgICAgICAgc2VsZWN0ZWRJdGVtLnRhYkluZGV4ID0gMDtcbiAgICAgICAgICAgIHNlbGVjdGVkSXRlbS5mb2N1cygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlZGlzcGF0Y2hFdmVudChlKSB7XG4gICAgICAgIHJlZGlzcGF0Y2hFdmVudCh0aGlzLCBlKTtcbiAgICB9XG4gICAgaGFuZGxlQ2xvc2VkKGUpIHtcbiAgICAgICAgdGhpcy5vcGVuID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVkaXNwYXRjaEV2ZW50KGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIHRoZSByZWFzb24gZm9yIGNsb3NpbmcsIGFuZCB1cGRhdGVzIHRoZSBVSSBhY2NvcmRpbmdseS5cbiAgICAgKi9cbiAgICBoYW5kbGVDbG9zZU1lbnUoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgcmVhc29uID0gZXZlbnQuZGV0YWlsLnJlYXNvbjtcbiAgICAgICAgY29uc3QgaXRlbSA9IGV2ZW50LmRldGFpbC5pdGVtUGF0aFswXTtcbiAgICAgICAgdGhpcy5vcGVuID0gZmFsc2U7XG4gICAgICAgIGxldCBoYXNDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGlmIChyZWFzb24ua2luZCA9PT0gJ2NsaWNrLXNlbGVjdGlvbicpIHtcbiAgICAgICAgICAgIGhhc0NoYW5nZWQgPSB0aGlzLnNlbGVjdEl0ZW0oaXRlbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocmVhc29uLmtpbmQgPT09ICdrZXlkb3duJyAmJiBpc1NlbGVjdGFibGVLZXkocmVhc29uLmtleSkpIHtcbiAgICAgICAgICAgIGhhc0NoYW5nZWQgPSB0aGlzLnNlbGVjdEl0ZW0oaXRlbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBUaGlzIGNhbiBoYXBwZW4gb24gRVNDIGJlaW5nIHByZXNzZWRcbiAgICAgICAgICAgIGl0ZW0udGFiSW5kZXggPSAtMTtcbiAgICAgICAgICAgIGl0ZW0uYmx1cigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIERpc3BhdGNoIGludGVyYWN0aW9uIGV2ZW50cyBzaW5jZSBzZWxlY3Rpb24gaGFzIGJlZW4gbWFkZSB2aWEga2V5Ym9hcmRcbiAgICAgICAgLy8gb3IgbW91c2UuXG4gICAgICAgIGlmIChoYXNDaGFuZ2VkKSB7XG4gICAgICAgICAgICB0aGlzLmRpc3BhdGNoSW50ZXJhY3Rpb25FdmVudHMoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWxlY3RzIGEgZ2l2ZW4gb3B0aW9uLCBkZXNlbGVjdHMgb3RoZXIgb3B0aW9ucywgYW5kIHVwZGF0ZXMgdGhlIFVJLlxuICAgICAqXG4gICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsYXN0IHNlbGVjdGVkIG9wdGlvbiBoYXMgY2hhbmdlZC5cbiAgICAgKi9cbiAgICBzZWxlY3RJdGVtKGl0ZW0pIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRPcHRpb25zID0gdGhpcy5nZXRTZWxlY3RlZE9wdGlvbnMoKSA/PyBbXTtcbiAgICAgICAgc2VsZWN0ZWRPcHRpb25zLmZvckVhY2goKFtvcHRpb25dKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXRlbSAhPT0gb3B0aW9uKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpdGVtLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMudXBkYXRlVmFsdWVBbmREaXNwbGF5VGV4dCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHVwZGF0aW5nIHNlbGVjdGlvbiB3aGVuIGFuIG9wdGlvbiBlbGVtZW50IHJlcXVlc3RzIHNlbGVjdGlvbiB2aWFcbiAgICAgKiBwcm9wZXJ0eSAvIGF0dHJpYnV0ZSBjaGFuZ2UuXG4gICAgICovXG4gICAgaGFuZGxlUmVxdWVzdFNlbGVjdGlvbihldmVudCkge1xuICAgICAgICBjb25zdCByZXF1ZXN0aW5nT3B0aW9uRWwgPSBldmVudC50YXJnZXQ7XG4gICAgICAgIC8vIE5vLW9wIGlmIHRoaXMgaXRlbSBpcyBhbHJlYWR5IHNlbGVjdGVkLlxuICAgICAgICBpZiAodGhpcy5sYXN0U2VsZWN0ZWRPcHRpb25SZWNvcmRzLnNvbWUoKFtvcHRpb25dKSA9PiBvcHRpb24gPT09IHJlcXVlc3RpbmdPcHRpb25FbCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbGVjdEl0ZW0ocmVxdWVzdGluZ09wdGlvbkVsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlcyB1cGRhdGluZyBzZWxlY3Rpb24gd2hlbiBhbiBvcHRpb24gZWxlbWVudCByZXF1ZXN0cyBkZXNlbGVjdGlvbiB2aWFcbiAgICAgKiBwcm9wZXJ0eSAvIGF0dHJpYnV0ZSBjaGFuZ2UuXG4gICAgICovXG4gICAgaGFuZGxlUmVxdWVzdERlc2VsZWN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RpbmdPcHRpb25FbCA9IGV2ZW50LnRhcmdldDtcbiAgICAgICAgLy8gTm8tb3AgaWYgdGhpcyBpdGVtIGlzIG5vdCBldmVuIGluIHRoZSBsaXN0IG9mIHRyYWNrZWQgc2VsZWN0ZWQgaXRlbXMuXG4gICAgICAgIGlmICghdGhpcy5sYXN0U2VsZWN0ZWRPcHRpb25SZWNvcmRzLnNvbWUoKFtvcHRpb25dKSA9PiBvcHRpb24gPT09IHJlcXVlc3RpbmdPcHRpb25FbCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZVZhbHVlQW5kRGlzcGxheVRleHQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gaW5pdGlhbGl6ZSB0aGUgc2VsZWN0ZWQgb3B0aW9uIGZyb20gdXNlci1zZXR0YWJsZSB2YWx1ZXMgbGlrZVxuICAgICAqIFNTUiwgc2V0dGluZyBgdmFsdWVgLCBvciBgc2VsZWN0ZWRJbmRleGAgYXQgc3RhcnR1cC5cbiAgICAgKi9cbiAgICBpbml0VXNlclNlbGVjdGlvbigpIHtcbiAgICAgICAgLy8gVXNlciBoYXMgc2V0IGAudmFsdWVgIGRpcmVjdGx5LCBidXQgaW50ZXJuYWxzIGhhdmUgbm90IHlldCBib290ZWQgdXAuXG4gICAgICAgIGlmICh0aGlzLmxhc3RVc2VyU2V0VmFsdWUgJiYgIXRoaXMubGFzdFNlbGVjdGVkT3B0aW9uUmVjb3Jkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0KHRoaXMubGFzdFVzZXJTZXRWYWx1ZSk7XG4gICAgICAgICAgICAvLyBVc2VyIGhhcyBzZXQgYC5zZWxlY3RlZEluZGV4YCBkaXJlY3RseSwgYnV0IGludGVybmFscyBoYXZlIG5vdCB5ZXRcbiAgICAgICAgICAgIC8vIGJvb3RlZCB1cC5cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLmxhc3RVc2VyU2V0U2VsZWN0ZWRJbmRleCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgIXRoaXMubGFzdFNlbGVjdGVkT3B0aW9uUmVjb3Jkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0SW5kZXgodGhpcy5sYXN0VXNlclNldFNlbGVjdGVkSW5kZXgpO1xuICAgICAgICAgICAgLy8gUmVndWxhciBib290IHVwIVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVWYWx1ZUFuZERpc3BsYXlUZXh0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaGFuZGxlSWNvbkNoYW5nZSgpIHtcbiAgICAgICAgdGhpcy5oYXNMZWFkaW5nSWNvbiA9IHRoaXMubGVhZGluZ0ljb25zLmxlbmd0aCA+IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERpc3BhdGNoZXMgdGhlIGBpbnB1dGAgYW5kIGBjaGFuZ2VgIGV2ZW50cy5cbiAgICAgKi9cbiAgICBkaXNwYXRjaEludGVyYWN0aW9uRXZlbnRzKCkge1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdpbnB1dCcsIHsgYnViYmxlczogdHJ1ZSwgY29tcG9zZWQ6IHRydWUgfSkpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdjaGFuZ2UnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgIH1cbiAgICBnZXRFcnJvclRleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yID8gdGhpcy5lcnJvclRleHQgOiB0aGlzLm5hdGl2ZUVycm9yVGV4dDtcbiAgICB9XG4gICAgW2dldEZvcm1WYWx1ZV0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cbiAgICBmb3JtUmVzZXRDYWxsYmFjaygpIHtcbiAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cbiAgICBmb3JtU3RhdGVSZXN0b3JlQ2FsbGJhY2soc3RhdGUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHN0YXRlO1xuICAgIH1cbiAgICBjbGljaygpIHtcbiAgICAgICAgdGhpcy5maWVsZD8uY2xpY2soKTtcbiAgICB9XG4gICAgW2NyZWF0ZVZhbGlkYXRvcl0oKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2VsZWN0VmFsaWRhdG9yKCgpID0+IHRoaXMpO1xuICAgIH1cbiAgICBbZ2V0VmFsaWRpdHlBbmNob3JdKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5maWVsZDtcbiAgICB9XG59XG4vKiogQG5vY29sbGFwc2UgKi9cblNlbGVjdC5zaGFkb3dSb290T3B0aW9ucyA9IHtcbiAgICAuLi5MaXRFbGVtZW50LnNoYWRvd1Jvb3RPcHRpb25zLFxuICAgIGRlbGVnYXRlc0ZvY3VzOiB0cnVlLFxufTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiB9KVxuXSwgU2VsZWN0LnByb3RvdHlwZSwgXCJxdWlja1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuIH0pXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcInJlcXVpcmVkXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IFN0cmluZywgYXR0cmlidXRlOiAnZXJyb3ItdGV4dCcgfSlcbl0sIFNlbGVjdC5wcm90b3R5cGUsIFwiZXJyb3JUZXh0XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcImxhYmVsXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ25vLWFzdGVyaXNrJyB9KVxuXSwgU2VsZWN0LnByb3RvdHlwZSwgXCJub0FzdGVyaXNrXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IFN0cmluZywgYXR0cmlidXRlOiAnc3VwcG9ydGluZy10ZXh0JyB9KVxuXSwgU2VsZWN0LnByb3RvdHlwZSwgXCJzdXBwb3J0aW5nVGV4dFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCByZWZsZWN0OiB0cnVlIH0pXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcImVycm9yXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IGF0dHJpYnV0ZTogJ21lbnUtcG9zaXRpb25pbmcnIH0pXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcIm1lbnVQb3NpdGlvbmluZ1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdjbGFtcC1tZW51LXdpZHRoJyB9KVxuXSwgU2VsZWN0LnByb3RvdHlwZSwgXCJjbGFtcE1lbnVXaWR0aFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBOdW1iZXIsIGF0dHJpYnV0ZTogJ3R5cGVhaGVhZC1kZWxheScgfSlcbl0sIFNlbGVjdC5wcm90b3R5cGUsIFwidHlwZWFoZWFkRGVsYXlcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnaGFzLWxlYWRpbmctaWNvbicgfSlcbl0sIFNlbGVjdC5wcm90b3R5cGUsIFwiaGFzTGVhZGluZ0ljb25cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgYXR0cmlidXRlOiAnZGlzcGxheS10ZXh0JyB9KVxuXSwgU2VsZWN0LnByb3RvdHlwZSwgXCJkaXNwbGF5VGV4dFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyBhdHRyaWJ1dGU6ICdtZW51LWFsaWduJyB9KVxuXSwgU2VsZWN0LnByb3RvdHlwZSwgXCJtZW51QWxpZ25cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KClcbl0sIFNlbGVjdC5wcm90b3R5cGUsIFwidmFsdWVcIiwgbnVsbCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IE51bWJlciwgYXR0cmlidXRlOiAnc2VsZWN0ZWQtaW5kZXgnIH0pXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcInNlbGVjdGVkSW5kZXhcIiwgbnVsbCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcIm5hdGl2ZUVycm9yXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcIm5hdGl2ZUVycm9yVGV4dFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgU2VsZWN0LnByb3RvdHlwZSwgXCJmb2N1c2VkXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcIm9wZW5cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIFNlbGVjdC5wcm90b3R5cGUsIFwiZGVmYXVsdEZvY3VzXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBxdWVyeSgnLmZpZWxkJylcbl0sIFNlbGVjdC5wcm90b3R5cGUsIFwiZmllbGRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5KCdtZC1tZW51Jylcbl0sIFNlbGVjdC5wcm90b3R5cGUsIFwibWVudVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcXVlcnkoJyNsYWJlbCcpXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcImxhYmVsRWxcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5QXNzaWduZWRFbGVtZW50cyh7IHNsb3Q6ICdsZWFkaW5nLWljb24nLCBmbGF0dGVuOiB0cnVlIH0pXG5dLCBTZWxlY3QucHJvdG90eXBlLCBcImxlYWRpbmdJY29uc1wiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VsZWN0LmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbmltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCAnLi4vLi4vLi4vZm9jdXMvbWQtZm9jdXMtcmluZy5qcyc7XG5pbXBvcnQgJy4uLy4uLy4uL2xhYnMvaXRlbS9pdGVtLmpzJztcbmltcG9ydCAnLi4vLi4vLi4vcmlwcGxlL3JpcHBsZS5qcyc7XG5pbXBvcnQgeyBodG1sLCBMaXRFbGVtZW50LCBub3RoaW5nIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IHByb3BlcnR5LCBxdWVyeSwgcXVlcnlBc3NpZ25lZEVsZW1lbnRzLCBxdWVyeUFzc2lnbmVkTm9kZXMsIH0gZnJvbSAnbGl0L2RlY29yYXRvcnMuanMnO1xuaW1wb3J0IHsgY2xhc3NNYXAgfSBmcm9tICdsaXQvZGlyZWN0aXZlcy9jbGFzcy1tYXAuanMnO1xuaW1wb3J0IHsgbWl4aW5EZWxlZ2F0ZXNBcmlhIH0gZnJvbSAnLi4vLi4vLi4vaW50ZXJuYWwvYXJpYS9kZWxlZ2F0ZS5qcyc7XG5pbXBvcnQgeyBTZWxlY3RPcHRpb25Db250cm9sbGVyIH0gZnJvbSAnLi9zZWxlY3RPcHRpb25Db250cm9sbGVyLmpzJztcbi8vIFNlcGFyYXRlIHZhcmlhYmxlIG5lZWRlZCBmb3IgY2xvc3VyZS5cbmNvbnN0IHNlbGVjdE9wdGlvbkJhc2VDbGFzcyA9IG1peGluRGVsZWdhdGVzQXJpYShMaXRFbGVtZW50KTtcbi8qKlxuICogQGZpcmVzIGNsb3NlLW1lbnUge0N1c3RvbUV2ZW50PHtpbml0aWF0b3I6IFNlbGVjdE9wdGlvbiwgcmVhc29uOiBSZWFzb24sIGl0ZW1QYXRoOiBTZWxlY3RPcHRpb25bXX0+fVxuICogQ2xvc2VzIHRoZSBlbmNhcHN1bGF0aW5nIG1lbnUgb24gY2xvc2FibGUgaW50ZXJhY3Rpb24uIC0tYnViYmxlcyAtLWNvbXBvc2VkXG4gKiBAZmlyZXMgcmVxdWVzdC1zZWxlY3Rpb24ge0V2ZW50fSBSZXF1ZXN0cyB0aGUgcGFyZW50IG1kLXNlbGVjdCB0byBzZWxlY3QgdGhpc1xuICogZWxlbWVudCAoYW5kIGRlc2VsZWN0IG90aGVycyBpZiBzaW5nbGUtc2VsZWN0aW9uKSB3aGVuIGBzZWxlY3RlZGAgY2hhbmdlZCB0b1xuICogYHRydWVgLiAtLWJ1YmJsZXMgLS1jb21wb3NlZFxuICogQGZpcmVzIHJlcXVlc3QtZGVzZWxlY3Rpb24ge0V2ZW50fSBSZXF1ZXN0cyB0aGUgcGFyZW50IG1kLXNlbGVjdCB0byBkZXNlbGVjdFxuICogdGhpcyBlbGVtZW50IHdoZW4gYHNlbGVjdGVkYCBjaGFuZ2VkIHRvIGBmYWxzZWAuIC0tYnViYmxlcyAtLWNvbXBvc2VkXG4gKi9cbmV4cG9ydCBjbGFzcyBTZWxlY3RPcHRpb25FbCBleHRlbmRzIHNlbGVjdE9wdGlvbkJhc2VDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlcyB0aGUgaXRlbSBhbmQgbWFrZXMgaXQgbm9uLXNlbGVjdGFibGUgYW5kIG5vbi1pbnRlcmFjdGl2ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJFQURPTkxZOiBzZWxmLWlkZW50aWZpZXMgYXMgYSBtZW51IGl0ZW0gYW5kIHNldHMgaXRzIGlkZW50aWZ5aW5nIGF0dHJpYnV0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pc01lbnVJdGVtID0gdHJ1ZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldHMgdGhlIGl0ZW0gaW4gdGhlIHNlbGVjdGVkIHZpc3VhbCBzdGF0ZSB3aGVuIGEgc3VibWVudSBpcyBvcGVuZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGb3JtIHZhbHVlIG9mIHRoZSBvcHRpb24uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnZhbHVlID0gJyc7XG4gICAgICAgIHRoaXMudHlwZSA9ICdvcHRpb24nO1xuICAgICAgICB0aGlzLnNlbGVjdE9wdGlvbkNvbnRyb2xsZXIgPSBuZXcgU2VsZWN0T3B0aW9uQ29udHJvbGxlcih0aGlzLCB7XG4gICAgICAgICAgICBnZXRIZWFkbGluZUVsZW1lbnRzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGVhZGxpbmVFbGVtZW50cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRTdXBwb3J0aW5nVGV4dEVsZW1lbnRzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3VwcG9ydGluZ1RleHRFbGVtZW50cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXREZWZhdWx0RWxlbWVudHM6ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWZhdWx0RWxlbWVudHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0SW50ZXJhY3RpdmVFbGVtZW50OiAoKSA9PiB0aGlzLmxpc3RJdGVtUm9vdCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0ZXh0IHRoYXQgaXMgc2VsZWN0YWJsZSB2aWEgdHlwZWFoZWFkLiBJZiBub3Qgc2V0LCBkZWZhdWx0cyB0byB0aGVcbiAgICAgKiBpbm5lclRleHQgb2YgdGhlIGl0ZW0gc2xvdHRlZCBpbnRvIHRoZSBgXCJoZWFkbGluZVwiYCBzbG90LlxuICAgICAqL1xuICAgIGdldCB0eXBlYWhlYWRUZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RPcHRpb25Db250cm9sbGVyLnR5cGVhaGVhZFRleHQ7XG4gICAgfVxuICAgIHNldCB0eXBlYWhlYWRUZXh0KHRleHQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RPcHRpb25Db250cm9sbGVyLnNldFR5cGVhaGVhZFRleHQodGV4dCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0ZXh0IHRoYXQgaXMgZGlzcGxheWVkIGluIHRoZSBzZWxlY3QgZmllbGQgd2hlbiBzZWxlY3RlZC4gSWYgbm90IHNldCxcbiAgICAgKiBkZWZhdWx0cyB0byB0aGUgdGV4dENvbnRlbnQgb2YgdGhlIGl0ZW0gc2xvdHRlZCBpbnRvIHRoZSBgXCJoZWFkbGluZVwiYCBzbG90LlxuICAgICAqL1xuICAgIGdldCBkaXNwbGF5VGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0T3B0aW9uQ29udHJvbGxlci5kaXNwbGF5VGV4dDtcbiAgICB9XG4gICAgc2V0IGRpc3BsYXlUZXh0KHRleHQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RPcHRpb25Db250cm9sbGVyLnNldERpc3BsYXlUZXh0KHRleHQpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbmRlckxpc3RJdGVtKGh0bWwgYFxuICAgICAgPG1kLWl0ZW0+XG4gICAgICAgIDxkaXYgc2xvdD1cImNvbnRhaW5lclwiPlxuICAgICAgICAgICR7dGhpcy5yZW5kZXJSaXBwbGUoKX0gJHt0aGlzLnJlbmRlckZvY3VzUmluZygpfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNsb3QgbmFtZT1cInN0YXJ0XCIgc2xvdD1cInN0YXJ0XCI+PC9zbG90PlxuICAgICAgICA8c2xvdCBuYW1lPVwiZW5kXCIgc2xvdD1cImVuZFwiPjwvc2xvdD5cbiAgICAgICAgJHt0aGlzLnJlbmRlckJvZHkoKX1cbiAgICAgIDwvbWQtaXRlbT5cbiAgICBgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVycyB0aGUgcm9vdCBsaXN0IGl0ZW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUgY2hpbGQgY29udGVudCBvZiB0aGUgbGlzdCBpdGVtLlxuICAgICAqL1xuICAgIHJlbmRlckxpc3RJdGVtKGNvbnRlbnQpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPGxpXG4gICAgICAgIGlkPVwiaXRlbVwiXG4gICAgICAgIHRhYmluZGV4PSR7dGhpcy5kaXNhYmxlZCA/IC0xIDogMH1cbiAgICAgICAgcm9sZT0ke3RoaXMuc2VsZWN0T3B0aW9uQ29udHJvbGxlci5yb2xlfVxuICAgICAgICBhcmlhLWxhYmVsPSR7dGhpcy5hcmlhTGFiZWwgfHwgbm90aGluZ31cbiAgICAgICAgYXJpYS1zZWxlY3RlZD0ke3RoaXMuYXJpYVNlbGVjdGVkIHx8IG5vdGhpbmd9XG4gICAgICAgIGFyaWEtY2hlY2tlZD0ke3RoaXMuYXJpYUNoZWNrZWQgfHwgbm90aGluZ31cbiAgICAgICAgYXJpYS1leHBhbmRlZD0ke3RoaXMuYXJpYUV4cGFuZGVkIHx8IG5vdGhpbmd9XG4gICAgICAgIGFyaWEtaGFzcG9wdXA9JHt0aGlzLmFyaWFIYXNQb3B1cCB8fCBub3RoaW5nfVxuICAgICAgICBjbGFzcz1cImxpc3QtaXRlbSAke2NsYXNzTWFwKHRoaXMuZ2V0UmVuZGVyQ2xhc3NlcygpKX1cIlxuICAgICAgICBAY2xpY2s9JHt0aGlzLnNlbGVjdE9wdGlvbkNvbnRyb2xsZXIub25DbGlja31cbiAgICAgICAgQGtleWRvd249JHt0aGlzLnNlbGVjdE9wdGlvbkNvbnRyb2xsZXIub25LZXlkb3dufVxuICAgICAgICA+JHtjb250ZW50fTwvbGlcbiAgICAgID5cbiAgICBgO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHJlbmRlcmluZyBvZiB0aGUgcmlwcGxlIGVsZW1lbnQuXG4gICAgICovXG4gICAgcmVuZGVyUmlwcGxlKCkge1xuICAgICAgICByZXR1cm4gaHRtbCBgIDxtZC1yaXBwbGVcbiAgICAgIHBhcnQ9XCJyaXBwbGVcIlxuICAgICAgZm9yPVwiaXRlbVwiXG4gICAgICA/ZGlzYWJsZWQ9JHt0aGlzLmRpc2FibGVkfT48L21kLXJpcHBsZT5gO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHJlbmRlcmluZyBvZiB0aGUgZm9jdXMgcmluZy5cbiAgICAgKi9cbiAgICByZW5kZXJGb2N1c1JpbmcoKSB7XG4gICAgICAgIHJldHVybiBodG1sIGAgPG1kLWZvY3VzLXJpbmdcbiAgICAgIHBhcnQ9XCJmb2N1cy1yaW5nXCJcbiAgICAgIGZvcj1cIml0ZW1cIlxuICAgICAgaW53YXJkPjwvbWQtZm9jdXMtcmluZz5gO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGFzc2VzIGFwcGxpZWQgdG8gdGhlIGxpc3QgaXRlbSByb290LlxuICAgICAqL1xuICAgIGdldFJlbmRlckNsYXNzZXMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAnZGlzYWJsZWQnOiB0aGlzLmRpc2FibGVkLFxuICAgICAgICAgICAgJ3NlbGVjdGVkJzogdGhpcy5zZWxlY3RlZCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlcyByZW5kZXJpbmcgdGhlIGhlYWRsaW5lIGFuZCBzdXBwb3J0aW5nIHRleHQuXG4gICAgICovXG4gICAgcmVuZGVyQm9keSgpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPHNsb3Q+PC9zbG90PlxuICAgICAgPHNsb3QgbmFtZT1cIm92ZXJsaW5lXCIgc2xvdD1cIm92ZXJsaW5lXCI+PC9zbG90PlxuICAgICAgPHNsb3QgbmFtZT1cImhlYWRsaW5lXCIgc2xvdD1cImhlYWRsaW5lXCI+PC9zbG90PlxuICAgICAgPHNsb3QgbmFtZT1cInN1cHBvcnRpbmctdGV4dFwiIHNsb3Q9XCJzdXBwb3J0aW5nLXRleHRcIj48L3Nsb3Q+XG4gICAgICA8c2xvdFxuICAgICAgICBuYW1lPVwidHJhaWxpbmctc3VwcG9ydGluZy10ZXh0XCJcbiAgICAgICAgc2xvdD1cInRyYWlsaW5nLXN1cHBvcnRpbmctdGV4dFwiPjwvc2xvdD5cbiAgICBgO1xuICAgIH1cbiAgICBmb2N1cygpIHtcbiAgICAgICAgLy8gVE9ETyhiLzMwMDMzNDUwOSk6IG5lZWRlZCBmb3Igc29tZSBjYXNlcyB3aGVyZSBkZWxlZ2F0ZXNGb2N1cyBkb2Vzbid0XG4gICAgICAgIC8vIHdvcmsgcHJvZ3JhbW1hdGljYWxseSBsaWtlIGluIEZGIGFuZCBzZWxlY3Qtb3B0aW9uXG4gICAgICAgIHRoaXMubGlzdEl0ZW1Sb290Py5mb2N1cygpO1xuICAgIH1cbn1cbi8qKiBAbm9jb2xsYXBzZSAqL1xuU2VsZWN0T3B0aW9uRWwuc2hhZG93Um9vdE9wdGlvbnMgPSB7XG4gICAgLi4uTGl0RWxlbWVudC5zaGFkb3dSb290T3B0aW9ucyxcbiAgICBkZWxlZ2F0ZXNGb2N1czogdHJ1ZSxcbn07XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IEJvb2xlYW4sIHJlZmxlY3Q6IHRydWUgfSlcbl0sIFNlbGVjdE9wdGlvbkVsLnByb3RvdHlwZSwgXCJkaXNhYmxlZFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdtZC1tZW51LWl0ZW0nLCByZWZsZWN0OiB0cnVlIH0pXG5dLCBTZWxlY3RPcHRpb25FbC5wcm90b3R5cGUsIFwiaXNNZW51SXRlbVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuIH0pXG5dLCBTZWxlY3RPcHRpb25FbC5wcm90b3R5cGUsIFwic2VsZWN0ZWRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KClcbl0sIFNlbGVjdE9wdGlvbkVsLnByb3RvdHlwZSwgXCJ2YWx1ZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcXVlcnkoJy5saXN0LWl0ZW0nKVxuXSwgU2VsZWN0T3B0aW9uRWwucHJvdG90eXBlLCBcImxpc3RJdGVtUm9vdFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcXVlcnlBc3NpZ25lZEVsZW1lbnRzKHsgc2xvdDogJ2hlYWRsaW5lJyB9KVxuXSwgU2VsZWN0T3B0aW9uRWwucHJvdG90eXBlLCBcImhlYWRsaW5lRWxlbWVudHNcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5QXNzaWduZWRFbGVtZW50cyh7IHNsb3Q6ICdzdXBwb3J0aW5nLXRleHQnIH0pXG5dLCBTZWxlY3RPcHRpb25FbC5wcm90b3R5cGUsIFwic3VwcG9ydGluZ1RleHRFbGVtZW50c1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcXVlcnlBc3NpZ25lZE5vZGVzKHsgc2xvdDogJycgfSlcbl0sIFNlbGVjdE9wdGlvbkVsLnByb3RvdHlwZSwgXCJkZWZhdWx0RWxlbWVudHNcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgYXR0cmlidXRlOiAndHlwZWFoZWFkLXRleHQnIH0pXG5dLCBTZWxlY3RPcHRpb25FbC5wcm90b3R5cGUsIFwidHlwZWFoZWFkVGV4dFwiLCBudWxsKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgYXR0cmlidXRlOiAnZGlzcGxheS10ZXh0JyB9KVxuXSwgU2VsZWN0T3B0aW9uRWwucHJvdG90eXBlLCBcImRpc3BsYXlUZXh0XCIsIG51bGwpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VsZWN0LW9wdGlvbi5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMyBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBNZW51SXRlbUNvbnRyb2xsZXIsIH0gZnJvbSAnLi4vLi4vLi4vbWVudS9pbnRlcm5hbC9jb250cm9sbGVycy9tZW51SXRlbUNvbnRyb2xsZXIuanMnO1xuLyoqXG4gKiBDcmVhdGVzIGFuIGV2ZW50IGZpcmVkIGJ5IGEgU2VsZWN0T3B0aW9uIHRvIHJlcXVlc3Qgc2VsZWN0aW9uIGZyb20gbWQtc2VsZWN0LlxuICogVHlwaWNhbGx5IGZpcmVkIGFmdGVyIGBzZWxlY3RlZGAgY2hhbmdlcyBmcm9tIGBmYWxzZWAgdG8gYHRydWVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVxdWVzdFNlbGVjdGlvbkV2ZW50KCkge1xuICAgIHJldHVybiBuZXcgRXZlbnQoJ3JlcXVlc3Qtc2VsZWN0aW9uJywge1xuICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICBjb21wb3NlZDogdHJ1ZSxcbiAgICB9KTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhbiBldmVudCBmaXJlZCBieSBhIFNlbGVjdE9wdGlvbiB0byByZXF1ZXN0IGRlc2VsZWN0aW9uIGZyb21cbiAqIG1kLXNlbGVjdC4gVHlwaWNhbGx5IGZpcmVkIGFmdGVyIGBzZWxlY3RlZGAgY2hhbmdlcyBmcm9tIGB0cnVlYCB0byBgZmFsc2VgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVxdWVzdERlc2VsZWN0aW9uRXZlbnQoKSB7XG4gICAgcmV0dXJuIG5ldyBFdmVudCgncmVxdWVzdC1kZXNlbGVjdGlvbicsIHtcbiAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgY29tcG9zZWQ6IHRydWUsXG4gICAgfSk7XG59XG4vKipcbiAqIEEgY29udHJvbGxlciB0aGF0IHByb3ZpZGVzIG1vc3QgZnVuY3Rpb25hbGl0eSBhbmQgbWQtc2VsZWN0IGNvbXBhdGliaWxpdHkgZm9yXG4gKiBhbiBlbGVtZW50IHRoYXQgaW1wbGVtZW50cyB0aGUgU2VsZWN0T3B0aW9uIGludGVyZmFjZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlbGVjdE9wdGlvbkNvbnRyb2xsZXIge1xuICAgIC8qKlxuICAgICAqIFRoZSByZWNvbW1lbmRlZCByb2xlIG9mIHRoZSBzZWxlY3Qgb3B0aW9uLlxuICAgICAqL1xuICAgIGdldCByb2xlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tZW51SXRlbUNvbnRyb2xsZXIucm9sZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRleHQgdGhhdCBpcyBzZWxlY3RhYmxlIHZpYSB0eXBlYWhlYWQuIElmIG5vdCBzZXQsIGRlZmF1bHRzIHRvIHRoZVxuICAgICAqIGlubmVyVGV4dCBvZiB0aGUgaXRlbSBzbG90dGVkIGludG8gdGhlIGBcImhlYWRsaW5lXCJgIHNsb3QsIGFuZCBpZiB0aGVyZSBhcmVcbiAgICAgKiBubyBzbG90dGVkIGVsZW1lbnRzIGludG8gaGVhZGxpbmUsIHRoZW4gaXQgY2hlY2tzIHRoZSBfZGVmYXVsdF8gc2xvdCwgYW5kXG4gICAgICogdGhlbiB0aGUgYFwic3VwcG9ydGluZy10ZXh0XCJgIHNsb3QgaWYgbm90aGluZyBpcyBpbiBfZGVmYXVsdF8uXG4gICAgICovXG4gICAgZ2V0IHR5cGVhaGVhZFRleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lbnVJdGVtQ29udHJvbGxlci50eXBlYWhlYWRUZXh0O1xuICAgIH1cbiAgICBzZXRUeXBlYWhlYWRUZXh0KHRleHQpIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbUNvbnRyb2xsZXIuc2V0VHlwZWFoZWFkVGV4dCh0ZXh0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRleHQgdGhhdCBpcyBkaXNwbGF5ZWQgaW4gdGhlIHNlbGVjdCBmaWVsZCB3aGVuIHNlbGVjdGVkLiBJZiBub3Qgc2V0LFxuICAgICAqIGRlZmF1bHRzIHRvIHRoZSB0ZXh0Q29udGVudCBvZiB0aGUgaXRlbSBzbG90dGVkIGludG8gdGhlIGBcImhlYWRsaW5lXCJgIHNsb3QsXG4gICAgICogYW5kIGlmIHRoZXJlIGFyZSBubyBzbG90dGVkIGVsZW1lbnRzIGludG8gaGVhZGxpbmUsIHRoZW4gaXQgY2hlY2tzIHRoZVxuICAgICAqIF9kZWZhdWx0XyBzbG90LCBhbmQgdGhlbiB0aGUgYFwic3VwcG9ydGluZy10ZXh0XCJgIHNsb3QgaWYgbm90aGluZyBpcyBpblxuICAgICAqIF9kZWZhdWx0Xy5cbiAgICAgKi9cbiAgICBnZXQgZGlzcGxheVRleHQoKSB7XG4gICAgICAgIGlmICh0aGlzLmludGVybmFsRGlzcGxheVRleHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmludGVybmFsRGlzcGxheVRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMubWVudUl0ZW1Db250cm9sbGVyLnR5cGVhaGVhZFRleHQ7XG4gICAgfVxuICAgIHNldERpc3BsYXlUZXh0KHRleHQpIHtcbiAgICAgICAgdGhpcy5pbnRlcm5hbERpc3BsYXlUZXh0ID0gdGV4dDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGhvc3QgVGhlIFNlbGVjdE9wdGlvbiBpbiB3aGljaCB0byBhdHRhY2ggdGhpcyBjb250cm9sbGVyIHRvLlxuICAgICAqIEBwYXJhbSBjb25maWcgVGhlIG9iamVjdCB0aGF0IGNvbmZpZ3VyZXMgdGhpcyBjb250cm9sbGVyJ3MgYmVoYXZpb3IuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoaG9zdCwgY29uZmlnKSB7XG4gICAgICAgIHRoaXMuaG9zdCA9IGhvc3Q7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxEaXNwbGF5VGV4dCA9IG51bGw7XG4gICAgICAgIHRoaXMuZmlyc3RVcGRhdGUgPSB0cnVlO1xuICAgICAgICAvKipcbiAgICAgICAgICogQmluZCB0aGlzIGNsaWNrIGxpc3RlbmVyIHRvIHRoZSBpbnRlcmFjdGl2ZSBlbGVtZW50LiBIYW5kbGVzIGNsb3NpbmcgdGhlXG4gICAgICAgICAqIG1lbnUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uQ2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm1lbnVJdGVtQ29udHJvbGxlci5vbkNsaWNrKCk7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBCaW5kIHRoaXMgY2xpY2sgbGlzdGVuZXIgdG8gdGhlIGludGVyYWN0aXZlIGVsZW1lbnQuIEhhbmRsZXMgY2xvc2luZyB0aGVcbiAgICAgICAgICogbWVudS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub25LZXlkb3duID0gKGUpID0+IHtcbiAgICAgICAgICAgIHRoaXMubWVudUl0ZW1Db250cm9sbGVyLm9uS2V5ZG93bihlKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5sYXN0U2VsZWN0ZWQgPSB0aGlzLmhvc3Quc2VsZWN0ZWQ7XG4gICAgICAgIHRoaXMubWVudUl0ZW1Db250cm9sbGVyID0gbmV3IE1lbnVJdGVtQ29udHJvbGxlcihob3N0LCBjb25maWcpO1xuICAgICAgICBob3N0LmFkZENvbnRyb2xsZXIodGhpcyk7XG4gICAgfVxuICAgIGhvc3RVcGRhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLmxhc3RTZWxlY3RlZCAhPT0gdGhpcy5ob3N0LnNlbGVjdGVkKSB7XG4gICAgICAgICAgICB0aGlzLmhvc3QuYXJpYVNlbGVjdGVkID0gdGhpcy5ob3N0LnNlbGVjdGVkID8gJ3RydWUnIDogJ2ZhbHNlJztcbiAgICAgICAgfVxuICAgIH1cbiAgICBob3N0VXBkYXRlZCgpIHtcbiAgICAgICAgLy8gRG8gbm90IGRpc3BhdGNoIGV2ZW50IG9uIGZpcnN0IHVwZGF0ZSAvIGJvb3QtdXAuXG4gICAgICAgIGlmICh0aGlzLmxhc3RTZWxlY3RlZCAhPT0gdGhpcy5ob3N0LnNlbGVjdGVkICYmICF0aGlzLmZpcnN0VXBkYXRlKSB7XG4gICAgICAgICAgICAvLyBUaGlzIHNlY3Rpb24gaXMgcmVhbGx5IHVzZWZ1bCBmb3Igd2hlbiB0aGUgdXNlciBzZXRzIHNlbGVjdGVkIG9uIHRoZVxuICAgICAgICAgICAgLy8gb3B0aW9uIHByb2dyYW1tYXRpY2FsbHkuIE1vc3Qgb3RoZXIgY2FzZXMgKGNsaWNrIGFuZCBrZXlib2FyZCkgYXJlXG4gICAgICAgICAgICAvLyBoYW5kbGVkIGJ5IG1kLXNlbGVjdCBiZWNhdXNlIGl0IG5lZWRzIHRvIGNvb3JkaW5hdGUgdGhlXG4gICAgICAgICAgICAvLyBzaW5nbGUtc2VsZWN0aW9uIGJlaGF2aW9yLlxuICAgICAgICAgICAgaWYgKHRoaXMuaG9zdC5zZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaG9zdC5kaXNwYXRjaEV2ZW50KGNyZWF0ZVJlcXVlc3RTZWxlY3Rpb25FdmVudCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaG9zdC5kaXNwYXRjaEV2ZW50KGNyZWF0ZVJlcXVlc3REZXNlbGVjdGlvbkV2ZW50KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkID0gdGhpcy5ob3N0LnNlbGVjdGVkO1xuICAgICAgICB0aGlzLmZpcnN0VXBkYXRlID0gZmFsc2U7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VsZWN0T3B0aW9uQ29udHJvbGxlci5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyNCBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG4vLyBHZW5lcmF0ZWQgc3R5bGVzaGVldCBmb3IgLi9zZWxlY3QvaW50ZXJuYWwvc2hhcmVkLXN0eWxlcy5jc3MuXG5pbXBvcnQgeyBjc3MgfSBmcm9tICdsaXQnO1xuZXhwb3J0IGNvbnN0IHN0eWxlcyA9IGNzcyBgOmhvc3R7Y29sb3I6dW5zZXQ7bWluLXdpZHRoOjIxMHB4O2Rpc3BsYXk6ZmxleH0uZmllbGR7Y3Vyc29yOmRlZmF1bHQ7b3V0bGluZTpub25lfS5zZWxlY3R7cG9zaXRpb246cmVsYXRpdmU7ZmxleC1kaXJlY3Rpb246Y29sdW1ufS5pY29uLnRyYWlsaW5nIHN2ZywuaWNvbiA6OnNsb3R0ZWQoKil7ZmlsbDpjdXJyZW50Q29sb3J9Lmljb24gOjpzbG90dGVkKCope3dpZHRoOmluaGVyaXQ7aGVpZ2h0OmluaGVyaXQ7Zm9udC1zaXplOmluaGVyaXR9Lmljb24gc2xvdHtkaXNwbGF5OmZsZXg7aGVpZ2h0OjEwMCU7d2lkdGg6MTAwJTthbGlnbi1pdGVtczpjZW50ZXI7anVzdGlmeS1jb250ZW50OmNlbnRlcn0uaWNvbi50cmFpbGluZyA6aXMoLnVwLC5kb3duKXtvcGFjaXR5OjA7dHJhbnNpdGlvbjpvcGFjaXR5IDc1bXMgbGluZWFyIDc1bXN9LnNlbGVjdDpub3QoLm9wZW4pIC5kb3duLC5zZWxlY3Qub3BlbiAudXB7b3BhY2l0eToxfS5maWVsZCwuc2VsZWN0LG1kLW1lbnV7bWluLXdpZHRoOmluaGVyaXQ7d2lkdGg6aW5oZXJpdDttYXgtd2lkdGg6aW5oZXJpdDtkaXNwbGF5OmZsZXh9bWQtbWVudXttaW4td2lkdGg6dmFyKC0tX19tZW51LW1pbi13aWR0aCk7bWF4LXdpZHRoOnZhcigtLV9fbWVudS1tYXgtd2lkdGgsIGluaGVyaXQpfS5tZW51LXdyYXBwZXJ7d2lkdGg6MHB4O2hlaWdodDowcHg7bWF4LXdpZHRoOmluaGVyaXR9bWQtbWVudSA6OnNsb3R0ZWQoOm5vdFtkaXNhYmxlZF0pe2N1cnNvcjpwb2ludGVyfS5maWVsZCwuc2VsZWN0e3dpZHRoOjEwMCV9Omhvc3R7ZGlzcGxheTppbmxpbmUtZmxleH06aG9zdChbZGlzYWJsZWRdKXtwb2ludGVyLWV2ZW50czpub25lfVxuYDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNoYXJlZC1zdHlsZXMuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjMgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuLyoqXG4gKiBHaXZlbiBhIGxpc3Qgb2Ygc2VsZWN0IG9wdGlvbnMsIHRoaXMgZnVuY3Rpb24gd2lsbCByZXR1cm4gYW4gYXJyYXkgb2ZcbiAqIFNlbGVjdE9wdGlvblJlY29yZHMgdGhhdCBhcmUgc2VsZWN0ZWQuXG4gKlxuICogQHJldHVybiBBbiBhcnJheSBvZiBTZWxlY3RPcHRpb25SZWNvcmRzIGRlc2NyaWJpbmcgdGhlIG9wdGlvbnMgdGhhdCBhcmVcbiAqIHNlbGVjdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VsZWN0ZWRJdGVtcyhpdGVtcykge1xuICAgIGNvbnN0IHNlbGVjdGVkSXRlbVJlY29yZHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1tpXTtcbiAgICAgICAgaWYgKGl0ZW0uc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIHNlbGVjdGVkSXRlbVJlY29yZHMucHVzaChbaXRlbSwgaV0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzZWxlY3RlZEl0ZW1SZWNvcmRzO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2hhcmVkLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8vIEdlbmVyYXRlZCBzdHlsZXNoZWV0IGZvciAuL3RleHRmaWVsZC9pbnRlcm5hbC9maWxsZWQtc3R5bGVzLmNzcy5cbmltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5leHBvcnQgY29uc3Qgc3R5bGVzID0gY3NzIGA6aG9zdHstLV9hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fYWN0aXZlLWluZGljYXRvci1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0LCAxcHgpOy0tX2NhcmV0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1jYXJldC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV9jb250YWluZXItY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWNvbnRhaW5lci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXN1cmZhY2UtY29udGFpbmVyLWhpZ2hlc3QsICNlNmUwZTkpKTstLV9kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Rpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0OiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCwgMXB4KTstLV9kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLW9wYWNpdHk6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWRpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3Itb3BhY2l0eSwgMC4zOCk7LS1fZGlzYWJsZWQtY29udGFpbmVyLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1kaXNhYmxlZC1jb250YWluZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fZGlzYWJsZWQtY29udGFpbmVyLW9wYWNpdHk6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWRpc2FibGVkLWNvbnRhaW5lci1vcGFjaXR5LCAwLjA0KTstLV9kaXNhYmxlZC1pbnB1dC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1kaXNhYmxlZC1pbnB1dC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Rpc2FibGVkLWlucHV0LXRleHQtb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZGlzYWJsZWQtaW5wdXQtdGV4dC1vcGFjaXR5LCAwLjM4KTstLV9kaXNhYmxlZC1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1kaXNhYmxlZC1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Rpc2FibGVkLWxhYmVsLXRleHQtb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZGlzYWJsZWQtbGFiZWwtdGV4dC1vcGFjaXR5LCAwLjM4KTstLV9kaXNhYmxlZC1sZWFkaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWRpc2FibGVkLWxlYWRpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9kaXNhYmxlZC1sZWFkaW5nLWljb24tb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZGlzYWJsZWQtbGVhZGluZy1pY29uLW9wYWNpdHksIDAuMzgpOy0tX2Rpc2FibGVkLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Rpc2FibGVkLXN1cHBvcnRpbmctdGV4dC1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1kaXNhYmxlZC1zdXBwb3J0aW5nLXRleHQtb3BhY2l0eSwgMC4zOCk7LS1fZGlzYWJsZWQtdHJhaWxpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZGlzYWJsZWQtdHJhaWxpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9kaXNhYmxlZC10cmFpbGluZy1pY29uLW9wYWNpdHk6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWRpc2FibGVkLXRyYWlsaW5nLWljb24tb3BhY2l0eSwgMC4zOCk7LS1fZXJyb3ItYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZXJyb3ItYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLWVycm9yLCAjYjMyNjFlKSk7LS1fZXJyb3ItZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZXJyb3ItZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLWVycm9yLCAjYjMyNjFlKSk7LS1fZXJyb3ItZm9jdXMtY2FyZXQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLWZvY3VzLWNhcmV0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItZXJyb3IsICNiMzI2MWUpKTstLV9lcnJvci1mb2N1cy1pbnB1dC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1lcnJvci1mb2N1cy1pbnB1dC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Vycm9yLWZvY3VzLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLWZvY3VzLWxhYmVsLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX2Vycm9yLWZvY3VzLWxlYWRpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZXJyb3ItZm9jdXMtbGVhZGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fZXJyb3ItZm9jdXMtc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1lcnJvci1mb2N1cy1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX2Vycm9yLWZvY3VzLXRyYWlsaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLWZvY3VzLXRyYWlsaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1lcnJvciwgI2IzMjYxZSkpOy0tX2Vycm9yLWhvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLWhvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1lcnJvci1jb250YWluZXIsICM0MTBlMGIpKTstLV9lcnJvci1ob3Zlci1pbnB1dC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1lcnJvci1ob3Zlci1pbnB1dC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZSwgIzFkMWIyMCkpOy0tX2Vycm9yLWhvdmVyLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLWhvdmVyLWxhYmVsLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1lcnJvci1jb250YWluZXIsICM0MTBlMGIpKTstLV9lcnJvci1ob3Zlci1sZWFkaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLWhvdmVyLWxlYWRpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2Vycm9yLWhvdmVyLXN0YXRlLWxheWVyLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5OiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5LCAwLjA4KTstLV9lcnJvci1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLWhvdmVyLXN1cHBvcnRpbmctdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLWVycm9yLCAjYjMyNjFlKSk7LS1fZXJyb3ItaG92ZXItdHJhaWxpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZXJyb3ItaG92ZXItdHJhaWxpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLWVycm9yLWNvbnRhaW5lciwgIzQxMGUwYikpOy0tX2Vycm9yLWlucHV0LXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLWlucHV0LXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1fZXJyb3ItbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZXJyb3ItbGFiZWwtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLWVycm9yLCAjYjMyNjFlKSk7LS1fZXJyb3ItbGVhZGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1lcnJvci1sZWFkaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWVycm9yLXN1cHBvcnRpbmctdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLWVycm9yLCAjYjMyNjFlKSk7LS1fZXJyb3ItdHJhaWxpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZXJyb3ItdHJhaWxpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLWVycm9yLCAjYjMyNjFlKSk7LS1fZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV9mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZm9jdXMtYWN0aXZlLWluZGljYXRvci1oZWlnaHQsIDNweCk7LS1fZm9jdXMtaW5wdXQtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZm9jdXMtaW5wdXQtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9mb2N1cy1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1mb2N1cy1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3ItcHJpbWFyeSwgIzY3NTBhNCkpOy0tX2ZvY3VzLWxlYWRpbmctaWNvbi1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtZm9jdXMtbGVhZGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1fZm9jdXMtc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1mb2N1cy1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9mb2N1cy10cmFpbGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1mb2N1cy10cmFpbGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1faG92ZXItYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaG92ZXItYWN0aXZlLWluZGljYXRvci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaG92ZXItYWN0aXZlLWluZGljYXRvci1oZWlnaHQsIDFweCk7LS1faG92ZXItaW5wdXQtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaG92ZXItaW5wdXQtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9ob3Zlci1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1ob3Zlci1sYWJlbC10ZXh0LWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1faG92ZXItbGVhZGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1ob3Zlci1sZWFkaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9ob3Zlci1zdGF0ZS1sYXllci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaG92ZXItc3RhdGUtbGF5ZXItY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLCAjMWQxYjIwKSk7LS1faG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eSwgMC4wOCk7LS1faG92ZXItc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9ob3Zlci10cmFpbGluZy1pY29uLWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1ob3Zlci10cmFpbGluZy1pY29uLWNvbG9yLCB2YXIoLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZS12YXJpYW50LCAjNDk0NTRmKSk7LS1faW5wdXQtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaW5wdXQtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UsICMxZDFiMjApKTstLV9pbnB1dC10ZXh0LWZvbnQ6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWlucHV0LXRleHQtZm9udCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLWZvbnQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS1wbGFpbiwgUm9ib3RvKSkpOy0tX2lucHV0LXRleHQtbGluZS1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWlucHV0LXRleHQtbGluZS1oZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1saW5lLWhlaWdodCwgMS41cmVtKSk7LS1faW5wdXQtdGV4dC1wbGFjZWhvbGRlci1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaW5wdXQtdGV4dC1wbGFjZWhvbGRlci1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2lucHV0LXRleHQtcHJlZml4LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1pbnB1dC10ZXh0LXByZWZpeC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2lucHV0LXRleHQtc2l6ZTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaW5wdXQtdGV4dC1zaXplLCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2Utc2l6ZSwgMXJlbSkpOy0tX2lucHV0LXRleHQtc3VmZml4LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1pbnB1dC10ZXh0LXN1ZmZpeC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2lucHV0LXRleHQtd2VpZ2h0OiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1pbnB1dC10ZXh0LXdlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLXdlaWdodCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXdlaWdodC1yZWd1bGFyLCA0MDApKSk7LS1fbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtbGFiZWwtdGV4dC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2xhYmVsLXRleHQtZm9udDogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtbGFiZWwtdGV4dC1mb250LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2UtZm9udCwgdmFyKC0tbWQtcmVmLXR5cGVmYWNlLXBsYWluLCBSb2JvdG8pKSk7LS1fbGFiZWwtdGV4dC1saW5lLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtbGFiZWwtdGV4dC1saW5lLWhlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LWxhcmdlLWxpbmUtaGVpZ2h0LCAxLjVyZW0pKTstLV9sYWJlbC10ZXh0LXBvcHVsYXRlZC1saW5lLWhlaWdodDogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtbGFiZWwtdGV4dC1wb3B1bGF0ZWQtbGluZS1oZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1zbWFsbC1saW5lLWhlaWdodCwgMXJlbSkpOy0tX2xhYmVsLXRleHQtcG9wdWxhdGVkLXNpemU6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWxhYmVsLXRleHQtcG9wdWxhdGVkLXNpemUsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1zbWFsbC1zaXplLCAwLjc1cmVtKSk7LS1fbGFiZWwtdGV4dC1zaXplOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1sYWJlbC10ZXh0LXNpemUsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1sYXJnZS1zaXplLCAxcmVtKSk7LS1fbGFiZWwtdGV4dC13ZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWxhYmVsLXRleHQtd2VpZ2h0LCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktbGFyZ2Utd2VpZ2h0LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2Utd2VpZ2h0LXJlZ3VsYXIsIDQwMCkpKTstLV9sZWFkaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWxlYWRpbmctaWNvbi1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLW9uLXN1cmZhY2UtdmFyaWFudCwgIzQ5NDU0ZikpOy0tX2xlYWRpbmctaWNvbi1zaXplOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1sZWFkaW5nLWljb24tc2l6ZSwgMjRweCk7LS1fc3VwcG9ydGluZy10ZXh0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1zdXBwb3J0aW5nLXRleHQtY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV9zdXBwb3J0aW5nLXRleHQtZm9udDogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtc3VwcG9ydGluZy10ZXh0LWZvbnQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1zbWFsbC1mb250LCB2YXIoLS1tZC1yZWYtdHlwZWZhY2UtcGxhaW4sIFJvYm90bykpKTstLV9zdXBwb3J0aW5nLXRleHQtbGluZS1oZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLXN1cHBvcnRpbmctdGV4dC1saW5lLWhlaWdodCwgdmFyKC0tbWQtc3lzLXR5cGVzY2FsZS1ib2R5LXNtYWxsLWxpbmUtaGVpZ2h0LCAxcmVtKSk7LS1fc3VwcG9ydGluZy10ZXh0LXNpemU6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLXN1cHBvcnRpbmctdGV4dC1zaXplLCB2YXIoLS1tZC1zeXMtdHlwZXNjYWxlLWJvZHktc21hbGwtc2l6ZSwgMC43NXJlbSkpOy0tX3N1cHBvcnRpbmctdGV4dC13ZWlnaHQ6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLXN1cHBvcnRpbmctdGV4dC13ZWlnaHQsIHZhcigtLW1kLXN5cy10eXBlc2NhbGUtYm9keS1zbWFsbC13ZWlnaHQsIHZhcigtLW1kLXJlZi10eXBlZmFjZS13ZWlnaHQtcmVndWxhciwgNDAwKSkpOy0tX3RyYWlsaW5nLWljb24tY29sb3I6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLXRyYWlsaW5nLWljb24tY29sb3IsIHZhcigtLW1kLXN5cy1jb2xvci1vbi1zdXJmYWNlLXZhcmlhbnQsICM0OTQ1NGYpKTstLV90cmFpbGluZy1pY29uLXNpemU6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLXRyYWlsaW5nLWljb24tc2l6ZSwgMjRweCk7LS1fY29udGFpbmVyLXNoYXBlLXN0YXJ0LXN0YXJ0OiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUtc3RhcnQtc3RhcnQsIHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZSwgdmFyKC0tbWQtc3lzLXNoYXBlLWNvcm5lci1leHRyYS1zbWFsbCwgNHB4KSkpOy0tX2NvbnRhaW5lci1zaGFwZS1zdGFydC1lbmQ6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZS1zdGFydC1lbmQsIHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWNvbnRhaW5lci1zaGFwZSwgdmFyKC0tbWQtc3lzLXNoYXBlLWNvcm5lci1leHRyYS1zbWFsbCwgNHB4KSkpOy0tX2NvbnRhaW5lci1zaGFwZS1lbmQtZW5kOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUtZW5kLWVuZCwgdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtY29udGFpbmVyLXNoYXBlLCB2YXIoLS1tZC1zeXMtc2hhcGUtY29ybmVyLW5vbmUsIDBweCkpKTstLV9jb250YWluZXItc2hhcGUtZW5kLXN0YXJ0OiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUtZW5kLXN0YXJ0LCB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1jb250YWluZXItc2hhcGUsIHZhcigtLW1kLXN5cy1zaGFwZS1jb3JuZXItbm9uZSwgMHB4KSkpOy0tX2ljb24taW5wdXQtc3BhY2U6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWljb24taW5wdXQtc3BhY2UsIDE2cHgpOy0tX2xlYWRpbmctc3BhY2U6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLWxlYWRpbmctc3BhY2UsIDE2cHgpOy0tX3RyYWlsaW5nLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC10cmFpbGluZy1zcGFjZSwgMTZweCk7LS1fdG9wLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC10b3Atc3BhY2UsIDE2cHgpOy0tX2JvdHRvbS1zcGFjZTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtYm90dG9tLXNwYWNlLCAxNnB4KTstLV9pbnB1dC10ZXh0LXByZWZpeC10cmFpbGluZy1zcGFjZTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaW5wdXQtdGV4dC1wcmVmaXgtdHJhaWxpbmctc3BhY2UsIDJweCk7LS1faW5wdXQtdGV4dC1zdWZmaXgtbGVhZGluZy1zcGFjZTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtaW5wdXQtdGV4dC1zdWZmaXgtbGVhZGluZy1zcGFjZSwgMnB4KTstLV93aXRoLWxhYmVsLXRvcC1zcGFjZTogdmFyKC0tbWQtZmlsbGVkLXRleHQtZmllbGQtd2l0aC1sYWJlbC10b3Atc3BhY2UsIDhweCk7LS1fd2l0aC1sYWJlbC1ib3R0b20tc3BhY2U6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLXdpdGgtbGFiZWwtYm90dG9tLXNwYWNlLCA4cHgpOy0tX2ZvY3VzLWNhcmV0LWNvbG9yOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC1mb2N1cy1jYXJldC1jb2xvciwgdmFyKC0tbWQtc3lzLWNvbG9yLXByaW1hcnksICM2NzUwYTQpKTstLV93aXRoLWxlYWRpbmctaWNvbi1sZWFkaW5nLXNwYWNlOiB2YXIoLS1tZC1maWxsZWQtdGV4dC1maWVsZC13aXRoLWxlYWRpbmctaWNvbi1sZWFkaW5nLXNwYWNlLCAxMnB4KTstLV93aXRoLXRyYWlsaW5nLWljb24tdHJhaWxpbmctc3BhY2U6IHZhcigtLW1kLWZpbGxlZC10ZXh0LWZpZWxkLXdpdGgtdHJhaWxpbmctaWNvbi10cmFpbGluZy1zcGFjZSwgMTJweCk7LS1tZC1maWxsZWQtZmllbGQtYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tX2FjdGl2ZS1pbmRpY2F0b3ItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0OiB2YXIoLS1fYWN0aXZlLWluZGljYXRvci1oZWlnaHQpOy0tbWQtZmlsbGVkLWZpZWxkLWJvdHRvbS1zcGFjZTogdmFyKC0tX2JvdHRvbS1zcGFjZSk7LS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLWNvbG9yOiB2YXIoLS1fY29udGFpbmVyLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1jb250YWluZXItc2hhcGUtZW5kLWVuZDogdmFyKC0tX2NvbnRhaW5lci1zaGFwZS1lbmQtZW5kKTstLW1kLWZpbGxlZC1maWVsZC1jb250YWluZXItc2hhcGUtZW5kLXN0YXJ0OiB2YXIoLS1fY29udGFpbmVyLXNoYXBlLWVuZC1zdGFydCk7LS1tZC1maWxsZWQtZmllbGQtY29udGFpbmVyLXNoYXBlLXN0YXJ0LWVuZDogdmFyKC0tX2NvbnRhaW5lci1zaGFwZS1zdGFydC1lbmQpOy0tbWQtZmlsbGVkLWZpZWxkLWNvbnRhaW5lci1zaGFwZS1zdGFydC1zdGFydDogdmFyKC0tX2NvbnRhaW5lci1zaGFwZS1zdGFydC1zdGFydCk7LS1tZC1maWxsZWQtZmllbGQtY29udGVudC1jb2xvcjogdmFyKC0tX2lucHV0LXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWNvbnRlbnQtZm9udDogdmFyKC0tX2lucHV0LXRleHQtZm9udCk7LS1tZC1maWxsZWQtZmllbGQtY29udGVudC1saW5lLWhlaWdodDogdmFyKC0tX2lucHV0LXRleHQtbGluZS1oZWlnaHQpOy0tbWQtZmlsbGVkLWZpZWxkLWNvbnRlbnQtc2l6ZTogdmFyKC0tX2lucHV0LXRleHQtc2l6ZSk7LS1tZC1maWxsZWQtZmllbGQtY29udGVudC1zcGFjZTogdmFyKC0tX2ljb24taW5wdXQtc3BhY2UpOy0tbWQtZmlsbGVkLWZpZWxkLWNvbnRlbnQtd2VpZ2h0OiB2YXIoLS1faW5wdXQtdGV4dC13ZWlnaHQpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLV9kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tX2Rpc2FibGVkLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLW9wYWNpdHk6IHZhcigtLV9kaXNhYmxlZC1hY3RpdmUtaW5kaWNhdG9yLW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWNvbnRhaW5lci1jb2xvcjogdmFyKC0tX2Rpc2FibGVkLWNvbnRhaW5lci1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtY29udGFpbmVyLW9wYWNpdHk6IHZhcigtLV9kaXNhYmxlZC1jb250YWluZXItb3BhY2l0eSk7LS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtY29udGVudC1jb2xvcjogdmFyKC0tX2Rpc2FibGVkLWlucHV0LXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWNvbnRlbnQtb3BhY2l0eTogdmFyKC0tX2Rpc2FibGVkLWlucHV0LXRleHQtb3BhY2l0eSk7LS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tX2Rpc2FibGVkLWxhYmVsLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLWxhYmVsLXRleHQtb3BhY2l0eTogdmFyKC0tX2Rpc2FibGVkLWxhYmVsLXRleHQtb3BhY2l0eSk7LS1tZC1maWxsZWQtZmllbGQtZGlzYWJsZWQtbGVhZGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1fZGlzYWJsZWQtbGVhZGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1sZWFkaW5nLWNvbnRlbnQtb3BhY2l0eTogdmFyKC0tX2Rpc2FibGVkLWxlYWRpbmctaWNvbi1vcGFjaXR5KTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLV9kaXNhYmxlZC1zdXBwb3J0aW5nLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLXN1cHBvcnRpbmctdGV4dC1vcGFjaXR5OiB2YXIoLS1fZGlzYWJsZWQtc3VwcG9ydGluZy10ZXh0LW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWRpc2FibGVkLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV9kaXNhYmxlZC10cmFpbGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1kaXNhYmxlZC10cmFpbGluZy1jb250ZW50LW9wYWNpdHk6IHZhcigtLV9kaXNhYmxlZC10cmFpbGluZy1pY29uLW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLV9lcnJvci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1jb250ZW50LWNvbG9yOiB2YXIoLS1fZXJyb3ItaW5wdXQtdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZXJyb3ItZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvcjogdmFyKC0tX2Vycm9yLWZvY3VzLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWZvY3VzLWNvbnRlbnQtY29sb3I6IHZhcigtLV9lcnJvci1mb2N1cy1pbnB1dC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1fZXJyb3ItZm9jdXMtbGFiZWwtdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZXJyb3ItZm9jdXMtbGVhZGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1fZXJyb3ItZm9jdXMtbGVhZGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1mb2N1cy1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLV9lcnJvci1mb2N1cy1zdXBwb3J0aW5nLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWZvY3VzLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV9lcnJvci1mb2N1cy10cmFpbGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1fZXJyb3ItaG92ZXItYWN0aXZlLWluZGljYXRvci1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZXJyb3ItaG92ZXItY29udGVudC1jb2xvcjogdmFyKC0tX2Vycm9yLWhvdmVyLWlucHV0LXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLV9lcnJvci1ob3Zlci1sYWJlbC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1ob3Zlci1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV9lcnJvci1ob3Zlci1sZWFkaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLXN0YXRlLWxheWVyLWNvbG9yOiB2YXIoLS1fZXJyb3ItaG92ZXItc3RhdGUtbGF5ZXItY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHk6IHZhcigtLV9lcnJvci1ob3Zlci1zdGF0ZS1sYXllci1vcGFjaXR5KTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLV9lcnJvci1ob3Zlci1zdXBwb3J0aW5nLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLWhvdmVyLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV9lcnJvci1ob3Zlci10cmFpbGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1sYWJlbC10ZXh0LWNvbG9yOiB2YXIoLS1fZXJyb3ItbGFiZWwtdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZXJyb3ItbGVhZGluZy1jb250ZW50LWNvbG9yOiB2YXIoLS1fZXJyb3ItbGVhZGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLV9lcnJvci1zdXBwb3J0aW5nLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWVycm9yLXRyYWlsaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV9lcnJvci10cmFpbGluZy1pY29uLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yOiB2YXIoLS1fZm9jdXMtYWN0aXZlLWluZGljYXRvci1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZm9jdXMtYWN0aXZlLWluZGljYXRvci1oZWlnaHQ6IHZhcigtLV9mb2N1cy1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodCk7LS1tZC1maWxsZWQtZmllbGQtZm9jdXMtY29udGVudC1jb2xvcjogdmFyKC0tX2ZvY3VzLWlucHV0LXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWZvY3VzLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLV9mb2N1cy1sYWJlbC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1mb2N1cy1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV9mb2N1cy1sZWFkaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWZvY3VzLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tX2ZvY3VzLXN1cHBvcnRpbmctdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtZm9jdXMtdHJhaWxpbmctY29udGVudC1jb2xvcjogdmFyKC0tX2ZvY3VzLXRyYWlsaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItY29sb3I6IHZhcigtLV9ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1ob3Zlci1hY3RpdmUtaW5kaWNhdG9yLWhlaWdodDogdmFyKC0tX2hvdmVyLWFjdGl2ZS1pbmRpY2F0b3ItaGVpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1ob3Zlci1jb250ZW50LWNvbG9yOiB2YXIoLS1faG92ZXItaW5wdXQtdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtaG92ZXItbGFiZWwtdGV4dC1jb2xvcjogdmFyKC0tX2hvdmVyLWxhYmVsLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLWxlYWRpbmctY29udGVudC1jb2xvcjogdmFyKC0tX2hvdmVyLWxlYWRpbmctaWNvbi1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtaG92ZXItc3RhdGUtbGF5ZXItY29sb3I6IHZhcigtLV9ob3Zlci1zdGF0ZS1sYXllci1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtaG92ZXItc3RhdGUtbGF5ZXItb3BhY2l0eTogdmFyKC0tX2hvdmVyLXN0YXRlLWxheWVyLW9wYWNpdHkpOy0tbWQtZmlsbGVkLWZpZWxkLWhvdmVyLXN1cHBvcnRpbmctdGV4dC1jb2xvcjogdmFyKC0tX2hvdmVyLXN1cHBvcnRpbmctdGV4dC1jb2xvcik7LS1tZC1maWxsZWQtZmllbGQtaG92ZXItdHJhaWxpbmctY29udGVudC1jb2xvcjogdmFyKC0tX2hvdmVyLXRyYWlsaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWxhYmVsLXRleHQtY29sb3I6IHZhcigtLV9sYWJlbC10ZXh0LWNvbG9yKTstLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LWZvbnQ6IHZhcigtLV9sYWJlbC10ZXh0LWZvbnQpOy0tbWQtZmlsbGVkLWZpZWxkLWxhYmVsLXRleHQtbGluZS1oZWlnaHQ6IHZhcigtLV9sYWJlbC10ZXh0LWxpbmUtaGVpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LXBvcHVsYXRlZC1saW5lLWhlaWdodDogdmFyKC0tX2xhYmVsLXRleHQtcG9wdWxhdGVkLWxpbmUtaGVpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LXBvcHVsYXRlZC1zaXplOiB2YXIoLS1fbGFiZWwtdGV4dC1wb3B1bGF0ZWQtc2l6ZSk7LS1tZC1maWxsZWQtZmllbGQtbGFiZWwtdGV4dC1zaXplOiB2YXIoLS1fbGFiZWwtdGV4dC1zaXplKTstLW1kLWZpbGxlZC1maWVsZC1sYWJlbC10ZXh0LXdlaWdodDogdmFyKC0tX2xhYmVsLXRleHQtd2VpZ2h0KTstLW1kLWZpbGxlZC1maWVsZC1sZWFkaW5nLWNvbnRlbnQtY29sb3I6IHZhcigtLV9sZWFkaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLWxlYWRpbmctc3BhY2U6IHZhcigtLV9sZWFkaW5nLXNwYWNlKTstLW1kLWZpbGxlZC1maWVsZC1zdXBwb3J0aW5nLXRleHQtY29sb3I6IHZhcigtLV9zdXBwb3J0aW5nLXRleHQtY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLXN1cHBvcnRpbmctdGV4dC1mb250OiB2YXIoLS1fc3VwcG9ydGluZy10ZXh0LWZvbnQpOy0tbWQtZmlsbGVkLWZpZWxkLXN1cHBvcnRpbmctdGV4dC1saW5lLWhlaWdodDogdmFyKC0tX3N1cHBvcnRpbmctdGV4dC1saW5lLWhlaWdodCk7LS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXNpemU6IHZhcigtLV9zdXBwb3J0aW5nLXRleHQtc2l6ZSk7LS1tZC1maWxsZWQtZmllbGQtc3VwcG9ydGluZy10ZXh0LXdlaWdodDogdmFyKC0tX3N1cHBvcnRpbmctdGV4dC13ZWlnaHQpOy0tbWQtZmlsbGVkLWZpZWxkLXRvcC1zcGFjZTogdmFyKC0tX3RvcC1zcGFjZSk7LS1tZC1maWxsZWQtZmllbGQtdHJhaWxpbmctY29udGVudC1jb2xvcjogdmFyKC0tX3RyYWlsaW5nLWljb24tY29sb3IpOy0tbWQtZmlsbGVkLWZpZWxkLXRyYWlsaW5nLXNwYWNlOiB2YXIoLS1fdHJhaWxpbmctc3BhY2UpOy0tbWQtZmlsbGVkLWZpZWxkLXdpdGgtbGFiZWwtYm90dG9tLXNwYWNlOiB2YXIoLS1fd2l0aC1sYWJlbC1ib3R0b20tc3BhY2UpOy0tbWQtZmlsbGVkLWZpZWxkLXdpdGgtbGFiZWwtdG9wLXNwYWNlOiB2YXIoLS1fd2l0aC1sYWJlbC10b3Atc3BhY2UpOy0tbWQtZmlsbGVkLWZpZWxkLXdpdGgtbGVhZGluZy1jb250ZW50LWxlYWRpbmctc3BhY2U6IHZhcigtLV93aXRoLWxlYWRpbmctaWNvbi1sZWFkaW5nLXNwYWNlKTstLW1kLWZpbGxlZC1maWVsZC13aXRoLXRyYWlsaW5nLWNvbnRlbnQtdHJhaWxpbmctc3BhY2U6IHZhcigtLV93aXRoLXRyYWlsaW5nLWljb24tdHJhaWxpbmctc3BhY2UpfVxuYDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpbGxlZC1zdHlsZXMuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjEgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiAqL1xuaW1wb3J0ICcuLi8uLi9maWVsZC9maWxsZWQtZmllbGQuanMnO1xuaW1wb3J0IHsgbGl0ZXJhbCB9IGZyb20gJ2xpdC9zdGF0aWMtaHRtbC5qcyc7XG5pbXBvcnQgeyBUZXh0RmllbGQgfSBmcm9tICcuL3RleHQtZmllbGQuanMnO1xuLyoqXG4gKiBBIGZpbGxlZCB0ZXh0IGZpZWxkIGNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbGxlZFRleHRGaWVsZCBleHRlbmRzIFRleHRGaWVsZCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuZmllbGRUYWcgPSBsaXRlcmFsIGBtZC1maWxsZWQtZmllbGRgO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpbGxlZC10ZXh0LWZpZWxkLmpzLm1hcCIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDI0IEdvb2dsZSBMTENcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cbi8vIEdlbmVyYXRlZCBzdHlsZXNoZWV0IGZvciAuL3RleHRmaWVsZC9pbnRlcm5hbC9zaGFyZWQtc3R5bGVzLmNzcy5cbmltcG9ydCB7IGNzcyB9IGZyb20gJ2xpdCc7XG5leHBvcnQgY29uc3Qgc3R5bGVzID0gY3NzIGA6aG9zdHtkaXNwbGF5OmlubGluZS1mbGV4O291dGxpbmU6bm9uZTtyZXNpemU6Ym90aDt0ZXh0LWFsaWduOnN0YXJ0Oy13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjpyZ2JhKDAsMCwwLDApfS50ZXh0LWZpZWxkLC5maWVsZHt3aWR0aDoxMDAlfS50ZXh0LWZpZWxke2Rpc3BsYXk6aW5saW5lLWZsZXh9LmZpZWxke2N1cnNvcjp0ZXh0fS5kaXNhYmxlZCAuZmllbGR7Y3Vyc29yOmRlZmF1bHR9LnRleHQtZmllbGQsLnRleHRhcmVhIC5maWVsZHtyZXNpemU6aW5oZXJpdH1zbG90W25hbWU9Y29udGFpbmVyXXtib3JkZXItcmFkaXVzOmluaGVyaXR9Lmljb257Y29sb3I6Y3VycmVudENvbG9yO2Rpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7anVzdGlmeS1jb250ZW50OmNlbnRlcjtmaWxsOmN1cnJlbnRDb2xvcjtwb3NpdGlvbjpyZWxhdGl2ZX0uaWNvbiA6OnNsb3R0ZWQoKil7ZGlzcGxheTpmbGV4O3Bvc2l0aW9uOmFic29sdXRlfVtoYXMtc3RhcnRdIC5pY29uLmxlYWRpbmd7Zm9udC1zaXplOnZhcigtLV9sZWFkaW5nLWljb24tc2l6ZSk7aGVpZ2h0OnZhcigtLV9sZWFkaW5nLWljb24tc2l6ZSk7d2lkdGg6dmFyKC0tX2xlYWRpbmctaWNvbi1zaXplKX1baGFzLWVuZF0gLmljb24udHJhaWxpbmd7Zm9udC1zaXplOnZhcigtLV90cmFpbGluZy1pY29uLXNpemUpO2hlaWdodDp2YXIoLS1fdHJhaWxpbmctaWNvbi1zaXplKTt3aWR0aDp2YXIoLS1fdHJhaWxpbmctaWNvbi1zaXplKX0uaW5wdXQtd3JhcHBlcntkaXNwbGF5OmZsZXh9LmlucHV0LXdyYXBwZXI+KnthbGw6aW5oZXJpdDtwYWRkaW5nOjB9LmlucHV0e2NhcmV0LWNvbG9yOnZhcigtLV9jYXJldC1jb2xvcik7b3ZlcmZsb3cteDpoaWRkZW47dGV4dC1hbGlnbjppbmhlcml0fS5pbnB1dDo6cGxhY2Vob2xkZXJ7Y29sb3I6Y3VycmVudENvbG9yO29wYWNpdHk6MX0uaW5wdXQ6Oi13ZWJraXQtY2FsZW5kYXItcGlja2VyLWluZGljYXRvcntkaXNwbGF5Om5vbmV9LmlucHV0Ojotd2Via2l0LXNlYXJjaC1kZWNvcmF0aW9uLC5pbnB1dDo6LXdlYmtpdC1zZWFyY2gtY2FuY2VsLWJ1dHRvbntkaXNwbGF5Om5vbmV9QG1lZGlhKGZvcmNlZC1jb2xvcnM6IGFjdGl2ZSl7LmlucHV0e2JhY2tncm91bmQ6bm9uZX19Lm5vLXNwaW5uZXIgLmlucHV0Ojotd2Via2l0LWlubmVyLXNwaW4tYnV0dG9uLC5uby1zcGlubmVyIC5pbnB1dDo6LXdlYmtpdC1vdXRlci1zcGluLWJ1dHRvbntkaXNwbGF5Om5vbmV9Lm5vLXNwaW5uZXIgLmlucHV0W3R5cGU9bnVtYmVyXXstbW96LWFwcGVhcmFuY2U6dGV4dGZpZWxkfTpmb2N1cy13aXRoaW4gLmlucHV0e2NhcmV0LWNvbG9yOnZhcigtLV9mb2N1cy1jYXJldC1jb2xvcil9LmVycm9yOmZvY3VzLXdpdGhpbiAuaW5wdXR7Y2FyZXQtY29sb3I6dmFyKC0tX2Vycm9yLWZvY3VzLWNhcmV0LWNvbG9yKX0udGV4dC1maWVsZDpub3QoLmRpc2FibGVkKSAucHJlZml4e2NvbG9yOnZhcigtLV9pbnB1dC10ZXh0LXByZWZpeC1jb2xvcil9LnRleHQtZmllbGQ6bm90KC5kaXNhYmxlZCkgLnN1ZmZpeHtjb2xvcjp2YXIoLS1faW5wdXQtdGV4dC1zdWZmaXgtY29sb3IpfS50ZXh0LWZpZWxkOm5vdCguZGlzYWJsZWQpIC5pbnB1dDo6cGxhY2Vob2xkZXJ7Y29sb3I6dmFyKC0tX2lucHV0LXRleHQtcGxhY2Vob2xkZXItY29sb3IpfS5wcmVmaXgsLnN1ZmZpeHt0ZXh0LXdyYXA6bm93cmFwO3dpZHRoOm1pbi1jb250ZW50fS5wcmVmaXh7cGFkZGluZy1pbmxpbmUtZW5kOnZhcigtLV9pbnB1dC10ZXh0LXByZWZpeC10cmFpbGluZy1zcGFjZSl9LnN1ZmZpeHtwYWRkaW5nLWlubGluZS1zdGFydDp2YXIoLS1faW5wdXQtdGV4dC1zdWZmaXgtbGVhZGluZy1zcGFjZSl9XG5gO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2hhcmVkLXN0eWxlcy5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMSBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5pbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBMaXRFbGVtZW50LCBodG1sLCBub3RoaW5nIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IHByb3BlcnR5LCBxdWVyeSwgcXVlcnlBc3NpZ25lZEVsZW1lbnRzLCBzdGF0ZSB9IGZyb20gJ2xpdC9kZWNvcmF0b3JzLmpzJztcbmltcG9ydCB7IGNsYXNzTWFwIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvY2xhc3MtbWFwLmpzJztcbmltcG9ydCB7IGxpdmUgfSBmcm9tICdsaXQvZGlyZWN0aXZlcy9saXZlLmpzJztcbmltcG9ydCB7IHN0eWxlTWFwIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvc3R5bGUtbWFwLmpzJztcbmltcG9ydCB7IGh0bWwgYXMgc3RhdGljSHRtbCB9IGZyb20gJ2xpdC9zdGF0aWMtaHRtbC5qcyc7XG5pbXBvcnQgeyBtaXhpbkRlbGVnYXRlc0FyaWEgfSBmcm9tICcuLi8uLi9pbnRlcm5hbC9hcmlhL2RlbGVnYXRlLmpzJztcbmltcG9ydCB7IHN0cmluZ0NvbnZlcnRlciB9IGZyb20gJy4uLy4uL2ludGVybmFsL2NvbnRyb2xsZXIvc3RyaW5nLWNvbnZlcnRlci5qcyc7XG5pbXBvcnQgeyByZWRpc3BhdGNoRXZlbnQgfSBmcm9tICcuLi8uLi9pbnRlcm5hbC9ldmVudHMvcmVkaXNwYXRjaC1ldmVudC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVWYWxpZGF0b3IsIGdldFZhbGlkaXR5QW5jaG9yLCBtaXhpbkNvbnN0cmFpbnRWYWxpZGF0aW9uLCB9IGZyb20gJy4uLy4uL2xhYnMvYmVoYXZpb3JzL2NvbnN0cmFpbnQtdmFsaWRhdGlvbi5qcyc7XG5pbXBvcnQgeyBtaXhpbkVsZW1lbnRJbnRlcm5hbHMgfSBmcm9tICcuLi8uLi9sYWJzL2JlaGF2aW9ycy9lbGVtZW50LWludGVybmFscy5qcyc7XG5pbXBvcnQgeyBnZXRGb3JtVmFsdWUsIG1peGluRm9ybUFzc29jaWF0ZWQsIH0gZnJvbSAnLi4vLi4vbGFicy9iZWhhdmlvcnMvZm9ybS1hc3NvY2lhdGVkLmpzJztcbmltcG9ydCB7IG1peGluT25SZXBvcnRWYWxpZGl0eSwgb25SZXBvcnRWYWxpZGl0eSwgfSBmcm9tICcuLi8uLi9sYWJzL2JlaGF2aW9ycy9vbi1yZXBvcnQtdmFsaWRpdHkuanMnO1xuaW1wb3J0IHsgVGV4dEZpZWxkVmFsaWRhdG9yIH0gZnJvbSAnLi4vLi4vbGFicy9iZWhhdmlvcnMvdmFsaWRhdG9ycy90ZXh0LWZpZWxkLXZhbGlkYXRvci5qcyc7XG4vLyBTZXBhcmF0ZSB2YXJpYWJsZSBuZWVkZWQgZm9yIGNsb3N1cmUuXG5jb25zdCB0ZXh0RmllbGRCYXNlQ2xhc3MgPSBtaXhpbkRlbGVnYXRlc0FyaWEobWl4aW5PblJlcG9ydFZhbGlkaXR5KG1peGluQ29uc3RyYWludFZhbGlkYXRpb24obWl4aW5Gb3JtQXNzb2NpYXRlZChtaXhpbkVsZW1lbnRJbnRlcm5hbHMoTGl0RWxlbWVudCkpKSkpO1xuLyoqXG4gKiBBIHRleHQgZmllbGQgY29tcG9uZW50LlxuICpcbiAqIEBmaXJlcyBzZWxlY3Qge0V2ZW50fSBUaGUgbmF0aXZlIGBzZWxlY3RgIGV2ZW50IG9uXG4gKiBbYDxpbnB1dD5gXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTElucHV0RWxlbWVudC9zZWxlY3RfZXZlbnQpXG4gKiAtLWJ1YmJsZXNcbiAqIEBmaXJlcyBjaGFuZ2Uge0V2ZW50fSBUaGUgbmF0aXZlIGBjaGFuZ2VgIGV2ZW50IG9uXG4gKiBbYDxpbnB1dD5gXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTEVsZW1lbnQvY2hhbmdlX2V2ZW50KVxuICogLS1idWJibGVzXG4gKiBAZmlyZXMgaW5wdXQge0lucHV0RXZlbnR9IFRoZSBuYXRpdmUgYGlucHV0YCBldmVudCBvblxuICogW2A8aW5wdXQ+YF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxFbGVtZW50L2lucHV0X2V2ZW50KVxuICogLS1idWJibGVzIC0tY29tcG9zZWRcbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRGaWVsZCBleHRlbmRzIHRleHRGaWVsZEJhc2VDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIG9yIHNldHMgd2hldGhlciBvciBub3QgdGhlIHRleHQgZmllbGQgaXMgaW4gYSB2aXN1YWxseSBpbnZhbGlkIHN0YXRlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGlzIGVycm9yIHN0YXRlIG92ZXJyaWRlcyB0aGUgZXJyb3Igc3RhdGUgY29udHJvbGxlZCBieVxuICAgICAgICAgKiBgcmVwb3J0VmFsaWRpdHkoKWAuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmVycm9yID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZXJyb3IgbWVzc2FnZSB0aGF0IHJlcGxhY2VzIHN1cHBvcnRpbmcgdGV4dCB3aGVuIGBlcnJvcmAgaXMgdHJ1ZS4gSWZcbiAgICAgICAgICogYGVycm9yVGV4dGAgaXMgYW4gZW1wdHkgc3RyaW5nLCB0aGVuIHRoZSBzdXBwb3J0aW5nIHRleHQgd2lsbCBjb250aW51ZSB0b1xuICAgICAgICAgKiBzaG93LlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGlzIGVycm9yIG1lc3NhZ2Ugb3ZlcnJpZGVzIHRoZSBlcnJvciBtZXNzYWdlIGRpc3BsYXllZCBieVxuICAgICAgICAgKiBgcmVwb3J0VmFsaWRpdHkoKWAuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmVycm9yVGV4dCA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGZsb2F0aW5nIE1hdGVyaWFsIGxhYmVsIG9mIHRoZSB0ZXh0ZmllbGQgY29tcG9uZW50LiBJdCBpbmZvcm1zIHRoZSB1c2VyXG4gICAgICAgICAqIGFib3V0IHdoYXQgaW5mb3JtYXRpb24gaXMgcmVxdWVzdGVkIGZvciBhIHRleHQgZmllbGQuIEl0IGlzIGFsaWduZWQgd2l0aFxuICAgICAgICAgKiB0aGUgaW5wdXQgdGV4dCwgaXMgYWx3YXlzIHZpc2libGUsIGFuZCBpdCBmbG9hdHMgd2hlbiBmb2N1c2VkIG9yIHdoZW4gdGV4dFxuICAgICAgICAgKiBpcyBlbnRlcmVkIGludG8gdGhlIHRleHRmaWVsZC4gVGhpcyBsYWJlbCBhbHNvIHNldHMgYWNjZXNzaWJpbHR5IGxhYmVscyxcbiAgICAgICAgICogYnV0IHRoZSBhY2Nlc3NpYmxlIGxhYmVsIGlzIG92ZXJyaWRlbiBieSBgYXJpYS1sYWJlbGAuXG4gICAgICAgICAqXG4gICAgICAgICAqIExlYXJuIG1vcmUgYWJvdXQgZmxvYXRpbmcgbGFiZWxzIGZyb20gdGhlIE1hdGVyaWFsIERlc2lnbiBndWlkZWxpbmVzOlxuICAgICAgICAgKiBodHRwczovL20zLm1hdGVyaWFsLmlvL2NvbXBvbmVudHMvdGV4dC1maWVsZHMvZ3VpZGVsaW5lc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sYWJlbCA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGlzYWJsZXMgdGhlIGFzdGVyaXNrIG9uIHRoZSBmbG9hdGluZyBsYWJlbCwgd2hlbiB0aGUgdGV4dCBmaWVsZCBpc1xuICAgICAgICAgKiByZXF1aXJlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubm9Bc3RlcmlzayA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIgbXVzdCBzcGVjaWZ5IGEgdmFsdWUgZm9yIHRoZSBpbnB1dCBiZWZvcmUgdGhlXG4gICAgICAgICAqIG93bmluZyBmb3JtIGNhbiBiZSBzdWJtaXR0ZWQgYW5kIHdpbGwgcmVuZGVyIGFuIGVycm9yIHN0YXRlIHdoZW5cbiAgICAgICAgICogYHJlcG9ydFZhbGlkaXR5KClgIGlzIGludm9rZWQgd2hlbiB2YWx1ZSBpcyBlbXB0eS4gQWRkaXRpb25hbGx5IHRoZVxuICAgICAgICAgKiBmbG9hdGluZyBsYWJlbCB3aWxsIHJlbmRlciBhbiBhc3RlcmlzayBgXCIqXCJgIHdoZW4gdHJ1ZS5cbiAgICAgICAgICpcbiAgICAgICAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9BdHRyaWJ1dGVzL3JlcXVpcmVkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnJlcXVpcmVkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgdGV4dCBmaWVsZC4gSXQgaXMgYWx3YXlzIGEgc3RyaW5nLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy52YWx1ZSA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogQW4gb3B0aW9uYWwgcHJlZml4IHRvIGRpc3BsYXkgYmVmb3JlIHRoZSBpbnB1dCB2YWx1ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucHJlZml4VGV4dCA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogQW4gb3B0aW9uYWwgc3VmZml4IHRvIGRpc3BsYXkgYWZ0ZXIgdGhlIGlucHV0IHZhbHVlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5zdWZmaXhUZXh0ID0gJyc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIG9yIG5vdCB0aGUgdGV4dCBmaWVsZCBoYXMgYSBsZWFkaW5nIGljb24uIFVzZWQgZm9yIFNTUi5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaGFzTGVhZGluZ0ljb24gPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSB0ZXh0IGZpZWxkIGhhcyBhIHRyYWlsaW5nIGljb24uIFVzZWQgZm9yIFNTUi5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaGFzVHJhaWxpbmdJY29uID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXlzIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gYmVsb3cgdGhlIHRleHQgZmllbGQsIHN1Y2ggYXMgaG93IGl0IHNob3VsZFxuICAgICAgICAgKiBiZSB1c2VkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5zdXBwb3J0aW5nVGV4dCA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogT3ZlcnJpZGUgdGhlIGlucHV0IHRleHQgQ1NTIGBkaXJlY3Rpb25gLiBVc2VmdWwgZm9yIFJUTCBsYW5ndWFnZXMgdGhhdCB1c2VcbiAgICAgICAgICogTFRSIG5vdGF0aW9uIGZvciBmcmFjdGlvbnMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnRleHREaXJlY3Rpb24gPSAnJztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBudW1iZXIgb2Ygcm93cyB0byBkaXNwbGF5IGZvciBhIGB0eXBlPVwidGV4dGFyZWFcImAgdGV4dCBmaWVsZC5cbiAgICAgICAgICogRGVmYXVsdHMgdG8gMi5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucm93cyA9IDI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIGNvbHMgdG8gZGlzcGxheSBmb3IgYSBgdHlwZT1cInRleHRhcmVhXCJgIHRleHQgZmllbGQuXG4gICAgICAgICAqIERlZmF1bHRzIHRvIDIwLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb2xzID0gMjA7XG4gICAgICAgIC8vIDxpbnB1dD4gcHJvcGVydGllc1xuICAgICAgICB0aGlzLmlucHV0TW9kZSA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGVmaW5lcyB0aGUgZ3JlYXRlc3QgdmFsdWUgaW4gdGhlIHJhbmdlIG9mIHBlcm1pdHRlZCB2YWx1ZXMuXG4gICAgICAgICAqXG4gICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9pbnB1dCNtYXhcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubWF4ID0gJyc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBhIHVzZXIgY2FuIGVudGVyIGludG8gdGhlIHRleHQgZmllbGQuIFNldFxuICAgICAgICAgKiB0byAtMSBmb3Igbm9uZS5cbiAgICAgICAgICpcbiAgICAgICAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2lucHV0I21heGxlbmd0aFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5tYXhMZW5ndGggPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlZmluZXMgdGhlIG1vc3QgbmVnYXRpdmUgdmFsdWUgaW4gdGhlIHJhbmdlIG9mIHBlcm1pdHRlZCB2YWx1ZXMuXG4gICAgICAgICAqXG4gICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9pbnB1dCNtaW5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubWluID0gJyc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWluaW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBhIHVzZXIgY2FuIGVudGVyIGludG8gdGhlIHRleHQgZmllbGQuIFNldFxuICAgICAgICAgKiB0byAtMSBmb3Igbm9uZS5cbiAgICAgICAgICpcbiAgICAgICAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2lucHV0I21pbmxlbmd0aFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5taW5MZW5ndGggPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZW4gdHJ1ZSwgaGlkZSB0aGUgc3Bpbm5lciBmb3IgYHR5cGU9XCJudW1iZXJcImAgdGV4dCBmaWVsZHMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm5vU3Bpbm5lciA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogQSByZWd1bGFyIGV4cHJlc3Npb24gdGhhdCB0aGUgdGV4dCBmaWVsZCdzIHZhbHVlIG11c3QgbWF0Y2ggdG8gcGFzc1xuICAgICAgICAgKiBjb25zdHJhaW50IHZhbGlkYXRpb24uXG4gICAgICAgICAqXG4gICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9pbnB1dCNwYXR0ZXJuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnBhdHRlcm4gPSAnJztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlZmluZXMgdGhlIHRleHQgZGlzcGxheWVkIGluIHRoZSB0ZXh0ZmllbGQgd2hlbiBpdCBoYXMgbm8gdmFsdWUuIFByb3ZpZGVzXG4gICAgICAgICAqIGEgYnJpZWYgaGludCB0byB0aGUgdXNlciBhcyB0byB0aGUgZXhwZWN0ZWQgdHlwZSBvZiBkYXRhIHRoYXQgc2hvdWxkIGJlXG4gICAgICAgICAqIGVudGVyZWQgaW50byB0aGUgY29udHJvbC4gVW5saWtlIGBsYWJlbGAsIHRoZSBwbGFjZWhvbGRlciBpcyBub3QgdmlzaWJsZVxuICAgICAgICAgKiBhbmQgZG9lcyBub3QgZmxvYXQgd2hlbiB0aGUgdGV4dGZpZWxkIGhhcyBhIHZhbHVlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0F0dHJpYnV0ZXMvcGxhY2Vob2xkZXJcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucGxhY2Vob2xkZXIgPSAnJztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCBhIHVzZXIgc2hvdWxkIGJlIGFibGUgdG8gZWRpdCB0aGUgdGV4dCBmaWVsZCdzXG4gICAgICAgICAqIHZhbHVlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvaW5wdXQjcmVhZG9ubHlcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVhZE9ubHkgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyB0aGF0IGlucHV0IGFjY2VwdHMgbXVsdGlwbGUgZW1haWwgYWRkcmVzc2VzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvaW5wdXQvZW1haWwjbXVsdGlwbGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubXVsdGlwbGUgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJldHVybnMgb3Igc2V0cyB0aGUgZWxlbWVudCdzIHN0ZXAgYXR0cmlidXRlLCB3aGljaCB3b3JrcyB3aXRoIG1pbiBhbmQgbWF4XG4gICAgICAgICAqIHRvIGxpbWl0IHRoZSBpbmNyZW1lbnRzIGF0IHdoaWNoIGEgbnVtZXJpYyBvciBkYXRlLXRpbWUgdmFsdWUgY2FuIGJlIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2lucHV0I3N0ZXBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuc3RlcCA9ICcnO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGA8aW5wdXQ+YCB0eXBlIHRvIHVzZSwgZGVmYXVsdHMgdG8gXCJ0ZXh0XCIuIFRoZSB0eXBlIGdyZWF0bHkgY2hhbmdlcyBob3dcbiAgICAgICAgICogdGhlIHRleHQgZmllbGQgYmVoYXZlcy5cbiAgICAgICAgICpcbiAgICAgICAgICogVGV4dCBmaWVsZHMgc3VwcG9ydCBhIGxpbWl0ZWQgbnVtYmVyIG9mIGA8aW5wdXQ+YCB0eXBlczpcbiAgICAgICAgICpcbiAgICAgICAgICogLSB0ZXh0XG4gICAgICAgICAqIC0gdGV4dGFyZWFcbiAgICAgICAgICogLSBlbWFpbFxuICAgICAgICAgKiAtIG51bWJlclxuICAgICAgICAgKiAtIHBhc3N3b3JkXG4gICAgICAgICAqIC0gc2VhcmNoXG4gICAgICAgICAqIC0gdGVsXG4gICAgICAgICAqIC0gdXJsXG4gICAgICAgICAqXG4gICAgICAgICAqIFNlZVxuICAgICAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvaW5wdXQjaW5wdXRfdHlwZXNcbiAgICAgICAgICogZm9yIG1vcmUgZGV0YWlscyBvbiBlYWNoIGlucHV0IHR5cGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnR5cGUgPSAndGV4dCc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZXNjcmliZXMgd2hhdCwgaWYgYW55LCB0eXBlIG9mIGF1dG9jb21wbGV0ZSBmdW5jdGlvbmFsaXR5IHRoZSBpbnB1dFxuICAgICAgICAgKiBzaG91bGQgcHJvdmlkZS5cbiAgICAgICAgICpcbiAgICAgICAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9BdHRyaWJ1dGVzL2F1dG9jb21wbGV0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hdXRvY29tcGxldGUgPSAnJztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSB0ZXh0IGZpZWxkIGhhcyBiZWVuIGludGVyYWN0ZWQgd2l0aC4gTmF0aXZlXG4gICAgICAgICAqIHZhbGlkYXRpb24gZXJyb3JzIG9ubHkgZGlzcGxheSBpbiByZXNwb25zZSB0byB1c2VyIGludGVyYWN0aW9ucy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5mb2N1c2VkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIG9yIG5vdCBhIG5hdGl2ZSBlcnJvciBoYXMgYmVlbiByZXBvcnRlZCB2aWEgYHJlcG9ydFZhbGlkaXR5KClgLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5uYXRpdmVFcnJvciA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbGlkYXRpb24gbWVzc2FnZSBkaXNwbGF5ZWQgZnJvbSBhIG5hdGl2ZSBlcnJvciB2aWFcbiAgICAgICAgICogYHJlcG9ydFZhbGlkaXR5KClgLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5uYXRpdmVFcnJvclRleHQgPSAnJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSBkaXJlY3Rpb24gaW4gd2hpY2ggc2VsZWN0aW9uIG9jY3VycmVkLlxuICAgICAqL1xuICAgIGdldCBzZWxlY3Rpb25EaXJlY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldElucHV0T3JUZXh0YXJlYSgpLnNlbGVjdGlvbkRpcmVjdGlvbjtcbiAgICB9XG4gICAgc2V0IHNlbGVjdGlvbkRpcmVjdGlvbih2YWx1ZSkge1xuICAgICAgICB0aGlzLmdldElucHV0T3JUZXh0YXJlYSgpLnNlbGVjdGlvbkRpcmVjdGlvbiA9IHZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXRzIG9yIHNldHMgdGhlIGVuZCBwb3NpdGlvbiBvciBvZmZzZXQgb2YgYSB0ZXh0IHNlbGVjdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgc2VsZWN0aW9uRW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRJbnB1dE9yVGV4dGFyZWEoKS5zZWxlY3Rpb25FbmQ7XG4gICAgfVxuICAgIHNldCBzZWxlY3Rpb25FbmQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5nZXRJbnB1dE9yVGV4dGFyZWEoKS5zZWxlY3Rpb25FbmQgPSB2YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyBvciBzZXRzIHRoZSBzdGFydGluZyBwb3NpdGlvbiBvciBvZmZzZXQgb2YgYSB0ZXh0IHNlbGVjdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgc2VsZWN0aW9uU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldElucHV0T3JUZXh0YXJlYSgpLnNlbGVjdGlvblN0YXJ0O1xuICAgIH1cbiAgICBzZXQgc2VsZWN0aW9uU3RhcnQodmFsdWUpIHtcbiAgICAgICAgdGhpcy5nZXRJbnB1dE9yVGV4dGFyZWEoKS5zZWxlY3Rpb25TdGFydCA9IHZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGV4dCBmaWVsZCdzIHZhbHVlIGFzIGEgbnVtYmVyLlxuICAgICAqL1xuICAgIGdldCB2YWx1ZUFzTnVtYmVyKCkge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHRoaXMuZ2V0SW5wdXQoKTtcbiAgICAgICAgaWYgKCFpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5wdXQudmFsdWVBc051bWJlcjtcbiAgICB9XG4gICAgc2V0IHZhbHVlQXNOdW1iZXIodmFsdWUpIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB0aGlzLmdldElucHV0KCk7XG4gICAgICAgIGlmICghaW5wdXQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dC52YWx1ZUFzTnVtYmVyID0gdmFsdWU7XG4gICAgICAgIHRoaXMudmFsdWUgPSBpbnB1dC52YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRleHQgZmllbGQncyB2YWx1ZSBhcyBhIERhdGUuXG4gICAgICovXG4gICAgZ2V0IHZhbHVlQXNEYXRlKCkge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHRoaXMuZ2V0SW5wdXQoKTtcbiAgICAgICAgaWYgKCFpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlucHV0LnZhbHVlQXNEYXRlO1xuICAgIH1cbiAgICBzZXQgdmFsdWVBc0RhdGUodmFsdWUpIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB0aGlzLmdldElucHV0KCk7XG4gICAgICAgIGlmICghaW5wdXQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dC52YWx1ZUFzRGF0ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnZhbHVlID0gaW5wdXQudmFsdWU7XG4gICAgfVxuICAgIGdldCBoYXNFcnJvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3IgfHwgdGhpcy5uYXRpdmVFcnJvcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VsZWN0cyBhbGwgdGhlIHRleHQgaW4gdGhlIHRleHQgZmllbGQuXG4gICAgICpcbiAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTElucHV0RWxlbWVudC9zZWxlY3RcbiAgICAgKi9cbiAgICBzZWxlY3QoKSB7XG4gICAgICAgIHRoaXMuZ2V0SW5wdXRPclRleHRhcmVhKCkuc2VsZWN0KCk7XG4gICAgfVxuICAgIHNldFJhbmdlVGV4dCguLi5hcmdzKSB7XG4gICAgICAgIC8vIENhbGxpbmcgc2V0UmFuZ2VUZXh0IHdpdGggMSB2cyAzLTQgYXJndW1lbnRzIGhhcyBkaWZmZXJlbnQgYmVoYXZpb3IuXG4gICAgICAgIC8vIFVzZSBzcHJlYWQgc3ludGF4IGFuZCB0eXBlIGNhc3RpbmcgdG8gZW5zdXJlIGNvcnJlY3QgdXNhZ2UuXG4gICAgICAgIHRoaXMuZ2V0SW5wdXRPclRleHRhcmVhKCkuc2V0UmFuZ2VUZXh0KC4uLmFyZ3MpO1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5nZXRJbnB1dE9yVGV4dGFyZWEoKS52YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgb2YgYSBzZWxlY3Rpb24gaW4gdGhlIHRleHQgZmllbGQuXG4gICAgICpcbiAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTElucHV0RWxlbWVudC9zZXRTZWxlY3Rpb25SYW5nZVxuICAgICAqXG4gICAgICogQHBhcmFtIHN0YXJ0IFRoZSBvZmZzZXQgaW50byB0aGUgdGV4dCBmaWVsZCBmb3IgdGhlIHN0YXJ0IG9mIHRoZSBzZWxlY3Rpb24uXG4gICAgICogQHBhcmFtIGVuZCBUaGUgb2Zmc2V0IGludG8gdGhlIHRleHQgZmllbGQgZm9yIHRoZSBlbmQgb2YgdGhlIHNlbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZGlyZWN0aW9uIFRoZSBkaXJlY3Rpb24gaW4gd2hpY2ggdGhlIHNlbGVjdGlvbiBpcyBwZXJmb3JtZWQuXG4gICAgICovXG4gICAgc2V0U2VsZWN0aW9uUmFuZ2Uoc3RhcnQsIGVuZCwgZGlyZWN0aW9uKSB7XG4gICAgICAgIHRoaXMuZ2V0SW5wdXRPclRleHRhcmVhKCkuc2V0U2VsZWN0aW9uUmFuZ2Uoc3RhcnQsIGVuZCwgZGlyZWN0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIGJyb3dzZXIgcGlja2VyIGZvciBhbiBpbnB1dCBlbGVtZW50IG9mIHR5cGUgXCJkYXRlXCIsIFwidGltZVwiLCBldGMuXG4gICAgICpcbiAgICAgKiBGb3IgYSBmdWxsIGxpc3Qgb2Ygc3VwcG9ydGVkIHR5cGVzLCBzZWU6XG4gICAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxJbnB1dEVsZW1lbnQvc2hvd1BpY2tlciNicm93c2VyX2NvbXBhdGliaWxpdHlcbiAgICAgKlxuICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MSW5wdXRFbGVtZW50L3Nob3dQaWNrZXJcbiAgICAgKi9cbiAgICBzaG93UGlja2VyKCkge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHRoaXMuZ2V0SW5wdXQoKTtcbiAgICAgICAgaWYgKCFpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlucHV0LnNob3dQaWNrZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVjcmVtZW50cyB0aGUgdmFsdWUgb2YgYSBudW1lcmljIHR5cGUgdGV4dCBmaWVsZCBieSBgc3RlcGAgb3IgYG5gIGBzdGVwYFxuICAgICAqIG51bWJlciBvZiB0aW1lcy5cbiAgICAgKlxuICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MSW5wdXRFbGVtZW50L3N0ZXBEb3duXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc3RlcERlY3JlbWVudCBUaGUgbnVtYmVyIG9mIHN0ZXBzIHRvIGRlY3JlbWVudCwgZGVmYXVsdHMgdG8gMS5cbiAgICAgKi9cbiAgICBzdGVwRG93bihzdGVwRGVjcmVtZW50KSB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gdGhpcy5nZXRJbnB1dCgpO1xuICAgICAgICBpZiAoIWlucHV0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaW5wdXQuc3RlcERvd24oc3RlcERlY3JlbWVudCk7XG4gICAgICAgIHRoaXMudmFsdWUgPSBpbnB1dC52YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5jcmVtZW50cyB0aGUgdmFsdWUgb2YgYSBudW1lcmljIHR5cGUgdGV4dCBmaWVsZCBieSBgc3RlcGAgb3IgYG5gIGBzdGVwYFxuICAgICAqIG51bWJlciBvZiB0aW1lcy5cbiAgICAgKlxuICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MSW5wdXRFbGVtZW50L3N0ZXBVcFxuICAgICAqXG4gICAgICogQHBhcmFtIHN0ZXBJbmNyZW1lbnQgVGhlIG51bWJlciBvZiBzdGVwcyB0byBpbmNyZW1lbnQsIGRlZmF1bHRzIHRvIDEuXG4gICAgICovXG4gICAgc3RlcFVwKHN0ZXBJbmNyZW1lbnQpIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB0aGlzLmdldElucHV0KCk7XG4gICAgICAgIGlmICghaW5wdXQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dC5zdGVwVXAoc3RlcEluY3JlbWVudCk7XG4gICAgICAgIHRoaXMudmFsdWUgPSBpbnB1dC52YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzZXQgdGhlIHRleHQgZmllbGQgdG8gaXRzIGRlZmF1bHQgdmFsdWUuXG4gICAgICovXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMuZGlydHkgPSBmYWxzZTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCd2YWx1ZScpID8/ICcnO1xuICAgICAgICB0aGlzLm5hdGl2ZUVycm9yID0gZmFsc2U7XG4gICAgICAgIHRoaXMubmF0aXZlRXJyb3JUZXh0ID0gJyc7XG4gICAgfVxuICAgIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhhdHRyaWJ1dGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSkge1xuICAgICAgICBpZiAoYXR0cmlidXRlID09PSAndmFsdWUnICYmIHRoaXMuZGlydHkpIHtcbiAgICAgICAgICAgIC8vIEFmdGVyIHVzZXIgaW5wdXQsIGNoYW5naW5nIHRoZSB2YWx1ZSBhdHRyaWJ1dGUgbm8gbG9uZ2VyIHVwZGF0ZXMgdGhlXG4gICAgICAgICAgICAvLyB0ZXh0IGZpZWxkJ3MgdmFsdWUgKHVudGlsIHJlc2V0KS4gVGhpcyBtYXRjaGVzIG5hdGl2ZSA8aW5wdXQ+IGJlaGF2aW9yLlxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhhdHRyaWJ1dGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSk7XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IHtcbiAgICAgICAgICAgICdkaXNhYmxlZCc6IHRoaXMuZGlzYWJsZWQsXG4gICAgICAgICAgICAnZXJyb3InOiAhdGhpcy5kaXNhYmxlZCAmJiB0aGlzLmhhc0Vycm9yLFxuICAgICAgICAgICAgJ3RleHRhcmVhJzogdGhpcy50eXBlID09PSAndGV4dGFyZWEnLFxuICAgICAgICAgICAgJ25vLXNwaW5uZXInOiB0aGlzLm5vU3Bpbm5lcixcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWZpZWxkICR7Y2xhc3NNYXAoY2xhc3Nlcyl9XCI+XG4gICAgICAgICR7dGhpcy5yZW5kZXJGaWVsZCgpfVxuICAgICAgPC9zcGFuPlxuICAgIGA7XG4gICAgfVxuICAgIHVwZGF0ZWQoY2hhbmdlZFByb3BlcnRpZXMpIHtcbiAgICAgICAgLy8gS2VlcCBjaGFuZ2VkUHJvcGVydGllcyBhcmcgc28gdGhhdCBzdWJjbGFzc2VzIG1heSBjYWxsIGl0XG4gICAgICAgIC8vIElmIGEgcHJvcGVydHkgc3VjaCBhcyBgdHlwZWAgY2hhbmdlcyBhbmQgY2F1c2VzIHRoZSBpbnRlcm5hbCA8aW5wdXQ+XG4gICAgICAgIC8vIHZhbHVlIHRvIGNoYW5nZSB3aXRob3V0IGRpc3BhdGNoaW5nIGFuIGV2ZW50LCByZS1zeW5jIGl0LlxuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0SW5wdXRPclRleHRhcmVhKCkudmFsdWU7XG4gICAgICAgIGlmICh0aGlzLnZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgLy8gTm90ZSB0aGlzIGlzIHR5cGljYWxseSBpbmVmZmljaWVudCBpbiB1cGRhdGVkKCkgc2luY2UgaXQgc2NoZWR1bGVzXG4gICAgICAgICAgICAvLyBhbm90aGVyIHVwZGF0ZS4gSG93ZXZlciwgaXQgaXMgbmVlZGVkIGZvciB0aGUgPGlucHV0PiB0byBmdWxseSByZW5kZXJcbiAgICAgICAgICAgIC8vIGJlZm9yZSBjaGVja2luZyBpdHMgdmFsdWUuXG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVuZGVyRmllbGQoKSB7XG4gICAgICAgIHJldHVybiBzdGF0aWNIdG1sIGA8JHt0aGlzLmZpZWxkVGFnfVxuICAgICAgY2xhc3M9XCJmaWVsZFwiXG4gICAgICBjb3VudD0ke3RoaXMudmFsdWUubGVuZ3RofVxuICAgICAgP2Rpc2FibGVkPSR7dGhpcy5kaXNhYmxlZH1cbiAgICAgID9lcnJvcj0ke3RoaXMuaGFzRXJyb3J9XG4gICAgICBlcnJvci10ZXh0PSR7dGhpcy5nZXRFcnJvclRleHQoKX1cbiAgICAgID9mb2N1c2VkPSR7dGhpcy5mb2N1c2VkfVxuICAgICAgP2hhcy1lbmQ9JHt0aGlzLmhhc1RyYWlsaW5nSWNvbn1cbiAgICAgID9oYXMtc3RhcnQ9JHt0aGlzLmhhc0xlYWRpbmdJY29ufVxuICAgICAgbGFiZWw9JHt0aGlzLmxhYmVsfVxuICAgICAgP25vLWFzdGVyaXNrPSR7dGhpcy5ub0FzdGVyaXNrfVxuICAgICAgbWF4PSR7dGhpcy5tYXhMZW5ndGh9XG4gICAgICA/cG9wdWxhdGVkPSR7ISF0aGlzLnZhbHVlfVxuICAgICAgP3JlcXVpcmVkPSR7dGhpcy5yZXF1aXJlZH1cbiAgICAgID9yZXNpemFibGU9JHt0aGlzLnR5cGUgPT09ICd0ZXh0YXJlYSd9XG4gICAgICBzdXBwb3J0aW5nLXRleHQ9JHt0aGlzLnN1cHBvcnRpbmdUZXh0fVxuICAgID5cbiAgICAgICR7dGhpcy5yZW5kZXJMZWFkaW5nSWNvbigpfVxuICAgICAgJHt0aGlzLnJlbmRlcklucHV0T3JUZXh0YXJlYSgpfVxuICAgICAgJHt0aGlzLnJlbmRlclRyYWlsaW5nSWNvbigpfVxuICAgICAgPGRpdiBpZD1cImRlc2NyaXB0aW9uXCIgc2xvdD1cImFyaWEtZGVzY3JpYmVkYnlcIj48L2Rpdj5cbiAgICAgIDxzbG90IG5hbWU9XCJjb250YWluZXJcIiBzbG90PVwiY29udGFpbmVyXCI+PC9zbG90PlxuICAgIDwvJHt0aGlzLmZpZWxkVGFnfT5gO1xuICAgIH1cbiAgICByZW5kZXJMZWFkaW5nSWNvbigpIHtcbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPHNwYW4gY2xhc3M9XCJpY29uIGxlYWRpbmdcIiBzbG90PVwic3RhcnRcIj5cbiAgICAgICAgPHNsb3QgbmFtZT1cImxlYWRpbmctaWNvblwiIEBzbG90Y2hhbmdlPSR7dGhpcy5oYW5kbGVJY29uQ2hhbmdlfT48L3Nsb3Q+XG4gICAgICA8L3NwYW4+XG4gICAgYDtcbiAgICB9XG4gICAgcmVuZGVyVHJhaWxpbmdJY29uKCkge1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8c3BhbiBjbGFzcz1cImljb24gdHJhaWxpbmdcIiBzbG90PVwiZW5kXCI+XG4gICAgICAgIDxzbG90IG5hbWU9XCJ0cmFpbGluZy1pY29uXCIgQHNsb3RjaGFuZ2U9JHt0aGlzLmhhbmRsZUljb25DaGFuZ2V9Pjwvc2xvdD5cbiAgICAgIDwvc3Bhbj5cbiAgICBgO1xuICAgIH1cbiAgICByZW5kZXJJbnB1dE9yVGV4dGFyZWEoKSB7XG4gICAgICAgIGNvbnN0IHN0eWxlID0geyAnZGlyZWN0aW9uJzogdGhpcy50ZXh0RGlyZWN0aW9uIH07XG4gICAgICAgIGNvbnN0IGFyaWFMYWJlbCA9IHRoaXMuYXJpYUxhYmVsIHx8IHRoaXMubGFiZWwgfHwgbm90aGluZztcbiAgICAgICAgLy8gbGl0LWFuYXlsemVyIGBhdXRvY29tcGxldGVgIHR5cGVzIGFyZSB0b28gc3RyaWN0XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgICAgY29uc3QgYXV0b2NvbXBsZXRlID0gdGhpcy5hdXRvY29tcGxldGU7XG4gICAgICAgIC8vIFRoZXNlIHByb3BlcnRpZXMgbWF5IGJlIHNldCB0byBudWxsIGlmIHRoZSBhdHRyaWJ1dGUgaXMgcmVtb3ZlZCwgYW5kXG4gICAgICAgIC8vIGBudWxsID4gLTFgIGlzIGluY29ycmVjdGx5IGB0cnVlYC5cbiAgICAgICAgY29uc3QgaGFzTWF4TGVuZ3RoID0gKHRoaXMubWF4TGVuZ3RoID8/IC0xKSA+IC0xO1xuICAgICAgICBjb25zdCBoYXNNaW5MZW5ndGggPSAodGhpcy5taW5MZW5ndGggPz8gLTEpID4gLTE7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICd0ZXh0YXJlYScpIHtcbiAgICAgICAgICAgIHJldHVybiBodG1sIGBcbiAgICAgICAgPHRleHRhcmVhXG4gICAgICAgICAgY2xhc3M9XCJpbnB1dFwiXG4gICAgICAgICAgc3R5bGU9JHtzdHlsZU1hcChzdHlsZSl9XG4gICAgICAgICAgYXJpYS1kZXNjcmliZWRieT1cImRlc2NyaXB0aW9uXCJcbiAgICAgICAgICBhcmlhLWludmFsaWQ9JHt0aGlzLmhhc0Vycm9yfVxuICAgICAgICAgIGFyaWEtbGFiZWw9JHthcmlhTGFiZWx9XG4gICAgICAgICAgYXV0b2NvbXBsZXRlPSR7YXV0b2NvbXBsZXRlIHx8IG5vdGhpbmd9XG4gICAgICAgICAgbmFtZT0ke3RoaXMubmFtZSB8fCBub3RoaW5nfVxuICAgICAgICAgID9kaXNhYmxlZD0ke3RoaXMuZGlzYWJsZWR9XG4gICAgICAgICAgbWF4bGVuZ3RoPSR7aGFzTWF4TGVuZ3RoID8gdGhpcy5tYXhMZW5ndGggOiBub3RoaW5nfVxuICAgICAgICAgIG1pbmxlbmd0aD0ke2hhc01pbkxlbmd0aCA/IHRoaXMubWluTGVuZ3RoIDogbm90aGluZ31cbiAgICAgICAgICBwbGFjZWhvbGRlcj0ke3RoaXMucGxhY2Vob2xkZXIgfHwgbm90aGluZ31cbiAgICAgICAgICA/cmVhZG9ubHk9JHt0aGlzLnJlYWRPbmx5fVxuICAgICAgICAgID9yZXF1aXJlZD0ke3RoaXMucmVxdWlyZWR9XG4gICAgICAgICAgcm93cz0ke3RoaXMucm93c31cbiAgICAgICAgICBjb2xzPSR7dGhpcy5jb2xzfVxuICAgICAgICAgIC52YWx1ZT0ke2xpdmUodGhpcy52YWx1ZSl9XG4gICAgICAgICAgQGNoYW5nZT0ke3RoaXMucmVkaXNwYXRjaEV2ZW50fVxuICAgICAgICAgIEBmb2N1cz0ke3RoaXMuaGFuZGxlRm9jdXNDaGFuZ2V9XG4gICAgICAgICAgQGJsdXI9JHt0aGlzLmhhbmRsZUZvY3VzQ2hhbmdlfVxuICAgICAgICAgIEBpbnB1dD0ke3RoaXMuaGFuZGxlSW5wdXR9XG4gICAgICAgICAgQHNlbGVjdD0ke3RoaXMucmVkaXNwYXRjaEV2ZW50fT48L3RleHRhcmVhPlxuICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcmVmaXggPSB0aGlzLnJlbmRlclByZWZpeCgpO1xuICAgICAgICBjb25zdCBzdWZmaXggPSB0aGlzLnJlbmRlclN1ZmZpeCgpO1xuICAgICAgICAvLyBUT0RPKGIvMjQzODA1ODQ4KTogcmVtb3ZlIGBhcyB1bmtub3duIGFzIG51bWJlcmAgYW5kIGBhcyBhbnlgIG9uY2UgbGl0XG4gICAgICAgIC8vIGFuYWx5emVyIGlzIGZpeGVkXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgICAgY29uc3QgaW5wdXRNb2RlID0gdGhpcy5pbnB1dE1vZGU7XG4gICAgICAgIHJldHVybiBodG1sIGBcbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC13cmFwcGVyXCI+XG4gICAgICAgICR7cHJlZml4fVxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBjbGFzcz1cImlucHV0XCJcbiAgICAgICAgICBzdHlsZT0ke3N0eWxlTWFwKHN0eWxlKX1cbiAgICAgICAgICBhcmlhLWRlc2NyaWJlZGJ5PVwiZGVzY3JpcHRpb25cIlxuICAgICAgICAgIGFyaWEtaW52YWxpZD0ke3RoaXMuaGFzRXJyb3J9XG4gICAgICAgICAgYXJpYS1sYWJlbD0ke2FyaWFMYWJlbH1cbiAgICAgICAgICBhdXRvY29tcGxldGU9JHthdXRvY29tcGxldGUgfHwgbm90aGluZ31cbiAgICAgICAgICBuYW1lPSR7dGhpcy5uYW1lIHx8IG5vdGhpbmd9XG4gICAgICAgICAgP2Rpc2FibGVkPSR7dGhpcy5kaXNhYmxlZH1cbiAgICAgICAgICBpbnB1dG1vZGU9JHtpbnB1dE1vZGUgfHwgbm90aGluZ31cbiAgICAgICAgICBtYXg9JHsodGhpcy5tYXggfHwgbm90aGluZyl9XG4gICAgICAgICAgbWF4bGVuZ3RoPSR7aGFzTWF4TGVuZ3RoID8gdGhpcy5tYXhMZW5ndGggOiBub3RoaW5nfVxuICAgICAgICAgIG1pbj0keyh0aGlzLm1pbiB8fCBub3RoaW5nKX1cbiAgICAgICAgICBtaW5sZW5ndGg9JHtoYXNNaW5MZW5ndGggPyB0aGlzLm1pbkxlbmd0aCA6IG5vdGhpbmd9XG4gICAgICAgICAgcGF0dGVybj0ke3RoaXMucGF0dGVybiB8fCBub3RoaW5nfVxuICAgICAgICAgIHBsYWNlaG9sZGVyPSR7dGhpcy5wbGFjZWhvbGRlciB8fCBub3RoaW5nfVxuICAgICAgICAgID9yZWFkb25seT0ke3RoaXMucmVhZE9ubHl9XG4gICAgICAgICAgP3JlcXVpcmVkPSR7dGhpcy5yZXF1aXJlZH1cbiAgICAgICAgICA/bXVsdGlwbGU9JHt0aGlzLm11bHRpcGxlfVxuICAgICAgICAgIHN0ZXA9JHsodGhpcy5zdGVwIHx8IG5vdGhpbmcpfVxuICAgICAgICAgIHR5cGU9JHt0aGlzLnR5cGV9XG4gICAgICAgICAgLnZhbHVlPSR7bGl2ZSh0aGlzLnZhbHVlKX1cbiAgICAgICAgICBAY2hhbmdlPSR7dGhpcy5yZWRpc3BhdGNoRXZlbnR9XG4gICAgICAgICAgQGZvY3VzPSR7dGhpcy5oYW5kbGVGb2N1c0NoYW5nZX1cbiAgICAgICAgICBAYmx1cj0ke3RoaXMuaGFuZGxlRm9jdXNDaGFuZ2V9XG4gICAgICAgICAgQGlucHV0PSR7dGhpcy5oYW5kbGVJbnB1dH1cbiAgICAgICAgICBAc2VsZWN0PSR7dGhpcy5yZWRpc3BhdGNoRXZlbnR9IC8+XG4gICAgICAgICR7c3VmZml4fVxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgICB9XG4gICAgcmVuZGVyUHJlZml4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXJBZmZpeCh0aGlzLnByZWZpeFRleHQsIC8qIGlzU3VmZml4ICovIGZhbHNlKTtcbiAgICB9XG4gICAgcmVuZGVyU3VmZml4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXJBZmZpeCh0aGlzLnN1ZmZpeFRleHQsIC8qIGlzU3VmZml4ICovIHRydWUpO1xuICAgIH1cbiAgICByZW5kZXJBZmZpeCh0ZXh0LCBpc1N1ZmZpeCkge1xuICAgICAgICBpZiAoIXRleHQpIHtcbiAgICAgICAgICAgIHJldHVybiBub3RoaW5nO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsYXNzZXMgPSB7XG4gICAgICAgICAgICAnc3VmZml4JzogaXNTdWZmaXgsXG4gICAgICAgICAgICAncHJlZml4JzogIWlzU3VmZml4LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gaHRtbCBgPHNwYW4gY2xhc3M9XCIke2NsYXNzTWFwKGNsYXNzZXMpfVwiPiR7dGV4dH08L3NwYW4+YDtcbiAgICB9XG4gICAgZ2V0RXJyb3JUZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lcnJvciA/IHRoaXMuZXJyb3JUZXh0IDogdGhpcy5uYXRpdmVFcnJvclRleHQ7XG4gICAgfVxuICAgIGhhbmRsZUZvY3VzQ2hhbmdlKCkge1xuICAgICAgICAvLyBXaGVuIGNhbGxpbmcgZm9jdXMoKSBvciByZXBvcnRWYWxpZGl0eSgpIGR1cmluZyBjaGFuZ2UsIGl0J3MgcG9zc2libGVcbiAgICAgICAgLy8gZm9yIGJsdXIgdG8gYmUgY2FsbGVkIGFmdGVyIHRoZSBuZXcgZm9jdXMgZXZlbnQuIFJhdGhlciB0aGFuIHNldFxuICAgICAgICAvLyBgdGhpcy5mb2N1c2VkYCB0byB0cnVlL2ZhbHNlIG9uIGZvY3VzL2JsdXIsIHdlIGFsd2F5cyBzZXQgaXQgdG8gd2hldGhlclxuICAgICAgICAvLyBvciBub3QgdGhlIGlucHV0IGl0c2VsZiBpcyBmb2N1c2VkLlxuICAgICAgICB0aGlzLmZvY3VzZWQgPSB0aGlzLmlucHV0T3JUZXh0YXJlYT8ubWF0Y2hlcygnOmZvY3VzJykgPz8gZmFsc2U7XG4gICAgfVxuICAgIGhhbmRsZUlucHV0KGV2ZW50KSB7XG4gICAgICAgIHRoaXMuZGlydHkgPSB0cnVlO1xuICAgICAgICB0aGlzLnZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIH1cbiAgICByZWRpc3BhdGNoRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgcmVkaXNwYXRjaEV2ZW50KHRoaXMsIGV2ZW50KTtcbiAgICB9XG4gICAgZ2V0SW5wdXRPclRleHRhcmVhKCkge1xuICAgICAgICBpZiAoIXRoaXMuaW5wdXRPclRleHRhcmVhKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5wdXQgaXMgbm90IHlldCBkZWZpbmVkLCBzeW5jaHJvbm91c2x5IHJlbmRlci5cbiAgICAgICAgICAgIC8vIGUuZy5cbiAgICAgICAgICAgIC8vIGNvbnN0IHRleHRGaWVsZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21kLW91dGxpbmVkLXRleHQtZmllbGQnKTtcbiAgICAgICAgICAgIC8vIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGV4dEZpZWxkKTtcbiAgICAgICAgICAgIC8vIHRleHRGaWVsZC5mb2N1cygpOyAvLyBzeW5jaHJvbm91c2x5IHJlbmRlclxuICAgICAgICAgICAgdGhpcy5jb25uZWN0ZWRDYWxsYmFjaygpO1xuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZVVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzVXBkYXRlUGVuZGluZykge1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIHBlbmRpbmcgdXBkYXRlcywgc3luY2hyb25vdXNseSBwZXJmb3JtIHRoZW0uIFRoaXMgZW5zdXJlc1xuICAgICAgICAgICAgLy8gdGhhdCBjb25zdHJhaW50IHZhbGlkYXRpb24gcHJvcGVydGllcyAobGlrZSBgcmVxdWlyZWRgKSBhcmUgc3luY2VkXG4gICAgICAgICAgICAvLyBiZWZvcmUgaW50ZXJhY3Rpbmcgd2l0aCBpbnB1dCBBUElzIHRoYXQgZGVwZW5kIG9uIHRoZW0uXG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlVXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXRPclRleHRhcmVhO1xuICAgIH1cbiAgICBnZXRJbnB1dCgpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3RleHRhcmVhJykge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW5wdXRPclRleHRhcmVhKCk7XG4gICAgfVxuICAgIGhhbmRsZUljb25DaGFuZ2UoKSB7XG4gICAgICAgIHRoaXMuaGFzTGVhZGluZ0ljb24gPSB0aGlzLmxlYWRpbmdJY29ucy5sZW5ndGggPiAwO1xuICAgICAgICB0aGlzLmhhc1RyYWlsaW5nSWNvbiA9IHRoaXMudHJhaWxpbmdJY29ucy5sZW5ndGggPiAwO1xuICAgIH1cbiAgICBbZ2V0Rm9ybVZhbHVlXSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gICAgfVxuICAgIGZvcm1SZXNldENhbGxiYWNrKCkge1xuICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgfVxuICAgIGZvcm1TdGF0ZVJlc3RvcmVDYWxsYmFjayhzdGF0ZSkge1xuICAgICAgICB0aGlzLnZhbHVlID0gc3RhdGU7XG4gICAgfVxuICAgIGZvY3VzKCkge1xuICAgICAgICAvLyBSZXF1aXJlZCBmb3IgdGhlIGNhc2UgdGhhdCB0aGUgdXNlciBzbG90cyBhIGZvY3VzYWJsZSBlbGVtZW50IGludG8gdGhlXG4gICAgICAgIC8vIGxlYWRpbmcgaWNvbiBzbG90IHN1Y2ggYXMgYW4gaWNvbmJ1dHRvbiBkdWUgdG8gaG93IGRlbGVnYXRlc0ZvY3VzIHdvcmtzLlxuICAgICAgICB0aGlzLmdldElucHV0T3JUZXh0YXJlYSgpLmZvY3VzKCk7XG4gICAgfVxuICAgIFtjcmVhdGVWYWxpZGF0b3JdKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRleHRGaWVsZFZhbGlkYXRvcigoKSA9PiAoe1xuICAgICAgICAgICAgc3RhdGU6IHRoaXMsXG4gICAgICAgICAgICByZW5kZXJlZENvbnRyb2w6IHRoaXMuaW5wdXRPclRleHRhcmVhLFxuICAgICAgICB9KSk7XG4gICAgfVxuICAgIFtnZXRWYWxpZGl0eUFuY2hvcl0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0T3JUZXh0YXJlYTtcbiAgICB9XG4gICAgW29uUmVwb3J0VmFsaWRpdHldKGludmFsaWRFdmVudCkge1xuICAgICAgICAvLyBQcmV2ZW50IGRlZmF1bHQgcG9wLXVwIGJlaGF2aW9yLlxuICAgICAgICBpbnZhbGlkRXZlbnQ/LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IHByZXZNZXNzYWdlID0gdGhpcy5nZXRFcnJvclRleHQoKTtcbiAgICAgICAgdGhpcy5uYXRpdmVFcnJvciA9ICEhaW52YWxpZEV2ZW50O1xuICAgICAgICB0aGlzLm5hdGl2ZUVycm9yVGV4dCA9IHRoaXMudmFsaWRhdGlvbk1lc3NhZ2U7XG4gICAgICAgIGlmIChwcmV2TWVzc2FnZSA9PT0gdGhpcy5nZXRFcnJvclRleHQoKSkge1xuICAgICAgICAgICAgdGhpcy5maWVsZD8ucmVhbm5vdW5jZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4vKiogQG5vY29sbGFwc2UgKi9cblRleHRGaWVsZC5zaGFkb3dSb290T3B0aW9ucyA9IHtcbiAgICAuLi5MaXRFbGVtZW50LnNoYWRvd1Jvb3RPcHRpb25zLFxuICAgIGRlbGVnYXRlc0ZvY3VzOiB0cnVlLFxufTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgcmVmbGVjdDogdHJ1ZSB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJlcnJvclwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyBhdHRyaWJ1dGU6ICdlcnJvci10ZXh0JyB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJlcnJvclRleHRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KClcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwibGFiZWxcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnbm8tYXN0ZXJpc2snIH0pXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcIm5vQXN0ZXJpc2tcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgcmVmbGVjdDogdHJ1ZSB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJyZXF1aXJlZFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoKVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJ2YWx1ZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyBhdHRyaWJ1dGU6ICdwcmVmaXgtdGV4dCcgfSlcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwicHJlZml4VGV4dFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyBhdHRyaWJ1dGU6ICdzdWZmaXgtdGV4dCcgfSlcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwic3VmZml4VGV4dFwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdoYXMtbGVhZGluZy1pY29uJyB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJoYXNMZWFkaW5nSWNvblwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdoYXMtdHJhaWxpbmctaWNvbicgfSlcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwiaGFzVHJhaWxpbmdJY29uXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IGF0dHJpYnV0ZTogJ3N1cHBvcnRpbmctdGV4dCcgfSlcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwic3VwcG9ydGluZ1RleHRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgYXR0cmlidXRlOiAndGV4dC1kaXJlY3Rpb24nIH0pXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcInRleHREaXJlY3Rpb25cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogTnVtYmVyIH0pXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcInJvd3NcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogTnVtYmVyIH0pXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcImNvbHNcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgcmVmbGVjdDogdHJ1ZSB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJpbnB1dE1vZGVcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KClcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwibWF4XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IE51bWJlciB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJtYXhMZW5ndGhcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KClcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwibWluXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHR5cGU6IE51bWJlciB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJtaW5MZW5ndGhcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnbm8tc3Bpbm5lcicgfSlcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwibm9TcGlubmVyXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcInBhdHRlcm5cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgcmVmbGVjdDogdHJ1ZSwgY29udmVydGVyOiBzdHJpbmdDb252ZXJ0ZXIgfSlcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwicGxhY2Vob2xkZXJcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgdHlwZTogQm9vbGVhbiwgcmVmbGVjdDogdHJ1ZSB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJyZWFkT25seVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoeyB0eXBlOiBCb29sZWFuLCByZWZsZWN0OiB0cnVlIH0pXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcIm11bHRpcGxlXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcInN0ZXBcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHByb3BlcnR5KHsgcmVmbGVjdDogdHJ1ZSB9KVxuXSwgVGV4dEZpZWxkLnByb3RvdHlwZSwgXCJ0eXBlXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSh7IHJlZmxlY3Q6IHRydWUgfSlcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwiYXV0b2NvbXBsZXRlXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcImRpcnR5XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcImZvY3VzZWRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwibmF0aXZlRXJyb3JcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwibmF0aXZlRXJyb3JUZXh0XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBxdWVyeSgnLmlucHV0Jylcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwiaW5wdXRPclRleHRhcmVhXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBxdWVyeSgnLmZpZWxkJylcbl0sIFRleHRGaWVsZC5wcm90b3R5cGUsIFwiZmllbGRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHF1ZXJ5QXNzaWduZWRFbGVtZW50cyh7IHNsb3Q6ICdsZWFkaW5nLWljb24nIH0pXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcImxlYWRpbmdJY29uc1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcXVlcnlBc3NpZ25lZEVsZW1lbnRzKHsgc2xvdDogJ3RyYWlsaW5nLWljb24nIH0pXG5dLCBUZXh0RmllbGQucHJvdG90eXBlLCBcInRyYWlsaW5nSWNvbnNcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRleHQtZmllbGQuanMubWFwIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBfYXRvYihzdHIpIHtcbiAgcmV0dXJuIGF0b2Ioc3RyKVxufVxuIiwiaW1wb3J0IHsgQ2hlY2tib3ggfSBmcm9tIFwiQG1hdGVyaWFsL3dlYi9jaGVja2JveC9pbnRlcm5hbC9jaGVja2JveC5qc1wiO1xuaW1wb3J0IHsgc3R5bGVzIH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvY2hlY2tib3gvaW50ZXJuYWwvY2hlY2tib3gtc3R5bGVzLmpzXCI7XG5leHBvcnQgY2xhc3MgRXdDaGVja2JveCBleHRlbmRzIENoZWNrYm94IHtcbn1cbkV3Q2hlY2tib3guc3R5bGVzID0gW3N0eWxlc107XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJldy1jaGVja2JveFwiLCBFd0NoZWNrYm94KTtcbiIsImltcG9ydCB7IENpcmN1bGFyUHJvZ3Jlc3MgfSBmcm9tIFwiQG1hdGVyaWFsL3dlYi9wcm9ncmVzcy9pbnRlcm5hbC9jaXJjdWxhci1wcm9ncmVzcy5qc1wiO1xuaW1wb3J0IHsgc3R5bGVzIH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvcHJvZ3Jlc3MvaW50ZXJuYWwvY2lyY3VsYXItcHJvZ3Jlc3Mtc3R5bGVzLmpzXCI7XG5leHBvcnQgY2xhc3MgRXdDaXJjdWxhclByb2dyZXNzIGV4dGVuZHMgQ2lyY3VsYXJQcm9ncmVzcyB7XG59XG5Fd0NpcmN1bGFyUHJvZ3Jlc3Muc3R5bGVzID0gW3N0eWxlc107XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJldy1jaXJjdWxhci1wcm9ncmVzc1wiLCBFd0NpcmN1bGFyUHJvZ3Jlc3MpO1xuIiwiaW1wb3J0IHsgRGl2aWRlciB9IGZyb20gXCJAbWF0ZXJpYWwvd2ViL2RpdmlkZXIvaW50ZXJuYWwvZGl2aWRlci5qc1wiO1xuaW1wb3J0IHsgc3R5bGVzIH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvZGl2aWRlci9pbnRlcm5hbC9kaXZpZGVyLXN0eWxlcy5qc1wiO1xuZXhwb3J0IGNsYXNzIEV3RGl2aWRlciBleHRlbmRzIERpdmlkZXIge1xufVxuRXdEaXZpZGVyLnN0eWxlcyA9IFtzdHlsZXNdO1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKFwiZXctZGl2aWRlclwiLCBFd0RpdmlkZXIpO1xuIiwiaW1wb3J0IHsgRmlsbGVkU2VsZWN0IH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvc2VsZWN0L2ludGVybmFsL2ZpbGxlZC1zZWxlY3QuanNcIjtcbmltcG9ydCB7IHN0eWxlcyB9IGZyb20gXCJAbWF0ZXJpYWwvd2ViL3NlbGVjdC9pbnRlcm5hbC9maWxsZWQtc2VsZWN0LXN0eWxlcy5qc1wiO1xuaW1wb3J0IHsgc3R5bGVzIGFzIHNoYXJlZFN0eWxlcyB9IGZyb20gXCJAbWF0ZXJpYWwvd2ViL3NlbGVjdC9pbnRlcm5hbC9zaGFyZWQtc3R5bGVzLmpzXCI7XG5leHBvcnQgY2xhc3MgRXdGaWxsZWRTZWxlY3QgZXh0ZW5kcyBGaWxsZWRTZWxlY3Qge1xufVxuRXdGaWxsZWRTZWxlY3Quc3R5bGVzID0gW3NoYXJlZFN0eWxlcywgc3R5bGVzXTtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZShcImV3LWZpbGxlZC1zZWxlY3RcIiwgRXdGaWxsZWRTZWxlY3QpO1xuIiwiaW1wb3J0IHsgc3R5bGVzIGFzIGZpbGxlZFN0eWxlcyB9IGZyb20gXCJAbWF0ZXJpYWwvd2ViL3RleHRmaWVsZC9pbnRlcm5hbC9maWxsZWQtc3R5bGVzLmpzXCI7XG5pbXBvcnQgeyBGaWxsZWRUZXh0RmllbGQgfSBmcm9tIFwiQG1hdGVyaWFsL3dlYi90ZXh0ZmllbGQvaW50ZXJuYWwvZmlsbGVkLXRleHQtZmllbGQuanNcIjtcbmltcG9ydCB7IHN0eWxlcyBhcyBzaGFyZWRTdHlsZXMgfSBmcm9tIFwiQG1hdGVyaWFsL3dlYi90ZXh0ZmllbGQvaW50ZXJuYWwvc2hhcmVkLXN0eWxlcy5qc1wiO1xuaW1wb3J0IHsgbGl0ZXJhbCB9IGZyb20gXCJsaXQvc3RhdGljLWh0bWwuanNcIjtcbmV4cG9ydCBjbGFzcyBFd0ZpbGxlZFRleHRGaWVsZCBleHRlbmRzIEZpbGxlZFRleHRGaWVsZCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuZmllbGRUYWcgPSBsaXRlcmFsIGBtZC1maWxsZWQtZmllbGRgO1xuICAgIH1cbn1cbkV3RmlsbGVkVGV4dEZpZWxkLnN0eWxlcyA9IFtzaGFyZWRTdHlsZXMsIGZpbGxlZFN0eWxlc107XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJldy1maWxsZWQtdGV4dC1maWVsZFwiLCBFd0ZpbGxlZFRleHRGaWVsZCk7XG4iLCJpbXBvcnQgeyBJY29uQnV0dG9uIH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvaWNvbmJ1dHRvbi9pbnRlcm5hbC9pY29uLWJ1dHRvbi5qc1wiO1xuaW1wb3J0IHsgc3R5bGVzIGFzIHNoYXJlZFN0eWxlcyB9IGZyb20gXCJAbWF0ZXJpYWwvd2ViL2ljb25idXR0b24vaW50ZXJuYWwvc2hhcmVkLXN0eWxlcy5qc1wiO1xuaW1wb3J0IHsgc3R5bGVzIH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvaWNvbmJ1dHRvbi9pbnRlcm5hbC9zdGFuZGFyZC1zdHlsZXMuanNcIjtcbmV4cG9ydCBjbGFzcyBFd0ljb25CdXR0b24gZXh0ZW5kcyBJY29uQnV0dG9uIHtcbn1cbkV3SWNvbkJ1dHRvbi5zdHlsZXMgPSBbc2hhcmVkU3R5bGVzLCBzdHlsZXNdO1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKFwiZXctaWNvbi1idXR0b25cIiwgRXdJY29uQnV0dG9uKTtcbiIsImltcG9ydCB7IExpc3RJdGVtRWwgYXMgTGlzdEl0ZW0gfSBmcm9tIFwiQG1hdGVyaWFsL3dlYi9saXN0L2ludGVybmFsL2xpc3RpdGVtL2xpc3QtaXRlbS5qc1wiO1xuaW1wb3J0IHsgc3R5bGVzIH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvbGlzdC9pbnRlcm5hbC9saXN0aXRlbS9saXN0LWl0ZW0tc3R5bGVzLmpzXCI7XG5leHBvcnQgY2xhc3MgRXdMaXN0SXRlbSBleHRlbmRzIExpc3RJdGVtIHtcbn1cbkV3TGlzdEl0ZW0uc3R5bGVzID0gW3N0eWxlc107XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJldy1saXN0LWl0ZW1cIiwgRXdMaXN0SXRlbSk7XG4iLCJpbXBvcnQgeyBMaXN0IH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvbGlzdC9pbnRlcm5hbC9saXN0LmpzXCI7XG5pbXBvcnQgeyBzdHlsZXMgfSBmcm9tIFwiQG1hdGVyaWFsL3dlYi9saXN0L2ludGVybmFsL2xpc3Qtc3R5bGVzLmpzXCI7XG5leHBvcnQgY2xhc3MgRXdMaXN0IGV4dGVuZHMgTGlzdCB7XG59XG5Fd0xpc3Quc3R5bGVzID0gW3N0eWxlc107XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJldy1saXN0XCIsIEV3TGlzdCk7XG4iLCJpbXBvcnQgeyBzdHlsZXMgfSBmcm9tIFwiQG1hdGVyaWFsL3dlYi9tZW51L2ludGVybmFsL21lbnVpdGVtL21lbnUtaXRlbS1zdHlsZXMuanNcIjtcbmltcG9ydCB7IFNlbGVjdE9wdGlvbkVsIH0gZnJvbSBcIkBtYXRlcmlhbC93ZWIvc2VsZWN0L2ludGVybmFsL3NlbGVjdG9wdGlvbi9zZWxlY3Qtb3B0aW9uLmpzXCI7XG5leHBvcnQgY2xhc3MgRXdTZWxlY3RPcHRpb24gZXh0ZW5kcyBTZWxlY3RPcHRpb25FbCB7XG59XG5Fd1NlbGVjdE9wdGlvbi5zdHlsZXMgPSBbc3R5bGVzXTtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZShcImV3LXNlbGVjdC1vcHRpb25cIiwgRXdTZWxlY3RPcHRpb24pO1xuIiwiaW1wb3J0IHsgQ29sb3JlZENvbnNvbGUsIGNvbG9yZWRDb25zb2xlU3R5bGVzIH0gZnJvbSBcIi4uL3V0aWwvY29uc29sZS1jb2xvclwiO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tIFwiLi4vdXRpbC9zbGVlcFwiO1xuaW1wb3J0IHsgTGluZUJyZWFrVHJhbnNmb3JtZXIgfSBmcm9tIFwiLi4vdXRpbC9saW5lLWJyZWFrLXRyYW5zZm9ybWVyXCI7XG5pbXBvcnQgeyBUaW1lc3RhbXBUcmFuc2Zvcm1lciB9IGZyb20gXCIuLi91dGlsL3RpbWVzdGFtcC10cmFuc2Zvcm1lclwiO1xuZXhwb3J0IGNsYXNzIEV3dENvbnNvbGUgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuYWxsb3dJbnB1dCA9IHRydWU7XG4gICAgfVxuICAgIGxvZ3MoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgcmV0dXJuICgoX2EgPSB0aGlzLl9jb25zb2xlKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EubG9ncygpKSB8fCBcIlwiO1xuICAgIH1cbiAgICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2NvbnNvbGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzaGFkb3dSb290ID0gdGhpcy5hdHRhY2hTaGFkb3coeyBtb2RlOiBcIm9wZW5cIiB9KTtcbiAgICAgICAgc2hhZG93Um9vdC5pbm5lckhUTUwgPSBgXG4gICAgICA8c3R5bGU+XG4gICAgICAgIDpob3N0LCBpbnB1dCB7XG4gICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzFjMWMxYztcbiAgICAgICAgICBjb2xvcjogI2RkZDtcbiAgICAgICAgICBmb250LWZhbWlseTogXCJTRk1vbm8tUmVndWxhclwiLCBDb25zb2xhcywgXCJMaWJlcmF0aW9uIE1vbm9cIiwgTWVubG8sIENvdXJpZXIsXG4gICAgICAgICAgICBtb25vc3BhY2U7XG4gICAgICAgICAgbGluZS1oZWlnaHQ6IDEuNDU7XG4gICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICB9XG4gICAgICAgIGZvcm0ge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgICBwYWRkaW5nOiAwIDhweCAwIDE2cHg7XG4gICAgICAgIH1cbiAgICAgICAgaW5wdXQge1xuICAgICAgICAgIGZsZXg6IDE7XG4gICAgICAgICAgcGFkZGluZzogNHB4O1xuICAgICAgICAgIG1hcmdpbjogMCA4cHg7XG4gICAgICAgICAgYm9yZGVyOiAwO1xuICAgICAgICAgIG91dGxpbmU6IG5vbmU7XG4gICAgICAgIH1cbiAgICAgICAgJHtjb2xvcmVkQ29uc29sZVN0eWxlc31cbiAgICAgIDwvc3R5bGU+XG4gICAgICA8ZGl2IGNsYXNzPVwibG9nXCI+PC9kaXY+XG4gICAgICAke3RoaXMuYWxsb3dJbnB1dFxuICAgICAgICAgICAgPyBgPGZvcm0+XG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBhdXRvZm9jdXM+XG4gICAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICAgIGBcbiAgICAgICAgICAgIDogXCJcIn1cbiAgICBgO1xuICAgICAgICB0aGlzLl9jb25zb2xlID0gbmV3IENvbG9yZWRDb25zb2xlKHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKFwiZGl2XCIpKTtcbiAgICAgICAgaWYgKHRoaXMuYWxsb3dJbnB1dCkge1xuICAgICAgICAgICAgY29uc3QgaW5wdXQgPSB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihcImlucHV0XCIpO1xuICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgICAgICAvLyBPbmx5IGZvY3VzIGlucHV0IGlmIHVzZXIgZGlkbid0IHNlbGVjdCBzb21lIHRleHRcbiAgICAgICAgICAgICAgICBpZiAoKChfYSA9IGdldFNlbGVjdGlvbigpKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EudG9TdHJpbmcoKSkgPT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIChldikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChldi5rZXkgPT09IFwiRW50ZXJcIikge1xuICAgICAgICAgICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VuZENvbW1hbmQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLl9jb25uZWN0KGFib3J0Q29udHJvbGxlci5zaWduYWwpO1xuICAgICAgICB0aGlzLl9jYW5jZWxDb25uZWN0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgYWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgICAgICAgICByZXR1cm4gY29ubmVjdGlvbjtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgX2Nvbm5lY3QoYWJvcnRTaWduYWwpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXCJTdGFydGluZyBjb25zb2xlIHJlYWQgbG9vcFwiKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucG9ydFxuICAgICAgICAgICAgICAgIC5yZWFkYWJsZS5waXBlVGhyb3VnaChuZXcgVGV4dERlY29kZXJTdHJlYW0oKSwge1xuICAgICAgICAgICAgICAgIHNpZ25hbDogYWJvcnRTaWduYWwsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5waXBlVGhyb3VnaChuZXcgVHJhbnNmb3JtU3RyZWFtKG5ldyBMaW5lQnJlYWtUcmFuc2Zvcm1lcigpKSlcbiAgICAgICAgICAgICAgICAucGlwZVRocm91Z2gobmV3IFRyYW5zZm9ybVN0cmVhbShuZXcgVGltZXN0YW1wVHJhbnNmb3JtZXIoKSkpXG4gICAgICAgICAgICAgICAgLnBpcGVUbyhuZXcgV3JpdGFibGVTdHJlYW0oe1xuICAgICAgICAgICAgICAgIHdyaXRlOiAoY2h1bmspID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29uc29sZS5hZGRMaW5lKGNodW5rLnJlcGxhY2UoXCJcXHJcIiwgXCJcIikpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBpZiAoIWFib3J0U2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25zb2xlLmFkZExpbmUoXCJcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5fY29uc29sZS5hZGRMaW5lKFwiXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvbnNvbGUuYWRkTGluZShcIlRlcm1pbmFsIGRpc2Nvbm5lY3RlZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhpcy5fY29uc29sZS5hZGRMaW5lKFwiXCIpO1xuICAgICAgICAgICAgdGhpcy5fY29uc29sZS5hZGRMaW5lKFwiXCIpO1xuICAgICAgICAgICAgdGhpcy5fY29uc29sZS5hZGRMaW5lKGBUZXJtaW5hbCBkaXNjb25uZWN0ZWQ6ICR7ZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGF3YWl0IHNsZWVwKDEwMCk7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcIkZpbmlzaGVkIGNvbnNvbGUgcmVhZCBsb29wXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIF9zZW5kQ29tbWFuZCgpIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihcImlucHV0XCIpO1xuICAgICAgICBjb25zdCBjb21tYW5kID0gaW5wdXQudmFsdWU7XG4gICAgICAgIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICAgICAgY29uc3Qgd3JpdGVyID0gdGhpcy5wb3J0LndyaXRhYmxlLmdldFdyaXRlcigpO1xuICAgICAgICBhd2FpdCB3cml0ZXIud3JpdGUoZW5jb2Rlci5lbmNvZGUoY29tbWFuZCArIFwiXFxyXFxuXCIpKTtcbiAgICAgICAgdGhpcy5fY29uc29sZS5hZGRMaW5lKGA+ICR7Y29tbWFuZH1cXHJcXG5gKTtcbiAgICAgICAgaW5wdXQudmFsdWUgPSBcIlwiO1xuICAgICAgICBpbnB1dC5mb2N1cygpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgd3JpdGVyLnJlbGVhc2VMb2NrKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIklnbm9yaW5nIHJlbGVhc2UgbG9jayBlcnJvclwiLCBlcnIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIGRpc2Nvbm5lY3QoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jYW5jZWxDb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9jYW5jZWxDb25uZWN0aW9uKCk7XG4gICAgICAgICAgICB0aGlzLl9jYW5jZWxDb25uZWN0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHJlc2V0KCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcIlRyaWdnZXJpbmcgcmVzZXRcIik7XG4gICAgICAgIGF3YWl0IHRoaXMucG9ydC5zZXRTaWduYWxzKHtcbiAgICAgICAgICAgIGRhdGFUZXJtaW5hbFJlYWR5OiBmYWxzZSxcbiAgICAgICAgICAgIHJlcXVlc3RUb1NlbmQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBzbGVlcCgyNTApO1xuICAgICAgICBhd2FpdCB0aGlzLnBvcnQuc2V0U2lnbmFscyh7XG4gICAgICAgICAgICBkYXRhVGVybWluYWxSZWFkeTogZmFsc2UsXG4gICAgICAgICAgICByZXF1ZXN0VG9TZW5kOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDI1MCk7XG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDEwMDApKTtcbiAgICB9XG59XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJld3QtY29uc29sZVwiLCBFd3RDb25zb2xlKTtcbiIsImltcG9ydCB7IHN2ZyB9IGZyb20gXCJsaXRcIjtcbmV4cG9ydCBjb25zdCBjbG9zZUljb24gPSBzdmcgYFxuICA8c3ZnIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj5cbiAgICA8cGF0aFxuICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiXG4gICAgICBkPVwiTTE5LDYuNDFMMTcuNTksNUwxMiwxMC41OUw2LjQxLDVMNSw2LjQxTDEwLjU5LDEyTDUsMTcuNTlMNi40MSwxOUwxMiwxMy40MUwxNy41OSwxOUwxOSwxNy41OUwxMy40MSwxMkwxOSw2LjQxWlwiXG4gICAgLz5cbiAgPC9zdmc+XG5gO1xuZXhwb3J0IGNvbnN0IHJlZnJlc2hJY29uID0gc3ZnIGBcbiAgPHN2ZyB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgPHBhdGhcbiAgICAgIGZpbGw9XCJjdXJyZW50Q29sb3JcIlxuICAgICAgZD1cIk0xNy42NSw2LjM1QzE2LjIsNC45IDE0LjIxLDQgMTIsNEE4LDggMCAwLDAgNCwxMkE4LDggMCAwLDAgMTIsMjBDMTUuNzMsMjAgMTguODQsMTcuNDUgMTkuNzMsMTRIMTcuNjVDMTYuODMsMTYuMzMgMTQuNjEsMTggMTIsMThBNiw2IDAgMCwxIDYsMTJBNiw2IDAgMCwxIDEyLDZDMTMuNjYsNiAxNS4xNCw2LjY5IDE2LjIyLDcuNzhMMTMsMTFIMjBWNEwxNy42NSw2LjM1WlwiXG4gICAgLz5cbiAgPC9zdmc+XG5gO1xuZXhwb3J0IGNvbnN0IGxpc3RJdGVtSW5zdGFsbEljb24gPSBzdmcgYFxuICA8c3ZnIHNsb3Q9XCJzdGFydFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj5cbiAgICA8cGF0aCBkPVwiTTUsMjBIMTlWMThINU0xOSw5SDE1VjNIOVY5SDVMMTIsMTZMMTksOVpcIiAvPlxuICA8L3N2Zz5cbmA7XG5leHBvcnQgY29uc3QgbGlzdEl0ZW1XaWZpID0gc3ZnIGBcbiAgPHN2ZyBzbG90PVwic3RhcnRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgPHBhdGggZD1cIk0xMiwyMUwxNS42LDE2LjJDMTQuNiwxNS40NSAxMy4zNSwxNSAxMiwxNUMxMC42NSwxNSA5LjQsMTUuNDUgOC40LDE2LjJMMTIsMjFNMTIsM0M3Ljk1LDMgNC4yMSw0LjM0IDEuMiw2LjZMMyw5QzUuNSw3LjEyIDguNjIsNiAxMiw2QzE1LjM4LDYgMTguNSw3LjEyIDIxLDlMMjIuOCw2LjZDMTkuNzksNC4zNCAxNi4wNSwzIDEyLDNNMTIsOUM5LjMsOSA2LjgxLDkuODkgNC44LDExLjRMNi42LDEzLjhDOC4xLDEyLjY3IDkuOTcsMTIgMTIsMTJDMTQuMDMsMTIgMTUuOSwxMi42NyAxNy40LDEzLjhMMTkuMiwxMS40QzE3LjE5LDkuODkgMTQuNyw5IDEyLDlaXCIgLz5cbiAgPC9zdmc+XG5gO1xuZXhwb3J0IGNvbnN0IGxpc3RJdGVtQ29uc29sZSA9IHN2ZyBgXG4gIDxzdmcgc2xvdD1cInN0YXJ0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPlxuICAgIDxwYXRoIGQ9XCJNMjAsMTlWN0g0VjE5SDIwTTIwLDNBMiwyIDAgMCwxIDIyLDVWMTlBMiwyIDAgMCwxIDIwLDIxSDRBMiwyIDAgMCwxIDIsMTlWNUMyLDMuODkgMi45LDMgNCwzSDIwTTEzLDE3VjE1SDE4VjE3SDEzTTkuNTgsMTNMNS41Nyw5SDguNEwxMS43LDEyLjNDMTIuMDksMTIuNjkgMTIuMDksMTMuMzMgMTEuNywxMy43Mkw4LjQyLDE3SDUuNTlMOS41OCwxM1pcIiAvPlxuICA8L3N2Zz5cbmA7XG5leHBvcnQgY29uc3QgbGlzdEl0ZW1WaXNpdERldmljZSA9IHN2ZyBgXG4gIDxzdmcgc2xvdD1cInN0YXJ0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPlxuICA8cGF0aCBkPVwiTTE2LjM2LDE0QzE2LjQ0LDEzLjM0IDE2LjUsMTIuNjggMTYuNSwxMkMxNi41LDExLjMyIDE2LjQ0LDEwLjY2IDE2LjM2LDEwSDE5Ljc0QzE5LjksMTAuNjQgMjAsMTEuMzEgMjAsMTJDMjAsMTIuNjkgMTkuOSwxMy4zNiAxOS43NCwxNE0xNC41OSwxOS41NkMxNS4xOSwxOC40NSAxNS42NSwxNy4yNSAxNS45NywxNkgxOC45MkMxNy45NiwxNy42NSAxNi40MywxOC45MyAxNC41OSwxOS41Nk0xNC4zNCwxNEg5LjY2QzkuNTYsMTMuMzQgOS41LDEyLjY4IDkuNSwxMkM5LjUsMTEuMzIgOS41NiwxMC42NSA5LjY2LDEwSDE0LjM0QzE0LjQzLDEwLjY1IDE0LjUsMTEuMzIgMTQuNSwxMkMxNC41LDEyLjY4IDE0LjQzLDEzLjM0IDE0LjM0LDE0TTEyLDE5Ljk2QzExLjE3LDE4Ljc2IDEwLjUsMTcuNDMgMTAuMDksMTZIMTMuOTFDMTMuNSwxNy40MyAxMi44MywxOC43NiAxMiwxOS45Nk04LDhINS4wOEM2LjAzLDYuMzQgNy41Nyw1LjA2IDkuNCw0LjQ0QzguOCw1LjU1IDguMzUsNi43NSA4LDhNNS4wOCwxNkg4QzguMzUsMTcuMjUgOC44LDE4LjQ1IDkuNCwxOS41NkM3LjU3LDE4LjkzIDYuMDMsMTcuNjUgNS4wOCwxNk00LjI2LDE0QzQuMSwxMy4zNiA0LDEyLjY5IDQsMTJDNCwxMS4zMSA0LjEsMTAuNjQgNC4yNiwxMEg3LjY0QzcuNTYsMTAuNjYgNy41LDExLjMyIDcuNSwxMkM3LjUsMTIuNjggNy41NiwxMy4zNCA3LjY0LDE0TTEyLDQuMDNDMTIuODMsNS4yMyAxMy41LDYuNTcgMTMuOTEsOEgxMC4wOUMxMC41LDYuNTcgMTEuMTcsNS4yMyAxMiw0LjAzTTE4LjkyLDhIMTUuOTdDMTUuNjUsNi43NSAxNS4xOSw1LjU1IDE0LjU5LDQuNDRDMTYuNDMsNS4wNyAxNy45Niw2LjM0IDE4LjkyLDhNMTIsMkM2LjQ3LDIgMiw2LjUgMiwxMkExMCwxMCAwIDAsMCAxMiwyMkExMCwxMCAwIDAsMCAyMiwxMkExMCwxMCAwIDAsMCAxMiwyWlwiIC8+XG4gIDwvc3ZnPlxuYDtcbmV4cG9ydCBjb25zdCBsaXN0SXRlbUhvbWVBc3Npc3RhbnQgPSBzdmcgYFxuICA8c3ZnIHNsb3Q9XCJzdGFydFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj5cbiAgICA8cGF0aCBkPVwibTEyLjE1MSAxLjU4ODJjLS4zMjYyIDAtLjY1MjMuMTI5MS0uODk5Ni4zODY3bC04LjM4NDggOC43MzU0Yy0uMDYxOS4wNjQ0LS4xMjIzLjEzNjgtLjE4MDcuMjE1NC0uMDU4OC4wNzg5LS4xMTUxLjE2MzgtLjE2ODguMjUzNC0uMjU5My40MzI1LS40NTUyLjk3NDktLjUyMzIgMS40NTU1LS4wMDI2LjAxOC0uMDA3Ni4wMzY5LS4wMDk0LjA1NDgtLjAxMjEuMDk4Ny0uMDE4NC4xOTQ0LS4wMTg0LjI4NTd2OC4wMTI0YTEuMjczMSAxLjI3MzEgMCAwMDEuMjczMSAxLjI3MzFoNy44MzEzbC0zLjQ0ODQtMy41OTNhMS43Mzk5IDEuNzM5OSAwIDExMS4wODAzLTEuMTI1bDIuNjg0NyAyLjc5NzJ2LTEwLjI0OGExLjczOTkgMS43Mzk5IDAgMTExLjUyNzYtMHY3LjE4N2wyLjY3MDItMi43ODJhMS43Mzk5IDEuNzM5OSAwIDExMS4wNTY2IDEuMTUwNWwtMy43MjY5IDMuODgzMXYyLjcyOTloOC4xNzRhMS4yNDcxIDEuMjQ3MSAwIDAwMS4yNDcxLTEuMjQ3MXYtOC4wMzc1YzAtLjA5MTItLjAwNTktLjE4NjgtLjAxODQtLjI4NTUtLjA2MDMtLjQ5MzUtLjI2MzYtMS4wNjE3LS41MzI2LTEuNTEwNS0uMDUzNy0uMDg5Ni0uMTEwMS0uMTc0NS0uMTY4NC0uMjUzLS4wNTg4LS4wNzktLjExOTEtLjE1MTMtLjE4MS0uMjE1OGwtOC4zODQ4LTguNzM2M2MtLjI0NzMtLjI1NzctLjU3MzUtLjM4NjYtLjg5OTUtLjM4NjRcIiAvPlxuICA8L3N2Zz5cbmA7XG5leHBvcnQgY29uc3QgbGlzdEl0ZW1FcmFzZVVzZXJEYXRhID0gc3ZnIGBcbiAgPHN2ZyBzbG90PVwic3RhcnRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgPHBhdGggZD1cIk0xNSwxNEMxNy42NywxNCAyMywxNS4zMyAyMywxOFYyMEg3VjE4QzcsMTUuMzMgMTIuMzMsMTQgMTUsMTRNMTUsMTJBNCw0IDAgMCwxIDExLDhBNCw0IDAgMCwxIDE1LDRBNCw0IDAgMCwxIDE5LDhBNCw0IDAgMCwxIDE1LDEyTTUsOS41OUw3LjEyLDcuNDZMOC41NCw4Ljg4TDYuNDEsMTFMOC41NCwxMy4xMkw3LjEyLDE0LjU0TDUsMTIuNDFMMi44OCwxNC41NEwxLjQ2LDEzLjEyTDMuNTksMTFMMS40Niw4Ljg4TDIuODgsNy40Nkw1LDkuNTlaXCIgLz5cbiAgPC9zdmc+XG5gO1xuZXhwb3J0IGNvbnN0IGxpc3RJdGVtRnVuZERldmVsb3BtZW50ID0gc3ZnIGBcbiAgPHN2ZyBzbG90PVwic3RhcnRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCI+XG4gICAgPHBhdGggZD1cIk0xMiwyMS4zNUwxMC41NSwyMC4wM0M1LjQsMTUuMzYgMiwxMi4yNyAyLDguNUMyLDUuNDEgNC40MiwzIDcuNSwzQzkuMjQsMyAxMC45MSwzLjgxIDEyLDUuMDhDMTMuMDksMy44MSAxNC43NiwzIDE2LjUsM0MxOS41OCwzIDIyLDUuNDEgMjIsOC41QzIyLDEyLjI3IDE4LjYsMTUuMzYgMTMuNDUsMjAuMDNMMTIsMjEuMzVaXCIgLz5cbiAgPC9zdmc+XG5gO1xuIiwiaW1wb3J0IHsgVHJhbnNwb3J0LCBFU1BMb2FkZXIgfSBmcm9tIFwiZXNwdG9vbC1qc1wiO1xuaW1wb3J0IHsgaGFyZFJlc2V0IH0gZnJvbSBcIi4vdXRpbC9yZXNldFwiO1xuZXhwb3J0IGNvbnN0IGZsYXNoID0gYXN5bmMgKG9uRXZlbnQsIHBvcnQsIG1hbmlmZXN0UGF0aCwgbWFuaWZlc3QsIGVyYXNlRmlyc3QpID0+IHtcbiAgICBsZXQgYnVpbGQ7XG4gICAgbGV0IGNoaXBGYW1pbHk7XG4gICAgY29uc3QgZmlyZVN0YXRlRXZlbnQgPSAoc3RhdGVVcGRhdGUpID0+IG9uRXZlbnQoe1xuICAgICAgICAuLi5zdGF0ZVVwZGF0ZSxcbiAgICAgICAgbWFuaWZlc3QsXG4gICAgICAgIGJ1aWxkLFxuICAgICAgICBjaGlwRmFtaWx5LFxuICAgIH0pO1xuICAgIGNvbnN0IHRyYW5zcG9ydCA9IG5ldyBUcmFuc3BvcnQocG9ydCk7XG4gICAgY29uc3QgZXNwbG9hZGVyID0gbmV3IEVTUExvYWRlcih7XG4gICAgICAgIHRyYW5zcG9ydCxcbiAgICAgICAgYmF1ZHJhdGU6IDExNTIwMCxcbiAgICAgICAgcm9tQmF1ZHJhdGU6IDExNTIwMCxcbiAgICAgICAgZW5hYmxlVHJhY2luZzogZmFsc2UsXG4gICAgfSk7XG4gICAgLy8gRm9yIGRlYnVnZ2luZ1xuICAgIHdpbmRvdy5lc3Bsb2FkZXIgPSBlc3Bsb2FkZXI7XG4gICAgZmlyZVN0YXRlRXZlbnQoe1xuICAgICAgICBzdGF0ZTogXCJpbml0aWFsaXppbmdcIiAvKiBGbGFzaFN0YXRlVHlwZS5JTklUSUFMSVpJTkcgKi8sXG4gICAgICAgIG1lc3NhZ2U6IFwiSW5pdGlhbGl6aW5nLi4uXCIsXG4gICAgICAgIGRldGFpbHM6IHsgZG9uZTogZmFsc2UgfSxcbiAgICB9KTtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBlc3Bsb2FkZXIubWFpbigpO1xuICAgICAgICBhd2FpdCBlc3Bsb2FkZXIuZmxhc2hJZCgpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgZmlyZVN0YXRlRXZlbnQoe1xuICAgICAgICAgICAgc3RhdGU6IFwiZXJyb3JcIiAvKiBGbGFzaFN0YXRlVHlwZS5FUlJPUiAqLyxcbiAgICAgICAgICAgIG1lc3NhZ2U6IFwiRmFpbGVkIHRvIGluaXRpYWxpemUuIFRyeSByZXNldHRpbmcgeW91ciBkZXZpY2Ugb3IgaG9sZGluZyB0aGUgQk9PVCBidXR0b24gd2hpbGUgY2xpY2tpbmcgSU5TVEFMTC5cIixcbiAgICAgICAgICAgIGRldGFpbHM6IHsgZXJyb3I6IFwiZmFpbGVkX2luaXRpYWxpemVcIiAvKiBGbGFzaEVycm9yLkZBSUxFRF9JTklUSUFMSVpJTkcgKi8sIGRldGFpbHM6IGVyciB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgaGFyZFJlc2V0KHRyYW5zcG9ydCk7XG4gICAgICAgIGF3YWl0IHRyYW5zcG9ydC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY2hpcEZhbWlseSA9IGVzcGxvYWRlci5jaGlwLkNISVBfTkFNRTtcbiAgICBmaXJlU3RhdGVFdmVudCh7XG4gICAgICAgIHN0YXRlOiBcImluaXRpYWxpemluZ1wiIC8qIEZsYXNoU3RhdGVUeXBlLklOSVRJQUxJWklORyAqLyxcbiAgICAgICAgbWVzc2FnZTogYEluaXRpYWxpemVkLiBGb3VuZCAke2NoaXBGYW1pbHl9YCxcbiAgICAgICAgZGV0YWlsczogeyBkb25lOiB0cnVlIH0sXG4gICAgfSk7XG4gICAgYnVpbGQgPSBtYW5pZmVzdC5idWlsZHMuZmluZCgoYikgPT4gYi5jaGlwRmFtaWx5ID09PSBjaGlwRmFtaWx5KTtcbiAgICBpZiAoIWJ1aWxkKSB7XG4gICAgICAgIGZpcmVTdGF0ZUV2ZW50KHtcbiAgICAgICAgICAgIHN0YXRlOiBcImVycm9yXCIgLyogRmxhc2hTdGF0ZVR5cGUuRVJST1IgKi8sXG4gICAgICAgICAgICBtZXNzYWdlOiBgWW91ciAke2NoaXBGYW1pbHl9IGJvYXJkIGlzIG5vdCBzdXBwb3J0ZWQuYCxcbiAgICAgICAgICAgIGRldGFpbHM6IHsgZXJyb3I6IFwibm90X3N1cHBvcnRlZFwiIC8qIEZsYXNoRXJyb3IuTk9UX1NVUFBPUlRFRCAqLywgZGV0YWlsczogY2hpcEZhbWlseSB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgaGFyZFJlc2V0KHRyYW5zcG9ydCk7XG4gICAgICAgIGF3YWl0IHRyYW5zcG9ydC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZmlyZVN0YXRlRXZlbnQoe1xuICAgICAgICBzdGF0ZTogXCJwcmVwYXJpbmdcIiAvKiBGbGFzaFN0YXRlVHlwZS5QUkVQQVJJTkcgKi8sXG4gICAgICAgIG1lc3NhZ2U6IFwiUHJlcGFyaW5nIGluc3RhbGxhdGlvbi4uLlwiLFxuICAgICAgICBkZXRhaWxzOiB7IGRvbmU6IGZhbHNlIH0sXG4gICAgfSk7XG4gICAgY29uc3QgbWFuaWZlc3RVUkwgPSBuZXcgVVJMKG1hbmlmZXN0UGF0aCwgbG9jYXRpb24udG9TdHJpbmcoKSkudG9TdHJpbmcoKTtcbiAgICBjb25zdCBmaWxlUHJvbWlzZXMgPSBidWlsZC5wYXJ0cy5tYXAoYXN5bmMgKHBhcnQpID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTChwYXJ0LnBhdGgsIG1hbmlmZXN0VVJMKS50b1N0cmluZygpO1xuICAgICAgICBjb25zdCByZXNwID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICAgICAgaWYgKCFyZXNwLm9rKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERvd25sYWRpbmcgZmlybXdhcmUgJHtwYXJ0LnBhdGh9IGZhaWxlZDogJHtyZXNwLnN0YXR1c31gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgICBjb25zdCBibG9iID0gYXdhaXQgcmVzcC5ibG9iKCk7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgcmVhZGVyLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsICgpID0+IHJlc29sdmUocmVhZGVyLnJlc3VsdCkpO1xuICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhibG9iKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgY29uc3QgZmlsZUFycmF5ID0gW107XG4gICAgbGV0IHRvdGFsU2l6ZSA9IDA7XG4gICAgZm9yIChsZXQgcGFydCA9IDA7IHBhcnQgPCBmaWxlUHJvbWlzZXMubGVuZ3RoOyBwYXJ0KyspIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBmaWxlUHJvbWlzZXNbcGFydF07XG4gICAgICAgICAgICBmaWxlQXJyYXkucHVzaCh7IGRhdGEsIGFkZHJlc3M6IGJ1aWxkLnBhcnRzW3BhcnRdLm9mZnNldCB9KTtcbiAgICAgICAgICAgIHRvdGFsU2l6ZSArPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBmaXJlU3RhdGVFdmVudCh7XG4gICAgICAgICAgICAgICAgc3RhdGU6IFwiZXJyb3JcIiAvKiBGbGFzaFN0YXRlVHlwZS5FUlJPUiAqLyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiBcImZhaWxlZF9maXJtd2FyZV9kb3dubG9hZFwiIC8qIEZsYXNoRXJyb3IuRkFJTEVEX0ZJUk1XQVJFX0RPV05MT0FEICovLFxuICAgICAgICAgICAgICAgICAgICBkZXRhaWxzOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhd2FpdCBoYXJkUmVzZXQodHJhbnNwb3J0KTtcbiAgICAgICAgICAgIGF3YWl0IHRyYW5zcG9ydC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9XG4gICAgZmlyZVN0YXRlRXZlbnQoe1xuICAgICAgICBzdGF0ZTogXCJwcmVwYXJpbmdcIiAvKiBGbGFzaFN0YXRlVHlwZS5QUkVQQVJJTkcgKi8sXG4gICAgICAgIG1lc3NhZ2U6IFwiSW5zdGFsbGF0aW9uIHByZXBhcmVkXCIsXG4gICAgICAgIGRldGFpbHM6IHsgZG9uZTogdHJ1ZSB9LFxuICAgIH0pO1xuICAgIGlmIChlcmFzZUZpcnN0KSB7XG4gICAgICAgIGZpcmVTdGF0ZUV2ZW50KHtcbiAgICAgICAgICAgIHN0YXRlOiBcImVyYXNpbmdcIiAvKiBGbGFzaFN0YXRlVHlwZS5FUkFTSU5HICovLFxuICAgICAgICAgICAgbWVzc2FnZTogXCJFcmFzaW5nIGRldmljZS4uLlwiLFxuICAgICAgICAgICAgZGV0YWlsczogeyBkb25lOiBmYWxzZSB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgZXNwbG9hZGVyLmVyYXNlRmxhc2goKTtcbiAgICAgICAgZmlyZVN0YXRlRXZlbnQoe1xuICAgICAgICAgICAgc3RhdGU6IFwiZXJhc2luZ1wiIC8qIEZsYXNoU3RhdGVUeXBlLkVSQVNJTkcgKi8sXG4gICAgICAgICAgICBtZXNzYWdlOiBcIkRldmljZSBlcmFzZWRcIixcbiAgICAgICAgICAgIGRldGFpbHM6IHsgZG9uZTogdHJ1ZSB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZmlyZVN0YXRlRXZlbnQoe1xuICAgICAgICBzdGF0ZTogXCJ3cml0aW5nXCIgLyogRmxhc2hTdGF0ZVR5cGUuV1JJVElORyAqLyxcbiAgICAgICAgbWVzc2FnZTogYFdyaXRpbmcgcHJvZ3Jlc3M6IDAlYCxcbiAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgICAgYnl0ZXNUb3RhbDogdG90YWxTaXplLFxuICAgICAgICAgICAgYnl0ZXNXcml0dGVuOiAwLFxuICAgICAgICAgICAgcGVyY2VudGFnZTogMCxcbiAgICAgICAgfSxcbiAgICB9KTtcbiAgICBsZXQgdG90YWxXcml0dGVuID0gMDtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBlc3Bsb2FkZXIud3JpdGVGbGFzaCh7XG4gICAgICAgICAgICBmaWxlQXJyYXksXG4gICAgICAgICAgICBmbGFzaFNpemU6IFwia2VlcFwiLFxuICAgICAgICAgICAgZmxhc2hNb2RlOiBcImtlZXBcIixcbiAgICAgICAgICAgIGZsYXNoRnJlcTogXCJrZWVwXCIsXG4gICAgICAgICAgICBlcmFzZUFsbDogZmFsc2UsXG4gICAgICAgICAgICBjb21wcmVzczogdHJ1ZSxcbiAgICAgICAgICAgIC8vIHJlcG9ydCBwcm9ncmVzc1xuICAgICAgICAgICAgcmVwb3J0UHJvZ3Jlc3M6IChmaWxlSW5kZXgsIHdyaXR0ZW4sIHRvdGFsKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdW5jb21wcmVzc2VkV3JpdHRlbiA9ICh3cml0dGVuIC8gdG90YWwpICogZmlsZUFycmF5W2ZpbGVJbmRleF0uZGF0YS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3UGN0ID0gTWF0aC5mbG9vcigoKHRvdGFsV3JpdHRlbiArIHVuY29tcHJlc3NlZFdyaXR0ZW4pIC8gdG90YWxTaXplKSAqIDEwMCk7XG4gICAgICAgICAgICAgICAgLy8gd2UncmUgZG9uZSB3aXRoIHRoaXMgZmlsZVxuICAgICAgICAgICAgICAgIGlmICh3cml0dGVuID09PSB0b3RhbCkge1xuICAgICAgICAgICAgICAgICAgICB0b3RhbFdyaXR0ZW4gKz0gdW5jb21wcmVzc2VkV3JpdHRlbjtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmaXJlU3RhdGVFdmVudCh7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlOiBcIndyaXRpbmdcIiAvKiBGbGFzaFN0YXRlVHlwZS5XUklUSU5HICovLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgV3JpdGluZyBwcm9ncmVzczogJHtuZXdQY3R9JWAsXG4gICAgICAgICAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzVG90YWw6IHRvdGFsU2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzV3JpdHRlbjogdG90YWxXcml0dGVuICsgd3JpdHRlbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2U6IG5ld1BjdCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGZpcmVTdGF0ZUV2ZW50KHtcbiAgICAgICAgICAgIHN0YXRlOiBcImVycm9yXCIgLyogRmxhc2hTdGF0ZVR5cGUuRVJST1IgKi8sXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgIGRldGFpbHM6IHsgZXJyb3I6IFwid3JpdGVfZmFpbGVkXCIgLyogRmxhc2hFcnJvci5XUklURV9GQUlMRUQgKi8sIGRldGFpbHM6IGVyciB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgaGFyZFJlc2V0KHRyYW5zcG9ydCk7XG4gICAgICAgIGF3YWl0IHRyYW5zcG9ydC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZmlyZVN0YXRlRXZlbnQoe1xuICAgICAgICBzdGF0ZTogXCJ3cml0aW5nXCIgLyogRmxhc2hTdGF0ZVR5cGUuV1JJVElORyAqLyxcbiAgICAgICAgbWVzc2FnZTogXCJXcml0aW5nIGNvbXBsZXRlXCIsXG4gICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgIGJ5dGVzVG90YWw6IHRvdGFsU2l6ZSxcbiAgICAgICAgICAgIGJ5dGVzV3JpdHRlbjogdG90YWxXcml0dGVuLFxuICAgICAgICAgICAgcGVyY2VudGFnZTogMTAwLFxuICAgICAgICB9LFxuICAgIH0pO1xuICAgIGF3YWl0IGhhcmRSZXNldCh0cmFuc3BvcnQpO1xuICAgIGNvbnNvbGUubG9nKFwiRElTQ09OTkVDVFwiKTtcbiAgICBhd2FpdCB0cmFuc3BvcnQuZGlzY29ubmVjdCgpO1xuICAgIGZpcmVTdGF0ZUV2ZW50KHtcbiAgICAgICAgc3RhdGU6IFwiZmluaXNoZWRcIiAvKiBGbGFzaFN0YXRlVHlwZS5GSU5JU0hFRCAqLyxcbiAgICAgICAgbWVzc2FnZTogXCJBbGwgZG9uZSFcIixcbiAgICB9KTtcbn07XG4iLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBMaXRFbGVtZW50LCBodG1sLCBjc3MgfSBmcm9tIFwibGl0XCI7XG5pbXBvcnQgeyBzdGF0ZSB9IGZyb20gXCJsaXQvZGVjb3JhdG9ycy5qc1wiO1xuaW1wb3J0IFwiLi9jb21wb25lbnRzL2V3LXRleHQtYnV0dG9uXCI7XG5pbXBvcnQgXCIuL2NvbXBvbmVudHMvZXctbGlzdFwiO1xuaW1wb3J0IFwiLi9jb21wb25lbnRzL2V3LWxpc3QtaXRlbVwiO1xuaW1wb3J0IFwiLi9jb21wb25lbnRzL2V3LWRpdmlkZXJcIjtcbmltcG9ydCBcIi4vY29tcG9uZW50cy9ldy1jaGVja2JveFwiO1xuaW1wb3J0IFwiLi9jb21wb25lbnRzL2V3dC1jb25zb2xlXCI7XG5pbXBvcnQgXCIuL2NvbXBvbmVudHMvZXctZGlhbG9nXCI7XG5pbXBvcnQgXCIuL2NvbXBvbmVudHMvZXctaWNvbi1idXR0b25cIjtcbmltcG9ydCBcIi4vY29tcG9uZW50cy9ldy1maWxsZWQtdGV4dC1maWVsZFwiO1xuaW1wb3J0IFwiLi9jb21wb25lbnRzL2V3LWZpbGxlZC1zZWxlY3RcIjtcbmltcG9ydCBcIi4vY29tcG9uZW50cy9ldy1zZWxlY3Qtb3B0aW9uXCI7XG5pbXBvcnQgXCIuL3BhZ2VzL2V3dC1wYWdlLXByb2dyZXNzXCI7XG5pbXBvcnQgXCIuL3BhZ2VzL2V3dC1wYWdlLW1lc3NhZ2VcIjtcbmltcG9ydCB7IGNsb3NlSWNvbiwgbGlzdEl0ZW1Db25zb2xlLCBsaXN0SXRlbUVyYXNlVXNlckRhdGEsIGxpc3RJdGVtRnVuZERldmVsb3BtZW50LCBsaXN0SXRlbUhvbWVBc3Npc3RhbnQsIGxpc3RJdGVtSW5zdGFsbEljb24sIGxpc3RJdGVtVmlzaXREZXZpY2UsIGxpc3RJdGVtV2lmaSwgcmVmcmVzaEljb24sIH0gZnJvbSBcIi4vY29tcG9uZW50cy9zdmdcIjtcbmltcG9ydCB7IEltcHJvdlNlcmlhbCB9IGZyb20gXCJpbXByb3Ytd2lmaS1zZXJpYWwtc2RrL2Rpc3Qvc2VyaWFsXCI7XG5pbXBvcnQgeyBJbXByb3ZTZXJpYWxDdXJyZW50U3RhdGUsIFBvcnROb3RSZWFkeSwgfSBmcm9tIFwiaW1wcm92LXdpZmktc2VyaWFsLXNkay9kaXN0L2NvbnN0XCI7XG5pbXBvcnQgeyBmbGFzaCB9IGZyb20gXCIuL2ZsYXNoXCI7XG5pbXBvcnQgeyB0ZXh0RG93bmxvYWQgfSBmcm9tIFwiLi91dGlsL2ZpbGUtZG93bmxvYWRcIjtcbmltcG9ydCB7IGZpcmVFdmVudCB9IGZyb20gXCIuL3V0aWwvZmlyZS1ldmVudFwiO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tIFwiLi91dGlsL3NsZWVwXCI7XG5pbXBvcnQgeyBkb3dubG9hZE1hbmlmZXN0IH0gZnJvbSBcIi4vdXRpbC9tYW5pZmVzdFwiO1xuaW1wb3J0IHsgZGlhbG9nU3R5bGVzIH0gZnJvbSBcIi4vc3R5bGVzXCI7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4vdmVyc2lvblwiO1xuY29uc29sZS5sb2coYEVTUCBXZWIgVG9vbHMgJHt2ZXJzaW9ufSBieSBPcGVuIEhvbWUgRm91bmRhdGlvbjsgaHR0cHM6Ly9lc3Bob21lLmdpdGh1Yi5pby9lc3Atd2ViLXRvb2xzL2ApO1xuY29uc3QgRVJST1JfSUNPTiA9IFwi4pqg77iPXCI7XG5jb25zdCBPS19JQ09OID0gXCLwn46JXCI7XG5leHBvcnQgY2xhc3MgRXd0SW5zdGFsbERpYWxvZyBleHRlbmRzIExpdEVsZW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmxvZ2dlciA9IGNvbnNvbGU7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gXCJEQVNIQk9BUkRcIjtcbiAgICAgICAgdGhpcy5faW5zdGFsbEVyYXNlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2luc3RhbGxDb25maXJtZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fcHJvdmlzaW9uRm9yY2UgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fd2FzUHJvdmlzaW9uZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fYnVzeSA9IGZhbHNlO1xuICAgICAgICAvLyBOYW1lIG9mIFNzaWQuIE51bGwgPSBvdGhlclxuICAgICAgICB0aGlzLl9zZWxlY3RlZFNzaWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9ib2R5T3ZlcmZsb3cgPSBudWxsO1xuICAgICAgICB0aGlzLl9oYW5kbGVEaXNjb25uZWN0ID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBcIkVSUk9SXCI7XG4gICAgICAgICAgICB0aGlzLl9lcnJvciA9IFwiRGlzY29ubmVjdGVkXCI7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnBvcnQpIHtcbiAgICAgICAgICAgIHJldHVybiBodG1sIGBgO1xuICAgICAgICB9XG4gICAgICAgIGxldCBoZWFkaW5nO1xuICAgICAgICBsZXQgY29udGVudDtcbiAgICAgICAgbGV0IGFsbG93Q2xvc2luZyA9IGZhbHNlO1xuICAgICAgICAvLyBEdXJpbmcgaW5zdGFsbGF0aW9uIHBoYXNlIHdlIHRlbXBvcmFyaWx5IHJlbW92ZSB0aGUgY2xpZW50XG4gICAgICAgIGlmICh0aGlzLl9jbGllbnQgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgIT09IFwiSU5TVEFMTFwiICYmXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSAhPT0gXCJMT0dTXCIpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9lcnJvcikge1xuICAgICAgICAgICAgICAgIFtoZWFkaW5nLCBjb250ZW50XSA9IHRoaXMuX3JlbmRlckVycm9yKHRoaXMuX2Vycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQgPSB0aGlzLl9yZW5kZXJQcm9ncmVzcyhcIkNvbm5lY3RpbmdcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fc3RhdGUgPT09IFwiSU5TVEFMTFwiKSB7XG4gICAgICAgICAgICBbaGVhZGluZywgY29udGVudCwgYWxsb3dDbG9zaW5nXSA9IHRoaXMuX3JlbmRlckluc3RhbGwoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9zdGF0ZSA9PT0gXCJBU0tfRVJBU0VcIikge1xuICAgICAgICAgICAgW2hlYWRpbmcsIGNvbnRlbnRdID0gdGhpcy5fcmVuZGVyQXNrRXJhc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9zdGF0ZSA9PT0gXCJFUlJPUlwiKSB7XG4gICAgICAgICAgICBbaGVhZGluZywgY29udGVudF0gPSB0aGlzLl9yZW5kZXJFcnJvcih0aGlzLl9lcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fc3RhdGUgPT09IFwiREFTSEJPQVJEXCIpIHtcbiAgICAgICAgICAgIFtoZWFkaW5nLCBjb250ZW50LCBhbGxvd0Nsb3NpbmddID0gdGhpcy5fY2xpZW50XG4gICAgICAgICAgICAgICAgPyB0aGlzLl9yZW5kZXJEYXNoYm9hcmQoKVxuICAgICAgICAgICAgICAgIDogdGhpcy5fcmVuZGVyRGFzaGJvYXJkTm9JbXByb3YoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9zdGF0ZSA9PT0gXCJQUk9WSVNJT05cIikge1xuICAgICAgICAgICAgW2hlYWRpbmcsIGNvbnRlbnRdID0gdGhpcy5fcmVuZGVyUHJvdmlzaW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fc3RhdGUgPT09IFwiTE9HU1wiKSB7XG4gICAgICAgICAgICBbaGVhZGluZywgY29udGVudF0gPSB0aGlzLl9yZW5kZXJMb2dzKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGh0bWwgYFxuICAgICAgPGV3LWRpYWxvZ1xuICAgICAgICBvcGVuXG4gICAgICAgIC5oZWFkaW5nPSR7aGVhZGluZ31cbiAgICAgICAgQGNhbmNlbD0ke3RoaXMuX3ByZXZlbnREZWZhdWx0fVxuICAgICAgICBAY2xvc2VkPSR7dGhpcy5faGFuZGxlQ2xvc2V9XG4gICAgICA+XG4gICAgICAgICR7aGVhZGluZyA/IGh0bWwgYDxkaXYgc2xvdD1cImhlYWRsaW5lXCI+JHtoZWFkaW5nfTwvZGl2PmAgOiBcIlwifVxuICAgICAgICAke2FsbG93Q2xvc2luZ1xuICAgICAgICAgICAgPyBodG1sIGBcbiAgICAgICAgICAgICAgPGV3LWljb24tYnV0dG9uIHNsb3Q9XCJoZWFkbGluZVwiIEBjbGljaz0ke3RoaXMuX2Nsb3NlRGlhbG9nfT5cbiAgICAgICAgICAgICAgICAke2Nsb3NlSWNvbn1cbiAgICAgICAgICAgICAgPC9ldy1pY29uLWJ1dHRvbj5cbiAgICAgICAgICAgIGBcbiAgICAgICAgICAgIDogXCJcIn1cbiAgICAgICAgJHtjb250ZW50fVxuICAgICAgPC9ldy1kaWFsb2c+XG4gICAgYDtcbiAgICB9XG4gICAgX3JlbmRlclByb2dyZXNzKGxhYmVsLCBwcm9ncmVzcykge1xuICAgICAgICByZXR1cm4gaHRtbCBgXG4gICAgICA8ZXd0LXBhZ2UtcHJvZ3Jlc3NcbiAgICAgICAgc2xvdD1cImNvbnRlbnRcIlxuICAgICAgICAubGFiZWw9JHtsYWJlbH1cbiAgICAgICAgLnByb2dyZXNzPSR7cHJvZ3Jlc3N9XG4gICAgICA+PC9ld3QtcGFnZS1wcm9ncmVzcz5cbiAgICBgO1xuICAgIH1cbiAgICBfcmVuZGVyRXJyb3IobGFiZWwpIHtcbiAgICAgICAgY29uc3QgaGVhZGluZyA9IFwiRXJyb3JcIjtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGh0bWwgYFxuICAgICAgPGV3dC1wYWdlLW1lc3NhZ2VcbiAgICAgICAgc2xvdD1cImNvbnRlbnRcIlxuICAgICAgICAuaWNvbj0ke0VSUk9SX0lDT059XG4gICAgICAgIC5sYWJlbD0ke2xhYmVsfVxuICAgICAgPjwvZXd0LXBhZ2UtbWVzc2FnZT5cbiAgICAgIDxkaXYgc2xvdD1cImFjdGlvbnNcIj5cbiAgICAgICAgPGV3LXRleHQtYnV0dG9uIEBjbGljaz0ke3RoaXMuX2Nsb3NlRGlhbG9nfT5DbG9zZTwvZXctdGV4dC1idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuICAgICAgICByZXR1cm4gW2hlYWRpbmcsIGNvbnRlbnRdO1xuICAgIH1cbiAgICBfcmVuZGVyRGFzaGJvYXJkKCkge1xuICAgICAgICBjb25zdCBoZWFkaW5nID0gdGhpcy5fbWFuaWZlc3QubmFtZTtcbiAgICAgICAgbGV0IGNvbnRlbnQ7XG4gICAgICAgIGxldCBhbGxvd0Nsb3NpbmcgPSB0cnVlO1xuICAgICAgICBjb250ZW50ID0gaHRtbCBgXG4gICAgICA8ZGl2IHNsb3Q9XCJjb250ZW50XCI+XG4gICAgICAgIDxldy1saXN0PlxuICAgICAgICAgIDxldy1saXN0LWl0ZW0+XG4gICAgICAgICAgICA8ZGl2IHNsb3Q9XCJoZWFkbGluZVwiPkNvbm5lY3RlZCB0byAke3RoaXMuX2luZm8ubmFtZX08L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgc2xvdD1cInN1cHBvcnRpbmctdGV4dFwiPlxuICAgICAgICAgICAgICAke3RoaXMuX2luZm8uZmlybXdhcmV9Jm5ic3A7JHt0aGlzLl9pbmZvLnZlcnNpb259XG4gICAgICAgICAgICAgICgke3RoaXMuX2luZm8uY2hpcEZhbWlseX0pXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2V3LWxpc3QtaXRlbT5cbiAgICAgICAgICAkeyF0aGlzLl9pc1NhbWVWZXJzaW9uXG4gICAgICAgICAgICA/IGh0bWwgYFxuICAgICAgICAgICAgICAgIDxldy1saXN0LWl0ZW1cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgQGNsaWNrPSR7KCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pc1NhbWVGaXJtd2FyZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydEluc3RhbGwoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9tYW5pZmVzdC5uZXdfaW5zdGFsbF9wcm9tcHRfZXJhc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBcIkFTS19FUkFTRVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRJbnN0YWxsKHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgJHtsaXN0SXRlbUluc3RhbGxJY29ufVxuICAgICAgICAgICAgICAgICAgPGRpdiBzbG90PVwiaGVhZGxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgJHshdGhpcy5faXNTYW1lRmlybXdhcmVcbiAgICAgICAgICAgICAgICA/IGBJbnN0YWxsICR7dGhpcy5fbWFuaWZlc3QubmFtZX1gXG4gICAgICAgICAgICAgICAgOiBgVXBkYXRlICR7dGhpcy5fbWFuaWZlc3QubmFtZX1gfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9ldy1saXN0LWl0ZW0+XG4gICAgICAgICAgICAgIGBcbiAgICAgICAgICAgIDogXCJcIn1cbiAgICAgICAgICAke3RoaXMuX2NsaWVudC5uZXh0VXJsID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gXCJcIlxuICAgICAgICAgICAgOiBodG1sIGBcbiAgICAgICAgICAgICAgICA8ZXctbGlzdC1pdGVtXG4gICAgICAgICAgICAgICAgICB0eXBlPVwibGlua1wiXG4gICAgICAgICAgICAgICAgICBocmVmPSR7dGhpcy5fY2xpZW50Lm5leHRVcmx9XG4gICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICR7bGlzdEl0ZW1WaXNpdERldmljZX1cbiAgICAgICAgICAgICAgICAgIDxkaXYgc2xvdD1cImhlYWRsaW5lXCI+VmlzaXQgRGV2aWNlPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9ldy1saXN0LWl0ZW0+XG4gICAgICAgICAgICAgIGB9XG4gICAgICAgICAgJHshdGhpcy5fbWFuaWZlc3QuaG9tZV9hc3Npc3RhbnRfZG9tYWluIHx8XG4gICAgICAgICAgICB0aGlzLl9jbGllbnQuc3RhdGUgIT09IEltcHJvdlNlcmlhbEN1cnJlbnRTdGF0ZS5QUk9WSVNJT05FRFxuICAgICAgICAgICAgPyBcIlwiXG4gICAgICAgICAgICA6IGh0bWwgYFxuICAgICAgICAgICAgICAgIDxldy1saXN0LWl0ZW1cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJsaW5rXCJcbiAgICAgICAgICAgICAgICAgIGhyZWY9JHtgaHR0cHM6Ly9teS5ob21lLWFzc2lzdGFudC5pby9yZWRpcmVjdC9jb25maWdfZmxvd19zdGFydC8/ZG9tYWluPSR7dGhpcy5fbWFuaWZlc3QuaG9tZV9hc3Npc3RhbnRfZG9tYWlufWB9XG4gICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICR7bGlzdEl0ZW1Ib21lQXNzaXN0YW50fVxuICAgICAgICAgICAgICAgICAgPGRpdiBzbG90PVwiaGVhZGxpbmVcIj5BZGQgdG8gSG9tZSBBc3Npc3RhbnQ8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2V3LWxpc3QtaXRlbT5cbiAgICAgICAgICAgICAgYH1cbiAgICAgICAgICA8ZXctbGlzdC1pdGVtXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIEBjbGljaz0keygpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gXCJQUk9WSVNJT05cIjtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jbGllbnQuc3RhdGUgPT09IEltcHJvdlNlcmlhbEN1cnJlbnRTdGF0ZS5QUk9WSVNJT05FRCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Byb3Zpc2lvbkZvcmNlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICAke2xpc3RJdGVtV2lmaX1cbiAgICAgICAgICAgIDxkaXYgc2xvdD1cImhlYWRsaW5lXCI+XG4gICAgICAgICAgICAgICR7dGhpcy5fY2xpZW50LnN0YXRlID09PSBJbXByb3ZTZXJpYWxDdXJyZW50U3RhdGUuUkVBRFlcbiAgICAgICAgICAgID8gXCJDb25uZWN0IHRvIFdpLUZpXCJcbiAgICAgICAgICAgIDogXCJDaGFuZ2UgV2ktRmlcIn1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZXctbGlzdC1pdGVtPlxuICAgICAgICAgIDxldy1saXN0LWl0ZW1cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgQGNsaWNrPSR7YXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5fY2xpZW50O1xuICAgICAgICAgICAgaWYgKGNsaWVudCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuX2Nsb3NlQ2xpZW50V2l0aG91dEV2ZW50cyhjbGllbnQpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHNsZWVwKDEwMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBBbHNvIHNldCBgbnVsbGAgYmFjayB0byB1bmRlZmluZWQuXG4gICAgICAgICAgICB0aGlzLl9jbGllbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiTE9HU1wiO1xuICAgICAgICB9fVxuICAgICAgICAgID5cbiAgICAgICAgICAgICR7bGlzdEl0ZW1Db25zb2xlfVxuICAgICAgICAgICAgPGRpdiBzbG90PVwiaGVhZGxpbmVcIj5Mb2dzICYgQ29uc29sZTwvZGl2PlxuICAgICAgICAgIDwvZXctbGlzdC1pdGVtPlxuICAgICAgICAgICR7dGhpcy5faXNTYW1lRmlybXdhcmUgJiYgdGhpcy5fbWFuaWZlc3QuZnVuZGluZ191cmxcbiAgICAgICAgICAgID8gaHRtbCBgXG4gICAgICAgICAgICAgICAgPGV3LWxpc3QtaXRlbVxuICAgICAgICAgICAgICAgICAgdHlwZT1cImxpbmtcIlxuICAgICAgICAgICAgICAgICAgaHJlZj0ke3RoaXMuX21hbmlmZXN0LmZ1bmRpbmdfdXJsfVxuICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAke2xpc3RJdGVtRnVuZERldmVsb3BtZW50fVxuICAgICAgICAgICAgICAgICAgPGRpdiBzbG90PVwiaGVhZGxpbmVcIj5GdW5kIERldmVsb3BtZW50PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9ldy1saXN0LWl0ZW0+XG4gICAgICAgICAgICAgIGBcbiAgICAgICAgICAgIDogXCJcIn1cbiAgICAgICAgICAke3RoaXMuX2lzU2FtZVZlcnNpb25cbiAgICAgICAgICAgID8gaHRtbCBgXG4gICAgICAgICAgICAgICAgPGV3LWxpc3QtaXRlbVxuICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImRhbmdlclwiXG4gICAgICAgICAgICAgICAgICBAY2xpY2s9JHsoKSA9PiB0aGlzLl9zdGFydEluc3RhbGwodHJ1ZSl9XG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgJHtsaXN0SXRlbUVyYXNlVXNlckRhdGF9XG4gICAgICAgICAgICAgICAgICA8ZGl2IHNsb3Q9XCJoZWFkbGluZVwiPkVyYXNlIFVzZXIgRGF0YTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZXctbGlzdC1pdGVtPlxuICAgICAgICAgICAgICBgXG4gICAgICAgICAgICA6IFwiXCJ9XG4gICAgICAgIDwvZXctbGlzdD5cbiAgICAgIDwvZGl2PlxuICAgIGA7XG4gICAgICAgIHJldHVybiBbaGVhZGluZywgY29udGVudCwgYWxsb3dDbG9zaW5nXTtcbiAgICB9XG4gICAgX3JlbmRlckRhc2hib2FyZE5vSW1wcm92KCkge1xuICAgICAgICBjb25zdCBoZWFkaW5nID0gdGhpcy5fbWFuaWZlc3QubmFtZTtcbiAgICAgICAgbGV0IGNvbnRlbnQ7XG4gICAgICAgIGxldCBhbGxvd0Nsb3NpbmcgPSB0cnVlO1xuICAgICAgICBjb250ZW50ID0gaHRtbCBgXG4gICAgICA8ZGl2IHNsb3Q9XCJjb250ZW50XCI+XG4gICAgICAgIDxldy1saXN0PlxuICAgICAgICAgIDxldy1saXN0LWl0ZW1cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgQGNsaWNrPSR7KCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuX21hbmlmZXN0Lm5ld19pbnN0YWxsX3Byb21wdF9lcmFzZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gXCJBU0tfRVJBU0VcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIERlZmF1bHQgaXMgdG8gZXJhc2UgYSBkZXZpY2UgdGhhdCBkb2VzIG5vdCBzdXBwb3J0IEltcHJvdiBTZXJpYWxcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydEluc3RhbGwodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgJHtsaXN0SXRlbUluc3RhbGxJY29ufVxuICAgICAgICAgICAgPGRpdiBzbG90PVwiaGVhZGxpbmVcIj4ke2BJbnN0YWxsICR7dGhpcy5fbWFuaWZlc3QubmFtZX1gfTwvZGl2PlxuICAgICAgICAgIDwvZXctbGlzdC1pdGVtPlxuICAgICAgICAgIDxldy1saXN0LWl0ZW1cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgQGNsaWNrPSR7YXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gQWxzbyBzZXQgYG51bGxgIGJhY2sgdG8gdW5kZWZpbmVkLlxuICAgICAgICAgICAgdGhpcy5fY2xpZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBcIkxPR1NcIjtcbiAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICAke2xpc3RJdGVtQ29uc29sZX1cbiAgICAgICAgICAgIDxkaXYgc2xvdD1cImhlYWRsaW5lXCI+TG9ncyAmIENvbnNvbGU8L2Rpdj5cbiAgICAgICAgICA8L2V3LWxpc3QtaXRlbT5cbiAgICAgICAgPC9ldy1saXN0PlxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgICAgICAgcmV0dXJuIFtoZWFkaW5nLCBjb250ZW50LCBhbGxvd0Nsb3NpbmddO1xuICAgIH1cbiAgICBfcmVuZGVyUHJvdmlzaW9uKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGxldCBoZWFkaW5nID0gXCJDb25maWd1cmUgV2ktRmlcIjtcbiAgICAgICAgbGV0IGNvbnRlbnQ7XG4gICAgICAgIGlmICh0aGlzLl9idXN5KSB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIGhlYWRpbmcsXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVuZGVyUHJvZ3Jlc3ModGhpcy5fc3NpZHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IFwiU2Nhbm5pbmcgZm9yIG5ldHdvcmtzXCJcbiAgICAgICAgICAgICAgICAgICAgOiBcIlRyeWluZyB0byBjb25uZWN0XCIpLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX3Byb3Zpc2lvbkZvcmNlICYmXG4gICAgICAgICAgICB0aGlzLl9jbGllbnQuc3RhdGUgPT09IEltcHJvdlNlcmlhbEN1cnJlbnRTdGF0ZS5QUk9WSVNJT05FRCkge1xuICAgICAgICAgICAgaGVhZGluZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGNvbnN0IHNob3dTZXR1cExpbmtzID0gIXRoaXMuX3dhc1Byb3Zpc2lvbmVkICYmXG4gICAgICAgICAgICAgICAgKHRoaXMuX2NsaWVudC5uZXh0VXJsICE9PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgICAgICAgICAgXCJob21lX2Fzc2lzdGFudF9kb21haW5cIiBpbiB0aGlzLl9tYW5pZmVzdCk7XG4gICAgICAgICAgICBjb250ZW50ID0gaHRtbCBgXG4gICAgICAgIDxkaXYgc2xvdD1cImNvbnRlbnRcIj5cbiAgICAgICAgICA8ZXd0LXBhZ2UtbWVzc2FnZVxuICAgICAgICAgICAgLmljb249JHtPS19JQ09OfVxuICAgICAgICAgICAgbGFiZWw9XCJEZXZpY2UgY29ubmVjdGVkIHRvIHRoZSBuZXR3b3JrIVwiXG4gICAgICAgICAgPjwvZXd0LXBhZ2UtbWVzc2FnZT5cbiAgICAgICAgICAke3Nob3dTZXR1cExpbmtzXG4gICAgICAgICAgICAgICAgPyBodG1sIGBcbiAgICAgICAgICAgICAgICA8ZXctbGlzdD5cbiAgICAgICAgICAgICAgICAgICR7dGhpcy5fY2xpZW50Lm5leHRVcmwgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IFwiXCJcbiAgICAgICAgICAgICAgICAgICAgOiBodG1sIGBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxldy1saXN0LWl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImxpbmtcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBocmVmPSR7dGhpcy5fY2xpZW50Lm5leHRVcmx9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIEBjbGljaz0keygpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gXCJEQVNIQk9BUkRcIjtcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgJHtsaXN0SXRlbVZpc2l0RGV2aWNlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHNsb3Q9XCJoZWFkbGluZVwiPlZpc2l0IERldmljZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9ldy1saXN0LWl0ZW0+XG4gICAgICAgICAgICAgICAgICAgICAgYH1cbiAgICAgICAgICAgICAgICAgICR7IXRoaXMuX21hbmlmZXN0LmhvbWVfYXNzaXN0YW50X2RvbWFpblxuICAgICAgICAgICAgICAgICAgICA/IFwiXCJcbiAgICAgICAgICAgICAgICAgICAgOiBodG1sIGBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxldy1saXN0LWl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImxpbmtcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBocmVmPSR7YGh0dHBzOi8vbXkuaG9tZS1hc3Npc3RhbnQuaW8vcmVkaXJlY3QvY29uZmlnX2Zsb3dfc3RhcnQvP2RvbWFpbj0ke3RoaXMuX21hbmlmZXN0LmhvbWVfYXNzaXN0YW50X2RvbWFpbn1gfVxuICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBAY2xpY2s9JHsoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiREFTSEJPQVJEXCI7XG4gICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICR7bGlzdEl0ZW1Ib21lQXNzaXN0YW50fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHNsb3Q9XCJoZWFkbGluZVwiPkFkZCB0byBIb21lIEFzc2lzdGFudDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9ldy1saXN0LWl0ZW0+XG4gICAgICAgICAgICAgICAgICAgICAgYH1cbiAgICAgICAgICAgICAgICAgIDxldy1saXN0LWl0ZW1cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIEBjbGljaz0keygpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBcIkRBU0hCT0FSRFwiO1xuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgc2xvdD1cInN0YXJ0XCIgY2xhc3M9XCJmYWtlLWljb25cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzbG90PVwiaGVhZGxpbmVcIj5Ta2lwPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2V3LWxpc3QtaXRlbT5cbiAgICAgICAgICAgICAgICA8L2V3LWxpc3Q+XG4gICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICA6IFwiXCJ9XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgICR7IXNob3dTZXR1cExpbmtzXG4gICAgICAgICAgICAgICAgPyBodG1sIGBcbiAgICAgICAgICAgICAgPGRpdiBzbG90PVwiYWN0aW9uc1wiPlxuICAgICAgICAgICAgICAgIDxldy10ZXh0LWJ1dHRvblxuICAgICAgICAgICAgICAgICAgQGNsaWNrPSR7KCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiREFTSEJPQVJEXCI7XG4gICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICBDb250aW51ZVxuICAgICAgICAgICAgICAgIDwvZXctdGV4dC1idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgYFxuICAgICAgICAgICAgICAgIDogXCJcIn1cbiAgICAgIGA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgZXJyb3I7XG4gICAgICAgICAgICBzd2l0Y2ggKHRoaXMuX2NsaWVudC5lcnJvcikge1xuICAgICAgICAgICAgICAgIGNhc2UgMyAvKiBJbXByb3ZTZXJpYWxFcnJvclN0YXRlLlVOQUJMRV9UT19DT05ORUNUICovOlxuICAgICAgICAgICAgICAgICAgICBlcnJvciA9IFwiVW5hYmxlIHRvIGNvbm5lY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAyNTQgLyogSW1wcm92U2VyaWFsRXJyb3JTdGF0ZS5USU1FT1VUICovOlxuICAgICAgICAgICAgICAgICAgICBlcnJvciA9IFwiVGltZW91dFwiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDAgLyogSW1wcm92U2VyaWFsRXJyb3JTdGF0ZS5OT19FUlJPUiAqLzpcbiAgICAgICAgICAgICAgICAvLyBIYXBwZW5zIHdoZW4gbGlzdCBTU0lEcyBub3Qgc3VwcG9ydGVkLlxuICAgICAgICAgICAgICAgIGNhc2UgMiAvKiBJbXByb3ZTZXJpYWxFcnJvclN0YXRlLlVOS05PV05fUlBDX0NPTU1BTkQgKi86XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gYFVua25vd24gZXJyb3IgKCR7dGhpcy5fY2xpZW50LmVycm9yfSlgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRTc2lkID0gKF9hID0gdGhpcy5fc3NpZHMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5maW5kKChpbmZvKSA9PiBpbmZvLm5hbWUgPT09IHRoaXMuX3NlbGVjdGVkU3NpZCk7XG4gICAgICAgICAgICBjb250ZW50ID0gaHRtbCBgXG4gICAgICAgIDxldy1pY29uLWJ1dHRvbiBzbG90PVwiaGVhZGxpbmVcIiBAY2xpY2s9JHt0aGlzLl91cGRhdGVTc2lkc30+XG4gICAgICAgICAgJHtyZWZyZXNoSWNvbn1cbiAgICAgICAgPC9ldy1pY29uLWJ1dHRvbj5cbiAgICAgICAgPGRpdiBzbG90PVwiY29udGVudFwiPlxuICAgICAgICAgIDxkaXY+Q29ubmVjdCB5b3VyIGRldmljZSB0byB0aGUgbmV0d29yayB0byBzdGFydCB1c2luZyBpdC48L2Rpdj5cbiAgICAgICAgICAke2Vycm9yID8gaHRtbCBgPHAgY2xhc3M9XCJlcnJvclwiPiR7ZXJyb3J9PC9wPmAgOiBcIlwifVxuICAgICAgICAgICR7dGhpcy5fc3NpZHMgIT09IG51bGxcbiAgICAgICAgICAgICAgICA/IGh0bWwgYFxuICAgICAgICAgICAgICAgIDxldy1maWxsZWQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICBtZW51LXBvc2l0aW9uaW5nPVwiZml4ZWRcIlxuICAgICAgICAgICAgICAgICAgbGFiZWw9XCJOZXR3b3JrXCJcbiAgICAgICAgICAgICAgICAgIEBjaGFuZ2U9JHsoZXYpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBldi50YXJnZXQuc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIFwiSm9pbiBPdGhlclwiIGl0ZW0gaXMgYWx3YXlzIHRoZSBsYXN0IGl0ZW0uXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NlbGVjdGVkU3NpZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9PT0gdGhpcy5fc3NpZHMubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0aGlzLl9zc2lkc1tpbmRleF0ubmFtZTtcbiAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICR7dGhpcy5fc3NpZHMubWFwKChpbmZvKSA9PiBodG1sIGBcbiAgICAgICAgICAgICAgICAgICAgICA8ZXctc2VsZWN0LW9wdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgLnNlbGVjdGVkPSR7c2VsZWN0ZWRTc2lkID09PSBpbmZvfVxuICAgICAgICAgICAgICAgICAgICAgICAgLnZhbHVlPSR7aW5mby5uYW1lfVxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7aW5mby5uYW1lfVxuICAgICAgICAgICAgICAgICAgICAgIDwvZXctc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgYCl9XG4gICAgICAgICAgICAgICAgICA8ZXctZGl2aWRlcj48L2V3LWRpdmlkZXI+XG4gICAgICAgICAgICAgICAgICA8ZXctc2VsZWN0LW9wdGlvbiAuc2VsZWN0ZWQ9JHshc2VsZWN0ZWRTc2lkfT5cbiAgICAgICAgICAgICAgICAgICAgSm9pbiBvdGhlcuKAplxuICAgICAgICAgICAgICAgICAgPC9ldy1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvZXctZmlsbGVkLXNlbGVjdD5cbiAgICAgICAgICAgICAgYFxuICAgICAgICAgICAgICAgIDogXCJcIn1cbiAgICAgICAgICAke1xuICAgICAgICAgICAgLy8gU2hvdyBpbnB1dCBib3ggaWYgY29tbWFuZCBub3Qgc3VwcG9ydGVkIG9yIFwiSm9pbiBPdGhlclwiIHNlbGVjdGVkXG4gICAgICAgICAgICAhc2VsZWN0ZWRTc2lkXG4gICAgICAgICAgICAgICAgPyBodG1sIGBcbiAgICAgICAgICAgICAgICAgIDxldy1maWxsZWQtdGV4dC1maWVsZFxuICAgICAgICAgICAgICAgICAgICBsYWJlbD1cIk5ldHdvcmsgTmFtZVwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJzc2lkXCJcbiAgICAgICAgICAgICAgICAgID48L2V3LWZpbGxlZC10ZXh0LWZpZWxkPlxuICAgICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICA6IFwiXCJ9XG4gICAgICAgICAgJHshc2VsZWN0ZWRTc2lkIHx8IHNlbGVjdGVkU3NpZC5zZWN1cmVkXG4gICAgICAgICAgICAgICAgPyBodG1sIGBcbiAgICAgICAgICAgICAgICA8ZXctZmlsbGVkLXRleHQtZmllbGRcbiAgICAgICAgICAgICAgICAgIGxhYmVsPVwiUGFzc3dvcmRcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cInBhc3N3b3JkXCJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJwYXNzd29yZFwiXG4gICAgICAgICAgICAgICAgPjwvZXctZmlsbGVkLXRleHQtZmllbGQ+XG4gICAgICAgICAgICAgIGBcbiAgICAgICAgICAgICAgICA6IFwiXCJ9XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IHNsb3Q9XCJhY3Rpb25zXCI+XG4gICAgICAgICAgPGV3LXRleHQtYnV0dG9uXG4gICAgICAgICAgICBAY2xpY2s9JHsoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBcIkRBU0hCT0FSRFwiO1xuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICAke3RoaXMuX2luc3RhbGxTdGF0ZSAmJiB0aGlzLl9pbnN0YWxsRXJhc2UgPyBcIlNraXBcIiA6IFwiQmFja1wifVxuICAgICAgICAgIDwvZXctdGV4dC1idXR0b24+XG4gICAgICAgICAgPGV3LXRleHQtYnV0dG9uIEBjbGljaz0ke3RoaXMuX2RvUHJvdmlzaW9ufT5Db25uZWN0PC9ldy10ZXh0LWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICBgO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbaGVhZGluZywgY29udGVudF07XG4gICAgfVxuICAgIF9yZW5kZXJBc2tFcmFzZSgpIHtcbiAgICAgICAgY29uc3QgaGVhZGluZyA9IFwiRXJhc2UgZGV2aWNlXCI7XG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBodG1sIGBcbiAgICAgIDxkaXYgc2xvdD1cImNvbnRlbnRcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICBEbyB5b3Ugd2FudCB0byBlcmFzZSB0aGUgZGV2aWNlIGJlZm9yZSBpbnN0YWxsaW5nXG4gICAgICAgICAgJHt0aGlzLl9tYW5pZmVzdC5uYW1lfT8gQWxsIGRhdGEgb24gdGhlIGRldmljZSB3aWxsIGJlIGxvc3QuXG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtZmllbGRcIj5cbiAgICAgICAgICA8ZXctY2hlY2tib3ggdG91Y2gtdGFyZ2V0PVwid3JhcHBlclwiIGNsYXNzPVwiZGFuZ2VyXCI+PC9ldy1jaGVja2JveD5cbiAgICAgICAgICBFcmFzZSBkZXZpY2VcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBzbG90PVwiYWN0aW9uc1wiPlxuICAgICAgICA8ZXctdGV4dC1idXR0b25cbiAgICAgICAgICBAY2xpY2s9JHsoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiREFTSEJPQVJEXCI7XG4gICAgICAgIH19XG4gICAgICAgID5cbiAgICAgICAgICBCYWNrXG4gICAgICAgIDwvZXctdGV4dC1idXR0b24+XG4gICAgICAgIDxldy10ZXh0LWJ1dHRvblxuICAgICAgICAgIEBjbGljaz0keygpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoZWNrYm94ID0gdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoXCJldy1jaGVja2JveFwiKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0SW5zdGFsbChjaGVja2JveC5jaGVja2VkKTtcbiAgICAgICAgfX1cbiAgICAgICAgPlxuICAgICAgICAgIE5leHRcbiAgICAgICAgPC9ldy10ZXh0LWJ1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIGA7XG4gICAgICAgIHJldHVybiBbaGVhZGluZywgY29udGVudF07XG4gICAgfVxuICAgIF9yZW5kZXJJbnN0YWxsKCkge1xuICAgICAgICBsZXQgaGVhZGluZztcbiAgICAgICAgbGV0IGNvbnRlbnQ7XG4gICAgICAgIGNvbnN0IGFsbG93Q2xvc2luZyA9IGZhbHNlO1xuICAgICAgICBjb25zdCBpc1VwZGF0ZSA9ICF0aGlzLl9pbnN0YWxsRXJhc2UgJiYgdGhpcy5faXNTYW1lRmlybXdhcmU7XG4gICAgICAgIGlmICghdGhpcy5faW5zdGFsbENvbmZpcm1lZCAmJiB0aGlzLl9pc1NhbWVWZXJzaW9uKSB7XG4gICAgICAgICAgICBoZWFkaW5nID0gXCJFcmFzZSBVc2VyIERhdGFcIjtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBodG1sIGBcbiAgICAgICAgPGRpdiBzbG90PVwiY29udGVudFwiPlxuICAgICAgICAgIERvIHlvdSB3YW50IHRvIHJlc2V0IHlvdXIgZGV2aWNlIGFuZCBlcmFzZSBhbGwgdXNlciBkYXRhIGZyb20geW91clxuICAgICAgICAgIGRldmljZT9cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgc2xvdD1cImFjdGlvbnNcIj5cbiAgICAgICAgICA8ZXctdGV4dC1idXR0b24gY2xhc3M9XCJkYW5nZXJcIiBAY2xpY2s9JHt0aGlzLl9jb25maXJtSW5zdGFsbH0+XG4gICAgICAgICAgICBFcmFzZSBVc2VyIERhdGFcbiAgICAgICAgICA8L2V3LXRleHQtYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIGA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXRoaXMuX2luc3RhbGxDb25maXJtZWQpIHtcbiAgICAgICAgICAgIGhlYWRpbmcgPSBcIkNvbmZpcm0gSW5zdGFsbGF0aW9uXCI7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb24gPSBpc1VwZGF0ZSA/IFwidXBkYXRlIHRvXCIgOiBcImluc3RhbGxcIjtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBodG1sIGBcbiAgICAgICAgPGRpdiBzbG90PVwiY29udGVudFwiPlxuICAgICAgICAgICR7aXNVcGRhdGVcbiAgICAgICAgICAgICAgICA/IGh0bWwgYFlvdXIgZGV2aWNlIGlzIHJ1bm5pbmdcbiAgICAgICAgICAgICAgICAke3RoaXMuX2luZm8uZmlybXdhcmV9Jm5ic3A7JHt0aGlzLl9pbmZvLnZlcnNpb259LjxiciAvPjxiciAvPmBcbiAgICAgICAgICAgICAgICA6IFwiXCJ9XG4gICAgICAgICAgRG8geW91IHdhbnQgdG8gJHthY3Rpb259XG4gICAgICAgICAgJHt0aGlzLl9tYW5pZmVzdC5uYW1lfSZuYnNwOyR7dGhpcy5fbWFuaWZlc3QudmVyc2lvbn0/XG4gICAgICAgICAgJHt0aGlzLl9pbnN0YWxsRXJhc2VcbiAgICAgICAgICAgICAgICA/IGh0bWwgYDxiciAvPjxiciAvPkFsbCBkYXRhIG9uIHRoZSBkZXZpY2Ugd2lsbCBiZSBlcmFzZWQuYFxuICAgICAgICAgICAgICAgIDogXCJcIn1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgc2xvdD1cImFjdGlvbnNcIj5cbiAgICAgICAgICA8ZXctdGV4dC1idXR0b25cbiAgICAgICAgICAgIEBjbGljaz0keygpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiREFTSEJPQVJEXCI7XG4gICAgICAgICAgICB9fVxuICAgICAgICAgID5cbiAgICAgICAgICAgIEJhY2tcbiAgICAgICAgICA8L2V3LXRleHQtYnV0dG9uPlxuICAgICAgICAgIDxldy10ZXh0LWJ1dHRvbiBAY2xpY2s9JHt0aGlzLl9jb25maXJtSW5zdGFsbH0+XG4gICAgICAgICAgICBJbnN0YWxsXG4gICAgICAgICAgPC9ldy10ZXh0LWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICBgO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCF0aGlzLl9pbnN0YWxsU3RhdGUgfHxcbiAgICAgICAgICAgIHRoaXMuX2luc3RhbGxTdGF0ZS5zdGF0ZSA9PT0gXCJpbml0aWFsaXppbmdcIiAvKiBGbGFzaFN0YXRlVHlwZS5JTklUSUFMSVpJTkcgKi8gfHxcbiAgICAgICAgICAgIHRoaXMuX2luc3RhbGxTdGF0ZS5zdGF0ZSA9PT0gXCJwcmVwYXJpbmdcIiAvKiBGbGFzaFN0YXRlVHlwZS5QUkVQQVJJTkcgKi8pIHtcbiAgICAgICAgICAgIGhlYWRpbmcgPSBcIkluc3RhbGxpbmdcIjtcbiAgICAgICAgICAgIGNvbnRlbnQgPSB0aGlzLl9yZW5kZXJQcm9ncmVzcyhcIlByZXBhcmluZyBpbnN0YWxsYXRpb25cIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5faW5zdGFsbFN0YXRlLnN0YXRlID09PSBcImVyYXNpbmdcIiAvKiBGbGFzaFN0YXRlVHlwZS5FUkFTSU5HICovKSB7XG4gICAgICAgICAgICBoZWFkaW5nID0gXCJJbnN0YWxsaW5nXCI7XG4gICAgICAgICAgICBjb250ZW50ID0gdGhpcy5fcmVuZGVyUHJvZ3Jlc3MoXCJFcmFzaW5nXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2luc3RhbGxTdGF0ZS5zdGF0ZSA9PT0gXCJ3cml0aW5nXCIgLyogRmxhc2hTdGF0ZVR5cGUuV1JJVElORyAqLyB8fFxuICAgICAgICAgICAgLy8gV2hlbiB3ZSdyZSBmaW5pc2hlZCwga2VlcCBzaG93aW5nIHRoaXMgc2NyZWVuIHdpdGggMTAwJSB3cml0dGVuXG4gICAgICAgICAgICAvLyB1bnRpbCBJbXByb3YgaXMgaW5pdGlhbGl6ZWQgLyBub3QgZGV0ZWN0ZWQuXG4gICAgICAgICAgICAodGhpcy5faW5zdGFsbFN0YXRlLnN0YXRlID09PSBcImZpbmlzaGVkXCIgLyogRmxhc2hTdGF0ZVR5cGUuRklOSVNIRUQgKi8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLl9jbGllbnQgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgIGhlYWRpbmcgPSBcIkluc3RhbGxpbmdcIjtcbiAgICAgICAgICAgIGxldCBwZXJjZW50YWdlO1xuICAgICAgICAgICAgbGV0IHVuZGV0ZXJtaW5hdGVMYWJlbDtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pbnN0YWxsU3RhdGUuc3RhdGUgPT09IFwiZmluaXNoZWRcIiAvKiBGbGFzaFN0YXRlVHlwZS5GSU5JU0hFRCAqLykge1xuICAgICAgICAgICAgICAgIC8vIFdlJ3JlIGRvbmUgd3JpdGluZyBhbmQgZGV0ZWN0aW5nIGltcHJvdiwgc2hvdyBzcGlubmVyXG4gICAgICAgICAgICAgICAgdW5kZXRlcm1pbmF0ZUxhYmVsID0gXCJXcmFwcGluZyB1cFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5faW5zdGFsbFN0YXRlLmRldGFpbHMucGVyY2VudGFnZSA8IDQpIHtcbiAgICAgICAgICAgICAgICAvLyBXZSdyZSB3cml0aW5nIHRoZSBmaXJtd2FyZSB1bmRlciA0JSwgc2hvdyBzcGlubmVyIG9yIGVsc2Ugd2UgZG9uJ3Qgc2hvdyBhbnkgcGl4ZWxzXG4gICAgICAgICAgICAgICAgdW5kZXRlcm1pbmF0ZUxhYmVsID0gXCJJbnN0YWxsaW5nXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBXZSdyZSB3cml0aW5nIHRoZSBmaXJtd2FyZSBvdmVyIDQlLCBzaG93IHByb2dyZXNzIGJhclxuICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2UgPSB0aGlzLl9pbnN0YWxsU3RhdGUuZGV0YWlscy5wZXJjZW50YWdlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGVudCA9IHRoaXMuX3JlbmRlclByb2dyZXNzKGh0bWwgYFxuICAgICAgICAgICR7dW5kZXRlcm1pbmF0ZUxhYmVsID8gaHRtbCBgJHt1bmRldGVybWluYXRlTGFiZWx9PGJyIC8+YCA6IFwiXCJ9XG4gICAgICAgICAgPGJyIC8+XG4gICAgICAgICAgVGhpcyB3aWxsIHRha2VcbiAgICAgICAgICAke3RoaXMuX2luc3RhbGxTdGF0ZS5jaGlwRmFtaWx5ID09PSBcIkVTUDgyNjZcIlxuICAgICAgICAgICAgICAgID8gXCJhIG1pbnV0ZVwiXG4gICAgICAgICAgICAgICAgOiBcIjIgbWludXRlc1wifS48YnIgLz5cbiAgICAgICAgICBLZWVwIHRoaXMgcGFnZSB2aXNpYmxlIHRvIHByZXZlbnQgc2xvdyBkb3duXG4gICAgICAgIGAsIHBlcmNlbnRhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2luc3RhbGxTdGF0ZS5zdGF0ZSA9PT0gXCJmaW5pc2hlZFwiIC8qIEZsYXNoU3RhdGVUeXBlLkZJTklTSEVEICovKSB7XG4gICAgICAgICAgICBoZWFkaW5nID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgY29uc3Qgc3VwcG9ydHNJbXByb3YgPSB0aGlzLl9jbGllbnQgIT09IG51bGw7XG4gICAgICAgICAgICBjb250ZW50ID0gaHRtbCBgXG4gICAgICAgIDxld3QtcGFnZS1tZXNzYWdlXG4gICAgICAgICAgc2xvdD1cImNvbnRlbnRcIlxuICAgICAgICAgIC5pY29uPSR7T0tfSUNPTn1cbiAgICAgICAgICBsYWJlbD1cIkluc3RhbGxhdGlvbiBjb21wbGV0ZSFcIlxuICAgICAgICA+PC9ld3QtcGFnZS1tZXNzYWdlPlxuXG4gICAgICAgIDxkaXYgc2xvdD1cImFjdGlvbnNcIj5cbiAgICAgICAgICA8ZXctdGV4dC1idXR0b25cbiAgICAgICAgICAgIEBjbGljaz0keygpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9XG4gICAgICAgICAgICAgICAgICAgIHN1cHBvcnRzSW1wcm92ICYmIHRoaXMuX2luc3RhbGxFcmFzZVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBcIlBST1ZJU0lPTlwiXG4gICAgICAgICAgICAgICAgICAgICAgICA6IFwiREFTSEJPQVJEXCI7XG4gICAgICAgICAgICB9fVxuICAgICAgICAgID5cbiAgICAgICAgICAgIE5leHRcbiAgICAgICAgICA8L2V3LXRleHQtYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIGA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5faW5zdGFsbFN0YXRlLnN0YXRlID09PSBcImVycm9yXCIgLyogRmxhc2hTdGF0ZVR5cGUuRVJST1IgKi8pIHtcbiAgICAgICAgICAgIGhlYWRpbmcgPSBcIkluc3RhbGxhdGlvbiBmYWlsZWRcIjtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBodG1sIGBcbiAgICAgICAgPGV3dC1wYWdlLW1lc3NhZ2VcbiAgICAgICAgICBzbG90PVwiY29udGVudFwiXG4gICAgICAgICAgLmljb249JHtFUlJPUl9JQ09OfVxuICAgICAgICAgIC5sYWJlbD0ke3RoaXMuX2luc3RhbGxTdGF0ZS5tZXNzYWdlfVxuICAgICAgICA+PC9ld3QtcGFnZS1tZXNzYWdlPlxuICAgICAgICA8ZGl2IHNsb3Q9XCJhY3Rpb25zXCI+XG4gICAgICAgICAgPGV3LXRleHQtYnV0dG9uXG4gICAgICAgICAgICBAY2xpY2s9JHthc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gXCJEQVNIQk9BUkRcIjtcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgQmFja1xuICAgICAgICAgIDwvZXctdGV4dC1idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2hlYWRpbmcsIGNvbnRlbnQsIGFsbG93Q2xvc2luZ107XG4gICAgfVxuICAgIF9yZW5kZXJMb2dzKCkge1xuICAgICAgICBsZXQgaGVhZGluZyA9IGBMb2dzYDtcbiAgICAgICAgbGV0IGNvbnRlbnQ7XG4gICAgICAgIGNvbnRlbnQgPSBodG1sIGBcbiAgICAgIDxkaXYgc2xvdD1cImNvbnRlbnRcIj5cbiAgICAgICAgPGV3dC1jb25zb2xlIC5wb3J0PSR7dGhpcy5wb3J0fSAubG9nZ2VyPSR7dGhpcy5sb2dnZXJ9PjwvZXd0LWNvbnNvbGU+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgc2xvdD1cImFjdGlvbnNcIj5cbiAgICAgICAgPGV3LXRleHQtYnV0dG9uXG4gICAgICAgICAgQGNsaWNrPSR7YXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoXCJld3QtY29uc29sZVwiKS5yZXNldCgpO1xuICAgICAgICB9fVxuICAgICAgICA+XG4gICAgICAgICAgUmVzZXQgRGV2aWNlXG4gICAgICAgIDwvZXctdGV4dC1idXR0b24+XG4gICAgICAgIDxldy10ZXh0LWJ1dHRvblxuICAgICAgICAgIEBjbGljaz0keygpID0+IHtcbiAgICAgICAgICAgIHRleHREb3dubG9hZCh0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihcImV3dC1jb25zb2xlXCIpLmxvZ3MoKSwgYGVzcC13ZWItdG9vbHMtbG9ncy50eHRgKTtcbiAgICAgICAgICAgIHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKFwiZXd0LWNvbnNvbGVcIikucmVzZXQoKTtcbiAgICAgICAgfX1cbiAgICAgICAgPlxuICAgICAgICAgIERvd25sb2FkIExvZ3NcbiAgICAgICAgPC9ldy10ZXh0LWJ1dHRvbj5cbiAgICAgICAgPGV3LXRleHQtYnV0dG9uXG4gICAgICAgICAgQGNsaWNrPSR7YXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoXCJld3QtY29uc29sZVwiKS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiREFTSEJPQVJEXCI7XG4gICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplKCk7XG4gICAgICAgIH19XG4gICAgICAgID5cbiAgICAgICAgICBCYWNrXG4gICAgICAgIDwvZXctdGV4dC1idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuICAgICAgICByZXR1cm4gW2hlYWRpbmcsIGNvbnRlbnRdO1xuICAgIH1cbiAgICB3aWxsVXBkYXRlKGNoYW5nZWRQcm9wcykge1xuICAgICAgICBpZiAoIWNoYW5nZWRQcm9wcy5oYXMoXCJfc3RhdGVcIikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBDbGVhciBlcnJvcnMgd2hlbiBjaGFuZ2luZyBiZXR3ZWVuIHBhZ2VzIHVubGVzcyB3ZSBjaGFuZ2VcbiAgICAgICAgLy8gdG8gdGhlIGVycm9yIHBhZ2UuXG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gXCJFUlJPUlwiKSB7XG4gICAgICAgICAgICB0aGlzLl9lcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBTY2FuIGZvciBTU0lEcyBvbiBwcm92aXNpb25cbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSBcIlBST1ZJU0lPTlwiKSB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVTc2lkcygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gUmVzZXQgdGhpcyB2YWx1ZSBpZiB3ZSBsZWF2ZSBwcm92aXNpb25pbmcuXG4gICAgICAgICAgICB0aGlzLl9wcm92aXNpb25Gb3JjZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gXCJJTlNUQUxMXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2luc3RhbGxDb25maXJtZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX2luc3RhbGxTdGF0ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBfdXBkYXRlU3NpZHModHJpZXMgPSAwKSB7XG4gICAgICAgIGNvbnN0IG9sZFNzaWRzID0gdGhpcy5fc3NpZHM7XG4gICAgICAgIHRoaXMuX3NzaWRzID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9idXN5ID0gdHJ1ZTtcbiAgICAgICAgbGV0IHNzaWRzO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3NpZHMgPSBhd2FpdCB0aGlzLl9jbGllbnQuc2NhbigpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgZmFpbCB3aGlsZSBsb2FkaW5nLCBwaWNrIFwiSm9pbiBvdGhlclwiXG4gICAgICAgICAgICBpZiAodGhpcy5fc3NpZHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NzaWRzID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RlZFNzaWQgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fYnVzeSA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIHdpbGwgcmV0cnkgYSBmZXcgdGltZXMgaWYgd2UgZG9uJ3QgZ2V0IGFueSByZXN1bHRzXG4gICAgICAgIGlmIChzc2lkcy5sZW5ndGggPT09IDAgJiYgdHJpZXMgPCAzKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIlNDSEVEVUxFIFJFVFJZXCIsIHRyaWVzKTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fdXBkYXRlU3NpZHModHJpZXMgKyAxKSwgMTAwMCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9sZFNzaWRzKSB7XG4gICAgICAgICAgICAvLyBJZiB3ZSBoYWQgYSBwcmV2aW91cyBsaXN0LCBlbnN1cmUgdGhlIHNlbGVjdGlvbiBpcyBzdGlsbCB2YWxpZFxuICAgICAgICAgICAgaWYgKHRoaXMuX3NlbGVjdGVkU3NpZCAmJlxuICAgICAgICAgICAgICAgICFzc2lkcy5maW5kKChzKSA9PiBzLm5hbWUgPT09IHRoaXMuX3NlbGVjdGVkU3NpZCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RlZFNzaWQgPSBzc2lkc1swXS5uYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2VsZWN0ZWRTc2lkID0gc3NpZHMubGVuZ3RoID8gc3NpZHNbMF0ubmFtZSA6IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3NpZHMgPSBzc2lkcztcbiAgICAgICAgdGhpcy5fYnVzeSA9IGZhbHNlO1xuICAgIH1cbiAgICBmaXJzdFVwZGF0ZWQoY2hhbmdlZFByb3BzKSB7XG4gICAgICAgIHN1cGVyLmZpcnN0VXBkYXRlZChjaGFuZ2VkUHJvcHMpO1xuICAgICAgICB0aGlzLl9ib2R5T3ZlcmZsb3cgPSBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93O1xuICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gXCJoaWRkZW5cIjtcbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZSgpO1xuICAgIH1cbiAgICB1cGRhdGVkKGNoYW5nZWRQcm9wcykge1xuICAgICAgICBzdXBlci51cGRhdGVkKGNoYW5nZWRQcm9wcyk7XG4gICAgICAgIGlmIChjaGFuZ2VkUHJvcHMuaGFzKFwiX3N0YXRlXCIpKSB7XG4gICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZShcInN0YXRlXCIsIHRoaXMuX3N0YXRlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fc3RhdGUgIT09IFwiUFJPVklTSU9OXCIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhbmdlZFByb3BzLmhhcyhcIl9zZWxlY3RlZFNzaWRcIikgJiYgdGhpcy5fc2VsZWN0ZWRTc2lkID09PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBJZiB3ZSBwaWNrIFwiSm9pbiBvdGhlclwiLCBzZWxlY3QgU1NJRCBpbnB1dC5cbiAgICAgICAgICAgIHRoaXMuX2ZvY3VzRm9ybUVsZW1lbnQoXCJldy1maWxsZWQtdGV4dC1maWVsZFtuYW1lPXNzaWRdXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNoYW5nZWRQcm9wcy5oYXMoXCJfc3NpZHNcIikpIHtcbiAgICAgICAgICAgIC8vIEZvcm0gaXMgc2hvd24gd2hlbiBTU0lEcyBhcmUgbG9hZGVkL21hcmtlZCBub3Qgc3VwcG9ydGVkXG4gICAgICAgICAgICB0aGlzLl9mb2N1c0Zvcm1FbGVtZW50KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2ZvY3VzRm9ybUVsZW1lbnQoc2VsZWN0b3IgPSBcImV3LWZpbGxlZC10ZXh0LWZpZWxkLCBldy1maWxsZWQtc2VsZWN0XCIpIHtcbiAgICAgICAgY29uc3QgZm9ybUVsID0gdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZm9ybUVsKSB7XG4gICAgICAgICAgICBmb3JtRWwudXBkYXRlQ29tcGxldGUudGhlbigoKSA9PiBzZXRUaW1lb3V0KCgpID0+IGZvcm1FbC5mb2N1cygpLCAxMDApKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBfaW5pdGlhbGl6ZShqdXN0SW5zdGFsbGVkID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKHRoaXMucG9ydC5yZWFkYWJsZSA9PT0gbnVsbCB8fCB0aGlzLnBvcnQud3JpdGFibGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gXCJFUlJPUlwiO1xuICAgICAgICAgICAgdGhpcy5fZXJyb3IgPVxuICAgICAgICAgICAgICAgIFwiU2VyaWFsIHBvcnQgaXMgbm90IHJlYWRhYmxlL3dyaXRhYmxlLiBDbG9zZSBhbnkgb3RoZXIgYXBwbGljYXRpb24gdXNpbmcgaXQgYW5kIHRyeSBhZ2Fpbi5cIjtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fbWFuaWZlc3QgPSBhd2FpdCBkb3dubG9hZE1hbmlmZXN0KHRoaXMubWFuaWZlc3RQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiRVJST1JcIjtcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yID0gXCJGYWlsZWQgdG8gZG93bmxvYWQgbWFuaWZlc3RcIjtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fbWFuaWZlc3QubmV3X2luc3RhbGxfaW1wcm92X3dhaXRfdGltZSA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fY2xpZW50ID0gbnVsbDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbGllbnQgPSBuZXcgSW1wcm92U2VyaWFsKHRoaXMucG9ydCwgdGhpcy5sb2dnZXIpO1xuICAgICAgICBjbGllbnQuYWRkRXZlbnRMaXN0ZW5lcihcInN0YXRlLWNoYW5nZWRcIiwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZXF1ZXN0VXBkYXRlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBjbGllbnQuYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yLWNoYW5nZWRcIiwgKCkgPT4gdGhpcy5yZXF1ZXN0VXBkYXRlKCkpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gSWYgYSBkZXZpY2Ugd2FzIGp1c3QgaW5zdGFsbGVkLCBnaXZlIG5ldyBmaXJtd2FyZSAxMCBzZWNvbmRzIChvdmVycmlkYWJsZSkgdG9cbiAgICAgICAgICAgIC8vIGZvcm1hdCB0aGUgcmVzdCBvZiB0aGUgZmxhc2ggYW5kIGRvIG90aGVyIHN0dWZmLlxuICAgICAgICAgICAgY29uc3QgdGltZW91dCA9ICFqdXN0SW5zdGFsbGVkXG4gICAgICAgICAgICAgICAgPyAxMDAwXG4gICAgICAgICAgICAgICAgOiB0aGlzLl9tYW5pZmVzdC5uZXdfaW5zdGFsbF9pbXByb3Zfd2FpdF90aW1lICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLl9tYW5pZmVzdC5uZXdfaW5zdGFsbF9pbXByb3Zfd2FpdF90aW1lICogMTAwMFxuICAgICAgICAgICAgICAgICAgICA6IDEwMDAwO1xuICAgICAgICAgICAgdGhpcy5faW5mbyA9IGF3YWl0IGNsaWVudC5pbml0aWFsaXplKHRpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5fY2xpZW50ID0gY2xpZW50O1xuICAgICAgICAgICAgY2xpZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJkaXNjb25uZWN0XCIsIHRoaXMuX2hhbmRsZURpc2Nvbm5lY3QpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIC8vIENsZWFyIG9sZCB2YWx1ZVxuICAgICAgICAgICAgdGhpcy5faW5mbyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBQb3J0Tm90UmVhZHkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiRVJST1JcIjtcbiAgICAgICAgICAgICAgICB0aGlzLl9lcnJvciA9XG4gICAgICAgICAgICAgICAgICAgIFwiU2VyaWFsIHBvcnQgaXMgbm90IHJlYWR5LiBDbG9zZSBhbnkgb3RoZXIgYXBwbGljYXRpb24gdXNpbmcgaXQgYW5kIHRyeSBhZ2Fpbi5cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NsaWVudCA9IG51bGw7IC8vIG5vdCBzdXBwb3J0ZWRcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihcIkltcHJvdiBpbml0aWFsaXphdGlvbiBmYWlsZWQuXCIsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgX3N0YXJ0SW5zdGFsbChlcmFzZSkge1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IFwiSU5TVEFMTFwiO1xuICAgICAgICB0aGlzLl9pbnN0YWxsRXJhc2UgPSBlcmFzZTtcbiAgICAgICAgdGhpcy5faW5zdGFsbENvbmZpcm1lZCA9IGZhbHNlO1xuICAgIH1cbiAgICBhc3luYyBfY29uZmlybUluc3RhbGwoKSB7XG4gICAgICAgIHRoaXMuX2luc3RhbGxDb25maXJtZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl9pbnN0YWxsU3RhdGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLl9jbGllbnQpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2Nsb3NlQ2xpZW50V2l0aG91dEV2ZW50cyh0aGlzLl9jbGllbnQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NsaWVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLy8gQ2xvc2UgcG9ydC4gRVNQTG9hZGVyIGxpa2VzIG9wZW5pbmcgaXQuXG4gICAgICAgIGF3YWl0IHRoaXMucG9ydC5jbG9zZSgpO1xuICAgICAgICBmbGFzaCgoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2luc3RhbGxTdGF0ZSA9IHN0YXRlO1xuICAgICAgICAgICAgaWYgKHN0YXRlLnN0YXRlID09PSBcImZpbmlzaGVkXCIgLyogRmxhc2hTdGF0ZVR5cGUuRklOSVNIRUQgKi8pIHtcbiAgICAgICAgICAgICAgICBzbGVlcCgxMDApXG4gICAgICAgICAgICAgICAgICAgIC8vIEZsYXNoaW5nIGNsb3NlcyB0aGUgcG9ydFxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnBvcnQub3Blbih7IGJhdWRSYXRlOiAxMTUyMDAsIGJ1ZmZlclNpemU6IDgxOTIgfSkpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMuX2luaXRpYWxpemUodHJ1ZSkpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVxdWVzdFVwZGF0ZSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHN0YXRlLnN0YXRlID09PSBcImVycm9yXCIgLyogRmxhc2hTdGF0ZVR5cGUuRVJST1IgKi8pIHtcbiAgICAgICAgICAgICAgICBzbGVlcCgxMDApXG4gICAgICAgICAgICAgICAgICAgIC8vIEZsYXNoaW5nIGNsb3NlcyB0aGUgcG9ydFxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnBvcnQub3Blbih7IGJhdWRSYXRlOiAxMTUyMDAsIGJ1ZmZlclNpemU6IDgxOTIgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB0aGlzLnBvcnQsIHRoaXMubWFuaWZlc3RQYXRoLCB0aGlzLl9tYW5pZmVzdCwgdGhpcy5faW5zdGFsbEVyYXNlKTtcbiAgICB9XG4gICAgYXN5bmMgX2RvUHJvdmlzaW9uKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHRoaXMuX2J1c3kgPSB0cnVlO1xuICAgICAgICB0aGlzLl93YXNQcm92aXNpb25lZCA9XG4gICAgICAgICAgICB0aGlzLl9jbGllbnQuc3RhdGUgPT09IEltcHJvdlNlcmlhbEN1cnJlbnRTdGF0ZS5QUk9WSVNJT05FRDtcbiAgICAgICAgY29uc3Qgc3NpZCA9IHRoaXMuX3NlbGVjdGVkU3NpZCA9PT0gbnVsbFxuICAgICAgICAgICAgPyB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihcImV3LWZpbGxlZC10ZXh0LWZpZWxkW25hbWU9c3NpZF1cIikudmFsdWVcbiAgICAgICAgICAgIDogdGhpcy5fc2VsZWN0ZWRTc2lkO1xuICAgICAgICBjb25zdCBwYXNzd29yZCA9ICgoX2EgPSB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihcImV3LWZpbGxlZC10ZXh0LWZpZWxkW25hbWU9cGFzc3dvcmRdXCIpKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EudmFsdWUpIHx8IFwiXCI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9jbGllbnQucHJvdmlzaW9uKHNzaWQsIHBhc3N3b3JkLCAzMDAwMCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5fYnVzeSA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fcHJvdmlzaW9uRm9yY2UgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBfY2xvc2VEaWFsb2coKSB7XG4gICAgICAgIHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKFwiZXctZGlhbG9nXCIpLmNsb3NlKCk7XG4gICAgfVxuICAgIGFzeW5jIF9oYW5kbGVDbG9zZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2NsaWVudCkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fY2xvc2VDbGllbnRXaXRob3V0RXZlbnRzKHRoaXMuX2NsaWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZmlyZUV2ZW50KHRoaXMsIFwiY2xvc2VkXCIpO1xuICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gdGhpcy5fYm9keU92ZXJmbG93O1xuICAgICAgICB0aGlzLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiBpZiB0aGUgZGV2aWNlIHJ1bnMgc2FtZSBmaXJtd2FyZSBhcyBtYW5pZmVzdC5cbiAgICAgKi9cbiAgICBnZXQgX2lzU2FtZUZpcm13YXJlKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIHJldHVybiAhdGhpcy5faW5mb1xuICAgICAgICAgICAgPyBmYWxzZVxuICAgICAgICAgICAgOiAoKF9hID0gdGhpcy5vdmVycmlkZXMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jaGVja1NhbWVGaXJtd2FyZSlcbiAgICAgICAgICAgICAgICA/IHRoaXMub3ZlcnJpZGVzLmNoZWNrU2FtZUZpcm13YXJlKHRoaXMuX21hbmlmZXN0LCB0aGlzLl9pbmZvKVxuICAgICAgICAgICAgICAgIDogdGhpcy5faW5mby5maXJtd2FyZSA9PT0gdGhpcy5fbWFuaWZlc3QubmFtZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIGlmIHRoZSBkZXZpY2UgcnVucyBzYW1lIGZpcm13YXJlIGFuZCB2ZXJzaW9uIGFzIG1hbmlmZXN0LlxuICAgICAqL1xuICAgIGdldCBfaXNTYW1lVmVyc2lvbigpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9pc1NhbWVGaXJtd2FyZSAmJiB0aGlzLl9pbmZvLnZlcnNpb24gPT09IHRoaXMuX21hbmlmZXN0LnZlcnNpb24pO1xuICAgIH1cbiAgICBhc3luYyBfY2xvc2VDbGllbnRXaXRob3V0RXZlbnRzKGNsaWVudCkge1xuICAgICAgICBjbGllbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImRpc2Nvbm5lY3RcIiwgdGhpcy5faGFuZGxlRGlzY29ubmVjdCk7XG4gICAgICAgIGF3YWl0IGNsaWVudC5jbG9zZSgpO1xuICAgIH1cbiAgICBfcHJldmVudERlZmF1bHQoZXYpIHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG59XG5Fd3RJbnN0YWxsRGlhbG9nLnN0eWxlcyA9IFtcbiAgICBkaWFsb2dTdHlsZXMsXG4gICAgY3NzIGBcbiAgICAgIDpob3N0IHtcbiAgICAgICAgLS1tZGMtZGlhbG9nLW1heC13aWR0aDogMzkwcHg7XG4gICAgICB9XG4gICAgICBkaXZbc2xvdD1cImhlYWRsaW5lXCJdIHtcbiAgICAgICAgcGFkZGluZy1yaWdodDogNDhweDtcbiAgICAgIH1cbiAgICAgIGV3LWljb24tYnV0dG9uW3Nsb3Q9XCJoZWFkbGluZVwiXSB7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgcmlnaHQ6IDRweDtcbiAgICAgICAgdG9wOiA4cHg7XG4gICAgICB9XG4gICAgICBldy1pY29uLWJ1dHRvbltzbG90PVwiaGVhZGxpbmVcIl0gc3ZnIHtcbiAgICAgICAgcGFkZGluZzogOHB4O1xuICAgICAgICBjb2xvcjogdmFyKC0tdGV4dC1jb2xvcik7XG4gICAgICB9XG4gICAgICAuZGlhbG9nLW5hdiBzdmcge1xuICAgICAgICBjb2xvcjogdmFyKC0tdGV4dC1jb2xvcik7XG4gICAgICB9XG4gICAgICAudGFibGUtcm93IHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIH1cbiAgICAgIC50YWJsZS1yb3cubGFzdCB7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDE2cHg7XG4gICAgICB9XG4gICAgICAudGFibGUtcm93IHN2ZyB7XG4gICAgICAgIHdpZHRoOiAyMHB4O1xuICAgICAgICBtYXJnaW4tcmlnaHQ6IDhweDtcbiAgICAgIH1cbiAgICAgIGV3LWZpbGxlZC10ZXh0LWZpZWxkLFxuICAgICAgZXctZmlsbGVkLXNlbGVjdCB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICBtYXJnaW4tdG9wOiAxNnB4O1xuICAgICAgfVxuICAgICAgbGFiZWwuZm9ybWZpZWxkIHtcbiAgICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IDhweDtcbiAgICAgIH1cbiAgICAgIGV3LWxpc3Qge1xuICAgICAgICBtYXJnaW46IDAgLTI0cHg7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICB9XG4gICAgICBldy1saXN0LWl0ZW0gc3ZnIHtcbiAgICAgICAgaGVpZ2h0OiAyNHB4O1xuICAgICAgfVxuICAgICAgZXd0LXBhZ2UtbWVzc2FnZSArIGV3LWxpc3Qge1xuICAgICAgICBwYWRkaW5nLXRvcDogMTZweDtcbiAgICAgIH1cbiAgICAgIC5mYWtlLWljb24ge1xuICAgICAgICB3aWR0aDogMjRweDtcbiAgICAgIH1cbiAgICAgIC5lcnJvciB7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1kYW5nZXItY29sb3IpO1xuICAgICAgfVxuICAgICAgLmRhbmdlciB7XG4gICAgICAgIC0tbWRjLXRoZW1lLXByaW1hcnk6IHZhcigtLWRhbmdlci1jb2xvcik7XG4gICAgICAgIC0tbWRjLXRoZW1lLXNlY29uZGFyeTogdmFyKC0tZGFuZ2VyLWNvbG9yKTtcbiAgICAgICAgLS1tZC1zeXMtY29sb3ItcHJpbWFyeTogdmFyKC0tZGFuZ2VyLWNvbG9yKTtcbiAgICAgICAgLS1tZC1zeXMtY29sb3Itb24tc3VyZmFjZTogdmFyKC0tZGFuZ2VyLWNvbG9yKTtcbiAgICAgIH1cbiAgICAgIGJ1dHRvbi5saW5rIHtcbiAgICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgICAgY29sb3I6IGluaGVyaXQ7XG4gICAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgZm9udDogaW5oZXJpdDtcbiAgICAgICAgdGV4dC1hbGlnbjogbGVmdDtcbiAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIH1cbiAgICAgIDpob3N0KFtzdGF0ZT1cIkxPR1NcIl0pIGV3LWRpYWxvZyB7XG4gICAgICAgIG1heC13aWR0aDogOTB2dztcbiAgICAgICAgbWF4LWhlaWdodDogOTB2aDtcbiAgICAgIH1cbiAgICAgIGV3dC1jb25zb2xlIHtcbiAgICAgICAgd2lkdGg6IGNhbGMoODB2dyAtIDQ4cHgpO1xuICAgICAgICBoZWlnaHQ6IGNhbGMoOTB2aCAtIDE2OHB4KTtcbiAgICAgIH1cbiAgICBgLFxuXTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIEV3dEluc3RhbGxEaWFsb2cucHJvdG90eXBlLCBcIl9jbGllbnRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIEV3dEluc3RhbGxEaWFsb2cucHJvdG90eXBlLCBcIl9zdGF0ZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgRXd0SW5zdGFsbERpYWxvZy5wcm90b3R5cGUsIFwiX2luc3RhbGxFcmFzZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgRXd0SW5zdGFsbERpYWxvZy5wcm90b3R5cGUsIFwiX2luc3RhbGxDb25maXJtZWRcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIEV3dEluc3RhbGxEaWFsb2cucHJvdG90eXBlLCBcIl9pbnN0YWxsU3RhdGVcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHN0YXRlKClcbl0sIEV3dEluc3RhbGxEaWFsb2cucHJvdG90eXBlLCBcIl9wcm92aXNpb25Gb3JjZVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgRXd0SW5zdGFsbERpYWxvZy5wcm90b3R5cGUsIFwiX2Vycm9yXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBFd3RJbnN0YWxsRGlhbG9nLnByb3RvdHlwZSwgXCJfYnVzeVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgc3RhdGUoKVxuXSwgRXd0SW5zdGFsbERpYWxvZy5wcm90b3R5cGUsIFwiX3NzaWRzXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBzdGF0ZSgpXG5dLCBFd3RJbnN0YWxsRGlhbG9nLnByb3RvdHlwZSwgXCJfc2VsZWN0ZWRTc2lkXCIsIHZvaWQgMCk7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJld3QtaW5zdGFsbC1kaWFsb2dcIiwgRXd0SW5zdGFsbERpYWxvZyk7XG4iLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBMaXRFbGVtZW50LCBodG1sLCBjc3MgfSBmcm9tIFwibGl0XCI7XG5pbXBvcnQgeyBwcm9wZXJ0eSB9IGZyb20gXCJsaXQvZGVjb3JhdG9ycy5qc1wiO1xuY2xhc3MgRXd0UGFnZU1lc3NhZ2UgZXh0ZW5kcyBMaXRFbGVtZW50IHtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBodG1sIGBcbiAgICAgIDxkaXYgY2xhc3M9XCJpY29uXCI+JHt0aGlzLmljb259PC9kaXY+XG4gICAgICAke3RoaXMubGFiZWx9XG4gICAgYDtcbiAgICB9XG59XG5Fd3RQYWdlTWVzc2FnZS5zdHlsZXMgPSBjc3MgYFxuICAgIDpob3N0IHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIH1cbiAgICAuaWNvbiB7XG4gICAgICBmb250LXNpemU6IDUwcHg7XG4gICAgICBsaW5lLWhlaWdodDogODBweDtcbiAgICAgIGNvbG9yOiBibGFjaztcbiAgICB9XG4gIGA7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBFd3RQYWdlTWVzc2FnZS5wcm90b3R5cGUsIFwiaWNvblwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcHJvcGVydHkoKVxuXSwgRXd0UGFnZU1lc3NhZ2UucHJvdG90eXBlLCBcImxhYmVsXCIsIHZvaWQgMCk7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJld3QtcGFnZS1tZXNzYWdlXCIsIEV3dFBhZ2VNZXNzYWdlKTtcbiIsImltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IExpdEVsZW1lbnQsIGh0bWwsIGNzcyB9IGZyb20gXCJsaXRcIjtcbmltcG9ydCB7IHByb3BlcnR5IH0gZnJvbSBcImxpdC9kZWNvcmF0b3JzLmpzXCI7XG5pbXBvcnQgXCIuLi9jb21wb25lbnRzL2V3LWNpcmN1bGFyLXByb2dyZXNzXCI7XG5jbGFzcyBFd3RQYWdlUHJvZ3Jlc3MgZXh0ZW5kcyBMaXRFbGVtZW50IHtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBodG1sIGBcbiAgICAgIDxkaXY+XG4gICAgICAgIDxldy1jaXJjdWxhci1wcm9ncmVzc1xuICAgICAgICAgIGFjdGl2ZVxuICAgICAgICAgID9pbmRldGVybWluYXRlPSR7dGhpcy5wcm9ncmVzcyA9PT0gdW5kZWZpbmVkfVxuICAgICAgICAgIC52YWx1ZT0ke3RoaXMucHJvZ3Jlc3MgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyB0aGlzLnByb2dyZXNzIC8gMTAwXG4gICAgICAgICAgICA6IHVuZGVmaW5lZH1cbiAgICAgICAgPjwvZXctY2lyY3VsYXItcHJvZ3Jlc3M+XG4gICAgICAgICR7dGhpcy5wcm9ncmVzcyAhPT0gdW5kZWZpbmVkID8gaHRtbCBgPGRpdj4ke3RoaXMucHJvZ3Jlc3N9JTwvZGl2PmAgOiBcIlwifVxuICAgICAgPC9kaXY+XG4gICAgICAke3RoaXMubGFiZWx9XG4gICAgYDtcbiAgICB9XG59XG5Fd3RQYWdlUHJvZ3Jlc3Muc3R5bGVzID0gY3NzIGBcbiAgICA6aG9zdCB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB9XG4gICAgZXctY2lyY3VsYXItcHJvZ3Jlc3Mge1xuICAgICAgbWFyZ2luLWJvdHRvbTogMTZweDtcbiAgICB9XG4gIGA7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBFd3RQYWdlUHJvZ3Jlc3MucHJvdG90eXBlLCBcImxhYmVsXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICBwcm9wZXJ0eSgpXG5dLCBFd3RQYWdlUHJvZ3Jlc3MucHJvdG90eXBlLCBcInByb2dyZXNzXCIsIHZvaWQgMCk7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoXCJld3QtcGFnZS1wcm9ncmVzc1wiLCBFd3RQYWdlUHJvZ3Jlc3MpO1xuIiwiZXhwb3J0IGNsYXNzIENvbG9yZWRDb25zb2xlIHtcbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBib2xkOiBmYWxzZSxcbiAgICAgICAgICAgIGl0YWxpYzogZmFsc2UsXG4gICAgICAgICAgICB1bmRlcmxpbmU6IGZhbHNlLFxuICAgICAgICAgICAgc3RyaWtldGhyb3VnaDogZmFsc2UsXG4gICAgICAgICAgICBmb3JlZ3JvdW5kQ29sb3I6IG51bGwsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IG51bGwsXG4gICAgICAgICAgICBjYXJyaWFnZVJldHVybjogZmFsc2UsXG4gICAgICAgICAgICBsaW5lczogW10sXG4gICAgICAgICAgICBzZWNyZXQ6IGZhbHNlLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBsb2dzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50YXJnZXRFbGVtZW50LmlubmVyVGV4dDtcbiAgICB9XG4gICAgcHJvY2Vzc0xpbmUobGluZSkge1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgIGNvbnN0IHJlID0gLyg/OlxcMDMzfFxcXFwwMzMpKD86XFxbKC4qPylbQC1+XXxcXF0uKj8oPzpcXDAwN3xcXDAzM1xcXFwpKS9nO1xuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIGNvbnN0IGxpbmVTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG4gICAgICAgIGxpbmVTcGFuLmNsYXNzTGlzdC5hZGQoXCJsaW5lXCIpO1xuICAgICAgICBjb25zdCBhZGRTcGFuID0gKGNvbnRlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChjb250ZW50ID09PSBcIlwiKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmJvbGQpXG4gICAgICAgICAgICAgICAgc3Bhbi5jbGFzc0xpc3QuYWRkKFwibG9nLWJvbGRcIik7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5pdGFsaWMpXG4gICAgICAgICAgICAgICAgc3Bhbi5jbGFzc0xpc3QuYWRkKFwibG9nLWl0YWxpY1wiKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnVuZGVybGluZSlcbiAgICAgICAgICAgICAgICBzcGFuLmNsYXNzTGlzdC5hZGQoXCJsb2ctdW5kZXJsaW5lXCIpO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc3RyaWtldGhyb3VnaClcbiAgICAgICAgICAgICAgICBzcGFuLmNsYXNzTGlzdC5hZGQoXCJsb2ctc3RyaWtldGhyb3VnaFwiKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNlY3JldClcbiAgICAgICAgICAgICAgICBzcGFuLmNsYXNzTGlzdC5hZGQoXCJsb2ctc2VjcmV0XCIpO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuZm9yZWdyb3VuZENvbG9yICE9PSBudWxsKVxuICAgICAgICAgICAgICAgIHNwYW4uY2xhc3NMaXN0LmFkZChgbG9nLWZnLSR7dGhpcy5zdGF0ZS5mb3JlZ3JvdW5kQ29sb3J9YCk7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5iYWNrZ3JvdW5kQ29sb3IgIT09IG51bGwpXG4gICAgICAgICAgICAgICAgc3Bhbi5jbGFzc0xpc3QuYWRkKGBsb2ctYmctJHt0aGlzLnN0YXRlLmJhY2tncm91bmRDb2xvcn1gKTtcbiAgICAgICAgICAgIHNwYW4uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY29udGVudCkpO1xuICAgICAgICAgICAgbGluZVNwYW4uYXBwZW5kQ2hpbGQoc3Bhbik7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWNyZXQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWRhY3RlZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgICAgICAgICAgICAgIHJlZGFjdGVkLmNsYXNzTGlzdC5hZGQoXCJsb2ctc2VjcmV0LXJlZGFjdGVkXCIpO1xuICAgICAgICAgICAgICAgIHJlZGFjdGVkLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFwiW3JlZGFjdGVkXVwiKSk7XG4gICAgICAgICAgICAgICAgbGluZVNwYW4uYXBwZW5kQ2hpbGQocmVkYWN0ZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgY29uc3QgbWF0Y2ggPSByZS5leGVjKGxpbmUpO1xuICAgICAgICAgICAgaWYgKG1hdGNoID09PSBudWxsKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY29uc3QgaiA9IG1hdGNoLmluZGV4O1xuICAgICAgICAgICAgYWRkU3BhbihsaW5lLnN1YnN0cmluZyhpLCBqKSk7XG4gICAgICAgICAgICBpID0gaiArIG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChtYXRjaFsxXSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgZm9yIChjb25zdCBjb2xvckNvZGUgb2YgbWF0Y2hbMV0uc3BsaXQoXCI7XCIpKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChwYXJzZUludChjb2xvckNvZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlc2V0XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmJvbGQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuaXRhbGljID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnVuZGVybGluZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5zdHJpa2V0aHJvdWdoID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmZvcmVncm91bmRDb2xvciA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmJhY2tncm91bmRDb2xvciA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnNlY3JldCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuYm9sZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5pdGFsaWMgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUudW5kZXJsaW5lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnNlY3JldCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWNyZXQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnN0cmlrZXRocm91Z2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjI6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmJvbGQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDIzOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5pdGFsaWMgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDI0OlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS51bmRlcmxpbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDI5OlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5zdHJpa2V0aHJvdWdoID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzMDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZm9yZWdyb3VuZENvbG9yID0gXCJibGFja1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzE6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmZvcmVncm91bmRDb2xvciA9IFwicmVkXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzMjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZm9yZWdyb3VuZENvbG9yID0gXCJncmVlblwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzM6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmZvcmVncm91bmRDb2xvciA9IFwieWVsbG93XCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzNDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZm9yZWdyb3VuZENvbG9yID0gXCJibHVlXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzNTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZm9yZWdyb3VuZENvbG9yID0gXCJtYWdlbnRhXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzNjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZm9yZWdyb3VuZENvbG9yID0gXCJjeWFuXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzNzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZm9yZWdyb3VuZENvbG9yID0gXCJ3aGl0ZVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzk6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmZvcmVncm91bmRDb2xvciA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0MTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuYmFja2dyb3VuZENvbG9yID0gXCJyZWRcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDQyOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5iYWNrZ3JvdW5kQ29sb3IgPSBcImdyZWVuXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0MzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuYmFja2dyb3VuZENvbG9yID0gXCJ5ZWxsb3dcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ0OlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5iYWNrZ3JvdW5kQ29sb3IgPSBcImJsdWVcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ1OlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5iYWNrZ3JvdW5kQ29sb3IgPSBcIm1hZ2VudGFcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ2OlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5iYWNrZ3JvdW5kQ29sb3IgPSBcImN5YW5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ3OlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5iYWNrZ3JvdW5kQ29sb3IgPSBcIndoaXRlXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0MDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuYmFja2dyb3VuZENvbG9yID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhZGRTcGFuKGxpbmUuc3Vic3RyaW5nKGkpKTtcbiAgICAgICAgcmV0dXJuIGxpbmVTcGFuO1xuICAgIH1cbiAgICBwcm9jZXNzTGluZXMoKSB7XG4gICAgICAgIGNvbnN0IGF0Qm90dG9tID0gdGhpcy50YXJnZXRFbGVtZW50LnNjcm9sbFRvcCA+XG4gICAgICAgICAgICB0aGlzLnRhcmdldEVsZW1lbnQuc2Nyb2xsSGVpZ2h0IC0gdGhpcy50YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCAtIDUwO1xuICAgICAgICBjb25zdCBwcmV2Q2FycmlhZ2VSZXR1cm4gPSB0aGlzLnN0YXRlLmNhcnJpYWdlUmV0dXJuO1xuICAgICAgICBjb25zdCBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUubGluZXMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGxpbmUgb2YgdGhpcy5zdGF0ZS5saW5lcykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2FycmlhZ2VSZXR1cm4gJiYgbGluZSAhPT0gXCJcXG5cIikge1xuICAgICAgICAgICAgICAgIGlmIChmcmFnbWVudC5jaGlsZEVsZW1lbnRDb3VudCkge1xuICAgICAgICAgICAgICAgICAgICBmcmFnbWVudC5yZW1vdmVDaGlsZChmcmFnbWVudC5sYXN0Q2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKHRoaXMucHJvY2Vzc0xpbmUobGluZSkpO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS5jYXJyaWFnZVJldHVybiA9IGxpbmUuaW5jbHVkZXMoXCJcXHJcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByZXZDYXJyaWFnZVJldHVybiAmJiB0aGlzLnN0YXRlLmxpbmVzWzBdICE9PSBcIlxcblwiKSB7XG4gICAgICAgICAgICB0aGlzLnRhcmdldEVsZW1lbnQucmVwbGFjZUNoaWxkKGZyYWdtZW50LCB0aGlzLnRhcmdldEVsZW1lbnQubGFzdENoaWxkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudC5hcHBlbmRDaGlsZChmcmFnbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZS5saW5lcyA9IFtdO1xuICAgICAgICAvLyBLZWVwIHNjcm9sbCBhdCBib3R0b21cbiAgICAgICAgaWYgKGF0Qm90dG9tKSB7XG4gICAgICAgICAgICB0aGlzLnRhcmdldEVsZW1lbnQuc2Nyb2xsVG9wID0gdGhpcy50YXJnZXRFbGVtZW50LnNjcm9sbEhlaWdodDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRMaW5lKGxpbmUpIHtcbiAgICAgICAgLy8gUHJvY2Vzc2luZyBvZiBsaW5lcyBpcyBkZWZlcnJlZCBmb3IgcGVyZm9ybWFuY2UgcmVhc29uc1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5saW5lcy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnByb2Nlc3NMaW5lcygpLCAwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXRlLmxpbmVzLnB1c2gobGluZSk7XG4gICAgfVxufVxuZXhwb3J0IGNvbnN0IGNvbG9yZWRDb25zb2xlU3R5bGVzID0gYFxuICAubG9nIHtcbiAgICBmbGV4OiAxO1xuICAgIGJhY2tncm91bmQtY29sb3I6ICMxYzFjMWM7XG4gICAgZm9udC1mYW1pbHk6IFwiU0ZNb25vLVJlZ3VsYXJcIiwgQ29uc29sYXMsIFwiTGliZXJhdGlvbiBNb25vXCIsIE1lbmxvLCBDb3VyaWVyLFxuICAgICAgbW9ub3NwYWNlO1xuICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICBwYWRkaW5nOiAxNnB4O1xuICAgIG92ZXJmbG93OiBhdXRvO1xuICAgIGxpbmUtaGVpZ2h0OiAxLjQ1O1xuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG4gICAgb3ZlcmZsb3ctd3JhcDogYnJlYWstd29yZDtcbiAgICBjb2xvcjogI2RkZDtcbiAgfVxuXG4gIC5sb2ctYm9sZCB7XG4gICAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gIH1cbiAgLmxvZy1pdGFsaWMge1xuICAgIGZvbnQtc3R5bGU6IGl0YWxpYztcbiAgfVxuICAubG9nLXVuZGVybGluZSB7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7XG4gIH1cbiAgLmxvZy1zdHJpa2V0aHJvdWdoIHtcbiAgICB0ZXh0LWRlY29yYXRpb246IGxpbmUtdGhyb3VnaDtcbiAgfVxuICAubG9nLXVuZGVybGluZS5sb2ctc3RyaWtldGhyb3VnaCB7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmUgbGluZS10aHJvdWdoO1xuICB9XG4gIC5sb2ctc2VjcmV0IHtcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xuICAgIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xuICAgIHVzZXItc2VsZWN0OiBub25lO1xuICB9XG4gIC5sb2ctc2VjcmV0LXJlZGFjdGVkIHtcbiAgICBvcGFjaXR5OiAwO1xuICAgIHdpZHRoOiAxcHg7XG4gICAgZm9udC1zaXplOiAxcHg7XG4gIH1cbiAgLmxvZy1mZy1ibGFjayB7XG4gICAgY29sb3I6IHJnYigxMjgsIDEyOCwgMTI4KTtcbiAgfVxuICAubG9nLWZnLXJlZCB7XG4gICAgY29sb3I6IHJnYigyNTUsIDAsIDApO1xuICB9XG4gIC5sb2ctZmctZ3JlZW4ge1xuICAgIGNvbG9yOiByZ2IoMCwgMjU1LCAwKTtcbiAgfVxuICAubG9nLWZnLXllbGxvdyB7XG4gICAgY29sb3I6IHJnYigyNTUsIDI1NSwgMCk7XG4gIH1cbiAgLmxvZy1mZy1ibHVlIHtcbiAgICBjb2xvcjogcmdiKDAsIDAsIDI1NSk7XG4gIH1cbiAgLmxvZy1mZy1tYWdlbnRhIHtcbiAgICBjb2xvcjogcmdiKDI1NSwgMCwgMjU1KTtcbiAgfVxuICAubG9nLWZnLWN5YW4ge1xuICAgIGNvbG9yOiByZ2IoMCwgMjU1LCAyNTUpO1xuICB9XG4gIC5sb2ctZmctd2hpdGUge1xuICAgIGNvbG9yOiByZ2IoMTg3LCAxODcsIDE4Nyk7XG4gIH1cbiAgLmxvZy1iZy1ibGFjayB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDAsIDAsIDApO1xuICB9XG4gIC5sb2ctYmctcmVkIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMjU1LCAwLCAwKTtcbiAgfVxuICAubG9nLWJnLWdyZWVuIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMCwgMjU1LCAwKTtcbiAgfVxuICAubG9nLWJnLXllbGxvdyB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDI1NSwgMjU1LCAwKTtcbiAgfVxuICAubG9nLWJnLWJsdWUge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYigwLCAwLCAyNTUpO1xuICB9XG4gIC5sb2ctYmctbWFnZW50YSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDI1NSwgMCwgMjU1KTtcbiAgfVxuICAubG9nLWJnLWN5YW4ge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYigwLCAyNTUsIDI1NSk7XG4gIH1cbiAgLmxvZy1iZy13aGl0ZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDI1NSwgMjU1LCAyNTUpO1xuICB9XG5gO1xuIiwiZXhwb3J0IGNvbnN0IGZpbGVEb3dubG9hZCA9IChocmVmLCBmaWxlbmFtZSA9IFwiXCIpID0+IHtcbiAgICBjb25zdCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIik7XG4gICAgYS50YXJnZXQgPSBcIl9ibGFua1wiO1xuICAgIGEuaHJlZiA9IGhyZWY7XG4gICAgYS5kb3dubG9hZCA9IGZpbGVuYW1lO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XG4gICAgYS5kaXNwYXRjaEV2ZW50KG5ldyBNb3VzZUV2ZW50KFwiY2xpY2tcIikpO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoYSk7XG59O1xuZXhwb3J0IGNvbnN0IHRleHREb3dubG9hZCA9ICh0ZXh0LCBmaWxlbmFtZSA9IFwiXCIpID0+IHtcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3RleHRdLCB7IHR5cGU6IFwidGV4dC9wbGFpblwiIH0pO1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgZmlsZURvd25sb2FkKHVybCwgZmlsZW5hbWUpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpLCAwKTtcbn07XG4iLCJleHBvcnQgY29uc3QgZmlyZUV2ZW50ID0gKGV2ZW50VGFyZ2V0LCB0eXBlLCBcbi8vIEB0cy1pZ25vcmVcbmRldGFpbCwgb3B0aW9ucykgPT4ge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIGNvbnN0IGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KHR5cGUsIHtcbiAgICAgICAgYnViYmxlczogb3B0aW9ucy5idWJibGVzID09PSB1bmRlZmluZWQgPyB0cnVlIDogb3B0aW9ucy5idWJibGVzLFxuICAgICAgICBjYW5jZWxhYmxlOiBCb29sZWFuKG9wdGlvbnMuY2FuY2VsYWJsZSksXG4gICAgICAgIGNvbXBvc2VkOiBvcHRpb25zLmNvbXBvc2VkID09PSB1bmRlZmluZWQgPyB0cnVlIDogb3B0aW9ucy5jb21wb3NlZCxcbiAgICAgICAgZGV0YWlsLFxuICAgIH0pO1xuICAgIGV2ZW50VGFyZ2V0LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xufTtcbiIsImV4cG9ydCBjbGFzcyBMaW5lQnJlYWtUcmFuc2Zvcm1lciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuY2h1bmtzID0gXCJcIjtcbiAgICB9XG4gICAgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAgIC8vIEFwcGVuZCBuZXcgY2h1bmtzIHRvIGV4aXN0aW5nIGNodW5rcy5cbiAgICAgICAgdGhpcy5jaHVua3MgKz0gY2h1bms7XG4gICAgICAgIC8vIEZvciBlYWNoIGxpbmUgYnJlYWtzIGluIGNodW5rcywgc2VuZCB0aGUgcGFyc2VkIGxpbmVzIG91dC5cbiAgICAgICAgY29uc3QgbGluZXMgPSB0aGlzLmNodW5rcy5zcGxpdCgvXFxyP1xcbi8pO1xuICAgICAgICB0aGlzLmNodW5rcyA9IGxpbmVzLnBvcCgpO1xuICAgICAgICBsaW5lcy5mb3JFYWNoKChsaW5lKSA9PiBjb250cm9sbGVyLmVucXVldWUobGluZSArIFwiXFxyXFxuXCIpKTtcbiAgICB9XG4gICAgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgICAvLyBXaGVuIHRoZSBzdHJlYW0gaXMgY2xvc2VkLCBmbHVzaCBhbnkgcmVtYWluaW5nIGNodW5rcyBvdXQuXG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZSh0aGlzLmNodW5rcyk7XG4gICAgfVxufVxuIiwiZXhwb3J0IGNvbnN0IGRvd25sb2FkTWFuaWZlc3QgPSBhc3luYyAobWFuaWZlc3RQYXRoKSA9PiB7XG4gICAgY29uc3QgbWFuaWZlc3RVUkwgPSBuZXcgVVJMKG1hbmlmZXN0UGF0aCwgbG9jYXRpb24udG9TdHJpbmcoKSkudG9TdHJpbmcoKTtcbiAgICBjb25zdCByZXNwID0gYXdhaXQgZmV0Y2gobWFuaWZlc3RVUkwpO1xuICAgIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgcmVzcC5qc29uKCk7XG4gICAgaWYgKFwibmV3X2luc3RhbGxfc2tpcF9lcmFzZVwiIGluIG1hbmlmZXN0KSB7XG4gICAgICAgIGNvbnNvbGUud2FybignTWFuaWZlc3Qgb3B0aW9uIFwibmV3X2luc3RhbGxfc2tpcF9lcmFzZVwiIGlzIGRlcHJlY2F0ZWQuIFVzZSBcIm5ld19pbnN0YWxsX3Byb21wdF9lcmFzZVwiIGluc3RlYWQuJyk7XG4gICAgICAgIGlmIChtYW5pZmVzdC5uZXdfaW5zdGFsbF9za2lwX2VyYXNlKSB7XG4gICAgICAgICAgICBtYW5pZmVzdC5uZXdfaW5zdGFsbF9wcm9tcHRfZXJhc2UgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYW5pZmVzdDtcbn07XG4iLCJpbXBvcnQgeyBzbGVlcCB9IGZyb20gXCIuL3NsZWVwXCI7XG5leHBvcnQgY29uc3QgaGFyZFJlc2V0ID0gYXN5bmMgKHRyYW5zcG9ydCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKFwiVHJpZ2dlcmluZyByZXNldFwiKTtcbiAgICBhd2FpdCB0cmFuc3BvcnQuZGV2aWNlLnNldFNpZ25hbHMoe1xuICAgICAgICBkYXRhVGVybWluYWxSZWFkeTogZmFsc2UsXG4gICAgICAgIHJlcXVlc3RUb1NlbmQ6IHRydWUsXG4gICAgfSk7XG4gICAgYXdhaXQgc2xlZXAoMjUwKTtcbiAgICBhd2FpdCB0cmFuc3BvcnQuZGV2aWNlLnNldFNpZ25hbHMoe1xuICAgICAgICBkYXRhVGVybWluYWxSZWFkeTogZmFsc2UsXG4gICAgICAgIHJlcXVlc3RUb1NlbmQ6IGZhbHNlLFxuICAgIH0pO1xuICAgIGF3YWl0IHNsZWVwKDI1MCk7XG4gICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMTAwMCkpO1xufTtcbiIsImV4cG9ydCBjb25zdCBzbGVlcCA9ICh0aW1lKSA9PiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCB0aW1lKSk7XG4iLCJleHBvcnQgY2xhc3MgVGltZXN0YW1wVHJhbnNmb3JtZXIge1xuICAgIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgY29uc3QgaCA9IGRhdGUuZ2V0SG91cnMoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsIFwiMFwiKTtcbiAgICAgICAgY29uc3QgbSA9IGRhdGUuZ2V0TWludXRlcygpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgXCIwXCIpO1xuICAgICAgICBjb25zdCBzID0gZGF0ZS5nZXRTZWNvbmRzKCkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCBcIjBcIik7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShgWyR7aH06JHttfToke3N9XSR7Y2h1bmt9YCk7XG4gICAgfVxufVxuIiwiZXhwb3J0IGNvbnN0IHZlcnNpb24gPSBcIjEwLjEuMVwiO1xuIiwiaW1wb3J0IHsgRVNQRXJyb3IgfSBmcm9tIFwiLi90eXBlcy9lcnJvci5qc1wiO1xuaW1wb3J0IHsgZGVmbGF0ZSwgSW5mbGF0ZSB9IGZyb20gXCJwYWtvXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnQgfSBmcm9tIFwiLi93ZWJzZXJpYWwuanNcIjtcbmltcG9ydCB7IENsYXNzaWNSZXNldCwgQ3VzdG9tUmVzZXQsIEhhcmRSZXNldCwgVXNiSnRhZ1NlcmlhbFJlc2V0IH0gZnJvbSBcIi4vcmVzZXQuanNcIjtcbmltcG9ydCB7IGdldFN0dWJKc29uQnlDaGlwTmFtZSB9IGZyb20gXCIuL3N0dWJGbGFzaGVyLmpzXCI7XG5pbXBvcnQgeyBwYWRUbyB9IGZyb20gXCIuL3V0aWwuanNcIjtcbi8qKlxuICogUmV0dXJuIHRoZSBjaGlwIFJPTSBiYXNlZCBvbiB0aGUgZ2l2ZW4gbWFnaWMgbnVtYmVyXG4gKiBAcGFyYW0ge251bWJlcn0gbWFnaWMgLSBtYWdpYyBoZXggbnVtYmVyIHRvIHNlbGVjdCBST00uXG4gKiBAcmV0dXJucyB7Uk9NfSBUaGUgY2hpcCBST00gY2xhc3MgcmVsYXRlZCB0byBnaXZlbiBtYWdpYyBoZXggbnVtYmVyLlxuICovXG5hc3luYyBmdW5jdGlvbiBtYWdpYzJDaGlwKG1hZ2ljKSB7XG4gICAgc3dpdGNoIChtYWdpYykge1xuICAgICAgICBjYXNlIDB4MDBmMDFkODM6IHtcbiAgICAgICAgICAgIGNvbnN0IHsgRVNQMzJST00gfSA9IGF3YWl0IGltcG9ydChcIi4vdGFyZ2V0cy9lc3AzMi5qc1wiKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRVNQMzJST00oKTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlIDB4YzIxZTA2ZjpcbiAgICAgICAgY2FzZSAweDZmNTEzMDZmOlxuICAgICAgICBjYXNlIDB4N2M0MWEwNmY6IHtcbiAgICAgICAgICAgIGNvbnN0IHsgRVNQMzJDMlJPTSB9ID0gYXdhaXQgaW1wb3J0KFwiLi90YXJnZXRzL2VzcDMyYzIuanNcIik7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVTUDMyQzJST00oKTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlIDB4NjkyMTUwNmY6XG4gICAgICAgIGNhc2UgMHgxYjMxNTA2ZjpcbiAgICAgICAgY2FzZSAweDQ4ODE2MDZmOlxuICAgICAgICBjYXNlIDB4NDM2MTYwNmY6IHtcbiAgICAgICAgICAgIGNvbnN0IHsgRVNQMzJDM1JPTSB9ID0gYXdhaXQgaW1wb3J0KFwiLi90YXJnZXRzL2VzcDMyYzMuanNcIik7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVTUDMyQzNST00oKTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlIDB4MmNlMDgwNmY6IHtcbiAgICAgICAgICAgIGNvbnN0IHsgRVNQMzJDNlJPTSB9ID0gYXdhaXQgaW1wb3J0KFwiLi90YXJnZXRzL2VzcDMyYzYuanNcIik7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVTUDMyQzZST00oKTtcbiAgICAgICAgfVxuICAgICAgICBjYXNlIDB4MjQyMTYwNmY6XG4gICAgICAgIGNhc2UgMHgzM2YwMjA2ZjpcbiAgICAgICAgY2FzZSAweDRmODE2MDZmOiB7XG4gICAgICAgICAgICBjb25zdCB7IEVTUDMyQzYxUk9NIH0gPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvZXNwMzJjNjEuanNcIik7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVTUDMyQzYxUk9NKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAweDExMDE0MDZmOlxuICAgICAgICBjYXNlIDB4NjNlMTQwNmY6XG4gICAgICAgIGNhc2UgMHg1ZmQxNDA2Zjoge1xuICAgICAgICAgICAgY29uc3QgeyBFU1AzMkM1Uk9NIH0gPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvZXNwMzJjNS5qc1wiKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRVNQMzJDNVJPTSgpO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMHhkN2I3M2U4MDoge1xuICAgICAgICAgICAgY29uc3QgeyBFU1AzMkgyUk9NIH0gPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvZXNwMzJoMi5qc1wiKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRVNQMzJIMlJPTSgpO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMHgwOToge1xuICAgICAgICAgICAgY29uc3QgeyBFU1AzMlMzUk9NIH0gPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvZXNwMzJzMy5qc1wiKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRVNQMzJTM1JPTSgpO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMHgwMDAwMDdjNjoge1xuICAgICAgICAgICAgY29uc3QgeyBFU1AzMlMyUk9NIH0gPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvZXNwMzJzMi5qc1wiKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRVNQMzJTMlJPTSgpO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMHhmZmYwYzEwMToge1xuICAgICAgICAgICAgY29uc3QgeyBFU1A4MjY2Uk9NIH0gPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvZXNwODI2Ni5qc1wiKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRVNQODI2NlJPTSgpO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMHgwOlxuICAgICAgICBjYXNlIDB4MGFkZGJhZDA6XG4gICAgICAgIGNhc2UgMHg3MDM5YWQ5OiB7XG4gICAgICAgICAgICBjb25zdCB7IEVTUDMyUDRST00gfSA9IGF3YWl0IGltcG9ydChcIi4vdGFyZ2V0cy9lc3AzMnA0LmpzXCIpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBFU1AzMlA0Uk9NKCk7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBFU1BMb2FkZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBFU1BMb2FkZXIgdG8gcGVyZm9ybSBzZXJpYWwgY29tbXVuaWNhdGlvblxuICAgICAqIHN1Y2ggYXMgcmVhZC93cml0ZSBmbGFzaCBtZW1vcnkgYW5kIHJlZ2lzdGVycyB1c2luZyBhIExvYWRlck9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7TG9hZGVyT3B0aW9uc30gb3B0aW9ucyAtIExvYWRlck9wdGlvbnMgb2JqZWN0IGFyZ3VtZW50IGZvciBFU1BMb2FkZXIuXG4gICAgICogYGBgXG4gICAgICogY29uc3QgbXlMb2FkZXIgPSBuZXcgRVNQTG9hZGVyKHsgdHJhbnNwb3J0OiBUcmFuc3BvcnQsIGJhdWRyYXRlOiBudW1iZXIsIHRlcm1pbmFsPzogSUVzcExvYWRlclRlcm1pbmFsIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgdmFyIF9hLCBfYiwgX2MsIF9kLCBfZSwgX2YsIF9nLCBfaDtcbiAgICAgICAgdGhpcy5FU1BfUkFNX0JMT0NLID0gMHgxODAwO1xuICAgICAgICB0aGlzLkVTUF9GTEFTSF9CRUdJTiA9IDB4MDI7XG4gICAgICAgIHRoaXMuRVNQX0ZMQVNIX0RBVEEgPSAweDAzO1xuICAgICAgICB0aGlzLkVTUF9GTEFTSF9FTkQgPSAweDA0O1xuICAgICAgICB0aGlzLkVTUF9NRU1fQkVHSU4gPSAweDA1O1xuICAgICAgICB0aGlzLkVTUF9NRU1fRU5EID0gMHgwNjtcbiAgICAgICAgdGhpcy5FU1BfTUVNX0RBVEEgPSAweDA3O1xuICAgICAgICB0aGlzLkVTUF9XUklURV9SRUcgPSAweDA5O1xuICAgICAgICB0aGlzLkVTUF9SRUFEX1JFRyA9IDB4MGE7XG4gICAgICAgIHRoaXMuRVNQX1NQSV9BVFRBQ0ggPSAweDBkO1xuICAgICAgICB0aGlzLkVTUF9DSEFOR0VfQkFVRFJBVEUgPSAweDBmO1xuICAgICAgICB0aGlzLkVTUF9GTEFTSF9ERUZMX0JFR0lOID0gMHgxMDtcbiAgICAgICAgdGhpcy5FU1BfRkxBU0hfREVGTF9EQVRBID0gMHgxMTtcbiAgICAgICAgdGhpcy5FU1BfRkxBU0hfREVGTF9FTkQgPSAweDEyO1xuICAgICAgICB0aGlzLkVTUF9TUElfRkxBU0hfTUQ1ID0gMHgxMztcbiAgICAgICAgLy8gT25seSBTdHViIHN1cHBvcnRlZCBjb21tYW5kc1xuICAgICAgICB0aGlzLkVTUF9FUkFTRV9GTEFTSCA9IDB4ZDA7XG4gICAgICAgIHRoaXMuRVNQX0VSQVNFX1JFR0lPTiA9IDB4ZDE7XG4gICAgICAgIHRoaXMuRVNQX1JFQURfRkxBU0ggPSAweGQyO1xuICAgICAgICB0aGlzLkVTUF9SVU5fVVNFUl9DT0RFID0gMHhkMztcbiAgICAgICAgdGhpcy5FU1BfSU1BR0VfTUFHSUMgPSAweGU5O1xuICAgICAgICB0aGlzLkVTUF9DSEVDS1NVTV9NQUdJQyA9IDB4ZWY7XG4gICAgICAgIC8vIFJlc3BvbnNlIGNvZGUocykgc2VudCBieSBST01cbiAgICAgICAgdGhpcy5ST01fSU5WQUxJRF9SRUNWX01TRyA9IDB4MDU7IC8vIHJlc3BvbnNlIGlmIGFuIGludmFsaWQgbWVzc2FnZSBpcyByZWNlaXZlZFxuICAgICAgICB0aGlzLkRFRkFVTFRfVElNRU9VVCA9IDMwMDA7XG4gICAgICAgIHRoaXMuRVJBU0VfUkVHSU9OX1RJTUVPVVRfUEVSX01CID0gMzAwMDA7XG4gICAgICAgIHRoaXMuRVJBU0VfV1JJVEVfVElNRU9VVF9QRVJfTUIgPSA0MDAwMDtcbiAgICAgICAgdGhpcy5NRDVfVElNRU9VVF9QRVJfTUIgPSA4MDAwO1xuICAgICAgICB0aGlzLkNISVBfRVJBU0VfVElNRU9VVCA9IDEyMDAwMDtcbiAgICAgICAgdGhpcy5GTEFTSF9SRUFEX1RJTUVPVVQgPSAxMDAwMDA7XG4gICAgICAgIHRoaXMuTUFYX1RJTUVPVVQgPSB0aGlzLkNISVBfRVJBU0VfVElNRU9VVCAqIDI7XG4gICAgICAgIHRoaXMuQ0hJUF9ERVRFQ1RfTUFHSUNfUkVHX0FERFIgPSAweDQwMDAxMDAwO1xuICAgICAgICB0aGlzLkRFVEVDVEVEX0ZMQVNIX1NJWkVTID0ge1xuICAgICAgICAgICAgMHgxMjogXCIyNTZLQlwiLFxuICAgICAgICAgICAgMHgxMzogXCI1MTJLQlwiLFxuICAgICAgICAgICAgMHgxNDogXCIxTUJcIixcbiAgICAgICAgICAgIDB4MTU6IFwiMk1CXCIsXG4gICAgICAgICAgICAweDE2OiBcIjRNQlwiLFxuICAgICAgICAgICAgMHgxNzogXCI4TUJcIixcbiAgICAgICAgICAgIDB4MTg6IFwiMTZNQlwiLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLkRFVEVDVEVEX0ZMQVNIX1NJWkVTX05VTSA9IHtcbiAgICAgICAgICAgIDB4MTI6IDI1NixcbiAgICAgICAgICAgIDB4MTM6IDUxMixcbiAgICAgICAgICAgIDB4MTQ6IDEwMjQsXG4gICAgICAgICAgICAweDE1OiAyMDQ4LFxuICAgICAgICAgICAgMHgxNjogNDA5NixcbiAgICAgICAgICAgIDB4MTc6IDgxOTIsXG4gICAgICAgICAgICAweDE4OiAxNjM4NCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5VU0JfSlRBR19TRVJJQUxfUElEID0gMHgxMDAxO1xuICAgICAgICB0aGlzLnJvbUJhdWRyYXRlID0gMTE1MjAwO1xuICAgICAgICB0aGlzLmRlYnVnTG9nZ2luZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN5bmNTdHViRGV0ZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldCBmbGFzaCBzaXplIGJ5dGVzIGZyb20gZmxhc2ggc2l6ZSBzdHJpbmcuXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmbGFzaFNpemUgRmxhc2ggU2l6ZSBzdHJpbmdcbiAgICAgICAgICogQHJldHVybnMge251bWJlcn0gRmxhc2ggc2l6ZSBieXRlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5mbGFzaFNpemVCeXRlcyA9IGZ1bmN0aW9uIChmbGFzaFNpemUpIHtcbiAgICAgICAgICAgIGxldCBmbGFzaFNpemVCID0gLTE7XG4gICAgICAgICAgICBpZiAoZmxhc2hTaXplLmluZGV4T2YoXCJLQlwiKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBmbGFzaFNpemVCID0gcGFyc2VJbnQoZmxhc2hTaXplLnNsaWNlKDAsIGZsYXNoU2l6ZS5pbmRleE9mKFwiS0JcIikpKSAqIDEwMjQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChmbGFzaFNpemUuaW5kZXhPZihcIk1CXCIpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIGZsYXNoU2l6ZUIgPSBwYXJzZUludChmbGFzaFNpemUuc2xpY2UoMCwgZmxhc2hTaXplLmluZGV4T2YoXCJNQlwiKSkpICogMTAyNCAqIDEwMjQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmxhc2hTaXplQjtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5JU19TVFVCID0gZmFsc2U7XG4gICAgICAgIHRoaXMuRkxBU0hfV1JJVEVfU0laRSA9IDB4NDAwMDtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQgPSBvcHRpb25zLnRyYW5zcG9ydDtcbiAgICAgICAgdGhpcy5iYXVkcmF0ZSA9IG9wdGlvbnMuYmF1ZHJhdGU7XG4gICAgICAgIHRoaXMucmVzZXRDb25zdHJ1Y3RvcnMgPSB7XG4gICAgICAgICAgICBjbGFzc2ljUmVzZXQ6ICh0cmFuc3BvcnQsIHJlc2V0RGVsYXkpID0+IG5ldyBDbGFzc2ljUmVzZXQodHJhbnNwb3J0LCByZXNldERlbGF5KSxcbiAgICAgICAgICAgIGN1c3RvbVJlc2V0OiAodHJhbnNwb3J0LCBzZXF1ZW5jZVN0cmluZykgPT4gbmV3IEN1c3RvbVJlc2V0KHRyYW5zcG9ydCwgc2VxdWVuY2VTdHJpbmcpLFxuICAgICAgICAgICAgaGFyZFJlc2V0OiAodHJhbnNwb3J0LCB1c2luZ1VzYk90ZykgPT4gbmV3IEhhcmRSZXNldCh0cmFuc3BvcnQsIHVzaW5nVXNiT3RnKSxcbiAgICAgICAgICAgIHVzYkpUQUdTZXJpYWxSZXNldDogKHRyYW5zcG9ydCkgPT4gbmV3IFVzYkp0YWdTZXJpYWxSZXNldCh0cmFuc3BvcnQpLFxuICAgICAgICB9O1xuICAgICAgICBpZiAob3B0aW9ucy5zZXJpYWxPcHRpb25zKSB7XG4gICAgICAgICAgICB0aGlzLnNlcmlhbE9wdGlvbnMgPSBvcHRpb25zLnNlcmlhbE9wdGlvbnM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMucm9tQmF1ZHJhdGUpIHtcbiAgICAgICAgICAgIHRoaXMucm9tQmF1ZHJhdGUgPSBvcHRpb25zLnJvbUJhdWRyYXRlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLnRlcm1pbmFsKSB7XG4gICAgICAgICAgICB0aGlzLnRlcm1pbmFsID0gb3B0aW9ucy50ZXJtaW5hbDtcbiAgICAgICAgICAgIHRoaXMudGVybWluYWwuY2xlYW4oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMuZGVidWdMb2dnaW5nICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB0aGlzLmRlYnVnTG9nZ2luZyA9IG9wdGlvbnMuZGVidWdMb2dnaW5nO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLnBvcnQpIHtcbiAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0ID0gbmV3IFRyYW5zcG9ydChvcHRpb25zLnBvcnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5lbmFibGVUcmFjaW5nICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydC50cmFjaW5nID0gb3B0aW9ucy5lbmFibGVUcmFjaW5nO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoX2EgPSBvcHRpb25zLnJlc2V0Q29uc3RydWN0b3JzKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuY2xhc3NpY1Jlc2V0KSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0Q29uc3RydWN0b3JzLmNsYXNzaWNSZXNldCA9IChfYiA9IG9wdGlvbnMucmVzZXRDb25zdHJ1Y3RvcnMpID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jbGFzc2ljUmVzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChfYyA9IG9wdGlvbnMucmVzZXRDb25zdHJ1Y3RvcnMpID09PSBudWxsIHx8IF9jID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYy5jdXN0b21SZXNldCkge1xuICAgICAgICAgICAgdGhpcy5yZXNldENvbnN0cnVjdG9ycy5jdXN0b21SZXNldCA9IChfZCA9IG9wdGlvbnMucmVzZXRDb25zdHJ1Y3RvcnMpID09PSBudWxsIHx8IF9kID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZC5jdXN0b21SZXNldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKF9lID0gb3B0aW9ucy5yZXNldENvbnN0cnVjdG9ycykgPT09IG51bGwgfHwgX2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9lLmhhcmRSZXNldCkge1xuICAgICAgICAgICAgdGhpcy5yZXNldENvbnN0cnVjdG9ycy5oYXJkUmVzZXQgPSAoX2YgPSBvcHRpb25zLnJlc2V0Q29uc3RydWN0b3JzKSA9PT0gbnVsbCB8fCBfZiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2YuaGFyZFJlc2V0O1xuICAgICAgICB9XG4gICAgICAgIGlmICgoX2cgPSBvcHRpb25zLnJlc2V0Q29uc3RydWN0b3JzKSA9PT0gbnVsbCB8fCBfZyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2cudXNiSlRBR1NlcmlhbFJlc2V0KSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0Q29uc3RydWN0b3JzLnVzYkpUQUdTZXJpYWxSZXNldCA9IChfaCA9IG9wdGlvbnMucmVzZXRDb25zdHJ1Y3RvcnMpID09PSBudWxsIHx8IF9oID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfaC51c2JKVEFHU2VyaWFsUmVzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbmZvKFwiZXNwdG9vbC5qc1wiKTtcbiAgICAgICAgdGhpcy5pbmZvKFwiU2VyaWFsIHBvcnQgXCIgKyB0aGlzLnRyYW5zcG9ydC5nZXRJbmZvKCkpO1xuICAgIH1cbiAgICBfc2xlZXAobXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdyaXRlIHRvIEVTUCBMb2FkZXIgY29uc3RydWN0b3IncyB0ZXJtaW5hbCB3aXRoIG9yIHdpdGhvdXQgbmV3IGxpbmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFN0cmluZyB0byB3cml0ZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhOZXdsaW5lIC0gQWRkIG5ldyBsaW5lIGF0IHRoZSBlbmQgP1xuICAgICAqL1xuICAgIHdyaXRlKHN0ciwgd2l0aE5ld2xpbmUgPSB0cnVlKSB7XG4gICAgICAgIGlmICh0aGlzLnRlcm1pbmFsKSB7XG4gICAgICAgICAgICBpZiAod2l0aE5ld2xpbmUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRlcm1pbmFsLndyaXRlTGluZShzdHIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy50ZXJtaW5hbC53cml0ZShzdHIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGUgZXJyb3IgbWVzc2FnZSB0byBFU1AgTG9hZGVyIGNvbnN0cnVjdG9yJ3MgdGVybWluYWwgd2l0aCBvciB3aXRob3V0IG5ldyBsaW5lLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gd3JpdGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSB3aXRoTmV3bGluZSAtIEFkZCBuZXcgbGluZSBhdCB0aGUgZW5kID9cbiAgICAgKi9cbiAgICBlcnJvcihzdHIsIHdpdGhOZXdsaW5lID0gdHJ1ZSkge1xuICAgICAgICB0aGlzLndyaXRlKGBFcnJvcjogJHtzdHJ9YCwgd2l0aE5ld2xpbmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZSBpbmZvcm1hdGlvbiBtZXNzYWdlIHRvIEVTUCBMb2FkZXIgY29uc3RydWN0b3IncyB0ZXJtaW5hbCB3aXRoIG9yIHdpdGhvdXQgbmV3IGxpbmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFN0cmluZyB0byB3cml0ZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhOZXdsaW5lIC0gQWRkIG5ldyBsaW5lIGF0IHRoZSBlbmQgP1xuICAgICAqL1xuICAgIGluZm8oc3RyLCB3aXRoTmV3bGluZSA9IHRydWUpIHtcbiAgICAgICAgdGhpcy53cml0ZShzdHIsIHdpdGhOZXdsaW5lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGUgZGVidWcgbWVzc2FnZSB0byBFU1AgTG9hZGVyIGNvbnN0cnVjdG9yJ3MgdGVybWluYWwgd2l0aCBvciB3aXRob3V0IG5ldyBsaW5lLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gd3JpdGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSB3aXRoTmV3bGluZSAtIEFkZCBuZXcgbGluZSBhdCB0aGUgZW5kID9cbiAgICAgKi9cbiAgICBkZWJ1ZyhzdHIsIHdpdGhOZXdsaW5lID0gdHJ1ZSkge1xuICAgICAgICBpZiAodGhpcy5kZWJ1Z0xvZ2dpbmcpIHtcbiAgICAgICAgICAgIHRoaXMud3JpdGUoYERlYnVnOiAke3N0cn1gLCB3aXRoTmV3bGluZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBzaG9ydCBpbnRlZ2VyIHRvIGJ5dGUgYXJyYXlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaSAtIE51bWJlciB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBCeXRlIGFycmF5LlxuICAgICAqL1xuICAgIF9zaG9ydFRvQnl0ZWFycmF5KGkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KFtpICYgMHhmZiwgKGkgPj4gOCkgJiAweGZmXSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgYW4gaW50ZWdlciB0byBieXRlIGFycmF5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGkgLSBOdW1iZXIgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7Uk9NfSBUaGUgY2hpcCBST00gY2xhc3MgcmVsYXRlZCB0byBnaXZlbiBtYWdpYyBoZXggbnVtYmVyLlxuICAgICAqL1xuICAgIF9pbnRUb0J5dGVBcnJheShpKSB7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShbaSAmIDB4ZmYsIChpID4+IDgpICYgMHhmZiwgKGkgPj4gMTYpICYgMHhmZiwgKGkgPj4gMjQpICYgMHhmZl0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGEgYnl0ZSBhcnJheSB0byBzaG9ydCBpbnRlZ2VyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpIC0gTnVtYmVyIHRvIGNvbnZlcnQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGogLSBOdW1iZXIgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm4gYSBzaG9ydCBpbnRlZ2VyIG51bWJlci5cbiAgICAgKi9cbiAgICBfYnl0ZUFycmF5VG9TaG9ydChpLCBqKSB7XG4gICAgICAgIHJldHVybiBpIHwgKGogPj4gOCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgYSBieXRlIGFycmF5IHRvIGludGVnZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGkgLSBOdW1iZXIgdG8gY29udmVydC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaiAtIE51bWJlciB0byBjb252ZXJ0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBrIC0gTnVtYmVyIHRvIGNvbnZlcnQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGwgLSBOdW1iZXIgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm4gYSBpbnRlZ2VyIG51bWJlci5cbiAgICAgKi9cbiAgICBfYnl0ZUFycmF5VG9JbnQoaSwgaiwgaywgbCkge1xuICAgICAgICByZXR1cm4gaSB8IChqIDw8IDgpIHwgKGsgPDwgMTYpIHwgKGwgPDwgMjQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcHBlbmQgYSBidWZmZXIgYXJyYXkgYWZ0ZXIgYW5vdGhlciBidWZmZXIgYXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXIxIC0gRmlyc3QgYXJyYXkgYnVmZmVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGJ1ZmZlcjIgLSBtYWdpYyBoZXggbnVtYmVyIHRvIHNlbGVjdCBST00uXG4gICAgICogQHJldHVybnMge0FycmF5QnVmZmVyTGlrZX0gUmV0dXJuIGFuIGFycmF5IGJ1ZmZlci5cbiAgICAgKi9cbiAgICBfYXBwZW5kQnVmZmVyKGJ1ZmZlcjEsIGJ1ZmZlcjIpIHtcbiAgICAgICAgY29uc3QgdG1wID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyMS5ieXRlTGVuZ3RoICsgYnVmZmVyMi5ieXRlTGVuZ3RoKTtcbiAgICAgICAgdG1wLnNldChuZXcgVWludDhBcnJheShidWZmZXIxKSwgMCk7XG4gICAgICAgIHRtcC5zZXQobmV3IFVpbnQ4QXJyYXkoYnVmZmVyMiksIGJ1ZmZlcjEuYnl0ZUxlbmd0aCk7XG4gICAgICAgIHJldHVybiB0bXAuYnVmZmVyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcHBlbmQgYSBidWZmZXIgYXJyYXkgYWZ0ZXIgYW5vdGhlciBidWZmZXIgYXJyYXlcbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGFycjEgLSBGaXJzdCBhcnJheSBidWZmZXIuXG4gICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBhcnIyIC0gbWFnaWMgaGV4IG51bWJlciB0byBzZWxlY3QgUk9NLlxuICAgICAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBSZXR1cm4gYSA4IGJpdCB1bnNpZ25lZCBhcnJheS5cbiAgICAgKi9cbiAgICBfYXBwZW5kQXJyYXkoYXJyMSwgYXJyMikge1xuICAgICAgICBjb25zdCBjID0gbmV3IFVpbnQ4QXJyYXkoYXJyMS5sZW5ndGggKyBhcnIyLmxlbmd0aCk7XG4gICAgICAgIGMuc2V0KGFycjEsIDApO1xuICAgICAgICBjLnNldChhcnIyLCBhcnIxLmxlbmd0aCk7XG4gICAgICAgIHJldHVybiBjO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGEgdW5zaWduZWQgOCBiaXQgaW50ZWdlciBhcnJheSB0byBieXRlIHN0cmluZy5cbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHU4QXJyYXkgLSBtYWdpYyBoZXggbnVtYmVyIHRvIHNlbGVjdCBST00uXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJuIHRoZSBlcXVpdmFsZW50IHN0cmluZy5cbiAgICAgKi9cbiAgICB1aThUb0JzdHIodThBcnJheSkge1xuICAgICAgICBsZXQgYlN0ciA9IFwiXCI7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdThBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYlN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHU4QXJyYXlbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiU3RyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGEgYnl0ZSBzdHJpbmcgdG8gdW5zaWduZWQgOCBiaXQgaW50ZWdlciBhcnJheS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYlN0ciAtIGJpbmFyeSBzdHJpbmcgaW5wdXRcbiAgICAgKiBAcmV0dXJucyB7VWludDhBcnJheX0gUmV0dXJuIGEgOCBiaXQgdW5zaWduZWQgaW50ZWdlciBhcnJheS5cbiAgICAgKi9cbiAgICBic3RyVG9VaTgoYlN0cikge1xuICAgICAgICBjb25zdCB1OEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYlN0ci5sZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJTdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHU4QXJyYXlbaV0gPSBiU3RyLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHU4QXJyYXk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZsdXNoIHRoZSBzZXJpYWwgaW5wdXQgYnkgcmF3IHJlYWQgd2l0aCAyMDAgbXMgdGltZW91dC5cbiAgICAgKi9cbiAgICBhc3luYyBmbHVzaElucHV0KCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuZmx1c2hJbnB1dCgpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aGlzLmVycm9yKGUubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVXNlIHRoZSBkZXZpY2Ugc2VyaWFsIHBvcnQgcmVhZCBmdW5jdGlvbiB3aXRoIGdpdmVuIHRpbWVvdXQgdG8gY3JlYXRlIGEgdmFsaWQgcGFja2V0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvcCBPcGVyYXRpb24gbnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgdGltZW91dCBudW1iZXIgaW4gbWlsbGlzZWNvbmRzXG4gICAgICogQHJldHVybnMge1tudW1iZXIsIFVpbnQ4QXJyYXldfSB2YWxpZCByZXNwb25zZSBwYWNrZXQuXG4gICAgICovXG4gICAgYXN5bmMgcmVhZFBhY2tldChvcCA9IG51bGwsIHRpbWVvdXQgPSB0aGlzLkRFRkFVTFRfVElNRU9VVCkge1xuICAgICAgICAvLyBDaGVjayB1cC10byBuZXh0IDEwMCBwYWNrZXRzIGZvciB2YWxpZCByZXNwb25zZSBwYWNrZXRcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxMDA7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgeyB2YWx1ZTogcCB9ID0gYXdhaXQgdGhpcy50cmFuc3BvcnQucmVhZCh0aW1lb3V0KS5uZXh0KCk7XG4gICAgICAgICAgICBpZiAoIXAgfHwgcC5sZW5ndGggPCA4KSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByZXNwID0gcFswXTtcbiAgICAgICAgICAgIGlmIChyZXNwICE9PSAxKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBvcFJldCA9IHBbMV07XG4gICAgICAgICAgICBjb25zdCB2YWwgPSB0aGlzLl9ieXRlQXJyYXlUb0ludChwWzRdLCBwWzVdLCBwWzZdLCBwWzddKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBwLnNsaWNlKDgpO1xuICAgICAgICAgICAgaWYgKHJlc3AgPT0gMSkge1xuICAgICAgICAgICAgICAgIGlmIChvcCA9PSBudWxsIHx8IG9wUmV0ID09IG9wKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbdmFsLCBkYXRhXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZGF0YVswXSAhPSAwICYmIGRhdGFbMV0gPT0gdGhpcy5ST01fSU5WQUxJRF9SRUNWX01TRykge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZsdXNoSW5wdXQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVTUEVycm9yKFwidW5zdXBwb3J0ZWQgY29tbWFuZCBlcnJvclwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVTUEVycm9yKFwiaW52YWxpZCByZXNwb25zZVwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGUgYSBzZXJpYWwgY29tbWFuZCB0byB0aGUgY2hpcFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvcCAtIE9wZXJhdGlvbiBudW1iZXJcbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGRhdGEgLSBVbnNpZ25lZCA4IGJpdCBhcnJheVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjaGsgLSBjaGFubmVsIG51bWJlclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gd2FpdFJlc3BvbnNlIC0gd2FpdCBmb3IgcmVzcG9uc2UgP1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0IC0gdGltZW91dCBudW1iZXIgaW4gbWlsbGlzZWNvbmRzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8W251bWJlciwgVWludDhBcnJheV0+fSBSZXR1cm4gYSBudW1iZXIgYW5kIGEgOCBiaXQgdW5zaWduZWQgaW50ZWdlciBhcnJheS5cbiAgICAgKi9cbiAgICBhc3luYyBjb21tYW5kKG9wID0gbnVsbCwgZGF0YSA9IG5ldyBVaW50OEFycmF5KDApLCBjaGsgPSAwLCB3YWl0UmVzcG9uc2UgPSB0cnVlLCB0aW1lb3V0ID0gdGhpcy5ERUZBVUxUX1RJTUVPVVQpIHtcbiAgICAgICAgaWYgKG9wICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRyYW5zcG9ydC50cmFjaW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQudHJhY2UoYGNvbW1hbmQgb3A6MHgke29wLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIil9IGRhdGEgbGVuPSR7ZGF0YS5sZW5ndGh9IHdhaXRfcmVzcG9uc2U9JHt3YWl0UmVzcG9uc2UgPyAxIDogMH0gdGltZW91dD0keyh0aW1lb3V0IC8gMTAwMCkudG9GaXhlZCgzKX0gZGF0YT0ke3RoaXMudHJhbnNwb3J0LmhleENvbnZlcnQoZGF0YSl9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBwa3QgPSBuZXcgVWludDhBcnJheSg4ICsgZGF0YS5sZW5ndGgpO1xuICAgICAgICAgICAgcGt0WzBdID0gMHgwMDtcbiAgICAgICAgICAgIHBrdFsxXSA9IG9wO1xuICAgICAgICAgICAgcGt0WzJdID0gdGhpcy5fc2hvcnRUb0J5dGVhcnJheShkYXRhLmxlbmd0aClbMF07XG4gICAgICAgICAgICBwa3RbM10gPSB0aGlzLl9zaG9ydFRvQnl0ZWFycmF5KGRhdGEubGVuZ3RoKVsxXTtcbiAgICAgICAgICAgIHBrdFs0XSA9IHRoaXMuX2ludFRvQnl0ZUFycmF5KGNoaylbMF07XG4gICAgICAgICAgICBwa3RbNV0gPSB0aGlzLl9pbnRUb0J5dGVBcnJheShjaGspWzFdO1xuICAgICAgICAgICAgcGt0WzZdID0gdGhpcy5faW50VG9CeXRlQXJyYXkoY2hrKVsyXTtcbiAgICAgICAgICAgIHBrdFs3XSA9IHRoaXMuX2ludFRvQnl0ZUFycmF5KGNoaylbM107XG4gICAgICAgICAgICBsZXQgaTtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcGt0WzggKyBpXSA9IGRhdGFbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC53cml0ZShwa3QpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghd2FpdFJlc3BvbnNlKSB7XG4gICAgICAgICAgICByZXR1cm4gWzAsIG5ldyBVaW50OEFycmF5KDApXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yZWFkUGFja2V0KG9wLCB0aW1lb3V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCBhIHJlZ2lzdGVyIGZyb20gY2hpcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYWRkciAtIFJlZ2lzdGVyIGFkZHJlc3MgbnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgLSBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoRGVmYXVsdDogMzAwMG1zKVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gQ29tbWFuZCBudW1iZXIgdmFsdWVcbiAgICAgKi9cbiAgICBhc3luYyByZWFkUmVnKGFkZHIsIHRpbWVvdXQgPSB0aGlzLkRFRkFVTFRfVElNRU9VVCkge1xuICAgICAgICBjb25zdCBwa3QgPSB0aGlzLl9pbnRUb0J5dGVBcnJheShhZGRyKTtcbiAgICAgICAgY29uc3QgdmFsID0gYXdhaXQgdGhpcy5jb21tYW5kKHRoaXMuRVNQX1JFQURfUkVHLCBwa3QsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIHZhbFswXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGUgYSBudW1iZXIgdmFsdWUgdG8gcmVnaXN0ZXIgYWRkcmVzcyBpbiBjaGlwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhZGRyIC0gUmVnaXN0ZXIgYWRkcmVzcyBudW1iZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgLSBOdW1iZXIgdmFsdWUgdG8gd3JpdGUgaW4gcmVnaXN0ZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWFzayAtIEhleCBudW1iZXIgZm9yIG1hc2tcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGVsYXlVcyBEZWxheSBudW1iZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGVsYXlBZnRlclVzIERlbGF5IGFmdGVyIHByZXZpb3VzIGRlbGF5XG4gICAgICovXG4gICAgYXN5bmMgd3JpdGVSZWcoYWRkciwgdmFsdWUsIG1hc2sgPSAweGZmZmZmZmZmLCBkZWxheVVzID0gMCwgZGVsYXlBZnRlclVzID0gMCkge1xuICAgICAgICBsZXQgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkodGhpcy5faW50VG9CeXRlQXJyYXkoYWRkciksIHRoaXMuX2ludFRvQnl0ZUFycmF5KHZhbHVlKSk7XG4gICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkobWFzaykpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KGRlbGF5VXMpKTtcbiAgICAgICAgaWYgKGRlbGF5QWZ0ZXJVcyA+IDApIHtcbiAgICAgICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkodGhpcy5jaGlwLlVBUlRfREFURV9SRUdfQUREUikpO1xuICAgICAgICAgICAgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkocGt0LCB0aGlzLl9pbnRUb0J5dGVBcnJheSgwKSk7XG4gICAgICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KDApKTtcbiAgICAgICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkoZGVsYXlBZnRlclVzKSk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0NvbW1hbmQoXCJ3cml0ZSB0YXJnZXQgbWVtb3J5XCIsIHRoaXMuRVNQX1dSSVRFX1JFRywgcGt0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyBjaGlwIGJ5IHNlbmRpbmcgc3luYyBjb21tYW5kLlxuICAgICAqIEByZXR1cm5zIHtbbnVtYmVyLCBVaW50OEFycmF5XX0gQ29tbWFuZCByZXN1bHRcbiAgICAgKi9cbiAgICBhc3luYyBzeW5jKCkge1xuICAgICAgICB0aGlzLmRlYnVnKFwiU3luY1wiKTtcbiAgICAgICAgY29uc3QgY21kID0gbmV3IFVpbnQ4QXJyYXkoMzYpO1xuICAgICAgICBsZXQgaTtcbiAgICAgICAgY21kWzBdID0gMHgwNztcbiAgICAgICAgY21kWzFdID0gMHgwNztcbiAgICAgICAgY21kWzJdID0gMHgxMjtcbiAgICAgICAgY21kWzNdID0gMHgyMDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDMyOyBpKyspIHtcbiAgICAgICAgICAgIGNtZFs0ICsgaV0gPSAweDU1O1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcmVzcCA9IGF3YWl0IHRoaXMuY29tbWFuZCgweDA4LCBjbWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAxMDApO1xuICAgICAgICAgICAgLy8gUk9NIGJvb3Rsb2FkZXJzIHNlbmQgc29tZSBub24temVybyBcInZhbFwiIHJlc3BvbnNlLiBUaGUgZmxhc2hlciBzdHViIHNlbmRzIDAuXG4gICAgICAgICAgICAvLyBJZiB3ZSByZWNlaXZlIDAgdGhlbiBpdCBwcm9iYWJseSBpbmRpY2F0ZXMgdGhhdCB0aGUgY2hpcCB3YXNuJ3Qgb3IgY291bGRuJ3QgYmVcbiAgICAgICAgICAgIC8vIHJlc2V0IHByb3Blcmx5IGFuZCBlc3B0b29sIGlzIHRhbGtpbmcgdG8gdGhlIGZsYXNoZXIgc3R1Yi5cbiAgICAgICAgICAgIHRoaXMuc3luY1N0dWJEZXRlY3RlZCA9IHJlc3BbMF0gPT09IDA7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgICAgIHJlc3AgPSBhd2FpdCB0aGlzLmNvbW1hbmQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN5bmNTdHViRGV0ZWN0ZWQgPSB0aGlzLnN5bmNTdHViRGV0ZWN0ZWQgJiYgcmVzcFswXSA9PT0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXNwO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aGlzLmRlYnVnKFwiU3luYyBlcnIgXCIgKyBlKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdCB0byBjb25uZWN0IHRvIHRoZSBjaGlwIGJ5IHNlbmRpbmcgYSByZXNldCBzZXF1ZW5jZSBhbmQgbGF0ZXIgYSBzeW5jIGNvbW1hbmQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1vZGUgLSBSZXNldCBtb2RlIHRvIHVzZVxuICAgICAqIEBwYXJhbSB7UmVzZXRTdHJhdGVneX0gcmVzZXRTdHJhdGVneSAtIFJlc2V0IHN0cmF0ZWd5IGNsYXNzIHRvIHVzZSBmb3IgY29ubmVjdFxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gUmV0dXJucyAnc3VjY2Vzcycgb3IgJ2Vycm9yJyBtZXNzYWdlLlxuICAgICAqL1xuICAgIGFzeW5jIF9jb25uZWN0QXR0ZW1wdChtb2RlID0gXCJkZWZhdWx0X3Jlc2V0XCIsIHJlc2V0U3RyYXRlZ3kpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZyhcIl9jb25uZWN0X2F0dGVtcHQgXCIgKyBtb2RlKTtcbiAgICAgICAgaWYgKHJlc2V0U3RyYXRlZ3kpIHtcbiAgICAgICAgICAgIGF3YWl0IHJlc2V0U3RyYXRlZ3kucmVzZXQoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3YWl0aW5nQnl0ZXMgPSB0aGlzLnRyYW5zcG9ydC5pbldhaXRpbmcoKTtcbiAgICAgICAgY29uc3QgcmVhZEJ5dGVzID0gYXdhaXQgdGhpcy50cmFuc3BvcnQubmV3UmVhZCh3YWl0aW5nQnl0ZXMgPiAwID8gd2FpdGluZ0J5dGVzIDogMSwgdGhpcy5ERUZBVUxUX1RJTUVPVVQpO1xuICAgICAgICBjb25zdCBiaW5hcnlTdHJpbmcgPSBBcnJheS5mcm9tKHJlYWRCeXRlcywgKGJ5dGUpID0+IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZSkpLmpvaW4oXCJcIik7XG4gICAgICAgIGNvbnN0IHJlZ2V4ID0gL2Jvb3Q6KDB4WzAtOWEtZkEtRl0rKSguKndhaXRpbmcgZm9yIGRvd25sb2FkKT8vO1xuICAgICAgICBjb25zdCBtYXRjaCA9IGJpbmFyeVN0cmluZy5tYXRjaChyZWdleCk7XG4gICAgICAgIGxldCBib290TG9nRGV0ZWN0ZWQgPSBmYWxzZSwgYm9vdE1vZGUgPSBcIlwiLCBkb3dubG9hZE1vZGUgPSBmYWxzZTtcbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICBib290TG9nRGV0ZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgYm9vdE1vZGUgPSBtYXRjaFsxXTtcbiAgICAgICAgICAgIGRvd25sb2FkTW9kZSA9ICEhbWF0Y2hbMl07XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGxhc3RFcnJvciA9IFwiXCI7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVidWcoYFN5bmMgY29ubmVjdCBhdHRlbXB0ICR7aX1gKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNwID0gYXdhaXQgdGhpcy5zeW5jKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWJ1ZyhyZXNwWzBdLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgIHJldHVybiBcInN1Y2Nlc3NcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVidWcoYEVycm9yIGF0IHN5bmMgJHtlcnJvcn1gKTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBsYXN0RXJyb3IgPSBlcnJvci5tZXNzYWdlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgZXJyb3IgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgbGFzdEVycm9yID0gZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsYXN0RXJyb3IgPSBKU09OLnN0cmluZ2lmeShlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChib290TG9nRGV0ZWN0ZWQpIHtcbiAgICAgICAgICAgIGxhc3RFcnJvciA9IGBXcm9uZyBib290IG1vZGUgZGV0ZWN0ZWQgKCR7Ym9vdE1vZGV9KS5cbiAgICAgICAgVGhpcyBjaGlwIG5lZWRzIHRvIGJlIGluIGRvd25sb2FkIG1vZGUuYDtcbiAgICAgICAgICAgIGlmIChkb3dubG9hZE1vZGUpIHtcbiAgICAgICAgICAgICAgICBsYXN0RXJyb3IgPSBgRG93bmxvYWQgbW9kZSBzdWNjZXNzZnVsbHkgZGV0ZWN0ZWQsIGJ1dCBnZXR0aW5nIG5vIHN5bmMgcmVwbHk6XG4gICAgICAgICAgIFRoZSBzZXJpYWwgVFggcGF0aCBzZWVtcyB0byBiZSBkb3duLmA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxhc3RFcnJvcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyBhIHNlcXVlbmNlIG9mIHJlc2V0IHN0cmF0ZWdpZXMgYmFzZWQgb24gdGhlIE9TLFxuICAgICAqIHVzZWQgRVNQIGNoaXAsIGV4dGVybmFsIHNldHRpbmdzLCBhbmQgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgICAqIFJldHVybnMgYSB0dXBsZSBvZiBvbmUgb3IgbW9yZSByZXNldCBzdHJhdGVnaWVzIHRvIGJlIHRyaWVkIHNlcXVlbnRpYWxseS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbW9kZSAtIFJlc2V0IG1vZGUgdG8gdXNlXG4gICAgICogQHJldHVybnMge1Jlc2V0U3RyYXRlZ3lbXX0gLSBBcnJheSBvZiByZXNldCBzdHJhdGVnaWVzXG4gICAgICovXG4gICAgY29uc3RydWN0UmVzZXRTZXF1ZW5jZShtb2RlKSB7XG4gICAgICAgIGlmIChtb2RlICE9PSBcIm5vX3Jlc2V0XCIpIHtcbiAgICAgICAgICAgIGlmIChtb2RlID09PSBcInVzYl9yZXNldFwiIHx8IHRoaXMudHJhbnNwb3J0LmdldFBpZCgpID09PSB0aGlzLlVTQl9KVEFHX1NFUklBTF9QSUQpIHtcbiAgICAgICAgICAgICAgICAvLyBDdXN0b20gcmVzZXQgc2VxdWVuY2UsIHdoaWNoIGlzIHJlcXVpcmVkIHdoZW4gdGhlIGRldmljZVxuICAgICAgICAgICAgICAgIC8vIGlzIGNvbm5lY3RpbmcgdmlhIGl0cyBVU0ItSlRBRy1TZXJpYWwgcGVyaXBoZXJhbFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlc2V0Q29uc3RydWN0b3JzLnVzYkpUQUdTZXJpYWxSZXNldCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlYnVnKFwidXNpbmcgVVNCIEpUQUcgU2VyaWFsIFJlc2V0XCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW3RoaXMucmVzZXRDb25zdHJ1Y3RvcnMudXNiSlRBR1NlcmlhbFJlc2V0KHRoaXMudHJhbnNwb3J0KV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgREVGQVVMVF9SRVNFVF9ERUxBWSA9IDUwO1xuICAgICAgICAgICAgICAgIGNvbnN0IEVYVFJBX0RFTEFZID0gREVGQVVMVF9SRVNFVF9ERUxBWSArIDUwMDtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXNldENvbnN0cnVjdG9ycy5jbGFzc2ljUmVzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWJ1ZyhcInVzaW5nIENsYXNzaWMgU2VyaWFsIFJlc2V0XCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNldENvbnN0cnVjdG9ycy5jbGFzc2ljUmVzZXQodGhpcy50cmFuc3BvcnQsIERFRkFVTFRfUkVTRVRfREVMQVkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNldENvbnN0cnVjdG9ycy5jbGFzc2ljUmVzZXQodGhpcy50cmFuc3BvcnQsIEVYVFJBX0RFTEFZKSxcbiAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtIGEgY29ubmVjdGlvbiB0byBjaGlwLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtb2RlIC0gUmVzZXQgbW9kZSB0byB1c2UuIEV4YW1wbGU6ICdkZWZhdWx0X3Jlc2V0JyB8ICdub19yZXNldCdcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYXR0ZW1wdHMgLSBOdW1iZXIgb2YgY29ubmVjdGlvbiBhdHRlbXB0c1xuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZGV0ZWN0aW5nIC0gRGV0ZWN0IHRoZSBjb25uZWN0ZWQgY2hpcFxuICAgICAqL1xuICAgIGFzeW5jIGNvbm5lY3QobW9kZSA9IFwiZGVmYXVsdF9yZXNldFwiLCBhdHRlbXB0cyA9IDcsIGRldGVjdGluZyA9IHRydWUpIHtcbiAgICAgICAgbGV0IHJlc3A7XG4gICAgICAgIHRoaXMuaW5mbyhcIkNvbm5lY3RpbmcuLi5cIiwgZmFsc2UpO1xuICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC5jb25uZWN0KHRoaXMucm9tQmF1ZHJhdGUsIHRoaXMuc2VyaWFsT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IHJlc2V0U2VxdWVuY2VzID0gdGhpcy5jb25zdHJ1Y3RSZXNldFNlcXVlbmNlKG1vZGUpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dGVtcHRzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc2V0U2VxdWVuY2UgPSByZXNldFNlcXVlbmNlcy5sZW5ndGggPiAwID8gcmVzZXRTZXF1ZW5jZXNbaSAlIHJlc2V0U2VxdWVuY2VzLmxlbmd0aF0gOiBudWxsO1xuICAgICAgICAgICAgcmVzcCA9IGF3YWl0IHRoaXMuX2Nvbm5lY3RBdHRlbXB0KG1vZGUsIHJlc2V0U2VxdWVuY2UpO1xuICAgICAgICAgICAgaWYgKHJlc3AgPT09IFwic3VjY2Vzc1wiKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3AgIT09IFwic3VjY2Vzc1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRVNQRXJyb3IoXCJGYWlsZWQgdG8gY29ubmVjdCB3aXRoIHRoZSBkZXZpY2VcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZWJ1ZyhcIkNvbm5lY3QgYXR0ZW1wdCBzdWNjZXNzZnVsLlwiKTtcbiAgICAgICAgdGhpcy5pbmZvKFwiXFxuXFxyXCIsIGZhbHNlKTtcbiAgICAgICAgaWYgKGRldGVjdGluZykge1xuICAgICAgICAgICAgY29uc3QgY2hpcE1hZ2ljVmFsdWUgPSAoYXdhaXQgdGhpcy5yZWFkUmVnKHRoaXMuQ0hJUF9ERVRFQ1RfTUFHSUNfUkVHX0FERFIpKSA+Pj4gMDtcbiAgICAgICAgICAgIHRoaXMuZGVidWcoXCJDaGlwIE1hZ2ljIFwiICsgY2hpcE1hZ2ljVmFsdWUudG9TdHJpbmcoMTYpKTtcbiAgICAgICAgICAgIGNvbnN0IGNoaXAgPSBhd2FpdCBtYWdpYzJDaGlwKGNoaXBNYWdpY1ZhbHVlKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmNoaXAgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRVNQRXJyb3IoYFVuZXhwZWN0ZWQgQ0hJUCBtYWdpYyB2YWx1ZSAke2NoaXBNYWdpY1ZhbHVlfS4gRmFpbGVkIHRvIGF1dG9kZXRlY3QgY2hpcCB0eXBlLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jaGlwID0gY2hpcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IGFuZCBkZXRlY3QgdGhlIGV4aXN0aW5nIGNoaXAuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1vZGUgUmVzZXQgbW9kZSB0byB1c2UgZm9yIGNvbm5lY3Rpb24uXG4gICAgICovXG4gICAgYXN5bmMgZGV0ZWN0Q2hpcChtb2RlID0gXCJkZWZhdWx0X3Jlc2V0XCIpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5jb25uZWN0KG1vZGUpO1xuICAgICAgICB0aGlzLmluZm8oXCJEZXRlY3RpbmcgY2hpcCB0eXBlLi4uIFwiLCBmYWxzZSk7XG4gICAgICAgIGlmICh0aGlzLmNoaXAgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5pbmZvKHRoaXMuY2hpcC5DSElQX05BTUUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pbmZvKFwidW5rbm93biFcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogRXhlY3V0ZSB0aGUgY29tbWFuZCBhbmQgY2hlY2sgdGhlIGNvbW1hbmQgcmVzcG9uc2UuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG9wRGVzY3JpcHRpb24gQ29tbWFuZCBvcGVyYXRpb24gZGVzY3JpcHRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG9wIENvbW1hbmQgb3BlcmF0aW9uIG51bWJlclxuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gZGF0YSBDb21tYW5kIHZhbHVlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNoayBDaGVja3N1bSB0byB1c2VcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdGltZW91dCBUSW1lb3V0IG51bWJlciBpbiBtaWxsaXNlY29uZHMgKG1zKVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IENvbW1hbmQgcmVzdWx0XG4gICAgICovXG4gICAgYXN5bmMgY2hlY2tDb21tYW5kKG9wRGVzY3JpcHRpb24gPSBcIlwiLCBvcCA9IG51bGwsIGRhdGEgPSBuZXcgVWludDhBcnJheSgwKSwgY2hrID0gMCwgdGltZW91dCA9IHRoaXMuREVGQVVMVF9USU1FT1VUKSB7XG4gICAgICAgIHRoaXMuZGVidWcoXCJjaGVja19jb21tYW5kIFwiICsgb3BEZXNjcmlwdGlvbik7XG4gICAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCB0aGlzLmNvbW1hbmQob3AsIGRhdGEsIGNoaywgdW5kZWZpbmVkLCB0aW1lb3V0KTtcbiAgICAgICAgaWYgKHJlc3BbMV0ubGVuZ3RoID4gNCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BbMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzcFswXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCBkb3dubG9hZGluZyBhbiBhcHBsaWNhdGlvbiBpbWFnZSB0byBSQU1cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBJbWFnZSBzaXplIG51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBibG9ja3MgTnVtYmVyIG9mIGRhdGEgYmxvY2tzXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJsb2Nrc2l6ZSBTaXplIG9mIGVhY2ggZGF0YSBibG9ja1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgSW1hZ2Ugb2Zmc2V0IG51bWJlclxuICAgICAqL1xuICAgIGFzeW5jIG1lbUJlZ2luKHNpemUsIGJsb2NrcywgYmxvY2tzaXplLCBvZmZzZXQpIHtcbiAgICAgICAgLyogWFhYOiBBZGQgY2hlY2sgdG8gZW5zdXJlIHRoYXQgU1RVQiBpcyBub3QgZ2V0dGluZyBvdmVyd3JpdHRlbiAqL1xuICAgICAgICBpZiAodGhpcy5JU19TVFVCKSB7XG4gICAgICAgICAgICBjb25zdCBsb2FkU3RhcnQgPSBvZmZzZXQ7XG4gICAgICAgICAgICBjb25zdCBsb2FkRW5kID0gb2Zmc2V0ICsgc2l6ZTtcbiAgICAgICAgICAgIGNvbnN0IHN0dWIgPSBhd2FpdCBnZXRTdHViSnNvbkJ5Q2hpcE5hbWUodGhpcy5jaGlwLkNISVBfTkFNRSk7XG4gICAgICAgICAgICBpZiAoc3R1Yikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyZWFzVG9DaGVjayA9IFtcbiAgICAgICAgICAgICAgICAgICAgW3N0dWIuYnNzX3N0YXJ0IHx8IHN0dWIuZGF0YV9zdGFydCwgc3R1Yi5kYXRhX3N0YXJ0ICsgc3R1Yi5kZWNvZGVkRGF0YS5sZW5ndGhdLFxuICAgICAgICAgICAgICAgICAgICBbc3R1Yi50ZXh0X3N0YXJ0LCBzdHViLnRleHRfc3RhcnQgKyBzdHViLmRlY29kZWRUZXh0Lmxlbmd0aF0sXG4gICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtzdHViU3RhcnQsIHN0dWJFbmRdIG9mIGFyZWFzVG9DaGVjaykge1xuICAgICAgICAgICAgICAgICAgICBpZiAobG9hZFN0YXJ0IDwgc3R1YkVuZCAmJiBsb2FkRW5kID4gc3R1YlN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRVNQRXJyb3IoYFNvZnR3YXJlIGxvYWRlciBpcyByZXNpZGVudCBhdCAweCR7c3R1YlN0YXJ0LnRvU3RyaW5nKDE2KS5wYWRTdGFydCg4LCBcIjBcIil9LTB4JHtzdHViRW5kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKDE2KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wYWRTdGFydCg4LCBcIjBcIil9LlxuICAgICAgICAgICAgQ2FuJ3QgbG9hZCBiaW5hcnkgYXQgb3ZlcmxhcHBpbmcgYWRkcmVzcyByYW5nZSAweCR7bG9hZFN0YXJ0LnRvU3RyaW5nKDE2KS5wYWRTdGFydCg4LCBcIjBcIil9LTB4JHtsb2FkRW5kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKDE2KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wYWRTdGFydCg4LCBcIjBcIil9LlxuICAgICAgICAgICAgRWl0aGVyIGNoYW5nZSBiaW5hcnkgbG9hZGluZyBhZGRyZXNzLCBvciB1c2UgdGhlIG5vLXN0dWIgb3B0aW9uIHRvIGRpc2FibGUgdGhlIHNvZnR3YXJlIGxvYWRlci5gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlYnVnKFwibWVtX2JlZ2luIFwiICsgc2l6ZSArIFwiIFwiICsgYmxvY2tzICsgXCIgXCIgKyBibG9ja3NpemUgKyBcIiBcIiArIG9mZnNldC50b1N0cmluZygxNikpO1xuICAgICAgICBsZXQgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkodGhpcy5faW50VG9CeXRlQXJyYXkoc2l6ZSksIHRoaXMuX2ludFRvQnl0ZUFycmF5KGJsb2NrcykpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KGJsb2Nrc2l6ZSkpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KG9mZnNldCkpO1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrQ29tbWFuZChcImVudGVyIFJBTSBkb3dubG9hZCBtb2RlXCIsIHRoaXMuRVNQX01FTV9CRUdJTiwgcGt0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjaGVja3N1bSBmb3IgZ2l2ZW4gdW5zaWduZWQgOC1iaXQgYXJyYXlcbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGRhdGEgVW5zaWduZWQgOC1iaXQgaW50ZWdlciBhcnJheVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGF0ZSBJbml0aWFsIGNoZWNrc3VtXG4gICAgICogQHJldHVybnMge251bWJlcn0gLSBBcnJheSBjaGVja3N1bVxuICAgICAqL1xuICAgIGNoZWNrc3VtKGRhdGEsIHN0YXRlID0gdGhpcy5FU1BfQ0hFQ0tTVU1fTUFHSUMpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBzdGF0ZSBePSBkYXRhW2ldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VuZCBhIGJsb2NrIG9mIGltYWdlIHRvIFJBTVxuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIFVuc2lnbmVkIDgtYml0IGFycmF5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNlcSBTZXF1ZW5jZSBudW1iZXJcbiAgICAgKi9cbiAgICBhc3luYyBtZW1CbG9jayhidWZmZXIsIHNlcSkge1xuICAgICAgICBsZXQgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkodGhpcy5faW50VG9CeXRlQXJyYXkoYnVmZmVyLmxlbmd0aCksIHRoaXMuX2ludFRvQnl0ZUFycmF5KHNlcSkpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KDApKTtcbiAgICAgICAgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkocGt0LCB0aGlzLl9pbnRUb0J5dGVBcnJheSgwKSk7XG4gICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgYnVmZmVyKTtcbiAgICAgICAgY29uc3QgY2hlY2tzdW0gPSB0aGlzLmNoZWNrc3VtKGJ1ZmZlcik7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tDb21tYW5kKFwid3JpdGUgdG8gdGFyZ2V0IFJBTVwiLCB0aGlzLkVTUF9NRU1fREFUQSwgcGt0LCBjaGVja3N1bSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExlYXZlIFJBTSBkb3dubG9hZCBtb2RlIGFuZCBydW4gYXBwbGljYXRpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW50cnlwb2ludCAtIEVudHJ5cG9pbnQgbnVtYmVyXG4gICAgICovXG4gICAgYXN5bmMgbWVtRmluaXNoKGVudHJ5cG9pbnQpIHtcbiAgICAgICAgY29uc3QgaXNFbnRyeSA9IGVudHJ5cG9pbnQgPT09IDAgPyAxIDogMDtcbiAgICAgICAgY29uc3QgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkodGhpcy5faW50VG9CeXRlQXJyYXkoaXNFbnRyeSksIHRoaXMuX2ludFRvQnl0ZUFycmF5KGVudHJ5cG9pbnQpKTtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0NvbW1hbmQoXCJsZWF2ZSBSQU0gZG93bmxvYWQgbW9kZVwiLCB0aGlzLkVTUF9NRU1fRU5ELCBwa3QsIHVuZGVmaW5lZCwgMjAwKTsgLy8gWFhYOiBoYW5kbGUgbm9uLXN0dWIgd2l0aCBkaWZmIHRpbWVvdXRcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29uZmlndXJlIFNQSSBmbGFzaCBwaW5zXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhzcGlBcmcgLSAgQXJndW1lbnQgZm9yIFNQSSBhdHRhY2htZW50XG4gICAgICovXG4gICAgYXN5bmMgZmxhc2hTcGlBdHRhY2goaHNwaUFyZykge1xuICAgICAgICBjb25zdCBwa3QgPSB0aGlzLl9pbnRUb0J5dGVBcnJheShoc3BpQXJnKTtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0NvbW1hbmQoXCJjb25maWd1cmUgU1BJIGZsYXNoIHBpbnNcIiwgdGhpcy5FU1BfU1BJX0FUVEFDSCwgcGt0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NhbGUgdGltZW91dHMgd2hpY2ggYXJlIHNpemUtc3BlY2lmaWMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNlY29uZHNQZXJNYiBTZWNvbmRzIHBlciBtZWdhYnl0ZXMgYXMgbnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNpemVCeXRlcyBTaXplIGJ5dGVzIG51bWJlclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gU2NhbGVkIHRpbWVvdXQgZm9yIHNwZWNpZmllZCBzaXplLlxuICAgICAqL1xuICAgIHRpbWVvdXRQZXJNYihzZWNvbmRzUGVyTWIsIHNpemVCeXRlcykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBzZWNvbmRzUGVyTWIgKiAoc2l6ZUJ5dGVzIC8gMTAwMDAwMCk7XG4gICAgICAgIGlmIChyZXN1bHQgPCAzMDAwKSB7XG4gICAgICAgICAgICByZXR1cm4gMzAwMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgZG93bmxvYWRpbmcgdG8gRmxhc2ggKHBlcmZvcm1zIGFuIGVyYXNlKVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFNpemUgdG8gZXJhc2VcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldCB0byBlcmFzZVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBibG9ja3MgKG9mIHNpemUgc2VsZi5GTEFTSF9XUklURV9TSVpFKSB0byB3cml0ZS5cbiAgICAgKi9cbiAgICBhc3luYyBmbGFzaEJlZ2luKHNpemUsIG9mZnNldCkge1xuICAgICAgICBjb25zdCBudW1CbG9ja3MgPSBNYXRoLmZsb29yKChzaXplICsgdGhpcy5GTEFTSF9XUklURV9TSVpFIC0gMSkgLyB0aGlzLkZMQVNIX1dSSVRFX1NJWkUpO1xuICAgICAgICBjb25zdCBlcmFzZVNpemUgPSB0aGlzLmNoaXAuZ2V0RXJhc2VTaXplKG9mZnNldCwgc2l6ZSk7XG4gICAgICAgIGNvbnN0IGQgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBjb25zdCB0MSA9IGQuZ2V0VGltZSgpO1xuICAgICAgICBsZXQgdGltZW91dCA9IDMwMDA7XG4gICAgICAgIGlmICh0aGlzLklTX1NUVUIgPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRpbWVvdXQgPSB0aGlzLnRpbWVvdXRQZXJNYih0aGlzLkVSQVNFX1JFR0lPTl9USU1FT1VUX1BFUl9NQiwgc2l6ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZWJ1ZyhcImZsYXNoIGJlZ2luIFwiICsgZXJhc2VTaXplICsgXCIgXCIgKyBudW1CbG9ja3MgKyBcIiBcIiArIHRoaXMuRkxBU0hfV1JJVEVfU0laRSArIFwiIFwiICsgb2Zmc2V0ICsgXCIgXCIgKyBzaXplKTtcbiAgICAgICAgbGV0IHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHRoaXMuX2ludFRvQnl0ZUFycmF5KGVyYXNlU2l6ZSksIHRoaXMuX2ludFRvQnl0ZUFycmF5KG51bUJsb2NrcykpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KHRoaXMuRkxBU0hfV1JJVEVfU0laRSkpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KG9mZnNldCkpO1xuICAgICAgICBpZiAodGhpcy5JU19TVFVCID09IGZhbHNlKSB7XG4gICAgICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KDApKTsgLy8gWFhYOiBTdXBwb3J0IGVuY3J5cHRlZFxuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tDb21tYW5kKFwiZW50ZXIgRmxhc2ggZG93bmxvYWQgbW9kZVwiLCB0aGlzLkVTUF9GTEFTSF9CRUdJTiwgcGt0LCB1bmRlZmluZWQsIHRpbWVvdXQpO1xuICAgICAgICBjb25zdCB0MiA9IGQuZ2V0VGltZSgpO1xuICAgICAgICBpZiAoc2l6ZSAhPSAwICYmIHRoaXMuSVNfU1RVQiA9PSBmYWxzZSkge1xuICAgICAgICAgICAgdGhpcy5pbmZvKFwiVG9vayBcIiArICh0MiAtIHQxKSAvIDEwMDAgKyBcIi5cIiArICgodDIgLSB0MSkgJSAxMDAwKSArIFwicyB0byBlcmFzZSBmbGFzaCBibG9ja1wiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVtQmxvY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCBkb3dubG9hZGluZyBjb21wcmVzc2VkIGRhdGEgdG8gRmxhc2ggKHBlcmZvcm1zIGFuIGVyYXNlKVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFdyaXRlIHNpemVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY29tcHNpemUgQ29tcHJlc3NlZCBzaXplXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQgZm9yIHdyaXRlXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyBudW1iZXIgb2YgYmxvY2tzIChzaXplIHNlbGYuRkxBU0hfV1JJVEVfU0laRSkgdG8gd3JpdGUuXG4gICAgICovXG4gICAgYXN5bmMgZmxhc2hEZWZsQmVnaW4oc2l6ZSwgY29tcHNpemUsIG9mZnNldCkge1xuICAgICAgICBjb25zdCBudW1CbG9ja3MgPSBNYXRoLmZsb29yKChjb21wc2l6ZSArIHRoaXMuRkxBU0hfV1JJVEVfU0laRSAtIDEpIC8gdGhpcy5GTEFTSF9XUklURV9TSVpFKTtcbiAgICAgICAgY29uc3QgZXJhc2VCbG9ja3MgPSBNYXRoLmZsb29yKChzaXplICsgdGhpcy5GTEFTSF9XUklURV9TSVpFIC0gMSkgLyB0aGlzLkZMQVNIX1dSSVRFX1NJWkUpO1xuICAgICAgICBjb25zdCBkID0gbmV3IERhdGUoKTtcbiAgICAgICAgY29uc3QgdDEgPSBkLmdldFRpbWUoKTtcbiAgICAgICAgbGV0IHdyaXRlU2l6ZSwgdGltZW91dDtcbiAgICAgICAgaWYgKHRoaXMuSVNfU1RVQikge1xuICAgICAgICAgICAgd3JpdGVTaXplID0gc2l6ZTtcbiAgICAgICAgICAgIHRpbWVvdXQgPSB0aGlzLkRFRkFVTFRfVElNRU9VVDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHdyaXRlU2l6ZSA9IGVyYXNlQmxvY2tzICogdGhpcy5GTEFTSF9XUklURV9TSVpFO1xuICAgICAgICAgICAgdGltZW91dCA9IHRoaXMudGltZW91dFBlck1iKHRoaXMuRVJBU0VfUkVHSU9OX1RJTUVPVVRfUEVSX01CLCB3cml0ZVNpemUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5mbyhcIkNvbXByZXNzZWQgXCIgKyBzaXplICsgXCIgYnl0ZXMgdG8gXCIgKyBjb21wc2l6ZSArIFwiLi4uXCIpO1xuICAgICAgICBsZXQgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkodGhpcy5faW50VG9CeXRlQXJyYXkod3JpdGVTaXplKSwgdGhpcy5faW50VG9CeXRlQXJyYXkobnVtQmxvY2tzKSk7XG4gICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkodGhpcy5GTEFTSF9XUklURV9TSVpFKSk7XG4gICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkob2Zmc2V0KSk7XG4gICAgICAgIGlmICgodGhpcy5jaGlwLkNISVBfTkFNRSA9PT0gXCJFU1AzMi1TMlwiIHx8XG4gICAgICAgICAgICB0aGlzLmNoaXAuQ0hJUF9OQU1FID09PSBcIkVTUDMyLVMzXCIgfHxcbiAgICAgICAgICAgIHRoaXMuY2hpcC5DSElQX05BTUUgPT09IFwiRVNQMzItQzNcIiB8fFxuICAgICAgICAgICAgdGhpcy5jaGlwLkNISVBfTkFNRSA9PT0gXCJFU1AzMi1DMlwiKSAmJlxuICAgICAgICAgICAgdGhpcy5JU19TVFVCID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkocGt0LCB0aGlzLl9pbnRUb0J5dGVBcnJheSgwKSk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0NvbW1hbmQoXCJlbnRlciBjb21wcmVzc2VkIGZsYXNoIG1vZGVcIiwgdGhpcy5FU1BfRkxBU0hfREVGTF9CRUdJTiwgcGt0LCB1bmRlZmluZWQsIHRpbWVvdXQpO1xuICAgICAgICBjb25zdCB0MiA9IGQuZ2V0VGltZSgpO1xuICAgICAgICBpZiAoc2l6ZSAhPSAwICYmIHRoaXMuSVNfU1RVQiA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuaW5mbyhcIlRvb2sgXCIgKyAodDIgLSB0MSkgLyAxMDAwICsgXCIuXCIgKyAoKHQyIC0gdDEpICUgMTAwMCkgKyBcInMgdG8gZXJhc2UgZmxhc2ggYmxvY2tcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bUJsb2NrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGUgYmxvY2sgdG8gZmxhc2gsIHJldHJ5IGlmIGZhaWxcbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGRhdGEgVW5zaWduZWQgOC1iaXQgYXJyYXkgZGF0YS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2VxIFNlcXVlbmNlIG51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0IFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIChtcylcbiAgICAgKi9cbiAgICBhc3luYyBmbGFzaEJsb2NrKGRhdGEsIHNlcSwgdGltZW91dCkge1xuICAgICAgICBsZXQgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkodGhpcy5faW50VG9CeXRlQXJyYXkoZGF0YS5sZW5ndGgpLCB0aGlzLl9pbnRUb0J5dGVBcnJheShzZXEpKTtcbiAgICAgICAgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkocGt0LCB0aGlzLl9pbnRUb0J5dGVBcnJheSgwKSk7XG4gICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkoMCkpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIGRhdGEpO1xuICAgICAgICBjb25zdCBjaGVja3N1bSA9IHRoaXMuY2hlY2tzdW0oZGF0YSk7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tDb21tYW5kKFwid3JpdGUgdG8gdGFyZ2V0IEZsYXNoIGFmdGVyIHNlcSBcIiArIHNlcSwgdGhpcy5FU1BfRkxBU0hfREFUQSwgcGt0LCBjaGVja3N1bSwgdGltZW91dCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdyaXRlIGJsb2NrIHRvIGZsYXNoLCBzZW5kIGNvbXByZXNzZWQsIHJldHJ5IGlmIGZhaWxcbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGRhdGEgVW5zaWduZWQgaW50IDgtYml0IGFycmF5IGRhdGEgdG8gd3JpdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2VxIFNlcXVlbmNlIG51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0IFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIChtcylcbiAgICAgKi9cbiAgICBhc3luYyBmbGFzaERlZmxCbG9jayhkYXRhLCBzZXEsIHRpbWVvdXQpIHtcbiAgICAgICAgbGV0IHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHRoaXMuX2ludFRvQnl0ZUFycmF5KGRhdGEubGVuZ3RoKSwgdGhpcy5faW50VG9CeXRlQXJyYXkoc2VxKSk7XG4gICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkoMCkpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KDApKTtcbiAgICAgICAgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkocGt0LCBkYXRhKTtcbiAgICAgICAgY29uc3QgY2hlY2tzdW0gPSB0aGlzLmNoZWNrc3VtKGRhdGEpO1xuICAgICAgICB0aGlzLmRlYnVnKFwiZmxhc2hfZGVmbF9ibG9jayBcIiArIGRhdGFbMF0udG9TdHJpbmcoMTYpICsgXCIgXCIgKyBkYXRhWzFdLnRvU3RyaW5nKDE2KSk7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tDb21tYW5kKFwid3JpdGUgY29tcHJlc3NlZCBkYXRhIHRvIGZsYXNoIGFmdGVyIHNlcSBcIiArIHNlcSwgdGhpcy5FU1BfRkxBU0hfREVGTF9EQVRBLCBwa3QsIGNoZWNrc3VtLCB0aW1lb3V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGVhdmUgZmxhc2ggbW9kZSBhbmQgcnVuL3JlYm9vdFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmVib290IFJlYm9vdCBhZnRlciBsZWF2aW5nIGZsYXNoIG1vZGUgP1xuICAgICAqL1xuICAgIGFzeW5jIGZsYXNoRmluaXNoKHJlYm9vdCA9IGZhbHNlKSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHJlYm9vdCA/IDAgOiAxO1xuICAgICAgICBjb25zdCBwa3QgPSB0aGlzLl9pbnRUb0J5dGVBcnJheSh2YWwpO1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrQ29tbWFuZChcImxlYXZlIEZsYXNoIG1vZGVcIiwgdGhpcy5FU1BfRkxBU0hfRU5ELCBwa3QpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMZWF2ZSBjb21wcmVzc2VkIGZsYXNoIG1vZGUgYW5kIHJ1bi9yZWJvb3RcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHJlYm9vdCBSZWJvb3QgYWZ0ZXIgbGVhdmluZyBmbGFzaCBtb2RlID9cbiAgICAgKi9cbiAgICBhc3luYyBmbGFzaERlZmxGaW5pc2gocmVib290ID0gZmFsc2UpIHtcbiAgICAgICAgY29uc3QgdmFsID0gcmVib290ID8gMCA6IDE7XG4gICAgICAgIGNvbnN0IHBrdCA9IHRoaXMuX2ludFRvQnl0ZUFycmF5KHZhbCk7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tDb21tYW5kKFwibGVhdmUgY29tcHJlc3NlZCBmbGFzaCBtb2RlXCIsIHRoaXMuRVNQX0ZMQVNIX0RFRkxfRU5ELCBwa3QpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSdW4gYW4gYXJiaXRyYXJ5IFNQSSBmbGFzaCBjb21tYW5kLlxuICAgICAqXG4gICAgICogVGhpcyBmdW5jdGlvbiB1c2VzIHRoZSBcIlVTUl9DT01NQU5EXCIgZnVuY3Rpb25hbGl0eSBpbiB0aGUgRVNQXG4gICAgICogU1BJIGhhcmR3YXJlLCByYXRoZXIgdGhhbiB0aGUgcHJlY2FubmVkIGNvbW1hbmRzIHN1cHBvcnRlZCBieVxuICAgICAqIGhhcmR3YXJlLiBTbyB0aGUgdmFsdWUgb2Ygc3BpZmxhc2hDb21tYW5kIGlzIGFuIGFjdHVhbCBjb21tYW5kXG4gICAgICogYnl0ZSwgc2VudCBvdmVyIHRoZSB3aXJlLlxuICAgICAqXG4gICAgICogQWZ0ZXIgd3JpdGluZyBjb21tYW5kIGJ5dGUsIHdyaXRlcyAnZGF0YScgdG8gTU9TSSBhbmQgdGhlblxuICAgICAqIHJlYWRzIGJhY2sgJ3JlYWRCaXRzJyBvZiByZXBseSBvbiBNSVNPLiBSZXN1bHQgaXMgYSBudW1iZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNwaWZsYXNoQ29tbWFuZCBDb21tYW5kIHRvIGV4ZWN1dGUgaW4gU1BJXG4gICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBkYXRhIERhdGEgdG8gc2VuZFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByZWFkQml0cyBOdW1iZXIgb2YgYml0cyB0byByZWFkXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmVnaXN0ZXIgU1BJX1cwX1JFRyB2YWx1ZVxuICAgICAqL1xuICAgIGFzeW5jIHJ1blNwaWZsYXNoQ29tbWFuZChzcGlmbGFzaENvbW1hbmQsIGRhdGEsIHJlYWRCaXRzKSB7XG4gICAgICAgIC8vIFNQSV9VU1IgcmVnaXN0ZXIgZmxhZ3NcbiAgICAgICAgY29uc3QgU1BJX1VTUl9DT01NQU5EID0gMSA8PCAzMTtcbiAgICAgICAgY29uc3QgU1BJX1VTUl9NSVNPID0gMSA8PCAyODtcbiAgICAgICAgY29uc3QgU1BJX1VTUl9NT1NJID0gMSA8PCAyNztcbiAgICAgICAgLy8gU1BJIHJlZ2lzdGVycywgYmFzZSBhZGRyZXNzIGRpZmZlcnMgRVNQMzIqIHZzIDgyNjZcbiAgICAgICAgY29uc3QgYmFzZSA9IHRoaXMuY2hpcC5TUElfUkVHX0JBU0U7XG4gICAgICAgIGNvbnN0IFNQSV9DTURfUkVHID0gYmFzZSArIDB4MDA7XG4gICAgICAgIGNvbnN0IFNQSV9VU1JfUkVHID0gYmFzZSArIHRoaXMuY2hpcC5TUElfVVNSX09GRlM7XG4gICAgICAgIGNvbnN0IFNQSV9VU1IxX1JFRyA9IGJhc2UgKyB0aGlzLmNoaXAuU1BJX1VTUjFfT0ZGUztcbiAgICAgICAgY29uc3QgU1BJX1VTUjJfUkVHID0gYmFzZSArIHRoaXMuY2hpcC5TUElfVVNSMl9PRkZTO1xuICAgICAgICBjb25zdCBTUElfVzBfUkVHID0gYmFzZSArIHRoaXMuY2hpcC5TUElfVzBfT0ZGUztcbiAgICAgICAgbGV0IHNldERhdGFMZW5ndGhzO1xuICAgICAgICBpZiAodGhpcy5jaGlwLlNQSV9NT1NJX0RMRU5fT0ZGUyAhPSBudWxsKSB7XG4gICAgICAgICAgICBzZXREYXRhTGVuZ3RocyA9IGFzeW5jIChtb3NpQml0cywgbWlzb0JpdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBTUElfTU9TSV9ETEVOX1JFRyA9IGJhc2UgKyB0aGlzLmNoaXAuU1BJX01PU0lfRExFTl9PRkZTO1xuICAgICAgICAgICAgICAgIGNvbnN0IFNQSV9NSVNPX0RMRU5fUkVHID0gYmFzZSArIHRoaXMuY2hpcC5TUElfTUlTT19ETEVOX09GRlM7XG4gICAgICAgICAgICAgICAgaWYgKG1vc2lCaXRzID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLndyaXRlUmVnKFNQSV9NT1NJX0RMRU5fUkVHLCBtb3NpQml0cyAtIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWlzb0JpdHMgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMud3JpdGVSZWcoU1BJX01JU09fRExFTl9SRUcsIG1pc29CaXRzIC0gMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHNldERhdGFMZW5ndGhzID0gYXN5bmMgKG1vc2lCaXRzLCBtaXNvQml0cykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IFNQSV9EQVRBX0xFTl9SRUcgPSBTUElfVVNSMV9SRUc7XG4gICAgICAgICAgICAgICAgY29uc3QgU1BJX01PU0lfQklUTEVOX1MgPSAxNztcbiAgICAgICAgICAgICAgICBjb25zdCBTUElfTUlTT19CSVRMRU5fUyA9IDg7XG4gICAgICAgICAgICAgICAgY29uc3QgbW9zaU1hc2sgPSBtb3NpQml0cyA9PT0gMCA/IDAgOiBtb3NpQml0cyAtIDE7XG4gICAgICAgICAgICAgICAgY29uc3QgbWlzb01hc2sgPSBtaXNvQml0cyA9PT0gMCA/IDAgOiBtaXNvQml0cyAtIDE7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsID0gKG1pc29NYXNrIDw8IFNQSV9NSVNPX0JJVExFTl9TKSB8IChtb3NpTWFzayA8PCBTUElfTU9TSV9CSVRMRU5fUyk7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy53cml0ZVJlZyhTUElfREFUQV9MRU5fUkVHLCB2YWwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBTUElfQ01EX1VTUiA9IDEgPDwgMTg7XG4gICAgICAgIGNvbnN0IFNQSV9VU1IyX0NPTU1BTkRfTEVOX1NISUZUID0gMjg7XG4gICAgICAgIGlmIChyZWFkQml0cyA+IDMyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRVNQRXJyb3IoXCJSZWFkaW5nIG1vcmUgdGhhbiAzMiBiaXRzIGJhY2sgZnJvbSBhIFNQSSBmbGFzaCBvcGVyYXRpb24gaXMgdW5zdXBwb3J0ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEubGVuZ3RoID4gNjQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFU1BFcnJvcihcIldyaXRpbmcgbW9yZSB0aGFuIDY0IGJ5dGVzIG9mIGRhdGEgd2l0aCBvbmUgU1BJIGNvbW1hbmQgaXMgdW5zdXBwb3J0ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0YUJpdHMgPSBkYXRhLmxlbmd0aCAqIDg7XG4gICAgICAgIGNvbnN0IG9sZFNwaVVzciA9IGF3YWl0IHRoaXMucmVhZFJlZyhTUElfVVNSX1JFRyk7XG4gICAgICAgIGNvbnN0IG9sZFNwaVVzcjIgPSBhd2FpdCB0aGlzLnJlYWRSZWcoU1BJX1VTUjJfUkVHKTtcbiAgICAgICAgbGV0IGZsYWdzID0gU1BJX1VTUl9DT01NQU5EO1xuICAgICAgICBsZXQgaTtcbiAgICAgICAgaWYgKHJlYWRCaXRzID4gMCkge1xuICAgICAgICAgICAgZmxhZ3MgfD0gU1BJX1VTUl9NSVNPO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRhQml0cyA+IDApIHtcbiAgICAgICAgICAgIGZsYWdzIHw9IFNQSV9VU1JfTU9TSTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBzZXREYXRhTGVuZ3RocyhkYXRhQml0cywgcmVhZEJpdHMpO1xuICAgICAgICBhd2FpdCB0aGlzLndyaXRlUmVnKFNQSV9VU1JfUkVHLCBmbGFncyk7XG4gICAgICAgIGxldCB2YWwgPSAoNyA8PCBTUElfVVNSMl9DT01NQU5EX0xFTl9TSElGVCkgfCBzcGlmbGFzaENvbW1hbmQ7XG4gICAgICAgIGF3YWl0IHRoaXMud3JpdGVSZWcoU1BJX1VTUjJfUkVHLCB2YWwpO1xuICAgICAgICBpZiAoZGF0YUJpdHMgPT0gMCkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy53cml0ZVJlZyhTUElfVzBfUkVHLCAwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAlIDQgIT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhZGRpbmcgPSBuZXcgVWludDhBcnJheShkYXRhLmxlbmd0aCAlIDQpO1xuICAgICAgICAgICAgICAgIGRhdGEgPSB0aGlzLl9hcHBlbmRBcnJheShkYXRhLCBwYWRkaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBuZXh0UmVnID0gU1BJX1cwX1JFRztcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBkYXRhLmxlbmd0aCAtIDQ7IGkgKz0gNCkge1xuICAgICAgICAgICAgICAgIHZhbCA9IHRoaXMuX2J5dGVBcnJheVRvSW50KGRhdGFbaV0sIGRhdGFbaSArIDFdLCBkYXRhW2kgKyAyXSwgZGF0YVtpICsgM10pO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMud3JpdGVSZWcobmV4dFJlZywgdmFsKTtcbiAgICAgICAgICAgICAgICBuZXh0UmVnICs9IDQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy53cml0ZVJlZyhTUElfQ01EX1JFRywgU1BJX0NNRF9VU1IpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykge1xuICAgICAgICAgICAgdmFsID0gKGF3YWl0IHRoaXMucmVhZFJlZyhTUElfQ01EX1JFRykpICYgU1BJX0NNRF9VU1I7XG4gICAgICAgICAgICBpZiAodmFsID09IDApIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaSA9PT0gMTApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFU1BFcnJvcihcIlNQSSBjb21tYW5kIGRpZCBub3QgY29tcGxldGUgaW4gdGltZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGF0ID0gYXdhaXQgdGhpcy5yZWFkUmVnKFNQSV9XMF9SRUcpO1xuICAgICAgICBhd2FpdCB0aGlzLndyaXRlUmVnKFNQSV9VU1JfUkVHLCBvbGRTcGlVc3IpO1xuICAgICAgICBhd2FpdCB0aGlzLndyaXRlUmVnKFNQSV9VU1IyX1JFRywgb2xkU3BpVXNyMik7XG4gICAgICAgIHJldHVybiBzdGF0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIGZsYXNoIGlkIGJ5IGV4ZWN1dGluZyB0aGUgU1BJRkxBU0hfUkRJRCBmbGFzaCBjb21tYW5kLlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59IFJlZ2lzdGVyIFNQSV9XMF9SRUcgdmFsdWVcbiAgICAgKi9cbiAgICBhc3luYyByZWFkRmxhc2hJZCgpIHtcbiAgICAgICAgY29uc3QgU1BJRkxBU0hfUkRJRCA9IDB4OWY7XG4gICAgICAgIGNvbnN0IHBrdCA9IG5ldyBVaW50OEFycmF5KDApO1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5TcGlmbGFzaENvbW1hbmQoU1BJRkxBU0hfUkRJRCwgcGt0LCAyNCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGUgdGhlIGVyYXNlIGZsYXNoIGNvbW1hbmRcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxudW1iZXIgfCBVaW50OEFycmF5Pn0gRXJhc2UgZmxhc2ggY29tbWFuZCByZXN1bHRcbiAgICAgKi9cbiAgICBhc3luYyBlcmFzZUZsYXNoKCkge1xuICAgICAgICB0aGlzLmluZm8oXCJFcmFzaW5nIGZsYXNoICh0aGlzIG1heSB0YWtlIGEgd2hpbGUpLi4uXCIpO1xuICAgICAgICBsZXQgZCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGNvbnN0IHQxID0gZC5nZXRUaW1lKCk7XG4gICAgICAgIGNvbnN0IHJldCA9IGF3YWl0IHRoaXMuY2hlY2tDb21tYW5kKFwiZXJhc2UgZmxhc2hcIiwgdGhpcy5FU1BfRVJBU0VfRkxBU0gsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aGlzLkNISVBfRVJBU0VfVElNRU9VVCk7XG4gICAgICAgIGQgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBjb25zdCB0MiA9IGQuZ2V0VGltZSgpO1xuICAgICAgICB0aGlzLmluZm8oXCJDaGlwIGVyYXNlIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkgaW4gXCIgKyAodDIgLSB0MSkgLyAxMDAwICsgXCJzXCIpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGEgbnVtYmVyIG9yIHVuc2lnbmVkIDgtYml0IGFycmF5IHRvIGhleCBzdHJpbmdcbiAgICAgKiBAcGFyYW0ge251bWJlciB8IFVpbnQ4QXJyYXkgfSBidWZmZXIgRGF0YSB0byBjb252ZXJ0IHRvIGhleCBzdHJpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQSBoZXggc3RyaW5nXG4gICAgICovXG4gICAgdG9IZXgoYnVmZmVyKSB7XG4gICAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUubWFwLmNhbGwoYnVmZmVyLCAoeCkgPT4gKFwiMDBcIiArIHgudG9TdHJpbmcoMTYpKS5zbGljZSgtMikpLmpvaW4oXCJcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZSB0aGUgTUQ1IENoZWNrc3VtIGNvbW1hbmRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYWRkciBBZGRyZXNzIG51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFBhY2thZ2Ugc2l6ZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IE1ENSBDaGVja3N1bSBzdHJpbmdcbiAgICAgKi9cbiAgICBhc3luYyBmbGFzaE1kNXN1bShhZGRyLCBzaXplKSB7XG4gICAgICAgIGNvbnN0IHRpbWVvdXQgPSB0aGlzLnRpbWVvdXRQZXJNYih0aGlzLk1ENV9USU1FT1VUX1BFUl9NQiwgc2l6ZSk7XG4gICAgICAgIGxldCBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheSh0aGlzLl9pbnRUb0J5dGVBcnJheShhZGRyKSwgdGhpcy5faW50VG9CeXRlQXJyYXkoc2l6ZSkpO1xuICAgICAgICBwa3QgPSB0aGlzLl9hcHBlbmRBcnJheShwa3QsIHRoaXMuX2ludFRvQnl0ZUFycmF5KDApKTtcbiAgICAgICAgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkocGt0LCB0aGlzLl9pbnRUb0J5dGVBcnJheSgwKSk7XG4gICAgICAgIGxldCByZXMgPSBhd2FpdCB0aGlzLmNoZWNrQ29tbWFuZChcImNhbGN1bGF0ZSBtZDVzdW1cIiwgdGhpcy5FU1BfU1BJX0ZMQVNIX01ENSwgcGt0LCB1bmRlZmluZWQsIHRpbWVvdXQpO1xuICAgICAgICBpZiAocmVzIGluc3RhbmNlb2YgVWludDhBcnJheSAmJiByZXMubGVuZ3RoID4gMTYpIHtcbiAgICAgICAgICAgIHJlcyA9IHJlcy5zbGljZSgwLCAxNik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RybWQ1ID0gdGhpcy50b0hleChyZXMpO1xuICAgICAgICByZXR1cm4gc3RybWQ1O1xuICAgIH1cbiAgICBhc3luYyByZWFkRmxhc2goYWRkciwgc2l6ZSwgb25QYWNrZXRSZWNlaXZlZCA9IG51bGwpIHtcbiAgICAgICAgbGV0IHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHRoaXMuX2ludFRvQnl0ZUFycmF5KGFkZHIpLCB0aGlzLl9pbnRUb0J5dGVBcnJheShzaXplKSk7XG4gICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkoMHgxMDAwKSk7XG4gICAgICAgIHBrdCA9IHRoaXMuX2FwcGVuZEFycmF5KHBrdCwgdGhpcy5faW50VG9CeXRlQXJyYXkoMTAyNCkpO1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmNoZWNrQ29tbWFuZChcInJlYWQgZmxhc2hcIiwgdGhpcy5FU1BfUkVBRF9GTEFTSCwgcGt0KTtcbiAgICAgICAgaWYgKHJlcyAhPSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRVNQRXJyb3IoXCJGYWlsZWQgdG8gcmVhZCBtZW1vcnk6IFwiICsgcmVzKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzcCA9IG5ldyBVaW50OEFycmF5KDApO1xuICAgICAgICB3aGlsZSAocmVzcC5sZW5ndGggPCBzaXplKSB7XG4gICAgICAgICAgICBjb25zdCB7IHZhbHVlOiBwYWNrZXQgfSA9IGF3YWl0IHRoaXMudHJhbnNwb3J0LnJlYWQodGhpcy5GTEFTSF9SRUFEX1RJTUVPVVQpLm5leHQoKTtcbiAgICAgICAgICAgIGlmIChwYWNrZXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhY2tldC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3AgPSB0aGlzLl9hcHBlbmRBcnJheShyZXNwLCBwYWNrZXQpO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC53cml0ZSh0aGlzLl9pbnRUb0J5dGVBcnJheShyZXNwLmxlbmd0aCkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAob25QYWNrZXRSZWNlaXZlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb25QYWNrZXRSZWNlaXZlZChwYWNrZXQsIHJlc3AubGVuZ3RoLCBzaXplKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFU1BFcnJvcihcIkZhaWxlZCB0byByZWFkIG1lbW9yeTogXCIgKyBwYWNrZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGxvYWQgdGhlIGZsYXNoZXIgUk9NIGJvb3Rsb2FkZXIgKGZsYXNoZXIgc3R1YikgdG8gdGhlIGNoaXAuXG4gICAgICogQHJldHVybnMge1JPTX0gVGhlIENoaXAgUk9NXG4gICAgICovXG4gICAgYXN5bmMgcnVuU3R1YigpIHtcbiAgICAgICAgaWYgKHRoaXMuc3luY1N0dWJEZXRlY3RlZCkge1xuICAgICAgICAgICAgdGhpcy5pbmZvKFwiU3R1YiBpcyBhbHJlYWR5IHJ1bm5pbmcuIE5vIHVwbG9hZCBpcyBuZWNlc3NhcnkuXCIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2hpcDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluZm8oXCJVcGxvYWRpbmcgc3R1Yi4uLlwiKTtcbiAgICAgICAgY29uc3Qgc3R1YkZsYXNoZXIgPSBhd2FpdCBnZXRTdHViSnNvbkJ5Q2hpcE5hbWUodGhpcy5jaGlwLkNISVBfTkFNRSk7XG4gICAgICAgIGlmIChzdHViRmxhc2hlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmRlYnVnKFwiRXJyb3IgbG9hZGluZyBTdHViIGpzb25cIik7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFcnJvciBsb2FkaW5nIFN0dWIganNvblwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdHViID0gW3N0dWJGbGFzaGVyLmRlY29kZWRUZXh0LCBzdHViRmxhc2hlci5kZWNvZGVkRGF0YV07XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3R1Yi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHN0dWJbaV0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvZmZzID0gaSA9PT0gMCA/IHN0dWJGbGFzaGVyLnRleHRfc3RhcnQgOiBzdHViRmxhc2hlci5kYXRhX3N0YXJ0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IHN0dWJbaV0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJsb2NrcyA9IE1hdGguZmxvb3IoKGxlbmd0aCArIHRoaXMuRVNQX1JBTV9CTE9DSyAtIDEpIC8gdGhpcy5FU1BfUkFNX0JMT0NLKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLm1lbUJlZ2luKGxlbmd0aCwgYmxvY2tzLCB0aGlzLkVTUF9SQU1fQkxPQ0ssIG9mZnMpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHNlcSA9IDA7IHNlcSA8IGJsb2Nrczsgc2VxKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnJvbU9mZnMgPSBzZXEgKiB0aGlzLkVTUF9SQU1fQkxPQ0s7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvT2ZmcyA9IGZyb21PZmZzICsgdGhpcy5FU1BfUkFNX0JMT0NLO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLm1lbUJsb2NrKHN0dWJbaV0uc2xpY2UoZnJvbU9mZnMsIHRvT2ZmcyksIHNlcSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5mbyhcIlJ1bm5pbmcgc3R1Yi4uLlwiKTtcbiAgICAgICAgYXdhaXQgdGhpcy5tZW1GaW5pc2goc3R1YkZsYXNoZXIuZW50cnkpO1xuICAgICAgICBjb25zdCB7IHZhbHVlOiBwYWNrZXRSZXN1bHQgfSA9IGF3YWl0IHRoaXMudHJhbnNwb3J0LnJlYWQodGhpcy5ERUZBVUxUX1RJTUVPVVQpLm5leHQoKTtcbiAgICAgICAgY29uc3QgcGFja2V0U3RyID0gU3RyaW5nLmZyb21DaGFyQ29kZSguLi5wYWNrZXRSZXN1bHQpO1xuICAgICAgICBpZiAocGFja2V0U3RyICE9PSBcIk9IQUlcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVTUEVycm9yKGBGYWlsZWQgdG8gc3RhcnQgc3R1Yi4gVW5leHBlY3RlZCByZXNwb25zZSAke3BhY2tldFN0cn1gKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluZm8oXCJTdHViIHJ1bm5pbmcuLi5cIik7XG4gICAgICAgIHRoaXMuSVNfU1RVQiA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzLmNoaXA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoYW5nZSB0aGUgY2hpcCBiYXVkcmF0ZS5cbiAgICAgKi9cbiAgICBhc3luYyBjaGFuZ2VCYXVkKCkge1xuICAgICAgICB0aGlzLmluZm8oXCJDaGFuZ2luZyBiYXVkcmF0ZSB0byBcIiArIHRoaXMuYmF1ZHJhdGUpO1xuICAgICAgICBjb25zdCBzZWNvbmRBcmcgPSB0aGlzLklTX1NUVUIgPyB0aGlzLnJvbUJhdWRyYXRlIDogMDtcbiAgICAgICAgY29uc3QgcGt0ID0gdGhpcy5fYXBwZW5kQXJyYXkodGhpcy5faW50VG9CeXRlQXJyYXkodGhpcy5iYXVkcmF0ZSksIHRoaXMuX2ludFRvQnl0ZUFycmF5KHNlY29uZEFyZykpO1xuICAgICAgICBhd2FpdCB0aGlzLmNvbW1hbmQodGhpcy5FU1BfQ0hBTkdFX0JBVURSQVRFLCBwa3QpO1xuICAgICAgICB0aGlzLmluZm8oXCJDaGFuZ2VkXCIpO1xuICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC5kaXNjb25uZWN0KCk7XG4gICAgICAgIGF3YWl0IHRoaXMuX3NsZWVwKDUwKTtcbiAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuY29ubmVjdCh0aGlzLmJhdWRyYXRlLCB0aGlzLnNlcmlhbE9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlIHRoZSBtYWluIGZ1bmN0aW9uIG9mIEVTUExvYWRlci5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbW9kZSBSZXNldCBtb2RlIHRvIHVzZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IGNoaXAgUk9NXG4gICAgICovXG4gICAgYXN5bmMgbWFpbihtb2RlID0gXCJkZWZhdWx0X3Jlc2V0XCIpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5kZXRlY3RDaGlwKG1vZGUpO1xuICAgICAgICBjb25zdCBjaGlwID0gYXdhaXQgdGhpcy5jaGlwLmdldENoaXBEZXNjcmlwdGlvbih0aGlzKTtcbiAgICAgICAgdGhpcy5pbmZvKFwiQ2hpcCBpcyBcIiArIGNoaXApO1xuICAgICAgICB0aGlzLmluZm8oXCJGZWF0dXJlczogXCIgKyAoYXdhaXQgdGhpcy5jaGlwLmdldENoaXBGZWF0dXJlcyh0aGlzKSkpO1xuICAgICAgICB0aGlzLmluZm8oXCJDcnlzdGFsIGlzIFwiICsgKGF3YWl0IHRoaXMuY2hpcC5nZXRDcnlzdGFsRnJlcSh0aGlzKSkgKyBcIk1IelwiKTtcbiAgICAgICAgdGhpcy5pbmZvKFwiTUFDOiBcIiArIChhd2FpdCB0aGlzLmNoaXAucmVhZE1hYyh0aGlzKSkpO1xuICAgICAgICBhd2FpdCB0aGlzLmNoaXAucmVhZE1hYyh0aGlzKTtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmNoaXAucG9zdENvbm5lY3QgIT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jaGlwLnBvc3RDb25uZWN0KHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMucnVuU3R1YigpO1xuICAgICAgICBpZiAodGhpcy5yb21CYXVkcmF0ZSAhPT0gdGhpcy5iYXVkcmF0ZSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jaGFuZ2VCYXVkKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNoaXA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhcnNlIGEgZ2l2ZW4gZmxhc2ggc2l6ZSBzdHJpbmcgdG8gYSBudW1iZXJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZmxzeiBGbGFzaCBzaXplIHRvIHJlcXVlc3RcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBGbGFzaCBzaXplIG51bWJlclxuICAgICAqL1xuICAgIHBhcnNlRmxhc2hTaXplQXJnKGZsc3opIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmNoaXAuRkxBU0hfU0laRVNbZmxzel0gPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFU1BFcnJvcihcIkZsYXNoIHNpemUgXCIgKyBmbHN6ICsgXCIgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGNoaXAgdHlwZS4gU3VwcG9ydGVkIHNpemVzOiBcIiArIHRoaXMuY2hpcC5GTEFTSF9TSVpFUyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuY2hpcC5GTEFTSF9TSVpFU1tmbHN6XTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSBpbWFnZSBmbGFzaCBwYXJhbWV0ZXJzIHdpdGggZ2l2ZW4gYXJndW1lbnRzLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpbWFnZSBiaW5hcnkgaW1hZ2UgYXMgc3RyaW5nXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGFkZHJlc3MgZmxhc2ggYWRkcmVzcyBudW1iZXJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZmxhc2hTaXplIEZsYXNoIHNpemUgc3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZsYXNoTW9kZSBGbGFzaCBtb2RlIHN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmbGFzaEZyZXEgRmxhc2ggZnJlcXVlbmN5IHN0cmluZ1xuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IG1vZGlmaWVkIGltYWdlIHN0cmluZ1xuICAgICAqL1xuICAgIF91cGRhdGVJbWFnZUZsYXNoUGFyYW1zKGltYWdlLCBhZGRyZXNzLCBmbGFzaFNpemUsIGZsYXNoTW9kZSwgZmxhc2hGcmVxKSB7XG4gICAgICAgIHRoaXMuZGVidWcoXCJfdXBkYXRlX2ltYWdlX2ZsYXNoX3BhcmFtcyBcIiArIGZsYXNoU2l6ZSArIFwiIFwiICsgZmxhc2hNb2RlICsgXCIgXCIgKyBmbGFzaEZyZXEpO1xuICAgICAgICBpZiAoaW1hZ2UubGVuZ3RoIDwgOCkge1xuICAgICAgICAgICAgcmV0dXJuIGltYWdlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhZGRyZXNzICE9IHRoaXMuY2hpcC5CT09UTE9BREVSX0ZMQVNIX09GRlNFVCkge1xuICAgICAgICAgICAgcmV0dXJuIGltYWdlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmbGFzaFNpemUgPT09IFwia2VlcFwiICYmIGZsYXNoTW9kZSA9PT0gXCJrZWVwXCIgJiYgZmxhc2hGcmVxID09PSBcImtlZXBcIikge1xuICAgICAgICAgICAgdGhpcy5pbmZvKFwiTm90IGNoYW5naW5nIHRoZSBpbWFnZVwiKTtcbiAgICAgICAgICAgIHJldHVybiBpbWFnZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYWdpYyA9IHBhcnNlSW50KGltYWdlWzBdKTtcbiAgICAgICAgbGV0IGFGbGFzaE1vZGUgPSBwYXJzZUludChpbWFnZVsyXSk7XG4gICAgICAgIGNvbnN0IGZsYXNoU2l6ZUZyZXEgPSBwYXJzZUludChpbWFnZVszXSk7XG4gICAgICAgIGlmIChtYWdpYyAhPT0gdGhpcy5FU1BfSU1BR0VfTUFHSUMpIHtcbiAgICAgICAgICAgIHRoaXMuaW5mbyhcIldhcm5pbmc6IEltYWdlIGZpbGUgYXQgMHhcIiArXG4gICAgICAgICAgICAgICAgYWRkcmVzcy50b1N0cmluZygxNikgK1xuICAgICAgICAgICAgICAgIFwiIGRvZXNuJ3QgbG9vayBsaWtlIGFuIGltYWdlIGZpbGUsIHNvIG5vdCBjaGFuZ2luZyBhbnkgZmxhc2ggc2V0dGluZ3MuXCIpO1xuICAgICAgICAgICAgcmV0dXJuIGltYWdlO1xuICAgICAgICB9XG4gICAgICAgIC8qIFhYWDogWWV0IHRvIGltcGxlbWVudCBhY3R1YWwgaW1hZ2UgdmVyaWZpY2F0aW9uICovXG4gICAgICAgIGlmIChmbGFzaE1vZGUgIT09IFwia2VlcFwiKSB7XG4gICAgICAgICAgICBjb25zdCBmbGFzaE1vZGVzID0geyBxaW86IDAsIHFvdXQ6IDEsIGRpbzogMiwgZG91dDogMyB9O1xuICAgICAgICAgICAgYUZsYXNoTW9kZSA9IGZsYXNoTW9kZXNbZmxhc2hNb2RlXTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYUZsYXNoRnJlcSA9IGZsYXNoU2l6ZUZyZXEgJiAweDBmO1xuICAgICAgICBpZiAoZmxhc2hGcmVxICE9PSBcImtlZXBcIikge1xuICAgICAgICAgICAgY29uc3QgZmxhc2hGcmVxcyA9IHsgXCI0MG1cIjogMCwgXCIyNm1cIjogMSwgXCIyMG1cIjogMiwgXCI4MG1cIjogMHhmIH07XG4gICAgICAgICAgICBhRmxhc2hGcmVxID0gZmxhc2hGcmVxc1tmbGFzaEZyZXFdO1xuICAgICAgICB9XG4gICAgICAgIGxldCBhRmxhc2hTaXplID0gZmxhc2hTaXplRnJlcSAmIDB4ZjA7XG4gICAgICAgIGlmIChmbGFzaFNpemUgIT09IFwia2VlcFwiKSB7XG4gICAgICAgICAgICBhRmxhc2hTaXplID0gdGhpcy5wYXJzZUZsYXNoU2l6ZUFyZyhmbGFzaFNpemUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZsYXNoUGFyYW1zID0gKGFGbGFzaE1vZGUgPDwgOCkgfCAoYUZsYXNoRnJlcSArIGFGbGFzaFNpemUpO1xuICAgICAgICB0aGlzLmluZm8oXCJGbGFzaCBwYXJhbXMgc2V0IHRvIFwiICsgZmxhc2hQYXJhbXMudG9TdHJpbmcoMTYpKTtcbiAgICAgICAgaWYgKHBhcnNlSW50KGltYWdlWzJdKSAhPT0gYUZsYXNoTW9kZSA8PCA4KSB7XG4gICAgICAgICAgICBpbWFnZSA9IGltYWdlLnN1YnN0cmluZygwLCAyKSArIChhRmxhc2hNb2RlIDw8IDgpLnRvU3RyaW5nKCkgKyBpbWFnZS5zdWJzdHJpbmcoMiArIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJzZUludChpbWFnZVszXSkgIT09IGFGbGFzaEZyZXEgKyBhRmxhc2hTaXplKSB7XG4gICAgICAgICAgICBpbWFnZSA9IGltYWdlLnN1YnN0cmluZygwLCAzKSArIChhRmxhc2hGcmVxICsgYUZsYXNoU2l6ZSkudG9TdHJpbmcoKSArIGltYWdlLnN1YnN0cmluZygzICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGltYWdlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZSBzZXQgb2YgZmlsZSBpbWFnZXMgaW50byBnaXZlbiBhZGRyZXNzIGJhc2VkIG9uIGdpdmVuIEZsYXNoT3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtGbGFzaE9wdGlvbnN9IG9wdGlvbnMgRmxhc2hPcHRpb25zIHRvIGNvbmZpZ3VyZSBob3cgYW5kIHdoYXQgdG8gd3JpdGUgaW50byBmbGFzaC5cbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZUZsYXNoKG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZyhcIkVzcExvYWRlciBwcm9ncmFtXCIpO1xuICAgICAgICBpZiAob3B0aW9ucy5mbGFzaFNpemUgIT09IFwia2VlcFwiKSB7XG4gICAgICAgICAgICBjb25zdCBmbGFzaEVuZCA9IHRoaXMuZmxhc2hTaXplQnl0ZXMob3B0aW9ucy5mbGFzaFNpemUpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLmZpbGVBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmZpbGVBcnJheVtpXS5kYXRhLmxlbmd0aCArIG9wdGlvbnMuZmlsZUFycmF5W2ldLmFkZHJlc3MgPiBmbGFzaEVuZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRVNQRXJyb3IoYEZpbGUgJHtpICsgMX0gZG9lc24ndCBmaXQgaW4gdGhlIGF2YWlsYWJsZSBmbGFzaGApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5JU19TVFVCID09PSB0cnVlICYmIG9wdGlvbnMuZXJhc2VBbGwgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZXJhc2VGbGFzaCgpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBpbWFnZSwgYWRkcmVzcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLmZpbGVBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5kZWJ1ZyhcIkRhdGEgTGVuZ3RoIFwiICsgb3B0aW9ucy5maWxlQXJyYXlbaV0uZGF0YS5sZW5ndGgpO1xuICAgICAgICAgICAgaW1hZ2UgPSBvcHRpb25zLmZpbGVBcnJheVtpXS5kYXRhO1xuICAgICAgICAgICAgdGhpcy5kZWJ1ZyhcIkltYWdlIExlbmd0aCBcIiArIGltYWdlLmxlbmd0aCk7XG4gICAgICAgICAgICBpZiAoaW1hZ2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWJ1ZyhcIldhcm5pbmc6IEZpbGUgaXMgZW1wdHlcIik7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbWFnZSA9IHRoaXMudWk4VG9Cc3RyKHBhZFRvKHRoaXMuYnN0clRvVWk4KGltYWdlKSwgNCkpO1xuICAgICAgICAgICAgYWRkcmVzcyA9IG9wdGlvbnMuZmlsZUFycmF5W2ldLmFkZHJlc3M7XG4gICAgICAgICAgICBpbWFnZSA9IHRoaXMuX3VwZGF0ZUltYWdlRmxhc2hQYXJhbXMoaW1hZ2UsIGFkZHJlc3MsIG9wdGlvbnMuZmxhc2hTaXplLCBvcHRpb25zLmZsYXNoTW9kZSwgb3B0aW9ucy5mbGFzaEZyZXEpO1xuICAgICAgICAgICAgbGV0IGNhbGNtZDUgPSBudWxsO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY2FsY3VsYXRlTUQ1SGFzaCkge1xuICAgICAgICAgICAgICAgIGNhbGNtZDUgPSBvcHRpb25zLmNhbGN1bGF0ZU1ENUhhc2goaW1hZ2UpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGVidWcoXCJJbWFnZSBNRDUgXCIgKyBjYWxjbWQ1KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHVuY3NpemUgPSBpbWFnZS5sZW5ndGg7XG4gICAgICAgICAgICBsZXQgYmxvY2tzO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29tcHJlc3MpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB1bmNpbWFnZSA9IHRoaXMuYnN0clRvVWk4KGltYWdlKTtcbiAgICAgICAgICAgICAgICBpbWFnZSA9IHRoaXMudWk4VG9Cc3RyKGRlZmxhdGUodW5jaW1hZ2UsIHsgbGV2ZWw6IDkgfSkpO1xuICAgICAgICAgICAgICAgIGJsb2NrcyA9IGF3YWl0IHRoaXMuZmxhc2hEZWZsQmVnaW4odW5jc2l6ZSwgaW1hZ2UubGVuZ3RoLCBhZGRyZXNzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGJsb2NrcyA9IGF3YWl0IHRoaXMuZmxhc2hCZWdpbih1bmNzaXplLCBhZGRyZXNzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBzZXEgPSAwO1xuICAgICAgICAgICAgbGV0IGJ5dGVzU2VudCA9IDA7XG4gICAgICAgICAgICBjb25zdCB0b3RhbEJ5dGVzID0gaW1hZ2UubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMucmVwb3J0UHJvZ3Jlc3MpXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5yZXBvcnRQcm9ncmVzcyhpLCAwLCB0b3RhbEJ5dGVzKTtcbiAgICAgICAgICAgIGxldCBkID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgIGNvbnN0IHQxID0gZC5nZXRUaW1lKCk7XG4gICAgICAgICAgICBsZXQgdGltZW91dCA9IDUwMDA7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBkZWNvbXByZXNzb3IgdG8ga2VlcCB0cmFjayBvZiB0aGUgc2l6ZSBvZiB1bmNvbXByZXNzZWQgZGF0YVxuICAgICAgICAgICAgLy8gdG8gYmUgd3JpdHRlbiBpbiBlYWNoIGNodW5rLlxuICAgICAgICAgICAgY29uc3QgaW5mbGF0ZSA9IG5ldyBJbmZsYXRlKHsgY2h1bmtTaXplOiAxIH0pO1xuICAgICAgICAgICAgbGV0IHRvdGFsTGVuVW5jb21wcmVzc2VkID0gMDtcbiAgICAgICAgICAgIGluZmxhdGUub25EYXRhID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgICAgICAgICAgdG90YWxMZW5VbmNvbXByZXNzZWQgKz0gY2h1bmsuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB3aGlsZSAoaW1hZ2UubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVidWcoXCJXcml0ZSBsb29wIFwiICsgYWRkcmVzcyArIFwiIFwiICsgc2VxICsgXCIgXCIgKyBibG9ja3MpO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5mbyhcIldyaXRpbmcgYXQgMHhcIiArXG4gICAgICAgICAgICAgICAgICAgIChhZGRyZXNzICsgdG90YWxMZW5VbmNvbXByZXNzZWQpLnRvU3RyaW5nKDE2KSArXG4gICAgICAgICAgICAgICAgICAgIFwiLi4uIChcIiArXG4gICAgICAgICAgICAgICAgICAgIE1hdGguZmxvb3IoKDEwMCAqIChzZXEgKyAxKSkgLyBibG9ja3MpICtcbiAgICAgICAgICAgICAgICAgICAgXCIlKVwiKTtcbiAgICAgICAgICAgICAgICBjb25zdCBibG9jayA9IHRoaXMuYnN0clRvVWk4KGltYWdlLnNsaWNlKDAsIHRoaXMuRkxBU0hfV1JJVEVfU0laRSkpO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmNvbXByZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlblVuY29tcHJlc3NlZFByZXZpb3VzID0gdG90YWxMZW5VbmNvbXByZXNzZWQ7XG4gICAgICAgICAgICAgICAgICAgIGluZmxhdGUucHVzaChibG9jaywgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBibG9ja1VuY29tcHJlc3NlZCA9IHRvdGFsTGVuVW5jb21wcmVzc2VkIC0gbGVuVW5jb21wcmVzc2VkUHJldmlvdXM7XG4gICAgICAgICAgICAgICAgICAgIGxldCBibG9ja1RpbWVvdXQgPSAzMDAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50aW1lb3V0UGVyTWIodGhpcy5FUkFTRV9XUklURV9USU1FT1VUX1BFUl9NQiwgYmxvY2tVbmNvbXByZXNzZWQpID4gMzAwMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tUaW1lb3V0ID0gdGhpcy50aW1lb3V0UGVyTWIodGhpcy5FUkFTRV9XUklURV9USU1FT1VUX1BFUl9NQiwgYmxvY2tVbmNvbXByZXNzZWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLklTX1NUVUIgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBST00gY29kZSB3cml0ZXMgYmxvY2sgdG8gZmxhc2ggYmVmb3JlIEFDS2luZ1xuICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dCA9IGJsb2NrVGltZW91dDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZsYXNoRGVmbEJsb2NrKGJsb2NrLCBzZXEsIHRpbWVvdXQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5JU19TVFVCKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTdHViIEFDS3Mgd2hlbiBibG9jayBpcyByZWNlaXZlZCwgdGhlbiB3cml0ZXMgdG8gZmxhc2ggd2hpbGUgcmVjZWl2aW5nIHRoZSBibG9jayBhZnRlciBpdFxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZW91dCA9IGJsb2NrVGltZW91dDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVTUEVycm9yKFwiWWV0IHRvIGhhbmRsZSBOb24gQ29tcHJlc3NlZCB3cml0ZXNcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJ5dGVzU2VudCArPSBibG9jay5sZW5ndGg7XG4gICAgICAgICAgICAgICAgaW1hZ2UgPSBpbWFnZS5zbGljZSh0aGlzLkZMQVNIX1dSSVRFX1NJWkUsIGltYWdlLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgc2VxKys7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMucmVwb3J0UHJvZ3Jlc3MpXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMucmVwb3J0UHJvZ3Jlc3MoaSwgYnl0ZXNTZW50LCB0b3RhbEJ5dGVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLklTX1NUVUIpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlYWRSZWcodGhpcy5DSElQX0RFVEVDVF9NQUdJQ19SRUdfQUREUiwgdGltZW91dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgIGNvbnN0IHQgPSBkLmdldFRpbWUoKSAtIHQxO1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29tcHJlc3MpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluZm8oXCJXcm90ZSBcIiArXG4gICAgICAgICAgICAgICAgICAgIHVuY3NpemUgK1xuICAgICAgICAgICAgICAgICAgICBcIiBieXRlcyAoXCIgK1xuICAgICAgICAgICAgICAgICAgICBieXRlc1NlbnQgK1xuICAgICAgICAgICAgICAgICAgICBcIiBjb21wcmVzc2VkKSBhdCAweFwiICtcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzcy50b1N0cmluZygxNikgK1xuICAgICAgICAgICAgICAgICAgICBcIiBpbiBcIiArXG4gICAgICAgICAgICAgICAgICAgIHQgLyAxMDAwICtcbiAgICAgICAgICAgICAgICAgICAgXCIgc2Vjb25kcy5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2FsY21kNSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuZmxhc2hNZDVzdW0oYWRkcmVzcywgdW5jc2l6ZSk7XG4gICAgICAgICAgICAgICAgaWYgKG5ldyBTdHJpbmcocmVzKS52YWx1ZU9mKCkgIT0gbmV3IFN0cmluZyhjYWxjbWQ1KS52YWx1ZU9mKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmZvKFwiRmlsZSAgbWQ1OiBcIiArIGNhbGNtZDUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZm8oXCJGbGFzaCBtZDU6IFwiICsgcmVzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVTUEVycm9yKFwiTUQ1IG9mIGZpbGUgZG9lcyBub3QgbWF0Y2ggZGF0YSBpbiBmbGFzaCFcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZm8oXCJIYXNoIG9mIGRhdGEgdmVyaWZpZWQuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmluZm8oXCJMZWF2aW5nLi4uXCIpO1xuICAgICAgICBpZiAodGhpcy5JU19TVFVCKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmZsYXNoQmVnaW4oMCwgMCk7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5jb21wcmVzcykge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuZmxhc2hEZWZsRmluaXNoKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZsYXNoRmluaXNoKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCBTUEkgZmxhc2ggbWFudWZhY3R1cmVyIGFuZCBkZXZpY2UgaWQuXG4gICAgICovXG4gICAgYXN5bmMgZmxhc2hJZCgpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZyhcImZsYXNoX2lkXCIpO1xuICAgICAgICBjb25zdCBmbGFzaGlkID0gYXdhaXQgdGhpcy5yZWFkRmxhc2hJZCgpO1xuICAgICAgICB0aGlzLmluZm8oXCJNYW51ZmFjdHVyZXI6IFwiICsgKGZsYXNoaWQgJiAweGZmKS50b1N0cmluZygxNikpO1xuICAgICAgICBjb25zdCBmbGlkTG93Ynl0ZSA9IChmbGFzaGlkID4+IDE2KSAmIDB4ZmY7XG4gICAgICAgIHRoaXMuaW5mbyhcIkRldmljZTogXCIgKyAoKGZsYXNoaWQgPj4gOCkgJiAweGZmKS50b1N0cmluZygxNikgKyBmbGlkTG93Ynl0ZS50b1N0cmluZygxNikpO1xuICAgICAgICB0aGlzLmluZm8oXCJEZXRlY3RlZCBmbGFzaCBzaXplOiBcIiArIHRoaXMuREVURUNURURfRkxBU0hfU0laRVNbZmxpZExvd2J5dGVdKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Rmxhc2hTaXplKCkge1xuICAgICAgICB0aGlzLmRlYnVnKFwiZmxhc2hfaWRcIik7XG4gICAgICAgIGNvbnN0IGZsYXNoaWQgPSBhd2FpdCB0aGlzLnJlYWRGbGFzaElkKCk7XG4gICAgICAgIGNvbnN0IGZsaWRMb3dieXRlID0gKGZsYXNoaWQgPj4gMTYpICYgMHhmZjtcbiAgICAgICAgcmV0dXJuIHRoaXMuREVURUNURURfRkxBU0hfU0laRVNfTlVNW2ZsaWRMb3dieXRlXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU29mdCByZXNldCB0aGUgZGV2aWNlIGNoaXAuIFNvZnQgcmVzZXQgd2l0aCBydW4gdXNlciBjb2RlIGlzIHRoZSBjbG9zZXN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gc3RheUluQm9vdGxvYWRlciBGbGFnIHRvIGluZGljYXRlIGlmIHRvIHN0YXkgaW4gYm9vdGxvYWRlclxuICAgICAqL1xuICAgIGFzeW5jIHNvZnRSZXNldChzdGF5SW5Cb290bG9hZGVyKSB7XG4gICAgICAgIGlmICghdGhpcy5JU19TVFVCKSB7XG4gICAgICAgICAgICBpZiAoc3RheUluQm9vdGxvYWRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybjsgLy8gUk9NIGJvb3Rsb2FkZXIgaXMgYWxyZWFkeSBpbiBib290bG9hZGVyIVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gXCJydW4gdXNlciBjb2RlXCIgaXMgYXMgY2xvc2UgdG8gYSBzb2Z0IHJlc2V0IGFzIHdlIGNhbiBkb1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5mbGFzaEJlZ2luKDAsIDApO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5mbGFzaEZpbmlzaChmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5jaGlwLkNISVBfTkFNRSAhPSBcIkVTUDgyNjZcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVTUEVycm9yKFwiU29mdCByZXNldHRpbmcgaXMgY3VycmVudGx5IG9ubHkgc3VwcG9ydGVkIG9uIEVTUDgyNjZcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoc3RheUluQm9vdGxvYWRlcikge1xuICAgICAgICAgICAgICAgIC8vIHNvZnQgcmVzZXR0aW5nIGZyb20gdGhlIHN0dWIgbG9hZGVyXG4gICAgICAgICAgICAgICAgLy8gd2lsbCByZS1sb2FkIHRoZSBST00gYm9vdGxvYWRlclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuZmxhc2hCZWdpbigwLCAwKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZsYXNoRmluaXNoKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gcnVubmluZyB1c2VyIGNvZGUgZnJvbSBzdHViIGxvYWRlciByZXF1aXJlcyBzb21lIGhhY2tzXG4gICAgICAgICAgICAgICAgLy8gaW4gdGhlIHN0dWIgbG9hZGVyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jb21tYW5kKHRoaXMuRVNQX1JVTl9VU0VSX0NPREUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogRXhlY3V0ZSB0aGlzIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgYWZ0ZXIgb3BlcmF0aW9uIHJlc2V0IGZ1bmN0aW9ucy5cbiAgICAgKiBAcGFyYW0ge0FmdGVyfSBtb2RlIEFmdGVyIG9wZXJhdGlvbiBtb2RlLiBEZWZhdWx0IGlzICdoYXJkX3Jlc2V0Jy5cbiAgICAgKiBAcGFyYW0geyBib29sZWFuIH0gdXNpbmdVc2JPdGcgRm9yICdoYXJkX3Jlc2V0JyB0byBzcGVjaWZ5IGlmIHVzaW5nIFVTQi1PVEdcbiAgICAgKi9cbiAgICBhc3luYyBhZnRlcihtb2RlID0gXCJoYXJkX3Jlc2V0XCIsIHVzaW5nVXNiT3RnKSB7XG4gICAgICAgIHN3aXRjaCAobW9kZSkge1xuICAgICAgICAgICAgY2FzZSBcImhhcmRfcmVzZXRcIjpcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXNldENvbnN0cnVjdG9ycy5oYXJkUmVzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmZvKFwiSGFyZCByZXNldHRpbmcgdmlhIFJUUyBwaW4uLi5cIik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGhhcmRSZXNldCA9IHRoaXMucmVzZXRDb25zdHJ1Y3RvcnMuaGFyZFJlc2V0KHRoaXMudHJhbnNwb3J0LCB1c2luZ1VzYk90Zyk7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGhhcmRSZXNldC5yZXNldCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJzb2Z0X3Jlc2V0XCI6XG4gICAgICAgICAgICAgICAgdGhpcy5pbmZvKFwiU29mdCByZXNldHRpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zb2Z0UmVzZXQoZmFsc2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIm5vX3Jlc2V0X3N0dWJcIjpcbiAgICAgICAgICAgICAgICB0aGlzLmluZm8oXCJTdGF5aW5nIGluIGZsYXNoZXIgc3R1Yi5cIik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRoaXMuaW5mbyhcIlN0YXlpbmcgaW4gYm9vdGxvYWRlci5cIik7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuSVNfU1RVQikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvZnRSZXNldCh0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJleHBvcnQgeyBFU1BMb2FkZXIgfSBmcm9tIFwiLi9lc3Bsb2FkZXIuanNcIjtcbmV4cG9ydCB7IENsYXNzaWNSZXNldCwgQ3VzdG9tUmVzZXQsIEhhcmRSZXNldCwgVXNiSnRhZ1NlcmlhbFJlc2V0LCB2YWxpZGF0ZUN1c3RvbVJlc2V0U3RyaW5nU2VxdWVuY2UsIH0gZnJvbSBcIi4vcmVzZXQuanNcIjtcbmV4cG9ydCB7IFJPTSB9IGZyb20gXCIuL3RhcmdldHMvcm9tLmpzXCI7XG5leHBvcnQgeyBUcmFuc3BvcnQgfSBmcm9tIFwiLi93ZWJzZXJpYWwuanNcIjtcbmV4cG9ydCB7IGRlY29kZUJhc2U2NERhdGEsIGdldFN0dWJKc29uQnlDaGlwTmFtZSB9IGZyb20gXCIuL3N0dWJGbGFzaGVyLmpzXCI7XG4iLCIvKipcbiAqIFNsZWVwIGZvciBtcyBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBtcyBNaWxsaXNlY29uZHMgdG8gd2FpdFxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gKi9cbmZ1bmN0aW9uIHNsZWVwKG1zKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG4vKipcbiAqIEV4ZWN1dGUgYSBjbGFzc2ljIHNldCBvZiBjb21tYW5kcyB0aGF0IHdpbGwgcmVzZXQgdGhlIGNoaXAuXG4gKlxuICogQ29tbWFuZHMgKGUuZy4gUjApIGFyZSBkZWZpbmVkIGJ5IGEgY29kZSAoUikgYW5kIGFuIGFyZ3VtZW50ICgwKS5cbiAqXG4gKiBUaGUgY29tbWFuZHMgYXJlOlxuICpcbiAqIEQ6IHNldERUUiAtIDE9VHJ1ZSAvIDA9RmFsc2VcbiAqXG4gKiBSOiBzZXRSVFMgLSAxPVRydWUgLyAwPUZhbHNlXG4gKlxuICogVzogV2FpdCAodGltZSBkZWxheSkgLSBwb3NpdGl2ZSBpbnRlZ2VyIG51bWJlciAobWlsaXNlY29uZHMpXG4gKlxuICogXCJEMHxSMXxXMTAwfEQxfFIwfFc1MHxEMFwiIHJlcHJlc2VudHMgdGhlIGNsYXNzaWMgcmVzZXQgc3RyYXRlZ3lcbiAqIEBwYXJhbSB7VHJhbnNwb3J0fSB0cmFuc3BvcnQgVHJhbnNwb3J0IGNsYXNzIHRvIHBlcmZvcm0gc2VyaWFsIGNvbW11bmljYXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gcmVzZXREZWxheSBEZWxheSBpbiBtaWxsaXNlY29uZHMgZm9yIHJlc2V0LlxuICovXG5leHBvcnQgY2xhc3MgQ2xhc3NpY1Jlc2V0IHtcbiAgICBjb25zdHJ1Y3Rvcih0cmFuc3BvcnQsIHJlc2V0RGVsYXkpIHtcbiAgICAgICAgdGhpcy5yZXNldERlbGF5ID0gcmVzZXREZWxheTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgfVxuICAgIGFzeW5jIHJlc2V0KCkge1xuICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC5zZXREVFIoZmFsc2UpO1xuICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC5zZXRSVFModHJ1ZSk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMCk7XG4gICAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnNldERUUih0cnVlKTtcbiAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuc2V0UlRTKGZhbHNlKTtcbiAgICAgICAgYXdhaXQgc2xlZXAodGhpcy5yZXNldERlbGF5KTtcbiAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuc2V0RFRSKGZhbHNlKTtcbiAgICB9XG59XG4vKipcbiAqIEV4ZWN1dGUgYSBzZXQgb2YgY29tbWFuZHMgZm9yIFVTQiBKVEFHIHNlcmlhbCByZXNldC5cbiAqXG4gKiBDb21tYW5kcyAoZS5nLiBSMCkgYXJlIGRlZmluZWQgYnkgYSBjb2RlIChSKSBhbmQgYW4gYXJndW1lbnQgKDApLlxuICpcbiAqIFRoZSBjb21tYW5kcyBhcmU6XG4gKlxuICogRDogc2V0RFRSIC0gMT1UcnVlIC8gMD1GYWxzZVxuICpcbiAqIFI6IHNldFJUUyAtIDE9VHJ1ZSAvIDA9RmFsc2VcbiAqXG4gKiBXOiBXYWl0ICh0aW1lIGRlbGF5KSAtIHBvc2l0aXZlIGludGVnZXIgbnVtYmVyIChtaWxpc2Vjb25kcylcbiAqIEBwYXJhbSB7VHJhbnNwb3J0fSB0cmFuc3BvcnQgVHJhbnNwb3J0IGNsYXNzIHRvIHBlcmZvcm0gc2VyaWFsIGNvbW11bmljYXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBVc2JKdGFnU2VyaWFsUmVzZXQge1xuICAgIGNvbnN0cnVjdG9yKHRyYW5zcG9ydCkge1xuICAgICAgICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydDtcbiAgICB9XG4gICAgYXN5bmMgcmVzZXQoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnNldFJUUyhmYWxzZSk7XG4gICAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnNldERUUihmYWxzZSk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMCk7XG4gICAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnNldERUUih0cnVlKTtcbiAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuc2V0UlRTKGZhbHNlKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwKTtcbiAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuc2V0UlRTKHRydWUpO1xuICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC5zZXREVFIoZmFsc2UpO1xuICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC5zZXRSVFModHJ1ZSk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMCk7XG4gICAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnNldFJUUyhmYWxzZSk7XG4gICAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnNldERUUihmYWxzZSk7XG4gICAgfVxufVxuLyoqXG4gKiBFeGVjdXRlIGEgc2V0IG9mIGNvbW1hbmRzIHRoYXQgd2lsbCBoYXJkIHJlc2V0IHRoZSBjaGlwLlxuICpcbiAqIENvbW1hbmRzIChlLmcuIFIwKSBhcmUgZGVmaW5lZCBieSBhIGNvZGUgKFIpIGFuZCBhbiBhcmd1bWVudCAoMCkuXG4gKlxuICogVGhlIGNvbW1hbmRzIGFyZTpcbiAqXG4gKiBEOiBzZXREVFIgLSAxPVRydWUgLyAwPUZhbHNlXG4gKlxuICogUjogc2V0UlRTIC0gMT1UcnVlIC8gMD1GYWxzZVxuICpcbiAqIFc6IFdhaXQgKHRpbWUgZGVsYXkpIC0gcG9zaXRpdmUgaW50ZWdlciBudW1iZXIgKG1pbGlzZWNvbmRzKVxuICogQHBhcmFtIHtUcmFuc3BvcnR9IHRyYW5zcG9ydCBUcmFuc3BvcnQgY2xhc3MgdG8gcGVyZm9ybSBzZXJpYWwgY29tbXVuaWNhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNpbmdVc2JPdGcgaXMgaXQgdXNpbmcgVVNCLU9URyA/XG4gKi9cbmV4cG9ydCBjbGFzcyBIYXJkUmVzZXQge1xuICAgIGNvbnN0cnVjdG9yKHRyYW5zcG9ydCwgdXNpbmdVc2JPdGcgPSBmYWxzZSkge1xuICAgICAgICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydDtcbiAgICAgICAgdGhpcy51c2luZ1VzYk90ZyA9IHVzaW5nVXNiT3RnO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydDtcbiAgICB9XG4gICAgYXN5bmMgcmVzZXQoKSB7XG4gICAgICAgIGlmICh0aGlzLnVzaW5nVXNiT3RnKSB7XG4gICAgICAgICAgICBhd2FpdCBzbGVlcCgyMDApO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuc2V0UlRTKGZhbHNlKTtcbiAgICAgICAgICAgIGF3YWl0IHNsZWVwKDIwMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCBzbGVlcCgxMDApO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQuc2V0UlRTKGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8qKlxuICogVmFsaWRhdGUgYSBzZXF1ZW5jZSBzdHJpbmcgYmFzZWQgb24gdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gKlxuICogQ29tbWFuZHMgKGUuZy4gUjApIGFyZSBkZWZpbmVkIGJ5IGEgY29kZSAoUikgYW5kIGFuIGFyZ3VtZW50ICgwKS5cbiAqXG4gKiBUaGUgY29tbWFuZHMgYXJlOlxuICpcbiAqIEQ6IHNldERUUiAtIDE9VHJ1ZSAvIDA9RmFsc2VcbiAqXG4gKiBSOiBzZXRSVFMgLSAxPVRydWUgLyAwPUZhbHNlXG4gKlxuICogVzogV2FpdCAodGltZSBkZWxheSkgLSBwb3NpdGl2ZSBpbnRlZ2VyIG51bWJlciAobWlsaXNlY29uZHMpXG4gKiBAcGFyYW0ge3N0cmluZ30gc2VxU3RyIFNlcXVlbmNlIHN0cmluZyB0byB2YWxpZGF0ZVxuICogQHJldHVybnMge2Jvb2xlYW59IElzIHRoZSBzZXF1ZW5jZSBzdHJpbmcgdmFsaWQgP1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVDdXN0b21SZXNldFN0cmluZ1NlcXVlbmNlKHNlcVN0cikge1xuICAgIGNvbnN0IGNvbW1hbmRzID0gW1wiRFwiLCBcIlJcIiwgXCJXXCJdO1xuICAgIGNvbnN0IGNvbW1hbmRzTGlzdCA9IHNlcVN0ci5zcGxpdChcInxcIik7XG4gICAgZm9yIChjb25zdCBjbWQgb2YgY29tbWFuZHNMaXN0KSB7XG4gICAgICAgIGNvbnN0IGNvZGUgPSBjbWRbMF07XG4gICAgICAgIGNvbnN0IGFyZyA9IGNtZC5zbGljZSgxKTtcbiAgICAgICAgaWYgKCFjb21tYW5kcy5pbmNsdWRlcyhjb2RlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBJbnZhbGlkIGNvbW1hbmQgY29kZVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb2RlID09PSBcIkRcIiB8fCBjb2RlID09PSBcIlJcIikge1xuICAgICAgICAgICAgaWYgKGFyZyAhPT0gXCIwXCIgJiYgYXJnICE9PSBcIjFcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gSW52YWxpZCBhcmd1bWVudCBmb3IgRCBhbmQgUiBjb21tYW5kc1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvZGUgPT09IFwiV1wiKSB7XG4gICAgICAgICAgICBjb25zdCBkZWxheSA9IHBhcnNlSW50KGFyZyk7XG4gICAgICAgICAgICBpZiAoaXNOYU4oZGVsYXkpIHx8IGRlbGF5IDw9IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIEludmFsaWQgYXJndW1lbnQgZm9yIFcgY29tbWFuZFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlOyAvLyBBbGwgY29tbWFuZHMgYXJlIHZhbGlkXG59XG4vKipcbiAqIEN1c3RvbSByZXNldCBzdHJhdGVneSBkZWZpbmVkIHdpdGggYSBzdHJpbmcuXG4gKlxuICogVGhlIHNlcXVlbmNlU3RyaW5nIGlucHV0IHN0cmluZyBjb25zaXN0cyBvZiBpbmRpdmlkdWFsIGNvbW1hbmRzIGRpdmlkZWQgYnkgXCJ8XCIuXG4gKlxuICogQ29tbWFuZHMgKGUuZy4gUjApIGFyZSBkZWZpbmVkIGJ5IGEgY29kZSAoUikgYW5kIGFuIGFyZ3VtZW50ICgwKS5cbiAqXG4gKiBUaGUgY29tbWFuZHMgYXJlOlxuICpcbiAqIEQ6IHNldERUUiAtIDE9VHJ1ZSAvIDA9RmFsc2VcbiAqXG4gKiBSOiBzZXRSVFMgLSAxPVRydWUgLyAwPUZhbHNlXG4gKlxuICogVzogV2FpdCAodGltZSBkZWxheSkgLSBwb3NpdGl2ZSBpbnRlZ2VyIG51bWJlciAobWlsaXNlY29uZHMpXG4gKlxuICogXCJEMHxSMXxXMTAwfEQxfFIwfFc1MHxEMFwiIHJlcHJlc2VudHMgdGhlIGNsYXNzaWMgcmVzZXQgc3RyYXRlZ3lcbiAqIEBwYXJhbSB7VHJhbnNwb3J0fSB0cmFuc3BvcnQgVHJhbnNwb3J0IGNsYXNzIHRvIHBlcmZvcm0gc2VyaWFsIGNvbW11bmljYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gc2VxdWVuY2VTdHJpbmcgQ3VzdG9tIHN0cmluZyBzZXF1ZW5jZSBmb3IgcmVzZXQgc3RyYXRlZ3lcbiAqL1xuZXhwb3J0IGNsYXNzIEN1c3RvbVJlc2V0IHtcbiAgICBjb25zdHJ1Y3Rvcih0cmFuc3BvcnQsIHNlcXVlbmNlU3RyaW5nKSB7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuICAgICAgICB0aGlzLnNlcXVlbmNlU3RyaW5nID0gc2VxdWVuY2VTdHJpbmc7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuICAgIH1cbiAgICBhc3luYyByZXNldCgpIHtcbiAgICAgICAgY29uc3QgcmVzZXREaWN0aW9uYXJ5ID0ge1xuICAgICAgICAgICAgRDogYXN5bmMgKGFyZykgPT4gYXdhaXQgdGhpcy50cmFuc3BvcnQuc2V0RFRSKGFyZyksXG4gICAgICAgICAgICBSOiBhc3luYyAoYXJnKSA9PiBhd2FpdCB0aGlzLnRyYW5zcG9ydC5zZXRSVFMoYXJnKSxcbiAgICAgICAgICAgIFc6IGFzeW5jIChkZWxheSkgPT4gYXdhaXQgc2xlZXAoZGVsYXkpLFxuICAgICAgICB9O1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgaXNWYWxpZFNlcXVlbmNlID0gdmFsaWRhdGVDdXN0b21SZXNldFN0cmluZ1NlcXVlbmNlKHRoaXMuc2VxdWVuY2VTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkU2VxdWVuY2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjbWRzID0gdGhpcy5zZXF1ZW5jZVN0cmluZy5zcGxpdChcInxcIik7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNtZCBvZiBjbWRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY21kS2V5ID0gY21kWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNtZFZhbCA9IGNtZC5zbGljZSgxKTtcbiAgICAgICAgICAgICAgICBpZiAoY21kS2V5ID09PSBcIldcIikge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXNldERpY3Rpb25hcnlbXCJXXCJdKE51bWJlcihjbWRWYWwpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY21kS2V5ID09PSBcIkRcIiB8fCBjbWRLZXkgPT09IFwiUlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlc2V0RGljdGlvbmFyeVtjbWRLZXldKGNtZFZhbCA9PT0gXCIxXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY3VzdG9tIHJlc2V0IHNlcXVlbmNlXCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgeyBDbGFzc2ljUmVzZXQsIEN1c3RvbVJlc2V0LCBIYXJkUmVzZXQsIFVzYkp0YWdTZXJpYWxSZXNldCwgdmFsaWRhdGVDdXN0b21SZXNldFN0cmluZ1NlcXVlbmNlIH07XG4iLCJpbXBvcnQgYXRvYiBmcm9tIFwiYXRvYi1saXRlXCI7XG4vKipcbiAqIEltcG9ydCBmbGFzaCBzdHViIGpzb24gZm9yIHRoZSBnaXZlbiBjaGlwIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gY2hpcE5hbWUgTmFtZSBvZiBjaGlwIHRvIG9idGFpbiBmbGFzaGVyIHN0dWJcbiAqIEByZXR1cm5zIHtTdHVifSBTdHViIGluZm9ybWF0aW9uIGFuZCBkZWNvZGVkIHRleHQgYW5kIGRhdGFcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldFN0dWJKc29uQnlDaGlwTmFtZShjaGlwTmFtZSkge1xuICAgIGxldCBqc29uU3R1YjtcbiAgICBzd2l0Y2ggKGNoaXBOYW1lKSB7XG4gICAgICAgIGNhc2UgXCJFU1AzMlwiOlxuICAgICAgICAgICAganNvblN0dWIgPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvc3R1Yl9mbGFzaGVyL3N0dWJfZmxhc2hlcl8zMi5qc29uXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJFU1AzMi1DMlwiOlxuICAgICAgICAgICAganNvblN0dWIgPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvc3R1Yl9mbGFzaGVyL3N0dWJfZmxhc2hlcl8zMmMyLmpzb25cIik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkVTUDMyLUMzXCI6XG4gICAgICAgICAgICBqc29uU3R1YiA9IGF3YWl0IGltcG9ydChcIi4vdGFyZ2V0cy9zdHViX2ZsYXNoZXIvc3R1Yl9mbGFzaGVyXzMyYzMuanNvblwiKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiRVNQMzItQzVcIjpcbiAgICAgICAgICAgIGpzb25TdHViID0gYXdhaXQgaW1wb3J0KFwiLi90YXJnZXRzL3N0dWJfZmxhc2hlci9zdHViX2ZsYXNoZXJfMzJjNS5qc29uXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJFU1AzMi1DNlwiOlxuICAgICAgICAgICAganNvblN0dWIgPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvc3R1Yl9mbGFzaGVyL3N0dWJfZmxhc2hlcl8zMmM2Lmpzb25cIik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkVTUDMyLUM2MVwiOlxuICAgICAgICAgICAganNvblN0dWIgPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvc3R1Yl9mbGFzaGVyL3N0dWJfZmxhc2hlcl8zMmM2MS5qc29uXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJFU1AzMi1IMlwiOlxuICAgICAgICAgICAganNvblN0dWIgPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvc3R1Yl9mbGFzaGVyL3N0dWJfZmxhc2hlcl8zMmgyLmpzb25cIik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkVTUDMyLVA0XCI6XG4gICAgICAgICAgICBqc29uU3R1YiA9IGF3YWl0IGltcG9ydChcIi4vdGFyZ2V0cy9zdHViX2ZsYXNoZXIvc3R1Yl9mbGFzaGVyXzMycDQuanNvblwiKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiRVNQMzItUzJcIjpcbiAgICAgICAgICAgIGpzb25TdHViID0gYXdhaXQgaW1wb3J0KFwiLi90YXJnZXRzL3N0dWJfZmxhc2hlci9zdHViX2ZsYXNoZXJfMzJzMi5qc29uXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJFU1AzMi1TM1wiOlxuICAgICAgICAgICAganNvblN0dWIgPSBhd2FpdCBpbXBvcnQoXCIuL3RhcmdldHMvc3R1Yl9mbGFzaGVyL3N0dWJfZmxhc2hlcl8zMnMzLmpzb25cIik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkVTUDgyNjZcIjpcbiAgICAgICAgICAgIGpzb25TdHViID0gYXdhaXQgaW1wb3J0KFwiLi90YXJnZXRzL3N0dWJfZmxhc2hlci9zdHViX2ZsYXNoZXJfODI2Ni5qc29uXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGlmIChqc29uU3R1Yikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYnNzX3N0YXJ0OiBqc29uU3R1Yi5ic3Nfc3RhcnQsXG4gICAgICAgICAgICBkYXRhOiBqc29uU3R1Yi5kYXRhLFxuICAgICAgICAgICAgZGF0YV9zdGFydDoganNvblN0dWIuZGF0YV9zdGFydCxcbiAgICAgICAgICAgIGVudHJ5OiBqc29uU3R1Yi5lbnRyeSxcbiAgICAgICAgICAgIHRleHQ6IGpzb25TdHViLnRleHQsXG4gICAgICAgICAgICB0ZXh0X3N0YXJ0OiBqc29uU3R1Yi50ZXh0X3N0YXJ0LFxuICAgICAgICAgICAgZGVjb2RlZERhdGE6IGRlY29kZUJhc2U2NERhdGEoanNvblN0dWIuZGF0YSksXG4gICAgICAgICAgICBkZWNvZGVkVGV4dDogZGVjb2RlQmFzZTY0RGF0YShqc29uU3R1Yi50ZXh0KSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuO1xufVxuLyoqXG4gKiBDb252ZXJ0IGEgYmFzZSA2NCBzdHJpbmcgdG8gVWludDhBcnJheS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhU3RyIEJhc2U2NCBTdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gRGVjb2RlZCBVaW50OEFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVCYXNlNjREYXRhKGRhdGFTdHIpIHtcbiAgICBjb25zdCBkZWNvZGVkID0gYXRvYihkYXRhU3RyKTtcbiAgICBjb25zdCBjaGFyZGF0YSA9IGRlY29kZWQuc3BsaXQoXCJcIikubWFwKGZ1bmN0aW9uICh4KSB7XG4gICAgICAgIHJldHVybiB4LmNoYXJDb2RlQXQoMCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGNoYXJkYXRhKTtcbn1cbiIsIi8qKlxuICogUmVwcmVzZW50cyBhIGNoaXAgUk9NIHdpdGggYmFzaWMgcmVnaXN0ZXJzIGZpZWxkIGFuZCBhYnN0cmFjdCBmdW5jdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBST00ge1xuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY2hpcCBlcmFzZSBzaXplLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgLSBPZmZzZXQgdG8gc3RhcnQgZXJhc2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNpemUgLSBTaXplIHRvIGVyYXNlLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBlcmFzZSBzaXplIG9mIHRoZSBjaGlwIGFzIG51bWJlci5cbiAgICAgKi9cbiAgICBnZXRFcmFzZVNpemUob2Zmc2V0LCBzaXplKSB7XG4gICAgICAgIHJldHVybiBzaXplO1xuICAgIH1cbn1cbiIsIi8qKlxuICogUmVwcmVzZW50cyBhIEVzcHJlc3NpZiBjaGlwIGVycm9yLlxuICovXG5jbGFzcyBFU1BFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbi8qKlxuICogUmVwcmVzZW50cyBhIEVzcHJlc3NpZiB0aW1lb3V0IGNoaXAgZXJyb3IuXG4gKi9cbmNsYXNzIFRpbWVvdXRFcnJvciBleHRlbmRzIEVTUEVycm9yIHtcbn1cbmV4cG9ydCB7IEVTUEVycm9yLCBUaW1lb3V0RXJyb3IgfTtcbiIsIi8qKlxuICogUGFkIHRvIHRoZSBuZXh0IGFsaWdubWVudCBib3VuZGFyeVxuICogQHBhcmFtIHtVaW50OEFycmF5fSBkYXRhIFVpbnQ4QXJyYXkgZGF0YSB0byBwYWRcbiAqIEBwYXJhbSB7bnVtYmVyfSBhbGlnbm1lbnQgQWxpZ25tZW50IGJvdW5kYXJ5IHRvIGZ1bGZpbGxcbiAqIEBwYXJhbSB7bnVtYmVyfSBwYWRDaGFyYWN0ZXIgQ2hhcmFjdGVyIHRvIGZpbGwgd2l0aFxuICogQHJldHVybnMge1VpbnQ4QXJyYXl9IFBhZGRlZCBVSW50OEFycmF5IGltYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYWRUbyhkYXRhLCBhbGlnbm1lbnQsIHBhZENoYXJhY3RlciA9IDB4ZmYpIHtcbiAgICBjb25zdCBwYWRNb2QgPSBkYXRhLmxlbmd0aCAlIGFsaWdubWVudDtcbiAgICBpZiAocGFkTW9kICE9PSAwKSB7XG4gICAgICAgIGNvbnN0IHBhZGRpbmcgPSBuZXcgVWludDhBcnJheShhbGlnbm1lbnQgLSBwYWRNb2QpLmZpbGwocGFkQ2hhcmFjdGVyKTtcbiAgICAgICAgY29uc3QgcGFkZGVkRGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEubGVuZ3RoICsgcGFkZGluZy5sZW5ndGgpO1xuICAgICAgICBwYWRkZWREYXRhLnNldChkYXRhKTtcbiAgICAgICAgcGFkZGVkRGF0YS5zZXQocGFkZGluZywgZGF0YS5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gcGFkZGVkRGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG59XG4iLCIvKiBnbG9iYWwgU2VyaWFsUG9ydCwgUGFyaXR5VHlwZSwgRmxvd0NvbnRyb2xUeXBlICovXG4vKipcbiAqIFdyYXBwZXIgY2xhc3MgYXJvdW5kIFdlYnNlcmlhbCBBUEkgdG8gY29tbXVuaWNhdGUgd2l0aCB0aGUgc2VyaWFsIGRldmljZS5cbiAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcInczYy13ZWItc2VyaWFsXCIpLlNlcmlhbFBvcnR9IGRldmljZSAtIFJlcXVlc3RlZCBkZXZpY2UgcHJvbXB0ZWQgYnkgdGhlIGJyb3dzZXIuXG4gKlxuICogYGBgXG4gKiBjb25zdCBwb3J0ID0gYXdhaXQgbmF2aWdhdG9yLnNlcmlhbC5yZXF1ZXN0UG9ydCgpO1xuICogYGBgXG4gKi9cbmNsYXNzIFRyYW5zcG9ydCB7XG4gICAgY29uc3RydWN0b3IoZGV2aWNlLCB0cmFjaW5nID0gZmFsc2UsIGVuYWJsZVNsaXBSZWFkZXIgPSB0cnVlKSB7XG4gICAgICAgIHRoaXMuZGV2aWNlID0gZGV2aWNlO1xuICAgICAgICB0aGlzLnRyYWNpbmcgPSB0cmFjaW5nO1xuICAgICAgICB0aGlzLnNsaXBSZWFkZXJFbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuYmF1ZHJhdGUgPSAwO1xuICAgICAgICB0aGlzLnRyYWNlTG9nID0gXCJcIjtcbiAgICAgICAgdGhpcy5sYXN0VHJhY2VUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgVWludDhBcnJheSgwKTtcbiAgICAgICAgdGhpcy5TTElQX0VORCA9IDB4YzA7XG4gICAgICAgIHRoaXMuU0xJUF9FU0MgPSAweGRiO1xuICAgICAgICB0aGlzLlNMSVBfRVNDX0VORCA9IDB4ZGM7XG4gICAgICAgIHRoaXMuU0xJUF9FU0NfRVNDID0gMHhkZDtcbiAgICAgICAgdGhpcy5fRFRSX3N0YXRlID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2xpcFJlYWRlckVuYWJsZWQgPSBlbmFibGVTbGlwUmVhZGVyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXF1ZXN0IHRoZSBzZXJpYWwgZGV2aWNlIHZlbmRvciBJRCBhbmQgUHJvZHVjdCBJRCBhcyBzdHJpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJuIHRoZSBkZXZpY2UgVmVuZG9ySUQgYW5kIFByb2R1Y3RJRCBmcm9tIFNlcmlhbFBvcnRJbmZvIGFzIGZvcm1hdHRlZCBzdHJpbmcuXG4gICAgICovXG4gICAgZ2V0SW5mbygpIHtcbiAgICAgICAgY29uc3QgaW5mbyA9IHRoaXMuZGV2aWNlLmdldEluZm8oKTtcbiAgICAgICAgcmV0dXJuIGluZm8udXNiVmVuZG9ySWQgJiYgaW5mby51c2JQcm9kdWN0SWRcbiAgICAgICAgICAgID8gYFdlYlNlcmlhbCBWZW5kb3JJRCAweCR7aW5mby51c2JWZW5kb3JJZC50b1N0cmluZygxNil9IFByb2R1Y3RJRCAweCR7aW5mby51c2JQcm9kdWN0SWQudG9TdHJpbmcoMTYpfWBcbiAgICAgICAgICAgIDogXCJcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVxdWVzdCB0aGUgc2VyaWFsIGRldmljZSBwcm9kdWN0IGlkIGZyb20gU2VyaWFsUG9ydEluZm8uXG4gICAgICogQHJldHVybnMge251bWJlciB8IHVuZGVmaW5lZH0gUmV0dXJuIHRoZSBwcm9kdWN0IElELlxuICAgICAqL1xuICAgIGdldFBpZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGV2aWNlLmdldEluZm8oKS51c2JQcm9kdWN0SWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZvcm1hdCByZWNlaXZlZCBvciBzZW50IGRhdGEgZm9yIHRyYWNpbmcgb3V0cHV0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIE1lc3NhZ2UgdG8gZm9ybWF0IGFzIHRyYWNlIGxpbmUuXG4gICAgICovXG4gICAgdHJhY2UobWVzc2FnZSkge1xuICAgICAgICBjb25zdCBkZWx0YSA9IERhdGUubm93KCkgLSB0aGlzLmxhc3RUcmFjZVRpbWU7XG4gICAgICAgIGNvbnN0IHByZWZpeCA9IGBUUkFDRSAke2RlbHRhLnRvRml4ZWQoMyl9YDtcbiAgICAgICAgY29uc3QgdHJhY2VNZXNzYWdlID0gYCR7cHJlZml4fSAke21lc3NhZ2V9YDtcbiAgICAgICAgY29uc29sZS5sb2codHJhY2VNZXNzYWdlKTtcbiAgICAgICAgdGhpcy50cmFjZUxvZyArPSB0cmFjZU1lc3NhZ2UgKyBcIlxcblwiO1xuICAgIH1cbiAgICBhc3luYyByZXR1cm5UcmFjZSgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHRoaXMudHJhY2VMb2cpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJUZXh0IGNvcGllZCB0byBjbGlwYm9hcmQhXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJGYWlsZWQgdG8gY29weSB0ZXh0OlwiLCBlcnIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGhleGlmeShzKSB7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKHMpXG4gICAgICAgICAgICAubWFwKChieXRlKSA9PiBieXRlLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIikpXG4gICAgICAgICAgICAuam9pbihcIlwiKVxuICAgICAgICAgICAgLnBhZEVuZCgxNiwgXCIgXCIpO1xuICAgIH1cbiAgICBoZXhDb252ZXJ0KHVpbnQ4QXJyYXksIGF1dG9TcGxpdCA9IHRydWUpIHtcbiAgICAgICAgaWYgKGF1dG9TcGxpdCAmJiB1aW50OEFycmF5Lmxlbmd0aCA+IDE2KSB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gXCJcIjtcbiAgICAgICAgICAgIGxldCBzID0gdWludDhBcnJheTtcbiAgICAgICAgICAgIHdoaWxlIChzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lID0gcy5zbGljZSgwLCAxNik7XG4gICAgICAgICAgICAgICAgY29uc3QgYXNjaWlMaW5lID0gU3RyaW5nLmZyb21DaGFyQ29kZSguLi5saW5lKVxuICAgICAgICAgICAgICAgICAgICAuc3BsaXQoXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLm1hcCgoYykgPT4gKGMgPT09IFwiIFwiIHx8IChjID49IFwiIFwiICYmIGMgPD0gXCJ+XCIgJiYgYyAhPT0gXCIgIFwiKSA/IGMgOiBcIi5cIikpXG4gICAgICAgICAgICAgICAgICAgIC5qb2luKFwiXCIpO1xuICAgICAgICAgICAgICAgIHMgPSBzLnNsaWNlKDE2KTtcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gYFxcbiAgICAke3RoaXMuaGV4aWZ5KGxpbmUuc2xpY2UoMCwgOCkpfSAke3RoaXMuaGV4aWZ5KGxpbmUuc2xpY2UoOCkpfSB8ICR7YXNjaWlMaW5lfWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGV4aWZ5KHVpbnQ4QXJyYXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZvcm1hdCBkYXRhIHBhY2tldCB1c2luZyB0aGUgU2VyaWFsIExpbmUgSW50ZXJuZXQgUHJvdG9jb2wgKFNMSVApLlxuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gZGF0YSBCaW5hcnkgdW5zaWduZWQgOCBiaXQgYXJyYXkgZGF0YSB0byBmb3JtYXQuXG4gICAgICogQHJldHVybnMge1VpbnQ4QXJyYXl9IEZvcm1hdHRlZCB1bnNpZ25lZCA4IGJpdCBkYXRhIGFycmF5LlxuICAgICAqL1xuICAgIHNsaXBXcml0ZXIoZGF0YSkge1xuICAgICAgICBjb25zdCBvdXREYXRhID0gW107XG4gICAgICAgIG91dERhdGEucHVzaCgweGMwKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZGF0YVtpXSA9PT0gMHhkYikge1xuICAgICAgICAgICAgICAgIG91dERhdGEucHVzaCgweGRiLCAweGRkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGRhdGFbaV0gPT09IDB4YzApIHtcbiAgICAgICAgICAgICAgICBvdXREYXRhLnB1c2goMHhkYiwgMHhkYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBvdXREYXRhLnB1c2goZGF0YVtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgb3V0RGF0YS5wdXNoKDB4YzApO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkob3V0RGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdyaXRlIGJpbmFyeSBkYXRhIHRvIGRldmljZSB1c2luZyB0aGUgV2ViU2VyaWFsIGRldmljZSB3cml0YWJsZSBzdHJlYW0uXG4gICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBkYXRhIDggYml0IHVuc2lnbmVkIGRhdGEgYXJyYXkgdG8gd3JpdGUgdG8gZGV2aWNlLlxuICAgICAqL1xuICAgIGFzeW5jIHdyaXRlKGRhdGEpIHtcbiAgICAgICAgY29uc3Qgb3V0RGF0YSA9IHRoaXMuc2xpcFdyaXRlcihkYXRhKTtcbiAgICAgICAgaWYgKHRoaXMuZGV2aWNlLndyaXRhYmxlKSB7XG4gICAgICAgICAgICBjb25zdCB3cml0ZXIgPSB0aGlzLmRldmljZS53cml0YWJsZS5nZXRXcml0ZXIoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnRyYWNpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIldyaXRlIGJ5dGVzXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMudHJhY2UoYFdyaXRlICR7b3V0RGF0YS5sZW5ndGh9IGJ5dGVzOiAke3RoaXMuaGV4Q29udmVydChvdXREYXRhKX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHdyaXRlci53cml0ZShvdXREYXRhKTtcbiAgICAgICAgICAgIHdyaXRlci5yZWxlYXNlTG9jaygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFwcGVuZCBhIGJ1ZmZlciBhcnJheSBhZnRlciBhbm90aGVyIGJ1ZmZlciBhcnJheVxuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gYXJyMSAtIEZpcnN0IGFycmF5IGJ1ZmZlci5cbiAgICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGFycjIgLSBtYWdpYyBoZXggbnVtYmVyIHRvIHNlbGVjdCBST00uXG4gICAgICogQHJldHVybnMge1VpbnQ4QXJyYXl9IFJldHVybiBhIDggYml0IHVuc2lnbmVkIGFycmF5LlxuICAgICAqL1xuICAgIGFwcGVuZEFycmF5KGFycjEsIGFycjIpIHtcbiAgICAgICAgY29uc3QgY29tYmluZWQgPSBuZXcgVWludDhBcnJheShhcnIxLmxlbmd0aCArIGFycjIubGVuZ3RoKTtcbiAgICAgICAgY29tYmluZWQuc2V0KGFycjEpO1xuICAgICAgICBjb21iaW5lZC5zZXQoYXJyMiwgYXJyMS5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gY29tYmluZWQ7XG4gICAgfVxuICAgIC8vIEFzeW5jaHJvbm91cyBnZW5lcmF0b3IgdG8geWllbGQgaW5jb21pbmcgZGF0YSBjaHVua3NcbiAgICBhc3luYyAqcmVhZExvb3AodGltZW91dCkge1xuICAgICAgICBpZiAoIXRoaXMucmVhZGVyKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aW1lb3V0UHJvbWlzZSA9IG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+IHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihcIlJlYWQgdGltZW91dCBleGNlZWRlZFwiKSksIHRpbWVvdXQpKTtcbiAgICAgICAgICAgICAgICAvLyBBd2FpdCB0aGUgcmFjZSBiZXR3ZWVuIHRoZSB0aW1lb3V0IGFuZCB0aGUgcmVhZGVyIHJlYWRcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcm9taXNlLnJhY2UoW3RoaXMucmVhZGVyLnJlYWQoKSwgdGltZW91dFByb21pc2VdKTtcbiAgICAgICAgICAgICAgICAvLyBJZiBhIHRpbWVvdXQgb2NjdXJzLCByZXN1bHQgd2lsbCBiZSBudWxsOyBvdGhlcndpc2UsIGl0IHdpbGwgaGF2ZSB7IHZhbHVlLCBkb25lIH1cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjb25zdCB7IHZhbHVlLCBkb25lIH0gPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgaWYgKGRvbmUgfHwgIXZhbHVlKVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB5aWVsZCB2YWx1ZTsgLy8gWWllbGQgZWFjaCBkYXRhIGNodW5rXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgcmVhZGluZyBmcm9tIHNlcmlhbCBwb3J0OlwiLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDApO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIFJlYWQgYSBzcGVjaWZpYyBudW1iZXIgb2YgYnl0ZXNcbiAgICBhc3luYyBuZXdSZWFkKG51bUJ5dGVzLCB0aW1lb3V0KSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sZW5ndGggPj0gbnVtQnl0ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dCA9IHRoaXMuYnVmZmVyLnNsaWNlKDAsIG51bUJ5dGVzKTtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gdGhpcy5idWZmZXIuc2xpY2UobnVtQnl0ZXMpOyAvLyBSZW1vdmUgdGhlIHJldHVybmVkIGRhdGEgZnJvbSBidWZmZXJcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHRoaXMuYnVmZmVyLmxlbmd0aCA8IG51bUJ5dGVzKSB7XG4gICAgICAgICAgICBjb25zdCByZWFkTG9vcCA9IHRoaXMucmVhZExvb3AodGltZW91dCk7XG4gICAgICAgICAgICBjb25zdCB7IHZhbHVlLCBkb25lIH0gPSBhd2FpdCByZWFkTG9vcC5uZXh0KCk7XG4gICAgICAgICAgICBpZiAoZG9uZSB8fCAhdmFsdWUpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFwcGVuZCB0aGUgbmV3bHkgcmVhZCBkYXRhIHRvIHRoZSBidWZmZXJcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gdGhpcy5hcHBlbmRBcnJheSh0aGlzLmJ1ZmZlciwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJldHVybiBhcyBtdWNoIGRhdGEgYXMgcG9zc2libGVcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gdGhpcy5idWZmZXIuc2xpY2UoMCwgbnVtQnl0ZXMpO1xuICAgICAgICB0aGlzLmJ1ZmZlciA9IHRoaXMuYnVmZmVyLnNsaWNlKG51bUJ5dGVzKTtcbiAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9XG4gICAgYXN5bmMgZmx1c2hJbnB1dCgpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBpZiAodGhpcy5yZWFkZXIgJiYgIShhd2FpdCB0aGlzLnJlYWRlci5jbG9zZWQpKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlYWRlci5jYW5jZWwoKTtcbiAgICAgICAgICAgIHRoaXMucmVhZGVyLnJlbGVhc2VMb2NrKCk7XG4gICAgICAgICAgICB0aGlzLnJlYWRlciA9IChfYSA9IHRoaXMuZGV2aWNlLnJlYWRhYmxlKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZ2V0UmVhZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgZmx1c2hPdXRwdXQoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMCk7XG4gICAgICAgIGF3YWl0ICgoX2EgPSB0aGlzLmRldmljZS53cml0YWJsZSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFdyaXRlcigpLmNsb3NlKCkpO1xuICAgICAgICAoX2IgPSB0aGlzLmRldmljZS53cml0YWJsZSkgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmdldFdyaXRlcigpLnJlbGVhc2VMb2NrKCk7XG4gICAgfVxuICAgIC8vIGBpbldhaXRpbmdgIHJldHVybnMgdGhlIGNvdW50IG9mIGJ5dGVzIGluIHRoZSBidWZmZXJcbiAgICBpbldhaXRpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERldGVjdCBpZiB0aGUgZGF0YSByZWFkIGZyb20gZGV2aWNlIGlzIGEgRmF0YWwgb3IgR3VydSBtZWRpdGF0aW9uIGVycm9yLlxuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gaW5wdXQgRGF0YSByZWFkIGZyb20gZGV2aWNlXG4gICAgICovXG4gICAgZGV0ZWN0UGFuaWNIYW5kbGVyKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IGd1cnVNZWRpdGF0aW9uUmVnZXggPSAvRz91cnUgTWVkaXRhdGlvbiBFcnJvcjogKD86Q29yZSBcXGQgcGFuaWMnZWQgXFwoKFthLXpBLVogXSopXFwpKT8vO1xuICAgICAgICBjb25zdCBmYXRhbEV4Y2VwdGlvblJlZ2V4ID0gL0Y/YXRhbCBleGNlcHRpb24gXFwoXFxkK1xcKTogKD86KFthLXpBLVogXSopPy4qZXBjKT8vO1xuICAgICAgICBjb25zdCBpbnB1dFN0cmluZyA9IG5ldyBUZXh0RGVjb2RlcihcInV0Zi04XCIpLmRlY29kZShpbnB1dCk7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gaW5wdXRTdHJpbmcubWF0Y2goZ3VydU1lZGl0YXRpb25SZWdleCkgfHwgaW5wdXRTdHJpbmcubWF0Y2goZmF0YWxFeGNlcHRpb25SZWdleCk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgY29uc3QgY2F1c2UgPSBtYXRjaFsxXSB8fCBtYXRjaFsyXTtcbiAgICAgICAgICAgIGNvbnN0IG1zZyA9IGBHdXJ1IE1lZGl0YXRpb24gRXJyb3IgZGV0ZWN0ZWQke2NhdXNlID8gYCAoJHtjYXVzZX0pYCA6IFwiXCJ9YDtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRha2UgYSBkYXRhIGFycmF5IGFuZCByZXR1cm4gdGhlIGZpcnN0IHdlbGwgZm9ybWVkIHBhY2tldCBhZnRlclxuICAgICAqIHJlcGxhY2luZyB0aGUgZXNjYXBlIHNlcXVlbmNlLiBSZWFkcyBhdCBsZWFzdCA4IGJ5dGVzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0IFRpbWVvdXQgcmVhZCBkYXRhLlxuICAgICAqIEB5aWVsZHMge1VpbnQ4QXJyYXl9IEZvcm1hdHRlZCBwYWNrZXQgdXNpbmcgU0xJUCBlc2NhcGUgc2VxdWVuY2VzLlxuICAgICAqL1xuICAgIGFzeW5jICpyZWFkKHRpbWVvdXQpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICBpZiAoIXRoaXMucmVhZGVyKSB7XG4gICAgICAgICAgICB0aGlzLnJlYWRlciA9IChfYSA9IHRoaXMuZGV2aWNlLnJlYWRhYmxlKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZ2V0UmVhZGVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBhcnRpYWxQYWNrZXQgPSBudWxsO1xuICAgICAgICBsZXQgaXNFc2NhcGluZyA9IGZhbHNlO1xuICAgICAgICBsZXQgc3VjY2Vzc2Z1bFNsaXAgPSBmYWxzZTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdhaXRpbmdCeXRlcyA9IHRoaXMuaW5XYWl0aW5nKCk7XG4gICAgICAgICAgICBjb25zdCByZWFkQnl0ZXMgPSBhd2FpdCB0aGlzLm5ld1JlYWQod2FpdGluZ0J5dGVzID4gMCA/IHdhaXRpbmdCeXRlcyA6IDEsIHRpbWVvdXQpO1xuICAgICAgICAgICAgaWYgKCFyZWFkQnl0ZXMgfHwgcmVhZEJ5dGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1zZyA9IHBhcnRpYWxQYWNrZXQgPT09IG51bGxcbiAgICAgICAgICAgICAgICAgICAgPyBzdWNjZXNzZnVsU2xpcFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBcIlNlcmlhbCBkYXRhIHN0cmVhbSBzdG9wcGVkOiBQb3NzaWJsZSBzZXJpYWwgbm9pc2Ugb3IgY29ycnVwdGlvbi5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgOiBcIk5vIHNlcmlhbCBkYXRhIHJlY2VpdmVkLlwiXG4gICAgICAgICAgICAgICAgICAgIDogYFBhY2tldCBjb250ZW50IHRyYW5zZmVyIHN0b3BwZWRgO1xuICAgICAgICAgICAgICAgIHRoaXMudHJhY2UobXNnKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudHJhY2UoYFJlYWQgJHtyZWFkQnl0ZXMubGVuZ3RofSBieXRlczogJHt0aGlzLmhleENvbnZlcnQocmVhZEJ5dGVzKX1gKTtcbiAgICAgICAgICAgIGxldCBpID0gMDsgLy8gVHJhY2sgcG9zaXRpb24gaW4gcmVhZEJ5dGVzXG4gICAgICAgICAgICB3aGlsZSAoaSA8IHJlYWRCeXRlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBieXRlID0gcmVhZEJ5dGVzW2krK107XG4gICAgICAgICAgICAgICAgaWYgKHBhcnRpYWxQYWNrZXQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJ5dGUgPT09IHRoaXMuU0xJUF9FTkQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxQYWNrZXQgPSBuZXcgVWludDhBcnJheSgwKTsgLy8gU3RhcnQgb2YgYSBuZXcgcGFja2V0XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYWNlKGBSZWFkIGludmFsaWQgZGF0YTogJHt0aGlzLmhleENvbnZlcnQocmVhZEJ5dGVzKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ0RhdGEgPSBhd2FpdCB0aGlzLm5ld1JlYWQodGhpcy5pbldhaXRpbmcoKSwgdGltZW91dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyYWNlKGBSZW1haW5pbmcgZGF0YSBpbiBzZXJpYWwgYnVmZmVyOiAke3RoaXMuaGV4Q29udmVydChyZW1haW5pbmdEYXRhKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGV0ZWN0UGFuaWNIYW5kbGVyKG5ldyBVaW50OEFycmF5KFsuLi5yZWFkQnl0ZXMsIC4uLihyZW1haW5pbmdEYXRhIHx8IFtdKV0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBoZWFkIG9mIHBhY2tldCAoMHgke2J5dGUudG9TdHJpbmcoMTYpfSk6IFBvc3NpYmxlIHNlcmlhbCBub2lzZSBvciBjb3JydXB0aW9uLmApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzRXNjYXBpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgaXNFc2NhcGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYnl0ZSA9PT0gdGhpcy5TTElQX0VTQ19FTkQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxQYWNrZXQgPSB0aGlzLmFwcGVuZEFycmF5KHBhcnRpYWxQYWNrZXQsIG5ldyBVaW50OEFycmF5KFt0aGlzLlNMSVBfRU5EXSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJ5dGUgPT09IHRoaXMuU0xJUF9FU0NfRVNDKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsUGFja2V0ID0gdGhpcy5hcHBlbmRBcnJheShwYXJ0aWFsUGFja2V0LCBuZXcgVWludDhBcnJheShbdGhpcy5TTElQX0VTQ10pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhY2UoYFJlYWQgaW52YWxpZCBkYXRhOiAke3RoaXMuaGV4Q29udmVydChyZWFkQnl0ZXMpfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nRGF0YSA9IGF3YWl0IHRoaXMubmV3UmVhZCh0aGlzLmluV2FpdGluZygpLCB0aW1lb3V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhY2UoYFJlbWFpbmluZyBkYXRhIGluIHNlcmlhbCBidWZmZXI6ICR7dGhpcy5oZXhDb252ZXJ0KHJlbWFpbmluZ0RhdGEpfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXRlY3RQYW5pY0hhbmRsZXIobmV3IFVpbnQ4QXJyYXkoWy4uLnJlYWRCeXRlcywgLi4uKHJlbWFpbmluZ0RhdGEgfHwgW10pXSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIFNMSVAgZXNjYXBlICgweGRiLCAweCR7Ynl0ZS50b1N0cmluZygxNil9KWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJ5dGUgPT09IHRoaXMuU0xJUF9FU0MpIHtcbiAgICAgICAgICAgICAgICAgICAgaXNFc2NhcGluZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJ5dGUgPT09IHRoaXMuU0xJUF9FTkQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFjZShgUmVjZWl2ZWQgZnVsbCBwYWNrZXQ6ICR7dGhpcy5oZXhDb252ZXJ0KHBhcnRpYWxQYWNrZXQpfWApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IHRoaXMuYXBwZW5kQXJyYXkodGhpcy5idWZmZXIsIHJlYWRCeXRlcy5zbGljZShpKSk7XG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIHBhcnRpYWxQYWNrZXQ7XG4gICAgICAgICAgICAgICAgICAgIHBhcnRpYWxQYWNrZXQgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzZnVsU2xpcCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsUGFja2V0ID0gdGhpcy5hcHBlbmRBcnJheShwYXJ0aWFsUGFja2V0LCBuZXcgVWludDhBcnJheShbYnl0ZV0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCBmcm9tIHNlcmlhbCBkZXZpY2Ugd2l0aG91dCBzbGlwIGZvcm1hdHRpbmcuXG4gICAgICogQHlpZWxkcyB7VWludDhBcnJheX0gVGhlIG5leHQgbnVtYmVyIGluIHRoZSBGaWJvbmFjY2kgc2VxdWVuY2UuXG4gICAgICovXG4gICAgYXN5bmMgKnJhd1JlYWQoKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IGF3YWl0IHRoaXMucmVhZGVyLnJlYWQoKTtcbiAgICAgICAgICAgICAgICBpZiAoZG9uZSB8fCAhdmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyYWNpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJSYXcgUmVhZCBieXRlc1wiKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFjZShgUmVhZCAke3ZhbHVlLmxlbmd0aH0gYnl0ZXM6ICR7dGhpcy5oZXhDb252ZXJ0KHZhbHVlKX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgeWllbGQgdmFsdWU7IC8vIFlpZWxkIGVhY2ggZGF0YSBjaHVua1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHJlYWRpbmcgZnJvbSBzZXJpYWwgcG9ydDpcIiwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgVWludDhBcnJheSgwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZW5kIHRoZSBSZXF1ZXN0VG9TZW5kIChSVFMpIHNpZ25hbCB0byBnaXZlbiBzdGF0ZVxuICAgICAqICMgVHJ1ZSBmb3IgRU49TE9XLCBjaGlwIGluIHJlc2V0IGFuZCBGYWxzZSBFTj1ISUdILCBjaGlwIG91dCBvZiByZXNldFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gc3RhdGUgQm9vbGVhbiBzdGF0ZSB0byBzZXQgdGhlIHNpZ25hbFxuICAgICAqL1xuICAgIGFzeW5jIHNldFJUUyhzdGF0ZSkge1xuICAgICAgICBhd2FpdCB0aGlzLmRldmljZS5zZXRTaWduYWxzKHsgcmVxdWVzdFRvU2VuZDogc3RhdGUgfSk7XG4gICAgICAgIC8vICMgV29yay1hcm91bmQgZm9yIGFkYXB0ZXJzIG9uIFdpbmRvd3MgdXNpbmcgdGhlIHVzYnNlci5zeXMgZHJpdmVyOlxuICAgICAgICAvLyAjIGdlbmVyYXRlIGEgZHVtbXkgY2hhbmdlIHRvIERUUiBzbyB0aGF0IHRoZSBzZXQtY29udHJvbC1saW5lLXN0YXRlXG4gICAgICAgIC8vICMgcmVxdWVzdCBpcyBzZW50IHdpdGggdGhlIHVwZGF0ZWQgUlRTIHN0YXRlIGFuZCB0aGUgc2FtZSBEVFIgc3RhdGVcbiAgICAgICAgLy8gUmVmZXJlbmNlZCB0byBlc3B0b29sLnB5XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0RFRSKHRoaXMuX0RUUl9zdGF0ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlbmQgdGhlIGRhdGFUZXJtaW5hbFJlYWR5IChEVFMpIHNpZ25hbCB0byBnaXZlbiBzdGF0ZVxuICAgICAqICMgVHJ1ZSBmb3IgSU8wPUxPVywgY2hpcCBpbiByZXNldCBhbmQgRmFsc2UgSU8wPUhJR0hcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHN0YXRlIEJvb2xlYW4gc3RhdGUgdG8gc2V0IHRoZSBzaWduYWxcbiAgICAgKi9cbiAgICBhc3luYyBzZXREVFIoc3RhdGUpIHtcbiAgICAgICAgdGhpcy5fRFRSX3N0YXRlID0gc3RhdGU7XG4gICAgICAgIGF3YWl0IHRoaXMuZGV2aWNlLnNldFNpZ25hbHMoeyBkYXRhVGVybWluYWxSZWFkeTogc3RhdGUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdG8gc2VyaWFsIGRldmljZSB1c2luZyB0aGUgV2Vic2VyaWFsIG9wZW4gbWV0aG9kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiYXVkIE51bWJlciBiYXVkIHJhdGUgZm9yIHNlcmlhbCBjb25uZWN0aW9uLiBEZWZhdWx0IGlzIDExNTIwMC5cbiAgICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCJ3M2Mtd2ViLXNlcmlhbFwiKS5TZXJpYWxPcHRpb25zfSBzZXJpYWxPcHRpb25zIFNlcmlhbCBPcHRpb25zIGZvciBXZWJVU0IgU2VyaWFsUG9ydCBjbGFzcy5cbiAgICAgKi9cbiAgICBhc3luYyBjb25uZWN0KGJhdWQgPSAxMTUyMDAsIHNlcmlhbE9wdGlvbnMgPSB7fSkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGF3YWl0IHRoaXMuZGV2aWNlLm9wZW4oe1xuICAgICAgICAgICAgYmF1ZFJhdGU6IGJhdWQsXG4gICAgICAgICAgICBkYXRhQml0czogc2VyaWFsT3B0aW9ucyA9PT0gbnVsbCB8fCBzZXJpYWxPcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBzZXJpYWxPcHRpb25zLmRhdGFCaXRzLFxuICAgICAgICAgICAgc3RvcEJpdHM6IHNlcmlhbE9wdGlvbnMgPT09IG51bGwgfHwgc2VyaWFsT3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogc2VyaWFsT3B0aW9ucy5zdG9wQml0cyxcbiAgICAgICAgICAgIGJ1ZmZlclNpemU6IHNlcmlhbE9wdGlvbnMgPT09IG51bGwgfHwgc2VyaWFsT3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogc2VyaWFsT3B0aW9ucy5idWZmZXJTaXplLFxuICAgICAgICAgICAgcGFyaXR5OiBzZXJpYWxPcHRpb25zID09PSBudWxsIHx8IHNlcmlhbE9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHNlcmlhbE9wdGlvbnMucGFyaXR5LFxuICAgICAgICAgICAgZmxvd0NvbnRyb2w6IHNlcmlhbE9wdGlvbnMgPT09IG51bGwgfHwgc2VyaWFsT3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogc2VyaWFsT3B0aW9ucy5mbG93Q29udHJvbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYmF1ZHJhdGUgPSBiYXVkO1xuICAgICAgICB0aGlzLnJlYWRlciA9IChfYSA9IHRoaXMuZGV2aWNlLnJlYWRhYmxlKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EuZ2V0UmVhZGVyKCk7XG4gICAgfVxuICAgIGFzeW5jIHNsZWVwKG1zKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXYWl0IGZvciBhIGdpdmVuIHRpbWVvdXQgbXMgZm9yIHNlcmlhbCBkZXZpY2UgdW5sb2NrLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0IFRpbWVvdXQgdGltZSBpbiBtaWxsaXNlY29uZHMgKG1zKSB0byBzbGVlcFxuICAgICAqL1xuICAgIGFzeW5jIHdhaXRGb3JVbmxvY2sodGltZW91dCkge1xuICAgICAgICB3aGlsZSAoKHRoaXMuZGV2aWNlLnJlYWRhYmxlICYmIHRoaXMuZGV2aWNlLnJlYWRhYmxlLmxvY2tlZCkgfHxcbiAgICAgICAgICAgICh0aGlzLmRldmljZS53cml0YWJsZSAmJiB0aGlzLmRldmljZS53cml0YWJsZS5sb2NrZWQpKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNsZWVwKHRpbWVvdXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERpc2Nvbm5lY3QgZnJvbSBzZXJpYWwgZGV2aWNlIGJ5IHJ1bm5pbmcgU2VyaWFsUG9ydC5jbG9zZSgpIGFmdGVyIHN0cmVhbXMgdW5sb2NrLlxuICAgICAqL1xuICAgIGFzeW5jIGRpc2Nvbm5lY3QoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIGlmICgoX2EgPSB0aGlzLmRldmljZS5yZWFkYWJsZSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmxvY2tlZCkge1xuICAgICAgICAgICAgYXdhaXQgKChfYiA9IHRoaXMucmVhZGVyKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2IuY2FuY2VsKCkpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvclVubG9jayg0MDApO1xuICAgICAgICBhd2FpdCB0aGlzLmRldmljZS5jbG9zZSgpO1xuICAgICAgICB0aGlzLnJlYWRlciA9IHVuZGVmaW5lZDtcbiAgICB9XG59XG5leHBvcnQgeyBUcmFuc3BvcnQgfTtcbiIsImV4cG9ydCBjb25zdCBTRVJJQUxfUEFDS0VUX0hFQURFUiA9IFtcbiAgICBcIklcIi5jaGFyQ29kZUF0KDApLFxuICAgIFwiTVwiLmNoYXJDb2RlQXQoMCksXG4gICAgXCJQXCIuY2hhckNvZGVBdCgwKSxcbiAgICBcIlJcIi5jaGFyQ29kZUF0KDApLFxuICAgIFwiT1wiLmNoYXJDb2RlQXQoMCksXG4gICAgXCJWXCIuY2hhckNvZGVBdCgwKSxcbiAgICAxLCAvLyBwcm90b2NvbCB2ZXJzaW9uXG5dO1xuZXhwb3J0IHZhciBJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZTtcbihmdW5jdGlvbiAoSW1wcm92U2VyaWFsTWVzc2FnZVR5cGUpIHtcbiAgICBJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZVtJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZVtcIkNVUlJFTlRfU1RBVEVcIl0gPSAxXSA9IFwiQ1VSUkVOVF9TVEFURVwiO1xuICAgIEltcHJvdlNlcmlhbE1lc3NhZ2VUeXBlW0ltcHJvdlNlcmlhbE1lc3NhZ2VUeXBlW1wiRVJST1JfU1RBVEVcIl0gPSAyXSA9IFwiRVJST1JfU1RBVEVcIjtcbiAgICBJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZVtJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZVtcIlJQQ1wiXSA9IDNdID0gXCJSUENcIjtcbiAgICBJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZVtJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZVtcIlJQQ19SRVNVTFRcIl0gPSA0XSA9IFwiUlBDX1JFU1VMVFwiO1xufSkoSW1wcm92U2VyaWFsTWVzc2FnZVR5cGUgfHwgKEltcHJvdlNlcmlhbE1lc3NhZ2VUeXBlID0ge30pKTtcbmV4cG9ydCB2YXIgSW1wcm92U2VyaWFsQ3VycmVudFN0YXRlO1xuKGZ1bmN0aW9uIChJbXByb3ZTZXJpYWxDdXJyZW50U3RhdGUpIHtcbiAgICBJbXByb3ZTZXJpYWxDdXJyZW50U3RhdGVbSW1wcm92U2VyaWFsQ3VycmVudFN0YXRlW1wiUkVBRFlcIl0gPSAyXSA9IFwiUkVBRFlcIjtcbiAgICBJbXByb3ZTZXJpYWxDdXJyZW50U3RhdGVbSW1wcm92U2VyaWFsQ3VycmVudFN0YXRlW1wiUFJPVklTSU9OSU5HXCJdID0gM10gPSBcIlBST1ZJU0lPTklOR1wiO1xuICAgIEltcHJvdlNlcmlhbEN1cnJlbnRTdGF0ZVtJbXByb3ZTZXJpYWxDdXJyZW50U3RhdGVbXCJQUk9WSVNJT05FRFwiXSA9IDRdID0gXCJQUk9WSVNJT05FRFwiO1xufSkoSW1wcm92U2VyaWFsQ3VycmVudFN0YXRlIHx8IChJbXByb3ZTZXJpYWxDdXJyZW50U3RhdGUgPSB7fSkpO1xuZXhwb3J0IGNvbnN0IEVSUk9SX01TR1MgPSB7XG4gICAgMHgwMDogXCJOT19FUlJPUlwiLFxuICAgIDB4MDE6IFwiSU5WQUxJRF9SUENfUEFDS0VUXCIsXG4gICAgMHgwMjogXCJVTktOT1dOX1JQQ19DT01NQU5EXCIsXG4gICAgMHgwMzogXCJVTkFCTEVfVE9fQ09OTkVDVFwiLFxuICAgIDB4ZmU6IFwiVElNRU9VVFwiLFxuICAgIDB4ZmY6IFwiVU5LTk9XTl9FUlJPUlwiLFxufTtcbmV4cG9ydCBjbGFzcyBQb3J0Tm90UmVhZHkgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKFwiUG9ydCBpcyBub3QgcmVhZHlcIik7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgRVJST1JfTVNHUywgSW1wcm92U2VyaWFsQ3VycmVudFN0YXRlLCBJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZSwgUG9ydE5vdFJlYWR5LCBTRVJJQUxfUEFDS0VUX0hFQURFUiwgfSBmcm9tIFwiLi9jb25zdC5qc1wiO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tIFwiLi91dGlsL3NsZWVwXCI7XG5pbXBvcnQgeyBoZXhGb3JtYXR0ZXIgfSBmcm9tIFwiLi91dGlsL2hleC1mb3JtYXR0ZXJcIjtcbmV4cG9ydCBjbGFzcyBJbXByb3ZTZXJpYWwgZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gICAgY29uc3RydWN0b3IocG9ydCwgbG9nZ2VyKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucG9ydCA9IHBvcnQ7XG4gICAgICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyO1xuICAgICAgICB0aGlzLmVycm9yID0gMCAvKiBJbXByb3ZTZXJpYWxFcnJvclN0YXRlLk5PX0VSUk9SICovO1xuICAgICAgICBpZiAocG9ydC5yZWFkYWJsZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUG9ydCBpcyBub3QgcmVhZGFibGVcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvcnQud3JpdGFibGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlBvcnQgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERldGVjdCBJbXByb3YgU2VyaWFsLCBmZXRjaCB0aGUgc3RhdGUgYW5kIHJldHVybiB0aGUgbmV4dCBVUkwgaWYgcHJvdmlzaW9uZWQuXG4gICAgICogQHBhcmFtIHRpbWVvdXQgVGltZW91dCBpbiBtcyB0byB3YWl0IGZvciB0aGUgZGV2aWNlIHRvIHJlc3BvbmQuIERlZmF1bHQgdG8gMTAwMG1zLlxuICAgICAqL1xuICAgIGFzeW5jIGluaXRpYWxpemUodGltZW91dCA9IDEwMDApIHtcbiAgICAgICAgdGhpcy5sb2dnZXIubG9nKFwiSW5pdGlhbGl6aW5nIEltcHJvdiBTZXJpYWxcIik7XG4gICAgICAgIHRoaXMuX3Byb2Nlc3NJbnB1dCgpO1xuICAgICAgICAvLyBUbyBnaXZlIHRoZSBpbnB1dCBwcm9jZXNzaW5nIHRpbWUgdG8gc3RhcnQuXG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuICAgICAgICBpZiAodGhpcy5fcmVhZGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQb3J0Tm90UmVhZHkoKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihcIkltcHJvdiBXaS1GaSBTZXJpYWwgbm90IGRldGVjdGVkXCIpKSwgdGltZW91dCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0Q3VycmVudFN0YXRlKCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlcXVlc3RJbmZvKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmluZm87XG4gICAgfVxuICAgIGFzeW5jIGNsb3NlKCkge1xuICAgICAgICBpZiAoIXRoaXMuX3JlYWRlcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9yZWFkZXIuY2FuY2VsKCk7XG4gICAgICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoXCJkaXNjb25uZWN0XCIsIHJlc29sdmUsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoaXMgY29tbWFuZCB3aWxsIHRyaWdnZXIgYXQgbGVhc3Qgb25lIHBhY2tldCxcbiAgICAgKiB0aGUgQ3VycmVudCBTdGF0ZSBhbmQgaWYgYWxyZWFkeSBwcm92aXNpb25lZCxcbiAgICAgKiB0aGUgc2FtZSByZXNwb25zZSB5b3Ugd291bGQgZ2V0IGlmIGRldmljZSBwcm92aXNpb25pbmdcbiAgICAgKiB3YXMgc3VjY2Vzc2Z1bCAoc2VlIGJlbG93KS5cbiAgICAgKi9cbiAgICBhc3luYyByZXF1ZXN0Q3VycmVudFN0YXRlKCkge1xuICAgICAgICAvLyBSZXF1ZXN0IGN1cnJlbnQgc3RhdGUgYW5kIHdhaXQgZm9yIDVzXG4gICAgICAgIGxldCBycGNSZXN1bHQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKFwic3RhdGUtY2hhbmdlZFwiLCByZXNvbHZlLCB7IG9uY2U6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgY2xlYW51cEFuZFJlamVjdCA9IChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKFwic3RhdGUtY2hhbmdlZFwiLCByZXNvbHZlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBycGNSZXN1bHQgPSB0aGlzLl9zZW5kUlBDV2l0aFJlc3BvbnNlKDIgLyogSW1wcm92U2VyaWFsUlBDQ29tbWFuZC5SRVFVRVNUX0NVUlJFTlRfU1RBVEUgKi8sIFtdKTtcbiAgICAgICAgICAgICAgICBycGNSZXN1bHQuY2F0Y2goY2xlYW51cEFuZFJlamVjdCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLl9ycGNGZWVkYmFjayA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZmV0Y2hpbmcgY3VycmVudCBzdGF0ZTogJHtlcnJ9YCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT25seSBpZiB3ZSBhcmUgcHJvdmlzaW9uZWQgd2lsbCB3ZSBnZXQgYW4gcnBjIHJlc3VsdFxuICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gSW1wcm92U2VyaWFsQ3VycmVudFN0YXRlLlBST1ZJU0lPTkVEKSB7XG4gICAgICAgICAgICB0aGlzLl9ycGNGZWVkYmFjayA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgcnBjUmVzdWx0O1xuICAgICAgICB0aGlzLm5leHRVcmwgPSBkYXRhWzBdO1xuICAgIH1cbiAgICBhc3luYyByZXF1ZXN0SW5mbyh0aW1lb3V0KSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZFJQQ1dpdGhSZXNwb25zZSgzIC8qIEltcHJvdlNlcmlhbFJQQ0NvbW1hbmQuUkVRVUVTVF9JTkZPICovLCBbXSwgdGltZW91dCk7XG4gICAgICAgIHRoaXMuaW5mbyA9IHtcbiAgICAgICAgICAgIGZpcm13YXJlOiByZXNwb25zZVswXSxcbiAgICAgICAgICAgIHZlcnNpb246IHJlc3BvbnNlWzFdLFxuICAgICAgICAgICAgbmFtZTogcmVzcG9uc2VbM10sXG4gICAgICAgICAgICBjaGlwRmFtaWx5OiByZXNwb25zZVsyXSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgcHJvdmlzaW9uKHNzaWQsIHBhc3N3b3JkLCB0aW1lb3V0KSB7XG4gICAgICAgIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICAgICAgY29uc3Qgc3NpZEVuY29kZWQgPSBlbmNvZGVyLmVuY29kZShzc2lkKTtcbiAgICAgICAgY29uc3QgcHdFbmNvZGVkID0gZW5jb2Rlci5lbmNvZGUocGFzc3dvcmQpO1xuICAgICAgICBjb25zdCBkYXRhID0gW1xuICAgICAgICAgICAgc3NpZEVuY29kZWQubGVuZ3RoLFxuICAgICAgICAgICAgLi4uc3NpZEVuY29kZWQsXG4gICAgICAgICAgICBwd0VuY29kZWQubGVuZ3RoLFxuICAgICAgICAgICAgLi4ucHdFbmNvZGVkLFxuICAgICAgICBdO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmRSUENXaXRoUmVzcG9uc2UoMSAvKiBJbXByb3ZTZXJpYWxSUENDb21tYW5kLlNFTkRfV0lGSV9TRVRUSU5HUyAqLywgZGF0YSwgdGltZW91dCk7XG4gICAgICAgIHRoaXMubmV4dFVybCA9IHJlc3BvbnNlWzBdO1xuICAgIH1cbiAgICBhc3luYyBzY2FuKCkge1xuICAgICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5fc2VuZFJQQ1dpdGhNdWx0aXBsZVJlc3BvbnNlcyg0IC8qIEltcHJvdlNlcmlhbFJQQ0NvbW1hbmQuUkVRVUVTVF9XSUZJX05FVFdPUktTICovLCBbXSk7XG4gICAgICAgIGNvbnN0IHNzaWRzID0gcmVzdWx0cy5tYXAoKFtuYW1lLCByc3NpLCBzZWN1cmVkXSkgPT4gKHtcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICByc3NpOiBwYXJzZUludChyc3NpKSxcbiAgICAgICAgICAgIHNlY3VyZWQ6IHNlY3VyZWQgPT09IFwiWUVTXCIsXG4gICAgICAgIH0pKTtcbiAgICAgICAgc3NpZHMuc29ydCgoYSwgYikgPT4gYS5uYW1lLnRvTG9jYWxlTG93ZXJDYXNlKCkubG9jYWxlQ29tcGFyZShiLm5hbWUudG9Mb2NhbGVMb3dlckNhc2UoKSkpO1xuICAgICAgICByZXR1cm4gc3NpZHM7XG4gICAgfVxuICAgIF9zZW5kUlBDKGNvbW1hbmQsIGRhdGEpIHtcbiAgICAgICAgdGhpcy53cml0ZVBhY2tldFRvU3RyZWFtKEltcHJvdlNlcmlhbE1lc3NhZ2VUeXBlLlJQQywgW1xuICAgICAgICAgICAgY29tbWFuZCxcbiAgICAgICAgICAgIGRhdGEubGVuZ3RoLFxuICAgICAgICAgICAgLi4uZGF0YSxcbiAgICAgICAgXSk7XG4gICAgfVxuICAgIGFzeW5jIF9zZW5kUlBDV2l0aFJlc3BvbnNlKGNvbW1hbmQsIGRhdGEsIHRpbWVvdXQpIHtcbiAgICAgICAgLy8gQ29tbWFuZHMgdGhhdCByZWNlaXZlIGZlZWRiYWNrIHdpbGwgZmluaXNoIHdoZW4gZWl0aGVyXG4gICAgICAgIC8vIHRoZSBzdGF0ZSBjaGFuZ2VzIG9yIHRoZSBlcnJvciBjb2RlIGJlY29tZXMgbm90IDAuXG4gICAgICAgIGlmICh0aGlzLl9ycGNGZWVkYmFjaykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiT25seSAxIFJQQyBjb21tYW5kIHRoYXQgcmVxdWlyZXMgZmVlZGJhY2sgY2FuIGJlIGFjdGl2ZVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fYXdhaXRSUENSZXN1bHRXaXRoVGltZW91dChuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9ycGNGZWVkYmFjayA9IHsgY29tbWFuZCwgcmVzb2x2ZSwgcmVqZWN0IH07XG4gICAgICAgICAgICB0aGlzLl9zZW5kUlBDKGNvbW1hbmQsIGRhdGEpO1xuICAgICAgICB9KSwgdGltZW91dCk7XG4gICAgfVxuICAgIGFzeW5jIF9zZW5kUlBDV2l0aE11bHRpcGxlUmVzcG9uc2VzKGNvbW1hbmQsIGRhdGEsIHRpbWVvdXQpIHtcbiAgICAgICAgLy8gQ29tbWFuZHMgdGhhdCByZWNlaXZlIG11bHRpcGxlIGZlZWRiYWNrcyB3aWxsIGZpbmlzaCB3aGVuIGVpdGhlclxuICAgICAgICAvLyB0aGUgc3RhdGUgY2hhbmdlcyBvciB0aGUgZXJyb3IgY29kZSBiZWNvbWVzIG5vdCAwLlxuICAgICAgICBpZiAodGhpcy5fcnBjRmVlZGJhY2spIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk9ubHkgMSBSUEMgY29tbWFuZCB0aGF0IHJlcXVpcmVzIGZlZWRiYWNrIGNhbiBiZSBhY3RpdmVcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX2F3YWl0UlBDUmVzdWx0V2l0aFRpbWVvdXQobmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcnBjRmVlZGJhY2sgPSB7XG4gICAgICAgICAgICAgICAgY29tbWFuZCxcbiAgICAgICAgICAgICAgICByZXNvbHZlLFxuICAgICAgICAgICAgICAgIHJlamVjdCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZERhdGE6IFtdLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuX3NlbmRSUEMoY29tbWFuZCwgZGF0YSk7XG4gICAgICAgIH0pLCB0aW1lb3V0KTtcbiAgICB9XG4gICAgYXN5bmMgX2F3YWl0UlBDUmVzdWx0V2l0aFRpbWVvdXQoc2VuZFJQQ1Byb21pc2UsIHRpbWVvdXQpIHtcbiAgICAgICAgaWYgKCF0aW1lb3V0KSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgc2VuZFJQQ1Byb21pc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRpbWVvdXRSUEMgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX3NldEVycm9yKDI1NCAvKiBJbXByb3ZTZXJpYWxFcnJvclN0YXRlLlRJTUVPVVQgKi8pLCB0aW1lb3V0KTtcbiAgICAgICAgICAgIHNlbmRSUENQcm9taXNlLmZpbmFsbHkoKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVvdXRSUEMpKTtcbiAgICAgICAgICAgIHNlbmRSUENQcm9taXNlLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGFzeW5jIF9wcm9jZXNzSW5wdXQoKSB7XG4gICAgICAgIC8vIHJlYWQgdGhlIGRhdGEgZnJvbSBzZXJpYWwgcG9ydC5cbiAgICAgICAgLy8gY3VycmVudCBzdGF0ZSwgZXJyb3Igc3RhdGUsIHJwYyByZXN1bHRcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXCJTdGFydGluZyByZWFkIGxvb3BcIik7XG4gICAgICAgIHRoaXMuX3JlYWRlciA9IHRoaXMucG9ydC5yZWFkYWJsZS5nZXRSZWFkZXIoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBsaW5lID0gW107XG4gICAgICAgICAgICAvLyB1bmRlZmluZWQgPSBub3Qgc3VyZSBpZiBpbXByb3YgcGFja2V0XG4gICAgICAgICAgICBsZXQgaXNJbXByb3Y7XG4gICAgICAgICAgICAvLyBsZW5ndGggb2YgaW1wcm92IGJ5dGVzIHRoYXQgd2UgZXhwZWN0XG4gICAgICAgICAgICBsZXQgaW1wcm92TGVuZ3RoID0gMDtcbiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyB2YWx1ZSwgZG9uZSB9ID0gYXdhaXQgdGhpcy5fcmVhZGVyLnJlYWQoKTtcbiAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSB8fCB2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYnl0ZSBvZiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNJbXByb3YgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGl0IHdhc24ndCBhbiBpbXByb3YgbGluZSwgZGlzY2FyZCBldmVyeXRoaW5nIHVudGkgd2UgZmluZCBuZXcgbGluZSBjaGFyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYnl0ZSA9PT0gMTApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0ltcHJvdiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0ltcHJvdiA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGluZS5wdXNoKGJ5dGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmUubGVuZ3RoID09PSBpbXByb3ZMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVJbmNvbWluZ1BhY2tldChsaW5lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0ltcHJvdiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYnl0ZSA9PT0gMTApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGxpbmUucHVzaChieXRlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmUubGVuZ3RoICE9PSA5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBpdCdzIGltcHJvdlxuICAgICAgICAgICAgICAgICAgICBpc0ltcHJvdiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoLi4ubGluZS5zbGljZSgwLCA2KSkgPT09IFwiSU1QUk9WXCI7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNJbXByb3YpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIEZvcm1hdDpcbiAgICAgICAgICAgICAgICAgICAgLy8gSSBNIFAgUiBPIFYgPFZFUlNJT04+IDxUWVBFPiA8TEVOR1RIPiA8REFUQT4gPENIRUNLU1VNPlxuICAgICAgICAgICAgICAgICAgICAvLyBPbmNlIHdlIGhhdmUgOSBieXRlcywgd2UgY2FuIGNoZWNrIGlmIGl0J3MgYW4gaW1wcm92IHBhY2tldFxuICAgICAgICAgICAgICAgICAgICAvLyBhbmQgZXh0cmFjdCBob3cgbXVjaCBtb3JlIHdlIG5lZWQgdG8gZmV0Y2guXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhY2tldExlbmd0aCA9IGxpbmVbOF07XG4gICAgICAgICAgICAgICAgICAgIGltcHJvdkxlbmd0aCA9IDkgKyBwYWNrZXRMZW5ndGggKyAxOyAvLyBoZWFkZXIgKyBkYXRhIGxlbmd0aCArIGNoZWNrc3VtXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFwiRXJyb3Igd2hpbGUgcmVhZGluZyBzZXJpYWwgcG9ydFwiLCBlcnIpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5fcmVhZGVyLnJlbGVhc2VMb2NrKCk7XG4gICAgICAgICAgICB0aGlzLl9yZWFkZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXCJGaW5pc2hlZCByZWFkIGxvb3BcIik7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJkaXNjb25uZWN0XCIpKTtcbiAgICB9XG4gICAgX2hhbmRsZUluY29taW5nUGFja2V0KGxpbmUpIHtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IGxpbmUuc2xpY2UoNik7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSBwYXlsb2FkWzBdO1xuICAgICAgICBjb25zdCBwYWNrZXRUeXBlID0gcGF5bG9hZFsxXTtcbiAgICAgICAgY29uc3QgcGFja2V0TGVuZ3RoID0gcGF5bG9hZFsyXTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHBheWxvYWQuc2xpY2UoMywgMyArIHBhY2tldExlbmd0aCk7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFwiUFJPQ0VTU1wiLCB7XG4gICAgICAgICAgICB2ZXJzaW9uLFxuICAgICAgICAgICAgcGFja2V0VHlwZSxcbiAgICAgICAgICAgIHBhY2tldExlbmd0aCxcbiAgICAgICAgICAgIGRhdGE6IGhleEZvcm1hdHRlcihkYXRhKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh2ZXJzaW9uICE9PSAxKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihcIlJlY2VpdmVkIHVuc3VwcG9ydGVkIHZlcnNpb25cIiwgdmVyc2lvbik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gVmVyaWZ5IGNoZWNrc3VtXG4gICAgICAgIGxldCBwYWNrZXRDaGVja3N1bSA9IHBheWxvYWRbMyArIHBhY2tldExlbmd0aF07XG4gICAgICAgIGxldCBjYWxjdWxhdGVkQ2hlY2tzdW0gPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmUubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICBjYWxjdWxhdGVkQ2hlY2tzdW0gKz0gbGluZVtpXTtcbiAgICAgICAgfVxuICAgICAgICBjYWxjdWxhdGVkQ2hlY2tzdW0gPSBjYWxjdWxhdGVkQ2hlY2tzdW0gJiAweGZmO1xuICAgICAgICBpZiAoY2FsY3VsYXRlZENoZWNrc3VtICE9PSBwYWNrZXRDaGVja3N1bSkge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoYFJlY2VpdmVkIGludmFsaWQgY2hlY2tzdW0gJHtwYWNrZXRDaGVja3N1bX0uIEV4cGVjdGVkICR7Y2FsY3VsYXRlZENoZWNrc3VtfWApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYWNrZXRUeXBlID09PSBJbXByb3ZTZXJpYWxNZXNzYWdlVHlwZS5DVVJSRU5UX1NUQVRFKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gZGF0YVswXTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJzdGF0ZS1jaGFuZ2VkXCIsIHtcbiAgICAgICAgICAgICAgICBkZXRhaWw6IHRoaXMuc3RhdGUsXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocGFja2V0VHlwZSA9PT0gSW1wcm92U2VyaWFsTWVzc2FnZVR5cGUuRVJST1JfU1RBVEUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NldEVycm9yKGRhdGFbMF0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBhY2tldFR5cGUgPT09IEltcHJvdlNlcmlhbE1lc3NhZ2VUeXBlLlJQQ19SRVNVTFQpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5fcnBjRmVlZGJhY2spIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihcIlJlY2VpdmVkIHJlc3VsdCB3aGlsZSBub3Qgd2FpdGluZyBmb3Igb25lXCIpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJwY0NvbW1hbmQgPSBkYXRhWzBdO1xuICAgICAgICAgICAgaWYgKHJwY0NvbW1hbmQgIT09IHRoaXMuX3JwY0ZlZWRiYWNrLmNvbW1hbmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihgUmVjZWl2ZWQgcmVzdWx0IGZvciBjb21tYW5kICR7cnBjQ29tbWFuZH0gYnV0IGV4cGVjdGVkICR7dGhpcy5fcnBjRmVlZGJhY2suY29tbWFuZH1gKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBDaG9wIG9mZiBycGMgY29tbWFuZCBhbmQgY2hlY2tzdW1cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgY29uc3QgdG90YWxMZW5ndGggPSBkYXRhWzFdO1xuICAgICAgICAgICAgbGV0IGlkeCA9IDI7XG4gICAgICAgICAgICB3aGlsZSAoaWR4IDwgMiArIHRvdGFsTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goU3RyaW5nLmZyb21Db2RlUG9pbnQoLi4uZGF0YS5zbGljZShpZHggKyAxLCBpZHggKyBkYXRhW2lkeF0gKyAxKSkpO1xuICAgICAgICAgICAgICAgIGlkeCArPSBkYXRhW2lkeF0gKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKFwicmVjZWl2ZWREYXRhXCIgaW4gdGhpcy5fcnBjRmVlZGJhY2spIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcnBjRmVlZGJhY2sucmVjZWl2ZWREYXRhLnB1c2gocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc3VsdCBvZiAwIG1lYW5zIHdlJ3JlIGRvbmUuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JwY0ZlZWRiYWNrLnJlc29sdmUodGhpcy5fcnBjRmVlZGJhY2sucmVjZWl2ZWREYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcnBjRmVlZGJhY2sgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcnBjRmVlZGJhY2sucmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3JwY0ZlZWRiYWNrID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoXCJVbmFibGUgdG8gaGFuZGxlIHBhY2tldFwiLCBwYXlsb2FkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgaGVhZGVyICsgY2hlY2tzdW0gYW5kIHdyaXRlIHBhY2tldCB0byBzdHJlYW1cbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZVBhY2tldFRvU3RyZWFtKHR5cGUsIGRhdGEpIHtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IG5ldyBVaW50OEFycmF5KFtcbiAgICAgICAgICAgIC4uLlNFUklBTF9QQUNLRVRfSEVBREVSLFxuICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgIGRhdGEubGVuZ3RoLFxuICAgICAgICAgICAgLi4uZGF0YSxcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICAwLCAvLyBXaWxsIGJlIG5ld2xpbmVcbiAgICAgICAgXSk7XG4gICAgICAgIC8vIENhbGN1bGF0ZSBjaGVja3N1bVxuICAgICAgICBwYXlsb2FkW3BheWxvYWQubGVuZ3RoIC0gMl0gPVxuICAgICAgICAgICAgcGF5bG9hZC5yZWR1Y2UoKHN1bSwgY3VyKSA9PiBzdW0gKyBjdXIsIDApICYgMHhmZjtcbiAgICAgICAgcGF5bG9hZFtwYXlsb2FkLmxlbmd0aCAtIDFdID0gMTA7IC8vIE5ld2xpbmVcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXCJXcml0aW5nIHRvIHN0cmVhbTpcIiwgaGV4Rm9ybWF0dGVyKG5ldyBBcnJheSguLi5wYXlsb2FkKSkpO1xuICAgICAgICBjb25zdCB3cml0ZXIgPSB0aGlzLnBvcnQud3JpdGFibGUuZ2V0V3JpdGVyKCk7XG4gICAgICAgIGF3YWl0IHdyaXRlci53cml0ZShwYXlsb2FkKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdyaXRlci5yZWxlYXNlTG9jaygpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJJZ25vcmluZyByZWxlYXNlIGxvY2sgZXJyb3JcIiwgZXJyKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBFcnJvciBpcyBlaXRoZXIgcmVjZWl2ZWQgZnJvbSBkZXZpY2Ugb3IgaXMgYSB0aW1lb3V0XG4gICAgX3NldEVycm9yKGVycm9yKSB7XG4gICAgICAgIHRoaXMuZXJyb3IgPSBlcnJvcjtcbiAgICAgICAgaWYgKGVycm9yID4gMCAmJiB0aGlzLl9ycGNGZWVkYmFjaykge1xuICAgICAgICAgICAgdGhpcy5fcnBjRmVlZGJhY2sucmVqZWN0KEVSUk9SX01TR1NbZXJyb3JdIHx8IGBVTktOT1dOX0VSUk9SICgke2Vycm9yfSlgKTtcbiAgICAgICAgICAgIHRoaXMuX3JwY0ZlZWRiYWNrID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJlcnJvci1jaGFuZ2VkXCIsIHtcbiAgICAgICAgICAgIGRldGFpbDogdGhpcy5lcnJvcixcbiAgICAgICAgfSkpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IHRvSGV4IH0gZnJvbSBcIi4vdG8taGV4XCI7XG5leHBvcnQgY29uc3QgaGV4Rm9ybWF0dGVyID0gKGJ5dGVzKSA9PiBcIltcIiArIGJ5dGVzLm1hcCgodmFsdWUpID0+IHRvSGV4KHZhbHVlKSkuam9pbihcIiwgXCIpICsgXCJdXCI7XG4iLCJleHBvcnQgY29uc3Qgc2xlZXAgPSAobXMpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG4iLCJleHBvcnQgY29uc3QgdG9IZXggPSAodmFsdWUsIHNpemUgPSAyKSA9PiB7XG4gICAgbGV0IGhleCA9IHZhbHVlLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuICAgIGlmIChoZXguc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgcmV0dXJuIFwiLTB4XCIgKyBoZXguc3Vic3RyaW5nKDEpLnBhZFN0YXJ0KHNpemUsIFwiMFwiKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBcIjB4XCIgKyBoZXgucGFkU3RhcnQoc2l6ZSwgXCIwXCIpO1xuICAgIH1cbn07XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlXG4gKi9cbmltcG9ydCB7IF8kTEgsIH0gZnJvbSAnLi9saXQtaHRtbC5qcyc7XG5jb25zdCB7IF9DaGlsZFBhcnQ6IENoaWxkUGFydCB9ID0gXyRMSDtcbmNvbnN0IEVOQUJMRV9TSEFEWURPTV9OT1BBVENIID0gdHJ1ZTtcbmNvbnN0IHdyYXAgPSBFTkFCTEVfU0hBRFlET01fTk9QQVRDSCAmJlxuICAgIHdpbmRvdy5TaGFkeURPTT8uaW5Vc2UgJiZcbiAgICB3aW5kb3cuU2hhZHlET00/Lm5vUGF0Y2ggPT09IHRydWVcbiAgICA/IHdpbmRvdy5TaGFkeURPTS53cmFwXG4gICAgOiAobm9kZSkgPT4gbm9kZTtcbi8qKlxuICogVGVzdHMgaWYgYSB2YWx1ZSBpcyBhIHByaW1pdGl2ZSB2YWx1ZS5cbiAqXG4gKiBTZWUgaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdHlwZW9mLW9wZXJhdG9yXG4gKi9cbmV4cG9ydCBjb25zdCBpc1ByaW1pdGl2ZSA9ICh2YWx1ZSkgPT4gdmFsdWUgPT09IG51bGwgfHwgKHR5cGVvZiB2YWx1ZSAhPSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgIT0gJ2Z1bmN0aW9uJyk7XG5leHBvcnQgY29uc3QgVGVtcGxhdGVSZXN1bHRUeXBlID0ge1xuICAgIEhUTUw6IDEsXG4gICAgU1ZHOiAyLFxuICAgIE1BVEhNTDogMyxcbn07XG4vKipcbiAqIFRlc3RzIGlmIGEgdmFsdWUgaXMgYSBUZW1wbGF0ZVJlc3VsdCBvciBhIENvbXBpbGVkVGVtcGxhdGVSZXN1bHQuXG4gKi9cbmV4cG9ydCBjb25zdCBpc1RlbXBsYXRlUmVzdWx0ID0gKHZhbHVlLCB0eXBlKSA9PiB0eXBlID09PSB1bmRlZmluZWRcbiAgICA/IC8vIFRoaXMgcHJvcGVydHkgbmVlZHMgdG8gcmVtYWluIHVubWluaWZpZWQuXG4gICAgICAgIHZhbHVlPy5bJ18kbGl0VHlwZSQnXSAhPT0gdW5kZWZpbmVkXG4gICAgOiB2YWx1ZT8uWydfJGxpdFR5cGUkJ10gPT09IHR5cGU7XG4vKipcbiAqIFRlc3RzIGlmIGEgdmFsdWUgaXMgYSBDb21waWxlZFRlbXBsYXRlUmVzdWx0LlxuICovXG5leHBvcnQgY29uc3QgaXNDb21waWxlZFRlbXBsYXRlUmVzdWx0ID0gKHZhbHVlKSA9PiB7XG4gICAgcmV0dXJuIHZhbHVlPy5bJ18kbGl0VHlwZSQnXT8uaCAhPSBudWxsO1xufTtcbi8qKlxuICogVGVzdHMgaWYgYSB2YWx1ZSBpcyBhIERpcmVjdGl2ZVJlc3VsdC5cbiAqL1xuZXhwb3J0IGNvbnN0IGlzRGlyZWN0aXZlUmVzdWx0ID0gKHZhbHVlKSA9PiBcbi8vIFRoaXMgcHJvcGVydHkgbmVlZHMgdG8gcmVtYWluIHVubWluaWZpZWQuXG52YWx1ZT8uWydfJGxpdERpcmVjdGl2ZSQnXSAhPT0gdW5kZWZpbmVkO1xuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIERpcmVjdGl2ZSBjbGFzcyBmb3IgYSBEaXJlY3RpdmVSZXN1bHRcbiAqL1xuZXhwb3J0IGNvbnN0IGdldERpcmVjdGl2ZUNsYXNzID0gKHZhbHVlKSA9PiBcbi8vIFRoaXMgcHJvcGVydHkgbmVlZHMgdG8gcmVtYWluIHVubWluaWZpZWQuXG52YWx1ZT8uWydfJGxpdERpcmVjdGl2ZSQnXTtcbi8qKlxuICogVGVzdHMgd2hldGhlciBhIHBhcnQgaGFzIG9ubHkgYSBzaW5nbGUtZXhwcmVzc2lvbiB3aXRoIG5vIHN0cmluZ3MgdG9cbiAqIGludGVycG9sYXRlIGJldHdlZW4uXG4gKlxuICogT25seSBBdHRyaWJ1dGVQYXJ0IGFuZCBQcm9wZXJ0eVBhcnQgY2FuIGhhdmUgbXVsdGlwbGUgZXhwcmVzc2lvbnMuXG4gKiBNdWx0aS1leHByZXNzaW9uIHBhcnRzIGhhdmUgYSBgc3RyaW5nc2AgcHJvcGVydHkgYW5kIHNpbmdsZS1leHByZXNzaW9uXG4gKiBwYXJ0cyBkbyBub3QuXG4gKi9cbmV4cG9ydCBjb25zdCBpc1NpbmdsZUV4cHJlc3Npb24gPSAocGFydCkgPT4gcGFydC5zdHJpbmdzID09PSB1bmRlZmluZWQ7XG5jb25zdCBjcmVhdGVNYXJrZXIgPSAoKSA9PiBkb2N1bWVudC5jcmVhdGVDb21tZW50KCcnKTtcbi8qKlxuICogSW5zZXJ0cyBhIENoaWxkUGFydCBpbnRvIHRoZSBnaXZlbiBjb250YWluZXIgQ2hpbGRQYXJ0J3MgRE9NLCBlaXRoZXIgYXQgdGhlXG4gKiBlbmQgb2YgdGhlIGNvbnRhaW5lciBDaGlsZFBhcnQsIG9yIGJlZm9yZSB0aGUgb3B0aW9uYWwgYHJlZlBhcnRgLlxuICpcbiAqIFRoaXMgZG9lcyBub3QgYWRkIHRoZSBwYXJ0IHRvIHRoZSBjb250YWluZXJQYXJ0J3MgY29tbWl0dGVkIHZhbHVlLiBUaGF0IG11c3RcbiAqIGJlIGRvbmUgYnkgY2FsbGVycy5cbiAqXG4gKiBAcGFyYW0gY29udGFpbmVyUGFydCBQYXJ0IHdpdGhpbiB3aGljaCB0byBhZGQgdGhlIG5ldyBDaGlsZFBhcnRcbiAqIEBwYXJhbSByZWZQYXJ0IFBhcnQgYmVmb3JlIHdoaWNoIHRvIGFkZCB0aGUgbmV3IENoaWxkUGFydDsgd2hlbiBvbWl0dGVkIHRoZVxuICogICAgIHBhcnQgYWRkZWQgdG8gdGhlIGVuZCBvZiB0aGUgYGNvbnRhaW5lclBhcnRgXG4gKiBAcGFyYW0gcGFydCBQYXJ0IHRvIGluc2VydCwgb3IgdW5kZWZpbmVkIHRvIGNyZWF0ZSBhIG5ldyBwYXJ0XG4gKi9cbmV4cG9ydCBjb25zdCBpbnNlcnRQYXJ0ID0gKGNvbnRhaW5lclBhcnQsIHJlZlBhcnQsIHBhcnQpID0+IHtcbiAgICBjb25zdCBjb250YWluZXIgPSB3cmFwKGNvbnRhaW5lclBhcnQuXyRzdGFydE5vZGUpLnBhcmVudE5vZGU7XG4gICAgY29uc3QgcmVmTm9kZSA9IHJlZlBhcnQgPT09IHVuZGVmaW5lZCA/IGNvbnRhaW5lclBhcnQuXyRlbmROb2RlIDogcmVmUGFydC5fJHN0YXJ0Tm9kZTtcbiAgICBpZiAocGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0Tm9kZSA9IHdyYXAoY29udGFpbmVyKS5pbnNlcnRCZWZvcmUoY3JlYXRlTWFya2VyKCksIHJlZk5vZGUpO1xuICAgICAgICBjb25zdCBlbmROb2RlID0gd3JhcChjb250YWluZXIpLmluc2VydEJlZm9yZShjcmVhdGVNYXJrZXIoKSwgcmVmTm9kZSk7XG4gICAgICAgIHBhcnQgPSBuZXcgQ2hpbGRQYXJ0KHN0YXJ0Tm9kZSwgZW5kTm9kZSwgY29udGFpbmVyUGFydCwgY29udGFpbmVyUGFydC5vcHRpb25zKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGNvbnN0IGVuZE5vZGUgPSB3cmFwKHBhcnQuXyRlbmROb2RlKS5uZXh0U2libGluZztcbiAgICAgICAgY29uc3Qgb2xkUGFyZW50ID0gcGFydC5fJHBhcmVudDtcbiAgICAgICAgY29uc3QgcGFyZW50Q2hhbmdlZCA9IG9sZFBhcmVudCAhPT0gY29udGFpbmVyUGFydDtcbiAgICAgICAgaWYgKHBhcmVudENoYW5nZWQpIHtcbiAgICAgICAgICAgIHBhcnQuXyRyZXBhcmVudERpc2Nvbm5lY3RhYmxlcz8uKGNvbnRhaW5lclBhcnQpO1xuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IGFsdGhvdWdoIGBfJHJlcGFyZW50RGlzY29ubmVjdGFibGVzYCB1cGRhdGVzIHRoZSBwYXJ0J3NcbiAgICAgICAgICAgIC8vIGBfJHBhcmVudGAgcmVmZXJlbmNlIGFmdGVyIHVubGlua2luZyBmcm9tIGl0cyBjdXJyZW50IHBhcmVudCwgdGhhdFxuICAgICAgICAgICAgLy8gbWV0aG9kIG9ubHkgZXhpc3RzIGlmIERpc2Nvbm5lY3RhYmxlcyBhcmUgcHJlc2VudCwgc28gd2UgbmVlZCB0b1xuICAgICAgICAgICAgLy8gdW5jb25kaXRpb25hbGx5IHNldCBpdCBoZXJlXG4gICAgICAgICAgICBwYXJ0Ll8kcGFyZW50ID0gY29udGFpbmVyUGFydDtcbiAgICAgICAgICAgIC8vIFNpbmNlIHRoZSBfJGlzQ29ubmVjdGVkIGdldHRlciBpcyBzb21ld2hhdCBjb3N0bHksIG9ubHlcbiAgICAgICAgICAgIC8vIHJlYWQgaXQgb25jZSB3ZSBrbm93IHRoZSBzdWJ0cmVlIGhhcyBkaXJlY3RpdmVzIHRoYXQgbmVlZFxuICAgICAgICAgICAgLy8gdG8gYmUgbm90aWZpZWRcbiAgICAgICAgICAgIGxldCBuZXdDb25uZWN0aW9uU3RhdGU7XG4gICAgICAgICAgICBpZiAocGFydC5fJG5vdGlmeUNvbm5lY3Rpb25DaGFuZ2VkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICAobmV3Q29ubmVjdGlvblN0YXRlID0gY29udGFpbmVyUGFydC5fJGlzQ29ubmVjdGVkKSAhPT1cbiAgICAgICAgICAgICAgICAgICAgb2xkUGFyZW50Ll8kaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBwYXJ0Ll8kbm90aWZ5Q29ubmVjdGlvbkNoYW5nZWQobmV3Q29ubmVjdGlvblN0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZW5kTm9kZSAhPT0gcmVmTm9kZSB8fCBwYXJlbnRDaGFuZ2VkKSB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSBwYXJ0Ll8kc3RhcnROb2RlO1xuICAgICAgICAgICAgd2hpbGUgKHN0YXJ0ICE9PSBlbmROb2RlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbiA9IHdyYXAoc3RhcnQpLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgICAgIHdyYXAoY29udGFpbmVyKS5pbnNlcnRCZWZvcmUoc3RhcnQsIHJlZk5vZGUpO1xuICAgICAgICAgICAgICAgIHN0YXJ0ID0gbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGFydDtcbn07XG4vKipcbiAqIFNldHMgdGhlIHZhbHVlIG9mIGEgUGFydC5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBzaG91bGQgb25seSBiZSB1c2VkIHRvIHNldC91cGRhdGUgdGhlIHZhbHVlIG9mIHVzZXItY3JlYXRlZFxuICogcGFydHMgKGkuZS4gdGhvc2UgY3JlYXRlZCB1c2luZyBgaW5zZXJ0UGFydGApOyBpdCBzaG91bGQgbm90IGJlIHVzZWRcbiAqIGJ5IGRpcmVjdGl2ZXMgdG8gc2V0IHRoZSB2YWx1ZSBvZiB0aGUgZGlyZWN0aXZlJ3MgY29udGFpbmVyIHBhcnQuIERpcmVjdGl2ZXNcbiAqIHNob3VsZCByZXR1cm4gYSB2YWx1ZSBmcm9tIGB1cGRhdGVgL2ByZW5kZXJgIHRvIHVwZGF0ZSB0aGVpciBwYXJ0IHN0YXRlLlxuICpcbiAqIEZvciBkaXJlY3RpdmVzIHRoYXQgcmVxdWlyZSBzZXR0aW5nIHRoZWlyIHBhcnQgdmFsdWUgYXN5bmNocm9ub3VzbHksIHRoZXlcbiAqIHNob3VsZCBleHRlbmQgYEFzeW5jRGlyZWN0aXZlYCBhbmQgY2FsbCBgdGhpcy5zZXRWYWx1ZSgpYC5cbiAqXG4gKiBAcGFyYW0gcGFydCBQYXJ0IHRvIHNldFxuICogQHBhcmFtIHZhbHVlIFZhbHVlIHRvIHNldFxuICogQHBhcmFtIGluZGV4IEZvciBgQXR0cmlidXRlUGFydGBzLCB0aGUgaW5kZXggdG8gc2V0XG4gKiBAcGFyYW0gZGlyZWN0aXZlUGFyZW50IFVzZWQgaW50ZXJuYWxseTsgc2hvdWxkIG5vdCBiZSBzZXQgYnkgdXNlclxuICovXG5leHBvcnQgY29uc3Qgc2V0Q2hpbGRQYXJ0VmFsdWUgPSAocGFydCwgdmFsdWUsIGRpcmVjdGl2ZVBhcmVudCA9IHBhcnQpID0+IHtcbiAgICBwYXJ0Ll8kc2V0VmFsdWUodmFsdWUsIGRpcmVjdGl2ZVBhcmVudCk7XG4gICAgcmV0dXJuIHBhcnQ7XG59O1xuLy8gQSBzZW50aW5lbCB2YWx1ZSB0aGF0IGNhbiBuZXZlciBhcHBlYXIgYXMgYSBwYXJ0IHZhbHVlIGV4Y2VwdCB3aGVuIHNldCBieVxuLy8gbGl2ZSgpLiBVc2VkIHRvIGZvcmNlIGEgZGlydHktY2hlY2sgdG8gZmFpbCBhbmQgY2F1c2UgYSByZS1yZW5kZXIuXG5jb25zdCBSRVNFVF9WQUxVRSA9IHt9O1xuLyoqXG4gKiBTZXRzIHRoZSBjb21taXR0ZWQgdmFsdWUgb2YgYSBDaGlsZFBhcnQgZGlyZWN0bHkgd2l0aG91dCB0cmlnZ2VyaW5nIHRoZVxuICogY29tbWl0IHN0YWdlIG9mIHRoZSBwYXJ0LlxuICpcbiAqIFRoaXMgaXMgdXNlZnVsIGluIGNhc2VzIHdoZXJlIGEgZGlyZWN0aXZlIG5lZWRzIHRvIHVwZGF0ZSB0aGUgcGFydCBzdWNoXG4gKiB0aGF0IHRoZSBuZXh0IHVwZGF0ZSBkZXRlY3RzIGEgdmFsdWUgY2hhbmdlIG9yIG5vdC4gV2hlbiB2YWx1ZSBpcyBvbWl0dGVkLFxuICogdGhlIG5leHQgdXBkYXRlIHdpbGwgYmUgZ3VhcmFudGVlZCB0byBiZSBkZXRlY3RlZCBhcyBhIGNoYW5nZS5cbiAqXG4gKiBAcGFyYW0gcGFydFxuICogQHBhcmFtIHZhbHVlXG4gKi9cbmV4cG9ydCBjb25zdCBzZXRDb21taXR0ZWRWYWx1ZSA9IChwYXJ0LCB2YWx1ZSA9IFJFU0VUX1ZBTFVFKSA9PiAocGFydC5fJGNvbW1pdHRlZFZhbHVlID0gdmFsdWUpO1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBjb21taXR0ZWQgdmFsdWUgb2YgYSBDaGlsZFBhcnQuXG4gKlxuICogVGhlIGNvbW1pdHRlZCB2YWx1ZSBpcyB1c2VkIGZvciBjaGFuZ2UgZGV0ZWN0aW9uIGFuZCBlZmZpY2llbnQgdXBkYXRlcyBvZlxuICogdGhlIHBhcnQuIEl0IGNhbiBkaWZmZXIgZnJvbSB0aGUgdmFsdWUgc2V0IGJ5IHRoZSB0ZW1wbGF0ZSBvciBkaXJlY3RpdmUgaW5cbiAqIGNhc2VzIHdoZXJlIHRoZSB0ZW1wbGF0ZSB2YWx1ZSBpcyB0cmFuc2Zvcm1lZCBiZWZvcmUgYmVpbmcgY29tbWl0dGVkLlxuICpcbiAqIC0gYFRlbXBsYXRlUmVzdWx0YHMgYXJlIGNvbW1pdHRlZCBhcyBhIGBUZW1wbGF0ZUluc3RhbmNlYFxuICogLSBJdGVyYWJsZXMgYXJlIGNvbW1pdHRlZCBhcyBgQXJyYXk8Q2hpbGRQYXJ0PmBcbiAqIC0gQWxsIG90aGVyIHR5cGVzIGFyZSBjb21taXR0ZWQgYXMgdGhlIHRlbXBsYXRlIHZhbHVlIG9yIHZhbHVlIHJldHVybmVkIG9yXG4gKiAgIHNldCBieSBhIGRpcmVjdGl2ZS5cbiAqXG4gKiBAcGFyYW0gcGFydFxuICovXG5leHBvcnQgY29uc3QgZ2V0Q29tbWl0dGVkVmFsdWUgPSAocGFydCkgPT4gcGFydC5fJGNvbW1pdHRlZFZhbHVlO1xuLyoqXG4gKiBSZW1vdmVzIGEgQ2hpbGRQYXJ0IGZyb20gdGhlIERPTSwgaW5jbHVkaW5nIGFueSBvZiBpdHMgY29udGVudC5cbiAqXG4gKiBAcGFyYW0gcGFydCBUaGUgUGFydCB0byByZW1vdmVcbiAqL1xuZXhwb3J0IGNvbnN0IHJlbW92ZVBhcnQgPSAocGFydCkgPT4ge1xuICAgIHBhcnQuXyRub3RpZnlDb25uZWN0aW9uQ2hhbmdlZD8uKGZhbHNlLCB0cnVlKTtcbiAgICBsZXQgc3RhcnQgPSBwYXJ0Ll8kc3RhcnROb2RlO1xuICAgIGNvbnN0IGVuZCA9IHdyYXAocGFydC5fJGVuZE5vZGUpLm5leHRTaWJsaW5nO1xuICAgIHdoaWxlIChzdGFydCAhPT0gZW5kKSB7XG4gICAgICAgIGNvbnN0IG4gPSB3cmFwKHN0YXJ0KS5uZXh0U2libGluZztcbiAgICAgICAgd3JhcChzdGFydCkucmVtb3ZlKCk7XG4gICAgICAgIHN0YXJ0ID0gbjtcbiAgICB9XG59O1xuZXhwb3J0IGNvbnN0IGNsZWFyUGFydCA9IChwYXJ0KSA9PiB7XG4gICAgcGFydC5fJGNsZWFyKCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGlyZWN0aXZlLWhlbHBlcnMuanMubWFwIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZVxuICovXG5pbXBvcnQgeyBub0NoYW5nZSwgbm90aGluZyB9IGZyb20gJy4uL2xpdC1odG1sLmpzJztcbmltcG9ydCB7IGRpcmVjdGl2ZSwgRGlyZWN0aXZlLCBQYXJ0VHlwZSwgfSBmcm9tICcuLi9kaXJlY3RpdmUuanMnO1xuaW1wb3J0IHsgaXNTaW5nbGVFeHByZXNzaW9uLCBzZXRDb21taXR0ZWRWYWx1ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZS1oZWxwZXJzLmpzJztcbmNsYXNzIExpdmVEaXJlY3RpdmUgZXh0ZW5kcyBEaXJlY3RpdmUge1xuICAgIGNvbnN0cnVjdG9yKHBhcnRJbmZvKSB7XG4gICAgICAgIHN1cGVyKHBhcnRJbmZvKTtcbiAgICAgICAgaWYgKCEocGFydEluZm8udHlwZSA9PT0gUGFydFR5cGUuUFJPUEVSVFkgfHxcbiAgICAgICAgICAgIHBhcnRJbmZvLnR5cGUgPT09IFBhcnRUeXBlLkFUVFJJQlVURSB8fFxuICAgICAgICAgICAgcGFydEluZm8udHlwZSA9PT0gUGFydFR5cGUuQk9PTEVBTl9BVFRSSUJVVEUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBgbGl2ZWAgZGlyZWN0aXZlIGlzIG5vdCBhbGxvd2VkIG9uIGNoaWxkIG9yIGV2ZW50IGJpbmRpbmdzJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1NpbmdsZUV4cHJlc3Npb24ocGFydEluZm8pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2BsaXZlYCBiaW5kaW5ncyBjYW4gb25seSBjb250YWluIGEgc2luZ2xlIGV4cHJlc3Npb24nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZW5kZXIodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICB1cGRhdGUocGFydCwgW3ZhbHVlXSkge1xuICAgICAgICBpZiAodmFsdWUgPT09IG5vQ2hhbmdlIHx8IHZhbHVlID09PSBub3RoaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHBhcnQuZWxlbWVudDtcbiAgICAgICAgY29uc3QgbmFtZSA9IHBhcnQubmFtZTtcbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gUGFydFR5cGUuUFJPUEVSVFkpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IGVsZW1lbnRbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9DaGFuZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocGFydC50eXBlID09PSBQYXJ0VHlwZS5CT09MRUFOX0FUVFJJQlVURSkge1xuICAgICAgICAgICAgaWYgKCEhdmFsdWUgPT09IGVsZW1lbnQuaGFzQXR0cmlidXRlKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vQ2hhbmdlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gUGFydFR5cGUuQVRUUklCVVRFKSB7XG4gICAgICAgICAgICBpZiAoZWxlbWVudC5nZXRBdHRyaWJ1dGUobmFtZSkgPT09IFN0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9DaGFuZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVzZXRzIHRoZSBwYXJ0J3MgdmFsdWUsIGNhdXNpbmcgaXRzIGRpcnR5LWNoZWNrIHRvIGZhaWwgc28gdGhhdCBpdFxuICAgICAgICAvLyBhbHdheXMgc2V0cyB0aGUgdmFsdWUuXG4gICAgICAgIHNldENvbW1pdHRlZFZhbHVlKHBhcnQpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxufVxuLyoqXG4gKiBDaGVja3MgYmluZGluZyB2YWx1ZXMgYWdhaW5zdCBsaXZlIERPTSB2YWx1ZXMsIGluc3RlYWQgb2YgcHJldmlvdXNseSBib3VuZFxuICogdmFsdWVzLCB3aGVuIGRldGVybWluaW5nIHdoZXRoZXIgdG8gdXBkYXRlIHRoZSB2YWx1ZS5cbiAqXG4gKiBUaGlzIGlzIHVzZWZ1bCBmb3IgY2FzZXMgd2hlcmUgdGhlIERPTSB2YWx1ZSBtYXkgY2hhbmdlIGZyb20gb3V0c2lkZSBvZlxuICogbGl0LWh0bWwsIHN1Y2ggYXMgd2l0aCBhIGJpbmRpbmcgdG8gYW4gYDxpbnB1dD5gIGVsZW1lbnQncyBgdmFsdWVgIHByb3BlcnR5LFxuICogYSBjb250ZW50IGVkaXRhYmxlIGVsZW1lbnRzIHRleHQsIG9yIHRvIGEgY3VzdG9tIGVsZW1lbnQgdGhhdCBjaGFuZ2VzIGl0J3NcbiAqIG93biBwcm9wZXJ0aWVzIG9yIGF0dHJpYnV0ZXMuXG4gKlxuICogSW4gdGhlc2UgY2FzZXMgaWYgdGhlIERPTSB2YWx1ZSBjaGFuZ2VzLCBidXQgdGhlIHZhbHVlIHNldCB0aHJvdWdoIGxpdC1odG1sXG4gKiBiaW5kaW5ncyBoYXNuJ3QsIGxpdC1odG1sIHdvbid0IGtub3cgdG8gdXBkYXRlIHRoZSBET00gdmFsdWUgYW5kIHdpbGwgbGVhdmVcbiAqIGl0IGFsb25lLiBJZiB0aGlzIGlzIG5vdCB3aGF0IHlvdSB3YW50LS1pZiB5b3Ugd2FudCB0byBvdmVyd3JpdGUgdGhlIERPTVxuICogdmFsdWUgd2l0aCB0aGUgYm91bmQgdmFsdWUgbm8gbWF0dGVyIHdoYXQtLXVzZSB0aGUgYGxpdmUoKWAgZGlyZWN0aXZlOlxuICpcbiAqIGBgYGpzXG4gKiBodG1sYDxpbnB1dCAudmFsdWU9JHtsaXZlKHgpfT5gXG4gKiBgYGBcbiAqXG4gKiBgbGl2ZSgpYCBwZXJmb3JtcyBhIHN0cmljdCBlcXVhbGl0eSBjaGVjayBhZ2FpbnN0IHRoZSBsaXZlIERPTSB2YWx1ZSwgYW5kIGlmXG4gKiB0aGUgbmV3IHZhbHVlIGlzIGVxdWFsIHRvIHRoZSBsaXZlIHZhbHVlLCBkb2VzIG5vdGhpbmcuIFRoaXMgbWVhbnMgdGhhdFxuICogYGxpdmUoKWAgc2hvdWxkIG5vdCBiZSB1c2VkIHdoZW4gdGhlIGJpbmRpbmcgd2lsbCBjYXVzZSBhIHR5cGUgY29udmVyc2lvbi4gSWZcbiAqIHlvdSB1c2UgYGxpdmUoKWAgd2l0aCBhbiBhdHRyaWJ1dGUgYmluZGluZywgbWFrZSBzdXJlIHRoYXQgb25seSBzdHJpbmdzIGFyZVxuICogcGFzc2VkIGluLCBvciB0aGUgYmluZGluZyB3aWxsIHVwZGF0ZSBldmVyeSByZW5kZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBsaXZlID0gZGlyZWN0aXZlKExpdmVEaXJlY3RpdmUpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGl2ZS5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOCBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlXG4gKi9cbmltcG9ydCB7IG5vQ2hhbmdlIH0gZnJvbSAnLi4vbGl0LWh0bWwuanMnO1xuaW1wb3J0IHsgZGlyZWN0aXZlLCBEaXJlY3RpdmUsIFBhcnRUeXBlLCB9IGZyb20gJy4uL2RpcmVjdGl2ZS5qcyc7XG5jb25zdCBpbXBvcnRhbnQgPSAnaW1wb3J0YW50Jztcbi8vIFRoZSBsZWFkaW5nIHNwYWNlIGlzIGltcG9ydGFudFxuY29uc3QgaW1wb3J0YW50RmxhZyA9ICcgIScgKyBpbXBvcnRhbnQ7XG4vLyBIb3cgbWFueSBjaGFyYWN0ZXJzIHRvIHJlbW92ZSBmcm9tIGEgdmFsdWUsIGFzIGEgbmVnYXRpdmUgbnVtYmVyXG5jb25zdCBmbGFnVHJpbSA9IDAgLSBpbXBvcnRhbnRGbGFnLmxlbmd0aDtcbmNsYXNzIFN0eWxlTWFwRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJ0SW5mbykge1xuICAgICAgICBzdXBlcihwYXJ0SW5mbyk7XG4gICAgICAgIGlmIChwYXJ0SW5mby50eXBlICE9PSBQYXJ0VHlwZS5BVFRSSUJVVEUgfHxcbiAgICAgICAgICAgIHBhcnRJbmZvLm5hbWUgIT09ICdzdHlsZScgfHxcbiAgICAgICAgICAgIHBhcnRJbmZvLnN0cmluZ3M/Lmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGBzdHlsZU1hcGAgZGlyZWN0aXZlIG11c3QgYmUgdXNlZCBpbiB0aGUgYHN0eWxlYCBhdHRyaWJ1dGUgJyArXG4gICAgICAgICAgICAgICAgJ2FuZCBtdXN0IGJlIHRoZSBvbmx5IHBhcnQgaW4gdGhlIGF0dHJpYnV0ZS4nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZW5kZXIoc3R5bGVJbmZvKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhzdHlsZUluZm8pLnJlZHVjZSgoc3R5bGUsIHByb3ApID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc3R5bGVJbmZvW3Byb3BdO1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3R5bGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBDb252ZXJ0IHByb3BlcnR5IG5hbWVzIGZyb20gY2FtZWwtY2FzZSB0byBkYXNoLWNhc2UsIGkuZS46XG4gICAgICAgICAgICAvLyAgYGJhY2tncm91bmRDb2xvcmAgLT4gYGJhY2tncm91bmQtY29sb3JgXG4gICAgICAgICAgICAvLyBWZW5kb3ItcHJlZml4ZWQgbmFtZXMgbmVlZCBhbiBleHRyYSBgLWAgYXBwZW5kZWQgdG8gZnJvbnQ6XG4gICAgICAgICAgICAvLyAgYHdlYmtpdEFwcGVhcmFuY2VgIC0+IGAtd2Via2l0LWFwcGVhcmFuY2VgXG4gICAgICAgICAgICAvLyBFeGNlcHRpb24gaXMgYW55IHByb3BlcnR5IG5hbWUgY29udGFpbmluZyBhIGRhc2gsIGluY2x1ZGluZ1xuICAgICAgICAgICAgLy8gY3VzdG9tIHByb3BlcnRpZXM7IHdlIGFzc3VtZSB0aGVzZSBhcmUgYWxyZWFkeSBkYXNoLWNhc2VkIGkuZS46XG4gICAgICAgICAgICAvLyAgYC0tbXktYnV0dG9uLWNvbG9yYCAtLT4gYC0tbXktYnV0dG9uLWNvbG9yYFxuICAgICAgICAgICAgcHJvcCA9IHByb3AuaW5jbHVkZXMoJy0nKVxuICAgICAgICAgICAgICAgID8gcHJvcFxuICAgICAgICAgICAgICAgIDogcHJvcFxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKD86Xih3ZWJraXR8bW96fG1zfG8pfCkoPz1bQS1aXSkvZywgJy0kJicpXG4gICAgICAgICAgICAgICAgICAgIC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHN0eWxlICsgYCR7cHJvcH06JHt2YWx1ZX07YDtcbiAgICAgICAgfSwgJycpO1xuICAgIH1cbiAgICB1cGRhdGUocGFydCwgW3N0eWxlSW5mb10pIHtcbiAgICAgICAgY29uc3QgeyBzdHlsZSB9ID0gcGFydC5lbGVtZW50O1xuICAgICAgICBpZiAodGhpcy5fcHJldmlvdXNTdHlsZVByb3BlcnRpZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNTdHlsZVByb3BlcnRpZXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKHN0eWxlSW5mbykpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyKHN0eWxlSW5mbyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVtb3ZlIG9sZCBwcm9wZXJ0aWVzIHRoYXQgbm8gbG9uZ2VyIGV4aXN0IGluIHN0eWxlSW5mb1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5fcHJldmlvdXNTdHlsZVByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBuYW1lIGlzbid0IGluIHN0eWxlSW5mbyBvciBpdCdzIG51bGwvdW5kZWZpbmVkXG4gICAgICAgICAgICBpZiAoc3R5bGVJbmZvW25hbWVdID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wcmV2aW91c1N0eWxlUHJvcGVydGllcy5kZWxldGUobmFtZSk7XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUuaW5jbHVkZXMoJy0nKSkge1xuICAgICAgICAgICAgICAgICAgICBzdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlW25hbWVdID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gQWRkIG9yIHVwZGF0ZSBwcm9wZXJ0aWVzXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBzdHlsZUluZm8pIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc3R5bGVJbmZvW25hbWVdO1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wcmV2aW91c1N0eWxlUHJvcGVydGllcy5hZGQobmFtZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgaXNJbXBvcnRhbnQgPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLmVuZHNXaXRoKGltcG9ydGFudEZsYWcpO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lLmluY2x1ZGVzKCctJykgfHwgaXNJbXBvcnRhbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgaXNJbXBvcnRhbnRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gdmFsdWUuc2xpY2UoMCwgZmxhZ1RyaW0pXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHZhbHVlLCBpc0ltcG9ydGFudCA/IGltcG9ydGFudCA6ICcnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlW25hbWVdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub0NoYW5nZTtcbiAgICB9XG59XG4vKipcbiAqIEEgZGlyZWN0aXZlIHRoYXQgYXBwbGllcyBDU1MgcHJvcGVydGllcyB0byBhbiBlbGVtZW50LlxuICpcbiAqIGBzdHlsZU1hcGAgY2FuIG9ubHkgYmUgdXNlZCBpbiB0aGUgYHN0eWxlYCBhdHRyaWJ1dGUgYW5kIG11c3QgYmUgdGhlIG9ubHlcbiAqIGV4cHJlc3Npb24gaW4gdGhlIGF0dHJpYnV0ZS4gSXQgdGFrZXMgdGhlIHByb3BlcnR5IG5hbWVzIGluIHRoZVxuICoge0BsaW5rIFN0eWxlSW5mbyBzdHlsZUluZm99IG9iamVjdCBhbmQgYWRkcyB0aGUgcHJvcGVydGllcyB0byB0aGUgaW5saW5lXG4gKiBzdHlsZSBvZiB0aGUgZWxlbWVudC5cbiAqXG4gKiBQcm9wZXJ0eSBuYW1lcyB3aXRoIGRhc2hlcyAoYC1gKSBhcmUgYXNzdW1lZCB0byBiZSB2YWxpZCBDU1NcbiAqIHByb3BlcnR5IG5hbWVzIGFuZCBzZXQgb24gdGhlIGVsZW1lbnQncyBzdHlsZSBvYmplY3QgdXNpbmcgYHNldFByb3BlcnR5KClgLlxuICogTmFtZXMgd2l0aG91dCBkYXNoZXMgYXJlIGFzc3VtZWQgdG8gYmUgY2FtZWxDYXNlZCBKYXZhU2NyaXB0IHByb3BlcnR5IG5hbWVzXG4gKiBhbmQgc2V0IG9uIHRoZSBlbGVtZW50J3Mgc3R5bGUgb2JqZWN0IHVzaW5nIHByb3BlcnR5IGFzc2lnbm1lbnQsIGFsbG93aW5nIHRoZVxuICogc3R5bGUgb2JqZWN0IHRvIHRyYW5zbGF0ZSBKYXZhU2NyaXB0LXN0eWxlIG5hbWVzIHRvIENTUyBwcm9wZXJ0eSBuYW1lcy5cbiAqXG4gKiBGb3IgZXhhbXBsZSBgc3R5bGVNYXAoe2JhY2tncm91bmRDb2xvcjogJ3JlZCcsICdib3JkZXItdG9wJzogJzVweCcsICctLXNpemUnOlxuICogJzAnfSlgIHNldHMgdGhlIGBiYWNrZ3JvdW5kLWNvbG9yYCwgYGJvcmRlci10b3BgIGFuZCBgLS1zaXplYCBwcm9wZXJ0aWVzLlxuICpcbiAqIEBwYXJhbSBzdHlsZUluZm9cbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vbGl0LmRldi9kb2NzL3RlbXBsYXRlcy9kaXJlY3RpdmVzLyNzdHlsZW1hcCBzdHlsZU1hcCBjb2RlIHNhbXBsZXMgb24gTGl0LmRldn1cbiAqL1xuZXhwb3J0IGNvbnN0IHN0eWxlTWFwID0gZGlyZWN0aXZlKFN0eWxlTWFwRGlyZWN0aXZlKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0eWxlLW1hcC5qcy5tYXAiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQlNELTMtQ2xhdXNlXG4gKi9cbi8vIEFueSBuZXcgZXhwb3J0cyBuZWVkIHRvIGJlIGFkZGVkIHRvIHRoZSBleHBvcnQgc3RhdGVtZW50IGluXG4vLyBgcGFja2FnZXMvbGl0L3NyYy9pbmRleC5hbGwudHNgLlxuaW1wb3J0IHsgaHRtbCBhcyBjb3JlSHRtbCwgc3ZnIGFzIGNvcmVTdmcsIG1hdGhtbCBhcyBjb3JlTWF0aG1sLCB9IGZyb20gJy4vbGl0LWh0bWwuanMnO1xuLyoqXG4gKiBQcmV2ZW50cyBKU09OIGluamVjdGlvbiBhdHRhY2tzLlxuICpcbiAqIFRoZSBnb2FscyBvZiB0aGlzIGJyYW5kOlxuICogICAxKSBmYXN0IHRvIGNoZWNrXG4gKiAgIDIpIGNvZGUgaXMgc21hbGwgb24gdGhlIHdpcmVcbiAqICAgMykgbXVsdGlwbGUgdmVyc2lvbnMgb2YgTGl0IGluIGEgc2luZ2xlIHBhZ2Ugd2lsbCBhbGwgcHJvZHVjZSBtdXR1YWxseVxuICogICAgICBpbnRlcm9wZXJhYmxlIFN0YXRpY1ZhbHVlc1xuICogICA0KSBub3JtYWwgSlNPTi5wYXJzZSAod2l0aG91dCBhbiB1bnVzdWFsIHJldml2ZXIpIGNhbiBub3QgcHJvZHVjZSBhXG4gKiAgICAgIFN0YXRpY1ZhbHVlXG4gKlxuICogU3ltYm9scyBzYXRpc2Z5ICgxKSwgKDIpLCBhbmQgKDQpLiBXZSB1c2UgU3ltYm9sLmZvciB0byBzYXRpc2Z5ICgzKSwgYnV0XG4gKiB3ZSBkb24ndCBjYXJlIGFib3V0IHRoZSBrZXksIHNvIHdlIGJyZWFrIHRpZXMgdmlhICgyKSBhbmQgdXNlIHRoZSBlbXB0eVxuICogc3RyaW5nLlxuICovXG5jb25zdCBicmFuZCA9IFN5bWJvbC5mb3IoJycpO1xuLyoqIFNhZmVseSBleHRyYWN0cyB0aGUgc3RyaW5nIHBhcnQgb2YgYSBTdGF0aWNWYWx1ZS4gKi9cbmNvbnN0IHVud3JhcFN0YXRpY1ZhbHVlID0gKHZhbHVlKSA9PiB7XG4gICAgaWYgKHZhbHVlPy5yICE9PSBicmFuZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU/LlsnXyRsaXRTdGF0aWMkJ107XG59O1xuLyoqXG4gKiBXcmFwcyBhIHN0cmluZyBzbyB0aGF0IGl0IGJlaGF2ZXMgbGlrZSBwYXJ0IG9mIHRoZSBzdGF0aWMgdGVtcGxhdGVcbiAqIHN0cmluZ3MgaW5zdGVhZCBvZiBhIGR5bmFtaWMgdmFsdWUuXG4gKlxuICogVXNlcnMgbXVzdCB0YWtlIGNhcmUgdG8gZW5zdXJlIHRoYXQgYWRkaW5nIHRoZSBzdGF0aWMgc3RyaW5nIHRvIHRoZSB0ZW1wbGF0ZVxuICogcmVzdWx0cyBpbiB3ZWxsLWZvcm1lZCBIVE1MLCBvciBlbHNlIHRlbXBsYXRlcyBtYXkgYnJlYWsgdW5leHBlY3RlZGx5LlxuICpcbiAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIGlzIHVuc2FmZSB0byB1c2Ugb24gdW50cnVzdGVkIGNvbnRlbnQsIGFzIGl0IHdpbGwgYmVcbiAqIGRpcmVjdGx5IHBhcnNlZCBpbnRvIEhUTUwuIERvIG5vdCBwYXNzIHVzZXIgaW5wdXQgdG8gdGhpcyBmdW5jdGlvblxuICogd2l0aG91dCBzYW5pdGl6aW5nIGl0LlxuICpcbiAqIFN0YXRpYyB2YWx1ZXMgY2FuIGJlIGNoYW5nZWQsIGJ1dCB0aGV5IHdpbGwgY2F1c2UgYSBjb21wbGV0ZSByZS1yZW5kZXJcbiAqIHNpbmNlIHRoZXkgZWZmZWN0aXZlbHkgY3JlYXRlIGEgbmV3IHRlbXBsYXRlLlxuICovXG5leHBvcnQgY29uc3QgdW5zYWZlU3RhdGljID0gKHZhbHVlKSA9PiAoe1xuICAgIFsnXyRsaXRTdGF0aWMkJ106IHZhbHVlLFxuICAgIHI6IGJyYW5kLFxufSk7XG5jb25zdCB0ZXh0RnJvbVN0YXRpYyA9ICh2YWx1ZSkgPT4ge1xuICAgIGlmICh2YWx1ZVsnXyRsaXRTdGF0aWMkJ10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdmFsdWVbJ18kbGl0U3RhdGljJCddO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBWYWx1ZSBwYXNzZWQgdG8gJ2xpdGVyYWwnIGZ1bmN0aW9uIG11c3QgYmUgYSAnbGl0ZXJhbCcgcmVzdWx0OiAke3ZhbHVlfS4gVXNlICd1bnNhZmVTdGF0aWMnIHRvIHBhc3Mgbm9uLWxpdGVyYWwgdmFsdWVzLCBidXRcbiAgICAgICAgICAgIHRha2UgY2FyZSB0byBlbnN1cmUgcGFnZSBzZWN1cml0eS5gKTtcbiAgICB9XG59O1xuLyoqXG4gKiBUYWdzIGEgc3RyaW5nIGxpdGVyYWwgc28gdGhhdCBpdCBiZWhhdmVzIGxpa2UgcGFydCBvZiB0aGUgc3RhdGljIHRlbXBsYXRlXG4gKiBzdHJpbmdzIGluc3RlYWQgb2YgYSBkeW5hbWljIHZhbHVlLlxuICpcbiAqIFRoZSBvbmx5IHZhbHVlcyB0aGF0IG1heSBiZSB1c2VkIGluIHRlbXBsYXRlIGV4cHJlc3Npb25zIGFyZSBvdGhlciB0YWdnZWRcbiAqIGBsaXRlcmFsYCByZXN1bHRzIG9yIGB1bnNhZmVTdGF0aWNgIHZhbHVlcyAobm90ZSB0aGF0IHVudHJ1c3RlZCBjb250ZW50XG4gKiBzaG91bGQgbmV2ZXIgYmUgcGFzc2VkIHRvIGB1bnNhZmVTdGF0aWNgKS5cbiAqXG4gKiBVc2VycyBtdXN0IHRha2UgY2FyZSB0byBlbnN1cmUgdGhhdCBhZGRpbmcgdGhlIHN0YXRpYyBzdHJpbmcgdG8gdGhlIHRlbXBsYXRlXG4gKiByZXN1bHRzIGluIHdlbGwtZm9ybWVkIEhUTUwsIG9yIGVsc2UgdGVtcGxhdGVzIG1heSBicmVhayB1bmV4cGVjdGVkbHkuXG4gKlxuICogU3RhdGljIHZhbHVlcyBjYW4gYmUgY2hhbmdlZCwgYnV0IHRoZXkgd2lsbCBjYXVzZSBhIGNvbXBsZXRlIHJlLXJlbmRlciBzaW5jZVxuICogdGhleSBlZmZlY3RpdmVseSBjcmVhdGUgYSBuZXcgdGVtcGxhdGUuXG4gKi9cbmV4cG9ydCBjb25zdCBsaXRlcmFsID0gKHN0cmluZ3MsIC4uLnZhbHVlcykgPT4gKHtcbiAgICBbJ18kbGl0U3RhdGljJCddOiB2YWx1ZXMucmVkdWNlKChhY2MsIHYsIGlkeCkgPT4gYWNjICsgdGV4dEZyb21TdGF0aWModikgKyBzdHJpbmdzW2lkeCArIDFdLCBzdHJpbmdzWzBdKSxcbiAgICByOiBicmFuZCxcbn0pO1xuY29uc3Qgc3RyaW5nc0NhY2hlID0gbmV3IE1hcCgpO1xuLyoqXG4gKiBXcmFwcyBhIGxpdC1odG1sIHRlbXBsYXRlIHRhZyAoYGh0bWxgIG9yIGBzdmdgKSB0byBhZGQgc3RhdGljIHZhbHVlIHN1cHBvcnQuXG4gKi9cbmV4cG9ydCBjb25zdCB3aXRoU3RhdGljID0gKGNvcmVUYWcpID0+IChzdHJpbmdzLCAuLi52YWx1ZXMpID0+IHtcbiAgICBjb25zdCBsID0gdmFsdWVzLmxlbmd0aDtcbiAgICBsZXQgc3RhdGljVmFsdWU7XG4gICAgbGV0IGR5bmFtaWNWYWx1ZTtcbiAgICBjb25zdCBzdGF0aWNTdHJpbmdzID0gW107XG4gICAgY29uc3QgZHluYW1pY1ZhbHVlcyA9IFtdO1xuICAgIGxldCBpID0gMDtcbiAgICBsZXQgaGFzU3RhdGljcyA9IGZhbHNlO1xuICAgIGxldCBzO1xuICAgIHdoaWxlIChpIDwgbCkge1xuICAgICAgICBzID0gc3RyaW5nc1tpXTtcbiAgICAgICAgLy8gQ29sbGVjdCBhbnkgdW5zYWZlU3RhdGljIHZhbHVlcywgYW5kIHRoZWlyIGZvbGxvd2luZyB0ZW1wbGF0ZSBzdHJpbmdzXG4gICAgICAgIC8vIHNvIHRoYXQgd2UgdHJlYXQgYSBydW4gb2YgdGVtcGxhdGUgc3RyaW5ncyBhbmQgdW5zYWZlIHN0YXRpYyB2YWx1ZXMgYXNcbiAgICAgICAgLy8gYSBzaW5nbGUgdGVtcGxhdGUgc3RyaW5nLlxuICAgICAgICB3aGlsZSAoaSA8IGwgJiZcbiAgICAgICAgICAgICgoZHluYW1pY1ZhbHVlID0gdmFsdWVzW2ldKSxcbiAgICAgICAgICAgICAgICAoc3RhdGljVmFsdWUgPSB1bndyYXBTdGF0aWNWYWx1ZShkeW5hbWljVmFsdWUpKSkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcyArPSBzdGF0aWNWYWx1ZSArIHN0cmluZ3NbKytpXTtcbiAgICAgICAgICAgIGhhc1N0YXRpY3MgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHRoZSBsYXN0IHZhbHVlIGlzIHN0YXRpYywgd2UgZG9uJ3QgbmVlZCB0byBwdXNoIGl0LlxuICAgICAgICBpZiAoaSAhPT0gbCkge1xuICAgICAgICAgICAgZHluYW1pY1ZhbHVlcy5wdXNoKGR5bmFtaWNWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGljU3RyaW5ncy5wdXNoKHMpO1xuICAgICAgICBpKys7XG4gICAgfVxuICAgIC8vIElmIHRoZSBsYXN0IHZhbHVlIGlzbid0IHN0YXRpYyAod2hpY2ggd291bGQgaGF2ZSBjb25zdW1lZCB0aGUgbGFzdFxuICAgIC8vIHN0cmluZyksIHRoZW4gd2UgbmVlZCB0byBhZGQgdGhlIGxhc3Qgc3RyaW5nLlxuICAgIGlmIChpID09PSBsKSB7XG4gICAgICAgIHN0YXRpY1N0cmluZ3MucHVzaChzdHJpbmdzW2xdKTtcbiAgICB9XG4gICAgaWYgKGhhc1N0YXRpY3MpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gc3RhdGljU3RyaW5ncy5qb2luKCckJGxpdCQkJyk7XG4gICAgICAgIHN0cmluZ3MgPSBzdHJpbmdzQ2FjaGUuZ2V0KGtleSk7XG4gICAgICAgIGlmIChzdHJpbmdzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIEJld2FyZTogaW4gZ2VuZXJhbCB0aGlzIHBhdHRlcm4gaXMgdW5zYWZlLCBhbmQgZG9pbmcgc28gbWF5IGJ5cGFzc1xuICAgICAgICAgICAgLy8gbGl0J3Mgc2VjdXJpdHkgY2hlY2tzIGFuZCBhbGxvdyBhbiBhdHRhY2tlciB0byBleGVjdXRlIGFyYml0cmFyeVxuICAgICAgICAgICAgLy8gY29kZSBhbmQgaW5qZWN0IGFyYml0cmFyeSBjb250ZW50LlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgIHN0YXRpY1N0cmluZ3MucmF3ID0gc3RhdGljU3RyaW5ncztcbiAgICAgICAgICAgIHN0cmluZ3NDYWNoZS5zZXQoa2V5LCAoc3RyaW5ncyA9IHN0YXRpY1N0cmluZ3MpKTtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZXMgPSBkeW5hbWljVmFsdWVzO1xuICAgIH1cbiAgICByZXR1cm4gY29yZVRhZyhzdHJpbmdzLCAuLi52YWx1ZXMpO1xufTtcbi8qKlxuICogSW50ZXJwcmV0cyBhIHRlbXBsYXRlIGxpdGVyYWwgYXMgYW4gSFRNTCB0ZW1wbGF0ZSB0aGF0IGNhbiBlZmZpY2llbnRseVxuICogcmVuZGVyIHRvIGFuZCB1cGRhdGUgYSBjb250YWluZXIuXG4gKlxuICogSW5jbHVkZXMgc3RhdGljIHZhbHVlIHN1cHBvcnQgZnJvbSBgbGl0LWh0bWwvc3RhdGljLmpzYC5cbiAqL1xuZXhwb3J0IGNvbnN0IGh0bWwgPSB3aXRoU3RhdGljKGNvcmVIdG1sKTtcbi8qKlxuICogSW50ZXJwcmV0cyBhIHRlbXBsYXRlIGxpdGVyYWwgYXMgYW4gU1ZHIHRlbXBsYXRlIHRoYXQgY2FuIGVmZmljaWVudGx5XG4gKiByZW5kZXIgdG8gYW5kIHVwZGF0ZSBhIGNvbnRhaW5lci5cbiAqXG4gKiBJbmNsdWRlcyBzdGF0aWMgdmFsdWUgc3VwcG9ydCBmcm9tIGBsaXQtaHRtbC9zdGF0aWMuanNgLlxuICovXG5leHBvcnQgY29uc3Qgc3ZnID0gd2l0aFN0YXRpYyhjb3JlU3ZnKTtcbi8qKlxuICogSW50ZXJwcmV0cyBhIHRlbXBsYXRlIGxpdGVyYWwgYXMgTWF0aE1MIGZyYWdtZW50IHRoYXQgY2FuIGVmZmljaWVudGx5IHJlbmRlclxuICogdG8gYW5kIHVwZGF0ZSBhIGNvbnRhaW5lci5cbiAqXG4gKiBJbmNsdWRlcyBzdGF0aWMgdmFsdWUgc3VwcG9ydCBmcm9tIGBsaXQtaHRtbC9zdGF0aWMuanNgLlxuICovXG5leHBvcnQgY29uc3QgbWF0aG1sID0gd2l0aFN0YXRpYyhjb3JlTWF0aG1sKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXRpYy5qcy5tYXAiLCJleHBvcnQqZnJvbVwibGl0LWh0bWwvZGlyZWN0aXZlcy9saXZlLmpzXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saXZlLmpzLm1hcFxuIiwiZXhwb3J0KmZyb21cImxpdC1odG1sL2RpcmVjdGl2ZXMvc3R5bGUtbWFwLmpzXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdHlsZS1tYXAuanMubWFwXG4iLCJleHBvcnQqZnJvbVwibGl0LWh0bWwvc3RhdGljLmpzXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGF0aWMtaHRtbC5qcy5tYXBcbiIsIlxuLyohIHBha28gMi4xLjAgaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9wYWtvIEBsaWNlbnNlIChNSVQgQU5EIFpsaWIpICovXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbi8qIGVzbGludC1kaXNhYmxlIHNwYWNlLXVuYXJ5LW9wcyAqL1xuXG4vKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vL2NvbnN0IFpfRklMVEVSRUQgICAgICAgICAgPSAxO1xuLy9jb25zdCBaX0hVRkZNQU5fT05MWSAgICAgID0gMjtcbi8vY29uc3QgWl9STEUgICAgICAgICAgICAgICA9IDM7XG5jb25zdCBaX0ZJWEVEJDEgICAgICAgICAgICAgICA9IDQ7XG4vL2NvbnN0IFpfREVGQVVMVF9TVFJBVEVHWSAgPSAwO1xuXG4vKiBQb3NzaWJsZSB2YWx1ZXMgb2YgdGhlIGRhdGFfdHlwZSBmaWVsZCAodGhvdWdoIHNlZSBpbmZsYXRlKCkpICovXG5jb25zdCBaX0JJTkFSWSAgICAgICAgICAgICAgPSAwO1xuY29uc3QgWl9URVhUICAgICAgICAgICAgICAgID0gMTtcbi8vY29uc3QgWl9BU0NJSSAgICAgICAgICAgICA9IDE7IC8vID0gWl9URVhUXG5jb25zdCBaX1VOS05PV04kMSAgICAgICAgICAgICA9IDI7XG5cbi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuZnVuY3Rpb24gemVybyQxKGJ1ZikgeyBsZXQgbGVuID0gYnVmLmxlbmd0aDsgd2hpbGUgKC0tbGVuID49IDApIHsgYnVmW2xlbl0gPSAwOyB9IH1cblxuLy8gRnJvbSB6dXRpbC5oXG5cbmNvbnN0IFNUT1JFRF9CTE9DSyA9IDA7XG5jb25zdCBTVEFUSUNfVFJFRVMgPSAxO1xuY29uc3QgRFlOX1RSRUVTICAgID0gMjtcbi8qIFRoZSB0aHJlZSBraW5kcyBvZiBibG9jayB0eXBlICovXG5cbmNvbnN0IE1JTl9NQVRDSCQxICAgID0gMztcbmNvbnN0IE1BWF9NQVRDSCQxICAgID0gMjU4O1xuLyogVGhlIG1pbmltdW0gYW5kIG1heGltdW0gbWF0Y2ggbGVuZ3RocyAqL1xuXG4vLyBGcm9tIGRlZmxhdGUuaFxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBJbnRlcm5hbCBjb21wcmVzc2lvbiBzdGF0ZS5cbiAqL1xuXG5jb25zdCBMRU5HVEhfQ09ERVMkMSAgPSAyOTtcbi8qIG51bWJlciBvZiBsZW5ndGggY29kZXMsIG5vdCBjb3VudGluZyB0aGUgc3BlY2lhbCBFTkRfQkxPQ0sgY29kZSAqL1xuXG5jb25zdCBMSVRFUkFMUyQxICAgICAgPSAyNTY7XG4vKiBudW1iZXIgb2YgbGl0ZXJhbCBieXRlcyAwLi4yNTUgKi9cblxuY29uc3QgTF9DT0RFUyQxICAgICAgID0gTElURVJBTFMkMSArIDEgKyBMRU5HVEhfQ09ERVMkMTtcbi8qIG51bWJlciBvZiBMaXRlcmFsIG9yIExlbmd0aCBjb2RlcywgaW5jbHVkaW5nIHRoZSBFTkRfQkxPQ0sgY29kZSAqL1xuXG5jb25zdCBEX0NPREVTJDEgICAgICAgPSAzMDtcbi8qIG51bWJlciBvZiBkaXN0YW5jZSBjb2RlcyAqL1xuXG5jb25zdCBCTF9DT0RFUyQxICAgICAgPSAxOTtcbi8qIG51bWJlciBvZiBjb2RlcyB1c2VkIHRvIHRyYW5zZmVyIHRoZSBiaXQgbGVuZ3RocyAqL1xuXG5jb25zdCBIRUFQX1NJWkUkMSAgICAgPSAyICogTF9DT0RFUyQxICsgMTtcbi8qIG1heGltdW0gaGVhcCBzaXplICovXG5cbmNvbnN0IE1BWF9CSVRTJDEgICAgICA9IDE1O1xuLyogQWxsIGNvZGVzIG11c3Qgbm90IGV4Y2VlZCBNQVhfQklUUyBiaXRzICovXG5cbmNvbnN0IEJ1Zl9zaXplICAgICAgPSAxNjtcbi8qIHNpemUgb2YgYml0IGJ1ZmZlciBpbiBiaV9idWYgKi9cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE1BWF9CTF9CSVRTID0gNztcbi8qIEJpdCBsZW5ndGggY29kZXMgbXVzdCBub3QgZXhjZWVkIE1BWF9CTF9CSVRTIGJpdHMgKi9cblxuY29uc3QgRU5EX0JMT0NLICAgPSAyNTY7XG4vKiBlbmQgb2YgYmxvY2sgbGl0ZXJhbCBjb2RlICovXG5cbmNvbnN0IFJFUF8zXzYgICAgID0gMTY7XG4vKiByZXBlYXQgcHJldmlvdXMgYml0IGxlbmd0aCAzLTYgdGltZXMgKDIgYml0cyBvZiByZXBlYXQgY291bnQpICovXG5cbmNvbnN0IFJFUFpfM18xMCAgID0gMTc7XG4vKiByZXBlYXQgYSB6ZXJvIGxlbmd0aCAzLTEwIHRpbWVzICAoMyBiaXRzIG9mIHJlcGVhdCBjb3VudCkgKi9cblxuY29uc3QgUkVQWl8xMV8xMzggPSAxODtcbi8qIHJlcGVhdCBhIHplcm8gbGVuZ3RoIDExLTEzOCB0aW1lcyAgKDcgYml0cyBvZiByZXBlYXQgY291bnQpICovXG5cbi8qIGVzbGludC1kaXNhYmxlIGNvbW1hLXNwYWNpbmcsYXJyYXktYnJhY2tldC1zcGFjaW5nICovXG5jb25zdCBleHRyYV9sYml0cyA9ICAgLyogZXh0cmEgYml0cyBmb3IgZWFjaCBsZW5ndGggY29kZSAqL1xuICBuZXcgVWludDhBcnJheShbMCwwLDAsMCwwLDAsMCwwLDEsMSwxLDEsMiwyLDIsMiwzLDMsMywzLDQsNCw0LDQsNSw1LDUsNSwwXSk7XG5cbmNvbnN0IGV4dHJhX2RiaXRzID0gICAvKiBleHRyYSBiaXRzIGZvciBlYWNoIGRpc3RhbmNlIGNvZGUgKi9cbiAgbmV3IFVpbnQ4QXJyYXkoWzAsMCwwLDAsMSwxLDIsMiwzLDMsNCw0LDUsNSw2LDYsNyw3LDgsOCw5LDksMTAsMTAsMTEsMTEsMTIsMTIsMTMsMTNdKTtcblxuY29uc3QgZXh0cmFfYmxiaXRzID0gIC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggYml0IGxlbmd0aCBjb2RlICovXG4gIG5ldyBVaW50OEFycmF5KFswLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDIsMyw3XSk7XG5cbmNvbnN0IGJsX29yZGVyID1cbiAgbmV3IFVpbnQ4QXJyYXkoWzE2LDE3LDE4LDAsOCw3LDksNiwxMCw1LDExLDQsMTIsMywxMywyLDE0LDEsMTVdKTtcbi8qIGVzbGludC1lbmFibGUgY29tbWEtc3BhY2luZyxhcnJheS1icmFja2V0LXNwYWNpbmcgKi9cblxuLyogVGhlIGxlbmd0aHMgb2YgdGhlIGJpdCBsZW5ndGggY29kZXMgYXJlIHNlbnQgaW4gb3JkZXIgb2YgZGVjcmVhc2luZ1xuICogcHJvYmFiaWxpdHksIHRvIGF2b2lkIHRyYW5zbWl0dGluZyB0aGUgbGVuZ3RocyBmb3IgdW51c2VkIGJpdCBsZW5ndGggY29kZXMuXG4gKi9cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBMb2NhbCBkYXRhLiBUaGVzZSBhcmUgaW5pdGlhbGl6ZWQgb25seSBvbmNlLlxuICovXG5cbi8vIFdlIHByZS1maWxsIGFycmF5cyB3aXRoIDAgdG8gYXZvaWQgdW5pbml0aWFsaXplZCBnYXBzXG5cbmNvbnN0IERJU1RfQ09ERV9MRU4gPSA1MTI7IC8qIHNlZSBkZWZpbml0aW9uIG9mIGFycmF5IGRpc3RfY29kZSBiZWxvdyAqL1xuXG4vLyAhISEhIFVzZSBmbGF0IGFycmF5IGluc3RlYWQgb2Ygc3RydWN0dXJlLCBGcmVxID0gaSoyLCBMZW4gPSBpKjIrMVxuY29uc3Qgc3RhdGljX2x0cmVlICA9IG5ldyBBcnJheSgoTF9DT0RFUyQxICsgMikgKiAyKTtcbnplcm8kMShzdGF0aWNfbHRyZWUpO1xuLyogVGhlIHN0YXRpYyBsaXRlcmFsIHRyZWUuIFNpbmNlIHRoZSBiaXQgbGVuZ3RocyBhcmUgaW1wb3NlZCwgdGhlcmUgaXMgbm9cbiAqIG5lZWQgZm9yIHRoZSBMX0NPREVTIGV4dHJhIGNvZGVzIHVzZWQgZHVyaW5nIGhlYXAgY29uc3RydWN0aW9uLiBIb3dldmVyXG4gKiBUaGUgY29kZXMgMjg2IGFuZCAyODcgYXJlIG5lZWRlZCB0byBidWlsZCBhIGNhbm9uaWNhbCB0cmVlIChzZWUgX3RyX2luaXRcbiAqIGJlbG93KS5cbiAqL1xuXG5jb25zdCBzdGF0aWNfZHRyZWUgID0gbmV3IEFycmF5KERfQ09ERVMkMSAqIDIpO1xuemVybyQxKHN0YXRpY19kdHJlZSk7XG4vKiBUaGUgc3RhdGljIGRpc3RhbmNlIHRyZWUuIChBY3R1YWxseSBhIHRyaXZpYWwgdHJlZSBzaW5jZSBhbGwgY29kZXMgdXNlXG4gKiA1IGJpdHMuKVxuICovXG5cbmNvbnN0IF9kaXN0X2NvZGUgICAgPSBuZXcgQXJyYXkoRElTVF9DT0RFX0xFTik7XG56ZXJvJDEoX2Rpc3RfY29kZSk7XG4vKiBEaXN0YW5jZSBjb2Rlcy4gVGhlIGZpcnN0IDI1NiB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUgZGlzdGFuY2VzXG4gKiAzIC4uIDI1OCwgdGhlIGxhc3QgMjU2IHZhbHVlcyBjb3JyZXNwb25kIHRvIHRoZSB0b3AgOCBiaXRzIG9mXG4gKiB0aGUgMTUgYml0IGRpc3RhbmNlcy5cbiAqL1xuXG5jb25zdCBfbGVuZ3RoX2NvZGUgID0gbmV3IEFycmF5KE1BWF9NQVRDSCQxIC0gTUlOX01BVENIJDEgKyAxKTtcbnplcm8kMShfbGVuZ3RoX2NvZGUpO1xuLyogbGVuZ3RoIGNvZGUgZm9yIGVhY2ggbm9ybWFsaXplZCBtYXRjaCBsZW5ndGggKDAgPT0gTUlOX01BVENIKSAqL1xuXG5jb25zdCBiYXNlX2xlbmd0aCAgID0gbmV3IEFycmF5KExFTkdUSF9DT0RFUyQxKTtcbnplcm8kMShiYXNlX2xlbmd0aCk7XG4vKiBGaXJzdCBub3JtYWxpemVkIGxlbmd0aCBmb3IgZWFjaCBjb2RlICgwID0gTUlOX01BVENIKSAqL1xuXG5jb25zdCBiYXNlX2Rpc3QgICAgID0gbmV3IEFycmF5KERfQ09ERVMkMSk7XG56ZXJvJDEoYmFzZV9kaXN0KTtcbi8qIEZpcnN0IG5vcm1hbGl6ZWQgZGlzdGFuY2UgZm9yIGVhY2ggY29kZSAoMCA9IGRpc3RhbmNlIG9mIDEpICovXG5cblxuZnVuY3Rpb24gU3RhdGljVHJlZURlc2Moc3RhdGljX3RyZWUsIGV4dHJhX2JpdHMsIGV4dHJhX2Jhc2UsIGVsZW1zLCBtYXhfbGVuZ3RoKSB7XG5cbiAgdGhpcy5zdGF0aWNfdHJlZSAgPSBzdGF0aWNfdHJlZTsgIC8qIHN0YXRpYyB0cmVlIG9yIE5VTEwgKi9cbiAgdGhpcy5leHRyYV9iaXRzICAgPSBleHRyYV9iaXRzOyAgIC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggY29kZSBvciBOVUxMICovXG4gIHRoaXMuZXh0cmFfYmFzZSAgID0gZXh0cmFfYmFzZTsgICAvKiBiYXNlIGluZGV4IGZvciBleHRyYV9iaXRzICovXG4gIHRoaXMuZWxlbXMgICAgICAgID0gZWxlbXM7ICAgICAgICAvKiBtYXggbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSB0cmVlICovXG4gIHRoaXMubWF4X2xlbmd0aCAgID0gbWF4X2xlbmd0aDsgICAvKiBtYXggYml0IGxlbmd0aCBmb3IgdGhlIGNvZGVzICovXG5cbiAgLy8gc2hvdyBpZiBgc3RhdGljX3RyZWVgIGhhcyBkYXRhIG9yIGR1bW15IC0gbmVlZGVkIGZvciBtb25vbW9ycGhpYyBvYmplY3RzXG4gIHRoaXMuaGFzX3N0cmVlICAgID0gc3RhdGljX3RyZWUgJiYgc3RhdGljX3RyZWUubGVuZ3RoO1xufVxuXG5cbmxldCBzdGF0aWNfbF9kZXNjO1xubGV0IHN0YXRpY19kX2Rlc2M7XG5sZXQgc3RhdGljX2JsX2Rlc2M7XG5cblxuZnVuY3Rpb24gVHJlZURlc2MoZHluX3RyZWUsIHN0YXRfZGVzYykge1xuICB0aGlzLmR5bl90cmVlID0gZHluX3RyZWU7ICAgICAvKiB0aGUgZHluYW1pYyB0cmVlICovXG4gIHRoaXMubWF4X2NvZGUgPSAwOyAgICAgICAgICAgIC8qIGxhcmdlc3QgY29kZSB3aXRoIG5vbiB6ZXJvIGZyZXF1ZW5jeSAqL1xuICB0aGlzLnN0YXRfZGVzYyA9IHN0YXRfZGVzYzsgICAvKiB0aGUgY29ycmVzcG9uZGluZyBzdGF0aWMgdHJlZSAqL1xufVxuXG5cblxuY29uc3QgZF9jb2RlID0gKGRpc3QpID0+IHtcblxuICByZXR1cm4gZGlzdCA8IDI1NiA/IF9kaXN0X2NvZGVbZGlzdF0gOiBfZGlzdF9jb2RlWzI1NiArIChkaXN0ID4+PiA3KV07XG59O1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogT3V0cHV0IGEgc2hvcnQgTFNCIGZpcnN0IG9uIHRoZSBzdHJlYW0uXG4gKiBJTiBhc3NlcnRpb246IHRoZXJlIGlzIGVub3VnaCByb29tIGluIHBlbmRpbmdCdWYuXG4gKi9cbmNvbnN0IHB1dF9zaG9ydCA9IChzLCB3KSA9PiB7XG4vLyAgICBwdXRfYnl0ZShzLCAodWNoKSgodykgJiAweGZmKSk7XG4vLyAgICBwdXRfYnl0ZShzLCAodWNoKSgodXNoKSh3KSA+PiA4KSk7XG4gIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gKHcpICYgMHhmZjtcbiAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSAodyA+Pj4gOCkgJiAweGZmO1xufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgYSB2YWx1ZSBvbiBhIGdpdmVuIG51bWJlciBvZiBiaXRzLlxuICogSU4gYXNzZXJ0aW9uOiBsZW5ndGggPD0gMTYgYW5kIHZhbHVlIGZpdHMgaW4gbGVuZ3RoIGJpdHMuXG4gKi9cbmNvbnN0IHNlbmRfYml0cyA9IChzLCB2YWx1ZSwgbGVuZ3RoKSA9PiB7XG5cbiAgaWYgKHMuYmlfdmFsaWQgPiAoQnVmX3NpemUgLSBsZW5ndGgpKSB7XG4gICAgcy5iaV9idWYgfD0gKHZhbHVlIDw8IHMuYmlfdmFsaWQpICYgMHhmZmZmO1xuICAgIHB1dF9zaG9ydChzLCBzLmJpX2J1Zik7XG4gICAgcy5iaV9idWYgPSB2YWx1ZSA+PiAoQnVmX3NpemUgLSBzLmJpX3ZhbGlkKTtcbiAgICBzLmJpX3ZhbGlkICs9IGxlbmd0aCAtIEJ1Zl9zaXplO1xuICB9IGVsc2Uge1xuICAgIHMuYmlfYnVmIHw9ICh2YWx1ZSA8PCBzLmJpX3ZhbGlkKSAmIDB4ZmZmZjtcbiAgICBzLmJpX3ZhbGlkICs9IGxlbmd0aDtcbiAgfVxufTtcblxuXG5jb25zdCBzZW5kX2NvZGUgPSAocywgYywgdHJlZSkgPT4ge1xuXG4gIHNlbmRfYml0cyhzLCB0cmVlW2MgKiAyXS8qLkNvZGUqLywgdHJlZVtjICogMiArIDFdLyouTGVuKi8pO1xufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFJldmVyc2UgdGhlIGZpcnN0IGxlbiBiaXRzIG9mIGEgY29kZSwgdXNpbmcgc3RyYWlnaHRmb3J3YXJkIGNvZGUgKGEgZmFzdGVyXG4gKiBtZXRob2Qgd291bGQgdXNlIGEgdGFibGUpXG4gKiBJTiBhc3NlcnRpb246IDEgPD0gbGVuIDw9IDE1XG4gKi9cbmNvbnN0IGJpX3JldmVyc2UgPSAoY29kZSwgbGVuKSA9PiB7XG5cbiAgbGV0IHJlcyA9IDA7XG4gIGRvIHtcbiAgICByZXMgfD0gY29kZSAmIDE7XG4gICAgY29kZSA+Pj49IDE7XG4gICAgcmVzIDw8PSAxO1xuICB9IHdoaWxlICgtLWxlbiA+IDApO1xuICByZXR1cm4gcmVzID4+PiAxO1xufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZsdXNoIHRoZSBiaXQgYnVmZmVyLCBrZWVwaW5nIGF0IG1vc3QgNyBiaXRzIGluIGl0LlxuICovXG5jb25zdCBiaV9mbHVzaCA9IChzKSA9PiB7XG5cbiAgaWYgKHMuYmlfdmFsaWQgPT09IDE2KSB7XG4gICAgcHV0X3Nob3J0KHMsIHMuYmlfYnVmKTtcbiAgICBzLmJpX2J1ZiA9IDA7XG4gICAgcy5iaV92YWxpZCA9IDA7XG5cbiAgfSBlbHNlIGlmIChzLmJpX3ZhbGlkID49IDgpIHtcbiAgICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IHMuYmlfYnVmICYgMHhmZjtcbiAgICBzLmJpX2J1ZiA+Pj0gODtcbiAgICBzLmJpX3ZhbGlkIC09IDg7XG4gIH1cbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb21wdXRlIHRoZSBvcHRpbWFsIGJpdCBsZW5ndGhzIGZvciBhIHRyZWUgYW5kIHVwZGF0ZSB0aGUgdG90YWwgYml0IGxlbmd0aFxuICogZm9yIHRoZSBjdXJyZW50IGJsb2NrLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGRzIGZyZXEgYW5kIGRhZCBhcmUgc2V0LCBoZWFwW2hlYXBfbWF4XSBhbmRcbiAqICAgIGFib3ZlIGFyZSB0aGUgdHJlZSBub2RlcyBzb3J0ZWQgYnkgaW5jcmVhc2luZyBmcmVxdWVuY3kuXG4gKiBPVVQgYXNzZXJ0aW9uczogdGhlIGZpZWxkIGxlbiBpcyBzZXQgdG8gdGhlIG9wdGltYWwgYml0IGxlbmd0aCwgdGhlXG4gKiAgICAgYXJyYXkgYmxfY291bnQgY29udGFpbnMgdGhlIGZyZXF1ZW5jaWVzIGZvciBlYWNoIGJpdCBsZW5ndGguXG4gKiAgICAgVGhlIGxlbmd0aCBvcHRfbGVuIGlzIHVwZGF0ZWQ7IHN0YXRpY19sZW4gaXMgYWxzbyB1cGRhdGVkIGlmIHN0cmVlIGlzXG4gKiAgICAgbm90IG51bGwuXG4gKi9cbmNvbnN0IGdlbl9iaXRsZW4gPSAocywgZGVzYykgPT4ge1xuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIHRyZWVfZGVzYyAqZGVzYzsgICAgLyogdGhlIHRyZWUgZGVzY3JpcHRvciAqL1xuXG4gIGNvbnN0IHRyZWUgICAgICAgICAgICA9IGRlc2MuZHluX3RyZWU7XG4gIGNvbnN0IG1heF9jb2RlICAgICAgICA9IGRlc2MubWF4X2NvZGU7XG4gIGNvbnN0IHN0cmVlICAgICAgICAgICA9IGRlc2Muc3RhdF9kZXNjLnN0YXRpY190cmVlO1xuICBjb25zdCBoYXNfc3RyZWUgICAgICAgPSBkZXNjLnN0YXRfZGVzYy5oYXNfc3RyZWU7XG4gIGNvbnN0IGV4dHJhICAgICAgICAgICA9IGRlc2Muc3RhdF9kZXNjLmV4dHJhX2JpdHM7XG4gIGNvbnN0IGJhc2UgICAgICAgICAgICA9IGRlc2Muc3RhdF9kZXNjLmV4dHJhX2Jhc2U7XG4gIGNvbnN0IG1heF9sZW5ndGggICAgICA9IGRlc2Muc3RhdF9kZXNjLm1heF9sZW5ndGg7XG4gIGxldCBoOyAgICAgICAgICAgICAgLyogaGVhcCBpbmRleCAqL1xuICBsZXQgbiwgbTsgICAgICAgICAgIC8qIGl0ZXJhdGUgb3ZlciB0aGUgdHJlZSBlbGVtZW50cyAqL1xuICBsZXQgYml0czsgICAgICAgICAgIC8qIGJpdCBsZW5ndGggKi9cbiAgbGV0IHhiaXRzOyAgICAgICAgICAvKiBleHRyYSBiaXRzICovXG4gIGxldCBmOyAgICAgICAgICAgICAgLyogZnJlcXVlbmN5ICovXG4gIGxldCBvdmVyZmxvdyA9IDA7ICAgLyogbnVtYmVyIG9mIGVsZW1lbnRzIHdpdGggYml0IGxlbmd0aCB0b28gbGFyZ2UgKi9cblxuICBmb3IgKGJpdHMgPSAwOyBiaXRzIDw9IE1BWF9CSVRTJDE7IGJpdHMrKykge1xuICAgIHMuYmxfY291bnRbYml0c10gPSAwO1xuICB9XG5cbiAgLyogSW4gYSBmaXJzdCBwYXNzLCBjb21wdXRlIHRoZSBvcHRpbWFsIGJpdCBsZW5ndGhzICh3aGljaCBtYXlcbiAgICogb3ZlcmZsb3cgaW4gdGhlIGNhc2Ugb2YgdGhlIGJpdCBsZW5ndGggdHJlZSkuXG4gICAqL1xuICB0cmVlW3MuaGVhcFtzLmhlYXBfbWF4XSAqIDIgKyAxXS8qLkxlbiovID0gMDsgLyogcm9vdCBvZiB0aGUgaGVhcCAqL1xuXG4gIGZvciAoaCA9IHMuaGVhcF9tYXggKyAxOyBoIDwgSEVBUF9TSVpFJDE7IGgrKykge1xuICAgIG4gPSBzLmhlYXBbaF07XG4gICAgYml0cyA9IHRyZWVbdHJlZVtuICogMiArIDFdLyouRGFkKi8gKiAyICsgMV0vKi5MZW4qLyArIDE7XG4gICAgaWYgKGJpdHMgPiBtYXhfbGVuZ3RoKSB7XG4gICAgICBiaXRzID0gbWF4X2xlbmd0aDtcbiAgICAgIG92ZXJmbG93Kys7XG4gICAgfVxuICAgIHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gYml0cztcbiAgICAvKiBXZSBvdmVyd3JpdGUgdHJlZVtuXS5EYWQgd2hpY2ggaXMgbm8gbG9uZ2VyIG5lZWRlZCAqL1xuXG4gICAgaWYgKG4gPiBtYXhfY29kZSkgeyBjb250aW51ZTsgfSAvKiBub3QgYSBsZWFmIG5vZGUgKi9cblxuICAgIHMuYmxfY291bnRbYml0c10rKztcbiAgICB4Yml0cyA9IDA7XG4gICAgaWYgKG4gPj0gYmFzZSkge1xuICAgICAgeGJpdHMgPSBleHRyYVtuIC0gYmFzZV07XG4gICAgfVxuICAgIGYgPSB0cmVlW24gKiAyXS8qLkZyZXEqLztcbiAgICBzLm9wdF9sZW4gKz0gZiAqIChiaXRzICsgeGJpdHMpO1xuICAgIGlmIChoYXNfc3RyZWUpIHtcbiAgICAgIHMuc3RhdGljX2xlbiArPSBmICogKHN0cmVlW24gKiAyICsgMV0vKi5MZW4qLyArIHhiaXRzKTtcbiAgICB9XG4gIH1cbiAgaWYgKG92ZXJmbG93ID09PSAwKSB7IHJldHVybjsgfVxuXG4gIC8vIFRyYWNldigoc3RkZXJyLFwiXFxuYml0IGxlbmd0aCBvdmVyZmxvd1xcblwiKSk7XG4gIC8qIFRoaXMgaGFwcGVucyBmb3IgZXhhbXBsZSBvbiBvYmoyIGFuZCBwaWMgb2YgdGhlIENhbGdhcnkgY29ycHVzICovXG5cbiAgLyogRmluZCB0aGUgZmlyc3QgYml0IGxlbmd0aCB3aGljaCBjb3VsZCBpbmNyZWFzZTogKi9cbiAgZG8ge1xuICAgIGJpdHMgPSBtYXhfbGVuZ3RoIC0gMTtcbiAgICB3aGlsZSAocy5ibF9jb3VudFtiaXRzXSA9PT0gMCkgeyBiaXRzLS07IH1cbiAgICBzLmJsX2NvdW50W2JpdHNdLS07ICAgICAgLyogbW92ZSBvbmUgbGVhZiBkb3duIHRoZSB0cmVlICovXG4gICAgcy5ibF9jb3VudFtiaXRzICsgMV0gKz0gMjsgLyogbW92ZSBvbmUgb3ZlcmZsb3cgaXRlbSBhcyBpdHMgYnJvdGhlciAqL1xuICAgIHMuYmxfY291bnRbbWF4X2xlbmd0aF0tLTtcbiAgICAvKiBUaGUgYnJvdGhlciBvZiB0aGUgb3ZlcmZsb3cgaXRlbSBhbHNvIG1vdmVzIG9uZSBzdGVwIHVwLFxuICAgICAqIGJ1dCB0aGlzIGRvZXMgbm90IGFmZmVjdCBibF9jb3VudFttYXhfbGVuZ3RoXVxuICAgICAqL1xuICAgIG92ZXJmbG93IC09IDI7XG4gIH0gd2hpbGUgKG92ZXJmbG93ID4gMCk7XG5cbiAgLyogTm93IHJlY29tcHV0ZSBhbGwgYml0IGxlbmd0aHMsIHNjYW5uaW5nIGluIGluY3JlYXNpbmcgZnJlcXVlbmN5LlxuICAgKiBoIGlzIHN0aWxsIGVxdWFsIHRvIEhFQVBfU0laRS4gKEl0IGlzIHNpbXBsZXIgdG8gcmVjb25zdHJ1Y3QgYWxsXG4gICAqIGxlbmd0aHMgaW5zdGVhZCBvZiBmaXhpbmcgb25seSB0aGUgd3Jvbmcgb25lcy4gVGhpcyBpZGVhIGlzIHRha2VuXG4gICAqIGZyb20gJ2FyJyB3cml0dGVuIGJ5IEhhcnVoaWtvIE9rdW11cmEuKVxuICAgKi9cbiAgZm9yIChiaXRzID0gbWF4X2xlbmd0aDsgYml0cyAhPT0gMDsgYml0cy0tKSB7XG4gICAgbiA9IHMuYmxfY291bnRbYml0c107XG4gICAgd2hpbGUgKG4gIT09IDApIHtcbiAgICAgIG0gPSBzLmhlYXBbLS1oXTtcbiAgICAgIGlmIChtID4gbWF4X2NvZGUpIHsgY29udGludWU7IH1cbiAgICAgIGlmICh0cmVlW20gKiAyICsgMV0vKi5MZW4qLyAhPT0gYml0cykge1xuICAgICAgICAvLyBUcmFjZXYoKHN0ZGVycixcImNvZGUgJWQgYml0cyAlZC0+JWRcXG5cIiwgbSwgdHJlZVttXS5MZW4sIGJpdHMpKTtcbiAgICAgICAgcy5vcHRfbGVuICs9IChiaXRzIC0gdHJlZVttICogMiArIDFdLyouTGVuKi8pICogdHJlZVttICogMl0vKi5GcmVxKi87XG4gICAgICAgIHRyZWVbbSAqIDIgKyAxXS8qLkxlbiovID0gYml0cztcbiAgICAgIH1cbiAgICAgIG4tLTtcbiAgICB9XG4gIH1cbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBHZW5lcmF0ZSB0aGUgY29kZXMgZm9yIGEgZ2l2ZW4gdHJlZSBhbmQgYml0IGNvdW50cyAod2hpY2ggbmVlZCBub3QgYmVcbiAqIG9wdGltYWwpLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgYXJyYXkgYmxfY291bnQgY29udGFpbnMgdGhlIGJpdCBsZW5ndGggc3RhdGlzdGljcyBmb3JcbiAqIHRoZSBnaXZlbiB0cmVlIGFuZCB0aGUgZmllbGQgbGVuIGlzIHNldCBmb3IgYWxsIHRyZWUgZWxlbWVudHMuXG4gKiBPVVQgYXNzZXJ0aW9uOiB0aGUgZmllbGQgY29kZSBpcyBzZXQgZm9yIGFsbCB0cmVlIGVsZW1lbnRzIG9mIG5vblxuICogICAgIHplcm8gY29kZSBsZW5ndGguXG4gKi9cbmNvbnN0IGdlbl9jb2RlcyA9ICh0cmVlLCBtYXhfY29kZSwgYmxfY291bnQpID0+IHtcbi8vICAgIGN0X2RhdGEgKnRyZWU7ICAgICAgICAgICAgIC8qIHRoZSB0cmVlIHRvIGRlY29yYXRlICovXG4vLyAgICBpbnQgbWF4X2NvZGU7ICAgICAgICAgICAgICAvKiBsYXJnZXN0IGNvZGUgd2l0aCBub24gemVybyBmcmVxdWVuY3kgKi9cbi8vICAgIHVzaGYgKmJsX2NvdW50OyAgICAgICAgICAgIC8qIG51bWJlciBvZiBjb2RlcyBhdCBlYWNoIGJpdCBsZW5ndGggKi9cblxuICBjb25zdCBuZXh0X2NvZGUgPSBuZXcgQXJyYXkoTUFYX0JJVFMkMSArIDEpOyAvKiBuZXh0IGNvZGUgdmFsdWUgZm9yIGVhY2ggYml0IGxlbmd0aCAqL1xuICBsZXQgY29kZSA9IDA7ICAgICAgICAgICAgICAvKiBydW5uaW5nIGNvZGUgdmFsdWUgKi9cbiAgbGV0IGJpdHM7ICAgICAgICAgICAgICAgICAgLyogYml0IGluZGV4ICovXG4gIGxldCBuOyAgICAgICAgICAgICAgICAgICAgIC8qIGNvZGUgaW5kZXggKi9cblxuICAvKiBUaGUgZGlzdHJpYnV0aW9uIGNvdW50cyBhcmUgZmlyc3QgdXNlZCB0byBnZW5lcmF0ZSB0aGUgY29kZSB2YWx1ZXNcbiAgICogd2l0aG91dCBiaXQgcmV2ZXJzYWwuXG4gICAqL1xuICBmb3IgKGJpdHMgPSAxOyBiaXRzIDw9IE1BWF9CSVRTJDE7IGJpdHMrKykge1xuICAgIGNvZGUgPSAoY29kZSArIGJsX2NvdW50W2JpdHMgLSAxXSkgPDwgMTtcbiAgICBuZXh0X2NvZGVbYml0c10gPSBjb2RlO1xuICB9XG4gIC8qIENoZWNrIHRoYXQgdGhlIGJpdCBjb3VudHMgaW4gYmxfY291bnQgYXJlIGNvbnNpc3RlbnQuIFRoZSBsYXN0IGNvZGVcbiAgICogbXVzdCBiZSBhbGwgb25lcy5cbiAgICovXG4gIC8vQXNzZXJ0IChjb2RlICsgYmxfY291bnRbTUFYX0JJVFNdLTEgPT0gKDE8PE1BWF9CSVRTKS0xLFxuICAvLyAgICAgICAgXCJpbmNvbnNpc3RlbnQgYml0IGNvdW50c1wiKTtcbiAgLy9UcmFjZXYoKHN0ZGVycixcIlxcbmdlbl9jb2RlczogbWF4X2NvZGUgJWQgXCIsIG1heF9jb2RlKSk7XG5cbiAgZm9yIChuID0gMDsgIG4gPD0gbWF4X2NvZGU7IG4rKykge1xuICAgIGxldCBsZW4gPSB0cmVlW24gKiAyICsgMV0vKi5MZW4qLztcbiAgICBpZiAobGVuID09PSAwKSB7IGNvbnRpbnVlOyB9XG4gICAgLyogTm93IHJldmVyc2UgdGhlIGJpdHMgKi9cbiAgICB0cmVlW24gKiAyXS8qLkNvZGUqLyA9IGJpX3JldmVyc2UobmV4dF9jb2RlW2xlbl0rKywgbGVuKTtcblxuICAgIC8vVHJhY2Vjdih0cmVlICE9IHN0YXRpY19sdHJlZSwgKHN0ZGVycixcIlxcbm4gJTNkICVjIGwgJTJkIGMgJTR4ICgleCkgXCIsXG4gICAgLy8gICAgIG4sIChpc2dyYXBoKG4pID8gbiA6ICcgJyksIGxlbiwgdHJlZVtuXS5Db2RlLCBuZXh0X2NvZGVbbGVuXS0xKSk7XG4gIH1cbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBJbml0aWFsaXplIHRoZSB2YXJpb3VzICdjb25zdGFudCcgdGFibGVzLlxuICovXG5jb25zdCB0cl9zdGF0aWNfaW5pdCA9ICgpID0+IHtcblxuICBsZXQgbjsgICAgICAgIC8qIGl0ZXJhdGVzIG92ZXIgdHJlZSBlbGVtZW50cyAqL1xuICBsZXQgYml0czsgICAgIC8qIGJpdCBjb3VudGVyICovXG4gIGxldCBsZW5ndGg7ICAgLyogbGVuZ3RoIHZhbHVlICovXG4gIGxldCBjb2RlOyAgICAgLyogY29kZSB2YWx1ZSAqL1xuICBsZXQgZGlzdDsgICAgIC8qIGRpc3RhbmNlIGluZGV4ICovXG4gIGNvbnN0IGJsX2NvdW50ID0gbmV3IEFycmF5KE1BWF9CSVRTJDEgKyAxKTtcbiAgLyogbnVtYmVyIG9mIGNvZGVzIGF0IGVhY2ggYml0IGxlbmd0aCBmb3IgYW4gb3B0aW1hbCB0cmVlICovXG5cbiAgLy8gZG8gY2hlY2sgaW4gX3RyX2luaXQoKVxuICAvL2lmIChzdGF0aWNfaW5pdF9kb25lKSByZXR1cm47XG5cbiAgLyogRm9yIHNvbWUgZW1iZWRkZWQgdGFyZ2V0cywgZ2xvYmFsIHZhcmlhYmxlcyBhcmUgbm90IGluaXRpYWxpemVkOiAqL1xuLyojaWZkZWYgTk9fSU5JVF9HTE9CQUxfUE9JTlRFUlNcbiAgc3RhdGljX2xfZGVzYy5zdGF0aWNfdHJlZSA9IHN0YXRpY19sdHJlZTtcbiAgc3RhdGljX2xfZGVzYy5leHRyYV9iaXRzID0gZXh0cmFfbGJpdHM7XG4gIHN0YXRpY19kX2Rlc2Muc3RhdGljX3RyZWUgPSBzdGF0aWNfZHRyZWU7XG4gIHN0YXRpY19kX2Rlc2MuZXh0cmFfYml0cyA9IGV4dHJhX2RiaXRzO1xuICBzdGF0aWNfYmxfZGVzYy5leHRyYV9iaXRzID0gZXh0cmFfYmxiaXRzO1xuI2VuZGlmKi9cblxuICAvKiBJbml0aWFsaXplIHRoZSBtYXBwaW5nIGxlbmd0aCAoMC4uMjU1KSAtPiBsZW5ndGggY29kZSAoMC4uMjgpICovXG4gIGxlbmd0aCA9IDA7XG4gIGZvciAoY29kZSA9IDA7IGNvZGUgPCBMRU5HVEhfQ09ERVMkMSAtIDE7IGNvZGUrKykge1xuICAgIGJhc2VfbGVuZ3RoW2NvZGVdID0gbGVuZ3RoO1xuICAgIGZvciAobiA9IDA7IG4gPCAoMSA8PCBleHRyYV9sYml0c1tjb2RlXSk7IG4rKykge1xuICAgICAgX2xlbmd0aF9jb2RlW2xlbmd0aCsrXSA9IGNvZGU7XG4gICAgfVxuICB9XG4gIC8vQXNzZXJ0IChsZW5ndGggPT0gMjU2LCBcInRyX3N0YXRpY19pbml0OiBsZW5ndGggIT0gMjU2XCIpO1xuICAvKiBOb3RlIHRoYXQgdGhlIGxlbmd0aCAyNTUgKG1hdGNoIGxlbmd0aCAyNTgpIGNhbiBiZSByZXByZXNlbnRlZFxuICAgKiBpbiB0d28gZGlmZmVyZW50IHdheXM6IGNvZGUgMjg0ICsgNSBiaXRzIG9yIGNvZGUgMjg1LCBzbyB3ZVxuICAgKiBvdmVyd3JpdGUgbGVuZ3RoX2NvZGVbMjU1XSB0byB1c2UgdGhlIGJlc3QgZW5jb2Rpbmc6XG4gICAqL1xuICBfbGVuZ3RoX2NvZGVbbGVuZ3RoIC0gMV0gPSBjb2RlO1xuXG4gIC8qIEluaXRpYWxpemUgdGhlIG1hcHBpbmcgZGlzdCAoMC4uMzJLKSAtPiBkaXN0IGNvZGUgKDAuLjI5KSAqL1xuICBkaXN0ID0gMDtcbiAgZm9yIChjb2RlID0gMDsgY29kZSA8IDE2OyBjb2RlKyspIHtcbiAgICBiYXNlX2Rpc3RbY29kZV0gPSBkaXN0O1xuICAgIGZvciAobiA9IDA7IG4gPCAoMSA8PCBleHRyYV9kYml0c1tjb2RlXSk7IG4rKykge1xuICAgICAgX2Rpc3RfY29kZVtkaXN0KytdID0gY29kZTtcbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQgKGRpc3QgPT0gMjU2LCBcInRyX3N0YXRpY19pbml0OiBkaXN0ICE9IDI1NlwiKTtcbiAgZGlzdCA+Pj0gNzsgLyogZnJvbSBub3cgb24sIGFsbCBkaXN0YW5jZXMgYXJlIGRpdmlkZWQgYnkgMTI4ICovXG4gIGZvciAoOyBjb2RlIDwgRF9DT0RFUyQxOyBjb2RlKyspIHtcbiAgICBiYXNlX2Rpc3RbY29kZV0gPSBkaXN0IDw8IDc7XG4gICAgZm9yIChuID0gMDsgbiA8ICgxIDw8IChleHRyYV9kYml0c1tjb2RlXSAtIDcpKTsgbisrKSB7XG4gICAgICBfZGlzdF9jb2RlWzI1NiArIGRpc3QrK10gPSBjb2RlO1xuICAgIH1cbiAgfVxuICAvL0Fzc2VydCAoZGlzdCA9PSAyNTYsIFwidHJfc3RhdGljX2luaXQ6IDI1NitkaXN0ICE9IDUxMlwiKTtcblxuICAvKiBDb25zdHJ1Y3QgdGhlIGNvZGVzIG9mIHRoZSBzdGF0aWMgbGl0ZXJhbCB0cmVlICovXG4gIGZvciAoYml0cyA9IDA7IGJpdHMgPD0gTUFYX0JJVFMkMTsgYml0cysrKSB7XG4gICAgYmxfY291bnRbYml0c10gPSAwO1xuICB9XG5cbiAgbiA9IDA7XG4gIHdoaWxlIChuIDw9IDE0Mykge1xuICAgIHN0YXRpY19sdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSA4O1xuICAgIG4rKztcbiAgICBibF9jb3VudFs4XSsrO1xuICB9XG4gIHdoaWxlIChuIDw9IDI1NSkge1xuICAgIHN0YXRpY19sdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSA5O1xuICAgIG4rKztcbiAgICBibF9jb3VudFs5XSsrO1xuICB9XG4gIHdoaWxlIChuIDw9IDI3OSkge1xuICAgIHN0YXRpY19sdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSA3O1xuICAgIG4rKztcbiAgICBibF9jb3VudFs3XSsrO1xuICB9XG4gIHdoaWxlIChuIDw9IDI4Nykge1xuICAgIHN0YXRpY19sdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSA4O1xuICAgIG4rKztcbiAgICBibF9jb3VudFs4XSsrO1xuICB9XG4gIC8qIENvZGVzIDI4NiBhbmQgMjg3IGRvIG5vdCBleGlzdCwgYnV0IHdlIG11c3QgaW5jbHVkZSB0aGVtIGluIHRoZVxuICAgKiB0cmVlIGNvbnN0cnVjdGlvbiB0byBnZXQgYSBjYW5vbmljYWwgSHVmZm1hbiB0cmVlIChsb25nZXN0IGNvZGVcbiAgICogYWxsIG9uZXMpXG4gICAqL1xuICBnZW5fY29kZXMoc3RhdGljX2x0cmVlLCBMX0NPREVTJDEgKyAxLCBibF9jb3VudCk7XG5cbiAgLyogVGhlIHN0YXRpYyBkaXN0YW5jZSB0cmVlIGlzIHRyaXZpYWw6ICovXG4gIGZvciAobiA9IDA7IG4gPCBEX0NPREVTJDE7IG4rKykge1xuICAgIHN0YXRpY19kdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSA1O1xuICAgIHN0YXRpY19kdHJlZVtuICogMl0vKi5Db2RlKi8gPSBiaV9yZXZlcnNlKG4sIDUpO1xuICB9XG5cbiAgLy8gTm93IGRhdGEgcmVhZHkgYW5kIHdlIGNhbiBpbml0IHN0YXRpYyB0cmVlc1xuICBzdGF0aWNfbF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKHN0YXRpY19sdHJlZSwgZXh0cmFfbGJpdHMsIExJVEVSQUxTJDEgKyAxLCBMX0NPREVTJDEsIE1BWF9CSVRTJDEpO1xuICBzdGF0aWNfZF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKHN0YXRpY19kdHJlZSwgZXh0cmFfZGJpdHMsIDAsICAgICAgICAgIERfQ09ERVMkMSwgTUFYX0JJVFMkMSk7XG4gIHN0YXRpY19ibF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKG5ldyBBcnJheSgwKSwgZXh0cmFfYmxiaXRzLCAwLCAgICAgICAgIEJMX0NPREVTJDEsIE1BWF9CTF9CSVRTKTtcblxuICAvL3N0YXRpY19pbml0X2RvbmUgPSB0cnVlO1xufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgYSBuZXcgYmxvY2suXG4gKi9cbmNvbnN0IGluaXRfYmxvY2sgPSAocykgPT4ge1xuXG4gIGxldCBuOyAvKiBpdGVyYXRlcyBvdmVyIHRyZWUgZWxlbWVudHMgKi9cblxuICAvKiBJbml0aWFsaXplIHRoZSB0cmVlcy4gKi9cbiAgZm9yIChuID0gMDsgbiA8IExfQ09ERVMkMTsgIG4rKykgeyBzLmR5bl9sdHJlZVtuICogMl0vKi5GcmVxKi8gPSAwOyB9XG4gIGZvciAobiA9IDA7IG4gPCBEX0NPREVTJDE7ICBuKyspIHsgcy5keW5fZHRyZWVbbiAqIDJdLyouRnJlcSovID0gMDsgfVxuICBmb3IgKG4gPSAwOyBuIDwgQkxfQ09ERVMkMTsgbisrKSB7IHMuYmxfdHJlZVtuICogMl0vKi5GcmVxKi8gPSAwOyB9XG5cbiAgcy5keW5fbHRyZWVbRU5EX0JMT0NLICogMl0vKi5GcmVxKi8gPSAxO1xuICBzLm9wdF9sZW4gPSBzLnN0YXRpY19sZW4gPSAwO1xuICBzLnN5bV9uZXh0ID0gcy5tYXRjaGVzID0gMDtcbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGbHVzaCB0aGUgYml0IGJ1ZmZlciBhbmQgYWxpZ24gdGhlIG91dHB1dCBvbiBhIGJ5dGUgYm91bmRhcnlcbiAqL1xuY29uc3QgYmlfd2luZHVwID0gKHMpID0+XG57XG4gIGlmIChzLmJpX3ZhbGlkID4gOCkge1xuICAgIHB1dF9zaG9ydChzLCBzLmJpX2J1Zik7XG4gIH0gZWxzZSBpZiAocy5iaV92YWxpZCA+IDApIHtcbiAgICAvL3B1dF9ieXRlKHMsIChCeXRlKXMtPmJpX2J1Zik7XG4gICAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBzLmJpX2J1ZjtcbiAgfVxuICBzLmJpX2J1ZiA9IDA7XG4gIHMuYmlfdmFsaWQgPSAwO1xufTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb21wYXJlcyB0byBzdWJ0cmVlcywgdXNpbmcgdGhlIHRyZWUgZGVwdGggYXMgdGllIGJyZWFrZXIgd2hlblxuICogdGhlIHN1YnRyZWVzIGhhdmUgZXF1YWwgZnJlcXVlbmN5LiBUaGlzIG1pbmltaXplcyB0aGUgd29yc3QgY2FzZSBsZW5ndGguXG4gKi9cbmNvbnN0IHNtYWxsZXIgPSAodHJlZSwgbiwgbSwgZGVwdGgpID0+IHtcblxuICBjb25zdCBfbjIgPSBuICogMjtcbiAgY29uc3QgX20yID0gbSAqIDI7XG4gIHJldHVybiAodHJlZVtfbjJdLyouRnJlcSovIDwgdHJlZVtfbTJdLyouRnJlcSovIHx8XG4gICAgICAgICAodHJlZVtfbjJdLyouRnJlcSovID09PSB0cmVlW19tMl0vKi5GcmVxKi8gJiYgZGVwdGhbbl0gPD0gZGVwdGhbbV0pKTtcbn07XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogUmVzdG9yZSB0aGUgaGVhcCBwcm9wZXJ0eSBieSBtb3ZpbmcgZG93biB0aGUgdHJlZSBzdGFydGluZyBhdCBub2RlIGssXG4gKiBleGNoYW5naW5nIGEgbm9kZSB3aXRoIHRoZSBzbWFsbGVzdCBvZiBpdHMgdHdvIHNvbnMgaWYgbmVjZXNzYXJ5LCBzdG9wcGluZ1xuICogd2hlbiB0aGUgaGVhcCBwcm9wZXJ0eSBpcyByZS1lc3RhYmxpc2hlZCAoZWFjaCBmYXRoZXIgc21hbGxlciB0aGFuIGl0c1xuICogdHdvIHNvbnMpLlxuICovXG5jb25zdCBwcWRvd25oZWFwID0gKHMsIHRyZWUsIGspID0+IHtcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBjdF9kYXRhICp0cmVlOyAgLyogdGhlIHRyZWUgdG8gcmVzdG9yZSAqL1xuLy8gICAgaW50IGs7ICAgICAgICAgICAgICAgLyogbm9kZSB0byBtb3ZlIGRvd24gKi9cblxuICBjb25zdCB2ID0gcy5oZWFwW2tdO1xuICBsZXQgaiA9IGsgPDwgMTsgIC8qIGxlZnQgc29uIG9mIGsgKi9cbiAgd2hpbGUgKGogPD0gcy5oZWFwX2xlbikge1xuICAgIC8qIFNldCBqIHRvIHRoZSBzbWFsbGVzdCBvZiB0aGUgdHdvIHNvbnM6ICovXG4gICAgaWYgKGogPCBzLmhlYXBfbGVuICYmXG4gICAgICBzbWFsbGVyKHRyZWUsIHMuaGVhcFtqICsgMV0sIHMuaGVhcFtqXSwgcy5kZXB0aCkpIHtcbiAgICAgIGorKztcbiAgICB9XG4gICAgLyogRXhpdCBpZiB2IGlzIHNtYWxsZXIgdGhhbiBib3RoIHNvbnMgKi9cbiAgICBpZiAoc21hbGxlcih0cmVlLCB2LCBzLmhlYXBbal0sIHMuZGVwdGgpKSB7IGJyZWFrOyB9XG5cbiAgICAvKiBFeGNoYW5nZSB2IHdpdGggdGhlIHNtYWxsZXN0IHNvbiAqL1xuICAgIHMuaGVhcFtrXSA9IHMuaGVhcFtqXTtcbiAgICBrID0gajtcblxuICAgIC8qIEFuZCBjb250aW51ZSBkb3duIHRoZSB0cmVlLCBzZXR0aW5nIGogdG8gdGhlIGxlZnQgc29uIG9mIGsgKi9cbiAgICBqIDw8PSAxO1xuICB9XG4gIHMuaGVhcFtrXSA9IHY7XG59O1xuXG5cbi8vIGlubGluZWQgbWFudWFsbHlcbi8vIGNvbnN0IFNNQUxMRVNUID0gMTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIHRoZSBibG9jayBkYXRhIGNvbXByZXNzZWQgdXNpbmcgdGhlIGdpdmVuIEh1ZmZtYW4gdHJlZXNcbiAqL1xuY29uc3QgY29tcHJlc3NfYmxvY2sgPSAocywgbHRyZWUsIGR0cmVlKSA9PiB7XG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgY29uc3QgY3RfZGF0YSAqbHRyZWU7IC8qIGxpdGVyYWwgdHJlZSAqL1xuLy8gICAgY29uc3QgY3RfZGF0YSAqZHRyZWU7IC8qIGRpc3RhbmNlIHRyZWUgKi9cblxuICBsZXQgZGlzdDsgICAgICAgICAgIC8qIGRpc3RhbmNlIG9mIG1hdGNoZWQgc3RyaW5nICovXG4gIGxldCBsYzsgICAgICAgICAgICAgLyogbWF0Y2ggbGVuZ3RoIG9yIHVubWF0Y2hlZCBjaGFyIChpZiBkaXN0ID09IDApICovXG4gIGxldCBzeCA9IDA7ICAgICAgICAgLyogcnVubmluZyBpbmRleCBpbiBzeW1fYnVmICovXG4gIGxldCBjb2RlOyAgICAgICAgICAgLyogdGhlIGNvZGUgdG8gc2VuZCAqL1xuICBsZXQgZXh0cmE7ICAgICAgICAgIC8qIG51bWJlciBvZiBleHRyYSBiaXRzIHRvIHNlbmQgKi9cblxuICBpZiAocy5zeW1fbmV4dCAhPT0gMCkge1xuICAgIGRvIHtcbiAgICAgIGRpc3QgPSBzLnBlbmRpbmdfYnVmW3Muc3ltX2J1ZiArIHN4KytdICYgMHhmZjtcbiAgICAgIGRpc3QgKz0gKHMucGVuZGluZ19idWZbcy5zeW1fYnVmICsgc3grK10gJiAweGZmKSA8PCA4O1xuICAgICAgbGMgPSBzLnBlbmRpbmdfYnVmW3Muc3ltX2J1ZiArIHN4KytdO1xuICAgICAgaWYgKGRpc3QgPT09IDApIHtcbiAgICAgICAgc2VuZF9jb2RlKHMsIGxjLCBsdHJlZSk7IC8qIHNlbmQgYSBsaXRlcmFsIGJ5dGUgKi9cbiAgICAgICAgLy9UcmFjZWN2KGlzZ3JhcGgobGMpLCAoc3RkZXJyLFwiICclYycgXCIsIGxjKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKiBIZXJlLCBsYyBpcyB0aGUgbWF0Y2ggbGVuZ3RoIC0gTUlOX01BVENIICovXG4gICAgICAgIGNvZGUgPSBfbGVuZ3RoX2NvZGVbbGNdO1xuICAgICAgICBzZW5kX2NvZGUocywgY29kZSArIExJVEVSQUxTJDEgKyAxLCBsdHJlZSk7IC8qIHNlbmQgdGhlIGxlbmd0aCBjb2RlICovXG4gICAgICAgIGV4dHJhID0gZXh0cmFfbGJpdHNbY29kZV07XG4gICAgICAgIGlmIChleHRyYSAhPT0gMCkge1xuICAgICAgICAgIGxjIC09IGJhc2VfbGVuZ3RoW2NvZGVdO1xuICAgICAgICAgIHNlbmRfYml0cyhzLCBsYywgZXh0cmEpOyAgICAgICAvKiBzZW5kIHRoZSBleHRyYSBsZW5ndGggYml0cyAqL1xuICAgICAgICB9XG4gICAgICAgIGRpc3QtLTsgLyogZGlzdCBpcyBub3cgdGhlIG1hdGNoIGRpc3RhbmNlIC0gMSAqL1xuICAgICAgICBjb2RlID0gZF9jb2RlKGRpc3QpO1xuICAgICAgICAvL0Fzc2VydCAoY29kZSA8IERfQ09ERVMsIFwiYmFkIGRfY29kZVwiKTtcblxuICAgICAgICBzZW5kX2NvZGUocywgY29kZSwgZHRyZWUpOyAgICAgICAvKiBzZW5kIHRoZSBkaXN0YW5jZSBjb2RlICovXG4gICAgICAgIGV4dHJhID0gZXh0cmFfZGJpdHNbY29kZV07XG4gICAgICAgIGlmIChleHRyYSAhPT0gMCkge1xuICAgICAgICAgIGRpc3QgLT0gYmFzZV9kaXN0W2NvZGVdO1xuICAgICAgICAgIHNlbmRfYml0cyhzLCBkaXN0LCBleHRyYSk7ICAgLyogc2VuZCB0aGUgZXh0cmEgZGlzdGFuY2UgYml0cyAqL1xuICAgICAgICB9XG4gICAgICB9IC8qIGxpdGVyYWwgb3IgbWF0Y2ggcGFpciA/ICovXG5cbiAgICAgIC8qIENoZWNrIHRoYXQgdGhlIG92ZXJsYXkgYmV0d2VlbiBwZW5kaW5nX2J1ZiBhbmQgc3ltX2J1ZiBpcyBvazogKi9cbiAgICAgIC8vQXNzZXJ0KHMtPnBlbmRpbmcgPCBzLT5saXRfYnVmc2l6ZSArIHN4LCBcInBlbmRpbmdCdWYgb3ZlcmZsb3dcIik7XG5cbiAgICB9IHdoaWxlIChzeCA8IHMuc3ltX25leHQpO1xuICB9XG5cbiAgc2VuZF9jb2RlKHMsIEVORF9CTE9DSywgbHRyZWUpO1xufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbnN0cnVjdCBvbmUgSHVmZm1hbiB0cmVlIGFuZCBhc3NpZ25zIHRoZSBjb2RlIGJpdCBzdHJpbmdzIGFuZCBsZW5ndGhzLlxuICogVXBkYXRlIHRoZSB0b3RhbCBiaXQgbGVuZ3RoIGZvciB0aGUgY3VycmVudCBibG9jay5cbiAqIElOIGFzc2VydGlvbjogdGhlIGZpZWxkIGZyZXEgaXMgc2V0IGZvciBhbGwgdHJlZSBlbGVtZW50cy5cbiAqIE9VVCBhc3NlcnRpb25zOiB0aGUgZmllbGRzIGxlbiBhbmQgY29kZSBhcmUgc2V0IHRvIHRoZSBvcHRpbWFsIGJpdCBsZW5ndGhcbiAqICAgICBhbmQgY29ycmVzcG9uZGluZyBjb2RlLiBUaGUgbGVuZ3RoIG9wdF9sZW4gaXMgdXBkYXRlZDsgc3RhdGljX2xlbiBpc1xuICogICAgIGFsc28gdXBkYXRlZCBpZiBzdHJlZSBpcyBub3QgbnVsbC4gVGhlIGZpZWxkIG1heF9jb2RlIGlzIHNldC5cbiAqL1xuY29uc3QgYnVpbGRfdHJlZSA9IChzLCBkZXNjKSA9PiB7XG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgdHJlZV9kZXNjICpkZXNjOyAvKiB0aGUgdHJlZSBkZXNjcmlwdG9yICovXG5cbiAgY29uc3QgdHJlZSAgICAgPSBkZXNjLmR5bl90cmVlO1xuICBjb25zdCBzdHJlZSAgICA9IGRlc2Muc3RhdF9kZXNjLnN0YXRpY190cmVlO1xuICBjb25zdCBoYXNfc3RyZWUgPSBkZXNjLnN0YXRfZGVzYy5oYXNfc3RyZWU7XG4gIGNvbnN0IGVsZW1zICAgID0gZGVzYy5zdGF0X2Rlc2MuZWxlbXM7XG4gIGxldCBuLCBtOyAgICAgICAgICAvKiBpdGVyYXRlIG92ZXIgaGVhcCBlbGVtZW50cyAqL1xuICBsZXQgbWF4X2NvZGUgPSAtMTsgLyogbGFyZ2VzdCBjb2RlIHdpdGggbm9uIHplcm8gZnJlcXVlbmN5ICovXG4gIGxldCBub2RlOyAgICAgICAgICAvKiBuZXcgbm9kZSBiZWluZyBjcmVhdGVkICovXG5cbiAgLyogQ29uc3RydWN0IHRoZSBpbml0aWFsIGhlYXAsIHdpdGggbGVhc3QgZnJlcXVlbnQgZWxlbWVudCBpblxuICAgKiBoZWFwW1NNQUxMRVNUXS4gVGhlIHNvbnMgb2YgaGVhcFtuXSBhcmUgaGVhcFsyKm5dIGFuZCBoZWFwWzIqbisxXS5cbiAgICogaGVhcFswXSBpcyBub3QgdXNlZC5cbiAgICovXG4gIHMuaGVhcF9sZW4gPSAwO1xuICBzLmhlYXBfbWF4ID0gSEVBUF9TSVpFJDE7XG5cbiAgZm9yIChuID0gMDsgbiA8IGVsZW1zOyBuKyspIHtcbiAgICBpZiAodHJlZVtuICogMl0vKi5GcmVxKi8gIT09IDApIHtcbiAgICAgIHMuaGVhcFsrK3MuaGVhcF9sZW5dID0gbWF4X2NvZGUgPSBuO1xuICAgICAgcy5kZXB0aFtuXSA9IDA7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSAwO1xuICAgIH1cbiAgfVxuXG4gIC8qIFRoZSBwa3ppcCBmb3JtYXQgcmVxdWlyZXMgdGhhdCBhdCBsZWFzdCBvbmUgZGlzdGFuY2UgY29kZSBleGlzdHMsXG4gICAqIGFuZCB0aGF0IGF0IGxlYXN0IG9uZSBiaXQgc2hvdWxkIGJlIHNlbnQgZXZlbiBpZiB0aGVyZSBpcyBvbmx5IG9uZVxuICAgKiBwb3NzaWJsZSBjb2RlLiBTbyB0byBhdm9pZCBzcGVjaWFsIGNoZWNrcyBsYXRlciBvbiB3ZSBmb3JjZSBhdCBsZWFzdFxuICAgKiB0d28gY29kZXMgb2Ygbm9uIHplcm8gZnJlcXVlbmN5LlxuICAgKi9cbiAgd2hpbGUgKHMuaGVhcF9sZW4gPCAyKSB7XG4gICAgbm9kZSA9IHMuaGVhcFsrK3MuaGVhcF9sZW5dID0gKG1heF9jb2RlIDwgMiA/ICsrbWF4X2NvZGUgOiAwKTtcbiAgICB0cmVlW25vZGUgKiAyXS8qLkZyZXEqLyA9IDE7XG4gICAgcy5kZXB0aFtub2RlXSA9IDA7XG4gICAgcy5vcHRfbGVuLS07XG5cbiAgICBpZiAoaGFzX3N0cmVlKSB7XG4gICAgICBzLnN0YXRpY19sZW4gLT0gc3RyZWVbbm9kZSAqIDIgKyAxXS8qLkxlbiovO1xuICAgIH1cbiAgICAvKiBub2RlIGlzIDAgb3IgMSBzbyBpdCBkb2VzIG5vdCBoYXZlIGV4dHJhIGJpdHMgKi9cbiAgfVxuICBkZXNjLm1heF9jb2RlID0gbWF4X2NvZGU7XG5cbiAgLyogVGhlIGVsZW1lbnRzIGhlYXBbaGVhcF9sZW4vMisxIC4uIGhlYXBfbGVuXSBhcmUgbGVhdmVzIG9mIHRoZSB0cmVlLFxuICAgKiBlc3RhYmxpc2ggc3ViLWhlYXBzIG9mIGluY3JlYXNpbmcgbGVuZ3RoczpcbiAgICovXG4gIGZvciAobiA9IChzLmhlYXBfbGVuID4+IDEvKmludCAvMiovKTsgbiA+PSAxOyBuLS0pIHsgcHFkb3duaGVhcChzLCB0cmVlLCBuKTsgfVxuXG4gIC8qIENvbnN0cnVjdCB0aGUgSHVmZm1hbiB0cmVlIGJ5IHJlcGVhdGVkbHkgY29tYmluaW5nIHRoZSBsZWFzdCB0d29cbiAgICogZnJlcXVlbnQgbm9kZXMuXG4gICAqL1xuICBub2RlID0gZWxlbXM7ICAgICAgICAgICAgICAvKiBuZXh0IGludGVybmFsIG5vZGUgb2YgdGhlIHRyZWUgKi9cbiAgZG8ge1xuICAgIC8vcHFyZW1vdmUocywgdHJlZSwgbik7ICAvKiBuID0gbm9kZSBvZiBsZWFzdCBmcmVxdWVuY3kgKi9cbiAgICAvKioqIHBxcmVtb3ZlICoqKi9cbiAgICBuID0gcy5oZWFwWzEvKlNNQUxMRVNUKi9dO1xuICAgIHMuaGVhcFsxLypTTUFMTEVTVCovXSA9IHMuaGVhcFtzLmhlYXBfbGVuLS1dO1xuICAgIHBxZG93bmhlYXAocywgdHJlZSwgMS8qU01BTExFU1QqLyk7XG4gICAgLyoqKi9cblxuICAgIG0gPSBzLmhlYXBbMS8qU01BTExFU1QqL107IC8qIG0gPSBub2RlIG9mIG5leHQgbGVhc3QgZnJlcXVlbmN5ICovXG5cbiAgICBzLmhlYXBbLS1zLmhlYXBfbWF4XSA9IG47IC8qIGtlZXAgdGhlIG5vZGVzIHNvcnRlZCBieSBmcmVxdWVuY3kgKi9cbiAgICBzLmhlYXBbLS1zLmhlYXBfbWF4XSA9IG07XG5cbiAgICAvKiBDcmVhdGUgYSBuZXcgbm9kZSBmYXRoZXIgb2YgbiBhbmQgbSAqL1xuICAgIHRyZWVbbm9kZSAqIDJdLyouRnJlcSovID0gdHJlZVtuICogMl0vKi5GcmVxKi8gKyB0cmVlW20gKiAyXS8qLkZyZXEqLztcbiAgICBzLmRlcHRoW25vZGVdID0gKHMuZGVwdGhbbl0gPj0gcy5kZXB0aFttXSA/IHMuZGVwdGhbbl0gOiBzLmRlcHRoW21dKSArIDE7XG4gICAgdHJlZVtuICogMiArIDFdLyouRGFkKi8gPSB0cmVlW20gKiAyICsgMV0vKi5EYWQqLyA9IG5vZGU7XG5cbiAgICAvKiBhbmQgaW5zZXJ0IHRoZSBuZXcgbm9kZSBpbiB0aGUgaGVhcCAqL1xuICAgIHMuaGVhcFsxLypTTUFMTEVTVCovXSA9IG5vZGUrKztcbiAgICBwcWRvd25oZWFwKHMsIHRyZWUsIDEvKlNNQUxMRVNUKi8pO1xuXG4gIH0gd2hpbGUgKHMuaGVhcF9sZW4gPj0gMik7XG5cbiAgcy5oZWFwWy0tcy5oZWFwX21heF0gPSBzLmhlYXBbMS8qU01BTExFU1QqL107XG5cbiAgLyogQXQgdGhpcyBwb2ludCwgdGhlIGZpZWxkcyBmcmVxIGFuZCBkYWQgYXJlIHNldC4gV2UgY2FuIG5vd1xuICAgKiBnZW5lcmF0ZSB0aGUgYml0IGxlbmd0aHMuXG4gICAqL1xuICBnZW5fYml0bGVuKHMsIGRlc2MpO1xuXG4gIC8qIFRoZSBmaWVsZCBsZW4gaXMgbm93IHNldCwgd2UgY2FuIGdlbmVyYXRlIHRoZSBiaXQgY29kZXMgKi9cbiAgZ2VuX2NvZGVzKHRyZWUsIG1heF9jb2RlLCBzLmJsX2NvdW50KTtcbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTY2FuIGEgbGl0ZXJhbCBvciBkaXN0YW5jZSB0cmVlIHRvIGRldGVybWluZSB0aGUgZnJlcXVlbmNpZXMgb2YgdGhlIGNvZGVzXG4gKiBpbiB0aGUgYml0IGxlbmd0aCB0cmVlLlxuICovXG5jb25zdCBzY2FuX3RyZWUgPSAocywgdHJlZSwgbWF4X2NvZGUpID0+IHtcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBjdF9kYXRhICp0cmVlOyAgIC8qIHRoZSB0cmVlIHRvIGJlIHNjYW5uZWQgKi9cbi8vICAgIGludCBtYXhfY29kZTsgICAgLyogYW5kIGl0cyBsYXJnZXN0IGNvZGUgb2Ygbm9uIHplcm8gZnJlcXVlbmN5ICovXG5cbiAgbGV0IG47ICAgICAgICAgICAgICAgICAgICAgLyogaXRlcmF0ZXMgb3ZlciBhbGwgdHJlZSBlbGVtZW50cyAqL1xuICBsZXQgcHJldmxlbiA9IC0xOyAgICAgICAgICAvKiBsYXN0IGVtaXR0ZWQgbGVuZ3RoICovXG4gIGxldCBjdXJsZW47ICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBvZiBjdXJyZW50IGNvZGUgKi9cblxuICBsZXQgbmV4dGxlbiA9IHRyZWVbMCAqIDIgKyAxXS8qLkxlbiovOyAvKiBsZW5ndGggb2YgbmV4dCBjb2RlICovXG5cbiAgbGV0IGNvdW50ID0gMDsgICAgICAgICAgICAgLyogcmVwZWF0IGNvdW50IG9mIHRoZSBjdXJyZW50IGNvZGUgKi9cbiAgbGV0IG1heF9jb3VudCA9IDc7ICAgICAgICAgLyogbWF4IHJlcGVhdCBjb3VudCAqL1xuICBsZXQgbWluX2NvdW50ID0gNDsgICAgICAgICAvKiBtaW4gcmVwZWF0IGNvdW50ICovXG5cbiAgaWYgKG5leHRsZW4gPT09IDApIHtcbiAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgbWluX2NvdW50ID0gMztcbiAgfVxuICB0cmVlWyhtYXhfY29kZSArIDEpICogMiArIDFdLyouTGVuKi8gPSAweGZmZmY7IC8qIGd1YXJkICovXG5cbiAgZm9yIChuID0gMDsgbiA8PSBtYXhfY29kZTsgbisrKSB7XG4gICAgY3VybGVuID0gbmV4dGxlbjtcbiAgICBuZXh0bGVuID0gdHJlZVsobiArIDEpICogMiArIDFdLyouTGVuKi87XG5cbiAgICBpZiAoKytjb3VudCA8IG1heF9jb3VudCAmJiBjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8IG1pbl9jb3VudCkge1xuICAgICAgcy5ibF90cmVlW2N1cmxlbiAqIDJdLyouRnJlcSovICs9IGNvdW50O1xuXG4gICAgfSBlbHNlIGlmIChjdXJsZW4gIT09IDApIHtcblxuICAgICAgaWYgKGN1cmxlbiAhPT0gcHJldmxlbikgeyBzLmJsX3RyZWVbY3VybGVuICogMl0vKi5GcmVxKi8rKzsgfVxuICAgICAgcy5ibF90cmVlW1JFUF8zXzYgKiAyXS8qLkZyZXEqLysrO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8PSAxMCkge1xuICAgICAgcy5ibF90cmVlW1JFUFpfM18xMCAqIDJdLyouRnJlcSovKys7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgcy5ibF90cmVlW1JFUFpfMTFfMTM4ICogMl0vKi5GcmVxKi8rKztcbiAgICB9XG5cbiAgICBjb3VudCA9IDA7XG4gICAgcHJldmxlbiA9IGN1cmxlbjtcblxuICAgIGlmIChuZXh0bGVuID09PSAwKSB7XG4gICAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgICBtaW5fY291bnQgPSAzO1xuXG4gICAgfSBlbHNlIGlmIChjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIG1heF9jb3VudCA9IDY7XG4gICAgICBtaW5fY291bnQgPSAzO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIG1heF9jb3VudCA9IDc7XG4gICAgICBtaW5fY291bnQgPSA0O1xuICAgIH1cbiAgfVxufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgYSBsaXRlcmFsIG9yIGRpc3RhbmNlIHRyZWUgaW4gY29tcHJlc3NlZCBmb3JtLCB1c2luZyB0aGUgY29kZXMgaW5cbiAqIGJsX3RyZWUuXG4gKi9cbmNvbnN0IHNlbmRfdHJlZSA9IChzLCB0cmVlLCBtYXhfY29kZSkgPT4ge1xuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGN0X2RhdGEgKnRyZWU7IC8qIHRoZSB0cmVlIHRvIGJlIHNjYW5uZWQgKi9cbi8vICAgIGludCBtYXhfY29kZTsgICAgICAgLyogYW5kIGl0cyBsYXJnZXN0IGNvZGUgb2Ygbm9uIHplcm8gZnJlcXVlbmN5ICovXG5cbiAgbGV0IG47ICAgICAgICAgICAgICAgICAgICAgLyogaXRlcmF0ZXMgb3ZlciBhbGwgdHJlZSBlbGVtZW50cyAqL1xuICBsZXQgcHJldmxlbiA9IC0xOyAgICAgICAgICAvKiBsYXN0IGVtaXR0ZWQgbGVuZ3RoICovXG4gIGxldCBjdXJsZW47ICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBvZiBjdXJyZW50IGNvZGUgKi9cblxuICBsZXQgbmV4dGxlbiA9IHRyZWVbMCAqIDIgKyAxXS8qLkxlbiovOyAvKiBsZW5ndGggb2YgbmV4dCBjb2RlICovXG5cbiAgbGV0IGNvdW50ID0gMDsgICAgICAgICAgICAgLyogcmVwZWF0IGNvdW50IG9mIHRoZSBjdXJyZW50IGNvZGUgKi9cbiAgbGV0IG1heF9jb3VudCA9IDc7ICAgICAgICAgLyogbWF4IHJlcGVhdCBjb3VudCAqL1xuICBsZXQgbWluX2NvdW50ID0gNDsgICAgICAgICAvKiBtaW4gcmVwZWF0IGNvdW50ICovXG5cbiAgLyogdHJlZVttYXhfY29kZSsxXS5MZW4gPSAtMTsgKi8gIC8qIGd1YXJkIGFscmVhZHkgc2V0ICovXG4gIGlmIChuZXh0bGVuID09PSAwKSB7XG4gICAgbWF4X2NvdW50ID0gMTM4O1xuICAgIG1pbl9jb3VudCA9IDM7XG4gIH1cblxuICBmb3IgKG4gPSAwOyBuIDw9IG1heF9jb2RlOyBuKyspIHtcbiAgICBjdXJsZW4gPSBuZXh0bGVuO1xuICAgIG5leHRsZW4gPSB0cmVlWyhuICsgMSkgKiAyICsgMV0vKi5MZW4qLztcblxuICAgIGlmICgrK2NvdW50IDwgbWF4X2NvdW50ICYmIGN1cmxlbiA9PT0gbmV4dGxlbikge1xuICAgICAgY29udGludWU7XG5cbiAgICB9IGVsc2UgaWYgKGNvdW50IDwgbWluX2NvdW50KSB7XG4gICAgICBkbyB7IHNlbmRfY29kZShzLCBjdXJsZW4sIHMuYmxfdHJlZSk7IH0gd2hpbGUgKC0tY291bnQgIT09IDApO1xuXG4gICAgfSBlbHNlIGlmIChjdXJsZW4gIT09IDApIHtcbiAgICAgIGlmIChjdXJsZW4gIT09IHByZXZsZW4pIHtcbiAgICAgICAgc2VuZF9jb2RlKHMsIGN1cmxlbiwgcy5ibF90cmVlKTtcbiAgICAgICAgY291bnQtLTtcbiAgICAgIH1cbiAgICAgIC8vQXNzZXJ0KGNvdW50ID49IDMgJiYgY291bnQgPD0gNiwgXCIgM182P1wiKTtcbiAgICAgIHNlbmRfY29kZShzLCBSRVBfM182LCBzLmJsX3RyZWUpO1xuICAgICAgc2VuZF9iaXRzKHMsIGNvdW50IC0gMywgMik7XG5cbiAgICB9IGVsc2UgaWYgKGNvdW50IDw9IDEwKSB7XG4gICAgICBzZW5kX2NvZGUocywgUkVQWl8zXzEwLCBzLmJsX3RyZWUpO1xuICAgICAgc2VuZF9iaXRzKHMsIGNvdW50IC0gMywgMyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgc2VuZF9jb2RlKHMsIFJFUFpfMTFfMTM4LCBzLmJsX3RyZWUpO1xuICAgICAgc2VuZF9iaXRzKHMsIGNvdW50IC0gMTEsIDcpO1xuICAgIH1cblxuICAgIGNvdW50ID0gMDtcbiAgICBwcmV2bGVuID0gY3VybGVuO1xuICAgIGlmIChuZXh0bGVuID09PSAwKSB7XG4gICAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgICBtaW5fY291bnQgPSAzO1xuXG4gICAgfSBlbHNlIGlmIChjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIG1heF9jb3VudCA9IDY7XG4gICAgICBtaW5fY291bnQgPSAzO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIG1heF9jb3VudCA9IDc7XG4gICAgICBtaW5fY291bnQgPSA0O1xuICAgIH1cbiAgfVxufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbnN0cnVjdCB0aGUgSHVmZm1hbiB0cmVlIGZvciB0aGUgYml0IGxlbmd0aHMgYW5kIHJldHVybiB0aGUgaW5kZXggaW5cbiAqIGJsX29yZGVyIG9mIHRoZSBsYXN0IGJpdCBsZW5ndGggY29kZSB0byBzZW5kLlxuICovXG5jb25zdCBidWlsZF9ibF90cmVlID0gKHMpID0+IHtcblxuICBsZXQgbWF4X2JsaW5kZXg7ICAvKiBpbmRleCBvZiBsYXN0IGJpdCBsZW5ndGggY29kZSBvZiBub24gemVybyBmcmVxICovXG5cbiAgLyogRGV0ZXJtaW5lIHRoZSBiaXQgbGVuZ3RoIGZyZXF1ZW5jaWVzIGZvciBsaXRlcmFsIGFuZCBkaXN0YW5jZSB0cmVlcyAqL1xuICBzY2FuX3RyZWUocywgcy5keW5fbHRyZWUsIHMubF9kZXNjLm1heF9jb2RlKTtcbiAgc2Nhbl90cmVlKHMsIHMuZHluX2R0cmVlLCBzLmRfZGVzYy5tYXhfY29kZSk7XG5cbiAgLyogQnVpbGQgdGhlIGJpdCBsZW5ndGggdHJlZTogKi9cbiAgYnVpbGRfdHJlZShzLCBzLmJsX2Rlc2MpO1xuICAvKiBvcHRfbGVuIG5vdyBpbmNsdWRlcyB0aGUgbGVuZ3RoIG9mIHRoZSB0cmVlIHJlcHJlc2VudGF0aW9ucywgZXhjZXB0XG4gICAqIHRoZSBsZW5ndGhzIG9mIHRoZSBiaXQgbGVuZ3RocyBjb2RlcyBhbmQgdGhlIDUrNSs0IGJpdHMgZm9yIHRoZSBjb3VudHMuXG4gICAqL1xuXG4gIC8qIERldGVybWluZSB0aGUgbnVtYmVyIG9mIGJpdCBsZW5ndGggY29kZXMgdG8gc2VuZC4gVGhlIHBremlwIGZvcm1hdFxuICAgKiByZXF1aXJlcyB0aGF0IGF0IGxlYXN0IDQgYml0IGxlbmd0aCBjb2RlcyBiZSBzZW50LiAoYXBwbm90ZS50eHQgc2F5c1xuICAgKiAzIGJ1dCB0aGUgYWN0dWFsIHZhbHVlIHVzZWQgaXMgNC4pXG4gICAqL1xuICBmb3IgKG1heF9ibGluZGV4ID0gQkxfQ09ERVMkMSAtIDE7IG1heF9ibGluZGV4ID49IDM7IG1heF9ibGluZGV4LS0pIHtcbiAgICBpZiAocy5ibF90cmVlW2JsX29yZGVyW21heF9ibGluZGV4XSAqIDIgKyAxXS8qLkxlbiovICE9PSAwKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgLyogVXBkYXRlIG9wdF9sZW4gdG8gaW5jbHVkZSB0aGUgYml0IGxlbmd0aCB0cmVlIGFuZCBjb3VudHMgKi9cbiAgcy5vcHRfbGVuICs9IDMgKiAobWF4X2JsaW5kZXggKyAxKSArIDUgKyA1ICsgNDtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJcXG5keW4gdHJlZXM6IGR5biAlbGQsIHN0YXQgJWxkXCIsXG4gIC8vICAgICAgICBzLT5vcHRfbGVuLCBzLT5zdGF0aWNfbGVuKSk7XG5cbiAgcmV0dXJuIG1heF9ibGluZGV4O1xufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgdGhlIGhlYWRlciBmb3IgYSBibG9jayB1c2luZyBkeW5hbWljIEh1ZmZtYW4gdHJlZXM6IHRoZSBjb3VudHMsIHRoZVxuICogbGVuZ3RocyBvZiB0aGUgYml0IGxlbmd0aCBjb2RlcywgdGhlIGxpdGVyYWwgdHJlZSBhbmQgdGhlIGRpc3RhbmNlIHRyZWUuXG4gKiBJTiBhc3NlcnRpb246IGxjb2RlcyA+PSAyNTcsIGRjb2RlcyA+PSAxLCBibGNvZGVzID49IDQuXG4gKi9cbmNvbnN0IHNlbmRfYWxsX3RyZWVzID0gKHMsIGxjb2RlcywgZGNvZGVzLCBibGNvZGVzKSA9PiB7XG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgaW50IGxjb2RlcywgZGNvZGVzLCBibGNvZGVzOyAvKiBudW1iZXIgb2YgY29kZXMgZm9yIGVhY2ggdHJlZSAqL1xuXG4gIGxldCByYW5rOyAgICAgICAgICAgICAgICAgICAgLyogaW5kZXggaW4gYmxfb3JkZXIgKi9cblxuICAvL0Fzc2VydCAobGNvZGVzID49IDI1NyAmJiBkY29kZXMgPj0gMSAmJiBibGNvZGVzID49IDQsIFwibm90IGVub3VnaCBjb2Rlc1wiKTtcbiAgLy9Bc3NlcnQgKGxjb2RlcyA8PSBMX0NPREVTICYmIGRjb2RlcyA8PSBEX0NPREVTICYmIGJsY29kZXMgPD0gQkxfQ09ERVMsXG4gIC8vICAgICAgICBcInRvbyBtYW55IGNvZGVzXCIpO1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmJsIGNvdW50czogXCIpKTtcbiAgc2VuZF9iaXRzKHMsIGxjb2RlcyAtIDI1NywgNSk7IC8qIG5vdCArMjU1IGFzIHN0YXRlZCBpbiBhcHBub3RlLnR4dCAqL1xuICBzZW5kX2JpdHMocywgZGNvZGVzIC0gMSwgICA1KTtcbiAgc2VuZF9iaXRzKHMsIGJsY29kZXMgLSA0LCAgNCk7IC8qIG5vdCAtMyBhcyBzdGF0ZWQgaW4gYXBwbm90ZS50eHQgKi9cbiAgZm9yIChyYW5rID0gMDsgcmFuayA8IGJsY29kZXM7IHJhbmsrKykge1xuICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiXFxuYmwgY29kZSAlMmQgXCIsIGJsX29yZGVyW3JhbmtdKSk7XG4gICAgc2VuZF9iaXRzKHMsIHMuYmxfdHJlZVtibF9vcmRlcltyYW5rXSAqIDIgKyAxXS8qLkxlbiovLCAzKTtcbiAgfVxuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmJsIHRyZWU6IHNlbnQgJWxkXCIsIHMtPmJpdHNfc2VudCkpO1xuXG4gIHNlbmRfdHJlZShzLCBzLmR5bl9sdHJlZSwgbGNvZGVzIC0gMSk7IC8qIGxpdGVyYWwgdHJlZSAqL1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmxpdCB0cmVlOiBzZW50ICVsZFwiLCBzLT5iaXRzX3NlbnQpKTtcblxuICBzZW5kX3RyZWUocywgcy5keW5fZHRyZWUsIGRjb2RlcyAtIDEpOyAvKiBkaXN0YW5jZSB0cmVlICovXG4gIC8vVHJhY2V2KChzdGRlcnIsIFwiXFxuZGlzdCB0cmVlOiBzZW50ICVsZFwiLCBzLT5iaXRzX3NlbnQpKTtcbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDaGVjayBpZiB0aGUgZGF0YSB0eXBlIGlzIFRFWFQgb3IgQklOQVJZLCB1c2luZyB0aGUgZm9sbG93aW5nIGFsZ29yaXRobTpcbiAqIC0gVEVYVCBpZiB0aGUgdHdvIGNvbmRpdGlvbnMgYmVsb3cgYXJlIHNhdGlzZmllZDpcbiAqICAgIGEpIFRoZXJlIGFyZSBubyBub24tcG9ydGFibGUgY29udHJvbCBjaGFyYWN0ZXJzIGJlbG9uZ2luZyB0byB0aGVcbiAqICAgICAgIFwiYmxvY2sgbGlzdFwiICgwLi42LCAxNC4uMjUsIDI4Li4zMSkuXG4gKiAgICBiKSBUaGVyZSBpcyBhdCBsZWFzdCBvbmUgcHJpbnRhYmxlIGNoYXJhY3RlciBiZWxvbmdpbmcgdG8gdGhlXG4gKiAgICAgICBcImFsbG93IGxpc3RcIiAoOSB7VEFCfSwgMTAge0xGfSwgMTMge0NSfSwgMzIuLjI1NSkuXG4gKiAtIEJJTkFSWSBvdGhlcndpc2UuXG4gKiAtIFRoZSBmb2xsb3dpbmcgcGFydGlhbGx5LXBvcnRhYmxlIGNvbnRyb2wgY2hhcmFjdGVycyBmb3JtIGFcbiAqICAgXCJncmF5IGxpc3RcIiB0aGF0IGlzIGlnbm9yZWQgaW4gdGhpcyBkZXRlY3Rpb24gYWxnb3JpdGhtOlxuICogICAoNyB7QkVMfSwgOCB7QlN9LCAxMSB7VlR9LCAxMiB7RkZ9LCAyNiB7U1VCfSwgMjcge0VTQ30pLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGRzIEZyZXEgb2YgZHluX2x0cmVlIGFyZSBzZXQuXG4gKi9cbmNvbnN0IGRldGVjdF9kYXRhX3R5cGUgPSAocykgPT4ge1xuICAvKiBibG9ja19tYXNrIGlzIHRoZSBiaXQgbWFzayBvZiBibG9jay1saXN0ZWQgYnl0ZXNcbiAgICogc2V0IGJpdHMgMC4uNiwgMTQuLjI1LCBhbmQgMjguLjMxXG4gICAqIDB4ZjNmZmMwN2YgPSBiaW5hcnkgMTExMTAwMTExMTExMTExMTExMDAwMDAwMDExMTExMTFcbiAgICovXG4gIGxldCBibG9ja19tYXNrID0gMHhmM2ZmYzA3ZjtcbiAgbGV0IG47XG5cbiAgLyogQ2hlY2sgZm9yIG5vbi10ZXh0dWFsIChcImJsb2NrLWxpc3RlZFwiKSBieXRlcy4gKi9cbiAgZm9yIChuID0gMDsgbiA8PSAzMTsgbisrLCBibG9ja19tYXNrID4+Pj0gMSkge1xuICAgIGlmICgoYmxvY2tfbWFzayAmIDEpICYmIChzLmR5bl9sdHJlZVtuICogMl0vKi5GcmVxKi8gIT09IDApKSB7XG4gICAgICByZXR1cm4gWl9CSU5BUlk7XG4gICAgfVxuICB9XG5cbiAgLyogQ2hlY2sgZm9yIHRleHR1YWwgKFwiYWxsb3ctbGlzdGVkXCIpIGJ5dGVzLiAqL1xuICBpZiAocy5keW5fbHRyZWVbOSAqIDJdLyouRnJlcSovICE9PSAwIHx8IHMuZHluX2x0cmVlWzEwICogMl0vKi5GcmVxKi8gIT09IDAgfHxcbiAgICAgIHMuZHluX2x0cmVlWzEzICogMl0vKi5GcmVxKi8gIT09IDApIHtcbiAgICByZXR1cm4gWl9URVhUO1xuICB9XG4gIGZvciAobiA9IDMyOyBuIDwgTElURVJBTFMkMTsgbisrKSB7XG4gICAgaWYgKHMuZHluX2x0cmVlW24gKiAyXS8qLkZyZXEqLyAhPT0gMCkge1xuICAgICAgcmV0dXJuIFpfVEVYVDtcbiAgICB9XG4gIH1cblxuICAvKiBUaGVyZSBhcmUgbm8gXCJibG9jay1saXN0ZWRcIiBvciBcImFsbG93LWxpc3RlZFwiIGJ5dGVzOlxuICAgKiB0aGlzIHN0cmVhbSBlaXRoZXIgaXMgZW1wdHkgb3IgaGFzIHRvbGVyYXRlZCAoXCJncmF5LWxpc3RlZFwiKSBieXRlcyBvbmx5LlxuICAgKi9cbiAgcmV0dXJuIFpfQklOQVJZO1xufTtcblxuXG5sZXQgc3RhdGljX2luaXRfZG9uZSA9IGZhbHNlO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgdGhlIHRyZWUgZGF0YSBzdHJ1Y3R1cmVzIGZvciBhIG5ldyB6bGliIHN0cmVhbS5cbiAqL1xuY29uc3QgX3RyX2luaXQkMSA9IChzKSA9Plxue1xuXG4gIGlmICghc3RhdGljX2luaXRfZG9uZSkge1xuICAgIHRyX3N0YXRpY19pbml0KCk7XG4gICAgc3RhdGljX2luaXRfZG9uZSA9IHRydWU7XG4gIH1cblxuICBzLmxfZGVzYyAgPSBuZXcgVHJlZURlc2Mocy5keW5fbHRyZWUsIHN0YXRpY19sX2Rlc2MpO1xuICBzLmRfZGVzYyAgPSBuZXcgVHJlZURlc2Mocy5keW5fZHRyZWUsIHN0YXRpY19kX2Rlc2MpO1xuICBzLmJsX2Rlc2MgPSBuZXcgVHJlZURlc2Mocy5ibF90cmVlLCBzdGF0aWNfYmxfZGVzYyk7XG5cbiAgcy5iaV9idWYgPSAwO1xuICBzLmJpX3ZhbGlkID0gMDtcblxuICAvKiBJbml0aWFsaXplIHRoZSBmaXJzdCBibG9jayBvZiB0aGUgZmlyc3QgZmlsZTogKi9cbiAgaW5pdF9ibG9jayhzKTtcbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIGEgc3RvcmVkIGJsb2NrXG4gKi9cbmNvbnN0IF90cl9zdG9yZWRfYmxvY2skMSA9IChzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpID0+IHtcbi8vRGVmbGF0ZVN0YXRlICpzO1xuLy9jaGFyZiAqYnVmOyAgICAgICAvKiBpbnB1dCBibG9jayAqL1xuLy91bGcgc3RvcmVkX2xlbjsgICAvKiBsZW5ndGggb2YgaW5wdXQgYmxvY2sgKi9cbi8vaW50IGxhc3Q7ICAgICAgICAgLyogb25lIGlmIHRoaXMgaXMgdGhlIGxhc3QgYmxvY2sgZm9yIGEgZmlsZSAqL1xuXG4gIHNlbmRfYml0cyhzLCAoU1RPUkVEX0JMT0NLIDw8IDEpICsgKGxhc3QgPyAxIDogMCksIDMpOyAgICAvKiBzZW5kIGJsb2NrIHR5cGUgKi9cbiAgYmlfd2luZHVwKHMpOyAgICAgICAgLyogYWxpZ24gb24gYnl0ZSBib3VuZGFyeSAqL1xuICBwdXRfc2hvcnQocywgc3RvcmVkX2xlbik7XG4gIHB1dF9zaG9ydChzLCB+c3RvcmVkX2xlbik7XG4gIGlmIChzdG9yZWRfbGVuKSB7XG4gICAgcy5wZW5kaW5nX2J1Zi5zZXQocy53aW5kb3cuc3ViYXJyYXkoYnVmLCBidWYgKyBzdG9yZWRfbGVuKSwgcy5wZW5kaW5nKTtcbiAgfVxuICBzLnBlbmRpbmcgKz0gc3RvcmVkX2xlbjtcbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIG9uZSBlbXB0eSBzdGF0aWMgYmxvY2sgdG8gZ2l2ZSBlbm91Z2ggbG9va2FoZWFkIGZvciBpbmZsYXRlLlxuICogVGhpcyB0YWtlcyAxMCBiaXRzLCBvZiB3aGljaCA3IG1heSByZW1haW4gaW4gdGhlIGJpdCBidWZmZXIuXG4gKi9cbmNvbnN0IF90cl9hbGlnbiQxID0gKHMpID0+IHtcbiAgc2VuZF9iaXRzKHMsIFNUQVRJQ19UUkVFUyA8PCAxLCAzKTtcbiAgc2VuZF9jb2RlKHMsIEVORF9CTE9DSywgc3RhdGljX2x0cmVlKTtcbiAgYmlfZmx1c2gocyk7XG59O1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRGV0ZXJtaW5lIHRoZSBiZXN0IGVuY29kaW5nIGZvciB0aGUgY3VycmVudCBibG9jazogZHluYW1pYyB0cmVlcywgc3RhdGljXG4gKiB0cmVlcyBvciBzdG9yZSwgYW5kIHdyaXRlIG91dCB0aGUgZW5jb2RlZCBibG9jay5cbiAqL1xuY29uc3QgX3RyX2ZsdXNoX2Jsb2NrJDEgPSAocywgYnVmLCBzdG9yZWRfbGVuLCBsYXN0KSA9PiB7XG4vL0RlZmxhdGVTdGF0ZSAqcztcbi8vY2hhcmYgKmJ1ZjsgICAgICAgLyogaW5wdXQgYmxvY2ssIG9yIE5VTEwgaWYgdG9vIG9sZCAqL1xuLy91bGcgc3RvcmVkX2xlbjsgICAvKiBsZW5ndGggb2YgaW5wdXQgYmxvY2sgKi9cbi8vaW50IGxhc3Q7ICAgICAgICAgLyogb25lIGlmIHRoaXMgaXMgdGhlIGxhc3QgYmxvY2sgZm9yIGEgZmlsZSAqL1xuXG4gIGxldCBvcHRfbGVuYiwgc3RhdGljX2xlbmI7ICAvKiBvcHRfbGVuIGFuZCBzdGF0aWNfbGVuIGluIGJ5dGVzICovXG4gIGxldCBtYXhfYmxpbmRleCA9IDA7ICAgICAgICAvKiBpbmRleCBvZiBsYXN0IGJpdCBsZW5ndGggY29kZSBvZiBub24gemVybyBmcmVxICovXG5cbiAgLyogQnVpbGQgdGhlIEh1ZmZtYW4gdHJlZXMgdW5sZXNzIGEgc3RvcmVkIGJsb2NrIGlzIGZvcmNlZCAqL1xuICBpZiAocy5sZXZlbCA+IDApIHtcblxuICAgIC8qIENoZWNrIGlmIHRoZSBmaWxlIGlzIGJpbmFyeSBvciB0ZXh0ICovXG4gICAgaWYgKHMuc3RybS5kYXRhX3R5cGUgPT09IFpfVU5LTk9XTiQxKSB7XG4gICAgICBzLnN0cm0uZGF0YV90eXBlID0gZGV0ZWN0X2RhdGFfdHlwZShzKTtcbiAgICB9XG5cbiAgICAvKiBDb25zdHJ1Y3QgdGhlIGxpdGVyYWwgYW5kIGRpc3RhbmNlIHRyZWVzICovXG4gICAgYnVpbGRfdHJlZShzLCBzLmxfZGVzYyk7XG4gICAgLy8gVHJhY2V2KChzdGRlcnIsIFwiXFxubGl0IGRhdGE6IGR5biAlbGQsIHN0YXQgJWxkXCIsIHMtPm9wdF9sZW4sXG4gICAgLy8gICAgICAgIHMtPnN0YXRpY19sZW4pKTtcblxuICAgIGJ1aWxkX3RyZWUocywgcy5kX2Rlc2MpO1xuICAgIC8vIFRyYWNldigoc3RkZXJyLCBcIlxcbmRpc3QgZGF0YTogZHluICVsZCwgc3RhdCAlbGRcIiwgcy0+b3B0X2xlbixcbiAgICAvLyAgICAgICAgcy0+c3RhdGljX2xlbikpO1xuICAgIC8qIEF0IHRoaXMgcG9pbnQsIG9wdF9sZW4gYW5kIHN0YXRpY19sZW4gYXJlIHRoZSB0b3RhbCBiaXQgbGVuZ3RocyBvZlxuICAgICAqIHRoZSBjb21wcmVzc2VkIGJsb2NrIGRhdGEsIGV4Y2x1ZGluZyB0aGUgdHJlZSByZXByZXNlbnRhdGlvbnMuXG4gICAgICovXG5cbiAgICAvKiBCdWlsZCB0aGUgYml0IGxlbmd0aCB0cmVlIGZvciB0aGUgYWJvdmUgdHdvIHRyZWVzLCBhbmQgZ2V0IHRoZSBpbmRleFxuICAgICAqIGluIGJsX29yZGVyIG9mIHRoZSBsYXN0IGJpdCBsZW5ndGggY29kZSB0byBzZW5kLlxuICAgICAqL1xuICAgIG1heF9ibGluZGV4ID0gYnVpbGRfYmxfdHJlZShzKTtcblxuICAgIC8qIERldGVybWluZSB0aGUgYmVzdCBlbmNvZGluZy4gQ29tcHV0ZSB0aGUgYmxvY2sgbGVuZ3RocyBpbiBieXRlcy4gKi9cbiAgICBvcHRfbGVuYiA9IChzLm9wdF9sZW4gKyAzICsgNykgPj4+IDM7XG4gICAgc3RhdGljX2xlbmIgPSAocy5zdGF0aWNfbGVuICsgMyArIDcpID4+PiAzO1xuXG4gICAgLy8gVHJhY2V2KChzdGRlcnIsIFwiXFxub3B0ICVsdSglbHUpIHN0YXQgJWx1KCVsdSkgc3RvcmVkICVsdSBsaXQgJXUgXCIsXG4gICAgLy8gICAgICAgIG9wdF9sZW5iLCBzLT5vcHRfbGVuLCBzdGF0aWNfbGVuYiwgcy0+c3RhdGljX2xlbiwgc3RvcmVkX2xlbixcbiAgICAvLyAgICAgICAgcy0+c3ltX25leHQgLyAzKSk7XG5cbiAgICBpZiAoc3RhdGljX2xlbmIgPD0gb3B0X2xlbmIpIHsgb3B0X2xlbmIgPSBzdGF0aWNfbGVuYjsgfVxuXG4gIH0gZWxzZSB7XG4gICAgLy8gQXNzZXJ0KGJ1ZiAhPSAoY2hhciopMCwgXCJsb3N0IGJ1ZlwiKTtcbiAgICBvcHRfbGVuYiA9IHN0YXRpY19sZW5iID0gc3RvcmVkX2xlbiArIDU7IC8qIGZvcmNlIGEgc3RvcmVkIGJsb2NrICovXG4gIH1cblxuICBpZiAoKHN0b3JlZF9sZW4gKyA0IDw9IG9wdF9sZW5iKSAmJiAoYnVmICE9PSAtMSkpIHtcbiAgICAvKiA0OiB0d28gd29yZHMgZm9yIHRoZSBsZW5ndGhzICovXG5cbiAgICAvKiBUaGUgdGVzdCBidWYgIT0gTlVMTCBpcyBvbmx5IG5lY2Vzc2FyeSBpZiBMSVRfQlVGU0laRSA+IFdTSVpFLlxuICAgICAqIE90aGVyd2lzZSB3ZSBjYW4ndCBoYXZlIHByb2Nlc3NlZCBtb3JlIHRoYW4gV1NJWkUgaW5wdXQgYnl0ZXMgc2luY2VcbiAgICAgKiB0aGUgbGFzdCBibG9jayBmbHVzaCwgYmVjYXVzZSBjb21wcmVzc2lvbiB3b3VsZCBoYXZlIGJlZW5cbiAgICAgKiBzdWNjZXNzZnVsLiBJZiBMSVRfQlVGU0laRSA8PSBXU0laRSwgaXQgaXMgbmV2ZXIgdG9vIGxhdGUgdG9cbiAgICAgKiB0cmFuc2Zvcm0gYSBibG9jayBpbnRvIGEgc3RvcmVkIGJsb2NrLlxuICAgICAqL1xuICAgIF90cl9zdG9yZWRfYmxvY2skMShzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpO1xuXG4gIH0gZWxzZSBpZiAocy5zdHJhdGVneSA9PT0gWl9GSVhFRCQxIHx8IHN0YXRpY19sZW5iID09PSBvcHRfbGVuYikge1xuXG4gICAgc2VuZF9iaXRzKHMsIChTVEFUSUNfVFJFRVMgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7XG4gICAgY29tcHJlc3NfYmxvY2socywgc3RhdGljX2x0cmVlLCBzdGF0aWNfZHRyZWUpO1xuXG4gIH0gZWxzZSB7XG4gICAgc2VuZF9iaXRzKHMsIChEWU5fVFJFRVMgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7XG4gICAgc2VuZF9hbGxfdHJlZXMocywgcy5sX2Rlc2MubWF4X2NvZGUgKyAxLCBzLmRfZGVzYy5tYXhfY29kZSArIDEsIG1heF9ibGluZGV4ICsgMSk7XG4gICAgY29tcHJlc3NfYmxvY2socywgcy5keW5fbHRyZWUsIHMuZHluX2R0cmVlKTtcbiAgfVxuICAvLyBBc3NlcnQgKHMtPmNvbXByZXNzZWRfbGVuID09IHMtPmJpdHNfc2VudCwgXCJiYWQgY29tcHJlc3NlZCBzaXplXCIpO1xuICAvKiBUaGUgYWJvdmUgY2hlY2sgaXMgbWFkZSBtb2QgMl4zMiwgZm9yIGZpbGVzIGxhcmdlciB0aGFuIDUxMiBNQlxuICAgKiBhbmQgdUxvbmcgaW1wbGVtZW50ZWQgb24gMzIgYml0cy5cbiAgICovXG4gIGluaXRfYmxvY2socyk7XG5cbiAgaWYgKGxhc3QpIHtcbiAgICBiaV93aW5kdXAocyk7XG4gIH1cbiAgLy8gVHJhY2V2KChzdGRlcnIsXCJcXG5jb21wcmxlbiAlbHUoJWx1KSBcIiwgcy0+Y29tcHJlc3NlZF9sZW4+PjMsXG4gIC8vICAgICAgIHMtPmNvbXByZXNzZWRfbGVuLTcqbGFzdCkpO1xufTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTYXZlIHRoZSBtYXRjaCBpbmZvIGFuZCB0YWxseSB0aGUgZnJlcXVlbmN5IGNvdW50cy4gUmV0dXJuIHRydWUgaWZcbiAqIHRoZSBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZC5cbiAqL1xuY29uc3QgX3RyX3RhbGx5JDEgPSAocywgZGlzdCwgbGMpID0+IHtcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICB1bnNpZ25lZCBkaXN0OyAgLyogZGlzdGFuY2Ugb2YgbWF0Y2hlZCBzdHJpbmcgKi9cbi8vICAgIHVuc2lnbmVkIGxjOyAgICAvKiBtYXRjaCBsZW5ndGgtTUlOX01BVENIIG9yIHVubWF0Y2hlZCBjaGFyIChpZiBkaXN0PT0wKSAqL1xuXG4gIHMucGVuZGluZ19idWZbcy5zeW1fYnVmICsgcy5zeW1fbmV4dCsrXSA9IGRpc3Q7XG4gIHMucGVuZGluZ19idWZbcy5zeW1fYnVmICsgcy5zeW1fbmV4dCsrXSA9IGRpc3QgPj4gODtcbiAgcy5wZW5kaW5nX2J1ZltzLnN5bV9idWYgKyBzLnN5bV9uZXh0KytdID0gbGM7XG4gIGlmIChkaXN0ID09PSAwKSB7XG4gICAgLyogbGMgaXMgdGhlIHVubWF0Y2hlZCBjaGFyICovXG4gICAgcy5keW5fbHRyZWVbbGMgKiAyXS8qLkZyZXEqLysrO1xuICB9IGVsc2Uge1xuICAgIHMubWF0Y2hlcysrO1xuICAgIC8qIEhlcmUsIGxjIGlzIHRoZSBtYXRjaCBsZW5ndGggLSBNSU5fTUFUQ0ggKi9cbiAgICBkaXN0LS07ICAgICAgICAgICAgIC8qIGRpc3QgPSBtYXRjaCBkaXN0YW5jZSAtIDEgKi9cbiAgICAvL0Fzc2VydCgodXNoKWRpc3QgPCAodXNoKU1BWF9ESVNUKHMpICYmXG4gICAgLy8gICAgICAgKHVzaClsYyA8PSAodXNoKShNQVhfTUFUQ0gtTUlOX01BVENIKSAmJlxuICAgIC8vICAgICAgICh1c2gpZF9jb2RlKGRpc3QpIDwgKHVzaClEX0NPREVTLCAgXCJfdHJfdGFsbHk6IGJhZCBtYXRjaFwiKTtcblxuICAgIHMuZHluX2x0cmVlWyhfbGVuZ3RoX2NvZGVbbGNdICsgTElURVJBTFMkMSArIDEpICogMl0vKi5GcmVxKi8rKztcbiAgICBzLmR5bl9kdHJlZVtkX2NvZGUoZGlzdCkgKiAyXS8qLkZyZXEqLysrO1xuICB9XG5cbiAgcmV0dXJuIChzLnN5bV9uZXh0ID09PSBzLnN5bV9lbmQpO1xufTtcblxudmFyIF90cl9pbml0XzEgID0gX3RyX2luaXQkMTtcbnZhciBfdHJfc3RvcmVkX2Jsb2NrXzEgPSBfdHJfc3RvcmVkX2Jsb2NrJDE7XG52YXIgX3RyX2ZsdXNoX2Jsb2NrXzEgID0gX3RyX2ZsdXNoX2Jsb2NrJDE7XG52YXIgX3RyX3RhbGx5XzEgPSBfdHJfdGFsbHkkMTtcbnZhciBfdHJfYWxpZ25fMSA9IF90cl9hbGlnbiQxO1xuXG52YXIgdHJlZXMgPSB7XG5cdF90cl9pbml0OiBfdHJfaW5pdF8xLFxuXHRfdHJfc3RvcmVkX2Jsb2NrOiBfdHJfc3RvcmVkX2Jsb2NrXzEsXG5cdF90cl9mbHVzaF9ibG9jazogX3RyX2ZsdXNoX2Jsb2NrXzEsXG5cdF90cl90YWxseTogX3RyX3RhbGx5XzEsXG5cdF90cl9hbGlnbjogX3RyX2FsaWduXzFcbn07XG5cbi8vIE5vdGU6IGFkbGVyMzIgdGFrZXMgMTIlIGZvciBsZXZlbCAwIGFuZCAyJSBmb3IgbGV2ZWwgNi5cbi8vIEl0IGlzbid0IHdvcnRoIGl0IHRvIG1ha2UgYWRkaXRpb25hbCBvcHRpbWl6YXRpb25zIGFzIGluIG9yaWdpbmFsLlxuLy8gU21hbGwgc2l6ZSBpcyBwcmVmZXJhYmxlLlxuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbmNvbnN0IGFkbGVyMzIgPSAoYWRsZXIsIGJ1ZiwgbGVuLCBwb3MpID0+IHtcbiAgbGV0IHMxID0gKGFkbGVyICYgMHhmZmZmKSB8MCxcbiAgICAgIHMyID0gKChhZGxlciA+Pj4gMTYpICYgMHhmZmZmKSB8MCxcbiAgICAgIG4gPSAwO1xuXG4gIHdoaWxlIChsZW4gIT09IDApIHtcbiAgICAvLyBTZXQgbGltaXQgfiB0d2ljZSBsZXNzIHRoYW4gNTU1MiwgdG8ga2VlcFxuICAgIC8vIHMyIGluIDMxLWJpdHMsIGJlY2F1c2Ugd2UgZm9yY2Ugc2lnbmVkIGludHMuXG4gICAgLy8gaW4gb3RoZXIgY2FzZSAlPSB3aWxsIGZhaWwuXG4gICAgbiA9IGxlbiA+IDIwMDAgPyAyMDAwIDogbGVuO1xuICAgIGxlbiAtPSBuO1xuXG4gICAgZG8ge1xuICAgICAgczEgPSAoczEgKyBidWZbcG9zKytdKSB8MDtcbiAgICAgIHMyID0gKHMyICsgczEpIHwwO1xuICAgIH0gd2hpbGUgKC0tbik7XG5cbiAgICBzMSAlPSA2NTUyMTtcbiAgICBzMiAlPSA2NTUyMTtcbiAgfVxuXG4gIHJldHVybiAoczEgfCAoczIgPDwgMTYpKSB8MDtcbn07XG5cblxudmFyIGFkbGVyMzJfMSA9IGFkbGVyMzI7XG5cbi8vIE5vdGU6IHdlIGNhbid0IGdldCBzaWduaWZpY2FudCBzcGVlZCBib29zdCBoZXJlLlxuLy8gU28gd3JpdGUgY29kZSB0byBtaW5pbWl6ZSBzaXplIC0gbm8gcHJlZ2VuZXJhdGVkIHRhYmxlc1xuLy8gYW5kIGFycmF5IHRvb2xzIGRlcGVuZGVuY2llcy5cblxuLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyXG4vLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpblxuLy9cbi8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkXG4vLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXNcbi8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsXG4vLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0XG4vLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6XG4vL1xuLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3Rcbi8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmVcbi8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlXG4vLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuXG4vLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZVxuLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuXG4vLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLlxuXG4vLyBVc2Ugb3JkaW5hcnkgYXJyYXksIHNpbmNlIHVudHlwZWQgbWFrZXMgbm8gYm9vc3QgaGVyZVxuY29uc3QgbWFrZVRhYmxlID0gKCkgPT4ge1xuICBsZXQgYywgdGFibGUgPSBbXTtcblxuICBmb3IgKHZhciBuID0gMDsgbiA8IDI1NjsgbisrKSB7XG4gICAgYyA9IG47XG4gICAgZm9yICh2YXIgayA9IDA7IGsgPCA4OyBrKyspIHtcbiAgICAgIGMgPSAoKGMgJiAxKSA/ICgweEVEQjg4MzIwIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG4gICAgfVxuICAgIHRhYmxlW25dID0gYztcbiAgfVxuXG4gIHJldHVybiB0YWJsZTtcbn07XG5cbi8vIENyZWF0ZSB0YWJsZSBvbiBsb2FkLiBKdXN0IDI1NSBzaWduZWQgbG9uZ3MuIE5vdCBhIHByb2JsZW0uXG5jb25zdCBjcmNUYWJsZSA9IG5ldyBVaW50MzJBcnJheShtYWtlVGFibGUoKSk7XG5cblxuY29uc3QgY3JjMzIgPSAoY3JjLCBidWYsIGxlbiwgcG9zKSA9PiB7XG4gIGNvbnN0IHQgPSBjcmNUYWJsZTtcbiAgY29uc3QgZW5kID0gcG9zICsgbGVuO1xuXG4gIGNyYyBePSAtMTtcblxuICBmb3IgKGxldCBpID0gcG9zOyBpIDwgZW5kOyBpKyspIHtcbiAgICBjcmMgPSAoY3JjID4+PiA4KSBeIHRbKGNyYyBeIGJ1ZltpXSkgJiAweEZGXTtcbiAgfVxuXG4gIHJldHVybiAoY3JjIF4gKC0xKSk7IC8vID4+PiAwO1xufTtcblxuXG52YXIgY3JjMzJfMSA9IGNyYzMyO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbnZhciBtZXNzYWdlcyA9IHtcbiAgMjogICAgICAnbmVlZCBkaWN0aW9uYXJ5JywgICAgIC8qIFpfTkVFRF9ESUNUICAgICAgIDIgICovXG4gIDE6ICAgICAgJ3N0cmVhbSBlbmQnLCAgICAgICAgICAvKiBaX1NUUkVBTV9FTkQgICAgICAxICAqL1xuICAwOiAgICAgICcnLCAgICAgICAgICAgICAgICAgICAgLyogWl9PSyAgICAgICAgICAgICAgMCAgKi9cbiAgJy0xJzogICAnZmlsZSBlcnJvcicsICAgICAgICAgIC8qIFpfRVJSTk8gICAgICAgICAoLTEpICovXG4gICctMic6ICAgJ3N0cmVhbSBlcnJvcicsICAgICAgICAvKiBaX1NUUkVBTV9FUlJPUiAgKC0yKSAqL1xuICAnLTMnOiAgICdkYXRhIGVycm9yJywgICAgICAgICAgLyogWl9EQVRBX0VSUk9SICAgICgtMykgKi9cbiAgJy00JzogICAnaW5zdWZmaWNpZW50IG1lbW9yeScsIC8qIFpfTUVNX0VSUk9SICAgICAoLTQpICovXG4gICctNSc6ICAgJ2J1ZmZlciBlcnJvcicsICAgICAgICAvKiBaX0JVRl9FUlJPUiAgICAgKC01KSAqL1xuICAnLTYnOiAgICdpbmNvbXBhdGlibGUgdmVyc2lvbicgLyogWl9WRVJTSU9OX0VSUk9SICgtNikgKi9cbn07XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxudmFyIGNvbnN0YW50cyQyID0ge1xuXG4gIC8qIEFsbG93ZWQgZmx1c2ggdmFsdWVzOyBzZWUgZGVmbGF0ZSgpIGFuZCBpbmZsYXRlKCkgYmVsb3cgZm9yIGRldGFpbHMgKi9cbiAgWl9OT19GTFVTSDogICAgICAgICAwLFxuICBaX1BBUlRJQUxfRkxVU0g6ICAgIDEsXG4gIFpfU1lOQ19GTFVTSDogICAgICAgMixcbiAgWl9GVUxMX0ZMVVNIOiAgICAgICAzLFxuICBaX0ZJTklTSDogICAgICAgICAgIDQsXG4gIFpfQkxPQ0s6ICAgICAgICAgICAgNSxcbiAgWl9UUkVFUzogICAgICAgICAgICA2LFxuXG4gIC8qIFJldHVybiBjb2RlcyBmb3IgdGhlIGNvbXByZXNzaW9uL2RlY29tcHJlc3Npb24gZnVuY3Rpb25zLiBOZWdhdGl2ZSB2YWx1ZXNcbiAgKiBhcmUgZXJyb3JzLCBwb3NpdGl2ZSB2YWx1ZXMgYXJlIHVzZWQgZm9yIHNwZWNpYWwgYnV0IG5vcm1hbCBldmVudHMuXG4gICovXG4gIFpfT0s6ICAgICAgICAgICAgICAgMCxcbiAgWl9TVFJFQU1fRU5EOiAgICAgICAxLFxuICBaX05FRURfRElDVDogICAgICAgIDIsXG4gIFpfRVJSTk86ICAgICAgICAgICAtMSxcbiAgWl9TVFJFQU1fRVJST1I6ICAgIC0yLFxuICBaX0RBVEFfRVJST1I6ICAgICAgLTMsXG4gIFpfTUVNX0VSUk9SOiAgICAgICAtNCxcbiAgWl9CVUZfRVJST1I6ICAgICAgIC01LFxuICAvL1pfVkVSU0lPTl9FUlJPUjogLTYsXG5cbiAgLyogY29tcHJlc3Npb24gbGV2ZWxzICovXG4gIFpfTk9fQ09NUFJFU1NJT046ICAgICAgICAgMCxcbiAgWl9CRVNUX1NQRUVEOiAgICAgICAgICAgICAxLFxuICBaX0JFU1RfQ09NUFJFU1NJT046ICAgICAgIDksXG4gIFpfREVGQVVMVF9DT01QUkVTU0lPTjogICAtMSxcblxuXG4gIFpfRklMVEVSRUQ6ICAgICAgICAgICAgICAgMSxcbiAgWl9IVUZGTUFOX09OTFk6ICAgICAgICAgICAyLFxuICBaX1JMRTogICAgICAgICAgICAgICAgICAgIDMsXG4gIFpfRklYRUQ6ICAgICAgICAgICAgICAgICAgNCxcbiAgWl9ERUZBVUxUX1NUUkFURUdZOiAgICAgICAwLFxuXG4gIC8qIFBvc3NpYmxlIHZhbHVlcyBvZiB0aGUgZGF0YV90eXBlIGZpZWxkICh0aG91Z2ggc2VlIGluZmxhdGUoKSkgKi9cbiAgWl9CSU5BUlk6ICAgICAgICAgICAgICAgICAwLFxuICBaX1RFWFQ6ICAgICAgICAgICAgICAgICAgIDEsXG4gIC8vWl9BU0NJSTogICAgICAgICAgICAgICAgMSwgLy8gPSBaX1RFWFQgKGRlcHJlY2F0ZWQpXG4gIFpfVU5LTk9XTjogICAgICAgICAgICAgICAgMixcblxuICAvKiBUaGUgZGVmbGF0ZSBjb21wcmVzc2lvbiBtZXRob2QgKi9cbiAgWl9ERUZMQVRFRDogICAgICAgICAgICAgICA4XG4gIC8vWl9OVUxMOiAgICAgICAgICAgICAgICAgbnVsbCAvLyBVc2UgLTEgb3IgbnVsbCBpbmxpbmUsIGRlcGVuZGluZyBvbiB2YXIgdHlwZVxufTtcblxuLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyXG4vLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpblxuLy9cbi8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkXG4vLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXNcbi8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsXG4vLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0XG4vLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6XG4vL1xuLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3Rcbi8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmVcbi8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlXG4vLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuXG4vLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZVxuLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuXG4vLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLlxuXG5jb25zdCB7IF90cl9pbml0LCBfdHJfc3RvcmVkX2Jsb2NrLCBfdHJfZmx1c2hfYmxvY2ssIF90cl90YWxseSwgX3RyX2FsaWduIH0gPSB0cmVlcztcblxuXG5cblxuLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cbmNvbnN0IHtcbiAgWl9OT19GTFVTSDogWl9OT19GTFVTSCQyLCBaX1BBUlRJQUxfRkxVU0gsIFpfRlVMTF9GTFVTSDogWl9GVUxMX0ZMVVNIJDEsIFpfRklOSVNIOiBaX0ZJTklTSCQzLCBaX0JMT0NLOiBaX0JMT0NLJDEsXG4gIFpfT0s6IFpfT0skMywgWl9TVFJFQU1fRU5EOiBaX1NUUkVBTV9FTkQkMywgWl9TVFJFQU1fRVJST1I6IFpfU1RSRUFNX0VSUk9SJDIsIFpfREFUQV9FUlJPUjogWl9EQVRBX0VSUk9SJDIsIFpfQlVGX0VSUk9SOiBaX0JVRl9FUlJPUiQxLFxuICBaX0RFRkFVTFRfQ09NUFJFU1NJT046IFpfREVGQVVMVF9DT01QUkVTU0lPTiQxLFxuICBaX0ZJTFRFUkVELCBaX0hVRkZNQU5fT05MWSwgWl9STEUsIFpfRklYRUQsIFpfREVGQVVMVF9TVFJBVEVHWTogWl9ERUZBVUxUX1NUUkFURUdZJDEsXG4gIFpfVU5LTk9XTixcbiAgWl9ERUZMQVRFRDogWl9ERUZMQVRFRCQyXG59ID0gY29uc3RhbnRzJDI7XG5cbi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuY29uc3QgTUFYX01FTV9MRVZFTCA9IDk7XG4vKiBNYXhpbXVtIHZhbHVlIGZvciBtZW1MZXZlbCBpbiBkZWZsYXRlSW5pdDIgKi9cbmNvbnN0IE1BWF9XQklUUyQxID0gMTU7XG4vKiAzMksgTFo3NyB3aW5kb3cgKi9cbmNvbnN0IERFRl9NRU1fTEVWRUwgPSA4O1xuXG5cbmNvbnN0IExFTkdUSF9DT0RFUyAgPSAyOTtcbi8qIG51bWJlciBvZiBsZW5ndGggY29kZXMsIG5vdCBjb3VudGluZyB0aGUgc3BlY2lhbCBFTkRfQkxPQ0sgY29kZSAqL1xuY29uc3QgTElURVJBTFMgICAgICA9IDI1Njtcbi8qIG51bWJlciBvZiBsaXRlcmFsIGJ5dGVzIDAuLjI1NSAqL1xuY29uc3QgTF9DT0RFUyAgICAgICA9IExJVEVSQUxTICsgMSArIExFTkdUSF9DT0RFUztcbi8qIG51bWJlciBvZiBMaXRlcmFsIG9yIExlbmd0aCBjb2RlcywgaW5jbHVkaW5nIHRoZSBFTkRfQkxPQ0sgY29kZSAqL1xuY29uc3QgRF9DT0RFUyAgICAgICA9IDMwO1xuLyogbnVtYmVyIG9mIGRpc3RhbmNlIGNvZGVzICovXG5jb25zdCBCTF9DT0RFUyAgICAgID0gMTk7XG4vKiBudW1iZXIgb2YgY29kZXMgdXNlZCB0byB0cmFuc2ZlciB0aGUgYml0IGxlbmd0aHMgKi9cbmNvbnN0IEhFQVBfU0laRSAgICAgPSAyICogTF9DT0RFUyArIDE7XG4vKiBtYXhpbXVtIGhlYXAgc2l6ZSAqL1xuY29uc3QgTUFYX0JJVFMgID0gMTU7XG4vKiBBbGwgY29kZXMgbXVzdCBub3QgZXhjZWVkIE1BWF9CSVRTIGJpdHMgKi9cblxuY29uc3QgTUlOX01BVENIID0gMztcbmNvbnN0IE1BWF9NQVRDSCA9IDI1ODtcbmNvbnN0IE1JTl9MT09LQUhFQUQgPSAoTUFYX01BVENIICsgTUlOX01BVENIICsgMSk7XG5cbmNvbnN0IFBSRVNFVF9ESUNUID0gMHgyMDtcblxuY29uc3QgSU5JVF9TVEFURSAgICA9ICA0MjsgICAgLyogemxpYiBoZWFkZXIgLT4gQlVTWV9TVEFURSAqL1xuLy8jaWZkZWYgR1pJUFxuY29uc3QgR1pJUF9TVEFURSAgICA9ICA1NzsgICAgLyogZ3ppcCBoZWFkZXIgLT4gQlVTWV9TVEFURSB8IEVYVFJBX1NUQVRFICovXG4vLyNlbmRpZlxuY29uc3QgRVhUUkFfU1RBVEUgICA9ICA2OTsgICAgLyogZ3ppcCBleHRyYSBibG9jayAtPiBOQU1FX1NUQVRFICovXG5jb25zdCBOQU1FX1NUQVRFICAgID0gIDczOyAgICAvKiBnemlwIGZpbGUgbmFtZSAtPiBDT01NRU5UX1NUQVRFICovXG5jb25zdCBDT01NRU5UX1NUQVRFID0gIDkxOyAgICAvKiBnemlwIGNvbW1lbnQgLT4gSENSQ19TVEFURSAqL1xuY29uc3QgSENSQ19TVEFURSAgICA9IDEwMzsgICAgLyogZ3ppcCBoZWFkZXIgQ1JDIC0+IEJVU1lfU1RBVEUgKi9cbmNvbnN0IEJVU1lfU1RBVEUgICAgPSAxMTM7ICAgIC8qIGRlZmxhdGUgLT4gRklOSVNIX1NUQVRFICovXG5jb25zdCBGSU5JU0hfU1RBVEUgID0gNjY2OyAgICAvKiBzdHJlYW0gY29tcGxldGUgKi9cblxuY29uc3QgQlNfTkVFRF9NT1JFICAgICAgPSAxOyAvKiBibG9jayBub3QgY29tcGxldGVkLCBuZWVkIG1vcmUgaW5wdXQgb3IgbW9yZSBvdXRwdXQgKi9cbmNvbnN0IEJTX0JMT0NLX0RPTkUgICAgID0gMjsgLyogYmxvY2sgZmx1c2ggcGVyZm9ybWVkICovXG5jb25zdCBCU19GSU5JU0hfU1RBUlRFRCA9IDM7IC8qIGZpbmlzaCBzdGFydGVkLCBuZWVkIG9ubHkgbW9yZSBvdXRwdXQgYXQgbmV4dCBkZWZsYXRlICovXG5jb25zdCBCU19GSU5JU0hfRE9ORSAgICA9IDQ7IC8qIGZpbmlzaCBkb25lLCBhY2NlcHQgbm8gbW9yZSBpbnB1dCBvciBvdXRwdXQgKi9cblxuY29uc3QgT1NfQ09ERSA9IDB4MDM7IC8vIFVuaXggOikgLiBEb24ndCBkZXRlY3QsIHVzZSB0aGlzIGRlZmF1bHQuXG5cbmNvbnN0IGVyciA9IChzdHJtLCBlcnJvckNvZGUpID0+IHtcbiAgc3RybS5tc2cgPSBtZXNzYWdlc1tlcnJvckNvZGVdO1xuICByZXR1cm4gZXJyb3JDb2RlO1xufTtcblxuY29uc3QgcmFuayA9IChmKSA9PiB7XG4gIHJldHVybiAoKGYpICogMikgLSAoKGYpID4gNCA/IDkgOiAwKTtcbn07XG5cbmNvbnN0IHplcm8gPSAoYnVmKSA9PiB7XG4gIGxldCBsZW4gPSBidWYubGVuZ3RoOyB3aGlsZSAoLS1sZW4gPj0gMCkgeyBidWZbbGVuXSA9IDA7IH1cbn07XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2xpZGUgdGhlIGhhc2ggdGFibGUgd2hlbiBzbGlkaW5nIHRoZSB3aW5kb3cgZG93biAoY291bGQgYmUgYXZvaWRlZCB3aXRoIDMyXG4gKiBiaXQgdmFsdWVzIGF0IHRoZSBleHBlbnNlIG9mIG1lbW9yeSB1c2FnZSkuIFdlIHNsaWRlIGV2ZW4gd2hlbiBsZXZlbCA9PSAwIHRvXG4gKiBrZWVwIHRoZSBoYXNoIHRhYmxlIGNvbnNpc3RlbnQgaWYgd2Ugc3dpdGNoIGJhY2sgdG8gbGV2ZWwgPiAwIGxhdGVyLlxuICovXG5jb25zdCBzbGlkZV9oYXNoID0gKHMpID0+IHtcbiAgbGV0IG4sIG07XG4gIGxldCBwO1xuICBsZXQgd3NpemUgPSBzLndfc2l6ZTtcblxuICBuID0gcy5oYXNoX3NpemU7XG4gIHAgPSBuO1xuICBkbyB7XG4gICAgbSA9IHMuaGVhZFstLXBdO1xuICAgIHMuaGVhZFtwXSA9IChtID49IHdzaXplID8gbSAtIHdzaXplIDogMCk7XG4gIH0gd2hpbGUgKC0tbik7XG4gIG4gPSB3c2l6ZTtcbi8vI2lmbmRlZiBGQVNURVNUXG4gIHAgPSBuO1xuICBkbyB7XG4gICAgbSA9IHMucHJldlstLXBdO1xuICAgIHMucHJldltwXSA9IChtID49IHdzaXplID8gbSAtIHdzaXplIDogMCk7XG4gICAgLyogSWYgbiBpcyBub3Qgb24gYW55IGhhc2ggY2hhaW4sIHByZXZbbl0gaXMgZ2FyYmFnZSBidXRcbiAgICAgKiBpdHMgdmFsdWUgd2lsbCBuZXZlciBiZSB1c2VkLlxuICAgICAqL1xuICB9IHdoaWxlICgtLW4pO1xuLy8jZW5kaWZcbn07XG5cbi8qIGVzbGludC1kaXNhYmxlIG5ldy1jYXAgKi9cbmxldCBIQVNIX1pMSUIgPSAocywgcHJldiwgZGF0YSkgPT4gKChwcmV2IDw8IHMuaGFzaF9zaGlmdCkgXiBkYXRhKSAmIHMuaGFzaF9tYXNrO1xuLy8gVGhpcyBoYXNoIGNhdXNlcyBsZXNzIGNvbGxpc2lvbnMsIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGFrby9pc3N1ZXMvMTM1XG4vLyBCdXQgYnJlYWtzIGJpbmFyeSBjb21wYXRpYmlsaXR5XG4vL2xldCBIQVNIX0ZBU1QgPSAocywgcHJldiwgZGF0YSkgPT4gKChwcmV2IDw8IDgpICsgKHByZXYgPj4gOCkgKyAoZGF0YSA8PCA0KSkgJiBzLmhhc2hfbWFzaztcbmxldCBIQVNIID0gSEFTSF9aTElCO1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZsdXNoIGFzIG11Y2ggcGVuZGluZyBvdXRwdXQgYXMgcG9zc2libGUuIEFsbCBkZWZsYXRlKCkgb3V0cHV0LCBleGNlcHQgZm9yXG4gKiBzb21lIGRlZmxhdGVfc3RvcmVkKCkgb3V0cHV0LCBnb2VzIHRocm91Z2ggdGhpcyBmdW5jdGlvbiBzbyBzb21lXG4gKiBhcHBsaWNhdGlvbnMgbWF5IHdpc2ggdG8gbW9kaWZ5IGl0IHRvIGF2b2lkIGFsbG9jYXRpbmcgYSBsYXJnZVxuICogc3RybS0+bmV4dF9vdXQgYnVmZmVyIGFuZCBjb3B5aW5nIGludG8gaXQuIChTZWUgYWxzbyByZWFkX2J1ZigpKS5cbiAqL1xuY29uc3QgZmx1c2hfcGVuZGluZyA9IChzdHJtKSA9PiB7XG4gIGNvbnN0IHMgPSBzdHJtLnN0YXRlO1xuXG4gIC8vX3RyX2ZsdXNoX2JpdHMocyk7XG4gIGxldCBsZW4gPSBzLnBlbmRpbmc7XG4gIGlmIChsZW4gPiBzdHJtLmF2YWlsX291dCkge1xuICAgIGxlbiA9IHN0cm0uYXZhaWxfb3V0O1xuICB9XG4gIGlmIChsZW4gPT09IDApIHsgcmV0dXJuOyB9XG5cbiAgc3RybS5vdXRwdXQuc2V0KHMucGVuZGluZ19idWYuc3ViYXJyYXkocy5wZW5kaW5nX291dCwgcy5wZW5kaW5nX291dCArIGxlbiksIHN0cm0ubmV4dF9vdXQpO1xuICBzdHJtLm5leHRfb3V0ICArPSBsZW47XG4gIHMucGVuZGluZ19vdXQgICs9IGxlbjtcbiAgc3RybS50b3RhbF9vdXQgKz0gbGVuO1xuICBzdHJtLmF2YWlsX291dCAtPSBsZW47XG4gIHMucGVuZGluZyAgICAgIC09IGxlbjtcbiAgaWYgKHMucGVuZGluZyA9PT0gMCkge1xuICAgIHMucGVuZGluZ19vdXQgPSAwO1xuICB9XG59O1xuXG5cbmNvbnN0IGZsdXNoX2Jsb2NrX29ubHkgPSAocywgbGFzdCkgPT4ge1xuICBfdHJfZmx1c2hfYmxvY2socywgKHMuYmxvY2tfc3RhcnQgPj0gMCA/IHMuYmxvY2tfc3RhcnQgOiAtMSksIHMuc3Ryc3RhcnQgLSBzLmJsb2NrX3N0YXJ0LCBsYXN0KTtcbiAgcy5ibG9ja19zdGFydCA9IHMuc3Ryc3RhcnQ7XG4gIGZsdXNoX3BlbmRpbmcocy5zdHJtKTtcbn07XG5cblxuY29uc3QgcHV0X2J5dGUgPSAocywgYikgPT4ge1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IGI7XG59O1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFB1dCBhIHNob3J0IGluIHRoZSBwZW5kaW5nIGJ1ZmZlci4gVGhlIDE2LWJpdCB2YWx1ZSBpcyBwdXQgaW4gTVNCIG9yZGVyLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgc3RyZWFtIHN0YXRlIGlzIGNvcnJlY3QgYW5kIHRoZXJlIGlzIGVub3VnaCByb29tIGluXG4gKiBwZW5kaW5nX2J1Zi5cbiAqL1xuY29uc3QgcHV0U2hvcnRNU0IgPSAocywgYikgPT4ge1xuXG4gIC8vICBwdXRfYnl0ZShzLCAoQnl0ZSkoYiA+PiA4KSk7XG4vLyAgcHV0X2J5dGUocywgKEJ5dGUpKGIgJiAweGZmKSk7XG4gIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gKGIgPj4+IDgpICYgMHhmZjtcbiAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBiICYgMHhmZjtcbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBSZWFkIGEgbmV3IGJ1ZmZlciBmcm9tIHRoZSBjdXJyZW50IGlucHV0IHN0cmVhbSwgdXBkYXRlIHRoZSBhZGxlcjMyXG4gKiBhbmQgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuICBBbGwgZGVmbGF0ZSgpIGlucHV0IGdvZXMgdGhyb3VnaFxuICogdGhpcyBmdW5jdGlvbiBzbyBzb21lIGFwcGxpY2F0aW9ucyBtYXkgd2lzaCB0byBtb2RpZnkgaXQgdG8gYXZvaWRcbiAqIGFsbG9jYXRpbmcgYSBsYXJnZSBzdHJtLT5pbnB1dCBidWZmZXIgYW5kIGNvcHlpbmcgZnJvbSBpdC5cbiAqIChTZWUgYWxzbyBmbHVzaF9wZW5kaW5nKCkpLlxuICovXG5jb25zdCByZWFkX2J1ZiA9IChzdHJtLCBidWYsIHN0YXJ0LCBzaXplKSA9PiB7XG5cbiAgbGV0IGxlbiA9IHN0cm0uYXZhaWxfaW47XG5cbiAgaWYgKGxlbiA+IHNpemUpIHsgbGVuID0gc2l6ZTsgfVxuICBpZiAobGVuID09PSAwKSB7IHJldHVybiAwOyB9XG5cbiAgc3RybS5hdmFpbF9pbiAtPSBsZW47XG5cbiAgLy8gem1lbWNweShidWYsIHN0cm0tPm5leHRfaW4sIGxlbik7XG4gIGJ1Zi5zZXQoc3RybS5pbnB1dC5zdWJhcnJheShzdHJtLm5leHRfaW4sIHN0cm0ubmV4dF9pbiArIGxlbiksIHN0YXJ0KTtcbiAgaWYgKHN0cm0uc3RhdGUud3JhcCA9PT0gMSkge1xuICAgIHN0cm0uYWRsZXIgPSBhZGxlcjMyXzEoc3RybS5hZGxlciwgYnVmLCBsZW4sIHN0YXJ0KTtcbiAgfVxuXG4gIGVsc2UgaWYgKHN0cm0uc3RhdGUud3JhcCA9PT0gMikge1xuICAgIHN0cm0uYWRsZXIgPSBjcmMzMl8xKHN0cm0uYWRsZXIsIGJ1ZiwgbGVuLCBzdGFydCk7XG4gIH1cblxuICBzdHJtLm5leHRfaW4gKz0gbGVuO1xuICBzdHJtLnRvdGFsX2luICs9IGxlbjtcblxuICByZXR1cm4gbGVuO1xufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNldCBtYXRjaF9zdGFydCB0byB0aGUgbG9uZ2VzdCBtYXRjaCBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gc3RyaW5nIGFuZFxuICogcmV0dXJuIGl0cyBsZW5ndGguIE1hdGNoZXMgc2hvcnRlciBvciBlcXVhbCB0byBwcmV2X2xlbmd0aCBhcmUgZGlzY2FyZGVkLFxuICogaW4gd2hpY2ggY2FzZSB0aGUgcmVzdWx0IGlzIGVxdWFsIHRvIHByZXZfbGVuZ3RoIGFuZCBtYXRjaF9zdGFydCBpc1xuICogZ2FyYmFnZS5cbiAqIElOIGFzc2VydGlvbnM6IGN1cl9tYXRjaCBpcyB0aGUgaGVhZCBvZiB0aGUgaGFzaCBjaGFpbiBmb3IgdGhlIGN1cnJlbnRcbiAqICAgc3RyaW5nIChzdHJzdGFydCkgYW5kIGl0cyBkaXN0YW5jZSBpcyA8PSBNQVhfRElTVCwgYW5kIHByZXZfbGVuZ3RoID49IDFcbiAqIE9VVCBhc3NlcnRpb246IHRoZSBtYXRjaCBsZW5ndGggaXMgbm90IGdyZWF0ZXIgdGhhbiBzLT5sb29rYWhlYWQuXG4gKi9cbmNvbnN0IGxvbmdlc3RfbWF0Y2ggPSAocywgY3VyX21hdGNoKSA9PiB7XG5cbiAgbGV0IGNoYWluX2xlbmd0aCA9IHMubWF4X2NoYWluX2xlbmd0aDsgICAgICAvKiBtYXggaGFzaCBjaGFpbiBsZW5ndGggKi9cbiAgbGV0IHNjYW4gPSBzLnN0cnN0YXJ0OyAvKiBjdXJyZW50IHN0cmluZyAqL1xuICBsZXQgbWF0Y2g7ICAgICAgICAgICAgICAgICAgICAgICAvKiBtYXRjaGVkIHN0cmluZyAqL1xuICBsZXQgbGVuOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBvZiBjdXJyZW50IG1hdGNoICovXG4gIGxldCBiZXN0X2xlbiA9IHMucHJldl9sZW5ndGg7ICAgICAgICAgICAgICAvKiBiZXN0IG1hdGNoIGxlbmd0aCBzbyBmYXIgKi9cbiAgbGV0IG5pY2VfbWF0Y2ggPSBzLm5pY2VfbWF0Y2g7ICAgICAgICAgICAgIC8qIHN0b3AgaWYgbWF0Y2ggbG9uZyBlbm91Z2ggKi9cbiAgY29uc3QgbGltaXQgPSAocy5zdHJzdGFydCA+IChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpKSA/XG4gICAgICBzLnN0cnN0YXJ0IC0gKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkgOiAwLypOSUwqLztcblxuICBjb25zdCBfd2luID0gcy53aW5kb3c7IC8vIHNob3J0Y3V0XG5cbiAgY29uc3Qgd21hc2sgPSBzLndfbWFzaztcbiAgY29uc3QgcHJldiAgPSBzLnByZXY7XG5cbiAgLyogU3RvcCB3aGVuIGN1cl9tYXRjaCBiZWNvbWVzIDw9IGxpbWl0LiBUbyBzaW1wbGlmeSB0aGUgY29kZSxcbiAgICogd2UgcHJldmVudCBtYXRjaGVzIHdpdGggdGhlIHN0cmluZyBvZiB3aW5kb3cgaW5kZXggMC5cbiAgICovXG5cbiAgY29uc3Qgc3RyZW5kID0gcy5zdHJzdGFydCArIE1BWF9NQVRDSDtcbiAgbGV0IHNjYW5fZW5kMSAgPSBfd2luW3NjYW4gKyBiZXN0X2xlbiAtIDFdO1xuICBsZXQgc2Nhbl9lbmQgICA9IF93aW5bc2NhbiArIGJlc3RfbGVuXTtcblxuICAvKiBUaGUgY29kZSBpcyBvcHRpbWl6ZWQgZm9yIEhBU0hfQklUUyA+PSA4IGFuZCBNQVhfTUFUQ0gtMiBtdWx0aXBsZSBvZiAxNi5cbiAgICogSXQgaXMgZWFzeSB0byBnZXQgcmlkIG9mIHRoaXMgb3B0aW1pemF0aW9uIGlmIG5lY2Vzc2FyeS5cbiAgICovXG4gIC8vIEFzc2VydChzLT5oYXNoX2JpdHMgPj0gOCAmJiBNQVhfTUFUQ0ggPT0gMjU4LCBcIkNvZGUgdG9vIGNsZXZlclwiKTtcblxuICAvKiBEbyBub3Qgd2FzdGUgdG9vIG11Y2ggdGltZSBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBnb29kIG1hdGNoOiAqL1xuICBpZiAocy5wcmV2X2xlbmd0aCA+PSBzLmdvb2RfbWF0Y2gpIHtcbiAgICBjaGFpbl9sZW5ndGggPj49IDI7XG4gIH1cbiAgLyogRG8gbm90IGxvb2sgZm9yIG1hdGNoZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIGlucHV0LiBUaGlzIGlzIG5lY2Vzc2FyeVxuICAgKiB0byBtYWtlIGRlZmxhdGUgZGV0ZXJtaW5pc3RpYy5cbiAgICovXG4gIGlmIChuaWNlX21hdGNoID4gcy5sb29rYWhlYWQpIHsgbmljZV9tYXRjaCA9IHMubG9va2FoZWFkOyB9XG5cbiAgLy8gQXNzZXJ0KCh1bGcpcy0+c3Ryc3RhcnQgPD0gcy0+d2luZG93X3NpemUtTUlOX0xPT0tBSEVBRCwgXCJuZWVkIGxvb2thaGVhZFwiKTtcblxuICBkbyB7XG4gICAgLy8gQXNzZXJ0KGN1cl9tYXRjaCA8IHMtPnN0cnN0YXJ0LCBcIm5vIGZ1dHVyZVwiKTtcbiAgICBtYXRjaCA9IGN1cl9tYXRjaDtcblxuICAgIC8qIFNraXAgdG8gbmV4dCBtYXRjaCBpZiB0aGUgbWF0Y2ggbGVuZ3RoIGNhbm5vdCBpbmNyZWFzZVxuICAgICAqIG9yIGlmIHRoZSBtYXRjaCBsZW5ndGggaXMgbGVzcyB0aGFuIDIuICBOb3RlIHRoYXQgdGhlIGNoZWNrcyBiZWxvd1xuICAgICAqIGZvciBpbnN1ZmZpY2llbnQgbG9va2FoZWFkIG9ubHkgb2NjdXIgb2NjYXNpb25hbGx5IGZvciBwZXJmb3JtYW5jZVxuICAgICAqIHJlYXNvbnMuICBUaGVyZWZvcmUgdW5pbml0aWFsaXplZCBtZW1vcnkgd2lsbCBiZSBhY2Nlc3NlZCwgYW5kXG4gICAgICogY29uZGl0aW9uYWwganVtcHMgd2lsbCBiZSBtYWRlIHRoYXQgZGVwZW5kIG9uIHRob3NlIHZhbHVlcy5cbiAgICAgKiBIb3dldmVyIHRoZSBsZW5ndGggb2YgdGhlIG1hdGNoIGlzIGxpbWl0ZWQgdG8gdGhlIGxvb2thaGVhZCwgc29cbiAgICAgKiB0aGUgb3V0cHV0IG9mIGRlZmxhdGUgaXMgbm90IGFmZmVjdGVkIGJ5IHRoZSB1bmluaXRpYWxpemVkIHZhbHVlcy5cbiAgICAgKi9cblxuICAgIGlmIChfd2luW21hdGNoICsgYmVzdF9sZW5dICAgICAhPT0gc2Nhbl9lbmQgIHx8XG4gICAgICAgIF93aW5bbWF0Y2ggKyBiZXN0X2xlbiAtIDFdICE9PSBzY2FuX2VuZDEgfHxcbiAgICAgICAgX3dpblttYXRjaF0gICAgICAgICAgICAgICAgIT09IF93aW5bc2Nhbl0gfHxcbiAgICAgICAgX3dpblsrK21hdGNoXSAgICAgICAgICAgICAgIT09IF93aW5bc2NhbiArIDFdKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvKiBUaGUgY2hlY2sgYXQgYmVzdF9sZW4tMSBjYW4gYmUgcmVtb3ZlZCBiZWNhdXNlIGl0IHdpbGwgYmUgbWFkZVxuICAgICAqIGFnYWluIGxhdGVyLiAoVGhpcyBoZXVyaXN0aWMgaXMgbm90IGFsd2F5cyBhIHdpbi4pXG4gICAgICogSXQgaXMgbm90IG5lY2Vzc2FyeSB0byBjb21wYXJlIHNjYW5bMl0gYW5kIG1hdGNoWzJdIHNpbmNlIHRoZXlcbiAgICAgKiBhcmUgYWx3YXlzIGVxdWFsIHdoZW4gdGhlIG90aGVyIGJ5dGVzIG1hdGNoLCBnaXZlbiB0aGF0XG4gICAgICogdGhlIGhhc2gga2V5cyBhcmUgZXF1YWwgYW5kIHRoYXQgSEFTSF9CSVRTID49IDguXG4gICAgICovXG4gICAgc2NhbiArPSAyO1xuICAgIG1hdGNoKys7XG4gICAgLy8gQXNzZXJ0KCpzY2FuID09ICptYXRjaCwgXCJtYXRjaFsyXT9cIik7XG5cbiAgICAvKiBXZSBjaGVjayBmb3IgaW5zdWZmaWNpZW50IGxvb2thaGVhZCBvbmx5IGV2ZXJ5IDh0aCBjb21wYXJpc29uO1xuICAgICAqIHRoZSAyNTZ0aCBjaGVjayB3aWxsIGJlIG1hZGUgYXQgc3Ryc3RhcnQrMjU4LlxuICAgICAqL1xuICAgIGRvIHtcbiAgICAgIC8qanNoaW50IG5vZW1wdHk6ZmFsc2UqL1xuICAgIH0gd2hpbGUgKF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiZcbiAgICAgICAgICAgICBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmXG4gICAgICAgICAgICAgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJlxuICAgICAgICAgICAgIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiZcbiAgICAgICAgICAgICBzY2FuIDwgc3RyZW5kKTtcblxuICAgIC8vIEFzc2VydChzY2FuIDw9IHMtPndpbmRvdysodW5zaWduZWQpKHMtPndpbmRvd19zaXplLTEpLCBcIndpbGQgc2NhblwiKTtcblxuICAgIGxlbiA9IE1BWF9NQVRDSCAtIChzdHJlbmQgLSBzY2FuKTtcbiAgICBzY2FuID0gc3RyZW5kIC0gTUFYX01BVENIO1xuXG4gICAgaWYgKGxlbiA+IGJlc3RfbGVuKSB7XG4gICAgICBzLm1hdGNoX3N0YXJ0ID0gY3VyX21hdGNoO1xuICAgICAgYmVzdF9sZW4gPSBsZW47XG4gICAgICBpZiAobGVuID49IG5pY2VfbWF0Y2gpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBzY2FuX2VuZDEgID0gX3dpbltzY2FuICsgYmVzdF9sZW4gLSAxXTtcbiAgICAgIHNjYW5fZW5kICAgPSBfd2luW3NjYW4gKyBiZXN0X2xlbl07XG4gICAgfVxuICB9IHdoaWxlICgoY3VyX21hdGNoID0gcHJldltjdXJfbWF0Y2ggJiB3bWFza10pID4gbGltaXQgJiYgLS1jaGFpbl9sZW5ndGggIT09IDApO1xuXG4gIGlmIChiZXN0X2xlbiA8PSBzLmxvb2thaGVhZCkge1xuICAgIHJldHVybiBiZXN0X2xlbjtcbiAgfVxuICByZXR1cm4gcy5sb29rYWhlYWQ7XG59O1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRmlsbCB0aGUgd2luZG93IHdoZW4gdGhlIGxvb2thaGVhZCBiZWNvbWVzIGluc3VmZmljaWVudC5cbiAqIFVwZGF0ZXMgc3Ryc3RhcnQgYW5kIGxvb2thaGVhZC5cbiAqXG4gKiBJTiBhc3NlcnRpb246IGxvb2thaGVhZCA8IE1JTl9MT09LQUhFQURcbiAqIE9VVCBhc3NlcnRpb25zOiBzdHJzdGFydCA8PSB3aW5kb3dfc2l6ZS1NSU5fTE9PS0FIRUFEXG4gKiAgICBBdCBsZWFzdCBvbmUgYnl0ZSBoYXMgYmVlbiByZWFkLCBvciBhdmFpbF9pbiA9PSAwOyByZWFkcyBhcmVcbiAqICAgIHBlcmZvcm1lZCBmb3IgYXQgbGVhc3QgdHdvIGJ5dGVzIChyZXF1aXJlZCBmb3IgdGhlIHppcCB0cmFuc2xhdGVfZW9sXG4gKiAgICBvcHRpb24gLS0gbm90IHN1cHBvcnRlZCBoZXJlKS5cbiAqL1xuY29uc3QgZmlsbF93aW5kb3cgPSAocykgPT4ge1xuXG4gIGNvbnN0IF93X3NpemUgPSBzLndfc2l6ZTtcbiAgbGV0IG4sIG1vcmUsIHN0cjtcblxuICAvL0Fzc2VydChzLT5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFELCBcImFscmVhZHkgZW5vdWdoIGxvb2thaGVhZFwiKTtcblxuICBkbyB7XG4gICAgbW9yZSA9IHMud2luZG93X3NpemUgLSBzLmxvb2thaGVhZCAtIHMuc3Ryc3RhcnQ7XG5cbiAgICAvLyBKUyBpbnRzIGhhdmUgMzIgYml0LCBibG9jayBiZWxvdyBub3QgbmVlZGVkXG4gICAgLyogRGVhbCB3aXRoICFAIyQlIDY0SyBsaW1pdDogKi9cbiAgICAvL2lmIChzaXplb2YoaW50KSA8PSAyKSB7XG4gICAgLy8gICAgaWYgKG1vcmUgPT0gMCAmJiBzLT5zdHJzdGFydCA9PSAwICYmIHMtPmxvb2thaGVhZCA9PSAwKSB7XG4gICAgLy8gICAgICAgIG1vcmUgPSB3c2l6ZTtcbiAgICAvL1xuICAgIC8vICB9IGVsc2UgaWYgKG1vcmUgPT0gKHVuc2lnbmVkKSgtMSkpIHtcbiAgICAvLyAgICAgICAgLyogVmVyeSB1bmxpa2VseSwgYnV0IHBvc3NpYmxlIG9uIDE2IGJpdCBtYWNoaW5lIGlmXG4gICAgLy8gICAgICAgICAqIHN0cnN0YXJ0ID09IDAgJiYgbG9va2FoZWFkID09IDEgKGlucHV0IGRvbmUgYSBieXRlIGF0IHRpbWUpXG4gICAgLy8gICAgICAgICAqL1xuICAgIC8vICAgICAgICBtb3JlLS07XG4gICAgLy8gICAgfVxuICAgIC8vfVxuXG5cbiAgICAvKiBJZiB0aGUgd2luZG93IGlzIGFsbW9zdCBmdWxsIGFuZCB0aGVyZSBpcyBpbnN1ZmZpY2llbnQgbG9va2FoZWFkLFxuICAgICAqIG1vdmUgdGhlIHVwcGVyIGhhbGYgdG8gdGhlIGxvd2VyIG9uZSB0byBtYWtlIHJvb20gaW4gdGhlIHVwcGVyIGhhbGYuXG4gICAgICovXG4gICAgaWYgKHMuc3Ryc3RhcnQgPj0gX3dfc2l6ZSArIChfd19zaXplIC0gTUlOX0xPT0tBSEVBRCkpIHtcblxuICAgICAgcy53aW5kb3cuc2V0KHMud2luZG93LnN1YmFycmF5KF93X3NpemUsIF93X3NpemUgKyBfd19zaXplIC0gbW9yZSksIDApO1xuICAgICAgcy5tYXRjaF9zdGFydCAtPSBfd19zaXplO1xuICAgICAgcy5zdHJzdGFydCAtPSBfd19zaXplO1xuICAgICAgLyogd2Ugbm93IGhhdmUgc3Ryc3RhcnQgPj0gTUFYX0RJU1QgKi9cbiAgICAgIHMuYmxvY2tfc3RhcnQgLT0gX3dfc2l6ZTtcbiAgICAgIGlmIChzLmluc2VydCA+IHMuc3Ryc3RhcnQpIHtcbiAgICAgICAgcy5pbnNlcnQgPSBzLnN0cnN0YXJ0O1xuICAgICAgfVxuICAgICAgc2xpZGVfaGFzaChzKTtcbiAgICAgIG1vcmUgKz0gX3dfc2l6ZTtcbiAgICB9XG4gICAgaWYgKHMuc3RybS5hdmFpbF9pbiA9PT0gMCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLyogSWYgdGhlcmUgd2FzIG5vIHNsaWRpbmc6XG4gICAgICogICAgc3Ryc3RhcnQgPD0gV1NJWkUrTUFYX0RJU1QtMSAmJiBsb29rYWhlYWQgPD0gTUlOX0xPT0tBSEVBRCAtIDEgJiZcbiAgICAgKiAgICBtb3JlID09IHdpbmRvd19zaXplIC0gbG9va2FoZWFkIC0gc3Ryc3RhcnRcbiAgICAgKiA9PiBtb3JlID49IHdpbmRvd19zaXplIC0gKE1JTl9MT09LQUhFQUQtMSArIFdTSVpFICsgTUFYX0RJU1QtMSlcbiAgICAgKiA9PiBtb3JlID49IHdpbmRvd19zaXplIC0gMipXU0laRSArIDJcbiAgICAgKiBJbiB0aGUgQklHX01FTSBvciBNTUFQIGNhc2UgKG5vdCB5ZXQgc3VwcG9ydGVkKSxcbiAgICAgKiAgIHdpbmRvd19zaXplID09IGlucHV0X3NpemUgKyBNSU5fTE9PS0FIRUFEICAmJlxuICAgICAqICAgc3Ryc3RhcnQgKyBzLT5sb29rYWhlYWQgPD0gaW5wdXRfc2l6ZSA9PiBtb3JlID49IE1JTl9MT09LQUhFQUQuXG4gICAgICogT3RoZXJ3aXNlLCB3aW5kb3dfc2l6ZSA9PSAyKldTSVpFIHNvIG1vcmUgPj0gMi5cbiAgICAgKiBJZiB0aGVyZSB3YXMgc2xpZGluZywgbW9yZSA+PSBXU0laRS4gU28gaW4gYWxsIGNhc2VzLCBtb3JlID49IDIuXG4gICAgICovXG4gICAgLy9Bc3NlcnQobW9yZSA+PSAyLCBcIm1vcmUgPCAyXCIpO1xuICAgIG4gPSByZWFkX2J1ZihzLnN0cm0sIHMud2luZG93LCBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQsIG1vcmUpO1xuICAgIHMubG9va2FoZWFkICs9IG47XG5cbiAgICAvKiBJbml0aWFsaXplIHRoZSBoYXNoIHZhbHVlIG5vdyB0aGF0IHdlIGhhdmUgc29tZSBpbnB1dDogKi9cbiAgICBpZiAocy5sb29rYWhlYWQgKyBzLmluc2VydCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIHN0ciA9IHMuc3Ryc3RhcnQgLSBzLmluc2VydDtcbiAgICAgIHMuaW5zX2ggPSBzLndpbmRvd1tzdHJdO1xuXG4gICAgICAvKiBVUERBVEVfSEFTSChzLCBzLT5pbnNfaCwgcy0+d2luZG93W3N0ciArIDFdKTsgKi9cbiAgICAgIHMuaW5zX2ggPSBIQVNIKHMsIHMuaW5zX2gsIHMud2luZG93W3N0ciArIDFdKTtcbi8vI2lmIE1JTl9NQVRDSCAhPSAzXG4vLyAgICAgICAgQ2FsbCB1cGRhdGVfaGFzaCgpIE1JTl9NQVRDSC0zIG1vcmUgdGltZXNcbi8vI2VuZGlmXG4gICAgICB3aGlsZSAocy5pbnNlcnQpIHtcbiAgICAgICAgLyogVVBEQVRFX0hBU0gocywgcy0+aW5zX2gsIHMtPndpbmRvd1tzdHIgKyBNSU5fTUFUQ0gtMV0pOyAqL1xuICAgICAgICBzLmluc19oID0gSEFTSChzLCBzLmluc19oLCBzLndpbmRvd1tzdHIgKyBNSU5fTUFUQ0ggLSAxXSk7XG5cbiAgICAgICAgcy5wcmV2W3N0ciAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgICAgcy5oZWFkW3MuaW5zX2hdID0gc3RyO1xuICAgICAgICBzdHIrKztcbiAgICAgICAgcy5pbnNlcnQtLTtcbiAgICAgICAgaWYgKHMubG9va2FoZWFkICsgcy5pbnNlcnQgPCBNSU5fTUFUQ0gpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvKiBJZiB0aGUgd2hvbGUgaW5wdXQgaGFzIGxlc3MgdGhhbiBNSU5fTUFUQ0ggYnl0ZXMsIGluc19oIGlzIGdhcmJhZ2UsXG4gICAgICogYnV0IHRoaXMgaXMgbm90IGltcG9ydGFudCBzaW5jZSBvbmx5IGxpdGVyYWwgYnl0ZXMgd2lsbCBiZSBlbWl0dGVkLlxuICAgICAqL1xuXG4gIH0gd2hpbGUgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCAmJiBzLnN0cm0uYXZhaWxfaW4gIT09IDApO1xuXG4gIC8qIElmIHRoZSBXSU5fSU5JVCBieXRlcyBhZnRlciB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGRhdGEgaGF2ZSBuZXZlciBiZWVuXG4gICAqIHdyaXR0ZW4sIHRoZW4gemVybyB0aG9zZSBieXRlcyBpbiBvcmRlciB0byBhdm9pZCBtZW1vcnkgY2hlY2sgcmVwb3J0cyBvZlxuICAgKiB0aGUgdXNlIG9mIHVuaW5pdGlhbGl6ZWQgKG9yIHVuaW5pdGlhbGlzZWQgYXMgSnVsaWFuIHdyaXRlcykgYnl0ZXMgYnlcbiAgICogdGhlIGxvbmdlc3QgbWF0Y2ggcm91dGluZXMuICBVcGRhdGUgdGhlIGhpZ2ggd2F0ZXIgbWFyayBmb3IgdGhlIG5leHRcbiAgICogdGltZSB0aHJvdWdoIGhlcmUuICBXSU5fSU5JVCBpcyBzZXQgdG8gTUFYX01BVENIIHNpbmNlIHRoZSBsb25nZXN0IG1hdGNoXG4gICAqIHJvdXRpbmVzIGFsbG93IHNjYW5uaW5nIHRvIHN0cnN0YXJ0ICsgTUFYX01BVENILCBpZ25vcmluZyBsb29rYWhlYWQuXG4gICAqL1xuLy8gIGlmIChzLmhpZ2hfd2F0ZXIgPCBzLndpbmRvd19zaXplKSB7XG4vLyAgICBjb25zdCBjdXJyID0gcy5zdHJzdGFydCArIHMubG9va2FoZWFkO1xuLy8gICAgbGV0IGluaXQgPSAwO1xuLy9cbi8vICAgIGlmIChzLmhpZ2hfd2F0ZXIgPCBjdXJyKSB7XG4vLyAgICAgIC8qIFByZXZpb3VzIGhpZ2ggd2F0ZXIgbWFyayBiZWxvdyBjdXJyZW50IGRhdGEgLS0gemVybyBXSU5fSU5JVFxuLy8gICAgICAgKiBieXRlcyBvciB1cCB0byBlbmQgb2Ygd2luZG93LCB3aGljaGV2ZXIgaXMgbGVzcy5cbi8vICAgICAgICovXG4vLyAgICAgIGluaXQgPSBzLndpbmRvd19zaXplIC0gY3Vycjtcbi8vICAgICAgaWYgKGluaXQgPiBXSU5fSU5JVClcbi8vICAgICAgICBpbml0ID0gV0lOX0lOSVQ7XG4vLyAgICAgIHptZW16ZXJvKHMtPndpbmRvdyArIGN1cnIsICh1bnNpZ25lZClpbml0KTtcbi8vICAgICAgcy0+aGlnaF93YXRlciA9IGN1cnIgKyBpbml0O1xuLy8gICAgfVxuLy8gICAgZWxzZSBpZiAocy0+aGlnaF93YXRlciA8ICh1bGcpY3VyciArIFdJTl9JTklUKSB7XG4vLyAgICAgIC8qIEhpZ2ggd2F0ZXIgbWFyayBhdCBvciBhYm92ZSBjdXJyZW50IGRhdGEsIGJ1dCBiZWxvdyBjdXJyZW50IGRhdGFcbi8vICAgICAgICogcGx1cyBXSU5fSU5JVCAtLSB6ZXJvIG91dCB0byBjdXJyZW50IGRhdGEgcGx1cyBXSU5fSU5JVCwgb3IgdXBcbi8vICAgICAgICogdG8gZW5kIG9mIHdpbmRvdywgd2hpY2hldmVyIGlzIGxlc3MuXG4vLyAgICAgICAqL1xuLy8gICAgICBpbml0ID0gKHVsZyljdXJyICsgV0lOX0lOSVQgLSBzLT5oaWdoX3dhdGVyO1xuLy8gICAgICBpZiAoaW5pdCA+IHMtPndpbmRvd19zaXplIC0gcy0+aGlnaF93YXRlcilcbi8vICAgICAgICBpbml0ID0gcy0+d2luZG93X3NpemUgLSBzLT5oaWdoX3dhdGVyO1xuLy8gICAgICB6bWVtemVybyhzLT53aW5kb3cgKyBzLT5oaWdoX3dhdGVyLCAodW5zaWduZWQpaW5pdCk7XG4vLyAgICAgIHMtPmhpZ2hfd2F0ZXIgKz0gaW5pdDtcbi8vICAgIH1cbi8vICB9XG4vL1xuLy8gIEFzc2VydCgodWxnKXMtPnN0cnN0YXJ0IDw9IHMtPndpbmRvd19zaXplIC0gTUlOX0xPT0tBSEVBRCxcbi8vICAgIFwibm90IGVub3VnaCByb29tIGZvciBzZWFyY2hcIik7XG59O1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHkgd2l0aG91dCBjb21wcmVzc2lvbiBhcyBtdWNoIGFzIHBvc3NpYmxlIGZyb20gdGhlIGlucHV0IHN0cmVhbSwgcmV0dXJuXG4gKiB0aGUgY3VycmVudCBibG9jayBzdGF0ZS5cbiAqXG4gKiBJbiBjYXNlIGRlZmxhdGVQYXJhbXMoKSBpcyB1c2VkIHRvIGxhdGVyIHN3aXRjaCB0byBhIG5vbi16ZXJvIGNvbXByZXNzaW9uXG4gKiBsZXZlbCwgcy0+bWF0Y2hlcyAob3RoZXJ3aXNlIHVudXNlZCB3aGVuIHN0b3JpbmcpIGtlZXBzIHRyYWNrIG9mIHRoZSBudW1iZXJcbiAqIG9mIGhhc2ggdGFibGUgc2xpZGVzIHRvIHBlcmZvcm0uIElmIHMtPm1hdGNoZXMgaXMgMSwgdGhlbiBvbmUgaGFzaCB0YWJsZVxuICogc2xpZGUgd2lsbCBiZSBkb25lIHdoZW4gc3dpdGNoaW5nLiBJZiBzLT5tYXRjaGVzIGlzIDIsIHRoZSBtYXhpbXVtIHZhbHVlXG4gKiBhbGxvd2VkIGhlcmUsIHRoZW4gdGhlIGhhc2ggdGFibGUgd2lsbCBiZSBjbGVhcmVkLCBzaW5jZSB0d28gb3IgbW9yZSBzbGlkZXNcbiAqIGlzIHRoZSBzYW1lIGFzIGEgY2xlYXIuXG4gKlxuICogZGVmbGF0ZV9zdG9yZWQoKSBpcyB3cml0dGVuIHRvIG1pbmltaXplIHRoZSBudW1iZXIgb2YgdGltZXMgYW4gaW5wdXQgYnl0ZSBpc1xuICogY29waWVkLiBJdCBpcyBtb3N0IGVmZmljaWVudCB3aXRoIGxhcmdlIGlucHV0IGFuZCBvdXRwdXQgYnVmZmVycywgd2hpY2hcbiAqIG1heGltaXplcyB0aGUgb3Bwb3J0dW5pdGVzIHRvIGhhdmUgYSBzaW5nbGUgY29weSBmcm9tIG5leHRfaW4gdG8gbmV4dF9vdXQuXG4gKi9cbmNvbnN0IGRlZmxhdGVfc3RvcmVkID0gKHMsIGZsdXNoKSA9PiB7XG5cbiAgLyogU21hbGxlc3Qgd29ydGh5IGJsb2NrIHNpemUgd2hlbiBub3QgZmx1c2hpbmcgb3IgZmluaXNoaW5nLiBCeSBkZWZhdWx0XG4gICAqIHRoaXMgaXMgMzJLLiBUaGlzIGNhbiBiZSBhcyBzbWFsbCBhcyA1MDcgYnl0ZXMgZm9yIG1lbUxldmVsID09IDEuIEZvclxuICAgKiBsYXJnZSBpbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMsIHRoZSBzdG9yZWQgYmxvY2sgc2l6ZSB3aWxsIGJlIGxhcmdlci5cbiAgICovXG4gIGxldCBtaW5fYmxvY2sgPSBzLnBlbmRpbmdfYnVmX3NpemUgLSA1ID4gcy53X3NpemUgPyBzLndfc2l6ZSA6IHMucGVuZGluZ19idWZfc2l6ZSAtIDU7XG5cbiAgLyogQ29weSBhcyBtYW55IG1pbl9ibG9jayBvciBsYXJnZXIgc3RvcmVkIGJsb2NrcyBkaXJlY3RseSB0byBuZXh0X291dCBhc1xuICAgKiBwb3NzaWJsZS4gSWYgZmx1c2hpbmcsIGNvcHkgdGhlIHJlbWFpbmluZyBhdmFpbGFibGUgaW5wdXQgdG8gbmV4dF9vdXQgYXNcbiAgICogc3RvcmVkIGJsb2NrcywgaWYgdGhlcmUgaXMgZW5vdWdoIHNwYWNlLlxuICAgKi9cbiAgbGV0IGxlbiwgbGVmdCwgaGF2ZSwgbGFzdCA9IDA7XG4gIGxldCB1c2VkID0gcy5zdHJtLmF2YWlsX2luO1xuICBkbyB7XG4gICAgLyogU2V0IGxlbiB0byB0aGUgbWF4aW11bSBzaXplIGJsb2NrIHRoYXQgd2UgY2FuIGNvcHkgZGlyZWN0bHkgd2l0aCB0aGVcbiAgICAgKiBhdmFpbGFibGUgaW5wdXQgZGF0YSBhbmQgb3V0cHV0IHNwYWNlLiBTZXQgbGVmdCB0byBob3cgbXVjaCBvZiB0aGF0XG4gICAgICogd291bGQgYmUgY29waWVkIGZyb20gd2hhdCdzIGxlZnQgaW4gdGhlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBsZW4gPSA2NTUzNS8qIE1BWF9TVE9SRUQgKi87ICAgICAvKiBtYXhpbXVtIGRlZmxhdGUgc3RvcmVkIGJsb2NrIGxlbmd0aCAqL1xuICAgIGhhdmUgPSAocy5iaV92YWxpZCArIDQyKSA+PiAzOyAgICAgLyogbnVtYmVyIG9mIGhlYWRlciBieXRlcyAqL1xuICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0IDwgaGF2ZSkgeyAgICAgICAgIC8qIG5lZWQgcm9vbSBmb3IgaGVhZGVyICovXG4gICAgICBicmVhaztcbiAgICB9XG4gICAgICAvKiBtYXhpbXVtIHN0b3JlZCBibG9jayBsZW5ndGggdGhhdCB3aWxsIGZpdCBpbiBhdmFpbF9vdXQ6ICovXG4gICAgaGF2ZSA9IHMuc3RybS5hdmFpbF9vdXQgLSBoYXZlO1xuICAgIGxlZnQgPSBzLnN0cnN0YXJ0IC0gcy5ibG9ja19zdGFydDsgIC8qIGJ5dGVzIGxlZnQgaW4gd2luZG93ICovXG4gICAgaWYgKGxlbiA+IGxlZnQgKyBzLnN0cm0uYXZhaWxfaW4pIHtcbiAgICAgIGxlbiA9IGxlZnQgKyBzLnN0cm0uYXZhaWxfaW47ICAgLyogbGltaXQgbGVuIHRvIHRoZSBpbnB1dCAqL1xuICAgIH1cbiAgICBpZiAobGVuID4gaGF2ZSkge1xuICAgICAgbGVuID0gaGF2ZTsgICAgICAgICAgICAgLyogbGltaXQgbGVuIHRvIHRoZSBvdXRwdXQgKi9cbiAgICB9XG5cbiAgICAvKiBJZiB0aGUgc3RvcmVkIGJsb2NrIHdvdWxkIGJlIGxlc3MgdGhhbiBtaW5fYmxvY2sgaW4gbGVuZ3RoLCBvciBpZlxuICAgICAqIHVuYWJsZSB0byBjb3B5IGFsbCBvZiB0aGUgYXZhaWxhYmxlIGlucHV0IHdoZW4gZmx1c2hpbmcsIHRoZW4gdHJ5XG4gICAgICogY29weWluZyB0byB0aGUgd2luZG93IGFuZCB0aGUgcGVuZGluZyBidWZmZXIgaW5zdGVhZC4gQWxzbyBkb24ndFxuICAgICAqIHdyaXRlIGFuIGVtcHR5IGJsb2NrIHdoZW4gZmx1c2hpbmcgLS0gZGVmbGF0ZSgpIGRvZXMgdGhhdC5cbiAgICAgKi9cbiAgICBpZiAobGVuIDwgbWluX2Jsb2NrICYmICgobGVuID09PSAwICYmIGZsdXNoICE9PSBaX0ZJTklTSCQzKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgZmx1c2ggPT09IFpfTk9fRkxVU0gkMiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuICE9PSBsZWZ0ICsgcy5zdHJtLmF2YWlsX2luKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLyogTWFrZSBhIGR1bW15IHN0b3JlZCBibG9jayBpbiBwZW5kaW5nIHRvIGdldCB0aGUgaGVhZGVyIGJ5dGVzLFxuICAgICAqIGluY2x1ZGluZyBhbnkgcGVuZGluZyBiaXRzLiBUaGlzIGFsc28gdXBkYXRlcyB0aGUgZGVidWdnaW5nIGNvdW50cy5cbiAgICAgKi9cbiAgICBsYXN0ID0gZmx1c2ggPT09IFpfRklOSVNIJDMgJiYgbGVuID09PSBsZWZ0ICsgcy5zdHJtLmF2YWlsX2luID8gMSA6IDA7XG4gICAgX3RyX3N0b3JlZF9ibG9jayhzLCAwLCAwLCBsYXN0KTtcblxuICAgIC8qIFJlcGxhY2UgdGhlIGxlbmd0aHMgaW4gdGhlIGR1bW15IHN0b3JlZCBibG9jayB3aXRoIGxlbi4gKi9cbiAgICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZyAtIDRdID0gbGVuO1xuICAgIHMucGVuZGluZ19idWZbcy5wZW5kaW5nIC0gM10gPSBsZW4gPj4gODtcbiAgICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZyAtIDJdID0gfmxlbjtcbiAgICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZyAtIDFdID0gfmxlbiA+PiA4O1xuXG4gICAgLyogV3JpdGUgdGhlIHN0b3JlZCBibG9jayBoZWFkZXIgYnl0ZXMuICovXG4gICAgZmx1c2hfcGVuZGluZyhzLnN0cm0pO1xuXG4vLyNpZmRlZiBaTElCX0RFQlVHXG4vLyAgICAvKiBVcGRhdGUgZGVidWdnaW5nIGNvdW50cyBmb3IgdGhlIGRhdGEgYWJvdXQgdG8gYmUgY29waWVkLiAqL1xuLy8gICAgcy0+Y29tcHJlc3NlZF9sZW4gKz0gbGVuIDw8IDM7XG4vLyAgICBzLT5iaXRzX3NlbnQgKz0gbGVuIDw8IDM7XG4vLyNlbmRpZlxuXG4gICAgLyogQ29weSB1bmNvbXByZXNzZWQgYnl0ZXMgZnJvbSB0aGUgd2luZG93IHRvIG5leHRfb3V0LiAqL1xuICAgIGlmIChsZWZ0KSB7XG4gICAgICBpZiAobGVmdCA+IGxlbikge1xuICAgICAgICBsZWZ0ID0gbGVuO1xuICAgICAgfVxuICAgICAgLy96bWVtY3B5KHMtPnN0cm0tPm5leHRfb3V0LCBzLT53aW5kb3cgKyBzLT5ibG9ja19zdGFydCwgbGVmdCk7XG4gICAgICBzLnN0cm0ub3V0cHV0LnNldChzLndpbmRvdy5zdWJhcnJheShzLmJsb2NrX3N0YXJ0LCBzLmJsb2NrX3N0YXJ0ICsgbGVmdCksIHMuc3RybS5uZXh0X291dCk7XG4gICAgICBzLnN0cm0ubmV4dF9vdXQgKz0gbGVmdDtcbiAgICAgIHMuc3RybS5hdmFpbF9vdXQgLT0gbGVmdDtcbiAgICAgIHMuc3RybS50b3RhbF9vdXQgKz0gbGVmdDtcbiAgICAgIHMuYmxvY2tfc3RhcnQgKz0gbGVmdDtcbiAgICAgIGxlbiAtPSBsZWZ0O1xuICAgIH1cblxuICAgIC8qIENvcHkgdW5jb21wcmVzc2VkIGJ5dGVzIGRpcmVjdGx5IGZyb20gbmV4dF9pbiB0byBuZXh0X291dCwgdXBkYXRpbmdcbiAgICAgKiB0aGUgY2hlY2sgdmFsdWUuXG4gICAgICovXG4gICAgaWYgKGxlbikge1xuICAgICAgcmVhZF9idWYocy5zdHJtLCBzLnN0cm0ub3V0cHV0LCBzLnN0cm0ubmV4dF9vdXQsIGxlbik7XG4gICAgICBzLnN0cm0ubmV4dF9vdXQgKz0gbGVuO1xuICAgICAgcy5zdHJtLmF2YWlsX291dCAtPSBsZW47XG4gICAgICBzLnN0cm0udG90YWxfb3V0ICs9IGxlbjtcbiAgICB9XG4gIH0gd2hpbGUgKGxhc3QgPT09IDApO1xuXG4gIC8qIFVwZGF0ZSB0aGUgc2xpZGluZyB3aW5kb3cgd2l0aCB0aGUgbGFzdCBzLT53X3NpemUgYnl0ZXMgb2YgdGhlIGNvcGllZFxuICAgKiBkYXRhLCBvciBhcHBlbmQgYWxsIG9mIHRoZSBjb3BpZWQgZGF0YSB0byB0aGUgZXhpc3Rpbmcgd2luZG93IGlmIGxlc3NcbiAgICogdGhhbiBzLT53X3NpemUgYnl0ZXMgd2VyZSBjb3BpZWQuIEFsc28gdXBkYXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG9cbiAgICogaW5zZXJ0IGluIHRoZSBoYXNoIHRhYmxlcywgaW4gdGhlIGV2ZW50IHRoYXQgZGVmbGF0ZVBhcmFtcygpIHN3aXRjaGVzIHRvXG4gICAqIGEgbm9uLXplcm8gY29tcHJlc3Npb24gbGV2ZWwuXG4gICAqL1xuICB1c2VkIC09IHMuc3RybS5hdmFpbF9pbjsgICAgLyogbnVtYmVyIG9mIGlucHV0IGJ5dGVzIGRpcmVjdGx5IGNvcGllZCAqL1xuICBpZiAodXNlZCkge1xuICAgIC8qIElmIGFueSBpbnB1dCB3YXMgdXNlZCwgdGhlbiBubyB1bnVzZWQgaW5wdXQgcmVtYWlucyBpbiB0aGUgd2luZG93LFxuICAgICAqIHRoZXJlZm9yZSBzLT5ibG9ja19zdGFydCA9PSBzLT5zdHJzdGFydC5cbiAgICAgKi9cbiAgICBpZiAodXNlZCA+PSBzLndfc2l6ZSkgeyAgLyogc3VwcGxhbnQgdGhlIHByZXZpb3VzIGhpc3RvcnkgKi9cbiAgICAgIHMubWF0Y2hlcyA9IDI7ICAgICAvKiBjbGVhciBoYXNoICovXG4gICAgICAvL3ptZW1jcHkocy0+d2luZG93LCBzLT5zdHJtLT5uZXh0X2luIC0gcy0+d19zaXplLCBzLT53X3NpemUpO1xuICAgICAgcy53aW5kb3cuc2V0KHMuc3RybS5pbnB1dC5zdWJhcnJheShzLnN0cm0ubmV4dF9pbiAtIHMud19zaXplLCBzLnN0cm0ubmV4dF9pbiksIDApO1xuICAgICAgcy5zdHJzdGFydCA9IHMud19zaXplO1xuICAgICAgcy5pbnNlcnQgPSBzLnN0cnN0YXJ0O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmIChzLndpbmRvd19zaXplIC0gcy5zdHJzdGFydCA8PSB1c2VkKSB7XG4gICAgICAgIC8qIFNsaWRlIHRoZSB3aW5kb3cgZG93bi4gKi9cbiAgICAgICAgcy5zdHJzdGFydCAtPSBzLndfc2l6ZTtcbiAgICAgICAgLy96bWVtY3B5KHMtPndpbmRvdywgcy0+d2luZG93ICsgcy0+d19zaXplLCBzLT5zdHJzdGFydCk7XG4gICAgICAgIHMud2luZG93LnNldChzLndpbmRvdy5zdWJhcnJheShzLndfc2l6ZSwgcy53X3NpemUgKyBzLnN0cnN0YXJ0KSwgMCk7XG4gICAgICAgIGlmIChzLm1hdGNoZXMgPCAyKSB7XG4gICAgICAgICAgcy5tYXRjaGVzKys7ICAgLyogYWRkIGEgcGVuZGluZyBzbGlkZV9oYXNoKCkgKi9cbiAgICAgICAgfVxuICAgICAgICBpZiAocy5pbnNlcnQgPiBzLnN0cnN0YXJ0KSB7XG4gICAgICAgICAgcy5pbnNlcnQgPSBzLnN0cnN0YXJ0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvL3ptZW1jcHkocy0+d2luZG93ICsgcy0+c3Ryc3RhcnQsIHMtPnN0cm0tPm5leHRfaW4gLSB1c2VkLCB1c2VkKTtcbiAgICAgIHMud2luZG93LnNldChzLnN0cm0uaW5wdXQuc3ViYXJyYXkocy5zdHJtLm5leHRfaW4gLSB1c2VkLCBzLnN0cm0ubmV4dF9pbiksIHMuc3Ryc3RhcnQpO1xuICAgICAgcy5zdHJzdGFydCArPSB1c2VkO1xuICAgICAgcy5pbnNlcnQgKz0gdXNlZCA+IHMud19zaXplIC0gcy5pbnNlcnQgPyBzLndfc2l6ZSAtIHMuaW5zZXJ0IDogdXNlZDtcbiAgICB9XG4gICAgcy5ibG9ja19zdGFydCA9IHMuc3Ryc3RhcnQ7XG4gIH1cbiAgaWYgKHMuaGlnaF93YXRlciA8IHMuc3Ryc3RhcnQpIHtcbiAgICBzLmhpZ2hfd2F0ZXIgPSBzLnN0cnN0YXJ0O1xuICB9XG5cbiAgLyogSWYgdGhlIGxhc3QgYmxvY2sgd2FzIHdyaXR0ZW4gdG8gbmV4dF9vdXQsIHRoZW4gZG9uZS4gKi9cbiAgaWYgKGxhc3QpIHtcbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cblxuICAvKiBJZiBmbHVzaGluZyBhbmQgYWxsIGlucHV0IGhhcyBiZWVuIGNvbnN1bWVkLCB0aGVuIGRvbmUuICovXG4gIGlmIChmbHVzaCAhPT0gWl9OT19GTFVTSCQyICYmIGZsdXNoICE9PSBaX0ZJTklTSCQzICYmXG4gICAgcy5zdHJtLmF2YWlsX2luID09PSAwICYmIHMuc3Ryc3RhcnQgPT09IHMuYmxvY2tfc3RhcnQpIHtcbiAgICByZXR1cm4gQlNfQkxPQ0tfRE9ORTtcbiAgfVxuXG4gIC8qIEZpbGwgdGhlIHdpbmRvdyB3aXRoIGFueSByZW1haW5pbmcgaW5wdXQuICovXG4gIGhhdmUgPSBzLndpbmRvd19zaXplIC0gcy5zdHJzdGFydDtcbiAgaWYgKHMuc3RybS5hdmFpbF9pbiA+IGhhdmUgJiYgcy5ibG9ja19zdGFydCA+PSBzLndfc2l6ZSkge1xuICAgIC8qIFNsaWRlIHRoZSB3aW5kb3cgZG93bi4gKi9cbiAgICBzLmJsb2NrX3N0YXJ0IC09IHMud19zaXplO1xuICAgIHMuc3Ryc3RhcnQgLT0gcy53X3NpemU7XG4gICAgLy96bWVtY3B5KHMtPndpbmRvdywgcy0+d2luZG93ICsgcy0+d19zaXplLCBzLT5zdHJzdGFydCk7XG4gICAgcy53aW5kb3cuc2V0KHMud2luZG93LnN1YmFycmF5KHMud19zaXplLCBzLndfc2l6ZSArIHMuc3Ryc3RhcnQpLCAwKTtcbiAgICBpZiAocy5tYXRjaGVzIDwgMikge1xuICAgICAgcy5tYXRjaGVzKys7ICAgICAgIC8qIGFkZCBhIHBlbmRpbmcgc2xpZGVfaGFzaCgpICovXG4gICAgfVxuICAgIGhhdmUgKz0gcy53X3NpemU7ICAgICAgLyogbW9yZSBzcGFjZSBub3cgKi9cbiAgICBpZiAocy5pbnNlcnQgPiBzLnN0cnN0YXJ0KSB7XG4gICAgICBzLmluc2VydCA9IHMuc3Ryc3RhcnQ7XG4gICAgfVxuICB9XG4gIGlmIChoYXZlID4gcy5zdHJtLmF2YWlsX2luKSB7XG4gICAgaGF2ZSA9IHMuc3RybS5hdmFpbF9pbjtcbiAgfVxuICBpZiAoaGF2ZSkge1xuICAgIHJlYWRfYnVmKHMuc3RybSwgcy53aW5kb3csIHMuc3Ryc3RhcnQsIGhhdmUpO1xuICAgIHMuc3Ryc3RhcnQgKz0gaGF2ZTtcbiAgICBzLmluc2VydCArPSBoYXZlID4gcy53X3NpemUgLSBzLmluc2VydCA/IHMud19zaXplIC0gcy5pbnNlcnQgOiBoYXZlO1xuICB9XG4gIGlmIChzLmhpZ2hfd2F0ZXIgPCBzLnN0cnN0YXJ0KSB7XG4gICAgcy5oaWdoX3dhdGVyID0gcy5zdHJzdGFydDtcbiAgfVxuXG4gIC8qIFRoZXJlIHdhcyBub3QgZW5vdWdoIGF2YWlsX291dCB0byB3cml0ZSBhIGNvbXBsZXRlIHdvcnRoeSBvciBmbHVzaGVkXG4gICAqIHN0b3JlZCBibG9jayB0byBuZXh0X291dC4gV3JpdGUgYSBzdG9yZWQgYmxvY2sgdG8gcGVuZGluZyBpbnN0ZWFkLCBpZiB3ZVxuICAgKiBoYXZlIGVub3VnaCBpbnB1dCBmb3IgYSB3b3J0aHkgYmxvY2ssIG9yIGlmIGZsdXNoaW5nIGFuZCB0aGVyZSBpcyBlbm91Z2hcbiAgICogcm9vbSBmb3IgdGhlIHJlbWFpbmluZyBpbnB1dCBhcyBhIHN0b3JlZCBibG9jayBpbiB0aGUgcGVuZGluZyBidWZmZXIuXG4gICAqL1xuICBoYXZlID0gKHMuYmlfdmFsaWQgKyA0MikgPj4gMzsgICAgIC8qIG51bWJlciBvZiBoZWFkZXIgYnl0ZXMgKi9cbiAgICAvKiBtYXhpbXVtIHN0b3JlZCBibG9jayBsZW5ndGggdGhhdCB3aWxsIGZpdCBpbiBwZW5kaW5nOiAqL1xuICBoYXZlID0gcy5wZW5kaW5nX2J1Zl9zaXplIC0gaGF2ZSA+IDY1NTM1LyogTUFYX1NUT1JFRCAqLyA/IDY1NTM1LyogTUFYX1NUT1JFRCAqLyA6IHMucGVuZGluZ19idWZfc2l6ZSAtIGhhdmU7XG4gIG1pbl9ibG9jayA9IGhhdmUgPiBzLndfc2l6ZSA/IHMud19zaXplIDogaGF2ZTtcbiAgbGVmdCA9IHMuc3Ryc3RhcnQgLSBzLmJsb2NrX3N0YXJ0O1xuICBpZiAobGVmdCA+PSBtaW5fYmxvY2sgfHxcbiAgICAgKChsZWZ0IHx8IGZsdXNoID09PSBaX0ZJTklTSCQzKSAmJiBmbHVzaCAhPT0gWl9OT19GTFVTSCQyICYmXG4gICAgIHMuc3RybS5hdmFpbF9pbiA9PT0gMCAmJiBsZWZ0IDw9IGhhdmUpKSB7XG4gICAgbGVuID0gbGVmdCA+IGhhdmUgPyBoYXZlIDogbGVmdDtcbiAgICBsYXN0ID0gZmx1c2ggPT09IFpfRklOSVNIJDMgJiYgcy5zdHJtLmF2YWlsX2luID09PSAwICYmXG4gICAgICAgICBsZW4gPT09IGxlZnQgPyAxIDogMDtcbiAgICBfdHJfc3RvcmVkX2Jsb2NrKHMsIHMuYmxvY2tfc3RhcnQsIGxlbiwgbGFzdCk7XG4gICAgcy5ibG9ja19zdGFydCArPSBsZW47XG4gICAgZmx1c2hfcGVuZGluZyhzLnN0cm0pO1xuICB9XG5cbiAgLyogV2UndmUgZG9uZSBhbGwgd2UgY2FuIHdpdGggdGhlIGF2YWlsYWJsZSBpbnB1dCBhbmQgb3V0cHV0LiAqL1xuICByZXR1cm4gbGFzdCA/IEJTX0ZJTklTSF9TVEFSVEVEIDogQlNfTkVFRF9NT1JFO1xufTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbXByZXNzIGFzIG11Y2ggYXMgcG9zc2libGUgZnJvbSB0aGUgaW5wdXQgc3RyZWFtLCByZXR1cm4gdGhlIGN1cnJlbnRcbiAqIGJsb2NrIHN0YXRlLlxuICogVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBwZXJmb3JtIGxhenkgZXZhbHVhdGlvbiBvZiBtYXRjaGVzIGFuZCBpbnNlcnRzXG4gKiBuZXcgc3RyaW5ncyBpbiB0aGUgZGljdGlvbmFyeSBvbmx5IGZvciB1bm1hdGNoZWQgc3RyaW5ncyBvciBmb3Igc2hvcnRcbiAqIG1hdGNoZXMuIEl0IGlzIHVzZWQgb25seSBmb3IgdGhlIGZhc3QgY29tcHJlc3Npb24gb3B0aW9ucy5cbiAqL1xuY29uc3QgZGVmbGF0ZV9mYXN0ID0gKHMsIGZsdXNoKSA9PiB7XG5cbiAgbGV0IGhhc2hfaGVhZDsgICAgICAgIC8qIGhlYWQgb2YgdGhlIGhhc2ggY2hhaW4gKi9cbiAgbGV0IGJmbHVzaDsgICAgICAgICAgIC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqL1xuXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHRcbiAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlc1xuICAgICAqIGZvciB0aGUgbmV4dCBtYXRjaCwgcGx1cyBNSU5fTUFUQ0ggYnl0ZXMgdG8gaW5zZXJ0IHRoZVxuICAgICAqIHN0cmluZyBmb2xsb3dpbmcgdGhlIG5leHQgbWF0Y2guXG4gICAgICovXG4gICAgaWYgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCkge1xuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEICYmIGZsdXNoID09PSBaX05PX0ZMVVNIJDIpIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgICBicmVhazsgLyogZmx1c2ggdGhlIGN1cnJlbnQgYmxvY2sgKi9cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKiBJbnNlcnQgdGhlIHN0cmluZyB3aW5kb3dbc3Ryc3RhcnQgLi4gc3Ryc3RhcnQrMl0gaW4gdGhlXG4gICAgICogZGljdGlvbmFyeSwgYW5kIHNldCBoYXNoX2hlYWQgdG8gdGhlIGhlYWQgb2YgdGhlIGhhc2ggY2hhaW46XG4gICAgICovXG4gICAgaGFzaF9oZWFkID0gMC8qTklMKi87XG4gICAgaWYgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkge1xuICAgICAgLyoqKiBJTlNFUlRfU1RSSU5HKHMsIHMuc3Ryc3RhcnQsIGhhc2hfaGVhZCk7ICoqKi9cbiAgICAgIHMuaW5zX2ggPSBIQVNIKHMsIHMuaW5zX2gsIHMud2luZG93W3Muc3Ryc3RhcnQgKyBNSU5fTUFUQ0ggLSAxXSk7XG4gICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgIHMuaGVhZFtzLmluc19oXSA9IHMuc3Ryc3RhcnQ7XG4gICAgICAvKioqL1xuICAgIH1cblxuICAgIC8qIEZpbmQgdGhlIGxvbmdlc3QgbWF0Y2gsIGRpc2NhcmRpbmcgdGhvc2UgPD0gcHJldl9sZW5ndGguXG4gICAgICogQXQgdGhpcyBwb2ludCB3ZSBoYXZlIGFsd2F5cyBtYXRjaF9sZW5ndGggPCBNSU5fTUFUQ0hcbiAgICAgKi9cbiAgICBpZiAoaGFzaF9oZWFkICE9PSAwLypOSUwqLyAmJiAoKHMuc3Ryc3RhcnQgLSBoYXNoX2hlYWQpIDw9IChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpKSkge1xuICAgICAgLyogVG8gc2ltcGxpZnkgdGhlIGNvZGUsIHdlIHByZXZlbnQgbWF0Y2hlcyB3aXRoIHRoZSBzdHJpbmdcbiAgICAgICAqIG9mIHdpbmRvdyBpbmRleCAwIChpbiBwYXJ0aWN1bGFyIHdlIGhhdmUgdG8gYXZvaWQgYSBtYXRjaFxuICAgICAgICogb2YgdGhlIHN0cmluZyB3aXRoIGl0c2VsZiBhdCB0aGUgc3RhcnQgb2YgdGhlIGlucHV0IGZpbGUpLlxuICAgICAgICovXG4gICAgICBzLm1hdGNoX2xlbmd0aCA9IGxvbmdlc3RfbWF0Y2gocywgaGFzaF9oZWFkKTtcbiAgICAgIC8qIGxvbmdlc3RfbWF0Y2goKSBzZXRzIG1hdGNoX3N0YXJ0ICovXG4gICAgfVxuICAgIGlmIChzLm1hdGNoX2xlbmd0aCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIC8vIGNoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQsIHMubWF0Y2hfc3RhcnQsIHMubWF0Y2hfbGVuZ3RoKTsgLy8gZm9yIGRlYnVnIG9ubHlcblxuICAgICAgLyoqKiBfdHJfdGFsbHlfZGlzdChzLCBzLnN0cnN0YXJ0IC0gcy5tYXRjaF9zdGFydCxcbiAgICAgICAgICAgICAgICAgICAgIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENILCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSBfdHJfdGFsbHkocywgcy5zdHJzdGFydCAtIHMubWF0Y2hfc3RhcnQsIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENIKTtcblxuICAgICAgcy5sb29rYWhlYWQgLT0gcy5tYXRjaF9sZW5ndGg7XG5cbiAgICAgIC8qIEluc2VydCBuZXcgc3RyaW5ncyBpbiB0aGUgaGFzaCB0YWJsZSBvbmx5IGlmIHRoZSBtYXRjaCBsZW5ndGhcbiAgICAgICAqIGlzIG5vdCB0b28gbGFyZ2UuIFRoaXMgc2F2ZXMgdGltZSBidXQgZGVncmFkZXMgY29tcHJlc3Npb24uXG4gICAgICAgKi9cbiAgICAgIGlmIChzLm1hdGNoX2xlbmd0aCA8PSBzLm1heF9sYXp5X21hdGNoLyptYXhfaW5zZXJ0X2xlbmd0aCovICYmIHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkge1xuICAgICAgICBzLm1hdGNoX2xlbmd0aC0tOyAvKiBzdHJpbmcgYXQgc3Ryc3RhcnQgYWxyZWFkeSBpbiB0YWJsZSAqL1xuICAgICAgICBkbyB7XG4gICAgICAgICAgcy5zdHJzdGFydCsrO1xuICAgICAgICAgIC8qKiogSU5TRVJUX1NUUklORyhzLCBzLnN0cnN0YXJ0LCBoYXNoX2hlYWQpOyAqKiovXG4gICAgICAgICAgcy5pbnNfaCA9IEhBU0gocywgcy5pbnNfaCwgcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKTtcbiAgICAgICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzLnN0cnN0YXJ0O1xuICAgICAgICAgIC8qKiovXG4gICAgICAgICAgLyogc3Ryc3RhcnQgbmV2ZXIgZXhjZWVkcyBXU0laRS1NQVhfTUFUQ0gsIHNvIHRoZXJlIGFyZVxuICAgICAgICAgICAqIGFsd2F5cyBNSU5fTUFUQ0ggYnl0ZXMgYWhlYWQuXG4gICAgICAgICAgICovXG4gICAgICAgIH0gd2hpbGUgKC0tcy5tYXRjaF9sZW5ndGggIT09IDApO1xuICAgICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgICB9IGVsc2VcbiAgICAgIHtcbiAgICAgICAgcy5zdHJzdGFydCArPSBzLm1hdGNoX2xlbmd0aDtcbiAgICAgICAgcy5tYXRjaF9sZW5ndGggPSAwO1xuICAgICAgICBzLmluc19oID0gcy53aW5kb3dbcy5zdHJzdGFydF07XG4gICAgICAgIC8qIFVQREFURV9IQVNIKHMsIHMuaW5zX2gsIHMud2luZG93W3Muc3Ryc3RhcnQrMV0pOyAqL1xuICAgICAgICBzLmluc19oID0gSEFTSChzLCBzLmluc19oLCBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgMV0pO1xuXG4vLyNpZiBNSU5fTUFUQ0ggIT0gM1xuLy8gICAgICAgICAgICAgICAgQ2FsbCBVUERBVEVfSEFTSCgpIE1JTl9NQVRDSC0zIG1vcmUgdGltZXNcbi8vI2VuZGlmXG4gICAgICAgIC8qIElmIGxvb2thaGVhZCA8IE1JTl9NQVRDSCwgaW5zX2ggaXMgZ2FyYmFnZSwgYnV0IGl0IGRvZXMgbm90XG4gICAgICAgICAqIG1hdHRlciBzaW5jZSBpdCB3aWxsIGJlIHJlY29tcHV0ZWQgYXQgbmV4dCBkZWZsYXRlIGNhbGwuXG4gICAgICAgICAqL1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiBObyBtYXRjaCwgb3V0cHV0IGEgbGl0ZXJhbCBieXRlICovXG4gICAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMud2luZG93W3Muc3Ryc3RhcnRdKSk7XG4gICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydF0sIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IF90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSk7XG5cbiAgICAgIHMubG9va2FoZWFkLS07XG4gICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgfVxuICAgIGlmIChiZmx1c2gpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG4gIHMuaW5zZXJ0ID0gKChzLnN0cnN0YXJ0IDwgKE1JTl9NQVRDSCAtIDEpKSA/IHMuc3Ryc3RhcnQgOiBNSU5fTUFUQ0ggLSAxKTtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCQzKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cbiAgaWYgKHMuc3ltX25leHQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cbiAgcmV0dXJuIEJTX0JMT0NLX0RPTkU7XG59O1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNhbWUgYXMgYWJvdmUsIGJ1dCBhY2hpZXZlcyBiZXR0ZXIgY29tcHJlc3Npb24uIFdlIHVzZSBhIGxhenlcbiAqIGV2YWx1YXRpb24gZm9yIG1hdGNoZXM6IGEgbWF0Y2ggaXMgZmluYWxseSBhZG9wdGVkIG9ubHkgaWYgdGhlcmUgaXNcbiAqIG5vIGJldHRlciBtYXRjaCBhdCB0aGUgbmV4dCB3aW5kb3cgcG9zaXRpb24uXG4gKi9cbmNvbnN0IGRlZmxhdGVfc2xvdyA9IChzLCBmbHVzaCkgPT4ge1xuXG4gIGxldCBoYXNoX2hlYWQ7ICAgICAgICAgIC8qIGhlYWQgb2YgaGFzaCBjaGFpbiAqL1xuICBsZXQgYmZsdXNoOyAgICAgICAgICAgICAgLyogc2V0IGlmIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkICovXG5cbiAgbGV0IG1heF9pbnNlcnQ7XG5cbiAgLyogUHJvY2VzcyB0aGUgaW5wdXQgYmxvY2suICovXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHRcbiAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlc1xuICAgICAqIGZvciB0aGUgbmV4dCBtYXRjaCwgcGx1cyBNSU5fTUFUQ0ggYnl0ZXMgdG8gaW5zZXJ0IHRoZVxuICAgICAqIHN0cmluZyBmb2xsb3dpbmcgdGhlIG5leHQgbWF0Y2guXG4gICAgICovXG4gICAgaWYgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCkge1xuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEICYmIGZsdXNoID09PSBaX05PX0ZMVVNIJDIpIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkgeyBicmVhazsgfSAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgIH1cblxuICAgIC8qIEluc2VydCB0aGUgc3RyaW5nIHdpbmRvd1tzdHJzdGFydCAuLiBzdHJzdGFydCsyXSBpbiB0aGVcbiAgICAgKiBkaWN0aW9uYXJ5LCBhbmQgc2V0IGhhc2hfaGVhZCB0byB0aGUgaGVhZCBvZiB0aGUgaGFzaCBjaGFpbjpcbiAgICAgKi9cbiAgICBoYXNoX2hlYWQgPSAwLypOSUwqLztcbiAgICBpZiAocy5sb29rYWhlYWQgPj0gTUlOX01BVENIKSB7XG4gICAgICAvKioqIElOU0VSVF9TVFJJTkcocywgcy5zdHJzdGFydCwgaGFzaF9oZWFkKTsgKioqL1xuICAgICAgcy5pbnNfaCA9IEhBU0gocywgcy5pbnNfaCwgcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKTtcbiAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuICAgICAgcy5oZWFkW3MuaW5zX2hdID0gcy5zdHJzdGFydDtcbiAgICAgIC8qKiovXG4gICAgfVxuXG4gICAgLyogRmluZCB0aGUgbG9uZ2VzdCBtYXRjaCwgZGlzY2FyZGluZyB0aG9zZSA8PSBwcmV2X2xlbmd0aC5cbiAgICAgKi9cbiAgICBzLnByZXZfbGVuZ3RoID0gcy5tYXRjaF9sZW5ndGg7XG4gICAgcy5wcmV2X21hdGNoID0gcy5tYXRjaF9zdGFydDtcbiAgICBzLm1hdGNoX2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7XG5cbiAgICBpZiAoaGFzaF9oZWFkICE9PSAwLypOSUwqLyAmJiBzLnByZXZfbGVuZ3RoIDwgcy5tYXhfbGF6eV9tYXRjaCAmJlxuICAgICAgICBzLnN0cnN0YXJ0IC0gaGFzaF9oZWFkIDw9IChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpLypNQVhfRElTVChzKSovKSB7XG4gICAgICAvKiBUbyBzaW1wbGlmeSB0aGUgY29kZSwgd2UgcHJldmVudCBtYXRjaGVzIHdpdGggdGhlIHN0cmluZ1xuICAgICAgICogb2Ygd2luZG93IGluZGV4IDAgKGluIHBhcnRpY3VsYXIgd2UgaGF2ZSB0byBhdm9pZCBhIG1hdGNoXG4gICAgICAgKiBvZiB0aGUgc3RyaW5nIHdpdGggaXRzZWxmIGF0IHRoZSBzdGFydCBvZiB0aGUgaW5wdXQgZmlsZSkuXG4gICAgICAgKi9cbiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gbG9uZ2VzdF9tYXRjaChzLCBoYXNoX2hlYWQpO1xuICAgICAgLyogbG9uZ2VzdF9tYXRjaCgpIHNldHMgbWF0Y2hfc3RhcnQgKi9cblxuICAgICAgaWYgKHMubWF0Y2hfbGVuZ3RoIDw9IDUgJiZcbiAgICAgICAgIChzLnN0cmF0ZWd5ID09PSBaX0ZJTFRFUkVEIHx8IChzLm1hdGNoX2xlbmd0aCA9PT0gTUlOX01BVENIICYmIHMuc3Ryc3RhcnQgLSBzLm1hdGNoX3N0YXJ0ID4gNDA5Ni8qVE9PX0ZBUiovKSkpIHtcblxuICAgICAgICAvKiBJZiBwcmV2X21hdGNoIGlzIGFsc28gTUlOX01BVENILCBtYXRjaF9zdGFydCBpcyBnYXJiYWdlXG4gICAgICAgICAqIGJ1dCB3ZSB3aWxsIGlnbm9yZSB0aGUgY3VycmVudCBtYXRjaCBhbnl3YXkuXG4gICAgICAgICAqL1xuICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7XG4gICAgICB9XG4gICAgfVxuICAgIC8qIElmIHRoZXJlIHdhcyBhIG1hdGNoIGF0IHRoZSBwcmV2aW91cyBzdGVwIGFuZCB0aGUgY3VycmVudFxuICAgICAqIG1hdGNoIGlzIG5vdCBiZXR0ZXIsIG91dHB1dCB0aGUgcHJldmlvdXMgbWF0Y2g6XG4gICAgICovXG4gICAgaWYgKHMucHJldl9sZW5ndGggPj0gTUlOX01BVENIICYmIHMubWF0Y2hfbGVuZ3RoIDw9IHMucHJldl9sZW5ndGgpIHtcbiAgICAgIG1heF9pbnNlcnQgPSBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQgLSBNSU5fTUFUQ0g7XG4gICAgICAvKiBEbyBub3QgaW5zZXJ0IHN0cmluZ3MgaW4gaGFzaCB0YWJsZSBiZXlvbmQgdGhpcy4gKi9cblxuICAgICAgLy9jaGVja19tYXRjaChzLCBzLnN0cnN0YXJ0LTEsIHMucHJldl9tYXRjaCwgcy5wcmV2X2xlbmd0aCk7XG5cbiAgICAgIC8qKipfdHJfdGFsbHlfZGlzdChzLCBzLnN0cnN0YXJ0IC0gMSAtIHMucHJldl9tYXRjaCxcbiAgICAgICAgICAgICAgICAgICAgIHMucHJldl9sZW5ndGggLSBNSU5fTUFUQ0gsIGJmbHVzaCk7KioqL1xuICAgICAgYmZsdXNoID0gX3RyX3RhbGx5KHMsIHMuc3Ryc3RhcnQgLSAxIC0gcy5wcmV2X21hdGNoLCBzLnByZXZfbGVuZ3RoIC0gTUlOX01BVENIKTtcbiAgICAgIC8qIEluc2VydCBpbiBoYXNoIHRhYmxlIGFsbCBzdHJpbmdzIHVwIHRvIHRoZSBlbmQgb2YgdGhlIG1hdGNoLlxuICAgICAgICogc3Ryc3RhcnQtMSBhbmQgc3Ryc3RhcnQgYXJlIGFscmVhZHkgaW5zZXJ0ZWQuIElmIHRoZXJlIGlzIG5vdFxuICAgICAgICogZW5vdWdoIGxvb2thaGVhZCwgdGhlIGxhc3QgdHdvIHN0cmluZ3MgYXJlIG5vdCBpbnNlcnRlZCBpblxuICAgICAgICogdGhlIGhhc2ggdGFibGUuXG4gICAgICAgKi9cbiAgICAgIHMubG9va2FoZWFkIC09IHMucHJldl9sZW5ndGggLSAxO1xuICAgICAgcy5wcmV2X2xlbmd0aCAtPSAyO1xuICAgICAgZG8ge1xuICAgICAgICBpZiAoKytzLnN0cnN0YXJ0IDw9IG1heF9pbnNlcnQpIHtcbiAgICAgICAgICAvKioqIElOU0VSVF9TVFJJTkcocywgcy5zdHJzdGFydCwgaGFzaF9oZWFkKTsgKioqL1xuICAgICAgICAgIHMuaW5zX2ggPSBIQVNIKHMsIHMuaW5zX2gsIHMud2luZG93W3Muc3Ryc3RhcnQgKyBNSU5fTUFUQ0ggLSAxXSk7XG4gICAgICAgICAgaGFzaF9oZWFkID0gcy5wcmV2W3Muc3Ryc3RhcnQgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG4gICAgICAgICAgcy5oZWFkW3MuaW5zX2hdID0gcy5zdHJzdGFydDtcbiAgICAgICAgICAvKioqL1xuICAgICAgICB9XG4gICAgICB9IHdoaWxlICgtLXMucHJldl9sZW5ndGggIT09IDApO1xuICAgICAgcy5tYXRjaF9hdmFpbGFibGUgPSAwO1xuICAgICAgcy5tYXRjaF9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuICAgICAgcy5zdHJzdGFydCsrO1xuXG4gICAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgICAgfVxuICAgICAgICAvKioqL1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmIChzLm1hdGNoX2F2YWlsYWJsZSkge1xuICAgICAgLyogSWYgdGhlcmUgd2FzIG5vIG1hdGNoIGF0IHRoZSBwcmV2aW91cyBwb3NpdGlvbiwgb3V0cHV0IGFcbiAgICAgICAqIHNpbmdsZSBsaXRlcmFsLiBJZiB0aGVyZSB3YXMgYSBtYXRjaCBidXQgdGhlIGN1cnJlbnQgbWF0Y2hcbiAgICAgICAqIGlzIGxvbmdlciwgdHJ1bmNhdGUgdGhlIHByZXZpb3VzIG1hdGNoIHRvIGEgc2luZ2xlIGxpdGVyYWwuXG4gICAgICAgKi9cbiAgICAgIC8vVHJhY2V2digoc3RkZXJyLFwiJWNcIiwgcy0+d2luZG93W3MtPnN0cnN0YXJ0LTFdKSk7XG4gICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydC0xXSwgYmZsdXNoKTsgKioqL1xuICAgICAgYmZsdXNoID0gX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnQgLSAxXSk7XG5cbiAgICAgIGlmIChiZmx1c2gpIHtcbiAgICAgICAgLyoqKiBGTFVTSF9CTE9DS19PTkxZKHMsIDApICoqKi9cbiAgICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICAgIC8qKiovXG4gICAgICB9XG4gICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgICBzLmxvb2thaGVhZC0tO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLyogVGhlcmUgaXMgbm8gcHJldmlvdXMgbWF0Y2ggdG8gY29tcGFyZSB3aXRoLCB3YWl0IGZvclxuICAgICAgICogdGhlIG5leHQgc3RlcCB0byBkZWNpZGUuXG4gICAgICAgKi9cbiAgICAgIHMubWF0Y2hfYXZhaWxhYmxlID0gMTtcbiAgICAgIHMuc3Ryc3RhcnQrKztcbiAgICAgIHMubG9va2FoZWFkLS07XG4gICAgfVxuICB9XG4gIC8vQXNzZXJ0IChmbHVzaCAhPSBaX05PX0ZMVVNILCBcIm5vIGZsdXNoP1wiKTtcbiAgaWYgKHMubWF0Y2hfYXZhaWxhYmxlKSB7XG4gICAgLy9UcmFjZXZ2KChzdGRlcnIsXCIlY1wiLCBzLT53aW5kb3dbcy0+c3Ryc3RhcnQtMV0pKTtcbiAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydC0xXSwgYmZsdXNoKTsgKioqL1xuICAgIGJmbHVzaCA9IF90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0IC0gMV0pO1xuXG4gICAgcy5tYXRjaF9hdmFpbGFibGUgPSAwO1xuICB9XG4gIHMuaW5zZXJ0ID0gcy5zdHJzdGFydCA8IE1JTl9NQVRDSCAtIDEgPyBzLnN0cnN0YXJ0IDogTUlOX01BVENIIC0gMTtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCQzKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cbiAgaWYgKHMuc3ltX25leHQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cblxuICByZXR1cm4gQlNfQkxPQ0tfRE9ORTtcbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGb3IgWl9STEUsIHNpbXBseSBsb29rIGZvciBydW5zIG9mIGJ5dGVzLCBnZW5lcmF0ZSBtYXRjaGVzIG9ubHkgb2YgZGlzdGFuY2VcbiAqIG9uZS4gIERvIG5vdCBtYWludGFpbiBhIGhhc2ggdGFibGUuICAoSXQgd2lsbCBiZSByZWdlbmVyYXRlZCBpZiB0aGlzIHJ1biBvZlxuICogZGVmbGF0ZSBzd2l0Y2hlcyBhd2F5IGZyb20gWl9STEUuKVxuICovXG5jb25zdCBkZWZsYXRlX3JsZSA9IChzLCBmbHVzaCkgPT4ge1xuXG4gIGxldCBiZmx1c2g7ICAgICAgICAgICAgLyogc2V0IGlmIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkICovXG4gIGxldCBwcmV2OyAgICAgICAgICAgICAgLyogYnl0ZSBhdCBkaXN0YW5jZSBvbmUgdG8gbWF0Y2ggKi9cbiAgbGV0IHNjYW4sIHN0cmVuZDsgICAgICAvKiBzY2FuIGdvZXMgdXAgdG8gc3RyZW5kIGZvciBsZW5ndGggb2YgcnVuICovXG5cbiAgY29uc3QgX3dpbiA9IHMud2luZG93O1xuXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHRcbiAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlc1xuICAgICAqIGZvciB0aGUgbG9uZ2VzdCBydW4sIHBsdXMgb25lIGZvciB0aGUgdW5yb2xsZWQgbG9vcC5cbiAgICAgKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPD0gTUFYX01BVENIKSB7XG4gICAgICBmaWxsX3dpbmRvdyhzKTtcbiAgICAgIGlmIChzLmxvb2thaGVhZCA8PSBNQVhfTUFUQ0ggJiYgZmx1c2ggPT09IFpfTk9fRkxVU0gkMikge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7IGJyZWFrOyB9IC8qIGZsdXNoIHRoZSBjdXJyZW50IGJsb2NrICovXG4gICAgfVxuXG4gICAgLyogU2VlIGhvdyBtYW55IHRpbWVzIHRoZSBwcmV2aW91cyBieXRlIHJlcGVhdHMgKi9cbiAgICBzLm1hdGNoX2xlbmd0aCA9IDA7XG4gICAgaWYgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCAmJiBzLnN0cnN0YXJ0ID4gMCkge1xuICAgICAgc2NhbiA9IHMuc3Ryc3RhcnQgLSAxO1xuICAgICAgcHJldiA9IF93aW5bc2Nhbl07XG4gICAgICBpZiAocHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0pIHtcbiAgICAgICAgc3RyZW5kID0gcy5zdHJzdGFydCArIE1BWF9NQVRDSDtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIC8qanNoaW50IG5vZW1wdHk6ZmFsc2UqL1xuICAgICAgICB9IHdoaWxlIChwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmXG4gICAgICAgICAgICAgICAgIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiZcbiAgICAgICAgICAgICAgICAgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJlxuICAgICAgICAgICAgICAgICBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmXG4gICAgICAgICAgICAgICAgIHNjYW4gPCBzdHJlbmQpO1xuICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IE1BWF9NQVRDSCAtIChzdHJlbmQgLSBzY2FuKTtcbiAgICAgICAgaWYgKHMubWF0Y2hfbGVuZ3RoID4gcy5sb29rYWhlYWQpIHtcbiAgICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IHMubG9va2FoZWFkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvL0Fzc2VydChzY2FuIDw9IHMtPndpbmRvdysodUludCkocy0+d2luZG93X3NpemUtMSksIFwid2lsZCBzY2FuXCIpO1xuICAgIH1cblxuICAgIC8qIEVtaXQgbWF0Y2ggaWYgaGF2ZSBydW4gb2YgTUlOX01BVENIIG9yIGxvbmdlciwgZWxzZSBlbWl0IGxpdGVyYWwgKi9cbiAgICBpZiAocy5tYXRjaF9sZW5ndGggPj0gTUlOX01BVENIKSB7XG4gICAgICAvL2NoZWNrX21hdGNoKHMsIHMuc3Ryc3RhcnQsIHMuc3Ryc3RhcnQgLSAxLCBzLm1hdGNoX2xlbmd0aCk7XG5cbiAgICAgIC8qKiogX3RyX3RhbGx5X2Rpc3QocywgMSwgcy5tYXRjaF9sZW5ndGggLSBNSU5fTUFUQ0gsIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IF90cl90YWxseShzLCAxLCBzLm1hdGNoX2xlbmd0aCAtIE1JTl9NQVRDSCk7XG5cbiAgICAgIHMubG9va2FoZWFkIC09IHMubWF0Y2hfbGVuZ3RoO1xuICAgICAgcy5zdHJzdGFydCArPSBzLm1hdGNoX2xlbmd0aDtcbiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgLyogTm8gbWF0Y2gsIG91dHB1dCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsXCIlY1wiLCBzLT53aW5kb3dbcy0+c3Ryc3RhcnRdKSk7XG4gICAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydF0sIGJmbHVzaCk7ICoqKi9cbiAgICAgIGJmbHVzaCA9IF90cl90YWxseShzLCAwLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSk7XG5cbiAgICAgIHMubG9va2FoZWFkLS07XG4gICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgfVxuICAgIGlmIChiZmx1c2gpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG4gIHMuaW5zZXJ0ID0gMDtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCQzKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cbiAgaWYgKHMuc3ltX25leHQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cbiAgcmV0dXJuIEJTX0JMT0NLX0RPTkU7XG59O1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZvciBaX0hVRkZNQU5fT05MWSwgZG8gbm90IGxvb2sgZm9yIG1hdGNoZXMuICBEbyBub3QgbWFpbnRhaW4gYSBoYXNoIHRhYmxlLlxuICogKEl0IHdpbGwgYmUgcmVnZW5lcmF0ZWQgaWYgdGhpcyBydW4gb2YgZGVmbGF0ZSBzd2l0Y2hlcyBhd2F5IGZyb20gSHVmZm1hbi4pXG4gKi9cbmNvbnN0IGRlZmxhdGVfaHVmZiA9IChzLCBmbHVzaCkgPT4ge1xuXG4gIGxldCBiZmx1c2g7ICAgICAgICAgICAgIC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqL1xuXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBoYXZlIGEgbGl0ZXJhbCB0byB3cml0ZS4gKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgIGZpbGxfd2luZG93KHMpO1xuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7XG4gICAgICAgIGlmIChmbHVzaCA9PT0gWl9OT19GTFVTSCQyKSB7XG4gICAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgICAgfVxuICAgICAgICBicmVhazsgICAgICAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qIE91dHB1dCBhIGxpdGVyYWwgYnl0ZSAqL1xuICAgIHMubWF0Y2hfbGVuZ3RoID0gMDtcbiAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMtPndpbmRvd1tzLT5zdHJzdGFydF0pKTtcbiAgICAvKioqIF90cl90YWxseV9saXQocywgcy53aW5kb3dbcy5zdHJzdGFydF0sIGJmbHVzaCk7ICoqKi9cbiAgICBiZmx1c2ggPSBfdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydF0pO1xuICAgIHMubG9va2FoZWFkLS07XG4gICAgcy5zdHJzdGFydCsrO1xuICAgIGlmIChiZmx1c2gpIHtcbiAgICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICAgIGZsdXNoX2Jsb2NrX29ubHkocywgZmFsc2UpO1xuICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICAgIH1cbiAgICAgIC8qKiovXG4gICAgfVxuICB9XG4gIHMuaW5zZXJ0ID0gMDtcbiAgaWYgKGZsdXNoID09PSBaX0ZJTklTSCQzKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cbiAgaWYgKHMuc3ltX25leHQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cbiAgcmV0dXJuIEJTX0JMT0NLX0RPTkU7XG59O1xuXG4vKiBWYWx1ZXMgZm9yIG1heF9sYXp5X21hdGNoLCBnb29kX21hdGNoIGFuZCBtYXhfY2hhaW5fbGVuZ3RoLCBkZXBlbmRpbmcgb25cbiAqIHRoZSBkZXNpcmVkIHBhY2sgbGV2ZWwgKDAuLjkpLiBUaGUgdmFsdWVzIGdpdmVuIGJlbG93IGhhdmUgYmVlbiB0dW5lZCB0b1xuICogZXhjbHVkZSB3b3JzdCBjYXNlIHBlcmZvcm1hbmNlIGZvciBwYXRob2xvZ2ljYWwgZmlsZXMuIEJldHRlciB2YWx1ZXMgbWF5IGJlXG4gKiBmb3VuZCBmb3Igc3BlY2lmaWMgZmlsZXMuXG4gKi9cbmZ1bmN0aW9uIENvbmZpZyhnb29kX2xlbmd0aCwgbWF4X2xhenksIG5pY2VfbGVuZ3RoLCBtYXhfY2hhaW4sIGZ1bmMpIHtcblxuICB0aGlzLmdvb2RfbGVuZ3RoID0gZ29vZF9sZW5ndGg7XG4gIHRoaXMubWF4X2xhenkgPSBtYXhfbGF6eTtcbiAgdGhpcy5uaWNlX2xlbmd0aCA9IG5pY2VfbGVuZ3RoO1xuICB0aGlzLm1heF9jaGFpbiA9IG1heF9jaGFpbjtcbiAgdGhpcy5mdW5jID0gZnVuYztcbn1cblxuY29uc3QgY29uZmlndXJhdGlvbl90YWJsZSA9IFtcbiAgLyogICAgICBnb29kIGxhenkgbmljZSBjaGFpbiAqL1xuICBuZXcgQ29uZmlnKDAsIDAsIDAsIDAsIGRlZmxhdGVfc3RvcmVkKSwgICAgICAgICAgLyogMCBzdG9yZSBvbmx5ICovXG4gIG5ldyBDb25maWcoNCwgNCwgOCwgNCwgZGVmbGF0ZV9mYXN0KSwgICAgICAgICAgICAvKiAxIG1heCBzcGVlZCwgbm8gbGF6eSBtYXRjaGVzICovXG4gIG5ldyBDb25maWcoNCwgNSwgMTYsIDgsIGRlZmxhdGVfZmFzdCksICAgICAgICAgICAvKiAyICovXG4gIG5ldyBDb25maWcoNCwgNiwgMzIsIDMyLCBkZWZsYXRlX2Zhc3QpLCAgICAgICAgICAvKiAzICovXG5cbiAgbmV3IENvbmZpZyg0LCA0LCAxNiwgMTYsIGRlZmxhdGVfc2xvdyksICAgICAgICAgIC8qIDQgbGF6eSBtYXRjaGVzICovXG4gIG5ldyBDb25maWcoOCwgMTYsIDMyLCAzMiwgZGVmbGF0ZV9zbG93KSwgICAgICAgICAvKiA1ICovXG4gIG5ldyBDb25maWcoOCwgMTYsIDEyOCwgMTI4LCBkZWZsYXRlX3Nsb3cpLCAgICAgICAvKiA2ICovXG4gIG5ldyBDb25maWcoOCwgMzIsIDEyOCwgMjU2LCBkZWZsYXRlX3Nsb3cpLCAgICAgICAvKiA3ICovXG4gIG5ldyBDb25maWcoMzIsIDEyOCwgMjU4LCAxMDI0LCBkZWZsYXRlX3Nsb3cpLCAgICAvKiA4ICovXG4gIG5ldyBDb25maWcoMzIsIDI1OCwgMjU4LCA0MDk2LCBkZWZsYXRlX3Nsb3cpICAgICAvKiA5IG1heCBjb21wcmVzc2lvbiAqL1xuXTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgdGhlIFwibG9uZ2VzdCBtYXRjaFwiIHJvdXRpbmVzIGZvciBhIG5ldyB6bGliIHN0cmVhbVxuICovXG5jb25zdCBsbV9pbml0ID0gKHMpID0+IHtcblxuICBzLndpbmRvd19zaXplID0gMiAqIHMud19zaXplO1xuXG4gIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqL1xuICB6ZXJvKHMuaGVhZCk7IC8vIEZpbGwgd2l0aCBOSUwgKD0gMCk7XG5cbiAgLyogU2V0IHRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyczpcbiAgICovXG4gIHMubWF4X2xhenlfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm1heF9sYXp5O1xuICBzLmdvb2RfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLmdvb2RfbGVuZ3RoO1xuICBzLm5pY2VfbWF0Y2ggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm5pY2VfbGVuZ3RoO1xuICBzLm1heF9jaGFpbl9sZW5ndGggPSBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLm1heF9jaGFpbjtcblxuICBzLnN0cnN0YXJ0ID0gMDtcbiAgcy5ibG9ja19zdGFydCA9IDA7XG4gIHMubG9va2FoZWFkID0gMDtcbiAgcy5pbnNlcnQgPSAwO1xuICBzLm1hdGNoX2xlbmd0aCA9IHMucHJldl9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuICBzLm1hdGNoX2F2YWlsYWJsZSA9IDA7XG4gIHMuaW5zX2ggPSAwO1xufTtcblxuXG5mdW5jdGlvbiBEZWZsYXRlU3RhdGUoKSB7XG4gIHRoaXMuc3RybSA9IG51bGw7ICAgICAgICAgICAgLyogcG9pbnRlciBiYWNrIHRvIHRoaXMgemxpYiBzdHJlYW0gKi9cbiAgdGhpcy5zdGF0dXMgPSAwOyAgICAgICAgICAgIC8qIGFzIHRoZSBuYW1lIGltcGxpZXMgKi9cbiAgdGhpcy5wZW5kaW5nX2J1ZiA9IG51bGw7ICAgICAgLyogb3V0cHV0IHN0aWxsIHBlbmRpbmcgKi9cbiAgdGhpcy5wZW5kaW5nX2J1Zl9zaXplID0gMDsgIC8qIHNpemUgb2YgcGVuZGluZ19idWYgKi9cbiAgdGhpcy5wZW5kaW5nX291dCA9IDA7ICAgICAgIC8qIG5leHQgcGVuZGluZyBieXRlIHRvIG91dHB1dCB0byB0aGUgc3RyZWFtICovXG4gIHRoaXMucGVuZGluZyA9IDA7ICAgICAgICAgICAvKiBuYiBvZiBieXRlcyBpbiB0aGUgcGVuZGluZyBidWZmZXIgKi9cbiAgdGhpcy53cmFwID0gMDsgICAgICAgICAgICAgIC8qIGJpdCAwIHRydWUgZm9yIHpsaWIsIGJpdCAxIHRydWUgZm9yIGd6aXAgKi9cbiAgdGhpcy5nemhlYWQgPSBudWxsOyAgICAgICAgIC8qIGd6aXAgaGVhZGVyIGluZm9ybWF0aW9uIHRvIHdyaXRlICovXG4gIHRoaXMuZ3ppbmRleCA9IDA7ICAgICAgICAgICAvKiB3aGVyZSBpbiBleHRyYSwgbmFtZSwgb3IgY29tbWVudCAqL1xuICB0aGlzLm1ldGhvZCA9IFpfREVGTEFURUQkMjsgLyogY2FuIG9ubHkgYmUgREVGTEFURUQgKi9cbiAgdGhpcy5sYXN0X2ZsdXNoID0gLTE7ICAgLyogdmFsdWUgb2YgZmx1c2ggcGFyYW0gZm9yIHByZXZpb3VzIGRlZmxhdGUgY2FsbCAqL1xuXG4gIHRoaXMud19zaXplID0gMDsgIC8qIExaNzcgd2luZG93IHNpemUgKDMySyBieSBkZWZhdWx0KSAqL1xuICB0aGlzLndfYml0cyA9IDA7ICAvKiBsb2cyKHdfc2l6ZSkgICg4Li4xNikgKi9cbiAgdGhpcy53X21hc2sgPSAwOyAgLyogd19zaXplIC0gMSAqL1xuXG4gIHRoaXMud2luZG93ID0gbnVsbDtcbiAgLyogU2xpZGluZyB3aW5kb3cuIElucHV0IGJ5dGVzIGFyZSByZWFkIGludG8gdGhlIHNlY29uZCBoYWxmIG9mIHRoZSB3aW5kb3csXG4gICAqIGFuZCBtb3ZlIHRvIHRoZSBmaXJzdCBoYWxmIGxhdGVyIHRvIGtlZXAgYSBkaWN0aW9uYXJ5IG9mIGF0IGxlYXN0IHdTaXplXG4gICAqIGJ5dGVzLiBXaXRoIHRoaXMgb3JnYW5pemF0aW9uLCBtYXRjaGVzIGFyZSBsaW1pdGVkIHRvIGEgZGlzdGFuY2Ugb2ZcbiAgICogd1NpemUtTUFYX01BVENIIGJ5dGVzLCBidXQgdGhpcyBlbnN1cmVzIHRoYXQgSU8gaXMgYWx3YXlzXG4gICAqIHBlcmZvcm1lZCB3aXRoIGEgbGVuZ3RoIG11bHRpcGxlIG9mIHRoZSBibG9jayBzaXplLlxuICAgKi9cblxuICB0aGlzLndpbmRvd19zaXplID0gMDtcbiAgLyogQWN0dWFsIHNpemUgb2Ygd2luZG93OiAyKndTaXplLCBleGNlcHQgd2hlbiB0aGUgdXNlciBpbnB1dCBidWZmZXJcbiAgICogaXMgZGlyZWN0bHkgdXNlZCBhcyBzbGlkaW5nIHdpbmRvdy5cbiAgICovXG5cbiAgdGhpcy5wcmV2ID0gbnVsbDtcbiAgLyogTGluayB0byBvbGRlciBzdHJpbmcgd2l0aCBzYW1lIGhhc2ggaW5kZXguIFRvIGxpbWl0IHRoZSBzaXplIG9mIHRoaXNcbiAgICogYXJyYXkgdG8gNjRLLCB0aGlzIGxpbmsgaXMgbWFpbnRhaW5lZCBvbmx5IGZvciB0aGUgbGFzdCAzMksgc3RyaW5ncy5cbiAgICogQW4gaW5kZXggaW4gdGhpcyBhcnJheSBpcyB0aHVzIGEgd2luZG93IGluZGV4IG1vZHVsbyAzMksuXG4gICAqL1xuXG4gIHRoaXMuaGVhZCA9IG51bGw7ICAgLyogSGVhZHMgb2YgdGhlIGhhc2ggY2hhaW5zIG9yIE5JTC4gKi9cblxuICB0aGlzLmluc19oID0gMDsgICAgICAgLyogaGFzaCBpbmRleCBvZiBzdHJpbmcgdG8gYmUgaW5zZXJ0ZWQgKi9cbiAgdGhpcy5oYXNoX3NpemUgPSAwOyAgIC8qIG51bWJlciBvZiBlbGVtZW50cyBpbiBoYXNoIHRhYmxlICovXG4gIHRoaXMuaGFzaF9iaXRzID0gMDsgICAvKiBsb2cyKGhhc2hfc2l6ZSkgKi9cbiAgdGhpcy5oYXNoX21hc2sgPSAwOyAgIC8qIGhhc2hfc2l6ZS0xICovXG5cbiAgdGhpcy5oYXNoX3NoaWZ0ID0gMDtcbiAgLyogTnVtYmVyIG9mIGJpdHMgYnkgd2hpY2ggaW5zX2ggbXVzdCBiZSBzaGlmdGVkIGF0IGVhY2ggaW5wdXRcbiAgICogc3RlcC4gSXQgbXVzdCBiZSBzdWNoIHRoYXQgYWZ0ZXIgTUlOX01BVENIIHN0ZXBzLCB0aGUgb2xkZXN0XG4gICAqIGJ5dGUgbm8gbG9uZ2VyIHRha2VzIHBhcnQgaW4gdGhlIGhhc2gga2V5LCB0aGF0IGlzOlxuICAgKiAgIGhhc2hfc2hpZnQgKiBNSU5fTUFUQ0ggPj0gaGFzaF9iaXRzXG4gICAqL1xuXG4gIHRoaXMuYmxvY2tfc3RhcnQgPSAwO1xuICAvKiBXaW5kb3cgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgY3VycmVudCBvdXRwdXQgYmxvY2suIEdldHNcbiAgICogbmVnYXRpdmUgd2hlbiB0aGUgd2luZG93IGlzIG1vdmVkIGJhY2t3YXJkcy5cbiAgICovXG5cbiAgdGhpcy5tYXRjaF9sZW5ndGggPSAwOyAgICAgIC8qIGxlbmd0aCBvZiBiZXN0IG1hdGNoICovXG4gIHRoaXMucHJldl9tYXRjaCA9IDA7ICAgICAgICAvKiBwcmV2aW91cyBtYXRjaCAqL1xuICB0aGlzLm1hdGNoX2F2YWlsYWJsZSA9IDA7ICAgLyogc2V0IGlmIHByZXZpb3VzIG1hdGNoIGV4aXN0cyAqL1xuICB0aGlzLnN0cnN0YXJ0ID0gMDsgICAgICAgICAgLyogc3RhcnQgb2Ygc3RyaW5nIHRvIGluc2VydCAqL1xuICB0aGlzLm1hdGNoX3N0YXJ0ID0gMDsgICAgICAgLyogc3RhcnQgb2YgbWF0Y2hpbmcgc3RyaW5nICovXG4gIHRoaXMubG9va2FoZWFkID0gMDsgICAgICAgICAvKiBudW1iZXIgb2YgdmFsaWQgYnl0ZXMgYWhlYWQgaW4gd2luZG93ICovXG5cbiAgdGhpcy5wcmV2X2xlbmd0aCA9IDA7XG4gIC8qIExlbmd0aCBvZiB0aGUgYmVzdCBtYXRjaCBhdCBwcmV2aW91cyBzdGVwLiBNYXRjaGVzIG5vdCBncmVhdGVyIHRoYW4gdGhpc1xuICAgKiBhcmUgZGlzY2FyZGVkLiBUaGlzIGlzIHVzZWQgaW4gdGhlIGxhenkgbWF0Y2ggZXZhbHVhdGlvbi5cbiAgICovXG5cbiAgdGhpcy5tYXhfY2hhaW5fbGVuZ3RoID0gMDtcbiAgLyogVG8gc3BlZWQgdXAgZGVmbGF0aW9uLCBoYXNoIGNoYWlucyBhcmUgbmV2ZXIgc2VhcmNoZWQgYmV5b25kIHRoaXNcbiAgICogbGVuZ3RoLiAgQSBoaWdoZXIgbGltaXQgaW1wcm92ZXMgY29tcHJlc3Npb24gcmF0aW8gYnV0IGRlZ3JhZGVzIHRoZVxuICAgKiBzcGVlZC5cbiAgICovXG5cbiAgdGhpcy5tYXhfbGF6eV9tYXRjaCA9IDA7XG4gIC8qIEF0dGVtcHQgdG8gZmluZCBhIGJldHRlciBtYXRjaCBvbmx5IHdoZW4gdGhlIGN1cnJlbnQgbWF0Y2ggaXMgc3RyaWN0bHlcbiAgICogc21hbGxlciB0aGFuIHRoaXMgdmFsdWUuIFRoaXMgbWVjaGFuaXNtIGlzIHVzZWQgb25seSBmb3IgY29tcHJlc3Npb25cbiAgICogbGV2ZWxzID49IDQuXG4gICAqL1xuICAvLyBUaGF0J3MgYWxpYXMgdG8gbWF4X2xhenlfbWF0Y2gsIGRvbid0IHVzZSBkaXJlY3RseVxuICAvL3RoaXMubWF4X2luc2VydF9sZW5ndGggPSAwO1xuICAvKiBJbnNlcnQgbmV3IHN0cmluZ3MgaW4gdGhlIGhhc2ggdGFibGUgb25seSBpZiB0aGUgbWF0Y2ggbGVuZ3RoIGlzIG5vdFxuICAgKiBncmVhdGVyIHRoYW4gdGhpcyBsZW5ndGguIFRoaXMgc2F2ZXMgdGltZSBidXQgZGVncmFkZXMgY29tcHJlc3Npb24uXG4gICAqIG1heF9pbnNlcnRfbGVuZ3RoIGlzIHVzZWQgb25seSBmb3IgY29tcHJlc3Npb24gbGV2ZWxzIDw9IDMuXG4gICAqL1xuXG4gIHRoaXMubGV2ZWwgPSAwOyAgICAgLyogY29tcHJlc3Npb24gbGV2ZWwgKDEuLjkpICovXG4gIHRoaXMuc3RyYXRlZ3kgPSAwOyAgLyogZmF2b3Igb3IgZm9yY2UgSHVmZm1hbiBjb2RpbmcqL1xuXG4gIHRoaXMuZ29vZF9tYXRjaCA9IDA7XG4gIC8qIFVzZSBhIGZhc3RlciBzZWFyY2ggd2hlbiB0aGUgcHJldmlvdXMgbWF0Y2ggaXMgbG9uZ2VyIHRoYW4gdGhpcyAqL1xuXG4gIHRoaXMubmljZV9tYXRjaCA9IDA7IC8qIFN0b3Agc2VhcmNoaW5nIHdoZW4gY3VycmVudCBtYXRjaCBleGNlZWRzIHRoaXMgKi9cblxuICAgICAgICAgICAgICAvKiB1c2VkIGJ5IHRyZWVzLmM6ICovXG5cbiAgLyogRGlkbid0IHVzZSBjdF9kYXRhIHR5cGVkZWYgYmVsb3cgdG8gc3VwcHJlc3MgY29tcGlsZXIgd2FybmluZyAqL1xuXG4gIC8vIHN0cnVjdCBjdF9kYXRhX3MgZHluX2x0cmVlW0hFQVBfU0laRV07ICAgLyogbGl0ZXJhbCBhbmQgbGVuZ3RoIHRyZWUgKi9cbiAgLy8gc3RydWN0IGN0X2RhdGFfcyBkeW5fZHRyZWVbMipEX0NPREVTKzFdOyAvKiBkaXN0YW5jZSB0cmVlICovXG4gIC8vIHN0cnVjdCBjdF9kYXRhX3MgYmxfdHJlZVsyKkJMX0NPREVTKzFdOyAgLyogSHVmZm1hbiB0cmVlIGZvciBiaXQgbGVuZ3RocyAqL1xuXG4gIC8vIFVzZSBmbGF0IGFycmF5IG9mIERPVUJMRSBzaXplLCB3aXRoIGludGVybGVhdmVkIGZhdGEsXG4gIC8vIGJlY2F1c2UgSlMgZG9lcyBub3Qgc3VwcG9ydCBlZmZlY3RpdmVcbiAgdGhpcy5keW5fbHRyZWUgID0gbmV3IFVpbnQxNkFycmF5KEhFQVBfU0laRSAqIDIpO1xuICB0aGlzLmR5bl9kdHJlZSAgPSBuZXcgVWludDE2QXJyYXkoKDIgKiBEX0NPREVTICsgMSkgKiAyKTtcbiAgdGhpcy5ibF90cmVlICAgID0gbmV3IFVpbnQxNkFycmF5KCgyICogQkxfQ09ERVMgKyAxKSAqIDIpO1xuICB6ZXJvKHRoaXMuZHluX2x0cmVlKTtcbiAgemVybyh0aGlzLmR5bl9kdHJlZSk7XG4gIHplcm8odGhpcy5ibF90cmVlKTtcblxuICB0aGlzLmxfZGVzYyAgID0gbnVsbDsgICAgICAgICAvKiBkZXNjLiBmb3IgbGl0ZXJhbCB0cmVlICovXG4gIHRoaXMuZF9kZXNjICAgPSBudWxsOyAgICAgICAgIC8qIGRlc2MuIGZvciBkaXN0YW5jZSB0cmVlICovXG4gIHRoaXMuYmxfZGVzYyAgPSBudWxsOyAgICAgICAgIC8qIGRlc2MuIGZvciBiaXQgbGVuZ3RoIHRyZWUgKi9cblxuICAvL3VzaCBibF9jb3VudFtNQVhfQklUUysxXTtcbiAgdGhpcy5ibF9jb3VudCA9IG5ldyBVaW50MTZBcnJheShNQVhfQklUUyArIDEpO1xuICAvKiBudW1iZXIgb2YgY29kZXMgYXQgZWFjaCBiaXQgbGVuZ3RoIGZvciBhbiBvcHRpbWFsIHRyZWUgKi9cblxuICAvL2ludCBoZWFwWzIqTF9DT0RFUysxXTsgICAgICAvKiBoZWFwIHVzZWQgdG8gYnVpbGQgdGhlIEh1ZmZtYW4gdHJlZXMgKi9cbiAgdGhpcy5oZWFwID0gbmV3IFVpbnQxNkFycmF5KDIgKiBMX0NPREVTICsgMSk7ICAvKiBoZWFwIHVzZWQgdG8gYnVpbGQgdGhlIEh1ZmZtYW4gdHJlZXMgKi9cbiAgemVybyh0aGlzLmhlYXApO1xuXG4gIHRoaXMuaGVhcF9sZW4gPSAwOyAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgaGVhcCAqL1xuICB0aGlzLmhlYXBfbWF4ID0gMDsgICAgICAgICAgICAgICAvKiBlbGVtZW50IG9mIGxhcmdlc3QgZnJlcXVlbmN5ICovXG4gIC8qIFRoZSBzb25zIG9mIGhlYXBbbl0gYXJlIGhlYXBbMipuXSBhbmQgaGVhcFsyKm4rMV0uIGhlYXBbMF0gaXMgbm90IHVzZWQuXG4gICAqIFRoZSBzYW1lIGhlYXAgYXJyYXkgaXMgdXNlZCB0byBidWlsZCBhbGwgdHJlZXMuXG4gICAqL1xuXG4gIHRoaXMuZGVwdGggPSBuZXcgVWludDE2QXJyYXkoMiAqIExfQ09ERVMgKyAxKTsgLy91Y2ggZGVwdGhbMipMX0NPREVTKzFdO1xuICB6ZXJvKHRoaXMuZGVwdGgpO1xuICAvKiBEZXB0aCBvZiBlYWNoIHN1YnRyZWUgdXNlZCBhcyB0aWUgYnJlYWtlciBmb3IgdHJlZXMgb2YgZXF1YWwgZnJlcXVlbmN5XG4gICAqL1xuXG4gIHRoaXMuc3ltX2J1ZiA9IDA7ICAgICAgICAvKiBidWZmZXIgZm9yIGRpc3RhbmNlcyBhbmQgbGl0ZXJhbHMvbGVuZ3RocyAqL1xuXG4gIHRoaXMubGl0X2J1ZnNpemUgPSAwO1xuICAvKiBTaXplIG9mIG1hdGNoIGJ1ZmZlciBmb3IgbGl0ZXJhbHMvbGVuZ3Rocy4gIFRoZXJlIGFyZSA0IHJlYXNvbnMgZm9yXG4gICAqIGxpbWl0aW5nIGxpdF9idWZzaXplIHRvIDY0SzpcbiAgICogICAtIGZyZXF1ZW5jaWVzIGNhbiBiZSBrZXB0IGluIDE2IGJpdCBjb3VudGVyc1xuICAgKiAgIC0gaWYgY29tcHJlc3Npb24gaXMgbm90IHN1Y2Nlc3NmdWwgZm9yIHRoZSBmaXJzdCBibG9jaywgYWxsIGlucHV0XG4gICAqICAgICBkYXRhIGlzIHN0aWxsIGluIHRoZSB3aW5kb3cgc28gd2UgY2FuIHN0aWxsIGVtaXQgYSBzdG9yZWQgYmxvY2sgZXZlblxuICAgKiAgICAgd2hlbiBpbnB1dCBjb21lcyBmcm9tIHN0YW5kYXJkIGlucHV0LiAgKFRoaXMgY2FuIGFsc28gYmUgZG9uZSBmb3JcbiAgICogICAgIGFsbCBibG9ja3MgaWYgbGl0X2J1ZnNpemUgaXMgbm90IGdyZWF0ZXIgdGhhbiAzMksuKVxuICAgKiAgIC0gaWYgY29tcHJlc3Npb24gaXMgbm90IHN1Y2Nlc3NmdWwgZm9yIGEgZmlsZSBzbWFsbGVyIHRoYW4gNjRLLCB3ZSBjYW5cbiAgICogICAgIGV2ZW4gZW1pdCBhIHN0b3JlZCBmaWxlIGluc3RlYWQgb2YgYSBzdG9yZWQgYmxvY2sgKHNhdmluZyA1IGJ5dGVzKS5cbiAgICogICAgIFRoaXMgaXMgYXBwbGljYWJsZSBvbmx5IGZvciB6aXAgKG5vdCBnemlwIG9yIHpsaWIpLlxuICAgKiAgIC0gY3JlYXRpbmcgbmV3IEh1ZmZtYW4gdHJlZXMgbGVzcyBmcmVxdWVudGx5IG1heSBub3QgcHJvdmlkZSBmYXN0XG4gICAqICAgICBhZGFwdGF0aW9uIHRvIGNoYW5nZXMgaW4gdGhlIGlucHV0IGRhdGEgc3RhdGlzdGljcy4gKFRha2UgZm9yXG4gICAqICAgICBleGFtcGxlIGEgYmluYXJ5IGZpbGUgd2l0aCBwb29ybHkgY29tcHJlc3NpYmxlIGNvZGUgZm9sbG93ZWQgYnlcbiAgICogICAgIGEgaGlnaGx5IGNvbXByZXNzaWJsZSBzdHJpbmcgdGFibGUuKSBTbWFsbGVyIGJ1ZmZlciBzaXplcyBnaXZlXG4gICAqICAgICBmYXN0IGFkYXB0YXRpb24gYnV0IGhhdmUgb2YgY291cnNlIHRoZSBvdmVyaGVhZCBvZiB0cmFuc21pdHRpbmdcbiAgICogICAgIHRyZWVzIG1vcmUgZnJlcXVlbnRseS5cbiAgICogICAtIEkgY2FuJ3QgY291bnQgYWJvdmUgNFxuICAgKi9cblxuICB0aGlzLnN5bV9uZXh0ID0gMDsgICAgICAvKiBydW5uaW5nIGluZGV4IGluIHN5bV9idWYgKi9cbiAgdGhpcy5zeW1fZW5kID0gMDsgICAgICAgLyogc3ltYm9sIHRhYmxlIGZ1bGwgd2hlbiBzeW1fbmV4dCByZWFjaGVzIHRoaXMgKi9cblxuICB0aGlzLm9wdF9sZW4gPSAwOyAgICAgICAvKiBiaXQgbGVuZ3RoIG9mIGN1cnJlbnQgYmxvY2sgd2l0aCBvcHRpbWFsIHRyZWVzICovXG4gIHRoaXMuc3RhdGljX2xlbiA9IDA7ICAgIC8qIGJpdCBsZW5ndGggb2YgY3VycmVudCBibG9jayB3aXRoIHN0YXRpYyB0cmVlcyAqL1xuICB0aGlzLm1hdGNoZXMgPSAwOyAgICAgICAvKiBudW1iZXIgb2Ygc3RyaW5nIG1hdGNoZXMgaW4gY3VycmVudCBibG9jayAqL1xuICB0aGlzLmluc2VydCA9IDA7ICAgICAgICAvKiBieXRlcyBhdCBlbmQgb2Ygd2luZG93IGxlZnQgdG8gaW5zZXJ0ICovXG5cblxuICB0aGlzLmJpX2J1ZiA9IDA7XG4gIC8qIE91dHB1dCBidWZmZXIuIGJpdHMgYXJlIGluc2VydGVkIHN0YXJ0aW5nIGF0IHRoZSBib3R0b20gKGxlYXN0XG4gICAqIHNpZ25pZmljYW50IGJpdHMpLlxuICAgKi9cbiAgdGhpcy5iaV92YWxpZCA9IDA7XG4gIC8qIE51bWJlciBvZiB2YWxpZCBiaXRzIGluIGJpX2J1Zi4gIEFsbCBiaXRzIGFib3ZlIHRoZSBsYXN0IHZhbGlkIGJpdFxuICAgKiBhcmUgYWx3YXlzIHplcm8uXG4gICAqL1xuXG4gIC8vIFVzZWQgZm9yIHdpbmRvdyBtZW1vcnkgaW5pdC4gV2Ugc2FmZWx5IGlnbm9yZSBpdCBmb3IgSlMuIFRoYXQgbWFrZXNcbiAgLy8gc2Vuc2Ugb25seSBmb3IgcG9pbnRlcnMgYW5kIG1lbW9yeSBjaGVjayB0b29scy5cbiAgLy90aGlzLmhpZ2hfd2F0ZXIgPSAwO1xuICAvKiBIaWdoIHdhdGVyIG1hcmsgb2Zmc2V0IGluIHdpbmRvdyBmb3IgaW5pdGlhbGl6ZWQgYnl0ZXMgLS0gYnl0ZXMgYWJvdmVcbiAgICogdGhpcyBhcmUgc2V0IHRvIHplcm8gaW4gb3JkZXIgdG8gYXZvaWQgbWVtb3J5IGNoZWNrIHdhcm5pbmdzIHdoZW5cbiAgICogbG9uZ2VzdCBtYXRjaCByb3V0aW5lcyBhY2Nlc3MgYnl0ZXMgcGFzdCB0aGUgaW5wdXQuICBUaGlzIGlzIHRoZW5cbiAgICogdXBkYXRlZCB0byB0aGUgbmV3IGhpZ2ggd2F0ZXIgbWFyay5cbiAgICovXG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ2hlY2sgZm9yIGEgdmFsaWQgZGVmbGF0ZSBzdHJlYW0gc3RhdGUuIFJldHVybiAwIGlmIG9rLCAxIGlmIG5vdC5cbiAqL1xuY29uc3QgZGVmbGF0ZVN0YXRlQ2hlY2sgPSAoc3RybSkgPT4ge1xuXG4gIGlmICghc3RybSkge1xuICAgIHJldHVybiAxO1xuICB9XG4gIGNvbnN0IHMgPSBzdHJtLnN0YXRlO1xuICBpZiAoIXMgfHwgcy5zdHJtICE9PSBzdHJtIHx8IChzLnN0YXR1cyAhPT0gSU5JVF9TVEFURSAmJlxuLy8jaWZkZWYgR1pJUFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLnN0YXR1cyAhPT0gR1pJUF9TVEFURSAmJlxuLy8jZW5kaWZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5zdGF0dXMgIT09IEVYVFJBX1NUQVRFICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuc3RhdHVzICE9PSBOQU1FX1NUQVRFICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuc3RhdHVzICE9PSBDT01NRU5UX1NUQVRFICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuc3RhdHVzICE9PSBIQ1JDX1NUQVRFICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuc3RhdHVzICE9PSBCVVNZX1NUQVRFICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuc3RhdHVzICE9PSBGSU5JU0hfU1RBVEUpKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59O1xuXG5cbmNvbnN0IGRlZmxhdGVSZXNldEtlZXAgPSAoc3RybSkgPT4ge1xuXG4gIGlmIChkZWZsYXRlU3RhdGVDaGVjayhzdHJtKSkge1xuICAgIHJldHVybiBlcnIoc3RybSwgWl9TVFJFQU1fRVJST1IkMik7XG4gIH1cblxuICBzdHJtLnRvdGFsX2luID0gc3RybS50b3RhbF9vdXQgPSAwO1xuICBzdHJtLmRhdGFfdHlwZSA9IFpfVU5LTk9XTjtcblxuICBjb25zdCBzID0gc3RybS5zdGF0ZTtcbiAgcy5wZW5kaW5nID0gMDtcbiAgcy5wZW5kaW5nX291dCA9IDA7XG5cbiAgaWYgKHMud3JhcCA8IDApIHtcbiAgICBzLndyYXAgPSAtcy53cmFwO1xuICAgIC8qIHdhcyBtYWRlIG5lZ2F0aXZlIGJ5IGRlZmxhdGUoLi4uLCBaX0ZJTklTSCk7ICovXG4gIH1cbiAgcy5zdGF0dXMgPVxuLy8jaWZkZWYgR1pJUFxuICAgIHMud3JhcCA9PT0gMiA/IEdaSVBfU1RBVEUgOlxuLy8jZW5kaWZcbiAgICBzLndyYXAgPyBJTklUX1NUQVRFIDogQlVTWV9TVEFURTtcbiAgc3RybS5hZGxlciA9IChzLndyYXAgPT09IDIpID9cbiAgICAwICAvLyBjcmMzMigwLCBaX05VTEwsIDApXG4gIDpcbiAgICAxOyAvLyBhZGxlcjMyKDAsIFpfTlVMTCwgMClcbiAgcy5sYXN0X2ZsdXNoID0gLTI7XG4gIF90cl9pbml0KHMpO1xuICByZXR1cm4gWl9PSyQzO1xufTtcblxuXG5jb25zdCBkZWZsYXRlUmVzZXQgPSAoc3RybSkgPT4ge1xuXG4gIGNvbnN0IHJldCA9IGRlZmxhdGVSZXNldEtlZXAoc3RybSk7XG4gIGlmIChyZXQgPT09IFpfT0skMykge1xuICAgIGxtX2luaXQoc3RybS5zdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn07XG5cblxuY29uc3QgZGVmbGF0ZVNldEhlYWRlciA9IChzdHJtLCBoZWFkKSA9PiB7XG5cbiAgaWYgKGRlZmxhdGVTdGF0ZUNoZWNrKHN0cm0pIHx8IHN0cm0uc3RhdGUud3JhcCAhPT0gMikge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUiQyO1xuICB9XG4gIHN0cm0uc3RhdGUuZ3poZWFkID0gaGVhZDtcbiAgcmV0dXJuIFpfT0skMztcbn07XG5cblxuY29uc3QgZGVmbGF0ZUluaXQyID0gKHN0cm0sIGxldmVsLCBtZXRob2QsIHdpbmRvd0JpdHMsIG1lbUxldmVsLCBzdHJhdGVneSkgPT4ge1xuXG4gIGlmICghc3RybSkgeyAvLyA9PT0gWl9OVUxMXG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDI7XG4gIH1cbiAgbGV0IHdyYXAgPSAxO1xuXG4gIGlmIChsZXZlbCA9PT0gWl9ERUZBVUxUX0NPTVBSRVNTSU9OJDEpIHtcbiAgICBsZXZlbCA9IDY7XG4gIH1cblxuICBpZiAod2luZG93Qml0cyA8IDApIHsgLyogc3VwcHJlc3MgemxpYiB3cmFwcGVyICovXG4gICAgd3JhcCA9IDA7XG4gICAgd2luZG93Qml0cyA9IC13aW5kb3dCaXRzO1xuICB9XG5cbiAgZWxzZSBpZiAod2luZG93Qml0cyA+IDE1KSB7XG4gICAgd3JhcCA9IDI7ICAgICAgICAgICAvKiB3cml0ZSBnemlwIHdyYXBwZXIgaW5zdGVhZCAqL1xuICAgIHdpbmRvd0JpdHMgLT0gMTY7XG4gIH1cblxuXG4gIGlmIChtZW1MZXZlbCA8IDEgfHwgbWVtTGV2ZWwgPiBNQVhfTUVNX0xFVkVMIHx8IG1ldGhvZCAhPT0gWl9ERUZMQVRFRCQyIHx8XG4gICAgd2luZG93Qml0cyA8IDggfHwgd2luZG93Qml0cyA+IDE1IHx8IGxldmVsIDwgMCB8fCBsZXZlbCA+IDkgfHxcbiAgICBzdHJhdGVneSA8IDAgfHwgc3RyYXRlZ3kgPiBaX0ZJWEVEIHx8ICh3aW5kb3dCaXRzID09PSA4ICYmIHdyYXAgIT09IDEpKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX1NUUkVBTV9FUlJPUiQyKTtcbiAgfVxuXG5cbiAgaWYgKHdpbmRvd0JpdHMgPT09IDgpIHtcbiAgICB3aW5kb3dCaXRzID0gOTtcbiAgfVxuICAvKiB1bnRpbCAyNTYtYnl0ZSB3aW5kb3cgYnVnIGZpeGVkICovXG5cbiAgY29uc3QgcyA9IG5ldyBEZWZsYXRlU3RhdGUoKTtcblxuICBzdHJtLnN0YXRlID0gcztcbiAgcy5zdHJtID0gc3RybTtcbiAgcy5zdGF0dXMgPSBJTklUX1NUQVRFOyAgICAgLyogdG8gcGFzcyBzdGF0ZSB0ZXN0IGluIGRlZmxhdGVSZXNldCgpICovXG5cbiAgcy53cmFwID0gd3JhcDtcbiAgcy5nemhlYWQgPSBudWxsO1xuICBzLndfYml0cyA9IHdpbmRvd0JpdHM7XG4gIHMud19zaXplID0gMSA8PCBzLndfYml0cztcbiAgcy53X21hc2sgPSBzLndfc2l6ZSAtIDE7XG5cbiAgcy5oYXNoX2JpdHMgPSBtZW1MZXZlbCArIDc7XG4gIHMuaGFzaF9zaXplID0gMSA8PCBzLmhhc2hfYml0cztcbiAgcy5oYXNoX21hc2sgPSBzLmhhc2hfc2l6ZSAtIDE7XG4gIHMuaGFzaF9zaGlmdCA9IH5+KChzLmhhc2hfYml0cyArIE1JTl9NQVRDSCAtIDEpIC8gTUlOX01BVENIKTtcblxuICBzLndpbmRvdyA9IG5ldyBVaW50OEFycmF5KHMud19zaXplICogMik7XG4gIHMuaGVhZCA9IG5ldyBVaW50MTZBcnJheShzLmhhc2hfc2l6ZSk7XG4gIHMucHJldiA9IG5ldyBVaW50MTZBcnJheShzLndfc2l6ZSk7XG5cbiAgLy8gRG9uJ3QgbmVlZCBtZW0gaW5pdCBtYWdpYyBmb3IgSlMuXG4gIC8vcy5oaWdoX3dhdGVyID0gMDsgIC8qIG5vdGhpbmcgd3JpdHRlbiB0byBzLT53aW5kb3cgeWV0ICovXG5cbiAgcy5saXRfYnVmc2l6ZSA9IDEgPDwgKG1lbUxldmVsICsgNik7IC8qIDE2SyBlbGVtZW50cyBieSBkZWZhdWx0ICovXG5cbiAgLyogV2Ugb3ZlcmxheSBwZW5kaW5nX2J1ZiBhbmQgc3ltX2J1Zi4gVGhpcyB3b3JrcyBzaW5jZSB0aGUgYXZlcmFnZSBzaXplXG4gICAqIGZvciBsZW5ndGgvZGlzdGFuY2UgcGFpcnMgb3ZlciBhbnkgY29tcHJlc3NlZCBibG9jayBpcyBhc3N1cmVkIHRvIGJlIDMxXG4gICAqIGJpdHMgb3IgbGVzcy5cbiAgICpcbiAgICogQW5hbHlzaXM6IFRoZSBsb25nZXN0IGZpeGVkIGNvZGVzIGFyZSBhIGxlbmd0aCBjb2RlIG9mIDggYml0cyBwbHVzIDVcbiAgICogZXh0cmEgYml0cywgZm9yIGxlbmd0aHMgMTMxIHRvIDI1Ny4gVGhlIGxvbmdlc3QgZml4ZWQgZGlzdGFuY2UgY29kZXMgYXJlXG4gICAqIDUgYml0cyBwbHVzIDEzIGV4dHJhIGJpdHMsIGZvciBkaXN0YW5jZXMgMTYzODUgdG8gMzI3NjguIFRoZSBsb25nZXN0XG4gICAqIHBvc3NpYmxlIGZpeGVkLWNvZGVzIGxlbmd0aC9kaXN0YW5jZSBwYWlyIGlzIHRoZW4gMzEgYml0cyB0b3RhbC5cbiAgICpcbiAgICogc3ltX2J1ZiBzdGFydHMgb25lLWZvdXJ0aCBvZiB0aGUgd2F5IGludG8gcGVuZGluZ19idWYuIFNvIHRoZXJlIGFyZVxuICAgKiB0aHJlZSBieXRlcyBpbiBzeW1fYnVmIGZvciBldmVyeSBmb3VyIGJ5dGVzIGluIHBlbmRpbmdfYnVmLiBFYWNoIHN5bWJvbFxuICAgKiBpbiBzeW1fYnVmIGlzIHRocmVlIGJ5dGVzIC0tIHR3byBmb3IgdGhlIGRpc3RhbmNlIGFuZCBvbmUgZm9yIHRoZVxuICAgKiBsaXRlcmFsL2xlbmd0aC4gQXMgZWFjaCBzeW1ib2wgaXMgY29uc3VtZWQsIHRoZSBwb2ludGVyIHRvIHRoZSBuZXh0XG4gICAqIHN5bV9idWYgdmFsdWUgdG8gcmVhZCBtb3ZlcyBmb3J3YXJkIHRocmVlIGJ5dGVzLiBGcm9tIHRoYXQgc3ltYm9sLCB1cCB0b1xuICAgKiAzMSBiaXRzIGFyZSB3cml0dGVuIHRvIHBlbmRpbmdfYnVmLiBUaGUgY2xvc2VzdCB0aGUgd3JpdHRlbiBwZW5kaW5nX2J1ZlxuICAgKiBiaXRzIGdldHMgdG8gdGhlIG5leHQgc3ltX2J1ZiBzeW1ib2wgdG8gcmVhZCBpcyBqdXN0IGJlZm9yZSB0aGUgbGFzdFxuICAgKiBjb2RlIGlzIHdyaXR0ZW4uIEF0IHRoYXQgdGltZSwgMzEqKG4tMikgYml0cyBoYXZlIGJlZW4gd3JpdHRlbiwganVzdFxuICAgKiBhZnRlciAyNCoobi0yKSBiaXRzIGhhdmUgYmVlbiBjb25zdW1lZCBmcm9tIHN5bV9idWYuIHN5bV9idWYgc3RhcnRzIGF0XG4gICAqIDgqbiBiaXRzIGludG8gcGVuZGluZ19idWYuIChOb3RlIHRoYXQgdGhlIHN5bWJvbCBidWZmZXIgZmlsbHMgd2hlbiBuLTFcbiAgICogc3ltYm9scyBhcmUgd3JpdHRlbi4pIFRoZSBjbG9zZXN0IHRoZSB3cml0aW5nIGdldHMgdG8gd2hhdCBpcyB1bnJlYWQgaXNcbiAgICogdGhlbiBuKzE0IGJpdHMuIEhlcmUgbiBpcyBsaXRfYnVmc2l6ZSwgd2hpY2ggaXMgMTYzODQgYnkgZGVmYXVsdCwgYW5kXG4gICAqIGNhbiByYW5nZSBmcm9tIDEyOCB0byAzMjc2OC5cbiAgICpcbiAgICogVGhlcmVmb3JlLCBhdCBhIG1pbmltdW0sIHRoZXJlIGFyZSAxNDIgYml0cyBvZiBzcGFjZSBiZXR3ZWVuIHdoYXQgaXNcbiAgICogd3JpdHRlbiBhbmQgd2hhdCBpcyByZWFkIGluIHRoZSBvdmVybGFpbiBidWZmZXJzLCBzbyB0aGUgc3ltYm9scyBjYW5ub3RcbiAgICogYmUgb3ZlcndyaXR0ZW4gYnkgdGhlIGNvbXByZXNzZWQgZGF0YS4gVGhhdCBzcGFjZSBpcyBhY3R1YWxseSAxMzkgYml0cyxcbiAgICogZHVlIHRvIHRoZSB0aHJlZS1iaXQgZml4ZWQtY29kZSBibG9jayBoZWFkZXIuXG4gICAqXG4gICAqIFRoYXQgY292ZXJzIHRoZSBjYXNlIHdoZXJlIGVpdGhlciBaX0ZJWEVEIGlzIHNwZWNpZmllZCwgZm9yY2luZyBmaXhlZFxuICAgKiBjb2Rlcywgb3Igd2hlbiB0aGUgdXNlIG9mIGZpeGVkIGNvZGVzIGlzIGNob3NlbiwgYmVjYXVzZSB0aGF0IGNob2ljZVxuICAgKiByZXN1bHRzIGluIGEgc21hbGxlciBjb21wcmVzc2VkIGJsb2NrIHRoYW4gZHluYW1pYyBjb2Rlcy4gVGhhdCBsYXR0ZXJcbiAgICogY29uZGl0aW9uIHRoZW4gYXNzdXJlcyB0aGF0IHRoZSBhYm92ZSBhbmFseXNpcyBhbHNvIGNvdmVycyBhbGwgZHluYW1pY1xuICAgKiBibG9ja3MuIEEgZHluYW1pYy1jb2RlIGJsb2NrIHdpbGwgb25seSBiZSBjaG9zZW4gdG8gYmUgZW1pdHRlZCBpZiBpdCBoYXNcbiAgICogZmV3ZXIgYml0cyB0aGFuIGEgZml4ZWQtY29kZSBibG9jayB3b3VsZCBmb3IgdGhlIHNhbWUgc2V0IG9mIHN5bWJvbHMuXG4gICAqIFRoZXJlZm9yZSBpdHMgYXZlcmFnZSBzeW1ib2wgbGVuZ3RoIGlzIGFzc3VyZWQgdG8gYmUgbGVzcyB0aGFuIDMxLiBTb1xuICAgKiB0aGUgY29tcHJlc3NlZCBkYXRhIGZvciBhIGR5bmFtaWMgYmxvY2sgYWxzbyBjYW5ub3Qgb3ZlcndyaXRlIHRoZVxuICAgKiBzeW1ib2xzIGZyb20gd2hpY2ggaXQgaXMgYmVpbmcgY29uc3RydWN0ZWQuXG4gICAqL1xuXG4gIHMucGVuZGluZ19idWZfc2l6ZSA9IHMubGl0X2J1ZnNpemUgKiA0O1xuICBzLnBlbmRpbmdfYnVmID0gbmV3IFVpbnQ4QXJyYXkocy5wZW5kaW5nX2J1Zl9zaXplKTtcblxuICAvLyBJdCBpcyBvZmZzZXQgZnJvbSBgcy5wZW5kaW5nX2J1ZmAgKHNpemUgaXMgYHMubGl0X2J1ZnNpemUgKiAyYClcbiAgLy9zLT5zeW1fYnVmID0gcy0+cGVuZGluZ19idWYgKyBzLT5saXRfYnVmc2l6ZTtcbiAgcy5zeW1fYnVmID0gcy5saXRfYnVmc2l6ZTtcblxuICAvL3MtPnN5bV9lbmQgPSAocy0+bGl0X2J1ZnNpemUgLSAxKSAqIDM7XG4gIHMuc3ltX2VuZCA9IChzLmxpdF9idWZzaXplIC0gMSkgKiAzO1xuICAvKiBXZSBhdm9pZCBlcXVhbGl0eSB3aXRoIGxpdF9idWZzaXplKjMgYmVjYXVzZSBvZiB3cmFwYXJvdW5kIGF0IDY0S1xuICAgKiBvbiAxNiBiaXQgbWFjaGluZXMgYW5kIGJlY2F1c2Ugc3RvcmVkIGJsb2NrcyBhcmUgcmVzdHJpY3RlZCB0b1xuICAgKiA2NEstMSBieXRlcy5cbiAgICovXG5cbiAgcy5sZXZlbCA9IGxldmVsO1xuICBzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7XG4gIHMubWV0aG9kID0gbWV0aG9kO1xuXG4gIHJldHVybiBkZWZsYXRlUmVzZXQoc3RybSk7XG59O1xuXG5jb25zdCBkZWZsYXRlSW5pdCA9IChzdHJtLCBsZXZlbCkgPT4ge1xuXG4gIHJldHVybiBkZWZsYXRlSW5pdDIoc3RybSwgbGV2ZWwsIFpfREVGTEFURUQkMiwgTUFYX1dCSVRTJDEsIERFRl9NRU1fTEVWRUwsIFpfREVGQVVMVF9TVFJBVEVHWSQxKTtcbn07XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuY29uc3QgZGVmbGF0ZSQyID0gKHN0cm0sIGZsdXNoKSA9PiB7XG5cbiAgaWYgKGRlZmxhdGVTdGF0ZUNoZWNrKHN0cm0pIHx8IGZsdXNoID4gWl9CTE9DSyQxIHx8IGZsdXNoIDwgMCkge1xuICAgIHJldHVybiBzdHJtID8gZXJyKHN0cm0sIFpfU1RSRUFNX0VSUk9SJDIpIDogWl9TVFJFQU1fRVJST1IkMjtcbiAgfVxuXG4gIGNvbnN0IHMgPSBzdHJtLnN0YXRlO1xuXG4gIGlmICghc3RybS5vdXRwdXQgfHxcbiAgICAgIChzdHJtLmF2YWlsX2luICE9PSAwICYmICFzdHJtLmlucHV0KSB8fFxuICAgICAgKHMuc3RhdHVzID09PSBGSU5JU0hfU1RBVEUgJiYgZmx1c2ggIT09IFpfRklOSVNIJDMpKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCAoc3RybS5hdmFpbF9vdXQgPT09IDApID8gWl9CVUZfRVJST1IkMSA6IFpfU1RSRUFNX0VSUk9SJDIpO1xuICB9XG5cbiAgY29uc3Qgb2xkX2ZsdXNoID0gcy5sYXN0X2ZsdXNoO1xuICBzLmxhc3RfZmx1c2ggPSBmbHVzaDtcblxuICAvKiBGbHVzaCBhcyBtdWNoIHBlbmRpbmcgb3V0cHV0IGFzIHBvc3NpYmxlICovXG4gIGlmIChzLnBlbmRpbmcgIT09IDApIHtcbiAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgLyogU2luY2UgYXZhaWxfb3V0IGlzIDAsIGRlZmxhdGUgd2lsbCBiZSBjYWxsZWQgYWdhaW4gd2l0aFxuICAgICAgICogbW9yZSBvdXRwdXQgc3BhY2UsIGJ1dCBwb3NzaWJseSB3aXRoIGJvdGggcGVuZGluZyBhbmRcbiAgICAgICAqIGF2YWlsX2luIGVxdWFsIHRvIHplcm8uIFRoZXJlIHdvbid0IGJlIGFueXRoaW5nIHRvIGRvLFxuICAgICAgICogYnV0IHRoaXMgaXMgbm90IGFuIGVycm9yIHNpdHVhdGlvbiBzbyBtYWtlIHN1cmUgd2VcbiAgICAgICAqIHJldHVybiBPSyBpbnN0ZWFkIG9mIEJVRl9FUlJPUiBhdCBuZXh0IGNhbGwgb2YgZGVmbGF0ZTpcbiAgICAgICAqL1xuICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7XG4gICAgICByZXR1cm4gWl9PSyQzO1xuICAgIH1cblxuICAgIC8qIE1ha2Ugc3VyZSB0aGVyZSBpcyBzb21ldGhpbmcgdG8gZG8gYW5kIGF2b2lkIGR1cGxpY2F0ZSBjb25zZWN1dGl2ZVxuICAgICAqIGZsdXNoZXMuIEZvciByZXBlYXRlZCBhbmQgdXNlbGVzcyBjYWxscyB3aXRoIFpfRklOSVNILCB3ZSBrZWVwXG4gICAgICogcmV0dXJuaW5nIFpfU1RSRUFNX0VORCBpbnN0ZWFkIG9mIFpfQlVGX0VSUk9SLlxuICAgICAqL1xuICB9IGVsc2UgaWYgKHN0cm0uYXZhaWxfaW4gPT09IDAgJiYgcmFuayhmbHVzaCkgPD0gcmFuayhvbGRfZmx1c2gpICYmXG4gICAgZmx1c2ggIT09IFpfRklOSVNIJDMpIHtcbiAgICByZXR1cm4gZXJyKHN0cm0sIFpfQlVGX0VSUk9SJDEpO1xuICB9XG5cbiAgLyogVXNlciBtdXN0IG5vdCBwcm92aWRlIG1vcmUgaW5wdXQgYWZ0ZXIgdGhlIGZpcnN0IEZJTklTSDogKi9cbiAgaWYgKHMuc3RhdHVzID09PSBGSU5JU0hfU1RBVEUgJiYgc3RybS5hdmFpbF9pbiAhPT0gMCkge1xuICAgIHJldHVybiBlcnIoc3RybSwgWl9CVUZfRVJST1IkMSk7XG4gIH1cblxuICAvKiBXcml0ZSB0aGUgaGVhZGVyICovXG4gIGlmIChzLnN0YXR1cyA9PT0gSU5JVF9TVEFURSAmJiBzLndyYXAgPT09IDApIHtcbiAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7XG4gIH1cbiAgaWYgKHMuc3RhdHVzID09PSBJTklUX1NUQVRFKSB7XG4gICAgLyogemxpYiBoZWFkZXIgKi9cbiAgICBsZXQgaGVhZGVyID0gKFpfREVGTEFURUQkMiArICgocy53X2JpdHMgLSA4KSA8PCA0KSkgPDwgODtcbiAgICBsZXQgbGV2ZWxfZmxhZ3MgPSAtMTtcblxuICAgIGlmIChzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyKSB7XG4gICAgICBsZXZlbF9mbGFncyA9IDA7XG4gICAgfSBlbHNlIGlmIChzLmxldmVsIDwgNikge1xuICAgICAgbGV2ZWxfZmxhZ3MgPSAxO1xuICAgIH0gZWxzZSBpZiAocy5sZXZlbCA9PT0gNikge1xuICAgICAgbGV2ZWxfZmxhZ3MgPSAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXZlbF9mbGFncyA9IDM7XG4gICAgfVxuICAgIGhlYWRlciB8PSAobGV2ZWxfZmxhZ3MgPDwgNik7XG4gICAgaWYgKHMuc3Ryc3RhcnQgIT09IDApIHsgaGVhZGVyIHw9IFBSRVNFVF9ESUNUOyB9XG4gICAgaGVhZGVyICs9IDMxIC0gKGhlYWRlciAlIDMxKTtcblxuICAgIHB1dFNob3J0TVNCKHMsIGhlYWRlcik7XG5cbiAgICAvKiBTYXZlIHRoZSBhZGxlcjMyIG9mIHRoZSBwcmVzZXQgZGljdGlvbmFyeTogKi9cbiAgICBpZiAocy5zdHJzdGFydCAhPT0gMCkge1xuICAgICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciA+Pj4gMTYpO1xuICAgICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciAmIDB4ZmZmZik7XG4gICAgfVxuICAgIHN0cm0uYWRsZXIgPSAxOyAvLyBhZGxlcjMyKDBMLCBaX05VTEwsIDApO1xuICAgIHMuc3RhdHVzID0gQlVTWV9TVEFURTtcblxuICAgIC8qIENvbXByZXNzaW9uIG11c3Qgc3RhcnQgd2l0aCBhbiBlbXB0eSBwZW5kaW5nIGJ1ZmZlciAqL1xuICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgaWYgKHMucGVuZGluZyAhPT0gMCkge1xuICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7XG4gICAgICByZXR1cm4gWl9PSyQzO1xuICAgIH1cbiAgfVxuLy8jaWZkZWYgR1pJUFxuICBpZiAocy5zdGF0dXMgPT09IEdaSVBfU1RBVEUpIHtcbiAgICAvKiBnemlwIGhlYWRlciAqL1xuICAgIHN0cm0uYWRsZXIgPSAwOyAgLy9jcmMzMigwTCwgWl9OVUxMLCAwKTtcbiAgICBwdXRfYnl0ZShzLCAzMSk7XG4gICAgcHV0X2J5dGUocywgMTM5KTtcbiAgICBwdXRfYnl0ZShzLCA4KTtcbiAgICBpZiAoIXMuZ3poZWFkKSB7IC8vIHMtPmd6aGVhZCA9PSBaX05VTExcbiAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICBwdXRfYnl0ZShzLCAwKTtcbiAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICBwdXRfYnl0ZShzLCBzLmxldmVsID09PSA5ID8gMiA6XG4gICAgICAgICAgICAgICAgICAocy5zdHJhdGVneSA+PSBaX0hVRkZNQU5fT05MWSB8fCBzLmxldmVsIDwgMiA/XG4gICAgICAgICAgICAgICAgICAgNCA6IDApKTtcbiAgICAgIHB1dF9ieXRlKHMsIE9TX0NPREUpO1xuICAgICAgcy5zdGF0dXMgPSBCVVNZX1NUQVRFO1xuXG4gICAgICAvKiBDb21wcmVzc2lvbiBtdXN0IHN0YXJ0IHdpdGggYW4gZW1wdHkgcGVuZGluZyBidWZmZXIgKi9cbiAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgICBpZiAocy5wZW5kaW5nICE9PSAwKSB7XG4gICAgICAgIHMubGFzdF9mbHVzaCA9IC0xO1xuICAgICAgICByZXR1cm4gWl9PSyQzO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC50ZXh0ID8gMSA6IDApICtcbiAgICAgICAgICAgICAgICAgIChzLmd6aGVhZC5oY3JjID8gMiA6IDApICtcbiAgICAgICAgICAgICAgICAgICghcy5nemhlYWQuZXh0cmEgPyAwIDogNCkgK1xuICAgICAgICAgICAgICAgICAgKCFzLmd6aGVhZC5uYW1lID8gMCA6IDgpICtcbiAgICAgICAgICAgICAgICAgICghcy5nemhlYWQuY29tbWVudCA/IDAgOiAxNilcbiAgICAgICk7XG4gICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC50aW1lICYgMHhmZik7XG4gICAgICBwdXRfYnl0ZShzLCAocy5nemhlYWQudGltZSA+PiA4KSAmIDB4ZmYpO1xuICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLnRpbWUgPj4gMTYpICYgMHhmZik7XG4gICAgICBwdXRfYnl0ZShzLCAocy5nemhlYWQudGltZSA+PiAyNCkgJiAweGZmKTtcbiAgICAgIHB1dF9ieXRlKHMsIHMubGV2ZWwgPT09IDkgPyAyIDpcbiAgICAgICAgICAgICAgICAgIChzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyID9cbiAgICAgICAgICAgICAgICAgICA0IDogMCkpO1xuICAgICAgcHV0X2J5dGUocywgcy5nemhlYWQub3MgJiAweGZmKTtcbiAgICAgIGlmIChzLmd6aGVhZC5leHRyYSAmJiBzLmd6aGVhZC5leHRyYS5sZW5ndGgpIHtcbiAgICAgICAgcHV0X2J5dGUocywgcy5nemhlYWQuZXh0cmEubGVuZ3RoICYgMHhmZik7XG4gICAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC5leHRyYS5sZW5ndGggPj4gOCkgJiAweGZmKTtcbiAgICAgIH1cbiAgICAgIGlmIChzLmd6aGVhZC5oY3JjKSB7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMl8xKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZywgMCk7XG4gICAgICB9XG4gICAgICBzLmd6aW5kZXggPSAwO1xuICAgICAgcy5zdGF0dXMgPSBFWFRSQV9TVEFURTtcbiAgICB9XG4gIH1cbiAgaWYgKHMuc3RhdHVzID09PSBFWFRSQV9TVEFURSkge1xuICAgIGlmIChzLmd6aGVhZC5leHRyYS8qICE9IFpfTlVMTCovKSB7XG4gICAgICBsZXQgYmVnID0gcy5wZW5kaW5nOyAgIC8qIHN0YXJ0IG9mIGJ5dGVzIHRvIHVwZGF0ZSBjcmMgKi9cbiAgICAgIGxldCBsZWZ0ID0gKHMuZ3poZWFkLmV4dHJhLmxlbmd0aCAmIDB4ZmZmZikgLSBzLmd6aW5kZXg7XG4gICAgICB3aGlsZSAocy5wZW5kaW5nICsgbGVmdCA+IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICBsZXQgY29weSA9IHMucGVuZGluZ19idWZfc2l6ZSAtIHMucGVuZGluZztcbiAgICAgICAgLy8gem1lbWNweShzLnBlbmRpbmdfYnVmICsgcy5wZW5kaW5nLFxuICAgICAgICAvLyAgICBzLmd6aGVhZC5leHRyYSArIHMuZ3ppbmRleCwgY29weSk7XG4gICAgICAgIHMucGVuZGluZ19idWYuc2V0KHMuZ3poZWFkLmV4dHJhLnN1YmFycmF5KHMuZ3ppbmRleCwgcy5nemluZGV4ICsgY29weSksIHMucGVuZGluZyk7XG4gICAgICAgIHMucGVuZGluZyA9IHMucGVuZGluZ19idWZfc2l6ZTtcbiAgICAgICAgLy8tLS0gSENSQ19VUERBVEUoYmVnKSAtLS0vL1xuICAgICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHtcbiAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzJfMShzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBzLmd6aW5kZXggKz0gY29weTtcbiAgICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICAgICAgaWYgKHMucGVuZGluZyAhPT0gMCkge1xuICAgICAgICAgIHMubGFzdF9mbHVzaCA9IC0xO1xuICAgICAgICAgIHJldHVybiBaX09LJDM7XG4gICAgICAgIH1cbiAgICAgICAgYmVnID0gMDtcbiAgICAgICAgbGVmdCAtPSBjb3B5O1xuICAgICAgfVxuICAgICAgLy8gSlMgc3BlY2lmaWM6IHMuZ3poZWFkLmV4dHJhIG1heSBiZSBUeXBlZEFycmF5IG9yIEFycmF5IGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG4gICAgICAvLyAgICAgICAgICAgICAgVHlwZWRBcnJheS5zbGljZSBhbmQgVHlwZWRBcnJheS5mcm9tIGRvbid0IGV4aXN0IGluIElFMTAtSUUxMVxuICAgICAgbGV0IGd6aGVhZF9leHRyYSA9IG5ldyBVaW50OEFycmF5KHMuZ3poZWFkLmV4dHJhKTtcbiAgICAgIC8vIHptZW1jcHkocy0+cGVuZGluZ19idWYgKyBzLT5wZW5kaW5nLFxuICAgICAgLy8gICAgIHMtPmd6aGVhZC0+ZXh0cmEgKyBzLT5nemluZGV4LCBsZWZ0KTtcbiAgICAgIHMucGVuZGluZ19idWYuc2V0KGd6aGVhZF9leHRyYS5zdWJhcnJheShzLmd6aW5kZXgsIHMuZ3ppbmRleCArIGxlZnQpLCBzLnBlbmRpbmcpO1xuICAgICAgcy5wZW5kaW5nICs9IGxlZnQ7XG4gICAgICAvLy0tLSBIQ1JDX1VQREFURShiZWcpIC0tLS8vXG4gICAgICBpZiAocy5nemhlYWQuaGNyYyAmJiBzLnBlbmRpbmcgPiBiZWcpIHtcbiAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyXzEoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgfVxuICAgICAgLy8tLS0vL1xuICAgICAgcy5nemluZGV4ID0gMDtcbiAgICB9XG4gICAgcy5zdGF0dXMgPSBOQU1FX1NUQVRFO1xuICB9XG4gIGlmIChzLnN0YXR1cyA9PT0gTkFNRV9TVEFURSkge1xuICAgIGlmIChzLmd6aGVhZC5uYW1lLyogIT0gWl9OVUxMKi8pIHtcbiAgICAgIGxldCBiZWcgPSBzLnBlbmRpbmc7ICAgLyogc3RhcnQgb2YgYnl0ZXMgdG8gdXBkYXRlIGNyYyAqL1xuICAgICAgbGV0IHZhbDtcbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgLy8tLS0gSENSQ19VUERBVEUoYmVnKSAtLS0vL1xuICAgICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyXzEoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICAgICAgICBpZiAocy5wZW5kaW5nICE9PSAwKSB7XG4gICAgICAgICAgICBzLmxhc3RfZmx1c2ggPSAtMTtcbiAgICAgICAgICAgIHJldHVybiBaX09LJDM7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJlZyA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSlMgc3BlY2lmaWM6IGxpdHRsZSBtYWdpYyB0byBhZGQgemVybyB0ZXJtaW5hdG9yIHRvIGVuZCBvZiBzdHJpbmdcbiAgICAgICAgaWYgKHMuZ3ppbmRleCA8IHMuZ3poZWFkLm5hbWUubGVuZ3RoKSB7XG4gICAgICAgICAgdmFsID0gcy5nemhlYWQubmFtZS5jaGFyQ29kZUF0KHMuZ3ppbmRleCsrKSAmIDB4ZmY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsID0gMDtcbiAgICAgICAgfVxuICAgICAgICBwdXRfYnl0ZShzLCB2YWwpO1xuICAgICAgfSB3aGlsZSAodmFsICE9PSAwKTtcbiAgICAgIC8vLS0tIEhDUkNfVVBEQVRFKGJlZykgLS0tLy9cbiAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzJfMShzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICB9XG4gICAgICAvLy0tLS8vXG4gICAgICBzLmd6aW5kZXggPSAwO1xuICAgIH1cbiAgICBzLnN0YXR1cyA9IENPTU1FTlRfU1RBVEU7XG4gIH1cbiAgaWYgKHMuc3RhdHVzID09PSBDT01NRU5UX1NUQVRFKSB7XG4gICAgaWYgKHMuZ3poZWFkLmNvbW1lbnQvKiAhPSBaX05VTEwqLykge1xuICAgICAgbGV0IGJlZyA9IHMucGVuZGluZzsgICAvKiBzdGFydCBvZiBieXRlcyB0byB1cGRhdGUgY3JjICovXG4gICAgICBsZXQgdmFsO1xuICAgICAgZG8ge1xuICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICAvLy0tLSBIQ1JDX1VQREFURShiZWcpIC0tLS8vXG4gICAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzJfMShzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgICAgIGlmIChzLnBlbmRpbmcgIT09IDApIHtcbiAgICAgICAgICAgIHMubGFzdF9mbHVzaCA9IC0xO1xuICAgICAgICAgICAgcmV0dXJuIFpfT0skMztcbiAgICAgICAgICB9XG4gICAgICAgICAgYmVnID0gMDtcbiAgICAgICAgfVxuICAgICAgICAvLyBKUyBzcGVjaWZpYzogbGl0dGxlIG1hZ2ljIHRvIGFkZCB6ZXJvIHRlcm1pbmF0b3IgdG8gZW5kIG9mIHN0cmluZ1xuICAgICAgICBpZiAocy5nemluZGV4IDwgcy5nemhlYWQuY29tbWVudC5sZW5ndGgpIHtcbiAgICAgICAgICB2YWwgPSBzLmd6aGVhZC5jb21tZW50LmNoYXJDb2RlQXQocy5nemluZGV4KyspICYgMHhmZjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWwgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHB1dF9ieXRlKHMsIHZhbCk7XG4gICAgICB9IHdoaWxlICh2YWwgIT09IDApO1xuICAgICAgLy8tLS0gSENSQ19VUERBVEUoYmVnKSAtLS0vL1xuICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMl8xKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTtcbiAgICAgIH1cbiAgICAgIC8vLS0tLy9cbiAgICB9XG4gICAgcy5zdGF0dXMgPSBIQ1JDX1NUQVRFO1xuICB9XG4gIGlmIChzLnN0YXR1cyA9PT0gSENSQ19TVEFURSkge1xuICAgIGlmIChzLmd6aGVhZC5oY3JjKSB7XG4gICAgICBpZiAocy5wZW5kaW5nICsgMiA+IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgICBpZiAocy5wZW5kaW5nICE9PSAwKSB7XG4gICAgICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7XG4gICAgICAgICAgcmV0dXJuIFpfT0skMztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcHV0X2J5dGUocywgc3RybS5hZGxlciAmIDB4ZmYpO1xuICAgICAgcHV0X2J5dGUocywgKHN0cm0uYWRsZXIgPj4gOCkgJiAweGZmKTtcbiAgICAgIHN0cm0uYWRsZXIgPSAwOyAvL2NyYzMyKDBMLCBaX05VTEwsIDApO1xuICAgIH1cbiAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7XG5cbiAgICAvKiBDb21wcmVzc2lvbiBtdXN0IHN0YXJ0IHdpdGggYW4gZW1wdHkgcGVuZGluZyBidWZmZXIgKi9cbiAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgIGlmIChzLnBlbmRpbmcgIT09IDApIHtcbiAgICAgIHMubGFzdF9mbHVzaCA9IC0xO1xuICAgICAgcmV0dXJuIFpfT0skMztcbiAgICB9XG4gIH1cbi8vI2VuZGlmXG5cbiAgLyogU3RhcnQgYSBuZXcgYmxvY2sgb3IgY29udGludWUgdGhlIGN1cnJlbnQgb25lLlxuICAgKi9cbiAgaWYgKHN0cm0uYXZhaWxfaW4gIT09IDAgfHwgcy5sb29rYWhlYWQgIT09IDAgfHxcbiAgICAoZmx1c2ggIT09IFpfTk9fRkxVU0gkMiAmJiBzLnN0YXR1cyAhPT0gRklOSVNIX1NUQVRFKSkge1xuICAgIGxldCBic3RhdGUgPSBzLmxldmVsID09PSAwID8gZGVmbGF0ZV9zdG9yZWQocywgZmx1c2gpIDpcbiAgICAgICAgICAgICAgICAgcy5zdHJhdGVneSA9PT0gWl9IVUZGTUFOX09OTFkgPyBkZWZsYXRlX2h1ZmYocywgZmx1c2gpIDpcbiAgICAgICAgICAgICAgICAgcy5zdHJhdGVneSA9PT0gWl9STEUgPyBkZWZsYXRlX3JsZShzLCBmbHVzaCkgOlxuICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLmZ1bmMocywgZmx1c2gpO1xuXG4gICAgaWYgKGJzdGF0ZSA9PT0gQlNfRklOSVNIX1NUQVJURUQgfHwgYnN0YXRlID09PSBCU19GSU5JU0hfRE9ORSkge1xuICAgICAgcy5zdGF0dXMgPSBGSU5JU0hfU1RBVEU7XG4gICAgfVxuICAgIGlmIChic3RhdGUgPT09IEJTX05FRURfTU9SRSB8fCBic3RhdGUgPT09IEJTX0ZJTklTSF9TVEFSVEVEKSB7XG4gICAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7XG4gICAgICAgIC8qIGF2b2lkIEJVRl9FUlJPUiBuZXh0IGNhbGwsIHNlZSBhYm92ZSAqL1xuICAgICAgfVxuICAgICAgcmV0dXJuIFpfT0skMztcbiAgICAgIC8qIElmIGZsdXNoICE9IFpfTk9fRkxVU0ggJiYgYXZhaWxfb3V0ID09IDAsIHRoZSBuZXh0IGNhbGxcbiAgICAgICAqIG9mIGRlZmxhdGUgc2hvdWxkIHVzZSB0aGUgc2FtZSBmbHVzaCBwYXJhbWV0ZXIgdG8gbWFrZSBzdXJlXG4gICAgICAgKiB0aGF0IHRoZSBmbHVzaCBpcyBjb21wbGV0ZS4gU28gd2UgZG9uJ3QgaGF2ZSB0byBvdXRwdXQgYW5cbiAgICAgICAqIGVtcHR5IGJsb2NrIGhlcmUsIHRoaXMgd2lsbCBiZSBkb25lIGF0IG5leHQgY2FsbC4gVGhpcyBhbHNvXG4gICAgICAgKiBlbnN1cmVzIHRoYXQgZm9yIGEgdmVyeSBzbWFsbCBvdXRwdXQgYnVmZmVyLCB3ZSBlbWl0IGF0IG1vc3RcbiAgICAgICAqIG9uZSBlbXB0eSBibG9jay5cbiAgICAgICAqL1xuICAgIH1cbiAgICBpZiAoYnN0YXRlID09PSBCU19CTE9DS19ET05FKSB7XG4gICAgICBpZiAoZmx1c2ggPT09IFpfUEFSVElBTF9GTFVTSCkge1xuICAgICAgICBfdHJfYWxpZ24ocyk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChmbHVzaCAhPT0gWl9CTE9DSyQxKSB7IC8qIEZVTExfRkxVU0ggb3IgU1lOQ19GTFVTSCAqL1xuXG4gICAgICAgIF90cl9zdG9yZWRfYmxvY2socywgMCwgMCwgZmFsc2UpO1xuICAgICAgICAvKiBGb3IgYSBmdWxsIGZsdXNoLCB0aGlzIGVtcHR5IGJsb2NrIHdpbGwgYmUgcmVjb2duaXplZFxuICAgICAgICAgKiBhcyBhIHNwZWNpYWwgbWFya2VyIGJ5IGluZmxhdGVfc3luYygpLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGZsdXNoID09PSBaX0ZVTExfRkxVU0gkMSkge1xuICAgICAgICAgIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqLyAgICAgICAgICAgICAvKiBmb3JnZXQgaGlzdG9yeSAqL1xuICAgICAgICAgIHplcm8ocy5oZWFkKTsgLy8gRmlsbCB3aXRoIE5JTCAoPSAwKTtcblxuICAgICAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCkge1xuICAgICAgICAgICAgcy5zdHJzdGFydCA9IDA7XG4gICAgICAgICAgICBzLmJsb2NrX3N0YXJ0ID0gMDtcbiAgICAgICAgICAgIHMuaW5zZXJ0ID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgcy5sYXN0X2ZsdXNoID0gLTE7IC8qIGF2b2lkIEJVRl9FUlJPUiBhdCBuZXh0IGNhbGwsIHNlZSBhYm92ZSAqL1xuICAgICAgICByZXR1cm4gWl9PSyQzO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChmbHVzaCAhPT0gWl9GSU5JU0gkMykgeyByZXR1cm4gWl9PSyQzOyB9XG4gIGlmIChzLndyYXAgPD0gMCkgeyByZXR1cm4gWl9TVFJFQU1fRU5EJDM7IH1cblxuICAvKiBXcml0ZSB0aGUgdHJhaWxlciAqL1xuICBpZiAocy53cmFwID09PSAyKSB7XG4gICAgcHV0X2J5dGUocywgc3RybS5hZGxlciAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLmFkbGVyID4+IDgpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0uYWRsZXIgPj4gMTYpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0uYWRsZXIgPj4gMjQpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgc3RybS50b3RhbF9pbiAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLnRvdGFsX2luID4+IDgpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0udG90YWxfaW4gPj4gMTYpICYgMHhmZik7XG4gICAgcHV0X2J5dGUocywgKHN0cm0udG90YWxfaW4gPj4gMjQpICYgMHhmZik7XG4gIH1cbiAgZWxzZVxuICB7XG4gICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciA+Pj4gMTYpO1xuICAgIHB1dFNob3J0TVNCKHMsIHN0cm0uYWRsZXIgJiAweGZmZmYpO1xuICB9XG5cbiAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgLyogSWYgYXZhaWxfb3V0IGlzIHplcm8sIHRoZSBhcHBsaWNhdGlvbiB3aWxsIGNhbGwgZGVmbGF0ZSBhZ2FpblxuICAgKiB0byBmbHVzaCB0aGUgcmVzdC5cbiAgICovXG4gIGlmIChzLndyYXAgPiAwKSB7IHMud3JhcCA9IC1zLndyYXA7IH1cbiAgLyogd3JpdGUgdGhlIHRyYWlsZXIgb25seSBvbmNlISAqL1xuICByZXR1cm4gcy5wZW5kaW5nICE9PSAwID8gWl9PSyQzIDogWl9TVFJFQU1fRU5EJDM7XG59O1xuXG5cbmNvbnN0IGRlZmxhdGVFbmQgPSAoc3RybSkgPT4ge1xuXG4gIGlmIChkZWZsYXRlU3RhdGVDaGVjayhzdHJtKSkge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUiQyO1xuICB9XG5cbiAgY29uc3Qgc3RhdHVzID0gc3RybS5zdGF0ZS5zdGF0dXM7XG5cbiAgc3RybS5zdGF0ZSA9IG51bGw7XG5cbiAgcmV0dXJuIHN0YXR1cyA9PT0gQlVTWV9TVEFURSA/IGVycihzdHJtLCBaX0RBVEFfRVJST1IkMikgOiBaX09LJDM7XG59O1xuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemVzIHRoZSBjb21wcmVzc2lvbiBkaWN0aW9uYXJ5IGZyb20gdGhlIGdpdmVuIGJ5dGVcbiAqIHNlcXVlbmNlIHdpdGhvdXQgcHJvZHVjaW5nIGFueSBjb21wcmVzc2VkIG91dHB1dC5cbiAqL1xuY29uc3QgZGVmbGF0ZVNldERpY3Rpb25hcnkgPSAoc3RybSwgZGljdGlvbmFyeSkgPT4ge1xuXG4gIGxldCBkaWN0TGVuZ3RoID0gZGljdGlvbmFyeS5sZW5ndGg7XG5cbiAgaWYgKGRlZmxhdGVTdGF0ZUNoZWNrKHN0cm0pKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDI7XG4gIH1cblxuICBjb25zdCBzID0gc3RybS5zdGF0ZTtcbiAgY29uc3Qgd3JhcCA9IHMud3JhcDtcblxuICBpZiAod3JhcCA9PT0gMiB8fCAod3JhcCA9PT0gMSAmJiBzLnN0YXR1cyAhPT0gSU5JVF9TVEFURSkgfHwgcy5sb29rYWhlYWQpIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMjtcbiAgfVxuXG4gIC8qIHdoZW4gdXNpbmcgemxpYiB3cmFwcGVycywgY29tcHV0ZSBBZGxlci0zMiBmb3IgcHJvdmlkZWQgZGljdGlvbmFyeSAqL1xuICBpZiAod3JhcCA9PT0gMSkge1xuICAgIC8qIGFkbGVyMzIoc3RybS0+YWRsZXIsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgpOyAqL1xuICAgIHN0cm0uYWRsZXIgPSBhZGxlcjMyXzEoc3RybS5hZGxlciwgZGljdGlvbmFyeSwgZGljdExlbmd0aCwgMCk7XG4gIH1cblxuICBzLndyYXAgPSAwOyAgIC8qIGF2b2lkIGNvbXB1dGluZyBBZGxlci0zMiBpbiByZWFkX2J1ZiAqL1xuXG4gIC8qIGlmIGRpY3Rpb25hcnkgd291bGQgZmlsbCB3aW5kb3csIGp1c3QgcmVwbGFjZSB0aGUgaGlzdG9yeSAqL1xuICBpZiAoZGljdExlbmd0aCA+PSBzLndfc2l6ZSkge1xuICAgIGlmICh3cmFwID09PSAwKSB7ICAgICAgICAgICAgLyogYWxyZWFkeSBlbXB0eSBvdGhlcndpc2UgKi9cbiAgICAgIC8qKiogQ0xFQVJfSEFTSChzKTsgKioqL1xuICAgICAgemVybyhzLmhlYWQpOyAvLyBGaWxsIHdpdGggTklMICg9IDApO1xuICAgICAgcy5zdHJzdGFydCA9IDA7XG4gICAgICBzLmJsb2NrX3N0YXJ0ID0gMDtcbiAgICAgIHMuaW5zZXJ0ID0gMDtcbiAgICB9XG4gICAgLyogdXNlIHRoZSB0YWlsICovXG4gICAgLy8gZGljdGlvbmFyeSA9IGRpY3Rpb25hcnkuc2xpY2UoZGljdExlbmd0aCAtIHMud19zaXplKTtcbiAgICBsZXQgdG1wRGljdCA9IG5ldyBVaW50OEFycmF5KHMud19zaXplKTtcbiAgICB0bXBEaWN0LnNldChkaWN0aW9uYXJ5LnN1YmFycmF5KGRpY3RMZW5ndGggLSBzLndfc2l6ZSwgZGljdExlbmd0aCksIDApO1xuICAgIGRpY3Rpb25hcnkgPSB0bXBEaWN0O1xuICAgIGRpY3RMZW5ndGggPSBzLndfc2l6ZTtcbiAgfVxuICAvKiBpbnNlcnQgZGljdGlvbmFyeSBpbnRvIHdpbmRvdyBhbmQgaGFzaCAqL1xuICBjb25zdCBhdmFpbCA9IHN0cm0uYXZhaWxfaW47XG4gIGNvbnN0IG5leHQgPSBzdHJtLm5leHRfaW47XG4gIGNvbnN0IGlucHV0ID0gc3RybS5pbnB1dDtcbiAgc3RybS5hdmFpbF9pbiA9IGRpY3RMZW5ndGg7XG4gIHN0cm0ubmV4dF9pbiA9IDA7XG4gIHN0cm0uaW5wdXQgPSBkaWN0aW9uYXJ5O1xuICBmaWxsX3dpbmRvdyhzKTtcbiAgd2hpbGUgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkge1xuICAgIGxldCBzdHIgPSBzLnN0cnN0YXJ0O1xuICAgIGxldCBuID0gcy5sb29rYWhlYWQgLSAoTUlOX01BVENIIC0gMSk7XG4gICAgZG8ge1xuICAgICAgLyogVVBEQVRFX0hBU0gocywgcy0+aW5zX2gsIHMtPndpbmRvd1tzdHIgKyBNSU5fTUFUQ0gtMV0pOyAqL1xuICAgICAgcy5pbnNfaCA9IEhBU0gocywgcy5pbnNfaCwgcy53aW5kb3dbc3RyICsgTUlOX01BVENIIC0gMV0pO1xuXG4gICAgICBzLnByZXZbc3RyICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuXG4gICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzdHI7XG4gICAgICBzdHIrKztcbiAgICB9IHdoaWxlICgtLW4pO1xuICAgIHMuc3Ryc3RhcnQgPSBzdHI7XG4gICAgcy5sb29rYWhlYWQgPSBNSU5fTUFUQ0ggLSAxO1xuICAgIGZpbGxfd2luZG93KHMpO1xuICB9XG4gIHMuc3Ryc3RhcnQgKz0gcy5sb29rYWhlYWQ7XG4gIHMuYmxvY2tfc3RhcnQgPSBzLnN0cnN0YXJ0O1xuICBzLmluc2VydCA9IHMubG9va2FoZWFkO1xuICBzLmxvb2thaGVhZCA9IDA7XG4gIHMubWF0Y2hfbGVuZ3RoID0gcy5wcmV2X2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7XG4gIHMubWF0Y2hfYXZhaWxhYmxlID0gMDtcbiAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgc3RybS5pbnB1dCA9IGlucHV0O1xuICBzdHJtLmF2YWlsX2luID0gYXZhaWw7XG4gIHMud3JhcCA9IHdyYXA7XG4gIHJldHVybiBaX09LJDM7XG59O1xuXG5cbnZhciBkZWZsYXRlSW5pdF8xID0gZGVmbGF0ZUluaXQ7XG52YXIgZGVmbGF0ZUluaXQyXzEgPSBkZWZsYXRlSW5pdDI7XG52YXIgZGVmbGF0ZVJlc2V0XzEgPSBkZWZsYXRlUmVzZXQ7XG52YXIgZGVmbGF0ZVJlc2V0S2VlcF8xID0gZGVmbGF0ZVJlc2V0S2VlcDtcbnZhciBkZWZsYXRlU2V0SGVhZGVyXzEgPSBkZWZsYXRlU2V0SGVhZGVyO1xudmFyIGRlZmxhdGVfMiQxID0gZGVmbGF0ZSQyO1xudmFyIGRlZmxhdGVFbmRfMSA9IGRlZmxhdGVFbmQ7XG52YXIgZGVmbGF0ZVNldERpY3Rpb25hcnlfMSA9IGRlZmxhdGVTZXREaWN0aW9uYXJ5O1xudmFyIGRlZmxhdGVJbmZvID0gJ3Bha28gZGVmbGF0ZSAoZnJvbSBOb2RlY2EgcHJvamVjdCknO1xuXG4vKiBOb3QgaW1wbGVtZW50ZWRcbm1vZHVsZS5leHBvcnRzLmRlZmxhdGVCb3VuZCA9IGRlZmxhdGVCb3VuZDtcbm1vZHVsZS5leHBvcnRzLmRlZmxhdGVDb3B5ID0gZGVmbGF0ZUNvcHk7XG5tb2R1bGUuZXhwb3J0cy5kZWZsYXRlR2V0RGljdGlvbmFyeSA9IGRlZmxhdGVHZXREaWN0aW9uYXJ5O1xubW9kdWxlLmV4cG9ydHMuZGVmbGF0ZVBhcmFtcyA9IGRlZmxhdGVQYXJhbXM7XG5tb2R1bGUuZXhwb3J0cy5kZWZsYXRlUGVuZGluZyA9IGRlZmxhdGVQZW5kaW5nO1xubW9kdWxlLmV4cG9ydHMuZGVmbGF0ZVByaW1lID0gZGVmbGF0ZVByaW1lO1xubW9kdWxlLmV4cG9ydHMuZGVmbGF0ZVR1bmUgPSBkZWZsYXRlVHVuZTtcbiovXG5cbnZhciBkZWZsYXRlXzEkMiA9IHtcblx0ZGVmbGF0ZUluaXQ6IGRlZmxhdGVJbml0XzEsXG5cdGRlZmxhdGVJbml0MjogZGVmbGF0ZUluaXQyXzEsXG5cdGRlZmxhdGVSZXNldDogZGVmbGF0ZVJlc2V0XzEsXG5cdGRlZmxhdGVSZXNldEtlZXA6IGRlZmxhdGVSZXNldEtlZXBfMSxcblx0ZGVmbGF0ZVNldEhlYWRlcjogZGVmbGF0ZVNldEhlYWRlcl8xLFxuXHRkZWZsYXRlOiBkZWZsYXRlXzIkMSxcblx0ZGVmbGF0ZUVuZDogZGVmbGF0ZUVuZF8xLFxuXHRkZWZsYXRlU2V0RGljdGlvbmFyeTogZGVmbGF0ZVNldERpY3Rpb25hcnlfMSxcblx0ZGVmbGF0ZUluZm86IGRlZmxhdGVJbmZvXG59O1xuXG5jb25zdCBfaGFzID0gKG9iaiwga2V5KSA9PiB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xufTtcblxudmFyIGFzc2lnbiA9IGZ1bmN0aW9uIChvYmogLypmcm9tMSwgZnJvbTIsIGZyb20zLCAuLi4qLykge1xuICBjb25zdCBzb3VyY2VzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgd2hpbGUgKHNvdXJjZXMubGVuZ3RoKSB7XG4gICAgY29uc3Qgc291cmNlID0gc291cmNlcy5zaGlmdCgpO1xuICAgIGlmICghc291cmNlKSB7IGNvbnRpbnVlOyB9XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3Ioc291cmNlICsgJ211c3QgYmUgbm9uLW9iamVjdCcpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcCBpbiBzb3VyY2UpIHtcbiAgICAgIGlmIChfaGFzKHNvdXJjZSwgcCkpIHtcbiAgICAgICAgb2JqW3BdID0gc291cmNlW3BdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59O1xuXG5cbi8vIEpvaW4gYXJyYXkgb2YgY2h1bmtzIHRvIHNpbmdsZSBhcnJheS5cbnZhciBmbGF0dGVuQ2h1bmtzID0gKGNodW5rcykgPT4ge1xuICAvLyBjYWxjdWxhdGUgZGF0YSBsZW5ndGhcbiAgbGV0IGxlbiA9IDA7XG5cbiAgZm9yIChsZXQgaSA9IDAsIGwgPSBjaHVua3MubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgbGVuICs9IGNodW5rc1tpXS5sZW5ndGg7XG4gIH1cblxuICAvLyBqb2luIGNodW5rc1xuICBjb25zdCByZXN1bHQgPSBuZXcgVWludDhBcnJheShsZW4pO1xuXG4gIGZvciAobGV0IGkgPSAwLCBwb3MgPSAwLCBsID0gY2h1bmtzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGxldCBjaHVuayA9IGNodW5rc1tpXTtcbiAgICByZXN1bHQuc2V0KGNodW5rLCBwb3MpO1xuICAgIHBvcyArPSBjaHVuay5sZW5ndGg7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxudmFyIGNvbW1vbiA9IHtcblx0YXNzaWduOiBhc3NpZ24sXG5cdGZsYXR0ZW5DaHVua3M6IGZsYXR0ZW5DaHVua3Ncbn07XG5cbi8vIFN0cmluZyBlbmNvZGUvZGVjb2RlIGhlbHBlcnNcblxuXG4vLyBRdWljayBjaGVjayBpZiB3ZSBjYW4gdXNlIGZhc3QgYXJyYXkgdG8gYmluIHN0cmluZyBjb252ZXJzaW9uXG4vL1xuLy8gLSBhcHBseShBcnJheSkgY2FuIGZhaWwgb24gQW5kcm9pZCAyLjJcbi8vIC0gYXBwbHkoVWludDhBcnJheSkgY2FuIGZhaWwgb24gaU9TIDUuMSBTYWZhcmlcbi8vXG5sZXQgU1RSX0FQUExZX1VJQV9PSyA9IHRydWU7XG5cbnRyeSB7IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQ4QXJyYXkoMSkpOyB9IGNhdGNoIChfXykgeyBTVFJfQVBQTFlfVUlBX09LID0gZmFsc2U7IH1cblxuXG4vLyBUYWJsZSB3aXRoIHV0ZjggbGVuZ3RocyAoY2FsY3VsYXRlZCBieSBmaXJzdCBieXRlIG9mIHNlcXVlbmNlKVxuLy8gTm90ZSwgdGhhdCA1ICYgNi1ieXRlIHZhbHVlcyBhbmQgc29tZSA0LWJ5dGUgdmFsdWVzIGNhbiBub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlMsXG4vLyBiZWNhdXNlIG1heCBwb3NzaWJsZSBjb2RlcG9pbnQgaXMgMHgxMGZmZmZcbmNvbnN0IF91dGY4bGVuID0gbmV3IFVpbnQ4QXJyYXkoMjU2KTtcbmZvciAobGV0IHEgPSAwOyBxIDwgMjU2OyBxKyspIHtcbiAgX3V0ZjhsZW5bcV0gPSAocSA+PSAyNTIgPyA2IDogcSA+PSAyNDggPyA1IDogcSA+PSAyNDAgPyA0IDogcSA+PSAyMjQgPyAzIDogcSA+PSAxOTIgPyAyIDogMSk7XG59XG5fdXRmOGxlblsyNTRdID0gX3V0ZjhsZW5bMjU0XSA9IDE7IC8vIEludmFsaWQgc2VxdWVuY2Ugc3RhcnRcblxuXG4vLyBjb252ZXJ0IHN0cmluZyB0byBhcnJheSAodHlwZWQsIHdoZW4gcG9zc2libGUpXG52YXIgc3RyaW5nMmJ1ZiA9IChzdHIpID0+IHtcbiAgaWYgKHR5cGVvZiBUZXh0RW5jb2RlciA9PT0gJ2Z1bmN0aW9uJyAmJiBUZXh0RW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlKSB7XG4gICAgcmV0dXJuIG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzdHIpO1xuICB9XG5cbiAgbGV0IGJ1ZiwgYywgYzIsIG1fcG9zLCBpLCBzdHJfbGVuID0gc3RyLmxlbmd0aCwgYnVmX2xlbiA9IDA7XG5cbiAgLy8gY291bnQgYmluYXJ5IHNpemVcbiAgZm9yIChtX3BvcyA9IDA7IG1fcG9zIDwgc3RyX2xlbjsgbV9wb3MrKykge1xuICAgIGMgPSBzdHIuY2hhckNvZGVBdChtX3Bvcyk7XG4gICAgaWYgKChjICYgMHhmYzAwKSA9PT0gMHhkODAwICYmIChtX3BvcyArIDEgPCBzdHJfbGVuKSkge1xuICAgICAgYzIgPSBzdHIuY2hhckNvZGVBdChtX3BvcyArIDEpO1xuICAgICAgaWYgKChjMiAmIDB4ZmMwMCkgPT09IDB4ZGMwMCkge1xuICAgICAgICBjID0gMHgxMDAwMCArICgoYyAtIDB4ZDgwMCkgPDwgMTApICsgKGMyIC0gMHhkYzAwKTtcbiAgICAgICAgbV9wb3MrKztcbiAgICAgIH1cbiAgICB9XG4gICAgYnVmX2xlbiArPSBjIDwgMHg4MCA/IDEgOiBjIDwgMHg4MDAgPyAyIDogYyA8IDB4MTAwMDAgPyAzIDogNDtcbiAgfVxuXG4gIC8vIGFsbG9jYXRlIGJ1ZmZlclxuICBidWYgPSBuZXcgVWludDhBcnJheShidWZfbGVuKTtcblxuICAvLyBjb252ZXJ0XG4gIGZvciAoaSA9IDAsIG1fcG9zID0gMDsgaSA8IGJ1Zl9sZW47IG1fcG9zKyspIHtcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQobV9wb3MpO1xuICAgIGlmICgoYyAmIDB4ZmMwMCkgPT09IDB4ZDgwMCAmJiAobV9wb3MgKyAxIDwgc3RyX2xlbikpIHtcbiAgICAgIGMyID0gc3RyLmNoYXJDb2RlQXQobV9wb3MgKyAxKTtcbiAgICAgIGlmICgoYzIgJiAweGZjMDApID09PSAweGRjMDApIHtcbiAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgLSAweGQ4MDApIDw8IDEwKSArIChjMiAtIDB4ZGMwMCk7XG4gICAgICAgIG1fcG9zKys7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgLyogb25lIGJ5dGUgKi9cbiAgICAgIGJ1ZltpKytdID0gYztcbiAgICB9IGVsc2UgaWYgKGMgPCAweDgwMCkge1xuICAgICAgLyogdHdvIGJ5dGVzICovXG4gICAgICBidWZbaSsrXSA9IDB4QzAgfCAoYyA+Pj4gNik7XG4gICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyAmIDB4M2YpO1xuICAgIH0gZWxzZSBpZiAoYyA8IDB4MTAwMDApIHtcbiAgICAgIC8qIHRocmVlIGJ5dGVzICovXG4gICAgICBidWZbaSsrXSA9IDB4RTAgfCAoYyA+Pj4gMTIpO1xuICAgICAgYnVmW2krK10gPSAweDgwIHwgKGMgPj4+IDYgJiAweDNmKTtcbiAgICAgIGJ1ZltpKytdID0gMHg4MCB8IChjICYgMHgzZik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIGZvdXIgYnl0ZXMgKi9cbiAgICAgIGJ1ZltpKytdID0gMHhmMCB8IChjID4+PiAxOCk7XG4gICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyA+Pj4gMTIgJiAweDNmKTtcbiAgICAgIGJ1ZltpKytdID0gMHg4MCB8IChjID4+PiA2ICYgMHgzZik7XG4gICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyAmIDB4M2YpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWY7XG59O1xuXG4vLyBIZWxwZXJcbmNvbnN0IGJ1ZjJiaW5zdHJpbmcgPSAoYnVmLCBsZW4pID0+IHtcbiAgLy8gT24gQ2hyb21lLCB0aGUgYXJndW1lbnRzIGluIGEgZnVuY3Rpb24gY2FsbCB0aGF0IGFyZSBhbGxvd2VkIGlzIGA2NTUzNGAuXG4gIC8vIElmIHRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlciBpcyBzbWFsbGVyIHRoYW4gdGhhdCwgd2UgY2FuIHVzZSB0aGlzIG9wdGltaXphdGlvbixcbiAgLy8gb3RoZXJ3aXNlIHdlIHdpbGwgdGFrZSBhIHNsb3dlciBwYXRoLlxuICBpZiAobGVuIDwgNjU1MzQpIHtcbiAgICBpZiAoYnVmLnN1YmFycmF5ICYmIFNUUl9BUFBMWV9VSUFfT0spIHtcbiAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGJ1Zi5sZW5ndGggPT09IGxlbiA/IGJ1ZiA6IGJ1Zi5zdWJhcnJheSgwLCBsZW4pKTtcbiAgICB9XG4gIH1cblxuICBsZXQgcmVzdWx0ID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbi8vIGNvbnZlcnQgYXJyYXkgdG8gc3RyaW5nXG52YXIgYnVmMnN0cmluZyA9IChidWYsIG1heCkgPT4ge1xuICBjb25zdCBsZW4gPSBtYXggfHwgYnVmLmxlbmd0aDtcblxuICBpZiAodHlwZW9mIFRleHREZWNvZGVyID09PSAnZnVuY3Rpb24nICYmIFRleHREZWNvZGVyLnByb3RvdHlwZS5kZWNvZGUpIHtcbiAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJ1Zi5zdWJhcnJheSgwLCBtYXgpKTtcbiAgfVxuXG4gIGxldCBpLCBvdXQ7XG5cbiAgLy8gUmVzZXJ2ZSBtYXggcG9zc2libGUgbGVuZ3RoICgyIHdvcmRzIHBlciBjaGFyKVxuICAvLyBOQjogYnkgdW5rbm93biByZWFzb25zLCBBcnJheSBpcyBzaWduaWZpY2FudGx5IGZhc3RlciBmb3JcbiAgLy8gICAgIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkgdGhhbiBVaW50MTZBcnJheS5cbiAgY29uc3QgdXRmMTZidWYgPSBuZXcgQXJyYXkobGVuICogMik7XG5cbiAgZm9yIChvdXQgPSAwLCBpID0gMDsgaSA8IGxlbjspIHtcbiAgICBsZXQgYyA9IGJ1ZltpKytdO1xuICAgIC8vIHF1aWNrIHByb2Nlc3MgYXNjaWlcbiAgICBpZiAoYyA8IDB4ODApIHsgdXRmMTZidWZbb3V0KytdID0gYzsgY29udGludWU7IH1cblxuICAgIGxldCBjX2xlbiA9IF91dGY4bGVuW2NdO1xuICAgIC8vIHNraXAgNSAmIDYgYnl0ZSBjb2Rlc1xuICAgIGlmIChjX2xlbiA+IDQpIHsgdXRmMTZidWZbb3V0KytdID0gMHhmZmZkOyBpICs9IGNfbGVuIC0gMTsgY29udGludWU7IH1cblxuICAgIC8vIGFwcGx5IG1hc2sgb24gZmlyc3QgYnl0ZVxuICAgIGMgJj0gY19sZW4gPT09IDIgPyAweDFmIDogY19sZW4gPT09IDMgPyAweDBmIDogMHgwNztcbiAgICAvLyBqb2luIHRoZSByZXN0XG4gICAgd2hpbGUgKGNfbGVuID4gMSAmJiBpIDwgbGVuKSB7XG4gICAgICBjID0gKGMgPDwgNikgfCAoYnVmW2krK10gJiAweDNmKTtcbiAgICAgIGNfbGVuLS07XG4gICAgfVxuXG4gICAgLy8gdGVybWluYXRlZCBieSBlbmQgb2Ygc3RyaW5nP1xuICAgIGlmIChjX2xlbiA+IDEpIHsgdXRmMTZidWZbb3V0KytdID0gMHhmZmZkOyBjb250aW51ZTsgfVxuXG4gICAgaWYgKGMgPCAweDEwMDAwKSB7XG4gICAgICB1dGYxNmJ1ZltvdXQrK10gPSBjO1xuICAgIH0gZWxzZSB7XG4gICAgICBjIC09IDB4MTAwMDA7XG4gICAgICB1dGYxNmJ1ZltvdXQrK10gPSAweGQ4MDAgfCAoKGMgPj4gMTApICYgMHgzZmYpO1xuICAgICAgdXRmMTZidWZbb3V0KytdID0gMHhkYzAwIHwgKGMgJiAweDNmZik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ1ZjJiaW5zdHJpbmcodXRmMTZidWYsIG91dCk7XG59O1xuXG5cbi8vIENhbGN1bGF0ZSBtYXggcG9zc2libGUgcG9zaXRpb24gaW4gdXRmOCBidWZmZXIsXG4vLyB0aGF0IHdpbGwgbm90IGJyZWFrIHNlcXVlbmNlLiBJZiB0aGF0J3Mgbm90IHBvc3NpYmxlXG4vLyAtICh2ZXJ5IHNtYWxsIGxpbWl0cykgcmV0dXJuIG1heCBzaXplIGFzIGlzLlxuLy9cbi8vIGJ1ZltdIC0gdXRmOCBieXRlcyBhcnJheVxuLy8gbWF4ICAgLSBsZW5ndGggbGltaXQgKG1hbmRhdG9yeSk7XG52YXIgdXRmOGJvcmRlciA9IChidWYsIG1heCkgPT4ge1xuXG4gIG1heCA9IG1heCB8fCBidWYubGVuZ3RoO1xuICBpZiAobWF4ID4gYnVmLmxlbmd0aCkgeyBtYXggPSBidWYubGVuZ3RoOyB9XG5cbiAgLy8gZ28gYmFjayBmcm9tIGxhc3QgcG9zaXRpb24sIHVudGlsIHN0YXJ0IG9mIHNlcXVlbmNlIGZvdW5kXG4gIGxldCBwb3MgPSBtYXggLSAxO1xuICB3aGlsZSAocG9zID49IDAgJiYgKGJ1Zltwb3NdICYgMHhDMCkgPT09IDB4ODApIHsgcG9zLS07IH1cblxuICAvLyBWZXJ5IHNtYWxsIGFuZCBicm9rZW4gc2VxdWVuY2UsXG4gIC8vIHJldHVybiBtYXgsIGJlY2F1c2Ugd2Ugc2hvdWxkIHJldHVybiBzb21ldGhpbmcgYW55d2F5LlxuICBpZiAocG9zIDwgMCkgeyByZXR1cm4gbWF4OyB9XG5cbiAgLy8gSWYgd2UgY2FtZSB0byBzdGFydCBvZiBidWZmZXIgLSB0aGF0IG1lYW5zIGJ1ZmZlciBpcyB0b28gc21hbGwsXG4gIC8vIHJldHVybiBtYXggdG9vLlxuICBpZiAocG9zID09PSAwKSB7IHJldHVybiBtYXg7IH1cblxuICByZXR1cm4gKHBvcyArIF91dGY4bGVuW2J1Zltwb3NdXSA+IG1heCkgPyBwb3MgOiBtYXg7XG59O1xuXG52YXIgc3RyaW5ncyA9IHtcblx0c3RyaW5nMmJ1Zjogc3RyaW5nMmJ1Zixcblx0YnVmMnN0cmluZzogYnVmMnN0cmluZyxcblx0dXRmOGJvcmRlcjogdXRmOGJvcmRlclxufTtcblxuLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyXG4vLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpblxuLy9cbi8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkXG4vLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXNcbi8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsXG4vLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0XG4vLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6XG4vL1xuLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3Rcbi8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmVcbi8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlXG4vLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuXG4vLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZVxuLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuXG4vLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLlxuXG5mdW5jdGlvbiBaU3RyZWFtKCkge1xuICAvKiBuZXh0IGlucHV0IGJ5dGUgKi9cbiAgdGhpcy5pbnB1dCA9IG51bGw7IC8vIEpTIHNwZWNpZmljLCBiZWNhdXNlIHdlIGhhdmUgbm8gcG9pbnRlcnNcbiAgdGhpcy5uZXh0X2luID0gMDtcbiAgLyogbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSBhdCBpbnB1dCAqL1xuICB0aGlzLmF2YWlsX2luID0gMDtcbiAgLyogdG90YWwgbnVtYmVyIG9mIGlucHV0IGJ5dGVzIHJlYWQgc28gZmFyICovXG4gIHRoaXMudG90YWxfaW4gPSAwO1xuICAvKiBuZXh0IG91dHB1dCBieXRlIHNob3VsZCBiZSBwdXQgdGhlcmUgKi9cbiAgdGhpcy5vdXRwdXQgPSBudWxsOyAvLyBKUyBzcGVjaWZpYywgYmVjYXVzZSB3ZSBoYXZlIG5vIHBvaW50ZXJzXG4gIHRoaXMubmV4dF9vdXQgPSAwO1xuICAvKiByZW1haW5pbmcgZnJlZSBzcGFjZSBhdCBvdXRwdXQgKi9cbiAgdGhpcy5hdmFpbF9vdXQgPSAwO1xuICAvKiB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgb3V0cHV0IHNvIGZhciAqL1xuICB0aGlzLnRvdGFsX291dCA9IDA7XG4gIC8qIGxhc3QgZXJyb3IgbWVzc2FnZSwgTlVMTCBpZiBubyBlcnJvciAqL1xuICB0aGlzLm1zZyA9ICcnLypaX05VTEwqLztcbiAgLyogbm90IHZpc2libGUgYnkgYXBwbGljYXRpb25zICovXG4gIHRoaXMuc3RhdGUgPSBudWxsO1xuICAvKiBiZXN0IGd1ZXNzIGFib3V0IHRoZSBkYXRhIHR5cGU6IGJpbmFyeSBvciB0ZXh0ICovXG4gIHRoaXMuZGF0YV90eXBlID0gMi8qWl9VTktOT1dOKi87XG4gIC8qIGFkbGVyMzIgdmFsdWUgb2YgdGhlIHVuY29tcHJlc3NlZCBkYXRhICovXG4gIHRoaXMuYWRsZXIgPSAwO1xufVxuXG52YXIgenN0cmVhbSA9IFpTdHJlYW07XG5cbmNvbnN0IHRvU3RyaW5nJDEgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuY29uc3Qge1xuICBaX05PX0ZMVVNIOiBaX05PX0ZMVVNIJDEsIFpfU1lOQ19GTFVTSCwgWl9GVUxMX0ZMVVNILCBaX0ZJTklTSDogWl9GSU5JU0gkMixcbiAgWl9PSzogWl9PSyQyLCBaX1NUUkVBTV9FTkQ6IFpfU1RSRUFNX0VORCQyLFxuICBaX0RFRkFVTFRfQ09NUFJFU1NJT04sXG4gIFpfREVGQVVMVF9TVFJBVEVHWSxcbiAgWl9ERUZMQVRFRDogWl9ERUZMQVRFRCQxXG59ID0gY29uc3RhbnRzJDI7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuLyoqXG4gKiBjbGFzcyBEZWZsYXRlXG4gKlxuICogR2VuZXJpYyBKUy1zdHlsZSB3cmFwcGVyIGZvciB6bGliIGNhbGxzLiBJZiB5b3UgZG9uJ3QgbmVlZFxuICogc3RyZWFtaW5nIGJlaGF2aW91ciAtIHVzZSBtb3JlIHNpbXBsZSBmdW5jdGlvbnM6IFtbZGVmbGF0ZV1dLFxuICogW1tkZWZsYXRlUmF3XV0gYW5kIFtbZ3ppcF1dLlxuICoqL1xuXG4vKiBpbnRlcm5hbFxuICogRGVmbGF0ZS5jaHVua3MgLT4gQXJyYXlcbiAqXG4gKiBDaHVua3Mgb2Ygb3V0cHV0IGRhdGEsIGlmIFtbRGVmbGF0ZSNvbkRhdGFdXSBub3Qgb3ZlcnJpZGRlbi5cbiAqKi9cblxuLyoqXG4gKiBEZWZsYXRlLnJlc3VsdCAtPiBVaW50OEFycmF5XG4gKlxuICogQ29tcHJlc3NlZCByZXN1bHQsIGdlbmVyYXRlZCBieSBkZWZhdWx0IFtbRGVmbGF0ZSNvbkRhdGFdXVxuICogYW5kIFtbRGVmbGF0ZSNvbkVuZF1dIGhhbmRsZXJzLiBGaWxsZWQgYWZ0ZXIgeW91IHB1c2ggbGFzdCBjaHVua1xuICogKGNhbGwgW1tEZWZsYXRlI3B1c2hdXSB3aXRoIGBaX0ZJTklTSGAgLyBgdHJ1ZWAgcGFyYW0pLlxuICoqL1xuXG4vKipcbiAqIERlZmxhdGUuZXJyIC0+IE51bWJlclxuICpcbiAqIEVycm9yIGNvZGUgYWZ0ZXIgZGVmbGF0ZSBmaW5pc2hlZC4gMCAoWl9PSykgb24gc3VjY2Vzcy5cbiAqIFlvdSB3aWxsIG5vdCBuZWVkIGl0IGluIHJlYWwgbGlmZSwgYmVjYXVzZSBkZWZsYXRlIGVycm9yc1xuICogYXJlIHBvc3NpYmxlIG9ubHkgb24gd3Jvbmcgb3B0aW9ucyBvciBiYWQgYG9uRGF0YWAgLyBgb25FbmRgXG4gKiBjdXN0b20gaGFuZGxlcnMuXG4gKiovXG5cbi8qKlxuICogRGVmbGF0ZS5tc2cgLT4gU3RyaW5nXG4gKlxuICogRXJyb3IgbWVzc2FnZSwgaWYgW1tEZWZsYXRlLmVycl1dICE9IDBcbiAqKi9cblxuXG4vKipcbiAqIG5ldyBEZWZsYXRlKG9wdGlvbnMpXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLlxuICpcbiAqIENyZWF0ZXMgbmV3IGRlZmxhdG9yIGluc3RhbmNlIHdpdGggc3BlY2lmaWVkIHBhcmFtcy4gVGhyb3dzIGV4Y2VwdGlvblxuICogb24gYmFkIHBhcmFtcy4gU3VwcG9ydGVkIG9wdGlvbnM6XG4gKlxuICogLSBgbGV2ZWxgXG4gKiAtIGB3aW5kb3dCaXRzYFxuICogLSBgbWVtTGV2ZWxgXG4gKiAtIGBzdHJhdGVneWBcbiAqIC0gYGRpY3Rpb25hcnlgXG4gKlxuICogW2h0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZF0oaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkKVxuICogZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlc2UuXG4gKlxuICogQWRkaXRpb25hbCBvcHRpb25zLCBmb3IgaW50ZXJuYWwgbmVlZHM6XG4gKlxuICogLSBgY2h1bmtTaXplYCAtIHNpemUgb2YgZ2VuZXJhdGVkIGRhdGEgY2h1bmtzICgxNksgYnkgZGVmYXVsdClcbiAqIC0gYHJhd2AgKEJvb2xlYW4pIC0gZG8gcmF3IGRlZmxhdGVcbiAqIC0gYGd6aXBgIChCb29sZWFuKSAtIGNyZWF0ZSBnemlwIHdyYXBwZXJcbiAqIC0gYGhlYWRlcmAgKE9iamVjdCkgLSBjdXN0b20gaGVhZGVyIGZvciBnemlwXG4gKiAgIC0gYHRleHRgIChCb29sZWFuKSAtIHRydWUgaWYgY29tcHJlc3NlZCBkYXRhIGJlbGlldmVkIHRvIGJlIHRleHRcbiAqICAgLSBgdGltZWAgKE51bWJlcikgLSBtb2RpZmljYXRpb24gdGltZSwgdW5peCB0aW1lc3RhbXBcbiAqICAgLSBgb3NgIChOdW1iZXIpIC0gb3BlcmF0aW9uIHN5c3RlbSBjb2RlXG4gKiAgIC0gYGV4dHJhYCAoQXJyYXkpIC0gYXJyYXkgb2YgYnl0ZXMgd2l0aCBleHRyYSBkYXRhIChtYXggNjU1MzYpXG4gKiAgIC0gYG5hbWVgIChTdHJpbmcpIC0gZmlsZSBuYW1lIChiaW5hcnkgc3RyaW5nKVxuICogICAtIGBjb21tZW50YCAoU3RyaW5nKSAtIGNvbW1lbnQgKGJpbmFyeSBzdHJpbmcpXG4gKiAgIC0gYGhjcmNgIChCb29sZWFuKSAtIHRydWUgaWYgaGVhZGVyIGNyYyBzaG91bGQgYmUgYWRkZWRcbiAqXG4gKiAjIyMjIyBFeGFtcGxlOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGNvbnN0IHBha28gPSByZXF1aXJlKCdwYWtvJylcbiAqICAgLCBjaHVuazEgPSBuZXcgVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKVxuICogICAsIGNodW5rMiA9IG5ldyBVaW50OEFycmF5KFsxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOV0pO1xuICpcbiAqIGNvbnN0IGRlZmxhdGUgPSBuZXcgcGFrby5EZWZsYXRlKHsgbGV2ZWw6IDN9KTtcbiAqXG4gKiBkZWZsYXRlLnB1c2goY2h1bmsxLCBmYWxzZSk7XG4gKiBkZWZsYXRlLnB1c2goY2h1bmsyLCB0cnVlKTsgIC8vIHRydWUgLT4gbGFzdCBjaHVua1xuICpcbiAqIGlmIChkZWZsYXRlLmVycikgeyB0aHJvdyBuZXcgRXJyb3IoZGVmbGF0ZS5lcnIpOyB9XG4gKlxuICogY29uc29sZS5sb2coZGVmbGF0ZS5yZXN1bHQpO1xuICogYGBgXG4gKiovXG5mdW5jdGlvbiBEZWZsYXRlJDEob3B0aW9ucykge1xuICB0aGlzLm9wdGlvbnMgPSBjb21tb24uYXNzaWduKHtcbiAgICBsZXZlbDogWl9ERUZBVUxUX0NPTVBSRVNTSU9OLFxuICAgIG1ldGhvZDogWl9ERUZMQVRFRCQxLFxuICAgIGNodW5rU2l6ZTogMTYzODQsXG4gICAgd2luZG93Qml0czogMTUsXG4gICAgbWVtTGV2ZWw6IDgsXG4gICAgc3RyYXRlZ3k6IFpfREVGQVVMVF9TVFJBVEVHWVxuICB9LCBvcHRpb25zIHx8IHt9KTtcblxuICBsZXQgb3B0ID0gdGhpcy5vcHRpb25zO1xuXG4gIGlmIChvcHQucmF3ICYmIChvcHQud2luZG93Qml0cyA+IDApKSB7XG4gICAgb3B0LndpbmRvd0JpdHMgPSAtb3B0LndpbmRvd0JpdHM7XG4gIH1cblxuICBlbHNlIGlmIChvcHQuZ3ppcCAmJiAob3B0LndpbmRvd0JpdHMgPiAwKSAmJiAob3B0LndpbmRvd0JpdHMgPCAxNikpIHtcbiAgICBvcHQud2luZG93Qml0cyArPSAxNjtcbiAgfVxuXG4gIHRoaXMuZXJyICAgID0gMDsgICAgICAvLyBlcnJvciBjb2RlLCBpZiBoYXBwZW5zICgwID0gWl9PSylcbiAgdGhpcy5tc2cgICAgPSAnJzsgICAgIC8vIGVycm9yIG1lc3NhZ2VcbiAgdGhpcy5lbmRlZCAgPSBmYWxzZTsgIC8vIHVzZWQgdG8gYXZvaWQgbXVsdGlwbGUgb25FbmQoKSBjYWxsc1xuICB0aGlzLmNodW5rcyA9IFtdOyAgICAgLy8gY2h1bmtzIG9mIGNvbXByZXNzZWQgZGF0YVxuXG4gIHRoaXMuc3RybSA9IG5ldyB6c3RyZWFtKCk7XG4gIHRoaXMuc3RybS5hdmFpbF9vdXQgPSAwO1xuXG4gIGxldCBzdGF0dXMgPSBkZWZsYXRlXzEkMi5kZWZsYXRlSW5pdDIoXG4gICAgdGhpcy5zdHJtLFxuICAgIG9wdC5sZXZlbCxcbiAgICBvcHQubWV0aG9kLFxuICAgIG9wdC53aW5kb3dCaXRzLFxuICAgIG9wdC5tZW1MZXZlbCxcbiAgICBvcHQuc3RyYXRlZ3lcbiAgKTtcblxuICBpZiAoc3RhdHVzICE9PSBaX09LJDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZXNbc3RhdHVzXSk7XG4gIH1cblxuICBpZiAob3B0LmhlYWRlcikge1xuICAgIGRlZmxhdGVfMSQyLmRlZmxhdGVTZXRIZWFkZXIodGhpcy5zdHJtLCBvcHQuaGVhZGVyKTtcbiAgfVxuXG4gIGlmIChvcHQuZGljdGlvbmFyeSkge1xuICAgIGxldCBkaWN0O1xuICAgIC8vIENvbnZlcnQgZGF0YSBpZiBuZWVkZWRcbiAgICBpZiAodHlwZW9mIG9wdC5kaWN0aW9uYXJ5ID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gSWYgd2UgbmVlZCB0byBjb21wcmVzcyB0ZXh0LCBjaGFuZ2UgZW5jb2RpbmcgdG8gdXRmOC5cbiAgICAgIGRpY3QgPSBzdHJpbmdzLnN0cmluZzJidWYob3B0LmRpY3Rpb25hcnkpO1xuICAgIH0gZWxzZSBpZiAodG9TdHJpbmckMS5jYWxsKG9wdC5kaWN0aW9uYXJ5KSA9PT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJykge1xuICAgICAgZGljdCA9IG5ldyBVaW50OEFycmF5KG9wdC5kaWN0aW9uYXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGljdCA9IG9wdC5kaWN0aW9uYXJ5O1xuICAgIH1cblxuICAgIHN0YXR1cyA9IGRlZmxhdGVfMSQyLmRlZmxhdGVTZXREaWN0aW9uYXJ5KHRoaXMuc3RybSwgZGljdCk7XG5cbiAgICBpZiAoc3RhdHVzICE9PSBaX09LJDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlc1tzdGF0dXNdKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaWN0X3NldCA9IHRydWU7XG4gIH1cbn1cblxuLyoqXG4gKiBEZWZsYXRlI3B1c2goZGF0YVssIGZsdXNoX21vZGVdKSAtPiBCb29sZWFuXG4gKiAtIGRhdGEgKFVpbnQ4QXJyYXl8QXJyYXlCdWZmZXJ8U3RyaW5nKTogaW5wdXQgZGF0YS4gU3RyaW5ncyB3aWxsIGJlXG4gKiAgIGNvbnZlcnRlZCB0byB1dGY4IGJ5dGUgc2VxdWVuY2UuXG4gKiAtIGZsdXNoX21vZGUgKE51bWJlcnxCb29sZWFuKTogMC4uNiBmb3IgY29ycmVzcG9uZGluZyBaX05PX0ZMVVNILi5aX1RSRUUgbW9kZXMuXG4gKiAgIFNlZSBjb25zdGFudHMuIFNraXBwZWQgb3IgYGZhbHNlYCBtZWFucyBaX05PX0ZMVVNILCBgdHJ1ZWAgbWVhbnMgWl9GSU5JU0guXG4gKlxuICogU2VuZHMgaW5wdXQgZGF0YSB0byBkZWZsYXRlIHBpcGUsIGdlbmVyYXRpbmcgW1tEZWZsYXRlI29uRGF0YV1dIGNhbGxzIHdpdGhcbiAqIG5ldyBjb21wcmVzc2VkIGNodW5rcy4gUmV0dXJucyBgdHJ1ZWAgb24gc3VjY2Vzcy4gVGhlIGxhc3QgZGF0YSBibG9jayBtdXN0XG4gKiBoYXZlIGBmbHVzaF9tb2RlYCBaX0ZJTklTSCAob3IgYHRydWVgKS4gVGhhdCB3aWxsIGZsdXNoIGludGVybmFsIHBlbmRpbmdcbiAqIGJ1ZmZlcnMgYW5kIGNhbGwgW1tEZWZsYXRlI29uRW5kXV0uXG4gKlxuICogT24gZmFpbCBjYWxsIFtbRGVmbGF0ZSNvbkVuZF1dIHdpdGggZXJyb3IgY29kZSBhbmQgcmV0dXJuIGZhbHNlLlxuICpcbiAqICMjIyMjIEV4YW1wbGVcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBwdXNoKGNodW5rLCBmYWxzZSk7IC8vIHB1c2ggb25lIG9mIGRhdGEgY2h1bmtzXG4gKiAuLi5cbiAqIHB1c2goY2h1bmssIHRydWUpOyAgLy8gcHVzaCBsYXN0IGNodW5rXG4gKiBgYGBcbiAqKi9cbkRlZmxhdGUkMS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChkYXRhLCBmbHVzaF9tb2RlKSB7XG4gIGNvbnN0IHN0cm0gPSB0aGlzLnN0cm07XG4gIGNvbnN0IGNodW5rU2l6ZSA9IHRoaXMub3B0aW9ucy5jaHVua1NpemU7XG4gIGxldCBzdGF0dXMsIF9mbHVzaF9tb2RlO1xuXG4gIGlmICh0aGlzLmVuZGVkKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gIGlmIChmbHVzaF9tb2RlID09PSB+fmZsdXNoX21vZGUpIF9mbHVzaF9tb2RlID0gZmx1c2hfbW9kZTtcbiAgZWxzZSBfZmx1c2hfbW9kZSA9IGZsdXNoX21vZGUgPT09IHRydWUgPyBaX0ZJTklTSCQyIDogWl9OT19GTFVTSCQxO1xuXG4gIC8vIENvbnZlcnQgZGF0YSBpZiBuZWVkZWRcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIC8vIElmIHdlIG5lZWQgdG8gY29tcHJlc3MgdGV4dCwgY2hhbmdlIGVuY29kaW5nIHRvIHV0ZjguXG4gICAgc3RybS5pbnB1dCA9IHN0cmluZ3Muc3RyaW5nMmJ1ZihkYXRhKTtcbiAgfSBlbHNlIGlmICh0b1N0cmluZyQxLmNhbGwoZGF0YSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICBzdHJtLmlucHV0ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIH0gZWxzZSB7XG4gICAgc3RybS5pbnB1dCA9IGRhdGE7XG4gIH1cblxuICBzdHJtLm5leHRfaW4gPSAwO1xuICBzdHJtLmF2YWlsX2luID0gc3RybS5pbnB1dC5sZW5ndGg7XG5cbiAgZm9yICg7Oykge1xuICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgc3RybS5vdXRwdXQgPSBuZXcgVWludDhBcnJheShjaHVua1NpemUpO1xuICAgICAgc3RybS5uZXh0X291dCA9IDA7XG4gICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZTtcbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgYXZhaWxfb3V0ID4gNiB0byBhdm9pZCByZXBlYXRpbmcgbWFya2Vyc1xuICAgIGlmICgoX2ZsdXNoX21vZGUgPT09IFpfU1lOQ19GTFVTSCB8fCBfZmx1c2hfbW9kZSA9PT0gWl9GVUxMX0ZMVVNIKSAmJiBzdHJtLmF2YWlsX291dCA8PSA2KSB7XG4gICAgICB0aGlzLm9uRGF0YShzdHJtLm91dHB1dC5zdWJhcnJheSgwLCBzdHJtLm5leHRfb3V0KSk7XG4gICAgICBzdHJtLmF2YWlsX291dCA9IDA7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBzdGF0dXMgPSBkZWZsYXRlXzEkMi5kZWZsYXRlKHN0cm0sIF9mbHVzaF9tb2RlKTtcblxuICAgIC8vIEVuZGVkID0+IGZsdXNoIGFuZCBmaW5pc2hcbiAgICBpZiAoc3RhdHVzID09PSBaX1NUUkVBTV9FTkQkMikge1xuICAgICAgaWYgKHN0cm0ubmV4dF9vdXQgPiAwKSB7XG4gICAgICAgIHRoaXMub25EYXRhKHN0cm0ub3V0cHV0LnN1YmFycmF5KDAsIHN0cm0ubmV4dF9vdXQpKTtcbiAgICAgIH1cbiAgICAgIHN0YXR1cyA9IGRlZmxhdGVfMSQyLmRlZmxhdGVFbmQodGhpcy5zdHJtKTtcbiAgICAgIHRoaXMub25FbmQoc3RhdHVzKTtcbiAgICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIHN0YXR1cyA9PT0gWl9PSyQyO1xuICAgIH1cblxuICAgIC8vIEZsdXNoIGlmIG91dCBidWZmZXIgZnVsbFxuICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgdGhpcy5vbkRhdGEoc3RybS5vdXRwdXQpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gRmx1c2ggaWYgcmVxdWVzdGVkIGFuZCBoYXMgZGF0YVxuICAgIGlmIChfZmx1c2hfbW9kZSA+IDAgJiYgc3RybS5uZXh0X291dCA+IDApIHtcbiAgICAgIHRoaXMub25EYXRhKHN0cm0ub3V0cHV0LnN1YmFycmF5KDAsIHN0cm0ubmV4dF9vdXQpKTtcbiAgICAgIHN0cm0uYXZhaWxfb3V0ID0gMDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChzdHJtLmF2YWlsX2luID09PSAwKSBicmVhaztcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuXG4vKipcbiAqIERlZmxhdGUjb25EYXRhKGNodW5rKSAtPiBWb2lkXG4gKiAtIGNodW5rIChVaW50OEFycmF5KTogb3V0cHV0IGRhdGEuXG4gKlxuICogQnkgZGVmYXVsdCwgc3RvcmVzIGRhdGEgYmxvY2tzIGluIGBjaHVua3NbXWAgcHJvcGVydHkgYW5kIGdsdWVcbiAqIHRob3NlIGluIGBvbkVuZGAuIE92ZXJyaWRlIHRoaXMgaGFuZGxlciwgaWYgeW91IG5lZWQgYW5vdGhlciBiZWhhdmlvdXIuXG4gKiovXG5EZWZsYXRlJDEucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChjaHVuaykge1xuICB0aGlzLmNodW5rcy5wdXNoKGNodW5rKTtcbn07XG5cblxuLyoqXG4gKiBEZWZsYXRlI29uRW5kKHN0YXR1cykgLT4gVm9pZFxuICogLSBzdGF0dXMgKE51bWJlcik6IGRlZmxhdGUgc3RhdHVzLiAwIChaX09LKSBvbiBzdWNjZXNzLFxuICogICBvdGhlciBpZiBub3QuXG4gKlxuICogQ2FsbGVkIG9uY2UgYWZ0ZXIgeW91IHRlbGwgZGVmbGF0ZSB0aGF0IHRoZSBpbnB1dCBzdHJlYW0gaXNcbiAqIGNvbXBsZXRlIChaX0ZJTklTSCkuIEJ5IGRlZmF1bHQgLSBqb2luIGNvbGxlY3RlZCBjaHVua3MsXG4gKiBmcmVlIG1lbW9yeSBhbmQgZmlsbCBgcmVzdWx0c2AgLyBgZXJyYCBwcm9wZXJ0aWVzLlxuICoqL1xuRGVmbGF0ZSQxLnByb3RvdHlwZS5vbkVuZCA9IGZ1bmN0aW9uIChzdGF0dXMpIHtcbiAgLy8gT24gc3VjY2VzcyAtIGpvaW5cbiAgaWYgKHN0YXR1cyA9PT0gWl9PSyQyKSB7XG4gICAgdGhpcy5yZXN1bHQgPSBjb21tb24uZmxhdHRlbkNodW5rcyh0aGlzLmNodW5rcyk7XG4gIH1cbiAgdGhpcy5jaHVua3MgPSBbXTtcbiAgdGhpcy5lcnIgPSBzdGF0dXM7XG4gIHRoaXMubXNnID0gdGhpcy5zdHJtLm1zZztcbn07XG5cblxuLyoqXG4gKiBkZWZsYXRlKGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheVxuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5QnVmZmVyfFN0cmluZyk6IGlucHV0IGRhdGEgdG8gY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLlxuICpcbiAqIENvbXByZXNzIGBkYXRhYCB3aXRoIGRlZmxhdGUgYWxnb3JpdGhtIGFuZCBgb3B0aW9uc2AuXG4gKlxuICogU3VwcG9ydGVkIG9wdGlvbnMgYXJlOlxuICpcbiAqIC0gbGV2ZWxcbiAqIC0gd2luZG93Qml0c1xuICogLSBtZW1MZXZlbFxuICogLSBzdHJhdGVneVxuICogLSBkaWN0aW9uYXJ5XG4gKlxuICogW2h0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZF0oaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkKVxuICogZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlc2UuXG4gKlxuICogU3VnYXIgKG9wdGlvbnMpOlxuICpcbiAqIC0gYHJhd2AgKEJvb2xlYW4pIC0gc2F5IHRoYXQgd2Ugd29yayB3aXRoIHJhdyBzdHJlYW0sIGlmIHlvdSBkb24ndCB3aXNoIHRvIHNwZWNpZnlcbiAqICAgbmVnYXRpdmUgd2luZG93Qml0cyBpbXBsaWNpdGx5LlxuICpcbiAqICMjIyMjIEV4YW1wbGU6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3QgcGFrbyA9IHJlcXVpcmUoJ3Bha28nKVxuICogY29uc3QgZGF0YSA9IG5ldyBVaW50OEFycmF5KFsxLDIsMyw0LDUsNiw3LDgsOV0pO1xuICpcbiAqIGNvbnNvbGUubG9nKHBha28uZGVmbGF0ZShkYXRhKSk7XG4gKiBgYGBcbiAqKi9cbmZ1bmN0aW9uIGRlZmxhdGUkMShpbnB1dCwgb3B0aW9ucykge1xuICBjb25zdCBkZWZsYXRvciA9IG5ldyBEZWZsYXRlJDEob3B0aW9ucyk7XG5cbiAgZGVmbGF0b3IucHVzaChpbnB1dCwgdHJ1ZSk7XG5cbiAgLy8gVGhhdCB3aWxsIG5ldmVyIGhhcHBlbnMsIGlmIHlvdSBkb24ndCBjaGVhdCB3aXRoIG9wdGlvbnMgOilcbiAgaWYgKGRlZmxhdG9yLmVycikgeyB0aHJvdyBkZWZsYXRvci5tc2cgfHwgbWVzc2FnZXNbZGVmbGF0b3IuZXJyXTsgfVxuXG4gIHJldHVybiBkZWZsYXRvci5yZXN1bHQ7XG59XG5cblxuLyoqXG4gKiBkZWZsYXRlUmF3KGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheVxuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5QnVmZmVyfFN0cmluZyk6IGlucHV0IGRhdGEgdG8gY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLlxuICpcbiAqIFRoZSBzYW1lIGFzIFtbZGVmbGF0ZV1dLCBidXQgY3JlYXRlcyByYXcgZGF0YSwgd2l0aG91dCB3cmFwcGVyXG4gKiAoaGVhZGVyIGFuZCBhZGxlcjMyIGNyYykuXG4gKiovXG5mdW5jdGlvbiBkZWZsYXRlUmF3JDEoaW5wdXQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIG9wdGlvbnMucmF3ID0gdHJ1ZTtcbiAgcmV0dXJuIGRlZmxhdGUkMShpbnB1dCwgb3B0aW9ucyk7XG59XG5cblxuLyoqXG4gKiBnemlwKGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheVxuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5QnVmZmVyfFN0cmluZyk6IGlucHV0IGRhdGEgdG8gY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLlxuICpcbiAqIFRoZSBzYW1lIGFzIFtbZGVmbGF0ZV1dLCBidXQgY3JlYXRlIGd6aXAgd3JhcHBlciBpbnN0ZWFkIG9mXG4gKiBkZWZsYXRlIG9uZS5cbiAqKi9cbmZ1bmN0aW9uIGd6aXAkMShpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgb3B0aW9ucy5nemlwID0gdHJ1ZTtcbiAgcmV0dXJuIGRlZmxhdGUkMShpbnB1dCwgb3B0aW9ucyk7XG59XG5cblxudmFyIERlZmxhdGVfMSQxID0gRGVmbGF0ZSQxO1xudmFyIGRlZmxhdGVfMiA9IGRlZmxhdGUkMTtcbnZhciBkZWZsYXRlUmF3XzEkMSA9IGRlZmxhdGVSYXckMTtcbnZhciBnemlwXzEkMSA9IGd6aXAkMTtcbnZhciBjb25zdGFudHMkMSA9IGNvbnN0YW50cyQyO1xuXG52YXIgZGVmbGF0ZV8xJDEgPSB7XG5cdERlZmxhdGU6IERlZmxhdGVfMSQxLFxuXHRkZWZsYXRlOiBkZWZsYXRlXzIsXG5cdGRlZmxhdGVSYXc6IGRlZmxhdGVSYXdfMSQxLFxuXHRnemlwOiBnemlwXzEkMSxcblx0Y29uc3RhbnRzOiBjb25zdGFudHMkMVxufTtcblxuLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyXG4vLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpblxuLy9cbi8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkXG4vLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXNcbi8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsXG4vLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0XG4vLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6XG4vL1xuLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3Rcbi8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmVcbi8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlXG4vLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuXG4vLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZVxuLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuXG4vLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLlxuXG4vLyBTZWUgc3RhdGUgZGVmcyBmcm9tIGluZmxhdGUuanNcbmNvbnN0IEJBRCQxID0gMTYyMDk7ICAgICAgIC8qIGdvdCBhIGRhdGEgZXJyb3IgLS0gcmVtYWluIGhlcmUgdW50aWwgcmVzZXQgKi9cbmNvbnN0IFRZUEUkMSA9IDE2MTkxOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIHR5cGUgYml0cywgaW5jbHVkaW5nIGxhc3QtZmxhZyBiaXQgKi9cblxuLypcbiAgIERlY29kZSBsaXRlcmFsLCBsZW5ndGgsIGFuZCBkaXN0YW5jZSBjb2RlcyBhbmQgd3JpdGUgb3V0IHRoZSByZXN1bHRpbmdcbiAgIGxpdGVyYWwgYW5kIG1hdGNoIGJ5dGVzIHVudGlsIGVpdGhlciBub3QgZW5vdWdoIGlucHV0IG9yIG91dHB1dCBpc1xuICAgYXZhaWxhYmxlLCBhbiBlbmQtb2YtYmxvY2sgaXMgZW5jb3VudGVyZWQsIG9yIGEgZGF0YSBlcnJvciBpcyBlbmNvdW50ZXJlZC5cbiAgIFdoZW4gbGFyZ2UgZW5vdWdoIGlucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBhcmUgc3VwcGxpZWQgdG8gaW5mbGF0ZSgpLCBmb3JcbiAgIGV4YW1wbGUsIGEgMTZLIGlucHV0IGJ1ZmZlciBhbmQgYSA2NEsgb3V0cHV0IGJ1ZmZlciwgbW9yZSB0aGFuIDk1JSBvZiB0aGVcbiAgIGluZmxhdGUgZXhlY3V0aW9uIHRpbWUgaXMgc3BlbnQgaW4gdGhpcyByb3V0aW5lLlxuXG4gICBFbnRyeSBhc3N1bXB0aW9uczpcblxuICAgICAgICBzdGF0ZS5tb2RlID09PSBMRU5cbiAgICAgICAgc3RybS5hdmFpbF9pbiA+PSA2XG4gICAgICAgIHN0cm0uYXZhaWxfb3V0ID49IDI1OFxuICAgICAgICBzdGFydCA+PSBzdHJtLmF2YWlsX291dFxuICAgICAgICBzdGF0ZS5iaXRzIDwgOFxuXG4gICBPbiByZXR1cm4sIHN0YXRlLm1vZGUgaXMgb25lIG9mOlxuXG4gICAgICAgIExFTiAtLSByYW4gb3V0IG9mIGVub3VnaCBvdXRwdXQgc3BhY2Ugb3IgZW5vdWdoIGF2YWlsYWJsZSBpbnB1dFxuICAgICAgICBUWVBFIC0tIHJlYWNoZWQgZW5kIG9mIGJsb2NrIGNvZGUsIGluZmxhdGUoKSB0byBpbnRlcnByZXQgbmV4dCBibG9ja1xuICAgICAgICBCQUQgLS0gZXJyb3IgaW4gYmxvY2sgZGF0YVxuXG4gICBOb3RlczpcblxuICAgIC0gVGhlIG1heGltdW0gaW5wdXQgYml0cyB1c2VkIGJ5IGEgbGVuZ3RoL2Rpc3RhbmNlIHBhaXIgaXMgMTUgYml0cyBmb3IgdGhlXG4gICAgICBsZW5ndGggY29kZSwgNSBiaXRzIGZvciB0aGUgbGVuZ3RoIGV4dHJhLCAxNSBiaXRzIGZvciB0aGUgZGlzdGFuY2UgY29kZSxcbiAgICAgIGFuZCAxMyBiaXRzIGZvciB0aGUgZGlzdGFuY2UgZXh0cmEuICBUaGlzIHRvdGFscyA0OCBiaXRzLCBvciBzaXggYnl0ZXMuXG4gICAgICBUaGVyZWZvcmUgaWYgc3RybS5hdmFpbF9pbiA+PSA2LCB0aGVuIHRoZXJlIGlzIGVub3VnaCBpbnB1dCB0byBhdm9pZFxuICAgICAgY2hlY2tpbmcgZm9yIGF2YWlsYWJsZSBpbnB1dCB3aGlsZSBkZWNvZGluZy5cblxuICAgIC0gVGhlIG1heGltdW0gYnl0ZXMgdGhhdCBhIHNpbmdsZSBsZW5ndGgvZGlzdGFuY2UgcGFpciBjYW4gb3V0cHV0IGlzIDI1OFxuICAgICAgYnl0ZXMsIHdoaWNoIGlzIHRoZSBtYXhpbXVtIGxlbmd0aCB0aGF0IGNhbiBiZSBjb2RlZC4gIGluZmxhdGVfZmFzdCgpXG4gICAgICByZXF1aXJlcyBzdHJtLmF2YWlsX291dCA+PSAyNTggZm9yIGVhY2ggbG9vcCB0byBhdm9pZCBjaGVja2luZyBmb3JcbiAgICAgIG91dHB1dCBzcGFjZS5cbiAqL1xudmFyIGluZmZhc3QgPSBmdW5jdGlvbiBpbmZsYXRlX2Zhc3Qoc3RybSwgc3RhcnQpIHtcbiAgbGV0IF9pbjsgICAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0uaW5wdXQgKi9cbiAgbGV0IGxhc3Q7ICAgICAgICAgICAgICAgICAgIC8qIGhhdmUgZW5vdWdoIGlucHV0IHdoaWxlIGluIDwgbGFzdCAqL1xuICBsZXQgX291dDsgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5vdXRwdXQgKi9cbiAgbGV0IGJlZzsgICAgICAgICAgICAgICAgICAgIC8qIGluZmxhdGUoKSdzIGluaXRpYWwgc3RybS5vdXRwdXQgKi9cbiAgbGV0IGVuZDsgICAgICAgICAgICAgICAgICAgIC8qIHdoaWxlIG91dCA8IGVuZCwgZW5vdWdoIHNwYWNlIGF2YWlsYWJsZSAqL1xuLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1RcbiAgbGV0IGRtYXg7ICAgICAgICAgICAgICAgICAgIC8qIG1heGltdW0gZGlzdGFuY2UgZnJvbSB6bGliIGhlYWRlciAqL1xuLy8jZW5kaWZcbiAgbGV0IHdzaXplOyAgICAgICAgICAgICAgICAgIC8qIHdpbmRvdyBzaXplIG9yIHplcm8gaWYgbm90IHVzaW5nIHdpbmRvdyAqL1xuICBsZXQgd2hhdmU7ICAgICAgICAgICAgICAgICAgLyogdmFsaWQgYnl0ZXMgaW4gdGhlIHdpbmRvdyAqL1xuICBsZXQgd25leHQ7ICAgICAgICAgICAgICAgICAgLyogd2luZG93IHdyaXRlIGluZGV4ICovXG4gIC8vIFVzZSBgc193aW5kb3dgIGluc3RlYWQgYHdpbmRvd2AsIGF2b2lkIGNvbmZsaWN0IHdpdGggaW5zdHJ1bWVudGF0aW9uIHRvb2xzXG4gIGxldCBzX3dpbmRvdzsgICAgICAgICAgICAgICAvKiBhbGxvY2F0ZWQgc2xpZGluZyB3aW5kb3csIGlmIHdzaXplICE9IDAgKi9cbiAgbGV0IGhvbGQ7ICAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0uaG9sZCAqL1xuICBsZXQgYml0czsgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5iaXRzICovXG4gIGxldCBsY29kZTsgICAgICAgICAgICAgICAgICAvKiBsb2NhbCBzdHJtLmxlbmNvZGUgKi9cbiAgbGV0IGRjb2RlOyAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0uZGlzdGNvZGUgKi9cbiAgbGV0IGxtYXNrOyAgICAgICAgICAgICAgICAgIC8qIG1hc2sgZm9yIGZpcnN0IGxldmVsIG9mIGxlbmd0aCBjb2RlcyAqL1xuICBsZXQgZG1hc2s7ICAgICAgICAgICAgICAgICAgLyogbWFzayBmb3IgZmlyc3QgbGV2ZWwgb2YgZGlzdGFuY2UgY29kZXMgKi9cbiAgbGV0IGhlcmU7ICAgICAgICAgICAgICAgICAgIC8qIHJldHJpZXZlZCB0YWJsZSBlbnRyeSAqL1xuICBsZXQgb3A7ICAgICAgICAgICAgICAgICAgICAgLyogY29kZSBiaXRzLCBvcGVyYXRpb24sIGV4dHJhIGJpdHMsIG9yICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAgd2luZG93IHBvc2l0aW9uLCB3aW5kb3cgYnl0ZXMgdG8gY29weSAqL1xuICBsZXQgbGVuOyAgICAgICAgICAgICAgICAgICAgLyogbWF0Y2ggbGVuZ3RoLCB1bnVzZWQgYnl0ZXMgKi9cbiAgbGV0IGRpc3Q7ICAgICAgICAgICAgICAgICAgIC8qIG1hdGNoIGRpc3RhbmNlICovXG4gIGxldCBmcm9tOyAgICAgICAgICAgICAgICAgICAvKiB3aGVyZSB0byBjb3B5IG1hdGNoIGZyb20gKi9cbiAgbGV0IGZyb21fc291cmNlO1xuXG5cbiAgbGV0IGlucHV0LCBvdXRwdXQ7IC8vIEpTIHNwZWNpZmljLCBiZWNhdXNlIHdlIGhhdmUgbm8gcG9pbnRlcnNcblxuICAvKiBjb3B5IHN0YXRlIHRvIGxvY2FsIHZhcmlhYmxlcyAqL1xuICBjb25zdCBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIC8vaGVyZSA9IHN0YXRlLmhlcmU7XG4gIF9pbiA9IHN0cm0ubmV4dF9pbjtcbiAgaW5wdXQgPSBzdHJtLmlucHV0O1xuICBsYXN0ID0gX2luICsgKHN0cm0uYXZhaWxfaW4gLSA1KTtcbiAgX291dCA9IHN0cm0ubmV4dF9vdXQ7XG4gIG91dHB1dCA9IHN0cm0ub3V0cHV0O1xuICBiZWcgPSBfb3V0IC0gKHN0YXJ0IC0gc3RybS5hdmFpbF9vdXQpO1xuICBlbmQgPSBfb3V0ICsgKHN0cm0uYXZhaWxfb3V0IC0gMjU3KTtcbi8vI2lmZGVmIElORkxBVEVfU1RSSUNUXG4gIGRtYXggPSBzdGF0ZS5kbWF4O1xuLy8jZW5kaWZcbiAgd3NpemUgPSBzdGF0ZS53c2l6ZTtcbiAgd2hhdmUgPSBzdGF0ZS53aGF2ZTtcbiAgd25leHQgPSBzdGF0ZS53bmV4dDtcbiAgc193aW5kb3cgPSBzdGF0ZS53aW5kb3c7XG4gIGhvbGQgPSBzdGF0ZS5ob2xkO1xuICBiaXRzID0gc3RhdGUuYml0cztcbiAgbGNvZGUgPSBzdGF0ZS5sZW5jb2RlO1xuICBkY29kZSA9IHN0YXRlLmRpc3Rjb2RlO1xuICBsbWFzayA9ICgxIDw8IHN0YXRlLmxlbmJpdHMpIC0gMTtcbiAgZG1hc2sgPSAoMSA8PCBzdGF0ZS5kaXN0Yml0cykgLSAxO1xuXG5cbiAgLyogZGVjb2RlIGxpdGVyYWxzIGFuZCBsZW5ndGgvZGlzdGFuY2VzIHVudGlsIGVuZC1vZi1ibG9jayBvciBub3QgZW5vdWdoXG4gICAgIGlucHV0IGRhdGEgb3Igb3V0cHV0IHNwYWNlICovXG5cbiAgdG9wOlxuICBkbyB7XG4gICAgaWYgKGJpdHMgPCAxNSkge1xuICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgIGJpdHMgKz0gODtcbiAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7XG4gICAgICBiaXRzICs9IDg7XG4gICAgfVxuXG4gICAgaGVyZSA9IGxjb2RlW2hvbGQgJiBsbWFza107XG5cbiAgICBkb2xlbjpcbiAgICBmb3IgKDs7KSB7IC8vIEdvdG8gZW11bGF0aW9uXG4gICAgICBvcCA9IGhlcmUgPj4+IDI0LypoZXJlLmJpdHMqLztcbiAgICAgIGhvbGQgPj4+PSBvcDtcbiAgICAgIGJpdHMgLT0gb3A7XG4gICAgICBvcCA9IChoZXJlID4+PiAxNikgJiAweGZmLypoZXJlLm9wKi87XG4gICAgICBpZiAob3AgPT09IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxpdGVyYWwgKi9cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIGhlcmUudmFsID49IDB4MjAgJiYgaGVyZS52YWwgPCAweDdmID9cbiAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsICclYydcXG5cIiA6XG4gICAgICAgIC8vICAgICAgICBcImluZmxhdGU6ICAgICAgICAgbGl0ZXJhbCAweCUwMnhcXG5cIiwgaGVyZS52YWwpKTtcbiAgICAgICAgb3V0cHV0W19vdXQrK10gPSBoZXJlICYgMHhmZmZmLypoZXJlLnZhbCovO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAob3AgJiAxNikgeyAgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBiYXNlICovXG4gICAgICAgIGxlbiA9IGhlcmUgJiAweGZmZmYvKmhlcmUudmFsKi87XG4gICAgICAgIG9wICY9IDE1OyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBleHRyYSBiaXRzICovXG4gICAgICAgIGlmIChvcCkge1xuICAgICAgICAgIGlmIChiaXRzIDwgb3ApIHtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7XG4gICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxlbiArPSBob2xkICYgKCgxIDw8IG9wKSAtIDEpO1xuICAgICAgICAgIGhvbGQgPj4+PSBvcDtcbiAgICAgICAgICBiaXRzIC09IG9wO1xuICAgICAgICB9XG4gICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgbGVuZ3RoICV1XFxuXCIsIGxlbikpO1xuICAgICAgICBpZiAoYml0cyA8IDE1KSB7XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgaGVyZSA9IGRjb2RlW2hvbGQgJiBkbWFza107XG5cbiAgICAgICAgZG9kaXN0OlxuICAgICAgICBmb3IgKDs7KSB7IC8vIGdvdG8gZW11bGF0aW9uXG4gICAgICAgICAgb3AgPSBoZXJlID4+PiAyNC8qaGVyZS5iaXRzKi87XG4gICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgIGJpdHMgLT0gb3A7XG4gICAgICAgICAgb3AgPSAoaGVyZSA+Pj4gMTYpICYgMHhmZi8qaGVyZS5vcCovO1xuXG4gICAgICAgICAgaWYgKG9wICYgMTYpIHsgICAgICAgICAgICAgICAgICAgICAgLyogZGlzdGFuY2UgYmFzZSAqL1xuICAgICAgICAgICAgZGlzdCA9IGhlcmUgJiAweGZmZmYvKmhlcmUudmFsKi87XG4gICAgICAgICAgICBvcCAmPSAxNTsgICAgICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBleHRyYSBiaXRzICovXG4gICAgICAgICAgICBpZiAoYml0cyA8IG9wKSB7XG4gICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7XG4gICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgICAgaWYgKGJpdHMgPCBvcCkge1xuICAgICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbX2luKytdIDw8IGJpdHM7XG4gICAgICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaXN0ICs9IGhvbGQgJiAoKDEgPDwgb3ApIC0gMSk7XG4vLyNpZmRlZiBJTkZMQVRFX1NUUklDVFxuICAgICAgICAgICAgaWYgKGRpc3QgPiBkbWF4KSB7XG4gICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrJztcbiAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRCQxO1xuICAgICAgICAgICAgICBicmVhayB0b3A7XG4gICAgICAgICAgICB9XG4vLyNlbmRpZlxuICAgICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgICAgYml0cyAtPSBvcDtcbiAgICAgICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZGlzdGFuY2UgJXVcXG5cIiwgZGlzdCkpO1xuICAgICAgICAgICAgb3AgPSBfb3V0IC0gYmVnOyAgICAgICAgICAgICAgICAvKiBtYXggZGlzdGFuY2UgaW4gb3V0cHV0ICovXG4gICAgICAgICAgICBpZiAoZGlzdCA+IG9wKSB7ICAgICAgICAgICAgICAgIC8qIHNlZSBpZiBjb3B5IGZyb20gd2luZG93ICovXG4gICAgICAgICAgICAgIG9wID0gZGlzdCAtIG9wOyAgICAgICAgICAgICAgIC8qIGRpc3RhbmNlIGJhY2sgaW4gd2luZG93ICovXG4gICAgICAgICAgICAgIGlmIChvcCA+IHdoYXZlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLnNhbmUpIHtcbiAgICAgICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrJztcbiAgICAgICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQkMTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrIHRvcDtcbiAgICAgICAgICAgICAgICB9XG5cbi8vICghKSBUaGlzIGJsb2NrIGlzIGRpc2FibGVkIGluIHpsaWIgZGVmYXVsdHMsXG4vLyBkb24ndCBlbmFibGUgaXQgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5XG4vLyNpZmRlZiBJTkZMQVRFX0FMTE9XX0lOVkFMSURfRElTVEFOQ0VfVE9PRkFSX0FSUlJcbi8vICAgICAgICAgICAgICAgIGlmIChsZW4gPD0gb3AgLSB3aGF2ZSkge1xuLy8gICAgICAgICAgICAgICAgICBkbyB7XG4vLyAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSAwO1xuLy8gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLWxlbik7XG4vLyAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHRvcDtcbi8vICAgICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICAgICAgIGxlbiAtPSBvcCAtIHdoYXZlO1xuLy8gICAgICAgICAgICAgICAgZG8ge1xuLy8gICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IDA7XG4vLyAgICAgICAgICAgICAgICB9IHdoaWxlICgtLW9wID4gd2hhdmUpO1xuLy8gICAgICAgICAgICAgICAgaWYgKG9wID09PSAwKSB7XG4vLyAgICAgICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDtcbi8vICAgICAgICAgICAgICAgICAgZG8ge1xuLy8gICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107XG4vLyAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tbGVuKTtcbi8vICAgICAgICAgICAgICAgICAgY29udGludWUgdG9wO1xuLy8gICAgICAgICAgICAgICAgfVxuLy8jZW5kaWZcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBmcm9tID0gMDsgLy8gd2luZG93IGluZGV4XG4gICAgICAgICAgICAgIGZyb21fc291cmNlID0gc193aW5kb3c7XG4gICAgICAgICAgICAgIGlmICh3bmV4dCA9PT0gMCkgeyAgICAgICAgICAgLyogdmVyeSBjb21tb24gY2FzZSAqL1xuICAgICAgICAgICAgICAgIGZyb20gKz0gd3NpemUgLSBvcDtcbiAgICAgICAgICAgICAgICBpZiAob3AgPCBsZW4pIHsgICAgICAgICAvKiBzb21lIGZyb20gd2luZG93ICovXG4gICAgICAgICAgICAgICAgICBsZW4gLT0gb3A7XG4gICAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gc193aW5kb3dbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3ApO1xuICAgICAgICAgICAgICAgICAgZnJvbSA9IF9vdXQgLSBkaXN0OyAgLyogcmVzdCBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgICAgICAgICAgZnJvbV9zb3VyY2UgPSBvdXRwdXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2UgaWYgKHduZXh0IDwgb3ApIHsgICAgICAvKiB3cmFwIGFyb3VuZCB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICBmcm9tICs9IHdzaXplICsgd25leHQgLSBvcDtcbiAgICAgICAgICAgICAgICBvcCAtPSB3bmV4dDtcbiAgICAgICAgICAgICAgICBpZiAob3AgPCBsZW4pIHsgICAgICAgICAvKiBzb21lIGZyb20gZW5kIG9mIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgICAgbGVuIC09IG9wO1xuICAgICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IHNfd2luZG93W2Zyb20rK107XG4gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLW9wKTtcbiAgICAgICAgICAgICAgICAgIGZyb20gPSAwO1xuICAgICAgICAgICAgICAgICAgaWYgKHduZXh0IDwgbGVuKSB7ICAvKiBzb21lIGZyb20gc3RhcnQgb2Ygd2luZG93ICovXG4gICAgICAgICAgICAgICAgICAgIG9wID0gd25leHQ7XG4gICAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDtcbiAgICAgICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gc193aW5kb3dbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDsgICAgICAvKiByZXN0IGZyb20gb3V0cHV0ICovXG4gICAgICAgICAgICAgICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgLyogY29udGlndW91cyBpbiB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICBmcm9tICs9IHduZXh0IC0gb3A7XG4gICAgICAgICAgICAgICAgaWYgKG9wIDwgbGVuKSB7ICAgICAgICAgLyogc29tZSBmcm9tIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgICAgbGVuIC09IG9wO1xuICAgICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IHNfd2luZG93W2Zyb20rK107XG4gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLW9wKTtcbiAgICAgICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDsgIC8qIHJlc3QgZnJvbSBvdXRwdXQgKi9cbiAgICAgICAgICAgICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB3aGlsZSAobGVuID4gMikge1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIGxlbiAtPSAzO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChsZW4pIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7ICAgICAgICAgIC8qIGNvcHkgZGlyZWN0IGZyb20gb3V0cHV0ICovXG4gICAgICAgICAgICAgIGRvIHsgICAgICAgICAgICAgICAgICAgICAgICAvKiBtaW5pbXVtIGxlbmd0aCBpcyB0aHJlZSAqL1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBvdXRwdXRbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIGxlbiAtPSAzO1xuICAgICAgICAgICAgICB9IHdoaWxlIChsZW4gPiAyKTtcbiAgICAgICAgICAgICAgaWYgKGxlbikge1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107XG4gICAgICAgICAgICAgICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKChvcCAmIDY0KSA9PT0gMCkgeyAgICAgICAgICAvKiAybmQgbGV2ZWwgZGlzdGFuY2UgY29kZSAqL1xuICAgICAgICAgICAgaGVyZSA9IGRjb2RlWyhoZXJlICYgMHhmZmZmKS8qaGVyZS52YWwqLyArIChob2xkICYgKCgxIDw8IG9wKSAtIDEpKV07XG4gICAgICAgICAgICBjb250aW51ZSBkb2Rpc3Q7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSBjb2RlJztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQkMTtcbiAgICAgICAgICAgIGJyZWFrIHRvcDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhazsgLy8gbmVlZCB0byBlbXVsYXRlIGdvdG8gdmlhIFwiY29udGludWVcIlxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIGlmICgob3AgJiA2NCkgPT09IDApIHsgICAgICAgICAgICAgIC8qIDJuZCBsZXZlbCBsZW5ndGggY29kZSAqL1xuICAgICAgICBoZXJlID0gbGNvZGVbKGhlcmUgJiAweGZmZmYpLypoZXJlLnZhbCovICsgKGhvbGQgJiAoKDEgPDwgb3ApIC0gMSkpXTtcbiAgICAgICAgY29udGludWUgZG9sZW47XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChvcCAmIDMyKSB7ICAgICAgICAgICAgICAgICAgICAgLyogZW5kLW9mLWJsb2NrICovXG4gICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZW5kIG9mIGJsb2NrXFxuXCIpKTtcbiAgICAgICAgc3RhdGUubW9kZSA9IFRZUEUkMTtcbiAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZSc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQkMTtcbiAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgfVxuXG4gICAgICBicmVhazsgLy8gbmVlZCB0byBlbXVsYXRlIGdvdG8gdmlhIFwiY29udGludWVcIlxuICAgIH1cbiAgfSB3aGlsZSAoX2luIDwgbGFzdCAmJiBfb3V0IDwgZW5kKTtcblxuICAvKiByZXR1cm4gdW51c2VkIGJ5dGVzIChvbiBlbnRyeSwgYml0cyA8IDgsIHNvIGluIHdvbid0IGdvIHRvbyBmYXIgYmFjaykgKi9cbiAgbGVuID0gYml0cyA+PiAzO1xuICBfaW4gLT0gbGVuO1xuICBiaXRzIC09IGxlbiA8PCAzO1xuICBob2xkICY9ICgxIDw8IGJpdHMpIC0gMTtcblxuICAvKiB1cGRhdGUgc3RhdGUgYW5kIHJldHVybiAqL1xuICBzdHJtLm5leHRfaW4gPSBfaW47XG4gIHN0cm0ubmV4dF9vdXQgPSBfb3V0O1xuICBzdHJtLmF2YWlsX2luID0gKF9pbiA8IGxhc3QgPyA1ICsgKGxhc3QgLSBfaW4pIDogNSAtIChfaW4gLSBsYXN0KSk7XG4gIHN0cm0uYXZhaWxfb3V0ID0gKF9vdXQgPCBlbmQgPyAyNTcgKyAoZW5kIC0gX291dCkgOiAyNTcgLSAoX291dCAtIGVuZCkpO1xuICBzdGF0ZS5ob2xkID0gaG9sZDtcbiAgc3RhdGUuYml0cyA9IGJpdHM7XG4gIHJldHVybjtcbn07XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxuY29uc3QgTUFYQklUUyA9IDE1O1xuY29uc3QgRU5PVUdIX0xFTlMkMSA9IDg1MjtcbmNvbnN0IEVOT1VHSF9ESVNUUyQxID0gNTkyO1xuLy9jb25zdCBFTk9VR0ggPSAoRU5PVUdIX0xFTlMrRU5PVUdIX0RJU1RTKTtcblxuY29uc3QgQ09ERVMkMSA9IDA7XG5jb25zdCBMRU5TJDEgPSAxO1xuY29uc3QgRElTVFMkMSA9IDI7XG5cbmNvbnN0IGxiYXNlID0gbmV3IFVpbnQxNkFycmF5KFsgLyogTGVuZ3RoIGNvZGVzIDI1Ny4uMjg1IGJhc2UgKi9cbiAgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMywgMTUsIDE3LCAxOSwgMjMsIDI3LCAzMSxcbiAgMzUsIDQzLCA1MSwgNTksIDY3LCA4MywgOTksIDExNSwgMTMxLCAxNjMsIDE5NSwgMjI3LCAyNTgsIDAsIDBcbl0pO1xuXG5jb25zdCBsZXh0ID0gbmV3IFVpbnQ4QXJyYXkoWyAvKiBMZW5ndGggY29kZXMgMjU3Li4yODUgZXh0cmEgKi9cbiAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNywgMTcsIDE3LCAxNywgMTgsIDE4LCAxOCwgMTgsXG4gIDE5LCAxOSwgMTksIDE5LCAyMCwgMjAsIDIwLCAyMCwgMjEsIDIxLCAyMSwgMjEsIDE2LCA3MiwgNzhcbl0pO1xuXG5jb25zdCBkYmFzZSA9IG5ldyBVaW50MTZBcnJheShbIC8qIERpc3RhbmNlIGNvZGVzIDAuLjI5IGJhc2UgKi9cbiAgMSwgMiwgMywgNCwgNSwgNywgOSwgMTMsIDE3LCAyNSwgMzMsIDQ5LCA2NSwgOTcsIDEyOSwgMTkzLFxuICAyNTcsIDM4NSwgNTEzLCA3NjksIDEwMjUsIDE1MzcsIDIwNDksIDMwNzMsIDQwOTcsIDYxNDUsXG4gIDgxOTMsIDEyMjg5LCAxNjM4NSwgMjQ1NzcsIDAsIDBcbl0pO1xuXG5jb25zdCBkZXh0ID0gbmV3IFVpbnQ4QXJyYXkoWyAvKiBEaXN0YW5jZSBjb2RlcyAwLi4yOSBleHRyYSAqL1xuICAxNiwgMTYsIDE2LCAxNiwgMTcsIDE3LCAxOCwgMTgsIDE5LCAxOSwgMjAsIDIwLCAyMSwgMjEsIDIyLCAyMixcbiAgMjMsIDIzLCAyNCwgMjQsIDI1LCAyNSwgMjYsIDI2LCAyNywgMjcsXG4gIDI4LCAyOCwgMjksIDI5LCA2NCwgNjRcbl0pO1xuXG5jb25zdCBpbmZsYXRlX3RhYmxlID0gKHR5cGUsIGxlbnMsIGxlbnNfaW5kZXgsIGNvZGVzLCB0YWJsZSwgdGFibGVfaW5kZXgsIHdvcmssIG9wdHMpID0+XG57XG4gIGNvbnN0IGJpdHMgPSBvcHRzLmJpdHM7XG4gICAgICAvL2hlcmUgPSBvcHRzLmhlcmU7IC8qIHRhYmxlIGVudHJ5IGZvciBkdXBsaWNhdGlvbiAqL1xuXG4gIGxldCBsZW4gPSAwOyAgICAgICAgICAgICAgIC8qIGEgY29kZSdzIGxlbmd0aCBpbiBiaXRzICovXG4gIGxldCBzeW0gPSAwOyAgICAgICAgICAgICAgIC8qIGluZGV4IG9mIGNvZGUgc3ltYm9scyAqL1xuICBsZXQgbWluID0gMCwgbWF4ID0gMDsgICAgICAgICAgLyogbWluaW11bSBhbmQgbWF4aW11bSBjb2RlIGxlbmd0aHMgKi9cbiAgbGV0IHJvb3QgPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGluZGV4IGJpdHMgZm9yIHJvb3QgdGFibGUgKi9cbiAgbGV0IGN1cnIgPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGluZGV4IGJpdHMgZm9yIGN1cnJlbnQgdGFibGUgKi9cbiAgbGV0IGRyb3AgPSAwOyAgICAgICAgICAgICAgLyogY29kZSBiaXRzIHRvIGRyb3AgZm9yIHN1Yi10YWJsZSAqL1xuICBsZXQgbGVmdCA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBwcmVmaXggY29kZXMgYXZhaWxhYmxlICovXG4gIGxldCB1c2VkID0gMDsgICAgICAgICAgICAgIC8qIGNvZGUgZW50cmllcyBpbiB0YWJsZSB1c2VkICovXG4gIGxldCBodWZmID0gMDsgICAgICAgICAgICAgIC8qIEh1ZmZtYW4gY29kZSAqL1xuICBsZXQgaW5jcjsgICAgICAgICAgICAgIC8qIGZvciBpbmNyZW1lbnRpbmcgY29kZSwgaW5kZXggKi9cbiAgbGV0IGZpbGw7ICAgICAgICAgICAgICAvKiBpbmRleCBmb3IgcmVwbGljYXRpbmcgZW50cmllcyAqL1xuICBsZXQgbG93OyAgICAgICAgICAgICAgIC8qIGxvdyBiaXRzIGZvciBjdXJyZW50IHJvb3QgZW50cnkgKi9cbiAgbGV0IG1hc2s7ICAgICAgICAgICAgICAvKiBtYXNrIGZvciBsb3cgcm9vdCBiaXRzICovXG4gIGxldCBuZXh0OyAgICAgICAgICAgICAvKiBuZXh0IGF2YWlsYWJsZSBzcGFjZSBpbiB0YWJsZSAqL1xuICBsZXQgYmFzZSA9IG51bGw7ICAgICAvKiBiYXNlIHZhbHVlIHRhYmxlIHRvIHVzZSAqL1xuLy8gIGxldCBzaG9leHRyYTsgICAgLyogZXh0cmEgYml0cyB0YWJsZSB0byB1c2UgKi9cbiAgbGV0IG1hdGNoOyAgICAgICAgICAgICAgICAgIC8qIHVzZSBiYXNlIGFuZCBleHRyYSBmb3Igc3ltYm9sID49IG1hdGNoICovXG4gIGNvbnN0IGNvdW50ID0gbmV3IFVpbnQxNkFycmF5KE1BWEJJVFMgKyAxKTsgLy9bTUFYQklUUysxXTsgICAgLyogbnVtYmVyIG9mIGNvZGVzIG9mIGVhY2ggbGVuZ3RoICovXG4gIGNvbnN0IG9mZnMgPSBuZXcgVWludDE2QXJyYXkoTUFYQklUUyArIDEpOyAvL1tNQVhCSVRTKzFdOyAgICAgLyogb2Zmc2V0cyBpbiB0YWJsZSBmb3IgZWFjaCBsZW5ndGggKi9cbiAgbGV0IGV4dHJhID0gbnVsbDtcblxuICBsZXQgaGVyZV9iaXRzLCBoZXJlX29wLCBoZXJlX3ZhbDtcblxuICAvKlxuICAgUHJvY2VzcyBhIHNldCBvZiBjb2RlIGxlbmd0aHMgdG8gY3JlYXRlIGEgY2Fub25pY2FsIEh1ZmZtYW4gY29kZS4gIFRoZVxuICAgY29kZSBsZW5ndGhzIGFyZSBsZW5zWzAuLmNvZGVzLTFdLiAgRWFjaCBsZW5ndGggY29ycmVzcG9uZHMgdG8gdGhlXG4gICBzeW1ib2xzIDAuLmNvZGVzLTEuICBUaGUgSHVmZm1hbiBjb2RlIGlzIGdlbmVyYXRlZCBieSBmaXJzdCBzb3J0aW5nIHRoZVxuICAgc3ltYm9scyBieSBsZW5ndGggZnJvbSBzaG9ydCB0byBsb25nLCBhbmQgcmV0YWluaW5nIHRoZSBzeW1ib2wgb3JkZXJcbiAgIGZvciBjb2RlcyB3aXRoIGVxdWFsIGxlbmd0aHMuICBUaGVuIHRoZSBjb2RlIHN0YXJ0cyB3aXRoIGFsbCB6ZXJvIGJpdHNcbiAgIGZvciB0aGUgZmlyc3QgY29kZSBvZiB0aGUgc2hvcnRlc3QgbGVuZ3RoLCBhbmQgdGhlIGNvZGVzIGFyZSBpbnRlZ2VyXG4gICBpbmNyZW1lbnRzIGZvciB0aGUgc2FtZSBsZW5ndGgsIGFuZCB6ZXJvcyBhcmUgYXBwZW5kZWQgYXMgdGhlIGxlbmd0aFxuICAgaW5jcmVhc2VzLiAgRm9yIHRoZSBkZWZsYXRlIGZvcm1hdCwgdGhlc2UgYml0cyBhcmUgc3RvcmVkIGJhY2t3YXJkc1xuICAgZnJvbSB0aGVpciBtb3JlIG5hdHVyYWwgaW50ZWdlciBpbmNyZW1lbnQgb3JkZXJpbmcsIGFuZCBzbyB3aGVuIHRoZVxuICAgZGVjb2RpbmcgdGFibGVzIGFyZSBidWlsdCBpbiB0aGUgbGFyZ2UgbG9vcCBiZWxvdywgdGhlIGludGVnZXIgY29kZXNcbiAgIGFyZSBpbmNyZW1lbnRlZCBiYWNrd2FyZHMuXG5cbiAgIFRoaXMgcm91dGluZSBhc3N1bWVzLCBidXQgZG9lcyBub3QgY2hlY2ssIHRoYXQgYWxsIG9mIHRoZSBlbnRyaWVzIGluXG4gICBsZW5zW10gYXJlIGluIHRoZSByYW5nZSAwLi5NQVhCSVRTLiAgVGhlIGNhbGxlciBtdXN0IGFzc3VyZSB0aGlzLlxuICAgMS4uTUFYQklUUyBpcyBpbnRlcnByZXRlZCBhcyB0aGF0IGNvZGUgbGVuZ3RoLiAgemVybyBtZWFucyB0aGF0IHRoYXRcbiAgIHN5bWJvbCBkb2VzIG5vdCBvY2N1ciBpbiB0aGlzIGNvZGUuXG5cbiAgIFRoZSBjb2RlcyBhcmUgc29ydGVkIGJ5IGNvbXB1dGluZyBhIGNvdW50IG9mIGNvZGVzIGZvciBlYWNoIGxlbmd0aCxcbiAgIGNyZWF0aW5nIGZyb20gdGhhdCBhIHRhYmxlIG9mIHN0YXJ0aW5nIGluZGljZXMgZm9yIGVhY2ggbGVuZ3RoIGluIHRoZVxuICAgc29ydGVkIHRhYmxlLCBhbmQgdGhlbiBlbnRlcmluZyB0aGUgc3ltYm9scyBpbiBvcmRlciBpbiB0aGUgc29ydGVkXG4gICB0YWJsZS4gIFRoZSBzb3J0ZWQgdGFibGUgaXMgd29ya1tdLCB3aXRoIHRoYXQgc3BhY2UgYmVpbmcgcHJvdmlkZWQgYnlcbiAgIHRoZSBjYWxsZXIuXG5cbiAgIFRoZSBsZW5ndGggY291bnRzIGFyZSB1c2VkIGZvciBvdGhlciBwdXJwb3NlcyBhcyB3ZWxsLCBpLmUuIGZpbmRpbmdcbiAgIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGxlbmd0aCBjb2RlcywgZGV0ZXJtaW5pbmcgaWYgdGhlcmUgYXJlIGFueVxuICAgY29kZXMgYXQgYWxsLCBjaGVja2luZyBmb3IgYSB2YWxpZCBzZXQgb2YgbGVuZ3RocywgYW5kIGxvb2tpbmcgYWhlYWRcbiAgIGF0IGxlbmd0aCBjb3VudHMgdG8gZGV0ZXJtaW5lIHN1Yi10YWJsZSBzaXplcyB3aGVuIGJ1aWxkaW5nIHRoZVxuICAgZGVjb2RpbmcgdGFibGVzLlxuICAgKi9cblxuICAvKiBhY2N1bXVsYXRlIGxlbmd0aHMgZm9yIGNvZGVzIChhc3N1bWVzIGxlbnNbXSBhbGwgaW4gMC4uTUFYQklUUykgKi9cbiAgZm9yIChsZW4gPSAwOyBsZW4gPD0gTUFYQklUUzsgbGVuKyspIHtcbiAgICBjb3VudFtsZW5dID0gMDtcbiAgfVxuICBmb3IgKHN5bSA9IDA7IHN5bSA8IGNvZGVzOyBzeW0rKykge1xuICAgIGNvdW50W2xlbnNbbGVuc19pbmRleCArIHN5bV1dKys7XG4gIH1cblxuICAvKiBib3VuZCBjb2RlIGxlbmd0aHMsIGZvcmNlIHJvb3QgdG8gYmUgd2l0aGluIGNvZGUgbGVuZ3RocyAqL1xuICByb290ID0gYml0cztcbiAgZm9yIChtYXggPSBNQVhCSVRTOyBtYXggPj0gMTsgbWF4LS0pIHtcbiAgICBpZiAoY291bnRbbWF4XSAhPT0gMCkgeyBicmVhazsgfVxuICB9XG4gIGlmIChyb290ID4gbWF4KSB7XG4gICAgcm9vdCA9IG1heDtcbiAgfVxuICBpZiAobWF4ID09PSAwKSB7ICAgICAgICAgICAgICAgICAgICAgLyogbm8gc3ltYm9scyB0byBjb2RlIGF0IGFsbCAqL1xuICAgIC8vdGFibGUub3Bbb3B0cy50YWJsZV9pbmRleF0gPSA2NDsgIC8vaGVyZS5vcCA9ICh2YXIgY2hhcik2NDsgICAgLyogaW52YWxpZCBjb2RlIG1hcmtlciAqL1xuICAgIC8vdGFibGUuYml0c1tvcHRzLnRhYmxlX2luZGV4XSA9IDE7ICAgLy9oZXJlLmJpdHMgPSAodmFyIGNoYXIpMTtcbiAgICAvL3RhYmxlLnZhbFtvcHRzLnRhYmxlX2luZGV4KytdID0gMDsgICAvL2hlcmUudmFsID0gKHZhciBzaG9ydCkwO1xuICAgIHRhYmxlW3RhYmxlX2luZGV4KytdID0gKDEgPDwgMjQpIHwgKDY0IDw8IDE2KSB8IDA7XG5cblxuICAgIC8vdGFibGUub3Bbb3B0cy50YWJsZV9pbmRleF0gPSA2NDtcbiAgICAvL3RhYmxlLmJpdHNbb3B0cy50YWJsZV9pbmRleF0gPSAxO1xuICAgIC8vdGFibGUudmFsW29wdHMudGFibGVfaW5kZXgrK10gPSAwO1xuICAgIHRhYmxlW3RhYmxlX2luZGV4KytdID0gKDEgPDwgMjQpIHwgKDY0IDw8IDE2KSB8IDA7XG5cbiAgICBvcHRzLmJpdHMgPSAxO1xuICAgIHJldHVybiAwOyAgICAgLyogbm8gc3ltYm9scywgYnV0IHdhaXQgZm9yIGRlY29kaW5nIHRvIHJlcG9ydCBlcnJvciAqL1xuICB9XG4gIGZvciAobWluID0gMTsgbWluIDwgbWF4OyBtaW4rKykge1xuICAgIGlmIChjb3VudFttaW5dICE9PSAwKSB7IGJyZWFrOyB9XG4gIH1cbiAgaWYgKHJvb3QgPCBtaW4pIHtcbiAgICByb290ID0gbWluO1xuICB9XG5cbiAgLyogY2hlY2sgZm9yIGFuIG92ZXItc3Vic2NyaWJlZCBvciBpbmNvbXBsZXRlIHNldCBvZiBsZW5ndGhzICovXG4gIGxlZnQgPSAxO1xuICBmb3IgKGxlbiA9IDE7IGxlbiA8PSBNQVhCSVRTOyBsZW4rKykge1xuICAgIGxlZnQgPDw9IDE7XG4gICAgbGVmdCAtPSBjb3VudFtsZW5dO1xuICAgIGlmIChsZWZ0IDwgMCkge1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH0gICAgICAgIC8qIG92ZXItc3Vic2NyaWJlZCAqL1xuICB9XG4gIGlmIChsZWZ0ID4gMCAmJiAodHlwZSA9PT0gQ09ERVMkMSB8fCBtYXggIT09IDEpKSB7XG4gICAgcmV0dXJuIC0xOyAgICAgICAgICAgICAgICAgICAgICAvKiBpbmNvbXBsZXRlIHNldCAqL1xuICB9XG5cbiAgLyogZ2VuZXJhdGUgb2Zmc2V0cyBpbnRvIHN5bWJvbCB0YWJsZSBmb3IgZWFjaCBsZW5ndGggZm9yIHNvcnRpbmcgKi9cbiAgb2Zmc1sxXSA9IDA7XG4gIGZvciAobGVuID0gMTsgbGVuIDwgTUFYQklUUzsgbGVuKyspIHtcbiAgICBvZmZzW2xlbiArIDFdID0gb2Zmc1tsZW5dICsgY291bnRbbGVuXTtcbiAgfVxuXG4gIC8qIHNvcnQgc3ltYm9scyBieSBsZW5ndGgsIGJ5IHN5bWJvbCBvcmRlciB3aXRoaW4gZWFjaCBsZW5ndGggKi9cbiAgZm9yIChzeW0gPSAwOyBzeW0gPCBjb2Rlczsgc3ltKyspIHtcbiAgICBpZiAobGVuc1tsZW5zX2luZGV4ICsgc3ltXSAhPT0gMCkge1xuICAgICAgd29ya1tvZmZzW2xlbnNbbGVuc19pbmRleCArIHN5bV1dKytdID0gc3ltO1xuICAgIH1cbiAgfVxuXG4gIC8qXG4gICBDcmVhdGUgYW5kIGZpbGwgaW4gZGVjb2RpbmcgdGFibGVzLiAgSW4gdGhpcyBsb29wLCB0aGUgdGFibGUgYmVpbmdcbiAgIGZpbGxlZCBpcyBhdCBuZXh0IGFuZCBoYXMgY3VyciBpbmRleCBiaXRzLiAgVGhlIGNvZGUgYmVpbmcgdXNlZCBpcyBodWZmXG4gICB3aXRoIGxlbmd0aCBsZW4uICBUaGF0IGNvZGUgaXMgY29udmVydGVkIHRvIGFuIGluZGV4IGJ5IGRyb3BwaW5nIGRyb3BcbiAgIGJpdHMgb2ZmIG9mIHRoZSBib3R0b20uICBGb3IgY29kZXMgd2hlcmUgbGVuIGlzIGxlc3MgdGhhbiBkcm9wICsgY3VycixcbiAgIHRob3NlIHRvcCBkcm9wICsgY3VyciAtIGxlbiBiaXRzIGFyZSBpbmNyZW1lbnRlZCB0aHJvdWdoIGFsbCB2YWx1ZXMgdG9cbiAgIGZpbGwgdGhlIHRhYmxlIHdpdGggcmVwbGljYXRlZCBlbnRyaWVzLlxuXG4gICByb290IGlzIHRoZSBudW1iZXIgb2YgaW5kZXggYml0cyBmb3IgdGhlIHJvb3QgdGFibGUuICBXaGVuIGxlbiBleGNlZWRzXG4gICByb290LCBzdWItdGFibGVzIGFyZSBjcmVhdGVkIHBvaW50ZWQgdG8gYnkgdGhlIHJvb3QgZW50cnkgd2l0aCBhbiBpbmRleFxuICAgb2YgdGhlIGxvdyByb290IGJpdHMgb2YgaHVmZi4gIFRoaXMgaXMgc2F2ZWQgaW4gbG93IHRvIGNoZWNrIGZvciB3aGVuIGFcbiAgIG5ldyBzdWItdGFibGUgc2hvdWxkIGJlIHN0YXJ0ZWQuICBkcm9wIGlzIHplcm8gd2hlbiB0aGUgcm9vdCB0YWJsZSBpc1xuICAgYmVpbmcgZmlsbGVkLCBhbmQgZHJvcCBpcyByb290IHdoZW4gc3ViLXRhYmxlcyBhcmUgYmVpbmcgZmlsbGVkLlxuXG4gICBXaGVuIGEgbmV3IHN1Yi10YWJsZSBpcyBuZWVkZWQsIGl0IGlzIG5lY2Vzc2FyeSB0byBsb29rIGFoZWFkIGluIHRoZVxuICAgY29kZSBsZW5ndGhzIHRvIGRldGVybWluZSB3aGF0IHNpemUgc3ViLXRhYmxlIGlzIG5lZWRlZC4gIFRoZSBsZW5ndGhcbiAgIGNvdW50cyBhcmUgdXNlZCBmb3IgdGhpcywgYW5kIHNvIGNvdW50W10gaXMgZGVjcmVtZW50ZWQgYXMgY29kZXMgYXJlXG4gICBlbnRlcmVkIGluIHRoZSB0YWJsZXMuXG5cbiAgIHVzZWQga2VlcHMgdHJhY2sgb2YgaG93IG1hbnkgdGFibGUgZW50cmllcyBoYXZlIGJlZW4gYWxsb2NhdGVkIGZyb20gdGhlXG4gICBwcm92aWRlZCAqdGFibGUgc3BhY2UuICBJdCBpcyBjaGVja2VkIGZvciBMRU5TIGFuZCBESVNUIHRhYmxlcyBhZ2FpbnN0XG4gICB0aGUgY29uc3RhbnRzIEVOT1VHSF9MRU5TIGFuZCBFTk9VR0hfRElTVFMgdG8gZ3VhcmQgYWdhaW5zdCBjaGFuZ2VzIGluXG4gICB0aGUgaW5pdGlhbCByb290IHRhYmxlIHNpemUgY29uc3RhbnRzLiAgU2VlIHRoZSBjb21tZW50cyBpbiBpbmZ0cmVlcy5oXG4gICBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cblxuICAgc3ltIGluY3JlbWVudHMgdGhyb3VnaCBhbGwgc3ltYm9scywgYW5kIHRoZSBsb29wIHRlcm1pbmF0ZXMgd2hlblxuICAgYWxsIGNvZGVzIG9mIGxlbmd0aCBtYXgsIGkuZS4gYWxsIGNvZGVzLCBoYXZlIGJlZW4gcHJvY2Vzc2VkLiAgVGhpc1xuICAgcm91dGluZSBwZXJtaXRzIGluY29tcGxldGUgY29kZXMsIHNvIGFub3RoZXIgbG9vcCBhZnRlciB0aGlzIG9uZSBmaWxsc1xuICAgaW4gdGhlIHJlc3Qgb2YgdGhlIGRlY29kaW5nIHRhYmxlcyB3aXRoIGludmFsaWQgY29kZSBtYXJrZXJzLlxuICAgKi9cblxuICAvKiBzZXQgdXAgZm9yIGNvZGUgdHlwZSAqL1xuICAvLyBwb29yIG1hbiBvcHRpbWl6YXRpb24gLSB1c2UgaWYtZWxzZSBpbnN0ZWFkIG9mIHN3aXRjaCxcbiAgLy8gdG8gYXZvaWQgZGVvcHRzIGluIG9sZCB2OFxuICBpZiAodHlwZSA9PT0gQ09ERVMkMSkge1xuICAgIGJhc2UgPSBleHRyYSA9IHdvcms7ICAgIC8qIGR1bW15IHZhbHVlLS1ub3QgdXNlZCAqL1xuICAgIG1hdGNoID0gMjA7XG5cbiAgfSBlbHNlIGlmICh0eXBlID09PSBMRU5TJDEpIHtcbiAgICBiYXNlID0gbGJhc2U7XG4gICAgZXh0cmEgPSBsZXh0O1xuICAgIG1hdGNoID0gMjU3O1xuXG4gIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAvKiBESVNUUyAqL1xuICAgIGJhc2UgPSBkYmFzZTtcbiAgICBleHRyYSA9IGRleHQ7XG4gICAgbWF0Y2ggPSAwO1xuICB9XG5cbiAgLyogaW5pdGlhbGl6ZSBvcHRzIGZvciBsb29wICovXG4gIGh1ZmYgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBzdGFydGluZyBjb2RlICovXG4gIHN5bSA9IDA7ICAgICAgICAgICAgICAgICAgICAvKiBzdGFydGluZyBjb2RlIHN5bWJvbCAqL1xuICBsZW4gPSBtaW47ICAgICAgICAgICAgICAgICAgLyogc3RhcnRpbmcgY29kZSBsZW5ndGggKi9cbiAgbmV4dCA9IHRhYmxlX2luZGV4OyAgICAgICAgICAgICAgLyogY3VycmVudCB0YWJsZSB0byBmaWxsIGluICovXG4gIGN1cnIgPSByb290OyAgICAgICAgICAgICAgICAvKiBjdXJyZW50IHRhYmxlIGluZGV4IGJpdHMgKi9cbiAgZHJvcCA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIGN1cnJlbnQgYml0cyB0byBkcm9wIGZyb20gY29kZSBmb3IgaW5kZXggKi9cbiAgbG93ID0gLTE7ICAgICAgICAgICAgICAgICAgIC8qIHRyaWdnZXIgbmV3IHN1Yi10YWJsZSB3aGVuIGxlbiA+IHJvb3QgKi9cbiAgdXNlZCA9IDEgPDwgcm9vdDsgICAgICAgICAgLyogdXNlIHJvb3QgdGFibGUgZW50cmllcyAqL1xuICBtYXNrID0gdXNlZCAtIDE7ICAgICAgICAgICAgLyogbWFzayBmb3IgY29tcGFyaW5nIGxvdyAqL1xuXG4gIC8qIGNoZWNrIGF2YWlsYWJsZSB0YWJsZSBzcGFjZSAqL1xuICBpZiAoKHR5cGUgPT09IExFTlMkMSAmJiB1c2VkID4gRU5PVUdIX0xFTlMkMSkgfHxcbiAgICAodHlwZSA9PT0gRElTVFMkMSAmJiB1c2VkID4gRU5PVUdIX0RJU1RTJDEpKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICAvKiBwcm9jZXNzIGFsbCBjb2RlcyBhbmQgbWFrZSB0YWJsZSBlbnRyaWVzICovXG4gIGZvciAoOzspIHtcbiAgICAvKiBjcmVhdGUgdGFibGUgZW50cnkgKi9cbiAgICBoZXJlX2JpdHMgPSBsZW4gLSBkcm9wO1xuICAgIGlmICh3b3JrW3N5bV0gKyAxIDwgbWF0Y2gpIHtcbiAgICAgIGhlcmVfb3AgPSAwO1xuICAgICAgaGVyZV92YWwgPSB3b3JrW3N5bV07XG4gICAgfVxuICAgIGVsc2UgaWYgKHdvcmtbc3ltXSA+PSBtYXRjaCkge1xuICAgICAgaGVyZV9vcCA9IGV4dHJhW3dvcmtbc3ltXSAtIG1hdGNoXTtcbiAgICAgIGhlcmVfdmFsID0gYmFzZVt3b3JrW3N5bV0gLSBtYXRjaF07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaGVyZV9vcCA9IDMyICsgNjQ7ICAgICAgICAgLyogZW5kIG9mIGJsb2NrICovXG4gICAgICBoZXJlX3ZhbCA9IDA7XG4gICAgfVxuXG4gICAgLyogcmVwbGljYXRlIGZvciB0aG9zZSBpbmRpY2VzIHdpdGggbG93IGxlbiBiaXRzIGVxdWFsIHRvIGh1ZmYgKi9cbiAgICBpbmNyID0gMSA8PCAobGVuIC0gZHJvcCk7XG4gICAgZmlsbCA9IDEgPDwgY3VycjtcbiAgICBtaW4gPSBmaWxsOyAgICAgICAgICAgICAgICAgLyogc2F2ZSBvZmZzZXQgdG8gbmV4dCB0YWJsZSAqL1xuICAgIGRvIHtcbiAgICAgIGZpbGwgLT0gaW5jcjtcbiAgICAgIHRhYmxlW25leHQgKyAoaHVmZiA+PiBkcm9wKSArIGZpbGxdID0gKGhlcmVfYml0cyA8PCAyNCkgfCAoaGVyZV9vcCA8PCAxNikgfCBoZXJlX3ZhbCB8MDtcbiAgICB9IHdoaWxlIChmaWxsICE9PSAwKTtcblxuICAgIC8qIGJhY2t3YXJkcyBpbmNyZW1lbnQgdGhlIGxlbi1iaXQgY29kZSBodWZmICovXG4gICAgaW5jciA9IDEgPDwgKGxlbiAtIDEpO1xuICAgIHdoaWxlIChodWZmICYgaW5jcikge1xuICAgICAgaW5jciA+Pj0gMTtcbiAgICB9XG4gICAgaWYgKGluY3IgIT09IDApIHtcbiAgICAgIGh1ZmYgJj0gaW5jciAtIDE7XG4gICAgICBodWZmICs9IGluY3I7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh1ZmYgPSAwO1xuICAgIH1cblxuICAgIC8qIGdvIHRvIG5leHQgc3ltYm9sLCB1cGRhdGUgY291bnQsIGxlbiAqL1xuICAgIHN5bSsrO1xuICAgIGlmICgtLWNvdW50W2xlbl0gPT09IDApIHtcbiAgICAgIGlmIChsZW4gPT09IG1heCkgeyBicmVhazsgfVxuICAgICAgbGVuID0gbGVuc1tsZW5zX2luZGV4ICsgd29ya1tzeW1dXTtcbiAgICB9XG5cbiAgICAvKiBjcmVhdGUgbmV3IHN1Yi10YWJsZSBpZiBuZWVkZWQgKi9cbiAgICBpZiAobGVuID4gcm9vdCAmJiAoaHVmZiAmIG1hc2spICE9PSBsb3cpIHtcbiAgICAgIC8qIGlmIGZpcnN0IHRpbWUsIHRyYW5zaXRpb24gdG8gc3ViLXRhYmxlcyAqL1xuICAgICAgaWYgKGRyb3AgPT09IDApIHtcbiAgICAgICAgZHJvcCA9IHJvb3Q7XG4gICAgICB9XG5cbiAgICAgIC8qIGluY3JlbWVudCBwYXN0IGxhc3QgdGFibGUgKi9cbiAgICAgIG5leHQgKz0gbWluOyAgICAgICAgICAgIC8qIGhlcmUgbWluIGlzIDEgPDwgY3VyciAqL1xuXG4gICAgICAvKiBkZXRlcm1pbmUgbGVuZ3RoIG9mIG5leHQgdGFibGUgKi9cbiAgICAgIGN1cnIgPSBsZW4gLSBkcm9wO1xuICAgICAgbGVmdCA9IDEgPDwgY3VycjtcbiAgICAgIHdoaWxlIChjdXJyICsgZHJvcCA8IG1heCkge1xuICAgICAgICBsZWZ0IC09IGNvdW50W2N1cnIgKyBkcm9wXTtcbiAgICAgICAgaWYgKGxlZnQgPD0gMCkgeyBicmVhazsgfVxuICAgICAgICBjdXJyKys7XG4gICAgICAgIGxlZnQgPDw9IDE7XG4gICAgICB9XG5cbiAgICAgIC8qIGNoZWNrIGZvciBlbm91Z2ggc3BhY2UgKi9cbiAgICAgIHVzZWQgKz0gMSA8PCBjdXJyO1xuICAgICAgaWYgKCh0eXBlID09PSBMRU5TJDEgJiYgdXNlZCA+IEVOT1VHSF9MRU5TJDEpIHx8XG4gICAgICAgICh0eXBlID09PSBESVNUUyQxICYmIHVzZWQgPiBFTk9VR0hfRElTVFMkMSkpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG5cbiAgICAgIC8qIHBvaW50IGVudHJ5IGluIHJvb3QgdGFibGUgdG8gc3ViLXRhYmxlICovXG4gICAgICBsb3cgPSBodWZmICYgbWFzaztcbiAgICAgIC8qdGFibGUub3BbbG93XSA9IGN1cnI7XG4gICAgICB0YWJsZS5iaXRzW2xvd10gPSByb290O1xuICAgICAgdGFibGUudmFsW2xvd10gPSBuZXh0IC0gb3B0cy50YWJsZV9pbmRleDsqL1xuICAgICAgdGFibGVbbG93XSA9IChyb290IDw8IDI0KSB8IChjdXJyIDw8IDE2KSB8IChuZXh0IC0gdGFibGVfaW5kZXgpIHwwO1xuICAgIH1cbiAgfVxuXG4gIC8qIGZpbGwgaW4gcmVtYWluaW5nIHRhYmxlIGVudHJ5IGlmIGNvZGUgaXMgaW5jb21wbGV0ZSAoZ3VhcmFudGVlZCB0byBoYXZlXG4gICBhdCBtb3N0IG9uZSByZW1haW5pbmcgZW50cnksIHNpbmNlIGlmIHRoZSBjb2RlIGlzIGluY29tcGxldGUsIHRoZVxuICAgbWF4aW11bSBjb2RlIGxlbmd0aCB0aGF0IHdhcyBhbGxvd2VkIHRvIGdldCB0aGlzIGZhciBpcyBvbmUgYml0KSAqL1xuICBpZiAoaHVmZiAhPT0gMCkge1xuICAgIC8vdGFibGUub3BbbmV4dCArIGh1ZmZdID0gNjQ7ICAgICAgICAgICAgLyogaW52YWxpZCBjb2RlIG1hcmtlciAqL1xuICAgIC8vdGFibGUuYml0c1tuZXh0ICsgaHVmZl0gPSBsZW4gLSBkcm9wO1xuICAgIC8vdGFibGUudmFsW25leHQgKyBodWZmXSA9IDA7XG4gICAgdGFibGVbbmV4dCArIGh1ZmZdID0gKChsZW4gLSBkcm9wKSA8PCAyNCkgfCAoNjQgPDwgMTYpIHwwO1xuICB9XG5cbiAgLyogc2V0IHJldHVybiBwYXJhbWV0ZXJzICovXG4gIC8vb3B0cy50YWJsZV9pbmRleCArPSB1c2VkO1xuICBvcHRzLmJpdHMgPSByb290O1xuICByZXR1cm4gMDtcbn07XG5cblxudmFyIGluZnRyZWVzID0gaW5mbGF0ZV90YWJsZTtcblxuLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyXG4vLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpblxuLy9cbi8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkXG4vLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXNcbi8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsXG4vLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0XG4vLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6XG4vL1xuLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3Rcbi8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmVcbi8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlXG4vLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuXG4vLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZVxuLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuXG4vLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLlxuXG5cblxuXG5cblxuY29uc3QgQ09ERVMgPSAwO1xuY29uc3QgTEVOUyA9IDE7XG5jb25zdCBESVNUUyA9IDI7XG5cbi8qIFB1YmxpYyBjb25zdGFudHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5jb25zdCB7XG4gIFpfRklOSVNIOiBaX0ZJTklTSCQxLCBaX0JMT0NLLCBaX1RSRUVTLFxuICBaX09LOiBaX09LJDEsIFpfU1RSRUFNX0VORDogWl9TVFJFQU1fRU5EJDEsIFpfTkVFRF9ESUNUOiBaX05FRURfRElDVCQxLCBaX1NUUkVBTV9FUlJPUjogWl9TVFJFQU1fRVJST1IkMSwgWl9EQVRBX0VSUk9SOiBaX0RBVEFfRVJST1IkMSwgWl9NRU1fRVJST1I6IFpfTUVNX0VSUk9SJDEsIFpfQlVGX0VSUk9SLFxuICBaX0RFRkxBVEVEXG59ID0gY29uc3RhbnRzJDI7XG5cblxuLyogU1RBVEVTID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuY29uc3QgICAgSEVBRCA9IDE2MTgwOyAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBtYWdpYyBoZWFkZXIgKi9cbmNvbnN0ICAgIEZMQUdTID0gMTYxODE7ICAgICAgLyogaTogd2FpdGluZyBmb3IgbWV0aG9kIGFuZCBmbGFncyAoZ3ppcCkgKi9cbmNvbnN0ICAgIFRJTUUgPSAxNjE4MjsgICAgICAgLyogaTogd2FpdGluZyBmb3IgbW9kaWZpY2F0aW9uIHRpbWUgKGd6aXApICovXG5jb25zdCAgICBPUyA9IDE2MTgzOyAgICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGV4dHJhIGZsYWdzIGFuZCBvcGVyYXRpbmcgc3lzdGVtIChnemlwKSAqL1xuY29uc3QgICAgRVhMRU4gPSAxNjE4NDsgICAgICAvKiBpOiB3YWl0aW5nIGZvciBleHRyYSBsZW5ndGggKGd6aXApICovXG5jb25zdCAgICBFWFRSQSA9IDE2MTg1OyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGV4dHJhIGJ5dGVzIChnemlwKSAqL1xuY29uc3QgICAgTkFNRSA9IDE2MTg2OyAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBlbmQgb2YgZmlsZSBuYW1lIChnemlwKSAqL1xuY29uc3QgICAgQ09NTUVOVCA9IDE2MTg3OyAgICAvKiBpOiB3YWl0aW5nIGZvciBlbmQgb2YgY29tbWVudCAoZ3ppcCkgKi9cbmNvbnN0ICAgIEhDUkMgPSAxNjE4ODsgICAgICAgLyogaTogd2FpdGluZyBmb3IgaGVhZGVyIGNyYyAoZ3ppcCkgKi9cbmNvbnN0ICAgIERJQ1RJRCA9IDE2MTg5OyAgICAvKiBpOiB3YWl0aW5nIGZvciBkaWN0aW9uYXJ5IGNoZWNrIHZhbHVlICovXG5jb25zdCAgICBESUNUID0gMTYxOTA7ICAgICAgLyogd2FpdGluZyBmb3IgaW5mbGF0ZVNldERpY3Rpb25hcnkoKSBjYWxsICovXG5jb25zdCAgICAgICAgVFlQRSA9IDE2MTkxOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIHR5cGUgYml0cywgaW5jbHVkaW5nIGxhc3QtZmxhZyBiaXQgKi9cbmNvbnN0ICAgICAgICBUWVBFRE8gPSAxNjE5MjsgICAgLyogaTogc2FtZSwgYnV0IHNraXAgY2hlY2sgdG8gZXhpdCBpbmZsYXRlIG9uIG5ldyBibG9jayAqL1xuY29uc3QgICAgICAgIFNUT1JFRCA9IDE2MTkzOyAgICAvKiBpOiB3YWl0aW5nIGZvciBzdG9yZWQgc2l6ZSAobGVuZ3RoIGFuZCBjb21wbGVtZW50KSAqL1xuY29uc3QgICAgICAgIENPUFlfID0gMTYxOTQ7ICAgICAvKiBpL286IHNhbWUgYXMgQ09QWSBiZWxvdywgYnV0IG9ubHkgZmlyc3QgdGltZSBpbiAqL1xuY29uc3QgICAgICAgIENPUFkgPSAxNjE5NTsgICAgICAvKiBpL286IHdhaXRpbmcgZm9yIGlucHV0IG9yIG91dHB1dCB0byBjb3B5IHN0b3JlZCBibG9jayAqL1xuY29uc3QgICAgICAgIFRBQkxFID0gMTYxOTY7ICAgICAvKiBpOiB3YWl0aW5nIGZvciBkeW5hbWljIGJsb2NrIHRhYmxlIGxlbmd0aHMgKi9cbmNvbnN0ICAgICAgICBMRU5MRU5TID0gMTYxOTc7ICAgLyogaTogd2FpdGluZyBmb3IgY29kZSBsZW5ndGggY29kZSBsZW5ndGhzICovXG5jb25zdCAgICAgICAgQ09ERUxFTlMgPSAxNjE5ODsgIC8qIGk6IHdhaXRpbmcgZm9yIGxlbmd0aC9saXQgYW5kIGRpc3RhbmNlIGNvZGUgbGVuZ3RocyAqL1xuY29uc3QgICAgICAgICAgICBMRU5fID0gMTYxOTk7ICAgICAgLyogaTogc2FtZSBhcyBMRU4gYmVsb3csIGJ1dCBvbmx5IGZpcnN0IHRpbWUgaW4gKi9cbmNvbnN0ICAgICAgICAgICAgTEVOID0gMTYyMDA7ICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGxlbmd0aC9saXQvZW9iIGNvZGUgKi9cbmNvbnN0ICAgICAgICAgICAgTEVORVhUID0gMTYyMDE7ICAgIC8qIGk6IHdhaXRpbmcgZm9yIGxlbmd0aCBleHRyYSBiaXRzICovXG5jb25zdCAgICAgICAgICAgIERJU1QgPSAxNjIwMjsgICAgICAvKiBpOiB3YWl0aW5nIGZvciBkaXN0YW5jZSBjb2RlICovXG5jb25zdCAgICAgICAgICAgIERJU1RFWFQgPSAxNjIwMzsgICAvKiBpOiB3YWl0aW5nIGZvciBkaXN0YW5jZSBleHRyYSBiaXRzICovXG5jb25zdCAgICAgICAgICAgIE1BVENIID0gMTYyMDQ7ICAgICAvKiBvOiB3YWl0aW5nIGZvciBvdXRwdXQgc3BhY2UgdG8gY29weSBzdHJpbmcgKi9cbmNvbnN0ICAgICAgICAgICAgTElUID0gMTYyMDU7ICAgICAgIC8qIG86IHdhaXRpbmcgZm9yIG91dHB1dCBzcGFjZSB0byB3cml0ZSBsaXRlcmFsICovXG5jb25zdCAgICBDSEVDSyA9IDE2MjA2OyAgICAgLyogaTogd2FpdGluZyBmb3IgMzItYml0IGNoZWNrIHZhbHVlICovXG5jb25zdCAgICBMRU5HVEggPSAxNjIwNzsgICAgLyogaTogd2FpdGluZyBmb3IgMzItYml0IGxlbmd0aCAoZ3ppcCkgKi9cbmNvbnN0ICAgIERPTkUgPSAxNjIwODsgICAgICAvKiBmaW5pc2hlZCBjaGVjaywgZG9uZSAtLSByZW1haW4gaGVyZSB1bnRpbCByZXNldCAqL1xuY29uc3QgICAgQkFEID0gMTYyMDk7ICAgICAgIC8qIGdvdCBhIGRhdGEgZXJyb3IgLS0gcmVtYWluIGhlcmUgdW50aWwgcmVzZXQgKi9cbmNvbnN0ICAgIE1FTSA9IDE2MjEwOyAgICAgICAvKiBnb3QgYW4gaW5mbGF0ZSgpIG1lbW9yeSBlcnJvciAtLSByZW1haW4gaGVyZSB1bnRpbCByZXNldCAqL1xuY29uc3QgICAgU1lOQyA9IDE2MjExOyAgICAgIC8qIGxvb2tpbmcgZm9yIHN5bmNocm9uaXphdGlvbiBieXRlcyB0byByZXN0YXJ0IGluZmxhdGUoKSAqL1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cblxuY29uc3QgRU5PVUdIX0xFTlMgPSA4NTI7XG5jb25zdCBFTk9VR0hfRElTVFMgPSA1OTI7XG4vL2NvbnN0IEVOT1VHSCA9ICAoRU5PVUdIX0xFTlMrRU5PVUdIX0RJU1RTKTtcblxuY29uc3QgTUFYX1dCSVRTID0gMTU7XG4vKiAzMksgTFo3NyB3aW5kb3cgKi9cbmNvbnN0IERFRl9XQklUUyA9IE1BWF9XQklUUztcblxuXG5jb25zdCB6c3dhcDMyID0gKHEpID0+IHtcblxuICByZXR1cm4gICgoKHEgPj4+IDI0KSAmIDB4ZmYpICtcbiAgICAgICAgICAoKHEgPj4+IDgpICYgMHhmZjAwKSArXG4gICAgICAgICAgKChxICYgMHhmZjAwKSA8PCA4KSArXG4gICAgICAgICAgKChxICYgMHhmZikgPDwgMjQpKTtcbn07XG5cblxuZnVuY3Rpb24gSW5mbGF0ZVN0YXRlKCkge1xuICB0aGlzLnN0cm0gPSBudWxsOyAgICAgICAgICAgLyogcG9pbnRlciBiYWNrIHRvIHRoaXMgemxpYiBzdHJlYW0gKi9cbiAgdGhpcy5tb2RlID0gMDsgICAgICAgICAgICAgIC8qIGN1cnJlbnQgaW5mbGF0ZSBtb2RlICovXG4gIHRoaXMubGFzdCA9IGZhbHNlOyAgICAgICAgICAvKiB0cnVlIGlmIHByb2Nlc3NpbmcgbGFzdCBibG9jayAqL1xuICB0aGlzLndyYXAgPSAwOyAgICAgICAgICAgICAgLyogYml0IDAgdHJ1ZSBmb3IgemxpYiwgYml0IDEgdHJ1ZSBmb3IgZ3ppcCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpdCAyIHRydWUgdG8gdmFsaWRhdGUgY2hlY2sgdmFsdWUgKi9cbiAgdGhpcy5oYXZlZGljdCA9IGZhbHNlOyAgICAgIC8qIHRydWUgaWYgZGljdGlvbmFyeSBwcm92aWRlZCAqL1xuICB0aGlzLmZsYWdzID0gMDsgICAgICAgICAgICAgLyogZ3ppcCBoZWFkZXIgbWV0aG9kIGFuZCBmbGFncyAoMCBpZiB6bGliKSwgb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0xIGlmIHJhdyBvciBubyBoZWFkZXIgeWV0ICovXG4gIHRoaXMuZG1heCA9IDA7ICAgICAgICAgICAgICAvKiB6bGliIGhlYWRlciBtYXggZGlzdGFuY2UgKElORkxBVEVfU1RSSUNUKSAqL1xuICB0aGlzLmNoZWNrID0gMDsgICAgICAgICAgICAgLyogcHJvdGVjdGVkIGNvcHkgb2YgY2hlY2sgdmFsdWUgKi9cbiAgdGhpcy50b3RhbCA9IDA7ICAgICAgICAgICAgIC8qIHByb3RlY3RlZCBjb3B5IG9mIG91dHB1dCBjb3VudCAqL1xuICAvLyBUT0RPOiBtYXkgYmUge31cbiAgdGhpcy5oZWFkID0gbnVsbDsgICAgICAgICAgIC8qIHdoZXJlIHRvIHNhdmUgZ3ppcCBoZWFkZXIgaW5mb3JtYXRpb24gKi9cblxuICAvKiBzbGlkaW5nIHdpbmRvdyAqL1xuICB0aGlzLndiaXRzID0gMDsgICAgICAgICAgICAgLyogbG9nIGJhc2UgMiBvZiByZXF1ZXN0ZWQgd2luZG93IHNpemUgKi9cbiAgdGhpcy53c2l6ZSA9IDA7ICAgICAgICAgICAgIC8qIHdpbmRvdyBzaXplIG9yIHplcm8gaWYgbm90IHVzaW5nIHdpbmRvdyAqL1xuICB0aGlzLndoYXZlID0gMDsgICAgICAgICAgICAgLyogdmFsaWQgYnl0ZXMgaW4gdGhlIHdpbmRvdyAqL1xuICB0aGlzLnduZXh0ID0gMDsgICAgICAgICAgICAgLyogd2luZG93IHdyaXRlIGluZGV4ICovXG4gIHRoaXMud2luZG93ID0gbnVsbDsgICAgICAgICAvKiBhbGxvY2F0ZWQgc2xpZGluZyB3aW5kb3csIGlmIG5lZWRlZCAqL1xuXG4gIC8qIGJpdCBhY2N1bXVsYXRvciAqL1xuICB0aGlzLmhvbGQgPSAwOyAgICAgICAgICAgICAgLyogaW5wdXQgYml0IGFjY3VtdWxhdG9yICovXG4gIHRoaXMuYml0cyA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgYml0cyBpbiBcImluXCIgKi9cblxuICAvKiBmb3Igc3RyaW5nIGFuZCBzdG9yZWQgYmxvY2sgY29weWluZyAqL1xuICB0aGlzLmxlbmd0aCA9IDA7ICAgICAgICAgICAgLyogbGl0ZXJhbCBvciBsZW5ndGggb2YgZGF0YSB0byBjb3B5ICovXG4gIHRoaXMub2Zmc2V0ID0gMDsgICAgICAgICAgICAvKiBkaXN0YW5jZSBiYWNrIHRvIGNvcHkgc3RyaW5nIGZyb20gKi9cblxuICAvKiBmb3IgdGFibGUgYW5kIGNvZGUgZGVjb2RpbmcgKi9cbiAgdGhpcy5leHRyYSA9IDA7ICAgICAgICAgICAgIC8qIGV4dHJhIGJpdHMgbmVlZGVkICovXG5cbiAgLyogZml4ZWQgYW5kIGR5bmFtaWMgY29kZSB0YWJsZXMgKi9cbiAgdGhpcy5sZW5jb2RlID0gbnVsbDsgICAgICAgICAgLyogc3RhcnRpbmcgdGFibGUgZm9yIGxlbmd0aC9saXRlcmFsIGNvZGVzICovXG4gIHRoaXMuZGlzdGNvZGUgPSBudWxsOyAgICAgICAgIC8qIHN0YXJ0aW5nIHRhYmxlIGZvciBkaXN0YW5jZSBjb2RlcyAqL1xuICB0aGlzLmxlbmJpdHMgPSAwOyAgICAgICAgICAgLyogaW5kZXggYml0cyBmb3IgbGVuY29kZSAqL1xuICB0aGlzLmRpc3RiaXRzID0gMDsgICAgICAgICAgLyogaW5kZXggYml0cyBmb3IgZGlzdGNvZGUgKi9cblxuICAvKiBkeW5hbWljIHRhYmxlIGJ1aWxkaW5nICovXG4gIHRoaXMubmNvZGUgPSAwOyAgICAgICAgICAgICAvKiBudW1iZXIgb2YgY29kZSBsZW5ndGggY29kZSBsZW5ndGhzICovXG4gIHRoaXMubmxlbiA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgbGVuZ3RoIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLm5kaXN0ID0gMDsgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGRpc3RhbmNlIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLmhhdmUgPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGNvZGUgbGVuZ3RocyBpbiBsZW5zW10gKi9cbiAgdGhpcy5uZXh0ID0gbnVsbDsgICAgICAgICAgICAgIC8qIG5leHQgYXZhaWxhYmxlIHNwYWNlIGluIGNvZGVzW10gKi9cblxuICB0aGlzLmxlbnMgPSBuZXcgVWludDE2QXJyYXkoMzIwKTsgLyogdGVtcG9yYXJ5IHN0b3JhZ2UgZm9yIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLndvcmsgPSBuZXcgVWludDE2QXJyYXkoMjg4KTsgLyogd29yayBhcmVhIGZvciBjb2RlIHRhYmxlIGJ1aWxkaW5nICovXG5cbiAgLypcbiAgIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSBwb2ludGVycyBpbiBqcywgd2UgdXNlIGxlbmNvZGUgYW5kIGRpc3Rjb2RlIGRpcmVjdGx5XG4gICBhcyBidWZmZXJzIHNvIHdlIGRvbid0IG5lZWQgY29kZXNcbiAgKi9cbiAgLy90aGlzLmNvZGVzID0gbmV3IEludDMyQXJyYXkoRU5PVUdIKTsgICAgICAgLyogc3BhY2UgZm9yIGNvZGUgdGFibGVzICovXG4gIHRoaXMubGVuZHluID0gbnVsbDsgICAgICAgICAgICAgIC8qIGR5bmFtaWMgdGFibGUgZm9yIGxlbmd0aC9saXRlcmFsIGNvZGVzIChKUyBzcGVjaWZpYykgKi9cbiAgdGhpcy5kaXN0ZHluID0gbnVsbDsgICAgICAgICAgICAgLyogZHluYW1pYyB0YWJsZSBmb3IgZGlzdGFuY2UgY29kZXMgKEpTIHNwZWNpZmljKSAqL1xuICB0aGlzLnNhbmUgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBpZiBmYWxzZSwgYWxsb3cgaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyICovXG4gIHRoaXMuYmFjayA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIGJpdHMgYmFjayBvZiBsYXN0IHVucHJvY2Vzc2VkIGxlbmd0aC9saXQgKi9cbiAgdGhpcy53YXMgPSAwOyAgICAgICAgICAgICAgICAgICAgLyogaW5pdGlhbCBsZW5ndGggb2YgbWF0Y2ggKi9cbn1cblxuXG5jb25zdCBpbmZsYXRlU3RhdGVDaGVjayA9IChzdHJtKSA9PiB7XG5cbiAgaWYgKCFzdHJtKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgY29uc3Qgc3RhdGUgPSBzdHJtLnN0YXRlO1xuICBpZiAoIXN0YXRlIHx8IHN0YXRlLnN0cm0gIT09IHN0cm0gfHxcbiAgICBzdGF0ZS5tb2RlIDwgSEVBRCB8fCBzdGF0ZS5tb2RlID4gU1lOQykge1xuICAgIHJldHVybiAxO1xuICB9XG4gIHJldHVybiAwO1xufTtcblxuXG5jb25zdCBpbmZsYXRlUmVzZXRLZWVwID0gKHN0cm0pID0+IHtcblxuICBpZiAoaW5mbGF0ZVN0YXRlQ2hlY2soc3RybSkpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDE7IH1cbiAgY29uc3Qgc3RhdGUgPSBzdHJtLnN0YXRlO1xuICBzdHJtLnRvdGFsX2luID0gc3RybS50b3RhbF9vdXQgPSBzdGF0ZS50b3RhbCA9IDA7XG4gIHN0cm0ubXNnID0gJyc7IC8qWl9OVUxMKi9cbiAgaWYgKHN0YXRlLndyYXApIHsgICAgICAgLyogdG8gc3VwcG9ydCBpbGwtY29uY2VpdmVkIEphdmEgdGVzdCBzdWl0ZSAqL1xuICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS53cmFwICYgMTtcbiAgfVxuICBzdGF0ZS5tb2RlID0gSEVBRDtcbiAgc3RhdGUubGFzdCA9IDA7XG4gIHN0YXRlLmhhdmVkaWN0ID0gMDtcbiAgc3RhdGUuZmxhZ3MgPSAtMTtcbiAgc3RhdGUuZG1heCA9IDMyNzY4O1xuICBzdGF0ZS5oZWFkID0gbnVsbC8qWl9OVUxMKi87XG4gIHN0YXRlLmhvbGQgPSAwO1xuICBzdGF0ZS5iaXRzID0gMDtcbiAgLy9zdGF0ZS5sZW5jb2RlID0gc3RhdGUuZGlzdGNvZGUgPSBzdGF0ZS5uZXh0ID0gc3RhdGUuY29kZXM7XG4gIHN0YXRlLmxlbmNvZGUgPSBzdGF0ZS5sZW5keW4gPSBuZXcgSW50MzJBcnJheShFTk9VR0hfTEVOUyk7XG4gIHN0YXRlLmRpc3Rjb2RlID0gc3RhdGUuZGlzdGR5biA9IG5ldyBJbnQzMkFycmF5KEVOT1VHSF9ESVNUUyk7XG5cbiAgc3RhdGUuc2FuZSA9IDE7XG4gIHN0YXRlLmJhY2sgPSAtMTtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiByZXNldFxcblwiKSk7XG4gIHJldHVybiBaX09LJDE7XG59O1xuXG5cbmNvbnN0IGluZmxhdGVSZXNldCA9IChzdHJtKSA9PiB7XG5cbiAgaWYgKGluZmxhdGVTdGF0ZUNoZWNrKHN0cm0pKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUiQxOyB9XG4gIGNvbnN0IHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgc3RhdGUud3NpemUgPSAwO1xuICBzdGF0ZS53aGF2ZSA9IDA7XG4gIHN0YXRlLnduZXh0ID0gMDtcbiAgcmV0dXJuIGluZmxhdGVSZXNldEtlZXAoc3RybSk7XG5cbn07XG5cblxuY29uc3QgaW5mbGF0ZVJlc2V0MiA9IChzdHJtLCB3aW5kb3dCaXRzKSA9PiB7XG4gIGxldCB3cmFwO1xuXG4gIC8qIGdldCB0aGUgc3RhdGUgKi9cbiAgaWYgKGluZmxhdGVTdGF0ZUNoZWNrKHN0cm0pKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUiQxOyB9XG4gIGNvbnN0IHN0YXRlID0gc3RybS5zdGF0ZTtcblxuICAvKiBleHRyYWN0IHdyYXAgcmVxdWVzdCBmcm9tIHdpbmRvd0JpdHMgcGFyYW1ldGVyICovXG4gIGlmICh3aW5kb3dCaXRzIDwgMCkge1xuICAgIHdyYXAgPSAwO1xuICAgIHdpbmRvd0JpdHMgPSAtd2luZG93Qml0cztcbiAgfVxuICBlbHNlIHtcbiAgICB3cmFwID0gKHdpbmRvd0JpdHMgPj4gNCkgKyA1O1xuICAgIGlmICh3aW5kb3dCaXRzIDwgNDgpIHtcbiAgICAgIHdpbmRvd0JpdHMgJj0gMTU7XG4gICAgfVxuICB9XG5cbiAgLyogc2V0IG51bWJlciBvZiB3aW5kb3cgYml0cywgZnJlZSB3aW5kb3cgaWYgZGlmZmVyZW50ICovXG4gIGlmICh3aW5kb3dCaXRzICYmICh3aW5kb3dCaXRzIDwgOCB8fCB3aW5kb3dCaXRzID4gMTUpKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDE7XG4gIH1cbiAgaWYgKHN0YXRlLndpbmRvdyAhPT0gbnVsbCAmJiBzdGF0ZS53Yml0cyAhPT0gd2luZG93Qml0cykge1xuICAgIHN0YXRlLndpbmRvdyA9IG51bGw7XG4gIH1cblxuICAvKiB1cGRhdGUgc3RhdGUgYW5kIHJlc2V0IHRoZSByZXN0IG9mIGl0ICovXG4gIHN0YXRlLndyYXAgPSB3cmFwO1xuICBzdGF0ZS53Yml0cyA9IHdpbmRvd0JpdHM7XG4gIHJldHVybiBpbmZsYXRlUmVzZXQoc3RybSk7XG59O1xuXG5cbmNvbnN0IGluZmxhdGVJbml0MiA9IChzdHJtLCB3aW5kb3dCaXRzKSA9PiB7XG5cbiAgaWYgKCFzdHJtKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUiQxOyB9XG4gIC8vc3RybS5tc2cgPSBaX05VTEw7ICAgICAgICAgICAgICAgICAvKiBpbiBjYXNlIHdlIHJldHVybiBhbiBlcnJvciAqL1xuXG4gIGNvbnN0IHN0YXRlID0gbmV3IEluZmxhdGVTdGF0ZSgpO1xuXG4gIC8vaWYgKHN0YXRlID09PSBaX05VTEwpIHJldHVybiBaX01FTV9FUlJPUjtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiBhbGxvY2F0ZWRcXG5cIikpO1xuICBzdHJtLnN0YXRlID0gc3RhdGU7XG4gIHN0YXRlLnN0cm0gPSBzdHJtO1xuICBzdGF0ZS53aW5kb3cgPSBudWxsLypaX05VTEwqLztcbiAgc3RhdGUubW9kZSA9IEhFQUQ7ICAgICAvKiB0byBwYXNzIHN0YXRlIHRlc3QgaW4gaW5mbGF0ZVJlc2V0MigpICovXG4gIGNvbnN0IHJldCA9IGluZmxhdGVSZXNldDIoc3RybSwgd2luZG93Qml0cyk7XG4gIGlmIChyZXQgIT09IFpfT0skMSkge1xuICAgIHN0cm0uc3RhdGUgPSBudWxsLypaX05VTEwqLztcbiAgfVxuICByZXR1cm4gcmV0O1xufTtcblxuXG5jb25zdCBpbmZsYXRlSW5pdCA9IChzdHJtKSA9PiB7XG5cbiAgcmV0dXJuIGluZmxhdGVJbml0MihzdHJtLCBERUZfV0JJVFMpO1xufTtcblxuXG4vKlxuIFJldHVybiBzdGF0ZSB3aXRoIGxlbmd0aCBhbmQgZGlzdGFuY2UgZGVjb2RpbmcgdGFibGVzIGFuZCBpbmRleCBzaXplcyBzZXQgdG9cbiBmaXhlZCBjb2RlIGRlY29kaW5nLiAgTm9ybWFsbHkgdGhpcyByZXR1cm5zIGZpeGVkIHRhYmxlcyBmcm9tIGluZmZpeGVkLmguXG4gSWYgQlVJTERGSVhFRCBpcyBkZWZpbmVkLCB0aGVuIGluc3RlYWQgdGhpcyByb3V0aW5lIGJ1aWxkcyB0aGUgdGFibGVzIHRoZVxuIGZpcnN0IHRpbWUgaXQncyBjYWxsZWQsIGFuZCByZXR1cm5zIHRob3NlIHRhYmxlcyB0aGUgZmlyc3QgdGltZSBhbmRcbiB0aGVyZWFmdGVyLiAgVGhpcyByZWR1Y2VzIHRoZSBzaXplIG9mIHRoZSBjb2RlIGJ5IGFib3V0IDJLIGJ5dGVzLCBpblxuIGV4Y2hhbmdlIGZvciBhIGxpdHRsZSBleGVjdXRpb24gdGltZS4gIEhvd2V2ZXIsIEJVSUxERklYRUQgc2hvdWxkIG5vdCBiZVxuIHVzZWQgZm9yIHRocmVhZGVkIGFwcGxpY2F0aW9ucywgc2luY2UgdGhlIHJld3JpdGluZyBvZiB0aGUgdGFibGVzIGFuZCB2aXJnaW5cbiBtYXkgbm90IGJlIHRocmVhZC1zYWZlLlxuICovXG5sZXQgdmlyZ2luID0gdHJ1ZTtcblxubGV0IGxlbmZpeCwgZGlzdGZpeDsgLy8gV2UgaGF2ZSBubyBwb2ludGVycyBpbiBKUywgc28ga2VlcCB0YWJsZXMgc2VwYXJhdGVcblxuXG5jb25zdCBmaXhlZHRhYmxlcyA9IChzdGF0ZSkgPT4ge1xuXG4gIC8qIGJ1aWxkIGZpeGVkIGh1ZmZtYW4gdGFibGVzIGlmIGZpcnN0IGNhbGwgKG1heSBub3QgYmUgdGhyZWFkIHNhZmUpICovXG4gIGlmICh2aXJnaW4pIHtcbiAgICBsZW5maXggPSBuZXcgSW50MzJBcnJheSg1MTIpO1xuICAgIGRpc3RmaXggPSBuZXcgSW50MzJBcnJheSgzMik7XG5cbiAgICAvKiBsaXRlcmFsL2xlbmd0aCB0YWJsZSAqL1xuICAgIGxldCBzeW0gPSAwO1xuICAgIHdoaWxlIChzeW0gPCAxNDQpIHsgc3RhdGUubGVuc1tzeW0rK10gPSA4OyB9XG4gICAgd2hpbGUgKHN5bSA8IDI1NikgeyBzdGF0ZS5sZW5zW3N5bSsrXSA9IDk7IH1cbiAgICB3aGlsZSAoc3ltIDwgMjgwKSB7IHN0YXRlLmxlbnNbc3ltKytdID0gNzsgfVxuICAgIHdoaWxlIChzeW0gPCAyODgpIHsgc3RhdGUubGVuc1tzeW0rK10gPSA4OyB9XG5cbiAgICBpbmZ0cmVlcyhMRU5TLCAgc3RhdGUubGVucywgMCwgMjg4LCBsZW5maXgsICAgMCwgc3RhdGUud29yaywgeyBiaXRzOiA5IH0pO1xuXG4gICAgLyogZGlzdGFuY2UgdGFibGUgKi9cbiAgICBzeW0gPSAwO1xuICAgIHdoaWxlIChzeW0gPCAzMikgeyBzdGF0ZS5sZW5zW3N5bSsrXSA9IDU7IH1cblxuICAgIGluZnRyZWVzKERJU1RTLCBzdGF0ZS5sZW5zLCAwLCAzMiwgICBkaXN0Zml4LCAwLCBzdGF0ZS53b3JrLCB7IGJpdHM6IDUgfSk7XG5cbiAgICAvKiBkbyB0aGlzIGp1c3Qgb25jZSAqL1xuICAgIHZpcmdpbiA9IGZhbHNlO1xuICB9XG5cbiAgc3RhdGUubGVuY29kZSA9IGxlbmZpeDtcbiAgc3RhdGUubGVuYml0cyA9IDk7XG4gIHN0YXRlLmRpc3Rjb2RlID0gZGlzdGZpeDtcbiAgc3RhdGUuZGlzdGJpdHMgPSA1O1xufTtcblxuXG4vKlxuIFVwZGF0ZSB0aGUgd2luZG93IHdpdGggdGhlIGxhc3Qgd3NpemUgKG5vcm1hbGx5IDMySykgYnl0ZXMgd3JpdHRlbiBiZWZvcmVcbiByZXR1cm5pbmcuICBJZiB3aW5kb3cgZG9lcyBub3QgZXhpc3QgeWV0LCBjcmVhdGUgaXQuICBUaGlzIGlzIG9ubHkgY2FsbGVkXG4gd2hlbiBhIHdpbmRvdyBpcyBhbHJlYWR5IGluIHVzZSwgb3Igd2hlbiBvdXRwdXQgaGFzIGJlZW4gd3JpdHRlbiBkdXJpbmcgdGhpc1xuIGluZmxhdGUgY2FsbCwgYnV0IHRoZSBlbmQgb2YgdGhlIGRlZmxhdGUgc3RyZWFtIGhhcyBub3QgYmVlbiByZWFjaGVkIHlldC5cbiBJdCBpcyBhbHNvIGNhbGxlZCB0byBjcmVhdGUgYSB3aW5kb3cgZm9yIGRpY3Rpb25hcnkgZGF0YSB3aGVuIGEgZGljdGlvbmFyeVxuIGlzIGxvYWRlZC5cblxuIFByb3ZpZGluZyBvdXRwdXQgYnVmZmVycyBsYXJnZXIgdGhhbiAzMksgdG8gaW5mbGF0ZSgpIHNob3VsZCBwcm92aWRlIGEgc3BlZWRcbiBhZHZhbnRhZ2UsIHNpbmNlIG9ubHkgdGhlIGxhc3QgMzJLIG9mIG91dHB1dCBpcyBjb3BpZWQgdG8gdGhlIHNsaWRpbmcgd2luZG93XG4gdXBvbiByZXR1cm4gZnJvbSBpbmZsYXRlKCksIGFuZCBzaW5jZSBhbGwgZGlzdGFuY2VzIGFmdGVyIHRoZSBmaXJzdCAzMksgb2ZcbiBvdXRwdXQgd2lsbCBmYWxsIGluIHRoZSBvdXRwdXQgZGF0YSwgbWFraW5nIG1hdGNoIGNvcGllcyBzaW1wbGVyIGFuZCBmYXN0ZXIuXG4gVGhlIGFkdmFudGFnZSBtYXkgYmUgZGVwZW5kZW50IG9uIHRoZSBzaXplIG9mIHRoZSBwcm9jZXNzb3IncyBkYXRhIGNhY2hlcy5cbiAqL1xuY29uc3QgdXBkYXRld2luZG93ID0gKHN0cm0sIHNyYywgZW5kLCBjb3B5KSA9PiB7XG5cbiAgbGV0IGRpc3Q7XG4gIGNvbnN0IHN0YXRlID0gc3RybS5zdGF0ZTtcblxuICAvKiBpZiBpdCBoYXNuJ3QgYmVlbiBkb25lIGFscmVhZHksIGFsbG9jYXRlIHNwYWNlIGZvciB0aGUgd2luZG93ICovXG4gIGlmIChzdGF0ZS53aW5kb3cgPT09IG51bGwpIHtcbiAgICBzdGF0ZS53c2l6ZSA9IDEgPDwgc3RhdGUud2JpdHM7XG4gICAgc3RhdGUud25leHQgPSAwO1xuICAgIHN0YXRlLndoYXZlID0gMDtcblxuICAgIHN0YXRlLndpbmRvdyA9IG5ldyBVaW50OEFycmF5KHN0YXRlLndzaXplKTtcbiAgfVxuXG4gIC8qIGNvcHkgc3RhdGUtPndzaXplIG9yIGxlc3Mgb3V0cHV0IGJ5dGVzIGludG8gdGhlIGNpcmN1bGFyIHdpbmRvdyAqL1xuICBpZiAoY29weSA+PSBzdGF0ZS53c2l6ZSkge1xuICAgIHN0YXRlLndpbmRvdy5zZXQoc3JjLnN1YmFycmF5KGVuZCAtIHN0YXRlLndzaXplLCBlbmQpLCAwKTtcbiAgICBzdGF0ZS53bmV4dCA9IDA7XG4gICAgc3RhdGUud2hhdmUgPSBzdGF0ZS53c2l6ZTtcbiAgfVxuICBlbHNlIHtcbiAgICBkaXN0ID0gc3RhdGUud3NpemUgLSBzdGF0ZS53bmV4dDtcbiAgICBpZiAoZGlzdCA+IGNvcHkpIHtcbiAgICAgIGRpc3QgPSBjb3B5O1xuICAgIH1cbiAgICAvL3ptZW1jcHkoc3RhdGUtPndpbmRvdyArIHN0YXRlLT53bmV4dCwgZW5kIC0gY29weSwgZGlzdCk7XG4gICAgc3RhdGUud2luZG93LnNldChzcmMuc3ViYXJyYXkoZW5kIC0gY29weSwgZW5kIC0gY29weSArIGRpc3QpLCBzdGF0ZS53bmV4dCk7XG4gICAgY29weSAtPSBkaXN0O1xuICAgIGlmIChjb3B5KSB7XG4gICAgICAvL3ptZW1jcHkoc3RhdGUtPndpbmRvdywgZW5kIC0gY29weSwgY29weSk7XG4gICAgICBzdGF0ZS53aW5kb3cuc2V0KHNyYy5zdWJhcnJheShlbmQgLSBjb3B5LCBlbmQpLCAwKTtcbiAgICAgIHN0YXRlLnduZXh0ID0gY29weTtcbiAgICAgIHN0YXRlLndoYXZlID0gc3RhdGUud3NpemU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgc3RhdGUud25leHQgKz0gZGlzdDtcbiAgICAgIGlmIChzdGF0ZS53bmV4dCA9PT0gc3RhdGUud3NpemUpIHsgc3RhdGUud25leHQgPSAwOyB9XG4gICAgICBpZiAoc3RhdGUud2hhdmUgPCBzdGF0ZS53c2l6ZSkgeyBzdGF0ZS53aGF2ZSArPSBkaXN0OyB9XG4gICAgfVxuICB9XG4gIHJldHVybiAwO1xufTtcblxuXG5jb25zdCBpbmZsYXRlJDIgPSAoc3RybSwgZmx1c2gpID0+IHtcblxuICBsZXQgc3RhdGU7XG4gIGxldCBpbnB1dCwgb3V0cHV0OyAgICAgICAgICAvLyBpbnB1dC9vdXRwdXQgYnVmZmVyc1xuICBsZXQgbmV4dDsgICAgICAgICAgICAgICAgICAgLyogbmV4dCBpbnB1dCBJTkRFWCAqL1xuICBsZXQgcHV0OyAgICAgICAgICAgICAgICAgICAgLyogbmV4dCBvdXRwdXQgSU5ERVggKi9cbiAgbGV0IGhhdmUsIGxlZnQ7ICAgICAgICAgICAgIC8qIGF2YWlsYWJsZSBpbnB1dCBhbmQgb3V0cHV0ICovXG4gIGxldCBob2xkOyAgICAgICAgICAgICAgICAgICAvKiBiaXQgYnVmZmVyICovXG4gIGxldCBiaXRzOyAgICAgICAgICAgICAgICAgICAvKiBiaXRzIGluIGJpdCBidWZmZXIgKi9cbiAgbGV0IF9pbiwgX291dDsgICAgICAgICAgICAgIC8qIHNhdmUgc3RhcnRpbmcgYXZhaWxhYmxlIGlucHV0IGFuZCBvdXRwdXQgKi9cbiAgbGV0IGNvcHk7ICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBzdG9yZWQgb3IgbWF0Y2ggYnl0ZXMgdG8gY29weSAqL1xuICBsZXQgZnJvbTsgICAgICAgICAgICAgICAgICAgLyogd2hlcmUgdG8gY29weSBtYXRjaCBieXRlcyBmcm9tICovXG4gIGxldCBmcm9tX3NvdXJjZTtcbiAgbGV0IGhlcmUgPSAwOyAgICAgICAgICAgICAgIC8qIGN1cnJlbnQgZGVjb2RpbmcgdGFibGUgZW50cnkgKi9cbiAgbGV0IGhlcmVfYml0cywgaGVyZV9vcCwgaGVyZV92YWw7IC8vIHBha2VkIFwiaGVyZVwiIGRlbm9ybWFsaXplZCAoSlMgc3BlY2lmaWMpXG4gIC8vbGV0IGxhc3Q7ICAgICAgICAgICAgICAgICAgIC8qIHBhcmVudCB0YWJsZSBlbnRyeSAqL1xuICBsZXQgbGFzdF9iaXRzLCBsYXN0X29wLCBsYXN0X3ZhbDsgLy8gcGFrZWQgXCJsYXN0XCIgZGVub3JtYWxpemVkIChKUyBzcGVjaWZpYylcbiAgbGV0IGxlbjsgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCB0byBjb3B5IGZvciByZXBlYXRzLCBiaXRzIHRvIGRyb3AgKi9cbiAgbGV0IHJldDsgICAgICAgICAgICAgICAgICAgIC8qIHJldHVybiBjb2RlICovXG4gIGNvbnN0IGhidWYgPSBuZXcgVWludDhBcnJheSg0KTsgICAgLyogYnVmZmVyIGZvciBnemlwIGhlYWRlciBjcmMgY2FsY3VsYXRpb24gKi9cbiAgbGV0IG9wdHM7XG5cbiAgbGV0IG47IC8vIHRlbXBvcmFyeSB2YXJpYWJsZSBmb3IgTkVFRF9CSVRTXG5cbiAgY29uc3Qgb3JkZXIgPSAvKiBwZXJtdXRhdGlvbiBvZiBjb2RlIGxlbmd0aHMgKi9cbiAgICBuZXcgVWludDhBcnJheShbIDE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTUgXSk7XG5cblxuICBpZiAoaW5mbGF0ZVN0YXRlQ2hlY2soc3RybSkgfHwgIXN0cm0ub3V0cHV0IHx8XG4gICAgICAoIXN0cm0uaW5wdXQgJiYgc3RybS5hdmFpbF9pbiAhPT0gMCkpIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTtcbiAgfVxuXG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgaWYgKHN0YXRlLm1vZGUgPT09IFRZUEUpIHsgc3RhdGUubW9kZSA9IFRZUEVETzsgfSAgICAvKiBza2lwIGNoZWNrICovXG5cblxuICAvLy0tLSBMT0FEKCkgLS0tXG4gIHB1dCA9IHN0cm0ubmV4dF9vdXQ7XG4gIG91dHB1dCA9IHN0cm0ub3V0cHV0O1xuICBsZWZ0ID0gc3RybS5hdmFpbF9vdXQ7XG4gIG5leHQgPSBzdHJtLm5leHRfaW47XG4gIGlucHV0ID0gc3RybS5pbnB1dDtcbiAgaGF2ZSA9IHN0cm0uYXZhaWxfaW47XG4gIGhvbGQgPSBzdGF0ZS5ob2xkO1xuICBiaXRzID0gc3RhdGUuYml0cztcbiAgLy8tLS1cblxuICBfaW4gPSBoYXZlO1xuICBfb3V0ID0gbGVmdDtcbiAgcmV0ID0gWl9PSyQxO1xuXG4gIGluZl9sZWF2ZTogLy8gZ290byBlbXVsYXRpb25cbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoc3RhdGUubW9kZSkge1xuICAgICAgY2FzZSBIRUFEOlxuICAgICAgICBpZiAoc3RhdGUud3JhcCA9PT0gMCkge1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFRE87XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gTkVFREJJVFMoMTYpO1xuICAgICAgICB3aGlsZSAoYml0cyA8IDE2KSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIGlmICgoc3RhdGUud3JhcCAmIDIpICYmIGhvbGQgPT09IDB4OGIxZikgeyAgLyogZ3ppcCBoZWFkZXIgKi9cbiAgICAgICAgICBpZiAoc3RhdGUud2JpdHMgPT09IDApIHtcbiAgICAgICAgICAgIHN0YXRlLndiaXRzID0gMTU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHN0YXRlLmNoZWNrID0gMC8qY3JjMzIoMEwsIFpfTlVMTCwgMCkqLztcbiAgICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTtcbiAgICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgICAgaGJ1ZlsxXSA9IChob2xkID4+PiA4KSAmIDB4ZmY7XG4gICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMl8xKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgICAvLz09PS8vXG5cbiAgICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICAgIGhvbGQgPSAwO1xuICAgICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICBzdGF0ZS5tb2RlID0gRkxBR1M7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICBzdGF0ZS5oZWFkLmRvbmUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIShzdGF0ZS53cmFwICYgMSkgfHwgICAvKiBjaGVjayBpZiB6bGliIGhlYWRlciBhbGxvd2VkICovXG4gICAgICAgICAgKCgoaG9sZCAmIDB4ZmYpLypCSVRTKDgpKi8gPDwgOCkgKyAoaG9sZCA+PiA4KSkgJSAzMSkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2luY29ycmVjdCBoZWFkZXIgY2hlY2snO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChob2xkICYgMHgwZikvKkJJVFMoNCkqLyAhPT0gWl9ERUZMQVRFRCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gY29tcHJlc3Npb24gbWV0aG9kJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vLS0tIERST1BCSVRTKDQpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSA0O1xuICAgICAgICBiaXRzIC09IDQ7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgbGVuID0gKGhvbGQgJiAweDBmKS8qQklUUyg0KSovICsgODtcbiAgICAgICAgaWYgKHN0YXRlLndiaXRzID09PSAwKSB7XG4gICAgICAgICAgc3RhdGUud2JpdHMgPSBsZW47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxlbiA+IDE1IHx8IGxlbiA+IHN0YXRlLndiaXRzKSB7XG4gICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCB3aW5kb3cgc2l6ZSc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vICEhISBwYWtvIHBhdGNoLiBGb3JjZSB1c2UgYG9wdGlvbnMud2luZG93Qml0c2AgaWYgcGFzc2VkLlxuICAgICAgICAvLyBSZXF1aXJlZCB0byBhbHdheXMgdXNlIG1heCB3aW5kb3cgc2l6ZSBieSBkZWZhdWx0LlxuICAgICAgICBzdGF0ZS5kbWF4ID0gMSA8PCBzdGF0ZS53Yml0cztcbiAgICAgICAgLy9zdGF0ZS5kbWF4ID0gMSA8PCBsZW47XG5cbiAgICAgICAgc3RhdGUuZmxhZ3MgPSAwOyAgICAgICAgICAgICAgIC8qIGluZGljYXRlIHpsaWIgaGVhZGVyICovXG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICB6bGliIGhlYWRlciBva1xcblwiKSk7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IDEvKmFkbGVyMzIoMEwsIFpfTlVMTCwgMCkqLztcbiAgICAgICAgc3RhdGUubW9kZSA9IGhvbGQgJiAweDIwMCA/IERJQ1RJRCA6IFRZUEU7XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgRkxBR1M6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5mbGFncyA9IGhvbGQ7XG4gICAgICAgIGlmICgoc3RhdGUuZmxhZ3MgJiAweGZmKSAhPT0gWl9ERUZMQVRFRCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gY29tcHJlc3Npb24gbWV0aG9kJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4ZTAwMCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gaGVhZGVyIGZsYWdzIHNldCc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQudGV4dCA9ICgoaG9sZCA+PiA4KSAmIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoc3RhdGUuZmxhZ3MgJiAweDAyMDApICYmIChzdGF0ZS53cmFwICYgNCkpIHtcbiAgICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTtcbiAgICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgICAgaGJ1ZlsxXSA9IChob2xkID4+PiA4KSAmIDB4ZmY7XG4gICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMl8xKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLm1vZGUgPSBUSU1FO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIFRJTUU6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQudGltZSA9IGhvbGQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChzdGF0ZS5mbGFncyAmIDB4MDIwMCkgJiYgKHN0YXRlLndyYXAgJiA0KSkge1xuICAgICAgICAgIC8vPT09IENSQzQoc3RhdGUuY2hlY2ssIGhvbGQpXG4gICAgICAgICAgaGJ1ZlswXSA9IGhvbGQgJiAweGZmO1xuICAgICAgICAgIGhidWZbMV0gPSAoaG9sZCA+Pj4gOCkgJiAweGZmO1xuICAgICAgICAgIGhidWZbMl0gPSAoaG9sZCA+Pj4gMTYpICYgMHhmZjtcbiAgICAgICAgICBoYnVmWzNdID0gKGhvbGQgPj4+IDI0KSAmIDB4ZmY7XG4gICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMl8xKHN0YXRlLmNoZWNrLCBoYnVmLCA0LCAwKTtcbiAgICAgICAgICAvLz09PVxuICAgICAgICB9XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gT1M7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgT1M6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQueGZsYWdzID0gKGhvbGQgJiAweGZmKTtcbiAgICAgICAgICBzdGF0ZS5oZWFkLm9zID0gKGhvbGQgPj4gOCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChzdGF0ZS5mbGFncyAmIDB4MDIwMCkgJiYgKHN0YXRlLndyYXAgJiA0KSkge1xuICAgICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpO1xuICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyXzEoc3RhdGUuY2hlY2ssIGhidWYsIDIsIDApO1xuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgfVxuICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICBob2xkID0gMDtcbiAgICAgICAgYml0cyA9IDA7XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgc3RhdGUubW9kZSA9IEVYTEVOO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIEVYTEVOOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHtcbiAgICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovXG4gICAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIHN0YXRlLmxlbmd0aCA9IGhvbGQ7XG4gICAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICAgIHN0YXRlLmhlYWQuZXh0cmFfbGVuID0gaG9sZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKChzdGF0ZS5mbGFncyAmIDB4MDIwMCkgJiYgKHN0YXRlLndyYXAgJiA0KSkge1xuICAgICAgICAgICAgLy89PT0gQ1JDMihzdGF0ZS5jaGVjaywgaG9sZCk7XG4gICAgICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzJfMShzdGF0ZS5jaGVjaywgaGJ1ZiwgMiwgMCk7XG4gICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgICAgYml0cyA9IDA7XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICBzdGF0ZS5oZWFkLmV4dHJhID0gbnVsbC8qWl9OVUxMKi87XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubW9kZSA9IEVYVFJBO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIEVYVFJBOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHtcbiAgICAgICAgICBjb3B5ID0gc3RhdGUubGVuZ3RoO1xuICAgICAgICAgIGlmIChjb3B5ID4gaGF2ZSkgeyBjb3B5ID0gaGF2ZTsgfVxuICAgICAgICAgIGlmIChjb3B5KSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgICAgICBsZW4gPSBzdGF0ZS5oZWFkLmV4dHJhX2xlbiAtIHN0YXRlLmxlbmd0aDtcbiAgICAgICAgICAgICAgaWYgKCFzdGF0ZS5oZWFkLmV4dHJhKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIHVudHlwZWQgYXJyYXkgZm9yIG1vcmUgY29udmVuaWVudCBwcm9jZXNzaW5nIGxhdGVyXG4gICAgICAgICAgICAgICAgc3RhdGUuaGVhZC5leHRyYSA9IG5ldyBVaW50OEFycmF5KHN0YXRlLmhlYWQuZXh0cmFfbGVuKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzdGF0ZS5oZWFkLmV4dHJhLnNldChcbiAgICAgICAgICAgICAgICBpbnB1dC5zdWJhcnJheShcbiAgICAgICAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICAgICAgICAvLyBleHRyYSBmaWVsZCBpcyBsaW1pdGVkIHRvIDY1NTM2IGJ5dGVzXG4gICAgICAgICAgICAgICAgICAvLyAtIG5vIG5lZWQgZm9yIGFkZGl0aW9uYWwgc2l6ZSBjaGVja1xuICAgICAgICAgICAgICAgICAgbmV4dCArIGNvcHlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIC8qbGVuICsgY29weSA+IHN0YXRlLmhlYWQuZXh0cmFfbWF4IC0gbGVuID8gc3RhdGUuaGVhZC5leHRyYV9tYXggOiBjb3B5LCovXG4gICAgICAgICAgICAgICAgbGVuXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIC8vem1lbWNweShzdGF0ZS5oZWFkLmV4dHJhICsgbGVuLCBuZXh0LFxuICAgICAgICAgICAgICAvLyAgICAgICAgbGVuICsgY29weSA+IHN0YXRlLmhlYWQuZXh0cmFfbWF4ID9cbiAgICAgICAgICAgICAgLy8gICAgICAgIHN0YXRlLmhlYWQuZXh0cmFfbWF4IC0gbGVuIDogY29weSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoKHN0YXRlLmZsYWdzICYgMHgwMjAwKSAmJiAoc3RhdGUud3JhcCAmIDQpKSB7XG4gICAgICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzJfMShzdGF0ZS5jaGVjaywgaW5wdXQsIGNvcHksIG5leHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGF2ZSAtPSBjb3B5O1xuICAgICAgICAgICAgbmV4dCArPSBjb3B5O1xuICAgICAgICAgICAgc3RhdGUubGVuZ3RoIC09IGNvcHk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzdGF0ZS5sZW5ndGgpIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubGVuZ3RoID0gMDtcbiAgICAgICAgc3RhdGUubW9kZSA9IE5BTUU7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTkFNRTpcbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwODAwKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgY29weSA9IDA7XG4gICAgICAgICAgZG8ge1xuICAgICAgICAgICAgLy8gVE9ETzogMiBvciAxIGJ5dGVzP1xuICAgICAgICAgICAgbGVuID0gaW5wdXRbbmV4dCArIGNvcHkrK107XG4gICAgICAgICAgICAvKiB1c2UgY29uc3RhbnQgbGltaXQgYmVjYXVzZSBpbiBqcyB3ZSBzaG91bGQgbm90IHByZWFsbG9jYXRlIG1lbW9yeSAqL1xuICAgICAgICAgICAgaWYgKHN0YXRlLmhlYWQgJiYgbGVuICYmXG4gICAgICAgICAgICAgICAgKHN0YXRlLmxlbmd0aCA8IDY1NTM2IC8qc3RhdGUuaGVhZC5uYW1lX21heCovKSkge1xuICAgICAgICAgICAgICBzdGF0ZS5oZWFkLm5hbWUgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gd2hpbGUgKGxlbiAmJiBjb3B5IDwgaGF2ZSk7XG5cbiAgICAgICAgICBpZiAoKHN0YXRlLmZsYWdzICYgMHgwMjAwKSAmJiAoc3RhdGUud3JhcCAmIDQpKSB7XG4gICAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyXzEoc3RhdGUuY2hlY2ssIGlucHV0LCBjb3B5LCBuZXh0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaGF2ZSAtPSBjb3B5O1xuICAgICAgICAgIG5leHQgKz0gY29weTtcbiAgICAgICAgICBpZiAobGVuKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICBzdGF0ZS5oZWFkLm5hbWUgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLmxlbmd0aCA9IDA7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBDT01NRU5UO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIENPTU1FTlQ6XG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MTAwMCkge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGNvcHkgPSAwO1xuICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgIGxlbiA9IGlucHV0W25leHQgKyBjb3B5KytdO1xuICAgICAgICAgICAgLyogdXNlIGNvbnN0YW50IGxpbWl0IGJlY2F1c2UgaW4ganMgd2Ugc2hvdWxkIG5vdCBwcmVhbGxvY2F0ZSBtZW1vcnkgKi9cbiAgICAgICAgICAgIGlmIChzdGF0ZS5oZWFkICYmIGxlbiAmJlxuICAgICAgICAgICAgICAgIChzdGF0ZS5sZW5ndGggPCA2NTUzNiAvKnN0YXRlLmhlYWQuY29tbV9tYXgqLykpIHtcbiAgICAgICAgICAgICAgc3RhdGUuaGVhZC5jb21tZW50ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IHdoaWxlIChsZW4gJiYgY29weSA8IGhhdmUpO1xuICAgICAgICAgIGlmICgoc3RhdGUuZmxhZ3MgJiAweDAyMDApICYmIChzdGF0ZS53cmFwICYgNCkpIHtcbiAgICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzJfMShzdGF0ZS5jaGVjaywgaW5wdXQsIGNvcHksIG5leHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBoYXZlIC09IGNvcHk7XG4gICAgICAgICAgbmV4dCArPSBjb3B5O1xuICAgICAgICAgIGlmIChsZW4pIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQuY29tbWVudCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubW9kZSA9IEhDUkM7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgSENSQzpcbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgLy89PT0gTkVFREJJVFMoMTYpOyAqL1xuICAgICAgICAgIHdoaWxlIChiaXRzIDwgMTYpIHtcbiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICBpZiAoKHN0YXRlLndyYXAgJiA0KSAmJiBob2xkICE9PSAoc3RhdGUuY2hlY2sgJiAweGZmZmYpKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdoZWFkZXIgY3JjIG1pc21hdGNoJztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgICBob2xkID0gMDtcbiAgICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICBzdGF0ZS5oZWFkLmhjcmMgPSAoKHN0YXRlLmZsYWdzID4+IDkpICYgMSk7XG4gICAgICAgICAgc3RhdGUuaGVhZC5kb25lID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAwO1xuICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIERJQ1RJRDpcbiAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpOyAqL1xuICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IHpzd2FwMzIoaG9sZCk7XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gRElDVDtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBESUNUOlxuICAgICAgICBpZiAoc3RhdGUuaGF2ZWRpY3QgPT09IDApIHtcbiAgICAgICAgICAvLy0tLSBSRVNUT1JFKCkgLS0tXG4gICAgICAgICAgc3RybS5uZXh0X291dCA9IHB1dDtcbiAgICAgICAgICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7XG4gICAgICAgICAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgICAgICAgICBzdHJtLmF2YWlsX2luID0gaGF2ZTtcbiAgICAgICAgICBzdGF0ZS5ob2xkID0gaG9sZDtcbiAgICAgICAgICBzdGF0ZS5iaXRzID0gYml0cztcbiAgICAgICAgICAvLy0tLVxuICAgICAgICAgIHJldHVybiBaX05FRURfRElDVCQxO1xuICAgICAgICB9XG4gICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IDEvKmFkbGVyMzIoMEwsIFpfTlVMTCwgMCkqLztcbiAgICAgICAgc3RhdGUubW9kZSA9IFRZUEU7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgVFlQRTpcbiAgICAgICAgaWYgKGZsdXNoID09PSBaX0JMT0NLIHx8IGZsdXNoID09PSBaX1RSRUVTKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIFRZUEVETzpcbiAgICAgICAgaWYgKHN0YXRlLmxhc3QpIHtcbiAgICAgICAgICAvLy0tLSBCWVRFQklUUygpIC0tLS8vXG4gICAgICAgICAgaG9sZCA+Pj49IGJpdHMgJiA3O1xuICAgICAgICAgIGJpdHMgLT0gYml0cyAmIDc7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBDSEVDSztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLz09PSBORUVEQklUUygzKTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAzKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLmxhc3QgPSAoaG9sZCAmIDB4MDEpLypCSVRTKDEpKi87XG4gICAgICAgIC8vLS0tIERST1BCSVRTKDEpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSAxO1xuICAgICAgICBiaXRzIC09IDE7XG4gICAgICAgIC8vLS0tLy9cblxuICAgICAgICBzd2l0Y2ggKChob2xkICYgMHgwMykvKkJJVFMoMikqLykge1xuICAgICAgICAgIGNhc2UgMDogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHN0b3JlZCBibG9jayAqL1xuICAgICAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgc3RvcmVkIGJsb2NrJXNcXG5cIixcbiAgICAgICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gXCIgKGxhc3QpXCIgOiBcIlwiKSk7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gU1RPUkVEO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAxOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZml4ZWQgYmxvY2sgKi9cbiAgICAgICAgICAgIGZpeGVkdGFibGVzKHN0YXRlKTtcbiAgICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgIGZpeGVkIGNvZGVzIGJsb2NrJXNcXG5cIixcbiAgICAgICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gXCIgKGxhc3QpXCIgOiBcIlwiKSk7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gTEVOXzsgICAgICAgICAgICAgLyogZGVjb2RlIGNvZGVzICovXG4gICAgICAgICAgICBpZiAoZmx1c2ggPT09IFpfVFJFRVMpIHtcbiAgICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IDI7XG4gICAgICAgICAgICAgIGJpdHMgLT0gMjtcbiAgICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgICBicmVhayBpbmZfbGVhdmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBkeW5hbWljIGJsb2NrICovXG4gICAgICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICBkeW5hbWljIGNvZGVzIGJsb2NrJXNcXG5cIixcbiAgICAgICAgICAgIC8vICAgICAgICBzdGF0ZS5sYXN0ID8gXCIgKGxhc3QpXCIgOiBcIlwiKSk7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gVEFCTEU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGJsb2NrIHR5cGUnO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgfVxuICAgICAgICAvLy0tLSBEUk9QQklUUygyKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gMjtcbiAgICAgICAgYml0cyAtPSAyO1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBTVE9SRUQ6XG4gICAgICAgIC8vLS0tIEJZVEVCSVRTKCkgLS0tLy8gLyogZ28gdG8gYnl0ZSBib3VuZGFyeSAqL1xuICAgICAgICBob2xkID4+Pj0gYml0cyAmIDc7XG4gICAgICAgIGJpdHMgLT0gYml0cyAmIDc7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpOyAqL1xuICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIGlmICgoaG9sZCAmIDB4ZmZmZikgIT09ICgoaG9sZCA+Pj4gMTYpIF4gMHhmZmZmKSkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgc3RvcmVkIGJsb2NrIGxlbmd0aHMnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubGVuZ3RoID0gaG9sZCAmIDB4ZmZmZjtcbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICBzdG9yZWQgbGVuZ3RoICV1XFxuXCIsXG4gICAgICAgIC8vICAgICAgICBzdGF0ZS5sZW5ndGgpKTtcbiAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLm1vZGUgPSBDT1BZXztcbiAgICAgICAgaWYgKGZsdXNoID09PSBaX1RSRUVTKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIENPUFlfOlxuICAgICAgICBzdGF0ZS5tb2RlID0gQ09QWTtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBDT1BZOlxuICAgICAgICBjb3B5ID0gc3RhdGUubGVuZ3RoO1xuICAgICAgICBpZiAoY29weSkge1xuICAgICAgICAgIGlmIChjb3B5ID4gaGF2ZSkgeyBjb3B5ID0gaGF2ZTsgfVxuICAgICAgICAgIGlmIChjb3B5ID4gbGVmdCkgeyBjb3B5ID0gbGVmdDsgfVxuICAgICAgICAgIGlmIChjb3B5ID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIC8vLS0tIHptZW1jcHkocHV0LCBuZXh0LCBjb3B5KTsgLS0tXG4gICAgICAgICAgb3V0cHV0LnNldChpbnB1dC5zdWJhcnJheShuZXh0LCBuZXh0ICsgY29weSksIHB1dCk7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgICAgbGVmdCAtPSBjb3B5O1xuICAgICAgICAgIHB1dCArPSBjb3B5O1xuICAgICAgICAgIHN0YXRlLmxlbmd0aCAtPSBjb3B5O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgc3RvcmVkIGVuZFxcblwiKSk7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVEFCTEU6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE0KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNCkge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5ubGVuID0gKGhvbGQgJiAweDFmKS8qQklUUyg1KSovICsgMjU3O1xuICAgICAgICAvLy0tLSBEUk9QQklUUyg1KSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gNTtcbiAgICAgICAgYml0cyAtPSA1O1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIHN0YXRlLm5kaXN0ID0gKGhvbGQgJiAweDFmKS8qQklUUyg1KSovICsgMTtcbiAgICAgICAgLy8tLS0gRFJPUEJJVFMoNSkgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IDU7XG4gICAgICAgIGJpdHMgLT0gNTtcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBzdGF0ZS5uY29kZSA9IChob2xkICYgMHgwZikvKkJJVFMoNCkqLyArIDQ7XG4gICAgICAgIC8vLS0tIERST1BCSVRTKDQpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSA0O1xuICAgICAgICBiaXRzIC09IDQ7XG4gICAgICAgIC8vLS0tLy9cbi8vI2lmbmRlZiBQS1pJUF9CVUdfV09SS0FST1VORFxuICAgICAgICBpZiAoc3RhdGUubmxlbiA+IDI4NiB8fCBzdGF0ZS5uZGlzdCA+IDMwKSB7XG4gICAgICAgICAgc3RybS5tc2cgPSAndG9vIG1hbnkgbGVuZ3RoIG9yIGRpc3RhbmNlIHN5bWJvbHMnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbi8vI2VuZGlmXG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgdGFibGUgc2l6ZXMgb2tcXG5cIikpO1xuICAgICAgICBzdGF0ZS5oYXZlID0gMDtcbiAgICAgICAgc3RhdGUubW9kZSA9IExFTkxFTlM7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOTEVOUzpcbiAgICAgICAgd2hpbGUgKHN0YXRlLmhhdmUgPCBzdGF0ZS5uY29kZSkge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMpO1xuICAgICAgICAgIHdoaWxlIChiaXRzIDwgMykge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIHN0YXRlLmxlbnNbb3JkZXJbc3RhdGUuaGF2ZSsrXV0gPSAoaG9sZCAmIDB4MDcpOy8vQklUUygzKTtcbiAgICAgICAgICAvLy0tLSBEUk9QQklUUygzKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSAzO1xuICAgICAgICAgIGJpdHMgLT0gMztcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHN0YXRlLmhhdmUgPCAxOSkge1xuICAgICAgICAgIHN0YXRlLmxlbnNbb3JkZXJbc3RhdGUuaGF2ZSsrXV0gPSAwO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIGhhdmUgc2VwYXJhdGUgdGFibGVzICYgbm8gcG9pbnRlcnMuIDIgY29tbWVudGVkIGxpbmVzIGJlbG93IG5vdCBuZWVkZWQuXG4gICAgICAgIC8vc3RhdGUubmV4dCA9IHN0YXRlLmNvZGVzO1xuICAgICAgICAvL3N0YXRlLmxlbmNvZGUgPSBzdGF0ZS5uZXh0O1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdXNlIGR5bmFtaWMgdGFibGVcbiAgICAgICAgc3RhdGUubGVuY29kZSA9IHN0YXRlLmxlbmR5bjtcbiAgICAgICAgc3RhdGUubGVuYml0cyA9IDc7XG5cbiAgICAgICAgb3B0cyA9IHsgYml0czogc3RhdGUubGVuYml0cyB9O1xuICAgICAgICByZXQgPSBpbmZ0cmVlcyhDT0RFUywgc3RhdGUubGVucywgMCwgMTksIHN0YXRlLmxlbmNvZGUsIDAsIHN0YXRlLndvcmssIG9wdHMpO1xuICAgICAgICBzdGF0ZS5sZW5iaXRzID0gb3B0cy5iaXRzO1xuXG4gICAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGNvZGUgbGVuZ3RocyBzZXQnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICBjb2RlIGxlbmd0aHMgb2tcXG5cIikpO1xuICAgICAgICBzdGF0ZS5oYXZlID0gMDtcbiAgICAgICAgc3RhdGUubW9kZSA9IENPREVMRU5TO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIENPREVMRU5TOlxuICAgICAgICB3aGlsZSAoc3RhdGUuaGF2ZSA8IHN0YXRlLm5sZW4gKyBzdGF0ZS5uZGlzdCkge1xuICAgICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgIGhlcmUgPSBzdGF0ZS5sZW5jb2RlW2hvbGQgJiAoKDEgPDwgc3RhdGUubGVuYml0cykgLSAxKV07LypCSVRTKHN0YXRlLmxlbmJpdHMpKi9cbiAgICAgICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgICBpZiAoKGhlcmVfYml0cykgPD0gYml0cykgeyBicmVhazsgfVxuICAgICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGhlcmVfdmFsIDwgMTYpIHtcbiAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgIHN0YXRlLmxlbnNbc3RhdGUuaGF2ZSsrXSA9IGhlcmVfdmFsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChoZXJlX3ZhbCA9PT0gMTYpIHtcbiAgICAgICAgICAgICAgLy89PT0gTkVFREJJVFMoaGVyZS5iaXRzICsgMik7XG4gICAgICAgICAgICAgIG4gPSBoZXJlX2JpdHMgKyAyO1xuICAgICAgICAgICAgICB3aGlsZSAoYml0cyA8IG4pIHtcbiAgICAgICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vL1xuICAgICAgICAgICAgICBob2xkID4+Pj0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgICBpZiAoc3RhdGUuaGF2ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgYml0IGxlbmd0aCByZXBlYXQnO1xuICAgICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGVuID0gc3RhdGUubGVuc1tzdGF0ZS5oYXZlIC0gMV07XG4gICAgICAgICAgICAgIGNvcHkgPSAzICsgKGhvbGQgJiAweDAzKTsvL0JJVFMoMik7XG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDIpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSAyO1xuICAgICAgICAgICAgICBiaXRzIC09IDI7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGhlcmVfdmFsID09PSAxNykge1xuICAgICAgICAgICAgICAvLz09PSBORUVEQklUUyhoZXJlLmJpdHMgKyAzKTtcbiAgICAgICAgICAgICAgbiA9IGhlcmVfYml0cyArIDM7XG4gICAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikge1xuICAgICAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy89PT0vL1xuICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgICAgIGxlbiA9IDA7XG4gICAgICAgICAgICAgIGNvcHkgPSAzICsgKGhvbGQgJiAweDA3KTsvL0JJVFMoMyk7XG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDMpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSAzO1xuICAgICAgICAgICAgICBiaXRzIC09IDM7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAvLz09PSBORUVEQklUUyhoZXJlLmJpdHMgKyA3KTtcbiAgICAgICAgICAgICAgbiA9IGhlcmVfYml0cyArIDc7XG4gICAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikge1xuICAgICAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy89PT0vL1xuICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgICAgIGxlbiA9IDA7XG4gICAgICAgICAgICAgIGNvcHkgPSAxMSArIChob2xkICYgMHg3Zik7Ly9CSVRTKDcpO1xuICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUyg3KSAtLS0vL1xuICAgICAgICAgICAgICBob2xkID4+Pj0gNztcbiAgICAgICAgICAgICAgYml0cyAtPSA3O1xuICAgICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc3RhdGUuaGF2ZSArIGNvcHkgPiBzdGF0ZS5ubGVuICsgc3RhdGUubmRpc3QpIHtcbiAgICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBiaXQgbGVuZ3RoIHJlcGVhdCc7XG4gICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgd2hpbGUgKGNvcHktLSkge1xuICAgICAgICAgICAgICBzdGF0ZS5sZW5zW3N0YXRlLmhhdmUrK10gPSBsZW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyogaGFuZGxlIGVycm9yIGJyZWFrcyBpbiB3aGlsZSAqL1xuICAgICAgICBpZiAoc3RhdGUubW9kZSA9PT0gQkFEKSB7IGJyZWFrOyB9XG5cbiAgICAgICAgLyogY2hlY2sgZm9yIGVuZC1vZi1ibG9jayBjb2RlIChiZXR0ZXIgaGF2ZSBvbmUpICovXG4gICAgICAgIGlmIChzdGF0ZS5sZW5zWzI1Nl0gPT09IDApIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGNvZGUgLS0gbWlzc2luZyBlbmQtb2YtYmxvY2snO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvKiBidWlsZCBjb2RlIHRhYmxlcyAtLSBub3RlOiBkbyBub3QgY2hhbmdlIHRoZSBsZW5iaXRzIG9yIGRpc3RiaXRzXG4gICAgICAgICAgIHZhbHVlcyBoZXJlICg5IGFuZCA2KSB3aXRob3V0IHJlYWRpbmcgdGhlIGNvbW1lbnRzIGluIGluZnRyZWVzLmhcbiAgICAgICAgICAgY29uY2VybmluZyB0aGUgRU5PVUdIIGNvbnN0YW50cywgd2hpY2ggZGVwZW5kIG9uIHRob3NlIHZhbHVlcyAqL1xuICAgICAgICBzdGF0ZS5sZW5iaXRzID0gOTtcblxuICAgICAgICBvcHRzID0geyBiaXRzOiBzdGF0ZS5sZW5iaXRzIH07XG4gICAgICAgIHJldCA9IGluZnRyZWVzKExFTlMsIHN0YXRlLmxlbnMsIDAsIHN0YXRlLm5sZW4sIHN0YXRlLmxlbmNvZGUsIDAsIHN0YXRlLndvcmssIG9wdHMpO1xuICAgICAgICAvLyBXZSBoYXZlIHNlcGFyYXRlIHRhYmxlcyAmIG5vIHBvaW50ZXJzLiAyIGNvbW1lbnRlZCBsaW5lcyBiZWxvdyBub3QgbmVlZGVkLlxuICAgICAgICAvLyBzdGF0ZS5uZXh0X2luZGV4ID0gb3B0cy50YWJsZV9pbmRleDtcbiAgICAgICAgc3RhdGUubGVuYml0cyA9IG9wdHMuYml0cztcbiAgICAgICAgLy8gc3RhdGUubGVuY29kZSA9IHN0YXRlLm5leHQ7XG5cbiAgICAgICAgaWYgKHJldCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGhzIHNldCc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlLmRpc3RiaXRzID0gNjtcbiAgICAgICAgLy9zdGF0ZS5kaXN0Y29kZS5jb3B5KHN0YXRlLmNvZGVzKTtcbiAgICAgICAgLy8gU3dpdGNoIHRvIHVzZSBkeW5hbWljIHRhYmxlXG4gICAgICAgIHN0YXRlLmRpc3Rjb2RlID0gc3RhdGUuZGlzdGR5bjtcbiAgICAgICAgb3B0cyA9IHsgYml0czogc3RhdGUuZGlzdGJpdHMgfTtcbiAgICAgICAgcmV0ID0gaW5mdHJlZXMoRElTVFMsIHN0YXRlLmxlbnMsIHN0YXRlLm5sZW4sIHN0YXRlLm5kaXN0LCBzdGF0ZS5kaXN0Y29kZSwgMCwgc3RhdGUud29yaywgb3B0cyk7XG4gICAgICAgIC8vIFdlIGhhdmUgc2VwYXJhdGUgdGFibGVzICYgbm8gcG9pbnRlcnMuIDIgY29tbWVudGVkIGxpbmVzIGJlbG93IG5vdCBuZWVkZWQuXG4gICAgICAgIC8vIHN0YXRlLm5leHRfaW5kZXggPSBvcHRzLnRhYmxlX2luZGV4O1xuICAgICAgICBzdGF0ZS5kaXN0Yml0cyA9IG9wdHMuYml0cztcbiAgICAgICAgLy8gc3RhdGUuZGlzdGNvZGUgPSBzdGF0ZS5uZXh0O1xuXG4gICAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlcyBzZXQnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgJ2luZmxhdGU6ICAgICAgIGNvZGVzIG9rXFxuJykpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gTEVOXztcbiAgICAgICAgaWYgKGZsdXNoID09PSBaX1RSRUVTKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIExFTl86XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMRU47XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOOlxuICAgICAgICBpZiAoaGF2ZSA+PSA2ICYmIGxlZnQgPj0gMjU4KSB7XG4gICAgICAgICAgLy8tLS0gUkVTVE9SRSgpIC0tLVxuICAgICAgICAgIHN0cm0ubmV4dF9vdXQgPSBwdXQ7XG4gICAgICAgICAgc3RybS5hdmFpbF9vdXQgPSBsZWZ0O1xuICAgICAgICAgIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gICAgICAgICAgc3RybS5hdmFpbF9pbiA9IGhhdmU7XG4gICAgICAgICAgc3RhdGUuaG9sZCA9IGhvbGQ7XG4gICAgICAgICAgc3RhdGUuYml0cyA9IGJpdHM7XG4gICAgICAgICAgLy8tLS1cbiAgICAgICAgICBpbmZmYXN0KHN0cm0sIF9vdXQpO1xuICAgICAgICAgIC8vLS0tIExPQUQoKSAtLS1cbiAgICAgICAgICBwdXQgPSBzdHJtLm5leHRfb3V0O1xuICAgICAgICAgIG91dHB1dCA9IHN0cm0ub3V0cHV0O1xuICAgICAgICAgIGxlZnQgPSBzdHJtLmF2YWlsX291dDtcbiAgICAgICAgICBuZXh0ID0gc3RybS5uZXh0X2luO1xuICAgICAgICAgIGlucHV0ID0gc3RybS5pbnB1dDtcbiAgICAgICAgICBoYXZlID0gc3RybS5hdmFpbF9pbjtcbiAgICAgICAgICBob2xkID0gc3RhdGUuaG9sZDtcbiAgICAgICAgICBiaXRzID0gc3RhdGUuYml0cztcbiAgICAgICAgICAvLy0tLVxuXG4gICAgICAgICAgaWYgKHN0YXRlLm1vZGUgPT09IFRZUEUpIHtcbiAgICAgICAgICAgIHN0YXRlLmJhY2sgPSAtMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUuYmFjayA9IDA7XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICBoZXJlID0gc3RhdGUubGVuY29kZVtob2xkICYgKCgxIDw8IHN0YXRlLmxlbmJpdHMpIC0gMSldOyAgLypCSVRTKHN0YXRlLmxlbmJpdHMpKi9cbiAgICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDtcbiAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgaWYgKGhlcmVfYml0cyA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICB9XG4gICAgICAgIGlmIChoZXJlX29wICYmIChoZXJlX29wICYgMHhmMCkgPT09IDApIHtcbiAgICAgICAgICBsYXN0X2JpdHMgPSBoZXJlX2JpdHM7XG4gICAgICAgICAgbGFzdF9vcCA9IGhlcmVfb3A7XG4gICAgICAgICAgbGFzdF92YWwgPSBoZXJlX3ZhbDtcbiAgICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICBoZXJlID0gc3RhdGUubGVuY29kZVtsYXN0X3ZhbCArXG4gICAgICAgICAgICAgICAgICAgICgoaG9sZCAmICgoMSA8PCAobGFzdF9iaXRzICsgbGFzdF9vcCkpIC0gMSkpLypCSVRTKGxhc3QuYml0cyArIGxhc3Qub3ApKi8gPj4gbGFzdF9iaXRzKV07XG4gICAgICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDtcbiAgICAgICAgICAgIGhlcmVfb3AgPSAoaGVyZSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjtcblxuICAgICAgICAgICAgaWYgKChsYXN0X2JpdHMgKyBoZXJlX2JpdHMpIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgICAgIC8vLS0tIFBVTExCWVRFKCkgLS0tLy9cbiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vLS0tIERST1BCSVRTKGxhc3QuYml0cykgLS0tLy9cbiAgICAgICAgICBob2xkID4+Pj0gbGFzdF9iaXRzO1xuICAgICAgICAgIGJpdHMgLT0gbGFzdF9iaXRzO1xuICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICBzdGF0ZS5iYWNrICs9IGxhc3RfYml0cztcbiAgICAgICAgfVxuICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIHN0YXRlLmJhY2sgKz0gaGVyZV9iaXRzO1xuICAgICAgICBzdGF0ZS5sZW5ndGggPSBoZXJlX3ZhbDtcbiAgICAgICAgaWYgKGhlcmVfb3AgPT09IDApIHtcbiAgICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgaGVyZS52YWwgPj0gMHgyMCAmJiBoZXJlLnZhbCA8IDB4N2YgP1xuICAgICAgICAgIC8vICAgICAgICBcImluZmxhdGU6ICAgICAgICAgbGl0ZXJhbCAnJWMnXFxuXCIgOlxuICAgICAgICAgIC8vICAgICAgICBcImluZmxhdGU6ICAgICAgICAgbGl0ZXJhbCAweCUwMnhcXG5cIiwgaGVyZS52YWwpKTtcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gTElUO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoZXJlX29wICYgMzIpIHtcbiAgICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgICAgIGVuZCBvZiBibG9ja1xcblwiKSk7XG4gICAgICAgICAgc3RhdGUuYmFjayA9IC0xO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoZXJlX29wICYgNjQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGxpdGVyYWwvbGVuZ3RoIGNvZGUnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUuZXh0cmEgPSBoZXJlX29wICYgMTU7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMRU5FWFQ7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVORVhUOlxuICAgICAgICBpZiAoc3RhdGUuZXh0cmEpIHtcbiAgICAgICAgICAvLz09PSBORUVEQklUUyhzdGF0ZS5leHRyYSk7XG4gICAgICAgICAgbiA9IHN0YXRlLmV4dHJhO1xuICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIHN0YXRlLmxlbmd0aCArPSBob2xkICYgKCgxIDw8IHN0YXRlLmV4dHJhKSAtIDEpLypCSVRTKHN0YXRlLmV4dHJhKSovO1xuICAgICAgICAgIC8vLS0tIERST1BCSVRTKHN0YXRlLmV4dHJhKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSBzdGF0ZS5leHRyYTtcbiAgICAgICAgICBiaXRzIC09IHN0YXRlLmV4dHJhO1xuICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICBzdGF0ZS5iYWNrICs9IHN0YXRlLmV4dHJhO1xuICAgICAgICB9XG4gICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgbGVuZ3RoICV1XFxuXCIsIHN0YXRlLmxlbmd0aCkpO1xuICAgICAgICBzdGF0ZS53YXMgPSBzdGF0ZS5sZW5ndGg7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBESVNUO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIERJU1Q6XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICBoZXJlID0gc3RhdGUuZGlzdGNvZGVbaG9sZCAmICgoMSA8PCBzdGF0ZS5kaXN0Yml0cykgLSAxKV07LypCSVRTKHN0YXRlLmRpc3RiaXRzKSovXG4gICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgIGhlcmVfdmFsID0gaGVyZSAmIDB4ZmZmZjtcblxuICAgICAgICAgIGlmICgoaGVyZV9iaXRzKSA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICB9XG4gICAgICAgIGlmICgoaGVyZV9vcCAmIDB4ZjApID09PSAwKSB7XG4gICAgICAgICAgbGFzdF9iaXRzID0gaGVyZV9iaXRzO1xuICAgICAgICAgIGxhc3Rfb3AgPSBoZXJlX29wO1xuICAgICAgICAgIGxhc3RfdmFsID0gaGVyZV92YWw7XG4gICAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgaGVyZSA9IHN0YXRlLmRpc3Rjb2RlW2xhc3RfdmFsICtcbiAgICAgICAgICAgICAgICAgICAgKChob2xkICYgKCgxIDw8IChsYXN0X2JpdHMgKyBsYXN0X29wKSkgLSAxKSkvKkJJVFMobGFzdC5iaXRzICsgbGFzdC5vcCkqLyA+PiBsYXN0X2JpdHMpXTtcbiAgICAgICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgICBpZiAoKGxhc3RfYml0cyArIGhlcmVfYml0cykgPD0gYml0cykgeyBicmVhazsgfVxuICAgICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8tLS0gRFJPUEJJVFMobGFzdC5iaXRzKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSBsYXN0X2JpdHM7XG4gICAgICAgICAgYml0cyAtPSBsYXN0X2JpdHM7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIHN0YXRlLmJhY2sgKz0gbGFzdF9iaXRzO1xuICAgICAgICB9XG4gICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgc3RhdGUuYmFjayArPSBoZXJlX2JpdHM7XG4gICAgICAgIGlmIChoZXJlX29wICYgNjQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIGNvZGUnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUub2Zmc2V0ID0gaGVyZV92YWw7XG4gICAgICAgIHN0YXRlLmV4dHJhID0gKGhlcmVfb3ApICYgMTU7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBESVNURVhUO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIERJU1RFWFQ6XG4gICAgICAgIGlmIChzdGF0ZS5leHRyYSkge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKHN0YXRlLmV4dHJhKTtcbiAgICAgICAgICBuID0gc3RhdGUuZXh0cmE7XG4gICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgc3RhdGUub2Zmc2V0ICs9IGhvbGQgJiAoKDEgPDwgc3RhdGUuZXh0cmEpIC0gMSkvKkJJVFMoc3RhdGUuZXh0cmEpKi87XG4gICAgICAgICAgLy8tLS0gRFJPUEJJVFMoc3RhdGUuZXh0cmEpIC0tLS8vXG4gICAgICAgICAgaG9sZCA+Pj49IHN0YXRlLmV4dHJhO1xuICAgICAgICAgIGJpdHMgLT0gc3RhdGUuZXh0cmE7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIHN0YXRlLmJhY2sgKz0gc3RhdGUuZXh0cmE7XG4gICAgICAgIH1cbi8vI2lmZGVmIElORkxBVEVfU1RSSUNUXG4gICAgICAgIGlmIChzdGF0ZS5vZmZzZXQgPiBzdGF0ZS5kbWF4KSB7XG4gICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2snO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbi8vI2VuZGlmXG4gICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZGlzdGFuY2UgJXVcXG5cIiwgc3RhdGUub2Zmc2V0KSk7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBNQVRDSDtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBNQVRDSDpcbiAgICAgICAgaWYgKGxlZnQgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIGNvcHkgPSBfb3V0IC0gbGVmdDtcbiAgICAgICAgaWYgKHN0YXRlLm9mZnNldCA+IGNvcHkpIHsgICAgICAgICAvKiBjb3B5IGZyb20gd2luZG93ICovXG4gICAgICAgICAgY29weSA9IHN0YXRlLm9mZnNldCAtIGNvcHk7XG4gICAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS53aGF2ZSkge1xuICAgICAgICAgICAgaWYgKHN0YXRlLnNhbmUpIHtcbiAgICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2snO1xuICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbi8vICghKSBUaGlzIGJsb2NrIGlzIGRpc2FibGVkIGluIHpsaWIgZGVmYXVsdHMsXG4vLyBkb24ndCBlbmFibGUgaXQgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5XG4vLyNpZmRlZiBJTkZMQVRFX0FMTE9XX0lOVkFMSURfRElTVEFOQ0VfVE9PRkFSX0FSUlJcbi8vICAgICAgICAgIFRyYWNlKChzdGRlcnIsIFwiaW5mbGF0ZS5jIHRvbyBmYXJcXG5cIikpO1xuLy8gICAgICAgICAgY29weSAtPSBzdGF0ZS53aGF2ZTtcbi8vICAgICAgICAgIGlmIChjb3B5ID4gc3RhdGUubGVuZ3RoKSB7IGNvcHkgPSBzdGF0ZS5sZW5ndGg7IH1cbi8vICAgICAgICAgIGlmIChjb3B5ID4gbGVmdCkgeyBjb3B5ID0gbGVmdDsgfVxuLy8gICAgICAgICAgbGVmdCAtPSBjb3B5O1xuLy8gICAgICAgICAgc3RhdGUubGVuZ3RoIC09IGNvcHk7XG4vLyAgICAgICAgICBkbyB7XG4vLyAgICAgICAgICAgIG91dHB1dFtwdXQrK10gPSAwO1xuLy8gICAgICAgICAgfSB3aGlsZSAoLS1jb3B5KTtcbi8vICAgICAgICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHsgc3RhdGUubW9kZSA9IExFTjsgfVxuLy8gICAgICAgICAgYnJlYWs7XG4vLyNlbmRpZlxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY29weSA+IHN0YXRlLnduZXh0KSB7XG4gICAgICAgICAgICBjb3B5IC09IHN0YXRlLnduZXh0O1xuICAgICAgICAgICAgZnJvbSA9IHN0YXRlLndzaXplIC0gY29weTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmcm9tID0gc3RhdGUud25leHQgLSBjb3B5O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY29weSA+IHN0YXRlLmxlbmd0aCkgeyBjb3B5ID0gc3RhdGUubGVuZ3RoOyB9XG4gICAgICAgICAgZnJvbV9zb3VyY2UgPSBzdGF0ZS53aW5kb3c7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY29weSBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0O1xuICAgICAgICAgIGZyb20gPSBwdXQgLSBzdGF0ZS5vZmZzZXQ7XG4gICAgICAgICAgY29weSA9IHN0YXRlLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29weSA+IGxlZnQpIHsgY29weSA9IGxlZnQ7IH1cbiAgICAgICAgbGVmdCAtPSBjb3B5O1xuICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbiAgICAgICAgZG8ge1xuICAgICAgICAgIG91dHB1dFtwdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICB9IHdoaWxlICgtLWNvcHkpO1xuICAgICAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSB7IHN0YXRlLm1vZGUgPSBMRU47IH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIExJVDpcbiAgICAgICAgaWYgKGxlZnQgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIG91dHB1dFtwdXQrK10gPSBzdGF0ZS5sZW5ndGg7XG4gICAgICAgIGxlZnQtLTtcbiAgICAgICAgc3RhdGUubW9kZSA9IExFTjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENIRUNLOlxuICAgICAgICBpZiAoc3RhdGUud3JhcCkge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTtcbiAgICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIC8vIFVzZSAnfCcgaW5zdGVhZCBvZiAnKycgdG8gbWFrZSBzdXJlIHRoYXQgcmVzdWx0IGlzIHNpZ25lZFxuICAgICAgICAgICAgaG9sZCB8PSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICBfb3V0IC09IGxlZnQ7XG4gICAgICAgICAgc3RybS50b3RhbF9vdXQgKz0gX291dDtcbiAgICAgICAgICBzdGF0ZS50b3RhbCArPSBfb3V0O1xuICAgICAgICAgIGlmICgoc3RhdGUud3JhcCAmIDQpICYmIF9vdXQpIHtcbiAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9XG4gICAgICAgICAgICAgICAgLypVUERBVEVfQ0hFQ0soc3RhdGUuY2hlY2ssIHB1dCAtIF9vdXQsIF9vdXQpOyovXG4gICAgICAgICAgICAgICAgKHN0YXRlLmZsYWdzID8gY3JjMzJfMShzdGF0ZS5jaGVjaywgb3V0cHV0LCBfb3V0LCBwdXQgLSBfb3V0KSA6IGFkbGVyMzJfMShzdGF0ZS5jaGVjaywgb3V0cHV0LCBfb3V0LCBwdXQgLSBfb3V0KSk7XG5cbiAgICAgICAgICB9XG4gICAgICAgICAgX291dCA9IGxlZnQ7XG4gICAgICAgICAgLy8gTkI6IGNyYzMyIHN0b3JlZCBhcyBzaWduZWQgMzItYml0IGludCwgenN3YXAzMiByZXR1cm5zIHNpZ25lZCB0b29cbiAgICAgICAgICBpZiAoKHN0YXRlLndyYXAgJiA0KSAmJiAoc3RhdGUuZmxhZ3MgPyBob2xkIDogenN3YXAzMihob2xkKSkgIT09IHN0YXRlLmNoZWNrKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgZGF0YSBjaGVjayc7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgICAgYml0cyA9IDA7XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICBjaGVjayBtYXRjaGVzIHRyYWlsZXJcXG5cIikpO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMRU5HVEg7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOR1RIOlxuICAgICAgICBpZiAoc3RhdGUud3JhcCAmJiBzdGF0ZS5mbGFncykge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTtcbiAgICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgaWYgKChzdGF0ZS53cmFwICYgNCkgJiYgaG9sZCAhPT0gKHN0YXRlLnRvdGFsICYgMHhmZmZmZmZmZikpIHtcbiAgICAgICAgICAgIHN0cm0ubXNnID0gJ2luY29ycmVjdCBsZW5ndGggY2hlY2snO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICAgIGhvbGQgPSAwO1xuICAgICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgbGVuZ3RoIG1hdGNoZXMgdHJhaWxlclxcblwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubW9kZSA9IERPTkU7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgRE9ORTpcbiAgICAgICAgcmV0ID0gWl9TVFJFQU1fRU5EJDE7XG4gICAgICAgIGJyZWFrIGluZl9sZWF2ZTtcbiAgICAgIGNhc2UgQkFEOlxuICAgICAgICByZXQgPSBaX0RBVEFfRVJST1IkMTtcbiAgICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgICAgY2FzZSBNRU06XG4gICAgICAgIHJldHVybiBaX01FTV9FUlJPUiQxO1xuICAgICAgY2FzZSBTWU5DOlxuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTtcbiAgICB9XG4gIH1cblxuICAvLyBpbmZfbGVhdmUgPC0gaGVyZSBpcyByZWFsIHBsYWNlIGZvciBcImdvdG8gaW5mX2xlYXZlXCIsIGVtdWxhdGVkIHZpYSBcImJyZWFrIGluZl9sZWF2ZVwiXG5cbiAgLypcbiAgICAgUmV0dXJuIGZyb20gaW5mbGF0ZSgpLCB1cGRhdGluZyB0aGUgdG90YWwgY291bnRzIGFuZCB0aGUgY2hlY2sgdmFsdWUuXG4gICAgIElmIHRoZXJlIHdhcyBubyBwcm9ncmVzcyBkdXJpbmcgdGhlIGluZmxhdGUoKSBjYWxsLCByZXR1cm4gYSBidWZmZXJcbiAgICAgZXJyb3IuICBDYWxsIHVwZGF0ZXdpbmRvdygpIHRvIGNyZWF0ZSBhbmQvb3IgdXBkYXRlIHRoZSB3aW5kb3cgc3RhdGUuXG4gICAgIE5vdGU6IGEgbWVtb3J5IGVycm9yIGZyb20gaW5mbGF0ZSgpIGlzIG5vbi1yZWNvdmVyYWJsZS5cbiAgICovXG5cbiAgLy8tLS0gUkVTVE9SRSgpIC0tLVxuICBzdHJtLm5leHRfb3V0ID0gcHV0O1xuICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7XG4gIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gIHN0cm0uYXZhaWxfaW4gPSBoYXZlO1xuICBzdGF0ZS5ob2xkID0gaG9sZDtcbiAgc3RhdGUuYml0cyA9IGJpdHM7XG4gIC8vLS0tXG5cbiAgaWYgKHN0YXRlLndzaXplIHx8IChfb3V0ICE9PSBzdHJtLmF2YWlsX291dCAmJiBzdGF0ZS5tb2RlIDwgQkFEICYmXG4gICAgICAgICAgICAgICAgICAgICAgKHN0YXRlLm1vZGUgPCBDSEVDSyB8fCBmbHVzaCAhPT0gWl9GSU5JU0gkMSkpKSB7XG4gICAgaWYgKHVwZGF0ZXdpbmRvdyhzdHJtLCBzdHJtLm91dHB1dCwgc3RybS5uZXh0X291dCwgX291dCAtIHN0cm0uYXZhaWxfb3V0KSkgO1xuICB9XG4gIF9pbiAtPSBzdHJtLmF2YWlsX2luO1xuICBfb3V0IC09IHN0cm0uYXZhaWxfb3V0O1xuICBzdHJtLnRvdGFsX2luICs9IF9pbjtcbiAgc3RybS50b3RhbF9vdXQgKz0gX291dDtcbiAgc3RhdGUudG90YWwgKz0gX291dDtcbiAgaWYgKChzdGF0ZS53cmFwICYgNCkgJiYgX291dCkge1xuICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IC8qVVBEQVRFX0NIRUNLKHN0YXRlLmNoZWNrLCBzdHJtLm5leHRfb3V0IC0gX291dCwgX291dCk7Ki9cbiAgICAgIChzdGF0ZS5mbGFncyA/IGNyYzMyXzEoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgc3RybS5uZXh0X291dCAtIF9vdXQpIDogYWRsZXIzMl8xKHN0YXRlLmNoZWNrLCBvdXRwdXQsIF9vdXQsIHN0cm0ubmV4dF9vdXQgLSBfb3V0KSk7XG4gIH1cbiAgc3RybS5kYXRhX3R5cGUgPSBzdGF0ZS5iaXRzICsgKHN0YXRlLmxhc3QgPyA2NCA6IDApICtcbiAgICAgICAgICAgICAgICAgICAgKHN0YXRlLm1vZGUgPT09IFRZUEUgPyAxMjggOiAwKSArXG4gICAgICAgICAgICAgICAgICAgIChzdGF0ZS5tb2RlID09PSBMRU5fIHx8IHN0YXRlLm1vZGUgPT09IENPUFlfID8gMjU2IDogMCk7XG4gIGlmICgoKF9pbiA9PT0gMCAmJiBfb3V0ID09PSAwKSB8fCBmbHVzaCA9PT0gWl9GSU5JU0gkMSkgJiYgcmV0ID09PSBaX09LJDEpIHtcbiAgICByZXQgPSBaX0JVRl9FUlJPUjtcbiAgfVxuICByZXR1cm4gcmV0O1xufTtcblxuXG5jb25zdCBpbmZsYXRlRW5kID0gKHN0cm0pID0+IHtcblxuICBpZiAoaW5mbGF0ZVN0YXRlQ2hlY2soc3RybSkpIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTtcbiAgfVxuXG4gIGxldCBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIGlmIChzdGF0ZS53aW5kb3cpIHtcbiAgICBzdGF0ZS53aW5kb3cgPSBudWxsO1xuICB9XG4gIHN0cm0uc3RhdGUgPSBudWxsO1xuICByZXR1cm4gWl9PSyQxO1xufTtcblxuXG5jb25zdCBpbmZsYXRlR2V0SGVhZGVyID0gKHN0cm0sIGhlYWQpID0+IHtcblxuICAvKiBjaGVjayBzdGF0ZSAqL1xuICBpZiAoaW5mbGF0ZVN0YXRlQ2hlY2soc3RybSkpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDE7IH1cbiAgY29uc3Qgc3RhdGUgPSBzdHJtLnN0YXRlO1xuICBpZiAoKHN0YXRlLndyYXAgJiAyKSA9PT0gMCkgeyByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTsgfVxuXG4gIC8qIHNhdmUgaGVhZGVyIHN0cnVjdHVyZSAqL1xuICBzdGF0ZS5oZWFkID0gaGVhZDtcbiAgaGVhZC5kb25lID0gZmFsc2U7XG4gIHJldHVybiBaX09LJDE7XG59O1xuXG5cbmNvbnN0IGluZmxhdGVTZXREaWN0aW9uYXJ5ID0gKHN0cm0sIGRpY3Rpb25hcnkpID0+IHtcbiAgY29uc3QgZGljdExlbmd0aCA9IGRpY3Rpb25hcnkubGVuZ3RoO1xuXG4gIGxldCBzdGF0ZTtcbiAgbGV0IGRpY3RpZDtcbiAgbGV0IHJldDtcblxuICAvKiBjaGVjayBzdGF0ZSAqL1xuICBpZiAoaW5mbGF0ZVN0YXRlQ2hlY2soc3RybSkpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SJDE7IH1cbiAgc3RhdGUgPSBzdHJtLnN0YXRlO1xuXG4gIGlmIChzdGF0ZS53cmFwICE9PSAwICYmIHN0YXRlLm1vZGUgIT09IERJQ1QpIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1IkMTtcbiAgfVxuXG4gIC8qIGNoZWNrIGZvciBjb3JyZWN0IGRpY3Rpb25hcnkgaWRlbnRpZmllciAqL1xuICBpZiAoc3RhdGUubW9kZSA9PT0gRElDVCkge1xuICAgIGRpY3RpZCA9IDE7IC8qIGFkbGVyMzIoMCwgbnVsbCwgMCkqL1xuICAgIC8qIGRpY3RpZCA9IGFkbGVyMzIoZGljdGlkLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoKTsgKi9cbiAgICBkaWN0aWQgPSBhZGxlcjMyXzEoZGljdGlkLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoLCAwKTtcbiAgICBpZiAoZGljdGlkICE9PSBzdGF0ZS5jaGVjaykge1xuICAgICAgcmV0dXJuIFpfREFUQV9FUlJPUiQxO1xuICAgIH1cbiAgfVxuICAvKiBjb3B5IGRpY3Rpb25hcnkgdG8gd2luZG93IHVzaW5nIHVwZGF0ZXdpbmRvdygpLCB3aGljaCB3aWxsIGFtZW5kIHRoZVxuICAgZXhpc3RpbmcgZGljdGlvbmFyeSBpZiBhcHByb3ByaWF0ZSAqL1xuICByZXQgPSB1cGRhdGV3aW5kb3coc3RybSwgZGljdGlvbmFyeSwgZGljdExlbmd0aCwgZGljdExlbmd0aCk7XG4gIGlmIChyZXQpIHtcbiAgICBzdGF0ZS5tb2RlID0gTUVNO1xuICAgIHJldHVybiBaX01FTV9FUlJPUiQxO1xuICB9XG4gIHN0YXRlLmhhdmVkaWN0ID0gMTtcbiAgLy8gVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICBkaWN0aW9uYXJ5IHNldFxcblwiKSk7XG4gIHJldHVybiBaX09LJDE7XG59O1xuXG5cbnZhciBpbmZsYXRlUmVzZXRfMSA9IGluZmxhdGVSZXNldDtcbnZhciBpbmZsYXRlUmVzZXQyXzEgPSBpbmZsYXRlUmVzZXQyO1xudmFyIGluZmxhdGVSZXNldEtlZXBfMSA9IGluZmxhdGVSZXNldEtlZXA7XG52YXIgaW5mbGF0ZUluaXRfMSA9IGluZmxhdGVJbml0O1xudmFyIGluZmxhdGVJbml0Ml8xID0gaW5mbGF0ZUluaXQyO1xudmFyIGluZmxhdGVfMiQxID0gaW5mbGF0ZSQyO1xudmFyIGluZmxhdGVFbmRfMSA9IGluZmxhdGVFbmQ7XG52YXIgaW5mbGF0ZUdldEhlYWRlcl8xID0gaW5mbGF0ZUdldEhlYWRlcjtcbnZhciBpbmZsYXRlU2V0RGljdGlvbmFyeV8xID0gaW5mbGF0ZVNldERpY3Rpb25hcnk7XG52YXIgaW5mbGF0ZUluZm8gPSAncGFrbyBpbmZsYXRlIChmcm9tIE5vZGVjYSBwcm9qZWN0KSc7XG5cbi8qIE5vdCBpbXBsZW1lbnRlZFxubW9kdWxlLmV4cG9ydHMuaW5mbGF0ZUNvZGVzVXNlZCA9IGluZmxhdGVDb2Rlc1VzZWQ7XG5tb2R1bGUuZXhwb3J0cy5pbmZsYXRlQ29weSA9IGluZmxhdGVDb3B5O1xubW9kdWxlLmV4cG9ydHMuaW5mbGF0ZUdldERpY3Rpb25hcnkgPSBpbmZsYXRlR2V0RGljdGlvbmFyeTtcbm1vZHVsZS5leHBvcnRzLmluZmxhdGVNYXJrID0gaW5mbGF0ZU1hcms7XG5tb2R1bGUuZXhwb3J0cy5pbmZsYXRlUHJpbWUgPSBpbmZsYXRlUHJpbWU7XG5tb2R1bGUuZXhwb3J0cy5pbmZsYXRlU3luYyA9IGluZmxhdGVTeW5jO1xubW9kdWxlLmV4cG9ydHMuaW5mbGF0ZVN5bmNQb2ludCA9IGluZmxhdGVTeW5jUG9pbnQ7XG5tb2R1bGUuZXhwb3J0cy5pbmZsYXRlVW5kZXJtaW5lID0gaW5mbGF0ZVVuZGVybWluZTtcbm1vZHVsZS5leHBvcnRzLmluZmxhdGVWYWxpZGF0ZSA9IGluZmxhdGVWYWxpZGF0ZTtcbiovXG5cbnZhciBpbmZsYXRlXzEkMiA9IHtcblx0aW5mbGF0ZVJlc2V0OiBpbmZsYXRlUmVzZXRfMSxcblx0aW5mbGF0ZVJlc2V0MjogaW5mbGF0ZVJlc2V0Ml8xLFxuXHRpbmZsYXRlUmVzZXRLZWVwOiBpbmZsYXRlUmVzZXRLZWVwXzEsXG5cdGluZmxhdGVJbml0OiBpbmZsYXRlSW5pdF8xLFxuXHRpbmZsYXRlSW5pdDI6IGluZmxhdGVJbml0Ml8xLFxuXHRpbmZsYXRlOiBpbmZsYXRlXzIkMSxcblx0aW5mbGF0ZUVuZDogaW5mbGF0ZUVuZF8xLFxuXHRpbmZsYXRlR2V0SGVhZGVyOiBpbmZsYXRlR2V0SGVhZGVyXzEsXG5cdGluZmxhdGVTZXREaWN0aW9uYXJ5OiBpbmZsYXRlU2V0RGljdGlvbmFyeV8xLFxuXHRpbmZsYXRlSW5mbzogaW5mbGF0ZUluZm9cbn07XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxuZnVuY3Rpb24gR1poZWFkZXIoKSB7XG4gIC8qIHRydWUgaWYgY29tcHJlc3NlZCBkYXRhIGJlbGlldmVkIHRvIGJlIHRleHQgKi9cbiAgdGhpcy50ZXh0ICAgICAgID0gMDtcbiAgLyogbW9kaWZpY2F0aW9uIHRpbWUgKi9cbiAgdGhpcy50aW1lICAgICAgID0gMDtcbiAgLyogZXh0cmEgZmxhZ3MgKG5vdCB1c2VkIHdoZW4gd3JpdGluZyBhIGd6aXAgZmlsZSkgKi9cbiAgdGhpcy54ZmxhZ3MgICAgID0gMDtcbiAgLyogb3BlcmF0aW5nIHN5c3RlbSAqL1xuICB0aGlzLm9zICAgICAgICAgPSAwO1xuICAvKiBwb2ludGVyIHRvIGV4dHJhIGZpZWxkIG9yIFpfTlVMTCBpZiBub25lICovXG4gIHRoaXMuZXh0cmEgICAgICA9IG51bGw7XG4gIC8qIGV4dHJhIGZpZWxkIGxlbmd0aCAodmFsaWQgaWYgZXh0cmEgIT0gWl9OVUxMKSAqL1xuICB0aGlzLmV4dHJhX2xlbiAgPSAwOyAvLyBBY3R1YWxseSwgd2UgZG9uJ3QgbmVlZCBpdCBpbiBKUyxcbiAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGxlYXZlIGZvciBmZXcgY29kZSBtb2RpZmljYXRpb25zXG5cbiAgLy9cbiAgLy8gU2V0dXAgbGltaXRzIGlzIG5vdCBuZWNlc3NhcnkgYmVjYXVzZSBpbiBqcyB3ZSBzaG91bGQgbm90IHByZWFsbG9jYXRlIG1lbW9yeVxuICAvLyBmb3IgaW5mbGF0ZSB1c2UgY29uc3RhbnQgbGltaXQgaW4gNjU1MzYgYnl0ZXNcbiAgLy9cblxuICAvKiBzcGFjZSBhdCBleHRyYSAob25seSB3aGVuIHJlYWRpbmcgaGVhZGVyKSAqL1xuICAvLyB0aGlzLmV4dHJhX21heCAgPSAwO1xuICAvKiBwb2ludGVyIHRvIHplcm8tdGVybWluYXRlZCBmaWxlIG5hbWUgb3IgWl9OVUxMICovXG4gIHRoaXMubmFtZSAgICAgICA9ICcnO1xuICAvKiBzcGFjZSBhdCBuYW1lIChvbmx5IHdoZW4gcmVhZGluZyBoZWFkZXIpICovXG4gIC8vIHRoaXMubmFtZV9tYXggICA9IDA7XG4gIC8qIHBvaW50ZXIgdG8gemVyby10ZXJtaW5hdGVkIGNvbW1lbnQgb3IgWl9OVUxMICovXG4gIHRoaXMuY29tbWVudCAgICA9ICcnO1xuICAvKiBzcGFjZSBhdCBjb21tZW50IChvbmx5IHdoZW4gcmVhZGluZyBoZWFkZXIpICovXG4gIC8vIHRoaXMuY29tbV9tYXggICA9IDA7XG4gIC8qIHRydWUgaWYgdGhlcmUgd2FzIG9yIHdpbGwgYmUgYSBoZWFkZXIgY3JjICovXG4gIHRoaXMuaGNyYyAgICAgICA9IDA7XG4gIC8qIHRydWUgd2hlbiBkb25lIHJlYWRpbmcgZ3ppcCBoZWFkZXIgKG5vdCB1c2VkIHdoZW4gd3JpdGluZyBhIGd6aXAgZmlsZSkgKi9cbiAgdGhpcy5kb25lICAgICAgID0gZmFsc2U7XG59XG5cbnZhciBnemhlYWRlciA9IEdaaGVhZGVyO1xuXG5jb25zdCB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qIFB1YmxpYyBjb25zdGFudHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5jb25zdCB7XG4gIFpfTk9fRkxVU0gsIFpfRklOSVNILFxuICBaX09LLCBaX1NUUkVBTV9FTkQsIFpfTkVFRF9ESUNULCBaX1NUUkVBTV9FUlJPUiwgWl9EQVRBX0VSUk9SLCBaX01FTV9FUlJPUlxufSA9IGNvbnN0YW50cyQyO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cbi8qKlxuICogY2xhc3MgSW5mbGF0ZVxuICpcbiAqIEdlbmVyaWMgSlMtc3R5bGUgd3JhcHBlciBmb3IgemxpYiBjYWxscy4gSWYgeW91IGRvbid0IG5lZWRcbiAqIHN0cmVhbWluZyBiZWhhdmlvdXIgLSB1c2UgbW9yZSBzaW1wbGUgZnVuY3Rpb25zOiBbW2luZmxhdGVdXVxuICogYW5kIFtbaW5mbGF0ZVJhd11dLlxuICoqL1xuXG4vKiBpbnRlcm5hbFxuICogaW5mbGF0ZS5jaHVua3MgLT4gQXJyYXlcbiAqXG4gKiBDaHVua3Mgb2Ygb3V0cHV0IGRhdGEsIGlmIFtbSW5mbGF0ZSNvbkRhdGFdXSBub3Qgb3ZlcnJpZGRlbi5cbiAqKi9cblxuLyoqXG4gKiBJbmZsYXRlLnJlc3VsdCAtPiBVaW50OEFycmF5fFN0cmluZ1xuICpcbiAqIFVuY29tcHJlc3NlZCByZXN1bHQsIGdlbmVyYXRlZCBieSBkZWZhdWx0IFtbSW5mbGF0ZSNvbkRhdGFdXVxuICogYW5kIFtbSW5mbGF0ZSNvbkVuZF1dIGhhbmRsZXJzLiBGaWxsZWQgYWZ0ZXIgeW91IHB1c2ggbGFzdCBjaHVua1xuICogKGNhbGwgW1tJbmZsYXRlI3B1c2hdXSB3aXRoIGBaX0ZJTklTSGAgLyBgdHJ1ZWAgcGFyYW0pLlxuICoqL1xuXG4vKipcbiAqIEluZmxhdGUuZXJyIC0+IE51bWJlclxuICpcbiAqIEVycm9yIGNvZGUgYWZ0ZXIgaW5mbGF0ZSBmaW5pc2hlZC4gMCAoWl9PSykgb24gc3VjY2Vzcy5cbiAqIFNob3VsZCBiZSBjaGVja2VkIGlmIGJyb2tlbiBkYXRhIHBvc3NpYmxlLlxuICoqL1xuXG4vKipcbiAqIEluZmxhdGUubXNnIC0+IFN0cmluZ1xuICpcbiAqIEVycm9yIG1lc3NhZ2UsIGlmIFtbSW5mbGF0ZS5lcnJdXSAhPSAwXG4gKiovXG5cblxuLyoqXG4gKiBuZXcgSW5mbGF0ZShvcHRpb25zKVxuICogLSBvcHRpb25zIChPYmplY3QpOiB6bGliIGluZmxhdGUgb3B0aW9ucy5cbiAqXG4gKiBDcmVhdGVzIG5ldyBpbmZsYXRvciBpbnN0YW5jZSB3aXRoIHNwZWNpZmllZCBwYXJhbXMuIFRocm93cyBleGNlcHRpb25cbiAqIG9uIGJhZCBwYXJhbXMuIFN1cHBvcnRlZCBvcHRpb25zOlxuICpcbiAqIC0gYHdpbmRvd0JpdHNgXG4gKiAtIGBkaWN0aW9uYXJ5YFxuICpcbiAqIFtodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWRdKGh0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZClcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZXNlLlxuICpcbiAqIEFkZGl0aW9uYWwgb3B0aW9ucywgZm9yIGludGVybmFsIG5lZWRzOlxuICpcbiAqIC0gYGNodW5rU2l6ZWAgLSBzaXplIG9mIGdlbmVyYXRlZCBkYXRhIGNodW5rcyAoMTZLIGJ5IGRlZmF1bHQpXG4gKiAtIGByYXdgIChCb29sZWFuKSAtIGRvIHJhdyBpbmZsYXRlXG4gKiAtIGB0b2AgKFN0cmluZykgLSBpZiBlcXVhbCB0byAnc3RyaW5nJywgdGhlbiByZXN1bHQgd2lsbCBiZSBjb252ZXJ0ZWRcbiAqICAgZnJvbSB1dGY4IHRvIHV0ZjE2IChqYXZhc2NyaXB0KSBzdHJpbmcuIFdoZW4gc3RyaW5nIG91dHB1dCByZXF1ZXN0ZWQsXG4gKiAgIGNodW5rIGxlbmd0aCBjYW4gZGlmZmVyIGZyb20gYGNodW5rU2l6ZWAsIGRlcGVuZGluZyBvbiBjb250ZW50LlxuICpcbiAqIEJ5IGRlZmF1bHQsIHdoZW4gbm8gb3B0aW9ucyBzZXQsIGF1dG9kZXRlY3QgZGVmbGF0ZS9nemlwIGRhdGEgZm9ybWF0IHZpYVxuICogd3JhcHBlciBoZWFkZXIuXG4gKlxuICogIyMjIyMgRXhhbXBsZTpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBjb25zdCBwYWtvID0gcmVxdWlyZSgncGFrbycpXG4gKiBjb25zdCBjaHVuazEgPSBuZXcgVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKVxuICogY29uc3QgY2h1bmsyID0gbmV3IFVpbnQ4QXJyYXkoWzEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5XSk7XG4gKlxuICogY29uc3QgaW5mbGF0ZSA9IG5ldyBwYWtvLkluZmxhdGUoeyBsZXZlbDogM30pO1xuICpcbiAqIGluZmxhdGUucHVzaChjaHVuazEsIGZhbHNlKTtcbiAqIGluZmxhdGUucHVzaChjaHVuazIsIHRydWUpOyAgLy8gdHJ1ZSAtPiBsYXN0IGNodW5rXG4gKlxuICogaWYgKGluZmxhdGUuZXJyKSB7IHRocm93IG5ldyBFcnJvcihpbmZsYXRlLmVycik7IH1cbiAqXG4gKiBjb25zb2xlLmxvZyhpbmZsYXRlLnJlc3VsdCk7XG4gKiBgYGBcbiAqKi9cbmZ1bmN0aW9uIEluZmxhdGUkMShvcHRpb25zKSB7XG4gIHRoaXMub3B0aW9ucyA9IGNvbW1vbi5hc3NpZ24oe1xuICAgIGNodW5rU2l6ZTogMTAyNCAqIDY0LFxuICAgIHdpbmRvd0JpdHM6IDE1LFxuICAgIHRvOiAnJ1xuICB9LCBvcHRpb25zIHx8IHt9KTtcblxuICBjb25zdCBvcHQgPSB0aGlzLm9wdGlvbnM7XG5cbiAgLy8gRm9yY2Ugd2luZG93IHNpemUgZm9yIGByYXdgIGRhdGEsIGlmIG5vdCBzZXQgZGlyZWN0bHksXG4gIC8vIGJlY2F1c2Ugd2UgaGF2ZSBubyBoZWFkZXIgZm9yIGF1dG9kZXRlY3QuXG4gIGlmIChvcHQucmF3ICYmIChvcHQud2luZG93Qml0cyA+PSAwKSAmJiAob3B0LndpbmRvd0JpdHMgPCAxNikpIHtcbiAgICBvcHQud2luZG93Qml0cyA9IC1vcHQud2luZG93Qml0cztcbiAgICBpZiAob3B0LndpbmRvd0JpdHMgPT09IDApIHsgb3B0LndpbmRvd0JpdHMgPSAtMTU7IH1cbiAgfVxuXG4gIC8vIElmIGB3aW5kb3dCaXRzYCBub3QgZGVmaW5lZCAoYW5kIG1vZGUgbm90IHJhdykgLSBzZXQgYXV0b2RldGVjdCBmbGFnIGZvciBnemlwL2RlZmxhdGVcbiAgaWYgKChvcHQud2luZG93Qml0cyA+PSAwKSAmJiAob3B0LndpbmRvd0JpdHMgPCAxNikgJiZcbiAgICAgICEob3B0aW9ucyAmJiBvcHRpb25zLndpbmRvd0JpdHMpKSB7XG4gICAgb3B0LndpbmRvd0JpdHMgKz0gMzI7XG4gIH1cblxuICAvLyBHemlwIGhlYWRlciBoYXMgbm8gaW5mbyBhYm91dCB3aW5kb3dzIHNpemUsIHdlIGNhbiBkbyBhdXRvZGV0ZWN0IG9ubHlcbiAgLy8gZm9yIGRlZmxhdGUuIFNvLCBpZiB3aW5kb3cgc2l6ZSBub3Qgc2V0LCBmb3JjZSBpdCB0byBtYXggd2hlbiBnemlwIHBvc3NpYmxlXG4gIGlmICgob3B0LndpbmRvd0JpdHMgPiAxNSkgJiYgKG9wdC53aW5kb3dCaXRzIDwgNDgpKSB7XG4gICAgLy8gYml0IDMgKDE2KSAtPiBnemlwcGVkIGRhdGFcbiAgICAvLyBiaXQgNCAoMzIpIC0+IGF1dG9kZXRlY3QgZ3ppcC9kZWZsYXRlXG4gICAgaWYgKChvcHQud2luZG93Qml0cyAmIDE1KSA9PT0gMCkge1xuICAgICAgb3B0LndpbmRvd0JpdHMgfD0gMTU7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5lcnIgICAgPSAwOyAgICAgIC8vIGVycm9yIGNvZGUsIGlmIGhhcHBlbnMgKDAgPSBaX09LKVxuICB0aGlzLm1zZyAgICA9ICcnOyAgICAgLy8gZXJyb3IgbWVzc2FnZVxuICB0aGlzLmVuZGVkICA9IGZhbHNlOyAgLy8gdXNlZCB0byBhdm9pZCBtdWx0aXBsZSBvbkVuZCgpIGNhbGxzXG4gIHRoaXMuY2h1bmtzID0gW107ICAgICAvLyBjaHVua3Mgb2YgY29tcHJlc3NlZCBkYXRhXG5cbiAgdGhpcy5zdHJtICAgPSBuZXcgenN0cmVhbSgpO1xuICB0aGlzLnN0cm0uYXZhaWxfb3V0ID0gMDtcblxuICBsZXQgc3RhdHVzICA9IGluZmxhdGVfMSQyLmluZmxhdGVJbml0MihcbiAgICB0aGlzLnN0cm0sXG4gICAgb3B0LndpbmRvd0JpdHNcbiAgKTtcblxuICBpZiAoc3RhdHVzICE9PSBaX09LKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2VzW3N0YXR1c10pO1xuICB9XG5cbiAgdGhpcy5oZWFkZXIgPSBuZXcgZ3poZWFkZXIoKTtcblxuICBpbmZsYXRlXzEkMi5pbmZsYXRlR2V0SGVhZGVyKHRoaXMuc3RybSwgdGhpcy5oZWFkZXIpO1xuXG4gIC8vIFNldHVwIGRpY3Rpb25hcnlcbiAgaWYgKG9wdC5kaWN0aW9uYXJ5KSB7XG4gICAgLy8gQ29udmVydCBkYXRhIGlmIG5lZWRlZFxuICAgIGlmICh0eXBlb2Ygb3B0LmRpY3Rpb25hcnkgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHQuZGljdGlvbmFyeSA9IHN0cmluZ3Muc3RyaW5nMmJ1ZihvcHQuZGljdGlvbmFyeSk7XG4gICAgfSBlbHNlIGlmICh0b1N0cmluZy5jYWxsKG9wdC5kaWN0aW9uYXJ5KSA9PT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJykge1xuICAgICAgb3B0LmRpY3Rpb25hcnkgPSBuZXcgVWludDhBcnJheShvcHQuZGljdGlvbmFyeSk7XG4gICAgfVxuICAgIGlmIChvcHQucmF3KSB7IC8vSW4gcmF3IG1vZGUgd2UgbmVlZCB0byBzZXQgdGhlIGRpY3Rpb25hcnkgZWFybHlcbiAgICAgIHN0YXR1cyA9IGluZmxhdGVfMSQyLmluZmxhdGVTZXREaWN0aW9uYXJ5KHRoaXMuc3RybSwgb3B0LmRpY3Rpb25hcnkpO1xuICAgICAgaWYgKHN0YXR1cyAhPT0gWl9PSykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZXNbc3RhdHVzXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogSW5mbGF0ZSNwdXNoKGRhdGFbLCBmbHVzaF9tb2RlXSkgLT4gQm9vbGVhblxuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5QnVmZmVyKTogaW5wdXQgZGF0YVxuICogLSBmbHVzaF9tb2RlIChOdW1iZXJ8Qm9vbGVhbik6IDAuLjYgZm9yIGNvcnJlc3BvbmRpbmcgWl9OT19GTFVTSC4uWl9UUkVFXG4gKiAgIGZsdXNoIG1vZGVzLiBTZWUgY29uc3RhbnRzLiBTa2lwcGVkIG9yIGBmYWxzZWAgbWVhbnMgWl9OT19GTFVTSCxcbiAqICAgYHRydWVgIG1lYW5zIFpfRklOSVNILlxuICpcbiAqIFNlbmRzIGlucHV0IGRhdGEgdG8gaW5mbGF0ZSBwaXBlLCBnZW5lcmF0aW5nIFtbSW5mbGF0ZSNvbkRhdGFdXSBjYWxscyB3aXRoXG4gKiBuZXcgb3V0cHV0IGNodW5rcy4gUmV0dXJucyBgdHJ1ZWAgb24gc3VjY2Vzcy4gSWYgZW5kIG9mIHN0cmVhbSBkZXRlY3RlZCxcbiAqIFtbSW5mbGF0ZSNvbkVuZF1dIHdpbGwgYmUgY2FsbGVkLlxuICpcbiAqIGBmbHVzaF9tb2RlYCBpcyBub3QgbmVlZGVkIGZvciBub3JtYWwgb3BlcmF0aW9uLCBiZWNhdXNlIGVuZCBvZiBzdHJlYW1cbiAqIGRldGVjdGVkIGF1dG9tYXRpY2FsbHkuIFlvdSBtYXkgdHJ5IHRvIHVzZSBpdCBmb3IgYWR2YW5jZWQgdGhpbmdzLCBidXRcbiAqIHRoaXMgZnVuY3Rpb25hbGl0eSB3YXMgbm90IHRlc3RlZC5cbiAqXG4gKiBPbiBmYWlsIGNhbGwgW1tJbmZsYXRlI29uRW5kXV0gd2l0aCBlcnJvciBjb2RlIGFuZCByZXR1cm4gZmFsc2UuXG4gKlxuICogIyMjIyMgRXhhbXBsZVxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHB1c2goY2h1bmssIGZhbHNlKTsgLy8gcHVzaCBvbmUgb2YgZGF0YSBjaHVua3NcbiAqIC4uLlxuICogcHVzaChjaHVuaywgdHJ1ZSk7ICAvLyBwdXNoIGxhc3QgY2h1bmtcbiAqIGBgYFxuICoqL1xuSW5mbGF0ZSQxLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGRhdGEsIGZsdXNoX21vZGUpIHtcbiAgY29uc3Qgc3RybSA9IHRoaXMuc3RybTtcbiAgY29uc3QgY2h1bmtTaXplID0gdGhpcy5vcHRpb25zLmNodW5rU2l6ZTtcbiAgY29uc3QgZGljdGlvbmFyeSA9IHRoaXMub3B0aW9ucy5kaWN0aW9uYXJ5O1xuICBsZXQgc3RhdHVzLCBfZmx1c2hfbW9kZSwgbGFzdF9hdmFpbF9vdXQ7XG5cbiAgaWYgKHRoaXMuZW5kZWQpIHJldHVybiBmYWxzZTtcblxuICBpZiAoZmx1c2hfbW9kZSA9PT0gfn5mbHVzaF9tb2RlKSBfZmx1c2hfbW9kZSA9IGZsdXNoX21vZGU7XG4gIGVsc2UgX2ZsdXNoX21vZGUgPSBmbHVzaF9tb2RlID09PSB0cnVlID8gWl9GSU5JU0ggOiBaX05PX0ZMVVNIO1xuXG4gIC8vIENvbnZlcnQgZGF0YSBpZiBuZWVkZWRcbiAgaWYgKHRvU3RyaW5nLmNhbGwoZGF0YSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICBzdHJtLmlucHV0ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIH0gZWxzZSB7XG4gICAgc3RybS5pbnB1dCA9IGRhdGE7XG4gIH1cblxuICBzdHJtLm5leHRfaW4gPSAwO1xuICBzdHJtLmF2YWlsX2luID0gc3RybS5pbnB1dC5sZW5ndGg7XG5cbiAgZm9yICg7Oykge1xuICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgc3RybS5vdXRwdXQgPSBuZXcgVWludDhBcnJheShjaHVua1NpemUpO1xuICAgICAgc3RybS5uZXh0X291dCA9IDA7XG4gICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZTtcbiAgICB9XG5cbiAgICBzdGF0dXMgPSBpbmZsYXRlXzEkMi5pbmZsYXRlKHN0cm0sIF9mbHVzaF9tb2RlKTtcblxuICAgIGlmIChzdGF0dXMgPT09IFpfTkVFRF9ESUNUICYmIGRpY3Rpb25hcnkpIHtcbiAgICAgIHN0YXR1cyA9IGluZmxhdGVfMSQyLmluZmxhdGVTZXREaWN0aW9uYXJ5KHN0cm0sIGRpY3Rpb25hcnkpO1xuXG4gICAgICBpZiAoc3RhdHVzID09PSBaX09LKSB7XG4gICAgICAgIHN0YXR1cyA9IGluZmxhdGVfMSQyLmluZmxhdGUoc3RybSwgX2ZsdXNoX21vZGUpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0dXMgPT09IFpfREFUQV9FUlJPUikge1xuICAgICAgICAvLyBSZXBsYWNlIGNvZGUgd2l0aCBtb3JlIHZlcmJvc2VcbiAgICAgICAgc3RhdHVzID0gWl9ORUVEX0RJQ1Q7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gU2tpcCBzbnljIG1hcmtlcnMgaWYgbW9yZSBkYXRhIGZvbGxvd3MgYW5kIG5vdCByYXcgbW9kZVxuICAgIHdoaWxlIChzdHJtLmF2YWlsX2luID4gMCAmJlxuICAgICAgICAgICBzdGF0dXMgPT09IFpfU1RSRUFNX0VORCAmJlxuICAgICAgICAgICBzdHJtLnN0YXRlLndyYXAgPiAwICYmXG4gICAgICAgICAgIGRhdGFbc3RybS5uZXh0X2luXSAhPT0gMClcbiAgICB7XG4gICAgICBpbmZsYXRlXzEkMi5pbmZsYXRlUmVzZXQoc3RybSk7XG4gICAgICBzdGF0dXMgPSBpbmZsYXRlXzEkMi5pbmZsYXRlKHN0cm0sIF9mbHVzaF9tb2RlKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHN0YXR1cykge1xuICAgICAgY2FzZSBaX1NUUkVBTV9FUlJPUjpcbiAgICAgIGNhc2UgWl9EQVRBX0VSUk9SOlxuICAgICAgY2FzZSBaX05FRURfRElDVDpcbiAgICAgIGNhc2UgWl9NRU1fRVJST1I6XG4gICAgICAgIHRoaXMub25FbmQoc3RhdHVzKTtcbiAgICAgICAgdGhpcy5lbmRlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBSZW1lbWJlciByZWFsIGBhdmFpbF9vdXRgIHZhbHVlLCBiZWNhdXNlIHdlIG1heSBwYXRjaCBvdXQgYnVmZmVyIGNvbnRlbnRcbiAgICAvLyB0byBhbGlnbiB1dGY4IHN0cmluZ3MgYm91bmRhcmllcy5cbiAgICBsYXN0X2F2YWlsX291dCA9IHN0cm0uYXZhaWxfb3V0O1xuXG4gICAgaWYgKHN0cm0ubmV4dF9vdXQpIHtcbiAgICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCB8fCBzdGF0dXMgPT09IFpfU1RSRUFNX0VORCkge1xuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMudG8gPT09ICdzdHJpbmcnKSB7XG5cbiAgICAgICAgICBsZXQgbmV4dF9vdXRfdXRmOCA9IHN0cmluZ3MudXRmOGJvcmRlcihzdHJtLm91dHB1dCwgc3RybS5uZXh0X291dCk7XG5cbiAgICAgICAgICBsZXQgdGFpbCA9IHN0cm0ubmV4dF9vdXQgLSBuZXh0X291dF91dGY4O1xuICAgICAgICAgIGxldCB1dGY4c3RyID0gc3RyaW5ncy5idWYyc3RyaW5nKHN0cm0ub3V0cHV0LCBuZXh0X291dF91dGY4KTtcblxuICAgICAgICAgIC8vIG1vdmUgdGFpbCAmIHJlYWxpZ24gY291bnRlcnNcbiAgICAgICAgICBzdHJtLm5leHRfb3V0ID0gdGFpbDtcbiAgICAgICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZSAtIHRhaWw7XG4gICAgICAgICAgaWYgKHRhaWwpIHN0cm0ub3V0cHV0LnNldChzdHJtLm91dHB1dC5zdWJhcnJheShuZXh0X291dF91dGY4LCBuZXh0X291dF91dGY4ICsgdGFpbCksIDApO1xuXG4gICAgICAgICAgdGhpcy5vbkRhdGEodXRmOHN0cik7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm9uRGF0YShzdHJtLm91dHB1dC5sZW5ndGggPT09IHN0cm0ubmV4dF9vdXQgPyBzdHJtLm91dHB1dCA6IHN0cm0ub3V0cHV0LnN1YmFycmF5KDAsIHN0cm0ubmV4dF9vdXQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE11c3QgcmVwZWF0IGl0ZXJhdGlvbiBpZiBvdXQgYnVmZmVyIGlzIGZ1bGxcbiAgICBpZiAoc3RhdHVzID09PSBaX09LICYmIGxhc3RfYXZhaWxfb3V0ID09PSAwKSBjb250aW51ZTtcblxuICAgIC8vIEZpbmFsaXplIGlmIGVuZCBvZiBzdHJlYW0gcmVhY2hlZC5cbiAgICBpZiAoc3RhdHVzID09PSBaX1NUUkVBTV9FTkQpIHtcbiAgICAgIHN0YXR1cyA9IGluZmxhdGVfMSQyLmluZmxhdGVFbmQodGhpcy5zdHJtKTtcbiAgICAgIHRoaXMub25FbmQoc3RhdHVzKTtcbiAgICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHN0cm0uYXZhaWxfaW4gPT09IDApIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5cbi8qKlxuICogSW5mbGF0ZSNvbkRhdGEoY2h1bmspIC0+IFZvaWRcbiAqIC0gY2h1bmsgKFVpbnQ4QXJyYXl8U3RyaW5nKTogb3V0cHV0IGRhdGEuIFdoZW4gc3RyaW5nIG91dHB1dCByZXF1ZXN0ZWQsXG4gKiAgIGVhY2ggY2h1bmsgd2lsbCBiZSBzdHJpbmcuXG4gKlxuICogQnkgZGVmYXVsdCwgc3RvcmVzIGRhdGEgYmxvY2tzIGluIGBjaHVua3NbXWAgcHJvcGVydHkgYW5kIGdsdWVcbiAqIHRob3NlIGluIGBvbkVuZGAuIE92ZXJyaWRlIHRoaXMgaGFuZGxlciwgaWYgeW91IG5lZWQgYW5vdGhlciBiZWhhdmlvdXIuXG4gKiovXG5JbmZsYXRlJDEucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChjaHVuaykge1xuICB0aGlzLmNodW5rcy5wdXNoKGNodW5rKTtcbn07XG5cblxuLyoqXG4gKiBJbmZsYXRlI29uRW5kKHN0YXR1cykgLT4gVm9pZFxuICogLSBzdGF0dXMgKE51bWJlcik6IGluZmxhdGUgc3RhdHVzLiAwIChaX09LKSBvbiBzdWNjZXNzLFxuICogICBvdGhlciBpZiBub3QuXG4gKlxuICogQ2FsbGVkIGVpdGhlciBhZnRlciB5b3UgdGVsbCBpbmZsYXRlIHRoYXQgdGhlIGlucHV0IHN0cmVhbSBpc1xuICogY29tcGxldGUgKFpfRklOSVNIKS4gQnkgZGVmYXVsdCAtIGpvaW4gY29sbGVjdGVkIGNodW5rcyxcbiAqIGZyZWUgbWVtb3J5IGFuZCBmaWxsIGByZXN1bHRzYCAvIGBlcnJgIHByb3BlcnRpZXMuXG4gKiovXG5JbmZsYXRlJDEucHJvdG90eXBlLm9uRW5kID0gZnVuY3Rpb24gKHN0YXR1cykge1xuICAvLyBPbiBzdWNjZXNzIC0gam9pblxuICBpZiAoc3RhdHVzID09PSBaX09LKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy50byA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMucmVzdWx0ID0gdGhpcy5jaHVua3Muam9pbignJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVzdWx0ID0gY29tbW9uLmZsYXR0ZW5DaHVua3ModGhpcy5jaHVua3MpO1xuICAgIH1cbiAgfVxuICB0aGlzLmNodW5rcyA9IFtdO1xuICB0aGlzLmVyciA9IHN0YXR1cztcbiAgdGhpcy5tc2cgPSB0aGlzLnN0cm0ubXNnO1xufTtcblxuXG4vKipcbiAqIGluZmxhdGUoZGF0YVssIG9wdGlvbnNdKSAtPiBVaW50OEFycmF5fFN0cmluZ1xuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5QnVmZmVyKTogaW5wdXQgZGF0YSB0byBkZWNvbXByZXNzLlxuICogLSBvcHRpb25zIChPYmplY3QpOiB6bGliIGluZmxhdGUgb3B0aW9ucy5cbiAqXG4gKiBEZWNvbXByZXNzIGBkYXRhYCB3aXRoIGluZmxhdGUvdW5nemlwIGFuZCBgb3B0aW9uc2AuIEF1dG9kZXRlY3RcbiAqIGZvcm1hdCB2aWEgd3JhcHBlciBoZWFkZXIgYnkgZGVmYXVsdC4gVGhhdCdzIHdoeSB3ZSBkb24ndCBwcm92aWRlXG4gKiBzZXBhcmF0ZSBgdW5nemlwYCBtZXRob2QuXG4gKlxuICogU3VwcG9ydGVkIG9wdGlvbnMgYXJlOlxuICpcbiAqIC0gd2luZG93Qml0c1xuICpcbiAqIFtodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWRdKGh0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZClcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICpcbiAqIFN1Z2FyIChvcHRpb25zKTpcbiAqXG4gKiAtIGByYXdgIChCb29sZWFuKSAtIHNheSB0aGF0IHdlIHdvcmsgd2l0aCByYXcgc3RyZWFtLCBpZiB5b3UgZG9uJ3Qgd2lzaCB0byBzcGVjaWZ5XG4gKiAgIG5lZ2F0aXZlIHdpbmRvd0JpdHMgaW1wbGljaXRseS5cbiAqIC0gYHRvYCAoU3RyaW5nKSAtIGlmIGVxdWFsIHRvICdzdHJpbmcnLCB0aGVuIHJlc3VsdCB3aWxsIGJlIGNvbnZlcnRlZFxuICogICBmcm9tIHV0ZjggdG8gdXRmMTYgKGphdmFzY3JpcHQpIHN0cmluZy4gV2hlbiBzdHJpbmcgb3V0cHV0IHJlcXVlc3RlZCxcbiAqICAgY2h1bmsgbGVuZ3RoIGNhbiBkaWZmZXIgZnJvbSBgY2h1bmtTaXplYCwgZGVwZW5kaW5nIG9uIGNvbnRlbnQuXG4gKlxuICpcbiAqICMjIyMjIEV4YW1wbGU6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3QgcGFrbyA9IHJlcXVpcmUoJ3Bha28nKTtcbiAqIGNvbnN0IGlucHV0ID0gcGFrby5kZWZsYXRlKG5ldyBVaW50OEFycmF5KFsxLDIsMyw0LDUsNiw3LDgsOV0pKTtcbiAqIGxldCBvdXRwdXQ7XG4gKlxuICogdHJ5IHtcbiAqICAgb3V0cHV0ID0gcGFrby5pbmZsYXRlKGlucHV0KTtcbiAqIH0gY2F0Y2ggKGVycikge1xuICogICBjb25zb2xlLmxvZyhlcnIpO1xuICogfVxuICogYGBgXG4gKiovXG5mdW5jdGlvbiBpbmZsYXRlJDEoaW5wdXQsIG9wdGlvbnMpIHtcbiAgY29uc3QgaW5mbGF0b3IgPSBuZXcgSW5mbGF0ZSQxKG9wdGlvbnMpO1xuXG4gIGluZmxhdG9yLnB1c2goaW5wdXQpO1xuXG4gIC8vIFRoYXQgd2lsbCBuZXZlciBoYXBwZW5zLCBpZiB5b3UgZG9uJ3QgY2hlYXQgd2l0aCBvcHRpb25zIDopXG4gIGlmIChpbmZsYXRvci5lcnIpIHRocm93IGluZmxhdG9yLm1zZyB8fCBtZXNzYWdlc1tpbmZsYXRvci5lcnJdO1xuXG4gIHJldHVybiBpbmZsYXRvci5yZXN1bHQ7XG59XG5cblxuLyoqXG4gKiBpbmZsYXRlUmF3KGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheXxTdHJpbmdcbiAqIC0gZGF0YSAoVWludDhBcnJheXxBcnJheUJ1ZmZlcik6IGlucHV0IGRhdGEgdG8gZGVjb21wcmVzcy5cbiAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBpbmZsYXRlIG9wdGlvbnMuXG4gKlxuICogVGhlIHNhbWUgYXMgW1tpbmZsYXRlXV0sIGJ1dCBjcmVhdGVzIHJhdyBkYXRhLCB3aXRob3V0IHdyYXBwZXJcbiAqIChoZWFkZXIgYW5kIGFkbGVyMzIgY3JjKS5cbiAqKi9cbmZ1bmN0aW9uIGluZmxhdGVSYXckMShpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgb3B0aW9ucy5yYXcgPSB0cnVlO1xuICByZXR1cm4gaW5mbGF0ZSQxKGlucHV0LCBvcHRpb25zKTtcbn1cblxuXG4vKipcbiAqIHVuZ3ppcChkYXRhWywgb3B0aW9uc10pIC0+IFVpbnQ4QXJyYXl8U3RyaW5nXG4gKiAtIGRhdGEgKFVpbnQ4QXJyYXl8QXJyYXlCdWZmZXIpOiBpbnB1dCBkYXRhIHRvIGRlY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgaW5mbGF0ZSBvcHRpb25zLlxuICpcbiAqIEp1c3Qgc2hvcnRjdXQgdG8gW1tpbmZsYXRlXV0sIGJlY2F1c2UgaXQgYXV0b2RldGVjdHMgZm9ybWF0XG4gKiBieSBoZWFkZXIuY29udGVudC4gRG9uZSBmb3IgY29udmVuaWVuY2UuXG4gKiovXG5cblxudmFyIEluZmxhdGVfMSQxID0gSW5mbGF0ZSQxO1xudmFyIGluZmxhdGVfMiA9IGluZmxhdGUkMTtcbnZhciBpbmZsYXRlUmF3XzEkMSA9IGluZmxhdGVSYXckMTtcbnZhciB1bmd6aXAkMSA9IGluZmxhdGUkMTtcbnZhciBjb25zdGFudHMgPSBjb25zdGFudHMkMjtcblxudmFyIGluZmxhdGVfMSQxID0ge1xuXHRJbmZsYXRlOiBJbmZsYXRlXzEkMSxcblx0aW5mbGF0ZTogaW5mbGF0ZV8yLFxuXHRpbmZsYXRlUmF3OiBpbmZsYXRlUmF3XzEkMSxcblx0dW5nemlwOiB1bmd6aXAkMSxcblx0Y29uc3RhbnRzOiBjb25zdGFudHNcbn07XG5cbmNvbnN0IHsgRGVmbGF0ZSwgZGVmbGF0ZSwgZGVmbGF0ZVJhdywgZ3ppcCB9ID0gZGVmbGF0ZV8xJDE7XG5cbmNvbnN0IHsgSW5mbGF0ZSwgaW5mbGF0ZSwgaW5mbGF0ZVJhdywgdW5nemlwIH0gPSBpbmZsYXRlXzEkMTtcblxuXG5cbnZhciBEZWZsYXRlXzEgPSBEZWZsYXRlO1xudmFyIGRlZmxhdGVfMSA9IGRlZmxhdGU7XG52YXIgZGVmbGF0ZVJhd18xID0gZGVmbGF0ZVJhdztcbnZhciBnemlwXzEgPSBnemlwO1xudmFyIEluZmxhdGVfMSA9IEluZmxhdGU7XG52YXIgaW5mbGF0ZV8xID0gaW5mbGF0ZTtcbnZhciBpbmZsYXRlUmF3XzEgPSBpbmZsYXRlUmF3O1xudmFyIHVuZ3ppcF8xID0gdW5nemlwO1xudmFyIGNvbnN0YW50c18xID0gY29uc3RhbnRzJDI7XG5cbnZhciBwYWtvID0ge1xuXHREZWZsYXRlOiBEZWZsYXRlXzEsXG5cdGRlZmxhdGU6IGRlZmxhdGVfMSxcblx0ZGVmbGF0ZVJhdzogZGVmbGF0ZVJhd18xLFxuXHRnemlwOiBnemlwXzEsXG5cdEluZmxhdGU6IEluZmxhdGVfMSxcblx0aW5mbGF0ZTogaW5mbGF0ZV8xLFxuXHRpbmZsYXRlUmF3OiBpbmZsYXRlUmF3XzEsXG5cdHVuZ3ppcDogdW5nemlwXzEsXG5cdGNvbnN0YW50czogY29uc3RhbnRzXzFcbn07XG5cbmV4cG9ydCB7IERlZmxhdGVfMSBhcyBEZWZsYXRlLCBJbmZsYXRlXzEgYXMgSW5mbGF0ZSwgY29uc3RhbnRzXzEgYXMgY29uc3RhbnRzLCBwYWtvIGFzIGRlZmF1bHQsIGRlZmxhdGVfMSBhcyBkZWZsYXRlLCBkZWZsYXRlUmF3XzEgYXMgZGVmbGF0ZVJhdywgZ3ppcF8xIGFzIGd6aXAsIGluZmxhdGVfMSBhcyBpbmZsYXRlLCBpbmZsYXRlUmF3XzEgYXMgaW5mbGF0ZVJhdywgdW5nemlwXzEgYXMgdW5nemlwIH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file diff --git a/docs/vendors-node_modules_esptool-js_lib_targets_esp32p4_js.bundle.js b/docs/vendors-node_modules_esptool-js_lib_targets_esp32p4_js.bundle.js deleted file mode 100644 index 7fb9285..0000000 --- a/docs/vendors-node_modules_esptool-js_lib_targets_esp32p4_js.bundle.js +++ /dev/null @@ -1,401 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["vendors-node_modules_esptool-js_lib_targets_esp32p4_js"],{ - -/***/ "./node_modules/esptool-js/lib/targets/esp32.js": -/*!******************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32.js ***! - \******************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32ROM: () => (/* binding */ ESP32ROM) -/* harmony export */ }); -/* harmony import */ var _rom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./rom.js */ "./node_modules/esptool-js/lib/targets/rom.js"); - -class ESP32ROM extends _rom_js__WEBPACK_IMPORTED_MODULE_0__.ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32"; - this.IMAGE_CHIP_ID = 0; - this.EFUSE_RD_REG_BASE = 0x3ff5a000; - this.DR_REG_SYSCON_BASE = 0x3ff66000; - this.UART_CLKDIV_REG = 0x3ff40014; - this.UART_CLKDIV_MASK = 0xfffff; - this.UART_DATE_REG_ADDR = 0x60000078; - this.XTAL_CLK_DIVIDER = 1; - this.FLASH_SIZES = { - "1MB": 0x00, - "2MB": 0x10, - "4MB": 0x20, - "8MB": 0x30, - "16MB": 0x40, - }; - this.FLASH_WRITE_SIZE = 0x400; - this.BOOTLOADER_FLASH_OFFSET = 0x1000; - this.SPI_REG_BASE = 0x3ff42000; - this.SPI_USR_OFFS = 0x1c; - this.SPI_USR1_OFFS = 0x20; - this.SPI_USR2_OFFS = 0x24; - this.SPI_W0_OFFS = 0x80; - this.SPI_MOSI_DLEN_OFFS = 0x28; - this.SPI_MISO_DLEN_OFFS = 0x2c; - } - async readEfuse(loader, offset) { - const addr = this.EFUSE_RD_REG_BASE + 4 * offset; - loader.debug("Read efuse " + addr); - return await loader.readReg(addr); - } - async getPkgVersion(loader) { - const word3 = await this.readEfuse(loader, 3); - let pkgVersion = (word3 >> 9) & 0x07; - pkgVersion += ((word3 >> 2) & 0x1) << 3; - return pkgVersion; - } - async getChipRevision(loader) { - const word3 = await this.readEfuse(loader, 3); - const word5 = await this.readEfuse(loader, 5); - const apbCtlDate = await loader.readReg(this.DR_REG_SYSCON_BASE + 0x7c); - const revBit0 = (word3 >> 15) & 0x1; - const revBit1 = (word5 >> 20) & 0x1; - const revBit2 = (apbCtlDate >> 31) & 0x1; - if (revBit0 != 0) { - if (revBit1 != 0) { - if (revBit2 != 0) { - return 3; - } - else { - return 2; - } - } - else { - return 1; - } - } - return 0; - } - async getChipDescription(loader) { - const chipDesc = [ - "ESP32-D0WDQ6", - "ESP32-D0WD", - "ESP32-D2WD", - "", - "ESP32-U4WDH", - "ESP32-PICO-D4", - "ESP32-PICO-V3-02", - ]; - let chipName = ""; - const pkgVersion = await this.getPkgVersion(loader); - const chipRevision = await this.getChipRevision(loader); - const rev3 = chipRevision == 3; - const single_core = (await this.readEfuse(loader, 3)) & (1 << 0); - if (single_core != 0) { - chipDesc[0] = "ESP32-S0WDQ6"; - chipDesc[1] = "ESP32-S0WD"; - } - if (rev3) { - chipDesc[5] = "ESP32-PICO-V3"; - } - if (pkgVersion >= 0 && pkgVersion <= 6) { - chipName = chipDesc[pkgVersion]; - } - else { - chipName = "Unknown ESP32"; - } - if (rev3 && (pkgVersion === 0 || pkgVersion === 1)) { - chipName += "-V3"; - } - return chipName + " (revision " + chipRevision + ")"; - } - async getChipFeatures(loader) { - const features = ["Wi-Fi"]; - const word3 = await this.readEfuse(loader, 3); - const chipVerDisBt = word3 & (1 << 1); - if (chipVerDisBt === 0) { - features.push(" BT"); - } - const chipVerDisAppCpu = word3 & (1 << 0); - if (chipVerDisAppCpu !== 0) { - features.push(" Single Core"); - } - else { - features.push(" Dual Core"); - } - const chipCpuFreqRated = word3 & (1 << 13); - if (chipCpuFreqRated !== 0) { - const chipCpuFreqLow = word3 & (1 << 12); - if (chipCpuFreqLow !== 0) { - features.push(" 160MHz"); - } - else { - features.push(" 240MHz"); - } - } - const pkgVersion = await this.getPkgVersion(loader); - if ([2, 4, 5, 6].indexOf(pkgVersion) !== -1) { - features.push(" Embedded Flash"); - } - if (pkgVersion === 6) { - features.push(" Embedded PSRAM"); - } - const word4 = await this.readEfuse(loader, 4); - const adcVref = (word4 >> 8) & 0x1f; - if (adcVref !== 0) { - features.push(" VRef calibration in efuse"); - } - const blk3PartRes = (word3 >> 14) & 0x1; - if (blk3PartRes !== 0) { - features.push(" BLK3 partially reserved"); - } - const word6 = await this.readEfuse(loader, 6); - const codingScheme = word6 & 0x3; - const codingSchemeArr = ["None", "3/4", "Repeat (UNSUPPORTED)", "Invalid"]; - features.push(" Coding Scheme " + codingSchemeArr[codingScheme]); - return features; - } - async getCrystalFreq(loader) { - const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK; - const etsXtal = (loader.transport.baudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER; - let normXtal; - if (etsXtal > 33) { - normXtal = 40; - } - else { - normXtal = 26; - } - if (Math.abs(normXtal - etsXtal) > 1) { - loader.info("WARNING: Unsupported crystal in use"); - } - return normXtal; - } - _d2h(d) { - const h = (+d).toString(16); - return h.length === 1 ? "0" + h : h; - } - async readMac(loader) { - let mac0 = await this.readEfuse(loader, 1); - mac0 = mac0 >>> 0; - let mac1 = await this.readEfuse(loader, 2); - mac1 = mac1 >>> 0; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } -} - - -/***/ }), - -/***/ "./node_modules/esptool-js/lib/targets/esp32p4.js": -/*!********************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/esp32p4.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ ESP32P4ROM: () => (/* binding */ ESP32P4ROM) -/* harmony export */ }); -/* harmony import */ var _esp32_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./esp32.js */ "./node_modules/esptool-js/lib/targets/esp32.js"); - -class ESP32P4ROM extends _esp32_js__WEBPACK_IMPORTED_MODULE_0__.ESP32ROM { - constructor() { - super(...arguments); - this.CHIP_NAME = "ESP32-P4"; - this.IMAGE_CHIP_ID = 18; - this.IROM_MAP_START = 0x40000000; - this.IROM_MAP_END = 0x4c000000; - this.DROM_MAP_START = 0x40000000; - this.DROM_MAP_END = 0x4c000000; - this.BOOTLOADER_FLASH_OFFSET = 0x2000; // First 2 sectors are reserved for FE purposes - this.CHIP_DETECT_MAGIC_VALUE = [0x0, 0x0addbad0]; - this.UART_DATE_REG_ADDR = 0x500ca000 + 0x8c; - this.EFUSE_BASE = 0x5012d000; - this.EFUSE_BLOCK1_ADDR = this.EFUSE_BASE + 0x044; - this.MAC_EFUSE_REG = this.EFUSE_BASE + 0x044; - this.SPI_REG_BASE = 0x5008d000; // SPIMEM1 - this.SPI_USR_OFFS = 0x18; - this.SPI_USR1_OFFS = 0x1c; - this.SPI_USR2_OFFS = 0x20; - this.SPI_MOSI_DLEN_OFFS = 0x24; - this.SPI_MISO_DLEN_OFFS = 0x28; - this.SPI_W0_OFFS = 0x58; - this.EFUSE_RD_REG_BASE = this.EFUSE_BASE + 0x030; // BLOCK0 read base address - this.EFUSE_PURPOSE_KEY0_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY0_SHIFT = 24; - this.EFUSE_PURPOSE_KEY1_REG = this.EFUSE_BASE + 0x34; - this.EFUSE_PURPOSE_KEY1_SHIFT = 28; - this.EFUSE_PURPOSE_KEY2_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY2_SHIFT = 0; - this.EFUSE_PURPOSE_KEY3_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY3_SHIFT = 4; - this.EFUSE_PURPOSE_KEY4_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY4_SHIFT = 8; - this.EFUSE_PURPOSE_KEY5_REG = this.EFUSE_BASE + 0x38; - this.EFUSE_PURPOSE_KEY5_SHIFT = 12; - this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = this.EFUSE_RD_REG_BASE; - this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = 1 << 20; - this.EFUSE_SPI_BOOT_CRYPT_CNT_REG = this.EFUSE_BASE + 0x034; - this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK = 0x7 << 18; - this.EFUSE_SECURE_BOOT_EN_REG = this.EFUSE_BASE + 0x038; - this.EFUSE_SECURE_BOOT_EN_MASK = 1 << 20; - this.PURPOSE_VAL_XTS_AES256_KEY_1 = 2; - this.PURPOSE_VAL_XTS_AES256_KEY_2 = 3; - this.PURPOSE_VAL_XTS_AES128_KEY = 4; - this.SUPPORTS_ENCRYPTED_FLASH = true; - this.FLASH_ENCRYPTED_WRITE_ALIGN = 16; - this.MEMORY_MAP = [ - [0x00000000, 0x00010000, "PADDING"], - [0x40000000, 0x4c000000, "DROM"], - [0x4ff00000, 0x4ffa0000, "DRAM"], - [0x4ff00000, 0x4ffa0000, "BYTE_ACCESSIBLE"], - [0x4fc00000, 0x4fc20000, "DROM_MASK"], - [0x4fc00000, 0x4fc20000, "IROM_MASK"], - [0x40000000, 0x4c000000, "IROM"], - [0x4ff00000, 0x4ffa0000, "IRAM"], - [0x50108000, 0x50110000, "RTC_IRAM"], - [0x50108000, 0x50110000, "RTC_DRAM"], - [0x600fe000, 0x60100000, "MEM_INTERNAL2"], - ]; - this.UF2_FAMILY_ID = 0x3d308e94; - this.EFUSE_MAX_KEY = 5; - this.KEY_PURPOSES = { - 0: "USER/EMPTY", - 1: "ECDSA_KEY", - 2: "XTS_AES_256_KEY_1", - 3: "XTS_AES_256_KEY_2", - 4: "XTS_AES_128_KEY", - 5: "HMAC_DOWN_ALL", - 6: "HMAC_DOWN_JTAG", - 7: "HMAC_DOWN_DIGITAL_SIGNATURE", - 8: "HMAC_UP", - 9: "SECURE_BOOT_DIGEST0", - 10: "SECURE_BOOT_DIGEST1", - 11: "SECURE_BOOT_DIGEST2", - 12: "KM_INIT_KEY", - }; - } - async getPkgVersion(loader) { - const numWord = 2; - const addr = this.EFUSE_BLOCK1_ADDR + 4 * numWord; - const registerValue = await loader.readReg(addr); - return (registerValue >> 27) & 0x07; - } - async getMinorChipVersion(loader) { - const numWord = 2; - const addr = this.EFUSE_BLOCK1_ADDR + 4 * numWord; - const registerValue = await loader.readReg(addr); - return (registerValue >> 0) & 0x0f; - } - async getMajorChipVersion(loader) { - const numWord = 2; - const addr = this.EFUSE_BLOCK1_ADDR + 4 * numWord; - const registerValue = await loader.readReg(addr); - return (registerValue >> 4) & 0x03; - } - async getChipDescription(loader) { - const pkgVersion = await this.getPkgVersion(loader); - const chipName = pkgVersion === 0 ? "ESP32-P4" : "unknown ESP32-P4"; - const majorRev = await this.getMajorChipVersion(loader); - const minorRev = await this.getMinorChipVersion(loader); - return `${chipName} (revision v${majorRev}.${minorRev})`; - } - async getChipFeatures(loader) { - return ["High-Performance MCU"]; - } - async getCrystalFreq(loader) { - return 40; // ESP32P4 XTAL is fixed to 40MHz - } - async getFlashVoltage(loader) { - return; - } - async overrideVddsdio(loader) { - loader.debug("VDD_SDIO overrides are not supported for ESP32-P4"); - } - async readMac(loader) { - let mac0 = await loader.readReg(this.MAC_EFUSE_REG); - mac0 = mac0 >>> 0; - let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4); - mac1 = (mac1 >>> 0) & 0x0000ffff; - const mac = new Uint8Array(6); - mac[0] = (mac1 >> 8) & 0xff; - mac[1] = mac1 & 0xff; - mac[2] = (mac0 >> 24) & 0xff; - mac[3] = (mac0 >> 16) & 0xff; - mac[4] = (mac0 >> 8) & 0xff; - mac[5] = mac0 & 0xff; - return (this._d2h(mac[0]) + - ":" + - this._d2h(mac[1]) + - ":" + - this._d2h(mac[2]) + - ":" + - this._d2h(mac[3]) + - ":" + - this._d2h(mac[4]) + - ":" + - this._d2h(mac[5])); - } - async getFlashCryptConfig(loader) { - return; // doesn't exist on ESP32-P4 - } - async getSecureBootEnabled(laoder) { - const registerValue = await laoder.readReg(this.EFUSE_SECURE_BOOT_EN_REG); - return registerValue & this.EFUSE_SECURE_BOOT_EN_MASK; - } - async getKeyBlockPurpose(loader, keyBlock) { - if (keyBlock < 0 || keyBlock > this.EFUSE_MAX_KEY) { - loader.debug(`Valid key block numbers must be in range 0-${this.EFUSE_MAX_KEY}`); - return; - } - const regShiftDictionary = [ - [this.EFUSE_PURPOSE_KEY0_REG, this.EFUSE_PURPOSE_KEY0_SHIFT], - [this.EFUSE_PURPOSE_KEY1_REG, this.EFUSE_PURPOSE_KEY1_SHIFT], - [this.EFUSE_PURPOSE_KEY2_REG, this.EFUSE_PURPOSE_KEY2_SHIFT], - [this.EFUSE_PURPOSE_KEY3_REG, this.EFUSE_PURPOSE_KEY3_SHIFT], - [this.EFUSE_PURPOSE_KEY4_REG, this.EFUSE_PURPOSE_KEY4_SHIFT], - [this.EFUSE_PURPOSE_KEY5_REG, this.EFUSE_PURPOSE_KEY5_SHIFT], - ]; - const [reg, shift] = regShiftDictionary[keyBlock]; - const registerValue = await loader.readReg(reg); - return (registerValue >> shift) & 0xf; - } - async isFlashEncryptionKeyValid(loader) { - const purposes = []; - for (let i = 0; i <= this.EFUSE_MAX_KEY; i++) { - const purpose = await this.getKeyBlockPurpose(loader, i); - purposes.push(purpose); - } - const isXtsAes128Key = purposes.find((p) => p === this.PURPOSE_VAL_XTS_AES128_KEY); - if (typeof isXtsAes128Key !== undefined) { - return true; - } - const isXtsAes256Key1 = purposes.find((p) => p === this.PURPOSE_VAL_XTS_AES256_KEY_1); - const isXtsAes256Key2 = purposes.find((p) => p === this.PURPOSE_VAL_XTS_AES256_KEY_2); - if (typeof isXtsAes256Key1 !== undefined && typeof isXtsAes256Key2 !== undefined) { - return true; - } - return false; - } -} - - -/***/ }) - -}]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVuZG9ycy1ub2RlX21vZHVsZXNfZXNwdG9vbC1qc19saWJfdGFyZ2V0c19lc3AzMnA0X2pzLmJ1bmRsZS5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUErQjtBQUN4Qix1QkFBdUIsd0NBQUc7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FDeExzQztBQUMvQix5QkFBeUIsK0NBQVE7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRDtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLFVBQVUsYUFBYSxTQUFTLEdBQUcsU0FBUztBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1RUFBdUUsbUJBQW1CO0FBQzFGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHlCQUF5QjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9UYWN0aWxpdHkgV2ViIEluc3RhbGxlci8uL25vZGVfbW9kdWxlcy9lc3B0b29sLWpzL2xpYi90YXJnZXRzL2VzcDMyLmpzIiwid2VicGFjazovL1RhY3RpbGl0eSBXZWIgSW5zdGFsbGVyLy4vbm9kZV9tb2R1bGVzL2VzcHRvb2wtanMvbGliL3RhcmdldHMvZXNwMzJwNC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBST00gfSBmcm9tIFwiLi9yb20uanNcIjtcbmV4cG9ydCBjbGFzcyBFU1AzMlJPTSBleHRlbmRzIFJPTSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuQ0hJUF9OQU1FID0gXCJFU1AzMlwiO1xuICAgICAgICB0aGlzLklNQUdFX0NISVBfSUQgPSAwO1xuICAgICAgICB0aGlzLkVGVVNFX1JEX1JFR19CQVNFID0gMHgzZmY1YTAwMDtcbiAgICAgICAgdGhpcy5EUl9SRUdfU1lTQ09OX0JBU0UgPSAweDNmZjY2MDAwO1xuICAgICAgICB0aGlzLlVBUlRfQ0xLRElWX1JFRyA9IDB4M2ZmNDAwMTQ7XG4gICAgICAgIHRoaXMuVUFSVF9DTEtESVZfTUFTSyA9IDB4ZmZmZmY7XG4gICAgICAgIHRoaXMuVUFSVF9EQVRFX1JFR19BRERSID0gMHg2MDAwMDA3ODtcbiAgICAgICAgdGhpcy5YVEFMX0NMS19ESVZJREVSID0gMTtcbiAgICAgICAgdGhpcy5GTEFTSF9TSVpFUyA9IHtcbiAgICAgICAgICAgIFwiMU1CXCI6IDB4MDAsXG4gICAgICAgICAgICBcIjJNQlwiOiAweDEwLFxuICAgICAgICAgICAgXCI0TUJcIjogMHgyMCxcbiAgICAgICAgICAgIFwiOE1CXCI6IDB4MzAsXG4gICAgICAgICAgICBcIjE2TUJcIjogMHg0MCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5GTEFTSF9XUklURV9TSVpFID0gMHg0MDA7XG4gICAgICAgIHRoaXMuQk9PVExPQURFUl9GTEFTSF9PRkZTRVQgPSAweDEwMDA7XG4gICAgICAgIHRoaXMuU1BJX1JFR19CQVNFID0gMHgzZmY0MjAwMDtcbiAgICAgICAgdGhpcy5TUElfVVNSX09GRlMgPSAweDFjO1xuICAgICAgICB0aGlzLlNQSV9VU1IxX09GRlMgPSAweDIwO1xuICAgICAgICB0aGlzLlNQSV9VU1IyX09GRlMgPSAweDI0O1xuICAgICAgICB0aGlzLlNQSV9XMF9PRkZTID0gMHg4MDtcbiAgICAgICAgdGhpcy5TUElfTU9TSV9ETEVOX09GRlMgPSAweDI4O1xuICAgICAgICB0aGlzLlNQSV9NSVNPX0RMRU5fT0ZGUyA9IDB4MmM7XG4gICAgfVxuICAgIGFzeW5jIHJlYWRFZnVzZShsb2FkZXIsIG9mZnNldCkge1xuICAgICAgICBjb25zdCBhZGRyID0gdGhpcy5FRlVTRV9SRF9SRUdfQkFTRSArIDQgKiBvZmZzZXQ7XG4gICAgICAgIGxvYWRlci5kZWJ1ZyhcIlJlYWQgZWZ1c2UgXCIgKyBhZGRyKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGxvYWRlci5yZWFkUmVnKGFkZHIpO1xuICAgIH1cbiAgICBhc3luYyBnZXRQa2dWZXJzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCB3b3JkMyA9IGF3YWl0IHRoaXMucmVhZEVmdXNlKGxvYWRlciwgMyk7XG4gICAgICAgIGxldCBwa2dWZXJzaW9uID0gKHdvcmQzID4+IDkpICYgMHgwNztcbiAgICAgICAgcGtnVmVyc2lvbiArPSAoKHdvcmQzID4+IDIpICYgMHgxKSA8PCAzO1xuICAgICAgICByZXR1cm4gcGtnVmVyc2lvbjtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcFJldmlzaW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCB3b3JkMyA9IGF3YWl0IHRoaXMucmVhZEVmdXNlKGxvYWRlciwgMyk7XG4gICAgICAgIGNvbnN0IHdvcmQ1ID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCA1KTtcbiAgICAgICAgY29uc3QgYXBiQ3RsRGF0ZSA9IGF3YWl0IGxvYWRlci5yZWFkUmVnKHRoaXMuRFJfUkVHX1NZU0NPTl9CQVNFICsgMHg3Yyk7XG4gICAgICAgIGNvbnN0IHJldkJpdDAgPSAod29yZDMgPj4gMTUpICYgMHgxO1xuICAgICAgICBjb25zdCByZXZCaXQxID0gKHdvcmQ1ID4+IDIwKSAmIDB4MTtcbiAgICAgICAgY29uc3QgcmV2Qml0MiA9IChhcGJDdGxEYXRlID4+IDMxKSAmIDB4MTtcbiAgICAgICAgaWYgKHJldkJpdDAgIT0gMCkge1xuICAgICAgICAgICAgaWYgKHJldkJpdDEgIT0gMCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXZCaXQyICE9IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Q2hpcERlc2NyaXB0aW9uKGxvYWRlcikge1xuICAgICAgICBjb25zdCBjaGlwRGVzYyA9IFtcbiAgICAgICAgICAgIFwiRVNQMzItRDBXRFE2XCIsXG4gICAgICAgICAgICBcIkVTUDMyLUQwV0RcIixcbiAgICAgICAgICAgIFwiRVNQMzItRDJXRFwiLFxuICAgICAgICAgICAgXCJcIixcbiAgICAgICAgICAgIFwiRVNQMzItVTRXREhcIixcbiAgICAgICAgICAgIFwiRVNQMzItUElDTy1ENFwiLFxuICAgICAgICAgICAgXCJFU1AzMi1QSUNPLVYzLTAyXCIsXG4gICAgICAgIF07XG4gICAgICAgIGxldCBjaGlwTmFtZSA9IFwiXCI7XG4gICAgICAgIGNvbnN0IHBrZ1ZlcnNpb24gPSBhd2FpdCB0aGlzLmdldFBrZ1ZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgY29uc3QgY2hpcFJldmlzaW9uID0gYXdhaXQgdGhpcy5nZXRDaGlwUmV2aXNpb24obG9hZGVyKTtcbiAgICAgICAgY29uc3QgcmV2MyA9IGNoaXBSZXZpc2lvbiA9PSAzO1xuICAgICAgICBjb25zdCBzaW5nbGVfY29yZSA9IChhd2FpdCB0aGlzLnJlYWRFZnVzZShsb2FkZXIsIDMpKSAmICgxIDw8IDApO1xuICAgICAgICBpZiAoc2luZ2xlX2NvcmUgIT0gMCkge1xuICAgICAgICAgICAgY2hpcERlc2NbMF0gPSBcIkVTUDMyLVMwV0RRNlwiO1xuICAgICAgICAgICAgY2hpcERlc2NbMV0gPSBcIkVTUDMyLVMwV0RcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmV2Mykge1xuICAgICAgICAgICAgY2hpcERlc2NbNV0gPSBcIkVTUDMyLVBJQ08tVjNcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGtnVmVyc2lvbiA+PSAwICYmIHBrZ1ZlcnNpb24gPD0gNikge1xuICAgICAgICAgICAgY2hpcE5hbWUgPSBjaGlwRGVzY1twa2dWZXJzaW9uXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNoaXBOYW1lID0gXCJVbmtub3duIEVTUDMyXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJldjMgJiYgKHBrZ1ZlcnNpb24gPT09IDAgfHwgcGtnVmVyc2lvbiA9PT0gMSkpIHtcbiAgICAgICAgICAgIGNoaXBOYW1lICs9IFwiLVYzXCI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNoaXBOYW1lICsgXCIgKHJldmlzaW9uIFwiICsgY2hpcFJldmlzaW9uICsgXCIpXCI7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBGZWF0dXJlcyhsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgZmVhdHVyZXMgPSBbXCJXaS1GaVwiXTtcbiAgICAgICAgY29uc3Qgd29yZDMgPSBhd2FpdCB0aGlzLnJlYWRFZnVzZShsb2FkZXIsIDMpO1xuICAgICAgICBjb25zdCBjaGlwVmVyRGlzQnQgPSB3b3JkMyAmICgxIDw8IDEpO1xuICAgICAgICBpZiAoY2hpcFZlckRpc0J0ID09PSAwKSB7XG4gICAgICAgICAgICBmZWF0dXJlcy5wdXNoKFwiIEJUXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaXBWZXJEaXNBcHBDcHUgPSB3b3JkMyAmICgxIDw8IDApO1xuICAgICAgICBpZiAoY2hpcFZlckRpc0FwcENwdSAhPT0gMCkge1xuICAgICAgICAgICAgZmVhdHVyZXMucHVzaChcIiBTaW5nbGUgQ29yZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goXCIgRHVhbCBDb3JlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaXBDcHVGcmVxUmF0ZWQgPSB3b3JkMyAmICgxIDw8IDEzKTtcbiAgICAgICAgaWYgKGNoaXBDcHVGcmVxUmF0ZWQgIT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGNoaXBDcHVGcmVxTG93ID0gd29yZDMgJiAoMSA8PCAxMik7XG4gICAgICAgICAgICBpZiAoY2hpcENwdUZyZXFMb3cgIT09IDApIHtcbiAgICAgICAgICAgICAgICBmZWF0dXJlcy5wdXNoKFwiIDE2ME1IelwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goXCIgMjQwTUh6XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBrZ1ZlcnNpb24gPSBhd2FpdCB0aGlzLmdldFBrZ1ZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgaWYgKFsyLCA0LCA1LCA2XS5pbmRleE9mKHBrZ1ZlcnNpb24pICE9PSAtMSkge1xuICAgICAgICAgICAgZmVhdHVyZXMucHVzaChcIiBFbWJlZGRlZCBGbGFzaFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGtnVmVyc2lvbiA9PT0gNikge1xuICAgICAgICAgICAgZmVhdHVyZXMucHVzaChcIiBFbWJlZGRlZCBQU1JBTVwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3b3JkNCA9IGF3YWl0IHRoaXMucmVhZEVmdXNlKGxvYWRlciwgNCk7XG4gICAgICAgIGNvbnN0IGFkY1ZyZWYgPSAod29yZDQgPj4gOCkgJiAweDFmO1xuICAgICAgICBpZiAoYWRjVnJlZiAhPT0gMCkge1xuICAgICAgICAgICAgZmVhdHVyZXMucHVzaChcIiBWUmVmIGNhbGlicmF0aW9uIGluIGVmdXNlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJsazNQYXJ0UmVzID0gKHdvcmQzID4+IDE0KSAmIDB4MTtcbiAgICAgICAgaWYgKGJsazNQYXJ0UmVzICE9PSAwKSB7XG4gICAgICAgICAgICBmZWF0dXJlcy5wdXNoKFwiIEJMSzMgcGFydGlhbGx5IHJlc2VydmVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdvcmQ2ID0gYXdhaXQgdGhpcy5yZWFkRWZ1c2UobG9hZGVyLCA2KTtcbiAgICAgICAgY29uc3QgY29kaW5nU2NoZW1lID0gd29yZDYgJiAweDM7XG4gICAgICAgIGNvbnN0IGNvZGluZ1NjaGVtZUFyciA9IFtcIk5vbmVcIiwgXCIzLzRcIiwgXCJSZXBlYXQgKFVOU1VQUE9SVEVEKVwiLCBcIkludmFsaWRcIl07XG4gICAgICAgIGZlYXR1cmVzLnB1c2goXCIgQ29kaW5nIFNjaGVtZSBcIiArIGNvZGluZ1NjaGVtZUFycltjb2RpbmdTY2hlbWVdKTtcbiAgICAgICAgcmV0dXJuIGZlYXR1cmVzO1xuICAgIH1cbiAgICBhc3luYyBnZXRDcnlzdGFsRnJlcShsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgdWFydERpdiA9IChhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLlVBUlRfQ0xLRElWX1JFRykpICYgdGhpcy5VQVJUX0NMS0RJVl9NQVNLO1xuICAgICAgICBjb25zdCBldHNYdGFsID0gKGxvYWRlci50cmFuc3BvcnQuYmF1ZHJhdGUgKiB1YXJ0RGl2KSAvIDEwMDAwMDAgLyB0aGlzLlhUQUxfQ0xLX0RJVklERVI7XG4gICAgICAgIGxldCBub3JtWHRhbDtcbiAgICAgICAgaWYgKGV0c1h0YWwgPiAzMykge1xuICAgICAgICAgICAgbm9ybVh0YWwgPSA0MDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG5vcm1YdGFsID0gMjY7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKE1hdGguYWJzKG5vcm1YdGFsIC0gZXRzWHRhbCkgPiAxKSB7XG4gICAgICAgICAgICBsb2FkZXIuaW5mbyhcIldBUk5JTkc6IFVuc3VwcG9ydGVkIGNyeXN0YWwgaW4gdXNlXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub3JtWHRhbDtcbiAgICB9XG4gICAgX2QyaChkKSB7XG4gICAgICAgIGNvbnN0IGggPSAoK2QpLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgcmV0dXJuIGgubGVuZ3RoID09PSAxID8gXCIwXCIgKyBoIDogaDtcbiAgICB9XG4gICAgYXN5bmMgcmVhZE1hYyhsb2FkZXIpIHtcbiAgICAgICAgbGV0IG1hYzAgPSBhd2FpdCB0aGlzLnJlYWRFZnVzZShsb2FkZXIsIDEpO1xuICAgICAgICBtYWMwID0gbWFjMCA+Pj4gMDtcbiAgICAgICAgbGV0IG1hYzEgPSBhd2FpdCB0aGlzLnJlYWRFZnVzZShsb2FkZXIsIDIpO1xuICAgICAgICBtYWMxID0gbWFjMSA+Pj4gMDtcbiAgICAgICAgY29uc3QgbWFjID0gbmV3IFVpbnQ4QXJyYXkoNik7XG4gICAgICAgIG1hY1swXSA9IChtYWMxID4+IDgpICYgMHhmZjtcbiAgICAgICAgbWFjWzFdID0gbWFjMSAmIDB4ZmY7XG4gICAgICAgIG1hY1syXSA9IChtYWMwID4+IDI0KSAmIDB4ZmY7XG4gICAgICAgIG1hY1szXSA9IChtYWMwID4+IDE2KSAmIDB4ZmY7XG4gICAgICAgIG1hY1s0XSA9IChtYWMwID4+IDgpICYgMHhmZjtcbiAgICAgICAgbWFjWzVdID0gbWFjMCAmIDB4ZmY7XG4gICAgICAgIHJldHVybiAodGhpcy5fZDJoKG1hY1swXSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1sxXSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1syXSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1szXSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1s0XSkgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5fZDJoKG1hY1s1XSkpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEVTUDMyUk9NIH0gZnJvbSBcIi4vZXNwMzIuanNcIjtcbmV4cG9ydCBjbGFzcyBFU1AzMlA0Uk9NIGV4dGVuZHMgRVNQMzJST00ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLkNISVBfTkFNRSA9IFwiRVNQMzItUDRcIjtcbiAgICAgICAgdGhpcy5JTUFHRV9DSElQX0lEID0gMTg7XG4gICAgICAgIHRoaXMuSVJPTV9NQVBfU1RBUlQgPSAweDQwMDAwMDAwO1xuICAgICAgICB0aGlzLklST01fTUFQX0VORCA9IDB4NGMwMDAwMDA7XG4gICAgICAgIHRoaXMuRFJPTV9NQVBfU1RBUlQgPSAweDQwMDAwMDAwO1xuICAgICAgICB0aGlzLkRST01fTUFQX0VORCA9IDB4NGMwMDAwMDA7XG4gICAgICAgIHRoaXMuQk9PVExPQURFUl9GTEFTSF9PRkZTRVQgPSAweDIwMDA7IC8vIEZpcnN0IDIgc2VjdG9ycyBhcmUgcmVzZXJ2ZWQgZm9yIEZFIHB1cnBvc2VzXG4gICAgICAgIHRoaXMuQ0hJUF9ERVRFQ1RfTUFHSUNfVkFMVUUgPSBbMHgwLCAweDBhZGRiYWQwXTtcbiAgICAgICAgdGhpcy5VQVJUX0RBVEVfUkVHX0FERFIgPSAweDUwMGNhMDAwICsgMHg4YztcbiAgICAgICAgdGhpcy5FRlVTRV9CQVNFID0gMHg1MDEyZDAwMDtcbiAgICAgICAgdGhpcy5FRlVTRV9CTE9DSzFfQUREUiA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDQ0O1xuICAgICAgICB0aGlzLk1BQ19FRlVTRV9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDA0NDtcbiAgICAgICAgdGhpcy5TUElfUkVHX0JBU0UgPSAweDUwMDhkMDAwOyAvLyBTUElNRU0xXG4gICAgICAgIHRoaXMuU1BJX1VTUl9PRkZTID0gMHgxODtcbiAgICAgICAgdGhpcy5TUElfVVNSMV9PRkZTID0gMHgxYztcbiAgICAgICAgdGhpcy5TUElfVVNSMl9PRkZTID0gMHgyMDtcbiAgICAgICAgdGhpcy5TUElfTU9TSV9ETEVOX09GRlMgPSAweDI0O1xuICAgICAgICB0aGlzLlNQSV9NSVNPX0RMRU5fT0ZGUyA9IDB4Mjg7XG4gICAgICAgIHRoaXMuU1BJX1cwX09GRlMgPSAweDU4O1xuICAgICAgICB0aGlzLkVGVVNFX1JEX1JFR19CQVNFID0gdGhpcy5FRlVTRV9CQVNFICsgMHgwMzA7IC8vIEJMT0NLMCByZWFkIGJhc2UgYWRkcmVzc1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMF9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMF9TSElGVCA9IDI0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMV9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM0O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMV9TSElGVCA9IDI4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMl9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZMl9TSElGVCA9IDA7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkzX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4Mzg7XG4gICAgICAgIHRoaXMuRUZVU0VfUFVSUE9TRV9LRVkzX1NISUZUID0gNDtcbiAgICAgICAgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTRfUkVHID0gdGhpcy5FRlVTRV9CQVNFICsgMHgzODtcbiAgICAgICAgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTRfU0hJRlQgPSA4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZNV9SRUcgPSB0aGlzLkVGVVNFX0JBU0UgKyAweDM4O1xuICAgICAgICB0aGlzLkVGVVNFX1BVUlBPU0VfS0VZNV9TSElGVCA9IDEyO1xuICAgICAgICB0aGlzLkVGVVNFX0RJU19ET1dOTE9BRF9NQU5VQUxfRU5DUllQVF9SRUcgPSB0aGlzLkVGVVNFX1JEX1JFR19CQVNFO1xuICAgICAgICB0aGlzLkVGVVNFX0RJU19ET1dOTE9BRF9NQU5VQUxfRU5DUllQVCA9IDEgPDwgMjA7XG4gICAgICAgIHRoaXMuRUZVU0VfU1BJX0JPT1RfQ1JZUFRfQ05UX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDM0O1xuICAgICAgICB0aGlzLkVGVVNFX1NQSV9CT09UX0NSWVBUX0NOVF9NQVNLID0gMHg3IDw8IDE4O1xuICAgICAgICB0aGlzLkVGVVNFX1NFQ1VSRV9CT09UX0VOX1JFRyA9IHRoaXMuRUZVU0VfQkFTRSArIDB4MDM4O1xuICAgICAgICB0aGlzLkVGVVNFX1NFQ1VSRV9CT09UX0VOX01BU0sgPSAxIDw8IDIwO1xuICAgICAgICB0aGlzLlBVUlBPU0VfVkFMX1hUU19BRVMyNTZfS0VZXzEgPSAyO1xuICAgICAgICB0aGlzLlBVUlBPU0VfVkFMX1hUU19BRVMyNTZfS0VZXzIgPSAzO1xuICAgICAgICB0aGlzLlBVUlBPU0VfVkFMX1hUU19BRVMxMjhfS0VZID0gNDtcbiAgICAgICAgdGhpcy5TVVBQT1JUU19FTkNSWVBURURfRkxBU0ggPSB0cnVlO1xuICAgICAgICB0aGlzLkZMQVNIX0VOQ1JZUFRFRF9XUklURV9BTElHTiA9IDE2O1xuICAgICAgICB0aGlzLk1FTU9SWV9NQVAgPSBbXG4gICAgICAgICAgICBbMHgwMDAwMDAwMCwgMHgwMDAxMDAwMCwgXCJQQURESU5HXCJdLFxuICAgICAgICAgICAgWzB4NDAwMDAwMDAsIDB4NGMwMDAwMDAsIFwiRFJPTVwiXSxcbiAgICAgICAgICAgIFsweDRmZjAwMDAwLCAweDRmZmEwMDAwLCBcIkRSQU1cIl0sXG4gICAgICAgICAgICBbMHg0ZmYwMDAwMCwgMHg0ZmZhMDAwMCwgXCJCWVRFX0FDQ0VTU0lCTEVcIl0sXG4gICAgICAgICAgICBbMHg0ZmMwMDAwMCwgMHg0ZmMyMDAwMCwgXCJEUk9NX01BU0tcIl0sXG4gICAgICAgICAgICBbMHg0ZmMwMDAwMCwgMHg0ZmMyMDAwMCwgXCJJUk9NX01BU0tcIl0sXG4gICAgICAgICAgICBbMHg0MDAwMDAwMCwgMHg0YzAwMDAwMCwgXCJJUk9NXCJdLFxuICAgICAgICAgICAgWzB4NGZmMDAwMDAsIDB4NGZmYTAwMDAsIFwiSVJBTVwiXSxcbiAgICAgICAgICAgIFsweDUwMTA4MDAwLCAweDUwMTEwMDAwLCBcIlJUQ19JUkFNXCJdLFxuICAgICAgICAgICAgWzB4NTAxMDgwMDAsIDB4NTAxMTAwMDAsIFwiUlRDX0RSQU1cIl0sXG4gICAgICAgICAgICBbMHg2MDBmZTAwMCwgMHg2MDEwMDAwMCwgXCJNRU1fSU5URVJOQUwyXCJdLFxuICAgICAgICBdO1xuICAgICAgICB0aGlzLlVGMl9GQU1JTFlfSUQgPSAweDNkMzA4ZTk0O1xuICAgICAgICB0aGlzLkVGVVNFX01BWF9LRVkgPSA1O1xuICAgICAgICB0aGlzLktFWV9QVVJQT1NFUyA9IHtcbiAgICAgICAgICAgIDA6IFwiVVNFUi9FTVBUWVwiLFxuICAgICAgICAgICAgMTogXCJFQ0RTQV9LRVlcIixcbiAgICAgICAgICAgIDI6IFwiWFRTX0FFU18yNTZfS0VZXzFcIixcbiAgICAgICAgICAgIDM6IFwiWFRTX0FFU18yNTZfS0VZXzJcIixcbiAgICAgICAgICAgIDQ6IFwiWFRTX0FFU18xMjhfS0VZXCIsXG4gICAgICAgICAgICA1OiBcIkhNQUNfRE9XTl9BTExcIixcbiAgICAgICAgICAgIDY6IFwiSE1BQ19ET1dOX0pUQUdcIixcbiAgICAgICAgICAgIDc6IFwiSE1BQ19ET1dOX0RJR0lUQUxfU0lHTkFUVVJFXCIsXG4gICAgICAgICAgICA4OiBcIkhNQUNfVVBcIixcbiAgICAgICAgICAgIDk6IFwiU0VDVVJFX0JPT1RfRElHRVNUMFwiLFxuICAgICAgICAgICAgMTA6IFwiU0VDVVJFX0JPT1RfRElHRVNUMVwiLFxuICAgICAgICAgICAgMTE6IFwiU0VDVVJFX0JPT1RfRElHRVNUMlwiLFxuICAgICAgICAgICAgMTI6IFwiS01fSU5JVF9LRVlcIixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0UGtnVmVyc2lvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgbnVtV29yZCA9IDI7XG4gICAgICAgIGNvbnN0IGFkZHIgPSB0aGlzLkVGVVNFX0JMT0NLMV9BRERSICsgNCAqIG51bVdvcmQ7XG4gICAgICAgIGNvbnN0IHJlZ2lzdGVyVmFsdWUgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyhhZGRyKTtcbiAgICAgICAgcmV0dXJuIChyZWdpc3RlclZhbHVlID4+IDI3KSAmIDB4MDc7XG4gICAgfVxuICAgIGFzeW5jIGdldE1pbm9yQ2hpcFZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSAyO1xuICAgICAgICBjb25zdCBhZGRyID0gdGhpcy5FRlVTRV9CTE9DSzFfQUREUiArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCByZWdpc3RlclZhbHVlID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgICAgIHJldHVybiAocmVnaXN0ZXJWYWx1ZSA+PiAwKSAmIDB4MGY7XG4gICAgfVxuICAgIGFzeW5jIGdldE1ham9yQ2hpcFZlcnNpb24obG9hZGVyKSB7XG4gICAgICAgIGNvbnN0IG51bVdvcmQgPSAyO1xuICAgICAgICBjb25zdCBhZGRyID0gdGhpcy5FRlVTRV9CTE9DSzFfQUREUiArIDQgKiBudW1Xb3JkO1xuICAgICAgICBjb25zdCByZWdpc3RlclZhbHVlID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcoYWRkcik7XG4gICAgICAgIHJldHVybiAocmVnaXN0ZXJWYWx1ZSA+PiA0KSAmIDB4MDM7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBEZXNjcmlwdGlvbihsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgcGtnVmVyc2lvbiA9IGF3YWl0IHRoaXMuZ2V0UGtnVmVyc2lvbihsb2FkZXIpO1xuICAgICAgICBjb25zdCBjaGlwTmFtZSA9IHBrZ1ZlcnNpb24gPT09IDAgPyBcIkVTUDMyLVA0XCIgOiBcInVua25vd24gRVNQMzItUDRcIjtcbiAgICAgICAgY29uc3QgbWFqb3JSZXYgPSBhd2FpdCB0aGlzLmdldE1ham9yQ2hpcFZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgY29uc3QgbWlub3JSZXYgPSBhd2FpdCB0aGlzLmdldE1pbm9yQ2hpcFZlcnNpb24obG9hZGVyKTtcbiAgICAgICAgcmV0dXJuIGAke2NoaXBOYW1lfSAocmV2aXNpb24gdiR7bWFqb3JSZXZ9LiR7bWlub3JSZXZ9KWA7XG4gICAgfVxuICAgIGFzeW5jIGdldENoaXBGZWF0dXJlcyhsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuIFtcIkhpZ2gtUGVyZm9ybWFuY2UgTUNVXCJdO1xuICAgIH1cbiAgICBhc3luYyBnZXRDcnlzdGFsRnJlcShsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuIDQwOyAvLyBFU1AzMlA0IFhUQUwgaXMgZml4ZWQgdG8gNDBNSHpcbiAgICB9XG4gICAgYXN5bmMgZ2V0Rmxhc2hWb2x0YWdlKGxvYWRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGFzeW5jIG92ZXJyaWRlVmRkc2Rpbyhsb2FkZXIpIHtcbiAgICAgICAgbG9hZGVyLmRlYnVnKFwiVkREX1NESU8gb3ZlcnJpZGVzIGFyZSBub3Qgc3VwcG9ydGVkIGZvciBFU1AzMi1QNFwiKTtcbiAgICB9XG4gICAgYXN5bmMgcmVhZE1hYyhsb2FkZXIpIHtcbiAgICAgICAgbGV0IG1hYzAgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcpO1xuICAgICAgICBtYWMwID0gbWFjMCA+Pj4gMDtcbiAgICAgICAgbGV0IG1hYzEgPSBhd2FpdCBsb2FkZXIucmVhZFJlZyh0aGlzLk1BQ19FRlVTRV9SRUcgKyA0KTtcbiAgICAgICAgbWFjMSA9IChtYWMxID4+PiAwKSAmIDB4MDAwMGZmZmY7XG4gICAgICAgIGNvbnN0IG1hYyA9IG5ldyBVaW50OEFycmF5KDYpO1xuICAgICAgICBtYWNbMF0gPSAobWFjMSA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1sxXSA9IG1hYzEgJiAweGZmO1xuICAgICAgICBtYWNbMl0gPSAobWFjMCA+PiAyNCkgJiAweGZmO1xuICAgICAgICBtYWNbM10gPSAobWFjMCA+PiAxNikgJiAweGZmO1xuICAgICAgICBtYWNbNF0gPSAobWFjMCA+PiA4KSAmIDB4ZmY7XG4gICAgICAgIG1hY1s1XSA9IG1hYzAgJiAweGZmO1xuICAgICAgICByZXR1cm4gKHRoaXMuX2QyaChtYWNbMF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMV0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbMl0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbM10pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNF0pICtcbiAgICAgICAgICAgIFwiOlwiICtcbiAgICAgICAgICAgIHRoaXMuX2QyaChtYWNbNV0pKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0Rmxhc2hDcnlwdENvbmZpZyhsb2FkZXIpIHtcbiAgICAgICAgcmV0dXJuOyAvLyBkb2Vzbid0IGV4aXN0IG9uIEVTUDMyLVA0XG4gICAgfVxuICAgIGFzeW5jIGdldFNlY3VyZUJvb3RFbmFibGVkKGxhb2Rlcikge1xuICAgICAgICBjb25zdCByZWdpc3RlclZhbHVlID0gYXdhaXQgbGFvZGVyLnJlYWRSZWcodGhpcy5FRlVTRV9TRUNVUkVfQk9PVF9FTl9SRUcpO1xuICAgICAgICByZXR1cm4gcmVnaXN0ZXJWYWx1ZSAmIHRoaXMuRUZVU0VfU0VDVVJFX0JPT1RfRU5fTUFTSztcbiAgICB9XG4gICAgYXN5bmMgZ2V0S2V5QmxvY2tQdXJwb3NlKGxvYWRlciwga2V5QmxvY2spIHtcbiAgICAgICAgaWYgKGtleUJsb2NrIDwgMCB8fCBrZXlCbG9jayA+IHRoaXMuRUZVU0VfTUFYX0tFWSkge1xuICAgICAgICAgICAgbG9hZGVyLmRlYnVnKGBWYWxpZCBrZXkgYmxvY2sgbnVtYmVycyBtdXN0IGJlIGluIHJhbmdlIDAtJHt0aGlzLkVGVVNFX01BWF9LRVl9YCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVnU2hpZnREaWN0aW9uYXJ5ID0gW1xuICAgICAgICAgICAgW3RoaXMuRUZVU0VfUFVSUE9TRV9LRVkwX1JFRywgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTBfU0hJRlRdLFxuICAgICAgICAgICAgW3RoaXMuRUZVU0VfUFVSUE9TRV9LRVkxX1JFRywgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTFfU0hJRlRdLFxuICAgICAgICAgICAgW3RoaXMuRUZVU0VfUFVSUE9TRV9LRVkyX1JFRywgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTJfU0hJRlRdLFxuICAgICAgICAgICAgW3RoaXMuRUZVU0VfUFVSUE9TRV9LRVkzX1JFRywgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTNfU0hJRlRdLFxuICAgICAgICAgICAgW3RoaXMuRUZVU0VfUFVSUE9TRV9LRVk0X1JFRywgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTRfU0hJRlRdLFxuICAgICAgICAgICAgW3RoaXMuRUZVU0VfUFVSUE9TRV9LRVk1X1JFRywgdGhpcy5FRlVTRV9QVVJQT1NFX0tFWTVfU0hJRlRdLFxuICAgICAgICBdO1xuICAgICAgICBjb25zdCBbcmVnLCBzaGlmdF0gPSByZWdTaGlmdERpY3Rpb25hcnlba2V5QmxvY2tdO1xuICAgICAgICBjb25zdCByZWdpc3RlclZhbHVlID0gYXdhaXQgbG9hZGVyLnJlYWRSZWcocmVnKTtcbiAgICAgICAgcmV0dXJuIChyZWdpc3RlclZhbHVlID4+IHNoaWZ0KSAmIDB4ZjtcbiAgICB9XG4gICAgYXN5bmMgaXNGbGFzaEVuY3J5cHRpb25LZXlWYWxpZChsb2FkZXIpIHtcbiAgICAgICAgY29uc3QgcHVycG9zZXMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gdGhpcy5FRlVTRV9NQVhfS0VZOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHB1cnBvc2UgPSBhd2FpdCB0aGlzLmdldEtleUJsb2NrUHVycG9zZShsb2FkZXIsIGkpO1xuICAgICAgICAgICAgcHVycG9zZXMucHVzaChwdXJwb3NlKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpc1h0c0FlczEyOEtleSA9IHB1cnBvc2VzLmZpbmQoKHApID0+IHAgPT09IHRoaXMuUFVSUE9TRV9WQUxfWFRTX0FFUzEyOF9LRVkpO1xuICAgICAgICBpZiAodHlwZW9mIGlzWHRzQWVzMTI4S2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlzWHRzQWVzMjU2S2V5MSA9IHB1cnBvc2VzLmZpbmQoKHApID0+IHAgPT09IHRoaXMuUFVSUE9TRV9WQUxfWFRTX0FFUzI1Nl9LRVlfMSk7XG4gICAgICAgIGNvbnN0IGlzWHRzQWVzMjU2S2V5MiA9IHB1cnBvc2VzLmZpbmQoKHApID0+IHAgPT09IHRoaXMuUFVSUE9TRV9WQUxfWFRTX0FFUzI1Nl9LRVlfMik7XG4gICAgICAgIGlmICh0eXBlb2YgaXNYdHNBZXMyNTZLZXkxICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGlzWHRzQWVzMjU2S2V5MiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/docs/vendors-node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_8266_json.bundle.js b/docs/vendors-node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_8266_json.bundle.js deleted file mode 100644 index 25a5961..0000000 --- a/docs/vendors-node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_8266_json.bundle.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -(self["webpackChunkTactility_Web_Installer"] = self["webpackChunkTactility_Web_Installer"] || []).push([["vendors-node_modules_esptool-js_lib_targets_stub_flasher_stub_flasher_8266_json"],{ - -/***/ "./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_8266.json": -/*!*********************************************************************************!*\ - !*** ./node_modules/esptool-js/lib/targets/stub_flasher/stub_flasher_8266.json ***! - \*********************************************************************************/ -/***/ ((module) => { - -module.exports = /*#__PURE__*/JSON.parse('{"entry":1074843652,"text":"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","text_start":1074843648,"data":"CIH+PwUFBAACAwcAAwMLANTXEEAL2BBAOdgQQNbYEECF5xBAOtkQQJDZEEDc2RBAhecQQKLaEEAf2xBA4NsQQIXnEECF5xBAeNwQQIXnEEBV3xBAHOAQQFfgEECF5xBAhecQQPPgEECF5xBA2+EQQIHiEEDA4xBAf+QQQFDlEECF5xBAhecQQIXnEECF5xBAfuYQQIXnEEB05xBAsN0QQKnYEEDC5RBAydoQQBvaEECF5xBACOcQQE/nEECF5xBAhecQQIXnEECF5xBAhecQQIXnEECF5xBAhecQQELaEEB/2hBA2uUQQAEAAAACAAAAAwAAAAQAAAAFAAAABwAAAAkAAAANAAAAEQAAABkAAAAhAAAAMQAAAEEAAABhAAAAgQAAAMEAAAABAQAAgQEAAAECAAABAwAAAQQAAAEGAAABCAAAAQwAAAEQAAABGAAAASAAAAEwAAABQAAAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAUAAAAGAAAABgAAAAcAAAAHAAAACAAAAAgAAAAJAAAACQAAAAoAAAAKAAAACwAAAAsAAAAMAAAADAAAAA0AAAANAAAAAAAAAAAAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAANAAAADwAAABEAAAATAAAAFwAAABsAAAAfAAAAIwAAACsAAAAzAAAAOwAAAEMAAABTAAAAYwAAAHMAAACDAAAAowAAAMMAAADjAAAAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAgAAAAMAAAADAAAAAwAAAAMAAAAEAAAABAAAAAQAAAAEAAAABQAAAAUAAAAFAAAABQAAAAAAAAAAAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AAQEAAAEAAAAEAAAA","data_start":1073720488,"bss_start":1073643776}'); - -/***/ }) - -}]); \ No newline at end of file diff --git a/package.json b/package.json index eba5688..ac335a8 100644 --- a/package.json +++ b/package.json @@ -12,16 +12,16 @@ "author": "", "license": "", "devDependencies": { + "copy-webpack-plugin": "^12.0.2", "css-loader": "^7.1.2", "exports-loader": "^5.0.0", "html-webpack-plugin": "^5.6.3", "style-loader": "^4.0.0", "webpack": "^5.97.1", "webpack-cli": "^6.0.1", - "webpack-dev-server": "^5.2.0", - "copy-webpack-plugin": "^12.0.2" + "webpack-dev-server": "^5.2.0" }, "dependencies": { - "esp-web-tools": "^10.1.1" + "esptool-js": "^0.7.1" } } diff --git a/src/.nojekyll b/src/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/src/CNAME b/src/CNAME deleted file mode 100644 index 7e1e67d..0000000 --- a/src/CNAME +++ /dev/null @@ -1 +0,0 @@ -install.tactilityproject.org diff --git a/src/app.css b/src/app.css index 755fbcd..bf92e8e 100644 --- a/src/app.css +++ b/src/app.css @@ -424,8 +424,7 @@ main > .notice { /* Buttons */ -esp-web-install-button { - display: block; +#InstallButton { margin-top: 18px; } @@ -449,6 +448,25 @@ esp-web-install-button { transform: translateY(1px); } +.button-primary:disabled { + filter: none; + opacity: 0.45; + cursor: not-allowed; +} + +.button-secondary { + padding: 12px 20px; + background: var(--surface-raised); + border: 1px solid var(--border); + border-radius: var(--radius-small); + font-weight: 650; + cursor: pointer; +} + +.button-secondary:hover { + border-color: var(--text-muted); +} + .button-link { padding: 0; background: none; @@ -461,11 +479,96 @@ esp-web-install-button { text-decoration: underline; } -.install-fallback { +/* Install dialog */ + +.dialog { + width: min(460px, calc(100vw - 32px)); + padding: 24px; + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--radius); + box-shadow: var(--shadow); + color: var(--text); +} + +.dialog::backdrop { + background: rgba(0, 0, 0, 0.55); +} + +.dialog h2 { + margin: 0 0 10px; + font-size: 1.2rem; +} + +.dialog p { + margin: 0 0 16px; + overflow-wrap: anywhere; +} + +.dialog-actions { + display: flex; + gap: 10px; + margin-top: 20px; +} + +.dialog-actions > * { + flex: 1; +} + +.dialog-hint { + color: var(--text-muted); + font-size: 0.88rem; +} + +.dialog progress { + display: block; + width: 100%; + height: 10px; + margin-bottom: 14px; + accent-color: var(--primary); +} + +.check { + display: flex; + gap: 10px; + align-items: flex-start; + padding: 12px 14px; + border: 1px solid var(--border); + border-radius: var(--radius-small); + cursor: pointer; +} + +.check input { + margin-top: 5px; + accent-color: var(--primary); +} + +.check-sub { display: block; color: var(--text-muted); - font-size: 0.92rem; - text-align: center; + font-size: 0.88rem; +} + +.install-log { + margin-top: 16px; + color: var(--text-muted); + font-size: 0.85rem; +} + +.install-log summary { + cursor: pointer; +} + +.install-log pre { + max-height: 180px; + margin: 8px 0 0; + padding: 10px; + overflow: auto; + background: var(--bg); + border-radius: var(--radius-small); + font-size: 0.78rem; + white-space: pre-wrap; + overflow-wrap: anywhere; } @media (max-width: 820px) { diff --git a/src/index.html b/src/index.html index 7efa576..284d6b9 100644 --- a/src/index.html +++ b/src/index.html @@ -36,6 +36,10 @@

    Install Tactility on your device

    or check the
    alternative install methods. + +

    1Choose your device

    @@ -85,15 +89,50 @@

    2Pick a version and install

    - - - Your browser is not supported. - Installing is only possible over HTTPS. - +
    + +
    +

    Install Tactility

    +

    + +
    + + +
    +
    + + + + + +
    + Log +
    
    +    
    +
    + diff --git a/src/install.js b/src/install.js new file mode 100644 index 0000000..26dd75b --- /dev/null +++ b/src/install.js @@ -0,0 +1,220 @@ +const BAUDRATE = 115200; + +const $ = (id) => document.getElementById(id); + +/** An error with a message that is fit to show to the user. */ +class InstallError extends Error {} + +/** The install that the dialog is currently showing: { port, manifestUrl, label } */ +let session = null; +let busy = false; + +/** Why installing is impossible in this browser context, or null when it is possible. */ +export function getUnsupportedReason() { + if (!window.isSecureContext) { + return 'insecure'; + } + return 'serial' in navigator ? null : 'browser'; +} + +function showStep(step) { + for (const element of $('InstallDialog').querySelectorAll('[data-step]')) { + element.hidden = element.dataset.step !== step; + } +} + +/** @param {?number} fraction progress from 0 to 1, or null when it is unknown */ +function setStatus(text, fraction = null) { + $('InstallStatus').textContent = text; + const bar = $('InstallBar'); + if (fraction === null) { + bar.removeAttribute('value'); + } else { + bar.value = fraction; + } +} + +function log(text) { + const output = $('InstallLog'); + output.textContent += text; + output.scrollTop = output.scrollHeight; +} + +const terminal = { + clean: () => { $('InstallLog').textContent = ''; }, + write: (text) => log(text), + writeLine: (text) => log(`${text}\n`), +}; + +function showResult(title, text, canRetry) { + $('InstallResultTitle').textContent = title; + $('InstallResultText').textContent = text; + $('InstallRetry').hidden = !canRetry; + showStep('result'); +} + +async function fetchOk(url) { + let response; + try { + response = await fetch(url); + } catch (error) { + throw new InstallError(`Failed to download ${url}. Check your internet connection.`, { cause: error }); + } + if (!response.ok) { + throw new InstallError(`Failed to download ${url} (HTTP ${response.status}).`); + } + return response; +} + +const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + +/** + * Restart the chip by pulsing its EN pin through the RTS line, like esptool.py does. + * The hard reset of esptool-js only releases RTS, which doesn't restart boards with a USB-UART bridge. + */ +async function hardReset(transport) { + await transport.setRTS(true); + await sleep(100); + await transport.setRTS(false); + await sleep(50); +} + +async function flash({ port, manifestUrl }, erase) { + setStatus('Preparing…'); + const [{ ESPLoader, Transport }, manifest] = await Promise.all([ + import('esptool-js'), + fetchOk(manifestUrl).then((response) => response.json()), + ]); + + const transport = new Transport(port); + try { + const loader = new ESPLoader({ + transport, + baudrate: BAUDRATE, + romBaudrate: BAUDRATE, + terminal, + resetConstructors: { hardReset: () => ({ reset: () => hardReset(transport) }) }, + }); + + setStatus('Connecting to the device…'); + try { + await loader.main(); + } catch (error) { + throw new InstallError( + 'Failed to connect to the device. Make sure no other program is using it, ' + + 'then try again while holding the BOOT button.', + { cause: error }, + ); + } + + const chip = loader.chip.CHIP_NAME; + const build = manifest.builds.find((candidate) => candidate.chipFamily === chip); + if (!build) { + throw new InstallError(`The connected device has an ${chip} chip, which this firmware does not support. ` + + 'Check that you selected the right device.'); + } + + setStatus('Downloading firmware…'); + const baseUrl = new URL(manifestUrl, location.href); + const fileArray = await Promise.all(build.parts.map(async (part) => { + const response = await fetchOk(new URL(part.path, baseUrl)); + return { address: part.offset, data: new Uint8Array(await response.arrayBuffer()) }; + })); + + if (erase) { + setStatus('Erasing the device. This can take a minute…'); + await loader.eraseFlash(); + } + + const totalSize = fileArray.reduce((sum, file) => sum + file.data.length, 0); + let finishedSize = 0; + setStatus('Installing… 0%', 0); + await loader.writeFlash({ + fileArray, + flashMode: 'keep', + flashFreq: 'keep', + flashSize: 'keep', + eraseAll: false, + compress: true, + // "written" and "total" count compressed bytes, so scale them to the size of the file + reportProgress: (fileIndex, written, total) => { + const fileSize = fileArray[fileIndex].data.length; + const fraction = (finishedSize + (written / total) * fileSize) / totalSize; + setStatus(`Installing… ${Math.floor(fraction * 100)}%`, fraction); + if (written === total) { + finishedSize += fileSize; + } + }, + }); + + setStatus('Restarting the device…'); + await loader.after('hard_reset'); + } catch (error) { + // Don't leave the device stuck in its bootloader + await hardReset(transport).catch((resetError) => console.warn('Failed to reset the device', resetError)); + throw error; + } finally { + await transport.disconnect().catch((error) => console.warn('Failed to close the serial port', error)); + } +} + +async function run() { + const erase = $('InstallErase').checked; + busy = true; + showStep('progress'); + try { + await flash(session, erase); + showResult('Installation complete', `${session.label} is installed. Your device is restarting.`, false); + } catch (error) { + console.error(error); + log(`\nError: ${error.message}\n`); + const text = error instanceof InstallError + ? error.message + : `Installation failed: ${error.message} Reconnect the device and try again.`; + showResult('Installation failed', text, true); + } finally { + busy = false; + } +} + +function showConfirm() { + $('InstallSummary').textContent = `${session.label} will be installed on the device you selected.`; + showStep('confirm'); +} + +/** + * Ask for a serial port and open the install dialog. Must be called from a user gesture. + * @param {string} manifestUrl URL of an ESP Web Tools manifest + * @param {string} label what is being installed, e.g. "Tactility 1.0.0 for LilyGO T-Deck" + */ +export async function startInstall(manifestUrl, label) { + let port; + try { + port = await navigator.serial.requestPort(); + } catch (error) { + if (error.name === 'NotFoundError') { + return; // The user closed the port picker + } + throw error; + } + session = { port, manifestUrl, label }; + $('InstallErase').checked = false; + $('InstallLog').textContent = ''; + showConfirm(); + $('InstallDialog').showModal(); +} + +export function initInstallDialog() { + const dialog = $('InstallDialog'); + $('InstallConfirm').addEventListener('click', run); + $('InstallRetry').addEventListener('click', showConfirm); + for (const button of dialog.querySelectorAll('[data-close]')) { + button.addEventListener('click', () => dialog.close()); + } + // Escape must not close the dialog halfway through an install + dialog.addEventListener('cancel', (event) => { + if (busy) { + event.preventDefault(); + } + }); +} diff --git a/src/main.js b/src/main.js index f151300..f034b66 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,5 @@ -import 'esp-web-tools'; import './app.css'; +import { getUnsupportedReason, initInstallDialog, startInstall } from './install'; import toolbarLogo from '../assets/images/toolbar-logo.svg'; import '../assets/images/favicon.svg'; @@ -20,7 +20,8 @@ const state = { function getCdnUrl(version, path) { const directory = version === 'unstable' ? 'snapshot' : version; - return `https://cdn.tactilityproject.org/firmware/${directory}/${path}`; + // CDN_BASE_URL is injected by webpack: empty (dev server proxy) when serving + return `${CDN_BASE_URL}/firmware/${directory}/${path}`; } /** Lowercase and strip punctuation, so "tdeck" matches "T-Deck". */ @@ -232,8 +233,6 @@ function renderDetails() { if (build.infoMessage) { info.append(createNotice(build.infoMessage, 'info')); } - - $('Installer').manifest = getCdnUrl(version, `${device.id}.json`); } function selectDevice(id) { @@ -307,7 +306,24 @@ async function load() { } $('NavbarImage').src = toolbarLogo; -$('UnsupportedNotice').hidden = 'serial' in navigator; +const unsupportedReason = getUnsupportedReason(); +$('UnsupportedNotice').hidden = unsupportedReason !== 'browser'; +$('InsecureNotice').hidden = unsupportedReason !== 'insecure'; +$('InstallButton').disabled = unsupportedReason !== null; +initInstallDialog(); + +$('InstallButton').addEventListener('click', () => { + const device = getSelectedDevice(); + if (device === null) { + return; + } + const version = getActiveVersion(device); + const label = `Tactility ${state.indexes[version].version} for ${device.label}`; + startInstall(getCdnUrl(version, `${device.id}.json`), label).catch((error) => { + console.error(error); + alert(`Failed to open the serial port: ${error.message}`); + }); +}); $('Search').addEventListener('input', (event) => { state.query = event.target.value; diff --git a/webpack.config.js b/webpack.config.js index 033f139..707b012 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,33 +1,39 @@ const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') -const CopyPlugin = require("copy-webpack-plugin"); +const { DefinePlugin } = require('webpack'); -module.exports = { +const CDN_ORIGIN = 'https://cdn.tactilityproject.org'; + +// The CDN only allows CORS from the production origin, so the dev server +// proxies /firmware and the app uses same-origin URLs while serving. +module.exports = (env = {}) => ({ entry: './src/main.js', - mode: 'development', - devtool: 'inline-source-map', + mode: env.WEBPACK_SERVE ? 'development' : 'production', + devtool: env.WEBPACK_SERVE ? 'inline-source-map' : 'source-map', output: { filename: 'bundle.js', - path: path.resolve(__dirname, 'docs'), + path: path.resolve(__dirname, 'dist'), + clean: true, assetModuleFilename: 'assets/images/[name][ext]' }, devServer: { - static: { - directory: path.join(__dirname, 'docs'), - }, compress: false, port: 8080, + proxy: [ + { + context: ['/firmware'], + target: CDN_ORIGIN, + changeOrigin: true, + }, + ], }, plugins: [ + new DefinePlugin({ + CDN_BASE_URL: JSON.stringify(env.WEBPACK_SERVE ? '' : CDN_ORIGIN), + }), new HtmlWebpackPlugin({ template: 'src/index.html' }), - new CopyPlugin({ - patterns: [ - { from: "src/CNAME", to: "./" }, - { from: "src/.nojekyll", to: "./" } - ], - }), ], module: { rules: [ @@ -41,4 +47,4 @@ module.exports = { } ] } -}; +});