dsh-client-auto-continue 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -62
- package/README.zh.md +7 -61
- package/lib/client.js +1 -2
- package/lib/client.js.map +7 -0
- package/package.json +2 -1
- package/scripts/patch-expose.mjs +92 -0
package/README.md
CHANGED
|
@@ -100,15 +100,19 @@ dsh web
|
|
|
100
100
|
|
|
101
101
|
> **Known DSH limitation (0.1.0-rc.6):** the web plugin-configuration section only
|
|
102
102
|
> exposes settings namespaces on a hardcoded allowlist in the installed
|
|
103
|
-
> `@deepseek-ai/dsh-host-apiproxy` bundle.
|
|
104
|
-
>
|
|
103
|
+
> `@deepseek-ai/dsh-host-apiproxy` bundle. Until upstream moves exposure into
|
|
104
|
+
> `settings.register()`, one idempotent vendor patch is required for the
|
|
105
|
+
> settings card to appear (re-run it after reinstalling dsh):
|
|
105
106
|
>
|
|
106
107
|
> ```sh
|
|
107
|
-
> node scripts/patch-expose.mjs
|
|
108
|
+
> node node_modules/dsh-client-auto-continue/scripts/patch-expose.mjs
|
|
108
109
|
> dsh web
|
|
109
110
|
> ```
|
|
110
111
|
>
|
|
111
|
-
> The
|
|
112
|
+
> The patch script ships inside the npm package (no repo clone needed) and
|
|
113
|
+
> covers every reachable dsh installation: the profile-linked copy, a global
|
|
114
|
+
> `npm i -g @deepseek-ai/dsh` install, and the invoking directory's own. The
|
|
115
|
+
> auto-continue engine itself works without this patch — it only gates the
|
|
112
116
|
> GUI settings card.
|
|
113
117
|
|
|
114
118
|
### Verify & uninstall
|
|
@@ -146,36 +150,6 @@ Everything is configurable from the GUI — no file or console edits needed. Ope
|
|
|
146
150
|
|
|
147
151
|
---
|
|
148
152
|
|
|
149
|
-
## Tech Stack & Structure
|
|
150
|
-
|
|
151
|
-
| Layer | Choice |
|
|
152
|
-
| --- | --- |
|
|
153
|
-
| Platform | DSH Web GUI client plugin (browser half + host half registering the settings namespace) |
|
|
154
|
-
| Language | TypeScript |
|
|
155
|
-
| Build | esbuild (browser bundle + node half) + tsc declarations |
|
|
156
|
-
| Runtime deps | Browser bundle: `react` (platform seed) + `createSnapshotStore` (module table); host half: `schemastery` + `dsh-settings` (resolved from the dsh installation) |
|
|
157
|
-
|
|
158
|
-
```
|
|
159
|
-
dsh-auto-continue/
|
|
160
|
-
├── package.json # plugin manifest (dsh.client / dsh.bundle)
|
|
161
|
-
├── cordis.patch.yml # profile patch layer: registers the plugin row
|
|
162
|
-
├── build.mjs # esbuild build (browser bundle + node half)
|
|
163
|
-
├── tsconfig.json / tsconfig.build.json
|
|
164
|
-
├── src/
|
|
165
|
-
│ ├── index.ts # host half: registers the auto-continue settings namespace
|
|
166
|
-
│ └── client/
|
|
167
|
-
│ ├── index.ts # browser half entry: engine + settings card wiring
|
|
168
|
-
│ ├── engine.ts # the auto-continue engine (reads the settings scope)
|
|
169
|
-
│ ├── settings-card.tsx / settings-form.ts / locales.ts / styles.ts
|
|
170
|
-
│ └── # settings card UI (staged form, zh/en copy, theme styles)
|
|
171
|
-
├── tests/simulate.mjs # headless behavioral tests (mock API + settings scope)
|
|
172
|
-
├── lib/ # build output (committed, ready to link)
|
|
173
|
-
├── docs/ # banner artwork (en + zh)
|
|
174
|
-
└── README.md / README.zh.md / LICENSE
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
153
|
## Development
|
|
180
154
|
|
|
181
155
|
```bash
|
|
@@ -189,36 +163,8 @@ While `npm run watch` runs, the profile's client-hmr row polls `lib/client.js` e
|
|
|
189
163
|
|
|
190
164
|
---
|
|
191
165
|
|
|
192
|
-
|
|
193
|
-
## Publishing
|
|
194
|
-
|
|
195
|
-
Tagging `v<version>` (matching `package.json`) triggers the publish workflow:
|
|
196
|
-
|
|
197
|
-
```bash
|
|
198
|
-
git tag v0.2.0
|
|
199
|
-
git push origin v0.2.0
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
The CI (`.github/workflows/publish.yml`) then:
|
|
203
|
-
|
|
204
|
-
1. Verifies the tag matches `package.json` version
|
|
205
|
-
2. Installs dependencies, builds (`npm run build`) and runs the test suite
|
|
206
|
-
3. Publishes the package to npm (`dsh-client-auto-continue`)
|
|
207
|
-
4. Creates a GitHub Release with the packed tarball and built artifacts
|
|
208
|
-
(`lib/client.js`, `lib/client.js.map`, `lib/index.js`) attached
|
|
209
|
-
|
|
210
|
-
The workflow requires the `NPM_TOKEN` repository secret (an npm automation
|
|
211
|
-
token with publish scope):
|
|
212
|
-
|
|
213
|
-
```bash
|
|
214
|
-
gh secret set NPM_TOKEN --repo HsiangNianian/dsh-auto-continue
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
166
|
## Links
|
|
220
167
|
|
|
221
|
-
|
|
222
168
|
- **Repository**: [github.com/HsiangNianian/dsh-auto-continue](https://github.com/HsiangNianian/dsh-auto-continue)
|
|
223
169
|
- **DeepSeek Harness**: [github.com/deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
224
170
|
|
package/README.zh.md
CHANGED
|
@@ -99,15 +99,18 @@ dsh web
|
|
|
99
99
|
> 从手动安装切换到 `dsh plugin add` 时, 请先删掉手动加的 `insert` 条目——包自带的 bundle patch 会注册插件行, 重复注册会冲突。
|
|
100
100
|
|
|
101
101
|
> **已知 DSH 限制(0.1.0-rc.6):** webui 的插件配置区只暴露已安装
|
|
102
|
-
> `@deepseek-ai/dsh-host-apiproxy`
|
|
103
|
-
>
|
|
102
|
+
> `@deepseek-ai/dsh-host-apiproxy` 包中硬编码白名单里的设置命名空间。在官方把暴露
|
|
103
|
+
> 逻辑移入 `settings.register()` 之前, 要让设置卡片显示出来, 需要执行一次幂等的
|
|
104
|
+
> 供应商补丁(重新安装 dsh 后重跑一次即可):
|
|
104
105
|
>
|
|
105
106
|
> ```sh
|
|
106
|
-
> node scripts/patch-expose.mjs
|
|
107
|
+
> node node_modules/dsh-client-auto-continue/scripts/patch-expose.mjs
|
|
107
108
|
> dsh web
|
|
108
109
|
> ```
|
|
109
110
|
>
|
|
110
|
-
>
|
|
111
|
+
> 补丁脚本随 npm 包一起发布(无需克隆仓库), 并覆盖所有可达的 dsh 安装: profile
|
|
112
|
+
> 链接副本、全局 `npm i -g @deepseek-ai/dsh` 安装、以及当前目录的安装。自动续跑
|
|
113
|
+
> 引擎本身不依赖这个补丁——它只影响 GUI 设置卡片是否可见。
|
|
111
114
|
|
|
112
115
|
### 验证与卸载
|
|
113
116
|
|
|
@@ -144,36 +147,6 @@ dsh web
|
|
|
144
147
|
|
|
145
148
|
---
|
|
146
149
|
|
|
147
|
-
## 技术栈与结构
|
|
148
|
-
|
|
149
|
-
| 分层 | 选型 |
|
|
150
|
-
| --- | --- |
|
|
151
|
-
| 平台 | DSH Web GUI 客户端插件(浏览器半区 + 注册设置命名空间的宿主半区) |
|
|
152
|
-
| 语言 | TypeScript |
|
|
153
|
-
| 构建 | esbuild(浏览器包 + 宿主半区)+ tsc 声明文件 |
|
|
154
|
-
| 运行时依赖 | 浏览器包: `react`(平台种子)+ `createSnapshotStore`(模块表); 宿主半区: `schemastery` + `dsh-settings`(由 dsh 安装解析) |
|
|
155
|
-
|
|
156
|
-
```
|
|
157
|
-
dsh-auto-continue/
|
|
158
|
-
├── package.json # 插件清单(dsh.client / dsh.bundle)
|
|
159
|
-
├── cordis.patch.yml # profile 补丁层: 注册插件行
|
|
160
|
-
├── build.mjs # esbuild 构建(浏览器包 + 宿主半区)
|
|
161
|
-
├── tsconfig.json / tsconfig.build.json
|
|
162
|
-
├── src/
|
|
163
|
-
│ ├── index.ts # host 半区: 注册 auto-continue 设置命名空间
|
|
164
|
-
│ └── client/
|
|
165
|
-
│ ├── index.ts # browser 半区入口: 引擎 + 设置卡片接线
|
|
166
|
-
│ ├── engine.ts # 自动续跑引擎(读取设置作用域)
|
|
167
|
-
│ ├── settings-card.tsx / settings-form.ts / locales.ts / styles.ts
|
|
168
|
-
│ └── # 设置卡片 UI(暂存表单、中英文案、主题样式)
|
|
169
|
-
├── tests/simulate.mjs # 无头行为测试(模拟 API + 设置作用域)
|
|
170
|
-
├── lib/ # 构建产物(已提交, 可直接链接)
|
|
171
|
-
├── docs/ # banner 图(英文 + 中文)
|
|
172
|
-
└── README.md / README.zh.md / LICENSE
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
---
|
|
176
|
-
|
|
177
150
|
## 开发
|
|
178
151
|
|
|
179
152
|
```bash
|
|
@@ -187,35 +160,8 @@ npm run test # node tests/simulate.mjs — 8 个行为场景
|
|
|
187
160
|
|
|
188
161
|
---
|
|
189
162
|
|
|
190
|
-
|
|
191
|
-
## 发布
|
|
192
|
-
|
|
193
|
-
打一个与 `package.json` 版本一致的 `v<version>` tag, 即可触发发布流水线:
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
git tag v0.2.0
|
|
197
|
-
git push origin v0.2.0
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
CI(`.github/workflows/publish.yml`)会依次:
|
|
201
|
-
|
|
202
|
-
1. 校验 tag 与 `package.json` 版本一致
|
|
203
|
-
2. 安装依赖、构建(`npm run build`)并跑测试套件
|
|
204
|
-
3. 发布到 npm(`dsh-client-auto-continue`)
|
|
205
|
-
4. 创建 GitHub Release, 附带打包好的 tarball 与构建产物
|
|
206
|
-
(`lib/client.js`、`lib/client.js.map`、`lib/index.js`)
|
|
207
|
-
|
|
208
|
-
流水线依赖仓库的 `NPM_TOKEN` secret(带 publish 权限的 npm automation token):
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
gh secret set NPM_TOKEN --repo HsiangNianian/dsh-auto-continue
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
163
|
## 链接
|
|
217
164
|
|
|
218
|
-
|
|
219
165
|
- **仓库**: [github.com/HsiangNianian/dsh-auto-continue](https://github.com/HsiangNianian/dsh-auto-continue)
|
|
220
166
|
- **DeepSeek Harness**: [github.com/deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
221
167
|
|
package/lib/client.js
CHANGED
|
@@ -1190,8 +1190,7 @@ function apply(ctx) {
|
|
|
1190
1190
|
)
|
|
1191
1191
|
);
|
|
1192
1192
|
}
|
|
1193
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2NsaWVudC9pbmRleC50cyIsICJzcmMvY2xpZW50L2VuZ2luZS50cyIsICJzcmMvY2xpZW50L2xvY2FsZXMudHMiLCAic3JjL2NsaWVudC9zZXR0aW5ncy1jYXJkLnRzeCIsICJzcmMvY2xpZW50L3NldHRpbmdzLWZvcm0udHMiLCAic3JjL2NsaWVudC9zdHlsZXMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQXV0by1jb250aW51ZSBwbHVnaW4sIGJyb3dzZXIgaGFsZi5cbiAqXG4gKiAtIFJ1bnMgdGhlIGF1dG8tY29udGludWUgZW5naW5lIG92ZXIgdGhlIGxpdmUgbXV4ICsgaG9zdCBldmVudCBzdHJlYW1zLlxuICogLSBSZWdpc3RlcnMgdGhlIGBhdXRvLWNvbnRpbnVlYCBzZXR0aW5ncyBjYXJkIGludG8gdGhlIHBsdWdpbi1jb25maWd1cmF0aW9uXG4gKiAgIHNlY3Rpb24gKGBzZXR0aW5ncy5wbHVnaW4uaXRlbWApLCBlZGl0aW5nIHRoZSBzYW1lIG5hbWVzcGFjZSB0aGUgZW5naW5lXG4gKiAgIHJlYWRzIOKAlCBldmVyeSBiZWhhdmlvciBrbm9iIGlzIGNvbmZpZ3VyYWJsZSBmcm9tIHRoZSBHVUkuXG4gKi9cbmltcG9ydCB0eXBlIHsgQ2xpZW50Q29udGV4dCB9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LXJ1bnRpbWUvY2xpZW50JztcbmltcG9ydCB0eXBlIHsgQ29ubmVjdGlvbkhhbmRsZSB9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LWNvbm5lY3Rpb24vY2xpZW50Jztcbi8vIFR5cGUtb25seTogcHVsbHMgdGhlIGxvY2FsZSBwbHVnaW4ncyBDb250ZXh0IG1lcmdlIChjdHgubG9jYWxlKS5cbmltcG9ydCB0eXBlIHt9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LWxvY2FsZS9jbGllbnQnO1xuLy8gVHlwZS1vbmx5OiBwdWxscyB0aGUgc2V0dGluZ3Mtc3VyZmFjZSBTbG90TWFwIG1lcmdlIGFuZCBjdHguc2V0dGluZ3NTY29wZS5cbmltcG9ydCB0eXBlIHt9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LXVpLXNldHRpbmdzL2NsaWVudCc7XG4vLyBUeXBlLW9ubHk6IHB1bGxzIHRoZSBgc2V0dGluZ3MucGx1Z2luLml0ZW1gIFNsb3RNYXAgbWVyZ2UuXG5pbXBvcnQgdHlwZSB7fSBmcm9tICdAZGVlcHNlZWstYWkvZHNoLWNsaWVudC11aS1zZXR0aW5ncy1wbHVnaW5zL2NsaWVudCc7XG5pbXBvcnQgeyBBdXRvQ29udGludWVSdW5uZXIsIHJlc29sdmVDb25maWcsIHR5cGUgQXV0b0NvbnRpbnVlU2V0dGluZ3MgfSBmcm9tICcuL2VuZ2luZS50cyc7XG5pbXBvcnQgeyBlbiwgemgsIHR5cGUgU2V0dGluZ3NDYXJkS2V5IH0gZnJvbSAnLi9sb2NhbGVzLnRzJztcbmltcG9ydCB7XG4gIEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZCxcbiAgQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkQ29udHJvbGxlcixcbn0gZnJvbSAnLi9zZXR0aW5ncy1jYXJkLnRzeCc7XG5cbi8qKiDlrqLmiLfnq6/moLnkuIrkuIvmlofnmoQgY29ubmVjdGlvbiDmnI3liqEo55SxIGRzaC1jbGllbnQtY29ubmVjdGlvbiDmjILovb0p44CCICovXG5kZWNsYXJlIG1vZHVsZSAnQGRlZXBzZWVrLWFpL2NvcmRpcycge1xuICBpbnRlcmZhY2UgQ29udGV4dCB7XG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbkhhbmRsZTtcbiAgfVxufVxuXG4vKiogRGljdGlvbmFyeSBuYW1lc3BhY2Ugb3duZWQgYnkgdGhpcyBwbHVnaW4uICovXG5jb25zdCBOUyA9ICdhdXRvLWNvbnRpbnVlJztcblxuLyoqIFNldHRpbmdzIG5hbWVzcGFjZSB0aGUgZW5naW5lIHJlYWRzIGFuZCB0aGUgc2V0dGluZ3MgY2FyZCBlZGl0cy4gKi9cbmNvbnN0IFNFVFRJTkdTX05TID0gJ2F1dG8tY29udGludWUnO1xuXG5kZWNsYXJlIG1vZHVsZSAnQGRlZXBzZWVrLWFpL2RzaC1jbGllbnQtdWktc2xvdHMnIHtcbiAgaW50ZXJmYWNlIExvY2FsZU5hbWVzcGFjZU1hcCB7XG4gICAgLyoqIGF1dG8tY29udGludWUgc2V0dGluZ3MtY2FyZCBjb3B5LiAqL1xuICAgICdhdXRvLWNvbnRpbnVlJzogU2V0dGluZ3NDYXJkS2V5O1xuICB9XG59XG5cbi8qKiBTZXJ2aWNlcyByZXF1aXJlZCBieSB0aGlzIHBsdWdpbi4gKi9cbmV4cG9ydCBjb25zdCBpbmplY3QgPSBbJ3Nsb3RzJywgJ2xvY2FsZScsICdjb25uZWN0aW9uJywgJ3NldHRpbmdzU2NvcGUnXTtcblxuLyoqIOW9k+WJjSBydW5uZXIoSE1SIOmHjei9veaXtuWFiOmUgOavgeaXp+eahOWGjeW7uuaWsOeahCnjgIIgKi9cbmxldCBjdXJyZW50OiBBdXRvQ29udGludWVSdW5uZXIgfCBudWxsID0gbnVsbDtcblxuLyoqXG4gKiBQbHVnaW4gYm9keTogbW91bnQgdGhlIGVuZ2luZSBhbmQgdGhlIHNldHRpbmdzIGNhcmQuXG4gKiBAcGFyYW0gY3R4IC0gY2xpZW50IHJvb3QgY29udGV4dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5KGN0eDogQ2xpZW50Q29udGV4dCk6IHZvaWQge1xuICBjdHguZWZmZWN0KCgpID0+IGN0eC5sb2NhbGUucmVnaXN0ZXIoTlMsIHsgemgsIGVuIH0pLCAnYXV0by1jb250aW51ZTogZGljdGlvbmFyaWVzJyk7XG5cbiAgLy8gRW5naW5lOiByZWFkcyB0aGUgc2V0dGluZ3Mgc2NvcGUgbGl2ZSwgc28gR1VJIGNoYW5nZXMgYXBwbHkgaW1tZWRpYXRlbHkuXG4gIGNvbnN0IHNjb3BlID0gY3R4LnNldHRpbmdzU2NvcGUuYmluZDxBdXRvQ29udGludWVTZXR0aW5ncz4oeyBuYW1lc3BhY2U6IFNFVFRJTkdTX05TIH0pO1xuICBjdXJyZW50Py5kaXNwb3NlKCk7XG4gIGN1cnJlbnQgPSBuZXcgQXV0b0NvbnRpbnVlUnVubmVyKGN0eC5jb25uZWN0aW9uLmFwaSwgKCkgPT4gcmVzb2x2ZUNvbmZpZyhzY29wZS5nZXRTbmFwc2hvdCgpLnZhbHVlKSk7XG5cbiAgLy8gUGx1Z2luIGNvbmZpZ3VyYXRpb24gY2FyZDogb25lIHN0YWdlZCBmb3JtIG92ZXIgdGhlIGBhdXRvLWNvbnRpbnVlYFxuICAvLyBzZXR0aW5ncyBuYW1lc3BhY2UsIGNvbnRyaWJ1dGVkIHRvIHRoZSBwbHVnaW4tY29uZmlndXJhdGlvbiBzZWN0aW9uLlxuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZENvbnRyb2xsZXIoc2NvcGUpO1xuICBjdHguc2xvdHMuaW5qZWN0KCdzZXR0aW5ncy5wbHVnaW4uaXRlbScsICgpID0+XG4gICAgY3R4LnNsb3RzLnJlZ2lzdGVyKFxuICAgICAge1xuICAgICAgICBuYW1lOiAnc2V0dGluZ3MucGx1Z2luLml0ZW0nLFxuICAgICAgICBpZDogJ2F1dG8tY29udGludWUnLFxuICAgICAgICBvcmRlcjogOTAsXG4gICAgICAgIGxvY2FsZTogTlMsXG4gICAgICAgIGluamVjdDogKCkgPT4gY29udHJvbGxlci5pbmplY3QoKSxcbiAgICAgIH0sXG4gICAgICBBdXRvQ29udGludWVTZXR0aW5nc0NhcmQsXG4gICAgKSxcbiAgKTtcbn1cbiIsICIvKipcbiAqIEF1dG8tY29udGludWUgZW5naW5lIOKAlCBicm93c2VyIGhhbGYgY29yZS5cbiAqXG4gKiBXYXRjaGVzIHRoZSB0d28gbGl2ZSBldmVudCBzdHJlYW1zIG9mIHRoZSBkc2ggd2ViIEdVSSAobXV4ICsgaG9zdCk6XG4gKiAgIC0gdHVybnMgZW5kZWQgZm9yIGEgbm9uLWh1bWFuIHJlYXNvbiAoYHR1cm4vZW5kYCByZWFzb24g4oiIIGVycm9yIC8gaW50ZXJydXB0ZWQgLyBtYXgtdG9rZW5zKVxuICogICAtIGhvc3QtcmVwb3J0ZWQgYWdlbnQgZmFpbHVyZXMgd2l0aCBubyB0dXJuIHBvc2l0aW9uIChgaG9zdC9hZ2VudC1lcnJvcmApXG4gKiBBZnRlciBhIGdyYWNlIHBlcmlvZCBpdCBzZW5kcyBhIHF1ZXVlZCBwcm9tcHQgKGRlZmF1bHQg44CM57un57ut44CNKSB0byB0aGF0XG4gKiBzZXNzaW9uIOKAlCBleGFjdGx5IGVxdWl2YWxlbnQgdG8gdGhlIHVzZXIgdHlwaW5nIGl0IG1hbnVhbGx5LlxuICpcbiAqIEFsbCBiZWhhdmlvciBpcyBkcml2ZW4gYnkgdGhlIGBhdXRvLWNvbnRpbnVlYCBzZXR0aW5ncyBuYW1lc3BhY2UgKHNlZSB0aGVcbiAqIHBsdWdpbidzIHNldHRpbmdzIGNhcmQpOyBldmVyeSBrbm9iIGJlbG93IGlzIHVzZXItY29uZmlndXJhYmxlIHRoZXJlLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgSG9zdEZyYW1lLFxuICBJQXBpQ2xpZW50LFxuICBNdXhGcmFtZSxcbiAgU2Vzc2lvbklkLFxuICBTZXNzaW9uU3VtbWFyeSxcbn0gZnJvbSAnQGRlZXBzZWVrLWFpL2RzaC1jbGllbnQtY29ubmVjdGlvbi9jbGllbnQnO1xuaW1wb3J0IHR5cGUgeyBTZXNzaW9uRXZlbnQgfSBmcm9tICdAZGVlcHNlZWstYWkvZHNoLXNlc3Npb24vdHlwZXMnO1xuXG4vKiogVGhlIGBhdXRvLWNvbnRpbnVlYCBzZXR0aW5ncyBzZWN0aW9uIChhbGwgZmllbGRzIG9wdGlvbmFsIG9uIHRoZSB3aXJlOyB0aGUgaG9zdCBzY2hlbWEgY2FycmllcyBkZWZhdWx0cykuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dG9Db250aW51ZVNldHRpbmdzIHtcbiAgLyoqIFRleHQgYXV0b21hdGljYWxseSBzZW50IGFmdGVyIGFuIGludGVycnVwdGlvbi4gKi9cbiAgY29udGludWVUZXh0Pzogc3RyaW5nO1xuICAvKiogR3JhY2UgcGVyaW9kIGFmdGVyIGFuIGludGVycnVwdGlvbiBiZWZvcmUgYXV0by1zZW5kaW5nIChtcykuICovXG4gIGdyYWNlTXM/OiBudW1iZXI7XG4gIC8qKiBNaW5pbXVtIGludGVydmFsIGJldHdlZW4gdHdvIGF1dG8tY29udGludWVzIHBlciBzZXNzaW9uIChtcykuICovXG4gIGNvb2xkb3duTXM/OiBudW1iZXI7XG4gIC8qKiBNYXggY29uc2VjdXRpdmUgYXV0by1jb250aW51ZXMgcGVyIHNlc3Npb24gYmVmb3JlIHN0b3BwaW5nLiAqL1xuICBtYXhDb25zZWN1dGl2ZT86IG51bWJlcjtcbiAgLyoqIFNjYW4gcmVjZW50bHkgaW50ZXJydXB0ZWQgc2Vzc2lvbnMgb24gcGFnZSBsb2FkIC8gcmVjb25uZWN0LiAqL1xuICBzY2FuT25Cb290PzogYm9vbGVhbjtcbiAgLyoqIE1heCBzZXNzaW9ucyB0aGUgc2NhbiBjaGVja3MgKG1vc3QgcmVjZW50bHkgdXBkYXRlZCkuICovXG4gIHNjYW5MaW1pdD86IG51bWJlcjtcbiAgLyoqIFNjYW4gb25seSBjb25zaWRlcnMgaW50ZXJydXB0aW9ucyBpbnNpZGUgdGhpcyB3aW5kb3cgKG1zKS4gKi9cbiAgZnJlc2hNcz86IG51bWJlcjtcbiAgLyoqIERlbGF5IGJlZm9yZSBzY2FubmluZyBhZnRlciBhIHJlY29ubmVjdCAobXMpLiAqL1xuICByZWNvbm5lY3RTY2FuRGVsYXlNcz86IG51bWJlcjtcbiAgLyoqIFNTRSByZWNvbm5lY3QgYmFja29mZiAobXMpLiAqL1xuICByZWNvbm5lY3RCYWNrb2ZmTXM/OiBudW1iZXI7XG4gIC8qKiBMb2cgYFthdXRvLWNvbnRpbnVlXWAgbGluZXMgdG8gdGhlIGJyb3dzZXIgY29uc29sZS4gKi9cbiAgdmVyYm9zZT86IGJvb2xlYW47XG59XG5cbi8qKiBGdWxseSByZXNvbHZlZCBjb25maWd1cmF0aW9uIChidWlsdC1pbiBkZWZhdWx0cyArIHVzZXIgb3ZlcnJpZGVzKS4gKi9cbmV4cG9ydCB0eXBlIEF1dG9Db250aW51ZUNvbmZpZyA9IFJlcXVpcmVkPEF1dG9Db250aW51ZVNldHRpbmdzPjtcblxuLyoqIEJ1aWx0LWluIGRlZmF1bHRzIOKAlCBtdXN0IG1hdGNoIHRoZSBob3N0IHNjaGVtYSBkZWZhdWx0cyBpbiBzcmMvaW5kZXgudHMuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9DT05GSUc6IEF1dG9Db250aW51ZUNvbmZpZyA9IHtcbiAgY29udGludWVUZXh0OiAn57un57utJyxcbiAgZ3JhY2VNczogMzAwMCxcbiAgY29vbGRvd25NczogMjAwMDAsXG4gIG1heENvbnNlY3V0aXZlOiAzLFxuICBzY2FuT25Cb290OiB0cnVlLFxuICBzY2FuTGltaXQ6IDgsXG4gIGZyZXNoTXM6IDE1ICogNjAgKiAxMDAwLFxuICByZWNvbm5lY3RTY2FuRGVsYXlNczogNTAwMCxcbiAgcmVjb25uZWN0QmFja29mZk1zOiAzMDAwLFxuICB2ZXJib3NlOiB0cnVlLFxufTtcblxuZnVuY3Rpb24gbnVtYmVyT3IodmFsdWU6IHVua25vd24sIGZhbGxiYWNrOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpICYmIHZhbHVlID49IDAgPyB2YWx1ZSA6IGZhbGxiYWNrO1xufVxuXG5mdW5jdGlvbiBib29sZWFuT3IodmFsdWU6IHVua25vd24sIGZhbGxiYWNrOiBib29sZWFuKTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJyA/IHZhbHVlIDogZmFsbGJhY2s7XG59XG5cbi8qKiBSZXNvbHZlIGEgKHBvc3NpYmx5IHBhcnRpYWwgLyBub3QteWV0LWxvYWRlZCkgc2V0dGluZ3Mgc2VjdGlvbiB0byBhIGZ1bGwgY29uZmlnLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVDb25maWcoc2VjdGlvbjogQXV0b0NvbnRpbnVlU2V0dGluZ3MgfCB1bmRlZmluZWQpOiBBdXRvQ29udGludWVDb25maWcge1xuICBjb25zdCB2YWx1ZSA9IHNlY3Rpb24gPz8ge307XG4gIGNvbnN0IHRleHQgPVxuICAgIHR5cGVvZiB2YWx1ZS5jb250aW51ZVRleHQgPT09ICdzdHJpbmcnICYmIHZhbHVlLmNvbnRpbnVlVGV4dC50cmltKCkgIT09ICcnXG4gICAgICA/IHZhbHVlLmNvbnRpbnVlVGV4dFxuICAgICAgOiBERUZBVUxUX0NPTkZJRy5jb250aW51ZVRleHQ7XG4gIHJldHVybiB7XG4gICAgY29udGludWVUZXh0OiB0ZXh0LFxuICAgIGdyYWNlTXM6IG51bWJlck9yKHZhbHVlLmdyYWNlTXMsIERFRkFVTFRfQ09ORklHLmdyYWNlTXMpLFxuICAgIGNvb2xkb3duTXM6IG51bWJlck9yKHZhbHVlLmNvb2xkb3duTXMsIERFRkFVTFRfQ09ORklHLmNvb2xkb3duTXMpLFxuICAgIG1heENvbnNlY3V0aXZlOiBNYXRoLm1heCgxLCBudW1iZXJPcih2YWx1ZS5tYXhDb25zZWN1dGl2ZSwgREVGQVVMVF9DT05GSUcubWF4Q29uc2VjdXRpdmUpKSxcbiAgICBzY2FuT25Cb290OiBib29sZWFuT3IodmFsdWUuc2Nhbk9uQm9vdCwgREVGQVVMVF9DT05GSUcuc2Nhbk9uQm9vdCksXG4gICAgc2NhbkxpbWl0OiBNYXRoLm1heCgxLCBudW1iZXJPcih2YWx1ZS5zY2FuTGltaXQsIERFRkFVTFRfQ09ORklHLnNjYW5MaW1pdCkpLFxuICAgIGZyZXNoTXM6IG51bWJlck9yKHZhbHVlLmZyZXNoTXMsIERFRkFVTFRfQ09ORklHLmZyZXNoTXMpLFxuICAgIHJlY29ubmVjdFNjYW5EZWxheU1zOiBudW1iZXJPcih2YWx1ZS5yZWNvbm5lY3RTY2FuRGVsYXlNcywgREVGQVVMVF9DT05GSUcucmVjb25uZWN0U2NhbkRlbGF5TXMpLFxuICAgIHJlY29ubmVjdEJhY2tvZmZNczogbnVtYmVyT3IodmFsdWUucmVjb25uZWN0QmFja29mZk1zLCBERUZBVUxUX0NPTkZJRy5yZWNvbm5lY3RCYWNrb2ZmTXMpLFxuICAgIHZlcmJvc2U6IGJvb2xlYW5Pcih2YWx1ZS52ZXJib3NlLCBERUZBVUxUX0NPTkZJRy52ZXJib3NlKSxcbiAgfTtcbn1cblxuLyoqIOinhuS4uuOAjOmdnuS6uuS4uuS4reaWreOAjeeahOWbnuWQiOe7k+adn+WOn+WboOOAgmFib3J0ZWQo55So5oi35YGc5q2iKeS4jiBibG9ja2VkKOetlueVpeaLkue7nSnkuI3lnKjlhbbkuK3jgIIgKi9cbnR5cGUgTm9uSHVtYW5SZWFzb24gPSAnZXJyb3InIHwgJ2ludGVycnVwdGVkJyB8ICdtYXgtdG9rZW5zJztcblxuZnVuY3Rpb24gaXNOb25IdW1hblJlYXNvbihraW5kOiBzdHJpbmcpOiBraW5kIGlzIE5vbkh1bWFuUmVhc29uIHtcbiAgcmV0dXJuIGtpbmQgPT09ICdlcnJvcicgfHwga2luZCA9PT0gJ2ludGVycnVwdGVkJyB8fCBraW5kID09PSAnbWF4LXRva2Vucyc7XG59XG5cbmZ1bmN0aW9uIHNsZWVwKG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG5cbi8qKiDmtY/op4jlmajlvZPliY0gSUFOQSDml7bljLo7IOS4jeWPr+eUqOaXtuecgeeVpSjlrr/kuLvlhYHorrjnnIHnlaUp44CCICovXG5mdW5jdGlvbiBjbGllbnRUaW1lWm9uZSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIHJldHVybiBJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmUgfHwgdW5kZWZpbmVkO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKiDot6jmoIfnrb7pobXkupLmlqXkuI7lhrfljbTorrDlvZUo5LuF5rWP6KeI5Zmo5pys5ZywLCDkuI3okL3nm5jliLDlrr/kuLsp44CCICovXG5jb25zdCBsb2NrUHJlZml4ID0gJ2RzaC1hdXRvLWNvbnRpbnVlOic7XG5jb25zdCBsb2NrS2V5ID0gKHNlc3Npb25JZDogU2Vzc2lvbklkKSA9PiBgJHtsb2NrUHJlZml4fWxvY2s6JHtzZXNzaW9uSWR9YDtcbmNvbnN0IHN0YW1wS2V5ID0gKHNlc3Npb25JZDogU2Vzc2lvbklkKSA9PiBgJHtsb2NrUHJlZml4fWxhc3Q6JHtzZXNzaW9uSWR9YDtcblxuLyoqIOWwneivleeLrOWNoOacrOasoeWPkemAgTog5Lik5Liq5qCH562+6aG15ZCM5pe26Kem5Y+R5pe25Y+q5pyJ5LiA5Liq5oiQ5Yqf44CCICovXG5mdW5jdGlvbiBjbGFpbVNlbmQoc2Vzc2lvbklkOiBTZXNzaW9uSWQpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB0b2tlbiA9IGAke0RhdGUubm93KCl9LSR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMil9YDtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShsb2NrS2V5KHNlc3Npb25JZCksIHRva2VuKTtcbiAgICByZXR1cm4gbG9jYWxTdG9yYWdlLmdldEl0ZW0obG9ja0tleShzZXNzaW9uSWQpKSA9PT0gdG9rZW47XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB0cnVlOyAvLyDlrZjlgqjkuI3lj6/nlKgo6ZqQ56eB5qih5byP562JKeaXtuaUvuihjFxuICB9XG59XG5cbmZ1bmN0aW9uIHJlbGVhc2VTZW5kKHNlc3Npb25JZDogU2Vzc2lvbklkKTogdm9pZCB7XG4gIHRyeSB7XG4gICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0obG9ja0tleShzZXNzaW9uSWQpKTtcbiAgfSBjYXRjaCB7XG4gICAgLyogaWdub3JlICovXG4gIH1cbn1cblxuLyoqIOivuy/lhpnjgIzkuIrmrKHoh6rliqjlj5HpgIHjgI3ml7bpl7TmiLMo6Leo5qCH562+6aG15Ya35Y20KeOAgiAqL1xuZnVuY3Rpb24gcmVhZExhc3RTZW5kKHNlc3Npb25JZDogU2Vzc2lvbklkKTogbnVtYmVyIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gTnVtYmVyKGxvY2FsU3RvcmFnZS5nZXRJdGVtKHN0YW1wS2V5KHNlc3Npb25JZCkpID8/IDApIHx8IDA7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiAwO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdyaXRlTGFzdFNlbmQoc2Vzc2lvbklkOiBTZXNzaW9uSWQsIGF0OiBudW1iZXIpOiB2b2lkIHtcbiAgdHJ5IHtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShzdGFtcEtleShzZXNzaW9uSWQpLCBTdHJpbmcoYXQpKTtcbiAgfSBjYXRjaCB7XG4gICAgLyogaWdub3JlICovXG4gIH1cbn1cblxuLyoqIOavj+S8muivnei/kOihjOaXtueKtuaAgeOAgiAqL1xuaW50ZXJmYWNlIFNlc3Npb25TdGF0ZSB7XG4gIC8qKiDov57nu63oh6rliqjjgIznu6fnu63jgI3mrKHmlbA7IOaIkOWKn+WbnuWQiOaIlueUqOaIt+aJi+WKqOS7i+WFpeWQjuW9kumbtuOAgiAqL1xuICBjb25zZWN1dGl2ZTogbnVtYmVyO1xuICAvKiog5LiK5qyh6Ieq5Yqo44CM57un57ut44CN5pe26Ze05oiz44CCICovXG4gIGxhc3RBdXRvQXQ6IG51bWJlcjtcbiAgLyoqIOS4iuasoeiHquWKqOOAjOe7p+e7reOAjeWwneivlSjmiJDlip/miJblpLHotKUp5pe26Ze05oizOyDpmLLmraLlpLHotKXlnLrmma/kuIvnmoTlv6vpgJ/ph43or5Xlvqrnjq/jgIIgKi9cbiAgbGFzdEF0dGVtcHRBdDogbnVtYmVyO1xuICAvKiog5oiR5Lus5LiK5qyh6Ieq5Yqo5Y+R6YCB55qE5paH5pysKOeUqOS6juivhuWIq+iHquW3seeahOWbnuaYvinjgIIgKi9cbiAgbGFzdFNlbnRUZXh0OiBzdHJpbmc7XG4gIC8qKiDlrr3pmZDmnJ/lrprml7blmago6L+b6KGM5Lit55qE5b6F5Y+R6YCBKeOAgiAqL1xuICBwZW5kaW5nVGltZXI6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgLyoqIOWuv+S4u+adg+WogSBydW5uaW5nIOS9jSjmnaXoh6ogaG9zdC9zZXNzaW9uLXN0YXR1cyDkuI7lm57lkIjkuovku7Yp44CCICovXG4gIHJ1bm5pbmc6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gIC8qKiDlvZPliY3mjpLpmJ/mtojmga/mlbAo5p2l6IeqIHNlc3Npb24vcXVldWUg5binKeOAgiAqL1xuICBxdWV1ZWQ6IG51bWJlcjtcbiAgLyoqIOWtkOS7o+eQhuS8muivnShob3N0L3Nlc3Npb24tYWRkZWQg5bimIHBhcmVudFNlc3Npb25JZCnjgIIgKi9cbiAgc3ViYWdlbnQ6IGJvb2xlYW47XG59XG5cbmNvbnN0IGZyZXNoU3RhdGUgPSAoKTogU2Vzc2lvblN0YXRlID0+ICh7XG4gIGNvbnNlY3V0aXZlOiAwLFxuICBsYXN0QXV0b0F0OiAwLFxuICBsYXN0QXR0ZW1wdEF0OiAwLFxuICBsYXN0U2VudFRleHQ6ICcnLFxuICBwZW5kaW5nVGltZXI6IHVuZGVmaW5lZCxcbiAgcnVubmluZzogdW5kZWZpbmVkLFxuICBxdWV1ZWQ6IDAsXG4gIHN1YmFnZW50OiBmYWxzZSxcbn0pO1xuXG4vKiog5Yik5a6a5LiA5p2hIHVzZXIvbWVzc2FnZSDmmK/lkKbmmK/miJHku6zoh6rlt7Hoh6rliqjlj5HpgIHnmoTlm57mmL7jgIIgKi9cbmZ1bmN0aW9uIGlzT3VyRWNobyhzdGF0ZTogU2Vzc2lvblN0YXRlLCBldmVudDogU2Vzc2lvbkV2ZW50KTogYm9vbGVhbiB7XG4gIGlmIChldmVudC50eXBlICE9PSAndXNlci9tZXNzYWdlJykgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBtZXNzYWdlID0gZXZlbnQuZGF0YTtcbiAgaWYgKG1lc3NhZ2Uuc291cmNlLmtpbmQgIT09ICd1c2VyJykgcmV0dXJuIGZhbHNlO1xuICBpZiAoc3RhdGUubGFzdFNlbnRUZXh0ID09PSAnJykgcmV0dXJuIGZhbHNlO1xuICBpZiAoRGF0ZS5ub3coKSAtIHN0YXRlLmxhc3RBdXRvQXQgPiAzMDAwMCkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCB0ZXh0ID0gbWVzc2FnZS5jb250ZW50XG4gICAgLmZpbHRlcigocGFydCk6IHBhcnQgaXMgeyB0eXBlOiAndGV4dCc7IHRleHQ6IHN0cmluZyB9ID0+IHBhcnQudHlwZSA9PT0gJ3RleHQnKVxuICAgIC5tYXAoKHBhcnQpID0+IHBhcnQudGV4dClcbiAgICAuam9pbignJyk7XG4gIHJldHVybiB0ZXh0ID09PSBzdGF0ZS5sYXN0U2VudFRleHQ7XG59XG5cbi8qKiBTU0Ug5bin5aSW5aOzOiBgeyBycGNJZCwgcGF5bG9hZCB9YOOAgiAqL1xudHlwZSBGcmFtZUVudmVsb3BlPFQ+ID0geyBwYXlsb2FkOiBUIH07XG5cbi8qKlxuICog5LqL5Lu25rWB5rO1OiDluKbmjIfmlbDpgIDpgb/nmoQgU1NFIOmHjei/nuW+queOr+OAglxuICogLSDku47mnKrmlLbliLDku7vkvZXluKco5a6/5Li75pyq5bCx57uqKTog6YCA6YG/6YeN6K+VLCDkuI3op6blj5Hmiavmj49cbiAqIC0g5pu+6L+e5LiK5ZCO5pat5byAOiDph43ov54sIOW5tumAmui/hyBvblJlY29ubmVjdCDpgJrnn6XlpJblsYIo5a6/5Li75Y+v6IO95bSp5rqD6YeN5ZCv6L+HKVxuICovXG5hc3luYyBmdW5jdGlvbiBwdW1wU3RyZWFtPFQ+KFxuICBvcGVuOiAoc2lnbmFsOiBBYm9ydFNpZ25hbCkgPT4gQXN5bmNJdGVyYWJsZTxGcmFtZUVudmVsb3BlPFQ+PixcbiAgb25GcmFtZTogKHBheWxvYWQ6IFQpID0+IHZvaWQsXG4gIG9uUmVjb25uZWN0OiAoKSA9PiB2b2lkLFxuICBnZXRCYWNrb2ZmOiAoKSA9PiBudW1iZXIsXG4gIGxvZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCxcbiAgc2lnbmFsOiBBYm9ydFNpZ25hbCxcbik6IFByb21pc2U8dm9pZD4ge1xuICBsZXQgYmFja29mZiA9IGdldEJhY2tvZmYoKTtcbiAgd2hpbGUgKCFzaWduYWwuYWJvcnRlZCkge1xuICAgIGxldCBjb25uZWN0ZWQgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgZm9yIGF3YWl0IChjb25zdCBlbnZlbG9wZSBvZiBvcGVuKHNpZ25hbCkpIHtcbiAgICAgICAgY29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgb25GcmFtZShlbnZlbG9wZS5wYXlsb2FkKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHJldHVybjtcbiAgICAgIGxvZyhgc3RyZWFtIGVycm9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKTtcbiAgICB9XG4gICAgaWYgKCFjb25uZWN0ZWQpIHtcbiAgICAgIC8vIOS7juacqui/nuS4iijlrr/kuLvmnKrlsLHnu6opOiDmjIfmlbDpgIDpgb/ph43or5VcbiAgICAgIGF3YWl0IHNsZWVwKGJhY2tvZmYpO1xuICAgICAgYmFja29mZiA9IE1hdGgubWluKGJhY2tvZmYgKiAyLCAxNTAwMCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgLy8g5pu+6L+e5LiK5ZCO5pat5byAIOKGkiDph43ov57lubbop6blj5HlpJblsYLmiavmj49cbiAgICBiYWNrb2ZmID0gZ2V0QmFja29mZigpO1xuICAgIG9uUmVjb25uZWN0KCk7XG4gICAgYXdhaXQgc2xlZXAoYmFja29mZik7XG4gIH1cbn1cblxuLyoqIOaPkuS7tuS4u+S9kzog5LiA5p2hIG11eCDmtYEgKyDkuIDmnaEgaG9zdCDmtYEgKyDlkK/liqgv6YeN6L+e5omr5o+P44CCICovXG5leHBvcnQgY2xhc3MgQXV0b0NvbnRpbnVlUnVubmVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGF0ZXMgPSBuZXcgTWFwPFNlc3Npb25JZCwgU2Vzc2lvblN0YXRlPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG11eEFib3J0ID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGhvc3RBYm9ydCA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgcHJpdmF0ZSBkaXNwb3NlZCA9IGZhbHNlO1xuICBwcml2YXRlIHJlY29ubmVjdFNjYW5zID0gMDtcblxuICAvKipcbiAgICogQHBhcmFtIGFwaSAtIHNoYXJlZCB3aXJlIGNsaWVudCAoY3R4LmNvbm5lY3Rpb24uYXBpKS5cbiAgICogQHBhcmFtIGdldENvbmZpZyAtIHJlYWQgdGhlIGN1cnJlbnQgcmVzb2x2ZWQgY29uZmlndXJhdGlvbiAoc2V0dGluZ3Mgc2NvcGUpLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBhcGk6IElBcGlDbGllbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBnZXRDb25maWc6ICgpID0+IEF1dG9Db250aW51ZUNvbmZpZyxcbiAgKSB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICB2b2lkIHRoaXMucnVuTXV4KCk7XG4gICAgdm9pZCB0aGlzLnJ1bkhvc3QoKTtcbiAgICBpZiAoY29uZmlnLnNjYW5PbkJvb3QpIHtcbiAgICAgIC8vIOWQr+WKqOaXtui/nuaOpeWPr+iDveWwmuacquW7uueriywg5b6q546v6YeN6K+V55u05Yiw5oiQ5Yqf44CCXG4gICAgICB2b2lkIHRoaXMuYm9vdFNjYW5Mb29wKCk7XG4gICAgfVxuICAgIHRoaXMubG9nKFxuICAgICAgYOW3suWQr+WKqCjmlofmnKw9XCIke2NvbmZpZy5jb250aW51ZVRleHR9XCIsIOWuvemZkCAke2NvbmZpZy5ncmFjZU1zfW1zLCBgICtcbiAgICAgICAgYOWGt+WNtCAke2NvbmZpZy5jb29sZG93bk1zfW1zLCDmnIDlpJrov57nu60gJHtjb25maWcubWF4Q29uc2VjdXRpdmV9IOasoSlgLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGxvZyhtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5nZXRDb25maWcoKS52ZXJib3NlKSBjb25zb2xlLmluZm8oYFthdXRvLWNvbnRpbnVlXSAke21lc3NhZ2V9YCk7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuICAgIHRoaXMubXV4QWJvcnQuYWJvcnQoKTtcbiAgICB0aGlzLmhvc3RBYm9ydC5hYm9ydCgpO1xuICAgIGZvciAoY29uc3Qgc3RhdGUgb2YgdGhpcy5zdGF0ZXMudmFsdWVzKCkpIHtcbiAgICAgIGlmIChzdGF0ZS5wZW5kaW5nVGltZXIgIT09IHVuZGVmaW5lZCkgY2xlYXJUaW1lb3V0KHN0YXRlLnBlbmRpbmdUaW1lcik7XG4gICAgfVxuICAgIHRoaXMuc3RhdGVzLmNsZWFyKCk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRlKHNlc3Npb25JZDogU2Vzc2lvbklkKTogU2Vzc2lvblN0YXRlIHtcbiAgICBsZXQgc3RhdGUgPSB0aGlzLnN0YXRlcy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoc3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc3RhdGUgPSBmcmVzaFN0YXRlKCk7XG4gICAgICB0aGlzLnN0YXRlcy5zZXQoc2Vzc2lvbklkLCBzdGF0ZSk7XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIHByaXZhdGUgcnVuTXV4KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBwdW1wU3RyZWFtPE11eEZyYW1lPihcbiAgICAgIChzaWduYWwpID0+IHRoaXMuYXBpLmV2ZW50cy5tdXgoe30sIHNpZ25hbCksXG4gICAgICAocGF5bG9hZCkgPT4gdGhpcy5vbk11eEZyYW1lKHBheWxvYWQpLFxuICAgICAgKCkgPT4gdGhpcy5zY2hlZHVsZVJlY29ubmVjdFNjYW4oKSxcbiAgICAgICgpID0+IHRoaXMuZ2V0Q29uZmlnKCkucmVjb25uZWN0QmFja29mZk1zLFxuICAgICAgKG0pID0+IHRoaXMubG9nKG0pLFxuICAgICAgdGhpcy5tdXhBYm9ydC5zaWduYWwsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgcnVuSG9zdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gcHVtcFN0cmVhbTxIb3N0RnJhbWU+KFxuICAgICAgKHNpZ25hbCkgPT4gdGhpcy5hcGkuZXZlbnRzLmhvc3Qoe30sIHNpZ25hbCksXG4gICAgICAocGF5bG9hZCkgPT4gdGhpcy5vbkhvc3RGcmFtZShwYXlsb2FkKSxcbiAgICAgICgpID0+IHRoaXMuc2NoZWR1bGVSZWNvbm5lY3RTY2FuKCksXG4gICAgICAoKSA9PiB0aGlzLmdldENvbmZpZygpLnJlY29ubmVjdEJhY2tvZmZNcyxcbiAgICAgIChtKSA9PiB0aGlzLmxvZyhtKSxcbiAgICAgIHRoaXMuaG9zdEFib3J0LnNpZ25hbCxcbiAgICApO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLSBtdXgg5binIC0tLS0tLS0tLS1cblxuICBwcml2YXRlIG9uTXV4RnJhbWUoZnJhbWU6IE11eEZyYW1lKTogdm9pZCB7XG4gICAgc3dpdGNoIChmcmFtZS50eXBlKSB7XG4gICAgICBjYXNlICdzZXNzaW9uL2V2ZW50JzpcbiAgICAgICAgdGhpcy5vblNlc3Npb25FdmVudChmcmFtZS5zZXNzaW9uSWQsIGZyYW1lLmV2ZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzZXNzaW9uL3F1ZXVlJzpcbiAgICAgICAgdGhpcy5zdGF0ZShmcmFtZS5zZXNzaW9uSWQpLnF1ZXVlZCA9IGZyYW1lLml0ZW1zLmxlbmd0aDtcbiAgICAgICAgaWYgKGZyYW1lLml0ZW1zLmxlbmd0aCA+IDApIHRoaXMuY2FuY2VsUGVuZGluZyhmcmFtZS5zZXNzaW9uSWQsICflh7rnjrDmjpLpmJ/mtojmga8nKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzdHJlYW0vZXJyb3InOlxuICAgICAgICB0aGlzLmxvZyhgbXV4IHN0cmVhbS9lcnJvcjogJHtmcmFtZS5lcnJvci5jb2RlfSAke2ZyYW1lLmVycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7IC8vIHNlc3Npb24vc3Vic2NyaWJlZOOAgWFwcHJvdmFsLyrjgIFxdWVzdGlvbi8q44CBc2Vzc2lvbi9qb2Jz44CBc2Vzc2lvbi9wcm9qZWN0aW9uIOS4juacrOaPkuS7tuaXoOWFs1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25TZXNzaW9uRXZlbnQoc2Vzc2lvbklkOiBTZXNzaW9uSWQsIGV2ZW50OiBTZXNzaW9uRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGUoc2Vzc2lvbklkKTtcbiAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgIGNhc2UgJ3R1cm4vc3RhcnQnOlxuICAgICAgICBzdGF0ZS5ydW5uaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jYW5jZWxQZW5kaW5nKHNlc3Npb25JZCwgJ+Wuv+S4u+iHquihjOW8gOWQr+aWsOWbnuWQiCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3R1cm4vZW5kJzoge1xuICAgICAgICBzdGF0ZS5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2FuY2VsUGVuZGluZyhzZXNzaW9uSWQsICfmlLbliLDmlrDnmoQgdHVybi9lbmQnKTtcbiAgICAgICAgY29uc3QgcmVhc29uID0gZXZlbnQuZGF0YS5yZWFzb247XG4gICAgICAgIGlmIChyZWFzb24ua2luZCA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICAgICAgICAvLyDmiJDlip/lm57lkIg6IOaBouWkjeWBpeW6t+eKtuaAgVxuICAgICAgICAgIHN0YXRlLmNvbnNlY3V0aXZlID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChyZWFzb24ua2luZCA9PT0gJ2Fib3J0ZWQnKSB7XG4gICAgICAgICAgLy8g55So5oi35Li75Yqo5YGc5q2iOiDkuI3oh6rliqjnu6fnu60sIOinhuS4uueUqOaIt+S7i+WFpVxuICAgICAgICAgIHN0YXRlLmNvbnNlY3V0aXZlID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChyZWFzb24ua2luZCA9PT0gJ2Jsb2NrZWQnKSB7XG4gICAgICAgICAgLy8g562W55Wl5ouS57udOiDkuI3oh6rliqjnu6fnu61cbiAgICAgICAgfSBlbHNlIGlmIChpc05vbkh1bWFuUmVhc29uKHJlYXNvbi5raW5kKSkge1xuICAgICAgICAgIHRoaXMuc2NoZWR1bGUoc2Vzc2lvbklkLCBgdHVybi9lbmQ6JHtyZWFzb24ua2luZH1gKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3VzZXIvbWVzc2FnZSc6XG4gICAgICAgIGlmIChpc091ckVjaG8oc3RhdGUsIGV2ZW50KSkgYnJlYWs7IC8vIOaIkeS7rOiHquW3seeahOWbnuaYvlxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5zb3VyY2Uua2luZCA9PT0gJ3VzZXInKSB7XG4gICAgICAgICAgLy8g55So5oi35omL5Yqo5LuL5YWlXG4gICAgICAgICAgc3RhdGUuY29uc2VjdXRpdmUgPSAwO1xuICAgICAgICAgIHRoaXMuY2FuY2VsUGVuZGluZyhzZXNzaW9uSWQsICfnlKjmiLfmiYvliqjlj5HpgIHmtojmga8nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0gaG9zdCDluKcgLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgb25Ib3N0RnJhbWUoZnJhbWU6IEhvc3RGcmFtZSk6IHZvaWQge1xuICAgIHN3aXRjaCAoZnJhbWUudHlwZSkge1xuICAgICAgY2FzZSAnaG9zdC9zZXNzaW9uLXN0YXR1cyc6XG4gICAgICAgIHRoaXMuc3RhdGUoZnJhbWUuc2Vzc2lvbklkKS5ydW5uaW5nID0gZnJhbWUucnVubmluZztcbiAgICAgICAgaWYgKGZyYW1lLnJ1bm5pbmcpIHRoaXMuY2FuY2VsUGVuZGluZyhmcmFtZS5zZXNzaW9uSWQsICflrr/kuLvmiqXlkYrkvJror53lvIDlp4vov5DooYwnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdob3N0L3Nlc3Npb24tYWRkZWQnOlxuICAgICAgICB0aGlzLnN0YXRlKGZyYW1lLnNlc3Npb25JZCkuc3ViYWdlbnQgPSBmcmFtZS5wYXJlbnRTZXNzaW9uSWQgIT09IHVuZGVmaW5lZDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdob3N0L2FnZW50LWVycm9yJzpcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUoZnJhbWUuc2Vzc2lvbklkKS5zdWJhZ2VudCkgYnJlYWs7XG4gICAgICAgIHRoaXMubG9nKGBob3N0L2FnZW50LWVycm9yKCR7ZnJhbWUuc2Vzc2lvbklkfSk6ICR7ZnJhbWUubWVzc2FnZX1gKTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZShmcmFtZS5zZXNzaW9uSWQsICdob3N0L2FnZW50LWVycm9yJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaG9zdC9zZXNzaW9uLXJlbW92ZWQnOlxuICAgICAgICB0aGlzLmNhbmNlbFBlbmRpbmcoZnJhbWUuc2Vzc2lvbklkLCAn5Lya6K+d5bey56e76ZmkJyk7XG4gICAgICAgIHRoaXMuc3RhdGVzLmRlbGV0ZShmcmFtZS5zZXNzaW9uSWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0g6LCD5bqmIC0tLS0tLS0tLS1cblxuICBwcml2YXRlIHNjaGVkdWxlKHNlc3Npb25JZDogU2Vzc2lvbklkLCByZWFzb246IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZShzZXNzaW9uSWQpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKHN0YXRlLnN1YmFnZW50KSByZXR1cm47IC8vIOWtkOS7o+eQhuS8muivneeUseeItuS7o+eQhuWkhOeQhiwg5LiN5oqi6LeRXG4gICAgaWYgKHN0YXRlLnBlbmRpbmdUaW1lciAhPT0gdW5kZWZpbmVkKSByZXR1cm47IC8vIOW3suacieW+heWPkemAgVxuICAgIGlmIChEYXRlLm5vdygpIC0gc3RhdGUubGFzdEF0dGVtcHRBdCA8IGNvbmZpZy5jb29sZG93bk1zKSByZXR1cm47IC8vIOWGt+WNtOacnyjlkKvlpLHotKXlsJ3or5UpXG4gICAgaWYgKHN0YXRlLmNvbnNlY3V0aXZlID49IGNvbmZpZy5tYXhDb25zZWN1dGl2ZSkge1xuICAgICAgdGhpcy5sb2coXG4gICAgICAgIGDot7Pov4cgJHtzZXNzaW9uSWR9KCR7cmVhc29ufSk6IOW3sui/nue7reiHquWKqOe7p+e7rSAke3N0YXRlLmNvbnNlY3V0aXZlfSDmrKEsIOetieW+heeUqOaIt+S7i+WFpeaIluaIkOWKn+WbnuWQiGAsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RhdGUucXVldWVkID4gMCkgcmV0dXJuOyAvLyDlt7LmnInmjpLpmJ/mtojmga8sIOWuv+S4u+S8muiHquihjOWUpOmGklxuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoc3RhdGUucGVuZGluZ1RpbWVyICE9PSB0aW1lcikgcmV0dXJuO1xuICAgICAgc3RhdGUucGVuZGluZ1RpbWVyID0gdW5kZWZpbmVkO1xuICAgICAgdm9pZCB0aGlzLmZpcmUoc2Vzc2lvbklkLCByZWFzb24pO1xuICAgIH0sIGNvbmZpZy5ncmFjZU1zKTtcbiAgICBzdGF0ZS5wZW5kaW5nVGltZXIgPSB0aW1lcjtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGDmo4DmtYvliLDpnZ7kurrkuLrkuK3mlq0gJHtzZXNzaW9uSWR9KCR7cmVhc29ufSksICR7Y29uZmlnLmdyYWNlTXN9bXMg5ZCO6Ieq5Yqo5Y+R6YCB44CMJHtjb25maWcuY29udGludWVUZXh0feOAjWAsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgY2FuY2VsUGVuZGluZyhzZXNzaW9uSWQ6IFNlc3Npb25JZCwgd2h5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGUoc2Vzc2lvbklkKTtcbiAgICBpZiAoc3RhdGUucGVuZGluZ1RpbWVyID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICBjbGVhclRpbWVvdXQoc3RhdGUucGVuZGluZ1RpbWVyKTtcbiAgICBzdGF0ZS5wZW5kaW5nVGltZXIgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sb2coYOWPlua2iCAke3Nlc3Npb25JZH0g55qE6Ieq5Yqo57un57utKCR7d2h5fSlgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmlyZShzZXNzaW9uSWQ6IFNlc3Npb25JZCwgcmVhc29uOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuO1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZShzZXNzaW9uSWQpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgLy8g5p2D5aiBIHJ1bm5pbmcg5qOA5p+lOiDkvJjlhYjnlKggaG9zdCDluKcsIOacquefpeaXtuWbnumAgOWIsCBzZXNzaW9uLmxpc3RcbiAgICBpZiAoc3RhdGUucnVubmluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBydW5uaW5nID0gYXdhaXQgdGhpcy5ydW5uaW5nVmlhTGlzdChzZXNzaW9uSWQpO1xuICAgICAgaWYgKHJ1bm5pbmcgPT09IHVuZGVmaW5lZCB8fCBydW5uaW5nKSB7XG4gICAgICAgIHRoaXMubG9nKGDot7Pov4cgJHtzZXNzaW9uSWR9OiDml6Dms5Xnoa7orqTnqbrpl7IoJHtydW5uaW5nID09PSB1bmRlZmluZWQgPyAn5pyq55+lJyA6ICfov5DooYzkuK0nfSlgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc3RhdGUucnVubmluZykge1xuICAgICAgdGhpcy5sb2coYOi3s+i/hyAke3Nlc3Npb25JZH06IOS8muivneS7jeWcqOi/kOihjGApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RhdGUucXVldWVkID4gMCkge1xuICAgICAgdGhpcy5sb2coYOi3s+i/hyAke3Nlc3Npb25JZH06IOW3suacieaOkumYn+a2iOaBr2ApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyDot6jmoIfnrb7pobXlhrfljbRcbiAgICBpZiAoRGF0ZS5ub3coKSAtIHJlYWRMYXN0U2VuZChzZXNzaW9uSWQpIDwgY29uZmlnLmNvb2xkb3duTXMpIHtcbiAgICAgIHRoaXMubG9nKGDot7Pov4cgJHtzZXNzaW9uSWR9OiDlhbbku5bmoIfnrb7pobXliJrlj5HpgIHov4dgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFjbGFpbVNlbmQoc2Vzc2lvbklkKSkge1xuICAgICAgdGhpcy5sb2coYOi3s+i/hyAke3Nlc3Npb25JZH06IOWFtuS7luagh+etvumhteato+WcqOWPkemAgWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0ZXh0ID0gY29uZmlnLmNvbnRpbnVlVGV4dDtcbiAgICBjb25zdCB6b25lID0gY2xpZW50VGltZVpvbmUoKTtcbiAgICBzdGF0ZS5sYXN0QXR0ZW1wdEF0ID0gRGF0ZS5ub3coKTsgLy8g5YWI6K6w6LSmOiDml6DorrrmiJDotKUsIOacrOasoeWwneivlemDvei/m+WFpeWGt+WNtFxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuYXBpLnNlc3Npb25zLnByb21wdCh7XG4gICAgICAgIHNlc3Npb25JZCxcbiAgICAgICAgbW9kZTogJ3F1ZXVlJyxcbiAgICAgICAgY29udGVudDogW3sgdHlwZTogJ3RleHQnLCB0ZXh0IH1dLFxuICAgICAgICAuLi4oem9uZSA9PT0gdW5kZWZpbmVkID8ge30gOiB7IGNsaWVudFRpbWVab25lOiB6b25lIH0pLFxuICAgICAgfSk7XG4gICAgICBpZiAocmVzcG9uc2UucmVzdWx0Lm9rKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIHN0YXRlLmNvbnNlY3V0aXZlICs9IDE7XG4gICAgICAgIHN0YXRlLmxhc3RBdXRvQXQgPSBub3c7XG4gICAgICAgIHN0YXRlLmxhc3RTZW50VGV4dCA9IHRleHQ7XG4gICAgICAgIHdyaXRlTGFzdFNlbmQoc2Vzc2lvbklkLCBub3cpO1xuICAgICAgICB0aGlzLmxvZyhg5bey6Ieq5Yqo5Y+R6YCB44CMJHt0ZXh0feOAjeWIsCAke3Nlc3Npb25JZH0oJHtyZWFzb259KSwg56ysICR7c3RhdGUuY29uc2VjdXRpdmV9IOasoei/nue7rWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgYOWPkemAgeWksei0pSAke3Nlc3Npb25JZH06ICR7cmVzcG9uc2UucmVzdWx0LmVycm9yLmNvZGV9ICR7cmVzcG9uc2UucmVzdWx0LmVycm9yLm1lc3NhZ2V9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5sb2coYOWPkemAgeW8guW4uCAke3Nlc3Npb25JZH06ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICByZWxlYXNlU2VuZChzZXNzaW9uSWQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcnVubmluZ1ZpYUxpc3Qoc2Vzc2lvbklkOiBTZXNzaW9uSWQpOiBQcm9taXNlPGJvb2xlYW4gfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmFwaS5zZXNzaW9ucy5saXN0KHt9KTtcbiAgICAgIGlmICghcmVzcG9uc2UucmVzdWx0Lm9rKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgaXRlbSA9IHJlc3BvbnNlLnJlc3VsdC52YWx1ZS5pdGVtcy5maW5kKFxuICAgICAgICAoc3VtbWFyeTogU2Vzc2lvblN1bW1hcnkpID0+IHN1bW1hcnkuc2Vzc2lvbklkID09PSBzZXNzaW9uSWQsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGl0ZW0gPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGl0ZW0ucnVubmluZztcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLSDlkK/liqgv6YeN6L+e5omr5o+PIC0tLS0tLS0tLS1cblxuICBwcml2YXRlIHNjaGVkdWxlUmVjb25uZWN0U2NhbigpOiB2b2lkIHtcbiAgICB0aGlzLnJlY29ubmVjdFNjYW5zICs9IDE7XG4gICAgY29uc3Qgc2NhbiA9IHRoaXMucmVjb25uZWN0U2NhbnM7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoc2NhbiAhPT0gdGhpcy5yZWNvbm5lY3RTY2FucyB8fCB0aGlzLmRpc3Bvc2VkKSByZXR1cm47XG4gICAgICB2b2lkIHRoaXMuc2Nhbkxvb3AoNiwgdGhpcy5nZXRDb25maWcoKS5yZWNvbm5lY3RTY2FuRGVsYXlNcyk7XG4gICAgfSwgdGhpcy5nZXRDb25maWcoKS5yZWNvbm5lY3RTY2FuRGVsYXlNcyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3RTY2FuTG9vcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnNjYW5Mb29wKEluZmluaXR5LCAzMDAwKTtcbiAgfVxuXG4gIC8qKiDlj43lpI3lsJ3or5Xmiavmj48sIOebtOWIsOaIkOWKnyjlrr/kuLvlsLHnu6op5oiW6L6+5Yiw5qyh5pWw5LiK6ZmQ44CCICovXG4gIHByaXZhdGUgYXN5bmMgc2Nhbkxvb3AoYXR0ZW1wdHM6IG51bWJlciwgZGVsYXlNczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPCBhdHRlbXB0cyAmJiAhdGhpcy5kaXNwb3NlZDsgYXR0ZW1wdCArPSAxKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoYXdhaXQgdGhpcy5zY2FuSW50ZXJydXB0ZWQoKSkgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgLy8g5a6/5Li75pyq5bCx57uq5pe25q+PIDNzIOmHjeivlTsg5Y+q6IqC5rWB6K6w5b2V5pel5b+XLCDpgb/lhY3liLflsY/jgIJcbiAgICAgICAgaWYgKGF0dGVtcHQgJSAxMCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgICAgYOaJq+aPj+Wksei0pSgke2F0dGVtcHQgKyAxfS8ke2F0dGVtcHRzID09PSBJbmZpbml0eSA/ICfiiJ4nIDogYXR0ZW1wdHN9KTogJHtcbiAgICAgICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgICAgICAgICB9YCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoYXR0ZW1wdCArIDEgPCBhdHRlbXB0cykgYXdhaXQgc2xlZXAoZGVsYXlNcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaJq+aPj+acgOi/keS4reaWrei/h+eahOS8muivnTog5pyA5ZCO5Zue5ZCI5Lul6Z2e5Lq65Li65Y6f5Zug57uT5p2fLCDkuJTlhbblkI7msqHmnInmlrDlm57lkIjmiJbnlKjmiLfmtojmga/jgIJcbiAgICogQHJldHVybnMg5piv5ZCm5oiQ5Yqf5a6M5oiQ5LiA5qyh5omr5o+PKOWuv+S4u+Wwsee7qinjgIJcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2NhbkludGVycnVwdGVkKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmFwaS5zZXNzaW9ucy5saXN0KHt9KTtcbiAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdC5vaykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGl0ZW1zID0gcmVzcG9uc2UucmVzdWx0LnZhbHVlLml0ZW1zO1xuICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBpdGVtc1xuICAgICAgLmZpbHRlcigoc3VtbWFyeSkgPT4gIXN1bW1hcnkucnVubmluZyAmJiBzdW1tYXJ5LnBhcmVudFNlc3Npb25JZCA9PT0gdW5kZWZpbmVkKVxuICAgICAgLnNsaWNlKDAsIGNvbmZpZy5zY2FuTGltaXQpO1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgZm9yIChjb25zdCBzdW1tYXJ5IG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgIGlmICh0aGlzLmRpc3Bvc2VkKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZShzdW1tYXJ5LnNlc3Npb25JZCk7XG4gICAgICBpZiAoc3RhdGUucGVuZGluZ1RpbWVyICE9PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgaWYgKHN0YXRlLmNvbnNlY3V0aXZlID49IGNvbmZpZy5tYXhDb25zZWN1dGl2ZSkgY29udGludWU7XG4gICAgICBpZiAobm93IC0gc3RhdGUubGFzdEF0dGVtcHRBdCA8IGNvbmZpZy5jb29sZG93bk1zKSBjb250aW51ZTtcbiAgICAgIGxldCBldmVudHM7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5hcGkuc2Vzc2lvbnMuaGlzdG9yeSh7XG4gICAgICAgICAgc2Vzc2lvbklkOiBzdW1tYXJ5LnNlc3Npb25JZCxcbiAgICAgICAgICBtYXhNZXNzYWdlczogMzAsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXBhZ2UucmVzdWx0Lm9rKSBjb250aW51ZTtcbiAgICAgICAgZXZlbnRzID0gcGFnZS5yZXN1bHQudmFsdWUuZXZlbnRzO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIGNvbnRpbnVlOyAvLyDkvJror53lj6/og73liJrooqvnp7vpmaRcbiAgICAgIH1cbiAgICAgIC8vIOS7juWwvumDqOaJvuacgOWQjuS4gOS4qiB0dXJuL2VuZCjlnKjliIbmlK/lhoXlrozmiJDmlLbnqoQpXG4gICAgICBsZXQgbGFzdEVuZDogU2Vzc2lvbkV2ZW50PCd0dXJuL2VuZCc+IHwgdW5kZWZpbmVkO1xuICAgICAgZm9yIChsZXQgaSA9IGV2ZW50cy5sZW5ndGggLSAxOyBpID49IDA7IGkgLT0gMSkge1xuICAgICAgICBjb25zdCBldmVudCA9IGV2ZW50c1tpXT8uZXZlbnQ7XG4gICAgICAgIGlmIChldmVudCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LnR5cGUgPT09ICd0dXJuL2VuZCcpIHtcbiAgICAgICAgICBsYXN0RW5kID0gZXZlbnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChsYXN0RW5kID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgcmVhc29uID0gbGFzdEVuZC5kYXRhLnJlYXNvbjtcbiAgICAgIGlmICghaXNOb25IdW1hblJlYXNvbihyZWFzb24ua2luZCkpIGNvbnRpbnVlO1xuICAgICAgaWYgKGxhc3RFbmQudGltZSA8IG5vdyAtIGNvbmZpZy5mcmVzaE1zKSBjb250aW51ZTsgLy8g5aSq5LmF6L+cLCDkuI3nv7vml6fotKZcbiAgICAgIC8vIOivpSB0dXJuL2VuZCDkuYvlkI7kuI3og73mnInmlrDlm57lkIjmiJbnlKjmiLfmtojmga8o6K+05piO5bey6KKr5aSE55CGKVxuICAgICAgbGV0IHN1cGVyc2VkZWQgPSBmYWxzZTtcbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZXZlbnRzKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gZW50cnkuZXZlbnQ7XG4gICAgICAgIGlmIChldmVudC5zZXEgPD0gbGFzdEVuZC5zZXEpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ3R1cm4vc3RhcnQnKSBzdXBlcnNlZGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICd1c2VyL21lc3NhZ2UnICYmIGV2ZW50LmRhdGEuc291cmNlLmtpbmQgPT09ICd1c2VyJykgc3VwZXJzZWRlZCA9IHRydWU7XG4gICAgICAgIGlmIChzdXBlcnNlZGVkKSBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzdXBlcnNlZGVkKSBjb250aW51ZTtcbiAgICAgIHRoaXMubG9nKGDmiavmj4/lj5HnjrDkuK3mlq0gJHtzdW1tYXJ5LnNlc3Npb25JZH0odHVybi9lbmQ6JHtyZWFzb24ua2luZH0pLCDlronmjpLoh6rliqjnu6fnu61gKTtcbiAgICAgIHRoaXMuc2NoZWR1bGUoc3VtbWFyeS5zZXNzaW9uSWQsIGBzY2FuOnR1cm4vZW5kOiR7cmVhc29uLmtpbmR9YCk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG4iLCAiLyoqXG4gKiBgYXV0by1jb250aW51ZWAgbmFtZXNwYWNlIGRpY3Rpb25hcmllczogY29weSBmb3IgdGhlIHBsdWdpbiBzZXR0aW5ncyBjYXJkXG4gKiByZWdpc3RlcmVkIGludG8gdGhlIGBzZXR0aW5ncy5wbHVnaW4uaXRlbWAgc2VhdCBvZiB0aGUgcGx1Z2luLWNvbmZpZ3VyYXRpb25cbiAqIHNlY3Rpb24uIEluY2x1ZGVzIHRoZSBjYXJkLWNocm9tZSBrZXlzIHRoZSBjYXJkIGNvbXBvbmVudCByZWFkcy5cbiAqL1xuXG4vKiog566A5L2T5Lit5paH6K+N5YW4KOmUrumbhueahOS6i+Wunuadpea6kCnjgIIgKi9cbmV4cG9ydCBjb25zdCB6aCA9IHtcbiAgJ2NhcmQudGl0bGUnOiAn6Ieq5Yqo57un57utJyxcbiAgJ2NhcmQuZGVzY3JpcHRpb24nOiAn6K+35rGC5Zug572R57uc562J5Y6f5ZugKOmdnuS6uuS4uinkuK3mlq3lkI4sIOiHquWKqOWPkemAgeOAjOe7p+e7reOAjee7rei3keOAgicsXG4gICdmaWVsZC5jb250aW51ZVRleHQnOiAn57un57ut5paH5pysJyxcbiAgJ2ZpZWxkLmNvbnRpbnVlVGV4dEhpbnQnOiAn5Lit5pat5ZCO6Ieq5Yqo5Y+R6YCB55qE5raI5oGv5YaF5a6544CCJyxcbiAgJ2ZpZWxkLmdyYWNlTXMnOiAn5a696ZmQ5pyfIChtcyknLFxuICAnZmllbGQuZ3JhY2VNc0hpbnQnOiAn5qOA5rWL5Yiw5Lit5pat5ZCO562J5b6F55qE5pe26ZW/OyDmnJ/pl7Tlrr/kuLvoh6rooYzmgaLlpI3liJnlj5bmtojjgIInLFxuICAnZmllbGQuY29vbGRvd25Ncyc6ICflhrfljbTml7bpl7QgKG1zKScsXG4gICdmaWVsZC5jb29sZG93bk1zSGludCc6ICflkIzkuIDkvJror53kuKTmrKHoh6rliqjjgIznu6fnu63jgI3nmoTmnIDlsI/pl7TpmpQsIOWksei0peWwneivleS5n+iuoeWFpeOAgicsXG4gICdmaWVsZC5tYXhDb25zZWN1dGl2ZSc6ICfmnIDlpKfov57nu63mrKHmlbAnLFxuICAnZmllbGQubWF4Q29uc2VjdXRpdmVIaW50JzogJ+WQjOS4gOS8muivnei/nue7reiHquWKqOOAjOe7p+e7reOAjeeahOS4iumZkDsg6LaF6L+H5ZCO5YGc5q2iLCDnm7TliLDnlKjmiLfmiYvliqjku4vlhaXmiJblh7rnjrDmiJDlip/lm57lkIjjgIInLFxuICAnZmllbGQuc2Nhbk9uQm9vdCc6ICflkK/liqgv6YeN6L+e5omr5o+PJyxcbiAgJ2ZpZWxkLnNjYW5PbkJvb3RIaW50JzogJ+mhtemdouWQr+WKqOaIlumHjei/nuaXtuaJq+aPj+acgOi/keS4reaWreeahOS8muivneW5tuiHquWKqOe7rei3kSjlpoLmtY/op4jlmajlhbPpl63mnJ/pl7Tlrr/kuLvltKnmuoMp44CCJyxcbiAgJ2ZpZWxkLnNjYW5MaW1pdCc6ICfmiavmj4/kvJror53mlbAnLFxuICAnZmllbGQuc2NhbkxpbWl0SGludCc6ICfmnIDlpJrmo4Dmn6XlpJrlsJHkuKrmnIDov5Hmm7TmlrDnmoTkvJror50o5LiN5ZCr6L+Q6KGM5Lit5LiO5a2Q5Luj55CG5Lya6K+dKeOAgicsXG4gICdmaWVsZC5mcmVzaE1zJzogJ+aJq+aPj+aXtumXtOeqlyAobXMpJyxcbiAgJ2ZpZWxkLmZyZXNoTXNIaW50JzogJ+aJq+aPj+WPquWkhOeQhuivpeaXtumXtOeql+WGheeahOS4reaWreOAgicsXG4gICdmaWVsZC5yZWNvbm5lY3RTY2FuRGVsYXlNcyc6ICfph43ov57miavmj4/lu7bov58gKG1zKScsXG4gICdmaWVsZC5yZWNvbm5lY3RTY2FuRGVsYXlNc0hpbnQnOiAn6YeN6L+e5ZCO562J5b6F5a6/5Li75a6M5oiQ5oGi5aSN5YaN5omr5o+P44CCJyxcbiAgJ2ZpZWxkLnJlY29ubmVjdEJhY2tvZmZNcyc6ICfph43ov57pgIDpgb8gKG1zKScsXG4gICdmaWVsZC5yZWNvbm5lY3RCYWNrb2ZmTXNIaW50JzogJ+S6i+S7tua1geaWreW8gOWQjueahOmHjei/numXtOmalOOAgicsXG4gICdmaWVsZC52ZXJib3NlJzogJ+ivpue7huaXpeW/lycsXG4gICdmaWVsZC52ZXJib3NlSGludCc6ICflnKjmtY/op4jlmajmjqfliLblj7DovpPlh7ogW2F1dG8tY29udGludWVdIOaXpeW/l+OAgicsXG4gICdjaHJvbWUuY29sbGFwc2UnOiAn5pS26LW36K6+572uJyxcbiAgJ2Nocm9tZS5leHBhbmQnOiAn5bGV5byA6K6+572uJyxcbiAgJ2Nocm9tZS51bnNhdmVkJzogJ+acquS/neWtmCcsXG4gICdjaHJvbWUucmVhZE9ubHknOiAn5b2T5YmN6YOo572y55qE6K6+572u5Y+q6K+744CCJyxcbiAgJ2Nocm9tZS5zYXZlRmFpbGVkJzogJ+mDqOe9suacquaOpeWPl+i/meS6m+WAvCwg5bey5L+d55WZ5L6b5L2g5L+u5pS544CCJyxcbiAgJ2Nocm9tZS5kaXNjYXJkJzogJ+aUvuW8gycsXG4gICdjaHJvbWUuc2F2aW5nJzogJ+S/neWtmOS4reKApicsXG4gICdjaHJvbWUuc2F2ZSc6ICfkv53lrZgnLFxuICAnY2hyb21lLm92ZXJyaWRkZW4nOiAn5bey6KaG55uWJyxcbiAgJ2Nocm9tZS5yZXNldCc6ICfmgaLlpI3pu5jorqQnLFxuICAnY2hyb21lLmludmFsaWROdW1iZXInOiAn6K+36L6T5YWl5pWw5a2XLCDnlZnnqbrliJnkvb/nlKjpu5jorqTlgLzjgIInLFxuICAnY2hyb21lLmluaGVyaXQnOiAn57un5om/JyxcbiAgJ2Nocm9tZS5vbic6ICflvIAnLFxuICAnY2hyb21lLm9mZic6ICflhbMnLFxufSBzYXRpc2ZpZXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuLyoqIOacrOaPkuS7tueahOmUruiBlOWQiOOAgiAqL1xuZXhwb3J0IHR5cGUgU2V0dGluZ3NDYXJkS2V5ID0ga2V5b2YgdHlwZW9mIHpoO1xuXG4vKiogRW5nbGlzaCBkaWN0aW9uYXJ5LCBjaGVja2VkIGNvbXBsZXRlIGFnYWluc3QgdGhlIHpoIGtleSBzZXQuICovXG5leHBvcnQgY29uc3QgZW46IFJlY29yZDxTZXR0aW5nc0NhcmRLZXksIHN0cmluZz4gPSB7XG4gICdjYXJkLnRpdGxlJzogJ0F1dG8gY29udGludWUnLFxuICAnY2FyZC5kZXNjcmlwdGlvbic6ICdXaGVuIGEgcmVxdWVzdCBpcyBpbnRlcnJ1cHRlZCBieSBhIG5vbi1odW1hbiBjYXVzZSwgYXV0b21hdGljYWxseSBzZW5kIOOAjOe7p+e7reOAjSB0byByZXN1bWUuJyxcbiAgJ2ZpZWxkLmNvbnRpbnVlVGV4dCc6ICdDb250aW51ZSB0ZXh0JyxcbiAgJ2ZpZWxkLmNvbnRpbnVlVGV4dEhpbnQnOiAnTWVzc2FnZSBhdXRvbWF0aWNhbGx5IHNlbnQgYWZ0ZXIgYW4gaW50ZXJydXB0aW9uLicsXG4gICdmaWVsZC5ncmFjZU1zJzogJ0dyYWNlIHBlcmlvZCAobXMpJyxcbiAgJ2ZpZWxkLmdyYWNlTXNIaW50JzogJ1dhaXQgYWZ0ZXIgYW4gaW50ZXJydXB0aW9uOyBjYW5jZWxsZWQgaWYgdGhlIGhvc3QgcmVjb3ZlcnMgb24gaXRzIG93bi4nLFxuICAnZmllbGQuY29vbGRvd25Ncyc6ICdDb29sZG93biAobXMpJyxcbiAgJ2ZpZWxkLmNvb2xkb3duTXNIaW50JzogJ01pbmltdW0gaW50ZXJ2YWwgYmV0d2VlbiBhdXRvLWNvbnRpbnVlcyBwZXIgc2Vzc2lvbjsgZmFpbGVkIGF0dGVtcHRzIGNvdW50IHRvby4nLFxuICAnZmllbGQubWF4Q29uc2VjdXRpdmUnOiAnTWF4IGNvbnNlY3V0aXZlJyxcbiAgJ2ZpZWxkLm1heENvbnNlY3V0aXZlSGludCc6ICdNYXggY29uc2VjdXRpdmUgYXV0by1jb250aW51ZXMgcGVyIHNlc3Npb247IHN0b3BzIHVudGlsIGEgdXNlciBpbnRlcnZlbmVzIG9yIGEgdHVybiBjb21wbGV0ZXMuJyxcbiAgJ2ZpZWxkLnNjYW5PbkJvb3QnOiAnU2NhbiBvbiBsb2FkIC8gcmVjb25uZWN0JyxcbiAgJ2ZpZWxkLnNjYW5PbkJvb3RIaW50JzogJ1NjYW4gcmVjZW50bHkgaW50ZXJydXB0ZWQgc2Vzc2lvbnMgb24gcGFnZSBsb2FkIG9yIHJlY29ubmVjdCAoZS5nLiB0aGUgaG9zdCBjcmFzaGVkIHdoaWxlIHRoZSBicm93c2VyIHdhcyBjbG9zZWQpLicsXG4gICdmaWVsZC5zY2FuTGltaXQnOiAnU2NhbiBsaW1pdCcsXG4gICdmaWVsZC5zY2FuTGltaXRIaW50JzogJ0hvdyBtYW55IG1vc3QtcmVjZW50bHktdXBkYXRlZCBzZXNzaW9ucyB0byBjaGVjayAocnVubmluZyAvIHN1YmFnZW50IHNlc3Npb25zIGV4Y2x1ZGVkKS4nLFxuICAnZmllbGQuZnJlc2hNcyc6ICdTY2FuIHdpbmRvdyAobXMpJyxcbiAgJ2ZpZWxkLmZyZXNoTXNIaW50JzogJ09ubHkgaW50ZXJydXB0aW9ucyBpbnNpZGUgdGhpcyB3aW5kb3cgYXJlIGNvbnNpZGVyZWQuJyxcbiAgJ2ZpZWxkLnJlY29ubmVjdFNjYW5EZWxheU1zJzogJ1JlY29ubmVjdCBzY2FuIGRlbGF5IChtcyknLFxuICAnZmllbGQucmVjb25uZWN0U2NhbkRlbGF5TXNIaW50JzogJ1dhaXQgZm9yIHRoZSBob3N0IHRvIGZpbmlzaCByZWNvdmVyaW5nIGJlZm9yZSBzY2FubmluZyBhZnRlciBhIHJlY29ubmVjdC4nLFxuICAnZmllbGQucmVjb25uZWN0QmFja29mZk1zJzogJ1JlY29ubmVjdCBiYWNrb2ZmIChtcyknLFxuICAnZmllbGQucmVjb25uZWN0QmFja29mZk1zSGludCc6ICdJbnRlcnZhbCBiZXR3ZWVuIGV2ZW50LXN0cmVhbSByZWNvbm5lY3QgYXR0ZW1wdHMuJyxcbiAgJ2ZpZWxkLnZlcmJvc2UnOiAnVmVyYm9zZSBsb2dzJyxcbiAgJ2ZpZWxkLnZlcmJvc2VIaW50JzogJ0xvZyBbYXV0by1jb250aW51ZV0gbGluZXMgdG8gdGhlIGJyb3dzZXIgY29uc29sZS4nLFxuICAnY2hyb21lLmNvbGxhcHNlJzogJ0hpZGUgc2V0dGluZ3MnLFxuICAnY2hyb21lLmV4cGFuZCc6ICdTaG93IHNldHRpbmdzJyxcbiAgJ2Nocm9tZS51bnNhdmVkJzogJ1Vuc2F2ZWQnLFxuICAnY2hyb21lLnJlYWRPbmx5JzogJ1RoaXMgZGVwbG95bWVudCBzdG9yZXMgc2V0dGluZ3MgcmVhZC1vbmx5LicsXG4gICdjaHJvbWUuc2F2ZUZhaWxlZCc6ICdUaGUgZGVwbG95bWVudCBkaWQgbm90IGFjY2VwdCB0aGVzZSB2YWx1ZXM7IHRoZXkgd2VyZSBsZWZ0IGZvciB5b3UgdG8gY29ycmVjdC4nLFxuICAnY2hyb21lLmRpc2NhcmQnOiAnRGlzY2FyZCcsXG4gICdjaHJvbWUuc2F2aW5nJzogJ1NhdmluZ+KApicsXG4gICdjaHJvbWUuc2F2ZSc6ICdTYXZlJyxcbiAgJ2Nocm9tZS5vdmVycmlkZGVuJzogJ092ZXJyaWRkZW4nLFxuICAnY2hyb21lLnJlc2V0JzogJ1Jlc2V0IHRvIGRlZmF1bHQnLFxuICAnY2hyb21lLmludmFsaWROdW1iZXInOiAnRW50ZXIgYSBudW1iZXIsIG9yIGxlYXZlIGJsYW5rIHRvIHVzZSB0aGUgZGVmYXVsdC4nLFxuICAnY2hyb21lLmluaGVyaXQnOiAnSW5oZXJpdCcsXG4gICdjaHJvbWUub24nOiAnT24nLFxuICAnY2hyb21lLm9mZic6ICdPZmYnLFxufTtcbiIsICIvKipcbiAqIFRoZSBhdXRvLWNvbnRpbnVlIHNldHRpbmdzIGNhcmQ6IGVkaXRzIHRoZSBgYXV0by1jb250aW51ZWAgbmFtZXNwYWNlIGZpZWxkc1xuICogZnJvbSB0aGUgcGx1Z2luLWNvbmZpZ3VyYXRpb24gc2VjdGlvbiAodGhlIGBzZXR0aW5ncy5wbHVnaW4uaXRlbWAgc2VhdCkuXG4gKlxuICogU2VsZi1jb250YWluZWQgY2FyZCBjaHJvbWUgKGRpc2Nsb3N1cmUgaGVhZGVyLCBzdGFnZWQgZmllbGRzLCBzYXZlL2Rpc2NhcmRcbiAqIGZvb3RlcikgZm9sbG93aW5nIHRoZSBwbHVnaW4tY2FyZCBzdG9yZSBwYXR0ZXJuIG9mIHRoZSBEU0ggcGx1Z2luXG4gKiBjb25maWd1cmF0aW9uIHNlY3Rpb247IHN0eWxlcyBsaXZlIGluIGBzdHlsZXMudHNgIGFuZCB1c2UgdGhlIERTSCBkZXNpZ25cbiAqIHRva2VucyBzbyB0aGUgY2FyZCBmb2xsb3dzIHRoZSBhY3RpdmUgdGhlbWUuXG4gKi9cbmltcG9ydCB7IHVzZVN0YXRlLCB0eXBlIFJlYWN0Tm9kZSB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGNyZWF0ZVNuYXBzaG90U3RvcmUsIHR5cGUgU2V0dGluZ3NTY29wZSwgdHlwZSBTbmFwc2hvdFN0b3JlIH0gZnJvbSAnQGRlZXBzZWVrLWFpL2RzaC1jbGllbnQtcnVudGltZS9jbGllbnQnO1xuaW1wb3J0IHR5cGUgeyBJbmplY3RGYWNlLCBQcm9wc0xvY2FsZSwgUHJvcHNSdW50aW1lIH0gZnJvbSAnQGRlZXBzZWVrLWFpL2RzaC1jbGllbnQtdWktc2xvdHMnO1xuaW1wb3J0IHR5cGUgeyBBdXRvQ29udGludWVTZXR0aW5ncyB9IGZyb20gJy4vZW5naW5lLnRzJztcbmltcG9ydCB0eXBlIHsgU2V0dGluZ3NDYXJkS2V5IH0gZnJvbSAnLi9sb2NhbGVzLnRzJztcbmltcG9ydCB7XG4gIGJvb2xlYW5GaWVsZCxcbiAgQ2FyZEZvcm0sXG4gIG51bWJlckZpZWxkLFxuICB0ZXh0RmllbGQsXG4gIHR5cGUgQ2FyZEFjdGlvbnMsXG4gIHR5cGUgQ2FyZEZpZWxkU3RhdGUsXG4gIHR5cGUgQ2FyZFNoZWxsLFxufSBmcm9tICcuL3NldHRpbmdzLWZvcm0udHMnO1xuaW1wb3J0IHsgaW5qZWN0U3R5bGVzIH0gZnJvbSAnLi9zdHlsZXMudHMnO1xuXG4vLyBTdHlsZXMgbXVzdCBsYW5kIGR1cmluZyBmYWN0b3J5IG1hdGVyaWFsaXphdGlvbiBzbyB0aGUgbW9kdWxlIHN5c3RlbSdzXG4vLyBzdHlsZSBib29ra2VlcGluZyAoSE1SKSBvd25zIHRoZW0uXG5pbmplY3RTdHlsZXMoKTtcblxuLyoqIFdoYXQgdGhlIGF1dG8tY29udGludWUgY2FyZCByZW5kZXJzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRvQ29udGludWVTZXR0aW5nc0NhcmRTdGF0ZSBleHRlbmRzIENhcmRTaGVsbCB7XG4gIGNvbnRpbnVlVGV4dDogQ2FyZEZpZWxkU3RhdGU7XG4gIGdyYWNlTXM6IENhcmRGaWVsZFN0YXRlO1xuICBjb29sZG93bk1zOiBDYXJkRmllbGRTdGF0ZTtcbiAgbWF4Q29uc2VjdXRpdmU6IENhcmRGaWVsZFN0YXRlO1xuICBzY2FuT25Cb290OiBDYXJkRmllbGRTdGF0ZTtcbiAgc2NhbkxpbWl0OiBDYXJkRmllbGRTdGF0ZTtcbiAgZnJlc2hNczogQ2FyZEZpZWxkU3RhdGU7XG4gIHJlY29ubmVjdFNjYW5EZWxheU1zOiBDYXJkRmllbGRTdGF0ZTtcbiAgcmVjb25uZWN0QmFja29mZk1zOiBDYXJkRmllbGRTdGF0ZTtcbiAgdmVyYm9zZTogQ2FyZEZpZWxkU3RhdGU7XG59XG5cbi8qKiBUaGUgcmVnaXN0cmF0aW9uLXNpZGUgZmFjZSB0aGUgY2FyZCdzIHNsb3QgZW50cnkgaW5qZWN0cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkRmFjZSBleHRlbmRzIENhcmRBY3Rpb25zIHtcbiAgaG9va3M6IHtcbiAgICAvKiogQ2FyZCBzbmFwc2hvdCBib3VuZCBieSB0aGUgcmVuZGVyZXIgYXMgdXNlQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkLiAqL1xuICAgIGF1dG9Db250aW51ZVNldHRpbmdzQ2FyZDogU25hcHNob3RTdG9yZTxBdXRvQ29udGludWVTZXR0aW5nc0NhcmRTdGF0ZT47XG4gIH07XG59XG5cbi8qKiBCcmlkZ2VzIHRoZSBgYXV0by1jb250aW51ZWAgc2NvcGUgb250byB0aGUgY2FyZCdzIHN0YWdlZCBmb3JtLiAqL1xuZXhwb3J0IGNsYXNzIEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZENvbnRyb2xsZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGZvcm06IENhcmRGb3JtPEF1dG9Db250aW51ZVNldHRpbmdzPjtcbiAgcHJpdmF0ZSByZWFkb25seSBzdG9yZTogU25hcHNob3RTdG9yZTxBdXRvQ29udGludWVTZXR0aW5nc0NhcmRTdGF0ZT47XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBzY29wZSAtIHRoZSBib3VuZCBzZXR0aW5ncyBzY29wZSBmb3IgdGhlIGBhdXRvLWNvbnRpbnVlYCBuYW1lc3BhY2UuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogU2V0dGluZ3NTY29wZTxBdXRvQ29udGludWVTZXR0aW5ncz4pIHtcbiAgICB0aGlzLmZvcm0gPSBuZXcgQ2FyZEZvcm0oc2NvcGUsIFtcbiAgICAgIHRleHRGaWVsZCgnY29udGludWVUZXh0JyksXG4gICAgICBudW1iZXJGaWVsZCgnZ3JhY2VNcycsIDApLFxuICAgICAgbnVtYmVyRmllbGQoJ2Nvb2xkb3duTXMnLCAwKSxcbiAgICAgIG51bWJlckZpZWxkKCdtYXhDb25zZWN1dGl2ZScsIDEpLFxuICAgICAgYm9vbGVhbkZpZWxkKCdzY2FuT25Cb290JyksXG4gICAgICBudW1iZXJGaWVsZCgnc2NhbkxpbWl0JywgMSksXG4gICAgICBudW1iZXJGaWVsZCgnZnJlc2hNcycsIDApLFxuICAgICAgbnVtYmVyRmllbGQoJ3JlY29ubmVjdFNjYW5EZWxheU1zJywgMCksXG4gICAgICBudW1iZXJGaWVsZCgncmVjb25uZWN0QmFja29mZk1zJywgMCksXG4gICAgICBib29sZWFuRmllbGQoJ3ZlcmJvc2UnKSxcbiAgICBdKTtcbiAgICB0aGlzLnN0b3JlID0gdGhpcy5mb3JtLmJpbmQoKCkgPT4gdGhpcy5wcm9qZWN0aW9uKCksIGNyZWF0ZVNuYXBzaG90U3RvcmUpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9qZWN0aW9uKCk6IEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZFN0YXRlIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5mb3JtLnNoZWxsKCksXG4gICAgICBjb250aW51ZVRleHQ6IHRoaXMuZm9ybS5maWVsZCgnY29udGludWVUZXh0JyksXG4gICAgICBncmFjZU1zOiB0aGlzLmZvcm0uZmllbGQoJ2dyYWNlTXMnKSxcbiAgICAgIGNvb2xkb3duTXM6IHRoaXMuZm9ybS5maWVsZCgnY29vbGRvd25NcycpLFxuICAgICAgbWF4Q29uc2VjdXRpdmU6IHRoaXMuZm9ybS5maWVsZCgnbWF4Q29uc2VjdXRpdmUnKSxcbiAgICAgIHNjYW5PbkJvb3Q6IHRoaXMuZm9ybS5maWVsZCgnc2Nhbk9uQm9vdCcpLFxuICAgICAgc2NhbkxpbWl0OiB0aGlzLmZvcm0uZmllbGQoJ3NjYW5MaW1pdCcpLFxuICAgICAgZnJlc2hNczogdGhpcy5mb3JtLmZpZWxkKCdmcmVzaE1zJyksXG4gICAgICByZWNvbm5lY3RTY2FuRGVsYXlNczogdGhpcy5mb3JtLmZpZWxkKCdyZWNvbm5lY3RTY2FuRGVsYXlNcycpLFxuICAgICAgcmVjb25uZWN0QmFja29mZk1zOiB0aGlzLmZvcm0uZmllbGQoJ3JlY29ubmVjdEJhY2tvZmZNcycpLFxuICAgICAgdmVyYm9zZTogdGhpcy5mb3JtLmZpZWxkKCd2ZXJib3NlJyksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgZmFjZSB0aGUgY2FyZCdzIHNsb3QgcmVnaXN0cmF0aW9uIGluamVjdHMuXG4gICAqIEByZXR1cm5zIHRoZSBjYXJkJ3Mgc25hcHNob3QgYW5kIGl0cyBmb3JtIGFjdGlvbnMuXG4gICAqL1xuICBpbmplY3QoKTogQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkRmFjZSB7XG4gICAgcmV0dXJuIHsgaG9va3M6IHsgYXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkOiB0aGlzLnN0b3JlIH0sIC4uLnRoaXMuZm9ybS5hY3Rpb25zKCkgfTtcbiAgfVxufVxuXG4vKiogUHJvcHMgdGhlIHJlbmRlcmVyIGJpbmRzIGZvciB0aGUgYXV0by1jb250aW51ZSBjYXJkLiAqL1xuZXhwb3J0IHR5cGUgQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkUHJvcHMgPVxuICBQcm9wc1J1bnRpbWU8J3NldHRpbmdzLnBsdWdpbi5pdGVtJz4gJiBQcm9wc0xvY2FsZTwnYXV0by1jb250aW51ZSc+ICYgSW5qZWN0RmFjZTxBdXRvQ29udGludWVTZXR0aW5nc0NhcmRGYWNlPjtcblxuLyoqIENhcmQgY2hyb21lOiBhIGRpc2Nsb3N1cmUgaGVhZGVyIG5hbWluZyB0aGUgcGx1Z2luIGFuZCB3aGF0IGl0cyBzZXR0aW5ncyBnb3Zlcm4sIHRoZSBjb250cm9scywgYW5kIHRoZSBzYXZlIHRoYXQgd3JpdGVzIHRoZW0uICovXG5mdW5jdGlvbiBTZXR0aW5nc0NhcmQocHJvcHM6IHtcbiAgdDogKGtleTogU2V0dGluZ3NDYXJkS2V5KSA9PiBzdHJpbmc7XG4gIHRpdGxlS2V5OiBTZXR0aW5nc0NhcmRLZXk7XG4gIGRlc2NyaXB0aW9uS2V5OiBTZXR0aW5nc0NhcmRLZXk7XG4gIHN0YXRlOiBDYXJkU2hlbGw7XG4gIG9uU2F2ZTogKCkgPT4gdm9pZDtcbiAgb25EaXNjYXJkOiAoKSA9PiB2b2lkO1xuICBjaGlsZHJlbjogUmVhY3ROb2RlO1xufSkge1xuICBjb25zdCBbb3Blbiwgc2V0T3Blbl0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIGNvbnN0IHsgc3RhdGUgfSA9IHByb3BzO1xuICBpZiAoIXN0YXRlLmF2YWlsYWJsZSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHRpdGxlID0gcHJvcHMudChwcm9wcy50aXRsZUtleSk7XG4gIGNvbnN0IGJsb2NrZWQgPSAhc3RhdGUuZGlydHkgfHwgc3RhdGUuaW52YWxpZCB8fCBzdGF0ZS5zYXZpbmc7XG4gIHJldHVybiAoXG4gICAgPGxpIGNsYXNzTmFtZT17b3BlbiA/ICdkc2hBY0NhcmQgZHNoQWNDYXJkT3BlbicgOiAnZHNoQWNDYXJkJ30+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzc05hbWU9XCJkc2hBY0hlYWRlclwiXG4gICAgICAgIGFyaWEtZXhwYW5kZWQ9e29wZW59XG4gICAgICAgIGFyaWEtbGFiZWw9e2Ake3Byb3BzLnQob3BlbiA/ICdjaHJvbWUuY29sbGFwc2UnIDogJ2Nocm9tZS5leHBhbmQnKX06ICR7dGl0bGV9YH1cbiAgICAgICAgdGl0bGU9e3Byb3BzLnQocHJvcHMuZGVzY3JpcHRpb25LZXkpfVxuICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXRPcGVuKCFvcGVuKX1cbiAgICAgID5cbiAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwiZHNoQWNIZWFkVGV4dFwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImRzaEFjTmFtZVwiPnt0aXRsZX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwiZHNoQWNEZXNjcmlwdGlvblwiPntwcm9wcy50KHByb3BzLmRlc2NyaXB0aW9uS2V5KX08L3NwYW4+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAge3N0YXRlLmRpcnR5ID8gKFxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImRzaEFjUGVuZGluZ1wiIHRpdGxlPXtwcm9wcy50KCdjaHJvbWUudW5zYXZlZCcpfT5cbiAgICAgICAgICAgIHtwcm9wcy50KCdjaHJvbWUudW5zYXZlZCcpfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgKSA6IG51bGx9XG4gICAgICAgIDxzcGFuIGNsYXNzTmFtZT17b3BlbiA/ICdkc2hBY0NoZXZyb24gZHNoQWNDaGV2cm9uT3BlbicgOiAnZHNoQWNDaGV2cm9uJ30+4pa+PC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgICB7b3BlbiA/IChcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJkc2hBY0JvZHlcIj5cbiAgICAgICAgICB7IXN0YXRlLndyaXRhYmxlID8gKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPVwiZHNoQWNSZWFkT25seVwiIHJvbGU9XCJzdGF0dXNcIj57cHJvcHMudCgnY2hyb21lLnJlYWRPbmx5Jyl9PC9wPlxuICAgICAgICAgICkgOiBudWxsfVxuICAgICAgICAgIHtwcm9wcy5jaGlsZHJlbn1cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImRzaEFjRm9vdGVyXCI+XG4gICAgICAgICAgICB7c3RhdGUuZmFpbGVkID8gKFxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9XCJkc2hBY0ZhaWxlZFwiIHJvbGU9XCJzdGF0dXNcIj57cHJvcHMudCgnY2hyb21lLnNhdmVGYWlsZWQnKX08L3A+XG4gICAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzTmFtZT1cImRzaEFjRGlzY2FyZFwiXG4gICAgICAgICAgICAgIGRpc2FibGVkPXshc3RhdGUuZGlydHkgfHwgc3RhdGUuc2F2aW5nfVxuICAgICAgICAgICAgICBvbkNsaWNrPXtwcm9wcy5vbkRpc2NhcmR9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHtwcm9wcy50KCdjaHJvbWUuZGlzY2FyZCcpfVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzc05hbWU9XCJkc2hBY1NhdmVcIiBkaXNhYmxlZD17YmxvY2tlZH0gb25DbGljaz17cHJvcHMub25TYXZlfT5cbiAgICAgICAgICAgICAge3Byb3BzLnQoIXN0YXRlLnNhdmluZyA/ICdjaHJvbWUuc2F2ZScgOiAnY2hyb21lLnNhdmluZycpfVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKSA6IG51bGx9XG4gICAgPC9saT5cbiAgKTtcbn1cblxuLyoqIFByb3BzIGV2ZXJ5IGZpZWxkIGNvbnRyb2wgbmVlZHMgcmVnYXJkbGVzcyBvZiBpdHMgdmFsdWUgdHlwZS4gKi9cbmludGVyZmFjZSBGaWVsZFByb3BzIHtcbiAgaWQ6IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZztcbiAgaGludDogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG4gIG92ZXJyaWRkZW46IGJvb2xlYW47XG4gIGludmFsaWQ6IGJvb2xlYW47XG4gIGRpc2FibGVkOiBib29sZWFuO1xuICB0OiAoa2V5OiBTZXR0aW5nc0NhcmRLZXkpID0+IHN0cmluZztcbiAgb25FZGl0OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkO1xuICBvblJlc2V0OiAoKSA9PiB2b2lkO1xufVxuXG4vKiogQSBzdGFnZWQgdmFsdWUgZmllbGQ7IGBudW1lcmljYCBvbmx5IGhpbnRzIHRoZSBrZXlwYWQsIHdoaWNoIGRyYWZ0cyBhIGZpZWxkIGFjY2VwdHMgaXMgZGVjaWRlZCBieSBpdHMgc3BlYy4gKi9cbmZ1bmN0aW9uIFZhbHVlRmllbGQocHJvcHM6IEZpZWxkUHJvcHMgJiB7IG51bWVyaWM/OiBib29sZWFuOyBwbGFjZWhvbGRlcj86IHN0cmluZyB9KSB7XG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJkc2hBY0ZpZWxkXCI+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImRzaEFjSGVhZFwiPlxuICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPVwiZHNoQWNMYWJlbFwiIGh0bWxGb3I9e3Byb3BzLmlkfT57cHJvcHMubGFiZWx9PC9sYWJlbD5cbiAgICAgICAge3Byb3BzLm92ZXJyaWRkZW4gPyAoXG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwiZHNoQWNCYWRnZXNcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImRzaEFjQmFkZ2VcIj57cHJvcHMudCgnY2hyb21lLm92ZXJyaWRkZW4nKX08L3NwYW4+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzc05hbWU9XCJkc2hBY1Jlc2V0XCIgZGlzYWJsZWQ9e3Byb3BzLmRpc2FibGVkfSBvbkNsaWNrPXtwcm9wcy5vblJlc2V0fT5cbiAgICAgICAgICAgICAge3Byb3BzLnQoJ2Nocm9tZS5yZXNldCcpfVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICApIDogbnVsbH1cbiAgICAgIDwvZGl2PlxuICAgICAgPGlucHV0XG4gICAgICAgIGlkPXtwcm9wcy5pZH1cbiAgICAgICAgY2xhc3NOYW1lPXtwcm9wcy5pbnZhbGlkID8gJ2RzaEFjSW5wdXQgZHNoQWNJbnB1dEludmFsaWQnIDogJ2RzaEFjSW5wdXQnfVxuICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgIGlucHV0TW9kZT17cHJvcHMubnVtZXJpYyA9PT0gdHJ1ZSA/ICdudW1lcmljJyA6IHVuZGVmaW5lZH1cbiAgICAgICAgYXJpYS1pbnZhbGlkPXtwcm9wcy5pbnZhbGlkIHx8IHVuZGVmaW5lZH1cbiAgICAgICAgdmFsdWU9e3Byb3BzLnRleHR9XG4gICAgICAgIHBsYWNlaG9sZGVyPXtwcm9wcy5wbGFjZWhvbGRlciA/PyAnJ31cbiAgICAgICAgZGlzYWJsZWQ9e3Byb3BzLmRpc2FibGVkfVxuICAgICAgICBvbkNoYW5nZT17KGV2ZW50KSA9PiBwcm9wcy5vbkVkaXQoZXZlbnQudGFyZ2V0LnZhbHVlKX1cbiAgICAgIC8+XG4gICAgICA8cCBjbGFzc05hbWU9e3Byb3BzLmludmFsaWQgPyAnZHNoQWNJbnZhbGlkJyA6ICdkc2hBY0hpbnQnfT5cbiAgICAgICAge3Byb3BzLmludmFsaWQgPyBwcm9wcy50KCdjaHJvbWUuaW52YWxpZE51bWJlcicpIDogcHJvcHMuaGludH1cbiAgICAgIDwvcD5cbiAgICA8L2Rpdj5cbiAgKTtcbn1cblxuLyoqIEEgc3RhZ2VkIGJvb2xlYW4gZmllbGQ6IGluaGVyaXQgLyBvbiAvIG9mZi4gKi9cbmZ1bmN0aW9uIEJvb2xlYW5GaWVsZChwcm9wczogRmllbGRQcm9wcykge1xuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwiZHNoQWNGaWVsZFwiPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJkc2hBY0hlYWRcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzTmFtZT1cImRzaEFjTGFiZWxcIiBodG1sRm9yPXtwcm9wcy5pZH0+e3Byb3BzLmxhYmVsfTwvbGFiZWw+XG4gICAgICAgIHtwcm9wcy5vdmVycmlkZGVuID8gKFxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImRzaEFjQmFkZ2VzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJkc2hBY0JhZGdlXCI+e3Byb3BzLnQoJ2Nocm9tZS5vdmVycmlkZGVuJyl9PC9zcGFuPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3NOYW1lPVwiZHNoQWNSZXNldFwiIGRpc2FibGVkPXtwcm9wcy5kaXNhYmxlZH0gb25DbGljaz17cHJvcHMub25SZXNldH0+XG4gICAgICAgICAgICAgIHtwcm9wcy50KCdjaHJvbWUucmVzZXQnKX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgKSA6IG51bGx9XG4gICAgICA8L2Rpdj5cbiAgICAgIDxzZWxlY3RcbiAgICAgICAgaWQ9e3Byb3BzLmlkfVxuICAgICAgICBjbGFzc05hbWU9XCJkc2hBY1NlbGVjdFwiXG4gICAgICAgIHZhbHVlPXtwcm9wcy50ZXh0fVxuICAgICAgICBkaXNhYmxlZD17cHJvcHMuZGlzYWJsZWR9XG4gICAgICAgIG9uQ2hhbmdlPXsoZXZlbnQpID0+IHByb3BzLm9uRWRpdChldmVudC50YXJnZXQudmFsdWUpfVxuICAgICAgPlxuICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+e3Byb3BzLnQoJ2Nocm9tZS5pbmhlcml0Jyl9PC9vcHRpb24+XG4gICAgICAgIDxvcHRpb24gdmFsdWU9XCJ0cnVlXCI+e3Byb3BzLnQoJ2Nocm9tZS5vbicpfTwvb3B0aW9uPlxuICAgICAgICA8b3B0aW9uIHZhbHVlPVwiZmFsc2VcIj57cHJvcHMudCgnY2hyb21lLm9mZicpfTwvb3B0aW9uPlxuICAgICAgPC9zZWxlY3Q+XG4gICAgICA8cCBjbGFzc05hbWU9XCJkc2hBY0hpbnRcIj57cHJvcHMuaGludH08L3A+XG4gICAgPC9kaXY+XG4gICk7XG59XG5cbi8qKlxuICogUmVuZGVyIHRoZSBhdXRvLWNvbnRpbnVlIGNhcmQuXG4gKiBAcGFyYW0gcHJvcHMgLSBsb2NhbGUgY29weSwgdGhlIGNhcmQgc25hcHNob3QsIGFuZCBpdHMgZm9ybSBhY3Rpb25zLlxuICogQHJldHVybnMgdGhlIGNhcmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBBdXRvQ29udGludWVTZXR0aW5nc0NhcmQocHJvcHM6IEF1dG9Db250aW51ZVNldHRpbmdzQ2FyZFByb3BzKSB7XG4gIGNvbnN0IHsgdCB9ID0gcHJvcHM7XG4gIGNvbnN0IHN0YXRlID0gcHJvcHMudXNlQXV0b0NvbnRpbnVlU2V0dGluZ3NDYXJkKChzbmFwc2hvdCkgPT4gc25hcHNob3QpO1xuICBjb25zdCBkaXNhYmxlZCA9ICFzdGF0ZS53cml0YWJsZTtcbiAgY29uc3Qgc2hhcmVkID0geyB0LCBkaXNhYmxlZCB9O1xuICByZXR1cm4gKFxuICAgIDxTZXR0aW5nc0NhcmRcbiAgICAgIHQ9e3R9XG4gICAgICB0aXRsZUtleT1cImNhcmQudGl0bGVcIlxuICAgICAgZGVzY3JpcHRpb25LZXk9XCJjYXJkLmRlc2NyaXB0aW9uXCJcbiAgICAgIHN0YXRlPXtzdGF0ZX1cbiAgICAgIG9uU2F2ZT17cHJvcHMuc2F2ZX1cbiAgICAgIG9uRGlzY2FyZD17cHJvcHMuZGlzY2FyZH1cbiAgICA+XG4gICAgICA8VmFsdWVGaWVsZFxuICAgICAgICBpZD1cImF1dG8tY29udGludWUtY29udGludWUtdGV4dFwiXG4gICAgICAgIGxhYmVsPXt0KCdmaWVsZC5jb250aW51ZVRleHQnKX1cbiAgICAgICAgaGludD17dCgnZmllbGQuY29udGludWVUZXh0SGludCcpfVxuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUuY29udGludWVUZXh0fVxuICAgICAgICBvbkVkaXQ9eyh0ZXh0KSA9PiBwcm9wcy5lZGl0KCdjb250aW51ZVRleHQnLCB0ZXh0KX1cbiAgICAgICAgb25SZXNldD17KCkgPT4gcHJvcHMucmVzZXRGaWVsZCgnY29udGludWVUZXh0Jyl9XG4gICAgICAvPlxuICAgICAgPFZhbHVlRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLWdyYWNlLW1zXCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLmdyYWNlTXMnKX1cbiAgICAgICAgaGludD17dCgnZmllbGQuZ3JhY2VNc0hpbnQnKX1cbiAgICAgICAgbnVtZXJpY1xuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUuZ3JhY2VNc31cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgnZ3JhY2VNcycsIHRleHQpfVxuICAgICAgICBvblJlc2V0PXsoKSA9PiBwcm9wcy5yZXNldEZpZWxkKCdncmFjZU1zJyl9XG4gICAgICAvPlxuICAgICAgPFZhbHVlRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLWNvb2xkb3duLW1zXCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLmNvb2xkb3duTXMnKX1cbiAgICAgICAgaGludD17dCgnZmllbGQuY29vbGRvd25Nc0hpbnQnKX1cbiAgICAgICAgbnVtZXJpY1xuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUuY29vbGRvd25Nc31cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgnY29vbGRvd25NcycsIHRleHQpfVxuICAgICAgICBvblJlc2V0PXsoKSA9PiBwcm9wcy5yZXNldEZpZWxkKCdjb29sZG93bk1zJyl9XG4gICAgICAvPlxuICAgICAgPFZhbHVlRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLW1heC1jb25zZWN1dGl2ZVwiXG4gICAgICAgIGxhYmVsPXt0KCdmaWVsZC5tYXhDb25zZWN1dGl2ZScpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC5tYXhDb25zZWN1dGl2ZUhpbnQnKX1cbiAgICAgICAgbnVtZXJpY1xuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUubWF4Q29uc2VjdXRpdmV9XG4gICAgICAgIG9uRWRpdD17KHRleHQpID0+IHByb3BzLmVkaXQoJ21heENvbnNlY3V0aXZlJywgdGV4dCl9XG4gICAgICAgIG9uUmVzZXQ9eygpID0+IHByb3BzLnJlc2V0RmllbGQoJ21heENvbnNlY3V0aXZlJyl9XG4gICAgICAvPlxuICAgICAgPEJvb2xlYW5GaWVsZFxuICAgICAgICBpZD1cImF1dG8tY29udGludWUtc2Nhbi1vbi1ib290XCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLnNjYW5PbkJvb3QnKX1cbiAgICAgICAgaGludD17dCgnZmllbGQuc2Nhbk9uQm9vdEhpbnQnKX1cbiAgICAgICAgey4uLnNoYXJlZH1cbiAgICAgICAgey4uLnN0YXRlLnNjYW5PbkJvb3R9XG4gICAgICAgIG9uRWRpdD17KHRleHQpID0+IHByb3BzLmVkaXQoJ3NjYW5PbkJvb3QnLCB0ZXh0KX1cbiAgICAgICAgb25SZXNldD17KCkgPT4gcHJvcHMucmVzZXRGaWVsZCgnc2Nhbk9uQm9vdCcpfVxuICAgICAgLz5cbiAgICAgIDxWYWx1ZUZpZWxkXG4gICAgICAgIGlkPVwiYXV0by1jb250aW51ZS1zY2FuLWxpbWl0XCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLnNjYW5MaW1pdCcpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC5zY2FuTGltaXRIaW50Jyl9XG4gICAgICAgIG51bWVyaWNcbiAgICAgICAgey4uLnNoYXJlZH1cbiAgICAgICAgey4uLnN0YXRlLnNjYW5MaW1pdH1cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgnc2NhbkxpbWl0JywgdGV4dCl9XG4gICAgICAgIG9uUmVzZXQ9eygpID0+IHByb3BzLnJlc2V0RmllbGQoJ3NjYW5MaW1pdCcpfVxuICAgICAgLz5cbiAgICAgIDxWYWx1ZUZpZWxkXG4gICAgICAgIGlkPVwiYXV0by1jb250aW51ZS1mcmVzaC1tc1wiXG4gICAgICAgIGxhYmVsPXt0KCdmaWVsZC5mcmVzaE1zJyl9XG4gICAgICAgIGhpbnQ9e3QoJ2ZpZWxkLmZyZXNoTXNIaW50Jyl9XG4gICAgICAgIG51bWVyaWNcbiAgICAgICAgey4uLnNoYXJlZH1cbiAgICAgICAgey4uLnN0YXRlLmZyZXNoTXN9XG4gICAgICAgIG9uRWRpdD17KHRleHQpID0+IHByb3BzLmVkaXQoJ2ZyZXNoTXMnLCB0ZXh0KX1cbiAgICAgICAgb25SZXNldD17KCkgPT4gcHJvcHMucmVzZXRGaWVsZCgnZnJlc2hNcycpfVxuICAgICAgLz5cbiAgICAgIDxWYWx1ZUZpZWxkXG4gICAgICAgIGlkPVwiYXV0by1jb250aW51ZS1yZWNvbm5lY3Qtc2Nhbi1kZWxheVwiXG4gICAgICAgIGxhYmVsPXt0KCdmaWVsZC5yZWNvbm5lY3RTY2FuRGVsYXlNcycpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC5yZWNvbm5lY3RTY2FuRGVsYXlNc0hpbnQnKX1cbiAgICAgICAgbnVtZXJpY1xuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUucmVjb25uZWN0U2NhbkRlbGF5TXN9XG4gICAgICAgIG9uRWRpdD17KHRleHQpID0+IHByb3BzLmVkaXQoJ3JlY29ubmVjdFNjYW5EZWxheU1zJywgdGV4dCl9XG4gICAgICAgIG9uUmVzZXQ9eygpID0+IHByb3BzLnJlc2V0RmllbGQoJ3JlY29ubmVjdFNjYW5EZWxheU1zJyl9XG4gICAgICAvPlxuICAgICAgPFZhbHVlRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLXJlY29ubmVjdC1iYWNrb2ZmXCJcbiAgICAgICAgbGFiZWw9e3QoJ2ZpZWxkLnJlY29ubmVjdEJhY2tvZmZNcycpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC5yZWNvbm5lY3RCYWNrb2ZmTXNIaW50Jyl9XG4gICAgICAgIG51bWVyaWNcbiAgICAgICAgey4uLnNoYXJlZH1cbiAgICAgICAgey4uLnN0YXRlLnJlY29ubmVjdEJhY2tvZmZNc31cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgncmVjb25uZWN0QmFja29mZk1zJywgdGV4dCl9XG4gICAgICAgIG9uUmVzZXQ9eygpID0+IHByb3BzLnJlc2V0RmllbGQoJ3JlY29ubmVjdEJhY2tvZmZNcycpfVxuICAgICAgLz5cbiAgICAgIDxCb29sZWFuRmllbGRcbiAgICAgICAgaWQ9XCJhdXRvLWNvbnRpbnVlLXZlcmJvc2VcIlxuICAgICAgICBsYWJlbD17dCgnZmllbGQudmVyYm9zZScpfVxuICAgICAgICBoaW50PXt0KCdmaWVsZC52ZXJib3NlSGludCcpfVxuICAgICAgICB7Li4uc2hhcmVkfVxuICAgICAgICB7Li4uc3RhdGUudmVyYm9zZX1cbiAgICAgICAgb25FZGl0PXsodGV4dCkgPT4gcHJvcHMuZWRpdCgndmVyYm9zZScsIHRleHQpfVxuICAgICAgICBvblJlc2V0PXsoKSA9PiBwcm9wcy5yZXNldEZpZWxkKCd2ZXJib3NlJyl9XG4gICAgICAvPlxuICAgIDwvU2V0dGluZ3NDYXJkPlxuICApO1xufVxuIiwgIi8qKlxuICogU3RhZ2VkIGZvcm0gbW9kZWwgYmVoaW5kIHRoZSBwbHVnaW4gc2V0dGluZ3MgY2FyZCDigJQgYSBzZWxmLWNvbnRhaW5lZFxuICogaW1wbGVtZW50YXRpb24gb2YgdGhlIHBsdWdpbi1jYXJkIHN0b3JlIHBhdHRlcm4gdXNlZCBieSB0aGUgRFNIIHBsdWdpblxuICogY29uZmlndXJhdGlvbiBzZWN0aW9uLlxuICpcbiAqIEEgY2FyZCBzdGFnZXMgd2hhdCB0aGUgdXNlciB0eXBlcyBhbmQgd3JpdGVzIGl0IG9ubHkgd2hlbiB0aGV5IHNhdmUuIEVhY2hcbiAqIHNldHRpbmdzIHdyaXRlIGlzIGEgZHVyYWJsZSwgcmV2aXNpb24tZmVuY2VkIGRvY3VtZW50IG11dGF0aW9uLCBzbyBzdGFnaW5nXG4gKiBrZWVwcyB3aGF0IGlzIG9uIHNjcmVlbiBleGFjdGx5IHdoYXQgYSBzYXZlIHdvdWxkIHN0b3JlLiBBIGZpZWxkIHNob3dzIGl0c1xuICogZWZmZWN0aXZlIHZhbHVlIOKAlCB0aGUgdXNlciBsYXllciBvdmVyIHRoZSBjb21wb3NpdGlvbiBsYXllciBvdmVyIHRoZSBzY2hlbWFcbiAqIGRlZmF1bHQg4oCUIGFuZCB3aGV0aGVyIHRoZSB1c2VyIGxheWVyIGNhcnJpZXMgaXQgKHByZXNlbmNlLCBub3QgdmFsdWVcbiAqIGVxdWFsaXR5LCBtYXJrcyBhbiBvdmVycmlkZSkuXG4gKi9cbmltcG9ydCB0eXBlIHsgU2V0dGluZ3NTY29wZSwgU25hcHNob3RTdG9yZSB9IGZyb20gJ0BkZWVwc2Vlay1haS9kc2gtY2xpZW50LXJ1bnRpbWUvY2xpZW50JztcblxuLyoqIFRoZSB3cml0ZSBvbmUgZmllbGQncyBzdGFnZWQgdGV4dCBwZXJmb3JtcyB3aGVuIHRoZSBjYXJkIGlzIHNhdmVkLiAqL1xuZXhwb3J0IHR5cGUgRmllbGRXcml0ZSA9IHsga2luZDogJ3NldCc7IHZhbHVlOiB1bmtub3duIH0gfCB7IGtpbmQ6ICdjbGVhcicgfTtcblxuLyoqIEhvdyBvbmUgZmllbGQgY29udmVydHMgYmV0d2VlbiBpdHMgc3RvcmVkIHZhbHVlIGFuZCBpdHMgZHJhZnQgdGV4dC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FyZEZpZWxkU3BlYyB7XG4gIC8qKiBGaWVsZCBuYW1lIGluc2lkZSB0aGUgbmFtZXNwYWNlIHNlY3Rpb24uICovXG4gIGZpZWxkOiBzdHJpbmc7XG4gIC8qKiBSZW5kZXIgYSBzdG9yZWQgdmFsdWUgYXMgZHJhZnQgdGV4dDsgdGhlIGVtcHR5IHN0cmluZyB3aGVuIHRoZSBzZWN0aW9uIGNhcnJpZXMgbm9uZS4gKi9cbiAgZm9ybWF0OiAodmFsdWU6IHVua25vd24pID0+IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSB3cml0ZSB0aGlzIGRyYWZ0IHRleHQgc3RhZ2VzLCBvciB1bmRlZmluZWQgd2hlbiB0aGUgdGV4dCBpcyBub3QgYVxuICAgKiB2YWx1ZSB0aGlzIGZpZWxkIGFjY2VwdHMg4oCUIHdoaWNoIGJsb2NrcyB0aGUgc2F2ZSByYXRoZXIgdGhhbiBkaXNjYXJkaW5nIGl0LlxuICAgKi9cbiAgcGFyc2U6ICh0ZXh0OiBzdHJpbmcpID0+IEZpZWxkV3JpdGUgfCB1bmRlZmluZWQ7XG59XG5cbi8qKiBPbmUgZmllbGQgYXMgdGhlIGNhcmQncyBjb250cm9sIHJlbmRlcnMgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIENhcmRGaWVsZFN0YXRlIHtcbiAgLyoqIERyYWZ0IHRleHQgdGhlIGNvbnRyb2wgcmVuZGVycy4gKi9cbiAgdGV4dDogc3RyaW5nO1xuICAvKiogV2hldGhlciBzYXZpbmcgd291bGQgbGVhdmUgYSB1c2VyLWxheWVyIGVudHJ5IGZvciB0aGlzIGZpZWxkLiAqL1xuICBvdmVycmlkZGVuOiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgZHJhZnQgaXMgbm90IGEgdmFsdWUgdGhpcyBmaWVsZCBhY2NlcHRzLCB3aGljaCBibG9ja3Mgc2F2aW5nLiAqL1xuICBpbnZhbGlkOiBib29sZWFuO1xufVxuXG4vKiogRm9ybSBzdGF0ZSBldmVyeSBwbHVnaW4gY2FyZCBzaGFyZXMuICovXG5leHBvcnQgaW50ZXJmYWNlIENhcmRTaGVsbCB7XG4gIC8qKiBGYWxzZSB3aGlsZSB0aGUgbmFtZXNwYWNlIGlzIG5vdCBzZXJ2ZWQgdG8gdGhpcyBjbGllbnQ7IHRoZSBjYXJkIHJlbmRlcnMgbm90aGluZy4gKi9cbiAgYXZhaWxhYmxlOiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgSG9zdCBkb2N1bWVudCBhY2NlcHRzIHdyaXRlcy4gKi9cbiAgd3JpdGFibGU6IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIHRoZSBmb3JtIGhvbGRzIGVkaXRzIHRoYXQgYSBzYXZlIHdvdWxkIHdyaXRlLiAqL1xuICBkaXJ0eTogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgYW55IHN0YWdlZCBkcmFmdCBpcyBpbnZhbGlkLCB3aGljaCBibG9ja3MgdGhlIHNhdmUuICovXG4gIGludmFsaWQ6IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIGEgc2F2ZSBpcyBjcm9zc2luZyB0aGUgd2lyZS4gKi9cbiAgc2F2aW5nOiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgbGFzdCBzYXZlIGRpZCBub3QgbGFuZCBhcyBzdGFnZWQ7IGNsZWFyZWQgYnkgdGhlIG5leHQgZWRpdCBvciBzYXZlLiAqL1xuICBmYWlsZWQ6IGJvb2xlYW47XG59XG5cbi8qKiBUaGUgd3JpdGUgYWN0aW9ucyB0aGUgY2FyZCdzIHNsb3QgZW50cnkgaW5qZWN0cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FyZEFjdGlvbnMge1xuICAvKiogU3RhZ2UgZHJhZnQgdGV4dCBmb3Igb25lIGZpZWxkLiAqL1xuICBlZGl0OiAoZmllbGQ6IHN0cmluZywgdGV4dDogc3RyaW5nKSA9PiB2b2lkO1xuICAvKiogU3RhZ2UgYSBjbGVhciwgc28gc2F2aW5nIGxldHMgdGhlIGZpZWxkIHJlLWluaGVyaXQgdGhlIGNvbXBvc2l0aW9uIGxheWVyLiAqL1xuICByZXNldEZpZWxkOiAoZmllbGQ6IHN0cmluZykgPT4gdm9pZDtcbiAgLyoqIFdyaXRlIGV2ZXJ5IHN0YWdlZCBlZGl0LCB0aGVuIHJlLXNlZWQgZnJvbSB3aGF0IHRoZSBIb3N0IGFjY2VwdGVkLiAqL1xuICBzYXZlOiAoKSA9PiB2b2lkO1xuICAvKiogRHJvcCBldmVyeSBzdGFnZWQgZWRpdC4gKi9cbiAgZGlzY2FyZDogKCkgPT4gdm9pZDtcbn1cblxuLyoqIEEgd2hvbGUtbnVtYmVyIGZpZWxkLiBBbiBlbXB0eSBkcmFmdCBjbGVhcnMgdGhlIGZpZWxkOyBhIG5vbi1udW1iZXIgb3Igb3V0LW9mLXJhbmdlIGRyYWZ0IGJsb2NrcyB0aGUgc2F2ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBudW1iZXJGaWVsZChmaWVsZDogc3RyaW5nLCBtaW4gPSAwKTogQ2FyZEZpZWxkU3BlYyB7XG4gIHJldHVybiB7XG4gICAgZmllbGQsXG4gICAgZm9ybWF0OiAodmFsdWUpID0+ICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInID8gU3RyaW5nKHZhbHVlKSA6ICcnKSxcbiAgICBwYXJzZTogKHRleHQpID0+IHtcbiAgICAgIGNvbnN0IHRyaW1tZWQgPSB0ZXh0LnRyaW0oKTtcbiAgICAgIGlmICh0cmltbWVkID09PSAnJykgcmV0dXJuIHsga2luZDogJ2NsZWFyJyB9O1xuICAgICAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHRyaW1tZWQpO1xuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUocGFyc2VkKSB8fCAhTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpIHx8IHBhcnNlZCA8IG1pbikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiB7IGtpbmQ6ICdzZXQnLCB2YWx1ZTogcGFyc2VkIH07XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIEEgZnJlZS10ZXh0IGZpZWxkLiBBbiBlbXB0eSBkcmFmdCBjbGVhcnMgdGhlIGZpZWxkLCBzbyBlbXB0eWluZyB0aGUgY29udHJvbCBhbmQgc2F2aW5nIGlzIHRoZSBzYW1lIGdlc3R1cmUgYXMgcmVzZXR0aW5nIGl0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRleHRGaWVsZChmaWVsZDogc3RyaW5nKTogQ2FyZEZpZWxkU3BlYyB7XG4gIHJldHVybiB7XG4gICAgZmllbGQsXG4gICAgZm9ybWF0OiAodmFsdWUpID0+ICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUgOiAnJyksXG4gICAgcGFyc2U6ICh0ZXh0KSA9PiB7XG4gICAgICBjb25zdCB0cmltbWVkID0gdGV4dC50cmltKCk7XG4gICAgICByZXR1cm4gdHJpbW1lZCA9PT0gJycgPyB7IGtpbmQ6ICdjbGVhcicgfSA6IHsga2luZDogJ3NldCcsIHZhbHVlOiB0cmltbWVkIH07XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIEEgYm9vbGVhbiBmaWVsZCwgZWRpdGVkIHRocm91Z2ggdHJ1ZS9mYWxzZSBkcmFmdCB0ZXh0OyBhbiBlbXB0eSBkcmFmdCBpbmhlcml0cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBib29sZWFuRmllbGQoZmllbGQ6IHN0cmluZyk6IENhcmRGaWVsZFNwZWMge1xuICByZXR1cm4ge1xuICAgIGZpZWxkLFxuICAgIGZvcm1hdDogKHZhbHVlKSA9PiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicgPyBTdHJpbmcodmFsdWUpIDogJycpLFxuICAgIHBhcnNlOiAodGV4dCkgPT4ge1xuICAgICAgY29uc3QgdHJpbW1lZCA9IHRleHQudHJpbSgpO1xuICAgICAgaWYgKHRyaW1tZWQgPT09ICcnKSByZXR1cm4geyBraW5kOiAnY2xlYXInIH07XG4gICAgICBpZiAodHJpbW1lZCA9PT0gJ3RydWUnKSByZXR1cm4geyBraW5kOiAnc2V0JywgdmFsdWU6IHRydWUgfTtcbiAgICAgIGlmICh0cmltbWVkID09PSAnZmFsc2UnKSByZXR1cm4geyBraW5kOiAnc2V0JywgdmFsdWU6IGZhbHNlIH07XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKiBPbmUgZmllbGQncyBzdGFnZWQgZWRpdC4gKi9cbmludGVyZmFjZSBTdGFnZWRFZGl0IHtcbiAgLyoqIERyYWZ0IHRleHQgdGhlIGNvbnRyb2wgcmVuZGVycy4gKi9cbiAgdGV4dDogc3RyaW5nO1xuICAvKiogVHJ1ZSB3aGVuIHRoaXMgZWRpdCBjbGVhcnMgdGhlIGZpZWxkIHdoYXRldmVyIHRleHQgaXQgc2hvd3MuICovXG4gIGNsZWFyOiBib29sZWFuO1xufVxuXG4vKipcbiAqIFN0YWdlcyBvbmUgY2FyZCdzIGVkaXRzIG92ZXIgb25lIHNldHRpbmdzIG5hbWVzcGFjZSBhbmQgd3JpdGVzIHRoZW0gb24gc2F2ZS5cbiAqXG4gKiBUaGUgSG9zdCBpcyB0aGUgb25seSBhdXRob3JpdHkgb24gd2hldGhlciBhIHZhbHVlIHdhcyBhY2NlcHRlZCwgc28gdGhlXG4gKiBvdXRjb21lIGlzIHJlYWQgYmFjayBmcm9tIHRoZSBzZWN0aW9uIHJhdGhlciB0aGFuIHByZWRpY3RlZCBoZXJlLiBBIHNhdmVcbiAqIHRoYXQgZGlkIG5vdCBsYW5kIGtlZXBzIGl0cyBkcmFmdHMsIHNvIHRoZSB1c2VyIGNhbiBjb3JyZWN0IHRoZW0gaW5zdGVhZCBvZlxuICogcmV0eXBpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBDYXJkRm9ybTxUPiB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3BlY3M6IE1hcDxzdHJpbmcsIENhcmRGaWVsZFNwZWM+O1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YWdlZCA9IG5ldyBNYXA8c3RyaW5nLCBTdGFnZWRFZGl0PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGxpc3RlbmVycyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKTtcbiAgcHJpdmF0ZSBzYXZpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBmYWlsZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogQHBhcmFtIHNjb3BlIC0gdGhlIGJvdW5kIHNldHRpbmdzIHNjb3BlIGZvciB0aGlzIGNhcmQncyBuYW1lc3BhY2UuXG4gICAqIEBwYXJhbSBzcGVjcyAtIHRoZSBzZWN0aW9uIGZpZWxkcyB0aGlzIGNhcmQgZWRpdHMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNjb3BlOiBTZXR0aW5nc1Njb3BlPFQ+LFxuICAgIHNwZWNzOiBDYXJkRmllbGRTcGVjW10sXG4gICkge1xuICAgIHRoaXMuc3BlY3MgPSBuZXcgTWFwKHNwZWNzLm1hcCgoc3BlYykgPT4gW3NwZWMuZmllbGQsIHNwZWNdKSk7XG4gICAgdGhpcy5zY29wZS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5wdWJsaXNoKCkpO1xuICB9XG5cbiAgLyoqIFB1Ymxpc2ggYSBwcm9qZWN0aW9uIG9mIHRoaXMgZm9ybSwgcmVidWlsdCB3aGVuZXZlciB0aGUgc2NvcGUgb3IgYSBkcmFmdCBjaGFuZ2VzLiAqL1xuICBiaW5kPFM+KHByb2plY3Q6ICgpID0+IFMsIGNyZWF0ZVN0b3JlOiAoaW5pdDogUykgPT4gU25hcHNob3RTdG9yZTxTPik6IFNuYXBzaG90U3RvcmU8Uz4ge1xuICAgIGNvbnN0IHN0b3JlID0gY3JlYXRlU3RvcmUocHJvamVjdCgpKTtcbiAgICB0aGlzLmxpc3RlbmVycy5hZGQoKCkgPT4gc3RvcmUuc2V0KHByb2plY3QoKSkpO1xuICAgIHJldHVybiBzdG9yZTtcbiAgfVxuXG4gIC8qKiBSZWFkIHRoZSBjYXJkLWxldmVsIHN0YXRlOiB3aGF0IHRoZSBIb3N0IHNlcnZlcywgYW5kIHdoYXQgYSBzYXZlIHdvdWxkIGRvLiAqL1xuICBzaGVsbCgpOiBDYXJkU2hlbGwge1xuICAgIGNvbnN0IHNuYXBzaG90ID0gdGhpcy5zY29wZS5nZXRTbmFwc2hvdCgpO1xuICAgIHJldHVybiB7XG4gICAgICBhdmFpbGFibGU6IHNuYXBzaG90LnN0YXR1cyA9PT0gJ3JlYWR5JyxcbiAgICAgIHdyaXRhYmxlOiBzbmFwc2hvdC53cml0YWJsZSxcbiAgICAgIGRpcnR5OiB0aGlzLnBsYW4oKS5sZW5ndGggPiAwLFxuICAgICAgaW52YWxpZDogdGhpcy5wbGFuKCkuc29tZSgoaXRlbSkgPT4gaXRlbS5ydW4gPT09IHVuZGVmaW5lZCksXG4gICAgICBzYXZpbmc6IHRoaXMuc2F2aW5nLFxuICAgICAgZmFpbGVkOiB0aGlzLmZhaWxlZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFJlYWQgb25lIGZpZWxkJ3Mgc3RhdGUgZnJvbSB0aGUgZWZmZWN0aXZlIHNlY3Rpb24gYW5kIGl0cyBzdGFnZWQgZHJhZnQuICovXG4gIGZpZWxkKGZpZWxkOiBzdHJpbmcpOiBDYXJkRmllbGRTdGF0ZSB7XG4gICAgY29uc3Qgc3BlYyA9IHRoaXMuc3BlY09mKGZpZWxkKTtcbiAgICBjb25zdCBzdGFnZWQgPSB0aGlzLnN0YWdlZC5nZXQoZmllbGQpO1xuICAgIGlmIChzdGFnZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGV4dDogc3BlYy5mb3JtYXQodGhpcy5zZWN0aW9uVmFsdWUoZmllbGQpKSxcbiAgICAgICAgb3ZlcnJpZGRlbjogdGhpcy5zdG9yZWQoZmllbGQpLFxuICAgICAgICBpbnZhbGlkOiBmYWxzZSxcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHdyaXRlID0gc3RhZ2VkLmNsZWFyID8geyBraW5kOiAnY2xlYXInIGFzIGNvbnN0IH0gOiBzcGVjLnBhcnNlKHN0YWdlZC50ZXh0KTtcbiAgICByZXR1cm4ge1xuICAgICAgdGV4dDogc3RhZ2VkLnRleHQsXG4gICAgICBvdmVycmlkZGVuOiB3cml0ZT8ua2luZCA9PT0gJ3NldCcsXG4gICAgICBpbnZhbGlkOiB3cml0ZSA9PT0gdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cblxuICAvKiogVGhlIGFjdGlvbnMgdGhlIGNhcmQncyBzbG90IHJlZ2lzdHJhdGlvbiBpbmplY3RzLiAqL1xuICBhY3Rpb25zKCk6IENhcmRBY3Rpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgZWRpdDogKGZpZWxkLCB0ZXh0KSA9PiB0aGlzLnN0YWdlKGZpZWxkLCB7IHRleHQsIGNsZWFyOiBmYWxzZSB9KSxcbiAgICAgIHJlc2V0RmllbGQ6IChmaWVsZCkgPT4ge1xuICAgICAgICB0aGlzLnN0YWdlKGZpZWxkLCB7IHRleHQ6IHRoaXMuc3BlY09mKGZpZWxkKS5mb3JtYXQodGhpcy5iYXNlVmFsdWUoZmllbGQpKSwgY2xlYXI6IHRydWUgfSk7XG4gICAgICB9LFxuICAgICAgc2F2ZTogKCkgPT4gdm9pZCB0aGlzLnNhdmUoKSxcbiAgICAgIGRpc2NhcmQ6ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuc3RhZ2VkLnNpemUgPT09IDAgJiYgIXRoaXMuZmFpbGVkKSByZXR1cm47XG4gICAgICAgIHRoaXMuc3RhZ2VkLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuZmFpbGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMucHVibGlzaCgpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlIGV2ZXJ5IHN0YWdlZCBlZGl0LCB0aGVuIHJlLXNlZWQgZnJvbSB3aGF0IHRoZSBIb3N0IGFjY2VwdGVkLlxuICAgKiBAcmV0dXJucyBzZXR0bGVtZW50IGFmdGVyIGV2ZXJ5IHdyaXRlIGFuZCB0aGUgcmVhZC1iYWNrLlxuICAgKi9cbiAgYXN5bmMgc2F2ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwbGFuID0gdGhpcy5wbGFuKCk7XG4gICAgY29uc3Qgd3JpdGVzID0gcGxhbi5mbGF0TWFwKChpdGVtKSA9PiAoaXRlbS5ydW4gPT09IHVuZGVmaW5lZCA/IFtdIDogW2l0ZW0ucnVuXSkpO1xuICAgIGlmIChwbGFuLmxlbmd0aCA9PT0gMCB8fCB0aGlzLnNhdmluZyB8fCB3cml0ZXMubGVuZ3RoICE9PSBwbGFuLmxlbmd0aCkgcmV0dXJuO1xuICAgIC8vIFNuYXBzaG90IHRoZSBmaWVsZHMgdGhpcyBzYXZlIHdyaXRlcywgc28gZWRpdHMgc3RhZ2VkIHdoaWxlIGl0IGlzIGluXG4gICAgLy8gZmxpZ2h0IHN1cnZpdmU6IG9ubHkgdGhlIHN0YWdlZCBrZXlzIHRoaXMgc2F2ZSBhY3R1YWxseSB3cm90ZSBhcmUgY2xlYXJlZC5cbiAgICBjb25zdCBmaWVsZHMgPSBuZXcgU2V0KHBsYW4ubWFwKChpdGVtKSA9PiBpdGVtLmZpZWxkKSk7XG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuZmFpbGVkID0gZmFsc2U7XG4gICAgdGhpcy5wdWJsaXNoKCk7XG4gICAgbGV0IGxhbmRlZCA9IHRydWU7XG4gICAgZm9yIChjb25zdCB3cml0ZSBvZiB3cml0ZXMpIHtcbiAgICAgIGxhbmRlZCA9IChhd2FpdCB3cml0ZSgpKSAmJiBsYW5kZWQ7XG4gICAgfVxuICAgIGlmIChsYW5kZWQpIHtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB0aGlzLnN0YWdlZC5kZWxldGUoZmllbGQpO1xuICAgIH1cbiAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgIHRoaXMuZmFpbGVkID0gIWxhbmRlZDtcbiAgICB0aGlzLnB1Ymxpc2goKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmVyeSBzdGFnZWQgZWRpdCBhIHNhdmUgd291bGQgd3JpdGUuIEFuIGVudHJ5IHdob3NlIGRyYWZ0IGlzIG5vdCBhIHZhbHVlXG4gICAqIGl0cyBmaWVsZCBhY2NlcHRzIGNhcnJpZXMgbm8gd3JpdGU6IHRoZSBmb3JtIGlzIHN0aWxsIGRpcnR5LCBhbmQgdGhlIHNhdmVcbiAgICogcmVmdXNlcyByYXRoZXIgdGhhbiBkcm9wcGluZyB0aGUgZWRpdC4gQSBzdGFnZWQgZWRpdCB0aGF0IG1hdGNoZXMgdGhlXG4gICAqIGVmZmVjdGl2ZSBzZWN0aW9uIGlzIG5vdCBhIHdyaXRlIGF0IGFsbC5cbiAgICovXG4gIHByaXZhdGUgcGxhbigpOiB7IGZpZWxkOiBzdHJpbmc7IHJ1bjogKCgpID0+IFByb21pc2U8Ym9vbGVhbj4pIHwgdW5kZWZpbmVkIH1bXSB7XG4gICAgY29uc3QgcGxhbjogeyBmaWVsZDogc3RyaW5nOyBydW46ICgoKSA9PiBQcm9taXNlPGJvb2xlYW4+KSB8IHVuZGVmaW5lZCB9W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IFtmaWVsZCwgc3RhZ2VkXSBvZiB0aGlzLnN0YWdlZCkge1xuICAgICAgY29uc3Qgc3BlYyA9IHRoaXMuc3BlY09mKGZpZWxkKTtcbiAgICAgIGlmIChzdGFnZWQuY2xlYXIpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RvcmVkKGZpZWxkKSkgcGxhbi5wdXNoKHsgZmllbGQsIHJ1bjogKCkgPT4gdGhpcy5jbGVhcihmaWVsZCkgfSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlZC50ZXh0ID09PSBzcGVjLmZvcm1hdCh0aGlzLnNlY3Rpb25WYWx1ZShmaWVsZCkpKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHdyaXRlID0gc3BlYy5wYXJzZShzdGFnZWQudGV4dCk7XG4gICAgICBpZiAod3JpdGUgPT09IHVuZGVmaW5lZCkgcGxhbi5wdXNoKHsgZmllbGQsIHJ1bjogdW5kZWZpbmVkIH0pO1xuICAgICAgZWxzZSBpZiAod3JpdGUua2luZCA9PT0gJ2NsZWFyJykgcGxhbi5wdXNoKHsgZmllbGQsIHJ1bjogKCkgPT4gdGhpcy5jbGVhcihmaWVsZCkgfSk7XG4gICAgICBlbHNlIHBsYW4ucHVzaCh7IGZpZWxkLCBydW46ICgpID0+IHRoaXMuc3RvcmUoZmllbGQsIHdyaXRlLnZhbHVlKSB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBsYW47XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNsZWFyKGZpZWxkOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBhd2FpdCB0aGlzLnNjb3BlLnVuc2V0KGZpZWxkKTtcbiAgICByZXR1cm4gIXRoaXMuc3RvcmVkKGZpZWxkKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc3RvcmUoZmllbGQ6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBhd2FpdCB0aGlzLnNjb3BlLnNldChmaWVsZCwgdmFsdWUpO1xuICAgIHJldHVybiB0aGlzLnVzZXJMYXllcigpPy5bZmllbGRdID09PSB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhZ2UoZmllbGQ6IHN0cmluZywgZWRpdDogU3RhZ2VkRWRpdCk6IHZvaWQge1xuICAgIHRoaXMuc3RhZ2VkLnNldChmaWVsZCwgZWRpdCk7XG4gICAgdGhpcy5mYWlsZWQgPSBmYWxzZTtcbiAgICB0aGlzLnB1Ymxpc2goKTtcbiAgfVxuXG4gIHByaXZhdGUgc3BlY09mKGZpZWxkOiBzdHJpbmcpOiBDYXJkRmllbGRTcGVjIHtcbiAgICBjb25zdCBzcGVjID0gdGhpcy5zcGVjcy5nZXQoZmllbGQpO1xuICAgIGlmIChzcGVjID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihgc2V0dGluZ3MgY2FyZCBoYXMgbm8gZmllbGQgJHtmaWVsZH1gKTtcbiAgICByZXR1cm4gc3BlYztcbiAgfVxuXG4gIHByaXZhdGUgc2VjdGlvblZhbHVlKGZpZWxkOiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICByZXR1cm4gKHRoaXMuc2NvcGUuZ2V0U25hcHNob3QoKS52YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCk/LltmaWVsZF07XG4gIH1cblxuICBwcml2YXRlIGJhc2VWYWx1ZShmaWVsZDogc3RyaW5nKTogdW5rbm93biB7XG4gICAgcmV0dXJuICh0aGlzLnNjb3BlLmdldFNuYXBzaG90KCkuYmFzZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCk/LltmaWVsZF07XG4gIH1cblxuICBwcml2YXRlIHVzZXJMYXllcigpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc2NvcGUuZ2V0U25hcHNob3QoKS51c2VyIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9yZWQoZmllbGQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHVzZXIgPSB0aGlzLnVzZXJMYXllcigpO1xuICAgIHJldHVybiB1c2VyICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHVzZXIsIGZpZWxkKTtcbiAgfVxuXG4gIHByaXZhdGUgcHVibGlzaCgpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMubGlzdGVuZXJzKSBsaXN0ZW5lcigpO1xuICB9XG59XG4iLCAiLyoqXG4gKiBTdHlsZXMgZm9yIHRoZSBhdXRvLWNvbnRpbnVlIHNldHRpbmdzIGNhcmQsIGluamVjdGVkIGF0IGZhY3RvcnlcbiAqIG1hdGVyaWFsaXphdGlvbiBzbyB0aGUgY2xpZW50IG1vZHVsZSBzeXN0ZW0ncyBzdHlsZSBib29ra2VlcGluZyAoSE1SKSBvd25zXG4gKiB0aGVtLiBVc2VzIHRoZSBEU0ggZGVzaWduIHRva2VucyAoYC0tZHN3LWFsaWFzLSpgKSBzbyB0aGUgY2FyZCBmb2xsb3dzIHRoZVxuICogYWN0aXZlIHRoZW1lLlxuICovXG5cbmNvbnN0IGNzcyA9IGBcbi5kc2hBY0NhcmQge1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTMpO1xuICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICBsaXN0LXN0eWxlOiBub25lO1xuICB0cmFuc2l0aW9uOiBib3JkZXItY29sb3IgLjE2cywgYmFja2dyb3VuZCAuMTZzO1xufVxuLmRzaEFjQ2FyZDpob3ZlciB7IGJvcmRlci1jb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLWRpbW1lZCk7IH1cbi5kc2hBY0NhcmRPcGVuIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTIpO1xuICBib3JkZXItY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1kaW1tZWQpO1xufVxuLmRzaEFjSGVhZGVyIHtcbiAgYXBwZWFyYW5jZTogbm9uZTtcbiAgd2lkdGg6IDEwMCU7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGNvbG9yOiBpbmhlcml0O1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJhY2tncm91bmQ6IG5vbmU7XG4gIGJvcmRlcjogMDtcbiAgYm9yZGVyLXJhZGl1czogMTJweDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiAxMnB4O1xuICBwYWRkaW5nOiAxNHB4IDE2cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG59XG4uZHNoQWNIZWFkZXI6Zm9jdXMtdmlzaWJsZSB7IG91dGxpbmU6IDJweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7IG91dGxpbmUtb2Zmc2V0OiAtMnB4OyB9XG4uZHNoQWNIZWFkVGV4dCB7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IGZsZXg6IDE7IGdhcDogNHB4OyBtaW4td2lkdGg6IDA7IGRpc3BsYXk6IGZsZXg7IH1cbi5kc2hBY05hbWUgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpOyBmb250LXNpemU6IDE1cHg7IGZvbnQtd2VpZ2h0OiA2MDA7IGxpbmUtaGVpZ2h0OiAxLjQ7IH1cbi5kc2hBY0Rlc2NyaXB0aW9uIHsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7IGZvbnQtc2l6ZTogMTNweDsgbGluZS1oZWlnaHQ6IDEuNTsgfVxuLmRzaEFjQ2hldnJvbiB7IGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpOyBmbGV4OiBub25lOyB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gLjE2czsgfVxuLmRzaEFjQ2hldnJvbk9wZW4geyB0cmFuc2Zvcm06IHJvdGF0ZSgxODBkZWcpOyB9XG4uZHNoQWNCb2R5IHsgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpOyBtYXJnaW46IDAgMTZweDsgcGFkZGluZy1ib3R0b206IDhweDsgfVxuLmRzaEFjUmVhZE9ubHkgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTsgbWFyZ2luOiAxMnB4IDAgMDsgZm9udC1zaXplOiAxMnB4OyBsaW5lLWhlaWdodDogMS41OyB9XG4uZHNoQWNQZW5kaW5nIHtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLW1vZHVsZS1wbGF0Zm9ybSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgYm9yZGVyLXJhZGl1czogOTk5cHg7XG4gIGZsZXg6IG5vbmU7XG4gIHBhZGRpbmc6IDFweCA4cHg7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgbGluZS1oZWlnaHQ6IDE3cHg7XG59XG4uZHNoQWNGb290ZXIge1xuICBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogOHB4O1xuICBwYWRkaW5nOiAxMnB4IDAgNHB4O1xuICBkaXNwbGF5OiBmbGV4O1xufVxuLmRzaEFjRmFpbGVkIHsgbWluLXdpZHRoOiAwOyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLWVycm9yKTsgZmxleDogMTsgbWFyZ2luOiAwOyBmb250LXNpemU6IDEycHg7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbi5kc2hBY0Rpc2NhcmQsIC5kc2hBY1NhdmUge1xuICBhcHBlYXJhbmNlOiBub25lO1xuICBmb250OiBpbmhlcml0O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIHBhZGRpbmc6IDVweCAxNHB4O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGxpbmUtaGVpZ2h0OiAxLjU7XG59XG4uZHNoQWNEaXNjYXJkIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpOyBiYWNrZ3JvdW5kOiBub25lOyB9XG4uZHNoQWNEaXNjYXJkOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtZGltbWVkKTsgfVxuLmRzaEFjU2F2ZSB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0zKTsgfVxuLmRzaEFjRGlzY2FyZDpkaXNhYmxlZCwgLmRzaEFjU2F2ZTpkaXNhYmxlZCB7IG9wYWNpdHk6IC40OyBjdXJzb3I6IGRlZmF1bHQ7IH1cbi5kc2hBY0Rpc2NhcmQ6Zm9jdXMtdmlzaWJsZSwgLmRzaEFjU2F2ZTpmb2N1cy12aXNpYmxlIHsgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTsgb3V0bGluZS1vZmZzZXQ6IDFweDsgfVxuLmRzaEFjRmllbGQgeyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDZweDsgcGFkZGluZzogMTJweCAwOyBkaXNwbGF5OiBmbGV4OyB9XG4uZHNoQWNGaWVsZCArIC5kc2hBY0ZpZWxkIHsgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpOyB9XG4uZHNoQWNIZWFkIHsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7IGRpc3BsYXk6IGZsZXg7IH1cbi5kc2hBY0xhYmVsIHsgbWluLXdpZHRoOiAwOyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpOyBmbGV4OiAxOyBmb250LXNpemU6IDEzcHg7IGZvbnQtd2VpZ2h0OiA1MDA7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbi5kc2hBY0JhZGdlcyB7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyBkaXNwbGF5OiBpbmxpbmUtZmxleDsgfVxuLmRzaEFjQmFkZ2Uge1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbW9kdWxlLXBsYXRmb3JtKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgcGFkZGluZzogMXB4IDhweDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBmb250LXdlaWdodDogNTAwO1xuICBsaW5lLWhlaWdodDogMTdweDtcbn1cbi5kc2hBY1Jlc2V0IHtcbiAgZm9udDogaW5oZXJpdDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGJhY2tncm91bmQ6IG5vbmU7XG4gIGJvcmRlcjogbm9uZTtcbiAgcGFkZGluZzogMDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBsaW5lLWhlaWdodDogMS41O1xufVxuLmRzaEFjUmVzZXQ6aG92ZXI6bm90KDpkaXNhYmxlZCkgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpOyB9XG4uZHNoQWNSZXNldDpkaXNhYmxlZCB7IGN1cnNvcjogZGVmYXVsdDsgfVxuLmRzaEFjSW5wdXQge1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTMpO1xuICBoZWlnaHQ6IDM0cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgcGFkZGluZzogMCAxMnB4O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGxpbmUtaGVpZ2h0OiAxLjU7XG59XG4uZHNoQWNJbnB1dDpmb2N1cy12aXNpYmxlIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7IG91dGxpbmU6IG5vbmU7IH1cbi5kc2hBY0lucHV0OmRpc2FibGVkIHsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7IGN1cnNvcjogZGVmYXVsdDsgfVxuLmRzaEFjSW5wdXRJbnZhbGlkIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtZXJyb3IpOyB9XG4uZHNoQWNTZWxlY3Qge1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTMpO1xuICBoZWlnaHQ6IDM0cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgcGFkZGluZzogMCA4cHg7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgbGluZS1oZWlnaHQ6IDEuNTtcbn1cbi5kc2hBY1NlbGVjdDpmb2N1cy12aXNpYmxlIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7IG91dGxpbmU6IG5vbmU7IH1cbi5kc2hBY1NlbGVjdDpkaXNhYmxlZCB7IGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpOyBjdXJzb3I6IGRlZmF1bHQ7IH1cbi5kc2hBY0ludmFsaWQgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLWVycm9yKTsgbWFyZ2luOiAwOyBmb250LXNpemU6IDEycHg7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbi5kc2hBY0hpbnQgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTsgbWFyZ2luOiAwOyBmb250LXNpemU6IDEycHg7IGxpbmUtaGVpZ2h0OiAxLjU7IH1cbmA7XG5cbi8qKiBJbmplY3QgdGhlIHN0eWxlc2hlZXQgb25jZTsgYSBuby1vcCBvdXRzaWRlIGEgYnJvd3NlciBlbnZpcm9ubWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RTdHlsZXMoKTogdm9pZCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdzdHlsZVtkYXRhLXBsdWdpbi1jc3M9XCJhdXRvLWNvbnRpbnVlL2NhcmRcIl0nKSAhPT0gbnVsbCkgcmV0dXJuO1xuICBjb25zdCB0YWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICB0YWcuZGF0YXNldC5wbHVnaW4gPSAnZHNoLWNsaWVudC1hdXRvLWNvbnRpbnVlJztcbiAgdGFnLmRhdGFzZXQucGx1Z2luQ3NzID0gJ2F1dG8tY29udGludWUvY2FyZCc7XG4gIHRhZy50ZXh0Q29udGVudCA9IGNzcztcbiAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCh0YWcpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7OztBQ2tETyxJQUFNLGlCQUFxQztBQUFBLEVBQ2hELGNBQWM7QUFBQSxFQUNkLFNBQVM7QUFBQSxFQUNULFlBQVk7QUFBQSxF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
|
|
1194
|
-
|
|
1193
|
+
//# sourceMappingURL=client.js.map
|
|
1195
1194
|
return module.exports;
|
|
1196
1195
|
}
|
|
1197
1196
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/client/index.ts", "src/client/engine.ts", "src/client/locales.ts", "src/client/settings-card.tsx", "src/client/settings-form.ts", "src/client/styles.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Auto-continue plugin, browser half.\n *\n * - Runs the auto-continue engine over the live mux + host event streams.\n * - Registers the `auto-continue` settings card into the plugin-configuration\n * section (`settings.plugin.item`), editing the same namespace the engine\n * reads — every behavior knob is configurable from the GUI.\n */\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client';\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client';\n// Type-only: pulls the settings-surface SlotMap merge and ctx.settingsScope.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client';\n// Type-only: pulls the `settings.plugin.item` SlotMap merge.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client';\nimport { AutoContinueRunner, resolveConfig, type AutoContinueSettings } from './engine.ts';\nimport { en, zh, type SettingsCardKey } from './locales.ts';\nimport {\n AutoContinueSettingsCard,\n AutoContinueSettingsCardController,\n} from './settings-card.tsx';\n\n/** 客户端根上下文的 connection 服务(由 dsh-client-connection 挂载)。 */\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n connection: ConnectionHandle;\n }\n}\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'auto-continue';\n\n/** Settings namespace the engine reads and the settings card edits. */\nconst SETTINGS_NS = 'auto-continue';\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** auto-continue settings-card copy. */\n 'auto-continue': SettingsCardKey;\n }\n}\n\n/** Services required by this plugin. */\nexport const inject = ['slots', 'locale', 'connection', 'settingsScope'];\n\n/** 当前 runner(HMR 重载时先销毁旧的再建新的)。 */\nlet current: AutoContinueRunner | null = null;\n\n/**\n * Plugin body: mount the engine and the settings card.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'auto-continue: dictionaries');\n\n // Engine: reads the settings scope live, so GUI changes apply immediately.\n const scope = ctx.settingsScope.bind<AutoContinueSettings>({ namespace: SETTINGS_NS });\n current?.dispose();\n current = new AutoContinueRunner(ctx.connection.api, () => resolveConfig(scope.getSnapshot().value));\n\n // Plugin configuration card: one staged form over the `auto-continue`\n // settings namespace, contributed to the plugin-configuration section.\n const controller = new AutoContinueSettingsCardController(scope);\n ctx.slots.inject('settings.plugin.item', () =>\n ctx.slots.register(\n {\n name: 'settings.plugin.item',\n id: 'auto-continue',\n order: 90,\n locale: NS,\n inject: () => controller.inject(),\n },\n AutoContinueSettingsCard,\n ),\n );\n}\n", "/**\n * Auto-continue engine — browser half core.\n *\n * Watches the two live event streams of the dsh web GUI (mux + host):\n * - turns ended for a non-human reason (`turn/end` reason ∈ error / interrupted / max-tokens)\n * - host-reported agent failures with no turn position (`host/agent-error`)\n * After a grace period it sends a queued prompt (default 「继续」) to that\n * session — exactly equivalent to the user typing it manually.\n *\n * All behavior is driven by the `auto-continue` settings namespace (see the\n * plugin's settings card); every knob below is user-configurable there.\n */\n\nimport type {\n HostFrame,\n IApiClient,\n MuxFrame,\n SessionId,\n SessionSummary,\n} from '@deepseek-ai/dsh-client-connection/client';\nimport type { SessionEvent } from '@deepseek-ai/dsh-session/types';\n\n/** The `auto-continue` settings section (all fields optional on the wire; the host schema carries defaults). */\nexport interface AutoContinueSettings {\n /** Text automatically sent after an interruption. */\n continueText?: string;\n /** Grace period after an interruption before auto-sending (ms). */\n graceMs?: number;\n /** Minimum interval between two auto-continues per session (ms). */\n cooldownMs?: number;\n /** Max consecutive auto-continues per session before stopping. */\n maxConsecutive?: number;\n /** Scan recently interrupted sessions on page load / reconnect. */\n scanOnBoot?: boolean;\n /** Max sessions the scan checks (most recently updated). */\n scanLimit?: number;\n /** Scan only considers interruptions inside this window (ms). */\n freshMs?: number;\n /** Delay before scanning after a reconnect (ms). */\n reconnectScanDelayMs?: number;\n /** SSE reconnect backoff (ms). */\n reconnectBackoffMs?: number;\n /** Log `[auto-continue]` lines to the browser console. */\n verbose?: boolean;\n}\n\n/** Fully resolved configuration (built-in defaults + user overrides). */\nexport type AutoContinueConfig = Required<AutoContinueSettings>;\n\n/** Built-in defaults — must match the host schema defaults in src/index.ts. */\nexport const DEFAULT_CONFIG: AutoContinueConfig = {\n continueText: '继续',\n graceMs: 3000,\n cooldownMs: 20000,\n maxConsecutive: 3,\n scanOnBoot: true,\n scanLimit: 8,\n freshMs: 15 * 60 * 1000,\n reconnectScanDelayMs: 5000,\n reconnectBackoffMs: 3000,\n verbose: true,\n};\n\nfunction numberOr(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : fallback;\n}\n\nfunction booleanOr(value: unknown, fallback: boolean): boolean {\n return typeof value === 'boolean' ? value : fallback;\n}\n\n/** Resolve a (possibly partial / not-yet-loaded) settings section to a full config. */\nexport function resolveConfig(section: AutoContinueSettings | undefined): AutoContinueConfig {\n const value = section ?? {};\n const text =\n typeof value.continueText === 'string' && value.continueText.trim() !== ''\n ? value.continueText\n : DEFAULT_CONFIG.continueText;\n return {\n continueText: text,\n graceMs: numberOr(value.graceMs, DEFAULT_CONFIG.graceMs),\n cooldownMs: numberOr(value.cooldownMs, DEFAULT_CONFIG.cooldownMs),\n maxConsecutive: Math.max(1, numberOr(value.maxConsecutive, DEFAULT_CONFIG.maxConsecutive)),\n scanOnBoot: booleanOr(value.scanOnBoot, DEFAULT_CONFIG.scanOnBoot),\n scanLimit: Math.max(1, numberOr(value.scanLimit, DEFAULT_CONFIG.scanLimit)),\n freshMs: numberOr(value.freshMs, DEFAULT_CONFIG.freshMs),\n reconnectScanDelayMs: numberOr(value.reconnectScanDelayMs, DEFAULT_CONFIG.reconnectScanDelayMs),\n reconnectBackoffMs: numberOr(value.reconnectBackoffMs, DEFAULT_CONFIG.reconnectBackoffMs),\n verbose: booleanOr(value.verbose, DEFAULT_CONFIG.verbose),\n };\n}\n\n/** 视为「非人为中断」的回合结束原因。aborted(用户停止)与 blocked(策略拒绝)不在其中。 */\ntype NonHumanReason = 'error' | 'interrupted' | 'max-tokens';\n\nfunction isNonHumanReason(kind: string): kind is NonHumanReason {\n return kind === 'error' || kind === 'interrupted' || kind === 'max-tokens';\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** 浏览器当前 IANA 时区; 不可用时省略(宿主允许省略)。 */\nfunction clientTimeZone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || undefined;\n } catch {\n return undefined;\n }\n}\n\n/** 跨标签页互斥与冷却记录(仅浏览器本地, 不落盘到宿主)。 */\nconst lockPrefix = 'dsh-auto-continue:';\nconst lockKey = (sessionId: SessionId) => `${lockPrefix}lock:${sessionId}`;\nconst stampKey = (sessionId: SessionId) => `${lockPrefix}last:${sessionId}`;\n\n/** 尝试独占本次发送: 两个标签页同时触发时只有一个成功。 */\nfunction claimSend(sessionId: SessionId): boolean {\n try {\n const token = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n localStorage.setItem(lockKey(sessionId), token);\n return localStorage.getItem(lockKey(sessionId)) === token;\n } catch {\n return true; // 存储不可用(隐私模式等)时放行\n }\n}\n\nfunction releaseSend(sessionId: SessionId): void {\n try {\n localStorage.removeItem(lockKey(sessionId));\n } catch {\n /* ignore */\n }\n}\n\n/** 读/写「上次自动发送」时间戳(跨标签页冷却)。 */\nfunction readLastSend(sessionId: SessionId): number {\n try {\n return Number(localStorage.getItem(stampKey(sessionId)) ?? 0) || 0;\n } catch {\n return 0;\n }\n}\n\nfunction writeLastSend(sessionId: SessionId, at: number): void {\n try {\n localStorage.setItem(stampKey(sessionId), String(at));\n } catch {\n /* ignore */\n }\n}\n\n/** 每会话运行时状态。 */\ninterface SessionState {\n /** 连续自动「继续」次数; 成功回合或用户手动介入后归零。 */\n consecutive: number;\n /** 上次自动「继续」时间戳。 */\n lastAutoAt: number;\n /** 上次自动「继续」尝试(成功或失败)时间戳; 防止失败场景下的快速重试循环。 */\n lastAttemptAt: number;\n /** 我们上次自动发送的文本(用于识别自己的回显)。 */\n lastSentText: string;\n /** 宽限期定时器(进行中的待发送)。 */\n pendingTimer: number | undefined;\n /** 宿主权威 running 位(来自 host/session-status 与回合事件)。 */\n running: boolean | undefined;\n /** 当前排队消息数(来自 session/queue 帧)。 */\n queued: number;\n /** 子代理会话(host/session-added 带 parentSessionId)。 */\n subagent: boolean;\n}\n\nconst freshState = (): SessionState => ({\n consecutive: 0,\n lastAutoAt: 0,\n lastAttemptAt: 0,\n lastSentText: '',\n pendingTimer: undefined,\n running: undefined,\n queued: 0,\n subagent: false,\n});\n\n/** 判定一条 user/message 是否是我们自己自动发送的回显。 */\nfunction isOurEcho(state: SessionState, event: SessionEvent): boolean {\n if (event.type !== 'user/message') return false;\n const message = event.data;\n if (message.source.kind !== 'user') return false;\n if (state.lastSentText === '') return false;\n if (Date.now() - state.lastAutoAt > 30000) return false;\n const text = message.content\n .filter((part): part is { type: 'text'; text: string } => part.type === 'text')\n .map((part) => part.text)\n .join('');\n return text === state.lastSentText;\n}\n\n/** SSE 帧外壳: `{ rpcId, payload }`。 */\ntype FrameEnvelope<T> = { payload: T };\n\n/**\n * 事件流泵: 带指数退避的 SSE 重连循环。\n * - 从未收到任何帧(宿主未就绪): 退避重试, 不触发扫描\n * - 曾连上后断开: 重连, 并通过 onReconnect 通知外层(宿主可能崩溃重启过)\n */\nasync function pumpStream<T>(\n open: (signal: AbortSignal) => AsyncIterable<FrameEnvelope<T>>,\n onFrame: (payload: T) => void,\n onReconnect: () => void,\n getBackoff: () => number,\n log: (message: string) => void,\n signal: AbortSignal,\n): Promise<void> {\n let backoff = getBackoff();\n while (!signal.aborted) {\n let connected = false;\n try {\n for await (const envelope of open(signal)) {\n connected = true;\n onFrame(envelope.payload);\n }\n if (signal.aborted) return;\n } catch (error) {\n if (signal.aborted) return;\n log(`stream error: ${error instanceof Error ? error.message : String(error)}`);\n }\n if (!connected) {\n // 从未连上(宿主未就绪): 指数退避重试\n await sleep(backoff);\n backoff = Math.min(backoff * 2, 15000);\n continue;\n }\n // 曾连上后断开 → 重连并触发外层扫描\n backoff = getBackoff();\n onReconnect();\n await sleep(backoff);\n }\n}\n\n/** 插件主体: 一条 mux 流 + 一条 host 流 + 启动/重连扫描。 */\nexport class AutoContinueRunner {\n private readonly states = new Map<SessionId, SessionState>();\n private readonly muxAbort = new AbortController();\n private readonly hostAbort = new AbortController();\n private disposed = false;\n private reconnectScans = 0;\n\n /**\n * @param api - shared wire client (ctx.connection.api).\n * @param getConfig - read the current resolved configuration (settings scope).\n */\n constructor(\n private readonly api: IApiClient,\n private readonly getConfig: () => AutoContinueConfig,\n ) {\n const config = this.getConfig();\n void this.runMux();\n void this.runHost();\n if (config.scanOnBoot) {\n // 启动时连接可能尚未建立, 循环重试直到成功。\n void this.bootScanLoop();\n }\n this.log(\n `已启动(文本=\"${config.continueText}\", 宽限 ${config.graceMs}ms, ` +\n `冷却 ${config.cooldownMs}ms, 最多连续 ${config.maxConsecutive} 次)`,\n );\n }\n\n private log(message: string): void {\n if (this.getConfig().verbose) console.info(`[auto-continue] ${message}`);\n }\n\n dispose(): void {\n this.disposed = true;\n this.muxAbort.abort();\n this.hostAbort.abort();\n for (const state of this.states.values()) {\n if (state.pendingTimer !== undefined) clearTimeout(state.pendingTimer);\n }\n this.states.clear();\n }\n\n private state(sessionId: SessionId): SessionState {\n let state = this.states.get(sessionId);\n if (state === undefined) {\n state = freshState();\n this.states.set(sessionId, state);\n }\n return state;\n }\n\n private runMux(): Promise<void> {\n return pumpStream<MuxFrame>(\n (signal) => this.api.events.mux({}, signal),\n (payload) => this.onMuxFrame(payload),\n () => this.scheduleReconnectScan(),\n () => this.getConfig().reconnectBackoffMs,\n (m) => this.log(m),\n this.muxAbort.signal,\n );\n }\n\n private runHost(): Promise<void> {\n return pumpStream<HostFrame>(\n (signal) => this.api.events.host({}, signal),\n (payload) => this.onHostFrame(payload),\n () => this.scheduleReconnectScan(),\n () => this.getConfig().reconnectBackoffMs,\n (m) => this.log(m),\n this.hostAbort.signal,\n );\n }\n\n // ---------- mux 帧 ----------\n\n private onMuxFrame(frame: MuxFrame): void {\n switch (frame.type) {\n case 'session/event':\n this.onSessionEvent(frame.sessionId, frame.event);\n break;\n case 'session/queue':\n this.state(frame.sessionId).queued = frame.items.length;\n if (frame.items.length > 0) this.cancelPending(frame.sessionId, '出现排队消息');\n break;\n case 'stream/error':\n this.log(`mux stream/error: ${frame.error.code} ${frame.error.message}`);\n break;\n default:\n break; // session/subscribed、approval/*、question/*、session/jobs、session/projection 与本插件无关\n }\n }\n\n private onSessionEvent(sessionId: SessionId, event: SessionEvent): void {\n const state = this.state(sessionId);\n switch (event.type) {\n case 'turn/start':\n state.running = true;\n this.cancelPending(sessionId, '宿主自行开启新回合');\n break;\n case 'turn/end': {\n state.running = false;\n this.cancelPending(sessionId, '收到新的 turn/end');\n const reason = event.data.reason;\n if (reason.kind === 'completed') {\n // 成功回合: 恢复健康状态\n state.consecutive = 0;\n } else if (reason.kind === 'aborted') {\n // 用户主动停止: 不自动继续, 视为用户介入\n state.consecutive = 0;\n } else if (reason.kind === 'blocked') {\n // 策略拒绝: 不自动继续\n } else if (isNonHumanReason(reason.kind)) {\n this.schedule(sessionId, `turn/end:${reason.kind}`);\n }\n break;\n }\n case 'user/message':\n if (isOurEcho(state, event)) break; // 我们自己的回显\n if (event.data.source.kind === 'user') {\n // 用户手动介入\n state.consecutive = 0;\n this.cancelPending(sessionId, '用户手动发送消息');\n }\n break;\n default:\n break;\n }\n }\n\n // ---------- host 帧 ----------\n\n private onHostFrame(frame: HostFrame): void {\n switch (frame.type) {\n case 'host/session-status':\n this.state(frame.sessionId).running = frame.running;\n if (frame.running) this.cancelPending(frame.sessionId, '宿主报告会话开始运行');\n break;\n case 'host/session-added':\n this.state(frame.sessionId).subagent = frame.parentSessionId !== undefined;\n break;\n case 'host/agent-error':\n if (this.state(frame.sessionId).subagent) break;\n this.log(`host/agent-error(${frame.sessionId}): ${frame.message}`);\n this.schedule(frame.sessionId, 'host/agent-error');\n break;\n case 'host/session-removed':\n this.cancelPending(frame.sessionId, '会话已移除');\n this.states.delete(frame.sessionId);\n break;\n default:\n break;\n }\n }\n\n // ---------- 调度 ----------\n\n private schedule(sessionId: SessionId, reason: string): void {\n const state = this.state(sessionId);\n const config = this.getConfig();\n if (state.subagent) return; // 子代理会话由父代理处理, 不抢跑\n if (state.pendingTimer !== undefined) return; // 已有待发送\n if (Date.now() - state.lastAttemptAt < config.cooldownMs) return; // 冷却期(含失败尝试)\n if (state.consecutive >= config.maxConsecutive) {\n this.log(\n `跳过 ${sessionId}(${reason}): 已连续自动继续 ${state.consecutive} 次, 等待用户介入或成功回合`,\n );\n return;\n }\n if (state.queued > 0) return; // 已有排队消息, 宿主会自行唤醒\n const timer = setTimeout(() => {\n if (state.pendingTimer !== timer) return;\n state.pendingTimer = undefined;\n void this.fire(sessionId, reason);\n }, config.graceMs);\n state.pendingTimer = timer;\n this.log(\n `检测到非人为中断 ${sessionId}(${reason}), ${config.graceMs}ms 后自动发送「${config.continueText}」`,\n );\n }\n\n private cancelPending(sessionId: SessionId, why: string): void {\n const state = this.state(sessionId);\n if (state.pendingTimer === undefined) return;\n clearTimeout(state.pendingTimer);\n state.pendingTimer = undefined;\n this.log(`取消 ${sessionId} 的自动继续(${why})`);\n }\n\n private async fire(sessionId: SessionId, reason: string): Promise<void> {\n if (this.disposed) return;\n const state = this.state(sessionId);\n const config = this.getConfig();\n // 权威 running 检查: 优先用 host 帧, 未知时回退到 session.list\n if (state.running === undefined) {\n const running = await this.runningViaList(sessionId);\n if (running === undefined || running) {\n this.log(`跳过 ${sessionId}: 无法确认空闲(${running === undefined ? '未知' : '运行中'})`);\n return;\n }\n } else if (state.running) {\n this.log(`跳过 ${sessionId}: 会话仍在运行`);\n return;\n }\n if (state.queued > 0) {\n this.log(`跳过 ${sessionId}: 已有排队消息`);\n return;\n }\n // 跨标签页冷却\n if (Date.now() - readLastSend(sessionId) < config.cooldownMs) {\n this.log(`跳过 ${sessionId}: 其他标签页刚发送过`);\n return;\n }\n if (!claimSend(sessionId)) {\n this.log(`跳过 ${sessionId}: 其他标签页正在发送`);\n return;\n }\n const text = config.continueText;\n const zone = clientTimeZone();\n state.lastAttemptAt = Date.now(); // 先记账: 无论成败, 本次尝试都进入冷却\n try {\n const response = await this.api.sessions.prompt({\n sessionId,\n mode: 'queue',\n content: [{ type: 'text', text }],\n ...(zone === undefined ? {} : { clientTimeZone: zone }),\n });\n if (response.result.ok) {\n const now = Date.now();\n state.consecutive += 1;\n state.lastAutoAt = now;\n state.lastSentText = text;\n writeLastSend(sessionId, now);\n this.log(`已自动发送「${text}」到 ${sessionId}(${reason}), 第 ${state.consecutive} 次连续`);\n } else {\n this.log(\n `发送失败 ${sessionId}: ${response.result.error.code} ${response.result.error.message}`,\n );\n }\n } catch (error) {\n this.log(`发送异常 ${sessionId}: ${error instanceof Error ? error.message : String(error)}`);\n } finally {\n releaseSend(sessionId);\n }\n }\n\n private async runningViaList(sessionId: SessionId): Promise<boolean | undefined> {\n try {\n const response = await this.api.sessions.list({});\n if (!response.result.ok) return undefined;\n const item = response.result.value.items.find(\n (summary: SessionSummary) => summary.sessionId === sessionId,\n );\n return item === undefined ? undefined : item.running;\n } catch {\n return undefined;\n }\n }\n\n // ---------- 启动/重连扫描 ----------\n\n private scheduleReconnectScan(): void {\n this.reconnectScans += 1;\n const scan = this.reconnectScans;\n setTimeout(() => {\n if (scan !== this.reconnectScans || this.disposed) return;\n void this.scanLoop(6, this.getConfig().reconnectScanDelayMs);\n }, this.getConfig().reconnectScanDelayMs);\n }\n\n private async bootScanLoop(): Promise<void> {\n await this.scanLoop(Infinity, 3000);\n }\n\n /** 反复尝试扫描, 直到成功(宿主就绪)或达到次数上限。 */\n private async scanLoop(attempts: number, delayMs: number): Promise<void> {\n for (let attempt = 0; attempt < attempts && !this.disposed; attempt += 1) {\n try {\n if (await this.scanInterrupted()) return;\n } catch (error) {\n if (this.disposed) return;\n // 宿主未就绪时每 3s 重试; 只节流记录日志, 避免刷屏。\n if (attempt % 10 === 0) {\n this.log(\n `扫描失败(${attempt + 1}/${attempts === Infinity ? '∞' : attempts}): ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n if (attempt + 1 < attempts) await sleep(delayMs);\n }\n }\n\n /**\n * 扫描最近中断过的会话: 最后回合以非人为原因结束, 且其后没有新回合或用户消息。\n * @returns 是否成功完成一次扫描(宿主就绪)。\n */\n private async scanInterrupted(): Promise<boolean> {\n const config = this.getConfig();\n const response = await this.api.sessions.list({});\n if (!response.result.ok) return false;\n const items = response.result.value.items;\n const candidates = items\n .filter((summary) => !summary.running && summary.parentSessionId === undefined)\n .slice(0, config.scanLimit);\n const now = Date.now();\n for (const summary of candidates) {\n if (this.disposed) return true;\n const state = this.state(summary.sessionId);\n if (state.pendingTimer !== undefined) continue;\n if (state.consecutive >= config.maxConsecutive) continue;\n if (now - state.lastAttemptAt < config.cooldownMs) continue;\n let events;\n try {\n const page = await this.api.sessions.history({\n sessionId: summary.sessionId,\n maxMessages: 30,\n });\n if (!page.result.ok) continue;\n events = page.result.value.events;\n } catch {\n continue; // 会话可能刚被移除\n }\n // 从尾部找最后一个 turn/end(在分支内完成收窄)\n let lastEnd: SessionEvent<'turn/end'> | undefined;\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]?.event;\n if (event !== undefined && event.type === 'turn/end') {\n lastEnd = event;\n break;\n }\n }\n if (lastEnd === undefined) continue;\n const reason = lastEnd.data.reason;\n if (!isNonHumanReason(reason.kind)) continue;\n if (lastEnd.time < now - config.freshMs) continue; // 太久远, 不翻旧账\n // 该 turn/end 之后不能有新回合或用户消息(说明已被处理)\n let superseded = false;\n for (const entry of events) {\n const event = entry.event;\n if (event.seq <= lastEnd.seq) continue;\n if (event.type === 'turn/start') superseded = true;\n if (event.type === 'user/message' && event.data.source.kind === 'user') superseded = true;\n if (superseded) break;\n }\n if (superseded) continue;\n this.log(`扫描发现中断 ${summary.sessionId}(turn/end:${reason.kind}), 安排自动继续`);\n this.schedule(summary.sessionId, `scan:turn/end:${reason.kind}`);\n }\n return true;\n }\n}\n", "/**\n * `auto-continue` namespace dictionaries: copy for the plugin settings card\n * registered into the `settings.plugin.item` seat of the plugin-configuration\n * section. Includes the card-chrome keys the card component reads.\n */\n\n/** 简体中文词典(键集的事实来源)。 */\nexport const zh = {\n 'card.title': '自动继续',\n 'card.description': '请求因网络等原因(非人为)中断后, 自动发送「继续」续跑。',\n 'field.continueText': '继续文本',\n 'field.continueTextHint': '中断后自动发送的消息内容。',\n 'field.graceMs': '宽限期 (ms)',\n 'field.graceMsHint': '检测到中断后等待的时长; 期间宿主自行恢复则取消。',\n 'field.cooldownMs': '冷却时间 (ms)',\n 'field.cooldownMsHint': '同一会话两次自动「继续」的最小间隔, 失败尝试也计入。',\n 'field.maxConsecutive': '最大连续次数',\n 'field.maxConsecutiveHint': '同一会话连续自动「继续」的上限; 超过后停止, 直到用户手动介入或出现成功回合。',\n 'field.scanOnBoot': '启动/重连扫描',\n 'field.scanOnBootHint': '页面启动或重连时扫描最近中断的会话并自动续跑(如浏览器关闭期间宿主崩溃)。',\n 'field.scanLimit': '扫描会话数',\n 'field.scanLimitHint': '最多检查多少个最近更新的会话(不含运行中与子代理会话)。',\n 'field.freshMs': '扫描时间窗 (ms)',\n 'field.freshMsHint': '扫描只处理该时间窗内的中断。',\n 'field.reconnectScanDelayMs': '重连扫描延迟 (ms)',\n 'field.reconnectScanDelayMsHint': '重连后等待宿主完成恢复再扫描。',\n 'field.reconnectBackoffMs': '重连退避 (ms)',\n 'field.reconnectBackoffMsHint': '事件流断开后的重连间隔。',\n 'field.verbose': '详细日志',\n 'field.verboseHint': '在浏览器控制台输出 [auto-continue] 日志。',\n 'chrome.collapse': '收起设置',\n 'chrome.expand': '展开设置',\n 'chrome.unsaved': '未保存',\n 'chrome.readOnly': '当前部署的设置只读。',\n 'chrome.saveFailed': '部署未接受这些值, 已保留供你修改。',\n 'chrome.discard': '放弃',\n 'chrome.saving': '保存中…',\n 'chrome.save': '保存',\n 'chrome.overridden': '已覆盖',\n 'chrome.reset': '恢复默认',\n 'chrome.invalidNumber': '请输入数字, 留空则使用默认值。',\n 'chrome.inherit': '继承',\n 'chrome.on': '开',\n 'chrome.off': '关',\n} satisfies Record<string, string>;\n\n/** 本插件的键联合。 */\nexport type SettingsCardKey = keyof typeof zh;\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en: Record<SettingsCardKey, string> = {\n 'card.title': 'Auto continue',\n 'card.description': 'When a request is interrupted by a non-human cause, automatically send 「继续」 to resume.',\n 'field.continueText': 'Continue text',\n 'field.continueTextHint': 'Message automatically sent after an interruption.',\n 'field.graceMs': 'Grace period (ms)',\n 'field.graceMsHint': 'Wait after an interruption; cancelled if the host recovers on its own.',\n 'field.cooldownMs': 'Cooldown (ms)',\n 'field.cooldownMsHint': 'Minimum interval between auto-continues per session; failed attempts count too.',\n 'field.maxConsecutive': 'Max consecutive',\n 'field.maxConsecutiveHint': 'Max consecutive auto-continues per session; stops until a user intervenes or a turn completes.',\n 'field.scanOnBoot': 'Scan on load / reconnect',\n 'field.scanOnBootHint': 'Scan recently interrupted sessions on page load or reconnect (e.g. the host crashed while the browser was closed).',\n 'field.scanLimit': 'Scan limit',\n 'field.scanLimitHint': 'How many most-recently-updated sessions to check (running / subagent sessions excluded).',\n 'field.freshMs': 'Scan window (ms)',\n 'field.freshMsHint': 'Only interruptions inside this window are considered.',\n 'field.reconnectScanDelayMs': 'Reconnect scan delay (ms)',\n 'field.reconnectScanDelayMsHint': 'Wait for the host to finish recovering before scanning after a reconnect.',\n 'field.reconnectBackoffMs': 'Reconnect backoff (ms)',\n 'field.reconnectBackoffMsHint': 'Interval between event-stream reconnect attempts.',\n 'field.verbose': 'Verbose logs',\n 'field.verboseHint': 'Log [auto-continue] lines to the browser console.',\n 'chrome.collapse': 'Hide settings',\n 'chrome.expand': 'Show settings',\n 'chrome.unsaved': 'Unsaved',\n 'chrome.readOnly': 'This deployment stores settings read-only.',\n 'chrome.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'chrome.discard': 'Discard',\n 'chrome.saving': 'Saving…',\n 'chrome.save': 'Save',\n 'chrome.overridden': 'Overridden',\n 'chrome.reset': 'Reset to default',\n 'chrome.invalidNumber': 'Enter a number, or leave blank to use the default.',\n 'chrome.inherit': 'Inherit',\n 'chrome.on': 'On',\n 'chrome.off': 'Off',\n};\n", "/**\n * The auto-continue settings card: edits the `auto-continue` namespace fields\n * from the plugin-configuration section (the `settings.plugin.item` seat).\n *\n * Self-contained card chrome (disclosure header, staged fields, save/discard\n * footer) following the plugin-card store pattern of the DSH plugin\n * configuration section; styles live in `styles.ts` and use the DSH design\n * tokens so the card follows the active theme.\n */\nimport { useState, type ReactNode } from 'react';\nimport { createSnapshotStore, type SettingsScope, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client';\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';\nimport type { AutoContinueSettings } from './engine.ts';\nimport type { SettingsCardKey } from './locales.ts';\nimport {\n booleanField,\n CardForm,\n numberField,\n textField,\n type CardActions,\n type CardFieldState,\n type CardShell,\n} from './settings-form.ts';\nimport { injectStyles } from './styles.ts';\n\n// Styles must land during factory materialization so the module system's\n// style bookkeeping (HMR) owns them.\ninjectStyles();\n\n/** What the auto-continue card renders. */\nexport interface AutoContinueSettingsCardState extends CardShell {\n continueText: CardFieldState;\n graceMs: CardFieldState;\n cooldownMs: CardFieldState;\n maxConsecutive: CardFieldState;\n scanOnBoot: CardFieldState;\n scanLimit: CardFieldState;\n freshMs: CardFieldState;\n reconnectScanDelayMs: CardFieldState;\n reconnectBackoffMs: CardFieldState;\n verbose: CardFieldState;\n}\n\n/** The registration-side face the card's slot entry injects. */\nexport interface AutoContinueSettingsCardFace extends CardActions {\n hooks: {\n /** Card snapshot bound by the renderer as useAutoContinueSettingsCard. */\n autoContinueSettingsCard: SnapshotStore<AutoContinueSettingsCardState>;\n };\n}\n\n/** Bridges the `auto-continue` scope onto the card's staged form. */\nexport class AutoContinueSettingsCardController {\n private readonly form: CardForm<AutoContinueSettings>;\n private readonly store: SnapshotStore<AutoContinueSettingsCardState>;\n\n /**\n * @param scope - the bound settings scope for the `auto-continue` namespace.\n */\n constructor(scope: SettingsScope<AutoContinueSettings>) {\n this.form = new CardForm(scope, [\n textField('continueText'),\n numberField('graceMs', 0),\n numberField('cooldownMs', 0),\n numberField('maxConsecutive', 1),\n booleanField('scanOnBoot'),\n numberField('scanLimit', 1),\n numberField('freshMs', 0),\n numberField('reconnectScanDelayMs', 0),\n numberField('reconnectBackoffMs', 0),\n booleanField('verbose'),\n ]);\n this.store = this.form.bind(() => this.projection(), createSnapshotStore);\n }\n\n private projection(): AutoContinueSettingsCardState {\n return {\n ...this.form.shell(),\n continueText: this.form.field('continueText'),\n graceMs: this.form.field('graceMs'),\n cooldownMs: this.form.field('cooldownMs'),\n maxConsecutive: this.form.field('maxConsecutive'),\n scanOnBoot: this.form.field('scanOnBoot'),\n scanLimit: this.form.field('scanLimit'),\n freshMs: this.form.field('freshMs'),\n reconnectScanDelayMs: this.form.field('reconnectScanDelayMs'),\n reconnectBackoffMs: this.form.field('reconnectBackoffMs'),\n verbose: this.form.field('verbose'),\n };\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot and its form actions.\n */\n inject(): AutoContinueSettingsCardFace {\n return { hooks: { autoContinueSettingsCard: this.store }, ...this.form.actions() };\n }\n}\n\n/** Props the renderer binds for the auto-continue card. */\nexport type AutoContinueSettingsCardProps =\n PropsRuntime<'settings.plugin.item'> & PropsLocale<'auto-continue'> & InjectFace<AutoContinueSettingsCardFace>;\n\n/** Card chrome: a disclosure header naming the plugin and what its settings govern, the controls, and the save that writes them. */\nfunction SettingsCard(props: {\n t: (key: SettingsCardKey) => string;\n titleKey: SettingsCardKey;\n descriptionKey: SettingsCardKey;\n state: CardShell;\n onSave: () => void;\n onDiscard: () => void;\n children: ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const { state } = props;\n if (!state.available) return null;\n const title = props.t(props.titleKey);\n const blocked = !state.dirty || state.invalid || state.saving;\n return (\n <li className={open ? 'dshAcCard dshAcCardOpen' : 'dshAcCard'}>\n <button\n type=\"button\"\n className=\"dshAcHeader\"\n aria-expanded={open}\n aria-label={`${props.t(open ? 'chrome.collapse' : 'chrome.expand')}: ${title}`}\n title={props.t(props.descriptionKey)}\n onClick={() => setOpen(!open)}\n >\n <span className=\"dshAcHeadText\">\n <span className=\"dshAcName\">{title}</span>\n <span className=\"dshAcDescription\">{props.t(props.descriptionKey)}</span>\n </span>\n {state.dirty ? (\n <span className=\"dshAcPending\" title={props.t('chrome.unsaved')}>\n {props.t('chrome.unsaved')}\n </span>\n ) : null}\n <span className={open ? 'dshAcChevron dshAcChevronOpen' : 'dshAcChevron'}>▾</span>\n </button>\n {open ? (\n <div className=\"dshAcBody\">\n {!state.writable ? (\n <p className=\"dshAcReadOnly\" role=\"status\">{props.t('chrome.readOnly')}</p>\n ) : null}\n {props.children}\n <div className=\"dshAcFooter\">\n {state.failed ? (\n <p className=\"dshAcFailed\" role=\"status\">{props.t('chrome.saveFailed')}</p>\n ) : null}\n <button\n type=\"button\"\n className=\"dshAcDiscard\"\n disabled={!state.dirty || state.saving}\n onClick={props.onDiscard}\n >\n {props.t('chrome.discard')}\n </button>\n <button type=\"button\" className=\"dshAcSave\" disabled={blocked} onClick={props.onSave}>\n {props.t(!state.saving ? 'chrome.save' : 'chrome.saving')}\n </button>\n </div>\n </div>\n ) : null}\n </li>\n );\n}\n\n/** Props every field control needs regardless of its value type. */\ninterface FieldProps {\n id: string;\n label: string;\n hint: string;\n text: string;\n overridden: boolean;\n invalid: boolean;\n disabled: boolean;\n t: (key: SettingsCardKey) => string;\n onEdit: (text: string) => void;\n onReset: () => void;\n}\n\n/** A staged value field; `numeric` only hints the keypad, which drafts a field accepts is decided by its spec. */\nfunction ValueField(props: FieldProps & { numeric?: boolean; placeholder?: string }) {\n return (\n <div className=\"dshAcField\">\n <div className=\"dshAcHead\">\n <label className=\"dshAcLabel\" htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className=\"dshAcBadges\">\n <span className=\"dshAcBadge\">{props.t('chrome.overridden')}</span>\n <button type=\"button\" className=\"dshAcReset\" disabled={props.disabled} onClick={props.onReset}>\n {props.t('chrome.reset')}\n </button>\n </span>\n ) : null}\n </div>\n <input\n id={props.id}\n className={props.invalid ? 'dshAcInput dshAcInputInvalid' : 'dshAcInput'}\n type=\"text\"\n inputMode={props.numeric === true ? 'numeric' : undefined}\n aria-invalid={props.invalid || undefined}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n onChange={(event) => props.onEdit(event.target.value)}\n />\n <p className={props.invalid ? 'dshAcInvalid' : 'dshAcHint'}>\n {props.invalid ? props.t('chrome.invalidNumber') : props.hint}\n </p>\n </div>\n );\n}\n\n/** A staged boolean field: inherit / on / off. */\nfunction BooleanField(props: FieldProps) {\n return (\n <div className=\"dshAcField\">\n <div className=\"dshAcHead\">\n <label className=\"dshAcLabel\" htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className=\"dshAcBadges\">\n <span className=\"dshAcBadge\">{props.t('chrome.overridden')}</span>\n <button type=\"button\" className=\"dshAcReset\" disabled={props.disabled} onClick={props.onReset}>\n {props.t('chrome.reset')}\n </button>\n </span>\n ) : null}\n </div>\n <select\n id={props.id}\n className=\"dshAcSelect\"\n value={props.text}\n disabled={props.disabled}\n onChange={(event) => props.onEdit(event.target.value)}\n >\n <option value=\"\">{props.t('chrome.inherit')}</option>\n <option value=\"true\">{props.t('chrome.on')}</option>\n <option value=\"false\">{props.t('chrome.off')}</option>\n </select>\n <p className=\"dshAcHint\">{props.hint}</p>\n </div>\n );\n}\n\n/**\n * Render the auto-continue card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function AutoContinueSettingsCard(props: AutoContinueSettingsCardProps) {\n const { t } = props;\n const state = props.useAutoContinueSettingsCard((snapshot) => snapshot);\n const disabled = !state.writable;\n const shared = { t, disabled };\n return (\n <SettingsCard\n t={t}\n titleKey=\"card.title\"\n descriptionKey=\"card.description\"\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <ValueField\n id=\"auto-continue-continue-text\"\n label={t('field.continueText')}\n hint={t('field.continueTextHint')}\n {...shared}\n {...state.continueText}\n onEdit={(text) => props.edit('continueText', text)}\n onReset={() => props.resetField('continueText')}\n />\n <ValueField\n id=\"auto-continue-grace-ms\"\n label={t('field.graceMs')}\n hint={t('field.graceMsHint')}\n numeric\n {...shared}\n {...state.graceMs}\n onEdit={(text) => props.edit('graceMs', text)}\n onReset={() => props.resetField('graceMs')}\n />\n <ValueField\n id=\"auto-continue-cooldown-ms\"\n label={t('field.cooldownMs')}\n hint={t('field.cooldownMsHint')}\n numeric\n {...shared}\n {...state.cooldownMs}\n onEdit={(text) => props.edit('cooldownMs', text)}\n onReset={() => props.resetField('cooldownMs')}\n />\n <ValueField\n id=\"auto-continue-max-consecutive\"\n label={t('field.maxConsecutive')}\n hint={t('field.maxConsecutiveHint')}\n numeric\n {...shared}\n {...state.maxConsecutive}\n onEdit={(text) => props.edit('maxConsecutive', text)}\n onReset={() => props.resetField('maxConsecutive')}\n />\n <BooleanField\n id=\"auto-continue-scan-on-boot\"\n label={t('field.scanOnBoot')}\n hint={t('field.scanOnBootHint')}\n {...shared}\n {...state.scanOnBoot}\n onEdit={(text) => props.edit('scanOnBoot', text)}\n onReset={() => props.resetField('scanOnBoot')}\n />\n <ValueField\n id=\"auto-continue-scan-limit\"\n label={t('field.scanLimit')}\n hint={t('field.scanLimitHint')}\n numeric\n {...shared}\n {...state.scanLimit}\n onEdit={(text) => props.edit('scanLimit', text)}\n onReset={() => props.resetField('scanLimit')}\n />\n <ValueField\n id=\"auto-continue-fresh-ms\"\n label={t('field.freshMs')}\n hint={t('field.freshMsHint')}\n numeric\n {...shared}\n {...state.freshMs}\n onEdit={(text) => props.edit('freshMs', text)}\n onReset={() => props.resetField('freshMs')}\n />\n <ValueField\n id=\"auto-continue-reconnect-scan-delay\"\n label={t('field.reconnectScanDelayMs')}\n hint={t('field.reconnectScanDelayMsHint')}\n numeric\n {...shared}\n {...state.reconnectScanDelayMs}\n onEdit={(text) => props.edit('reconnectScanDelayMs', text)}\n onReset={() => props.resetField('reconnectScanDelayMs')}\n />\n <ValueField\n id=\"auto-continue-reconnect-backoff\"\n label={t('field.reconnectBackoffMs')}\n hint={t('field.reconnectBackoffMsHint')}\n numeric\n {...shared}\n {...state.reconnectBackoffMs}\n onEdit={(text) => props.edit('reconnectBackoffMs', text)}\n onReset={() => props.resetField('reconnectBackoffMs')}\n />\n <BooleanField\n id=\"auto-continue-verbose\"\n label={t('field.verbose')}\n hint={t('field.verboseHint')}\n {...shared}\n {...state.verbose}\n onEdit={(text) => props.edit('verbose', text)}\n onReset={() => props.resetField('verbose')}\n />\n </SettingsCard>\n );\n}\n", "/**\n * Staged form model behind the plugin settings card — a self-contained\n * implementation of the plugin-card store pattern used by the DSH plugin\n * configuration section.\n *\n * A card stages what the user types and writes it only when they save. Each\n * settings write is a durable, revision-fenced document mutation, so staging\n * keeps what is on screen exactly what a save would store. A field shows its\n * effective value — the user layer over the composition layer over the schema\n * default — and whether the user layer carries it (presence, not value\n * equality, marks an override).\n */\nimport type { SettingsScope, SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client';\n\n/** The write one field's staged text performs when the card is saved. */\nexport type FieldWrite = { kind: 'set'; value: unknown } | { kind: 'clear' };\n\n/** How one field converts between its stored value and its draft text. */\nexport interface CardFieldSpec {\n /** Field name inside the namespace section. */\n field: string;\n /** Render a stored value as draft text; the empty string when the section carries none. */\n format: (value: unknown) => string;\n /**\n * The write this draft text stages, or undefined when the text is not a\n * value this field accepts — which blocks the save rather than discarding it.\n */\n parse: (text: string) => FieldWrite | undefined;\n}\n\n/** One field as the card's control renders it. */\nexport interface CardFieldState {\n /** Draft text the control renders. */\n text: string;\n /** Whether saving would leave a user-layer entry for this field. */\n overridden: boolean;\n /** Whether the draft is not a value this field accepts, which blocks saving. */\n invalid: boolean;\n}\n\n/** Form state every plugin card shares. */\nexport interface CardShell {\n /** False while the namespace is not served to this client; the card renders nothing. */\n available: boolean;\n /** Whether the Host document accepts writes. */\n writable: boolean;\n /** Whether the form holds edits that a save would write. */\n dirty: boolean;\n /** Whether any staged draft is invalid, which blocks the save. */\n invalid: boolean;\n /** Whether a save is crossing the wire. */\n saving: boolean;\n /** Whether the last save did not land as staged; cleared by the next edit or save. */\n failed: boolean;\n}\n\n/** The write actions the card's slot entry injects. */\nexport interface CardActions {\n /** Stage draft text for one field. */\n edit: (field: string, text: string) => void;\n /** Stage a clear, so saving lets the field re-inherit the composition layer. */\n resetField: (field: string) => void;\n /** Write every staged edit, then re-seed from what the Host accepted. */\n save: () => void;\n /** Drop every staged edit. */\n discard: () => void;\n}\n\n/** A whole-number field. An empty draft clears the field; a non-number or out-of-range draft blocks the save. */\nexport function numberField(field: string, min = 0): CardFieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'number' ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim();\n if (trimmed === '') return { kind: 'clear' };\n const parsed = Number(trimmed);\n if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < min) return undefined;\n return { kind: 'set', value: parsed };\n },\n };\n}\n\n/** A free-text field. An empty draft clears the field, so emptying the control and saving is the same gesture as resetting it. */\nexport function textField(field: string): CardFieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'string' ? value : ''),\n parse: (text) => {\n const trimmed = text.trim();\n return trimmed === '' ? { kind: 'clear' } : { kind: 'set', value: trimmed };\n },\n };\n}\n\n/** A boolean field, edited through true/false draft text; an empty draft inherits. */\nexport function booleanField(field: string): CardFieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim();\n if (trimmed === '') return { kind: 'clear' };\n if (trimmed === 'true') return { kind: 'set', value: true };\n if (trimmed === 'false') return { kind: 'set', value: false };\n return undefined;\n },\n };\n}\n\n/** One field's staged edit. */\ninterface StagedEdit {\n /** Draft text the control renders. */\n text: string;\n /** True when this edit clears the field whatever text it shows. */\n clear: boolean;\n}\n\n/**\n * Stages one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted, so the\n * outcome is read back from the section rather than predicted here. A save\n * that did not land keeps its drafts, so the user can correct them instead of\n * retyping.\n */\nexport class CardForm<T> {\n private readonly specs: Map<string, CardFieldSpec>;\n private readonly staged = new Map<string, StagedEdit>();\n private readonly listeners = new Set<() => void>();\n private saving = false;\n private failed = false;\n\n /**\n * @param scope - the bound settings scope for this card's namespace.\n * @param specs - the section fields this card edits.\n */\n constructor(\n private readonly scope: SettingsScope<T>,\n specs: CardFieldSpec[],\n ) {\n this.specs = new Map(specs.map((spec) => [spec.field, spec]));\n this.scope.subscribe(() => this.publish());\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<S>(project: () => S, createStore: (init: S) => SnapshotStore<S>): SnapshotStore<S> {\n const store = createStore(project());\n this.listeners.add(() => store.set(project()));\n return store;\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot();\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: this.plan().length > 0,\n invalid: this.plan().some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n };\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): CardFieldState {\n const spec = this.specOf(field);\n const staged = this.staged.get(field);\n if (staged === undefined) {\n return {\n text: spec.format(this.sectionValue(field)),\n overridden: this.stored(field),\n invalid: false,\n };\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text);\n return {\n text: staged.text,\n overridden: write?.kind === 'set',\n invalid: write === undefined,\n };\n }\n\n /** The actions the card's slot registration injects. */\n actions(): CardActions {\n return {\n edit: (field, text) => this.stage(field, { text, clear: false }),\n resetField: (field) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true });\n },\n save: () => void this.save(),\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return;\n this.staged.clear();\n this.failed = false;\n this.publish();\n },\n };\n }\n\n /**\n * Write every staged edit, then re-seed from what the Host accepted.\n * @returns settlement after every write and the read-back.\n */\n async save(): Promise<void> {\n const plan = this.plan();\n const writes = plan.flatMap((item) => (item.run === undefined ? [] : [item.run]));\n if (plan.length === 0 || this.saving || writes.length !== plan.length) return;\n // Snapshot the fields this save writes, so edits staged while it is in\n // flight survive: only the staged keys this save actually wrote are cleared.\n const fields = new Set(plan.map((item) => item.field));\n this.saving = true;\n this.failed = false;\n this.publish();\n let landed = true;\n for (const write of writes) {\n landed = (await write()) && landed;\n }\n if (landed) {\n for (const field of fields) this.staged.delete(field);\n }\n this.saving = false;\n this.failed = !landed;\n this.publish();\n }\n\n /**\n * Every staged edit a save would write. An entry whose draft is not a value\n * its field accepts carries no write: the form is still dirty, and the save\n * refuses rather than dropping the edit. A staged edit that matches the\n * effective section is not a write at all.\n */\n private plan(): { field: string; run: (() => Promise<boolean>) | undefined }[] {\n const plan: { field: string; run: (() => Promise<boolean>) | undefined }[] = [];\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field);\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, run: () => this.clear(field) });\n continue;\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue;\n const write = spec.parse(staged.text);\n if (write === undefined) plan.push({ field, run: undefined });\n else if (write.kind === 'clear') plan.push({ field, run: () => this.clear(field) });\n else plan.push({ field, run: () => this.store(field, write.value) });\n }\n return plan;\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field);\n return !this.stored(field);\n }\n\n private async store(field: string, value: unknown): Promise<boolean> {\n await this.scope.set(field, value);\n return this.userLayer()?.[field] === value;\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit);\n this.failed = false;\n this.publish();\n }\n\n private specOf(field: string): CardFieldSpec {\n const spec = this.specs.get(field);\n if (spec === undefined) throw new Error(`settings card has no field ${field}`);\n return spec;\n }\n\n private sectionValue(field: string): unknown {\n return (this.scope.getSnapshot().value as Record<string, unknown> | undefined)?.[field];\n }\n\n private baseValue(field: string): unknown {\n return (this.scope.getSnapshot().base as Record<string, unknown> | undefined)?.[field];\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.scope.getSnapshot().user as Record<string, unknown> | undefined;\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer();\n return user !== undefined && Object.prototype.hasOwnProperty.call(user, field);\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener();\n }\n}\n", "/**\n * Styles for the auto-continue settings card, injected at factory\n * materialization so the client module system's style bookkeeping (HMR) owns\n * them. Uses the DSH design tokens (`--dsw-alias-*`) so the card follows the\n * active theme.\n */\n\nconst css = `\n.dshAcCard {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n border-radius: 12px;\n list-style: none;\n transition: border-color .16s, background .16s;\n}\n.dshAcCard:hover { border-color: var(--dsw-alias-label-dimmed); }\n.dshAcCardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n.dshAcHeader {\n appearance: none;\n width: 100%;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: none;\n border: 0;\n border-radius: 12px;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n display: flex;\n}\n.dshAcHeader:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: -2px; }\n.dshAcHeadText { flex-direction: column; flex: 1; gap: 4px; min-width: 0; display: flex; }\n.dshAcName { color: var(--dsw-alias-label-primary); font-size: 15px; font-weight: 600; line-height: 1.4; }\n.dshAcDescription { color: var(--dsw-alias-label-tertiary); font-size: 13px; line-height: 1.5; }\n.dshAcChevron { color: var(--dsw-alias-label-tertiary); flex: none; transition: transform .16s; }\n.dshAcChevronOpen { transform: rotate(180deg); }\n.dshAcBody { border-top: 1px solid var(--dsw-alias-border-l2); margin: 0 16px; padding-bottom: 8px; }\n.dshAcReadOnly { color: var(--dsw-alias-label-tertiary); margin: 12px 0 0; font-size: 12px; line-height: 1.5; }\n.dshAcPending {\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n border-radius: 999px;\n flex: none;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n.dshAcFooter {\n border-top: 1px solid var(--dsw-alias-border-l2);\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 12px 0 4px;\n display: flex;\n}\n.dshAcFailed { min-width: 0; color: var(--dsw-alias-label-error); flex: 1; margin: 0; font-size: 12px; line-height: 1.5; }\n.dshAcDiscard, .dshAcSave {\n appearance: none;\n font: inherit;\n cursor: pointer;\n border: 1px solid transparent;\n border-radius: 8px;\n padding: 5px 14px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcDiscard { border-color: var(--dsw-alias-border-l2); color: var(--dsw-alias-label-secondary); background: none; }\n.dshAcDiscard:hover:not(:disabled) { color: var(--dsw-alias-label-primary); border-color: var(--dsw-alias-label-dimmed); }\n.dshAcSave { background: var(--dsw-alias-label-primary); color: var(--dsw-alias-bg-layer-3); }\n.dshAcDiscard:disabled, .dshAcSave:disabled { opacity: .4; cursor: default; }\n.dshAcDiscard:focus-visible, .dshAcSave:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 1px; }\n.dshAcField { flex-direction: column; gap: 6px; padding: 12px 0; display: flex; }\n.dshAcField + .dshAcField { border-top: 1px solid var(--dsw-alias-border-l2); }\n.dshAcHead { align-items: center; gap: 8px; display: flex; }\n.dshAcLabel { min-width: 0; color: var(--dsw-alias-label-primary); flex: 1; font-size: 13px; font-weight: 500; line-height: 1.5; }\n.dshAcBadges { align-items: center; gap: 8px; display: inline-flex; }\n.dshAcBadge {\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n.dshAcReset {\n font: inherit;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n background: none;\n border: none;\n padding: 0;\n font-size: 12px;\n line-height: 1.5;\n}\n.dshAcReset:hover:not(:disabled) { color: var(--dsw-alias-label-primary); }\n.dshAcReset:disabled { cursor: default; }\n.dshAcInput {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n height: 34px;\n font: inherit;\n color: var(--dsw-alias-label-primary);\n border-radius: 8px;\n padding: 0 12px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcInput:focus-visible { border-color: var(--dsw-alias-brand-primary); outline: none; }\n.dshAcInput:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n.dshAcInputInvalid { border-color: var(--dsw-alias-label-error); }\n.dshAcSelect {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n height: 34px;\n font: inherit;\n color: var(--dsw-alias-label-primary);\n border-radius: 8px;\n padding: 0 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcSelect:focus-visible { border-color: var(--dsw-alias-brand-primary); outline: none; }\n.dshAcSelect:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n.dshAcInvalid { color: var(--dsw-alias-label-error); margin: 0; font-size: 12px; line-height: 1.5; }\n.dshAcHint { color: var(--dsw-alias-label-tertiary); margin: 0; font-size: 12px; line-height: 1.5; }\n`;\n\n/** Inject the stylesheet once; a no-op outside a browser environment. */\nexport function injectStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.querySelector('style[data-plugin-css=\"auto-continue/card\"]') !== null) return;\n const tag = document.createElement('style');\n tag.dataset.plugin = 'dsh-client-auto-continue';\n tag.dataset.pluginCss = 'auto-continue/card';\n tag.textContent = css;\n document.head.appendChild(tag);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-client-auto-continue",
|
|
3
3
|
"description": "DSH Web UI plugin: automatically sends \"继续\" (continue) when a request is interrupted by network errors or other non-human causes",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"files": [
|
|
20
20
|
"lib",
|
|
21
21
|
"cordis.patch.yml",
|
|
22
|
+
"scripts",
|
|
22
23
|
"README.md",
|
|
23
24
|
"README.zh.md",
|
|
24
25
|
"LICENSE"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Vendor patch for a known DSH limitation (0.1.0-rc.6):
|
|
4
|
+
*
|
|
5
|
+
* The web plugin-configuration section only exposes settings namespaces listed
|
|
6
|
+
* in `WEB_SETTINGS_NAMESPACES`, hardcoded in the installed
|
|
7
|
+
* `@deepseek-ai/dsh-host-apiproxy` bundle ("adding a section to that page is a
|
|
8
|
+
* decision made here rather than by the registering plugin. Moving that
|
|
9
|
+
* declaration to `settings.register()` ... is deferred work"). Without this
|
|
10
|
+
* patch the browser half of a third-party plugin's settings card reads
|
|
11
|
+
* `settings-not-exposed` and renders nothing.
|
|
12
|
+
*
|
|
13
|
+
* This script adds the `auto-continue` namespace to that allowlist in EVERY
|
|
14
|
+
* reachable dsh installation: the profile-linked copy (pnpm store / npx cache)
|
|
15
|
+
* and a global `npm i -g @deepseek-ai/dsh` install under the active Node
|
|
16
|
+
* version, plus the invoking directory's own install. It is idempotent:
|
|
17
|
+
* re-running it after any dsh reinstall reapplies the patch to the copies
|
|
18
|
+
* that lack it.
|
|
19
|
+
*
|
|
20
|
+
* Usage: node scripts/patch-expose.mjs
|
|
21
|
+
*/
|
|
22
|
+
import { createRequire } from 'node:module';
|
|
23
|
+
import { readFileSync, writeFileSync, realpathSync } from 'node:fs';
|
|
24
|
+
import { dirname, join } from 'node:path';
|
|
25
|
+
import { homedir } from 'node:os';
|
|
26
|
+
|
|
27
|
+
/** The namespace this plugin's settings card edits. */
|
|
28
|
+
const NS = 'auto-continue';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Collect candidate dsh-host-apiproxy package.json paths: the profile-linked
|
|
32
|
+
* copy, a global install under the active Node version (nvm layout), and the
|
|
33
|
+
* invoking directory's own install. Deduplicated by real path.
|
|
34
|
+
*/
|
|
35
|
+
function candidatePackageJsons() {
|
|
36
|
+
const found = new Set();
|
|
37
|
+
const add = (pkgJson) => {
|
|
38
|
+
try {
|
|
39
|
+
found.add(realpathSync(pkgJson));
|
|
40
|
+
} catch {
|
|
41
|
+
/* candidate not present */
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const tryResolve = (requireFn) => {
|
|
45
|
+
try {
|
|
46
|
+
add(requireFn.resolve('@deepseek-ai/dsh-host-apiproxy/package.json'));
|
|
47
|
+
} catch {
|
|
48
|
+
/* not resolvable from this anchor */
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// 1. The copy the profile's node_modules links to.
|
|
53
|
+
tryResolve(createRequire(join(homedir(), '.dsh', 'profiles', 'web', 'package.json')));
|
|
54
|
+
// 2. A global install under the active Node version's nvm layout
|
|
55
|
+
// (`<nvm>/<version>/lib/node_modules/@deepseek-ai/dsh`).
|
|
56
|
+
try {
|
|
57
|
+
const globalRoot = realpathSync(join(process.execPath, '..', '..', 'lib', 'node_modules'));
|
|
58
|
+
tryResolve(createRequire(join(globalRoot, '@deepseek-ai', 'dsh', 'package.json')));
|
|
59
|
+
} catch {
|
|
60
|
+
/* not an nvm-style global root */
|
|
61
|
+
}
|
|
62
|
+
// 3. The invoking directory's own install.
|
|
63
|
+
tryResolve(createRequire(join(process.cwd(), 'package.json')));
|
|
64
|
+
return [...found];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const candidates = candidatePackageJsons();
|
|
68
|
+
if (candidates.length === 0) {
|
|
69
|
+
console.error('[patch-expose] could not resolve any @deepseek-ai/dsh-host-apiproxy installation');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let patchedAny = false;
|
|
74
|
+
for (const packageJson of candidates) {
|
|
75
|
+
const bundlePath = join(dirname(packageJson), 'lib', 'index.js');
|
|
76
|
+
const source = readFileSync(bundlePath, 'utf8');
|
|
77
|
+
if (source.includes(`"${NS}"`)) {
|
|
78
|
+
console.log(`[patch-expose] ${NS} already present in ${bundlePath} — skipped.`);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const marker = `\t"web-search-deepseek"\n];`;
|
|
82
|
+
if (!source.includes(marker)) {
|
|
83
|
+
console.error(`[patch-expose] could not locate the WEB_SETTINGS_NAMESPACES tail in ${bundlePath}`);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const patched = source.replace(marker, `\t"web-search-deepseek",\n\t"${NS}"\n];`);
|
|
87
|
+
writeFileSync(bundlePath, patched);
|
|
88
|
+
patchedAny = true;
|
|
89
|
+
console.log(`[patch-expose] added "${NS}" to WEB_SETTINGS_NAMESPACES in ${bundlePath}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (patchedAny) console.log('[patch-expose] restart `dsh web` for the change to take effect.');
|