@pipeline-builder/pipeline-data 0.0.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 (48) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +61 -0
  3. package/drizzle.config.ts +17 -0
  4. package/lib/api/access-control-builder.d.ts +148 -0
  5. package/lib/api/access-control-builder.js +199 -0
  6. package/lib/api/crud-service.d.ts +343 -0
  7. package/lib/api/crud-service.js +849 -0
  8. package/lib/api/query-builders.d.ts +82 -0
  9. package/lib/api/query-builders.js +460 -0
  10. package/lib/api/reporting-service.d.ts +685 -0
  11. package/lib/api/reporting-service.js +1564 -0
  12. package/lib/api/soft-delete-sweep.d.ts +65 -0
  13. package/lib/api/soft-delete-sweep.js +124 -0
  14. package/lib/api/viewer-context.d.ts +29 -0
  15. package/lib/api/viewer-context.js +63 -0
  16. package/lib/core/query-filters.d.ts +263 -0
  17. package/lib/core/query-filters.js +4 -0
  18. package/lib/database/drizzle-schema.d.ts +7357 -0
  19. package/lib/database/drizzle-schema.js +66 -0
  20. package/lib/database/index.d.ts +5 -0
  21. package/lib/database/index.js +8 -0
  22. package/lib/database/migrator.d.ts +20 -0
  23. package/lib/database/migrator.js +80 -0
  24. package/lib/database/postgres-connection.d.ts +201 -0
  25. package/lib/database/postgres-connection.js +413 -0
  26. package/lib/database/retry-strategy.d.ts +68 -0
  27. package/lib/database/retry-strategy.js +122 -0
  28. package/lib/database/schema/alert.d.ts +588 -0
  29. package/lib/database/schema/alert.js +130 -0
  30. package/lib/database/schema/compliance.d.ts +3319 -0
  31. package/lib/database/schema/compliance.js +377 -0
  32. package/lib/database/schema/dashboard.d.ts +474 -0
  33. package/lib/database/schema/dashboard.js +129 -0
  34. package/lib/database/schema/message-attachment.d.ts +183 -0
  35. package/lib/database/schema/message-attachment.js +40 -0
  36. package/lib/database/schema/message.d.ts +411 -0
  37. package/lib/database/schema/message.js +114 -0
  38. package/lib/database/schema/pipeline-template.d.ts +466 -0
  39. package/lib/database/schema/pipeline-template.js +80 -0
  40. package/lib/database/schema/pipeline.d.ts +1613 -0
  41. package/lib/database/schema/pipeline.js +332 -0
  42. package/lib/database/schema/plugin.d.ts +749 -0
  43. package/lib/database/schema/plugin.js +166 -0
  44. package/lib/database/tenancy.d.ts +103 -0
  45. package/lib/database/tenancy.js +167 -0
  46. package/lib/index.d.ts +32 -0
  47. package/lib/index.js +38 -0
  48. package/package.json +161 -0
@@ -0,0 +1,130 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { sql } from 'drizzle-orm';
4
+ import { boolean, varchar, pgTable, text, timestamp, uuid, index, uniqueIndex } from 'drizzle-orm/pg-core';
5
+ /**
6
+ * Per-org alert notification destination. Multi-tenant alerting routes
7
+ * Alertmanager webhooks to the platform; the platform looks the firing
8
+ * alert's `org_id` label up here and forwards to each enabled destination.
9
+ *
10
+ * Channels * - `slack` `target` is the incoming-webhook URL
11
+ * - `webhook` `target` is any HTTPS URL; the relay posts the
12
+ * Alertmanager v2 webhook payload verbatim
13
+ * - `in-app` `target` ignored; surfaces as an in-app message via
14
+ * the existing `messages` table
15
+ *
16
+ * Secrets * - For `slack`/`webhook` channels, the URL itself is the secret. We don't
17
+ * log it on `dashboard.update` or surface the full URL on GET endpoints
18
+ * after write; just a masked preview (last 12 chars). Stored in clear
19
+ * text same posture as `compliance_notification_preferences.webhook_url`
20
+ * and consistent with the rest of the app's secret handling for org-level
21
+ * integrations. If we add a KMS-encryption tier for any secret column,
22
+ * this is one of the first to migrate.
23
+ *
24
+ * @table org_alert_destinations
25
+ */
26
+ export const orgAlertDestination = pgTable('org_alert_destinations', {
27
+ id: uuid('id').primaryKey().defaultRandom(),
28
+ orgId: varchar('org_id', { length: 255 }).notNull(),
29
+ createdBy: text('created_by').notNull(),
30
+ createdAt: timestamp('created_at', { withTimezone: true })
31
+ .defaultNow()
32
+ .notNull(),
33
+ updatedBy: text('updated_by').notNull(),
34
+ updatedAt: timestamp('updated_at', { withTimezone: true })
35
+ .defaultNow()
36
+ .notNull(),
37
+ /** 'slack' | 'webhook' | 'in-app' | 'email' kept stringly so future channels
38
+ * (PagerDuty, …) can be added without a schema migration. */
39
+ channel: varchar('channel', { length: 20 })
40
+ .$type()
41
+ .notNull(),
42
+ /** Channel-specific target. Slack/webhook: URL. Email: address. In-app: ignored. */
43
+ target: text('target').default('').notNull(),
44
+ /** Friendly label shown in the settings UI. */
45
+ label: varchar('label', { length: 100 }).notNull(),
46
+ /** Lowest severity that triggers this destination ('warning' = warning+critical,
47
+ * 'critical' = critical only). Mirrors Alertmanager severity ordering. */
48
+ minSeverity: varchar('min_severity', { length: 10 })
49
+ .$type()
50
+ .default('warning')
51
+ .notNull(),
52
+ enabled: boolean('enabled').default(true).notNull(),
53
+ /** Soft delete so we keep audit history of who-deleted-what. */
54
+ deletedAt: timestamp('deleted_at', { withTimezone: true }),
55
+ deletedBy: text('deleted_by'),
56
+ // Soft-delete purge deadline: the retention sweep hard-deletes tombstoned
57
+ // rows once `purge_after` has passed (set on delete alongside deleted_at).
58
+ purgeAfter: timestamp('purge_after', { withTimezone: true }),
59
+ }, (table) => ({
60
+ // Partial index over just the tombstones — drives the retention purge sweep.
61
+ purgeIdx: index('org_alert_destination_purge_idx').on(table.purgeAfter).where(sql `deleted_at IS NOT NULL`),
62
+ // Per-org listing the only access path.
63
+ orgIdx: index('org_alert_destination_org_idx')
64
+ .on(table.orgId, table.enabled),
65
+ }));
66
+ /**
67
+ * Per-org alert rules authored by operators.
68
+ *
69
+ * Each row materializes into a `groups[].rules[]` entry in a Prometheus
70
+ * `rule_files` YAML. The materializer endpoint
71
+ * `GET /api/observability/alert-rules/materialized.yml` renders all enabled
72
+ * rules across all orgs (deleted=null) into one document; Prometheus polls
73
+ * or a sidecar copies it into the rules dir.
74
+ *
75
+ * Tenancy + safety * - `expr` is user-authored PromQL. The CRUD route enforces that the
76
+ * expression substring-contains `org_id="<orgId>"` so an operator can't
77
+ * write rules that fire on other orgs' metrics. This is a coarse gate
78
+ * (a malformed expression can still be syntactically wrong) but it
79
+ * closes the cross-tenant data leak. Real PromQL parsing + automatic
80
+ * org_id injection is a follow-on.
81
+ * - The materialized rule carries `labels.org_id = <orgId>` so the
82
+ * alertmanager-relay routes firing alerts to the right org's
83
+ * destinations (matches the alert-relay model).
84
+ *
85
+ * @table org_alert_rules
86
+ */
87
+ export const orgAlertRule = pgTable('org_alert_rules', {
88
+ id: uuid('id').primaryKey().defaultRandom(),
89
+ orgId: varchar('org_id', { length: 255 }).notNull(),
90
+ createdBy: text('created_by').notNull(),
91
+ createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
92
+ updatedBy: text('updated_by').notNull(),
93
+ updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
94
+ /** Operator-supplied rule name. Sanitized into a valid Prom alert name at
95
+ * materialization time (becomes `OrgRule_<orgId>_<slug>` to avoid name
96
+ * collisions across orgs). */
97
+ name: varchar('name', { length: 100 }).notNull(),
98
+ /** PromQL expression. MUST substring-contain `org_id="<orgId>"`. */
99
+ expr: text('expr').notNull(),
100
+ /** `for: 5m` style duration. Validated against Prom's duration regex. */
101
+ forDuration: varchar('for_duration', { length: 20 }).default('5m').notNull(),
102
+ /** 'warning' | 'critical' matches the platform-wide severity ladder. */
103
+ severity: varchar('severity', { length: 20 })
104
+ .$type()
105
+ .default('warning')
106
+ .notNull(),
107
+ /** Alertmanager `summary` annotation. Supports `{{ $value }}`. */
108
+ summary: text('summary').notNull(),
109
+ /** Alertmanager `description` annotation. Optional; '' is fine. */
110
+ description: text('description').default('').notNull(),
111
+ /** Disabled rules don't materialize. Lets operators stage rules without firing. */
112
+ enabled: boolean('enabled').default(true).notNull(),
113
+ /** Soft delete so we keep audit of who-deleted-what. */
114
+ deletedAt: timestamp('deleted_at', { withTimezone: true }),
115
+ deletedBy: text('deleted_by'),
116
+ // Soft-delete purge deadline: the retention sweep hard-deletes tombstoned
117
+ // rows once `purge_after` has passed (set on delete alongside deleted_at).
118
+ purgeAfter: timestamp('purge_after', { withTimezone: true }),
119
+ }, (table) => ({
120
+ // Partial index over just the tombstones — drives the retention purge sweep.
121
+ purgeIdx: index('org_alert_rule_purge_idx').on(table.purgeAfter).where(sql `deleted_at IS NOT NULL`),
122
+ // Per-org listing + materializer's enabled-only scan.
123
+ orgEnabledIdx: index('org_alert_rule_org_enabled_idx')
124
+ .on(table.orgId, table.enabled),
125
+ // Unique within an org so operators can't accidentally clone a rule.
126
+ orgNameUq: uniqueIndex('org_alert_rule_org_name_uq')
127
+ .on(table.orgId, table.name)
128
+ .where(sql `deleted_at IS NULL`),
129
+ }));
130
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxlcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2Uvc2NoZW1hL2FsZXJ0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTNHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsRUFBRTtJQUNuRSxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDLGFBQWEsRUFBRTtJQUMzQyxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUVuRCxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN2QyxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztTQUN2RCxVQUFVLEVBQUU7U0FDWixPQUFPLEVBQUU7SUFDWixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLE9BQU8sRUFBRTtJQUN2QyxTQUFTLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztTQUN2RCxVQUFVLEVBQUU7U0FDWixPQUFPLEVBQUU7SUFFWjtpRUFDNkQ7SUFDN0QsT0FBTyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFF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QixLQUFLLENBQUMsR0FBRyxDQUFBLG9CQUFvQixDQUFDO0NBQ2xDLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IGJvb2xlYW4sIHZhcmNoYXIsIHBnVGFibGUsIHRleHQsIHRpbWVzdGFtcCwgdXVpZCwgaW5kZXgsIHVuaXF1ZUluZGV4IH0gZnJvbSAnZHJpenpsZS1vcm0vcGctY29yZSc7XG5cbi8qKlxuICogUGVyLW9yZyBhbGVydCBub3RpZmljYXRpb24gZGVzdGluYXRpb24uIE11bHRpLXRlbmFudCBhbGVydGluZyByb3V0ZXNcbiAqIEFsZXJ0bWFuYWdlciB3ZWJob29rcyB0byB0aGUgcGxhdGZvcm07IHRoZSBwbGF0Zm9ybSBsb29rcyB0aGUgZmlyaW5nXG4gKiBhbGVydCdzIGBvcmdfaWRgIGxhYmVsIHVwIGhlcmUgYW5kIGZvcndhcmRzIHRvIGVhY2ggZW5hYmxlZCBkZXN0aW5hdGlvbi5cbiAqXG4gKiBDaGFubmVscyAqIC0gYHNsYWNrYCAgYHRhcmdldGAgaXMgdGhlIGluY29taW5nLXdlYmhvb2sgVVJMXG4gKiAtIGB3ZWJob29rYCAgYHRhcmdldGAgaXMgYW55IEhUVFBTIFVSTDsgdGhlIHJlbGF5IHBvc3RzIHRoZVxuICogQWxlcnRtYW5hZ2VyIHYyIHdlYmhvb2sgcGF5bG9hZCB2ZXJiYXRpbVxuICogLSBgaW4tYXBwYCAgYHRhcmdldGAgaWdub3JlZDsgc3VyZmFjZXMgYXMgYW4gaW4tYXBwIG1lc3NhZ2UgdmlhXG4gKiB0aGUgZXhpc3RpbmcgYG1lc3NhZ2VzYCB0YWJsZVxuICpcbiAqIFNlY3JldHMgKiAtIEZvciBgc2xhY2tgL2B3ZWJob29rYCBjaGFubmVscywgdGhlIFVSTCBpdHNlbGYgaXMgdGhlIHNlY3JldC4gV2UgZG9uJ3RcbiAqIGxvZyBpdCBvbiBgZGFzaGJvYXJkLnVwZGF0ZWAgb3Igc3VyZmFjZSB0aGUgZnVsbCBVUkwgb24gR0VUIGVuZHBvaW50c1xuICogYWZ0ZXIgd3JpdGU7IGp1c3QgYSBtYXNrZWQgcHJldmlldyAobGFzdCAxMiBjaGFycykuIFN0b3JlZCBpbiBjbGVhclxuICogdGV4dCAgc2FtZSBwb3N0dXJlIGFzIGBjb21wbGlhbmNlX25vdGlmaWNhdGlvbl9wcmVmZXJlbmNlcy53ZWJob29rX3VybGBcbiAqIGFuZCBjb25zaXN0ZW50IHdpdGggdGhlIHJlc3Qgb2YgdGhlIGFwcCdzIHNlY3JldCBoYW5kbGluZyBmb3Igb3JnLWxldmVsXG4gKiBpbnRlZ3JhdGlvbnMuIElmIHdlIGFkZCBhIEtNUy1lbmNyeXB0aW9uIHRpZXIgZm9yIGFueSBzZWNyZXQgY29sdW1uLFxuICogdGhpcyBpcyBvbmUgb2YgdGhlIGZpcnN0IHRvIG1pZ3JhdGUuXG4gKlxuICogQHRhYmxlIG9yZ19hbGVydF9kZXN0aW5hdGlvbnNcbiAqL1xuZXhwb3J0IGNvbnN0IG9yZ0FsZXJ0RGVzdGluYXRpb24gPSBwZ1RhYmxlKCdvcmdfYWxlcnRfZGVzdGluYXRpb25zJywge1xuICBpZDogdXVpZCgnaWQnKS5wcmltYXJ5S2V5KCkuZGVmYXVsdFJhbmRvbSgpLFxuICBvcmdJZDogdmFyY2hhcignb3JnX2lkJywgeyBsZW5ndGg6IDI1NSB9KS5ub3ROdWxsKCksXG5cbiAgY3JlYXRlZEJ5OiB0ZXh0KCdjcmVhdGVkX2J5Jykubm90TnVsbCgpLFxuICBjcmVhdGVkQXQ6IHRpbWVzdGFtcCgnY3JlYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pXG4gICAgLmRlZmF1bHROb3coKVxuICAgIC5ub3ROdWxsKCksXG4gIHVwZGF0ZWRCeTogdGV4dCgndXBkYXRlZF9ieScpLm5vdE51bGwoKSxcbiAgdXBkYXRlZEF0OiB0aW1lc3RhbXAoJ3VwZGF0ZWRfYXQnLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KVxuICAgIC5kZWZhdWx0Tm93KClcbiAgICAubm90TnVsbCgpLFxuXG4gIC8qKiAnc2xhY2snIHwgJ3dlYmhvb2snIHwgJ2luLWFwcCcgfCAnZW1haWwnICBrZXB0IHN0cmluZ2x5IHNvIGZ1dHVyZSBjaGFubmVsc1xuICAgKiAoUGFnZXJEdXR5LCDigKYpIGNhbiBiZSBhZGRlZCB3aXRob3V0IGEgc2NoZW1hIG1pZ3JhdGlvbi4gKi9cbiAgY2hhbm5lbDogdmFyY2hhcignY2hhbm5lbCcsIHsgbGVuZ3RoOiAyMCB9KVxuICAgIC4kdHlwZTwnc2xhY2snIHwgJ3dlYmhvb2snIHwgJ2luLWFwcCcgfCAnZW1haWwnPigpXG4gICAgLm5vdE51bGwoKSxcbiAgLyoqIENoYW5uZWwtc3BlY2lmaWMgdGFyZ2V0LiBTbGFjay93ZWJob29rOiBVUkwuIEVtYWlsOiBhZGRyZXNzLiBJbi1hcHA6IGlnbm9yZWQuICovXG4gIHRhcmdldDogdGV4dCgndGFyZ2V0JykuZGVmYXVsdCgnJykubm90TnVsbCgpLFxuICAvKiogRnJpZW5kbHkgbGFiZWwgc2hvd24gaW4gdGhlIHNldHRpbmdzIFVJLiAqL1xuICBsYWJlbDogdmFyY2hhcignbGFiZWwnLCB7IGxlbmd0aDogMTAwIH0pLm5vdE51bGwoKSxcblxuICAvKiogTG93ZXN0IHNldmVyaXR5IHRoYXQgdHJpZ2dlcnMgdGhpcyBkZXN0aW5hdGlvbiAoJ3dhcm5pbmcnID0gd2FybmluZytjcml0aWNhbCxcbiAgICogJ2NyaXRpY2FsJyA9IGNyaXRpY2FsIG9ubHkpLiBNaXJyb3JzIEFsZXJ0bWFuYWdlciBzZXZlcml0eSBvcmRlcmluZy4gKi9cbiAgbWluU2V2ZXJpdHk6IHZhcmNoYXIoJ21pbl9zZXZlcml0eScsIHsgbGVuZ3RoOiAxMCB9KVxuICAgIC4kdHlwZTwnd2FybmluZycgfCAnY3JpdGljYWwnPigpXG4gICAgLmRlZmF1bHQoJ3dhcm5pbmcnKVxuICAgIC5ub3ROdWxsKCksXG4gIGVuYWJsZWQ6IGJvb2xlYW4oJ2VuYWJsZWQnKS5kZWZhdWx0KHRydWUpLm5vdE51bGwoKSxcblxuICAvKiogU29mdCBkZWxldGUgc28gd2Uga2VlcCBhdWRpdCBoaXN0b3J5IG9mIHdoby1kZWxldGVkLXdoYXQuICovXG4gIGRlbGV0ZWRBdDogdGltZXN0YW1wKCdkZWxldGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSksXG4gIGRlbGV0ZWRCeTogdGV4dCgnZGVsZXRlZF9ieScpLFxuICAvLyBTb2Z0LWRlbGV0ZSBwdXJnZSBkZWFkbGluZTogdGhlIHJldGVudGlvbiBzd2VlcCBoYXJkLWRlbGV0ZXMgdG9tYnN0b25lZFxuICAvLyByb3dzIG9uY2UgYHB1cmdlX2FmdGVyYCBoYXMgcGFzc2VkIChzZXQgb24gZGVsZXRlIGFsb25nc2lkZSBkZWxldGVkX2F0KS5cbiAgcHVyZ2VBZnRlcjogdGltZXN0YW1wKCdwdXJnZV9hZnRlcicsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxufSwgKHRhYmxlKSA9PiAoe1xuICAvLyBQYXJ0aWFsIGluZGV4IG92ZXIganVzdCB0aGUgdG9tYnN0b25lcyDigJQgZHJpdmVzIHRoZSByZXRlbnRpb24gcHVyZ2Ugc3dlZXAuXG4gIHB1cmdlSWR4OiBpbmRleCgnb3JnX2FsZXJ0X2Rlc3RpbmF0aW9uX3B1cmdlX2lkeCcpLm9uKHRhYmxlLnB1cmdlQWZ0ZXIpLndoZXJlKHNxbGBkZWxldGVkX2F0IElTIE5PVCBOVUxMYCksXG4gIC8vIFBlci1vcmcgbGlzdGluZyAgdGhlIG9ubHkgYWNjZXNzIHBhdGguXG4gIG9yZ0lkeDogaW5kZXgoJ29yZ19hbGVydF9kZXN0aW5hdGlvbl9vcmdfaWR4JylcbiAgICAub24odGFibGUub3JnSWQsIHRhYmxlLmVuYWJsZWQpLFxufSkpO1xuXG4vKipcbiAqICBQZXItb3JnIGFsZXJ0IHJ1bGVzIGF1dGhvcmVkIGJ5IG9wZXJhdG9ycy5cbiAqXG4gKiBFYWNoIHJvdyBtYXRlcmlhbGl6ZXMgaW50byBhIGBncm91cHNbXS5ydWxlc1tdYCBlbnRyeSBpbiBhIFByb21ldGhldXNcbiAqIGBydWxlX2ZpbGVzYCBZQU1MLiBUaGUgbWF0ZXJpYWxpemVyIGVuZHBvaW50XG4gKiBgR0VUIC9hcGkvb2JzZXJ2YWJpbGl0eS9hbGVydC1ydWxlcy9tYXRlcmlhbGl6ZWQueW1sYCByZW5kZXJzIGFsbCBlbmFibGVkXG4gKiBydWxlcyBhY3Jvc3MgYWxsIG9yZ3MgKGRlbGV0ZWQ9bnVsbCkgaW50byBvbmUgZG9jdW1lbnQ7IFByb21ldGhldXMgcG9sbHNcbiAqIG9yIGEgc2lkZWNhciBjb3BpZXMgaXQgaW50byB0aGUgcnVsZXMgZGlyLlxuICpcbiAqIFRlbmFuY3kgKyBzYWZldHkgKiAtIGBleHByYCBpcyB1c2VyLWF1dGhvcmVkIFByb21RTC4gVGhlIENSVUQgcm91dGUgZW5mb3JjZXMgdGhhdCB0aGVcbiAqIGV4cHJlc3Npb24gc3Vic3RyaW5nLWNvbnRhaW5zIGBvcmdfaWQ9XCI8b3JnSWQ+XCJgIHNvIGFuIG9wZXJhdG9yIGNhbid0XG4gKiB3cml0ZSBydWxlcyB0aGF0IGZpcmUgb24gb3RoZXIgb3JncycgbWV0cmljcy4gVGhpcyBpcyBhIGNvYXJzZSBnYXRlXG4gKiAoYSBtYWxmb3JtZWQgZXhwcmVzc2lvbiBjYW4gc3RpbGwgYmUgc3ludGFjdGljYWxseSB3cm9uZykgYnV0IGl0XG4gKiBjbG9zZXMgdGhlIGNyb3NzLXRlbmFudCBkYXRhIGxlYWsuIFJlYWwgUHJvbVFMIHBhcnNpbmcgKyBhdXRvbWF0aWNcbiAqIG9yZ19pZCBpbmplY3Rpb24gaXMgYSBmb2xsb3ctb24uXG4gKiAtIFRoZSBtYXRlcmlhbGl6ZWQgcnVsZSBjYXJyaWVzIGBsYWJlbHMub3JnX2lkID0gPG9yZ0lkPmAgc28gdGhlXG4gKiBhbGVydG1hbmFnZXItcmVsYXkgcm91dGVzIGZpcmluZyBhbGVydHMgdG8gdGhlIHJpZ2h0IG9yZydzXG4gKiBkZXN0aW5hdGlvbnMgKG1hdGNoZXMgdGhlIGFsZXJ0LXJlbGF5IG1vZGVsKS5cbiAqXG4gKiBAdGFibGUgb3JnX2FsZXJ0X3J1bGVzXG4gKi9cbmV4cG9ydCBjb25zdCBvcmdBbGVydFJ1bGUgPSBwZ1RhYmxlKCdvcmdfYWxlcnRfcnVsZXMnLCB7XG4gIGlkOiB1dWlkKCdpZCcpLnByaW1hcnlLZXkoKS5kZWZhdWx0UmFuZG9tKCksXG4gIG9yZ0lkOiB2YXJjaGFyKCdvcmdfaWQnLCB7IGxlbmd0aDogMjU1IH0pLm5vdE51bGwoKSxcblxuICBjcmVhdGVkQnk6IHRleHQoJ2NyZWF0ZWRfYnknKS5ub3ROdWxsKCksXG4gIGNyZWF0ZWRBdDogdGltZXN0YW1wKCdjcmVhdGVkX2F0JywgeyB3aXRoVGltZXpvbmU6IHRydWUgfSkuZGVmYXVsdE5vdygpLm5vdE51bGwoKSxcbiAgdXBkYXRlZEJ5OiB0ZXh0KCd1cGRhdGVkX2J5Jykubm90TnVsbCgpLFxuICB1cGRhdGVkQXQ6IHRpbWVzdGFtcCgndXBkYXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLmRlZmF1bHROb3coKS5ub3ROdWxsKCksXG5cbiAgLyoqIE9wZXJhdG9yLXN1cHBsaWVkIHJ1bGUgbmFtZS4gU2FuaXRpemVkIGludG8gYSB2YWxpZCBQcm9tIGFsZXJ0IG5hbWUgYXRcbiAgICogbWF0ZXJpYWxpemF0aW9uIHRpbWUgKGJlY29tZXMgYE9yZ1J1bGVfPG9yZ0lkPl88c2x1Zz5gIHRvIGF2b2lkIG5hbWVcbiAgICogY29sbGlzaW9ucyBhY3Jvc3Mgb3JncykuICovXG4gIG5hbWU6IHZhcmNoYXIoJ25hbWUnLCB7IGxlbmd0aDogMTAwIH0pLm5vdE51bGwoKSxcbiAgLyoqIFByb21RTCBleHByZXNzaW9uLiBNVVNUIHN1YnN0cmluZy1jb250YWluIGBvcmdfaWQ9XCI8b3JnSWQ+XCJgLiAqL1xuICBleHByOiB0ZXh0KCdleHByJykubm90TnVsbCgpLFxuICAvKiogYGZvcjogNW1gIHN0eWxlIGR1cmF0aW9uLiBWYWxpZGF0ZWQgYWdhaW5zdCBQcm9tJ3MgZHVyYXRpb24gcmVnZXguICovXG4gIGZvckR1cmF0aW9uOiB2YXJjaGFyKCdmb3JfZHVyYXRpb24nLCB7IGxlbmd0aDogMjAgfSkuZGVmYXVsdCgnNW0nKS5ub3ROdWxsKCksXG4gIC8qKiAnd2FybmluZycgfCAnY3JpdGljYWwnICBtYXRjaGVzIHRoZSBwbGF0Zm9ybS13aWRlIHNldmVyaXR5IGxhZGRlci4gKi9cbiAgc2V2ZXJpdHk6IHZhcmNoYXIoJ3NldmVyaXR5JywgeyBsZW5ndGg6IDIwIH0pXG4gICAgLiR0eXBlPCd3YXJuaW5nJyB8ICdjcml0aWNhbCc+KClcbiAgICAuZGVmYXVsdCgnd2FybmluZycpXG4gICAgLm5vdE51bGwoKSxcbiAgLyoqIEFsZXJ0bWFuYWdlciBgc3VtbWFyeWAgYW5ub3RhdGlvbi4gU3VwcG9ydHMgYHt7ICR2YWx1ZSB9fWAuICovXG4gIHN1bW1hcnk6IHRleHQoJ3N1bW1hcnknKS5ub3ROdWxsKCksXG4gIC8qKiBBbGVydG1hbmFnZXIgYGRlc2NyaXB0aW9uYCBhbm5vdGF0aW9uLiBPcHRpb25hbDsgJycgaXMgZmluZS4gKi9cbiAgZGVzY3JpcHRpb246IHRleHQoJ2Rlc2NyaXB0aW9uJykuZGVmYXVsdCgnJykubm90TnVsbCgpLFxuXG4gIC8qKiBEaXNhYmxlZCBydWxlcyBkb24ndCBtYXRlcmlhbGl6ZS4gTGV0cyBvcGVyYXRvcnMgc3RhZ2UgcnVsZXMgd2l0aG91dCBmaXJpbmcuICovXG4gIGVuYWJsZWQ6IGJvb2xlYW4oJ2VuYWJsZWQnKS5kZWZhdWx0KHRydWUpLm5vdE51bGwoKSxcblxuICAvKiogU29mdCBkZWxldGUgc28gd2Uga2VlcCBhdWRpdCBvZiB3aG8tZGVsZXRlZC13aGF0LiAqL1xuICBkZWxldGVkQXQ6IHRpbWVzdGFtcCgnZGVsZXRlZF9hdCcsIHsgd2l0aFRpbWV6b25lOiB0cnVlIH0pLFxuICBkZWxldGVkQnk6IHRleHQoJ2RlbGV0ZWRfYnknKSxcbiAgLy8gU29mdC1kZWxldGUgcHVyZ2UgZGVhZGxpbmU6IHRoZSByZXRlbnRpb24gc3dlZXAgaGFyZC1kZWxldGVzIHRvbWJzdG9uZWRcbiAgLy8gcm93cyBvbmNlIGBwdXJnZV9hZnRlcmAgaGFzIHBhc3NlZCAoc2V0IG9uIGRlbGV0ZSBhbG9uZ3NpZGUgZGVsZXRlZF9hdCkuXG4gIHB1cmdlQWZ0ZXI6IHRpbWVzdGFtcCgncHVyZ2VfYWZ0ZXInLCB7IHdpdGhUaW1lem9uZTogdHJ1ZSB9KSxcbn0sICh0YWJsZSkgPT4gKHtcbiAgLy8gUGFydGlhbCBpbmRleCBvdmVyIGp1c3QgdGhlIHRvbWJzdG9uZXMg4oCUIGRyaXZlcyB0aGUgcmV0ZW50aW9uIHB1cmdlIHN3ZWVwLlxuICBwdXJnZUlkeDogaW5kZXgoJ29yZ19hbGVydF9ydWxlX3B1cmdlX2lkeCcpLm9uKHRhYmxlLnB1cmdlQWZ0ZXIpLndoZXJlKHNxbGBkZWxldGVkX2F0IElTIE5PVCBOVUxMYCksXG4gIC8vIFBlci1vcmcgbGlzdGluZyArIG1hdGVyaWFsaXplcidzIGVuYWJsZWQtb25seSBzY2FuLlxuICBvcmdFbmFibGVkSWR4OiBpbmRleCgnb3JnX2FsZXJ0X3J1bGVfb3JnX2VuYWJsZWRfaWR4JylcbiAgICAub24odGFibGUub3JnSWQsIHRhYmxlLmVuYWJsZWQpLFxuICAvLyBVbmlxdWUgd2l0aGluIGFuIG9yZyBzbyBvcGVyYXRvcnMgY2FuJ3QgYWNjaWRlbnRhbGx5IGNsb25lIGEgcnVsZS5cbiAgb3JnTmFtZVVxOiB1bmlxdWVJbmRleCgnb3JnX2FsZXJ0X3J1bGVfb3JnX25hbWVfdXEnKVxuICAgIC5vbih0YWJsZS5vcmdJZCwgdGFibGUubmFtZSlcbiAgICAud2hlcmUoc3FsYGRlbGV0ZWRfYXQgSVMgTlVMTGApLFxufSkpO1xuXG5leHBvcnQgdHlwZSBPcmdBbGVydERlc3RpbmF0aW9uID0gdHlwZW9mIG9yZ0FsZXJ0RGVzdGluYXRpb24uJGluZmVyU2VsZWN0O1xuZXhwb3J0IHR5cGUgT3JnQWxlcnREZXN0aW5hdGlvbkluc2VydCA9IHR5cGVvZiBvcmdBbGVydERlc3RpbmF0aW9uLiRpbmZlckluc2VydDtcbmV4cG9ydCB0eXBlIE9yZ0FsZXJ0RGVzdGluYXRpb25VcGRhdGUgPSBQYXJ0aWFsPE9taXQ8T3JnQWxlcnREZXN0aW5hdGlvbkluc2VydCwgJ2lkJyB8ICdjcmVhdGVkQXQnIHwgJ2NyZWF0ZWRCeScgfCAnb3JnSWQnPj47XG4iXX0=