diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 8a4eb32..5a42d58 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ "name": "lua-agent-builder", "source": "./plugins/lua-agent-builder", "description": "Build, test, and deploy Lua AI agents from inside Claude Code", - "version": "1.5.0", + "version": "1.6.0", "homepage": "https://github.com/lua-ai-global/claude-code-lua-plugin#readme", "repository": "https://github.com/lua-ai-global/claude-code-lua-plugin.git", "license": "MIT", diff --git a/README.md b/README.md index 032c3b2..2fa3cf7 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ A [Claude Code](https://code.claude.com) marketplace + plugin for building, test πŸ“– **[User Guide β†’](./docs/USER_GUIDE.md)** β€” installation, walkthroughs, every slash command, hooks, MCP tools, safety model, troubleshooting. +πŸ€– **[Running in the Lua Job tier β†’](./docs/JOB_TIER.md)** β€” headless use (`LUA_PLUGIN_HEADLESS=1`, `claude -p`): inline playbooks, `--mcp-config`, and why the Lua-API proxy, not the hooks, is the boundary. + lua-cli is a TypeScript SDK/CLI. It has nothing to do with the Lua programming language. ## Install @@ -21,7 +23,7 @@ Then `/lua-auth`: an existing credential is kept; a new login runs `lua auth con | Plugin | Description | |---|---| -| [`lua-agent-builder`](./plugins/lua-agent-builder/) | 21 slash commands, 5 subagents, 10 hooks, a 6-file knowledge base verified against lua-cli source (3.33.0 base; 1.3.0 added per-step model classes and the workflow autonomy envelope from lua-cli 3.36.0, 1.4.0 the Job-tier billing rules and the lua-cli 3.37.0 cost read-outs, 1.5.0 log drains and the `lua logs` read window from lua-cli 3.38.0, read from `main`), a local read-only platform MCP server and the public docs MCP | +| [`lua-agent-builder`](./plugins/lua-agent-builder/) | 21 slash commands, 5 subagents, 10 hooks, a 6-file knowledge base verified against lua-cli source (3.33.0 base; 1.3.0 added per-step model classes and the workflow autonomy envelope from lua-cli 3.36.0, 1.4.0 the Job-tier billing rules and the lua-cli 3.37.0 cost read-outs, 1.5.0 log drains and the `lua logs` read window from lua-cli 3.38.0, read from `main`; 1.6.0 headless mode and a hardened production-gate parser), a local read-only platform MCP server and the public docs MCP | ## Quick walkthrough diff --git a/docs/JOB_TIER.md b/docs/JOB_TIER.md new file mode 100644 index 0000000..df29880 --- /dev/null +++ b/docs/JOB_TIER.md @@ -0,0 +1,134 @@ +# Running in the Lua Job tier (headless) + +This page is for the people who run `lua-agent-builder` **unattended**: inside `claude -p` on a Lua workflow Job step, or in any CI-style harness where no one answers a prompt. It covers what changes when the plugin knows it is headless, what still works, and where the real security boundary sits. It applies from plugin **1.6.0**. + +> lua-cli is a TypeScript SDK/CLI; it is unrelated to the Lua programming language. + +## 1. Turn on headless mode + +Set **`LUA_PLUGIN_HEADLESS=1`** in the environment of the `claude` process. `true`, `yes` and `on` are accepted too. + +With it set, the hooks behave as follows: + +| Hook | Interactive (default) | Headless | +|---|---|---| +| `check-lua-auth` (SessionStart) | A failed probe says "not authenticated … run `/lua-auth`" | One neutral note: authentication *could not be confirmed*, behind a Lua-API proxy that often means only that the probe route is refused, carry on. It names no slash command. | +| `check-lua-version` (SessionStart) | Points at `/lua-doctor` / `/lua-update` / `npm i -g` | The same finding with no fix-it instruction. The image owns the lua-cli version, not the run. | +| `detect-project` (SessionStart) | "… Run /lua-doctor or /lua-test to begin." | "βœ“ Lua agent project detected: ``." | +| `confirm-deploy` (PreToolUse) | Bare production verbs are blocked. `LUA_DEPLOY_CONFIRMED=1 lua …` is allowed. | **Every** production verb is blocked, prefixed or not (`DEPLOY_DENIED_HEADLESS`). The prefix means "a person confirmed this deploy"; headless, the model would be confirming to itself. | +| `block-auto-deploy` (PreToolUse) | Blocks `--auto-deploy`, points at `/lua-deploy` | Blocks it, and tells the model to push without the flag | +| `post-deploy-smoke` (PostToolUse) | Sends a production `lua chat` ping after a deploy | Never runs. A headless deploy should be impossible, and more production traffic is the wrong response if one happens. | + +Nothing that is blocked interactively is allowed headless. The only differences are wording, the void prefix, and the skipped smoke ping. + +## 2. Load the plugin, and pass MCP servers explicitly + +```bash +LUA_PLUGIN_HEADLESS=1 LUA_TELEMETRY=false \ +claude -p "$STEP_PROMPT" \ + --plugin-dir /opt/claude-code-lua-plugin/plugins/lua-agent-builder \ + --setting-sources '' \ + --strict-mcp-config \ + --mcp-config "$MCP_CONFIG_JSON" \ + --settings "$INLINE_SETTINGS_JSON" \ + --disallowedTools Agent +``` + +- **`--strict-mcp-config` drops the plugin's own `.mcp.json`.** Skills, subagent files and hooks still load, but `lua-platform` and `lua-docs` do not. If you want them, pass them in `--mcp-config`: + + ```json + { + "mcpServers": { + "lua-docs": { "type": "http", "url": "https://docs.heylua.ai/mcp" }, + "lua-platform": { + "command": "node", + "args": ["/opt/claude-code-lua-plugin/plugins/lua-agent-builder/mcp/lua-platform/dist/server.js"] + } + } + } + ``` + + Tool names then follow the plain spelling (`mcp__lua-platform__get_agent`), not the `mcp__plugin_lua-agent-builder_…` one. +- **`lua-platform` is self-contained since 1.6.0.** `dist/server.js` bundles `@modelcontextprotocol/sdk` and every other dependency, so baking the plugin into an image needs no `npm ci`. Up to 1.5.0 it failed with `ERR_MODULE_NOT_FOUND` (seen as `lua-platform CONNECTION_CLOSED`). `mcp/lua-platform/tests/standalone-bundle.test.mjs` keeps it that way. + - It honours `LUA_API_URL` and `LUA_API_KEY`, so behind a proxy it needs no real credential. + - `list_agents` / `get_agent` shell out to `lua agents --json --ci`. The other three tools are GET-only. + - It is optional: every reference to its tools has a `lua status` / `lua logs` fallback. + - A harness that can only emit `{type: "http"}` servers cannot pass it. Leave it out rather than work around that. +- **`--setting-sources ''`** keeps the user and project `~/.claude` agents, skills and settings out of the run. +- `LUA_TELEMETRY=false` stops lua-cli's PostHog calls. lua-cli's npm-registry version check (3 s, silent on failure) still runs on every command. + +## 3. The Agent tool is denied: run the playbooks inline + +The Job-tier harness denies the `Agent` tool. Every slash command that hands work to a subagent cannot complete headless: `/lua-new`, `/lua-qa`, `/lua-deploy`, `/lua-architect`, and the `/lua-test` β†’ `lua-debug` failure hand-off. + +The subagent files are plain Markdown playbooks. Point the step prompt at them as instructions for the main model: + +| Need | Read inline | +|---|---| +| Scaffold, register, compile and test one primitive | `${CLAUDE_PLUGIN_ROOT}/agents/lua-skill-builder.md` | +| Diagnose a failing `lua compile --ci` / `lua test --ci` / `lua push` | `${CLAUDE_PLUGIN_ROOT}/agents/lua-debug.md` | +| A conversational QA pass with a triage report | `${CLAUDE_PLUGIN_ROOT}/agents/lua-qa.md`. Its sandbox chats run real tools against the agent's live Data and connections, so use read-only cases only. | + +`lua-deploy-pilot.md` has no headless use, because nothing goes live from a headless run. + +`AskUserQuestion` is refused in `-p` mode. The slash commands built around it do not work headless: `/lua-auth`, `/lua-doctor`, `/lua-update`, `/lua-init`, `/lua-sync`, `/lua-template`, `/lua-env`, `/lua-drains`, `/lua-logs` without arguments, and `/lua-version create` without a message. + +The following work inline with their arguments given up front: +- `lua push --ci --force`; +- `lua test --ci …` with the input JSON in the prompt; +- `lua chat --ci -e sandbox -m "" -t `; +- `lua workflows run` (offline); +- `lua version list|show|diff`; +- `lua version create --ci -m ""`. + +## 4. The proxy is the boundary. Hooks are belts. + +`confirm-deploy` got much harder to slip past in 1.6.0. +- It lexes the whole command and finds a production verb: + - anywhere in a `&&` / `;` / `||` / pipe chain; + - in a `( )` or `{ }` group; + - in `$( )`, backticks or `<( )`; + - in a string run by `bash -c` / `eval` / `ssh` / `… | sh`, or in a heredoc fed to a shell; + - behind `FOO=1` prefixes, `sudo` / `env` / `timeout`, `npx lua`, `npx lua-cli`, `pnpm exec lua` or `node …/lua-cli/…`, and at a binary path. +- A shell variable in the binary or verb position is blocked. +- It fails closed. A command over 32 KB, one that exhausts the 1.5 s budget, or an internal error is blocked if it mentions lua, because a hook that hits its timeout lets the command run. +- The confirmation prefix counts only as the first word of the exact simple command that runs the verb. + +It is still a **belt**: +- A turn that can run a shell can always build a command the classifier cannot see: `echo | base64 -d | sh`, a script file written first, an `npm run` script, a `node` program that assembles the string, or a raw HTTP call. +- The Job tier also runs in `bypassPermissions` (the coding turn needs a shell), where permission **allow** rules have no effect. + +So: + +1. **The Lua-API proxy decides what reaches production.** It must refuse: + - deploy, promote and activate routes; + - workflow and job version bodies with `activate: true`; + - the live `PATCH …/sub-agent` and MCP upserts that `lua push all` issues. + + It must also pin the credential to the target agent. +2. **Inline `--settings` should carry deny rows, not the plugin's permission template.** Deny rows still apply under `bypassPermissions`. The template's allow list admits the `LUA_DEPLOY_CONFIRMED=1` forms, which is right for a person and wrong for a headless run. Suggested rows: + + ``` + Bash(*lua deploy*) Bash(*lua * deploy*) Bash(*version promote*) + Bash(*workflows deploy*) Bash(*workflows activate*) Bash(*mcp activate*) + Bash(*publish*) Bash(*--auto-deploy*) Bash(*--auto-push*) + Bash(*LUA_DEPLOY_CONFIRMED*) Bash(*lua push agent*) Bash(*lua env*) + Bash(*lua auth*) Bash(*npm install -g*) + ``` + +3. **Allow `GET /agents/self-serve/models` through the proxy.** It is the `check-lua-auth` probe (`lua models list --json --ci`). If the proxy refuses it, the headless hook emits its neutral note and the run carries on, but the note is noise. + - Do not disable hooks with `--settings '{"disableAllHooks": true}'` to silence it. That also removes the `confirm-deploy` belt. + +## 5. Environment hygiene + +`lua chat -e sandbox` uploads the invoking process's **entire environment** as the sandbox skill version's `env` (see [SECURITY.md](../plugins/lua-agent-builder/SECURITY.md), "Known platform-side exposure"). Keep the `claude` child environment minimal: the proxy URL, the proxy-scoped key, `PATH`, `HOME`, `LUA_PLUGIN_HEADLESS` and `LUA_TELEMETRY`. Nothing else. + +## 6. Checklist + +- [ ] `LUA_PLUGIN_HEADLESS=1` and `LUA_TELEMETRY=false` are set on the `claude` process. +- [ ] The plugin is baked from this repository's `plugins/lua-agent-builder` at a pinned commit (1.6.0 or later), with no `npm ci` needed. +- [ ] `--strict-mcp-config` is set, plus `--mcp-config` for whichever of `lua-docs` / `lua-platform` you want. +- [ ] `--disallowedTools Agent` is set, and the step prompts point at `agents/*.md` as inline playbooks. +- [ ] Inline `--settings` carries the deny rows above. +- [ ] The proxy refuses every go-live route and body, allows `GET /agents/self-serve/models`, and pins the target agent. +- [ ] The child environment is scrubbed. diff --git a/plugins/lua-agent-builder/.claude-plugin/plugin.json b/plugins/lua-agent-builder/.claude-plugin/plugin.json index 1270bf5..f80bf15 100644 --- a/plugins/lua-agent-builder/.claude-plugin/plugin.json +++ b/plugins/lua-agent-builder/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "lua-agent-builder", - "version": "1.5.0", + "version": "1.6.0", "description": "Build, test, and deploy Lua AI agents from inside Claude Code", "author": { "name": "Lua AI", diff --git a/plugins/lua-agent-builder/CHANGELOG.md b/plugins/lua-agent-builder/CHANGELOG.md index 5045edc..fdc2867 100644 --- a/plugins/lua-agent-builder/CHANGELOG.md +++ b/plugins/lua-agent-builder/CHANGELOG.md @@ -2,6 +2,122 @@ All notable changes to the `lua-agent-builder` plugin. Versions follow the tag `release-prod.yml` cuts from `package.json` (`v`). lua-cli is a TypeScript SDK/CLI; it is unrelated to the Lua programming language. +## 1.6.0 β€” 2026-09-26 + +**Headless hardening and a standalone MCP server (EM-WS8).** Three findings from the Lua Job-tier audit, where the plugin runs unattended inside `claude -p`: +- the `lua-platform` MCP server could not start without an `npm ci` nobody runs; +- the `confirm-deploy` parser was a start-anchored regex with five known bypasses; +- the hooks steered an unattended model into interactive flows that cannot complete. + +The lua-cli pin is unchanged (3.38.0). + +### `lua-platform` runs with no `node_modules` + +- `mcp/lua-platform/scripts/bundle.mjs` no longer marks `@modelcontextprotocol/sdk` external. `dist/server.js` now inlines every npm dependency from the committed lockfile: 106 KB β†’ 529 KB, against a 5 MB budget. The build also writes `dist/THIRD_PARTY_NOTICES.txt`, generated from the esbuild metafile: every bundled package (`@modelcontextprotocol/sdk`, `zod`, both MIT) with its version and full licence text. Any `/*! */` legal comments are kept at the end of the bundle. + - Before this, a marketplace install, or the plugin baked into an image, died with `ERR_MODULE_NOT_FOUND`, which Claude Code reports as `lua-platform CONNECTION_CLOSED`. The plugin ships no `node_modules`, and `.mcp.json` launches `dist/server.js` directly. + - A `createRequire` banner gives the ESM bundle a real `require` for any CommonJS dependency. +- New `tests/standalone-bundle.test.mjs`: + - copies the bundle into an empty temp directory, asserting no `node_modules` exists anywhere above it; + - spawns it with `NODE_PATH` removed and runs `initialize` β†’ `tools/list` over stdio; + - asserts the five tools, and that `serverInfo.version` equals `package.json`, which catches a version bump that forgot to rebuild `dist/`. + - Against the 1.5.0 bundle it fails with `ERR_MODULE_NOT_FOUND`, as intended. + +### `confirm-deploy`: the parser reads the whole command + +`lib/tokenizer.mjs` used to test one regex anchored at the start of the string. These all ran a production verb straight past it: +- `cd x && lua deploy …` +- `true; lua version promote 3` +- `FOO=1 lua deploy all` +- `/usr/local/bin/lua deploy all` +- `npx lua deploy all` + +It now lexes the command the way a POSIX shell does (quotes, escapes, `&& || ; | |& &`, newlines, `( )` and `{ }` groups, redirections, heredocs) and checks **every simple command**: + +- **The binary is found at any word position, by basename.** That covers: + - `./node_modules/.bin/lua`, `C:/…/npm/lua.cmd`, and `"lua"` or `l\ua` spellings; + - env-assignment prefixes, and the `sudo` / `env` / `command` / `exec` / `timeout N` wrappers; + - launchers: `npx lua`, `npx lua-cli`, `npx -y lua-cli@3.38.0`, `pnpm exec lua`, `pnpm dlx lua-cli`, `yarn lua`, `npm exec -- lua`, `bunx lua-cli`; + - `node [opts] …/lua-cli/dist/index.js` and a directly executed `…/lua-cli/dist/index.js`. + - A bare `lua-cli` at the head is still unclassified, as in 1.5.0: it is not an installed binary. +- **Options between the binary and the verb are skipped**, both as boolean flags and as `--flag value` pairs. `lua --ci deploy`, `lua workflows -v 3 deploy x`. +- **Substitutions are parsed recursively.** That covers `$( )`, backticks and `<( )`, including inside double quotes. +- **Strings run by another shell are parsed too.** That covers `bash -c` / `sh -lc` / `eval` / `ssh host "…"` / `watch` / `npx -c`, `… | sh`, heredocs and here-strings fed to a shell, and `alias` / `trap` bodies. + - Inline interpreter code (`node -e`, `python3 -c`, `perl -e`) is searched as text. +- **A shell variable in the binary or verb position is blocked**, because it cannot be resolved: `L=lua; $L deploy all`, `lua $VERB all`, `… | xargs lua`. The label is `lua `. +- **Input the lexer cannot close** (an unterminated quote or substitution) falls back to an unanchored textual search, reported as unprefixed. +- **Alias gaps closed**, from lua-cli `aliases.ts`: + - `marketplace.noun` maps `templates`, `agent-template` and `agent-templates` to `template`; + - `normalizeArg` lower-cases action words, so `lua workflows DEPLOY x` is live. Matching is now case-insensitive. +- **`LUA_DEPLOY_CONFIRMED=1` counts only in its canonical shape.** It must be the first word of the very simple command that runs the verb (optionally after `env`), with the binary spelled bare, outside any pipe, group, substitution or wrapper string. + - Each verb in a chain needs its own prefix, and one unprefixed verb blocks the whole command. + - Blocked: `export LUA_DEPLOY_CONFIRMED=1; lua deploy all`, `LUA_DEPLOY_CONFIRMED=1 true && lua deploy all`, `LUA_DEPLOY_CONFIRMED=1 npx lua deploy all`, `FOO=1 LUA_DEPLOY_CONFIRMED=1 lua deploy all`. + - Allowed: `cd agent && LUA_DEPLOY_CONFIRMED=1 lua deploy skill …`, and redirections such as `> deploy.log 2>&1`. + - Every form `/lua-deploy`, the deploy pilot and `/lua-template` emit is unchanged and still allowed. +- **Text that only *mentions* a verb stays unclassified**: `git commit -m "lua deploy all"`, `grep -r "lua deploy" .`, `lua chat … -m "please lua deploy all"`, and a heredoc written to a file. +- **Fails closed, and decides inside the hook timeout.** A PreToolUse hook that throws or runs past its 10 s timeout fails *open*. The independent review reproduced exactly that against a draft, with 24 KB inputs. So: + - Everything is linear. + - The textual fallback is a token scan that reuses the parser's argument matcher, not a set of regexes. + - Two regex drafts backtracked: one exponentially (28 options β‰ˆ 200 s), one quadratically (`lua/` Γ— 6000 β‰ˆ 10 s). + - A command over **32 KB** (`MAX_COMMAND_LENGTH`) is not parsed. + - A classification has a **1.5 s budget** (`TIME_BUDGET_MS`). + - An over-length command, a spent budget, or an internal error **blocks** the command if it mentions a lua binary (`DEPLOY_DENIED_UNCLASSIFIABLE`, `lua `), and passes it otherwise. + - New `test/hooks/confirm-deploy.timeout.test.mjs` spawns the real hook on adversarial inputs up to 100 KB, including the review's reproductions and inputs just under the cap. It asserts a decision in under 2 s. + - The review's performance probe and a 3,000-string shell fuzz run as unit tests. +- **Command position only.** The binary is recognised as the command a shell would run, not at any word position. + - Recognised: the first word after assignments, and the command a wrapper, launcher or shell keyword runs, including `find … -exec lua` and `if/then/do/coproc`. + - `cp -r lua deploy`, `ls lua deploy` and `echo lua deploy all` no longer block. + - A pipeline feeding a shell (`echo lua deploy all | sh`) is still searched. +- **Computed words (review finding 2).** An unquoted glob (`/usr/local/bin/lu? deploy`) or brace expansion (`{lua,} deploy`, `lua de{ploy,} all`) is a runtime-computed word, like `$VAR`. `lua${IFS}deploy${IFS}all` is split at its expansions. A computed binary with a computed verb (`$(printf lua) $(printf deploy) all`, `L=lua; V=deploy; $L $V all`) is blocked when the command mentions lua anywhere. Unicode spaces count as separators. +- **More strings that run as code (review finding 3):** + - `env -S` / `--split-string`; + - awk `system(…)`, `print … | "cmd"` and `"cmd" | getline`; + - `osascript -e`, and editor `-c '!…'` / `+cmd`; + - GNU sed's `e` command and `s///e`; + - `git -c alias.x='!…'`; + - `tmux` / `screen`, `docker exec c sh -c` (a shell name counts at any position), and `bash < <(…)` / `source <(…)`; + - `$(…)` inside an unquoted heredoc; + - a heredoc written to a script that the same command then runs (`cat > x.sh <__`; the subagents, slashes and the permission template use that form (the plain `mcp__lua-platform__…` spelling only exists for a server you register yourself with `claude mcp add`). diff --git a/plugins/lua-agent-builder/SECURITY.md b/plugins/lua-agent-builder/SECURITY.md index 17e0be1..368239a 100644 --- a/plugins/lua-agent-builder/SECURITY.md +++ b/plugins/lua-agent-builder/SECURITY.md @@ -11,7 +11,7 @@ We aim to acknowledge within 2 business days and ship a fix within 30 days for h This plugin's surface includes: - **Hooks** (`hooks/*.mjs`) β€” run as subprocesses of Claude Code on `SessionStart`, `UserPromptSubmit`, and `Pre/PostToolUse(Bash)` events. -- **MCP servers** β€” `mcp/lua-platform/dist/server.js`, a local stdio server exposing 5 read-only tools; it talks to `https://api.heylua.ai` over HTTPS with the user's lua-cli credential (and, for a session login, refreshes the stored refresh token at Google's securetoken endpoint exactly like lua-cli does). `lua-docs` is the public remote MCP at `https://docs.heylua.ai/mcp` (read-only docs search). +- **MCP servers** β€” `mcp/lua-platform/dist/server.js`, a local stdio server exposing 5 read-only tools (a single self-contained bundle since 1.6.0 β€” its npm dependencies, `@modelcontextprotocol/sdk` included, are inlined at build time from the lockfile); it talks to `https://api.heylua.ai` over HTTPS with the user's lua-cli credential (and, for a session login, refreshes the stored refresh token at Google's securetoken endpoint exactly like lua-cli does). `lua-docs` is the public remote MCP at `https://docs.heylua.ai/mcp` (read-only docs search). - **Slash commands and subagents** (`commands/*.md`, `agents/*.md`) β€” Markdown prompts that Claude reads and executes. - **Permission rules** (`lib/permissions-template.json`) β€” merged into the user's `.claude/settings.json` by `/lua-doctor` Step 5 with consent. @@ -32,10 +32,11 @@ Out of scope: | Contract | Where enforced | |---|---| -| Production gate: `lua deploy`, `lua skills\|webhooks\|jobs\|preprocessors\|postprocessors deploy`, `lua persona production deploy`, `lua workflows deploy\|activate`, `lua version promote`, `lua mcp activate`, `lua marketplace template publish\|apply` are blocked in bare form; only the `LUA_DEPLOY_CONFIRMED=1`-prefixed form emitted after the user's confirmation runs. The gate covers every spelling lua-cli accepts: the action aliases from its `aliases.ts` (`publish`β†’deploy, `on`/`enable`β†’activate, `submit`/`publish_version`β†’template publish, `deploy`/`fleet-apply`/`rollout`β†’template apply, `prod`/`prd`/`live`β†’production) and all three installed binaries (`lua`, `heylua`, `lua-ai`) | **The hook is the gate.** `hooks/confirm-deploy.mjs` runs on **every** Bash call (no `if` glob to drift), classifies with `lib/tokenizer.mjs` (the single source of truth) and exits 2 on a bare verb β€” a hook block takes precedence over any allow rule, including a broad `Bash(lua *)` in the user's own settings. Wrappers and pipes are refused even with the prefix. `lib/permissions-template.json` allows the literal prefixed forms (so the confirmed command runs without a second prompt) and deliberately has **no** deny/ask rule for the bare verbs: Claude Code evaluates deny/ask rules past a leading env assignment (code.claude.com/docs/en/permissions: "A deny or ask rule matches past any leading assignment"), so a `Bash(lua deploy*)` deny would also block the confirmed form and make every deploy impossible β€” verified live on 2026-09-12. A bare verb that reaches the permission layer falls to Claude Code's default prompt (a denial in `-p` mode). `heylua`/`lua-ai` are denied wholesale. `test/lib/permissions-mirror.test.mjs` and `scripts/lint-permissions.mjs` fail if a deny/ask rule would shadow a confirmed form or an allow rule admits a bare one | +| Production gate: `lua deploy`, `lua skills\|webhooks\|jobs\|preprocessors\|postprocessors deploy`, `lua persona production deploy`, `lua workflows deploy\|activate`, `lua version promote`, `lua mcp activate`, `lua marketplace template publish\|apply` are blocked in bare form; only the `LUA_DEPLOY_CONFIRMED=1`-prefixed form emitted after the user's confirmation runs. The gate covers every spelling lua-cli accepts: the action aliases from its `aliases.ts` (`publish`β†’deploy, `on`/`enable`β†’activate, `submit`/`publish_version`β†’template publish, `deploy`/`fleet-apply`/`rollout`β†’template apply, `prod`/`prd`/`live`β†’production) and all three installed binaries (`lua`, `heylua`, `lua-ai`) | **The hook is the gate.** `hooks/confirm-deploy.mjs` runs on **every** Bash call (no `if` glob to drift), classifies with `lib/tokenizer.mjs` (the single source of truth) and exits 2 on a bare verb β€” a hook block takes precedence over any allow rule, including a broad `Bash(lua *)` in the user's own settings. Since 1.6.0 the classifier lexes the whole command. It recognises the binary in command position: after assignments, and as the command of a wrapper, launcher or keyword (`sudo`, `env`, `timeout`, `xargs`, `npx lua`, `npx lua-cli`, `pnpm exec lua`, `node …/lua-cli/…`, `find -exec`, `if`/`then`), at any path and in any case. That applies to every simple command of a `&&`/`;`/`||`/pipe chain, to `( )`/`{ }` groups, to `$( )`/backticks/`<( )`, and to strings run as code: `bash -c`, `eval`, `ssh`, `env -S`, `… | sh`, heredocs fed to a shell or written to a script that is then run, inline interpreter code, awk `system()`, sed `e`, and `git -c alias.x='!…'`. A word the shell computes at runtime (`$VAR`, `$(…)`, `${IFS}`, globs, brace expansion) in the binary or verb position is blocked. The prefix counts only as the first word of the very simple command that runs the verb, with the binary spelled bare. It never counts through a pipe, group, substitution, wrapper string or launcher, and each verb in a chain needs its own. The classifier is linear and **fails closed**: a command over 32 KB, one that exhausts the 1.5 s budget, or an internal error blocks the command if it mentions lua. This matters because a hook that hits its 10 s timeout lets the command run; `test/hooks/confirm-deploy.timeout.test.mjs` spawns the real hook on 100 KB adversarial inputs. With `LUA_PLUGIN_HEADLESS=1` the prefix is void and every production verb is blocked (docs/JOB_TIER.md). The hook is still a belt against a model, not a sandbox: a command assembled at runtime (`base64 -d \| sh`, a script file, an npm script, a raw HTTP call) is out of its reach β€” in unattended runs the Lua-API proxy is the boundary. `lib/permissions-template.json` allows the literal prefixed forms (so the confirmed command runs without a second prompt) and deliberately has **no** deny/ask rule for the bare verbs: Claude Code evaluates deny/ask rules past a leading env assignment (code.claude.com/docs/en/permissions: "A deny or ask rule matches past any leading assignment"), so a `Bash(lua deploy*)` deny would also block the confirmed form and make every deploy impossible β€” verified live on 2026-09-12. A bare verb that reaches the permission layer falls to Claude Code's default prompt (a denial in `-p` mode). `heylua`/`lua-ai` are denied wholesale. `test/lib/permissions-mirror.test.mjs` and `scripts/lint-permissions.mjs` fail if a deny/ask rule would shadow a confirmed form or an allow rule admits a bare one | | `--auto-deploy` is never allowed | deny list (`Bash(lua * --auto-deploy*)` matches prefixed or not) + `hooks/block-auto-deploy.mjs` + `hooks/confirm-deploy.mjs` | | Single-permission contract: each slash asks at most one prompt. For workflow run-control verbs (`lua workflows start\|approve\|signal\|resume\|retry-step\|resolve-step\|raise-budget\|cancel\|deactivate\|export\|schedules\|goals`) that single prompt is the **Bash permission prompt** from the `ask` tier, which shows the exact command; `/lua-workflow` does not add an AskUserQuestion on top. `/lua-env` (`lua env *`; listings are masked by the CLI, set values are never echoed by the slash) and `/lua-integrations` (connect/update/disconnect/convert, webhook and MCP toggles) rely on the same `ask`-tier prompt | `scripts/lint-single-permission.mjs`; `ask` tier of `lib/permissions-template.json` | -| Post-deploy smoke check fires after every verb that makes something live (`SMOKE_LABELS` in `lib/tokenizer.mjs`: deploy spellings, `persona production deploy`, `workflows deploy`, `version promote`, `mcp activate`) | `hooks/post-deploy-smoke.mjs` (PostToolUse on every Bash call) | +| Post-deploy smoke check fires after every verb that makes something live (`SMOKE_LABELS` in `lib/tokenizer.mjs`: deploy spellings, `persona production deploy`, `workflows deploy`, `version promote`, `mcp activate`); never in headless mode, which sends no production ping | `hooks/post-deploy-smoke.mjs` (PostToolUse on every Bash call) | +| Headless mode (`LUA_PLUGIN_HEADLESS=1`): no hook message points at a slash command (they need AskUserQuestion or the Agent tool), and nothing blocked interactively is allowed | `lib/headless.mjs`; `test/hooks/headless.test.mjs` | | Credential isolation: account details, one-time codes and credentials never enter the conversation | `commands/lua-auth.md` sends login to a private terminal; `hooks/block-auth-configure.mjs`; `lua auth configure\|key\|logout` denied in `lib/permissions-template.json` | | Read-only MCP: no tool mutates platform state | `mcp/lua-platform/src/tools/*` (GET routes and `lua agents --json` only) | diff --git a/plugins/lua-agent-builder/hooks/block-auto-deploy.mjs b/plugins/lua-agent-builder/hooks/block-auto-deploy.mjs index 7e5c46e..33adbe5 100644 --- a/plugins/lua-agent-builder/hooks/block-auto-deploy.mjs +++ b/plugins/lua-agent-builder/hooks/block-auto-deploy.mjs @@ -7,11 +7,13 @@ import { runHook, checkNodeVersion, isMainScript } from '../lib/hook-runtime.mjs'; import { hasAutoDeploy } from '../lib/tokenizer.mjs'; +import { isHeadless } from '../lib/headless.mjs'; /** * @param {{tool_input?: {command?: string}}|null} input + * @param {Record} [env] β€” defaults to process.env (headless switch) */ -export function decide(input) { +export function decide(input, env = process.env) { const command = input?.tool_input?.command ?? ''; if (hasAutoDeploy(command)) { @@ -19,8 +21,11 @@ export function decide(input) { block: true, reason: 'DEPLOY_DENIED_AUTO: --auto-deploy is never the right choice from inside Claude Code. ' + - 'Use /lua-deploy instead β€” it spawns the deploy-pilot subagent which gates each step ' + - 'with the Β§3.7 single-permission contract.', + (isHeadless(env) + ? 'This is a headless run (LUA_PLUGIN_HEADLESS=1): push without that flag and report what you ' + + 'staged; nothing goes live from this session.' + : 'Use /lua-deploy instead β€” it spawns the deploy-pilot subagent which gates each step ' + + 'with the Β§3.7 single-permission contract.'), }; } diff --git a/plugins/lua-agent-builder/hooks/check-lua-auth.mjs b/plugins/lua-agent-builder/hooks/check-lua-auth.mjs index 9586004..e244d26 100644 --- a/plugins/lua-agent-builder/hooks/check-lua-auth.mjs +++ b/plugins/lua-agent-builder/hooks/check-lua-auth.mjs @@ -17,9 +17,17 @@ // were signed out. lua-cli's exit-code classes (3.33.0) tell the outcomes // apart: 0 ok Β· 9 auth Β· 10 forbidden (a typed key scoped too narrowly for // the catalog route β€” still a valid login) Β· 11 Lua API unavailable. +// +// Headless (LUA_PLUGIN_HEADLESS=1, 1.6.0): every failure becomes one neutral +// note that names no slash command. In the Lua Job tier the credential is the +// pod's, lua-cli talks to a Lua-API proxy, and a proxy that refuses +// `GET /agents/self-serve/models` makes this probe fail with a perfectly good +// credential β€” "run /lua-auth" would send the model into an AskUserQuestion +// flow that cannot complete in `claude -p`. import { runHook, checkNodeVersion, isMainScript } from '../lib/hook-runtime.mjs'; import { spawnLua } from '../lib/lua-cli.mjs'; +import { isHeadless, HEADLESS_NOTE } from '../lib/headless.mjs'; export const AUTH_PROBE_ARGS = ['models', 'list', '--json', '--ci']; const AUTH_PROBE_TIMEOUT_MS = 15_000; @@ -29,8 +37,9 @@ const AUTH_PROBE_TIMEOUT_MS = 15_000; * Result of `lua --version` (must succeed before auth probe makes sense). * @param {{exitCode: number|null, stdout?: string, stderr?: string, timedOut?: boolean}} authResult * Result of `lua models list --json --ci`. + * @param {Record} [env] β€” defaults to process.env (headless switch) */ -export function decide(versionResult, authResult) { +export function decide(versionResult, authResult, env = process.env) { // If lua-cli isn't installed, check-lua-version already warned the user. // Don't double-warn here. if (versionResult.exitCode !== 0) return null; @@ -39,6 +48,18 @@ export function decide(versionResult, authResult) { // away from the catalog route β€” still authenticated for its own agents. if (authResult.exitCode === 0 || authResult.exitCode === 10) return null; + if (isHeadless(env)) { + const outcome = authResult.timedOut || authResult.exitCode === null + ? `did not answer within ${AUTH_PROBE_TIMEOUT_MS / 1000}s` + : `exited ${authResult.exitCode}`; + return { + warn: + `β„Ή Lua authentication could not be confirmed at session start (\`lua models list\` ${outcome}). ` + + 'Behind a Lua-API proxy this often means only that the probe route is not allowed; lua-cli commands ' + + 'that need the platform may still work, and any that fail will say why. ' + HEADLESS_NOTE, + }; + } + // A slow probe is not a missing credential. if (authResult.timedOut || authResult.exitCode === null) { return { diff --git a/plugins/lua-agent-builder/hooks/check-lua-version.mjs b/plugins/lua-agent-builder/hooks/check-lua-version.mjs index aa740ec..0d1062b 100644 --- a/plugins/lua-agent-builder/hooks/check-lua-version.mjs +++ b/plugins/lua-agent-builder/hooks/check-lua-version.mjs @@ -5,6 +5,7 @@ import { runHook, checkNodeVersion, isMainScript } from '../lib/hook-runtime.mjs'; import { spawnLua } from '../lib/lua-cli.mjs'; +import { isHeadless, HEADLESS_NOTE } from '../lib/headless.mjs'; // Pinned minimum lua-cli version. The plugin's commands, agents and knowledge // files describe the lua-cli 3.38.0 surface: the 3.33.0 base (workflows, @@ -62,25 +63,34 @@ export function compareSemver(a, b) { * Returns null (allow silently), or { warn } to print a warning. * * @param {{stdout: string, exitCode: number|null}} versionResult + * @param {Record} [env] β€” defaults to process.env. Headless + * (LUA_PLUGIN_HEADLESS=1): the same findings, but no /lua-doctor or /lua-update + * pointer and no install instruction β€” the image, not the run, owns lua-cli. */ -export function decide(versionResult) { +export function decide(versionResult, env = process.env) { + const headless = isHeadless(env); if (versionResult.exitCode !== 0) { return { - warn: 'Could not detect lua-cli version. Run /lua-doctor to install.', + warn: headless + ? `Could not detect lua-cli (\`lua --version\` failed). ${HEADLESS_NOTE}` + : 'Could not detect lua-cli version. Run /lua-doctor to install.', }; } const installed = parseSemver(versionResult.stdout); if (!installed) { return { - warn: `Couldn't parse lua --version output: "${versionResult.stdout.trim()}". Run /lua-doctor.`, + warn: `Couldn't parse lua --version output: "${versionResult.stdout.trim()}". ` + + (headless ? HEADLESS_NOTE : 'Run /lua-doctor.'), }; } const minimum = parseSemver(PINNED_MIN_LUA_CLI); if (compareSemver(installed, minimum) < 0) { return { - warn: `Lua plugin requires lua-cli β‰₯${PINNED_MIN_LUA_CLI} (you have ${installed.join('.')}) β€” run /lua-update or: npm i -g lua-cli@latest. The plugin will continue to work with degraded functionality until you do (lua drains, and the lua logs --since/--until/--environment/--follow options, do not exist below ${PINNED_MIN_LUA_CLI}).`, + warn: headless + ? `lua-cli ${installed.join('.')} is older than the plugin's minimum ${PINNED_MIN_LUA_CLI}: lua drains, and the lua logs --since/--until/--environment/--follow options, do not exist on it. ${HEADLESS_NOTE}` + : `Lua plugin requires lua-cli β‰₯${PINNED_MIN_LUA_CLI} (you have ${installed.join('.')}) β€” run /lua-update or: npm i -g lua-cli@latest. The plugin will continue to work with degraded functionality until you do (lua drains, and the lua logs --since/--until/--environment/--follow options, do not exist below ${PINNED_MIN_LUA_CLI}).`, }; } diff --git a/plugins/lua-agent-builder/hooks/confirm-deploy.mjs b/plugins/lua-agent-builder/hooks/confirm-deploy.mjs index d8ad899..2b798df 100644 --- a/plugins/lua-agent-builder/hooks/confirm-deploy.mjs +++ b/plugins/lua-agent-builder/hooks/confirm-deploy.mjs @@ -16,18 +16,38 @@ // therefore lists only the prefixed forms (allow) and nothing for the bare // forms; an exit-2 block from this hook takes precedence over any allow rule, // including a broad `Bash(lua *)` in the user's own settings. +// +// 1.6.0 (EM-WS8): the classifier reads the whole command β€” every simple +// command in a `&&`/`;`/`||`/pipe chain, subshells, substitutions, strings run +// by another shell, env-assignment prefixes, launchers (`npx lua`, `npx +// lua-cli`, `pnpm exec lua`, `node …/lua`) and binary paths β€” and accepts +// the prefix only on the very simple command that runs the verb. Headless +// (LUA_PLUGIN_HEADLESS=1) the prefix is void: nobody is there to confirm, so +// every production verb is blocked and the block names no slash command. +// It remains a belt; in the Lua Job tier the Lua-API proxy is the boundary. import { runHook, checkNodeVersion, isMainScript } from '../lib/hook-runtime.mjs'; -import { classifyProductionCommand, hasAutoDeploy } from '../lib/tokenizer.mjs'; +import { + classifyProductionCommand, hasAutoDeploy, UNCLASSIFIABLE_LABEL, MAX_COMMAND_LENGTH, +} from '../lib/tokenizer.mjs'; +import { isHeadless } from '../lib/headless.mjs'; + +const HEADLESS_REASON = + 'This is a headless run (LUA_PLUGIN_HEADLESS=1): nothing here can confirm a production change, so the ' + + 'LUA_DEPLOY_CONFIRMED=1 prefix is not accepted and no deploy, promote, activation or template release ' + + 'runs from this session. Stage the change (lua push, lua version create) and report it; it is made live ' + + 'outside the run. Do not retry with another spelling.'; /** * Pure function β€” exported so tests can import and call directly without * the side effects of running as a script (per tech spec Β§17.1.1). * * @param {{tool_input?: {command?: string}}|null} input + * @param {Record} [env] β€” defaults to process.env (headless switch) */ -export function decide(input) { +export function decide(input, env = process.env) { const command = input?.tool_input?.command ?? ''; + const headless = isHeadless(env); if (hasAutoDeploy(command)) { return { @@ -35,21 +55,43 @@ export function decide(input) { reason: 'DEPLOY_DENIED_AUTO: --auto-deploy is never appropriate from inside Claude Code ' + '(a granular push would publish as a side effect; lua-cli ignores it for `push all` anyway). ' + - 'Use /lua-deploy instead β€” it spawns the deploy-pilot subagent which gates each step.', + (headless + ? HEADLESS_REASON + : 'Use /lua-deploy instead β€” it spawns the deploy-pilot subagent which gates each step.'), }; } const classified = classifyProductionCommand(command); if (!classified) return null; // Not a production verb β€” allow + + if (headless) { + return { + block: true, + reason: `DEPLOY_DENIED_HEADLESS: \`${classified.label}\` changes what runs in production. ${HEADLESS_REASON}`, + }; + } + if (classified.prefixed) return null; // User-authorised via the slash flow β€” allow + if (classified.label === UNCLASSIFIABLE_LABEL) { + return { + block: true, + reason: + 'DEPLOY_DENIED_UNCLASSIFIABLE: this command mentions lua but is too long or too complex to check for a ' + + `production verb (over ${MAX_COMMAND_LENGTH} bytes, or past the classifier's time budget), so it is ` + + 'blocked. Split it into shorter commands, or write long text to a file first and pass the file.', + }; + } + return { block: true, reason: `DEPLOY_DENIED_BARE: \`${classified.label}\` changes what runs in production and is blocked without the ` + `LUA_DEPLOY_CONFIRMED=1 prefix. Use ${classified.slash} (it collects your single confirmation per the Β§3.7 ` + - 'contract, then emits the prefixed form). Shell wrappers and pipes are refused even with the prefix.', + 'contract, then emits the prefixed form). The prefix counts only as the first word of the simple command ' + + 'that runs the verb, with the binary spelled `lua` β€” not in a pipe, subshell, `$(…)`, `bash -c` string, ' + + 'or through npx/pnpm/node/a path, and it confirms only that one command in a chain.', }; } diff --git a/plugins/lua-agent-builder/hooks/detect-project.mjs b/plugins/lua-agent-builder/hooks/detect-project.mjs index a6b41f5..e37bf38 100644 --- a/plugins/lua-agent-builder/hooks/detect-project.mjs +++ b/plugins/lua-agent-builder/hooks/detect-project.mjs @@ -13,6 +13,7 @@ import { existsSync, readFileSync } from 'node:fs'; import { join } from 'node:path'; import { runHook, checkNodeVersion, isMainScript } from '../lib/hook-runtime.mjs'; +import { isHeadless } from '../lib/headless.mjs'; /** * Pure decision function. Reads from disk synchronously β€” file existence @@ -25,7 +26,9 @@ import { runHook, checkNodeVersion, isMainScript } from '../lib/hook-runtime.mjs * Test injection point retained as `opts.cwd` for backward compat. * * @param {{cwd?: string}|null} input β€” Claude Code hook payload - * @param {{cwd?: string}} [opts] β€” test override; takes precedence over input.cwd + * @param {{cwd?: string, env?: Record}} [opts] β€” test override; + * `cwd` takes precedence over input.cwd; `env` defaults to process.env (headless switch: + * no "run /lua-doctor" pointer when LUA_PLUGIN_HEADLESS=1) */ export function decide(input, opts = {}) { const cwd = opts.cwd ?? input?.cwd ?? process.cwd(); @@ -48,10 +51,9 @@ export function decide(input, opts = {}) { // Permission denied, etc. β€” print a generic message and move on. } + const detected = agentId ? `βœ“ Lua agent project detected: ${agentId}.` : 'βœ“ Lua agent project detected.'; return { - warn: agentId - ? `βœ“ Lua agent project detected: ${agentId}. Run /lua-doctor or /lua-test to begin.` - : 'βœ“ Lua agent project detected. Run /lua-doctor or /lua-test to begin.', + warn: isHeadless(opts.env ?? process.env) ? detected : `${detected} Run /lua-doctor or /lua-test to begin.`, }; } diff --git a/plugins/lua-agent-builder/hooks/post-deploy-smoke.mjs b/plugins/lua-agent-builder/hooks/post-deploy-smoke.mjs index 8e29219..49288bc 100644 --- a/plugins/lua-agent-builder/hooks/post-deploy-smoke.mjs +++ b/plugins/lua-agent-builder/hooks/post-deploy-smoke.mjs @@ -14,6 +14,7 @@ import { runHook, checkNodeVersion, isMainScript } from '../lib/hook-runtime.mjs'; import { classifyProductionCommand, SMOKE_LABELS } from '../lib/tokenizer.mjs'; +import { isHeadless } from '../lib/headless.mjs'; /** How far back the post-deploy log scan looks, in both spellings. */ const SMOKE_WINDOW = '1m'; @@ -21,12 +22,17 @@ const SMOKE_WINDOW_MS = 60_000; /** * @param {{tool_input?: {command?: string}, tool_response?: {success?: boolean}}|null} input - * @param {{spawnLuaFn?: Function}} [opts] β€” injectable for tests + * @param {{spawnLuaFn?: Function, env?: Record}} [opts] β€” injectable for tests */ export async function decide( input, - { spawnLuaFn } = {} + { spawnLuaFn, env = process.env } = {} ) { + // Headless (LUA_PLUGIN_HEADLESS=1): never send a production `lua chat` ping + // from an unattended run. confirm-deploy blocks every production verb there, + // so reaching this point would itself be a finding for the harness, not + // something to probe with more production traffic. + if (isHeadless(env)) return null; const command = input?.tool_input?.command ?? ''; const classified = classifyProductionCommand(command); if (!classified || !SMOKE_LABELS.has(classified.label)) return null; diff --git a/plugins/lua-agent-builder/lib/headless.mjs b/plugins/lua-agent-builder/lib/headless.mjs new file mode 100644 index 0000000..cc34804 --- /dev/null +++ b/plugins/lua-agent-builder/lib/headless.mjs @@ -0,0 +1,33 @@ +// Headless mode (EM-WS8, 1.6.0). See docs/JOB_TIER.md at the repository root. +// +// `LUA_PLUGIN_HEADLESS=1` tells the hooks that no human is in the loop β€” the +// plugin runs inside `claude -p` in the Lua Job tier (or any other +// unattended harness). In that mode: +// +// * no hook message points at a slash command. The slashes that fix things +// (/lua-auth, /lua-doctor, /lua-update, /lua-deploy, /lua-template) all +// need AskUserQuestion or the Agent tool, both unavailable headless, and a +// message naming them steers the model into a flow that cannot complete; +// * confirm-deploy treats the LUA_DEPLOY_CONFIRMED=1 prefix as VOID. The +// prefix means "a person confirmed this deploy"; headless, the model would +// be confirming to itself. Every production verb is blocked (fail closed); +// production changes are made outside the run; +// * post-deploy-smoke never sends its production `lua chat` ping. +// +// Blocking behaviour is otherwise identical: every command that is blocked +// interactively is blocked headless too. + +const TRUTHY = new Set(['1', 'true', 'yes', 'on']); + +/** + * @param {Record} [env] + * @returns {boolean} + */ +export function isHeadless(env = process.env) { + return TRUTHY.has(String(env?.LUA_PLUGIN_HEADLESS ?? '').trim().toLowerCase()); +} + +/** The sentence every headless message ends with instead of a slash command. */ +export const HEADLESS_NOTE = + 'This is a headless run (LUA_PLUGIN_HEADLESS=1): there is no one to answer a prompt, so do not start ' + + 'an interactive sign-in, install or deploy flow β€” continue with the task, or report the problem in your result.'; diff --git a/plugins/lua-agent-builder/lib/hook-runtime.mjs b/plugins/lua-agent-builder/lib/hook-runtime.mjs index 770408c..edb1e60 100644 --- a/plugins/lua-agent-builder/lib/hook-runtime.mjs +++ b/plugins/lua-agent-builder/lib/hook-runtime.mjs @@ -6,6 +6,7 @@ import { fileURLToPath } from 'node:url'; import { resolve } from 'node:path'; +import { isHeadless } from './headless.mjs'; const REQUIRED_NODE_MAJOR = 18; @@ -23,7 +24,8 @@ export function checkNodeVersion() { if (major < REQUIRED_NODE_MAJOR) { log.toClaudeCode( `LUA_NODE_VERSION_TOO_OLD: This plugin requires Node β‰₯${REQUIRED_NODE_MAJOR}. ` + - `You have ${process.versions.node}. Update Node and re-run /lua-doctor.` + `You have ${process.versions.node}. ` + + (isHeadless() ? 'The plugin hooks are inactive in this run.' : 'Update Node and re-run /lua-doctor.') ); exit(0); // Fail-open per Β§6.1 } diff --git a/plugins/lua-agent-builder/lib/tokenizer.mjs b/plugins/lua-agent-builder/lib/tokenizer.mjs index 2433888..aeb76c2 100644 --- a/plugins/lua-agent-builder/lib/tokenizer.mjs +++ b/plugins/lua-agent-builder/lib/tokenizer.mjs @@ -1,8 +1,7 @@ -// Per tech spec Β§17.4 / feature doc Β§6.5. +// Per tech spec Β§17.4 / feature doc Β§6.5, hardened in 1.6.0 (EM-WS8). // Parses bash command strings to detect production-affecting lua-cli // invocations and the LUA_DEPLOY_CONFIRMED=1 prefix that signals -// user-authorised intent. Refuses shell wrappers and pipes β€” these can't be -// safely classified, so they're denied even with the right env var. +// user-authorised intent. // // THIS FILE IS THE SINGLE SOURCE OF TRUTH for "what changes production". // hooks/confirm-deploy.mjs and hooks/post-deploy-smoke.mjs classify with it @@ -15,11 +14,13 @@ // // The gated set is every lua-cli verb that changes what runs in production // (verified against packages/lua-cli/src/cli/command-definitions.ts and -// src/utils/aliases.ts, lua-cli 3.33.0), INCLUDING the action aliases the CLI -// resolves at runtime (aliases.ts: `publish` β†’ deploy, `on`/`enable` β†’ -// activate, `submit`/`publish_version` β†’ template publish, `deploy`/ -// `fleet-apply`/`rollout` β†’ template apply, `prod`/`prd`/`live` β†’ -// production) and the three installed binaries (`lua`, `heylua`, `lua-ai`). +// src/utils/aliases.ts), INCLUDING the action aliases the CLI resolves at +// runtime (aliases.ts: `publish` β†’ deploy, `on`/`enable` β†’ activate, +// `submit`/`publish_version` β†’ template publish, `deploy`/`fleet-apply`/ +// `rollout` β†’ template apply, `prod`/`prd`/`live` β†’ production, +// `templates`/`agent-template(s)` β†’ template) and the three installed +// binaries (`lua`, `heylua`, `lua-ai`). `normalizeArg` lower-cases every +// action word, so matching is case-insensitive. // // lua deploy per-primitive publish (skill, webhook, trigger, job, pre/postprocessor, persona, all) // lua skills|webhooks|jobs|preprocessors|postprocessors deploy|publish the same publish, older spelling @@ -34,34 +35,163 @@ // `lua push … --auto-deploy` publishes as a side effect of a push and is // never allowed, prefix or not (lua-cli ignores it for `push all`, but a // granular push would deploy). +// +// ── How a command is read (1.6.0) ───────────────────────────────────────── +// Up to 1.5.0 this was a regex anchored at the start of the string, so +// `cd x && lua deploy all`, `true; lua version promote 3`, `FOO=1 lua deploy +// all`, `/usr/local/bin/lua deploy all` and `npx lua deploy all` all passed +// (Job-tier audit, finding 3). The classifier now LEXES the command the way a +// POSIX shell would β€” quotes, escapes, `&& || ; | |& &`, newlines, `( )` and +// `{ }` groups, redirections, heredocs β€” and inspects EVERY simple command: +// +// * the lua binary is recognised in COMMAND POSITION, by basename +// (`/usr/local/bin/lua`, `./node_modules/.bin/heylua`, `lua.cmd`, `LUA`): +// the first word after env assignments, and the command a wrapper runs β€” +// `sudo`/`env`/`command`/`exec`/`timeout N`/`nohup`/`xargs`/`watch`/ +// `coproc`/`if`/`then`/…, launchers (`npx lua`, `npx lua-cli`, +// `npx -y lua-cli@3`, `pnpm exec lua`, `pnpm dlx lua-cli`, `yarn lua`, +// `npm exec -- lua`, `bunx lua`), `node [opts] …/lua-cli/dist/index.js` +// and `find … -exec lua …`. `cp -r lua deploy` is not a deploy; +// * option tokens between the binary and the verb are skipped (both as +// boolean flags and as `--flag value` pairs); +// * a word the shell computes at runtime β€” `$VAR`, `$(…)`, `${IFS}`, +// `$'\x6c…'`, an unquoted glob (`lu?`) or brace expansion (`{lua,}`) β€” +// in the binary or verb position cannot be resolved and is blocked when +// the command mentions lua (fail closed); +// * `$(…)`, backticks and `<(…)` are parsed recursively, also inside +// double quotes and unquoted heredocs; heredoc bodies are skipped as text +// (`gh pr create --body "$(cat <<'EOF' … EOF)"` is not code); a string +// handed to a shell (`bash -c`, `eval`, `ssh`, `env -S`, `watch`, +// `tmux`, `npx -c`, `… | sh`, `bash < <(…)`, a heredoc fed to a shell or +// written to a script that is then run, `trap`, `alias`, +// `git -c alias.x='!…'`) is parsed recursively too; inline code for +// `node -e` / `python -c` / `perl -e` / `osascript -e`, awk `system(…)`, +// sed's `e` command and editor `-c '!…'` is searched as text; +// * input the lexer cannot close (an unterminated quote or substitution) +// falls back to a textual token search; +// * everything is linear; a command over MAX_COMMAND_LENGTH, one that runs +// past TIME_BUDGET_MS, or an internal error BLOCKS if the command +// mentions lua β€” the hook must decide inside its timeout, because a hook +// that times out fails open. +// +// The LUA_DEPLOY_CONFIRMED=1 allowance survives ONLY in its canonical shape: +// `[env ]LUA_DEPLOY_CONFIRMED=1 lua|heylua|lua-ai …` as ONE simple +// command β€” the assignment is the first word of the very simple command that +// runs the verb, the binary is spelled bare, and the command is not part of a +// pipeline, a `( )`/`{ }` group, a substitution or a string run by another +// shell. `export LUA_DEPLOY_CONFIRMED=1; lua deploy all`, +// `LUA_DEPLOY_CONFIRMED=1 true && lua deploy all` and +// `LUA_DEPLOY_CONFIRMED=1 npx lua deploy all` are all blocked. In a chain, +// every production verb needs its own prefix; one unprefixed verb blocks the +// whole command. +// +// This is a belt, not the boundary. A determined caller can always build the +// command at runtime (`base64 -d | sh`, a script file, an npm script, a raw +// HTTP call). In the Lua Job tier the Lua-API proxy is the boundary; see +// docs/JOB_TIER.md. -const PREFIX = /^(?:env\s+)?LUA_DEPLOY_CONFIRMED=1\s+/; -const WRAPPER_HEAD = /^(bash|sh|zsh)\s/; const BIN = '(?:lua|heylua|lua-ai)'; -const rule = (label, body, slash) => ({ label, re: new RegExp(`^${BIN}\\s+${body}`), slash }); +/** Binaries lua-cli installs (package.json `bin`). */ +const BINARIES = new Set(['lua', 'heylua', 'lua-ai']); +/** Also accepted after a launcher (`npx lua-cli …`) or as a node entry point. */ +const PACKAGES = new Set([...BINARIES, 'lua-cli']); + +/** + * Commands (and shell keywords) that take ANOTHER command as argv: the word + * after them β€” past their options and option values β€” is again in command + * position. The lua binary is only recognised in command position, so + * `cp -r lua deploy` and `ls lua deploy` are not deploys. + */ +const WRAPPERS = new Set([ + 'env', 'command', 'exec', 'builtin', 'nohup', 'time', 'nice', 'ionice', 'timeout', 'sudo', 'doas', + 'xargs', 'stdbuf', 'setsid', 'caffeinate', 'unbuffer', 'chronic', 'npx', 'pnpx', 'bunx', 'npm', + 'pnpm', 'yarn', 'bun', 'run', 'dlx', 'x', 'eval', 'watch', 'coproc', 'flock', 'nodemon', 'entr', + 'node', 'nodejs', 'tsx', 'ts-node', 'deno', 'ssh', 'su', 'runuser', 'parallel', 'strace', 'ltrace', + 'gtimeout', 'unshare', 'chroot', 'nsenter', 'firejail', 'script', 'tmux', 'screen', + '!', 'then', 'do', 'else', 'elif', 'if', 'while', 'until', +]); + +/** `find … -exec CMD …`: the word after one of these is in command position. */ +const EXEC_FLAGS = new Set(['-exec', '-execdir', '-ok', '-okdir']); + +/** Commands that run a STRING as shell code (their string arguments are parsed, and searched, as code). */ +const SCRIPT_RUNNERS = new Set([ + 'sh', 'bash', 'zsh', 'dash', 'ksh', 'mksh', 'ash', 'fish', 'busybox', 'pwsh', 'powershell', 'cmd', + 'eval', 'ssh', 'su', 'runuser', 'script', 'flock', 'watch', 'parallel', 'npx', 'npm', 'concurrently', + 'nodemon', 'entr', 'trap', 'at', 'batch', 'source', '.', 'tmux', 'screen', 'xargs', +]); + +/** Shell interpreters: their name counts as a runner at any word position. */ +const SHELLS = new Set(['sh', 'bash', 'zsh', 'dash', 'ksh', 'mksh', 'ash', 'fish', 'pwsh', 'powershell']); + +/** Shells, and `source`/`.` β€” running one of these on a FILE executes whatever was written to it. */ +const FILE_RUNNERS = new Set(['sh', 'bash', 'zsh', 'dash', 'ksh', 'mksh', 'ash', 'fish', 'source', '.']); + +/** Interpreters whose inline code (after `-e`, `-c`, `-p`, `-r`, …) is searched textually. */ +const INLINE_CODE = new Set([ + 'node', 'nodejs', 'bun', 'deno', 'python', 'python2', 'python3', 'perl', 'ruby', 'php', 'osascript', + 'luajit', 'tclsh', 'rscript', 'pwsh', 'powershell', +]); +/** An option that introduces inline code for one of INLINE_CODE (`-e`, `-pe`, `-c`, `--eval`, …). */ +const INLINE_FLAG = /^-(?:[a-zA-Z]*[ecEpr]|-eval|-print|-command|-exec)$/; +/** awk runs shell commands through `system(…)`, `print … | "cmd"` and `"cmd" | getline`. */ +const AWK = new Set(['awk', 'gawk', 'mawk', 'nawk', 'busybox']); +const AWK_EXEC = /system\s*\(|\|\s*["'$]|["']\s*\|\s*getline|\|&/; +/** Editors whose `-c` / `+cmd` / `:!cmd` run shell commands. */ +const EDITORS = new Set(['vim', 'vi', 'nvim', 'ex', 'view', 'gvim', 'mvim', 'nano', 'emacs']); + +const MAX_DEPTH = 6; + +/** + * Commands longer than this are not parsed: a command that mentions a lua + * binary is blocked as unclassifiable, any other passes. Every step below is + * linear, but the hook must decide well inside its 10 s timeout on any input β€” + * a hook that times out fails OPEN. + */ +export const MAX_COMMAND_LENGTH = 32 * 1024; +/** Wall-clock budget for one classification; exceeding it fails closed. */ +export const TIME_BUDGET_MS = 1500; + +const rule = (label, seq, slash) => ({ + label, + seq, + slash, + re: new RegExp(`^${BIN}\\s+${seq.map((alts) => `(?:${alts.join('|')})`).join('\\s+')}(?![\\w-])`, 'i'), +}); + +const DEPLOY = ['deploy', 'publish']; +const ACTIVATE = ['activate', 'on', 'enable']; +const PROD_ENV = ['production', 'prod', 'prd', 'live']; +const TEMPLATE = ['template', 'templates', 'agent-template', 'agent-templates']; /** - * Ordered list of gated command shapes. Each entry: the regex that matches - * the command (after any prefix is stripped; anchored at the binary), a short - * label, and the slash command that collects the user's confirmation. + * Ordered list of gated command shapes. Each entry: the positional token + * sequence (each position lists every spelling the CLI accepts), the + * equivalent binary-anchored regex, a short label, and the slash command that + * collects the user's confirmation. */ export const PRODUCTION_COMMANDS = [ - rule('lua deploy', 'deploy\\b', '/lua-deploy'), - rule('lua skills deploy', 'skills\\s+(?:deploy|publish)\\b', '/lua-deploy'), - rule('lua webhooks deploy', 'webhooks\\s+(?:deploy|publish)\\b', '/lua-deploy'), - rule('lua jobs deploy', 'jobs\\s+(?:deploy|publish)\\b', '/lua-deploy'), - rule('lua preprocessors deploy', 'preprocessors\\s+(?:deploy|publish)\\b', '/lua-deploy'), - rule('lua postprocessors deploy', 'postprocessors\\s+(?:deploy|publish)\\b', '/lua-deploy'), - rule('lua persona production deploy', 'persona\\s+(?:production|prod|prd|live)\\s+(?:deploy|publish)\\b', '/lua-deploy'), - rule('lua workflows deploy', 'workflows\\s+(?:deploy|publish)\\b', '/lua-deploy'), - rule('lua workflows activate', 'workflows\\s+(?:activate|on|enable)\\b', '/lua-deploy'), - rule('lua version promote', 'version\\s+promote\\b', '/lua-deploy'), - rule('lua mcp activate', 'mcp\\s+(?:activate|on|enable)\\b', '/lua-deploy'), - rule('lua marketplace template publish', 'marketplace\\s+template\\s+(?:publish|publish_version|submit)\\b', '/lua-template'), - rule('lua marketplace template apply', 'marketplace\\s+template\\s+(?:apply|deploy|fleet-apply|rollout)\\b', '/lua-template'), + rule('lua deploy', [['deploy']], '/lua-deploy'), + rule('lua skills deploy', [['skills'], DEPLOY], '/lua-deploy'), + rule('lua webhooks deploy', [['webhooks'], DEPLOY], '/lua-deploy'), + rule('lua jobs deploy', [['jobs'], DEPLOY], '/lua-deploy'), + rule('lua preprocessors deploy', [['preprocessors'], DEPLOY], '/lua-deploy'), + rule('lua postprocessors deploy', [['postprocessors'], DEPLOY], '/lua-deploy'), + rule('lua persona production deploy', [['persona'], PROD_ENV, DEPLOY], '/lua-deploy'), + rule('lua workflows deploy', [['workflows'], DEPLOY], '/lua-deploy'), + rule('lua workflows activate', [['workflows'], ACTIVATE], '/lua-deploy'), + rule('lua version promote', [['version'], ['promote']], '/lua-deploy'), + rule('lua mcp activate', [['mcp'], ACTIVATE], '/lua-deploy'), + rule('lua marketplace template publish', [['marketplace'], TEMPLATE, ['publish', 'publish_version', 'submit']], '/lua-template'), + rule('lua marketplace template apply', [['marketplace'], TEMPLATE, ['apply', 'deploy', 'fleet-apply', 'rollout']], '/lua-template'), ]; +/** Label for a lua invocation whose binary or verb comes from an expansion (cannot be resolved statically). */ +export const UNRESOLVED_LABEL = 'lua '; +/** Label for a command that mentions lua but could not be classified (too long, over budget, internal error). */ +export const UNCLASSIFIABLE_LABEL = 'lua '; + /** Labels whose success should trigger the post-deploy smoke check (something now runs live). */ export const SMOKE_LABELS = new Set([ 'lua deploy', 'lua skills deploy', 'lua webhooks deploy', 'lua jobs deploy', 'lua preprocessors deploy', @@ -69,35 +199,763 @@ export const SMOKE_LABELS = new Set([ 'lua mcp activate', ]); +// Unanchored textual patterns β€” the fallback for input the lexer cannot close +// and for inline interpreter code. `lua-cli/` covers a node entry point. +// +// The textual fallback (for input the lexer cannot close, and for inline +// interpreter code) is a TOKEN scan, not a regex: split on everything that +// cannot be part of a word, then read each lua token's next few tokens with +// the same matchArgs() the parser uses. Linear in the text, and interruptible +// by the time budget. Two regex drafts were not: `-{1,2}[\w-]+` backtracked +// exponentially (28 options β‰ˆ 200 s) and a path group re-scanned the text +// from every `lua` (`lua/` Γ— 6000 β‰ˆ 10 s) β€” both past the hook timeout, where +// a hook fails OPEN. test/lib/tokenizer-hardening.test.mjs and +// test/hooks/confirm-deploy.timeout.test.mjs pin the bound. +const RAW_TOKEN_SPLIT = /[^\w.@/\\-]+/; + +/** Does the text mention a lua binary at all? (Used to fail closed.) */ +const MENTIONS_LUA = /(? deadline) throw new BudgetExceeded('time budget exceeded'); +} + +// ── Lexer ────────────────────────────────────────────────────────────────── + +/** + * @typedef {{text: string, quoted: boolean, dynamic: boolean}} Word + * @typedef {{words: Word[], sep: string|null, grouped: boolean, pipeline: boolean, pipeId: number, + * heredocs: string[], herestrings: string[]}} Segment + */ + +const newSegment = () => ({ + words: [], sep: null, grouped: false, pipeline: false, pipeId: 0, heredocs: [], herestrings: [], subs: [], +}); + +/** + * Parse the delimiter of a heredoc whose `<<` starts at `i`. + * @returns {{delim: string, strip: boolean, quoted: boolean, end: number}} + */ +function parseHeredocDelim(src, i) { + const n = src.length; + i += 2; + const strip = src[i] === '-'; + if (strip) i++; + while (src[i] === ' ' || src[i] === '\t') i++; + let delim = ''; + let quoted = false; + while (i < n && !/[\s;&|<>()]/.test(src[i])) { + if (src[i] === "'" || src[i] === '"' || src[i] === '\\') quoted = true; + else delim += src[i]; + i++; + } + return { delim, strip, quoted, end: i }; +} + +/** + * Skip heredoc bodies that start at `i` (just after a newline), one per + * pending delimiter. Returns the index after the last body and each body. + */ +function skipHeredocBodies(src, i, pending) { + const n = src.length; + const bodies = []; + for (const h of pending) { + const lines = []; + while (i < n) { + checkBudget(); + let end = src.indexOf('\n', i); + if (end < 0) end = n; + const line = src.slice(i, end); + i = end + 1; + if ((h.strip ? line.replace(/^\t+/, '') : line) === h.delim) break; + lines.push(line); + } + if (i > n) i = n; + bodies.push(lines.join('\n')); + } + return { next: i, bodies }; +} + +/** + * Index of the `)` closing the `(` at `start`, honouring quotes, nesting and + * heredoc bodies (a body is literal text: `$(cat <<'EOF'\n it's \nEOF\n)` is + * how Claude Code writes every commit message and PR body); -1 if none. + */ +function findClose(src, start) { + let depth = 0; + let pending = []; + for (let i = start; i < src.length; i++) { + checkBudget(); + const c = src[i]; + if (c === '\n' && pending.length) { + i = skipHeredocBodies(src, i + 1, pending).next - 1; + pending = []; + continue; + } + if (c === '<' && src[i + 1] === '<') { + if (src[i + 2] === '<') { i += 2; continue; } + const h = parseHeredocDelim(src, i); + pending.push(h); + i = h.end - 1; + continue; + } + if (c === '\\') { i++; continue; } + if (c === "'") { + const j = src.indexOf("'", i + 1); + if (j < 0) return -1; + i = j; + continue; + } + if (c === '"') { + let j = i + 1; + while (j < src.length && src[j] !== '"') j += src[j] === '\\' ? 2 : 1; + if (j >= src.length) return -1; + i = j; + continue; + } + if (c === '#' && (i === start + 1 || /[\s;&|(]/.test(src[i - 1]))) { + // A comment runs to end of line; its quotes and parentheses are text. + const nl = src.indexOf('\n', i); + if (nl < 0) return -1; + i = nl - 1; + continue; + } + if (c === '(') depth++; + else if (c === ')' && --depth === 0) return i; + } + return -1; +} + +/** Index of the next unescaped backtick after `start`; -1 if none. */ +function findBacktick(src, start) { + for (let i = start + 1; i < src.length; i++) { + if (src[i] === '\\') { i++; continue; } + if (src[i] === '`') return i; + } + return -1; +} + +/** + * Split a shell command into simple commands. Collects command-substitution + * bodies (`$(…)`, backticks, `<(…)`, and those inside an unquoted heredoc) in + * `subs` β€” and in the owning segment's `subs` β€” for recursive inspection, and + * sets `opaque` when something could not be closed. + * + * A word is `dynamic` when the shell would compute it at runtime: parameter + * or command expansion, ANSI-C quoting, an unquoted glob (`lu?`, `l*a`) or an + * unquoted brace expansion (`{lua,}`, `de{ploy,}`). + * + * @param {string} src + * @returns {{segments: Segment[], subs: string[], opaque: boolean}} + */ +export function lex(src) { + /** @type {Segment[]} */ + const segments = []; + const subs = []; + let opaque = false; + let seg = newSegment(); + /** @type {(Word & {brace?: boolean})|null} */ + let word = null; + let depth = 0; + let redirTarget = null; // null | 'file' | 'herestring' + /** @type {{delim: string, strip: boolean, quoted: boolean, seg: Segment}[]} */ + let pendingHeredocs = []; + const n = src.length; + let i = 0; + + const addSub = (text) => { subs.push(text); seg.subs.push(text); }; + const startWord = () => { if (!word) word = { text: '', quoted: false, dynamic: false }; return word; }; + const endWord = () => { + if (!word) return; + const w = word; + word = null; + if (w.brace && /\{[^{}]*(?:,|\.\.)[^{}]*\}/.test(w.text)) w.dynamic = true; + delete w.brace; + if (redirTarget) { + if (redirTarget === 'herestring') seg.herestrings.push(w.text); + redirTarget = null; + return; + } + if (!w.quoted && w.text === '{') { + // Brace group: `{ cmd; }` (also `function f { …; }`). What precedes it is + // its own command; what follows starts a new, grouped one. + if (seg.words.length) endSegment(';'); + depth++; + seg.grouped = true; + return; + } + if (!w.quoted && w.text === '}') { depth = Math.max(0, depth - 1); return; } + seg.words.push(w); + }; + const endSegment = (sep) => { + endWord(); + if (seg.words.length || seg.heredocs.length || seg.herestrings.length || seg.subs.length) { + seg.sep = sep; + if (depth > 0) seg.grouped = true; + segments.push(seg); + } else if ((sep === '|' || sep === '|&') && segments.length) { + segments[segments.length - 1].sep = sep; + } + seg = newSegment(); + }; + const takeSubstitution = (open) => { + // `open` indexes the `(` of `$(`, `<(` or `>(`. + const close = findClose(src, open); + if (close < 0) { opaque = true; addSub(src.slice(open + 1)); return n; } + addSub(src.slice(open + 1, close)); + return close + 1; + }; + /** Command substitutions inside an UNQUOTED heredoc body run (`cat < { + for (let k = 0; k < body.length; k++) { + checkBudget(); + if (body[k] === '\\') { k++; continue; } + if (body[k] === '$' && body[k + 1] === '(') { + const close = findClose(body, k + 1); + const text = close < 0 ? body.slice(k + 2) : body.slice(k + 2, close); + if (close < 0) opaque = true; + subs.push(text); + owner.subs.push(text); + if (close < 0) return; + k = close; + } else if (body[k] === '`') { + const close = findBacktick(body, k); + const text = close < 0 ? body.slice(k + 1) : body.slice(k + 1, close); + if (close < 0) opaque = true; + subs.push(text); + owner.subs.push(text); + if (close < 0) return; + k = close; + } + } + }; + const readHeredocBodies = () => { + const { next, bodies } = skipHeredocBodies(src, i, pendingHeredocs); + pendingHeredocs.forEach((h, k) => { + h.seg.heredocs.push(bodies[k]); + if (!h.quoted) scanExpandingBody(bodies[k], h.seg); + }); + i = next; + pendingHeredocs = []; + }; + + while (i < n) { + checkBudget(); + const c = src[i]; + const next = src[i + 1]; + + if (c === '\\') { + if (next === '\n') { i += 2; continue; } + const w = startWord(); + w.quoted = true; + if (next !== undefined) w.text += next; + i += 2; + continue; + } + if (c === "'") { + const w = startWord(); + w.quoted = true; + const j = src.indexOf("'", i + 1); + if (j < 0) { opaque = true; w.text += src.slice(i + 1); i = n; continue; } + w.text += src.slice(i + 1, j); + i = j + 1; + continue; + } + if (c === '"') { + const w = startWord(); + w.quoted = true; + let j = i + 1; + let closed = false; + while (j < n) { + checkBudget(); + const d = src[j]; + if (d === '"') { closed = true; break; } + if (d === '\\') { + const e = src[j + 1]; + if (e === '\n') { j += 2; continue; } + if (e !== undefined && '$`"\\'.includes(e)) { w.text += e; j += 2; continue; } + w.text += d; + j++; + continue; + } + if (d === '$' && src[j + 1] === '(') { w.dynamic = true; w.text += '$(…)'; j = takeSubstitution(j + 1); continue; } + if (d === '`') { + const k = findBacktick(src, j); + w.dynamic = true; + if (k < 0) { opaque = true; addSub(src.slice(j + 1)); j = n; break; } + addSub(src.slice(j + 1, k)); + w.text += '`…`'; + j = k + 1; + continue; + } + if (d === '$' && /[A-Za-z_{0-9@*#?$!-]/.test(src[j + 1] ?? '')) w.dynamic = true; + w.text += d; + j++; + } + if (!closed) opaque = true; + i = j + 1; + continue; + } + if (c === '`') { + const w = startWord(); + w.dynamic = true; + const k = findBacktick(src, i); + if (k < 0) { opaque = true; addSub(src.slice(i + 1)); i = n; continue; } + addSub(src.slice(i + 1, k)); + w.text += '`…`'; + i = k + 1; + continue; + } + if (c === '$') { + const w = startWord(); + if (next === '(') { w.dynamic = true; w.text += '$(…)'; i = takeSubstitution(i + 1); continue; } + if (next === "'") { + // ANSI-C quoting ($'\x6cua') can spell anything β€” treat as unresolvable. + w.dynamic = true; + w.quoted = true; + let j = i + 2; + while (j < n && src[j] !== "'") j += src[j] === '\\' ? 2 : 1; + if (j >= n) opaque = true; + w.text += src.slice(i, j + 1); + i = j + 1; + continue; + } + if (next === '"') { i++; continue; } // $"…" locale string = "…" + if (/[A-Za-z_{0-9@*#?$!-]/.test(next ?? '')) w.dynamic = true; + w.text += '$'; + i++; + continue; + } + if (c === ' ' || c === '\t' || c === '\r' || UNICODE_SPACE.test(c)) { endWord(); i++; continue; } + if (c === '\n') { + endWord(); + i++; + if (pendingHeredocs.length) readHeredocBodies(); + endSegment(';'); + continue; + } + if (c === '#' && !word) { + while (i < n && src[i] !== '\n') i++; + continue; + } + if (c === ';') { endSegment(';'); i += next === ';' ? 2 : 1; continue; } + if (c === '&') { + if (next === '&') { endSegment('&&'); i += 2; continue; } + if (next === '>') { + endWord(); + i += src[i + 2] === '>' ? 3 : 2; + redirTarget = 'file'; + continue; + } + endSegment('&'); + i++; + continue; + } + if (c === '|') { + if (next === '|') { endSegment('||'); i += 2; continue; } + if (next === '&') { endSegment('|&'); i += 2; continue; } + endSegment('|'); + i++; + continue; + } + if (c === '(') { + if (word && word.text.endsWith('=')) { + // Array assignment `a=(x y)` β€” keep it as one word. + const close = findClose(src, i); + if (close < 0) { opaque = true; i = n; continue; } + word.text += src.slice(i, close + 1); + i = close + 1; + continue; + } + endWord(); + if (next === ')' && seg.words.length) { i += 2; continue; } // `name()` function definition + endSegment(';'); + depth++; + i++; + continue; + } + if (c === ')') { + endWord(); + if (seg.words.length) { seg.grouped = true; } + endSegment(')'); + depth = Math.max(0, depth - 1); + i++; + continue; + } + if (c === '<' || c === '>') { + if (next === '(') { + // Process substitution <(…) / >(…) is a word that runs a command. + const w = startWord(); + w.dynamic = true; + w.text += `${c}(…)`; + i = takeSubstitution(i + 1); + continue; + } + if (word && !word.quoted && !word.dynamic && /^\d+$/.test(word.text)) word = null; // fd number + else endWord(); + if (src.startsWith('<<<', i)) { i += 3; redirTarget = 'herestring'; continue; } + if (src.startsWith('<<', i)) { + const h = parseHeredocDelim(src, i); + pendingHeredocs.push({ delim: h.delim, strip: h.strip, quoted: h.quoted, seg }); + i = h.end; + continue; + } + i++; + if ('>&|'.includes(src[i] ?? '') && !(c === '<' && src[i] === '|')) i++; + if (src[i - 1] === '&') { + let consumed = false; + while (i < n && /[\d-]/.test(src[i])) { i++; consumed = true; } + if (consumed) continue; + } + redirTarget = 'file'; + continue; + } + const w = startWord(); + if (c === '*' || c === '?' || c === '[') w.dynamic = true; // unquoted glob + if (c === '{') w.brace = true; // possible brace expansion, decided at endWord + w.text += c; + i++; + } + if (pendingHeredocs.length) readHeredocBodies(); + endSegment(null); + + let pipeId = 0; + for (let k = 0; k < segments.length; k++) { + segments[k].pipeId = pipeId; + const piped = segments[k].sep === '|' || segments[k].sep === '|&'; + if (piped) { + segments[k].pipeline = true; + if (segments[k + 1]) segments[k + 1].pipeline = true; + } else { + pipeId++; + } + } + return { segments, subs, opaque }; +} + +// ── Classification ───────────────────────────────────────────────────────── + +/** Command name as the shell would resolve it: basename, no `@version`, no Windows extension, lower-cased. */ +function commandName(text) { + let b = text.split(/[\\/]/).pop() ?? ''; + const at = b.indexOf('@', 1); + if (at > 0) b = b.slice(0, at); + return b.replace(/\.(?:cmd|exe|bat|ps1)$/i, '').toLowerCase(); +} + +const isFlag = (w) => w.text.length > 1 && w.text.startsWith('-'); +/** An assignment in the shell's sense (unquoted name). */ +const isAssignment = (w) => !w.quoted && /^[A-Za-z_][A-Za-z0-9_]*=/.test(w.text); +/** Anything that LOOKS like an assignment β€” skipped when looking for the command (fail closed). */ +const looksLikeAssignment = (w) => /^[A-Za-z_][A-Za-z0-9_]*=/.test(w.text); +const isPrefixWord = (w) => !!w && !w.quoted && !w.dynamic && w.text === 'LUA_DEPLOY_CONFIRMED=1'; +const nameOf = (w) => (w.dynamic ? '' : commandName(w.text)); + +/** Is `text` (a literal word, or the literal head of a dynamic one) a lua-cli binary or entry point? */ +function isLuaBinaryText(text, afterLauncher) { + const name = commandName(text); + if (BINARIES.has(name)) return true; + // `lua-cli` is the package name, not an installed binary: gated after a + // launcher (`npx lua-cli`), or as a path to the package. + if (name === 'lua-cli' && (afterLauncher || /[\\/]/.test(text))) return true; + // The entry point run by node or through its shebang: `…/lua-cli/dist/index.js`. + // Only the tail is examined, so a pathological 30 KB word costs one bounded scan. + return /(?:^|[\\/])(?:lua-cli|heylua|lua-ai)[\\/]\S*\.[mc]?js$/i.test(text.slice(-512)); +} + +/** Splits a dynamic word at its expansions: `lua${IFS}deploy${IFS}all` β†’ lua, deploy, all. */ +const EXPANSION = /\$\{[^}]*\}|\$[A-Za-z_][A-Za-z0-9_]*|\$[0-9@*#?$!-]|\$\(…\)|`…`|\$'[^']*'|[<>]\(…\)|[*?]|\[[^\]]*\]|[{},]/; + +/** + * Word indexes in command position: the first word after any leading + * assignments, and β€” after a wrapper (`sudo`, `env`, `npx`, `timeout`, `if`, + * `xargs`, `node`, …) β€” the next word past its options, option values, + * assignments and durations. An option's value may itself be the command + * (`sudo -u me lua …` vs `sudo -E lua …`), so both readings are kept. + * `find … -exec CMD` adds CMD. + */ +function commandPositions(words) { + const out = new Set(); + const seen = new Set(); + const walk = (start) => { + let k = start; + while (k < words.length && looksLikeAssignment(words[k])) k++; + if (k >= words.length || seen.has(k)) return; + seen.add(k); + out.add(k); + if (!WRAPPERS.has(nameOf(words[k]))) return; + let q = k + 1; + let afterFlag = false; + while (q < words.length) { + checkBudget(); + const w = words[q]; + if (w.text === '--' || isFlag(w)) { afterFlag = w.text !== '--' && !w.text.includes('='); q++; continue; } + if (looksLikeAssignment(w) || /^\d+(?:\.\d+)?[smhd]?$/.test(w.text)) { afterFlag = false; q++; continue; } + walk(q); + if (!afterFlag) return; + afterFlag = false; // it may have been the option's value: keep looking + q++; + } + }; + walk(0); + words.forEach((w, k) => { if (EXEC_FLAGS.has(w.text) && k + 1 < words.length) walk(k + 1); }); + return [...out].sort((a, b) => a - b); +} + /** - * Classify a command. Returns null for commands that are not gated, or - * `{ label, slash, prefixed }` for a production-affecting lua-cli verb. - * Shell wrappers and pipes are reported as unsafe (`prefixed: false`) even - * when the env var is present, because the real command can't be seen. + * If a lua-cli invocation starts at word `j` (a command position), return its + * arguments and whether the binary itself was computed at runtime; else null. + */ +function invocationAt(words, j, afterLauncher) { + const w = words[j]; + const rest = words.slice(j + 1, j + 1 + 64); + if (w.dynamic) { + // `lua${IFS}deploy`, `"$DIR/lua"`: the literal part can still name lua. + const pieces = w.text.split(new RegExp(EXPANSION.source, 'g')).filter(Boolean); + if (pieces.length && isLuaBinaryText(pieces[0], true)) { + const extra = pieces.slice(1).flatMap((p) => p.split(/\s+/)).filter(Boolean) + .map((text) => ({ text, quoted: false, dynamic: false })); + return { args: [...extra, ...rest], dynamicHead: false }; + } + return { args: rest, dynamicHead: true }; + } + if (isLuaBinaryText(w.text, afterLauncher)) return { args: rest, dynamicHead: false }; + return null; +} + +/** + * Match the arguments after a lua binary against the gated shapes. Options + * are skipped twice over β€” once as boolean flags, once as `--flag value` + * pairs β€” so neither reading hides a verb. + * + * @param {Word[]} args + * @param {boolean} allowDynamic a computed token may stand in for a verb + * @returns {{label: string, slash: string, dynamic: boolean}|null} + */ +function matchArgs(args, allowDynamic) { + const loose = []; // flags dropped, their values kept + const strict = []; // flags and the word after a value-less `--flag` dropped + let pendingValue = false; + for (const a of args) { + if (loose.length >= 3 && strict.length >= 3) break; + if (a.text === '--') { pendingValue = false; continue; } + if (isFlag(a)) { pendingValue = !a.text.includes('='); continue; } + loose.push(a); + if (pendingValue) pendingValue = false; + else strict.push(a); + } + let dynamicHit = null; + for (const positional of [loose, strict]) { + for (const entry of PRODUCTION_COMMANDS) { + let ok = true; + let usedDynamic = false; + for (let p = 0; p < entry.seq.length; p++) { + const tok = positional[p]; + if (!tok) { ok = false; break; } + if (tok.dynamic) { + if (!allowDynamic) { ok = false; break; } + usedDynamic = true; + continue; + } + if (!entry.seq[p].includes(tok.text.toLowerCase())) { ok = false; break; } + } + if (!ok) continue; + if (!usedDynamic) return { label: entry.label, slash: entry.slash, dynamic: false }; + dynamicHit ??= { label: UNRESOLVED_LABEL, slash: '/lua-deploy', dynamic: true }; + } + } + return dynamicHit; +} + +/** Unanchored textual search, for text the lexer cannot structure. Linear: a bounded window per lua token. */ +function rawSearch(text, hits) { + checkBudget(); + if (!MENTIONS_LUA.test(text)) return; + const toks = text.split(RAW_TOKEN_SPLIT); + for (let k = 0; k < toks.length; k++) { + checkBudget(); + const t = toks[k]; + if (!t || !isLuaBinaryText(t, true)) continue; + const args = []; + for (let q = k + 1; q < toks.length && args.length < 64; q++) { + if (toks[q]) args.push({ text: toks[q], quoted: false, dynamic: false }); + } + const m = matchArgs(args, false); + if (m) hits.push({ label: m.label, slash: m.slash, prefixed: false }); + } +} + +/** GNU sed's `e` command / `s///e` flag runs the pattern space as a shell command. */ +function sedExecutes(script) { + if (/(?:^|[;\n{}]|\d|\$|\/)\s*e(?:\s|$)/.test(script)) return true; + const m = /^s(.)/.exec(script); + if (!m) return false; + const parts = script.split(m[1]); + return parts.length >= 4 && /e/.test(parts[parts.length - 1]); +} + +/** + * @typedef {{nested: boolean, depth: number, mentionsLua: boolean}} Ctx + * @param {Segment} seg + * @param {Ctx} ctx + * @param {boolean} pipedIntoRunner another stage of this pipeline runs its input as code + * @param {Array<{label: string, slash: string, prefixed: boolean}>} hits + */ +function analyzeSegment(seg, ctx, pipedIntoRunner, hits) { + checkBudget(); + const words = seg.words; + const names = words.map(nameOf); + const positions = commandPositions(words); + // A runner counts in command position (`sudo bash -c`, `xargs sh -c`); a + // shell's name counts anywhere (`docker exec c sh -c …`). `rg x .` is not `source`. + const hasRunner = + positions.some((j) => SCRIPT_RUNNERS.has(names[j])) || names.some((nm) => SHELLS.has(nm)); + const runsStrings = pipedIntoRunner || hasRunner; + const inline = names.some((nm) => INLINE_CODE.has(nm)); + const awk = names.some((nm) => AWK.has(nm)); + const editor = names.some((nm) => EDITORS.has(nm)); + const sed = names.some((nm) => nm === 'sed' || nm === 'gsed'); + const hasEnv = names.includes('env'); + const nested = { ...ctx, nested: true, depth: ctx.depth + 1 }; + + // Whatever feeds a shell (`… | sh`) or a runner's argv (`ssh host lua …`, + // `eval lua …`) is searched as text as well as parsed. + if (runsStrings) rawSearch(words.map((w) => w.text).join(' '), hits); + words.forEach((w, k) => { + if (k === 0) return; + const prev = words[k - 1].text; + if (runsStrings && /[\s;&|`$()]/.test(w.text)) analyzeScript(w.text, nested, hits); + if (inline && (INLINE_FLAG.test(prev) || (prev === 'eval' && names.includes('deno')))) rawSearch(w.text, hits); + if (awk && AWK_EXEC.test(w.text)) rawSearch(w.text, hits); + if (editor && (/^[-+]c$|^--cmd$/.test(prev) || /^[+:]/.test(w.text) || w.text.includes('!'))) rawSearch(w.text, hits); + if (sed && !isFlag(w) && sedExecutes(w.text)) rawSearch(w.text, hits); + if (hasEnv && (prev === '-S' || prev === '--split-string')) analyzeScript(w.text, nested, hits); + if (hasEnv && /^(?:-S|--split-string=)./.test(w.text)) analyzeScript(w.text.replace(/^(?:-S|--split-string=)/, ''), nested, hits); + // `git -c alias.x='!cmd'` runs cmd through the shell. + const alias = /^alias\.[^=]*=\s*!(.*)$/s.exec(w.text); + if (alias) { analyzeScript(alias[1], nested, hits); rawSearch(alias[1], hits); } + if (names[0] === 'alias' || names[0] === 'trap') { + const eq = w.text.indexOf('='); + analyzeScript(eq > 0 ? w.text.slice(eq + 1) : w.text, nested, hits); + } + }); + for (const body of [...seg.heredocs, ...seg.herestrings]) { + if (runsStrings || inline || awk) { + analyzeScript(body, nested, hits); + rawSearch(body, hits); + } + } + // `bash < <(echo lua …)`, `source <(…)`: the substitution's OUTPUT is code. + if (runsStrings) for (const sub of seg.subs) rawSearch(sub, hits); + + for (const j of positions) { + const afterLauncher = j > 0; + const inv = invocationAt(words, j, afterLauncher); + if (!inv) continue; + // `… | xargs lua`: the verb arrives on stdin and cannot be classified. + const fedByXargs = names.slice(0, j).includes('xargs'); + // A computed binary with a computed verb (`$(printf lua) $(printf deploy)`) + // is blocked when the command mentions lua anywhere. + let match = matchArgs(inv.args, !inv.dynamicHead || ctx.mentionsLua); + if (!match && fedByXargs && !inv.dynamicHead) { + match = { label: UNRESOLVED_LABEL, slash: '/lua-deploy', dynamic: true }; + } + if (!match) continue; + const canonicalPrefix = + !inv.dynamicHead && + !words[j].dynamic && + BINARIES.has(words[j].text) && + ((j === 1 && isPrefixWord(words[0])) || + (j === 2 && words[0].text === 'env' && !words[0].quoted && isPrefixWord(words[1]))); + const prefixed = + canonicalPrefix && !match.dynamic && !ctx.nested && !seg.pipeline && !seg.grouped; + hits.push({ label: match.label, slash: match.slash, prefixed }); + } +} + +/** + * @param {string} src + * @param {Ctx} ctx + * @param {Array<{label: string, slash: string, prefixed: boolean}>} hits + */ +function analyzeScript(src, ctx, hits) { + checkBudget(); + if (ctx.depth > MAX_DEPTH) { rawSearch(src, hits); return; } + const { segments, subs, opaque } = lex(src); + if (opaque) rawSearch(src, hits); + + // A pipeline stage that runs its stdin as code (`… | sh`, `… | xargs sh -c`) + // turns every string in the pipeline into code. + const runnerPipes = new Set( + segments + .filter((s) => s.pipeline && commandPositions(s.words).some((j) => SCRIPT_RUNNERS.has(nameOf(s.words[j])))) + .map((s) => s.pipeId), + ); + for (const seg of segments) analyzeSegment(seg, ctx, runnerPipes.has(seg.pipeId), hits); + for (const sub of subs) analyzeScript(sub, { ...ctx, nested: true, depth: ctx.depth + 1 }, hits); + + // `cat > x.sh < { + const first = commandPositions(s.words)[0]; + if (first === undefined) return false; + const w = s.words[first]; + if (/\.(?:sh|bash|zsh|command)$/i.test(w.text)) return true; + return FILE_RUNNERS.has(nameOf(w)) && s.words.slice(first + 1).some((a) => !isFlag(a)); + }); + if (runsAFile) { + for (const s of segments) for (const body of [...s.heredocs, ...s.herestrings]) rawSearch(body, hits); + } +} + +const unclassifiable = () => ({ label: UNCLASSIFIABLE_LABEL, slash: '/lua-deploy', prefixed: false }); + +/** + * Classify a command. Returns null for commands that run no gated verb, or + * `{ label, slash, prefixed }` for a production-affecting lua-cli verb. When a + * command runs several gated verbs, the first one WITHOUT a valid prefix is + * returned (so one unconfirmed verb blocks the whole chain); `prefixed` is + * true only when every gated verb in it carries the canonical prefix. + * + * Fails closed: a command that mentions a lua binary and is longer than + * MAX_COMMAND_LENGTH, runs past TIME_BUDGET_MS, or trips an internal error + * is returned as UNCLASSIFIABLE_LABEL, unprefixed. * * @param {unknown} command + * @param {{analyze?: Function, budgetMs?: number}} [opts] β€” test seams * @returns {{label: string, slash: string, prefixed: boolean}|null} */ -export function classifyProductionCommand(command) { +export function classifyProductionCommand(command, { analyze = analyzeScript, budgetMs = TIME_BUDGET_MS } = {}) { if (typeof command !== 'string') return null; - const trimmed = command.trimStart(); - const unsafe = trimmed.includes('|') || WRAPPER_HEAD.test(trimmed); - const hasPrefix = PREFIX.test(trimmed); - const body = hasPrefix ? trimmed.replace(PREFIX, '') : trimmed; - // Inside a wrapper/pipe the verb may sit anywhere β€” search, don't anchor. - const haystack = unsafe ? trimmed : body; - for (const entry of PRODUCTION_COMMANDS) { - const anchored = unsafe ? new RegExp(entry.re.source.replace(/^\^/, '(? MAX_COMMAND_LENGTH) return mentionsLua ? unclassifiable() : null; + const hits = []; + deadline = performance.now() + budgetMs; + ticks = 0; + try { + analyze(command, { nested: false, depth: 0, mentionsLua }, hits); + } catch { + // A classifier bug or a spent budget must not wave a lua command through. + return mentionsLua ? unclassifiable() : null; + } finally { + deadline = Infinity; } - return null; + if (hits.length === 0) return null; + const { label, slash, prefixed } = hits.find((h) => !h.prefixed) ?? hits[0]; + return { label, slash, prefixed }; } /** - * True iff the command is a gated production verb carrying the - * LUA_DEPLOY_CONFIRMED=1 prefix, with no wrapper or pipe. + * True iff the command runs a gated production verb and every such verb + * carries the LUA_DEPLOY_CONFIRMED=1 prefix in its canonical shape. * * @param {unknown} command * @returns {boolean} diff --git a/plugins/lua-agent-builder/mcp/lua-platform/README.md b/plugins/lua-agent-builder/mcp/lua-platform/README.md index e4d124e..cf9dc5c 100644 --- a/plugins/lua-agent-builder/mcp/lua-platform/README.md +++ b/plugins/lua-agent-builder/mcp/lua-platform/README.md @@ -77,8 +77,15 @@ npm run build # esbuild β†’ dist/server.js npm test ``` -Output: `dist/server.js` (single bundled file, `@modelcontextprotocol/sdk` -external). The plugin's `.mcp.json` launches it via +Output: `dist/server.js` β€” a single self-contained file. Since 1.6.0 every npm +dependency, `@modelcontextprotocol/sdk` included, is bundled from the +lockfile, so the server runs with no `node_modules` anywhere (a marketplace +install, or the plugin baked into a Lua Job-tier image). +The build also writes `dist/THIRD_PARTY_NOTICES.txt` (every bundled package, its +version and its full licence text, from the esbuild metafile); ship it with the +bundle. `tests/standalone-bundle.test.mjs` copies the bundle into an empty temp +directory and lists the tools over stdio to keep it that way; rebuild after +any change to `src/` or a dependency bump and commit `dist/`. The plugin's `.mcp.json` launches it via `node ${CLAUDE_PLUGIN_ROOT}/mcp/lua-platform/dist/server.js`; the built file is committed so marketplace installs (which copy the repo verbatim) work without a build step. diff --git a/plugins/lua-agent-builder/mcp/lua-platform/dist/THIRD_PARTY_NOTICES.txt b/plugins/lua-agent-builder/mcp/lua-platform/dist/THIRD_PARTY_NOTICES.txt new file mode 100644 index 0000000..2ba01c5 --- /dev/null +++ b/plugins/lua-agent-builder/mcp/lua-platform/dist/THIRD_PARTY_NOTICES.txt @@ -0,0 +1,53 @@ +Third-party software bundled into dist/server.js (@lua/claude-plugin-mcp). +Generated by scripts/bundle.mjs from the esbuild metafile; do not edit by hand. + +@modelcontextprotocol/sdk@0.6.1 β€” MIT + +MIT License + +Copyright (c) 2024 Anthropic, PBC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------ + +zod@3.25.76 β€” MIT +Source: git+https://github.com/colinhacks/zod.git + +MIT License + +Copyright (c) 2025 Colin McDonnell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/lua-agent-builder/mcp/lua-platform/dist/server.js b/plugins/lua-agent-builder/mcp/lua-platform/dist/server.js index ca3ef57..1897652 100644 --- a/plugins/lua-agent-builder/mcp/lua-platform/dist/server.js +++ b/plugins/lua-agent-builder/mcp/lua-platform/dist/server.js @@ -1,3 +1,6 @@ -var ie=Object.defineProperty;var ae=(e,t)=>{for(var r in t)ie(e,r,{get:t[r],enumerable:!0})};import{Server as $e}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as Oe}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as Ue,ListToolsRequestSchema as Ne}from"@modelcontextprotocol/sdk/types.js";var K={};ae(K,{getAgent:()=>W,getDeploymentStatus:()=>te,listAgents:()=>G,listPrimitiveVersions:()=>Q,tailLogs:()=>re});import{spawn as le}from"node:child_process";var ce=6e4;function pe(e,{spawnFn:t=le,timeoutMs:r=ce,label:s="lua"}={}){return new Promise((o,i)=>{let a=t("lua",e,{shell:process.platform==="win32",windowsHide:!0,env:{...process.env,LUA_NO_BANNER:"1",LUA_NO_HINTS:"1"}}),n="",l="";a.stdout.on("data",m=>{n+=m.toString("utf8")}),a.stderr.on("data",m=>{l+=m.toString("utf8")});let c=setTimeout(()=>{a.kill("SIGTERM"),i(new Error(`${s}: 'lua ${e.join(" ")}' timed out after ${r}ms`))},r);a.on("exit",m=>{clearTimeout(c),m!==0?i(new Error(`'lua ${e.join(" ")}' exited ${m}: ${l.trim()}`)):o(n)}),a.on("error",m=>{clearTimeout(c),i(m)})})}function ue(e){let t=e,r=Array.isArray(t)?t:t?.agents??t?.orgs??[];return r.length>0&&r[0]&&Array.isArray(r[0].agents)?r.flatMap(o=>(o.agents??[]).map(i=>({id:i.agentId??i.id??i._id,name:i.name??null,orgId:o.orgId??o.id??o._id??null,orgName:o.name??o.registeredName??null,visibility:i.visibility??null}))):r.map(o=>({id:o.agentId??o.id??o._id,name:o.name??null,orgId:o.orgId??null,orgName:o.orgName??null,visibility:o.visibility??null}))}async function T({spawnFn:e,label:t="list_agents"}={}){let r=await pe(["agents","--json","--ci"],{spawnFn:e,label:t}),s;try{s=JSON.parse(r)}catch(o){throw new Error(`${t}: could not parse 'lua agents --json' output: ${o.message}`)}return ue(s)}var G={spec:{name:"list_agents",description:"List all Lua agents the authenticated credential can reach. Returns a compact array of {id, name, orgId, orgName, visibility} flattened across all organisations. Same data as `lua agents --json` \u2014 it resolves every organisation, so on accounts with many orgs this takes 20 s or more; prefer get_agent when you already know the id.",inputSchema:{type:"object",properties:{},required:[]}},async handler(e,t={}){let r=await T({spawnFn:t.spawnFn,label:"list_agents"});return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}};var W={spec:{name:"get_agent",description:"Look up one Lua agent by ID and return {id, name, orgId, orgName, visibility}. For what is live use get_deployment_status / list_primitive_versions; for logs use tail_logs.",inputSchema:{type:"object",properties:{agentId:{type:"string",description:"Agent ID (the `id` field from list_agents; also `agent.agentId` in lua.skill.yaml)"}},required:["agentId"]}},async handler({agentId:e},t={}){if(!e)throw new Error("agentId is required");let s=(await T({spawnFn:t.spawnFn,label:"get_agent"})).find(o=>o.id===e)??null;if(!s)throw new Error(`get_agent: no agent with id "${e}" found in the authenticated credential's accessible orgs. Run list_agents to see available agents.`);return{content:[{type:"text",text:JSON.stringify(s,null,2)}]}}};import{readFile as j,readdir as de,stat as me}from"node:fs/promises";import{join as R,dirname as fe}from"node:path";import{homedir as ge}from"node:os";var he="https://api.heylua.ai",we="https://securetoken.googleapis.com/v1/token",ve=15e3,ye=6e4,_e=["TOKEN_EXPIRED","USER_DISABLED","USER_NOT_FOUND","INVALID_REFRESH_TOKEN","INVALID_GRANT_TYPE","MISSING_REFRESH_TOKEN"],X=new Map;function Ee(e){for(let t of e.split(/\r?\n/)){let r=t.match(/^\s*(?:export\s+)?LUA_API_KEY\s*=\s*(.*)$/);if(!r)continue;let s=r[1].trim(),o=s.match(/^(['"`])(.*?)\1(?:\s+#.*)?\s*$/);return o?s=o[2]:s=s.replace(/\s+#.*$/,"").trim(),s||null}return null}async function Se({sessionsDir:e,apiUrl:t}){let r;try{r=await de(e)}catch{return null}let s=[];for(let o of r){if(!o.endsWith(".json")||o.startsWith("."))continue;let i=R(e,o);try{let a=JSON.parse(await j(i,"utf8"));if(a?.kind!=="firebase-session"||a?.version!==1||typeof a.refreshToken!="string"||!a.refreshToken||typeof a.firebaseWebApiKey!="string"||!a.firebaseWebApiKey||a.apiUrl!==t)continue;let{mtimeMs:n}=await me(i);s.push({path:i,session:a,mtimeMs:n})}catch{}}return s.length===0?null:(s.sort((o,i)=>i.mtimeMs-o.mtimeMs),{path:s[0].path,session:s[0].session})}async function Ae({path:e,session:t,fetchFn:r=globalThis.fetch,now:s=Date.now}){let o=X.get(e);if(o&&o.expiresAt-s()>ye)return o.idToken;let i=new AbortController,a=setTimeout(()=>i.abort(),ve),n;try{n=await r(`${we}?key=${encodeURIComponent(t.firebaseWebApiKey)}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:t.refreshToken}).toString(),signal:i.signal})}catch(p){throw new Error(`MCP_AUTH_UNAVAILABLE: could not refresh the lua-cli session (${p?.name==="AbortError"?"timed out":p.message}). Check your network, or set LUA_API_KEY to bypass the session.`)}finally{clearTimeout(a)}if(!n.ok){let p=n.statusText??String(n.status);try{let d=(await n.json())?.error?.message;typeof d=="string"&&d&&(p=d.split(":")[0].trim())}catch{}let g=n.status<500&&_e.find(u=>p.toUpperCase().includes(u));throw g?new Error(`MCP_AUTH_STALE: your lua-cli session was signed out (${g}). Signing out of the Lua dashboard, desktop or mobile app also ends CLI sessions. Run \`lua auth configure\` in a terminal to sign in again.`):new Error(`MCP_AUTH_UNAVAILABLE: lua-cli session refresh failed (${n.status} ${p}). Retry in a moment.`)}let l=await n.json(),c=l?.id_token,m=Number(l?.expires_in);if(typeof c!="string"||!c||!Number.isFinite(m)||m<=0)throw new Error("MCP_AUTH_UNAVAILABLE: the session refresh returned an invalid token. Run `lua auth configure` again.");return X.set(e,{idToken:c,expiresAt:s()+m*1e3}),c}async function z({env:e=process.env,credentialsPath:t=e.LUA_CREDENTIALS_PATH??R(ge(),".lua-cli","credentials"),sessionsDir:r=e.LUA_SESSIONS_DIR??R(fe(t),"sessions"),cwd:s=process.cwd(),apiUrl:o=e.LUA_API_URL||he,fetchFn:i=globalThis.fetch,now:a=Date.now}={}){if(e.LUA_API_KEY&&e.LUA_API_KEY.trim())return e.LUA_API_KEY.trim();try{let l=Ee(await j(R(s,".env"),"utf8"));if(l)return l}catch{}let n=await Se({sessionsDir:r,apiUrl:o});if(n)return Ae({...n,fetchFn:i,now:a});try{let l=(await j(t,"utf8")).trim();if(l){if(l.startsWith("{"))try{let c=JSON.parse(l);if(c?.apiKey)return c.apiKey}catch{}return l}}catch{}throw new Error("MCP_AUTH_STALE: No lua-cli credentials found in LUA_API_KEY, .env, ~/.lua-cli/sessions, or ~/.lua-cli/credentials. Run `lua auth configure` in a terminal (or /lua-auth in Claude Code).")}var be="https://api.heylua.ai",ke=1e4,Ge=Object.freeze({skills:"automations:read",webhooks:"automations:read",jobs:"automations:read",triggers:"automations:read",preprocessors:"automations:read",postprocessors:"automations:read",workflows:"workflows:read",persona:"agents:read",logs:"knowledge:read"}),Ie="skills/webhooks/jobs/triggers/preprocessors/postprocessors need automations:read, workflows need workflows:read, persona needs agents:read, logs need knowledge:read";async function v(e,{method:t="GET",body:r,query:s,fetchFn:o=globalThis.fetch,baseUrl:i=process.env.LUA_API_URL||be,timeoutMs:a=ke}={}){let n=await z(),l=new URL(i.replace(/\/$/,"")+e);if(s)for(let[p,g]of Object.entries(s))l.searchParams.set(p,String(g));let c=new AbortController,m=setTimeout(()=>c.abort(),a);try{let p=await o(l.toString(),{method:t,headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json","X-Lua-Client":"claude-plugin/1.5.0"},body:r?JSON.stringify(r):void 0,signal:c.signal});if(p.status===401)throw new Error("MCP_AUTH_STALE: lua-api returned 401. The credential is missing, expired, or the session was signed out (signing out of the Lua dashboard or apps also ends CLI sessions). Run `lua auth configure` in a terminal, or re-run /lua-doctor.");if(p.status===403)throw new Error(`MCP_FORBIDDEN: lua-api returned 403 for ${e}. The credential cannot access this agent or org, or it lacks the route scope (${Ie} \u2014 typed keys are scoped to the agents and role chosen at \`lua auth configure\`). Re-run /lua-doctor or check the LUA_API_KEY env var.`);if(!p.ok){let g=await p.text(),u=g;try{let d=JSON.parse(g);u=d?.error?.message??d?.message??g;let h=d?.error?.code;typeof h=="string"&&h&&!String(u).includes(h)&&(u=`${h}: ${u}`)}catch{}throw new Error(`lua-api ${p.status}: ${u}`)}return await p.json()}catch(p){throw p.name==="AbortError"?new Error(`MCP_TIMEOUT: ${e} did not respond in ${a}ms`):p}finally{clearTimeout(m)}}var V={skill:e=>e?.skills??[],webhook:e=>e?.data?.webhooks??[],job:e=>e?.data?.jobs??[],trigger:e=>e?.data?.triggers??[],preprocessor:e=>e?.data?.preprocessors??[],postprocessor:e=>e?.data?.postprocessors??[],workflow:e=>e?.data?.workflows??[]},D={skill:e=>e?.versions??[],webhook:e=>e?.data?.versions??[],job:e=>Array.isArray(e?.data)?e.data:[],trigger:e=>e?.data?.versions??[],preprocessor:e=>e?.data?.versions??[],postprocessor:e=>e?.data?.versions??[],workflow:e=>Array.isArray(e?.data)?e.data:[],persona:e=>e?.versions??[]},_={skill:"skills",webhook:"webhooks",job:"jobs",trigger:"triggers",preprocessor:"preprocessors",postprocessor:"postprocessors",workflow:"workflows"};function L(e,t){let r=V[e];if(!r)throw new Error(`extractList: unknown primitive type "${e}". Valid: ${Object.keys(V).join(", ")}`);return r(t)}function E(e,t){let r=D[e];if(!r)throw new Error(`extractVersions: unknown primitive type "${e}". Valid: ${Object.keys(D).join(", ")}`);return r(t)}function S(e){let t=e?.data?.activeVersionId;return typeof t=="string"&&t?t:null}function A(e,t,r){if(!t||typeof t!="object")return!1;switch(e){case"skill":case"persona":return t.isCurrent===!0;case"job":case"workflow":return t.active===!0;case"webhook":case"trigger":case"preprocessor":case"postprocessor":{if(t.isActive===!0)return!0;let s=S(r),o=t.versionId??t.id??null;return!!s&&o===s}default:return!1}}function b(e){if(!e||typeof e!="object")return null;let t=e.createdAt??e.createdDate??null;return t==null?null:typeof t=="number"?Number.isFinite(t)?new Date(t).toISOString():null:String(t)}function x(e){return!e||typeof e!="object"?null:e.versionId??e.id??null}var Xe=Object.keys(V),Z=Object.keys(D);var F=new Set(Z),Q={spec:{name:"list_primitive_versions",description:"List the server-side versions of one primitive (skill, webhook, job, trigger, preprocessor, postprocessor, workflow) or the agent persona. Returns { activeVersionId, versions: [{version, versionId, active, createdAt}] } \u2014 `active` is the version currently live. `versionId` is null for types whose versions route carries no per-entry id: skill, persona and webhook (the webhook route exposes the row id only under a misnamed `webhookId` key). For those, identify a version by `version`; for webhooks the live row id is the top-level `activeVersionId`. `activeVersionId` is populated only for webhook, trigger, preprocessor and postprocessor envelopes and is null for skill, job, workflow and persona.",inputSchema:{type:"object",properties:{agentId:{type:"string"},type:{type:"string",enum:[...F]},name:{type:"string",description:"Primitive name as written in lua.skill.yaml (omit for persona \u2014 an agent has only one)"}},required:["agentId","type"]}},async handler({agentId:e,type:t,name:r},s={}){if(!e||!t)throw new Error("agentId and type are required");if(!F.has(t))throw new Error(`Invalid type: ${t}. Valid: ${[...F].join(", ")}`);if(t!=="persona"&&!r)throw new Error("name is required for all types except persona");let o;if(t==="persona")o=`/developer/agents/${encodeURIComponent(e)}/persona/versions`;else{let c=await Te({agentId:e,type:t,name:r,fetchFn:s.fetchFn});o=`/developer/${_[t]}/${encodeURIComponent(e)}/${encodeURIComponent(c)}/versions`}let i=await v(o,{fetchFn:s.fetchFn}),n=E(t,i).map(c=>({version:c.version,versionId:x(c),active:A(t,c,i),createdAt:b(c)})),l={agentId:e,type:t,name:t==="persona"?null:r,activeVersionId:S(i),versions:n};return{content:[{type:"text",text:JSON.stringify(l,null,2)}]}}};async function Te({agentId:e,type:t,name:r,fetchFn:s}){let o=`/developer/${_[t]}/${encodeURIComponent(e)}`,i=await v(o,{fetchFn:s}),a=L(t,i),n=a.find(c=>c.name===r);if(!n){let c=a.map(m=>m.name).filter(Boolean).join(", ")||"(none)";throw new Error(`list_primitive_versions: no ${t} named "${r}" on agent ${e}. Available: ${c}`)}let l=n.id??n._id;if(!l)throw new Error(`list_primitive_versions: ${t} "${r}" exists but has no id field`);return l}var $=["skill","webhook","job","trigger","preprocessor","postprocessor","workflow"],ee=5,Re=45e3,te={spec:{name:"get_deployment_status",description:'What is live right now for an agent: for every skill, webhook, job, trigger, preprocessor, postprocessor and workflow the active (deployed) version, plus the active persona version. Composed from the per-type lua-api version routes (list calls in parallel, then per-item version lookups in chunks of 5). Bounded by a 45 s wall-clock budget: if exceeded, remaining items are listed with `error: "skipped: \u2026"` and the result carries `partial: true` + `partialReason`. Inside a project, `lua status --json` additionally compares local vs deployed.',inputSchema:{type:"object",properties:{agentId:{type:"string"}},required:["agentId"]}},async handler({agentId:e},t={}){if(!e)throw new Error("agentId is required");let r=encodeURIComponent(e),s=Number.isFinite(t.budgetMs)?t.budgetMs:Re,o=Date.now(),i=()=>Date.now()-o>s,a=u=>v(u,{fetchFn:t.fetchFn}),n={agentId:e,persona:null,primitives:{}};for(let u of $)n.primitives[u]=[];let[l,...c]=await Promise.allSettled([a(`/developer/agents/${r}/persona/versions`),...$.map(u=>a(`/developer/${_[u]}/${r}`))]);if(l.status==="fulfilled"){let u=l.value,d=E("persona",u),h=d.find(y=>A("persona",y,u))??null;n.persona={activeVersion:h?.version??null,activeVersionCreatedAt:b(h),versionCount:d.length}}else n.persona={error:l.reason?.message??String(l.reason)};let m=!1,p=0,g=0;for(let u=0;u<$.length;u++){let d=$[u],h=_[d],y=c[u];if(y.status!=="fulfilled"){n.primitives[d]={error:y.reason?.message??String(y.reason)};continue}let O=L(d,y.value).map(f=>({p:f,primId:f.id??f._id,name:f.name??f.id??f._id})).filter(f=>f.primId);g+=O.length;for(let f=0;fa(`/developer/${h}/${r}/${encodeURIComponent(w)}/versions`)))).forEach((w,U)=>{let{p:I,primId:q,name:B}=k[U];if(w.status!=="fulfilled"){n.primitives[d].push({name:B,id:q,error:w.reason?.message??String(w.reason)});return}let N=w.value,J=E(d,N),C=J.find(ne=>A(d,ne,N))??null,P={name:B,id:q,activeVersion:C?.version??null,activeVersionId:x(C)??S(N),activeVersionCreatedAt:b(C),versionCount:J.length};typeof I.active=="boolean"&&(P.enabled=I.active),d==="workflow"&&typeof I.dynamic=="boolean"&&(P.dynamic=I.dynamic),n.primitives[d].push(P)})}}return p>0&&(n.partial=!0,n.partialReason=`Wall-clock budget of ${s}ms exceeded after ${Date.now()-o}ms; ${p} of ${g} version lookups were not issued (entries carry error: "skipped: \u2026").`),{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}};var Le=["skill","job","webhook","trigger","preprocessor","postprocessor","user_message","agent_response","agent_error","runtime","mcp","rag","device","device-trigger","model-resolver","workflow-step","workflow-script","workflow"],H=["error","warn","info","debug","start","complete"],M=new Set(["all",...Le]),xe=new Set(H),re={spec:{name:"tail_logs",description:"Fetch recent execution logs for an agent (same data as `lua logs --json`). Returns { logs: LogEntry[], pagination }. Each LogEntry has `subType` (error | warn | info | debug | start | complete), `message`, `timestamp`, and `metadata.logSource` / `metadata.primitiveName` \u2014 there is NO `level` field. Filter by source (`type`), primitive (`name`) and/or severity (`logType`, which filters on `subType`).",inputSchema:{type:"object",properties:{agentId:{type:"string"},type:{type:"string",enum:[...M],default:"all",description:"Log source filter (maps to lua-api `logSource`). `all` = no filter."},name:{type:"string",description:"Filter by primitive name (optional; maps to `primitiveName`)"},logType:{type:"string",enum:H,description:"Filter by LogEntry `subType` (optional; maps to lua-api `logType`). Omit for every severity. e.g. `error` to see only failures."},limit:{type:"number",default:50,minimum:1,maximum:100},page:{type:"number",minimum:1,description:"Page number for pagination (optional)"}},required:["agentId"]}},async handler({agentId:e,type:t="all",name:r,logType:s,limit:o=50,page:i},a={}){if(!e)throw new Error("agentId is required");if(!M.has(t))throw new Error(`Invalid type: ${t}. Valid: ${[...M].join(", ")}`);if(s!==void 0&&!xe.has(s))throw new Error(`Invalid logType: ${s}. Valid: ${H.join(", ")}`);if(o>100)throw new Error(`Invalid limit: ${o}. lua-api caps logs at 100 entries per call.`);let n={limit:o};t!=="all"&&(n.logSource=t),r&&(n.primitiveName=r),s&&(n.logType=s),i&&(n.page=i);let l=await v(`/developer/agents/${encodeURIComponent(e)}/logs`,{query:n,fetchFn:a.fetchFn});return{content:[{type:"text",text:JSON.stringify(l,null,2)}]}}};var oe=Object.values(K),Y=new $e({name:"lua-platform",version:"1.5.0"},{capabilities:{tools:{}}});Y.setRequestHandler(Ne,async()=>({tools:oe.map(e=>e.spec)}));Y.setRequestHandler(Ue,async e=>{let t=oe.find(r=>r.spec.name===e.params.name);if(!t)throw new Error(`Unknown tool: ${e.params.name}`);try{return await t.handler(e.params.arguments??{})}catch(r){return{content:[{type:"text",text:`Error: ${r.message}`}],isError:!0}}});function se(e){process.stderr.write(JSON.stringify(e)+` -`,()=>process.exit(1))}process.on("uncaughtException",e=>{se({event:"mcp_server_crash",kind:"uncaughtException",message:e?.message,stack:e?.stack,plugin_version:"1.5.0",lua_cli_version:process.env.LUA_CLI_VERSION??null,platform:process.platform,ts:new Date().toISOString()})});process.on("unhandledRejection",e=>{se({event:"mcp_server_crash",kind:"unhandledRejection",reason:String(e),stack:e?.stack,plugin_version:"1.5.0",lua_cli_version:process.env.LUA_CLI_VERSION??null,platform:process.platform,ts:new Date().toISOString()})});await Y.connect(new Oe); -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NlcnZlci5tanMiLCAiLi4vc3JjL3Rvb2xzL2luZGV4Lm1qcyIsICIuLi9zcmMvcnVuLWx1YS5tanMiLCAiLi4vc3JjL3Rvb2xzL2xpc3QtYWdlbnRzLm1qcyIsICIuLi9zcmMvdG9vbHMvZ2V0LWFnZW50Lm1qcyIsICIuLi9zcmMvYXV0aC5tanMiLCAiLi4vc3JjL2FwaS1jbGllbnQubWpzIiwgIi4uL3NyYy9yZXNwb25zZS1zaGFwZXMubWpzIiwgIi4uL3NyYy90b29scy9saXN0LXByaW1pdGl2ZS12ZXJzaW9ucy5tanMiLCAiLi4vc3JjL3Rvb2xzL2dldC1kZXBsb3ltZW50LXN0YXR1cy5tanMiLCAiLi4vc3JjL3Rvb2xzL3RhaWwtbG9ncy5tanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8vIE1DUCBzdGRpbyBzZXJ2ZXIgYm9vdHN0cmFwLiBQZXIgdGVjaCBzcGVjIFx1MDBBNzguMS5cblxuaW1wb3J0IHsgU2VydmVyIH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvaW5kZXguanMnO1xuaW1wb3J0IHsgU3RkaW9TZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9zdGRpby5qcyc7XG5pbXBvcnQge1xuICBDYWxsVG9vbFJlcXVlc3RTY2hlbWEsXG4gIExpc3RUb29sc1JlcXVlc3RTY2hlbWEsXG59IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvdHlwZXMuanMnO1xuaW1wb3J0ICogYXMgdG9vbHMgZnJvbSAnLi90b29scy9pbmRleC5tanMnO1xuXG5jb25zdCBUT09MX1JFR0lTVFJZID0gT2JqZWN0LnZhbHVlcyh0b29scyk7XG5cbmNvbnN0IHNlcnZlciA9IG5ldyBTZXJ2ZXIoXG4gIHsgbmFtZTogJ2x1YS1wbGF0Zm9ybScsIHZlcnNpb246ICcxLjUuMCcgfSxcbiAgeyBjYXBhYmlsaXRpZXM6IHsgdG9vbHM6IHt9IH0gfVxuKTtcblxuc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKExpc3RUb29sc1JlcXVlc3RTY2hlbWEsIGFzeW5jICgpID0+ICh7XG4gIHRvb2xzOiBUT09MX1JFR0lTVFJZLm1hcCgodCkgPT4gdC5zcGVjKSxcbn0pKTtcblxuc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKENhbGxUb29sUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcSkgPT4ge1xuICBjb25zdCB0b29sID0gVE9PTF9SRUdJU1RSWS5maW5kKCh0KSA9PiB0LnNwZWMubmFtZSA9PT0gcmVxLnBhcmFtcy5uYW1lKTtcbiAgaWYgKCF0b29sKSB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdG9vbDogJHtyZXEucGFyYW1zLm5hbWV9YCk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHRvb2wuaGFuZGxlcihyZXEucGFyYW1zLmFyZ3VtZW50cyA/PyB7fSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiAndGV4dCcsIHRleHQ6IGBFcnJvcjogJHtlcnIubWVzc2FnZX1gIH1dLFxuICAgICAgaXNFcnJvcjogdHJ1ZSxcbiAgICB9O1xuICB9XG59KTtcblxuLy8gXHUwMEE3MTkuNiBjcmFzaCByZXBvcnRpbmcgXHUyMDE0IG11c3QgbGFuZCBCRUZPUkUgcHJvY2VzcyBleGl0IHNvIHRoZSBldmVudCByZWFjaGVzXG4vLyB0ZWxlbWV0cnkuIFdpbmRvd3MgY2FuIGRyb3AgdGhlIGxhc3Qgc3RkZXJyIHdyaXRlIGlmIHByb2Nlc3MuZXhpdCBmaXJlc1xuLy8gc3luY2hyb25vdXNseSBhZnRlciBpdDsgc2FtZSBidWcgY2xhc3MgYXMgbGliL2hvb2stcnVudGltZS5tanMncyBleGl0KCkuXG4vLyBFeGl0IG9ubHkgaW5zaWRlIHRoZSB3cml0ZSBjYWxsYmFjayBzbyB0aGUgZmx1c2ggY29tcGxldGVzLlxuZnVuY3Rpb24gcmVwb3J0Q3Jhc2hBbmRFeGl0KHBheWxvYWQpIHtcbiAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkgKyAnXFxuJywgKCkgPT4gcHJvY2Vzcy5leGl0KDEpKTtcbn1cblxucHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCAoZXJyKSA9PiB7XG4gIHJlcG9ydENyYXNoQW5kRXhpdCh7XG4gICAgZXZlbnQ6ICdtY3Bfc2VydmVyX2NyYXNoJyxcbiAgICBraW5kOiAndW5jYXVnaHRFeGNlcHRpb24nLFxuICAgIG1lc3NhZ2U6IGVycj8ubWVzc2FnZSxcbiAgICBzdGFjazogZXJyPy5zdGFjayxcbiAgICBwbHVnaW5fdmVyc2lvbjogJzEuNS4wJyxcbiAgICBsdWFfY2xpX3ZlcnNpb246IHByb2Nlc3MuZW52LkxVQV9DTElfVkVSU0lPTiA/PyBudWxsLFxuICAgIHBsYXRmb3JtOiBwcm9jZXNzLnBsYXRmb3JtLFxuICAgIHRzOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gIH0pO1xufSk7XG5cbnByb2Nlc3Mub24oJ3VuaGFuZGxlZFJlamVjdGlvbicsIChyZWFzb24pID0+IHtcbiAgcmVwb3J0Q3Jhc2hBbmRFeGl0KHtcbiAgICBldmVudDogJ21jcF9zZXJ2ZXJfY3Jhc2gnLFxuICAgIGtpbmQ6ICd1bmhhbmRsZWRSZWplY3Rpb24nLFxuICAgIHJlYXNvbjogU3RyaW5nKHJlYXNvbiksXG4gICAgc3RhY2s6IC8qKiBAdHlwZSB7YW55fSAqLyAocmVhc29uKT8uc3RhY2ssXG4gICAgcGx1Z2luX3ZlcnNpb246ICcxLjUuMCcsXG4gICAgbHVhX2NsaV92ZXJzaW9uOiBwcm9jZXNzLmVudi5MVUFfQ0xJX1ZFUlNJT04gPz8gbnVsbCxcbiAgICBwbGF0Zm9ybTogcHJvY2Vzcy5wbGF0Zm9ybSxcbiAgICB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICB9KTtcbn0pO1xuXG5hd2FpdCBzZXJ2ZXIuY29ubmVjdChuZXcgU3RkaW9TZXJ2ZXJUcmFuc3BvcnQoKSk7XG4iLCAiZXhwb3J0IHsgbGlzdEFnZW50cyB9IGZyb20gJy4vbGlzdC1hZ2VudHMubWpzJztcbmV4cG9ydCB7IGdldEFnZW50IH0gZnJvbSAnLi9nZXQtYWdlbnQubWpzJztcbmV4cG9ydCB7IGxpc3RQcmltaXRpdmVWZXJzaW9ucyB9IGZyb20gJy4vbGlzdC1wcmltaXRpdmUtdmVyc2lvbnMubWpzJztcbmV4cG9ydCB7IGdldERlcGxveW1lbnRTdGF0dXMgfSBmcm9tICcuL2dldC1kZXBsb3ltZW50LXN0YXR1cy5tanMnO1xuZXhwb3J0IHsgdGFpbExvZ3MgfSBmcm9tICcuL3RhaWwtbG9ncy5tanMnO1xuLy8gY2hlY2tfZHJpZnQgcmVtb3ZlZCBpbiB2MS4yNSBcdTIwMTQgdXNlIEJhc2gobHVhIHN5bmMgLS1jaGVjaykgZGlyZWN0bHkuIFRoZVxuLy8gTUNQIHNlcnZlciBpcyBsb2NhbCBhbmQgc28gaXMgdGhlIENMSTsgcmVpbXBsZW1lbnRpbmcgZHJpZnQgZGV0ZWN0aW9uXG4vLyBzZXJ2ZXItc2lkZSBvciBpbiB0aGUgTUNQIHdvdWxkIGR1cGxpY2F0ZSBsb2dpYyB0aGF0IGx1YS1jbGkgYWxyZWFkeSBvd25zLlxuIiwgIi8vIFNoYXJlZCBzdWJwcm9jZXNzIGhlbHBlciBmb3IgdG9vbHMgdGhhdCBzaGVsbCBvdXQgdG8gdGhlIGx1YS1jbGkgYmluYXJ5LlxuLy9cbi8vIFdoeSBzaGVsbCBvdXQgYXQgYWxsOiB0aGVyZSBpcyBubyBcImxpc3QgZXZlcnkgYWdlbnQgdGhpcyBjcmVkZW50aWFsIGNhblxuLy8gcmVhY2hcIiBSRVNUIHJvdXRlIFx1MjAxNCBgbHVhIGFnZW50cyAtLWpzb25gIGFscmVhZHkgZG9lcyB0aGUgY3JlZGVudGlhbC10by1cbi8vIGF1dGhvcml6YXRpb24tcHJvamVjdGlvbiByZXNvbHV0aW9uIChQUk8tMTcxMikgZm9yIGV2ZXJ5IGNyZWRlbnRpYWwgY2xhc3Ncbi8vIChBUEkga2V5LCB0eXBlZCBzY29wZWQga2V5LCByZW5ld2FibGUgc2Vzc2lvbikuIFJlaW1wbGVtZW50aW5nIHRoYXQgaW4gdGhlXG4vLyBNQ1Agd291bGQgZHVwbGljYXRlIGxvZ2ljIGx1YS1jbGkgb3ducy5cblxuaW1wb3J0IHsgc3Bhd24gfSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuXG4vLyBgbHVhIGFnZW50c2Agd2Fsa3MgZXZlcnkgb3JnYW5pc2F0aW9uIHRoZSBjcmVkZW50aWFsIGNhbiBzZWUgYW5kLCBmb3IgYVxuLy8gc2Vzc2lvbiBsb2dpbiwgcmVmcmVzaGVzIHRoZSBzZXNzaW9uIGZpcnN0LiBNZWFzdXJlZCAyMDI2LTA5LTEyIG9uIGFcbi8vIDE0NC1vcmcgYWNjb3VudDogMThcdTIwMTMyNSBzLiBUaGUgYnVkZ2V0IG11c3QgY292ZXIgdGhhdC5cbmNvbnN0IERFRkFVTFRfVElNRU9VVF9NUyA9IDYwXzAwMDtcblxuLyoqXG4gKiBSdW4gYGx1YSA8YXJncz5gIGFuZCByZXNvbHZlIHdpdGggaXRzIHN0ZG91dC5cbiAqXG4gKiBPbiBXaW5kb3dzIHRoZSBucG0gYmluIGlzIGEgYGx1YS5jbWRgIHNoaW0sIHdoaWNoIE5vZGUgKFx1MjI2NTE4LjIwIC8gXHUyMjY1MjAuMTIpXG4gKiByZWZ1c2VzIHRvIHNwYXduIHdpdGhvdXQgYSBzaGVsbDsgdGhlIGFyZ3MgYXJlIGZpeGVkIGxpdGVyYWxzIChubyB1c2VyXG4gKiBpbnB1dCksIHNvIGBzaGVsbDogdHJ1ZWAgdGhlcmUgaXMgc2FmZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzXG4gKiBAcGFyYW0ge3tzcGF3bkZuPzogdHlwZW9mIHNwYXduLCB0aW1lb3V0TXM/OiBudW1iZXIsIGxhYmVsPzogc3RyaW5nfX0gW29wdHNdXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuTHVhKGFyZ3MsIHsgc3Bhd25GbiA9IHNwYXduLCB0aW1lb3V0TXMgPSBERUZBVUxUX1RJTUVPVVRfTVMsIGxhYmVsID0gJ2x1YScgfSA9IHt9KSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2hpbGQgPSBzcGF3bkZuKCdsdWEnLCBhcmdzLCB7XG4gICAgICBzaGVsbDogcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyxcbiAgICAgIHdpbmRvd3NIaWRlOiB0cnVlLFxuICAgICAgZW52OiB7IC4uLnByb2Nlc3MuZW52LCBMVUFfTk9fQkFOTkVSOiAnMScsIExVQV9OT19ISU5UUzogJzEnIH0sXG4gICAgfSk7XG4gICAgbGV0IHN0ZG91dCA9ICcnO1xuICAgIGxldCBzdGRlcnIgPSAnJztcbiAgICBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCAoZCkgPT4geyBzdGRvdXQgKz0gZC50b1N0cmluZygndXRmOCcpOyB9KTtcbiAgICBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCAoZCkgPT4geyBzdGRlcnIgKz0gZC50b1N0cmluZygndXRmOCcpOyB9KTtcblxuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjaGlsZC5raWxsKCdTSUdURVJNJyk7XG4gICAgICByZWplY3QobmV3IEVycm9yKGAke2xhYmVsfTogJ2x1YSAke2FyZ3Muam9pbignICcpfScgdGltZWQgb3V0IGFmdGVyICR7dGltZW91dE1zfW1zYCkpO1xuICAgIH0sIHRpbWVvdXRNcyk7XG5cbiAgICBjaGlsZC5vbignZXhpdCcsIChjb2RlKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgaWYgKGNvZGUgIT09IDApIHJlamVjdChuZXcgRXJyb3IoYCdsdWEgJHthcmdzLmpvaW4oJyAnKX0nIGV4aXRlZCAke2NvZGV9OiAke3N0ZGVyci50cmltKCl9YCkpO1xuICAgICAgZWxzZSByZXNvbHZlKHN0ZG91dCk7XG4gICAgfSk7XG4gICAgY2hpbGQub24oJ2Vycm9yJywgKGVycikgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIHJlamVjdChlcnIpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBGbGF0dGVuIGBsdWEgYWdlbnRzIC0tanNvbmAgb3V0cHV0IChsdWEtY2xpIFx1MjI2NSAzLjI4OiBhbiBhcnJheSBvZlxuICogQ3JlZGVudGlhbE9yZ2FuaXphdGlvbiByb3dzIFx1MjAxNCBgeyBvcmdJZCwgbmFtZT8sIGFyY2hpdmVkLCBkaXNjb3ZlcmVkVmlhLFxuICogYWdlbnRzOiBbeyBhZ2VudElkLCBuYW1lPywgdmlzaWJpbGl0eSwgZGlzcGxheVJvbGVzIH1dIH1gLCBzZWVcbiAqIHBhY2thZ2VzL2x1YS1jbGkvc3JjL3NlcnZpY2VzL2NyZWRlbnRpYWwtb3BlcmF0aW9uYWwtY29udGV4dC50cykgaW50byBhXG4gKiBjb21wYWN0IGFnZW50IGxpc3QuIE9sZGVyIGZsYXQgc2hhcGVzIGFyZSB0b2xlcmF0ZWQgZm9yIGZvcndhcmQtY29tcGF0LlxuICpcbiAqIEBwYXJhbSB7dW5rbm93bn0gcGFyc2VkXG4gKiBAcmV0dXJucyB7QXJyYXk8e2lkOiBzdHJpbmcsIG5hbWU6IHN0cmluZ3xudWxsLCBvcmdJZDogc3RyaW5nfG51bGwsIG9yZ05hbWU6IHN0cmluZ3xudWxsLCB2aXNpYmlsaXR5OiBzdHJpbmd8bnVsbH0+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZmxhdHRlbkFnZW50cyhwYXJzZWQpIHtcbiAgY29uc3Qgb2JqID0gLyoqIEB0eXBlIHthbnl9ICovIChwYXJzZWQpO1xuICBjb25zdCBlbnRyaWVzID0gQXJyYXkuaXNBcnJheShvYmopID8gb2JqIDogKG9iaj8uYWdlbnRzID8/IG9iaj8ub3JncyA/PyBbXSk7XG4gIGNvbnN0IGxvb2tzTGlrZU9yZ3MgPSBlbnRyaWVzLmxlbmd0aCA+IDAgJiYgZW50cmllc1swXSAmJiBBcnJheS5pc0FycmF5KGVudHJpZXNbMF0uYWdlbnRzKTtcblxuICBpZiAobG9va3NMaWtlT3Jncykge1xuICAgIHJldHVybiBlbnRyaWVzLmZsYXRNYXAoKG9yZykgPT4gKG9yZy5hZ2VudHMgPz8gW10pLm1hcCgoYSkgPT4gKHtcbiAgICAgIGlkOiBhLmFnZW50SWQgPz8gYS5pZCA/PyBhLl9pZCxcbiAgICAgIG5hbWU6IGEubmFtZSA/PyBudWxsLFxuICAgICAgb3JnSWQ6IG9yZy5vcmdJZCA/PyBvcmcuaWQgPz8gb3JnLl9pZCA/PyBudWxsLFxuICAgICAgb3JnTmFtZTogb3JnLm5hbWUgPz8gb3JnLnJlZ2lzdGVyZWROYW1lID8/IG51bGwsXG4gICAgICB2aXNpYmlsaXR5OiBhLnZpc2liaWxpdHkgPz8gbnVsbCxcbiAgICB9KSkpO1xuICB9XG4gIHJldHVybiBlbnRyaWVzLm1hcCgoYSkgPT4gKHtcbiAgICBpZDogYS5hZ2VudElkID8/IGEuaWQgPz8gYS5faWQsXG4gICAgbmFtZTogYS5uYW1lID8/IG51bGwsXG4gICAgb3JnSWQ6IGEub3JnSWQgPz8gbnVsbCxcbiAgICBvcmdOYW1lOiBhLm9yZ05hbWUgPz8gbnVsbCxcbiAgICB2aXNpYmlsaXR5OiBhLnZpc2liaWxpdHkgPz8gbnVsbCxcbiAgfSkpO1xufVxuXG4vKipcbiAqIFJ1biBgbHVhIGFnZW50cyAtLWpzb24gLS1jaWAgYW5kIHJldHVybiB0aGUgZmxhdHRlbmVkIGFnZW50IGxpc3QuXG4gKlxuICogQHBhcmFtIHt7c3Bhd25Gbj86IHR5cGVvZiBzcGF3biwgbGFiZWw/OiBzdHJpbmd9fSBbb3B0c11cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RBZ2VudHNWaWFDbGkoeyBzcGF3bkZuLCBsYWJlbCA9ICdsaXN0X2FnZW50cycgfSA9IHt9KSB7XG4gIGNvbnN0IHN0ZG91dCA9IGF3YWl0IHJ1bkx1YShbJ2FnZW50cycsICctLWpzb24nLCAnLS1jaSddLCB7IHNwYXduRm4sIGxhYmVsIH0pO1xuICBsZXQgcGFyc2VkO1xuICB0cnkge1xuICAgIHBhcnNlZCA9IEpTT04ucGFyc2Uoc3Rkb3V0KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke2xhYmVsfTogY291bGQgbm90IHBhcnNlICdsdWEgYWdlbnRzIC0tanNvbicgb3V0cHV0OiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG4gIHJldHVybiBmbGF0dGVuQWdlbnRzKHBhcnNlZCk7XG59XG4iLCAiaW1wb3J0IHsgbGlzdEFnZW50c1ZpYUNsaSB9IGZyb20gJy4uL3J1bi1sdWEubWpzJztcblxuLy8gU2hlbGxzIG91dCB0byBgbHVhIGFnZW50cyAtLWpzb24gLS1jaWAgKHNlZSBydW4tbHVhLm1qcyBmb3Igd2h5KS4gVGhlIENMSVxuLy8gZW1pdHMgb25lIHJvdyBwZXIgb3JnYW5pc2F0aW9uIHdpdGggYSBuZXN0ZWQgYGFnZW50c2AgYXJyYXk7IHdlIGZsYXR0ZW4uXG5cbmV4cG9ydCBjb25zdCBsaXN0QWdlbnRzID0ge1xuICBzcGVjOiB7XG4gICAgbmFtZTogJ2xpc3RfYWdlbnRzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0xpc3QgYWxsIEx1YSBhZ2VudHMgdGhlIGF1dGhlbnRpY2F0ZWQgY3JlZGVudGlhbCBjYW4gcmVhY2guIFJldHVybnMgYSBjb21wYWN0IGFycmF5IG9mIHtpZCwgbmFtZSwgb3JnSWQsIG9yZ05hbWUsIHZpc2liaWxpdHl9IGZsYXR0ZW5lZCBhY3Jvc3MgYWxsIG9yZ2FuaXNhdGlvbnMuIFNhbWUgZGF0YSBhcyBgbHVhIGFnZW50cyAtLWpzb25gIFx1MjAxNCBpdCByZXNvbHZlcyBldmVyeSBvcmdhbmlzYXRpb24sIHNvIG9uIGFjY291bnRzIHdpdGggbWFueSBvcmdzIHRoaXMgdGFrZXMgMjAgcyBvciBtb3JlOyBwcmVmZXIgZ2V0X2FnZW50IHdoZW4geW91IGFscmVhZHkga25vdyB0aGUgaWQuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7fSxcbiAgICAgIHJlcXVpcmVkOiBbXSxcbiAgICB9LFxuICB9LFxuICBhc3luYyBoYW5kbGVyKF9hcmdzLCBkZXBzID0ge30pIHtcbiAgICBjb25zdCBjb21wYWN0ID0gYXdhaXQgbGlzdEFnZW50c1ZpYUNsaSh7IHNwYXduRm46IGRlcHMuc3Bhd25GbiwgbGFiZWw6ICdsaXN0X2FnZW50cycgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogSlNPTi5zdHJpbmdpZnkoY29tcGFjdCwgbnVsbCwgMikgfV0sXG4gICAgfTtcbiAgfSxcbn07XG4iLCAiaW1wb3J0IHsgbGlzdEFnZW50c1ZpYUNsaSB9IGZyb20gJy4uL3J1bi1sdWEubWpzJztcblxuLy8gVGhlcmUgaXMgbm8gY29uc29saWRhdGVkIGBHRVQgL2RldmVsb3Blci9hZ2VudHMvOmFnZW50SWRgIHJvdXRlLCBhbmQgdGhlXG4vLyBwdWJsaWMgYC9wdWJsaWMvYWdlbnRzLzphZ2VudElkYCByb3V0ZSBpcyBvcmlnaW4tZ3VhcmRlZCAoYnJvd3NlciBvbmx5KS5cbi8vIFRoZSBhZ2VudCdzIGlkZW50aXR5IChpZCwgbmFtZSwgb3JnLCB2aXNpYmlsaXR5KSBJUyBpbiBgbHVhIGFnZW50cyAtLWpzb25gLFxuLy8gc28gd2Ugc2hlbGwgb3V0IGFuZCBmaWx0ZXIgXHUyMDE0IHNhbWUgcGF0aCBhcyBsaXN0X2FnZW50cy4gUGVyc29uYSwgbW9kZWwgYW5kXG4vLyBlbnYgbGl2ZSBiZWhpbmQgc2VwYXJhdGUgcGVyLXJlc291cmNlIHJvdXRlczsgdXNlIHRoZSBkZWRpY2F0ZWQgdG9vbHMgKG9yXG4vLyBgbHVhIHN0YXR1cyAtLWpzb25gIGluc2lkZSB0aGUgcHJvamVjdCkgZm9yIHRob3NlLlxuXG5leHBvcnQgY29uc3QgZ2V0QWdlbnQgPSB7XG4gIHNwZWM6IHtcbiAgICBuYW1lOiAnZ2V0X2FnZW50JyxcbiAgICBkZXNjcmlwdGlvbjogJ0xvb2sgdXAgb25lIEx1YSBhZ2VudCBieSBJRCBhbmQgcmV0dXJuIHtpZCwgbmFtZSwgb3JnSWQsIG9yZ05hbWUsIHZpc2liaWxpdHl9LiBGb3Igd2hhdCBpcyBsaXZlIHVzZSBnZXRfZGVwbG95bWVudF9zdGF0dXMgLyBsaXN0X3ByaW1pdGl2ZV92ZXJzaW9uczsgZm9yIGxvZ3MgdXNlIHRhaWxfbG9ncy4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYWdlbnRJZDogeyB0eXBlOiAnc3RyaW5nJywgZGVzY3JpcHRpb246ICdBZ2VudCBJRCAodGhlIGBpZGAgZmllbGQgZnJvbSBsaXN0X2FnZW50czsgYWxzbyBgYWdlbnQuYWdlbnRJZGAgaW4gbHVhLnNraWxsLnlhbWwpJyB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2FnZW50SWQnXSxcbiAgICB9LFxuICB9LFxuICBhc3luYyBoYW5kbGVyKHsgYWdlbnRJZCB9LCBkZXBzID0ge30pIHtcbiAgICBpZiAoIWFnZW50SWQpIHRocm93IG5ldyBFcnJvcignYWdlbnRJZCBpcyByZXF1aXJlZCcpO1xuICAgIGNvbnN0IGFnZW50cyA9IGF3YWl0IGxpc3RBZ2VudHNWaWFDbGkoeyBzcGF3bkZuOiBkZXBzLnNwYXduRm4sIGxhYmVsOiAnZ2V0X2FnZW50JyB9KTtcbiAgICBjb25zdCBtYXRjaCA9IGFnZW50cy5maW5kKChhKSA9PiBhLmlkID09PSBhZ2VudElkKSA/PyBudWxsO1xuXG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBnZXRfYWdlbnQ6IG5vIGFnZW50IHdpdGggaWQgXCIke2FnZW50SWR9XCIgZm91bmQgaW4gdGhlIGF1dGhlbnRpY2F0ZWQgY3JlZGVudGlhbCdzIGFjY2Vzc2libGUgb3Jncy4gUnVuIGxpc3RfYWdlbnRzIHRvIHNlZSBhdmFpbGFibGUgYWdlbnRzLmApO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiAndGV4dCcsIHRleHQ6IEpTT04uc3RyaW5naWZ5KG1hdGNoLCBudWxsLCAyKSB9XSxcbiAgICB9O1xuICB9LFxufTtcbiIsICIvLyBDcmVkZW50aWFsIHJlc29sdXRpb24gZm9yIHRoZSBNQ1Agc2VydmVyLiBSZXNvbHZlZCBvbiBFVkVSWSBjYWxsLCBub3QgYXRcbi8vIHNlcnZlciBzdGFydHVwIFx1MjAxNCBzdXBwb3J0cyB0aGUgZmxvdyB3aGVyZSBhIHVzZXIgcmUtcnVucyBgbHVhIGF1dGggY29uZmlndXJlYFxuLy8gbWlkLXNlc3Npb24uXG4vL1xuLy8gVGhlIGNoYWluIE1VU1QgbWF0Y2ggbHVhLWNsaSdzIGByZXNvbHZlUmVxdWVzdENyZWRlbnRpYWwoKWBcbi8vIChwYWNrYWdlcy9sdWEtY2xpL3NyYy9zZXJ2aWNlcy9yZXF1ZXN0LWNyZWRlbnRpYWwudHMsIGx1YS1jbGkgMy4zMy4wKTpcbi8vXG4vLyAgIDEuIExVQV9BUElfS0VZIGluIHRoZSBwcm9jZXNzIGVudmlyb25tZW50LiBsdWEtY2xpIGxvYWRzIGAuLy5lbnZgIGludG9cbi8vICAgICAgcHJvY2Vzcy5lbnYgZmlyc3QgKGBpbXBvcnQgJ2RvdGVudi9jb25maWcnYCksIHNvIGEgYC5lbnZgIHZhbHVlIGluIHRoZVxuLy8gICAgICB3b3JraW5nIGRpcmVjdG9yeSBpcyBwYXJ0IG9mIHRoaXMgdGllciBcdTIwMTQgaXQgYmVhdHMgYSBzdG9yZWQgc2Vzc2lvbi5cbi8vICAgMi4gVGhlIHJlbmV3YWJsZSBmaXJzdC1wYXJ0eSBzZXNzaW9uIGBsdWEgYXV0aCBjb25maWd1cmVgIChlbWFpbCArIE9UUClcbi8vICAgICAgd3JpdGVzIHRvIH4vLmx1YS1jbGkvc2Vzc2lvbnMvPGVudi1oYXNoPi5qc29uLiBUaGlzIGlzIHRoZSBERUZBVUxUXG4vLyAgICAgIGxvZ2luIHNpbmNlIGx1YS1jbGkgMy4yOSBhbmQgaXQgREVMRVRFUyB+Ly5sdWEtY2xpL2NyZWRlbnRpYWxzLCBzbyBhblxuLy8gICAgICBNQ1Agc2VydmVyIHRoYXQgb25seSByZWFkIHRoZSBjcmVkZW50aWFscyBmaWxlIGZhaWxlZCBmb3IgZXZlcnlcbi8vICAgICAgc2Vzc2lvbiB1c2VyLiBUaGUgZmlsZSBob2xkcyBhIEZpcmViYXNlIHJlZnJlc2ggdG9rZW47IHRoZSBiZWFyZXIgaXNcbi8vICAgICAgYSBzaG9ydC1saXZlZCBJRCB0b2tlbiBvYnRhaW5lZCBmcm9tIEdvb2dsZSdzIHNlY3VyZXRva2VuIGVuZHBvaW50LlxuLy8gICAzLiB+Ly5sdWEtY2xpL2NyZWRlbnRpYWxzIFx1MjAxNCBhIHBsYWluLXRleHQgQVBJIGtleSAodHlwZWQgYGFwaV88dXVpZD4uPDQzPmBcbi8vICAgICAgb3IgbGVnYWN5KSwgd3JpdHRlbiB3aGVuIHRoZSB1c2VyIHBpY2tzIHRoZSBBUEkta2V5IG9wdGlvbiBvZlxuLy8gICAgICBgbHVhIGF1dGggY29uZmlndXJlYC5cbi8vXG4vLyBUaGlzIGZpbGUgZGVsaWJlcmF0ZWx5IGR1cGxpY2F0ZXMgbGliL2NyZWRlbnRpYWxzLm1qcyBiZWNhdXNlIHRoZSBNQ1Bcbi8vIHNlcnZlciBpcyBhIHNlcGFyYXRlIG5wbSBwYWNrYWdlIGFuZCBjYW4ndCByZWFjaCBpbnRvIHRoZSBwbHVnaW4ncyBsaWIvLlxuXG5pbXBvcnQgeyByZWFkRmlsZSwgcmVhZGRpciwgc3RhdCB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgam9pbiwgZGlybmFtZSB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyBob21lZGlyIH0gZnJvbSAnbm9kZTpvcyc7XG5cbmNvbnN0IERFRkFVTFRfQVBJX1VSTCA9ICdodHRwczovL2FwaS5oZXlsdWEuYWknO1xuY29uc3QgRklSRUJBU0VfUkVGUkVTSF9VUkwgPSAnaHR0cHM6Ly9zZWN1cmV0b2tlbi5nb29nbGVhcGlzLmNvbS92MS90b2tlbic7XG5jb25zdCBSRUZSRVNIX1RJTUVPVVRfTVMgPSAxNV8wMDA7XG5jb25zdCBSRUZSRVNIX1NLRVdfTVMgPSA2MF8wMDA7XG5cbi8vIEdvb2dsZSdzIHZlcmRpY3RzIHRoYXQgdGhlIHN0b3JlZCByZWZyZXNoIHRva2VuIGNhbiBuZXZlciB3b3JrIGFnYWluLlxuLy8gTWlycm9ycyBsdWEtY2xpJ3MgUkVKRUNURURfUkVGUkVTSF9SRUFTT05TIChzZXJ2aWNlcy9maXJlYmFzZS1zZXNzaW9uLnRzKS5cbmNvbnN0IFJFSkVDVEVEX1JFRlJFU0hfUkVBU09OUyA9IFtcbiAgJ1RPS0VOX0VYUElSRUQnLFxuICAnVVNFUl9ESVNBQkxFRCcsXG4gICdVU0VSX05PVF9GT1VORCcsXG4gICdJTlZBTElEX1JFRlJFU0hfVE9LRU4nLFxuICAnSU5WQUxJRF9HUkFOVF9UWVBFJyxcbiAgJ01JU1NJTkdfUkVGUkVTSF9UT0tFTicsXG5dO1xuXG4vLyBJbi1wcm9jZXNzIGNhY2hlIG9mIHJlZnJlc2hlZCBJRCB0b2tlbnMsIGtleWVkIGJ5IHNlc3Npb24gZmlsZSBwYXRoLlxuY29uc3QgdG9rZW5DYWNoZSA9IG5ldyBNYXAoKTtcblxuLyoqIEV4cG9ydGVkIGZvciB0ZXN0cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGVhclRva2VuQ2FjaGUoKSB7XG4gIHRva2VuQ2FjaGUuY2xlYXIoKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhIGRvdGVudi1zdHlsZSBmaWxlIGZvciBMVUFfQVBJX0tFWSB0aGUgd2F5IGRvdGVudiBkb2VzOiBvcHRpb25hbFxuICogYGV4cG9ydCBgIHByZWZpeCwgc3Vycm91bmRpbmcgc2luZ2xlL2RvdWJsZSBxdW90ZXMgc3RyaXBwZWQsIGEgdHJhaWxpbmdcbiAqIGAgIyBjb21tZW50YCBkcm9wcGVkIGZyb20gdW5xdW90ZWQgdmFsdWVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50XG4gKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURvdGVudkFwaUtleShjb250ZW50KSB7XG4gIGZvciAoY29uc3QgcmF3TGluZSBvZiBjb250ZW50LnNwbGl0KC9cXHI/XFxuLykpIHtcbiAgICBjb25zdCBtID0gcmF3TGluZS5tYXRjaCgvXlxccyooPzpleHBvcnRcXHMrKT9MVUFfQVBJX0tFWVxccyo9XFxzKiguKikkLyk7XG4gICAgaWYgKCFtKSBjb250aW51ZTtcbiAgICBsZXQgdmFsdWUgPSBtWzFdLnRyaW0oKTtcbiAgICBjb25zdCBxdW90ZWQgPSB2YWx1ZS5tYXRjaCgvXihbJ1wiYF0pKC4qPylcXDEoPzpcXHMrIy4qKT9cXHMqJC8pO1xuICAgIGlmIChxdW90ZWQpIHZhbHVlID0gcXVvdGVkWzJdO1xuICAgIGVsc2UgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXHMrIy4qJC8sICcnKS50cmltKCk7XG4gICAgcmV0dXJuIHZhbHVlIHx8IG51bGw7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogTG9jYXRlIHRoZSBsdWEtY2xpIHNlc3Npb24gZmlsZSBmb3IgdGhlIEFQSSBiYXNlIFVSTCBpbiB1c2UuIGx1YS1jbGkgbmFtZXNcbiAqIHRoZSBmaWxlIGJ5IGEgaGFzaCBvZiAoYXBpVXJsLCBhdXRoVXJsLCBmaXJlYmFzZVdlYkFwaUtleSk7IHJhdGhlciB0aGFuXG4gKiByZWNvbXB1dGUgaXQgd2Ugc2NhbiB0aGUgZGlyZWN0b3J5IGZvciBhIGBmaXJlYmFzZS1zZXNzaW9uYCByZWNvcmQgd2hvc2VcbiAqIGBhcGlVcmxgIG1hdGNoZXMsIG5ld2VzdCBmaXJzdC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx7cGF0aDogc3RyaW5nLCBzZXNzaW9uOiBvYmplY3R9fG51bGw+fVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluZFNlc3Npb25GaWxlKHsgc2Vzc2lvbnNEaXIsIGFwaVVybCB9KSB7XG4gIGxldCBuYW1lcztcbiAgdHJ5IHtcbiAgICBuYW1lcyA9IGF3YWl0IHJlYWRkaXIoc2Vzc2lvbnNEaXIpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCBjYW5kaWRhdGVzID0gW107XG4gIGZvciAoY29uc3QgbmFtZSBvZiBuYW1lcykge1xuICAgIGlmICghbmFtZS5lbmRzV2l0aCgnLmpzb24nKSB8fCBuYW1lLnN0YXJ0c1dpdGgoJy4nKSkgY29udGludWU7XG4gICAgY29uc3QgcGF0aCA9IGpvaW4oc2Vzc2lvbnNEaXIsIG5hbWUpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzZXNzaW9uID0gSlNPTi5wYXJzZShhd2FpdCByZWFkRmlsZShwYXRoLCAndXRmOCcpKTtcbiAgICAgIGlmIChzZXNzaW9uPy5raW5kICE9PSAnZmlyZWJhc2Utc2Vzc2lvbicgfHwgc2Vzc2lvbj8udmVyc2lvbiAhPT0gMSkgY29udGludWU7XG4gICAgICBpZiAodHlwZW9mIHNlc3Npb24ucmVmcmVzaFRva2VuICE9PSAnc3RyaW5nJyB8fCAhc2Vzc2lvbi5yZWZyZXNoVG9rZW4pIGNvbnRpbnVlO1xuICAgICAgaWYgKHR5cGVvZiBzZXNzaW9uLmZpcmViYXNlV2ViQXBpS2V5ICE9PSAnc3RyaW5nJyB8fCAhc2Vzc2lvbi5maXJlYmFzZVdlYkFwaUtleSkgY29udGludWU7XG4gICAgICBpZiAoc2Vzc2lvbi5hcGlVcmwgIT09IGFwaVVybCkgY29udGludWU7XG4gICAgICBjb25zdCB7IG10aW1lTXMgfSA9IGF3YWl0IHN0YXQocGF0aCk7XG4gICAgICBjYW5kaWRhdGVzLnB1c2goeyBwYXRoLCBzZXNzaW9uLCBtdGltZU1zIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gdW5yZWFkYWJsZSAvIG1hbGZvcm1lZCBcdTIwMTQgc2tpcCwgbHVhLWNsaSB3aWxsIGNvbXBsYWluIG9uIGl0cyBvd25cbiAgICB9XG4gIH1cbiAgaWYgKGNhbmRpZGF0ZXMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgY2FuZGlkYXRlcy5zb3J0KChhLCBiKSA9PiBiLm10aW1lTXMgLSBhLm10aW1lTXMpO1xuICByZXR1cm4geyBwYXRoOiBjYW5kaWRhdGVzWzBdLnBhdGgsIHNlc3Npb246IGNhbmRpZGF0ZXNbMF0uc2Vzc2lvbiB9O1xufVxuXG4vKipcbiAqIEV4Y2hhbmdlIHRoZSBzdG9yZWQgcmVmcmVzaCB0b2tlbiBmb3IgYSBGaXJlYmFzZSBJRCB0b2tlbiAodGhlIGJlYXJlclxuICogbHVhLWFwaSBhY2NlcHRzKS4gQ2FjaGVkIGluLXByb2Nlc3MgdW50aWwgNjAgcyBiZWZvcmUgZXhwaXJ5LiBUaGUgc2Vzc2lvblxuICogZmlsZSBpcyBuZXZlciB3cml0dGVuOiBsdWEtY2xpIG93bnMgaXQuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gYmVhcmVyIHRva2VuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWZyZXNoU2Vzc2lvbkJlYXJlcih7IHBhdGgsIHNlc3Npb24sIGZldGNoRm4gPSBnbG9iYWxUaGlzLmZldGNoLCBub3cgPSBEYXRlLm5vdyB9KSB7XG4gIGNvbnN0IGNhY2hlZCA9IHRva2VuQ2FjaGUuZ2V0KHBhdGgpO1xuICBpZiAoY2FjaGVkICYmIGNhY2hlZC5leHBpcmVzQXQgLSBub3coKSA+IFJFRlJFU0hfU0tFV19NUykgcmV0dXJuIGNhY2hlZC5pZFRva2VuO1xuXG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiBjb250cm9sbGVyLmFib3J0KCksIFJFRlJFU0hfVElNRU9VVF9NUyk7XG4gIGxldCByZXM7XG4gIHRyeSB7XG4gICAgcmVzID0gYXdhaXQgZmV0Y2hGbihgJHtGSVJFQkFTRV9SRUZSRVNIX1VSTH0/a2V5PSR7ZW5jb2RlVVJJQ29tcG9uZW50KHNlc3Npb24uZmlyZWJhc2VXZWJBcGlLZXkpfWAsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSxcbiAgICAgIGJvZHk6IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyBncmFudF90eXBlOiAncmVmcmVzaF90b2tlbicsIHJlZnJlc2hfdG9rZW46IHNlc3Npb24ucmVmcmVzaFRva2VuIH0pLnRvU3RyaW5nKCksXG4gICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgIH0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTUNQX0FVVEhfVU5BVkFJTEFCTEU6IGNvdWxkIG5vdCByZWZyZXNoIHRoZSBsdWEtY2xpIHNlc3Npb24gKCR7ZXJyPy5uYW1lID09PSAnQWJvcnRFcnJvcicgPyAndGltZWQgb3V0JyA6IGVyci5tZXNzYWdlfSkuIGAgK1xuICAgICAgJ0NoZWNrIHlvdXIgbmV0d29yaywgb3Igc2V0IExVQV9BUElfS0VZIHRvIGJ5cGFzcyB0aGUgc2Vzc2lvbi4nXG4gICAgKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICB9XG5cbiAgaWYgKCFyZXMub2spIHtcbiAgICBsZXQgcmVhc29uID0gcmVzLnN0YXR1c1RleHQgPz8gU3RyaW5nKHJlcy5zdGF0dXMpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBib2R5ID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBib2R5Py5lcnJvcj8ubWVzc2FnZTtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycgJiYgbWVzc2FnZSkgcmVhc29uID0gbWVzc2FnZS5zcGxpdCgnOicpWzBdLnRyaW0oKTtcbiAgICB9IGNhdGNoIHsgLyoga2VlcCBzdGF0dXNUZXh0ICovIH1cbiAgICBjb25zdCByZWplY3RlZCA9IHJlcy5zdGF0dXMgPCA1MDAgJiYgUkVKRUNURURfUkVGUkVTSF9SRUFTT05TLmZpbmQoKHIpID0+IHJlYXNvbi50b1VwcGVyQ2FzZSgpLmluY2x1ZGVzKHIpKTtcbiAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYE1DUF9BVVRIX1NUQUxFOiB5b3VyIGx1YS1jbGkgc2Vzc2lvbiB3YXMgc2lnbmVkIG91dCAoJHtyZWplY3RlZH0pLiBgICtcbiAgICAgICAgJ1NpZ25pbmcgb3V0IG9mIHRoZSBMdWEgZGFzaGJvYXJkLCBkZXNrdG9wIG9yIG1vYmlsZSBhcHAgYWxzbyBlbmRzIENMSSBzZXNzaW9ucy4gJyArXG4gICAgICAgICdSdW4gYGx1YSBhdXRoIGNvbmZpZ3VyZWAgaW4gYSB0ZXJtaW5hbCB0byBzaWduIGluIGFnYWluLidcbiAgICAgICk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgTUNQX0FVVEhfVU5BVkFJTEFCTEU6IGx1YS1jbGkgc2Vzc2lvbiByZWZyZXNoIGZhaWxlZCAoJHtyZXMuc3RhdHVzfSAke3JlYXNvbn0pLiBSZXRyeSBpbiBhIG1vbWVudC5gKTtcbiAgfVxuXG4gIGNvbnN0IGJvZHkgPSBhd2FpdCByZXMuanNvbigpO1xuICBjb25zdCBpZFRva2VuID0gYm9keT8uaWRfdG9rZW47XG4gIGNvbnN0IGV4cGlyZXNJbiA9IE51bWJlcihib2R5Py5leHBpcmVzX2luKTtcbiAgaWYgKHR5cGVvZiBpZFRva2VuICE9PSAnc3RyaW5nJyB8fCAhaWRUb2tlbiB8fCAhTnVtYmVyLmlzRmluaXRlKGV4cGlyZXNJbikgfHwgZXhwaXJlc0luIDw9IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01DUF9BVVRIX1VOQVZBSUxBQkxFOiB0aGUgc2Vzc2lvbiByZWZyZXNoIHJldHVybmVkIGFuIGludmFsaWQgdG9rZW4uIFJ1biBgbHVhIGF1dGggY29uZmlndXJlYCBhZ2Fpbi4nKTtcbiAgfVxuICB0b2tlbkNhY2hlLnNldChwYXRoLCB7IGlkVG9rZW4sIGV4cGlyZXNBdDogbm93KCkgKyBleHBpcmVzSW4gKiAxMDAwIH0pO1xuICByZXR1cm4gaWRUb2tlbjtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBiZWFyZXIgdG9rZW4gZXZlcnkgbHVhLWFwaSByZXF1ZXN0IHNob3VsZCBjYXJyeS5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fVxuICogQHRocm93cyB7RXJyb3J9IE1DUF9BVVRIX1NUQUxFIHdoZW4gbm8gY3JlZGVudGlhbCByZXNvbHZlcyBmcm9tIGFueSB0aWVyXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNvbHZlQXBpS2V5KHtcbiAgZW52ID0gcHJvY2Vzcy5lbnYsXG4gIGNyZWRlbnRpYWxzUGF0aCA9IGVudi5MVUFfQ1JFREVOVElBTFNfUEFUSCA/PyBqb2luKGhvbWVkaXIoKSwgJy5sdWEtY2xpJywgJ2NyZWRlbnRpYWxzJyksXG4gIHNlc3Npb25zRGlyID0gZW52LkxVQV9TRVNTSU9OU19ESVIgPz8gam9pbihkaXJuYW1lKGNyZWRlbnRpYWxzUGF0aCksICdzZXNzaW9ucycpLFxuICBjd2QgPSBwcm9jZXNzLmN3ZCgpLFxuICBhcGlVcmwgPSBlbnYuTFVBX0FQSV9VUkwgfHwgREVGQVVMVF9BUElfVVJMLFxuICBmZXRjaEZuID0gZ2xvYmFsVGhpcy5mZXRjaCxcbiAgbm93ID0gRGF0ZS5ub3csXG59ID0ge30pIHtcbiAgLy8gVGllciAxYTogcHJvY2VzcyBlbnZpcm9ubWVudFxuICBpZiAoZW52LkxVQV9BUElfS0VZICYmIGVudi5MVUFfQVBJX0tFWS50cmltKCkpIHJldHVybiBlbnYuTFVBX0FQSV9LRVkudHJpbSgpO1xuXG4gIC8vIFRpZXIgMWI6IC5lbnYgaW4gdGhlIHdvcmtpbmcgZGlyZWN0b3J5IChsdWEtY2xpIGxvYWRzIGl0IGludG8gcHJvY2Vzcy5lbnZcbiAgLy8gYmVmb3JlIHJlYWRpbmcgTFVBX0FQSV9LRVksIHNvIGl0IHJhbmtzIGFib3ZlIHRoZSBzdG9yZWQgc2Vzc2lvbilcbiAgdHJ5IHtcbiAgICBjb25zdCBmcm9tRG90ZW52ID0gcGFyc2VEb3RlbnZBcGlLZXkoYXdhaXQgcmVhZEZpbGUoam9pbihjd2QsICcuZW52JyksICd1dGY4JykpO1xuICAgIGlmIChmcm9tRG90ZW52KSByZXR1cm4gZnJvbURvdGVudjtcbiAgfSBjYXRjaCB7IC8qIG5vIC5lbnYgXHUyMDE0IGZhbGwgdGhyb3VnaCAqLyB9XG5cbiAgLy8gVGllciAyOiByZW5ld2FibGUgZmlyc3QtcGFydHkgc2Vzc2lvblxuICBjb25zdCBmb3VuZCA9IGF3YWl0IGZpbmRTZXNzaW9uRmlsZSh7IHNlc3Npb25zRGlyLCBhcGlVcmwgfSk7XG4gIGlmIChmb3VuZCkgcmV0dXJuIHJlZnJlc2hTZXNzaW9uQmVhcmVyKHsgLi4uZm91bmQsIGZldGNoRm4sIG5vdyB9KTtcblxuICAvLyBUaWVyIDM6IH4vLmx1YS1jbGkvY3JlZGVudGlhbHMgKHBsYWluIHRleHQgQVBJIGtleSlcbiAgdHJ5IHtcbiAgICBjb25zdCByYXcgPSAoYXdhaXQgcmVhZEZpbGUoY3JlZGVudGlhbHNQYXRoLCAndXRmOCcpKS50cmltKCk7XG4gICAgaWYgKHJhdykge1xuICAgICAgaWYgKHJhdy5zdGFydHNXaXRoKCd7JykpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgICAgICAgaWYgKHBhcnNlZD8uYXBpS2V5KSByZXR1cm4gcGFyc2VkLmFwaUtleTtcbiAgICAgICAgfSBjYXRjaCB7IC8qIG5vdCBKU09OIGRlc3BpdGUgbGVhZGluZyBicmFjZSAqLyB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmF3O1xuICAgIH1cbiAgfSBjYXRjaCB7IC8qIG1pc3NpbmcgLyB1bnJlYWRhYmxlIFx1MjAxNCBmYWxsIHRocm91Z2ggKi8gfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICAnTUNQX0FVVEhfU1RBTEU6IE5vIGx1YS1jbGkgY3JlZGVudGlhbHMgZm91bmQgaW4gTFVBX0FQSV9LRVksIC5lbnYsIH4vLmx1YS1jbGkvc2Vzc2lvbnMsIG9yIH4vLmx1YS1jbGkvY3JlZGVudGlhbHMuICcgK1xuICAgICdSdW4gYGx1YSBhdXRoIGNvbmZpZ3VyZWAgaW4gYSB0ZXJtaW5hbCAob3IgL2x1YS1hdXRoIGluIENsYXVkZSBDb2RlKS4nXG4gICk7XG59XG4iLCAiLy8gVGhpbiBIVFRQIHdyYXBwZXIgYXJvdW5kIGx1YS1hcGkuIFBlciB0ZWNoIHNwZWMgXHUwMEE3OC5cbi8vXG4vLyBXZSBkbyBOT1QgaW1wb3J0IGx1YS1jbGkncyBIdHRwQ2xpZW50IGNsYXNzZXMgYXQgcnVudGltZSAod291bGQgZm9yY2Vcbi8vIHRoZSBlbnRpcmUgbHVhLWNsaSBwYWNrYWdlIHRvIGJlIGJ1bmRsZWQpLiBJbnN0ZWFkLCB0aGlzIG1pbmltYWwgY2xpZW50XG4vLyBoaXRzIHRoZSBzYW1lIFJFU1QgZW5kcG9pbnRzIGx1YS1jbGkgZG9lcy4gRXZlcnkgcm91dGUsIHF1ZXJ5IHBhcmFtZXRlclxuLy8gYW5kIGVudmVsb3BlIHVzZWQgYnkgdGhlIHRvb2xzIGlzIHZlcmlmaWVkIGFnYWluc3QgcGFja2FnZXMvbHVhLWFwaVxuLy8gKGNvbnRyb2xsZXJzL2RldmVsb3Blci8qKiwgZHRvLyoqKSBcdTIwMTQgc2VlIHJlc3BvbnNlLXNoYXBlcy5tanMuXG5cbmltcG9ydCB7IHJlc29sdmVBcGlLZXkgfSBmcm9tICcuL2F1dGgubWpzJztcblxuY29uc3QgREVGQVVMVF9CQVNFX1VSTCA9ICdodHRwczovL2FwaS5oZXlsdWEuYWknO1xuY29uc3QgREVGQVVMVF9USU1FT1VUX01TID0gMTBfMDAwO1xuXG4vLyBTY29wZSBlYWNoIHJvdXRlIGZhbWlseSB0aGUgdG9vbHMgY2FsbCBhY3R1YWxseSByZXF1aXJlcyBcdTIwMTQgcmVhZCBmcm9tIHRoZVxuLy8gYEBSZXF1aXJlU2NvcGUoLi4uKWAgZGVjb3JhdG9yIG9uIGV2ZXJ5IEdFVCB0aGUgdG9vbHMgaGl0LCB1bmRlclxuLy8gbHVhLWNvcmUtc2VydmljZXMgcGFja2FnZXMvbHVhLWFwaS9zcmMvY29udHJvbGxlcnMvZGV2ZWxvcGVyLzpcbi8vICAgc2tpbGxzL2Jhc2UuY29udHJvbGxlci50cywgd2ViaG9va3MvYmFzZS5jb250cm9sbGVyLnRzLFxuLy8gICBqb2JzL2Jhc2UuY29udHJvbGxlci50cywgdHJpZ2dlcnMvYmFzZS5jb250cm9sbGVyLnRzLFxuLy8gICBwcmVwcm9jZXNzb3JzL2Jhc2UuY29udHJvbGxlci50cywgcG9zdHByb2Nlc3NvcnMvYmFzZS5jb250cm9sbGVyLnRzXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcdTIxOTIgJ2F1dG9tYXRpb25zOnJlYWQnIChsaXN0ICsgOmlkL3ZlcnNpb25zKVxuLy8gICB3b3JrZmxvd3MvYmFzZS5jb250cm9sbGVyLnRzICAgXHUyMTkyICd3b3JrZmxvd3M6cmVhZCcgICAoR0VUIDphZ2VudElkLCBHRVQgOmFnZW50SWQvOndvcmtmbG93SWQvdmVyc2lvbnMpXG4vLyAgIHBlcnNvbmEvYmFzZS5jb250cm9sbGVyLnRzICAgICBcdTIxOTIgJ2FnZW50czpyZWFkJyAgICAgIChHRVQgOmFnZW50SWQvcGVyc29uYS92ZXJzaW9ucylcbi8vICAgYmFzZS5jb250cm9sbGVyLnRzICAgICAgICAgICAgIFx1MjE5MiAna25vd2xlZGdlOnJlYWQnICAgKEdFVCBhZ2VudHMvOmFnZW50SWQvbG9ncylcbi8vIFdvcmtmbG93cyBhcmUgTk9UIHVuZGVyIGF1dG9tYXRpb25zOnJlYWQgXHUyMDE0IHRoZXkgaGF2ZSB0aGVpciBvd24gc2NvcGUgcGFpclxuLy8gKHdvcmtmbG93czpyZWFkIC8gd29ya2Zsb3dzOndyaXRlKS5cbmV4cG9ydCBjb25zdCBST1VURV9TQ09QRVMgPSBPYmplY3QuZnJlZXplKHtcbiAgc2tpbGxzOiAnYXV0b21hdGlvbnM6cmVhZCcsXG4gIHdlYmhvb2tzOiAnYXV0b21hdGlvbnM6cmVhZCcsXG4gIGpvYnM6ICdhdXRvbWF0aW9uczpyZWFkJyxcbiAgdHJpZ2dlcnM6ICdhdXRvbWF0aW9uczpyZWFkJyxcbiAgcHJlcHJvY2Vzc29yczogJ2F1dG9tYXRpb25zOnJlYWQnLFxuICBwb3N0cHJvY2Vzc29yczogJ2F1dG9tYXRpb25zOnJlYWQnLFxuICB3b3JrZmxvd3M6ICd3b3JrZmxvd3M6cmVhZCcsXG4gIHBlcnNvbmE6ICdhZ2VudHM6cmVhZCcsXG4gIGxvZ3M6ICdrbm93bGVkZ2U6cmVhZCcsXG59KTtcblxuY29uc3QgUk9VVEVfU0NPUEVfU1VNTUFSWSA9XG4gICdza2lsbHMvd2ViaG9va3Mvam9icy90cmlnZ2Vycy9wcmVwcm9jZXNzb3JzL3Bvc3Rwcm9jZXNzb3JzIG5lZWQgYXV0b21hdGlvbnM6cmVhZCwgd29ya2Zsb3dzIG5lZWQgJyArXG4gICd3b3JrZmxvd3M6cmVhZCwgcGVyc29uYSBuZWVkcyBhZ2VudHM6cmVhZCwgbG9ncyBuZWVkIGtub3dsZWRnZTpyZWFkJztcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIEFQSSBwYXRoICh3aXRoIGxlYWRpbmcgc2xhc2gpXG4gKiBAcGFyYW0ge3ttZXRob2Q/OiBzdHJpbmcsIGJvZHk/OiBvYmplY3QsIHF1ZXJ5PzogUmVjb3JkPHN0cmluZyxzdHJpbmd8bnVtYmVyPiwgZmV0Y2hGbj86IHR5cGVvZiBmZXRjaCwgYmFzZVVybD86IHN0cmluZywgdGltZW91dE1zPzogbnVtYmVyfX0gW29wdHNdXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhcGlSZXF1ZXN0KHBhdGgsIHtcbiAgbWV0aG9kID0gJ0dFVCcsXG4gIGJvZHksXG4gIHF1ZXJ5LFxuICBmZXRjaEZuID0gZ2xvYmFsVGhpcy5mZXRjaCxcbiAgYmFzZVVybCA9IHByb2Nlc3MuZW52LkxVQV9BUElfVVJMIHx8IERFRkFVTFRfQkFTRV9VUkwsXG4gIHRpbWVvdXRNcyA9IERFRkFVTFRfVElNRU9VVF9NUyxcbn0gPSB7fSkge1xuICBjb25zdCBhcGlLZXkgPSBhd2FpdCByZXNvbHZlQXBpS2V5KCk7XG4gIC8vIEpvaW4gYnkgc3RyaW5nIGNvbmNhdGVuYXRpb24sIE5PVCBgbmV3IFVSTChwYXRoLCBiYXNlVXJsKWA6IHRoZSBXSEFUV0dcbiAgLy8gcmVzb2x2ZXIgdHJlYXRzIGEgbGVhZGluZy1zbGFzaCBwYXRoIGFzIGhvc3QtYWJzb2x1dGUgYW5kIHdvdWxkIGRyb3AgYW55XG4gIC8vIHBhdGggcHJlZml4IG9uIExVQV9BUElfVVJMIChodHRwczovL2hvc3QvYXBpICsgL2RldmVsb3Blci94IFx1MjE5MlxuICAvLyBodHRwczovL2hvc3QvZGV2ZWxvcGVyL3gpLiBgcGF0aGAgYWx3YXlzIHN0YXJ0cyB3aXRoICcvJywgc28gc3RyaXAgb25lXG4gIC8vIHRyYWlsaW5nIHNsYXNoIGZyb20gdGhlIGJhc2UgYW5kIGNvbmNhdGVuYXRlLlxuICBjb25zdCB1cmwgPSBuZXcgVVJMKGJhc2VVcmwucmVwbGFjZSgvXFwvJC8sICcnKSArIHBhdGgpO1xuICBpZiAocXVlcnkpIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKHF1ZXJ5KSkgdXJsLnNlYXJjaFBhcmFtcy5zZXQoaywgU3RyaW5nKHYpKTtcblxuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gY29udHJvbGxlci5hYm9ydCgpLCB0aW1lb3V0TXMpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2hGbih1cmwudG9TdHJpbmcoKSwge1xuICAgICAgbWV0aG9kLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHthcGlLZXl9YCxcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ1gtTHVhLUNsaWVudCc6ICdjbGF1ZGUtcGx1Z2luLzEuNS4wJyxcbiAgICAgIH0sXG4gICAgICBib2R5OiBib2R5ID8gSlNPTi5zdHJpbmdpZnkoYm9keSkgOiB1bmRlZmluZWQsXG4gICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgIH0pO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnTUNQX0FVVEhfU1RBTEU6IGx1YS1hcGkgcmV0dXJuZWQgNDAxLiBUaGUgY3JlZGVudGlhbCBpcyBtaXNzaW5nLCBleHBpcmVkLCBvciB0aGUgc2Vzc2lvbiB3YXMgc2lnbmVkIG91dCAnICtcbiAgICAgICAgJyhzaWduaW5nIG91dCBvZiB0aGUgTHVhIGRhc2hib2FyZCBvciBhcHBzIGFsc28gZW5kcyBDTEkgc2Vzc2lvbnMpLiBSdW4gYGx1YSBhdXRoIGNvbmZpZ3VyZWAgaW4gYSB0ZXJtaW5hbCwgJyArXG4gICAgICAgICdvciByZS1ydW4gL2x1YS1kb2N0b3IuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgTUNQX0ZPUkJJRERFTjogbHVhLWFwaSByZXR1cm5lZCA0MDMgZm9yICR7cGF0aH0uIFRoZSBjcmVkZW50aWFsIGNhbm5vdCBhY2Nlc3MgdGhpcyBhZ2VudCBvciBvcmcsIG9yIGl0IGxhY2tzIGAgK1xuICAgICAgICBgdGhlIHJvdXRlIHNjb3BlICgke1JPVVRFX1NDT1BFX1NVTU1BUll9IFx1MjAxNCB0eXBlZCBrZXlzIGFyZSBzY29wZWQgdG8gdGhlIGFnZW50cyBhbmQgcm9sZSBjaG9zZW4gYXQgYCArXG4gICAgICAgICdgbHVhIGF1dGggY29uZmlndXJlYCkuIFJlLXJ1biAvbHVhLWRvY3RvciBvciBjaGVjayB0aGUgTFVBX0FQSV9LRVkgZW52IHZhci4nXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoIXJlcy5vaykge1xuICAgICAgLy8gVHJ5IHRvIHBhcnNlIGx1YS1hcGkncyBzdHJ1Y3R1cmVkIGVycm9yIGVudmVsb3BlOlxuICAgICAgLy8gICB7IHN1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogeyBtZXNzYWdlLCBzdGF0dXNDb2RlLCBjb2RlPywgLi4uIH0gfVxuICAgICAgLy8gRmFsbHMgYmFjayB0byByYXcgdGV4dCBvbiBwYXJzZSBmYWlsdXJlIChlLmcuIHByb3h5IDUwMiB3aXRoIEhUTUwgYm9keSkuXG4gICAgICBjb25zdCByYXcgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgbGV0IGZyaWVuZGx5TXNnID0gcmF3O1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgICBmcmllbmRseU1zZyA9IHBhcnNlZD8uZXJyb3I/Lm1lc3NhZ2UgPz8gcGFyc2VkPy5tZXNzYWdlID8/IHJhdztcbiAgICAgICAgY29uc3QgY29kZSA9IHBhcnNlZD8uZXJyb3I/LmNvZGU7XG4gICAgICAgIGlmICh0eXBlb2YgY29kZSA9PT0gJ3N0cmluZycgJiYgY29kZSAmJiAhU3RyaW5nKGZyaWVuZGx5TXNnKS5pbmNsdWRlcyhjb2RlKSkgZnJpZW5kbHlNc2cgPSBgJHtjb2RlfTogJHtmcmllbmRseU1zZ31gO1xuICAgICAgfSBjYXRjaCB7IC8qIG5vdCBKU09OOyByYXcgaXMgZmluZSAqLyB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGx1YS1hcGkgJHtyZXMuc3RhdHVzfTogJHtmcmllbmRseU1zZ31gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgcmVzLmpzb24oKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKGVyci5uYW1lID09PSAnQWJvcnRFcnJvcicpIHRocm93IG5ldyBFcnJvcihgTUNQX1RJTUVPVVQ6ICR7cGF0aH0gZGlkIG5vdCByZXNwb25kIGluICR7dGltZW91dE1zfW1zYCk7XG4gICAgdGhyb3cgZXJyO1xuICB9IGZpbmFsbHkge1xuICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gIH1cbn1cbiIsICIvLyBQZXItdHlwZSByZXNwb25zZS1zaGFwZSBleHRyYWN0b3JzLlxuLy9cbi8vIGx1YS1hcGkncyBkZXZlbG9wZXIgZW5kcG9pbnRzIGhhdmUgSU5DT05TSVNURU5UIHJlc3BvbnNlIHNoYXBlcyBhY3Jvc3Ncbi8vIHByaW1pdGl2ZSB0eXBlcy4gVmVyaWZpZWQgYWdhaW5zdCBwYWNrYWdlcy9sdWEtYXBpL3NyYy9kdG8vKi5kdG8udHMgYW5kXG4vLyBwYWNrYWdlcy9sdWEtYXBpL3NyYy9jb250cm9sbGVycy9kZXZlbG9wZXIvKiovYmFzZS5jb250cm9sbGVyLnRzLCBwbHVzXG4vLyBwYWNrYWdlcy9sdWEtY2xpL3NyYy9pbnRlcmZhY2VzL3dvcmtmbG93cy50cyAobHVhLWNsaSAzLjMzLjApOlxuLy9cbi8vICAgU2tpbGxzICAgICAgICAgR0VUIC9kZXZlbG9wZXIvc2tpbGxzLzphZ2VudElkICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHNraWxsczogU2tpbGxEdG9bXSB9XG4vLyAgICAgICAgICAgICAgICAgIEdFVCAvZGV2ZWxvcGVyL3NraWxscy86YWdlbnRJZC86c2tpbGxJZC92ZXJzaW9ucyAgICBcdTIxOTIgeyB2ZXJzaW9uczogW3sgdmVyc2lvbiwgY3JlYXRlZERhdGUsIGlzQ3VycmVudCwgLi4uIH1dIH1cbi8vICAgV2ViaG9va3MgICAgICAgR0VUIC9kZXZlbG9wZXIvd2ViaG9va3MvOmFnZW50SWQgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHN1Y2Nlc3MsIGRhdGE6IHsgd2ViaG9va3MgfSB9XG4vLyAgICAgICAgICAgICAgICAgIEdFVCAuLi4vOndlYmhvb2tJZC92ZXJzaW9ucyAgICAgICAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyBzdWNjZXNzLCBkYXRhOiB7IHZlcnNpb25zOiBbeyB2ZXJzaW9uLCB3ZWJob29rSWQsIGNyZWF0ZWRBdCwgaXNBY3RpdmUgfV0sIGFjdGl2ZVZlcnNpb25JZD8gfSB9XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXJ2aWNlcy9kZXZlbG9wZXIud2ViaG9vay5zZXJ2aWNlLnRzIHNldHMgYHdlYmhvb2tJZDogdi5pZGAgXHUyMDE0IHRoZVxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbiBST1cgaWQgdW5kZXIgYSBtaXNuYW1lZCBrZXk7IHRoZXJlIGlzIG5vIHZlcnNpb25JZC9pZCwgc29cbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnNpb25JZCgpIGlzIG51bGwgYW5kIHRoZSBlbnZlbG9wZSdzIGFjdGl2ZVZlcnNpb25JZCBpcyB0aGUgb25seSBpZClcbi8vICAgSm9icyAgICAgICAgICAgR0VUIC9kZXZlbG9wZXIvam9icy86YWdlbnRJZCAgICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHN1Y2Nlc3MsIGRhdGE6IHsgam9icyB9IH1cbi8vICAgICAgICAgICAgICAgICAgR0VUIC4uLi86am9iSWQvdmVyc2lvbnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHN1Y2Nlc3MsIGRhdGE6IEpvYlZlcnNpb25EdG9bXSB9ICAgXHUyMTkwIGFycmF5IHVuZGVyIGRhdGE7IGBhY3RpdmVgXG4vLyAgIFRyaWdnZXJzICAgICAgIEdFVCAvZGV2ZWxvcGVyL3RyaWdnZXJzLzphZ2VudElkICAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyBzdWNjZXNzLCBkYXRhOiB7IHRyaWdnZXJzIH0gfVxuLy8gICAgICAgICAgICAgICAgICBHRVQgLi4uLzp0cmlnZ2VySWQvdmVyc2lvbnMgICAgICAgICAgICAgICAgICAgICAgICAgXHUyMTkyIHsgc3VjY2VzcywgZGF0YTogeyB2ZXJzaW9uczogW3sgdmVyc2lvbiwgdmVyc2lvbklkLCBjcmVhdGVkQXQsIGlzQWN0aXZlIH1dLCBhY3RpdmVWZXJzaW9uSWQ/IH0gfVxuLy8gICBQcmVwcm9jZXNzb3JzICBHRVQgL2RldmVsb3Blci9wcmVwcm9jZXNzb3JzLzphZ2VudElkICAgICAgICAgICAgICAgXHUyMTkyIHsgc3VjY2VzcywgZGF0YTogeyBwcmVwcm9jZXNzb3JzIH0gfVxuLy8gICAgICAgICAgICAgICAgICBHRVQgLi4uLzpwcmVwcm9jZXNzb3JJZC92ZXJzaW9ucyAgICAgICAgICAgICAgICAgICAgXHUyMTkyIHsgc3VjY2VzcywgZGF0YTogeyB2ZXJzaW9uczogW3sgdmVyc2lvbklkLCB2ZXJzaW9uLCBpc0FjdGl2ZSwgY3JlYXRlZEF0IH1dLCBhY3RpdmVWZXJzaW9uSWQ/IH0gfVxuLy8gICBQb3N0cHJvY2Vzc29ycyBHRVQgL2RldmVsb3Blci9wb3N0cHJvY2Vzc29ycy86YWdlbnRJZCAgICAgICAgICAgICAgXHUyMTkyIHsgc3VjY2VzcywgZGF0YTogeyBwb3N0cHJvY2Vzc29ycyB9IH1cbi8vICAgICAgICAgICAgICAgICAgR0VUIC4uLi86cG9zdHByb2Nlc3NvcklkL3ZlcnNpb25zICAgICAgICAgICAgICAgICAgIFx1MjE5MiBzYW1lIGZhbWlseSBhcyBwcmVwcm9jZXNzb3JzXG4vLyAgIFdvcmtmbG93cyAgICAgIEdFVCAvZGV2ZWxvcGVyL3dvcmtmbG93cy86YWdlbnRJZCAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyBzdWNjZXNzLCBkYXRhOiB7IHdvcmtmbG93cyB9IH0gICAoY29kZS9zY3JpcHQgcHJvamVjdGVkIG91dClcbi8vICAgICAgICAgICAgICAgICAgR0VUIC4uLi86d29ya2Zsb3dJZC92ZXJzaW9ucyAgICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHN1Y2Nlc3MsIGRhdGE6IFdvcmtmbG93VmVyc2lvbltdIH0gICBcdTIxOTAgYXJyYXkgdW5kZXIgZGF0YTsgYGFjdGl2ZWBcbi8vICAgUGVyc29uYSAgICAgICAgR0VUIC9kZXZlbG9wZXIvYWdlbnRzLzphZ2VudElkL3BlcnNvbmEvdmVyc2lvbnMgICAgIFx1MjE5MiB7IHN0YXR1cywgbWVzc2FnZSwgdmVyc2lvbnM6IFt7IHZlcnNpb246IG51bWJlciwgY3JlYXRlZERhdGU6IG51bWJlciwgaXNDdXJyZW50LCBwZXJzb25hIH1dIH1cbi8vXG4vLyBObyB2ZXJzaW9uIERUTyBjYXJyaWVzIGBkZXBsb3llZEF0YCBvciBgc291cmNlSGFzaGAuIFRoZSBcImxpdmVcIiBmbGFnIGlzXG4vLyBgaXNDdXJyZW50YCAoc2tpbGwsIHBlcnNvbmEpLCBgYWN0aXZlYCAoam9iLCB3b3JrZmxvdykgb3IgYGlzQWN0aXZlYCAvXG4vLyBgYWN0aXZlVmVyc2lvbklkYCAod2ViaG9vaywgdHJpZ2dlciwgcHJlL3Bvc3Rwcm9jZXNzb3IpLiBDcmVhdGlvbiB0aW1lIGlzXG4vLyBgY3JlYXRlZEF0YCAoSVNPIHN0cmluZykgZXZlcnl3aGVyZSBleGNlcHQgc2tpbGwvcGVyc29uYSAoYGNyZWF0ZWREYXRlYDtcbi8vIHBlcnNvbmEncyBpcyBhbiBlcG9jaC1tcyBudW1iZXIpLlxuXG5jb25zdCBMSVNUX0VYVFJBQ1RPUlMgPSB7XG4gIHNraWxsOiAgICAgICAgIChyKSA9PiByPy5za2lsbHMgPz8gW10sXG4gIHdlYmhvb2s6ICAgICAgIChyKSA9PiByPy5kYXRhPy53ZWJob29rcyA/PyBbXSxcbiAgam9iOiAgICAgICAgICAgKHIpID0+IHI/LmRhdGE/LmpvYnMgPz8gW10sXG4gIHRyaWdnZXI6ICAgICAgIChyKSA9PiByPy5kYXRhPy50cmlnZ2VycyA/PyBbXSxcbiAgcHJlcHJvY2Vzc29yOiAgKHIpID0+IHI/LmRhdGE/LnByZXByb2Nlc3NvcnMgPz8gW10sXG4gIHBvc3Rwcm9jZXNzb3I6IChyKSA9PiByPy5kYXRhPy5wb3N0cHJvY2Vzc29ycyA/PyBbXSxcbiAgd29ya2Zsb3c6ICAgICAgKHIpID0+IHI/LmRhdGE/LndvcmtmbG93cyA/PyBbXSxcbn07XG5cbmNvbnN0IFZFUlNJT05TX0VYVFJBQ1RPUlMgPSB7XG4gIHNraWxsOiAgICAgICAgIChyKSA9PiByPy52ZXJzaW9ucyA/PyBbXSxcbiAgd2ViaG9vazogICAgICAgKHIpID0+IHI/LmRhdGE/LnZlcnNpb25zID8/IFtdLFxuICBqb2I6ICAgICAgICAgICAocikgPT4gKEFycmF5LmlzQXJyYXkocj8uZGF0YSkgPyByLmRhdGEgOiBbXSksXG4gIHRyaWdnZXI6ICAgICAgIChyKSA9PiByPy5kYXRhPy52ZXJzaW9ucyA/PyBbXSxcbiAgcHJlcHJvY2Vzc29yOiAgKHIpID0+IHI/LmRhdGE/LnZlcnNpb25zID8/IFtdLFxuICBwb3N0cHJvY2Vzc29yOiAocikgPT4gcj8uZGF0YT8udmVyc2lvbnMgPz8gW10sXG4gIHdvcmtmbG93OiAgICAgIChyKSA9PiAoQXJyYXkuaXNBcnJheShyPy5kYXRhKSA/IHIuZGF0YSA6IFtdKSxcbiAgcGVyc29uYTogICAgICAgKHIpID0+IHI/LnZlcnNpb25zID8/IFtdLFxufTtcblxuLyoqIFVSTCBwYXRoIHNlZ21lbnQgdW5kZXIgL2RldmVsb3Blci8gZm9yIGVhY2ggbGlzdGFibGUgdHlwZS4gKi9cbmV4cG9ydCBjb25zdCBMSVNUX1BBVEhTID0ge1xuICBza2lsbDogJ3NraWxscycsXG4gIHdlYmhvb2s6ICd3ZWJob29rcycsXG4gIGpvYjogJ2pvYnMnLFxuICB0cmlnZ2VyOiAndHJpZ2dlcnMnLFxuICBwcmVwcm9jZXNzb3I6ICdwcmVwcm9jZXNzb3JzJyxcbiAgcG9zdHByb2Nlc3NvcjogJ3Bvc3Rwcm9jZXNzb3JzJyxcbiAgd29ya2Zsb3c6ICd3b3JrZmxvd3MnLFxufTtcblxuLyoqXG4gKiBFeHRyYWN0IGEgbGlzdCBvZiBwcmltaXRpdmVzIGZyb20gYSBsaXN0LWVuZHBvaW50IHJlc3BvbnNlLlxuICogQHRocm93cyBpZiB0aGUgdHlwZSBpcyB1bmtub3duLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdExpc3QodHlwZSwgcmVzcG9uc2UpIHtcbiAgY29uc3QgZm4gPSBMSVNUX0VYVFJBQ1RPUlNbdHlwZV07XG4gIGlmICghZm4pIHRocm93IG5ldyBFcnJvcihgZXh0cmFjdExpc3Q6IHVua25vd24gcHJpbWl0aXZlIHR5cGUgXCIke3R5cGV9XCIuIFZhbGlkOiAke09iamVjdC5rZXlzKExJU1RfRVhUUkFDVE9SUykuam9pbignLCAnKX1gKTtcbiAgcmV0dXJuIGZuKHJlc3BvbnNlKTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0IGEgbGlzdCBvZiB2ZXJzaW9ucyBmcm9tIGEgdmVyc2lvbnMtZW5kcG9pbnQgcmVzcG9uc2UuXG4gKiBAdGhyb3dzIGlmIHRoZSB0eXBlIGlzIHVua25vd24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0VmVyc2lvbnModHlwZSwgcmVzcG9uc2UpIHtcbiAgY29uc3QgZm4gPSBWRVJTSU9OU19FWFRSQUNUT1JTW3R5cGVdO1xuICBpZiAoIWZuKSB0aHJvdyBuZXcgRXJyb3IoYGV4dHJhY3RWZXJzaW9uczogdW5rbm93biBwcmltaXRpdmUgdHlwZSBcIiR7dHlwZX1cIi4gVmFsaWQ6ICR7T2JqZWN0LmtleXMoVkVSU0lPTlNfRVhUUkFDVE9SUykuam9pbignLCAnKX1gKTtcbiAgcmV0dXJuIGZuKHJlc3BvbnNlKTtcbn1cblxuLyoqXG4gKiBUaGUgYGFjdGl2ZVZlcnNpb25JZGAgYSB2ZXJzaW9ucyBlbnZlbG9wZSBtYXkgY2FycnkgYmVzaWRlIGl0cyBhcnJheVxuICogKHdlYmhvb2ssIHRyaWdnZXIsIHByZS9wb3N0cHJvY2Vzc29yKS4gTnVsbCBmb3IgdGhlIG90aGVyIGZhbWlsaWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEFjdGl2ZVZlcnNpb25JZChyZXNwb25zZSkge1xuICBjb25zdCBpZCA9IHJlc3BvbnNlPy5kYXRhPy5hY3RpdmVWZXJzaW9uSWQ7XG4gIHJldHVybiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmIGlkID8gaWQgOiBudWxsO1xufVxuXG4vKipcbiAqIElzIHRoaXMgdmVyc2lvbiB0aGUgb25lIHRoYXQgaXMgbGl2ZT8gRWFjaCBmYW1pbHkgc3BlbGxzIGl0IGRpZmZlcmVudGx5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge29iamVjdH0gdmVyc2lvbiAtIG9uZSBlbGVtZW50IG9mIGV4dHJhY3RWZXJzaW9ucygpXG4gKiBAcGFyYW0ge29iamVjdH0gW3Jlc3BvbnNlXSAtIHRoZSB2ZXJzaW9ucyBlbnZlbG9wZSAoZm9yIGFjdGl2ZVZlcnNpb25JZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQWN0aXZlVmVyc2lvbih0eXBlLCB2ZXJzaW9uLCByZXNwb25zZSkge1xuICBpZiAoIXZlcnNpb24gfHwgdHlwZW9mIHZlcnNpb24gIT09ICdvYmplY3QnKSByZXR1cm4gZmFsc2U7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ3NraWxsJzpcbiAgICBjYXNlICdwZXJzb25hJzpcbiAgICAgIHJldHVybiB2ZXJzaW9uLmlzQ3VycmVudCA9PT0gdHJ1ZTtcbiAgICBjYXNlICdqb2InOlxuICAgIGNhc2UgJ3dvcmtmbG93JzpcbiAgICAgIHJldHVybiB2ZXJzaW9uLmFjdGl2ZSA9PT0gdHJ1ZTtcbiAgICBjYXNlICd3ZWJob29rJzpcbiAgICBjYXNlICd0cmlnZ2VyJzpcbiAgICBjYXNlICdwcmVwcm9jZXNzb3InOlxuICAgIGNhc2UgJ3Bvc3Rwcm9jZXNzb3InOiB7XG4gICAgICBpZiAodmVyc2lvbi5pc0FjdGl2ZSA9PT0gdHJ1ZSkgcmV0dXJuIHRydWU7XG4gICAgICBjb25zdCBhY3RpdmVJZCA9IGV4dHJhY3RBY3RpdmVWZXJzaW9uSWQocmVzcG9uc2UpO1xuICAgICAgY29uc3Qgb3duSWQgPSB2ZXJzaW9uLnZlcnNpb25JZCA/PyB2ZXJzaW9uLmlkID8/IG51bGw7XG4gICAgICByZXR1cm4gISFhY3RpdmVJZCAmJiBvd25JZCA9PT0gYWN0aXZlSWQ7XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBJU08tODYwMSBjcmVhdGlvbiB0aW1lIG9mIGEgdmVyc2lvbiwgb3IgbnVsbC4gTm9ybWFsaXNlcyBza2lsbC9wZXJzb25hJ3NcbiAqIGBjcmVhdGVkRGF0ZWAgKHBlcnNvbmE6IGVwb2NoIG1zKSBvbnRvIHRoZSBgY3JlYXRlZEF0YCBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyc2lvbkNyZWF0ZWRBdCh2ZXJzaW9uKSB7XG4gIGlmICghdmVyc2lvbiB8fCB0eXBlb2YgdmVyc2lvbiAhPT0gJ29iamVjdCcpIHJldHVybiBudWxsO1xuICBjb25zdCByYXcgPSB2ZXJzaW9uLmNyZWF0ZWRBdCA/PyB2ZXJzaW9uLmNyZWF0ZWREYXRlID8/IG51bGw7XG4gIGlmIChyYXcgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gIGlmICh0eXBlb2YgcmF3ID09PSAnbnVtYmVyJykgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShyYXcpID8gbmV3IERhdGUocmF3KS50b0lTT1N0cmluZygpIDogbnVsbDtcbiAgcmV0dXJuIFN0cmluZyhyYXcpO1xufVxuXG4vKiogSWRlbnRpZmllciBvZiBhIHZlcnNpb24gcm93ICh0aGUgc2xvdCBsdWEtYXBpIGtleXMgYGFjdGl2ZVZlcnNpb25JZGAgb24pLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcnNpb25JZCh2ZXJzaW9uKSB7XG4gIGlmICghdmVyc2lvbiB8fCB0eXBlb2YgdmVyc2lvbiAhPT0gJ29iamVjdCcpIHJldHVybiBudWxsO1xuICByZXR1cm4gdmVyc2lvbi52ZXJzaW9uSWQgPz8gdmVyc2lvbi5pZCA/PyBudWxsO1xufVxuXG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX0xJU1RfVFlQRVMgPSBPYmplY3Qua2V5cyhMSVNUX0VYVFJBQ1RPUlMpO1xuZXhwb3J0IGNvbnN0IFNVUFBPUlRFRF9WRVJTSU9OX1RZUEVTID0gT2JqZWN0LmtleXMoVkVSU0lPTlNfRVhUUkFDVE9SUyk7XG4iLCAiaW1wb3J0IHsgYXBpUmVxdWVzdCB9IGZyb20gJy4uL2FwaS1jbGllbnQubWpzJztcbmltcG9ydCB7XG4gIGV4dHJhY3RMaXN0LFxuICBleHRyYWN0VmVyc2lvbnMsXG4gIGV4dHJhY3RBY3RpdmVWZXJzaW9uSWQsXG4gIGlzQWN0aXZlVmVyc2lvbixcbiAgdmVyc2lvbkNyZWF0ZWRBdCxcbiAgdmVyc2lvbklkLFxuICBMSVNUX1BBVEhTLFxuICBTVVBQT1JURURfVkVSU0lPTl9UWVBFUyxcbn0gZnJvbSAnLi4vcmVzcG9uc2Utc2hhcGVzLm1qcyc7XG5cbmNvbnN0IFZBTElEX1RZUEVTID0gbmV3IFNldChTVVBQT1JURURfVkVSU0lPTl9UWVBFUyk7XG5cbmV4cG9ydCBjb25zdCBsaXN0UHJpbWl0aXZlVmVyc2lvbnMgPSB7XG4gIHNwZWM6IHtcbiAgICBuYW1lOiAnbGlzdF9wcmltaXRpdmVfdmVyc2lvbnMnLFxuICAgIC8vIFdoaWNoIGZhbWlsaWVzIGNhcnJ5IGEgcGVyLWVudHJ5IGlkIFx1MjAxNCB2ZXJpZmllZCBpbiBsdWEtYXBpJ3Mgc2VydmljZVxuICAgIC8vIG1hcHBlcnMgKHBhY2thZ2VzL2x1YS1hcGkvc3JjL3NlcnZpY2VzLyk6XG4gICAgLy8gICBkZXZlbG9wZXIudHJpZ2dlci5zZXJ2aWNlLnRzIGdldFRyaWdnZXJWZXJzaW9ucyAgICAgICAgICAgIFx1MjE5MiB7IHZlcnNpb24sIHZlcnNpb25JZDogdi5pZCwgY3JlYXRlZEF0LCBpc0FjdGl2ZSB9XG4gICAgLy8gICBkZXZlbG9wZXIucHJlcHJvY2Vzc29yLnNlcnZpY2UudHMgZ2V0UHJlUHJvY2Vzc29yVmVyc2lvbnMgIFx1MjE5MiB7IHZlcnNpb25JZDogdi5pZCwgdmVyc2lvbiwgaXNBY3RpdmUsIGNyZWF0ZWRBdCB9XG4gICAgLy8gICBkZXZlbG9wZXIucG9zdHByb2Nlc3Nvci5zZXJ2aWNlLnRzIGdldFBvc3RQcm9jZXNzb3JWZXJzaW9uc1x1MjE5MiBzYW1lIGFzIHByZXByb2Nlc3NvclxuICAgIC8vICAgZGV2ZWxvcGVyLndvcmtmbG93LnNlcnZpY2UudHMgdG9WZXJzaW9uRHRvICAgICAgICAgICAgICAgICBcdTIxOTIgeyBpZCwgdmVyc2lvbiwgYWN0aXZlLCAuLi4gfVxuICAgIC8vICAgZHRvL2pvYi5kdG8udHMgSm9iVmVyc2lvbkR0byAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyBpZCwgdmVyc2lvbiwgYWN0aXZlLCAuLi4gfVxuICAgIC8vICAgZGV2ZWxvcGVyLndlYmhvb2suc2VydmljZS50cyBnZXRXZWJob29rVmVyc2lvbnMgICAgICAgICAgICBcdTIxOTIgeyB2ZXJzaW9uLCB3ZWJob29rSWQ6IHYuaWQsIGNyZWF0ZWRBdCwgaXNBY3RpdmUgfVxuICAgIC8vICAgICAgIChOTyB2ZXJzaW9uSWQvaWQga2V5IFx1MjAxNCB0aGUgcm93IGlkIGlzIHN0YXNoZWQgdW5kZXIgdGhlIG1pc25hbWVkXG4gICAgLy8gICAgICAgIGB3ZWJob29rSWRgLCB3aGljaCB3ZSBkZWxpYmVyYXRlbHkgZG8gbm90IHJlYWQgYXMgYSB2ZXJzaW9uIGlkKVxuICAgIC8vICAgZHRvL3NraWxsLmR0by50cyBTa2lsbFZlcnNpb25EdG8gICAgICAgICAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyB2ZXJzaW9uLCBjcmVhdGVkRGF0ZSwgY3JlYXRlZEJ5LCBpc0N1cnJlbnQgfSAobm8gaWQpXG4gICAgLy8gICBwZXJzb25hL2Jhc2UuY29udHJvbGxlci50cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHZlcnNpb246IG51bWJlciwgY3JlYXRlZERhdGUsIGlzQ3VycmVudCwgcGVyc29uYSB9IChubyBpZClcbiAgICBkZXNjcmlwdGlvbjogJ0xpc3QgdGhlIHNlcnZlci1zaWRlIHZlcnNpb25zIG9mIG9uZSBwcmltaXRpdmUgKHNraWxsLCB3ZWJob29rLCBqb2IsIHRyaWdnZXIsIHByZXByb2Nlc3NvciwgcG9zdHByb2Nlc3Nvciwgd29ya2Zsb3cpIG9yIHRoZSBhZ2VudCBwZXJzb25hLiBSZXR1cm5zIHsgYWN0aXZlVmVyc2lvbklkLCB2ZXJzaW9uczogW3t2ZXJzaW9uLCB2ZXJzaW9uSWQsIGFjdGl2ZSwgY3JlYXRlZEF0fV0gfSBcdTIwMTQgYGFjdGl2ZWAgaXMgdGhlIHZlcnNpb24gY3VycmVudGx5IGxpdmUuIGB2ZXJzaW9uSWRgIGlzIG51bGwgZm9yIHR5cGVzIHdob3NlIHZlcnNpb25zIHJvdXRlIGNhcnJpZXMgbm8gcGVyLWVudHJ5IGlkOiBza2lsbCwgcGVyc29uYSBhbmQgd2ViaG9vayAodGhlIHdlYmhvb2sgcm91dGUgZXhwb3NlcyB0aGUgcm93IGlkIG9ubHkgdW5kZXIgYSBtaXNuYW1lZCBgd2ViaG9va0lkYCBrZXkpLiBGb3IgdGhvc2UsIGlkZW50aWZ5IGEgdmVyc2lvbiBieSBgdmVyc2lvbmA7IGZvciB3ZWJob29rcyB0aGUgbGl2ZSByb3cgaWQgaXMgdGhlIHRvcC1sZXZlbCBgYWN0aXZlVmVyc2lvbklkYC4gYGFjdGl2ZVZlcnNpb25JZGAgaXMgcG9wdWxhdGVkIG9ubHkgZm9yIHdlYmhvb2ssIHRyaWdnZXIsIHByZXByb2Nlc3NvciBhbmQgcG9zdHByb2Nlc3NvciBlbnZlbG9wZXMgYW5kIGlzIG51bGwgZm9yIHNraWxsLCBqb2IsIHdvcmtmbG93IGFuZCBwZXJzb25hLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBhZ2VudElkOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgIHR5cGU6IHsgdHlwZTogJ3N0cmluZycsIGVudW06IFsuLi5WQUxJRF9UWVBFU10gfSxcbiAgICAgICAgbmFtZTogeyB0eXBlOiAnc3RyaW5nJywgZGVzY3JpcHRpb246ICdQcmltaXRpdmUgbmFtZSBhcyB3cml0dGVuIGluIGx1YS5za2lsbC55YW1sIChvbWl0IGZvciBwZXJzb25hIFx1MjAxNCBhbiBhZ2VudCBoYXMgb25seSBvbmUpJyB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2FnZW50SWQnLCAndHlwZSddLFxuICAgIH0sXG4gIH0sXG4gIGFzeW5jIGhhbmRsZXIoeyBhZ2VudElkLCB0eXBlLCBuYW1lIH0sIGRlcHMgPSB7fSkge1xuICAgIGlmICghYWdlbnRJZCB8fCAhdHlwZSkgdGhyb3cgbmV3IEVycm9yKCdhZ2VudElkIGFuZCB0eXBlIGFyZSByZXF1aXJlZCcpO1xuICAgIGlmICghVkFMSURfVFlQRVMuaGFzKHR5cGUpKSB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdHlwZTogJHt0eXBlfS4gVmFsaWQ6ICR7Wy4uLlZBTElEX1RZUEVTXS5qb2luKCcsICcpfWApO1xuICAgIGlmICh0eXBlICE9PSAncGVyc29uYScgJiYgIW5hbWUpIHRocm93IG5ldyBFcnJvcignbmFtZSBpcyByZXF1aXJlZCBmb3IgYWxsIHR5cGVzIGV4Y2VwdCBwZXJzb25hJyk7XG5cbiAgICAvLyBWZXJzaW9ucyBsaXZlIHVuZGVyIC9kZXZlbG9wZXIvPHBsdXJhbD4vOmFnZW50SWQvOmlkL3ZlcnNpb25zLCBFWENFUFRcbiAgICAvLyBwZXJzb25hIHdoaWNoIGxpdmVzIHVuZGVyIC9kZXZlbG9wZXIvYWdlbnRzLzphZ2VudElkL3BlcnNvbmEvdmVyc2lvbnNcbiAgICAvLyAobm8gOmlkKS4gVGhlIDppZCBzbG90IGlzIHRoZSBzZXJ2ZXIgaWQgKHNraWxsSWQgLyB3ZWJob29rSWQgLyAuLi4pLFxuICAgIC8vIG5ldmVyIHRoZSBuYW1lIFx1MjAxNCBzbyByZXNvbHZlIG5hbWUgXHUyMTkyIGlkIGJ5IGxpc3RpbmcgZmlyc3QuXG4gICAgbGV0IHBhdGg7XG4gICAgaWYgKHR5cGUgPT09ICdwZXJzb25hJykge1xuICAgICAgcGF0aCA9IGAvZGV2ZWxvcGVyL2FnZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChhZ2VudElkKX0vcGVyc29uYS92ZXJzaW9uc2A7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGlkID0gYXdhaXQgcmVzb2x2ZU5hbWVUb0lkKHsgYWdlbnRJZCwgdHlwZSwgbmFtZSwgZmV0Y2hGbjogZGVwcy5mZXRjaEZuIH0pO1xuICAgICAgcGF0aCA9IGAvZGV2ZWxvcGVyLyR7TElTVF9QQVRIU1t0eXBlXX0vJHtlbmNvZGVVUklDb21wb25lbnQoYWdlbnRJZCl9LyR7ZW5jb2RlVVJJQ29tcG9uZW50KGlkKX0vdmVyc2lvbnNgO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBhcGlSZXF1ZXN0KHBhdGgsIHsgZmV0Y2hGbjogZGVwcy5mZXRjaEZuIH0pO1xuICAgIGNvbnN0IHZlcnNpb25zID0gZXh0cmFjdFZlcnNpb25zKHR5cGUsIGRhdGEpO1xuICAgIGNvbnN0IGNvbXBhY3QgPSB2ZXJzaW9ucy5tYXAoKHYpID0+ICh7XG4gICAgICB2ZXJzaW9uOiB2LnZlcnNpb24sXG4gICAgICB2ZXJzaW9uSWQ6IHZlcnNpb25JZCh2KSxcbiAgICAgIGFjdGl2ZTogaXNBY3RpdmVWZXJzaW9uKHR5cGUsIHYsIGRhdGEpLFxuICAgICAgY3JlYXRlZEF0OiB2ZXJzaW9uQ3JlYXRlZEF0KHYpLFxuICAgIH0pKTtcbiAgICBjb25zdCByZXN1bHQgPSB7IGFnZW50SWQsIHR5cGUsIG5hbWU6IHR5cGUgPT09ICdwZXJzb25hJyA/IG51bGwgOiBuYW1lLCBhY3RpdmVWZXJzaW9uSWQ6IGV4dHJhY3RBY3RpdmVWZXJzaW9uSWQoZGF0YSksIHZlcnNpb25zOiBjb21wYWN0IH07XG4gICAgcmV0dXJuIHsgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBKU09OLnN0cmluZ2lmeShyZXN1bHQsIG51bGwsIDIpIH1dIH07XG4gIH0sXG59O1xuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlTmFtZVRvSWQoeyBhZ2VudElkLCB0eXBlLCBuYW1lLCBmZXRjaEZuIH0pIHtcbiAgY29uc3QgbGlzdFBhdGggPSBgL2RldmVsb3Blci8ke0xJU1RfUEFUSFNbdHlwZV19LyR7ZW5jb2RlVVJJQ29tcG9uZW50KGFnZW50SWQpfWA7XG4gIGNvbnN0IGxpc3RSZXNwb25zZSA9IGF3YWl0IGFwaVJlcXVlc3QobGlzdFBhdGgsIHsgZmV0Y2hGbiB9KTtcbiAgY29uc3QgaXRlbXMgPSBleHRyYWN0TGlzdCh0eXBlLCBsaXN0UmVzcG9uc2UpO1xuICBjb25zdCBtYXRjaCA9IGl0ZW1zLmZpbmQoKHApID0+IHAubmFtZSA9PT0gbmFtZSk7XG4gIGlmICghbWF0Y2gpIHtcbiAgICBjb25zdCBhdmFpbGFibGUgPSBpdGVtcy5tYXAoKHApID0+IHAubmFtZSkuZmlsdGVyKEJvb2xlYW4pLmpvaW4oJywgJykgfHwgJyhub25lKSc7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBsaXN0X3ByaW1pdGl2ZV92ZXJzaW9uczogbm8gJHt0eXBlfSBuYW1lZCBcIiR7bmFtZX1cIiBvbiBhZ2VudCAke2FnZW50SWR9LiBBdmFpbGFibGU6ICR7YXZhaWxhYmxlfWApO1xuICB9XG4gIGNvbnN0IGlkID0gbWF0Y2guaWQgPz8gbWF0Y2guX2lkO1xuICBpZiAoIWlkKSB0aHJvdyBuZXcgRXJyb3IoYGxpc3RfcHJpbWl0aXZlX3ZlcnNpb25zOiAke3R5cGV9IFwiJHtuYW1lfVwiIGV4aXN0cyBidXQgaGFzIG5vIGlkIGZpZWxkYCk7XG4gIHJldHVybiBpZDtcbn1cbiIsICJpbXBvcnQgeyBhcGlSZXF1ZXN0IH0gZnJvbSAnLi4vYXBpLWNsaWVudC5tanMnO1xuaW1wb3J0IHtcbiAgZXh0cmFjdExpc3QsXG4gIGV4dHJhY3RWZXJzaW9ucyxcbiAgZXh0cmFjdEFjdGl2ZVZlcnNpb25JZCxcbiAgaXNBY3RpdmVWZXJzaW9uLFxuICB2ZXJzaW9uQ3JlYXRlZEF0LFxuICB2ZXJzaW9uSWQsXG4gIExJU1RfUEFUSFMsXG59IGZyb20gJy4uL3Jlc3BvbnNlLXNoYXBlcy5tanMnO1xuXG4vLyBDb21wb3NlcyBcIndoYXQgaXMgbGl2ZVwiIGZyb20gdGhlIHBlci10eXBlIGx1YS1hcGkgbGlzdCArIHZlcnNpb25zIHJvdXRlcy5cbi8vIFRoZXJlIGlzIG5vIHNpbmdsZSBgL2FnZW50cy86aWQvcHJvZHVjdGlvbmAgcm91dGU7IGBsdWEgc3RhdHVzIC0tanNvbmBcbi8vIGdpdmVzIHRoZSBzYW1lIHBpY3R1cmUgZm9yIHRoZSBDVVJSRU5UIHByb2plY3QgKGxvY2FsIHZzIGRlcGxveWVkKSBhbmQgaXNcbi8vIHRoZSBiZXR0ZXIgdG9vbCB3aGVuIGEgbHVhLnNraWxsLnlhbWwgaXMgYXQgaGFuZC4gVGhpcyB0b29sIHdvcmtzIGZvciBhbnlcbi8vIGFnZW50IHRoZSBjcmVkZW50aWFsIGNhbiByZWFjaCwgcHJvamVjdCBvciBub3QuXG4vL1xuLy8gUGVyLXR5cGUgZW52ZWxvcGUgaGFuZGxpbmcgbGl2ZXMgaW4gcmVzcG9uc2Utc2hhcGVzLm1qcy5cbi8vXG4vLyBSZXF1ZXN0IGZhbi1vdXQgKDEgKyA3ICsgTiB2ZXJzaW9uIGxvb2t1cHMpIGlzIHBhcmFsbGVsaXNlZCBpbiB0d28gcGhhc2VzOlxuLy8gICAxLiB0aGUgcGVyc29uYSBjYWxsIGFuZCB0aGUgc2V2ZW4gbGlzdCBjYWxscyBydW4gdG9nZXRoZXI7XG4vLyAgIDIuIHBlciB0eXBlLCBpdGVtIHZlcnNpb24gbG9va3VwcyBydW4gaW4gY2h1bmtzIG9mIFZFUlNJT05TX0NIVU5LX1NJWkUuXG4vLyBPdXRwdXQgb3JkZXIgaXMgZGV0ZXJtaW5pc3RpYyByZWdhcmRsZXNzIG9mIGNvbXBsZXRpb24gb3JkZXI6IHR5cGVzIGluXG4vLyBQUklNSVRJVkVfVFlQRVMgb3JkZXIsIGl0ZW1zIGluIHRoZSBvcmRlciB0aGUgbGlzdCByb3V0ZSByZXR1cm5lZCB0aGVtLlxuLy8gQSB3YWxsLWNsb2NrIGJ1ZGdldCAoQlVER0VUX01TLCBpbmplY3RhYmxlIGFzIGRlcHMuYnVkZ2V0TXMpIHN0b3BzIE5FV1xuLy8gcmVxdWVzdHMgb25jZSBleGNlZWRlZDsgYWxyZWFkeS1pc3N1ZWQgcmVxdWVzdHMgc3RpbGwgY29tcGxldGUuIEl0ZW1zIHRoYXRcbi8vIGNvdWxkIG5vdCBiZSBsb29rZWQgdXAgYXJlIHN0aWxsIGxpc3RlZCwgd2l0aCBgZXJyb3I6IFwic2tpcHBlZDogXHUyMDI2XCJgLCBhbmRcbi8vIHRoZSByZXN1bHQgY2FycmllcyBgcGFydGlhbDogdHJ1ZWAgKyBgcGFydGlhbFJlYXNvbmAuXG5cbmNvbnN0IFBSSU1JVElWRV9UWVBFUyA9IFsnc2tpbGwnLCAnd2ViaG9vaycsICdqb2InLCAndHJpZ2dlcicsICdwcmVwcm9jZXNzb3InLCAncG9zdHByb2Nlc3NvcicsICd3b3JrZmxvdyddO1xuY29uc3QgVkVSU0lPTlNfQ0hVTktfU0laRSA9IDU7XG5jb25zdCBERUZBVUxUX0JVREdFVF9NUyA9IDQ1XzAwMDtcblxuZXhwb3J0IGNvbnN0IGdldERlcGxveW1lbnRTdGF0dXMgPSB7XG4gIHNwZWM6IHtcbiAgICBuYW1lOiAnZ2V0X2RlcGxveW1lbnRfc3RhdHVzJyxcbiAgICBkZXNjcmlwdGlvbjogJ1doYXQgaXMgbGl2ZSByaWdodCBub3cgZm9yIGFuIGFnZW50OiBmb3IgZXZlcnkgc2tpbGwsIHdlYmhvb2ssIGpvYiwgdHJpZ2dlciwgcHJlcHJvY2Vzc29yLCBwb3N0cHJvY2Vzc29yIGFuZCB3b3JrZmxvdyB0aGUgYWN0aXZlIChkZXBsb3llZCkgdmVyc2lvbiwgcGx1cyB0aGUgYWN0aXZlIHBlcnNvbmEgdmVyc2lvbi4gQ29tcG9zZWQgZnJvbSB0aGUgcGVyLXR5cGUgbHVhLWFwaSB2ZXJzaW9uIHJvdXRlcyAobGlzdCBjYWxscyBpbiBwYXJhbGxlbCwgdGhlbiBwZXItaXRlbSB2ZXJzaW9uIGxvb2t1cHMgaW4gY2h1bmtzIG9mIDUpLiBCb3VuZGVkIGJ5IGEgNDUgcyB3YWxsLWNsb2NrIGJ1ZGdldDogaWYgZXhjZWVkZWQsIHJlbWFpbmluZyBpdGVtcyBhcmUgbGlzdGVkIHdpdGggYGVycm9yOiBcInNraXBwZWQ6IFx1MjAyNlwiYCBhbmQgdGhlIHJlc3VsdCBjYXJyaWVzIGBwYXJ0aWFsOiB0cnVlYCArIGBwYXJ0aWFsUmVhc29uYC4gSW5zaWRlIGEgcHJvamVjdCwgYGx1YSBzdGF0dXMgLS1qc29uYCBhZGRpdGlvbmFsbHkgY29tcGFyZXMgbG9jYWwgdnMgZGVwbG95ZWQuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGFnZW50SWQ6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWydhZ2VudElkJ10sXG4gICAgfSxcbiAgfSxcbiAgYXN5bmMgaGFuZGxlcih7IGFnZW50SWQgfSwgZGVwcyA9IHt9KSB7XG4gICAgaWYgKCFhZ2VudElkKSB0aHJvdyBuZXcgRXJyb3IoJ2FnZW50SWQgaXMgcmVxdWlyZWQnKTtcbiAgICBjb25zdCBpZCA9IGVuY29kZVVSSUNvbXBvbmVudChhZ2VudElkKTtcbiAgICBjb25zdCBidWRnZXRNcyA9IE51bWJlci5pc0Zpbml0ZShkZXBzLmJ1ZGdldE1zKSA/IGRlcHMuYnVkZ2V0TXMgOiBERUZBVUxUX0JVREdFVF9NUztcbiAgICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IG92ZXJCdWRnZXQgPSAoKSA9PiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0ID4gYnVkZ2V0TXM7XG4gICAgY29uc3QgZ2V0ID0gKHBhdGgpID0+IGFwaVJlcXVlc3QocGF0aCwgeyBmZXRjaEZuOiBkZXBzLmZldGNoRm4gfSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB7IGFnZW50SWQsIHBlcnNvbmE6IG51bGwsIHByaW1pdGl2ZXM6IHt9IH07XG4gICAgLy8gU2VlZCBrZXlzIHVwIGZyb250IHNvIHRoZSBvdXRwdXQga2V5IG9yZGVyIG5ldmVyIGRlcGVuZHMgb24gdGltaW5nLlxuICAgIGZvciAoY29uc3QgdHlwZSBvZiBQUklNSVRJVkVfVFlQRVMpIHJlc3VsdC5wcmltaXRpdmVzW3R5cGVdID0gW107XG5cbiAgICAvLyBQaGFzZSAxOiBwZXJzb25hICsgZXZlcnkgbGlzdCByb3V0ZSwgYWxsIGluIGZsaWdodCBhdCBvbmNlLlxuICAgIC8vIFBlcnNvbmE6IG9uZSBwZXIgYWdlbnQsIHZlcnNpb25zIHVuZGVyIC9kZXZlbG9wZXIvYWdlbnRzLzphZ2VudElkL3BlcnNvbmEvdmVyc2lvbnMuXG4gICAgY29uc3QgW3BlcnNvbmFPdXRjb21lLCAuLi5saXN0T3V0Y29tZXNdID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAgIGdldChgL2RldmVsb3Blci9hZ2VudHMvJHtpZH0vcGVyc29uYS92ZXJzaW9uc2ApLFxuICAgICAgLi4uUFJJTUlUSVZFX1RZUEVTLm1hcCgodHlwZSkgPT4gZ2V0KGAvZGV2ZWxvcGVyLyR7TElTVF9QQVRIU1t0eXBlXX0vJHtpZH1gKSksXG4gICAgXSk7XG5cbiAgICBpZiAocGVyc29uYU91dGNvbWUuc3RhdHVzID09PSAnZnVsZmlsbGVkJykge1xuICAgICAgY29uc3QgcGVyc29uYVJlc3BvbnNlID0gcGVyc29uYU91dGNvbWUudmFsdWU7XG4gICAgICBjb25zdCB2ZXJzaW9ucyA9IGV4dHJhY3RWZXJzaW9ucygncGVyc29uYScsIHBlcnNvbmFSZXNwb25zZSk7XG4gICAgICBjb25zdCBhY3RpdmUgPSB2ZXJzaW9ucy5maW5kKCh2KSA9PiBpc0FjdGl2ZVZlcnNpb24oJ3BlcnNvbmEnLCB2LCBwZXJzb25hUmVzcG9uc2UpKSA/PyBudWxsO1xuICAgICAgcmVzdWx0LnBlcnNvbmEgPSB7XG4gICAgICAgIGFjdGl2ZVZlcnNpb246IGFjdGl2ZT8udmVyc2lvbiA/PyBudWxsLFxuICAgICAgICBhY3RpdmVWZXJzaW9uQ3JlYXRlZEF0OiB2ZXJzaW9uQ3JlYXRlZEF0KGFjdGl2ZSksXG4gICAgICAgIHZlcnNpb25Db3VudDogdmVyc2lvbnMubGVuZ3RoLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0LnBlcnNvbmEgPSB7IGVycm9yOiBwZXJzb25hT3V0Y29tZS5yZWFzb24/Lm1lc3NhZ2UgPz8gU3RyaW5nKHBlcnNvbmFPdXRjb21lLnJlYXNvbikgfTtcbiAgICB9XG5cbiAgICAvLyBQaGFzZSAyOiBwZXIgdHlwZSwgcmVzb2x2ZSBlYWNoIGl0ZW0ncyB2ZXJzaW9ucyBpbiBjaHVua3MuIFR5cGVzIGFyZVxuICAgIC8vIHZpc2l0ZWQgc2VxdWVudGlhbGx5IChjYW5vbmljYWwgb3JkZXIpOyB3aXRoaW4gYSB0eXBlIHVwIHRvXG4gICAgLy8gVkVSU0lPTlNfQ0hVTktfU0laRSBsb29rdXBzIGFyZSBpbiBmbGlnaHQgdG9nZXRoZXIuXG4gICAgbGV0IGJ1ZGdldEV4aGF1c3RlZCA9IGZhbHNlO1xuICAgIGxldCBza2lwcGVkID0gMDtcbiAgICBsZXQgdG90YWwgPSAwO1xuXG4gICAgZm9yIChsZXQgdCA9IDA7IHQgPCBQUklNSVRJVkVfVFlQRVMubGVuZ3RoOyB0KyspIHtcbiAgICAgIGNvbnN0IHR5cGUgPSBQUklNSVRJVkVfVFlQRVNbdF07XG4gICAgICBjb25zdCBwYXRoID0gTElTVF9QQVRIU1t0eXBlXTtcbiAgICAgIGNvbnN0IG91dGNvbWUgPSBsaXN0T3V0Y29tZXNbdF07XG4gICAgICBpZiAob3V0Y29tZS5zdGF0dXMgIT09ICdmdWxmaWxsZWQnKSB7XG4gICAgICAgIHJlc3VsdC5wcmltaXRpdmVzW3R5cGVdID0geyBlcnJvcjogb3V0Y29tZS5yZWFzb24/Lm1lc3NhZ2UgPz8gU3RyaW5nKG91dGNvbWUucmVhc29uKSB9O1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gVGhlIFVSTCBzbG90IGlzIHRoZSBzZXJ2ZXIgaWQgKDpza2lsbElkIC8gOndlYmhvb2tJZCAvIC4uLiksIG5ldmVyXG4gICAgICAvLyB0aGUgbmFtZS4gSXRlbXMgd2l0aG91dCBhbiBpZCBhcmUgZHJvcHBlZCwgYXMgYmVmb3JlLlxuICAgICAgY29uc3QgdGFyZ2V0cyA9IGV4dHJhY3RMaXN0KHR5cGUsIG91dGNvbWUudmFsdWUpXG4gICAgICAgIC5tYXAoKHApID0+ICh7IHAsIHByaW1JZDogcC5pZCA/PyBwLl9pZCwgbmFtZTogcC5uYW1lID8/IHAuaWQgPz8gcC5faWQgfSkpXG4gICAgICAgIC5maWx0ZXIoKHRndCkgPT4gdGd0LnByaW1JZCk7XG4gICAgICB0b3RhbCArPSB0YXJnZXRzLmxlbmd0aDtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXRzLmxlbmd0aDsgaSArPSBWRVJTSU9OU19DSFVOS19TSVpFKSB7XG4gICAgICAgIGNvbnN0IGNodW5rID0gdGFyZ2V0cy5zbGljZShpLCBpICsgVkVSU0lPTlNfQ0hVTktfU0laRSk7XG5cbiAgICAgICAgaWYgKGJ1ZGdldEV4aGF1c3RlZCB8fCBvdmVyQnVkZ2V0KCkpIHtcbiAgICAgICAgICBidWRnZXRFeGhhdXN0ZWQgPSB0cnVlO1xuICAgICAgICAgIHNraXBwZWQgKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICAgIGZvciAoY29uc3QgeyBuYW1lLCBwcmltSWQgfSBvZiBjaHVuaykge1xuICAgICAgICAgICAgcmVzdWx0LnByaW1pdGl2ZXNbdHlwZV0ucHVzaCh7XG4gICAgICAgICAgICAgIG5hbWUsIGlkOiBwcmltSWQsXG4gICAgICAgICAgICAgIGVycm9yOiBgc2tpcHBlZDogd2FsbC1jbG9jayBidWRnZXQgb2YgJHtidWRnZXRNc31tcyBleGhhdXN0ZWQgYmVmb3JlIHRoaXMgdmVyc2lvbiBsb29rdXAgd2FzIGlzc3VlZGAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvdXRjb21lcyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChcbiAgICAgICAgICBjaHVuay5tYXAoKHsgcHJpbUlkIH0pID0+IGdldChgL2RldmVsb3Blci8ke3BhdGh9LyR7aWR9LyR7ZW5jb2RlVVJJQ29tcG9uZW50KHByaW1JZCl9L3ZlcnNpb25zYCkpXG4gICAgICAgICk7XG5cbiAgICAgICAgb3V0Y29tZXMuZm9yRWFjaCgodm8sIGopID0+IHtcbiAgICAgICAgICBjb25zdCB7IHAsIHByaW1JZCwgbmFtZSB9ID0gY2h1bmtbal07XG4gICAgICAgICAgaWYgKHZvLnN0YXR1cyAhPT0gJ2Z1bGZpbGxlZCcpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wcmltaXRpdmVzW3R5cGVdLnB1c2goeyBuYW1lLCBpZDogcHJpbUlkLCBlcnJvcjogdm8ucmVhc29uPy5tZXNzYWdlID8/IFN0cmluZyh2by5yZWFzb24pIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB2ZXJzaW9uc1Jlc3BvbnNlID0gdm8udmFsdWU7XG4gICAgICAgICAgY29uc3QgdmVyc2lvbnMgPSBleHRyYWN0VmVyc2lvbnModHlwZSwgdmVyc2lvbnNSZXNwb25zZSk7XG4gICAgICAgICAgY29uc3QgYWN0aXZlID0gdmVyc2lvbnMuZmluZCgodikgPT4gaXNBY3RpdmVWZXJzaW9uKHR5cGUsIHYsIHZlcnNpb25zUmVzcG9uc2UpKSA/PyBudWxsO1xuXG4gICAgICAgICAgY29uc3QgZW50cnkgPSB7XG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgaWQ6IHByaW1JZCxcbiAgICAgICAgICAgIGFjdGl2ZVZlcnNpb246IGFjdGl2ZT8udmVyc2lvbiA/PyBudWxsLFxuICAgICAgICAgICAgYWN0aXZlVmVyc2lvbklkOiB2ZXJzaW9uSWQoYWN0aXZlKSA/PyBleHRyYWN0QWN0aXZlVmVyc2lvbklkKHZlcnNpb25zUmVzcG9uc2UpLFxuICAgICAgICAgICAgYWN0aXZlVmVyc2lvbkNyZWF0ZWRBdDogdmVyc2lvbkNyZWF0ZWRBdChhY3RpdmUpLFxuICAgICAgICAgICAgdmVyc2lvbkNvdW50OiB2ZXJzaW9ucy5sZW5ndGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyBSZWNvcmRzIHRoYXQgY2FycnkgdGhlaXIgb3duIGVuYWJsZWQvZGlzYWJsZWQgc3dpdGNoLlxuICAgICAgICAgIGlmICh0eXBlb2YgcC5hY3RpdmUgPT09ICdib29sZWFuJykgZW50cnkuZW5hYmxlZCA9IHAuYWN0aXZlO1xuICAgICAgICAgIGlmICh0eXBlID09PSAnd29ya2Zsb3cnICYmIHR5cGVvZiBwLmR5bmFtaWMgPT09ICdib29sZWFuJykgZW50cnkuZHluYW1pYyA9IHAuZHluYW1pYztcbiAgICAgICAgICByZXN1bHQucHJpbWl0aXZlc1t0eXBlXS5wdXNoKGVudHJ5KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNraXBwZWQgPiAwKSB7XG4gICAgICByZXN1bHQucGFydGlhbCA9IHRydWU7XG4gICAgICByZXN1bHQucGFydGlhbFJlYXNvbiA9XG4gICAgICAgIGBXYWxsLWNsb2NrIGJ1ZGdldCBvZiAke2J1ZGdldE1zfW1zIGV4Y2VlZGVkIGFmdGVyICR7RGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdH1tczsgYCArXG4gICAgICAgIGAke3NraXBwZWR9IG9mICR7dG90YWx9IHZlcnNpb24gbG9va3VwcyB3ZXJlIG5vdCBpc3N1ZWQgKGVudHJpZXMgY2FycnkgZXJyb3I6IFwic2tpcHBlZDogXHUyMDI2XCIpLmA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogSlNPTi5zdHJpbmdpZnkocmVzdWx0LCBudWxsLCAyKSB9XSxcbiAgICB9O1xuICB9LFxufTtcbiIsICJpbXBvcnQgeyBhcGlSZXF1ZXN0IH0gZnJvbSAnLi4vYXBpLWNsaWVudC5tanMnO1xuXG4vLyBUaGUgYGxvZ1NvdXJjZWAgZW51bSBsdWEtYXBpIGFjY2VwdHMgXHUyMDE0IEFHRU5UX0xPR19TT1VSQ0VTIGluXG4vLyBwYWNrYWdlcy9zaGFyZWQtdHlwZXMvc3JjL3ZtLWV4ZWN1dGlvbi1sb2cudHlwZXMudHMgKHRoZSBzaW5nbGUgc291cmNlIG9mXG4vLyB0cnV0aCBldmVyeSBzZXJ2aWNlIGltcG9ydHMpLiBgYWxsYCBpcyB0aGUgTUNQLXNpZGUgc2VudGluZWwgZm9yIFwibm9cbi8vIGZpbHRlclwiLiBOb3RlOiBgbHVhIGxvZ3MgLS10eXBlYCBhY2NlcHRzIGEgbmFycm93ZXIgbGlzdCBhbmQgbm8gYG1hc3RyYWAuXG5leHBvcnQgY29uc3QgTE9HX1NPVVJDRVMgPSBbXG4gICdza2lsbCcsICdqb2InLCAnd2ViaG9vaycsICd0cmlnZ2VyJywgJ3ByZXByb2Nlc3NvcicsICdwb3N0cHJvY2Vzc29yJyxcbiAgJ3VzZXJfbWVzc2FnZScsICdhZ2VudF9yZXNwb25zZScsICdhZ2VudF9lcnJvcicsICdydW50aW1lJywgJ21jcCcsICdyYWcnLFxuICAnZGV2aWNlJywgJ2RldmljZS10cmlnZ2VyJywgJ21vZGVsLXJlc29sdmVyJyxcbiAgJ3dvcmtmbG93LXN0ZXAnLCAnd29ya2Zsb3ctc2NyaXB0JywgJ3dvcmtmbG93Jyxcbl07XG5cbi8vIFRoZSBgbG9nVHlwZWAgcXVlcnkgcGFyYW0gXHUyMDE0IEdFVCAvZGV2ZWxvcGVyL2FnZW50cy86YWdlbnRJZC9sb2dzIHJlYWRzIGl0XG4vLyAoY29udHJvbGxlcnMvZGV2ZWxvcGVyL2Jhc2UuY29udHJvbGxlci50cykgYW5kIGRldmVsb3Blci5zZXJ2aWNlLnRzXG4vLyBnZXRBZ2VudExvZ3MgYXBwbGllcyBpdCB2ZXJiYXRpbSBhcyBgZmlsdGVyLnN1YlR5cGUgPSBsb2dUeXBlYC4gVGhlXG4vLyBhY2NlcHRlZCB2YWx1ZXMgYXJlIHRoZXJlZm9yZSB0aGUgVm1FeGVjdXRpb25Mb2cgYHN1YlR5cGVgIGVudW0gaW5cbi8vIHBhY2thZ2VzL3NoYXJlZC1zY2hlbWFzL3NyYy92bUV4ZWN1dGlvbkxvZ3Muc2NoZW1hLnRzOlxuLy8gICBlbnVtOiBbJ3N0YXJ0JywgJ2NvbXBsZXRlJywgJ2Vycm9yJywgJ2RlYnVnJywgJ3dhcm4nLCAnaW5mbyddXG4vLyAobWlycm9yZWQgYnkgbHVhLWNsaSdzIExvZ0VudHJ5LnN1YlR5cGUgaW4gc3JjL2ludGVyZmFjZXMvbG9ncy50cykuIEFueVxuLy8gb3RoZXIgc3RyaW5nIGlzIG5vdCByZWplY3RlZCBzZXJ2ZXItc2lkZSBcdTIwMTQgaXQgc2ltcGx5IG1hdGNoZXMgbm90aGluZy5cbmV4cG9ydCBjb25zdCBMT0dfVFlQRVMgPSBbJ2Vycm9yJywgJ3dhcm4nLCAnaW5mbycsICdkZWJ1ZycsICdzdGFydCcsICdjb21wbGV0ZSddO1xuXG5jb25zdCBWQUxJRF9UWVBFUyA9IG5ldyBTZXQoWydhbGwnLCAuLi5MT0dfU09VUkNFU10pO1xuY29uc3QgVkFMSURfTE9HX1RZUEVTID0gbmV3IFNldChMT0dfVFlQRVMpO1xuXG5leHBvcnQgY29uc3QgdGFpbExvZ3MgPSB7XG4gIHNwZWM6IHtcbiAgICBuYW1lOiAndGFpbF9sb2dzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0ZldGNoIHJlY2VudCBleGVjdXRpb24gbG9ncyBmb3IgYW4gYWdlbnQgKHNhbWUgZGF0YSBhcyBgbHVhIGxvZ3MgLS1qc29uYCkuIFJldHVybnMgeyBsb2dzOiBMb2dFbnRyeVtdLCBwYWdpbmF0aW9uIH0uIEVhY2ggTG9nRW50cnkgaGFzIGBzdWJUeXBlYCAoZXJyb3IgfCB3YXJuIHwgaW5mbyB8IGRlYnVnIHwgc3RhcnQgfCBjb21wbGV0ZSksIGBtZXNzYWdlYCwgYHRpbWVzdGFtcGAsIGFuZCBgbWV0YWRhdGEubG9nU291cmNlYCAvIGBtZXRhZGF0YS5wcmltaXRpdmVOYW1lYCBcdTIwMTQgdGhlcmUgaXMgTk8gYGxldmVsYCBmaWVsZC4gRmlsdGVyIGJ5IHNvdXJjZSAoYHR5cGVgKSwgcHJpbWl0aXZlIChgbmFtZWApIGFuZC9vciBzZXZlcml0eSAoYGxvZ1R5cGVgLCB3aGljaCBmaWx0ZXJzIG9uIGBzdWJUeXBlYCkuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGFnZW50SWQ6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICAgdHlwZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGVudW06IFsuLi5WQUxJRF9UWVBFU10sXG4gICAgICAgICAgZGVmYXVsdDogJ2FsbCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdMb2cgc291cmNlIGZpbHRlciAobWFwcyB0byBsdWEtYXBpIGBsb2dTb3VyY2VgKS4gYGFsbGAgPSBubyBmaWx0ZXIuJyxcbiAgICAgICAgfSxcbiAgICAgICAgbmFtZTogeyB0eXBlOiAnc3RyaW5nJywgZGVzY3JpcHRpb246ICdGaWx0ZXIgYnkgcHJpbWl0aXZlIG5hbWUgKG9wdGlvbmFsOyBtYXBzIHRvIGBwcmltaXRpdmVOYW1lYCknIH0sXG4gICAgICAgIGxvZ1R5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBlbnVtOiBMT0dfVFlQRVMsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdGaWx0ZXIgYnkgTG9nRW50cnkgYHN1YlR5cGVgIChvcHRpb25hbDsgbWFwcyB0byBsdWEtYXBpIGBsb2dUeXBlYCkuIE9taXQgZm9yIGV2ZXJ5IHNldmVyaXR5LiBlLmcuIGBlcnJvcmAgdG8gc2VlIG9ubHkgZmFpbHVyZXMuJyxcbiAgICAgICAgfSxcbiAgICAgICAgLy8gbHVhLWFwaSBjYXBzIGxpbWl0IGF0IDEwMCBzZXJ2ZXItc2lkZSAoTWF0aC5taW4oMTAwLCAuLi4pIGluXG4gICAgICAgIC8vIGNvbnRyb2xsZXJzL2RldmVsb3Blci9iYXNlLmNvbnRyb2xsZXIudHMpLiBNYXRjaCB0aGUgc2VydmVyIGNhcCBzb1xuICAgICAgICAvLyB0aGUgdG9vbCdzIGNvbnRyYWN0IGlzIGhvbmVzdC5cbiAgICAgICAgbGltaXQ6IHsgdHlwZTogJ251bWJlcicsIGRlZmF1bHQ6IDUwLCBtaW5pbXVtOiAxLCBtYXhpbXVtOiAxMDAgfSxcbiAgICAgICAgcGFnZTogeyB0eXBlOiAnbnVtYmVyJywgbWluaW11bTogMSwgZGVzY3JpcHRpb246ICdQYWdlIG51bWJlciBmb3IgcGFnaW5hdGlvbiAob3B0aW9uYWwpJyB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2FnZW50SWQnXSxcbiAgICB9LFxuICB9LFxuICBhc3luYyBoYW5kbGVyKHsgYWdlbnRJZCwgdHlwZSA9ICdhbGwnLCBuYW1lLCBsb2dUeXBlLCBsaW1pdCA9IDUwLCBwYWdlIH0sIGRlcHMgPSB7fSkge1xuICAgIGlmICghYWdlbnRJZCkgdGhyb3cgbmV3IEVycm9yKCdhZ2VudElkIGlzIHJlcXVpcmVkJyk7XG4gICAgaWYgKCFWQUxJRF9UWVBFUy5oYXModHlwZSkpIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0eXBlOiAke3R5cGV9LiBWYWxpZDogJHtbLi4uVkFMSURfVFlQRVNdLmpvaW4oJywgJyl9YCk7XG4gICAgaWYgKGxvZ1R5cGUgIT09IHVuZGVmaW5lZCAmJiAhVkFMSURfTE9HX1RZUEVTLmhhcyhsb2dUeXBlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGxvZ1R5cGU6ICR7bG9nVHlwZX0uIFZhbGlkOiAke0xPR19UWVBFUy5qb2luKCcsICcpfWApO1xuICAgIH1cbiAgICAvLyBEZWZlbnNpdmUgY2FwIG1hdGNoaW5nIHRoZSBzZXJ2ZXItc2lkZSBsaW1pdDsgcmVqZWN0cyBsb3VkIHJhdGhlclxuICAgIC8vIHRoYW4gc2lsZW50bHkgdHJ1bmNhdGluZy5cbiAgICBpZiAobGltaXQgPiAxMDApIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBsaW1pdDogJHtsaW1pdH0uIGx1YS1hcGkgY2FwcyBsb2dzIGF0IDEwMCBlbnRyaWVzIHBlciBjYWxsLmApO1xuICAgIC8vIFJvdXRlOiBHRVQgL2RldmVsb3Blci9hZ2VudHMvOmFnZW50SWQvbG9ncyAoY29udHJvbGxlcnMvZGV2ZWxvcGVyL2Jhc2UuY29udHJvbGxlci50cykuXG4gICAgLy8gUXVlcnkgcGFyYW1zIHRoZSBzZXJ2ZXIgcmVhZHM6IHBhZ2UsIGxpbWl0LCBzb3J0QnksIHNvcnRPcmRlciwgbG9nU291cmNlLFxuICAgIC8vIHByaW1pdGl2ZUlkLCBwcmltaXRpdmVOYW1lLCB0b29sSWQsIHRvb2xOYW1lLCBsb2dUeXBlLCB1c2VySWQuIFRoZVxuICAgIC8vIHR5cGUgZmlsdGVyIGlzIGBsb2dTb3VyY2VgIFx1MjAxNCBhIGBwcmltaXRpdmVUeXBlYCBwYXJhbSBpcyBzaWxlbnRseSBpZ25vcmVkLlxuICAgIGNvbnN0IHF1ZXJ5ID0geyBsaW1pdCB9O1xuICAgIGlmICh0eXBlICE9PSAnYWxsJykgcXVlcnkubG9nU291cmNlID0gdHlwZTtcbiAgICBpZiAobmFtZSkgcXVlcnkucHJpbWl0aXZlTmFtZSA9IG5hbWU7XG4gICAgaWYgKGxvZ1R5cGUpIHF1ZXJ5LmxvZ1R5cGUgPSBsb2dUeXBlO1xuICAgIGlmIChwYWdlKSBxdWVyeS5wYWdlID0gcGFnZTtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgYXBpUmVxdWVzdChcbiAgICAgIGAvZGV2ZWxvcGVyL2FnZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChhZ2VudElkKX0vbG9nc2AsXG4gICAgICB7IHF1ZXJ5LCBmZXRjaEZuOiBkZXBzLmZldGNoRm4gfVxuICAgICk7XG4gICAgcmV0dXJuIHsgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBKU09OLnN0cmluZ2lmeShkYXRhLCBudWxsLCAyKSB9XSB9O1xuICB9LFxufTtcbiJdLAogICJtYXBwaW5ncyI6ICI2RkFFQSxPQUFTLFVBQUFBLE9BQWMsNENBQ3ZCLE9BQVMsd0JBQUFDLE9BQTRCLDRDQUNy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Q0FBTyxFQUFJO0FBQUEsRUFBTSxJQUFNLFFBQVEsS0FBSyxDQUFDLENBQUMsQ0FDNUUsQ0FFQSxRQUFRLEdBQUcsb0JBQXNCRixHQUFRLENBQ3ZDQyxHQUFtQixDQUNqQixNQUFPLG1CQUNQLEtBQU0sb0JBQ04sUUFBU0QsR0FBSyxRQUNkLE1BQU9BLEdBQUssTUFDWixlQUFnQixRQUNoQixnQkFBaUIsUUFBUSxJQUFJLGlCQUFtQixLQUNoRCxTQUFVLFFBQVEsU0FDbEIsR0FBSSxJQUFJLEtBQUssRUFBRSxZQUFZLENBQzdCLENBQUMsQ0FDSCxDQUFDLEVBRUQsUUFBUSxHQUFHLHFCQUF1QkcsR0FBVyxDQUMzQ0YsR0FBbUIsQ0FDakIsTUFBTyxtQkFDUCxLQUFNLHFCQUNOLE9BQVEsT0FBT0UsQ0FBTSxFQUNyQixNQUEyQkEsR0FBUyxNQUNwQyxlQUFnQixRQUNoQixnQkFBaUIsUUFBUSxJQUFJLGlCQUFtQixLQUNoRCxTQUFVLFFBQVEsU0FDbEIsR0FBSSxJQUFJLEtBQUssRUFBRSxZQUFZLENBQzdCLENBQUMsQ0FDSCxDQUFDLEVBRUQsTUFBTVYsRUFBTyxRQUFRLElBQUlXLEVBQXNCIiwKICAibmFtZXMiOiBbIlNlcnZlciIsICJTdGRpb1NlcnZlclRyYW5zcG9ydCIsICJDYWxsVG9vbFJlcXVlc3RTY2hlbWEiLCAiTGlzdFRvb2xzUmVxdWVzdFNjaGVtYSIsICJ0b29sc19leHBvcnRzIiwgIl9fZXhwb3J0IiwgImdldEFnZW50IiwgImdldERlcGxveW1lbnRTdGF0dXMiLCAibGlzdEFnZW50cyIsICJsaXN0UHJpbWl0aXZlVmVyc2lvbnMiLCAidGFpbExvZ3MiLCAic3Bhd24iLCAiREVGQVVMVF9USU1FT1VUX01TIiwgInJ1bkx1YSIsICJhcmdzIiwgInNwYXduRm4iLCAidGltZW91dE1zIiwgImxhYmVsIiwgInJlc29sdmUiLCAicmVqZWN0IiwgImNoaWxkIiwgInN0ZG91dCIsICJzdGRlcnIiLCAiZCIsICJ0aW1lciIsICJjb2RlIiwgImVyciIsICJmbGF0dGVuQWdlbnRzIiwgInBhcnNlZCIsICJvYmoiLCAiZW50cmllcyIsICJvcmciLCAiYSIsICJsaXN0QWdlbnRzVmlhQ2xpIiwgImxpc3RBZ2VudHMiLCAiX2FyZ3MiLCAiZGVwcyIsICJjb21wYWN0IiwgImxpc3RBZ2VudHNWaWFDbGkiLCAiZ2V0QWdlbnQiLCAiYWdlbnRJZCIsICJkZXBzIiwgIm1hdGNoIiwgImxpc3RBZ2VudHNWaWFDbGkiLCAiYSIsICJyZWFkRmlsZSIsICJyZWFkZGlyIiwgInN0YXQiLCAiam9pbiIsICJkaXJuYW1lIiwgImhvbWVkaXIiLCAiREVGQVVMVF9BUElfVVJMIiwgIkZJUkVCQVNFX1JFRlJFU0hfVVJMIiwgIlJFRlJFU0hfVElNRU9VVF9NUyIsICJSRUZSRVNIX1NLRVdfTVMiLCAiUkVKRUNURURfUkVGUkVTSF9SRUFTT05TIiwgInRva2VuQ2FjaGUiLCAicGFyc2VEb3RlbnZBcGlLZXkiLCAiY29udGVudCIsICJyYXdMaW5lIiwgIm0iLCAidmFsdWUiLCAicXVvdGVkIiwgImZpbmRTZXNzaW9uRmlsZSIsICJzZXNzaW9uc0RpciIsICJhcGlVcmwiLCAibmFtZXMiLCAicmVhZGRpciIsICJjYW5kaWRhdGVzIiwgIm5hbWUiLCAicGF0aCIsICJqb2luIiwgInNlc3Npb24iLCAicmVhZEZpbGUiLCAibXRpbWVNcyIsICJzdGF0IiwgImEiLCAiYiIsICJyZWZyZXNoU2Vzc2lvbkJlYXJlciIsICJmZXRjaEZuIiwgIm5vdyIsICJjYWNoZWQiLCAidG9rZW5DYWNoZSIsICJSRUZSRVNIX1NLRVdfTVMiLCAiY29udHJvbGxlciIsICJ0aW1lciIsICJSRUZSRVNIX1RJTUVPVVRfTVMiLCAicmVzIiwgIkZJUkVCQVNFX1JFRlJFU0hfVVJMIiwgImVyciIsICJyZWFzb24iLCAibWVzc2FnZSIsICJyZWplY3RlZCIsICJSRUpFQ1RFRF9SRUZSRVNIX1JFQVNPTlMiLCAiciIsICJib2R5IiwgImlkVG9rZW4iLCAiZXhwaXJlc0luIiwgInJlc29sdmVBcGlLZXkiLCAiZW52IiwgImNyZWRlbnRpYWxzUGF0aCIsICJob21lZGlyIiwgImRpcm5hbWUiLCAiY3dkIiwgIkRFRkFVTFRfQVBJX1VSTCIsICJmcm9tRG90ZW52IiwgImZvdW5kIiwgInJhdyIsICJwYXJzZWQiLCAiREVGQVVMVF9CQVNFX1VSTCIsICJERUZBVUxUX1RJTUVPVVRfTVMiLCAiUk9VVEVfU0NPUEVTIiwgIlJPVVRFX1NDT1BFX1NVTU1BUlkiLCAiYXBpUmVxdWVzdCIsICJwYXRoIiwgIm1ldGhvZCIsICJib2R5IiwgInF1ZXJ5IiwgImZldGNoRm4iLCAiYmFzZVVybCIsICJ0aW1lb3V0TXMiLCAiYXBpS2V5IiwgInJlc29sdmVBcGlLZXkiLCAidXJsIiwgImsiLCAidiIsICJjb250cm9sbGVyIiwgInRpbWVyIiwgInJlcyIsICJyYXciLCAiZnJpZW5kbHlNc2ciLCAicGFyc2VkIiwgImNvZGUiLCAiZXJyIiwgIkxJU1RfRVhUUkFDVE9SUyIsICJyIiwgIlZFUlNJT05TX0VYVFJBQ1RPUlMiLCAiTElTVF9QQVRIUyIsICJleHRyYWN0TGlzdCIsICJ0eXBlIiwgInJlc3BvbnNlIiwgImZuIiwgImV4dHJhY3RWZXJzaW9ucyIsICJleHRyYWN0QWN0aXZlVmVyc2lvbklkIiwgImlkIiwgImlzQWN0aXZlVmVyc2lvbiIsICJ2ZXJzaW9uIiwgImFjdGl2ZUlkIiwgIm93bklkIiwgInZlcnNpb25DcmVhdGVkQXQiLCAicmF3IiwgInZlcnNpb25JZCIsICJTVVBQT1JURURfTElTVF9UWVBFUyIsICJTVVBQT1JURURfVkVSU0lPTl9UWVBFUyIsICJWQUxJRF9UWVBFUyIsICJTVVBQT1JURURfVkVSU0lPTl9UWVBFUyIsICJsaXN0UHJpbWl0aXZlVmVyc2lvbnMiLCAiYWdlbnRJZCIsICJ0eXBlIiwgIm5hbWUiLCAiZGVwcyIsICJwYXRoIiwgImlkIiwgInJlc29sdmVOYW1lVG9JZCIsICJMSVNUX1BBVEhTIiwgImRhdGEiLCAiYXBpUmVxdWVzdCIsICJjb21wYWN0IiwgImV4dHJhY3RWZXJzaW9ucyIsICJ2IiwgInZlcnNpb25JZCIsICJpc0FjdGl2ZVZlcnNpb24iLCAidmVyc2lvbkNyZWF0ZWRBdCIsICJyZXN1bHQiLCAiZXh0cmFjdEFjdGl2ZVZlcnNpb25JZCIsICJmZXRjaEZuIiwgImxpc3RQYXRoIiwgImxpc3RSZXNwb25zZSIsICJpdGVtcyIsICJleHRyYWN0TGlzdCIsICJtYXRjaCIsICJwIiwgImF2YWlsYWJsZSIsICJQUklNSVRJVkVfVFlQRVMiLCAiVkVSU0lPTlNfQ0hVTktfU0laRSIsICJERUZBVUxUX0JVREdFVF9NUyIsICJnZXREZXBsb3ltZW50U3RhdHVzIiwgImFnZW50SWQiLCAiZGVwcyIsICJpZCIsICJidWRnZXRNcyIsICJzdGFydGVkQXQiLCAib3ZlckJ1ZGdldCIsICJnZXQiLCAicGF0aCIsICJhcGlSZXF1ZXN0IiwgInJlc3VsdCIsICJ0eXBlIiwgInBlcnNvbmFPdXRjb21lIiwgImxpc3RPdXRjb21lcyIsICJMSVNUX1BBVEhTIiwgInBlcnNvbmFSZXNwb25zZSIsICJ2ZXJzaW9ucyIsICJleHRyYWN0VmVyc2lvbnMiLCAiYWN0aXZlIiwgInYiLCAiaXNBY3RpdmVWZXJzaW9uIiwgInZlcnNpb25DcmVhdGVkQXQiLCAiYnVkZ2V0RXhoYXVzdGVkIiwgInNraXBwZWQiLCAidG90YWwiLCAidCIsICJvdXRjb21lIiwgInRhcmdldHMiLCAiZXh0cmFjdExpc3QiLCAicCIsICJ0Z3QiLCAiaSIsICJjaHVuayIsICJuYW1lIiwgInByaW1JZCIsICJ2byIsICJqIiwgInZlcnNpb25zUmVzcG9uc2UiLCAiZW50cnkiLCAidmVyc2lvbklkIiwgImV4dHJhY3RBY3RpdmVWZXJzaW9uSWQiLCAiTE9HX1NPVVJDRVMiLCAiTE9HX1RZUEVTIiwgIlZBTElEX1RZUEVTIiwgIlZBTElEX0xPR19UWVBFUyIsICJ0YWlsTG9ncyIsICJhZ2VudElkIiwgInR5cGUiLCAibmFtZSIsICJsb2dUeXBlIiwgImxpbWl0IiwgInBhZ2UiLCAiZGVwcyIsICJxdWVyeSIsICJkYXRhIiwgImFwaVJlcXVlc3QiLCAiVE9PTF9SRUdJU1RSWSIsICJ0b29sc19leHBvcnRzIiwgInNlcnZlciIsICJTZXJ2ZXIiLCAiTGlzdFRvb2xzUmVxdWVzdFNjaGVtYSIsICJ0IiwgIkNhbGxUb29sUmVxdWVzdFNjaGVtYSIsICJyZXEiLCAidG9vbCIsICJlcnIiLCAicmVwb3J0Q3Jhc2hBbmRFeGl0IiwgInBheWxvYWQiLCAicmVhc29uIiwgIlN0ZGlvU2VydmVyVHJhbnNwb3J0Il0KfQo= +import { createRequire as __luaCreateRequire } from 'node:module'; const require = __luaCreateRequire(import.meta.url); +var mr=Object.defineProperty;var Nt=(r,e)=>{for(var t in e)mr(r,t,{get:e[t],enumerable:!0})};var i={};Nt(i,{BRAND:()=>Dr,DIRTY:()=>Q,EMPTY_PATH:()=>vr,INVALID:()=>g,NEVER:()=>Ts,OK:()=>E,ParseStatus:()=>R,Schema:()=>v,ZodAny:()=>G,ZodArray:()=>J,ZodBigInt:()=>te,ZodBoolean:()=>re,ZodBranded:()=>Ce,ZodCatch:()=>he,ZodDate:()=>se,ZodDefault:()=>pe,ZodDiscriminatedUnion:()=>Ue,ZodEffects:()=>L,ZodEnum:()=>de,ZodError:()=>I,ZodFirstPartyTypeKind:()=>_,ZodFunction:()=>De,ZodIntersection:()=>oe,ZodIssueCode:()=>u,ZodLazy:()=>ce,ZodLiteral:()=>le,ZodMap:()=>we,ZodNaN:()=>Se,ZodNativeEnum:()=>ue,ZodNever:()=>P,ZodNull:()=>ae,ZodNullable:()=>D,ZodNumber:()=>ee,ZodObject:()=>A,ZodOptional:()=>j,ZodParsedType:()=>h,ZodPipeline:()=>Ie,ZodPromise:()=>X,ZodReadonly:()=>fe,ZodRecord:()=>qe,ZodSchema:()=>v,ZodSet:()=>ke,ZodString:()=>K,ZodSymbol:()=>xe,ZodTransformer:()=>L,ZodTuple:()=>q,ZodType:()=>v,ZodUndefined:()=>ne,ZodUnion:()=>ie,ZodUnknown:()=>B,ZodVoid:()=>be,addIssueToContext:()=>p,any:()=>Kr,array:()=>es,bigint:()=>zr,boolean:()=>Ft,coerce:()=>Ss,custom:()=>qt,date:()=>Br,datetimeRegex:()=>Vt,defaultErrorMap:()=>H,discriminatedUnion:()=>ns,effect:()=>gs,enum:()=>hs,function:()=>ds,getErrorMap:()=>_e,getParsedType:()=>U,instanceof:()=>Fr,intersection:()=>as,isAborted:()=>Me,isAsync:()=>ye,isDirty:()=>Ve,isValid:()=>Y,late:()=>Zr,lazy:()=>us,literal:()=>ps,makeIssue:()=>Ee,map:()=>cs,nan:()=>Hr,nativeEnum:()=>fs,never:()=>Xr,null:()=>Yr,nullable:()=>ys,number:()=>Zt,object:()=>ts,objectUtil:()=>ut,oboolean:()=>ks,onumber:()=>ws,optional:()=>_s,ostring:()=>bs,pipeline:()=>xs,preprocess:()=>vs,promise:()=>ms,quotelessJson:()=>gr,record:()=>os,set:()=>ls,setErrorMap:()=>yr,strictObject:()=>rs,string:()=>Dt,symbol:()=>Jr,transformer:()=>gs,tuple:()=>is,undefined:()=>Wr,union:()=>ss,unknown:()=>Gr,util:()=>b,void:()=>Qr});var b;(function(r){r.assertEqual=n=>{};function e(n){}r.assertIs=e;function t(n){throw new Error}r.assertNever=t,r.arrayToEnum=n=>{let a={};for(let c of n)a[c]=c;return a},r.getValidEnumValues=n=>{let a=r.objectKeys(n).filter(o=>typeof n[n[o]]!="number"),c={};for(let o of a)c[o]=n[o];return r.objectValues(c)},r.objectValues=n=>r.objectKeys(n).map(function(a){return n[a]}),r.objectKeys=typeof Object.keys=="function"?n=>Object.keys(n):n=>{let a=[];for(let c in n)Object.prototype.hasOwnProperty.call(n,c)&&a.push(c);return a},r.find=(n,a)=>{for(let c of n)if(a(c))return c},r.isInteger=typeof Number.isInteger=="function"?n=>Number.isInteger(n):n=>typeof n=="number"&&Number.isFinite(n)&&Math.floor(n)===n;function s(n,a=" | "){return n.map(c=>typeof c=="string"?`'${c}'`:c).join(a)}r.joinValues=s,r.jsonStringifyReplacer=(n,a)=>typeof a=="bigint"?a.toString():a})(b||(b={}));var ut;(function(r){r.mergeShapes=(e,t)=>({...e,...t})})(ut||(ut={}));var h=b.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),U=r=>{switch(typeof r){case"undefined":return h.undefined;case"string":return h.string;case"number":return Number.isNaN(r)?h.nan:h.number;case"boolean":return h.boolean;case"function":return h.function;case"bigint":return h.bigint;case"symbol":return h.symbol;case"object":return Array.isArray(r)?h.array:r===null?h.null:r.then&&typeof r.then=="function"&&r.catch&&typeof r.catch=="function"?h.promise:typeof Map<"u"&&r instanceof Map?h.map:typeof Set<"u"&&r instanceof Set?h.set:typeof Date<"u"&&r instanceof Date?h.date:h.object;default:return h.unknown}};var u=b.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]),gr=r=>JSON.stringify(r,null,2).replace(/"([^"]+)":/g,"$1:"),I=class r extends Error{get errors(){return this.issues}constructor(e){super(),this.issues=[],this.addIssue=s=>{this.issues=[...this.issues,s]},this.addIssues=(s=[])=>{this.issues=[...this.issues,...s]};let t=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,t):this.__proto__=t,this.name="ZodError",this.issues=e}format(e){let t=e||function(a){return a.message},s={_errors:[]},n=a=>{for(let c of a.issues)if(c.code==="invalid_union")c.unionErrors.map(n);else if(c.code==="invalid_return_type")n(c.returnTypeError);else if(c.code==="invalid_arguments")n(c.argumentsError);else if(c.path.length===0)s._errors.push(t(c));else{let o=s,l=0;for(;lt.message){let t={},s=[];for(let n of this.issues)if(n.path.length>0){let a=n.path[0];t[a]=t[a]||[],t[a].push(e(n))}else s.push(e(n));return{formErrors:s,fieldErrors:t}}get formErrors(){return this.flatten()}};I.create=r=>new I(r);var _r=(r,e)=>{let t;switch(r.code){case u.invalid_type:r.received===h.undefined?t="Required":t=`Expected ${r.expected}, received ${r.received}`;break;case u.invalid_literal:t=`Invalid literal value, expected ${JSON.stringify(r.expected,b.jsonStringifyReplacer)}`;break;case u.unrecognized_keys:t=`Unrecognized key(s) in object: ${b.joinValues(r.keys,", ")}`;break;case u.invalid_union:t="Invalid input";break;case u.invalid_union_discriminator:t=`Invalid discriminator value. Expected ${b.joinValues(r.options)}`;break;case u.invalid_enum_value:t=`Invalid enum value. Expected ${b.joinValues(r.options)}, received '${r.received}'`;break;case u.invalid_arguments:t="Invalid function arguments";break;case u.invalid_return_type:t="Invalid function return type";break;case u.invalid_date:t="Invalid date";break;case u.invalid_string:typeof r.validation=="object"?"includes"in r.validation?(t=`Invalid input: must include "${r.validation.includes}"`,typeof r.validation.position=="number"&&(t=`${t} at one or more positions greater than or equal to ${r.validation.position}`)):"startsWith"in r.validation?t=`Invalid input: must start with "${r.validation.startsWith}"`:"endsWith"in r.validation?t=`Invalid input: must end with "${r.validation.endsWith}"`:b.assertNever(r.validation):r.validation!=="regex"?t=`Invalid ${r.validation}`:t="Invalid";break;case u.too_small:r.type==="array"?t=`Array must contain ${r.exact?"exactly":r.inclusive?"at least":"more than"} ${r.minimum} element(s)`:r.type==="string"?t=`String must contain ${r.exact?"exactly":r.inclusive?"at least":"over"} ${r.minimum} character(s)`:r.type==="number"?t=`Number must be ${r.exact?"exactly equal to ":r.inclusive?"greater than or equal to ":"greater than "}${r.minimum}`:r.type==="bigint"?t=`Number must be ${r.exact?"exactly equal to ":r.inclusive?"greater than or equal to ":"greater than "}${r.minimum}`:r.type==="date"?t=`Date must be ${r.exact?"exactly equal to ":r.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(r.minimum))}`:t="Invalid input";break;case u.too_big:r.type==="array"?t=`Array must contain ${r.exact?"exactly":r.inclusive?"at most":"less than"} ${r.maximum} element(s)`:r.type==="string"?t=`String must contain ${r.exact?"exactly":r.inclusive?"at most":"under"} ${r.maximum} character(s)`:r.type==="number"?t=`Number must be ${r.exact?"exactly":r.inclusive?"less than or equal to":"less than"} ${r.maximum}`:r.type==="bigint"?t=`BigInt must be ${r.exact?"exactly":r.inclusive?"less than or equal to":"less than"} ${r.maximum}`:r.type==="date"?t=`Date must be ${r.exact?"exactly":r.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(r.maximum))}`:t="Invalid input";break;case u.custom:t="Invalid input";break;case u.invalid_intersection_types:t="Intersection results could not be merged";break;case u.not_multiple_of:t=`Number must be a multiple of ${r.multipleOf}`;break;case u.not_finite:t="Number must be finite";break;default:t=e.defaultError,b.assertNever(r)}return{message:t}},H=_r;var jt=H;function yr(r){jt=r}function _e(){return jt}var Ee=r=>{let{data:e,path:t,errorMaps:s,issueData:n}=r,a=[...t,...n.path||[]],c={...n,path:a};if(n.message!==void 0)return{...n,path:a,message:n.message};let o="",l=s.filter(d=>!!d).slice().reverse();for(let d of l)o=d(c,{data:e,defaultError:o}).message;return{...n,path:a,message:o}},vr=[];function p(r,e){let t=_e(),s=Ee({issueData:e,data:r.data,path:r.path,errorMaps:[r.common.contextualErrorMap,r.schemaErrorMap,t,t===H?void 0:H].filter(n=>!!n)});r.common.issues.push(s)}var R=class r{constructor(){this.value="valid"}dirty(){this.value==="valid"&&(this.value="dirty")}abort(){this.value!=="aborted"&&(this.value="aborted")}static mergeArray(e,t){let s=[];for(let n of t){if(n.status==="aborted")return g;n.status==="dirty"&&e.dirty(),s.push(n.value)}return{status:e.value,value:s}}static async mergeObjectAsync(e,t){let s=[];for(let n of t){let a=await n.key,c=await n.value;s.push({key:a,value:c})}return r.mergeObjectSync(e,s)}static mergeObjectSync(e,t){let s={};for(let n of t){let{key:a,value:c}=n;if(a.status==="aborted"||c.status==="aborted")return g;a.status==="dirty"&&e.dirty(),c.status==="dirty"&&e.dirty(),a.value!=="__proto__"&&(typeof c.value<"u"||n.alwaysSet)&&(s[a.value]=c.value)}return{status:e.value,value:s}}},g=Object.freeze({status:"aborted"}),Q=r=>({status:"dirty",value:r}),E=r=>({status:"valid",value:r}),Me=r=>r.status==="aborted",Ve=r=>r.status==="dirty",Y=r=>r.status==="valid",ye=r=>typeof Promise<"u"&&r instanceof Promise;var m;(function(r){r.errToObj=e=>typeof e=="string"?{message:e}:e||{},r.toString=e=>typeof e=="string"?e:e?.message})(m||(m={}));var $=class{constructor(e,t,s,n){this._cachedPath=[],this.parent=e,this.data=t,this._path=s,this._key=n}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},$t=(r,e)=>{if(Y(e))return{success:!0,data:e.value};if(!r.common.issues.length)throw new Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;let t=new I(r.common.issues);return this._error=t,this._error}}};function y(r){if(!r)return{};let{errorMap:e,invalid_type_error:t,required_error:s,description:n}=r;if(e&&(t||s))throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);return e?{errorMap:e,description:n}:{errorMap:(c,o)=>{let{message:l}=r;return c.code==="invalid_enum_value"?{message:l??o.defaultError}:typeof o.data>"u"?{message:l??s??o.defaultError}:c.code!=="invalid_type"?{message:o.defaultError}:{message:l??t??o.defaultError}},description:n}}var v=class{get description(){return this._def.description}_getType(e){return U(e.data)}_getOrReturnCtx(e,t){return t||{common:e.parent.common,data:e.data,parsedType:U(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new R,ctx:{common:e.parent.common,data:e.data,parsedType:U(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){let t=this._parse(e);if(ye(t))throw new Error("Synchronous parse encountered promise.");return t}_parseAsync(e){let t=this._parse(e);return Promise.resolve(t)}parse(e,t){let s=this.safeParse(e,t);if(s.success)return s.data;throw s.error}safeParse(e,t){let s={common:{issues:[],async:t?.async??!1,contextualErrorMap:t?.errorMap},path:t?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:U(e)},n=this._parseSync({data:e,path:s.path,parent:s});return $t(s,n)}"~validate"(e){let t={common:{issues:[],async:!!this["~standard"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:U(e)};if(!this["~standard"].async)try{let s=this._parseSync({data:e,path:[],parent:t});return Y(s)?{value:s.value}:{issues:t.common.issues}}catch(s){s?.message?.toLowerCase()?.includes("encountered")&&(this["~standard"].async=!0),t.common={issues:[],async:!0}}return this._parseAsync({data:e,path:[],parent:t}).then(s=>Y(s)?{value:s.value}:{issues:t.common.issues})}async parseAsync(e,t){let s=await this.safeParseAsync(e,t);if(s.success)return s.data;throw s.error}async safeParseAsync(e,t){let s={common:{issues:[],contextualErrorMap:t?.errorMap,async:!0},path:t?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:U(e)},n=this._parse({data:e,path:s.path,parent:s}),a=await(ye(n)?n:Promise.resolve(n));return $t(s,a)}refine(e,t){let s=n=>typeof t=="string"||typeof t>"u"?{message:t}:typeof t=="function"?t(n):t;return this._refinement((n,a)=>{let c=e(n),o=()=>a.addIssue({code:u.custom,...s(n)});return typeof Promise<"u"&&c instanceof Promise?c.then(l=>l?!0:(o(),!1)):c?!0:(o(),!1)})}refinement(e,t){return this._refinement((s,n)=>e(s)?!0:(n.addIssue(typeof t=="function"?t(s,n):t),!1))}_refinement(e){return new L({schema:this,typeName:_.ZodEffects,effect:{type:"refinement",refinement:e}})}superRefine(e){return this._refinement(e)}constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this["~standard"]={version:1,vendor:"zod",validate:t=>this["~validate"](t)}}optional(){return j.create(this,this._def)}nullable(){return D.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return J.create(this)}promise(){return X.create(this,this._def)}or(e){return ie.create([this,e],this._def)}and(e){return oe.create(this,e,this._def)}transform(e){return new L({...y(this._def),schema:this,typeName:_.ZodEffects,effect:{type:"transform",transform:e}})}default(e){let t=typeof e=="function"?e:()=>e;return new pe({...y(this._def),innerType:this,defaultValue:t,typeName:_.ZodDefault})}brand(){return new Ce({typeName:_.ZodBranded,type:this,...y(this._def)})}catch(e){let t=typeof e=="function"?e:()=>e;return new he({...y(this._def),innerType:this,catchValue:t,typeName:_.ZodCatch})}describe(e){let t=this.constructor;return new t({...this._def,description:e})}pipe(e){return Ie.create(this,e)}readonly(){return fe.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},xr=/^c[^\s-]{8,}$/i,br=/^[0-9a-z]+$/,wr=/^[0-9A-HJKMNP-TV-Z]{26}$/i,kr=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,Sr=/^[a-z0-9_-]{21}$/i,Tr=/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/,Rr=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,Er=/^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,Cr="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$",pt,Ir=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,Ar=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,Or=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,Nr=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,jr=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,$r=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Pt="((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))",Lr=new RegExp(`^${Pt}$`);function Mt(r){let e="[0-5]\\d";r.precision?e=`${e}\\.\\d{${r.precision}}`:r.precision==null&&(e=`${e}(\\.\\d+)?`);let t=r.precision?"+":"?";return`([01]\\d|2[0-3]):[0-5]\\d(:${e})${t}`}function Pr(r){return new RegExp(`^${Mt(r)}$`)}function Vt(r){let e=`${Pt}T${Mt(r)}`,t=[];return t.push(r.local?"Z?":"Z"),r.offset&&t.push("([+-]\\d{2}:?\\d{2})"),e=`${e}(${t.join("|")})`,new RegExp(`^${e}$`)}function Mr(r,e){return!!((e==="v4"||!e)&&Ir.test(r)||(e==="v6"||!e)&&Or.test(r))}function Vr(r,e){if(!Tr.test(r))return!1;try{let[t]=r.split(".");if(!t)return!1;let s=t.replace(/-/g,"+").replace(/_/g,"/").padEnd(t.length+(4-t.length%4)%4,"="),n=JSON.parse(atob(s));return!(typeof n!="object"||n===null||"typ"in n&&n?.typ!=="JWT"||!n.alg||e&&n.alg!==e)}catch{return!1}}function Ur(r,e){return!!((e==="v4"||!e)&&Ar.test(r)||(e==="v6"||!e)&&Nr.test(r))}var K=class r extends v{_parse(e){if(this._def.coerce&&(e.data=String(e.data)),this._getType(e)!==h.string){let a=this._getOrReturnCtx(e);return p(a,{code:u.invalid_type,expected:h.string,received:a.parsedType}),g}let s=new R,n;for(let a of this._def.checks)if(a.kind==="min")e.data.lengtha.value&&(n=this._getOrReturnCtx(e,n),p(n,{code:u.too_big,maximum:a.value,type:"string",inclusive:!0,exact:!1,message:a.message}),s.dirty());else if(a.kind==="length"){let c=e.data.length>a.value,o=e.data.lengthe.test(n),{validation:t,code:u.invalid_string,...m.errToObj(s)})}_addCheck(e){return new r({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:"email",...m.errToObj(e)})}url(e){return this._addCheck({kind:"url",...m.errToObj(e)})}emoji(e){return this._addCheck({kind:"emoji",...m.errToObj(e)})}uuid(e){return this._addCheck({kind:"uuid",...m.errToObj(e)})}nanoid(e){return this._addCheck({kind:"nanoid",...m.errToObj(e)})}cuid(e){return this._addCheck({kind:"cuid",...m.errToObj(e)})}cuid2(e){return this._addCheck({kind:"cuid2",...m.errToObj(e)})}ulid(e){return this._addCheck({kind:"ulid",...m.errToObj(e)})}base64(e){return this._addCheck({kind:"base64",...m.errToObj(e)})}base64url(e){return this._addCheck({kind:"base64url",...m.errToObj(e)})}jwt(e){return this._addCheck({kind:"jwt",...m.errToObj(e)})}ip(e){return this._addCheck({kind:"ip",...m.errToObj(e)})}cidr(e){return this._addCheck({kind:"cidr",...m.errToObj(e)})}datetime(e){return typeof e=="string"?this._addCheck({kind:"datetime",precision:null,offset:!1,local:!1,message:e}):this._addCheck({kind:"datetime",precision:typeof e?.precision>"u"?null:e?.precision,offset:e?.offset??!1,local:e?.local??!1,...m.errToObj(e?.message)})}date(e){return this._addCheck({kind:"date",message:e})}time(e){return typeof e=="string"?this._addCheck({kind:"time",precision:null,message:e}):this._addCheck({kind:"time",precision:typeof e?.precision>"u"?null:e?.precision,...m.errToObj(e?.message)})}duration(e){return this._addCheck({kind:"duration",...m.errToObj(e)})}regex(e,t){return this._addCheck({kind:"regex",regex:e,...m.errToObj(t)})}includes(e,t){return this._addCheck({kind:"includes",value:e,position:t?.position,...m.errToObj(t?.message)})}startsWith(e,t){return this._addCheck({kind:"startsWith",value:e,...m.errToObj(t)})}endsWith(e,t){return this._addCheck({kind:"endsWith",value:e,...m.errToObj(t)})}min(e,t){return this._addCheck({kind:"min",value:e,...m.errToObj(t)})}max(e,t){return this._addCheck({kind:"max",value:e,...m.errToObj(t)})}length(e,t){return this._addCheck({kind:"length",value:e,...m.errToObj(t)})}nonempty(e){return this.min(1,m.errToObj(e))}trim(){return new r({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new r({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new r({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(e=>e.kind==="datetime")}get isDate(){return!!this._def.checks.find(e=>e.kind==="date")}get isTime(){return!!this._def.checks.find(e=>e.kind==="time")}get isDuration(){return!!this._def.checks.find(e=>e.kind==="duration")}get isEmail(){return!!this._def.checks.find(e=>e.kind==="email")}get isURL(){return!!this._def.checks.find(e=>e.kind==="url")}get isEmoji(){return!!this._def.checks.find(e=>e.kind==="emoji")}get isUUID(){return!!this._def.checks.find(e=>e.kind==="uuid")}get isNANOID(){return!!this._def.checks.find(e=>e.kind==="nanoid")}get isCUID(){return!!this._def.checks.find(e=>e.kind==="cuid")}get isCUID2(){return!!this._def.checks.find(e=>e.kind==="cuid2")}get isULID(){return!!this._def.checks.find(e=>e.kind==="ulid")}get isIP(){return!!this._def.checks.find(e=>e.kind==="ip")}get isCIDR(){return!!this._def.checks.find(e=>e.kind==="cidr")}get isBase64(){return!!this._def.checks.find(e=>e.kind==="base64")}get isBase64url(){return!!this._def.checks.find(e=>e.kind==="base64url")}get minLength(){let e=null;for(let t of this._def.checks)t.kind==="min"&&(e===null||t.value>e)&&(e=t.value);return e}get maxLength(){let e=null;for(let t of this._def.checks)t.kind==="max"&&(e===null||t.valuenew K({checks:[],typeName:_.ZodString,coerce:r?.coerce??!1,...y(r)});function qr(r,e){let t=(r.toString().split(".")[1]||"").length,s=(e.toString().split(".")[1]||"").length,n=t>s?t:s,a=Number.parseInt(r.toFixed(n).replace(".","")),c=Number.parseInt(e.toFixed(n).replace(".",""));return a%c/10**n}var ee=class r extends v{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(e){if(this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==h.number){let a=this._getOrReturnCtx(e);return p(a,{code:u.invalid_type,expected:h.number,received:a.parsedType}),g}let s,n=new R;for(let a of this._def.checks)a.kind==="int"?b.isInteger(e.data)||(s=this._getOrReturnCtx(e,s),p(s,{code:u.invalid_type,expected:"integer",received:"float",message:a.message}),n.dirty()):a.kind==="min"?(a.inclusive?e.dataa.value:e.data>=a.value)&&(s=this._getOrReturnCtx(e,s),p(s,{code:u.too_big,maximum:a.value,type:"number",inclusive:a.inclusive,exact:!1,message:a.message}),n.dirty()):a.kind==="multipleOf"?qr(e.data,a.value)!==0&&(s=this._getOrReturnCtx(e,s),p(s,{code:u.not_multiple_of,multipleOf:a.value,message:a.message}),n.dirty()):a.kind==="finite"?Number.isFinite(e.data)||(s=this._getOrReturnCtx(e,s),p(s,{code:u.not_finite,message:a.message}),n.dirty()):b.assertNever(a);return{status:n.value,value:e.data}}gte(e,t){return this.setLimit("min",e,!0,m.toString(t))}gt(e,t){return this.setLimit("min",e,!1,m.toString(t))}lte(e,t){return this.setLimit("max",e,!0,m.toString(t))}lt(e,t){return this.setLimit("max",e,!1,m.toString(t))}setLimit(e,t,s,n){return new r({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:s,message:m.toString(n)}]})}_addCheck(e){return new r({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:"int",message:m.toString(e)})}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:m.toString(e)})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:m.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:m.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:m.toString(e)})}multipleOf(e,t){return this._addCheck({kind:"multipleOf",value:e,message:m.toString(t)})}finite(e){return this._addCheck({kind:"finite",message:m.toString(e)})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:m.toString(e)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:m.toString(e)})}get minValue(){let e=null;for(let t of this._def.checks)t.kind==="min"&&(e===null||t.value>e)&&(e=t.value);return e}get maxValue(){let e=null;for(let t of this._def.checks)t.kind==="max"&&(e===null||t.valuee.kind==="int"||e.kind==="multipleOf"&&b.isInteger(e.value))}get isFinite(){let e=null,t=null;for(let s of this._def.checks){if(s.kind==="finite"||s.kind==="int"||s.kind==="multipleOf")return!0;s.kind==="min"?(t===null||s.value>t)&&(t=s.value):s.kind==="max"&&(e===null||s.valuenew ee({checks:[],typeName:_.ZodNumber,coerce:r?.coerce||!1,...y(r)});var te=class r extends v{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(e){if(this._def.coerce)try{e.data=BigInt(e.data)}catch{return this._getInvalidInput(e)}if(this._getType(e)!==h.bigint)return this._getInvalidInput(e);let s,n=new R;for(let a of this._def.checks)a.kind==="min"?(a.inclusive?e.dataa.value:e.data>=a.value)&&(s=this._getOrReturnCtx(e,s),p(s,{code:u.too_big,type:"bigint",maximum:a.value,inclusive:a.inclusive,message:a.message}),n.dirty()):a.kind==="multipleOf"?e.data%a.value!==BigInt(0)&&(s=this._getOrReturnCtx(e,s),p(s,{code:u.not_multiple_of,multipleOf:a.value,message:a.message}),n.dirty()):b.assertNever(a);return{status:n.value,value:e.data}}_getInvalidInput(e){let t=this._getOrReturnCtx(e);return p(t,{code:u.invalid_type,expected:h.bigint,received:t.parsedType}),g}gte(e,t){return this.setLimit("min",e,!0,m.toString(t))}gt(e,t){return this.setLimit("min",e,!1,m.toString(t))}lte(e,t){return this.setLimit("max",e,!0,m.toString(t))}lt(e,t){return this.setLimit("max",e,!1,m.toString(t))}setLimit(e,t,s,n){return new r({...this._def,checks:[...this._def.checks,{kind:e,value:t,inclusive:s,message:m.toString(n)}]})}_addCheck(e){return new r({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:m.toString(e)})}negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:m.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:m.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:m.toString(e)})}multipleOf(e,t){return this._addCheck({kind:"multipleOf",value:e,message:m.toString(t)})}get minValue(){let e=null;for(let t of this._def.checks)t.kind==="min"&&(e===null||t.value>e)&&(e=t.value);return e}get maxValue(){let e=null;for(let t of this._def.checks)t.kind==="max"&&(e===null||t.valuenew te({checks:[],typeName:_.ZodBigInt,coerce:r?.coerce??!1,...y(r)});var re=class extends v{_parse(e){if(this._def.coerce&&(e.data=!!e.data),this._getType(e)!==h.boolean){let s=this._getOrReturnCtx(e);return p(s,{code:u.invalid_type,expected:h.boolean,received:s.parsedType}),g}return E(e.data)}};re.create=r=>new re({typeName:_.ZodBoolean,coerce:r?.coerce||!1,...y(r)});var se=class r extends v{_parse(e){if(this._def.coerce&&(e.data=new Date(e.data)),this._getType(e)!==h.date){let a=this._getOrReturnCtx(e);return p(a,{code:u.invalid_type,expected:h.date,received:a.parsedType}),g}if(Number.isNaN(e.data.getTime())){let a=this._getOrReturnCtx(e);return p(a,{code:u.invalid_date}),g}let s=new R,n;for(let a of this._def.checks)a.kind==="min"?e.data.getTime()a.value&&(n=this._getOrReturnCtx(e,n),p(n,{code:u.too_big,message:a.message,inclusive:!0,exact:!1,maximum:a.value,type:"date"}),s.dirty()):b.assertNever(a);return{status:s.value,value:new Date(e.data.getTime())}}_addCheck(e){return new r({...this._def,checks:[...this._def.checks,e]})}min(e,t){return this._addCheck({kind:"min",value:e.getTime(),message:m.toString(t)})}max(e,t){return this._addCheck({kind:"max",value:e.getTime(),message:m.toString(t)})}get minDate(){let e=null;for(let t of this._def.checks)t.kind==="min"&&(e===null||t.value>e)&&(e=t.value);return e!=null?new Date(e):null}get maxDate(){let e=null;for(let t of this._def.checks)t.kind==="max"&&(e===null||t.valuenew se({checks:[],coerce:r?.coerce||!1,typeName:_.ZodDate,...y(r)});var xe=class extends v{_parse(e){if(this._getType(e)!==h.symbol){let s=this._getOrReturnCtx(e);return p(s,{code:u.invalid_type,expected:h.symbol,received:s.parsedType}),g}return E(e.data)}};xe.create=r=>new xe({typeName:_.ZodSymbol,...y(r)});var ne=class extends v{_parse(e){if(this._getType(e)!==h.undefined){let s=this._getOrReturnCtx(e);return p(s,{code:u.invalid_type,expected:h.undefined,received:s.parsedType}),g}return E(e.data)}};ne.create=r=>new ne({typeName:_.ZodUndefined,...y(r)});var ae=class extends v{_parse(e){if(this._getType(e)!==h.null){let s=this._getOrReturnCtx(e);return p(s,{code:u.invalid_type,expected:h.null,received:s.parsedType}),g}return E(e.data)}};ae.create=r=>new ae({typeName:_.ZodNull,...y(r)});var G=class extends v{constructor(){super(...arguments),this._any=!0}_parse(e){return E(e.data)}};G.create=r=>new G({typeName:_.ZodAny,...y(r)});var B=class extends v{constructor(){super(...arguments),this._unknown=!0}_parse(e){return E(e.data)}};B.create=r=>new B({typeName:_.ZodUnknown,...y(r)});var P=class extends v{_parse(e){let t=this._getOrReturnCtx(e);return p(t,{code:u.invalid_type,expected:h.never,received:t.parsedType}),g}};P.create=r=>new P({typeName:_.ZodNever,...y(r)});var be=class extends v{_parse(e){if(this._getType(e)!==h.undefined){let s=this._getOrReturnCtx(e);return p(s,{code:u.invalid_type,expected:h.void,received:s.parsedType}),g}return E(e.data)}};be.create=r=>new be({typeName:_.ZodVoid,...y(r)});var J=class r extends v{_parse(e){let{ctx:t,status:s}=this._processInputParams(e),n=this._def;if(t.parsedType!==h.array)return p(t,{code:u.invalid_type,expected:h.array,received:t.parsedType}),g;if(n.exactLength!==null){let c=t.data.length>n.exactLength.value,o=t.data.lengthn.maxLength.value&&(p(t,{code:u.too_big,maximum:n.maxLength.value,type:"array",inclusive:!0,exact:!1,message:n.maxLength.message}),s.dirty()),t.common.async)return Promise.all([...t.data].map((c,o)=>n.type._parseAsync(new $(t,c,t.path,o)))).then(c=>R.mergeArray(s,c));let a=[...t.data].map((c,o)=>n.type._parseSync(new $(t,c,t.path,o)));return R.mergeArray(s,a)}get element(){return this._def.type}min(e,t){return new r({...this._def,minLength:{value:e,message:m.toString(t)}})}max(e,t){return new r({...this._def,maxLength:{value:e,message:m.toString(t)}})}length(e,t){return new r({...this._def,exactLength:{value:e,message:m.toString(t)}})}nonempty(e){return this.min(1,e)}};J.create=(r,e)=>new J({type:r,minLength:null,maxLength:null,exactLength:null,typeName:_.ZodArray,...y(e)});function ve(r){if(r instanceof A){let e={};for(let t in r.shape){let s=r.shape[t];e[t]=j.create(ve(s))}return new A({...r._def,shape:()=>e})}else return r instanceof J?new J({...r._def,type:ve(r.element)}):r instanceof j?j.create(ve(r.unwrap())):r instanceof D?D.create(ve(r.unwrap())):r instanceof q?q.create(r.items.map(e=>ve(e))):r}var A=class r extends v{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(this._cached!==null)return this._cached;let e=this._def.shape(),t=b.objectKeys(e);return this._cached={shape:e,keys:t},this._cached}_parse(e){if(this._getType(e)!==h.object){let d=this._getOrReturnCtx(e);return p(d,{code:u.invalid_type,expected:h.object,received:d.parsedType}),g}let{status:s,ctx:n}=this._processInputParams(e),{shape:a,keys:c}=this._getCached(),o=[];if(!(this._def.catchall instanceof P&&this._def.unknownKeys==="strip"))for(let d in n.data)c.includes(d)||o.push(d);let l=[];for(let d of c){let f=a[d],x=n.data[d];l.push({key:{status:"valid",value:d},value:f._parse(new $(n,x,n.path,d)),alwaysSet:d in n.data})}if(this._def.catchall instanceof P){let d=this._def.unknownKeys;if(d==="passthrough")for(let f of o)l.push({key:{status:"valid",value:f},value:{status:"valid",value:n.data[f]}});else if(d==="strict")o.length>0&&(p(n,{code:u.unrecognized_keys,keys:o}),s.dirty());else if(d!=="strip")throw new Error("Internal ZodObject error: invalid unknownKeys value.")}else{let d=this._def.catchall;for(let f of o){let x=n.data[f];l.push({key:{status:"valid",value:f},value:d._parse(new $(n,x,n.path,f)),alwaysSet:f in n.data})}}return n.common.async?Promise.resolve().then(async()=>{let d=[];for(let f of l){let x=await f.key,S=await f.value;d.push({key:x,value:S,alwaysSet:f.alwaysSet})}return d}).then(d=>R.mergeObjectSync(s,d)):R.mergeObjectSync(s,l)}get shape(){return this._def.shape()}strict(e){return m.errToObj,new r({...this._def,unknownKeys:"strict",...e!==void 0?{errorMap:(t,s)=>{let n=this._def.errorMap?.(t,s).message??s.defaultError;return t.code==="unrecognized_keys"?{message:m.errToObj(e).message??n}:{message:n}}}:{}})}strip(){return new r({...this._def,unknownKeys:"strip"})}passthrough(){return new r({...this._def,unknownKeys:"passthrough"})}extend(e){return new r({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new r({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:_.ZodObject})}setKey(e,t){return this.augment({[e]:t})}catchall(e){return new r({...this._def,catchall:e})}pick(e){let t={};for(let s of b.objectKeys(e))e[s]&&this.shape[s]&&(t[s]=this.shape[s]);return new r({...this._def,shape:()=>t})}omit(e){let t={};for(let s of b.objectKeys(this.shape))e[s]||(t[s]=this.shape[s]);return new r({...this._def,shape:()=>t})}deepPartial(){return ve(this)}partial(e){let t={};for(let s of b.objectKeys(this.shape)){let n=this.shape[s];e&&!e[s]?t[s]=n:t[s]=n.optional()}return new r({...this._def,shape:()=>t})}required(e){let t={};for(let s of b.objectKeys(this.shape))if(e&&!e[s])t[s]=this.shape[s];else{let a=this.shape[s];for(;a instanceof j;)a=a._def.innerType;t[s]=a}return new r({...this._def,shape:()=>t})}keyof(){return Ut(b.objectKeys(this.shape))}};A.create=(r,e)=>new A({shape:()=>r,unknownKeys:"strip",catchall:P.create(),typeName:_.ZodObject,...y(e)});A.strictCreate=(r,e)=>new A({shape:()=>r,unknownKeys:"strict",catchall:P.create(),typeName:_.ZodObject,...y(e)});A.lazycreate=(r,e)=>new A({shape:r,unknownKeys:"strip",catchall:P.create(),typeName:_.ZodObject,...y(e)});var ie=class extends v{_parse(e){let{ctx:t}=this._processInputParams(e),s=this._def.options;function n(a){for(let o of a)if(o.result.status==="valid")return o.result;for(let o of a)if(o.result.status==="dirty")return t.common.issues.push(...o.ctx.common.issues),o.result;let c=a.map(o=>new I(o.ctx.common.issues));return p(t,{code:u.invalid_union,unionErrors:c}),g}if(t.common.async)return Promise.all(s.map(async a=>{let c={...t,common:{...t.common,issues:[]},parent:null};return{result:await a._parseAsync({data:t.data,path:t.path,parent:c}),ctx:c}})).then(n);{let a,c=[];for(let l of s){let d={...t,common:{...t.common,issues:[]},parent:null},f=l._parseSync({data:t.data,path:t.path,parent:d});if(f.status==="valid")return f;f.status==="dirty"&&!a&&(a={result:f,ctx:d}),d.common.issues.length&&c.push(d.common.issues)}if(a)return t.common.issues.push(...a.ctx.common.issues),a.result;let o=c.map(l=>new I(l));return p(t,{code:u.invalid_union,unionErrors:o}),g}}get options(){return this._def.options}};ie.create=(r,e)=>new ie({options:r,typeName:_.ZodUnion,...y(e)});var z=r=>r instanceof ce?z(r.schema):r instanceof L?z(r.innerType()):r instanceof le?[r.value]:r instanceof de?r.options:r instanceof ue?b.objectValues(r.enum):r instanceof pe?z(r._def.innerType):r instanceof ne?[void 0]:r instanceof ae?[null]:r instanceof j?[void 0,...z(r.unwrap())]:r instanceof D?[null,...z(r.unwrap())]:r instanceof Ce||r instanceof fe?z(r.unwrap()):r instanceof he?z(r._def.innerType):[],Ue=class r extends v{_parse(e){let{ctx:t}=this._processInputParams(e);if(t.parsedType!==h.object)return p(t,{code:u.invalid_type,expected:h.object,received:t.parsedType}),g;let s=this.discriminator,n=t.data[s],a=this.optionsMap.get(n);return a?t.common.async?a._parseAsync({data:t.data,path:t.path,parent:t}):a._parseSync({data:t.data,path:t.path,parent:t}):(p(t,{code:u.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[s]}),g)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,t,s){let n=new Map;for(let a of t){let c=z(a.shape[e]);if(!c.length)throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`);for(let o of c){if(n.has(o))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(o)}`);n.set(o,a)}}return new r({typeName:_.ZodDiscriminatedUnion,discriminator:e,options:t,optionsMap:n,...y(s)})}};function ht(r,e){let t=U(r),s=U(e);if(r===e)return{valid:!0,data:r};if(t===h.object&&s===h.object){let n=b.objectKeys(e),a=b.objectKeys(r).filter(o=>n.indexOf(o)!==-1),c={...r,...e};for(let o of a){let l=ht(r[o],e[o]);if(!l.valid)return{valid:!1};c[o]=l.data}return{valid:!0,data:c}}else if(t===h.array&&s===h.array){if(r.length!==e.length)return{valid:!1};let n=[];for(let a=0;a{if(Me(a)||Me(c))return g;let o=ht(a.value,c.value);return o.valid?((Ve(a)||Ve(c))&&t.dirty(),{status:t.value,value:o.data}):(p(s,{code:u.invalid_intersection_types}),g)};return s.common.async?Promise.all([this._def.left._parseAsync({data:s.data,path:s.path,parent:s}),this._def.right._parseAsync({data:s.data,path:s.path,parent:s})]).then(([a,c])=>n(a,c)):n(this._def.left._parseSync({data:s.data,path:s.path,parent:s}),this._def.right._parseSync({data:s.data,path:s.path,parent:s}))}};oe.create=(r,e,t)=>new oe({left:r,right:e,typeName:_.ZodIntersection,...y(t)});var q=class r extends v{_parse(e){let{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==h.array)return p(s,{code:u.invalid_type,expected:h.array,received:s.parsedType}),g;if(s.data.lengththis._def.items.length&&(p(s,{code:u.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),t.dirty());let a=[...s.data].map((c,o)=>{let l=this._def.items[o]||this._def.rest;return l?l._parse(new $(s,c,s.path,o)):null}).filter(c=>!!c);return s.common.async?Promise.all(a).then(c=>R.mergeArray(t,c)):R.mergeArray(t,a)}get items(){return this._def.items}rest(e){return new r({...this._def,rest:e})}};q.create=(r,e)=>{if(!Array.isArray(r))throw new Error("You must pass an array of schemas to z.tuple([ ... ])");return new q({items:r,typeName:_.ZodTuple,rest:null,...y(e)})};var qe=class r extends v{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){let{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==h.object)return p(s,{code:u.invalid_type,expected:h.object,received:s.parsedType}),g;let n=[],a=this._def.keyType,c=this._def.valueType;for(let o in s.data)n.push({key:a._parse(new $(s,o,s.path,o)),value:c._parse(new $(s,s.data[o],s.path,o)),alwaysSet:o in s.data});return s.common.async?R.mergeObjectAsync(t,n):R.mergeObjectSync(t,n)}get element(){return this._def.valueType}static create(e,t,s){return t instanceof v?new r({keyType:e,valueType:t,typeName:_.ZodRecord,...y(s)}):new r({keyType:K.create(),valueType:e,typeName:_.ZodRecord,...y(t)})}},we=class extends v{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){let{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==h.map)return p(s,{code:u.invalid_type,expected:h.map,received:s.parsedType}),g;let n=this._def.keyType,a=this._def.valueType,c=[...s.data.entries()].map(([o,l],d)=>({key:n._parse(new $(s,o,s.path,[d,"key"])),value:a._parse(new $(s,l,s.path,[d,"value"]))}));if(s.common.async){let o=new Map;return Promise.resolve().then(async()=>{for(let l of c){let d=await l.key,f=await l.value;if(d.status==="aborted"||f.status==="aborted")return g;(d.status==="dirty"||f.status==="dirty")&&t.dirty(),o.set(d.value,f.value)}return{status:t.value,value:o}})}else{let o=new Map;for(let l of c){let d=l.key,f=l.value;if(d.status==="aborted"||f.status==="aborted")return g;(d.status==="dirty"||f.status==="dirty")&&t.dirty(),o.set(d.value,f.value)}return{status:t.value,value:o}}}};we.create=(r,e,t)=>new we({valueType:e,keyType:r,typeName:_.ZodMap,...y(t)});var ke=class r extends v{_parse(e){let{status:t,ctx:s}=this._processInputParams(e);if(s.parsedType!==h.set)return p(s,{code:u.invalid_type,expected:h.set,received:s.parsedType}),g;let n=this._def;n.minSize!==null&&s.data.sizen.maxSize.value&&(p(s,{code:u.too_big,maximum:n.maxSize.value,type:"set",inclusive:!0,exact:!1,message:n.maxSize.message}),t.dirty());let a=this._def.valueType;function c(l){let d=new Set;for(let f of l){if(f.status==="aborted")return g;f.status==="dirty"&&t.dirty(),d.add(f.value)}return{status:t.value,value:d}}let o=[...s.data.values()].map((l,d)=>a._parse(new $(s,l,s.path,d)));return s.common.async?Promise.all(o).then(l=>c(l)):c(o)}min(e,t){return new r({...this._def,minSize:{value:e,message:m.toString(t)}})}max(e,t){return new r({...this._def,maxSize:{value:e,message:m.toString(t)}})}size(e,t){return this.min(e,t).max(e,t)}nonempty(e){return this.min(1,e)}};ke.create=(r,e)=>new ke({valueType:r,minSize:null,maxSize:null,typeName:_.ZodSet,...y(e)});var De=class r extends v{constructor(){super(...arguments),this.validate=this.implement}_parse(e){let{ctx:t}=this._processInputParams(e);if(t.parsedType!==h.function)return p(t,{code:u.invalid_type,expected:h.function,received:t.parsedType}),g;function s(o,l){return Ee({data:o,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,_e(),H].filter(d=>!!d),issueData:{code:u.invalid_arguments,argumentsError:l}})}function n(o,l){return Ee({data:o,path:t.path,errorMaps:[t.common.contextualErrorMap,t.schemaErrorMap,_e(),H].filter(d=>!!d),issueData:{code:u.invalid_return_type,returnTypeError:l}})}let a={errorMap:t.common.contextualErrorMap},c=t.data;if(this._def.returns instanceof X){let o=this;return E(async function(...l){let d=new I([]),f=await o._def.args.parseAsync(l,a).catch(w=>{throw d.addIssue(s(l,w)),d}),x=await Reflect.apply(c,this,f);return await o._def.returns._def.type.parseAsync(x,a).catch(w=>{throw d.addIssue(n(x,w)),d})})}else{let o=this;return E(function(...l){let d=o._def.args.safeParse(l,a);if(!d.success)throw new I([s(l,d.error)]);let f=Reflect.apply(c,this,d.data),x=o._def.returns.safeParse(f,a);if(!x.success)throw new I([n(f,x.error)]);return x.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new r({...this._def,args:q.create(e).rest(B.create())})}returns(e){return new r({...this._def,returns:e})}implement(e){return this.parse(e)}strictImplement(e){return this.parse(e)}static create(e,t,s){return new r({args:e||q.create([]).rest(B.create()),returns:t||B.create(),typeName:_.ZodFunction,...y(s)})}},ce=class extends v{get schema(){return this._def.getter()}_parse(e){let{ctx:t}=this._processInputParams(e);return this._def.getter()._parse({data:t.data,path:t.path,parent:t})}};ce.create=(r,e)=>new ce({getter:r,typeName:_.ZodLazy,...y(e)});var le=class extends v{_parse(e){if(e.data!==this._def.value){let t=this._getOrReturnCtx(e);return p(t,{received:t.data,code:u.invalid_literal,expected:this._def.value}),g}return{status:"valid",value:e.data}}get value(){return this._def.value}};le.create=(r,e)=>new le({value:r,typeName:_.ZodLiteral,...y(e)});function Ut(r,e){return new de({values:r,typeName:_.ZodEnum,...y(e)})}var de=class r extends v{_parse(e){if(typeof e.data!="string"){let t=this._getOrReturnCtx(e),s=this._def.values;return p(t,{expected:b.joinValues(s),received:t.parsedType,code:u.invalid_type}),g}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(e.data)){let t=this._getOrReturnCtx(e),s=this._def.values;return p(t,{received:t.data,code:u.invalid_enum_value,options:s}),g}return E(e.data)}get options(){return this._def.values}get enum(){let e={};for(let t of this._def.values)e[t]=t;return e}get Values(){let e={};for(let t of this._def.values)e[t]=t;return e}get Enum(){let e={};for(let t of this._def.values)e[t]=t;return e}extract(e,t=this._def){return r.create(e,{...this._def,...t})}exclude(e,t=this._def){return r.create(this.options.filter(s=>!e.includes(s)),{...this._def,...t})}};de.create=Ut;var ue=class extends v{_parse(e){let t=b.getValidEnumValues(this._def.values),s=this._getOrReturnCtx(e);if(s.parsedType!==h.string&&s.parsedType!==h.number){let n=b.objectValues(t);return p(s,{expected:b.joinValues(n),received:s.parsedType,code:u.invalid_type}),g}if(this._cache||(this._cache=new Set(b.getValidEnumValues(this._def.values))),!this._cache.has(e.data)){let n=b.objectValues(t);return p(s,{received:s.data,code:u.invalid_enum_value,options:n}),g}return E(e.data)}get enum(){return this._def.values}};ue.create=(r,e)=>new ue({values:r,typeName:_.ZodNativeEnum,...y(e)});var X=class extends v{unwrap(){return this._def.type}_parse(e){let{ctx:t}=this._processInputParams(e);if(t.parsedType!==h.promise&&t.common.async===!1)return p(t,{code:u.invalid_type,expected:h.promise,received:t.parsedType}),g;let s=t.parsedType===h.promise?t.data:Promise.resolve(t.data);return E(s.then(n=>this._def.type.parseAsync(n,{path:t.path,errorMap:t.common.contextualErrorMap})))}};X.create=(r,e)=>new X({type:r,typeName:_.ZodPromise,...y(e)});var L=class extends v{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===_.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(e){let{status:t,ctx:s}=this._processInputParams(e),n=this._def.effect||null,a={addIssue:c=>{p(s,c),c.fatal?t.abort():t.dirty()},get path(){return s.path}};if(a.addIssue=a.addIssue.bind(a),n.type==="preprocess"){let c=n.transform(s.data,a);if(s.common.async)return Promise.resolve(c).then(async o=>{if(t.value==="aborted")return g;let l=await this._def.schema._parseAsync({data:o,path:s.path,parent:s});return l.status==="aborted"?g:l.status==="dirty"?Q(l.value):t.value==="dirty"?Q(l.value):l});{if(t.value==="aborted")return g;let o=this._def.schema._parseSync({data:c,path:s.path,parent:s});return o.status==="aborted"?g:o.status==="dirty"?Q(o.value):t.value==="dirty"?Q(o.value):o}}if(n.type==="refinement"){let c=o=>{let l=n.refinement(o,a);if(s.common.async)return Promise.resolve(l);if(l instanceof Promise)throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return o};if(s.common.async===!1){let o=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});return o.status==="aborted"?g:(o.status==="dirty"&&t.dirty(),c(o.value),{status:t.value,value:o.value})}else return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then(o=>o.status==="aborted"?g:(o.status==="dirty"&&t.dirty(),c(o.value).then(()=>({status:t.value,value:o.value}))))}if(n.type==="transform")if(s.common.async===!1){let c=this._def.schema._parseSync({data:s.data,path:s.path,parent:s});if(!Y(c))return g;let o=n.transform(c.value,a);if(o instanceof Promise)throw new Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:t.value,value:o}}else return this._def.schema._parseAsync({data:s.data,path:s.path,parent:s}).then(c=>Y(c)?Promise.resolve(n.transform(c.value,a)).then(o=>({status:t.value,value:o})):g);b.assertNever(n)}};L.create=(r,e,t)=>new L({schema:r,typeName:_.ZodEffects,effect:e,...y(t)});L.createWithPreprocess=(r,e,t)=>new L({schema:e,effect:{type:"preprocess",transform:r},typeName:_.ZodEffects,...y(t)});var j=class extends v{_parse(e){return this._getType(e)===h.undefined?E(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}};j.create=(r,e)=>new j({innerType:r,typeName:_.ZodOptional,...y(e)});var D=class extends v{_parse(e){return this._getType(e)===h.null?E(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}};D.create=(r,e)=>new D({innerType:r,typeName:_.ZodNullable,...y(e)});var pe=class extends v{_parse(e){let{ctx:t}=this._processInputParams(e),s=t.data;return t.parsedType===h.undefined&&(s=this._def.defaultValue()),this._def.innerType._parse({data:s,path:t.path,parent:t})}removeDefault(){return this._def.innerType}};pe.create=(r,e)=>new pe({innerType:r,typeName:_.ZodDefault,defaultValue:typeof e.default=="function"?e.default:()=>e.default,...y(e)});var he=class extends v{_parse(e){let{ctx:t}=this._processInputParams(e),s={...t,common:{...t.common,issues:[]}},n=this._def.innerType._parse({data:s.data,path:s.path,parent:{...s}});return ye(n)?n.then(a=>({status:"valid",value:a.status==="valid"?a.value:this._def.catchValue({get error(){return new I(s.common.issues)},input:s.data})})):{status:"valid",value:n.status==="valid"?n.value:this._def.catchValue({get error(){return new I(s.common.issues)},input:s.data})}}removeCatch(){return this._def.innerType}};he.create=(r,e)=>new he({innerType:r,typeName:_.ZodCatch,catchValue:typeof e.catch=="function"?e.catch:()=>e.catch,...y(e)});var Se=class extends v{_parse(e){if(this._getType(e)!==h.nan){let s=this._getOrReturnCtx(e);return p(s,{code:u.invalid_type,expected:h.nan,received:s.parsedType}),g}return{status:"valid",value:e.data}}};Se.create=r=>new Se({typeName:_.ZodNaN,...y(r)});var Dr=Symbol("zod_brand"),Ce=class extends v{_parse(e){let{ctx:t}=this._processInputParams(e),s=t.data;return this._def.type._parse({data:s,path:t.path,parent:t})}unwrap(){return this._def.type}},Ie=class r extends v{_parse(e){let{status:t,ctx:s}=this._processInputParams(e);if(s.common.async)return(async()=>{let a=await this._def.in._parseAsync({data:s.data,path:s.path,parent:s});return a.status==="aborted"?g:a.status==="dirty"?(t.dirty(),Q(a.value)):this._def.out._parseAsync({data:a.value,path:s.path,parent:s})})();{let n=this._def.in._parseSync({data:s.data,path:s.path,parent:s});return n.status==="aborted"?g:n.status==="dirty"?(t.dirty(),{status:"dirty",value:n.value}):this._def.out._parseSync({data:n.value,path:s.path,parent:s})}}static create(e,t){return new r({in:e,out:t,typeName:_.ZodPipeline})}},fe=class extends v{_parse(e){let t=this._def.innerType._parse(e),s=n=>(Y(n)&&(n.value=Object.freeze(n.value)),n);return ye(t)?t.then(n=>s(n)):s(t)}unwrap(){return this._def.innerType}};fe.create=(r,e)=>new fe({innerType:r,typeName:_.ZodReadonly,...y(e)});function Lt(r,e){let t=typeof r=="function"?r(e):typeof r=="string"?{message:r}:r;return typeof t=="string"?{message:t}:t}function qt(r,e={},t){return r?G.create().superRefine((s,n)=>{let a=r(s);if(a instanceof Promise)return a.then(c=>{if(!c){let o=Lt(e,s),l=o.fatal??t??!0;n.addIssue({code:"custom",...o,fatal:l})}});if(!a){let c=Lt(e,s),o=c.fatal??t??!0;n.addIssue({code:"custom",...c,fatal:o})}}):G.create()}var Zr={object:A.lazycreate},_;(function(r){r.ZodString="ZodString",r.ZodNumber="ZodNumber",r.ZodNaN="ZodNaN",r.ZodBigInt="ZodBigInt",r.ZodBoolean="ZodBoolean",r.ZodDate="ZodDate",r.ZodSymbol="ZodSymbol",r.ZodUndefined="ZodUndefined",r.ZodNull="ZodNull",r.ZodAny="ZodAny",r.ZodUnknown="ZodUnknown",r.ZodNever="ZodNever",r.ZodVoid="ZodVoid",r.ZodArray="ZodArray",r.ZodObject="ZodObject",r.ZodUnion="ZodUnion",r.ZodDiscriminatedUnion="ZodDiscriminatedUnion",r.ZodIntersection="ZodIntersection",r.ZodTuple="ZodTuple",r.ZodRecord="ZodRecord",r.ZodMap="ZodMap",r.ZodSet="ZodSet",r.ZodFunction="ZodFunction",r.ZodLazy="ZodLazy",r.ZodLiteral="ZodLiteral",r.ZodEnum="ZodEnum",r.ZodEffects="ZodEffects",r.ZodNativeEnum="ZodNativeEnum",r.ZodOptional="ZodOptional",r.ZodNullable="ZodNullable",r.ZodDefault="ZodDefault",r.ZodCatch="ZodCatch",r.ZodPromise="ZodPromise",r.ZodBranded="ZodBranded",r.ZodPipeline="ZodPipeline",r.ZodReadonly="ZodReadonly"})(_||(_={}));var Fr=(r,e={message:`Input not instance of ${r.name}`})=>qt(t=>t instanceof r,e),Dt=K.create,Zt=ee.create,Hr=Se.create,zr=te.create,Ft=re.create,Br=se.create,Jr=xe.create,Wr=ne.create,Yr=ae.create,Kr=G.create,Gr=B.create,Xr=P.create,Qr=be.create,es=J.create,ts=A.create,rs=A.strictCreate,ss=ie.create,ns=Ue.create,as=oe.create,is=q.create,os=qe.create,cs=we.create,ls=ke.create,ds=De.create,us=ce.create,ps=le.create,hs=de.create,fs=ue.create,ms=X.create,gs=L.create,_s=j.create,ys=D.create,vs=L.createWithPreprocess,xs=Ie.create,bs=()=>Dt().optional(),ws=()=>Zt().optional(),ks=()=>Ft().optional(),Ss={string:r=>K.create({...r,coerce:!0}),number:r=>ee.create({...r,coerce:!0}),boolean:r=>re.create({...r,coerce:!0}),bigint:r=>te.create({...r,coerce:!0}),date:r=>se.create({...r,coerce:!0})};var Ts=g;var ft="2024-11-05",Ht=[ft,"2024-10-07"],Ze="2.0",zt=i.union([i.string(),i.number().int()]),Bt=i.string(),M=i.object({_meta:i.optional(i.object({progressToken:i.optional(zt)}).passthrough())}).passthrough(),N=i.object({method:i.string(),params:i.optional(M)}),Ae=i.object({_meta:i.optional(i.object({}).passthrough())}).passthrough(),Z=i.object({method:i.string(),params:i.optional(Ae)}),V=i.object({_meta:i.optional(i.object({}).passthrough())}).passthrough(),Fe=i.union([i.string(),i.number().int()]),Rs=i.object({jsonrpc:i.literal(Ze),id:Fe}).merge(N).strict(),Es=i.object({jsonrpc:i.literal(Ze)}).merge(Z).strict(),Cs=i.object({jsonrpc:i.literal(Ze),id:Fe,result:V}).strict(),me;(function(r){r[r.ConnectionClosed=-1]="ConnectionClosed",r[r.RequestTimeout=-2]="RequestTimeout",r[r.ParseError=-32700]="ParseError",r[r.InvalidRequest=-32600]="InvalidRequest",r[r.MethodNotFound=-32601]="MethodNotFound",r[r.InvalidParams=-32602]="InvalidParams",r[r.InternalError=-32603]="InternalError"})(me||(me={}));var Is=i.object({jsonrpc:i.literal(Ze),id:Fe,error:i.object({code:i.number().int(),message:i.string(),data:i.optional(i.unknown())})}).strict(),Jt=i.union([Rs,Es,Cs,Is]),He=V.strict(),ze=Z.extend({method:i.literal("notifications/cancelled"),params:Ae.extend({requestId:Fe,reason:i.string().optional()})}),Wt=i.object({name:i.string(),version:i.string()}).passthrough(),As=i.object({experimental:i.optional(i.object({}).passthrough()),sampling:i.optional(i.object({}).passthrough()),roots:i.optional(i.object({listChanged:i.optional(i.boolean())}).passthrough())}).passthrough(),mt=N.extend({method:i.literal("initialize"),params:M.extend({protocolVersion:i.string(),capabilities:As,clientInfo:Wt})}),Os=i.object({experimental:i.optional(i.object({}).passthrough()),logging:i.optional(i.object({}).passthrough()),prompts:i.optional(i.object({listChanged:i.optional(i.boolean())}).passthrough()),resources:i.optional(i.object({subscribe:i.optional(i.boolean()),listChanged:i.optional(i.boolean())}).passthrough()),tools:i.optional(i.object({listChanged:i.optional(i.boolean())}).passthrough())}).passthrough(),Ns=V.extend({protocolVersion:i.string(),capabilities:Os,serverInfo:Wt}),gt=Z.extend({method:i.literal("notifications/initialized")}),Be=N.extend({method:i.literal("ping")}),js=i.object({progress:i.number(),total:i.optional(i.number())}).passthrough(),Je=Z.extend({method:i.literal("notifications/progress"),params:Ae.merge(js).extend({progressToken:zt})}),We=N.extend({params:M.extend({cursor:i.optional(Bt)}).optional()}),Ye=V.extend({nextCursor:i.optional(Bt)}),Yt=i.object({uri:i.string(),mimeType:i.optional(i.string())}).passthrough(),Kt=Yt.extend({text:i.string()}),Gt=Yt.extend({blob:i.string().base64()}),$s=i.object({uri:i.string(),name:i.string(),description:i.optional(i.string()),mimeType:i.optional(i.string())}).passthrough(),Ls=i.object({uriTemplate:i.string(),name:i.string(),description:i.optional(i.string()),mimeType:i.optional(i.string())}).passthrough(),Ps=We.extend({method:i.literal("resources/list")}),Ms=Ye.extend({resources:i.array($s)}),Vs=We.extend({method:i.literal("resources/templates/list")}),Us=Ye.extend({resourceTemplates:i.array(Ls)}),qs=N.extend({method:i.literal("resources/read"),params:M.extend({uri:i.string()})}),Ds=V.extend({contents:i.array(i.union([Kt,Gt]))}),Zs=Z.extend({method:i.literal("notifications/resources/list_changed")}),Fs=N.extend({method:i.literal("resources/subscribe"),params:M.extend({uri:i.string()})}),Hs=N.extend({method:i.literal("resources/unsubscribe"),params:M.extend({uri:i.string()})}),zs=Z.extend({method:i.literal("notifications/resources/updated"),params:Ae.extend({uri:i.string()})}),Bs=i.object({name:i.string(),description:i.optional(i.string()),required:i.optional(i.boolean())}).passthrough(),Js=i.object({name:i.string(),description:i.optional(i.string()),arguments:i.optional(i.array(Bs))}).passthrough(),Ws=We.extend({method:i.literal("prompts/list")}),Ys=Ye.extend({prompts:i.array(Js)}),Ks=N.extend({method:i.literal("prompts/get"),params:M.extend({name:i.string(),arguments:i.optional(i.record(i.string()))})}),Ke=i.object({type:i.literal("text"),text:i.string()}).passthrough(),Ge=i.object({type:i.literal("image"),data:i.string().base64(),mimeType:i.string()}).passthrough(),Xt=i.object({type:i.literal("resource"),resource:i.union([Kt,Gt])}).passthrough(),Gs=i.object({role:i.enum(["user","assistant"]),content:i.union([Ke,Ge,Xt])}).passthrough(),Xs=V.extend({description:i.optional(i.string()),messages:i.array(Gs)}),Qs=Z.extend({method:i.literal("notifications/prompts/list_changed")}),en=i.object({name:i.string(),description:i.optional(i.string()),inputSchema:i.object({type:i.literal("object"),properties:i.optional(i.object({}).passthrough())}).passthrough()}).passthrough(),_t=We.extend({method:i.literal("tools/list")}),tn=Ye.extend({tools:i.array(en)}),Qt=V.extend({content:i.array(i.union([Ke,Ge,Xt])),isError:i.boolean().default(!1).optional()}),_a=Qt.or(V.extend({toolResult:i.unknown()})),yt=N.extend({method:i.literal("tools/call"),params:M.extend({name:i.string(),arguments:i.optional(i.record(i.unknown()))})}),rn=Z.extend({method:i.literal("notifications/tools/list_changed")}),er=i.enum(["debug","info","notice","warning","error","critical","alert","emergency"]),sn=N.extend({method:i.literal("logging/setLevel"),params:M.extend({level:er})}),nn=Z.extend({method:i.literal("notifications/message"),params:Ae.extend({level:er,logger:i.optional(i.string()),data:i.unknown()})}),an=i.object({name:i.string().optional()}).passthrough(),on=i.object({hints:i.optional(i.array(an)),costPriority:i.optional(i.number().min(0).max(1)),speedPriority:i.optional(i.number().min(0).max(1)),intelligencePriority:i.optional(i.number().min(0).max(1))}).passthrough(),cn=i.object({role:i.enum(["user","assistant"]),content:i.union([Ke,Ge])}).passthrough(),ln=N.extend({method:i.literal("sampling/createMessage"),params:M.extend({messages:i.array(cn),systemPrompt:i.optional(i.string()),includeContext:i.optional(i.enum(["none","thisServer","allServers"])),temperature:i.optional(i.number()),maxTokens:i.number().int(),stopSequences:i.optional(i.array(i.string())),metadata:i.optional(i.object({}).passthrough()),modelPreferences:i.optional(on)})}),vt=V.extend({model:i.string(),stopReason:i.optional(i.enum(["endTurn","stopSequence","maxTokens"]).or(i.string())),role:i.enum(["user","assistant"]),content:i.discriminatedUnion("type",[Ke,Ge])}),dn=i.object({type:i.literal("ref/resource"),uri:i.string()}).passthrough(),un=i.object({type:i.literal("ref/prompt"),name:i.string()}).passthrough(),pn=N.extend({method:i.literal("completion/complete"),params:M.extend({ref:i.union([un,dn]),argument:i.object({name:i.string(),value:i.string()}).passthrough()})}),hn=V.extend({completion:i.object({values:i.array(i.string()).max(100),total:i.optional(i.number().int()),hasMore:i.optional(i.boolean())}).passthrough()}),fn=i.object({uri:i.string().startsWith("file://"),name:i.optional(i.string())}).passthrough(),mn=N.extend({method:i.literal("roots/list")}),xt=V.extend({roots:i.array(fn)}),gn=Z.extend({method:i.literal("notifications/roots/list_changed")}),ya=i.union([Be,mt,pn,sn,Ks,Ws,Ps,Vs,qs,Fs,Hs,yt,_t]),va=i.union([ze,Je,gt,gn]),xa=i.union([He,vt,xt]),ba=i.union([Be,ln,mn]),wa=i.union([ze,Je,nn,zs,Zs,rn,Qs]),ka=i.union([He,Ns,hn,Xs,Ys,Ms,Us,Ds,Qt,tn]),Te=class extends Error{constructor(e,t,s){super(`MCP error ${e}: ${t}`),this.code=e,this.data=s}};var _n=6e4,Xe=class{constructor(e){this._options=e,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this.setNotificationHandler(ze,t=>{let s=this._requestHandlerAbortControllers.get(t.params.requestId);s?.abort(t.params.reason)}),this.setNotificationHandler(Je,t=>{this._onprogress(t)}),this.setRequestHandler(Be,t=>({}))}async connect(e){this._transport=e,this._transport.onclose=()=>{this._onclose()},this._transport.onerror=t=>{this._onerror(t)},this._transport.onmessage=t=>{"method"in t?"id"in t?this._onrequest(t):this._onnotification(t):this._onresponse(t)},await this._transport.start()}_onclose(){var e;let t=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._transport=void 0,(e=this.onclose)===null||e===void 0||e.call(this);let s=new Te(me.ConnectionClosed,"Connection closed");for(let n of t.values())n(s)}_onerror(e){var t;(t=this.onerror)===null||t===void 0||t.call(this,e)}_onnotification(e){var t;let s=(t=this._notificationHandlers.get(e.method))!==null&&t!==void 0?t:this.fallbackNotificationHandler;s!==void 0&&Promise.resolve().then(()=>s(e)).catch(n=>this._onerror(new Error(`Uncaught error in notification handler: ${n}`)))}_onrequest(e){var t,s;let n=(t=this._requestHandlers.get(e.method))!==null&&t!==void 0?t:this.fallbackRequestHandler;if(n===void 0){(s=this._transport)===null||s===void 0||s.send({jsonrpc:"2.0",id:e.id,error:{code:me.MethodNotFound,message:"Method not found"}}).catch(c=>this._onerror(new Error(`Failed to send an error response: ${c}`)));return}let a=new AbortController;this._requestHandlerAbortControllers.set(e.id,a),Promise.resolve().then(()=>n(e,{signal:a.signal})).then(c=>{var o;if(!a.signal.aborted)return(o=this._transport)===null||o===void 0?void 0:o.send({result:c,jsonrpc:"2.0",id:e.id})},c=>{var o,l;if(!a.signal.aborted)return(o=this._transport)===null||o===void 0?void 0:o.send({jsonrpc:"2.0",id:e.id,error:{code:Number.isSafeInteger(c.code)?c.code:me.InternalError,message:(l=c.message)!==null&&l!==void 0?l:"Internal error"}})}).catch(c=>this._onerror(new Error(`Failed to send response: ${c}`))).finally(()=>{this._requestHandlerAbortControllers.delete(e.id)})}_onprogress(e){let{progress:t,total:s,progressToken:n}=e.params,a=this._progressHandlers.get(Number(n));if(a===void 0){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(e)}`));return}a({progress:t,total:s})}_onresponse(e){let t=e.id,s=this._responseHandlers.get(Number(t));if(s===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(e)}`));return}if(this._responseHandlers.delete(Number(t)),this._progressHandlers.delete(Number(t)),"result"in e)s(e);else{let n=new Te(e.error.code,e.error.message,e.error.data);s(n)}}get transport(){return this._transport}async close(){var e;await((e=this._transport)===null||e===void 0?void 0:e.close())}request(e,t,s){return new Promise((n,a)=>{var c,o,l,d;if(!this._transport){a(new Error("Not connected"));return}((c=this._options)===null||c===void 0?void 0:c.enforceStrictCapabilities)===!0&&this.assertCapabilityForMethod(e.method),(o=s?.signal)===null||o===void 0||o.throwIfAborted();let f=this._requestMessageId++,x={...e,jsonrpc:"2.0",id:f};s?.onprogress&&(this._progressHandlers.set(f,s.onprogress),x.params={...e.params,_meta:{progressToken:f}});let S;this._responseHandlers.set(f,T=>{var C;if(S!==void 0&&clearTimeout(S),!(!((C=s?.signal)===null||C===void 0)&&C.aborted)){if(T instanceof Error)return a(T);try{let F=t.parse(T.result);n(F)}catch(F){a(F)}}});let w=T=>{var C;this._responseHandlers.delete(f),this._progressHandlers.delete(f),(C=this._transport)===null||C===void 0||C.send({jsonrpc:"2.0",method:"cancelled",params:{requestId:f,reason:String(T)}}).catch(F=>this._onerror(new Error(`Failed to send cancellation: ${F}`))),a(T)};(l=s?.signal)===null||l===void 0||l.addEventListener("abort",()=>{var T;S!==void 0&&clearTimeout(S),w((T=s?.signal)===null||T===void 0?void 0:T.reason)});let k=(d=s?.timeout)!==null&&d!==void 0?d:_n;S=setTimeout(()=>w(new Te(me.RequestTimeout,"Request timed out",{timeout:k})),k),this._transport.send(x).catch(T=>{S!==void 0&&clearTimeout(S),a(T)})})}async notification(e){if(!this._transport)throw new Error("Not connected");this.assertNotificationCapability(e.method);let t={...e,jsonrpc:"2.0"};await this._transport.send(t)}setRequestHandler(e,t){let s=e.shape.method.value;this.assertRequestHandlerCapability(s),this._requestHandlers.set(s,(n,a)=>Promise.resolve(t(e.parse(n),a)))}removeRequestHandler(e){this._requestHandlers.delete(e)}setNotificationHandler(e,t){this._notificationHandlers.set(e.shape.method.value,s=>Promise.resolve(t(e.parse(s))))}removeNotificationHandler(e){this._notificationHandlers.delete(e)}};var Qe=class extends Xe{constructor(e,t){super(t),this._serverInfo=e,this._capabilities=t.capabilities,this.setRequestHandler(mt,s=>this._oninitialize(s)),this.setNotificationHandler(gt,()=>{var s;return(s=this.oninitialized)===null||s===void 0?void 0:s.call(this)})}assertCapabilityForMethod(e){var t,s;switch(e){case"sampling/createMessage":if(!(!((t=this._clientCapabilities)===null||t===void 0)&&t.sampling))throw new Error(`Client does not support sampling (required for ${e})`);break;case"roots/list":if(!(!((s=this._clientCapabilities)===null||s===void 0)&&s.roots))throw new Error(`Client does not support listing roots (required for ${e})`);break;case"ping":break}}assertNotificationCapability(e){switch(e){case"notifications/message":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${e})`);break;case"notifications/resources/updated":case"notifications/resources/list_changed":if(!this._capabilities.resources)throw new Error(`Server does not support notifying about resources (required for ${e})`);break;case"notifications/tools/list_changed":if(!this._capabilities.tools)throw new Error(`Server does not support notifying of tool list changes (required for ${e})`);break;case"notifications/prompts/list_changed":if(!this._capabilities.prompts)throw new Error(`Server does not support notifying of prompt list changes (required for ${e})`);break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(e){switch(e){case"sampling/createMessage":if(!this._capabilities.sampling)throw new Error(`Server does not support sampling (required for ${e})`);break;case"logging/setLevel":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${e})`);break;case"prompts/get":case"prompts/list":if(!this._capabilities.prompts)throw new Error(`Server does not support prompts (required for ${e})`);break;case"resources/list":case"resources/templates/list":case"resources/read":if(!this._capabilities.resources)throw new Error(`Server does not support resources (required for ${e})`);break;case"tools/call":case"tools/list":if(!this._capabilities.tools)throw new Error(`Server does not support tools (required for ${e})`);break;case"ping":case"initialize":break}}async _oninitialize(e){let t=e.params.protocolVersion;return this._clientCapabilities=e.params.capabilities,this._clientVersion=e.params.clientInfo,{protocolVersion:Ht.includes(t)?t:ft,capabilities:this.getCapabilities(),serverInfo:this._serverInfo}}getClientCapabilities(){return this._clientCapabilities}getClientVersion(){return this._clientVersion}getCapabilities(){return this._capabilities}async ping(){return this.request({method:"ping"},He)}async createMessage(e,t){return this.request({method:"sampling/createMessage",params:e},vt,t)}async listRoots(e,t){return this.request({method:"roots/list",params:e},xt,t)}async sendLoggingMessage(e){return this.notification({method:"notifications/message",params:e})}async sendResourceUpdated(e){return this.notification({method:"notifications/resources/updated",params:e})}async sendResourceListChanged(){return this.notification({method:"notifications/resources/list_changed"})}async sendToolListChanged(){return this.notification({method:"notifications/tools/list_changed"})}async sendPromptListChanged(){return this.notification({method:"notifications/prompts/list_changed"})}};import rr from"node:process";var et=class{append(e){this._buffer=this._buffer?Buffer.concat([this._buffer,e]):e}readMessage(){if(!this._buffer)return null;let e=this._buffer.indexOf(` +`);if(e===-1)return null;let t=this._buffer.toString("utf8",0,e);return this._buffer=this._buffer.subarray(e+1),yn(t)}clear(){this._buffer=void 0}};function yn(r){return Jt.parse(JSON.parse(r))}function tr(r){return JSON.stringify(r)+` +`}var tt=class{constructor(e=rr.stdin,t=rr.stdout){this._stdin=e,this._stdout=t,this._readBuffer=new et,this._started=!1,this._ondata=s=>{this._readBuffer.append(s),this.processReadBuffer()},this._onerror=s=>{var n;(n=this.onerror)===null||n===void 0||n.call(this,s)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(var e,t;;)try{let s=this._readBuffer.readMessage();if(s===null)break;(e=this.onmessage)===null||e===void 0||e.call(this,s)}catch(s){(t=this.onerror)===null||t===void 0||t.call(this,s)}}async close(){var e;this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._readBuffer.clear(),(e=this.onclose)===null||e===void 0||e.call(this)}send(e){return new Promise(t=>{let s=tr(e);this._stdout.write(s)?t():this._stdout.once("drain",t)})}};var Et={};Nt(Et,{getAgent:()=>nr,getDeploymentStatus:()=>dr,listAgents:()=>sr,listPrimitiveVersions:()=>cr,tailLogs:()=>ur});import{spawn as vn}from"node:child_process";var xn=6e4;function bn(r,{spawnFn:e=vn,timeoutMs:t=xn,label:s="lua"}={}){return new Promise((n,a)=>{let c=e("lua",r,{shell:process.platform==="win32",windowsHide:!0,env:{...process.env,LUA_NO_BANNER:"1",LUA_NO_HINTS:"1"}}),o="",l="";c.stdout.on("data",f=>{o+=f.toString("utf8")}),c.stderr.on("data",f=>{l+=f.toString("utf8")});let d=setTimeout(()=>{c.kill("SIGTERM"),a(new Error(`${s}: 'lua ${r.join(" ")}' timed out after ${t}ms`))},t);c.on("exit",f=>{clearTimeout(d),f!==0?a(new Error(`'lua ${r.join(" ")}' exited ${f}: ${l.trim()}`)):n(o)}),c.on("error",f=>{clearTimeout(d),a(f)})})}function wn(r){let e=r,t=Array.isArray(e)?e:e?.agents??e?.orgs??[];return t.length>0&&t[0]&&Array.isArray(t[0].agents)?t.flatMap(n=>(n.agents??[]).map(a=>({id:a.agentId??a.id??a._id,name:a.name??null,orgId:n.orgId??n.id??n._id??null,orgName:n.name??n.registeredName??null,visibility:a.visibility??null}))):t.map(n=>({id:n.agentId??n.id??n._id,name:n.name??null,orgId:n.orgId??null,orgName:n.orgName??null,visibility:n.visibility??null}))}async function rt({spawnFn:r,label:e="list_agents"}={}){let t=await bn(["agents","--json","--ci"],{spawnFn:r,label:e}),s;try{s=JSON.parse(t)}catch(n){throw new Error(`${e}: could not parse 'lua agents --json' output: ${n.message}`)}return wn(s)}var sr={spec:{name:"list_agents",description:"List all Lua agents the authenticated credential can reach. Returns a compact array of {id, name, orgId, orgName, visibility} flattened across all organisations. Same data as `lua agents --json` \u2014 it resolves every organisation, so on accounts with many orgs this takes 20 s or more; prefer get_agent when you already know the id.",inputSchema:{type:"object",properties:{},required:[]}},async handler(r,e={}){let t=await rt({spawnFn:e.spawnFn,label:"list_agents"});return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}};var nr={spec:{name:"get_agent",description:"Look up one Lua agent by ID and return {id, name, orgId, orgName, visibility}. For what is live use get_deployment_status / list_primitive_versions; for logs use tail_logs.",inputSchema:{type:"object",properties:{agentId:{type:"string",description:"Agent ID (the `id` field from list_agents; also `agent.agentId` in lua.skill.yaml)"}},required:["agentId"]}},async handler({agentId:r},e={}){if(!r)throw new Error("agentId is required");let s=(await rt({spawnFn:e.spawnFn,label:"get_agent"})).find(n=>n.id===r)??null;if(!s)throw new Error(`get_agent: no agent with id "${r}" found in the authenticated credential's accessible orgs. Run list_agents to see available agents.`);return{content:[{type:"text",text:JSON.stringify(s,null,2)}]}}};import{readFile as bt,readdir as kn,stat as Sn}from"node:fs/promises";import{join as st,dirname as Tn}from"node:path";import{homedir as Rn}from"node:os";var En="https://api.heylua.ai",Cn="https://securetoken.googleapis.com/v1/token",In=15e3,An=6e4,On=["TOKEN_EXPIRED","USER_DISABLED","USER_NOT_FOUND","INVALID_REFRESH_TOKEN","INVALID_GRANT_TYPE","MISSING_REFRESH_TOKEN"],ar=new Map;function Nn(r){for(let e of r.split(/\r?\n/)){let t=e.match(/^\s*(?:export\s+)?LUA_API_KEY\s*=\s*(.*)$/);if(!t)continue;let s=t[1].trim(),n=s.match(/^(['"`])(.*?)\1(?:\s+#.*)?\s*$/);return n?s=n[2]:s=s.replace(/\s+#.*$/,"").trim(),s||null}return null}async function jn({sessionsDir:r,apiUrl:e}){let t;try{t=await kn(r)}catch{return null}let s=[];for(let n of t){if(!n.endsWith(".json")||n.startsWith("."))continue;let a=st(r,n);try{let c=JSON.parse(await bt(a,"utf8"));if(c?.kind!=="firebase-session"||c?.version!==1||typeof c.refreshToken!="string"||!c.refreshToken||typeof c.firebaseWebApiKey!="string"||!c.firebaseWebApiKey||c.apiUrl!==e)continue;let{mtimeMs:o}=await Sn(a);s.push({path:a,session:c,mtimeMs:o})}catch{}}return s.length===0?null:(s.sort((n,a)=>a.mtimeMs-n.mtimeMs),{path:s[0].path,session:s[0].session})}async function $n({path:r,session:e,fetchFn:t=globalThis.fetch,now:s=Date.now}){let n=ar.get(r);if(n&&n.expiresAt-s()>An)return n.idToken;let a=new AbortController,c=setTimeout(()=>a.abort(),In),o;try{o=await t(`${Cn}?key=${encodeURIComponent(e.firebaseWebApiKey)}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:e.refreshToken}).toString(),signal:a.signal})}catch(x){throw new Error(`MCP_AUTH_UNAVAILABLE: could not refresh the lua-cli session (${x?.name==="AbortError"?"timed out":x.message}). Check your network, or set LUA_API_KEY to bypass the session.`)}finally{clearTimeout(c)}if(!o.ok){let x=o.statusText??String(o.status);try{let k=(await o.json())?.error?.message;typeof k=="string"&&k&&(x=k.split(":")[0].trim())}catch{}let S=o.status<500&&On.find(w=>x.toUpperCase().includes(w));throw S?new Error(`MCP_AUTH_STALE: your lua-cli session was signed out (${S}). Signing out of the Lua dashboard, desktop or mobile app also ends CLI sessions. Run \`lua auth configure\` in a terminal to sign in again.`):new Error(`MCP_AUTH_UNAVAILABLE: lua-cli session refresh failed (${o.status} ${x}). Retry in a moment.`)}let l=await o.json(),d=l?.id_token,f=Number(l?.expires_in);if(typeof d!="string"||!d||!Number.isFinite(f)||f<=0)throw new Error("MCP_AUTH_UNAVAILABLE: the session refresh returned an invalid token. Run `lua auth configure` again.");return ar.set(r,{idToken:d,expiresAt:s()+f*1e3}),d}async function ir({env:r=process.env,credentialsPath:e=r.LUA_CREDENTIALS_PATH??st(Rn(),".lua-cli","credentials"),sessionsDir:t=r.LUA_SESSIONS_DIR??st(Tn(e),"sessions"),cwd:s=process.cwd(),apiUrl:n=r.LUA_API_URL||En,fetchFn:a=globalThis.fetch,now:c=Date.now}={}){if(r.LUA_API_KEY&&r.LUA_API_KEY.trim())return r.LUA_API_KEY.trim();try{let l=Nn(await bt(st(s,".env"),"utf8"));if(l)return l}catch{}let o=await jn({sessionsDir:t,apiUrl:n});if(o)return $n({...o,fetchFn:a,now:c});try{let l=(await bt(e,"utf8")).trim();if(l){if(l.startsWith("{"))try{let d=JSON.parse(l);if(d?.apiKey)return d.apiKey}catch{}return l}}catch{}throw new Error("MCP_AUTH_STALE: No lua-cli credentials found in LUA_API_KEY, .env, ~/.lua-cli/sessions, or ~/.lua-cli/credentials. Run `lua auth configure` in a terminal (or /lua-auth in Claude Code).")}var Ln="https://api.heylua.ai",Pn=1e4,Ba=Object.freeze({skills:"automations:read",webhooks:"automations:read",jobs:"automations:read",triggers:"automations:read",preprocessors:"automations:read",postprocessors:"automations:read",workflows:"workflows:read",persona:"agents:read",logs:"knowledge:read"}),Mn="skills/webhooks/jobs/triggers/preprocessors/postprocessors need automations:read, workflows need workflows:read, persona needs agents:read, logs need knowledge:read";async function ge(r,{method:e="GET",body:t,query:s,fetchFn:n=globalThis.fetch,baseUrl:a=process.env.LUA_API_URL||Ln,timeoutMs:c=Pn}={}){let o=await ir(),l=new URL(a.replace(/\/$/,"")+r);if(s)for(let[x,S]of Object.entries(s))l.searchParams.set(x,String(S));let d=new AbortController,f=setTimeout(()=>d.abort(),c);try{let x=await n(l.toString(),{method:e,headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json","X-Lua-Client":"claude-plugin/1.6.0"},body:t?JSON.stringify(t):void 0,signal:d.signal});if(x.status===401)throw new Error("MCP_AUTH_STALE: lua-api returned 401. The credential is missing, expired, or the session was signed out (signing out of the Lua dashboard or apps also ends CLI sessions). Run `lua auth configure` in a terminal, or re-run /lua-doctor.");if(x.status===403)throw new Error(`MCP_FORBIDDEN: lua-api returned 403 for ${r}. The credential cannot access this agent or org, or it lacks the route scope (${Mn} \u2014 typed keys are scoped to the agents and role chosen at \`lua auth configure\`). Re-run /lua-doctor or check the LUA_API_KEY env var.`);if(!x.ok){let S=await x.text(),w=S;try{let k=JSON.parse(S);w=k?.error?.message??k?.message??S;let T=k?.error?.code;typeof T=="string"&&T&&!String(w).includes(T)&&(w=`${T}: ${w}`)}catch{}throw new Error(`lua-api ${x.status}: ${w}`)}return await x.json()}catch(x){throw x.name==="AbortError"?new Error(`MCP_TIMEOUT: ${r} did not respond in ${c}ms`):x}finally{clearTimeout(f)}}var wt={skill:r=>r?.skills??[],webhook:r=>r?.data?.webhooks??[],job:r=>r?.data?.jobs??[],trigger:r=>r?.data?.triggers??[],preprocessor:r=>r?.data?.preprocessors??[],postprocessor:r=>r?.data?.postprocessors??[],workflow:r=>r?.data?.workflows??[]},kt={skill:r=>r?.versions??[],webhook:r=>r?.data?.versions??[],job:r=>Array.isArray(r?.data)?r.data:[],trigger:r=>r?.data?.versions??[],preprocessor:r=>r?.data?.versions??[],postprocessor:r=>r?.data?.versions??[],workflow:r=>Array.isArray(r?.data)?r.data:[],persona:r=>r?.versions??[]},Re={skill:"skills",webhook:"webhooks",job:"jobs",trigger:"triggers",preprocessor:"preprocessors",postprocessor:"postprocessors",workflow:"workflows"};function nt(r,e){let t=wt[r];if(!t)throw new Error(`extractList: unknown primitive type "${r}". Valid: ${Object.keys(wt).join(", ")}`);return t(e)}function Oe(r,e){let t=kt[r];if(!t)throw new Error(`extractVersions: unknown primitive type "${r}". Valid: ${Object.keys(kt).join(", ")}`);return t(e)}function Ne(r){let e=r?.data?.activeVersionId;return typeof e=="string"&&e?e:null}function je(r,e,t){if(!e||typeof e!="object")return!1;switch(r){case"skill":case"persona":return e.isCurrent===!0;case"job":case"workflow":return e.active===!0;case"webhook":case"trigger":case"preprocessor":case"postprocessor":{if(e.isActive===!0)return!0;let s=Ne(t),n=e.versionId??e.id??null;return!!s&&n===s}default:return!1}}function $e(r){if(!r||typeof r!="object")return null;let e=r.createdAt??r.createdDate??null;return e==null?null:typeof e=="number"?Number.isFinite(e)?new Date(e).toISOString():null:String(e)}function at(r){return!r||typeof r!="object"?null:r.versionId??r.id??null}var Wa=Object.keys(wt),or=Object.keys(kt);var St=new Set(or),cr={spec:{name:"list_primitive_versions",description:"List the server-side versions of one primitive (skill, webhook, job, trigger, preprocessor, postprocessor, workflow) or the agent persona. Returns { activeVersionId, versions: [{version, versionId, active, createdAt}] } \u2014 `active` is the version currently live. `versionId` is null for types whose versions route carries no per-entry id: skill, persona and webhook (the webhook route exposes the row id only under a misnamed `webhookId` key). For those, identify a version by `version`; for webhooks the live row id is the top-level `activeVersionId`. `activeVersionId` is populated only for webhook, trigger, preprocessor and postprocessor envelopes and is null for skill, job, workflow and persona.",inputSchema:{type:"object",properties:{agentId:{type:"string"},type:{type:"string",enum:[...St]},name:{type:"string",description:"Primitive name as written in lua.skill.yaml (omit for persona \u2014 an agent has only one)"}},required:["agentId","type"]}},async handler({agentId:r,type:e,name:t},s={}){if(!r||!e)throw new Error("agentId and type are required");if(!St.has(e))throw new Error(`Invalid type: ${e}. Valid: ${[...St].join(", ")}`);if(e!=="persona"&&!t)throw new Error("name is required for all types except persona");let n;if(e==="persona")n=`/developer/agents/${encodeURIComponent(r)}/persona/versions`;else{let d=await Vn({agentId:r,type:e,name:t,fetchFn:s.fetchFn});n=`/developer/${Re[e]}/${encodeURIComponent(r)}/${encodeURIComponent(d)}/versions`}let a=await ge(n,{fetchFn:s.fetchFn}),o=Oe(e,a).map(d=>({version:d.version,versionId:at(d),active:je(e,d,a),createdAt:$e(d)})),l={agentId:r,type:e,name:e==="persona"?null:t,activeVersionId:Ne(a),versions:o};return{content:[{type:"text",text:JSON.stringify(l,null,2)}]}}};async function Vn({agentId:r,type:e,name:t,fetchFn:s}){let n=`/developer/${Re[e]}/${encodeURIComponent(r)}`,a=await ge(n,{fetchFn:s}),c=nt(e,a),o=c.find(d=>d.name===t);if(!o){let d=c.map(f=>f.name).filter(Boolean).join(", ")||"(none)";throw new Error(`list_primitive_versions: no ${e} named "${t}" on agent ${r}. Available: ${d}`)}let l=o.id??o._id;if(!l)throw new Error(`list_primitive_versions: ${e} "${t}" exists but has no id field`);return l}var it=["skill","webhook","job","trigger","preprocessor","postprocessor","workflow"],lr=5,Un=45e3,dr={spec:{name:"get_deployment_status",description:'What is live right now for an agent: for every skill, webhook, job, trigger, preprocessor, postprocessor and workflow the active (deployed) version, plus the active persona version. Composed from the per-type lua-api version routes (list calls in parallel, then per-item version lookups in chunks of 5). Bounded by a 45 s wall-clock budget: if exceeded, remaining items are listed with `error: "skipped: \u2026"` and the result carries `partial: true` + `partialReason`. Inside a project, `lua status --json` additionally compares local vs deployed.',inputSchema:{type:"object",properties:{agentId:{type:"string"}},required:["agentId"]}},async handler({agentId:r},e={}){if(!r)throw new Error("agentId is required");let t=encodeURIComponent(r),s=Number.isFinite(e.budgetMs)?e.budgetMs:Un,n=Date.now(),a=()=>Date.now()-n>s,c=w=>ge(w,{fetchFn:e.fetchFn}),o={agentId:r,persona:null,primitives:{}};for(let w of it)o.primitives[w]=[];let[l,...d]=await Promise.allSettled([c(`/developer/agents/${t}/persona/versions`),...it.map(w=>c(`/developer/${Re[w]}/${t}`))]);if(l.status==="fulfilled"){let w=l.value,k=Oe("persona",w),T=k.find(C=>je("persona",C,w))??null;o.persona={activeVersion:T?.version??null,activeVersionCreatedAt:$e(T),versionCount:k.length}}else o.persona={error:l.reason?.message??String(l.reason)};let f=!1,x=0,S=0;for(let w=0;w({p:O,primId:O.id??O._id,name:O.name??O.id??O._id})).filter(O=>O.primId);S+=F.length;for(let O=0;Oc(`/developer/${T}/${t}/${encodeURIComponent(W)}/versions`)))).forEach((W,ot)=>{let{p:Pe,primId:It,name:At}=Le[ot];if(W.status!=="fulfilled"){o.primitives[k].push({name:At,id:It,error:W.reason?.message??String(W.reason)});return}let ct=W.value,Ot=Oe(k,ct),lt=Ot.find(fr=>je(k,fr,ct))??null,dt={name:At,id:It,activeVersion:lt?.version??null,activeVersionId:at(lt)??Ne(ct),activeVersionCreatedAt:$e(lt),versionCount:Ot.length};typeof Pe.active=="boolean"&&(dt.enabled=Pe.active),k==="workflow"&&typeof Pe.dynamic=="boolean"&&(dt.dynamic=Pe.dynamic),o.primitives[k].push(dt)})}}return x>0&&(o.partial=!0,o.partialReason=`Wall-clock budget of ${s}ms exceeded after ${Date.now()-n}ms; ${x} of ${S} version lookups were not issued (entries carry error: "skipped: \u2026").`),{content:[{type:"text",text:JSON.stringify(o,null,2)}]}}};var qn=["skill","job","webhook","trigger","preprocessor","postprocessor","user_message","agent_response","agent_error","runtime","mcp","rag","device","device-trigger","model-resolver","workflow-step","workflow-script","workflow"],Rt=["error","warn","info","debug","start","complete"],Tt=new Set(["all",...qn]),Dn=new Set(Rt),ur={spec:{name:"tail_logs",description:"Fetch recent execution logs for an agent (same data as `lua logs --json`). Returns { logs: LogEntry[], pagination }. Each LogEntry has `subType` (error | warn | info | debug | start | complete), `message`, `timestamp`, and `metadata.logSource` / `metadata.primitiveName` \u2014 there is NO `level` field. Filter by source (`type`), primitive (`name`) and/or severity (`logType`, which filters on `subType`).",inputSchema:{type:"object",properties:{agentId:{type:"string"},type:{type:"string",enum:[...Tt],default:"all",description:"Log source filter (maps to lua-api `logSource`). `all` = no filter."},name:{type:"string",description:"Filter by primitive name (optional; maps to `primitiveName`)"},logType:{type:"string",enum:Rt,description:"Filter by LogEntry `subType` (optional; maps to lua-api `logType`). Omit for every severity. e.g. `error` to see only failures."},limit:{type:"number",default:50,minimum:1,maximum:100},page:{type:"number",minimum:1,description:"Page number for pagination (optional)"}},required:["agentId"]}},async handler({agentId:r,type:e="all",name:t,logType:s,limit:n=50,page:a},c={}){if(!r)throw new Error("agentId is required");if(!Tt.has(e))throw new Error(`Invalid type: ${e}. Valid: ${[...Tt].join(", ")}`);if(s!==void 0&&!Dn.has(s))throw new Error(`Invalid logType: ${s}. Valid: ${Rt.join(", ")}`);if(n>100)throw new Error(`Invalid limit: ${n}. lua-api caps logs at 100 entries per call.`);let o={limit:n};e!=="all"&&(o.logSource=e),t&&(o.primitiveName=t),s&&(o.logType=s),a&&(o.page=a);let l=await ge(`/developer/agents/${encodeURIComponent(r)}/logs`,{query:o,fetchFn:c.fetchFn});return{content:[{type:"text",text:JSON.stringify(l,null,2)}]}}};var pr=Object.values(Et),Ct=new Qe({name:"lua-platform",version:"1.6.0"},{capabilities:{tools:{}}});Ct.setRequestHandler(_t,async()=>({tools:pr.map(r=>r.spec)}));Ct.setRequestHandler(yt,async r=>{let e=pr.find(t=>t.spec.name===r.params.name);if(!e)throw new Error(`Unknown tool: ${r.params.name}`);try{return await e.handler(r.params.arguments??{})}catch(t){return{content:[{type:"text",text:`Error: ${t.message}`}],isError:!0}}});function hr(r){process.stderr.write(JSON.stringify(r)+` +`,()=>process.exit(1))}process.on("uncaughtException",r=>{hr({event:"mcp_server_crash",kind:"uncaughtException",message:r?.message,stack:r?.stack,plugin_version:"1.6.0",lua_cli_version:process.env.LUA_CLI_VERSION??null,platform:process.platform,ts:new Date().toISOString()})});process.on("unhandledRejection",r=>{hr({event:"mcp_server_crash",kind:"unhandledRejection",reason:String(r),stack:r?.stack,plugin_version:"1.6.0",lua_cli_version:process.env.LUA_CLI_VERSION??null,platform:process.platform,ts:new Date().toISOString()})});await Ct.connect(new tt); +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vbm9kZV9tb2R1bGVzL3pvZC92My9leHRlcm5hbC5qcyIsICIuLi9ub2RlX21vZHVsZXMvem9kL3YzL2hlbHBlcnMvdXRpbC5qcyIsICIuLi9ub2RlX21vZHVsZXMvem9kL3YzL1pvZEVycm9yLmpzIiwgIi4uL25vZGVfbW9kdWxlcy96b2QvdjMvbG9jYWxlcy9lbi5qcyIsICIuLi9ub2RlX21vZHVsZXMvem9kL3YzL2Vycm9ycy5qcyIsICIuLi9ub2RlX21vZHVsZXMvem9kL3YzL2hlbHBlcnMvcGFyc2VVdGlsLmpzIiwgIi4uL25vZGVfbW9kdWxlcy96b2QvdjMvaGVscGVycy9lcnJvclV0aWwuanMiLCAiLi4vbm9kZV9tb2R1bGVzL3pvZC92My90eXBlcy5qcyIsICIuLi9ub2RlX21vZHVsZXMvQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zcmMvdHlwZXMudHMiLCAiLi4vbm9kZV9tb2R1bGVzL0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc3JjL3NoYXJlZC9wcm90b2NvbC50cyIsICIuLi9ub2RlX21vZHVsZXMvQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zcmMvc2VydmVyL2luZGV4LnRzIiwgIi4uL25vZGVfbW9kdWxlcy9AbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NyYy9zZXJ2ZXIvc3RkaW8udHMiLCAiLi4vbm9kZV9tb2R1bGVzL0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc3JjL3NoYXJlZC9zdGRpby50cyIsICIuLi9zcmMvdG9vbHMvaW5kZXgubWpzIiwgIi4uL3NyYy9ydW4tbHVhLm1qcyIsICIuLi9zcmMvdG9vbHMvbGlzdC1hZ2VudHMubWpzIiwgIi4uL3NyYy90b29scy9nZXQtYWdlbnQubWpzIiwgIi4uL3NyYy9hdXRoLm1qcyIsICIuLi9zcmMvYXBpLWNsaWVudC5tanMiLCAiLi4vc3JjL3Jlc3BvbnNlLXNoYXBlcy5tanMiLCAiLi4vc3JjL3Rvb2xzL2xpc3QtcHJpbWl0aXZlLXZlcnNpb25zLm1qcyIsICIuLi9zcmMvdG9vbHMvZ2V0LWRlcGxveW1lbnQtc3RhdHVzLm1qcyIsICIuLi9zcmMvdG9vbHMvdGFpbC1sb2dzLm1qcyIsICIuLi9zcmMvc2VydmVyLm1qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0ICogZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9oZWxwZXJzL3BhcnNlVXRpbC5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vaGVscGVycy90eXBlQWxpYXNlcy5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vaGVscGVycy91dGlsLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlcy5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vWm9kRXJyb3IuanNcIjtcbiIsICJleHBvcnQgdmFyIHV0aWw7XG4oZnVuY3Rpb24gKHV0aWwpIHtcbiAgICB1dGlsLmFzc2VydEVxdWFsID0gKF8pID0+IHsgfTtcbiAgICBmdW5jdGlvbiBhc3NlcnRJcyhfYXJnKSB7IH1cbiAgICB1dGlsLmFzc2VydElzID0gYXNzZXJ0SXM7XG4gICAgZnVuY3Rpb24gYXNzZXJ0TmV2ZXIoX3gpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfVxuICAgIHV0aWwuYXNzZXJ0TmV2ZXIgPSBhc3NlcnROZXZlcjtcbiAgICB1dGlsLmFycmF5VG9FbnVtID0gKGl0ZW1zKSA9PiB7XG4gICAgICAgIGNvbnN0IG9iaiA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgICAgIG9ialtpdGVtXSA9IGl0ZW07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9O1xuICAgIHV0aWwuZ2V0VmFsaWRFbnVtVmFsdWVzID0gKG9iaikgPT4ge1xuICAgICAgICBjb25zdCB2YWxpZEtleXMgPSB1dGlsLm9iamVjdEtleXMob2JqKS5maWx0ZXIoKGspID0+IHR5cGVvZiBvYmpbb2JqW2tdXSAhPT0gXCJudW1iZXJcIik7XG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0ge307XG4gICAgICAgIGZvciAoY29uc3QgayBvZiB2YWxpZEtleXMpIHtcbiAgICAgICAgICAgIGZpbHRlcmVkW2tdID0gb2JqW2tdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1dGlsLm9iamVjdFZhbHVlcyhmaWx0ZXJlZCk7XG4gICAgfTtcbiAgICB1dGlsLm9iamVjdFZhbHVlcyA9IChvYmopID0+IHtcbiAgICAgICAgcmV0dXJuIHV0aWwub2JqZWN0S2V5cyhvYmopLm1hcChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIG9ialtlXTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICB1dGlsLm9iamVjdEtleXMgPSB0eXBlb2YgT2JqZWN0LmtleXMgPT09IFwiZnVuY3Rpb25cIiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGJhbi9iYW5cbiAgICAgICAgPyAob2JqKSA9PiBPYmplY3Qua2V5cyhvYmopIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgYmFuL2JhblxuICAgICAgICA6IChvYmplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGtleXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGtleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBrZXlzO1xuICAgICAgICB9O1xuICAgIHV0aWwuZmluZCA9IChhcnIsIGNoZWNrZXIpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGFycikge1xuICAgICAgICAgICAgaWYgKGNoZWNrZXIoaXRlbSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9O1xuICAgIHV0aWwuaXNJbnRlZ2VyID0gdHlwZW9mIE51bWJlci5pc0ludGVnZXIgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/ICh2YWwpID0+IE51bWJlci5pc0ludGVnZXIodmFsKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGJhbi9iYW5cbiAgICAgICAgOiAodmFsKSA9PiB0eXBlb2YgdmFsID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh2YWwpICYmIE1hdGguZmxvb3IodmFsKSA9PT0gdmFsO1xuICAgIGZ1bmN0aW9uIGpvaW5WYWx1ZXMoYXJyYXksIHNlcGFyYXRvciA9IFwiIHwgXCIpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5Lm1hcCgodmFsKSA9PiAodHlwZW9mIHZhbCA9PT0gXCJzdHJpbmdcIiA/IGAnJHt2YWx9J2AgOiB2YWwpKS5qb2luKHNlcGFyYXRvcik7XG4gICAgfVxuICAgIHV0aWwuam9pblZhbHVlcyA9IGpvaW5WYWx1ZXM7XG4gICAgdXRpbC5qc29uU3RyaW5naWZ5UmVwbGFjZXIgPSAoXywgdmFsdWUpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJiaWdpbnRcIikge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG59KSh1dGlsIHx8ICh1dGlsID0ge30pKTtcbmV4cG9ydCB2YXIgb2JqZWN0VXRpbDtcbihmdW5jdGlvbiAob2JqZWN0VXRpbCkge1xuICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXMgPSAoZmlyc3QsIHNlY29uZCkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uZmlyc3QsXG4gICAgICAgICAgICAuLi5zZWNvbmQsIC8vIHNlY29uZCBvdmVyd3JpdGVzIGZpcnN0XG4gICAgICAgIH07XG4gICAgfTtcbn0pKG9iamVjdFV0aWwgfHwgKG9iamVjdFV0aWwgPSB7fSkpO1xuZXhwb3J0IGNvbnN0IFpvZFBhcnNlZFR5cGUgPSB1dGlsLmFycmF5VG9FbnVtKFtcbiAgICBcInN0cmluZ1wiLFxuICAgIFwibmFuXCIsXG4gICAgXCJudW1iZXJcIixcbiAgICBcImludGVnZXJcIixcbiAgICBcImZsb2F0XCIsXG4gICAgXCJib29sZWFuXCIsXG4gICAgXCJkYXRlXCIsXG4gICAgXCJiaWdpbnRcIixcbiAgICBcInN5bWJvbFwiLFxuICAgIFwiZnVuY3Rpb25cIixcbiAgICBcInVuZGVmaW5lZFwiLFxuICAgIFwibnVsbFwiLFxuICAgIFwiYXJyYXlcIixcbiAgICBcIm9iamVjdFwiLFxuICAgIFwidW5rbm93blwiLFxuICAgIFwicHJvbWlzZVwiLFxuICAgIFwidm9pZFwiLFxuICAgIFwibmV2ZXJcIixcbiAgICBcIm1hcFwiLFxuICAgIFwic2V0XCIsXG5dKTtcbmV4cG9ydCBjb25zdCBnZXRQYXJzZWRUeXBlID0gKGRhdGEpID0+IHtcbiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7XG4gICAgc3dpdGNoICh0KSB7XG4gICAgICAgIGNhc2UgXCJ1bmRlZmluZWRcIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnVuZGVmaW5lZDtcbiAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc3RyaW5nO1xuICAgICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGEpID8gWm9kUGFyc2VkVHlwZS5uYW4gOiBab2RQYXJzZWRUeXBlLm51bWJlcjtcbiAgICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmJvb2xlYW47XG4gICAgICAgIGNhc2UgXCJmdW5jdGlvblwiOlxuICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuZnVuY3Rpb247XG4gICAgICAgIGNhc2UgXCJiaWdpbnRcIjpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmJpZ2ludDtcbiAgICAgICAgY2FzZSBcInN5bWJvbFwiOlxuICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc3ltYm9sO1xuICAgICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmFycmF5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5udWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEudGhlbiAmJiB0eXBlb2YgZGF0YS50aGVuID09PSBcImZ1bmN0aW9uXCIgJiYgZGF0YS5jYXRjaCAmJiB0eXBlb2YgZGF0YS5jYXRjaCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUucHJvbWlzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgTWFwICE9PSBcInVuZGVmaW5lZFwiICYmIGRhdGEgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5tYXA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIFNldCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkYXRhIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc2V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBEYXRlICE9PSBcInVuZGVmaW5lZFwiICYmIGRhdGEgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuZGF0ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLm9iamVjdDtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLnVua25vd247XG4gICAgfVxufTtcbiIsICJpbXBvcnQgeyB1dGlsIH0gZnJvbSBcIi4vaGVscGVycy91dGlsLmpzXCI7XG5leHBvcnQgY29uc3QgWm9kSXNzdWVDb2RlID0gdXRpbC5hcnJheVRvRW51bShbXG4gICAgXCJpbnZhbGlkX3R5cGVcIixcbiAgICBcImludmFsaWRfbGl0ZXJhbFwiLFxuICAgIFwiY3VzdG9tXCIsXG4gICAgXCJpbnZhbGlkX3VuaW9uXCIsXG4gICAgXCJpbnZhbGlkX3VuaW9uX2Rpc2NyaW1pbmF0b3JcIixcbiAgICBcImludmFsaWRfZW51bV92YWx1ZVwiLFxuICAgIFwidW5yZWNvZ25pemVkX2tleXNcIixcbiAgICBcImludmFsaWRfYXJndW1lbnRzXCIsXG4gICAgXCJpbnZhbGlkX3JldHVybl90eXBlXCIsXG4gICAgXCJpbnZhbGlkX2RhdGVcIixcbiAgICBcImludmFsaWRfc3RyaW5nXCIsXG4gICAgXCJ0b29fc21hbGxcIixcbiAgICBcInRvb19iaWdcIixcbiAgICBcImludmFsaWRfaW50ZXJzZWN0aW9uX3R5cGVzXCIsXG4gICAgXCJub3RfbXVsdGlwbGVfb2ZcIixcbiAgICBcIm5vdF9maW5pdGVcIixcbl0pO1xuZXhwb3J0IGNvbnN0IHF1b3RlbGVzc0pzb24gPSAob2JqKSA9PiB7XG4gICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KG9iaiwgbnVsbCwgMik7XG4gICAgcmV0dXJuIGpzb24ucmVwbGFjZSgvXCIoW15cIl0rKVwiOi9nLCBcIiQxOlwiKTtcbn07XG5leHBvcnQgY2xhc3MgWm9kRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgZ2V0IGVycm9ycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNzdWVzO1xuICAgIH1cbiAgICBjb25zdHJ1Y3Rvcihpc3N1ZXMpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5pc3N1ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5hZGRJc3N1ZSA9IChzdWIpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXNzdWVzID0gWy4uLnRoaXMuaXNzdWVzLCBzdWJdO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmFkZElzc3VlcyA9IChzdWJzID0gW10pID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXNzdWVzID0gWy4uLnRoaXMuaXNzdWVzLCAuLi5zdWJzXTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYWN0dWFsUHJvdG8gPSBuZXcudGFyZ2V0LnByb3RvdHlwZTtcbiAgICAgICAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGJhbi9iYW5cbiAgICAgICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBhY3R1YWxQcm90byk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9fcHJvdG9fXyA9IGFjdHVhbFByb3RvO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubmFtZSA9IFwiWm9kRXJyb3JcIjtcbiAgICAgICAgdGhpcy5pc3N1ZXMgPSBpc3N1ZXM7XG4gICAgfVxuICAgIGZvcm1hdChfbWFwcGVyKSB7XG4gICAgICAgIGNvbnN0IG1hcHBlciA9IF9tYXBwZXIgfHxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChpc3N1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc3N1ZS5tZXNzYWdlO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7IF9lcnJvcnM6IFtdIH07XG4gICAgICAgIGNvbnN0IHByb2Nlc3NFcnJvciA9IChlcnJvcikgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCBpc3N1ZSBvZiBlcnJvci5pc3N1ZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gXCJpbnZhbGlkX3VuaW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaXNzdWUudW5pb25FcnJvcnMubWFwKHByb2Nlc3NFcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzc3VlLmNvZGUgPT09IFwiaW52YWxpZF9yZXR1cm5fdHlwZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3NFcnJvcihpc3N1ZS5yZXR1cm5UeXBlRXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS5jb2RlID09PSBcImludmFsaWRfYXJndW1lbnRzXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLmFyZ3VtZW50c0Vycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUucGF0aC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZmllbGRFcnJvcnMuX2Vycm9ycy5wdXNoKG1hcHBlcihpc3N1ZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGN1cnIgPSBmaWVsZEVycm9ycztcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaSA8IGlzc3VlLnBhdGgubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbCA9IGlzc3VlLnBhdGhbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXJtaW5hbCA9IGkgPT09IGlzc3VlLnBhdGgubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGVybWluYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHsgX2Vycm9yczogW10gfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiAodHlwZW9mIGVsID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHsgX2Vycm9yczogW10gfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB9IGVsc2UgaWYgKHR5cGVvZiBlbCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgY29uc3QgZXJyb3JBcnJheTogYW55ID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBlcnJvckFycmF5Ll9lcnJvcnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgIGN1cnJbZWxdID0gY3VycltlbF0gfHwgZXJyb3JBcnJheTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHsgX2Vycm9yczogW10gfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyW2VsXS5fZXJyb3JzLnB1c2gobWFwcGVyKGlzc3VlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyID0gY3VycltlbF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpKys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHByb2Nlc3NFcnJvcih0aGlzKTtcbiAgICAgICAgcmV0dXJuIGZpZWxkRXJyb3JzO1xuICAgIH1cbiAgICBzdGF0aWMgYXNzZXJ0KHZhbHVlKSB7XG4gICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgWm9kRXJyb3IpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhIFpvZEVycm9yOiAke3ZhbHVlfWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXNzYWdlO1xuICAgIH1cbiAgICBnZXQgbWVzc2FnZSgpIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMuaXNzdWVzLCB1dGlsLmpzb25TdHJpbmdpZnlSZXBsYWNlciwgMik7XG4gICAgfVxuICAgIGdldCBpc0VtcHR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc3N1ZXMubGVuZ3RoID09PSAwO1xuICAgIH1cbiAgICBmbGF0dGVuKG1hcHBlciA9IChpc3N1ZSkgPT4gaXNzdWUubWVzc2FnZSkge1xuICAgICAgICBjb25zdCBmaWVsZEVycm9ycyA9IHt9O1xuICAgICAgICBjb25zdCBmb3JtRXJyb3JzID0gW107XG4gICAgICAgIGZvciAoY29uc3Qgc3ViIG9mIHRoaXMuaXNzdWVzKSB7XG4gICAgICAgICAgICBpZiAoc3ViLnBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0RWwgPSBzdWIucGF0aFswXTtcbiAgICAgICAgICAgICAgICBmaWVsZEVycm9yc1tmaXJzdEVsXSA9IGZpZWxkRXJyb3JzW2ZpcnN0RWxdIHx8IFtdO1xuICAgICAgICAgICAgICAgIGZpZWxkRXJyb3JzW2ZpcnN0RWxdLnB1c2gobWFwcGVyKHN1YikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9ybUVycm9ycy5wdXNoKG1hcHBlcihzdWIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBmb3JtRXJyb3JzLCBmaWVsZEVycm9ycyB9O1xuICAgIH1cbiAgICBnZXQgZm9ybUVycm9ycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmxhdHRlbigpO1xuICAgIH1cbn1cblpvZEVycm9yLmNyZWF0ZSA9IChpc3N1ZXMpID0+IHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihpc3N1ZXMpO1xuICAgIHJldHVybiBlcnJvcjtcbn07XG4iLCAiaW1wb3J0IHsgWm9kSXNzdWVDb2RlIH0gZnJvbSBcIi4uL1pvZEVycm9yLmpzXCI7XG5pbXBvcnQgeyB1dGlsLCBab2RQYXJzZWRUeXBlIH0gZnJvbSBcIi4uL2hlbHBlcnMvdXRpbC5qc1wiO1xuY29uc3QgZXJyb3JNYXAgPSAoaXNzdWUsIF9jdHgpID0+IHtcbiAgICBsZXQgbWVzc2FnZTtcbiAgICBzd2l0Y2ggKGlzc3VlLmNvZGUpIHtcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlOlxuICAgICAgICAgICAgaWYgKGlzc3VlLnJlY2VpdmVkID09PSBab2RQYXJzZWRUeXBlLnVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBcIlJlcXVpcmVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gYEV4cGVjdGVkICR7aXNzdWUuZXhwZWN0ZWR9LCByZWNlaXZlZCAke2lzc3VlLnJlY2VpdmVkfWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9saXRlcmFsOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGxpdGVyYWwgdmFsdWUsIGV4cGVjdGVkICR7SlNPTi5zdHJpbmdpZnkoaXNzdWUuZXhwZWN0ZWQsIHV0aWwuanNvblN0cmluZ2lmeVJlcGxhY2VyKX1gO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLnVucmVjb2duaXplZF9rZXlzOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBVbnJlY29nbml6ZWQga2V5KHMpIGluIG9iamVjdDogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgXCIsIFwiKX1gO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb246XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXRgO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb25fZGlzY3JpbWluYXRvcjpcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBkaXNjcmltaW5hdG9yIHZhbHVlLiBFeHBlY3RlZCAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5vcHRpb25zKX1gO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfZW51bV92YWx1ZTpcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBlbnVtIHZhbHVlLiBFeHBlY3RlZCAke3V0aWwuam9pblZhbHVlcyhpc3N1ZS5vcHRpb25zKX0sIHJlY2VpdmVkICcke2lzc3VlLnJlY2VpdmVkfSdgO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfYXJndW1lbnRzOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIGFyZ3VtZW50c2A7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9yZXR1cm5fdHlwZTpcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBmdW5jdGlvbiByZXR1cm4gdHlwZWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9kYXRlOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGRhdGVgO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nOlxuICAgICAgICAgICAgaWYgKHR5cGVvZiBpc3N1ZS52YWxpZGF0aW9uID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKFwiaW5jbHVkZXNcIiBpbiBpc3N1ZS52YWxpZGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBpbnB1dDogbXVzdCBpbmNsdWRlIFwiJHtpc3N1ZS52YWxpZGF0aW9uLmluY2x1ZGVzfVwiYDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpc3N1ZS52YWxpZGF0aW9uLnBvc2l0aW9uID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gYCR7bWVzc2FnZX0gYXQgb25lIG9yIG1vcmUgcG9zaXRpb25zIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAke2lzc3VlLnZhbGlkYXRpb24ucG9zaXRpb259YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChcInN0YXJ0c1dpdGhcIiBpbiBpc3N1ZS52YWxpZGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBpbnB1dDogbXVzdCBzdGFydCB3aXRoIFwiJHtpc3N1ZS52YWxpZGF0aW9uLnN0YXJ0c1dpdGh9XCJgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChcImVuZHNXaXRoXCIgaW4gaXNzdWUudmFsaWRhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXQ6IG11c3QgZW5kIHdpdGggXCIke2lzc3VlLnZhbGlkYXRpb24uZW5kc1dpdGh9XCJgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5hc3NlcnROZXZlcihpc3N1ZS52YWxpZGF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS52YWxpZGF0aW9uICE9PSBcInJlZ2V4XCIpIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgJHtpc3N1ZS52YWxpZGF0aW9ufWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gXCJJbnZhbGlkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX3NtYWxsOlxuICAgICAgICAgICAgaWYgKGlzc3VlLnR5cGUgPT09IFwiYXJyYXlcIilcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gYEFycmF5IG11c3QgY29udGFpbiAke2lzc3VlLmV4YWN0ID8gXCJleGFjdGx5XCIgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgYXQgbGVhc3RgIDogYG1vcmUgdGhhbmB9ICR7aXNzdWUubWluaW11bX0gZWxlbWVudChzKWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgU3RyaW5nIG11c3QgY29udGFpbiAke2lzc3VlLmV4YWN0ID8gXCJleGFjdGx5XCIgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgYXQgbGVhc3RgIDogYG92ZXJgfSAke2lzc3VlLm1pbmltdW19IGNoYXJhY3RlcihzKWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgTnVtYmVyIG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5IGVxdWFsIHRvIGAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGAgOiBgZ3JlYXRlciB0aGFuIGB9JHtpc3N1ZS5taW5pbXVtfWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcImJpZ2ludFwiKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgTnVtYmVyIG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5IGVxdWFsIHRvIGAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGAgOiBgZ3JlYXRlciB0aGFuIGB9JHtpc3N1ZS5taW5pbXVtfWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcImRhdGVcIilcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gYERhdGUgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHkgZXF1YWwgdG8gYCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYCA6IGBncmVhdGVyIHRoYW4gYH0ke25ldyBEYXRlKE51bWJlcihpc3N1ZS5taW5pbXVtKSl9YDtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gXCJJbnZhbGlkIGlucHV0XCI7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX2JpZzpcbiAgICAgICAgICAgIGlmIChpc3N1ZS50eXBlID09PSBcImFycmF5XCIpXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBtb3N0YCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19IGVsZW1lbnQocylgO1xuICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gYFN0cmluZyBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBtb3N0YCA6IGB1bmRlcmB9ICR7aXNzdWUubWF4aW11bX0gY2hhcmFjdGVyKHMpYDtcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBOdW1iZXIgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHlgIDogaXNzdWUuaW5jbHVzaXZlID8gYGxlc3MgdGhhbiBvciBlcXVhbCB0b2AgOiBgbGVzcyB0aGFuYH0gJHtpc3N1ZS5tYXhpbXVtfWA7XG4gICAgICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSBcImJpZ2ludFwiKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgQmlnSW50IG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBsZXNzIHRoYW4gb3IgZXF1YWwgdG9gIDogYGxlc3MgdGhhbmB9ICR7aXNzdWUubWF4aW11bX1gO1xuICAgICAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gXCJkYXRlXCIpXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBEYXRlIG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBzbWFsbGVyIHRoYW4gb3IgZXF1YWwgdG9gIDogYHNtYWxsZXIgdGhhbmB9ICR7bmV3IERhdGUoTnVtYmVyKGlzc3VlLm1heGltdW0pKX1gO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBcIkludmFsaWQgaW5wdXRcIjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5jdXN0b206XG4gICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXRgO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfaW50ZXJzZWN0aW9uX3R5cGVzOlxuICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnRlcnNlY3Rpb24gcmVzdWx0cyBjb3VsZCBub3QgYmUgbWVyZ2VkYDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2Y6XG4gICAgICAgICAgICBtZXNzYWdlID0gYE51bWJlciBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgJHtpc3N1ZS5tdWx0aXBsZU9mfWA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X2Zpbml0ZTpcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBcIk51bWJlciBtdXN0IGJlIGZpbml0ZVwiO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBtZXNzYWdlID0gX2N0eC5kZWZhdWx0RXJyb3I7XG4gICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGlzc3VlKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgbWVzc2FnZSB9O1xufTtcbmV4cG9ydCBkZWZhdWx0IGVycm9yTWFwO1xuIiwgImltcG9ydCBkZWZhdWx0RXJyb3JNYXAgZnJvbSBcIi4vbG9jYWxlcy9lbi5qc1wiO1xubGV0IG92ZXJyaWRlRXJyb3JNYXAgPSBkZWZhdWx0RXJyb3JNYXA7XG5leHBvcnQgeyBkZWZhdWx0RXJyb3JNYXAgfTtcbmV4cG9ydCBmdW5jdGlvbiBzZXRFcnJvck1hcChtYXApIHtcbiAgICBvdmVycmlkZUVycm9yTWFwID0gbWFwO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldEVycm9yTWFwKCkge1xuICAgIHJldHVybiBvdmVycmlkZUVycm9yTWFwO1xufVxuIiwgImltcG9ydCB7IGdldEVycm9yTWFwIH0gZnJvbSBcIi4uL2Vycm9ycy5qc1wiO1xuaW1wb3J0IGRlZmF1bHRFcnJvck1hcCBmcm9tIFwiLi4vbG9jYWxlcy9lbi5qc1wiO1xuZXhwb3J0IGNvbnN0IG1ha2VJc3N1ZSA9IChwYXJhbXMpID0+IHtcbiAgICBjb25zdCB7IGRhdGEsIHBhdGgsIGVycm9yTWFwcywgaXNzdWVEYXRhIH0gPSBwYXJhbXM7XG4gICAgY29uc3QgZnVsbFBhdGggPSBbLi4ucGF0aCwgLi4uKGlzc3VlRGF0YS5wYXRoIHx8IFtdKV07XG4gICAgY29uc3QgZnVsbElzc3VlID0ge1xuICAgICAgICAuLi5pc3N1ZURhdGEsXG4gICAgICAgIHBhdGg6IGZ1bGxQYXRoLFxuICAgIH07XG4gICAgaWYgKGlzc3VlRGF0YS5tZXNzYWdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmlzc3VlRGF0YSxcbiAgICAgICAgICAgIHBhdGg6IGZ1bGxQYXRoLFxuICAgICAgICAgICAgbWVzc2FnZTogaXNzdWVEYXRhLm1lc3NhZ2UsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGxldCBlcnJvck1lc3NhZ2UgPSBcIlwiO1xuICAgIGNvbnN0IG1hcHMgPSBlcnJvck1hcHNcbiAgICAgICAgLmZpbHRlcigobSkgPT4gISFtKVxuICAgICAgICAuc2xpY2UoKVxuICAgICAgICAucmV2ZXJzZSgpO1xuICAgIGZvciAoY29uc3QgbWFwIG9mIG1hcHMpIHtcbiAgICAgICAgZXJyb3JNZXNzYWdlID0gbWFwKGZ1bGxJc3N1ZSwgeyBkYXRhLCBkZWZhdWx0RXJyb3I6IGVycm9yTWVzc2FnZSB9KS5tZXNzYWdlO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICAuLi5pc3N1ZURhdGEsXG4gICAgICAgIHBhdGg6IGZ1bGxQYXRoLFxuICAgICAgICBtZXNzYWdlOiBlcnJvck1lc3NhZ2UsXG4gICAgfTtcbn07XG5leHBvcnQgY29uc3QgRU1QVFlfUEFUSCA9IFtdO1xuZXhwb3J0IGZ1bmN0aW9uIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgaXNzdWVEYXRhKSB7XG4gICAgY29uc3Qgb3ZlcnJpZGVNYXAgPSBnZXRFcnJvck1hcCgpO1xuICAgIGNvbnN0IGlzc3VlID0gbWFrZUlzc3VlKHtcbiAgICAgICAgaXNzdWVEYXRhOiBpc3N1ZURhdGEsXG4gICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgZXJyb3JNYXBzOiBbXG4gICAgICAgICAgICBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCwgLy8gY29udGV4dHVhbCBlcnJvciBtYXAgaXMgZmlyc3QgcHJpb3JpdHlcbiAgICAgICAgICAgIGN0eC5zY2hlbWFFcnJvck1hcCwgLy8gdGhlbiBzY2hlbWEtYm91bmQgbWFwIGlmIGF2YWlsYWJsZVxuICAgICAgICAgICAgb3ZlcnJpZGVNYXAsIC8vIHRoZW4gZ2xvYmFsIG92ZXJyaWRlIG1hcFxuICAgICAgICAgICAgb3ZlcnJpZGVNYXAgPT09IGRlZmF1bHRFcnJvck1hcCA/IHVuZGVmaW5lZCA6IGRlZmF1bHRFcnJvck1hcCwgLy8gdGhlbiBnbG9iYWwgZGVmYXVsdCBtYXBcbiAgICAgICAgXS5maWx0ZXIoKHgpID0+ICEheCksXG4gICAgfSk7XG4gICAgY3R4LmNvbW1vbi5pc3N1ZXMucHVzaChpc3N1ZSk7XG59XG5leHBvcnQgY2xhc3MgUGFyc2VTdGF0dXMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnZhbHVlID0gXCJ2YWxpZFwiO1xuICAgIH1cbiAgICBkaXJ0eSgpIHtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgPT09IFwidmFsaWRcIilcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBcImRpcnR5XCI7XG4gICAgfVxuICAgIGFib3J0KCkge1xuICAgICAgICBpZiAodGhpcy52YWx1ZSAhPT0gXCJhYm9ydGVkXCIpXG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gXCJhYm9ydGVkXCI7XG4gICAgfVxuICAgIHN0YXRpYyBtZXJnZUFycmF5KHN0YXR1cywgcmVzdWx0cykge1xuICAgICAgICBjb25zdCBhcnJheVZhbHVlID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcyBvZiByZXN1bHRzKSB7XG4gICAgICAgICAgICBpZiAocy5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgaWYgKHMuc3RhdHVzID09PSBcImRpcnR5XCIpXG4gICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICBhcnJheVZhbHVlLnB1c2gocy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBhcnJheVZhbHVlIH07XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyBtZXJnZU9iamVjdEFzeW5jKHN0YXR1cywgcGFpcnMpIHtcbiAgICAgICAgY29uc3Qgc3luY1BhaXJzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycykge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgcGFpci5rZXk7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHBhaXIudmFsdWU7XG4gICAgICAgICAgICBzeW5jUGFpcnMucHVzaCh7XG4gICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHN5bmNQYWlycyk7XG4gICAgfVxuICAgIHN0YXRpYyBtZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBwYWlycykge1xuICAgICAgICBjb25zdCBmaW5hbE9iamVjdCA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsga2V5LCB2YWx1ZSB9ID0gcGFpcjtcbiAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImFib3J0ZWRcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgIGlmICh2YWx1ZS5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgaWYgKGtleS5zdGF0dXMgPT09IFwiZGlydHlcIilcbiAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZS5zdGF0dXMgPT09IFwiZGlydHlcIilcbiAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIGlmIChrZXkudmFsdWUgIT09IFwiX19wcm90b19fXCIgJiYgKHR5cGVvZiB2YWx1ZS52YWx1ZSAhPT0gXCJ1bmRlZmluZWRcIiB8fCBwYWlyLmFsd2F5c1NldCkpIHtcbiAgICAgICAgICAgICAgICBmaW5hbE9iamVjdFtrZXkudmFsdWVdID0gdmFsdWUudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBmaW5hbE9iamVjdCB9O1xuICAgIH1cbn1cbmV4cG9ydCBjb25zdCBJTlZBTElEID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgc3RhdHVzOiBcImFib3J0ZWRcIixcbn0pO1xuZXhwb3J0IGNvbnN0IERJUlRZID0gKHZhbHVlKSA9PiAoeyBzdGF0dXM6IFwiZGlydHlcIiwgdmFsdWUgfSk7XG5leHBvcnQgY29uc3QgT0sgPSAodmFsdWUpID0+ICh7IHN0YXR1czogXCJ2YWxpZFwiLCB2YWx1ZSB9KTtcbmV4cG9ydCBjb25zdCBpc0Fib3J0ZWQgPSAoeCkgPT4geC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiO1xuZXhwb3J0IGNvbnN0IGlzRGlydHkgPSAoeCkgPT4geC5zdGF0dXMgPT09IFwiZGlydHlcIjtcbmV4cG9ydCBjb25zdCBpc1ZhbGlkID0gKHgpID0+IHguc3RhdHVzID09PSBcInZhbGlkXCI7XG5leHBvcnQgY29uc3QgaXNBc3luYyA9ICh4KSA9PiB0eXBlb2YgUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiB4IGluc3RhbmNlb2YgUHJvbWlzZTtcbiIsICJleHBvcnQgdmFyIGVycm9yVXRpbDtcbihmdW5jdGlvbiAoZXJyb3JVdGlsKSB7XG4gICAgZXJyb3JVdGlsLmVyclRvT2JqID0gKG1lc3NhZ2UpID0+IHR5cGVvZiBtZXNzYWdlID09PSBcInN0cmluZ1wiID8geyBtZXNzYWdlIH0gOiBtZXNzYWdlIHx8IHt9O1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50OlxuICAgIGVycm9yVXRpbC50b1N0cmluZyA9IChtZXNzYWdlKSA9PiB0eXBlb2YgbWVzc2FnZSA9PT0gXCJzdHJpbmdcIiA/IG1lc3NhZ2UgOiBtZXNzYWdlPy5tZXNzYWdlO1xufSkoZXJyb3JVdGlsIHx8IChlcnJvclV0aWwgPSB7fSkpO1xuIiwgImltcG9ydCB7IFpvZEVycm9yLCBab2RJc3N1ZUNvZGUsIH0gZnJvbSBcIi4vWm9kRXJyb3IuanNcIjtcbmltcG9ydCB7IGRlZmF1bHRFcnJvck1hcCwgZ2V0RXJyb3JNYXAgfSBmcm9tIFwiLi9lcnJvcnMuanNcIjtcbmltcG9ydCB7IGVycm9yVXRpbCB9IGZyb20gXCIuL2hlbHBlcnMvZXJyb3JVdGlsLmpzXCI7XG5pbXBvcnQgeyBESVJUWSwgSU5WQUxJRCwgT0ssIFBhcnNlU3RhdHVzLCBhZGRJc3N1ZVRvQ29udGV4dCwgaXNBYm9ydGVkLCBpc0FzeW5jLCBpc0RpcnR5LCBpc1ZhbGlkLCBtYWtlSXNzdWUsIH0gZnJvbSBcIi4vaGVscGVycy9wYXJzZVV0aWwuanNcIjtcbmltcG9ydCB7IHV0aWwsIFpvZFBhcnNlZFR5cGUsIGdldFBhcnNlZFR5cGUgfSBmcm9tIFwiLi9oZWxwZXJzL3V0aWwuanNcIjtcbmNsYXNzIFBhcnNlSW5wdXRMYXp5UGF0aCB7XG4gICAgY29uc3RydWN0b3IocGFyZW50LCB2YWx1ZSwgcGF0aCwga2V5KSB7XG4gICAgICAgIHRoaXMuX2NhY2hlZFBhdGggPSBbXTtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIHRoaXMuZGF0YSA9IHZhbHVlO1xuICAgICAgICB0aGlzLl9wYXRoID0gcGF0aDtcbiAgICAgICAgdGhpcy5fa2V5ID0ga2V5O1xuICAgIH1cbiAgICBnZXQgcGF0aCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9jYWNoZWRQYXRoLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5fa2V5KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlZFBhdGgucHVzaCguLi50aGlzLl9wYXRoLCAuLi50aGlzLl9rZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVkUGF0aC5wdXNoKC4uLnRoaXMuX3BhdGgsIHRoaXMuX2tleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZFBhdGg7XG4gICAgfVxufVxuY29uc3QgaGFuZGxlUmVzdWx0ID0gKGN0eCwgcmVzdWx0KSA9PiB7XG4gICAgaWYgKGlzVmFsaWQocmVzdWx0KSkge1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBkYXRhOiByZXN1bHQudmFsdWUgfTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmICghY3R4LmNvbW1vbi5pc3N1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJWYWxpZGF0aW9uIGZhaWxlZCBidXQgbm8gaXNzdWVzIGRldGVjdGVkLlwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBnZXQgZXJyb3IoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2Vycm9yKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3I7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgWm9kRXJyb3IoY3R4LmNvbW1vbi5pc3N1ZXMpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2Vycm9yID0gZXJyb3I7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9XG59O1xuZnVuY3Rpb24gcHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpIHtcbiAgICBpZiAoIXBhcmFtcylcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIGNvbnN0IHsgZXJyb3JNYXAsIGludmFsaWRfdHlwZV9lcnJvciwgcmVxdWlyZWRfZXJyb3IsIGRlc2NyaXB0aW9uIH0gPSBwYXJhbXM7XG4gICAgaWYgKGVycm9yTWFwICYmIChpbnZhbGlkX3R5cGVfZXJyb3IgfHwgcmVxdWlyZWRfZXJyb3IpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgdXNlIFwiaW52YWxpZF90eXBlX2Vycm9yXCIgb3IgXCJyZXF1aXJlZF9lcnJvclwiIGluIGNvbmp1bmN0aW9uIHdpdGggY3VzdG9tIGVycm9yIG1hcC5gKTtcbiAgICB9XG4gICAgaWYgKGVycm9yTWFwKVxuICAgICAgICByZXR1cm4geyBlcnJvck1hcDogZXJyb3JNYXAsIGRlc2NyaXB0aW9uIH07XG4gICAgY29uc3QgY3VzdG9tTWFwID0gKGlzcywgY3R4KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgbWVzc2FnZSB9ID0gcGFyYW1zO1xuICAgICAgICBpZiAoaXNzLmNvZGUgPT09IFwiaW52YWxpZF9lbnVtX3ZhbHVlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB7IG1lc3NhZ2U6IG1lc3NhZ2UgPz8gY3R4LmRlZmF1bHRFcnJvciB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgY3R4LmRhdGEgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB7IG1lc3NhZ2U6IG1lc3NhZ2UgPz8gcmVxdWlyZWRfZXJyb3IgPz8gY3R4LmRlZmF1bHRFcnJvciB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc3MuY29kZSAhPT0gXCJpbnZhbGlkX3R5cGVcIilcbiAgICAgICAgICAgIHJldHVybiB7IG1lc3NhZ2U6IGN0eC5kZWZhdWx0RXJyb3IgfTtcbiAgICAgICAgcmV0dXJuIHsgbWVzc2FnZTogbWVzc2FnZSA/PyBpbnZhbGlkX3R5cGVfZXJyb3IgPz8gY3R4LmRlZmF1bHRFcnJvciB9O1xuICAgIH07XG4gICAgcmV0dXJuIHsgZXJyb3JNYXA6IGN1c3RvbU1hcCwgZGVzY3JpcHRpb24gfTtcbn1cbmV4cG9ydCBjbGFzcyBab2RUeXBlIHtcbiAgICBnZXQgZGVzY3JpcHRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuZGVzY3JpcHRpb247XG4gICAgfVxuICAgIF9nZXRUeXBlKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBnZXRQYXJzZWRUeXBlKGlucHV0LmRhdGEpO1xuICAgIH1cbiAgICBfZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCkge1xuICAgICAgICByZXR1cm4gKGN0eCB8fCB7XG4gICAgICAgICAgICBjb21tb246IGlucHV0LnBhcmVudC5jb21tb24sXG4gICAgICAgICAgICBkYXRhOiBpbnB1dC5kYXRhLFxuICAgICAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShpbnB1dC5kYXRhKSxcbiAgICAgICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsXG4gICAgICAgICAgICBwYXRoOiBpbnB1dC5wYXRoLFxuICAgICAgICAgICAgcGFyZW50OiBpbnB1dC5wYXJlbnQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IG5ldyBQYXJzZVN0YXR1cygpLFxuICAgICAgICAgICAgY3R4OiB7XG4gICAgICAgICAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLFxuICAgICAgICAgICAgICAgIGRhdGE6IGlucHV0LmRhdGEsXG4gICAgICAgICAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShpbnB1dC5kYXRhKSxcbiAgICAgICAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLFxuICAgICAgICAgICAgICAgIHBhdGg6IGlucHV0LnBhdGgsXG4gICAgICAgICAgICAgICAgcGFyZW50OiBpbnB1dC5wYXJlbnQsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH1cbiAgICBfcGFyc2VTeW5jKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlKGlucHV0KTtcbiAgICAgICAgaWYgKGlzQXN5bmMocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY2hyb25vdXMgcGFyc2UgZW5jb3VudGVyZWQgcHJvbWlzZS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgX3BhcnNlQXN5bmMoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcGFyc2UoaW5wdXQpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgfVxuICAgIHBhcnNlKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnNhZmVQYXJzZShkYXRhLCBwYXJhbXMpO1xuICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LmRhdGE7XG4gICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICB9XG4gICAgc2FmZVBhcnNlKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCBjdHggPSB7XG4gICAgICAgICAgICBjb21tb246IHtcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGFzeW5jOiBwYXJhbXM/LmFzeW5jID8/IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNvbnRleHR1YWxFcnJvck1hcDogcGFyYW1zPy5lcnJvck1hcCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYXRoOiBwYXJhbXM/LnBhdGggfHwgW10sXG4gICAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLFxuICAgICAgICAgICAgcGFyZW50OiBudWxsLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoZGF0YSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlU3luYyh7IGRhdGEsIHBhdGg6IGN0eC5wYXRoLCBwYXJlbnQ6IGN0eCB9KTtcbiAgICAgICAgcmV0dXJuIGhhbmRsZVJlc3VsdChjdHgsIHJlc3VsdCk7XG4gICAgfVxuICAgIFwifnZhbGlkYXRlXCIoZGF0YSkge1xuICAgICAgICBjb25zdCBjdHggPSB7XG4gICAgICAgICAgICBjb21tb246IHtcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGFzeW5jOiAhIXRoaXNbXCJ+c3RhbmRhcmRcIl0uYXN5bmMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGF0aDogW10sXG4gICAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLFxuICAgICAgICAgICAgcGFyZW50OiBudWxsLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoZGF0YSksXG4gICAgICAgIH07XG4gICAgICAgIGlmICghdGhpc1tcIn5zdGFuZGFyZFwiXS5hc3luYykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9wYXJzZVN5bmMoeyBkYXRhLCBwYXRoOiBbXSwgcGFyZW50OiBjdHggfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWQocmVzdWx0KVxuICAgICAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiByZXN1bHQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc3N1ZXM6IGN0eC5jb21tb24uaXNzdWVzLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChlcnI/Lm1lc3NhZ2U/LnRvTG93ZXJDYXNlKCk/LmluY2x1ZGVzKFwiZW5jb3VudGVyZWRcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tcIn5zdGFuZGFyZFwiXS5hc3luYyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGN0eC5jb21tb24gPSB7XG4gICAgICAgICAgICAgICAgICAgIGlzc3VlczogW10sXG4gICAgICAgICAgICAgICAgICAgIGFzeW5jOiB0cnVlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnNlQXN5bmMoeyBkYXRhLCBwYXRoOiBbXSwgcGFyZW50OiBjdHggfSkudGhlbigocmVzdWx0KSA9PiBpc1ZhbGlkKHJlc3VsdClcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIHZhbHVlOiByZXN1bHQudmFsdWUsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IGN0eC5jb21tb24uaXNzdWVzLFxuICAgICAgICAgICAgfSk7XG4gICAgfVxuICAgIGFzeW5jIHBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc2FmZVBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKTtcbiAgICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5kYXRhO1xuICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgfVxuICAgIGFzeW5jIHNhZmVQYXJzZUFzeW5jKGRhdGEsIHBhcmFtcykge1xuICAgICAgICBjb25zdCBjdHggPSB7XG4gICAgICAgICAgICBjb21tb246IHtcbiAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdLFxuICAgICAgICAgICAgICAgIGNvbnRleHR1YWxFcnJvck1hcDogcGFyYW1zPy5lcnJvck1hcCxcbiAgICAgICAgICAgICAgICBhc3luYzogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYXRoOiBwYXJhbXM/LnBhdGggfHwgW10sXG4gICAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLFxuICAgICAgICAgICAgcGFyZW50OiBudWxsLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoZGF0YSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG1heWJlQXN5bmNSZXN1bHQgPSB0aGlzLl9wYXJzZSh7IGRhdGEsIHBhdGg6IGN0eC5wYXRoLCBwYXJlbnQ6IGN0eCB9KTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgKGlzQXN5bmMobWF5YmVBc3luY1Jlc3VsdCkgPyBtYXliZUFzeW5jUmVzdWx0IDogUHJvbWlzZS5yZXNvbHZlKG1heWJlQXN5bmNSZXN1bHQpKTtcbiAgICAgICAgcmV0dXJuIGhhbmRsZVJlc3VsdChjdHgsIHJlc3VsdCk7XG4gICAgfVxuICAgIHJlZmluZShjaGVjaywgbWVzc2FnZSkge1xuICAgICAgICBjb25zdCBnZXRJc3N1ZVByb3BlcnRpZXMgPSAodmFsKSA9PiB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09IFwic3RyaW5nXCIgfHwgdHlwZW9mIG1lc3NhZ2UgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBtZXNzYWdlIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2UodmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVmaW5lbWVudCgodmFsLCBjdHgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNoZWNrKHZhbCk7XG4gICAgICAgICAgICBjb25zdCBzZXRFcnJvciA9ICgpID0+IGN0eC5hZGRJc3N1ZSh7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmN1c3RvbSxcbiAgICAgICAgICAgICAgICAuLi5nZXRJc3N1ZVByb3BlcnRpZXModmFsKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBQcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnRoZW4oKGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgc2V0RXJyb3IoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlZmluZW1lbnQoY2hlY2ssIHJlZmluZW1lbnREYXRhKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWZpbmVtZW50KCh2YWwsIGN0eCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFjaGVjayh2YWwpKSB7XG4gICAgICAgICAgICAgICAgY3R4LmFkZElzc3VlKHR5cGVvZiByZWZpbmVtZW50RGF0YSA9PT0gXCJmdW5jdGlvblwiID8gcmVmaW5lbWVudERhdGEodmFsLCBjdHgpIDogcmVmaW5lbWVudERhdGEpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgX3JlZmluZW1lbnQocmVmaW5lbWVudCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEVmZmVjdHMoe1xuICAgICAgICAgICAgc2NoZW1hOiB0aGlzLFxuICAgICAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFZmZlY3RzLFxuICAgICAgICAgICAgZWZmZWN0OiB7IHR5cGU6IFwicmVmaW5lbWVudFwiLCByZWZpbmVtZW50IH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdXBlclJlZmluZShyZWZpbmVtZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWZpbmVtZW50KHJlZmluZW1lbnQpO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcihkZWYpIHtcbiAgICAgICAgLyoqIEFsaWFzIG9mIHNhZmVQYXJzZUFzeW5jICovXG4gICAgICAgIHRoaXMuc3BhID0gdGhpcy5zYWZlUGFyc2VBc3luYztcbiAgICAgICAgdGhpcy5fZGVmID0gZGVmO1xuICAgICAgICB0aGlzLnBhcnNlID0gdGhpcy5wYXJzZS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNhZmVQYXJzZSA9IHRoaXMuc2FmZVBhcnNlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMucGFyc2VBc3luYyA9IHRoaXMucGFyc2VBc3luYy5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNhZmVQYXJzZUFzeW5jID0gdGhpcy5zYWZlUGFyc2VBc3luYy5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnNwYSA9IHRoaXMuc3BhLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMucmVmaW5lID0gdGhpcy5yZWZpbmUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5yZWZpbmVtZW50ID0gdGhpcy5yZWZpbmVtZW50LmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuc3VwZXJSZWZpbmUgPSB0aGlzLnN1cGVyUmVmaW5lLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMub3B0aW9uYWwgPSB0aGlzLm9wdGlvbmFsLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMubnVsbGFibGUgPSB0aGlzLm51bGxhYmxlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMubnVsbGlzaCA9IHRoaXMubnVsbGlzaC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmFycmF5ID0gdGhpcy5hcnJheS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnByb21pc2UgPSB0aGlzLnByb21pc2UuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5vciA9IHRoaXMub3IuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5hbmQgPSB0aGlzLmFuZC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnRyYW5zZm9ybSA9IHRoaXMudHJhbnNmb3JtLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuYnJhbmQgPSB0aGlzLmJyYW5kLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZGVmYXVsdCA9IHRoaXMuZGVmYXVsdC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmNhdGNoID0gdGhpcy5jYXRjaC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmRlc2NyaWJlID0gdGhpcy5kZXNjcmliZS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnBpcGUgPSB0aGlzLnBpcGUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5yZWFkb25seSA9IHRoaXMucmVhZG9ubHkuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5pc051bGxhYmxlID0gdGhpcy5pc051bGxhYmxlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuaXNPcHRpb25hbCA9IHRoaXMuaXNPcHRpb25hbC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzW1wifnN0YW5kYXJkXCJdID0ge1xuICAgICAgICAgICAgdmVyc2lvbjogMSxcbiAgICAgICAgICAgIHZlbmRvcjogXCJ6b2RcIixcbiAgICAgICAgICAgIHZhbGlkYXRlOiAoZGF0YSkgPT4gdGhpc1tcIn52YWxpZGF0ZVwiXShkYXRhKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgb3B0aW9uYWwoKSB7XG4gICAgICAgIHJldHVybiBab2RPcHRpb25hbC5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTtcbiAgICB9XG4gICAgbnVsbGFibGUoKSB7XG4gICAgICAgIHJldHVybiBab2ROdWxsYWJsZS5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTtcbiAgICB9XG4gICAgbnVsbGlzaCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubnVsbGFibGUoKS5vcHRpb25hbCgpO1xuICAgIH1cbiAgICBhcnJheSgpIHtcbiAgICAgICAgcmV0dXJuIFpvZEFycmF5LmNyZWF0ZSh0aGlzKTtcbiAgICB9XG4gICAgcHJvbWlzZSgpIHtcbiAgICAgICAgcmV0dXJuIFpvZFByb21pc2UuY3JlYXRlKHRoaXMsIHRoaXMuX2RlZik7XG4gICAgfVxuICAgIG9yKG9wdGlvbikge1xuICAgICAgICByZXR1cm4gWm9kVW5pb24uY3JlYXRlKFt0aGlzLCBvcHRpb25dLCB0aGlzLl9kZWYpO1xuICAgIH1cbiAgICBhbmQoaW5jb21pbmcpIHtcbiAgICAgICAgcmV0dXJuIFpvZEludGVyc2VjdGlvbi5jcmVhdGUodGhpcywgaW5jb21pbmcsIHRoaXMuX2RlZik7XG4gICAgfVxuICAgIHRyYW5zZm9ybSh0cmFuc2Zvcm0pIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RFZmZlY3RzKHtcbiAgICAgICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKSxcbiAgICAgICAgICAgIHNjaGVtYTogdGhpcyxcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0cyxcbiAgICAgICAgICAgIGVmZmVjdDogeyB0eXBlOiBcInRyYW5zZm9ybVwiLCB0cmFuc2Zvcm0gfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRlZmF1bHQoZGVmKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZUZ1bmMgPSB0eXBlb2YgZGVmID09PSBcImZ1bmN0aW9uXCIgPyBkZWYgOiAoKSA9PiBkZWY7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRGVmYXVsdCh7XG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXMuX2RlZiksXG4gICAgICAgICAgICBpbm5lclR5cGU6IHRoaXMsXG4gICAgICAgICAgICBkZWZhdWx0VmFsdWU6IGRlZmF1bHRWYWx1ZUZ1bmMsXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERlZmF1bHQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBicmFuZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RCcmFuZGVkKHtcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQnJhbmRlZCxcbiAgICAgICAgICAgIHR5cGU6IHRoaXMsXG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHRoaXMuX2RlZiksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjYXRjaChkZWYpIHtcbiAgICAgICAgY29uc3QgY2F0Y2hWYWx1ZUZ1bmMgPSB0eXBlb2YgZGVmID09PSBcImZ1bmN0aW9uXCIgPyBkZWYgOiAoKSA9PiBkZWY7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goe1xuICAgICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyh0aGlzLl9kZWYpLFxuICAgICAgICAgICAgaW5uZXJUeXBlOiB0aGlzLFxuICAgICAgICAgICAgY2F0Y2hWYWx1ZTogY2F0Y2hWYWx1ZUZ1bmMsXG4gICAgICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZENhdGNoLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGVzY3JpYmUoZGVzY3JpcHRpb24pIHtcbiAgICAgICAgY29uc3QgVGhpcyA9IHRoaXMuY29uc3RydWN0b3I7XG4gICAgICAgIHJldHVybiBuZXcgVGhpcyh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHBpcGUodGFyZ2V0KSB7XG4gICAgICAgIHJldHVybiBab2RQaXBlbGluZS5jcmVhdGUodGhpcywgdGFyZ2V0KTtcbiAgICB9XG4gICAgcmVhZG9ubHkoKSB7XG4gICAgICAgIHJldHVybiBab2RSZWFkb25seS5jcmVhdGUodGhpcyk7XG4gICAgfVxuICAgIGlzT3B0aW9uYWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZSh1bmRlZmluZWQpLnN1Y2Nlc3M7XG4gICAgfVxuICAgIGlzTnVsbGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZShudWxsKS5zdWNjZXNzO1xuICAgIH1cbn1cbmNvbnN0IGN1aWRSZWdleCA9IC9eY1teXFxzLV17OCx9JC9pO1xuY29uc3QgY3VpZDJSZWdleCA9IC9eWzAtOWEtel0rJC87XG5jb25zdCB1bGlkUmVnZXggPSAvXlswLTlBLUhKS01OUC1UVi1aXXsyNn0kL2k7XG4vLyBjb25zdCB1dWlkUmVnZXggPVxuLy8gICAvXihbYS1mMC05XXs4fS1bYS1mMC05XXs0fS1bMS01XVthLWYwLTldezN9LVthLWYwLTldezR9LVthLWYwLTldezEyfXwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDApJC9pO1xuY29uc3QgdXVpZFJlZ2V4ID0gL15bMC05YS1mQS1GXXs4fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXs0fVxcYi1bMC05YS1mQS1GXXsxMn0kL2k7XG5jb25zdCBuYW5vaWRSZWdleCA9IC9eW2EtejAtOV8tXXsyMX0kL2k7XG5jb25zdCBqd3RSZWdleCA9IC9eW0EtWmEtejAtOS1fXStcXC5bQS1aYS16MC05LV9dK1xcLltBLVphLXowLTktX10qJC87XG5jb25zdCBkdXJhdGlvblJlZ2V4ID0gL15bLStdP1AoPyEkKSg/Oig/OlstK10/XFxkK1kpfCg/OlstK10/XFxkK1suLF1cXGQrWSQpKT8oPzooPzpbLStdP1xcZCtNKXwoPzpbLStdP1xcZCtbLixdXFxkK00kKSk/KD86KD86Wy0rXT9cXGQrVyl8KD86Wy0rXT9cXGQrWy4sXVxcZCtXJCkpPyg/Oig/OlstK10/XFxkK0QpfCg/OlstK10/XFxkK1suLF1cXGQrRCQpKT8oPzpUKD89W1xcZCstXSkoPzooPzpbLStdP1xcZCtIKXwoPzpbLStdP1xcZCtbLixdXFxkK0gkKSk/KD86KD86Wy0rXT9cXGQrTSl8KD86Wy0rXT9cXGQrWy4sXVxcZCtNJCkpPyg/OlstK10/XFxkKyg/OlsuLF1cXGQrKT9TKT8pPz8kLztcbi8vIGZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzQ2MTgxLzE1NTAxNTVcbi8vIG9sZCB2ZXJzaW9uOiB0b28gc2xvdywgZGlkbid0IHN1cHBvcnQgdW5pY29kZVxuLy8gY29uc3QgZW1haWxSZWdleCA9IC9eKCgoW2Etel18XFxkfFshI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9fl18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKyhcXC4oW2Etel18XFxkfFshI1xcJCUmJ1xcKlxcK1xcLVxcLz1cXD9cXF5fYHtcXHx9fl18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKykqKXwoKFxceDIyKSgoKChcXHgyMHxcXHgwOSkqKFxceDBkXFx4MGEpKT8oXFx4MjB8XFx4MDkpKyk/KChbXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHg3Zl18XFx4MjF8W1xceDIzLVxceDViXXxbXFx4NWQtXFx4N2VdfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKXwoXFxcXChbXFx4MDEtXFx4MDlcXHgwYlxceDBjXFx4MGQtXFx4N2ZdfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKSkpKSooKChcXHgyMHxcXHgwOSkqKFxceDBkXFx4MGEpKT8oXFx4MjB8XFx4MDkpKyk/KFxceDIyKSkpQCgoKFthLXpdfFxcZHxbXFx1MDBBMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSl8KChbYS16XXxcXGR8W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKFthLXpdfFxcZHwtfFxcLnxffH58W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKihbYS16XXxcXGR8W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKSlcXC4pKygoW2Etel18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pfCgoW2Etel18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKFthLXpdfFxcZHwtfFxcLnxffH58W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKihbYS16XXxbXFx1MDBBMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSkpKSQvaTtcbi8vb2xkIGVtYWlsIHJlZ2V4XG4vLyBjb25zdCBlbWFpbFJlZ2V4ID0gL14oKFtePD4oKVtcXF0uLDs6XFxzQFwiXSsoXFwuW148PigpW1xcXS4sOzpcXHNAXCJdKykqKXwoXCIuK1wiKSlAKCg/IS0pKFtePD4oKVtcXF0uLDs6XFxzQFwiXStcXC4pK1tePD4oKVtcXF0uLDs6XFxzQFwiXXsxLH0pW14tPD4oKVtcXF0uLDs6XFxzQFwiXSQvaTtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuLy8gY29uc3QgZW1haWxSZWdleCA9XG4vLyAgIC9eKChbXjw+KClbXFxdXFxcXC4sOzpcXHNAXFxcIl0rKFxcLltePD4oKVtcXF1cXFxcLiw7Olxcc0BcXFwiXSspKil8KFxcXCIuK1xcXCIpKUAoKFxcWygoKDI1WzAtNV0pfCgyWzAtNF1bMC05XSl8KDFbMC05XXsyfSl8KFswLTldezEsMn0pKVxcLil7M30oKDI1WzAtNV0pfCgyWzAtNF1bMC05XSl8KDFbMC05XXsyfSl8KFswLTldezEsMn0pKVxcXSl8KFxcW0lQdjY6KChbYS1mMC05XXsxLDR9Oil7N318OjooW2EtZjAtOV17MSw0fTopezAsNn18KFthLWYwLTldezEsNH06KXsxfTooW2EtZjAtOV17MSw0fTopezAsNX18KFthLWYwLTldezEsNH06KXsyfTooW2EtZjAtOV17MSw0fTopezAsNH18KFthLWYwLTldezEsNH06KXszfTooW2EtZjAtOV17MSw0fTopezAsM318KFthLWYwLTldezEsNH06KXs0fTooW2EtZjAtOV17MSw0fTopezAsMn18KFthLWYwLTldezEsNH06KXs1fTooW2EtZjAtOV17MSw0fTopezAsMX0pKFthLWYwLTldezEsNH18KCgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpXFwuKXszfSgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpKVxcXSl8KFtBLVphLXowLTldKFtBLVphLXowLTktXSpbQS1aYS16MC05XSkqKFxcLltBLVphLXpdezIsfSkrKSkkLztcbi8vIGNvbnN0IGVtYWlsUmVnZXggPVxuLy8gICAvXlthLXpBLVowLTlcXC5cXCFcXCNcXCRcXCVcXCZcXCdcXCpcXCtcXC9cXD1cXD9cXF5cXF9cXGBcXHtcXHxcXH1cXH5cXC1dK0BbYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8oPzpcXC5bYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8pKiQvO1xuLy8gY29uc3QgZW1haWxSZWdleCA9XG4vLyAgIC9eKD86W2EtejAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKyg/OlxcLlthLXowLTkhIyQlJicqKy89P15fYHt8fX4tXSspKnxcIig/OltcXHgwMS1cXHgwOFxceDBiXFx4MGNcXHgwZS1cXHgxZlxceDIxXFx4MjMtXFx4NWJcXHg1ZC1cXHg3Zl18XFxcXFtcXHgwMS1cXHgwOVxceDBiXFx4MGNcXHgwZS1cXHg3Zl0pKlwiKUAoPzooPzpbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/XFwuKStbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/fFxcWyg/Oig/OjI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldPylcXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldWzAtOV0/fFthLXowLTktXSpbYS16MC05XTooPzpbXFx4MDEtXFx4MDhcXHgwYlxceDBjXFx4MGUtXFx4MWZcXHgyMS1cXHg1YVxceDUzLVxceDdmXXxcXFxcW1xceDAxLVxceDA5XFx4MGJcXHgwY1xceDBlLVxceDdmXSkrKVxcXSkkL2k7XG5jb25zdCBlbWFpbFJlZ2V4ID0gL14oPyFcXC4pKD8hLipcXC5cXC4pKFtBLVowLTlfJytcXC1cXC5dKilbQS1aMC05XystXUAoW0EtWjAtOV1bQS1aMC05XFwtXSpcXC4pK1tBLVpdezIsfSQvaTtcbi8vIGNvbnN0IGVtYWlsUmVnZXggPVxuLy8gICAvXlthLXowLTkuISMkJSZcdTIwMTkqKy89P15fYHt8fX4tXStAW2EtejAtOS1dKyg/OlxcLlthLXowLTlcXC1dKykqJC9pO1xuLy8gZnJvbSBodHRwczovL3RoZWtldmluc2NvdHQuY29tL2Vtb2ppcy1pbi1qYXZhc2NyaXB0LyN3cml0aW5nLWEtcmVndWxhci1leHByZXNzaW9uXG5jb25zdCBfZW1vamlSZWdleCA9IGBeKFxcXFxwe0V4dGVuZGVkX1BpY3RvZ3JhcGhpY318XFxcXHB7RW1vamlfQ29tcG9uZW50fSkrJGA7XG5sZXQgZW1vamlSZWdleDtcbi8vIGZhc3Rlciwgc2ltcGxlciwgc2FmZXJcbmNvbnN0IGlwdjRSZWdleCA9IC9eKD86KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKVxcLil7M30oPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pJC87XG5jb25zdCBpcHY0Q2lkclJlZ2V4ID0gL14oPzooPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pXFwuKXszfSg/OjI1WzAtNV18MlswLTRdWzAtOV18MVswLTldWzAtOV18WzEtOV1bMC05XXxbMC05XSlcXC8oM1swLTJdfFsxMl0/WzAtOV0pJC87XG4vLyBjb25zdCBpcHY2UmVnZXggPVxuLy8gL14oKFthLWYwLTldezEsNH06KXs3fXw6OihbYS1mMC05XXsxLDR9Oil7MCw2fXwoW2EtZjAtOV17MSw0fTopezF9OihbYS1mMC05XXsxLDR9Oil7MCw1fXwoW2EtZjAtOV17MSw0fTopezJ9OihbYS1mMC05XXsxLDR9Oil7MCw0fXwoW2EtZjAtOV17MSw0fTopezN9OihbYS1mMC05XXsxLDR9Oil7MCwzfXwoW2EtZjAtOV17MSw0fTopezR9OihbYS1mMC05XXsxLDR9Oil7MCwyfXwoW2EtZjAtOV17MSw0fTopezV9OihbYS1mMC05XXsxLDR9Oil7MCwxfSkoW2EtZjAtOV17MSw0fXwoKCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSlcXC4pezN9KCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSkpJC87XG5jb25zdCBpcHY2UmVnZXggPSAvXigoWzAtOWEtZkEtRl17MSw0fTopezcsN31bMC05YS1mQS1GXXsxLDR9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw3fTp8KFswLTlhLWZBLUZdezEsNH06KXsxLDZ9OlswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDV9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDJ9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw0fSg6WzAtOWEtZkEtRl17MSw0fSl7MSwzfXwoWzAtOWEtZkEtRl17MSw0fTopezEsM30oOlswLTlhLWZBLUZdezEsNH0pezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDJ9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDV9fFswLTlhLWZBLUZdezEsNH06KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw2fSl8OigoOlswLTlhLWZBLUZdezEsNH0pezEsN318Oil8ZmU4MDooOlswLTlhLWZBLUZdezAsNH0pezAsNH0lWzAtOWEtekEtWl17MSx9fDo6KGZmZmYoOjB7MSw0fSl7MCwxfTopezAsMX0oKDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKVxcLil7MywzfSgyNVswLTVdfCgyWzAtNF18MXswLDF9WzAtOV0pezAsMX1bMC05XSl8KFswLTlhLWZBLUZdezEsNH06KXsxLDR9OigoMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pXFwuKXszLDN9KDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKSkkLztcbmNvbnN0IGlwdjZDaWRyUmVnZXggPSAvXigoWzAtOWEtZkEtRl17MSw0fTopezcsN31bMC05YS1mQS1GXXsxLDR9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw3fTp8KFswLTlhLWZBLUZdezEsNH06KXsxLDZ9OlswLTlhLWZBLUZdezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDV9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDJ9fChbMC05YS1mQS1GXXsxLDR9Oil7MSw0fSg6WzAtOWEtZkEtRl17MSw0fSl7MSwzfXwoWzAtOWEtZkEtRl17MSw0fTopezEsM30oOlswLTlhLWZBLUZdezEsNH0pezEsNH18KFswLTlhLWZBLUZdezEsNH06KXsxLDJ9KDpbMC05YS1mQS1GXXsxLDR9KXsxLDV9fFswLTlhLWZBLUZdezEsNH06KCg6WzAtOWEtZkEtRl17MSw0fSl7MSw2fSl8OigoOlswLTlhLWZBLUZdezEsNH0pezEsN318Oil8ZmU4MDooOlswLTlhLWZBLUZdezAsNH0pezAsNH0lWzAtOWEtekEtWl17MSx9fDo6KGZmZmYoOjB7MSw0fSl7MCwxfTopezAsMX0oKDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKVxcLil7MywzfSgyNVswLTVdfCgyWzAtNF18MXswLDF9WzAtOV0pezAsMX1bMC05XSl8KFswLTlhLWZBLUZdezEsNH06KXsxLDR9OigoMjVbMC01XXwoMlswLTRdfDF7MCwxfVswLTldKXswLDF9WzAtOV0pXFwuKXszLDN9KDI1WzAtNV18KDJbMC00XXwxezAsMX1bMC05XSl7MCwxfVswLTldKSlcXC8oMTJbMC04XXwxWzAxXVswLTldfFsxLTldP1swLTldKSQvO1xuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzg2MDM5Mi9kZXRlcm1pbmUtaWYtc3RyaW5nLWlzLWluLWJhc2U2NC11c2luZy1qYXZhc2NyaXB0XG5jb25zdCBiYXNlNjRSZWdleCA9IC9eKFswLTlhLXpBLVorL117NH0pKigoWzAtOWEtekEtWisvXXsyfT09KXwoWzAtOWEtekEtWisvXXszfT0pKT8kLztcbi8vIGh0dHBzOi8vYmFzZTY0Lmd1cnUvc3RhbmRhcmRzL2Jhc2U2NHVybFxuY29uc3QgYmFzZTY0dXJsUmVnZXggPSAvXihbMC05YS16QS1aLV9dezR9KSooKFswLTlhLXpBLVotX117Mn0oPT0pPyl8KFswLTlhLXpBLVotX117M30oPSk/KSk/JC87XG4vLyBzaW1wbGVcbi8vIGNvbnN0IGRhdGVSZWdleFNvdXJjZSA9IGBcXFxcZHs0fS1cXFxcZHsyfS1cXFxcZHsyfWA7XG4vLyBubyBsZWFwIHllYXIgdmFsaWRhdGlvblxuLy8gY29uc3QgZGF0ZVJlZ2V4U291cmNlID0gYFxcXFxkezR9LSgoMFsxMzU3OF18MTB8MTIpLTMxfCgwWzEzLTldfDFbMC0yXSktMzB8KDBbMS05XXwxWzAtMl0pLSgwWzEtOV18MVxcXFxkfDJcXFxcZCkpYDtcbi8vIHdpdGggbGVhcCB5ZWFyIHZhbGlkYXRpb25cbmNvbnN0IGRhdGVSZWdleFNvdXJjZSA9IGAoKFxcXFxkXFxcXGRbMjQ2OF1bMDQ4XXxcXFxcZFxcXFxkWzEzNTc5XVsyNl18XFxcXGRcXFxcZDBbNDhdfFswMjQ2OF1bMDQ4XTAwfFsxMzU3OV1bMjZdMDApLTAyLTI5fFxcXFxkezR9LSgoMFsxMzU3OF18MVswMl0pLSgwWzEtOV18WzEyXVxcXFxkfDNbMDFdKXwoMFs0NjldfDExKS0oMFsxLTldfFsxMl1cXFxcZHwzMCl8KDAyKS0oMFsxLTldfDFcXFxcZHwyWzAtOF0pKSlgO1xuY29uc3QgZGF0ZVJlZ2V4ID0gbmV3IFJlZ0V4cChgXiR7ZGF0ZVJlZ2V4U291cmNlfSRgKTtcbmZ1bmN0aW9uIHRpbWVSZWdleFNvdXJjZShhcmdzKSB7XG4gICAgbGV0IHNlY29uZHNSZWdleFNvdXJjZSA9IGBbMC01XVxcXFxkYDtcbiAgICBpZiAoYXJncy5wcmVjaXNpb24pIHtcbiAgICAgICAgc2Vjb25kc1JlZ2V4U291cmNlID0gYCR7c2Vjb25kc1JlZ2V4U291cmNlfVxcXFwuXFxcXGR7JHthcmdzLnByZWNpc2lvbn19YDtcbiAgICB9XG4gICAgZWxzZSBpZiAoYXJncy5wcmVjaXNpb24gPT0gbnVsbCkge1xuICAgICAgICBzZWNvbmRzUmVnZXhTb3VyY2UgPSBgJHtzZWNvbmRzUmVnZXhTb3VyY2V9KFxcXFwuXFxcXGQrKT9gO1xuICAgIH1cbiAgICBjb25zdCBzZWNvbmRzUXVhbnRpZmllciA9IGFyZ3MucHJlY2lzaW9uID8gXCIrXCIgOiBcIj9cIjsgLy8gcmVxdWlyZSBzZWNvbmRzIGlmIHByZWNpc2lvbiBpcyBub256ZXJvXG4gICAgcmV0dXJuIGAoWzAxXVxcXFxkfDJbMC0zXSk6WzAtNV1cXFxcZCg6JHtzZWNvbmRzUmVnZXhTb3VyY2V9KSR7c2Vjb25kc1F1YW50aWZpZXJ9YDtcbn1cbmZ1bmN0aW9uIHRpbWVSZWdleChhcmdzKSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke3RpbWVSZWdleFNvdXJjZShhcmdzKX0kYCk7XG59XG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzMxNDMyMzFcbmV4cG9ydCBmdW5jdGlvbiBkYXRldGltZVJlZ2V4KGFyZ3MpIHtcbiAgICBsZXQgcmVnZXggPSBgJHtkYXRlUmVnZXhTb3VyY2V9VCR7dGltZVJlZ2V4U291cmNlKGFyZ3MpfWA7XG4gICAgY29uc3Qgb3B0cyA9IFtdO1xuICAgIG9wdHMucHVzaChhcmdzLmxvY2FsID8gYFo/YCA6IGBaYCk7XG4gICAgaWYgKGFyZ3Mub2Zmc2V0KVxuICAgICAgICBvcHRzLnB1c2goYChbKy1dXFxcXGR7Mn06P1xcXFxkezJ9KWApO1xuICAgIHJlZ2V4ID0gYCR7cmVnZXh9KCR7b3B0cy5qb2luKFwifFwiKX0pYDtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChgXiR7cmVnZXh9JGApO1xufVxuZnVuY3Rpb24gaXNWYWxpZElQKGlwLCB2ZXJzaW9uKSB7XG4gICAgaWYgKCh2ZXJzaW9uID09PSBcInY0XCIgfHwgIXZlcnNpb24pICYmIGlwdjRSZWdleC50ZXN0KGlwKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCh2ZXJzaW9uID09PSBcInY2XCIgfHwgIXZlcnNpb24pICYmIGlwdjZSZWdleC50ZXN0KGlwKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gaXNWYWxpZEpXVChqd3QsIGFsZykge1xuICAgIGlmICghand0UmVnZXgudGVzdChqd3QpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgW2hlYWRlcl0gPSBqd3Quc3BsaXQoXCIuXCIpO1xuICAgICAgICBpZiAoIWhlYWRlcilcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gQ29udmVydCBiYXNlNjR1cmwgdG8gYmFzZTY0XG4gICAgICAgIGNvbnN0IGJhc2U2NCA9IGhlYWRlclxuICAgICAgICAgICAgLnJlcGxhY2UoLy0vZywgXCIrXCIpXG4gICAgICAgICAgICAucmVwbGFjZSgvXy9nLCBcIi9cIilcbiAgICAgICAgICAgIC5wYWRFbmQoaGVhZGVyLmxlbmd0aCArICgoNCAtIChoZWFkZXIubGVuZ3RoICUgNCkpICUgNCksIFwiPVwiKTtcbiAgICAgICAgY29uc3QgZGVjb2RlZCA9IEpTT04ucGFyc2UoYXRvYihiYXNlNjQpKTtcbiAgICAgICAgaWYgKHR5cGVvZiBkZWNvZGVkICE9PSBcIm9iamVjdFwiIHx8IGRlY29kZWQgPT09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChcInR5cFwiIGluIGRlY29kZWQgJiYgZGVjb2RlZD8udHlwICE9PSBcIkpXVFwiKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoIWRlY29kZWQuYWxnKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoYWxnICYmIGRlY29kZWQuYWxnICE9PSBhbGcpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5mdW5jdGlvbiBpc1ZhbGlkQ2lkcihpcCwgdmVyc2lvbikge1xuICAgIGlmICgodmVyc2lvbiA9PT0gXCJ2NFwiIHx8ICF2ZXJzaW9uKSAmJiBpcHY0Q2lkclJlZ2V4LnRlc3QoaXApKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoKHZlcnNpb24gPT09IFwidjZcIiB8fCAhdmVyc2lvbikgJiYgaXB2NkNpZHJSZWdleC50ZXN0KGlwKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZXhwb3J0IGNsYXNzIFpvZFN0cmluZyBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgaW5wdXQuZGF0YSA9IFN0cmluZyhpbnB1dC5kYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7XG4gICAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN0cmluZykge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zdHJpbmcsXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTtcbiAgICAgICAgbGV0IGN0eCA9IHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7XG4gICAgICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gXCJtaW5cIikge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmxlbmd0aCA8IGNoZWNrLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBleGFjdDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJtYXhcIikge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmxlbmd0aCA+IGNoZWNrLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibGVuZ3RoXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29CaWcgPSBpbnB1dC5kYXRhLmxlbmd0aCA+IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb1NtYWxsID0gaW5wdXQuZGF0YS5sZW5ndGggPCBjaGVjay52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAodG9vQmlnIHx8IHRvb1NtYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodG9vQmlnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhpbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGFjdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodG9vU21hbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluaW11bTogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiZW1haWxcIikge1xuICAgICAgICAgICAgICAgIGlmICghZW1haWxSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiZW1haWxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImVtb2ppXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgZW1vamlSZWdleCA9IG5ldyBSZWdFeHAoX2Vtb2ppUmVnZXgsIFwidVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFlbW9qaVJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJlbW9qaVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwidXVpZFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1dWlkUmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcInV1aWRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcIm5hbm9pZFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFuYW5vaWRSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwibmFub2lkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJjdWlkXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWN1aWRSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiY3VpZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiY3VpZDJcIikge1xuICAgICAgICAgICAgICAgIGlmICghY3VpZDJSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiY3VpZDJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInVsaWRcIikge1xuICAgICAgICAgICAgICAgIGlmICghdWxpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJ1bGlkXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ1cmxcIikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIG5ldyBVUkwoaW5wdXQuZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJ1cmxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInJlZ2V4XCIpIHtcbiAgICAgICAgICAgICAgICBjaGVjay5yZWdleC5sYXN0SW5kZXggPSAwO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRlc3RSZXN1bHQgPSBjaGVjay5yZWdleC50ZXN0KGlucHV0LmRhdGEpO1xuICAgICAgICAgICAgICAgIGlmICghdGVzdFJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcInJlZ2V4XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ0cmltXCIpIHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50cmltKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImluY2x1ZGVzXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuaW5jbHVkZXMoY2hlY2sudmFsdWUsIGNoZWNrLnBvc2l0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiB7IGluY2x1ZGVzOiBjaGVjay52YWx1ZSwgcG9zaXRpb246IGNoZWNrLnBvc2l0aW9uIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJ0b0xvd2VyQ2FzZVwiKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQuZGF0YSA9IGlucHV0LmRhdGEudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwidG9VcHBlckNhc2VcIikge1xuICAgICAgICAgICAgICAgIGlucHV0LmRhdGEgPSBpbnB1dC5kYXRhLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInN0YXJ0c1dpdGhcIikge1xuICAgICAgICAgICAgICAgIGlmICghaW5wdXQuZGF0YS5zdGFydHNXaXRoKGNoZWNrLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiB7IHN0YXJ0c1dpdGg6IGNoZWNrLnZhbHVlIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJlbmRzV2l0aFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpbnB1dC5kYXRhLmVuZHNXaXRoKGNoZWNrLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiB7IGVuZHNXaXRoOiBjaGVjay52YWx1ZSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiZGF0ZXRpbWVcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2V4ID0gZGF0ZXRpbWVSZWdleChjaGVjayk7XG4gICAgICAgICAgICAgICAgaWYgKCFyZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiZGF0ZXRpbWVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImRhdGVcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2V4ID0gZGF0ZVJlZ2V4O1xuICAgICAgICAgICAgICAgIGlmICghcmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImRhdGVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcInRpbWVcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2V4ID0gdGltZVJlZ2V4KGNoZWNrKTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJ0aW1lXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJkdXJhdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkdXJhdGlvblJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJkdXJhdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiaXBcIikge1xuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZElQKGlucHV0LmRhdGEsIGNoZWNrLnZlcnNpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb246IFwiaXBcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImp3dFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkSldUKGlucHV0LmRhdGEsIGNoZWNrLmFsZykpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJqd3RcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImNpZHJcIikge1xuICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZENpZHIoaW5wdXQuZGF0YSwgY2hlY2sudmVyc2lvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJjaWRyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJiYXNlNjRcIikge1xuICAgICAgICAgICAgICAgIGlmICghYmFzZTY0UmVnZXgudGVzdChpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uOiBcImJhc2U2NFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwiYmFzZTY0dXJsXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWJhc2U2NHVybFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbjogXCJiYXNlNjR1cmxcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGNoZWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlucHV0LmRhdGEgfTtcbiAgICB9XG4gICAgX3JlZ2V4KHJlZ2V4LCB2YWxpZGF0aW9uLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZmluZW1lbnQoKGRhdGEpID0+IHJlZ2V4LnRlc3QoZGF0YSksIHtcbiAgICAgICAgICAgIHZhbGlkYXRpb24sXG4gICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfYWRkQ2hlY2soY2hlY2spIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZW1haWwobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soeyBraW5kOiBcImVtYWlsXCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTtcbiAgICB9XG4gICAgdXJsKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogXCJ1cmxcIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pO1xuICAgIH1cbiAgICBlbW9qaShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6IFwiZW1vamlcIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pO1xuICAgIH1cbiAgICB1dWlkKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogXCJ1dWlkXCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTtcbiAgICB9XG4gICAgbmFub2lkKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogXCJuYW5vaWRcIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pO1xuICAgIH1cbiAgICBjdWlkKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogXCJjdWlkXCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTtcbiAgICB9XG4gICAgY3VpZDIobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soeyBraW5kOiBcImN1aWQyXCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTtcbiAgICB9XG4gICAgdWxpZChtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6IFwidWxpZFwiLCAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkgfSk7XG4gICAgfVxuICAgIGJhc2U2NChtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6IFwiYmFzZTY0XCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTtcbiAgICB9XG4gICAgYmFzZTY0dXJsKG1lc3NhZ2UpIHtcbiAgICAgICAgLy8gYmFzZTY0dXJsIGVuY29kaW5nIGlzIGEgbW9kaWZpY2F0aW9uIG9mIGJhc2U2NCB0aGF0IGNhbiBzYWZlbHkgYmUgdXNlZCBpbiBVUkxzIGFuZCBmaWxlbmFtZXNcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwiYmFzZTY0dXJsXCIsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBqd3Qob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soeyBraW5kOiBcImp3dFwiLCAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucykgfSk7XG4gICAgfVxuICAgIGlwKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogXCJpcFwiLCAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucykgfSk7XG4gICAgfVxuICAgIGNpZHIob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soeyBraW5kOiBcImNpZHJcIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMpIH0pO1xuICAgIH1cbiAgICBkYXRldGltZShvcHRpb25zKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgICAgICBraW5kOiBcImRhdGV0aW1lXCIsXG4gICAgICAgICAgICAgICAgcHJlY2lzaW9uOiBudWxsLFxuICAgICAgICAgICAgICAgIG9mZnNldDogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG9wdGlvbnMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJkYXRldGltZVwiLFxuICAgICAgICAgICAgcHJlY2lzaW9uOiB0eXBlb2Ygb3B0aW9ucz8ucHJlY2lzaW9uID09PSBcInVuZGVmaW5lZFwiID8gbnVsbCA6IG9wdGlvbnM/LnByZWNpc2lvbixcbiAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucz8ub2Zmc2V0ID8/IGZhbHNlLFxuICAgICAgICAgICAgbG9jYWw6IG9wdGlvbnM/LmxvY2FsID8/IGZhbHNlLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnM/Lm1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGF0ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6IFwiZGF0ZVwiLCBtZXNzYWdlIH0pO1xuICAgIH1cbiAgICB0aW1lKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAgICAgIGtpbmQ6IFwidGltZVwiLFxuICAgICAgICAgICAgICAgIHByZWNpc2lvbjogbnVsbCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBvcHRpb25zLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwidGltZVwiLFxuICAgICAgICAgICAgcHJlY2lzaW9uOiB0eXBlb2Ygb3B0aW9ucz8ucHJlY2lzaW9uID09PSBcInVuZGVmaW5lZFwiID8gbnVsbCA6IG9wdGlvbnM/LnByZWNpc2lvbixcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihvcHRpb25zPy5tZXNzYWdlKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGR1cmF0aW9uKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogXCJkdXJhdGlvblwiLCAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkgfSk7XG4gICAgfVxuICAgIHJlZ2V4KHJlZ2V4LCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcInJlZ2V4XCIsXG4gICAgICAgICAgICByZWdleDogcmVnZXgsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpbmNsdWRlcyh2YWx1ZSwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJpbmNsdWRlc1wiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgcG9zaXRpb246IG9wdGlvbnM/LnBvc2l0aW9uLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnM/Lm1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhcnRzV2l0aCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJzdGFydHNXaXRoXCIsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbmRzV2l0aCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJlbmRzV2l0aFwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbWluKG1pbkxlbmd0aCwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiBtaW5MZW5ndGgsXG4gICAgICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtYXgobWF4TGVuZ3RoLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1heFwiLFxuICAgICAgICAgICAgdmFsdWU6IG1heExlbmd0aCxcbiAgICAgICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGxlbmd0aChsZW4sIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibGVuZ3RoXCIsXG4gICAgICAgICAgICB2YWx1ZTogbGVuLFxuICAgICAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXF1aXZhbGVudCB0byBgLm1pbigxKWBcbiAgICAgKi9cbiAgICBub25lbXB0eShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbigxLCBlcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkpO1xuICAgIH1cbiAgICB0cmltKCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFsuLi50aGlzLl9kZWYuY2hlY2tzLCB7IGtpbmQ6IFwidHJpbVwiIH1dLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdG9Mb3dlckNhc2UoKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kU3RyaW5nKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIHsga2luZDogXCJ0b0xvd2VyQ2FzZVwiIH1dLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdG9VcHBlckNhc2UoKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kU3RyaW5nKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIHsga2luZDogXCJ0b1VwcGVyQ2FzZVwiIH1dLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0IGlzRGF0ZXRpbWUoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09IFwiZGF0ZXRpbWVcIik7XG4gICAgfVxuICAgIGdldCBpc0RhdGUoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09IFwiZGF0ZVwiKTtcbiAgICB9XG4gICAgZ2V0IGlzVGltZSgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gXCJ0aW1lXCIpO1xuICAgIH1cbiAgICBnZXQgaXNEdXJhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gXCJkdXJhdGlvblwiKTtcbiAgICB9XG4gICAgZ2V0IGlzRW1haWwoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09IFwiZW1haWxcIik7XG4gICAgfVxuICAgIGdldCBpc1VSTCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gXCJ1cmxcIik7XG4gICAgfVxuICAgIGdldCBpc0Vtb2ppKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSBcImVtb2ppXCIpO1xuICAgIH1cbiAgICBnZXQgaXNVVUlEKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSBcInV1aWRcIik7XG4gICAgfVxuICAgIGdldCBpc05BTk9JRCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gXCJuYW5vaWRcIik7XG4gICAgfVxuICAgIGdldCBpc0NVSUQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09IFwiY3VpZFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzQ1VJRDIoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09IFwiY3VpZDJcIik7XG4gICAgfVxuICAgIGdldCBpc1VMSUQoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09IFwidWxpZFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzSVAoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09IFwiaXBcIik7XG4gICAgfVxuICAgIGdldCBpc0NJRFIoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09IFwiY2lkclwiKTtcbiAgICB9XG4gICAgZ2V0IGlzQmFzZTY0KCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSBcImJhc2U2NFwiKTtcbiAgICB9XG4gICAgZ2V0IGlzQmFzZTY0dXJsKCkge1xuICAgICAgICAvLyBiYXNlNjR1cmwgZW5jb2RpbmcgaXMgYSBtb2RpZmljYXRpb24gb2YgYmFzZTY0IHRoYXQgY2FuIHNhZmVseSBiZSB1c2VkIGluIFVSTHMgYW5kIGZpbGVuYW1lc1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSBcImJhc2U2NHVybFwiKTtcbiAgICB9XG4gICAgZ2V0IG1pbkxlbmd0aCgpIHtcbiAgICAgICAgbGV0IG1pbiA9IG51bGw7XG4gICAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykge1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKVxuICAgICAgICAgICAgICAgICAgICBtaW4gPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgIH1cbiAgICBnZXQgbWF4TGVuZ3RoKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7XG4gICAgICAgICAgICBpZiAoY2gua2luZCA9PT0gXCJtYXhcIikge1xuICAgICAgICAgICAgICAgIGlmIChtYXggPT09IG51bGwgfHwgY2gudmFsdWUgPCBtYXgpXG4gICAgICAgICAgICAgICAgICAgIG1heCA9IGNoLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXg7XG4gICAgfVxufVxuWm9kU3RyaW5nLmNyZWF0ZSA9IChwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7XG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nLFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlID8/IGZhbHNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzk2NjQ4NC93aHktZG9lcy1tb2R1bHVzLW9wZXJhdG9yLXJldHVybi1mcmFjdGlvbmFsLW51bWJlci1pbi1qYXZhc2NyaXB0LzMxNzExMDM0IzMxNzExMDM0XG5mdW5jdGlvbiBmbG9hdFNhZmVSZW1haW5kZXIodmFsLCBzdGVwKSB7XG4gICAgY29uc3QgdmFsRGVjQ291bnQgPSAodmFsLnRvU3RyaW5nKCkuc3BsaXQoXCIuXCIpWzFdIHx8IFwiXCIpLmxlbmd0aDtcbiAgICBjb25zdCBzdGVwRGVjQ291bnQgPSAoc3RlcC50b1N0cmluZygpLnNwbGl0KFwiLlwiKVsxXSB8fCBcIlwiKS5sZW5ndGg7XG4gICAgY29uc3QgZGVjQ291bnQgPSB2YWxEZWNDb3VudCA+IHN0ZXBEZWNDb3VudCA/IHZhbERlY0NvdW50IDogc3RlcERlY0NvdW50O1xuICAgIGNvbnN0IHZhbEludCA9IE51bWJlci5wYXJzZUludCh2YWwudG9GaXhlZChkZWNDb3VudCkucmVwbGFjZShcIi5cIiwgXCJcIikpO1xuICAgIGNvbnN0IHN0ZXBJbnQgPSBOdW1iZXIucGFyc2VJbnQoc3RlcC50b0ZpeGVkKGRlY0NvdW50KS5yZXBsYWNlKFwiLlwiLCBcIlwiKSk7XG4gICAgcmV0dXJuICh2YWxJbnQgJSBzdGVwSW50KSAvIDEwICoqIGRlY0NvdW50O1xufVxuZXhwb3J0IGNsYXNzIFpvZE51bWJlciBleHRlbmRzIFpvZFR5cGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm1pbiA9IHRoaXMuZ3RlO1xuICAgICAgICB0aGlzLm1heCA9IHRoaXMubHRlO1xuICAgICAgICB0aGlzLnN0ZXAgPSB0aGlzLm11bHRpcGxlT2Y7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgaW5wdXQuZGF0YSA9IE51bWJlcihpbnB1dC5kYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7XG4gICAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm51bWJlcikge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5udW1iZXIsXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY3R4ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTtcbiAgICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7XG4gICAgICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gXCJpbnRcIikge1xuICAgICAgICAgICAgICAgIGlmICghdXRpbC5pc0ludGVnZXIoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBcImludGVnZXJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBcImZsb2F0XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gXCJtaW5cIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb1NtYWxsID0gY2hlY2suaW5jbHVzaXZlID8gaW5wdXQuZGF0YSA8IGNoZWNrLnZhbHVlIDogaW5wdXQuZGF0YSA8PSBjaGVjay52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAodG9vU21hbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29CaWcgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhID4gY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhID49IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmICh0b29CaWcpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhpbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IGNoZWNrLmluY2x1c2l2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcIm11bHRpcGxlT2ZcIikge1xuICAgICAgICAgICAgICAgIGlmIChmbG9hdFNhZmVSZW1haW5kZXIoaW5wdXQuZGF0YSwgY2hlY2sudmFsdWUpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpO1xuICAgICAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2YsXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZU9mOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcImZpbml0ZVwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9maW5pdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXRpbC5hc3NlcnROZXZlcihjaGVjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBpbnB1dC5kYXRhIH07XG4gICAgfVxuICAgIGd0ZSh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1pblwiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTtcbiAgICB9XG4gICAgZ3QodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0TGltaXQoXCJtaW5cIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBsdGUodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0TGltaXQoXCJtYXhcIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7XG4gICAgfVxuICAgIGx0KHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KFwibWF4XCIsIHZhbHVlLCBmYWxzZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTtcbiAgICB9XG4gICAgc2V0TGltaXQoa2luZCwgdmFsdWUsIGluY2x1c2l2ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZE51bWJlcih7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjaGVja3M6IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAga2luZCxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgX2FkZENoZWNrKGNoZWNrKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kTnVtYmVyKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIGNoZWNrXSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGludChtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImludFwiLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG5lZ2F0aXZlKG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibWF4XCIsXG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgICAgIGluY2x1c2l2ZTogZmFsc2UsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBub25wb3NpdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1heFwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtdWx0aXBsZU9mKHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm11bHRpcGxlT2ZcIixcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZpbml0ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcImZpbml0ZVwiLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2FmZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgdmFsdWU6IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpLFxuICAgICAgICB9KS5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUixcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdldCBtaW5WYWx1ZSgpIHtcbiAgICAgICAgbGV0IG1pbiA9IG51bGw7XG4gICAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykge1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKVxuICAgICAgICAgICAgICAgICAgICBtaW4gPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIGxldCBtYXggPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1heFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heClcbiAgICAgICAgICAgICAgICAgICAgbWF4ID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICB9XG4gICAgZ2V0IGlzSW50KCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSBcImludFwiIHx8IChjaC5raW5kID09PSBcIm11bHRpcGxlT2ZcIiAmJiB1dGlsLmlzSW50ZWdlcihjaC52YWx1ZSkpKTtcbiAgICB9XG4gICAgZ2V0IGlzRmluaXRlKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgbGV0IG1pbiA9IG51bGw7XG4gICAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykge1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwiZmluaXRlXCIgfHwgY2gua2luZCA9PT0gXCJpbnRcIiB8fCBjaC5raW5kID09PSBcIm11bHRpcGxlT2ZcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2gua2luZCA9PT0gXCJtaW5cIikge1xuICAgICAgICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pXG4gICAgICAgICAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2gua2luZCA9PT0gXCJtYXhcIikge1xuICAgICAgICAgICAgICAgIGlmIChtYXggPT09IG51bGwgfHwgY2gudmFsdWUgPCBtYXgpXG4gICAgICAgICAgICAgICAgICAgIG1heCA9IGNoLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBOdW1iZXIuaXNGaW5pdGUobWluKSAmJiBOdW1iZXIuaXNGaW5pdGUobWF4KTtcbiAgICB9XG59XG5ab2ROdW1iZXIuY3JlYXRlID0gKHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kTnVtYmVyKHtcbiAgICAgICAgY2hlY2tzOiBbXSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROdW1iZXIsXG4gICAgICAgIGNvZXJjZTogcGFyYW1zPy5jb2VyY2UgfHwgZmFsc2UsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kQmlnSW50IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubWluID0gdGhpcy5ndGU7XG4gICAgICAgIHRoaXMubWF4ID0gdGhpcy5sdGU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpbnB1dC5kYXRhID0gQmlnSW50KGlucHV0LmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRJbnZhbGlkSW5wdXQoaW5wdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuYmlnaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0SW52YWxpZElucHV0KGlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY3R4ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTtcbiAgICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7XG4gICAgICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gXCJtaW5cIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRvb1NtYWxsID0gY2hlY2suaW5jbHVzaXZlID8gaW5wdXQuZGF0YSA8IGNoZWNrLnZhbHVlIDogaW5wdXQuZGF0YSA8PSBjaGVjay52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAodG9vU21hbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiYmlnaW50XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0b29CaWcgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhID4gY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhID49IGNoZWNrLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmICh0b29CaWcpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImJpZ2ludFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IGNoZWNrLmluY2x1c2l2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcIm11bHRpcGxlT2ZcIikge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dC5kYXRhICUgY2hlY2sudmFsdWUgIT09IEJpZ0ludCgwKSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUubm90X211bHRpcGxlX29mLFxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGVPZjogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXRpbC5hc3NlcnROZXZlcihjaGVjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBpbnB1dC5kYXRhIH07XG4gICAgfVxuICAgIF9nZXRJbnZhbGlkSW5wdXQoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5iaWdpbnQsXG4gICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICB9XG4gICAgZ3RlKHZhbHVlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KFwibWluXCIsIHZhbHVlLCB0cnVlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBndCh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1pblwiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7XG4gICAgfVxuICAgIGx0ZSh2YWx1ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdChcIm1heFwiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTtcbiAgICB9XG4gICAgbHQodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0TGltaXQoXCJtYXhcIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpO1xuICAgIH1cbiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGNoZWNrczogW1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuX2RlZi5jaGVja3MsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBraW5kLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfYWRkQ2hlY2soY2hlY2spIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RCaWdJbnQoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtaW5cIixcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQoMCksXG4gICAgICAgICAgICBpbmNsdXNpdmU6IGZhbHNlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbmVnYXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQoMCksXG4gICAgICAgICAgICBpbmNsdXNpdmU6IGZhbHNlLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbm9ucG9zaXRpdmUobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQoMCksXG4gICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7XG4gICAgICAgICAgICBraW5kOiBcIm1pblwiLFxuICAgICAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSxcbiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG11bHRpcGxlT2YodmFsdWUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibXVsdGlwbGVPZlwiLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgIGxldCBtaW4gPSBudWxsO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHtcbiAgICAgICAgICAgIGlmIChjaC5raW5kID09PSBcIm1pblwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBjaC52YWx1ZSA+IG1pbilcbiAgICAgICAgICAgICAgICAgICAgbWluID0gY2gudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1pbjtcbiAgICB9XG4gICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICBsZXQgbWF4ID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7XG4gICAgICAgICAgICBpZiAoY2gua2luZCA9PT0gXCJtYXhcIikge1xuICAgICAgICAgICAgICAgIGlmIChtYXggPT09IG51bGwgfHwgY2gudmFsdWUgPCBtYXgpXG4gICAgICAgICAgICAgICAgICAgIG1heCA9IGNoLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXg7XG4gICAgfVxufVxuWm9kQmlnSW50LmNyZWF0ZSA9IChwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZEJpZ0ludCh7XG4gICAgICAgIGNoZWNrczogW10sXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQmlnSW50LFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlID8/IGZhbHNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEJvb2xlYW4gZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2RlZi5jb2VyY2UpIHtcbiAgICAgICAgICAgIGlucHV0LmRhdGEgPSBCb29sZWFuKGlucHV0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuYm9vbGVhbikge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5ib29sZWFuLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbn1cblpvZEJvb2xlYW4uY3JlYXRlID0gKHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kQm9vbGVhbih7XG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQm9vbGVhbixcbiAgICAgICAgY29lcmNlOiBwYXJhbXM/LmNvZXJjZSB8fCBmYWxzZSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpLFxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2REYXRlIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7XG4gICAgICAgICAgICBpbnB1dC5kYXRhID0gbmV3IERhdGUoaW5wdXQuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5kYXRlKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmRhdGUsXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTnVtYmVyLmlzTmFOKGlucHV0LmRhdGEuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZGF0ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdHVzID0gbmV3IFBhcnNlU3RhdHVzKCk7XG4gICAgICAgIGxldCBjdHggPSB1bmRlZmluZWQ7XG4gICAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgdGhpcy5fZGVmLmNoZWNrcykge1xuICAgICAgICAgICAgaWYgKGNoZWNrLmtpbmQgPT09IFwibWluXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZGF0YS5nZXRUaW1lKCkgPCBjaGVjay52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJkYXRlXCIsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjaGVjay5raW5kID09PSBcIm1heFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlucHV0LmRhdGEuZ2V0VGltZSgpID4gY2hlY2sudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImRhdGVcIixcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgIHZhbHVlOiBuZXcgRGF0ZShpbnB1dC5kYXRhLmdldFRpbWUoKSksXG4gICAgICAgIH07XG4gICAgfVxuICAgIF9hZGRDaGVjayhjaGVjaykge1xuICAgICAgICByZXR1cm4gbmV3IFpvZERhdGUoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbWluKG1pbkRhdGUsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHtcbiAgICAgICAgICAgIGtpbmQ6IFwibWluXCIsXG4gICAgICAgICAgICB2YWx1ZTogbWluRGF0ZS5nZXRUaW1lKCksXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtYXgobWF4RGF0ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soe1xuICAgICAgICAgICAga2luZDogXCJtYXhcIixcbiAgICAgICAgICAgIHZhbHVlOiBtYXhEYXRlLmdldFRpbWUoKSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdldCBtaW5EYXRlKCkge1xuICAgICAgICBsZXQgbWluID0gbnVsbDtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7XG4gICAgICAgICAgICBpZiAoY2gua2luZCA9PT0gXCJtaW5cIikge1xuICAgICAgICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pXG4gICAgICAgICAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtaW4gIT0gbnVsbCA/IG5ldyBEYXRlKG1pbikgOiBudWxsO1xuICAgIH1cbiAgICBnZXQgbWF4RGF0ZSgpIHtcbiAgICAgICAgbGV0IG1heCA9IG51bGw7XG4gICAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykge1xuICAgICAgICAgICAgaWYgKGNoLmtpbmQgPT09IFwibWF4XCIpIHtcbiAgICAgICAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KVxuICAgICAgICAgICAgICAgICAgICBtYXggPSBjaC52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF4ICE9IG51bGwgPyBuZXcgRGF0ZShtYXgpIDogbnVsbDtcbiAgICB9XG59XG5ab2REYXRlLmNyZWF0ZSA9IChwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZERhdGUoe1xuICAgICAgICBjaGVja3M6IFtdLFxuICAgICAgICBjb2VyY2U6IHBhcmFtcz8uY29lcmNlIHx8IGZhbHNlLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERhdGUsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kU3ltYm9sIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuc3ltYm9sKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnN5bWJvbCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2RTeW1ib2wuY3JlYXRlID0gKHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kU3ltYm9sKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RTeW1ib2wsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kVW5kZWZpbmVkIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2RVbmRlZmluZWQuY3JlYXRlID0gKHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kVW5kZWZpbmVkKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmRlZmluZWQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kTnVsbCBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7XG4gICAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUubnVsbCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTtcbiAgICB9XG59XG5ab2ROdWxsLmNyZWF0ZSA9IChwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZE51bGwoe1xuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGwsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kQW55IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIC8vIHRvIHByZXZlbnQgaW5zdGFuY2VzIG9mIG90aGVyIGNsYXNzZXMgZnJvbSBleHRlbmRpbmcgWm9kQW55LiB0aGlzIGNhdXNlcyBpc3N1ZXMgd2l0aCBjYXRjaGFsbCBpbiBab2RPYmplY3QuXG4gICAgICAgIHRoaXMuX2FueSA9IHRydWU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7XG4gICAgfVxufVxuWm9kQW55LmNyZWF0ZSA9IChwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZEFueSh7XG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQW55LFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZFVua25vd24gZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgLy8gcmVxdWlyZWRcbiAgICAgICAgdGhpcy5fdW5rbm93biA9IHRydWU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7XG4gICAgfVxufVxuWm9kVW5rbm93bi5jcmVhdGUgPSAocGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2RVbmtub3duKHtcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmtub3duLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZE5ldmVyIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUubmV2ZXIsXG4gICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICB9XG59XG5ab2ROZXZlci5jcmVhdGUgPSAocGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2ROZXZlcih7XG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmV2ZXIsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kVm9pZCBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7XG4gICAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS52b2lkLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpO1xuICAgIH1cbn1cblpvZFZvaWQuY3JlYXRlID0gKHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kVm9pZCh7XG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVm9pZCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpLFxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RBcnJheSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IGN0eCwgc3RhdHVzIH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBkZWYgPSB0aGlzLl9kZWY7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5hcnJheSkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5hcnJheSxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWYuZXhhY3RMZW5ndGggIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHRvb0JpZyA9IGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5leGFjdExlbmd0aC52YWx1ZTtcbiAgICAgICAgICAgIGNvbnN0IHRvb1NtYWxsID0gY3R4LmRhdGEubGVuZ3RoIDwgZGVmLmV4YWN0TGVuZ3RoLnZhbHVlO1xuICAgICAgICAgICAgaWYgKHRvb0JpZyB8fCB0b29TbWFsbCkge1xuICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiB0b29CaWcgPyBab2RJc3N1ZUNvZGUudG9vX2JpZyA6IFpvZElzc3VlQ29kZS50b29fc21hbGwsXG4gICAgICAgICAgICAgICAgICAgIG1pbmltdW06ICh0b29TbWFsbCA/IGRlZi5leGFjdExlbmd0aC52YWx1ZSA6IHVuZGVmaW5lZCksXG4gICAgICAgICAgICAgICAgICAgIG1heGltdW06ICh0b29CaWcgPyBkZWYuZXhhY3RMZW5ndGgudmFsdWUgOiB1bmRlZmluZWQpLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGRlZi5leGFjdExlbmd0aC5tZXNzYWdlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkZWYubWluTGVuZ3RoICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoY3R4LmRhdGEubGVuZ3RoIDwgZGVmLm1pbkxlbmd0aC52YWx1ZSkge1xuICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLFxuICAgICAgICAgICAgICAgICAgICBtaW5pbXVtOiBkZWYubWluTGVuZ3RoLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkZWYubWluTGVuZ3RoLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlZi5tYXhMZW5ndGggIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChjdHguZGF0YS5sZW5ndGggPiBkZWYubWF4TGVuZ3RoLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLFxuICAgICAgICAgICAgICAgICAgICBtYXhpbXVtOiBkZWYubWF4TGVuZ3RoLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkZWYubWF4TGVuZ3RoLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbLi4uY3R4LmRhdGFdLm1hcCgoaXRlbSwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZWYudHlwZS5fcGFyc2VBc3luYyhuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgaXRlbSwgY3R4LnBhdGgsIGkpKTtcbiAgICAgICAgICAgIH0pKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXN1bHQgPSBbLi4uY3R4LmRhdGFdLm1hcCgoaXRlbSwgaSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGRlZi50eXBlLl9wYXJzZVN5bmMobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGl0ZW0sIGN0eC5wYXRoLCBpKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdCk7XG4gICAgfVxuICAgIGdldCBlbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7XG4gICAgfVxuICAgIG1pbihtaW5MZW5ndGgsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RBcnJheSh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBtaW5MZW5ndGg6IHsgdmFsdWU6IG1pbkxlbmd0aCwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBtYXgobWF4TGVuZ3RoLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgbWF4TGVuZ3RoOiB7IHZhbHVlOiBtYXhMZW5ndGgsIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbGVuZ3RoKGxlbiwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEFycmF5KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIGV4YWN0TGVuZ3RoOiB7IHZhbHVlOiBsZW4sIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgbm9uZW1wdHkobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5taW4oMSwgbWVzc2FnZSk7XG4gICAgfVxufVxuWm9kQXJyYXkuY3JlYXRlID0gKHNjaGVtYSwgcGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2RBcnJheSh7XG4gICAgICAgIHR5cGU6IHNjaGVtYSxcbiAgICAgICAgbWluTGVuZ3RoOiBudWxsLFxuICAgICAgICBtYXhMZW5ndGg6IG51bGwsXG4gICAgICAgIGV4YWN0TGVuZ3RoOiBudWxsLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEFycmF5LFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuZnVuY3Rpb24gZGVlcFBhcnRpYWxpZnkoc2NoZW1hKSB7XG4gICAgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9iamVjdCkge1xuICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzY2hlbWEuc2hhcGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpZWxkU2NoZW1hID0gc2NoZW1hLnNoYXBlW2tleV07XG4gICAgICAgICAgICBuZXdTaGFwZVtrZXldID0gWm9kT3B0aW9uYWwuY3JlYXRlKGRlZXBQYXJ0aWFsaWZ5KGZpZWxkU2NoZW1hKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4uc2NoZW1hLl9kZWYsXG4gICAgICAgICAgICBzaGFwZTogKCkgPT4gbmV3U2hhcGUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIGlmIChzY2hlbWEgaW5zdGFuY2VvZiBab2RBcnJheSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZEFycmF5KHtcbiAgICAgICAgICAgIC4uLnNjaGVtYS5fZGVmLFxuICAgICAgICAgICAgdHlwZTogZGVlcFBhcnRpYWxpZnkoc2NoZW1hLmVsZW1lbnQpLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc2NoZW1hIGluc3RhbmNlb2YgWm9kT3B0aW9uYWwpIHtcbiAgICAgICAgcmV0dXJuIFpvZE9wdGlvbmFsLmNyZWF0ZShkZWVwUGFydGlhbGlmeShzY2hlbWEudW53cmFwKCkpKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc2NoZW1hIGluc3RhbmNlb2YgWm9kTnVsbGFibGUpIHtcbiAgICAgICAgcmV0dXJuIFpvZE51bGxhYmxlLmNyZWF0ZShkZWVwUGFydGlhbGlmeShzY2hlbWEudW53cmFwKCkpKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc2NoZW1hIGluc3RhbmNlb2YgWm9kVHVwbGUpIHtcbiAgICAgICAgcmV0dXJuIFpvZFR1cGxlLmNyZWF0ZShzY2hlbWEuaXRlbXMubWFwKChpdGVtKSA9PiBkZWVwUGFydGlhbGlmeShpdGVtKSkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kT2JqZWN0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX2NhY2hlZCA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVwcmVjYXRlZCBJbiBtb3N0IGNhc2VzLCB0aGlzIGlzIG5vIGxvbmdlciBuZWVkZWQgLSB1bmtub3duIHByb3BlcnRpZXMgYXJlIG5vdyBzaWxlbnRseSBzdHJpcHBlZC5cbiAgICAgICAgICogSWYgeW91IHdhbnQgdG8gcGFzcyB0aHJvdWdoIHVua25vd24gcHJvcGVydGllcywgdXNlIGAucGFzc3Rocm91Z2goKWAgaW5zdGVhZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubm9uc3RyaWN0ID0gdGhpcy5wYXNzdGhyb3VnaDtcbiAgICAgICAgLy8gZXh0ZW5kPFxuICAgICAgICAvLyAgIEF1Z21lbnRhdGlvbiBleHRlbmRzIFpvZFJhd1NoYXBlLFxuICAgICAgICAvLyAgIE5ld091dHB1dCBleHRlbmRzIHV0aWwuZmxhdHRlbjx7XG4gICAgICAgIC8vICAgICBbayBpbiBrZXlvZiBBdWdtZW50YXRpb24gfCBrZXlvZiBPdXRwdXRdOiBrIGV4dGVuZHMga2V5b2YgQXVnbWVudGF0aW9uXG4gICAgICAgIC8vICAgICAgID8gQXVnbWVudGF0aW9uW2tdW1wiX291dHB1dFwiXVxuICAgICAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBPdXRwdXRcbiAgICAgICAgLy8gICAgICAgPyBPdXRwdXRba11cbiAgICAgICAgLy8gICAgICAgOiBuZXZlcjtcbiAgICAgICAgLy8gICB9PixcbiAgICAgICAgLy8gICBOZXdJbnB1dCBleHRlbmRzIHV0aWwuZmxhdHRlbjx7XG4gICAgICAgIC8vICAgICBbayBpbiBrZXlvZiBBdWdtZW50YXRpb24gfCBrZXlvZiBJbnB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb25cbiAgICAgICAgLy8gICAgICAgPyBBdWdtZW50YXRpb25ba11bXCJfaW5wdXRcIl1cbiAgICAgICAgLy8gICAgICAgOiBrIGV4dGVuZHMga2V5b2YgSW5wdXRcbiAgICAgICAgLy8gICAgICAgPyBJbnB1dFtrXVxuICAgICAgICAvLyAgICAgICA6IG5ldmVyO1xuICAgICAgICAvLyAgIH0+XG4gICAgICAgIC8vID4oXG4gICAgICAgIC8vICAgYXVnbWVudGF0aW9uOiBBdWdtZW50YXRpb25cbiAgICAgICAgLy8gKTogWm9kT2JqZWN0PFxuICAgICAgICAvLyAgIGV4dGVuZFNoYXBlPFQsIEF1Z21lbnRhdGlvbj4sXG4gICAgICAgIC8vICAgVW5rbm93bktleXMsXG4gICAgICAgIC8vICAgQ2F0Y2hhbGwsXG4gICAgICAgIC8vICAgTmV3T3V0cHV0LFxuICAgICAgICAvLyAgIE5ld0lucHV0XG4gICAgICAgIC8vID4ge1xuICAgICAgICAvLyAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgLy8gICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgLy8gICAgIHNoYXBlOiAoKSA9PiAoe1xuICAgICAgICAvLyAgICAgICAuLi50aGlzLl9kZWYuc2hhcGUoKSxcbiAgICAgICAgLy8gICAgICAgLi4uYXVnbWVudGF0aW9uLFxuICAgICAgICAvLyAgICAgfSksXG4gICAgICAgIC8vICAgfSkgYXMgYW55O1xuICAgICAgICAvLyB9XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYC5leHRlbmRgIGluc3RlYWRcbiAgICAgICAgICogICovXG4gICAgICAgIHRoaXMuYXVnbWVudCA9IHRoaXMuZXh0ZW5kO1xuICAgIH1cbiAgICBfZ2V0Q2FjaGVkKCkge1xuICAgICAgICBpZiAodGhpcy5fY2FjaGVkICE9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZDtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLl9kZWYuc2hhcGUoKTtcbiAgICAgICAgY29uc3Qga2V5cyA9IHV0aWwub2JqZWN0S2V5cyhzaGFwZSk7XG4gICAgICAgIHRoaXMuX2NhY2hlZCA9IHsgc2hhcGUsIGtleXMgfTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZDtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGNvbnN0IHsgc2hhcGUsIGtleXM6IHNoYXBlS2V5cyB9ID0gdGhpcy5fZ2V0Q2FjaGVkKCk7XG4gICAgICAgIGNvbnN0IGV4dHJhS2V5cyA9IFtdO1xuICAgICAgICBpZiAoISh0aGlzLl9kZWYuY2F0Y2hhbGwgaW5zdGFuY2VvZiBab2ROZXZlciAmJiB0aGlzLl9kZWYudW5rbm93bktleXMgPT09IFwic3RyaXBcIikpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGN0eC5kYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzaGFwZUtleXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBleHRyYUtleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYWlycyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBzaGFwZUtleXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGtleVZhbGlkYXRvciA9IHNoYXBlW2tleV07XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGN0eC5kYXRhW2tleV07XG4gICAgICAgICAgICBwYWlycy5wdXNoKHtcbiAgICAgICAgICAgICAgICBrZXk6IHsgc3RhdHVzOiBcInZhbGlkXCIsIHZhbHVlOiBrZXkgfSxcbiAgICAgICAgICAgICAgICB2YWx1ZToga2V5VmFsaWRhdG9yLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgdmFsdWUsIGN0eC5wYXRoLCBrZXkpKSxcbiAgICAgICAgICAgICAgICBhbHdheXNTZXQ6IGtleSBpbiBjdHguZGF0YSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9kZWYuY2F0Y2hhbGwgaW5zdGFuY2VvZiBab2ROZXZlcikge1xuICAgICAgICAgICAgY29uc3QgdW5rbm93bktleXMgPSB0aGlzLl9kZWYudW5rbm93bktleXM7XG4gICAgICAgICAgICBpZiAodW5rbm93bktleXMgPT09IFwicGFzc3Rocm91Z2hcIikge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGV4dHJhS2V5cykge1xuICAgICAgICAgICAgICAgICAgICBwYWlycy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogeyBzdGF0dXM6IFwidmFsaWRcIiwgdmFsdWU6IGtleSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHsgc3RhdHVzOiBcInZhbGlkXCIsIHZhbHVlOiBjdHguZGF0YVtrZXldIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHVua25vd25LZXlzID09PSBcInN0cmljdFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4dHJhS2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnVucmVjb2duaXplZF9rZXlzLFxuICAgICAgICAgICAgICAgICAgICAgICAga2V5czogZXh0cmFLZXlzLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodW5rbm93bktleXMgPT09IFwic3RyaXBcIikge1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnRlcm5hbCBab2RPYmplY3QgZXJyb3I6IGludmFsaWQgdW5rbm93bktleXMgdmFsdWUuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBydW4gY2F0Y2hhbGwgdmFsaWRhdGlvblxuICAgICAgICAgICAgY29uc3QgY2F0Y2hhbGwgPSB0aGlzLl9kZWYuY2F0Y2hhbGw7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBleHRyYUtleXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGN0eC5kYXRhW2tleV07XG4gICAgICAgICAgICAgICAgcGFpcnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGtleTogeyBzdGF0dXM6IFwidmFsaWRcIiwgdmFsdWU6IGtleSB9LFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogY2F0Y2hhbGwuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCB2YWx1ZSwgY3R4LnBhdGgsIGtleSkgLy8sIGN0eC5jaGlsZChrZXkpLCB2YWx1ZSwgZ2V0UGFyc2VkVHlwZSh2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgYWx3YXlzU2V0OiBrZXkgaW4gY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgICAgICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzeW5jUGFpcnMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgcGFpci5rZXk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcGFpci52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgc3luY1BhaXJzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBhbHdheXNTZXQ6IHBhaXIuYWx3YXlzU2V0LFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN5bmNQYWlycztcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oKHN5bmNQYWlycykgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBzeW5jUGFpcnMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgcGFpcnMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBzaGFwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5zaGFwZSgpO1xuICAgIH1cbiAgICBzdHJpY3QobWVzc2FnZSkge1xuICAgICAgICBlcnJvclV0aWwuZXJyVG9PYmo7XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHVua25vd25LZXlzOiBcInN0cmljdFwiLFxuICAgICAgICAgICAgLi4uKG1lc3NhZ2UgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvck1hcDogKGlzc3VlLCBjdHgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRFcnJvciA9IHRoaXMuX2RlZi5lcnJvck1hcD8uKGlzc3VlLCBjdHgpLm1lc3NhZ2UgPz8gY3R4LmRlZmF1bHRFcnJvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc3N1ZS5jb2RlID09PSBcInVucmVjb2duaXplZF9rZXlzXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpLm1lc3NhZ2UgPz8gZGVmYXVsdEVycm9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGRlZmF1bHRFcnJvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RyaXAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHVua25vd25LZXlzOiBcInN0cmlwXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBwYXNzdGhyb3VnaCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgdW5rbm93bktleXM6IFwicGFzc3Rocm91Z2hcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIGNvbnN0IEF1Z21lbnRGYWN0b3J5ID1cbiAgICAvLyAgIDxEZWYgZXh0ZW5kcyBab2RPYmplY3REZWY+KGRlZjogRGVmKSA9PlxuICAgIC8vICAgPEF1Z21lbnRhdGlvbiBleHRlbmRzIFpvZFJhd1NoYXBlPihcbiAgICAvLyAgICAgYXVnbWVudGF0aW9uOiBBdWdtZW50YXRpb25cbiAgICAvLyAgICk6IFpvZE9iamVjdDxcbiAgICAvLyAgICAgZXh0ZW5kU2hhcGU8UmV0dXJuVHlwZTxEZWZbXCJzaGFwZVwiXT4sIEF1Z21lbnRhdGlvbj4sXG4gICAgLy8gICAgIERlZltcInVua25vd25LZXlzXCJdLFxuICAgIC8vICAgICBEZWZbXCJjYXRjaGFsbFwiXVxuICAgIC8vICAgPiA9PiB7XG4gICAgLy8gICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAvLyAgICAgICAuLi5kZWYsXG4gICAgLy8gICAgICAgc2hhcGU6ICgpID0+ICh7XG4gICAgLy8gICAgICAgICAuLi5kZWYuc2hhcGUoKSxcbiAgICAvLyAgICAgICAgIC4uLmF1Z21lbnRhdGlvbixcbiAgICAvLyAgICAgICB9KSxcbiAgICAvLyAgICAgfSkgYXMgYW55O1xuICAgIC8vICAgfTtcbiAgICBleHRlbmQoYXVnbWVudGF0aW9uKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHNoYXBlOiAoKSA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuX2RlZi5zaGFwZSgpLFxuICAgICAgICAgICAgICAgIC4uLmF1Z21lbnRhdGlvbixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJpb3IgdG8gem9kQDEuMC4xMiB0aGVyZSB3YXMgYSBidWcgaW4gdGhlXG4gICAgICogaW5mZXJyZWQgdHlwZSBvZiBtZXJnZWQgb2JqZWN0cy4gUGxlYXNlXG4gICAgICogdXBncmFkZSBpZiB5b3UgYXJlIGV4cGVyaWVuY2luZyBpc3N1ZXMuXG4gICAgICovXG4gICAgbWVyZ2UobWVyZ2luZykge1xuICAgICAgICBjb25zdCBtZXJnZWQgPSBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsXG4gICAgICAgICAgICBjYXRjaGFsbDogbWVyZ2luZy5fZGVmLmNhdGNoYWxsLFxuICAgICAgICAgICAgc2hhcGU6ICgpID0+ICh7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5fZGVmLnNoYXBlKCksXG4gICAgICAgICAgICAgICAgLi4ubWVyZ2luZy5fZGVmLnNoYXBlKCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG1lcmdlZDtcbiAgICB9XG4gICAgLy8gbWVyZ2U8XG4gICAgLy8gICBJbmNvbWluZyBleHRlbmRzIEFueVpvZE9iamVjdCxcbiAgICAvLyAgIEF1Z21lbnRhdGlvbiBleHRlbmRzIEluY29taW5nW1wic2hhcGVcIl0sXG4gICAgLy8gICBOZXdPdXRwdXQgZXh0ZW5kcyB7XG4gICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIE91dHB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb25cbiAgICAvLyAgICAgICA/IEF1Z21lbnRhdGlvbltrXVtcIl9vdXRwdXRcIl1cbiAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBPdXRwdXRcbiAgICAvLyAgICAgICA/IE91dHB1dFtrXVxuICAgIC8vICAgICAgIDogbmV2ZXI7XG4gICAgLy8gICB9LFxuICAgIC8vICAgTmV3SW5wdXQgZXh0ZW5kcyB7XG4gICAgLy8gICAgIFtrIGluIGtleW9mIEF1Z21lbnRhdGlvbiB8IGtleW9mIElucHV0XTogayBleHRlbmRzIGtleW9mIEF1Z21lbnRhdGlvblxuICAgIC8vICAgICAgID8gQXVnbWVudGF0aW9uW2tdW1wiX2lucHV0XCJdXG4gICAgLy8gICAgICAgOiBrIGV4dGVuZHMga2V5b2YgSW5wdXRcbiAgICAvLyAgICAgICA/IElucHV0W2tdXG4gICAgLy8gICAgICAgOiBuZXZlcjtcbiAgICAvLyAgIH1cbiAgICAvLyA+KFxuICAgIC8vICAgbWVyZ2luZzogSW5jb21pbmdcbiAgICAvLyApOiBab2RPYmplY3Q8XG4gICAgLy8gICBleHRlbmRTaGFwZTxULCBSZXR1cm5UeXBlPEluY29taW5nW1wiX2RlZlwiXVtcInNoYXBlXCJdPj4sXG4gICAgLy8gICBJbmNvbWluZ1tcIl9kZWZcIl1bXCJ1bmtub3duS2V5c1wiXSxcbiAgICAvLyAgIEluY29taW5nW1wiX2RlZlwiXVtcImNhdGNoYWxsXCJdLFxuICAgIC8vICAgTmV3T3V0cHV0LFxuICAgIC8vICAgTmV3SW5wdXRcbiAgICAvLyA+IHtcbiAgICAvLyAgIGNvbnN0IG1lcmdlZDogYW55ID0gbmV3IFpvZE9iamVjdCh7XG4gICAgLy8gICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsXG4gICAgLy8gICAgIGNhdGNoYWxsOiBtZXJnaW5nLl9kZWYuY2F0Y2hhbGwsXG4gICAgLy8gICAgIHNoYXBlOiAoKSA9PlxuICAgIC8vICAgICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXModGhpcy5fZGVmLnNoYXBlKCksIG1lcmdpbmcuX2RlZi5zaGFwZSgpKSxcbiAgICAvLyAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsXG4gICAgLy8gICB9KSBhcyBhbnk7XG4gICAgLy8gICByZXR1cm4gbWVyZ2VkO1xuICAgIC8vIH1cbiAgICBzZXRLZXkoa2V5LCBzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXVnbWVudCh7IFtrZXldOiBzY2hlbWEgfSk7XG4gICAgfVxuICAgIC8vIG1lcmdlPEluY29taW5nIGV4dGVuZHMgQW55Wm9kT2JqZWN0PihcbiAgICAvLyAgIG1lcmdpbmc6IEluY29taW5nXG4gICAgLy8gKTogLy9ab2RPYmplY3Q8VCAmIEluY29taW5nW1wiX3NoYXBlXCJdLCBVbmtub3duS2V5cywgQ2F0Y2hhbGw+ID0gKG1lcmdpbmcpID0+IHtcbiAgICAvLyBab2RPYmplY3Q8XG4gICAgLy8gICBleHRlbmRTaGFwZTxULCBSZXR1cm5UeXBlPEluY29taW5nW1wiX2RlZlwiXVtcInNoYXBlXCJdPj4sXG4gICAgLy8gICBJbmNvbWluZ1tcIl9kZWZcIl1bXCJ1bmtub3duS2V5c1wiXSxcbiAgICAvLyAgIEluY29taW5nW1wiX2RlZlwiXVtcImNhdGNoYWxsXCJdXG4gICAgLy8gPiB7XG4gICAgLy8gICAvLyBjb25zdCBtZXJnZWRTaGFwZSA9IG9iamVjdFV0aWwubWVyZ2VTaGFwZXMoXG4gICAgLy8gICAvLyAgIHRoaXMuX2RlZi5zaGFwZSgpLFxuICAgIC8vICAgLy8gICBtZXJnaW5nLl9kZWYuc2hhcGUoKVxuICAgIC8vICAgLy8gKTtcbiAgICAvLyAgIGNvbnN0IG1lcmdlZDogYW55ID0gbmV3IFpvZE9iamVjdCh7XG4gICAgLy8gICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsXG4gICAgLy8gICAgIGNhdGNoYWxsOiBtZXJnaW5nLl9kZWYuY2F0Y2hhbGwsXG4gICAgLy8gICAgIHNoYXBlOiAoKSA9PlxuICAgIC8vICAgICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXModGhpcy5fZGVmLnNoYXBlKCksIG1lcmdpbmcuX2RlZi5zaGFwZSgpKSxcbiAgICAvLyAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsXG4gICAgLy8gICB9KSBhcyBhbnk7XG4gICAgLy8gICByZXR1cm4gbWVyZ2VkO1xuICAgIC8vIH1cbiAgICBjYXRjaGFsbChpbmRleCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBjYXRjaGFsbDogaW5kZXgsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBwaWNrKG1hc2spIHtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgdXRpbC5vYmplY3RLZXlzKG1hc2spKSB7XG4gICAgICAgICAgICBpZiAobWFza1trZXldICYmIHRoaXMuc2hhcGVba2V5XSkge1xuICAgICAgICAgICAgICAgIHNoYXBlW2tleV0gPSB0aGlzLnNoYXBlW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgc2hhcGU6ICgpID0+IHNoYXBlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgb21pdChtYXNrKSB7XG4gICAgICAgIGNvbnN0IHNoYXBlID0ge307XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKSkge1xuICAgICAgICAgICAgaWYgKCFtYXNrW2tleV0pIHtcbiAgICAgICAgICAgICAgICBzaGFwZVtrZXldID0gdGhpcy5zaGFwZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHNoYXBlOiAoKSA9PiBzaGFwZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgZGVlcFBhcnRpYWwoKSB7XG4gICAgICAgIHJldHVybiBkZWVwUGFydGlhbGlmeSh0aGlzKTtcbiAgICB9XG4gICAgcGFydGlhbChtYXNrKSB7XG4gICAgICAgIGNvbnN0IG5ld1NoYXBlID0ge307XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKSkge1xuICAgICAgICAgICAgY29uc3QgZmllbGRTY2hlbWEgPSB0aGlzLnNoYXBlW2tleV07XG4gICAgICAgICAgICBpZiAobWFzayAmJiAhbWFza1trZXldKSB7XG4gICAgICAgICAgICAgICAgbmV3U2hhcGVba2V5XSA9IGZpZWxkU2NoZW1hO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV3U2hhcGVba2V5XSA9IGZpZWxkU2NoZW1hLm9wdGlvbmFsKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgc2hhcGU6ICgpID0+IG5ld1NoYXBlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVxdWlyZWQobWFzaykge1xuICAgICAgICBjb25zdCBuZXdTaGFwZSA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiB1dGlsLm9iamVjdEtleXModGhpcy5zaGFwZSkpIHtcbiAgICAgICAgICAgIGlmIChtYXNrICYmICFtYXNrW2tleV0pIHtcbiAgICAgICAgICAgICAgICBuZXdTaGFwZVtrZXldID0gdGhpcy5zaGFwZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmllbGRTY2hlbWEgPSB0aGlzLnNoYXBlW2tleV07XG4gICAgICAgICAgICAgICAgbGV0IG5ld0ZpZWxkID0gZmllbGRTY2hlbWE7XG4gICAgICAgICAgICAgICAgd2hpbGUgKG5ld0ZpZWxkIGluc3RhbmNlb2YgWm9kT3B0aW9uYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3RmllbGQgPSBuZXdGaWVsZC5fZGVmLmlubmVyVHlwZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmV3U2hhcGVba2V5XSA9IG5ld0ZpZWxkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHNoYXBlOiAoKSA9PiBuZXdTaGFwZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGtleW9mKCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlWm9kRW51bSh1dGlsLm9iamVjdEtleXModGhpcy5zaGFwZSkpO1xuICAgIH1cbn1cblpvZE9iamVjdC5jcmVhdGUgPSAoc2hhcGUsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgc2hhcGU6ICgpID0+IHNoYXBlLFxuICAgICAgICB1bmtub3duS2V5czogXCJzdHJpcFwiLFxuICAgICAgICBjYXRjaGFsbDogWm9kTmV2ZXIuY3JlYXRlKCksXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuWm9kT2JqZWN0LnN0cmljdENyZWF0ZSA9IChzaGFwZSwgcGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2RPYmplY3Qoe1xuICAgICAgICBzaGFwZTogKCkgPT4gc2hhcGUsXG4gICAgICAgIHVua25vd25LZXlzOiBcInN0cmljdFwiLFxuICAgICAgICBjYXRjaGFsbDogWm9kTmV2ZXIuY3JlYXRlKCksXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuWm9kT2JqZWN0LmxhenljcmVhdGUgPSAoc2hhcGUsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHtcbiAgICAgICAgc2hhcGUsXG4gICAgICAgIHVua25vd25LZXlzOiBcInN0cmlwXCIsXG4gICAgICAgIGNhdGNoYWxsOiBab2ROZXZlci5jcmVhdGUoKSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kVW5pb24gZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLl9kZWYub3B0aW9ucztcbiAgICAgICAgZnVuY3Rpb24gaGFuZGxlUmVzdWx0cyhyZXN1bHRzKSB7XG4gICAgICAgICAgICAvLyByZXR1cm4gZmlyc3QgaXNzdWUtZnJlZSB2YWxpZGF0aW9uIGlmIGl0IGV4aXN0c1xuICAgICAgICAgICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQucmVzdWx0LnN0YXR1cyA9PT0gXCJ2YWxpZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQucmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIikge1xuICAgICAgICAgICAgICAgICAgICAvLyBhZGQgaXNzdWVzIGZyb20gZGlydHkgb3B0aW9uXG4gICAgICAgICAgICAgICAgICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goLi4ucmVzdWx0LmN0eC5jb21tb24uaXNzdWVzKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gcmV0dXJuIGludmFsaWRcbiAgICAgICAgICAgIGNvbnN0IHVuaW9uRXJyb3JzID0gcmVzdWx0cy5tYXAoKHJlc3VsdCkgPT4gbmV3IFpvZEVycm9yKHJlc3VsdC5jdHguY29tbW9uLmlzc3VlcykpO1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb24sXG4gICAgICAgICAgICAgICAgdW5pb25FcnJvcnMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwob3B0aW9ucy5tYXAoYXN5bmMgKG9wdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkQ3R4ID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5jdHgsXG4gICAgICAgICAgICAgICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uY3R4LmNvbW1vbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlczogW10sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogbnVsbCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdDogYXdhaXQgb3B0aW9uLl9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGNoaWxkQ3R4LFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgY3R4OiBjaGlsZEN0eCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSkpLnRoZW4oaGFuZGxlUmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgZGlydHkgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBjb25zdCBpc3N1ZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZEN0eCA9IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY3R4LFxuICAgICAgICAgICAgICAgICAgICBjb21tb246IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmN0eC5jb21tb24sXG4gICAgICAgICAgICAgICAgICAgICAgICBpc3N1ZXM6IFtdLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IG51bGwsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBvcHRpb24uX3BhcnNlU3luYyh7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBjaGlsZEN0eCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJ2YWxpZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIiAmJiAhZGlydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlydHkgPSB7IHJlc3VsdCwgY3R4OiBjaGlsZEN0eCB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoY2hpbGRDdHguY29tbW9uLmlzc3Vlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVzLnB1c2goY2hpbGRDdHguY29tbW9uLmlzc3Vlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRpcnR5KSB7XG4gICAgICAgICAgICAgICAgY3R4LmNvbW1vbi5pc3N1ZXMucHVzaCguLi5kaXJ0eS5jdHguY29tbW9uLmlzc3Vlcyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRpcnR5LnJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHVuaW9uRXJyb3JzID0gaXNzdWVzLm1hcCgoaXNzdWVzKSA9PiBuZXcgWm9kRXJyb3IoaXNzdWVzKSk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbixcbiAgICAgICAgICAgICAgICB1bmlvbkVycm9ycyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9ucztcbiAgICB9XG59XG5ab2RVbmlvbi5jcmVhdGUgPSAodHlwZXMsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kVW5pb24oe1xuICAgICAgICBvcHRpb25zOiB0eXBlcyxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmlvbixcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpLFxuICAgIH0pO1xufTtcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vLy8vLy8vLy9cbi8vLy8vLy8vLy8gICAgICBab2REaXNjcmltaW5hdGVkVW5pb24gICAgICAvLy8vLy8vLy8vXG4vLy8vLy8vLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5jb25zdCBnZXREaXNjcmltaW5hdG9yID0gKHR5cGUpID0+IHtcbiAgICBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZExhenkpIHtcbiAgICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5zY2hlbWEpO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRWZmZWN0cykge1xuICAgICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLmlubmVyVHlwZSgpKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZExpdGVyYWwpIHtcbiAgICAgICAgcmV0dXJuIFt0eXBlLnZhbHVlXTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZEVudW0pIHtcbiAgICAgICAgcmV0dXJuIHR5cGUub3B0aW9ucztcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE5hdGl2ZUVudW0pIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGJhbi9iYW5cbiAgICAgICAgcmV0dXJuIHV0aWwub2JqZWN0VmFsdWVzKHR5cGUuZW51bSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2REZWZhdWx0KSB7XG4gICAgICAgIHJldHVybiBnZXREaXNjcmltaW5hdG9yKHR5cGUuX2RlZi5pbm5lclR5cGUpO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kVW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBbdW5kZWZpbmVkXTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtudWxsXTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE9wdGlvbmFsKSB7XG4gICAgICAgIHJldHVybiBbdW5kZWZpbmVkLCAuLi5nZXREaXNjcmltaW5hdG9yKHR5cGUudW53cmFwKCkpXTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZE51bGxhYmxlKSB7XG4gICAgICAgIHJldHVybiBbbnVsbCwgLi4uZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKV07XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RCcmFuZGVkKSB7XG4gICAgICAgIHJldHVybiBnZXREaXNjcmltaW5hdG9yKHR5cGUudW53cmFwKCkpO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kUmVhZG9ubHkpIHtcbiAgICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS51bndyYXAoKSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RDYXRjaCkge1xuICAgICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLl9kZWYuaW5uZXJUeXBlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG59O1xuZXhwb3J0IGNsYXNzIFpvZERpc2NyaW1pbmF0ZWRVbmlvbiBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm9iamVjdCkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5vYmplY3QsXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkaXNjcmltaW5hdG9yID0gdGhpcy5kaXNjcmltaW5hdG9yO1xuICAgICAgICBjb25zdCBkaXNjcmltaW5hdG9yVmFsdWUgPSBjdHguZGF0YVtkaXNjcmltaW5hdG9yXTtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gdGhpcy5vcHRpb25zTWFwLmdldChkaXNjcmltaW5hdG9yVmFsdWUpO1xuICAgICAgICBpZiAoIW9wdGlvbikge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb25fZGlzY3JpbWluYXRvcixcbiAgICAgICAgICAgICAgICBvcHRpb25zOiBBcnJheS5mcm9tKHRoaXMub3B0aW9uc01hcC5rZXlzKCkpLFxuICAgICAgICAgICAgICAgIHBhdGg6IFtkaXNjcmltaW5hdG9yXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBvcHRpb24uX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIHBhcmVudDogY3R4LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9uLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIHBhcmVudDogY3R4LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IGRpc2NyaW1pbmF0b3IoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuZGlzY3JpbWluYXRvcjtcbiAgICB9XG4gICAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9ucztcbiAgICB9XG4gICAgZ2V0IG9wdGlvbnNNYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9uc01hcDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBkaXNjcmltaW5hdGVkIHVuaW9uIHNjaGVtYS4gSXRzIGJlaGF2aW91ciBpcyB2ZXJ5IHNpbWlsYXIgdG8gdGhhdCBvZiB0aGUgbm9ybWFsIHoudW5pb24oKSBjb25zdHJ1Y3Rvci5cbiAgICAgKiBIb3dldmVyLCBpdCBvbmx5IGFsbG93cyBhIHVuaW9uIG9mIG9iamVjdHMsIGFsbCBvZiB3aGljaCBuZWVkIHRvIHNoYXJlIGEgZGlzY3JpbWluYXRvciBwcm9wZXJ0eS4gVGhpcyBwcm9wZXJ0eSBtdXN0XG4gICAgICogaGF2ZSBhIGRpZmZlcmVudCB2YWx1ZSBmb3IgZWFjaCBvYmplY3QgaW4gdGhlIHVuaW9uLlxuICAgICAqIEBwYXJhbSBkaXNjcmltaW5hdG9yIHRoZSBuYW1lIG9mIHRoZSBkaXNjcmltaW5hdG9yIHByb3BlcnR5XG4gICAgICogQHBhcmFtIHR5cGVzIGFuIGFycmF5IG9mIG9iamVjdCBzY2hlbWFzXG4gICAgICogQHBhcmFtIHBhcmFtc1xuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoZGlzY3JpbWluYXRvciwgb3B0aW9ucywgcGFyYW1zKSB7XG4gICAgICAgIC8vIEdldCBhbGwgdGhlIHZhbGlkIGRpc2NyaW1pbmF0b3IgdmFsdWVzXG4gICAgICAgIGNvbnN0IG9wdGlvbnNNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8vIHRyeSB7XG4gICAgICAgIGZvciAoY29uc3QgdHlwZSBvZiBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBkaXNjcmltaW5hdG9yVmFsdWVzID0gZ2V0RGlzY3JpbWluYXRvcih0eXBlLnNoYXBlW2Rpc2NyaW1pbmF0b3JdKTtcbiAgICAgICAgICAgIGlmICghZGlzY3JpbWluYXRvclZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEEgZGlzY3JpbWluYXRvciB2YWx1ZSBmb3Iga2V5IFxcYCR7ZGlzY3JpbWluYXRvcn1cXGAgY291bGQgbm90IGJlIGV4dHJhY3RlZCBmcm9tIGFsbCBzY2hlbWEgb3B0aW9uc2ApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiBkaXNjcmltaW5hdG9yVmFsdWVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnNNYXAuaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERpc2NyaW1pbmF0b3IgcHJvcGVydHkgJHtTdHJpbmcoZGlzY3JpbWluYXRvcil9IGhhcyBkdXBsaWNhdGUgdmFsdWUgJHtTdHJpbmcodmFsdWUpfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvcHRpb25zTWFwLnNldCh2YWx1ZSwgdHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2REaXNjcmltaW5hdGVkVW5pb24oe1xuICAgICAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REaXNjcmltaW5hdGVkVW5pb24sXG4gICAgICAgICAgICBkaXNjcmltaW5hdG9yLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIG9wdGlvbnNNYXAsXG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1lcmdlVmFsdWVzKGEsIGIpIHtcbiAgICBjb25zdCBhVHlwZSA9IGdldFBhcnNlZFR5cGUoYSk7XG4gICAgY29uc3QgYlR5cGUgPSBnZXRQYXJzZWRUeXBlKGIpO1xuICAgIGlmIChhID09PSBiKSB7XG4gICAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlLCBkYXRhOiBhIH07XG4gICAgfVxuICAgIGVsc2UgaWYgKGFUeXBlID09PSBab2RQYXJzZWRUeXBlLm9iamVjdCAmJiBiVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5vYmplY3QpIHtcbiAgICAgICAgY29uc3QgYktleXMgPSB1dGlsLm9iamVjdEtleXMoYik7XG4gICAgICAgIGNvbnN0IHNoYXJlZEtleXMgPSB1dGlsLm9iamVjdEtleXMoYSkuZmlsdGVyKChrZXkpID0+IGJLZXlzLmluZGV4T2Yoa2V5KSAhPT0gLTEpO1xuICAgICAgICBjb25zdCBuZXdPYmogPSB7IC4uLmEsIC4uLmIgfTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Ygc2hhcmVkS2V5cykge1xuICAgICAgICAgICAgY29uc3Qgc2hhcmVkVmFsdWUgPSBtZXJnZVZhbHVlcyhhW2tleV0sIGJba2V5XSk7XG4gICAgICAgICAgICBpZiAoIXNoYXJlZFZhbHVlLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBuZXdPYmpba2V5XSA9IHNoYXJlZFZhbHVlLmRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUsIGRhdGE6IG5ld09iaiB9O1xuICAgIH1cbiAgICBlbHNlIGlmIChhVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5hcnJheSAmJiBiVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5hcnJheSkge1xuICAgICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4geyB2YWxpZDogZmFsc2UgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdBcnJheSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYS5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1BID0gYVtpbmRleF07XG4gICAgICAgICAgICBjb25zdCBpdGVtQiA9IGJbaW5kZXhdO1xuICAgICAgICAgICAgY29uc3Qgc2hhcmVkVmFsdWUgPSBtZXJnZVZhbHVlcyhpdGVtQSwgaXRlbUIpO1xuICAgICAgICAgICAgaWYgKCFzaGFyZWRWYWx1ZS52YWxpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV3QXJyYXkucHVzaChzaGFyZWRWYWx1ZS5kYXRhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogbmV3QXJyYXkgfTtcbiAgICB9XG4gICAgZWxzZSBpZiAoYVR5cGUgPT09IFpvZFBhcnNlZFR5cGUuZGF0ZSAmJiBiVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5kYXRlICYmICthID09PSArYikge1xuICAgICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogYSB9O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlIH07XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIFpvZEludGVyc2VjdGlvbiBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBoYW5kbGVQYXJzZWQgPSAocGFyc2VkTGVmdCwgcGFyc2VkUmlnaHQpID0+IHtcbiAgICAgICAgICAgIGlmIChpc0Fib3J0ZWQocGFyc2VkTGVmdCkgfHwgaXNBYm9ydGVkKHBhcnNlZFJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWVyZ2VkID0gbWVyZ2VWYWx1ZXMocGFyc2VkTGVmdC52YWx1ZSwgcGFyc2VkUmlnaHQudmFsdWUpO1xuICAgICAgICAgICAgaWYgKCFtZXJnZWQudmFsaWQpIHtcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfaW50ZXJzZWN0aW9uX3R5cGVzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzRGlydHkocGFyc2VkTGVmdCkgfHwgaXNEaXJ0eShwYXJzZWRSaWdodCkpIHtcbiAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogbWVyZ2VkLmRhdGEgfTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgdGhpcy5fZGVmLmxlZnQuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRoaXMuX2RlZi5yaWdodC5fcGFyc2VBc3luYyh7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBjdHgsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBdKS50aGVuKChbbGVmdCwgcmlnaHRdKSA9PiBoYW5kbGVQYXJzZWQobGVmdCwgcmlnaHQpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVQYXJzZWQodGhpcy5fZGVmLmxlZnQuX3BhcnNlU3luYyh7XG4gICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgcGFyZW50OiBjdHgsXG4gICAgICAgICAgICB9KSwgdGhpcy5fZGVmLnJpZ2h0Ll9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIHBhcmVudDogY3R4LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgfVxufVxuWm9kSW50ZXJzZWN0aW9uLmNyZWF0ZSA9IChsZWZ0LCByaWdodCwgcGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2RJbnRlcnNlY3Rpb24oe1xuICAgICAgICBsZWZ0OiBsZWZ0LFxuICAgICAgICByaWdodDogcmlnaHQsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kSW50ZXJzZWN0aW9uLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuLy8gdHlwZSBab2RUdXBsZUl0ZW1zID0gW1pvZFR5cGVBbnksIC4uLlpvZFR5cGVBbnlbXV07XG5leHBvcnQgY2xhc3MgWm9kVHVwbGUgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmFycmF5KSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmFycmF5LFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGN0eC5kYXRhLmxlbmd0aCA8IHRoaXMuX2RlZi5pdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsXG4gICAgICAgICAgICAgICAgbWluaW11bTogdGhpcy5fZGVmLml0ZW1zLmxlbmd0aCxcbiAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzdCA9IHRoaXMuX2RlZi5yZXN0O1xuICAgICAgICBpZiAoIXJlc3QgJiYgY3R4LmRhdGEubGVuZ3RoID4gdGhpcy5fZGVmLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsXG4gICAgICAgICAgICAgICAgbWF4aW11bTogdGhpcy5fZGVmLml0ZW1zLmxlbmd0aCxcbiAgICAgICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsXG4gICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaXRlbXMgPSBbLi4uY3R4LmRhdGFdXG4gICAgICAgICAgICAubWFwKChpdGVtLCBpdGVtSW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMuX2RlZi5pdGVtc1tpdGVtSW5kZXhdIHx8IHRoaXMuX2RlZi5yZXN0O1xuICAgICAgICAgICAgaWYgKCFzY2hlbWEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgaXRlbSwgY3R4LnBhdGgsIGl0ZW1JbmRleCkpO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLmZpbHRlcigoeCkgPT4gISF4KTsgLy8gZmlsdGVyIG51bGxzXG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoaXRlbXMpLnRoZW4oKHJlc3VsdHMpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIGl0ZW1zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgaXRlbXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaXRlbXM7XG4gICAgfVxuICAgIHJlc3QocmVzdCkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFR1cGxlKHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIHJlc3QsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblpvZFR1cGxlLmNyZWF0ZSA9IChzY2hlbWFzLCBwYXJhbXMpID0+IHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2NoZW1hcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiWW91IG11c3QgcGFzcyBhbiBhcnJheSBvZiBzY2hlbWFzIHRvIHoudHVwbGUoWyAuLi4gXSlcIik7XG4gICAgfVxuICAgIHJldHVybiBuZXcgWm9kVHVwbGUoe1xuICAgICAgICBpdGVtczogc2NoZW1hcyxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RUdXBsZSxcbiAgICAgICAgcmVzdDogbnVsbCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpLFxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RSZWNvcmQgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBnZXQga2V5U2NoZW1hKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmtleVR5cGU7XG4gICAgfVxuICAgIGdldCB2YWx1ZVNjaGVtYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgfVxuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhaXJzID0gW107XG4gICAgICAgIGNvbnN0IGtleVR5cGUgPSB0aGlzLl9kZWYua2V5VHlwZTtcbiAgICAgICAgY29uc3QgdmFsdWVUeXBlID0gdGhpcy5fZGVmLnZhbHVlVHlwZTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gY3R4LmRhdGEpIHtcbiAgICAgICAgICAgIHBhaXJzLnB1c2goe1xuICAgICAgICAgICAgICAgIGtleToga2V5VHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGtleSwgY3R4LnBhdGgsIGtleSkpLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBjdHguZGF0YVtrZXldLCBjdHgucGF0aCwga2V5KSksXG4gICAgICAgICAgICAgICAgYWx3YXlzU2V0OiBrZXkgaW4gY3R4LmRhdGEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0QXN5bmMoc3RhdHVzLCBwYWlycyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgcGFpcnMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBlbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlVHlwZTtcbiAgICB9XG4gICAgc3RhdGljIGNyZWF0ZShmaXJzdCwgc2Vjb25kLCB0aGlyZCkge1xuICAgICAgICBpZiAoc2Vjb25kIGluc3RhbmNlb2YgWm9kVHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoe1xuICAgICAgICAgICAgICAgIGtleVR5cGU6IGZpcnN0LFxuICAgICAgICAgICAgICAgIHZhbHVlVHlwZTogc2Vjb25kLFxuICAgICAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUmVjb3JkLFxuICAgICAgICAgICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcmQpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoe1xuICAgICAgICAgICAga2V5VHlwZTogWm9kU3RyaW5nLmNyZWF0ZSgpLFxuICAgICAgICAgICAgdmFsdWVUeXBlOiBmaXJzdCxcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUmVjb3JkLFxuICAgICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhzZWNvbmQpLFxuICAgICAgICB9KTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kTWFwIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgZ2V0IGtleVNjaGVtYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5rZXlUeXBlO1xuICAgIH1cbiAgICBnZXQgdmFsdWVTY2hlbWEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYudmFsdWVUeXBlO1xuICAgIH1cbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm1hcCkge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5tYXAsXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXlUeXBlID0gdGhpcy5fZGVmLmtleVR5cGU7XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgICAgIGNvbnN0IHBhaXJzID0gWy4uLmN0eC5kYXRhLmVudHJpZXMoKV0ubWFwKChba2V5LCB2YWx1ZV0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGtleToga2V5VHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGtleSwgY3R4LnBhdGgsIFtpbmRleCwgXCJrZXlcIl0pKSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWVUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgdmFsdWUsIGN0eC5wYXRoLCBbaW5kZXgsIFwidmFsdWVcIl0pKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykge1xuICAgICAgICAgICAgY29uc3QgZmluYWxNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBwYWlyIG9mIHBhaXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IHBhaXIua2V5O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHBhaXIudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImFib3J0ZWRcIiB8fCB2YWx1ZS5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gXCJkaXJ0eVwiIHx8IHZhbHVlLnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmaW5hbE1hcC5zZXQoa2V5LnZhbHVlLCB2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogZmluYWxNYXAgfTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZmluYWxNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBwYWlyLmtleTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHBhaXIudmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKGtleS5zdGF0dXMgPT09IFwiYWJvcnRlZFwiIHx8IHZhbHVlLnN0YXR1cyA9PT0gXCJhYm9ydGVkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSBcImRpcnR5XCIgfHwgdmFsdWUuc3RhdHVzID09PSBcImRpcnR5XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZpbmFsTWFwLnNldChrZXkudmFsdWUsIHZhbHVlLnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogZmluYWxNYXAgfTtcbiAgICAgICAgfVxuICAgIH1cbn1cblpvZE1hcC5jcmVhdGUgPSAoa2V5VHlwZSwgdmFsdWVUeXBlLCBwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZE1hcCh7XG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAga2V5VHlwZSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RNYXAsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kU2V0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zZXQpIHtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuc2V0LFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVmID0gdGhpcy5fZGVmO1xuICAgICAgICBpZiAoZGVmLm1pblNpemUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChjdHguZGF0YS5zaXplIDwgZGVmLm1pblNpemUudmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCxcbiAgICAgICAgICAgICAgICAgICAgbWluaW11bTogZGVmLm1pblNpemUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic2V0XCIsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkZWYubWluU2l6ZS5tZXNzYWdlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkZWYubWF4U2l6ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGN0eC5kYXRhLnNpemUgPiBkZWYubWF4U2l6ZS52YWx1ZSkge1xuICAgICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZyxcbiAgICAgICAgICAgICAgICAgICAgbWF4aW11bTogZGVmLm1heFNpemUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic2V0XCIsXG4gICAgICAgICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkZWYubWF4U2l6ZS5tZXNzYWdlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IHRoaXMuX2RlZi52YWx1ZVR5cGU7XG4gICAgICAgIGZ1bmN0aW9uIGZpbmFsaXplU2V0KGVsZW1lbnRzKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWRTZXQgPSBuZXcgU2V0KCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5zdGF0dXMgPT09IFwiZGlydHlcIilcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7XG4gICAgICAgICAgICAgICAgcGFyc2VkU2V0LmFkZChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogcGFyc2VkU2V0IH07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSBbLi4uY3R4LmRhdGEudmFsdWVzKCldLm1hcCgoaXRlbSwgaSkgPT4gdmFsdWVUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgaXRlbSwgY3R4LnBhdGgsIGkpKSk7XG4gICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoZWxlbWVudHMpLnRoZW4oKGVsZW1lbnRzKSA9PiBmaW5hbGl6ZVNldChlbGVtZW50cykpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZpbmFsaXplU2V0KGVsZW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBtaW4obWluU2l6ZSwgbWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gbmV3IFpvZFNldCh7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBtaW5TaXplOiB7IHZhbHVlOiBtaW5TaXplLCBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG1heChtYXhTaXplLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kU2V0KHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIG1heFNpemU6IHsgdmFsdWU6IG1heFNpemUsIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2l6ZShzaXplLCBtZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbihzaXplLCBtZXNzYWdlKS5tYXgoc2l6ZSwgbWVzc2FnZSk7XG4gICAgfVxuICAgIG5vbmVtcHR5KG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWluKDEsIG1lc3NhZ2UpO1xuICAgIH1cbn1cblpvZFNldC5jcmVhdGUgPSAodmFsdWVUeXBlLCBwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZFNldCh7XG4gICAgICAgIHZhbHVlVHlwZSxcbiAgICAgICAgbWluU2l6ZTogbnVsbCxcbiAgICAgICAgbWF4U2l6ZTogbnVsbCxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RTZXQsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kRnVuY3Rpb24gZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy52YWxpZGF0ZSA9IHRoaXMuaW1wbGVtZW50O1xuICAgIH1cbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5mdW5jdGlvbikge1xuICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7XG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5mdW5jdGlvbixcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG1ha2VBcmdzSXNzdWUoYXJncywgZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBtYWtlSXNzdWUoe1xuICAgICAgICAgICAgICAgIGRhdGE6IGFyZ3MsXG4gICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgZXJyb3JNYXBzOiBbY3R4LmNvbW1vbi5jb250ZXh0dWFsRXJyb3JNYXAsIGN0eC5zY2hlbWFFcnJvck1hcCwgZ2V0RXJyb3JNYXAoKSwgZGVmYXVsdEVycm9yTWFwXS5maWx0ZXIoKHgpID0+ICEheCksXG4gICAgICAgICAgICAgICAgaXNzdWVEYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX2FyZ3VtZW50cyxcbiAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzRXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBtYWtlUmV0dXJuc0lzc3VlKHJldHVybnMsIGVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gbWFrZUlzc3VlKHtcbiAgICAgICAgICAgICAgICBkYXRhOiByZXR1cm5zLFxuICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgIGVycm9yTWFwczogW2N0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLCBjdHguc2NoZW1hRXJyb3JNYXAsIGdldEVycm9yTWFwKCksIGRlZmF1bHRFcnJvck1hcF0uZmlsdGVyKCh4KSA9PiAhIXgpLFxuICAgICAgICAgICAgICAgIGlzc3VlRGF0YToge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9yZXR1cm5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuVHlwZUVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyYW1zID0geyBlcnJvck1hcDogY3R4LmNvbW1vbi5jb250ZXh0dWFsRXJyb3JNYXAgfTtcbiAgICAgICAgY29uc3QgZm4gPSBjdHguZGF0YTtcbiAgICAgICAgaWYgKHRoaXMuX2RlZi5yZXR1cm5zIGluc3RhbmNlb2YgWm9kUHJvbWlzZSkge1xuICAgICAgICAgICAgLy8gV291bGQgbG92ZSBhIHdheSB0byBhdm9pZCBkaXNhYmxpbmcgdGhpcyBydWxlLCBidXQgd2UgbmVlZFxuICAgICAgICAgICAgLy8gYW4gYWxpYXMgKHVzaW5nIGFuIGFycm93IGZ1bmN0aW9uIHdhcyB3aGF0IGNhdXNlZCAyNjUxKS5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgICAgICAgICAgY29uc3QgbWUgPSB0aGlzO1xuICAgICAgICAgICAgcmV0dXJuIE9LKGFzeW5jIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgWm9kRXJyb3IoW10pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZEFyZ3MgPSBhd2FpdCBtZS5fZGVmLmFyZ3MucGFyc2VBc3luYyhhcmdzLCBwYXJhbXMpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yLmFkZElzc3VlKG1ha2VBcmdzSXNzdWUoYXJncywgZSkpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBSZWZsZWN0LmFwcGx5KGZuLCB0aGlzLCBwYXJzZWRBcmdzKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWRSZXR1cm5zID0gYXdhaXQgbWUuX2RlZi5yZXR1cm5zLl9kZWYudHlwZVxuICAgICAgICAgICAgICAgICAgICAucGFyc2VBc3luYyhyZXN1bHQsIHBhcmFtcylcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yLmFkZElzc3VlKG1ha2VSZXR1cm5zSXNzdWUocmVzdWx0LCBlKSk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWRSZXR1cm5zO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBXb3VsZCBsb3ZlIGEgd2F5IHRvIGF2b2lkIGRpc2FibGluZyB0aGlzIHJ1bGUsIGJ1dCB3ZSBuZWVkXG4gICAgICAgICAgICAvLyBhbiBhbGlhcyAodXNpbmcgYW4gYXJyb3cgZnVuY3Rpb24gd2FzIHdoYXQgY2F1c2VkIDI2NTEpLlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgICAgICAgICBjb25zdCBtZSA9IHRoaXM7XG4gICAgICAgICAgICByZXR1cm4gT0soZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWRBcmdzID0gbWUuX2RlZi5hcmdzLnNhZmVQYXJzZShhcmdzLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgIGlmICghcGFyc2VkQXJncy5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBab2RFcnJvcihbbWFrZUFyZ3NJc3N1ZShhcmdzLCBwYXJzZWRBcmdzLmVycm9yKV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LmFwcGx5KGZuLCB0aGlzLCBwYXJzZWRBcmdzLmRhdGEpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZFJldHVybnMgPSBtZS5fZGVmLnJldHVybnMuc2FmZVBhcnNlKHJlc3VsdCwgcGFyYW1zKTtcbiAgICAgICAgICAgICAgICBpZiAoIXBhcnNlZFJldHVybnMuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgWm9kRXJyb3IoW21ha2VSZXR1cm5zSXNzdWUocmVzdWx0LCBwYXJzZWRSZXR1cm5zLmVycm9yKV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VkUmV0dXJucy5kYXRhO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcGFyYW1ldGVycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5hcmdzO1xuICAgIH1cbiAgICByZXR1cm5UeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnJldHVybnM7XG4gICAgfVxuICAgIGFyZ3MoLi4uaXRlbXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RGdW5jdGlvbih7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICBhcmdzOiBab2RUdXBsZS5jcmVhdGUoaXRlbXMpLnJlc3QoWm9kVW5rbm93bi5jcmVhdGUoKSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm5zKHJldHVyblR5cGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RGdW5jdGlvbih7XG4gICAgICAgICAgICAuLi50aGlzLl9kZWYsXG4gICAgICAgICAgICByZXR1cm5zOiByZXR1cm5UeXBlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaW1wbGVtZW50KGZ1bmMpIHtcbiAgICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jO1xuICAgIH1cbiAgICBzdHJpY3RJbXBsZW1lbnQoZnVuYykge1xuICAgICAgICBjb25zdCB2YWxpZGF0ZWRGdW5jID0gdGhpcy5wYXJzZShmdW5jKTtcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRlZEZ1bmM7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUoYXJncywgcmV0dXJucywgcGFyYW1zKSB7XG4gICAgICAgIHJldHVybiBuZXcgWm9kRnVuY3Rpb24oe1xuICAgICAgICAgICAgYXJnczogKGFyZ3MgPyBhcmdzIDogWm9kVHVwbGUuY3JlYXRlKFtdKS5yZXN0KFpvZFVua25vd24uY3JlYXRlKCkpKSxcbiAgICAgICAgICAgIHJldHVybnM6IHJldHVybnMgfHwgWm9kVW5rbm93bi5jcmVhdGUoKSxcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRnVuY3Rpb24sXG4gICAgICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBab2RMYXp5IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgZ2V0IHNjaGVtYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5nZXR0ZXIoKTtcbiAgICB9XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBsYXp5U2NoZW1hID0gdGhpcy5fZGVmLmdldHRlcigpO1xuICAgICAgICByZXR1cm4gbGF6eVNjaGVtYS5fcGFyc2UoeyBkYXRhOiBjdHguZGF0YSwgcGF0aDogY3R4LnBhdGgsIHBhcmVudDogY3R4IH0pO1xuICAgIH1cbn1cblpvZExhenkuY3JlYXRlID0gKGdldHRlciwgcGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2RMYXp5KHtcbiAgICAgICAgZ2V0dGVyOiBnZXR0ZXIsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTGF6eSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpLFxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RMaXRlcmFsIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5kYXRhICE9PSB0aGlzLl9kZWYudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9saXRlcmFsLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB0aGlzLl9kZWYudmFsdWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHN0YXR1czogXCJ2YWxpZFwiLCB2YWx1ZTogaW5wdXQuZGF0YSB9O1xuICAgIH1cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYudmFsdWU7XG4gICAgfVxufVxuWm9kTGl0ZXJhbC5jcmVhdGUgPSAodmFsdWUsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kTGl0ZXJhbCh7XG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RMaXRlcmFsLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuZnVuY3Rpb24gY3JlYXRlWm9kRW51bSh2YWx1ZXMsIHBhcmFtcykge1xuICAgIHJldHVybiBuZXcgWm9kRW51bSh7XG4gICAgICAgIHZhbHVlcyxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFbnVtLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59XG5leHBvcnQgY2xhc3MgWm9kRW51bSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0LmRhdGEgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdGhpcy5fZGVmLnZhbHVlcztcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLFxuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZSxcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlKSB7XG4gICAgICAgICAgICB0aGlzLl9jYWNoZSA9IG5ldyBTZXQodGhpcy5fZGVmLnZhbHVlcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLl9jYWNoZS5oYXMoaW5wdXQuZGF0YSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdGhpcy5fZGVmLnZhbHVlcztcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9lbnVtX3ZhbHVlLFxuICAgICAgICAgICAgICAgIG9wdGlvbnM6IGV4cGVjdGVkVmFsdWVzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7XG4gICAgfVxuICAgIGdldCBvcHRpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlcztcbiAgICB9XG4gICAgZ2V0IGVudW0oKSB7XG4gICAgICAgIGNvbnN0IGVudW1WYWx1ZXMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCB2YWwgb2YgdGhpcy5fZGVmLnZhbHVlcykge1xuICAgICAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbnVtVmFsdWVzO1xuICAgIH1cbiAgICBnZXQgVmFsdWVzKCkge1xuICAgICAgICBjb25zdCBlbnVtVmFsdWVzID0ge307XG4gICAgICAgIGZvciAoY29uc3QgdmFsIG9mIHRoaXMuX2RlZi52YWx1ZXMpIHtcbiAgICAgICAgICAgIGVudW1WYWx1ZXNbdmFsXSA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZW51bVZhbHVlcztcbiAgICB9XG4gICAgZ2V0IEVudW0oKSB7XG4gICAgICAgIGNvbnN0IGVudW1WYWx1ZXMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCB2YWwgb2YgdGhpcy5fZGVmLnZhbHVlcykge1xuICAgICAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbnVtVmFsdWVzO1xuICAgIH1cbiAgICBleHRyYWN0KHZhbHVlcywgbmV3RGVmID0gdGhpcy5fZGVmKSB7XG4gICAgICAgIHJldHVybiBab2RFbnVtLmNyZWF0ZSh2YWx1ZXMsIHtcbiAgICAgICAgICAgIC4uLnRoaXMuX2RlZixcbiAgICAgICAgICAgIC4uLm5ld0RlZixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGV4Y2x1ZGUodmFsdWVzLCBuZXdEZWYgPSB0aGlzLl9kZWYpIHtcbiAgICAgICAgcmV0dXJuIFpvZEVudW0uY3JlYXRlKHRoaXMub3B0aW9ucy5maWx0ZXIoKG9wdCkgPT4gIXZhbHVlcy5pbmNsdWRlcyhvcHQpKSwge1xuICAgICAgICAgICAgLi4udGhpcy5fZGVmLFxuICAgICAgICAgICAgLi4ubmV3RGVmLFxuICAgICAgICB9KTtcbiAgICB9XG59XG5ab2RFbnVtLmNyZWF0ZSA9IGNyZWF0ZVpvZEVudW07XG5leHBvcnQgY2xhc3MgWm9kTmF0aXZlRW51bSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCBuYXRpdmVFbnVtVmFsdWVzID0gdXRpbC5nZXRWYWxpZEVudW1WYWx1ZXModGhpcy5fZGVmLnZhbHVlcyk7XG4gICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN0cmluZyAmJiBjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5udW1iZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdXRpbC5vYmplY3RWYWx1ZXMobmF0aXZlRW51bVZhbHVlcyk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdXRpbC5qb2luVmFsdWVzKGV4cGVjdGVkVmFsdWVzKSxcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLl9jYWNoZSkge1xuICAgICAgICAgICAgdGhpcy5fY2FjaGUgPSBuZXcgU2V0KHV0aWwuZ2V0VmFsaWRFbnVtVmFsdWVzKHRoaXMuX2RlZi52YWx1ZXMpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX2NhY2hlLmhhcyhpbnB1dC5kYXRhKSkge1xuICAgICAgICAgICAgY29uc3QgZXhwZWN0ZWRWYWx1ZXMgPSB1dGlsLm9iamVjdFZhbHVlcyhuYXRpdmVFbnVtVmFsdWVzKTtcbiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVkOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9lbnVtX3ZhbHVlLFxuICAgICAgICAgICAgICAgIG9wdGlvbnM6IGV4cGVjdGVkVmFsdWVzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7XG4gICAgfVxuICAgIGdldCBlbnVtKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlcztcbiAgICB9XG59XG5ab2ROYXRpdmVFbnVtLmNyZWF0ZSA9ICh2YWx1ZXMsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kTmF0aXZlRW51bSh7XG4gICAgICAgIHZhbHVlczogdmFsdWVzLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE5hdGl2ZUVudW0sXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kUHJvbWlzZSBleHRlbmRzIFpvZFR5cGUge1xuICAgIHVud3JhcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlO1xuICAgIH1cbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7XG4gICAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5wcm9taXNlICYmIGN0eC5jb21tb24uYXN5bmMgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnByb21pc2UsXG4gICAgICAgICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9taXNpZmllZCA9IGN0eC5wYXJzZWRUeXBlID09PSBab2RQYXJzZWRUeXBlLnByb21pc2UgPyBjdHguZGF0YSA6IFByb21pc2UucmVzb2x2ZShjdHguZGF0YSk7XG4gICAgICAgIHJldHVybiBPSyhwcm9taXNpZmllZC50aGVuKChkYXRhKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGUucGFyc2VBc3luYyhkYXRhLCB7XG4gICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgZXJyb3JNYXA6IGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG59XG5ab2RQcm9taXNlLmNyZWF0ZSA9IChzY2hlbWEsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kUHJvbWlzZSh7XG4gICAgICAgIHR5cGU6IHNjaGVtYSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RQcm9taXNlLFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuZXhwb3J0IGNsYXNzIFpvZEVmZmVjdHMgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBpbm5lclR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hO1xuICAgIH1cbiAgICBzb3VyY2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNjaGVtYS5fZGVmLnR5cGVOYW1lID09PSBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0c1xuICAgICAgICAgICAgPyB0aGlzLl9kZWYuc2NoZW1hLnNvdXJjZVR5cGUoKVxuICAgICAgICAgICAgOiB0aGlzLl9kZWYuc2NoZW1hO1xuICAgIH1cbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgY29uc3QgZWZmZWN0ID0gdGhpcy5fZGVmLmVmZmVjdCB8fCBudWxsO1xuICAgICAgICBjb25zdCBjaGVja0N0eCA9IHtcbiAgICAgICAgICAgIGFkZElzc3VlOiAoYXJnKSA9PiB7XG4gICAgICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCBhcmcpO1xuICAgICAgICAgICAgICAgIGlmIChhcmcuZmF0YWwpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzLmFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhdGgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5wYXRoO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY2hlY2tDdHguYWRkSXNzdWUgPSBjaGVja0N0eC5hZGRJc3N1ZS5iaW5kKGNoZWNrQ3R4KTtcbiAgICAgICAgaWYgKGVmZmVjdC50eXBlID09PSBcInByZXByb2Nlc3NcIikge1xuICAgICAgICAgICAgY29uc3QgcHJvY2Vzc2VkID0gZWZmZWN0LnRyYW5zZm9ybShjdHguZGF0YSwgY2hlY2tDdHgpO1xuICAgICAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHByb2Nlc3NlZCkudGhlbihhc3luYyAocHJvY2Vzc2VkKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMudmFsdWUgPT09IFwiYWJvcnRlZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX2RlZi5zY2hlbWEuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogcHJvY2Vzc2VkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eCxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcImFib3J0ZWRcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJkaXJ0eVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMudmFsdWUgPT09IFwiZGlydHlcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBESVJUWShyZXN1bHQudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gXCJhYm9ydGVkXCIpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2RlZi5zY2hlbWEuX3BhcnNlU3luYyh7XG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHByb2Nlc3NlZCxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcImFib3J0ZWRcIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiZGlydHlcIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gXCJkaXJ0eVwiKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChlZmZlY3QudHlwZSA9PT0gXCJyZWZpbmVtZW50XCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4ZWN1dGVSZWZpbmVtZW50ID0gKGFjYykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGVmZmVjdC5yZWZpbmVtZW50KGFjYywgY2hlY2tDdHgpO1xuICAgICAgICAgICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXN5bmMgcmVmaW5lbWVudCBlbmNvdW50ZXJlZCBkdXJpbmcgc3luY2hyb25vdXMgcGFyc2Ugb3BlcmF0aW9uLiBVc2UgLnBhcnNlQXN5bmMgaW5zdGVhZC5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5uZXIgPSB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZVN5bmMoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChpbm5lci5zdGF0dXMgPT09IFwiYWJvcnRlZFwiKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gSU5WQUxJRDtcbiAgICAgICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSBcImRpcnR5XCIpXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgIC8vIHJldHVybiB2YWx1ZSBpcyBpZ25vcmVkXG4gICAgICAgICAgICAgICAgZXhlY3V0ZVJlZmluZW1lbnQoaW5uZXIudmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogaW5uZXIudmFsdWUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZUFzeW5jKHsgZGF0YTogY3R4LmRhdGEsIHBhdGg6IGN0eC5wYXRoLCBwYXJlbnQ6IGN0eCB9KS50aGVuKChpbm5lcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSBcImFib3J0ZWRcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSBcImRpcnR5XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4ZWN1dGVSZWZpbmVtZW50KGlubmVyLnZhbHVlKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogaW5uZXIudmFsdWUgfTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVmZmVjdC50eXBlID09PSBcInRyYW5zZm9ybVwiKSB7XG4gICAgICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBiYXNlID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWQoYmFzZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGVmZmVjdC50cmFuc2Zvcm0oYmFzZS52YWx1ZSwgY2hlY2tDdHgpO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQXN5bmNocm9ub3VzIHRyYW5zZm9ybSBlbmNvdW50ZXJlZCBkdXJpbmcgc3luY2hyb25vdXMgcGFyc2Ugb3BlcmF0aW9uLiBVc2UgLnBhcnNlQXN5bmMgaW5zdGVhZC5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiByZXN1bHQgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZUFzeW5jKHsgZGF0YTogY3R4LmRhdGEsIHBhdGg6IGN0eC5wYXRoLCBwYXJlbnQ6IGN0eCB9KS50aGVuKChiYXNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZChiYXNlKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVmZmVjdC50cmFuc2Zvcm0oYmFzZS52YWx1ZSwgY2hlY2tDdHgpKS50aGVuKChyZXN1bHQpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cy52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiByZXN1bHQsXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGVmZmVjdCk7XG4gICAgfVxufVxuWm9kRWZmZWN0cy5jcmVhdGUgPSAoc2NoZW1hLCBlZmZlY3QsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7XG4gICAgICAgIHNjaGVtYSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RFZmZlY3RzLFxuICAgICAgICBlZmZlY3QsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5ab2RFZmZlY3RzLmNyZWF0ZVdpdGhQcmVwcm9jZXNzID0gKHByZXByb2Nlc3MsIHNjaGVtYSwgcGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2RFZmZlY3RzKHtcbiAgICAgICAgc2NoZW1hLFxuICAgICAgICBlZmZlY3Q6IHsgdHlwZTogXCJwcmVwcm9jZXNzXCIsIHRyYW5zZm9ybTogcHJlcHJvY2VzcyB9LFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgeyBab2RFZmZlY3RzIGFzIFpvZFRyYW5zZm9ybWVyIH07XG5leHBvcnQgY2xhc3MgWm9kT3B0aW9uYWwgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBPSyh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZShpbnB1dCk7XG4gICAgfVxuICAgIHVud3JhcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGU7XG4gICAgfVxufVxuWm9kT3B0aW9uYWwuY3JlYXRlID0gKHR5cGUsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kT3B0aW9uYWwoe1xuICAgICAgICBpbm5lclR5cGU6IHR5cGUsXG4gICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT3B0aW9uYWwsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kTnVsbGFibGUgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpO1xuICAgICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5udWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gT0sobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGUuX3BhcnNlKGlucHV0KTtcbiAgICB9XG4gICAgdW53cmFwKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTtcbiAgICB9XG59XG5ab2ROdWxsYWJsZS5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2ROdWxsYWJsZSh7XG4gICAgICAgIGlubmVyVHlwZTogdHlwZSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2ROdWxsYWJsZSxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpLFxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2REZWZhdWx0IGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBsZXQgZGF0YSA9IGN0eC5kYXRhO1xuICAgICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBkYXRhID0gdGhpcy5fZGVmLmRlZmF1bHRWYWx1ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZSh7XG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsXG4gICAgICAgICAgICBwYXJlbnQ6IGN0eCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlbW92ZURlZmF1bHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlO1xuICAgIH1cbn1cblpvZERlZmF1bHQuY3JlYXRlID0gKHR5cGUsIHBhcmFtcykgPT4ge1xuICAgIHJldHVybiBuZXcgWm9kRGVmYXVsdCh7XG4gICAgICAgIGlubmVyVHlwZTogdHlwZSxcbiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REZWZhdWx0LFxuICAgICAgICBkZWZhdWx0VmFsdWU6IHR5cGVvZiBwYXJhbXMuZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiID8gcGFyYW1zLmRlZmF1bHQgOiAoKSA9PiBwYXJhbXMuZGVmYXVsdCxcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpLFxuICAgIH0pO1xufTtcbmV4cG9ydCBjbGFzcyBab2RDYXRjaCBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgLy8gbmV3Q3R4IGlzIHVzZWQgdG8gbm90IGNvbGxlY3QgaXNzdWVzIGZyb20gaW5uZXIgdHlwZXMgaW4gY3R4XG4gICAgICAgIGNvbnN0IG5ld0N0eCA9IHtcbiAgICAgICAgICAgIC4uLmN0eCxcbiAgICAgICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgICAgICAgIC4uLmN0eC5jb21tb24sXG4gICAgICAgICAgICAgICAgaXNzdWVzOiBbXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2RlZi5pbm5lclR5cGUuX3BhcnNlKHtcbiAgICAgICAgICAgIGRhdGE6IG5ld0N0eC5kYXRhLFxuICAgICAgICAgICAgcGF0aDogbmV3Q3R4LnBhdGgsXG4gICAgICAgICAgICBwYXJlbnQ6IHtcbiAgICAgICAgICAgICAgICAuLi5uZXdDdHgsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGlzQXN5bmMocmVzdWx0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IFwidmFsaWRcIixcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHJlc3VsdC5zdGF0dXMgPT09IFwidmFsaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPyByZXN1bHQudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5fZGVmLmNhdGNoVmFsdWUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldCBlcnJvcigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dDogbmV3Q3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN0YXR1czogXCJ2YWxpZFwiLFxuICAgICAgICAgICAgICAgIHZhbHVlOiByZXN1bHQuc3RhdHVzID09PSBcInZhbGlkXCJcbiAgICAgICAgICAgICAgICAgICAgPyByZXN1bHQudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLl9kZWYuY2F0Y2hWYWx1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQgZXJyb3IoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQ6IG5ld0N0eC5kYXRhLFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVtb3ZlQ2F0Y2goKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlO1xuICAgIH1cbn1cblpvZENhdGNoLmNyZWF0ZSA9ICh0eXBlLCBwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZENhdGNoKHtcbiAgICAgICAgaW5uZXJUeXBlOiB0eXBlLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZENhdGNoLFxuICAgICAgICBjYXRjaFZhbHVlOiB0eXBlb2YgcGFyYW1zLmNhdGNoID09PSBcImZ1bmN0aW9uXCIgPyBwYXJhbXMuY2F0Y2ggOiAoKSA9PiBwYXJhbXMuY2F0Y2gsXG4gICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSxcbiAgICB9KTtcbn07XG5leHBvcnQgY2xhc3MgWm9kTmFOIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTtcbiAgICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubmFuKSB7XG4gICAgICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7XG4gICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHtcbiAgICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLFxuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm5hbixcbiAgICAgICAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBJTlZBTElEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHN0YXR1czogXCJ2YWxpZFwiLCB2YWx1ZTogaW5wdXQuZGF0YSB9O1xuICAgIH1cbn1cblpvZE5hTi5jcmVhdGUgPSAocGFyYW1zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBab2ROYU4oe1xuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE5hTixcbiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpLFxuICAgIH0pO1xufTtcbmV4cG9ydCBjb25zdCBCUkFORCA9IFN5bWJvbChcInpvZF9icmFuZFwiKTtcbmV4cG9ydCBjbGFzcyBab2RCcmFuZGVkIGV4dGVuZHMgWm9kVHlwZSB7XG4gICAgX3BhcnNlKGlucHV0KSB7XG4gICAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpO1xuICAgICAgICBjb25zdCBkYXRhID0gY3R4LmRhdGE7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYudHlwZS5fcGFyc2Uoe1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgcGFyZW50OiBjdHgsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB1bndyYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYudHlwZTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgWm9kUGlwZWxpbmUgZXh0ZW5kcyBab2RUeXBlIHtcbiAgICBfcGFyc2UoaW5wdXQpIHtcbiAgICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTtcbiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZUFzeW5jID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluUmVzdWx0ID0gYXdhaXQgdGhpcy5fZGVmLmluLl9wYXJzZUFzeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoaW5SZXN1bHQuc3RhdHVzID09PSBcImFib3J0ZWRcIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gXCJkaXJ0eVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRElSVFkoaW5SZXN1bHQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vdXQuX3BhcnNlQXN5bmMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogaW5SZXN1bHQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogY3R4LFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIGhhbmRsZUFzeW5jKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBpblJlc3VsdCA9IHRoaXMuX2RlZi5pbi5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICBkYXRhOiBjdHguZGF0YSxcbiAgICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCxcbiAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gXCJhYm9ydGVkXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7XG4gICAgICAgICAgICBpZiAoaW5SZXN1bHQuc3RhdHVzID09PSBcImRpcnR5XCIpIHtcbiAgICAgICAgICAgICAgICBzdGF0dXMuZGlydHkoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IFwiZGlydHlcIixcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGluUmVzdWx0LnZhbHVlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLm91dC5fcGFyc2VTeW5jKHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogaW5SZXN1bHQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLFxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGN0eCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgY3JlYXRlKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBab2RQaXBlbGluZSh7XG4gICAgICAgICAgICBpbjogYSxcbiAgICAgICAgICAgIG91dDogYixcbiAgICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUGlwZWxpbmUsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBab2RSZWFkb25seSBleHRlbmRzIFpvZFR5cGUge1xuICAgIF9wYXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZShpbnB1dCk7XG4gICAgICAgIGNvbnN0IGZyZWV6ZSA9IChkYXRhKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNWYWxpZChkYXRhKSkge1xuICAgICAgICAgICAgICAgIGRhdGEudmFsdWUgPSBPYmplY3QuZnJlZXplKGRhdGEudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBpc0FzeW5jKHJlc3VsdCkgPyByZXN1bHQudGhlbigoZGF0YSkgPT4gZnJlZXplKGRhdGEpKSA6IGZyZWV6ZShyZXN1bHQpO1xuICAgIH1cbiAgICB1bndyYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlO1xuICAgIH1cbn1cblpvZFJlYWRvbmx5LmNyZWF0ZSA9ICh0eXBlLCBwYXJhbXMpID0+IHtcbiAgICByZXR1cm4gbmV3IFpvZFJlYWRvbmx5KHtcbiAgICAgICAgaW5uZXJUeXBlOiB0eXBlLFxuICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFJlYWRvbmx5LFxuICAgICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcyksXG4gICAgfSk7XG59O1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgIHouY3VzdG9tICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLyAgICAgICAgICAgICAgICAgICAgLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuZnVuY3Rpb24gY2xlYW5QYXJhbXMocGFyYW1zLCBkYXRhKSB7XG4gICAgY29uc3QgcCA9IHR5cGVvZiBwYXJhbXMgPT09IFwiZnVuY3Rpb25cIiA/IHBhcmFtcyhkYXRhKSA6IHR5cGVvZiBwYXJhbXMgPT09IFwic3RyaW5nXCIgPyB7IG1lc3NhZ2U6IHBhcmFtcyB9IDogcGFyYW1zO1xuICAgIGNvbnN0IHAyID0gdHlwZW9mIHAgPT09IFwic3RyaW5nXCIgPyB7IG1lc3NhZ2U6IHAgfSA6IHA7XG4gICAgcmV0dXJuIHAyO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGN1c3RvbShjaGVjaywgX3BhcmFtcyA9IHt9LCBcbi8qKlxuICogQGRlcHJlY2F0ZWRcbiAqXG4gKiBQYXNzIGBmYXRhbGAgaW50byB0aGUgcGFyYW1zIG9iamVjdCBpbnN0ZWFkOlxuICpcbiAqIGBgYHRzXG4gKiB6LnN0cmluZygpLmN1c3RvbSgodmFsKSA9PiB2YWwubGVuZ3RoID4gNSwgeyBmYXRhbDogZmFsc2UgfSlcbiAqIGBgYFxuICpcbiAqL1xuZmF0YWwpIHtcbiAgICBpZiAoY2hlY2spXG4gICAgICAgIHJldHVybiBab2RBbnkuY3JlYXRlKCkuc3VwZXJSZWZpbmUoKGRhdGEsIGN0eCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgciA9IGNoZWNrKGRhdGEpO1xuICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHIudGhlbigocikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IGNsZWFuUGFyYW1zKF9wYXJhbXMsIGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgX2ZhdGFsID0gcGFyYW1zLmZhdGFsID8/IGZhdGFsID8/IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguYWRkSXNzdWUoeyBjb2RlOiBcImN1c3RvbVwiLCAuLi5wYXJhbXMsIGZhdGFsOiBfZmF0YWwgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghcikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IGNsZWFuUGFyYW1zKF9wYXJhbXMsIGRhdGEpO1xuICAgICAgICAgICAgICAgIGNvbnN0IF9mYXRhbCA9IHBhcmFtcy5mYXRhbCA/PyBmYXRhbCA/PyB0cnVlO1xuICAgICAgICAgICAgICAgIGN0eC5hZGRJc3N1ZSh7IGNvZGU6IFwiY3VzdG9tXCIsIC4uLnBhcmFtcywgZmF0YWw6IF9mYXRhbCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSk7XG4gICAgcmV0dXJuIFpvZEFueS5jcmVhdGUoKTtcbn1cbmV4cG9ydCB7IFpvZFR5cGUgYXMgU2NoZW1hLCBab2RUeXBlIGFzIFpvZFNjaGVtYSB9O1xuZXhwb3J0IGNvbnN0IGxhdGUgPSB7XG4gICAgb2JqZWN0OiBab2RPYmplY3QubGF6eWNyZWF0ZSxcbn07XG5leHBvcnQgdmFyIFpvZEZpcnN0UGFydHlUeXBlS2luZDtcbihmdW5jdGlvbiAoWm9kRmlyc3RQYXJ0eVR5cGVLaW5kKSB7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kU3RyaW5nXCJdID0gXCJab2RTdHJpbmdcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROdW1iZXJcIl0gPSBcIlpvZE51bWJlclwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZE5hTlwiXSA9IFwiWm9kTmFOXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kQmlnSW50XCJdID0gXCJab2RCaWdJbnRcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RCb29sZWFuXCJdID0gXCJab2RCb29sZWFuXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGF0ZVwiXSA9IFwiWm9kRGF0ZVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFN5bWJvbFwiXSA9IFwiWm9kU3ltYm9sXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVW5kZWZpbmVkXCJdID0gXCJab2RVbmRlZmluZWRcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROdWxsXCJdID0gXCJab2ROdWxsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kQW55XCJdID0gXCJab2RBbnlcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RVbmtub3duXCJdID0gXCJab2RVbmtub3duXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTmV2ZXJcIl0gPSBcIlpvZE5ldmVyXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVm9pZFwiXSA9IFwiWm9kVm9pZFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEFycmF5XCJdID0gXCJab2RBcnJheVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZE9iamVjdFwiXSA9IFwiWm9kT2JqZWN0XCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kVW5pb25cIl0gPSBcIlpvZFVuaW9uXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGlzY3JpbWluYXRlZFVuaW9uXCJdID0gXCJab2REaXNjcmltaW5hdGVkVW5pb25cIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RJbnRlcnNlY3Rpb25cIl0gPSBcIlpvZEludGVyc2VjdGlvblwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFR1cGxlXCJdID0gXCJab2RUdXBsZVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFJlY29yZFwiXSA9IFwiWm9kUmVjb3JkXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTWFwXCJdID0gXCJab2RNYXBcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RTZXRcIl0gPSBcIlpvZFNldFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEZ1bmN0aW9uXCJdID0gXCJab2RGdW5jdGlvblwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZExhenlcIl0gPSBcIlpvZExhenlcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RMaXRlcmFsXCJdID0gXCJab2RMaXRlcmFsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRW51bVwiXSA9IFwiWm9kRW51bVwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZEVmZmVjdHNcIl0gPSBcIlpvZEVmZmVjdHNcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2ROYXRpdmVFbnVtXCJdID0gXCJab2ROYXRpdmVFbnVtXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kT3B0aW9uYWxcIl0gPSBcIlpvZE9wdGlvbmFsXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kTnVsbGFibGVcIl0gPSBcIlpvZE51bGxhYmxlXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kRGVmYXVsdFwiXSA9IFwiWm9kRGVmYXVsdFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZENhdGNoXCJdID0gXCJab2RDYXRjaFwiO1xuICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZFtcIlpvZFByb21pc2VcIl0gPSBcIlpvZFByb21pc2VcIjtcbiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmRbXCJab2RCcmFuZGVkXCJdID0gXCJab2RCcmFuZGVkXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kUGlwZWxpbmVcIl0gPSBcIlpvZFBpcGVsaW5lXCI7XG4gICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kW1wiWm9kUmVhZG9ubHlcIl0gPSBcIlpvZFJlYWRvbmx5XCI7XG59KShab2RGaXJzdFBhcnR5VHlwZUtpbmQgfHwgKFpvZEZpcnN0UGFydHlUeXBlS2luZCA9IHt9KSk7XG4vLyByZXF1aXJlcyBUUyA0LjQrXG5jbGFzcyBDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoLi4uXykgeyB9XG59XG5jb25zdCBpbnN0YW5jZU9mVHlwZSA9IChcbi8vIGNvbnN0IGluc3RhbmNlT2ZUeXBlID0gPFQgZXh0ZW5kcyBuZXcgKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnk+KFxuY2xzLCBwYXJhbXMgPSB7XG4gICAgbWVzc2FnZTogYElucHV0IG5vdCBpbnN0YW5jZSBvZiAke2Nscy5uYW1lfWAsXG59KSA9PiBjdXN0b20oKGRhdGEpID0+IGRhdGEgaW5zdGFuY2VvZiBjbHMsIHBhcmFtcyk7XG5jb25zdCBzdHJpbmdUeXBlID0gWm9kU3RyaW5nLmNyZWF0ZTtcbmNvbnN0IG51bWJlclR5cGUgPSBab2ROdW1iZXIuY3JlYXRlO1xuY29uc3QgbmFuVHlwZSA9IFpvZE5hTi5jcmVhdGU7XG5jb25zdCBiaWdJbnRUeXBlID0gWm9kQmlnSW50LmNyZWF0ZTtcbmNvbnN0IGJvb2xlYW5UeXBlID0gWm9kQm9vbGVhbi5jcmVhdGU7XG5jb25zdCBkYXRlVHlwZSA9IFpvZERhdGUuY3JlYXRlO1xuY29uc3Qgc3ltYm9sVHlwZSA9IFpvZFN5bWJvbC5jcmVhdGU7XG5jb25zdCB1bmRlZmluZWRUeXBlID0gWm9kVW5kZWZpbmVkLmNyZWF0ZTtcbmNvbnN0IG51bGxUeXBlID0gWm9kTnVsbC5jcmVhdGU7XG5jb25zdCBhbnlUeXBlID0gWm9kQW55LmNyZWF0ZTtcbmNvbnN0IHVua25vd25UeXBlID0gWm9kVW5rbm93bi5jcmVhdGU7XG5jb25zdCBuZXZlclR5cGUgPSBab2ROZXZlci5jcmVhdGU7XG5jb25zdCB2b2lkVHlwZSA9IFpvZFZvaWQuY3JlYXRlO1xuY29uc3QgYXJyYXlUeXBlID0gWm9kQXJyYXkuY3JlYXRlO1xuY29uc3Qgb2JqZWN0VHlwZSA9IFpvZE9iamVjdC5jcmVhdGU7XG5jb25zdCBzdHJpY3RPYmplY3RUeXBlID0gWm9kT2JqZWN0LnN0cmljdENyZWF0ZTtcbmNvbnN0IHVuaW9uVHlwZSA9IFpvZFVuaW9uLmNyZWF0ZTtcbmNvbnN0IGRpc2NyaW1pbmF0ZWRVbmlvblR5cGUgPSBab2REaXNjcmltaW5hdGVkVW5pb24uY3JlYXRlO1xuY29uc3QgaW50ZXJzZWN0aW9uVHlwZSA9IFpvZEludGVyc2VjdGlvbi5jcmVhdGU7XG5jb25zdCB0dXBsZVR5cGUgPSBab2RUdXBsZS5jcmVhdGU7XG5jb25zdCByZWNvcmRUeXBlID0gWm9kUmVjb3JkLmNyZWF0ZTtcbmNvbnN0IG1hcFR5cGUgPSBab2RNYXAuY3JlYXRlO1xuY29uc3Qgc2V0VHlwZSA9IFpvZFNldC5jcmVhdGU7XG5jb25zdCBmdW5jdGlvblR5cGUgPSBab2RGdW5jdGlvbi5jcmVhdGU7XG5jb25zdCBsYXp5VHlwZSA9IFpvZExhenkuY3JlYXRlO1xuY29uc3QgbGl0ZXJhbFR5cGUgPSBab2RMaXRlcmFsLmNyZWF0ZTtcbmNvbnN0IGVudW1UeXBlID0gWm9kRW51bS5jcmVhdGU7XG5jb25zdCBuYXRpdmVFbnVtVHlwZSA9IFpvZE5hdGl2ZUVudW0uY3JlYXRlO1xuY29uc3QgcHJvbWlzZVR5cGUgPSBab2RQcm9taXNlLmNyZWF0ZTtcbmNvbnN0IGVmZmVjdHNUeXBlID0gWm9kRWZmZWN0cy5jcmVhdGU7XG5jb25zdCBvcHRpb25hbFR5cGUgPSBab2RPcHRpb25hbC5jcmVhdGU7XG5jb25zdCBudWxsYWJsZVR5cGUgPSBab2ROdWxsYWJsZS5jcmVhdGU7XG5jb25zdCBwcmVwcm9jZXNzVHlwZSA9IFpvZEVmZmVjdHMuY3JlYXRlV2l0aFByZXByb2Nlc3M7XG5jb25zdCBwaXBlbGluZVR5cGUgPSBab2RQaXBlbGluZS5jcmVhdGU7XG5jb25zdCBvc3RyaW5nID0gKCkgPT4gc3RyaW5nVHlwZSgpLm9wdGlvbmFsKCk7XG5jb25zdCBvbnVtYmVyID0gKCkgPT4gbnVtYmVyVHlwZSgpLm9wdGlvbmFsKCk7XG5jb25zdCBvYm9vbGVhbiA9ICgpID0+IGJvb2xlYW5UeXBlKCkub3B0aW9uYWwoKTtcbmV4cG9ydCBjb25zdCBjb2VyY2UgPSB7XG4gICAgc3RyaW5nOiAoKGFyZykgPT4gWm9kU3RyaW5nLmNyZWF0ZSh7IC4uLmFyZywgY29lcmNlOiB0cnVlIH0pKSxcbiAgICBudW1iZXI6ICgoYXJnKSA9PiBab2ROdW1iZXIuY3JlYXRlKHsgLi4uYXJnLCBjb2VyY2U6IHRydWUgfSkpLFxuICAgIGJvb2xlYW46ICgoYXJnKSA9PiBab2RCb29sZWFuLmNyZWF0ZSh7XG4gICAgICAgIC4uLmFyZyxcbiAgICAgICAgY29lcmNlOiB0cnVlLFxuICAgIH0pKSxcbiAgICBiaWdpbnQ6ICgoYXJnKSA9PiBab2RCaWdJbnQuY3JlYXRlKHsgLi4uYXJnLCBjb2VyY2U6IHRydWUgfSkpLFxuICAgIGRhdGU6ICgoYXJnKSA9PiBab2REYXRlLmNyZWF0ZSh7IC4uLmFyZywgY29lcmNlOiB0cnVlIH0pKSxcbn07XG5leHBvcnQgeyBhbnlUeXBlIGFzIGFueSwgYXJyYXlUeXBlIGFzIGFycmF5LCBiaWdJbnRUeXBlIGFzIGJpZ2ludCwgYm9vbGVhblR5cGUgYXMgYm9vbGVhbiwgZGF0ZVR5cGUgYXMgZGF0ZSwgZGlzY3JpbWluYXRlZFVuaW9uVHlwZSBhcyBkaXNjcmltaW5hdGVkVW5pb24sIGVmZmVjdHNUeXBlIGFzIGVmZmVjdCwgZW51bVR5cGUgYXMgZW51bSwgZnVuY3Rpb25UeXBlIGFzIGZ1bmN0aW9uLCBpbnN0YW5jZU9mVHlwZSBhcyBpbnN0YW5jZW9mLCBpbnRlcnNlY3Rpb25UeXBlIGFzIGludGVyc2VjdGlvbiwgbGF6eVR5cGUgYXMgbGF6eSwgbGl0ZXJhbFR5cGUgYXMgbGl0ZXJhbCwgbWFwVHlwZSBhcyBtYXAsIG5hblR5cGUgYXMgbmFuLCBuYXRpdmVFbnVtVHlwZSBhcyBuYXRpdmVFbnVtLCBuZXZlclR5cGUgYXMgbmV2ZXIsIG51bGxUeXBlIGFzIG51bGwsIG51bGxhYmxlVHlwZSBhcyBudWxsYWJsZSwgbnVtYmVyVHlwZSBhcyBudW1iZXIsIG9iamVjdFR5cGUgYXMgb2JqZWN0LCBvYm9vbGVhbiwgb251bWJlciwgb3B0aW9uYWxUeXBlIGFzIG9wdGlvbmFsLCBvc3RyaW5nLCBwaXBlbGluZVR5cGUgYXMgcGlwZWxpbmUsIHByZXByb2Nlc3NUeXBlIGFzIHByZXByb2Nlc3MsIHByb21pc2VUeXBlIGFzIHByb21pc2UsIHJlY29yZFR5cGUgYXMgcmVjb3JkLCBzZXRUeXBlIGFzIHNldCwgc3RyaWN0T2JqZWN0VHlwZSBhcyBzdHJpY3RPYmplY3QsIHN0cmluZ1R5cGUgYXMgc3RyaW5nLCBzeW1ib2xUeXBlIGFzIHN5bWJvbCwgZWZmZWN0c1R5cGUgYXMgdHJhbnNmb3JtZXIsIHR1cGxlVHlwZSBhcyB0dXBsZSwgdW5kZWZpbmVkVHlwZSBhcyB1bmRlZmluZWQsIHVuaW9uVHlwZSBhcyB1bmlvbiwgdW5rbm93blR5cGUgYXMgdW5rbm93biwgdm9pZFR5cGUgYXMgdm9pZCwgfTtcbmV4cG9ydCBjb25zdCBORVZFUiA9IElOVkFMSUQ7XG4iLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCAiZXhwb3J0IHsgbGlzdEFnZW50cyB9IGZyb20gJy4vbGlzdC1hZ2VudHMubWpzJztcbmV4cG9ydCB7IGdldEFnZW50IH0gZnJvbSAnLi9nZXQtYWdlbnQubWpzJztcbmV4cG9ydCB7IGxpc3RQcmltaXRpdmVWZXJzaW9ucyB9IGZyb20gJy4vbGlzdC1wcmltaXRpdmUtdmVyc2lvbnMubWpzJztcbmV4cG9ydCB7IGdldERlcGxveW1lbnRTdGF0dXMgfSBmcm9tICcuL2dldC1kZXBsb3ltZW50LXN0YXR1cy5tanMnO1xuZXhwb3J0IHsgdGFpbExvZ3MgfSBmcm9tICcuL3RhaWwtbG9ncy5tanMnO1xuLy8gY2hlY2tfZHJpZnQgcmVtb3ZlZCBpbiB2MS4yNSBcdTIwMTQgdXNlIEJhc2gobHVhIHN5bmMgLS1jaGVjaykgZGlyZWN0bHkuIFRoZVxuLy8gTUNQIHNlcnZlciBpcyBsb2NhbCBhbmQgc28gaXMgdGhlIENMSTsgcmVpbXBsZW1lbnRpbmcgZHJpZnQgZGV0ZWN0aW9uXG4vLyBzZXJ2ZXItc2lkZSBvciBpbiB0aGUgTUNQIHdvdWxkIGR1cGxpY2F0ZSBsb2dpYyB0aGF0IGx1YS1jbGkgYWxyZWFkeSBvd25zLlxuIiwgIi8vIFNoYXJlZCBzdWJwcm9jZXNzIGhlbHBlciBmb3IgdG9vbHMgdGhhdCBzaGVsbCBvdXQgdG8gdGhlIGx1YS1jbGkgYmluYXJ5LlxuLy9cbi8vIFdoeSBzaGVsbCBvdXQgYXQgYWxsOiB0aGVyZSBpcyBubyBcImxpc3QgZXZlcnkgYWdlbnQgdGhpcyBjcmVkZW50aWFsIGNhblxuLy8gcmVhY2hcIiBSRVNUIHJvdXRlIFx1MjAxNCBgbHVhIGFnZW50cyAtLWpzb25gIGFscmVhZHkgZG9lcyB0aGUgY3JlZGVudGlhbC10by1cbi8vIGF1dGhvcml6YXRpb24tcHJvamVjdGlvbiByZXNvbHV0aW9uIChQUk8tMTcxMikgZm9yIGV2ZXJ5IGNyZWRlbnRpYWwgY2xhc3Ncbi8vIChBUEkga2V5LCB0eXBlZCBzY29wZWQga2V5LCByZW5ld2FibGUgc2Vzc2lvbikuIFJlaW1wbGVtZW50aW5nIHRoYXQgaW4gdGhlXG4vLyBNQ1Agd291bGQgZHVwbGljYXRlIGxvZ2ljIGx1YS1jbGkgb3ducy5cblxuaW1wb3J0IHsgc3Bhd24gfSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuXG4vLyBgbHVhIGFnZW50c2Agd2Fsa3MgZXZlcnkgb3JnYW5pc2F0aW9uIHRoZSBjcmVkZW50aWFsIGNhbiBzZWUgYW5kLCBmb3IgYVxuLy8gc2Vzc2lvbiBsb2dpbiwgcmVmcmVzaGVzIHRoZSBzZXNzaW9uIGZpcnN0LiBNZWFzdXJlZCAyMDI2LTA5LTEyIG9uIGFcbi8vIDE0NC1vcmcgYWNjb3VudDogMThcdTIwMTMyNSBzLiBUaGUgYnVkZ2V0IG11c3QgY292ZXIgdGhhdC5cbmNvbnN0IERFRkFVTFRfVElNRU9VVF9NUyA9IDYwXzAwMDtcblxuLyoqXG4gKiBSdW4gYGx1YSA8YXJncz5gIGFuZCByZXNvbHZlIHdpdGggaXRzIHN0ZG91dC5cbiAqXG4gKiBPbiBXaW5kb3dzIHRoZSBucG0gYmluIGlzIGEgYGx1YS5jbWRgIHNoaW0sIHdoaWNoIE5vZGUgKFx1MjI2NTE4LjIwIC8gXHUyMjY1MjAuMTIpXG4gKiByZWZ1c2VzIHRvIHNwYXduIHdpdGhvdXQgYSBzaGVsbDsgdGhlIGFyZ3MgYXJlIGZpeGVkIGxpdGVyYWxzIChubyB1c2VyXG4gKiBpbnB1dCksIHNvIGBzaGVsbDogdHJ1ZWAgdGhlcmUgaXMgc2FmZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzXG4gKiBAcGFyYW0ge3tzcGF3bkZuPzogdHlwZW9mIHNwYXduLCB0aW1lb3V0TXM/OiBudW1iZXIsIGxhYmVsPzogc3RyaW5nfX0gW29wdHNdXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gcnVuTHVhKGFyZ3MsIHsgc3Bhd25GbiA9IHNwYXduLCB0aW1lb3V0TXMgPSBERUZBVUxUX1RJTUVPVVRfTVMsIGxhYmVsID0gJ2x1YScgfSA9IHt9KSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2hpbGQgPSBzcGF3bkZuKCdsdWEnLCBhcmdzLCB7XG4gICAgICBzaGVsbDogcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyxcbiAgICAgIHdpbmRvd3NIaWRlOiB0cnVlLFxuICAgICAgZW52OiB7IC4uLnByb2Nlc3MuZW52LCBMVUFfTk9fQkFOTkVSOiAnMScsIExVQV9OT19ISU5UUzogJzEnIH0sXG4gICAgfSk7XG4gICAgbGV0IHN0ZG91dCA9ICcnO1xuICAgIGxldCBzdGRlcnIgPSAnJztcbiAgICBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCAoZCkgPT4geyBzdGRvdXQgKz0gZC50b1N0cmluZygndXRmOCcpOyB9KTtcbiAgICBjaGlsZC5zdGRlcnIub24oJ2RhdGEnLCAoZCkgPT4geyBzdGRlcnIgKz0gZC50b1N0cmluZygndXRmOCcpOyB9KTtcblxuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjaGlsZC5raWxsKCdTSUdURVJNJyk7XG4gICAgICByZWplY3QobmV3IEVycm9yKGAke2xhYmVsfTogJ2x1YSAke2FyZ3Muam9pbignICcpfScgdGltZWQgb3V0IGFmdGVyICR7dGltZW91dE1zfW1zYCkpO1xuICAgIH0sIHRpbWVvdXRNcyk7XG5cbiAgICBjaGlsZC5vbignZXhpdCcsIChjb2RlKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgaWYgKGNvZGUgIT09IDApIHJlamVjdChuZXcgRXJyb3IoYCdsdWEgJHthcmdzLmpvaW4oJyAnKX0nIGV4aXRlZCAke2NvZGV9OiAke3N0ZGVyci50cmltKCl9YCkpO1xuICAgICAgZWxzZSByZXNvbHZlKHN0ZG91dCk7XG4gICAgfSk7XG4gICAgY2hpbGQub24oJ2Vycm9yJywgKGVycikgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIHJlamVjdChlcnIpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBGbGF0dGVuIGBsdWEgYWdlbnRzIC0tanNvbmAgb3V0cHV0IChsdWEtY2xpIFx1MjI2NSAzLjI4OiBhbiBhcnJheSBvZlxuICogQ3JlZGVudGlhbE9yZ2FuaXphdGlvbiByb3dzIFx1MjAxNCBgeyBvcmdJZCwgbmFtZT8sIGFyY2hpdmVkLCBkaXNjb3ZlcmVkVmlhLFxuICogYWdlbnRzOiBbeyBhZ2VudElkLCBuYW1lPywgdmlzaWJpbGl0eSwgZGlzcGxheVJvbGVzIH1dIH1gLCBzZWVcbiAqIHBhY2thZ2VzL2x1YS1jbGkvc3JjL3NlcnZpY2VzL2NyZWRlbnRpYWwtb3BlcmF0aW9uYWwtY29udGV4dC50cykgaW50byBhXG4gKiBjb21wYWN0IGFnZW50IGxpc3QuIE9sZGVyIGZsYXQgc2hhcGVzIGFyZSB0b2xlcmF0ZWQgZm9yIGZvcndhcmQtY29tcGF0LlxuICpcbiAqIEBwYXJhbSB7dW5rbm93bn0gcGFyc2VkXG4gKiBAcmV0dXJucyB7QXJyYXk8e2lkOiBzdHJpbmcsIG5hbWU6IHN0cmluZ3xudWxsLCBvcmdJZDogc3RyaW5nfG51bGwsIG9yZ05hbWU6IHN0cmluZ3xudWxsLCB2aXNpYmlsaXR5OiBzdHJpbmd8bnVsbH0+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZmxhdHRlbkFnZW50cyhwYXJzZWQpIHtcbiAgY29uc3Qgb2JqID0gLyoqIEB0eXBlIHthbnl9ICovIChwYXJzZWQpO1xuICBjb25zdCBlbnRyaWVzID0gQXJyYXkuaXNBcnJheShvYmopID8gb2JqIDogKG9iaj8uYWdlbnRzID8/IG9iaj8ub3JncyA/PyBbXSk7XG4gIGNvbnN0IGxvb2tzTGlrZU9yZ3MgPSBlbnRyaWVzLmxlbmd0aCA+IDAgJiYgZW50cmllc1swXSAmJiBBcnJheS5pc0FycmF5KGVudHJpZXNbMF0uYWdlbnRzKTtcblxuICBpZiAobG9va3NMaWtlT3Jncykge1xuICAgIHJldHVybiBlbnRyaWVzLmZsYXRNYXAoKG9yZykgPT4gKG9yZy5hZ2VudHMgPz8gW10pLm1hcCgoYSkgPT4gKHtcbiAgICAgIGlkOiBhLmFnZW50SWQgPz8gYS5pZCA/PyBhLl9pZCxcbiAgICAgIG5hbWU6IGEubmFtZSA/PyBudWxsLFxuICAgICAgb3JnSWQ6IG9yZy5vcmdJZCA/PyBvcmcuaWQgPz8gb3JnLl9pZCA/PyBudWxsLFxuICAgICAgb3JnTmFtZTogb3JnLm5hbWUgPz8gb3JnLnJlZ2lzdGVyZWROYW1lID8/IG51bGwsXG4gICAgICB2aXNpYmlsaXR5OiBhLnZpc2liaWxpdHkgPz8gbnVsbCxcbiAgICB9KSkpO1xuICB9XG4gIHJldHVybiBlbnRyaWVzLm1hcCgoYSkgPT4gKHtcbiAgICBpZDogYS5hZ2VudElkID8/IGEuaWQgPz8gYS5faWQsXG4gICAgbmFtZTogYS5uYW1lID8/IG51bGwsXG4gICAgb3JnSWQ6IGEub3JnSWQgPz8gbnVsbCxcbiAgICBvcmdOYW1lOiBhLm9yZ05hbWUgPz8gbnVsbCxcbiAgICB2aXNpYmlsaXR5OiBhLnZpc2liaWxpdHkgPz8gbnVsbCxcbiAgfSkpO1xufVxuXG4vKipcbiAqIFJ1biBgbHVhIGFnZW50cyAtLWpzb24gLS1jaWAgYW5kIHJldHVybiB0aGUgZmxhdHRlbmVkIGFnZW50IGxpc3QuXG4gKlxuICogQHBhcmFtIHt7c3Bhd25Gbj86IHR5cGVvZiBzcGF3biwgbGFiZWw/OiBzdHJpbmd9fSBbb3B0c11cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RBZ2VudHNWaWFDbGkoeyBzcGF3bkZuLCBsYWJlbCA9ICdsaXN0X2FnZW50cycgfSA9IHt9KSB7XG4gIGNvbnN0IHN0ZG91dCA9IGF3YWl0IHJ1bkx1YShbJ2FnZW50cycsICctLWpzb24nLCAnLS1jaSddLCB7IHNwYXduRm4sIGxhYmVsIH0pO1xuICBsZXQgcGFyc2VkO1xuICB0cnkge1xuICAgIHBhcnNlZCA9IEpTT04ucGFyc2Uoc3Rkb3V0KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke2xhYmVsfTogY291bGQgbm90IHBhcnNlICdsdWEgYWdlbnRzIC0tanNvbicgb3V0cHV0OiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG4gIHJldHVybiBmbGF0dGVuQWdlbnRzKHBhcnNlZCk7XG59XG4iLCAiaW1wb3J0IHsgbGlzdEFnZW50c1ZpYUNsaSB9IGZyb20gJy4uL3J1bi1sdWEubWpzJztcblxuLy8gU2hlbGxzIG91dCB0byBgbHVhIGFnZW50cyAtLWpzb24gLS1jaWAgKHNlZSBydW4tbHVhLm1qcyBmb3Igd2h5KS4gVGhlIENMSVxuLy8gZW1pdHMgb25lIHJvdyBwZXIgb3JnYW5pc2F0aW9uIHdpdGggYSBuZXN0ZWQgYGFnZW50c2AgYXJyYXk7IHdlIGZsYXR0ZW4uXG5cbmV4cG9ydCBjb25zdCBsaXN0QWdlbnRzID0ge1xuICBzcGVjOiB7XG4gICAgbmFtZTogJ2xpc3RfYWdlbnRzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0xpc3QgYWxsIEx1YSBhZ2VudHMgdGhlIGF1dGhlbnRpY2F0ZWQgY3JlZGVudGlhbCBjYW4gcmVhY2guIFJldHVybnMgYSBjb21wYWN0IGFycmF5IG9mIHtpZCwgbmFtZSwgb3JnSWQsIG9yZ05hbWUsIHZpc2liaWxpdHl9IGZsYXR0ZW5lZCBhY3Jvc3MgYWxsIG9yZ2FuaXNhdGlvbnMuIFNhbWUgZGF0YSBhcyBgbHVhIGFnZW50cyAtLWpzb25gIFx1MjAxNCBpdCByZXNvbHZlcyBldmVyeSBvcmdhbmlzYXRpb24sIHNvIG9uIGFjY291bnRzIHdpdGggbWFueSBvcmdzIHRoaXMgdGFrZXMgMjAgcyBvciBtb3JlOyBwcmVmZXIgZ2V0X2FnZW50IHdoZW4geW91IGFscmVhZHkga25vdyB0aGUgaWQuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7fSxcbiAgICAgIHJlcXVpcmVkOiBbXSxcbiAgICB9LFxuICB9LFxuICBhc3luYyBoYW5kbGVyKF9hcmdzLCBkZXBzID0ge30pIHtcbiAgICBjb25zdCBjb21wYWN0ID0gYXdhaXQgbGlzdEFnZW50c1ZpYUNsaSh7IHNwYXduRm46IGRlcHMuc3Bhd25GbiwgbGFiZWw6ICdsaXN0X2FnZW50cycgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogSlNPTi5zdHJpbmdpZnkoY29tcGFjdCwgbnVsbCwgMikgfV0sXG4gICAgfTtcbiAgfSxcbn07XG4iLCAiaW1wb3J0IHsgbGlzdEFnZW50c1ZpYUNsaSB9IGZyb20gJy4uL3J1bi1sdWEubWpzJztcblxuLy8gVGhlcmUgaXMgbm8gY29uc29saWRhdGVkIGBHRVQgL2RldmVsb3Blci9hZ2VudHMvOmFnZW50SWRgIHJvdXRlLCBhbmQgdGhlXG4vLyBwdWJsaWMgYC9wdWJsaWMvYWdlbnRzLzphZ2VudElkYCByb3V0ZSBpcyBvcmlnaW4tZ3VhcmRlZCAoYnJvd3NlciBvbmx5KS5cbi8vIFRoZSBhZ2VudCdzIGlkZW50aXR5IChpZCwgbmFtZSwgb3JnLCB2aXNpYmlsaXR5KSBJUyBpbiBgbHVhIGFnZW50cyAtLWpzb25gLFxuLy8gc28gd2Ugc2hlbGwgb3V0IGFuZCBmaWx0ZXIgXHUyMDE0IHNhbWUgcGF0aCBhcyBsaXN0X2FnZW50cy4gUGVyc29uYSwgbW9kZWwgYW5kXG4vLyBlbnYgbGl2ZSBiZWhpbmQgc2VwYXJhdGUgcGVyLXJlc291cmNlIHJvdXRlczsgdXNlIHRoZSBkZWRpY2F0ZWQgdG9vbHMgKG9yXG4vLyBgbHVhIHN0YXR1cyAtLWpzb25gIGluc2lkZSB0aGUgcHJvamVjdCkgZm9yIHRob3NlLlxuXG5leHBvcnQgY29uc3QgZ2V0QWdlbnQgPSB7XG4gIHNwZWM6IHtcbiAgICBuYW1lOiAnZ2V0X2FnZW50JyxcbiAgICBkZXNjcmlwdGlvbjogJ0xvb2sgdXAgb25lIEx1YSBhZ2VudCBieSBJRCBhbmQgcmV0dXJuIHtpZCwgbmFtZSwgb3JnSWQsIG9yZ05hbWUsIHZpc2liaWxpdHl9LiBGb3Igd2hhdCBpcyBsaXZlIHVzZSBnZXRfZGVwbG95bWVudF9zdGF0dXMgLyBsaXN0X3ByaW1pdGl2ZV92ZXJzaW9uczsgZm9yIGxvZ3MgdXNlIHRhaWxfbG9ncy4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYWdlbnRJZDogeyB0eXBlOiAnc3RyaW5nJywgZGVzY3JpcHRpb246ICdBZ2VudCBJRCAodGhlIGBpZGAgZmllbGQgZnJvbSBsaXN0X2FnZW50czsgYWxzbyBgYWdlbnQuYWdlbnRJZGAgaW4gbHVhLnNraWxsLnlhbWwpJyB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2FnZW50SWQnXSxcbiAgICB9LFxuICB9LFxuICBhc3luYyBoYW5kbGVyKHsgYWdlbnRJZCB9LCBkZXBzID0ge30pIHtcbiAgICBpZiAoIWFnZW50SWQpIHRocm93IG5ldyBFcnJvcignYWdlbnRJZCBpcyByZXF1aXJlZCcpO1xuICAgIGNvbnN0IGFnZW50cyA9IGF3YWl0IGxpc3RBZ2VudHNWaWFDbGkoeyBzcGF3bkZuOiBkZXBzLnNwYXduRm4sIGxhYmVsOiAnZ2V0X2FnZW50JyB9KTtcbiAgICBjb25zdCBtYXRjaCA9IGFnZW50cy5maW5kKChhKSA9PiBhLmlkID09PSBhZ2VudElkKSA/PyBudWxsO1xuXG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBnZXRfYWdlbnQ6IG5vIGFnZW50IHdpdGggaWQgXCIke2FnZW50SWR9XCIgZm91bmQgaW4gdGhlIGF1dGhlbnRpY2F0ZWQgY3JlZGVudGlhbCdzIGFjY2Vzc2libGUgb3Jncy4gUnVuIGxpc3RfYWdlbnRzIHRvIHNlZSBhdmFpbGFibGUgYWdlbnRzLmApO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbeyB0eXBlOiAndGV4dCcsIHRleHQ6IEpTT04uc3RyaW5naWZ5KG1hdGNoLCBudWxsLCAyKSB9XSxcbiAgICB9O1xuICB9LFxufTtcbiIsICIvLyBDcmVkZW50aWFsIHJlc29sdXRpb24gZm9yIHRoZSBNQ1Agc2VydmVyLiBSZXNvbHZlZCBvbiBFVkVSWSBjYWxsLCBub3QgYXRcbi8vIHNlcnZlciBzdGFydHVwIFx1MjAxNCBzdXBwb3J0cyB0aGUgZmxvdyB3aGVyZSBhIHVzZXIgcmUtcnVucyBgbHVhIGF1dGggY29uZmlndXJlYFxuLy8gbWlkLXNlc3Npb24uXG4vL1xuLy8gVGhlIGNoYWluIE1VU1QgbWF0Y2ggbHVhLWNsaSdzIGByZXNvbHZlUmVxdWVzdENyZWRlbnRpYWwoKWBcbi8vIChwYWNrYWdlcy9sdWEtY2xpL3NyYy9zZXJ2aWNlcy9yZXF1ZXN0LWNyZWRlbnRpYWwudHMsIGx1YS1jbGkgMy4zMy4wKTpcbi8vXG4vLyAgIDEuIExVQV9BUElfS0VZIGluIHRoZSBwcm9jZXNzIGVudmlyb25tZW50LiBsdWEtY2xpIGxvYWRzIGAuLy5lbnZgIGludG9cbi8vICAgICAgcHJvY2Vzcy5lbnYgZmlyc3QgKGBpbXBvcnQgJ2RvdGVudi9jb25maWcnYCksIHNvIGEgYC5lbnZgIHZhbHVlIGluIHRoZVxuLy8gICAgICB3b3JraW5nIGRpcmVjdG9yeSBpcyBwYXJ0IG9mIHRoaXMgdGllciBcdTIwMTQgaXQgYmVhdHMgYSBzdG9yZWQgc2Vzc2lvbi5cbi8vICAgMi4gVGhlIHJlbmV3YWJsZSBmaXJzdC1wYXJ0eSBzZXNzaW9uIGBsdWEgYXV0aCBjb25maWd1cmVgIChlbWFpbCArIE9UUClcbi8vICAgICAgd3JpdGVzIHRvIH4vLmx1YS1jbGkvc2Vzc2lvbnMvPGVudi1oYXNoPi5qc29uLiBUaGlzIGlzIHRoZSBERUZBVUxUXG4vLyAgICAgIGxvZ2luIHNpbmNlIGx1YS1jbGkgMy4yOSBhbmQgaXQgREVMRVRFUyB+Ly5sdWEtY2xpL2NyZWRlbnRpYWxzLCBzbyBhblxuLy8gICAgICBNQ1Agc2VydmVyIHRoYXQgb25seSByZWFkIHRoZSBjcmVkZW50aWFscyBmaWxlIGZhaWxlZCBmb3IgZXZlcnlcbi8vICAgICAgc2Vzc2lvbiB1c2VyLiBUaGUgZmlsZSBob2xkcyBhIEZpcmViYXNlIHJlZnJlc2ggdG9rZW47IHRoZSBiZWFyZXIgaXNcbi8vICAgICAgYSBzaG9ydC1saXZlZCBJRCB0b2tlbiBvYnRhaW5lZCBmcm9tIEdvb2dsZSdzIHNlY3VyZXRva2VuIGVuZHBvaW50LlxuLy8gICAzLiB+Ly5sdWEtY2xpL2NyZWRlbnRpYWxzIFx1MjAxNCBhIHBsYWluLXRleHQgQVBJIGtleSAodHlwZWQgYGFwaV88dXVpZD4uPDQzPmBcbi8vICAgICAgb3IgbGVnYWN5KSwgd3JpdHRlbiB3aGVuIHRoZSB1c2VyIHBpY2tzIHRoZSBBUEkta2V5IG9wdGlvbiBvZlxuLy8gICAgICBgbHVhIGF1dGggY29uZmlndXJlYC5cbi8vXG4vLyBUaGlzIGZpbGUgZGVsaWJlcmF0ZWx5IGR1cGxpY2F0ZXMgbGliL2NyZWRlbnRpYWxzLm1qcyBiZWNhdXNlIHRoZSBNQ1Bcbi8vIHNlcnZlciBpcyBhIHNlcGFyYXRlIG5wbSBwYWNrYWdlIGFuZCBjYW4ndCByZWFjaCBpbnRvIHRoZSBwbHVnaW4ncyBsaWIvLlxuXG5pbXBvcnQgeyByZWFkRmlsZSwgcmVhZGRpciwgc3RhdCB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgam9pbiwgZGlybmFtZSB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyBob21lZGlyIH0gZnJvbSAnbm9kZTpvcyc7XG5cbmNvbnN0IERFRkFVTFRfQVBJX1VSTCA9ICdodHRwczovL2FwaS5oZXlsdWEuYWknO1xuY29uc3QgRklSRUJBU0VfUkVGUkVTSF9VUkwgPSAnaHR0cHM6Ly9zZWN1cmV0b2tlbi5nb29nbGVhcGlzLmNvbS92MS90b2tlbic7XG5jb25zdCBSRUZSRVNIX1RJTUVPVVRfTVMgPSAxNV8wMDA7XG5jb25zdCBSRUZSRVNIX1NLRVdfTVMgPSA2MF8wMDA7XG5cbi8vIEdvb2dsZSdzIHZlcmRpY3RzIHRoYXQgdGhlIHN0b3JlZCByZWZyZXNoIHRva2VuIGNhbiBuZXZlciB3b3JrIGFnYWluLlxuLy8gTWlycm9ycyBsdWEtY2xpJ3MgUkVKRUNURURfUkVGUkVTSF9SRUFTT05TIChzZXJ2aWNlcy9maXJlYmFzZS1zZXNzaW9uLnRzKS5cbmNvbnN0IFJFSkVDVEVEX1JFRlJFU0hfUkVBU09OUyA9IFtcbiAgJ1RPS0VOX0VYUElSRUQnLFxuICAnVVNFUl9ESVNBQkxFRCcsXG4gICdVU0VSX05PVF9GT1VORCcsXG4gICdJTlZBTElEX1JFRlJFU0hfVE9LRU4nLFxuICAnSU5WQUxJRF9HUkFOVF9UWVBFJyxcbiAgJ01JU1NJTkdfUkVGUkVTSF9UT0tFTicsXG5dO1xuXG4vLyBJbi1wcm9jZXNzIGNhY2hlIG9mIHJlZnJlc2hlZCBJRCB0b2tlbnMsIGtleWVkIGJ5IHNlc3Npb24gZmlsZSBwYXRoLlxuY29uc3QgdG9rZW5DYWNoZSA9IG5ldyBNYXAoKTtcblxuLyoqIEV4cG9ydGVkIGZvciB0ZXN0cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGVhclRva2VuQ2FjaGUoKSB7XG4gIHRva2VuQ2FjaGUuY2xlYXIoKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhIGRvdGVudi1zdHlsZSBmaWxlIGZvciBMVUFfQVBJX0tFWSB0aGUgd2F5IGRvdGVudiBkb2VzOiBvcHRpb25hbFxuICogYGV4cG9ydCBgIHByZWZpeCwgc3Vycm91bmRpbmcgc2luZ2xlL2RvdWJsZSBxdW90ZXMgc3RyaXBwZWQsIGEgdHJhaWxpbmdcbiAqIGAgIyBjb21tZW50YCBkcm9wcGVkIGZyb20gdW5xdW90ZWQgdmFsdWVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50XG4gKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURvdGVudkFwaUtleShjb250ZW50KSB7XG4gIGZvciAoY29uc3QgcmF3TGluZSBvZiBjb250ZW50LnNwbGl0KC9cXHI/XFxuLykpIHtcbiAgICBjb25zdCBtID0gcmF3TGluZS5tYXRjaCgvXlxccyooPzpleHBvcnRcXHMrKT9MVUFfQVBJX0tFWVxccyo9XFxzKiguKikkLyk7XG4gICAgaWYgKCFtKSBjb250aW51ZTtcbiAgICBsZXQgdmFsdWUgPSBtWzFdLnRyaW0oKTtcbiAgICBjb25zdCBxdW90ZWQgPSB2YWx1ZS5tYXRjaCgvXihbJ1wiYF0pKC4qPylcXDEoPzpcXHMrIy4qKT9cXHMqJC8pO1xuICAgIGlmIChxdW90ZWQpIHZhbHVlID0gcXVvdGVkWzJdO1xuICAgIGVsc2UgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXHMrIy4qJC8sICcnKS50cmltKCk7XG4gICAgcmV0dXJuIHZhbHVlIHx8IG51bGw7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogTG9jYXRlIHRoZSBsdWEtY2xpIHNlc3Npb24gZmlsZSBmb3IgdGhlIEFQSSBiYXNlIFVSTCBpbiB1c2UuIGx1YS1jbGkgbmFtZXNcbiAqIHRoZSBmaWxlIGJ5IGEgaGFzaCBvZiAoYXBpVXJsLCBhdXRoVXJsLCBmaXJlYmFzZVdlYkFwaUtleSk7IHJhdGhlciB0aGFuXG4gKiByZWNvbXB1dGUgaXQgd2Ugc2NhbiB0aGUgZGlyZWN0b3J5IGZvciBhIGBmaXJlYmFzZS1zZXNzaW9uYCByZWNvcmQgd2hvc2VcbiAqIGBhcGlVcmxgIG1hdGNoZXMsIG5ld2VzdCBmaXJzdC5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx7cGF0aDogc3RyaW5nLCBzZXNzaW9uOiBvYmplY3R9fG51bGw+fVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluZFNlc3Npb25GaWxlKHsgc2Vzc2lvbnNEaXIsIGFwaVVybCB9KSB7XG4gIGxldCBuYW1lcztcbiAgdHJ5IHtcbiAgICBuYW1lcyA9IGF3YWl0IHJlYWRkaXIoc2Vzc2lvbnNEaXIpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCBjYW5kaWRhdGVzID0gW107XG4gIGZvciAoY29uc3QgbmFtZSBvZiBuYW1lcykge1xuICAgIGlmICghbmFtZS5lbmRzV2l0aCgnLmpzb24nKSB8fCBuYW1lLnN0YXJ0c1dpdGgoJy4nKSkgY29udGludWU7XG4gICAgY29uc3QgcGF0aCA9IGpvaW4oc2Vzc2lvbnNEaXIsIG5hbWUpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzZXNzaW9uID0gSlNPTi5wYXJzZShhd2FpdCByZWFkRmlsZShwYXRoLCAndXRmOCcpKTtcbiAgICAgIGlmIChzZXNzaW9uPy5raW5kICE9PSAnZmlyZWJhc2Utc2Vzc2lvbicgfHwgc2Vzc2lvbj8udmVyc2lvbiAhPT0gMSkgY29udGludWU7XG4gICAgICBpZiAodHlwZW9mIHNlc3Npb24ucmVmcmVzaFRva2VuICE9PSAnc3RyaW5nJyB8fCAhc2Vzc2lvbi5yZWZyZXNoVG9rZW4pIGNvbnRpbnVlO1xuICAgICAgaWYgKHR5cGVvZiBzZXNzaW9uLmZpcmViYXNlV2ViQXBpS2V5ICE9PSAnc3RyaW5nJyB8fCAhc2Vzc2lvbi5maXJlYmFzZVdlYkFwaUtleSkgY29udGludWU7XG4gICAgICBpZiAoc2Vzc2lvbi5hcGlVcmwgIT09IGFwaVVybCkgY29udGludWU7XG4gICAgICBjb25zdCB7IG10aW1lTXMgfSA9IGF3YWl0IHN0YXQocGF0aCk7XG4gICAgICBjYW5kaWRhdGVzLnB1c2goeyBwYXRoLCBzZXNzaW9uLCBtdGltZU1zIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gdW5yZWFkYWJsZSAvIG1hbGZvcm1lZCBcdTIwMTQgc2tpcCwgbHVhLWNsaSB3aWxsIGNvbXBsYWluIG9uIGl0cyBvd25cbiAgICB9XG4gIH1cbiAgaWYgKGNhbmRpZGF0ZXMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgY2FuZGlkYXRlcy5zb3J0KChhLCBiKSA9PiBiLm10aW1lTXMgLSBhLm10aW1lTXMpO1xuICByZXR1cm4geyBwYXRoOiBjYW5kaWRhdGVzWzBdLnBhdGgsIHNlc3Npb246IGNhbmRpZGF0ZXNbMF0uc2Vzc2lvbiB9O1xufVxuXG4vKipcbiAqIEV4Y2hhbmdlIHRoZSBzdG9yZWQgcmVmcmVzaCB0b2tlbiBmb3IgYSBGaXJlYmFzZSBJRCB0b2tlbiAodGhlIGJlYXJlclxuICogbHVhLWFwaSBhY2NlcHRzKS4gQ2FjaGVkIGluLXByb2Nlc3MgdW50aWwgNjAgcyBiZWZvcmUgZXhwaXJ5LiBUaGUgc2Vzc2lvblxuICogZmlsZSBpcyBuZXZlciB3cml0dGVuOiBsdWEtY2xpIG93bnMgaXQuXG4gKlxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gYmVhcmVyIHRva2VuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWZyZXNoU2Vzc2lvbkJlYXJlcih7IHBhdGgsIHNlc3Npb24sIGZldGNoRm4gPSBnbG9iYWxUaGlzLmZldGNoLCBub3cgPSBEYXRlLm5vdyB9KSB7XG4gIGNvbnN0IGNhY2hlZCA9IHRva2VuQ2FjaGUuZ2V0KHBhdGgpO1xuICBpZiAoY2FjaGVkICYmIGNhY2hlZC5leHBpcmVzQXQgLSBub3coKSA+IFJFRlJFU0hfU0tFV19NUykgcmV0dXJuIGNhY2hlZC5pZFRva2VuO1xuXG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiBjb250cm9sbGVyLmFib3J0KCksIFJFRlJFU0hfVElNRU9VVF9NUyk7XG4gIGxldCByZXM7XG4gIHRyeSB7XG4gICAgcmVzID0gYXdhaXQgZmV0Y2hGbihgJHtGSVJFQkFTRV9SRUZSRVNIX1VSTH0/a2V5PSR7ZW5jb2RlVVJJQ29tcG9uZW50KHNlc3Npb24uZmlyZWJhc2VXZWJBcGlLZXkpfWAsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSxcbiAgICAgIGJvZHk6IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyBncmFudF90eXBlOiAncmVmcmVzaF90b2tlbicsIHJlZnJlc2hfdG9rZW46IHNlc3Npb24ucmVmcmVzaFRva2VuIH0pLnRvU3RyaW5nKCksXG4gICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgIH0pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTUNQX0FVVEhfVU5BVkFJTEFCTEU6IGNvdWxkIG5vdCByZWZyZXNoIHRoZSBsdWEtY2xpIHNlc3Npb24gKCR7ZXJyPy5uYW1lID09PSAnQWJvcnRFcnJvcicgPyAndGltZWQgb3V0JyA6IGVyci5tZXNzYWdlfSkuIGAgK1xuICAgICAgJ0NoZWNrIHlvdXIgbmV0d29yaywgb3Igc2V0IExVQV9BUElfS0VZIHRvIGJ5cGFzcyB0aGUgc2Vzc2lvbi4nXG4gICAgKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICB9XG5cbiAgaWYgKCFyZXMub2spIHtcbiAgICBsZXQgcmVhc29uID0gcmVzLnN0YXR1c1RleHQgPz8gU3RyaW5nKHJlcy5zdGF0dXMpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBib2R5ID0gYXdhaXQgcmVzLmpzb24oKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBib2R5Py5lcnJvcj8ubWVzc2FnZTtcbiAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycgJiYgbWVzc2FnZSkgcmVhc29uID0gbWVzc2FnZS5zcGxpdCgnOicpWzBdLnRyaW0oKTtcbiAgICB9IGNhdGNoIHsgLyoga2VlcCBzdGF0dXNUZXh0ICovIH1cbiAgICBjb25zdCByZWplY3RlZCA9IHJlcy5zdGF0dXMgPCA1MDAgJiYgUkVKRUNURURfUkVGUkVTSF9SRUFTT05TLmZpbmQoKHIpID0+IHJlYXNvbi50b1VwcGVyQ2FzZSgpLmluY2x1ZGVzKHIpKTtcbiAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYE1DUF9BVVRIX1NUQUxFOiB5b3VyIGx1YS1jbGkgc2Vzc2lvbiB3YXMgc2lnbmVkIG91dCAoJHtyZWplY3RlZH0pLiBgICtcbiAgICAgICAgJ1NpZ25pbmcgb3V0IG9mIHRoZSBMdWEgZGFzaGJvYXJkLCBkZXNrdG9wIG9yIG1vYmlsZSBhcHAgYWxzbyBlbmRzIENMSSBzZXNzaW9ucy4gJyArXG4gICAgICAgICdSdW4gYGx1YSBhdXRoIGNvbmZpZ3VyZWAgaW4gYSB0ZXJtaW5hbCB0byBzaWduIGluIGFnYWluLidcbiAgICAgICk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgTUNQX0FVVEhfVU5BVkFJTEFCTEU6IGx1YS1jbGkgc2Vzc2lvbiByZWZyZXNoIGZhaWxlZCAoJHtyZXMuc3RhdHVzfSAke3JlYXNvbn0pLiBSZXRyeSBpbiBhIG1vbWVudC5gKTtcbiAgfVxuXG4gIGNvbnN0IGJvZHkgPSBhd2FpdCByZXMuanNvbigpO1xuICBjb25zdCBpZFRva2VuID0gYm9keT8uaWRfdG9rZW47XG4gIGNvbnN0IGV4cGlyZXNJbiA9IE51bWJlcihib2R5Py5leHBpcmVzX2luKTtcbiAgaWYgKHR5cGVvZiBpZFRva2VuICE9PSAnc3RyaW5nJyB8fCAhaWRUb2tlbiB8fCAhTnVtYmVyLmlzRmluaXRlKGV4cGlyZXNJbikgfHwgZXhwaXJlc0luIDw9IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01DUF9BVVRIX1VOQVZBSUxBQkxFOiB0aGUgc2Vzc2lvbiByZWZyZXNoIHJldHVybmVkIGFuIGludmFsaWQgdG9rZW4uIFJ1biBgbHVhIGF1dGggY29uZmlndXJlYCBhZ2Fpbi4nKTtcbiAgfVxuICB0b2tlbkNhY2hlLnNldChwYXRoLCB7IGlkVG9rZW4sIGV4cGlyZXNBdDogbm93KCkgKyBleHBpcmVzSW4gKiAxMDAwIH0pO1xuICByZXR1cm4gaWRUb2tlbjtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBiZWFyZXIgdG9rZW4gZXZlcnkgbHVhLWFwaSByZXF1ZXN0IHNob3VsZCBjYXJyeS5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fVxuICogQHRocm93cyB7RXJyb3J9IE1DUF9BVVRIX1NUQUxFIHdoZW4gbm8gY3JlZGVudGlhbCByZXNvbHZlcyBmcm9tIGFueSB0aWVyXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNvbHZlQXBpS2V5KHtcbiAgZW52ID0gcHJvY2Vzcy5lbnYsXG4gIGNyZWRlbnRpYWxzUGF0aCA9IGVudi5MVUFfQ1JFREVOVElBTFNfUEFUSCA/PyBqb2luKGhvbWVkaXIoKSwgJy5sdWEtY2xpJywgJ2NyZWRlbnRpYWxzJyksXG4gIHNlc3Npb25zRGlyID0gZW52LkxVQV9TRVNTSU9OU19ESVIgPz8gam9pbihkaXJuYW1lKGNyZWRlbnRpYWxzUGF0aCksICdzZXNzaW9ucycpLFxuICBjd2QgPSBwcm9jZXNzLmN3ZCgpLFxuICBhcGlVcmwgPSBlbnYuTFVBX0FQSV9VUkwgfHwgREVGQVVMVF9BUElfVVJMLFxuICBmZXRjaEZuID0gZ2xvYmFsVGhpcy5mZXRjaCxcbiAgbm93ID0gRGF0ZS5ub3csXG59ID0ge30pIHtcbiAgLy8gVGllciAxYTogcHJvY2VzcyBlbnZpcm9ubWVudFxuICBpZiAoZW52LkxVQV9BUElfS0VZICYmIGVudi5MVUFfQVBJX0tFWS50cmltKCkpIHJldHVybiBlbnYuTFVBX0FQSV9LRVkudHJpbSgpO1xuXG4gIC8vIFRpZXIgMWI6IC5lbnYgaW4gdGhlIHdvcmtpbmcgZGlyZWN0b3J5IChsdWEtY2xpIGxvYWRzIGl0IGludG8gcHJvY2Vzcy5lbnZcbiAgLy8gYmVmb3JlIHJlYWRpbmcgTFVBX0FQSV9LRVksIHNvIGl0IHJhbmtzIGFib3ZlIHRoZSBzdG9yZWQgc2Vzc2lvbilcbiAgdHJ5IHtcbiAgICBjb25zdCBmcm9tRG90ZW52ID0gcGFyc2VEb3RlbnZBcGlLZXkoYXdhaXQgcmVhZEZpbGUoam9pbihjd2QsICcuZW52JyksICd1dGY4JykpO1xuICAgIGlmIChmcm9tRG90ZW52KSByZXR1cm4gZnJvbURvdGVudjtcbiAgfSBjYXRjaCB7IC8qIG5vIC5lbnYgXHUyMDE0IGZhbGwgdGhyb3VnaCAqLyB9XG5cbiAgLy8gVGllciAyOiByZW5ld2FibGUgZmlyc3QtcGFydHkgc2Vzc2lvblxuICBjb25zdCBmb3VuZCA9IGF3YWl0IGZpbmRTZXNzaW9uRmlsZSh7IHNlc3Npb25zRGlyLCBhcGlVcmwgfSk7XG4gIGlmIChmb3VuZCkgcmV0dXJuIHJlZnJlc2hTZXNzaW9uQmVhcmVyKHsgLi4uZm91bmQsIGZldGNoRm4sIG5vdyB9KTtcblxuICAvLyBUaWVyIDM6IH4vLmx1YS1jbGkvY3JlZGVudGlhbHMgKHBsYWluIHRleHQgQVBJIGtleSlcbiAgdHJ5IHtcbiAgICBjb25zdCByYXcgPSAoYXdhaXQgcmVhZEZpbGUoY3JlZGVudGlhbHNQYXRoLCAndXRmOCcpKS50cmltKCk7XG4gICAgaWYgKHJhdykge1xuICAgICAgaWYgKHJhdy5zdGFydHNXaXRoKCd7JykpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgICAgICAgaWYgKHBhcnNlZD8uYXBpS2V5KSByZXR1cm4gcGFyc2VkLmFwaUtleTtcbiAgICAgICAgfSBjYXRjaCB7IC8qIG5vdCBKU09OIGRlc3BpdGUgbGVhZGluZyBicmFjZSAqLyB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmF3O1xuICAgIH1cbiAgfSBjYXRjaCB7IC8qIG1pc3NpbmcgLyB1bnJlYWRhYmxlIFx1MjAxNCBmYWxsIHRocm91Z2ggKi8gfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICAnTUNQX0FVVEhfU1RBTEU6IE5vIGx1YS1jbGkgY3JlZGVudGlhbHMgZm91bmQgaW4gTFVBX0FQSV9LRVksIC5lbnYsIH4vLmx1YS1jbGkvc2Vzc2lvbnMsIG9yIH4vLmx1YS1jbGkvY3JlZGVudGlhbHMuICcgK1xuICAgICdSdW4gYGx1YSBhdXRoIGNvbmZpZ3VyZWAgaW4gYSB0ZXJtaW5hbCAob3IgL2x1YS1hdXRoIGluIENsYXVkZSBDb2RlKS4nXG4gICk7XG59XG4iLCAiLy8gVGhpbiBIVFRQIHdyYXBwZXIgYXJvdW5kIGx1YS1hcGkuIFBlciB0ZWNoIHNwZWMgXHUwMEE3OC5cbi8vXG4vLyBXZSBkbyBOT1QgaW1wb3J0IGx1YS1jbGkncyBIdHRwQ2xpZW50IGNsYXNzZXMgYXQgcnVudGltZSAod291bGQgZm9yY2Vcbi8vIHRoZSBlbnRpcmUgbHVhLWNsaSBwYWNrYWdlIHRvIGJlIGJ1bmRsZWQpLiBJbnN0ZWFkLCB0aGlzIG1pbmltYWwgY2xpZW50XG4vLyBoaXRzIHRoZSBzYW1lIFJFU1QgZW5kcG9pbnRzIGx1YS1jbGkgZG9lcy4gRXZlcnkgcm91dGUsIHF1ZXJ5IHBhcmFtZXRlclxuLy8gYW5kIGVudmVsb3BlIHVzZWQgYnkgdGhlIHRvb2xzIGlzIHZlcmlmaWVkIGFnYWluc3QgcGFja2FnZXMvbHVhLWFwaVxuLy8gKGNvbnRyb2xsZXJzL2RldmVsb3Blci8qKiwgZHRvLyoqKSBcdTIwMTQgc2VlIHJlc3BvbnNlLXNoYXBlcy5tanMuXG5cbmltcG9ydCB7IHJlc29sdmVBcGlLZXkgfSBmcm9tICcuL2F1dGgubWpzJztcblxuY29uc3QgREVGQVVMVF9CQVNFX1VSTCA9ICdodHRwczovL2FwaS5oZXlsdWEuYWknO1xuY29uc3QgREVGQVVMVF9USU1FT1VUX01TID0gMTBfMDAwO1xuXG4vLyBTY29wZSBlYWNoIHJvdXRlIGZhbWlseSB0aGUgdG9vbHMgY2FsbCBhY3R1YWxseSByZXF1aXJlcyBcdTIwMTQgcmVhZCBmcm9tIHRoZVxuLy8gYEBSZXF1aXJlU2NvcGUoLi4uKWAgZGVjb3JhdG9yIG9uIGV2ZXJ5IEdFVCB0aGUgdG9vbHMgaGl0LCB1bmRlclxuLy8gbHVhLWNvcmUtc2VydmljZXMgcGFja2FnZXMvbHVhLWFwaS9zcmMvY29udHJvbGxlcnMvZGV2ZWxvcGVyLzpcbi8vICAgc2tpbGxzL2Jhc2UuY29udHJvbGxlci50cywgd2ViaG9va3MvYmFzZS5jb250cm9sbGVyLnRzLFxuLy8gICBqb2JzL2Jhc2UuY29udHJvbGxlci50cywgdHJpZ2dlcnMvYmFzZS5jb250cm9sbGVyLnRzLFxuLy8gICBwcmVwcm9jZXNzb3JzL2Jhc2UuY29udHJvbGxlci50cywgcG9zdHByb2Nlc3NvcnMvYmFzZS5jb250cm9sbGVyLnRzXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcdTIxOTIgJ2F1dG9tYXRpb25zOnJlYWQnIChsaXN0ICsgOmlkL3ZlcnNpb25zKVxuLy8gICB3b3JrZmxvd3MvYmFzZS5jb250cm9sbGVyLnRzICAgXHUyMTkyICd3b3JrZmxvd3M6cmVhZCcgICAoR0VUIDphZ2VudElkLCBHRVQgOmFnZW50SWQvOndvcmtmbG93SWQvdmVyc2lvbnMpXG4vLyAgIHBlcnNvbmEvYmFzZS5jb250cm9sbGVyLnRzICAgICBcdTIxOTIgJ2FnZW50czpyZWFkJyAgICAgIChHRVQgOmFnZW50SWQvcGVyc29uYS92ZXJzaW9ucylcbi8vICAgYmFzZS5jb250cm9sbGVyLnRzICAgICAgICAgICAgIFx1MjE5MiAna25vd2xlZGdlOnJlYWQnICAgKEdFVCBhZ2VudHMvOmFnZW50SWQvbG9ncylcbi8vIFdvcmtmbG93cyBhcmUgTk9UIHVuZGVyIGF1dG9tYXRpb25zOnJlYWQgXHUyMDE0IHRoZXkgaGF2ZSB0aGVpciBvd24gc2NvcGUgcGFpclxuLy8gKHdvcmtmbG93czpyZWFkIC8gd29ya2Zsb3dzOndyaXRlKS5cbmV4cG9ydCBjb25zdCBST1VURV9TQ09QRVMgPSBPYmplY3QuZnJlZXplKHtcbiAgc2tpbGxzOiAnYXV0b21hdGlvbnM6cmVhZCcsXG4gIHdlYmhvb2tzOiAnYXV0b21hdGlvbnM6cmVhZCcsXG4gIGpvYnM6ICdhdXRvbWF0aW9uczpyZWFkJyxcbiAgdHJpZ2dlcnM6ICdhdXRvbWF0aW9uczpyZWFkJyxcbiAgcHJlcHJvY2Vzc29yczogJ2F1dG9tYXRpb25zOnJlYWQnLFxuICBwb3N0cHJvY2Vzc29yczogJ2F1dG9tYXRpb25zOnJlYWQnLFxuICB3b3JrZmxvd3M6ICd3b3JrZmxvd3M6cmVhZCcsXG4gIHBlcnNvbmE6ICdhZ2VudHM6cmVhZCcsXG4gIGxvZ3M6ICdrbm93bGVkZ2U6cmVhZCcsXG59KTtcblxuY29uc3QgUk9VVEVfU0NPUEVfU1VNTUFSWSA9XG4gICdza2lsbHMvd2ViaG9va3Mvam9icy90cmlnZ2Vycy9wcmVwcm9jZXNzb3JzL3Bvc3Rwcm9jZXNzb3JzIG5lZWQgYXV0b21hdGlvbnM6cmVhZCwgd29ya2Zsb3dzIG5lZWQgJyArXG4gICd3b3JrZmxvd3M6cmVhZCwgcGVyc29uYSBuZWVkcyBhZ2VudHM6cmVhZCwgbG9ncyBuZWVkIGtub3dsZWRnZTpyZWFkJztcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIEFQSSBwYXRoICh3aXRoIGxlYWRpbmcgc2xhc2gpXG4gKiBAcGFyYW0ge3ttZXRob2Q/OiBzdHJpbmcsIGJvZHk/OiBvYmplY3QsIHF1ZXJ5PzogUmVjb3JkPHN0cmluZyxzdHJpbmd8bnVtYmVyPiwgZmV0Y2hGbj86IHR5cGVvZiBmZXRjaCwgYmFzZVVybD86IHN0cmluZywgdGltZW91dE1zPzogbnVtYmVyfX0gW29wdHNdXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhcGlSZXF1ZXN0KHBhdGgsIHtcbiAgbWV0aG9kID0gJ0dFVCcsXG4gIGJvZHksXG4gIHF1ZXJ5LFxuICBmZXRjaEZuID0gZ2xvYmFsVGhpcy5mZXRjaCxcbiAgYmFzZVVybCA9IHByb2Nlc3MuZW52LkxVQV9BUElfVVJMIHx8IERFRkFVTFRfQkFTRV9VUkwsXG4gIHRpbWVvdXRNcyA9IERFRkFVTFRfVElNRU9VVF9NUyxcbn0gPSB7fSkge1xuICBjb25zdCBhcGlLZXkgPSBhd2FpdCByZXNvbHZlQXBpS2V5KCk7XG4gIC8vIEpvaW4gYnkgc3RyaW5nIGNvbmNhdGVuYXRpb24sIE5PVCBgbmV3IFVSTChwYXRoLCBiYXNlVXJsKWA6IHRoZSBXSEFUV0dcbiAgLy8gcmVzb2x2ZXIgdHJlYXRzIGEgbGVhZGluZy1zbGFzaCBwYXRoIGFzIGhvc3QtYWJzb2x1dGUgYW5kIHdvdWxkIGRyb3AgYW55XG4gIC8vIHBhdGggcHJlZml4IG9uIExVQV9BUElfVVJMIChodHRwczovL2hvc3QvYXBpICsgL2RldmVsb3Blci94IFx1MjE5MlxuICAvLyBodHRwczovL2hvc3QvZGV2ZWxvcGVyL3gpLiBgcGF0aGAgYWx3YXlzIHN0YXJ0cyB3aXRoICcvJywgc28gc3RyaXAgb25lXG4gIC8vIHRyYWlsaW5nIHNsYXNoIGZyb20gdGhlIGJhc2UgYW5kIGNvbmNhdGVuYXRlLlxuICBjb25zdCB1cmwgPSBuZXcgVVJMKGJhc2VVcmwucmVwbGFjZSgvXFwvJC8sICcnKSArIHBhdGgpO1xuICBpZiAocXVlcnkpIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKHF1ZXJ5KSkgdXJsLnNlYXJjaFBhcmFtcy5zZXQoaywgU3RyaW5nKHYpKTtcblxuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gY29udHJvbGxlci5hYm9ydCgpLCB0aW1lb3V0TXMpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2hGbih1cmwudG9TdHJpbmcoKSwge1xuICAgICAgbWV0aG9kLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHthcGlLZXl9YCxcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgJ1gtTHVhLUNsaWVudCc6ICdjbGF1ZGUtcGx1Z2luLzEuNi4wJyxcbiAgICAgIH0sXG4gICAgICBib2R5OiBib2R5ID8gSlNPTi5zdHJpbmdpZnkoYm9keSkgOiB1bmRlZmluZWQsXG4gICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgIH0pO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnTUNQX0FVVEhfU1RBTEU6IGx1YS1hcGkgcmV0dXJuZWQgNDAxLiBUaGUgY3JlZGVudGlhbCBpcyBtaXNzaW5nLCBleHBpcmVkLCBvciB0aGUgc2Vzc2lvbiB3YXMgc2lnbmVkIG91dCAnICtcbiAgICAgICAgJyhzaWduaW5nIG91dCBvZiB0aGUgTHVhIGRhc2hib2FyZCBvciBhcHBzIGFsc28gZW5kcyBDTEkgc2Vzc2lvbnMpLiBSdW4gYGx1YSBhdXRoIGNvbmZpZ3VyZWAgaW4gYSB0ZXJtaW5hbCwgJyArXG4gICAgICAgICdvciByZS1ydW4gL2x1YS1kb2N0b3IuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgTUNQX0ZPUkJJRERFTjogbHVhLWFwaSByZXR1cm5lZCA0MDMgZm9yICR7cGF0aH0uIFRoZSBjcmVkZW50aWFsIGNhbm5vdCBhY2Nlc3MgdGhpcyBhZ2VudCBvciBvcmcsIG9yIGl0IGxhY2tzIGAgK1xuICAgICAgICBgdGhlIHJvdXRlIHNjb3BlICgke1JPVVRFX1NDT1BFX1NVTU1BUll9IFx1MjAxNCB0eXBlZCBrZXlzIGFyZSBzY29wZWQgdG8gdGhlIGFnZW50cyBhbmQgcm9sZSBjaG9zZW4gYXQgYCArXG4gICAgICAgICdgbHVhIGF1dGggY29uZmlndXJlYCkuIFJlLXJ1biAvbHVhLWRvY3RvciBvciBjaGVjayB0aGUgTFVBX0FQSV9LRVkgZW52IHZhci4nXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoIXJlcy5vaykge1xuICAgICAgLy8gVHJ5IHRvIHBhcnNlIGx1YS1hcGkncyBzdHJ1Y3R1cmVkIGVycm9yIGVudmVsb3BlOlxuICAgICAgLy8gICB7IHN1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogeyBtZXNzYWdlLCBzdGF0dXNDb2RlLCBjb2RlPywgLi4uIH0gfVxuICAgICAgLy8gRmFsbHMgYmFjayB0byByYXcgdGV4dCBvbiBwYXJzZSBmYWlsdXJlIChlLmcuIHByb3h5IDUwMiB3aXRoIEhUTUwgYm9keSkuXG4gICAgICBjb25zdCByYXcgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgbGV0IGZyaWVuZGx5TXNnID0gcmF3O1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgICBmcmllbmRseU1zZyA9IHBhcnNlZD8uZXJyb3I/Lm1lc3NhZ2UgPz8gcGFyc2VkPy5tZXNzYWdlID8/IHJhdztcbiAgICAgICAgY29uc3QgY29kZSA9IHBhcnNlZD8uZXJyb3I/LmNvZGU7XG4gICAgICAgIGlmICh0eXBlb2YgY29kZSA9PT0gJ3N0cmluZycgJiYgY29kZSAmJiAhU3RyaW5nKGZyaWVuZGx5TXNnKS5pbmNsdWRlcyhjb2RlKSkgZnJpZW5kbHlNc2cgPSBgJHtjb2RlfTogJHtmcmllbmRseU1zZ31gO1xuICAgICAgfSBjYXRjaCB7IC8qIG5vdCBKU09OOyByYXcgaXMgZmluZSAqLyB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGx1YS1hcGkgJHtyZXMuc3RhdHVzfTogJHtmcmllbmRseU1zZ31gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgcmVzLmpzb24oKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKGVyci5uYW1lID09PSAnQWJvcnRFcnJvcicpIHRocm93IG5ldyBFcnJvcihgTUNQX1RJTUVPVVQ6ICR7cGF0aH0gZGlkIG5vdCByZXNwb25kIGluICR7dGltZW91dE1zfW1zYCk7XG4gICAgdGhyb3cgZXJyO1xuICB9IGZpbmFsbHkge1xuICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gIH1cbn1cbiIsICIvLyBQZXItdHlwZSByZXNwb25zZS1zaGFwZSBleHRyYWN0b3JzLlxuLy9cbi8vIGx1YS1hcGkncyBkZXZlbG9wZXIgZW5kcG9pbnRzIGhhdmUgSU5DT05TSVNURU5UIHJlc3BvbnNlIHNoYXBlcyBhY3Jvc3Ncbi8vIHByaW1pdGl2ZSB0eXBlcy4gVmVyaWZpZWQgYWdhaW5zdCBwYWNrYWdlcy9sdWEtYXBpL3NyYy9kdG8vKi5kdG8udHMgYW5kXG4vLyBwYWNrYWdlcy9sdWEtYXBpL3NyYy9jb250cm9sbGVycy9kZXZlbG9wZXIvKiovYmFzZS5jb250cm9sbGVyLnRzLCBwbHVzXG4vLyBwYWNrYWdlcy9sdWEtY2xpL3NyYy9pbnRlcmZhY2VzL3dvcmtmbG93cy50cyAobHVhLWNsaSAzLjMzLjApOlxuLy9cbi8vICAgU2tpbGxzICAgICAgICAgR0VUIC9kZXZlbG9wZXIvc2tpbGxzLzphZ2VudElkICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHNraWxsczogU2tpbGxEdG9bXSB9XG4vLyAgICAgICAgICAgICAgICAgIEdFVCAvZGV2ZWxvcGVyL3NraWxscy86YWdlbnRJZC86c2tpbGxJZC92ZXJzaW9ucyAgICBcdTIxOTIgeyB2ZXJzaW9uczogW3sgdmVyc2lvbiwgY3JlYXRlZERhdGUsIGlzQ3VycmVudCwgLi4uIH1dIH1cbi8vICAgV2ViaG9va3MgICAgICAgR0VUIC9kZXZlbG9wZXIvd2ViaG9va3MvOmFnZW50SWQgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHN1Y2Nlc3MsIGRhdGE6IHsgd2ViaG9va3MgfSB9XG4vLyAgICAgICAgICAgICAgICAgIEdFVCAuLi4vOndlYmhvb2tJZC92ZXJzaW9ucyAgICAgICAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyBzdWNjZXNzLCBkYXRhOiB7IHZlcnNpb25zOiBbeyB2ZXJzaW9uLCB3ZWJob29rSWQsIGNyZWF0ZWRBdCwgaXNBY3RpdmUgfV0sIGFjdGl2ZVZlcnNpb25JZD8gfSB9XG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXJ2aWNlcy9kZXZlbG9wZXIud2ViaG9vay5zZXJ2aWNlLnRzIHNldHMgYHdlYmhvb2tJZDogdi5pZGAgXHUyMDE0IHRoZVxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbiBST1cgaWQgdW5kZXIgYSBtaXNuYW1lZCBrZXk7IHRoZXJlIGlzIG5vIHZlcnNpb25JZC9pZCwgc29cbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnNpb25JZCgpIGlzIG51bGwgYW5kIHRoZSBlbnZlbG9wZSdzIGFjdGl2ZVZlcnNpb25JZCBpcyB0aGUgb25seSBpZClcbi8vICAgSm9icyAgICAgICAgICAgR0VUIC9kZXZlbG9wZXIvam9icy86YWdlbnRJZCAgICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHN1Y2Nlc3MsIGRhdGE6IHsgam9icyB9IH1cbi8vICAgICAgICAgICAgICAgICAgR0VUIC4uLi86am9iSWQvdmVyc2lvbnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHN1Y2Nlc3MsIGRhdGE6IEpvYlZlcnNpb25EdG9bXSB9ICAgXHUyMTkwIGFycmF5IHVuZGVyIGRhdGE7IGBhY3RpdmVgXG4vLyAgIFRyaWdnZXJzICAgICAgIEdFVCAvZGV2ZWxvcGVyL3RyaWdnZXJzLzphZ2VudElkICAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyBzdWNjZXNzLCBkYXRhOiB7IHRyaWdnZXJzIH0gfVxuLy8gICAgICAgICAgICAgICAgICBHRVQgLi4uLzp0cmlnZ2VySWQvdmVyc2lvbnMgICAgICAgICAgICAgICAgICAgICAgICAgXHUyMTkyIHsgc3VjY2VzcywgZGF0YTogeyB2ZXJzaW9uczogW3sgdmVyc2lvbiwgdmVyc2lvbklkLCBjcmVhdGVkQXQsIGlzQWN0aXZlIH1dLCBhY3RpdmVWZXJzaW9uSWQ/IH0gfVxuLy8gICBQcmVwcm9jZXNzb3JzICBHRVQgL2RldmVsb3Blci9wcmVwcm9jZXNzb3JzLzphZ2VudElkICAgICAgICAgICAgICAgXHUyMTkyIHsgc3VjY2VzcywgZGF0YTogeyBwcmVwcm9jZXNzb3JzIH0gfVxuLy8gICAgICAgICAgICAgICAgICBHRVQgLi4uLzpwcmVwcm9jZXNzb3JJZC92ZXJzaW9ucyAgICAgICAgICAgICAgICAgICAgXHUyMTkyIHsgc3VjY2VzcywgZGF0YTogeyB2ZXJzaW9uczogW3sgdmVyc2lvbklkLCB2ZXJzaW9uLCBpc0FjdGl2ZSwgY3JlYXRlZEF0IH1dLCBhY3RpdmVWZXJzaW9uSWQ/IH0gfVxuLy8gICBQb3N0cHJvY2Vzc29ycyBHRVQgL2RldmVsb3Blci9wb3N0cHJvY2Vzc29ycy86YWdlbnRJZCAgICAgICAgICAgICAgXHUyMTkyIHsgc3VjY2VzcywgZGF0YTogeyBwb3N0cHJvY2Vzc29ycyB9IH1cbi8vICAgICAgICAgICAgICAgICAgR0VUIC4uLi86cG9zdHByb2Nlc3NvcklkL3ZlcnNpb25zICAgICAgICAgICAgICAgICAgIFx1MjE5MiBzYW1lIGZhbWlseSBhcyBwcmVwcm9jZXNzb3JzXG4vLyAgIFdvcmtmbG93cyAgICAgIEdFVCAvZGV2ZWxvcGVyL3dvcmtmbG93cy86YWdlbnRJZCAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyBzdWNjZXNzLCBkYXRhOiB7IHdvcmtmbG93cyB9IH0gICAoY29kZS9zY3JpcHQgcHJvamVjdGVkIG91dClcbi8vICAgICAgICAgICAgICAgICAgR0VUIC4uLi86d29ya2Zsb3dJZC92ZXJzaW9ucyAgICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHN1Y2Nlc3MsIGRhdGE6IFdvcmtmbG93VmVyc2lvbltdIH0gICBcdTIxOTAgYXJyYXkgdW5kZXIgZGF0YTsgYGFjdGl2ZWBcbi8vICAgUGVyc29uYSAgICAgICAgR0VUIC9kZXZlbG9wZXIvYWdlbnRzLzphZ2VudElkL3BlcnNvbmEvdmVyc2lvbnMgICAgIFx1MjE5MiB7IHN0YXR1cywgbWVzc2FnZSwgdmVyc2lvbnM6IFt7IHZlcnNpb246IG51bWJlciwgY3JlYXRlZERhdGU6IG51bWJlciwgaXNDdXJyZW50LCBwZXJzb25hIH1dIH1cbi8vXG4vLyBObyB2ZXJzaW9uIERUTyBjYXJyaWVzIGBkZXBsb3llZEF0YCBvciBgc291cmNlSGFzaGAuIFRoZSBcImxpdmVcIiBmbGFnIGlzXG4vLyBgaXNDdXJyZW50YCAoc2tpbGwsIHBlcnNvbmEpLCBgYWN0aXZlYCAoam9iLCB3b3JrZmxvdykgb3IgYGlzQWN0aXZlYCAvXG4vLyBgYWN0aXZlVmVyc2lvbklkYCAod2ViaG9vaywgdHJpZ2dlciwgcHJlL3Bvc3Rwcm9jZXNzb3IpLiBDcmVhdGlvbiB0aW1lIGlzXG4vLyBgY3JlYXRlZEF0YCAoSVNPIHN0cmluZykgZXZlcnl3aGVyZSBleGNlcHQgc2tpbGwvcGVyc29uYSAoYGNyZWF0ZWREYXRlYDtcbi8vIHBlcnNvbmEncyBpcyBhbiBlcG9jaC1tcyBudW1iZXIpLlxuXG5jb25zdCBMSVNUX0VYVFJBQ1RPUlMgPSB7XG4gIHNraWxsOiAgICAgICAgIChyKSA9PiByPy5za2lsbHMgPz8gW10sXG4gIHdlYmhvb2s6ICAgICAgIChyKSA9PiByPy5kYXRhPy53ZWJob29rcyA/PyBbXSxcbiAgam9iOiAgICAgICAgICAgKHIpID0+IHI/LmRhdGE/LmpvYnMgPz8gW10sXG4gIHRyaWdnZXI6ICAgICAgIChyKSA9PiByPy5kYXRhPy50cmlnZ2VycyA/PyBbXSxcbiAgcHJlcHJvY2Vzc29yOiAgKHIpID0+IHI/LmRhdGE/LnByZXByb2Nlc3NvcnMgPz8gW10sXG4gIHBvc3Rwcm9jZXNzb3I6IChyKSA9PiByPy5kYXRhPy5wb3N0cHJvY2Vzc29ycyA/PyBbXSxcbiAgd29ya2Zsb3c6ICAgICAgKHIpID0+IHI/LmRhdGE/LndvcmtmbG93cyA/PyBbXSxcbn07XG5cbmNvbnN0IFZFUlNJT05TX0VYVFJBQ1RPUlMgPSB7XG4gIHNraWxsOiAgICAgICAgIChyKSA9PiByPy52ZXJzaW9ucyA/PyBbXSxcbiAgd2ViaG9vazogICAgICAgKHIpID0+IHI/LmRhdGE/LnZlcnNpb25zID8/IFtdLFxuICBqb2I6ICAgICAgICAgICAocikgPT4gKEFycmF5LmlzQXJyYXkocj8uZGF0YSkgPyByLmRhdGEgOiBbXSksXG4gIHRyaWdnZXI6ICAgICAgIChyKSA9PiByPy5kYXRhPy52ZXJzaW9ucyA/PyBbXSxcbiAgcHJlcHJvY2Vzc29yOiAgKHIpID0+IHI/LmRhdGE/LnZlcnNpb25zID8/IFtdLFxuICBwb3N0cHJvY2Vzc29yOiAocikgPT4gcj8uZGF0YT8udmVyc2lvbnMgPz8gW10sXG4gIHdvcmtmbG93OiAgICAgIChyKSA9PiAoQXJyYXkuaXNBcnJheShyPy5kYXRhKSA/IHIuZGF0YSA6IFtdKSxcbiAgcGVyc29uYTogICAgICAgKHIpID0+IHI/LnZlcnNpb25zID8/IFtdLFxufTtcblxuLyoqIFVSTCBwYXRoIHNlZ21lbnQgdW5kZXIgL2RldmVsb3Blci8gZm9yIGVhY2ggbGlzdGFibGUgdHlwZS4gKi9cbmV4cG9ydCBjb25zdCBMSVNUX1BBVEhTID0ge1xuICBza2lsbDogJ3NraWxscycsXG4gIHdlYmhvb2s6ICd3ZWJob29rcycsXG4gIGpvYjogJ2pvYnMnLFxuICB0cmlnZ2VyOiAndHJpZ2dlcnMnLFxuICBwcmVwcm9jZXNzb3I6ICdwcmVwcm9jZXNzb3JzJyxcbiAgcG9zdHByb2Nlc3NvcjogJ3Bvc3Rwcm9jZXNzb3JzJyxcbiAgd29ya2Zsb3c6ICd3b3JrZmxvd3MnLFxufTtcblxuLyoqXG4gKiBFeHRyYWN0IGEgbGlzdCBvZiBwcmltaXRpdmVzIGZyb20gYSBsaXN0LWVuZHBvaW50IHJlc3BvbnNlLlxuICogQHRocm93cyBpZiB0aGUgdHlwZSBpcyB1bmtub3duLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdExpc3QodHlwZSwgcmVzcG9uc2UpIHtcbiAgY29uc3QgZm4gPSBMSVNUX0VYVFJBQ1RPUlNbdHlwZV07XG4gIGlmICghZm4pIHRocm93IG5ldyBFcnJvcihgZXh0cmFjdExpc3Q6IHVua25vd24gcHJpbWl0aXZlIHR5cGUgXCIke3R5cGV9XCIuIFZhbGlkOiAke09iamVjdC5rZXlzKExJU1RfRVhUUkFDVE9SUykuam9pbignLCAnKX1gKTtcbiAgcmV0dXJuIGZuKHJlc3BvbnNlKTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0IGEgbGlzdCBvZiB2ZXJzaW9ucyBmcm9tIGEgdmVyc2lvbnMtZW5kcG9pbnQgcmVzcG9uc2UuXG4gKiBAdGhyb3dzIGlmIHRoZSB0eXBlIGlzIHVua25vd24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0VmVyc2lvbnModHlwZSwgcmVzcG9uc2UpIHtcbiAgY29uc3QgZm4gPSBWRVJTSU9OU19FWFRSQUNUT1JTW3R5cGVdO1xuICBpZiAoIWZuKSB0aHJvdyBuZXcgRXJyb3IoYGV4dHJhY3RWZXJzaW9uczogdW5rbm93biBwcmltaXRpdmUgdHlwZSBcIiR7dHlwZX1cIi4gVmFsaWQ6ICR7T2JqZWN0LmtleXMoVkVSU0lPTlNfRVhUUkFDVE9SUykuam9pbignLCAnKX1gKTtcbiAgcmV0dXJuIGZuKHJlc3BvbnNlKTtcbn1cblxuLyoqXG4gKiBUaGUgYGFjdGl2ZVZlcnNpb25JZGAgYSB2ZXJzaW9ucyBlbnZlbG9wZSBtYXkgY2FycnkgYmVzaWRlIGl0cyBhcnJheVxuICogKHdlYmhvb2ssIHRyaWdnZXIsIHByZS9wb3N0cHJvY2Vzc29yKS4gTnVsbCBmb3IgdGhlIG90aGVyIGZhbWlsaWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEFjdGl2ZVZlcnNpb25JZChyZXNwb25zZSkge1xuICBjb25zdCBpZCA9IHJlc3BvbnNlPy5kYXRhPy5hY3RpdmVWZXJzaW9uSWQ7XG4gIHJldHVybiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmIGlkID8gaWQgOiBudWxsO1xufVxuXG4vKipcbiAqIElzIHRoaXMgdmVyc2lvbiB0aGUgb25lIHRoYXQgaXMgbGl2ZT8gRWFjaCBmYW1pbHkgc3BlbGxzIGl0IGRpZmZlcmVudGx5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge29iamVjdH0gdmVyc2lvbiAtIG9uZSBlbGVtZW50IG9mIGV4dHJhY3RWZXJzaW9ucygpXG4gKiBAcGFyYW0ge29iamVjdH0gW3Jlc3BvbnNlXSAtIHRoZSB2ZXJzaW9ucyBlbnZlbG9wZSAoZm9yIGFjdGl2ZVZlcnNpb25JZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQWN0aXZlVmVyc2lvbih0eXBlLCB2ZXJzaW9uLCByZXNwb25zZSkge1xuICBpZiAoIXZlcnNpb24gfHwgdHlwZW9mIHZlcnNpb24gIT09ICdvYmplY3QnKSByZXR1cm4gZmFsc2U7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ3NraWxsJzpcbiAgICBjYXNlICdwZXJzb25hJzpcbiAgICAgIHJldHVybiB2ZXJzaW9uLmlzQ3VycmVudCA9PT0gdHJ1ZTtcbiAgICBjYXNlICdqb2InOlxuICAgIGNhc2UgJ3dvcmtmbG93JzpcbiAgICAgIHJldHVybiB2ZXJzaW9uLmFjdGl2ZSA9PT0gdHJ1ZTtcbiAgICBjYXNlICd3ZWJob29rJzpcbiAgICBjYXNlICd0cmlnZ2VyJzpcbiAgICBjYXNlICdwcmVwcm9jZXNzb3InOlxuICAgIGNhc2UgJ3Bvc3Rwcm9jZXNzb3InOiB7XG4gICAgICBpZiAodmVyc2lvbi5pc0FjdGl2ZSA9PT0gdHJ1ZSkgcmV0dXJuIHRydWU7XG4gICAgICBjb25zdCBhY3RpdmVJZCA9IGV4dHJhY3RBY3RpdmVWZXJzaW9uSWQocmVzcG9uc2UpO1xuICAgICAgY29uc3Qgb3duSWQgPSB2ZXJzaW9uLnZlcnNpb25JZCA/PyB2ZXJzaW9uLmlkID8/IG51bGw7XG4gICAgICByZXR1cm4gISFhY3RpdmVJZCAmJiBvd25JZCA9PT0gYWN0aXZlSWQ7XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBJU08tODYwMSBjcmVhdGlvbiB0aW1lIG9mIGEgdmVyc2lvbiwgb3IgbnVsbC4gTm9ybWFsaXNlcyBza2lsbC9wZXJzb25hJ3NcbiAqIGBjcmVhdGVkRGF0ZWAgKHBlcnNvbmE6IGVwb2NoIG1zKSBvbnRvIHRoZSBgY3JlYXRlZEF0YCBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyc2lvbkNyZWF0ZWRBdCh2ZXJzaW9uKSB7XG4gIGlmICghdmVyc2lvbiB8fCB0eXBlb2YgdmVyc2lvbiAhPT0gJ29iamVjdCcpIHJldHVybiBudWxsO1xuICBjb25zdCByYXcgPSB2ZXJzaW9uLmNyZWF0ZWRBdCA/PyB2ZXJzaW9uLmNyZWF0ZWREYXRlID8/IG51bGw7XG4gIGlmIChyYXcgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gIGlmICh0eXBlb2YgcmF3ID09PSAnbnVtYmVyJykgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShyYXcpID8gbmV3IERhdGUocmF3KS50b0lTT1N0cmluZygpIDogbnVsbDtcbiAgcmV0dXJuIFN0cmluZyhyYXcpO1xufVxuXG4vKiogSWRlbnRpZmllciBvZiBhIHZlcnNpb24gcm93ICh0aGUgc2xvdCBsdWEtYXBpIGtleXMgYGFjdGl2ZVZlcnNpb25JZGAgb24pLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcnNpb25JZCh2ZXJzaW9uKSB7XG4gIGlmICghdmVyc2lvbiB8fCB0eXBlb2YgdmVyc2lvbiAhPT0gJ29iamVjdCcpIHJldHVybiBudWxsO1xuICByZXR1cm4gdmVyc2lvbi52ZXJzaW9uSWQgPz8gdmVyc2lvbi5pZCA/PyBudWxsO1xufVxuXG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX0xJU1RfVFlQRVMgPSBPYmplY3Qua2V5cyhMSVNUX0VYVFJBQ1RPUlMpO1xuZXhwb3J0IGNvbnN0IFNVUFBPUlRFRF9WRVJTSU9OX1RZUEVTID0gT2JqZWN0LmtleXMoVkVSU0lPTlNfRVhUUkFDVE9SUyk7XG4iLCAiaW1wb3J0IHsgYXBpUmVxdWVzdCB9IGZyb20gJy4uL2FwaS1jbGllbnQubWpzJztcbmltcG9ydCB7XG4gIGV4dHJhY3RMaXN0LFxuICBleHRyYWN0VmVyc2lvbnMsXG4gIGV4dHJhY3RBY3RpdmVWZXJzaW9uSWQsXG4gIGlzQWN0aXZlVmVyc2lvbixcbiAgdmVyc2lvbkNyZWF0ZWRBdCxcbiAgdmVyc2lvbklkLFxuICBMSVNUX1BBVEhTLFxuICBTVVBQT1JURURfVkVSU0lPTl9UWVBFUyxcbn0gZnJvbSAnLi4vcmVzcG9uc2Utc2hhcGVzLm1qcyc7XG5cbmNvbnN0IFZBTElEX1RZUEVTID0gbmV3IFNldChTVVBQT1JURURfVkVSU0lPTl9UWVBFUyk7XG5cbmV4cG9ydCBjb25zdCBsaXN0UHJpbWl0aXZlVmVyc2lvbnMgPSB7XG4gIHNwZWM6IHtcbiAgICBuYW1lOiAnbGlzdF9wcmltaXRpdmVfdmVyc2lvbnMnLFxuICAgIC8vIFdoaWNoIGZhbWlsaWVzIGNhcnJ5IGEgcGVyLWVudHJ5IGlkIFx1MjAxNCB2ZXJpZmllZCBpbiBsdWEtYXBpJ3Mgc2VydmljZVxuICAgIC8vIG1hcHBlcnMgKHBhY2thZ2VzL2x1YS1hcGkvc3JjL3NlcnZpY2VzLyk6XG4gICAgLy8gICBkZXZlbG9wZXIudHJpZ2dlci5zZXJ2aWNlLnRzIGdldFRyaWdnZXJWZXJzaW9ucyAgICAgICAgICAgIFx1MjE5MiB7IHZlcnNpb24sIHZlcnNpb25JZDogdi5pZCwgY3JlYXRlZEF0LCBpc0FjdGl2ZSB9XG4gICAgLy8gICBkZXZlbG9wZXIucHJlcHJvY2Vzc29yLnNlcnZpY2UudHMgZ2V0UHJlUHJvY2Vzc29yVmVyc2lvbnMgIFx1MjE5MiB7IHZlcnNpb25JZDogdi5pZCwgdmVyc2lvbiwgaXNBY3RpdmUsIGNyZWF0ZWRBdCB9XG4gICAgLy8gICBkZXZlbG9wZXIucG9zdHByb2Nlc3Nvci5zZXJ2aWNlLnRzIGdldFBvc3RQcm9jZXNzb3JWZXJzaW9uc1x1MjE5MiBzYW1lIGFzIHByZXByb2Nlc3NvclxuICAgIC8vICAgZGV2ZWxvcGVyLndvcmtmbG93LnNlcnZpY2UudHMgdG9WZXJzaW9uRHRvICAgICAgICAgICAgICAgICBcdTIxOTIgeyBpZCwgdmVyc2lvbiwgYWN0aXZlLCAuLi4gfVxuICAgIC8vICAgZHRvL2pvYi5kdG8udHMgSm9iVmVyc2lvbkR0byAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyBpZCwgdmVyc2lvbiwgYWN0aXZlLCAuLi4gfVxuICAgIC8vICAgZGV2ZWxvcGVyLndlYmhvb2suc2VydmljZS50cyBnZXRXZWJob29rVmVyc2lvbnMgICAgICAgICAgICBcdTIxOTIgeyB2ZXJzaW9uLCB3ZWJob29rSWQ6IHYuaWQsIGNyZWF0ZWRBdCwgaXNBY3RpdmUgfVxuICAgIC8vICAgICAgIChOTyB2ZXJzaW9uSWQvaWQga2V5IFx1MjAxNCB0aGUgcm93IGlkIGlzIHN0YXNoZWQgdW5kZXIgdGhlIG1pc25hbWVkXG4gICAgLy8gICAgICAgIGB3ZWJob29rSWRgLCB3aGljaCB3ZSBkZWxpYmVyYXRlbHkgZG8gbm90IHJlYWQgYXMgYSB2ZXJzaW9uIGlkKVxuICAgIC8vICAgZHRvL3NraWxsLmR0by50cyBTa2lsbFZlcnNpb25EdG8gICAgICAgICAgICAgICAgICAgICAgICAgICBcdTIxOTIgeyB2ZXJzaW9uLCBjcmVhdGVkRGF0ZSwgY3JlYXRlZEJ5LCBpc0N1cnJlbnQgfSAobm8gaWQpXG4gICAgLy8gICBwZXJzb25hL2Jhc2UuY29udHJvbGxlci50cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFx1MjE5MiB7IHZlcnNpb246IG51bWJlciwgY3JlYXRlZERhdGUsIGlzQ3VycmVudCwgcGVyc29uYSB9IChubyBpZClcbiAgICBkZXNjcmlwdGlvbjogJ0xpc3QgdGhlIHNlcnZlci1zaWRlIHZlcnNpb25zIG9mIG9uZSBwcmltaXRpdmUgKHNraWxsLCB3ZWJob29rLCBqb2IsIHRyaWdnZXIsIHByZXByb2Nlc3NvciwgcG9zdHByb2Nlc3Nvciwgd29ya2Zsb3cpIG9yIHRoZSBhZ2VudCBwZXJzb25hLiBSZXR1cm5zIHsgYWN0aXZlVmVyc2lvbklkLCB2ZXJzaW9uczogW3t2ZXJzaW9uLCB2ZXJzaW9uSWQsIGFjdGl2ZSwgY3JlYXRlZEF0fV0gfSBcdTIwMTQgYGFjdGl2ZWAgaXMgdGhlIHZlcnNpb24gY3VycmVudGx5IGxpdmUuIGB2ZXJzaW9uSWRgIGlzIG51bGwgZm9yIHR5cGVzIHdob3NlIHZlcnNpb25zIHJvdXRlIGNhcnJpZXMgbm8gcGVyLWVudHJ5IGlkOiBza2lsbCwgcGVyc29uYSBhbmQgd2ViaG9vayAodGhlIHdlYmhvb2sgcm91dGUgZXhwb3NlcyB0aGUgcm93IGlkIG9ubHkgdW5kZXIgYSBtaXNuYW1lZCBgd2ViaG9va0lkYCBrZXkpLiBGb3IgdGhvc2UsIGlkZW50aWZ5IGEgdmVyc2lvbiBieSBgdmVyc2lvbmA7IGZvciB3ZWJob29rcyB0aGUgbGl2ZSByb3cgaWQgaXMgdGhlIHRvcC1sZXZlbCBgYWN0aXZlVmVyc2lvbklkYC4gYGFjdGl2ZVZlcnNpb25JZGAgaXMgcG9wdWxhdGVkIG9ubHkgZm9yIHdlYmhvb2ssIHRyaWdnZXIsIHByZXByb2Nlc3NvciBhbmQgcG9zdHByb2Nlc3NvciBlbnZlbG9wZXMgYW5kIGlzIG51bGwgZm9yIHNraWxsLCBqb2IsIHdvcmtmbG93IGFuZCBwZXJzb25hLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBhZ2VudElkOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgIHR5cGU6IHsgdHlwZTogJ3N0cmluZycsIGVudW06IFsuLi5WQUxJRF9UWVBFU10gfSxcbiAgICAgICAgbmFtZTogeyB0eXBlOiAnc3RyaW5nJywgZGVzY3JpcHRpb246ICdQcmltaXRpdmUgbmFtZSBhcyB3cml0dGVuIGluIGx1YS5za2lsbC55YW1sIChvbWl0IGZvciBwZXJzb25hIFx1MjAxNCBhbiBhZ2VudCBoYXMgb25seSBvbmUpJyB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2FnZW50SWQnLCAndHlwZSddLFxuICAgIH0sXG4gIH0sXG4gIGFzeW5jIGhhbmRsZXIoeyBhZ2VudElkLCB0eXBlLCBuYW1lIH0sIGRlcHMgPSB7fSkge1xuICAgIGlmICghYWdlbnRJZCB8fCAhdHlwZSkgdGhyb3cgbmV3IEVycm9yKCdhZ2VudElkIGFuZCB0eXBlIGFyZSByZXF1aXJlZCcpO1xuICAgIGlmICghVkFMSURfVFlQRVMuaGFzKHR5cGUpKSB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdHlwZTogJHt0eXBlfS4gVmFsaWQ6ICR7Wy4uLlZBTElEX1RZUEVTXS5qb2luKCcsICcpfWApO1xuICAgIGlmICh0eXBlICE9PSAncGVyc29uYScgJiYgIW5hbWUpIHRocm93IG5ldyBFcnJvcignbmFtZSBpcyByZXF1aXJlZCBmb3IgYWxsIHR5cGVzIGV4Y2VwdCBwZXJzb25hJyk7XG5cbiAgICAvLyBWZXJzaW9ucyBsaXZlIHVuZGVyIC9kZXZlbG9wZXIvPHBsdXJhbD4vOmFnZW50SWQvOmlkL3ZlcnNpb25zLCBFWENFUFRcbiAgICAvLyBwZXJzb25hIHdoaWNoIGxpdmVzIHVuZGVyIC9kZXZlbG9wZXIvYWdlbnRzLzphZ2VudElkL3BlcnNvbmEvdmVyc2lvbnNcbiAgICAvLyAobm8gOmlkKS4gVGhlIDppZCBzbG90IGlzIHRoZSBzZXJ2ZXIgaWQgKHNraWxsSWQgLyB3ZWJob29rSWQgLyAuLi4pLFxuICAgIC8vIG5ldmVyIHRoZSBuYW1lIFx1MjAxNCBzbyByZXNvbHZlIG5hbWUgXHUyMTkyIGlkIGJ5IGxpc3RpbmcgZmlyc3QuXG4gICAgbGV0IHBhdGg7XG4gICAgaWYgKHR5cGUgPT09ICdwZXJzb25hJykge1xuICAgICAgcGF0aCA9IGAvZGV2ZWxvcGVyL2FnZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChhZ2VudElkKX0vcGVyc29uYS92ZXJzaW9uc2A7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGlkID0gYXdhaXQgcmVzb2x2ZU5hbWVUb0lkKHsgYWdlbnRJZCwgdHlwZSwgbmFtZSwgZmV0Y2hGbjogZGVwcy5mZXRjaEZuIH0pO1xuICAgICAgcGF0aCA9IGAvZGV2ZWxvcGVyLyR7TElTVF9QQVRIU1t0eXBlXX0vJHtlbmNvZGVVUklDb21wb25lbnQoYWdlbnRJZCl9LyR7ZW5jb2RlVVJJQ29tcG9uZW50KGlkKX0vdmVyc2lvbnNgO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBhcGlSZXF1ZXN0KHBhdGgsIHsgZmV0Y2hGbjogZGVwcy5mZXRjaEZuIH0pO1xuICAgIGNvbnN0IHZlcnNpb25zID0gZXh0cmFjdFZlcnNpb25zKHR5cGUsIGRhdGEpO1xuICAgIGNvbnN0IGNvbXBhY3QgPSB2ZXJzaW9ucy5tYXAoKHYpID0+ICh7XG4gICAgICB2ZXJzaW9uOiB2LnZlcnNpb24sXG4gICAgICB2ZXJzaW9uSWQ6IHZlcnNpb25JZCh2KSxcbiAgICAgIGFjdGl2ZTogaXNBY3RpdmVWZXJzaW9uKHR5cGUsIHYsIGRhdGEpLFxuICAgICAgY3JlYXRlZEF0OiB2ZXJzaW9uQ3JlYXRlZEF0KHYpLFxuICAgIH0pKTtcbiAgICBjb25zdCByZXN1bHQgPSB7IGFnZW50SWQsIHR5cGUsIG5hbWU6IHR5cGUgPT09ICdwZXJzb25hJyA/IG51bGwgOiBuYW1lLCBhY3RpdmVWZXJzaW9uSWQ6IGV4dHJhY3RBY3RpdmVWZXJzaW9uSWQoZGF0YSksIHZlcnNpb25zOiBjb21wYWN0IH07XG4gICAgcmV0dXJuIHsgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBKU09OLnN0cmluZ2lmeShyZXN1bHQsIG51bGwsIDIpIH1dIH07XG4gIH0sXG59O1xuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlTmFtZVRvSWQoeyBhZ2VudElkLCB0eXBlLCBuYW1lLCBmZXRjaEZuIH0pIHtcbiAgY29uc3QgbGlzdFBhdGggPSBgL2RldmVsb3Blci8ke0xJU1RfUEFUSFNbdHlwZV19LyR7ZW5jb2RlVVJJQ29tcG9uZW50KGFnZW50SWQpfWA7XG4gIGNvbnN0IGxpc3RSZXNwb25zZSA9IGF3YWl0IGFwaVJlcXVlc3QobGlzdFBhdGgsIHsgZmV0Y2hGbiB9KTtcbiAgY29uc3QgaXRlbXMgPSBleHRyYWN0TGlzdCh0eXBlLCBsaXN0UmVzcG9uc2UpO1xuICBjb25zdCBtYXRjaCA9IGl0ZW1zLmZpbmQoKHApID0+IHAubmFtZSA9PT0gbmFtZSk7XG4gIGlmICghbWF0Y2gpIHtcbiAgICBjb25zdCBhdmFpbGFibGUgPSBpdGVtcy5tYXAoKHApID0+IHAubmFtZSkuZmlsdGVyKEJvb2xlYW4pLmpvaW4oJywgJykgfHwgJyhub25lKSc7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBsaXN0X3ByaW1pdGl2ZV92ZXJzaW9uczogbm8gJHt0eXBlfSBuYW1lZCBcIiR7bmFtZX1cIiBvbiBhZ2VudCAke2FnZW50SWR9LiBBdmFpbGFibGU6ICR7YXZhaWxhYmxlfWApO1xuICB9XG4gIGNvbnN0IGlkID0gbWF0Y2guaWQgPz8gbWF0Y2guX2lkO1xuICBpZiAoIWlkKSB0aHJvdyBuZXcgRXJyb3IoYGxpc3RfcHJpbWl0aXZlX3ZlcnNpb25zOiAke3R5cGV9IFwiJHtuYW1lfVwiIGV4aXN0cyBidXQgaGFzIG5vIGlkIGZpZWxkYCk7XG4gIHJldHVybiBpZDtcbn1cbiIsICJpbXBvcnQgeyBhcGlSZXF1ZXN0IH0gZnJvbSAnLi4vYXBpLWNsaWVudC5tanMnO1xuaW1wb3J0IHtcbiAgZXh0cmFjdExpc3QsXG4gIGV4dHJhY3RWZXJzaW9ucyxcbiAgZXh0cmFjdEFjdGl2ZVZlcnNpb25JZCxcbiAgaXNBY3RpdmVWZXJzaW9uLFxuICB2ZXJzaW9uQ3JlYXRlZEF0LFxuICB2ZXJzaW9uSWQsXG4gIExJU1RfUEFUSFMsXG59IGZyb20gJy4uL3Jlc3BvbnNlLXNoYXBlcy5tanMnO1xuXG4vLyBDb21wb3NlcyBcIndoYXQgaXMgbGl2ZVwiIGZyb20gdGhlIHBlci10eXBlIGx1YS1hcGkgbGlzdCArIHZlcnNpb25zIHJvdXRlcy5cbi8vIFRoZXJlIGlzIG5vIHNpbmdsZSBgL2FnZW50cy86aWQvcHJvZHVjdGlvbmAgcm91dGU7IGBsdWEgc3RhdHVzIC0tanNvbmBcbi8vIGdpdmVzIHRoZSBzYW1lIHBpY3R1cmUgZm9yIHRoZSBDVVJSRU5UIHByb2plY3QgKGxvY2FsIHZzIGRlcGxveWVkKSBhbmQgaXNcbi8vIHRoZSBiZXR0ZXIgdG9vbCB3aGVuIGEgbHVhLnNraWxsLnlhbWwgaXMgYXQgaGFuZC4gVGhpcyB0b29sIHdvcmtzIGZvciBhbnlcbi8vIGFnZW50IHRoZSBjcmVkZW50aWFsIGNhbiByZWFjaCwgcHJvamVjdCBvciBub3QuXG4vL1xuLy8gUGVyLXR5cGUgZW52ZWxvcGUgaGFuZGxpbmcgbGl2ZXMgaW4gcmVzcG9uc2Utc2hhcGVzLm1qcy5cbi8vXG4vLyBSZXF1ZXN0IGZhbi1vdXQgKDEgKyA3ICsgTiB2ZXJzaW9uIGxvb2t1cHMpIGlzIHBhcmFsbGVsaXNlZCBpbiB0d28gcGhhc2VzOlxuLy8gICAxLiB0aGUgcGVyc29uYSBjYWxsIGFuZCB0aGUgc2V2ZW4gbGlzdCBjYWxscyBydW4gdG9nZXRoZXI7XG4vLyAgIDIuIHBlciB0eXBlLCBpdGVtIHZlcnNpb24gbG9va3VwcyBydW4gaW4gY2h1bmtzIG9mIFZFUlNJT05TX0NIVU5LX1NJWkUuXG4vLyBPdXRwdXQgb3JkZXIgaXMgZGV0ZXJtaW5pc3RpYyByZWdhcmRsZXNzIG9mIGNvbXBsZXRpb24gb3JkZXI6IHR5cGVzIGluXG4vLyBQUklNSVRJVkVfVFlQRVMgb3JkZXIsIGl0ZW1zIGluIHRoZSBvcmRlciB0aGUgbGlzdCByb3V0ZSByZXR1cm5lZCB0aGVtLlxuLy8gQSB3YWxsLWNsb2NrIGJ1ZGdldCAoQlVER0VUX01TLCBpbmplY3RhYmxlIGFzIGRlcHMuYnVkZ2V0TXMpIHN0b3BzIE5FV1xuLy8gcmVxdWVzdHMgb25jZSBleGNlZWRlZDsgYWxyZWFkeS1pc3N1ZWQgcmVxdWVzdHMgc3RpbGwgY29tcGxldGUuIEl0ZW1zIHRoYXRcbi8vIGNvdWxkIG5vdCBiZSBsb29rZWQgdXAgYXJlIHN0aWxsIGxpc3RlZCwgd2l0aCBgZXJyb3I6IFwic2tpcHBlZDogXHUyMDI2XCJgLCBhbmRcbi8vIHRoZSByZXN1bHQgY2FycmllcyBgcGFydGlhbDogdHJ1ZWAgKyBgcGFydGlhbFJlYXNvbmAuXG5cbmNvbnN0IFBSSU1JVElWRV9UWVBFUyA9IFsnc2tpbGwnLCAnd2ViaG9vaycsICdqb2InLCAndHJpZ2dlcicsICdwcmVwcm9jZXNzb3InLCAncG9zdHByb2Nlc3NvcicsICd3b3JrZmxvdyddO1xuY29uc3QgVkVSU0lPTlNfQ0hVTktfU0laRSA9IDU7XG5jb25zdCBERUZBVUxUX0JVREdFVF9NUyA9IDQ1XzAwMDtcblxuZXhwb3J0IGNvbnN0IGdldERlcGxveW1lbnRTdGF0dXMgPSB7XG4gIHNwZWM6IHtcbiAgICBuYW1lOiAnZ2V0X2RlcGxveW1lbnRfc3RhdHVzJyxcbiAgICBkZXNjcmlwdGlvbjogJ1doYXQgaXMgbGl2ZSByaWdodCBub3cgZm9yIGFuIGFnZW50OiBmb3IgZXZlcnkgc2tpbGwsIHdlYmhvb2ssIGpvYiwgdHJpZ2dlciwgcHJlcHJvY2Vzc29yLCBwb3N0cHJvY2Vzc29yIGFuZCB3b3JrZmxvdyB0aGUgYWN0aXZlIChkZXBsb3llZCkgdmVyc2lvbiwgcGx1cyB0aGUgYWN0aXZlIHBlcnNvbmEgdmVyc2lvbi4gQ29tcG9zZWQgZnJvbSB0aGUgcGVyLXR5cGUgbHVhLWFwaSB2ZXJzaW9uIHJvdXRlcyAobGlzdCBjYWxscyBpbiBwYXJhbGxlbCwgdGhlbiBwZXItaXRlbSB2ZXJzaW9uIGxvb2t1cHMgaW4gY2h1bmtzIG9mIDUpLiBCb3VuZGVkIGJ5IGEgNDUgcyB3YWxsLWNsb2NrIGJ1ZGdldDogaWYgZXhjZWVkZWQsIHJlbWFpbmluZyBpdGVtcyBhcmUgbGlzdGVkIHdpdGggYGVycm9yOiBcInNraXBwZWQ6IFx1MjAyNlwiYCBhbmQgdGhlIHJlc3VsdCBjYXJyaWVzIGBwYXJ0aWFsOiB0cnVlYCArIGBwYXJ0aWFsUmVhc29uYC4gSW5zaWRlIGEgcHJvamVjdCwgYGx1YSBzdGF0dXMgLS1qc29uYCBhZGRpdGlvbmFsbHkgY29tcGFyZXMgbG9jYWwgdnMgZGVwbG95ZWQuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGFnZW50SWQ6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWydhZ2VudElkJ10sXG4gICAgfSxcbiAgfSxcbiAgYXN5bmMgaGFuZGxlcih7IGFnZW50SWQgfSwgZGVwcyA9IHt9KSB7XG4gICAgaWYgKCFhZ2VudElkKSB0aHJvdyBuZXcgRXJyb3IoJ2FnZW50SWQgaXMgcmVxdWlyZWQnKTtcbiAgICBjb25zdCBpZCA9IGVuY29kZVVSSUNvbXBvbmVudChhZ2VudElkKTtcbiAgICBjb25zdCBidWRnZXRNcyA9IE51bWJlci5pc0Zpbml0ZShkZXBzLmJ1ZGdldE1zKSA/IGRlcHMuYnVkZ2V0TXMgOiBERUZBVUxUX0JVREdFVF9NUztcbiAgICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IG92ZXJCdWRnZXQgPSAoKSA9PiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0ID4gYnVkZ2V0TXM7XG4gICAgY29uc3QgZ2V0ID0gKHBhdGgpID0+IGFwaVJlcXVlc3QocGF0aCwgeyBmZXRjaEZuOiBkZXBzLmZldGNoRm4gfSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB7IGFnZW50SWQsIHBlcnNvbmE6IG51bGwsIHByaW1pdGl2ZXM6IHt9IH07XG4gICAgLy8gU2VlZCBrZXlzIHVwIGZyb250IHNvIHRoZSBvdXRwdXQga2V5IG9yZGVyIG5ldmVyIGRlcGVuZHMgb24gdGltaW5nLlxuICAgIGZvciAoY29uc3QgdHlwZSBvZiBQUklNSVRJVkVfVFlQRVMpIHJlc3VsdC5wcmltaXRpdmVzW3R5cGVdID0gW107XG5cbiAgICAvLyBQaGFzZSAxOiBwZXJzb25hICsgZXZlcnkgbGlzdCByb3V0ZSwgYWxsIGluIGZsaWdodCBhdCBvbmNlLlxuICAgIC8vIFBlcnNvbmE6IG9uZSBwZXIgYWdlbnQsIHZlcnNpb25zIHVuZGVyIC9kZXZlbG9wZXIvYWdlbnRzLzphZ2VudElkL3BlcnNvbmEvdmVyc2lvbnMuXG4gICAgY29uc3QgW3BlcnNvbmFPdXRjb21lLCAuLi5saXN0T3V0Y29tZXNdID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAgIGdldChgL2RldmVsb3Blci9hZ2VudHMvJHtpZH0vcGVyc29uYS92ZXJzaW9uc2ApLFxuICAgICAgLi4uUFJJTUlUSVZFX1RZUEVTLm1hcCgodHlwZSkgPT4gZ2V0KGAvZGV2ZWxvcGVyLyR7TElTVF9QQVRIU1t0eXBlXX0vJHtpZH1gKSksXG4gICAgXSk7XG5cbiAgICBpZiAocGVyc29uYU91dGNvbWUuc3RhdHVzID09PSAnZnVsZmlsbGVkJykge1xuICAgICAgY29uc3QgcGVyc29uYVJlc3BvbnNlID0gcGVyc29uYU91dGNvbWUudmFsdWU7XG4gICAgICBjb25zdCB2ZXJzaW9ucyA9IGV4dHJhY3RWZXJzaW9ucygncGVyc29uYScsIHBlcnNvbmFSZXNwb25zZSk7XG4gICAgICBjb25zdCBhY3RpdmUgPSB2ZXJzaW9ucy5maW5kKCh2KSA9PiBpc0FjdGl2ZVZlcnNpb24oJ3BlcnNvbmEnLCB2LCBwZXJzb25hUmVzcG9uc2UpKSA/PyBudWxsO1xuICAgICAgcmVzdWx0LnBlcnNvbmEgPSB7XG4gICAgICAgIGFjdGl2ZVZlcnNpb246IGFjdGl2ZT8udmVyc2lvbiA/PyBudWxsLFxuICAgICAgICBhY3RpdmVWZXJzaW9uQ3JlYXRlZEF0OiB2ZXJzaW9uQ3JlYXRlZEF0KGFjdGl2ZSksXG4gICAgICAgIHZlcnNpb25Db3VudDogdmVyc2lvbnMubGVuZ3RoLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0LnBlcnNvbmEgPSB7IGVycm9yOiBwZXJzb25hT3V0Y29tZS5yZWFzb24/Lm1lc3NhZ2UgPz8gU3RyaW5nKHBlcnNvbmFPdXRjb21lLnJlYXNvbikgfTtcbiAgICB9XG5cbiAgICAvLyBQaGFzZSAyOiBwZXIgdHlwZSwgcmVzb2x2ZSBlYWNoIGl0ZW0ncyB2ZXJzaW9ucyBpbiBjaHVua3MuIFR5cGVzIGFyZVxuICAgIC8vIHZpc2l0ZWQgc2VxdWVudGlhbGx5IChjYW5vbmljYWwgb3JkZXIpOyB3aXRoaW4gYSB0eXBlIHVwIHRvXG4gICAgLy8gVkVSU0lPTlNfQ0hVTktfU0laRSBsb29rdXBzIGFyZSBpbiBmbGlnaHQgdG9nZXRoZXIuXG4gICAgbGV0IGJ1ZGdldEV4aGF1c3RlZCA9IGZhbHNlO1xuICAgIGxldCBza2lwcGVkID0gMDtcbiAgICBsZXQgdG90YWwgPSAwO1xuXG4gICAgZm9yIChsZXQgdCA9IDA7IHQgPCBQUklNSVRJVkVfVFlQRVMubGVuZ3RoOyB0KyspIHtcbiAgICAgIGNvbnN0IHR5cGUgPSBQUklNSVRJVkVfVFlQRVNbdF07XG4gICAgICBjb25zdCBwYXRoID0gTElTVF9QQVRIU1t0eXBlXTtcbiAgICAgIGNvbnN0IG91dGNvbWUgPSBsaXN0T3V0Y29tZXNbdF07XG4gICAgICBpZiAob3V0Y29tZS5zdGF0dXMgIT09ICdmdWxmaWxsZWQnKSB7XG4gICAgICAgIHJlc3VsdC5wcmltaXRpdmVzW3R5cGVdID0geyBlcnJvcjogb3V0Y29tZS5yZWFzb24/Lm1lc3NhZ2UgPz8gU3RyaW5nKG91dGNvbWUucmVhc29uKSB9O1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gVGhlIFVSTCBzbG90IGlzIHRoZSBzZXJ2ZXIgaWQgKDpza2lsbElkIC8gOndlYmhvb2tJZCAvIC4uLiksIG5ldmVyXG4gICAgICAvLyB0aGUgbmFtZS4gSXRlbXMgd2l0aG91dCBhbiBpZCBhcmUgZHJvcHBlZCwgYXMgYmVmb3JlLlxuICAgICAgY29uc3QgdGFyZ2V0cyA9IGV4dHJhY3RMaXN0KHR5cGUsIG91dGNvbWUudmFsdWUpXG4gICAgICAgIC5tYXAoKHApID0+ICh7IHAsIHByaW1JZDogcC5pZCA/PyBwLl9pZCwgbmFtZTogcC5uYW1lID8/IHAuaWQgPz8gcC5faWQgfSkpXG4gICAgICAgIC5maWx0ZXIoKHRndCkgPT4gdGd0LnByaW1JZCk7XG4gICAgICB0b3RhbCArPSB0YXJnZXRzLmxlbmd0aDtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXRzLmxlbmd0aDsgaSArPSBWRVJTSU9OU19DSFVOS19TSVpFKSB7XG4gICAgICAgIGNvbnN0IGNodW5rID0gdGFyZ2V0cy5zbGljZShpLCBpICsgVkVSU0lPTlNfQ0hVTktfU0laRSk7XG5cbiAgICAgICAgaWYgKGJ1ZGdldEV4aGF1c3RlZCB8fCBvdmVyQnVkZ2V0KCkpIHtcbiAgICAgICAgICBidWRnZXRFeGhhdXN0ZWQgPSB0cnVlO1xuICAgICAgICAgIHNraXBwZWQgKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICAgIGZvciAoY29uc3QgeyBuYW1lLCBwcmltSWQgfSBvZiBjaHVuaykge1xuICAgICAgICAgICAgcmVzdWx0LnByaW1pdGl2ZXNbdHlwZV0ucHVzaCh7XG4gICAgICAgICAgICAgIG5hbWUsIGlkOiBwcmltSWQsXG4gICAgICAgICAgICAgIGVycm9yOiBgc2tpcHBlZDogd2FsbC1jbG9jayBidWRnZXQgb2YgJHtidWRnZXRNc31tcyBleGhhdXN0ZWQgYmVmb3JlIHRoaXMgdmVyc2lvbiBsb29rdXAgd2FzIGlzc3VlZGAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvdXRjb21lcyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChcbiAgICAgICAgICBjaHVuay5tYXAoKHsgcHJpbUlkIH0pID0+IGdldChgL2RldmVsb3Blci8ke3BhdGh9LyR7aWR9LyR7ZW5jb2RlVVJJQ29tcG9uZW50KHByaW1JZCl9L3ZlcnNpb25zYCkpXG4gICAgICAgICk7XG5cbiAgICAgICAgb3V0Y29tZXMuZm9yRWFjaCgodm8sIGopID0+IHtcbiAgICAgICAgICBjb25zdCB7IHAsIHByaW1JZCwgbmFtZSB9ID0gY2h1bmtbal07XG4gICAgICAgICAgaWYgKHZvLnN0YXR1cyAhPT0gJ2Z1bGZpbGxlZCcpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wcmltaXRpdmVzW3R5cGVdLnB1c2goeyBuYW1lLCBpZDogcHJpbUlkLCBlcnJvcjogdm8ucmVhc29uPy5tZXNzYWdlID8/IFN0cmluZyh2by5yZWFzb24pIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB2ZXJzaW9uc1Jlc3BvbnNlID0gdm8udmFsdWU7XG4gICAgICAgICAgY29uc3QgdmVyc2lvbnMgPSBleHRyYWN0VmVyc2lvbnModHlwZSwgdmVyc2lvbnNSZXNwb25zZSk7XG4gICAgICAgICAgY29uc3QgYWN0aXZlID0gdmVyc2lvbnMuZmluZCgodikgPT4gaXNBY3RpdmVWZXJzaW9uKHR5cGUsIHYsIHZlcnNpb25zUmVzcG9uc2UpKSA/PyBudWxsO1xuXG4gICAgICAgICAgY29uc3QgZW50cnkgPSB7XG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgaWQ6IHByaW1JZCxcbiAgICAgICAgICAgIGFjdGl2ZVZlcnNpb246IGFjdGl2ZT8udmVyc2lvbiA/PyBudWxsLFxuICAgICAgICAgICAgYWN0aXZlVmVyc2lvbklkOiB2ZXJzaW9uSWQoYWN0aXZlKSA/PyBleHRyYWN0QWN0aXZlVmVyc2lvbklkKHZlcnNpb25zUmVzcG9uc2UpLFxuICAgICAgICAgICAgYWN0aXZlVmVyc2lvbkNyZWF0ZWRBdDogdmVyc2lvbkNyZWF0ZWRBdChhY3RpdmUpLFxuICAgICAgICAgICAgdmVyc2lvbkNvdW50OiB2ZXJzaW9ucy5sZW5ndGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyBSZWNvcmRzIHRoYXQgY2FycnkgdGhlaXIgb3duIGVuYWJsZWQvZGlzYWJsZWQgc3dpdGNoLlxuICAgICAgICAgIGlmICh0eXBlb2YgcC5hY3RpdmUgPT09ICdib29sZWFuJykgZW50cnkuZW5hYmxlZCA9IHAuYWN0aXZlO1xuICAgICAgICAgIGlmICh0eXBlID09PSAnd29ya2Zsb3cnICYmIHR5cGVvZiBwLmR5bmFtaWMgPT09ICdib29sZWFuJykgZW50cnkuZHluYW1pYyA9IHAuZHluYW1pYztcbiAgICAgICAgICByZXN1bHQucHJpbWl0aXZlc1t0eXBlXS5wdXNoKGVudHJ5KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNraXBwZWQgPiAwKSB7XG4gICAgICByZXN1bHQucGFydGlhbCA9IHRydWU7XG4gICAgICByZXN1bHQucGFydGlhbFJlYXNvbiA9XG4gICAgICAgIGBXYWxsLWNsb2NrIGJ1ZGdldCBvZiAke2J1ZGdldE1zfW1zIGV4Y2VlZGVkIGFmdGVyICR7RGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdH1tczsgYCArXG4gICAgICAgIGAke3NraXBwZWR9IG9mICR7dG90YWx9IHZlcnNpb24gbG9va3VwcyB3ZXJlIG5vdCBpc3N1ZWQgKGVudHJpZXMgY2FycnkgZXJyb3I6IFwic2tpcHBlZDogXHUyMDI2XCIpLmA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogSlNPTi5zdHJpbmdpZnkocmVzdWx0LCBudWxsLCAyKSB9XSxcbiAgICB9O1xuICB9LFxufTtcbiIsICJpbXBvcnQgeyBhcGlSZXF1ZXN0IH0gZnJvbSAnLi4vYXBpLWNsaWVudC5tanMnO1xuXG4vLyBUaGUgYGxvZ1NvdXJjZWAgZW51bSBsdWEtYXBpIGFjY2VwdHMgXHUyMDE0IEFHRU5UX0xPR19TT1VSQ0VTIGluXG4vLyBwYWNrYWdlcy9zaGFyZWQtdHlwZXMvc3JjL3ZtLWV4ZWN1dGlvbi1sb2cudHlwZXMudHMgKHRoZSBzaW5nbGUgc291cmNlIG9mXG4vLyB0cnV0aCBldmVyeSBzZXJ2aWNlIGltcG9ydHMpLiBgYWxsYCBpcyB0aGUgTUNQLXNpZGUgc2VudGluZWwgZm9yIFwibm9cbi8vIGZpbHRlclwiLiBOb3RlOiBgbHVhIGxvZ3MgLS10eXBlYCBhY2NlcHRzIGEgbmFycm93ZXIgbGlzdCBhbmQgbm8gYG1hc3RyYWAuXG5leHBvcnQgY29uc3QgTE9HX1NPVVJDRVMgPSBbXG4gICdza2lsbCcsICdqb2InLCAnd2ViaG9vaycsICd0cmlnZ2VyJywgJ3ByZXByb2Nlc3NvcicsICdwb3N0cHJvY2Vzc29yJyxcbiAgJ3VzZXJfbWVzc2FnZScsICdhZ2VudF9yZXNwb25zZScsICdhZ2VudF9lcnJvcicsICdydW50aW1lJywgJ21jcCcsICdyYWcnLFxuICAnZGV2aWNlJywgJ2RldmljZS10cmlnZ2VyJywgJ21vZGVsLXJlc29sdmVyJyxcbiAgJ3dvcmtmbG93LXN0ZXAnLCAnd29ya2Zsb3ctc2NyaXB0JywgJ3dvcmtmbG93Jyxcbl07XG5cbi8vIFRoZSBgbG9nVHlwZWAgcXVlcnkgcGFyYW0gXHUyMDE0IEdFVCAvZGV2ZWxvcGVyL2FnZW50cy86YWdlbnRJZC9sb2dzIHJlYWRzIGl0XG4vLyAoY29udHJvbGxlcnMvZGV2ZWxvcGVyL2Jhc2UuY29udHJvbGxlci50cykgYW5kIGRldmVsb3Blci5zZXJ2aWNlLnRzXG4vLyBnZXRBZ2VudExvZ3MgYXBwbGllcyBpdCB2ZXJiYXRpbSBhcyBgZmlsdGVyLnN1YlR5cGUgPSBsb2dUeXBlYC4gVGhlXG4vLyBhY2NlcHRlZCB2YWx1ZXMgYXJlIHRoZXJlZm9yZSB0aGUgVm1FeGVjdXRpb25Mb2cgYHN1YlR5cGVgIGVudW0gaW5cbi8vIHBhY2thZ2VzL3NoYXJlZC1zY2hlbWFzL3NyYy92bUV4ZWN1dGlvbkxvZ3Muc2NoZW1hLnRzOlxuLy8gICBlbnVtOiBbJ3N0YXJ0JywgJ2NvbXBsZXRlJywgJ2Vycm9yJywgJ2RlYnVnJywgJ3dhcm4nLCAnaW5mbyddXG4vLyAobWlycm9yZWQgYnkgbHVhLWNsaSdzIExvZ0VudHJ5LnN1YlR5cGUgaW4gc3JjL2ludGVyZmFjZXMvbG9ncy50cykuIEFueVxuLy8gb3RoZXIgc3RyaW5nIGlzIG5vdCByZWplY3RlZCBzZXJ2ZXItc2lkZSBcdTIwMTQgaXQgc2ltcGx5IG1hdGNoZXMgbm90aGluZy5cbmV4cG9ydCBjb25zdCBMT0dfVFlQRVMgPSBbJ2Vycm9yJywgJ3dhcm4nLCAnaW5mbycsICdkZWJ1ZycsICdzdGFydCcsICdjb21wbGV0ZSddO1xuXG5jb25zdCBWQUxJRF9UWVBFUyA9IG5ldyBTZXQoWydhbGwnLCAuLi5MT0dfU09VUkNFU10pO1xuY29uc3QgVkFMSURfTE9HX1RZUEVTID0gbmV3IFNldChMT0dfVFlQRVMpO1xuXG5leHBvcnQgY29uc3QgdGFpbExvZ3MgPSB7XG4gIHNwZWM6IHtcbiAgICBuYW1lOiAndGFpbF9sb2dzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0ZldGNoIHJlY2VudCBleGVjdXRpb24gbG9ncyBmb3IgYW4gYWdlbnQgKHNhbWUgZGF0YSBhcyBgbHVhIGxvZ3MgLS1qc29uYCkuIFJldHVybnMgeyBsb2dzOiBMb2dFbnRyeVtdLCBwYWdpbmF0aW9uIH0uIEVhY2ggTG9nRW50cnkgaGFzIGBzdWJUeXBlYCAoZXJyb3IgfCB3YXJuIHwgaW5mbyB8IGRlYnVnIHwgc3RhcnQgfCBjb21wbGV0ZSksIGBtZXNzYWdlYCwgYHRpbWVzdGFtcGAsIGFuZCBgbWV0YWRhdGEubG9nU291cmNlYCAvIGBtZXRhZGF0YS5wcmltaXRpdmVOYW1lYCBcdTIwMTQgdGhlcmUgaXMgTk8gYGxldmVsYCBmaWVsZC4gRmlsdGVyIGJ5IHNvdXJjZSAoYHR5cGVgKSwgcHJpbWl0aXZlIChgbmFtZWApIGFuZC9vciBzZXZlcml0eSAoYGxvZ1R5cGVgLCB3aGljaCBmaWx0ZXJzIG9uIGBzdWJUeXBlYCkuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGFnZW50SWQ6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICAgdHlwZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGVudW06IFsuLi5WQUxJRF9UWVBFU10sXG4gICAgICAgICAgZGVmYXVsdDogJ2FsbCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdMb2cgc291cmNlIGZpbHRlciAobWFwcyB0byBsdWEtYXBpIGBsb2dTb3VyY2VgKS4gYGFsbGAgPSBubyBmaWx0ZXIuJyxcbiAgICAgICAgfSxcbiAgICAgICAgbmFtZTogeyB0eXBlOiAnc3RyaW5nJywgZGVzY3JpcHRpb246ICdGaWx0ZXIgYnkgcHJpbWl0aXZlIG5hbWUgKG9wdGlvbmFsOyBtYXBzIHRvIGBwcmltaXRpdmVOYW1lYCknIH0sXG4gICAgICAgIGxvZ1R5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBlbnVtOiBMT0dfVFlQRVMsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdGaWx0ZXIgYnkgTG9nRW50cnkgYHN1YlR5cGVgIChvcHRpb25hbDsgbWFwcyB0byBsdWEtYXBpIGBsb2dUeXBlYCkuIE9taXQgZm9yIGV2ZXJ5IHNldmVyaXR5LiBlLmcuIGBlcnJvcmAgdG8gc2VlIG9ubHkgZmFpbHVyZXMuJyxcbiAgICAgICAgfSxcbiAgICAgICAgLy8gbHVhLWFwaSBjYXBzIGxpbWl0IGF0IDEwMCBzZXJ2ZXItc2lkZSAoTWF0aC5taW4oMTAwLCAuLi4pIGluXG4gICAgICAgIC8vIGNvbnRyb2xsZXJzL2RldmVsb3Blci9iYXNlLmNvbnRyb2xsZXIudHMpLiBNYXRjaCB0aGUgc2VydmVyIGNhcCBzb1xuICAgICAgICAvLyB0aGUgdG9vbCdzIGNvbnRyYWN0IGlzIGhvbmVzdC5cbiAgICAgICAgbGltaXQ6IHsgdHlwZTogJ251bWJlcicsIGRlZmF1bHQ6IDUwLCBtaW5pbXVtOiAxLCBtYXhpbXVtOiAxMDAgfSxcbiAgICAgICAgcGFnZTogeyB0eXBlOiAnbnVtYmVyJywgbWluaW11bTogMSwgZGVzY3JpcHRpb246ICdQYWdlIG51bWJlciBmb3IgcGFnaW5hdGlvbiAob3B0aW9uYWwpJyB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2FnZW50SWQnXSxcbiAgICB9LFxuICB9LFxuICBhc3luYyBoYW5kbGVyKHsgYWdlbnRJZCwgdHlwZSA9ICdhbGwnLCBuYW1lLCBsb2dUeXBlLCBsaW1pdCA9IDUwLCBwYWdlIH0sIGRlcHMgPSB7fSkge1xuICAgIGlmICghYWdlbnRJZCkgdGhyb3cgbmV3IEVycm9yKCdhZ2VudElkIGlzIHJlcXVpcmVkJyk7XG4gICAgaWYgKCFWQUxJRF9UWVBFUy5oYXModHlwZSkpIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0eXBlOiAke3R5cGV9LiBWYWxpZDogJHtbLi4uVkFMSURfVFlQRVNdLmpvaW4oJywgJyl9YCk7XG4gICAgaWYgKGxvZ1R5cGUgIT09IHVuZGVmaW5lZCAmJiAhVkFMSURfTE9HX1RZUEVTLmhhcyhsb2dUeXBlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGxvZ1R5cGU6ICR7bG9nVHlwZX0uIFZhbGlkOiAke0xPR19UWVBFUy5qb2luKCcsICcpfWApO1xuICAgIH1cbiAgICAvLyBEZWZlbnNpdmUgY2FwIG1hdGNoaW5nIHRoZSBzZXJ2ZXItc2lkZSBsaW1pdDsgcmVqZWN0cyBsb3VkIHJhdGhlclxuICAgIC8vIHRoYW4gc2lsZW50bHkgdHJ1bmNhdGluZy5cbiAgICBpZiAobGltaXQgPiAxMDApIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBsaW1pdDogJHtsaW1pdH0uIGx1YS1hcGkgY2FwcyBsb2dzIGF0IDEwMCBlbnRyaWVzIHBlciBjYWxsLmApO1xuICAgIC8vIFJvdXRlOiBHRVQgL2RldmVsb3Blci9hZ2VudHMvOmFnZW50SWQvbG9ncyAoY29udHJvbGxlcnMvZGV2ZWxvcGVyL2Jhc2UuY29udHJvbGxlci50cykuXG4gICAgLy8gUXVlcnkgcGFyYW1zIHRoZSBzZXJ2ZXIgcmVhZHM6IHBhZ2UsIGxpbWl0LCBzb3J0QnksIHNvcnRPcmRlciwgbG9nU291cmNlLFxuICAgIC8vIHByaW1pdGl2ZUlkLCBwcmltaXRpdmVOYW1lLCB0b29sSWQsIHRvb2xOYW1lLCBsb2dUeXBlLCB1c2VySWQuIFRoZVxuICAgIC8vIHR5cGUgZmlsdGVyIGlzIGBsb2dTb3VyY2VgIFx1MjAxNCBhIGBwcmltaXRpdmVUeXBlYCBwYXJhbSBpcyBzaWxlbnRseSBpZ25vcmVkLlxuICAgIGNvbnN0IHF1ZXJ5ID0geyBsaW1pdCB9O1xuICAgIGlmICh0eXBlICE9PSAnYWxsJykgcXVlcnkubG9nU291cmNlID0gdHlwZTtcbiAgICBpZiAobmFtZSkgcXVlcnkucHJpbWl0aXZlTmFtZSA9IG5hbWU7XG4gICAgaWYgKGxvZ1R5cGUpIHF1ZXJ5LmxvZ1R5cGUgPSBsb2dUeXBlO1xuICAgIGlmIChwYWdlKSBxdWVyeS5wYWdlID0gcGFnZTtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgYXBpUmVxdWVzdChcbiAgICAgIGAvZGV2ZWxvcGVyL2FnZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChhZ2VudElkKX0vbG9nc2AsXG4gICAgICB7IHF1ZXJ5LCBmZXRjaEZuOiBkZXBzLmZldGNoRm4gfVxuICAgICk7XG4gICAgcmV0dXJuIHsgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBKU09OLnN0cmluZ2lmeShkYXRhLCBudWxsLCAyKSB9XSB9O1xuICB9LFxufTtcbiIsICIvLyBNQ1Agc3RkaW8gc2VydmVyIGJvb3RzdHJhcC4gUGVyIHRlY2ggc3BlYyBcdTAwQTc4LjEuXG5cbmltcG9ydCB7IFNlcnZlciB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL2luZGV4LmpzJztcbmltcG9ydCB7IFN0ZGlvU2VydmVyVHJhbnNwb3J0IH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvc3RkaW8uanMnO1xuaW1wb3J0IHtcbiAgQ2FsbFRvb2xSZXF1ZXN0U2NoZW1hLFxuICBMaXN0VG9vbHNSZXF1ZXN0U2NoZW1hLFxufSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3R5cGVzLmpzJztcbmltcG9ydCAqIGFzIHRvb2xzIGZyb20gJy4vdG9vbHMvaW5kZXgubWpzJztcblxuY29uc3QgVE9PTF9SRUdJU1RSWSA9IE9iamVjdC52YWx1ZXModG9vbHMpO1xuXG5jb25zdCBzZXJ2ZXIgPSBuZXcgU2VydmVyKFxuICB7IG5hbWU6ICdsdWEtcGxhdGZvcm0nLCB2ZXJzaW9uOiAnMS42LjAnIH0sXG4gIHsgY2FwYWJpbGl0aWVzOiB7IHRvb2xzOiB7fSB9IH1cbik7XG5cbnNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0VG9vbHNSZXF1ZXN0U2NoZW1hLCBhc3luYyAoKSA9PiAoe1xuICB0b29sczogVE9PTF9SRUdJU1RSWS5tYXAoKHQpID0+IHQuc3BlYyksXG59KSk7XG5cbnNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihDYWxsVG9vbFJlcXVlc3RTY2hlbWEsIGFzeW5jIChyZXEpID0+IHtcbiAgY29uc3QgdG9vbCA9IFRPT0xfUkVHSVNUUlkuZmluZCgodCkgPT4gdC5zcGVjLm5hbWUgPT09IHJlcS5wYXJhbXMubmFtZSk7XG4gIGlmICghdG9vbCkgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRvb2w6ICR7cmVxLnBhcmFtcy5uYW1lfWApO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB0b29sLmhhbmRsZXIocmVxLnBhcmFtcy5hcmd1bWVudHMgPz8ge30pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0OiBgRXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YCB9XSxcbiAgICAgIGlzRXJyb3I6IHRydWUsXG4gICAgfTtcbiAgfVxufSk7XG5cbi8vIFx1MDBBNzE5LjYgY3Jhc2ggcmVwb3J0aW5nIFx1MjAxNCBtdXN0IGxhbmQgQkVGT1JFIHByb2Nlc3MgZXhpdCBzbyB0aGUgZXZlbnQgcmVhY2hlc1xuLy8gdGVsZW1ldHJ5LiBXaW5kb3dzIGNhbiBkcm9wIHRoZSBsYXN0IHN0ZGVyciB3cml0ZSBpZiBwcm9jZXNzLmV4aXQgZmlyZXNcbi8vIHN5bmNocm9ub3VzbHkgYWZ0ZXIgaXQ7IHNhbWUgYnVnIGNsYXNzIGFzIGxpYi9ob29rLXJ1bnRpbWUubWpzJ3MgZXhpdCgpLlxuLy8gRXhpdCBvbmx5IGluc2lkZSB0aGUgd3JpdGUgY2FsbGJhY2sgc28gdGhlIGZsdXNoIGNvbXBsZXRlcy5cbmZ1bmN0aW9uIHJlcG9ydENyYXNoQW5kRXhpdChwYXlsb2FkKSB7XG4gIHByb2Nlc3Muc3RkZXJyLndyaXRlKEpTT04uc3RyaW5naWZ5KHBheWxvYWQpICsgJ1xcbicsICgpID0+IHByb2Nlc3MuZXhpdCgxKSk7XG59XG5cbnByb2Nlc3Mub24oJ3VuY2F1Z2h0RXhjZXB0aW9uJywgKGVycikgPT4ge1xuICByZXBvcnRDcmFzaEFuZEV4aXQoe1xuICAgIGV2ZW50OiAnbWNwX3NlcnZlcl9jcmFzaCcsXG4gICAga2luZDogJ3VuY2F1Z2h0RXhjZXB0aW9uJyxcbiAgICBtZXNzYWdlOiBlcnI/Lm1lc3NhZ2UsXG4gICAgc3RhY2s6IGVycj8uc3RhY2ssXG4gICAgcGx1Z2luX3ZlcnNpb246ICcxLjYuMCcsXG4gICAgbHVhX2NsaV92ZXJzaW9uOiBwcm9jZXNzLmVudi5MVUFfQ0xJX1ZFUlNJT04gPz8gbnVsbCxcbiAgICBwbGF0Zm9ybTogcHJvY2Vzcy5wbGF0Zm9ybSxcbiAgICB0czogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICB9KTtcbn0pO1xuXG5wcm9jZXNzLm9uKCd1bmhhbmRsZWRSZWplY3Rpb24nLCAocmVhc29uKSA9PiB7XG4gIHJlcG9ydENyYXNoQW5kRXhpdCh7XG4gICAgZXZlbnQ6ICdtY3Bfc2VydmVyX2NyYXNoJyxcbiAgICBraW5kOiAndW5oYW5kbGVkUmVqZWN0aW9uJyxcbiAgICByZWFzb246IFN0cmluZyhyZWFzb24pLFxuICAgIHN0YWNrOiAvKiogQHR5cGUge2FueX0gKi8gKHJlYXNvbik/LnN0YWNrLFxuICAgIHBsdWdpbl92ZXJzaW9uOiAnMS42LjAnLFxuICAgIGx1YV9jbGlfdmVyc2lvbjogcHJvY2Vzcy5lbnYuTFVBX0NMSV9WRVJTSU9OID8/IG51bGwsXG4gICAgcGxhdGZvcm06IHByb2Nlc3MucGxhdGZvcm0sXG4gICAgdHM6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgfSk7XG59KTtcblxu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LElBQUksaUJBQW1CLEtBQ2hELFNBQVUsUUFBUSxTQUNsQixHQUFJLElBQUksS0FBSyxFQUFFLFlBQVksQ0FDN0IsQ0FBQyxDQUNILENBQUMsRUFFRCxNQUFNVixHQUFPLFFBQVEsSUFBSVcsRUFBc0IiLAogICJuYW1lcyI6IFsiZXh0ZXJuYWxfZXhwb3J0cyIsICJfX2V4cG9ydCIsICJCUkFORCIsICJESVJUWSIsICJFTVBUWV9QQVRIIiwgIklOVkFMSUQiLCAiTkVWRVIiLCAiT0siLCAiUGFyc2VTdGF0dXMiLCAiWm9kVHlwZSIsICJab2RBbnkiLCAiWm9kQXJyYXkiLCAiWm9kQmlnSW50IiwgIlpvZEJvb2xlYW4iLCAiWm9kQnJhbmRlZCIsICJab2RDYXRjaCIsICJab2REYXRlIiwgIlpvZERlZmF1bHQiLCAiWm9kRGlzY3JpbWluYXRlZFVuaW9uIiwgIlpvZEVmZmVjdHMiLCAiWm9kRW51bSIsICJab2RFcnJvciIsICJab2RGaXJzdFBhcnR5VHlwZUtpbmQiLCAiWm9kRnVuY3Rpb24iLCAiWm9kSW50ZXJzZWN0aW9uIiwgIlpvZElzc3VlQ29kZSIsICJab2RMYXp5IiwgIlpvZExpdGVyYWwiLCAiWm9kTWFwIiwgIlpvZE5hTiIsICJab2ROYXRpdmVFbnVtIiwgIlpvZE5ldmVyIiwgIlpvZE51bGwiLCAiWm9kTnVsbGFibGUiLCAiWm9kTnVtYmVyIiwgIlpvZE9iamVjdCIsICJab2RPcHRpb25hbCIsICJab2RQYXJzZWRUeXBlIiwgIlpvZFBpcGVsaW5lIiwgIlpvZFByb21pc2UiLCAiWm9kUmVhZG9ubHkiLCAiWm9kUmVjb3JkIiwgIlpvZFNldCIsICJab2RTdHJpbmciLCAiWm9kU3ltYm9sIiwgIlpvZFR1cGxlIiwgIlpvZFVuZGVmaW5lZCIsICJab2RVbmlvbiIsICJab2RVbmtub3duIiwgIlpvZFZvaWQiLCAiYWRkSXNzdWVUb0NvbnRleHQiLCAiYW55VHlwZSIsICJhcnJheVR5cGUiLCAiYmlnSW50VHlwZSIsICJib29sZWFuVHlwZSIsICJjb2VyY2UiLCAiY3VzdG9tIiwgImRhdGVUeXBlIiwgImRhdGV0aW1lUmVnZXgiLCAiZW5fZGVmYXVsdCIsICJkaXNjcmltaW5hdGVkVW5pb25UeXBlIiwgImVmZmVjdHNUeXBlIiwgImVudW1UeXBlIiwgImZ1bmN0aW9uVHlwZSIsICJnZXRFcnJvck1hcCIsICJnZXRQYXJzZWRUeXBlIiwgImluc3RhbmNlT2ZUeXBlIiwgImludGVyc2VjdGlvblR5cGUiLCAiaXNBYm9ydGVkIiwgImlzQXN5bmMiLCAiaXNEaXJ0eSIsICJpc1ZhbGlkIiwgImxhdGUiLCAibGF6eVR5cGUiLCAibGl0ZXJhbFR5cGUiLCAibWFrZUlzc3VlIiwgIm1hcFR5cGUiLCAibmFuVHlwZSIsICJuYXRpdmVFbnVtVHlwZSIsICJuZXZlclR5cGUiLCAibnVsbFR5cGUiLCAibnVsbGFibGVUeXBlIiwgIm51bWJlclR5cGUiLCAib2JqZWN0VHlwZSIsICJvYmplY3RVdGlsIiwgIm9ib29sZWFuIiwgIm9udW1iZXIiLCAib3B0aW9uYWxUeXBlIiwgIm9zdHJpbmciLCAicGlwZWxpbmVUeXBlIiwgInByZXByb2Nlc3NUeXBlIiwgInByb21pc2VUeXBlIiwgInF1b3RlbGVzc0pzb24iLCAicmVjb3JkVHlwZSIsICJzZXRUeXBlIiwgInNldEVycm9yTWFwIiwgInN0cmljdE9iamVjdFR5cGUiLCAic3RyaW5nVHlwZSIsICJzeW1ib2xUeXBlIiwgInR1cGxlVHlwZSIsICJ1bmRlZmluZWRUeXBlIiwgInVuaW9uVHlwZSIsICJ1bmtub3duVHlwZSIsICJ1dGlsIiwgInZvaWRUeXBlIiwgInV0aWwiLCAiXyIsICJhc3NlcnRJcyIsICJfYXJnIiwgImFzc2VydE5ldmVyIiwgIl94IiwgIml0ZW1zIiwgIm9iaiIsICJpdGVtIiwgInZhbGlkS2V5cyIsICJrIiwgImZpbHRlcmVkIiwgImUiLCAib2JqZWN0IiwgImtleXMiLCAia2V5IiwgImFyciIsICJjaGVja2VyIiwgInZhbCIsICJqb2luVmFsdWVzIiwgImFycmF5IiwgInNlcGFyYXRvciIsICJ2YWx1ZSIsICJvYmplY3RVdGlsIiwgImZpcnN0IiwgInNlY29uZCIsICJab2RQYXJzZWRUeXBlIiwgImdldFBhcnNlZFR5cGUiLCAiZGF0YSIsICJab2RJc3N1ZUNvZGUiLCAidXRpbCIsICJxdW90ZWxlc3NKc29uIiwgIm9iaiIsICJab2RFcnJvciIsICJfWm9kRXJyb3IiLCAiaXNzdWVzIiwgInN1YiIsICJzdWJzIiwgImFjdHVhbFByb3RvIiwgIl9tYXBwZXIiLCAibWFwcGVyIiwgImlzc3VlIiwgImZpZWxkRXJyb3JzIiwgInByb2Nlc3NFcnJvciIsICJlcnJvciIsICJjdXJyIiwgImkiLCAiZWwiLCAidmFsdWUiLCAiZm9ybUVycm9ycyIsICJmaXJzdEVsIiwgImVycm9yTWFwIiwgImlzc3VlIiwgIl9jdHgiLCAibWVzc2FnZSIsICJab2RJc3N1ZUNvZGUiLCAiWm9kUGFyc2VkVHlwZSIsICJ1dGlsIiwgImVuX2RlZmF1bHQiLCAib3ZlcnJpZGVFcnJvck1hcCIsICJlbl9kZWZhdWx0IiwgInNldEVycm9yTWFwIiwgIm1hcCIsICJvdmVycmlkZUVycm9yTWFwIiwgImdldEVycm9yTWFwIiwgIm1ha2VJc3N1ZSIsICJwYXJhbXMiLCAiZGF0YSIsICJwYXRoIiwgImVycm9yTWFwcyIsICJpc3N1ZURhdGEiLCAiZnVsbFBhdGgiLCAiZnVsbElzc3VlIiwgImVycm9yTWVzc2FnZSIsICJtYXBzIiwgIm0iLCAibWFwIiwgIkVNUFRZX1BBVEgiLCAiYWRkSXNzdWVUb0NvbnRleHQiLCAiY3R4IiwgIm92ZXJyaWRlTWFwIiwgImdldEVycm9yTWFwIiwgImlzc3VlIiwgImVuX2RlZmF1bHQiLCAieCIsICJQYXJzZVN0YXR1cyIsICJfUGFyc2VTdGF0dXMiLCAic3RhdHVzIiwgInJlc3VsdHMiLCAiYXJyYXlWYWx1ZSIsICJzIiwgIklOVkFMSUQiLCAicGFpcnMiLCAic3luY1BhaXJzIiwgInBhaXIiLCAia2V5IiwgInZhbHVlIiwgImZpbmFsT2JqZWN0IiwgIkRJUlRZIiwgIk9LIiwgImlzQWJvcnRlZCIsICJpc0RpcnR5IiwgImlzVmFsaWQiLCAiaXNBc3luYyIsICJlcnJvclV0aWwiLCAibWVzc2FnZSIsICJQYXJzZUlucHV0TGF6eVBhdGgiLCAicGFyZW50IiwgInZhbHVlIiwgInBhdGgiLCAia2V5IiwgImhhbmRsZVJlc3VsdCIsICJjdHgiLCAicmVzdWx0IiwgImlzVmFsaWQiLCAiZXJyb3IiLCAiWm9kRXJyb3IiLCAicHJvY2Vzc0NyZWF0ZVBhcmFtcyIsICJwYXJhbXMiLCAiZXJyb3JNYXAiLCAiaW52YWxpZF90eXBlX2Vycm9yIiwgInJlcXVpcmVkX2Vycm9yIiwgImRlc2NyaXB0aW9uIiwgImlzcyIsICJtZXNzYWdlIiwgIlpvZFR5cGUiLCAiaW5wdXQiLCAiZ2V0UGFyc2VkVHlwZSIsICJQYXJzZVN0YXR1cyIsICJpc0FzeW5jIiwgImRhdGEiLCAiZXJyIiwgIm1heWJlQXN5bmNSZXN1bHQiLCAiY2hlY2siLCAiZ2V0SXNzdWVQcm9wZXJ0aWVzIiwgInZhbCIsICJzZXRFcnJvciIsICJab2RJc3N1ZUNvZGUiLCAicmVmaW5lbWVudERhdGEiLCAicmVmaW5lbWVudCIsICJab2RFZmZlY3RzIiwgIlpvZEZpcnN0UGFydHlUeXBlS2luZCIsICJkZWYiLCAiWm9kT3B0aW9uYWwiLCAiWm9kTnVsbGFibGUiLCAiWm9kQXJyYXkiLCAiWm9kUHJvbWlzZSIsICJvcHRpb24iLCAiWm9kVW5pb24iLCAiaW5jb21pbmciLCAiWm9kSW50ZXJzZWN0aW9uIiwgInRyYW5zZm9ybSIsICJkZWZhdWx0VmFsdWVGdW5jIiwgIlpvZERlZmF1bHQiLCAiWm9kQnJhbmRlZCIsICJjYXRjaFZhbHVlRnVuYyIsICJab2RDYXRjaCIsICJUaGlzIiwgInRhcmdldCIsICJab2RQaXBlbGluZSIsICJab2RSZWFkb25seSIsICJjdWlkUmVnZXgiLCAiY3VpZDJSZWdleCIsICJ1bGlkUmVnZXgiLCAidXVpZFJlZ2V4IiwgIm5hbm9pZFJlZ2V4IiwgImp3dFJlZ2V4IiwgImR1cmF0aW9uUmVnZXgiLCAiZW1haWxSZWdleCIsICJfZW1vamlSZWdleCIsICJlbW9qaVJlZ2V4IiwgImlwdjRSZWdleCIsICJpcHY0Q2lkclJlZ2V4IiwgImlwdjZSZWdleCIsICJpcHY2Q2lkclJlZ2V4IiwgImJhc2U2NFJlZ2V4IiwgImJhc2U2NHVybFJlZ2V4IiwgImRhdGVSZWdleFNvdXJjZSIsICJkYXRlUmVnZXgiLCAidGltZVJlZ2V4U291cmNlIiwgImFyZ3MiLCAic2Vjb25kc1JlZ2V4U291cmNlIiwgInNlY29uZHNRdWFudGlmaWVyIiwgInRpbWVSZWdleCIsICJkYXRldGltZVJlZ2V4IiwgInJlZ2V4IiwgIm9wdHMiLCAiaXNWYWxpZElQIiwgImlwIiwgInZlcnNpb24iLCAiaXNWYWxpZEpXVCIsICJqd3QiLCAiYWxnIiwgImhlYWRlciIsICJiYXNlNjQiLCAiZGVjb2RlZCIsICJpc1ZhbGlkQ2lkciIsICJab2RTdHJpbmciLCAiX1pvZFN0cmluZyIsICJab2RQYXJzZWRUeXBlIiwgImFkZElzc3VlVG9Db250ZXh0IiwgIklOVkFMSUQiLCAic3RhdHVzIiwgInRvb0JpZyIsICJ0b29TbWFsbCIsICJ1dGlsIiwgInZhbGlkYXRpb24iLCAiZXJyb3JVdGlsIiwgIm9wdGlvbnMiLCAibWluTGVuZ3RoIiwgIm1heExlbmd0aCIsICJsZW4iLCAiY2giLCAibWluIiwgIm1heCIsICJmbG9hdFNhZmVSZW1haW5kZXIiLCAic3RlcCIsICJ2YWxEZWNDb3VudCIsICJzdGVwRGVjQ291bnQiLCAiZGVjQ291bnQiLCAidmFsSW50IiwgInN0ZXBJbnQiLCAiWm9kTnVtYmVyIiwgIl9ab2ROdW1iZXIiLCAia2luZCIsICJpbmNsdXNpdmUiLCAiWm9kQmlnSW50IiwgIl9ab2RCaWdJbnQiLCAiWm9kQm9vbGVhbiIsICJPSyIsICJab2REYXRlIiwgIl9ab2REYXRlIiwgIm1pbkRhdGUiLCAibWF4RGF0ZSIsICJab2RTeW1ib2wiLCAiWm9kVW5kZWZpbmVkIiwgIlpvZE51bGwiLCAiWm9kQW55IiwgIlpvZFVua25vd24iLCAiWm9kTmV2ZXIiLCAiWm9kVm9pZCIsICJfWm9kQXJyYXkiLCAiaXRlbSIsICJpIiwgInNjaGVtYSIsICJkZWVwUGFydGlhbGlmeSIsICJab2RPYmplY3QiLCAibmV3U2hhcGUiLCAiZmllbGRTY2hlbWEiLCAiWm9kVHVwbGUiLCAiX1pvZE9iamVjdCIsICJzaGFwZSIsICJrZXlzIiwgInNoYXBlS2V5cyIsICJleHRyYUtleXMiLCAicGFpcnMiLCAia2V5VmFsaWRhdG9yIiwgInVua25vd25LZXlzIiwgImNhdGNoYWxsIiwgInN5bmNQYWlycyIsICJwYWlyIiwgImlzc3VlIiwgImRlZmF1bHRFcnJvciIsICJhdWdtZW50YXRpb24iLCAibWVyZ2luZyIsICJpbmRleCIsICJtYXNrIiwgIm5ld0ZpZWxkIiwgImNyZWF0ZVpvZEVudW0iLCAiaGFuZGxlUmVzdWx0cyIsICJyZXN1bHRzIiwgInVuaW9uRXJyb3JzIiwgImNoaWxkQ3R4IiwgImRpcnR5IiwgImlzc3VlcyIsICJ0eXBlcyIsICJnZXREaXNjcmltaW5hdG9yIiwgInR5cGUiLCAiWm9kTGF6eSIsICJab2RMaXRlcmFsIiwgIlpvZEVudW0iLCAiWm9kTmF0aXZlRW51bSIsICJab2REaXNjcmltaW5hdGVkVW5pb24iLCAiX1pvZERpc2NyaW1pbmF0ZWRVbmlvbiIsICJkaXNjcmltaW5hdG9yIiwgImRpc2NyaW1pbmF0b3JWYWx1ZSIsICJvcHRpb25zTWFwIiwgImRpc2NyaW1pbmF0b3JWYWx1ZXMiLCAibWVyZ2VWYWx1ZXMiLCAiYSIsICJiIiwgImFUeXBlIiwgImJUeXBlIiwgImJLZXlzIiwgInNoYXJlZEtleXMiLCAibmV3T2JqIiwgInNoYXJlZFZhbHVlIiwgIm5ld0FycmF5IiwgIml0ZW1BIiwgIml0ZW1CIiwgImhhbmRsZVBhcnNlZCIsICJwYXJzZWRMZWZ0IiwgInBhcnNlZFJpZ2h0IiwgImlzQWJvcnRlZCIsICJtZXJnZWQiLCAiaXNEaXJ0eSIsICJsZWZ0IiwgInJpZ2h0IiwgIl9ab2RUdXBsZSIsICJpdGVtcyIsICJpdGVtSW5kZXgiLCAieCIsICJyZXN0IiwgInNjaGVtYXMiLCAiWm9kUmVjb3JkIiwgIl9ab2RSZWNvcmQiLCAia2V5VHlwZSIsICJ2YWx1ZVR5cGUiLCAiZmlyc3QiLCAic2Vjb25kIiwgInRoaXJkIiwgIlpvZE1hcCIsICJmaW5hbE1hcCIsICJab2RTZXQiLCAiX1pvZFNldCIsICJmaW5hbGl6ZVNldCIsICJlbGVtZW50cyIsICJwYXJzZWRTZXQiLCAiZWxlbWVudCIsICJtaW5TaXplIiwgIm1heFNpemUiLCAic2l6ZSIsICJab2RGdW5jdGlvbiIsICJfWm9kRnVuY3Rpb24iLCAibWFrZUFyZ3NJc3N1ZSIsICJtYWtlSXNzdWUiLCAiZ2V0RXJyb3JNYXAiLCAiZW5fZGVmYXVsdCIsICJtYWtlUmV0dXJuc0lzc3VlIiwgInJldHVybnMiLCAiZm4iLCAibWUiLCAicGFyc2VkQXJncyIsICJlIiwgInBhcnNlZFJldHVybnMiLCAicmV0dXJuVHlwZSIsICJmdW5jIiwgImdldHRlciIsICJ2YWx1ZXMiLCAiX1pvZEVudW0iLCAiZXhwZWN0ZWRWYWx1ZXMiLCAiZW51bVZhbHVlcyIsICJuZXdEZWYiLCAib3B0IiwgIm5hdGl2ZUVudW1WYWx1ZXMiLCAicHJvbWlzaWZpZWQiLCAiZWZmZWN0IiwgImNoZWNrQ3R4IiwgImFyZyIsICJwcm9jZXNzZWQiLCAiRElSVFkiLCAiZXhlY3V0ZVJlZmluZW1lbnQiLCAiYWNjIiwgImlubmVyIiwgImJhc2UiLCAicHJlcHJvY2VzcyIsICJab2RPcHRpb25hbCIsICJab2RUeXBlIiwgImlucHV0IiwgIlpvZFBhcnNlZFR5cGUiLCAiT0siLCAidHlwZSIsICJwYXJhbXMiLCAiWm9kRmlyc3RQYXJ0eVR5cGVLaW5kIiwgInByb2Nlc3NDcmVhdGVQYXJhbXMiLCAiWm9kTnVsbGFibGUiLCAiWm9kRGVmYXVsdCIsICJjdHgiLCAiZGF0YSIsICJab2RDYXRjaCIsICJuZXdDdHgiLCAicmVzdWx0IiwgImlzQXN5bmMiLCAiWm9kRXJyb3IiLCAiWm9kTmFOIiwgImFkZElzc3VlVG9Db250ZXh0IiwgIlpvZElzc3VlQ29kZSIsICJJTlZBTElEIiwgIkJSQU5EIiwgIlpvZEJyYW5kZWQiLCAiWm9kUGlwZWxpbmUiLCAiX1pvZFBpcGVsaW5lIiwgInN0YXR1cyIsICJpblJlc3VsdCIsICJESVJUWSIsICJhIiwgImIiLCAiWm9kUmVhZG9ubHkiLCAiZnJlZXplIiwgImlzVmFsaWQiLCAiY2xlYW5QYXJhbXMiLCAicCIsICJjdXN0b20iLCAiY2hlY2siLCAiX3BhcmFtcyIsICJmYXRhbCIsICJab2RBbnkiLCAiciIsICJfZmF0YWwiLCAibGF0ZSIsICJab2RPYmplY3QiLCAiWm9kRmlyc3RQYXJ0eVR5cGVLaW5kIiwgImluc3RhbmNlT2ZUeXBlIiwgImNscyIsICJwYXJhbXMiLCAiY3VzdG9tIiwgImRhdGEiLCAic3RyaW5nVHlwZSIsICJab2RTdHJpbmciLCAibnVtYmVyVHlwZSIsICJab2ROdW1iZXIiLCAibmFuVHlwZSIsICJab2ROYU4iLCAiYmlnSW50VHlwZSIsICJab2RCaWdJbnQiLCAiYm9vbGVhblR5cGUiLCAiWm9kQm9vbGVhbiIsICJkYXRlVHlwZSIsICJab2REYXRlIiwgInN5bWJvbFR5cGUiLCAiWm9kU3ltYm9sIiwgInVuZGVmaW5lZFR5cGUiLCAiWm9kVW5kZWZpbmVkIiwgIm51bGxUeXBlIiwgIlpvZE51bGwiLCAiYW55VHlwZSIsICJab2RBbnkiLCAidW5rbm93blR5cGUiLCAiWm9kVW5rbm93biIsICJuZXZlclR5cGUiLCAiWm9kTmV2ZXIiLCAidm9pZFR5cGUiLCAiWm9kVm9pZCIsICJhcnJheVR5cGUiLCAiWm9kQXJyYXkiLCAib2JqZWN0VHlwZSIsICJab2RPYmplY3QiLCAic3RyaWN0T2JqZWN0VHlwZSIsICJ1bmlvblR5cGUiLCAiWm9kVW5pb24iLCAiZGlzY3JpbWluYXRlZFVuaW9uVHlwZSIsICJab2REaXNjcmltaW5hdGVkVW5pb24iLCAiaW50ZXJzZWN0aW9uVHlwZSIsICJab2RJbnRlcnNlY3Rpb24iLCAidHVwbGVUeXBlIiwgIlpvZFR1cGxlIiwgInJlY29yZFR5cGUiLCAiWm9kUmVjb3JkIiwgIm1hcFR5cGUiLCAiWm9kTWFwIiwgInNldFR5cGUiLCAiWm9kU2V0IiwgImZ1bmN0aW9uVHlwZSIsICJab2RGdW5jdGlvbiIsICJsYXp5VHlwZSIsICJab2RMYXp5IiwgImxpdGVyYWxUeXBlIiwgIlpvZExpdGVyYWwiLCAiZW51bVR5cGUiLCAiWm9kRW51bSIsICJuYXRpdmVFbnVtVHlwZSIsICJab2ROYXRpdmVFbnVtIiwgInByb21pc2VUeXBlIiwgIlpvZFByb21pc2UiLCAiZWZmZWN0c1R5cGUiLCAiWm9kRWZmZWN0cyIsICJvcHRpb25hbFR5cGUiLCAiWm9kT3B0aW9uYWwiLCAibnVsbGFibGVUeXBlIiwgIlpvZE51bGxhYmxlIiwgInByZXByb2Nlc3NUeXBlIiwgInBpcGVsaW5lVHlwZSIsICJab2RQaXBlbGluZSIsICJvc3RyaW5nIiwgIm9udW1iZXIiLCAib2Jvb2xlYW4iLCAiY29lcmNlIiwgImFyZyIsICJORVZFUiIsICJJTlZBTElEIiwgIkxBVEVTVF9QUk9UT0NPTF9WRVJTSU9OIiwgIlNVUFBPUlRFRF9QUk9UT0NPTF9WRVJTSU9OUyIsICJKU09OUlBDX1ZFUlNJT04iLCAiUHJvZ3Jlc3NUb2tlblNjaGVtYSIsICJleHRlcm5hbF9leHBvcnRzIiwgIkN1cnNvclNjaGVtYSIsICJCYXNlUmVxdWVzdFBhcmFtc1NjaGVtYSIsICJSZXF1ZXN0U2NoZW1hIiwgIkJhc2VOb3RpZmljYXRpb25QYXJhbXNTY2hlbWEiLCAiTm90aWZpY2F0aW9uU2NoZW1hIiwgIlJlc3VsdFNjaGVtYSIsICJSZXF1ZXN0SWRTY2hlbWEiLCAiSlNPTlJQQ1JlcXVlc3RTY2hlbWEiLCAiSlNPTlJQQ05vdGlmaWNhdGlvblNjaGVtYSIsICJKU09OUlBDUmVzcG9uc2VTY2hlbWEiLCAiRXJyb3JDb2RlIiwgIkpTT05SUENFcnJvclNjaGVtYSIsICJKU09OUlBDTWVzc2FnZVNjaGVtYSIsICJFbXB0eVJlc3VsdFNjaGVtYSIsICJDYW5jZWxsZWROb3RpZmljYXRpb25TY2hlbWEiLCAiSW1wbGVtZW50YXRpb25TY2hlbWEiLCAiQ2xpZW50Q2FwYWJpbGl0aWVzU2NoZW1hIiwgIkluaXRpYWxpemVSZXF1ZXN0U2NoZW1hIiwgIlNlcnZlckNhcGFiaWxpdGllc1NjaGVtYSIsICJJbml0aWFsaXplUmVzdWx0U2NoZW1hIiwgIkluaXRpYWxpemVkTm90aWZpY2F0aW9uU2NoZW1hIiwgIlBpbmdSZXF1ZXN0U2NoZW1hIiwgIlByb2dyZXNzU2NoZW1hIiwgIlByb2dyZXNzTm90aWZpY2F0aW9uU2NoZW1hIiwgIlBhZ2luYXRlZFJlcXVlc3RTY2hlbWEiLCAiUGFnaW5hdGVkUmVzdWx0U2NoZW1hIiwgIlJlc291cmNlQ29udGVudHNTY2hlbWEiLCAiVGV4dFJlc291cmNlQ29udGVudHNTY2hlbWEiLCAiQmxvYlJlc291cmNlQ29udGVudHNTY2hlbWEiLCAiUmVzb3VyY2VTY2hlbWEiLCAiUmVzb3VyY2VUZW1wbGF0ZVNjaGVtYSIsICJMaXN0UmVzb3VyY2VzUmVxdWVzdFNjaGVtYSIsICJMaXN0UmVzb3VyY2VzUmVzdWx0U2NoZW1hIiwgIkxpc3RSZXNvdXJjZVRlbXBsYXRlc1JlcXVlc3RTY2hlbWEiLCAiTGlzdFJlc291cmNlVGVtcGxhdGVzUmVzdWx0U2NoZW1hIiwgIlJlYWRSZXNvdXJjZVJlcXVlc3RTY2hlbWEiLCAiUmVhZFJlc291cmNlUmVzdWx0U2NoZW1hIiwgIlJlc291cmNlTGlzdENoYW5nZWROb3RpZmljYXRpb25TY2hlbWEiLCAiU3Vic2NyaWJlUmVxdWVzdFNjaGVtYSIsICJVbnN1YnNjcmliZVJlcXVlc3RTY2hlbWEiLCAiUmVzb3VyY2VVcGRhdGVkTm90aWZpY2F0aW9uU2NoZW1hIiwgIlByb21wdEFyZ3VtZW50U2NoZW1hIiwgIlByb21wdFNjaGVtYSIsICJMaXN0UHJvbXB0c1JlcXVlc3RTY2hlbWEiLCAiTGlzdFByb21wdHNSZXN1bHRTY2hlbWEiLCAiR2V0UHJvbXB0UmVxdWVzdFNjaGVtYSIsICJUZXh0Q29udGVudFNjaGVtYSIsICJJbWFnZUNvbnRlbnRTY2hlbWEiLCAiRW1iZWRkZWRSZXNvdXJjZVNjaGVtYSIsICJQcm9tcHRNZXNzYWdlU2NoZW1hIiwgIkdldFByb21wdFJlc3VsdFNjaGVtYSIsICJQcm9tcHRMaXN0Q2hhbmdlZE5vdGlmaWNhdGlvblNjaGVtYSIsICJUb29sU2NoZW1hIiwgIkxpc3RUb29sc1JlcXVlc3RTY2hlbWEiLCAiTGlzdFRvb2xzUmVzdWx0U2NoZW1hIiwgIkNhbGxUb29sUmVzdWx0U2NoZW1hIiwgIkNvbXBhdGliaWxpdHlDYWxsVG9vbFJlc3VsdFNjaGVtYSIsICJDYWxsVG9vbFJlcXVlc3RTY2hlbWEiLCAiVG9vbExpc3RDaGFuZ2VkTm90aWZpY2F0aW9uU2NoZW1hIiwgIkxvZ2dpbmdMZXZlbFNjaGVtYSIsICJTZXRMZXZlbFJlcXVlc3RTY2hlbWEiLCAiTG9nZ2luZ01lc3NhZ2VOb3RpZmljYXRpb25TY2hlbWEiLCAiTW9kZWxIaW50U2NoZW1hIiwgIk1vZGVsUHJlZmVyZW5jZXNTY2hlbWEiLCAiU2FtcGxpbmdNZXNzYWdlU2NoZW1hIiwgIkNyZWF0ZU1lc3NhZ2VSZXF1ZXN0U2NoZW1hIiwgIkNyZWF0ZU1lc3NhZ2VSZXN1bHRTY2hlbWEiLCAiUmVzb3VyY2VSZWZlcmVuY2VTY2hlbWEiLCAiUHJvbXB0UmVmZXJlbmNlU2NoZW1hIiwgIkNvbXBsZXRlUmVxdWVzdFNjaGVtYSIsICJDb21wbGV0ZVJlc3VsdFNjaGVtYSIsICJSb290U2NoZW1hIiwgIkxpc3RSb290c1JlcXVlc3RTY2hlbWEiLCAiTGlzdFJvb3RzUmVzdWx0U2NoZW1hIiwgIlJvb3RzTGlzdENoYW5nZWROb3RpZmljYXRpb25TY2hlbWEiLCAiQ2xpZW50UmVxdWVzdFNjaGVtYSIsICJDbGllbnROb3RpZmljYXRpb25TY2hlbWEiLCAiQ2xpZW50UmVzdWx0U2NoZW1hIiwgIlNlcnZlclJlcXVlc3RTY2hlbWEiLCAiU2VydmVyTm90aWZpY2F0aW9uU2NoZW1hIiwgIlNlcnZlclJlc3VsdFNjaGVtYSIsICJNY3BFcnJvciIsICJjb2RlIiwgIm1lc3NhZ2UiLCAiZGF0YSIsICJERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NU0VDIiwgIlByb3RvY29sIiwgIl9vcHRpb25zIiwgIkNhbmNlbGxlZE5vdGlmaWNhdGlvblNjaGVtYSIsICJub3RpZmljYXRpb24iLCAiY29udHJvbGxlciIsICJQcm9ncmVzc05vdGlmaWNhdGlvblNjaGVtYSIsICJQaW5nUmVxdWVzdFNjaGVtYSIsICJfcmVxdWVzdCIsICJ0cmFuc3BvcnQiLCAiZXJyb3IiLCAibWVzc2FnZSIsICJyZXNwb25zZUhhbmRsZXJzIiwgIl9hIiwgIk1jcEVycm9yIiwgIkVycm9yQ29kZSIsICJoYW5kbGVyIiwgInJlcXVlc3QiLCAiX2IiLCAiYWJvcnRDb250cm9sbGVyIiwgInJlc3VsdCIsICJwcm9ncmVzcyIsICJ0b3RhbCIsICJwcm9ncmVzc1Rva2VuIiwgInJlc3BvbnNlIiwgIm1lc3NhZ2VJZCIsICJyZXN1bHRTY2hlbWEiLCAib3B0aW9ucyIsICJyZXNvbHZlIiwgInJlamVjdCIsICJqc29ucnBjUmVxdWVzdCIsICJ0aW1lb3V0SWQiLCAiY2FuY2VsIiwgInJlYXNvbiIsICJfYyIsICJ0aW1lb3V0IiwgIl9kIiwgImpzb25ycGNOb3RpZmljYXRpb24iLCAicmVxdWVzdFNjaGVtYSIsICJtZXRob2QiLCAiZXh0cmEiLCAibm90aWZpY2F0aW9uU2NoZW1hIiwgIlNlcnZlciIsICJQcm90b2NvbCIsICJfc2VydmVySW5mbyIsICJvcHRpb25zIiwgIkluaXRpYWxpemVSZXF1ZXN0U2NoZW1hIiwgInJlcXVlc3QiLCAiSW5pdGlhbGl6ZWROb3RpZmljYXRpb25TY2hlbWEiLCAiX2EiLCAibWV0aG9kIiwgIl9iIiwgInJlcXVlc3RlZFZlcnNpb24iLCAiU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT05TIiwgIkxBVEVTVF9QUk9UT0NPTF9WRVJTSU9OIiwgIkVtcHR5UmVzdWx0U2NoZW1hIiwgInBhcmFtcyIsICJDcmVhdGVNZXNzYWdlUmVzdWx0U2NoZW1hIiwgIkxpc3RSb290c1Jlc3VsdFNjaGVtYSIsICJwcm9jZXNzIiwgIlJlYWRCdWZmZXIiLCAiY2h1bmsiLCAiaW5kZXgiLCAibGluZSIsICJkZXNlcmlhbGl6ZU1lc3NhZ2UiLCAiSlNPTlJQQ01lc3NhZ2VTY2hlbWEiLCAic2VyaWFsaXplTWVzc2FnZSIsICJtZXNzYWdlIiwgIlN0ZGlvU2VydmVyVHJhbnNwb3J0IiwgIl9zdGRpbiIsICJwcm9jZXNzIiwgIl9zdGRvdXQiLCAiUmVhZEJ1ZmZlciIsICJjaHVuayIsICJlcnJvciIsICJfYSIsICJtZXNzYWdlIiwgIl9iIiwgInJlc29sdmUiLCAianNvbiIsICJzZXJpYWxpemVNZXNzYWdlIiwgInRvb2xzX2V4cG9ydHMiLCAiX19leHBvcnQiLCAiZ2V0QWdlbnQiLCAiZ2V0RGVwbG95bWVudFN0YXR1cyIsICJsaXN0QWdlbnRzIiwgImxpc3RQcmltaXRpdmVWZXJzaW9ucyIsICJ0YWlsTG9ncyIsICJzcGF3biIsICJERUZBVUxUX1RJTUVPVVRfTVMiLCAicnVuTHVhIiwgImFyZ3MiLCAic3Bhd25GbiIsICJ0aW1lb3V0TXMiLCAibGFiZWwiLCAicmVzb2x2ZSIsICJyZWplY3QiLCAiY2hpbGQiLCAic3Rkb3V0IiwgInN0ZGVyciIsICJkIiwgInRpbWVyIiwgImNvZGUiLCAiZXJyIiwgImZsYXR0ZW5BZ2VudHMiLCAicGFyc2VkIiwgIm9iaiIsICJlbnRyaWVzIiwgIm9yZyIsICJhIiwgImxpc3RBZ2VudHNWaWFDbGkiLCAibGlzdEFnZW50cyIsICJfYXJncyIsICJkZXBzIiwgImNvbXBhY3QiLCAibGlzdEFnZW50c1ZpYUNsaSIsICJnZXRBZ2VudCIsICJhZ2VudElkIiwgImRlcHMiLCAibWF0Y2giLCAibGlzdEFnZW50c1ZpYUNsaSIsICJhIiwgInJlYWRGaWxlIiwgInJlYWRkaXIiLCAic3RhdCIsICJqb2luIiwgImRpcm5hbWUiLCAiaG9tZWRpciIsICJERUZBVUxUX0FQSV9VUkwiLCAiRklSRUJBU0VfUkVGUkVTSF9VUkwiLCAiUkVGUkVTSF9USU1FT1VUX01TIiwgIlJFRlJFU0hfU0tFV19NUyIsICJSRUpFQ1RFRF9SRUZSRVNIX1JFQVNPTlMiLCAidG9rZW5DYWNoZSIsICJwYXJzZURvdGVudkFwaUtleSIsICJjb250ZW50IiwgInJhd0xpbmUiLCAibSIsICJ2YWx1ZSIsICJxdW90ZWQiLCAiZmluZFNlc3Npb25GaWxlIiwgInNlc3Npb25zRGlyIiwgImFwaVVybCIsICJuYW1lcyIsICJyZWFkZGlyIiwgImNhbmRpZGF0ZXMiLCAibmFtZSIsICJwYXRoIiwgImpvaW4iLCAic2Vzc2lvbiIsICJyZWFkRmlsZSIsICJtdGltZU1zIiwgInN0YXQiLCAiYSIsICJiIiwgInJlZnJlc2hTZXNzaW9uQmVhcmVyIiwgImZldGNoRm4iLCAibm93IiwgImNhY2hlZCIsICJ0b2tlbkNhY2hlIiwgIlJFRlJFU0hfU0tFV19NUyIsICJjb250cm9sbGVyIiwgInRpbWVyIiwgIlJFRlJFU0hfVElNRU9VVF9NUyIsICJyZXMiLCAiRklSRUJBU0VfUkVGUkVTSF9VUkwiLCAiZXJyIiwgInJlYXNvbiIsICJtZXNzYWdlIiwgInJlamVjdGVkIiwgIlJFSkVDVEVEX1JFRlJFU0hfUkVBU09OUyIsICJyIiwgImJvZHkiLCAiaWRUb2tlbiIsICJleHBpcmVzSW4iLCAicmVzb2x2ZUFwaUtleSIsICJlbnYiLCAiY3JlZGVudGlhbHNQYXRoIiwgImhvbWVkaXIiLCAiZGlybmFtZSIsICJjd2QiLCAiREVGQVVMVF9BUElfVVJMIiwgImZyb21Eb3RlbnYiLCAiZm91bmQiLCAicmF3IiwgInBhcnNlZCIsICJERUZBVUxUX0JBU0VfVVJMIiwgIkRFRkFVTFRfVElNRU9VVF9NUyIsICJST1VURV9TQ09QRVMiLCAiUk9VVEVfU0NPUEVfU1VNTUFSWSIsICJhcGlSZXF1ZXN0IiwgInBhdGgiLCAibWV0aG9kIiwgImJvZHkiLCAicXVlcnkiLCAiZmV0Y2hGbiIsICJiYXNlVXJsIiwgInRpbWVvdXRNcyIsICJhcGlLZXkiLCAicmVzb2x2ZUFwaUtleSIsICJ1cmwiLCAiayIsICJ2IiwgImNvbnRyb2xsZXIiLCAidGltZXIiLCAicmVzIiwgInJhdyIsICJmcmllbmRseU1zZyIsICJwYXJzZWQiLCAiY29kZSIsICJlcnIiLCAiTElTVF9FWFRSQUNUT1JTIiwgIlZFUlNJT05TX0VYVFJBQ1RPUlMiLCAiTElTVF9QQVRIUyIsICJleHRyYWN0TGlzdCIsICJ0eXBlIiwgInJlc3BvbnNlIiwgImZuIiwgImV4dHJhY3RWZXJzaW9ucyIsICJleHRyYWN0QWN0aXZlVmVyc2lvbklkIiwgImlkIiwgImlzQWN0aXZlVmVyc2lvbiIsICJ2ZXJzaW9uIiwgImFjdGl2ZUlkIiwgIm93bklkIiwgInZlcnNpb25DcmVhdGVkQXQiLCAicmF3IiwgInZlcnNpb25JZCIsICJTVVBQT1JURURfTElTVF9UWVBFUyIsICJTVVBQT1JURURfVkVSU0lPTl9UWVBFUyIsICJWQUxJRF9UWVBFUyIsICJTVVBQT1JURURfVkVSU0lPTl9UWVBFUyIsICJsaXN0UHJpbWl0aXZlVmVyc2lvbnMiLCAiYWdlbnRJZCIsICJ0eXBlIiwgIm5hbWUiLCAiZGVwcyIsICJwYXRoIiwgImlkIiwgInJlc29sdmVOYW1lVG9JZCIsICJMSVNUX1BBVEhTIiwgImRhdGEiLCAiYXBpUmVxdWVzdCIsICJjb21wYWN0IiwgImV4dHJhY3RWZXJzaW9ucyIsICJ2IiwgInZlcnNpb25JZCIsICJpc0FjdGl2ZVZlcnNpb24iLCAidmVyc2lvbkNyZWF0ZWRBdCIsICJyZXN1bHQiLCAiZXh0cmFjdEFjdGl2ZVZlcnNpb25JZCIsICJmZXRjaEZuIiwgImxpc3RQYXRoIiwgImxpc3RSZXNwb25zZSIsICJpdGVtcyIsICJleHRyYWN0TGlzdCIsICJtYXRjaCIsICJwIiwgImF2YWlsYWJsZSIsICJQUklNSVRJVkVfVFlQRVMiLCAiVkVSU0lPTlNfQ0hVTktfU0laRSIsICJERUZBVUxUX0JVREdFVF9NUyIsICJnZXREZXBsb3ltZW50U3RhdHVzIiwgImFnZW50SWQiLCAiZGVwcyIsICJpZCIsICJidWRnZXRNcyIsICJzdGFydGVkQXQiLCAib3ZlckJ1ZGdldCIsICJnZXQiLCAicGF0aCIsICJhcGlSZXF1ZXN0IiwgInJlc3VsdCIsICJ0eXBlIiwgInBlcnNvbmFPdXRjb21lIiwgImxpc3RPdXRjb21lcyIsICJMSVNUX1BBVEhTIiwgInBlcnNvbmFSZXNwb25zZSIsICJ2ZXJzaW9ucyIsICJleHRyYWN0VmVyc2lvbnMiLCAiYWN0aXZlIiwgInYiLCAiaXNBY3RpdmVWZXJzaW9uIiwgInZlcnNpb25DcmVhdGVkQXQiLCAiYnVkZ2V0RXhoYXVzdGVkIiwgInNraXBwZWQiLCAidG90YWwiLCAidCIsICJvdXRjb21lIiwgInRhcmdldHMiLCAiZXh0cmFjdExpc3QiLCAicCIsICJ0Z3QiLCAiaSIsICJjaHVuayIsICJuYW1lIiwgInByaW1JZCIsICJ2byIsICJqIiwgInZlcnNpb25zUmVzcG9uc2UiLCAiZW50cnkiLCAidmVyc2lvbklkIiwgImV4dHJhY3RBY3RpdmVWZXJzaW9uSWQiLCAiTE9HX1NPVVJDRVMiLCAiTE9HX1RZUEVTIiwgIlZBTElEX1RZUEVTIiwgIlZBTElEX0xPR19UWVBFUyIsICJ0YWlsTG9ncyIsICJhZ2VudElkIiwgInR5cGUiLCAibmFtZSIsICJsb2dUeXBlIiwgImxpbWl0IiwgInBhZ2UiLCAiZGVwcyIsICJxdWVyeSIsICJkYXRhIiwgImFwaVJlcXVlc3QiLCAiVE9PTF9SRUdJU1RSWSIsICJ0b29sc19leHBvcnRzIiwgInNlcnZlciIsICJTZXJ2ZXIiLCAiTGlzdFRvb2xzUmVxdWVzdFNjaGVtYSIsICJ0IiwgIkNhbGxUb29sUmVxdWVzdFNjaGVtYSIsICJyZXEiLCAidG9vbCIsICJlcnIiLCAicmVwb3J0Q3Jhc2hBbmRFeGl0IiwgInBheWxvYWQiLCAicmVhc29uIiwgIlN0ZGlvU2VydmVyVHJhbnNwb3J0Il0KfQo= diff --git a/plugins/lua-agent-builder/mcp/lua-platform/package-lock.json b/plugins/lua-agent-builder/mcp/lua-platform/package-lock.json index b451b1f..0c554d3 100644 --- a/plugins/lua-agent-builder/mcp/lua-platform/package-lock.json +++ b/plugins/lua-agent-builder/mcp/lua-platform/package-lock.json @@ -1,12 +1,12 @@ { "name": "@lua/claude-plugin-mcp", - "version": "1.5.0", + "version": "1.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@lua/claude-plugin-mcp", - "version": "1.5.0", + "version": "1.6.0", "dependencies": { "@modelcontextprotocol/sdk": "~0.6.0" }, diff --git a/plugins/lua-agent-builder/mcp/lua-platform/package.json b/plugins/lua-agent-builder/mcp/lua-platform/package.json index 1250fb4..6ce4e91 100644 --- a/plugins/lua-agent-builder/mcp/lua-platform/package.json +++ b/plugins/lua-agent-builder/mcp/lua-platform/package.json @@ -1,6 +1,6 @@ { "name": "@lua/claude-plugin-mcp", - "version": "1.5.0", + "version": "1.6.0", "description": "Read-only MCP server for the lua-agent-builder Claude Code plugin", "type": "module", "main": "dist/server.js", diff --git a/plugins/lua-agent-builder/mcp/lua-platform/scripts/bundle.mjs b/plugins/lua-agent-builder/mcp/lua-platform/scripts/bundle.mjs index 8e3f200..c289f82 100644 --- a/plugins/lua-agent-builder/mcp/lua-platform/scripts/bundle.mjs +++ b/plugins/lua-agent-builder/mcp/lua-platform/scripts/bundle.mjs @@ -1,22 +1,70 @@ #!/usr/bin/env node import { build } from 'esbuild'; +import { readFileSync, readdirSync, writeFileSync, existsSync } from 'node:fs'; +import { join } from 'node:path'; -// Iteration-13 audit: removed `packages: 'bundle'` β€” that option only exists -// in esbuild β‰₯0.22 but the pinned dep is `^0.20.0` (would fail at build with -// `Invalid value "bundle" in "--packages=bundle"`). The MCP server has only -// one npm runtime dep (`@modelcontextprotocol/sdk`, marked external below) -// and node builtins (auto-external), so `bundle: true` alone correctly -// bundles every relative import without needing `packages: 'bundle'`. -await build({ +// EM-WS8 (1.6.0): EVERYTHING is bundled, `@modelcontextprotocol/sdk` included. +// The plugin ships no node_modules β€” marketplace installs copy the directory +// verbatim and the Lua Job tier bakes it into an image the same way β€” so an +// external SDK made the server die with ERR_MODULE_NOT_FOUND on every install +// (Claude Code shows it as `lua-platform CONNECTION_CLOSED`). +// tests/standalone-bundle.test.mjs copies dist/server.js into an empty temp +// directory and lists the tools over stdio to keep it that way. +// +// Iteration-13 audit: `packages: 'bundle'` is not used β€” that option only +// exists in esbuild >=0.22 and the pinned dep is `^0.20.0`; `bundle: true` +// with no `external` already bundles every npm import. Node builtins stay +// external automatically (`platform: 'node'`). +// +// The banner gives the ESM bundle a real `require`, so any CommonJS module +// the SDK pulls in can still `require()` a node builtin. +// +// Licences: the bundle redistributes third-party code, so the build also +// writes dist/THIRD_PARTY_NOTICES.txt β€” every npm package esbuild actually +// pulled in (from the metafile), with its version, licence and full licence +// text β€” and keeps any `/*! … */` legal comments at the end of the bundle. +const result = await build({ entryPoints: ['src/server.mjs'], bundle: true, platform: 'node', target: 'node18', format: 'esm', - external: ['@modelcontextprotocol/sdk'], + banner: { + js: "import { createRequire as __luaCreateRequire } from 'node:module'; const require = __luaCreateRequire(import.meta.url);", + }, minify: true, + legalComments: 'eof', + metafile: true, sourcemap: 'inline', outfile: 'dist/server.js', }); -console.log('βœ“ Bundled to dist/server.js'); +/** node_modules//… β†’ package directory, for every bundled input. */ +const packageDirs = new Set(); +for (const input of Object.keys(result.metafile.inputs)) { + const m = /^(.*?node_modules\/(?:@[^/]+\/)?[^/]+)\//.exec(input.replace(/\\/g, '/')); + if (m) packageDirs.add(m[1]); +} + +const LICENCE_FILE = /^(?:licen[cs]e|copying|notice)(?:[.-].*)?$/i; +const sections = [...packageDirs].sort().map((dir) => { + const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')); + const licence = typeof pkg.license === 'string' ? pkg.license : pkg.license?.type ?? 'UNKNOWN'; + const files = existsSync(dir) ? readdirSync(dir).filter((f) => LICENCE_FILE.test(f)).sort() : []; + const texts = files.map((f) => readFileSync(join(dir, f), 'utf8').trim()); + return [ + `${pkg.name}@${pkg.version} β€” ${licence}`, + pkg.repository ? `Source: ${typeof pkg.repository === 'string' ? pkg.repository : pkg.repository.url}` : null, + '', + texts.length ? texts.join('\n\n') : `(No licence file ships with the package; its package.json declares ${licence}.)`, + ].filter((l) => l !== null).join('\n'); +}); + +writeFileSync( + 'dist/THIRD_PARTY_NOTICES.txt', + 'Third-party software bundled into dist/server.js (@lua/claude-plugin-mcp).\n' + + 'Generated by scripts/bundle.mjs from the esbuild metafile; do not edit by hand.\n\n' + + sections.join('\n\n' + '-'.repeat(78) + '\n\n') + '\n', +); + +console.log(`βœ“ Bundled to dist/server.js (self-contained, no runtime node_modules needed); ${packageDirs.size} third-party package(s) listed in dist/THIRD_PARTY_NOTICES.txt`); diff --git a/plugins/lua-agent-builder/mcp/lua-platform/src/api-client.mjs b/plugins/lua-agent-builder/mcp/lua-platform/src/api-client.mjs index 4b8ba48..2bd9d1a 100644 --- a/plugins/lua-agent-builder/mcp/lua-platform/src/api-client.mjs +++ b/plugins/lua-agent-builder/mcp/lua-platform/src/api-client.mjs @@ -69,7 +69,7 @@ export async function apiRequest(path, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', - 'X-Lua-Client': 'claude-plugin/1.5.0', + 'X-Lua-Client': 'claude-plugin/1.6.0', }, body: body ? JSON.stringify(body) : undefined, signal: controller.signal, diff --git a/plugins/lua-agent-builder/mcp/lua-platform/src/server.mjs b/plugins/lua-agent-builder/mcp/lua-platform/src/server.mjs index 8f787dc..1673055 100644 --- a/plugins/lua-agent-builder/mcp/lua-platform/src/server.mjs +++ b/plugins/lua-agent-builder/mcp/lua-platform/src/server.mjs @@ -11,7 +11,7 @@ import * as tools from './tools/index.mjs'; const TOOL_REGISTRY = Object.values(tools); const server = new Server( - { name: 'lua-platform', version: '1.5.0' }, + { name: 'lua-platform', version: '1.6.0' }, { capabilities: { tools: {} } } ); @@ -46,7 +46,7 @@ process.on('uncaughtException', (err) => { kind: 'uncaughtException', message: err?.message, stack: err?.stack, - plugin_version: '1.5.0', + plugin_version: '1.6.0', lua_cli_version: process.env.LUA_CLI_VERSION ?? null, platform: process.platform, ts: new Date().toISOString(), @@ -59,7 +59,7 @@ process.on('unhandledRejection', (reason) => { kind: 'unhandledRejection', reason: String(reason), stack: /** @type {any} */ (reason)?.stack, - plugin_version: '1.5.0', + plugin_version: '1.6.0', lua_cli_version: process.env.LUA_CLI_VERSION ?? null, platform: process.platform, ts: new Date().toISOString(), diff --git a/plugins/lua-agent-builder/mcp/lua-platform/tests/standalone-bundle.test.mjs b/plugins/lua-agent-builder/mcp/lua-platform/tests/standalone-bundle.test.mjs new file mode 100644 index 0000000..725354c --- /dev/null +++ b/plugins/lua-agent-builder/mcp/lua-platform/tests/standalone-bundle.test.mjs @@ -0,0 +1,131 @@ +// EM-WS8: dist/server.js must run with NO node_modules anywhere above it. +// +// Marketplace installs copy the plugin verbatim β€” no `npm ci` runs β€” and the +// Lua Job tier bakes the plugin into an image the same way. Until 1.6.0 the +// bundle left `@modelcontextprotocol/sdk` external, so the server died with +// ERR_MODULE_NOT_FOUND on every such install (Claude Code reported it as +// `lua-platform CONNECTION_CLOSED`). +// +// The test copies the bundle into a fresh temp directory before spawning it. +// Spawning it in place would pass vacuously: Node resolves a bare import by +// walking up the parent directories, and CI has just run `npm ci` in +// mcp/lua-platform/, so the SDK would be found in ../node_modules. + +import { describe, test, expect, beforeAll, afterAll } from '@jest/globals'; +import { spawn } from 'node:child_process'; +import { copyFileSync, mkdirSync, mkdtempSync, readFileSync, rmSync, existsSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join, resolve, parse } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const PKG_DIR = resolve(__dirname, '..'); +const DIST = join(PKG_DIR, 'dist', 'server.js'); +const PKG_VERSION = JSON.parse(readFileSync(join(PKG_DIR, 'package.json'), 'utf8')).version; + +const EXPECTED_TOOLS = [ + 'get_agent', + 'get_deployment_status', + 'list_agents', + 'list_primitive_versions', + 'tail_logs', +]; + +/** True if any directory from `dir` up to the filesystem root has a node_modules. */ +function nodeModulesAbove(dir) { + let cur = dir; + const { root } = parse(cur); + for (;;) { + if (existsSync(join(cur, 'node_modules'))) return cur; + if (cur === root) return null; + cur = dirname(cur); + } +} + +/** + * Spawn `node ` with a scrubbed environment, send newline-delimited + * JSON-RPC requests, and resolve with every response keyed by id once the + * responses for all `waitFor` ids arrived (or reject on exit/timeout). + */ +function rpcSession(file, cwd, messages, waitFor) { + return new Promise((resolveP, reject) => { + const env = { ...process.env, LUA_API_KEY: 'test', LUA_CREDENTIALS_PATH: '/nonexistent' }; + delete env.NODE_PATH; + delete env.NODE_OPTIONS; + const child = spawn(process.execPath, [file], { cwd, env, shell: false, windowsHide: true }); + const responses = new Map(); + let buf = ''; + let stderr = ''; + const finish = (err) => { + clearTimeout(timer); + child.kill(); + if (err) reject(err); else resolveP(responses); + }; + const timer = setTimeout( + () => finish(new Error(`timed out; got ids ${[...responses.keys()]}; stderr=${stderr}`)), + 10_000, + ); + child.stdout.on('data', (d) => { + buf += d.toString('utf8'); + let nl; + while ((nl = buf.indexOf('\n')) >= 0) { + const line = buf.slice(0, nl).trim(); + buf = buf.slice(nl + 1); + if (!line) continue; + const msg = JSON.parse(line); + if (msg.id !== undefined) responses.set(msg.id, msg); + } + if (waitFor.every((id) => responses.has(id))) finish(); + }); + child.stderr.on('data', (d) => { stderr += d.toString('utf8'); }); + child.on('exit', (code) => finish(new Error(`server exited ${code} before replying: ${stderr}`))); + child.on('error', finish); + for (const m of messages) child.stdin.write(JSON.stringify(m) + '\n'); + }); +} + +describe('dist/server.js runs standalone (no node_modules)', () => { + let tmp; + let copied; + + beforeAll(() => { + // Mirror the shipped layout: package.json (its `"type": "module"` makes + // Node 18/20 load dist/server.js as ESM) next to dist/server.js β€” and + // nothing else, in particular no node_modules. + tmp = mkdtempSync(join(tmpdir(), 'lua-mcp-standalone-')); + mkdirSync(join(tmp, 'dist')); + copyFileSync(join(PKG_DIR, 'package.json'), join(tmp, 'package.json')); + copied = join(tmp, 'dist', 'server.js'); + copyFileSync(DIST, copied); + }); + afterAll(() => { rmSync(tmp, { recursive: true, force: true }); }); + + test('the isolation is real: no node_modules above the copied bundle', () => { + expect(nodeModulesAbove(tmp)).toBeNull(); + }); + + test('initialize + tools/list answer with the five read-only tools', async () => { + const responses = await rpcSession(copied, tmp, [ + { + jsonrpc: '2.0', id: 1, method: 'initialize', + params: { + protocolVersion: '2024-11-05', + capabilities: {}, + clientInfo: { name: 'standalone-test', version: '0.0.0' }, + }, + }, + { jsonrpc: '2.0', method: 'notifications/initialized' }, + { jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} }, + ], [1, 2]); + + const init = responses.get(1); + expect(init.error).toBeUndefined(); + expect(init.result.serverInfo.name).toBe('lua-platform'); + // Catches a version bump that forgot to rebuild dist/. + expect(init.result.serverInfo.version).toBe(PKG_VERSION); + + const list = responses.get(2); + expect(list.error).toBeUndefined(); + expect(list.result.tools.map((t) => t.name).sort()).toEqual(EXPECTED_TOOLS); + }); +}); diff --git a/plugins/lua-agent-builder/package-lock.json b/plugins/lua-agent-builder/package-lock.json index 7b31cf7..ef1ed28 100644 --- a/plugins/lua-agent-builder/package-lock.json +++ b/plugins/lua-agent-builder/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-code-lua-plugin", - "version": "1.5.0", + "version": "1.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-code-lua-plugin", - "version": "1.5.0", + "version": "1.6.0", "devDependencies": { "@types/node": "^20.11.0", "eslint": "^8.57.0", diff --git a/plugins/lua-agent-builder/package.json b/plugins/lua-agent-builder/package.json index 2614d5d..7c2a07e 100644 --- a/plugins/lua-agent-builder/package.json +++ b/plugins/lua-agent-builder/package.json @@ -1,6 +1,6 @@ { "name": "claude-code-lua-plugin", - "version": "1.5.0", + "version": "1.6.0", "description": "Plugin assets for the lua-agent-builder Claude Code plugin", "private": true, "type": "module", diff --git a/plugins/lua-agent-builder/test/hooks/confirm-deploy.integration.test.mjs b/plugins/lua-agent-builder/test/hooks/confirm-deploy.integration.test.mjs index ed05fe8..de128cb 100644 --- a/plugins/lua-agent-builder/test/hooks/confirm-deploy.integration.test.mjs +++ b/plugins/lua-agent-builder/test/hooks/confirm-deploy.integration.test.mjs @@ -25,6 +25,26 @@ describe('confirm-deploy script entry (spawned)', () => { expect(result.stderr).toContain('Use /lua-deploy'); }); + // EM-WS8: the Job-tier audit's chain bypasses, end to end. + test.each([ + 'cd agent && lua deploy all --force', + 'true; lua version promote 3', + 'FOO=1 lua deploy all', + 'npx lua-cli deploy all', + 'export LUA_DEPLOY_CONFIRMED=1; lua deploy all', + ])('exits 2 on the chained / launched form %s', async (command) => { + const result = await runHook('confirm-deploy.mjs', { tool_input: { command } }, { env: { LUA_PLUGIN_HEADLESS: '' } }); + expect(result.exitCode).toBe(2); + expect(result.stderr).toContain('DEPLOY_DENIED_BARE'); + }); + + test('exits 0 when the prefix sits on the simple command that deploys', async () => { + const result = await runHook('confirm-deploy.mjs', { + tool_input: { command: 'cd agent && LUA_DEPLOY_CONFIRMED=1 lua deploy skill --ci --force' }, + }, { env: { LUA_PLUGIN_HEADLESS: '' } }); + expect(result.exitCode).toBe(0); + }); + test('exits 2 with DEPLOY_DENIED_AUTO on --auto-deploy', async () => { const result = await runHook('confirm-deploy.mjs', { tool_input: { command: 'LUA_DEPLOY_CONFIRMED=1 lua deploy --auto-deploy' }, diff --git a/plugins/lua-agent-builder/test/hooks/confirm-deploy.timeout.test.mjs b/plugins/lua-agent-builder/test/hooks/confirm-deploy.timeout.test.mjs new file mode 100644 index 0000000..4f49a6e --- /dev/null +++ b/plugins/lua-agent-builder/test/hooks/confirm-deploy.timeout.test.mjs @@ -0,0 +1,49 @@ +// EM-WS8 review finding 1: a PreToolUse hook that is killed by its timeout +// (10 s in hooks.json) fails OPEN β€” the command runs. The independent review +// reproduced exactly that with 24 KB inputs against an earlier draft. This +// test spawns the REAL hook script, as Claude Code does, on adversarial inputs +// up to 100 KB and asserts it DECIDES (exit 2 / exit 0, never a signal) well +// inside the timeout. + +import { describe, test, expect } from '@jest/globals'; +import { runHook } from '../helpers/run-hook.mjs'; +import { MAX_COMMAND_LENGTH } from '../../lib/tokenizer.mjs'; + +const LIMIT_MS = 2_000; +const KB = 1024; +const fill = (unit, bytes) => unit.repeat(Math.ceil(bytes / unit.length)); + +// [name, command, expected exit code] +const CASES = [ + // The review's reproductions, at their size and at 100 KB. + ['opaque lua/ run, 24 KB', 'lua deploy all; echo ' + fill('lua/', 24 * KB) + " '", 2], + ['inline-code lua/ run, 16 KB', 'node -e "' + fill('lua/', 16 * KB) + '"; lua deploy all', 2], + ['lua words, 60 KB', 'echo ' + fill('lua ', 60 * KB) + '; lua deploy all', 2], + ['opaque lua/ run, 100 KB', 'lua deploy all; echo ' + fill('lua/', 100 * KB) + " '", 2], + ['inline-code lua/ run, 100 KB', 'node -e "' + fill('lua/', 100 * KB) + '"; lua deploy all', 2], + ['lua words, 100 KB', 'echo ' + fill('lua ', 100 * KB) + '; lua deploy all', 2], + ['options, 100 KB', 'lua ' + fill('--a ', 100 * KB) + 'x "', 2], + ['nested substitutions, 100 KB', fill('$(', 50 * KB) + 'lua deploy all' + fill(')', 50 * KB), 2], + ['heredocs, 100 KB', fill('cat < { + test.each(CASES)('%s', async (_name, command, expectedExit) => { + const t0 = Date.now(); + const result = await runHook( + 'confirm-deploy.mjs', + { tool_input: { command } }, + { timeoutMs: 10_000, env: { LUA_PLUGIN_HEADLESS: '' } }, + ); + const elapsed = Date.now() - t0; + expect({ exitCode: result.exitCode, fast: elapsed < LIMIT_MS }).toEqual({ exitCode: expectedExit, fast: true }); + }, 15_000); +}); diff --git a/plugins/lua-agent-builder/test/hooks/headless.test.mjs b/plugins/lua-agent-builder/test/hooks/headless.test.mjs new file mode 100644 index 0000000..296c4dc --- /dev/null +++ b/plugins/lua-agent-builder/test/hooks/headless.test.mjs @@ -0,0 +1,183 @@ +// EM-WS8 (1.6.0): LUA_PLUGIN_HEADLESS=1 β€” the hooks in an unattended run +// (`claude -p` in the Lua Job tier). Two invariants: +// 1. no message a hook injects or returns points at a slash command β€” the +// slashes need AskUserQuestion or the Agent tool, unavailable headless; +// 2. nothing that is blocked interactively is allowed headless, and the +// LUA_DEPLOY_CONFIRMED=1 prefix is void (the model would confirm to itself). + +import { describe, test, expect, beforeAll, afterAll } from '@jest/globals'; +import { mkdtempSync, writeFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { isHeadless, HEADLESS_NOTE } from '../../lib/headless.mjs'; +import { decide as confirmDeploy } from '../../hooks/confirm-deploy.mjs'; +import { decide as blockAutoDeploy } from '../../hooks/block-auto-deploy.mjs'; +import { decide as checkAuth } from '../../hooks/check-lua-auth.mjs'; +import { decide as checkVersion, PINNED_MIN_LUA_CLI } from '../../hooks/check-lua-version.mjs'; +import { decide as detectProject } from '../../hooks/detect-project.mjs'; +import { decide as postDeploySmoke } from '../../hooks/post-deploy-smoke.mjs'; +import { runHook } from '../helpers/run-hook.mjs'; + +const HEADLESS = { LUA_PLUGIN_HEADLESS: '1' }; +const INTERACTIVE = {}; +const SLASH = /\/lua-[a-z]/; +const versionOK = { exitCode: 0, stdout: `${PINNED_MIN_LUA_CLI}\n`, stderr: '' }; + +describe('isHeadless()', () => { + test.each([ + ['1', true], ['true', true], ['TRUE', true], [' yes ', true], ['on', true], + ['0', false], ['false', false], ['', false], [undefined, false], ['headless', false], + ])('LUA_PLUGIN_HEADLESS=%p β†’ %p', (value, expected) => { + expect(isHeadless({ LUA_PLUGIN_HEADLESS: value })).toBe(expected); + }); + + test('defaults to process.env and tolerates a missing env', () => { + expect(typeof isHeadless()).toBe('boolean'); + expect(isHeadless(undefined)).toBe(isHeadless(process.env)); + expect(isHeadless(null)).toBe(false); + }); + + test('the shared note names no slash command', () => { + expect(HEADLESS_NOTE).not.toMatch(SLASH); + }); +}); + +describe('check-lua-auth headless: a neutral note, never "run /lua-auth"', () => { + test.each([ + [{ exitCode: 9, stdout: '', stderr: 'βœ– auth' }, 'exited 9'], + [{ exitCode: 1, stdout: '', stderr: 'boom' }, 'exited 1'], + [{ exitCode: 11, stdout: '', stderr: 'βœ– unavailable' }, 'exited 11'], + [{ exitCode: 403, stdout: '', stderr: 'proxy: route not allowed' }, 'exited 403'], + [{ exitCode: null, stdout: '', stderr: '', timedOut: true }, 'did not answer'], + ])('%p', (authResult, outcome) => { + const result = checkAuth(versionOK, authResult, HEADLESS); + expect(result?.warn).toContain('could not be confirmed'); + expect(result?.warn).toContain(outcome); + expect(result?.warn).toContain('proxy'); + expect(result?.warn).not.toMatch(SLASH); + expect(result?.warn).not.toContain('not authenticated'); + }); + + test('success stays silent headless too', () => { + expect(checkAuth(versionOK, { exitCode: 0, stdout: '{}', stderr: '' }, HEADLESS)).toBeNull(); + expect(checkAuth(versionOK, { exitCode: 10, stdout: '', stderr: '' }, HEADLESS)).toBeNull(); + expect(checkAuth({ exitCode: -1, stdout: '', stderr: '' }, { exitCode: -1 }, HEADLESS)).toBeNull(); + }); + + test('interactive keeps recommending /lua-auth', () => { + expect(checkAuth(versionOK, { exitCode: 9, stdout: '', stderr: '' }, INTERACTIVE)?.warn).toContain('/lua-auth'); + }); +}); + +describe('check-lua-version headless: same findings, no /lua-doctor, /lua-update or npm install', () => { + test.each([ + [{ exitCode: -1, stdout: '', stderr: 'ENOENT' }, 'Could not detect lua-cli'], + [{ exitCode: 0, stdout: 'garbage', stderr: '' }, "Couldn't parse"], + [{ exitCode: 0, stdout: '1.0.0', stderr: '' }, 'older than'], + ])('%p', (versionResult, finding) => { + const warn = checkVersion(versionResult, HEADLESS)?.warn; + expect(warn).toContain(finding); + expect(warn).not.toMatch(SLASH); + expect(warn).not.toContain('npm i'); + expect(warn).toContain('headless'); + }); + + test('interactive text is unchanged', () => { + expect(checkVersion({ exitCode: -1, stdout: '' }, INTERACTIVE)?.warn).toBe('Could not detect lua-cli version. Run /lua-doctor to install.'); + expect(checkVersion({ exitCode: 0, stdout: 'garbage' }, INTERACTIVE)?.warn).toContain('Run /lua-doctor.'); + expect(checkVersion({ exitCode: 0, stdout: '1.0.0' }, INTERACTIVE)?.warn).toContain('/lua-update'); + expect(checkVersion(versionOK, HEADLESS)).toBeNull(); + }); +}); + +describe('detect-project headless', () => { + let dir; + beforeAll(() => { + dir = mkdtempSync(join(tmpdir(), 'lua-headless-')); + writeFileSync(join(dir, 'lua.skill.yaml'), 'agent:\n agentId: agent_123\n'); + }); + afterAll(() => rmSync(dir, { recursive: true, force: true })); + + test('reports the project without pointing at /lua-doctor', () => { + expect(detectProject(null, { cwd: dir, env: HEADLESS })).toEqual({ warn: 'βœ“ Lua agent project detected: agent_123.' }); + }); + + test('interactive keeps the pointer', () => { + expect(detectProject(null, { cwd: dir, env: INTERACTIVE })?.warn).toContain('/lua-doctor'); + }); +}); + +describe('confirm-deploy headless: every production verb blocked, the prefix is void', () => { + test.each([ + 'lua deploy all --force', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy skill --ci --name x --set-version latest --force', + 'env LUA_DEPLOY_CONFIRMED=1 lua version promote 3', + 'LUA_DEPLOY_CONFIRMED=1 lua marketplace template apply --template-id t --all-installed --force', + 'cd x && npx lua-cli workflows activate outreach', + ])('%s', (command) => { + const result = confirmDeploy({ tool_input: { command } }, HEADLESS); + expect(result?.block).toBe(true); + expect(result?.reason).toContain('DEPLOY_DENIED_HEADLESS'); + expect(result?.reason).not.toMatch(SLASH); + }); + + test('the same prefixed command is allowed interactively', () => { + expect(confirmDeploy({ tool_input: { command: 'LUA_DEPLOY_CONFIRMED=1 lua version promote 3' } }, INTERACTIVE)).toBeNull(); + }); + + test('--auto-deploy is blocked headless without a slash pointer', () => { + const result = confirmDeploy({ tool_input: { command: 'lua push skill --ci --force --auto-deploy' } }, HEADLESS); + expect(result?.block).toBe(true); + expect(result?.reason).toContain('DEPLOY_DENIED_AUTO'); + expect(result?.reason).not.toMatch(SLASH); + }); + + test('non-production commands pass headless', () => { + for (const command of ['lua push all --ci --force', 'lua version create --ci -m "x"', 'lua compile --ci', 'git status']) { + expect(confirmDeploy({ tool_input: { command } }, HEADLESS)).toBeNull(); + } + }); + + test('spawned with LUA_PLUGIN_HEADLESS=1, a prefixed deploy exits 2', async () => { + const result = await runHook( + 'confirm-deploy.mjs', + { tool_input: { command: 'LUA_DEPLOY_CONFIRMED=1 lua deploy skill --ci --force' } }, + { env: HEADLESS }, + ); + expect(result.exitCode).toBe(2); + expect(result.stderr).toContain('DEPLOY_DENIED_HEADLESS'); + }); +}); + +describe('confirm-deploy: an unclassifiable command', () => { + test('is blocked with its own reason, interactive and headless alike', () => { + const command = `lua status ${'x'.repeat(40 * 1024)}`; + const interactive = confirmDeploy({ tool_input: { command } }, INTERACTIVE); + expect(interactive?.block).toBe(true); + expect(interactive?.reason).toContain('DEPLOY_DENIED_UNCLASSIFIABLE'); + expect(interactive?.reason).not.toMatch(SLASH); + expect(confirmDeploy({ tool_input: { command } }, HEADLESS)?.block).toBe(true); + }); +}); + +describe('block-auto-deploy headless', () => { + test('still blocks, names no slash', () => { + const result = blockAutoDeploy({ tool_input: { command: 'lua push all --auto-deploy' } }, HEADLESS); + expect(result?.block).toBe(true); + expect(result?.reason).not.toMatch(SLASH); + }); + + test('interactive keeps /lua-deploy', () => { + expect(blockAutoDeploy({ tool_input: { command: 'lua push all --auto-deploy' } }, INTERACTIVE)?.reason).toContain('/lua-deploy'); + }); +}); + +describe('post-deploy-smoke headless', () => { + test('never spawns the production ping', async () => { + const spawnLuaFn = async () => { throw new Error('must not spawn headless'); }; + await expect(postDeploySmoke( + { tool_input: { command: 'LUA_DEPLOY_CONFIRMED=1 lua version promote 3' }, tool_response: { success: true } }, + { spawnLuaFn, env: HEADLESS }, + )).resolves.toBeNull(); + }); +}); diff --git a/plugins/lua-agent-builder/test/lib/tokenizer-hardening.test.mjs b/plugins/lua-agent-builder/test/lib/tokenizer-hardening.test.mjs new file mode 100644 index 0000000..d3d4d60 --- /dev/null +++ b/plugins/lua-agent-builder/test/lib/tokenizer-hardening.test.mjs @@ -0,0 +1,586 @@ +// EM-WS8 (1.6.0): the confirm-deploy parser bypasses from the Job-tier audit +// (finding 3; `lib/tokenizer.mjs:81-96` in 1.5.0) and the shell shapes that +// neighbour them. Every case here PASSED the 1.5.0 regex classifier. + +import { describe, test, expect } from '@jest/globals'; +import { + classifyProductionCommand, isPrefixedDeploy, lex, UNRESOLVED_LABEL, UNCLASSIFIABLE_LABEL, MAX_COMMAND_LENGTH, TIME_BUDGET_MS, +} from '../../lib/tokenizer.mjs'; + +const bare = (label, slash = '/lua-deploy') => ({ label, slash, prefixed: false }); +const DEPLOY = bare('lua deploy'); +const PROMOTE = bare('lua version promote'); + +describe('the five bypasses named in the Job-tier audit', () => { + test.each([ + ['cd x && lua deploy all --force', DEPLOY], + ['true; lua version promote 3', PROMOTE], + ['FOO=1 lua deploy all', DEPLOY], + ['/usr/local/bin/lua deploy all', DEPLOY], + ['npx lua deploy all', DEPLOY], + ])('%s is classified and not prefixed', (cmd, expected) => { + expect(classifyProductionCommand(cmd)).toEqual(expected); + }); +}); + +describe('verbs anywhere in a command chain', () => { + test.each([ + 'false || lua deploy all', + 'lua compile --ci && lua deploy all', + 'lua compile --ci\nlua deploy all', + 'lua compile --ci & lua deploy all', + 'lua compile --ci; lua deploy all', + '(lua deploy all)', + '(cd agent && lua deploy all)', + '{ lua deploy all; }', + 'if true; then lua deploy all; fi', + 'for i in 1; do lua deploy all; done', + '! lua deploy all', + 'lua status |& lua deploy all', + 'f() { lua deploy all; }; f', + 'case x in x) lua deploy all;; esac', + ])('%s', (cmd) => { + expect(classifyProductionCommand(cmd)).toEqual(DEPLOY); + }); +}); + +describe('env-assignment prefixes, wrappers and binary paths', () => { + test.each([ + 'FOO=1 BAR=2 lua deploy all', + 'env FOO=1 lua deploy all', + 'env -i PATH=/usr/bin lua deploy all', + 'command lua deploy all', + 'exec lua deploy all', + 'nohup lua deploy all', + 'time lua deploy all', + 'timeout 60 lua deploy all', + 'sudo -u deployer lua deploy all', + './node_modules/.bin/lua deploy all', + '~/.npm-global/bin/heylua deploy all', + '"C:\\Users\\me\\AppData\\Roaming\\npm\\lua.cmd" deploy all', + 'C:/Users/me/AppData/Roaming/npm/lua.cmd deploy all', + '"lua" deploy all', + "'lua' deploy all", + 'l\\ua deploy all', + 'lu""a deploy all', + ])('%s', (cmd) => { + expect(classifyProductionCommand(cmd)).toEqual(DEPLOY); + }); +}); + +describe('package runners and node entry points', () => { + test.each([ + 'npx lua deploy all', + 'npx lua-cli deploy all', + 'npx -y lua-cli@3.38.0 deploy all', + 'npx --yes lua-cli@latest deploy all', + 'npx -p lua-cli lua deploy all', + 'pnpm exec lua deploy all', + 'pnpm dlx lua-cli deploy all', + 'pnpx lua-cli deploy all', + 'yarn lua deploy all', + 'yarn dlx lua-cli deploy all', + 'npm exec -- lua deploy all', + 'npm x lua-cli -- deploy all', + 'bunx lua-cli deploy all', + 'node /x/lua deploy all', + 'node ./node_modules/.bin/lua deploy all', + 'node node_modules/lua-cli/dist/index.js deploy all', + 'node --no-warnings -r dotenv/config /usr/lib/node_modules/lua-cli/dist/index.js deploy all', + 'node /opt/heylua/dist/index.js deploy all', + '/opt/lua-cli/dist/index.js deploy all', + ])('%s', (cmd) => { + expect(classifyProductionCommand(cmd)).toEqual(DEPLOY); + }); + + test('`lua-cli` alone at the head is not an installed binary (unchanged from 1.5.0)', () => { + expect(classifyProductionCommand('lua-cli deploy')).toBeNull(); + }); + + test('node running some other script is not lua', () => { + expect(classifyProductionCommand('node scripts/build.mjs deploy all')).toBeNull(); + expect(classifyProductionCommand('node --version')).toBeNull(); + }); +}); + +describe('options between the binary and the verb', () => { + test.each([ + ['lua --ci deploy all', 'lua deploy'], + ['lua workflows -v 3 deploy outreach', 'lua workflows deploy'], + ['lua workflows --version=3 deploy outreach', 'lua workflows deploy'], + ['lua persona --force production deploy --persona-version 5', 'lua persona production deploy'], + ['lua version --json promote 3', 'lua version promote'], + ])('%s β†’ %s', (cmd, label) => { + expect(classifyProductionCommand(cmd)?.label).toBe(label); + }); +}); + +describe('aliases the 1.5.0 table missed', () => { + test.each([ + ['lua marketplace templates publish --template-id t', 'lua marketplace template publish'], + ['lua marketplace agent-template submit --template-id t', 'lua marketplace template publish'], + ['lua marketplace agent-templates rollout --template-id t', 'lua marketplace template apply'], + ['lua workflows DEPLOY outreach -v 2', 'lua workflows deploy'], + ['lua mcp ON fs', 'lua mcp activate'], + ['lua persona LIVE Publish --persona-version 5', 'lua persona production deploy'], + ])('%s β†’ %s', (cmd, label) => { + expect(classifyProductionCommand(cmd)?.label).toBe(label); + expect(classifyProductionCommand(`LUA_DEPLOY_CONFIRMED=1 ${cmd}`)?.prefixed).toBe(true); + }); +}); + +describe('substitutions and strings run by another shell', () => { + test.each([ + 'echo $(lua deploy all)', + 'echo "$(lua deploy all)"', + 'echo `lua deploy all`', + 'echo "`lua deploy all`"', + 'lua chat --ci -e sandbox -m "$(lua version promote 3)" -t t1', + 'diff <(lua deploy all) /dev/null', + 'tee >(lua deploy all) < /dev/null', + 'bash -c "lua deploy all"', + "sh -lc 'lua deploy all'", + 'zsh -c "cd x && lua deploy all"', + '/bin/bash -c "lua deploy all"', + 'eval "lua deploy all"', + 'eval lua deploy all', + 'ssh prod-box "lua deploy all"', + 'watch -n 5 "lua deploy all"', + 'npx -c "lua deploy all"', + 'printf "lua deploy all" | sh', + 'echo "lua deploy all" | bash -s', + 'bash < { + const c = classifyProductionCommand(cmd); + expect(c).not.toBeNull(); + expect(c.prefixed).toBe(false); + }); + + test('inline interpreter code is searched as text', () => { + for (const cmd of [ + "node -e \"require('child_process').execSync('lua deploy all')\"", + "python3 -c \"import os; os.system('lua version promote 3')\"", + "perl -e 'system(\"lua deploy all\")'", + 'python3 < { + for (const cmd of [ + 'bash -c "LUA_DEPLOY_CONFIRMED=1 lua deploy skill"', + 'echo $(LUA_DEPLOY_CONFIRMED=1 lua deploy skill)', + '(LUA_DEPLOY_CONFIRMED=1 lua deploy skill)', + '{ LUA_DEPLOY_CONFIRMED=1 lua deploy skill; }', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy skill | tee log', + 'echo y | LUA_DEPLOY_CONFIRMED=1 lua deploy skill', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy skill |& cat', + ]) { + expect({ cmd, prefixed: isPrefixedDeploy(cmd) }).toEqual({ cmd, prefixed: false }); + expect(classifyProductionCommand(cmd)).not.toBeNull(); + } + }); +}); + +describe('shell variables in the binary or verb position (cannot be resolved β†’ blocked)', () => { + test.each([ + ['L=lua; $L deploy all', 'lua deploy'], + ['"$LUA_BIN" version promote 3', 'lua version promote'], + ['$(which lua) deploy all', 'lua deploy'], + ['env $LUA deploy all', 'lua deploy'], + ["$'\\x6cua' deploy all", 'lua deploy'], + ['lua $VERB all', UNRESOLVED_LABEL], + ['lua "$VERB" all', UNRESOLVED_LABEL], + ['lua workflows $ACTION outreach', UNRESOLVED_LABEL], + ['lua ${CMD} all', UNRESOLVED_LABEL], + ])('%s β†’ %s', (cmd, label) => { + expect(classifyProductionCommand(cmd)).toEqual({ label, slash: '/lua-deploy', prefixed: false }); + }); + + test('a prefixed command with a variable verb is still blocked', () => { + expect(isPrefixedDeploy('LUA_DEPLOY_CONFIRMED=1 lua $VERB all')).toBe(false); + }); + + test('a variable that is not in command position is just an argument', () => { + expect(classifyProductionCommand('echo $HOME deploy all')).toBeNull(); + expect(classifyProductionCommand('lua test --ci skill --name $SKILL')).toBeNull(); + expect(classifyProductionCommand('lua chat --ci -e sandbox -m "$MSG" -t t1')).toBeNull(); + }); +}); + +describe('LUA_DEPLOY_CONFIRMED=1 counts only on the same simple command', () => { + test.each([ + 'export LUA_DEPLOY_CONFIRMED=1; lua deploy all', + 'export LUA_DEPLOY_CONFIRMED=1 && lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1 true && lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1; lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy skill; lua version promote 3', + 'LUA_DEPLOY_CONFIRMED=1 lua compile --ci && lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1 npx lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1 /usr/local/bin/lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1 node node_modules/lua-cli/dist/index.js deploy all', + 'FOO=1 LUA_DEPLOY_CONFIRMED=1 lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1 FOO=1 lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1 env lua deploy all', + '"LUA_DEPLOY_CONFIRMED=1" lua deploy all', + 'sudo LUA_DEPLOY_CONFIRMED=1 lua deploy all', + 'if LUA_DEPLOY_CONFIRMED=1 lua deploy all; then :; fi', + ])('blocks %s', (cmd) => { + expect(isPrefixedDeploy(cmd)).toBe(false); + expect(classifyProductionCommand(cmd)?.prefixed).toBe(false); + }); + + test.each([ + 'cd agent && LUA_DEPLOY_CONFIRMED=1 lua deploy skill --ci --name x --set-version latest --force', + 'lua compile --ci && LUA_DEPLOY_CONFIRMED=1 lua deploy all --ci --force', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy skill --ci --force && LUA_DEPLOY_CONFIRMED=1 lua deploy webhook --ci --force', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy skill --ci --name x --set-version 1 --force > deploy.log 2>&1', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all --ci --force 2>/dev/null', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all --ci --force &> deploy.log', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all --ci --force # ship it', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all \\\n --ci --force', + 'LUA_DEPLOY_CONFIRMED=1 lua marketplace template publish --template-id t --changelog "fix: a; b && c" --yes', + "LUA_DEPLOY_CONFIRMED=1 lua workflows deploy outreach -v 'latest'", + 'LUA_DEPLOY_CONFIRMED=1 heylua version promote 3', + 'env LUA_DEPLOY_CONFIRMED=1 lua-ai mcp activate fs', + ])('allows %s', (cmd) => { + expect(isPrefixedDeploy(cmd)).toBe(true); + }); +}); + +describe('false-positive guards: text that only MENTIONS a verb', () => { + test.each([ + 'git commit -m "lua deploy all"', + "git commit -m 'chore: document lua version promote 3'", + "echo 'lua version promote 3'", + 'grep -r "lua deploy" .', + 'grep -rn "lua workflows activate" commands/', + 'lua push skill --ci --force && lua compile --ci', + 'lua chat --ci -e production -m "please lua deploy all" -t t1', + 'gh pr create --title "x" --body "run lua deploy all after merge"', + 'cat > notes.md < notes.md\nlua version promote 3\nEOF", + 'lua deployment', + 'lua workflows status deploy', + 'lua workflows deactivate outreach', + 'lua test --ci skill --name deploy', + 'lua logs --ci --type all --json 2>&1 | head -20', + 'arr=(lua deploy all); echo ok', + 'git log --oneline -5 # lua deploy all', + 'echo "\\"lua deploy\\" is gated"', + 'echo "cost: $5" && lua status --json --ci', + ])('%s', (cmd) => { + expect(classifyProductionCommand(cmd)).toBeNull(); + }); +}); + +describe('input the lexer cannot close falls back to a textual search (fail closed)', () => { + test.each([ + 'bash -c "lua deploy all', + "echo 'unterminated && lua deploy all", + 'echo $(lua deploy all', + 'echo `lua deploy all', + 'echo "`lua deploy all', + "echo $'lua deploy all", + 'arr=(lua deploy all', + 'lua-cli/dist/index.js --ci deploy all "', + ])('%s', (cmd) => { + expect(classifyProductionCommand(cmd)?.prefixed).toBe(false); + }); + + test('deeply nested shells stop recursing and search the rest as text', () => { + let cmd = 'lua deploy all'; + for (let k = 0; k < 10; k++) cmd = `eval ${JSON.stringify(cmd)}`; + expect(classifyProductionCommand(cmd)?.prefixed).toBe(false); + }); +}); + +describe('the classifier stays fast and fails closed (a hook that times out or throws fails OPEN)', () => { + // Before the fix, 28 options made the textual fallback backtrack for ~200 s. + test.each([ + ['inline code', 'node -e 1 "lua ' + '--a '.repeat(40) + 'zz"; lua deploy all', 'lua deploy'], + ['opaque input', 'lua ' + '--a '.repeat(40) + 'zz "', null], + ['opaque input with values', 'lua ' + '--a=1 '.repeat(40) + 'zz "', null], + ['opaque input that deploys', 'lua ' + '--a=1 '.repeat(40) + 'deploy all "', 'lua deploy'], + ['long chains', 'lua status --ci && '.repeat(400) + 'lua deploy all', 'lua deploy'], + ['deep substitutions', 'echo '.concat('$('.repeat(50), 'lua deploy all', ')'.repeat(50)), 'lua deploy'], + ])('%s', (_name, cmd, label) => { + const t0 = performance.now(); + const result = classifyProductionCommand(cmd); + expect(performance.now() - t0).toBeLessThan(500); + expect(result?.label ?? null).toBe(label); + }); + + test('random shell soup never throws and never takes long', () => { + const parts = ['"', "'", '\\', '$', '(', ')', '`', '|', '&', ';', '<', '>', '{', '}', '\n', ' ', '#', '=', + 'lua deploy all', 'lua', 'deploy', '--ci', '< { seed = (seed * 1103515245 + 12345) % 2 ** 31; return seed % n; }; + const t0 = performance.now(); + for (let k = 0; k < 3000; k++) { + let cmd = ''; + for (let p = rand(30); p > 0; p--) cmd += parts[rand(parts.length)]; + expect(() => classifyProductionCommand(cmd)).not.toThrow(); + } + expect(performance.now() - t0).toBeLessThan(10_000); + }); + + test('an internal error blocks a command that mentions lua, and ignores one that does not', () => { + const boom = () => { throw new Error('classifier bug'); }; + expect(classifyProductionCommand('lua status', { analyze: boom })) + .toEqual({ label: UNCLASSIFIABLE_LABEL, slash: '/lua-deploy', prefixed: false }); + expect(classifyProductionCommand('git status', { analyze: boom })).toBeNull(); + }); + + test('a spent time budget fails closed', () => { + const cmd = 'lua status --ci && '.repeat(2000) + 'lua status'; + expect(classifyProductionCommand(cmd, { budgetMs: -1 })) + .toEqual({ label: UNCLASSIFIABLE_LABEL, slash: '/lua-deploy', prefixed: false }); + expect(classifyProductionCommand(cmd.replace(/lua/g, 'git'), { budgetMs: -1 })).toBeNull(); + // The budget is per call: the next call starts fresh. + expect(classifyProductionCommand('lua status --ci')).toBeNull(); + }); + + test(`a command over ${MAX_COMMAND_LENGTH} bytes is blocked if it mentions lua, passed if not`, () => { + const pad = 'x'.repeat(MAX_COMMAND_LENGTH); + expect(classifyProductionCommand(`lua status ${pad}`)) + .toEqual({ label: UNCLASSIFIABLE_LABEL, slash: '/lua-deploy', prefixed: false }); + expect(classifyProductionCommand(`git status ${pad}`)).toBeNull(); + }); + + // The reviewer's performance probe: every shape decides within budget. + test.each([ + ['opts-unclosed', 'lua ' + '--a '.repeat(5000) + 'x "'], + ['opts-unclosed-mixed', 'lua ' + '-a=b --c-d '.repeat(2500) + "'"], + ['many-lua-unclosed', 'lua lua-cli/x '.repeat(2000) + "'"], + ['many-lua-words', 'lua '.repeat(7000) + 'x'], + ['nested-subs', '$('.repeat(3000) + 'lua deploy all' + ')'.repeat(3000)], + ['nested-unclosed', '$('.repeat(15000)], + ['nested-quotes-subs', '"$('.repeat(3000) + 'x' + ')"'.repeat(3000)], + ['many-subs', '$(true) '.repeat(4000)], + ['many-backticks-unclosed', '`' + ' $( '.repeat(7000)], + ['open-parens', '('.repeat(30000)], + ['findclose-quad', '$( '.repeat(5000) + "'"], + ['dq-subs-unclosed', '"' + '$( '.repeat(5000)], + ['backtick-dq', '"' + '`x` '.repeat(7000)], + ['heredocs', 'cat < { + const t0 = performance.now(); + expect(() => classifyProductionCommand(cmd)).not.toThrow(); + expect(performance.now() - t0).toBeLessThan(TIME_BUDGET_MS + 250); + }); +}); + +// The independent review's probe sets (bypass.json / fp.json), verbatim. +describe('review probes: bypasses are blocked', () => { + test.each([ + '{lua,} deploy all', + 'lua de{ploy,} all', + 'lua {deploy,} all', + '/usr/local/bin/lu? deploy all', + '/usr/local/bin/l*a deploy all', + 'lua${IFS}deploy${IFS}all', + '$(printf lua) $(printf deploy) all', + 'L=lua; V=deploy; $L $V all', + 'env -S "lua deploy all"', + 'env --split-string="lua deploy all"', + 'tmux new -d "lua deploy all"', + 'awk \'BEGIN{system("lua deploy all")}\'', + 'gawk \'BEGIN{print "x" | "lua deploy all"}\'', + "osascript -e 'do shell script \"lua deploy all\"'", + "git -c alias.x='!lua deploy all' x", + "vim -c '!lua deploy all' -c q", + "sed -n '1e lua deploy all' /etc/hosts", + "sed 's/x/lua deploy all/e' f", + 'lua\tdeploy all', + "find . -maxdepth 0 -exec sh -c 'lua deploy all' \\;", + 'find . -maxdepth 0 -exec lua deploy all \\;', + 'xargs -a <(echo deploy all) lua', + 'echo deploy all | xargs -I{} lua {}', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all\nlua version promote 3', + 'L\\UA_DEPLOY_CONFIRMED=1 lua deploy all', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all & lua version promote 3', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all || lua mcp on x', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all <<< "$(lua version promote 3)"', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all\\\n; lua version promote 3', + 'lua Deploy all', + 'LUA deploy all', + 'Lua.exe deploy all', + "ruby -e 'system %q(lua deploy all)'", + "parallel ::: 'lua deploy all'", + 'watch -n1 lua deploy all', + 'coproc lua deploy all', + 'case x in x) lua deploy all;; esac', + 'function f { lua deploy all; }; f', + "x=$'\\x6cua'; $x deploy all", + "$'\\x6cua' deploy all", + "lua $'\\x64eploy' all", + 'lua "$(echo deploy)" all', + "printf '%s' 'lua deploy all' | bash", + 'echo lua deploy all | sh', + "bash <<< 'lua deploy all'", + 'bash < <(echo lua deploy all)', + 'source <(echo lua deploy all)', + 'lua --profile=x -- deploy all', + 'npx --yes lua-cli@latest deploy all', + 'npm x lua-cli deploy all', + 'node --require=x ./node_modules/lua-cli/dist/index.js deploy all', + 'node --no-warnings --stack-size 999 ./node_modules/lua-cli/dist/index.js deploy all', + 'node --stack-size 999 ./node_modules/lua-cli/dist/index.js deploy all', + 'lua marketplace templates rollout x', + 'lua persona live publish', + "cat > x.sh <<'EOF'\nlua deploy all\nEOF\nsh x.sh", + "cat > x.sh <<'EOF'\nlua deploy all\nEOF\n./x.sh", + 'cat < { + const c = classifyProductionCommand(cmd); + expect(c).not.toBeNull(); + expect(c.prefixed).toBe(false); + }); + + test('not bypasses: a comment, and command names lua-cli does not have', () => { + expect(classifyProductionCommand('LUA_DEPLOY_CONFIRMED=1 lua deploy all # ; lua version promote 3')?.prefixed).toBe(true); + expect(classifyProductionCommand('lua workflow deploy x -v 1')).toBeNull(); + expect(classifyProductionCommand('lua skill deploy')).toBeNull(); + }); +}); + +describe('review probes: interactive commands are not blocked', () => { + test.each([ + 'lua compile --ci', + "lua test skill --name x --input '{}' --ci", + 'lua chat --ci -e sandbox -m "please deploy all the things" -t abc', + 'lua chat --ci -e production -m "lua deploy all" -t abc', + 'lua push all --ci --force', + 'lua push skill --name deploy --ci', + 'lua logs --ci --json --type deploy', + 'lua logs --ci --json --since 1h | jq \'.[] | select(.msg|test("deploy"))\'', + 'lua status --json --ci', + 'lua version list', + 'lua version create -m "before deploy"', + 'lua workflows list', + 'lua env production --list', + "git commit -m \"$(cat <<'EOF'\nfix: don't run lua deploy all bare (it's gated)\n\nCo-Authored-By: x\nEOF\n)\"", + "git commit -m \"$(cat <<'EOF'\nfeat(deploy): support lua version promote (see docs)\nEOF\n)\"", + "gh pr create --title x --body \"$(cat <<'EOF'\n## Summary\n- blocks `lua deploy all` bare\n- it's fine :)\nEOF\n)\"", + "git log --oneline | grep 'lua deploy'", + 'grep -rn "lua deploy" docs/', + "rg 'lua version promote' .", + "cat > notes.md <<'EOF'\nRun lua deploy all after review\nEOF", + 'npm test && npm run lint', + 'npm run deploy', + 'cp -r lua deploy', + 'ls lua deploy', + 'echo lua deploy all', + 'cd lua && npm install', + 'node scripts/check.mjs "lua deploy all"', + "python3 -c 'print(1)' && echo done", + 'echo "Next: lua deploy all"', + "echo 'Next: lua deploy all'", + "printf 'lua deploy all\\n' >> TODO.md", + "sed -i '' 's/lua deploy all/LUA_DEPLOY_CONFIRMED=1 lua deploy all/' README.md", + "awk '/lua deploy/ {print}' notes.md", + ])('%j', (cmd) => { + expect(classifyProductionCommand(cmd)).toBeNull(); + }); + + test.each([ + 'LUA_DEPLOY_CONFIRMED=1 lua deploy skill --name x --skill-version 3 --ci --force', + 'LUA_DEPLOY_CONFIRMED=1 lua version promote 4 --ci', + 'env LUA_DEPLOY_CONFIRMED=1 lua mcp activate x --ci', + 'cd agent && LUA_DEPLOY_CONFIRMED=1 lua deploy all --ci --force', + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all --ci --force && lua status --json --ci', + ])('the confirmed form is allowed: %j', (cmd) => { + expect(isPrefixedDeploy(cmd)).toBe(true); + }); + + test.each([ + 'LUA_DEPLOY_CONFIRMED=1 lua deploy all --ci --force 2>&1 | tail -20', + 'LUA_DEPLOY_CONFIRMED=1 npx lua deploy all', + ])('by design a pipe or launcher voids the prefix: %j', (cmd) => { + expect(classifyProductionCommand(cmd)?.prefixed).toBe(false); + }); +}); + +describe('lex()', () => { + test('splits a chain into simple commands and marks pipelines and groups', () => { + const { segments, subs, opaque } = lex('a 1 && (b 2 | c 3); d "x y" 2>&1 > out'); + expect(opaque).toBe(false); + expect(subs).toEqual([]); + expect(segments.map((s) => s.words.map((w) => w.text))).toEqual([['a', '1'], ['b', '2'], ['c', '3'], ['d', 'x y']]); + expect(segments.map((s) => s.pipeline)).toEqual([false, true, true, false]); + expect(segments.map((s) => s.grouped)).toEqual([false, true, true, false]); + }); + + test('collects substitutions, heredocs and here-strings', () => { + const { segments, subs } = lex('x $(y) `z` <(w) <<< "h s"\ncat < { + const { segments } = lex('cat < { + const { segments } = lex('a "q\\"x\\\\y\\z" $"loc" b\\ c 3< in # c\n <> rw x >| y'); + expect(segments[0].words.map((w) => w.text)).toEqual(['a', 'q"x\\y\\z', 'loc', 'b c']); + expect(segments[1].words.map((w) => w.text)).toEqual(['x']); + }); + + test('double-quoted line continuation and a trailing escape', () => { + const { segments } = lex('a "x\\\ny" b\\'); + expect(segments[0].words.map((w) => w.text)).toEqual(['a', 'xy', 'b']); + }); + + test('an empty pipe stage still marks the pipeline', () => { + const { segments } = lex('a || b | | c'); + expect(segments.map((s) => s.pipeline)).toEqual([false, true, true]); + }); + + test('a substitution body keeps its quoted parentheses', () => { + expect(lex('echo $(printf \'a)\' "b)\\")" \\) x)').subs).toEqual(['printf \'a)\' "b)\\")" \\) x']); + expect(lex("echo $(printf 'a").opaque).toBe(true); + expect(lex('echo $(printf "a').opaque).toBe(true); + }); + + test('an unmatched ")" and a lone "$" do not throw', () => { + expect(lex('a ) b $').segments.map((s) => s.words.map((w) => w.text))).toEqual([['a'], ['b', '$']]); + }); +});