@rainbow-robotics/muscat-plugin-kit 1.10.2-dev.2 → 1.10.2-dev.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/cli/src/ai-rules.mjs +37 -0
  2. package/cli/src/mcp.mjs +30 -0
  3. package/cli/src/new.mjs +2 -1
  4. package/cli/src/projectCheck.mjs +102 -0
  5. package/cli/src/templates-embedded.mjs +4 -0
  6. package/cli/src/update.mjs +41 -102
  7. package/cli/storybook-dist/assets/{Color-YHDXOIA2-B4IER17l.js → Color-YHDXOIA2-d4UialIW.js} +1 -1
  8. package/cli/storybook-dist/assets/{Docs-DUfeiM4I.js → Docs-BySWRVQD.js} +1 -1
  9. package/cli/storybook-dist/assets/{Docs-DNYQC7nl.js → Docs-CppxziOu.js} +1 -1
  10. package/cli/storybook-dist/assets/{Docs-C8GCHFtK.js → Docs-DOzwT3cw.js} +1 -1
  11. package/cli/storybook-dist/assets/{Docs-Ck3WHvk6.js → Docs-DpuckkF2.js} +1 -1
  12. package/cli/storybook-dist/assets/{Docs-D9NHsoeZ.js → Docs-tWjVyRAS.js} +1 -1
  13. package/cli/storybook-dist/assets/{Docs-CgdEMPQP.js → Docs-vU43epz3.js} +1 -1
  14. package/cli/storybook-dist/assets/{DocsRenderer-CFRXHY34-C0WhyDoR.js → DocsRenderer-CFRXHY34-Boj7BBcx.js} +1 -1
  15. package/cli/storybook-dist/assets/{entry-preview-D7IHsza_.js → entry-preview-BfxbSNyQ.js} +1 -1
  16. package/cli/storybook-dist/assets/{iframe-CbaIp5I-.js → iframe-D3ykNOcq.js} +2 -2
  17. package/cli/storybook-dist/assets/{index-C6CBgMuG.js → index-NJyPL3Uy.js} +3 -3
  18. package/cli/storybook-dist/assets/{preview-CRWqc9DH.js → preview-3_yzT7Wt.js} +2 -2
  19. package/cli/storybook-dist/assets/{preview-B-iYLDuW.js → preview-BoJV1ynr.js} +2 -2
  20. package/cli/storybook-dist/iframe.html +1 -1
  21. package/cli/storybook-dist/index.html +1 -1
  22. package/cli/storybook-dist/project.json +1 -1
  23. package/cli/templates/common/README.md +4 -0
  24. package/cli/templates/readme-cpp/README.md +4 -0
  25. package/package.json +3 -3
  26. package/cli/templates/common/.mcp.json +0 -8
@@ -29,6 +29,33 @@ const UI_RULES = [
29
29
  "Colors and type come from tokens (bg-bg-*, text-fg-*, typo-*), not hex values or arbitrary Tailwind colors.",
30
30
  ];
31
31
 
32
+ // plugin-ui 1.x replaced the remote-dom components and the connect() bootstrap. The project check
33
+ // (update, MCP check_project) flags these; the migration rules below tell an agent how to fix them.
34
+ export const LEGACY_SUBPATHS = {
35
+ connect: "removed — drop `connect(App)` and `export default App` instead (the host renders the entry's default export)",
36
+ elements: "removed — use the RB* components from @rainbow-robotics/plugin-ui/react",
37
+ "dist-browser": "removed — import from @rainbow-robotics/plugin-ui/react",
38
+ };
39
+ export const LEGACY_COMPONENTS = {
40
+ Slider: "RBSlider",
41
+ Button: "RBLabelButton",
42
+ IconButton: "RBIconButton",
43
+ Text: "a plain element or RBTextLabel",
44
+ TextInput: "RBTextInput / RBTextField",
45
+ Switch: "RBSwitch",
46
+ Select: "RBSelectBox",
47
+ };
48
+ const MIGRATION_RULES = [
49
+ "After `muscat-pk update`, or when the UI fails to build or the preview says \"no default export\", call check_project and fix every item it lists. Call it again until it reports no issues.",
50
+ "Each top-level ui/*.tsx is an entry and ends in `export default App`. The old `connect(App)` bootstrap and @rainbow-robotics/plugin-ui/connect are gone.",
51
+ "vite.config.ts uses the muscat() preset (`plugins: [muscat()]` from @rainbow-robotics/muscat-plugin-kit/vite); keep any other plugins the project adds. A hand-written config drops the entry's default export from the build.",
52
+ "rb.toast takes one object: rb.toast({ message, type }).",
53
+ `Old components → new: ${Object.entries(LEGACY_COMPONENTS).map(([o, n]) => `${o} → ${n}`).join(", ")}. Their props differ (no event.detail) — call get_component_example for the new component before rewriting.`,
54
+ ];
55
+
56
+ // Claude Code reads this to start the MCP server; `muscat-pk` hands off to the project's local kit.
57
+ export const MCP_JSON = `${JSON.stringify({ mcpServers: { muscat: { command: "muscat-pk", args: ["mcp"] } } }, null, 2)}\n`;
58
+
32
59
  const nativeTable = () => NATIVE_TO_RB.map(([el, rb]) => `- ${el}: ${rb}`).join("\n");
33
60
 
34
61
  export const SERVER_INSTRUCTIONS = `Muscat plugin UI (ui/*.tsx) is built only from @rainbow-robotics/plugin-ui/react, styled with the design-token Tailwind classes (list_design_tokens).
@@ -39,6 +66,9 @@ ${UI_RULES.map((r) => `- ${r}`).join("\n")}
39
66
  Native element -> plugin-ui component:
40
67
  ${nativeTable()}
41
68
 
69
+ Upgrading a project made with an older kit:
70
+ ${MIGRATION_RULES.map((r) => `- ${r}`).join("\n")}
71
+
42
72
  Backend, manifest and SDK questions: search_rb_sdk, list_rb_sdk, get_rb_sdk_api.`;
43
73
 
44
74
  // AGENTS.md (Codex, Cursor, Gemini CLI, Copilot …). CLAUDE.md imports it with `@AGENTS.md`.
@@ -64,6 +94,13 @@ ${UI_RULES.map((r) => `- ${r}`).join("\n")}
64
94
  Native element → plugin-ui component:
65
95
 
66
96
  ${nativeTable()}
97
+
98
+ ## Upgrading from an older kit
99
+
100
+ \`muscat-pk update\` bumps the kit, plugin-ui and preview-host and lists what the project must change.
101
+ The MCP tool \`check_project\` runs the same check (known old APIs + \`tsc --noEmit\`).
102
+
103
+ ${MIGRATION_RULES.map((r) => `- ${r}`).join("\n")}
67
104
  `;
68
105
  }
69
106
 
package/cli/src/mcp.mjs CHANGED
@@ -43,6 +43,7 @@ import { PYTHON_DEV_IMAGE } from "./python.mjs";
43
43
  import { SHIPPED_STORIES_SRC, SHIPPED_DESIGN_TOKENS } from "./storybook.mjs";
44
44
  import { CPP_DEV_IMAGE } from "./cpp.mjs";
45
45
  import { NATIVE_TO_RB, SERVER_INSTRUCTIONS } from "./ai-rules.mjs";
46
+ import { checkProject, formatProjectCheck } from "./projectCheck.mjs";
46
47
 
47
48
  const TEMPLATE_READMES = { python: "common/README.md", cpp: "readme-cpp/README.md" };
48
49
  // Design tokens: prefer the shipped copy, fall back to the monorepo source.
@@ -1090,6 +1091,35 @@ print(json.dumps(res))
1090
1091
  },
1091
1092
  );
1092
1093
 
1094
+ server.registerTool(
1095
+ "check_project",
1096
+ {
1097
+ title: "Check the plugin project for changes the installed plugin-ui needs",
1098
+ description:
1099
+ "List what the plugin project must change to work with the plugin-ui it has installed: old APIs " +
1100
+ "(connect(App), Slider/Text/Switch…, rb.toast(message, type), a vite.config without the muscat() " +
1101
+ "preset, entries without a default export) and `tsc --noEmit` errors, each as file:line. Same check " +
1102
+ "as `muscat-pk update`. Call it after an update or when the UI fails to build, fix each item " +
1103
+ "(get_component_example for replacement components), and call it again until it reports no issues.",
1104
+ inputSchema: {
1105
+ path: z.string().optional().describe("Plugin project directory (default: the server's working directory)"),
1106
+ },
1107
+ },
1108
+ async ({ path }) => {
1109
+ let root;
1110
+ try {
1111
+ root = findPluginRoot(path ? resolve(path) : process.cwd());
1112
+ } catch (err) {
1113
+ return { isError: true, content: [{ type: "text", text: err.message }] };
1114
+ }
1115
+ const lines = formatProjectCheck(checkProject(root));
1116
+ const text = lines.length
1117
+ ? `${root}: ${lines.filter((l) => /:\d+ {2}/.test(l)).length} item(s) to fix\n${lines.join("\n")}`
1118
+ : `${root}: no issues — the project matches the installed plugin-ui.`;
1119
+ return { content: [{ type: "text", text }] };
1120
+ },
1121
+ );
1122
+
1093
1123
  const transport = new StdioServerTransport();
1094
1124
  await server.connect(transport);
1095
1125
  }
package/cli/src/new.mjs CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  } from "node:fs";
14
14
  import { basename, dirname, resolve } from "node:path";
15
15
  import { color, ensureIdeVenv, hasBin, kitVersion, parseArgs, prompt, templatesDir, log } from "./util.mjs";
16
- import { agentsMd, CLAUDE_MD } from "./ai-rules.mjs";
16
+ import { agentsMd, CLAUDE_MD, MCP_JSON } from "./ai-rules.mjs";
17
17
 
18
18
  // Like cpSync(src, dst, {recursive:true}) but reads from the embedded snapshot
19
19
  // when the templates dir doesn't exist on disk (compiled binary mode).
@@ -281,6 +281,7 @@ export async function runNew(args) {
281
281
  // Rules for AI agents, generated from the same source as the MCP server's instructions.
282
282
  writeFileSync(resolve(target, "AGENTS.md"), agentsMd({ pluginName }));
283
283
  writeFileSync(resolve(target, "CLAUDE.md"), CLAUDE_MD);
284
+ writeFileSync(resolve(target, ".mcp.json"), MCP_JSON);
284
285
 
285
286
  if (!opts["no-install"]) {
286
287
  try {
@@ -0,0 +1,102 @@
1
+ // What a project must change for the plugin-ui it has installed: known old APIs (ai-rules.mjs) plus
2
+ // `tsc --noEmit`. Shared by `muscat-pk update` and the MCP tool check_project, so a user and an
3
+ // agent see the same list.
4
+ import { spawnSync } from "node:child_process";
5
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
6
+ import { join, relative, resolve } from "node:path";
7
+ import { LEGACY_COMPONENTS, LEGACY_SUBPATHS } from "./ai-rules.mjs";
8
+
9
+ const isBinaryMode = typeof Bun !== "undefined";
10
+
11
+ // The clause can't hold quotes or `;`, so a match can't start at an earlier import statement.
12
+ const PLUGIN_UI_IMPORT = /import\s+([^;'"]*?)\s+from\s+["']@rainbow-robotics\/plugin-ui\/([\w-]+)["']/g;
13
+
14
+ function listUiFiles(dir) {
15
+ return readdirSync(dir, { withFileTypes: true }).flatMap((e) =>
16
+ e.isDirectory() ? listUiFiles(join(dir, e.name)) : /\.[jt]sx?$/.test(e.name) ? [join(dir, e.name)] : [],
17
+ );
18
+ }
19
+
20
+ // rb.toast takes one { message, type } object now; flag a string or multi-argument call.
21
+ const TOAST_CALL = /\.toast\(([^()]*)\)/g;
22
+
23
+ /** Uses of the pre-1.x plugin-ui API in the project (ui/ and vite.config), as { file, line, text }. */
24
+ function findLegacyUiUsage(root) {
25
+ const uiDir = resolve(root, "ui");
26
+ if (!existsSync(uiDir)) return [];
27
+ const found = [];
28
+ // The old hand-written config builds entries without their exports (connect() rendered as a side
29
+ // effect), so `export default App` is dropped from dist. The muscat() preset keeps it.
30
+ const viteConfig = ["vite.config.ts", "vite.config.mts", "vite.config.js", "vite.config.mjs"].find((f) => existsSync(resolve(root, f)));
31
+ if (viteConfig && !readFileSync(resolve(root, viteConfig), "utf8").includes("@rainbow-robotics/muscat-plugin-kit/vite")) {
32
+ found.push({
33
+ file: viteConfig,
34
+ line: 1,
35
+ text: 'not using the muscat() preset — the build drops the entry\'s default export. Use: import { muscat } from "@rainbow-robotics/muscat-plugin-kit/vite"; defineConfig({ plugins: [muscat()] })',
36
+ });
37
+ }
38
+ for (const file of listUiFiles(uiDir)) {
39
+ const src = readFileSync(file, "utf8");
40
+ const rel = relative(root, file);
41
+ const lineOf = (index) => src.slice(0, index).split("\n").length;
42
+ for (const m of src.matchAll(PLUGIN_UI_IMPORT)) {
43
+ const [, clause, subpath] = m;
44
+ if (LEGACY_SUBPATHS[subpath]) {
45
+ found.push({ file: rel, line: lineOf(m.index), text: `@rainbow-robotics/plugin-ui/${subpath} ${LEGACY_SUBPATHS[subpath]}` });
46
+ } else if (subpath === "react") {
47
+ const named = clause.match(/\{([\s\S]*)\}/)?.[1] ?? "";
48
+ for (const spec of named.split(",")) {
49
+ const name = spec.trim().replace(/^type\s+/, "").split(/\s+as\s+/)[0];
50
+ if (LEGACY_COMPONENTS[name]) {
51
+ found.push({ file: rel, line: lineOf(m.index), text: `${name} → ${LEGACY_COMPONENTS[name]}` });
52
+ }
53
+ }
54
+ }
55
+ }
56
+ for (const m of src.matchAll(TOAST_CALL)) {
57
+ const arg = m[1].trim();
58
+ if (!arg.startsWith("{") && (/^["'`]/.test(arg) || arg.includes(","))) {
59
+ found.push({ file: rel, line: lineOf(m.index), text: "rb.toast(message, type) → rb.toast({ message, type })" });
60
+ }
61
+ }
62
+ // Top-level ui/ files are the entries; the host mounts their default export.
63
+ if (relative(uiDir, file).split(/[\\/]/).length === 1 && !/export\s+default\b/.test(src)) {
64
+ found.push({ file: rel, line: 1, text: "no default export — the host renders the entry's default export" });
65
+ }
66
+ }
67
+ return found;
68
+ }
69
+
70
+ // The known-API list above only knows past changes. Type-checking against the plugin-ui that was
71
+ // just installed catches whatever a later release removes or reshapes, with no list to keep up.
72
+ function typeScriptErrors(root) {
73
+ const tsc = resolve(root, "node_modules/typescript/bin/tsc");
74
+ if (!existsSync(tsc) || !existsSync(resolve(root, "tsconfig.json"))) return [];
75
+ const runtime = isBinaryMode ? "node" : process.execPath;
76
+ const r = spawnSync(runtime, [tsc, "--noEmit", "-p", root, "--pretty", "false"], { cwd: root, encoding: "utf8" });
77
+ return `${r.stdout ?? ""}`
78
+ .split("\n")
79
+ .map((l) => /^(.+?)\((\d+),\d+\): error (TS\d+): (.*)$/.exec(l))
80
+ .filter(Boolean)
81
+ .map(([, file, line, code, text]) => ({ file: relative(root, resolve(root, file)), line: Number(line), text: `${code} ${text}` }));
82
+ }
83
+
84
+ /** Everything the project must change, as { file, line, text, source: "known" | "tsc" }. */
85
+ export function checkProject(root) {
86
+ return [
87
+ ...findLegacyUiUsage(root).map((f) => ({ ...f, source: "known" })),
88
+ ...typeScriptErrors(root).map((e) => ({ ...e, source: "tsc" })),
89
+ ];
90
+ }
91
+
92
+ /** Plain-text lines for a checkProject() result (empty when there is nothing to fix). */
93
+ export function formatProjectCheck(items) {
94
+ if (!items.length) return [];
95
+ const line = (i) => ` ${i.file}:${i.line} ${i.text}`;
96
+ const tsc = items.filter((i) => i.source === "tsc");
97
+ return [
98
+ ...items.filter((i) => i.source !== "tsc").map(line),
99
+ ...(tsc.length ? [" TypeScript (tsc --noEmit):", ...tsc.map(line)] : []),
100
+ " For working examples, generate a fresh project and read its ui/content.tsx: muscat-pk new <dir>",
101
+ ];
102
+ }
@@ -0,0 +1,4 @@
1
+ // AUTO-GENERATED by cli/bundle-templates.mjs — do not edit.
2
+ // ponytail: generated at publish time; not tracked in git.
3
+ export const KIT_VERSION = "1.3.8-dev.3";
4
+ export const TEMPLATES = {"common/.mcp.json":"ewogICJtY3BTZXJ2ZXJzIjogewogICAgIm11c2NhdCI6IHsKICAgICAgImNvbW1hbmQiOiAibXVzY2F0LXBrIiwKICAgICAgImFyZ3MiOiBbIm1jcCJdCiAgICB9CiAgfQp9Cg==","common/README.md":"IyBfX1BMVUdJTl9OQU1FX18KCkEgTXVzY2F0IHBsdWdpbiBwcm9qZWN0LiBCdWlsZCwgZGV2ZWxvcCwgYW5kIHNoaXAgd2l0aCBgbXVzY2F0LXBrYCBDTEkuCgojIyBRdWljayBzdGFydAoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJIHByZXZpZXcgKyBiYWNrZW5kIHRvZ2V0aGVyCm11c2NhdC1wayBkZXY6dWkgICAgICMgVUkgcHJldmlldyBvbmx5Cm11c2NhdC1wayBkZXY6YmFjayAgICMgYmFja2VuZCBvbmx5IChQeXRob24gd2F0Y2hmaWxlcyAvIFJPUzIgRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkICsgZGlzdHJpYnV0YWJsZSBaSVAKYGBgCgotLS0KCiMjIFByb2plY3Qgc3RydWN0dXJlCgpgYGAKX19QTFVHSU5fRElSX18vCuKUnOKUgCB1aS8K4pSCICAg4pSc4pSAIGNvbnRlbnQudHN4ICAgICAgIyBwbHVnaW4gVUkgZW50cnkgcG9pbnQK4pSCICAg4pSU4pSAIHN0eWxlLmNzcyAgICAgICAgIyBwbHVnaW4gc3R5bGVzIGF1dG8tbG9hZGVkIGJ5IG11c2NhdCgpCuKUnOKUgCBweS8K4pSCICAg4pSU4pSAIG1haW4ucHkgICAgICAgICAgIyBQeXRob24gYmFja2VuZCBlbnRyeSBwb2ludArilJzilIAgYXNzZXRzLwrilIIgICDilJTilIAgaWNvbi5zdmcgICAgICAgICAjIGljb24gcmVmZXJlbmNlZCBmcm9tIG1hbmlmZXN0CuKUnOKUgCBtYW5pZmVzdC5qc29uICAgICAgICAjIG1ldGFkYXRhLCBjb250cmlidXRpb24gcG9pbnRzLCBydW50aW1lIGNvbmZpZwrilJzilIAgUkVBRE1FLm1kICAgICAgICAgICAgIyB0aGlzIGZpbGUgKGNvcGllZCB0byBkaXN0LyBvbiBidWlsZCkK4pSU4pSAIHJlcXVpcmVtZW50cy50eHQgICAgICMgUHl0aG9uIGRlcHMgKGF1dG8tcGlubmVkIHRvIGxhdGVzdCBvbiBidWlsZCkKYGBgCgo+IFJPUzIgcGx1Z2lucyBhZGRpdGlvbmFsbHkgaW5jbHVkZSBhIGByb3MyX3dzL2AgZGlyZWN0b3J5LgoKLS0tCgojIyBGcm9udGVuZCAoYHVpL2NvbnRlbnQudHN4YCkKCiMjIyBKYXZhU2NyaXB0IGRlcGVuZGVuY2llcwoKYG11c2NhdC1wayBidWlsZGAgcnVucyB0aGlzIHBsdWdpbiBwcm9qZWN0J3Mgb3duIFZpdGUgYnVpbGQuIFZpdGUgcmVzb2x2ZXMKaW1wb3J0cyBmcm9tIGluc3RhbGxlZCBgbm9kZV9tb2R1bGVzYDsgaXQgZG9lcyBub3QgY2FyZSB3aGV0aGVyIGEgcGFja2FnZSBpcwpsaXN0ZWQgdW5kZXIgYGRlcGVuZGVuY2llc2Agb3IgYGRldkRlcGVuZGVuY2llc2AsIGJ1dCB0aGUgcGFja2FnZSBtdXN0IGJlCmluc3RhbGxlZC4KCkRvIG5vdCBydW4gYSBwcm9kdWN0aW9uLW9ubHkgaW5zdGFsbCBzdWNoIGFzIGBucG0gaW5zdGFsbCAtLW9taXQ9ZGV2YCBiZWZvcmUKYnVpbGRpbmcgdGhlIHBsdWdpbiBVSSwgYmVjYXVzZSBidWlsZCB0b29scyBsaWtlIGB2aXRlYCwgYHR5cGVzY3JpcHRgLApgdGFpbHdpbmRjc3NgLCBgQHRhaWx3aW5kY3NzL3ZpdGVgLCBgc2Fzc2AsIG9yIGBsZXNzYCBhcmUgdXN1YWxseQpgZGV2RGVwZW5kZW5jaWVzYC4KClRoZSBzY2FmZm9sZCBrZWVwcyB0aGlzIHNwbGl0OgoKfCBwYWNrYWdlIGtpbmQgfCBleGFtcGxlcyB8IHdoeSB8CnwtLS18LS0tfC0tLXwKfCBgZGVwZW5kZW5jaWVzYCB8IGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWlgLCBVSSBsaWJyYXJpZXMgaW1wb3J0ZWQgYnkgcGx1Z2luIHNvdXJjZSB8IEF1dGhvci1mYWNpbmcgQVBJcyB1c2VkIGJ5IGB1aS8qLnRzeGAgfAp8IGBkZXZEZXBlbmRlbmNpZXNgIHwgYHZpdGVgLCBgdHlwZXNjcmlwdGAsIGB0YWlsd2luZGNzc2AsIGBAdGFpbHdpbmRjc3Mvdml0ZWAsIGBzYXNzYCwgYGxlc3NgIHwgQnVpbGQvZGV2IHRvb2xzIG5lZWRlZCBiZWZvcmUgYGRpc3QvKi5qc2AgaXMgcHJvZHVjZWQgfAoKVGhlIGJ1aWx0IHBsdWdpbiBaSVAgZG9lcyBub3QgaW5jbHVkZSBgcGFja2FnZS5qc29uYCBvciBgbm9kZV9tb2R1bGVzYC4gRm9yCnByb2R1Y3Rpb24sIE11c2NhdCBwcm92aWRlcyBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpYCwgUmVhY3QsIGFuZCBSZWFjdERPTQp0aHJvdWdoIHRoZSBob3N0IGltcG9ydCBtYXA7IHBsdWdpbiBVSSBidWlsZCBvdXRwdXQgaW1wb3J0cyB0aG9zZSBhcyBob3N0CmV4dGVybmFscy4KCiMjIyBTdHlsZXMKCmBtdXNjYXQoKWAgYXV0b21hdGljYWxseSBsb2FkcyBgdWkvc3R5bGUue2NzcyxzY3NzLHNhc3MsbGVzc31gIChvcgpgdWkvc3R5bGVzLntjc3Msc2NzcyxzYXNzLGxlc3N9YCkgZm9yIGV2ZXJ5IFVJIGVudHJ5LCBwbHVzCmB1aS97ZW50cnl9Lntjc3Msc2NzcyxzYXNzLGxlc3N9YCBmb3IgYSBtYXRjaGluZyBlbnRyeS1zcGVjaWZpYyBzdHlsZXNoZWV0LiBZb3UKZG8gbm90IG5lZWQgdG8gaW1wb3J0IENTUyBmcm9tIGV2ZXJ5IGAudHN4YCBmaWxlLgoKVGhlIHNjYWZmb2xkIHVzZXMgVGFpbHdpbmQncyB0aGVtZS91dGlsaXRpZXMgbGF5ZXJzIG9ubHksIHNvIHBsdWdpbiB1dGlsaXRpZXMKYXJlIGdlbmVyYXRlZCBmcm9tIGZpbGVzIHVuZGVyIGB1aS9gIHdpdGhvdXQgYXBwbHlpbmcgVGFpbHdpbmQgcHJlZmxpZ2h0IHJlc2V0cwp0byB0aGUgaG9zdCBwYWdlLgoKQnVpbHQgQ1NTIHNlbGVjdG9ycyBhcmUgc2NvcGVkIHVuZGVyIHRoZSBjdXJyZW50IHBsdWdpbiBpZAooYFtkYXRhLW11c2NhdC1wbHVnaW4taWQ9Ii4uLiJdYCkuIENTUy1pbi1KUyBsaWJyYXJpZXMgc3VjaCBhcyBFbW90aW9uIHdvcmsKbm9ybWFsbHksIGJ1dCBnbG9iYWwgc3R5bGVzIHNob3VsZCBiZSBzY29wZWQgYnkgdGhlIGF1dGhvci4KCiMjIyMgVGFpbHdpbmQKClRoaXMgdGVtcGxhdGUgZW5hYmxlcyBUYWlsd2luZCBpbiBgdml0ZS5jb25maWcudHNgOgoKYGBgdHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsKYGBgCgpUaGUgZGVmYXVsdCBgdWkvc3R5bGUuY3NzYCB1c2VzIFRhaWx3aW5kIHRoZW1lL3V0aWxpdGllcyBvbmx5LCBub3QgcHJlZmxpZ2h0OgoKYGBgY3NzCkBsYXllciB0aGVtZSwgdXRpbGl0aWVzOwoKQGltcG9ydCAidGFpbHdpbmRjc3MvdGhlbWUuY3NzIiBsYXllcih0aGVtZSk7CkBpbXBvcnQgInRhaWx3aW5kY3NzL3V0aWxpdGllcy5jc3MiIGxheWVyKHV0aWxpdGllcyk7CgpAc291cmNlICIuLyoqLyoue3RzLHRzeH0iOwpgYGAKCiMjIyMgU0NTUywgU2FzcywgYW5kIExlc3MKCkluc3RhbGwgdGhlIHByZXByb2Nlc3NvciBwYWNrYWdlLCB0aGVuIGNyZWF0ZSBvbmUgb2YgdGhlIGF1dG8tbG9hZGVkIHN0eWxlIGZpbGVzLgoKYGBgYmFzaApucG0gaSAtRCBzYXNzCmBgYAoKYGBgc2NzcwovKiB1aS9zdHlsZS5zY3NzICovCiRhY2NlbnQ6ICMzYjgyZjY7CgoucGFuZWwgewogIGJvcmRlcjogMXB4IHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCAkYWNjZW50IDQwJSwgdHJhbnNwYXJlbnQpOwoKICAmX190aXRsZSB7CiAgICBjb2xvcjogJGFjY2VudDsKICB9Cn0KYGBgCgpGb3IgTGVzcywgaW5zdGFsbCBgbGVzc2AgYW5kIHVzZSBgdWkvc3R5bGUubGVzc2AuCgojIyMjIEVtb3Rpb24KCkVtb3Rpb24gZGVwZW5kZW5jaWVzIG1heSBiZSBpbiBgZGVwZW5kZW5jaWVzYCBvciBgZGV2RGVwZW5kZW5jaWVzYDsgVml0ZSBjYW4KYnVuZGxlIHRoZW0gd2hlbiB0aGV5IGFyZSBpbnN0YWxsZWQgYW5kIGltcG9ydGVkIGJ5IHRoZSBwbHVnaW4uCgpGb3IgYHN0eWxlZGAsIG5vIFZpdGUgY29uZmlnIGNoYW5nZSBpcyBuZWVkZWQ6CgpgYGBiYXNoCm5wbSBpIEBlbW90aW9uL3JlYWN0IEBlbW90aW9uL3N0eWxlZApgYGAKCmBgYHRzeAppbXBvcnQgc3R5bGVkIGZyb20gIkBlbW90aW9uL3N0eWxlZCI7Cgpjb25zdCBQYW5lbCA9IHN0eWxlZC5kaXYoewogIGRpc3BsYXk6ICJncmlkIiwKICBnYXA6IDEyLAp9KTsKYGBgCgpGb3IgRW1vdGlvbidzIGBjc3NgIHByb3AsIHBhc3MgUmVhY3QgcGx1Z2luIG9wdGlvbnMgdGhyb3VnaCBgbXVzY2F0KClgIGFuZCBhZGQKYGpzeEltcG9ydFNvdXJjZWAgdG8gYHRzY29uZmlnLmpzb25gOgoKYGBgYmFzaApucG0gaSBAZW1vdGlvbi9yZWFjdCBAZW1vdGlvbi9zdHlsZWQKbnBtIGkgLUQgQGVtb3Rpb24vYmFiZWwtcGx1Z2luCmBgYAoKYGBgdHMKLy8gdml0ZS5jb25maWcudHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbCiAgICB0YWlsd2luZGNzcygpLAogICAgbXVzY2F0KHsKICAgICAgcmVhY3Q6IHsKICAgICAgICBqc3hJbXBvcnRTb3VyY2U6ICJAZW1vdGlvbi9yZWFjdCIsCiAgICAgICAgYmFiZWw6IHsKICAgICAgICAgIHBsdWdpbnM6IFsiQGVtb3Rpb24vYmFiZWwtcGx1Z2luIl0sCiAgICAgICAgfSwKICAgICAgfSwKICAgIH0pLAogIF0sCn0pOwpgYGAKCmBgYGpzb24KewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAianN4SW1wb3J0U291cmNlIjogIkBlbW90aW9uL3JlYWN0IgogIH0KfQpgYGAKCkVtb3Rpb24gYEdsb2JhbGAgd3JpdGVzIGdsb2JhbCBDU1MgYXQgcnVudGltZSwgc28gc2NvcGUgaXQgbWFudWFsbHkgb3IgYXZvaWQgaXQKaW5zaWRlIHBsdWdpbnMuCgojIyMgdXNlUmIoKSBob29rCgpBY2Nlc3MgdGhlIGNvbW11bmljYXRpb24gQVBJIGJldHdlZW4gdGhlIHBsdWdpbiBtb2R1bGUgYW5kIFVJIGZyb20gYW55IHBsdWdpbiBjb21wb25lbnQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlUmIgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvc2RrIjsKCmZ1bmN0aW9uIEFwcCgpIHsKICBjb25zdCByYiA9IHVzZVJiKCk7Cn0KYGBgCgojIyMgcmIgQVBJCgp8IE1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfAp8IGByYi5wdWIodG9waWMsIHBheWxvYWQpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFB1Ymxpc2ggYSBtZXNzYWdlIHRvIGEgdG9waWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IGByYi5zdWIodG9waWMsIGhhbmRsZXIpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFN1YnNjcmliZSB0byBhIHRvcGljIOKAlCByZXR1cm5zIGB7IHVuZGVjbGFyZSgpIH1gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmFjdGlvbih0b3BpYywgcGF5bG9hZD8pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2VuZCBhIHJlcXVlc3QgYW5kIGF3YWl0IGEgcmVwbHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnNlcnZlKHRvcGljLCBoYW5kbGVyKWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSGFuZGxlIGluY29taW5nIHJlcXVlc3RzIGZyb20gdGhlIGJhY2tlbmQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnRvYXN0KHsgdGl0bGU/LCBtZXNzYWdlLCB0eXBlPywgYWN0aW9uTGFiZWw/LCBoYW5kbGVBY3Rpb25DbGljaz8sIGNsb3NlT25BY3Rpb25DbGljaz8sIGR1cmF0aW9uPywgb25DbG9zZT8gfSlgIHwgU2hvdyBhIGhvc3QgdG9hc3Qgbm90aWZpY2F0aW9uLiBgbWVzc2FnZWAgYWNjZXB0cyBhIHN0cmluZyBvciBgUmVhY3RFbGVtZW50YC4gYHR5cGVgIGNhbiBiZSBgImluZm8iYCwgYCJkYW5nZXIiYCwgYCJ3YXJuaW5nImAsIGAiY2F1dGlvbiJgLCBvciBgInN1Y2Nlc3MiYCB8CnwgYHJiLmFsZXJ0KHsgdGl0bGU/LCBtZXNzYWdlLCBidXR0b25UZXh0PyB9KWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgYWxlcnQgZGlhbG9nLiBSZXNvbHZlcyB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmNvbmZpcm0oeyB0aXRsZT8sIG1lc3NhZ2UsIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgY29uZmlybWF0aW9uIGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gYHRydWVgIG9yIGBmYWxzZWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnByb21wdCh7IHRpdGxlPywgbWVzc2FnZSwgdmFsdWU/LCBwbGFjZWhvbGRlcj8sIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgcHJvbXB0IGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gdGhlIGVudGVyZWQgc3RyaW5nIG9yIGB1bmRlZmluZWRgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgpUb3BpYyBuYW1lcyBwYXNzZWQgdG8gYHB1YmAsIGBzdWJgLCBgYWN0aW9uYCwgYW5kIGBzZXJ2ZWAgYXJlIGlzb2xhdGVkIHBlciBwbHVnaW4uCgoKQWxsIG1ldGhvZHMgc3VwcG9ydCBHZW5lcmljIFR5cGVzOgoKYGBgdHN4CmNvbnN0IHN0YXR1cyA9IGF3YWl0IHJiLmFjdGlvbjx7IG9rOiBib29sZWFuIH0sIHsgaWQ6IG51bWJlciB9PigKICAiZ2V0LXN0YXR1cyIsCiAgeyBpZDogMSB9LAopOwoKY29uc3Qgc3ViID0gYXdhaXQgcmIuc3ViPHsgdmFsdWU6IG51bWJlciB9Pigic2Vuc29yL2RhdGEiLCAoZGF0YSkgPT4gewogIGNvbnNvbGUubG9nKGRhdGEudmFsdWUpOwp9KTsKc3ViLnVuZGVjbGFyZSgpOyAvLyBjbGVhbnVwCgpjb25zdCBvayA9IGF3YWl0IHJiLmNvbmZpcm0oewogIHRpdGxlOiAiUnVuIiwKICBtZXNzYWdlOiAiU3RhcnQgdGhlIGJhY2tlbmQgYWN0aW9uPyIsCn0pOwppZiAob2spIHsKICBhd2FpdCByYi5hY3Rpb24oInJ1biIpOwp9CmBgYAoKIyMjIFNhdmluZyBhbmQgcmVzdG9yaW5nIGZvcm0gZGF0YSAoYHVzZVJiRm9ybURhdGFgIC8gYHVzZVJiU2F2ZWApCgpJZiB0aGUgaG9zdCBlbWJlZHMgeW91ciBwbHVnaW4gaW4gYSBmb3JtIGl0IG93bnMgKGUuZy4gYSBwcm9ncmFtIHN0ZXAgZWRpdG9yCndpdGggaXRzIG93biBTYXZlIGJ1dHRvbiksIGl0IGNhbiBoYW5kIHlvdXIgcGx1Z2luIHByZXZpb3VzbHktc2F2ZWQgdmFsdWVzIGFuZApwdWxsIHRoZSBjdXJyZW50IHZhbHVlcyBiYWNrIG91dCB3aGVuIHRoZSB1c2VyIHNhdmVzLiBUaGUgaG9zdCDigJQgbm90IHRoZQpwbHVnaW4g4oCUIHBlcnNpc3RzIHRoZSBkYXRhIChJbmRleGVkREIsIGJhY2tlbmQsIGV0Yy4pLgoKYGBgdHN4CmltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSAicmVhY3QiOwppbXBvcnQgeyB1c2VSYkZvcm1EYXRhLCB1c2VSYlNhdmUgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwoKdHlwZSBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogc3RyaW5nOyB3aWR0aDogbnVtYmVyIH07CmNvbnN0IERFRkFVTFRTOiBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogIiIsIHdpZHRoOiAyMCB9OwoKZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwKCkgewogIC8vIFByZXZpb3VzbHktc2F2ZWQgdmFsdWVzLCBvciB1bmRlZmluZWQgZm9yIGEgYnJhbmQtbmV3IGluc3RhbmNlLgogIGNvbnN0IHNhdmVkID0gdXNlUmJGb3JtRGF0YTxHcmlwQXJncz4oKTsKICBjb25zdCBbYXJncywgc2V0QXJnc10gPSB1c2VTdGF0ZTxHcmlwQXJncz4oeyAuLi5ERUZBVUxUUywgLi4uc2F2ZWQgfSk7CgogIC8vIFJlZ2lzdGVycyBhIGdldHRlciB0aGUgaG9zdCBjYWxscyB3aGVuIGl0cyBTYXZlIGJ1dHRvbiBpcyBjbGlja2VkLgogIC8vIEFsd2F5cyByZXR1cm5zIHRoZSBDVVJSRU5UIHZhbHVlcyDigJQgcmUtcmVnaXN0ZXJpbmcgb24gZXZlcnkgcmVuZGVyIGtlZXBzCiAgLy8gdGhlIGNsb3N1cmUgZnJlc2gsIHdoaWNoIHVzZVJiU2F2ZSBhbHJlYWR5IGhhbmRsZXMgZm9yIHlvdS4KICB1c2VSYlNhdmUoKCkgPT4gKHsKICAgIGFyZ3MsCiAgICBzdW1tYXJ5OiBgJHthcmdzLnRhcmdldE5hbWUgfHwgInRhcmdldCJ9IMK3ICR7YXJncy53aWR0aH1tbWAsCiAgfSkpOwoKICByZXR1cm4gKC8qIC4uLmZvcm0gVUkgcmVhZGluZy93cml0aW5nIGBhcmdzYC4uLiAqLyk7Cn0KYGBgCgpUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBgdXNlUmJTYXZlYCBtdXN0IGJlIEpTT04tc2VyaWFsaXNhYmxlIOKAlCB0aGUgaG9zdApwZXJzaXN0cyBpdCBhcy1pcy4gTm90IGV2ZXJ5IGhvc3QgZW1iZWRzIHBsdWdpbnMgaW4gYSBzYXZlL3Jlc3RvcmUgZm9ybTsgaWYKeW91cnMgZG9lc24ndCwgeW91IGNhbiBza2lwIHRoZXNlIGhvb2tzIGVudGlyZWx5LgoKIyMjIFVJIGNvbXBvbmVudHMKCkltcG9ydCBNdXNjYXQgY29tcG9uZW50cyBmcm9tIGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3RgIGFuZCBleHBvcnQgYQpSZWFjdCBjb21wb25lbnQgYXMgdGhlIGRlZmF1bHQgZXhwb3J0LiBUaGUgaG9zdCBtb3VudHMgdGhhdCBjb21wb25lbnQgZGlyZWN0bHkKYW5kIHByb3ZpZGVzIGB1c2VSYigpYCB0aHJvdWdoIGNvbnRleHQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7IFJCTGFiZWxCdXR0b24sIFJCU2xpZGVyLCBSQlN3aXRjaCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9yZWFjdCI7CmltcG9ydCB7IHVzZVJiIH0gZnJvbSAiQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3NkayI7CgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt3aWR0aCwgc2V0V2lkdGhdID0gdXNlU3RhdGUoMjApOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwoKICByZXR1cm4gKAogICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICA8UkJTbGlkZXIKICAgICAgICB2YWx1ZT17W3dpZHRoXX0KICAgICAgICBtaW49ezB9CiAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgb25WYWx1ZUNoYW5nZT17KHZhbHVlczogbnVtYmVyW10pID0+IHNldFdpZHRoKHZhbHVlc1swXSA/PyAwKX0KICAgICAgLz4KICAgICAgPFJCU3dpdGNoIGNoZWNrZWQ9e2VuYWJsZWR9IG9uQ2hlY2tlZENoYW5nZT17c2V0RW5hYmxlZH0gLz4KICAgICAgPFJCTGFiZWxCdXR0b24KICAgICAgICBkaXNhYmxlZD17IWVuYWJsZWR9CiAgICAgICAgb25DbGljaz17KCkgPT4gcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KX0KICAgICAgPgogICAgICAgIEdyaXAKICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgPC9kaXY+CiAgKTsKfQpgYGAKCi0tLQoKIyMgRGV2ZWxvcGluZyBkaXJlY3RseSBvbiB0aGUgcm9ib3QgUEMKCklmIHlvdSdyZSBydW5uaW5nIGBtdXNjYXQtcGsgZGV2YCAqKm9uIHRoZSByb2JvdCBQQyBpdHNlbGYqKiwgTXVzY2F0IGFscmVhZHkgc2VydmVzIHRoZQpwbHVnaW4gZ2F0ZXdheSBvbiBwb3J0IDEwMDAwLiBUaGUgQ0xJIHNlZXMgdGhhdCwgZG9lcyBub3Qgc3RhcnQgaXRzIG93biBsb2NhbCBNdXNjYXQsIGFuZAp5b3VyIHBsdWdpbiBiYWNrZW5kIGNvbm5lY3RzIHRvIHRoZSByb2JvdCdzIGdhdGV3YXkg4oCUIGV4YWN0bHkgd2hhdCB5b3Ugd2FudCB3aGVuCmRldmVsb3Bpbmcgb24gdGhlIHJvYm90LgoKLS0tCgojIyBCYWNrZW5kIHJ1bnRpbWVzCgpgbWFuaWZlc3QuanNvbmAgY2hvb3NlcyBvbmUgYmFja2VuZCBydW50aW1lLiBgbXVzY2F0LXBrIGRldmAgcnVucyBiYWNrZW5kIGNvZGUgaW4KYSBEb2NrZXIgY29udGFpbmVyIG1hdGNoaW5nIHRoZSByb2JvdCBlbnZpcm9ubWVudC4gQmFja2VuZCBjb2RlIHNob3VsZCBjb250YWluCnBsdWdpbiBsb2dpYyBvbmx5OyBpdCBzaG91bGQgbm90IHN0YXJ0IGl0cyBvd24gY29weSBvZiB0aGUgcGx1Z2luIGdhdGV3YXkuCgojIyMgV2hpY2ggYmFja2VuZCBwYXR0ZXJuPyAoZGVwZW5kcyBvbiB0aGUgY29udHJpYnV0aW9uIHBvaW50KQoKKipIb3cgeW91IGNvbnRyb2wgdGhlIHJvYm90IGRlcGVuZHMgb24gd2hhdCB5b3VyIHBsdWdpbiBjb250cmlidXRlcyoqIChzZWUKYG1hbmlmZXN0Lmpzb25gIOKGkiBgY29udHJpYnV0ZXNbXS5wb2ludGApLiBEb24ndCBtaXggdGhlc2UgdXA6Cgp8IENvbnRyaWJ1dGlvbiBwb2ludCB8IFdoYXQgaXQgaXMgfCBCYWNrZW5kIHBhdHRlcm4gfAp8IC0tLSB8IC0tLSB8IC0tLSB8CnwgYHByb2dyYW0ucGFuZWxgICh3aXRoIGBjb21tYW5kSW5mb2ApIHwgRGVmaW5lcyBhICoqY3VzdG9tIGNvbW1hbmQqKiB0aGUgcGx1Z2luIGFkZHMgdG8gdGhlIFByb2dyYW0gcGFnZSdzIHJ1bGUtYmFzZWQgc2VxdWVuY2UgYnVpbGRlci4gVGhlIG9wZXJhdG9yIHBsYWNlcyBpdCBpbnRvIHRoZSBwcm9ncmFtIHRyZWUgbGlrZSBhbnkgYnVpbHQtaW4gY29tbWFuZCAoTW92ZSBKLCBQb2ludCwgV2FpdCwg4oCmKTsgaXQgcnVucyB3aGVuIHRoZSBwcm9ncmFtIHJlYWNoZXMgdGhhdCBzdGVwLiB8ICoqYFBsdWdpblByb2dyYW1Db250ZXh0YCoqIOKAlCBpbnRlZ3JhdGVkIHdpdGggdGhlIHByb2dyYW0ncyBzdG9wL3BhdXNlIGFuZCB2YXJpYWJsZXMuIFNlZSBfUHJvZ3JhbSBjb21tYW5kIGJhY2tlbmRfIGJlbG93LiB8CnwgYHRvb2xiYXJgIC8gYGxuYmAgLyBgbW92ZS5wYW5lbGAgfCBBIGxpdmUgVUkgcGFuZWwvcG9wb3ZlciB0aGUgb3BlcmF0b3IgaW50ZXJhY3RzIHdpdGggZGlyZWN0bHkgfCBDYWxsIHRoZSByb2JvdCAqKlNESyBkaXJlY3RseSoqIChgUkJNYW5pcHVsYXRlU0RLYCwgYFJCQW1yU0RLYCkgZnJvbSBgcHkvbWFpbi5weWAsIG9yIGByYi5hY3Rpb24oLi4uKWAg4oaSIHlvdXIgYmFja2VuZCDihpIgU0RLLiAqKk5vdCoqIGEgcHJvZ3JhbSBzdGVwIOKAlCB0aGVyZSBpcyBubyBzdG9wL3BhdXNlL3ZhcmlhYmxlIGNvbnRleHQuIHwKClJ1bGUgb2YgdGh1bWI6IHVzZSBgUGx1Z2luUHJvZ3JhbUNvbnRleHRgICoqb25seSoqIGZvciBhIGBwcm9ncmFtLnBhbmVsYCBjb21tYW5kCnRoYXQgcnVucyBhcyBwYXJ0IG9mIGEgcHJvZ3JhbS4gVG8gbW92ZSB0aGUgcm9ib3QgbGl2ZSBmcm9tIGEgdG9vbGJhci9tb3ZlIHBhbmVsLAp1c2UgdGhlIFNESyDigJQgYSBwcm9ncmFtLXN0ZXAgY29udGV4dCBkb2VzIG5vdCBhcHBseS4KCiMjIyBGcm9udGVuZC1vbmx5IChgbm9uZWApCgpVc2UgdGhpcyB3aGVuIHRoZSBwbHVnaW4gb25seSBoYXMgVUkgYW5kIGNhbGxzIGhvc3Qgc2VydmljZXM6CgpgYGBqc29uCnsgInJ1bnRpbWUiOiB7ICJ0eXBlIjogIm5vbmUiIH0gfQpgYGAKCiMjIyBQeXRob24KClB5dGhvbiBwbHVnaW5zIHVzZSBgcHkvbWFpbi5weWAgYW5kIGNhbiBjb21tdW5pY2F0ZSB3aXRoIHRoZSBVSSB0aHJvdWdoCmByYWluYm93LnJiX3Nkay5SQlBsdWdpbkNhbGxgLgoKYGBgcHl0aG9uCmltcG9ydCB0aW1lCmZyb20gcmFpbmJvdy5yYl9zZGsgaW1wb3J0IFJCQW1yU0RLLCBSQk1hbmlwdWxhdGVTREssIFJCUGx1Z2luQ2FsbAoKcGx1Z2luID0gUkJQbHVnaW5DYWxsKCkKCgpwbHVnaW4ucHVibGlzaCgic3RhdGUiLCB7InJlYWR5IjogVHJ1ZX0pCgoKQHBsdWdpbi5zdWJzY3JpYmUoImV2ZW50IikKZGVmIG9uX3VpX2V2ZW50KHBheWxvYWQ9Tm9uZSk6CiAgICBwcmludChwYXlsb2FkKQoKCkBwbHVnaW4uc2VydmUoInRvb2wvZWNobyIpCmRlZiBlY2hvKHBheWxvYWQ9Tm9uZSk6CiAgICByZXR1cm4geyJlY2hvIjogcGF5bG9hZH0KCgpkZWYgY2FsbF9mcm9udGVuZCgpOgogICAgcmVzID0gcGx1Z2luLmNhbGwoInRvb2wvcGluZyIsIHBheWxvYWQ9eyJoZWxsbyI6ICJwbHVnaW4ifSkKICAgIHByaW50KHJlcykKCgpkZWYgbW92ZV9qX2V4YW1wbGUoKToKICAgIGFtciA9IFJCQW1yU0RLKCkKICAgIG1hbmlwdWxhdGUgPSBSQk1hbmlwdWxhdGVTREsoKQogICAgcmV0dXJuIG1hbmlwdWxhdGUubW92ZS5jYWxsX21vdmVfaigKICAgICAgICByb2JvdF9tb2RlbD0iQzUwMDkyMCIsCiAgICAgICAgdGFyZ2V0PXsidGFyX3ZhbHVlcyI6IFswLCAwLCAwLCAwLCAwLCAwXSwgInRhcl9mcmFtZSI6IDAsICJ0YXJfdW5pdCI6IDB9LAogICAgKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB3aGlsZSBUcnVlOgogICAgICAgIHRpbWUuc2xlZXAoMSkKYGBgCgojIyMjIEV4dGVybmFsIGVuZHBvaW50cyAoYHBsdWdpbi5yb3V0ZXJgKQoKYHBsdWdpbi5zZXJ2ZWAgLyBgcGx1Z2luLnN1YnNjcmliZWAgLyBgcGx1Z2luLnB1Ymxpc2hgIGFyZSAqKmludGVybmFsIG9ubHkqKiAocGx1Z2luClVJIOKGlCBiYWNrZW5kLCBwbHVnaW4g4oaUIHBsdWdpbikuIFRvIGV4cG9zZSBhbiBlbmRwb2ludCB0byB0aGUgb3V0c2lkZSB3b3JsZCDigJQKUkVTVCwgU29ja2V0LklPLCBUQ1AsIE1RVFQsIFdlYlJUQyDigJQgdXNlIGBwbHVnaW4ucm91dGVyYC4gRGVjbGFyaW5nIG9uZSBpcyBhCnNpbmdsZSBkZWNvcmF0b3I7IHRoZSBydW5uaW5nIE11c2NhdCAoYGNvbW1vbmApIHBpY2tzIGl0IHVwIHdpdGhvdXQgYSByZXN0YXJ0LAphbmQgaXQgZGlzYXBwZWFycyB3aGVuIHRoZSBwbHVnaW4gc3RvcHMgb3IgaXMgcmVtb3ZlZC4KCj4gUmVxdWlyZXMgYSByb2JvdCBydW5uaW5nIGByYWluYm93LXJiLXNka2AgKiowLjAuOS5kZXY1IG9yIG5ld2VyKiogKHRoZSBTREsgaXMKPiBwcm92aWRlZCBieSB0aGUgcGx1Z2luIGNvbnRhaW5lciBhdCBydW50aW1lKS4gT24gb2xkZXIgcm9ib3RzIGBwbHVnaW4ucm91dGVyYAo+IGRvZXMgbm90IGV4aXN0IGFuZCByYWlzZXMgYEF0dHJpYnV0ZUVycm9yYC4KCmBgYHB5dGhvbgpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQlBsdWdpbkNhbGwKZnJvbSByYWluYm93LnJiX3Nkay5wbHVnaW4gaW1wb3J0IFBsdWdpblJvdXRlRXJyb3IKCnBsdWdpbiA9IFJCUGx1Z2luQ2FsbCgpICAjIHBsdWdpbl9pZCBjb21lcyBmcm9tIGVudiBSQl9QTFVHSU5fSUQKCgpAcGx1Z2luLnJvdXRlci5vbigiL2hlbGxvIikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhbGwgNSB0cmFuc3BvcnRzCmRlZiBoZWxsbyhwYXlsb2FkOiBkaWN0LCBtZXRhOiBkaWN0KToKICAgIHJldHVybiB7Im1zZyI6IGYiaGkge3BheWxvYWQuZ2V0KCduYW1lJyl9In0gICAgICAgICAgICAgICMgcmV0dXJuIHZhbHVlID0gcmVzcG9uc2UgYm9keQoKCkBwbHVnaW4ucm91dGVyLm9uKCIvYWRtaW4iLCBleHBsaWNpdF9yb3V0ZXM9WyJhcGkiXSkgICAgICAgICAjIFJFU1Qgb25seQpkZWYgYWRtaW4ocGF5bG9hZCwgbWV0YSk6CiAgICBpZiBub3QgKG1ldGEuZ2V0KCJwcmluY2lwYWwiKSBvciB7fSkuZ2V0KCJpc19hZG1pbiIpOgogICAgICAgIHJhaXNlIFBsdWdpblJvdXRlRXJyb3IoNDAzLCAiYWRtaW4gb25seSIpICAgICAgICAgICAgIyBiZWNvbWVzIHRoZSBleHRlcm5hbCBzdGF0dXMKICAgIC4uLgoKCkBwbHVnaW4ucm91dGVyLnN1YnNjcmliZSgiL2NtZCIsIGV4cGxpY2l0X2V2ZW50cz1bInRjcCJdKSAgICAjIHJlY2VpdmUgZXh0ZXJuYWwgVENQIHB1Ymxpc2gKZGVmIG9uX2NtZChwYXlsb2FkOiBkaWN0KToKICAgIC4uLgoKCnBsdWdpbi5yb3V0ZXIuZW1pdCgiL3N0YXRlIiwgeyJidXN5IjogVHJ1ZX0pICAgICAgICAgICAgICAgICAjIHB1c2ggdG8gZXh0ZXJuYWwgc3Vic2NyaWJlcnMKYGBgCgp8IEFQSSB8IE1lYW5pbmcgfCBFeHRlcm5hbCBhZGRyZXNzIHwKfCAtLS0gfCAtLS0gfCAtLS0gfAp8IGByb3V0ZXIub24ocGF0aCwgZXhwbGljaXRfcm91dGVzPU5vbmUpYCB8IHJlcXVlc3QvcmVzcG9uc2UgaGFuZGxlciB8IGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3twYXRofWAgKFJFU1QgaXMgYWx3YXlzIGBQT1NUYCkgfAp8IGByb3V0ZXIuc3Vic2NyaWJlKHRvcGljLCBleHBsaWNpdF9ldmVudHM9Tm9uZSlgIHwgcmVjZWl2ZSBleHRlcm5hbCBwdWJsaXNoZXMgfCBleHRlcm5hbCBzaWRlIHB1Ymxpc2hlcyB0byBgY29tbW9uL3BsdWdpbi97cGx1Z2luX2lkfS97dG9waWN9YCB8CnwgYHJvdXRlci5lbWl0KHRvcGljLCBwYXlsb2FkKWAgfCBwbHVnaW4g4oaSIGV4dGVybmFsIHB1c2ggfCBleHRlcm5hbCBzaWRlIHN1YnNjcmliZXMgdG8gYGNvbW1vbi9wbHVnaW4ve3BsdWdpbl9pZH0ve3RvcGljfWAgfAoKLSBUaGUgYHBsdWdpbl9pZGAgcHJlZml4IGlzIGFkZGVkIGJ5IHRoZSBTREsg4oCUIHdyaXRlIG9ubHkgdGhlIHBhdGggaW4gcGx1Z2luIGNvZGUuCi0gUGF0aHMgbWF5IGhhdmUgc2V2ZXJhbCBzZWdtZW50cyAoYC90b29sL2VjaG9gKS4gRGVjbGFyaW5nIHRoZSBzYW1lIHBhdGggdHdpY2UgcmFpc2VzIGBWYWx1ZUVycm9yYC4KLSBUcmFuc3BvcnQgbmFtZXM6IGBhcGkgfCBzb2NrZXQgfCB0Y3AgfCBtcXR0IHwgd2VicnRjYC4gYHN1YnNjcmliZWAgYWNjZXB0cyBvbmx5IGB0Y3AgfCBtcXR0IHwgd2VicnRjYC4gVW5rbm93biBuYW1lcyByYWlzZSBgVmFsdWVFcnJvcmAuCi0gYGV4cGxpY2l0X3JvdXRlc2AgLyBgZXhwbGljaXRfZXZlbnRzYCBvZiBgTm9uZWAgbWVhbnMgZXZlcnkgdHJhbnNwb3J0LiBBIHJlcXVlc3Qgb24gYSB0cmFuc3BvcnQgbm90IGxpc3RlZCBnZXRzIDQwNC4KCkhhbmRsZXIgY29udHJhY3Q6CgotIFNpZ25hdHVyZSBgKHBheWxvYWQsIG1ldGEpYCwgYChwYXlsb2FkKWAgb3IgYCgpYCDigJQgb25seSB0aGUgYXJndW1lbnRzIHlvdSBkZWNsYXJlIGFyZSBpbmplY3RlZC4gU3luYyBhbmQgYXN5bmMgYm90aCB3b3JrLgotIGBwYXlsb2FkYDogd2hhdCB0aGUgY2FsbGVyIHNlbnQgKGZvciBSRVNUOiBKU09OIGJvZHkgbWVyZ2VkIHdpdGggcXVlcnkgcGFyYW1zKS4gVGhlIHNoYXBlIGlzIHVwIHRvIHRoZSBwbHVnaW4uCi0gYG1ldGFgOiBgeyJ0cmFuc3BvcnQiOiAiYXBpInwic29ja2V0InwidGNwInwibXF0dCJ8IndlYnJ0YyIsICJwcmluY2lwYWwiOiBkaWN0IHwgTm9uZX1gLiBXaGVuIHRoZSByb2JvdCdzIGxvZ2luIHBvbGljeSBpcyBvbiwgYHByaW5jaXBhbGAgaG9sZHMgdGhlIHRva2VuIHN1YmplY3QuICoqUm9sZSBjaGVja3MgYXJlIHRoZSBwbHVnaW4ncyBqb2IqKiDigJQgaW5zcGVjdCBgbWV0YVsicHJpbmNpcGFsIl1gIHlvdXJzZWxmLgotIFRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIHJlc3BvbnNlIGJvZHkgKG11c3QgYmUgSlNPTi1zZXJpYWxpc2FibGUpLiBgTm9uZWAg4oaSIGVtcHR5IHJlc3BvbnNlLgotIFN0YXR1cyBjb2RlczogYHJhaXNlIFBsdWdpblJvdXRlRXJyb3IoY29kZSwgbWVzc2FnZSlgLiBBbnkgb3RoZXIgZXhjZXB0aW9uIOKGkiA1MDAgd2l0aCBgc3RyKGV4YylgIGFzIHRoZSBtZXNzYWdlLgotIGBzdWJzY3JpYmVgIGhhbmRsZXJzIHRha2UgYChwYXlsb2FkKWAgb25seSBhbmQgcmV0dXJuIG5vdGhpbmcuCgojIyMjIENhbGxpbmcgcGx1Z2luIGVuZHBvaW50cyBmcm9tIG91dHNpZGUKCnwgVHJhbnNwb3J0IHwgSG93IHwKfCAtLS0gfCAtLS0gfAp8IFJFU1QgfCBgUE9TVCAvY29tbW9uL3BsdWdpbi97cGx1Z2luX2lkfS97cGF0aH1gICh0aHJvdWdoIHRoZSBhcGktZ2F0ZXdheSksIEpTT04gYm9keSB8CnwgU29ja2V0LklPIHwgZW1pdCBldmVudCBgY29tbW9uL3BsdWdpbi97cGx1Z2luX2lkfS97cGF0aH1gLCByZXNwb25zZSBhcnJpdmVzIGluIHRoZSBhY2sgfAp8IFRDUCB8IHRvcGljIGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3twYXRofWAgcmVxdWVzdCAvIHB1Ymxpc2ggfAp8IE1RVFQgfCByZXF1ZXN0OiBgY29tbW9uL3BsdWdpbi97cGx1Z2luX2lkfS97cGF0aH0vX19yZXFfX2AsIHB1Ymxpc2g6IGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3t0b3BpY31gIHwKfCBXZWJSVEMgfCBkYXRhIGNoYW5uZWwgdG9waWMgYGNvbW1vbi9wbHVnaW4ve3BsdWdpbl9pZH0ve3BhdGh9YCB8CgpBdXRoOiB3aGVuIHRoZSByb2JvdCdzIGxvZ2luIHBvbGljeSBpcyBvbiwgYSB0b2tlbiBpcyAqKnJlcXVpcmVkKiogKGFueSByb2xlIOKAlCBHVUVTVCBwYXNzZXMpLiBXaGVuIGl0IGlzIG9mZiwgY2FsbHMgZ28gc3RyYWlnaHQgdGhyb3VnaC4gUkVTVCB1c2VzIHRoZSBzYW1lIEJlYXJlciB0b2tlbiBhcyB0aGUgb3RoZXIgTXVzY2F0IEFQSXMuCgpgYGBiYXNoCmN1cmwgLXMgLVggUE9TVCBodHRwOi8vPHJvYm90Pi9jb21tb24vcGx1Z2luL215LXBsdWdpbi9oZWxsbyBcCiAgLUggJ0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbicgLWQgJ3sibmFtZSI6ImtpbSJ9JwpgYGAKCnwgU2l0dWF0aW9uIHwgU3RhdHVzIHwKfCAtLS0gfCAtLS0gfAp8IE5vIHBsdWdpbiBkZWNsYXJlcyB0aGF0IHBhdGggLyBwbHVnaW4gaXMgZG93biAvIHRyYW5zcG9ydCBub3QgYWxsb3dlZCB8IDQwNCB8CnwgUGx1Z2luIGRpZCBub3QgYW5zd2VyIHdpdGhpbiAxMCBzIHwgNTA0IHwKfCBgY29tbW9uYCDihpQgZ2F0ZXdheSBub3QgY29ubmVjdGVkIHwgNTAzIHwKfCBIYW5kbGVyIHJhaXNlZCB8IDUwMCAoYFBsdWdpblJvdXRlRXJyb3JgIOKGkiBpdHMgYGNvZGVgKSB8CgpLbm93biBsaW1pdHM6CgotIEEgcGx1Z2luIHBhdGggbmFtZWQgYGluc3RhbGxgIGNhbm5vdCBiZSBjYWxsZWQgb3ZlciBSRVNUIChgUE9TVCAvY29tbW9uL3BsdWdpbi97aWR9L2luc3RhbGxgIGlzIHRha2VuIGJ5IHRoZSByZWdpc3RyeSBpbnN0YWxsIHJvdXRlIGZpcnN0KS4gU29ja2V0L1RDUCBhcmUgdW5hZmZlY3RlZC4KLSBTd2FnZ2VyIHNob3dzIG9uZSBjYXRjaC1hbGwgcm91dGUsIG5vdCBwZXItcGx1Z2luIHBhdGhzLgotIFRoZSBNUVRUIGJyb2tlciBlY2hvZXMgdG8gdGhlIHNlbmRlcjogYSBwbHVnaW4gdGhhdCBgZW1pdGBzIGFuZCBgc3Vic2NyaWJlYHMgdGhlIHNhbWUgdG9waWMgcmVjZWl2ZXMgaXRzIG93biBwdXNoIG92ZXIgYG1xdHRgLiBEcm9wIGBtcXR0YCBmcm9tIGBleHBsaWNpdF9ldmVudHNgIG9yIHVzZSBzZXBhcmF0ZSB0b3BpY3MuIChUQ1AgaXMgZmlsdGVyZWQgYnkgYHNlbmRlcl9pZGAuKQotIGBvbmAgYW5kIGBzdWJzY3JpYmVgIG1heSBzaGFyZSBhIG5hbWUg4oCUIHRoZXkgbGl2ZSBpbiBzZXBhcmF0ZSB0YWJsZXMuCgpEdXJpbmcgYG11c2NhdC1wayBkZXZgIHRoZSBsb2NhbCBNdXNjYXQgcnVudGltZSB0YWtlcyB0aGUgYHJvdXRlci4qYCByZWdpc3RyYXRpb25zCm9uIGl0cyBnYXRld2F5IChwb3J0IGAxMDAwMGApLCBhbmQgaXRzIGBjb21tb25gIChwb3J0IGAzMDAwYCkgcm91dGVzCmBjb21tb24vcGx1Z2luLy4uLmAgdG8gdGhlbSBsaWtlIG9uIHRoZSByb2JvdCDigJQgdHJ5CmBjdXJsIGh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC9jb21tb24vcGx1Z2luLzxwbHVnaW4taWQ+LzxwYXRoPmAuIEFmdGVyIHJlc3RhcnRpbmcgdGhlIHBsdWdpbiBwcm9jZXNzLApleHRlcm5hbCBjYWxscyBtYXkgcmV0dXJuIDUwNCBmb3IgdXAgdG8gYWJvdXQgYSBtaW51dGUgKHVudGlsIHRoZSBnYXRld2F5IG5vdGljZXMKdGhlIG9sZCBzb2NrZXQgaXMgZ29uZSksIHRoZW4gNDA0IOKAlCB0aGF0IGlzIGV4cGVjdGVkLgoKIyMjIyBQcm9ncmFtIGNvbW1hbmQgYmFja2VuZCAoYHByb2dyYW0ucGFuZWxgKQoKQSBgcHJvZ3JhbS5wYW5lbGAgY29udHJpYnV0aW9uIGRlZmluZXMgYSAqKmN1c3RvbSBjb21tYW5kKiogeW91ciBwbHVnaW4gYWRkcyB0bwp0aGUgTXVzY2F0ICoqUHJvZ3JhbSBwYWdlKiosIHdoZXJlIHRoZSBvcGVyYXRvciBidWlsZHMgYSByb2JvdCBwcm9ncmFtIGFzIGEKcnVsZS1iYXNlZCBzZXF1ZW5jZSAoYSBwcm9ncmFtIHRyZWUpLiBZb3VyIGNvbW1hbmQgYXBwZWFycyBhbG9uZ3NpZGUgdGhlCmJ1aWx0LWlucyAoTW92ZSBKLCBQb2ludCwgV2FpdCwg4oCmKTsgdGhlIG9wZXJhdG9yIHBsYWNlcyBpdCBpbnRvIHRoZSB0cmVlLCBhbmQKZWFjaCB0aW1lIHRoZSBwcm9ncmFtIGV4ZWN1dGVzIHRoYXQgc3RlcCB0aGUgaG9zdCBjYWxscyB5b3VyIGJhY2tlbmQgdGhyb3VnaApgUGx1Z2luUHJvZ3JhbUNvbnRleHRgIOKAlCByZWNlaXZpbmcgdGhlIHN0ZXAgYXJncywgY2hlY2tpbmcgZm9yIHN0b3AvcGF1c2UsCnJlYWRpbmcvd3JpdGluZyBwcm9ncmFtIHZhcmlhYmxlcywgYW5kIHNpZ25hbGxpbmcgY29tcGxldGlvbi4gVGhpcyBwYXR0ZXJuIGlzCioqb25seSoqIGZvciBgcHJvZ3JhbS5wYW5lbGA7IGEgdG9vbGJhci9tb3ZlLXBhbmVsIHBsdWdpbiB1c2VzIHRoZSBTREsgZGlyZWN0bHkKaW5zdGVhZCAoc2VlIHRoZSB0YWJsZSBhYm92ZSkuCgpgYGBweXRob24KIiIiClBsdWdpbiBiYWNrZW5kIG1haW4ucHkgZXhhbXBsZSAocHJvZ3JhbS5wYW5lbCBjb21tYW5kKS4KCm1hbmlmZXN0Lmpzb246CiAgInJ1bnRpbWUiOiB7InR5cGUiOiAicHl0aG9uIiwgImVudHJ5IjogIm1haW4ucHkifSwKICAiY29udHJpYnV0ZXMiOiBbewogICAgInBvaW50IjogInByb2dyYW0ucGFuZWwiLAogICAgInVpIjogInByb2dyYW0iLAogICAgImxhYmVsIjogeyJlbiI6ICJNeSBQbHVnaW4gU3RlcCJ9LAogICAgImNvbW1hbmRJbmZvIjogewogICAgICAibmFtZSI6ICJNeSBQbHVnaW4gU3RlcCIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJmdW5jTmFtZSI6ICJyYl9wcm9ncmFtX3Nkay5wbHVnaW5fZXhlY3V0ZSIsCiAgICAgICJhcmdzIjogeyJtZXNzYWdlIjogImhlbGxvIn0gICAjIHBsdWdpbi1hdXRob3ItZGVmaW5lZCBhcmdzCiAgICB9CiAgfV0KClRoZSBob3N0IGludm9rZXMgY29tbWFuZEluZm8uZnVuY05hbWUgKHJiX3Byb2dyYW1fc2RrLnBsdWdpbl9leGVjdXRlKSB3aXRoCmFyZ3MucGx1Z2luX2lkICsgeW91ciBhcmdzIHdoZW4gdGhlIHByb2dyYW0gcmVhY2hlcyB0aGlzIHN0ZXAuCiIiIgppbXBvcnQgYXN5bmNpbwpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBQbHVnaW5Qcm9ncmFtQ29udGV4dAoKY3R4ID0gUGx1Z2luUHJvZ3JhbUNvbnRleHQocGx1Z2luX2lkPSJteS1wbHVnaW4iKQoKCkBjdHgub25fZXhlY3V0ZQphc3luYyBkZWYgaGFuZGxlKGFyZ3M6IGRpY3QpIC0+IE5vbmU6CiAgICAiIiJDYWxsZWQgb25jZSB3aGVuIG15IFN0ZXAgZXhlY3V0ZXMuIFZhcmlhYmxlIHdyaXRlcyBhcHBseSB0byB0aGUKICAgIHJ1bm5pbmcgcHJvZ3JhbSBpbW1lZGlhdGVseSArIGJyb2FkY2FzdCB0byBvdGhlciByb2JvdHMnIG1haW4gdGFza3MuIiIiCiAgICBjb3VudCA9IGF3YWl0IGN0eC5nZXRfdmFyaWFibGUoImNvdW50ZXIiKSAgICAgICAgICAjIHJlYWQgYW4gZXhpc3RpbmcgcHJvZ3JhbSB2YXJpYWJsZQogICAgYXdhaXQgY3R4LnNldF92YXJpYWJsZSgiY291bnRlciIsIGNvdW50ICsgMSkgICAgICAgIyB1cGRhdGUgYW4gZXhpc3RpbmcgdmFyaWFibGUg4oCUIGFsbG93ZWQKICAgIGF3YWl0IGN0eC5zZXRfdmFyaWFibGUoIlJCUF9URVNUIiwgMSkgICAgICAgICAgICAgICMgTkVXIHZhcmlhYmxlcyBtdXN0IHN0YXJ0IHdpdGggUkJQXwoKICAgIGZvciBpIGluIHJhbmdlKDEwMCk6CiAgICAgICAgYXdhaXQgY3R4LmNoZWNrX3N0b3AoKSAgICMgYXV0by1zY29wZWQgdG8gdGhpcyBTdGVwJ3Mgcm9ib3QgbW9kZWwKICAgICAgICBhd2FpdCBhc3luY2lvLnNsZWVwKDAuNSkKCiAgICBhd2FpdCBjdHguZG9uZSgpCgoKYXN5bmMgZGVmIGJhY2tncm91bmRfbW9uaXRvcigpIC0+IE5vbmU6CiAgICAiIiJSZXNpZGVudCB0YXNrIG91dHNpZGUgYW55IFN0ZXAuIElmIG5vIHByb2dyYW0gaXMgcnVubmluZywKICAgIGdldCByZXR1cm5zIE5vbmUgYW5kIHNldCBpcyBzaWxlbnRseSBpZ25vcmVkIOKAlCBhbHdheXMgc2FmZSB0byBjYWxsLiIiIgogICAgd2hpbGUgVHJ1ZToKICAgICAgICBhd2FpdCBhc3luY2lvLnNsZWVwKDEuMCkKCiAgICAgICAgIyB0YXJnZXRzIGV2ZXJ5IHJ1bm5pbmcgbWFpbiB0YXNrIChubyByb2JvdF9tb2RlbCBwYXJhbSDigJQgYWx3YXlzIGJyb2FkY2FzdCkKICAgICAgICBhd2FpdCBjdHguc2V0X3ZhcmlhYmxlKCJSQlBfVEVTVCIsIDMpCgogICAgICAgICMgZ2V0IG9wdGlvbnMKICAgICAgICB2MSA9IGF3YWl0IGN0eC5nZXRfdmFyaWFibGUoImNvdW50ZXIiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICMgZmlyc3QgdmFsdWUgZm91bmQgaW4gdGhlIHdob2xlIHRyZWUKICAgICAgICB2MiA9IGF3YWl0IGN0eC5nZXRfdmFyaWFibGUoImNvdW50ZXIiLCByb2JvdF9tb2RlbD0iQzUwMDkyMCIpICAgICMgYSBzcGVjaWZpYyByb2JvdAogICAgICAgIHYzID0gYXdhaXQgY3R4LmdldF92YXJpYWJsZSgiUkJQX1RFU1QiLCBwbHVnaW5faWQ9Im15LXBsdWdpbiIpICAgIyB0aGUgdmFsdWUgbXktcGx1Z2luIGxhc3Qgd3JvdGUKCiAgICAgICAgaWYgY3R4LmV4ZWN1dG9yX3N0YXRlKCJDNTAwOTIwIikgPT0gInBhdXNlZCI6CiAgICAgICAgICAgIHByaW50KCJDNTAwOTIwIHByb2dyYW0gaXMgcGF1c2VkIikKCgphc3luYyBkZWYgbWFpbigpIC0+IE5vbmU6CiAgICBhc3luY2lvLmNyZWF0ZV90YXNrKGJhY2tncm91bmRfbW9uaXRvcigpKQogICAgYXdhaXQgY3R4LnN0YXJ0KCkgICMgc3RheXMgcmVzaWRlbnQKCgphc3luY2lvLnJ1bihtYWluKCkpCmBgYAoKIyMjIyBQcm9ncmFtIHZhcmlhYmxlcyAmIGV4ZWN1dG9yIHN0YXRlIChgUGx1Z2luUHJvZ3JhbUNvbnRleHRgKQoKYHJhaW5ib3cucmJfc2RrLlBsdWdpblByb2dyYW1Db250ZXh0YCBsZXRzIHRoZSBwbHVnaW4gcHJvY2VzcyBpbnRlcmFjdCB3aXRoIHRoZQpydW5uaW5nIHByb2dyYW0gKFB5Rk0pOiByZWFkL3dyaXRlIHByb2dyYW0gdmFyaWFibGVzIGFuZCBvYnNlcnZlIGV4ZWN1dGlvbgpzdGF0ZSDigJQgaW5zaWRlIGEgU3RlcCBoYW5kbGVyIG9yIGZyb20gYSByZXNpZGVudCB0YXNrLCBhdCBhbnkgdGltZS4KCi0gVGhlIGBvbl9leGVjdXRlYCBoYW5kbGVyIGlzIGNhbGxlZCAqKm9ubHkgd2hlbiBQeUZNIGV4ZWN1dGVzIHRoaXMgcGx1Z2luJ3MKICBTdGVwKiouIE9uZSBTdGVwIGV4ZWN1dGlvbiA9IG9uZSBoYW5kbGVyIGNhbGwsIGFuZCB0aGUgU3RlcCBkb2VzIG5vdCBmaW5pc2gKICB1bnRpbCB5b3UgY2FsbCBgY3R4LmRvbmUoKWAg4oCUIGFsd2F5cyBjYWxsIGl0LgotIFRoZSBwbHVnaW4gcHJvY2VzcyBpdHNlbGYgc3RheXMgcmVzaWRlbnQgYWZ0ZXIgYGN0eC5zdGFydCgpYDsgZXhlY3V0b3Igc3RhdGUKICBxdWVyaWVzIGFuZCB2YXJpYWJsZSBhY2Nlc3MgYmVsb3cga2VlcCB3b3JraW5nIHdoZXRoZXIgb3Igbm90IGEgU3RlcCBpcwogIGV4ZWN1dGluZy4KCiMjIyMgVmFyaWFibGUgbmFtaW5nIHJ1bGVzIChpbXBvcnRhbnQpCgpQeUZNIHZhcmlhYmxlcyBhcmUgYSAqKnByb2dyYW0td2lkZSBzaGFyZWQgbmFtZXNwYWNlKiouIE9uZSBydWxlOgoKLSAqKk1vZGlmeWluZyBhbiBleGlzdGluZyB2YXJpYWJsZSoqIOKAlCB0aGUgbmFtZSBwYXNzZXMgYXMtaXMuIEV4Y2hhbmdpbmcKICB2YXJpYWJsZXMgYmV0d2VlbiB0aGUgcHJvZ3JhbSBhbmQgdGhlIHBsdWdpbiBpcyB0aGUgaW50ZW5kZWQgdXNhZ2UuCi0gKipDcmVhdGluZyBhIHZhcmlhYmxlIHRoYXQgZG9lc24ndCBleGlzdCoqIOKAlCB0aGUgYFJCUF9gIHByZWZpeCBpcwogICoqcmVxdWlyZWQqKiAoZW5mb3JjZWQgYnkgdGhlIFNESy9zZXJ2ZXI7IGEgdmlvbGF0aW9uIHJhaXNlcwogIGBSdW50aW1lRXJyb3JgKS4gQXBwbGllcyBlcXVhbGx5IGluc2lkZSBhbmQgb3V0c2lkZSBTdGVwIGV4ZWN1dGlvbi4KCkZvciBuZXcgdmFyaWFibGUgbmFtZXMsIGEgY29udmVudGlvbiB0aGF0IGluY2x1ZGVzIHRoZSBwbHVnaW4gaWQgaXMgc3Ryb25nbHkKcmVjb21tZW5kZWQ6CgpgYGAKUkJQX3twbHVnaW5faWR9X3tuYW1lfQoKZS5nLiBSQlBfdmlzaW9uX2RldGVjdF9jb3VudCwgUkJQX2dyaXBwZXJfbGFzdF9lcnJvcgpgYGAKCldoeToKCi0gYFJCUF9gIOKAlCBpbnN0YW50bHkgaWRlbnRpZmllcyBwbHVnaW4tY3JlYXRlZCB2YXJpYWJsZXMgaW4gdGhlIHByb2dyYW0KICBlZGl0b3IvVUkuCi0gYHtwbHVnaW5faWR9YCDigJQgKipwcmV2ZW50cyBuYW1lIGNvbGxpc2lvbnMgd2l0aCBvdGhlciBwbHVnaW5zLioqIElmIHR3bwogIHBsdWdpbnMgdXNlIHRoZSBzYW1lIG5hbWUgdGhleSBvdmVyd3JpdGUgdGhlIHNhbWUgdmFyaWFibGUgKGBSQlBfYCBhbG9uZSBpcwogIG5vdCBzb21ldGhpbmcgdGhlIFNESyBndWFyZHMgYWdhaW5zdCkuCgojIyMjIFJlYWRpbmcgLyB3cml0aW5nIHZhcmlhYmxlcwoKYGBgcHl0aG9uCnZhbHVlID0gYXdhaXQgY3R4LmdldF92YXJpYWJsZSgiY291bnRlciIpICAgICAgICAgICAgICAgICAjIHJlYWQgKG5vIG5hbWUgcmVzdHJpY3Rpb24pCmF3YWl0IGN0eC5zZXRfdmFyaWFibGUoImNvdW50ZXIiLCB2YWx1ZSArIDEpICAgICAgICAgICAgICAjIG1vZGlmeSBleGlzdGluZyB2YXJpYWJsZSDigJQgYWxsb3dlZAphd2FpdCBjdHguc2V0X3ZhcmlhYmxlKCJSQlBfbXktcGx1Z2luX3Jlc3VsdCIsIDQyKSAgICAgICAgIyBjcmVhdGUgbmV3IHZhcmlhYmxlIOKAlCBSQlBfIHJlcXVpcmVkCmBgYAoKYHNldF92YXJpYWJsZWAgYWx3YXlzIGFwcGxpZXMgdG8gKipldmVyeSBydW5uaW5nIG1haW4gdGFzayoqIChhIHBsdWdpbiBiZWxvbmdzCnRvIG11c2NhdCwgbm90IHRvIGEgc3BlY2lmaWMgcm9ib3Qg4oCUIHRoZXJlIGlzIG5vIGByb2JvdF9tb2RlbGAgcGFyYW1ldGVyKToKCnwgV2hlbiB8IE93biBwcm9ncmFtIHwgT3RoZXIgcm9ib3RzJyBtYWluIHRhc2tzIHwKfC0tLXwtLS18LS0tfAp8IER1cmluZyBvd24gU3RlcCBleGVjdXRpb24gfCB2aWEgdGhlIGNvbnRyb2wgcXVlcnlhYmxlIOKAlCAqKmltbWVkaWF0ZSoqIHwgYnJvYWRjYXN0IOKAlCBlYWNoIGF0IGl0cyBuZXh0IFN0ZXAgYm91bmRhcnkgfAp8IE91dHNpZGUgYSBTdGVwIChyZXNpZGVudCB0YXNrLCDigKYpIHwgcmVzaWRlbnQgZW5kcG9pbnQg4oCUIG5leHQgU3RlcCBib3VuZGFyeSB8IHNhbWUgfAoKYGdldF92YXJpYWJsZWAgaGFzIG9wdGlvbnM6CgpgYGBweXRob24KYXdhaXQgY3R4LmdldF92YXJpYWJsZSgiY291bnRlciIpICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNlYXJjaCBhbGwgbWFpbiB0YXNrcyAoZmlyc3QgdmFsdWUgZm91bmQpCmF3YWl0IGN0eC5nZXRfdmFyaWFibGUoImNvdW50ZXIiLCByb2JvdF9tb2RlbD0iQzUwMDkyMCIpICAgIyBhIHNwZWNpZmljIHJvYm90J3MgdmFsdWUKYXdhaXQgY3R4LmdldF92YXJpYWJsZSgiUkJQX1RFU1QiLCBwbHVnaW5faWQ9IkEucGx1Z2luIikgICAjIHRoZSB2YWx1ZSB0aGF0IHBsdWdpbiBsYXN0IHdyb3RlCmBgYAoKQ2F2ZWF0czoKCi0gSWYgbm8gcHJvZ3JhbSBpcyBydW5uaW5nLCBgc2V0X3ZhcmlhYmxlYCBpcyAqKnNpbGVudGx5IGlnbm9yZWQqKiBhbmQKICBgZ2V0X3ZhcmlhYmxlYCByZXR1cm5zIGBOb25lYC4gKGBSdW50aW1lRXJyb3JgIGlzIHJhaXNlZCBvbmx5IGZvciByZWFsCiAgZXJyb3JzLCBsaWtlIHRoZSBgUkJQX2AgdmlvbGF0aW9uIG9uIGEgbmV3IHZhcmlhYmxlIOKAlCB0aGUgbWVzc2FnZSBpcyB0YWdnZWQKICBgW3BsdWdpbjp7aWR9XWAgd2l0aCB0aGUgb2ZmZW5kaW5nIHBsdWdpbi4pCi0gUmFyZWx5LCBhIHdyaXRlIGNhbiBiZSBsb3N0IGlmIGl0IHJhY2VzIHRoZSB3b3JrZXIncyB2YXJpYWJsZSBmbHVzaAogIChsb2NrLWZyZWUgcmVhZC1tb2RpZnktd3JpdGUpLiBGb3IgaW1wb3J0YW50IHZhbHVlcywgcmUtY2hlY2sgYW5kIHJldHJ5IG9uCiAgdGhlIG5leHQgY3ljbGUuCgojIyMjIFBlci1wbHVnaW4gdmFsdWUgc3RvcmFnZSAobWV0YSkKCkJlc2lkZXMgdGhlIHNoYXJlZCB2YWx1ZSwgZWFjaCB2YXJpYWJsZSBlbnRyeSByZWNvcmRzIHdoaWNoIHBsdWdpbiBsYXN0IHdyb3RlCndoYXQ6CgpgYGBweXRob24KIyBzdGF0ZV9kaWN0WyJ2YXJpYWJsZXMiXSDigJQgYWZ0ZXIgQSB3cm90ZSAxIGFuZCBCIHdyb3RlIDIKIlJCUF9URVNUIjogewogICAgInZhbHVlIjogMiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2hhcmVkIHNsb3QgPSBsYXN0IHdyaXR0ZW4gdmFsdWUKICAgICJ0eXBlIjogImxvY2FsIiwKICAgICJtZXRhIjogeyJ3cml0ZXJzIjogeyJBLnBsdWdpbiI6IDEsICJCLnBsdWdpbiI6IDJ9fSwgICAjIHBlci1wbHVnaW4gcmVjb3JkCn0KYGBgCgpTbyB0aGUgZXhhY3QgdmFsdWUgaXMgcmVjb3ZlcmFibGUgZXZlbiB3aGVuIG5hbWVzIGNvbGxpZGU6CgotIFBsdWdpbiBTREs6IGBjdHguZ2V0X3ZhcmlhYmxlKCJSQlBfVEVTVCIsIHBsdWdpbl9pZD0iQS5wbHVnaW4iKWAg4oaSIGAxYAotIFByb2dyYW0gc3RlcCBleHByZXNzaW9uOiBgQ09VTlQgPSBnZXRfdmFyKCJBLnBsdWdpbiIsICJSQlBfVEVTVCIpICsgMWAg4oaSIGAyYAotIEEgcGxhaW4gbmFtZSAoYFJCUF9URVNUICs9IDFgKSB1c2VzIHRoZSBzaGFyZWQgc2xvdCAobGFzdCB3cml0dGVuIHZhbHVlKSDihpIgYDNgCgojIyMjIEV4ZWN1dG9yIHN0YXRlCgpTdWJzY3JpYmVzIHRvIHRoZSBgbXVzY2F0L2V4ZWN1dG9yL3N0YXRlYCBwdWJsaXNoICgwLjggcyBpbnRlcnZhbCkgYW5kIGV4cG9zZXMKcGVyLXJvYm90LW1vZGVsIHN0YXRlOgoKYGBgcHl0aG9uCmN0eC5leGVjdXRvcl9zdGF0ZSgiQzUwMDkyMCIpICAgIyAicnVubmluZyIgfCAicGF1c2VkIiB8ICJ3YWl0aW5nIiB8IC4uLiB8IE5vbmUKY3R4LmV4ZWN1dG9yX3N0YXRlKCkgICAgICAgICAgICAjIHsiQzUwMDkyMCI6ICJwYXVzZWQiLCAiYW1yIjogInJ1bm5pbmcifQpjdHguaXNfcGF1c2VkKCJDNTAwOTIwIikgICAgICAgICMgd2hldGhlciB0aGF0IG1vZGVsIGlzIHBhdXNlZApjdHguaXNfc3RvcHBlZCgiQzUwMDkyMCIpICAgICAgICMgc3RvcC9lcnJvciB0cmFuc2l0aW9uIG9mIGEgbW9kZWwgc2VlbiBhY3RpdmUgdGhpcyBydW4KYGBgCgotIFN0YXRlczogYGlkbGUgfCBydW5uaW5nIHwgcGF1c2VkIHwgd2FpdGluZyB8IHN0b3BwZWQgfCBwb3N0X3N0YXJ0IHwgY29tcGxldGVkIHwgZXJyb3JgCi0gQSBtb2RlbCB3aXRoIG5vIHJ1bm5pbmcgdGFzayBpcyBgTm9uZWAgLyBhYnNlbnQgZnJvbSB0aGUgZGljdC4KLSBUaGUgcHVibGlzaCBpbnRlcnZhbCBpcyAwLjggcywgc28gZXhwZWN0IHVwIHRvIH4xIHMgb2YgbGF0ZW5jeS4KLSBXaXRoIGBJU19ERVY9dHJ1ZWAgdGhlcmUgaXMgbm8gcHVibGlzaCBhdCBhbGwg4oCUIGFsd2F5cyBgTm9uZWAuCgpUbyBnZXQgYSBjYWxsYmFjayBhdCB0aGUgbW9tZW50IHRoZSBzdGF0ZSBjaGFuZ2VzLCB3aXRob3V0IHBvbGxpbmc6CgpgYGBweXRob24KQGN0eC5vbl9leGVjdXRvcl9zdGF0ZV9jaGFuZ2UKYXN5bmMgZGVmIG9uX2NoYW5nZShyb2JvdF9tb2RlbDogc3RyLCBzdGF0ZTogc3RyKSAtPiBOb25lOgogICAgaWYgc3RhdGUgPT0gInBhdXNlZCI6CiAgICAgICAgcHJpbnQoZiJ7cm9ib3RfbW9kZWx9IHBhdXNlZCIpCmBgYAoKLSBOb3QgY2FsbGVkIGZvciByZXBlYXRlZCBwdWJsaXNoZXMgb2YgdGhlIHNhbWUgc3RhdGUg4oCUIGZpcmVzIGV4YWN0bHkgb25jZQogIHBlciBwZXItbW9kZWwgc3RhdGUgY2hhbmdlLgotIEFuIGV4Y2VwdGlvbiBpbiB0aGUgaGFuZGxlciBpcyBvbmx5IGxvZ2dlZDsgc3RhdGUgdHJhY2tpbmcga2VlcHMgcnVubmluZy4KCiMjIyMgUmVzcG9uZGluZyB0byBwYXVzZSAvIHN0b3AKCmBgYHB5dGhvbgpAY3R4Lm9uX2V4ZWN1dGUKYXN5bmMgZGVmIGhhbmRsZShhcmdzOiBkaWN0KSAtPiBOb25lOgogICAgZm9yIGkgaW4gcmFuZ2UoMTAwKToKICAgICAgICAjIHN0b3Ag4oaSIENhbmNlbGxlZEVycm9yIChwcm9wYWdhdGVkIHRvIHRoZSBleGVjdXRvciBhcyBhIHN0b3ApLAogICAgICAgICMgcGF1c2Ug4oaSIHdhaXRzIGhlcmUgdW50aWwgcmVzdW1lZC4KICAgICAgICAjIEluc2lkZSBvbl9leGVjdXRlIHRoaXMgYXV0b21hdGljYWxseSB3YXRjaGVzIG9ubHkgdGhlIHJvYm90IG1vZGVsCiAgICAgICAgIyBleGVjdXRpbmcgdGhpcyBTdGVwLgogICAgICAgIGF3YWl0IGN0eC5jaGVja19zdG9wKCkKCiAgICAgICAgLi4uICAjIGFjdHVhbCB3b3JrCiAgICAgICAgYXdhaXQgYXN5bmNpby5zbGVlcCgwLjUpCgogICAgYXdhaXQgY3R4LmRvbmUoKQpgYGAKClNjb3BlIHByaW9yaXR5IGZvciBgY2hlY2tfc3RvcGAgLyBgaXNfcGF1c2VkYCAvIGBpc19zdG9wcGVkYDoKCjEuIGByb2JvdF9tb2RlbGAgZ2l2ZW4g4oCUIHRoYXQgbW9kZWwgb25seQoyLiBPbWl0dGVkIGluc2lkZSBgb25fZXhlY3V0ZWAg4oCUICoqb25seSB0aGUgbW9kZWwgZXhlY3V0aW5nIHRoaXMgU3RlcCoqCiAgIChwYXNzZWQgaW4gYnkgdGhlIGV4ZWN1dG9yKQozLiBPbWl0dGVkIGVsc2V3aGVyZSAocmVzaWRlbnQgdGFzaywg4oCmKSDigJQgYWxsIG1vZGVscwoKQSBoYW5kbGVyIGRvaW5nIGxvbmctcnVubmluZyB3b3JrIG11c3QgY2FsbCBgY2hlY2tfc3RvcCgpYCBldmVyeSBsb29wCml0ZXJhdGlvbiBzbyBpdCByZWFjdHMgdG8gcGF1c2Uvc3RvcCBpbW1lZGlhdGVseS4gV2l0aG91dCBpdCwgdGhlIHBsdWdpbiBrZWVwcwpydW5uaW5nIGV2ZW4gYWZ0ZXIgdGhlIG9wZXJhdG9yIHByZXNzZXMgU3RvcC4KClZhcmlhYmxlcyB5b3VyIHBsdWdpbiB3YW50cyB0aGUgUHJvZ3JhbSBwYWdlIHZhcmlhYmxlIHBpY2tlciB0byBvZmZlciBtdXN0IGJlCnByZS1kZWNsYXJlZCBpbiBgbWFuaWZlc3QuanNvbmAgdW5kZXIgYCJ2YXJpYWJsZXMiYCAoc2VlIHRoZSBtYW5pZmVzdCBzZWN0aW9uCmJlbG93KS4KCiMjIyBDKysKCkMrKyBwbHVnaW5zIHVzZSBgY3BwL2AgYW5kIGFyZSBidWlsdCB3aXRoIENNYWtlIGluc2lkZSBEb2NrZXIgYWdhaW5zdCB0aGUKUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLIChzZWUgX0MrKyBTREtfIGJlbG93KS4KCmBgYGNwcAojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dGhyZWFkPgoKaW50IG1haW4oKSB7CiAgY29uc3QgY2hhciogcGx1Z2luX2lkID0gc3RkOjpnZXRlbnYoIlJCX1BMVUdJTl9JRCIpOwogIHN0ZDo6Y291dCA8PCAiW19fUExVR0lOX05BTUVfX10gYmFja2VuZCByZWFkeSIKICAgICAgICAgICAgPDwgKHBsdWdpbl9pZCA/IHN0ZDo6c3RyaW5nKCIgKGlkPSIpICsgcGx1Z2luX2lkICsgIikiIDogIiIpCiAgICAgICAgICAgIDw8IHN0ZDo6ZW5kbDsKCiAgd2hpbGUgKHRydWUpIHsKICAgIHN0ZDo6dGhpc190aHJlYWQ6OnNsZWVwX2ZvcihzdGQ6OmNocm9ubzo6c2Vjb25kcygxKSk7CiAgfQogIHJldHVybiAwOwp9CmBgYAoKIyMjIyBDKysgU0RLIChgcmFpbmJvdy1yYi1zZGstZGV2YCkKCkJvdGggQysrIHJ1bnRpbWVzIChgY3BwYCwgYHJvczJgICsgYHJjbGNwcGApIGxpbmsgdGhlIFJhaW5ib3cgUm9ib3RpY3MgQysrIFNESwpmcm9tIHRoZSBhcHQgcGFja2FnZSBgcmFpbmJvdy1yYi1zZGstZGV2YC4gVGhlIGBtdXNjYXQtcGtgIGRldiBjb250YWluZXJzIGFscmVhZHkKaGF2ZSBpdCwgc28gYG11c2NhdC1wayBkZXZgIC8gYGJ1aWxkYCBuZWVkIG5vdGhpbmcgZXh0cmEuIFRvIGJ1aWxkIG91dHNpZGUgdGhlCmNvbnRhaW5lciAoeW91ciBvd24gVWJ1bnR1IDI0LjA0IG1hY2hpbmUsIG9yIHRoZSByb2JvdCBQQyk6CgpgYGBiYXNoCmN1cmwgLWZzU0wgaHR0cHM6Ly9yYWluYm93cm9ib3RpY3MuZ2l0aHViLmlvL3JiLXNkay9yYi1zZGstYXB0LXJlcG8uZ3BnLmtleSB8IHN1ZG8gZ3BnIC0tZGVhcm1vciAtbyAvdXNyL3NoYXJlL2tleXJpbmdzL3JiLXNkay1hcHQuZ3BnCmVjaG8gJ2RlYiBbc2lnbmVkLWJ5PS91c3Ivc2hhcmUva2V5cmluZ3MvcmItc2RrLWFwdC5ncGddIGh0dHBzOi8vcmFpbmJvd3JvYm90aWNzLmdpdGh1Yi5pby9yYi1zZGsgc3RhYmxlIG1haW4nIHwgc3VkbyB0ZWUgL2V0Yy9hcHQvc291cmNlcy5saXN0LmQvcmItc2RrLmxpc3QKc3VkbyBhcHQgdXBkYXRlICYmIHN1ZG8gYXB0IGluc3RhbGwgcmFpbmJvdy1yYi1zZGstZGV2CmBgYAoKLSBDTWFrZTogYGZpbmRfcGFja2FnZShyYl9zZGsgUkVRVUlSRUQpYCArIGB0YXJnZXRfbGlua19saWJyYXJpZXMoPHRhcmdldD4gcmJfc2RrOjpyYl9zZGspYCAoQysrMjApLiBwa2ctY29uZmlnOiBgcmJfc2RrYC4KLSBIZWFkZXJzOiBgPHJhaW5ib3cvcmJfc2RrL21hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwPmAgKGBSQk1hbmlwdWxhdGVTREtgKSwKICBgPHJhaW5ib3cvcmJfc2RrL3Byb2dyYW0vcGx1Z2luX3Byb2dyYW1fY29udGV4dC5ocHA+YCAoYHJiX3BsdWdpbjo6UGx1Z2luUHJvZ3JhbUNvbnRleHRgLCBmb3IgYHByb2dyYW0ucGFuZWxgIGNvbW1hbmRzIOKAlCB0aGUgaGVhZGVyJ3MgdG9wIGNvbW1lbnQgaGFzIGEgZnVsbCBgbWFpbigpYCBleGFtcGxlKS4KLSBUaGUgYmluYXJ5IGlzIGxpbmtlZCAqKmR5bmFtaWNhbGx5Kio7IGBtdXNjYXQtcGsgYnVpbGRgIGNvcGllcyB0aGUgbWF0Y2hpbmcgYGxpYnJiX3Nkay5zb2AgaW50byBgZGlzdC88YXJjaD4vbGliL2AgKHRoZSByb2JvdCBoYXMgbm8gU0RLIGluc3RhbGxlZCksIHNvIGVhY2ggcGx1Z2luIGtlZXBzIHRoZSBTREsgdmVyc2lvbiBpdCB3YXMgYnVpbHQgd2l0aC4gVGhlIHZlcnNpb24gaXMgdGhlIG9uZSBwaW5uZWQgaW4gYENNYWtlTGlzdHMudHh0YCAoYGZpbmRfcGFja2FnZShyYl9zZGsgPHZlcnNpb24+IEVYQUNUIFJFUVVJUkVEKWApOyBjaGFuZ2UgaXQgd2l0aCBgbXVzY2F0LXBrIHNkayB1cGRhdGUgPHZlcnNpb24+YC4KLSBVSSDihpQgYmFja2VuZCBtZXNzYWdpbmcgd29ya3MgZnJvbSBDKysgdG9vOiBgcmJfcGx1Z2luOjpSQlBsdWdpbkNhbGxgIGluIGA8cmFpbmJvdy9yYl9zZGsvcGx1Z2luL3JiX3BsdWdpbi5ocHA+YCAoc2VlIHRoZSBzY2FmZm9sZGVkIGBjcHAvbWFpbi5jcHBgKS4KCiMjIyBST1MyIChyY2xweSkKClJPUzIgUHl0aG9uIHBsdWdpbnMgdXNlIGByb3MyX3dzL2Agd2l0aCBgcnVudGltZS5yb3NDbGllbnQ6ICJyY2xweSJgLiByZWxhdGl2ZSB0b3BpYyBuYW1lcyBhcmUgcGxhY2VkIHVuZGVyIHRoZSBwbHVnaW4ncyBST1MgbmFtZXNwYWNlIOKAlCB0aGUgcGx1Z2luIGlkCndpdGggIi4iIOKGkiAiLyIgYW5kICItIiDihpIgIl8iIChgY29tLmV4YW1wbGUubXktcGx1Z2luYCDihpIgYC9jb20vZXhhbXBsZS9teV9wbHVnaW5gKSwgaW4gZGV2CmFuZCBvbiB0aGUgcm9ib3QuIFVzZSBhbiBhYnNvbHV0ZSBuYW1lIChgL2NtZF92ZWxgKSBmb3IgdG9waWNzIHNoYXJlZCB3aXRoIG90aGVyIG5vZGVzLgpgUkJQbHVnaW5DYWxsYCB3b3JrcyBpbiB0aGUgbm9kZSBtb2R1bGUgdG9vIChVSSBtZXNzYWdpbmcgYW5kIGBwbHVnaW4ucm91dGVyYCkuCgpgYGBweXRob24KIyByb3MyX3dzL3NyYy9fX1BMVUdJTl9TTFVHX18vX19QTFVHSU5fU0xVR19fL25vZGUucHkKaW1wb3J0IHJjbHB5CmZyb20gcmNscHkubm9kZSBpbXBvcnQgTm9kZQpmcm9tIHJhaW5ib3cucmJfc2RrIGltcG9ydCBSQk1hbmlwdWxhdGVTREsKCnNkayA9IFJCTWFuaXB1bGF0ZVNESygpCgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUoTm9kZSk6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygiX19QTFVHSU5fU0xVR19fX25vZGUiKQogICAgICAgIHNlbGYuZ2V0X2xvZ2dlcigpLmluZm8oIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKQogICAgICAgICMgdXNlIHNkayBhbG9uZ3NpZGUgUk9TMiBwdWJsaXNoZXJzL3N1YnNjcmliZXJzL3NlcnZpY2VzIGFzIG5lZWRlZApgYGAKCgojIyMjIFRhbGtpbmcgdG8gYW4gZXh0ZXJuYWwgUEMgb3ZlciBST1MgMgoKUk9TIDIgZGlzY292ZXJ5IHN0YXlzIG9uIHRoZSByb2JvdCAoYFJPU19BVVRPTUFUSUNfRElTQ09WRVJZX1JBTkdFPUxPQ0FMSE9TVGA7IGBtdXNjYXQtcGsgZGV2YApydW5zIHRoZSBzYW1lKSwgc28gcm9ib3RzIG9uIG9uZSBMQU4gZG9uJ3QgbWl4IHRvcGljcy4gQWxsb3cgc3BlY2lmaWMgUENzIGZyb20gdGhlIHBsdWdpbiBVSSDigJQKTXVzY2F0IGtlZXBzIHRoZSBsaXN0IHBlciBwbHVnaW4sIHN0YXJ0cyB5b3VyIGJhY2tlbmQgd2l0aCBgUk9TX1NUQVRJQ19QRUVSU2Agc2V0IHRvIGl0LCBhbmQKcmVzdGFydHMgdGhlIHBsdWdpbiB3aGVuIGl0IGNoYW5nZXMuIFlvdXIgUk9TIGNvZGUgbmVlZHMgbm8gY2hhbmdlczsgdGhlIFBDIG5lZWRzIG5vIGV4dHJhIHNldHRpbmdzLgoKYGBgdHN4CmNvbnN0IHJiID0gdXNlUmIoKTsKY29uc3QgcGVlcnMgPSBhd2FpdCByYi5yb3NQZWVycy5nZXQoKTsgICAgICAgICAgICAgICAvLyBbIjE5Mi4xNjguMC41MCJdCmF3YWl0IHJiLnJvc1BlZXJzLnNldChbIjE5Mi4xNjguMC41MCIsICIxOTIuMTY4LjAuNTEiXSk7IC8vIHNhdmVzICsgcmVzdGFydHMgdGhlIHBsdWdpbjsgcmVqZWN0cyBvbiBhIGJhZCBJUApgYGAKCi0gUGVyIHBsdWdpbjogcGx1Z2luIEIga2VlcHMgaXRzIGFsbG93ZWQgUENzIHdoZW4gcGx1Z2luIEEgKGFsbG93aW5nIHRoZSBzYW1lIFBDKSBpcyBzdG9wcGVkIG9yIHJlbW92ZWQuCi0gSXQgb3BlbnMgY29tbXVuaWNhdGlvbjsgaXQgaXMgbm90IGFjY2VzcyBjb250cm9sIOKAlCBhIFBDIHRoYXQga25vd3MgdGhlIHJvYm90J3MgSVAgY2FuIHN0aWxsCiAgYWRkIHRoZSByb2JvdCB0byBpdHMgb3duIGBST1NfU1RBVElDX1BFRVJTYC4KLSBJbiBgbXVzY2F0LXBrIGRldmAgdGhlIGxpc3QgaXMga2VwdCBpbiBgLm11c2NhdC1kZXYvcm9zLXBlZXJzLmpzb25gIChST1MgMiBiYWNrZW5kcykuCgojIyMgUk9TMiAocmNsY3BwKQoKUk9TMiBDKysgcGx1Z2lucyB1c2UgYHJvczJfd3MvYCB3aXRoIGBydW50aW1lLnJvc0NsaWVudDogInJjbGNwcCJgLiBUaGUgbm9kZSBsaW5rcwp0aGUgUmFpbmJvdyBDKysgU0RLIHRoZSBzYW1lIHdheSBhcyB0aGUgYGNwcGAgcnVudGltZSAoc2VlIF9DKysgU0RLXyBhYm92ZSkuCgpgYGBjcHAKI2luY2x1ZGUgInJjbGNwcC9yY2xjcHAuaHBwIgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUgOiBwdWJsaWMgcmNsY3BwOjpOb2RlIHsKcHVibGljOgogIF9fUExVR0lOX0NMQVNTX19Ob2RlKCkgOiBOb2RlKCJfX1BMVUdJTl9TTFVHX19fbm9kZSIpIHsKICAgIFJDTENQUF9JTkZPKHRoaXMtPmdldF9sb2dnZXIoKSwgIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKTsKICB9Cn07CmBgYAoKLS0tCgojIyBWaWRlbyBzdHJlYW1pbmcgKE1lZGlhTVRYKQoKTXVzY2F0IHJ1bnMgYSBNZWRpYU1UWCBtZWRpYSBzZXJ2ZXIuIFRoZSBiYWNrZW5kIHB1Ymxpc2hlcyBhIHN0cmVhbSBvdmVyIFJUU1AgYW5kCnRoZSBVSSBwbGF5cyBpdCBvdmVyIFdlYlJUQy4gYG11c2NhdC1wayBkZXZgIHJ1bnMgdGhlIHNhbWUgc2VydmVyIChvciB1c2VzIGEgbG9jYWwKTXVzY2F0J3MpLCBzbyB0aGUgYWRkcmVzc2VzIGFyZSBpZGVudGljYWwgaW4gZGV2IGFuZCBvbiB0aGUgcm9ib3QuCgp8IHwgQWRkcmVzcyB8CnwgLS0tIHwgLS0tIHwKfCBQdWJsaXNoIChiYWNrZW5kKSB8IGBydHNwOi8vMTI3LjAuMC4xOjg1NTQvPHBsdWdpbl9pZD4vPG5hbWU+YCB8CnwgUGxheSAoVUkpIHwgYGh0dHA6Ly88aG9zdD46ODg4OS88cGx1Z2luX2lkPi88bmFtZT4vYCB8CgotIFByZWZpeCB0aGUgcGF0aCB3aXRoIHlvdXIgcGx1Z2luIGlkIOKAlCBwYXRocyBhcmUgc2hhcmVkIHdpdGggcm9ib3QgY2FtZXJhcyBhbmQgb3RoZXIgcGx1Z2lucy4KLSBUaGUgcm9ib3QgcnVudGltZSBoYXMgbm8gZmZtcGVnLCBHU3RyZWFtZXIgb3IgT3BlbkNWOyBicmluZyB5b3VyIG93biBlbmNvZGVyIChiZWxvdykuCgoqKkJhY2tlbmQgKFB5dGhvbikqKiDigJQgdXNlIFB5QVY6IGFkZCBgYXZgIGFuZCBgbnVtcHlgIHRvIGByZXF1aXJlbWVudHMudHh0YC4gSXRzIHdoZWVscwppbmNsdWRlIEZGbXBlZywgc28gdGhleSBzaGlwIGluIHRoZSBaSVAgbGlrZSBhbnkgb3RoZXIgZGVwZW5kZW5jeS4KCmBgYHB5dGhvbgppbXBvcnQgZnJhY3Rpb25zLCB0aW1lCmltcG9ydCBhdiwgbnVtcHkgYXMgbnAKCm91dCA9IGF2Lm9wZW4oInJ0c3A6Ly8xMjcuMC4wLjE6ODU1NC9fX1BMVUdJTl9JRF9fL2NhbSIsIG1vZGU9InciLCBmb3JtYXQ9InJ0c3AiLAogICAgICAgICAgICAgIG9wdGlvbnM9eyJydHNwX3RyYW5zcG9ydCI6ICJ0Y3AifSkKc3RyZWFtID0gb3V0LmFkZF9zdHJlYW0oImxpYngyNjQiLCByYXRlPTI1LCBvcHRpb25zPXsicHJlc2V0IjogInVsdHJhZmFzdCIsICJ0dW5lIjogInplcm9sYXRlbmN5In0pCnN0cmVhbS53aWR0aCwgc3RyZWFtLmhlaWdodCwgc3RyZWFtLnBpeF9mbXQgPSA2NDAsIDM2MCwgInl1djQyMHAiCgppID0gMAp3aGlsZSBUcnVlOgogICAgaW1nID0gbnAuemVyb3MoKDM2MCwgNjQwLCAzKSwgZHR5cGU9bnAudWludDgpICAgICAgICAgICMgeW91ciBSR0IgZnJhbWUgaGVyZQogICAgZnJhbWUgPSBhdi5WaWRlb0ZyYW1lLmZyb21fbmRhcnJheShpbWcsIGZvcm1hdD0icmdiMjQiKQogICAgZnJhbWUucHRzLCBmcmFtZS50aW1lX2Jhc2UgPSBpLCBmcmFjdGlvbnMuRnJhY3Rpb24oMSwgMjUpCiAgICBmb3IgcGFja2V0IGluIHN0cmVhbS5lbmNvZGUoZnJhbWUpOgogICAgICAgIG91dC5tdXgocGFja2V0KQogICAgaSArPSAxCiAgICB0aW1lLnNsZWVwKDEgLyAyNSkKYGBgCgpSdW4gdGhlIGVuY29kZXIgbG9vcCBpbiBhIHRocmVhZCAob3IgYGFzeW5jaW8udG9fdGhyZWFkYCkgc28gaXQgZG9lc24ndCBibG9jayB0aGUKYFJCUGx1Z2luQ2FsbGAgaGFuZGxlcnMuCgoqKlVJKiog4oCUIGVtYmVkIE1lZGlhTVRYJ3MgV2ViUlRDIHBsYXllci4gYGxvY2F0aW9uLmhvc3RuYW1lYCBpcyBgbG9jYWxob3N0YCBpbiB0aGUKcHJldmlldyBhbmQgdGhlIHJvYm90J3MgYWRkcmVzcyBvbiB0aGUgcm9ib3Q6CgpgYGB0c3gKY29uc3QgU1RSRUFNID0gIl9fUExVR0lOX0lEX18vY2FtIjsgLy8gdGhlIHBhdGggdGhlIGJhY2tlbmQgcHVibGlzaGVzCgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDYW1lcmEoKSB7CiAgcmV0dXJuICgKICAgIDxpZnJhbWUKICAgICAgc3JjPXtgJHtsb2NhdGlvbi5wcm90b2NvbH0vLyR7bG9jYXRpb24uaG9zdG5hbWV9Ojg4ODkvJHtTVFJFQU19L2B9CiAgICAgIGFsbG93PSJhdXRvcGxheSIKICAgICAgY2xhc3NOYW1lPSJhc3BlY3QtdmlkZW8gdy1mdWxsIGJvcmRlci0wIgogICAgLz4KICApOwp9CmBgYAoKLS0tCgojIyBtYW5pZmVzdC5qc29uCgpgYGBqc29uYwp7CiAgLy8gdW5pcXVlIHBsdWdpbiBJRCDigJQgcmV2ZXJzZS1kb21haW4gZm9ybWF0IHJlY29tbWVuZGVkCiAgImlkIjogImNvbS5leGFtcGxlLm15LXBsdWdpbiIsCiAgIm5hbWUiOiAiTXkgUGx1Z2luIiwKICAidmVyc2lvbiI6ICIxLjAuMCIsCgogIC8vIG1pbmltdW0gTXVzY2F0IHZlcnNpb24gcmVxdWlyZWQgdG8gbG9hZCB0aGlzIHBsdWdpbgogICJtaW5NdXNjYXRWZXJzaW9uIjogIjEuMC4wIiwKCiAgLy8gcGx1Z2luIGF1dGhvciAoZW1wdHkgc3RyaW5nIGlzIGZpbmUpCiAgImF1dGhvciI6ICJZb3VyIE5hbWUiLAoKICAvLyBkaXNwbGF5ZWQgaW4gdGhlIE11c2NhdCBwbHVnaW4gc3RvcmUgLyBpbmZvIHBhbmVsCiAgLy8gc3RyaW5nIG9yIHsgZW4gKHJlcXVpcmVkKSwga28sIGphLCB6aCwgdmksIHRoLCBlcyB9CiAgImRlc2NyaXB0aW9uIjogeyAiZW4iOiAiUGx1Z2luIGRlc2NyaXB0aW9uIiwgImtvIjogIu2UjOufrOq3uOyduCDshKTrqoUiIH0sCgogIC8vIFNWRyBzdHJpbmcgKHNpbmdsZSBmaWxlKSBvciBQTkcvSlBHIHNpemUgbWFwIChhbGwgdGhyZWUgc2l6ZXMgcmVxdWlyZWQpCiAgImljb25zIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgLy8gImljb25zIjogeyAiMTYiOiAiYXNzZXRzL2ljb24tMTYucG5nIiwgIjQ4IjogImFzc2V0cy9pY29uLTQ4LnBuZyIsICIxMjgiOiAiYXNzZXRzL2ljb24tMTI4LnBuZyIgfSwKCiAgLy8gdGFyZ2V0TW9kZWxzIGFuZC9vciB0YXJnZXRDYXRlZ29yeXMg4oCUIGF0IGxlYXN0IG9uZSBpcyByZXF1aXJlZAogIC8vICJhbGwiID0gZXZlcnkgdGFyZ2V0LCBvciBsaXN0IHNwZWNpZmljIHZhbHVlcwogICJ0YXJnZXRNb2RlbHMiOiAiYWxsIiwKICAvLyAidGFyZ2V0TW9kZWxzIjogWyJDNTAwOTIwIiwgIkM1MDA5MzAiXSwKICAidGFyZ2V0Q2F0ZWdvcnlzIjogImFsbCIsCiAgLy8gInRhcmdldENhdGVnb3J5cyI6IFsibWFuaXB1bGF0ZSIsICJhbXIiLCAicmJ5MSIsICJ2aXNpb24iXSwKCiAgImNvbnRyaWJ1dGVzIjogWwogICAgLy8gcHJvZ3JhbS5wYW5lbCDigJQgZGVmaW5lcyBhIGN1c3RvbSBjb21tYW5kIGZvciB0aGUgUHJvZ3JhbSBwYWdlIHNlcXVlbmNlCiAgICAvLyAgIGJ1aWxkZXI7IHJ1bnMgdmlhIFBsdWdpblByb2dyYW1Db250ZXh0IHdoZW4gdGhlIHByb2dyYW0gcmVhY2hlcyBpdAogICAgewogICAgICAicG9pbnQiOiAicHJvZ3JhbS5wYW5lbCIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIuuCtCDtlIzrn6zqt7jsnbgiLCAiZW4iOiAiTXkgUGx1Z2luIiB9LAogICAgICAidWkiOiAicHJvZ3JhbSIsICAgICAgICAgICAvLyBtdXN0IGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGNvbnRyaWJ1dGlvbnMKICAgICAgImNvbW1hbmRJbmZvIjogewogICAgICAgICJuYW1lIjogIk15IFBsdWdpbiIsCiAgICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgICAiZnVuY05hbWUiOiAicmJfcHJvZ3JhbV9zZGsucGx1Z2luX2V4ZWN1dGUiLAogICAgICAgICJhcmdzIjoge30KICAgICAgfQogICAgfSwKICAgIC8vIHRvb2xiYXIg4oCUIGFkZHMgYSBidXR0b24gdG8gdGhlIHRvcCB0b29sYmFyIChyZXF1aXJlZCkKICAgIHsKICAgICAgInBvaW50IjogInRvb2xiYXIiLAogICAgICAiaWNvbiI6ICJhc3NldHMvaWNvbi5zdmciLAogICAgICAibGFiZWwiOiB7ICJrbyI6ICLrgrQg7ZSM65+s6re47J24IiwgImVuIjogIk15IFBsdWdpbiIgfSwKICAgICAgInVpIjogImNvbnRlbnQiLCAgICAgICAgICAgLy8gbXVzdCBiZSB1bmlxdWUgYWNyb3NzIGFsbCBjb250cmlidXRpb25zCiAgICAgICJvcGVucyI6ICJwb3BvdmVyIiAgICAgICAgIC8vIHBvcG92ZXIgfCBwYW5lbCB8IHBhZ2UKICAgIH0sCiAgICAvLyBtb3ZlLnBhbmVsIOKAlCBhZGRzIGEgcGFuZWwgdG8gdGhlIE1vdmUgc2NyZWVuCiAgICB7CiAgICAgICJwb2ludCI6ICJtb3ZlLnBhbmVsIiwKICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgImxhYmVsIjogeyAia28iOiAi64K0IO2UjOufrOq3uOyduCIsICJlbiI6ICJNeSBQbHVnaW4iIH0sCiAgICAgICJ1aSI6ICJtb3ZlIiAgICAgICAgICAgICAgIC8vIG11c3QgYmUgdW5pcXVlIGFjcm9zcyBhbGwgY29udHJpYnV0aW9ucwogICAgfQogIF0sCgogIC8vIG9wdGlvbmFsOiB2YXJpYWJsZXMgdGhpcyBwbHVnaW4gZXhwb3NlcyB0byBweWZtIHByb2dyYW1zIOKAlCB0aGUgUHJvZ3JhbQogIC8vIHBhZ2UgdmFyaWFibGUgcGlja2VyIGxpc3RzIE9OTFkgZGVjbGFyZWQgdmFyaWFibGVzLiBuYW1lIG11c3Qgc3RhcnQgd2l0aAogIC8vIFJCUF87IGRlc2NyaXB0aW9uIGlzIG9wdGlvbmFsIGJ1dCB3aXRob3V0IGl0IHRoZSBVSSBjYW4ndCBleHBsYWluIHRoZQogIC8vIHZhcmlhYmxlLCBzbyB3cml0ZSBvbmUuCiAgInZhcmlhYmxlcyI6IFsKICAgIHsgIm5hbWUiOiAiUkJQX2dyaXBfZm9yY2UiLCAidHlwZSI6ICJudW1iZXIiLCAiaW5pdCI6IDAuNSwgImRlc2NyaXB0aW9uIjogeyAia28iOiAi6re466as7Y28IO2emCIsICJlbiI6ICJHcmlwcGVyIGZvcmNlIiB9IH0sCiAgICB7ICJuYW1lIjogIlJCUF90YXJnZXRfcG9zZSIsICJ0eXBlIjogImFycmF5IiwgImluaXQiOiBbMCwgMCwgMF0gfQogIF0sCgogIC8vIHJ1bnRpbWUg4oCUIG9uZSBvZjoKICAvLyAgIHsgInR5cGUiOiAibm9uZSIgfQogIC8vICAgeyAidHlwZSI6ICJweXRob24iLCAiZW50cnkiOiAibWFpbi5weSIgfQogIC8vICAgeyAidHlwZSI6ICJjcHAiLCAiZW50cnkiOiAiPGV4ZWN1dGFibGUgbmFtZT4iIH0KICAvLyAgIHsgInR5cGUiOiAicm9zMiIsICJyb3NDbGllbnQiOiAicmNscHkiIHwgInJjbGNwcCIsICJwYWNrYWdlIjogIi4uLiIsICJsYXVuY2giOiAiLi4uX25vZGUiIH0KICAicnVudGltZSI6IHsgInR5cGUiOiAicHl0aG9uIiwgImVudHJ5IjogIm1haW4ucHkiIH0sCgogIC8vIG9wdGlvbmFsOiBUQ1AgcG9ydHMgb3BlbmVkIGJ5IHRoaXMgcGx1Z2luIGJhY2tlbmQKICAvLyBvbmx5IG51bWJlcltdIGlzIGFsbG93ZWQ7IHJhbmdlcy9vYmplY3RzIGFyZSBub3QgYWNjZXB0ZWQKICAvLyBleHRlcm5hbCBwbHVnaW4gcG9ydHMgbXVzdCBiZSB3aXRoaW4gMjg2MDAtMjg5OTkKICAicG9ydHMiOiBbMjg2MDBdCn0KYGBgCgoqKkJhY2tlbmQgdHlwZXM6KioKCnwgdHlwZSB8IHNvdXJjZSBkaXIgfCBidWlsZCAvIHJ1biB8IGVudHJ5IHwKfC0tLXwtLS18LS0tfC0tLXwKfCBgcHl0aG9uYCB8IGBweS9gIHwgcGlwICsgcnVuIGluIERvY2tlciB8IGBtYWluLnB5YCB8CnwgYGNwcGAgfCBgY3BwL2AgfCBDTWFrZSBpbiBEb2NrZXIgfCBidWlsdCBleGVjdXRhYmxlIG5hbWUgfAp8IGByb3MyYCAocmNscHkpIHwgYHJvczJfd3MvYCB8IGNvbGNvbiAoYW1lbnRfcHl0aG9uKSBpbiBEb2NrZXIgfCDigJQgfAp8IGByb3MyYCAocmNsY3BwKSB8IGByb3MyX3dzL2AgfCBjb2xjb24gKGFtZW50X2NtYWtlKSBpbiBEb2NrZXIgfCDigJQgfAoKPiBFdmVyeSBiYWNrIGVuZCBydW5zIGluIGEgRG9ja2VyIGNvbnRhaW5lciBtYXRjaGluZyB0aGUgcm9ib3QgKFVidW50dSAyNC4wNCArIFB5dGhvbiAzLjEyKSwgc28gZGV2IGJlaGF2ZXMgbGlrZSBwcm9kdWN0aW9uIGFuZCBjb21waWxlZCBiaW5hcmllcyBhcmUgQUJJLWNvbXBhdGlibGUuICoqRG9ja2VyIGlzIHJlcXVpcmVkKiogZm9yIGFsbCBiYWNrZW5kIHR5cGVzIChvbmx5IGEgZnJvbnRlbmQtb25seSBgbm9uZWAgcGx1Z2luIHNraXBzIGl0KS4gTm8gbG9jYWwgUHl0aG9uL3Rvb2xjaGFpbiBzZXR1cCBpcyBuZWVkZWQuCgoqKkNvbnRyaWJ1dGlvbiBwb2ludHM6KioKCnwgcG9pbnQgfCBXaGVyZSBpdCBhcHBlYXJzIHwgQmFja2VuZCB8IGBjb21tYW5kSW5mb2AgfAp8LS0tfC0tLXwtLS18Oi0tLTp8CnwgYHRvb2xiYXJgIHwgVG9wIHRvb2xiYXIgYnV0dG9uIChtdXN0IGhhdmUgYXQgbGVhc3Qgb25lKSB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgbG5iYCB8IExlZnQgbmF2aWdhdGlvbiBlbnRyeSB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgbW92ZS5wYW5lbGAgfCBNb3ZlIHNjcmVlbiBwYW5lbCB8IFNESyAvIGByYi5hY3Rpb25gIHwg4oCUIHwKfCBgcHJvZ3JhbS5wYW5lbGAgfCBDdXN0b20gY29tbWFuZCBpbiB0aGUgUHJvZ3JhbSBwYWdlIHNlcXVlbmNlIGJ1aWxkZXIgfCBgUGx1Z2luUHJvZ3JhbUNvbnRleHRgIHwg4pyTIHwKCioqYGNvbW1hbmRJbmZvYCBmaWVsZHMqKiAoZm9yIGBwcm9ncmFtLnBhbmVsYCk6Cgp8IGZpZWxkIHwgdHlwZSB8IGRlc2NyaXB0aW9uIHwKfC0tLXwtLS18LS0tfAp8IGBuYW1lYCB8IGBzdHJpbmdgIHwgRGlzcGxheSBuYW1lIG9mIHRoZSBjb21tYW5kIGluIHRoZSBwcm9ncmFtIHRyZWUgfAp8IGBpY29uYCB8IGBzdHJpbmdgIHwgSWNvbiBwYXRoIHwKfCBgaWNvbkNsYXNzTmFtZWAgfCBgc3RyaW5nP2AgfCBPcHRpb25hbCBDU1MgY2xhc3MgZm9yIHRoZSBpY29uIHwKfCBgZnVuY05hbWVgIHwgYHN0cmluZz9gIHwgQmFja2VuZCBmdW5jdGlvbiBuYW1lIHRvIGNhbGwgfAp8IGBhcmdzYCB8IGBSZWNvcmQ8c3RyaW5nLCBhbnk+P2AgfCBEZWZhdWx0IGFyZ3VtZW50cyB8CnwgYGRpc2FibGVkYCB8IGBib29sZWFuP2AgfCBXaGV0aGVyIHRoZSBub2RlIGlzIGRpc2FibGVkIHwKfCBgYWxsb3dDaGlsZHJlbmAgfCBgc3RyaW5nW10/YCB8IEFsbG93ZWQgY2hpbGQgY29tbWFuZHMgfAp8IGBhbGxvd1BhcmVudHNgIHwgYHN0cmluZ1tdP2AgfCBBbGxvd2VkIHBhcmVudCBjb21tYW5kcyB8CnwgYG5vdEFsbG93Q2hpbGRyZW5gIHwgYHN0cmluZ1tdP2AgfCBEaXNhbGxvd2VkIGNoaWxkIGNvbW1hbmRzIHwKfCBgc3luY0dyb3VwSWRgIHwgYGJvb2xlYW4/YCB8IFN5bmMgZ3JvdXAgSUQgYWNyb3NzIGNoaWxkcmVuIHwKfCBgZGlzYWJsZUNvcHlgIHwgYGJvb2xlYW4/YCB8IFByZXZlbnQgY29weSB8CnwgYGRpc2FibGVEZWxldGVgIHwgYGJvb2xlYW4/YCB8IFByZXZlbnQgZGVsZXRlIHwKfCBgcmVxdWlyZUNoaWxkcmVuYCB8IGBib29sZWFuP2AgfCBXaGV0aGVyIGEgY2hpbGQgY29tbWFuZCBpcyByZXF1aXJlZCB8CnwgYHJlcXVpcmVQYXJlbnRgIHwgYGJvb2xlYW4/YCB8IFdoZXRoZXIgYSBwYXJlbnQgY29tbWFuZCBpcyByZXF1aXJlZCB8CnwgYGNoaWxkcmVuQ29tbWFuZGAgfCBgc3RyaW5nP2AgfCBEZWZhdWx0IGNvbW1hbmQgdHlwZSBmb3IgY2hpbGRyZW4gfAoKKipWYWxpZGF0aW9uIHJ1bGVzOioqCi0gYGlkYCwgYG5hbWVgLCBgdmVyc2lvbmAsIGBtaW5NdXNjYXRWZXJzaW9uYCDigJQgcmVxdWlyZWQgbm9uLWVtcHR5IHN0cmluZ3MKLSBgYXV0aG9yYCDigJQgcmVxdWlyZWQgbm9uLWVtcHR5IHN0cmluZwotIGBkZXNjcmlwdGlvbmAg4oCUIHJlcXVpcmVkIChgc3RyaW5nYCBvciBgeyBlbiAocmVxdWlyZWQpLCBrbz8sIGphPywgemg/LCB2aT8sIHRoPywgZXM/IH1gKQotIGBpY29uc2Ag4oCUIFNWRzogc2luZ2xlIHN0cmluZyBwYXRoIGVuZGluZyBpbiBgLnN2Z2A7IFBORy9KUEc6IG9iamVjdCB3aXRoIGAiMTYiYCwgYCI0OCJgLCBgIjEyOCJgIGFsbCBwcmVzZW50Ci0gYHRhcmdldE1vZGVsc2Ag4oCUIGAiYWxsImAgb3IgYSBub24tZW1wdHkgYXJyYXkgb2Ygcm9ib3QgbW9kZWwgSUQgc3RyaW5ncyAoYXQgbGVhc3Qgb25lIG9mIGB0YXJnZXRNb2RlbHNgIC8gYHRhcmdldENhdGVnb3J5c2AgcmVxdWlyZWQpCi0gYHRhcmdldENhdGVnb3J5c2Ag4oCUIGAiYWxsImAgb3IgYSBub24tZW1wdHkgYXJyYXkgb2YgYCJtYW5pcHVsYXRlIiB8ICJhbXIiIHwgInJieTEiIHwgInZpc2lvbiJgIChhdCBsZWFzdCBvbmUgb2YgYHRhcmdldE1vZGVsc2AgLyBgdGFyZ2V0Q2F0ZWdvcnlzYCByZXF1aXJlZCkKLSBgY29udHJpYnV0ZXNgIOKAlCB0aGUgcGx1Z2luJ3Mgc2NyZWVuczsgd2hlbiBwcmVzZW50IGl0IG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgYHRvb2xiYXJgIGVudHJ5LiBMZWF2ZSBpdCBvdXQgKG9yIGBbXWApIGZvciBhIGJhY2tlbmQtb25seSBwbHVnaW46IG5vIFVJIGlzIGJ1aWx0LCBhbmQgTm9kZS5qcyBpcyBub3QgbmVlZGVkIHRvIGJ1aWxkIGl0Ci0gYHVpYCDigJQgZWFjaCBjb250cmlidXRpb24gbXVzdCBoYXZlIGEgdW5pcXVlIHZhbHVlCi0gYGNvbW1hbmRJbmZvYCDigJQgcmVxdWlyZWQgd2hlbiBgcG9pbnRgIGlzIGAicHJvZ3JhbS5wYW5lbCJgCi0gYHBvcnRzYCDigJQgb3B0aW9uYWwgYG51bWJlcltdYDsgZXZlcnkgcG9ydCBtdXN0IGJlIHdpdGhpbiBgMjg2MDAtMjg5OTlgCiAgYW5kIG11c3Qgbm90IGJlIGEgcmVzZXJ2ZWQgcm9ib3QvaW5kdXN0cmlhbC9pbnRlcm5hbCBwb3J0Ci0gYHZhcmlhYmxlc2Ag4oCUIG9wdGlvbmFsIGFycmF5IG9mIGB7IG5hbWUsIHR5cGUsIGluaXQsIGRlc2NyaXB0aW9uPyB9YDoKICAtIGBuYW1lYCDigJQgbXVzdCBzdGFydCB3aXRoIGBSQlBfYCwgdGhlbiBsZXR0ZXJzL2RpZ2l0cy91bmRlcnNjb3JlOyB1bmlxdWUgcGVyIHBsdWdpbgogIC0gYHR5cGVgIOKAlCBgIm51bWJlciIgfCAic3RyaW5nIiB8ICJhcnJheSJgCiAgLSBgaW5pdGAg4oCUIHJlcXVpcmVkIGluaXRpYWwgdmFsdWUsIG11c3QgbWF0Y2ggYHR5cGVgCiAgLSBgZGVzY3JpcHRpb25gIOKAlCBvcHRpb25hbCBgc3RyaW5nYCBvciBpMThuIG9iamVjdCAoYGVuYCByZXF1aXJlZCBpbiBvYmplY3QgZm9ybSkKCmBtdXNjYXQtcGsgYnVpbGRgIHRocm93cyBvbiBhbnkgdmFsaWRhdGlvbiBlcnJvci4gYG11c2NhdC1wayBkZXZgIHByaW50cwp3YXJuaW5ncyDigJQgZXhjZXB0IGB2YXJpYWJsZXNgIGVycm9ycyAoZS5nLiBhIG5hbWUgd2l0aG91dCB0aGUgYFJCUF9gIHByZWZpeCksCndoaWNoIGFyZSBoYXJkIGVycm9ycyBpbiBgZGV2YCAvIGBkZXY6YmFja2AgdG9vLgoKKipCYWNrZW5kIHBvcnQgcnVsZXM6KioKLSBEZWNsYXJlIGEgcG9ydCBvbmx5IGlmIHlvdXIgYmFja2VuZCBvcGVucyBhIFRDUCBzZXJ2ZXIvbGlzdGVuZXIuCi0gKipFdmVyeSBsaXN0ZW5pbmcgVENQIHBvcnQgbXVzdCBiZSBkZWNsYXJlZC4qKiBgbXVzY2F0LXBrIGRldmAgYW5kCiAgYG11c2NhdC1wayBkZXY6YmFja2Agd2F0Y2ggdGhlIGJhY2tlbmQgYW5kIHN0b3AgaXQgdGhlIG1vbWVudCBpdCBvcGVucyBhIHBvcnQKICB0aGF0IGlzIG5vdCBpbiBgcG9ydHNgLiBBIHBvcnQgb3V0c2lkZSBgMjg2MDAtMjg5OTlgIGNhbid0IGJlIGRlY2xhcmVkLCBzbyBpdAogIG11c3Qgbm90IGJlIG9wZW5lZCBlaXRoZXIg4oCUIHBpY2tpbmcgZS5nLiBgNTUwMGAgaXMgbm90IGEgd2F5IGFyb3VuZCB0aGUgcnVsZS4KICBJdCB3b3VsZCBlc2NhcGUgdGhpcyBjaGVjayAqYW5kKiB0aGUgcm9ib3QncyBpbnN0YWxsLXRpbWUgY29uZmxpY3QgY2hlY2ssIGFuZAogIG9ubHkgY29sbGlkZSBvbmNlIGl0J3MgcnVubmluZyBvbiBhIHJvYm90LgotIFJlc2VydmVkIHBvcnRzIGluY2x1ZGUgYDUwMmAsIGAyMjIyYCwgYDQ4NDBgLCBgNTE3MC01MTc5YCwgYDgwMDAtODk5OWAsCiAgYDEwMDAwYCwgYDMwMDA0YCwgYDM0OTY0YCwgYDQ0ODE4YCwgYDUwMDAwLTUwMDA1YCwgYW5kIGA1MDA1MWAuCi0gVGhlIHJvYm90IHJlamVjdHMgaW5zdGFsbGF0aW9uIChIVFRQIDQwOSkgaWYgYSBkZWNsYXJlZCBwb3J0IGlzIHJlc2VydmVkLAogIG91dCBvZiByYW5nZSwgb3IgYWxyZWFkeSBjbGFpbWVkIGJ5IGFub3RoZXIgZW5hYmxlZCBwbHVnaW4uCgoqKlJlYWNoaW5nIHlvdXIgYmFja2VuZCdzIHBvcnRzIGR1cmluZyBkZXZlbG9wbWVudDoqKgotIERlY2xhcmVkIHBvcnRzIGFyZSBwdWJsaXNoZWQgdG8gYDEyNy4wLjAuMWAgb24geW91ciBtYWNoaW5lLCBzbwogIGBjdXJsIGh0dHA6Ly8xMjcuMC4wLjE6Mjg2MDBgIHdvcmtzIGZyb20gdGhlIGhvc3Qgb24gbWFjT1MsIFdpbmRvd3MsIGFuZCBMaW51eC4KLSBPbiBuYXRpdmUgTGludXggdGhlIGRldiBjb250YWluZXIgdXNlcyBob3N0IG5ldHdvcmtpbmcsIHNvIHRoZSBwb3J0cyBhcmUgb24KICB0aGUgaG9zdCBhbHJlYWR5LgotIElmIGEgZGVjbGFyZWQgcG9ydCBpcyBhbHJlYWR5IHRha2VuIG9uIHlvdXIgbWFjaGluZSwgYG11c2NhdC1wayBkZXZgIHdhcm5zIGFuZAogIHNraXBzIHB1Ymxpc2hpbmcgdGhhdCBvbmUg4oCUIHRoZSBiYWNrZW5kIHN0aWxsIGxpc3RlbnMgaW5zaWRlIHRoZSBjb250YWluZXIuCgotLS0KCiMjIExvY2FsaXplZCBkb2N1bWVudGF0aW9uCgpZb3UgY2FuIHNoaXAgcGVyLWxhbmd1YWdlIFJFQURNRSBmaWxlcyBhbG9uZ3NpZGUgdGhlIG1haW4gYFJFQURNRS5tZGAuIFBsYWNlIHRoZW0gaW4gdGhlIHByb2plY3Qgcm9vdDoKCmBgYApSRUFETUUubWQgICAgICAgICMgZGVmYXVsdCAvIEVuZ2xpc2ggZmFsbGJhY2sKUkVBRE1FLmtvLm1kICAgICAjIEtvcmVhbgpSRUFETUUuZW4ubWQgICAgICMgZXhwbGljaXQgRW5nbGlzaCAob3B0aW9uYWwpClJFQURNRS5qYS5tZCAgICAgIyBKYXBhbmVzZQpgYGAKCkFsbCBgUkVBRE1FKi5tZGAgZmlsZXMgZm91bmQgYXQgdGhlIHByb2plY3Qgcm9vdCBhcmUgYXV0b21hdGljYWxseSBjb3BpZWQgdG8gYGRpc3QvYCBvbgpgbXVzY2F0LXBrIGJ1aWxkYC4gTXVzY2F0IGRpc3BsYXlzIHRoZSBmaWxlIG1hdGNoaW5nIHRoZSB1c2VyJ3MgbG9jYWxlLApmYWxsaW5nIGJhY2sgdG8gYFJFQURNRS5tZGAgaWYgbm9uZSBtYXRjaGVzLgoKLS0tCgojIyBJbnN0YWxsaW5nIFB5dGhvbiBkZXBlbmRlbmNpZXMKCkFkZCBhbnkgcGFja2FnZSB3aXRoIGFuIG9wdGlvbmFsIHZlcnNpb24gcGluIHRvIGByZXF1aXJlbWVudHMudHh0YDoKCmBgYApyYWluYm93LXJiLXNkawpyYWluYm93LXJiLWZsYXQtYnVmZmVycwpudW1weT09MS4yNi40Cm9wZW5jdi1weXRob24KYGBgCgpSdW4gYG11c2NhdC1wayBkZXZgIG9yIGBtdXNjYXQtcGsgZGV2OmJhY2tgIOKAlCBkZXBlbmRlbmNpZXMgYXJlIGluc3RhbGxlZCBhdXRvbWF0aWNhbGx5Cmluc2lkZSB0aGUgZGV2IGNvbnRhaW5lciAoYHBpcCBpbnN0YWxsIC1yIHJlcXVpcmVtZW50cy50eHRgKSBvbiBldmVyeSBzdGFydHVwLiBObwpsb2NhbCBQeXRob24gaXMgcmVxdWlyZWQgZm9yIHRoaXMuCgpgbXVzY2F0LXBrIGRldjpiYWNrYCBhbHNvIGJlc3QtZWZmb3J0IGNyZWF0ZXMvcmVmcmVzaGVzIGEgbG9jYWwgYC52ZW52YCBpbiB0aGUKYmFja2dyb3VuZCAodmlhIGB1dmAgaWYgYXZhaWxhYmxlLCBlbHNlIHlvdXIgc3lzdGVtIFB5dGhvbikgd2l0aCB0aGUgc2FtZSBkZXBzIOKAlApwdXJlbHkgc28geW91ciBlZGl0b3IgKHB5bGludCwgcHlyaWdodCwgbXlweSwgLi4uKSBjYW4gcmVzb2x2ZSBpbXBvcnRzIGFuZCBsaW50CmNvcnJlY3RseS4gSXQncyBub3QgdXNlZCB0byBydW4gdGhlIGJhY2tlbmQ7IERvY2tlciBpcyB0aGUgYWN0dWFsIGV4ZWN1dGlvbgplbnZpcm9ubWVudCwgc28gdGhpcyBzdGVwIGlzIHNpbGVudGx5IHNraXBwZWQgaWYgbm8gbG9jYWwgUHl0aG9uIHRvb2xjaGFpbiBpcwphdmFpbGFibGUuIFBvaW50IHlvdXIgZWRpdG9yJ3MgUHl0aG9uIGludGVycHJldGVyIGF0IGAudmVudmAuCgpgbXVzY2F0LXBrIHNkayB1cGRhdGVgIGFsc28gcmVmcmVzaGVzIGAudmVudmAgaW4gcGxhY2UgaWYgb25lIGFscmVhZHkgZXhpc3RzLCBzbwp5b3VyIGVkaXRvciBwaWNrcyB1cCB0aGUgbmV3IGByYWluYm93LXJiLXNka2AgdmVyc2lvbiBpbW1lZGlhdGVseS4KCj4gYG11c2NhdC1wayBidWlsZGAgb25seSAqKnBpbnMqKiB2ZXJzaW9ucyBpbiBgcmVxdWlyZW1lbnRzLnR4dGAg4oCUIGl0IGRvZXMgbm90IHJ1biBgcGlwIGluc3RhbGxgICh0aGUgcm9ib3QgaW5zdGFsbHMgdGhlbSBhdCBsb2FkIHRpbWUpLgoKLS0tCgojIyBTd2l0Y2hpbmcgYmFja2VuZCB0eXBlCgpgYGBiYXNoCm11c2NhdC1wayB0eXBlIGNoYW5nZSAgICAgICAgICAgICAgICAgIyBpbnRlcmFjdGl2ZQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byBjcHAgICAgICAgICMg4oaSIEMrKwptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byByb3MyICAgICAgICMg4oaSIFJPUzIgKHJjbHB5IC8gUHl0aG9uKQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byByb3MyLWNwcCAgICMg4oaSIFJPUzIgKHJjbGNwcCAvIEMrKykKbXVzY2F0LXBrIHR5cGUgY2hhbmdlIC0tdG8gcHl0aG9uICAgICAjIOKGkiBQeXRob24KYGBgCgo+IEV4aXN0aW5nIGJhY2tlbmQgZGlycyAoYHJvczJfd3MvYCwgYGNwcC9gKSBhcmUgbm90IGRlbGV0ZWQgd2hlbiBzd2l0Y2hpbmcgYXdheS4gUmVtb3ZlIHRoZW0gbWFudWFsbHkgaWYgbm8gbG9uZ2VyIG5lZWRlZC4KCj4gU3dpdGNoaW5nIGJldHdlZW4gYSBQeXRob24gYW5kIGEgQysrIGJhY2tlbmQgYXNrcyB3aGV0aGVyIHRvIHJlcGxhY2UgdGhpcyBSRUFETUUgd2l0aCB0aGUgbWF0Y2hpbmcgb25lICh0aGUgb2xkIGZpbGUgaXMga2VwdCBhcyBgUkVBRE1FLm1kLmJha2ApLiBBZGQgYC0tcmVhZG1lYCB0byBhbnN3ZXIgeWVzIHdpdGhvdXQgdGhlIHByb21wdC4KCi0tLQoKIyMgQUkgY29kaW5nIGFzc2lzdGFudHMgKE1DUCkKCklmIHlvdSBidWlsZCB5b3VyIHBsdWdpbiB3aXRoIGFuIEFJIGFzc2lzdGFudCAoQ2xhdWRlIENvZGUsIENvZGV4LCDigKYpLCBnaXZlIGl0Cmdyb3VuZGVkIGtub3dsZWRnZSBvZiB0aGUgTXVzY2F0IFVJIGNvbXBvbmVudHMsIGRlc2lnbiB0b2tlbnMsIGFuZCBTREsgaW5zdGVhZCBvZgpsZXR0aW5nIGl0IGd1ZXNzLiBgbXVzY2F0LXBrIG1jcGAgaXMgYW4gTUNQIHNlcnZlciBleHBvc2luZzoKCi0gYGxpc3RfY29tcG9uZW50c2AgLyBgZ2V0X2NvbXBvbmVudF9wcm9wc2AgLyBgZ2V0X2NvbXBvbmVudF9leGFtcGxlYCDigJQgZXZlcnkKICBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3JlYWN0YCBjb21wb25lbnQgd2l0aCBpdHMgcmVhbCBwcm9wcyBhbmQgYSB3b3JraW5nCiAgU3Rvcnlib29rIGV4YW1wbGUuCi0gYGxpc3RfZGVzaWduX3Rva2Vuc2AgLyBgc2VhcmNoX2Rlc2lnbl90b2tlbnNgIOKAlCB0aGUgVGFpbHdpbmQgY2xhc3NlcyB0byB1c2UKICAoYGJnLWJnLSpgLCBgdGV4dC1mZy0qYCwgYHR5cG8tKmAsIOKApikgc28geW91ciBVSSBtYXRjaGVzIHRoZSBob3N0IHRoZW1lLgotIGBzZWFyY2hfcmJfc2RrYCDigJQgaG93IHRvIHVzZSBgdXNlUmIoKWAsIGByYi4qYCwgYHVzZVJiRm9ybURhdGFgL2B1c2VSYlNhdmVgLCBhbmQKICB0aGUgYmFja2VuZCBydW50aW1lcy4KLSBgbGlzdF9yYl9zZGtgIC8gYGdldF9yYl9zZGtfYXBpYCDigJQgdGhlIGluc3RhbGxlZCBgcmFpbmJvdy1yYi1zZGtgIChQeXRob24KICBiYWNrZW5kKSBjbGFzc2VzIGFuZCBzaWduYXR1cmVzOyB3aXRoIGBsYW5nOiAiY3BwImAsIHRoZSBDKysgU0RLIGhlYWRlcnMKICAoYHJhaW5ib3ctcmItc2RrLWRldmAsIHJlYWQgb3V0IG9mIHRoZSBgbXVzY2F0LXBrYCBjcHAgZGV2IGltYWdlIOKAlCBidWlsZCBpdAogIG9uY2Ugd2l0aCBgbXVzY2F0LXBrIGRldjpiYWNrYCkuCgoqKkJyb3dzZSB0aGUgY29tcG9uZW50cyBsaXZlKiogd2l0aCBgbXVzY2F0LXBrIHN0b3J5Ym9va2AuCgojIyMgUmVnaXN0ZXIgdGhlIHNlcnZlcgoKKipDbGF1ZGUgQ29kZSoqIOKAlCBhIGAubWNwLmpzb25gIGlzIGFscmVhZHkgc2NhZmZvbGRlZCBhdCB5b3VyIHBsdWdpbiByb290LCBzbwppdCB3b3JrcyBvdXQgb2YgdGhlIGJveDoKCmBgYGpzb24KewogICJtY3BTZXJ2ZXJzIjogewogICAgIm11c2NhdCI6IHsKICAgICAgImNvbW1hbmQiOiAibXVzY2F0LXBrIiwKICAgICAgImFyZ3MiOiBbIm1jcCJdCiAgICB9CiAgfQp9CmBgYAoKKipDb2RleCoqIOKAlCByZWdpc3RlciBvbmNlIHdpdGg6CgpgYGBiYXNoCm11c2NhdC1wayBtY3AgLS1pbnN0YWxsIGNvZGV4CmBgYAoKVGhpcyBhcHBlbmRzIHRoZSBzZXJ2ZXIgdG8gYH4vLmNvZGV4L2NvbmZpZy50b21sYCAoaWRlbXBvdGVudCDigJQgc2FmZSB0byBydW4KYWdhaW4pLiBFcXVpdmFsZW50IG1hbnVhbCBjb25maWc6CgpgYGB0b21sClttY3Bfc2VydmVycy5tdXNjYXRdCmNvbW1hbmQgPSAibXVzY2F0LXBrIgphcmdzID0gWyJtY3AiXQpgYGAKCkFueSBvdGhlciBNQ1AgY2xpZW50IHdvcmtzIHRvbyDigJQgaXQncyBhIHN0YW5kYXJkIHN0ZGlvIE1DUCBzZXJ2ZXIgc3RhcnRlZCB3aXRoCmBtdXNjYXQtcGsgbWNwYC4gSWYgYG11c2NhdC1wa2AgaXNuJ3Qgb24gdGhlIGNsaWVudCdzIFBBVEgsIHVzZSBpdHMgYWJzb2x1dGUgcGF0aAooYHdoaWNoIG11c2NhdC1wa2ApIGFzIGBjb21tYW5kYC4KCi0tLQoKIyMgU2hpcHBpbmcKCmBgYGJhc2gKbXVzY2F0LXBrIGJ1aWxkICAgICAgICAgICAgIyBidWlsZCArIFpJUAptdXNjYXQtcGsgYnVpbGQgLS1uby16aXAgICAjIGJ1aWxkIG9ubHksIG5vIFpJUApgYGAKCj4gQnVpbGRpbmcgdGhlIG90aGVyIGFyY2ggKGUuZy4gYXJtNjQgb24gYW4gYW1kNjQgUEMpIHJ1bnMgaW4gYW4gZW11bGF0ZWQgY29udGFpbmVyIGZvcgo+IEMrKyBiYWNrZW5kcy4gRG9ja2VyIERlc2t0b3AgaGFzIGl0IGJ1aWx0IGluOyBvbiBMaW51eCBlbmFibGUgaXQgb25jZSB3aXRoCj4gYGRvY2tlciBydW4gLS1wcml2aWxlZ2VkIC0tcm0gdG9uaXN0aWlnaS9iaW5mbXQgLS1pbnN0YWxsIGFsbGAsIG9yIHBhc3MgYC0tYXJjaGAgZm9yIG9uZSBhcmNoLgoKLSBCdWlsZHMgYHVpL2NvbnRlbnQudHN4YCDihpIgYGRpc3QvY29udGVudC5qc2AgKG1pbmlmaWVkKQotIFBpbnMgYHJlcXVpcmVtZW50cy50eHRgIHRvIGxhdGVzdCB2ZXJzaW9ucyAoc3RhYmxlLW9ubHkgb24gYG1haW5gIGJyYW5jaCkKLSBDb3BpZXMgYGFzc2V0cy9gLCBgbWFuaWZlc3QuanNvbmAsIGBSRUFETUUqLm1kYCwgYHB5L2AsIGFuZCBgcmVxdWlyZW1lbnRzLnR4dGAgaW50byBgZGlzdC9gCi0gUk9TMjogcnVucyBgY29sY29uIGJ1aWxkYCBpbnNpZGUgdGhlIEphenp5IGNvbnRhaW5lcjsgaW5jbHVkZXMgYHJvczJfd3MvaW5zdGFsbC9gCi0gT3V0cHV0OiBgX19QTFVHSU5fRElSX18te3ZlcnNpb259LnppcGAKClpJUCBsYXlvdXQ6CgpgYGAKX19QTFVHSU5fRElSX18tMS4wLjAuemlwCuKUnOKUgCBkaXN0LwrilIIgICDilJzilIAgY29udGVudC5qcyAgICAgICAgIyBidWlsdCBVSQrilIIgICDilJzilIAgbWFuaWZlc3QuanNvbgrilIIgICDilJzilIAgYXNzZXRzLwrilIIgICDilJzilIAgUkVBRE1FLm1kCuKUgiAgIOKUnOKUgCBSRUFETUUua28ubWQgICAgICAjIGlmIHByZXNlbnQK4pSCICAg4pSc4pSAIG1haW4ucHkgICAgICAgICAgICMgZnJvbSBweS8K4pSCICAg4pSU4pSAIHJlcXVpcmVtZW50cy50eHQgICMgcGlubmVkCuKUlOKUgCByb3MyX3dzL2luc3RhbGwvICAgICAgIyBST1MyIG9ubHkKYGBgCgotLS0KCiMjIEFsbCBjb21tYW5kcwoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJICsgYmFja2VuZAptdXNjYXQtcGsgZGV2OnVpICAgICAjIFVJIHByZXZpZXcgb25seSAocHJldmlldy1ob3N0KQptdXNjYXQtcGsgZGV2OmJhY2sgICAjIGJhY2tlbmQgb25seSAoUHl0aG9uOiB3YXRjaGZpbGVzIC8gUk9TMjogRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkIOKGkiBkaXN0LyArIGRpc3RyaWJ1dGFibGUgWklQICgtLW5vLXppcCB0byBza2lwKQptdXNjYXQtcGsgc3Rvcnlib29rICAjIGJyb3dzZSB0aGUgcmItY29tcG9uZW50cyBVSSBsaWJyYXJ5IGluIGEgYnJvd3NlcgptdXNjYXQtcGsgbWNwICAgICAgICAjIE1DUCBzZXJ2ZXIgZm9yIEFJIGFzc2lzdGFudHMgKGNvbXBvbmVudHMvdG9rZW5zL1NESyBkb2NzKQpgYGAKCmBgYGJhc2gKbXVzY2F0LXBrIHR5cGUgY2hhbmdlICAgICMgc3dpdGNoIGJhY2tlbmQgdHlwZQptdXNjYXQtcGsgc2RrIGxpc3QgICAgICAgIyBzaG93IGN1cnJlbnQgUHl0aG9uIFNESyB2ZXJzaW9uCm11c2NhdC1wayBzZGsgdXBkYXRlICAgICAjIHVwZGF0ZSBQeXRob24gU0RLIHRvIGxhdGVzdAptdXNjYXQtcGsgdXBkYXRlICAgICAgICAgIyB1cGRhdGUgbXVzY2F0LXBsdWdpbi1raXQgaXRzZWxmCm11c2NhdC1wayB1bmluc3RhbGwgICAgICAjIHJlbW92ZSBtdXNjYXQtcGsgaXRzZWxmCmBgYAo=","common/assets/icon.svg":"PHN2ZyB3aWR0aD0iMjU2IiBoZWlnaHQ9IjI1NiIgdmlld0JveD0iMCAwIDI1NiAyNTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGRlZnM+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImJnIiB4MT0iMzYiIHkxPSIyOCIgeDI9IjIyMCIgeTI9IjIyOCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgogICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjOEI1Q0Y2Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzVCMjFCNiIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iZ3JhcGUiIHgxPSI5MiIgeTE9Ijc0IiB4Mj0iMTY4IiB5Mj0iMTc4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgICAgIDxzdG9wIHN0b3AtY29sb3I9IiNEOEI0RkUiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjQTg1NUY3Ii8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogIDwvZGVmcz4KCiAgPHJlY3QgeD0iMTYiIHk9IjE2IiB3aWR0aD0iMjI0IiBoZWlnaHQ9IjIyNCIgcng9IjUyIiBmaWxsPSJ1cmwoI2JnKSIvPgoKICA8IS0tIHBsdWdpbiBicmFja2V0cyAtLT4KICA8cGF0aCBkPSJNNzIgODRINTZDNDcuMTYzNCA4NCA0MCA5MS4xNjM0IDQwIDEwMFYxMTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik0xODQgODRIMjAwQzIwOC44MzcgODQgMjE2IDkxLjE2MzQgMjE2IDEwMFYxMTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgogIDxwYXRoIGQ9Ik03MiAxNzJINTZDNDcuMTYzNCAxNzIgNDAgMTY0LjgzNyA0MCAxNTZWMTQwIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjEyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNMTg0IDE3MkgyMDBDMjA4LjgzNyAxNzIgMjE2IDE2NC44MzcgMjE2IDE1NlYxNDAiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgoKICA8IS0tIGdyYXBlIHN0ZW0gKyBsZWFmIC0tPgogIDxwYXRoIGQ9Ik0xMjggNzNDMTI4IDU5IDEzNyA0OCAxNTEgNDQiIHN0cm9rZT0iI0YzRThGRiIgc3Ryb2tlLXdpZHRoPSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHBhdGggZD0iTTE0MiA1MUMxNTEgMzkgMTY5IDM5IDE3OSA1MEMxNjUgNjAgMTUxIDYyIDE0MiA1MVoiIGZpbGw9IiNDNEI1RkQiLz4KCiAgPCEtLSBtdXNjYXQgZ3JhcGUgY2x1c3RlciAtLT4KICA8Y2lyY2xlIGN4PSIxMDYiIGN5PSI5MSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTMyIiBjeT0iODgiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE1OCIgY3k9IjkxIiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSI5NCIgY3k9IjExOSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTIwIiBjeT0iMTE2IiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxNDYiIGN5PSIxMTYiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE3MiIgY3k9IjExOSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTA3IiBjeT0iMTQ1IiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxMzMiIGN5PSIxNDQiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjE1OSIgY3k9IjE0NSIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CiAgPGNpcmNsZSBjeD0iMTIwIiBjeT0iMTcwIiByPSIxOCIgZmlsbD0idXJsKCNncmFwZSkiLz4KICA8Y2lyY2xlIGN4PSIxNDYiIGN5PSIxNzAiIHI9IjE4IiBmaWxsPSJ1cmwoI2dyYXBlKSIvPgogIDxjaXJjbGUgY3g9IjEzMyIgY3k9IjE5MyIgcj0iMTgiIGZpbGw9InVybCgjZ3JhcGUpIi8+CgogIDwhLS0gY2VudGVyIHBsdWdpbiBnbHlwaCAtLT4KICA8cGF0aCBkPSJNMTIyIDExOVYxMDlDMTIyIDEwMy40NzcgMTI2LjQ3NyA5OSAxMzIgOTlIMTM2QzE0MS41MjMgOTkgMTQ2IDEwMy40NzcgMTQ2IDEwOVYxMTkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+CiAgPHJlY3QgeD0iMTE2IiB5PSIxMTgiIHdpZHRoPSIzNiIgaGVpZ2h0PSIzNCIgcng9IjEwIiBmaWxsPSJ3aGl0ZSIvPgogIDxwYXRoIGQ9Ik0xMjcgMTUyVjE2MyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI4IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KICA8cGF0aCBkPSJNMTQxIDE1MlYxNjMiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iOCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+Cjwvc3ZnPgo=","common/manifest.json":"ewogICJpZCI6ICJfX1BMVUdJTl9JRF9fIiwKICAibmFtZSI6ICJfX1BMVUdJTl9OQU1FX18iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAibWluTXVzY2F0VmVyc2lvbiI6ICIxLjAuMCIsCiAgImF1dGhvciI6ICJfX1BMVUdJTl9BVVRIT1JfXyIsCiAgImVtYWlsIjogIl9fUExVR0lOX0VNQUlMX18iLAogICJkZXNjcmlwdGlvbiI6IHsKICAgICJrbyI6ICIiLAogICAgImVuIjogIiIKICB9LAogICJpY29ucyI6ICJhc3NldHMvaWNvbi5zdmciLAogICJ0YXJnZXRNb2RlbHMiOiAiYWxsIiwKICAidGFyZ2V0Q2F0ZWdvcnlzIjogImFsbCIsCiAgImNvbnRyaWJ1dGVzIjogWwogICAgewogICAgICAicG9pbnQiOiAidG9vbGJhciIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIl9fUExVR0lOX05BTUVfXyIsICJlbiI6ICJfX1BMVUdJTl9OQU1FX18iIH0sCiAgICAgICJ1aSI6ICJjb250ZW50IiwKICAgICAgIm9wZW5zIjogInBvcG92ZXIiCiAgICB9CiAgXSwKICAidmFyaWFibGVzIjogW10sCiAgInJ1bnRpbWUiOiB7ICJ0eXBlIjogIl9fUlVOVElNRV9UWVBFX18iLCAiZW50cnkiOiAibWFpbi5weSIgfQp9Cg==","common/package.json":"ewogICJuYW1lIjogIl9fUExVR0lOX0lEX18iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAicHJpdmF0ZSI6IHRydWUsCiAgInR5cGUiOiAibW9kdWxlIiwKICAiZGVwZW5kZW5jaWVzIjogewogICAgIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aSI6ICJfX1JCX1ZFUlNJT05fXyIKICB9LAogICJkZXZEZXBlbmRlbmNpZXMiOiB7CiAgICAiQHRhaWx3aW5kY3NzL3ZpdGUiOiAiXjQuMS4wIiwKICAgICJAcmFpbmJvdy1yb2JvdGljcy9tdXNjYXQtcGx1Z2luLWtpdCI6ICJfX1JCX1ZFUlNJT05fXyIsCiAgICAiQHJhaW5ib3ctcm9ib3RpY3MvcHJldmlldy1ob3N0IjogIl9fUkJfVkVSU0lPTl9fIiwKICAgICJAdHlwZXMvcmVhY3QiOiAiXjE5LjAuMTAiLAogICAgIkB0eXBlcy9yZWFjdC1kb20iOiAiXjE5LjAuNCIsCiAgICAiQHZpdGVqcy9wbHVnaW4tcmVhY3QiOiAiXjQuMC4wIiwKICAgICJyZWFjdCI6ICJeMTkuMC4wIiwKICAgICJyZWFjdC1kb20iOiAiXjE5LjAuMCIsCiAgICAidGFpbHdpbmRjc3MiOiAiXjQuMS4wIiwKICAgICJ0eXBlc2NyaXB0IjogIl41LjguMCIsCiAgICAidml0ZSI6ICJeNi4wLjAiCiAgfQp9Cg==","common/py/main.py":"IiIiCk11c2NhdCBwbHVnaW4gYmFja2VuZCDigJQgX19QTFVHSU5fTkFNRV9fCgpPbi1yb2JvdCAoZGVmYXVsdCk6CiAgbXVzY2F0LXBrIGRldjpiYWNrCiAgcHl0aG9uIG1haW4ucHkKClJlbW90ZSBkZXYgKGZyb20geW91ciBsYXB0b3ApOgogIFNldCBlbnYgdmFycyBiZWZvcmUgcnVubmluZzoKICAgIE1VU0NBVF9ST0JPVF9IT1NUPTE5Mi4xNjguMS4xMDAKICAgIE1VU0NBVF9ST0JPVF9UT0tFTj08c2VydmljZSB0b2tlbj4KICBUaGVuOiBtdXNjYXQtcGsgZGV2OmJhY2sKCkhhbmRsZXJzOgogIHBsdWdpbi5zZXJ2ZSAvIHBsdWdpbi5zdWJzY3JpYmUgLyBwbHVnaW4ucHVibGlzaCAgLT4gcGx1Z2luIFVJIDwtPiBiYWNrZW5kIG9ubHkKICBwbHVnaW4ucm91dGVyLm9uIC8gc3Vic2NyaWJlIC8gZW1pdCAgICAgICAgICAgICAgIC0+IGV4dGVybmFsIGVuZHBvaW50cwogICAgKFJFU1QgLyBTb2NrZXQuSU8gLyBUQ1AgLyBNUVRUIC8gV2ViUlRDIGF0IGNvbW1vbi9wbHVnaW4vPHBsdWdpbl9pZD4vPHBhdGg+KS4KICAgIE5lZWRzIGEgcm9ib3QgcnVubmluZyByYWluYm93LXJiLXNkayA+PSAwLjAuOS5kZXY1OyBvbGRlciByb2JvdHMgaGF2ZSBubwogICAgYHBsdWdpbi5yb3V0ZXJgIChBdHRyaWJ1dGVFcnJvcikuIFNlZSBSRUFETUUgIkV4dGVybmFsIGVuZHBvaW50cyIuCiIiIgoKaW1wb3J0IGFzeW5jaW8KaW1wb3J0IG9zCmZyb20gdHlwaW5nIGltcG9ydCBBbnkKCmZyb20gcmFpbmJvdy5yYl9zZGsgaW1wb3J0IFJCTWFuaXB1bGF0ZVNESywgUkJQbHVnaW5DYWxsCmZyb20gcmFpbmJvdy5yYl9zZGsucmJfc2RrX2NwcCBpbXBvcnQgQ29ubmVjdE9wdGlvbnMKCgpQTFVHSU5fTkFNRSA9ICJfX1BMVUdJTl9OQU1FX18iCgpwbHVnaW4gPSBSQlBsdWdpbkNhbGwoKQptYW5pcHVsYXRlID0gUkJNYW5pcHVsYXRlU0RLKCkKCgpkZWYgcmVnaXN0ZXJfaGFuZGxlcnMoKToKICAgICMgUmVnaXN0ZXIgaGFuZGxlcnMgaGVyZSDigJQgY2FsbGVkIGFmdGVyIGNvbm5lY3QoKSBzbyBzdWJzY3JpcHRpb25zIHN1cnZpdmUKICAgICMgc2Vzc2lvbiByZWNvbm5lY3Rpb24gaW4gcmVtb3RlLWRldiBtb2RlLgoKICAgICMgLS0tIFBsdWdpbiBVSSA8LT4gYmFja2VuZCAobm90IHJlYWNoYWJsZSBmcm9tIG91dHNpZGUgTXVzY2F0KSAtLS0KCiAgICBAcGx1Z2luLnN1YnNjcmliZSgiZXZlbnQiKQogICAgZGVmIG9uX3VpX2V2ZW50KHBheWxvYWQ6IGRpY3Rbc3RyLCBBbnldIHwgTm9uZSA9IE5vbmUpOgogICAgICAgICIiIkhhbmRsZSBtZXNzYWdlcyBwdWJsaXNoZWQgZnJvbSB0aGUgcGx1Z2luIFVJIHdpdGggcmIucHViKCJldmVudCIsIC4uLikuIiIiCiAgICAgICAgcHJpbnQoZiJbe1BMVUdJTl9OQU1FfV0gZXZlbnQ6IiwgcGF5bG9hZCkKCiAgICBAcGx1Z2luLnNlcnZlKCJncmlwIikKICAgIGRlZiBncmlwKHBheWxvYWQ6IGRpY3Rbc3RyLCBBbnldIHwgTm9uZSA9IE5vbmUpOgogICAgICAgICIiIkhhbmRsZSB0aGUgZGVmYXVsdCBVSSBidXR0b246IHJiLmFjdGlvbigiZ3JpcCIsIHsgd2lkdGggfSkuIiIiCiAgICAgICAgd2lkdGggPSAocGF5bG9hZCBvciB7fSkuZ2V0KCJ3aWR0aCIsIDIwKQogICAgICAgIHByaW50KGYiW3tQTFVHSU5fTkFNRX1dIGdyaXAgcmVxdWVzdGVkOiB3aWR0aD17d2lkdGh9IikKICAgICAgICBwbHVnaW4ucHVibGlzaCgic3RhdGUiLCB7InJlYWR5IjogVHJ1ZSwgImxhc3RfZ3JpcF93aWR0aCI6IHdpZHRofSkKICAgICAgICByZXR1cm4geyJvayI6IFRydWUsICJ3aWR0aCI6IHdpZHRofQoKICAgIEBwbHVnaW4uc2VydmUoInRvb2wvZWNobyIpCiAgICBkZWYgZWNobyhwYXlsb2FkOiBkaWN0W3N0ciwgQW55XSB8IE5vbmUgPSBOb25lKToKICAgICAgICAiIiJTbWFsbCBxdWVyeSBleGFtcGxlIGNhbGxhYmxlIGZyb20gdGhlIFVJIHdpdGggcmIuYWN0aW9uKCJ0b29sL2VjaG8iLCAuLi4pLiIiIgogICAgICAgIHJldHVybiB7ImVjaG8iOiBwYXlsb2FkLCAicGx1Z2luIjogUExVR0lOX05BTUV9CgogICAgIyAtLS0gRXh0ZXJuYWwgZW5kcG9pbnRzIChSRVNUIC8gU29ja2V0LklPIC8gVENQIC8gTVFUVCAvIFdlYlJUQykgLS0tCiAgICAjIEV4cG9zZWQgYXMgY29tbW9uL3BsdWdpbi88cGx1Z2luX2lkPi9oZWxsbywgZS5nLgogICAgIyAgIGN1cmwgLVggUE9TVCBodHRwOi8vPHJvYm90Pi9jb21tb24vcGx1Z2luLzxwbHVnaW5faWQ+L2hlbGxvIFwKICAgICMgICAgICAgIC1IICdDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL2pzb24nIC1kICd7Im5hbWUiOiAia2ltIn0nCiAgICAjIFJlc3RyaWN0IHRyYW5zcG9ydHMgd2l0aCBleHBsaWNpdF9yb3V0ZXM9WyJhcGkiXSAoUkVTVCBvbmx5KSwgZXRjLgogICAgIyBSYWlzZSBQbHVnaW5Sb3V0ZUVycm9yKDQwMywgIm1zZyIpIHRvIHNldCB0aGUgcmVzcG9uc2Ugc3RhdHVzLgoKICAgIEBwbHVnaW4ucm91dGVyLm9uKCIvaGVsbG8iKQogICAgZGVmIGhlbGxvKHBheWxvYWQ6IGRpY3Rbc3RyLCBBbnldIHwgTm9uZSA9IE5vbmUsIG1ldGE6IGRpY3Rbc3RyLCBBbnldIHwgTm9uZSA9IE5vbmUpOgogICAgICAgICIiIm1ldGEgPSB7InRyYW5zcG9ydCI6ICJhcGkifCJzb2NrZXQifCJ0Y3AifCJtcXR0Inwid2VicnRjIiwgInByaW5jaXBhbCI6IGRpY3QgfCBOb25lfS4iIiIKICAgICAgICBuYW1lID0gKHBheWxvYWQgb3Ige30pLmdldCgibmFtZSIsICJ0aGVyZSIpCiAgICAgICAgcmV0dXJuIHsibXNnIjogZiJoaSB7bmFtZX0iLCAidmlhIjogKG1ldGEgb3Ige30pLmdldCgidHJhbnNwb3J0Iil9CgoKZGVmIG1vdmVfal9leGFtcGxlKCk6CiAgICAiIiIKICAgIEV4YW1wbGU6IHVzZSBvdGhlciByb2JvdCBTREtzIGZyb20gdGhlIHNhbWUgYmFja2VuZC4KCiAgICBUaGlzIGZ1bmN0aW9uIGlzIG5vdCBjYWxsZWQgYXV0b21hdGljYWxseS4gQWRkIHNhZmV0eSBjaGVja3MgYW5kIGNhbGwgaXQKICAgIGZyb20geW91ciBvd24gaGFuZGxlciB3aGVuIHRoZSByb2JvdCBpcyByZWFkeS4KICAgICIiIgogICAgcmV0dXJuIG1hbmlwdWxhdGUubW92ZS5jYWxsX21vdmVfaigKICAgICAgICByb2JvdF9tb2RlbD0iQzUwMDkyMCIsCiAgICAgICAgdGFyZ2V0PXsKICAgICAgICAgICAgInRhcl92YWx1ZXMiOiBbMCwgMCwgMCwgMCwgMCwgMF0sCiAgICAgICAgICAgICJ0YXJfZnJhbWUiOiAwLAogICAgICAgICAgICAidGFyX3VuaXQiOiAwLAogICAgICAgIH0sCiAgICApCgoKYXN5bmMgZGVmIG1haW4oKToKICAgIHJvYm90X2hvc3QgPSBvcy5nZXRlbnYoIk1VU0NBVF9ST0JPVF9IT1NUIikKICAgIHJvYm90X3Rva2VuID0gb3MuZ2V0ZW52KCJNVVNDQVRfUk9CT1RfVE9LRU4iKQoKICAgIGlmIHJvYm90X2hvc3QgYW5kIHJvYm90X3Rva2VuOgogICAgICAgICMgUmVtb3RlIGRldjogY29ubmVjdCB0byB0aGUgcm9ib3QgYmVmb3JlIHJlZ2lzdGVyaW5nIGFueSBoYW5kbGVycy4KICAgICAgICAjIGNvbm5lY3QoKSBjbG9zZXMgYW5kIHJlb3BlbnMgdGhlIFplbm9oIHNlc3Npb24sIHNvIGhhbmRsZXJzIHJlZ2lzdGVyZWQKICAgICAgICAjIGJlZm9yZSB0aGlzIGNhbGwgd291bGQgYmUgbG9zdC4KICAgICAgICBvcHRzID0gQ29ubmVjdE9wdGlvbnMoKQogICAgICAgIG9wdHMudG9rZW4gPSByb2JvdF90b2tlbgogICAgICAgIG9wdHMuaG9zdCA9IHJvYm90X2hvc3QKICAgICAgICBtYW5pcHVsYXRlLmNvbm5lY3Qob3B0cykKCiAgICByZWdpc3Rlcl9oYW5kbGVycygpCgogICAgcGx1Z2luLnB1Ymxpc2goInN0YXRlIiwgeyJyZWFkeSI6IFRydWUsICJwbHVnaW4iOiBQTFVHSU5fTkFNRX0pICAgICAgICMgLT4gcGx1Z2luIFVJCiAgICBwbHVnaW4ucm91dGVyLmVtaXQoIi9zdGF0ZSIsIHsicmVhZHkiOiBUcnVlLCAicGx1Z2luIjogUExVR0lOX05BTUV9KSAgIyAtPiBleHRlcm5hbCBzdWJzY3JpYmVycyBvZiBjb21tb24vcGx1Z2luLzxwbHVnaW5faWQ+L3N0YXRlCiAgICBwcmludChmIlt7UExVR0lOX05BTUV9XSBiYWNrZW5kIHJlYWR5IikKCiAgICB0cnk6CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgYXdhaXQgYXN5bmNpby5zbGVlcCgxKQogICAgZXhjZXB0IChLZXlib2FyZEludGVycnVwdCwgYXN5bmNpby5DYW5jZWxsZWRFcnJvcik6CiAgICAgICAgcGFzcwogICAgZmluYWxseToKICAgICAgICBpZiByb2JvdF9ob3N0IGFuZCByb2JvdF90b2tlbjoKICAgICAgICAgICAgYXdhaXQgbWFuaXB1bGF0ZS5kaXNjb25uZWN0KCkKICAgICAgICBwcmludChmIlt7UExVR0lOX05BTUV9XSBzdG9wcGVkIikKCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdHJ5OgogICAgICAgIGFzeW5jaW8ucnVuKG1haW4oKSkKICAgIGV4Y2VwdCBLZXlib2FyZEludGVycnVwdDoKICAgICAgICBwYXNzCg==","common/requirements.txt":"cmFpbmJvdy1yYi1zZGs9PTAuMTAuMgpyYWluYm93LXJiLWZsYXQtYnVmZmVycz09MC4xMC4yCnJhaW5ib3ctcmItemVub2g9PTAuMTAuMgpyZXF1ZXN0cz09Mi4zNC4yCg==","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":"Y21ha2VfbWluaW11bV9yZXF1aXJlZChWRVJTSU9OIDMuMTYpCnByb2plY3QoX19QTFVHSU5fU0xVR19fIENYWCkKCnNldChDTUFLRV9DWFhfU1RBTkRBUkQgMjApCnNldChDTUFLRV9DWFhfU1RBTkRBUkRfUkVRVUlSRUQgT04pCgojIFJhaW5ib3cgUm9ib3RpY3MgQysrIFNESyDigJQgcHJvdmlkZWQgYnkgdGhlIGFwdCBwYWNrYWdlIHJhaW5ib3ctcmItc2RrLWRldgojIChwcmUtaW5zdGFsbGVkIGluIHRoZSBtdXNjYXQtcGsgZGV2IGNvbnRhaW5lcikuIFRoZSB2ZXJzaW9uIGhlcmUgaXMgdGhlIG9uZSB0aGUKIyBkZXYgY29udGFpbmVyIGluc3RhbGxzOyBjaGFuZ2UgaXQgd2l0aCBgbXVzY2F0LXBrIHNkayB1cGRhdGUgPHZlcnNpb24+YC4KZmluZF9wYWNrYWdlKHJiX3NkayAwLjEwLjIgRVhBQ1QgUkVRVUlSRUQpCgojIFRoZSBleGVjdXRhYmxlIG5hbWUgbXVzdCBtYXRjaCBydW50aW1lLmVudHJ5IGluIG1hbmlmZXN0Lmpzb24uCmFkZF9leGVjdXRhYmxlKF9fUExVR0lOX1NMVUdfXyBtYWluLmNwcCkKdGFyZ2V0X2xpbmtfbGlicmFyaWVzKF9fUExVR0lOX1NMVUdfXyBQUklWQVRFIHJiX3Nkazo6cmJfc2RrKQo=","cpp/cpp/main.cpp":"Ly8gX19QTFVHSU5fTkFNRV9fIOKAlCBDKysgcGx1Z2luIGJhY2sgZW5kLgovLwovLyBUaGUgUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLIChhcHQ6IHJhaW5ib3ctcmItc2RrLWRldikgaXMgaW5zdGFsbGVkIGluIHRoZQovLyBkZXYgY29udGFpbmVyIGFuZCBsaW5rZWQgdmlhIENNYWtlIChyYl9zZGs6OnJiX3NkaykuIEhlYWRlcnMgbGl2ZSB1bmRlcgovLyA8cmFpbmJvdy9yYl9zZGsvLi4uPjoKLy8gICAtIHBsdWdpbi9yYl9wbHVnaW4uaHBwICAgICAgICAgICAgICAgcmJfcGx1Z2luOjpSQlBsdWdpbkNhbGwg4oCUIHBsdWdpbiBVSSA8LT4gYmFja2VuZAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VydmUvc3Vic2NyaWJlL3B1Ymxpc2gpIGFuZCBleHRlcm5hbCBlbmRwb2ludHMgKHJvdXRlcikKLy8gICAtIG1hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwICAgUkJNYW5pcHVsYXRlU0RLIOKAlCBjb250cm9sIHRoZSByb2JvdAovLyAgIC0gcHJvZ3JhbS9wbHVnaW5fcHJvZ3JhbV9jb250ZXh0LmhwcCByYl9wbHVnaW46OlBsdWdpblByb2dyYW1Db250ZXh0IOKAlAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9ncmFtLnBhbmVsIGNvbW1hbmRzIChkb25lL3BhdXNlL3N0b3AsCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyYW0gdmFyaWFibGVzKQoKI2luY2x1ZGUgPHJhaW5ib3cvcmJfc2RrL21hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwPgojaW5jbHVkZSA8cmFpbmJvdy9yYl9zZGsvcGx1Z2luL3JiX3BsdWdpbi5ocHA+CgojaW5jbHVkZSA8bmxvaG1hbm4vanNvbi5ocHA+CgojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dGhyZWFkPgoKdXNpbmcgbmxvaG1hbm46Ompzb247CnVzaW5nIHJiX3BsdWdpbjo6UkJQbHVnaW5DYWxsOwoKaW50IG1haW4oKSB7CiAgY29uc3Qgc3RkOjpzdHJpbmcgbmFtZSA9ICJfX1BMVUdJTl9OQU1FX18iOwoKICAvLyBSZW1vdGUgZGV2OiBjb25uZWN0IGJlZm9yZSByZWdpc3RlcmluZyBoYW5kbGVycyAoY29ubmVjdCgpIHJlb3BlbnMgdGhlIHNlc3Npb24pLgogIFJCTWFuaXB1bGF0ZVNESyBtYW5pcHVsYXRlOwogIGNvbnN0IGNoYXIqIGhvc3QgPSBzdGQ6OmdldGVudigiTVVTQ0FUX1JPQk9UX0hPU1QiKTsKICBjb25zdCBjaGFyKiB0b2tlbiA9IHN0ZDo6Z2V0ZW52KCJNVVNDQVRfUk9CT1RfVE9LRU4iKTsKICBpZiAoaG9zdCAmJiB0b2tlbikgbWFuaXB1bGF0ZS5jb25uZWN0KHsudG9rZW4gPSB0b2tlbiwgLmhvc3QgPSBob3N0fSk7CgogIC8vIHBsdWdpbiBpZCBjb21lcyBmcm9tIFJCX1BMVUdJTl9JRC4KICBhdXRvIHBsdWdpbiA9IFJCUGx1Z2luQ2FsbDo6Z2V0X2luc3RhbmNlKFJCUGx1Z2luQ2FsbDo6cmVzb2x2ZV9wbHVnaW5faWQoc3RkOjpudWxsb3B0KSk7CgogIC8vIC0tLSBQbHVnaW4gVUkgPC0+IGJhY2tlbmQgKG5vdCByZWFjaGFibGUgZnJvbSBvdXRzaWRlIE11c2NhdCkgLS0tCgogIC8vIFVJOiBhd2FpdCByYi5hY3Rpb24oImdyaXAiLCB7IHdpZHRoIH0pCiAgcGx1Z2luLT5zZXJ2ZSgiZ3JpcCIsIFsmXShjb25zdCBqc29uJiBwYXlsb2FkKSB7CiAgICBjb25zdCBpbnQgd2lkdGggPSBwYXlsb2FkLmlzX29iamVjdCgpID8gcGF5bG9hZC52YWx1ZSgid2lkdGgiLCAyMCkgOiAyMDsKICAgIHN0ZDo6Y291dCA8PCAiWyIgPDwgbmFtZSA8PCAiXSBncmlwIHJlcXVlc3RlZDogd2lkdGg9IiA8PCB3aWR0aCA8PCBzdGQ6OmVuZGw7CiAgICBwbHVnaW4tPnB1Ymxpc2goInN0YXRlIiwge3sicmVhZHkiLCB0cnVlfSwgeyJsYXN0X2dyaXBfd2lkdGgiLCB3aWR0aH19KTsgIC8vIC0+IHJiLnN1Yigic3RhdGUiKQogICAgcmV0dXJuIGpzb257eyJvayIsIHRydWV9LCB7IndpZHRoIiwgd2lkdGh9fTsKICB9KTsKCiAgLy8gVUk6IHJiLnB1YigiZXZlbnQiLCAuLi4pCiAgYXV0byBldmVudF9zdWIgPSBwbHVnaW4tPnN1YnNjcmliZSgiZXZlbnQiLCBbJl0oY29uc3Qgc3RkOjpzdHJpbmcmLCBjb25zdCBqc29uJiBwYXlsb2FkKSB7CiAgICBzdGQ6OmNvdXQgPDwgIlsiIDw8IG5hbWUgPDwgIl0gZXZlbnQ6ICIgPDwgcGF5bG9hZC5kdW1wKCkgPDwgc3RkOjplbmRsOwogIH0pOwoKICAvLyAtLS0gRXh0ZXJuYWwgZW5kcG9pbnRzIChSRVNUIC8gU29ja2V0LklPIC8gVENQIC8gTVFUVCAvIFdlYlJUQykgLS0tCiAgLy8gICBjdXJsIC1YIFBPU1QgaHR0cDovLzxyb2JvdD4vY29tbW9uL3BsdWdpbi88cGx1Z2luX2lkPi9oZWxsbyAtZCAneyJuYW1lIjoia2ltIn0nCiAgcGx1Z2luLT5yb3V0ZXIoKS5vbigiL2hlbGxvIiwgW10oY29uc3QganNvbiYgcGF5bG9hZCwgY29uc3QganNvbiYgbWV0YSkgewogICAgY29uc3Qgc3RkOjpzdHJpbmcgd2hvID0gcGF5bG9hZC5pc19vYmplY3QoKSA/IHBheWxvYWQudmFsdWUoIm5hbWUiLCBzdGQ6OnN0cmluZygidGhlcmUiKSkgOiAidGhlcmUiOwogICAgcmV0dXJuIGpzb257eyJtc2ciLCAiaGkgIiArIHdob30sIHsidmlhIiwgbWV0YS52YWx1ZSgidHJhbnNwb3J0Iiwgc3RkOjpzdHJpbmcoKSl9fTsKICB9KTsKCiAgLy8gRXhhbXBsZTogcm9ib3QgY29udHJvbCAobm90IGNhbGxlZCBhdXRvbWF0aWNhbGx5IOKAlCBhZGQgc2FmZXR5IGNoZWNrcyBmaXJzdCkuCiAgLy8gICBJUEM6Ok1vdmVJbnB1dF9UYXJnZXRUIHQ7IHQudGFyX3ZhbHVlcyA9IHswLCAwLCAwLCAwLCAwLCAwfTsKICAvLyAgIG1hbmlwdWxhdGUubW92ZS5jYWxsX21vdmVfaigiQzUwMDkyMCIsIHQpOwoKICBwbHVnaW4tPnB1Ymxpc2goInN0YXRlIiwge3sicmVhZHkiLCB0cnVlfSwgeyJwbHVnaW4iLCBuYW1lfX0pOwogIHN0ZDo6Y291dCA8PCAiWyIgPDwgbmFtZSA8PCAiXSBiYWNrZW5kIHJlYWR5IiA8PCBzdGQ6OmVuZGw7CgogIC8vIEtlZXAgdGhlIHByb2Nlc3MgYWxpdmUuCiAgd2hpbGUgKHRydWUpIHsKICAgIHN0ZDo6dGhpc190aHJlYWQ6OnNsZWVwX2ZvcihzdGQ6OmNocm9ubzo6c2Vjb25kcygxKSk7CiAgfQogIHJldHVybiAwOwp9Cg==","readme-cpp/README.md":"IyBfX1BMVUdJTl9OQU1FX18KCkEgTXVzY2F0IHBsdWdpbiBwcm9qZWN0LiBCdWlsZCwgZGV2ZWxvcCwgYW5kIHNoaXAgd2l0aCBgbXVzY2F0LXBrYCBDTEkuCgojIyBRdWljayBzdGFydAoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJIHByZXZpZXcgKyBiYWNrZW5kIHRvZ2V0aGVyCm11c2NhdC1wayBkZXY6dWkgICAgICMgVUkgcHJldmlldyBvbmx5Cm11c2NhdC1wayBkZXY6YmFjayAgICMgYmFja2VuZCBvbmx5IChDKysgcmVidWlsZCArIHJlc3RhcnQgaW4gRG9ja2VyKQptdXNjYXQtcGsgYnVpbGQgICAgICAjIGJ1aWxkICsgZGlzdHJpYnV0YWJsZSBaSVAKYGBgCgotLS0KCiMjIFByb2plY3Qgc3RydWN0dXJlCgpgYGAKX19QTFVHSU5fRElSX18vCuKUnOKUgCB1aS8K4pSCICAg4pSc4pSAIGNvbnRlbnQudHN4ICAgICAgIyBwbHVnaW4gVUkgZW50cnkgcG9pbnQK4pSCICAg4pSU4pSAIHN0eWxlLmNzcyAgICAgICAgIyBwbHVnaW4gc3R5bGVzIGF1dG8tbG9hZGVkIGJ5IG11c2NhdCgpCuKUnOKUgCBjcHAvCuKUgiAgIOKUnOKUgCBDTWFrZUxpc3RzLnR4dCAgICMgbGlua3MgcmJfc2RrOjpyYl9zZGsgKEMrKyBTREspCuKUgiAgIOKUlOKUgCBtYWluLmNwcCAgICAgICAgICMgQysrIGJhY2tlbmQgZW50cnkgcG9pbnQK4pSc4pSAIGFzc2V0cy8K4pSCICAg4pSU4pSAIGljb24uc3ZnICAgICAgICAgIyBpY29uIHJlZmVyZW5jZWQgZnJvbSBtYW5pZmVzdArilJzilIAgbWFuaWZlc3QuanNvbiAgICAgICAgIyBtZXRhZGF0YSwgY29udHJpYnV0aW9uIHBvaW50cywgcnVudGltZSBjb25maWcK4pSU4pSAIFJFQURNRS5tZCAgICAgICAgICAgICMgdGhpcyBmaWxlIChjb3BpZWQgdG8gZGlzdC8gb24gYnVpbGQpCmBgYAoKPiBST1MyIChyY2xjcHApIHBsdWdpbnMgaGF2ZSBgcm9zMl93cy9gIGluc3RlYWQgb2YgYGNwcC9gLgoKLS0tCgojIyBGcm9udGVuZCAoYHVpL2NvbnRlbnQudHN4YCkKCiMjIyBKYXZhU2NyaXB0IGRlcGVuZGVuY2llcwoKYG11c2NhdC1wayBidWlsZGAgcnVucyB0aGlzIHBsdWdpbiBwcm9qZWN0J3Mgb3duIFZpdGUgYnVpbGQuIFZpdGUgcmVzb2x2ZXMKaW1wb3J0cyBmcm9tIGluc3RhbGxlZCBgbm9kZV9tb2R1bGVzYDsgaXQgZG9lcyBub3QgY2FyZSB3aGV0aGVyIGEgcGFja2FnZSBpcwpsaXN0ZWQgdW5kZXIgYGRlcGVuZGVuY2llc2Agb3IgYGRldkRlcGVuZGVuY2llc2AsIGJ1dCB0aGUgcGFja2FnZSBtdXN0IGJlCmluc3RhbGxlZC4KCkRvIG5vdCBydW4gYSBwcm9kdWN0aW9uLW9ubHkgaW5zdGFsbCBzdWNoIGFzIGBucG0gaW5zdGFsbCAtLW9taXQ9ZGV2YCBiZWZvcmUKYnVpbGRpbmcgdGhlIHBsdWdpbiBVSSwgYmVjYXVzZSBidWlsZCB0b29scyBsaWtlIGB2aXRlYCwgYHR5cGVzY3JpcHRgLApgdGFpbHdpbmRjc3NgLCBgQHRhaWx3aW5kY3NzL3ZpdGVgLCBgc2Fzc2AsIG9yIGBsZXNzYCBhcmUgdXN1YWxseQpgZGV2RGVwZW5kZW5jaWVzYC4KClRoZSBzY2FmZm9sZCBrZWVwcyB0aGlzIHNwbGl0OgoKfCBwYWNrYWdlIGtpbmQgfCBleGFtcGxlcyB8IHdoeSB8CnwtLS18LS0tfC0tLXwKfCBgZGVwZW5kZW5jaWVzYCB8IGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWlgLCBVSSBsaWJyYXJpZXMgaW1wb3J0ZWQgYnkgcGx1Z2luIHNvdXJjZSB8IEF1dGhvci1mYWNpbmcgQVBJcyB1c2VkIGJ5IGB1aS8qLnRzeGAgfAp8IGBkZXZEZXBlbmRlbmNpZXNgIHwgYHZpdGVgLCBgdHlwZXNjcmlwdGAsIGB0YWlsd2luZGNzc2AsIGBAdGFpbHdpbmRjc3Mvdml0ZWAsIGBzYXNzYCwgYGxlc3NgIHwgQnVpbGQvZGV2IHRvb2xzIG5lZWRlZCBiZWZvcmUgYGRpc3QvKi5qc2AgaXMgcHJvZHVjZWQgfAoKVGhlIGJ1aWx0IHBsdWdpbiBaSVAgZG9lcyBub3QgaW5jbHVkZSBgcGFja2FnZS5qc29uYCBvciBgbm9kZV9tb2R1bGVzYC4gRm9yCnByb2R1Y3Rpb24sIE11c2NhdCBwcm92aWRlcyBgQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpYCwgUmVhY3QsIGFuZCBSZWFjdERPTQp0aHJvdWdoIHRoZSBob3N0IGltcG9ydCBtYXA7IHBsdWdpbiBVSSBidWlsZCBvdXRwdXQgaW1wb3J0cyB0aG9zZSBhcyBob3N0CmV4dGVybmFscy4KCiMjIyBTdHlsZXMKCmBtdXNjYXQoKWAgYXV0b21hdGljYWxseSBsb2FkcyBgdWkvc3R5bGUue2NzcyxzY3NzLHNhc3MsbGVzc31gIChvcgpgdWkvc3R5bGVzLntjc3Msc2NzcyxzYXNzLGxlc3N9YCkgZm9yIGV2ZXJ5IFVJIGVudHJ5LCBwbHVzCmB1aS97ZW50cnl9Lntjc3Msc2NzcyxzYXNzLGxlc3N9YCBmb3IgYSBtYXRjaGluZyBlbnRyeS1zcGVjaWZpYyBzdHlsZXNoZWV0LiBZb3UKZG8gbm90IG5lZWQgdG8gaW1wb3J0IENTUyBmcm9tIGV2ZXJ5IGAudHN4YCBmaWxlLgoKVGhlIHNjYWZmb2xkIHVzZXMgVGFpbHdpbmQncyB0aGVtZS91dGlsaXRpZXMgbGF5ZXJzIG9ubHksIHNvIHBsdWdpbiB1dGlsaXRpZXMKYXJlIGdlbmVyYXRlZCBmcm9tIGZpbGVzIHVuZGVyIGB1aS9gIHdpdGhvdXQgYXBwbHlpbmcgVGFpbHdpbmQgcHJlZmxpZ2h0IHJlc2V0cwp0byB0aGUgaG9zdCBwYWdlLgoKQnVpbHQgQ1NTIHNlbGVjdG9ycyBhcmUgc2NvcGVkIHVuZGVyIHRoZSBjdXJyZW50IHBsdWdpbiBpZAooYFtkYXRhLW11c2NhdC1wbHVnaW4taWQ9Ii4uLiJdYCkuIENTUy1pbi1KUyBsaWJyYXJpZXMgc3VjaCBhcyBFbW90aW9uIHdvcmsKbm9ybWFsbHksIGJ1dCBnbG9iYWwgc3R5bGVzIHNob3VsZCBiZSBzY29wZWQgYnkgdGhlIGF1dGhvci4KCiMjIyMgVGFpbHdpbmQKClRoaXMgdGVtcGxhdGUgZW5hYmxlcyBUYWlsd2luZCBpbiBgdml0ZS5jb25maWcudHNgOgoKYGBgdHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbdGFpbHdpbmRjc3MoKSwgbXVzY2F0KCldLAp9KTsKYGBgCgpUaGUgZGVmYXVsdCBgdWkvc3R5bGUuY3NzYCB1c2VzIFRhaWx3aW5kIHRoZW1lL3V0aWxpdGllcyBvbmx5LCBub3QgcHJlZmxpZ2h0OgoKYGBgY3NzCkBsYXllciB0aGVtZSwgdXRpbGl0aWVzOwoKQGltcG9ydCAidGFpbHdpbmRjc3MvdGhlbWUuY3NzIiBsYXllcih0aGVtZSk7CkBpbXBvcnQgInRhaWx3aW5kY3NzL3V0aWxpdGllcy5jc3MiIGxheWVyKHV0aWxpdGllcyk7CgpAc291cmNlICIuLyoqLyoue3RzLHRzeH0iOwpgYGAKCiMjIyMgU0NTUywgU2FzcywgYW5kIExlc3MKCkluc3RhbGwgdGhlIHByZXByb2Nlc3NvciBwYWNrYWdlLCB0aGVuIGNyZWF0ZSBvbmUgb2YgdGhlIGF1dG8tbG9hZGVkIHN0eWxlIGZpbGVzLgoKYGBgYmFzaApucG0gaSAtRCBzYXNzCmBgYAoKYGBgc2NzcwovKiB1aS9zdHlsZS5zY3NzICovCiRhY2NlbnQ6ICMzYjgyZjY7CgoucGFuZWwgewogIGJvcmRlcjogMXB4IHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCAkYWNjZW50IDQwJSwgdHJhbnNwYXJlbnQpOwoKICAmX190aXRsZSB7CiAgICBjb2xvcjogJGFjY2VudDsKICB9Cn0KYGBgCgpGb3IgTGVzcywgaW5zdGFsbCBgbGVzc2AgYW5kIHVzZSBgdWkvc3R5bGUubGVzc2AuCgojIyMjIEVtb3Rpb24KCkVtb3Rpb24gZGVwZW5kZW5jaWVzIG1heSBiZSBpbiBgZGVwZW5kZW5jaWVzYCBvciBgZGV2RGVwZW5kZW5jaWVzYDsgVml0ZSBjYW4KYnVuZGxlIHRoZW0gd2hlbiB0aGV5IGFyZSBpbnN0YWxsZWQgYW5kIGltcG9ydGVkIGJ5IHRoZSBwbHVnaW4uCgpGb3IgYHN0eWxlZGAsIG5vIFZpdGUgY29uZmlnIGNoYW5nZSBpcyBuZWVkZWQ6CgpgYGBiYXNoCm5wbSBpIEBlbW90aW9uL3JlYWN0IEBlbW90aW9uL3N0eWxlZApgYGAKCmBgYHRzeAppbXBvcnQgc3R5bGVkIGZyb20gIkBlbW90aW9uL3N0eWxlZCI7Cgpjb25zdCBQYW5lbCA9IHN0eWxlZC5kaXYoewogIGRpc3BsYXk6ICJncmlkIiwKICBnYXA6IDEyLAp9KTsKYGBgCgpGb3IgRW1vdGlvbidzIGBjc3NgIHByb3AsIHBhc3MgUmVhY3QgcGx1Z2luIG9wdGlvbnMgdGhyb3VnaCBgbXVzY2F0KClgIGFuZCBhZGQKYGpzeEltcG9ydFNvdXJjZWAgdG8gYHRzY29uZmlnLmpzb25gOgoKYGBgYmFzaApucG0gaSBAZW1vdGlvbi9yZWFjdCBAZW1vdGlvbi9zdHlsZWQKbnBtIGkgLUQgQGVtb3Rpb24vYmFiZWwtcGx1Z2luCmBgYAoKYGBgdHMKLy8gdml0ZS5jb25maWcudHMKaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAidml0ZSI7CmltcG9ydCB0YWlsd2luZGNzcyBmcm9tICJAdGFpbHdpbmRjc3Mvdml0ZSI7CmltcG9ydCB7IG11c2NhdCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL211c2NhdC1wbHVnaW4ta2l0L3ZpdGUiOwoKZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHsKICBwbHVnaW5zOiBbCiAgICB0YWlsd2luZGNzcygpLAogICAgbXVzY2F0KHsKICAgICAgcmVhY3Q6IHsKICAgICAgICBqc3hJbXBvcnRTb3VyY2U6ICJAZW1vdGlvbi9yZWFjdCIsCiAgICAgICAgYmFiZWw6IHsKICAgICAgICAgIHBsdWdpbnM6IFsiQGVtb3Rpb24vYmFiZWwtcGx1Z2luIl0sCiAgICAgICAgfSwKICAgICAgfSwKICAgIH0pLAogIF0sCn0pOwpgYGAKCmBgYGpzb24KewogICJjb21waWxlck9wdGlvbnMiOiB7CiAgICAianN4SW1wb3J0U291cmNlIjogIkBlbW90aW9uL3JlYWN0IgogIH0KfQpgYGAKCkVtb3Rpb24gYEdsb2JhbGAgd3JpdGVzIGdsb2JhbCBDU1MgYXQgcnVudGltZSwgc28gc2NvcGUgaXQgbWFudWFsbHkgb3IgYXZvaWQgaXQKaW5zaWRlIHBsdWdpbnMuCgojIyMgdXNlUmIoKSBob29rCgpBY2Nlc3MgdGhlIGNvbW11bmljYXRpb24gQVBJIGJldHdlZW4gdGhlIHBsdWdpbiBtb2R1bGUgYW5kIFVJIGZyb20gYW55IHBsdWdpbiBjb21wb25lbnQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlUmIgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvc2RrIjsKCmZ1bmN0aW9uIEFwcCgpIHsKICBjb25zdCByYiA9IHVzZVJiKCk7Cn0KYGBgCgojIyMgcmIgQVBJCgp8IE1ldGhvZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfAp8IGByYi5wdWIodG9waWMsIHBheWxvYWQpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFB1Ymxpc2ggYSBtZXNzYWdlIHRvIGEgdG9waWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAp8IGByYi5zdWIodG9waWMsIGhhbmRsZXIpYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFN1YnNjcmliZSB0byBhIHRvcGljIOKAlCByZXR1cm5zIGB7IHVuZGVjbGFyZSgpIH1gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmFjdGlvbih0b3BpYywgcGF5bG9hZD8pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2VuZCBhIHJlcXVlc3QgYW5kIGF3YWl0IGEgcmVwbHkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnNlcnZlKHRvcGljLCBoYW5kbGVyKWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgSGFuZGxlIGluY29taW5nIHJlcXVlc3RzIGZyb20gdGhlIGJhY2tlbmQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnRvYXN0KHsgdGl0bGU/LCBtZXNzYWdlLCB0eXBlPywgYWN0aW9uTGFiZWw/LCBoYW5kbGVBY3Rpb25DbGljaz8sIGNsb3NlT25BY3Rpb25DbGljaz8sIGR1cmF0aW9uPywgb25DbG9zZT8gfSlgIHwgU2hvdyBhIGhvc3QgdG9hc3Qgbm90aWZpY2F0aW9uLiBgbWVzc2FnZWAgYWNjZXB0cyBhIHN0cmluZyBvciBgUmVhY3RFbGVtZW50YC4gYHR5cGVgIGNhbiBiZSBgImluZm8iYCwgYCJkYW5nZXIiYCwgYCJ3YXJuaW5nImAsIGAiY2F1dGlvbiJgLCBvciBgInN1Y2Nlc3MiYCB8CnwgYHJiLmFsZXJ0KHsgdGl0bGU/LCBtZXNzYWdlLCBidXR0b25UZXh0PyB9KWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgYWxlcnQgZGlhbG9nLiBSZXNvbHZlcyB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLmNvbmZpcm0oeyB0aXRsZT8sIG1lc3NhZ2UsIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgY29uZmlybWF0aW9uIGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gYHRydWVgIG9yIGBmYWxzZWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgYHJiLnByb21wdCh7IHRpdGxlPywgbWVzc2FnZSwgdmFsdWU/LCBwbGFjZWhvbGRlcj8sIGJ1dHRvblRleHQ/IH0pYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2hvdyBhIGhvc3QgcHJvbXB0IGRpYWxvZy4gYGJ1dHRvblRleHRgIGFjY2VwdHMgYHsgeWVzLCBubyB9YC4gUmVzb2x2ZXMgdG8gdGhlIGVudGVyZWQgc3RyaW5nIG9yIGB1bmRlZmluZWRgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CgpUb3BpYyBuYW1lcyBwYXNzZWQgdG8gYHB1YmAsIGBzdWJgLCBgYWN0aW9uYCwgYW5kIGBzZXJ2ZWAgYXJlIGlzb2xhdGVkIHBlciBwbHVnaW4uCgoKQWxsIG1ldGhvZHMgc3VwcG9ydCBHZW5lcmljIFR5cGVzOgoKYGBgdHN4CmNvbnN0IHN0YXR1cyA9IGF3YWl0IHJiLmFjdGlvbjx7IG9rOiBib29sZWFuIH0sIHsgaWQ6IG51bWJlciB9PigKICAiZ2V0LXN0YXR1cyIsCiAgeyBpZDogMSB9LAopOwoKY29uc3Qgc3ViID0gYXdhaXQgcmIuc3ViPHsgdmFsdWU6IG51bWJlciB9Pigic2Vuc29yL2RhdGEiLCAoZGF0YSkgPT4gewogIGNvbnNvbGUubG9nKGRhdGEudmFsdWUpOwp9KTsKc3ViLnVuZGVjbGFyZSgpOyAvLyBjbGVhbnVwCgpjb25zdCBvayA9IGF3YWl0IHJiLmNvbmZpcm0oewogIHRpdGxlOiAiUnVuIiwKICBtZXNzYWdlOiAiU3RhcnQgdGhlIGJhY2tlbmQgYWN0aW9uPyIsCn0pOwppZiAob2spIHsKICBhd2FpdCByYi5hY3Rpb24oInJ1biIpOwp9CmBgYAoKIyMjIFNhdmluZyBhbmQgcmVzdG9yaW5nIGZvcm0gZGF0YSAoYHVzZVJiRm9ybURhdGFgIC8gYHVzZVJiU2F2ZWApCgpJZiB0aGUgaG9zdCBlbWJlZHMgeW91ciBwbHVnaW4gaW4gYSBmb3JtIGl0IG93bnMgKGUuZy4gYSBwcm9ncmFtIHN0ZXAgZWRpdG9yCndpdGggaXRzIG93biBTYXZlIGJ1dHRvbiksIGl0IGNhbiBoYW5kIHlvdXIgcGx1Z2luIHByZXZpb3VzbHktc2F2ZWQgdmFsdWVzIGFuZApwdWxsIHRoZSBjdXJyZW50IHZhbHVlcyBiYWNrIG91dCB3aGVuIHRoZSB1c2VyIHNhdmVzLiBUaGUgaG9zdCDigJQgbm90IHRoZQpwbHVnaW4g4oCUIHBlcnNpc3RzIHRoZSBkYXRhIChJbmRleGVkREIsIGJhY2tlbmQsIGV0Yy4pLgoKYGBgdHN4CmltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSAicmVhY3QiOwppbXBvcnQgeyB1c2VSYkZvcm1EYXRhLCB1c2VSYlNhdmUgfSBmcm9tICJAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3QiOwoKdHlwZSBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogc3RyaW5nOyB3aWR0aDogbnVtYmVyIH07CmNvbnN0IERFRkFVTFRTOiBHcmlwQXJncyA9IHsgdGFyZ2V0TmFtZTogIiIsIHdpZHRoOiAyMCB9OwoKZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwKCkgewogIC8vIFByZXZpb3VzbHktc2F2ZWQgdmFsdWVzLCBvciB1bmRlZmluZWQgZm9yIGEgYnJhbmQtbmV3IGluc3RhbmNlLgogIGNvbnN0IHNhdmVkID0gdXNlUmJGb3JtRGF0YTxHcmlwQXJncz4oKTsKICBjb25zdCBbYXJncywgc2V0QXJnc10gPSB1c2VTdGF0ZTxHcmlwQXJncz4oeyAuLi5ERUZBVUxUUywgLi4uc2F2ZWQgfSk7CgogIC8vIFJlZ2lzdGVycyBhIGdldHRlciB0aGUgaG9zdCBjYWxscyB3aGVuIGl0cyBTYXZlIGJ1dHRvbiBpcyBjbGlja2VkLgogIC8vIEFsd2F5cyByZXR1cm5zIHRoZSBDVVJSRU5UIHZhbHVlcyDigJQgcmUtcmVnaXN0ZXJpbmcgb24gZXZlcnkgcmVuZGVyIGtlZXBzCiAgLy8gdGhlIGNsb3N1cmUgZnJlc2gsIHdoaWNoIHVzZVJiU2F2ZSBhbHJlYWR5IGhhbmRsZXMgZm9yIHlvdS4KICB1c2VSYlNhdmUoKCkgPT4gKHsKICAgIGFyZ3MsCiAgICBzdW1tYXJ5OiBgJHthcmdzLnRhcmdldE5hbWUgfHwgInRhcmdldCJ9IMK3ICR7YXJncy53aWR0aH1tbWAsCiAgfSkpOwoKICByZXR1cm4gKC8qIC4uLmZvcm0gVUkgcmVhZGluZy93cml0aW5nIGBhcmdzYC4uLiAqLyk7Cn0KYGBgCgpUaGUgdmFsdWUgcmV0dXJuZWQgZnJvbSBgdXNlUmJTYXZlYCBtdXN0IGJlIEpTT04tc2VyaWFsaXNhYmxlIOKAlCB0aGUgaG9zdApwZXJzaXN0cyBpdCBhcy1pcy4gTm90IGV2ZXJ5IGhvc3QgZW1iZWRzIHBsdWdpbnMgaW4gYSBzYXZlL3Jlc3RvcmUgZm9ybTsgaWYKeW91cnMgZG9lc24ndCwgeW91IGNhbiBza2lwIHRoZXNlIGhvb2tzIGVudGlyZWx5LgoKIyMjIFVJIGNvbXBvbmVudHMKCkltcG9ydCBNdXNjYXQgY29tcG9uZW50cyBmcm9tIGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3RgIGFuZCBleHBvcnQgYQpSZWFjdCBjb21wb25lbnQgYXMgdGhlIGRlZmF1bHQgZXhwb3J0LiBUaGUgaG9zdCBtb3VudHMgdGhhdCBjb21wb25lbnQgZGlyZWN0bHkKYW5kIHByb3ZpZGVzIGB1c2VSYigpYCB0aHJvdWdoIGNvbnRleHQuCgpgYGB0c3gKaW1wb3J0IHsgdXNlU3RhdGUgfSBmcm9tICJyZWFjdCI7CmltcG9ydCB7IFJCTGFiZWxCdXR0b24sIFJCU2xpZGVyLCBSQlN3aXRjaCB9IGZyb20gIkByYWluYm93LXJvYm90aWNzL3BsdWdpbi11aS9yZWFjdCI7CmltcG9ydCB7IHVzZVJiIH0gZnJvbSAiQHJhaW5ib3ctcm9ib3RpY3MvcGx1Z2luLXVpL3NkayI7CgpleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7CiAgY29uc3QgcmIgPSB1c2VSYigpOwogIGNvbnN0IFt3aWR0aCwgc2V0V2lkdGhdID0gdXNlU3RhdGUoMjApOwogIGNvbnN0IFtlbmFibGVkLCBzZXRFbmFibGVkXSA9IHVzZVN0YXRlKHRydWUpOwoKICByZXR1cm4gKAogICAgPGRpdiBjbGFzc05hbWU9ImZsZXggZmxleC1jb2wgZ2FwLTQiPgogICAgICA8UkJTbGlkZXIKICAgICAgICB2YWx1ZT17W3dpZHRoXX0KICAgICAgICBtaW49ezB9CiAgICAgICAgbWF4PXsxMDB9CiAgICAgICAgb25WYWx1ZUNoYW5nZT17KHZhbHVlczogbnVtYmVyW10pID0+IHNldFdpZHRoKHZhbHVlc1swXSA/PyAwKX0KICAgICAgLz4KICAgICAgPFJCU3dpdGNoIGNoZWNrZWQ9e2VuYWJsZWR9IG9uQ2hlY2tlZENoYW5nZT17c2V0RW5hYmxlZH0gLz4KICAgICAgPFJCTGFiZWxCdXR0b24KICAgICAgICBkaXNhYmxlZD17IWVuYWJsZWR9CiAgICAgICAgb25DbGljaz17KCkgPT4gcmIuYWN0aW9uKCJncmlwIiwgeyB3aWR0aCB9KX0KICAgICAgPgogICAgICAgIEdyaXAKICAgICAgPC9SQkxhYmVsQnV0dG9uPgogICAgPC9kaXY+CiAgKTsKfQpgYGAKCi0tLQoKIyMgRGV2ZWxvcGluZyBkaXJlY3RseSBvbiB0aGUgcm9ib3QgUEMKCklmIHlvdSdyZSBydW5uaW5nIGBtdXNjYXQtcGsgZGV2YCAqKm9uIHRoZSByb2JvdCBQQyBpdHNlbGYqKiwgTXVzY2F0IGFscmVhZHkgc2VydmVzIHRoZQpwbHVnaW4gZ2F0ZXdheSBvbiBwb3J0IDEwMDAwLiBUaGUgQ0xJIHNlZXMgdGhhdCwgZG9lcyBub3Qgc3RhcnQgaXRzIG93biBsb2NhbCBNdXNjYXQsIGFuZAp5b3VyIHBsdWdpbiBiYWNrZW5kIGNvbm5lY3RzIHRvIHRoZSByb2JvdCdzIGdhdGV3YXkg4oCUIGV4YWN0bHkgd2hhdCB5b3Ugd2FudCB3aGVuCmRldmVsb3Bpbmcgb24gdGhlIHJvYm90LgoKLS0tCgojIyBCYWNrZW5kIHJ1bnRpbWVzCgpgbWFuaWZlc3QuanNvbmAgY2hvb3NlcyBvbmUgYmFja2VuZCBydW50aW1lLiBgbXVzY2F0LXBrIGRldmAgcnVucyBiYWNrZW5kIGNvZGUgaW4KYSBEb2NrZXIgY29udGFpbmVyIG1hdGNoaW5nIHRoZSByb2JvdCBlbnZpcm9ubWVudC4gQmFja2VuZCBjb2RlIHNob3VsZCBjb250YWluCnBsdWdpbiBsb2dpYyBvbmx5OyBpdCBzaG91bGQgbm90IHN0YXJ0IGl0cyBvd24gY29weSBvZiB0aGUgcGx1Z2luIGdhdGV3YXkuCgojIyMgV2hpY2ggYmFja2VuZCBwYXR0ZXJuPyAoZGVwZW5kcyBvbiB0aGUgY29udHJpYnV0aW9uIHBvaW50KQoKKipIb3cgeW91IGNvbnRyb2wgdGhlIHJvYm90IGRlcGVuZHMgb24gd2hhdCB5b3VyIHBsdWdpbiBjb250cmlidXRlcyoqIChzZWUKYG1hbmlmZXN0Lmpzb25gIOKGkiBgY29udHJpYnV0ZXNbXS5wb2ludGApLiBEb24ndCBtaXggdGhlc2UgdXA6Cgp8IENvbnRyaWJ1dGlvbiBwb2ludCB8IFdoYXQgaXQgaXMgfCBCYWNrZW5kIHBhdHRlcm4gfAp8IC0tLSB8IC0tLSB8IC0tLSB8CnwgYHByb2dyYW0ucGFuZWxgICh3aXRoIGBjb21tYW5kSW5mb2ApIHwgRGVmaW5lcyBhICoqY3VzdG9tIGNvbW1hbmQqKiB0aGUgcGx1Z2luIGFkZHMgdG8gdGhlIFByb2dyYW0gcGFnZSdzIHJ1bGUtYmFzZWQgc2VxdWVuY2UgYnVpbGRlci4gVGhlIG9wZXJhdG9yIHBsYWNlcyBpdCBpbnRvIHRoZSBwcm9ncmFtIHRyZWUgbGlrZSBhbnkgYnVpbHQtaW4gY29tbWFuZCAoTW92ZSBKLCBQb2ludCwgV2FpdCwg4oCmKTsgaXQgcnVucyB3aGVuIHRoZSBwcm9ncmFtIHJlYWNoZXMgdGhhdCBzdGVwLiB8ICoqYFBsdWdpblByb2dyYW1Db250ZXh0YCoqIOKAlCBpbnRlZ3JhdGVkIHdpdGggdGhlIHByb2dyYW0ncyBzdG9wL3BhdXNlIGFuZCB2YXJpYWJsZXMuIFNlZSBfUHJvZ3JhbSBjb21tYW5kIGJhY2tlbmRfIGJlbG93LiB8CnwgYHRvb2xiYXJgIC8gYGxuYmAgLyBgbW92ZS5wYW5lbGAgfCBBIGxpdmUgVUkgcGFuZWwvcG9wb3ZlciB0aGUgb3BlcmF0b3IgaW50ZXJhY3RzIHdpdGggZGlyZWN0bHkgfCBDYWxsIHRoZSByb2JvdCAqKlNESyBkaXJlY3RseSoqIChgUkJNYW5pcHVsYXRlU0RLYCkgZnJvbSBgY3BwL21haW4uY3BwYCwgb3IgYHJiLmFjdGlvbiguLi4pYCDihpIgeW91ciBiYWNrZW5kIOKGkiBTREsuICoqTm90KiogYSBwcm9ncmFtIHN0ZXAg4oCUIHRoZXJlIGlzIG5vIHN0b3AvcGF1c2UvdmFyaWFibGUgY29udGV4dC4gfAoKUnVsZSBvZiB0aHVtYjogdXNlIGBQbHVnaW5Qcm9ncmFtQ29udGV4dGAgKipvbmx5KiogZm9yIGEgYHByb2dyYW0ucGFuZWxgIGNvbW1hbmQKdGhhdCBydW5zIGFzIHBhcnQgb2YgYSBwcm9ncmFtLiBUbyBtb3ZlIHRoZSByb2JvdCBsaXZlIGZyb20gYSB0b29sYmFyL21vdmUgcGFuZWwsCnVzZSB0aGUgU0RLIOKAlCBhIHByb2dyYW0tc3RlcCBjb250ZXh0IGRvZXMgbm90IGFwcGx5LgoKIyMjIEZyb250ZW5kLW9ubHkgKGBub25lYCkKClVzZSB0aGlzIHdoZW4gdGhlIHBsdWdpbiBvbmx5IGhhcyBVSSBhbmQgY2FsbHMgaG9zdCBzZXJ2aWNlczoKCmBgYGpzb24KeyAicnVudGltZSI6IHsgInR5cGUiOiAibm9uZSIgfSB9CmBgYAoKIyMjIEMrKyAoYGNwcGApCgpDKysgcGx1Z2lucyBidWlsZCBgY3BwL2Agd2l0aCBDTWFrZSBhbmQgcnVuIHRoZSBleGVjdXRhYmxlIG5hbWVkIGJ5CmBtYW5pZmVzdC5qc29uYCDihpIgYHJ1bnRpbWUuZW50cnlgLiBUaGUgUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLCihgcmFpbmJvdy1yYi1zZGstZGV2YCkgaXMgcHJlLWluc3RhbGxlZCBpbiB0aGUgYG11c2NhdC1wa2AgZGV2IGNvbnRhaW5lciDigJQgeW91CmRvbid0IGluc3RhbGwgYW55dGhpbmcgbG9jYWxseS4KCmBgYGpzb24KeyAicnVudGltZSI6IHsgInR5cGUiOiAiY3BwIiwgImVudHJ5IjogIl9fUExVR0lOX1NMVUdfXyIgfSB9CmBgYAoKYGBgY21ha2UKIyBjcHAvQ01ha2VMaXN0cy50eHQg4oCUIHRoZSB2ZXJzaW9uIGlzIHRoZSBTREsgdGhlIGRldiBjb250YWluZXIgaW5zdGFsbHMgKG11c2NhdC1wayBzZGsgdXBkYXRlIDx2ZXJzaW9uPikKZmluZF9wYWNrYWdlKHJiX3NkayAwLjEwLjIgRVhBQ1QgUkVRVUlSRUQpCmFkZF9leGVjdXRhYmxlKF9fUExVR0lOX1NMVUdfXyBtYWluLmNwcCkgICAgICAgICAgICMgbmFtZSBtdXN0IGVxdWFsIHJ1bnRpbWUuZW50cnkKdGFyZ2V0X2xpbmtfbGlicmFyaWVzKF9fUExVR0lOX1NMVUdfXyBQUklWQVRFIHJiX3Nkazo6cmJfc2RrKQpgYGAKCkVkaXRvciBzdXBwb3J0OiB0aGUgU0RLIGlzIGluc3RhbGxlZCBvbmx5IGluc2lkZSB0aGUgZGV2IGNvbnRhaW5lciwgc28gYG11c2NhdC1wayBuZXdgIChhbmQgbGF0ZXIKYGRldmAgLyBgYnVpbGRgIC8gYHR5cGUgY2hhbmdlYCkgY29waWVzIGl0cyBoZWFkZXJzIHRvIGAubXVzY2F0LWRldi9zeXNyb290YCBhbmQgd3JpdGVzIGEgYE11c2NhdGAKY29uZmlndXJhdGlvbiB0byBgLnZzY29kZS9jX2NwcF9wcm9wZXJ0aWVzLmpzb25gLiBWUyBDb2RlJ3MgQy9DKysgZXh0ZW5zaW9uIHRoZW4gcmVzb2x2ZXMgYHJiX3Nka2AKbmFtZXMuIFRoZSBjb3BpZXMgZm9sbG93IHRoZSBTREsgdmVyc2lvbiBhYm92ZTsgdGhlIGJ1aWxkIGl0c2VsZiBuZXZlciB1c2VzIHRoZW0uIFJPUyAyIGhlYWRlcnMKKGByY2xjcHBgKSBhcmUgbm90IGNvcGllZC4KCkhlYWRlcnMgbGl2ZSB1bmRlciBgPHJhaW5ib3cvcmJfc2RrLy4uLj5gOgoKfCBIZWFkZXIgfCBDbGFzcyB8IFVzZSB8CnwgLS0tIHwgLS0tIHwgLS0tIHwKfCBgcGx1Z2luL3JiX3BsdWdpbi5ocHBgIHwgYHJiX3BsdWdpbjo6UkJQbHVnaW5DYWxsYCB8IHBsdWdpbiBVSSDihpQgYmFja2VuZCwgZXh0ZXJuYWwgZW5kcG9pbnRzIChgcm91dGVyKClgKSB8CnwgYG1hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwYCB8IGBSQk1hbmlwdWxhdGVTREtgIHwgY29udHJvbCBhIG1hbmlwdWxhdG9yIHwKfCBgcHJvZ3JhbS9yYl9wcm9ncmFtX3Nkay5ocHBgIHwgYFJCUHJvZ3JhbVNES2AgfCBwcm9ncmFtLXNpZGUgaGVscGVycyB8CnwgYHByb2dyYW0vcGx1Z2luX3Byb2dyYW1fY29udGV4dC5ocHBgIHwgYHJiX3BsdWdpbjo6UGx1Z2luUHJvZ3JhbUNvbnRleHRgIHwgYHByb2dyYW0ucGFuZWxgIGNvbW1hbmRzIHwKfCBgemVub2hfY2xpZW50LmhwcGAgfCBgWmVub2hDbGllbnRgIHwgbG93LWxldmVsIHB1Yi9zdWIvcXVlcnkgfAoKUGF5bG9hZHMgYXJlIGBubG9obWFubjo6anNvbmAgKGAjaW5jbHVkZSA8bmxvaG1hbm4vanNvbi5ocHA+YCwgaW5zdGFsbGVkIHdpdGggdGhlIFNESykuCgojIyMjIFRhbGtpbmcgdG8gdGhlIHBsdWdpbiBVSSAoYFJCUGx1Z2luQ2FsbGApCgpgYGBjcHAKI2luY2x1ZGUgPHJhaW5ib3cvcmJfc2RrL3BsdWdpbi9yYl9wbHVnaW4uaHBwPgojaW5jbHVkZSA8bmxvaG1hbm4vanNvbi5ocHA+Cgp1c2luZyBubG9obWFubjo6anNvbjsKdXNpbmcgcmJfcGx1Z2luOjpSQlBsdWdpbkNhbGw7CgppbnQgbWFpbigpIHsKICAvLyBwbHVnaW4gaWQgY29tZXMgZnJvbSBlbnYgUkJfUExVR0lOX0lEIChzZXQgYnkgbXVzY2F0LXBrIGRldiBhbmQgYnkgdGhlIHJvYm90KQogIGF1dG8gcGx1Z2luID0gUkJQbHVnaW5DYWxsOjpnZXRfaW5zdGFuY2UoUkJQbHVnaW5DYWxsOjpyZXNvbHZlX3BsdWdpbl9pZChzdGQ6Om51bGxvcHQpKTsKCiAgcGx1Z2luLT5wdWJsaXNoKCJzdGF0ZSIsIHt7InJlYWR5IiwgdHJ1ZX19KTsgICAgICAgICAgICAgICAgIC8vIFVJOiByYi5zdWIoInN0YXRlIiwgLi4uKQoKICBhdXRvIHN1YiA9IHBsdWdpbi0+c3Vic2NyaWJlKCJldmVudCIsICAgICAgICAgICAgICAgICAgICAgICAgLy8gVUk6IHJiLnB1YigiZXZlbnQiLCAuLi4pCiAgICAgIFtdKGNvbnN0IHN0ZDo6c3RyaW5nJiB0b3BpYywgY29uc3QganNvbiYgcGF5bG9hZCkgeyAvKiAuLi4gKi8gfSk7CgogIHBsdWdpbi0+c2VydmUoInRvb2wvZWNobyIsIFtdKGNvbnN0IGpzb24mIHBheWxvYWQpIHsgICAgICAgICAvLyBVSTogYXdhaXQgcmIuYWN0aW9uKCJ0b29sL2VjaG8iLCAuLi4pCiAgICByZXR1cm4ganNvbnt7ImVjaG8iLCBwYXlsb2FkfX07CiAgfSk7CgogIGpzb24gcmVzID0gcGx1Z2luLT5jYWxsKCJ0b29sL3BpbmciLCB7eyJoZWxsbyIsICJwbHVnaW4ifX0sIDUuMCk7ICAvLyBVSSBhbnN3ZXJzIHdpdGggcmIuc2VydmUoInRvb2wvcGluZyIsIC4uLikKCiAgZm9yICg7Oykgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjpzZWNvbmRzKDEpKTsgICAgLy8gc3RheSByZXNpZGVudAp9CmBgYAoKfCBDKysgfCBVSSAoYHVzZVJiKClgKSB8CnwgLS0tIHwgLS0tIHwKfCBgcGx1Z2luLT5zZXJ2ZSh0b3BpYywgZm4pYCB8IGBhd2FpdCByYi5hY3Rpb24odG9waWMsIHBheWxvYWQpYCB8CnwgYHBsdWdpbi0+c3Vic2NyaWJlKHRvcGljLCBmbilgIHwgYHJiLnB1Yih0b3BpYywgcGF5bG9hZClgIHwKfCBgcGx1Z2luLT5wdWJsaXNoKHRvcGljLCBwYXlsb2FkKWAgfCBgcmIuc3ViKHRvcGljLCBoYW5kbGVyKWAgfAp8IGBwbHVnaW4tPmNhbGwodG9waWMsIHBheWxvYWQsIHRpbWVvdXRfc2VjKWAgfCBgcmIuc2VydmUodG9waWMsIGhhbmRsZXIpYCB8CgotIEtlZXAgdGhlIGBTdWJzY3JpcHRpb25gIHJldHVybmVkIGJ5IGBzdWJzY3JpYmVgOyBwYXNzIGl0IHRvIGBwbHVnaW4tPnVuc3Vic2NyaWJlKHN0ZDo6bnVsbG9wdCwgc3ViKWAgdG8gcmVtb3ZlIGp1c3QgdGhhdCBvbmUuCi0gYGNhbGxgIHRocm93cyBgcmJfcGx1Z2luOjpSQlBsdWdpbkdhdGV3YXlFcnJvcmAgd2hlbiB0aGUgZ2F0ZXdheSBpcyBkb3duIG9yIHRoZSBVSSBkb2Vzbid0IGFuc3dlciBpbiB0aW1lLgoKIyMjIyBFeHRlcm5hbCBlbmRwb2ludHMgKGByb3V0ZXIoKWApCgpgc2VydmVgIC8gYHN1YnNjcmliZWAgLyBgcHVibGlzaGAgYXJlICoqaW50ZXJuYWwgb25seSoqIChwbHVnaW4gVUkg4oaUIGJhY2tlbmQpLgpUbyBleHBvc2UgYW4gZW5kcG9pbnQgdG8gdGhlIG91dHNpZGUgd29ybGQg4oCUIFJFU1QsIFNvY2tldC5JTywgVENQLCBNUVRULApXZWJSVEMg4oCUIHVzZSBgcGx1Z2luLT5yb3V0ZXIoKWAuIFRoZSBydW5uaW5nIE11c2NhdCAoYGNvbW1vbmApIHBpY2tzIGl0IHVwCndpdGhvdXQgYSByZXN0YXJ0LCBhbmQgaXQgZGlzYXBwZWFycyB3aGVuIHRoZSBwbHVnaW4gc3RvcHMuCgpgYGBjcHAKYXV0byYgcm91dGVyID0gcGx1Z2luLT5yb3V0ZXIoKTsKCnJvdXRlci5vbigiL2hlbGxvIiwgW10oY29uc3QganNvbiYgcGF5bG9hZCwgY29uc3QganNvbiYgbWV0YSkgeyAgICAgICAvLyBhbGwgNSB0cmFuc3BvcnRzCiAgcmV0dXJuIGpzb257eyJtc2ciLCAiaGkgIiArIHBheWxvYWQudmFsdWUoIm5hbWUiLCBzdGQ6OnN0cmluZygidGhlcmUiKSl9fTsKfSk7Cgpyb3V0ZXIub24oIi9hZG1pbiIsIFtdKGNvbnN0IGpzb24mIHBheWxvYWQsIGNvbnN0IGpzb24mIG1ldGEpIHsKICBpZiAoIW1ldGEudmFsdWUoInByaW5jaXBhbCIsIGpzb246Om9iamVjdCgpKS52YWx1ZSgiaXNfYWRtaW4iLCBmYWxzZSkpCiAgICB0aHJvdyByYl9wbHVnaW46OlBsdWdpblJvdXRlRXJyb3IoNDAzLCAiYWRtaW4gb25seSIpOyAgICAgICAgICAgICAgLy8gYmVjb21lcyB0aGUgZXh0ZXJuYWwgc3RhdHVzCiAgcmV0dXJuIGpzb246Om9iamVjdCgpOwp9LCBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz57ImFwaSJ9KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUkVTVCBvbmx5Cgpyb3V0ZXIuc3Vic2NyaWJlKCIvY21kIiwgW10oY29uc3QganNvbiYgcGF5bG9hZCkgeyAvKiAuLi4gKi8gfSwKICAgICAgICAgICAgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz57InRjcCJ9KTsgICAgICAgICAgICAgICAgICAgIC8vIHJlY2VpdmUgZXh0ZXJuYWwgVENQIHB1Ymxpc2gKCnJvdXRlci5lbWl0KCIvc3RhdGUiLCB7eyJidXN5IiwgdHJ1ZX19KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHVzaCB0byBleHRlcm5hbCBzdWJzY3JpYmVycwpgYGAKCmBgYGJhc2gKY3VybCAtcyAtWCBQT1NUIGh0dHA6Ly88cm9ib3Q+L2NvbW1vbi9wbHVnaW4vPHBsdWdpbl9pZD4vaGVsbG8gXAogIC1IICdDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL2pzb24nIC1kICd7Im5hbWUiOiJraW0ifScKIyDihpIgeyJtc2ciOiJoaSBraW0ifQpgYGAKCnwgQVBJIHwgTWVhbmluZyB8IEV4dGVybmFsIGFkZHJlc3MgfAp8IC0tLSB8IC0tLSB8IC0tLSB8CnwgYHJvdXRlci5vbihwYXRoLCBoYW5kbGVyLCBleHBsaWNpdF9yb3V0ZXMpYCB8IHJlcXVlc3QvcmVzcG9uc2UgaGFuZGxlciB8IGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3twYXRofWAgKFJFU1QgaXMgYWx3YXlzIGBQT1NUYCkgfAp8IGByb3V0ZXIuc3Vic2NyaWJlKHRvcGljLCBoYW5kbGVyLCBleHBsaWNpdF9ldmVudHMpYCB8IHJlY2VpdmUgZXh0ZXJuYWwgcHVibGlzaGVzIHwgZXh0ZXJuYWwgc2lkZSBwdWJsaXNoZXMgdG8gYGNvbW1vbi9wbHVnaW4ve3BsdWdpbl9pZH0ve3RvcGljfWAgfAp8IGByb3V0ZXIuZW1pdCh0b3BpYywgcGF5bG9hZClgIHwgcGx1Z2luIOKGkiBleHRlcm5hbCBwdXNoIHwgZXh0ZXJuYWwgc2lkZSBzdWJzY3JpYmVzIHRvIGBjb21tb24vcGx1Z2luL3twbHVnaW5faWR9L3t0b3BpY31gIHwKCi0gYG1ldGFgID0gYHsidHJhbnNwb3J0IjogImFwaSJ8InNvY2tldCJ8InRjcCJ8Im1xdHQifCJ3ZWJydGMiLCAicHJpbmNpcGFsIjogb2JqZWN0IHwgbnVsbH1gLiAqKlJvbGUgY2hlY2tzIGFyZSB0aGUgcGx1Z2luJ3Mgam9iLioqCi0gVHJhbnNwb3J0IG5hbWVzOiBgYXBpIHwgc29ja2V0IHwgdGNwIHwgbXF0dCB8IHdlYnJ0Y2A7IGBzdWJzY3JpYmVgIGFjY2VwdHMgb25seSBgdGNwIHwgbXF0dCB8IHdlYnJ0Y2AuIFVua25vd24gbmFtZXMgb3IgZHVwbGljYXRlIHBhdGhzIHRocm93IGBzdGQ6OmludmFsaWRfYXJndW1lbnRgLgotIFRocm93IGByYl9wbHVnaW46OlBsdWdpblJvdXRlRXJyb3IoY29kZSwgbWVzc2FnZSlgIHRvIHNldCB0aGUgc3RhdHVzOyBhbnkgb3RoZXIgZXhjZXB0aW9uIOKGkiA1MDAuCgp8IFNpdHVhdGlvbiB8IFN0YXR1cyB8CnwgLS0tIHwgLS0tIHwKfCBObyBwbHVnaW4gZGVjbGFyZXMgdGhhdCBwYXRoIC8gcGx1Z2luIGlzIGRvd24gLyB0cmFuc3BvcnQgbm90IGFsbG93ZWQgfCA0MDQgfAp8IFBsdWdpbiBkaWQgbm90IGFuc3dlciB3aXRoaW4gMTAgcyB8IDUwNCB8CnwgYGNvbW1vbmAg4oaUIGdhdGV3YXkgbm90IGNvbm5lY3RlZCB8IDUwMyB8CgpEdXJpbmcgYG11c2NhdC1wayBkZXZgIHRoZSBsb2NhbCBNdXNjYXQgcnVudGltZSB0YWtlcyBgcm91dGVyKClgIHJlZ2lzdHJhdGlvbnMgb24gaXRzCmdhdGV3YXkgYW5kIGl0cyBgY29tbW9uYCByb3V0ZXMgZXh0ZXJuYWwgY2FsbHMgdG8gdGhlbSBsaWtlIG9uIHRoZSByb2JvdAooYGN1cmwgaHR0cDovL2xvY2FsaG9zdDozMDAwL2NvbW1vbi9wbHVnaW4vPHBsdWdpbi1pZD4vPHBhdGg+YCkuIEFmdGVyCnJlc3RhcnRpbmcgdGhlIHBsdWdpbiwgZXh0ZXJuYWwgY2FsbHMgbWF5IHJldHVybiA1MDQgZm9yIGFib3V0IGEgbWludXRlLCB0aGVuIDQwNC4KCiMjIyMgUHJvZ3JhbSBjb21tYW5kIGJhY2tlbmQgKGBwcm9ncmFtLnBhbmVsYCkKCkEgYHByb2dyYW0ucGFuZWxgIGNvbnRyaWJ1dGlvbiBhZGRzIGEgKipjdXN0b20gY29tbWFuZCoqIHRvIHRoZSBQcm9ncmFtIHBhZ2UuCkVhY2ggdGltZSB0aGUgcHJvZ3JhbSByZWFjaGVzIHRoYXQgc3RlcCwgdGhlIGhvc3QgY2FsbHMgeW91ciBiYWNrZW5kIHRocm91Z2gKYFBsdWdpblByb2dyYW1Db250ZXh0YCB3aXRoIHRoZSBzdGVwIGFyZ3MgKHdoYXQgdGhlIFVJIHNhdmVkIHdpdGggYHVzZVJiU2F2ZWApLgoKYGBgY3BwCiNpbmNsdWRlIDxyYWluYm93L3JiX3Nkay9wcm9ncmFtL3BsdWdpbl9wcm9ncmFtX2NvbnRleHQuaHBwPgoKdXNpbmcgcmJfcGx1Z2luOjpQbHVnaW5Qcm9ncmFtQ29udGV4dDsKCmludCBtYWluKCkgewogIFBsdWdpblByb2dyYW1Db250ZXh0IGN0eCgiX19QTFVHSU5fSURfXyIpOwoKICBjdHguc2V0X2V4ZWN1dGVfaGFuZGxlcihbJl0oY29uc3QgbmxvaG1hbm46Ompzb24mIGFyZ3MpIHsKICAgIGF1dG8gY291bnQgPSBjdHguZ2V0X3ZhcmlhYmxlKCJjb3VudGVyIik7ICAgICAgICAgICAgICAgICAgLy8ganNvbjsgbnVsbCBpZiBubyBwcm9ncmFtIHJ1bnMKICAgIGN0eC5zZXRfdmFyaWFibGUoImNvdW50ZXIiLCBjb3VudC5pc19udW1iZXIoKSA/IGNvdW50LmdldDxpbnQ+KCkgKyAxIDogMSk7CiAgICBjdHguc2V0X3ZhcmlhYmxlKCJSQlBfX19QTFVHSU5fU0xVR19fX3Jlc3VsdCIsIDQyKTsgICAgICAgIC8vIE5FVyB2YXJpYWJsZXMgbXVzdCBzdGFydCB3aXRoIFJCUF8KCiAgICB0cnkgewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwMDsgKytpKSB7CiAgICAgICAgY3R4LmNoZWNrX3N0b3AoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBhdXNlIOKGkiBibG9ja3MsIHN0b3Ag4oaSIHRocm93cyBQbHVnaW5TdG9wcGVkCiAgICAgICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHMoNTAwKSk7CiAgICAgIH0KICAgIH0gY2F0Y2ggKGNvbnN0IHJiX3BsdWdpbjo6UGx1Z2luU3RvcHBlZCYpIHsKICAgICAgcmV0dXJuOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvZ3JhbSB3YXMgc3RvcHBlZAogICAgfQogICAgY3R4LmRvbmUoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbHdheXMgY2FsbCDigJQgdGhlIHN0ZXAgZW5kcyBoZXJlCiAgfSk7CgogIGN0eC5zdGFydCgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkb2VzIG5vdCBibG9jawogIGZvciAoOzspIHN0ZDo6dGhpc190aHJlYWQ6OnNsZWVwX2ZvcihzdGQ6OmNocm9ubzo6c2Vjb25kcygxKSk7Cn0KYGBgCgotIFRoZSBzdGVwIGRvZXMgbm90IGZpbmlzaCB1bnRpbCB5b3UgY2FsbCBgY3R4LmRvbmUoKWAuCi0gYHNldF9leGVjdXRlX2hhbmRsZXJgIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBgc3RhcnQoKWAuCi0gKipOZXcqKiB2YXJpYWJsZXMgbmVlZCB0aGUgYFJCUF9gIHByZWZpeCAoYFJCUF97cGx1Z2luX2lkfV97bmFtZX1gIHJlY29tbWVuZGVkKTsgZXhpc3Rpbmcgb25lcyBwYXNzIGFzLWlzLgotIGBnZXRfdmFyaWFibGUobmFtZSwgcm9ib3RfbW9kZWwsIHBsdWdpbl9pZClgIOKAlCBvcHRpb25hbCBmaWx0ZXJzOiBhIHNwZWNpZmljIHJvYm90LCBvciB0aGUgdmFsdWUgYSBnaXZlbiBwbHVnaW4gbGFzdCB3cm90ZS4KLSBFeGVjdXRvciBzdGF0ZTogYGN0eC5leGVjdXRvcl9zdGF0ZV9mb3IoIkM1MDA5MjAiKWAsIGBjdHguZXhlY3V0b3Jfc3RhdGVzKClgLCBgY3R4LmlzX3BhdXNlZCgpYCwgYGN0eC5pc19zdG9wcGVkKClgLAogIG9yIGBjdHguc2V0X3N0YXRlX2NoYW5nZV9oYW5kbGVyKFtdKGNvbnN0IHN0ZDo6c3RyaW5nJiBtb2RlbCwgY29uc3Qgc3RkOjpzdHJpbmcmIHN0YXRlKSB7IC4uLiB9KWAuCi0gQSBsb25nLXJ1bm5pbmcgaGFuZGxlciBtdXN0IGNhbGwgYGNoZWNrX3N0b3AoKWAgZXZlcnkgaXRlcmF0aW9uLCBvciBpdCBrZWVwcyBydW5uaW5nIGFmdGVyIHRoZSBvcGVyYXRvciBwcmVzc2VzIFN0b3AuCgpWYXJpYWJsZXMgdGhlIFByb2dyYW0gcGFnZSB2YXJpYWJsZSBwaWNrZXIgc2hvdWxkIG9mZmVyIG11c3QgYmUgZGVjbGFyZWQgaW4KYG1hbmlmZXN0Lmpzb25gIHVuZGVyIGAidmFyaWFibGVzImAuCgojIyMjIENvbnRyb2xsaW5nIHRoZSByb2JvdAoKYGBgY3BwCiNpbmNsdWRlIDxyYWluYm93L3JiX3Nkay9tYW5pcHVsYXRlL3JiX21hbmlwdWxhdGVfc2RrLmhwcD4KClJCTWFuaXB1bGF0ZVNESyBtYW5pcHVsYXRlOyAgICAgICAgICAgICAgICAgICAgICAgLy8gb24gdGhlIHJvYm90OiBjb25uZWN0cyB0byB0aGUgbG9jYWwgWmVub2gKbWFuaXB1bGF0ZS5zdGF0ZS5jYWxsX3NlcnZvY29udHJvbCgiQzUwMDkyMCIsIDEpOwoKSVBDOjpNb3ZlSW5wdXRfVGFyZ2V0VCB0Owp0LnRhcl92YWx1ZXMgPSB7MCwgMCwgOTAsIDAsIDkwLCAwfTsKdC50YXJfZnJhbWUgPSAwOwp0LnRhcl91bml0ID0gMTsKbWFuaXB1bGF0ZS5tb3ZlLmNhbGxfbW92ZV9qKCJDNTAwOTIwIiwgdCwgc3RkOjpudWxsb3B0LCBNb3ZlU3BlZWRBcmd7MSwgNjAuZiwgMTIwLmZ9KTsKbWFuaXB1bGF0ZS5tb3ZlLmNhbGxfbW92ZV93YWl0KCJDNTAwOTIwIiwgLTEpOwpgYGAKClJlbW90ZSBkZXYgKGBtdXNjYXQtcGsgZGV2IC0tcm9ib3QtaXAgPGlwPiAtLXJvYm90LXRva2VuIDx0b2tlbj5gKSBzZXRzCmBNVVNDQVRfUk9CT1RfSE9TVGAgLyBgTVVTQ0FUX1JPQk9UX1RPS0VOYDsgY29ubmVjdCAqKmJlZm9yZSoqIHJlZ2lzdGVyaW5nCnN1YnNjcmlwdGlvbnMsIGJlY2F1c2UgYGNvbm5lY3QoKWAgcmVvcGVucyB0aGUgWmVub2ggc2Vzc2lvbjoKCmBgYGNwcAppZiAoY29uc3QgY2hhciogaG9zdCA9IHN0ZDo6Z2V0ZW52KCJNVVNDQVRfUk9CT1RfSE9TVCIpKQogIGlmIChjb25zdCBjaGFyKiB0b2tlbiA9IHN0ZDo6Z2V0ZW52KCJNVVNDQVRfUk9CT1RfVE9LRU4iKSkKICAgIG1hbmlwdWxhdGUuY29ubmVjdCh7LnRva2VuID0gdG9rZW4sIC5ob3N0ID0gaG9zdH0pOwpgYGAKCkFNUiBhbmQgUkItWTEgU0RLcyBhcmUgUHl0aG9uLW9ubHkgZm9yIG5vdy4KCiMjIyBST1MyIChyY2xjcHApCgpST1MyIEMrKyBwbHVnaW5zIHVzZSBgcm9zMl93cy9gIHdpdGggYHJ1bnRpbWUucm9zQ2xpZW50OiAicmNsY3BwImAuIFRoZSBub2RlCmxpbmtzIHRoZSBDKysgU0RLIHRoZSBzYW1lIHdheSAoYGZpbmRfcGFja2FnZShyYl9zZGspYCArIGByYl9zZGs6OnJiX3Nka2ApOyByZWxhdGl2ZSB0b3BpYyBuYW1lcyBhcmUgcGxhY2VkIHVuZGVyIHRoZSBwbHVnaW4ncyBST1MgbmFtZXNwYWNlIOKAlCB0aGUgcGx1Z2luIGlkCndpdGggIi4iIOKGkiAiLyIgYW5kICItIiDihpIgIl8iIChgY29tLmV4YW1wbGUubXktcGx1Z2luYCDihpIgYC9jb20vZXhhbXBsZS9teV9wbHVnaW5gKSwgaW4gZGV2CmFuZCBvbiB0aGUgcm9ib3QuIFVzZSBhbiBhYnNvbHV0ZSBuYW1lIChgL2NtZF92ZWxgKSBmb3IgdG9waWNzIHNoYXJlZCB3aXRoIG90aGVyIG5vZGVzLgoKYGBgY3BwCiNpbmNsdWRlICJyY2xjcHAvcmNsY3BwLmhwcCIKI2luY2x1ZGUgPHJhaW5ib3cvcmJfc2RrL21hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwPgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUgOiBwdWJsaWMgcmNsY3BwOjpOb2RlIHsKcHVibGljOgogIF9fUExVR0lOX0NMQVNTX19Ob2RlKCkgOiBOb2RlKCJfX1BMVUdJTl9TTFVHX19fbm9kZSIpIHsKICAgIFJDTENQUF9JTkZPKHRoaXMtPmdldF9sb2dnZXIoKSwgIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKTsKICB9Cn07CgppbnQgbWFpbihpbnQgYXJnYywgY2hhcioqIGFyZ3YpIHsKICByY2xjcHA6OmluaXQoYXJnYywgYXJndik7CiAgcmNsY3BwOjpzcGluKHN0ZDo6bWFrZV9zaGFyZWQ8X19QTFVHSU5fQ0xBU1NfX05vZGU+KCkpOwogIHJjbGNwcDo6c2h1dGRvd24oKTsKICByZXR1cm4gMDsKfQpgYGAKCmBSQlBsdWdpbkNhbGxgIGFuZCBgUGx1Z2luUHJvZ3JhbUNvbnRleHRgIHdvcmsgaW4gYW4gcmNsY3BwIG5vZGUgdG9vIOKAlCBjcmVhdGUKdGhlbSBpbiBgbWFpbigpYCBiZWZvcmUgYHJjbGNwcDo6c3BpbmAuCgoKIyMjIyBUYWxraW5nIHRvIGFuIGV4dGVybmFsIFBDIG92ZXIgUk9TIDIKClJPUyAyIGRpc2NvdmVyeSBzdGF5cyBvbiB0aGUgcm9ib3QgKGBST1NfQVVUT01BVElDX0RJU0NPVkVSWV9SQU5HRT1MT0NBTEhPU1RgOyBgbXVzY2F0LXBrIGRldmAKcnVucyB0aGUgc2FtZSksIHNvIHJvYm90cyBvbiBvbmUgTEFOIGRvbid0IG1peCB0b3BpY3MuIEFsbG93IHNwZWNpZmljIFBDcyBmcm9tIHRoZSBwbHVnaW4gVUkg4oCUCk11c2NhdCBrZWVwcyB0aGUgbGlzdCBwZXIgcGx1Z2luLCBzdGFydHMgeW91ciBiYWNrZW5kIHdpdGggYFJPU19TVEFUSUNfUEVFUlNgIHNldCB0byBpdCwgYW5kCnJlc3RhcnRzIHRoZSBwbHVnaW4gd2hlbiBpdCBjaGFuZ2VzLiBZb3VyIFJPUyBjb2RlIG5lZWRzIG5vIGNoYW5nZXM7IHRoZSBQQyBuZWVkcyBubyBleHRyYSBzZXR0aW5ncy4KCmBgYHRzeApjb25zdCByYiA9IHVzZVJiKCk7CmNvbnN0IHBlZXJzID0gYXdhaXQgcmIucm9zUGVlcnMuZ2V0KCk7ICAgICAgICAgICAgICAgLy8gWyIxOTIuMTY4LjAuNTAiXQphd2FpdCByYi5yb3NQZWVycy5zZXQoWyIxOTIuMTY4LjAuNTAiLCAiMTkyLjE2OC4wLjUxIl0pOyAvLyBzYXZlcyArIHJlc3RhcnRzIHRoZSBwbHVnaW47IHJlamVjdHMgb24gYSBiYWQgSVAKYGBgCgotIFBlciBwbHVnaW46IHBsdWdpbiBCIGtlZXBzIGl0cyBhbGxvd2VkIFBDcyB3aGVuIHBsdWdpbiBBIChhbGxvd2luZyB0aGUgc2FtZSBQQykgaXMgc3RvcHBlZCBvciByZW1vdmVkLgotIEl0IG9wZW5zIGNvbW11bmljYXRpb247IGl0IGlzIG5vdCBhY2Nlc3MgY29udHJvbCDigJQgYSBQQyB0aGF0IGtub3dzIHRoZSByb2JvdCdzIElQIGNhbiBzdGlsbAogIGFkZCB0aGUgcm9ib3QgdG8gaXRzIG93biBgUk9TX1NUQVRJQ19QRUVSU2AuCi0gSW4gYG11c2NhdC1wayBkZXZgIHRoZSBsaXN0IGlzIGtlcHQgaW4gYC5tdXNjYXQtZGV2L3Jvcy1wZWVycy5qc29uYCAoUk9TIDIgYmFja2VuZHMpLgoKLS0tCgojIyBWaWRlbyBzdHJlYW1pbmcgKE1lZGlhTVRYKQoKTXVzY2F0IHJ1bnMgYSBNZWRpYU1UWCBtZWRpYSBzZXJ2ZXIuIFRoZSBiYWNrZW5kIHB1Ymxpc2hlcyBhIHN0cmVhbSBvdmVyIFJUU1AgYW5kCnRoZSBVSSBwbGF5cyBpdCBvdmVyIFdlYlJUQy4gYG11c2NhdC1wayBkZXZgIHJ1bnMgdGhlIHNhbWUgc2VydmVyIChvciB1c2VzIGEgbG9jYWwKTXVzY2F0J3MpLCBzbyB0aGUgYWRkcmVzc2VzIGFyZSBpZGVudGljYWwgaW4gZGV2IGFuZCBvbiB0aGUgcm9ib3QuCgp8IHwgQWRkcmVzcyB8CnwgLS0tIHwgLS0tIHwKfCBQdWJsaXNoIChiYWNrZW5kKSB8IGBydHNwOi8vMTI3LjAuMC4xOjg1NTQvPHBsdWdpbl9pZD4vPG5hbWU+YCB8CnwgUGxheSAoVUkpIHwgYGh0dHA6Ly88aG9zdD46ODg4OS88cGx1Z2luX2lkPi88bmFtZT4vYCB8CgotIFByZWZpeCB0aGUgcGF0aCB3aXRoIHlvdXIgcGx1Z2luIGlkIOKAlCBwYXRocyBhcmUgc2hhcmVkIHdpdGggcm9ib3QgY2FtZXJhcyBhbmQgb3RoZXIgcGx1Z2lucy4KLSBUaGUgcm9ib3QgcnVudGltZSBoYXMgbm8gZmZtcGVnLCBHU3RyZWFtZXIgb3IgT3BlbkNWOyBicmluZyB5b3VyIG93biBlbmNvZGVyIChiZWxvdykuCgoqKkJhY2tlbmQgKEMrKykqKiDigJQgcHVibGlzaCBSVFNQIHdpdGggYW4gZW5jb2RlciBsaWJyYXJ5IHlvdSBicmluZyAoZS5nLiBGRm1wZWcncwpsaWJhdmZvcm1hdCAvIGxpYngyNjQpOyB0aGUgcm9ib3QgaGFzIG5vbmUgaW5zdGFsbGVkLiBTaGlwIGl0IHdpdGggdGhlIHBsdWdpbiDigJQgc2VlCl9CdW5kbGluZyBleHRyYSBzaGFyZWQgbGlicmFyaWVzXy4KCioqVUkqKiDigJQgZW1iZWQgTWVkaWFNVFgncyBXZWJSVEMgcGxheWVyLiBgbG9jYXRpb24uaG9zdG5hbWVgIGlzIGBsb2NhbGhvc3RgIGluIHRoZQpwcmV2aWV3IGFuZCB0aGUgcm9ib3QncyBhZGRyZXNzIG9uIHRoZSByb2JvdDoKCmBgYHRzeApjb25zdCBTVFJFQU0gPSAiX19QTFVHSU5fSURfXy9jYW0iOyAvLyB0aGUgcGF0aCB0aGUgYmFja2VuZCBwdWJsaXNoZXMKCmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENhbWVyYSgpIHsKICByZXR1cm4gKAogICAgPGlmcmFtZQogICAgICBzcmM9e2Ake2xvY2F0aW9uLnByb3RvY29sfS8vJHtsb2NhdGlvbi5ob3N0bmFtZX06ODg4OS8ke1NUUkVBTX0vYH0KICAgICAgYWxsb3c9ImF1dG9wbGF5IgogICAgICBjbGFzc05hbWU9ImFzcGVjdC12aWRlbyB3LWZ1bGwgYm9yZGVyLTAiCiAgICAvPgogICk7Cn0KYGBgCgotLS0KCiMjIG1hbmlmZXN0Lmpzb24KCmBgYGpzb25jCnsKICAvLyB1bmlxdWUgcGx1Z2luIElEIOKAlCByZXZlcnNlLWRvbWFpbiBmb3JtYXQgcmVjb21tZW5kZWQKICAiaWQiOiAiY29tLmV4YW1wbGUubXktcGx1Z2luIiwKICAibmFtZSI6ICJNeSBQbHVnaW4iLAogICJ2ZXJzaW9uIjogIjEuMC4wIiwKCiAgLy8gbWluaW11bSBNdXNjYXQgdmVyc2lvbiByZXF1aXJlZCB0byBsb2FkIHRoaXMgcGx1Z2luCiAgIm1pbk11c2NhdFZlcnNpb24iOiAiMS4wLjAiLAoKICAvLyBwbHVnaW4gYXV0aG9yIChlbXB0eSBzdHJpbmcgaXMgZmluZSkKICAiYXV0aG9yIjogIllvdXIgTmFtZSIsCgogIC8vIGRpc3BsYXllZCBpbiB0aGUgTXVzY2F0IHBsdWdpbiBzdG9yZSAvIGluZm8gcGFuZWwKICAvLyBzdHJpbmcgb3IgeyBlbiAocmVxdWlyZWQpLCBrbywgamEsIHpoLCB2aSwgdGgsIGVzIH0KICAiZGVzY3JpcHRpb24iOiB7ICJlbiI6ICJQbHVnaW4gZGVzY3JpcHRpb24iLCAia28iOiAi7ZSM65+s6re47J24IOyEpOuqhSIgfSwKCiAgLy8gU1ZHIHN0cmluZyAoc2luZ2xlIGZpbGUpIG9yIFBORy9KUEcgc2l6ZSBtYXAgKGFsbCB0aHJlZSBzaXplcyByZXF1aXJlZCkKICAiaWNvbnMiOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAvLyAiaWNvbnMiOiB7ICIxNiI6ICJhc3NldHMvaWNvbi0xNi5wbmciLCAiNDgiOiAiYXNzZXRzL2ljb24tNDgucG5nIiwgIjEyOCI6ICJhc3NldHMvaWNvbi0xMjgucG5nIiB9LAoKICAvLyB0YXJnZXRNb2RlbHMgYW5kL29yIHRhcmdldENhdGVnb3J5cyDigJQgYXQgbGVhc3Qgb25lIGlzIHJlcXVpcmVkCiAgLy8gImFsbCIgPSBldmVyeSB0YXJnZXQsIG9yIGxpc3Qgc3BlY2lmaWMgdmFsdWVzCiAgInRhcmdldE1vZGVscyI6ICJhbGwiLAogIC8vICJ0YXJnZXRNb2RlbHMiOiBbIkM1MDA5MjAiLCAiQzUwMDkzMCJdLAogICJ0YXJnZXRDYXRlZ29yeXMiOiAiYWxsIiwKICAvLyAidGFyZ2V0Q2F0ZWdvcnlzIjogWyJtYW5pcHVsYXRlIiwgImFtciIsICJyYnkxIiwgInZpc2lvbiJdLAoKICAiY29udHJpYnV0ZXMiOiBbCiAgICAvLyBwcm9ncmFtLnBhbmVsIOKAlCBkZWZpbmVzIGEgY3VzdG9tIGNvbW1hbmQgZm9yIHRoZSBQcm9ncmFtIHBhZ2Ugc2VxdWVuY2UKICAgIC8vICAgYnVpbGRlcjsgcnVucyB2aWEgUGx1Z2luUHJvZ3JhbUNvbnRleHQgd2hlbiB0aGUgcHJvZ3JhbSByZWFjaGVzIGl0CiAgICB7CiAgICAgICJwb2ludCI6ICJwcm9ncmFtLnBhbmVsIiwKICAgICAgImljb24iOiAiYXNzZXRzL2ljb24uc3ZnIiwKICAgICAgImxhYmVsIjogeyAia28iOiAi64K0IO2UjOufrOq3uOyduCIsICJlbiI6ICJNeSBQbHVnaW4iIH0sCiAgICAgICJ1aSI6ICJwcm9ncmFtIiwgICAgICAgICAgIC8vIG11c3QgYmUgdW5pcXVlIGFjcm9zcyBhbGwgY29udHJpYnV0aW9ucwogICAgICAiY29tbWFuZEluZm8iOiB7CiAgICAgICAgIm5hbWUiOiAiTXkgUGx1Z2luIiwKICAgICAgICAiaWNvbiI6ICJhc3NldHMvaWNvbi5zdmciLAogICAgICAgICJmdW5jTmFtZSI6ICJyYl9wcm9ncmFtX3Nkay5wbHVnaW5fZXhlY3V0ZSIsCiAgICAgICAgImFyZ3MiOiB7fQogICAgICB9CiAgICB9LAogICAgLy8gdG9vbGJhciDigJQgYWRkcyBhIGJ1dHRvbiB0byB0aGUgdG9wIHRvb2xiYXIgKHJlcXVpcmVkKQogICAgewogICAgICAicG9pbnQiOiAidG9vbGJhciIsCiAgICAgICJpY29uIjogImFzc2V0cy9pY29uLnN2ZyIsCiAgICAgICJsYWJlbCI6IHsgImtvIjogIuuCtCDtlIzrn6zqt7jsnbgiLCAiZW4iOiAiTXkgUGx1Z2luIiB9LAogICAgICAidWkiOiAiY29udGVudCIsICAgICAgICAgICAvLyBtdXN0IGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGNvbnRyaWJ1dGlvbnMKICAgICAgIm9wZW5zIjogInBvcG92ZXIiICAgICAgICAgLy8gcG9wb3ZlciB8IHBhbmVsIHwgcGFnZQogICAgfSwKICAgIC8vIG1vdmUucGFuZWwg4oCUIGFkZHMgYSBwYW5lbCB0byB0aGUgTW92ZSBzY3JlZW4KICAgIHsKICAgICAgInBvaW50IjogIm1vdmUucGFuZWwiLAogICAgICAiaWNvbiI6ICJhc3NldHMvaWNvbi5zdmciLAogICAgICAibGFiZWwiOiB7ICJrbyI6ICLrgrQg7ZSM65+s6re47J24IiwgImVuIjogIk15IFBsdWdpbiIgfSwKICAgICAgInVpIjogIm1vdmUiICAgICAgICAgICAgICAgLy8gbXVzdCBiZSB1bmlxdWUgYWNyb3NzIGFsbCBjb250cmlidXRpb25zCiAgICB9CiAgXSwKCiAgLy8gb3B0aW9uYWw6IHZhcmlhYmxlcyB0aGlzIHBsdWdpbiBleHBvc2VzIHRvIHB5Zm0gcHJvZ3JhbXMg4oCUIHRoZSBQcm9ncmFtCiAgLy8gcGFnZSB2YXJpYWJsZSBwaWNrZXIgbGlzdHMgT05MWSBkZWNsYXJlZCB2YXJpYWJsZXMuIG5hbWUgbXVzdCBzdGFydCB3aXRoCiAgLy8gUkJQXzsgZGVzY3JpcHRpb24gaXMgb3B0aW9uYWwgYnV0IHdpdGhvdXQgaXQgdGhlIFVJIGNhbid0IGV4cGxhaW4gdGhlCiAgLy8gdmFyaWFibGUsIHNvIHdyaXRlIG9uZS4KICAidmFyaWFibGVzIjogWwogICAgeyAibmFtZSI6ICJSQlBfZ3JpcF9mb3JjZSIsICJ0eXBlIjogIm51bWJlciIsICJpbml0IjogMC41LCAiZGVzY3JpcHRpb24iOiB7ICJrbyI6ICLqt7jrpqztjbwg7Z6YIiwgImVuIjogIkdyaXBwZXIgZm9yY2UiIH0gfSwKICAgIHsgIm5hbWUiOiAiUkJQX3RhcmdldF9wb3NlIiwgInR5cGUiOiAiYXJyYXkiLCAiaW5pdCI6IFswLCAwLCAwXSB9CiAgXSwKCiAgLy8gcnVudGltZSDigJQgb25lIG9mOgogIC8vICAgeyAidHlwZSI6ICJub25lIiB9CiAgLy8gICB7ICJ0eXBlIjogInB5dGhvbiIsICJlbnRyeSI6ICJtYWluLnB5IiB9CiAgLy8gICB7ICJ0eXBlIjogImNwcCIsICJlbnRyeSI6ICI8ZXhlY3V0YWJsZSBuYW1lPiIgfQogIC8vICAgeyAidHlwZSI6ICJyb3MyIiwgInJvc0NsaWVudCI6ICJyY2xweSIgfCAicmNsY3BwIiwgInBhY2thZ2UiOiAiLi4uIiwgImxhdW5jaCI6ICIuLi5fbm9kZSIgfQogICJydW50aW1lIjogeyAidHlwZSI6ICJjcHAiLCAiZW50cnkiOiAiX19QTFVHSU5fU0xVR19fIiB9LAoKICAvLyBvcHRpb25hbDogVENQIHBvcnRzIG9wZW5lZCBieSB0aGlzIHBsdWdpbiBiYWNrZW5kCiAgLy8gb25seSBudW1iZXJbXSBpcyBhbGxvd2VkOyByYW5nZXMvb2JqZWN0cyBhcmUgbm90IGFjY2VwdGVkCiAgLy8gZXh0ZXJuYWwgcGx1Z2luIHBvcnRzIG11c3QgYmUgd2l0aGluIDI4NjAwLTI4OTk5CiAgInBvcnRzIjogWzI4NjAwXQp9CmBgYAoKKipCYWNrZW5kIHR5cGVzOioqCgp8IHR5cGUgfCBzb3VyY2UgZGlyIHwgYnVpbGQgLyBydW4gfCBlbnRyeSB8CnwtLS18LS0tfC0tLXwtLS18CnwgYHB5dGhvbmAgfCBgcHkvYCB8IHBpcCArIHJ1biBpbiBEb2NrZXIgfCBgbWFpbi5weWAgfAp8IGBjcHBgIHwgYGNwcC9gIHwgQ01ha2UgaW4gRG9ja2VyIHwgYnVpbHQgZXhlY3V0YWJsZSBuYW1lIHwKfCBgcm9zMmAgKHJjbHB5KSB8IGByb3MyX3dzL2AgfCBjb2xjb24gKGFtZW50X3B5dGhvbikgaW4gRG9ja2VyIHwg4oCUIHwKfCBgcm9zMmAgKHJjbGNwcCkgfCBgcm9zMl93cy9gIHwgY29sY29uIChhbWVudF9jbWFrZSkgaW4gRG9ja2VyIHwg4oCUIHwKCj4gRXZlcnkgYmFjayBlbmQgcnVucyBpbiBhIERvY2tlciBjb250YWluZXIgbWF0Y2hpbmcgdGhlIHJvYm90IChVYnVudHUgMjQuMDQgKyBQeXRob24gMy4xMiksIHNvIGRldiBiZWhhdmVzIGxpa2UgcHJvZHVjdGlvbiBhbmQgY29tcGlsZWQgYmluYXJpZXMgYXJlIEFCSS1jb21wYXRpYmxlLiAqKkRvY2tlciBpcyByZXF1aXJlZCoqIGZvciBhbGwgYmFja2VuZCB0eXBlcyAob25seSBhIGZyb250ZW5kLW9ubHkgYG5vbmVgIHBsdWdpbiBza2lwcyBpdCkuIE5vIGxvY2FsIFB5dGhvbi90b29sY2hhaW4gc2V0dXAgaXMgbmVlZGVkLgoKKipDb250cmlidXRpb24gcG9pbnRzOioqCgp8IHBvaW50IHwgV2hlcmUgaXQgYXBwZWFycyB8IEJhY2tlbmQgfCBgY29tbWFuZEluZm9gIHwKfC0tLXwtLS18LS0tfDotLS06fAp8IGB0b29sYmFyYCB8IFRvcCB0b29sYmFyIGJ1dHRvbiAobXVzdCBoYXZlIGF0IGxlYXN0IG9uZSkgfCBTREsgLyBgcmIuYWN0aW9uYCB8IOKAlCB8CnwgYGxuYmAgfCBMZWZ0IG5hdmlnYXRpb24gZW50cnkgfCBTREsgLyBgcmIuYWN0aW9uYCB8IOKAlCB8CnwgYG1vdmUucGFuZWxgIHwgTW92ZSBzY3JlZW4gcGFuZWwgfCBTREsgLyBgcmIuYWN0aW9uYCB8IOKAlCB8CnwgYHByb2dyYW0ucGFuZWxgIHwgQ3VzdG9tIGNvbW1hbmQgaW4gdGhlIFByb2dyYW0gcGFnZSBzZXF1ZW5jZSBidWlsZGVyIHwgYFBsdWdpblByb2dyYW1Db250ZXh0YCB8IOKckyB8CgoqKmBjb21tYW5kSW5mb2AgZmllbGRzKiogKGZvciBgcHJvZ3JhbS5wYW5lbGApOgoKfCBmaWVsZCB8IHR5cGUgfCBkZXNjcmlwdGlvbiB8CnwtLS18LS0tfC0tLXwKfCBgbmFtZWAgfCBgc3RyaW5nYCB8IERpc3BsYXkgbmFtZSBvZiB0aGUgY29tbWFuZCBpbiB0aGUgcHJvZ3JhbSB0cmVlIHwKfCBgaWNvbmAgfCBgc3RyaW5nYCB8IEljb24gcGF0aCB8CnwgYGljb25DbGFzc05hbWVgIHwgYHN0cmluZz9gIHwgT3B0aW9uYWwgQ1NTIGNsYXNzIGZvciB0aGUgaWNvbiB8CnwgYGZ1bmNOYW1lYCB8IGBzdHJpbmc/YCB8IEJhY2tlbmQgZnVuY3Rpb24gbmFtZSB0byBjYWxsIHwKfCBgYXJnc2AgfCBgUmVjb3JkPHN0cmluZywgYW55Pj9gIHwgRGVmYXVsdCBhcmd1bWVudHMgfAp8IGBkaXNhYmxlZGAgfCBgYm9vbGVhbj9gIHwgV2hldGhlciB0aGUgbm9kZSBpcyBkaXNhYmxlZCB8CnwgYGFsbG93Q2hpbGRyZW5gIHwgYHN0cmluZ1tdP2AgfCBBbGxvd2VkIGNoaWxkIGNvbW1hbmRzIHwKfCBgYWxsb3dQYXJlbnRzYCB8IGBzdHJpbmdbXT9gIHwgQWxsb3dlZCBwYXJlbnQgY29tbWFuZHMgfAp8IGBub3RBbGxvd0NoaWxkcmVuYCB8IGBzdHJpbmdbXT9gIHwgRGlzYWxsb3dlZCBjaGlsZCBjb21tYW5kcyB8CnwgYHN5bmNHcm91cElkYCB8IGBib29sZWFuP2AgfCBTeW5jIGdyb3VwIElEIGFjcm9zcyBjaGlsZHJlbiB8CnwgYGRpc2FibGVDb3B5YCB8IGBib29sZWFuP2AgfCBQcmV2ZW50IGNvcHkgfAp8IGBkaXNhYmxlRGVsZXRlYCB8IGBib29sZWFuP2AgfCBQcmV2ZW50IGRlbGV0ZSB8CnwgYHJlcXVpcmVDaGlsZHJlbmAgfCBgYm9vbGVhbj9gIHwgV2hldGhlciBhIGNoaWxkIGNvbW1hbmQgaXMgcmVxdWlyZWQgfAp8IGByZXF1aXJlUGFyZW50YCB8IGBib29sZWFuP2AgfCBXaGV0aGVyIGEgcGFyZW50IGNvbW1hbmQgaXMgcmVxdWlyZWQgfAp8IGBjaGlsZHJlbkNvbW1hbmRgIHwgYHN0cmluZz9gIHwgRGVmYXVsdCBjb21tYW5kIHR5cGUgZm9yIGNoaWxkcmVuIHwKCioqVmFsaWRhdGlvbiBydWxlczoqKgotIGBpZGAsIGBuYW1lYCwgYHZlcnNpb25gLCBgbWluTXVzY2F0VmVyc2lvbmAg4oCUIHJlcXVpcmVkIG5vbi1lbXB0eSBzdHJpbmdzCi0gYGF1dGhvcmAg4oCUIHJlcXVpcmVkIG5vbi1lbXB0eSBzdHJpbmcKLSBgZGVzY3JpcHRpb25gIOKAlCByZXF1aXJlZCAoYHN0cmluZ2Agb3IgYHsgZW4gKHJlcXVpcmVkKSwga28/LCBqYT8sIHpoPywgdmk/LCB0aD8sIGVzPyB9YCkKLSBgaWNvbnNgIOKAlCBTVkc6IHNpbmdsZSBzdHJpbmcgcGF0aCBlbmRpbmcgaW4gYC5zdmdgOyBQTkcvSlBHOiBvYmplY3Qgd2l0aCBgIjE2ImAsIGAiNDgiYCwgYCIxMjgiYCBhbGwgcHJlc2VudAotIGB0YXJnZXRNb2RlbHNgIOKAlCBgImFsbCJgIG9yIGEgbm9uLWVtcHR5IGFycmF5IG9mIHJvYm90IG1vZGVsIElEIHN0cmluZ3MgKGF0IGxlYXN0IG9uZSBvZiBgdGFyZ2V0TW9kZWxzYCAvIGB0YXJnZXRDYXRlZ29yeXNgIHJlcXVpcmVkKQotIGB0YXJnZXRDYXRlZ29yeXNgIOKAlCBgImFsbCJgIG9yIGEgbm9uLWVtcHR5IGFycmF5IG9mIGAibWFuaXB1bGF0ZSIgfCAiYW1yIiB8ICJyYnkxIiB8ICJ2aXNpb24iYCAoYXQgbGVhc3Qgb25lIG9mIGB0YXJnZXRNb2RlbHNgIC8gYHRhcmdldENhdGVnb3J5c2AgcmVxdWlyZWQpCi0gYGNvbnRyaWJ1dGVzYCDigJQgdGhlIHBsdWdpbidzIHNjcmVlbnM7IHdoZW4gcHJlc2VudCBpdCBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGB0b29sYmFyYCBlbnRyeS4gTGVhdmUgaXQgb3V0IChvciBgW11gKSBmb3IgYSBiYWNrZW5kLW9ubHkgcGx1Z2luOiBubyBVSSBpcyBidWlsdCwgYW5kIE5vZGUuanMgaXMgbm90IG5lZWRlZCB0byBidWlsZCBpdAotIGB1aWAg4oCUIGVhY2ggY29udHJpYnV0aW9uIG11c3QgaGF2ZSBhIHVuaXF1ZSB2YWx1ZQotIGBjb21tYW5kSW5mb2Ag4oCUIHJlcXVpcmVkIHdoZW4gYHBvaW50YCBpcyBgInByb2dyYW0ucGFuZWwiYAotIGBwb3J0c2Ag4oCUIG9wdGlvbmFsIGBudW1iZXJbXWA7IGV2ZXJ5IHBvcnQgbXVzdCBiZSB3aXRoaW4gYDI4NjAwLTI4OTk5YAogIGFuZCBtdXN0IG5vdCBiZSBhIHJlc2VydmVkIHJvYm90L2luZHVzdHJpYWwvaW50ZXJuYWwgcG9ydAotIGB2YXJpYWJsZXNgIOKAlCBvcHRpb25hbCBhcnJheSBvZiBgeyBuYW1lLCB0eXBlLCBpbml0LCBkZXNjcmlwdGlvbj8gfWA6CiAgLSBgbmFtZWAg4oCUIG11c3Qgc3RhcnQgd2l0aCBgUkJQX2AsIHRoZW4gbGV0dGVycy9kaWdpdHMvdW5kZXJzY29yZTsgdW5pcXVlIHBlciBwbHVnaW4KICAtIGB0eXBlYCDigJQgYCJudW1iZXIiIHwgInN0cmluZyIgfCAiYXJyYXkiYAogIC0gYGluaXRgIOKAlCByZXF1aXJlZCBpbml0aWFsIHZhbHVlLCBtdXN0IG1hdGNoIGB0eXBlYAogIC0gYGRlc2NyaXB0aW9uYCDigJQgb3B0aW9uYWwgYHN0cmluZ2Agb3IgaTE4biBvYmplY3QgKGBlbmAgcmVxdWlyZWQgaW4gb2JqZWN0IGZvcm0pCgpgbXVzY2F0LXBrIGJ1aWxkYCB0aHJvd3Mgb24gYW55IHZhbGlkYXRpb24gZXJyb3IuIGBtdXNjYXQtcGsgZGV2YCBwcmludHMKd2FybmluZ3Mg4oCUIGV4Y2VwdCBgdmFyaWFibGVzYCBlcnJvcnMgKGUuZy4gYSBuYW1lIHdpdGhvdXQgdGhlIGBSQlBfYCBwcmVmaXgpLAp3aGljaCBhcmUgaGFyZCBlcnJvcnMgaW4gYGRldmAgLyBgZGV2OmJhY2tgIHRvby4KCioqQmFja2VuZCBwb3J0IHJ1bGVzOioqCi0gRGVjbGFyZSBhIHBvcnQgb25seSBpZiB5b3VyIGJhY2tlbmQgb3BlbnMgYSBUQ1Agc2VydmVyL2xpc3RlbmVyLgotICoqRXZlcnkgbGlzdGVuaW5nIFRDUCBwb3J0IG11c3QgYmUgZGVjbGFyZWQuKiogYG11c2NhdC1wayBkZXZgIGFuZAogIGBtdXNjYXQtcGsgZGV2OmJhY2tgIHdhdGNoIHRoZSBiYWNrZW5kIGFuZCBzdG9wIGl0IHRoZSBtb21lbnQgaXQgb3BlbnMgYSBwb3J0CiAgdGhhdCBpcyBub3QgaW4gYHBvcnRzYC4gQSBwb3J0IG91dHNpZGUgYDI4NjAwLTI4OTk5YCBjYW4ndCBiZSBkZWNsYXJlZCwgc28gaXQKICBtdXN0IG5vdCBiZSBvcGVuZWQgZWl0aGVyIOKAlCBwaWNraW5nIGUuZy4gYDU1MDBgIGlzIG5vdCBhIHdheSBhcm91bmQgdGhlIHJ1bGUuCiAgSXQgd291bGQgZXNjYXBlIHRoaXMgY2hlY2sgKmFuZCogdGhlIHJvYm90J3MgaW5zdGFsbC10aW1lIGNvbmZsaWN0IGNoZWNrLCBhbmQKICBvbmx5IGNvbGxpZGUgb25jZSBpdCdzIHJ1bm5pbmcgb24gYSByb2JvdC4KLSBSZXNlcnZlZCBwb3J0cyBpbmNsdWRlIGA1MDJgLCBgMjIyMmAsIGA0ODQwYCwgYDUxNzAtNTE3OWAsIGA4MDAwLTg5OTlgLAogIGAxMDAwMGAsIGAzMDAwNGAsIGAzNDk2NGAsIGA0NDgxOGAsIGA1MDAwMC01MDAwNWAsIGFuZCBgNTAwNTFgLgotIFRoZSByb2JvdCByZWplY3RzIGluc3RhbGxhdGlvbiAoSFRUUCA0MDkpIGlmIGEgZGVjbGFyZWQgcG9ydCBpcyByZXNlcnZlZCwKICBvdXQgb2YgcmFuZ2UsIG9yIGFscmVhZHkgY2xhaW1lZCBieSBhbm90aGVyIGVuYWJsZWQgcGx1Z2luLgoKKipSZWFjaGluZyB5b3VyIGJhY2tlbmQncyBwb3J0cyBkdXJpbmcgZGV2ZWxvcG1lbnQ6KioKLSBEZWNsYXJlZCBwb3J0cyBhcmUgcHVibGlzaGVkIHRvIGAxMjcuMC4wLjFgIG9uIHlvdXIgbWFjaGluZSwgc28KICBgY3VybCBodHRwOi8vMTI3LjAuMC4xOjI4NjAwYCB3b3JrcyBmcm9tIHRoZSBob3N0IG9uIG1hY09TLCBXaW5kb3dzLCBhbmQgTGludXguCi0gT24gbmF0aXZlIExpbnV4IHRoZSBkZXYgY29udGFpbmVyIHVzZXMgaG9zdCBuZXR3b3JraW5nLCBzbyB0aGUgcG9ydHMgYXJlIG9uCiAgdGhlIGhvc3QgYWxyZWFkeS4KLSBJZiBhIGRlY2xhcmVkIHBvcnQgaXMgYWxyZWFkeSB0YWtlbiBvbiB5b3VyIG1hY2hpbmUsIGBtdXNjYXQtcGsgZGV2YCB3YXJucyBhbmQKICBza2lwcyBwdWJsaXNoaW5nIHRoYXQgb25lIOKAlCB0aGUgYmFja2VuZCBzdGlsbCBsaXN0ZW5zIGluc2lkZSB0aGUgY29udGFpbmVyLgoKLS0tCgojIyBMb2NhbGl6ZWQgZG9jdW1lbnRhdGlvbgoKWW91IGNhbiBzaGlwIHBlci1sYW5ndWFnZSBSRUFETUUgZmlsZXMgYWxvbmdzaWRlIHRoZSBtYWluIGBSRUFETUUubWRgLiBQbGFjZSB0aGVtIGluIHRoZSBwcm9qZWN0IHJvb3Q6CgpgYGAKUkVBRE1FLm1kICAgICAgICAjIGRlZmF1bHQgLyBFbmdsaXNoIGZhbGxiYWNrClJFQURNRS5rby5tZCAgICAgIyBLb3JlYW4KUkVBRE1FLmVuLm1kICAgICAjIGV4cGxpY2l0IEVuZ2xpc2ggKG9wdGlvbmFsKQpSRUFETUUuamEubWQgICAgICMgSmFwYW5lc2UKYGBgCgpBbGwgYFJFQURNRSoubWRgIGZpbGVzIGZvdW5kIGF0IHRoZSBwcm9qZWN0IHJvb3QgYXJlIGF1dG9tYXRpY2FsbHkgY29waWVkIHRvIGBkaXN0L2Agb24KYG11c2NhdC1wayBidWlsZGAuIE11c2NhdCBkaXNwbGF5cyB0aGUgZmlsZSBtYXRjaGluZyB0aGUgdXNlcidzIGxvY2FsZSwKZmFsbGluZyBiYWNrIHRvIGBSRUFETUUubWRgIGlmIG5vbmUgbWF0Y2hlcy4KCi0tLQoKIyMgQysrIFNESyAmIGRlcGVuZGVuY2llcwoKVGhlIGRldiBjb250YWluZXIgaGFzIHRoZSBDKysgU0RLIChgcmFpbmJvdy1yYi1zZGstZGV2YCkgcHJlLWluc3RhbGxlZCDigJQgbm8gbG9jYWwKaW5zdGFsbCBuZWVkZWQuIFRoZSBTREsgdmVyc2lvbiBpcyB0aGUgb25lIHBpbm5lZCBpbiBgQ01ha2VMaXN0cy50eHRgIChgZmluZF9wYWNrYWdlKHJiX3NkayA8dmVyc2lvbj4gRVhBQ1QgUkVRVUlSRUQpYCkuIFBpY2sgYSBkaWZmZXJlbnQgb25lIHdpdGg6CgpgYGBiYXNoCm11c2NhdC1wayBzZGsgdXBkYXRlIDx2ZXJzaW9uPgpgYGAKCmBtdXNjYXQtcGsgYnVpbGRgIGNvcGllcyB0aGUgbWF0Y2hpbmcgYGxpYnJiX3Nkay5zb2AgbmV4dCB0byB5b3VyIGJpbmFyeQooYGRpc3QvPGFyY2g+L2xpYi9gLCBvciBgaW5zdGFsbC08YXJjaD4vPHBrZz4vbGliL2AgZm9yIHJjbGNwcCksIHNvIHRoZSByb2JvdCBuZWVkcyBubyBTREsKaW5zdGFsbCBhbmQgZWFjaCBwbHVnaW4ga2VlcHMgdGhlIFNESyB2ZXJzaW9uIGl0IHdhcyBidWlsdCB3aXRoLgoKT3RoZXIgbGlicmFyaWVzOiBpbnN0YWxsIHRoZW0gaW4gdGhlIGJ1aWxkIChlLmcuIHZlbmRvciB0aGVtIHVuZGVyIGBjcHAvYCBhbmQKYGFkZF9zdWJkaXJlY3RvcnlgLCBvciBsaW5rIHN0YXRpY2FsbHkpIOKAlCB0aGUgcm9ib3Qgb25seSBoYXMgVWJ1bnR1IDI0LjA0IGJhc2UKbGlicmFyaWVzLgoKVG8gdXNlIHRoZSBTREsgb3V0c2lkZSBhIHBsdWdpbiAoeW91ciBvd24gVWJ1bnR1IDI0LjA0IG1hY2hpbmUpOgoKYGBgYmFzaApjdXJsIC1mc1NMIGh0dHBzOi8vcmFpbmJvd3JvYm90aWNzLmdpdGh1Yi5pby9yYi1zZGsvcmItc2RrLWFwdC1yZXBvLmdwZy5rZXkgfCBzdWRvIGdwZyAtLWRlYXJtb3IgLW8gL3Vzci9zaGFyZS9rZXlyaW5ncy9yYi1zZGstYXB0LmdwZwplY2hvICdkZWIgW3NpZ25lZC1ieT0vdXNyL3NoYXJlL2tleXJpbmdzL3JiLXNkay1hcHQuZ3BnXSBodHRwczovL3JhaW5ib3dyb2JvdGljcy5naXRodWIuaW8vcmItc2RrIHN0YWJsZSBtYWluJyB8IHN1ZG8gdGVlIC9ldGMvYXB0L3NvdXJjZXMubGlzdC5kL3JiLXNkay5saXN0CnN1ZG8gYXB0IHVwZGF0ZSAmJiBzdWRvIGFwdCBpbnN0YWxsIHJhaW5ib3ctcmItc2RrLWRldgpgYGAKCgojIyMgQnVuZGxpbmcgZXh0cmEgc2hhcmVkIGxpYnJhcmllcwoKVGhlIHJvYm90IG9ubHkgaGFzIFVidW50dSAyNC4wNCBiYXNlIGxpYnJhcmllcy4gQ29weSBhbnkgb3RoZXIgYC5zb2AgeW91ciBleGVjdXRhYmxlCm5lZWRzIGludG8gYCR7Q01BS0VfQklOQVJZX0RJUn0vbGliYCDigJQgYG11c2NhdC1wayBidWlsZGAgc2hpcHMgdGhhdCBmb2xkZXIgYXMKYGRpc3QvPGFyY2g+L2xpYi9gIGFuZCB0aGUgZXhlY3V0YWJsZSBmaW5kcyBpdCB2aWEgaXRzIFJQQVRIIChgJE9SSUdJTi9saWJgKToKCmBgYGNtYWtlCiMgY3BwL0NNYWtlTGlzdHMudHh0IOKAlCB0aGlyZF9wYXJ0eS8gaG9sZHMgcHJlYnVpbHQgbGlicyBmb3IgYW1kNjQgLyBhcm02NApzZXQoQVJDSF9ESVIgJHtDTUFLRV9TT1VSQ0VfRElSfS90aGlyZF9wYXJ0eS8ke0NNQUtFX1NZU1RFTV9QUk9DRVNTT1J9KQp0YXJnZXRfbGlua19saWJyYXJpZXMoX19QTFVHSU5fU0xVR19fIFBSSVZBVEUgJHtBUkNIX0RJUn0vbGliZm9vLnNvKQphZGRfY3VzdG9tX2NvbW1hbmQoVEFSR0VUIF9fUExVR0lOX1NMVUdfXyBQT1NUX0JVSUxECiAgQ09NTUFORCAke0NNQUtFX0NPTU1BTkR9IC1FIG1ha2VfZGlyZWN0b3J5ICR7Q01BS0VfQklOQVJZX0RJUn0vbGliCiAgQ09NTUFORCAke0NNQUtFX0NPTU1BTkR9IC1FIGNvcHkgJHtBUkNIX0RJUn0vbGliZm9vLnNvICR7Q01BS0VfQklOQVJZX0RJUn0vbGliLykKYGBgCgpCdWlsZCB0aGVtIGZvciBib3RoIGFyY2hlcyAoYHg4Nl82NGAsIGBhYXJjaDY0YCkgb24gVWJ1bnR1IDI0LjA0IHNvIHRoZXkgbWF0Y2ggdGhlIHJvYm90LgpTdGF0aWMgbGlua2luZyB3b3JrcyB0b28gYW5kIG5lZWRzIG5vIGJ1bmRsaW5nLiBGb3IgYW4gcmNsY3BwIG5vZGUsIGBpbnN0YWxsKEZJTEVTIC4uLiBERVNUSU5BVElPTiBsaWIpYAppbnN0ZWFkIOKAlCB0aGUgbm9kZSBmaW5kcyBgaW5zdGFsbC08YXJjaD4vPHBrZz4vbGliL2AgdGhlIHNhbWUgd2F5LgotLS0KCiMjIFN3aXRjaGluZyBiYWNrZW5kIHR5cGUKCmBgYGJhc2gKbXVzY2F0LXBrIHR5cGUgY2hhbmdlICAgICAgICAgICAgICAgICAjIGludGVyYWN0aXZlCm11c2NhdC1wayB0eXBlIGNoYW5nZSAtLXRvIGNwcCAgICAgICAgIyDihpIgQysrCm11c2NhdC1wayB0eXBlIGNoYW5nZSAtLXRvIHJvczIgICAgICAgIyDihpIgUk9TMiAocmNscHkgLyBQeXRob24pCm11c2NhdC1wayB0eXBlIGNoYW5nZSAtLXRvIHJvczItY3BwICAgIyDihpIgUk9TMiAocmNsY3BwIC8gQysrKQptdXNjYXQtcGsgdHlwZSBjaGFuZ2UgLS10byBweXRob24gICAgICMg4oaSIFB5dGhvbgpgYGAKCj4gRXhpc3RpbmcgYmFja2VuZCBkaXJzIChgcm9zMl93cy9gLCBgY3BwL2ApIGFyZSBub3QgZGVsZXRlZCB3aGVuIHN3aXRjaGluZyBhd2F5LiBSZW1vdmUgdGhlbSBtYW51YWxseSBpZiBubyBsb25nZXIgbmVlZGVkLgoKPiBTd2l0Y2hpbmcgYmV0d2VlbiBhIFB5dGhvbiBhbmQgYSBDKysgYmFja2VuZCBhc2tzIHdoZXRoZXIgdG8gcmVwbGFjZSB0aGlzIFJFQURNRSB3aXRoIHRoZSBtYXRjaGluZyBvbmUgKHRoZSBvbGQgZmlsZSBpcyBrZXB0IGFzIGBSRUFETUUubWQuYmFrYCkuIEFkZCBgLS1yZWFkbWVgIHRvIGFuc3dlciB5ZXMgd2l0aG91dCB0aGUgcHJvbXB0LgoKLS0tCgojIyBBSSBjb2RpbmcgYXNzaXN0YW50cyAoTUNQKQoKSWYgeW91IGJ1aWxkIHlvdXIgcGx1Z2luIHdpdGggYW4gQUkgYXNzaXN0YW50IChDbGF1ZGUgQ29kZSwgQ29kZXgsIOKApiksIGdpdmUgaXQKZ3JvdW5kZWQga25vd2xlZGdlIG9mIHRoZSBNdXNjYXQgVUkgY29tcG9uZW50cywgZGVzaWduIHRva2VucywgYW5kIFNESyBpbnN0ZWFkIG9mCmxldHRpbmcgaXQgZ3Vlc3MuIGBtdXNjYXQtcGsgbWNwYCBpcyBhbiBNQ1Agc2VydmVyIGV4cG9zaW5nOgoKLSBgbGlzdF9jb21wb25lbnRzYCAvIGBnZXRfY29tcG9uZW50X3Byb3BzYCAvIGBnZXRfY29tcG9uZW50X2V4YW1wbGVgIOKAlCBldmVyeQogIGBAcmFpbmJvdy1yb2JvdGljcy9wbHVnaW4tdWkvcmVhY3RgIGNvbXBvbmVudCB3aXRoIGl0cyByZWFsIHByb3BzIGFuZCBhIHdvcmtpbmcKICBTdG9yeWJvb2sgZXhhbXBsZS4KLSBgbGlzdF9kZXNpZ25fdG9rZW5zYCAvIGBzZWFyY2hfZGVzaWduX3Rva2Vuc2Ag4oCUIHRoZSBUYWlsd2luZCBjbGFzc2VzIHRvIHVzZQogIChgYmctYmctKmAsIGB0ZXh0LWZnLSpgLCBgdHlwby0qYCwg4oCmKSBzbyB5b3VyIFVJIG1hdGNoZXMgdGhlIGhvc3QgdGhlbWUuCi0gYHNlYXJjaF9yYl9zZGtgIOKAlCBob3cgdG8gdXNlIGB1c2VSYigpYCwgYHJiLipgLCBgdXNlUmJGb3JtRGF0YWAvYHVzZVJiU2F2ZWAsIGFuZAogIHRoZSBiYWNrZW5kIHJ1bnRpbWVzLgotIGBsaXN0X3JiX3Nka2AgLyBgZ2V0X3JiX3Nka19hcGlgIOKAlCB0aGUgaW5zdGFsbGVkIGByYWluYm93LXJiLXNka2AgKFB5dGhvbgogIGJhY2tlbmQpIGNsYXNzZXMgYW5kIHNpZ25hdHVyZXM7IHdpdGggYGxhbmc6ICJjcHAiYCwgdGhlIEMrKyBTREsgaGVhZGVycwogIChgcmFpbmJvdy1yYi1zZGstZGV2YCwgcmVhZCBvdXQgb2YgdGhlIGBtdXNjYXQtcGtgIGNwcCBkZXYgaW1hZ2Ug4oCUIGJ1aWxkIGl0CiAgb25jZSB3aXRoIGBtdXNjYXQtcGsgZGV2OmJhY2tgKS4KCioqQnJvd3NlIHRoZSBjb21wb25lbnRzIGxpdmUqKiB3aXRoIGBtdXNjYXQtcGsgc3Rvcnlib29rYC4KCiMjIyBSZWdpc3RlciB0aGUgc2VydmVyCgoqKkNsYXVkZSBDb2RlKiog4oCUIGEgYC5tY3AuanNvbmAgaXMgYWxyZWFkeSBzY2FmZm9sZGVkIGF0IHlvdXIgcGx1Z2luIHJvb3QsIHNvCml0IHdvcmtzIG91dCBvZiB0aGUgYm94OgoKYGBganNvbgp7CiAgIm1jcFNlcnZlcnMiOiB7CiAgICAibXVzY2F0IjogewogICAgICAiY29tbWFuZCI6ICJtdXNjYXQtcGsiLAogICAgICAiYXJncyI6IFsibWNwIl0KICAgIH0KICB9Cn0KYGBgCgoqKkNvZGV4Kiog4oCUIHJlZ2lzdGVyIG9uY2Ugd2l0aDoKCmBgYGJhc2gKbXVzY2F0LXBrIG1jcCAtLWluc3RhbGwgY29kZXgKYGBgCgpUaGlzIGFwcGVuZHMgdGhlIHNlcnZlciB0byBgfi8uY29kZXgvY29uZmlnLnRvbWxgIChpZGVtcG90ZW50IOKAlCBzYWZlIHRvIHJ1bgphZ2FpbikuIEVxdWl2YWxlbnQgbWFudWFsIGNvbmZpZzoKCmBgYHRvbWwKW21jcF9zZXJ2ZXJzLm11c2NhdF0KY29tbWFuZCA9ICJtdXNjYXQtcGsiCmFyZ3MgPSBbIm1jcCJdCmBgYAoKQW55IG90aGVyIE1DUCBjbGllbnQgd29ya3MgdG9vIOKAlCBpdCdzIGEgc3RhbmRhcmQgc3RkaW8gTUNQIHNlcnZlciBzdGFydGVkIHdpdGgKYG11c2NhdC1wayBtY3BgLiBJZiBgbXVzY2F0LXBrYCBpc24ndCBvbiB0aGUgY2xpZW50J3MgUEFUSCwgdXNlIGl0cyBhYnNvbHV0ZSBwYXRoCihgd2hpY2ggbXVzY2F0LXBrYCkgYXMgYGNvbW1hbmRgLgoKLS0tCgojIyBTaGlwcGluZwoKYGBgYmFzaAptdXNjYXQtcGsgYnVpbGQgICAgICAgICAgICAjIGJ1aWxkICsgWklQCm11c2NhdC1wayBidWlsZCAtLW5vLXppcCAgICMgYnVpbGQgb25seSwgbm8gWklQCmBgYAoKPiBCdWlsZGluZyB0aGUgb3RoZXIgYXJjaCAoZS5nLiBhcm02NCBvbiBhbiBhbWQ2NCBQQykgcnVucyBpbiBhbiBlbXVsYXRlZCBjb250YWluZXIgZm9yCj4gQysrIGJhY2tlbmRzLiBEb2NrZXIgRGVza3RvcCBoYXMgaXQgYnVpbHQgaW47IG9uIExpbnV4IGVuYWJsZSBpdCBvbmNlIHdpdGgKPiBgZG9ja2VyIHJ1biAtLXByaXZpbGVnZWQgLS1ybSB0b25pc3RpaWdpL2JpbmZtdCAtLWluc3RhbGwgYWxsYCwgb3IgcGFzcyBgLS1hcmNoYCBmb3Igb25lIGFyY2guCgotIEJ1aWxkcyBgdWkvY29udGVudC50c3hgIOKGkiBgZGlzdC9jb250ZW50LmpzYCAobWluaWZpZWQpCi0gQ29tcGlsZXMgYGNwcC9gIChSZWxlYXNlKSBpbiB0aGUgVWJ1bnR1IDI0LjA0IGNvbnRhaW5lciBwZXIgYXJjaCDihpIgYGRpc3QvPGFyY2g+LzxlbnRyeT5gICsgYGRpc3QvPGFyY2g+L2xpYi9saWJyYl9zZGsuc28uKmAKLSBST1MyIChyY2xjcHApOiBydW5zIGBjb2xjb24gYnVpbGRgIHBlciBhcmNoIOKGkiBgZGlzdC9yb3MyX3dzL2luc3RhbGwtPGFyY2g+L2AKLSBDb3BpZXMgYGFzc2V0cy9gLCBgbWFuaWZlc3QuanNvbmAsIGFuZCBgUkVBRE1FKi5tZGAgaW50byBgZGlzdC9gCi0gT3V0cHV0OiBgX19QTFVHSU5fRElSX18te3ZlcnNpb259LnppcGAKClpJUCBsYXlvdXQ6CgpgYGAKX19QTFVHSU5fRElSX18tMS4wLjAuemlwCuKUnOKUgCBkaXN0LwrilIIgICDilJzilIAgY29udGVudC5qcyAgICAgICAgIyBidWlsdCBVSQrilIIgICDilJzilIAgbWFuaWZlc3QuanNvbgrilIIgICDilJzilIAgYXNzZXRzLwrilIIgICDilJzilIAgUkVBRE1FLm1kCuKUgiAgIOKUnOKUgCBSRUFETUUua28ubWQgICAgICAjIGlmIHByZXNlbnQK4pSCICAg4pSc4pSAIGFtZDY0LyAgICAgICAgICAgICMgY3BwOiA8ZW50cnk+ICsgbGliL2xpYnJiX3Nkay5zby4qCuKUgiAgIOKUnOKUgCBhcm02NC8K4pSCICAg4pSU4pSAIHJvczJfd3MvICAgICAgICAgICMgcmNsY3BwOiBpbnN0YWxsLWFtZDY0LywgaW5zdGFsbC1hcm02NC8KYGBgCgotLS0KCiMjIEFsbCBjb21tYW5kcwoKYGBgYmFzaAptdXNjYXQtcGsgZGV2ICAgICAgICAjIFVJICsgYmFja2VuZAptdXNjYXQtcGsgZGV2OnVpICAgICAjIFVJIHByZXZpZXcgb25seSAocHJldmlldy1ob3N0KQptdXNjYXQtcGsgZGV2OmJhY2sgICAjIGJhY2tlbmQgb25seSAoQysrIHJlYnVpbGQgKyByZXN0YXJ0IGluIERvY2tlcikKbXVzY2F0LXBrIGJ1aWxkICAgICAgIyBidWlsZCDihpIgZGlzdC8gKyBkaXN0cmlidXRhYmxlIFpJUCAoLS1uby16aXAgdG8gc2tpcCkKbXVzY2F0LXBrIHN0b3J5Ym9vayAgIyBicm93c2UgdGhlIHJiLWNvbXBvbmVudHMgVUkgbGlicmFyeSBpbiBhIGJyb3dzZXIKbXVzY2F0LXBrIG1jcCAgICAgICAgIyBNQ1Agc2VydmVyIGZvciBBSSBhc3Npc3RhbnRzIChjb21wb25lbnRzL3Rva2Vucy9TREsgZG9jcykKYGBgCgpgYGBiYXNoCm11c2NhdC1wayB0eXBlIGNoYW5nZSAgICAjIHN3aXRjaCBiYWNrZW5kIHR5cGUKbXVzY2F0LXBrIHVwZGF0ZSAgICAgICAgICMgdXBkYXRlIG11c2NhdC1wbHVnaW4ta2l0IGl0c2VsZgptdXNjYXQtcGsgdW5pbnN0YWxsICAgICAgIyByZW1vdmUgbXVzY2F0LXBrIGl0c2VsZgpgYGAK","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":"Y21ha2VfbWluaW11bV9yZXF1aXJlZChWRVJTSU9OIDMuMTYpCnByb2plY3QoX19QTFVHSU5fU0xVR19fKQoKaWYoTk9UIENNQUtFX0NYWF9TVEFOREFSRCkKICBzZXQoQ01BS0VfQ1hYX1NUQU5EQVJEIDE3KQplbmRpZigpCgpmaW5kX3BhY2thZ2UoYW1lbnRfY21ha2UgUkVRVUlSRUQpCmZpbmRfcGFja2FnZShyY2xjcHAgUkVRVUlSRUQpCiMgUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLIChhcHQ6IHJhaW5ib3ctcmItc2RrLWRldiwgcHJlLWluc3RhbGxlZCBpbiB0aGUgZGV2CiMgY29udGFpbmVyKS4gVGhlIHZlcnNpb24gaGVyZSBpcyB0aGUgb25lIHRoZSBkZXYgY29udGFpbmVyIGluc3RhbGxzOyBjaGFuZ2UgaXQKIyB3aXRoIGBtdXNjYXQtcGsgc2RrIHVwZGF0ZSA8dmVyc2lvbj5gLgpmaW5kX3BhY2thZ2UocmJfc2RrIDAuMTAuMiBFWEFDVCBSRVFVSVJFRCkKCmFkZF9leGVjdXRhYmxlKF9fUExVR0lOX1NMVUdfX19ub2RlIHNyYy9ub2RlLmNwcCkKYW1lbnRfdGFyZ2V0X2RlcGVuZGVuY2llcyhfX1BMVUdJTl9TTFVHX19fbm9kZSByY2xjcHApCnRhcmdldF9saW5rX2xpYnJhcmllcyhfX1BMVUdJTl9TTFVHX19fbm9kZSByYl9zZGs6OnJiX3NkaykKCmluc3RhbGwoVEFSR0VUUyBfX1BMVUdJTl9TTFVHX19fbm9kZQogIERFU1RJTkFUSU9OIGxpYi8ke1BST0pFQ1RfTkFNRX0pCgphbWVudF9wYWNrYWdlKCkK","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":"Ly8gX19QTFVHSU5fTkFNRV9fIOKAlCBST1MyIG5vZGUgKHJjbGNwcCkuCi8vCi8vIFJlbGF0aXZlIHRvcGljIG5hbWVzIGxhbmQgdW5kZXIgdGhlIHBsdWdpbidzIFJPUyBuYW1lc3BhY2UgKHBsdWdpbiBpZCB3aXRoCi8vICIuIiDihpIgIi8iLCAiLSIg4oaSICJfIik7IHVzZSBhbiBhYnNvbHV0ZSBuYW1lICgiL2NtZF92ZWwiKSBmb3Igc2hhcmVkIHRvcGljcy4KLy8gVUkgbWVzc2FnaW5nIC8gZXh0ZXJuYWwgZW5kcG9pbnRzOiByYl9wbHVnaW46OlJCUGx1Z2luQ2FsbCAocGx1Z2luL3JiX3BsdWdpbi5ocHApLgojaW5jbHVkZSAicmNsY3BwL3JjbGNwcC5ocHAiCi8vIFJhaW5ib3cgUm9ib3RpY3MgQysrIFNESyAobGlua2VkIGFzIHJiX3Nkazo6cmJfc2RrKTogUkJNYW5pcHVsYXRlU0RLIGV0Yy4KI2luY2x1ZGUgPHJhaW5ib3cvcmJfc2RrL21hbmlwdWxhdGUvcmJfbWFuaXB1bGF0ZV9zZGsuaHBwPgoKY2xhc3MgX19QTFVHSU5fQ0xBU1NfX05vZGUgOiBwdWJsaWMgcmNsY3BwOjpOb2RlIHsKcHVibGljOgogIF9fUExVR0lOX0NMQVNTX19Ob2RlKCkgOiBOb2RlKCJfX1BMVUdJTl9TTFVHX19fbm9kZSIpIHsKICAgIFJDTENQUF9JTkZPKHRoaXMtPmdldF9sb2dnZXIoKSwgIl9fUExVR0lOX05BTUVfXyBub2RlIHN0YXJ0ZWQiKTsKICAgIC8vIGNyZWF0ZSBwdWJsaXNoZXJzIC8gc3Vic2NyaWJlcnMgLyBzZXJ2aWNlcyBoZXJlCiAgfQp9OwoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgcmNsY3BwOjppbml0KGFyZ2MsIGFyZ3YpOwogIHJjbGNwcDo6c3BpbihzdGQ6Om1ha2Vfc2hhcmVkPF9fUExVR0lOX0NMQVNTX19Ob2RlPigpKTsKICByY2xjcHA6OnNodXRkb3duKCk7CiAgcmV0dXJuIDA7Cn0K","docker/Dockerfile.cpp":"IyBEZXYvYnVpbGQgY29udGFpbmVyIGZvciB0aGUgcHVyZSBDKysgcGx1Z2luIGJhY2sgZW5kLgojIE1hdGNoZXMgdGhlIE11c2NhdCByb2JvdCBiYWNrZW5kIE9TIChVYnVudHUgMjQuMDQpIHNvIHRoZSBjb21waWxlZCBiaW5hcnkKIyBpcyBBQkktY29tcGF0aWJsZSB3aXRoIHRoZSByb2JvdC4gVXNlZCBieSBgbXVzY2F0LXBrIGRldjpiYWNrYCBhbmQgYGJ1aWxkYAojIOKAlCBOT1Qgc2hpcHBlZCBpbiB0aGUgcGx1Z2luIFpJUC4KRlJPTSB1YnVudHU6MjQuMDQKTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBcCiAgICAgIGJ1aWxkLWVzc2VudGlhbCBcCiAgICAgIGNtYWtlIFwKICAgICYmIHJtIC1yZiAvdmFyL2xpYi9hcHQvbGlzdHMvKgoKIyBSYWluYm93IFJvYm90aWNzIEMrKyBTREsgZm9yIGZpbmRfcGFja2FnZShyYl9zZGspLiBtdXNjYXQtcGsgcGFzc2VzIHRoZSB2ZXJzaW9uIHBpbm5lZCBpbiB0aGUKIyBwcm9qZWN0J3MgQ01ha2VMaXN0cy50eHQgKGZpbmRfcGFja2FnZShyYl9zZGsgPHZlcj4gRVhBQ1QpKTsgd2l0aG91dCBhIHBpbiAoUk9TIDIgcmNscHksIGBtdXNjYXQtcGsgbWNwYAojIG91dHNpZGUgYSBwcm9qZWN0KSB0aGUgbmV3ZXN0IFNESyBpcyBpbnN0YWxsZWQuIFJ1bnRpbWUgYW5kIC1kZXYgYXJlIGluc3RhbGxlZCB0b2dldGhlciBhdCBvbmUgdmVyc2lvbi4KQVJHIFJCX1NES19WRVJTSU9OPQpSVU4gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzIGNhLWNlcnRpZmljYXRlcyBjdXJsIFwKICAgICYmIGluc3RhbGwgLWQgL2V0Yy9hcHQva2V5cmluZ3MgXAogICAgJiYgY3VybCAtZnNTTCBodHRwczovL3JhaW5ib3dyb2JvdGljcy5naXRodWIuaW8vcmItc2RrL3JiLXNkay1hcHQtcmVwby5ncGcua2V5IC1vIC9ldGMvYXB0L2tleXJpbmdzL3JiLXNkay5hc2MgXAogICAgJiYgcHJpbnRmICdkZWIgW3NpZ25lZC1ieT0vZXRjL2FwdC9rZXlyaW5ncy9yYi1zZGsuYXNjXSBodHRwczovL3JhaW5ib3dyb2JvdGljcy5naXRodWIuaW8vcmItc2RrICVzIG1haW5cbicgc3RhYmxlIGRldiA+IC9ldGMvYXB0L3NvdXJjZXMubGlzdC5kL3JiLXNkay5saXN0IFwKICAgICYmIGFwdC1nZXQgdXBkYXRlIFwKICAgICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyAicmFpbmJvdy1yYi1zZGske1JCX1NES19WRVJTSU9OOis9JFJCX1NES19WRVJTSU9OfSIgInJhaW5ib3ctcmItc2RrLWRldiR7UkJfU0RLX1ZFUlNJT046Kz0kUkJfU0RLX1ZFUlNJT059IiBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCgpXT1JLRElSIC9wbHVnaW4KCkNNRCBbImJhc2giXQo=","docker/Dockerfile.dev":"IyBEZXYtb25seSBjb250YWluZXIgZm9yIHRoZSBST1MyIHBsdWdpbiBiYWNrIGVuZC4KIyBNYXRjaGVzIHRoZSBNdXNjYXQgcm9ib3QgYmFja2VuZDogUk9TMiBKYXp6eSArIFB5dGhvbiAzLjEyIChVYnVudHUgMjQuMDQpLgojIFVzZWQgYnkgYG11c2NhdC1wayBkZXY6YmFja2Ag4oCUIE5PVCBzaGlwcGVkIGluIHRoZSBwbHVnaW4gWklQLgpGUk9NIHJvczpqYXp6eS1yb3MtYmFzZQpMQUJFTCBjb20ucmFpbmJvdy1yb2JvdGljcy5tdXNjYXQtcGs9InRydWUiCgpSVU4gYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzIFwKICAgICAgcHl0aG9uMy1waXAgXAogICAgICBweXRob24zLWNvbGNvbi1jb21tb24tZXh0ZW5zaW9ucyBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCiMgUmFpbmJvdyBSb2JvdGljcyBDKysgU0RLIGZvciBmaW5kX3BhY2thZ2UocmJfc2RrKS4gbXVzY2F0LXBrIHBhc3NlcyB0aGUgdmVyc2lvbiBwaW5uZWQgaW4gdGhlCiMgcHJvamVjdCdzIENNYWtlTGlzdHMudHh0IChmaW5kX3BhY2thZ2UocmJfc2RrIDx2ZXI+IEVYQUNUKSk7IHdpdGhvdXQgYSBwaW4gKFJPUyAyIHJjbHB5LCBgbXVzY2F0LXBrIG1jcGAKIyBvdXRzaWRlIGEgcHJvamVjdCkgdGhlIG5ld2VzdCBTREsgaXMgaW5zdGFsbGVkLiBSdW50aW1lIGFuZCAtZGV2IGFyZSBpbnN0YWxsZWQgdG9nZXRoZXIgYXQgb25lIHZlcnNpb24uCkFSRyBSQl9TREtfVkVSU0lPTj0KUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBjYS1jZXJ0aWZpY2F0ZXMgY3VybCBcCiAgICAmJiBpbnN0YWxsIC1kIC9ldGMvYXB0L2tleXJpbmdzIFwKICAgICYmIGN1cmwgLWZzU0wgaHR0cHM6Ly9yYWluYm93cm9ib3RpY3MuZ2l0aHViLmlvL3JiLXNkay9yYi1zZGstYXB0LXJlcG8uZ3BnLmtleSAtbyAvZXRjL2FwdC9rZXlyaW5ncy9yYi1zZGsuYXNjIFwKICAgICYmIHByaW50ZiAnZGViIFtzaWduZWQtYnk9L2V0Yy9hcHQva2V5cmluZ3MvcmItc2RrLmFzY10gaHR0cHM6Ly9yYWluYm93cm9ib3RpY3MuZ2l0aHViLmlvL3JiLXNkayAlcyBtYWluXG4nIHN0YWJsZSBkZXYgPiAvZXRjL2FwdC9zb3VyY2VzLmxpc3QuZC9yYi1zZGsubGlzdCBcCiAgICAmJiBhcHQtZ2V0IHVwZGF0ZSBcCiAgICAmJiBhcHQtZ2V0IGluc3RhbGwgLXkgLS1uby1pbnN0YWxsLXJlY29tbWVuZHMgInJhaW5ib3ctcmItc2RrJHtSQl9TREtfVkVSU0lPTjorPSRSQl9TREtfVkVSU0lPTn0iICJyYWluYm93LXJiLXNkay1kZXYke1JCX1NES19WRVJTSU9OOis9JFJCX1NES19WRVJTSU9OfSIgXAogICAgJiYgcm0gLXJmIC92YXIvbGliL2FwdC9saXN0cy8qCgoKIyBgZG9ja2VyIGV4ZWNgIHNraXBzIC9yb3NfZW50cnlwb2ludC5zaCDigJQgc291cmNlIFJPUyBmb3IgdGhlIGxvZ2luIHNoZWxscyBkZXY6YmFjayBydW5zLgpSVU4gZWNobyAiLiAvb3B0L3Jvcy8ke1JPU19ESVNUUk99L3NldHVwLnNoIiA+IC9ldGMvcHJvZmlsZS5kL3Jvcy5zaAoKV09SS0RJUiAvcGx1Z2luCgpDTUQgWyJiYXNoIl0K","docker/Dockerfile.python":"IyBEZXYvYnVpbGQgY29udGFpbmVyIGZvciB0aGUgUHl0aG9uIHBsdWdpbiBiYWNrIGVuZC4KIyBNYXRjaGVzIHRoZSBNdXNjYXQgcm9ib3QgYmFja2VuZDogVWJ1bnR1IDI0LjA0ICsgUHl0aG9uIDMuMTIuCiMgVXNlZCBieSBgbXVzY2F0LXBrIGRldjpiYWNrYCAoaG90LXJlbG9hZCkgYW5kIGBtdXNjYXQtcGsgYnVpbGRgIChsb2NrICsgd2hlZWwgdmVuZG9yKS4KIyBOT1Qgc2hpcHBlZCBpbiB0aGUgcGx1Z2luIFpJUCDigJQgdGhlIHJvYm90IGluc3RhbGxzIGRlcHMgZnJvbSBkaXN0L3doZWVscy8gb2ZmbGluZS4KRlJPTSB1YnVudHU6MjQuMDQKTEFCRUwgY29tLnJhaW5ib3ctcm9ib3RpY3MubXVzY2F0LXBrPSJ0cnVlIgoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBcCiAgICAgIHB5dGhvbjMgXAogICAgICBweXRob24zLXBpcCBcCiAgICAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyogXAogICAgJiYgcGlwMyBpbnN0YWxsIHV2PT0wLjguMTggLS1icmVhay1zeXN0ZW0tcGFja2FnZXMKCiMgVE9ETyhjcHAtc2RrKTogdGhlIFB5dGhvbiBTREsgaXMgYSBweWJpbmQgd3JhcHBlciBvdmVyIHRoZSBjcHAgU0RLLCBzbyB0aGUKIyBjcHAgU0RLIHNoYXJlZCBsaWIgbXVzdCBiZSBwcmVzZW50IGZvciB0aGUgcHl0aG9uIG1vZHVsZSB0byBsb2FkLiBJbnN0YWxsIHRoZQojIHJhaW5ib3cgY3BwIFNESyAoYXB0LCBwaW5uZWQgdG8gdGhlIHJvYm90J3MgdmVyc2lvbikgaGVyZSBvbmNlIGl0IGV4aXN0cy4KCgpXT1JLRElSIC9wbHVnaW4KCkNNRCBbImJhc2giXQo="};