@theotherwillembotha/node-red-statsd 0.4.0

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.
@@ -0,0 +1,3 @@
1
+ export * from "./statsd/service/StatsdMetricsContainer";
2
+ export * from "./statsd/node/StatsdMetricsConfigNode";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yCAAyC,CAAC;AACxD,cAAc,uCAAuC,CAAC"}
package/build/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./statsd/service/StatsdMetricsContainer"), exports);
18
+ __exportStar(require("./statsd/node/StatsdMetricsConfigNode"), exports);
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /**
3
+ * NodeManagerRuntime.ts
4
+ *
5
+ * STANDALONE - zero imports from the rest of plugincore.
6
+ *
7
+ * This file is compiled and copied into every plugin's build output so that
8
+ * plugins are self-contained and do not require plugincore to be separately
9
+ * installed in the user's Node-RED environment.
10
+ *
11
+ * When multiple plugins are deployed, each ships its own copy of this file.
12
+ * The first plugin to load registers its NodeManager and nodes; subsequent
13
+ * copies operate independently on their own node types with no conflict.
14
+ *
15
+ * POST_CONSTRUCT_KEY is intentionally a plain string (not a Symbol) so that
16
+ * the decorators (from plugincore's NodeConstructor, loaded via the plugin's
17
+ * dependency on plugincore) and this runtime file (a separate module instance)
18
+ * resolve to the same property key on node instances.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.NodeManager = exports.POST_CONSTRUCT_KEY = exports.NODEMANAGER_API_VERSION = void 0;
22
+ exports.runPostConstructInitializers = runPostConstructInitializers;
23
+ // ─── API version ────────────────────────────────────────────────────────────
24
+ // Semver of the NodeManager API contract - independent of plugincore's package
25
+ // version. Bump when the contract changes; plugins can read this to warn users
26
+ // that they were built against a different NodeManager version.
27
+ exports.NODEMANAGER_API_VERSION = "1.0.0";
28
+ // ─── Shared key for post-construct initializer lists ────────────────────────
29
+ // Must be a plain string so it resolves identically across module instances.
30
+ exports.POST_CONSTRUCT_KEY = '__plugincore_postConstructInitializers__';
31
+ // ─── Post-construct initializer runner ───────────────────────────────────────
32
+ function runPostConstructInitializers(instance) {
33
+ const initializers = instance[exports.POST_CONSTRUCT_KEY];
34
+ if (!initializers || initializers.length === 0)
35
+ return;
36
+ const className = instance.constructor.name;
37
+ initializers.forEach((init, index) => {
38
+ try {
39
+ init(instance);
40
+ }
41
+ catch (error) {
42
+ console.error(`Post-construct initialization failed:\n` +
43
+ ` Class: ${className}\n` +
44
+ ` Initializer: ${index + 1}/${initializers.length}\n` +
45
+ ` Error: ${error instanceof Error ? error.message : String(error)}`);
46
+ throw error;
47
+ }
48
+ });
49
+ delete instance[exports.POST_CONSTRUCT_KEY];
50
+ }
51
+ // ─── NodeManager ─────────────────────────────────────────────────────────────
52
+ // RED is stored on `global` rather than as a static class field so that all
53
+ // module instances of NodeManagerRuntime (the local copy bundled into Nodes.js
54
+ // and the copy bundled via plugincore's NodeConstructor) share the same value.
55
+ // Without this, esbuild's two separate inline copies would have independent
56
+ // static fields and the one used by decorators would never see RED being set.
57
+ const _GLOBAL_RED_KEY = '__plugincore_NodeManager_RED__';
58
+ // ─── Global node-type registration guard ─────────────────────────────────────
59
+ // When multiple self-contained plugins are installed they each bundle plugincore
60
+ // inline and each try to call RED.nodes.registerType for the same shared
61
+ // infrastructure node types (ConsoleLoggerConfigNode, RestLoggerConfigNode, etc.).
62
+ // Node-RED rejects duplicate registrations with a warning and the second
63
+ // plugin's Nodes.js fails to load. This global set tracks which types have
64
+ // already been registered so subsequent plugins silently skip them.
65
+ const _GLOBAL_REGISTERED_NODES_KEY = '__plugincore_registered_nodes__';
66
+ function getRegisteredNodes() {
67
+ if (!global[_GLOBAL_REGISTERED_NODES_KEY]) {
68
+ global[_GLOBAL_REGISTERED_NODES_KEY] = new Set();
69
+ }
70
+ return global[_GLOBAL_REGISTERED_NODES_KEY];
71
+ }
72
+ class NodeManager {
73
+ constructor(RED) {
74
+ this.typeBacklog = [];
75
+ global[_GLOBAL_RED_KEY] = RED;
76
+ const nodeTypeServiceId = "@theotherwillembotha/nodetypeservice";
77
+ const nodeTypeServiceListener = (pluginID) => {
78
+ if (pluginID === nodeTypeServiceId) {
79
+ RED.events.off('plugin.instantiated', nodeTypeServiceListener);
80
+ this.nodeTypeService = RED.plugins.get(nodeTypeServiceId).instance;
81
+ for (const nodeType of this.typeBacklog) {
82
+ for (const tag of nodeType.getNodeDescriptor().tags()) {
83
+ this.nodeTypeService.registerNodeType(tag, nodeType);
84
+ }
85
+ }
86
+ this.typeBacklog = [];
87
+ }
88
+ };
89
+ this.nodeTypeService = RED.plugins.get(nodeTypeServiceId)?.instance;
90
+ if (!this.nodeTypeService) {
91
+ RED.events.on('plugin.instantiated', nodeTypeServiceListener);
92
+ }
93
+ }
94
+ static get RED() {
95
+ return global[_GLOBAL_RED_KEY];
96
+ }
97
+ registerNodeType(typeName, type) {
98
+ if (!type) {
99
+ console.error(`[NodeManager v${exports.NODEMANAGER_API_VERSION}] Type "${typeName}" is undefined. ` +
100
+ `Ensure it is exported and included in GenerateNodes.`);
101
+ return this;
102
+ }
103
+ const registeredNodes = getRegisteredNodes();
104
+ if (registeredNodes.has(typeName)) {
105
+ // Already registered by another plugin - skip to avoid Node-RED duplicate-registration error.
106
+ return this;
107
+ }
108
+ registeredNodes.add(typeName);
109
+ const nodeConstructor = function (config) {
110
+ try {
111
+ NodeManager.RED.nodes.createNode(this, config);
112
+ const node = new type(this, config);
113
+ runPostConstructInitializers(node);
114
+ if (node.onInit) {
115
+ node.onInit();
116
+ }
117
+ }
118
+ catch (error) {
119
+ console.error(`[NodeManager v${exports.NODEMANAGER_API_VERSION}] Failed to construct node "${typeName}":`, error);
120
+ }
121
+ };
122
+ try {
123
+ NodeManager.RED.nodes.registerType(typeName, nodeConstructor, { settings: {} });
124
+ const nodeDescription = type.getNodeDescriptor();
125
+ if (this.nodeTypeService) {
126
+ for (const tag of nodeDescription.tags()) {
127
+ this.nodeTypeService.registerNodeType(tag, type);
128
+ }
129
+ }
130
+ else {
131
+ this.typeBacklog.push(type);
132
+ }
133
+ }
134
+ catch (error) {
135
+ console.error(`[NodeManager v${exports.NODEMANAGER_API_VERSION}] Failed to register node type "${typeName}":`, error);
136
+ }
137
+ return this;
138
+ }
139
+ }
140
+ exports.NodeManager = NodeManager;
@@ -0,0 +1,34 @@
1
+ <script type="application/json" fragment-section="metaData">
2
+ { "label": "StatsD Counter" }
3
+ </script>
4
+
5
+ <script type="text/html" fragment-section="onForm">
6
+ <div class="form-row">
7
+ <label class="towb_editorlabel" for="fragment-metric-key"><i class="fa fa-key"></i> Metric Key</label>
8
+ <input type="text" id="fragment-metric-key" placeholder="{{metric}}.{{name}}" />
9
+ </div>
10
+ <div class="form-tips" style="margin-bottom:8px;">
11
+ <i class="fa fa-info-circle"></i> <b>Metric Key</b> supports template variables:
12
+ <code>{{metric}}</code>, <code>{{name}}</code>, <code>{{flow}}</code>,
13
+ <code>{{type}}</code>, <code>{{id}}</code>.
14
+ The prefix configured on the StatsD config node is prepended automatically.
15
+ </div>
16
+ </script>
17
+
18
+ <script type="text/javascript" fragment-section="onLoad">
19
+ var $c = $(container);
20
+ $c.find("#fragment-metric-key").val(config.metricKey || "{{metric}}.{{name}}");
21
+ </script>
22
+
23
+ <script type="text/javascript" fragment-section="onSave">
24
+ var $c = $(container);
25
+ return {
26
+ metricKey: $c.find("#fragment-metric-key").val() || "{{metric}}.{{name}}"
27
+ };
28
+ </script>
29
+
30
+ <script type="text/javascript" fragment-section="onReplace">
31
+ </script>
32
+
33
+ <script type="text/javascript" fragment-section="onDestroy">
34
+ </script>
@@ -0,0 +1,34 @@
1
+ <script type="application/json" fragment-section="metaData">
2
+ { "label": "StatsD Gauge" }
3
+ </script>
4
+
5
+ <script type="text/html" fragment-section="onForm">
6
+ <div class="form-row">
7
+ <label class="towb_editorlabel" for="fragment-metric-key"><i class="fa fa-key"></i> Metric Key</label>
8
+ <input type="text" id="fragment-metric-key" placeholder="{{metric}}.{{name}}" />
9
+ </div>
10
+ <div class="form-tips" style="margin-bottom:8px;">
11
+ <i class="fa fa-info-circle"></i> <b>Metric Key</b> supports template variables:
12
+ <code>{{metric}}</code>, <code>{{name}}</code>, <code>{{flow}}</code>,
13
+ <code>{{type}}</code>, <code>{{id}}</code>.
14
+ The prefix configured on the StatsD config node is prepended automatically.
15
+ </div>
16
+ </script>
17
+
18
+ <script type="text/javascript" fragment-section="onLoad">
19
+ var $c = $(container);
20
+ $c.find("#fragment-metric-key").val(config.metricKey || "{{metric}}.{{name}}");
21
+ </script>
22
+
23
+ <script type="text/javascript" fragment-section="onSave">
24
+ var $c = $(container);
25
+ return {
26
+ metricKey: $c.find("#fragment-metric-key").val() || "{{metric}}.{{name}}"
27
+ };
28
+ </script>
29
+
30
+ <script type="text/javascript" fragment-section="onReplace">
31
+ </script>
32
+
33
+ <script type="text/javascript" fragment-section="onDestroy">
34
+ </script>
@@ -0,0 +1,41 @@
1
+ <script type="application/json" fragment-section="metaData">
2
+ { "label": "StatsD Timer" }
3
+ </script>
4
+
5
+ <script type="text/html" fragment-section="onForm">
6
+ <div class="form-row">
7
+ <label class="towb_editorlabel"><i class="fa fa-clock-o"></i> Metric Type</label>
8
+ <span style="line-height:34px;">Timing (ms)</span>
9
+ </div>
10
+ <div class="form-row">
11
+ <label class="towb_editorlabel" for="fragment-metric-key"><i class="fa fa-key"></i> Metric Key</label>
12
+ <input type="text" id="fragment-metric-key" placeholder="{{metric}}.{{name}}" />
13
+ </div>
14
+ <div class="form-tips" style="margin-bottom:8px;">
15
+ <i class="fa fa-info-circle"></i> StatsD timers record duration values in milliseconds.
16
+ Aggregation (percentiles, averages, counts) is performed by the StatsD server.<br/>
17
+ <b>Metric Key</b> supports template variables:
18
+ <code>{{metric}}</code>, <code>{{name}}</code>, <code>{{flow}}</code>,
19
+ <code>{{type}}</code>, <code>{{id}}</code>.
20
+ The prefix configured on the StatsD config node is prepended automatically.
21
+ </div>
22
+ </script>
23
+
24
+ <script type="text/javascript" fragment-section="onLoad">
25
+ var $c = $(container);
26
+ $c.find("#fragment-metric-key").val(config.metricKey || "{{metric}}.{{name}}");
27
+ </script>
28
+
29
+ <script type="text/javascript" fragment-section="onSave">
30
+ var $c = $(container);
31
+ return {
32
+ metricType: "timing",
33
+ metricKey: $c.find("#fragment-metric-key").val() || "{{metric}}.{{name}}"
34
+ };
35
+ </script>
36
+
37
+ <script type="text/javascript" fragment-section="onReplace">
38
+ </script>
39
+
40
+ <script type="text/javascript" fragment-section="onDestroy">
41
+ </script>
@@ -0,0 +1,15 @@
1
+ import { Node } from "node-red";
2
+ import { ConfigNodeConfig } from "@theotherwillembotha/node-red-plugincore";
3
+ import { MetricsConfigNode, MetricsContainer, MetricsConfig } from "@theotherwillembotha/node-red-plugincore";
4
+ interface StatsdMetricsConfigNodeConfig extends ConfigNodeConfig {
5
+ host: string;
6
+ port: number;
7
+ prefix: string;
8
+ protocol: string;
9
+ }
10
+ export declare class StatsdMetricsConfigNode extends MetricsConfigNode {
11
+ constructor(node: Node, config: StatsdMetricsConfigNodeConfig);
12
+ protected createContainer(baseConfig: MetricsConfig): MetricsContainer;
13
+ }
14
+ export {};
15
+ //# sourceMappingURL=StatsdMetricsConfigNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatsdMetricsConfigNode.d.ts","sourceRoot":"","sources":["../../../src/statsd/node/StatsdMetricsConfigNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAiB,MAAM,0CAA0C,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAI9G,UAAU,6BAA8B,SAAQ,gBAAgB;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,qBAQa,uBAAwB,SAAQ,iBAAiB;gBAE9C,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,6BAA6B;IAW7D,SAAS,CAAC,eAAe,CAAC,UAAU,EAAE,aAAa,GAAG,gBAAgB;CAWzE"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.StatsdMetricsConfigNode = void 0;
13
+ const node_red_plugincore_1 = require("@theotherwillembotha/node-red-plugincore");
14
+ const node_red_plugincore_2 = require("@theotherwillembotha/node-red-plugincore");
15
+ const node_red_plugincore_3 = require("@theotherwillembotha/node-red-plugincore");
16
+ const StatsdMetricsContainer_1 = require("../service/StatsdMetricsContainer");
17
+ let StatsdMetricsConfigNode = class StatsdMetricsConfigNode extends node_red_plugincore_2.MetricsConfigNode {
18
+ constructor(node, config) {
19
+ super(node, config);
20
+ this.node().on("close", () => {
21
+ const container = this.metrics();
22
+ if (container) {
23
+ container.close();
24
+ }
25
+ });
26
+ }
27
+ createContainer(baseConfig) {
28
+ const config = this.config();
29
+ const statsdConfig = {
30
+ id: baseConfig.id,
31
+ host: config.host,
32
+ port: config.port,
33
+ prefix: config.prefix,
34
+ protocol: config.protocol,
35
+ };
36
+ return new StatsdMetricsContainer_1.StatsdMetricsContainer(statsdConfig);
37
+ }
38
+ };
39
+ exports.StatsdMetricsConfigNode = StatsdMetricsConfigNode;
40
+ exports.StatsdMetricsConfigNode = StatsdMetricsConfigNode = __decorate([
41
+ (0, node_red_plugincore_3.NodeDescription)({
42
+ id: "StatsdMetricsConfigNode",
43
+ name: "StatsD Metrics Config",
44
+ group: "config",
45
+ sourceFile: node_red_plugincore_1.SourceUtility.getSourcePath("/build/", "/src/") + "StatsdMetricsConfigNode.html",
46
+ package: "@theotherwillembotha/node-red-statsd",
47
+ tags: ["MetricsProvider"]
48
+ }),
49
+ __metadata("design:paramtypes", [Object, Object])
50
+ ], StatsdMetricsConfigNode);
@@ -0,0 +1,86 @@
1
+ import { Metric, MetricCapability, MetricConfig, MetricsConfig, MetricsContainer, CounterMetric, CounterMetricConfig, CounterCallback, CounterState, GaugeMetric, GaugeMetricConfig, GaugeCallback, GaugeState, HistogramMetric, HistogramMetricConfig, HistogramCallback, SummaryMetric, SummaryMetricConfig, SummaryCallback } from "@theotherwillembotha/node-red-plugincore";
2
+ import type { BaseNode, BaseNodeConfig } from "@theotherwillembotha/node-red-plugincore";
3
+ export declare class StatsdCounterMetric extends Metric<CounterMetricConfig> implements CounterMetric {
4
+ private client;
5
+ private metricKey;
6
+ private value;
7
+ private subscribers;
8
+ constructor(client: any, metricKey: string, config: CounterMetricConfig);
9
+ inc(): this;
10
+ reset(): void;
11
+ get(): Promise<CounterState>;
12
+ subscribe(node: BaseNode<BaseNodeConfig>, callback: CounterCallback): void;
13
+ unsubscribe(node: BaseNode<BaseNodeConfig>): void;
14
+ }
15
+ export declare class StatsdGaugeMetric extends Metric<GaugeMetricConfig> implements GaugeMetric {
16
+ private client;
17
+ private metricKey;
18
+ private value;
19
+ private subscribers;
20
+ constructor(client: any, metricKey: string, config: GaugeMetricConfig);
21
+ inc(): this;
22
+ dec(): this;
23
+ set(value: number): this;
24
+ reset(): void;
25
+ get(): GaugeState;
26
+ subscribe(node: BaseNode<BaseNodeConfig>, callback: GaugeCallback): void;
27
+ unsubscribe(node: BaseNode<BaseNodeConfig>): void;
28
+ private notifySubscribers;
29
+ }
30
+ export declare class StatsdHistogramMetric extends Metric<HistogramMetricConfig> implements HistogramMetric {
31
+ private client;
32
+ private metricKey;
33
+ private sum;
34
+ private count;
35
+ private subscribers;
36
+ constructor(client: any, metricKey: string, config: HistogramMetricConfig);
37
+ observe(value: number): void;
38
+ reset(): void;
39
+ subscribe(node: BaseNode<BaseNodeConfig>, callback: HistogramCallback): void;
40
+ unsubscribe(node: BaseNode<BaseNodeConfig>): void;
41
+ }
42
+ export declare class StatsdSummaryMetric extends Metric<SummaryMetricConfig> implements SummaryMetric {
43
+ private client;
44
+ private metricKey;
45
+ private sum;
46
+ private count;
47
+ private subscribers;
48
+ constructor(client: any, metricKey: string, config: SummaryMetricConfig);
49
+ observe(value: number): void;
50
+ reset(): void;
51
+ subscribe(node: BaseNode<BaseNodeConfig>, callback: SummaryCallback): void;
52
+ unsubscribe(node: BaseNode<BaseNodeConfig>): void;
53
+ }
54
+ export interface StatsdMetricsConfig extends MetricsConfig {
55
+ host: string;
56
+ port: number;
57
+ prefix: string;
58
+ protocol: "udp" | "tcp";
59
+ }
60
+ export declare class StatsdMetricsContainer extends MetricsContainer {
61
+ private _config;
62
+ private _client;
63
+ private counters;
64
+ private gauges;
65
+ private histograms;
66
+ private summaries;
67
+ constructor(config: StatsdMetricsConfig);
68
+ supports(capability: MetricCapability): boolean;
69
+ hasChanged(config: MetricsConfig): boolean;
70
+ close(): void;
71
+ client(): any;
72
+ counter(config: CounterMetricConfig): CounterMetric;
73
+ gauge(config: GaugeMetricConfig): GaugeMetric;
74
+ histogram(config: HistogramMetricConfig): HistogramMetric;
75
+ summary(config: SummaryMetricConfig): SummaryMetric;
76
+ createTimer(metricConfig: MetricConfig, fragmentData: any): HistogramMetric | SummaryMetric;
77
+ createCounter(metricConfig: MetricConfig, fragmentData: any): CounterMetric;
78
+ createGauge(metricConfig: MetricConfig, fragmentData: any): GaugeMetric;
79
+ /**
80
+ * Resolves a metric key pattern using flat MetricConfig fields.
81
+ * All labels are fixed at creation time — no dynamic resolution needed.
82
+ */
83
+ private static resolvePattern;
84
+ static registerFragments(): void;
85
+ }
86
+ //# sourceMappingURL=StatsdMetricsContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatsdMetricsContainer.d.ts","sourceRoot":"","sources":["../../../src/statsd/service/StatsdMetricsContainer.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,MAAM,EACN,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,gBAAgB,EAEhB,aAAa,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,EACjE,WAAW,EAAI,iBAAiB,EAAI,aAAa,EAAI,UAAU,EAC/D,eAAe,EAAE,qBAAqB,EAAE,iBAAiB,EACzD,aAAa,EAAI,mBAAmB,EAAG,eAAe,EAEzD,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAQzF,qBAAa,mBAAoB,SAAQ,MAAM,CAAC,mBAAmB,CAAE,YAAW,aAAa;IACzF,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,WAAW,CAA0C;gBAEjD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB;IAMhE,GAAG,IAAI,IAAI;IAQX,KAAK,IAAI,IAAI;IAEb,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;IAI5B,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI;IAI1E,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,IAAI;CAG3D;AAMD,qBAAa,iBAAkB,SAAQ,MAAM,CAAC,iBAAiB,CAAE,YAAW,WAAW;IACnF,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,WAAW,CAAwC;gBAE/C,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB;IAM9D,GAAG,IAAI,IAAI;IAOX,GAAG,IAAI,IAAI;IAOX,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAOxB,KAAK,IAAI,IAAI;IAKb,GAAG,IAAI,UAAU;IAEjB,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAIxE,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,IAAI;IAIxD,OAAO,CAAC,iBAAiB;CAI5B;AAMD,qBAAa,qBAAsB,SAAQ,MAAM,CAAC,qBAAqB,CAAE,YAAW,eAAe;IAC/F,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,WAAW,CAA4C;gBAEnD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB;IAMlE,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ5B,KAAK,IAAI,IAAI;IAKb,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAI5E,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,IAAI;CAG3D;AAMD,qBAAa,mBAAoB,SAAQ,MAAM,CAAC,mBAAmB,CAAE,YAAW,aAAa;IACzF,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,WAAW,CAA0C;gBAEjD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB;IAMhE,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS5B,KAAK,IAAI,IAAI;IAKb,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI;IAI1E,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,IAAI;CAG3D;AAMD,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,KAAK,CAAC;CAC3B;AAED,qBAAa,sBAAuB,SAAQ,gBAAgB;IACxD,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,OAAO,CAAM;IAErB,OAAO,CAAC,QAAQ,CAAkD;IAClE,OAAO,CAAC,MAAM,CAAoD;IAClE,OAAO,CAAC,UAAU,CAAgD;IAClE,OAAO,CAAC,SAAS,CAAiD;gBAEtD,MAAM,EAAE,mBAAmB;IAehC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO;IAE/C,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO;IAU1C,KAAK,IAAI,IAAI;IAWb,MAAM,IAAI,GAAG;IAEb,OAAO,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa;IAQnD,KAAK,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW;IAQ7C,SAAS,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe;IAQzD,OAAO,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa;IAQnD,WAAW,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,GAAG,eAAe,GAAG,aAAa;IAkB3F,aAAa,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,GAAG,aAAa;IAgB3E,WAAW,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,GAAG,WAAW;IAgB9E;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;WASf,iBAAiB,IAAI,IAAI;CAsB1C"}