@mj-biz-apps/orders-server 5.12.2 → 5.14.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,42 @@
1
+ /**
2
+ * @fileoverview `Orders: Spawn Renewals` — the scheduling surface for `Orders.SpawnRenewals`.
3
+ *
4
+ * WHY THIS EXISTS AT ALL, GIVEN THE OPERATION ALREADY DOES THE WORK. `Orders.SpawnRenewals` is a
5
+ * remote operation, which is the API a browser calls. Nothing calls it, because renewals have no
6
+ * browser: the term expires whether or not somebody opens the app that week. A scheduled job is the
7
+ * caller this needs, and MJ's scheduler dispatches Actions and Agents — there is no driver that
8
+ * takes an operation key. So the Action is the adapter between the two, and it is deliberately the
9
+ * thinnest thing that can be: read params, route to the operation, report what came back.
10
+ *
11
+ * NO RENEWAL LOGIC LIVES HERE, and that is the point. Selection, both idempotency guards, the
12
+ * booking path and the lead-day inheritance are all in `SpawnRenewalsOperation`, where the check
13
+ * suite (SR1–SR11) already holds them. A second implementation living in an Action would be a
14
+ * second thing to keep true, and the first one to drift would be the one nobody runs by hand.
15
+ *
16
+ * IT ROUTES, IT DOES NOT CONSTRUCT. `OrdersSpawnRenewalsOperation.Execute` goes through the
17
+ * provider, which on a server resolves the registered subclass and runs its `Authorize` hook.
18
+ * Calling the server class directly would skip that hook and pin this file to a server-only import
19
+ * it does not otherwise need.
20
+ *
21
+ * PREVIEW IS A PARAMETER, NOT A SEPARATE ACTION. The go-live gate is one preview run whose list a
22
+ * person confirms before the same job is allowed to place anything. Two Actions would be two code
23
+ * paths, and the one that bills customers would be the one that had never been rehearsed.
24
+ *
25
+ * @module @mj-biz-apps/orders-actions
26
+ */
27
+ import { BaseAction } from '@memberjunction/actions';
28
+ import type { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
29
+ /**
30
+ * Place the renewal orders that are due, or report what would be placed.
31
+ *
32
+ * Inputs: `AsOfDate`, `Preview`, `MaxCount`, `SubscriptionID` — all optional.
33
+ * Outputs: `Placed`, `Skipped`, `CandidateCount`, `Candidates`, `PreviewedOnly`.
34
+ */
35
+ export declare class SpawnRenewalsAction extends BaseAction {
36
+ /** An action must not throw at its caller — same reasoning as the other hand-authored actions. */
37
+ protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
38
+ private spawn;
39
+ }
40
+ /** Tree-shaking anchor — without it the decorator never runs and the action has nothing behind it. */
41
+ export declare function LoadSpawnRenewalsAction(): void;
42
+ //# sourceMappingURL=spawn-renewals.action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-renewals.action.d.ts","sourceRoot":"","sources":["../../src/custom/spawn-renewals.action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EAAe,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAgErG;;;;;GAKG;AACH,qBACa,mBAAoB,SAAQ,UAAU;IAC/C,kGAAkG;cAClF,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAYzE,KAAK;CA4HtB;AAED,sGAAsG;AACtG,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * @fileoverview `Orders: Spawn Renewals` — the scheduling surface for `Orders.SpawnRenewals`.
3
+ *
4
+ * WHY THIS EXISTS AT ALL, GIVEN THE OPERATION ALREADY DOES THE WORK. `Orders.SpawnRenewals` is a
5
+ * remote operation, which is the API a browser calls. Nothing calls it, because renewals have no
6
+ * browser: the term expires whether or not somebody opens the app that week. A scheduled job is the
7
+ * caller this needs, and MJ's scheduler dispatches Actions and Agents — there is no driver that
8
+ * takes an operation key. So the Action is the adapter between the two, and it is deliberately the
9
+ * thinnest thing that can be: read params, route to the operation, report what came back.
10
+ *
11
+ * NO RENEWAL LOGIC LIVES HERE, and that is the point. Selection, both idempotency guards, the
12
+ * booking path and the lead-day inheritance are all in `SpawnRenewalsOperation`, where the check
13
+ * suite (SR1–SR11) already holds them. A second implementation living in an Action would be a
14
+ * second thing to keep true, and the first one to drift would be the one nobody runs by hand.
15
+ *
16
+ * IT ROUTES, IT DOES NOT CONSTRUCT. `OrdersSpawnRenewalsOperation.Execute` goes through the
17
+ * provider, which on a server resolves the registered subclass and runs its `Authorize` hook.
18
+ * Calling the server class directly would skip that hook and pin this file to a server-only import
19
+ * it does not otherwise need.
20
+ *
21
+ * PREVIEW IS A PARAMETER, NOT A SEPARATE ACTION. The go-live gate is one preview run whose list a
22
+ * person confirms before the same job is allowed to place anything. Two Actions would be two code
23
+ * paths, and the one that bills customers would be the one that had never been rehearsed.
24
+ *
25
+ * @module @mj-biz-apps/orders-actions
26
+ */
27
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
28
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
30
+ 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;
31
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
32
+ };
33
+ import { BaseAction } from '@memberjunction/actions';
34
+ import { Metadata } from '@memberjunction/core';
35
+ import { RegisterClass } from '@memberjunction/global';
36
+ import { OrdersSpawnRenewalsOperation } from '@mj-biz-apps/orders-entities';
37
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
38
+ function param(params, name) {
39
+ return params.Params?.find((p) => p.Name?.toLowerCase() === name.toLowerCase())?.Value;
40
+ }
41
+ function strParam(params, name) {
42
+ const raw = param(params, name);
43
+ if (raw == null)
44
+ return null;
45
+ const value = String(raw).trim();
46
+ return value.length ? value : null;
47
+ }
48
+ /**
49
+ * `null` means ABSENT; a value that is present but unreadable comes back as `NaN` so the caller
50
+ * refuses it. Folding the two together is what would make a mis-typed `MaxCount` read as "no cap
51
+ * was asked for" — the cap silently disappears in exactly the mis-configuration it exists to catch.
52
+ */
53
+ function numParam(params, name) {
54
+ const raw = param(params, name);
55
+ if (!supplied(params, name))
56
+ return null;
57
+ return Number(raw);
58
+ }
59
+ /**
60
+ * Whether the caller actually gave us this parameter. A scheduler writes an unset parameter as an
61
+ * empty string rather than omitting the row, so blank is absent — otherwise clearing a value in
62
+ * the job editor turns into a job that fails every night instead of one that takes the default.
63
+ */
64
+ function supplied(params, name) {
65
+ const raw = param(params, name);
66
+ return raw != null && String(raw).trim().length > 0;
67
+ }
68
+ /**
69
+ * A scheduler stores every param as text, so `false` arrives as the string "false" — which is
70
+ * truthy. Reading it loosely here is what keeps a job configured for preview from placing orders.
71
+ */
72
+ function boolParam(params, name) {
73
+ const raw = param(params, name);
74
+ if (raw == null || raw === '')
75
+ return null;
76
+ if (typeof raw === 'boolean')
77
+ return raw;
78
+ const value = String(raw).trim().toLowerCase();
79
+ if (['true', '1', 'yes', 'y'].includes(value))
80
+ return true;
81
+ if (['false', '0', 'no', 'n'].includes(value))
82
+ return false;
83
+ return null;
84
+ }
85
+ function setOutput(params, name, value) {
86
+ const existing = params.Params?.find((p) => p.Name?.toLowerCase() === name.toLowerCase());
87
+ if (existing) {
88
+ existing.Value = value;
89
+ existing.Type = 'Output';
90
+ return;
91
+ }
92
+ params.Params = params.Params ?? [];
93
+ params.Params.push({ Name: name, Value: value, Type: 'Output' });
94
+ }
95
+ /**
96
+ * Place the renewal orders that are due, or report what would be placed.
97
+ *
98
+ * Inputs: `AsOfDate`, `Preview`, `MaxCount`, `SubscriptionID` — all optional.
99
+ * Outputs: `Placed`, `Skipped`, `CandidateCount`, `Candidates`, `PreviewedOnly`.
100
+ */
101
+ let SpawnRenewalsAction = class SpawnRenewalsAction extends BaseAction {
102
+ /** An action must not throw at its caller — same reasoning as the other hand-authored actions. */
103
+ async InternalRunAction(params) {
104
+ try {
105
+ return await this.spawn(params);
106
+ }
107
+ catch (error) {
108
+ return {
109
+ Success: false,
110
+ ResultCode: 'ERROR',
111
+ Message: `The renewal pass failed: ${error instanceof Error ? error.message : String(error)}`,
112
+ };
113
+ }
114
+ }
115
+ async spawn(params) {
116
+ const user = params.ContextUser;
117
+ if (!user) {
118
+ return {
119
+ Success: false,
120
+ ResultCode: 'NO_CONTEXT_USER',
121
+ Message: 'ContextUser is required: a renewal places a confirmed order, and the order has to be attributable to somebody.',
122
+ };
123
+ }
124
+ const input = {};
125
+ const asOf = strParam(params, 'AsOfDate');
126
+ if (asOf !== null) {
127
+ // A date we cannot read is refused rather than quietly replaced with today. Today is
128
+ // the one value most likely to look right and be wrong — a preview run for the cutover
129
+ // would silently report the wrong quarter, and a live run would bill it.
130
+ if (Number.isNaN(new Date(asOf).getTime())) {
131
+ return {
132
+ Success: false,
133
+ ResultCode: 'INVALID_AS_OF_DATE',
134
+ Message: `'${asOf}' is not a date. AsOfDate takes YYYY-MM-DD, and is omitted for "today".`,
135
+ };
136
+ }
137
+ input.AsOfDate = asOf;
138
+ }
139
+ const subscriptionID = strParam(params, 'SubscriptionID');
140
+ if (subscriptionID !== null) {
141
+ if (!UUID.test(subscriptionID)) {
142
+ return {
143
+ Success: false,
144
+ ResultCode: 'INVALID_SUBSCRIPTION_ID',
145
+ Message: `'${subscriptionID}' is not a subscription ID. This takes the Subscription row's ID, not its SubscriptionNumber.`,
146
+ };
147
+ }
148
+ input.SubscriptionID = subscriptionID;
149
+ }
150
+ const maxCount = numParam(params, 'MaxCount');
151
+ if (maxCount !== null) {
152
+ // Refused rather than dropped. A dropped MaxCount is not a smaller cap, it is NO cap —
153
+ // the operation falls back to MAX_SAFE_INTEGER — so '1,000' would invoice the book it
154
+ // was written to protect.
155
+ if (!Number.isInteger(maxCount) || maxCount < 1) {
156
+ return {
157
+ Success: false,
158
+ ResultCode: 'INVALID_MAX_COUNT',
159
+ Message: `MaxCount is a cap on orders placed in one pass, so it must be a whole number of at least 1 — got '${String(param(params, 'MaxCount'))}'.`,
160
+ };
161
+ }
162
+ input.MaxCount = maxCount;
163
+ }
164
+ const preview = boolParam(params, 'Preview');
165
+ if (preview === null && supplied(params, 'Preview')) {
166
+ return {
167
+ Success: false,
168
+ ResultCode: 'INVALID_PREVIEW',
169
+ Message: `Preview takes true or false — got '${String(param(params, 'Preview'))}'. Refused rather than guessed, because the wrong guess bills customers.`,
170
+ };
171
+ }
172
+ if (preview !== null) {
173
+ input.Preview = preview;
174
+ }
175
+ const provider = params.Provider ?? Metadata.Provider;
176
+ const result = await new OrdersSpawnRenewalsOperation().Execute(input, { provider, user });
177
+ if (!result.Success || !result.Output) {
178
+ return {
179
+ Success: false,
180
+ ResultCode: result.ResultCode ?? 'OPERATION_FAILED',
181
+ Params: params.Params,
182
+ Message: result.ErrorMessage ?? 'Orders.SpawnRenewals returned no result.',
183
+ };
184
+ }
185
+ const output = result.Output;
186
+ setOutput(params, 'Placed', output.Placed);
187
+ setOutput(params, 'Skipped', output.Skipped);
188
+ setOutput(params, 'CandidateCount', output.Candidates.length);
189
+ // The candidate list is the deliverable of a preview run, so it comes back in full rather
190
+ // than as a count. The scheduler stores it on the ScheduledJobRun, which is where the
191
+ // person confirming the list reads it.
192
+ setOutput(params, 'Candidates', output.Candidates);
193
+ // NOT named `Preview`. `setOutput` matches by name, so writing the flag back under the
194
+ // input's own name overwrites the value the job was called with and flips that row's Type
195
+ // — destroying the one record of whether this pass was a rehearsal or the real thing.
196
+ setOutput(params, 'PreviewedOnly', input.Preview === true);
197
+ // A LIVE PASS THAT LEFT A DUE SUBSCRIPTION UNRENEWED IS NOT A SUCCESS. The operation
198
+ // catches each booking failure on purpose — one bad row must not stop the batch — records
199
+ // the reason on the candidate and carries on reporting Success. Passing that straight
200
+ // through is how a night on which every renewal threw writes a green ScheduledJobRun, and
201
+ // a job that notifies only on failure then tells nobody: it renews nobody and looks exactly
202
+ // like nothing having been due. Both ways a live candidate goes unplaced need a person —
203
+ // a booking that threw, and a prior pass whose term write failed after its order was
204
+ // booked. A preview places nothing by definition, so nothing there is unplaced.
205
+ const unplaced = input.Preview === true ? [] : output.Candidates.filter((c) => !c.OrderID);
206
+ if (!output.Success || unplaced.length > 0) {
207
+ const detail = unplaced
208
+ .slice(0, 3)
209
+ .map((c) => `${c.SubscriptionNumber}: ${c.SkippedReason ?? 'no reason reported'}`)
210
+ .join('; ');
211
+ return {
212
+ Success: false,
213
+ ResultCode: output.Success ? 'PARTIAL' : 'OPERATION_REPORTED_FAILURE',
214
+ Params: params.Params,
215
+ Message: `${output.Placed} renewal order(s) placed; ${unplaced.length} due subscription(s) were NOT renewed ` +
216
+ `(every reason is on Candidates)${detail ? `: ${detail}` : ''}` +
217
+ `${unplaced.length > 3 ? `, and ${unplaced.length - 3} more` : ''}.`,
218
+ };
219
+ }
220
+ return {
221
+ Success: true,
222
+ ResultCode: input.Preview === true ? 'PREVIEWED' : 'COMPLETED',
223
+ Params: params.Params,
224
+ Message: output.Message ?? `${output.Placed} renewal order(s) placed, ${output.Skipped} skipped.`,
225
+ };
226
+ }
227
+ };
228
+ SpawnRenewalsAction = __decorate([
229
+ RegisterClass(BaseAction, 'Orders.SpawnRenewals')
230
+ ], SpawnRenewalsAction);
231
+ export { SpawnRenewalsAction };
232
+ /** Tree-shaking anchor — without it the decorator never runs and the action has nothing behind it. */
233
+ export function LoadSpawnRenewalsAction() {
234
+ void SpawnRenewalsAction;
235
+ }
236
+ //# sourceMappingURL=spawn-renewals.action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-renewals.action.js","sourceRoot":"","sources":["../../src/custom/spawn-renewals.action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;;;;;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAA0B,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,4BAA4B,EAA2B,MAAM,8BAA8B,CAAC;AAErG,MAAM,IAAI,GAAG,iEAAiE,CAAC;AAE/E,SAAS,KAAK,CAAC,MAAuB,EAAE,IAAY;IAChD,OAAO,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,KAAK,CAAC;AAC3F,CAAC;AAED,SAAS,QAAQ,CAAC,MAAuB,EAAE,IAAY;IACnD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAAC,MAAuB,EAAE,IAAY;IACnD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAAC,MAAuB,EAAE,IAAY;IACnD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChC,OAAO,GAAG,IAAI,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,MAAuB,EAAE,IAAY;IACpD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,OAAO,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,SAAS,CAAC,MAAuB,EAAE,IAAY,EAAE,KAAc;IACpE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1F,IAAI,QAAQ,EAAE,CAAC;QACX,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;QACvB,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC;QACzB,OAAO;IACX,CAAC;IACD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAiB,CAAC,CAAC;AACpF,CAAC;AAED;;;;;GAKG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,UAAU;IAC/C,kGAAkG;IACxF,KAAK,CAAC,iBAAiB,CAAC,MAAuB;QACrD,IAAI,CAAC;YACD,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,OAAO;gBACnB,OAAO,EAAE,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aAChG,CAAC;QACN,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,MAAuB;QACvC,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,iBAAiB;gBAC7B,OAAO,EACH,gHAAgH;aACvH,CAAC;QACN,CAAC;QAED,MAAM,KAAK,GAAuB,EAAE,CAAC;QAErC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC1C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,qFAAqF;YACrF,uFAAuF;YACvF,yEAAyE;YACzE,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBACzC,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,UAAU,EAAE,oBAAoB;oBAChC,OAAO,EAAE,IAAI,IAAI,yEAAyE;iBAC7F,CAAC;YACN,CAAC;YACD,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1B,CAAC;QAED,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAC1D,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC7B,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,UAAU,EAAE,yBAAyB;oBACrC,OAAO,EAAE,IAAI,cAAc,+FAA+F;iBAC7H,CAAC;YACN,CAAC;YACD,KAAK,CAAC,cAAc,GAAG,cAAc,CAAC;QAC1C,CAAC;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC9C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,uFAAuF;YACvF,sFAAsF;YACtF,0BAA0B;YAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;gBAC9C,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,UAAU,EAAE,mBAAmB;oBAC/B,OAAO,EAAE,qGAAqG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,IAAI;iBACtJ,CAAC;YACN,CAAC;YACD,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC9B,CAAC;QAED,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC7C,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;YAClD,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,iBAAiB;gBAC7B,OAAO,EAAE,sCAAsC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,0EAA0E;aAC5J,CAAC;QACN,CAAC;QACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACnB,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QAC5B,CAAC;QAED,MAAM,QAAQ,GAAsB,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC;QACzE,MAAM,MAAM,GAAG,MAAM,IAAI,4BAA4B,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3F,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACpC,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,kBAAkB;gBACnD,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EAAE,MAAM,CAAC,YAAY,IAAI,0CAA0C;aAC7E,CAAC;QACN,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7C,SAAS,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC9D,0FAA0F;QAC1F,sFAAsF;QACtF,uCAAuC;QACvC,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACnD,uFAAuF;QACvF,0FAA0F;QAC1F,sFAAsF;QACtF,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;QAE3D,qFAAqF;QACrF,0FAA0F;QAC1F,sFAAsF;QACtF,0FAA0F;QAC1F,4FAA4F;QAC5F,yFAAyF;QACzF,qFAAqF;QACrF,gFAAgF;QAChF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3F,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,QAAQ;iBAClB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,kBAAkB,KAAK,CAAC,CAAC,aAAa,IAAI,oBAAoB,EAAE,CAAC;iBACjF,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,4BAA4B;gBACrE,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EACH,GAAG,MAAM,CAAC,MAAM,6BAA6B,QAAQ,CAAC,MAAM,wCAAwC;oBACpG,kCAAkC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;oBAC/D,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG;aAC3E,CAAC;QACN,CAAC;QAED,OAAO;YACH,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW;YAC9D,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,GAAG,MAAM,CAAC,MAAM,6BAA6B,MAAM,CAAC,OAAO,WAAW;SACpG,CAAC;IACN,CAAC;CACJ,CAAA;AA1IY,mBAAmB;IAD/B,aAAa,CAAC,UAAU,EAAE,sBAAsB,CAAC;GACrC,mBAAmB,CA0I/B;;AAED,sGAAsG;AACtG,MAAM,UAAU,uBAAuB;IACnC,KAAK,mBAAmB,CAAC;AAC7B,CAAC"}