@decaf-ts/integrations 0.4.1-2 → 0.5.1

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 (50) hide show
  1. package/dist/integrations.cjs +4 -4
  2. package/dist/integrations.js +4 -4
  3. package/lib/cjs/feature-flags/services/FeatureFlag.service.cjs +13 -5
  4. package/lib/cjs/graph/engine/errors/GraphBreakSignal.cjs +37 -0
  5. package/lib/cjs/graph/engine/errors/index.cjs +3 -2
  6. package/lib/cjs/graph/engine/execution/BreakGraphNodeExecutor.cjs +22 -0
  7. package/lib/cjs/graph/engine/execution/index.cjs +3 -2
  8. package/lib/cjs/graph/engine/index.cjs +4 -2
  9. package/lib/cjs/graph/engine/loops/ForeachGraphNodeExecutor.cjs +54 -19
  10. package/lib/cjs/graph/engine/types.cjs +2 -2
  11. package/lib/cjs/graph/shared/nodes/flow-control.cjs +41 -3
  12. package/lib/cjs/index.cjs +3 -3
  13. package/lib/cjs/nest/graph/GraphExecutorRegistryFactory.cjs +7 -2
  14. package/lib/cjs/nest/keycloakAuthHandler.cjs +5 -3
  15. package/lib/cjs/nest/utils.cjs +15 -4
  16. package/lib/cjs/plugins/superset/templates.cjs +14 -20
  17. package/lib/esm/feature-flags/services/FeatureFlag.service.js +13 -5
  18. package/lib/esm/graph/engine/errors/GraphBreakSignal.js +32 -0
  19. package/lib/esm/graph/engine/errors/index.js +2 -1
  20. package/lib/esm/graph/engine/execution/BreakGraphNodeExecutor.js +17 -0
  21. package/lib/esm/graph/engine/execution/index.js +2 -1
  22. package/lib/esm/graph/engine/index.js +3 -1
  23. package/lib/esm/graph/engine/loops/ForeachGraphNodeExecutor.js +53 -18
  24. package/lib/esm/graph/engine/types.js +1 -1
  25. package/lib/esm/graph/shared/nodes/flow-control.js +39 -1
  26. package/lib/esm/index.js +3 -3
  27. package/lib/esm/nest/graph/GraphExecutorRegistryFactory.js +7 -2
  28. package/lib/esm/nest/keycloakAuthHandler.js +4 -2
  29. package/lib/esm/nest/utils.js +14 -3
  30. package/lib/esm/plugins/superset/templates.js +13 -19
  31. package/lib/types/graph/engine/errors/GraphBreakSignal.d.cts +28 -0
  32. package/lib/types/graph/engine/errors/GraphBreakSignal.d.mts +28 -0
  33. package/lib/types/graph/engine/errors/index.d.cts +1 -0
  34. package/lib/types/graph/engine/errors/index.d.mts +1 -0
  35. package/lib/types/graph/engine/execution/BreakGraphNodeExecutor.d.cts +22 -0
  36. package/lib/types/graph/engine/execution/BreakGraphNodeExecutor.d.mts +22 -0
  37. package/lib/types/graph/engine/execution/index.d.cts +1 -0
  38. package/lib/types/graph/engine/execution/index.d.mts +1 -0
  39. package/lib/types/graph/engine/index.d.cts +2 -0
  40. package/lib/types/graph/engine/index.d.mts +2 -0
  41. package/lib/types/graph/engine/loops/ForeachGraphNodeExecutor.d.cts +11 -3
  42. package/lib/types/graph/engine/loops/ForeachGraphNodeExecutor.d.mts +11 -3
  43. package/lib/types/graph/engine/types.d.cts +6 -0
  44. package/lib/types/graph/engine/types.d.mts +6 -0
  45. package/lib/types/graph/shared/nodes/flow-control.d.cts +12 -1
  46. package/lib/types/graph/shared/nodes/flow-control.d.mts +12 -1
  47. package/lib/types/index.d.cts +2 -2
  48. package/lib/types/index.d.mts +2 -2
  49. package/package.json +6 -3
  50. package/plugins/superset/Dockerfile +9 -9
@@ -101,25 +101,19 @@ def patch_react_import(content: str) -> str:
101
101
  def locate_embedded_component(
102
102
  content: str,
103
103
  ) -> tuple[re.Match[str], str]:
104
- names = [
105
- "EmbeddedLazyDashboardPage",
106
- "EmbededLazyDashboardPage",
107
- ]
108
-
109
- for name in names:
110
- pattern = re.compile(
111
- rf"const {name} = \\(\\) => \\{{.*?\\n\\}};\\n"
112
- rf"(?=const EmbeddedRoute)",
113
- re.DOTALL,
114
- )
104
+ pattern = re.compile(
105
+ r"const\\s+([A-Za-z0-9_]+)\\s*=\\s*\\(\\)\\s*=>\\s*\\{.*?\\};\\s*"
106
+ r"(?=const\\s+EmbeddedRoute)",
107
+ re.DOTALL,
108
+ )
115
109
 
116
- match = pattern.search(content)
110
+ match = pattern.search(content)
117
111
 
118
- if match:
119
- return match, name
112
+ if match:
113
+ return match, match.group(1)
120
114
 
121
115
  raise PatchError(
122
- "Could not find EmbeddedLazyDashboardPage before EmbeddedRoute"
116
+ "Could not find an embedded dashboard component before EmbeddedRoute"
123
117
  )
124
118
 
125
119
 
@@ -136,7 +130,7 @@ def patch_frontend(frontend_path: Path) -> None:
136
130
  content
137
131
  )
138
132
 
139
- replacement_component = \`// SUPERSET_SWITCHABLE_EMBED_PATCH
133
+ replacement_component = """// SUPERSET_SWITCHABLE_EMBED_PATCH
140
134
  //
141
135
  // Allows the existing embedded Superset document to replace DashboardPage
142
136
  // without navigating or recreating the iframe.
@@ -163,7 +157,7 @@ type DashboardSwitchHandler = (
163
157
 
164
158
  let dashboardSwitchHandler: DashboardSwitchHandler | undefined;
165
159
 
166
- const \${component_name} = () => {
160
+ const __COMPONENT_NAME__ = () => {
167
161
  const uiConfig = useUiConfig();
168
162
 
169
163
  const [dashboardId, setDashboardId] = useState<string | null>(
@@ -250,7 +244,7 @@ const \${component_name} = () => {
250
244
  />
251
245
  );
252
246
  };
253
- \`
247
+ """.replace("__COMPONENT_NAME__", component_name)
254
248
 
255
249
  content = (
256
250
  content[: component_match.start()]
@@ -837,4 +831,4 @@ export function supersetPatchFiles() {
837
831
  { path: "README.md", content: README },
838
832
  ];
839
833
  }
840
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3BsdWdpbnMvc3VwZXJzZXQvdGVtcGxhdGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsdUJBQXVCLEVBQUUsc0JBQW1CO0FBV3pFLE1BQU0sY0FBYyxHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQXNtQnRCLENBQUM7QUFFRixNQUFNLGVBQWUsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0F5Q3ZCLENBQUM7QUFFRixNQUFNLFlBQVksR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBMkJwQixDQUFDO0FBRUYsTUFBTSxpQkFBaUIsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FvQnpCLENBQUM7QUFFRixNQUFNLGtCQUFrQixHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBK0IxQixDQUFDO0FBRUYsTUFBTSxlQUFlLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBZ0N2QixDQUFDO0FBRUYsTUFBTSxNQUFNLEdBQUcsS0FBSyxrQkFBa0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7V0FxQzNCLHVCQUF1QjtDQUNqQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCO0lBQ2hDLE9BQU87UUFDTCxFQUFFLElBQUksRUFBRSxxQ0FBcUMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUU7UUFDMUYsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFO1FBQy9FLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRTtRQUN2RSxFQUFFLElBQUksRUFBRSxrQ0FBa0MsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRTtRQUMxRixFQUFFLElBQUksRUFBRSwwQkFBMEIsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRTtRQUNuRixFQUFFLElBQUksRUFBRSw2QkFBNkIsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUU7UUFDbkYsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUU7S0FDdkMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBtb2R1bGUgaW50ZWdyYXRpb25zL3BsdWdpbnMvc3VwZXJzZXQvdGVtcGxhdGVzXG4gKiBAc3VtbWFyeSBQYXRjaCBhbmQgYnVpbGQgc2NyaXB0IHRlbXBsYXRlcyBmb3IgdGhlIFN1cGVyc2V0IGVtYmVkIHBsdWdpbi5cbiAqIEBkZXNjcmlwdGlvbiBIb2xkcyBhbGwgcGF0Y2ggc2NyaXB0cyAoUHl0aG9uICsgQmFzaCkgYW5kIGJ1aWxkIHNjcmlwdHMgYXNcbiAqIHN0cmluZyB0ZW1wbGF0ZXMuIFRoZXNlIGFyZSBtYXRlcmlhbGl6ZWQgb250byBkaXNrIGJ5IHRoZSBpbnN0YWxsZXIuIERlY2FmXG4gKiBkb2VzIG5vdCBnZW5lcmF0ZSBuZXcgU3VwZXJzZXQgc291cmNlIOKAlCBpdCBwYXRjaGVzIGV4aXN0aW5nIGludGVybmFsIGZpbGVzXG4gKiAoYHN1cGVyc2V0LWZyb250ZW5kL3NyYy9lbWJlZGRlZC9pbmRleC50c3hgIGFuZFxuICogYHN1cGVyc2V0LWVtYmVkZGVkLXNkay9zcmMvaW5kZXgudHNgKSBmb2xsb3dpbmcgdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvblxuICogZnJvbSBERUNBRi00MCDCpzkuXG4gKlxuICogVGhlIHBhdGNoIGFkZHMgYSBgc3dpdGNoRGFzaGJvYXJkYCBtZXRob2QgdG8gU3VwZXJzZXQncyBleGlzdGluZyBTd2l0Y2hib2FyZFxuICogY2hhbm5lbCwgcmVwbGFjaW5nIG9ubHkgYERhc2hib2FyZFBhZ2VgIHdoaWxlIGtlZXBpbmcgdGhlIGlmcmFtZSBlbGVtZW50LFxuICogZG9jdW1lbnQsIGNvbnRlbnRXaW5kb3csIFJlYWN0IHJ1bnRpbWUsIGFuZCBtZXNzYWdlIGNoYW5uZWwgYWxpdmUuXG4gKi9cbmltcG9ydCB7IFNVUEVSU0VUX1BMVUdJTl9JRCwgU1VQRVJTRVRfUExVR0lOX1ZFUlNJT04gfSBmcm9tIFwiLi9tYW5pZmVzdFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN1cGVyc2V0UGF0Y2hGaWxlIHtcbiAgLyoqIFJlbGF0aXZlIHBhdGggd2l0aGluIHRoZSB0YXJnZXQgZGlyZWN0b3J5LiAqL1xuICBwYXRoOiBzdHJpbmc7XG4gIC8qKiBGaWxlIGNvbnRlbnRzLiAqL1xuICBjb250ZW50OiBzdHJpbmc7XG4gIC8qKiBXaGV0aGVyIHRvIG1hcmsgdGhlIGZpbGUgZXhlY3V0YWJsZSBvbiBQT1NJWC4gKi9cbiAgZXhlY3V0YWJsZT86IGJvb2xlYW47XG59XG5cbmNvbnN0IEFQUExZX1BBVENIX1BZID0gYCMhL3Vzci9iaW4vZW52IHB5dGhvbjNcblxuZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCBhbm5vdGF0aW9uc1xuXG5pbXBvcnQgYXJncGFyc2VcbmltcG9ydCByZVxuaW1wb3J0IHN5c1xuZnJvbSBwYXRobGliIGltcG9ydCBQYXRoXG5cblxuRlJPTlRFTkRfRklMRSA9IFBhdGgoXCJzdXBlcnNldC1mcm9udGVuZC9zcmMvZW1iZWRkZWQvaW5kZXgudHN4XCIpXG5TREtfRklMRSA9IFBhdGgoXCJzdXBlcnNldC1lbWJlZGRlZC1zZGsvc3JjL2luZGV4LnRzXCIpXG5cblxuY2xhc3MgUGF0Y2hFcnJvcihSdW50aW1lRXJyb3IpOlxuICAgIHBhc3NcblxuXG5kZWYgcmVwbGFjZV9vbmNlKFxuICAgIGNvbnRlbnQ6IHN0cixcbiAgICBvbGQ6IHN0cixcbiAgICBuZXc6IHN0cixcbiAgICBkZXNjcmlwdGlvbjogc3RyLFxuKSAtPiBzdHI6XG4gICAgY291bnQgPSBjb250ZW50LmNvdW50KG9sZClcblxuICAgIGlmIGNvdW50ICE9IDE6XG4gICAgICAgIHJhaXNlIFBhdGNoRXJyb3IoXG4gICAgICAgICAgICBmXCJ7ZGVzY3JpcHRpb259OiBleHBlY3RlZCBleGFjdGx5IG9uZSBvY2N1cnJlbmNlLCBmb3VuZCB7Y291bnR9XCJcbiAgICAgICAgKVxuXG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShvbGQsIG5ldywgMSlcblxuXG5kZWYgcmVwbGFjZV9yZWdleF9vbmNlKFxuICAgIGNvbnRlbnQ6IHN0cixcbiAgICBwYXR0ZXJuOiByZS5QYXR0ZXJuW3N0cl0sXG4gICAgcmVwbGFjZW1lbnQ6IHN0cixcbiAgICBkZXNjcmlwdGlvbjogc3RyLFxuKSAtPiBzdHI6XG4gICAgdXBkYXRlZCwgY291bnQgPSBwYXR0ZXJuLnN1Ym4ocmVwbGFjZW1lbnQsIGNvbnRlbnQsIGNvdW50PTEpXG5cbiAgICBpZiBjb3VudCAhPSAxOlxuICAgICAgICByYWlzZSBQYXRjaEVycm9yKFxuICAgICAgICAgICAgZlwie2Rlc2NyaXB0aW9ufTogZXhwZWN0ZWQgZXhhY3RseSBvbmUgbWF0Y2gsIGZvdW5kIHtjb3VudH1cIlxuICAgICAgICApXG5cbiAgICByZXR1cm4gdXBkYXRlZFxuXG5cbmRlZiBwYXRjaF9yZWFjdF9pbXBvcnQoY29udGVudDogc3RyKSAtPiBzdHI6XG4gICAgcmVhY3RfaW1wb3J0X3BhdHRlcm4gPSByZS5jb21waWxlKFxuICAgICAgICByXCJpbXBvcnRcXFxccypcXFxce1xcXFxzKihbXn1dKylcXFxccypcXFxcfVxcXFxzKmZyb21cXFxccyoncmVhY3QnO1wiXG4gICAgKVxuXG4gICAgbWF0Y2ggPSByZWFjdF9pbXBvcnRfcGF0dGVybi5zZWFyY2goY29udGVudClcblxuICAgIGlmIG5vdCBtYXRjaDpcbiAgICAgICAgcmFpc2UgUGF0Y2hFcnJvcihcIkNvdWxkIG5vdCBsb2NhdGUgdGhlIG5hbWVkIFJlYWN0IGltcG9ydFwiKVxuXG4gICAgaW1wb3J0cyA9IFtcbiAgICAgICAgdmFsdWUuc3RyaXAoKVxuICAgICAgICBmb3IgdmFsdWUgaW4gbWF0Y2guZ3JvdXAoMSkucmVwbGFjZShcIlxcXFxuXCIsIFwiIFwiKS5zcGxpdChcIixcIilcbiAgICAgICAgaWYgdmFsdWUuc3RyaXAoKVxuICAgIF1cblxuICAgIHJlcXVpcmVkX2ltcG9ydHMgPSBbXCJsYXp5XCIsIFwiU3VzcGVuc2VcIiwgXCJ1c2VFZmZlY3RcIiwgXCJ1c2VTdGF0ZVwiXVxuXG4gICAgZm9yIHJlcXVpcmVkX2ltcG9ydCBpbiByZXF1aXJlZF9pbXBvcnRzOlxuICAgICAgICBpZiByZXF1aXJlZF9pbXBvcnQgbm90IGluIGltcG9ydHM6XG4gICAgICAgICAgICBpbXBvcnRzLmFwcGVuZChyZXF1aXJlZF9pbXBvcnQpXG5cbiAgICByZXBsYWNlbWVudCA9IChcbiAgICAgICAgXCJpbXBvcnQge1xcXFxuICBcIlxuICAgICAgICArIFwiLFxcXFxuICBcIi5qb2luKGltcG9ydHMpXG4gICAgICAgICsgXCIsXFxcXG59IGZyb20gJ3JlYWN0JztcIlxuICAgIClcblxuICAgIHJldHVybiAoXG4gICAgICAgIGNvbnRlbnRbOiBtYXRjaC5zdGFydCgpXVxuICAgICAgICArIHJlcGxhY2VtZW50XG4gICAgICAgICsgY29udGVudFttYXRjaC5lbmQoKSA6XVxuICAgIClcblxuXG5kZWYgbG9jYXRlX2VtYmVkZGVkX2NvbXBvbmVudChcbiAgICBjb250ZW50OiBzdHIsXG4pIC0+IHR1cGxlW3JlLk1hdGNoW3N0cl0sIHN0cl06XG4gICAgbmFtZXMgPSBbXG4gICAgICAgIFwiRW1iZWRkZWRMYXp5RGFzaGJvYXJkUGFnZVwiLFxuICAgICAgICBcIkVtYmVkZWRMYXp5RGFzaGJvYXJkUGFnZVwiLFxuICAgIF1cblxuICAgIGZvciBuYW1lIGluIG5hbWVzOlxuICAgICAgICBwYXR0ZXJuID0gcmUuY29tcGlsZShcbiAgICAgICAgICAgIHJmXCJjb25zdCB7bmFtZX0gPSBcXFxcKFxcXFwpID0+IFxcXFx7ey4qP1xcXFxuXFxcXH19O1xcXFxuXCJcbiAgICAgICAgICAgIHJmXCIoPz1jb25zdCBFbWJlZGRlZFJvdXRlKVwiLFxuICAgICAgICAgICAgcmUuRE9UQUxMLFxuICAgICAgICApXG5cbiAgICAgICAgbWF0Y2ggPSBwYXR0ZXJuLnNlYXJjaChjb250ZW50KVxuXG4gICAgICAgIGlmIG1hdGNoOlxuICAgICAgICAgICAgcmV0dXJuIG1hdGNoLCBuYW1lXG5cbiAgICByYWlzZSBQYXRjaEVycm9yKFxuICAgICAgICBcIkNvdWxkIG5vdCBmaW5kIEVtYmVkZGVkTGF6eURhc2hib2FyZFBhZ2UgYmVmb3JlIEVtYmVkZGVkUm91dGVcIlxuICAgIClcblxuXG5kZWYgcGF0Y2hfZnJvbnRlbmQoZnJvbnRlbmRfcGF0aDogUGF0aCkgLT4gTm9uZTpcbiAgICBjb250ZW50ID0gZnJvbnRlbmRfcGF0aC5yZWFkX3RleHQoZW5jb2Rpbmc9XCJ1dGYtOFwiKVxuXG4gICAgaWYgXCJTVVBFUlNFVF9TV0lUQ0hBQkxFX0VNQkVEX1BBVENIXCIgaW4gY29udGVudDpcbiAgICAgICAgcHJpbnQoZlwiQWxyZWFkeSBwYXRjaGVkOiB7ZnJvbnRlbmRfcGF0aH1cIilcbiAgICAgICAgcmV0dXJuXG5cbiAgICBjb250ZW50ID0gcGF0Y2hfcmVhY3RfaW1wb3J0KGNvbnRlbnQpXG5cbiAgICBjb21wb25lbnRfbWF0Y2gsIGNvbXBvbmVudF9uYW1lID0gbG9jYXRlX2VtYmVkZGVkX2NvbXBvbmVudChcbiAgICAgICAgY29udGVudFxuICAgIClcblxuICAgIHJlcGxhY2VtZW50X2NvbXBvbmVudCA9IFxcYC8vIFNVUEVSU0VUX1NXSVRDSEFCTEVfRU1CRURfUEFUQ0hcbi8vXG4vLyBBbGxvd3MgdGhlIGV4aXN0aW5nIGVtYmVkZGVkIFN1cGVyc2V0IGRvY3VtZW50IHRvIHJlcGxhY2UgRGFzaGJvYXJkUGFnZVxuLy8gd2l0aG91dCBuYXZpZ2F0aW5nIG9yIHJlY3JlYXRpbmcgdGhlIGlmcmFtZS5cbi8vXG4vLyBTZWN1cml0eTpcbi8vIC0gVGhpcyBtZXRob2QgaXMgZXhwb3NlZCBvbmx5IHRocm91Z2ggU3VwZXJzZXQncyBleGlzdGluZyBTd2l0Y2hib2FyZFxuLy8gICBNZXNzYWdlQ2hhbm5lbC5cbi8vIC0gVGhlIGhvc3QgYXBwbGljYXRpb24gbXVzdCBvYnRhaW4gYSBndWVzdCB0b2tlbiBmb3IgdGhlIHRhcmdldCBkYXNoYm9hcmQuXG4vLyAtIFN1cGVyc2V0J3Mgbm9ybWFsIEFsbG93ZWQgRG9tYWlucyB2YWxpZGF0aW9uIHJlbWFpbnMgaW4gZWZmZWN0LlxuXG5pbnRlcmZhY2UgU3dpdGNoRGFzaGJvYXJkUGF5bG9hZCB7XG4gIGRhc2hib2FyZElkOiBzdHJpbmc7XG4gIGd1ZXN0VG9rZW46IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFN3aXRjaERhc2hib2FyZFJlc3VsdCB7XG4gIGRhc2hib2FyZElkOiBzdHJpbmc7XG4gIGFjY2VwdGVkOiB0cnVlO1xufVxuXG50eXBlIERhc2hib2FyZFN3aXRjaEhhbmRsZXIgPSAoXG4gIHBheWxvYWQ6IFN3aXRjaERhc2hib2FyZFBheWxvYWQsXG4pID0+IFByb21pc2U8U3dpdGNoRGFzaGJvYXJkUmVzdWx0PjtcblxubGV0IGRhc2hib2FyZFN3aXRjaEhhbmRsZXI6IERhc2hib2FyZFN3aXRjaEhhbmRsZXIgfCB1bmRlZmluZWQ7XG5cbmNvbnN0IFxcJHtjb21wb25lbnRfbmFtZX0gPSAoKSA9PiB7XG4gIGNvbnN0IHVpQ29uZmlnID0gdXNlVWlDb25maWcoKTtcblxuICBjb25zdCBbZGFzaGJvYXJkSWQsIHNldERhc2hib2FyZElkXSA9IHVzZVN0YXRlPHN0cmluZyB8IG51bGw+KFxuICAgIGJvb3RzdHJhcERhdGEuZW1iZWRkZWQhLmRhc2hib2FyZF9pZCxcbiAgKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGRhc2hib2FyZFN3aXRjaEhhbmRsZXIgPSBhc3luYyAoe1xuICAgICAgZGFzaGJvYXJkSWQ6IHJlcXVlc3RlZERhc2hib2FyZElkLFxuICAgICAgZ3Vlc3RUb2tlbixcbiAgICB9OiBTd2l0Y2hEYXNoYm9hcmRQYXlsb2FkKSA9PiB7XG4gICAgICBjb25zdCBuZXh0RGFzaGJvYXJkSWQgPSByZXF1ZXN0ZWREYXNoYm9hcmRJZC50cmltKCk7XG5cbiAgICAgIGlmICghbmV4dERhc2hib2FyZElkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnZGFzaGJvYXJkSWQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBndWVzdFRva2VuICE9PSAnc3RyaW5nJyB8fFxuICAgICAgICBndWVzdFRva2VuLnRyaW0oKS5sZW5ndGggPT09IDBcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ2d1ZXN0VG9rZW4gbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBzZXREYXNoYm9hcmRJZChudWxsKTtcblxuICAgICAgZGlzcGxheWVkVW5hdXRob3JpemVkVG9hc3QgPSBmYWxzZTtcblxuICAgICAgc2V0dXBHdWVzdENsaWVudChndWVzdFRva2VuKTtcblxuICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4ocmVzb2x2ZSA9PiB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gcmVzb2x2ZSgpKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXREYXNoYm9hcmRJZChuZXh0RGFzaGJvYXJkSWQpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXNoYm9hcmRJZDogbmV4dERhc2hib2FyZElkLFxuICAgICAgICBhY2NlcHRlZDogdHJ1ZSxcbiAgICAgIH07XG4gICAgfTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkYXNoYm9hcmRTd2l0Y2hIYW5kbGVyID0gdW5kZWZpbmVkO1xuICAgIH07XG4gIH0sIFtdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghdWlDb25maWc/LmVtaXREYXRhTWFza3MpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgbGV0IHByZXZpb3VzRGF0YU1hc2sgPSBzdG9yZS5nZXRTdGF0ZSgpLmRhdGFNYXNrO1xuXG4gICAgcmV0dXJuIHN0b3JlLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50RGF0YU1hc2sgPSBzdG9yZS5nZXRTdGF0ZSgpLmRhdGFNYXNrO1xuXG4gICAgICBpZiAocHJldmlvdXNEYXRhTWFzayAhPT0gY3VycmVudERhdGFNYXNrKSB7XG4gICAgICAgIFN3aXRjaGJvYXJkLmVtaXQoJ29ic2VydmVEYXRhTWFzaycsIHtcbiAgICAgICAgICAuLi5jdXJyZW50RGF0YU1hc2ssXG4gICAgICAgICAgLi4uZ2V0RGF0YU1hc2tDaGFuZ2VUcmlnZ2VyKFxuICAgICAgICAgICAgY3VycmVudERhdGFNYXNrLFxuICAgICAgICAgICAgcHJldmlvdXNEYXRhTWFzayxcbiAgICAgICAgICApLFxuICAgICAgICB9KTtcblxuICAgICAgICBwcmV2aW91c0RhdGFNYXNrID0gY3VycmVudERhdGFNYXNrO1xuICAgICAgfVxuICAgIH0pO1xuICB9LCBbdWlDb25maWc/LmVtaXREYXRhTWFza3NdKTtcblxuICBpZiAoIWRhc2hib2FyZElkKSB7XG4gICAgcmV0dXJuIDxMb2FkaW5nIC8+O1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICA8TGF6eURhc2hib2FyZFBhZ2VcbiAgICAgIGtleT17ZGFzaGJvYXJkSWR9XG4gICAgICBpZE9yU2x1Zz17ZGFzaGJvYXJkSWR9XG4gICAgLz5cbiAgKTtcbn07XG5cXGBcblxuICAgIGNvbnRlbnQgPSAoXG4gICAgICAgIGNvbnRlbnRbOiBjb21wb25lbnRfbWF0Y2guc3RhcnQoKV1cbiAgICAgICAgKyByZXBsYWNlbWVudF9jb21wb25lbnRcbiAgICAgICAgKyBjb250ZW50W2NvbXBvbmVudF9tYXRjaC5lbmQoKSA6XVxuICAgIClcblxuICAgIHN3aXRjaGJvYXJkX2FuY2hvcl9jYW5kaWRhdGVzID0gW1xuICAgICAgICAoXG4gICAgICAgICAgICBcIiAgICBTd2l0Y2hib2FyZC5kZWZpbmVNZXRob2QoXCJcbiAgICAgICAgICAgIFwiJ2dldFNjcm9sbFNpemUnLCBlbWJlZGRlZEFwaS5nZXRTY3JvbGxTaXplKTtcIlxuICAgICAgICApLFxuICAgICAgICAoXG4gICAgICAgICAgICBcIiAgICBTd2l0Y2hib2FyZC5kZWZpbmVNZXRob2QoXFxcXG5cIlxuICAgICAgICAgICAgXCIgICAgICAnZ2V0U2Nyb2xsU2l6ZScsXFxcXG5cIlxuICAgICAgICAgICAgXCIgICAgICBlbWJlZGRlZEFwaS5nZXRTY3JvbGxTaXplLFxcXFxuXCJcbiAgICAgICAgICAgIFwiICAgICk7XCJcbiAgICAgICAgKSxcbiAgICBdXG5cbiAgICBzd2l0Y2hib2FyZF9tZXRob2QgPSBcIlwiXCIgICAgU3dpdGNoYm9hcmQuZGVmaW5lTWV0aG9kKFxuICAgICAgJ3N3aXRjaERhc2hib2FyZCcsXG4gICAgICBhc3luYyAoXG4gICAgICAgIHBheWxvYWQ6IFN3aXRjaERhc2hib2FyZFBheWxvYWQsXG4gICAgICApOiBQcm9taXNlPFN3aXRjaERhc2hib2FyZFJlc3VsdD4gPT4ge1xuICAgICAgICBpZiAoIWRhc2hib2FyZFN3aXRjaEhhbmRsZXIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAnVGhlIGVtYmVkZGVkIGRhc2hib2FyZCBpcyBub3QgcmVhZHkgdG8gc3dpdGNoJyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhc2hib2FyZFN3aXRjaEhhbmRsZXIocGF5bG9hZCk7XG4gICAgICB9LFxuICAgICk7XG5cblwiXCJcIlxuXG4gICAgYW5jaG9yX2ZvdW5kID0gRmFsc2VcblxuICAgIGZvciBhbmNob3IgaW4gc3dpdGNoYm9hcmRfYW5jaG9yX2NhbmRpZGF0ZXM6XG4gICAgICAgIGlmIGNvbnRlbnQuY291bnQoYW5jaG9yKSA9PSAxOlxuICAgICAgICAgICAgY29udGVudCA9IGNvbnRlbnQucmVwbGFjZShcbiAgICAgICAgICAgICAgICBhbmNob3IsXG4gICAgICAgICAgICAgICAgc3dpdGNoYm9hcmRfbWV0aG9kICsgYW5jaG9yLFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBhbmNob3JfZm91bmQgPSBUcnVlXG4gICAgICAgICAgICBicmVha1xuXG4gICAgaWYgbm90IGFuY2hvcl9mb3VuZDpcbiAgICAgICAgcmFpc2UgUGF0Y2hFcnJvcihcbiAgICAgICAgICAgIFwiQ291bGQgbm90IGxvY2F0ZSB0aGUgZ2V0U2Nyb2xsU2l6ZSBTd2l0Y2hib2FyZCBtZXRob2RcIlxuICAgICAgICApXG5cbiAgICBmcm9udGVuZF9wYXRoLndyaXRlX3RleHQoY29udGVudCwgZW5jb2Rpbmc9XCJ1dGYtOFwiKVxuICAgIHByaW50KGZcIlBhdGNoZWQ6IHtmcm9udGVuZF9wYXRofVwiKVxuXG5cbmRlZiBwYXRjaF9ndWVzdF90b2tlbl9mZXRjaF90eXBlKGNvbnRlbnQ6IHN0cikgLT4gc3RyOlxuICAgIGNhbmRpZGF0ZXMgPSBbXG4gICAgICAgIFwiZXhwb3J0IHR5cGUgR3Vlc3RUb2tlbkZldGNoRm4gPSAoKSA9PiBQcm9taXNlPHN0cmluZz47XCIsXG4gICAgICAgIChcbiAgICAgICAgICAgIFwiZXhwb3J0IHR5cGUgR3Vlc3RUb2tlbkZldGNoRm4gPSBcIlxuICAgICAgICAgICAgXCIoKSA9PiBQcm9taXNlPHN0cmluZz47XCJcbiAgICAgICAgKSxcbiAgICBdXG5cbiAgICByZXBsYWNlbWVudCA9IFwiXCJcIi8vIFNVUEVSU0VUX1NXSVRDSEFCTEVfRU1CRURfU0RLX1BBVENIXG4vL1xuLy8gZGFzaGJvYXJkSWQgaXMgdW5kZWZpbmVkIGZvciB0aGUgaW5pdGlhbCBkYXNoYm9hcmQgYm9vdHN0cmFwLlxuLy8gQWZ0ZXIgYSBzdWNjZXNzZnVsIGRhc2hib2FyZCBzd2l0Y2gsIHRva2VuIHJlZnJlc2hlcyByZWNlaXZlIHRoZSBhY3RpdmVcbi8vIGRhc2hib2FyZCBVVUlELlxuZXhwb3J0IHR5cGUgR3Vlc3RUb2tlbkZldGNoRm4gPSAoXG4gIGRhc2hib2FyZElkPzogc3RyaW5nLFxuKSA9PiBQcm9taXNlPHN0cmluZz47XCJcIlwiXG5cbiAgICBmb3IgY2FuZGlkYXRlIGluIGNhbmRpZGF0ZXM6XG4gICAgICAgIGlmIGNvbnRlbnQuY291bnQoY2FuZGlkYXRlKSA9PSAxOlxuICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQsXG4gICAgICAgICAgICAgICAgMSxcbiAgICAgICAgICAgIClcblxuICAgIHJhaXNlIFBhdGNoRXJyb3IoXCJDb3VsZCBub3QgbG9jYXRlIEd1ZXN0VG9rZW5GZXRjaEZuXCIpXG5cblxuZGVmIHBhdGNoX2VtYmVkZGVkX2Rhc2hib2FyZF90eXBlKGNvbnRlbnQ6IHN0cikgLT4gc3RyOlxuICAgIHR5cGVfcGF0dGVybiA9IHJlLmNvbXBpbGUoXG4gICAgICAgIHJcIihleHBvcnRcXFxccysoPzppbnRlcmZhY2V8dHlwZSlcXFxccytFbWJlZGRlZERhc2hib2FyZFwiXG4gICAgICAgIHJcIi4qP1xcXFx7KSguKj8pKFxcXFxuXFxcXH07KVwiLFxuICAgICAgICByZS5ET1RBTEwsXG4gICAgKVxuXG4gICAgbWF0Y2ggPSB0eXBlX3BhdHRlcm4uc2VhcmNoKGNvbnRlbnQpXG5cbiAgICBpZiBub3QgbWF0Y2g6XG4gICAgICAgIHJhaXNlIFBhdGNoRXJyb3IoXG4gICAgICAgICAgICBcIkNvdWxkIG5vdCBsb2NhdGUgdGhlIEVtYmVkZGVkRGFzaGJvYXJkIHB1YmxpYyB0eXBlXCJcbiAgICAgICAgKVxuXG4gICAgYm9keSA9IG1hdGNoLmdyb3VwKDIpXG5cbiAgICBpZiBcInN3aXRjaERhc2hib2FyZDpcIiBpbiBib2R5OlxuICAgICAgICByZXR1cm4gY29udGVudFxuXG4gICAgbWV0aG9kID0gXCJcIlwiXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBEYXNoYm9hcmRQYWdlIGluIHRoZSBleGlzdGluZyBpZnJhbWUgZG9jdW1lbnQuXG4gICAqXG4gICAqIFRoZSB2YWx1ZSBtdXN0IGJlIHRoZSB0YXJnZXQgZGFzaGJvYXJkIFVVSUQvaWQgYWNjZXB0ZWQgYnlcbiAgICogRGFzaGJvYXJkUGFnZSwgbm90IHRoZSBlbWJlZGRlZC1jb25maWd1cmF0aW9uIFVVSUQgdXNlZCBpbiB0aGVcbiAgICogaW5pdGlhbCAvZW1iZWRkZWQvOnV1aWQgVVJMLlxuICAgKi9cbiAgc3dpdGNoRGFzaGJvYXJkOiAoXG4gICAgZGFzaGJvYXJkSWQ6IHN0cmluZyxcbiAgKSA9PiBQcm9taXNlPHtcbiAgICBkYXNoYm9hcmRJZDogc3RyaW5nO1xuICAgIGFjY2VwdGVkOiB0cnVlO1xuICB9PjtcblwiXCJcIlxuXG4gICAgdXBkYXRlZF90eXBlID0gKFxuICAgICAgICBtYXRjaC5ncm91cCgxKVxuICAgICAgICArIGJvZHkucnN0cmlwKClcbiAgICAgICAgKyBcIlxcXFxuXCJcbiAgICAgICAgKyBtZXRob2QucnN0cmlwKClcbiAgICAgICAgKyBtYXRjaC5ncm91cCgzKVxuICAgIClcblxuICAgIHJldHVybiAoXG4gICAgICAgIGNvbnRlbnRbOiBtYXRjaC5zdGFydCgpXVxuICAgICAgICArIHVwZGF0ZWRfdHlwZVxuICAgICAgICArIGNvbnRlbnRbbWF0Y2guZW5kKCkgOl1cbiAgICApXG5cblxuZGVmIHBhdGNoX2luaXRpYWxfZ3Vlc3RfdG9rZW5fZmV0Y2goY29udGVudDogc3RyKSAtPiBzdHI6XG4gICAgY2FuZGlkYXRlcyA9IFtcbiAgICAgICAgXCJmZXRjaEd1ZXN0VG9rZW4oKSxcIixcbiAgICAgICAgXCJhd2FpdCBmZXRjaEd1ZXN0VG9rZW4oKSxcIixcbiAgICBdXG5cbiAgICBmb3IgY2FuZGlkYXRlIGluIGNhbmRpZGF0ZXM6XG4gICAgICAgIGlmIGNvbnRlbnQuY291bnQoY2FuZGlkYXRlKSA+PSAxOlxuICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgICAgIFwiZmV0Y2hHdWVzdFRva2VuKClcIixcbiAgICAgICAgICAgICAgICAgICAgXCJmZXRjaEd1ZXN0VG9rZW4odW5kZWZpbmVkKVwiLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgMSxcbiAgICAgICAgICAgIClcblxuICAgIHJhaXNlIFBhdGNoRXJyb3IoXG4gICAgICAgIFwiQ291bGQgbm90IGxvY2F0ZSB0aGUgaW5pdGlhbCBmZXRjaEd1ZXN0VG9rZW4gY2FsbFwiXG4gICAgKVxuXG5cbmRlZiBwYXRjaF9ndWVzdF90b2tlbl9yZWZyZXNoKGNvbnRlbnQ6IHN0cikgLT4gc3RyOlxuICAgIHBhdHRlcm5zID0gW1xuICAgICAgICByZS5jb21waWxlKFxuICAgICAgICAgICAgclwiYXN5bmMgZnVuY3Rpb24gcmVmcmVzaEd1ZXN0VG9rZW5cXFxcKFxcXFwpIFxcXFx7XFxcXHMqXCJcbiAgICAgICAgICAgIHJcImNvbnN0IG5ld0d1ZXN0VG9rZW4gPSBhd2FpdCBmZXRjaEd1ZXN0VG9rZW5cXFxcKFxcXFwpO1xcXFxzKlwiXG4gICAgICAgICAgICByXCJvdXJQb3J0XFxcXC5lbWl0XFxcXChcIlxuICAgICAgICAgICAgclwiJ2d1ZXN0VG9rZW4nLFxcXFxzKlxcXFx7XFxcXHMqZ3Vlc3RUb2tlbjpcXFxccypuZXdHdWVzdFRva2VuXFxcXHMqXFxcXH1cIlxuICAgICAgICAgICAgclwiXFxcXCk7XFxcXHMqXCJcbiAgICAgICAgICAgIHJcInNldFRpbWVvdXRcXFxcKFwiXG4gICAgICAgICAgICByXCJyZWZyZXNoR3Vlc3RUb2tlbixcXFxccypcIlxuICAgICAgICAgICAgclwiZ2V0R3Vlc3RUb2tlblJlZnJlc2hUaW1pbmdcXFxcKG5ld0d1ZXN0VG9rZW5cXFxcKVwiXG4gICAgICAgICAgICByXCJcXFxcKTtcXFxccypcIlxuICAgICAgICAgICAgclwiXFxcXH1cIixcbiAgICAgICAgICAgIHJlLkRPVEFMTCxcbiAgICAgICAgKSxcbiAgICAgICAgcmUuY29tcGlsZShcbiAgICAgICAgICAgIHJcImNvbnN0IHJlZnJlc2hHdWVzdFRva2VuID0gYXN5bmMgXFxcXChcXFxcKSA9PiBcXFxce1xcXFxzKlwiXG4gICAgICAgICAgICByXCJjb25zdCBuZXdHdWVzdFRva2VuID0gYXdhaXQgZmV0Y2hHdWVzdFRva2VuXFxcXChcXFxcKTtcXFxccypcIlxuICAgICAgICAgICAgclwib3VyUG9ydFxcXFwuZW1pdFxcXFwoXCJcbiAgICAgICAgICAgIHJcIidndWVzdFRva2VuJyxcXFxccypcXFxce1xcXFxzKmd1ZXN0VG9rZW46XFxcXHMqbmV3R3Vlc3RUb2tlblxcXFxzKlxcXFx9XCJcbiAgICAgICAgICAgIHJcIlxcXFwpO1xcXFxzKlwiXG4gICAgICAgICAgICByXCJzZXRUaW1lb3V0XFxcXChcIlxuICAgICAgICAgICAgclwicmVmcmVzaEd1ZXN0VG9rZW4sXFxcXHMqXCJcbiAgICAgICAgICAgIHJcImdldEd1ZXN0VG9rZW5SZWZyZXNoVGltaW5nXFxcXChuZXdHdWVzdFRva2VuXFxcXClcIlxuICAgICAgICAgICAgclwiXFxcXCk7XFxcXHMqXCJcbiAgICAgICAgICAgIHJcIlxcXFx9O1wiLFxuICAgICAgICAgICAgcmUuRE9UQUxMLFxuICAgICAgICApLFxuICAgIF1cblxuICAgIHJlcGxhY2VtZW50ID0gXCJcIlwibGV0IGFjdGl2ZURhc2hib2FyZElkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVmcmVzaEd1ZXN0VG9rZW4oKSB7XG4gICAgY29uc3QgbmV3R3Vlc3RUb2tlbiA9IGF3YWl0IGZldGNoR3Vlc3RUb2tlbihcbiAgICAgIGFjdGl2ZURhc2hib2FyZElkLFxuICAgICk7XG5cbiAgICBvdXJQb3J0LmVtaXQoJ2d1ZXN0VG9rZW4nLCB7XG4gICAgICBndWVzdFRva2VuOiBuZXdHdWVzdFRva2VuLFxuICAgIH0pO1xuXG4gICAgc2V0VGltZW91dChcbiAgICAgIHJlZnJlc2hHdWVzdFRva2VuLFxuICAgICAgZ2V0R3Vlc3RUb2tlblJlZnJlc2hUaW1pbmcobmV3R3Vlc3RUb2tlbiksXG4gICAgKTtcbiAgfVwiXCJcIlxuXG4gICAgZm9yIHBhdHRlcm4gaW4gcGF0dGVybnM6XG4gICAgICAgIHVwZGF0ZWQsIGNvdW50ID0gcGF0dGVybi5zdWJuKFxuICAgICAgICAgICAgcmVwbGFjZW1lbnQsXG4gICAgICAgICAgICBjb250ZW50LFxuICAgICAgICAgICAgY291bnQ9MSxcbiAgICAgICAgKVxuXG4gICAgICAgIGlmIGNvdW50ID09IDE6XG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlZFxuXG4gICAgcmFpc2UgUGF0Y2hFcnJvcihcbiAgICAgICAgXCJDb3VsZCBub3QgbG9jYXRlIHRoZSBndWVzdC10b2tlbiByZWZyZXNoIGZ1bmN0aW9uXCJcbiAgICApXG5cblxuZGVmIHBhdGNoX3Nka19mdW5jdGlvbnMoY29udGVudDogc3RyKSAtPiBzdHI6XG4gICAgYW5jaG9yX2NhbmRpZGF0ZXMgPSBbXG4gICAgICAgIChcbiAgICAgICAgICAgIFwiICBjb25zdCBnZXRTY3JvbGxTaXplID0gKCkgPT4gXCJcbiAgICAgICAgICAgIFwib3VyUG9ydC5nZXQ8U2l6ZT4oJ2dldFNjcm9sbFNpemUnKTtcIlxuICAgICAgICApLFxuICAgICAgICAoXG4gICAgICAgICAgICBcIiAgY29uc3QgZ2V0U2Nyb2xsU2l6ZSA9ICgpID0+XFxcXG5cIlxuICAgICAgICAgICAgXCIgICAgb3VyUG9ydC5nZXQ8U2l6ZT4oJ2dldFNjcm9sbFNpemUnKTtcIlxuICAgICAgICApLFxuICAgIF1cblxuICAgIHN3aXRjaF9mdW5jdGlvbiA9IFwiXCJcIiAgY29uc3Qgc3dpdGNoRGFzaGJvYXJkID0gYXN5bmMgKFxuICAgIGRhc2hib2FyZElkOiBzdHJpbmcsXG4gICk6IFByb21pc2U8e1xuICAgIGRhc2hib2FyZElkOiBzdHJpbmc7XG4gICAgYWNjZXB0ZWQ6IHRydWU7XG4gIH0+ID0+IHtcbiAgICBjb25zdCBub3JtYWxpemVkRGFzaGJvYXJkSWQgPSBkYXNoYm9hcmRJZC50cmltKCk7XG5cbiAgICBpZiAoIW5vcm1hbGl6ZWREYXNoYm9hcmRJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnZGFzaGJvYXJkSWQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBndWVzdFRva2VuID0gYXdhaXQgZmV0Y2hHdWVzdFRva2VuKFxuICAgICAgbm9ybWFsaXplZERhc2hib2FyZElkLFxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvdXJQb3J0LmdldDx7XG4gICAgICBkYXNoYm9hcmRJZDogc3RyaW5nO1xuICAgICAgYWNjZXB0ZWQ6IHRydWU7XG4gICAgfT4oJ3N3aXRjaERhc2hib2FyZCcsIHtcbiAgICAgIGRhc2hib2FyZElkOiBub3JtYWxpemVkRGFzaGJvYXJkSWQsXG4gICAgICBndWVzdFRva2VuLFxuICAgIH0pO1xuXG4gICAgYWN0aXZlRGFzaGJvYXJkSWQgPSBub3JtYWxpemVkRGFzaGJvYXJkSWQ7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG5cIlwiXCJcblxuICAgIGZvciBhbmNob3IgaW4gYW5jaG9yX2NhbmRpZGF0ZXM6XG4gICAgICAgIGlmIGNvbnRlbnQuY291bnQoYW5jaG9yKSA9PSAxOlxuICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShcbiAgICAgICAgICAgICAgICBhbmNob3IsXG4gICAgICAgICAgICAgICAgc3dpdGNoX2Z1bmN0aW9uICsgYW5jaG9yLFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICApXG5cbiAgICByYWlzZSBQYXRjaEVycm9yKFxuICAgICAgICBcIkNvdWxkIG5vdCBsb2NhdGUgdGhlIFNESyBnZXRTY3JvbGxTaXplIGZ1bmN0aW9uXCJcbiAgICApXG5cblxuZGVmIHBhdGNoX3Nka19yZXR1cm5fb2JqZWN0KGNvbnRlbnQ6IHN0cikgLT4gc3RyOlxuICAgIGNhbmRpZGF0ZXMgPSBbXG4gICAgICAgIFwiICAgIHNldFRoZW1lTW9kZSxcXFxcbiAgfTtcIixcbiAgICAgICAgXCIgICAgc2V0VGhlbWVNb2RlLFxcXFxuICAgIHVubW91bnQsXFxcXG4gIH07XCIsXG4gICAgICAgIFwiICAgIHVubW91bnQsXFxcXG4gICAgc2V0VGhlbWVNb2RlLFxcXFxuICB9O1wiLFxuICAgIF1cblxuICAgIGZvciBjYW5kaWRhdGUgaW4gY2FuZGlkYXRlczpcbiAgICAgICAgaWYgY29udGVudC5jb3VudChjYW5kaWRhdGUpID09IDE6XG4gICAgICAgICAgICBsaW5lcyA9IGNhbmRpZGF0ZS5zcGxpdGxpbmVzKClcblxuICAgICAgICAgICAgY2xvc2luZyA9IGxpbmVzLnBvcCgpXG4gICAgICAgICAgICBib2R5ID0gXCJcXFxcblwiLmpvaW4obGluZXMpXG5cbiAgICAgICAgICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlLFxuICAgICAgICAgICAgICAgIGJvZHlcbiAgICAgICAgICAgICAgICArIFwiXFxcXG5cIlxuICAgICAgICAgICAgICAgICsgXCIgICAgc3dpdGNoRGFzaGJvYXJkLFxcXFxuXCJcbiAgICAgICAgICAgICAgICArIGNsb3NpbmcsXG4gICAgICAgICAgICAgICAgMSxcbiAgICAgICAgICAgIClcblxuICAgIHJhaXNlIFBhdGNoRXJyb3IoXG4gICAgICAgIFwiQ291bGQgbm90IGxvY2F0ZSB0aGUgRW1iZWRkZWREYXNoYm9hcmQgcmV0dXJuIG9iamVjdFwiXG4gICAgKVxuXG5cbmRlZiBwYXRjaF9zZGsoc2RrX3BhdGg6IFBhdGgpIC0+IE5vbmU6XG4gICAgY29udGVudCA9IHNka19wYXRoLnJlYWRfdGV4dChlbmNvZGluZz1cInV0Zi04XCIpXG5cbiAgICBpZiBcIlNVUEVSU0VUX1NXSVRDSEFCTEVfRU1CRURfU0RLX1BBVENIXCIgaW4gY29udGVudDpcbiAgICAgICAgcHJpbnQoZlwiQWxyZWFkeSBwYXRjaGVkOiB7c2RrX3BhdGh9XCIpXG4gICAgICAgIHJldHVyblxuXG4gICAgY29udGVudCA9IHBhdGNoX2d1ZXN0X3Rva2VuX2ZldGNoX3R5cGUoY29udGVudClcbiAgICBjb250ZW50ID0gcGF0Y2hfZW1iZWRkZWRfZGFzaGJvYXJkX3R5cGUoY29udGVudClcbiAgICBjb250ZW50ID0gcGF0Y2hfaW5pdGlhbF9ndWVzdF90b2tlbl9mZXRjaChjb250ZW50KVxuICAgIGNvbnRlbnQgPSBwYXRjaF9ndWVzdF90b2tlbl9yZWZyZXNoKGNvbnRlbnQpXG4gICAgY29udGVudCA9IHBhdGNoX3Nka19mdW5jdGlvbnMoY29udGVudClcbiAgICBjb250ZW50ID0gcGF0Y2hfc2RrX3JldHVybl9vYmplY3QoY29udGVudClcblxuICAgIHNka19wYXRoLndyaXRlX3RleHQoY29udGVudCwgZW5jb2Rpbmc9XCJ1dGYtOFwiKVxuICAgIHByaW50KGZcIlBhdGNoZWQ6IHtzZGtfcGF0aH1cIilcblxuXG5kZWYgbWFpbigpIC0+IGludDpcbiAgICBwYXJzZXIgPSBhcmdwYXJzZS5Bcmd1bWVudFBhcnNlcihcbiAgICAgICAgZGVzY3JpcHRpb249KFxuICAgICAgICAgICAgXCJBcHBseSB0aGUgc3dpdGNoYWJsZS1kYXNoYm9hcmQgcGF0Y2ggdG8gYSBcIlxuICAgICAgICAgICAgXCJTdXBlcnNldCA2LjEueCBzb3VyY2UgY2hlY2tvdXQuXCJcbiAgICAgICAgKVxuICAgIClcblxuICAgIHBhcnNlci5hZGRfYXJndW1lbnQoXG4gICAgICAgIFwic3VwZXJzZXRfcm9vdFwiLFxuICAgICAgICB0eXBlPVBhdGgsXG4gICAgICAgIGhlbHA9XCJQYXRoIHRvIHRoZSBBcGFjaGUgU3VwZXJzZXQgc291cmNlIGNoZWNrb3V0XCIsXG4gICAgKVxuXG4gICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKClcbiAgICByb290ID0gYXJncy5zdXBlcnNldF9yb290LnJlc29sdmUoKVxuXG4gICAgZnJvbnRlbmRfcGF0aCA9IHJvb3QgLyBGUk9OVEVORF9GSUxFXG4gICAgc2RrX3BhdGggPSByb290IC8gU0RLX0ZJTEVcblxuICAgIG1pc3NpbmcgPSBbXG4gICAgICAgIHBhdGhcbiAgICAgICAgZm9yIHBhdGggaW4gW2Zyb250ZW5kX3BhdGgsIHNka19wYXRoXVxuICAgICAgICBpZiBub3QgcGF0aC5leGlzdHMoKVxuICAgIF1cblxuICAgIGlmIG1pc3Npbmc6XG4gICAgICAgIHByaW50KFxuICAgICAgICAgICAgXCJUaGUgdGFyZ2V0IGRvZXMgbm90IGFwcGVhciB0byBiZSBhIGNvbXBhdGlibGUgXCJcbiAgICAgICAgICAgIFwiU3VwZXJzZXQgc291cmNlIGNoZWNrb3V0LlwiLFxuICAgICAgICAgICAgZmlsZT1zeXMuc3RkZXJyLFxuICAgICAgICApXG5cbiAgICAgICAgZm9yIG1pc3NpbmdfcGF0aCBpbiBtaXNzaW5nOlxuICAgICAgICAgICAgcHJpbnQoZlwiTWlzc2luZzoge21pc3NpbmdfcGF0aH1cIiwgZmlsZT1zeXMuc3RkZXJyKVxuXG4gICAgICAgIHJldHVybiAyXG5cbiAgICB0cnk6XG4gICAgICAgIHBhdGNoX2Zyb250ZW5kKGZyb250ZW5kX3BhdGgpXG4gICAgICAgIHBhdGNoX3NkayhzZGtfcGF0aClcbiAgICBleGNlcHQgUGF0Y2hFcnJvciBhcyBlcnJvcjpcbiAgICAgICAgcHJpbnQoZlwiUGF0Y2ggZmFpbGVkOiB7ZXJyb3J9XCIsIGZpbGU9c3lzLnN0ZGVycilcbiAgICAgICAgcmV0dXJuIDFcblxuICAgIHByaW50KFwiUGF0Y2ggY29tcGxldGVkIHN1Y2Nlc3NmdWxseS5cIilcbiAgICByZXR1cm4gMFxuXG5cbmlmIF9fbmFtZV9fID09IFwiX19tYWluX19cIjpcbiAgICByYWlzZSBTeXN0ZW1FeGl0KG1haW4oKSlcbmA7XG5cbmNvbnN0IFZFUklGWV9QQVRDSF9TSCA9IGAjIS91c3IvYmluL2VudiBiYXNoXG5cbnNldCAtZXVvIHBpcGVmYWlsXG5cblNVUEVSU0VUX1JPT1Q9XFwkezE6P1VzYWdlOiB2ZXJpZnlfcGF0Y2guc2ggL3BhdGgvdG8vc3VwZXJzZXR9XG5cbkZST05URU5EX0ZJTEU9XCIkU1VQRVJTRVRfUk9PVC9zdXBlcnNldC1mcm9udGVuZC9zcmMvZW1iZWRkZWQvaW5kZXgudHN4XCJcblNES19GSUxFPVwiJFNVUEVSU0VUX1JPT1Qvc3VwZXJzZXQtZW1iZWRkZWQtc2RrL3NyYy9pbmRleC50c1wiXG5cbnRlc3QgLWYgXCIkRlJPTlRFTkRfRklMRVwiXG50ZXN0IC1mIFwiJFNES19GSUxFXCJcblxuZ3JlcCAtcSBcXFxcXG4gIFwiU1VQRVJTRVRfU1dJVENIQUJMRV9FTUJFRF9QQVRDSFwiIFxcXFxcbiAgXCIkRlJPTlRFTkRfRklMRVwiXG5cbmdyZXAgLXEgXFxcXFxuICBcIidzd2l0Y2hEYXNoYm9hcmQnXCIgXFxcXFxuICBcIiRGUk9OVEVORF9GSUxFXCJcblxuZ3JlcCAtcSBcXFxcXG4gIFwiZGFzaGJvYXJkU3dpdGNoSGFuZGxlclwiIFxcXFxcbiAgXCIkRlJPTlRFTkRfRklMRVwiXG5cbmdyZXAgLXEgXFxcXFxuICBcIlNVUEVSU0VUX1NXSVRDSEFCTEVfRU1CRURfU0RLX1BBVENIXCIgXFxcXFxuICBcIiRTREtfRklMRVwiXG5cbmdyZXAgLXEgXFxcXFxuICBcInN3aXRjaERhc2hib2FyZDpcIiBcXFxcXG4gIFwiJFNES19GSUxFXCJcblxuZ3JlcCAtcSBcXFxcXG4gIFwiYWN0aXZlRGFzaGJvYXJkSWRcIiBcXFxcXG4gIFwiJFNES19GSUxFXCJcblxuZ3JlcCAtcSBcXFxcXG4gIFwiZmV0Y2hHdWVzdFRva2VuKFwiIFxcXFxcbiAgXCIkU0RLX0ZJTEVcIlxuXG5lY2hvIFwiVGhlIHN3aXRjaGFibGUtZGFzaGJvYXJkIHBhdGNoIGlzIHByZXNlbnQuXCJcbmA7XG5cbmNvbnN0IEJVSUxEX1NES19TSCA9IGAjIS91c3IvYmluL2VudiBiYXNoXG5cbnNldCAtZXVvIHBpcGVmYWlsXG5cblNVUEVSU0VUX1JPT1Q9XFwkezE6P1VzYWdlOiBidWlsZC1zZGsuc2ggL3BhdGgvdG8vc3VwZXJzZXR9XG5cblNES19ST09UPVwiJFNVUEVSU0VUX1JPT1Qvc3VwZXJzZXQtZW1iZWRkZWQtc2RrXCJcblxuaWYgWyAhIC1mIFwiJFNES19ST09UL3BhY2thZ2UuanNvblwiIF07IHRoZW5cbiAgZWNobyBcIk1pc3NpbmcgU0RLIHBhY2thZ2U6ICRTREtfUk9PVFwiID4mMlxuICBleGl0IDFcbmZpXG5cbmNkIFwiJFNES19ST09UXCJcblxubnBtIGNpXG5cbm5wbSBydW4gYnVpbGRcblxuZWNob1xuZWNobyBcIkVtYmVkZGVkIFNESyBidWlsZCBjb21wbGV0ZWQuXCJcbmVjaG8gXCJPdXRwdXQgZGlyZWN0b3J5OlwiXG5maW5kIC4gXFxcXFxuICAtbWF4ZGVwdGggMiBcXFxcXG4gIC10eXBlIGQgXFxcXFxuICBcXFxcKCAtbmFtZSBkaXN0IC1vIC1uYW1lIGxpYiBcXFxcKSBcXFxcXG4gIC1wcmludFxuYDtcblxuY29uc3QgQlVJTERfRlJPTlRFTkRfU0ggPSBgIyEvdXNyL2Jpbi9lbnYgYmFzaFxuXG5zZXQgLWV1byBwaXBlZmFpbFxuXG5TVVBFUlNFVF9ST09UPVxcJHsxOj9Vc2FnZTogYnVpbGQtc3VwZXJzZXQtZnJvbnRlbmQuc2ggL3BhdGgvdG8vc3VwZXJzZXR9XG5cbkZST05URU5EX1JPT1Q9XCIkU1VQRVJTRVRfUk9PVC9zdXBlcnNldC1mcm9udGVuZFwiXG5cbmlmIFsgISAtZiBcIiRGUk9OVEVORF9ST09UL3BhY2thZ2UuanNvblwiIF07IHRoZW5cbiAgZWNobyBcIk1pc3NpbmcgU3VwZXJzZXQgZnJvbnRlbmQ6ICRGUk9OVEVORF9ST09UXCIgPiYyXG4gIGV4aXQgMVxuZmlcblxuY2QgXCIkRlJPTlRFTkRfUk9PVFwiXG5cbm5wbSBjaVxuXG5ucG0gcnVuIGJ1aWxkXG5cbmVjaG8gXCJTdXBlcnNldCBmcm9udGVuZCBidWlsZCBjb21wbGV0ZWQuXCJcbmA7XG5cbmNvbnN0IFBBVENIX0FORF9CVUlMRF9TSCA9IGAjIS91c3IvYmluL2VudiBiYXNoXG5cbnNldCAtZXVvIHBpcGVmYWlsXG5cblNVUEVSU0VUX1JPT1Q9XFwkezE6P1VzYWdlOiBwYXRjaC1hbmQtYnVpbGQuc2ggL3BhdGgvdG8vc3VwZXJzZXR9XG5cblNDUklQVF9ESVI9JChcbiAgY2QgXCIkKGRpcm5hbWUgXCJcXCR7QkFTSF9TT1VSQ0VbMF19XCIpXCJcbiAgcHdkXG4pXG5cblBST0pFQ1RfUk9PVD0kKFxuICBjZCBcIiRTQ1JJUFRfRElSLy4uXCJcbiAgcHdkXG4pXG5cbnB5dGhvbjMgXFxcXFxuICBcIiRQUk9KRUNUX1JPT1QvcGF0Y2hlcy9hcHBseV9zdXBlcnNldF82XzFfcGF0Y2gucHlcIiBcXFxcXG4gIFwiJFNVUEVSU0VUX1JPT1RcIlxuXG5cIiRQUk9KRUNUX1JPT1QvcGF0Y2hlcy92ZXJpZnlfcGF0Y2guc2hcIiBcXFxcXG4gIFwiJFNVUEVSU0VUX1JPT1RcIlxuXG5cIiRTQ1JJUFRfRElSL2J1aWxkLXNkay5zaFwiIFxcXFxcbiAgXCIkU1VQRVJTRVRfUk9PVFwiXG5cblwiJFNDUklQVF9ESVIvYnVpbGQtc3VwZXJzZXQtZnJvbnRlbmQuc2hcIiBcXFxcXG4gIFwiJFNVUEVSU0VUX1JPT1RcIlxuXG5lY2hvXG5lY2hvIFwiUGF0Y2ggYW5kIGZyb250ZW5kIGJ1aWxkcyBjb21wbGV0ZWQuXCJcbmA7XG5cbmNvbnN0IEJVSUxEX0RPQ0tFUl9TSCA9IGAjIS91c3IvYmluL2VudiBiYXNoXG5cbnNldCAtZXVvIHBpcGVmYWlsXG5cblNVUEVSU0VUX1JPT1Q9XFwkezE6P1VzYWdlOiBidWlsZC1kb2NrZXItaW1hZ2Uuc2ggL3BhdGgvdG8vc3VwZXJzZXQgW2ltYWdlLXRhZ119XG5JTUFHRV9UQUc9XFwkezI6LWxvY2FsL3N1cGVyc2V0LXN3aXRjaGFibGU6Ni4xLjB9XG5cblNDUklQVF9ESVI9JChcbiAgY2QgXCIkKGRpcm5hbWUgXCJcXCR7QkFTSF9TT1VSQ0VbMF19XCIpXCJcbiAgcHdkXG4pXG5cblBST0pFQ1RfUk9PVD0kKFxuICBjZCBcIiRTQ1JJUFRfRElSLy4uXCJcbiAgcHdkXG4pXG5cbnB5dGhvbjMgXFxcXFxuICBcIiRQUk9KRUNUX1JPT1QvcGF0Y2hlcy9hcHBseV9zdXBlcnNldF82XzFfcGF0Y2gucHlcIiBcXFxcXG4gIFwiJFNVUEVSU0VUX1JPT1RcIlxuXG5cIiRQUk9KRUNUX1JPT1QvcGF0Y2hlcy92ZXJpZnlfcGF0Y2guc2hcIiBcXFxcXG4gIFwiJFNVUEVSU0VUX1JPT1RcIlxuXG5jZCBcIiRTVVBFUlNFVF9ST09UXCJcblxuZG9ja2VyIGJ1aWxkIFxcXFxcbiAgLS10YXJnZXQgbGVhbiBcXFxcXG4gIC0tdGFnIFwiJElNQUdFX1RBR1wiIFxcXFxcbiAgLlxuXG5lY2hvIFwiQnVpbHQgRG9ja2VyIGltYWdlOiAkSU1BR0VfVEFHXCJcbmA7XG5cbmNvbnN0IFJFQURNRSA9IGAjICR7U1VQRVJTRVRfUExVR0lOX0lEfVxuXG5NdWx0aS10ZW5hbnQsIG9yZy1hZ25vc3RpYyBTdXBlcnNldCBkYXNoYm9hcmQgZW1iZWQgcGx1Z2luIChwYXRjaC1hbmQtYnVpbGQgc3RyYXRlZ3kpLlxuXG5UaGlzIGlzIG5vdCBhIGdlbmVyYXRlZCBwbHVnaW4gbGlrZSB0aGUgS2liYW5hIHZhcmlhbnQuIEluc3RlYWQsIERlY2FmIGhvbGRzXG5wYXRjaCBzY3JpcHRzIHRoYXQgbW9kaWZ5IFN1cGVyc2V0J3MgaW50ZXJuYWwgZW1iZWRkZWQgZnJvbnRlbmQgYW5kIGVtYmVkZGVkXG5TREsgc291cmNlIGZpbGVzIHRvIGFkZCBhIFxcYHN3aXRjaERhc2hib2FyZFxcYCBtZXRob2QuIFRoZSBleGlzdGluZyBpZnJhbWVcbmVsZW1lbnQsIGRvY3VtZW50LCBjb250ZW50V2luZG93LCBSZWFjdCBydW50aW1lLCBhbmQgU3dpdGNoYm9hcmQgTWVzc2FnZUNoYW5uZWxcbmFyZSBwcmVzZXJ2ZWQgYWNyb3NzIGRhc2hib2FyZCBzd2l0Y2hlcy5cblxuIyMgV2hhdCBpdCBwYXRjaGVzXG5cbi0gXFxgc3VwZXJzZXQtZnJvbnRlbmQvc3JjL2VtYmVkZGVkL2luZGV4LnRzeFxcYCDigJQgYWRkcyBcXGBzd2l0Y2hEYXNoYm9hcmRcXGAgdG8gdGhlXG4gIFN3aXRjaGJvYXJkIGNoYW5uZWw7IHJlcGxhY2VzIG9ubHkgXFxgRGFzaGJvYXJkUGFnZVxcYC5cbi0gXFxgc3VwZXJzZXQtZW1iZWRkZWQtc2RrL3NyYy9pbmRleC50c1xcYCDigJQgYWRkc1xuICBcXGBlbWJlZGRlZERhc2hib2FyZC5zd2l0Y2hEYXNoYm9hcmQoZGFzaGJvYXJkSWQpXFxgOyByZXF1ZXN0cyBhIGd1ZXN0IHRva2VuIGZvclxuICB0aGUgc2VsZWN0ZWQgZGFzaGJvYXJkOyByZWZyZXNoZXMgZnV0dXJlIGd1ZXN0IHRva2VucyBmb3IgdGhlIGFjdGl2ZSBkYXNoYm9hcmQuXG5cbiMjIEJ1aWxkXG5cblxcYFxcYFxcYGJhc2hcbiMgQXBwbHkgcGF0Y2ggKyB2ZXJpZnkgKyBidWlsZCBTREsgKyBidWlsZCBmcm9udGVuZFxuYnVpbGQvcGF0Y2gtYW5kLWJ1aWxkLnNoIC9wYXRoL3RvL3N1cGVyc2V0XG5cbiMgT3IgYnVpbGQgYSBEb2NrZXIgaW1hZ2VcbmJ1aWxkL2J1aWxkLWRvY2tlci1pbWFnZS5zaCAvcGF0aC90by9zdXBlcnNldCByZWdpc3RyeS5leGFtcGxlLmNvbS9zdXBlcnNldC1zd2l0Y2hhYmxlOjYuMS4wXG5cXGBcXGBcXGBcblxuVGhlIHBhdGNoZWQgU0RLIG11c3QgYmUgcGFja2VkIGFuZCBpbnN0YWxsZWQgaW50byB0aGUgQW5ndWxhciBhcHBsaWNhdGlvbjpcblxuXFxgXFxgXFxgYmFzaFxuY2QgL3BhdGgvdG8vc3VwZXJzZXQvc3VwZXJzZXQtZW1iZWRkZWQtc2RrXG5ucG0gY2kgJiYgbnBtIHJ1biBidWlsZCAmJiBucG0gcGFja1xuY2QgL3BhdGgvdG8vYW5ndWxhci1hcHBcbm5wbSBpbnN0YWxsIC9wYXRoL3RvL3N1cGVyc2V0L3N1cGVyc2V0LWVtYmVkZGVkLXNkay9zdXBlcnNldC11aS1lbWJlZGRlZC1zZGstKi50Z3pcblxcYFxcYFxcYFxuXG5WZXJzaW9uOiAke1NVUEVSU0VUX1BMVUdJTl9WRVJTSU9OfVxuYDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmdWxsIHNldCBvZiBwYXRjaCBhbmQgYnVpbGQgc2NyaXB0IGZpbGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3VwZXJzZXRQYXRjaEZpbGVzKCk6IFN1cGVyc2V0UGF0Y2hGaWxlW10ge1xuICByZXR1cm4gW1xuICAgIHsgcGF0aDogXCJwYXRjaGVzL2FwcGx5X3N1cGVyc2V0XzZfMV9wYXRjaC5weVwiLCBjb250ZW50OiBBUFBMWV9QQVRDSF9QWSwgZXhlY3V0YWJsZTogdHJ1ZSB9LFxuICAgIHsgcGF0aDogXCJwYXRjaGVzL3ZlcmlmeV9wYXRjaC5zaFwiLCBjb250ZW50OiBWRVJJRllfUEFUQ0hfU0gsIGV4ZWN1dGFibGU6IHRydWUgfSxcbiAgICB7IHBhdGg6IFwiYnVpbGQvYnVpbGQtc2RrLnNoXCIsIGNvbnRlbnQ6IEJVSUxEX1NES19TSCwgZXhlY3V0YWJsZTogdHJ1ZSB9LFxuICAgIHsgcGF0aDogXCJidWlsZC9idWlsZC1zdXBlcnNldC1mcm9udGVuZC5zaFwiLCBjb250ZW50OiBCVUlMRF9GUk9OVEVORF9TSCwgZXhlY3V0YWJsZTogdHJ1ZSB9LFxuICAgIHsgcGF0aDogXCJidWlsZC9wYXRjaC1hbmQtYnVpbGQuc2hcIiwgY29udGVudDogUEFUQ0hfQU5EX0JVSUxEX1NILCBleGVjdXRhYmxlOiB0cnVlIH0sXG4gICAgeyBwYXRoOiBcImJ1aWxkL2J1aWxkLWRvY2tlci1pbWFnZS5zaFwiLCBjb250ZW50OiBCVUlMRF9ET0NLRVJfU0gsIGV4ZWN1dGFibGU6IHRydWUgfSxcbiAgICB7IHBhdGg6IFwiUkVBRE1FLm1kXCIsIGNvbnRlbnQ6IFJFQURNRSB9LFxuICBdO1xufVxuIl19
834
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3BsdWdpbnMvc3VwZXJzZXQvdGVtcGxhdGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsdUJBQXVCLEVBQUUsc0JBQW1CO0FBV3pFLE1BQU0sY0FBYyxHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQWdtQnRCLENBQUM7QUFFRixNQUFNLGVBQWUsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0F5Q3ZCLENBQUM7QUFFRixNQUFNLFlBQVksR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBMkJwQixDQUFDO0FBRUYsTUFBTSxpQkFBaUIsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FvQnpCLENBQUM7QUFFRixNQUFNLGtCQUFrQixHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBK0IxQixDQUFDO0FBRUYsTUFBTSxlQUFlLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBZ0N2QixDQUFDO0FBRUYsTUFBTSxNQUFNLEdBQUcsS0FBSyxrQkFBa0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7V0FxQzNCLHVCQUF1QjtDQUNqQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCO0lBQ2hDLE9BQU87UUFDTCxFQUFFLElBQUksRUFBRSxxQ0FBcUMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUU7UUFDMUYsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFO1FBQy9FLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRTtRQUN2RSxFQUFFLElBQUksRUFBRSxrQ0FBa0MsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRTtRQUMxRixFQUFFLElBQUksRUFBRSwwQkFBMEIsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRTtRQUNuRixFQUFFLElBQUksRUFBRSw2QkFBNkIsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUU7UUFDbkYsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUU7S0FDdkMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBtb2R1bGUgaW50ZWdyYXRpb25zL3BsdWdpbnMvc3VwZXJzZXQvdGVtcGxhdGVzXG4gKiBAc3VtbWFyeSBQYXRjaCBhbmQgYnVpbGQgc2NyaXB0IHRlbXBsYXRlcyBmb3IgdGhlIFN1cGVyc2V0IGVtYmVkIHBsdWdpbi5cbiAqIEBkZXNjcmlwdGlvbiBIb2xkcyBhbGwgcGF0Y2ggc2NyaXB0cyAoUHl0aG9uICsgQmFzaCkgYW5kIGJ1aWxkIHNjcmlwdHMgYXNcbiAqIHN0cmluZyB0ZW1wbGF0ZXMuIFRoZXNlIGFyZSBtYXRlcmlhbGl6ZWQgb250byBkaXNrIGJ5IHRoZSBpbnN0YWxsZXIuIERlY2FmXG4gKiBkb2VzIG5vdCBnZW5lcmF0ZSBuZXcgU3VwZXJzZXQgc291cmNlIOKAlCBpdCBwYXRjaGVzIGV4aXN0aW5nIGludGVybmFsIGZpbGVzXG4gKiAoYHN1cGVyc2V0LWZyb250ZW5kL3NyYy9lbWJlZGRlZC9pbmRleC50c3hgIGFuZFxuICogYHN1cGVyc2V0LWVtYmVkZGVkLXNkay9zcmMvaW5kZXgudHNgKSBmb2xsb3dpbmcgdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvblxuICogZnJvbSBERUNBRi00MCDCpzkuXG4gKlxuICogVGhlIHBhdGNoIGFkZHMgYSBgc3dpdGNoRGFzaGJvYXJkYCBtZXRob2QgdG8gU3VwZXJzZXQncyBleGlzdGluZyBTd2l0Y2hib2FyZFxuICogY2hhbm5lbCwgcmVwbGFjaW5nIG9ubHkgYERhc2hib2FyZFBhZ2VgIHdoaWxlIGtlZXBpbmcgdGhlIGlmcmFtZSBlbGVtZW50LFxuICogZG9jdW1lbnQsIGNvbnRlbnRXaW5kb3csIFJlYWN0IHJ1bnRpbWUsIGFuZCBtZXNzYWdlIGNoYW5uZWwgYWxpdmUuXG4gKi9cbmltcG9ydCB7IFNVUEVSU0VUX1BMVUdJTl9JRCwgU1VQRVJTRVRfUExVR0lOX1ZFUlNJT04gfSBmcm9tIFwiLi9tYW5pZmVzdFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN1cGVyc2V0UGF0Y2hGaWxlIHtcbiAgLyoqIFJlbGF0aXZlIHBhdGggd2l0aGluIHRoZSB0YXJnZXQgZGlyZWN0b3J5LiAqL1xuICBwYXRoOiBzdHJpbmc7XG4gIC8qKiBGaWxlIGNvbnRlbnRzLiAqL1xuICBjb250ZW50OiBzdHJpbmc7XG4gIC8qKiBXaGV0aGVyIHRvIG1hcmsgdGhlIGZpbGUgZXhlY3V0YWJsZSBvbiBQT1NJWC4gKi9cbiAgZXhlY3V0YWJsZT86IGJvb2xlYW47XG59XG5cbmNvbnN0IEFQUExZX1BBVENIX1BZID0gYCMhL3Vzci9iaW4vZW52IHB5dGhvbjNcblxuZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCBhbm5vdGF0aW9uc1xuXG5pbXBvcnQgYXJncGFyc2VcbmltcG9ydCByZVxuaW1wb3J0IHN5c1xuZnJvbSBwYXRobGliIGltcG9ydCBQYXRoXG5cblxuRlJPTlRFTkRfRklMRSA9IFBhdGgoXCJzdXBlcnNldC1mcm9udGVuZC9zcmMvZW1iZWRkZWQvaW5kZXgudHN4XCIpXG5TREtfRklMRSA9IFBhdGgoXCJzdXBlcnNldC1lbWJlZGRlZC1zZGsvc3JjL2luZGV4LnRzXCIpXG5cblxuY2xhc3MgUGF0Y2hFcnJvcihSdW50aW1lRXJyb3IpOlxuICAgIHBhc3NcblxuXG5kZWYgcmVwbGFjZV9vbmNlKFxuICAgIGNvbnRlbnQ6IHN0cixcbiAgICBvbGQ6IHN0cixcbiAgICBuZXc6IHN0cixcbiAgICBkZXNjcmlwdGlvbjogc3RyLFxuKSAtPiBzdHI6XG4gICAgY291bnQgPSBjb250ZW50LmNvdW50KG9sZClcblxuICAgIGlmIGNvdW50ICE9IDE6XG4gICAgICAgIHJhaXNlIFBhdGNoRXJyb3IoXG4gICAgICAgICAgICBmXCJ7ZGVzY3JpcHRpb259OiBleHBlY3RlZCBleGFjdGx5IG9uZSBvY2N1cnJlbmNlLCBmb3VuZCB7Y291bnR9XCJcbiAgICAgICAgKVxuXG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShvbGQsIG5ldywgMSlcblxuXG5kZWYgcmVwbGFjZV9yZWdleF9vbmNlKFxuICAgIGNvbnRlbnQ6IHN0cixcbiAgICBwYXR0ZXJuOiByZS5QYXR0ZXJuW3N0cl0sXG4gICAgcmVwbGFjZW1lbnQ6IHN0cixcbiAgICBkZXNjcmlwdGlvbjogc3RyLFxuKSAtPiBzdHI6XG4gICAgdXBkYXRlZCwgY291bnQgPSBwYXR0ZXJuLnN1Ym4ocmVwbGFjZW1lbnQsIGNvbnRlbnQsIGNvdW50PTEpXG5cbiAgICBpZiBjb3VudCAhPSAxOlxuICAgICAgICByYWlzZSBQYXRjaEVycm9yKFxuICAgICAgICAgICAgZlwie2Rlc2NyaXB0aW9ufTogZXhwZWN0ZWQgZXhhY3RseSBvbmUgbWF0Y2gsIGZvdW5kIHtjb3VudH1cIlxuICAgICAgICApXG5cbiAgICByZXR1cm4gdXBkYXRlZFxuXG5cbmRlZiBwYXRjaF9yZWFjdF9pbXBvcnQoY29udGVudDogc3RyKSAtPiBzdHI6XG4gICAgcmVhY3RfaW1wb3J0X3BhdHRlcm4gPSByZS5jb21waWxlKFxuICAgICAgICByXCJpbXBvcnRcXFxccypcXFxce1xcXFxzKihbXn1dKylcXFxccypcXFxcfVxcXFxzKmZyb21cXFxccyoncmVhY3QnO1wiXG4gICAgKVxuXG4gICAgbWF0Y2ggPSByZWFjdF9pbXBvcnRfcGF0dGVybi5zZWFyY2goY29udGVudClcblxuICAgIGlmIG5vdCBtYXRjaDpcbiAgICAgICAgcmFpc2UgUGF0Y2hFcnJvcihcIkNvdWxkIG5vdCBsb2NhdGUgdGhlIG5hbWVkIFJlYWN0IGltcG9ydFwiKVxuXG4gICAgaW1wb3J0cyA9IFtcbiAgICAgICAgdmFsdWUuc3RyaXAoKVxuICAgICAgICBmb3IgdmFsdWUgaW4gbWF0Y2guZ3JvdXAoMSkucmVwbGFjZShcIlxcXFxuXCIsIFwiIFwiKS5zcGxpdChcIixcIilcbiAgICAgICAgaWYgdmFsdWUuc3RyaXAoKVxuICAgIF1cblxuICAgIHJlcXVpcmVkX2ltcG9ydHMgPSBbXCJsYXp5XCIsIFwiU3VzcGVuc2VcIiwgXCJ1c2VFZmZlY3RcIiwgXCJ1c2VTdGF0ZVwiXVxuXG4gICAgZm9yIHJlcXVpcmVkX2ltcG9ydCBpbiByZXF1aXJlZF9pbXBvcnRzOlxuICAgICAgICBpZiByZXF1aXJlZF9pbXBvcnQgbm90IGluIGltcG9ydHM6XG4gICAgICAgICAgICBpbXBvcnRzLmFwcGVuZChyZXF1aXJlZF9pbXBvcnQpXG5cbiAgICByZXBsYWNlbWVudCA9IChcbiAgICAgICAgXCJpbXBvcnQge1xcXFxuICBcIlxuICAgICAgICArIFwiLFxcXFxuICBcIi5qb2luKGltcG9ydHMpXG4gICAgICAgICsgXCIsXFxcXG59IGZyb20gJ3JlYWN0JztcIlxuICAgIClcblxuICAgIHJldHVybiAoXG4gICAgICAgIGNvbnRlbnRbOiBtYXRjaC5zdGFydCgpXVxuICAgICAgICArIHJlcGxhY2VtZW50XG4gICAgICAgICsgY29udGVudFttYXRjaC5lbmQoKSA6XVxuICAgIClcblxuXG5kZWYgbG9jYXRlX2VtYmVkZGVkX2NvbXBvbmVudChcbiAgICBjb250ZW50OiBzdHIsXG4pIC0+IHR1cGxlW3JlLk1hdGNoW3N0cl0sIHN0cl06XG4gICAgcGF0dGVybiA9IHJlLmNvbXBpbGUoXG4gICAgICAgIHJcImNvbnN0XFxcXHMrKFtBLVphLXowLTlfXSspXFxcXHMqPVxcXFxzKlxcXFwoXFxcXClcXFxccyo9PlxcXFxzKlxcXFx7Lio/XFxcXH07XFxcXHMqXCJcbiAgICAgICAgclwiKD89Y29uc3RcXFxccytFbWJlZGRlZFJvdXRlKVwiLFxuICAgICAgICByZS5ET1RBTEwsXG4gICAgKVxuXG4gICAgbWF0Y2ggPSBwYXR0ZXJuLnNlYXJjaChjb250ZW50KVxuXG4gICAgaWYgbWF0Y2g6XG4gICAgICAgIHJldHVybiBtYXRjaCwgbWF0Y2guZ3JvdXAoMSlcblxuICAgIHJhaXNlIFBhdGNoRXJyb3IoXG4gICAgICAgIFwiQ291bGQgbm90IGZpbmQgYW4gZW1iZWRkZWQgZGFzaGJvYXJkIGNvbXBvbmVudCBiZWZvcmUgRW1iZWRkZWRSb3V0ZVwiXG4gICAgKVxuXG5cbmRlZiBwYXRjaF9mcm9udGVuZChmcm9udGVuZF9wYXRoOiBQYXRoKSAtPiBOb25lOlxuICAgIGNvbnRlbnQgPSBmcm9udGVuZF9wYXRoLnJlYWRfdGV4dChlbmNvZGluZz1cInV0Zi04XCIpXG5cbiAgICBpZiBcIlNVUEVSU0VUX1NXSVRDSEFCTEVfRU1CRURfUEFUQ0hcIiBpbiBjb250ZW50OlxuICAgICAgICBwcmludChmXCJBbHJlYWR5IHBhdGNoZWQ6IHtmcm9udGVuZF9wYXRofVwiKVxuICAgICAgICByZXR1cm5cblxuICAgIGNvbnRlbnQgPSBwYXRjaF9yZWFjdF9pbXBvcnQoY29udGVudClcblxuICAgIGNvbXBvbmVudF9tYXRjaCwgY29tcG9uZW50X25hbWUgPSBsb2NhdGVfZW1iZWRkZWRfY29tcG9uZW50KFxuICAgICAgICBjb250ZW50XG4gICAgKVxuXG4gICAgcmVwbGFjZW1lbnRfY29tcG9uZW50ID0gXCJcIlwiLy8gU1VQRVJTRVRfU1dJVENIQUJMRV9FTUJFRF9QQVRDSFxuLy9cbi8vIEFsbG93cyB0aGUgZXhpc3RpbmcgZW1iZWRkZWQgU3VwZXJzZXQgZG9jdW1lbnQgdG8gcmVwbGFjZSBEYXNoYm9hcmRQYWdlXG4vLyB3aXRob3V0IG5hdmlnYXRpbmcgb3IgcmVjcmVhdGluZyB0aGUgaWZyYW1lLlxuLy9cbi8vIFNlY3VyaXR5OlxuLy8gLSBUaGlzIG1ldGhvZCBpcyBleHBvc2VkIG9ubHkgdGhyb3VnaCBTdXBlcnNldCdzIGV4aXN0aW5nIFN3aXRjaGJvYXJkXG4vLyAgIE1lc3NhZ2VDaGFubmVsLlxuLy8gLSBUaGUgaG9zdCBhcHBsaWNhdGlvbiBtdXN0IG9idGFpbiBhIGd1ZXN0IHRva2VuIGZvciB0aGUgdGFyZ2V0IGRhc2hib2FyZC5cbi8vIC0gU3VwZXJzZXQncyBub3JtYWwgQWxsb3dlZCBEb21haW5zIHZhbGlkYXRpb24gcmVtYWlucyBpbiBlZmZlY3QuXG5cbmludGVyZmFjZSBTd2l0Y2hEYXNoYm9hcmRQYXlsb2FkIHtcbiAgZGFzaGJvYXJkSWQ6IHN0cmluZztcbiAgZ3Vlc3RUb2tlbjogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgU3dpdGNoRGFzaGJvYXJkUmVzdWx0IHtcbiAgZGFzaGJvYXJkSWQ6IHN0cmluZztcbiAgYWNjZXB0ZWQ6IHRydWU7XG59XG5cbnR5cGUgRGFzaGJvYXJkU3dpdGNoSGFuZGxlciA9IChcbiAgcGF5bG9hZDogU3dpdGNoRGFzaGJvYXJkUGF5bG9hZCxcbikgPT4gUHJvbWlzZTxTd2l0Y2hEYXNoYm9hcmRSZXN1bHQ+O1xuXG5sZXQgZGFzaGJvYXJkU3dpdGNoSGFuZGxlcjogRGFzaGJvYXJkU3dpdGNoSGFuZGxlciB8IHVuZGVmaW5lZDtcblxuY29uc3QgX19DT01QT05FTlRfTkFNRV9fID0gKCkgPT4ge1xuICBjb25zdCB1aUNvbmZpZyA9IHVzZVVpQ29uZmlnKCk7XG5cbiAgY29uc3QgW2Rhc2hib2FyZElkLCBzZXREYXNoYm9hcmRJZF0gPSB1c2VTdGF0ZTxzdHJpbmcgfCBudWxsPihcbiAgICBib290c3RyYXBEYXRhLmVtYmVkZGVkIS5kYXNoYm9hcmRfaWQsXG4gICk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBkYXNoYm9hcmRTd2l0Y2hIYW5kbGVyID0gYXN5bmMgKHtcbiAgICAgIGRhc2hib2FyZElkOiByZXF1ZXN0ZWREYXNoYm9hcmRJZCxcbiAgICAgIGd1ZXN0VG9rZW4sXG4gICAgfTogU3dpdGNoRGFzaGJvYXJkUGF5bG9hZCkgPT4ge1xuICAgICAgY29uc3QgbmV4dERhc2hib2FyZElkID0gcmVxdWVzdGVkRGFzaGJvYXJkSWQudHJpbSgpO1xuXG4gICAgICBpZiAoIW5leHREYXNoYm9hcmRJZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ2Rhc2hib2FyZElkIG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nJyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgZ3Vlc3RUb2tlbiAhPT0gJ3N0cmluZycgfHxcbiAgICAgICAgZ3Vlc3RUb2tlbi50cmltKCkubGVuZ3RoID09PSAwXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdndWVzdFRva2VuIG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nJyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgc2V0RGFzaGJvYXJkSWQobnVsbCk7XG5cbiAgICAgIGRpc3BsYXllZFVuYXV0aG9yaXplZFRvYXN0ID0gZmFsc2U7XG5cbiAgICAgIHNldHVwR3Vlc3RDbGllbnQoZ3Vlc3RUb2tlbik7XG5cbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4ge1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHJlc29sdmUoKSk7XG4gICAgICB9KTtcblxuICAgICAgc2V0RGFzaGJvYXJkSWQobmV4dERhc2hib2FyZElkKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGFzaGJvYXJkSWQ6IG5leHREYXNoYm9hcmRJZCxcbiAgICAgICAgYWNjZXB0ZWQ6IHRydWUsXG4gICAgICB9O1xuICAgIH07XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZGFzaGJvYXJkU3dpdGNoSGFuZGxlciA9IHVuZGVmaW5lZDtcbiAgICB9O1xuICB9LCBbXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIXVpQ29uZmlnPy5lbWl0RGF0YU1hc2tzKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGxldCBwcmV2aW91c0RhdGFNYXNrID0gc3RvcmUuZ2V0U3RhdGUoKS5kYXRhTWFzaztcblxuICAgIHJldHVybiBzdG9yZS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudERhdGFNYXNrID0gc3RvcmUuZ2V0U3RhdGUoKS5kYXRhTWFzaztcblxuICAgICAgaWYgKHByZXZpb3VzRGF0YU1hc2sgIT09IGN1cnJlbnREYXRhTWFzaykge1xuICAgICAgICBTd2l0Y2hib2FyZC5lbWl0KCdvYnNlcnZlRGF0YU1hc2snLCB7XG4gICAgICAgICAgLi4uY3VycmVudERhdGFNYXNrLFxuICAgICAgICAgIC4uLmdldERhdGFNYXNrQ2hhbmdlVHJpZ2dlcihcbiAgICAgICAgICAgIGN1cnJlbnREYXRhTWFzayxcbiAgICAgICAgICAgIHByZXZpb3VzRGF0YU1hc2ssXG4gICAgICAgICAgKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcHJldmlvdXNEYXRhTWFzayA9IGN1cnJlbnREYXRhTWFzaztcbiAgICAgIH1cbiAgICB9KTtcbiAgfSwgW3VpQ29uZmlnPy5lbWl0RGF0YU1hc2tzXSk7XG5cbiAgaWYgKCFkYXNoYm9hcmRJZCkge1xuICAgIHJldHVybiA8TG9hZGluZyAvPjtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPExhenlEYXNoYm9hcmRQYWdlXG4gICAgICBrZXk9e2Rhc2hib2FyZElkfVxuICAgICAgaWRPclNsdWc9e2Rhc2hib2FyZElkfVxuICAgIC8+XG4gICk7XG59O1xuXCJcIlwiLnJlcGxhY2UoXCJfX0NPTVBPTkVOVF9OQU1FX19cIiwgY29tcG9uZW50X25hbWUpXG5cbiAgICBjb250ZW50ID0gKFxuICAgICAgICBjb250ZW50WzogY29tcG9uZW50X21hdGNoLnN0YXJ0KCldXG4gICAgICAgICsgcmVwbGFjZW1lbnRfY29tcG9uZW50XG4gICAgICAgICsgY29udGVudFtjb21wb25lbnRfbWF0Y2guZW5kKCkgOl1cbiAgICApXG5cbiAgICBzd2l0Y2hib2FyZF9hbmNob3JfY2FuZGlkYXRlcyA9IFtcbiAgICAgICAgKFxuICAgICAgICAgICAgXCIgICAgU3dpdGNoYm9hcmQuZGVmaW5lTWV0aG9kKFwiXG4gICAgICAgICAgICBcIidnZXRTY3JvbGxTaXplJywgZW1iZWRkZWRBcGkuZ2V0U2Nyb2xsU2l6ZSk7XCJcbiAgICAgICAgKSxcbiAgICAgICAgKFxuICAgICAgICAgICAgXCIgICAgU3dpdGNoYm9hcmQuZGVmaW5lTWV0aG9kKFxcXFxuXCJcbiAgICAgICAgICAgIFwiICAgICAgJ2dldFNjcm9sbFNpemUnLFxcXFxuXCJcbiAgICAgICAgICAgIFwiICAgICAgZW1iZWRkZWRBcGkuZ2V0U2Nyb2xsU2l6ZSxcXFxcblwiXG4gICAgICAgICAgICBcIiAgICApO1wiXG4gICAgICAgICksXG4gICAgXVxuXG4gICAgc3dpdGNoYm9hcmRfbWV0aG9kID0gXCJcIlwiICAgIFN3aXRjaGJvYXJkLmRlZmluZU1ldGhvZChcbiAgICAgICdzd2l0Y2hEYXNoYm9hcmQnLFxuICAgICAgYXN5bmMgKFxuICAgICAgICBwYXlsb2FkOiBTd2l0Y2hEYXNoYm9hcmRQYXlsb2FkLFxuICAgICAgKTogUHJvbWlzZTxTd2l0Y2hEYXNoYm9hcmRSZXN1bHQ+ID0+IHtcbiAgICAgICAgaWYgKCFkYXNoYm9hcmRTd2l0Y2hIYW5kbGVyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgJ1RoZSBlbWJlZGRlZCBkYXNoYm9hcmQgaXMgbm90IHJlYWR5IHRvIHN3aXRjaCcsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXNoYm9hcmRTd2l0Y2hIYW5kbGVyKHBheWxvYWQpO1xuICAgICAgfSxcbiAgICApO1xuXG5cIlwiXCJcblxuICAgIGFuY2hvcl9mb3VuZCA9IEZhbHNlXG5cbiAgICBmb3IgYW5jaG9yIGluIHN3aXRjaGJvYXJkX2FuY2hvcl9jYW5kaWRhdGVzOlxuICAgICAgICBpZiBjb250ZW50LmNvdW50KGFuY2hvcikgPT0gMTpcbiAgICAgICAgICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgYW5jaG9yLFxuICAgICAgICAgICAgICAgIHN3aXRjaGJvYXJkX21ldGhvZCArIGFuY2hvcixcbiAgICAgICAgICAgICAgICAxLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgYW5jaG9yX2ZvdW5kID0gVHJ1ZVxuICAgICAgICAgICAgYnJlYWtcblxuICAgIGlmIG5vdCBhbmNob3JfZm91bmQ6XG4gICAgICAgIHJhaXNlIFBhdGNoRXJyb3IoXG4gICAgICAgICAgICBcIkNvdWxkIG5vdCBsb2NhdGUgdGhlIGdldFNjcm9sbFNpemUgU3dpdGNoYm9hcmQgbWV0aG9kXCJcbiAgICAgICAgKVxuXG4gICAgZnJvbnRlbmRfcGF0aC53cml0ZV90ZXh0KGNvbnRlbnQsIGVuY29kaW5nPVwidXRmLThcIilcbiAgICBwcmludChmXCJQYXRjaGVkOiB7ZnJvbnRlbmRfcGF0aH1cIilcblxuXG5kZWYgcGF0Y2hfZ3Vlc3RfdG9rZW5fZmV0Y2hfdHlwZShjb250ZW50OiBzdHIpIC0+IHN0cjpcbiAgICBjYW5kaWRhdGVzID0gW1xuICAgICAgICBcImV4cG9ydCB0eXBlIEd1ZXN0VG9rZW5GZXRjaEZuID0gKCkgPT4gUHJvbWlzZTxzdHJpbmc+O1wiLFxuICAgICAgICAoXG4gICAgICAgICAgICBcImV4cG9ydCB0eXBlIEd1ZXN0VG9rZW5GZXRjaEZuID0gXCJcbiAgICAgICAgICAgIFwiKCkgPT4gUHJvbWlzZTxzdHJpbmc+O1wiXG4gICAgICAgICksXG4gICAgXVxuXG4gICAgcmVwbGFjZW1lbnQgPSBcIlwiXCIvLyBTVVBFUlNFVF9TV0lUQ0hBQkxFX0VNQkVEX1NES19QQVRDSFxuLy9cbi8vIGRhc2hib2FyZElkIGlzIHVuZGVmaW5lZCBmb3IgdGhlIGluaXRpYWwgZGFzaGJvYXJkIGJvb3RzdHJhcC5cbi8vIEFmdGVyIGEgc3VjY2Vzc2Z1bCBkYXNoYm9hcmQgc3dpdGNoLCB0b2tlbiByZWZyZXNoZXMgcmVjZWl2ZSB0aGUgYWN0aXZlXG4vLyBkYXNoYm9hcmQgVVVJRC5cbmV4cG9ydCB0eXBlIEd1ZXN0VG9rZW5GZXRjaEZuID0gKFxuICBkYXNoYm9hcmRJZD86IHN0cmluZyxcbikgPT4gUHJvbWlzZTxzdHJpbmc+O1wiXCJcIlxuXG4gICAgZm9yIGNhbmRpZGF0ZSBpbiBjYW5kaWRhdGVzOlxuICAgICAgICBpZiBjb250ZW50LmNvdW50KGNhbmRpZGF0ZSkgPT0gMTpcbiAgICAgICAgICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlLFxuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICApXG5cbiAgICByYWlzZSBQYXRjaEVycm9yKFwiQ291bGQgbm90IGxvY2F0ZSBHdWVzdFRva2VuRmV0Y2hGblwiKVxuXG5cbmRlZiBwYXRjaF9lbWJlZGRlZF9kYXNoYm9hcmRfdHlwZShjb250ZW50OiBzdHIpIC0+IHN0cjpcbiAgICB0eXBlX3BhdHRlcm4gPSByZS5jb21waWxlKFxuICAgICAgICByXCIoZXhwb3J0XFxcXHMrKD86aW50ZXJmYWNlfHR5cGUpXFxcXHMrRW1iZWRkZWREYXNoYm9hcmRcIlxuICAgICAgICByXCIuKj9cXFxceykoLio/KShcXFxcblxcXFx9OylcIixcbiAgICAgICAgcmUuRE9UQUxMLFxuICAgIClcblxuICAgIG1hdGNoID0gdHlwZV9wYXR0ZXJuLnNlYXJjaChjb250ZW50KVxuXG4gICAgaWYgbm90IG1hdGNoOlxuICAgICAgICByYWlzZSBQYXRjaEVycm9yKFxuICAgICAgICAgICAgXCJDb3VsZCBub3QgbG9jYXRlIHRoZSBFbWJlZGRlZERhc2hib2FyZCBwdWJsaWMgdHlwZVwiXG4gICAgICAgIClcblxuICAgIGJvZHkgPSBtYXRjaC5ncm91cCgyKVxuXG4gICAgaWYgXCJzd2l0Y2hEYXNoYm9hcmQ6XCIgaW4gYm9keTpcbiAgICAgICAgcmV0dXJuIGNvbnRlbnRcblxuICAgIG1ldGhvZCA9IFwiXCJcIlxuICAvKipcbiAgICogUmVwbGFjZXMgRGFzaGJvYXJkUGFnZSBpbiB0aGUgZXhpc3RpbmcgaWZyYW1lIGRvY3VtZW50LlxuICAgKlxuICAgKiBUaGUgdmFsdWUgbXVzdCBiZSB0aGUgdGFyZ2V0IGRhc2hib2FyZCBVVUlEL2lkIGFjY2VwdGVkIGJ5XG4gICAqIERhc2hib2FyZFBhZ2UsIG5vdCB0aGUgZW1iZWRkZWQtY29uZmlndXJhdGlvbiBVVUlEIHVzZWQgaW4gdGhlXG4gICAqIGluaXRpYWwgL2VtYmVkZGVkLzp1dWlkIFVSTC5cbiAgICovXG4gIHN3aXRjaERhc2hib2FyZDogKFxuICAgIGRhc2hib2FyZElkOiBzdHJpbmcsXG4gICkgPT4gUHJvbWlzZTx7XG4gICAgZGFzaGJvYXJkSWQ6IHN0cmluZztcbiAgICBhY2NlcHRlZDogdHJ1ZTtcbiAgfT47XG5cIlwiXCJcblxuICAgIHVwZGF0ZWRfdHlwZSA9IChcbiAgICAgICAgbWF0Y2guZ3JvdXAoMSlcbiAgICAgICAgKyBib2R5LnJzdHJpcCgpXG4gICAgICAgICsgXCJcXFxcblwiXG4gICAgICAgICsgbWV0aG9kLnJzdHJpcCgpXG4gICAgICAgICsgbWF0Y2guZ3JvdXAoMylcbiAgICApXG5cbiAgICByZXR1cm4gKFxuICAgICAgICBjb250ZW50WzogbWF0Y2guc3RhcnQoKV1cbiAgICAgICAgKyB1cGRhdGVkX3R5cGVcbiAgICAgICAgKyBjb250ZW50W21hdGNoLmVuZCgpIDpdXG4gICAgKVxuXG5cbmRlZiBwYXRjaF9pbml0aWFsX2d1ZXN0X3Rva2VuX2ZldGNoKGNvbnRlbnQ6IHN0cikgLT4gc3RyOlxuICAgIGNhbmRpZGF0ZXMgPSBbXG4gICAgICAgIFwiZmV0Y2hHdWVzdFRva2VuKCksXCIsXG4gICAgICAgIFwiYXdhaXQgZmV0Y2hHdWVzdFRva2VuKCksXCIsXG4gICAgXVxuXG4gICAgZm9yIGNhbmRpZGF0ZSBpbiBjYW5kaWRhdGVzOlxuICAgICAgICBpZiBjb250ZW50LmNvdW50KGNhbmRpZGF0ZSkgPj0gMTpcbiAgICAgICAgICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlLFxuICAgICAgICAgICAgICAgIGNhbmRpZGF0ZS5yZXBsYWNlKFxuICAgICAgICAgICAgICAgICAgICBcImZldGNoR3Vlc3RUb2tlbigpXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiZmV0Y2hHdWVzdFRva2VuKHVuZGVmaW5lZClcIixcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICApXG5cbiAgICByYWlzZSBQYXRjaEVycm9yKFxuICAgICAgICBcIkNvdWxkIG5vdCBsb2NhdGUgdGhlIGluaXRpYWwgZmV0Y2hHdWVzdFRva2VuIGNhbGxcIlxuICAgIClcblxuXG5kZWYgcGF0Y2hfZ3Vlc3RfdG9rZW5fcmVmcmVzaChjb250ZW50OiBzdHIpIC0+IHN0cjpcbiAgICBwYXR0ZXJucyA9IFtcbiAgICAgICAgcmUuY29tcGlsZShcbiAgICAgICAgICAgIHJcImFzeW5jIGZ1bmN0aW9uIHJlZnJlc2hHdWVzdFRva2VuXFxcXChcXFxcKSBcXFxce1xcXFxzKlwiXG4gICAgICAgICAgICByXCJjb25zdCBuZXdHdWVzdFRva2VuID0gYXdhaXQgZmV0Y2hHdWVzdFRva2VuXFxcXChcXFxcKTtcXFxccypcIlxuICAgICAgICAgICAgclwib3VyUG9ydFxcXFwuZW1pdFxcXFwoXCJcbiAgICAgICAgICAgIHJcIidndWVzdFRva2VuJyxcXFxccypcXFxce1xcXFxzKmd1ZXN0VG9rZW46XFxcXHMqbmV3R3Vlc3RUb2tlblxcXFxzKlxcXFx9XCJcbiAgICAgICAgICAgIHJcIlxcXFwpO1xcXFxzKlwiXG4gICAgICAgICAgICByXCJzZXRUaW1lb3V0XFxcXChcIlxuICAgICAgICAgICAgclwicmVmcmVzaEd1ZXN0VG9rZW4sXFxcXHMqXCJcbiAgICAgICAgICAgIHJcImdldEd1ZXN0VG9rZW5SZWZyZXNoVGltaW5nXFxcXChuZXdHdWVzdFRva2VuXFxcXClcIlxuICAgICAgICAgICAgclwiXFxcXCk7XFxcXHMqXCJcbiAgICAgICAgICAgIHJcIlxcXFx9XCIsXG4gICAgICAgICAgICByZS5ET1RBTEwsXG4gICAgICAgICksXG4gICAgICAgIHJlLmNvbXBpbGUoXG4gICAgICAgICAgICByXCJjb25zdCByZWZyZXNoR3Vlc3RUb2tlbiA9IGFzeW5jIFxcXFwoXFxcXCkgPT4gXFxcXHtcXFxccypcIlxuICAgICAgICAgICAgclwiY29uc3QgbmV3R3Vlc3RUb2tlbiA9IGF3YWl0IGZldGNoR3Vlc3RUb2tlblxcXFwoXFxcXCk7XFxcXHMqXCJcbiAgICAgICAgICAgIHJcIm91clBvcnRcXFxcLmVtaXRcXFxcKFwiXG4gICAgICAgICAgICByXCInZ3Vlc3RUb2tlbicsXFxcXHMqXFxcXHtcXFxccypndWVzdFRva2VuOlxcXFxzKm5ld0d1ZXN0VG9rZW5cXFxccypcXFxcfVwiXG4gICAgICAgICAgICByXCJcXFxcKTtcXFxccypcIlxuICAgICAgICAgICAgclwic2V0VGltZW91dFxcXFwoXCJcbiAgICAgICAgICAgIHJcInJlZnJlc2hHdWVzdFRva2VuLFxcXFxzKlwiXG4gICAgICAgICAgICByXCJnZXRHdWVzdFRva2VuUmVmcmVzaFRpbWluZ1xcXFwobmV3R3Vlc3RUb2tlblxcXFwpXCJcbiAgICAgICAgICAgIHJcIlxcXFwpO1xcXFxzKlwiXG4gICAgICAgICAgICByXCJcXFxcfTtcIixcbiAgICAgICAgICAgIHJlLkRPVEFMTCxcbiAgICAgICAgKSxcbiAgICBdXG5cbiAgICByZXBsYWNlbWVudCA9IFwiXCJcImxldCBhY3RpdmVEYXNoYm9hcmRJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlZnJlc2hHdWVzdFRva2VuKCkge1xuICAgIGNvbnN0IG5ld0d1ZXN0VG9rZW4gPSBhd2FpdCBmZXRjaEd1ZXN0VG9rZW4oXG4gICAgICBhY3RpdmVEYXNoYm9hcmRJZCxcbiAgICApO1xuXG4gICAgb3VyUG9ydC5lbWl0KCdndWVzdFRva2VuJywge1xuICAgICAgZ3Vlc3RUb2tlbjogbmV3R3Vlc3RUb2tlbixcbiAgICB9KTtcblxuICAgIHNldFRpbWVvdXQoXG4gICAgICByZWZyZXNoR3Vlc3RUb2tlbixcbiAgICAgIGdldEd1ZXN0VG9rZW5SZWZyZXNoVGltaW5nKG5ld0d1ZXN0VG9rZW4pLFxuICAgICk7XG4gIH1cIlwiXCJcblxuICAgIGZvciBwYXR0ZXJuIGluIHBhdHRlcm5zOlxuICAgICAgICB1cGRhdGVkLCBjb3VudCA9IHBhdHRlcm4uc3VibihcbiAgICAgICAgICAgIHJlcGxhY2VtZW50LFxuICAgICAgICAgICAgY29udGVudCxcbiAgICAgICAgICAgIGNvdW50PTEsXG4gICAgICAgIClcblxuICAgICAgICBpZiBjb3VudCA9PSAxOlxuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZWRcblxuICAgIHJhaXNlIFBhdGNoRXJyb3IoXG4gICAgICAgIFwiQ291bGQgbm90IGxvY2F0ZSB0aGUgZ3Vlc3QtdG9rZW4gcmVmcmVzaCBmdW5jdGlvblwiXG4gICAgKVxuXG5cbmRlZiBwYXRjaF9zZGtfZnVuY3Rpb25zKGNvbnRlbnQ6IHN0cikgLT4gc3RyOlxuICAgIGFuY2hvcl9jYW5kaWRhdGVzID0gW1xuICAgICAgICAoXG4gICAgICAgICAgICBcIiAgY29uc3QgZ2V0U2Nyb2xsU2l6ZSA9ICgpID0+IFwiXG4gICAgICAgICAgICBcIm91clBvcnQuZ2V0PFNpemU+KCdnZXRTY3JvbGxTaXplJyk7XCJcbiAgICAgICAgKSxcbiAgICAgICAgKFxuICAgICAgICAgICAgXCIgIGNvbnN0IGdldFNjcm9sbFNpemUgPSAoKSA9PlxcXFxuXCJcbiAgICAgICAgICAgIFwiICAgIG91clBvcnQuZ2V0PFNpemU+KCdnZXRTY3JvbGxTaXplJyk7XCJcbiAgICAgICAgKSxcbiAgICBdXG5cbiAgICBzd2l0Y2hfZnVuY3Rpb24gPSBcIlwiXCIgIGNvbnN0IHN3aXRjaERhc2hib2FyZCA9IGFzeW5jIChcbiAgICBkYXNoYm9hcmRJZDogc3RyaW5nLFxuICApOiBQcm9taXNlPHtcbiAgICBkYXNoYm9hcmRJZDogc3RyaW5nO1xuICAgIGFjY2VwdGVkOiB0cnVlO1xuICB9PiA9PiB7XG4gICAgY29uc3Qgbm9ybWFsaXplZERhc2hib2FyZElkID0gZGFzaGJvYXJkSWQudHJpbSgpO1xuXG4gICAgaWYgKCFub3JtYWxpemVkRGFzaGJvYXJkSWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ2Rhc2hib2FyZElkIG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgZ3Vlc3RUb2tlbiA9IGF3YWl0IGZldGNoR3Vlc3RUb2tlbihcbiAgICAgIG5vcm1hbGl6ZWREYXNoYm9hcmRJZCxcbiAgICApO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb3VyUG9ydC5nZXQ8e1xuICAgICAgZGFzaGJvYXJkSWQ6IHN0cmluZztcbiAgICAgIGFjY2VwdGVkOiB0cnVlO1xuICAgIH0+KCdzd2l0Y2hEYXNoYm9hcmQnLCB7XG4gICAgICBkYXNoYm9hcmRJZDogbm9ybWFsaXplZERhc2hib2FyZElkLFxuICAgICAgZ3Vlc3RUb2tlbixcbiAgICB9KTtcblxuICAgIGFjdGl2ZURhc2hib2FyZElkID0gbm9ybWFsaXplZERhc2hib2FyZElkO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuXCJcIlwiXG5cbiAgICBmb3IgYW5jaG9yIGluIGFuY2hvcl9jYW5kaWRhdGVzOlxuICAgICAgICBpZiBjb250ZW50LmNvdW50KGFuY2hvcikgPT0gMTpcbiAgICAgICAgICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgYW5jaG9yLFxuICAgICAgICAgICAgICAgIHN3aXRjaF9mdW5jdGlvbiArIGFuY2hvcixcbiAgICAgICAgICAgICAgICAxLFxuICAgICAgICAgICAgKVxuXG4gICAgcmFpc2UgUGF0Y2hFcnJvcihcbiAgICAgICAgXCJDb3VsZCBub3QgbG9jYXRlIHRoZSBTREsgZ2V0U2Nyb2xsU2l6ZSBmdW5jdGlvblwiXG4gICAgKVxuXG5cbmRlZiBwYXRjaF9zZGtfcmV0dXJuX29iamVjdChjb250ZW50OiBzdHIpIC0+IHN0cjpcbiAgICBjYW5kaWRhdGVzID0gW1xuICAgICAgICBcIiAgICBzZXRUaGVtZU1vZGUsXFxcXG4gIH07XCIsXG4gICAgICAgIFwiICAgIHNldFRoZW1lTW9kZSxcXFxcbiAgICB1bm1vdW50LFxcXFxuICB9O1wiLFxuICAgICAgICBcIiAgICB1bm1vdW50LFxcXFxuICAgIHNldFRoZW1lTW9kZSxcXFxcbiAgfTtcIixcbiAgICBdXG5cbiAgICBmb3IgY2FuZGlkYXRlIGluIGNhbmRpZGF0ZXM6XG4gICAgICAgIGlmIGNvbnRlbnQuY291bnQoY2FuZGlkYXRlKSA9PSAxOlxuICAgICAgICAgICAgbGluZXMgPSBjYW5kaWRhdGUuc3BsaXRsaW5lcygpXG5cbiAgICAgICAgICAgIGNsb3NpbmcgPSBsaW5lcy5wb3AoKVxuICAgICAgICAgICAgYm9keSA9IFwiXFxcXG5cIi5qb2luKGxpbmVzKVxuXG4gICAgICAgICAgICByZXR1cm4gY29udGVudC5yZXBsYWNlKFxuICAgICAgICAgICAgICAgIGNhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICBib2R5XG4gICAgICAgICAgICAgICAgKyBcIlxcXFxuXCJcbiAgICAgICAgICAgICAgICArIFwiICAgIHN3aXRjaERhc2hib2FyZCxcXFxcblwiXG4gICAgICAgICAgICAgICAgKyBjbG9zaW5nLFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICApXG5cbiAgICByYWlzZSBQYXRjaEVycm9yKFxuICAgICAgICBcIkNvdWxkIG5vdCBsb2NhdGUgdGhlIEVtYmVkZGVkRGFzaGJvYXJkIHJldHVybiBvYmplY3RcIlxuICAgIClcblxuXG5kZWYgcGF0Y2hfc2RrKHNka19wYXRoOiBQYXRoKSAtPiBOb25lOlxuICAgIGNvbnRlbnQgPSBzZGtfcGF0aC5yZWFkX3RleHQoZW5jb2Rpbmc9XCJ1dGYtOFwiKVxuXG4gICAgaWYgXCJTVVBFUlNFVF9TV0lUQ0hBQkxFX0VNQkVEX1NES19QQVRDSFwiIGluIGNvbnRlbnQ6XG4gICAgICAgIHByaW50KGZcIkFscmVhZHkgcGF0Y2hlZDoge3Nka19wYXRofVwiKVxuICAgICAgICByZXR1cm5cblxuICAgIGNvbnRlbnQgPSBwYXRjaF9ndWVzdF90b2tlbl9mZXRjaF90eXBlKGNvbnRlbnQpXG4gICAgY29udGVudCA9IHBhdGNoX2VtYmVkZGVkX2Rhc2hib2FyZF90eXBlKGNvbnRlbnQpXG4gICAgY29udGVudCA9IHBhdGNoX2luaXRpYWxfZ3Vlc3RfdG9rZW5fZmV0Y2goY29udGVudClcbiAgICBjb250ZW50ID0gcGF0Y2hfZ3Vlc3RfdG9rZW5fcmVmcmVzaChjb250ZW50KVxuICAgIGNvbnRlbnQgPSBwYXRjaF9zZGtfZnVuY3Rpb25zKGNvbnRlbnQpXG4gICAgY29udGVudCA9IHBhdGNoX3Nka19yZXR1cm5fb2JqZWN0KGNvbnRlbnQpXG5cbiAgICBzZGtfcGF0aC53cml0ZV90ZXh0KGNvbnRlbnQsIGVuY29kaW5nPVwidXRmLThcIilcbiAgICBwcmludChmXCJQYXRjaGVkOiB7c2RrX3BhdGh9XCIpXG5cblxuZGVmIG1haW4oKSAtPiBpbnQ6XG4gICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoXG4gICAgICAgIGRlc2NyaXB0aW9uPShcbiAgICAgICAgICAgIFwiQXBwbHkgdGhlIHN3aXRjaGFibGUtZGFzaGJvYXJkIHBhdGNoIHRvIGEgXCJcbiAgICAgICAgICAgIFwiU3VwZXJzZXQgNi4xLnggc291cmNlIGNoZWNrb3V0LlwiXG4gICAgICAgIClcbiAgICApXG5cbiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KFxuICAgICAgICBcInN1cGVyc2V0X3Jvb3RcIixcbiAgICAgICAgdHlwZT1QYXRoLFxuICAgICAgICBoZWxwPVwiUGF0aCB0byB0aGUgQXBhY2hlIFN1cGVyc2V0IHNvdXJjZSBjaGVja291dFwiLFxuICAgIClcblxuICAgIGFyZ3MgPSBwYXJzZXIucGFyc2VfYXJncygpXG4gICAgcm9vdCA9IGFyZ3Muc3VwZXJzZXRfcm9vdC5yZXNvbHZlKClcblxuICAgIGZyb250ZW5kX3BhdGggPSByb290IC8gRlJPTlRFTkRfRklMRVxuICAgIHNka19wYXRoID0gcm9vdCAvIFNES19GSUxFXG5cbiAgICBtaXNzaW5nID0gW1xuICAgICAgICBwYXRoXG4gICAgICAgIGZvciBwYXRoIGluIFtmcm9udGVuZF9wYXRoLCBzZGtfcGF0aF1cbiAgICAgICAgaWYgbm90IHBhdGguZXhpc3RzKClcbiAgICBdXG5cbiAgICBpZiBtaXNzaW5nOlxuICAgICAgICBwcmludChcbiAgICAgICAgICAgIFwiVGhlIHRhcmdldCBkb2VzIG5vdCBhcHBlYXIgdG8gYmUgYSBjb21wYXRpYmxlIFwiXG4gICAgICAgICAgICBcIlN1cGVyc2V0IHNvdXJjZSBjaGVja291dC5cIixcbiAgICAgICAgICAgIGZpbGU9c3lzLnN0ZGVycixcbiAgICAgICAgKVxuXG4gICAgICAgIGZvciBtaXNzaW5nX3BhdGggaW4gbWlzc2luZzpcbiAgICAgICAgICAgIHByaW50KGZcIk1pc3Npbmc6IHttaXNzaW5nX3BhdGh9XCIsIGZpbGU9c3lzLnN0ZGVycilcblxuICAgICAgICByZXR1cm4gMlxuXG4gICAgdHJ5OlxuICAgICAgICBwYXRjaF9mcm9udGVuZChmcm9udGVuZF9wYXRoKVxuICAgICAgICBwYXRjaF9zZGsoc2RrX3BhdGgpXG4gICAgZXhjZXB0IFBhdGNoRXJyb3IgYXMgZXJyb3I6XG4gICAgICAgIHByaW50KGZcIlBhdGNoIGZhaWxlZDoge2Vycm9yfVwiLCBmaWxlPXN5cy5zdGRlcnIpXG4gICAgICAgIHJldHVybiAxXG5cbiAgICBwcmludChcIlBhdGNoIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkuXCIpXG4gICAgcmV0dXJuIDBcblxuXG5pZiBfX25hbWVfXyA9PSBcIl9fbWFpbl9fXCI6XG4gICAgcmFpc2UgU3lzdGVtRXhpdChtYWluKCkpXG5gO1xuXG5jb25zdCBWRVJJRllfUEFUQ0hfU0ggPSBgIyEvdXNyL2Jpbi9lbnYgYmFzaFxuXG5zZXQgLWV1byBwaXBlZmFpbFxuXG5TVVBFUlNFVF9ST09UPVxcJHsxOj9Vc2FnZTogdmVyaWZ5X3BhdGNoLnNoIC9wYXRoL3RvL3N1cGVyc2V0fVxuXG5GUk9OVEVORF9GSUxFPVwiJFNVUEVSU0VUX1JPT1Qvc3VwZXJzZXQtZnJvbnRlbmQvc3JjL2VtYmVkZGVkL2luZGV4LnRzeFwiXG5TREtfRklMRT1cIiRTVVBFUlNFVF9ST09UL3N1cGVyc2V0LWVtYmVkZGVkLXNkay9zcmMvaW5kZXgudHNcIlxuXG50ZXN0IC1mIFwiJEZST05URU5EX0ZJTEVcIlxudGVzdCAtZiBcIiRTREtfRklMRVwiXG5cbmdyZXAgLXEgXFxcXFxuICBcIlNVUEVSU0VUX1NXSVRDSEFCTEVfRU1CRURfUEFUQ0hcIiBcXFxcXG4gIFwiJEZST05URU5EX0ZJTEVcIlxuXG5ncmVwIC1xIFxcXFxcbiAgXCInc3dpdGNoRGFzaGJvYXJkJ1wiIFxcXFxcbiAgXCIkRlJPTlRFTkRfRklMRVwiXG5cbmdyZXAgLXEgXFxcXFxuICBcImRhc2hib2FyZFN3aXRjaEhhbmRsZXJcIiBcXFxcXG4gIFwiJEZST05URU5EX0ZJTEVcIlxuXG5ncmVwIC1xIFxcXFxcbiAgXCJTVVBFUlNFVF9TV0lUQ0hBQkxFX0VNQkVEX1NES19QQVRDSFwiIFxcXFxcbiAgXCIkU0RLX0ZJTEVcIlxuXG5ncmVwIC1xIFxcXFxcbiAgXCJzd2l0Y2hEYXNoYm9hcmQ6XCIgXFxcXFxuICBcIiRTREtfRklMRVwiXG5cbmdyZXAgLXEgXFxcXFxuICBcImFjdGl2ZURhc2hib2FyZElkXCIgXFxcXFxuICBcIiRTREtfRklMRVwiXG5cbmdyZXAgLXEgXFxcXFxuICBcImZldGNoR3Vlc3RUb2tlbihcIiBcXFxcXG4gIFwiJFNES19GSUxFXCJcblxuZWNobyBcIlRoZSBzd2l0Y2hhYmxlLWRhc2hib2FyZCBwYXRjaCBpcyBwcmVzZW50LlwiXG5gO1xuXG5jb25zdCBCVUlMRF9TREtfU0ggPSBgIyEvdXNyL2Jpbi9lbnYgYmFzaFxuXG5zZXQgLWV1byBwaXBlZmFpbFxuXG5TVVBFUlNFVF9ST09UPVxcJHsxOj9Vc2FnZTogYnVpbGQtc2RrLnNoIC9wYXRoL3RvL3N1cGVyc2V0fVxuXG5TREtfUk9PVD1cIiRTVVBFUlNFVF9ST09UL3N1cGVyc2V0LWVtYmVkZGVkLXNka1wiXG5cbmlmIFsgISAtZiBcIiRTREtfUk9PVC9wYWNrYWdlLmpzb25cIiBdOyB0aGVuXG4gIGVjaG8gXCJNaXNzaW5nIFNESyBwYWNrYWdlOiAkU0RLX1JPT1RcIiA+JjJcbiAgZXhpdCAxXG5maVxuXG5jZCBcIiRTREtfUk9PVFwiXG5cbm5wbSBjaVxuXG5ucG0gcnVuIGJ1aWxkXG5cbmVjaG9cbmVjaG8gXCJFbWJlZGRlZCBTREsgYnVpbGQgY29tcGxldGVkLlwiXG5lY2hvIFwiT3V0cHV0IGRpcmVjdG9yeTpcIlxuZmluZCAuIFxcXFxcbiAgLW1heGRlcHRoIDIgXFxcXFxuICAtdHlwZSBkIFxcXFxcbiAgXFxcXCggLW5hbWUgZGlzdCAtbyAtbmFtZSBsaWIgXFxcXCkgXFxcXFxuICAtcHJpbnRcbmA7XG5cbmNvbnN0IEJVSUxEX0ZST05URU5EX1NIID0gYCMhL3Vzci9iaW4vZW52IGJhc2hcblxuc2V0IC1ldW8gcGlwZWZhaWxcblxuU1VQRVJTRVRfUk9PVD1cXCR7MTo/VXNhZ2U6IGJ1aWxkLXN1cGVyc2V0LWZyb250ZW5kLnNoIC9wYXRoL3RvL3N1cGVyc2V0fVxuXG5GUk9OVEVORF9ST09UPVwiJFNVUEVSU0VUX1JPT1Qvc3VwZXJzZXQtZnJvbnRlbmRcIlxuXG5pZiBbICEgLWYgXCIkRlJPTlRFTkRfUk9PVC9wYWNrYWdlLmpzb25cIiBdOyB0aGVuXG4gIGVjaG8gXCJNaXNzaW5nIFN1cGVyc2V0IGZyb250ZW5kOiAkRlJPTlRFTkRfUk9PVFwiID4mMlxuICBleGl0IDFcbmZpXG5cbmNkIFwiJEZST05URU5EX1JPT1RcIlxuXG5ucG0gY2lcblxubnBtIHJ1biBidWlsZFxuXG5lY2hvIFwiU3VwZXJzZXQgZnJvbnRlbmQgYnVpbGQgY29tcGxldGVkLlwiXG5gO1xuXG5jb25zdCBQQVRDSF9BTkRfQlVJTERfU0ggPSBgIyEvdXNyL2Jpbi9lbnYgYmFzaFxuXG5zZXQgLWV1byBwaXBlZmFpbFxuXG5TVVBFUlNFVF9ST09UPVxcJHsxOj9Vc2FnZTogcGF0Y2gtYW5kLWJ1aWxkLnNoIC9wYXRoL3RvL3N1cGVyc2V0fVxuXG5TQ1JJUFRfRElSPSQoXG4gIGNkIFwiJChkaXJuYW1lIFwiXFwke0JBU0hfU09VUkNFWzBdfVwiKVwiXG4gIHB3ZFxuKVxuXG5QUk9KRUNUX1JPT1Q9JChcbiAgY2QgXCIkU0NSSVBUX0RJUi8uLlwiXG4gIHB3ZFxuKVxuXG5weXRob24zIFxcXFxcbiAgXCIkUFJPSkVDVF9ST09UL3BhdGNoZXMvYXBwbHlfc3VwZXJzZXRfNl8xX3BhdGNoLnB5XCIgXFxcXFxuICBcIiRTVVBFUlNFVF9ST09UXCJcblxuXCIkUFJPSkVDVF9ST09UL3BhdGNoZXMvdmVyaWZ5X3BhdGNoLnNoXCIgXFxcXFxuICBcIiRTVVBFUlNFVF9ST09UXCJcblxuXCIkU0NSSVBUX0RJUi9idWlsZC1zZGsuc2hcIiBcXFxcXG4gIFwiJFNVUEVSU0VUX1JPT1RcIlxuXG5cIiRTQ1JJUFRfRElSL2J1aWxkLXN1cGVyc2V0LWZyb250ZW5kLnNoXCIgXFxcXFxuICBcIiRTVVBFUlNFVF9ST09UXCJcblxuZWNob1xuZWNobyBcIlBhdGNoIGFuZCBmcm9udGVuZCBidWlsZHMgY29tcGxldGVkLlwiXG5gO1xuXG5jb25zdCBCVUlMRF9ET0NLRVJfU0ggPSBgIyEvdXNyL2Jpbi9lbnYgYmFzaFxuXG5zZXQgLWV1byBwaXBlZmFpbFxuXG5TVVBFUlNFVF9ST09UPVxcJHsxOj9Vc2FnZTogYnVpbGQtZG9ja2VyLWltYWdlLnNoIC9wYXRoL3RvL3N1cGVyc2V0IFtpbWFnZS10YWddfVxuSU1BR0VfVEFHPVxcJHsyOi1sb2NhbC9zdXBlcnNldC1zd2l0Y2hhYmxlOjYuMS4wfVxuXG5TQ1JJUFRfRElSPSQoXG4gIGNkIFwiJChkaXJuYW1lIFwiXFwke0JBU0hfU09VUkNFWzBdfVwiKVwiXG4gIHB3ZFxuKVxuXG5QUk9KRUNUX1JPT1Q9JChcbiAgY2QgXCIkU0NSSVBUX0RJUi8uLlwiXG4gIHB3ZFxuKVxuXG5weXRob24zIFxcXFxcbiAgXCIkUFJPSkVDVF9ST09UL3BhdGNoZXMvYXBwbHlfc3VwZXJzZXRfNl8xX3BhdGNoLnB5XCIgXFxcXFxuICBcIiRTVVBFUlNFVF9ST09UXCJcblxuXCIkUFJPSkVDVF9ST09UL3BhdGNoZXMvdmVyaWZ5X3BhdGNoLnNoXCIgXFxcXFxuICBcIiRTVVBFUlNFVF9ST09UXCJcblxuY2QgXCIkU1VQRVJTRVRfUk9PVFwiXG5cbmRvY2tlciBidWlsZCBcXFxcXG4gIC0tdGFyZ2V0IGxlYW4gXFxcXFxuICAtLXRhZyBcIiRJTUFHRV9UQUdcIiBcXFxcXG4gIC5cblxuZWNobyBcIkJ1aWx0IERvY2tlciBpbWFnZTogJElNQUdFX1RBR1wiXG5gO1xuXG5jb25zdCBSRUFETUUgPSBgIyAke1NVUEVSU0VUX1BMVUdJTl9JRH1cblxuTXVsdGktdGVuYW50LCBvcmctYWdub3N0aWMgU3VwZXJzZXQgZGFzaGJvYXJkIGVtYmVkIHBsdWdpbiAocGF0Y2gtYW5kLWJ1aWxkIHN0cmF0ZWd5KS5cblxuVGhpcyBpcyBub3QgYSBnZW5lcmF0ZWQgcGx1Z2luIGxpa2UgdGhlIEtpYmFuYSB2YXJpYW50LiBJbnN0ZWFkLCBEZWNhZiBob2xkc1xucGF0Y2ggc2NyaXB0cyB0aGF0IG1vZGlmeSBTdXBlcnNldCdzIGludGVybmFsIGVtYmVkZGVkIGZyb250ZW5kIGFuZCBlbWJlZGRlZFxuU0RLIHNvdXJjZSBmaWxlcyB0byBhZGQgYSBcXGBzd2l0Y2hEYXNoYm9hcmRcXGAgbWV0aG9kLiBUaGUgZXhpc3RpbmcgaWZyYW1lXG5lbGVtZW50LCBkb2N1bWVudCwgY29udGVudFdpbmRvdywgUmVhY3QgcnVudGltZSwgYW5kIFN3aXRjaGJvYXJkIE1lc3NhZ2VDaGFubmVsXG5hcmUgcHJlc2VydmVkIGFjcm9zcyBkYXNoYm9hcmQgc3dpdGNoZXMuXG5cbiMjIFdoYXQgaXQgcGF0Y2hlc1xuXG4tIFxcYHN1cGVyc2V0LWZyb250ZW5kL3NyYy9lbWJlZGRlZC9pbmRleC50c3hcXGAg4oCUIGFkZHMgXFxgc3dpdGNoRGFzaGJvYXJkXFxgIHRvIHRoZVxuICBTd2l0Y2hib2FyZCBjaGFubmVsOyByZXBsYWNlcyBvbmx5IFxcYERhc2hib2FyZFBhZ2VcXGAuXG4tIFxcYHN1cGVyc2V0LWVtYmVkZGVkLXNkay9zcmMvaW5kZXgudHNcXGAg4oCUIGFkZHNcbiAgXFxgZW1iZWRkZWREYXNoYm9hcmQuc3dpdGNoRGFzaGJvYXJkKGRhc2hib2FyZElkKVxcYDsgcmVxdWVzdHMgYSBndWVzdCB0b2tlbiBmb3JcbiAgdGhlIHNlbGVjdGVkIGRhc2hib2FyZDsgcmVmcmVzaGVzIGZ1dHVyZSBndWVzdCB0b2tlbnMgZm9yIHRoZSBhY3RpdmUgZGFzaGJvYXJkLlxuXG4jIyBCdWlsZFxuXG5cXGBcXGBcXGBiYXNoXG4jIEFwcGx5IHBhdGNoICsgdmVyaWZ5ICsgYnVpbGQgU0RLICsgYnVpbGQgZnJvbnRlbmRcbmJ1aWxkL3BhdGNoLWFuZC1idWlsZC5zaCAvcGF0aC90by9zdXBlcnNldFxuXG4jIE9yIGJ1aWxkIGEgRG9ja2VyIGltYWdlXG5idWlsZC9idWlsZC1kb2NrZXItaW1hZ2Uuc2ggL3BhdGgvdG8vc3VwZXJzZXQgcmVnaXN0cnkuZXhhbXBsZS5jb20vc3VwZXJzZXQtc3dpdGNoYWJsZTo2LjEuMFxuXFxgXFxgXFxgXG5cblRoZSBwYXRjaGVkIFNESyBtdXN0IGJlIHBhY2tlZCBhbmQgaW5zdGFsbGVkIGludG8gdGhlIEFuZ3VsYXIgYXBwbGljYXRpb246XG5cblxcYFxcYFxcYGJhc2hcbmNkIC9wYXRoL3RvL3N1cGVyc2V0L3N1cGVyc2V0LWVtYmVkZGVkLXNka1xubnBtIGNpICYmIG5wbSBydW4gYnVpbGQgJiYgbnBtIHBhY2tcbmNkIC9wYXRoL3RvL2FuZ3VsYXItYXBwXG5ucG0gaW5zdGFsbCAvcGF0aC90by9zdXBlcnNldC9zdXBlcnNldC1lbWJlZGRlZC1zZGsvc3VwZXJzZXQtdWktZW1iZWRkZWQtc2RrLSoudGd6XG5cXGBcXGBcXGBcblxuVmVyc2lvbjogJHtTVVBFUlNFVF9QTFVHSU5fVkVSU0lPTn1cbmA7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZnVsbCBzZXQgb2YgcGF0Y2ggYW5kIGJ1aWxkIHNjcmlwdCBmaWxlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1cGVyc2V0UGF0Y2hGaWxlcygpOiBTdXBlcnNldFBhdGNoRmlsZVtdIHtcbiAgcmV0dXJuIFtcbiAgICB7IHBhdGg6IFwicGF0Y2hlcy9hcHBseV9zdXBlcnNldF82XzFfcGF0Y2gucHlcIiwgY29udGVudDogQVBQTFlfUEFUQ0hfUFksIGV4ZWN1dGFibGU6IHRydWUgfSxcbiAgICB7IHBhdGg6IFwicGF0Y2hlcy92ZXJpZnlfcGF0Y2guc2hcIiwgY29udGVudDogVkVSSUZZX1BBVENIX1NILCBleGVjdXRhYmxlOiB0cnVlIH0sXG4gICAgeyBwYXRoOiBcImJ1aWxkL2J1aWxkLXNkay5zaFwiLCBjb250ZW50OiBCVUlMRF9TREtfU0gsIGV4ZWN1dGFibGU6IHRydWUgfSxcbiAgICB7IHBhdGg6IFwiYnVpbGQvYnVpbGQtc3VwZXJzZXQtZnJvbnRlbmQuc2hcIiwgY29udGVudDogQlVJTERfRlJPTlRFTkRfU0gsIGV4ZWN1dGFibGU6IHRydWUgfSxcbiAgICB7IHBhdGg6IFwiYnVpbGQvcGF0Y2gtYW5kLWJ1aWxkLnNoXCIsIGNvbnRlbnQ6IFBBVENIX0FORF9CVUlMRF9TSCwgZXhlY3V0YWJsZTogdHJ1ZSB9LFxuICAgIHsgcGF0aDogXCJidWlsZC9idWlsZC1kb2NrZXItaW1hZ2Uuc2hcIiwgY29udGVudDogQlVJTERfRE9DS0VSX1NILCBleGVjdXRhYmxlOiB0cnVlIH0sXG4gICAgeyBwYXRoOiBcIlJFQURNRS5tZFwiLCBjb250ZW50OiBSRUFETUUgfSxcbiAgXTtcbn1cbiJdfQ==
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @module integrations/graph/errors/GraphBreakSignal
3
+ * @summary Control-flow signal used by `core.flow.break` to exit a loop early.
4
+ * @description Thrown by the Break node executor and caught by the enclosing
5
+ * loop executor (`core.loop.foreach`, `core.loop.while`, `core.loop.until`).
6
+ * Unlike a real error, a break signal is a cooperative control-flow token: it
7
+ * is NOT propagated as a workflow failure. When caught, the loop terminates
8
+ * early and returns the results collected so far (plus the optional `value`
9
+ * carried by the signal as the final partial result).
10
+ */
11
+ import { GraphExecutionError } from "./GraphExecutionError.d.cts";
12
+ /**
13
+ * Control-flow signal thrown by `core.flow.break` nodes.
14
+ *
15
+ * Extends {@link GraphExecutionError} so it rides on the existing error
16
+ * pipeline, but carries the `graphCode` `"GRAPH_BREAK_SIGNAL"` and the flag
17
+ * `isBreakSignal = true` so loop executors can distinguish it from a genuine
18
+ * execution failure via `instanceof` or the flag.
19
+ */
20
+ export declare class GraphBreakSignal extends GraphExecutionError {
21
+ /** Distinguishes a break signal from a genuine error without `instanceof`. */
22
+ readonly isBreakSignal = true;
23
+ /**
24
+ * @param value - Optional value forwarded by the Break node. The enclosing
25
+ * loop appends this to the collected results as the last partial result.
26
+ */
27
+ constructor(value?: unknown);
28
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @module integrations/graph/errors/GraphBreakSignal
3
+ * @summary Control-flow signal used by `core.flow.break` to exit a loop early.
4
+ * @description Thrown by the Break node executor and caught by the enclosing
5
+ * loop executor (`core.loop.foreach`, `core.loop.while`, `core.loop.until`).
6
+ * Unlike a real error, a break signal is a cooperative control-flow token: it
7
+ * is NOT propagated as a workflow failure. When caught, the loop terminates
8
+ * early and returns the results collected so far (plus the optional `value`
9
+ * carried by the signal as the final partial result).
10
+ */
11
+ import { GraphExecutionError } from "./GraphExecutionError.d.mts";
12
+ /**
13
+ * Control-flow signal thrown by `core.flow.break` nodes.
14
+ *
15
+ * Extends {@link GraphExecutionError} so it rides on the existing error
16
+ * pipeline, but carries the `graphCode` `"GRAPH_BREAK_SIGNAL"` and the flag
17
+ * `isBreakSignal = true` so loop executors can distinguish it from a genuine
18
+ * execution failure via `instanceof` or the flag.
19
+ */
20
+ export declare class GraphBreakSignal extends GraphExecutionError {
21
+ /** Distinguishes a break signal from a genuine error without `instanceof`. */
22
+ readonly isBreakSignal = true;
23
+ /**
24
+ * @param value - Optional value forwarded by the Break node. The enclosing
25
+ * loop appends this to the collected results as the last partial result.
26
+ */
27
+ constructor(value?: unknown);
28
+ }
@@ -11,3 +11,4 @@ export * from "./GraphPinningError.d.cts";
11
11
  export * from "./GraphPortError.d.cts";
12
12
  export * from "./GraphStoreError.d.cts";
13
13
  export * from "./GraphTopologyError.d.cts";
14
+ export * from "./GraphBreakSignal.d.cts";
@@ -11,3 +11,4 @@ export * from "./GraphPinningError.d.mts";
11
11
  export * from "./GraphPortError.d.mts";
12
12
  export * from "./GraphStoreError.d.mts";
13
13
  export * from "./GraphTopologyError.d.mts";
14
+ export * from "./GraphBreakSignal.d.mts";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @module integrations/graph/execution/BreakGraphNodeExecutor
3
+ * @summary Executor for the Break flow-control node.
4
+ * @description Throws a {@link GraphBreakSignal} that the enclosing loop
5
+ * executor catches to terminate the loop early. The optional `value` input is
6
+ * carried on the signal so the loop can append it as the last partial result.
7
+ */
8
+ import type { GraphNodeExecutor } from "./GraphNodeExecutor.d.cts";
9
+ import type { GraphExecutionContext } from "./GraphExecutionContext.d.cts";
10
+ import type { GraphExecutionValues } from "../types.d.cts";
11
+ /**
12
+ * Executor for `core.flow.break` nodes.
13
+ *
14
+ * Reads the optional `value` input port and throws a {@link GraphBreakSignal}
15
+ * carrying it. The enclosing loop executor (`core.loop.foreach`,
16
+ * `core.loop.while`, `core.loop.until`) catches the signal, stops iterating,
17
+ * and returns the results collected so far (plus the carried value as the
18
+ * final partial result).
19
+ */
20
+ export declare class BreakGraphNodeExecutor implements GraphNodeExecutor {
21
+ execute(input: GraphExecutionValues, _context: GraphExecutionContext): Promise<GraphExecutionValues>;
22
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @module integrations/graph/execution/BreakGraphNodeExecutor
3
+ * @summary Executor for the Break flow-control node.
4
+ * @description Throws a {@link GraphBreakSignal} that the enclosing loop
5
+ * executor catches to terminate the loop early. The optional `value` input is
6
+ * carried on the signal so the loop can append it as the last partial result.
7
+ */
8
+ import type { GraphNodeExecutor } from "./GraphNodeExecutor.d.mts";
9
+ import type { GraphExecutionContext } from "./GraphExecutionContext.d.mts";
10
+ import type { GraphExecutionValues } from "../types.d.mts";
11
+ /**
12
+ * Executor for `core.flow.break` nodes.
13
+ *
14
+ * Reads the optional `value` input port and throws a {@link GraphBreakSignal}
15
+ * carrying it. The enclosing loop executor (`core.loop.foreach`,
16
+ * `core.loop.while`, `core.loop.until`) catches the signal, stops iterating,
17
+ * and returns the results collected so far (plus the carried value as the
18
+ * final partial result).
19
+ */
20
+ export declare class BreakGraphNodeExecutor implements GraphNodeExecutor {
21
+ execute(input: GraphExecutionValues, _context: GraphExecutionContext): Promise<GraphExecutionValues>;
22
+ }
@@ -12,4 +12,5 @@ export * from "./CodeSandboxEvaluator.d.cts";
12
12
  export * from "./SwitchGraphNodeExecutor.d.cts";
13
13
  export * from "./CodeGraphNodeExecutor.d.cts";
14
14
  export * from "./LogGraphNodeExecutor.d.cts";
15
+ export * from "./BreakGraphNodeExecutor.d.cts";
15
16
  export * from "./IsolatedVmCodeSandboxEvaluator.d.cts";
@@ -12,4 +12,5 @@ export * from "./CodeSandboxEvaluator.d.mts";
12
12
  export * from "./SwitchGraphNodeExecutor.d.mts";
13
13
  export * from "./CodeGraphNodeExecutor.d.mts";
14
14
  export * from "./LogGraphNodeExecutor.d.mts";
15
+ export * from "./BreakGraphNodeExecutor.d.mts";
15
16
  export * from "./IsolatedVmCodeSandboxEvaluator.d.mts";
@@ -20,6 +20,7 @@ export * from "./errors/GraphPinningError.d.cts";
20
20
  export * from "./errors/GraphPortError.d.cts";
21
21
  export * from "./errors/GraphStoreError.d.cts";
22
22
  export * from "./errors/GraphTopologyError.d.cts";
23
+ export * from "./errors/GraphBreakSignal.d.cts";
23
24
  export * from "./events/GraphExecutionEvent.d.cts";
24
25
  export * from "./events/GraphExecutionObserver.d.cts";
25
26
  export * from "./events/GraphExecutionEventEmitter.d.cts";
@@ -33,6 +34,7 @@ export * from "./execution/CodeSandboxEvaluator.d.cts";
33
34
  export * from "./execution/SwitchGraphNodeExecutor.d.cts";
34
35
  export * from "./execution/CodeGraphNodeExecutor.d.cts";
35
36
  export * from "./execution/LogGraphNodeExecutor.d.cts";
37
+ export * from "./execution/BreakGraphNodeExecutor.d.cts";
36
38
  export * from "./execution/IsolatedVmCodeSandboxEvaluator.d.cts";
37
39
  export * from "./registry/GraphNodeExecutorRegistry.d.cts";
38
40
  export * from "./registry/GraphNodeExecutorResolver.d.cts";
@@ -20,6 +20,7 @@ export * from "./errors/GraphPinningError.d.mts";
20
20
  export * from "./errors/GraphPortError.d.mts";
21
21
  export * from "./errors/GraphStoreError.d.mts";
22
22
  export * from "./errors/GraphTopologyError.d.mts";
23
+ export * from "./errors/GraphBreakSignal.d.mts";
23
24
  export * from "./events/GraphExecutionEvent.d.mts";
24
25
  export * from "./events/GraphExecutionObserver.d.mts";
25
26
  export * from "./events/GraphExecutionEventEmitter.d.mts";
@@ -33,6 +34,7 @@ export * from "./execution/CodeSandboxEvaluator.d.mts";
33
34
  export * from "./execution/SwitchGraphNodeExecutor.d.mts";
34
35
  export * from "./execution/CodeGraphNodeExecutor.d.mts";
35
36
  export * from "./execution/LogGraphNodeExecutor.d.mts";
37
+ export * from "./execution/BreakGraphNodeExecutor.d.mts";
36
38
  export * from "./execution/IsolatedVmCodeSandboxEvaluator.d.mts";
37
39
  export * from "./registry/GraphNodeExecutorRegistry.d.mts";
38
40
  export * from "./registry/GraphNodeExecutorResolver.d.mts";
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * @module integrations/graph/loops/ForeachGraphNodeExecutor
3
3
  * @summary Foreach loop node executor.
4
- * @description Executes a body workflow once per item in the input array, collecting results in order.
4
+ * @description Executes a body workflow once per item (or per slice of items)
5
+ * in the input array, collecting results in order. Supports a configurable
6
+ * `slice` size and cooperative early termination via `core.flow.break` nodes
7
+ * (which throw a {@link GraphBreakSignal}).
5
8
  */
6
9
  import type { GraphNodeExecutor } from "../execution/GraphNodeExecutor.d.cts";
7
10
  import type { GraphExecutionContext } from "../execution/GraphExecutionContext.d.cts";
@@ -12,12 +15,17 @@ import type { GraphExecutionValues } from "../types.d.cts";
12
15
  *
13
16
  * Expects input:
14
17
  * - `items`: array of values to iterate over
18
+ * - `slice?`: optional slice size (overrides `metadata.loop.slice`); default `1`
15
19
  * - `state?`: optional initial state
16
20
  *
17
21
  * Produces output:
18
- * - `results`: array of body outputs (in item order)
19
- * - `state?`: final state
22
+ * - `results`: array of body outputs (in item order). When `slice > 1`, one
23
+ * entry per slice (the body receives a slice array on the item port).
24
+ * - `completed`: alias for `results` — the flow after the loop ends (the
25
+ * collected results array).
20
26
  * - `iterations`: number of iterations executed
27
+ * - `broken`: `true` when the loop was terminated early by a Break node
28
+ * - `state?`: final state
21
29
  */
22
30
  export declare class ForeachGraphNodeExecutor implements GraphNodeExecutor {
23
31
  private readonly engine;
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * @module integrations/graph/loops/ForeachGraphNodeExecutor
3
3
  * @summary Foreach loop node executor.
4
- * @description Executes a body workflow once per item in the input array, collecting results in order.
4
+ * @description Executes a body workflow once per item (or per slice of items)
5
+ * in the input array, collecting results in order. Supports a configurable
6
+ * `slice` size and cooperative early termination via `core.flow.break` nodes
7
+ * (which throw a {@link GraphBreakSignal}).
5
8
  */
6
9
  import type { GraphNodeExecutor } from "../execution/GraphNodeExecutor.d.mts";
7
10
  import type { GraphExecutionContext } from "../execution/GraphExecutionContext.d.mts";
@@ -12,12 +15,17 @@ import type { GraphExecutionValues } from "../types.d.mts";
12
15
  *
13
16
  * Expects input:
14
17
  * - `items`: array of values to iterate over
18
+ * - `slice?`: optional slice size (overrides `metadata.loop.slice`); default `1`
15
19
  * - `state?`: optional initial state
16
20
  *
17
21
  * Produces output:
18
- * - `results`: array of body outputs (in item order)
19
- * - `state?`: final state
22
+ * - `results`: array of body outputs (in item order). When `slice > 1`, one
23
+ * entry per slice (the body receives a slice array on the item port).
24
+ * - `completed`: alias for `results` — the flow after the loop ends (the
25
+ * collected results array).
20
26
  * - `iterations`: number of iterations executed
27
+ * - `broken`: `true` when the loop was terminated early by a Break node
28
+ * - `state?`: final state
21
29
  */
22
30
  export declare class ForeachGraphNodeExecutor implements GraphNodeExecutor {
23
31
  private readonly engine;
@@ -107,6 +107,12 @@ export interface GraphLoopMetadata {
107
107
  itemPort?: string;
108
108
  resultPort?: string;
109
109
  statePort?: string;
110
+ /**
111
+ * How many items are taken from the input list per iteration (foreach only).
112
+ * Default `1`. When greater than `1`, the body receives a slice (array) on
113
+ * the item port and the collected result is one entry per slice.
114
+ */
115
+ slice?: number;
110
116
  }
111
117
  /**
112
118
  * Definition of a condition evaluated by the loop condition evaluator.
@@ -107,6 +107,12 @@ export interface GraphLoopMetadata {
107
107
  itemPort?: string;
108
108
  resultPort?: string;
109
109
  statePort?: string;
110
+ /**
111
+ * How many items are taken from the input list per iteration (foreach only).
112
+ * Default `1`. When greater than `1`, the body receives a slice (array) on
113
+ * the item port and the collected result is one entry per slice.
114
+ */
115
+ slice?: number;
110
116
  }
111
117
  /**
112
118
  * Definition of a condition evaluated by the loop condition evaluator.
@@ -133,7 +133,18 @@ export declare class LogFlowNode extends Model {
133
133
  value: unknown;
134
134
  logged: unknown;
135
135
  }
136
+ /**
137
+ * Break — breaks out of the enclosing loop (foreach/while/until). When
138
+ * executed inside a loop body, the loop terminates early and the loop's
139
+ * `completed`/`state` output carries the results collected so far. The
140
+ * Break node executor throws a {@link GraphBreakSignal} that the enclosing
141
+ * loop executor catches.
142
+ */
143
+ export declare class BreakFlowNode extends Model {
144
+ value: unknown;
145
+ broken: unknown;
146
+ }
136
147
  /**
137
148
  * All built-in flow-control node constructors.
138
149
  */
139
- export declare const GRAPH_FLOW_CONTROL_NODES: readonly [typeof IfFlowNode, typeof SwitchFlowNode, typeof ParallelFlowNode, typeof MergeFlowNode, typeof MapFlowNode, typeof DelayFlowNode, typeof ErrorBoundaryFlowNode, typeof HumanApprovalFlowNode, typeof ReturnFlowNode, typeof CodeFlowNode, typeof LogFlowNode];
150
+ export declare const GRAPH_FLOW_CONTROL_NODES: readonly [typeof IfFlowNode, typeof SwitchFlowNode, typeof ParallelFlowNode, typeof MergeFlowNode, typeof MapFlowNode, typeof DelayFlowNode, typeof ErrorBoundaryFlowNode, typeof HumanApprovalFlowNode, typeof ReturnFlowNode, typeof CodeFlowNode, typeof LogFlowNode, typeof BreakFlowNode];
@@ -133,7 +133,18 @@ export declare class LogFlowNode extends Model {
133
133
  value: unknown;
134
134
  logged: unknown;
135
135
  }
136
+ /**
137
+ * Break — breaks out of the enclosing loop (foreach/while/until). When
138
+ * executed inside a loop body, the loop terminates early and the loop's
139
+ * `completed`/`state` output carries the results collected so far. The
140
+ * Break node executor throws a {@link GraphBreakSignal} that the enclosing
141
+ * loop executor catches.
142
+ */
143
+ export declare class BreakFlowNode extends Model {
144
+ value: unknown;
145
+ broken: unknown;
146
+ }
136
147
  /**
137
148
  * All built-in flow-control node constructors.
138
149
  */
139
- export declare const GRAPH_FLOW_CONTROL_NODES: readonly [typeof IfFlowNode, typeof SwitchFlowNode, typeof ParallelFlowNode, typeof MergeFlowNode, typeof MapFlowNode, typeof DelayFlowNode, typeof ErrorBoundaryFlowNode, typeof HumanApprovalFlowNode, typeof ReturnFlowNode, typeof CodeFlowNode, typeof LogFlowNode];
150
+ export declare const GRAPH_FLOW_CONTROL_NODES: readonly [typeof IfFlowNode, typeof SwitchFlowNode, typeof ParallelFlowNode, typeof MergeFlowNode, typeof MapFlowNode, typeof DelayFlowNode, typeof ErrorBoundaryFlowNode, typeof HumanApprovalFlowNode, typeof ReturnFlowNode, typeof CodeFlowNode, typeof LogFlowNode, typeof BreakFlowNode];
@@ -7,6 +7,6 @@ export * from "./utils.d.cts";
7
7
  export * from "./namespaces/index.d.cts";
8
8
  export * from "./feature-flags/index.d.cts";
9
9
  export declare const VERSION: string;
10
- export declare const COMMIT = "7ccddad";
11
- export declare const FULL_VERSION = "0.4.1-1-7ccddad";
10
+ export declare const COMMIT = "e21cc70";
11
+ export declare const FULL_VERSION = "0.5.1-e21cc70";
12
12
  export declare const PACKAGE_NAME: string;
@@ -7,6 +7,6 @@ export * from "./utils.d.mts";
7
7
  export * from "./namespaces/index.d.mts";
8
8
  export * from "./feature-flags/index.d.mts";
9
9
  export declare const VERSION: string;
10
- export declare const COMMIT = "7ccddad";
11
- export declare const FULL_VERSION = "0.4.1-1-7ccddad";
10
+ export declare const COMMIT = "e21cc70";
11
+ export declare const FULL_VERSION = "0.5.1-e21cc70";
12
12
  export declare const PACKAGE_NAME: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decaf-ts/integrations",
3
- "version": "0.4.1-2",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.mts",
@@ -313,6 +313,9 @@
313
313
  "reset": "rm -rf * && git checkout . && git pull && npm run do-install",
314
314
  "build": "build-scripts --dev",
315
315
  "build:prod": "build-scripts --prod",
316
+ "boot:plugins:kibana": "npm run build && node ./bin/boot-plugin.mjs kibana 8.14.3",
317
+ "boot:plugins:superset": "npm run build && node ./bin/boot-plugin.mjs superset 6.1.0",
318
+ "boot:plugins": "npm run boot:plugins:kibana && npm run boot:plugins:superset",
316
319
  "test": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest --watchman=false --runInBand --coverage --detectOpenHandles",
317
320
  "test:unit": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watchman=false --testPathPatterns=\"/tests/unit\" --passWithNoTests --detectOpenHandles",
318
321
  "test:integration": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watchman=false --testPathPatterns=\"/tests/(integration)\" --passWithNoTests --detectOpenHandles",
@@ -365,7 +368,7 @@
365
368
  "@decaf-ts/cli": "latest",
366
369
  "@decaf-ts/for-http": "latest",
367
370
  "@decaf-ts/for-nano": "latest",
368
- "@decaf-ts/for-nest": "0.12.2-0",
371
+ "@decaf-ts/for-nest": "latest",
369
372
  "@decaf-ts/utils": "latest",
370
373
  "@nestjs/common": "^11.0.0",
371
374
  "@nestjs/core": "^11.0.0",
@@ -382,7 +385,7 @@
382
385
  "peerDependencies": {
383
386
  "@decaf-ts/as-zod": "latest",
384
387
  "@decaf-ts/for-http": "latest",
385
- "@decaf-ts/for-nest": "0.12.2-0",
388
+ "@decaf-ts/for-nest": "latest",
386
389
  "jose": ">=5.0.0"
387
390
  },
388
391
  "peerDependenciesMeta": {
@@ -8,10 +8,10 @@
8
8
  # - org_dashboard_embed_superset/ (generated by install())
9
9
  # - superset_config.py (curated runtime config)
10
10
  #
11
- FROM node:18-slim AS builder
11
+ FROM node:22-slim AS builder
12
12
 
13
13
  RUN apt-get update && apt-get install -y --no-install-recommends \
14
- git python3 python3-pip curl bash \
14
+ git python3 python3-pip curl bash zstd \
15
15
  && rm -rf /var/lib/apt/lists/*
16
16
 
17
17
  WORKDIR /build
@@ -38,10 +38,10 @@ RUN cd /build/superset/superset-embedded-sdk && npm ci && npm run build
38
38
  RUN cd /build/superset/superset-frontend && npm ci && npm run build
39
39
 
40
40
  # ─── Runtime stage ──────────────────────────────────────────────────────
41
- FROM node:18-slim AS runtime
41
+ FROM node:22-slim AS runtime
42
42
 
43
43
  RUN apt-get update && apt-get install -y --no-install-recommends \
44
- python3 python3-pip python3-venv curl bash \
44
+ python3 python3-pip python3-venv curl bash zstd \
45
45
  && rm -rf /var/lib/apt/lists/*
46
46
 
47
47
  RUN python3 -m venv /app/venv
@@ -55,7 +55,8 @@ RUN pip install --no-cache-dir \
55
55
  psycopg2-binary \
56
56
  celery \
57
57
  redis \
58
- gunicorn
58
+ gunicorn \
59
+ rich
59
60
 
60
61
  # Copy built frontend assets from builder
61
62
  COPY --from=builder /build/superset/superset-frontend/ /app/superset-frontend/
@@ -71,9 +72,8 @@ ENV FLASK_APP=superset
71
72
 
72
73
  EXPOSE 8088
73
74
 
74
- # Initialize Superset
75
- RUN superset db upgrade && \
76
- superset fab create-admin --username admin --firstname Admin --lastname User --email admin@example.com --password admin || true && \
77
- superset init
75
+ COPY entrypoint.sh /app/entrypoint.sh
76
+ RUN chmod +x /app/entrypoint.sh
78
77
 
78
+ ENTRYPOINT ["/app/entrypoint.sh"]
79
79
  CMD ["gunicorn", "-b", "0.0.0.0:8088", "-w", "4", "--timeout", "120", "superset.app:create_app()"]