@usine/core 0.2.0 → 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.
Files changed (102) hide show
  1. package/README.md +43 -16
  2. package/dist/agent/agent.d.ts +12 -8
  3. package/dist/agent/agent.d.ts.map +1 -1
  4. package/dist/agent/agent.js +14 -10
  5. package/dist/agent/agent.js.map +1 -1
  6. package/dist/agent/brain.d.ts +2 -6
  7. package/dist/agent/brain.d.ts.map +1 -1
  8. package/dist/agent/brain.js +3 -7
  9. package/dist/agent/brain.js.map +1 -1
  10. package/dist/agent/capability.d.ts +4 -4
  11. package/dist/agent/capability.d.ts.map +1 -1
  12. package/dist/agent/capability.js +4 -4
  13. package/dist/agent/capability.js.map +1 -1
  14. package/dist/agent/session.d.ts +95 -21
  15. package/dist/agent/session.d.ts.map +1 -1
  16. package/dist/agent/session.js +100 -21
  17. package/dist/agent/session.js.map +1 -1
  18. package/dist/attempt/attempt.d.ts +63 -11
  19. package/dist/attempt/attempt.d.ts.map +1 -1
  20. package/dist/attempt/attempt.js +81 -11
  21. package/dist/attempt/attempt.js.map +1 -1
  22. package/dist/attempt/channel.d.ts +142 -44
  23. package/dist/attempt/channel.d.ts.map +1 -1
  24. package/dist/attempt/channel.js +124 -36
  25. package/dist/attempt/channel.js.map +1 -1
  26. package/dist/attempt/failure.d.ts +27 -14
  27. package/dist/attempt/failure.d.ts.map +1 -1
  28. package/dist/attempt/failure.js +27 -14
  29. package/dist/attempt/failure.js.map +1 -1
  30. package/dist/attempt/outcome.d.ts +3 -5
  31. package/dist/attempt/outcome.d.ts.map +1 -1
  32. package/dist/attempt/outcome.js +2 -4
  33. package/dist/attempt/outcome.js.map +1 -1
  34. package/dist/attempt/salvage.d.ts +50 -0
  35. package/dist/attempt/salvage.d.ts.map +1 -0
  36. package/dist/attempt/salvage.js +21 -0
  37. package/dist/attempt/salvage.js.map +1 -0
  38. package/dist/attempt/start.d.ts +35 -0
  39. package/dist/attempt/start.d.ts.map +1 -0
  40. package/dist/attempt/start.js +30 -0
  41. package/dist/attempt/start.js.map +1 -0
  42. package/dist/cycle-budget.d.ts +7 -8
  43. package/dist/cycle-budget.d.ts.map +1 -1
  44. package/dist/cycle-budget.js +9 -10
  45. package/dist/cycle-budget.js.map +1 -1
  46. package/dist/event.d.ts +4 -8
  47. package/dist/event.d.ts.map +1 -1
  48. package/dist/event.js +4 -8
  49. package/dist/event.js.map +1 -1
  50. package/dist/instance.d.ts +1 -1
  51. package/dist/instance.d.ts.map +1 -1
  52. package/dist/instance.js +1 -1
  53. package/dist/instance.js.map +1 -1
  54. package/dist/item.d.ts +1 -2
  55. package/dist/item.d.ts.map +1 -1
  56. package/dist/item.js +1 -2
  57. package/dist/item.js.map +1 -1
  58. package/dist/loop.d.ts +10 -2
  59. package/dist/loop.d.ts.map +1 -1
  60. package/dist/loop.js +9 -2
  61. package/dist/loop.js.map +1 -1
  62. package/dist/operator.d.ts +8 -0
  63. package/dist/operator.d.ts.map +1 -0
  64. package/dist/operator.js +9 -0
  65. package/dist/operator.js.map +1 -0
  66. package/dist/repository.d.ts +6 -8
  67. package/dist/repository.d.ts.map +1 -1
  68. package/dist/repository.js +8 -10
  69. package/dist/repository.js.map +1 -1
  70. package/dist/run/again.d.ts +13 -0
  71. package/dist/run/again.d.ts.map +1 -0
  72. package/dist/run/again.js +13 -0
  73. package/dist/run/again.js.map +1 -0
  74. package/dist/run/approval.d.ts +27 -0
  75. package/dist/run/approval.d.ts.map +1 -0
  76. package/dist/run/approval.js +26 -0
  77. package/dist/run/approval.js.map +1 -0
  78. package/dist/run/run.d.ts +2 -2
  79. package/dist/run/run.d.ts.map +1 -1
  80. package/dist/run/run.js +2 -2
  81. package/dist/run/run.js.map +1 -1
  82. package/dist/run/state.d.ts +22 -31
  83. package/dist/run/state.d.ts.map +1 -1
  84. package/dist/run/state.js +23 -36
  85. package/dist/run/state.js.map +1 -1
  86. package/dist/step/harvest.d.ts +44 -0
  87. package/dist/step/harvest.d.ts.map +1 -0
  88. package/dist/step/harvest.js +368 -0
  89. package/dist/step/harvest.js.map +1 -0
  90. package/dist/step/result.d.ts +15 -4
  91. package/dist/step/result.d.ts.map +1 -1
  92. package/dist/step/result.js +14 -4
  93. package/dist/step/result.js.map +1 -1
  94. package/dist/step/step.d.ts +2 -8
  95. package/dist/step/step.d.ts.map +1 -1
  96. package/dist/step/step.js +2 -8
  97. package/dist/step/step.js.map +1 -1
  98. package/dist/worker.d.ts +48 -4
  99. package/dist/worker.d.ts.map +1 -1
  100. package/dist/worker.js +47 -4
  101. package/dist/worker.js.map +1 -1
  102. package/package.json +27 -2
package/dist/run/state.js CHANGED
@@ -12,91 +12,78 @@ import { EventId } from "../event.js";
12
12
  * pending | waiting | queued ──► canceled (supersede, revoke: a started
13
13
  * attempt always finishes, ADR 0007)
14
14
  *
15
- * Each transition accepts only the states it is legal on, so an illegal
16
- * transition fails to compile. Construct states through the transitions or by
17
- * decoding a stored row with `RunState`.
15
+ * Each transition accepts only its legal source states, so an illegal transition is a type
16
+ * error. States come from the transitions or from decoding a stored row with `RunState`.
18
17
  */
19
- /** The operator closed the run by hand. */
20
18
  export class OperatorCanceled extends Schema.TaggedClass("CancelReason/OperatorCanceled")("OperatorCanceled", {}) {
21
19
  }
22
- /** A newer Event for the same Item took the run's place before any attempt started. */
20
+ /** Cancellation because a newer Event for the same Item arrived before any Attempt started. */
23
21
  export class Superseded extends Schema.TaggedClass("CancelReason/Superseded")("Superseded", { by: EventId }) {
24
22
  }
25
- /** The run's Item stopped matching its loop's trigger before any attempt started. */
23
+ /** Cancellation because the Item stopped matching the Loop's trigger before any Attempt started. */
26
24
  export class Revoked extends Schema.TaggedClass("CancelReason/Revoked")("Revoked", {}) {
27
25
  }
28
26
  export const CancelReason = Schema.Union([OperatorCanceled, Superseded, Revoked]);
29
- /** Just created: no attempt started and no approval gate passed. */
27
+ /** A new Run with no Attempt started and no approval gate passed. */
30
28
  export class Pending extends Schema.TaggedClass("RunState/Pending")("Pending", {}) {
31
29
  }
32
- /** Parked on the loop's approval gate. The approval it waits for is an Event like any other fact. */
30
+ /** A Run waiting for its Loop's approval Event. */
33
31
  export class Waiting extends Schema.TaggedClass("RunState/Waiting")("Waiting", {}) {
34
32
  }
35
- /** Approved and waiting for a worker slot. */
33
+ /** An approved Run waiting for a Worker slot. */
36
34
  export class Queued extends Schema.TaggedClass("RunState/Queued")("Queued", {}) {
37
35
  }
38
- /** An attempt is executing on a worker. */
36
+ /** A Run with an Attempt running on a Worker. */
39
37
  export class Running extends Schema.TaggedClass("RunState/Running")("Running", {}) {
40
38
  }
41
- /** The step finished and its result is stored. */
39
+ /** A Run whose Step finished with a stored result. */
42
40
  export class Succeeded extends Schema.TaggedClass("RunState/Succeeded")("Succeeded", {}) {
43
41
  }
44
- /** The last attempt failed and no auto-retry applies. The failure is on the Attempt, and `retry` reopens the run. */
42
+ /** A Run whose last Attempt failed without an auto-retry; the failure is stored on the Attempt. */
45
43
  export class Failed extends Schema.TaggedClass("RunState/Failed")("Failed", {}) {
46
44
  }
47
- /** Canceled, with the reason recorded. */
48
45
  export class Canceled extends Schema.TaggedClass("RunState/Canceled")("Canceled", {
49
46
  reason: CancelReason,
50
47
  }) {
51
48
  }
52
- /** Runs that still owe work, including those waiting for approval or a Worker. */
49
+ /** The states of a Run that isn't closed. */
53
50
  export const Open = Schema.Union([Pending, Waiting, Queued, Running]);
54
- /** A Run's progress from creation through approval and execution to a recorded outcome. */
55
51
  export const RunState = Schema.Union([...Open.members, Succeeded, Failed, Canceled]);
56
- /** The states with no attempt started: what `supersede` and `revoke` accept. */
52
+ /** The states before any Attempt starts, accepted by `supersede` and `revoke`. */
57
53
  export const Unstarted = Schema.Union([Pending, Waiting, Queued]);
58
- /** The states an attempt can start from: the gate is passed or absent. */
54
+ /** The states from which an Attempt can start. */
59
55
  export const Startable = Schema.Union([Pending, Queued]);
60
56
  export const isOpen = Schema.is(Open);
61
57
  export const isUnstarted = Schema.is(Unstarted);
62
58
  export const isStartable = Schema.is(Startable);
63
- /** The operator actions permitted by a Run's lifecycle state. Command handlers still apply the typed transitions. */
59
+ /** Returns the operator actions allowed in `state`. */
64
60
  export const operatorActions = (state) => ({
65
61
  canApprove: state._tag === "Waiting",
66
62
  canRetry: state._tag === "Failed",
63
+ canResolveFailure: state._tag === "Failed",
67
64
  canCancel: isOpen(state),
65
+ canRunAgain: state._tag === "Succeeded" || state._tag === "Canceled",
68
66
  });
69
- /**
70
- * Builds a tag tuple that must name every `_tag` of `State` and nothing else,
71
- * so the SQL-side lists below cannot drift from the unions above. A foreign tag
72
- * fails the `Tags` constraint; a missing tag collapses the parameters to `[never]`.
73
- */
67
+ /** Returns its arguments, which must be exactly the `_tag` values of `State`; a missing or extra tag is a type error. */
74
68
  const tagsOf = () => (...tags) => tags;
75
- /** The open states as `_tag` literals, for queries that filter stored rows. */
69
+ /** The `_tag` values of `Open`, for SQL filters. */
76
70
  export const OPEN_STATE_TAGS = tagsOf()("Pending", "Waiting", "Queued", "Running");
77
- /** Every state as a `_tag` literal, for read models that project stored rows. */
71
+ /** The `_tag` values of `RunState`. */
78
72
  export const STATE_TAGS = tagsOf()("Pending", "Waiting", "Queued", "Running", "Succeeded", "Failed", "Canceled");
79
- /** The unstarted states as `_tag` literals, for queries that filter stored rows. */
73
+ /** The `_tag` values of `Unstarted`, for SQL filters. */
80
74
  export const UNSTARTED_STATE_TAGS = tagsOf()("Pending", "Waiting", "Queued");
81
- /** Parks a pending run on its loop's approval gate. */
82
75
  export const awaitApproval = (_state) => new Waiting();
83
- /** Returns the approved state; the Run still waits for a Worker slot before execution. */
84
76
  export const approve = (_state) => new Queued();
85
- /** Returns the running state for a first Attempt after any required approval has been granted. */
86
77
  export const start = (_state) => new Running();
87
- /** Closes the run after a successful attempt. */
88
78
  export const succeed = (_state) => new Succeeded();
89
- /** Closes the run after a failed attempt when no auto-retry applies; `shouldAutoRetry` decides that. */
79
+ /** Returns `Failed`. Callers use it only if `shouldAutoRetry` returns `false`. */
90
80
  export const fail = (_state) => new Failed();
91
- /** Returns the reopened state for operator retry; attempt N+1 belongs to the same Run and Step. */
92
81
  export const retry = (_state) => new Running();
93
- /** Cancels from any open state. */
94
82
  export const cancelByOperator = (_state) => new Canceled({ reason: new OperatorCanceled() });
95
83
  /**
96
- * Cancels an unstarted run because a newer Event for the same Item replaced it.
97
- * A running attempt always finishes and the newer state is judged when it ends (ADR 0007).
84
+ * Returns `Canceled` for a Run replaced by the newer Event `by`. A running Run isn't
85
+ * superseded; the engine evaluates the newer Event after its Attempt ends (ADR 0007).
98
86
  */
99
87
  export const supersede = (_state, by) => new Canceled({ reason: new Superseded({ by }) });
100
- /** Cancels an unstarted run because its Item stopped matching the loop's trigger. */
101
88
  export const revoke = (_state) => new Canceled({ reason: new Revoked() });
102
89
  //# sourceMappingURL=state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/run/state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/run/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AAEH,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,CACtD,+BAA+B,CAChC,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAAG;AAE5B,+FAA+F;AAC/F,MAAM,OAAO,UAAW,SAAQ,MAAM,CAAC,WAAW,CAAa,yBAAyB,CAAC,CACvF,YAAY,EACZ,EAAE,EAAE,EAAE,OAAO,EAAE,CAChB;CAAG;AAEJ,oGAAoG;AACpG,MAAM,OAAO,OAAQ,SAAQ,MAAM,CAAC,WAAW,CAAU,sBAAsB,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;CAAG;AAElG,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AAGlF,qEAAqE;AACrE,MAAM,OAAO,OAAQ,SAAQ,MAAM,CAAC,WAAW,CAAU,kBAAkB,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;CAAG;AAE9F,mDAAmD;AACnD,MAAM,OAAO,OAAQ,SAAQ,MAAM,CAAC,WAAW,CAAU,kBAAkB,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;CAAG;AAE9F,iDAAiD;AACjD,MAAM,OAAO,MAAO,SAAQ,MAAM,CAAC,WAAW,CAAS,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;CAAG;AAE1F,iDAAiD;AACjD,MAAM,OAAO,OAAQ,SAAQ,MAAM,CAAC,WAAW,CAAU,kBAAkB,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;CAAG;AAE9F,sDAAsD;AACtD,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,WAAW,CAAY,oBAAoB,CAAC,CAChF,WAAW,EACX,EAAE,CACH;CAAG;AAEJ,mGAAmG;AACnG,MAAM,OAAO,MAAO,SAAQ,MAAM,CAAC,WAAW,CAAS,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;CAAG;AAE1F,MAAM,OAAO,QAAS,SAAQ,MAAM,CAAC,WAAW,CAAW,mBAAmB,CAAC,CAAC,UAAU,EAAE;IAC1F,MAAM,EAAE,YAAY;CACrB,CAAC;CAAG;AAEL,6CAA6C;AAC7C,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAGtE,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAGrF,kFAAkF;AAClF,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAGlE,kDAAkD;AAClD,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAGzD,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;AAEhD,uDAAuD;AACvD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAe,EAAE,EAAE,CAAC,CAAC;IACnD,UAAU,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS;IACpC,QAAQ,EAAE,KAAK,CAAC,IAAI,KAAK,QAAQ;IACjC,iBAAiB,EAAE,KAAK,CAAC,IAAI,KAAK,QAAQ;IAC1C,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;IACxB,WAAW,EAAE,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;CACrE,CAAC,CAAC;AAEH,yHAAyH;AACzH,MAAM,MAAM,GACV,GAA2B,EAAE,CAC7B,CACE,GAAG,IAA6D,EAChE,EAAE,CACF,IAAI,CAAC;AAET,oDAAoD;AACpD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,EAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAEzF,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,EAAY,CAC1C,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,QAAQ,EACR,UAAU,CACX,CAAC;AAEF,yDAAyD;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,EAAa,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAExF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAe,EAAW,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;AAEzE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAe,EAAU,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC;AAEjE,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,MAAiB,EAAW,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;AAEnE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAe,EAAa,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;AAEvE,kFAAkF;AAClF,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,MAAe,EAAU,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC;AAE9D,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,MAAc,EAAW,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;AAEhE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAY,EAAY,EAAE,CACzD,IAAI,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,gBAAgB,EAAE,EAAE,CAAC,CAAC;AAEnD;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAiB,EAAE,EAAW,EAAY,EAAE,CACpE,IAAI,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;AAEnD,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAiB,EAAY,EAAE,CAAC,IAAI,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { AttemptWindows } from "../attempt/attempt.ts";
3
+ import type { RunSpec } from "../attempt/channel.ts";
4
+ import { Comment, Commit, PullRequest } from "./result.ts";
5
+ /** The fields of `RunSpec` that harvesting reads. */
6
+ export type HarvestSpec = Pick<RunSpec, "attemptId" | "repository" | "revision" | "baseCommit" | "payload" | "preparedAt" | "botLogin" | "agent">;
7
+ /**
8
+ * An effect that reads the harvested Attempt's `AttemptWindows`. Harvesting runs it after
9
+ * GitHub lists the comments, so the result includes Attempts that started during the harvest.
10
+ */
11
+ export type AttemptWindowsRead<W> = Effect.Effect<AttemptWindows, W>;
12
+ /**
13
+ * A function that runs a read-only `git` or `gh` command in the checkout and returns its
14
+ * stdout lines. Fails with `E` on a non-zero exit.
15
+ */
16
+ export type HarvestCommand<E> = (command: "git" | "gh", args: ReadonlyArray<string>) => Effect.Effect<ReadonlyArray<string>, E>;
17
+ declare const HarvestError_base: Schema.Class<HarvestError, Schema.TaggedStruct<"HarvestError", {
18
+ readonly stage: Schema.Literals<readonly ["git", "github", "windows"]>;
19
+ readonly message: Schema.NonEmptyString;
20
+ readonly cause: Schema.Defect;
21
+ }>, import("effect/Cause").YieldableError>;
22
+ /** An error for invalid `git` or GitHub output, or for Attempt windows that can't be read. */
23
+ export declare class HarvestError extends HarvestError_base {
24
+ }
25
+ /**
26
+ * Returns the facts from a finished Attempt's checkout: new commits, the pull requests at the
27
+ * final commit, and the comments and reviews attributed to the Attempt. A GitHub failure or
28
+ * 10-second timeout drops only the GitHub facts. Fails with `HarvestError` if git output is
29
+ * invalid or the windows can't be read.
30
+ */
31
+ export declare const harvestFacts: <E extends {
32
+ readonly _tag: string;
33
+ readonly message: string;
34
+ }, W>(spec: HarvestSpec, run: HarvestCommand<E>, windows: AttemptWindowsRead<W>) => Effect.Effect<readonly (Comment | Commit | PullRequest)[], E | HarvestError, never>;
35
+ /**
36
+ * Returns the comments and reviews that an unsuccessful Attempt posted on the Run's Item,
37
+ * attributed as in `harvestFacts`. Never fails; on any error, returns an empty list.
38
+ */
39
+ export declare const harvestPostedComments: <E extends {
40
+ readonly _tag: string;
41
+ readonly message: string;
42
+ }, W>(spec: HarvestSpec, run: HarvestCommand<E>, windows: AttemptWindowsRead<W>) => Effect.Effect<readonly Comment[], never, never>;
43
+ export {};
44
+ //# sourceMappingURL=harvest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harvest.d.ts","sourceRoot":"","sources":["../../src/step/harvest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,EAAsB,cAAc,EAAe,MAAM,uBAAuB,CAAC;AACxF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,OAAO,EAAE,OAAO,EAAoB,MAAM,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAC;AAElG,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,IAAI,CAC5B,OAAO,EACL,WAAW,GACX,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,UAAU,GACV,OAAO,CACV,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,CAC9B,OAAO,EAAE,KAAK,GAAG,IAAI,EACrB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KACxB,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;;;;;;AAE7C,8FAA8F;AAC9F,qBAAa,YAAa,SAAQ,iBAOjC;CAAG;AAohBJ;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GACvB,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC7D,CAAC,mKAUD,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC7D,CAAC,+HAUD,CAAC"}
@@ -0,0 +1,368 @@
1
+ import { DateTime, Effect, Option, Schema } from "effect";
2
+ import { githubSignature } from "../agent/agent.js";
3
+ import { AttemptWindows, windowHolds } from "../attempt/attempt.js";
4
+ import { ItemNumber } from "../item.js";
5
+ import { CommitSha, RepositoryRevision } from "../repository.js";
6
+ import { Comment, Commit, PullRequest } from "./result.js";
7
+ /** An error for invalid `git` or GitHub output, or for Attempt windows that can't be read. */
8
+ export class HarvestError extends Schema.TaggedError("@usine/core/HarvestError")("HarvestError", {
9
+ stage: Schema.Literals(["git", "github", "windows"]),
10
+ message: Schema.NonEmptyString,
11
+ cause: Schema.Defect(),
12
+ }) {
13
+ }
14
+ const PullRequestResponse = Schema.Struct({
15
+ number: PullRequest.fields.number,
16
+ url: Schema.URLFromString,
17
+ head: Schema.Struct({ sha: CommitSha }),
18
+ }).pipe(Schema.encodeKeys({ url: "html_url" }));
19
+ const decodePullRequestPages = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Array(Schema.Array(PullRequestResponse))));
20
+ const decodeCommit = Schema.decodeUnknownEffect(CommitSha);
21
+ /** Decodes the Item `number` and `url` from a payload. Returns `None` for a schedule payload. */
22
+ const decodePayloadItem = Schema.decodeUnknownOption(Schema.Struct({ number: ItemNumber, url: Schema.URLFromString }));
23
+ /** The GraphQL query for the credential's login, used only if the `RunSpec` has no bot login. */
24
+ const VIEWER_QUERY = "query=query { viewer { login } }";
25
+ const decodeViewer = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Struct({
26
+ data: Schema.Struct({ viewer: Schema.Struct({ login: Schema.NonEmptyString }) }),
27
+ })));
28
+ const Author = Schema.NullOr(Schema.Struct({ login: Schema.String }));
29
+ // GitHub's schema has an optional body for issue comments and a required body for reviews and
30
+ // review comments; a review without text has an empty body.
31
+ const IssueCommentResponse = Schema.Struct({
32
+ url: Schema.URLFromString,
33
+ user: Author,
34
+ body: Schema.optionalKey(Schema.String),
35
+ createdAt: Schema.DateTimeUtcFromString,
36
+ updatedAt: Schema.DateTimeUtcFromString,
37
+ }).pipe(Schema.encodeKeys({ url: "html_url", createdAt: "created_at", updatedAt: "updated_at" }));
38
+ const decodeIssueCommentPages = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Array(Schema.Array(IssueCommentResponse))));
39
+ const ReviewResponse = Schema.Struct({
40
+ id: Schema.Int,
41
+ url: Schema.URLFromString,
42
+ user: Author,
43
+ body: Schema.String,
44
+ state: Schema.String,
45
+ submittedAt: Schema.optionalKey(Schema.NullOr(Schema.DateTimeUtcFromString)),
46
+ }).pipe(Schema.encodeKeys({ url: "html_url", submittedAt: "submitted_at" }));
47
+ const decodeReviewPages = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Array(Schema.Array(ReviewResponse))));
48
+ const ReviewCommentResponse = Schema.Struct({
49
+ url: Schema.URLFromString,
50
+ user: Author,
51
+ body: Schema.String,
52
+ createdAt: Schema.DateTimeUtcFromString,
53
+ updatedAt: Schema.DateTimeUtcFromString,
54
+ reviewId: Schema.NullOr(Schema.Int),
55
+ }).pipe(Schema.encodeKeys({
56
+ url: "html_url",
57
+ createdAt: "created_at",
58
+ updatedAt: "updated_at",
59
+ reviewId: "pull_request_review_id",
60
+ }));
61
+ const decodeReviewCommentPages = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Array(Schema.Array(ReviewCommentResponse))));
62
+ /** Runs a `gh` command and decodes its output. Fails with a `github` `HarvestError` if the output is invalid. */
63
+ const askGitHub = (run, args, decode, what) => run("gh", args).pipe(Effect.flatMap((lines) => decode(lines.join("\n")).pipe(Effect.mapError((cause) => new HarvestError({
64
+ stage: "github",
65
+ message: `GitHub returned invalid ${what}`,
66
+ cause,
67
+ })))));
68
+ /** Returns the commits from the checkout's base to its final HEAD, oldest first. */
69
+ const harvestCommits = Effect.fn("StepResult.harvestCommits")(function* (spec, run) {
70
+ yield* Effect.annotateCurrentSpan({ attemptId: spec.attemptId, repository: spec.repository });
71
+ // The first space ends the commit ID.
72
+ const lines = yield* run("git", [
73
+ "log",
74
+ "--reverse",
75
+ "--format=%H %s",
76
+ `${spec.baseCommit}..HEAD`,
77
+ ]);
78
+ return yield* Effect.forEach(lines, (line) => Effect.gen(function* () {
79
+ const separator = line.indexOf(" ");
80
+ const sha = yield* decodeCommit(separator < 0 ? line : line.slice(0, separator)).pipe(Effect.mapError((cause) => new HarvestError({ stage: "git", message: "Git returned an invalid commit ID", cause })));
81
+ const summary = separator < 0 ? "" : line.slice(separator + 1).trim();
82
+ if (summary.length === 0) {
83
+ return yield* new HarvestError({
84
+ stage: "git",
85
+ message: `Commit ${sha} has no summary`,
86
+ cause: new Error("empty commit summary"),
87
+ });
88
+ }
89
+ return new Commit({ sha, summary });
90
+ }));
91
+ });
92
+ /** Returns the pull requests whose head is the checkout's final commit, without duplicates. */
93
+ const harvestPullRequests = Effect.fn("StepResult.harvestPullRequests")(function* (spec, run) {
94
+ yield* Effect.annotateCurrentSpan({ attemptId: spec.attemptId, repository: spec.repository });
95
+ const head = yield* decodeCommit((yield* run("git", ["rev-parse", "HEAD"])).join("")).pipe(Effect.mapError((cause) => new HarvestError({ stage: "git", message: "Git returned an invalid final HEAD", cause })));
96
+ const branch = (yield* run("git", ["branch", "--show-current"])).join("");
97
+ // Checkouts start detached. There's no candidate if HEAD is unchanged, no branch was created,
98
+ // and the revision isn't a fixed commit.
99
+ if (head === spec.baseCommit &&
100
+ spec.revision !== RepositoryRevision.make(spec.baseCommit) &&
101
+ branch === "") {
102
+ yield* Effect.logDebug("No pull request candidate in the Attempt checkout", {
103
+ attemptId: spec.attemptId,
104
+ });
105
+ return [];
106
+ }
107
+ // GitHub returns HTTP 422 for a commit that was never pushed, so first check that a branch or
108
+ // `refs/pull/<n>/head` points at it.
109
+ if (head !== spec.baseCommit) {
110
+ const refs = yield* run("git", ["ls-remote", "origin", "refs/heads/*", "refs/pull/*/head"]);
111
+ if (!refs.some((ref) => ref.startsWith(`${head}\t`))) {
112
+ yield* Effect.logDebug("No remote branch or pull request has the Attempt's final commit", {
113
+ attemptId: spec.attemptId,
114
+ head,
115
+ });
116
+ return [];
117
+ }
118
+ }
119
+ const pages = yield* askGitHub(run, ["api", `repos/${spec.repository}/commits/${head}/pulls?per_page=100`, "--paginate", "--slurp"], decodePullRequestPages, "pull request results");
120
+ // The response also has pull requests that contain the commit as an ancestor.
121
+ const facts = new Map();
122
+ for (const pr of pages.flat()) {
123
+ if (pr.head.sha === head)
124
+ facts.set(pr.number, new PullRequest({ number: pr.number, url: pr.url }));
125
+ }
126
+ yield* Effect.logInfo("Collected Attempt pull request results", {
127
+ attemptId: spec.attemptId,
128
+ head,
129
+ pullRequests: [...facts.keys()],
130
+ });
131
+ return [...facts.values()];
132
+ });
133
+ /** Returns the login of the Attempt's credential, as reported by GitHub. */
134
+ const credentialLogin = Effect.fn("StepResult.credentialLogin")(function* (spec, item, run) {
135
+ yield* Effect.logInfo("The RunSpec names no bot login, so harvesting asks GitHub for the login of the Attempt's credential", { attemptId: spec.attemptId, repository: spec.repository, item });
136
+ const { data } = yield* askGitHub(run, ["api", "graphql", "-f", VIEWER_QUERY], decodeViewer, "the credential's login");
137
+ return { login: data.viewer.login, source: "viewer" };
138
+ });
139
+ /**
140
+ * Lists the comments, and for a pull request the submitted reviews and diff comments, that the
141
+ * bot login posted on the Run's Item since preparation. Returns `None` if the Run has no Item
142
+ * or no preparation time.
143
+ */
144
+ const listComments = Effect.fn("StepResult.listComments")(function* (spec, run) {
145
+ yield* Effect.annotateCurrentSpan({ attemptId: spec.attemptId, repository: spec.repository });
146
+ const item = decodePayloadItem(spec.payload);
147
+ if (Option.isNone(item)) {
148
+ yield* Effect.logDebug("The Run has no GitHub Item, so no comment is collected", {
149
+ attemptId: spec.attemptId,
150
+ });
151
+ return Option.none();
152
+ }
153
+ const { number, url } = item.value;
154
+ if (Option.isNone(spec.preparedAt)) {
155
+ yield* Effect.logInfo("The Attempt was prepared before preparation times were recorded, so no comment is collected", { attemptId: spec.attemptId, repository: spec.repository, item: number });
156
+ return Option.none();
157
+ }
158
+ // GitHub records times to the second, and `since` takes YYYY-MM-DDTHH:MM:SSZ.
159
+ const prepared = DateTime.toEpochMillis(spec.preparedAt.value);
160
+ const since = prepared - (prepared % 1_000);
161
+ const sinceParameter = `${DateTime.formatIso(DateTime.makeUnsafe(since)).slice(0, 19)}Z`;
162
+ const author = Option.isSome(spec.botLogin)
163
+ ? { login: spec.botLogin.value, source: "run-spec" }
164
+ : yield* credentialLogin(spec, number, run);
165
+ const { login } = author;
166
+ yield* Effect.annotateCurrentSpan({
167
+ item: number,
168
+ author: login,
169
+ authorSource: author.source,
170
+ agent: spec.agent.name,
171
+ });
172
+ const list = (path) => [
173
+ "api",
174
+ `repos/${spec.repository}/${path}`,
175
+ "--paginate",
176
+ "--slurp",
177
+ ];
178
+ // GitHub's pull request URLs are /<owner>/<repo>/pull/<number>; an issue's use `issues`.
179
+ const pullRequest = url.pathname.split("/")[3] === "pull";
180
+ const [conversation, reviews, diffComments] = yield* Effect.all([
181
+ askGitHub(run, list(`issues/${number}/comments?since=${sinceParameter}&per_page=100`), decodeIssueCommentPages, "issue comments"),
182
+ pullRequest
183
+ ? askGitHub(run, list(`pulls/${number}/reviews?per_page=100`), decodeReviewPages, "pull request reviews")
184
+ : Effect.succeed([]),
185
+ pullRequest
186
+ ? askGitHub(run, list(`pulls/${number}/comments?since=${sinceParameter}&per_page=100`), decodeReviewCommentPages, "review comments")
187
+ : Effect.succeed([]),
188
+ ], { concurrency: "unbounded" });
189
+ const byLogin = (user) => user !== null && user.login === login;
190
+ const sincePrepared = (at) => DateTime.toEpochMillis(at) >= since;
191
+ // A pending review and its comments are a draft visible only to its author.
192
+ const pending = new Set(reviews.flat().flatMap(({ id, state }) => (state === "PENDING" ? [id] : [])));
193
+ // A comment's post time is its creation time and a review's is its submission time. The
194
+ // reviews endpoint ignores `since`, so reviews are filtered by submission time.
195
+ const written = [
196
+ ...conversation.flat().flatMap(({ url, user, body, createdAt }) => byLogin(user)
197
+ ? [
198
+ {
199
+ body,
200
+ at: createdAt,
201
+ fact: new Comment({ url, kind: "issue-comment", at: Option.some(createdAt) }),
202
+ },
203
+ ]
204
+ : []),
205
+ ...reviews.flat().flatMap(({ url, user, body, state, submittedAt }) => state !== "PENDING" &&
206
+ submittedAt !== undefined &&
207
+ submittedAt !== null &&
208
+ byLogin(user) &&
209
+ sincePrepared(submittedAt)
210
+ ? [
211
+ {
212
+ body,
213
+ at: submittedAt,
214
+ fact: new Comment({ url, kind: "review", at: Option.some(submittedAt) }),
215
+ },
216
+ ]
217
+ : []),
218
+ ...diffComments.flat().flatMap(({ url, user, body, createdAt, reviewId }) => (reviewId === null || !pending.has(reviewId)) && byLogin(user)
219
+ ? [
220
+ {
221
+ body,
222
+ at: createdAt,
223
+ fact: new Comment({ url, kind: "review-comment", at: Option.some(createdAt) }),
224
+ },
225
+ ]
226
+ : []),
227
+ ];
228
+ // `since` filters by update time, so it also returns comments created before preparation and
229
+ // edited later; those are dropped (#429).
230
+ const posted = written.filter(({ at }) => sincePrepared(at));
231
+ // Attempts that write as the same bot login are distinguished by the Agent's signature
232
+ // (ADR 0006, #394). Trailing whitespace is ignored.
233
+ const signature = githubSignature(spec.agent.name);
234
+ const signed = posted.filter(({ body }) => body !== undefined && body.trimEnd().endsWith(signature));
235
+ return Option.some({
236
+ item: number,
237
+ author,
238
+ since: sinceParameter,
239
+ signed,
240
+ unsigned: posted.length - signed.length,
241
+ edited: written.length - posted.length,
242
+ });
243
+ });
244
+ /** Formats `window` as an ISO interval for logs, with the end `open` while running. Returns `unrecorded` for `None`. */
245
+ const describeWindow = (window) => Option.match(window, {
246
+ onNone: () => "unrecorded",
247
+ onSome: ({ startedAt, endedAt }) => {
248
+ const end = Option.match(endedAt, { onNone: () => "open", onSome: DateTime.formatIso });
249
+ return `${DateTime.formatIso(startedAt)}/${end}`;
250
+ },
251
+ });
252
+ /**
253
+ * Returns the signed comments in `listing` that are inside the Attempt's own window and outside
254
+ * the overlapping windows (#429). Reads `windows` only if a comment is signed. Fails with a
255
+ * `windows` `HarvestError` if the read fails.
256
+ */
257
+ const attributeComments = Effect.fn("StepResult.attributeComments")(function* (spec, listing, windows) {
258
+ yield* Effect.annotateCurrentSpan({
259
+ attemptId: spec.attemptId,
260
+ repository: spec.repository,
261
+ item: listing.item,
262
+ });
263
+ // Read after the listing so the result includes every Attempt that could have posted a comment.
264
+ const { own, overlapping } = listing.signed.length === 0
265
+ ? new AttemptWindows({ own: Option.none(), overlapping: [] })
266
+ : yield* windows.pipe(Effect.mapError((cause) => new HarvestError({
267
+ stage: "windows",
268
+ message: "Can't read the windows of this attempt and of the agent's other attempts on the item",
269
+ cause,
270
+ })));
271
+ const placed = listing.signed.map(({ at, fact }) => ({
272
+ at,
273
+ fact,
274
+ inside: Option.exists(own, (window) => windowHolds(window, at)),
275
+ others: overlapping.filter((window) => windowHolds(window, at)),
276
+ }));
277
+ const outside = placed.filter(({ inside }) => !inside);
278
+ const ambiguous = placed.filter(({ inside, others }) => inside && others.length > 0);
279
+ const posted = placed.flatMap(({ inside, others, fact }) => inside && others.length === 0 ? [fact] : []);
280
+ yield* Effect.forEach(outside, ({ at, fact }) => Effect.logInfo("Left out a comment posted outside the Attempt's own window on the Item", {
281
+ attemptId: spec.attemptId,
282
+ window: describeWindow(own),
283
+ postedAt: DateTime.formatIso(at),
284
+ comment: fact.url.href,
285
+ kind: fact.kind,
286
+ }), { discard: true });
287
+ yield* Effect.forEach(ambiguous, ({ fact, others }) => Effect.logInfo("Left out a comment that another open Attempt of the Agent on the Item could have posted", {
288
+ attemptId: spec.attemptId,
289
+ overlapping: others.map(({ attemptId }) => attemptId),
290
+ comment: fact.url.href,
291
+ kind: fact.kind,
292
+ }), { discard: true });
293
+ const counted = (kind) => posted.filter((comment) => comment.kind === kind).length;
294
+ yield* Effect.logInfo("Collected the comments and reviews the Attempt posted on its Item", {
295
+ attemptId: spec.attemptId,
296
+ repository: spec.repository,
297
+ item: listing.item,
298
+ author: listing.author.login,
299
+ authorSource: listing.author.source,
300
+ agent: spec.agent.name,
301
+ since: listing.since,
302
+ issueComments: counted("issue-comment"),
303
+ reviews: counted("review"),
304
+ reviewComments: counted("review-comment"),
305
+ // Posted since preparation without the Agent's signature.
306
+ unsigned: listing.unsigned,
307
+ // Posted before preparation and edited since.
308
+ edited: listing.edited,
309
+ // Signed, but posted outside the Attempt's own window, for example after a cancel.
310
+ outside: outside.length,
311
+ // Signed, but posted while another Attempt of the Agent was open on the Item.
312
+ ambiguous: ambiguous.length,
313
+ // Empty if no listed comment is signed.
314
+ overlapping: overlapping.map(({ attemptId }) => attemptId),
315
+ });
316
+ return posted;
317
+ });
318
+ /**
319
+ * Runs `discovery` with a 10-second timeout. If it fails or times out, logs a warning that ends
320
+ * with `retaining` and returns `nothing`.
321
+ */
322
+ const enrichment = (spec, subject, discovery, nothing, retaining = "retaining the completed agent result") => discovery.pipe(Effect.timeout("10 seconds"), Effect.catch((error) => Effect.logWarning(error._tag === "TimeoutError"
323
+ ? `${subject} discovery timed out; ${retaining}`
324
+ : `${subject} discovery failed; ${retaining}`, {
325
+ attemptId: spec.attemptId,
326
+ repository: spec.repository,
327
+ errorTag: error._tag,
328
+ message: error.message,
329
+ }).pipe(Effect.as(nothing))));
330
+ /**
331
+ * Returns the comments and reviews attributed to the Attempt. If GitHub discovery fails, returns
332
+ * an empty list. Fails with `HarvestError` if the windows can't be read.
333
+ */
334
+ const harvestComments = (spec, run, windows, retaining) => enrichment(spec, "Comment", listComments(spec, run), Option.none(), retaining).pipe(Effect.flatMap(Option.match({
335
+ onNone: () => Effect.succeed([]),
336
+ onSome: (listing) => attributeComments(spec, listing, windows),
337
+ })));
338
+ /** Logs a warning that the windows couldn't be read, ending with `outcome`. */
339
+ const windowsUnread = (spec, outcome) => (error) => Effect.logWarning(`Could not read the Attempt's window and those of the Agent's other Attempts on the Item, so the Attempt's comments cannot be told from theirs; ${outcome}`, {
340
+ attemptId: spec.attemptId,
341
+ repository: spec.repository,
342
+ cause: String(error.cause),
343
+ });
344
+ /**
345
+ * Returns the facts from a finished Attempt's checkout: new commits, the pull requests at the
346
+ * final commit, and the comments and reviews attributed to the Attempt. A GitHub failure or
347
+ * 10-second timeout drops only the GitHub facts. Fails with `HarvestError` if git output is
348
+ * invalid or the windows can't be read.
349
+ */
350
+ export const harvestFacts = Effect.fn("StepResult.harvest")(function* (spec, run, windows) {
351
+ yield* Effect.annotateCurrentSpan({ attemptId: spec.attemptId, repository: spec.repository });
352
+ const commits = yield* harvestCommits(spec, run);
353
+ const pullRequests = yield* enrichment(spec, "Pull request", harvestPullRequests(spec, run), []);
354
+ const comments = yield* harvestComments(spec, run, windows).pipe(Effect.tapError(windowsUnread(spec, "the harvest fails")));
355
+ const facts = [...commits, ...pullRequests, ...comments];
356
+ return facts;
357
+ });
358
+ /**
359
+ * Returns the comments and reviews that an unsuccessful Attempt posted on the Run's Item,
360
+ * attributed as in `harvestFacts`. Never fails; on any error, returns an empty list.
361
+ */
362
+ export const harvestPostedComments = Effect.fn("StepResult.harvestPostedComments")(function* (spec, run, windows) {
363
+ yield* Effect.annotateCurrentSpan({ attemptId: spec.attemptId, repository: spec.repository });
364
+ const outcome = "the Attempt that ended without success records no comment";
365
+ const comments = yield* harvestComments(spec, run, windows, outcome).pipe(Effect.catch((error) => windowsUnread(spec, outcome)(error).pipe(Effect.as([]))));
366
+ return comments;
367
+ });
368
+ //# sourceMappingURL=harvest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harvest.js","sourceRoot":"","sources":["../../src/step/harvest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAsB,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAExF,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAoB,MAAM,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAC;AA8BlG,8FAA8F;AAC9F,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,WAAW,CAAe,0BAA0B,CAAC,CAC5F,cAAc,EACd;IACE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;CACvB,CACF;CAAG;AAEJ,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM;IACjC,GAAG,EAAE,MAAM,CAAC,aAAa;IACzB,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;CACxC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;AAChD,MAAM,sBAAsB,GAAG,MAAM,CAAC,mBAAmB,CACvD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,CACvE,CAAC;AACF,MAAM,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;AAE3D,iGAAiG;AACjG,MAAM,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAClD,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CACjE,CAAC;AAEF,iGAAiG;AACjG,MAAM,YAAY,GAAG,kCAAkC,CAAC;AACxD,MAAM,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAC7C,MAAM,CAAC,cAAc,CACnB,MAAM,CAAC,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC;CACjF,CAAC,CACH,CACF,CAAC;AAEF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACtE,8FAA8F;AAC9F,4DAA4D;AAC5D,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC;IACzC,GAAG,EAAE,MAAM,CAAC,aAAa;IACzB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC,qBAAqB;IACvC,SAAS,EAAE,MAAM,CAAC,qBAAqB;CACxC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAClG,MAAM,uBAAuB,GAAG,MAAM,CAAC,mBAAmB,CACxD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CACxE,CAAC;AACF,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IACnC,EAAE,EAAE,MAAM,CAAC,GAAG;IACd,GAAG,EAAE,MAAM,CAAC,aAAa;IACzB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;CAC7E,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;AAC7E,MAAM,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAClD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAClE,CAAC;AACF,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,GAAG,EAAE,MAAM,CAAC,aAAa;IACzB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,SAAS,EAAE,MAAM,CAAC,qBAAqB;IACvC,SAAS,EAAE,MAAM,CAAC,qBAAqB;IACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;CACpC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,UAAU,CAAC;IAChB,GAAG,EAAE,UAAU;IACf,SAAS,EAAE,YAAY;IACvB,SAAS,EAAE,YAAY;IACvB,QAAQ,EAAE,wBAAwB;CACnC,CAAC,CACH,CAAC;AACF,MAAM,wBAAwB,GAAG,MAAM,CAAC,mBAAmB,CACzD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CACzE,CAAC;AAEF,iHAAiH;AACjH,MAAM,SAAS,GAAG,CAChB,GAAsB,EACtB,IAA2B,EAC3B,MAA+C,EAC/C,IAAY,EACZ,EAAE,CACF,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAClB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACvB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC3B,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,YAAY,CAAC;IACf,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,2BAA2B,IAAI,EAAE;IAC1C,KAAK;CACN,CAAC,CACL,CACF,CACF,CACF,CAAC;AAEJ,oFAAoF;AACpF,MAAM,cAAc,GAAG,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,CAAC,QAAQ,CAAC,EACrE,IAAiB,EACjB,GAAsB;IAEtB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9F,sCAAsC;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE;QAC9B,KAAK;QACL,WAAW;QACX,gBAAgB;QAChB,GAAG,IAAI,CAAC,UAAU,QAAQ;KAC3B,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CACnF,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,mCAAmC,EAAE,KAAK,EAAE,CAAC,CAC1F,CACF,CAAC;QACF,MAAM,OAAO,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC;gBAC7B,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,UAAU,GAAG,iBAAiB;gBACvC,KAAK,EAAE,IAAI,KAAK,CAAC,sBAAsB,CAAC;aACzC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,+FAA+F;AAC/F,MAAM,mBAAmB,GAAG,MAAM,CAAC,EAAE,CAAC,gCAAgC,CAAC,CAAC,QAAQ,CAAC,EAC/E,IAAiB,EACjB,GAAsB;IAEtB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9F,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CACxF,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,oCAAoC,EAAE,KAAK,EAAE,CAAC,CAC3F,CACF,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1E,8FAA8F;IAC9F,yCAAyC;IACzC,IACE,IAAI,KAAK,IAAI,CAAC,UAAU;QACxB,IAAI,CAAC,QAAQ,KAAK,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;QAC1D,MAAM,KAAK,EAAE,EACb,CAAC;QACD,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,mDAAmD,EAAE;YAC1E,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,8FAA8F;IAC9F,qCAAqC;IACrC,IAAI,IAAI,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC5F,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC;YACrD,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,iEAAiE,EAAE;gBACxF,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,IAAI;aACL,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,SAAS,CAC5B,GAAG,EACH,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,UAAU,YAAY,IAAI,qBAAqB,EAAE,YAAY,EAAE,SAAS,CAAC,EAC/F,sBAAsB,EACtB,sBAAsB,CACvB,CAAC;IACF,8EAA8E;IAC9E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI;YACtB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,wCAAwC,EAAE;QAC9D,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI;QACJ,YAAY,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;KAChC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAQH,4EAA4E;AAC5E,MAAM,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EACvE,IAAiB,EACjB,IAAgB,EAChB,GAAsB;IAEtB,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnB,qGAAqG,EACrG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CACjE,CAAC;IACF,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,SAAS,CAC/B,GAAG,EACH,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,CAAC,EACtC,YAAY,EACZ,wBAAwB,CACzB,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAmB,CAAC;AACzE,CAAC,CAAC,CAAC;AAwBH;;;;GAIG;AACH,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,QAAQ,CAAC,EACjE,IAAiB,EACjB,GAAsB;IAEtB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9F,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,wDAAwD,EAAE;YAC/E,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAW,CAAC;IAChC,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;IACnC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnB,6FAA6F,EAC7F,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,CACzE,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,EAAW,CAAC;IAChC,CAAC;IACD,8EAA8E;IAC9E,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,QAAQ,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;IACzF,MAAM,MAAM,GAAW,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;QACjD,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE;QACpD,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC;QAChC,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,KAAK;QACb,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;KACvB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC;QAC7B,KAAK;QACL,SAAS,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE;QAClC,YAAY;QACZ,SAAS;KACV,CAAC;IACF,yFAAyF;IACzF,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;IAC1D,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAC7D;QACE,SAAS,CACP,GAAG,EACH,IAAI,CAAC,UAAU,MAAM,mBAAmB,cAAc,eAAe,CAAC,EACtE,uBAAuB,EACvB,gBAAgB,CACjB;QACD,WAAW;YACT,CAAC,CAAC,SAAS,CACP,GAAG,EACH,IAAI,CAAC,SAAS,MAAM,uBAAuB,CAAC,EAC5C,iBAAiB,EACjB,sBAAsB,CACvB;YACH,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACtB,WAAW;YACT,CAAC,CAAC,SAAS,CACP,GAAG,EACH,IAAI,CAAC,SAAS,MAAM,mBAAmB,cAAc,eAAe,CAAC,EACrE,wBAAwB,EACxB,iBAAiB,CAClB;YACH,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;KACvB,EACD,EAAE,WAAW,EAAE,WAAW,EAAE,CAC7B,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,IAAwB,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;IACpF,MAAM,aAAa,GAAG,CAAC,EAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC;IAChF,4EAA4E;IAC5E,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC7E,CAAC;IACF,wFAAwF;IACxF,gFAAgF;IAChF,MAAM,OAAO,GAAG;QACd,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAChE,OAAO,CAAC,IAAI,CAAC;YACX,CAAC,CAAC;gBACE;oBACE,IAAI;oBACJ,EAAE,EAAE,SAAS;oBACb,IAAI,EAAE,IAAI,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;iBAC9E;aACF;YACH,CAAC,CAAC,EAAE,CACP;QACD,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CACpE,KAAK,KAAK,SAAS;YACnB,WAAW,KAAK,SAAS;YACzB,WAAW,KAAK,IAAI;YACpB,OAAO,CAAC,IAAI,CAAC;YACb,aAAa,CAAC,WAAW,CAAC;YACxB,CAAC,CAAC;gBACE;oBACE,IAAI;oBACJ,EAAE,EAAE,WAAW;oBACf,IAAI,EAAE,IAAI,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;iBACzE;aACF;YACH,CAAC,CAAC,EAAE,CACP;QACD,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,CAC1E,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;YAC5D,CAAC,CAAC;gBACE;oBACE,IAAI;oBACJ,EAAE,EAAE,SAAS;oBACb,IAAI,EAAE,IAAI,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;iBAC/E;aACF;YACH,CAAC,CAAC,EAAE,CACP;KACF,CAAC;IACF,6FAA6F;IAC7F,0CAA0C;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,uFAAuF;IACvF,oDAAoD;IACpD,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAC1B,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CACvE,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAU;QAC1B,IAAI,EAAE,MAAM;QACZ,MAAM;QACN,KAAK,EAAE,cAAc;QACrB,MAAM;QACN,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;QACvC,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;KACvC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,wHAAwH;AACxH,MAAM,cAAc,GAAG,CAAC,MAAoC,EAAE,EAAE,CAC9D,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE;IACnB,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY;IAC1B,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QACxF,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC;IACnD,CAAC;CACF,CAAC,CAAC;AAEL;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC,QAAQ,CAAC,EAC3E,IAAiB,EACjB,OAAgB,EAChB,OAA8B;IAE9B,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC;QAChC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAC;IACH,gGAAgG;IAChG,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC,IAAI,cAAc,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;QAC7D,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CACjB,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,YAAY,CAAC;YACf,KAAK,EAAE,SAAS;YAChB,OAAO,EACL,sFAAsF;YACxF,KAAK;SACN,CAAC,CACL,CACF,CAAC;IACR,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACnD,EAAE;QACF,IAAI;QACJ,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;KAChE,CAAC,CAAC,CAAC;IACJ,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CACzD,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAC5C,CAAC;IACF,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnB,OAAO,EACP,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CACf,MAAM,CAAC,OAAO,CAAC,wEAAwE,EAAE;QACvF,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC;QAC3B,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;QACtB,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,EACJ,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAC;IACF,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnB,SAAS,EACT,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CACnB,MAAM,CAAC,OAAO,CACZ,yFAAyF,EACzF;QACE,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC;QACrD,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;QACtB,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CACF,EACH,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,IAAiB,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;IAChG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,mEAAmE,EAAE;QACzF,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK;QAC5B,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;QACnC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,aAAa,EAAE,OAAO,CAAC,eAAe,CAAC;QACvC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC;QAC1B,cAAc,EAAE,OAAO,CAAC,gBAAgB,CAAC;QACzC,0DAA0D;QAC1D,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,8CAA8C;QAC9C,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,mFAAmF;QACnF,OAAO,EAAE,OAAO,CAAC,MAAM;QACvB,8EAA8E;QAC9E,SAAS,EAAE,SAAS,CAAC,MAAM;QAC3B,wCAAwC;QACxC,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC;KAC3D,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,GAAG,CACjB,IAAiB,EACjB,OAAmC,EACnC,SAA8B,EAC9B,OAAU,EACV,SAAS,GAAG,sCAAsC,EAClD,EAAE,CACF,SAAS,CAAC,IAAI,CACZ,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAC5B,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CACrB,MAAM,CAAC,UAAU,CACf,KAAK,CAAC,IAAI,KAAK,cAAc;IAC3B,CAAC,CAAC,GAAG,OAAO,yBAAyB,SAAS,EAAE;IAChD,CAAC,CAAC,GAAG,OAAO,sBAAsB,SAAS,EAAE,EAC/C;IACE,SAAS,EAAE,IAAI,CAAC,SAAS;IACzB,UAAU,EAAE,IAAI,CAAC,UAAU;IAC3B,QAAQ,EAAE,KAAK,CAAC,IAAI;IACpB,OAAO,EAAE,KAAK,CAAC,OAAO;CACvB,CACF,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAC3B,CACF,CAAC;AAEJ;;;GAGG;AACH,MAAM,eAAe,GAAG,CACtB,IAAiB,EACjB,GAAsB,EACtB,OAA8B,EAC9B,SAAkB,EAClB,EAAE,CACF,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,IAAI,EAAW,EAAE,SAAS,CAAC,CAAC,IAAI,CAC1F,MAAM,CAAC,OAAO,CACZ,MAAM,CAAC,KAAK,CAAC;IACX,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAyB,EAAE,CAAC;IACxD,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC;CAC/D,CAAC,CACH,CACF,CAAC;AAEJ,+EAA+E;AAC/E,MAAM,aAAa,GAAG,CAAC,IAAiB,EAAE,OAAe,EAAE,EAAE,CAAC,CAAC,KAAmB,EAAE,EAAE,CACpF,MAAM,CAAC,UAAU,CACf,kJAAkJ,OAAO,EAAE,EAC3J;IACE,SAAS,EAAE,IAAI,CAAC,SAAS;IACzB,UAAU,EAAE,IAAI,CAAC,UAAU;IAC3B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;CAC3B,CACF,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,EAGnE,IAAiB,EAAE,GAAsB,EAAE,OAA8B;IACzE,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACjG,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,CAC9D,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,CAC1D,CAAC;IACF,MAAM,KAAK,GAAkC,CAAC,GAAG,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,QAAQ,CAAC,CAAC;IACxF,OAAO,KAAK,CAAC;AACf,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,EAAE,CAAC,kCAAkC,CAAC,CAAC,QAAQ,CAAC,EAG1F,IAAiB,EAAE,GAAsB,EAAE,OAA8B;IACzE,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,2DAA2D,CAAC;IAC5E,MAAM,QAAQ,GAA2B,KAAK,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAC/F,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CACrB,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAyB,EAAE,CAAC,CAAC,CAChF,CACF,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC,CAAC"}