@rainbow-robotics/muscat-plugin-kit 0.1.2-dev.50 → 0.1.2-dev.52
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/cli/src/bridge.mjs +7 -2
- package/cli/src/dev.mjs +112 -2
- package/cli/src/devBack.mjs +99 -2
- package/cli/src/socketBridge.mjs +5 -1
- package/cli/src/templates-embedded.mjs +1 -1
- package/cli/src/zenohDev.mjs +75 -0
- package/cli/storybook-dist/project.json +1 -1
- package/cli/templates/common/package.json +2 -0
- package/cli/vite.mjs +11 -0
- package/package.json +3 -3
package/cli/src/bridge.mjs
CHANGED
|
@@ -63,7 +63,7 @@ function ensureImage() {
|
|
|
63
63
|
* Build the image, preflight the port, and start the bridge container.
|
|
64
64
|
* Returns true if bridge started, false if port was already in use (caller decides).
|
|
65
65
|
*/
|
|
66
|
-
export async function startBridge() {
|
|
66
|
+
export async function startBridge({ zenohPort = null } = {}) {
|
|
67
67
|
assertDockerReady();
|
|
68
68
|
|
|
69
69
|
// remove our own stale container first, then check the host port is free
|
|
@@ -73,15 +73,20 @@ export async function startBridge() {
|
|
|
73
73
|
ensureImage();
|
|
74
74
|
|
|
75
75
|
log.step("starting Socket.IO bridge container…");
|
|
76
|
+
const portFlags = [
|
|
77
|
+
"-p", `127.0.0.1:${BRIDGE_PORT}:${BRIDGE_PORT}`,
|
|
78
|
+
...(zenohPort ? ["-p", `${zenohPort}:${zenohPort}`] : []),
|
|
79
|
+
];
|
|
76
80
|
const up = spawnSync(
|
|
77
81
|
"docker",
|
|
78
|
-
["run", "-d", "--name", BRIDGE_CONTAINER,
|
|
82
|
+
["run", "-d", "--name", BRIDGE_CONTAINER, ...portFlags, BRIDGE_IMAGE],
|
|
79
83
|
{ stdio: "inherit" },
|
|
80
84
|
);
|
|
81
85
|
if (up.status !== 0) throw new Error("failed to start bridge container.");
|
|
82
86
|
|
|
83
87
|
await waitForPort(BRIDGE_PORT);
|
|
84
88
|
log.step(`Socket.IO bridge listening on ws://127.0.0.1:${BRIDGE_PORT}`);
|
|
89
|
+
if (zenohPort) log.step(`Zenoh dev peer port published on :${zenohPort}`);
|
|
85
90
|
return true;
|
|
86
91
|
}
|
|
87
92
|
|
package/cli/src/dev.mjs
CHANGED
|
@@ -1,10 +1,105 @@
|
|
|
1
1
|
// muscat-pk dev — run the Socket.IO bridge (Docker), dev:ui, and dev:back together.
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { release } from "node:os";
|
|
5
|
+
import { resolve } from "node:path";
|
|
2
6
|
import { runDevUi } from "./devUi.mjs";
|
|
3
7
|
import { runDevBack, stopDevBackContainers } from "./devBack.mjs";
|
|
4
8
|
import { startBridge, stopBridge, BRIDGE_CONTAINER, BRIDGE_PORT } from "./bridge.mjs";
|
|
5
9
|
import { assertManifestPorts } from "./manifest.mjs";
|
|
6
10
|
import { formatPortRanges } from "./ports.mjs";
|
|
7
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
ensureDocker,
|
|
13
|
+
ensureIdeVenv,
|
|
14
|
+
findPluginRoot,
|
|
15
|
+
log,
|
|
16
|
+
prompt,
|
|
17
|
+
promptRobotConnection,
|
|
18
|
+
venvPython,
|
|
19
|
+
} from "./util.mjs";
|
|
20
|
+
import { detectRouteAddress, ensureRemoteZenohEnv, getFreePort, isRemoteRobot } from "./zenohDev.mjs";
|
|
21
|
+
|
|
22
|
+
const DEFAULT_HOST_AGENT_PORT = 18080;
|
|
23
|
+
const isWsl = () => process.platform === "linux" && /microsoft|wsl/i.test(release());
|
|
24
|
+
const canAutoStartHostAgent = () => process.platform === "darwin" || isWsl();
|
|
25
|
+
|
|
26
|
+
function waitForHostAgent(port, { timeoutMs = 30_000 } = {}) {
|
|
27
|
+
const deadline = Date.now() + timeoutMs;
|
|
28
|
+
const url = `http://127.0.0.1:${port}/health`;
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const probe = async () => {
|
|
31
|
+
try {
|
|
32
|
+
const res = await fetch(url);
|
|
33
|
+
if (res.ok) return resolve(true);
|
|
34
|
+
} catch {
|
|
35
|
+
// keep polling
|
|
36
|
+
}
|
|
37
|
+
if (Date.now() >= deadline) {
|
|
38
|
+
reject(new Error(`host SDK agent did not become ready at ${url}`));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
setTimeout(probe, 300);
|
|
42
|
+
};
|
|
43
|
+
probe();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function maybeStartHostAgent(root, { robotIp, robotToken }) {
|
|
48
|
+
if (process.env.MUSCAT_HOST_AGENT_URL) {
|
|
49
|
+
log.step(`host SDK agent → ${process.env.MUSCAT_HOST_AGENT_URL}`);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
if (process.env.MUSCAT_HOST_AGENT_DISABLE === "1") return null;
|
|
53
|
+
if (!canAutoStartHostAgent() || !isRemoteRobot(robotIp)) return null;
|
|
54
|
+
|
|
55
|
+
const agentPath = resolve(root, "py", "host_agent.py");
|
|
56
|
+
if (!existsSync(agentPath)) return null;
|
|
57
|
+
|
|
58
|
+
const wsl = isWsl();
|
|
59
|
+
if (wsl) await ensureRemoteZenohEnv(robotIp, { log });
|
|
60
|
+
|
|
61
|
+
const bindHost = wsl ? "0.0.0.0" : "127.0.0.1";
|
|
62
|
+
const containerHost = wsl
|
|
63
|
+
? process.env.MUSCAT_HOST_AGENT_CONTAINER_HOST || await detectRouteAddress(robotIp)
|
|
64
|
+
: "host.docker.internal";
|
|
65
|
+
|
|
66
|
+
if (!containerHost) {
|
|
67
|
+
log.warn("host SDK agent skipped: could not determine container-reachable host");
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
log.step("starting host SDK agent (Docker Desktop workaround)...");
|
|
72
|
+
if (!ensureIdeVenv(root)) {
|
|
73
|
+
log.warn("host SDK agent skipped: could not prepare .venv");
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const port = await getFreePort(Number(process.env.MUSCAT_HOST_AGENT_PORT || DEFAULT_HOST_AGENT_PORT));
|
|
78
|
+
const py = venvPython(resolve(root, ".venv"));
|
|
79
|
+
const child = spawn(py, [agentPath], {
|
|
80
|
+
cwd: root,
|
|
81
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
82
|
+
env: {
|
|
83
|
+
...process.env,
|
|
84
|
+
MUSCAT_ROBOT_HOST: robotIp,
|
|
85
|
+
MUSCAT_ROBOT_TOKEN: robotToken,
|
|
86
|
+
MUSCAT_HOST_AGENT_BIND: bindHost,
|
|
87
|
+
MUSCAT_HOST_AGENT_PORT: String(port),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
await waitForHostAgent(port);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
child.kill();
|
|
95
|
+
throw e;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const containerUrl = `http://${containerHost}:${port}`;
|
|
99
|
+
process.env.MUSCAT_HOST_AGENT_URL = containerUrl;
|
|
100
|
+
log.step(`host SDK agent → ${containerUrl}`);
|
|
101
|
+
return child;
|
|
102
|
+
}
|
|
8
103
|
|
|
9
104
|
export async function runDev(args = []) {
|
|
10
105
|
const root = findPluginRoot();
|
|
@@ -17,8 +112,22 @@ export async function runDev(args = []) {
|
|
|
17
112
|
const { robotIp, robotToken } = await promptRobotConnection(args);
|
|
18
113
|
process.env.MUSCAT_ROBOT_HOST = robotIp;
|
|
19
114
|
if (robotToken) process.env.MUSCAT_ROBOT_TOKEN = robotToken;
|
|
115
|
+
|
|
116
|
+
const remoteRobot = isRemoteRobot(robotIp);
|
|
117
|
+
const hostAgent = await maybeStartHostAgent(root, { robotIp, robotToken });
|
|
118
|
+
const hostAgentUrl = process.env.MUSCAT_HOST_AGENT_URL || "";
|
|
119
|
+
// Compute the Zenoh advertise host/port up front — startBridge() needs the
|
|
120
|
+
// port to publish it on the bridge container so the robot can reach back.
|
|
121
|
+
if (hostAgentUrl && !hostAgent) {
|
|
122
|
+
log.step(`host SDK agent → ${hostAgentUrl}`);
|
|
123
|
+
} else if (!hostAgentUrl) {
|
|
124
|
+
await ensureRemoteZenohEnv(robotIp, { log });
|
|
125
|
+
}
|
|
126
|
+
|
|
20
127
|
log.step("starting Socket.IO bridge (Docker) + dev:ui + dev:back");
|
|
21
|
-
const bridgeStarted = await startBridge(
|
|
128
|
+
const bridgeStarted = await startBridge({
|
|
129
|
+
zenohPort: remoteRobot && !hostAgentUrl ? Number(process.env.MUSCAT_ZENOH_PORT) : null,
|
|
130
|
+
});
|
|
22
131
|
|
|
23
132
|
if (!bridgeStarted) {
|
|
24
133
|
log.warn(`port ${BRIDGE_PORT} is already in use — can't start Socket.IO bridge.`);
|
|
@@ -34,6 +143,7 @@ export async function runDev(args = []) {
|
|
|
34
143
|
process.env.MUSCAT_PK_MANAGED_DEV = "1";
|
|
35
144
|
|
|
36
145
|
const cleanup = () => {
|
|
146
|
+
if (hostAgent && hostAgent.exitCode === null) hostAgent.kill();
|
|
37
147
|
stopDevBackContainers();
|
|
38
148
|
if (bridgeStarted) stopBridge();
|
|
39
149
|
};
|
package/cli/src/devBack.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
11
11
|
import { existsSync, watch } from "node:fs";
|
|
12
12
|
import { resolve } from "node:path";
|
|
13
13
|
import { ensureDocker, ensureIdeVenv, findPluginRoot, log, promptRobotConnection } from "./util.mjs";
|
|
14
|
+
import { ensureRemoteZenohEnv } from "./zenohDev.mjs";
|
|
14
15
|
import { assertManifestPorts, manifestRuntime, readManifest, validateManifest } from "./manifest.mjs";
|
|
15
16
|
import {
|
|
16
17
|
formatPortRanges,
|
|
@@ -84,10 +85,14 @@ async function runPython(root, portRanges) {
|
|
|
84
85
|
const container = `${PYTHON_DEV_IMAGE}-run`;
|
|
85
86
|
const robotIp = process.env.MUSCAT_ROBOT_HOST ?? "";
|
|
86
87
|
const robotToken = process.env.MUSCAT_ROBOT_TOKEN ?? "";
|
|
88
|
+
const zenohAdvertiseHost = process.env.MUSCAT_ZENOH_ADVERTISE_HOST ?? "";
|
|
89
|
+
const zenohPort = process.env.MUSCAT_ZENOH_PORT ?? "";
|
|
90
|
+
const hostAgentUrl = process.env.MUSCAT_HOST_AGENT_URL ?? "";
|
|
87
91
|
// Share the bridge container's network namespace so localhost:10000 is the
|
|
88
92
|
// bridge (set by `muscat-pk dev`). Standalone dev:back has no bridge to join.
|
|
89
93
|
const bridgeContainer = process.env.MUSCAT_PK_BRIDGE_CONTAINER;
|
|
90
94
|
const netFlags = bridgeContainer ? ["--network", `container:${bridgeContainer}`] : [];
|
|
95
|
+
const standaloneZenohPortFlags = !bridgeContainer && zenohPort ? ["-p", `${zenohPort}:${zenohPort}`] : [];
|
|
91
96
|
const hostGatewayFlags = bridgeContainer
|
|
92
97
|
? []
|
|
93
98
|
: ["--add-host", "host.docker.internal:host-gateway"];
|
|
@@ -108,6 +113,9 @@ async function runPython(root, portRanges) {
|
|
|
108
113
|
...(pluginId ? ["-e", `RB_PLUGIN_ID=${pluginId}`] : []),
|
|
109
114
|
...(robotIp ? ["-e", `MUSCAT_ROBOT_HOST=${robotIp}`] : []),
|
|
110
115
|
...(robotToken ? ["-e", `MUSCAT_ROBOT_TOKEN=${robotToken}`] : []),
|
|
116
|
+
...(!hostAgentUrl && zenohAdvertiseHost ? ["-e", `MUSCAT_ZENOH_ADVERTISE_HOST=${zenohAdvertiseHost}`] : []),
|
|
117
|
+
...(!hostAgentUrl && zenohPort ? ["-e", `MUSCAT_ZENOH_PORT=${zenohPort}`] : []),
|
|
118
|
+
...(hostAgentUrl ? ["-e", `MUSCAT_HOST_AGENT_URL=${hostAgentUrl}`] : []),
|
|
111
119
|
...portEnvFlags(portRanges),
|
|
112
120
|
];
|
|
113
121
|
const docker = (args, opts = {}) =>
|
|
@@ -117,7 +125,7 @@ async function runPython(root, portRanges) {
|
|
|
117
125
|
docker(["rm", "-f", container], { stdio: "ignore" });
|
|
118
126
|
log.step("starting Python dev container…");
|
|
119
127
|
const up = docker(
|
|
120
|
-
["run", "-d", "--name", container, ...netFlags,
|
|
128
|
+
["run", "-d", "--name", container, ...netFlags, ...standaloneZenohPortFlags,
|
|
121
129
|
// host.docker.internal is automatic on Docker Desktop (macOS/Windows);
|
|
122
130
|
// this makes it resolve on Linux too, for the no-bridge gateway fallback above.
|
|
123
131
|
...hostGatewayFlags,
|
|
@@ -133,12 +141,96 @@ async function runPython(root, portRanges) {
|
|
|
133
141
|
"pip install --break-system-packages --ignore-installed -q watchfiles" +
|
|
134
142
|
" && { [ -f requirements.txt ] && pip install --break-system-packages --ignore-installed -q -r requirements.txt || true; }"]);
|
|
135
143
|
|
|
144
|
+
docker(["exec", container, "bash", "-lc", `cat > /tmp/muscat-pk-python-dev-entry.py <<'PY'
|
|
145
|
+
import json
|
|
146
|
+
import os
|
|
147
|
+
import urllib.request
|
|
148
|
+
|
|
149
|
+
def install_host_agent_sdk_patch(host_agent_url):
|
|
150
|
+
from rainbow.rb_sdk.base import RBBaseSDK
|
|
151
|
+
from rainbow.rb_sdk.manipulate_sdk.manipulate_move import RBManipulateMoveSDK
|
|
152
|
+
|
|
153
|
+
base_url = host_agent_url.rstrip("/")
|
|
154
|
+
|
|
155
|
+
def post_json(path, payload):
|
|
156
|
+
req = urllib.request.Request(
|
|
157
|
+
f"{base_url}{path}",
|
|
158
|
+
data=json.dumps(payload).encode("utf-8"),
|
|
159
|
+
headers={"Content-Type": "application/json"},
|
|
160
|
+
method="POST",
|
|
161
|
+
)
|
|
162
|
+
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
163
|
+
data = json.loads(resp.read().decode("utf-8"))
|
|
164
|
+
if not data.get("ok"):
|
|
165
|
+
raise RuntimeError(data.get("error") or "host SDK agent request failed")
|
|
166
|
+
return data.get("result")
|
|
167
|
+
|
|
168
|
+
async def connect_via_host_agent(self, *args, **kwargs):
|
|
169
|
+
print(f"[muscat-pk] SDK connect routed through host agent: {base_url}", flush=True)
|
|
170
|
+
return "host-agent"
|
|
171
|
+
|
|
172
|
+
async def disconnect_via_host_agent(self, *args, **kwargs):
|
|
173
|
+
return None
|
|
174
|
+
|
|
175
|
+
def call_move_j_via_host_agent(
|
|
176
|
+
self,
|
|
177
|
+
*,
|
|
178
|
+
robot_model,
|
|
179
|
+
target,
|
|
180
|
+
reference_value=None,
|
|
181
|
+
speed=None,
|
|
182
|
+
flow_manager_args=None,
|
|
183
|
+
):
|
|
184
|
+
result = post_json("/move_j", {
|
|
185
|
+
"robot_model": robot_model,
|
|
186
|
+
"values": target.get("tar_values") if isinstance(target, dict) else None,
|
|
187
|
+
"target": target,
|
|
188
|
+
"reference_value": reference_value,
|
|
189
|
+
"speed": speed,
|
|
190
|
+
})
|
|
191
|
+
if flow_manager_args is not None:
|
|
192
|
+
flow_manager_args.done()
|
|
193
|
+
return result
|
|
194
|
+
|
|
195
|
+
RBBaseSDK.connect = connect_via_host_agent
|
|
196
|
+
RBBaseSDK.disconnect = disconnect_via_host_agent
|
|
197
|
+
RBManipulateMoveSDK.call_move_j = call_move_j_via_host_agent
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
advertise_host = os.getenv("MUSCAT_ZENOH_ADVERTISE_HOST")
|
|
201
|
+
zenoh_port = os.getenv("MUSCAT_ZENOH_PORT")
|
|
202
|
+
host_agent_url = os.getenv("MUSCAT_HOST_AGENT_URL")
|
|
203
|
+
|
|
204
|
+
if host_agent_url:
|
|
205
|
+
print(f"[muscat-pk] host SDK agent mode: {host_agent_url}", flush=True)
|
|
206
|
+
install_host_agent_sdk_patch(host_agent_url)
|
|
207
|
+
else:
|
|
208
|
+
from rainbow.rb_sdk.base import RBBaseSDK
|
|
209
|
+
if advertise_host:
|
|
210
|
+
RBBaseSDK._detect_local_ip = staticmethod(lambda host: advertise_host)
|
|
211
|
+
if zenoh_port:
|
|
212
|
+
_orig_connect = RBBaseSDK.connect
|
|
213
|
+
|
|
214
|
+
async def _connect_with_dev_port(self, *args, **kwargs):
|
|
215
|
+
kwargs.setdefault("zenoh_port", int(zenoh_port))
|
|
216
|
+
return await _orig_connect(self, *args, **kwargs)
|
|
217
|
+
|
|
218
|
+
RBBaseSDK.connect = _connect_with_dev_port
|
|
219
|
+
except Exception as exc:
|
|
220
|
+
print(f"[muscat-pk] SDK dev network patch skipped: {exc}", flush=True)
|
|
221
|
+
|
|
222
|
+
import runpy
|
|
223
|
+
runpy.run_path("/plugin/py/main.py", run_name="__main__")
|
|
224
|
+
PY`]);
|
|
225
|
+
|
|
136
226
|
if (pluginId) log.step(`RB_PLUGIN_ID=${pluginId}`);
|
|
227
|
+
if (!hostAgentUrl && zenohAdvertiseHost && zenohPort) log.step(`Zenoh advertise → ${zenohAdvertiseHost}:${zenohPort}`);
|
|
228
|
+
if (hostAgentUrl) log.step(`host SDK agent → ${hostAgentUrl}`);
|
|
137
229
|
log.step("watchfiles → py/main.py (reload on any .py change in py/)");
|
|
138
230
|
const child = spawn(
|
|
139
231
|
"docker",
|
|
140
232
|
["exec", ...envFlags, container, "bash", "-lc",
|
|
141
|
-
"python3 -m watchfiles --filter python --target-type command 'python3
|
|
233
|
+
"python3 -m watchfiles --filter python --target-type command 'python3 /tmp/muscat-pk-python-dev-entry.py' py"],
|
|
142
234
|
{ cwd: root, stdio: ["inherit", "inherit", "pipe"] },
|
|
143
235
|
);
|
|
144
236
|
// watchfiles prints a KeyboardInterrupt traceback on SIGTERM — suppress it
|
|
@@ -351,6 +443,11 @@ export async function runDevBack(args = []) {
|
|
|
351
443
|
const { robotIp, robotToken } = await promptRobotConnection(args);
|
|
352
444
|
if (robotIp) process.env.MUSCAT_ROBOT_HOST = robotIp;
|
|
353
445
|
if (robotToken) process.env.MUSCAT_ROBOT_TOKEN = robotToken;
|
|
446
|
+
// Standalone `dev:back` against a remote robot needs the Zenoh reverse-path
|
|
447
|
+
// advertise host/port too (idempotent — `muscat-pk dev` already set these).
|
|
448
|
+
// Host-agent mode routes robot SDK calls through the mac host, so the Docker
|
|
449
|
+
// backend does not need its own remote Zenoh peer.
|
|
450
|
+
if (!process.env.MUSCAT_HOST_AGENT_URL) await ensureRemoteZenohEnv(robotIp, { log });
|
|
354
451
|
const type = manifestRuntime(root);
|
|
355
452
|
if (type === "ros2") return await runRos2(root, portRanges);
|
|
356
453
|
if (type === "cpp") return await runCpp(root, portRanges);
|
package/cli/src/socketBridge.mjs
CHANGED
|
@@ -53,10 +53,12 @@ export function startSocketBridge({ port = 10000, host = "0.0.0.0" } = {}) {
|
|
|
53
53
|
socket.on("serve_register", (data = {}) => {
|
|
54
54
|
if (!data.topic) return;
|
|
55
55
|
queryables.set(data.topic, socket.id);
|
|
56
|
+
log.step(`serve registered: ${data.topic}`);
|
|
56
57
|
});
|
|
57
58
|
|
|
58
59
|
socket.on("serve_unregister", (data = {}) => {
|
|
59
60
|
if (queryables.get(data.topic) === socket.id) queryables.delete(data.topic);
|
|
61
|
+
if (data.topic) log.step(`serve unregistered: ${data.topic}`);
|
|
60
62
|
});
|
|
61
63
|
|
|
62
64
|
socket.on("serve_reply", (data = {}) => {
|
|
@@ -72,9 +74,11 @@ export function startSocketBridge({ port = 10000, host = "0.0.0.0" } = {}) {
|
|
|
72
74
|
const targetSid = queryables.get(topic);
|
|
73
75
|
const target = targetSid && io.sockets.sockets.get(targetSid);
|
|
74
76
|
if (!target) {
|
|
75
|
-
|
|
77
|
+
log.warn(`action has no handler: ${topic}`);
|
|
78
|
+
if (typeof ack === "function") ack({ error: `No handler registered for ${topic}` });
|
|
76
79
|
return;
|
|
77
80
|
}
|
|
81
|
+
log.step(`action: ${topic}`);
|
|
78
82
|
const id = randomUUID();
|
|
79
83
|
const timer = setTimeout(() => {
|
|
80
84
|
pending.delete(id);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// AUTO-GENERATED by cli/bundle-templates.mjs — do not edit.
|
|
2
2
|
// ponytail: generated at publish time; not tracked in git.
|
|
3
|
-
export const TEMPLATES = {"common/.mcp.json":"ewogICJtY3BTZXJ2ZXJzIjogewogICAgIm11c2NhdCI6IHsKICAgICAgImNvbW1hbmQiOiAibXVzY2F0LXBrIiwKICAgICAgImFyZ3MiOiBbIm1jcCJdCiAgICB9CiAgfQp9Cg==","common/README.md":"IyBfX1BMVUdJTl9OQU1FX18KCkEgTXVzY2F0IHBsdWdpbiBwcm9qZWN0LiBCdWlsZCwgZGV2ZWxvcCwgYW5kIHNoaXAgd2l0aCBgbXVzY2F0LXBrYCBDTEkuCgojIyBRdWljayBzdGFydAoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJIHByZXZpZXcgKyBiYWNrZW5kIHRvZ2V0aGVyCm11c2NhdC1wayBkZXY6dWkgICAgICMgVUkgcHJldmlldyBvbmx5Cm11c2NhdC1wayBkZXY6YmFjayAgICMgYmFja2VuZCBvbmx5IChQeXRob24gd2F0Y2hmaWxlcyAvIFJPUzIgRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkICsgZGlzdHJpYnV0YWJsZSBaSVAKYGBgCgotLS0KCiMjIFByb2plY3Qgc3RydWN0dXJlCgpgYGAKX19QTFVHSU5fRElSX18vCuKUnOKUgCB1aS8K4pSCICAg4pSc4pSAIGNvbnRlbnQudHN4ICAgICAgIyBwbHVnaW4gVUkgZW50cnkgcG9pbnQK4pSCICAg4pSU4pSAIHN0eWxlLmNzcyAgICAgICAgIyBwbHVnaW4gc3R5bGVzIGF1dG8tbG9hZGVkIGJ5IG11c2NhdCgpCuKUnOKUgCBweS8K4pSCICAg4pSU4pSAIG1haW4ucHkgICAgICAgICAgIyBQeXRob24gYmFja2VuZCBlbnRyeSBwb2ludArilJzilIAgYXNzZXRzLwrilIIgICDilJTilIAgaWNvbi5zdmcgICAgICAgICAjIGljb24gcmVmZXJlbmNlZCBmcm9tIG1hbmlmZXN0CuKUnOKUgCBtYW5pZmVzdC5qc29uICAgICAgICAjIG1ldGFkYXRhLCBjb250cmlidXRpb24gcG9pbnRzLCBydW50aW1lIGNvbmZpZwrilJzilIAgUkVBRE1FLm1kICAgICAgICAgICAgIyB0aGlzIGZpbGUgKGNvcGllZCB0byBkaXN0LyBvbiBidWlsZCkK4pSU4pSAIHJlcXVpcmVtZW50cy50eHQgICAgICMgUHl0aG9uIGRlcHMgKGF1dG8tcGlubmVkIHRvIGxhdGVzdCBvbiBidWlsZCkKYGBgCgo+IFJPUzIgcGx1Z2lucyBhZGRpdGlvbmFsbHkgaW5jbHVkZSBhIGByb3MyX3dzL2AgZGlyZWN0b3J5LgoKLS0tCgojIyBGcm9udGVuZCAoYHVpL2NvbnRlbnQudHN4YCkKCiMjIyBKYXZhU2NyaXB0IGRlcGVuZGVuY2llcwoKYG11c2NhdC1wayBidWlsZGAgcnVucyB0aGlzIHBsdWdpbiBwcm9qZWN0J3Mgb3duIFZpdGUgYnVpbGQuIFZpdGUgcmVzb2x2ZXMKaW1wb3J0cyBmcm9tIGluc3RhbGxlZCBgbm9kZV9tb2R1bGVzYDsgaXQgZG9lcyBub3QgY2FyZSB3aGV0aGVyIGEgcGFja2FnZSBpcwpsaXN0ZWQgdW5kZXIgYGRlcGVuZGVuY2llc2Agb3IgYGRldkRlcGVuZGVuY2llc2AsIGJ1dCB0aGUgcGFja2FnZSBtdXN0IGJlCmluc3RhbGxlZC4KCkRvIG5vdCBydW4gYSBwcm9kdWN0aW9uLW9ubHkgaW5zdGFsbCBzdWNoIGFzIGBucG0gaW5zdGFsbCAtLW9taXQ9ZGV2YCBiZWZvcmUKYnVpbGRpbmcgdGhlIHBsdWdpbiBVSSwgYmVjYXVzZSBidWlsZCB0b29scyBsaWtlIGB2aXRlYCwgYHR5cGVzY3JpcHRgLApgdGFpbHdpbmRjc3NgLCBgQHRhaWx3aW5kY3NzL3ZpdGVgLCBgc2Fzc2AsIG9yIGBsZXNzYCBhcmUgdXN1YWxseQpgZGV2RGVwZW5kZW5jaWVzYC4KClRoZSBzY2FmZm9sZCBrZWVwcyB0aGlzIHNwbGl0OgoKfCBwYWNrYWdlIGtpbmQgfCBleGFtcGxlcyB8IHdoeSB8CnwtLS18LS0tfC0tLXwKfCBgZGVwZW5kZW5jaWVzYCB8IGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWlgLCBVSSBsaWJyYXJpZXMgaW1wb3J0ZWQgYnkgcGx1Z2luIHNvdXJjZSB8IEF1dGhvci1mYWNpbmcgQVBJcyB1c2VkIGJ5IGB1aS8qLnRzeGAgfAp8IGBkZXZEZXBlbmRlbmNpZXNgIHwgYHZpdGVgLCBgdHlwZXNjcmlwdGAsIGB0YWlsd2luZGNzc2AsIGBAdGFpbHdpbmRjc3Mvdml0ZWAsIGBzYXNzYCwgYGxlc3NgIHwgQnVpbGQvZGV2IHRvb2xzIG5lZWRlZCBiZWZvcmUgYGRpc3QvKi5qc2AgaXMgcHJvZHVjZWQgfAoKVGhlIGJ1aWx0IHBsdWdpbiBaSVAgZG9lcyBub3QgaW5jbHVkZSBgcGFja2FnZS5qc29uYCBvciBgbm9kZV9tb2R1bGVzYC4gRm9yCnByb2R1Y3Rpb24sIE11c2NhdCBwcm92aWRlcyBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpYCwgUmVhY3QsIGFuZCBSZWFjdERPTQp0aHJvdWdoIHRoZSBob3N0IGltcG9ydCBtYXA7IHBsdWdpbiBVSSBidWlsZCBvdXRwdXQgaW1wb3J0cyB0aG9zZSBhcyBob3N0CmV4dGVybmFscy4KCiMjIyBTdHlsZXMKCmBtdXNjYXQoKWAgYXV0b21hdGljYWxseSBsb2FkcyBgdWkvc3R5bGUue2NzcyxzY3NzLHNhc3MsbGVzc31gIChvcgpgdWkvc3R5bGVzLntjc3Msc2NzcyxzYXNzLGxlc3N9YCkgZm9yIGV2ZXJ5IFVJIGVudHJ5LCBwbHVzCmB1aS97ZW50cnl9Lntjc3Msc2NzcyxzYXNzLGxlc3N9YCBmb3IgYSBtYXRjaGluZyBlbnRyeS1zcGVjaWZpYyBzdHlsZXNoZWV0LiBZb3UKZG8gbm90IG5lZWQgdG8gaW1wb3J0IENTUyBmcm9tIGV2ZXJ5IGAudHN4YCBmaWxlLgoKVGhlIHNjYWZmb2xkIHVzZXMgVGFpbHdpbmQncyB0aGVtZS91dGlsaXRpZXMgbGF5ZXJzIG9ubHksIHNvIHBsdWdpbiB1dGlsaXRpZXMKYXJlIGdlbmVyYXRlZCBmcm9tIGZpbGVzIHVuZGVyIGB1aS9gIHdpdGhvdXQgYXBwbHlpbmcgVGFpbHdpbmQgcHJlZmxpZ2h0IHJlc2V0cwp0byB0aGUgaG9zdCBwYWdlLgoKQnVpbHQgQ1NTIHNlbGVjdG9ycyBhcmUgc2NvcGVkIHVuZGVyIHRoZSBjdXJyZW50IHBsdWdpbiBpZAooYFtkYXRhLW11c2NhdC1wbHVnaW4taWQ9Ii4uLiJdYCkuIENTUy1pbi1KUyBsaWJyYXJpZXMgc3VjaCBhcyBFbW90aW9uIHdvcmsKbm9ybWFsbHksIGJ1dCBnbG9iYWwgc3R5bGVzIHNob3VsZCBiZSBzY29wZWQgYnkgdGhlIGF1dGhvci4KCiMjIyMgVGFpbHdpbmQKClRoaXMgdGVtcGxhdGUgZW5hYmxlcyBUYWlsd2luZCBpbiBgdml0ZS5jb25maWcudHNgOgoKYGBgdHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsKYGBgCgpUaGUgZGVmYXVsdCBgdWkvc3R5bGUuY3NzYCB1c2VzIFRhaWx3aW5kIHRoZW1lL3V0aWxpdGllcyBvbmx5LCBub3QgcHJlZmxpZ2h0OgoKYGBgY3NzCkBsYXllciB0aGVtZSwgdXRpbGl0aWVzOwoKQGltcG9ydCAidGFpbHdpbmRjc3MvdGhlbWUuY3NzIiBsYXllcih0aGVtZSk7CkBpbXBvcnQgInRhaWx3aW5kY3NzL3V0aWxpdGllcy5jc3MiIGxheWVyKHV0aWxpdGllcyk7CgpAc291cmNlICIuLyoqLyoue3RzLHRzeH0iOwpgYGAKCiMjIyMgU0NTUywgU2FzcywgYW5kIExlc3MKCkluc3RhbGwgdGhlIHByZXByb2Nlc3NvciBwYWNrYWdlLCB0aGVuIGNyZWF0ZSBvbmUgb2YgdGhlIGF1dG8tbG9hZGVkIHN0eWxlIGZpbGVzLgoKYGBgYmFzaApucG0gaSAtRCBzYXNzCmBgYAoKYGBgc2NzcwovKiB1aS9zdHlsZS5zY3NzICovCiRhY2NlbnQ6ICMzYjgyZjY7CgoucGFuZWwgewogIGJvcmRlcjogMXB4IHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCAkYWNjZW50IDQwJSwgdHJhbnNwYXJlbnQpOwoKICAmX190aXRsZSB7CiAgICBjb2xvcjogJGFjY2VudDsKICB9Cn0KYGBgCgpGb3IgTGVzcywgaW5zdGFsbCBgbGVzc2AgYW5kIHVzZSBgdWkvc3R5bGUubGVzc2AuCgojIyMjIEVtb3Rpb24KCkVtb3Rpb24gZGVwZW5kZW5jaWVzIG1heSBiZSBpbiBgZGVwZW5kZW5jaWVzYCBvciBgZGV2RGVwZW5kZW5jaWVzYDsgVml0ZSBjYW4KYnVuZGxlIHRoZW0gd2hlbiB0aGV5IGFyZSBpbnN0YWxsZWQgYW5kIGltcG9ydGVkIGJ5IHRoZSBwbHVnaW4uCgpGb3IgYHN0eWxlZGAsIG5vIFZpdGUgY29uZmlnIGNoYW5nZSBpcyBuZWVkZWQ6CgpgYGBiYXNoCm5wbSBpIEBlbW90aW9uL3JlYWN0IEBlbW90aW9uL3N0eWxlZApgYGAKCmBgYHRzeAppbXBvcnQgc3R5bGVkIGZyb20gIkBlbW90aW9uL3N0eWxlZCI7Cgpjb25zdCBQYW5lbCA9IHN0eWxlZC5kaXYoewogIGRpc3BsYXk6ICJncmlkIiwKICBnYXA6IDEyLAp9KTsKYGBgCgpGb3IgRW1vdGlvbidzIGBjc3NgIHByb3AsIHBhc3MgUmVhY3QgcGx1Z2luIG9wdGlvbnMgdGhyb3VnaCBgbXVzY2F0KClgIGFuZCBhZGQKYGpzeEltcG9ydFNvdXJjZWAgdG8gYHRzY29uZmlnLmpzb25gOgoKYGBgYmFzaApucG0gaSBAZW1vdGlvbi9yZWFjdCBAZW1vdGlvbi9zdHlsZWQKbnBtIGkgLUQgQGVtb3Rpb24vYmFiZWwtcGx1Z2luCmBgYAoKYGBgdHMKLy8gdml0ZS5jb25maWcudHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbCiAgICB0YWlsd2luZGNzcygpLAogICAgbXVzY2F0KHsKICAgICAgcmVhY3Q6IHsKICAgICAgICBqc3hJbXBvcnRTb3VyY2U6ICJAZW1vdGlvbi9yZWFjdCIsCiAgICAgICAgYmFiZWw6IHsKICAgICAgICAgIHBsdWdpbnM6IFsiQGVtb3Rpb24vYmFiZWwtcGx1Z2luIl0sCiAgICAgICAgfSwKICAgICAgfSwKICAgIH0pLAogIF0sCn0pOwpgYGAKCmBgYGpzb24KewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAianN4SW1wb3J0U291cmNlIjogIkBlbW90aW9uL3JlYWN0IgogIH0KfQpgYGAKCkVtb3Rpb24gYEdsb2JhbGAgd3JpdGVzIGdsb2JhbCBDU1MgYXQgcnVudGltZSwgc28gc2NvcGUgaXQgbWFudWFsbHkgb3IgYXZvaWQgaXQKaW5zaWRlIHBsdWdpbnMuCgojIyMgdXNlUmIoKSBob29rCgpBY2Nlc3MgdGhlIGNvbW11bmljYXRpb24gQVBJIGJldHdlZW4gdGhlIHBsdWdpbiBtb2R1bGUgYW5kIFVJIGZyb20gYW55IHBsdWdpbiBjb21wb25lbnQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlUmIgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvc2RrIjsKCmZ1bmN0aW9uIEFwcCgpIHsKICBjb25zdCByYiA9IHVzZVJiKCk7Cn0KYGBgCgojIyMgcmIgQVBJCgp8IE1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfAp8IGByYi5wdWIodG9waWMsIHBheWxvYWQpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFB1Ymxpc2ggYSBtZXNzYWdlIHRvIGEgdG9waWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IGByYi5zdWIodG9waWMsIGhhbmRsZXIpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFN1YnNjcmliZSB0byBhIHRvcGljIOKAlCByZXR1cm5zIGB7IHVuZGVjbGFyZSgpIH1gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmFjdGlvbih0b3BpYywgcGF5bG9hZD8pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2VuZCBhIHJlcXVlc3QgYW5kIGF3YWl0IGEgcmVwbHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnNlcnZlKHRvcGljLCBoYW5kbGVyKWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSGFuZGxlIGluY29taW5nIHJlcXVlc3RzIGZyb20gdGhlIGJhY2tlbmQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnRvYXN0KHsgdGl0bGU/LCBtZXNzYWdlLCB0eXBlPywgYWN0aW9uTGFiZWw/LCBoYW5kbGVBY3Rpb25DbGljaz8sIGNsb3NlT25BY3Rpb25DbGljaz8sIGR1cmF0aW9uPywgb25DbG9zZT8gfSlgIHwgU2hvdyBhIGhvc3QgdG9hc3Qgbm90aWZpY2F0aW9uLiBgbWVzc2FnZWAgYWNjZXB0cyBhIHN0cmluZyBvciBgUmVhY3RFbGVtZW50YC4gYHR5cGVgIGNhbiBiZSBgImluZm8iYCwgYCJkYW5nZXIiYCwgYCJ3YXJuaW5nImAsIGAiY2F1dGlvbiJgLCBvciBgInN1Y2Nlc3MiYCB8CnwgYHJiLmFsZXJ0KHsgdGl0bGU/LCBtZXNzYWdlLCBidXR0b25UZXh0PyB9KWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgYWxlcnQgZGlhbG9nLiBSZXNvbHZlcyB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmNvbmZpcm0oeyB0aXRsZT8sIG1lc3NhZ2UsIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgY29uZmlybWF0aW9uIGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gYHRydWVgIG9yIGBmYWxzZWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnByb21wdCh7IHRpdGxlPywgbWVzc2FnZSwgdmFsdWU/LCBwbGFjZWhvbGRlcj8sIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgcHJvbXB0IGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gdGhlIGVudGVyZWQgc3RyaW5nIG9yIGB1bmRlZmluZWRgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgpUb3BpYyBuYW1lcyBwYXNzZWQgdG8gYHB1YmAsIGBzdWJgLCBgYWN0aW9uYCwgYW5kIGBzZXJ2ZWAgYXJlIGlzb2xhdGVkIHBlciBwbHVnaW4uCgoKQWxsIG1ldGhvZHMgc3VwcG9ydCBHZW5lcmljIFR5cGVzOgoKYGBgdHN4CmNvbnN0IHN0YXR1cyA9IGF3YWl0IHJiLmFjdGlvbjx7IG9rOiBib29sZWFuIH0sIHsgaWQ6IG51bWJlciB9PigKICAiZ2V0LXN0YXR1cyIsCiAgeyBpZDogMSB9LAopOwoKY29uc3Qgc3ViID0gYXdhaXQgcmIuc3ViPHsgdmFsdWU6IG51bWJlciB9Pigic2Vuc29yL2RhdGEiLCAoZGF0YSkgPT4gewogIGNvbnNvbGUubG9nKGRhdGEudmFsdWUpOwp9KTsKc3ViLnVuZGVjbGFyZSgpOyAvLyBjbGVhbnVwCgpjb25zdCBvayA9IGF3YWl0IHJiLmNvbmZpcm0oewogIHRpdGxlOiAiUnVuIiwKICBtZXNzYWdlOiAiU3RhcnQgdGhlIGJhY2tlbmQgYWN0aW9uPyIsCn0pOwppZiAob2spIHsKICBhd2FpdCByYi5hY3Rpb24oInJ1biIpOwp9CmBgYAoKIyMjIFNhdmluZyBhbmQgcmVzdG9yaW5nIGZvcm0gZGF0YSAoYHVzZVJiRm9ybURhdGFgIC8gYHVzZVJiU2F2ZWApCgpJZiB0aGUgaG9zdCBlbWJlZHMgeW91ciBwbHVnaW4gaW4gYSBmb3JtIGl0IG93bnMgKGUuZy4gYSBwcm9ncmFtIHN0ZXAgZWRpdG9yCndpdGggaXRzIG93biBTYXZlIGJ1dHRvbiksIGl0IGNhbiBoYW5kIHlvdXIgcGx1Z2luIHByZXZpb3VzbHktc2F2ZWQgdmFsdWVzIGFuZApwdWxsIHRoZSBjdXJyZW50IHZhbHVlcyBiYWNrIG91dCB3aGVuIHRoZSB1c2VyIHNhdmVzLiBUaGUgaG9zdCDigJQgbm90IHRoZQpwbHVnaW4g4oCUIHBlcnNpc3RzIHRoZSBkYXRhIChJbmRleGVkREIsIGJhY2tlbmQsIGV0Yy4pLgoKYGBgdHN4CmltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSAicmVhY3QiOwppbXBvcnQgeyB1c2VSYkZvcm1EYXRhLCB1c2VSYlNhdmUgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwoKdHlwZSBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogc3RyaW5nOyB3aWR0aDogbnVtYmVyIH07CmNvbnN0IERFRkFVTFRTOiBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogIiIsIHdpZHRoOiAyMCB9OwoKZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwKCkgewogIC8vIFByZXZpb3VzbHktc2F2ZWQgdmFsdWVzLCBvciB1bmRlZmluZWQgZm9yIGEgYnJhbmQtbmV3IGluc3RhbmNlLgogIGNvbnN0IHNhdmVkID0gdXNlUmJGb3JtRGF0YTxHcmlwQXJncz4oKTsKICBjb25zdCBbYXJncywgc2V0QXJnc10gPSB1c2VTdGF0ZTxHcmlwQXJncz4oeyAuLi5ERUZBVUxUUywgLi4uc2F2ZWQgfSk7CgogIC8vIFJlZ2lzdGVycyBhIGdldHRlciB0aGUgaG9zdCBjYWxscyB3aGVuIGl0cyBTYXZlIGJ1dHRvbiBpcyBjbGlja2VkLgogIC8vIEFsd2F5cyByZXR1cm5zIHRoZSBDVVJSRU5UIHZhbHVlcyDigJQgcmUtcmVnaXN0ZXJpbmcgb24gZXZlcnkgcmVuZGVyIGtlZXBzCiAgLy8gdGhlIGNsb3N1cmUgZnJlc2gsIHdoaWNoIHVzZVJiU2F2ZSBhbHJlYWR5IGhhbmRsZXMgZm9yIHlvdS4KICB1c2VSYlNhdmUoKCkgPT4gKHsKICAgIGFyZ3MsCiAgICBzdW1tYXJ5OiBgJHthcmdzLnRhcmdldE5hbWUgfHwgInRhcmdldCJ9IMK3ICR7YXJncy53aWR0aH1tbWAsCiAgfSkpOwoKICByZXR1cm4gKC8qIC4uLmZvcm0gVUkgcmVhZGluZy93cml0aW5nIGBhcmdzYC4uLiAqLyk7Cn0KYGBgCgpUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBgdXNlUmJTYXZlYCBtdXN0IGJlIEpTT04tc2VyaWFsaXNhYmxlIOKAlCB0aGUgaG9zdApwZXJzaXN0cyBpdCBhcy1pcy4gTm90IGV2ZXJ5IGhvc3QgZW1iZWRzIHBsdWdpbnMgaW4gYSBzYXZlL3Jlc3RvcmUgZm9ybTsgaWYKeW91cnMgZG9lc24ndCwgeW91IGNhbiBza2lwIHRoZXNlIGhvb2tzIGVudGlyZWx5LgoKIyMjIFVJIGNvbXBvbmVudHMKCkltcG9ydCBNdXNjYXQgY29tcG9uZW50cyBmcm9tIGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3RgIGFuZCBleHBvcnQgYQpSZWFjdCBjb21wb25lbnQgYXMgdGhlIGRlZmF1bHQgZXhwb3J0LiBUaGUgaG9zdCBtb3VudHMgdGhhdCBjb21wb25lbnQgZGlyZWN0bHkKYW5kIHByb3ZpZGVzIGB1c2VSYigpYCB0aHJvdWdoIGNvbnRleHQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7IFJCTGFiZWxCdXR0b24sIFJCU2xpZGVyLCBSQlN3aXRjaCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9yZWFjdCI7CmltcG9ydCB7IHVzZVJiIH0gZnJvbSAiQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3NkayI7CgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt3aWR0aCwgc2V0V2lkdGhdID0gdXNlU3RhdGUoMjApOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwoKICByZXR1cm4gKAogICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICA8UkJTbGlkZXIKICAgICAgICB2YWx1ZT17W3dpZHRoXX0KICAgICAgICBtaW49ezB9CiAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgb25WYWx1ZUNoYW5nZT17KHZhbHVlczogbnVtYmVyW10pID0+IHNldFdpZHRoKHZhbHVlc1swXSA/PyAwKX0KICAgICAgLz4KICAgICAgPFJCU3dpdGNoIGNoZWNrZWQ9e2VuYWJsZWR9IG9uQ2hlY2tlZENoYW5nZT17c2V0RW5hYmxlZH0gLz4KICAgICAgPFJCTGFiZWxCdXR0b24KICAgICAgICBkaXNhYmxlZD17IWVuYWJsZWR9CiAgICAgICAgb25DbGljaz17KCkgPT4gcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KX0KICAgICAgPgogICAgICAgIEdyaXAKICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgPC9kaXY+CiAgKTsKfQpgYGAKCi0tLQoKIyMgRGV2ZWxvcGluZyBkaXJlY3RseSBvbiB0aGUgcm9ib3QgUEMKCklmIHlvdSdyZSBydW5uaW5nIGBtdXNjYXQtcGsgZGV2YCAqKm9uIHRoZSByb2JvdCBQQyBpdHNlbGYqKiwgTXVzY2F0IGlzIGxpa2VseSBhbHJlYWR5CnJ1bm5pbmcgaXRzIG93biBTb2NrZXQuSU8gYnJpZGdlIG9uIHBvcnQgMTAwMDAuIEluIHRoYXQgY2FzZSB0aGUgQ0xJIGRldGVjdHMgdGhlIHBvcnQKY29uZmxpY3QgYW5kIGFza3M6CgpgYGAK4pqgIHBvcnQgMTAwMDAgaXMgYWxyZWFkeSBpbiB1c2Ug4oCUIGNhbid0IHN0YXJ0IFNvY2tldC5JTyBicmlkZ2UuCiAgUHJvY2VlZCB3aXRob3V0IFNvY2tldC5JTyBicmlkZ2U/IFt5L05dOgpgYGAKCkFuc3dlciAqKnkqKi4gWW91ciBwbHVnaW4gYmFja2VuZCB3aWxsIGNvbm5lY3QgdG8gdGhlIE11c2NhdCBicmlkZ2UgdGhhdCdzIGFscmVhZHkKcnVubmluZyBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGEgbmV3IG9uZSDigJQgZXhhY3RseSB3aGF0IHlvdSB3YW50IHdoZW4gZGV2ZWxvcGluZyBvbiB0aGUKcm9ib3QuCgo+IElmIHlvdSBhbnN3ZXIgKipuKiogKG9yIGp1c3QgcHJlc3MgRW50ZXIpLCB0aGUgQ0xJIGV4aXRzIHNvIHlvdSBjYW4gZnJlZSB0aGUgcG9ydAo+IG1hbnVhbGx5IGFuZCByZXRyeS4KCi0tLQoKIyMgQmFja2VuZCBydW50aW1lcwoKYG1hbmlmZXN0Lmpzb25gIGNob29zZXMgb25lIGJhY2tlbmQgcnVudGltZS4gYG11c2NhdC1wayBkZXZgIHJ1bnMgYmFja2VuZCBjb2RlIGluCmEgRG9ja2VyIGNvbnRhaW5lciBtYXRjaGluZyB0aGUgcm9ib3QgZW52aXJvbm1lbnQuIEJhY2tlbmQgY29kZSBzaG91bGQgY29udGFpbgpwbHVnaW4gbG9naWMgb25seTsgaXQgc2hvdWxkIG5vdCBzdGFydCB0aGUgTXVzY2F0IGJyaWRnZSBvciBpdHMgb3duIGNvcHkgb2YgdGhlCnBsdWdpbiBnYXRld2F5LgoKIyMjIFdoaWNoIGJhY2tlbmQgcGF0dGVybj8gKGRlcGVuZHMgb24gdGhlIGNvbnRyaWJ1dGlvbiBwb2ludCkKCioqSG93IHlvdSBjb250cm9sIHRoZSByb2JvdCBkZXBlbmRzIG9uIHdoYXQgeW91ciBwbHVnaW4gY29udHJpYnV0ZXMqKiAoc2VlCmBtYW5pZmVzdC5qc29uYCDihpIgYGNvbnRyaWJ1dGVzW10ucG9pbnRgKS4gRG9uJ3QgbWl4IHRoZXNlIHVwOgoKfCBDb250cmlidXRpb24gcG9pbnQgfCBXaGF0IGl0IGlzIHwgQmFja2VuZCBwYXR0ZXJuIHwKfCAtLS0gfCAtLS0gfCAtLS0gfAp8IGBwcm9ncmFtLnBhbmVsYCAod2l0aCBgY29tbWFuZEluZm9gKSB8IERlZmluZXMgYSAqKmN1c3RvbSBjb21tYW5kKiogdGhlIHBsdWdpbiBhZGRzIHRvIHRoZSBQcm9ncmFtIHBhZ2UncyBydWxlLWJhc2VkIHNlcXVlbmNlIGJ1aWxkZXIuIFRoZSBvcGVyYXRvciBwbGFjZXMgaXQgaW50byB0aGUgcHJvZ3JhbSB0cmVlIGxpa2UgYW55IGJ1aWx0LWluIGNvbW1hbmQgKE1vdmUgSiwgUG9pbnQsIFdhaXQsIOKApik7IGl0IHJ1bnMgd2hlbiB0aGUgcHJvZ3JhbSByZWFjaGVzIHRoYXQgc3RlcC4gfCAqKmBQbHVnaW5Qcm9ncmFtQ29udGV4dGAqKiDigJQgaW50ZWdyYXRlZCB3aXRoIHRoZSBwcm9ncmFtJ3Mgc3RvcC9wYXVzZSBhbmQgdmFyaWFibGVzLiBTZWUgX1Byb2dyYW0gY29tbWFuZCBiYWNrZW5kXyBiZWxvdy4gfAp8IGB0b29sYmFyYCAvIGBsbmJgIC8gYG1vdmUucGFuZWxgIHwgQSBsaXZlIFVJIHBhbmVsL3BvcG92ZXIgdGhlIG9wZXJhdG9yIGludGVyYWN0cyB3aXRoIGRpcmVjdGx5IHwgQ2FsbCB0aGUgcm9ib3QgKipTREsgZGlyZWN0bHkqKiAoYFJCTWFuaXB1bGF0ZVNES2AsIGBSQkFtclNES2ApIGZyb20gYHB5L21haW4ucHlgLCBvciBgcmIuYWN0aW9uKC4uLilgIOKGkiB5b3VyIGJhY2tlbmQg4oaSIFNESy4gKipOb3QqKiBhIHByb2dyYW0gc3RlcCDigJQgdGhlcmUgaXMgbm8gc3RvcC9wYXVzZS92YXJpYWJsZSBjb250ZXh0LiB8CgpSdWxlIG9mIHRodW1iOiB1c2UgYFBsdWdpblByb2dyYW1Db250ZXh0YCAqKm9ubHkqKiBmb3IgYSBgcHJvZ3JhbS5wYW5lbGAgY29tbWFuZAp0aGF0IHJ1bnMgYXMgcGFydCBvZiBhIHByb2dyYW0uIFRvIG1vdmUgdGhlIHJvYm90IGxpdmUgZnJvbSBhIHRvb2xiYXIvbW92ZSBwYW5lbCwKdXNlIHRoZSBTREsg4oCUIGEgcHJvZ3JhbS1zdGVwIGNvbnRleHQgZG9lcyBub3QgYXBwbHkuCgojIyMgRnJvbnRlbmQtb25seSAoYG5vbmVgKQoKVXNlIHRoaXMgd2hlbiB0aGUgcGx1Z2luIG9ubHkgaGFzIFVJIGFuZCBjYWxscyBob3N0IHNlcnZpY2VzOgoKYGBganNvbgp7ICJydW50aW1lIjogeyAidHlwZSI6ICJub25lIiB9IH0KYGBgCgojIyMgUHl0aG9uCgpQeXRob24gcGx1Z2lucyB1c2UgYHB5L21haW4ucHlgIGFuZCBjYW4gY29tbXVuaWNhdGUgd2l0aCB0aGUgVUkgdGhyb3VnaApgcmFpbmJvdy5yYl9zZGsuUkJQbHVnaW5DYWxsYC4KCmBgYHB5dGhvbgppbXBvcnQgdGltZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQkFtclNESywgUkJNYW5pcHVsYXRlU0RLLCBSQlBsdWdpbkNhbGwKCnBsdWdpbiA9IFJCUGx1Z2luQ2FsbCgpCgoKcGx1Z2luLnB1Ymxpc2goInN0YXRlIiwgeyJyZWFkeSI6IFRydWV9KQoKCkBwbHVnaW4uc3Vic2NyaWJlKCJldmVudCIpCmRlZiBvbl91aV9ldmVudChwYXlsb2FkPU5vbmUpOgogICAgcHJpbnQocGF5bG9hZCkKCgpAcGx1Z2luLnNlcnZlKCJ0b29sL2VjaG8iKQpkZWYgZWNobyhwYXlsb2FkPU5vbmUpOgogICAgcmV0dXJuIHsiZWNobyI6IHBheWxvYWR9CgoKZGVmIGNhbGxfZnJvbnRlbmQoKToKICAgIHJlcyA9IHBsdWdpbi5jYWxsKCJ0b29sL3BpbmciLCBwYXlsb2FkPXsiaGVsbG8iOiAicGx1Z2luIn0pCiAgICBwcmludChyZXMpCgoKZGVmIG1vdmVfal9leGFtcGxlKCk6CiAgICBhbXIgPSBSQkFtclNESygpCiAgICBtYW5pcHVsYXRlID0gUkJNYW5pcHVsYXRlU0RLKCkKICAgIHJldHVybiBtYW5pcHVsYXRlLm1vdmUuY2FsbF9tb3ZlX2ooCiAgICAgICAgcm9ib3RfbW9kZWw9IkM1MDA5MjAiLAogICAgICAgIHRhcmdldD17InRhcl92YWx1ZXMiOiBbMCwgMCwgMCwgMCwgMCwgMF0sICJ0YXJfZnJhbWUiOiAwLCAidGFyX3VuaXQiOiAwfSwKICAgICkKCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgd2hpbGUgVHJ1ZToKICAgICAgICB0aW1lLnNsZWVwKDEpCmBgYAoKIyMjIyBQcm9ncmFtIGNvbW1hbmQgYmFja2VuZCAoYHByb2dyYW0ucGFuZWxgKQoKQSBgcHJvZ3JhbS5wYW5lbGAgY29udHJpYnV0aW9uIGRlZmluZXMgYSAqKmN1c3RvbSBjb21tYW5kKiogeW91ciBwbHVnaW4gYWRkcyB0bwp0aGUgTXVzY2F0ICoqUHJvZ3JhbSBwYWdlKiosIHdoZXJlIHRoZSBvcGVyYXRvciBidWlsZHMgYSByb2JvdCBwcm9ncmFtIGFzIGEKcnVsZS1iYXNlZCBzZXF1ZW5jZSAoYSBwcm9ncmFtIHRyZWUpLiBZb3VyIGNvbW1hbmQgYXBwZWFycyBhbG9uZ3NpZGUgdGhlCmJ1aWx0LWlucyAoTW92ZSBKLCBQb2ludCwgV2FpdCwg4oCmKTsgdGhlIG9wZXJhdG9yIHBsYWNlcyBpdCBpbnRvIHRoZSB0cmVlLCBhbmQKZWFjaCB0aW1lIHRoZSBwcm9ncmFtIGV4ZWN1dGVzIHRoYXQgc3RlcCB0aGUgaG9zdCBjYWxscyB5b3VyIGJhY2tlbmQgdGhyb3VnaApgUGx1Z2luUHJvZ3JhbUNvbnRleHRgIOKAlCByZWNlaXZpbmcgdGhlIHN0ZXAgYXJncywgY2hlY2tpbmcgZm9yIHN0b3AvcGF1c2UsCnJlYWRpbmcvd3JpdGluZyBwcm9ncmFtIHZhcmlhYmxlcywgYW5kIHNpZ25hbGxpbmcgY29tcGxldGlvbi4gVGhpcyBwYXR0ZXJuIGlzCioqb25seSoqIGZvciBgcHJvZ3JhbS5wYW5lbGA7IGEgdG9vbGJhci9tb3ZlLXBhbmVsIHBsdWdpbiB1c2VzIHRoZSBTREsgZGlyZWN0bHkKaW5zdGVhZCAoc2VlIHRoZSB0YWJsZSBhYm92ZSkuCgpgYGBweXRob24KIiIiClBsdWdpbiBiYWNrZW5kIG1haW4ucHkgZXhhbXBsZSAocHJvZ3JhbS5wYW5lbCBjb21tYW5kKS4KCm1hbmlmZXN0Lmpzb246CiAgInJ1bnRpbWUiOiB7InR5cGUiOiAicHl0aG9uIiwgImVudHJ5IjogIm1haW4ucHkifSwKICAiY29udHJpYnV0ZXMiOiBbewogICAgInBvaW50IjogInByb2dyYW0ucGFuZWwiLAogICAgInVpIjogInByb2dyYW0iLAogICAgImxhYmVsIjogeyJlbiI6ICJNeSBQbHVnaW4gU3RlcCJ9LAogICAgImNvbW1hbmRJbmZvIjogewogICAgICAibmFtZSI6ICJNeSBQbHVnaW4gU3RlcCIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJmdW5jTmFtZSI6ICJyYl9wcm9ncmFtX3Nkay5wbHVnaW5fZXhlY3V0ZSIsCiAgICAgICJhcmdzIjogeyJtZXNzYWdlIjogImhlbGxvIn0gICAjIHBsdWdpbi1hdXRob3ItZGVmaW5lZCBhcmdzCiAgICB9CiAgfV0KClRoZSBob3N0IGludm9rZXMgY29tbWFuZEluZm8uZnVuY05hbWUgKHJiX3Byb2dyYW1fc2RrLnBsdWdpbl9leGVjdXRlKSB3aXRoCmFyZ3MucGx1Z2luX2lkICsgeW91ciBhcmdzIHdoZW4gdGhlIHByb2dyYW0gcmVhY2hlcyB0aGlzIHN0ZXAuCiIiIgppbXBvcnQgYXN5bmNpbwpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBQbHVnaW5Qcm9ncmFtQ29udGV4dAoKY3R4ID0gUGx1Z2luUHJvZ3JhbUNvbnRleHQocGx1Z2luX2lkPSJteS1wbHVnaW4iKQoKCkBjdHgub25fZXhlY3V0ZQphc3luYyBkZWYgaGFuZGxlKGFyZ3M6IGRpY3QpIC0+IE5vbmU6CiAgICBtZXNzYWdlID0gYXJncy5nZXQoIm1lc3NhZ2UiLCAiIikKICAgIHByaW50KGYiW215LXBsdWdpbl0gZXhlY3V0ZSBjYWxsZWQ6IG1lc3NhZ2U9e21lc3NhZ2V9IiwgZmx1c2g9VHJ1ZSkKCiAgICAjIGNoZWNrIHN0b3AvcGF1c2UgZHVyaW5nIGxvbmctcnVubmluZyB3b3JrCiAgICBmb3IgXyBpbiByYW5nZSgxMCk6CiAgICAgICAgYXdhaXQgY3R4LmNoZWNrX3N0b3AoKQogICAgICAgIGF3YWl0IGFzeW5jaW8uc2xlZXAoMC4xKQoKICAgICMgcmVhZCBhIHByb2dyYW0gdmFyaWFibGUKICAgIGNvdW50ZXIgPSBhd2FpdCBjdHguZ2V0X3ZhcmlhYmxlKCJjb3VudGVyIikKICAgIHByaW50KGYiW215LXBsdWdpbl0gY291bnRlcj17Y291bnRlcn0iLCBmbHVzaD1UcnVlKQoKICAgICMgdXBkYXRlIGEgdmFyaWFibGUKICAgIGF3YWl0IGN0eC5zZXRfdmFyaWFibGUoInJlc3VsdCIsIGYiZG9uZToge21lc3NhZ2V9IikKCiAgICAjIGZpbmlzaCB0aGUgc3RlcAogICAgYXdhaXQgY3R4LmRvbmUoKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBhc3luY2lvLnJ1bihjdHguc3RhcnQoKSkKYGBgCgojIyMgQysrCgpDKysgcGx1Z2lucyB1c2UgYGNwcC9gIGFuZCBhcmUgYnVpbHQgd2l0aCBDTWFrZSBpbnNpZGUgRG9ja2VyLiBUaGUgY3VycmVudCBDKysKdGVtcGxhdGUgaXMgYSBidWlsZC9ydW4gc2tlbGV0b247IHdpcmUgaXQgdG8gdGhlIHBsdWdpbiBnYXRld2F5IHdoZW4gdGhlIEMrKyBTREsKaXMgYXZhaWxhYmxlLgoKYGBgY3BwCiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx0aHJlYWQ+CgppbnQgbWFpbigpIHsKICBjb25zdCBjaGFyKiBwbHVnaW5faWQgPSBzdGQ6OmdldGVudigiUkJfUExVR0lOX0lEIik7CiAgc3RkOjpjb3V0IDw8ICJbX19QTFVHSU5fTkFNRV9fXSBiYWNrZW5kIHJlYWR5IgogICAgICAgICAgICA8PCAocGx1Z2luX2lkID8gc3RkOjpzdHJpbmcoIiAoaWQ9IikgKyBwbHVnaW5faWQgKyAiKSIgOiAiIikKICAgICAgICAgICAgPDwgc3RkOjplbmRsOwoKICB3aGlsZSAodHJ1ZSkgewogICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjpzZWNvbmRzKDEpKTsKICB9CiAgcmV0dXJuIDA7Cn0KYGBgCgojIyMgUk9TMiAocmNscHkpCgpST1MyIFB5dGhvbiBwbHVnaW5zIHVzZSBgcm9zMl93cy9gIHdpdGggYHJ1bnRpbWUucm9zQ2xpZW50OiAicmNscHkiYC4gVGhlIG5vZGUKaXMgbGF1bmNoZWQgd2l0aCBgLS1yb3MtYXJncyAtciBfX25zOj0ve3NsdWd9YCBhdXRvbWF0aWNhbGx5IGJ5IGBkZXY6YmFja2AuCgpgYGBweXRob24KIyByb3MyX3dzL3NyYy9fX1BMVUdJTl9TTFVHX18vX19QTFVHSU5fU0xVR19fL25vZGUucHkKaW1wb3J0IHJjbHB5CmZyb20gcmNscHkubm9kZSBpbXBvcnQgTm9kZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQk1hbmlwdWxhdGVTREsKCnNkayA9IFJCTWFuaXB1bGF0ZVNESygpCgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUoTm9kZSk6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygiX19QTFVHSU5fU0xVR19fX25vZGUiKQogICAgICAgIHNlbGYuZ2V0X2xvZ2dlcigpLmluZm8oIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKQogICAgICAgICMgdXNlIHNkayBhbG9uZ3NpZGUgUk9TMiBwdWJsaXNoZXJzL3N1YnNjcmliZXJzL3NlcnZpY2VzIGFzIG5lZWRlZApgYGAKCiMjIyBST1MyIChyY2xjcHApCgpST1MyIEMrKyBwbHVnaW5zIHVzZSBgcm9zMl93cy9gIHdpdGggYHJ1bnRpbWUucm9zQ2xpZW50OiAicmNsY3BwImAuCgpgYGBjcHAKI2luY2x1ZGUgInJjbGNwcC9yY2xjcHAuaHBwIgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUgOiBwdWJsaWMgcmNsY3BwOjpOb2RlIHsKcHVibGljOgogIF9fUExVR0lOX0NMQVNTX19Ob2RlKCkgOiBOb2RlKCJfX1BMVUdJTl9TTFVHX19fbm9kZSIpIHsKICAgIFJDTENQUF9JTkZPKHRoaXMtPmdldF9sb2dnZXIoKSwgIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKTsKICB9Cn07CmBgYAoKLS0tCgojIyBtYW5pZmVzdC5qc29uCgpgYGBqc29uYwp7CiAgLy8gdW5pcXVlIHBsdWdpbiBJRCDigJQgcmV2ZXJzZS1kb21haW4gZm9ybWF0IHJlY29tbWVuZGVkCiAgImlkIjogImNvbS5leGFtcGxlLm15LXBsdWdpbiIsCiAgIm5hbWUiOiAiTXkgUGx1Z2luIiwKICAidmVyc2lvbiI6ICIxLjAuMCIsCgogIC8vIG1pbmltdW0gTXVzY2F0IHZlcnNpb24gcmVxdWlyZWQgdG8gbG9hZCB0aGlzIHBsdWdpbgogICJtaW5NdXNjYXRWZXJzaW9uIjogIjEuMC4wIiwKCiAgLy8gcGx1Z2luIGF1dGhvciAoZW1wdHkgc3RyaW5nIGlzIGZpbmUpCiAgImF1dGhvciI6ICJZb3VyIE5hbWUiLAoKICAvLyBkaXNwbGF5ZWQgaW4gdGhlIE11c2NhdCBwbHVnaW4gc3RvcmUgLyBpbmZvIHBhbmVsCiAgLy8gc3RyaW5nIG9yIHsgZW4gKHJlcXVpcmVkKSwga28sIGphLCB6aCwgdmksIHRoLCBlcyB9CiAgImRlc2NyaXB0aW9uIjogeyAiZW4iOiAiUGx1Z2luIGRlc2NyaXB0aW9uIiwgImtvIjogIu2UjOufrOq3uOyduCDshKTrqoUiIH0sCgogIC8vIFNWRyBzdHJpbmcgKHNpbmdsZSBmaWxlKSBvciBQTkcvSlBHIHNpemUgbWFwIChhbGwgdGhyZWUgc2l6ZXMgcmVxdWlyZWQpCiAgImljb25zIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgLy8gImljb25zIjogeyAiMTYiOiAiYXNzZXRzL2ljb24tMTYucG5nIiwgIjQ4IjogImFzc2V0cy9pY29uLTQ4LnBuZyIsICIxMjgiOiAiYXNzZXRzL2ljb24tMTI4LnBuZyIgfSwKCiAgLy8gdGFyZ2V0TW9kZWxzIGFuZC9vciB0YXJnZXRDYXRlZ29yeXMg4oCUIGF0IGxlYXN0IG9uZSBpcyByZXF1aXJlZAogIC8vICJhbGwiID0gZXZlcnkgdGFyZ2V0LCBvciBsaXN0IHNwZWNpZmljIHZhbHVlcwogICJ0YXJnZXRNb2RlbHMiOiAiYWxsIiwKICAvLyAidGFyZ2V0TW9kZWxzIjogWyJDNTAwOTIwIiwgIkM1MDA5MzAiXSwKICAidGFyZ2V0Q2F0ZWdvcnlzIjogImFsbCIsCiAgLy8gInRhcmdldENhdGVnb3J5cyI6IFsibWFuaXB1bGF0ZSIsICJhbXIiLCAicmJ5MSIsICJ2aXNpb24iXSwKCiAgImNvbnRyaWJ1dGVzIjogWwogICAgLy8gcHJvZ3JhbS5wYW5lbCDigJQgZGVmaW5lcyBhIGN1c3RvbSBjb21tYW5kIGZvciB0aGUgUHJvZ3JhbSBwYWdlIHNlcXVlbmNlCiAgICAvLyAgIGJ1aWxkZXI7IHJ1bnMgdmlhIFBsdWdpblByb2dyYW1Db250ZXh0IHdoZW4gdGhlIHByb2dyYW0gcmVhY2hlcyBpdAogICAgewogICAgICAicG9pbnQiOiAicHJvZ3JhbS5wYW5lbCIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIuuCtCDtlIzrn6zqt7jsnbgiLCAiZW4iOiAiTXkgUGx1Z2luIiB9LAogICAgICAidWkiOiAicHJvZ3JhbSIsICAgICAgICAgICAvLyBtdXN0IGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGNvbnRyaWJ1dGlvbnMKICAgICAgImNvbW1hbmRJbmZvIjogewogICAgICAgICJuYW1lIjogIk15IFBsdWdpbiIsCiAgICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgICAiZnVuY05hbWUiOiAicmJfcHJvZ3JhbV9zZGsucGx1Z2luX2V4ZWN1dGUiLAogICAgICAgICJhcmdzIjoge30KICAgICAgfQogICAgfSwKICAgIC8vIHRvb2xiYXIg4oCUIGFkZHMgYSBidXR0b24gdG8gdGhlIHRvcCB0b29sYmFyIChyZXF1aXJlZCkKICAgIHsKICAgICAgInBvaW50IjogInRvb2xiYXIiLAogICAgICAiaWNvbiI6ICJhc3NldHMvaWNvbi5zdmciLAogICAgICAibGFiZWwiOiB7ICJrbyI6ICLrgrQg7ZSM65+s6re47J24IiwgImVuIjogIk15IFBsdWdpbiIgfSwKICAgICAgInVpIjogImNvbnRlbnQiLCAgICAgICAgICAgLy8gbXVzdCBiZSB1bmlxdWUgYWNyb3NzIGFsbCBjb250cmlidXRpb25zCiAgICAgICJvcGVucyI6ICJwb3BvdmVyIiAgICAgICAgIC8vIHBvcG92ZXIgfCBwYW5lbCB8IHBhZ2UKICAgIH0sCiAgICAvLyBtb3ZlLnBhbmVsIOKAlCBhZGRzIGEgcGFuZWwgdG8gdGhlIE1vdmUgc2NyZWVuCiAgICB7CiAgICAgICJwb2ludCI6ICJtb3ZlLnBhbmVsIiwKICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgImxhYmVsIjogeyAia28iOiAi64K0IO2UjOufrOq3uOyduCIsICJlbiI6ICJNeSBQbHVnaW4iIH0sCiAgICAgICJ1aSI6ICJtb3ZlIiAgICAgICAgICAgICAgIC8vIG11c3QgYmUgdW5pcXVlIGFjcm9zcyBhbGwgY29udHJpYnV0aW9ucwogICAgfQogIF0sCgogIC8vIHJ1bnRpbWUg4oCUIG9uZSBvZjoKICAvLyAgIHsgInR5cGUiOiAibm9uZSIgfQogIC8vICAgeyAidHlwZSI6ICJweXRob24iLCAiZW50cnkiOiAibWFpbi5weSIgfQogIC8vICAgeyAidHlwZSI6ICJjcHAiLCAiZW50cnkiOiAiPGV4ZWN1dGFibGUgbmFtZT4iIH0KICAvLyAgIHsgInR5cGUiOiAicm9zMiIsICJyb3NDbGllbnQiOiAicmNscHkiIHwgInJjbGNwcCIsICJwYWNrYWdlIjogIi4uLiIsICJsYXVuY2giOiAiLi4uX25vZGUiIH0KICAicnVudGltZSI6IHsgInR5cGUiOiAicHl0aG9uIiwgImVudHJ5IjogIm1haW4ucHkiIH0sCgogIC8vIG9wdGlvbmFsOiBUQ1AgcG9ydHMgb3BlbmVkIGJ5IHRoaXMgcGx1Z2luIGJhY2tlbmQKICAvLyBvbmx5IG51bWJlcltdIGlzIGFsbG93ZWQ7IHJhbmdlcy9vYmplY3RzIGFyZSBub3QgYWNjZXB0ZWQKICAvLyBleHRlcm5hbCBwbHVnaW4gcG9ydHMgbXVzdCBiZSB3aXRoaW4gMjg2MDAtMjg5OTkKICAicG9ydHMiOiBbMjg2MDBdCn0KYGBgCgoqKkJhY2tlbmQgdHlwZXM6KioKCnwgdHlwZSB8IHNvdXJjZSBkaXIgfCBidWlsZCAvIHJ1biB8IGVudHJ5IHwKfC0tLXwtLS18LS0tfC0tLXwKfCBgcHl0aG9uYCB8IGBweS9gIHwgcGlwICsgcnVuIGluIERvY2tlciB8IGBtYWluLnB5YCB8CnwgYGNwcGAgfCBgY3BwL2AgfCBDTWFrZSBpbiBEb2NrZXIgfCBidWlsdCBleGVjdXRhYmxlIG5hbWUgfAp8IGByb3MyYCAocmNscHkpIHwgYHJvczJfd3MvYCB8IGNvbGNvbiAoYW1lbnRfcHl0aG9uKSBpbiBEb2NrZXIgfCDigJQgfAp8IGByb3MyYCAocmNsY3BwKSB8IGByb3MyX3dzL2AgfCBjb2xjb24gKGFtZW50X2NtYWtlKSBpbiBEb2NrZXIgfCDigJQgfAoKPiBFdmVyeSBiYWNrIGVuZCBydW5zIGluIGEgRG9ja2VyIGNvbnRhaW5lciBtYXRjaGluZyB0aGUgcm9ib3QgKFVidW50dSAyNC4wNCArIFB5dGhvbiAzLjEyKSwgc28gZGV2IGJlaGF2ZXMgbGlrZSBwcm9kdWN0aW9uIGFuZCBjb21waWxlZCBiaW5hcmllcyBhcmUgQUJJLWNvbXBhdGlibGUuICoqRG9ja2VyIGlzIHJlcXVpcmVkKiogZm9yIGFsbCBiYWNrZW5kIHR5cGVzIChvbmx5IGEgZnJvbnRlbmQtb25seSBgbm9uZWAgcGx1Z2luIHNraXBzIGl0KS4gTm8gbG9jYWwgUHl0aG9uL3Rvb2xjaGFpbiBzZXR1cCBpcyBuZWVkZWQuCgoqKkNvbnRyaWJ1dGlvbiBwb2ludHM6KioKCnwgcG9pbnQgfCBXaGVyZSBpdCBhcHBlYXJzIHwgQmFja2VuZCB8IGBjb21tYW5kSW5mb2AgfAp8LS0tfC0tLXwtLS18Oi0tLTp8CnwgYHRvb2xiYXJgIHwgVG9wIHRvb2xiYXIgYnV0dG9uIChtdXN0IGhhdmUgYXQgbGVhc3Qgb25lKSB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgbG5iYCB8IExlZnQgbmF2aWdhdGlvbiBlbnRyeSB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgbW92ZS5wYW5lbGAgfCBNb3ZlIHNjcmVlbiBwYW5lbCB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgcHJvZ3JhbS5wYW5lbGAgfCBDdXN0b20gY29tbWFuZCBpbiB0aGUgUHJvZ3JhbSBwYWdlIHNlcXVlbmNlIGJ1aWxkZXIgfCBgUGx1Z2luUHJvZ3JhbUNvbnRleHRgIHwg4pyTIHwKCioqYGNvbW1hbmRJbmZvYCBmaWVsZHMqKiAoZm9yIGBwcm9ncmFtLnBhbmVsYCk6Cgp8IGZpZWxkIHwgdHlwZSB8IGRlc2NyaXB0aW9uIHwKfC0tLXwtLS18LS0tfAp8IGBuYW1lYCB8IGBzdHJpbmdgIHwgRGlzcGxheSBuYW1lIG9mIHRoZSBjb21tYW5kIGluIHRoZSBwcm9ncmFtIHRyZWUgfAp8IGBpY29uYCB8IGBzdHJpbmdgIHwgSWNvbiBwYXRoIHwKfCBgaWNvbkNsYXNzTmFtZWAgfCBgc3RyaW5nP2AgfCBPcHRpb25hbCBDU1MgY2xhc3MgZm9yIHRoZSBpY29uIHwKfCBgZnVuY05hbWVgIHwgYHN0cmluZz9gIHwgQmFja2VuZCBmdW5jdGlvbiBuYW1lIHRvIGNhbGwgfAp8IGBhcmdzYCB8IGBSZWNvcmQ8c3RyaW5nLCBhbnk+P2AgfCBEZWZhdWx0IGFyZ3VtZW50cyB8CnwgYGRpc2FibGVkYCB8IGBib29sZWFuP2AgfCBXaGV0aGVyIHRoZSBub2RlIGlzIGRpc2FibGVkIHwKfCBgYWxsb3dDaGlsZHJlbmAgfCBgc3RyaW5nW10/YCB8IEFsbG93ZWQgY2hpbGQgY29tbWFuZHMgfAp8IGBhbGxvd1BhcmVudHNgIHwgYHN0cmluZ1tdP2AgfCBBbGxvd2VkIHBhcmVudCBjb21tYW5kcyB8CnwgYG5vdEFsbG93Q2hpbGRyZW5gIHwgYHN0cmluZ1tdP2AgfCBEaXNhbGxvd2VkIGNoaWxkIGNvbW1hbmRzIHwKfCBgc3luY0dyb3VwSWRgIHwgYGJvb2xlYW4/YCB8IFN5bmMgZ3JvdXAgSUQgYWNyb3NzIGNoaWxkcmVuIHwKfCBgZGlzYWJsZUNvcHlgIHwgYGJvb2xlYW4/YCB8IFByZXZlbnQgY29weSB8CnwgYGRpc2FibGVEZWxldGVgIHwgYGJvb2xlYW4/YCB8IFByZXZlbnQgZGVsZXRlIHwKfCBgcmVxdWlyZUNoaWxkcmVuYCB8IGBib29sZWFuP2AgfCBXaGV0aGVyIGEgY2hpbGQgY29tbWFuZCBpcyByZXF1aXJlZCB8CnwgYHJlcXVpcmVQYXJlbnRgIHwgYGJvb2xlYW4/YCB8IFdoZXRoZXIgYSBwYXJlbnQgY29tbWFuZCBpcyByZXF1aXJlZCB8CnwgYGNoaWxkcmVuQ29tbWFuZGAgfCBgc3RyaW5nP2AgfCBEZWZhdWx0IGNvbW1hbmQgdHlwZSBmb3IgY2hpbGRyZW4gfAoKKipWYWxpZGF0aW9uIHJ1bGVzOioqCi0gYGlkYCwgYG5hbWVgLCBgdmVyc2lvbmAsIGBtaW5NdXNjYXRWZXJzaW9uYCDigJQgcmVxdWlyZWQgbm9uLWVtcHR5IHN0cmluZ3MKLSBgYXV0aG9yYCDigJQgcmVxdWlyZWQgbm9uLWVtcHR5IHN0cmluZwotIGBkZXNjcmlwdGlvbmAg4oCUIHJlcXVpcmVkIChgc3RyaW5nYCBvciBgeyBlbiAocmVxdWlyZWQpLCBrbz8sIGphPywgemg/LCB2aT8sIHRoPywgZXM/IH1gKQotIGBpY29uc2Ag4oCUIFNWRzogc2luZ2xlIHN0cmluZyBwYXRoIGVuZGluZyBpbiBgLnN2Z2A7IFBORy9KUEc6IG9iamVjdCB3aXRoIGAiMTYiYCwgYCI0OCJgLCBgIjEyOCJgIGFsbCBwcmVzZW50Ci0gYHRhcmdldE1vZGVsc2Ag4oCUIGAiYWxsImAgb3IgYSBub24tZW1wdHkgYXJyYXkgb2Ygcm9ib3QgbW9kZWwgSUQgc3RyaW5ncyAoYXQgbGVhc3Qgb25lIG9mIGB0YXJnZXRNb2RlbHNgIC8gYHRhcmdldENhdGVnb3J5c2AgcmVxdWlyZWQpCi0gYHRhcmdldENhdGVnb3J5c2Ag4oCUIGAiYWxsImAgb3IgYSBub24tZW1wdHkgYXJyYXkgb2YgYCJtYW5pcHVsYXRlIiB8ICJhbXIiIHwgInJieTEiIHwgInZpc2lvbiJgIChhdCBsZWFzdCBvbmUgb2YgYHRhcmdldE1vZGVsc2AgLyBgdGFyZ2V0Q2F0ZWdvcnlzYCByZXF1aXJlZCkKLSBgY29udHJpYnV0ZXNgIOKAlCByZXF1aXJlZCBhcnJheTsgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBgdG9vbGJhcmAgZW50cnkKLSBgdWlgIOKAlCBlYWNoIGNvbnRyaWJ1dGlvbiBtdXN0IGhhdmUgYSB1bmlxdWUgdmFsdWUKLSBgY29tbWFuZEluZm9gIOKAlCByZXF1aXJlZCB3aGVuIGBwb2ludGAgaXMgYCJwcm9ncmFtLnBhbmVsImAKLSBgcG9ydHNgIOKAlCBvcHRpb25hbCBgbnVtYmVyW11gOyBldmVyeSBwb3J0IG11c3QgYmUgd2l0aGluIGAyODYwMC0yODk5OWAKICBhbmQgbXVzdCBub3QgYmUgYSByZXNlcnZlZCByb2JvdC9pbmR1c3RyaWFsL2ludGVybmFsIHBvcnQKCmBtdXNjYXQtcGsgYnVpbGRgIHRocm93cyBvbiBhbnkgdmFsaWRhdGlvbiBlcnJvci4gYG11c2NhdC1wayBkZXZgIHByaW50cyB3YXJuaW5ncy4KCioqQmFja2VuZCBwb3J0IHJ1bGVzOioqCi0gRGVjbGFyZSBhIHBvcnQgb25seSBpZiB5b3VyIGJhY2tlbmQgb3BlbnMgYSBUQ1Agc2VydmVyL2xpc3RlbmVyLgotIGBtdXNjYXQtcGsgZGV2YCBhbmQgYG11c2NhdC1wayBkZXY6YmFja2Agc3RvcCB0aGUgYmFja2VuZCBpZiBpdCBvcGVucyBhbgogIHVuZGVjbGFyZWQgbWFuYWdlZCBwb3J0LgotIFJlc2VydmVkIHBvcnRzIGluY2x1ZGUgYDUwMmAsIGAyMjIyYCwgYDQ4NDBgLCBgNTE3MC01MTc5YCwgYDgwMDAtODk5OWAsCiAgYDEwMDAwYCwgYDMwMDA0YCwgYDM0OTY0YCwgYDQ0ODE4YCwgYDUwMDAwLTUwMDA1YCwgYW5kIGA1MDA1MWAuCgotLS0KCiMjIExvY2FsaXplZCBkb2N1bWVudGF0aW9uCgpZb3UgY2FuIHNoaXAgcGVyLWxhbmd1YWdlIFJFQURNRSBmaWxlcyBhbG9uZ3NpZGUgdGhlIG1haW4gYFJFQURNRS5tZGAuIFBsYWNlIHRoZW0gaW4gdGhlIHByb2plY3Qgcm9vdDoKCmBgYApSRUFETUUubWQgICAgICAgICMgZGVmYXVsdCAvIEVuZ2xpc2ggZmFsbGJhY2sKUkVBRE1FLmtvLm1kICAgICAjIEtvcmVhbgpSRUFETUUuZW4ubWQgICAgICMgZXhwbGljaXQgRW5nbGlzaCAob3B0aW9uYWwpClJFQURNRS5qYS5tZCAgICAgIyBKYXBhbmVzZQpgYGAKCkFsbCBgUkVBRE1FKi5tZGAgZmlsZXMgZm91bmQgYXQgdGhlIHByb2plY3Qgcm9vdCBhcmUgYXV0b21hdGljYWxseSBjb3BpZWQgdG8gYGRpc3QvYCBvbgpgbXVzY2F0LXBrIGJ1aWxkYC4gTXVzY2F0IGRpc3BsYXlzIHRoZSBmaWxlIG1hdGNoaW5nIHRoZSB1c2VyJ3MgbG9jYWxlLApmYWxsaW5nIGJhY2sgdG8gYFJFQURNRS5tZGAgaWYgbm9uZSBtYXRjaGVzLgoKLS0tCgojIyBJbnN0YWxsaW5nIFB5dGhvbiBkZXBlbmRlbmNpZXMKCkFkZCBhbnkgcGFja2FnZSB3aXRoIGFuIG9wdGlvbmFsIHZlcnNpb24gcGluIHRvIGByZXF1aXJlbWVudHMudHh0YDoKCmBgYApyYWluYm93LXJiLXNkawpyYWluYm93LXJiLWZsYXQtYnVmZmVycwpudW1weT09MS4yNi40Cm9wZW5jdi1weXRob24KYGBgCgpSdW4gYG11c2NhdC1wayBkZXZgIG9yIGBtdXNjYXQtcGsgZGV2OmJhY2tgIOKAlCBkZXBlbmRlbmNpZXMgYXJlIGluc3RhbGxlZCBhdXRvbWF0aWNhbGx5Cmluc2lkZSB0aGUgZGV2IGNvbnRhaW5lciAoYHBpcCBpbnN0YWxsIC1yIHJlcXVpcmVtZW50cy50eHRgKSBvbiBldmVyeSBzdGFydHVwLiBObwpsb2NhbCBQeXRob24gaXMgcmVxdWlyZWQgZm9yIHRoaXMuCgpgbXVzY2F0LXBrIGRldjpiYWNrYCBhbHNvIGJlc3QtZWZmb3J0IGNyZWF0ZXMvcmVmcmVzaGVzIGEgbG9jYWwgYC52ZW52YCBpbiB0aGUKYmFja2dyb3VuZCAodmlhIGB1dmAgaWYgYXZhaWxhYmxlLCBlbHNlIHlvdXIgc3lzdGVtIFB5dGhvbikgd2l0aCB0aGUgc2FtZSBkZXBzIOKAlApwdXJlbHkgc28geW91ciBlZGl0b3IgKHB5bGludCwgcHlyaWdodCwgbXlweSwgLi4uKSBjYW4gcmVzb2x2ZSBpbXBvcnRzIGFuZCBsaW50CmNvcnJlY3RseS4gSXQncyBub3QgdXNlZCB0byBydW4gdGhlIGJhY2tlbmQ7IERvY2tlciBpcyB0aGUgYWN0dWFsIGV4ZWN1dGlvbgplbnZpcm9ubWVudCwgc28gdGhpcyBzdGVwIGlzIHNpbGVudGx5IHNraXBwZWQgaWYgbm8gbG9jYWwgUHl0aG9uIHRvb2xjaGFpbiBpcwphdmFpbGFibGUuIFBvaW50IHlvdXIgZWRpdG9yJ3MgUHl0aG9uIGludGVycHJldGVyIGF0IGAudmVudmAuCgpgbXVzY2F0LXBrIHNkayB1cGRhdGVgIGFsc28gcmVmcmVzaGVzIGAudmVudmAgaW4gcGxhY2UgaWYgb25lIGFscmVhZHkgZXhpc3RzLCBzbwp5b3VyIGVkaXRvciBwaWNrcyB1cCB0aGUgbmV3IGByYWluYm93LXJiLXNka2AgdmVyc2lvbiBpbW1lZGlhdGVseS4KCj4gYG11c2NhdC1wayBidWlsZGAgb25seSAqKnBpbnMqKiB2ZXJzaW9ucyBpbiBgcmVxdWlyZW1lbnRzLnR4dGAg4oCUIGl0IGRvZXMgbm90IHJ1biBgcGlwIGluc3RhbGxgICh0aGUgcm9ib3QgaW5zdGFsbHMgdGhlbSBhdCBsb2FkIHRpbWUpLgoKLS0tCgojIyBTd2l0Y2hpbmcgYmFja2VuZCB0eXBlCgpgYGBiYXNoCm11c2NhdC1wayB0eXBlIGNoYW5nZSAgICAgICAgICAgICAgICAgIyBpbnRlcmFjdGl2ZQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byBjcHAgICAgICAgICMg4oaSIEMrKwptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byByb3MyICAgICAgICMg4oaSIFJPUzIgKHJjbHB5IC8gUHl0aG9uKQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byByb3MyLWNwcCAgICMg4oaSIFJPUzIgKHJjbGNwcCAvIEMrKykKbXVzY2F0LXBrIHR5cGUgY2hhbmdlIC0tdG8gcHl0aG9uICAgICAjIOKGkiBQeXRob24KYGBgCgo+IEV4aXN0aW5nIGJhY2tlbmQgZGlycyAoYHJvczJfd3MvYCwgYGNwcC9gKSBhcmUgbm90IGRlbGV0ZWQgd2hlbiBzd2l0Y2hpbmcgYXdheS4gUmVtb3ZlIHRoZW0gbWFudWFsbHkgaWYgbm8gbG9uZ2VyIG5lZWRlZC4KCi0tLQoKIyMgQUkgY29kaW5nIGFzc2lzdGFudHMgKE1DUCkKCklmIHlvdSBidWlsZCB5b3VyIHBsdWdpbiB3aXRoIGFuIEFJIGFzc2lzdGFudCAoQ2xhdWRlIENvZGUsIENvZGV4LCDigKYpLCBnaXZlIGl0Cmdyb3VuZGVkIGtub3dsZWRnZSBvZiB0aGUgTXVzY2F0IFVJIGNvbXBvbmVudHMsIGRlc2lnbiB0b2tlbnMsIGFuZCBTREsgaW5zdGVhZCBvZgpsZXR0aW5nIGl0IGd1ZXNzLiBgbXVzY2F0LXBrIG1jcGAgaXMgYW4gTUNQIHNlcnZlciBleHBvc2luZzoKCi0gYGxpc3RfY29tcG9uZW50c2AgLyBgZ2V0X2NvbXBvbmVudF9wcm9wc2AgLyBgZ2V0X2NvbXBvbmVudF9leGFtcGxlYCDigJQgZXZlcnkKICBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3JlYWN0YCBjb21wb25lbnQgd2l0aCBpdHMgcmVhbCBwcm9wcyBhbmQgYSB3b3JraW5nCiAgU3Rvcnlib29rIGV4YW1wbGUuCi0gYGxpc3RfZGVzaWduX3Rva2Vuc2AgLyBgc2VhcmNoX2Rlc2lnbl90b2tlbnNgIOKAlCB0aGUgVGFpbHdpbmQgY2xhc3NlcyB0byB1c2UKICAoYGJnLWJnLSpgLCBgdGV4dC1mZy0qYCwgYHR5cG8tKmAsIOKApikgc28geW91ciBVSSBtYXRjaGVzIHRoZSBob3N0IHRoZW1lLgotIGBzZWFyY2hfcmJfc2RrYCDigJQgaG93IHRvIHVzZSBgdXNlUmIoKWAsIGByYi4qYCwgYHVzZVJiRm9ybURhdGFgL2B1c2VSYlNhdmVgLCBhbmQKICB0aGUgYmFja2VuZCBydW50aW1lcy4KLSBgbGlzdF9yYl9zZGtgIC8gYGdldF9yYl9zZGtfYXBpYCDigJQgdGhlIGluc3RhbGxlZCBgcmFpbmJvdy1yYi1zZGtgIChQeXRob24KICBiYWNrZW5kKSBjbGFzc2VzIGFuZCBzaWduYXR1cmVzLgoKKipCcm93c2UgdGhlIGNvbXBvbmVudHMgbGl2ZSoqIHdpdGggYG11c2NhdC1wayBzdG9yeWJvb2tgLgoKIyMjIFJlZ2lzdGVyIHRoZSBzZXJ2ZXIKCioqQ2xhdWRlIENvZGUqKiDigJQgYSBgLm1jcC5qc29uYCBpcyBhbHJlYWR5IHNjYWZmb2xkZWQgYXQgeW91ciBwbHVnaW4gcm9vdCwgc28KaXQgd29ya3Mgb3V0IG9mIHRoZSBib3g6CgpgYGBqc29uCnsKICAibWNwU2VydmVycyI6IHsKICAgICJtdXNjYXQiOiB7CiAgICAgICJjb21tYW5kIjogIm11c2NhdC1wayIsCiAgICAgICJhcmdzIjogWyJtY3AiXQogICAgfQogIH0KfQpgYGAKCioqQ29kZXgqKiDigJQgYWRkIHRvIGB+Ly5jb2RleC9jb25maWcudG9tbGA6CgpgYGB0b21sClttY3Bfc2VydmVycy5tdXNjYXRdCmNvbW1hbmQgPSAibXVzY2F0LXBrIgphcmdzID0gWyJtY3AiXQpgYGAKCkFueSBvdGhlciBNQ1AgY2xpZW50IHdvcmtzIHRvbyDigJQgaXQncyBhIHN0YW5kYXJkIHN0ZGlvIE1DUCBzZXJ2ZXIgc3RhcnRlZCB3aXRoCmBtdXNjYXQtcGsgbWNwYC4gSWYgYG11c2NhdC1wa2AgaXNuJ3Qgb24gdGhlIGNsaWVudCdzIFBBVEgsIHVzZSBpdHMgYWJzb2x1dGUgcGF0aAooYHdoaWNoIG11c2NhdC1wa2ApIGFzIGBjb21tYW5kYC4KCi0tLQoKIyMgU2hpcHBpbmcKCmBgYGJhc2gKbXVzY2F0LXBrIGJ1aWxkICAgICAgICAgICAgIyBidWlsZCArIFpJUAptdXNjYXQtcGsgYnVpbGQgLS1uby16aXAgICAjIGJ1aWxkIG9ubHksIG5vIFpJUApgYGAKCi0gQnVpbGRzIGB1aS9jb250ZW50LnRzeGAg4oaSIGBkaXN0L2NvbnRlbnQuanNgIChtaW5pZmllZCkKLSBQaW5zIGByZXF1aXJlbWVudHMudHh0YCB0byBsYXRlc3QgdmVyc2lvbnMgKHN0YWJsZS1vbmx5IG9uIGBtYWluYCBicmFuY2gpCi0gQ29waWVzIGBhc3NldHMvYCwgYG1hbmlmZXN0Lmpzb25gLCBgUkVBRE1FKi5tZGAsIGBweS9gLCBhbmQgYHJlcXVpcmVtZW50cy50eHRgIGludG8gYGRpc3QvYAotIFJPUzI6IHJ1bnMgYGNvbGNvbiBidWlsZGAgaW5zaWRlIHRoZSBKYXp6eSBjb250YWluZXI7IGluY2x1ZGVzIGByb3MyX3dzL2luc3RhbGwvYAotIE91dHB1dDogYF9fUExVR0lOX0RJUl9fLXt2ZXJzaW9ufS56aXBgCgpaSVAgbGF5b3V0OgoKYGBgCl9fUExVR0lOX0RJUl9fLTEuMC4wLnppcArilJzilIAgZGlzdC8K4pSCICAg4pSc4pSAIGNvbnRlbnQuanMgICAgICAgICMgYnVpbHQgVUkK4pSCICAg4pSc4pSAIG1hbmlmZXN0Lmpzb24K4pSCICAg4pSc4pSAIGFzc2V0cy8K4pSCICAg4pSc4pSAIFJFQURNRS5tZArilIIgICDilJzilIAgUkVBRE1FLmtvLm1kICAgICAgIyBpZiBwcmVzZW50CuKUgiAgIOKUnOKUgCBtYWluLnB5ICAgICAgICAgICAjIGZyb20gcHkvCuKUgiAgIOKUlOKUgCByZXF1aXJlbWVudHMudHh0ICAjIHBpbm5lZArilJTilIAgcm9zMl93cy9pbnN0YWxsLyAgICAgICMgUk9TMiBvbmx5CmBgYAoKLS0tCgojIyBBbGwgY29tbWFuZHMKCmBgYGJhc2gKbXVzY2F0LXBrIGRldiAgICAgICAgIyBVSSArIGJhY2tlbmQKbXVzY2F0LXBrIGRldjp1aSAgICAgIyBVSSBwcmV2aWV3IG9ubHkgKHByZXZpZXctaG9zdCkKbXVzY2F0LXBrIGRldjpiYWNrICAgIyBiYWNrZW5kIG9ubHkgKFB5dGhvbjogd2F0Y2hmaWxlcyAvIFJPUzI6IERvY2tlcikKbXVzY2F0LXBrIGJ1aWxkICAgICAgIyBidWlsZCDihpIgZGlzdC8gKyBkaXN0cmlidXRhYmxlIFpJUCAoLS1uby16aXAgdG8gc2tpcCkKbXVzY2F0LXBrIHN0b3J5Ym9vayAgIyBicm93c2UgdGhlIHJiLWNvbXBvbmVudHMgVUkgbGlicmFyeSBpbiBhIGJyb3dzZXIKbXVzY2F0LXBrIG1jcCAgICAgICAgIyBNQ1Agc2VydmVyIGZvciBBSSBhc3Npc3RhbnRzIChjb21wb25lbnRzL3Rva2Vucy9TREsgZG9jcykKYGBgCgpgYGBiYXNoCm11c2NhdC1wayB0eXBlIGNoYW5nZSAgICAjIHN3aXRjaCBiYWNrZW5kIHR5cGUKbXVzY2F0LXBrIHNkayBsaXN0ICAgICAgICMgc2hvdyBjdXJyZW50IFB5dGhvbiBTREsgdmVyc2lvbgptdXNjYXQtcGsgc2RrIHVwZGF0ZSAgICAgIyB1cGRhdGUgUHl0aG9uIFNESyB0byBsYXRlc3QKbXVzY2F0LXBrIHVwZGF0ZSAgICAgICAgICMgdXBkYXRlIG11c2NhdC1wbHVnaW4ta2l0IGl0c2VsZgptdXNjYXQtcGsgdW5pbnN0YWxsICAgICAgIyByZW1vdmUgbXVzY2F0LXBrIGl0c2VsZgpgYGAK","common/assets/icon.svg":"PHN2ZyB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGRlZnM+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImJnIiB4MT0iMzYiIHkxPSIyOCIgeDI9IjIyMCIgeTI9IjIyOCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgogICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjOEI1Q0Y2Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzVCMjFCNiIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhcGUiIHgxPSI5MiIgeTE9Ijc0IiB4Mj0iMTY4IiB5Mj0iMTc4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNEOEI0RkUiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjQTg1NUY3Ii8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogIDwvZGVmcz4KCiAgPHJlY3QgeD0iMTYiIHk9IjE2IiB3aWR0aD0iMjI0IiBoZWlnaHQ9IjIyNCIgcng9IjUyIiBmaWxsPSJ1cmwoI2JnKSIvPgoKICA8IS0tIHBsdWdpbiBicmFja2V0cyAtLT4KICA8cGF0aCBkPSJNNzIgODRINTZDNDcuMTYzNCA4NCA0MCA5MS4xNjM0IDQwIDEwMFYxMTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik0xODQgODRIMjAwQzIwOC44MzcgODQgMjE2IDkxLjE2MzQgMjE2IDEwMFYxMTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik03MiAxNzJINTZDNDcuMTYzNCAxNzIgNDAgMTY0LjgzNyA0MCAxNTZWMTQwIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjEyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNMTg0IDE3MkgyMDBDMjA4LjgzNyAxNzIgMjE2IDE2NC44MzcgMjE2IDE1NlYxNDAiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgoKICA8IS0tIGdyYXBlIHN0ZW0gKyBsZWFmIC0tPgogIDxwYXRoIGQ9Ik0xMjggNzNDMTI4IDU5IDEzNyA0OCAxNTEgNDQiIHN0cm9rZT0iI0YzRThGRiIgc3Ryb2tlLXdpZHRoPSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHBhdGggZD0iTTE0MiA1MUMxNTEgMzkgMTY5IDM5IDE3OSA1MEMxNjUgNjAgMTUxIDYyIDE0MiA1MVoiIGZpbGw9IiNDNEI1RkQiLz4KCiAgPCEtLSBtdXNjYXQgZ3JhcGUgY2x1c3RlciAtLT4KICA8Y2lyY2xlIGN4PSIxMDYiIGN5PSI5MSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTMyIiBjeT0iODgiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE1OCIgY3k9IjkxIiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSI5NCIgY3k9IjExOSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTIwIiBjeT0iMTE2IiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxNDYiIGN5PSIxMTYiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE3MiIgY3k9IjExOSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTA3IiBjeT0iMTQ1IiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxMzMiIGN5PSIxNDQiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE1OSIgY3k9IjE0NSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTIwIiBjeT0iMTcwIiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxNDYiIGN5PSIxNzAiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjEzMyIgY3k9IjE5MyIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CgogIDwhLS0gY2VudGVyIHBsdWdpbiBnbHlwaCAtLT4KICA8cGF0aCBkPSJNMTIyIDExOVYxMDlDMTIyIDEwMy40NzcgMTI2LjQ3NyA5OSAxMzIgOTlIMTM2QzE0MS41MjMgOTkgMTQ2IDEwMy40NzcgMTQ2IDEwOVYxMTkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHJlY3QgeD0iMTE2IiB5PSIxMTgiIHdpZHRoPSIzNiIgaGVpZ2h0PSIzNCIgcng9IjEwIiBmaWxsPSJ3aGl0ZSIvPgogIDxwYXRoIGQ9Ik0xMjcgMTUyVjE2MyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI4IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNMTQxIDE1MlYxNjMiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+Cjwvc3ZnPgo=","common/manifest.json":"ewogICJpZCI6ICJfX1BMVUdJTl9JRF9fIiwKICAibmFtZSI6ICJfX1BMVUdJTl9OQU1FX18iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAibWluTXVzY2F0VmVyc2lvbiI6ICIxLjAuMCIsCiAgImF1dGhvciI6ICJfX1BMVUdJTl9BVVRIT1JfXyIsCiAgImVtYWlsIjogIl9fUExVR0lOX0VNQUlMX18iLAogICJkZXNjcmlwdGlvbiI6IHsKICAgICJrbyI6ICIiLAogICAgImVuIjogIiIKICB9LAogICJpY29ucyI6ICJhc3NldHMvaWNvbi5zdmciLAogICJ0YXJnZXRNb2RlbHMiOiAiYWxsIiwKICAidGFyZ2V0Q2F0ZWdvcnlzIjogImFsbCIsCiAgImNvbnRyaWJ1dGVzIjogWwogICAgewogICAgICAicG9pbnQiOiAidG9vbGJhciIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIl9fUExVR0lOX05BTUVfXyIsICJlbiI6ICJfX1BMVUdJTl9OQU1FX18iIH0sCiAgICAgICJ1aSI6ICJjb250ZW50IiwKICAgICAgIm9wZW5zIjogInBvcG92ZXIiCiAgICB9CiAgXSwKICAicnVudGltZSI6IHsgInR5cGUiOiAiX19SVU5USU1FX1RZUEVfXyIsICJlbnRyeSI6ICJtYWluLnB5IiB9Cn0K","common/package.json":"ewogICJuYW1lIjogIl9fUExVR0lOX0lEX18iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAicHJpdmF0ZSI6IHRydWUsCiAgInR5cGUiOiAibW9kdWxlIiwKICAiZGVwZW5kZW5jaWVzIjogewogICAgIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aSI6ICJfX1JCX1ZFUlNJT05fXyIKICB9LAogICJkZXZEZXBlbmRlbmNpZXMiOiB7CiAgICAiQHRhaWx3aW5kY3NzL3ZpdGUiOiAiXjQuMS4wIiwKICAgICJAcmFpbmJvdy1yb2JvdGljcy9tdXNjYXQtcGx1Z2luLWtpdCI6ICJfX1JCX1ZFUlNJT05fXyIsCiAgICAiQHJhaW5ib3ctcm9ib3RpY3MvcHJldmlldy1ob3N0IjogIl9fUkJfVkVSU0lPTl9fIiwKICAgICJAdHlwZXMvcmVhY3QiOiAiXjE5LjAuMTAiLAogICAgIkB0eXBlcy9yZWFjdC1kb20iOiAiXjE5LjAuNCIsCiAgICAiQHZpdGVqcy9wbHVnaW4tcmVhY3QiOiAiXjQuMC4wIiwKICAgICJ0YWlsd2luZGNzcyI6ICJeNC4xLjAiLAogICAgInR5cGVzY3JpcHQiOiAiXjUuOC4wIiwKICAgICJ2aXRlIjogIl42LjAuMCIKICB9Cn0K","common/py/main.py":"IiIiCk11c2NhdCBwbHVnaW4gYmFja2VuZCDigJQgX19QTFVHSU5fTkFNRV9fCgpPbi1yb2JvdCAoZGVmYXVsdCk6CiAgbXVzY2F0LXBrIGRldjpiYWNrCiAgcHl0aG9uIG1haW4ucHkKClJlbW90ZSBkZXYgKGZyb20geW91ciBsYXB0b3ApOgogIFNldCBlbnYgdmFycyBiZWZvcmUgcnVubmluZzoKICAgIE1VU0NBVF9ST0JPVF9IT1NUPTE5Mi4xNjguMS4xMDAKICAgIE1VU0NBVF9ST0JPVF9UT0tFTj08c2VydmljZSB0b2tlbj4KICBUaGVuOiBtdXNjYXQtcGsgZGV2OmJhY2sKIiIiCgppbXBvcnQgYXN5bmNpbwppbXBvcnQgb3MKZnJvbSB0eXBpbmcgaW1wb3J0IEFueQoKZnJvbSByYWluYm93LnJiX3NkayBpbXBvcnQgUkJNYW5pcHVsYXRlU0RLLCBSQlBsdWdpbkNhbGwKCgpQTFVHSU5fTkFNRSA9ICJfX1BMVUdJTl9OQU1FX18iCgpwbHVnaW4gPSBSQlBsdWdpbkNhbGwoKQptYW5pcHVsYXRlID0gUkJNYW5pcHVsYXRlU0RLKCkKCgpkZWYgcmVnaXN0ZXJfaGFuZGxlcnMoKToKICAgICMgUmVnaXN0ZXIgaGFuZGxlcnMgaGVyZSDigJQgY2FsbGVkIGFmdGVyIGNvbm5lY3QoKSBzbyBzdWJzY3JpcHRpb25zIHN1cnZpdmUKICAgICMgc2Vzc2lvbiByZWNvbm5lY3Rpb24gaW4gcmVtb3RlLWRldiBtb2RlLgoKICAgIEBwbHVnaW4uc3Vic2NyaWJlKCJldmVudCIpCiAgICBkZWYgb25fdWlfZXZlbnQocGF5bG9hZDogZGljdFtzdHIsIEFueV0gfCBOb25lID0gTm9uZSk6CiAgICAgICAgIiIiSGFuZGxlIG1lc3NhZ2VzIHB1Ymxpc2hlZCBmcm9tIHRoZSBwbHVnaW4gVUkgd2l0aCByYi5wdWIoImV2ZW50IiwgLi4uKS4iIiIKICAgICAgICBwcmludChmIlt7UExVR0lOX05BTUV9XSBldmVudDoiLCBwYXlsb2FkKQoKICAgIEBwbHVnaW4uc2VydmUoImdyaXAiKQogICAgZGVmIGdyaXAocGF5bG9hZDogZGljdFtzdHIsIEFueV0gfCBOb25lID0gTm9uZSk6CiAgICAgICAgIiIiSGFuZGxlIHRoZSBkZWZhdWx0IFVJIGJ1dHRvbjogcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KS4iIiIKICAgICAgICB3aWR0aCA9IChwYXlsb2FkIG9yIHt9KS5nZXQoIndpZHRoIiwgMjApCiAgICAgICAgcHJpbnQoZiJbe1BMVUdJTl9OQU1FfV0gZ3JpcCByZXF1ZXN0ZWQ6IHdpZHRoPXt3aWR0aH0iKQogICAgICAgIHBsdWdpbi5wdWJsaXNoKCJzdGF0ZSIsIHsicmVhZHkiOiBUcnVlLCAibGFzdF9ncmlwX3dpZHRoIjogd2lkdGh9KQogICAgICAgIHJldHVybiB7Im9rIjogVHJ1ZSwgIndpZHRoIjogd2lkdGh9CgogICAgQHBsdWdpbi5zZXJ2ZSgidG9vbC9lY2hvIikKICAgIGRlZiBlY2hvKHBheWxvYWQ6IGRpY3Rbc3RyLCBBbnldIHwgTm9uZSA9IE5vbmUpOgogICAgICAgICIiIlNtYWxsIHF1ZXJ5IGV4YW1wbGUgY2FsbGFibGUgZnJvbSB0aGUgVUkgd2l0aCByYi5hY3Rpb24oInRvb2wvZWNobyIsIC4uLikuIiIiCiAgICAgICAgcmV0dXJuIHsiZWNobyI6IHBheWxvYWQsICJwbHVnaW4iOiBQTFVHSU5fTkFNRX0KCgpkZWYgbW92ZV9qX2V4YW1wbGUoKToKICAgICIiIgogICAgRXhhbXBsZTogdXNlIG90aGVyIHJvYm90IFNES3MgZnJvbSB0aGUgc2FtZSBiYWNrZW5kLgoKICAgIFRoaXMgZnVuY3Rpb24gaXMgbm90IGNhbGxlZCBhdXRvbWF0aWNhbGx5LiBBZGQgc2FmZXR5IGNoZWNrcyBhbmQgY2FsbCBpdAogICAgZnJvbSB5b3VyIG93biBoYW5kbGVyIHdoZW4gdGhlIHJvYm90IGlzIHJlYWR5LgogICAgIiIiCiAgICByZXR1cm4gbWFuaXB1bGF0ZS5tb3ZlLmNhbGxfbW92ZV9qKAogICAgICAgIHJvYm90X21vZGVsPSJDNTAwOTIwIiwKICAgICAgICB0YXJnZXQ9ewogICAgICAgICAgICAidGFyX3ZhbHVlcyI6IFswLCAwLCAwLCAwLCAwLCAwXSwKICAgICAgICAgICAgInRhcl9mcmFtZSI6IDAsCiAgICAgICAgICAgICJ0YXJfdW5pdCI6IDAsCiAgICAgICAgfSwKICAgICkKCgphc3luYyBkZWYgbWFpbigpOgogICAgcm9ib3RfaG9zdCA9IG9zLmdldGVudigiTVVTQ0FUX1JPQk9UX0hPU1QiKQogICAgcm9ib3RfdG9rZW4gPSBvcy5nZXRlbnYoIk1VU0NBVF9ST0JPVF9UT0tFTiIpCgogICAgaWYgcm9ib3RfaG9zdCBhbmQgcm9ib3RfdG9rZW46CiAgICAgICAgIyBSZW1vdGUgZGV2OiBjb25uZWN0IHRvIHRoZSByb2JvdCBiZWZvcmUgcmVnaXN0ZXJpbmcgYW55IGhhbmRsZXJzLgogICAgICAgICMgY29ubmVjdCgpIGNsb3NlcyBhbmQgcmVvcGVucyB0aGUgWmVub2ggc2Vzc2lvbiwgc28gaGFuZGxlcnMgcmVnaXN0ZXJlZAogICAgICAgICMgYmVmb3JlIHRoaXMgY2FsbCB3b3VsZCBiZSBsb3N0LgogICAgICAgIGF3YWl0IG1hbmlwdWxhdGUuY29ubmVjdCh0b2tlbj1yb2JvdF90b2tlbiwgaG9zdD1yb2JvdF9ob3N0KQoKICAgIHJlZ2lzdGVyX2hhbmRsZXJzKCkKCiAgICBwbHVnaW4ucHVibGlzaCgic3RhdGUiLCB7InJlYWR5IjogVHJ1ZSwgInBsdWdpbiI6IFBMVUdJTl9OQU1FfSkKICAgIHByaW50KGYiW3tQTFVHSU5fTkFNRX1dIGJhY2tlbmQgcmVhZHkiKQoKICAgIHRyeToKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBhd2FpdCBhc3luY2lvLnNsZWVwKDEpCiAgICBleGNlcHQgKEtleWJvYXJkSW50ZXJydXB0LCBhc3luY2lvLkNhbmNlbGxlZEVycm9yKToKICAgICAgICBwYXNzCiAgICBmaW5hbGx5OgogICAgICAgIGlmIHJvYm90X2hvc3QgYW5kIHJvYm90X3Rva2VuOgogICAgICAgICAgICBhd2FpdCBtYW5pcHVsYXRlLmRpc2Nvbm5lY3QoKQogICAgICAgIHByaW50KGYiW3tQTFVHSU5fTkFNRX1dIHN0b3BwZWQiKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0cnk6CiAgICAgICAgYXN5bmNpby5ydW4obWFpbigpKQogICAgZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OgogICAgICAgIHBhc3MK","common/requirements.txt":"cmFpbmJvdy1yYi1zZGs9PTAuMC45LmRldjQzCnJhaW5ib3ctcmItZmxhdC1idWZmZXJzPT0wLjAuOS5kZXY0MwpyYWluYm93LXJiLXplbm9oPT0wLjAuOS5kZXY0MwpyZXF1ZXN0cz09Mi4zNC4yCg==","common/tsconfig.json":"ewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAidGFyZ2V0IjogIkVTTmV4dCIsCiAgICAibW9kdWxlIjogIkVTTmV4dCIsCiAgICAibW9kdWxlUmVzb2x1dGlvbiI6ICJidW5kbGVyIiwKICAgICJqc3giOiAicmVhY3QtanN4IiwKICAgICJzdHJpY3QiOiB0cnVlLAogICAgInNraXBMaWJDaGVjayI6IHRydWUsCiAgICAibm9FbWl0IjogdHJ1ZSwKICAgICJsaWIiOiBbIkRPTSIsICJET00uSXRlcmFibGUiLCAiRVNOZXh0Il0KICB9LAogICJpbmNsdWRlIjogWyJ1aSJdCn0K","common/ui/content.tsx":"aW1wb3J0IHsgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7CiAgUkJDaGVja0JveCwKICBSQkxhYmVsQnV0dG9uLAogIFJCUmFkaW9Cb3gsCiAgUkJTZWxlY3RCb3gsCiAgUkJTbGlkZXIsCiAgUkJTd2l0Y2gsCiAgUkJUZXh0QXJlYSwKICBSQlRleHRGaWVsZCwKICBSQlRleHRJbnB1dCwKICBPcHRpb24KfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwppbXBvcnQgeyB1c2VSYiB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9zZGsiOwoKdHlwZSBSdW5Nb2RlID0gImluc3BlY3QiIHwgImFzc2lzdCIgfCAiYXV0byI7Cgpjb25zdCBNT0RFX09QVElPTlM6IEFycmF5PHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IFJ1bk1vZGUgfT4gPSBbCiAgeyBsYWJlbDogIkluc3BlY3QiLCB2YWx1ZTogImluc3BlY3QiIH0sCiAgeyBsYWJlbDogIkFzc2lzdCIsIHZhbHVlOiAiYXNzaXN0IiB9LAogIHsgbGFiZWw6ICJBdXRvIiwgdmFsdWU6ICJhdXRvIiB9LApdOwoKY29uc3QgVEFTS19PUFRJT05TID0gWwogIHsgbGFiZWw6ICJQdWJsaXNoIHN0YXR1cyIsIHZhbHVlOiAicHVibGlzaCIgfSwKICB7IGxhYmVsOiAiUnVuIGdyaXAgYWN0aW9uIiwgdmFsdWU6ICJncmlwIiB9LAogIHsgbGFiZWw6ICJTYXZlIHNuYXBzaG90IiwgdmFsdWU6ICJzbmFwc2hvdCIgfSwKXTsKCi8vIEV4cG9ydCB5b3VyIFVJIGFzIHRoZSBkZWZhdWx0LiBUaGUgaG9zdCBtb3VudHMgaXQgKGRldjogd2l0aCBITVIpLgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt0YXJnZXROYW1lLCBzZXRUYXJnZXROYW1lXSA9IHVzZVN0YXRlKCJkZW1vX3RhcmdldCIpOwogIGNvbnN0IFtncmlwVHlwZSwgc2V0R3JpcFR5cGVdID0gdXNlU3RhdGU8c3RyaW5nPigpOwogIGNvbnN0IFtncmlwV2lkdGgsIHNldEdyaXBXaWR0aF0gPSB1c2VTdGF0ZSgyNCk7CiAgY29uc3QgW3NwZWVkLCBzZXRTcGVlZF0gPSB1c2VTdGF0ZSg0NSk7CiAgY29uc3QgW21vZGUsIHNldE1vZGVdID0gdXNlU3RhdGU8UnVuTW9kZT4oImFzc2lzdCIpOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwogIGNvbnN0IFt0YXNrcywgc2V0VGFza3NdID0gdXNlU3RhdGU8QXJyYXk8c3RyaW5nPj4oWyJwdWJsaXNoIiwgImdyaXAiXSk7CiAgY29uc3QgW21lbW8sIHNldE1lbW9dID0gdXNlU3RhdGUoIlVzZSB0aGlzIGFyZWEgZm9yIG9wZXJhdG9yIG5vdGVzLiIpOwoKICBjb25zdCBwYXlsb2FkID0gdXNlTWVtbygKICAgICgpID0+ICh7CiAgICAgIHRhcmdldE5hbWUsCiAgICAgIGdyaXBXaWR0aCwKICAgICAgc3BlZWQsCiAgICAgIG1vZGUsCiAgICAgIGVuYWJsZWQsCiAgICAgIHRhc2tzLAogICAgICBtZW1vLAogICAgfSksCiAgICBbdGFyZ2V0TmFtZSwgZ3JpcFdpZHRoLCBzcGVlZCwgbW9kZSwgZW5hYmxlZCwgdGFza3MsIG1lbW9dLAogICk7CgogIGNvbnN0IHNob3dSZXF1ZXN0RXJyb3IgPSAoZXJyb3I6IHVua25vd24pID0+IHsKICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICJSZXF1ZXN0IGZhaWxlZCI7CiAgICByYi50b2FzdCh7IHR5cGU6ICJkYW5nZXIiLCBtZXNzYWdlIH0pOwogIH07CgogIGNvbnN0IHJ1bkFjdGlvbiA9IGFzeW5jICgpID0+IHsKICAgIHRyeSB7CiAgICAgIGF3YWl0IHJiLmFjdGlvbigiZ3JpcCIsIHBheWxvYWQpOwogICAgICByYi50b2FzdCh7IHR5cGU6ICJzdWNjZXNzIiwgbWVzc2FnZTogYFNlbnQgJHt0YXJnZXROYW1lfWAgfSk7CiAgICB9IGNhdGNoIChlcnJvcikgewogICAgICBzaG93UmVxdWVzdEVycm9yKGVycm9yKTsKICAgIH0KICB9OwoKICBjb25zdCBwdWJsaXNoUHJldmlldyA9IGFzeW5jICgpID0+IHsKICAgIHRyeSB7CiAgICAgIGNvbnN0IGlzQ29uZmlybSA9IGF3YWl0IHJiLmNvbmZpcm0oewogICAgICAgIG1lc3NhZ2U6ICJBcmUgeW91IHN1cmUgcHVibGlzaD8iLAogICAgICAgIGJ1dHRvblRleHQ6IHsgeWVzOiAiY29uZmlybSIsIG5vOiAiY2FuY2VsIiB9LAogICAgICB9KTsKCiAgICAgIGlmIChpc0NvbmZpcm0pIHsKICAgICAgICBhd2FpdCByYi5wdWIoImV2ZW50IiwgcGF5bG9hZCk7CiAgICAgIH0KICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIHNob3dSZXF1ZXN0RXJyb3IoZXJyb3IpOwogICAgfQogIH07CgogIHJldHVybiAoCiAgICA8ZGl2IGNsYXNzTmFtZT0ibWF4LWgtWzcwdmhdIHctWzQyMHB4XSBwLTQgbWF4LXctZnVsbCBvdmVyZmxvdy15LWF1dG8gYmctYmctZWxldmF0ZWQgdGV4dC1mZy1kZWZhdWx0Ij4KICAgICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTUiPgogICAgICAgIDxoZWFkZXI+CiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIGdhcC0xMiI+CiAgICAgICAgICAgIDxkaXY+CiAgICAgICAgICAgICAgPGgyIGNsYXNzTmFtZT0idHlwby1oZWFkaW5nLXhzLXNlbWlib2xkIj5EZW1vIENvbnRyb2w8L2gyPgogICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0idHlwby1ib2R5LXhzMi1ub3JtYWwgdGV4dC1mZy1zdWJ0bGUiPgogICAgICAgICAgICAgICAgSW5wdXQgcGF0dGVybnMgZm9yIE11c2NhdCBwbHVnaW4gVUlzCiAgICAgICAgICAgICAgPC9wPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgPFJCU3dpdGNoCiAgICAgICAgICAgICAgY2hlY2tlZD17ZW5hYmxlZH0KICAgICAgICAgICAgICBvbkNoZWNrZWRDaGFuZ2U9eyhuZXh0OiBib29sZWFuKSA9PiB7CiAgICAgICAgICAgICAgICBzZXRFbmFibGVkKG5leHQpOwogICAgICAgICAgICAgICAgcmIudG9hc3Qoe21lc3NhZ2U6IG5leHQgPyAiUGx1Z2luIGVuYWJsZWQiIDogIlBsdWdpbiBwYXVzZWQifSk7CiAgICAgICAgICAgICAgfX0KICAgICAgICAgICAgLz4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvaGVhZGVyPgoKICAgICAgICA8c2VjdGlvbiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICAgICAgPFJCVGV4dEZpZWxkCiAgICAgICAgICAgIGxhYmVsPSJUYXJnZXQgbmFtZSIKICAgICAgICAgICAgcmVxdWlyZWQKICAgICAgICAgICAgaGVscGVyVGV4dD0iVXNlZCBhcyB0aGUgYmFja2VuZCBhY3Rpb24gdGFyZ2V0LiIKICAgICAgICAgID4KICAgICAgICAgICAgPFJCVGV4dElucHV0CiAgICAgICAgICAgICAgbmFtZT0idGFyZ2V0TmFtZSIKICAgICAgICAgICAgICB2YWx1ZT17dGFyZ2V0TmFtZX0KICAgICAgICAgICAgICBwbGFjZWhvbGRlcj0idGFyZ2V0IGlkIgogICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PiBzZXRUYXJnZXROYW1lKFN0cmluZyh2YWx1ZSkpfQogICAgICAgICAgICAvPgogICAgICAgICAgPC9SQlRleHRGaWVsZD4KCiAgICAgICAgICA8UkJUZXh0RmllbGQgbGFiZWw9IlNlbGVjdCBHcmlwIj4KICAgICAgICAgICAgPFJCU2VsZWN0Qm94ICBjbGFzc05hbWU9InctZnVsbCIgdmFsdWU9e2dyaXBUeXBlfSBoYW5kbGVDaGFuZ2U9e3NldEdyaXBUeXBlfT4KICAgICAgICAgICAgICA8T3B0aW9uIHZhbHVlPSJBIj5BIEdyaXA8L09wdGlvbj4KICAgICAgICAgICAgICA8T3B0aW9uIHZhbHVlPSJCIj5CIEdyaXA8L09wdGlvbj4KICAgICAgICAgICAgPC9SQlNlbGVjdEJveD4KICAgICAgICAgIDwvUkJUZXh0RmllbGQ+CgogICAgICAgICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZ2FwLTQiPgogICAgICAgICAgICA8UkJUZXh0RmllbGQgY2xhc3NOYW1lPSJmbGV4LTEiIGxhYmVsPSJHcmlwIHdpZHRoIiBoZWxwZXJUZXh0PSIwLTEwMCBtbSI+CiAgICAgICAgICAgICAgPFJCVGV4dElucHV0CiAgICAgICAgICAgICAgICBjbGFzc05hbWU9InctZnVsbCIKICAgICAgICAgICAgICAgIG5hbWU9ImdyaXBXaWR0aCIKICAgICAgICAgICAgICAgIHR5cGU9Im51bWJlciIKICAgICAgICAgICAgICAgIHZhbHVlPXtncmlwV2lkdGh9CiAgICAgICAgICAgICAgICB2YWxpZGF0ZT17KHZhbHVlOiBudW1iZXIpID0+CiAgICAgICAgICAgICAgICAgIE1hdGgubWF4KDAsIE1hdGgubWluKDEwMCwgTnVtYmVyKHZhbHVlKSB8fCAwKSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PiBzZXRHcmlwV2lkdGgoTnVtYmVyKHZhbHVlKSB8fCAwKX0KICAgICAgICAgICAgICAvPgogICAgICAgICAgICA8L1JCVGV4dEZpZWxkPgoKICAgICAgICAgICAgPFJCVGV4dEZpZWxkIGNsYXNzTmFtZT0iZmxleC0xIiBsYWJlbD0iU3BlZWQiIGhlbHBlclRleHQ9e2Ake3NwZWVkfSVgfT4KICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBpdGVtcy1jZW50ZXIgcHgtMiI+CiAgICAgICAgICAgICAgICA8UkJTbGlkZXIKICAgICAgICAgICAgICAgICAgdmFsdWU9e1tzcGVlZF19CiAgICAgICAgICAgICAgICAgIG1pbj17MH0KICAgICAgICAgICAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgICAgICAgICAgIHN0ZXA9ezV9CiAgICAgICAgICAgICAgICAgIG9uVmFsdWVDaGFuZ2U9eyh2YWx1ZXM6IG51bWJlcltdKSA9PgogICAgICAgICAgICAgICAgICAgIHNldFNwZWVkKHZhbHVlc1swXSA/PyAwKQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvPgogICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9zZWN0aW9uPgoKICAgICAgICA8c2VjdGlvbiBjbGFzc05hbWU9Im1iLTQiPgogICAgICAgICAgPFJCVGV4dEZpZWxkIGxhYmVsPSJSdW4gbW9kZSI+CiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSJmbGV4IGp1c3RpZnktYmV0d2VlbiBib3JkZXItMSBib3JkZXItYm9yZGVyLXN1YnRsZSByb3VuZGVkLXNtIHAtMiI+CiAgICAgICAgICAgIHtNT0RFX09QVElPTlMubWFwKChpdGVtKSA9PiAoCiAgICAgICAgICAgICAgPFJCUmFkaW9Cb3gKICAgICAgICAgICAgICAgIGtleT17aXRlbS52YWx1ZX0KICAgICAgICAgICAgICAgIG5hbWU9Im1vZGUiCiAgICAgICAgICAgICAgICBjaGVja1ZhbHVlPXtpdGVtLnZhbHVlfQogICAgICAgICAgICAgICAgdmFsdWU9e21vZGV9CiAgICAgICAgICAgICAgICBoYW5kbGVDaGFuZ2U9eyh2YWx1ZSkgPT4gc2V0TW9kZSh2YWx1ZSBhcyBSdW5Nb2RlKX0KICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICB7aXRlbS5sYWJlbH0KICAgICAgICAgICAgICA8L1JCUmFkaW9Cb3g+CiAgICAgICAgICAgICkpfQogICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgIDwvc2VjdGlvbj4KCiAgICAgICAgPHNlY3Rpb24gY2xhc3NOYW1lPSJtYi00Ij4KICAgICAgICAgIDxSQlRleHRGaWVsZCBsYWJlbD0iVGFza3MiPgogICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBqdXN0aWZ5LWJldHdlZW4gYm9yZGVyLTEgYm9yZGVyLWJvcmRlci1zdWJ0bGUgcm91bmRlZC1zbSBwLTIiPgogICAgICAgICAgICAgIHtUQVNLX09QVElPTlMubWFwKChpdGVtKSA9PiAoCiAgICAgICAgICAgICAgICA8UkJDaGVja0JveAogICAgICAgICAgICAgICAgICBrZXk9e2l0ZW0udmFsdWV9CiAgICAgICAgICAgICAgICAgIG5hbWU9InRhc2tzIgogICAgICAgICAgICAgICAgICBjaGVja1ZhbHVlPXtpdGVtLnZhbHVlfQogICAgICAgICAgICAgICAgICB2YWx1ZT17dGFza3N9CiAgICAgICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PgogICAgICAgICAgICAgICAgICAgIHNldFRhc2tzKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUubWFwKFN0cmluZykgOiBbXSkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICB7aXRlbS5sYWJlbH0KICAgICAgICAgICAgICAgIDwvUkJDaGVja0JveD4KICAgICAgICAgICAgICApKX0KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgICAgCiAgICAgICAgPC9zZWN0aW9uPgoKICAgICAgICA8UkJUZXh0RmllbGQgbGFiZWw9Ik1lbW8iPgogICAgICAgICAgPFJCVGV4dEFyZWEKICAgICAgICAgICAgbmFtZT0ibWVtbyIKICAgICAgICAgICAgdmFsdWU9e21lbW99CiAgICAgICAgICAgIG1heExlbmd0aD17MTIwfQogICAgICAgICAgICByb3dzPXs0fQogICAgICAgICAgICBoYW5kbGVDaGFuZ2U9e3NldE1lbW99CiAgICAgICAgICAvPgogICAgICAgIDwvUkJUZXh0RmllbGQ+CgogICAgICAgIDxmb290ZXIgY2xhc3NOYW1lPSJncmlkIGdyaWQtY29scy0yIGdhcC04IHB0LTQiPgogICAgICAgICAgPFJCTGFiZWxCdXR0b24gdmFyaWFudD0ib3V0bGluZWQiIG9uQ2xpY2s9e3B1Ymxpc2hQcmV2aWV3fT4KICAgICAgICAgICAgUHVibGlzaAogICAgICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgICAgICAgPFJCTGFiZWxCdXR0b24gb25DbGljaz17cnVuQWN0aW9ufSBkaXNhYmxlZD17IWVuYWJsZWR9PgogICAgICAgICAgICBSdW4gQWN0aW9uCiAgICAgICAgICA8L1JCTGFiZWxCdXR0b24+CiAgICAgICAgPC9mb290ZXI+CiAgICAgIDwvZGl2PgogICAgPC9kaXY+CiAgKTsKfQo=","common/ui/style.css":"QGxheWVyIHRoZW1lLCB1dGlsaXRpZXM7CgpAaW1wb3J0ICJ0YWlsd2luZGNzcy90aGVtZS5jc3MiIGxheWVyKHRoZW1lKTsKQGltcG9ydCAidGFpbHdpbmRjc3MvdXRpbGl0aWVzLmNzcyIgbGF5ZXIodXRpbGl0aWVzKTsKCkBzb3VyY2UgIi4vKiovKi57dHMsdHN4fSI7Cg==","common/vite.config.ts":"aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKLy8gVGhlIG11c2NhdCgpIHByZXNldCB3aXJlcyByZWFjdC1yZWZyZXNoLCB1aS8gZW50cnkgZGlzY292ZXJ5LCBhbmQgbWFya3MgdGhlCi8vIGhvc3QtcHJvdmlkZWQgcnVudGltZSAocGx1Z2luLXVpLCByZWFjdCkgYXMgZXh0ZXJuYWwuIEFkZCB5b3VyIG93biBwbHVnaW5zIG9yCi8vIG92ZXJyaWRlcyBoZXJlIGFzIG5lZWRlZC4KZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsK","cpp/cpp/CMakeLists.txt":"Y21ha2VfbWluaW11bV9yZXF1aXJlZChWRVJTSU9OIDMuMTYpCnByb2plY3QoX19QTFVHSU5fU0xVR19fIENYWCkKCnNldChDTUFLRV9DWFhfU1RBTkRBUkQgMTcpCnNldChDTUFLRV9DWFhfU1RBTkRBUkRfUkVRVUlSRUQgT04pCgojIFRoZSBleGVjdXRhYmxlIG5hbWUgbXVzdCBtYXRjaCBydW50aW1lLmVudHJ5IGluIG1hbmlmZXN0Lmpzb24uCmFkZF9leGVjdXRhYmxlKF9fUExVR0lOX1NMVUdfXyBtYWluLmNwcCkKCiMgVE9ETyhjcHAtc2RrKTogbGluayB0aGUgcmFpbmJvdyBjcHAgU0RLIGR5bmFtaWNhbGx5ICh0aGUgcm9ib3QgcHJvdmlkZXMgdGhlCiMgLnNvIGF0IHJ1bnRpbWUg4oCUIGRvIE5PVCBidW5kbGUvc3RhdGljLWxpbmsgaXQpLiBPbmNlIHRoZSBTREsgc2hpcHMgYW4gYXB0CiMgcGFja2FnZSB3aXRoIENNYWtlIGNvbmZpZywgZW5hYmxlOgojICAgZmluZF9wYWNrYWdlKHJhaW5ib3dfY3BwX3NkayBSRVFVSVJFRCkKIyAgIHRhcmdldF9saW5rX2xpYnJhcmllcyhfX1BMVUdJTl9TTFVHX18gUFJJVkFURSByYWluYm93OjpjcHBfc2RrKQo=","cpp/cpp/main.cpp":"Ly8gX19QTFVHSU5fTkFNRV9fIOKAlCBDKysgcGx1Z2luIGJhY2sgZW5kLgovLwovLyBUaGUgQysrIHBsdWdpbiBTREsgaXMgbm90IGF2YWlsYWJsZSB5ZXQsIHNvIHRoaXMgaXMgYSBidWlsZC9ydW4gc2tlbGV0b24uCi8vIE9uY2UgdGhlIFNESyBsYW5kcywgY29ubmVjdCB0byB0aGUgcGx1Z2luIGdhdGV3YXkgaGVyZSAodGhlIGhvc3QgZXhwb3NlcyBpdAovLyBhdCB0aGUgUkJfUExVR0lOX0dBVEVXQVkgLyBSQl9QTFVHSU5fSUQgZW52aXJvbm1lbnQgdmFyaWFibGVzKSBhbmQgd2lyZSB1cAovLyBwdWIgLyBzdWIgLyBzZXJ2ZSwgbWlycm9yaW5nIHRoZSBQeXRob24gcmFpbmJvdy5yYl9zZGsuUkJQbHVnaW5DYWxsIEFQSS4KCiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx0aHJlYWQ+CgppbnQgbWFpbigpIHsKICBjb25zdCBjaGFyKiBwbHVnaW5faWQgPSBzdGQ6OmdldGVudigiUkJfUExVR0lOX0lEIik7CiAgc3RkOjpjb3V0IDw8ICJbX19QTFVHSU5fTkFNRV9fXSBiYWNrZW5kIHJlYWR5IgogICAgICAgICAgICA8PCAocGx1Z2luX2lkID8gc3RkOjpzdHJpbmcoIiAoaWQ9IikgKyBwbHVnaW5faWQgKyAiKSIgOiAiIikKICAgICAgICAgICAgPDwgc3RkOjplbmRsOwoKICAvLyBUT0RPOiBjb25uZWN0IHRvIHRoZSBwbHVnaW4gZ2F0ZXdheSBhbmQgcmVnaXN0ZXIgaGFuZGxlcnMgb25jZSB0aGUKICAvLyAgICAgICBDKysgU0RLIGlzIGF2YWlsYWJsZS4gRm9yIG5vdywganVzdCBrZWVwIHRoZSBwcm9jZXNzIGFsaXZlLgogIHdoaWxlICh0cnVlKSB7CiAgICBzdGQ6OnRoaXNfdGhyZWFkOjpzbGVlcF9mb3Ioc3RkOjpjaHJvbm86OnNlY29uZHMoMSkpOwogIH0KICByZXR1cm4gMDsKfQo=","ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/__init__.py":"","ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/node.py":"aW1wb3J0IHJjbHB5CmZyb20gcmNscHkubm9kZSBpbXBvcnQgTm9kZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQk1hbmlwdWxhdGVTREsgICMgUHlQSTogcmFpbmJvdy1yYi1zZGsKCgpzZGsgPSBSQk1hbmlwdWxhdGVTREsoKQoKCmNsYXNzIF9fUExVR0lOX0NMQVNTX19Ob2RlKE5vZGUpOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHN1cGVyKCkuX19pbml0X18oIl9fUExVR0lOX1NMVUdfX19ub2RlIikKICAgICAgICBzZWxmLmdldF9sb2dnZXIoKS5pbmZvKCJfX1BMVUdJTl9OQU1FX18gbm9kZSBzdGFydGVkIikKICAgICAgICAjIHNkayBpcyBhdmFpbGFibGUgaGVyZSDigJQgdXNlIGl0IGFsb25nc2lkZSBST1MyIHRvcGljcyBhcyBuZWVkZWQKCgpkZWYgbWFpbihhcmdzPU5vbmUpOgogICAgcmNscHkuaW5pdChhcmdzPWFyZ3MpCiAgICBub2RlID0gX19QTFVHSU5fQ0xBU1NfX05vZGUoKQogICAgcmNscHkuc3Bpbihub2RlKQogICAgbm9kZS5kZXN0cm95X25vZGUoKQogICAgcmNscHkuc2h1dGRvd24oKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBtYWluKCkK","ros2/ros2_ws/src/__PLUGIN_SLUG__/package.xml":"PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxwYWNrYWdlIGZvcm1hdD0iMyI+CiAgPG5hbWU+X19QTFVHSU5fU0xVR19fPC9uYW1lPgogIDx2ZXJzaW9uPjAuMC4xPC92ZXJzaW9uPgogIDxkZXNjcmlwdGlvbj5fX1BMVUdJTl9OQU1FX18gUk9TMiBub2RlPC9kZXNjcmlwdGlvbj4KICA8bWFpbnRhaW5lciBlbWFpbD0idG9kb0BleGFtcGxlLmNvbSI+bWFpbnRhaW5lcjwvbWFpbnRhaW5lcj4KICA8bGljZW5zZT5Qcm9wcmlldGFyeTwvbGljZW5zZT4KICA8ZGVwZW5kPnJjbHB5PC9kZXBlbmQ+CiAgPGV4cG9ydD48YnVpbGRfdHlwZT5hbWVudF9weXRob248L2J1aWxkX3R5cGU+PC9leHBvcnQ+CjwvcGFja2FnZT4K","ros2/ros2_ws/src/__PLUGIN_SLUG__/resource/__PLUGIN_SLUG__":"","ros2/ros2_ws/src/__PLUGIN_SLUG__/setup.py":"ZnJvbSBzZXR1cHRvb2xzIGltcG9ydCBzZXR1cAoKcGFja2FnZV9uYW1lID0gIl9fUExVR0lOX1NMVUdfXyIKCnNldHVwKAogICAgbmFtZT1wYWNrYWdlX25hbWUsCiAgICB2ZXJzaW9uPSIwLjAuMSIsCiAgICBwYWNrYWdlcz1bcGFja2FnZV9uYW1lXSwKICAgIGRhdGFfZmlsZXM9WwogICAgICAgICgic2hhcmUvYW1lbnRfaW5kZXgvcmVzb3VyY2VfaW5kZXgvcGFja2FnZXMiLCBbInJlc291cmNlLyIgKyBwYWNrYWdlX25hbWVdKSwKICAgICAgICAoInNoYXJlLyIgKyBwYWNrYWdlX25hbWUsIFsicGFja2FnZS54bWwiXSksCiAgICBdLAogICAgaW5zdGFsbF9yZXF1aXJlcz1bInNldHVwdG9vbHMiXSwKICAgIHppcF9zYWZlPVRydWUsCiAgICBlbnRyeV9wb2ludHM9ewogICAgICAgICJjb25zb2xlX3NjcmlwdHMiOiBbIl9fUExVR0lOX1NMVUdfX19ub2RlID0gX19QTFVHSU5fU0xVR19fLm5vZGU6bWFpbiJdLAogICAgfSwKKQo=","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/CMakeLists.txt":"Y21ha2VfbWluaW11bV9yZXF1aXJlZChWRVJTSU9OIDMuMTYpCnByb2plY3QoX19QTFVHSU5fU0xVR19fKQoKaWYoTk9UIENNQUtFX0NYWF9TVEFOREFSRCkKICBzZXQoQ01BS0VfQ1hYX1NUQU5EQVJEIDE3KQplbmRpZigpCgpmaW5kX3BhY2thZ2UoYW1lbnRfY21ha2UgUkVRVUlSRUQpCmZpbmRfcGFja2FnZShyY2xjcHAgUkVRVUlSRUQpCgphZGRfZXhlY3V0YWJsZShfX1BMVUdJTl9TTFVHX19fbm9kZSBzcmMvbm9kZS5jcHApCmFtZW50X3RhcmdldF9kZXBlbmRlbmNpZXMoX19QTFVHSU5fU0xVR19fX25vZGUgcmNsY3BwKQoKaW5zdGFsbChUQVJHRVRTIF9fUExVR0lOX1NMVUdfX19ub2RlCiAgREVTVElOQVRJT04gbGliLyR7UFJPSkVDVF9OQU1FfSkKCmFtZW50X3BhY2thZ2UoKQo=","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/package.xml":"PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxwYWNrYWdlIGZvcm1hdD0iMyI+CiAgPG5hbWU+X19QTFVHSU5fU0xVR19fPC9uYW1lPgogIDx2ZXJzaW9uPjAuMC4xPC92ZXJzaW9uPgogIDxkZXNjcmlwdGlvbj5fX1BMVUdJTl9OQU1FX18gUk9TMiBub2RlIChyY2xjcHApPC9kZXNjcmlwdGlvbj4KICA8bWFpbnRhaW5lciBlbWFpbD0idG9kb0BleGFtcGxlLmNvbSI+bWFpbnRhaW5lcjwvbWFpbnRhaW5lcj4KICA8bGljZW5zZT5Qcm9wcmlldGFyeTwvbGljZW5zZT4KICA8YnVpbGR0b29sX2RlcGVuZD5hbWVudF9jbWFrZTwvYnVpbGR0b29sX2RlcGVuZD4KICA8ZGVwZW5kPnJjbGNwcDwvZGVwZW5kPgogIDxleHBvcnQ+PGJ1aWxkX3R5cGU+YW1lbnRfY21ha2U8L2J1aWxkX3R5cGU+PC9leHBvcnQ+CjwvcGFja2FnZT4K","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/src/node.cpp":"Ly8gX19QTFVHSU5fTkFNRV9fIOKAlCBST1MyIG5vZGUgKHJjbGNwcCkuCi8vCi8vIFRoZSBub2RlIGlzIGxhdW5jaGVkIHdpdGggYC0tcm9zLWFyZ3MgLXIgX19uczo9L3tzbHVnfWAgYXV0b21hdGljYWxseSBieQovLyBkZXY6YmFjay4gUk9TMiB0b3BpY3MgYXJlIGJyaWRnZWQgdG8gdGhlIHBsdWdpbiBjb21tdW5pY2F0aW9uIGxheWVyLCBzbyBhCi8vIHBsYWluIHJjbGNwcCBub2RlIGlzIGFsbCB5b3UgbmVlZCDigJQgcmVsYXRpdmUgdG9waWMgbmFtZXMgZ2V0IHRoZSBuYW1lc3BhY2UKLy8gcHJlZml4IGFwcGxpZWQgYXV0b21hdGljYWxseS4KI2luY2x1ZGUgInJjbGNwcC9yY2xjcHAuaHBwIgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUgOiBwdWJsaWMgcmNsY3BwOjpOb2RlIHsKcHVibGljOgogIF9fUExVR0lOX0NMQVNTX19Ob2RlKCkgOiBOb2RlKCJfX1BMVUdJTl9TTFVHX19fbm9kZSIpIHsKICAgIFJDTENQUF9JTkZPKHRoaXMtPmdldF9sb2dnZXIoKSwgIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKTsKICAgIC8vIGNyZWF0ZSBwdWJsaXNoZXJzIC8gc3Vic2NyaWJlcnMgLyBzZXJ2aWNlcyBoZXJlCiAgfQp9OwoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgcmNsY3BwOjppbml0KGFyZ2MsIGFyZ3YpOwogIHJjbGNwcDo6c3BpbihzdGQ6Om1ha2Vfc2hhcmVkPF9fUExVR0lOX0NMQVNTX19Ob2RlPigpKTsKICByY2xjcHA6OnNodXRkb3duKCk7CiAgcmV0dXJuIDA7Cn0K","docker/Dockerfile.bridge":"IyBTb2NrZXQuSU8gYnJpZGdlIGNvbnRhaW5lciDigJQgdGhlIGZyb250ZW5kIChwcmV2aWV3LWhvc3QpIGFuZCB0aGUgYmFja2VuZAojIGNvbnRhaW5lciByZW5kZXp2b3VzIGhlcmUgZHVyaW5nIGBtdXNjYXQtcGsgZGV2YC4KIyAgIC0gZnJvbnRlbmQgKGhvc3QpICDihpIgcHVibGlzaGVkIHBvcnQgbG9jYWxob3N0OjEwMDAwCiMgICAtIGJhY2tlbmQgY29udGFpbmVyIOKGkiBzaGFyZXMgdGhpcyBjb250YWluZXIncyBuZXRucyAoLS1uZXR3b3JrIGNvbnRhaW5lcjopLAojICAgICAgICAgICAgICAgICAgICAgICAgIHNvIGl0IHJlYWNoZXMgdGhlIGJyaWRnZSBhdCBsb2NhbGhvc3Q6MTAwMDAgdG9vCiMgQnVpbGQgY29udGV4dCBpcyB0aGUgYGNsaS9gIGRpciBzbyBpdCBjYW4gY29weSBzcmMvc29ja2V0QnJpZGdlLm1qcy4KRlJPTSBub2RlOjIwLXNsaW0KTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKV09SS0RJUiAvYnJpZGdlCkNPUFkgZG9ja2VyL2JyaWRnZS1wYWNrYWdlLmpzb24gcGFja2FnZS5qc29uClJVTiBucG0gaW5zdGFsbCAtLW9taXQ9ZGV2IC0tbm8tYXVkaXQgLS1uby1mdW5kCgpDT1BZIHNyYy9zb2NrZXRCcmlkZ2UubWpzIC4vc29ja2V0QnJpZGdlLm1qcwoKRVhQT1NFIDEwMDAwCkNNRCBbIm5vZGUiLCAic29ja2V0QnJpZGdlLm1qcyJdCg==","docker/Dockerfile.cpp":"IyBEZXYvYnVpbGQgY29udGFpbmVyIGZvciB0aGUgcHVyZSBDKysgcGx1Z2luIGJhY2sgZW5kLgojIE1hdGNoZXMgdGhlIE11c2NhdCByb2JvdCBiYWNrZW5kIE9TIChVYnVudHUgMjQuMDQpIHNvIHRoZSBjb21waWxlZCBiaW5hcnkKIyBpcyBBQkktY29tcGF0aWJsZSB3aXRoIHRoZSByb2JvdC4gVXNlZCBieSBgbXVzY2F0LXBrIGRldjpiYWNrYCBhbmQgYGJ1aWxkYAojIOKAlCBOT1Qgc2hpcHBlZCBpbiB0aGUgcGx1Z2luIFpJUC4KRlJPTSB1YnVudHU6MjQuMDQKTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBcCiAgICAgIGJ1aWxkLWVzc2VudGlhbCBcCiAgICAgIGNtYWtlIFwKICAgICYmIHJtIC1yZiAvdmFyL2xpYi9hcHQvbGlzdHMvKgoKIyBUT0RPKGNwcC1zZGspOiBpbnN0YWxsIHRoZSByYWluYm93IGNwcCBTREsgKGRldiBwYWNrYWdlKSBoZXJlLCBwaW5uZWQgdG8gdGhlCiMgcm9ib3QncyB2ZXJzaW9uLCBzbyBwbHVnaW5zIGJ1aWxkL2xpbmsgYWdhaW5zdCB0aGUgc2FtZSBTREsgYXMgcHJvZHVjdGlvbi4KIyBQbGFuOiBhcHQgcGFja2FnZSArIGR5bmFtaWMgbGluayAodGhlIHJvYm90IHByb3ZpZGVzIHRoZSAuc28gYXQgcnVudGltZTsKIyB3ZSBkbyBOT1QgYnVuZGxlIGl0IGludG8gdGhlIHBsdWdpbiBiaW5hcnkpLiBlLmcuOgojICAgUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSByYWluYm93LWNwcC1zZGstZGV2PTxyb2JvdC12ZXJzaW9uPiBcCiMgICAgICAgJiYgcm0gLXJmIC92YXIvbGliL2FwdC9saXN0cy8qCgpXT1JLRElSIC9wbHVnaW4KCkNNRCBbImJhc2giXQo=","docker/Dockerfile.dev":"IyBEZXYtb25seSBjb250YWluZXIgZm9yIHRoZSBST1MyIHBsdWdpbiBiYWNrIGVuZC4KIyBNYXRjaGVzIHRoZSBNdXNjYXQgcm9ib3QgYmFja2VuZDogUk9TMiBKYXp6eSArIFB5dGhvbiAzLjEyIChVYnVudHUgMjQuMDQpLgojIFVzZWQgYnkgYG11c2NhdC1wayBkZXY6YmFja2Ag4oCUIE5PVCBzaGlwcGVkIGluIHRoZSBwbHVnaW4gWklQLgpGUk9NIHJvczpqYXp6eS1yb3MtYmFzZQpMQUJFTCBjb20ucmFpbmJvdy1yb2JvdGljcy5tdXNjYXQtcGs9InRydWUiCgpSVU4gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzIFwKICAgICAgcHl0aG9uMy1waXAgXAogICAgICBweXRob24zLWNvbGNvbi1jb21tb24tZXh0ZW5zaW9ucyBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCldPUktESVIgL3BsdWdpbgoKQ01EIFsiYmFzaCJdCg==","docker/Dockerfile.python":"IyBEZXYvYnVpbGQgY29udGFpbmVyIGZvciB0aGUgUHl0aG9uIHBsdWdpbiBiYWNrIGVuZC4KIyBNYXRjaGVzIHRoZSBNdXNjYXQgcm9ib3QgYmFja2VuZDogVWJ1bnR1IDI0LjA0ICsgUHl0aG9uIDMuMTIuCiMgVXNlZCBieSBgbXVzY2F0LXBrIGRldjpiYWNrYCAoaG90LXJlbG9hZCkgYW5kIGBtdXNjYXQtcGsgYnVpbGRgIChsb2NrICsgd2hlZWwgdmVuZG9yKS4KIyBOT1Qgc2hpcHBlZCBpbiB0aGUgcGx1Z2luIFpJUCDigJQgdGhlIHJvYm90IGluc3RhbGxzIGRlcHMgZnJvbSBkaXN0L3doZWVscy8gb2ZmbGluZS4KRlJPTSB1YnVudHU6MjQuMDQKTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBcCiAgICAgIHB5dGhvbjMgXAogICAgICBweXRob24zLXBpcCBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyogXAogICAgJiYgcGlwMyBpbnN0YWxsIHV2PT0wLjguMTggLS1icmVhay1zeXN0ZW0tcGFja2FnZXMKCiMgVE9ETyhjcHAtc2RrKTogdGhlIFB5dGhvbiBTREsgaXMgYSBweWJpbmQgd3JhcHBlciBvdmVyIHRoZSBjcHAgU0RLLCBzbyB0aGUKIyBjcHAgU0RLIHNoYXJlZCBsaWIgbXVzdCBiZSBwcmVzZW50IGZvciB0aGUgcHl0aG9uIG1vZHVsZSB0byBsb2FkLiBJbnN0YWxsIHRoZQojIHJhaW5ib3cgY3BwIFNESyAoYXB0LCBwaW5uZWQgdG8gdGhlIHJvYm90J3MgdmVyc2lvbikgaGVyZSBvbmNlIGl0IGV4aXN0cy4KCldPUktESVIgL3BsdWdpbgoKQ01EIFsiYmFzaCJdCg==","docker/bridge-package.json":"ewogICJuYW1lIjogIm11c2NhdC1way1icmlkZ2UiLAogICJwcml2YXRlIjogdHJ1ZSwKICAidHlwZSI6ICJtb2R1bGUiLAogICJkZXBlbmRlbmNpZXMiOiB7CiAgICAic29ja2V0LmlvIjogIl40LjguMSIKICB9Cn0K"};
|
|
3
|
+
export const TEMPLATES = {"common/.mcp.json":"ewogICJtY3BTZXJ2ZXJzIjogewogICAgIm11c2NhdCI6IHsKICAgICAgImNvbW1hbmQiOiAibXVzY2F0LXBrIiwKICAgICAgImFyZ3MiOiBbIm1jcCJdCiAgICB9CiAgfQp9Cg==","common/README.md":"IyBfX1BMVUdJTl9OQU1FX18KCkEgTXVzY2F0IHBsdWdpbiBwcm9qZWN0LiBCdWlsZCwgZGV2ZWxvcCwgYW5kIHNoaXAgd2l0aCBgbXVzY2F0LXBrYCBDTEkuCgojIyBRdWljayBzdGFydAoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJIHByZXZpZXcgKyBiYWNrZW5kIHRvZ2V0aGVyCm11c2NhdC1wayBkZXY6dWkgICAgICMgVUkgcHJldmlldyBvbmx5Cm11c2NhdC1wayBkZXY6YmFjayAgICMgYmFja2VuZCBvbmx5IChQeXRob24gd2F0Y2hmaWxlcyAvIFJPUzIgRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkICsgZGlzdHJpYnV0YWJsZSBaSVAKYGBgCgotLS0KCiMjIFByb2plY3Qgc3RydWN0dXJlCgpgYGAKX19QTFVHSU5fRElSX18vCuKUnOKUgCB1aS8K4pSCICAg4pSc4pSAIGNvbnRlbnQudHN4ICAgICAgIyBwbHVnaW4gVUkgZW50cnkgcG9pbnQK4pSCICAg4pSU4pSAIHN0eWxlLmNzcyAgICAgICAgIyBwbHVnaW4gc3R5bGVzIGF1dG8tbG9hZGVkIGJ5IG11c2NhdCgpCuKUnOKUgCBweS8K4pSCICAg4pSU4pSAIG1haW4ucHkgICAgICAgICAgIyBQeXRob24gYmFja2VuZCBlbnRyeSBwb2ludArilJzilIAgYXNzZXRzLwrilIIgICDilJTilIAgaWNvbi5zdmcgICAgICAgICAjIGljb24gcmVmZXJlbmNlZCBmcm9tIG1hbmlmZXN0CuKUnOKUgCBtYW5pZmVzdC5qc29uICAgICAgICAjIG1ldGFkYXRhLCBjb250cmlidXRpb24gcG9pbnRzLCBydW50aW1lIGNvbmZpZwrilJzilIAgUkVBRE1FLm1kICAgICAgICAgICAgIyB0aGlzIGZpbGUgKGNvcGllZCB0byBkaXN0LyBvbiBidWlsZCkK4pSU4pSAIHJlcXVpcmVtZW50cy50eHQgICAgICMgUHl0aG9uIGRlcHMgKGF1dG8tcGlubmVkIHRvIGxhdGVzdCBvbiBidWlsZCkKYGBgCgo+IFJPUzIgcGx1Z2lucyBhZGRpdGlvbmFsbHkgaW5jbHVkZSBhIGByb3MyX3dzL2AgZGlyZWN0b3J5LgoKLS0tCgojIyBGcm9udGVuZCAoYHVpL2NvbnRlbnQudHN4YCkKCiMjIyBKYXZhU2NyaXB0IGRlcGVuZGVuY2llcwoKYG11c2NhdC1wayBidWlsZGAgcnVucyB0aGlzIHBsdWdpbiBwcm9qZWN0J3Mgb3duIFZpdGUgYnVpbGQuIFZpdGUgcmVzb2x2ZXMKaW1wb3J0cyBmcm9tIGluc3RhbGxlZCBgbm9kZV9tb2R1bGVzYDsgaXQgZG9lcyBub3QgY2FyZSB3aGV0aGVyIGEgcGFja2FnZSBpcwpsaXN0ZWQgdW5kZXIgYGRlcGVuZGVuY2llc2Agb3IgYGRldkRlcGVuZGVuY2llc2AsIGJ1dCB0aGUgcGFja2FnZSBtdXN0IGJlCmluc3RhbGxlZC4KCkRvIG5vdCBydW4gYSBwcm9kdWN0aW9uLW9ubHkgaW5zdGFsbCBzdWNoIGFzIGBucG0gaW5zdGFsbCAtLW9taXQ9ZGV2YCBiZWZvcmUKYnVpbGRpbmcgdGhlIHBsdWdpbiBVSSwgYmVjYXVzZSBidWlsZCB0b29scyBsaWtlIGB2aXRlYCwgYHR5cGVzY3JpcHRgLApgdGFpbHdpbmRjc3NgLCBgQHRhaWx3aW5kY3NzL3ZpdGVgLCBgc2Fzc2AsIG9yIGBsZXNzYCBhcmUgdXN1YWxseQpgZGV2RGVwZW5kZW5jaWVzYC4KClRoZSBzY2FmZm9sZCBrZWVwcyB0aGlzIHNwbGl0OgoKfCBwYWNrYWdlIGtpbmQgfCBleGFtcGxlcyB8IHdoeSB8CnwtLS18LS0tfC0tLXwKfCBgZGVwZW5kZW5jaWVzYCB8IGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWlgLCBVSSBsaWJyYXJpZXMgaW1wb3J0ZWQgYnkgcGx1Z2luIHNvdXJjZSB8IEF1dGhvci1mYWNpbmcgQVBJcyB1c2VkIGJ5IGB1aS8qLnRzeGAgfAp8IGBkZXZEZXBlbmRlbmNpZXNgIHwgYHZpdGVgLCBgdHlwZXNjcmlwdGAsIGB0YWlsd2luZGNzc2AsIGBAdGFpbHdpbmRjc3Mvdml0ZWAsIGBzYXNzYCwgYGxlc3NgIHwgQnVpbGQvZGV2IHRvb2xzIG5lZWRlZCBiZWZvcmUgYGRpc3QvKi5qc2AgaXMgcHJvZHVjZWQgfAoKVGhlIGJ1aWx0IHBsdWdpbiBaSVAgZG9lcyBub3QgaW5jbHVkZSBgcGFja2FnZS5qc29uYCBvciBgbm9kZV9tb2R1bGVzYC4gRm9yCnByb2R1Y3Rpb24sIE11c2NhdCBwcm92aWRlcyBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpYCwgUmVhY3QsIGFuZCBSZWFjdERPTQp0aHJvdWdoIHRoZSBob3N0IGltcG9ydCBtYXA7IHBsdWdpbiBVSSBidWlsZCBvdXRwdXQgaW1wb3J0cyB0aG9zZSBhcyBob3N0CmV4dGVybmFscy4KCiMjIyBTdHlsZXMKCmBtdXNjYXQoKWAgYXV0b21hdGljYWxseSBsb2FkcyBgdWkvc3R5bGUue2NzcyxzY3NzLHNhc3MsbGVzc31gIChvcgpgdWkvc3R5bGVzLntjc3Msc2NzcyxzYXNzLGxlc3N9YCkgZm9yIGV2ZXJ5IFVJIGVudHJ5LCBwbHVzCmB1aS97ZW50cnl9Lntjc3Msc2NzcyxzYXNzLGxlc3N9YCBmb3IgYSBtYXRjaGluZyBlbnRyeS1zcGVjaWZpYyBzdHlsZXNoZWV0LiBZb3UKZG8gbm90IG5lZWQgdG8gaW1wb3J0IENTUyBmcm9tIGV2ZXJ5IGAudHN4YCBmaWxlLgoKVGhlIHNjYWZmb2xkIHVzZXMgVGFpbHdpbmQncyB0aGVtZS91dGlsaXRpZXMgbGF5ZXJzIG9ubHksIHNvIHBsdWdpbiB1dGlsaXRpZXMKYXJlIGdlbmVyYXRlZCBmcm9tIGZpbGVzIHVuZGVyIGB1aS9gIHdpdGhvdXQgYXBwbHlpbmcgVGFpbHdpbmQgcHJlZmxpZ2h0IHJlc2V0cwp0byB0aGUgaG9zdCBwYWdlLgoKQnVpbHQgQ1NTIHNlbGVjdG9ycyBhcmUgc2NvcGVkIHVuZGVyIHRoZSBjdXJyZW50IHBsdWdpbiBpZAooYFtkYXRhLW11c2NhdC1wbHVnaW4taWQ9Ii4uLiJdYCkuIENTUy1pbi1KUyBsaWJyYXJpZXMgc3VjaCBhcyBFbW90aW9uIHdvcmsKbm9ybWFsbHksIGJ1dCBnbG9iYWwgc3R5bGVzIHNob3VsZCBiZSBzY29wZWQgYnkgdGhlIGF1dGhvci4KCiMjIyMgVGFpbHdpbmQKClRoaXMgdGVtcGxhdGUgZW5hYmxlcyBUYWlsd2luZCBpbiBgdml0ZS5jb25maWcudHNgOgoKYGBgdHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsKYGBgCgpUaGUgZGVmYXVsdCBgdWkvc3R5bGUuY3NzYCB1c2VzIFRhaWx3aW5kIHRoZW1lL3V0aWxpdGllcyBvbmx5LCBub3QgcHJlZmxpZ2h0OgoKYGBgY3NzCkBsYXllciB0aGVtZSwgdXRpbGl0aWVzOwoKQGltcG9ydCAidGFpbHdpbmRjc3MvdGhlbWUuY3NzIiBsYXllcih0aGVtZSk7CkBpbXBvcnQgInRhaWx3aW5kY3NzL3V0aWxpdGllcy5jc3MiIGxheWVyKHV0aWxpdGllcyk7CgpAc291cmNlICIuLyoqLyoue3RzLHRzeH0iOwpgYGAKCiMjIyMgU0NTUywgU2FzcywgYW5kIExlc3MKCkluc3RhbGwgdGhlIHByZXByb2Nlc3NvciBwYWNrYWdlLCB0aGVuIGNyZWF0ZSBvbmUgb2YgdGhlIGF1dG8tbG9hZGVkIHN0eWxlIGZpbGVzLgoKYGBgYmFzaApucG0gaSAtRCBzYXNzCmBgYAoKYGBgc2NzcwovKiB1aS9zdHlsZS5zY3NzICovCiRhY2NlbnQ6ICMzYjgyZjY7CgoucGFuZWwgewogIGJvcmRlcjogMXB4IHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCAkYWNjZW50IDQwJSwgdHJhbnNwYXJlbnQpOwoKICAmX190aXRsZSB7CiAgICBjb2xvcjogJGFjY2VudDsKICB9Cn0KYGBgCgpGb3IgTGVzcywgaW5zdGFsbCBgbGVzc2AgYW5kIHVzZSBgdWkvc3R5bGUubGVzc2AuCgojIyMjIEVtb3Rpb24KCkVtb3Rpb24gZGVwZW5kZW5jaWVzIG1heSBiZSBpbiBgZGVwZW5kZW5jaWVzYCBvciBgZGV2RGVwZW5kZW5jaWVzYDsgVml0ZSBjYW4KYnVuZGxlIHRoZW0gd2hlbiB0aGV5IGFyZSBpbnN0YWxsZWQgYW5kIGltcG9ydGVkIGJ5IHRoZSBwbHVnaW4uCgpGb3IgYHN0eWxlZGAsIG5vIFZpdGUgY29uZmlnIGNoYW5nZSBpcyBuZWVkZWQ6CgpgYGBiYXNoCm5wbSBpIEBlbW90aW9uL3JlYWN0IEBlbW90aW9uL3N0eWxlZApgYGAKCmBgYHRzeAppbXBvcnQgc3R5bGVkIGZyb20gIkBlbW90aW9uL3N0eWxlZCI7Cgpjb25zdCBQYW5lbCA9IHN0eWxlZC5kaXYoewogIGRpc3BsYXk6ICJncmlkIiwKICBnYXA6IDEyLAp9KTsKYGBgCgpGb3IgRW1vdGlvbidzIGBjc3NgIHByb3AsIHBhc3MgUmVhY3QgcGx1Z2luIG9wdGlvbnMgdGhyb3VnaCBgbXVzY2F0KClgIGFuZCBhZGQKYGpzeEltcG9ydFNvdXJjZWAgdG8gYHRzY29uZmlnLmpzb25gOgoKYGBgYmFzaApucG0gaSBAZW1vdGlvbi9yZWFjdCBAZW1vdGlvbi9zdHlsZWQKbnBtIGkgLUQgQGVtb3Rpb24vYmFiZWwtcGx1Z2luCmBgYAoKYGBgdHMKLy8gdml0ZS5jb25maWcudHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbCiAgICB0YWlsd2luZGNzcygpLAogICAgbXVzY2F0KHsKICAgICAgcmVhY3Q6IHsKICAgICAgICBqc3hJbXBvcnRTb3VyY2U6ICJAZW1vdGlvbi9yZWFjdCIsCiAgICAgICAgYmFiZWw6IHsKICAgICAgICAgIHBsdWdpbnM6IFsiQGVtb3Rpb24vYmFiZWwtcGx1Z2luIl0sCiAgICAgICAgfSwKICAgICAgfSwKICAgIH0pLAogIF0sCn0pOwpgYGAKCmBgYGpzb24KewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAianN4SW1wb3J0U291cmNlIjogIkBlbW90aW9uL3JlYWN0IgogIH0KfQpgYGAKCkVtb3Rpb24gYEdsb2JhbGAgd3JpdGVzIGdsb2JhbCBDU1MgYXQgcnVudGltZSwgc28gc2NvcGUgaXQgbWFudWFsbHkgb3IgYXZvaWQgaXQKaW5zaWRlIHBsdWdpbnMuCgojIyMgdXNlUmIoKSBob29rCgpBY2Nlc3MgdGhlIGNvbW11bmljYXRpb24gQVBJIGJldHdlZW4gdGhlIHBsdWdpbiBtb2R1bGUgYW5kIFVJIGZyb20gYW55IHBsdWdpbiBjb21wb25lbnQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlUmIgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvc2RrIjsKCmZ1bmN0aW9uIEFwcCgpIHsKICBjb25zdCByYiA9IHVzZVJiKCk7Cn0KYGBgCgojIyMgcmIgQVBJCgp8IE1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfAp8IGByYi5wdWIodG9waWMsIHBheWxvYWQpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFB1Ymxpc2ggYSBtZXNzYWdlIHRvIGEgdG9waWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IGByYi5zdWIodG9waWMsIGhhbmRsZXIpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFN1YnNjcmliZSB0byBhIHRvcGljIOKAlCByZXR1cm5zIGB7IHVuZGVjbGFyZSgpIH1gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmFjdGlvbih0b3BpYywgcGF5bG9hZD8pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2VuZCBhIHJlcXVlc3QgYW5kIGF3YWl0IGEgcmVwbHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnNlcnZlKHRvcGljLCBoYW5kbGVyKWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSGFuZGxlIGluY29taW5nIHJlcXVlc3RzIGZyb20gdGhlIGJhY2tlbmQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnRvYXN0KHsgdGl0bGU/LCBtZXNzYWdlLCB0eXBlPywgYWN0aW9uTGFiZWw/LCBoYW5kbGVBY3Rpb25DbGljaz8sIGNsb3NlT25BY3Rpb25DbGljaz8sIGR1cmF0aW9uPywgb25DbG9zZT8gfSlgIHwgU2hvdyBhIGhvc3QgdG9hc3Qgbm90aWZpY2F0aW9uLiBgbWVzc2FnZWAgYWNjZXB0cyBhIHN0cmluZyBvciBgUmVhY3RFbGVtZW50YC4gYHR5cGVgIGNhbiBiZSBgImluZm8iYCwgYCJkYW5nZXIiYCwgYCJ3YXJuaW5nImAsIGAiY2F1dGlvbiJgLCBvciBgInN1Y2Nlc3MiYCB8CnwgYHJiLmFsZXJ0KHsgdGl0bGU/LCBtZXNzYWdlLCBidXR0b25UZXh0PyB9KWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgYWxlcnQgZGlhbG9nLiBSZXNvbHZlcyB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmNvbmZpcm0oeyB0aXRsZT8sIG1lc3NhZ2UsIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgY29uZmlybWF0aW9uIGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gYHRydWVgIG9yIGBmYWxzZWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnByb21wdCh7IHRpdGxlPywgbWVzc2FnZSwgdmFsdWU/LCBwbGFjZWhvbGRlcj8sIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgcHJvbXB0IGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gdGhlIGVudGVyZWQgc3RyaW5nIG9yIGB1bmRlZmluZWRgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgpUb3BpYyBuYW1lcyBwYXNzZWQgdG8gYHB1YmAsIGBzdWJgLCBgYWN0aW9uYCwgYW5kIGBzZXJ2ZWAgYXJlIGlzb2xhdGVkIHBlciBwbHVnaW4uCgoKQWxsIG1ldGhvZHMgc3VwcG9ydCBHZW5lcmljIFR5cGVzOgoKYGBgdHN4CmNvbnN0IHN0YXR1cyA9IGF3YWl0IHJiLmFjdGlvbjx7IG9rOiBib29sZWFuIH0sIHsgaWQ6IG51bWJlciB9PigKICAiZ2V0LXN0YXR1cyIsCiAgeyBpZDogMSB9LAopOwoKY29uc3Qgc3ViID0gYXdhaXQgcmIuc3ViPHsgdmFsdWU6IG51bWJlciB9Pigic2Vuc29yL2RhdGEiLCAoZGF0YSkgPT4gewogIGNvbnNvbGUubG9nKGRhdGEudmFsdWUpOwp9KTsKc3ViLnVuZGVjbGFyZSgpOyAvLyBjbGVhbnVwCgpjb25zdCBvayA9IGF3YWl0IHJiLmNvbmZpcm0oewogIHRpdGxlOiAiUnVuIiwKICBtZXNzYWdlOiAiU3RhcnQgdGhlIGJhY2tlbmQgYWN0aW9uPyIsCn0pOwppZiAob2spIHsKICBhd2FpdCByYi5hY3Rpb24oInJ1biIpOwp9CmBgYAoKIyMjIFNhdmluZyBhbmQgcmVzdG9yaW5nIGZvcm0gZGF0YSAoYHVzZVJiRm9ybURhdGFgIC8gYHVzZVJiU2F2ZWApCgpJZiB0aGUgaG9zdCBlbWJlZHMgeW91ciBwbHVnaW4gaW4gYSBmb3JtIGl0IG93bnMgKGUuZy4gYSBwcm9ncmFtIHN0ZXAgZWRpdG9yCndpdGggaXRzIG93biBTYXZlIGJ1dHRvbiksIGl0IGNhbiBoYW5kIHlvdXIgcGx1Z2luIHByZXZpb3VzbHktc2F2ZWQgdmFsdWVzIGFuZApwdWxsIHRoZSBjdXJyZW50IHZhbHVlcyBiYWNrIG91dCB3aGVuIHRoZSB1c2VyIHNhdmVzLiBUaGUgaG9zdCDigJQgbm90IHRoZQpwbHVnaW4g4oCUIHBlcnNpc3RzIHRoZSBkYXRhIChJbmRleGVkREIsIGJhY2tlbmQsIGV0Yy4pLgoKYGBgdHN4CmltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSAicmVhY3QiOwppbXBvcnQgeyB1c2VSYkZvcm1EYXRhLCB1c2VSYlNhdmUgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwoKdHlwZSBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogc3RyaW5nOyB3aWR0aDogbnVtYmVyIH07CmNvbnN0IERFRkFVTFRTOiBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogIiIsIHdpZHRoOiAyMCB9OwoKZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwKCkgewogIC8vIFByZXZpb3VzbHktc2F2ZWQgdmFsdWVzLCBvciB1bmRlZmluZWQgZm9yIGEgYnJhbmQtbmV3IGluc3RhbmNlLgogIGNvbnN0IHNhdmVkID0gdXNlUmJGb3JtRGF0YTxHcmlwQXJncz4oKTsKICBjb25zdCBbYXJncywgc2V0QXJnc10gPSB1c2VTdGF0ZTxHcmlwQXJncz4oeyAuLi5ERUZBVUxUUywgLi4uc2F2ZWQgfSk7CgogIC8vIFJlZ2lzdGVycyBhIGdldHRlciB0aGUgaG9zdCBjYWxscyB3aGVuIGl0cyBTYXZlIGJ1dHRvbiBpcyBjbGlja2VkLgogIC8vIEFsd2F5cyByZXR1cm5zIHRoZSBDVVJSRU5UIHZhbHVlcyDigJQgcmUtcmVnaXN0ZXJpbmcgb24gZXZlcnkgcmVuZGVyIGtlZXBzCiAgLy8gdGhlIGNsb3N1cmUgZnJlc2gsIHdoaWNoIHVzZVJiU2F2ZSBhbHJlYWR5IGhhbmRsZXMgZm9yIHlvdS4KICB1c2VSYlNhdmUoKCkgPT4gKHsKICAgIGFyZ3MsCiAgICBzdW1tYXJ5OiBgJHthcmdzLnRhcmdldE5hbWUgfHwgInRhcmdldCJ9IMK3ICR7YXJncy53aWR0aH1tbWAsCiAgfSkpOwoKICByZXR1cm4gKC8qIC4uLmZvcm0gVUkgcmVhZGluZy93cml0aW5nIGBhcmdzYC4uLiAqLyk7Cn0KYGBgCgpUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBgdXNlUmJTYXZlYCBtdXN0IGJlIEpTT04tc2VyaWFsaXNhYmxlIOKAlCB0aGUgaG9zdApwZXJzaXN0cyBpdCBhcy1pcy4gTm90IGV2ZXJ5IGhvc3QgZW1iZWRzIHBsdWdpbnMgaW4gYSBzYXZlL3Jlc3RvcmUgZm9ybTsgaWYKeW91cnMgZG9lc24ndCwgeW91IGNhbiBza2lwIHRoZXNlIGhvb2tzIGVudGlyZWx5LgoKIyMjIFVJIGNvbXBvbmVudHMKCkltcG9ydCBNdXNjYXQgY29tcG9uZW50cyBmcm9tIGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3RgIGFuZCBleHBvcnQgYQpSZWFjdCBjb21wb25lbnQgYXMgdGhlIGRlZmF1bHQgZXhwb3J0LiBUaGUgaG9zdCBtb3VudHMgdGhhdCBjb21wb25lbnQgZGlyZWN0bHkKYW5kIHByb3ZpZGVzIGB1c2VSYigpYCB0aHJvdWdoIGNvbnRleHQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7IFJCTGFiZWxCdXR0b24sIFJCU2xpZGVyLCBSQlN3aXRjaCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9yZWFjdCI7CmltcG9ydCB7IHVzZVJiIH0gZnJvbSAiQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3NkayI7CgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt3aWR0aCwgc2V0V2lkdGhdID0gdXNlU3RhdGUoMjApOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwoKICByZXR1cm4gKAogICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICA8UkJTbGlkZXIKICAgICAgICB2YWx1ZT17W3dpZHRoXX0KICAgICAgICBtaW49ezB9CiAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgb25WYWx1ZUNoYW5nZT17KHZhbHVlczogbnVtYmVyW10pID0+IHNldFdpZHRoKHZhbHVlc1swXSA/PyAwKX0KICAgICAgLz4KICAgICAgPFJCU3dpdGNoIGNoZWNrZWQ9e2VuYWJsZWR9IG9uQ2hlY2tlZENoYW5nZT17c2V0RW5hYmxlZH0gLz4KICAgICAgPFJCTGFiZWxCdXR0b24KICAgICAgICBkaXNhYmxlZD17IWVuYWJsZWR9CiAgICAgICAgb25DbGljaz17KCkgPT4gcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KX0KICAgICAgPgogICAgICAgIEdyaXAKICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgPC9kaXY+CiAgKTsKfQpgYGAKCi0tLQoKIyMgRGV2ZWxvcGluZyBkaXJlY3RseSBvbiB0aGUgcm9ib3QgUEMKCklmIHlvdSdyZSBydW5uaW5nIGBtdXNjYXQtcGsgZGV2YCAqKm9uIHRoZSByb2JvdCBQQyBpdHNlbGYqKiwgTXVzY2F0IGlzIGxpa2VseSBhbHJlYWR5CnJ1bm5pbmcgaXRzIG93biBTb2NrZXQuSU8gYnJpZGdlIG9uIHBvcnQgMTAwMDAuIEluIHRoYXQgY2FzZSB0aGUgQ0xJIGRldGVjdHMgdGhlIHBvcnQKY29uZmxpY3QgYW5kIGFza3M6CgpgYGAK4pqgIHBvcnQgMTAwMDAgaXMgYWxyZWFkeSBpbiB1c2Ug4oCUIGNhbid0IHN0YXJ0IFNvY2tldC5JTyBicmlkZ2UuCiAgUHJvY2VlZCB3aXRob3V0IFNvY2tldC5JTyBicmlkZ2U/IFt5L05dOgpgYGAKCkFuc3dlciAqKnkqKi4gWW91ciBwbHVnaW4gYmFja2VuZCB3aWxsIGNvbm5lY3QgdG8gdGhlIE11c2NhdCBicmlkZ2UgdGhhdCdzIGFscmVhZHkKcnVubmluZyBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGEgbmV3IG9uZSDigJQgZXhhY3RseSB3aGF0IHlvdSB3YW50IHdoZW4gZGV2ZWxvcGluZyBvbiB0aGUKcm9ib3QuCgo+IElmIHlvdSBhbnN3ZXIgKipuKiogKG9yIGp1c3QgcHJlc3MgRW50ZXIpLCB0aGUgQ0xJIGV4aXRzIHNvIHlvdSBjYW4gZnJlZSB0aGUgcG9ydAo+IG1hbnVhbGx5IGFuZCByZXRyeS4KCi0tLQoKIyMgQmFja2VuZCBydW50aW1lcwoKYG1hbmlmZXN0Lmpzb25gIGNob29zZXMgb25lIGJhY2tlbmQgcnVudGltZS4gYG11c2NhdC1wayBkZXZgIHJ1bnMgYmFja2VuZCBjb2RlIGluCmEgRG9ja2VyIGNvbnRhaW5lciBtYXRjaGluZyB0aGUgcm9ib3QgZW52aXJvbm1lbnQuIEJhY2tlbmQgY29kZSBzaG91bGQgY29udGFpbgpwbHVnaW4gbG9naWMgb25seTsgaXQgc2hvdWxkIG5vdCBzdGFydCB0aGUgTXVzY2F0IGJyaWRnZSBvciBpdHMgb3duIGNvcHkgb2YgdGhlCnBsdWdpbiBnYXRld2F5LgoKIyMjIFdoaWNoIGJhY2tlbmQgcGF0dGVybj8gKGRlcGVuZHMgb24gdGhlIGNvbnRyaWJ1dGlvbiBwb2ludCkKCioqSG93IHlvdSBjb250cm9sIHRoZSByb2JvdCBkZXBlbmRzIG9uIHdoYXQgeW91ciBwbHVnaW4gY29udHJpYnV0ZXMqKiAoc2VlCmBtYW5pZmVzdC5qc29uYCDihpIgYGNvbnRyaWJ1dGVzW10ucG9pbnRgKS4gRG9uJ3QgbWl4IHRoZXNlIHVwOgoKfCBDb250cmlidXRpb24gcG9pbnQgfCBXaGF0IGl0IGlzIHwgQmFja2VuZCBwYXR0ZXJuIHwKfCAtLS0gfCAtLS0gfCAtLS0gfAp8IGBwcm9ncmFtLnBhbmVsYCAod2l0aCBgY29tbWFuZEluZm9gKSB8IERlZmluZXMgYSAqKmN1c3RvbSBjb21tYW5kKiogdGhlIHBsdWdpbiBhZGRzIHRvIHRoZSBQcm9ncmFtIHBhZ2UncyBydWxlLWJhc2VkIHNlcXVlbmNlIGJ1aWxkZXIuIFRoZSBvcGVyYXRvciBwbGFjZXMgaXQgaW50byB0aGUgcHJvZ3JhbSB0cmVlIGxpa2UgYW55IGJ1aWx0LWluIGNvbW1hbmQgKE1vdmUgSiwgUG9pbnQsIFdhaXQsIOKApik7IGl0IHJ1bnMgd2hlbiB0aGUgcHJvZ3JhbSByZWFjaGVzIHRoYXQgc3RlcC4gfCAqKmBQbHVnaW5Qcm9ncmFtQ29udGV4dGAqKiDigJQgaW50ZWdyYXRlZCB3aXRoIHRoZSBwcm9ncmFtJ3Mgc3RvcC9wYXVzZSBhbmQgdmFyaWFibGVzLiBTZWUgX1Byb2dyYW0gY29tbWFuZCBiYWNrZW5kXyBiZWxvdy4gfAp8IGB0b29sYmFyYCAvIGBsbmJgIC8gYG1vdmUucGFuZWxgIHwgQSBsaXZlIFVJIHBhbmVsL3BvcG92ZXIgdGhlIG9wZXJhdG9yIGludGVyYWN0cyB3aXRoIGRpcmVjdGx5IHwgQ2FsbCB0aGUgcm9ib3QgKipTREsgZGlyZWN0bHkqKiAoYFJCTWFuaXB1bGF0ZVNES2AsIGBSQkFtclNES2ApIGZyb20gYHB5L21haW4ucHlgLCBvciBgcmIuYWN0aW9uKC4uLilgIOKGkiB5b3VyIGJhY2tlbmQg4oaSIFNESy4gKipOb3QqKiBhIHByb2dyYW0gc3RlcCDigJQgdGhlcmUgaXMgbm8gc3RvcC9wYXVzZS92YXJpYWJsZSBjb250ZXh0LiB8CgpSdWxlIG9mIHRodW1iOiB1c2UgYFBsdWdpblByb2dyYW1Db250ZXh0YCAqKm9ubHkqKiBmb3IgYSBgcHJvZ3JhbS5wYW5lbGAgY29tbWFuZAp0aGF0IHJ1bnMgYXMgcGFydCBvZiBhIHByb2dyYW0uIFRvIG1vdmUgdGhlIHJvYm90IGxpdmUgZnJvbSBhIHRvb2xiYXIvbW92ZSBwYW5lbCwKdXNlIHRoZSBTREsg4oCUIGEgcHJvZ3JhbS1zdGVwIGNvbnRleHQgZG9lcyBub3QgYXBwbHkuCgojIyMgRnJvbnRlbmQtb25seSAoYG5vbmVgKQoKVXNlIHRoaXMgd2hlbiB0aGUgcGx1Z2luIG9ubHkgaGFzIFVJIGFuZCBjYWxscyBob3N0IHNlcnZpY2VzOgoKYGBganNvbgp7ICJydW50aW1lIjogeyAidHlwZSI6ICJub25lIiB9IH0KYGBgCgojIyMgUHl0aG9uCgpQeXRob24gcGx1Z2lucyB1c2UgYHB5L21haW4ucHlgIGFuZCBjYW4gY29tbXVuaWNhdGUgd2l0aCB0aGUgVUkgdGhyb3VnaApgcmFpbmJvdy5yYl9zZGsuUkJQbHVnaW5DYWxsYC4KCmBgYHB5dGhvbgppbXBvcnQgdGltZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQkFtclNESywgUkJNYW5pcHVsYXRlU0RLLCBSQlBsdWdpbkNhbGwKCnBsdWdpbiA9IFJCUGx1Z2luQ2FsbCgpCgoKcGx1Z2luLnB1Ymxpc2goInN0YXRlIiwgeyJyZWFkeSI6IFRydWV9KQoKCkBwbHVnaW4uc3Vic2NyaWJlKCJldmVudCIpCmRlZiBvbl91aV9ldmVudChwYXlsb2FkPU5vbmUpOgogICAgcHJpbnQocGF5bG9hZCkKCgpAcGx1Z2luLnNlcnZlKCJ0b29sL2VjaG8iKQpkZWYgZWNobyhwYXlsb2FkPU5vbmUpOgogICAgcmV0dXJuIHsiZWNobyI6IHBheWxvYWR9CgoKZGVmIGNhbGxfZnJvbnRlbmQoKToKICAgIHJlcyA9IHBsdWdpbi5jYWxsKCJ0b29sL3BpbmciLCBwYXlsb2FkPXsiaGVsbG8iOiAicGx1Z2luIn0pCiAgICBwcmludChyZXMpCgoKZGVmIG1vdmVfal9leGFtcGxlKCk6CiAgICBhbXIgPSBSQkFtclNESygpCiAgICBtYW5pcHVsYXRlID0gUkJNYW5pcHVsYXRlU0RLKCkKICAgIHJldHVybiBtYW5pcHVsYXRlLm1vdmUuY2FsbF9tb3ZlX2ooCiAgICAgICAgcm9ib3RfbW9kZWw9IkM1MDA5MjAiLAogICAgICAgIHRhcmdldD17InRhcl92YWx1ZXMiOiBbMCwgMCwgMCwgMCwgMCwgMF0sICJ0YXJfZnJhbWUiOiAwLCAidGFyX3VuaXQiOiAwfSwKICAgICkKCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgd2hpbGUgVHJ1ZToKICAgICAgICB0aW1lLnNsZWVwKDEpCmBgYAoKIyMjIyBQcm9ncmFtIGNvbW1hbmQgYmFja2VuZCAoYHByb2dyYW0ucGFuZWxgKQoKQSBgcHJvZ3JhbS5wYW5lbGAgY29udHJpYnV0aW9uIGRlZmluZXMgYSAqKmN1c3RvbSBjb21tYW5kKiogeW91ciBwbHVnaW4gYWRkcyB0bwp0aGUgTXVzY2F0ICoqUHJvZ3JhbSBwYWdlKiosIHdoZXJlIHRoZSBvcGVyYXRvciBidWlsZHMgYSByb2JvdCBwcm9ncmFtIGFzIGEKcnVsZS1iYXNlZCBzZXF1ZW5jZSAoYSBwcm9ncmFtIHRyZWUpLiBZb3VyIGNvbW1hbmQgYXBwZWFycyBhbG9uZ3NpZGUgdGhlCmJ1aWx0LWlucyAoTW92ZSBKLCBQb2ludCwgV2FpdCwg4oCmKTsgdGhlIG9wZXJhdG9yIHBsYWNlcyBpdCBpbnRvIHRoZSB0cmVlLCBhbmQKZWFjaCB0aW1lIHRoZSBwcm9ncmFtIGV4ZWN1dGVzIHRoYXQgc3RlcCB0aGUgaG9zdCBjYWxscyB5b3VyIGJhY2tlbmQgdGhyb3VnaApgUGx1Z2luUHJvZ3JhbUNvbnRleHRgIOKAlCByZWNlaXZpbmcgdGhlIHN0ZXAgYXJncywgY2hlY2tpbmcgZm9yIHN0b3AvcGF1c2UsCnJlYWRpbmcvd3JpdGluZyBwcm9ncmFtIHZhcmlhYmxlcywgYW5kIHNpZ25hbGxpbmcgY29tcGxldGlvbi4gVGhpcyBwYXR0ZXJuIGlzCioqb25seSoqIGZvciBgcHJvZ3JhbS5wYW5lbGA7IGEgdG9vbGJhci9tb3ZlLXBhbmVsIHBsdWdpbiB1c2VzIHRoZSBTREsgZGlyZWN0bHkKaW5zdGVhZCAoc2VlIHRoZSB0YWJsZSBhYm92ZSkuCgpgYGBweXRob24KIiIiClBsdWdpbiBiYWNrZW5kIG1haW4ucHkgZXhhbXBsZSAocHJvZ3JhbS5wYW5lbCBjb21tYW5kKS4KCm1hbmlmZXN0Lmpzb246CiAgInJ1bnRpbWUiOiB7InR5cGUiOiAicHl0aG9uIiwgImVudHJ5IjogIm1haW4ucHkifSwKICAiY29udHJpYnV0ZXMiOiBbewogICAgInBvaW50IjogInByb2dyYW0ucGFuZWwiLAogICAgInVpIjogInByb2dyYW0iLAogICAgImxhYmVsIjogeyJlbiI6ICJNeSBQbHVnaW4gU3RlcCJ9LAogICAgImNvbW1hbmRJbmZvIjogewogICAgICAibmFtZSI6ICJNeSBQbHVnaW4gU3RlcCIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJmdW5jTmFtZSI6ICJyYl9wcm9ncmFtX3Nkay5wbHVnaW5fZXhlY3V0ZSIsCiAgICAgICJhcmdzIjogeyJtZXNzYWdlIjogImhlbGxvIn0gICAjIHBsdWdpbi1hdXRob3ItZGVmaW5lZCBhcmdzCiAgICB9CiAgfV0KClRoZSBob3N0IGludm9rZXMgY29tbWFuZEluZm8uZnVuY05hbWUgKHJiX3Byb2dyYW1fc2RrLnBsdWdpbl9leGVjdXRlKSB3aXRoCmFyZ3MucGx1Z2luX2lkICsgeW91ciBhcmdzIHdoZW4gdGhlIHByb2dyYW0gcmVhY2hlcyB0aGlzIHN0ZXAuCiIiIgppbXBvcnQgYXN5bmNpbwpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBQbHVnaW5Qcm9ncmFtQ29udGV4dAoKY3R4ID0gUGx1Z2luUHJvZ3JhbUNvbnRleHQocGx1Z2luX2lkPSJteS1wbHVnaW4iKQoKCkBjdHgub25fZXhlY3V0ZQphc3luYyBkZWYgaGFuZGxlKGFyZ3M6IGRpY3QpIC0+IE5vbmU6CiAgICBtZXNzYWdlID0gYXJncy5nZXQoIm1lc3NhZ2UiLCAiIikKICAgIHByaW50KGYiW215LXBsdWdpbl0gZXhlY3V0ZSBjYWxsZWQ6IG1lc3NhZ2U9e21lc3NhZ2V9IiwgZmx1c2g9VHJ1ZSkKCiAgICAjIGNoZWNrIHN0b3AvcGF1c2UgZHVyaW5nIGxvbmctcnVubmluZyB3b3JrCiAgICBmb3IgXyBpbiByYW5nZSgxMCk6CiAgICAgICAgYXdhaXQgY3R4LmNoZWNrX3N0b3AoKQogICAgICAgIGF3YWl0IGFzeW5jaW8uc2xlZXAoMC4xKQoKICAgICMgcmVhZCBhIHByb2dyYW0gdmFyaWFibGUKICAgIGNvdW50ZXIgPSBhd2FpdCBjdHguZ2V0X3ZhcmlhYmxlKCJjb3VudGVyIikKICAgIHByaW50KGYiW215LXBsdWdpbl0gY291bnRlcj17Y291bnRlcn0iLCBmbHVzaD1UcnVlKQoKICAgICMgdXBkYXRlIGEgdmFyaWFibGUKICAgIGF3YWl0IGN0eC5zZXRfdmFyaWFibGUoInJlc3VsdCIsIGYiZG9uZToge21lc3NhZ2V9IikKCiAgICAjIGZpbmlzaCB0aGUgc3RlcAogICAgYXdhaXQgY3R4LmRvbmUoKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBhc3luY2lvLnJ1bihjdHguc3RhcnQoKSkKYGBgCgojIyMgQysrCgpDKysgcGx1Z2lucyB1c2UgYGNwcC9gIGFuZCBhcmUgYnVpbHQgd2l0aCBDTWFrZSBpbnNpZGUgRG9ja2VyLiBUaGUgY3VycmVudCBDKysKdGVtcGxhdGUgaXMgYSBidWlsZC9ydW4gc2tlbGV0b247IHdpcmUgaXQgdG8gdGhlIHBsdWdpbiBnYXRld2F5IHdoZW4gdGhlIEMrKyBTREsKaXMgYXZhaWxhYmxlLgoKYGBgY3BwCiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx0aHJlYWQ+CgppbnQgbWFpbigpIHsKICBjb25zdCBjaGFyKiBwbHVnaW5faWQgPSBzdGQ6OmdldGVudigiUkJfUExVR0lOX0lEIik7CiAgc3RkOjpjb3V0IDw8ICJbX19QTFVHSU5fTkFNRV9fXSBiYWNrZW5kIHJlYWR5IgogICAgICAgICAgICA8PCAocGx1Z2luX2lkID8gc3RkOjpzdHJpbmcoIiAoaWQ9IikgKyBwbHVnaW5faWQgKyAiKSIgOiAiIikKICAgICAgICAgICAgPDwgc3RkOjplbmRsOwoKICB3aGlsZSAodHJ1ZSkgewogICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjpzZWNvbmRzKDEpKTsKICB9CiAgcmV0dXJuIDA7Cn0KYGBgCgojIyMgUk9TMiAocmNscHkpCgpST1MyIFB5dGhvbiBwbHVnaW5zIHVzZSBgcm9zMl93cy9gIHdpdGggYHJ1bnRpbWUucm9zQ2xpZW50OiAicmNscHkiYC4gVGhlIG5vZGUKaXMgbGF1bmNoZWQgd2l0aCBgLS1yb3MtYXJncyAtciBfX25zOj0ve3NsdWd9YCBhdXRvbWF0aWNhbGx5IGJ5IGBkZXY6YmFja2AuCgpgYGBweXRob24KIyByb3MyX3dzL3NyYy9fX1BMVUdJTl9TTFVHX18vX19QTFVHSU5fU0xVR19fL25vZGUucHkKaW1wb3J0IHJjbHB5CmZyb20gcmNscHkubm9kZSBpbXBvcnQgTm9kZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQk1hbmlwdWxhdGVTREsKCnNkayA9IFJCTWFuaXB1bGF0ZVNESygpCgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUoTm9kZSk6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygiX19QTFVHSU5fU0xVR19fX25vZGUiKQogICAgICAgIHNlbGYuZ2V0X2xvZ2dlcigpLmluZm8oIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKQogICAgICAgICMgdXNlIHNkayBhbG9uZ3NpZGUgUk9TMiBwdWJsaXNoZXJzL3N1YnNjcmliZXJzL3NlcnZpY2VzIGFzIG5lZWRlZApgYGAKCiMjIyBST1MyIChyY2xjcHApCgpST1MyIEMrKyBwbHVnaW5zIHVzZSBgcm9zMl93cy9gIHdpdGggYHJ1bnRpbWUucm9zQ2xpZW50OiAicmNsY3BwImAuCgpgYGBjcHAKI2luY2x1ZGUgInJjbGNwcC9yY2xjcHAuaHBwIgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUgOiBwdWJsaWMgcmNsY3BwOjpOb2RlIHsKcHVibGljOgogIF9fUExVR0lOX0NMQVNTX19Ob2RlKCkgOiBOb2RlKCJfX1BMVUdJTl9TTFVHX19fbm9kZSIpIHsKICAgIFJDTENQUF9JTkZPKHRoaXMtPmdldF9sb2dnZXIoKSwgIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKTsKICB9Cn07CmBgYAoKLS0tCgojIyBtYW5pZmVzdC5qc29uCgpgYGBqc29uYwp7CiAgLy8gdW5pcXVlIHBsdWdpbiBJRCDigJQgcmV2ZXJzZS1kb21haW4gZm9ybWF0IHJlY29tbWVuZGVkCiAgImlkIjogImNvbS5leGFtcGxlLm15LXBsdWdpbiIsCiAgIm5hbWUiOiAiTXkgUGx1Z2luIiwKICAidmVyc2lvbiI6ICIxLjAuMCIsCgogIC8vIG1pbmltdW0gTXVzY2F0IHZlcnNpb24gcmVxdWlyZWQgdG8gbG9hZCB0aGlzIHBsdWdpbgogICJtaW5NdXNjYXRWZXJzaW9uIjogIjEuMC4wIiwKCiAgLy8gcGx1Z2luIGF1dGhvciAoZW1wdHkgc3RyaW5nIGlzIGZpbmUpCiAgImF1dGhvciI6ICJZb3VyIE5hbWUiLAoKICAvLyBkaXNwbGF5ZWQgaW4gdGhlIE11c2NhdCBwbHVnaW4gc3RvcmUgLyBpbmZvIHBhbmVsCiAgLy8gc3RyaW5nIG9yIHsgZW4gKHJlcXVpcmVkKSwga28sIGphLCB6aCwgdmksIHRoLCBlcyB9CiAgImRlc2NyaXB0aW9uIjogeyAiZW4iOiAiUGx1Z2luIGRlc2NyaXB0aW9uIiwgImtvIjogIu2UjOufrOq3uOyduCDshKTrqoUiIH0sCgogIC8vIFNWRyBzdHJpbmcgKHNpbmdsZSBmaWxlKSBvciBQTkcvSlBHIHNpemUgbWFwIChhbGwgdGhyZWUgc2l6ZXMgcmVxdWlyZWQpCiAgImljb25zIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgLy8gImljb25zIjogeyAiMTYiOiAiYXNzZXRzL2ljb24tMTYucG5nIiwgIjQ4IjogImFzc2V0cy9pY29uLTQ4LnBuZyIsICIxMjgiOiAiYXNzZXRzL2ljb24tMTI4LnBuZyIgfSwKCiAgLy8gdGFyZ2V0TW9kZWxzIGFuZC9vciB0YXJnZXRDYXRlZ29yeXMg4oCUIGF0IGxlYXN0IG9uZSBpcyByZXF1aXJlZAogIC8vICJhbGwiID0gZXZlcnkgdGFyZ2V0LCBvciBsaXN0IHNwZWNpZmljIHZhbHVlcwogICJ0YXJnZXRNb2RlbHMiOiAiYWxsIiwKICAvLyAidGFyZ2V0TW9kZWxzIjogWyJDNTAwOTIwIiwgIkM1MDA5MzAiXSwKICAidGFyZ2V0Q2F0ZWdvcnlzIjogImFsbCIsCiAgLy8gInRhcmdldENhdGVnb3J5cyI6IFsibWFuaXB1bGF0ZSIsICJhbXIiLCAicmJ5MSIsICJ2aXNpb24iXSwKCiAgImNvbnRyaWJ1dGVzIjogWwogICAgLy8gcHJvZ3JhbS5wYW5lbCDigJQgZGVmaW5lcyBhIGN1c3RvbSBjb21tYW5kIGZvciB0aGUgUHJvZ3JhbSBwYWdlIHNlcXVlbmNlCiAgICAvLyAgIGJ1aWxkZXI7IHJ1bnMgdmlhIFBsdWdpblByb2dyYW1Db250ZXh0IHdoZW4gdGhlIHByb2dyYW0gcmVhY2hlcyBpdAogICAgewogICAgICAicG9pbnQiOiAicHJvZ3JhbS5wYW5lbCIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIuuCtCDtlIzrn6zqt7jsnbgiLCAiZW4iOiAiTXkgUGx1Z2luIiB9LAogICAgICAidWkiOiAicHJvZ3JhbSIsICAgICAgICAgICAvLyBtdXN0IGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGNvbnRyaWJ1dGlvbnMKICAgICAgImNvbW1hbmRJbmZvIjogewogICAgICAgICJuYW1lIjogIk15IFBsdWdpbiIsCiAgICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgICAiZnVuY05hbWUiOiAicmJfcHJvZ3JhbV9zZGsucGx1Z2luX2V4ZWN1dGUiLAogICAgICAgICJhcmdzIjoge30KICAgICAgfQogICAgfSwKICAgIC8vIHRvb2xiYXIg4oCUIGFkZHMgYSBidXR0b24gdG8gdGhlIHRvcCB0b29sYmFyIChyZXF1aXJlZCkKICAgIHsKICAgICAgInBvaW50IjogInRvb2xiYXIiLAogICAgICAiaWNvbiI6ICJhc3NldHMvaWNvbi5zdmciLAogICAgICAibGFiZWwiOiB7ICJrbyI6ICLrgrQg7ZSM65+s6re47J24IiwgImVuIjogIk15IFBsdWdpbiIgfSwKICAgICAgInVpIjogImNvbnRlbnQiLCAgICAgICAgICAgLy8gbXVzdCBiZSB1bmlxdWUgYWNyb3NzIGFsbCBjb250cmlidXRpb25zCiAgICAgICJvcGVucyI6ICJwb3BvdmVyIiAgICAgICAgIC8vIHBvcG92ZXIgfCBwYW5lbCB8IHBhZ2UKICAgIH0sCiAgICAvLyBtb3ZlLnBhbmVsIOKAlCBhZGRzIGEgcGFuZWwgdG8gdGhlIE1vdmUgc2NyZWVuCiAgICB7CiAgICAgICJwb2ludCI6ICJtb3ZlLnBhbmVsIiwKICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgImxhYmVsIjogeyAia28iOiAi64K0IO2UjOufrOq3uOyduCIsICJlbiI6ICJNeSBQbHVnaW4iIH0sCiAgICAgICJ1aSI6ICJtb3ZlIiAgICAgICAgICAgICAgIC8vIG11c3QgYmUgdW5pcXVlIGFjcm9zcyBhbGwgY29udHJpYnV0aW9ucwogICAgfQogIF0sCgogIC8vIHJ1bnRpbWUg4oCUIG9uZSBvZjoKICAvLyAgIHsgInR5cGUiOiAibm9uZSIgfQogIC8vICAgeyAidHlwZSI6ICJweXRob24iLCAiZW50cnkiOiAibWFpbi5weSIgfQogIC8vICAgeyAidHlwZSI6ICJjcHAiLCAiZW50cnkiOiAiPGV4ZWN1dGFibGUgbmFtZT4iIH0KICAvLyAgIHsgInR5cGUiOiAicm9zMiIsICJyb3NDbGllbnQiOiAicmNscHkiIHwgInJjbGNwcCIsICJwYWNrYWdlIjogIi4uLiIsICJsYXVuY2giOiAiLi4uX25vZGUiIH0KICAicnVudGltZSI6IHsgInR5cGUiOiAicHl0aG9uIiwgImVudHJ5IjogIm1haW4ucHkiIH0sCgogIC8vIG9wdGlvbmFsOiBUQ1AgcG9ydHMgb3BlbmVkIGJ5IHRoaXMgcGx1Z2luIGJhY2tlbmQKICAvLyBvbmx5IG51bWJlcltdIGlzIGFsbG93ZWQ7IHJhbmdlcy9vYmplY3RzIGFyZSBub3QgYWNjZXB0ZWQKICAvLyBleHRlcm5hbCBwbHVnaW4gcG9ydHMgbXVzdCBiZSB3aXRoaW4gMjg2MDAtMjg5OTkKICAicG9ydHMiOiBbMjg2MDBdCn0KYGBgCgoqKkJhY2tlbmQgdHlwZXM6KioKCnwgdHlwZSB8IHNvdXJjZSBkaXIgfCBidWlsZCAvIHJ1biB8IGVudHJ5IHwKfC0tLXwtLS18LS0tfC0tLXwKfCBgcHl0aG9uYCB8IGBweS9gIHwgcGlwICsgcnVuIGluIERvY2tlciB8IGBtYWluLnB5YCB8CnwgYGNwcGAgfCBgY3BwL2AgfCBDTWFrZSBpbiBEb2NrZXIgfCBidWlsdCBleGVjdXRhYmxlIG5hbWUgfAp8IGByb3MyYCAocmNscHkpIHwgYHJvczJfd3MvYCB8IGNvbGNvbiAoYW1lbnRfcHl0aG9uKSBpbiBEb2NrZXIgfCDigJQgfAp8IGByb3MyYCAocmNsY3BwKSB8IGByb3MyX3dzL2AgfCBjb2xjb24gKGFtZW50X2NtYWtlKSBpbiBEb2NrZXIgfCDigJQgfAoKPiBFdmVyeSBiYWNrIGVuZCBydW5zIGluIGEgRG9ja2VyIGNvbnRhaW5lciBtYXRjaGluZyB0aGUgcm9ib3QgKFVidW50dSAyNC4wNCArIFB5dGhvbiAzLjEyKSwgc28gZGV2IGJlaGF2ZXMgbGlrZSBwcm9kdWN0aW9uIGFuZCBjb21waWxlZCBiaW5hcmllcyBhcmUgQUJJLWNvbXBhdGlibGUuICoqRG9ja2VyIGlzIHJlcXVpcmVkKiogZm9yIGFsbCBiYWNrZW5kIHR5cGVzIChvbmx5IGEgZnJvbnRlbmQtb25seSBgbm9uZWAgcGx1Z2luIHNraXBzIGl0KS4gTm8gbG9jYWwgUHl0aG9uL3Rvb2xjaGFpbiBzZXR1cCBpcyBuZWVkZWQuCgoqKkNvbnRyaWJ1dGlvbiBwb2ludHM6KioKCnwgcG9pbnQgfCBXaGVyZSBpdCBhcHBlYXJzIHwgQmFja2VuZCB8IGBjb21tYW5kSW5mb2AgfAp8LS0tfC0tLXwtLS18Oi0tLTp8CnwgYHRvb2xiYXJgIHwgVG9wIHRvb2xiYXIgYnV0dG9uIChtdXN0IGhhdmUgYXQgbGVhc3Qgb25lKSB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgbG5iYCB8IExlZnQgbmF2aWdhdGlvbiBlbnRyeSB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgbW92ZS5wYW5lbGAgfCBNb3ZlIHNjcmVlbiBwYW5lbCB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgcHJvZ3JhbS5wYW5lbGAgfCBDdXN0b20gY29tbWFuZCBpbiB0aGUgUHJvZ3JhbSBwYWdlIHNlcXVlbmNlIGJ1aWxkZXIgfCBgUGx1Z2luUHJvZ3JhbUNvbnRleHRgIHwg4pyTIHwKCioqYGNvbW1hbmRJbmZvYCBmaWVsZHMqKiAoZm9yIGBwcm9ncmFtLnBhbmVsYCk6Cgp8IGZpZWxkIHwgdHlwZSB8IGRlc2NyaXB0aW9uIHwKfC0tLXwtLS18LS0tfAp8IGBuYW1lYCB8IGBzdHJpbmdgIHwgRGlzcGxheSBuYW1lIG9mIHRoZSBjb21tYW5kIGluIHRoZSBwcm9ncmFtIHRyZWUgfAp8IGBpY29uYCB8IGBzdHJpbmdgIHwgSWNvbiBwYXRoIHwKfCBgaWNvbkNsYXNzTmFtZWAgfCBgc3RyaW5nP2AgfCBPcHRpb25hbCBDU1MgY2xhc3MgZm9yIHRoZSBpY29uIHwKfCBgZnVuY05hbWVgIHwgYHN0cmluZz9gIHwgQmFja2VuZCBmdW5jdGlvbiBuYW1lIHRvIGNhbGwgfAp8IGBhcmdzYCB8IGBSZWNvcmQ8c3RyaW5nLCBhbnk+P2AgfCBEZWZhdWx0IGFyZ3VtZW50cyB8CnwgYGRpc2FibGVkYCB8IGBib29sZWFuP2AgfCBXaGV0aGVyIHRoZSBub2RlIGlzIGRpc2FibGVkIHwKfCBgYWxsb3dDaGlsZHJlbmAgfCBgc3RyaW5nW10/YCB8IEFsbG93ZWQgY2hpbGQgY29tbWFuZHMgfAp8IGBhbGxvd1BhcmVudHNgIHwgYHN0cmluZ1tdP2AgfCBBbGxvd2VkIHBhcmVudCBjb21tYW5kcyB8CnwgYG5vdEFsbG93Q2hpbGRyZW5gIHwgYHN0cmluZ1tdP2AgfCBEaXNhbGxvd2VkIGNoaWxkIGNvbW1hbmRzIHwKfCBgc3luY0dyb3VwSWRgIHwgYGJvb2xlYW4/YCB8IFN5bmMgZ3JvdXAgSUQgYWNyb3NzIGNoaWxkcmVuIHwKfCBgZGlzYWJsZUNvcHlgIHwgYGJvb2xlYW4/YCB8IFByZXZlbnQgY29weSB8CnwgYGRpc2FibGVEZWxldGVgIHwgYGJvb2xlYW4/YCB8IFByZXZlbnQgZGVsZXRlIHwKfCBgcmVxdWlyZUNoaWxkcmVuYCB8IGBib29sZWFuP2AgfCBXaGV0aGVyIGEgY2hpbGQgY29tbWFuZCBpcyByZXF1aXJlZCB8CnwgYHJlcXVpcmVQYXJlbnRgIHwgYGJvb2xlYW4/YCB8IFdoZXRoZXIgYSBwYXJlbnQgY29tbWFuZCBpcyByZXF1aXJlZCB8CnwgYGNoaWxkcmVuQ29tbWFuZGAgfCBgc3RyaW5nP2AgfCBEZWZhdWx0IGNvbW1hbmQgdHlwZSBmb3IgY2hpbGRyZW4gfAoKKipWYWxpZGF0aW9uIHJ1bGVzOioqCi0gYGlkYCwgYG5hbWVgLCBgdmVyc2lvbmAsIGBtaW5NdXNjYXRWZXJzaW9uYCDigJQgcmVxdWlyZWQgbm9uLWVtcHR5IHN0cmluZ3MKLSBgYXV0aG9yYCDigJQgcmVxdWlyZWQgbm9uLWVtcHR5IHN0cmluZwotIGBkZXNjcmlwdGlvbmAg4oCUIHJlcXVpcmVkIChgc3RyaW5nYCBvciBgeyBlbiAocmVxdWlyZWQpLCBrbz8sIGphPywgemg/LCB2aT8sIHRoPywgZXM/IH1gKQotIGBpY29uc2Ag4oCUIFNWRzogc2luZ2xlIHN0cmluZyBwYXRoIGVuZGluZyBpbiBgLnN2Z2A7IFBORy9KUEc6IG9iamVjdCB3aXRoIGAiMTYiYCwgYCI0OCJgLCBgIjEyOCJgIGFsbCBwcmVzZW50Ci0gYHRhcmdldE1vZGVsc2Ag4oCUIGAiYWxsImAgb3IgYSBub24tZW1wdHkgYXJyYXkgb2Ygcm9ib3QgbW9kZWwgSUQgc3RyaW5ncyAoYXQgbGVhc3Qgb25lIG9mIGB0YXJnZXRNb2RlbHNgIC8gYHRhcmdldENhdGVnb3J5c2AgcmVxdWlyZWQpCi0gYHRhcmdldENhdGVnb3J5c2Ag4oCUIGAiYWxsImAgb3IgYSBub24tZW1wdHkgYXJyYXkgb2YgYCJtYW5pcHVsYXRlIiB8ICJhbXIiIHwgInJieTEiIHwgInZpc2lvbiJgIChhdCBsZWFzdCBvbmUgb2YgYHRhcmdldE1vZGVsc2AgLyBgdGFyZ2V0Q2F0ZWdvcnlzYCByZXF1aXJlZCkKLSBgY29udHJpYnV0ZXNgIOKAlCByZXF1aXJlZCBhcnJheTsgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBgdG9vbGJhcmAgZW50cnkKLSBgdWlgIOKAlCBlYWNoIGNvbnRyaWJ1dGlvbiBtdXN0IGhhdmUgYSB1bmlxdWUgdmFsdWUKLSBgY29tbWFuZEluZm9gIOKAlCByZXF1aXJlZCB3aGVuIGBwb2ludGAgaXMgYCJwcm9ncmFtLnBhbmVsImAKLSBgcG9ydHNgIOKAlCBvcHRpb25hbCBgbnVtYmVyW11gOyBldmVyeSBwb3J0IG11c3QgYmUgd2l0aGluIGAyODYwMC0yODk5OWAKICBhbmQgbXVzdCBub3QgYmUgYSByZXNlcnZlZCByb2JvdC9pbmR1c3RyaWFsL2ludGVybmFsIHBvcnQKCmBtdXNjYXQtcGsgYnVpbGRgIHRocm93cyBvbiBhbnkgdmFsaWRhdGlvbiBlcnJvci4gYG11c2NhdC1wayBkZXZgIHByaW50cyB3YXJuaW5ncy4KCioqQmFja2VuZCBwb3J0IHJ1bGVzOioqCi0gRGVjbGFyZSBhIHBvcnQgb25seSBpZiB5b3VyIGJhY2tlbmQgb3BlbnMgYSBUQ1Agc2VydmVyL2xpc3RlbmVyLgotIGBtdXNjYXQtcGsgZGV2YCBhbmQgYG11c2NhdC1wayBkZXY6YmFja2Agc3RvcCB0aGUgYmFja2VuZCBpZiBpdCBvcGVucyBhbgogIHVuZGVjbGFyZWQgbWFuYWdlZCBwb3J0LgotIFJlc2VydmVkIHBvcnRzIGluY2x1ZGUgYDUwMmAsIGAyMjIyYCwgYDQ4NDBgLCBgNTE3MC01MTc5YCwgYDgwMDAtODk5OWAsCiAgYDEwMDAwYCwgYDMwMDA0YCwgYDM0OTY0YCwgYDQ0ODE4YCwgYDUwMDAwLTUwMDA1YCwgYW5kIGA1MDA1MWAuCgotLS0KCiMjIExvY2FsaXplZCBkb2N1bWVudGF0aW9uCgpZb3UgY2FuIHNoaXAgcGVyLWxhbmd1YWdlIFJFQURNRSBmaWxlcyBhbG9uZ3NpZGUgdGhlIG1haW4gYFJFQURNRS5tZGAuIFBsYWNlIHRoZW0gaW4gdGhlIHByb2plY3Qgcm9vdDoKCmBgYApSRUFETUUubWQgICAgICAgICMgZGVmYXVsdCAvIEVuZ2xpc2ggZmFsbGJhY2sKUkVBRE1FLmtvLm1kICAgICAjIEtvcmVhbgpSRUFETUUuZW4ubWQgICAgICMgZXhwbGljaXQgRW5nbGlzaCAob3B0aW9uYWwpClJFQURNRS5qYS5tZCAgICAgIyBKYXBhbmVzZQpgYGAKCkFsbCBgUkVBRE1FKi5tZGAgZmlsZXMgZm91bmQgYXQgdGhlIHByb2plY3Qgcm9vdCBhcmUgYXV0b21hdGljYWxseSBjb3BpZWQgdG8gYGRpc3QvYCBvbgpgbXVzY2F0LXBrIGJ1aWxkYC4gTXVzY2F0IGRpc3BsYXlzIHRoZSBmaWxlIG1hdGNoaW5nIHRoZSB1c2VyJ3MgbG9jYWxlLApmYWxsaW5nIGJhY2sgdG8gYFJFQURNRS5tZGAgaWYgbm9uZSBtYXRjaGVzLgoKLS0tCgojIyBJbnN0YWxsaW5nIFB5dGhvbiBkZXBlbmRlbmNpZXMKCkFkZCBhbnkgcGFja2FnZSB3aXRoIGFuIG9wdGlvbmFsIHZlcnNpb24gcGluIHRvIGByZXF1aXJlbWVudHMudHh0YDoKCmBgYApyYWluYm93LXJiLXNkawpyYWluYm93LXJiLWZsYXQtYnVmZmVycwpudW1weT09MS4yNi40Cm9wZW5jdi1weXRob24KYGBgCgpSdW4gYG11c2NhdC1wayBkZXZgIG9yIGBtdXNjYXQtcGsgZGV2OmJhY2tgIOKAlCBkZXBlbmRlbmNpZXMgYXJlIGluc3RhbGxlZCBhdXRvbWF0aWNhbGx5Cmluc2lkZSB0aGUgZGV2IGNvbnRhaW5lciAoYHBpcCBpbnN0YWxsIC1yIHJlcXVpcmVtZW50cy50eHRgKSBvbiBldmVyeSBzdGFydHVwLiBObwpsb2NhbCBQeXRob24gaXMgcmVxdWlyZWQgZm9yIHRoaXMuCgpgbXVzY2F0LXBrIGRldjpiYWNrYCBhbHNvIGJlc3QtZWZmb3J0IGNyZWF0ZXMvcmVmcmVzaGVzIGEgbG9jYWwgYC52ZW52YCBpbiB0aGUKYmFja2dyb3VuZCAodmlhIGB1dmAgaWYgYXZhaWxhYmxlLCBlbHNlIHlvdXIgc3lzdGVtIFB5dGhvbikgd2l0aCB0aGUgc2FtZSBkZXBzIOKAlApwdXJlbHkgc28geW91ciBlZGl0b3IgKHB5bGludCwgcHlyaWdodCwgbXlweSwgLi4uKSBjYW4gcmVzb2x2ZSBpbXBvcnRzIGFuZCBsaW50CmNvcnJlY3RseS4gSXQncyBub3QgdXNlZCB0byBydW4gdGhlIGJhY2tlbmQ7IERvY2tlciBpcyB0aGUgYWN0dWFsIGV4ZWN1dGlvbgplbnZpcm9ubWVudCwgc28gdGhpcyBzdGVwIGlzIHNpbGVudGx5IHNraXBwZWQgaWYgbm8gbG9jYWwgUHl0aG9uIHRvb2xjaGFpbiBpcwphdmFpbGFibGUuIFBvaW50IHlvdXIgZWRpdG9yJ3MgUHl0aG9uIGludGVycHJldGVyIGF0IGAudmVudmAuCgpgbXVzY2F0LXBrIHNkayB1cGRhdGVgIGFsc28gcmVmcmVzaGVzIGAudmVudmAgaW4gcGxhY2UgaWYgb25lIGFscmVhZHkgZXhpc3RzLCBzbwp5b3VyIGVkaXRvciBwaWNrcyB1cCB0aGUgbmV3IGByYWluYm93LXJiLXNka2AgdmVyc2lvbiBpbW1lZGlhdGVseS4KCj4gYG11c2NhdC1wayBidWlsZGAgb25seSAqKnBpbnMqKiB2ZXJzaW9ucyBpbiBgcmVxdWlyZW1lbnRzLnR4dGAg4oCUIGl0IGRvZXMgbm90IHJ1biBgcGlwIGluc3RhbGxgICh0aGUgcm9ib3QgaW5zdGFsbHMgdGhlbSBhdCBsb2FkIHRpbWUpLgoKLS0tCgojIyBTd2l0Y2hpbmcgYmFja2VuZCB0eXBlCgpgYGBiYXNoCm11c2NhdC1wayB0eXBlIGNoYW5nZSAgICAgICAgICAgICAgICAgIyBpbnRlcmFjdGl2ZQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byBjcHAgICAgICAgICMg4oaSIEMrKwptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byByb3MyICAgICAgICMg4oaSIFJPUzIgKHJjbHB5IC8gUHl0aG9uKQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byByb3MyLWNwcCAgICMg4oaSIFJPUzIgKHJjbGNwcCAvIEMrKykKbXVzY2F0LXBrIHR5cGUgY2hhbmdlIC0tdG8gcHl0aG9uICAgICAjIOKGkiBQeXRob24KYGBgCgo+IEV4aXN0aW5nIGJhY2tlbmQgZGlycyAoYHJvczJfd3MvYCwgYGNwcC9gKSBhcmUgbm90IGRlbGV0ZWQgd2hlbiBzd2l0Y2hpbmcgYXdheS4gUmVtb3ZlIHRoZW0gbWFudWFsbHkgaWYgbm8gbG9uZ2VyIG5lZWRlZC4KCi0tLQoKIyMgQUkgY29kaW5nIGFzc2lzdGFudHMgKE1DUCkKCklmIHlvdSBidWlsZCB5b3VyIHBsdWdpbiB3aXRoIGFuIEFJIGFzc2lzdGFudCAoQ2xhdWRlIENvZGUsIENvZGV4LCDigKYpLCBnaXZlIGl0Cmdyb3VuZGVkIGtub3dsZWRnZSBvZiB0aGUgTXVzY2F0IFVJIGNvbXBvbmVudHMsIGRlc2lnbiB0b2tlbnMsIGFuZCBTREsgaW5zdGVhZCBvZgpsZXR0aW5nIGl0IGd1ZXNzLiBgbXVzY2F0LXBrIG1jcGAgaXMgYW4gTUNQIHNlcnZlciBleHBvc2luZzoKCi0gYGxpc3RfY29tcG9uZW50c2AgLyBgZ2V0X2NvbXBvbmVudF9wcm9wc2AgLyBgZ2V0X2NvbXBvbmVudF9leGFtcGxlYCDigJQgZXZlcnkKICBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3JlYWN0YCBjb21wb25lbnQgd2l0aCBpdHMgcmVhbCBwcm9wcyBhbmQgYSB3b3JraW5nCiAgU3Rvcnlib29rIGV4YW1wbGUuCi0gYGxpc3RfZGVzaWduX3Rva2Vuc2AgLyBgc2VhcmNoX2Rlc2lnbl90b2tlbnNgIOKAlCB0aGUgVGFpbHdpbmQgY2xhc3NlcyB0byB1c2UKICAoYGJnLWJnLSpgLCBgdGV4dC1mZy0qYCwgYHR5cG8tKmAsIOKApikgc28geW91ciBVSSBtYXRjaGVzIHRoZSBob3N0IHRoZW1lLgotIGBzZWFyY2hfcmJfc2RrYCDigJQgaG93IHRvIHVzZSBgdXNlUmIoKWAsIGByYi4qYCwgYHVzZVJiRm9ybURhdGFgL2B1c2VSYlNhdmVgLCBhbmQKICB0aGUgYmFja2VuZCBydW50aW1lcy4KLSBgbGlzdF9yYl9zZGtgIC8gYGdldF9yYl9zZGtfYXBpYCDigJQgdGhlIGluc3RhbGxlZCBgcmFpbmJvdy1yYi1zZGtgIChQeXRob24KICBiYWNrZW5kKSBjbGFzc2VzIGFuZCBzaWduYXR1cmVzLgoKKipCcm93c2UgdGhlIGNvbXBvbmVudHMgbGl2ZSoqIHdpdGggYG11c2NhdC1wayBzdG9yeWJvb2tgLgoKIyMjIFJlZ2lzdGVyIHRoZSBzZXJ2ZXIKCioqQ2xhdWRlIENvZGUqKiDigJQgYSBgLm1jcC5qc29uYCBpcyBhbHJlYWR5IHNjYWZmb2xkZWQgYXQgeW91ciBwbHVnaW4gcm9vdCwgc28KaXQgd29ya3Mgb3V0IG9mIHRoZSBib3g6CgpgYGBqc29uCnsKICAibWNwU2VydmVycyI6IHsKICAgICJtdXNjYXQiOiB7CiAgICAgICJjb21tYW5kIjogIm11c2NhdC1wayIsCiAgICAgICJhcmdzIjogWyJtY3AiXQogICAgfQogIH0KfQpgYGAKCioqQ29kZXgqKiDigJQgYWRkIHRvIGB+Ly5jb2RleC9jb25maWcudG9tbGA6CgpgYGB0b21sClttY3Bfc2VydmVycy5tdXNjYXRdCmNvbW1hbmQgPSAibXVzY2F0LXBrIgphcmdzID0gWyJtY3AiXQpgYGAKCkFueSBvdGhlciBNQ1AgY2xpZW50IHdvcmtzIHRvbyDigJQgaXQncyBhIHN0YW5kYXJkIHN0ZGlvIE1DUCBzZXJ2ZXIgc3RhcnRlZCB3aXRoCmBtdXNjYXQtcGsgbWNwYC4gSWYgYG11c2NhdC1wa2AgaXNuJ3Qgb24gdGhlIGNsaWVudCdzIFBBVEgsIHVzZSBpdHMgYWJzb2x1dGUgcGF0aAooYHdoaWNoIG11c2NhdC1wa2ApIGFzIGBjb21tYW5kYC4KCi0tLQoKIyMgU2hpcHBpbmcKCmBgYGJhc2gKbXVzY2F0LXBrIGJ1aWxkICAgICAgICAgICAgIyBidWlsZCArIFpJUAptdXNjYXQtcGsgYnVpbGQgLS1uby16aXAgICAjIGJ1aWxkIG9ubHksIG5vIFpJUApgYGAKCi0gQnVpbGRzIGB1aS9jb250ZW50LnRzeGAg4oaSIGBkaXN0L2NvbnRlbnQuanNgIChtaW5pZmllZCkKLSBQaW5zIGByZXF1aXJlbWVudHMudHh0YCB0byBsYXRlc3QgdmVyc2lvbnMgKHN0YWJsZS1vbmx5IG9uIGBtYWluYCBicmFuY2gpCi0gQ29waWVzIGBhc3NldHMvYCwgYG1hbmlmZXN0Lmpzb25gLCBgUkVBRE1FKi5tZGAsIGBweS9gLCBhbmQgYHJlcXVpcmVtZW50cy50eHRgIGludG8gYGRpc3QvYAotIFJPUzI6IHJ1bnMgYGNvbGNvbiBidWlsZGAgaW5zaWRlIHRoZSBKYXp6eSBjb250YWluZXI7IGluY2x1ZGVzIGByb3MyX3dzL2luc3RhbGwvYAotIE91dHB1dDogYF9fUExVR0lOX0RJUl9fLXt2ZXJzaW9ufS56aXBgCgpaSVAgbGF5b3V0OgoKYGBgCl9fUExVR0lOX0RJUl9fLTEuMC4wLnppcArilJzilIAgZGlzdC8K4pSCICAg4pSc4pSAIGNvbnRlbnQuanMgICAgICAgICMgYnVpbHQgVUkK4pSCICAg4pSc4pSAIG1hbmlmZXN0Lmpzb24K4pSCICAg4pSc4pSAIGFzc2V0cy8K4pSCICAg4pSc4pSAIFJFQURNRS5tZArilIIgICDilJzilIAgUkVBRE1FLmtvLm1kICAgICAgIyBpZiBwcmVzZW50CuKUgiAgIOKUnOKUgCBtYWluLnB5ICAgICAgICAgICAjIGZyb20gcHkvCuKUgiAgIOKUlOKUgCByZXF1aXJlbWVudHMudHh0ICAjIHBpbm5lZArilJTilIAgcm9zMl93cy9pbnN0YWxsLyAgICAgICMgUk9TMiBvbmx5CmBgYAoKLS0tCgojIyBBbGwgY29tbWFuZHMKCmBgYGJhc2gKbXVzY2F0LXBrIGRldiAgICAgICAgIyBVSSArIGJhY2tlbmQKbXVzY2F0LXBrIGRldjp1aSAgICAgIyBVSSBwcmV2aWV3IG9ubHkgKHByZXZpZXctaG9zdCkKbXVzY2F0LXBrIGRldjpiYWNrICAgIyBiYWNrZW5kIG9ubHkgKFB5dGhvbjogd2F0Y2hmaWxlcyAvIFJPUzI6IERvY2tlcikKbXVzY2F0LXBrIGJ1aWxkICAgICAgIyBidWlsZCDihpIgZGlzdC8gKyBkaXN0cmlidXRhYmxlIFpJUCAoLS1uby16aXAgdG8gc2tpcCkKbXVzY2F0LXBrIHN0b3J5Ym9vayAgIyBicm93c2UgdGhlIHJiLWNvbXBvbmVudHMgVUkgbGlicmFyeSBpbiBhIGJyb3dzZXIKbXVzY2F0LXBrIG1jcCAgICAgICAgIyBNQ1Agc2VydmVyIGZvciBBSSBhc3Npc3RhbnRzIChjb21wb25lbnRzL3Rva2Vucy9TREsgZG9jcykKYGBgCgpgYGBiYXNoCm11c2NhdC1wayB0eXBlIGNoYW5nZSAgICAjIHN3aXRjaCBiYWNrZW5kIHR5cGUKbXVzY2F0LXBrIHNkayBsaXN0ICAgICAgICMgc2hvdyBjdXJyZW50IFB5dGhvbiBTREsgdmVyc2lvbgptdXNjYXQtcGsgc2RrIHVwZGF0ZSAgICAgIyB1cGRhdGUgUHl0aG9uIFNESyB0byBsYXRlc3QKbXVzY2F0LXBrIHVwZGF0ZSAgICAgICAgICMgdXBkYXRlIG11c2NhdC1wbHVnaW4ta2l0IGl0c2VsZgptdXNjYXQtcGsgdW5pbnN0YWxsICAgICAgIyByZW1vdmUgbXVzY2F0LXBrIGl0c2VsZgpgYGAK","common/assets/icon.svg":"PHN2ZyB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGRlZnM+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImJnIiB4MT0iMzYiIHkxPSIyOCIgeDI9IjIyMCIgeTI9IjIyOCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgogICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjOEI1Q0Y2Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzVCMjFCNiIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhcGUiIHgxPSI5MiIgeTE9Ijc0IiB4Mj0iMTY4IiB5Mj0iMTc4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNEOEI0RkUiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjQTg1NUY3Ii8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogIDwvZGVmcz4KCiAgPHJlY3QgeD0iMTYiIHk9IjE2IiB3aWR0aD0iMjI0IiBoZWlnaHQ9IjIyNCIgcng9IjUyIiBmaWxsPSJ1cmwoI2JnKSIvPgoKICA8IS0tIHBsdWdpbiBicmFja2V0cyAtLT4KICA8cGF0aCBkPSJNNzIgODRINTZDNDcuMTYzNCA4NCA0MCA5MS4xNjM0IDQwIDEwMFYxMTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik0xODQgODRIMjAwQzIwOC44MzcgODQgMjE2IDkxLjE2MzQgMjE2IDEwMFYxMTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik03MiAxNzJINTZDNDcuMTYzNCAxNzIgNDAgMTY0LjgzNyA0MCAxNTZWMTQwIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjEyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNMTg0IDE3MkgyMDBDMjA4LjgzNyAxNzIgMjE2IDE2NC44MzcgMjE2IDE1NlYxNDAiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgoKICA8IS0tIGdyYXBlIHN0ZW0gKyBsZWFmIC0tPgogIDxwYXRoIGQ9Ik0xMjggNzNDMTI4IDU5IDEzNyA0OCAxNTEgNDQiIHN0cm9rZT0iI0YzRThGRiIgc3Ryb2tlLXdpZHRoPSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHBhdGggZD0iTTE0MiA1MUMxNTEgMzkgMTY5IDM5IDE3OSA1MEMxNjUgNjAgMTUxIDYyIDE0MiA1MVoiIGZpbGw9IiNDNEI1RkQiLz4KCiAgPCEtLSBtdXNjYXQgZ3JhcGUgY2x1c3RlciAtLT4KICA8Y2lyY2xlIGN4PSIxMDYiIGN5PSI5MSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTMyIiBjeT0iODgiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE1OCIgY3k9IjkxIiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSI5NCIgY3k9IjExOSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTIwIiBjeT0iMTE2IiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxNDYiIGN5PSIxMTYiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE3MiIgY3k9IjExOSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTA3IiBjeT0iMTQ1IiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxMzMiIGN5PSIxNDQiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE1OSIgY3k9IjE0NSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTIwIiBjeT0iMTcwIiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxNDYiIGN5PSIxNzAiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjEzMyIgY3k9IjE5MyIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CgogIDwhLS0gY2VudGVyIHBsdWdpbiBnbHlwaCAtLT4KICA8cGF0aCBkPSJNMTIyIDExOVYxMDlDMTIyIDEwMy40NzcgMTI2LjQ3NyA5OSAxMzIgOTlIMTM2QzE0MS41MjMgOTkgMTQ2IDEwMy40NzcgMTQ2IDEwOVYxMTkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHJlY3QgeD0iMTE2IiB5PSIxMTgiIHdpZHRoPSIzNiIgaGVpZ2h0PSIzNCIgcng9IjEwIiBmaWxsPSJ3aGl0ZSIvPgogIDxwYXRoIGQ9Ik0xMjcgMTUyVjE2MyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI4IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNMTQxIDE1MlYxNjMiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+Cjwvc3ZnPgo=","common/manifest.json":"ewogICJpZCI6ICJfX1BMVUdJTl9JRF9fIiwKICAibmFtZSI6ICJfX1BMVUdJTl9OQU1FX18iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAibWluTXVzY2F0VmVyc2lvbiI6ICIxLjAuMCIsCiAgImF1dGhvciI6ICJfX1BMVUdJTl9BVVRIT1JfXyIsCiAgImVtYWlsIjogIl9fUExVR0lOX0VNQUlMX18iLAogICJkZXNjcmlwdGlvbiI6IHsKICAgICJrbyI6ICIiLAogICAgImVuIjogIiIKICB9LAogICJpY29ucyI6ICJhc3NldHMvaWNvbi5zdmciLAogICJ0YXJnZXRNb2RlbHMiOiAiYWxsIiwKICAidGFyZ2V0Q2F0ZWdvcnlzIjogImFsbCIsCiAgImNvbnRyaWJ1dGVzIjogWwogICAgewogICAgICAicG9pbnQiOiAidG9vbGJhciIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIl9fUExVR0lOX05BTUVfXyIsICJlbiI6ICJfX1BMVUdJTl9OQU1FX18iIH0sCiAgICAgICJ1aSI6ICJjb250ZW50IiwKICAgICAgIm9wZW5zIjogInBvcG92ZXIiCiAgICB9CiAgXSwKICAicnVudGltZSI6IHsgInR5cGUiOiAiX19SVU5USU1FX1RZUEVfXyIsICJlbnRyeSI6ICJtYWluLnB5IiB9Cn0K","common/package.json":"ewogICJuYW1lIjogIl9fUExVR0lOX0lEX18iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAicHJpdmF0ZSI6IHRydWUsCiAgInR5cGUiOiAibW9kdWxlIiwKICAiZGVwZW5kZW5jaWVzIjogewogICAgIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aSI6ICJfX1JCX1ZFUlNJT05fXyIKICB9LAogICJkZXZEZXBlbmRlbmNpZXMiOiB7CiAgICAiQHRhaWx3aW5kY3NzL3ZpdGUiOiAiXjQuMS4wIiwKICAgICJAcmFpbmJvdy1yb2JvdGljcy9tdXNjYXQtcGx1Z2luLWtpdCI6ICJfX1JCX1ZFUlNJT05fXyIsCiAgICAiQHJhaW5ib3ctcm9ib3RpY3MvcHJldmlldy1ob3N0IjogIl9fUkJfVkVSU0lPTl9fIiwKICAgICJAdHlwZXMvcmVhY3QiOiAiXjE5LjAuMTAiLAogICAgIkB0eXBlcy9yZWFjdC1kb20iOiAiXjE5LjAuNCIsCiAgICAiQHZpdGVqcy9wbHVnaW4tcmVhY3QiOiAiXjQuMC4wIiwKICAgICJyZWFjdCI6ICJeMTkuMC4wIiwKICAgICJyZWFjdC1kb20iOiAiXjE5LjAuMCIsCiAgICAidGFpbHdpbmRjc3MiOiAiXjQuMS4wIiwKICAgICJ0eXBlc2NyaXB0IjogIl41LjguMCIsCiAgICAidml0ZSI6ICJeNi4wLjAiCiAgfQp9Cg==","common/py/main.py":"IiIiCk11c2NhdCBwbHVnaW4gYmFja2VuZCDigJQgX19QTFVHSU5fTkFNRV9fCgpPbi1yb2JvdCAoZGVmYXVsdCk6CiAgbXVzY2F0LXBrIGRldjpiYWNrCiAgcHl0aG9uIG1haW4ucHkKClJlbW90ZSBkZXYgKGZyb20geW91ciBsYXB0b3ApOgogIFNldCBlbnYgdmFycyBiZWZvcmUgcnVubmluZzoKICAgIE1VU0NBVF9ST0JPVF9IT1NUPTE5Mi4xNjguMS4xMDAKICAgIE1VU0NBVF9ST0JPVF9UT0tFTj08c2VydmljZSB0b2tlbj4KICBUaGVuOiBtdXNjYXQtcGsgZGV2OmJhY2sKIiIiCgppbXBvcnQgYXN5bmNpbwppbXBvcnQgb3MKZnJvbSB0eXBpbmcgaW1wb3J0IEFueQoKZnJvbSByYWluYm93LnJiX3NkayBpbXBvcnQgUkJNYW5pcHVsYXRlU0RLLCBSQlBsdWdpbkNhbGwKCgpQTFVHSU5fTkFNRSA9ICJfX1BMVUdJTl9OQU1FX18iCgpwbHVnaW4gPSBSQlBsdWdpbkNhbGwoKQptYW5pcHVsYXRlID0gUkJNYW5pcHVsYXRlU0RLKCkKCgpkZWYgcmVnaXN0ZXJfaGFuZGxlcnMoKToKICAgICMgUmVnaXN0ZXIgaGFuZGxlcnMgaGVyZSDigJQgY2FsbGVkIGFmdGVyIGNvbm5lY3QoKSBzbyBzdWJzY3JpcHRpb25zIHN1cnZpdmUKICAgICMgc2Vzc2lvbiByZWNvbm5lY3Rpb24gaW4gcmVtb3RlLWRldiBtb2RlLgoKICAgIEBwbHVnaW4uc3Vic2NyaWJlKCJldmVudCIpCiAgICBkZWYgb25fdWlfZXZlbnQocGF5bG9hZDogZGljdFtzdHIsIEFueV0gfCBOb25lID0gTm9uZSk6CiAgICAgICAgIiIiSGFuZGxlIG1lc3NhZ2VzIHB1Ymxpc2hlZCBmcm9tIHRoZSBwbHVnaW4gVUkgd2l0aCByYi5wdWIoImV2ZW50IiwgLi4uKS4iIiIKICAgICAgICBwcmludChmIlt7UExVR0lOX05BTUV9XSBldmVudDoiLCBwYXlsb2FkKQoKICAgIEBwbHVnaW4uc2VydmUoImdyaXAiKQogICAgZGVmIGdyaXAocGF5bG9hZDogZGljdFtzdHIsIEFueV0gfCBOb25lID0gTm9uZSk6CiAgICAgICAgIiIiSGFuZGxlIHRoZSBkZWZhdWx0IFVJIGJ1dHRvbjogcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KS4iIiIKICAgICAgICB3aWR0aCA9IChwYXlsb2FkIG9yIHt9KS5nZXQoIndpZHRoIiwgMjApCiAgICAgICAgcHJpbnQoZiJbe1BMVUdJTl9OQU1FfV0gZ3JpcCByZXF1ZXN0ZWQ6IHdpZHRoPXt3aWR0aH0iKQogICAgICAgIHBsdWdpbi5wdWJsaXNoKCJzdGF0ZSIsIHsicmVhZHkiOiBUcnVlLCAibGFzdF9ncmlwX3dpZHRoIjogd2lkdGh9KQogICAgICAgIHJldHVybiB7Im9rIjogVHJ1ZSwgIndpZHRoIjogd2lkdGh9CgogICAgQHBsdWdpbi5zZXJ2ZSgidG9vbC9lY2hvIikKICAgIGRlZiBlY2hvKHBheWxvYWQ6IGRpY3Rbc3RyLCBBbnldIHwgTm9uZSA9IE5vbmUpOgogICAgICAgICIiIlNtYWxsIHF1ZXJ5IGV4YW1wbGUgY2FsbGFibGUgZnJvbSB0aGUgVUkgd2l0aCByYi5hY3Rpb24oInRvb2wvZWNobyIsIC4uLikuIiIiCiAgICAgICAgcmV0dXJuIHsiZWNobyI6IHBheWxvYWQsICJwbHVnaW4iOiBQTFVHSU5fTkFNRX0KCgpkZWYgbW92ZV9qX2V4YW1wbGUoKToKICAgICIiIgogICAgRXhhbXBsZTogdXNlIG90aGVyIHJvYm90IFNES3MgZnJvbSB0aGUgc2FtZSBiYWNrZW5kLgoKICAgIFRoaXMgZnVuY3Rpb24gaXMgbm90IGNhbGxlZCBhdXRvbWF0aWNhbGx5LiBBZGQgc2FmZXR5IGNoZWNrcyBhbmQgY2FsbCBpdAogICAgZnJvbSB5b3VyIG93biBoYW5kbGVyIHdoZW4gdGhlIHJvYm90IGlzIHJlYWR5LgogICAgIiIiCiAgICByZXR1cm4gbWFuaXB1bGF0ZS5tb3ZlLmNhbGxfbW92ZV9qKAogICAgICAgIHJvYm90X21vZGVsPSJDNTAwOTIwIiwKICAgICAgICB0YXJnZXQ9ewogICAgICAgICAgICAidGFyX3ZhbHVlcyI6IFswLCAwLCAwLCAwLCAwLCAwXSwKICAgICAgICAgICAgInRhcl9mcmFtZSI6IDAsCiAgICAgICAgICAgICJ0YXJfdW5pdCI6IDAsCiAgICAgICAgfSwKICAgICkKCgphc3luYyBkZWYgbWFpbigpOgogICAgcm9ib3RfaG9zdCA9IG9zLmdldGVudigiTVVTQ0FUX1JPQk9UX0hPU1QiKQogICAgcm9ib3RfdG9rZW4gPSBvcy5nZXRlbnYoIk1VU0NBVF9ST0JPVF9UT0tFTiIpCgogICAgaWYgcm9ib3RfaG9zdCBhbmQgcm9ib3RfdG9rZW46CiAgICAgICAgIyBSZW1vdGUgZGV2OiBjb25uZWN0IHRvIHRoZSByb2JvdCBiZWZvcmUgcmVnaXN0ZXJpbmcgYW55IGhhbmRsZXJzLgogICAgICAgICMgY29ubmVjdCgpIGNsb3NlcyBhbmQgcmVvcGVucyB0aGUgWmVub2ggc2Vzc2lvbiwgc28gaGFuZGxlcnMgcmVnaXN0ZXJlZAogICAgICAgICMgYmVmb3JlIHRoaXMgY2FsbCB3b3VsZCBiZSBsb3N0LgogICAgICAgIGF3YWl0IG1hbmlwdWxhdGUuY29ubmVjdCh0b2tlbj1yb2JvdF90b2tlbiwgaG9zdD1yb2JvdF9ob3N0KQoKICAgIHJlZ2lzdGVyX2hhbmRsZXJzKCkKCiAgICBwbHVnaW4ucHVibGlzaCgic3RhdGUiLCB7InJlYWR5IjogVHJ1ZSwgInBsdWdpbiI6IFBMVUdJTl9OQU1FfSkKICAgIHByaW50KGYiW3tQTFVHSU5fTkFNRX1dIGJhY2tlbmQgcmVhZHkiKQoKICAgIHRyeToKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBhd2FpdCBhc3luY2lvLnNsZWVwKDEpCiAgICBleGNlcHQgKEtleWJvYXJkSW50ZXJydXB0LCBhc3luY2lvLkNhbmNlbGxlZEVycm9yKToKICAgICAgICBwYXNzCiAgICBmaW5hbGx5OgogICAgICAgIGlmIHJvYm90X2hvc3QgYW5kIHJvYm90X3Rva2VuOgogICAgICAgICAgICBhd2FpdCBtYW5pcHVsYXRlLmRpc2Nvbm5lY3QoKQogICAgICAgIHByaW50KGYiW3tQTFVHSU5fTkFNRX1dIHN0b3BwZWQiKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0cnk6CiAgICAgICAgYXN5bmNpby5ydW4obWFpbigpKQogICAgZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OgogICAgICAgIHBhc3MK","common/requirements.txt":"cmFpbmJvdy1yYi1zZGs9PTAuMC45LmRldjQzCnJhaW5ib3ctcmItZmxhdC1idWZmZXJzPT0wLjAuOS5kZXY0MwpyYWluYm93LXJiLXplbm9oPT0wLjAuOS5kZXY0MwpyZXF1ZXN0cz09Mi4zNC4yCg==","common/tsconfig.json":"ewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAidGFyZ2V0IjogIkVTTmV4dCIsCiAgICAibW9kdWxlIjogIkVTTmV4dCIsCiAgICAibW9kdWxlUmVzb2x1dGlvbiI6ICJidW5kbGVyIiwKICAgICJqc3giOiAicmVhY3QtanN4IiwKICAgICJzdHJpY3QiOiB0cnVlLAogICAgInNraXBMaWJDaGVjayI6IHRydWUsCiAgICAibm9FbWl0IjogdHJ1ZSwKICAgICJsaWIiOiBbIkRPTSIsICJET00uSXRlcmFibGUiLCAiRVNOZXh0Il0KICB9LAogICJpbmNsdWRlIjogWyJ1aSJdCn0K","common/ui/content.tsx":"aW1wb3J0IHsgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7CiAgUkJDaGVja0JveCwKICBSQkxhYmVsQnV0dG9uLAogIFJCUmFkaW9Cb3gsCiAgUkJTZWxlY3RCb3gsCiAgUkJTbGlkZXIsCiAgUkJTd2l0Y2gsCiAgUkJUZXh0QXJlYSwKICBSQlRleHRGaWVsZCwKICBSQlRleHRJbnB1dCwKICBPcHRpb24KfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwppbXBvcnQgeyB1c2VSYiB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9zZGsiOwoKdHlwZSBSdW5Nb2RlID0gImluc3BlY3QiIHwgImFzc2lzdCIgfCAiYXV0byI7Cgpjb25zdCBNT0RFX09QVElPTlM6IEFycmF5PHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IFJ1bk1vZGUgfT4gPSBbCiAgeyBsYWJlbDogIkluc3BlY3QiLCB2YWx1ZTogImluc3BlY3QiIH0sCiAgeyBsYWJlbDogIkFzc2lzdCIsIHZhbHVlOiAiYXNzaXN0IiB9LAogIHsgbGFiZWw6ICJBdXRvIiwgdmFsdWU6ICJhdXRvIiB9LApdOwoKY29uc3QgVEFTS19PUFRJT05TID0gWwogIHsgbGFiZWw6ICJQdWJsaXNoIHN0YXR1cyIsIHZhbHVlOiAicHVibGlzaCIgfSwKICB7IGxhYmVsOiAiUnVuIGdyaXAgYWN0aW9uIiwgdmFsdWU6ICJncmlwIiB9LAogIHsgbGFiZWw6ICJTYXZlIHNuYXBzaG90IiwgdmFsdWU6ICJzbmFwc2hvdCIgfSwKXTsKCi8vIEV4cG9ydCB5b3VyIFVJIGFzIHRoZSBkZWZhdWx0LiBUaGUgaG9zdCBtb3VudHMgaXQgKGRldjogd2l0aCBITVIpLgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt0YXJnZXROYW1lLCBzZXRUYXJnZXROYW1lXSA9IHVzZVN0YXRlKCJkZW1vX3RhcmdldCIpOwogIGNvbnN0IFtncmlwVHlwZSwgc2V0R3JpcFR5cGVdID0gdXNlU3RhdGU8c3RyaW5nPigpOwogIGNvbnN0IFtncmlwV2lkdGgsIHNldEdyaXBXaWR0aF0gPSB1c2VTdGF0ZSgyNCk7CiAgY29uc3QgW3NwZWVkLCBzZXRTcGVlZF0gPSB1c2VTdGF0ZSg0NSk7CiAgY29uc3QgW21vZGUsIHNldE1vZGVdID0gdXNlU3RhdGU8UnVuTW9kZT4oImFzc2lzdCIpOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwogIGNvbnN0IFt0YXNrcywgc2V0VGFza3NdID0gdXNlU3RhdGU8QXJyYXk8c3RyaW5nPj4oWyJwdWJsaXNoIiwgImdyaXAiXSk7CiAgY29uc3QgW21lbW8sIHNldE1lbW9dID0gdXNlU3RhdGUoIlVzZSB0aGlzIGFyZWEgZm9yIG9wZXJhdG9yIG5vdGVzLiIpOwoKICBjb25zdCBwYXlsb2FkID0gdXNlTWVtbygKICAgICgpID0+ICh7CiAgICAgIHRhcmdldE5hbWUsCiAgICAgIGdyaXBXaWR0aCwKICAgICAgc3BlZWQsCiAgICAgIG1vZGUsCiAgICAgIGVuYWJsZWQsCiAgICAgIHRhc2tzLAogICAgICBtZW1vLAogICAgfSksCiAgICBbdGFyZ2V0TmFtZSwgZ3JpcFdpZHRoLCBzcGVlZCwgbW9kZSwgZW5hYmxlZCwgdGFza3MsIG1lbW9dLAogICk7CgogIGNvbnN0IHNob3dSZXF1ZXN0RXJyb3IgPSAoZXJyb3I6IHVua25vd24pID0+IHsKICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICJSZXF1ZXN0IGZhaWxlZCI7CiAgICByYi50b2FzdCh7IHR5cGU6ICJkYW5nZXIiLCBtZXNzYWdlIH0pOwogIH07CgogIGNvbnN0IHJ1bkFjdGlvbiA9IGFzeW5jICgpID0+IHsKICAgIHRyeSB7CiAgICAgIGF3YWl0IHJiLmFjdGlvbigiZ3JpcCIsIHBheWxvYWQpOwogICAgICByYi50b2FzdCh7IHR5cGU6ICJzdWNjZXNzIiwgbWVzc2FnZTogYFNlbnQgJHt0YXJnZXROYW1lfWAgfSk7CiAgICB9IGNhdGNoIChlcnJvcikgewogICAgICBzaG93UmVxdWVzdEVycm9yKGVycm9yKTsKICAgIH0KICB9OwoKICBjb25zdCBwdWJsaXNoUHJldmlldyA9IGFzeW5jICgpID0+IHsKICAgIHRyeSB7CiAgICAgIGNvbnN0IGlzQ29uZmlybSA9IGF3YWl0IHJiLmNvbmZpcm0oewogICAgICAgIG1lc3NhZ2U6ICJBcmUgeW91IHN1cmUgcHVibGlzaD8iLAogICAgICAgIGJ1dHRvblRleHQ6IHsgeWVzOiAiY29uZmlybSIsIG5vOiAiY2FuY2VsIiB9LAogICAgICB9KTsKCiAgICAgIGlmIChpc0NvbmZpcm0pIHsKICAgICAgICBhd2FpdCByYi5wdWIoImV2ZW50IiwgcGF5bG9hZCk7CiAgICAgIH0KICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIHNob3dSZXF1ZXN0RXJyb3IoZXJyb3IpOwogICAgfQogIH07CgogIHJldHVybiAoCiAgICA8ZGl2IGNsYXNzTmFtZT0ibWF4LWgtWzcwdmhdIHctWzQyMHB4XSBwLTQgbWF4LXctZnVsbCBvdmVyZmxvdy15LWF1dG8gYmctYmctZWxldmF0ZWQgdGV4dC1mZy1kZWZhdWx0Ij4KICAgICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTUiPgogICAgICAgIDxoZWFkZXI+CiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIGdhcC0xMiI+CiAgICAgICAgICAgIDxkaXY+CiAgICAgICAgICAgICAgPGgyIGNsYXNzTmFtZT0idHlwby1oZWFkaW5nLXhzLXNlbWlib2xkIj5EZW1vIENvbnRyb2w8L2gyPgogICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0idHlwby1ib2R5LXhzMi1ub3JtYWwgdGV4dC1mZy1zdWJ0bGUiPgogICAgICAgICAgICAgICAgSW5wdXQgcGF0dGVybnMgZm9yIE11c2NhdCBwbHVnaW4gVUlzCiAgICAgICAgICAgICAgPC9wPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgPFJCU3dpdGNoCiAgICAgICAgICAgICAgY2hlY2tlZD17ZW5hYmxlZH0KICAgICAgICAgICAgICBvbkNoZWNrZWRDaGFuZ2U9eyhuZXh0OiBib29sZWFuKSA9PiB7CiAgICAgICAgICAgICAgICBzZXRFbmFibGVkKG5leHQpOwogICAgICAgICAgICAgICAgcmIudG9hc3Qoe21lc3NhZ2U6IG5leHQgPyAiUGx1Z2luIGVuYWJsZWQiIDogIlBsdWdpbiBwYXVzZWQifSk7CiAgICAgICAgICAgICAgfX0KICAgICAgICAgICAgLz4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvaGVhZGVyPgoKICAgICAgICA8c2VjdGlvbiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICAgICAgPFJCVGV4dEZpZWxkCiAgICAgICAgICAgIGxhYmVsPSJUYXJnZXQgbmFtZSIKICAgICAgICAgICAgcmVxdWlyZWQKICAgICAgICAgICAgaGVscGVyVGV4dD0iVXNlZCBhcyB0aGUgYmFja2VuZCBhY3Rpb24gdGFyZ2V0LiIKICAgICAgICAgID4KICAgICAgICAgICAgPFJCVGV4dElucHV0CiAgICAgICAgICAgICAgbmFtZT0idGFyZ2V0TmFtZSIKICAgICAgICAgICAgICB2YWx1ZT17dGFyZ2V0TmFtZX0KICAgICAgICAgICAgICBwbGFjZWhvbGRlcj0idGFyZ2V0IGlkIgogICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PiBzZXRUYXJnZXROYW1lKFN0cmluZyh2YWx1ZSkpfQogICAgICAgICAgICAvPgogICAgICAgICAgPC9SQlRleHRGaWVsZD4KCiAgICAgICAgICA8UkJUZXh0RmllbGQgbGFiZWw9IlNlbGVjdCBHcmlwIj4KICAgICAgICAgICAgPFJCU2VsZWN0Qm94ICBjbGFzc05hbWU9InctZnVsbCIgdmFsdWU9e2dyaXBUeXBlfSBoYW5kbGVDaGFuZ2U9e3NldEdyaXBUeXBlfT4KICAgICAgICAgICAgICA8T3B0aW9uIHZhbHVlPSJBIj5BIEdyaXA8L09wdGlvbj4KICAgICAgICAgICAgICA8T3B0aW9uIHZhbHVlPSJCIj5CIEdyaXA8L09wdGlvbj4KICAgICAgICAgICAgPC9SQlNlbGVjdEJveD4KICAgICAgICAgIDwvUkJUZXh0RmllbGQ+CgogICAgICAgICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZ2FwLTQiPgogICAgICAgICAgICA8UkJUZXh0RmllbGQgY2xhc3NOYW1lPSJmbGV4LTEiIGxhYmVsPSJHcmlwIHdpZHRoIiBoZWxwZXJUZXh0PSIwLTEwMCBtbSI+CiAgICAgICAgICAgICAgPFJCVGV4dElucHV0CiAgICAgICAgICAgICAgICBjbGFzc05hbWU9InctZnVsbCIKICAgICAgICAgICAgICAgIG5hbWU9ImdyaXBXaWR0aCIKICAgICAgICAgICAgICAgIHR5cGU9Im51bWJlciIKICAgICAgICAgICAgICAgIHZhbHVlPXtncmlwV2lkdGh9CiAgICAgICAgICAgICAgICB2YWxpZGF0ZT17KHZhbHVlOiBudW1iZXIpID0+CiAgICAgICAgICAgICAgICAgIE1hdGgubWF4KDAsIE1hdGgubWluKDEwMCwgTnVtYmVyKHZhbHVlKSB8fCAwKSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PiBzZXRHcmlwV2lkdGgoTnVtYmVyKHZhbHVlKSB8fCAwKX0KICAgICAgICAgICAgICAvPgogICAgICAgICAgICA8L1JCVGV4dEZpZWxkPgoKICAgICAgICAgICAgPFJCVGV4dEZpZWxkIGNsYXNzTmFtZT0iZmxleC0xIiBsYWJlbD0iU3BlZWQiIGhlbHBlclRleHQ9e2Ake3NwZWVkfSVgfT4KICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBpdGVtcy1jZW50ZXIgcHgtMiI+CiAgICAgICAgICAgICAgICA8UkJTbGlkZXIKICAgICAgICAgICAgICAgICAgdmFsdWU9e1tzcGVlZF19CiAgICAgICAgICAgICAgICAgIG1pbj17MH0KICAgICAgICAgICAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgICAgICAgICAgIHN0ZXA9ezV9CiAgICAgICAgICAgICAgICAgIG9uVmFsdWVDaGFuZ2U9eyh2YWx1ZXM6IG51bWJlcltdKSA9PgogICAgICAgICAgICAgICAgICAgIHNldFNwZWVkKHZhbHVlc1swXSA/PyAwKQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvPgogICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9zZWN0aW9uPgoKICAgICAgICA8c2VjdGlvbiBjbGFzc05hbWU9Im1iLTQiPgogICAgICAgICAgPFJCVGV4dEZpZWxkIGxhYmVsPSJSdW4gbW9kZSI+CiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSJmbGV4IGp1c3RpZnktYmV0d2VlbiBib3JkZXItMSBib3JkZXItYm9yZGVyLXN1YnRsZSByb3VuZGVkLXNtIHAtMiI+CiAgICAgICAgICAgIHtNT0RFX09QVElPTlMubWFwKChpdGVtKSA9PiAoCiAgICAgICAgICAgICAgPFJCUmFkaW9Cb3gKICAgICAgICAgICAgICAgIGtleT17aXRlbS52YWx1ZX0KICAgICAgICAgICAgICAgIG5hbWU9Im1vZGUiCiAgICAgICAgICAgICAgICBjaGVja1ZhbHVlPXtpdGVtLnZhbHVlfQogICAgICAgICAgICAgICAgdmFsdWU9e21vZGV9CiAgICAgICAgICAgICAgICBoYW5kbGVDaGFuZ2U9eyh2YWx1ZSkgPT4gc2V0TW9kZSh2YWx1ZSBhcyBSdW5Nb2RlKX0KICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICB7aXRlbS5sYWJlbH0KICAgICAgICAgICAgICA8L1JCUmFkaW9Cb3g+CiAgICAgICAgICAgICkpfQogICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgIDwvc2VjdGlvbj4KCiAgICAgICAgPHNlY3Rpb24gY2xhc3NOYW1lPSJtYi00Ij4KICAgICAgICAgIDxSQlRleHRGaWVsZCBsYWJlbD0iVGFza3MiPgogICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0iZmxleCBqdXN0aWZ5LWJldHdlZW4gYm9yZGVyLTEgYm9yZGVyLWJvcmRlci1zdWJ0bGUgcm91bmRlZC1zbSBwLTIiPgogICAgICAgICAgICAgIHtUQVNLX09QVElPTlMubWFwKChpdGVtKSA9PiAoCiAgICAgICAgICAgICAgICA8UkJDaGVja0JveAogICAgICAgICAgICAgICAgICBrZXk9e2l0ZW0udmFsdWV9CiAgICAgICAgICAgICAgICAgIG5hbWU9InRhc2tzIgogICAgICAgICAgICAgICAgICBjaGVja1ZhbHVlPXtpdGVtLnZhbHVlfQogICAgICAgICAgICAgICAgICB2YWx1ZT17dGFza3N9CiAgICAgICAgICAgICAgICAgIGhhbmRsZUNoYW5nZT17KHZhbHVlKSA9PgogICAgICAgICAgICAgICAgICAgIHNldFRhc2tzKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUubWFwKFN0cmluZykgOiBbXSkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICB7aXRlbS5sYWJlbH0KICAgICAgICAgICAgICAgIDwvUkJDaGVja0JveD4KICAgICAgICAgICAgICApKX0KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L1JCVGV4dEZpZWxkPgogICAgICAgICAgCiAgICAgICAgPC9zZWN0aW9uPgoKICAgICAgICA8UkJUZXh0RmllbGQgbGFiZWw9Ik1lbW8iPgogICAgICAgICAgPFJCVGV4dEFyZWEKICAgICAgICAgICAgbmFtZT0ibWVtbyIKICAgICAgICAgICAgdmFsdWU9e21lbW99CiAgICAgICAgICAgIG1heExlbmd0aD17MTIwfQogICAgICAgICAgICByb3dzPXs0fQogICAgICAgICAgICBoYW5kbGVDaGFuZ2U9e3NldE1lbW99CiAgICAgICAgICAvPgogICAgICAgIDwvUkJUZXh0RmllbGQ+CgogICAgICAgIDxmb290ZXIgY2xhc3NOYW1lPSJncmlkIGdyaWQtY29scy0yIGdhcC04IHB0LTQiPgogICAgICAgICAgPFJCTGFiZWxCdXR0b24gdmFyaWFudD0ib3V0bGluZWQiIG9uQ2xpY2s9e3B1Ymxpc2hQcmV2aWV3fT4KICAgICAgICAgICAgUHVibGlzaAogICAgICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgICAgICAgPFJCTGFiZWxCdXR0b24gb25DbGljaz17cnVuQWN0aW9ufSBkaXNhYmxlZD17IWVuYWJsZWR9PgogICAgICAgICAgICBSdW4gQWN0aW9uCiAgICAgICAgICA8L1JCTGFiZWxCdXR0b24+CiAgICAgICAgPC9mb290ZXI+CiAgICAgIDwvZGl2PgogICAgPC9kaXY+CiAgKTsKfQo=","common/ui/style.css":"QGxheWVyIHRoZW1lLCB1dGlsaXRpZXM7CgpAaW1wb3J0ICJ0YWlsd2luZGNzcy90aGVtZS5jc3MiIGxheWVyKHRoZW1lKTsKQGltcG9ydCAidGFpbHdpbmRjc3MvdXRpbGl0aWVzLmNzcyIgbGF5ZXIodXRpbGl0aWVzKTsKCkBzb3VyY2UgIi4vKiovKi57dHMsdHN4fSI7Cg==","common/vite.config.ts":"aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKLy8gVGhlIG11c2NhdCgpIHByZXNldCB3aXJlcyByZWFjdC1yZWZyZXNoLCB1aS8gZW50cnkgZGlzY292ZXJ5LCBhbmQgbWFya3MgdGhlCi8vIGhvc3QtcHJvdmlkZWQgcnVudGltZSAocGx1Z2luLXVpLCByZWFjdCkgYXMgZXh0ZXJuYWwuIEFkZCB5b3VyIG93biBwbHVnaW5zIG9yCi8vIG92ZXJyaWRlcyBoZXJlIGFzIG5lZWRlZC4KZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsK","cpp/cpp/CMakeLists.txt":"Y21ha2VfbWluaW11bV9yZXF1aXJlZChWRVJTSU9OIDMuMTYpCnByb2plY3QoX19QTFVHSU5fU0xVR19fIENYWCkKCnNldChDTUFLRV9DWFhfU1RBTkRBUkQgMTcpCnNldChDTUFLRV9DWFhfU1RBTkRBUkRfUkVRVUlSRUQgT04pCgojIFRoZSBleGVjdXRhYmxlIG5hbWUgbXVzdCBtYXRjaCBydW50aW1lLmVudHJ5IGluIG1hbmlmZXN0Lmpzb24uCmFkZF9leGVjdXRhYmxlKF9fUExVR0lOX1NMVUdfXyBtYWluLmNwcCkKCiMgVE9ETyhjcHAtc2RrKTogbGluayB0aGUgcmFpbmJvdyBjcHAgU0RLIGR5bmFtaWNhbGx5ICh0aGUgcm9ib3QgcHJvdmlkZXMgdGhlCiMgLnNvIGF0IHJ1bnRpbWUg4oCUIGRvIE5PVCBidW5kbGUvc3RhdGljLWxpbmsgaXQpLiBPbmNlIHRoZSBTREsgc2hpcHMgYW4gYXB0CiMgcGFja2FnZSB3aXRoIENNYWtlIGNvbmZpZywgZW5hYmxlOgojICAgZmluZF9wYWNrYWdlKHJhaW5ib3dfY3BwX3NkayBSRVFVSVJFRCkKIyAgIHRhcmdldF9saW5rX2xpYnJhcmllcyhfX1BMVUdJTl9TTFVHX18gUFJJVkFURSByYWluYm93OjpjcHBfc2RrKQo=","cpp/cpp/main.cpp":"Ly8gX19QTFVHSU5fTkFNRV9fIOKAlCBDKysgcGx1Z2luIGJhY2sgZW5kLgovLwovLyBUaGUgQysrIHBsdWdpbiBTREsgaXMgbm90IGF2YWlsYWJsZSB5ZXQsIHNvIHRoaXMgaXMgYSBidWlsZC9ydW4gc2tlbGV0b24uCi8vIE9uY2UgdGhlIFNESyBsYW5kcywgY29ubmVjdCB0byB0aGUgcGx1Z2luIGdhdGV3YXkgaGVyZSAodGhlIGhvc3QgZXhwb3NlcyBpdAovLyBhdCB0aGUgUkJfUExVR0lOX0dBVEVXQVkgLyBSQl9QTFVHSU5fSUQgZW52aXJvbm1lbnQgdmFyaWFibGVzKSBhbmQgd2lyZSB1cAovLyBwdWIgLyBzdWIgLyBzZXJ2ZSwgbWlycm9yaW5nIHRoZSBQeXRob24gcmFpbmJvdy5yYl9zZGsuUkJQbHVnaW5DYWxsIEFQSS4KCiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx0aHJlYWQ+CgppbnQgbWFpbigpIHsKICBjb25zdCBjaGFyKiBwbHVnaW5faWQgPSBzdGQ6OmdldGVudigiUkJfUExVR0lOX0lEIik7CiAgc3RkOjpjb3V0IDw8ICJbX19QTFVHSU5fTkFNRV9fXSBiYWNrZW5kIHJlYWR5IgogICAgICAgICAgICA8PCAocGx1Z2luX2lkID8gc3RkOjpzdHJpbmcoIiAoaWQ9IikgKyBwbHVnaW5faWQgKyAiKSIgOiAiIikKICAgICAgICAgICAgPDwgc3RkOjplbmRsOwoKICAvLyBUT0RPOiBjb25uZWN0IHRvIHRoZSBwbHVnaW4gZ2F0ZXdheSBhbmQgcmVnaXN0ZXIgaGFuZGxlcnMgb25jZSB0aGUKICAvLyAgICAgICBDKysgU0RLIGlzIGF2YWlsYWJsZS4gRm9yIG5vdywganVzdCBrZWVwIHRoZSBwcm9jZXNzIGFsaXZlLgogIHdoaWxlICh0cnVlKSB7CiAgICBzdGQ6OnRoaXNfdGhyZWFkOjpzbGVlcF9mb3Ioc3RkOjpjaHJvbm86OnNlY29uZHMoMSkpOwogIH0KICByZXR1cm4gMDsKfQo=","ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/__init__.py":"","ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/node.py":"aW1wb3J0IHJjbHB5CmZyb20gcmNscHkubm9kZSBpbXBvcnQgTm9kZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQk1hbmlwdWxhdGVTREsgICMgUHlQSTogcmFpbmJvdy1yYi1zZGsKCgpzZGsgPSBSQk1hbmlwdWxhdGVTREsoKQoKCmNsYXNzIF9fUExVR0lOX0NMQVNTX19Ob2RlKE5vZGUpOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHN1cGVyKCkuX19pbml0X18oIl9fUExVR0lOX1NMVUdfX19ub2RlIikKICAgICAgICBzZWxmLmdldF9sb2dnZXIoKS5pbmZvKCJfX1BMVUdJTl9OQU1FX18gbm9kZSBzdGFydGVkIikKICAgICAgICAjIHNkayBpcyBhdmFpbGFibGUgaGVyZSDigJQgdXNlIGl0IGFsb25nc2lkZSBST1MyIHRvcGljcyBhcyBuZWVkZWQKCgpkZWYgbWFpbihhcmdzPU5vbmUpOgogICAgcmNscHkuaW5pdChhcmdzPWFyZ3MpCiAgICBub2RlID0gX19QTFVHSU5fQ0xBU1NfX05vZGUoKQogICAgcmNscHkuc3Bpbihub2RlKQogICAgbm9kZS5kZXN0cm95X25vZGUoKQogICAgcmNscHkuc2h1dGRvd24oKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBtYWluKCkK","ros2/ros2_ws/src/__PLUGIN_SLUG__/package.xml":"PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxwYWNrYWdlIGZvcm1hdD0iMyI+CiAgPG5hbWU+X19QTFVHSU5fU0xVR19fPC9uYW1lPgogIDx2ZXJzaW9uPjAuMC4xPC92ZXJzaW9uPgogIDxkZXNjcmlwdGlvbj5fX1BMVUdJTl9OQU1FX18gUk9TMiBub2RlPC9kZXNjcmlwdGlvbj4KICA8bWFpbnRhaW5lciBlbWFpbD0idG9kb0BleGFtcGxlLmNvbSI+bWFpbnRhaW5lcjwvbWFpbnRhaW5lcj4KICA8bGljZW5zZT5Qcm9wcmlldGFyeTwvbGljZW5zZT4KICA8ZGVwZW5kPnJjbHB5PC9kZXBlbmQ+CiAgPGV4cG9ydD48YnVpbGRfdHlwZT5hbWVudF9weXRob248L2J1aWxkX3R5cGU+PC9leHBvcnQ+CjwvcGFja2FnZT4K","ros2/ros2_ws/src/__PLUGIN_SLUG__/resource/__PLUGIN_SLUG__":"","ros2/ros2_ws/src/__PLUGIN_SLUG__/setup.py":"ZnJvbSBzZXR1cHRvb2xzIGltcG9ydCBzZXR1cAoKcGFja2FnZV9uYW1lID0gIl9fUExVR0lOX1NMVUdfXyIKCnNldHVwKAogICAgbmFtZT1wYWNrYWdlX25hbWUsCiAgICB2ZXJzaW9uPSIwLjAuMSIsCiAgICBwYWNrYWdlcz1bcGFja2FnZV9uYW1lXSwKICAgIGRhdGFfZmlsZXM9WwogICAgICAgICgic2hhcmUvYW1lbnRfaW5kZXgvcmVzb3VyY2VfaW5kZXgvcGFja2FnZXMiLCBbInJlc291cmNlLyIgKyBwYWNrYWdlX25hbWVdKSwKICAgICAgICAoInNoYXJlLyIgKyBwYWNrYWdlX25hbWUsIFsicGFja2FnZS54bWwiXSksCiAgICBdLAogICAgaW5zdGFsbF9yZXF1aXJlcz1bInNldHVwdG9vbHMiXSwKICAgIHppcF9zYWZlPVRydWUsCiAgICBlbnRyeV9wb2ludHM9ewogICAgICAgICJjb25zb2xlX3NjcmlwdHMiOiBbIl9fUExVR0lOX1NMVUdfX19ub2RlID0gX19QTFVHSU5fU0xVR19fLm5vZGU6bWFpbiJdLAogICAgfSwKKQo=","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/CMakeLists.txt":"Y21ha2VfbWluaW11bV9yZXF1aXJlZChWRVJTSU9OIDMuMTYpCnByb2plY3QoX19QTFVHSU5fU0xVR19fKQoKaWYoTk9UIENNQUtFX0NYWF9TVEFOREFSRCkKICBzZXQoQ01BS0VfQ1hYX1NUQU5EQVJEIDE3KQplbmRpZigpCgpmaW5kX3BhY2thZ2UoYW1lbnRfY21ha2UgUkVRVUlSRUQpCmZpbmRfcGFja2FnZShyY2xjcHAgUkVRVUlSRUQpCgphZGRfZXhlY3V0YWJsZShfX1BMVUdJTl9TTFVHX19fbm9kZSBzcmMvbm9kZS5jcHApCmFtZW50X3RhcmdldF9kZXBlbmRlbmNpZXMoX19QTFVHSU5fU0xVR19fX25vZGUgcmNsY3BwKQoKaW5zdGFsbChUQVJHRVRTIF9fUExVR0lOX1NMVUdfX19ub2RlCiAgREVTVElOQVRJT04gbGliLyR7UFJPSkVDVF9OQU1FfSkKCmFtZW50X3BhY2thZ2UoKQo=","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/package.xml":"PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxwYWNrYWdlIGZvcm1hdD0iMyI+CiAgPG5hbWU+X19QTFVHSU5fU0xVR19fPC9uYW1lPgogIDx2ZXJzaW9uPjAuMC4xPC92ZXJzaW9uPgogIDxkZXNjcmlwdGlvbj5fX1BMVUdJTl9OQU1FX18gUk9TMiBub2RlIChyY2xjcHApPC9kZXNjcmlwdGlvbj4KICA8bWFpbnRhaW5lciBlbWFpbD0idG9kb0BleGFtcGxlLmNvbSI+bWFpbnRhaW5lcjwvbWFpbnRhaW5lcj4KICA8bGljZW5zZT5Qcm9wcmlldGFyeTwvbGljZW5zZT4KICA8YnVpbGR0b29sX2RlcGVuZD5hbWVudF9jbWFrZTwvYnVpbGR0b29sX2RlcGVuZD4KICA8ZGVwZW5kPnJjbGNwcDwvZGVwZW5kPgogIDxleHBvcnQ+PGJ1aWxkX3R5cGU+YW1lbnRfY21ha2U8L2J1aWxkX3R5cGU+PC9leHBvcnQ+CjwvcGFja2FnZT4K","ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/src/node.cpp":"Ly8gX19QTFVHSU5fTkFNRV9fIOKAlCBST1MyIG5vZGUgKHJjbGNwcCkuCi8vCi8vIFRoZSBub2RlIGlzIGxhdW5jaGVkIHdpdGggYC0tcm9zLWFyZ3MgLXIgX19uczo9L3tzbHVnfWAgYXV0b21hdGljYWxseSBieQovLyBkZXY6YmFjay4gUk9TMiB0b3BpY3MgYXJlIGJyaWRnZWQgdG8gdGhlIHBsdWdpbiBjb21tdW5pY2F0aW9uIGxheWVyLCBzbyBhCi8vIHBsYWluIHJjbGNwcCBub2RlIGlzIGFsbCB5b3UgbmVlZCDigJQgcmVsYXRpdmUgdG9waWMgbmFtZXMgZ2V0IHRoZSBuYW1lc3BhY2UKLy8gcHJlZml4IGFwcGxpZWQgYXV0b21hdGljYWxseS4KI2luY2x1ZGUgInJjbGNwcC9yY2xjcHAuaHBwIgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUgOiBwdWJsaWMgcmNsY3BwOjpOb2RlIHsKcHVibGljOgogIF9fUExVR0lOX0NMQVNTX19Ob2RlKCkgOiBOb2RlKCJfX1BMVUdJTl9TTFVHX19fbm9kZSIpIHsKICAgIFJDTENQUF9JTkZPKHRoaXMtPmdldF9sb2dnZXIoKSwgIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKTsKICAgIC8vIGNyZWF0ZSBwdWJsaXNoZXJzIC8gc3Vic2NyaWJlcnMgLyBzZXJ2aWNlcyBoZXJlCiAgfQp9OwoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgcmNsY3BwOjppbml0KGFyZ2MsIGFyZ3YpOwogIHJjbGNwcDo6c3BpbihzdGQ6Om1ha2Vfc2hhcmVkPF9fUExVR0lOX0NMQVNTX19Ob2RlPigpKTsKICByY2xjcHA6OnNodXRkb3duKCk7CiAgcmV0dXJuIDA7Cn0K","docker/Dockerfile.bridge":"IyBTb2NrZXQuSU8gYnJpZGdlIGNvbnRhaW5lciDigJQgdGhlIGZyb250ZW5kIChwcmV2aWV3LWhvc3QpIGFuZCB0aGUgYmFja2VuZAojIGNvbnRhaW5lciByZW5kZXp2b3VzIGhlcmUgZHVyaW5nIGBtdXNjYXQtcGsgZGV2YC4KIyAgIC0gZnJvbnRlbmQgKGhvc3QpICDihpIgcHVibGlzaGVkIHBvcnQgbG9jYWxob3N0OjEwMDAwCiMgICAtIGJhY2tlbmQgY29udGFpbmVyIOKGkiBzaGFyZXMgdGhpcyBjb250YWluZXIncyBuZXRucyAoLS1uZXR3b3JrIGNvbnRhaW5lcjopLAojICAgICAgICAgICAgICAgICAgICAgICAgIHNvIGl0IHJlYWNoZXMgdGhlIGJyaWRnZSBhdCBsb2NhbGhvc3Q6MTAwMDAgdG9vCiMgQnVpbGQgY29udGV4dCBpcyB0aGUgYGNsaS9gIGRpciBzbyBpdCBjYW4gY29weSBzcmMvc29ja2V0QnJpZGdlLm1qcy4KRlJPTSBub2RlOjIwLXNsaW0KTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKV09SS0RJUiAvYnJpZGdlCkNPUFkgZG9ja2VyL2JyaWRnZS1wYWNrYWdlLmpzb24gcGFja2FnZS5qc29uClJVTiBucG0gaW5zdGFsbCAtLW9taXQ9ZGV2IC0tbm8tYXVkaXQgLS1uby1mdW5kCgpDT1BZIHNyYy9zb2NrZXRCcmlkZ2UubWpzIC4vc29ja2V0QnJpZGdlLm1qcwoKRVhQT1NFIDEwMDAwCkNNRCBbIm5vZGUiLCAic29ja2V0QnJpZGdlLm1qcyJdCg==","docker/Dockerfile.cpp":"IyBEZXYvYnVpbGQgY29udGFpbmVyIGZvciB0aGUgcHVyZSBDKysgcGx1Z2luIGJhY2sgZW5kLgojIE1hdGNoZXMgdGhlIE11c2NhdCByb2JvdCBiYWNrZW5kIE9TIChVYnVudHUgMjQuMDQpIHNvIHRoZSBjb21waWxlZCBiaW5hcnkKIyBpcyBBQkktY29tcGF0aWJsZSB3aXRoIHRoZSByb2JvdC4gVXNlZCBieSBgbXVzY2F0LXBrIGRldjpiYWNrYCBhbmQgYGJ1aWxkYAojIOKAlCBOT1Qgc2hpcHBlZCBpbiB0aGUgcGx1Z2luIFpJUC4KRlJPTSB1YnVudHU6MjQuMDQKTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBcCiAgICAgIGJ1aWxkLWVzc2VudGlhbCBcCiAgICAgIGNtYWtlIFwKICAgICYmIHJtIC1yZiAvdmFyL2xpYi9hcHQvbGlzdHMvKgoKIyBUT0RPKGNwcC1zZGspOiBpbnN0YWxsIHRoZSByYWluYm93IGNwcCBTREsgKGRldiBwYWNrYWdlKSBoZXJlLCBwaW5uZWQgdG8gdGhlCiMgcm9ib3QncyB2ZXJzaW9uLCBzbyBwbHVnaW5zIGJ1aWxkL2xpbmsgYWdhaW5zdCB0aGUgc2FtZSBTREsgYXMgcHJvZHVjdGlvbi4KIyBQbGFuOiBhcHQgcGFja2FnZSArIGR5bmFtaWMgbGluayAodGhlIHJvYm90IHByb3ZpZGVzIHRoZSAuc28gYXQgcnVudGltZTsKIyB3ZSBkbyBOT1QgYnVuZGxlIGl0IGludG8gdGhlIHBsdWdpbiBiaW5hcnkpLiBlLmcuOgojICAgUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSByYWluYm93LWNwcC1zZGstZGV2PTxyb2JvdC12ZXJzaW9uPiBcCiMgICAgICAgJiYgcm0gLXJmIC92YXIvbGliL2FwdC9saXN0cy8qCgpXT1JLRElSIC9wbHVnaW4KCkNNRCBbImJhc2giXQo=","docker/Dockerfile.dev":"IyBEZXYtb25seSBjb250YWluZXIgZm9yIHRoZSBST1MyIHBsdWdpbiBiYWNrIGVuZC4KIyBNYXRjaGVzIHRoZSBNdXNjYXQgcm9ib3QgYmFja2VuZDogUk9TMiBKYXp6eSArIFB5dGhvbiAzLjEyIChVYnVudHUgMjQuMDQpLgojIFVzZWQgYnkgYG11c2NhdC1wayBkZXY6YmFja2Ag4oCUIE5PVCBzaGlwcGVkIGluIHRoZSBwbHVnaW4gWklQLgpGUk9NIHJvczpqYXp6eS1yb3MtYmFzZQpMQUJFTCBjb20ucmFpbmJvdy1yb2JvdGljcy5tdXNjYXQtcGs9InRydWUiCgpSVU4gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzIFwKICAgICAgcHl0aG9uMy1waXAgXAogICAgICBweXRob24zLWNvbGNvbi1jb21tb24tZXh0ZW5zaW9ucyBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCldPUktESVIgL3BsdWdpbgoKQ01EIFsiYmFzaCJdCg==","docker/Dockerfile.python":"IyBEZXYvYnVpbGQgY29udGFpbmVyIGZvciB0aGUgUHl0aG9uIHBsdWdpbiBiYWNrIGVuZC4KIyBNYXRjaGVzIHRoZSBNdXNjYXQgcm9ib3QgYmFja2VuZDogVWJ1bnR1IDI0LjA0ICsgUHl0aG9uIDMuMTIuCiMgVXNlZCBieSBgbXVzY2F0LXBrIGRldjpiYWNrYCAoaG90LXJlbG9hZCkgYW5kIGBtdXNjYXQtcGsgYnVpbGRgIChsb2NrICsgd2hlZWwgdmVuZG9yKS4KIyBOT1Qgc2hpcHBlZCBpbiB0aGUgcGx1Z2luIFpJUCDigJQgdGhlIHJvYm90IGluc3RhbGxzIGRlcHMgZnJvbSBkaXN0L3doZWVscy8gb2ZmbGluZS4KRlJPTSB1YnVudHU6MjQuMDQKTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBcCiAgICAgIHB5dGhvbjMgXAogICAgICBweXRob24zLXBpcCBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyogXAogICAgJiYgcGlwMyBpbnN0YWxsIHV2PT0wLjguMTggLS1icmVhay1zeXN0ZW0tcGFja2FnZXMKCiMgVE9ETyhjcHAtc2RrKTogdGhlIFB5dGhvbiBTREsgaXMgYSBweWJpbmQgd3JhcHBlciBvdmVyIHRoZSBjcHAgU0RLLCBzbyB0aGUKIyBjcHAgU0RLIHNoYXJlZCBsaWIgbXVzdCBiZSBwcmVzZW50IGZvciB0aGUgcHl0aG9uIG1vZHVsZSB0byBsb2FkLiBJbnN0YWxsIHRoZQojIHJhaW5ib3cgY3BwIFNESyAoYXB0LCBwaW5uZWQgdG8gdGhlIHJvYm90J3MgdmVyc2lvbikgaGVyZSBvbmNlIGl0IGV4aXN0cy4KCldPUktESVIgL3BsdWdpbgoKQ01EIFsiYmFzaCJdCg==","docker/bridge-package.json":"ewogICJuYW1lIjogIm11c2NhdC1way1icmlkZ2UiLAogICJwcml2YXRlIjogdHJ1ZSwKICAidHlwZSI6ICJtb2R1bGUiLAogICJkZXBlbmRlbmNpZXMiOiB7CiAgICAic29ja2V0LmlvIjogIl40LjguMSIKICB9Cn0K"};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Remote-robot Zenoh dev networking helpers, shared by `muscat-pk dev` and
|
|
2
|
+
// standalone `muscat-pk dev:back`.
|
|
3
|
+
//
|
|
4
|
+
// The plugin backend runs in a Docker container. When it connects to a REMOTE
|
|
5
|
+
// robot, rainbow.rb_sdk registers this machine as a Zenoh peer and the robot's
|
|
6
|
+
// `common` service connects BACK to the advertised ip:port to form the mesh.
|
|
7
|
+
// Inside a container, the SDK's own _detect_local_ip() returns the container's
|
|
8
|
+
// internal IP (unreachable from the robot) and lets the OS pick a random listen
|
|
9
|
+
// port (unpublished) — so the reverse connection never lands and SDK calls like
|
|
10
|
+
// call_move_j get no reply. We fix both ends:
|
|
11
|
+
// - MUSCAT_ZENOH_ADVERTISE_HOST → the host's LAN IP toward the robot, which
|
|
12
|
+
// devBack's entry script uses to override _detect_local_ip.
|
|
13
|
+
// - MUSCAT_ZENOH_PORT → a fixed, host-published listen port the robot can reach.
|
|
14
|
+
import { createSocket } from "node:dgram";
|
|
15
|
+
import { createServer } from "node:net";
|
|
16
|
+
|
|
17
|
+
export const DEFAULT_ZENOH_DEV_PORT = 53917;
|
|
18
|
+
export const LOCAL_HOSTS = new Set(["", "localhost", "127.0.0.1", "::1"]);
|
|
19
|
+
|
|
20
|
+
export const isRemoteRobot = (robotIp) => !!robotIp && !LOCAL_HOSTS.has(robotIp);
|
|
21
|
+
|
|
22
|
+
/** The local interface IP the OS would use to reach `host` (no packet sent). */
|
|
23
|
+
export function detectRouteAddress(host) {
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
const socket = createSocket("udp4");
|
|
26
|
+
socket.once("error", () => {
|
|
27
|
+
socket.close();
|
|
28
|
+
resolve("");
|
|
29
|
+
});
|
|
30
|
+
socket.connect(80, host, () => {
|
|
31
|
+
const address = socket.address();
|
|
32
|
+
socket.close();
|
|
33
|
+
resolve(typeof address === "object" ? address.address : "");
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** `preferred` if free, otherwise an OS-assigned free port. */
|
|
39
|
+
export function getFreePort(preferred) {
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
const srv = createServer();
|
|
42
|
+
srv.once("error", () => {
|
|
43
|
+
const fallback = createServer();
|
|
44
|
+
fallback.listen(0, "0.0.0.0", () => {
|
|
45
|
+
const address = fallback.address();
|
|
46
|
+
const port = typeof address === "object" && address ? address.port : preferred;
|
|
47
|
+
fallback.close(() => resolve(port));
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
srv.listen(preferred, "0.0.0.0", () => srv.close(() => resolve(preferred)));
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Compute and set MUSCAT_ZENOH_ADVERTISE_HOST / MUSCAT_ZENOH_PORT for a remote
|
|
56
|
+
* robot, unless already set by a parent command (idempotent). No-op for a local
|
|
57
|
+
* robot. Returns the resolved { advertiseHost, zenohPort } (or null if local).
|
|
58
|
+
*/
|
|
59
|
+
export async function ensureRemoteZenohEnv(robotIp, { log } = {}) {
|
|
60
|
+
if (!isRemoteRobot(robotIp)) return null;
|
|
61
|
+
// Already set (e.g. `muscat-pk dev` computed it before starting the bridge).
|
|
62
|
+
if (process.env.MUSCAT_ZENOH_PORT) {
|
|
63
|
+
return {
|
|
64
|
+
advertiseHost: process.env.MUSCAT_ZENOH_ADVERTISE_HOST || "",
|
|
65
|
+
zenohPort: Number(process.env.MUSCAT_ZENOH_PORT),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const advertiseHost =
|
|
69
|
+
process.env.MUSCAT_ZENOH_ADVERTISE_HOST || (await detectRouteAddress(robotIp));
|
|
70
|
+
const zenohPort = await getFreePort(DEFAULT_ZENOH_DEV_PORT);
|
|
71
|
+
if (advertiseHost) process.env.MUSCAT_ZENOH_ADVERTISE_HOST = advertiseHost;
|
|
72
|
+
process.env.MUSCAT_ZENOH_PORT = String(zenohPort);
|
|
73
|
+
log?.step?.(`remote Zenoh dev peer → ${advertiseHost || "(auto)"}:${zenohPort}`);
|
|
74
|
+
return { advertiseHost, zenohPort };
|
|
75
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"generatedAt":
|
|
1
|
+
{"generatedAt":1783659929067,"userSince":1750932757926,"hasCustomBabel":false,"hasCustomWebpack":false,"hasStaticDirs":false,"hasStorybookEslint":true,"refCount":0,"testPackages":{"@vitest/browser":"3.2.4","@vitest/coverage-v8":"3.2.4","playwright":"1.59.1","vitest":"3.2.4"},"hasRouterPackage":false,"monorepo":"Turborepo","packageManager":{"type":"yarn","version":"berry","agent":"yarn@berry"},"preview":{"usesGlobals":false},"framework":{"name":"@storybook/react-vite","options":{}},"builder":"@storybook/builder-vite","renderer":"@storybook/react","portableStoriesFileCount":0,"applicationFileCount":0,"storybookVersion":"8.6.18","storybookVersionSpecifier":"^8.6.4","language":"typescript","storybookPackages":{"@chromatic-com/storybook":{"version":"3.2.7"},"@storybook/addon-essentials":{"version":"8.6.18"},"@storybook/addon-links":{"version":"8.6.18"},"@storybook/addon-onboarding":{"version":"8.6.18"},"@storybook/addon-themes":{"version":"8.6.18"},"@storybook/blocks":{"version":"8.6.18"},"@storybook/experimental-addon-test":{"version":"8.6.18"},"@storybook/react":{"version":"8.6.18"},"@storybook/react-vite":{"version":"8.6.18"},"@storybook/test":{"version":"8.6.18"},"@storybook/theming":{"version":"8.6.18"},"eslint-plugin-storybook":{"version":"0.11.6"},"storybook":{"version":"8.6.18"},"storybook-addon-react-docgen":{"version":"1.2.44"}},"addons":{"$SNIP/node_modules/@storybook/addon-links":{"version":null},"$SNIP/node_modules/@storybook/addon-essentials":{"version":null},"$SNIP/node_modules/@chromatic-com/storybook":{"version":null},"$SNIP/node_modules/@storybook/addon-themes":{"version":null},"$SNIP/node_modules/@storybook/experimental-addon-test":{"version":null}}}
|
package/cli/vite.mjs
CHANGED
|
@@ -257,6 +257,17 @@ export function muscat(options = {}) {
|
|
|
257
257
|
apply: "serve",
|
|
258
258
|
config: () => {
|
|
259
259
|
return {
|
|
260
|
+
// NOTE: even with sharedRuntimeBase set (so `alias` is empty and our
|
|
261
|
+
// resolveId below wins for every actual import), @vitejs/plugin-react
|
|
262
|
+
// still unconditionally adds react/react-dom/jsx-(dev-)runtime to
|
|
263
|
+
// optimizeDeps.include for Fast Refresh — Vite merges every plugin's
|
|
264
|
+
// optimizeDeps (arrays are concatenated, not overridden), so esbuild's
|
|
265
|
+
// pre-bundle scanner still tries to statically resolve those on disk.
|
|
266
|
+
// That's why the scaffold template keeps react/react-dom as local
|
|
267
|
+
// devDependencies even in shared-runtime mode: purely so this static
|
|
268
|
+
// scan has something real to resolve. The actual dev-server imports
|
|
269
|
+
// never reach that local copy — resolveId (enforce: "pre") below
|
|
270
|
+
// always wins first and redirects to the host's instance.
|
|
260
271
|
resolve: {
|
|
261
272
|
alias: sharedRuntimeBase ? [] : reactAliases(pluginRoot),
|
|
262
273
|
dedupe: ["react", "react-dom"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rainbow-robotics/muscat-plugin-kit",
|
|
3
|
-
"version": "0.1.2-dev.
|
|
3
|
+
"version": "0.1.2-dev.52",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20"
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
56
|
-
"@rainbow-robotics/plugin-ui": "0.1.2-dev.
|
|
57
|
-
"@rainbow-robotics/preview-host": "0.1.2-dev.
|
|
56
|
+
"@rainbow-robotics/plugin-ui": "0.1.2-dev.52",
|
|
57
|
+
"@rainbow-robotics/preview-host": "0.1.2-dev.52",
|
|
58
58
|
"postcss": "^8.5.8",
|
|
59
59
|
"socket.io": "^4.8.1",
|
|
60
60
|
"typescript": "^5.8.0",
|