@yadsh/dsh-qa-surface 0.11.2 → 0.13.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 (85) hide show
  1. package/lib/access/service.js +2 -1
  2. package/lib/access/service.js.map +1 -1
  3. package/lib/admin/service.js +254 -52
  4. package/lib/admin/service.js.map +1 -1
  5. package/lib/client/QaAccountsController.js +19 -1
  6. package/lib/client/QaAccountsController.js.map +1 -1
  7. package/lib/client/QaSurface.js +9 -2
  8. package/lib/client/QaSurface.js.map +1 -1
  9. package/lib/client/admin/pages/Conversations.js +9 -2
  10. package/lib/client/admin/pages/Conversations.js.map +1 -1
  11. package/lib/client/admin/pages/Overview.js +1 -1
  12. package/lib/client/admin/pages/Overview.js.map +1 -1
  13. package/lib/client/admin/pages/Quality.js +1 -1
  14. package/lib/client/admin/pages/Quality.js.map +1 -1
  15. package/lib/client/admin/pages/Review.js +8 -4
  16. package/lib/client/admin/pages/Review.js.map +1 -1
  17. package/lib/client/admin/shared.js +42 -4
  18. package/lib/client/admin/shared.js.map +1 -1
  19. package/lib/client/components/QaChangelog.js +52 -9
  20. package/lib/client/components/QaChangelog.js.map +1 -1
  21. package/lib/client/components/QaSidebar.js +13 -15
  22. package/lib/client/components/QaSidebar.js.map +1 -1
  23. package/lib/client/index.js +18 -4
  24. package/lib/client/index.js.map +1 -1
  25. package/lib/client/markdown/MermaidBlock.js +80 -0
  26. package/lib/client/markdown/MermaidBlock.js.map +1 -0
  27. package/lib/client/markdown/render.js +4 -0
  28. package/lib/client/markdown/render.js.map +1 -1
  29. package/lib/client/rating-harvest.js +138 -0
  30. package/lib/client/rating-harvest.js.map +1 -0
  31. package/lib/client/settings/card.js +2 -2
  32. package/lib/client/settings/card.js.map +1 -1
  33. package/lib/client/settings/sections/docs.js +41 -0
  34. package/lib/client/settings/sections/docs.js.map +1 -0
  35. package/lib/client/settings/sections.js +1 -0
  36. package/lib/client/settings/sections.js.map +1 -1
  37. package/lib/client/styles.js +24 -2
  38. package/lib/client/styles.js.map +1 -1
  39. package/lib/client/types.js.map +1 -1
  40. package/lib/client.js +2526 -232
  41. package/lib/client.js.map +1 -1
  42. package/lib/config-resolvers/defaults.js +4 -0
  43. package/lib/config-resolvers/defaults.js.map +1 -1
  44. package/lib/config-resolvers/integration.js +7 -7
  45. package/lib/config-resolvers/integration.js.map +1 -1
  46. package/lib/config-resolvers/tools.js +25 -0
  47. package/lib/config-resolvers/tools.js.map +1 -1
  48. package/lib/config.js +15 -0
  49. package/lib/config.js.map +1 -1
  50. package/lib/index.js +32 -10
  51. package/lib/index.js.map +1 -1
  52. package/lib/provenance/extractors.js +1 -1
  53. package/lib/provenance/extractors.js.map +1 -1
  54. package/lib/provenance/host-store.js +5 -1
  55. package/lib/provenance/host-store.js.map +1 -1
  56. package/lib/qa-tools/catalog.js +13 -2
  57. package/lib/qa-tools/catalog.js.map +1 -1
  58. package/lib/qa-tools/docs-tools.js +329 -31
  59. package/lib/qa-tools/docs-tools.js.map +1 -1
  60. package/lib/qa-tools/index.js +1 -0
  61. package/lib/qa-tools/index.js.map +1 -1
  62. package/lib/secure-session.js +11 -13
  63. package/lib/secure-session.js.map +1 -1
  64. package/lib/shared/docs-version.js +19 -0
  65. package/lib/shared/docs-version.js.map +1 -0
  66. package/lib/typert.host.js +140 -73
  67. package/lib/typert.remote-client.d.ts +11 -9
  68. package/lib/typert.remote-client.js +119 -67
  69. package/lib/types/admin/service.d.ts +60 -9
  70. package/lib/types/client/QaAccountsController.d.ts +12 -1
  71. package/lib/types/client/admin/shared.d.ts +16 -1
  72. package/lib/types/client/markdown/MermaidBlock.d.ts +6 -0
  73. package/lib/types/client/rating-harvest.d.ts +49 -0
  74. package/lib/types/client/settings/sections/docs.d.ts +15 -0
  75. package/lib/types/client/settings/sections.d.ts +1 -0
  76. package/lib/types/client/types.d.ts +11 -4
  77. package/lib/types/config-resolvers/integration.d.ts +5 -5
  78. package/lib/types/config-resolvers/tools.d.ts +9 -0
  79. package/lib/types/index.d.ts +18 -6
  80. package/lib/types/qa-tools/catalog.d.ts +6 -1
  81. package/lib/types/qa-tools/docs-tools.d.ts +17 -2
  82. package/lib/types/qa-tools/index.d.ts +6 -1
  83. package/lib/types/shared/docs-version.d.ts +15 -0
  84. package/lib/types/types.d.ts +42 -0
  85. package/package.json +5 -4
package/lib/client.js CHANGED
@@ -4,6 +4,21 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ const require_src = require("./src-DYN0ucCI.cjs");
8
+ const require_chunk_Y2CYZVJY = require("./chunk-Y2CYZVJY-CKJMflD1.cjs");
9
+ const require_chunk_DU6HZSFF = require("./chunk-DU6HZSFF-DH5Rw2xo.cjs");
10
+ const require_chunk_75Z2AOVW = require("./chunk-75Z2AOVW-DloyPyHI.cjs");
11
+ const require_chunk_CLGD4ZFX = require("./chunk-CLGD4ZFX-Bvury_Vx.cjs");
12
+ require("./chunk-P2QGCYS3-CY9swMLN.cjs");
13
+ const require_chunk_PWAF6VOD = require("./chunk-PWAF6VOD-Di_8tji9.cjs");
14
+ const require_chunk_GMAD6QVW = require("./chunk-GMAD6QVW-LWv7apx8.cjs");
15
+ require("./chunk-4HAMMTFA-Zu1h-E11.cjs");
16
+ require("./chunk-GVQU2GXP-C4pqETtp.cjs");
17
+ require("./chunk-L3NEJ4N5-C_zR5ZWg.cjs");
18
+ require("./chunk-OSK3NFVY-BiIp85OT.cjs");
19
+ require("./chunk-2E4U76K2-BlQgyl-u.cjs");
20
+ const require_chunk_LNGE3PJU = require("./chunk-LNGE3PJU-Ihy6PCu-.cjs");
21
+ const require_chunk_TLUHSLCS = require("./chunk-TLUHSLCS-qlu0Jjmx.cjs");
7
22
  let react_jsx_runtime = require("react/jsx-runtime");
8
23
  let react = require("react");
9
24
  let react_dom = require("react-dom");
@@ -671,7 +686,7 @@ window.__ModuleLoader__.load({
671
686
  /** Get-or-create `obj[key]` as an own data property. A path segment naming an inherited member
672
687
  * ("toString", "constructor") would otherwise read through to the prototype, and assigning
673
688
  * "__proto__" would hit the setter instead of creating a key. */
674
- function node(obj, key, make) {
689
+ function node$1(obj, key, make) {
675
690
  if (!Object.prototype.hasOwnProperty.call(obj, key)) {
676
691
  if (key === "__proto__") Object.defineProperty(obj, key, {
677
692
  value: make(),
@@ -686,7 +701,7 @@ window.__ModuleLoader__.load({
686
701
  function flattenError(error, mapper = (issue) => issue.message) {
687
702
  const fieldErrors = {};
688
703
  const formErrors = [];
689
- for (const sub of error.issues) if (sub.path.length > 0) node(fieldErrors, sub.path[0], () => []).push(mapper(sub));
704
+ for (const sub of error.issues) if (sub.path.length > 0) node$1(fieldErrors, sub.path[0], () => []).push(mapper(sub));
690
705
  else formErrors.push(mapper(sub));
691
706
  return {
692
707
  formErrors,
@@ -2736,7 +2751,7 @@ window.__ModuleLoader__.load({
2736
2751
  }
2737
2752
  let handoff;
2738
2753
  const open$1 = [];
2739
- const memo$10 = {
2754
+ const memo$11 = {
2740
2755
  alloc(_inst, payload, empty) {
2741
2756
  const bucket = handoff;
2742
2757
  if (!bucket) return empty;
@@ -2827,7 +2842,7 @@ window.__ModuleLoader__.load({
2827
2842
  };
2828
2843
  /** The memoizer that gives containers cycle support. `zod` installs it by default; `zod/mini` opts in with `config({ memoizer: memoizer() })`. */
2829
2844
  function memoizer() {
2830
- return memo$10;
2845
+ return memo$11;
2831
2846
  }
2832
2847
  /** Whether this value is a node a back-edge resolved to before it finished. */
2833
2848
  function isBackEdge(ctx, value) {
@@ -4300,7 +4315,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4300
4315
  const ZodRealError = /*@__PURE__*/ $constructor("ZodError", initializer, void 0, { Parent: Error });
4301
4316
  //#endregion
4302
4317
  //#region ../../node_modules/.pnpm/zod@4.5.2/node_modules/zod/v4/classic/parse.js
4303
- const parse = /* @__PURE__ */ _parse(ZodRealError);
4318
+ const parse$2 = /* @__PURE__ */ _parse(ZodRealError);
4304
4319
  const parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
4305
4320
  const safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
4306
4321
  const safeParseAsync = /* @__PURE__ */ _safeParseAsync(ZodRealError);
@@ -4432,7 +4447,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4432
4447
  own(this, "~standard", value);
4433
4448
  },
4434
4449
  parse: function _parse(data, params) {
4435
- return parse(this, data, params, { callee: _parse });
4450
+ return parse$2(this, data, params, { callee: _parse });
4436
4451
  },
4437
4452
  parseAsync: async function _parseAsync(data, params) {
4438
4453
  return await parseAsync(this, data, params, { callee: _parseAsync });
@@ -6254,6 +6269,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6254
6269
  "nextCursor": union([literal(null), string()]).readonly(),
6255
6270
  "total": number().readonly()
6256
6271
  });
6272
+ const _yadsh_dsh_qa_surface_qaSurface_adminHarvestFeedback_parameter_0$schema = string();
6273
+ const _yadsh_dsh_qa_surface_qaSurface_adminHarvestFeedback_parameter_1$schema = array(object({
6274
+ "conversationId": string().readonly(),
6275
+ "messageId": string().readonly(),
6276
+ "rating": union([literal("positive"), literal("negative")]).readonly()
6277
+ }));
6278
+ const _yadsh_dsh_qa_surface_qaSurface_adminHarvestFeedback_result$schema = object({
6279
+ "recorded": number().readonly(),
6280
+ "present": number().readonly(),
6281
+ "rejected": number().readonly()
6282
+ });
6257
6283
  const _yadsh_dsh_qa_surface_qaSurface_adminMetrics_parameter_0$schema = string();
6258
6284
  const _yadsh_dsh_qa_surface_qaSurface_adminMetrics_result$schema = object({
6259
6285
  "conversations": number().readonly(),
@@ -7295,7 +7321,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7295
7321
  "activationSkill": string().readonly(),
7296
7322
  "activationMode": literal("all").readonly(),
7297
7323
  "activationPresets": array(string()).readonly(),
7298
- "docsRoot": string().readonly()
7324
+ "docsRoot": string().readonly(),
7325
+ "docsDefaultVersion": string().readonly(),
7326
+ "docsDefaultVersionEnabled": boolean().readonly()
7299
7327
  }).readonly(),
7300
7328
  "sources": object({
7301
7329
  "enabled": boolean().readonly(),
@@ -7971,7 +7999,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
7971
7999
  },
7972
8000
  sourceLocation: {
7973
8001
  "file": "packages/dsh-qa-surface/src/index.ts",
7974
- "line": 910,
8002
+ "line": 917,
7975
8003
  "column": 9
7976
8004
  }
7977
8005
  },
@@ -8007,7 +8035,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8007
8035
  },
8008
8036
  sourceLocation: {
8009
8037
  "file": "packages/dsh-qa-surface/src/index.ts",
8010
- "line": 921,
8038
+ "line": 928,
8011
8039
  "column": 3
8012
8040
  }
8013
8041
  },
@@ -8034,7 +8062,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8034
8062
  },
8035
8063
  sourceLocation: {
8036
8064
  "file": "packages/dsh-qa-surface/src/index.ts",
8037
- "line": 895,
8065
+ "line": 902,
8038
8066
  "column": 3
8039
8067
  }
8040
8068
  },
@@ -8083,7 +8111,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8083
8111
  },
8084
8112
  sourceLocation: {
8085
8113
  "file": "packages/dsh-qa-surface/src/index.ts",
8086
- "line": 935,
8114
+ "line": 942,
8087
8115
  "column": 3
8088
8116
  }
8089
8117
  },
@@ -8119,7 +8147,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8119
8147
  },
8120
8148
  sourceLocation: {
8121
8149
  "file": "packages/dsh-qa-surface/src/index.ts",
8122
- "line": 901,
8150
+ "line": 908,
8123
8151
  "column": 3
8124
8152
  }
8125
8153
  },
@@ -8155,7 +8183,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8155
8183
  },
8156
8184
  sourceLocation: {
8157
8185
  "file": "packages/dsh-qa-surface/src/index.ts",
8158
- "line": 980,
8186
+ "line": 987,
8159
8187
  "column": 3
8160
8188
  }
8161
8189
  },
@@ -8204,7 +8232,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8204
8232
  },
8205
8233
  sourceLocation: {
8206
8234
  "file": "packages/dsh-qa-surface/src/index.ts",
8207
- "line": 957,
8235
+ "line": 964,
8208
8236
  "column": 3
8209
8237
  }
8210
8238
  },
@@ -8240,7 +8268,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8240
8268
  },
8241
8269
  sourceLocation: {
8242
8270
  "file": "packages/dsh-qa-surface/src/index.ts",
8243
- "line": 947,
8271
+ "line": 954,
8244
8272
  "column": 3
8245
8273
  }
8246
8274
  },
@@ -8276,7 +8304,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8276
8304
  },
8277
8305
  sourceLocation: {
8278
8306
  "file": "packages/dsh-qa-surface/src/index.ts",
8279
- "line": 969,
8307
+ "line": 976,
8280
8308
  "column": 3
8281
8309
  }
8282
8310
  },
@@ -8325,7 +8353,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8325
8353
  },
8326
8354
  sourceLocation: {
8327
8355
  "file": "packages/dsh-qa-surface/src/index.ts",
8328
- "line": 928,
8356
+ "line": 935,
8329
8357
  "column": 3
8330
8358
  }
8331
8359
  },
@@ -8374,7 +8402,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8374
8402
  },
8375
8403
  sourceLocation: {
8376
8404
  "file": "packages/dsh-qa-surface/src/index.ts",
8377
- "line": 651,
8405
+ "line": 658,
8378
8406
  "column": 3
8379
8407
  }
8380
8408
  },
@@ -8410,7 +8438,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8410
8438
  },
8411
8439
  sourceLocation: {
8412
8440
  "file": "packages/dsh-qa-surface/src/index.ts",
8413
- "line": 685,
8441
+ "line": 692,
8414
8442
  "column": 3
8415
8443
  }
8416
8444
  },
@@ -8446,7 +8474,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8446
8474
  },
8447
8475
  sourceLocation: {
8448
8476
  "file": "packages/dsh-qa-surface/src/index.ts",
8449
- "line": 758,
8477
+ "line": 765,
8450
8478
  "column": 3
8451
8479
  }
8452
8480
  },
@@ -8473,7 +8501,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8473
8501
  },
8474
8502
  sourceLocation: {
8475
8503
  "file": "packages/dsh-qa-surface/src/index.ts",
8476
- "line": 706,
8504
+ "line": 713,
8477
8505
  "column": 3
8478
8506
  }
8479
8507
  },
@@ -8500,7 +8528,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8500
8528
  },
8501
8529
  sourceLocation: {
8502
8530
  "file": "packages/dsh-qa-surface/src/index.ts",
8503
- "line": 745,
8531
+ "line": 752,
8504
8532
  "column": 3
8505
8533
  }
8506
8534
  },
@@ -8536,7 +8564,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8536
8564
  },
8537
8565
  sourceLocation: {
8538
8566
  "file": "packages/dsh-qa-surface/src/index.ts",
8539
- "line": 645,
8567
+ "line": 652,
8540
8568
  "column": 3
8541
8569
  }
8542
8570
  },
@@ -8563,7 +8591,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8563
8591
  },
8564
8592
  sourceLocation: {
8565
8593
  "file": "packages/dsh-qa-surface/src/index.ts",
8566
- "line": 696,
8594
+ "line": 703,
8567
8595
  "column": 3
8568
8596
  }
8569
8597
  },
@@ -8599,7 +8627,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8599
8627
  },
8600
8628
  sourceLocation: {
8601
8629
  "file": "packages/dsh-qa-surface/src/index.ts",
8602
- "line": 640,
8630
+ "line": 647,
8603
8631
  "column": 3
8604
8632
  }
8605
8633
  },
@@ -8626,7 +8654,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8626
8654
  },
8627
8655
  sourceLocation: {
8628
8656
  "file": "packages/dsh-qa-surface/src/index.ts",
8629
- "line": 669,
8657
+ "line": 676,
8630
8658
  "column": 3
8631
8659
  }
8632
8660
  },
@@ -8662,7 +8690,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8662
8690
  },
8663
8691
  sourceLocation: {
8664
8692
  "file": "packages/dsh-qa-surface/src/index.ts",
8665
- "line": 771,
8693
+ "line": 778,
8666
8694
  "column": 3
8667
8695
  }
8668
8696
  },
@@ -8698,7 +8726,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8698
8726
  },
8699
8727
  sourceLocation: {
8700
8728
  "file": "packages/dsh-qa-surface/src/index.ts",
8701
- "line": 719,
8729
+ "line": 726,
8702
8730
  "column": 3
8703
8731
  }
8704
8732
  },
@@ -8734,7 +8762,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8734
8762
  },
8735
8763
  sourceLocation: {
8736
8764
  "file": "packages/dsh-qa-surface/src/index.ts",
8737
- "line": 732,
8765
+ "line": 739,
8738
8766
  "column": 3
8739
8767
  }
8740
8768
  },
@@ -8761,7 +8789,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8761
8789
  },
8762
8790
  sourceLocation: {
8763
8791
  "file": "packages/dsh-qa-surface/src/index.ts",
8764
- "line": 675,
8792
+ "line": 682,
8765
8793
  "column": 3
8766
8794
  }
8767
8795
  },
@@ -8820,7 +8848,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8820
8848
  },
8821
8849
  sourceLocation: {
8822
8850
  "file": "packages/dsh-qa-surface/src/index.ts",
8823
- "line": 1246,
8851
+ "line": 1286,
8824
8852
  "column": 3
8825
8853
  }
8826
8854
  },
@@ -8856,7 +8884,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8856
8884
  },
8857
8885
  sourceLocation: {
8858
8886
  "file": "packages/dsh-qa-surface/src/index.ts",
8859
- "line": 1148,
8887
+ "line": 1166,
8860
8888
  "column": 3
8861
8889
  }
8862
8890
  },
@@ -8908,6 +8936,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8908
8936
  }
8909
8937
  }
8910
8938
  ],
8939
+ cancellation: { parameter: "signal" },
8911
8940
  result: {
8912
8941
  mode: "strict",
8913
8942
  typeSymbol: "@yadsh/dsh-qa-surface/types#QaAdminPage",
@@ -8915,7 +8944,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8915
8944
  },
8916
8945
  sourceLocation: {
8917
8946
  "file": "packages/dsh-qa-surface/src/index.ts",
8918
- "line": 1130,
8947
+ "line": 1146,
8919
8948
  "column": 3
8920
8949
  }
8921
8950
  },
@@ -8951,7 +8980,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
8951
8980
  },
8952
8981
  sourceLocation: {
8953
8982
  "file": "packages/dsh-qa-surface/src/index.ts",
8954
- "line": 1163,
8983
+ "line": 1181,
8955
8984
  "column": 3
8956
8985
  }
8957
8986
  },
@@ -9010,7 +9039,43 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9010
9039
  },
9011
9040
  sourceLocation: {
9012
9041
  "file": "packages/dsh-qa-surface/src/index.ts",
9013
- "line": 1173,
9042
+ "line": 1191,
9043
+ "column": 3
9044
+ }
9045
+ },
9046
+ {
9047
+ id: "@yadsh/dsh-qa-surface#qaSurface/adminHarvestFeedback",
9048
+ service: "qaSurface",
9049
+ namespace: "qaSurface",
9050
+ method: "adminHarvestFeedback",
9051
+ invocation: { kind: "direct" },
9052
+ parameters: [{
9053
+ name: "token",
9054
+ wire: "token",
9055
+ source: "json",
9056
+ codec: {
9057
+ mode: "strict",
9058
+ typeSymbol: "@yadsh/dsh-qa-surface#qaSurface/adminHarvestFeedback:token",
9059
+ schema: _yadsh_dsh_qa_surface_qaSurface_adminHarvestFeedback_parameter_0$schema
9060
+ }
9061
+ }, {
9062
+ name: "entries",
9063
+ wire: "entries",
9064
+ source: "json",
9065
+ codec: {
9066
+ mode: "strict",
9067
+ typeSymbol: "@yadsh/dsh-qa-surface#qaSurface/adminHarvestFeedback:entries",
9068
+ schema: _yadsh_dsh_qa_surface_qaSurface_adminHarvestFeedback_parameter_1$schema
9069
+ }
9070
+ }],
9071
+ result: {
9072
+ mode: "strict",
9073
+ typeSymbol: "@yadsh/dsh-qa-surface/types#QaFeedbackHarvestResult",
9074
+ schema: _yadsh_dsh_qa_surface_qaSurface_adminHarvestFeedback_result$schema
9075
+ },
9076
+ sourceLocation: {
9077
+ "file": "packages/dsh-qa-surface/src/index.ts",
9078
+ "line": 1228,
9014
9079
  "column": 3
9015
9080
  }
9016
9081
  },
@@ -9030,6 +9095,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9030
9095
  schema: _yadsh_dsh_qa_surface_qaSurface_adminMetrics_parameter_0$schema
9031
9096
  }
9032
9097
  }],
9098
+ cancellation: { parameter: "signal" },
9033
9099
  result: {
9034
9100
  mode: "strict",
9035
9101
  typeSymbol: "@yadsh/dsh-qa-surface/types#QaQualityMetrics",
@@ -9037,7 +9103,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9037
9103
  },
9038
9104
  sourceLocation: {
9039
9105
  "file": "packages/dsh-qa-surface/src/index.ts",
9040
- "line": 1241,
9106
+ "line": 1279,
9041
9107
  "column": 3
9042
9108
  }
9043
9109
  },
@@ -9057,6 +9123,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9057
9123
  schema: _yadsh_dsh_qa_surface_qaSurface_adminOverview_parameter_0$schema
9058
9124
  }
9059
9125
  }],
9126
+ cancellation: { parameter: "signal" },
9060
9127
  result: {
9061
9128
  mode: "strict",
9062
9129
  typeSymbol: "@yadsh/dsh-qa-surface/types#QaAdminOverview",
@@ -9064,7 +9131,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9064
9131
  },
9065
9132
  sourceLocation: {
9066
9133
  "file": "packages/dsh-qa-surface/src/index.ts",
9067
- "line": 1076,
9134
+ "line": 1090,
9068
9135
  "column": 3
9069
9136
  }
9070
9137
  },
@@ -9091,7 +9158,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9091
9158
  },
9092
9159
  sourceLocation: {
9093
9160
  "file": "packages/dsh-qa-surface/src/index.ts",
9094
- "line": 1110,
9161
+ "line": 1126,
9095
9162
  "column": 3
9096
9163
  }
9097
9164
  },
@@ -9140,7 +9207,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9140
9207
  },
9141
9208
  sourceLocation: {
9142
9209
  "file": "packages/dsh-qa-surface/src/index.ts",
9143
- "line": 1218,
9210
+ "line": 1256,
9144
9211
  "column": 3
9145
9212
  }
9146
9213
  },
@@ -9199,7 +9266,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9199
9266
  },
9200
9267
  sourceLocation: {
9201
9268
  "file": "packages/dsh-qa-surface/src/index.ts",
9202
- "line": 1194,
9269
+ "line": 1212,
9203
9270
  "column": 3
9204
9271
  }
9205
9272
  },
@@ -9248,7 +9315,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9248
9315
  },
9249
9316
  sourceLocation: {
9250
9317
  "file": "packages/dsh-qa-surface/src/index.ts",
9251
- "line": 1119,
9318
+ "line": 1135,
9252
9319
  "column": 3
9253
9320
  }
9254
9321
  },
@@ -9290,6 +9357,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9290
9357
  }
9291
9358
  }
9292
9359
  ],
9360
+ cancellation: { parameter: "signal" },
9293
9361
  result: {
9294
9362
  mode: "strict",
9295
9363
  typeSymbol: "@yadsh/dsh-qa-surface/types#QaAdminPage",
@@ -9297,7 +9365,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9297
9365
  },
9298
9366
  sourceLocation: {
9299
9367
  "file": "packages/dsh-qa-surface/src/index.ts",
9300
- "line": 1206,
9368
+ "line": 1238,
9301
9369
  "column": 3
9302
9370
  }
9303
9371
  },
@@ -9333,7 +9401,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9333
9401
  },
9334
9402
  sourceLocation: {
9335
9403
  "file": "packages/dsh-qa-surface/src/index.ts",
9336
- "line": 1233,
9404
+ "line": 1271,
9337
9405
  "column": 3
9338
9406
  }
9339
9407
  },
@@ -9382,7 +9450,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9382
9450
  },
9383
9451
  sourceLocation: {
9384
9452
  "file": "packages/dsh-qa-surface/src/index.ts",
9385
- "line": 1010,
9453
+ "line": 1017,
9386
9454
  "column": 3
9387
9455
  }
9388
9456
  },
@@ -9441,7 +9509,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9441
9509
  },
9442
9510
  sourceLocation: {
9443
9511
  "file": "packages/dsh-qa-surface/src/index.ts",
9444
- "line": 1038,
9512
+ "line": 1045,
9445
9513
  "column": 3
9446
9514
  }
9447
9515
  },
@@ -9477,7 +9545,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9477
9545
  },
9478
9546
  sourceLocation: {
9479
9547
  "file": "packages/dsh-qa-surface/src/index.ts",
9480
- "line": 1001,
9548
+ "line": 1008,
9481
9549
  "column": 3
9482
9550
  }
9483
9551
  },
@@ -9536,7 +9604,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9536
9604
  },
9537
9605
  sourceLocation: {
9538
9606
  "file": "packages/dsh-qa-surface/src/index.ts",
9539
- "line": 1025,
9607
+ "line": 1032,
9540
9608
  "column": 3
9541
9609
  }
9542
9610
  },
@@ -9572,7 +9640,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9572
9640
  },
9573
9641
  sourceLocation: {
9574
9642
  "file": "packages/dsh-qa-surface/src/index.ts",
9575
- "line": 1064,
9643
+ "line": 1071,
9576
9644
  "column": 9
9577
9645
  }
9578
9646
  },
@@ -9631,7 +9699,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9631
9699
  },
9632
9700
  sourceLocation: {
9633
9701
  "file": "packages/dsh-qa-surface/src/index.ts",
9634
- "line": 1051,
9702
+ "line": 1058,
9635
9703
  "column": 3
9636
9704
  }
9637
9705
  },
@@ -9680,7 +9748,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9680
9748
  },
9681
9749
  sourceLocation: {
9682
9750
  "file": "packages/dsh-qa-surface/src/index.ts",
9683
- "line": 1099,
9751
+ "line": 1115,
9684
9752
  "column": 3
9685
9753
  }
9686
9754
  },
@@ -9716,7 +9784,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9716
9784
  },
9717
9785
  sourceLocation: {
9718
9786
  "file": "packages/dsh-qa-surface/src/index.ts",
9719
- "line": 1093,
9787
+ "line": 1109,
9720
9788
  "column": 3
9721
9789
  }
9722
9790
  },
@@ -9775,7 +9843,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9775
9843
  },
9776
9844
  sourceLocation: {
9777
9845
  "file": "packages/dsh-qa-surface/src/index.ts",
9778
- "line": 1081,
9846
+ "line": 1097,
9779
9847
  "column": 3
9780
9848
  }
9781
9849
  },
@@ -9834,7 +9902,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9834
9902
  },
9835
9903
  sourceLocation: {
9836
9904
  "file": "packages/dsh-qa-surface/src/index.ts",
9837
- "line": 1322,
9905
+ "line": 1362,
9838
9906
  "column": 9
9839
9907
  }
9840
9908
  },
@@ -9893,7 +9961,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9893
9961
  },
9894
9962
  sourceLocation: {
9895
9963
  "file": "packages/dsh-qa-surface/src/index.ts",
9896
- "line": 1351,
9964
+ "line": 1391,
9897
9965
  "column": 9
9898
9966
  }
9899
9967
  },
@@ -9942,7 +10010,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9942
10010
  },
9943
10011
  sourceLocation: {
9944
10012
  "file": "packages/dsh-qa-surface/src/index.ts",
9945
- "line": 1363,
10013
+ "line": 1403,
9946
10014
  "column": 9
9947
10015
  }
9948
10016
  },
@@ -9991,7 +10059,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
9991
10059
  },
9992
10060
  sourceLocation: {
9993
10061
  "file": "packages/dsh-qa-surface/src/index.ts",
9994
- "line": 796,
10062
+ "line": 803,
9995
10063
  "column": 9
9996
10064
  }
9997
10065
  },
@@ -10009,7 +10077,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10009
10077
  },
10010
10078
  sourceLocation: {
10011
10079
  "file": "packages/dsh-qa-surface/src/index.ts",
10012
- "line": 786,
10080
+ "line": 793,
10013
10081
  "column": 3
10014
10082
  }
10015
10083
  },
@@ -10058,7 +10126,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10058
10126
  },
10059
10127
  sourceLocation: {
10060
10128
  "file": "packages/dsh-qa-surface/src/index.ts",
10061
- "line": 1431,
10129
+ "line": 1471,
10062
10130
  "column": 9
10063
10131
  }
10064
10132
  },
@@ -10094,7 +10162,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10094
10162
  },
10095
10163
  sourceLocation: {
10096
10164
  "file": "packages/dsh-qa-surface/src/index.ts",
10097
- "line": 1308,
10165
+ "line": 1348,
10098
10166
  "column": 9
10099
10167
  }
10100
10168
  },
@@ -10130,7 +10198,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10130
10198
  },
10131
10199
  sourceLocation: {
10132
10200
  "file": "packages/dsh-qa-surface/src/index.ts",
10133
- "line": 1337,
10201
+ "line": 1377,
10134
10202
  "column": 9
10135
10203
  }
10136
10204
  },
@@ -10179,7 +10247,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10179
10247
  },
10180
10248
  sourceLocation: {
10181
10249
  "file": "packages/dsh-qa-surface/src/index.ts",
10182
- "line": 1492,
10250
+ "line": 1532,
10183
10251
  "column": 9
10184
10252
  }
10185
10253
  },
@@ -10228,7 +10296,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10228
10296
  },
10229
10297
  sourceLocation: {
10230
10298
  "file": "packages/dsh-qa-surface/src/index.ts",
10231
- "line": 1382,
10299
+ "line": 1422,
10232
10300
  "column": 9
10233
10301
  }
10234
10302
  },
@@ -10277,7 +10345,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10277
10345
  },
10278
10346
  sourceLocation: {
10279
10347
  "file": "packages/dsh-qa-surface/src/index.ts",
10280
- "line": 1458,
10348
+ "line": 1498,
10281
10349
  "column": 9
10282
10350
  }
10283
10351
  },
@@ -10313,7 +10381,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10313
10381
  },
10314
10382
  sourceLocation: {
10315
10383
  "file": "packages/dsh-qa-surface/src/index.ts",
10316
- "line": 1259,
10384
+ "line": 1299,
10317
10385
  "column": 9
10318
10386
  }
10319
10387
  },
@@ -10349,7 +10417,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10349
10417
  },
10350
10418
  sourceLocation: {
10351
10419
  "file": "packages/dsh-qa-surface/src/index.ts",
10352
- "line": 1562,
10420
+ "line": 1602,
10353
10421
  "column": 3
10354
10422
  }
10355
10423
  },
@@ -10385,7 +10453,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10385
10453
  },
10386
10454
  sourceLocation: {
10387
10455
  "file": "packages/dsh-qa-surface/src/index.ts",
10388
- "line": 1556,
10456
+ "line": 1596,
10389
10457
  "column": 3
10390
10458
  }
10391
10459
  },
@@ -10412,7 +10480,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10412
10480
  },
10413
10481
  sourceLocation: {
10414
10482
  "file": "packages/dsh-qa-surface/src/index.ts",
10415
- "line": 1550,
10483
+ "line": 1590,
10416
10484
  "column": 3
10417
10485
  }
10418
10486
  },
@@ -10461,7 +10529,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10461
10529
  },
10462
10530
  sourceLocation: {
10463
10531
  "file": "packages/dsh-qa-surface/src/index.ts",
10464
- "line": 1581,
10532
+ "line": 1621,
10465
10533
  "column": 3
10466
10534
  }
10467
10535
  },
@@ -10488,7 +10556,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10488
10556
  },
10489
10557
  sourceLocation: {
10490
10558
  "file": "packages/dsh-qa-surface/src/index.ts",
10491
- "line": 1607,
10559
+ "line": 1647,
10492
10560
  "column": 3
10493
10561
  }
10494
10562
  },
@@ -10537,7 +10605,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10537
10605
  },
10538
10606
  sourceLocation: {
10539
10607
  "file": "packages/dsh-qa-surface/src/index.ts",
10540
- "line": 1571,
10608
+ "line": 1611,
10541
10609
  "column": 3
10542
10610
  }
10543
10611
  },
@@ -10586,7 +10654,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10586
10654
  },
10587
10655
  sourceLocation: {
10588
10656
  "file": "packages/dsh-qa-surface/src/index.ts",
10589
- "line": 1594,
10657
+ "line": 1634,
10590
10658
  "column": 3
10591
10659
  }
10592
10660
  },
@@ -10622,7 +10690,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10622
10690
  },
10623
10691
  sourceLocation: {
10624
10692
  "file": "packages/dsh-qa-surface/src/index.ts",
10625
- "line": 1624,
10693
+ "line": 1664,
10626
10694
  "column": 3
10627
10695
  }
10628
10696
  },
@@ -10681,7 +10749,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10681
10749
  },
10682
10750
  sourceLocation: {
10683
10751
  "file": "packages/dsh-qa-surface/src/index.ts",
10684
- "line": 1639,
10752
+ "line": 1679,
10685
10753
  "column": 3
10686
10754
  }
10687
10755
  },
@@ -10717,7 +10785,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10717
10785
  },
10718
10786
  sourceLocation: {
10719
10787
  "file": "packages/dsh-qa-surface/src/index.ts",
10720
- "line": 1295,
10788
+ "line": 1335,
10721
10789
  "column": 9
10722
10790
  }
10723
10791
  }
@@ -11446,7 +11514,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11446
11514
  activationSkill: "qa-surface",
11447
11515
  activationMode: "all",
11448
11516
  activationPresets: Object.freeze([]),
11449
- docsRoot: ""
11517
+ docsRoot: "",
11518
+ docsDefaultVersion: "",
11519
+ docsDefaultVersionEnabled: false
11450
11520
  }),
11451
11521
  sources: Object.freeze({
11452
11522
  enabled: true,
@@ -11548,16 +11618,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11548
11618
  return /^([a-zA-Z]:[/\\]|\/)/u.test(value);
11549
11619
  }
11550
11620
  /**
11551
- * Shared numeric guard for a limit with a floor but no honest ceiling: the value
11552
- * has to be a safe integer of at least `min`. A ceiling belongs on a budget the
11553
- * deployment itself spends (bytes, parallel calls); a wait it merely allows is
11554
- * the operator's call, and a ceiling there only ever truncated a legitimate long
11555
- * answer.
11556
- */
11557
- function assertIntAtLeast(name, value, min) {
11558
- if (!Number.isSafeInteger(value) || value < min) throw new TypeError(`dsh-qa-surface: ${name} must be an integer of at least ${min}`);
11559
- }
11560
- /**
11561
11621
  * Shared numeric guard for operator-tuned limits: the value has to be a safe
11562
11622
  * integer inside [min, max], and every rejection carries the same message.
11563
11623
  */
@@ -11709,13 +11769,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11709
11769
  }
11710
11770
  const QA_INTEGRATION_TTL_DAYS_MAX = 3650;
11711
11771
  /**
11712
- * Floor only: how long an integration may wait for its answer is the operator's
11713
- * call. The deployment spends no budget of its own by waiting, and the ceiling
11714
- * this constant used to carry (10 minutes) truncated exactly the long questions
11715
- * an integration exists for — a nineteen-minute analysis came back as
11716
- * "escalate" while the answer was still being written.
11772
+ * The operator may choose any wait Node can represent faithfully. The former
11773
+ * ten-minute product ceiling cut off legitimate long analyses, while values
11774
+ * above the runtime ceiling wrap to an almost immediate timer.
11717
11775
  */
11718
11776
  const QA_INTEGRATION_TIMEOUT_MS_MIN = 5e3;
11777
+ /** Largest delay Node schedules without overflowing to an immediate timer. */
11778
+ const QA_INTEGRATION_TIMEOUT_MS_MAX = 2147483647;
11719
11779
  const QA_INTEGRATION_BODY_BYTES_MIN = 1048576;
11720
11780
  const QA_INTEGRATION_BODY_BYTES_MAX = 67108864;
11721
11781
  const QA_INTEGRATION_ATTACHMENT_BYTES_MIN = 1024;
@@ -11768,7 +11828,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
11768
11828
  const maxAttachmentBytes = input?.maxAttachmentBytes ?? fallback.maxAttachmentBytes;
11769
11829
  const maxAnswerCharacters = input?.maxAnswerCharacters ?? fallback.maxAnswerCharacters;
11770
11830
  assertIntInRange("integration.tokenTtlDays", tokenTtlDays, 1, QA_INTEGRATION_TTL_DAYS_MAX);
11771
- assertIntAtLeast("integration.requestTimeoutMs", requestTimeoutMs, QA_INTEGRATION_TIMEOUT_MS_MIN);
11831
+ assertIntInRange("integration.requestTimeoutMs", requestTimeoutMs, QA_INTEGRATION_TIMEOUT_MS_MIN, QA_INTEGRATION_TIMEOUT_MS_MAX);
11772
11832
  assertIntInRange("integration.maxConcurrent", maxConcurrent, 1, 16);
11773
11833
  assertIntInRange("integration.requestsPerMinute", requestsPerMinute, 1, 600);
11774
11834
  assertIntInRange("integration.maxRequestBytes", maxRequestBytes, QA_INTEGRATION_BODY_BYTES_MIN, QA_INTEGRATION_BODY_BYTES_MAX);
@@ -12047,6 +12107,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12047
12107
  });
12048
12108
  }
12049
12109
  //#endregion
12110
+ //#region src/shared/docs-version.ts
12111
+ /**
12112
+ * The documentation version grammar, shared by the Host and the browser half.
12113
+ *
12114
+ * This module must stay dependency-free: the settings card bundle inlines the
12115
+ * resolver that validates a configured default version, and a browser build
12116
+ * must not pull the QA tool runtime — or the Node builtins it reads files with
12117
+ * — into the page just to learn what a version looks like.
12118
+ */
12119
+ /** `3.8`, `v2`, `2024.1`: the directory segment a corpus names an edition with. */
12120
+ const VERSION_SEGMENT = /^v?\d+(?:\.\d+)*$/iu;
12121
+ /**
12122
+ * Whether a path segment — or a configured default version — is a documentation
12123
+ * version. A default the corpus can never match is refused where it is written
12124
+ * rather than answered with an empty search.
12125
+ */
12126
+ function isDocumentationVersion(value) {
12127
+ return VERSION_SEGMENT.test(value.trim());
12128
+ }
12129
+ //#endregion
12050
12130
  //#region src/config-resolvers/tools.ts
12051
12131
  /**
12052
12132
  * The public skill-name grammar (`@deepseek-ai/dsh-skill`): lowercase
@@ -12062,12 +12142,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12062
12142
  if (activationMode !== "all") throw new Error(`tools.activationMode must be "all"; got "${String(activationMode)}"`);
12063
12143
  const activationPresets = [...input.tools?.activationPresets ?? DEFAULT_QA_SURFACE_CONFIG.tools.activationPresets];
12064
12144
  for (const preset of activationPresets) if (preset.length === 0) throw new Error("tools.activationPresets must not contain empty names");
12145
+ const defaultVersion = (input.tools?.docsDefaultVersion ?? DEFAULT_QA_SURFACE_CONFIG.tools.docsDefaultVersion).trim();
12146
+ if (defaultVersion !== "" && !isDocumentationVersion(defaultVersion)) throw new Error(`tools.docsDefaultVersion must be a documentation version such as "3.8", got "${defaultVersion}"`);
12065
12147
  return Object.freeze({
12066
12148
  activationSkill,
12067
12149
  activationMode,
12068
12150
  activationPresets: Object.freeze(activationPresets),
12069
12151
  dynamicActivation: input.tools?.dynamicActivation ?? DEFAULT_QA_SURFACE_CONFIG.tools.dynamicActivation,
12070
- docsRoot: input.tools?.docsRoot ?? DEFAULT_QA_SURFACE_CONFIG.tools.docsRoot
12152
+ docsRoot: input.tools?.docsRoot ?? DEFAULT_QA_SURFACE_CONFIG.tools.docsRoot,
12153
+ docsDefaultVersion: defaultVersion,
12154
+ docsDefaultVersionEnabled: input.tools?.docsDefaultVersionEnabled ?? DEFAULT_QA_SURFACE_CONFIG.tools.docsDefaultVersionEnabled
12071
12155
  });
12072
12156
  }
12073
12157
  //#endregion
@@ -12807,20 +12891,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12807
12891
  });
12808
12892
  }
12809
12893
  }
12810
- /** Own the account, migrate the legacy index, then project authed. */
12894
+ /** Own the account, migrate the legacy index, replay held ratings, then auth. */
12811
12895
  async enterSession(token, user) {
12812
12896
  const migration = this.options.legacyChatIds?.() ?? [];
12813
12897
  let ownedIds = [];
12814
12898
  let ownership = [];
12899
+ let ownershipKnown = false;
12815
12900
  try {
12816
12901
  const claimed = await this.options.remote.accountsClaimSessions(token, migration);
12817
12902
  for (const conflict of claimed.ok ? claimed.value.conflicts : []) this.options.forgetChat?.(conflict);
12818
12903
  const ids = await this.options.remote.accountsOwnedSessions(token);
12819
12904
  ownedIds = ids.ok ? ids.value.ids : [];
12905
+ ownershipKnown = ids.ok;
12820
12906
  if (user.role === "admin" && this.options.config().accounts.showOtherUsersChats) ownership = await this.fetchOwnership(token);
12821
12907
  } catch (error) {
12822
12908
  console.warn("dsh-qa-surface: chat migration claim failed", error);
12823
12909
  }
12910
+ if (ownershipKnown) try {
12911
+ await this.options.harvestRatings?.({
12912
+ token,
12913
+ accountId: user.id,
12914
+ ownedIds
12915
+ });
12916
+ } catch (error) {
12917
+ console.warn("dsh-qa-surface: rating harvest failed", error);
12918
+ }
12824
12919
  if (this.disposed) return;
12825
12920
  this.publish({
12826
12921
  stage: "authed",
@@ -12976,6 +13071,138 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
12976
13071
  }
12977
13072
  };
12978
13073
  //#endregion
13074
+ //#region src/client/rating-harvest.ts
13075
+ /**
13076
+ * One-shot replay of the ratings this browser still holds locally.
13077
+ *
13078
+ * A thumbs given before the surface could file it lives in the chat's ratings
13079
+ * map and nowhere else. That map carries no timestamp and no reasons, so it
13080
+ * cannot tell a lost rating from one the Host already holds a fuller version
13081
+ * of — which is why the harvest writes through an insert-only call, offers only
13082
+ * the ratings of the chats the signing-in account owns, and marks an account as
13083
+ * read rather than re-offering its verdicts on every login.
13084
+ */
13085
+ /** Chat-scoped ratings keys sit under this marker: `<ns>:chat:<id>:ratings`. */
13086
+ const CHAT_MARKER = ":chat:";
13087
+ /** The suffix the message row writes its ratings map under. */
13088
+ const RATINGS_SUFFIX = ":ratings";
13089
+ /** Prefix of the per-account marker: `<ns>:ratings-harvested:<account>`. */
13090
+ const HARVESTED_MARKER = ":ratings-harvested:";
13091
+ /** How many ratings one request carries. */
13092
+ const BATCH_SIZE = 100;
13093
+ /** The durable log position an answer row's browser id carries. */
13094
+ const RATED_ANSWER = /^assistant:(\d+)$/u;
13095
+ const ALREADY_HARVESTED = Object.freeze({
13096
+ status: "already-harvested",
13097
+ entries: 0,
13098
+ recorded: 0
13099
+ });
13100
+ function harvestedKey(namespace, accountId) {
13101
+ return `${namespace}${HARVESTED_MARKER}${accountId}`;
13102
+ }
13103
+ /** Whether this browser has already been read out for that account. */
13104
+ function ratingsHarvested(storage, namespace, accountId) {
13105
+ try {
13106
+ return storage.getItem(harvestedKey(namespace, accountId)) === "1";
13107
+ } catch {
13108
+ return false;
13109
+ }
13110
+ }
13111
+ function markRatingsHarvested(storage, namespace, accountId) {
13112
+ try {
13113
+ storage.setItem(harvestedKey(namespace, accountId), "1");
13114
+ } catch {}
13115
+ }
13116
+ function readKeys(storage) {
13117
+ const keys = [];
13118
+ try {
13119
+ for (let index = 0; index < storage.length; index += 1) {
13120
+ const key = storage.key(index);
13121
+ if (typeof key === "string") keys.push(key);
13122
+ }
13123
+ } catch {}
13124
+ return keys;
13125
+ }
13126
+ function parseRatings(raw) {
13127
+ if (raw === null) return {};
13128
+ try {
13129
+ const parsed = JSON.parse(raw);
13130
+ return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
13131
+ } catch {
13132
+ return {};
13133
+ }
13134
+ }
13135
+ function ratingOf(thumbs) {
13136
+ if (thumbs === "up") return "positive";
13137
+ return thumbs === "down" ? "negative" : void 0;
13138
+ }
13139
+ /**
13140
+ * Every rating this browser holds for that namespace, addressed by the
13141
+ * conversation and by the durable log position the Host files a verdict under.
13142
+ *
13143
+ * An answer row's browser id is `assistant:<position>`, so those keys are
13144
+ * addressable. Anything else — a work row, a half-streamed answer, an id the
13145
+ * Host named rather than numbered — cannot be traced back to a log position,
13146
+ * and is left where it is instead of guessed at.
13147
+ */
13148
+ function collectLocalRatings(storage, namespace) {
13149
+ const prefix = `${namespace}${CHAT_MARKER}`;
13150
+ const entries = [];
13151
+ for (const key of readKeys(storage)) {
13152
+ if (!key.startsWith(prefix) || !key.endsWith(RATINGS_SUFFIX)) continue;
13153
+ const conversationId = key.slice(prefix.length, -8);
13154
+ if (conversationId === "") continue;
13155
+ for (const [messageId, thumbs] of Object.entries(parseRatings(storage.getItem(key)))) {
13156
+ const position = RATED_ANSWER.exec(messageId)?.[1];
13157
+ const rating = ratingOf(thumbs);
13158
+ if (position === void 0 || rating === void 0) continue;
13159
+ entries.push({
13160
+ conversationId,
13161
+ messageId: position,
13162
+ rating
13163
+ });
13164
+ }
13165
+ }
13166
+ return entries;
13167
+ }
13168
+ /**
13169
+ * Read this browser's ratings out through `send`, once per account.
13170
+ *
13171
+ * `send` is the Host call; the caller chooses the token and the remote it
13172
+ * travels on. The marker is written only after every batch landed, so a
13173
+ * half-failed harvest is retried by the next login rather than lost.
13174
+ */
13175
+ async function harvestLocalRatings(options) {
13176
+ const { storage, namespace, accountId, ownedIds, send } = options;
13177
+ if (ratingsHarvested(storage, namespace, accountId)) return ALREADY_HARVESTED;
13178
+ const owned = new Set(ownedIds);
13179
+ const entries = collectLocalRatings(storage, namespace).filter((entry) => owned.has(entry.conversationId));
13180
+ if (entries.length === 0) {
13181
+ markRatingsHarvested(storage, namespace, accountId);
13182
+ return {
13183
+ status: "nothing-to-harvest",
13184
+ entries: 0,
13185
+ recorded: 0
13186
+ };
13187
+ }
13188
+ let recorded = 0;
13189
+ for (let offset = 0; offset < entries.length; offset += BATCH_SIZE) {
13190
+ const result = await send(entries.slice(offset, offset + BATCH_SIZE));
13191
+ if (!result.ok) return {
13192
+ status: "failed",
13193
+ entries: entries.length,
13194
+ recorded
13195
+ };
13196
+ recorded += result.value.recorded;
13197
+ }
13198
+ markRatingsHarvested(storage, namespace, accountId);
13199
+ return {
13200
+ status: "harvested",
13201
+ entries: entries.length,
13202
+ recorded
13203
+ };
13204
+ }
13205
+ //#endregion
12979
13206
  //#region src/client/lineage.ts
12980
13207
  /**
12981
13208
  * Whether one session-list entry is a delegated child — a subagent's session —
@@ -14478,7 +14705,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14478
14705
  id: "dsh-web-fetch",
14479
14706
  matches(context) {
14480
14707
  const meta = presentationRecord(context.presentation);
14481
- return context.toolName === "web_fetch" || typeof meta?.url === "string" && typeof meta.statusCode === "number";
14708
+ return [
14709
+ "web_fetch",
14710
+ "web_fetch_file",
14711
+ "web_fetch_image"
14712
+ ].includes(context.toolName) || typeof meta?.url === "string" && typeof meta.statusCode === "number";
14482
14713
  },
14483
14714
  extract(context) {
14484
14715
  const args = parsedArgs(context.args);
@@ -20286,7 +20517,1872 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20286
20517
  });
20287
20518
  }
20288
20519
  //#endregion
20520
+ //#region ../../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/compat/_internal/isPrototype.mjs
20521
+ function isPrototype(value) {
20522
+ const constructor = value?.constructor;
20523
+ return value === (typeof constructor === "function" ? constructor.prototype : Object.prototype);
20524
+ }
20525
+ //#endregion
20526
+ //#region ../../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/compat/predicate/isEmpty.mjs
20527
+ /**
20528
+ * Checks if a given value is empty.
20529
+ *
20530
+ * - If the given value is a string, checks if it is an empty string.
20531
+ * - If the given value is an array, `Map`, or `Set`, checks if its size is 0.
20532
+ * - If the given value is an [array-like object](../predicate/isArrayLike.md), checks if its length is 0.
20533
+ * - If the given value is an object, checks if it is an empty object with no properties.
20534
+ * - Primitive values (booleans, numbers, or bigints) are considered empty.
20535
+ *
20536
+ * @param [value] - The value to check.
20537
+ * @returns `true` if the value is empty, `false` otherwise.
20538
+ *
20539
+ * @example
20540
+ * isEmpty(); // true
20541
+ * isEmpty(null); // true
20542
+ * isEmpty(""); // true
20543
+ * isEmpty([]); // true
20544
+ * isEmpty({}); // true
20545
+ * isEmpty(new Map()); // true
20546
+ * isEmpty(new Set()); // true
20547
+ * isEmpty("hello"); // false
20548
+ * isEmpty([1, 2, 3]); // false
20549
+ * isEmpty({ a: 1 }); // false
20550
+ * isEmpty(new Map([["key", "value"]])); // false
20551
+ * isEmpty(new Set([1, 2, 3])); // false
20552
+ */
20553
+ function isEmpty(value) {
20554
+ if (value == null) return true;
20555
+ if (require_chunk_75Z2AOVW.isArrayLike(value)) {
20556
+ if (typeof value.splice !== "function" && typeof value !== "string" && !require_chunk_75Z2AOVW.isBuffer(value) && !require_chunk_75Z2AOVW.isTypedArray(value) && !require_chunk_75Z2AOVW.isArguments(value)) return false;
20557
+ return value.length === 0;
20558
+ }
20559
+ if (typeof value === "object" || typeof value === "function") {
20560
+ if (value instanceof Map || value instanceof Set) return value.size === 0;
20561
+ const keys = Object.keys(value);
20562
+ if (isPrototype(value)) return keys.filter((x) => x !== "constructor").length === 0;
20563
+ return keys.length === 0;
20564
+ }
20565
+ return true;
20566
+ }
20567
+ //#endregion
20568
+ //#region ../../node_modules/.pnpm/stylis@4.4.0/node_modules/stylis/src/Enum.js
20569
+ var COMMENT = "comm";
20570
+ var RULESET = "rule";
20571
+ var DECLARATION = "decl";
20572
+ var IMPORT = "@import";
20573
+ var NAMESPACE = "@namespace";
20574
+ var KEYFRAMES = "@keyframes";
20575
+ var LAYER = "@layer";
20576
+ //#endregion
20577
+ //#region ../../node_modules/.pnpm/stylis@4.4.0/node_modules/stylis/src/Utility.js
20578
+ /**
20579
+ * @param {number}
20580
+ * @return {number}
20581
+ */
20582
+ var abs = Math.abs;
20583
+ /**
20584
+ * @param {number}
20585
+ * @return {string}
20586
+ */
20587
+ var from = String.fromCharCode;
20588
+ /**
20589
+ * @param {string} value
20590
+ * @return {string}
20591
+ */
20592
+ function trim(value) {
20593
+ return value.trim();
20594
+ }
20595
+ /**
20596
+ * @param {string} value
20597
+ * @param {(string|RegExp)} pattern
20598
+ * @param {string} replacement
20599
+ * @return {string}
20600
+ */
20601
+ function replace(value, pattern, replacement) {
20602
+ return value.replace(pattern, replacement);
20603
+ }
20604
+ /**
20605
+ * @param {string} value
20606
+ * @param {number} index
20607
+ * @return {number}
20608
+ */
20609
+ function charat(value, index) {
20610
+ return value.charCodeAt(index) | 0;
20611
+ }
20612
+ /**
20613
+ * @param {string} value
20614
+ * @param {number} begin
20615
+ * @param {number} end
20616
+ * @return {string}
20617
+ */
20618
+ function substr(value, begin, end) {
20619
+ return value.slice(begin, end);
20620
+ }
20621
+ /**
20622
+ * @param {string} value
20623
+ * @return {number}
20624
+ */
20625
+ function strlen(value) {
20626
+ return value.length;
20627
+ }
20628
+ /**
20629
+ * @param {any[]} value
20630
+ * @return {number}
20631
+ */
20632
+ function sizeof(value) {
20633
+ return value.length;
20634
+ }
20635
+ /**
20636
+ * @param {any} value
20637
+ * @param {any[]} array
20638
+ * @return {any}
20639
+ */
20640
+ function append(value, array) {
20641
+ return array.push(value), value;
20642
+ }
20643
+ //#endregion
20644
+ //#region ../../node_modules/.pnpm/stylis@4.4.0/node_modules/stylis/src/Tokenizer.js
20645
+ var line = 1;
20646
+ var column = 1;
20647
+ var length = 0;
20648
+ var position = 0;
20649
+ var character = 0;
20650
+ var characters = "";
20651
+ /**
20652
+ * @param {string} value
20653
+ * @param {object | null} root
20654
+ * @param {object | null} parent
20655
+ * @param {string} type
20656
+ * @param {string[] | string} props
20657
+ * @param {object[] | string} children
20658
+ * @param {object[]} siblings
20659
+ * @param {number} length
20660
+ */
20661
+ function node(value, root, parent, type, props, children, length, siblings) {
20662
+ return {
20663
+ value,
20664
+ root,
20665
+ parent,
20666
+ type,
20667
+ props,
20668
+ children,
20669
+ line,
20670
+ column,
20671
+ length,
20672
+ return: "",
20673
+ siblings
20674
+ };
20675
+ }
20676
+ /**
20677
+ * @return {number}
20678
+ */
20679
+ function char() {
20680
+ return character;
20681
+ }
20682
+ /**
20683
+ * @return {number}
20684
+ */
20685
+ function prev() {
20686
+ character = position > 0 ? charat(characters, --position) : 0;
20687
+ if (column--, character === 10) column = 1, line--;
20688
+ return character;
20689
+ }
20690
+ /**
20691
+ * @return {number}
20692
+ */
20693
+ function next() {
20694
+ character = position < length ? charat(characters, position++) : 0;
20695
+ if (column++, character === 10) column = 1, line++;
20696
+ return character;
20697
+ }
20698
+ /**
20699
+ * @return {number}
20700
+ */
20701
+ function peek() {
20702
+ return charat(characters, position);
20703
+ }
20704
+ /**
20705
+ * @return {number}
20706
+ */
20707
+ function caret() {
20708
+ return position;
20709
+ }
20710
+ /**
20711
+ * @param {number} begin
20712
+ * @param {number} end
20713
+ * @return {string}
20714
+ */
20715
+ function slice(begin, end) {
20716
+ return substr(characters, begin, end);
20717
+ }
20718
+ /**
20719
+ * @param {number} type
20720
+ * @return {number}
20721
+ */
20722
+ function token(type) {
20723
+ switch (type) {
20724
+ case 0:
20725
+ case 9:
20726
+ case 10:
20727
+ case 13:
20728
+ case 32: return 5;
20729
+ case 33:
20730
+ case 43:
20731
+ case 44:
20732
+ case 47:
20733
+ case 62:
20734
+ case 64:
20735
+ case 126:
20736
+ case 59:
20737
+ case 123:
20738
+ case 125: return 4;
20739
+ case 58: return 3;
20740
+ case 34:
20741
+ case 39:
20742
+ case 40:
20743
+ case 91: return 2;
20744
+ case 41:
20745
+ case 93: return 1;
20746
+ }
20747
+ return 0;
20748
+ }
20749
+ /**
20750
+ * @param {string} value
20751
+ * @return {any[]}
20752
+ */
20753
+ function alloc(value) {
20754
+ return line = column = 1, length = strlen(characters = value), position = 0, [];
20755
+ }
20756
+ /**
20757
+ * @param {any} value
20758
+ * @return {any}
20759
+ */
20760
+ function dealloc(value) {
20761
+ return characters = "", value;
20762
+ }
20763
+ /**
20764
+ * @param {number} type
20765
+ * @return {string}
20766
+ */
20767
+ function delimit(type) {
20768
+ return trim(slice(position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type)));
20769
+ }
20770
+ /**
20771
+ * @param {number} type
20772
+ * @return {string}
20773
+ */
20774
+ function whitespace(type) {
20775
+ while (character = peek()) if (character < 33) next();
20776
+ else break;
20777
+ return token(type) > 2 || token(character) > 3 ? "" : " ";
20778
+ }
20779
+ /**
20780
+ * @param {number} index
20781
+ * @param {number} count
20782
+ * @return {string}
20783
+ */
20784
+ function escaping(index, count) {
20785
+ while (--count && next()) if (character < 48 || character > 102 || character > 57 && character < 65 || character > 70 && character < 97) break;
20786
+ return slice(index, caret() + (count < 6 && peek() == 32 && next() == 32));
20787
+ }
20788
+ /**
20789
+ * @param {number} type
20790
+ * @return {number}
20791
+ */
20792
+ function delimiter(type) {
20793
+ while (next()) switch (character) {
20794
+ case type: return position;
20795
+ case 34:
20796
+ case 39:
20797
+ if (type !== 34 && type !== 39) delimiter(character);
20798
+ break;
20799
+ case 40:
20800
+ if (type === 41) delimiter(type);
20801
+ break;
20802
+ case 92: next();
20803
+ }
20804
+ return position;
20805
+ }
20806
+ /**
20807
+ * @param {number} type
20808
+ * @param {number} index
20809
+ * @return {number}
20810
+ */
20811
+ function commenter(type, index) {
20812
+ while (next()) if (type + character === 57) break;
20813
+ else if (type + character === 84 && peek() === 47) break;
20814
+ return "/*" + slice(index, position - 1) + "*" + from(type === 47 ? type : next());
20815
+ }
20816
+ /**
20817
+ * @param {number} index
20818
+ * @return {string}
20819
+ */
20820
+ function identifier(index) {
20821
+ while (!token(peek())) next();
20822
+ return slice(index, position);
20823
+ }
20824
+ //#endregion
20825
+ //#region ../../node_modules/.pnpm/stylis@4.4.0/node_modules/stylis/src/Parser.js
20826
+ /**
20827
+ * @param {string} value
20828
+ * @return {object[]}
20829
+ */
20830
+ function compile(value) {
20831
+ return dealloc(parse$1("", null, null, null, [""], value = alloc(value), 0, [0], value));
20832
+ }
20833
+ /**
20834
+ * @param {string} value
20835
+ * @param {object} root
20836
+ * @param {object?} parent
20837
+ * @param {string[]} rule
20838
+ * @param {string[]} rules
20839
+ * @param {string[]} rulesets
20840
+ * @param {number[]} pseudo
20841
+ * @param {number[]} points
20842
+ * @param {string[]} declarations
20843
+ * @return {object}
20844
+ */
20845
+ function parse$1(value, root, parent, rule, rules, rulesets, pseudo, points, declarations) {
20846
+ var index = 0;
20847
+ var offset = 0;
20848
+ var length = pseudo;
20849
+ var atrule = 0;
20850
+ var property = 0;
20851
+ var previous = 0;
20852
+ var variable = 1;
20853
+ var scanning = 1;
20854
+ var ampersand = 1;
20855
+ var parens = 0;
20856
+ var character = 0;
20857
+ var type = "";
20858
+ var props = rules;
20859
+ var children = rulesets;
20860
+ var reference = rule;
20861
+ var characters = type;
20862
+ while (scanning) switch (previous = character, character = next()) {
20863
+ case 40:
20864
+ if (previous != 108 && charat(characters, length - 1) == 58) parens++, characters += "(";
20865
+ else characters += delimit(character);
20866
+ break;
20867
+ case 41:
20868
+ parens--, characters += ")";
20869
+ break;
20870
+ case 34:
20871
+ case 39:
20872
+ case 91:
20873
+ characters += delimit(character);
20874
+ break;
20875
+ case 9:
20876
+ case 10:
20877
+ case 13:
20878
+ case 32:
20879
+ if (parens > 0) {
20880
+ characters += from(character);
20881
+ break;
20882
+ }
20883
+ characters += whitespace(previous);
20884
+ break;
20885
+ case 92:
20886
+ characters += escaping(caret() - 1, 7);
20887
+ continue;
20888
+ case 47:
20889
+ switch (peek()) {
20890
+ case 42:
20891
+ case 47:
20892
+ append(comment(commenter(next(), caret()), root, parent, declarations), declarations);
20893
+ if ((token(previous || 1) == 5 || token(peek() || 1) == 5) && strlen(characters) && substr(characters, -1, void 0) !== " ") characters += " ";
20894
+ break;
20895
+ default: characters += "/";
20896
+ }
20897
+ break;
20898
+ case 123 * variable: points[index++] = strlen(characters) * ampersand;
20899
+ case 125 * variable:
20900
+ case 59:
20901
+ case 0:
20902
+ if (parens > 0 && character) {
20903
+ characters += from(character);
20904
+ break;
20905
+ }
20906
+ switch (character) {
20907
+ case 0:
20908
+ case 125: scanning = 0;
20909
+ case 59 + offset:
20910
+ if (ampersand == -1) characters = replace(characters, /\f/g, "");
20911
+ if (property > 0 && (strlen(characters) - length || variable === 0)) append(property > 32 ? declaration(characters + ";", rule, parent, length - 1, declarations) : declaration(replace(characters, " ", "") + ";", rule, parent, length - 2, declarations), declarations);
20912
+ break;
20913
+ case 59: characters += ";";
20914
+ default:
20915
+ append(reference = ruleset(characters, root, parent, index, offset, rules, points, type, props = [], children = [], length, rulesets), rulesets);
20916
+ if (character === 123) if (offset === 0) parse$1(characters, root, reference, reference, props, rulesets, length, points, children);
20917
+ else {
20918
+ switch (atrule) {
20919
+ case 99: if (charat(characters, 3) === 110) break;
20920
+ case 108: if (charat(characters, 2) === 97) break;
20921
+ default: offset = 0;
20922
+ case 100:
20923
+ case 109:
20924
+ case 115:
20925
+ }
20926
+ if (offset) parse$1(value, reference, reference, rule && append(ruleset(value, reference, reference, 0, 0, rules, points, type, rules, props = [], length, children), children), rules, children, length, points, rule ? props : children);
20927
+ else parse$1(characters, reference, reference, reference, [""], children, 0, points, children);
20928
+ }
20929
+ }
20930
+ index = offset = property = 0, variable = ampersand = 1, type = characters = "", length = pseudo;
20931
+ break;
20932
+ case 58: length = 1 + strlen(characters), property = previous;
20933
+ default:
20934
+ if (variable < 1) {
20935
+ if (character == 123) --variable;
20936
+ else if (character == 125 && variable++ == 0 && prev() == 125) continue;
20937
+ }
20938
+ switch (characters += from(character), character * variable) {
20939
+ case 38:
20940
+ ampersand = offset > 0 ? 1 : (characters += "\f", -1);
20941
+ break;
20942
+ case 44:
20943
+ if (parens > 0) break;
20944
+ points[index++] = (strlen(characters) - 1) * ampersand, ampersand = 1;
20945
+ break;
20946
+ case 64:
20947
+ if (peek() === 45) characters += delimit(next());
20948
+ atrule = peek(), offset = length = strlen(type = characters += identifier(caret())), character++;
20949
+ break;
20950
+ case 45: if (previous === 45 && strlen(characters) == 2) variable = 0;
20951
+ }
20952
+ }
20953
+ return rulesets;
20954
+ }
20955
+ /**
20956
+ * @param {string} value
20957
+ * @param {object} root
20958
+ * @param {object?} parent
20959
+ * @param {number} index
20960
+ * @param {number} offset
20961
+ * @param {string[]} rules
20962
+ * @param {number[]} points
20963
+ * @param {string} type
20964
+ * @param {string[]} props
20965
+ * @param {string[]} children
20966
+ * @param {number} length
20967
+ * @param {object[]} siblings
20968
+ * @return {object}
20969
+ */
20970
+ function ruleset(value, root, parent, index, offset, rules, points, type, props, children, length, siblings) {
20971
+ var post = offset - 1;
20972
+ var rule = offset === 0 ? rules : [""];
20973
+ var size = sizeof(rule);
20974
+ for (var i = 0, j = 0, k = 0; i < index; ++i) for (var x = 0, y = substr(value, post + 1, post = abs(j = points[i])), z = value; x < size; ++x) if (z = trim(j > 0 ? rule[x] + " " + y : replace(y, /&\f/g, rule[x]))) props[k++] = z;
20975
+ return node(value, root, parent, offset === 0 ? RULESET : type, props, children, length, siblings);
20976
+ }
20977
+ /**
20978
+ * @param {number} value
20979
+ * @param {object} root
20980
+ * @param {object?} parent
20981
+ * @param {object[]} siblings
20982
+ * @return {object}
20983
+ */
20984
+ function comment(value, root, parent, siblings) {
20985
+ return node(value, root, parent, COMMENT, from(char()), substr(value, 2, -2), 0, siblings);
20986
+ }
20987
+ /**
20988
+ * @param {string} value
20989
+ * @param {object} root
20990
+ * @param {object?} parent
20991
+ * @param {number} length
20992
+ * @param {object[]} siblings
20993
+ * @return {object}
20994
+ */
20995
+ function declaration(value, root, parent, length, siblings) {
20996
+ return node(value, root, parent, DECLARATION, substr(value, 0, length), substr(value, length + 1, -1), length, siblings);
20997
+ }
20998
+ //#endregion
20999
+ //#region ../../node_modules/.pnpm/stylis@4.4.0/node_modules/stylis/src/Serializer.js
21000
+ /**
21001
+ * @param {object[]} children
21002
+ * @param {function} callback
21003
+ * @return {string}
21004
+ */
21005
+ function serialize(children, callback) {
21006
+ var output = "";
21007
+ for (var i = 0; i < children.length; i++) output += callback(children[i], i, children, callback) || "";
21008
+ return output;
21009
+ }
21010
+ /**
21011
+ * @param {object} element
21012
+ * @param {number} index
21013
+ * @param {object[]} children
21014
+ * @param {function} callback
21015
+ * @return {string}
21016
+ */
21017
+ function stringify(element, index, children, callback) {
21018
+ switch (element.type) {
21019
+ case LAYER: if (element.children.length) break;
21020
+ case IMPORT:
21021
+ case NAMESPACE:
21022
+ case DECLARATION: return element.return = element.return || element.value;
21023
+ case COMMENT: return "";
21024
+ case KEYFRAMES: return element.return = element.value + "{" + serialize(element.children, callback) + "}";
21025
+ case RULESET: if (!strlen(element.value = element.props.join(","))) return "";
21026
+ }
21027
+ return strlen(children = serialize(element.children, callback)) ? element.return = element.value + "{" + children + "}" : "";
21028
+ }
21029
+ //#endregion
21030
+ //#region ../../node_modules/.pnpm/stylis@4.4.0/node_modules/stylis/src/Middleware.js
21031
+ /**
21032
+ * @param {function[]} collection
21033
+ * @return {function}
21034
+ */
21035
+ function middleware(collection) {
21036
+ var length = sizeof(collection);
21037
+ return function(element, index, children, callback) {
21038
+ var output = "";
21039
+ for (var i = 0; i < length; i++) output += collection[i](element, index, children, callback) || "";
21040
+ return output;
21041
+ };
21042
+ }
21043
+ //#endregion
21044
+ //#region ../../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/mermaid.core.mjs
21045
+ var id = "c4";
21046
+ var c4Detector_default = {
21047
+ id,
21048
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21049
+ return /^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(txt);
21050
+ }, "detector"),
21051
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21052
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./c4Diagram-7LVT6UL2-CFvYVb_D.cjs"));
21053
+ return {
21054
+ id,
21055
+ diagram: diagram2
21056
+ };
21057
+ }, "loader")
21058
+ };
21059
+ var id2 = "flowchart";
21060
+ var flowDetector_default = {
21061
+ id: id2,
21062
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt, config) => {
21063
+ if (config?.flowchart?.defaultRenderer === "dagre-wrapper" || config?.flowchart?.defaultRenderer === "elk") return false;
21064
+ return /^\s*graph/.test(txt);
21065
+ }, "detector"),
21066
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21067
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./flowDiagram-HODETNUW-VH2Rn6lb.cjs"));
21068
+ return {
21069
+ id: id2,
21070
+ diagram: diagram2
21071
+ };
21072
+ }, "loader")
21073
+ };
21074
+ var id3 = "flowchart-v2";
21075
+ var flowDetector_v2_default = {
21076
+ id: id3,
21077
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt, config) => {
21078
+ if (config?.flowchart?.defaultRenderer === "dagre-d3") return false;
21079
+ if (config?.flowchart?.defaultRenderer === "elk") config.layout = "elk";
21080
+ if (/^\s*graph/.test(txt) && config?.flowchart?.defaultRenderer === "dagre-wrapper") return true;
21081
+ return /^\s*flowchart/.test(txt);
21082
+ }, "detector"),
21083
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21084
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./flowDiagram-HODETNUW-VH2Rn6lb.cjs"));
21085
+ return {
21086
+ id: id3,
21087
+ diagram: diagram2
21088
+ };
21089
+ }, "loader")
21090
+ };
21091
+ var id4 = "swimlane";
21092
+ var detector_default = {
21093
+ id: id4,
21094
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21095
+ return /^\s*swimlane-beta\b/.test(txt);
21096
+ }, "detector"),
21097
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21098
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./swimlanesDiagram-VR7AAH4N-BBHpr-0x.cjs"));
21099
+ return {
21100
+ id: id4,
21101
+ diagram: diagram2
21102
+ };
21103
+ }, "loader")
21104
+ };
21105
+ var id5 = "er";
21106
+ var erDetector_default = {
21107
+ id: id5,
21108
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21109
+ return /^\s*erDiagram/.test(txt);
21110
+ }, "detector"),
21111
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21112
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./erDiagram-RLTQ6QDP-CCudjekz.cjs"));
21113
+ return {
21114
+ id: id5,
21115
+ diagram: diagram2
21116
+ };
21117
+ }, "loader")
21118
+ };
21119
+ var id6 = "gitGraph";
21120
+ var gitGraphDetector_default = {
21121
+ id: id6,
21122
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21123
+ return /^\s*gitGraph/.test(txt);
21124
+ }, "detector"),
21125
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21126
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./gitGraphDiagram-WWUBYQGX-CJXV-l6A.cjs"));
21127
+ return {
21128
+ id: id6,
21129
+ diagram: diagram2
21130
+ };
21131
+ }, "loader")
21132
+ };
21133
+ var id7 = "gantt";
21134
+ var ganttDetector_default = {
21135
+ id: id7,
21136
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21137
+ return /^\s*gantt/.test(txt);
21138
+ }, "detector"),
21139
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21140
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./ganttDiagram-EL5Y4UJY-Kpz6vAiy.cjs"));
21141
+ return {
21142
+ id: id7,
21143
+ diagram: diagram2
21144
+ };
21145
+ }, "loader")
21146
+ };
21147
+ var id8 = "info";
21148
+ var info = {
21149
+ id: id8,
21150
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21151
+ return /^\s*info/.test(txt);
21152
+ }, "detector"),
21153
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21154
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./infoDiagram-27XIBGKW-BOI_kUgt.cjs"));
21155
+ return {
21156
+ id: id8,
21157
+ diagram: diagram2
21158
+ };
21159
+ }, "loader")
21160
+ };
21161
+ var id9 = "pie";
21162
+ var pie = {
21163
+ id: id9,
21164
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21165
+ return /^\s*pie/.test(txt);
21166
+ }, "detector"),
21167
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21168
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./pieDiagram-E7YTZNPT-B2ZJ3K5b.cjs"));
21169
+ return {
21170
+ id: id9,
21171
+ diagram: diagram2
21172
+ };
21173
+ }, "loader")
21174
+ };
21175
+ var id10 = "quadrantChart";
21176
+ var quadrantDetector_default = {
21177
+ id: id10,
21178
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21179
+ return /^\s*quadrantChart/.test(txt);
21180
+ }, "detector"),
21181
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21182
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./quadrantDiagram-AXDQQJYC-CUbgXii0.cjs"));
21183
+ return {
21184
+ id: id10,
21185
+ diagram: diagram2
21186
+ };
21187
+ }, "loader")
21188
+ };
21189
+ var id11 = "xychart";
21190
+ var xychartDetector_default = {
21191
+ id: id11,
21192
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21193
+ return /^\s*xychart(-beta)?/.test(txt);
21194
+ }, "detector"),
21195
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21196
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./xychartDiagram-S5SC5T6Z-iYUZjZwr.cjs"));
21197
+ return {
21198
+ id: id11,
21199
+ diagram: diagram2
21200
+ };
21201
+ }, "loader")
21202
+ };
21203
+ var id12 = "requirement";
21204
+ var requirementDetector_default = {
21205
+ id: id12,
21206
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21207
+ return /^\s*requirement(Diagram)?/.test(txt);
21208
+ }, "detector"),
21209
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21210
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./requirementDiagram-BXWQKSXE-B8yziCAV.cjs"));
21211
+ return {
21212
+ id: id12,
21213
+ diagram: diagram2
21214
+ };
21215
+ }, "loader")
21216
+ };
21217
+ var id13 = "sequence";
21218
+ var sequenceDetector_default = {
21219
+ id: id13,
21220
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21221
+ return /^\s*sequenceDiagram/.test(txt);
21222
+ }, "detector"),
21223
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21224
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./sequenceDiagram-WJ2MYXX4-BjVAVAeI.cjs"));
21225
+ return {
21226
+ id: id13,
21227
+ diagram: diagram2
21228
+ };
21229
+ }, "loader")
21230
+ };
21231
+ var id14 = "class";
21232
+ var classDetector_default = {
21233
+ id: id14,
21234
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt, config) => {
21235
+ if (config?.class?.defaultRenderer === "dagre-wrapper") return false;
21236
+ return /^\s*classDiagram/.test(txt);
21237
+ }, "detector"),
21238
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21239
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./classDiagram-ZZMXUADV-Bz4P2oRX.cjs"));
21240
+ return {
21241
+ id: id14,
21242
+ diagram: diagram2
21243
+ };
21244
+ }, "loader")
21245
+ };
21246
+ var id15 = "classDiagram";
21247
+ var classDetector_V2_default = {
21248
+ id: id15,
21249
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt, config) => {
21250
+ if (/^\s*classDiagram/.test(txt) && config?.class?.defaultRenderer === "dagre-wrapper") return true;
21251
+ return /^\s*classDiagram-v2/.test(txt);
21252
+ }, "detector"),
21253
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21254
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./classDiagram-v2-VYDZK3BY-Bz4P2oRX.cjs"));
21255
+ return {
21256
+ id: id15,
21257
+ diagram: diagram2
21258
+ };
21259
+ }, "loader")
21260
+ };
21261
+ var id16 = "state";
21262
+ var stateDetector_default = {
21263
+ id: id16,
21264
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt, config) => {
21265
+ if (config?.state?.defaultRenderer === "dagre-wrapper") return false;
21266
+ return /^\s*stateDiagram/.test(txt);
21267
+ }, "detector"),
21268
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21269
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./stateDiagram-D77RDMKH-CjJPJLAB.cjs"));
21270
+ return {
21271
+ id: id16,
21272
+ diagram: diagram2
21273
+ };
21274
+ }, "loader")
21275
+ };
21276
+ var id17 = "stateDiagram";
21277
+ var stateDetector_V2_default = {
21278
+ id: id17,
21279
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt, config) => {
21280
+ if (/^\s*stateDiagram-v2/.test(txt)) return true;
21281
+ if (/^\s*stateDiagram/.test(txt) && config?.state?.defaultRenderer === "dagre-wrapper") return true;
21282
+ return false;
21283
+ }, "detector"),
21284
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21285
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./stateDiagram-v2-MP3YSRHH-DLVXgDR-.cjs"));
21286
+ return {
21287
+ id: id17,
21288
+ diagram: diagram2
21289
+ };
21290
+ }, "loader")
21291
+ };
21292
+ var id18 = "journey";
21293
+ var journeyDetector_default = {
21294
+ id: id18,
21295
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21296
+ return /^\s*journey/.test(txt);
21297
+ }, "detector"),
21298
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21299
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./journeyDiagram-3NMN7TZE-BoyV_lYH.cjs"));
21300
+ return {
21301
+ id: id18,
21302
+ diagram: diagram2
21303
+ };
21304
+ }, "loader")
21305
+ };
21306
+ var renderer = { draw: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((_text, id39, version) => {
21307
+ require_src.log.debug("rendering svg for syntax error\n");
21308
+ const svg = require_chunk_CLGD4ZFX.selectSvgElement(id39);
21309
+ const g = svg.append("g");
21310
+ svg.attr("viewBox", "0 0 2412 512");
21311
+ require_chunk_DU6HZSFF.configureSvgSize(svg, 100, 512, true);
21312
+ g.append("path").attr("class", "error-icon").attr("d", "m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z");
21313
+ g.append("path").attr("class", "error-icon").attr("d", "m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z");
21314
+ g.append("path").attr("class", "error-icon").attr("d", "m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z");
21315
+ g.append("path").attr("class", "error-icon").attr("d", "m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z");
21316
+ g.append("path").attr("class", "error-icon").attr("d", "m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z");
21317
+ g.append("path").attr("class", "error-icon").attr("d", "m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z");
21318
+ g.append("text").attr("class", "error-text").attr("x", 1440).attr("y", 250).attr("font-size", "150px").style("text-anchor", "middle").text("Syntax error in text");
21319
+ g.append("text").attr("class", "error-text").attr("x", 1250).attr("y", 400).attr("font-size", "100px").style("text-anchor", "middle").text(`mermaid version ${version}`);
21320
+ }, "draw") };
21321
+ var errorRenderer_default = renderer;
21322
+ var errorDiagram_default = {
21323
+ db: {},
21324
+ renderer,
21325
+ parser: { parse: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {}, "parse") }
21326
+ };
21327
+ var id19 = "flowchart-elk";
21328
+ var detector_default2 = {
21329
+ id: id19,
21330
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt, config = {}) => {
21331
+ if (/^\s*flowchart-elk/.test(txt) || /^\s*(flowchart|graph)/.test(txt) && config?.flowchart?.defaultRenderer === "elk") {
21332
+ config.layout = "elk";
21333
+ return true;
21334
+ }
21335
+ return false;
21336
+ }, "detector"),
21337
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21338
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./flowDiagram-HODETNUW-VH2Rn6lb.cjs"));
21339
+ return {
21340
+ id: id19,
21341
+ diagram: diagram2
21342
+ };
21343
+ }, "loader")
21344
+ };
21345
+ var id20 = "timeline";
21346
+ var detector_default3 = {
21347
+ id: id20,
21348
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21349
+ return /^\s*timeline/.test(txt);
21350
+ }, "detector"),
21351
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21352
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./timeline-definition-24CTP7MA-B6FLO9fn.cjs"));
21353
+ return {
21354
+ id: id20,
21355
+ diagram: diagram2
21356
+ };
21357
+ }, "loader")
21358
+ };
21359
+ var id21 = "mindmap";
21360
+ var detector_default4 = {
21361
+ id: id21,
21362
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21363
+ return /^\s*mindmap/.test(txt);
21364
+ }, "detector"),
21365
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21366
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./mindmap-definition-YA3MSWOX-7X_4_0S6.cjs"));
21367
+ return {
21368
+ id: id21,
21369
+ diagram: diagram2
21370
+ };
21371
+ }, "loader")
21372
+ };
21373
+ var id22 = "kanban";
21374
+ var detector_default5 = {
21375
+ id: id22,
21376
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21377
+ return /^\s*kanban/.test(txt);
21378
+ }, "detector"),
21379
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21380
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./kanban-definition-UXKFOSKX-Cp5PiN69.cjs"));
21381
+ return {
21382
+ id: id22,
21383
+ diagram: diagram2
21384
+ };
21385
+ }, "loader")
21386
+ };
21387
+ var id23 = "sankey";
21388
+ var sankeyDetector_default = {
21389
+ id: id23,
21390
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21391
+ return /^\s*sankey(-beta)?/.test(txt);
21392
+ }, "detector"),
21393
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21394
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./sankeyDiagram-P5KCCOFB-am60dMKk.cjs"));
21395
+ return {
21396
+ id: id23,
21397
+ diagram: diagram2
21398
+ };
21399
+ }, "loader")
21400
+ };
21401
+ var id24 = "packet";
21402
+ var packet = {
21403
+ id: id24,
21404
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21405
+ return /^\s*packet(-beta)?/.test(txt);
21406
+ }, "detector"),
21407
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21408
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./diagram-Z3DM3KII-8uxj8GzQ.cjs"));
21409
+ return {
21410
+ id: id24,
21411
+ diagram: diagram2
21412
+ };
21413
+ }, "loader")
21414
+ };
21415
+ var id25 = "radar";
21416
+ var radar = {
21417
+ id: id25,
21418
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21419
+ return /^\s*radar-beta/.test(txt);
21420
+ }, "detector"),
21421
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21422
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./diagram-UQ7AKVKN-BnGYpddE.cjs"));
21423
+ return {
21424
+ id: id25,
21425
+ diagram: diagram2
21426
+ };
21427
+ }, "loader")
21428
+ };
21429
+ var id26 = "block";
21430
+ var blockDetector_default = {
21431
+ id: id26,
21432
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21433
+ return /^\s*block(-beta)?/.test(txt);
21434
+ }, "detector"),
21435
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21436
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./blockDiagram-I7D4REHJ-CN12kJVh.cjs"));
21437
+ return {
21438
+ id: id26,
21439
+ diagram: diagram2
21440
+ };
21441
+ }, "loader")
21442
+ };
21443
+ var id27 = "treeView";
21444
+ var detector_default6 = {
21445
+ id: id27,
21446
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21447
+ return /^\s*treeView-beta/.test(txt);
21448
+ }, "detector"),
21449
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21450
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./diagram-S7CK7UJ4-BSYI0VgZ.cjs"));
21451
+ return {
21452
+ id: id27,
21453
+ diagram: diagram2
21454
+ };
21455
+ }, "loader")
21456
+ };
21457
+ var id28 = "architecture";
21458
+ var architectureDetector_default = {
21459
+ id: id28,
21460
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21461
+ return /^\s*architecture/.test(txt);
21462
+ }, "detector"),
21463
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21464
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./architectureDiagram-5GKGNRK7-NVjH6XTq.cjs"));
21465
+ return {
21466
+ id: id28,
21467
+ diagram: diagram2
21468
+ };
21469
+ }, "loader")
21470
+ };
21471
+ var id29 = "eventmodeling";
21472
+ var detector_default7 = {
21473
+ id: id29,
21474
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21475
+ return /^\s*eventmodeling/.test(txt);
21476
+ }, "detector"),
21477
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21478
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./diagram-VSXAHHWV-B-hbzZAq.cjs"));
21479
+ return {
21480
+ id: id29,
21481
+ diagram: diagram2
21482
+ };
21483
+ }, "loader")
21484
+ };
21485
+ var id30 = "ishikawa";
21486
+ var ishikawa = {
21487
+ id: id30,
21488
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21489
+ return /^\s*ishikawa(-beta)?\b/i.test(txt);
21490
+ }, "detector"),
21491
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21492
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./ishikawaDiagram-5VMMS53U-C1otik_b.cjs"));
21493
+ return {
21494
+ id: id30,
21495
+ diagram: diagram2
21496
+ };
21497
+ }, "loader")
21498
+ };
21499
+ var id31 = "venn";
21500
+ var vennDetector_default = {
21501
+ id: id31,
21502
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21503
+ return /^\s*venn-beta/.test(txt);
21504
+ }, "detector"),
21505
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21506
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./vennDiagram-4TSXK5OY-BoPrSQa4.cjs"));
21507
+ return {
21508
+ id: id31,
21509
+ diagram: diagram2
21510
+ };
21511
+ }, "loader")
21512
+ };
21513
+ var id32 = "treemap";
21514
+ var treemap = {
21515
+ id: id32,
21516
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21517
+ return /^\s*treemap/.test(txt);
21518
+ }, "detector"),
21519
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21520
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./diagram-VX7I27RA-DmtZpJBQ.cjs"));
21521
+ return {
21522
+ id: id32,
21523
+ diagram: diagram2
21524
+ };
21525
+ }, "loader")
21526
+ };
21527
+ var id33 = "wardley";
21528
+ var wardleyDetector_default = {
21529
+ id: id33,
21530
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((text) => {
21531
+ return /^\s*wardley-beta/i.test(text);
21532
+ }, "detector"),
21533
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21534
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./wardleyDiagram-VM6X3IG4-pRLM7H2c.cjs"));
21535
+ return {
21536
+ id: id33,
21537
+ diagram: diagram2
21538
+ };
21539
+ }, "loader")
21540
+ };
21541
+ var id34 = "cynefin";
21542
+ var cynefin = {
21543
+ id: id34,
21544
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21545
+ return /^\s*cynefin-beta(?:[\s:]|$)/.test(txt);
21546
+ }, "detector"),
21547
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21548
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./cynefinDiagram-5FMLGOSQ-Ap6hVoa3.cjs"));
21549
+ return {
21550
+ id: id34,
21551
+ diagram: diagram2
21552
+ };
21553
+ }, "loader")
21554
+ };
21555
+ var id35 = "railroad";
21556
+ var railroad = {
21557
+ id: id35,
21558
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21559
+ return /^\s*railroad-beta/i.test(txt);
21560
+ }, "detector"),
21561
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21562
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./railroadDiagram-O6MQD6OU-B1_htIeQ.cjs"));
21563
+ return {
21564
+ id: id35,
21565
+ diagram: diagram2
21566
+ };
21567
+ }, "loader")
21568
+ };
21569
+ var id36 = "railroadEbnf";
21570
+ var railroadEbnf = {
21571
+ id: id36,
21572
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21573
+ return /^\s*railroad-ebnf-beta/i.test(txt);
21574
+ }, "detector"),
21575
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21576
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./ebnfDiagram-PWID7BFC-C447qgdc.cjs"));
21577
+ return {
21578
+ id: id36,
21579
+ diagram: diagram2
21580
+ };
21581
+ }, "loader")
21582
+ };
21583
+ var id37 = "railroadAbnf";
21584
+ var railroadAbnf = {
21585
+ id: id37,
21586
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21587
+ return /^\s*railroad-abnf-beta/i.test(txt);
21588
+ }, "detector"),
21589
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21590
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./abnfDiagram-VCTEODGH-B_j4_Ip0.cjs"));
21591
+ return {
21592
+ id: id37,
21593
+ diagram: diagram2
21594
+ };
21595
+ }, "loader")
21596
+ };
21597
+ var id38 = "railroadPeg";
21598
+ var railroadPeg = {
21599
+ id: id38,
21600
+ detector: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((txt) => {
21601
+ return /^\s*railroad-peg-beta/i.test(txt);
21602
+ }, "detector"),
21603
+ loader: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21604
+ const { diagram: diagram2 } = await Promise.resolve().then(() => require("./pegDiagram-XKGWAZYB-CguB2tzQ.cjs"));
21605
+ return {
21606
+ id: id38,
21607
+ diagram: diagram2
21608
+ };
21609
+ }, "loader")
21610
+ };
21611
+ var hasLoadedDiagrams = false;
21612
+ var addDiagrams = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {
21613
+ if (hasLoadedDiagrams) return;
21614
+ hasLoadedDiagrams = true;
21615
+ require_chunk_DU6HZSFF.registerDiagram("error", errorDiagram_default, (text) => {
21616
+ return text.toLowerCase().trim() === "error";
21617
+ });
21618
+ require_chunk_DU6HZSFF.registerDiagram("---", {
21619
+ db: { clear: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {}, "clear") },
21620
+ styles: {},
21621
+ renderer: { draw: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {}, "draw") },
21622
+ parser: { parse: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {
21623
+ throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks");
21624
+ }, "parse") },
21625
+ init: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => null, "init")
21626
+ }, (text) => {
21627
+ return text.toLowerCase().trimStart().startsWith("---");
21628
+ });
21629
+ require_chunk_DU6HZSFF.registerLazyLoadedDiagrams(detector_default2, detector_default4, architectureDetector_default);
21630
+ require_chunk_DU6HZSFF.registerLazyLoadedDiagrams(c4Detector_default, detector_default5, classDetector_V2_default, classDetector_default, erDetector_default, ganttDetector_default, info, pie, requirementDetector_default, sequenceDetector_default, detector_default, flowDetector_v2_default, flowDetector_default, detector_default3, gitGraphDetector_default, stateDetector_V2_default, stateDetector_default, journeyDetector_default, quadrantDetector_default, sankeyDetector_default, packet, xychartDetector_default, blockDetector_default, detector_default7, detector_default6, radar, ishikawa, treemap, railroad, railroadEbnf, railroadAbnf, railroadPeg, vennDetector_default, wardleyDetector_default, cynefin);
21631
+ }, "addDiagrams");
21632
+ var loadRegisteredDiagrams = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
21633
+ require_src.log.debug(`Loading registered diagrams`);
21634
+ const failed = (await Promise.allSettled(Object.entries(require_chunk_DU6HZSFF.detectors).map(async ([key, { detector: detector39, loader: loader39 }]) => {
21635
+ if (!loader39) return;
21636
+ try {
21637
+ require_chunk_DU6HZSFF.getDiagram(key);
21638
+ } catch {
21639
+ try {
21640
+ const { diagram: diagram2, id: id39 } = await loader39();
21641
+ require_chunk_DU6HZSFF.registerDiagram(id39, diagram2, detector39);
21642
+ } catch (err) {
21643
+ require_src.log.error(`Failed to load external diagram with key ${key}. Removing from detectors.`);
21644
+ delete require_chunk_DU6HZSFF.detectors[key];
21645
+ throw err;
21646
+ }
21647
+ }
21648
+ }))).filter((result) => result.status === "rejected");
21649
+ if (failed.length > 0) {
21650
+ require_src.log.error(`Failed to load ${failed.length} external diagrams`);
21651
+ for (const res of failed) require_src.log.error(res);
21652
+ throw new Error(`Failed to load ${failed.length} external diagrams`);
21653
+ }
21654
+ }, "loadRegisteredDiagrams");
21655
+ var SVG_ROLE = "graphics-document document";
21656
+ function setA11yDiagramInfo(svg, diagramType) {
21657
+ svg.attr("role", SVG_ROLE);
21658
+ if (diagramType !== "") svg.attr("aria-roledescription", diagramType);
21659
+ }
21660
+ require_chunk_Y2CYZVJY.__name(setA11yDiagramInfo, "setA11yDiagramInfo");
21661
+ function addSVGa11yTitleDescription(svg, a11yTitle, a11yDesc, baseId) {
21662
+ if (svg.insert === void 0) return;
21663
+ if (a11yDesc) {
21664
+ const descId = `chart-desc-${baseId}`;
21665
+ svg.attr("aria-describedby", descId);
21666
+ svg.insert("desc", ":first-child").attr("id", descId).text(a11yDesc);
21667
+ }
21668
+ if (a11yTitle) {
21669
+ const titleId = `chart-title-${baseId}`;
21670
+ svg.attr("aria-labelledby", titleId);
21671
+ svg.insert("title", ":first-child").attr("id", titleId).text(a11yTitle);
21672
+ }
21673
+ }
21674
+ require_chunk_Y2CYZVJY.__name(addSVGa11yTitleDescription, "addSVGa11yTitleDescription");
21675
+ var Diagram = class _Diagram {
21676
+ constructor(type, text, db, parser, renderer2) {
21677
+ this.type = type;
21678
+ this.text = text;
21679
+ this.db = db;
21680
+ this.parser = parser;
21681
+ this.renderer = renderer2;
21682
+ }
21683
+ static {
21684
+ require_chunk_Y2CYZVJY.__name(this, "Diagram");
21685
+ }
21686
+ static async fromText(text, metadata = {}) {
21687
+ const config = require_chunk_DU6HZSFF.getConfig();
21688
+ const type = require_chunk_DU6HZSFF.detectType(text, config);
21689
+ text = require_chunk_75Z2AOVW.encodeEntities(text) + "\n";
21690
+ try {
21691
+ require_chunk_DU6HZSFF.getDiagram(type);
21692
+ } catch {
21693
+ const loader39 = require_chunk_DU6HZSFF.getDiagramLoader(type);
21694
+ if (!loader39) throw new require_chunk_DU6HZSFF.UnknownDiagramError(`Diagram ${type} not found.`);
21695
+ const { id: id39, diagram: diagram2 } = await loader39();
21696
+ require_chunk_DU6HZSFF.registerDiagram(id39, diagram2);
21697
+ }
21698
+ const { db, parser, renderer: renderer2, init: init2 } = require_chunk_DU6HZSFF.getDiagram(type);
21699
+ if (parser.parser) parser.parser.yy = db;
21700
+ db.clear?.();
21701
+ init2?.(config);
21702
+ if (metadata.title) db.setDiagramTitle?.(metadata.title);
21703
+ await parser.parse(text);
21704
+ return new _Diagram(type, text, db, parser, renderer2);
21705
+ }
21706
+ async render(id39, version) {
21707
+ await this.renderer.draw(this.text, id39, version, this);
21708
+ }
21709
+ getParser() {
21710
+ return this.parser;
21711
+ }
21712
+ getType() {
21713
+ return this.type;
21714
+ }
21715
+ };
21716
+ var interactionFunctions = [];
21717
+ var attachFunctions = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {
21718
+ interactionFunctions.forEach((f) => {
21719
+ f();
21720
+ });
21721
+ interactionFunctions = [];
21722
+ }, "attachFunctions");
21723
+ var cleanupComments = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((text) => {
21724
+ return text.replace(/^\s*%%(?!{)[^\n]+\n?/gm, "").trimStart();
21725
+ }, "cleanupComments");
21726
+ function extractFrontMatter(text) {
21727
+ const matches = text.match(require_chunk_DU6HZSFF.frontMatterRegex);
21728
+ if (!matches) return {
21729
+ text,
21730
+ metadata: {}
21731
+ };
21732
+ const indent = matches[1];
21733
+ const yamlBody = indent ? matches[2].split("\n").map((line) => line.startsWith(indent) ? line.slice(indent.length) : line).join("\n") : matches[2];
21734
+ let parsed = require_chunk_LNGE3PJU.load(yamlBody, { schema: require_chunk_LNGE3PJU.JSON_SCHEMA }) ?? {};
21735
+ parsed = typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
21736
+ const metadata = {};
21737
+ if (parsed.displayMode) metadata.displayMode = parsed.displayMode.toString();
21738
+ if (parsed.title) metadata.title = parsed.title.toString();
21739
+ if (parsed.config) metadata.config = parsed.config;
21740
+ return {
21741
+ text: text.slice(matches[0].length),
21742
+ metadata
21743
+ };
21744
+ }
21745
+ require_chunk_Y2CYZVJY.__name(extractFrontMatter, "extractFrontMatter");
21746
+ var cleanupText = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((code) => {
21747
+ return code.replace(/\r\n?/g, "\n").replace(/<(\w+)([^>]*)>/g, (match, tag, attributes) => "<" + tag + attributes.replace(/="([^"]*)"/g, "='$1'") + ">");
21748
+ }, "cleanupText");
21749
+ var processFrontmatter = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((code) => {
21750
+ const { text, metadata } = extractFrontMatter(code);
21751
+ const { displayMode, title, config = {} } = metadata;
21752
+ if (displayMode) {
21753
+ if (!config.gantt) config.gantt = {};
21754
+ config.gantt.displayMode = displayMode;
21755
+ }
21756
+ return {
21757
+ title,
21758
+ config,
21759
+ text
21760
+ };
21761
+ }, "processFrontmatter");
21762
+ var processDirectives = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((code) => {
21763
+ const initDirective = require_chunk_75Z2AOVW.utils_default.detectInit(code) ?? {};
21764
+ const wrapDirectives = require_chunk_75Z2AOVW.utils_default.detectDirective(code, "wrap");
21765
+ if (Array.isArray(wrapDirectives)) initDirective.wrap = wrapDirectives.some(({ type }) => type === "wrap");
21766
+ else if (wrapDirectives?.type === "wrap") initDirective.wrap = true;
21767
+ return {
21768
+ text: require_chunk_75Z2AOVW.removeDirectives(code),
21769
+ directive: initDirective
21770
+ };
21771
+ }, "processDirectives");
21772
+ function preprocessDiagram(code) {
21773
+ const frontMatterResult = processFrontmatter(cleanupText(code));
21774
+ const directiveResult = processDirectives(frontMatterResult.text);
21775
+ const config = require_chunk_75Z2AOVW.cleanAndMerge(frontMatterResult.config, directiveResult.directive);
21776
+ code = cleanupComments(directiveResult.text);
21777
+ return {
21778
+ code,
21779
+ title: frontMatterResult.title,
21780
+ config
21781
+ };
21782
+ }
21783
+ require_chunk_Y2CYZVJY.__name(preprocessDiagram, "preprocessDiagram");
21784
+ function toBase64(str) {
21785
+ const utf8Bytes = new TextEncoder().encode(str);
21786
+ const utf8Str = Array.from(utf8Bytes, (byte) => String.fromCodePoint(byte)).join("");
21787
+ return btoa(utf8Str);
21788
+ }
21789
+ require_chunk_Y2CYZVJY.__name(toBase64, "toBase64");
21790
+ var MAX_TEXTLENGTH = 5e4;
21791
+ var MAX_TEXTLENGTH_EXCEEDED_MSG = "graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa";
21792
+ var SECURITY_LVL_SANDBOX = "sandbox";
21793
+ var SECURITY_LVL_LOOSE = "loose";
21794
+ var XMLNS_SVG_STD = "http://www.w3.org/2000/svg";
21795
+ var XMLNS_XLINK_STD = "http://www.w3.org/1999/xlink";
21796
+ var XMLNS_XHTML_STD = "http://www.w3.org/1999/xhtml";
21797
+ var IFRAME_WIDTH = "100%";
21798
+ var IFRAME_HEIGHT = "100%";
21799
+ var IFRAME_STYLES = "border:0;margin:0;";
21800
+ var IFRAME_BODY_STYLE = "margin:0";
21801
+ var IFRAME_SANDBOX_OPTS = "allow-top-navigation-by-user-activation allow-popups";
21802
+ var IFRAME_NOT_SUPPORTED_MSG = "The \"iframe\" tag is not supported by your browser.";
21803
+ var DOMPURIFY_TAGS = ["foreignobject"];
21804
+ var DOMPURIFY_ATTR = ["dominant-baseline"];
21805
+ function processAndSetConfigs(text) {
21806
+ const processed = preprocessDiagram(text);
21807
+ require_chunk_DU6HZSFF.reset();
21808
+ require_chunk_DU6HZSFF.addDirective(processed.config ?? {});
21809
+ return processed;
21810
+ }
21811
+ require_chunk_Y2CYZVJY.__name(processAndSetConfigs, "processAndSetConfigs");
21812
+ async function parse(text, parseOptions) {
21813
+ addDiagrams();
21814
+ try {
21815
+ const { code, config } = processAndSetConfigs(text);
21816
+ return {
21817
+ diagramType: (await getDiagramFromText(code)).type,
21818
+ config
21819
+ };
21820
+ } catch (error) {
21821
+ if (parseOptions?.suppressErrors) return false;
21822
+ throw error;
21823
+ }
21824
+ }
21825
+ require_chunk_Y2CYZVJY.__name(parse, "parse");
21826
+ var cssImportantStyles = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((cssClass, element, cssClasses = []) => {
21827
+ return `.${cssClass} ${element} ${require_chunk_DU6HZSFF.sanitizeCss(`{ ${cssClasses.join(" !important; ")} !important; }`)}`;
21828
+ }, "cssImportantStyles");
21829
+ var createCssStyles = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((config, classDefs = /* @__PURE__ */ new Map()) => {
21830
+ const cssStyles = new CSSStyleSheet();
21831
+ if (config.fontFamily !== void 0) cssStyles.insertRule(`:root { --mermaid-font-family: ${config.fontFamily}}`, cssStyles.cssRules.length);
21832
+ if (config.altFontFamily !== void 0) cssStyles.insertRule(`:root { --mermaid-alt-font-family: ${config.altFontFamily}}`, cssStyles.cssRules.length);
21833
+ if (classDefs instanceof Map) {
21834
+ const cssElements = require_chunk_DU6HZSFF.getEffectiveHtmlLabels(config) ? ["> *", "span"] : [
21835
+ "rect",
21836
+ "polygon",
21837
+ "ellipse",
21838
+ "circle",
21839
+ "path"
21840
+ ];
21841
+ classDefs.forEach((styleClassDef) => {
21842
+ if (!isEmpty(styleClassDef.styles)) cssElements.forEach((cssElement) => {
21843
+ cssStyles.insertRule(cssImportantStyles(styleClassDef.id, cssElement, styleClassDef.styles), cssStyles.cssRules.length);
21844
+ });
21845
+ if (!isEmpty(styleClassDef.textStyles)) cssStyles.insertRule(cssImportantStyles(styleClassDef.id, "tspan", (styleClassDef?.textStyles || []).map((s) => s.replace("color", "fill"))), cssStyles.cssRules.length);
21846
+ });
21847
+ }
21848
+ let cssString = "";
21849
+ if (config.themeCSS !== void 0) {
21850
+ if (typeof cssStyles.replaceSync === "function") {
21851
+ const themeCssStyleSheet = new CSSStyleSheet();
21852
+ themeCssStyleSheet.replaceSync(config.themeCSS);
21853
+ cssString = require_chunk_DU6HZSFF.cssStyleSheetToString(themeCssStyleSheet) + "\n";
21854
+ } else cssString += `${config.themeCSS}
21855
+ `;
21856
+ }
21857
+ return cssString + require_chunk_DU6HZSFF.cssStyleSheetToString(cssStyles);
21858
+ }, "createCssStyles");
21859
+ var compileCSS = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((namespace, css) => {
21860
+ return serialize(compile(`${namespace}{${css}}`), middleware([/* @__PURE__ */ require_chunk_Y2CYZVJY.__name(function addNamespace(element, _index, _children, _callback) {
21861
+ if (element.type === "rule" && Array.isArray(element.props)) {
21862
+ if (element.parent && element.parent.type === "@keyframes") return;
21863
+ element.props = element.props.map((prop) => {
21864
+ if (prop === namespace && Array.isArray(element.children) && element.children.every((child) => {
21865
+ if (child.type !== "decl") return false;
21866
+ return (/* @__PURE__ */ new Set([
21867
+ "font-family",
21868
+ "font-size",
21869
+ "fill"
21870
+ ])).has(child.props);
21871
+ })) return prop;
21872
+ if (!((prop.startsWith(`${namespace} `) || prop.startsWith(`${namespace}>`)) && !prop.startsWith(`${namespace} ||`))) return `${namespace} ${prop}`;
21873
+ return prop;
21874
+ });
21875
+ } else if (element.type.startsWith("@")) {
21876
+ if (![...[
21877
+ "@media",
21878
+ "@supports",
21879
+ "@layer",
21880
+ "@scope",
21881
+ "@container",
21882
+ "@starting-style"
21883
+ ], "@keyframes"].includes(element.type)) {
21884
+ require_src.log.warn(`Removing unsupported at-rule ${element.type} from CSS`);
21885
+ element.type = COMMENT;
21886
+ }
21887
+ }
21888
+ }, "addNamespace"), stringify]));
21889
+ }, "compileCSS");
21890
+ var createUserStyles = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((config, graphType, classDefs, svgId) => {
21891
+ const userCSSstyles = createCssStyles(config, classDefs);
21892
+ return compileCSS(svgId, require_chunk_DU6HZSFF.styles_default(graphType, userCSSstyles, {
21893
+ ...config.themeVariables,
21894
+ theme: config.theme,
21895
+ look: config.look
21896
+ }, svgId));
21897
+ }, "createUserStyles");
21898
+ var cleanUpSvgCode = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((svgCode = "", inSandboxMode, useArrowMarkerUrls) => {
21899
+ let cleanedUpSvg = svgCode;
21900
+ if (!useArrowMarkerUrls && !inSandboxMode) cleanedUpSvg = cleanedUpSvg.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g, "marker-end=\"url(#");
21901
+ cleanedUpSvg = require_chunk_75Z2AOVW.decodeEntities(cleanedUpSvg);
21902
+ cleanedUpSvg = cleanedUpSvg.replace(/<br>/g, "<br/>");
21903
+ return cleanedUpSvg;
21904
+ }, "cleanUpSvgCode");
21905
+ var putIntoIFrame = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((svgCode = "", svgElement) => {
21906
+ return `<iframe style="width:${IFRAME_WIDTH};height:${svgElement?.viewBox?.baseVal?.height ? svgElement.viewBox.baseVal.height + "px" : IFRAME_HEIGHT};${IFRAME_STYLES}" src="data:text/html;charset=UTF-8;base64,${toBase64(`<body style="${IFRAME_BODY_STYLE}">${svgCode}</body>`)}" sandbox="${IFRAME_SANDBOX_OPTS}">
21907
+ ${IFRAME_NOT_SUPPORTED_MSG}
21908
+ </iframe>`;
21909
+ }, "putIntoIFrame");
21910
+ var appendDivSvgG = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((parentRoot, id39, enclosingDivId, divStyle, svgXlink) => {
21911
+ const enclosingDiv = parentRoot.append("div");
21912
+ enclosingDiv.attr("id", enclosingDivId);
21913
+ if (divStyle) enclosingDiv.attr("style", divStyle);
21914
+ const svgNode = enclosingDiv.append("svg").attr("id", id39).attr("width", "100%").attr("xmlns", XMLNS_SVG_STD);
21915
+ if (svgXlink) svgNode.attr("xmlns:xlink", svgXlink);
21916
+ svgNode.append("g");
21917
+ return parentRoot;
21918
+ }, "appendDivSvgG");
21919
+ function sandboxedIframe(parentNode, iFrameId) {
21920
+ return parentNode.append("iframe").attr("id", iFrameId).attr("style", "width: 100%; height: 100%;").attr("sandbox", "");
21921
+ }
21922
+ require_chunk_Y2CYZVJY.__name(sandboxedIframe, "sandboxedIframe");
21923
+ var removeExistingElements = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((doc, id39, divId, iFrameId) => {
21924
+ doc.getElementById(id39)?.remove();
21925
+ doc.getElementById(divId)?.remove();
21926
+ doc.getElementById(iFrameId)?.remove();
21927
+ }, "removeExistingElements");
21928
+ var render$1 = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async function(id39, text, svgContainingElement) {
21929
+ addDiagrams();
21930
+ const processed = processAndSetConfigs(text);
21931
+ text = processed.code;
21932
+ const config = require_chunk_DU6HZSFF.getConfig();
21933
+ require_src.log.debug(config);
21934
+ if (text.length > (config?.maxTextSize ?? MAX_TEXTLENGTH)) text = MAX_TEXTLENGTH_EXCEEDED_MSG;
21935
+ const idSelector = `#${id39}`;
21936
+ const iFrameID = "i" + id39;
21937
+ const iFrameID_selector = "#" + iFrameID;
21938
+ const enclosingDivID = "d" + id39;
21939
+ const enclosingDivID_selector = "#" + enclosingDivID;
21940
+ const removeTempElements = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {
21941
+ const node = require_src.select_default(isSandboxed ? iFrameID_selector : enclosingDivID_selector).node();
21942
+ if (node && "remove" in node) node.remove();
21943
+ }, "removeTempElements");
21944
+ let root = require_src.select_default(document.body);
21945
+ const isSandboxed = config.securityLevel === SECURITY_LVL_SANDBOX;
21946
+ const isLooseSecurityLevel = config.securityLevel === SECURITY_LVL_LOOSE;
21947
+ const fontFamily = config.fontFamily;
21948
+ if (svgContainingElement !== void 0) {
21949
+ if (svgContainingElement) svgContainingElement.innerHTML = "";
21950
+ if (isSandboxed) {
21951
+ const iframe = sandboxedIframe(require_src.select_default(svgContainingElement), iFrameID);
21952
+ root = require_src.select_default(iframe.nodes()[0].contentDocument.body);
21953
+ root.node().style.margin = "0";
21954
+ } else root = require_src.select_default(svgContainingElement);
21955
+ appendDivSvgG(root, id39, enclosingDivID, `font-family: ${fontFamily}`, XMLNS_XLINK_STD);
21956
+ } else {
21957
+ removeExistingElements(document, id39, enclosingDivID, iFrameID);
21958
+ if (isSandboxed) {
21959
+ const iframe = sandboxedIframe(require_src.select_default(document.body), iFrameID);
21960
+ root = require_src.select_default(iframe.nodes()[0].contentDocument.body);
21961
+ root.node().style.margin = "0";
21962
+ } else root = require_src.select_default("body");
21963
+ appendDivSvgG(root, id39, enclosingDivID);
21964
+ }
21965
+ let diag;
21966
+ let parseEncounteredException;
21967
+ try {
21968
+ diag = await Diagram.fromText(text, { title: processed.title });
21969
+ } catch (error) {
21970
+ if (config.suppressErrorRendering) {
21971
+ removeTempElements();
21972
+ throw error;
21973
+ }
21974
+ diag = await Diagram.fromText("error");
21975
+ parseEncounteredException = error;
21976
+ }
21977
+ const element = root.select(enclosingDivID_selector).node();
21978
+ const diagramType = diag.type;
21979
+ const svg = element.firstChild;
21980
+ const firstChild = svg.firstChild;
21981
+ const diagramClassDefs = diag.renderer.getClasses?.(text, diag);
21982
+ const rules = createUserStyles(config, diagramType, diagramClassDefs, idSelector);
21983
+ const style1 = document.createElement("style");
21984
+ style1.innerHTML = rules;
21985
+ svg.insertBefore(style1, firstChild);
21986
+ try {
21987
+ await diag.renderer.draw(text, id39, "11.17.2", diag);
21988
+ } catch (e) {
21989
+ if (config.suppressErrorRendering) removeTempElements();
21990
+ else errorRenderer_default.draw(text, id39, "11.17.2");
21991
+ throw e;
21992
+ }
21993
+ const svgNode = root.select(`${enclosingDivID_selector} svg`);
21994
+ const a11yTitle = diag.db.getAccTitle?.();
21995
+ const a11yDescr = diag.db.getAccDescription?.();
21996
+ addA11yInfo(diagramType, svgNode, a11yTitle, a11yDescr);
21997
+ const svgCode = (/* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {
21998
+ root.select(`[id="${id39}"]`).selectAll("foreignobject > *").attr("xmlns", XMLNS_XHTML_STD);
21999
+ let code = root.select(enclosingDivID_selector).node().innerHTML;
22000
+ require_src.log.debug("config.arrowMarkerAbsolute", config.arrowMarkerAbsolute);
22001
+ code = cleanUpSvgCode(code, isSandboxed, require_chunk_DU6HZSFF.evaluate(config.arrowMarkerAbsolute));
22002
+ if (isSandboxed) {
22003
+ const svgEl = root.select(enclosingDivID_selector + " svg").node();
22004
+ code = putIntoIFrame(code, svgEl);
22005
+ } else if (!isLooseSecurityLevel) code = require_chunk_DU6HZSFF.purify_default.sanitize(code, {
22006
+ ADD_TAGS: DOMPURIFY_TAGS,
22007
+ ADD_ATTR: DOMPURIFY_ATTR,
22008
+ HTML_INTEGRATION_POINTS: { foreignobject: true }
22009
+ });
22010
+ attachFunctions();
22011
+ return code;
22012
+ }, "serializeSvg"))();
22013
+ if (parseEncounteredException) throw parseEncounteredException;
22014
+ removeTempElements();
22015
+ return {
22016
+ diagramType,
22017
+ svg: svgCode,
22018
+ bindFunctions: diag.db.bindFunctions
22019
+ };
22020
+ }, "render");
22021
+ function initialize(userOptions = {}) {
22022
+ const options = require_chunk_DU6HZSFF.assignWithDepth_default({}, userOptions);
22023
+ if (options?.fontFamily && !options.themeVariables?.fontFamily) {
22024
+ if (!options.themeVariables) options.themeVariables = {};
22025
+ options.themeVariables.fontFamily = options.fontFamily;
22026
+ }
22027
+ require_chunk_DU6HZSFF.saveConfigFromInitialize(options);
22028
+ if (options?.theme && options.theme in require_chunk_DU6HZSFF.themes_default) options.themeVariables = require_chunk_DU6HZSFF.themes_default[options.theme].getThemeVariables(options.themeVariables);
22029
+ else if (options) options.themeVariables = require_chunk_DU6HZSFF.themes_default.default.getThemeVariables(options.themeVariables);
22030
+ const config = typeof options === "object" ? require_chunk_DU6HZSFF.setSiteConfig(options) : require_chunk_DU6HZSFF.getSiteConfig();
22031
+ require_src.setLogLevel(config.logLevel);
22032
+ addDiagrams();
22033
+ }
22034
+ require_chunk_Y2CYZVJY.__name(initialize, "initialize");
22035
+ var getDiagramFromText = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((text, metadata = {}) => {
22036
+ const { code } = preprocessDiagram(text);
22037
+ return Diagram.fromText(code, metadata);
22038
+ }, "getDiagramFromText");
22039
+ function addA11yInfo(diagramType, svgNode, a11yTitle, a11yDescr) {
22040
+ setA11yDiagramInfo(svgNode, diagramType);
22041
+ addSVGa11yTitleDescription(svgNode, a11yTitle, a11yDescr, svgNode.attr("id"));
22042
+ }
22043
+ require_chunk_Y2CYZVJY.__name(addA11yInfo, "addA11yInfo");
22044
+ var mermaidAPI = Object.freeze({
22045
+ render: render$1,
22046
+ parse,
22047
+ getDiagramFromText,
22048
+ initialize,
22049
+ getConfig: require_chunk_DU6HZSFF.getConfig,
22050
+ /**
22051
+ * @deprecated This function does nothing. It will be overwritten by the next
22052
+ * call to {@link render} or {@link parse}.
22053
+ */
22054
+ setConfig: require_chunk_DU6HZSFF.setConfig,
22055
+ getSiteConfig: require_chunk_DU6HZSFF.getSiteConfig,
22056
+ updateSiteConfig: require_chunk_DU6HZSFF.updateSiteConfig,
22057
+ reset: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {
22058
+ require_chunk_DU6HZSFF.reset();
22059
+ }, "reset"),
22060
+ globalReset: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {
22061
+ require_chunk_DU6HZSFF.reset(require_chunk_DU6HZSFF.defaultConfig);
22062
+ }, "globalReset"),
22063
+ defaultConfig: require_chunk_DU6HZSFF.defaultConfig
22064
+ });
22065
+ require_src.setLogLevel(require_chunk_DU6HZSFF.getConfig().logLevel);
22066
+ require_chunk_DU6HZSFF.reset(require_chunk_DU6HZSFF.getConfig());
22067
+ var handleError = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((error, errors, parseError) => {
22068
+ require_src.log.warn(error);
22069
+ if (require_chunk_75Z2AOVW.isDetailedError(error)) {
22070
+ if (parseError) parseError(error.str, error.hash);
22071
+ errors.push({
22072
+ ...error,
22073
+ message: error.str,
22074
+ error
22075
+ });
22076
+ } else {
22077
+ if (parseError) parseError(error);
22078
+ if (error instanceof Error) errors.push({
22079
+ str: error.message,
22080
+ message: error.message,
22081
+ hash: error.name,
22082
+ error
22083
+ });
22084
+ }
22085
+ }, "handleError");
22086
+ var run = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async function(options = { querySelector: ".mermaid" }) {
22087
+ try {
22088
+ await runThrowsErrors(options);
22089
+ } catch (e) {
22090
+ if (require_chunk_75Z2AOVW.isDetailedError(e)) require_src.log.error(e.str);
22091
+ if (mermaid.parseError) mermaid.parseError(e);
22092
+ if (!options.suppressErrors) {
22093
+ require_src.log.error("Use the suppressErrors option to suppress these errors");
22094
+ throw e;
22095
+ }
22096
+ }
22097
+ }, "run");
22098
+ var runThrowsErrors = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async function({ postRenderCallback, querySelector, nodes } = { querySelector: ".mermaid" }) {
22099
+ const conf = mermaidAPI.getConfig();
22100
+ require_src.log.debug(`${!postRenderCallback ? "No " : ""}Callback function found`);
22101
+ let nodesToProcess;
22102
+ if (nodes) nodesToProcess = nodes;
22103
+ else if (querySelector) nodesToProcess = document.querySelectorAll(querySelector);
22104
+ else throw new Error("Nodes and querySelector are both undefined");
22105
+ require_src.log.debug(`Found ${nodesToProcess.length} diagrams`);
22106
+ if (conf?.startOnLoad !== void 0) {
22107
+ require_src.log.debug("Start On Load: " + conf?.startOnLoad);
22108
+ mermaidAPI.updateSiteConfig({ startOnLoad: conf?.startOnLoad });
22109
+ }
22110
+ const idGenerator = new require_chunk_75Z2AOVW.utils_default.InitIDGenerator(conf.deterministicIds, conf.deterministicIDSeed);
22111
+ let txt;
22112
+ const errors = [];
22113
+ for (const element of Array.from(nodesToProcess)) {
22114
+ require_src.log.info("Rendering diagram: " + element.id);
22115
+ if (element.getAttribute("data-processed")) continue;
22116
+ element.setAttribute("data-processed", "true");
22117
+ const id39 = `mermaid-${idGenerator.next()}`;
22118
+ txt = element.innerHTML;
22119
+ txt = require_chunk_GMAD6QVW.dedent(require_chunk_75Z2AOVW.utils_default.entityDecode(txt)).trim().replace(/<br\s*\/?>/gi, "<br/>");
22120
+ const init2 = require_chunk_75Z2AOVW.utils_default.detectInit(txt);
22121
+ if (init2) require_src.log.debug("Detected early reinit: ", init2);
22122
+ try {
22123
+ const { svg, bindFunctions } = await render2(id39, txt, element);
22124
+ element.innerHTML = svg;
22125
+ if (postRenderCallback) await postRenderCallback(id39);
22126
+ if (bindFunctions) bindFunctions(element);
22127
+ } catch (error) {
22128
+ handleError(error, errors, mermaid.parseError);
22129
+ }
22130
+ }
22131
+ if (errors.length > 0) throw errors[0];
22132
+ }, "runThrowsErrors");
22133
+ var initialize2 = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(function(config) {
22134
+ mermaidAPI.initialize(config);
22135
+ }, "initialize");
22136
+ var init = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async function(config, nodes, callback) {
22137
+ require_src.log.warn("mermaid.init is deprecated. Please use run instead.");
22138
+ if (config) initialize2(config);
22139
+ const runOptions = {
22140
+ postRenderCallback: callback,
22141
+ querySelector: ".mermaid"
22142
+ };
22143
+ if (typeof nodes === "string") runOptions.querySelector = nodes;
22144
+ else if (nodes) {
22145
+ if (nodes instanceof HTMLElement) runOptions.nodes = [nodes];
22146
+ else runOptions.nodes = nodes;
22147
+ }
22148
+ await run(runOptions);
22149
+ }, "init");
22150
+ var registerExternalDiagrams = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async (diagrams, { lazyLoad = true } = {}) => {
22151
+ addDiagrams();
22152
+ require_chunk_DU6HZSFF.registerLazyLoadedDiagrams(...diagrams);
22153
+ if (lazyLoad === false) await loadRegisteredDiagrams();
22154
+ }, "registerExternalDiagrams");
22155
+ var contentLoaded = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(function() {
22156
+ if (mermaid.startOnLoad) {
22157
+ const { startOnLoad } = mermaidAPI.getConfig();
22158
+ if (startOnLoad) mermaid.run().catch((err) => require_src.log.error("Mermaid failed to initialize", err));
22159
+ }
22160
+ }, "contentLoaded");
22161
+ if (typeof document !== "undefined") window.addEventListener("load", contentLoaded, false);
22162
+ var setParseErrorHandler = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(function(parseErrorHandler) {
22163
+ mermaid.parseError = parseErrorHandler;
22164
+ }, "setParseErrorHandler");
22165
+ var executionQueue = [];
22166
+ var executionQueueRunning = false;
22167
+ var executeQueue = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async () => {
22168
+ if (executionQueueRunning) return;
22169
+ executionQueueRunning = true;
22170
+ while (executionQueue.length > 0) {
22171
+ const f = executionQueue.shift();
22172
+ if (f) try {
22173
+ await f();
22174
+ } catch (e) {
22175
+ require_src.log.error("Error executing queue", e);
22176
+ }
22177
+ }
22178
+ executionQueueRunning = false;
22179
+ }, "executeQueue");
22180
+ var parse2 = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(async (text, parseOptions) => {
22181
+ return new Promise((resolve, reject) => {
22182
+ const performCall = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => new Promise((res, rej) => {
22183
+ mermaidAPI.parse(text, parseOptions).then((r) => {
22184
+ res(r);
22185
+ resolve(r);
22186
+ }, (e) => {
22187
+ require_src.log.error("Error parsing", e);
22188
+ mermaid.parseError?.(e);
22189
+ rej(e);
22190
+ reject(e);
22191
+ });
22192
+ }), "performCall");
22193
+ executionQueue.push(performCall);
22194
+ executeQueue().catch(reject);
22195
+ });
22196
+ }, "parse");
22197
+ var render2 = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name((id39, text, container) => {
22198
+ return new Promise((resolve, reject) => {
22199
+ const performCall = /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => new Promise((res, rej) => {
22200
+ mermaidAPI.render(id39, text, container).then((r) => {
22201
+ res(r);
22202
+ resolve(r);
22203
+ }, (e) => {
22204
+ require_src.log.error("Error parsing", e);
22205
+ mermaid.parseError?.(e);
22206
+ rej(e);
22207
+ reject(e);
22208
+ });
22209
+ }), "performCall");
22210
+ executionQueue.push(performCall);
22211
+ executeQueue().catch(reject);
22212
+ });
22213
+ }, "render");
22214
+ var mermaid = {
22215
+ startOnLoad: true,
22216
+ mermaidAPI,
22217
+ parse: parse2,
22218
+ render: render2,
22219
+ init,
22220
+ run,
22221
+ registerExternalDiagrams,
22222
+ registerLayoutLoaders: require_chunk_TLUHSLCS.registerLayoutLoaders,
22223
+ initialize: initialize2,
22224
+ parseError: void 0,
22225
+ contentLoaded,
22226
+ setParseErrorHandler,
22227
+ detectType: require_chunk_DU6HZSFF.detectType,
22228
+ registerIconPacks: require_chunk_PWAF6VOD.registerIconPacks,
22229
+ getRegisteredDiagramsMetadata: /* @__PURE__ */ require_chunk_Y2CYZVJY.__name(() => {
22230
+ return Object.keys(require_chunk_DU6HZSFF.detectors).map((id39) => ({ id: id39 }));
22231
+ }, "getRegisteredDiagramsMetadata")
22232
+ };
22233
+ var mermaid_default = mermaid;
22234
+ /*! Check if previously processed */
22235
+ /*!
22236
+ * Wait for document loaded before starting the execution
22237
+ */
22238
+ //#endregion
22239
+ //#region src/client/markdown/MermaidBlock.tsx
22240
+ mermaid_default.initialize({
22241
+ startOnLoad: false,
22242
+ securityLevel: "strict",
22243
+ suppressErrorRendering: true,
22244
+ theme: "neutral",
22245
+ flowchart: { htmlLabels: false }
22246
+ });
22247
+ /** Remove executable and remotely loading SVG features before DOM insertion. */
22248
+ function sanitizeMermaidSvg(svg) {
22249
+ const document = new DOMParser().parseFromString(svg, "image/svg+xml");
22250
+ const root = document.documentElement;
22251
+ if (root.nodeName.toLowerCase() !== "svg") throw new Error("Mermaid returned invalid SVG");
22252
+ for (const element of document.querySelectorAll("script,foreignObject,iframe,object,embed,audio,video,image")) element.remove();
22253
+ for (const element of document.querySelectorAll("*")) for (const attribute of [...element.attributes]) {
22254
+ const name = attribute.name.toLowerCase();
22255
+ const value = attribute.value.trim();
22256
+ if (name.startsWith("on")) element.removeAttribute(attribute.name);
22257
+ if ((name === "href" || name === "xlink:href") && !value.startsWith("#")) element.removeAttribute(attribute.name);
22258
+ if (name === "style" && /url\(\s*["']?(?!#)/iu.test(attribute.value)) element.removeAttribute(attribute.name);
22259
+ }
22260
+ return root;
22261
+ }
22262
+ function MermaidCanvas({ diagram, zoom }) {
22263
+ const canvas = (0, react.useRef)(null);
22264
+ (0, react.useEffect)(() => {
22265
+ canvas.current?.replaceChildren(diagram.cloneNode(true));
22266
+ }, [diagram]);
22267
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
22268
+ ref: canvas,
22269
+ className: "dsh-qa-mermaid__canvas",
22270
+ style: { width: `${zoom * 100}%` }
22271
+ });
22272
+ }
22273
+ const MermaidBlock = (0, react.memo)(function MermaidBlock({ code }) {
22274
+ const reactId = (0, react.useId)();
22275
+ const renderId = (0, react.useMemo)(() => `dsh-qa-mermaid-${reactId.replace(/[^a-z0-9_-]/giu, "")}`, [reactId]);
22276
+ const [diagram, setDiagram] = (0, react.useState)();
22277
+ const [failed, setFailed] = (0, react.useState)(false);
22278
+ const [showCode, setShowCode] = (0, react.useState)(false);
22279
+ const [expanded, setExpanded] = (0, react.useState)(false);
22280
+ const [zoom, setZoom] = (0, react.useState)(1);
22281
+ (0, react.useEffect)(() => {
22282
+ let active = true;
22283
+ setDiagram(void 0);
22284
+ setFailed(false);
22285
+ mermaid_default.render(renderId, code).then(({ svg: rendered }) => {
22286
+ if (!active) return;
22287
+ try {
22288
+ setDiagram(sanitizeMermaidSvg(rendered));
22289
+ } catch {
22290
+ setFailed(true);
22291
+ }
22292
+ }, () => {
22293
+ if (active) setFailed(true);
22294
+ });
22295
+ return () => {
22296
+ active = false;
22297
+ };
22298
+ }, [code, renderId]);
22299
+ if (failed) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
22300
+ className: "dsh-qa-mermaid dsh-qa-mermaid--error",
22301
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
22302
+ role: "status",
22303
+ children: "Не удалось отобразить Mermaid-диаграмму. Показан исходный код."
22304
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeBlock, {
22305
+ code,
22306
+ lang: "mermaid"
22307
+ })]
22308
+ });
22309
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
22310
+ className: `dsh-qa-mermaid${expanded ? " dsh-qa-mermaid--expanded" : ""}`,
22311
+ "aria-label": "Диаграмма Mermaid",
22312
+ children: [
22313
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
22314
+ className: "dsh-qa-mermaid__toolbar",
22315
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: "Mermaid" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
22316
+ className: "dsh-qa-mermaid__actions",
22317
+ children: [
22318
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
22319
+ type: "button",
22320
+ onClick: () => setZoom((value) => Math.max(.5, value - .25)),
22321
+ "aria-label": "Уменьшить диаграмму",
22322
+ children: "−"
22323
+ }),
22324
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
22325
+ type: "button",
22326
+ onClick: () => setZoom(1),
22327
+ children: "По размеру"
22328
+ }),
22329
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
22330
+ type: "button",
22331
+ onClick: () => setZoom((value) => Math.min(2.5, value + .25)),
22332
+ "aria-label": "Увеличить диаграмму",
22333
+ children: "+"
22334
+ }),
22335
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
22336
+ type: "button",
22337
+ "aria-pressed": showCode,
22338
+ onClick: () => setShowCode((value) => !value),
22339
+ children: showCode ? "Скрыть код" : "Код"
22340
+ }),
22341
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
22342
+ type: "button",
22343
+ "aria-expanded": expanded,
22344
+ onClick: () => setExpanded((value) => !value),
22345
+ children: expanded ? "Закрыть" : "Во весь экран"
22346
+ })
22347
+ ]
22348
+ })]
22349
+ }),
22350
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
22351
+ className: "dsh-qa-mermaid__viewport",
22352
+ children: diagram === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
22353
+ className: "dsh-qa-mermaid__loading",
22354
+ role: "status",
22355
+ children: "Строим диаграмму…"
22356
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MermaidCanvas, {
22357
+ diagram,
22358
+ zoom
22359
+ })
22360
+ }),
22361
+ showCode ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeBlock, {
22362
+ code,
22363
+ lang: "mermaid"
22364
+ }) : null
22365
+ ]
22366
+ });
22367
+ });
22368
+ //#endregion
20289
22369
  //#region ../../node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.mjs
22370
+ var katex_exports = /* @__PURE__ */ require_src.__exportAll({
22371
+ ParseError: () => ParseError,
22372
+ SETTINGS_SCHEMA: () => SETTINGS_SCHEMA,
22373
+ __defineFunction: () => defineFunction,
22374
+ __defineMacro: () => defineMacro,
22375
+ __defineSymbol: () => defineSymbol,
22376
+ __domTree: () => __domTree,
22377
+ __parse: () => generateParseTree,
22378
+ __renderToDomTree: () => renderToDomTree,
22379
+ __renderToHTMLTree: () => renderToHTMLTree,
22380
+ __setFontMetrics: () => setFontMetrics,
22381
+ default: () => katex,
22382
+ render: () => render,
22383
+ renderToString: () => renderToString,
22384
+ version: () => version
22385
+ });
20290
22386
  /**
20291
22387
  * This is the ParseError class, which is the main error thrown by KaTeX
20292
22388
  * functions when something has gone wrong. This is used to distinguish internal
@@ -46636,11 +48732,32 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
46636
48732
  return renderError(error, expression, settings);
46637
48733
  }
46638
48734
  };
48735
+ /**
48736
+ * Generates and returns the katex build tree, with just HTML (no MathML).
48737
+ * This is used for advanced use cases (like rendering to custom output).
48738
+ */
48739
+ var renderToHTMLTree = function renderToHTMLTree(expression, options) {
48740
+ var settings = new Settings(options);
48741
+ try {
48742
+ return buildHTMLTree(parseTree(expression, settings), expression, settings);
48743
+ } catch (error) {
48744
+ return renderError(error, expression, settings);
48745
+ }
48746
+ };
48747
+ var version = "0.16.47";
48748
+ var __domTree = {
48749
+ Span,
48750
+ Anchor,
48751
+ SymbolNode,
48752
+ SvgNode,
48753
+ PathNode,
48754
+ LineNode
48755
+ };
46639
48756
  var katex = {
46640
48757
  /**
46641
48758
  * Current KaTeX version
46642
48759
  */
46643
- version: "0.16.47",
48760
+ version,
46644
48761
  /**
46645
48762
  * Renders the given LaTeX into an HTML+MathML combination, and adds
46646
48763
  * it as a child to the specified DOM node.
@@ -46685,14 +48802,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
46685
48802
  * The internal tree representation is unstable and is very likely
46686
48803
  * to change. Use at your own risk.
46687
48804
  */
46688
- __renderToHTMLTree: function renderToHTMLTree(expression, options) {
46689
- var settings = new Settings(options);
46690
- try {
46691
- return buildHTMLTree(parseTree(expression, settings), expression, settings);
46692
- } catch (error) {
46693
- return renderError(error, expression, settings);
46694
- }
46695
- },
48805
+ __renderToHTMLTree: renderToHTMLTree,
46696
48806
  /**
46697
48807
  * extends internal font metrics object with a new object
46698
48808
  * each key in the new object represents a font name
@@ -46719,14 +48829,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
46719
48829
  * The internal tree representation is unstable and is very likely
46720
48830
  * to change. Use at your own risk.
46721
48831
  */
46722
- __domTree: {
46723
- Span,
46724
- Anchor,
46725
- SymbolNode,
46726
- SvgNode,
46727
- PathNode,
46728
- LineNode
46729
- }
48832
+ __domTree
46730
48833
  };
46731
48834
  //#endregion
46732
48835
  //#region src/client/markdown/math.tsx
@@ -47053,6 +49156,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
47053
49156
  className: "dsh-qa-md-math",
47054
49157
  children: renderTexToReact(block.text, true)
47055
49158
  }, key);
49159
+ if (block.lang?.toLowerCase() === "mermaid") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MermaidBlock, { code: block.text }, key);
47056
49160
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeBlock, {
47057
49161
  code: block.text,
47058
49162
  ...block.lang === void 0 ? {} : { lang: block.lang }
@@ -49919,6 +52023,76 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
49919
52023
  };
49920
52024
  }
49921
52025
  //#endregion
52026
+ //#region src/client/user-settings/fields.tsx
52027
+ function QaSettingsField(props) {
52028
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
52029
+ className: "dsh-qa-settings__field",
52030
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
52031
+ className: "dsh-qa-settings__field-label",
52032
+ children: [props.label, props.children]
52033
+ }), props.hint === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
52034
+ className: "dsh-qa-settings__field-hint",
52035
+ children: props.hint
52036
+ })]
52037
+ });
52038
+ }
52039
+ function QaSettingsSection(props) {
52040
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
52041
+ className: "dsh-qa-settings__section",
52042
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
52043
+ className: "dsh-qa-settings__section-head",
52044
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
52045
+ className: "dsh-qa-settings__section-title",
52046
+ children: props.title
52047
+ }), props.aside]
52048
+ }), props.children]
52049
+ });
52050
+ }
52051
+ function QaSettingsToggle(props) {
52052
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
52053
+ className: "dsh-qa-settings__toggle-row",
52054
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
52055
+ className: "dsh-qa-settings__toggle",
52056
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
52057
+ type: "checkbox",
52058
+ checked: props.checked,
52059
+ disabled: props.disabled === true,
52060
+ onChange: (event) => props.onChange(event.currentTarget.checked)
52061
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
52062
+ className: "dsh-qa-settings__toggle-label",
52063
+ children: props.label
52064
+ })]
52065
+ }), props.hint === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
52066
+ className: "dsh-qa-settings__field-hint",
52067
+ children: props.hint
52068
+ })]
52069
+ });
52070
+ }
52071
+ function QaSettingsNotice(props) {
52072
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
52073
+ className: `dsh-qa-settings__notice dsh-qa-settings__notice--${props.tone}`,
52074
+ role: props.tone === "error" ? "alert" : "status",
52075
+ children: props.children
52076
+ });
52077
+ }
52078
+ function QaSettingsActions(props) {
52079
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
52080
+ className: "dsh-qa-settings__actions",
52081
+ children: props.children
52082
+ });
52083
+ }
52084
+ function QaSettingsButton(props) {
52085
+ const tone = props.tone ?? "plain";
52086
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
52087
+ type: props.type ?? "button",
52088
+ className: `dsh-qa-settings__button dsh-qa-settings__button--${tone}`,
52089
+ disabled: props.disabled === true,
52090
+ ...props.title === void 0 ? {} : { title: props.title },
52091
+ ...props.onClick === void 0 ? {} : { onClick: props.onClick },
52092
+ children: props.label
52093
+ });
52094
+ }
52095
+ //#endregion
49922
52096
  //#region src/client/components/QaModal.tsx
49923
52097
  /**
49924
52098
  * Open dialogs, innermost last. A dialog opened from another one (the tool
@@ -49999,8 +52173,43 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
49999
52173
  }
50000
52174
  //#endregion
50001
52175
  //#region src/client/components/QaChangelog.tsx
50002
- const QA_VERSION = "0.11.2";
52176
+ const QA_VERSION = "0.13.0";
50003
52177
  const QA_CHANGELOG = [
52178
+ {
52179
+ version: "0.13.0",
52180
+ date: "2026-09-24",
52181
+ sections: [{
52182
+ title: "Новое",
52183
+ items: ["Диаграммы в блоках Mermaid теперь открываются прямо в ответе: их можно увеличить, подогнать по ширине, развернуть на весь экран и переключить на исходный код. Если синтаксис диаграммы неверен, чат не ломается и показывает код с понятным предупреждением.", "Стенд добирает оценки, которые нажимали до исправления. Пока отзыв не умел передаваться на стенд, 👍 и 👎 оставались только в браузере того, кто их нажал: в списке оценок, в очереди на разбор и в метриках качества не было ни одной. Теперь при первом входе в свою учётную запись браузер один раз передаёт стенду те из своих оценок, которые относятся к чатам этой учётной записи и которые можно сопоставить с ответом в журнале. Уже записанный отзыв стенд не перезаписывает: оценка с причиной и комментарием остаётся такой, какой её сдали в момент нажатия, — а разовость сбора помечается у себя, чтобы при следующем входе то же самое не предлагать. Учётная запись на другом браузере добирает свои оценки сама. Оценки самых первых версий, где список отзывов был один на весь стенд и не был привязан к чату, остаются в браузере: по ним нельзя понять, к какому разговору их нажимали, а угадывать стенд не стал."]
52184
+ }, {
52185
+ title: "Исправления",
52186
+ items: [
52187
+ "Диалог смены роли получил оформление стенда: кнопки, состояния наведения и фокуса больше не выглядят как элементы браузера без стилей.",
52188
+ "Поиск по документации принимает безопасные регулярные выражения: варианты слова можно перечислить через |, например бригадир|бригадира|бригада. Путь может быть относительным внутри docs или абсолютным внутри опубликованного дерева; версия и модуль продолжают ограничивать область поиска.",
52189
+ "Загрузки через web_fetch_file и web_fetch_image теперь сохраняются среди источников ответа, даже когда инструмент не передал отдельные метаданные представления.",
52190
+ "Страницы консоли администратора — «Обзор», «Разговоры», «Аналитика» и «Очередь разбора» — открываются сразу, а не минутами, и больше не задерживают всё остальное. На стенде с настоящей историей эти страницы ждали больше четырёх с половиной минут, и пока одна из них грузилась, остальные вызовы админки стояли в очереди: браузер держит с одного адреса не больше нескольких соединений. Причина была в том, сколько журналов разговоров страница перечитывает. Список разговоров открывал журнал каждого разговора стенда, чтобы отфильтровать список, который ни о чём не спрашивали, — название разговора нужно только когда кто-то ищет, а на странице двадцать пять строк. Агрегатные страницы перечитывали две сотни свежих журналов при каждой загрузке, хотя чтение одного журнала на стенде перед собой перечисляет все сохранённые разговоры развёртывания и проигрывает журнал целиком; при этом кэш журналов был меньше окна, которое этими страницами сканируется, поэтому одна страница выбрасывала то, что только что прочитала другая. Теперь журнал читается только там, где фильтр действительно о нём спрашивает: список без поиска стоит ровно его показанные строки. Разговор, который стенд уже не держит открытым, не может получить новых сообщений, поэтому его проекция остаётся в кэше, а не устаревает каждые тридцать секунд — для разговора, который пишется прямо сейчас, устаревание сохранено. Счётчики сообщений и сбои инструментов собираются за один проход по окну, а страница, которой нужно то же окно, присоединяется к уже идущему проходу вместо второго скана по тем же журналам. И все четыре страницы теперь слышат отмену: ушли со страницы, которая не отвечает, — чтение журналов останавливается на следующем разговоре, а не дочитывает их все ради ответа, который уже никто не ждёт.",
52191
+ "Источники ответа снова собираются в настоящем чате. Правая рейка, доказательства чата и превью файлов опираются на список источников разговора: стенд ведёт его за спиной помощника и записывает туда каждый прочитанный файл, открытую страницу и вызванный инструмент. На развёрнутом стенде этот список оставался пустым — стенд сопоставлял ответ инструмента с его вызовом по одному имени поля, а харнесс подписывает это сопоставление другим; инструменты отрабатывали, ответ приходил, а источников в нём не было. Теперь сопоставление читается правильно: в ответе видны источники, по клику открывается превью только что прочитанного файла, и отказ «источник больше не входит в доказательства этого чата» перестаёт звучать на файл, который только что был в ответе."
52192
+ ]
52193
+ }]
52194
+ },
52195
+ {
52196
+ version: "0.12.0",
52197
+ date: "2026-09-22",
52198
+ sections: [{
52199
+ title: "Новое",
52200
+ items: ["Стенд может назвать редакцию документации, по которой отвечает. Корпус публикуется сразу в нескольких редакциях — одна и та же глава про монтаж или про интеграцию лежит отдельно для 3.7 и для 3.8, — и вопрос «как настроить интеграцию» попадал в ту редакцию, которая встретилась поиску первой. Теперь в настройках, в разделе «Документация», задаётся версия по умолчанию: поиск, которому не назвали версию и не сузили подкаталог, ищет только по ней. Версия, названная в самом вопросе к поиску или в пути, сильнее умолчания — спросить про другую редакцию по-прежнему можно. Рядом видно, откуда стенд читает документацию: общий корпус развёртывания или каталог docs рабочего каталога чата. В ответе поиска видно, что редакцию подставил стенд, а не спрашивающий: «version 3.8, the stand's default»."]
52201
+ }, {
52202
+ title: "Исправления",
52203
+ items: [
52204
+ "Первое сообщение нового чата больше не исчезает. После создания разговора стенд закрепляет его за учётной записью; это обновление списка чатов ошибочно перезапускало контроллер ровно между проверкой допуска и отправкой вопроса. Поле ввода уже очищалось, вопрос на мгновение появлялся в переписке, затем снова показывался пустой экран, а ошибки не было. Теперь изменение списка принадлежащих пользователю чатов не считается новым входом: первый вопрос остаётся на экране и доходит до только что созданного разговора.",
52205
+ "Удаление чата из истории теперь требует явного подтверждения. Первый клик открывает диалог с названием чата и пояснением, что удаляется запись этого браузера, а сам разговор остаётся на стенде; действие можно отменить кнопкой, крестиком, кликом по фону или Escape.",
52206
+ "Настройки документации применяются без перезапуска стенда. Смена общего корня или версии по умолчанию раньше меняла карточку настроек, но уже созданные инструменты продолжали читать прежний снимок. Заодно общий каталог может называться не только docs — в ответах путь всё равно остаётся привычным docs/…, редакция V2 совпадает с v2, исключённые редакции не расходуют предел обхода, а поиск по явно заданному пути не приписывает выбор версии умолчанию стенда.",
52207
+ "Права роли больше не расширяются самим фактом подключения динамического набора инструментов. В чате с учётной записью инструмент доступен только тогда, когда он указан в роли или выдан разрешённым навыком; подключённый к агенту, но не разрешённый ролью инструмент получает отказ до выполнения.",
52208
+ "Поиск по документации находит документы, а не описи. У корпуса есть служебные каталоги рядом с документами — дерево картинок, описи, разбор спорных случаев, — и поиск читал их первыми: подчёркивание в имени сортируется раньше букв, а опись перечисляет все модули и версии корпуса, поэтому она отвечала на любой вопрос о продукте и выбирала весь лимит ответа до того, как открывался первый документ. На стенде с таким корпусом поиск без указания пути не находил вообще ничего: обход считал картинки, упирался в предел и останавливался, не дойдя до текстов. Теперь порядок обхода — документы, затем отдельные файлы, затем служебные каталоги; очередь каталогов решается путём, а не порядком обнаружения (служебная опись в корне больше не опережает документ модуля на уровень глубже); картинки, архивы и офисные файлы узнаются по расширению и не читаются вовсе; ни они, ни файлы вне выбранной области не расходуют предел прочитанных документов. Поиск, который ничего не нашёл, теперь говорит это, прочитав корпус.",
52209
+ "Фильтры «версия» и «модуль» снова работают. Ответ поиска называет редакцию и модуль, по которым он искал, но в объявленной схеме ответа эти два поля не были описаны, а стенд отказывает в ответе с неописанным полем: каждый вызов с фильтром падал с «returned invalid output» уже после выполненного поиска — то есть ровно тот вызов, ради которого фильтры и сделаны. Оба поля объявлены."
52210
+ ]
52211
+ }]
52212
+ },
50004
52213
  {
50005
52214
  version: "0.11.2",
50006
52215
  date: "2026-09-22",
@@ -50088,16 +52297,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50088
52297
  "Вопрос, на который уже нельзя ответить, больше не остаётся на экране. Запрос жил до тех пор, пока его не закроют: при остановке хода вопрос снимался по сигналу самого вызова, но запрос без такого сигнала или ход, завершившийся другим путём, оставляли форму навсегда — ответ на неё уходил в никуда, а оператор видел живое на вид поле. Теперь стенд закрывает всё, что осталось от хода, как только спросивший помощник перестаёт работать, а страница продолжает сверяться со стендом, пока форма на экране: ответ, которого стенд уже не ждёт, отклоняется вместо тихой отправки.",
50089
52298
  "Вопрос, оставшийся до перезагрузки страницы, снова появляется после неё. Страница читает список вопросов чата сразу при его открытии и при каждом восстановлении связи, а не только пока идёт ход: раньше перезагрузка могла показать пустое поле ввода, за которым агент продолжал ждать ответа.",
50090
52299
  "Сбой при чтении персональных навыков одного аккаунта больше не прячет навыки у всех. Чтение каталога навыков, которому не повезло с файловой системой (отказ доступа, гонка чтения каталога), отдавало ошибку в реестр навыков харнесса, и тот в ответ переставал публиковать список доступных навыков целиком: модель получала «навык недоступен» на любое имя, включая навыки плагинов и корпоративные. Теперь такой сбой вырождается в «у этого аккаунта навыков не прочитано» и пишется в журнал событием skill.discover-failed, а остальной каталог продолжает публиковаться.",
50091
- "Раздел «Общие возможности» в консоли администратора снова видит навыки и инструменты, которые монтирует агентский пресет. Список читался «глобально», а каталог навыков стенда и семейство инструментов пресета живут в области видимости пресета: администратор не видел ни корпоративных навыков поиска, ни инструментов пресета и не мог ничего из них выдать или отозвать. Теперь страница читает реестры глазами того пресета, под которым идут QA-чаты (задаётся session.agentPreset, на стенде это qa-research), а если пресет не удалось собрать — как и раньше остаётся глобальный вид, и страница не падает."
52300
+ "Раздел «Общие возможности» в консоли администратора снова видит навыки и инструменты, которые монтирует агентский пресет. Список читался «глобально», а каталог навыков стенда и семейство инструментов пресета живут в области видимости пресета: администратор не видел ни корпоративных навыков поиска, ни инструментов пресета и не мог ничего из них выдать или отозвать. Теперь страница читает реестры глазами того пресета, под которым идут QA-чаты (задаётся session.agentPreset, на стенде это qa-research), а если пресет не удалось собрать — как и раньше остаётся глобальный вид, и страница не падает.",
52301
+ "Стенд больше не принимает давно не открывавшийся разговор за удалённый: перед очисткой он сверяется и с долговременным хранилищем, а при неполном ответе ничего не удаляет.",
52302
+ "После настоящего удаления разговора больше не остаются оценки, очередь на разбор и другие служебные записи; админка обновляет это состояние при открытии."
50092
52303
  ]
50093
52304
  },
50094
52305
  {
50095
52306
  title: "Прочее",
50096
- items: ["Оператору стенда: настройка вопросов, которая ничего не делает, теперь видна в журнале и в карточке настроек. Если вопросы включены, а инструмент ask_user_question не входит в список разрешённых (lockdown.toolPolicy.allow), форма не появится никогда; если инструмент разрешён, а вопросы выключены, каждый запрос отклоняется. Оба случая пишут в журнал одно предупреждение question.config-incomplete на чат с указанием, какой половины не хватает, а в разделе «Состояние» появилась плашка «Вопросы модели» с тем же предупреждением — сам чат при этом открывается как обычно.", "Оператору стенда: в журнале появились события о ходе вопроса — запрос принят и ждёт ответа (question.claimed), ответ получен (question.answered), вопрос закрыт оператором (question.cancelled) или снят вместе с ходом (question.aborted), запрос отдан другому интерфейсу (question.delegated), ответ отклонён (question.refused). Текст ответа в журнал не попадает: только число вопросов и то, был ли среди ответов свободный текст."]
52307
+ items: [
52308
+ "Оператору стенда: настройка вопросов, которая ничего не делает, теперь видна в журнале и в карточке настроек. Если вопросы включены, а инструмент ask_user_question не входит в список разрешённых (lockdown.toolPolicy.allow), форма не появится никогда; если инструмент разрешён, а вопросы выключены, каждый запрос отклоняется. Оба случая пишут в журнал одно предупреждение question.config-incomplete на чат с указанием, какой половины не хватает, а в разделе «Состояние» появилась плашка «Вопросы модели» с тем же предупреждением — сам чат при этом открывается как обычно.",
52309
+ "Оператору стенда: в журнале появились события о ходе вопроса — запрос принят и ждёт ответа (question.claimed), ответ получен (question.answered), вопрос закрыт оператором (question.cancelled) или снят вместе с ходом (question.aborted), запрос отдан другому интерфейсу (question.delegated), ответ отклонён (question.refused). Текст ответа в журнал не попадает: только число вопросов и то, был ли среди ответов свободный текст.",
52310
+ "Оператору стенда: разговоры из личных папок посетителей ожидаемо остаются в разделе Ungrouped. Для старых разговоров, чей каталог совпадает с рабочей областью, добавлена безопасная команда qa-attach-sessions с предварительным просмотром и резервной копией."
52311
+ ]
50097
52312
  },
50098
52313
  {
50099
52314
  title: "Новое",
50100
- items: ["В конфигурации стенда значение enabled для interaction.questions означает то же, что и interactive: включать вопросы модели стало можно любым из двух написаний."]
52315
+ items: ["В конфигурации стенда значение enabled для interaction.questions означает то же, что и interactive: включать вопросы модели стало можно любым из двух написаний.", "Администратор может удалить разговор со стенда вместе со служебными сессиями, оценками, разбором и источниками. Удаление требует подтверждения, записывается в журнал действий и отказывается работать, если разговор ещё открыт или хранилище нельзя безопасно очистить."]
50101
52316
  }
50102
52317
  ]
50103
52318
  },
@@ -50107,7 +52322,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50107
52322
  sections: [
50108
52323
  {
50109
52324
  title: "Новое",
50110
- items: ["Администратор может удалить разговор со стенда. Раньше удалить разговор было нечем: кнопка «Удалить чат» в списке убирает строку только в вашем браузере, и после перезагрузки чат возвращался, поэтому сломанные или ненужные разговоры оставались на стенде навсегда. На странице разговора в админке появилась кнопка «Удалить разговор»: она спрашивает подтверждение и удаляет сам разговор, его служебные сессии вместе с ним, оценки, разбор и собранные источники. В списке чатов кнопка осталась прежней — она по-прежнему скрывает строку только у вас.", "Удаление доступно только администратору и записывается в журнал действий. Если разговор сейчас открыт на стенде, удаление откажется работать — сначала нужно, чтобы стенд его отпустил, иначе разговор вернётся при следующей записи. Там, где стенд хранит журналы не файлами, удаление тоже недоступно, и об этом будет сказано прямо, а не сделано наполовину."]
52325
+ items: []
50111
52326
  },
50112
52327
  {
50113
52328
  title: "Исправления",
@@ -50115,20 +52330,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50115
52330
  "Ответы агента стали заметно отзывчивее на загруженном стенде: раньше данные о том, какие документы и страницы агент прочитал, хранились в одном общем файле стенда, и каждый ход агента — включая ходы всех его помощников — переписывал этот файл целиком. Стоимость хода росла вместе со всей накопленной историей стенда: на реальных данных один ход стоил от 7 миллисекунд на небольшом стенде до 106 на большом, и всё это время сервер не отвечал никому из пользователей. Теперь данные каждого чата лежат отдельно, и ход переписывает только свой чат: на том же объёме — 4.2 миллисекунды вместо 106. Разбор ответа и панель источников работают как раньше.",
50116
52331
  "Открытие чата больше не переписывает все данные стенда. Список пользователей и записи о том, кому принадлежит какой чат, лежали в одном файле настроек, и он целиком перезаписывался при каждом действии — а записей становится на одну больше с каждым созданным чатом, так что со временем это становилось всё дороже. Теперь каждое действие записывает только своё изменение, и открытие чата стоит одинаково на стенде любого возраста.",
50117
52332
  "Удалённые чаты больше не копятся в консоли администратора. Запись о том, кому принадлежит чат, переживала сам чат: «удалить» в браузере лишь скрывало его, а серверный список возвращал обратно, поэтому в «Разговорах», в счётчиках и в аналитике навсегда оставались чаты, которых уже нет. Теперь при создании новых чатов стенд убирает записи о тех, которых больше нет на стенде, — и никогда не трогает записи существующих чатов, даже очень старых.",
50118
- "Стенд больше не убирает записи о существующих чатах. Убирая из «Разговоров» чаты, которых нет, стенд спрашивал только о тех, что открывались после последнего запуска: чат, к которому сутки не обращались, выглядел как удалённый, и запись о нём исчезала — разговор пропадал из истории своего владельца, из счётчиков и из аналитики, хотя сам он был цел. Теперь стенд сверяется и с тем, что лежит в хранилище, а если ответить наверняка не может, не убирает ничего.",
50119
- "Удалённый чат больше не оставляет после себя оценок и очереди на разбор. Оценки ответов, вердикты рецензентов и очередь на разбор хранились по идентификатору чата и переживали его: в «Обратной связи», в очереди и в аналитике оставались записи о разговоре, которого уже нет, а открыть его было нельзя. Теперь вместе с записью о владении убираются и они; журнал действий администраторов остаётся нетронутым.",
50120
- "Админка показывает состояние на момент открытия: «Разговоры», счётчики и аналитика больше не ждут, пока кто-нибудь создаст новый чат, чтобы убрать из списка исчезнувшие.",
50121
52333
  "Файл настроек стенда стал в разы меньше: политика доступа каждого чата хранилась в нём отдельной копией, хотя у всех чатов она одна и та же. На одном стенде из 25 копий различными оказались две — эта часть уменьшилась без потери данных: каждый чат по-прежнему помнит именно тот набор возможностей, с которым был открыт.",
50122
52334
  "Обновление стенда до этой версии сохраняет все учётные записи, пароли и привязку чатов к пользователям: прежний файл настроек переносится автоматически при первом запуске, а сам файл не удаляется, а сохраняется рядом с пометкой о переносе."
50123
52335
  ]
50124
52336
  },
50125
52337
  {
50126
52338
  title: "Прочее",
50127
- items: [
50128
- "У хранения данных чатов появился предел: на чат сохраняются источники последних 200 ходов, на стенде — 500 последних чатов, а чат, к которому не обращались месяц, освобождает место. Это касается только служебных данных разбора: сам текст разговора не удаляется, старый чат открывается как раньше, но панель источников у него может быть пустой.",
50129
- "Оператору стенда: пределы хранения настраиваются (сколько ходов и чатов держать, через сколько дней освобождать, как часто убирать записи о несуществующих чатах). Значения по умолчанию подобраны под обычную нагрузку, менять их не обязательно.",
50130
- "Оператору стенда: в списке чатов DSH разговоры стенда показываются в разделе «Ungrouped». Так и должно быть при включённых личных папках посетителей: чат работает в своей папке внутри рабочей области, а список группирует только те чаты, чей рабочий каталог совпадает с рабочей областью целиком, и перенести чат в область задним числом нельзя. Исключение — чаты, созданные прежней настройкой, когда рабочий каталог задавался напрямую (или задавался тем же каталогом, но записанным иначе, например через прямые слэши): их можно вернуть в рабочую область командой qa-attach-sessions при остановленном стенде — она сначала показывает, что изменит, а с ключом --write вносит правку и сохраняет копию реестра рабочей области. На чаты посетителей с личными папками команда не влияет."
50131
- ]
52339
+ items: ["У хранения данных чатов появился предел: на чат сохраняются источники последних 200 ходов, на стенде — 500 последних чатов, а чат, к которому не обращались месяц, освобождает место. Это касается только служебных данных разбора: сам текст разговора не удаляется, старый чат открывается как раньше, но панель источников у него может быть пустой.", "Оператору стенда: пределы хранения настраиваются (сколько ходов и чатов держать, через сколько дней освобождать, как часто убирать записи о несуществующих чатах). Значения по умолчанию подобраны под обычную нагрузку, менять их не обязательно."]
50132
52340
  },
50133
52341
  {
50134
52342
  title: "Исправления",
@@ -50408,12 +52616,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50408
52616
  className: "dsh-qa-changelog__date",
50409
52617
  children: entry.date
50410
52618
  }),
50411
- entry.version === "0.11.2" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
52619
+ entry.version === "0.13.0" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
50412
52620
  className: "dsh-qa-changelog__current",
50413
52621
  children: "текущая"
50414
52622
  }) : null
50415
52623
  ]
50416
- }), entry.sections.map((section) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
52624
+ }), entry.sections.map((section, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50417
52625
  className: "dsh-qa-changelog__section",
50418
52626
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
50419
52627
  className: "dsh-qa-changelog__section-title",
@@ -50422,7 +52630,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50422
52630
  className: "dsh-qa-changelog__list",
50423
52631
  children: section.items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: item }, item))
50424
52632
  })]
50425
- }, section.title))]
52633
+ }, `${section.title}:${index}`))]
50426
52634
  }, entry.version))
50427
52635
  });
50428
52636
  }
@@ -50839,13 +53047,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50839
53047
  });
50840
53048
  const normalizedQuery = query.trim().toLowerCase();
50841
53049
  const visibleRows = normalizedQuery === "" ? props.rows : props.rows.filter((row) => rowMatches(row, normalizedQuery));
50842
- const confirmingVisible = confirmingId !== null && props.rows.some((row) => row.id === confirmingId);
53050
+ const confirmingRow = confirmingId === null ? void 0 : props.rows.find((row) => row.id === confirmingId);
50843
53051
  const sections = props.groupByOwner === true ? buildOwnerSections(visibleRows) : [{
50844
53052
  name: "",
50845
53053
  rows: visibleRows
50846
53054
  }];
50847
53055
  const renderRow = (row) => {
50848
- const confirming = confirmingVisible && confirmingId === row.id;
50849
53056
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
50850
53057
  className: row.active ? "dsh-qa-sidebar__item dsh-qa-sidebar__item--active" : "dsh-qa-sidebar__item",
50851
53058
  children: [
@@ -50877,22 +53084,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50877
53084
  })(),
50878
53085
  props.onDelete === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
50879
53086
  type: "button",
50880
- className: confirming ? "dsh-qa-sidebar__item-delete dsh-qa-sidebar__item-delete--confirm" : "dsh-qa-sidebar__item-delete",
50881
- "aria-label": confirming ? "Подтвердить удаление чата" : "Удалить чат",
50882
- title: confirming ? "Нажмите ещё раз для удаления" : "Удалить чат",
50883
- onClick: () => {
50884
- if (confirming) {
50885
- setConfirmingId(null);
50886
- props.onDelete?.(row.id);
50887
- return;
50888
- }
50889
- setConfirmingId(row.id);
50890
- },
50891
- children: confirming ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
50892
- viewBox: "0 0 16 16",
50893
- "aria-hidden": "true",
50894
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m3.5 8.5 3 3L12.5 5" })
50895
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
53087
+ className: "dsh-qa-sidebar__item-delete",
53088
+ "aria-label": "Удалить чат",
53089
+ title: "Удалить чат",
53090
+ onClick: () => setConfirmingId(row.id),
53091
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
50896
53092
  viewBox: "0 0 16 16",
50897
53093
  "aria-hidden": "true",
50898
53094
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2.5 4h11M6.5 4V2.5h3V4m-6.2 0 .6 9.5h7.2L12 4" })
@@ -51030,6 +53226,32 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
51030
53226
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QaChangelogModal, {
51031
53227
  open: changelogOpen,
51032
53228
  onClose: () => setChangelogOpen(false)
53229
+ }),
53230
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QaModal, {
53231
+ open: confirmingRow !== void 0,
53232
+ title: "Удалить чат",
53233
+ closeLabel: "Закрыть подтверждение удаления чата",
53234
+ onClose: () => setConfirmingId(null),
53235
+ footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(QaSettingsButton, {
53236
+ label: "Отмена",
53237
+ onClick: () => setConfirmingId(null)
53238
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QaSettingsButton, {
53239
+ tone: "danger",
53240
+ label: "Удалить из истории",
53241
+ onClick: () => {
53242
+ if (confirmingRow === void 0) return;
53243
+ setConfirmingId(null);
53244
+ props.onDelete?.(confirmingRow.id);
53245
+ }
53246
+ })] }),
53247
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
53248
+ className: "dsh-qa-settings__lead",
53249
+ children: [
53250
+ "Удалить чат «",
53251
+ confirmingRow?.title ?? "Новый чат",
53252
+ "» из истории в этом браузере? Сам разговор останется на стенде."
53253
+ ]
53254
+ })
51033
53255
  })
51034
53256
  ]
51035
53257
  });
@@ -52497,76 +54719,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
52497
54719
  return `${title.slice(0, 51).trimEnd()}…`;
52498
54720
  }
52499
54721
  //#endregion
52500
- //#region src/client/user-settings/fields.tsx
52501
- function QaSettingsField(props) {
52502
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
52503
- className: "dsh-qa-settings__field",
52504
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
52505
- className: "dsh-qa-settings__field-label",
52506
- children: [props.label, props.children]
52507
- }), props.hint === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
52508
- className: "dsh-qa-settings__field-hint",
52509
- children: props.hint
52510
- })]
52511
- });
52512
- }
52513
- function QaSettingsSection(props) {
52514
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
52515
- className: "dsh-qa-settings__section",
52516
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
52517
- className: "dsh-qa-settings__section-head",
52518
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
52519
- className: "dsh-qa-settings__section-title",
52520
- children: props.title
52521
- }), props.aside]
52522
- }), props.children]
52523
- });
52524
- }
52525
- function QaSettingsToggle(props) {
52526
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
52527
- className: "dsh-qa-settings__toggle-row",
52528
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
52529
- className: "dsh-qa-settings__toggle",
52530
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
52531
- type: "checkbox",
52532
- checked: props.checked,
52533
- disabled: props.disabled === true,
52534
- onChange: (event) => props.onChange(event.currentTarget.checked)
52535
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
52536
- className: "dsh-qa-settings__toggle-label",
52537
- children: props.label
52538
- })]
52539
- }), props.hint === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
52540
- className: "dsh-qa-settings__field-hint",
52541
- children: props.hint
52542
- })]
52543
- });
52544
- }
52545
- function QaSettingsNotice(props) {
52546
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
52547
- className: `dsh-qa-settings__notice dsh-qa-settings__notice--${props.tone}`,
52548
- role: props.tone === "error" ? "alert" : "status",
52549
- children: props.children
52550
- });
52551
- }
52552
- function QaSettingsActions(props) {
52553
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
52554
- className: "dsh-qa-settings__actions",
52555
- children: props.children
52556
- });
52557
- }
52558
- function QaSettingsButton(props) {
52559
- const tone = props.tone ?? "plain";
52560
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
52561
- type: props.type ?? "button",
52562
- className: `dsh-qa-settings__button dsh-qa-settings__button--${tone}`,
52563
- disabled: props.disabled === true,
52564
- ...props.title === void 0 ? {} : { title: props.title },
52565
- ...props.onClick === void 0 ? {} : { onClick: props.onClick },
52566
- children: props.label
52567
- });
52568
- }
52569
- //#endregion
52570
54722
  //#region src/client/user-settings/GeneralSettingsPage.tsx
52571
54723
  /**
52572
54724
  * Placeholder with a purpose: the section exists so the dialog has a home for
@@ -55223,35 +57375,69 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
55223
57375
  return message;
55224
57376
  }
55225
57377
  /**
57378
+ * One cancellable request slot. A page that starts a second request has stopped
57379
+ * waiting for the first, and a page that is gone waits for nothing at all —
57380
+ * either way the abandoned call should end instead of holding its connection and
57381
+ * the deployment's log reader open. The aggregate pages take minutes to answer on
57382
+ * a real store, so an abandoned page used to keep working long after the reviewer
57383
+ * moved on, and the calls it queued behind it paid for that.
57384
+ */
57385
+ function useRequestSlot() {
57386
+ const current = (0, react.useRef)(void 0);
57387
+ const start = (0, react.useCallback)(() => {
57388
+ current.current?.abort();
57389
+ const controller = new AbortController();
57390
+ current.current = controller;
57391
+ return controller;
57392
+ }, []);
57393
+ const cancel = (0, react.useCallback)(() => {
57394
+ current.current?.abort();
57395
+ current.current = void 0;
57396
+ }, []);
57397
+ (0, react.useEffect)(() => cancel, [cancel]);
57398
+ return (0, react.useMemo)(() => ({
57399
+ start,
57400
+ cancel
57401
+ }), [start, cancel]);
57402
+ }
57403
+ /**
55226
57404
  * Load one administrative resource, keeping the previous value visible while
55227
57405
  * it refreshes. Reviewers page through lists while new conversations arrive;
55228
57406
  * blanking the table on every reload would make that unusable.
57407
+ *
57408
+ * `load` receives the cancellation of the call it is making: pass it on to the
57409
+ * Remote, and a page the reviewer left stops being read on the server.
55229
57410
  */
55230
57411
  function useAdminResource(load, deps) {
55231
57412
  const [data, setData] = (0, react.useState)();
55232
57413
  const [error, setError] = (0, react.useState)();
55233
57414
  const [loading, setLoading] = (0, react.useState)(true);
57415
+ const request = useRequestSlot();
55234
57416
  const apply = (0, react.useCallback)((value) => {
55235
57417
  setData(value);
55236
57418
  setError(void 0);
55237
57419
  }, []);
55238
57420
  const reload = (0, react.useCallback)(async () => {
57421
+ const controller = request.start();
55239
57422
  setLoading(true);
55240
57423
  try {
55241
- const result = await load();
57424
+ const result = await load(controller.signal);
57425
+ if (controller.signal.aborted) return;
55242
57426
  if (result.ok) {
55243
57427
  setData(result.value);
55244
57428
  setError(void 0);
55245
57429
  } else setError(errorMessage$1(result.error));
55246
57430
  } catch (cause) {
57431
+ if (controller.signal.aborted) return;
55247
57432
  setError(errorMessage$1(cause));
55248
57433
  } finally {
55249
- setLoading(false);
57434
+ if (!controller.signal.aborted) setLoading(false);
55250
57435
  }
55251
57436
  }, deps);
55252
57437
  (0, react.useEffect)(() => {
55253
57438
  reload();
55254
- }, [reload]);
57439
+ return request.cancel;
57440
+ }, [reload, request]);
55255
57441
  return {
55256
57442
  data,
55257
57443
  error,
@@ -55352,7 +57538,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
55352
57538
  });
55353
57539
  }
55354
57540
  function AdminOverview(props) {
55355
- const { data, error, reload } = useAdminResource(() => props.api.overview(props.token), [props.api, props.token]);
57541
+ const { data, error, reload } = useAdminResource((signal) => props.api.overview(props.token, signal), [props.api, props.token]);
55356
57542
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
55357
57543
  className: "dsh-qa-admin__page",
55358
57544
  "aria-label": "Обзор",
@@ -55506,14 +57692,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
55506
57692
  const [rows, setRows] = (0, react.useState)([]);
55507
57693
  const [cursor, setCursor] = (0, react.useState)(null);
55508
57694
  const [total, setTotal] = (0, react.useState)(0);
57695
+ const request = useRequestSlot();
55509
57696
  const load = async (next, append) => {
55510
- const result = await props.api.reviewQueue(props.token, next, PAGE_SIZE$3);
55511
- if (!result.ok) return;
57697
+ const controller = request.start();
57698
+ const result = await props.api.reviewQueue(props.token, next, PAGE_SIZE$3, controller.signal);
57699
+ if (controller.signal.aborted || !result.ok) return;
55512
57700
  setTotal(result.value.total);
55513
57701
  setCursor(result.value.nextCursor);
55514
57702
  setRows((current) => append ? [...current, ...result.value.items] : result.value.items);
55515
57703
  };
55516
- const resource = useAdminResource(() => props.api.reviewQueue(props.token, null, PAGE_SIZE$3), [props.api, props.token]);
57704
+ const resource = useAdminResource((signal) => props.api.reviewQueue(props.token, null, PAGE_SIZE$3, signal), [props.api, props.token]);
55517
57705
  const items = resource.data?.items ?? rows;
55518
57706
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
55519
57707
  className: "dsh-qa-admin__page",
@@ -55775,7 +57963,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
55775
57963
  const [total, setTotal] = (0, react.useState)(0);
55776
57964
  const [error, setError] = (0, react.useState)();
55777
57965
  const [loading, setLoading] = (0, react.useState)(true);
57966
+ const request = useRequestSlot();
55778
57967
  const load = (0, react.useCallback)(async (next, append) => {
57968
+ const controller = request.start();
55779
57969
  setLoading(true);
55780
57970
  const query = {
55781
57971
  userId: props.userId ?? null,
@@ -55785,7 +57975,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
55785
57975
  from: from === "" ? null : new Date(from).toISOString(),
55786
57976
  to: to === "" ? null : (/* @__PURE__ */ new Date(`${to}T23:59:59.999Z`)).toISOString()
55787
57977
  };
55788
- const result = await props.api.conversations(props.token, query, next, PAGE_SIZE$2);
57978
+ const result = await props.api.conversations(props.token, query, next, PAGE_SIZE$2, controller.signal);
57979
+ if (controller.signal.aborted) return;
55789
57980
  setLoading(false);
55790
57981
  if (!result.ok) {
55791
57982
  setError(adminErrorMessage(result.error));
@@ -55796,6 +57987,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
55796
57987
  setCursor(result.value.nextCursor);
55797
57988
  setRows((current) => append ? [...current, ...result.value.items] : result.value.items);
55798
57989
  }, [
57990
+ request,
55799
57991
  props.api,
55800
57992
  props.token,
55801
57993
  props.userId,
@@ -56356,7 +58548,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
56356
58548
  }
56357
58549
  /** Issue distribution, per-subrole satisfaction and the trend over time. */
56358
58550
  function AdminQuality(props) {
56359
- const resource = useAdminResource(() => props.api.metrics(props.token), [props.api, props.token]);
58551
+ const resource = useAdminResource((signal) => props.api.metrics(props.token, signal), [props.api, props.token]);
56360
58552
  const metrics = resource.data;
56361
58553
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
56362
58554
  className: "dsh-qa-admin__page",
@@ -58516,6 +60708,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
58516
60708
  const accounts = props.accounts;
58517
60709
  const accountsSnapshot = (0, react.useSyncExternalStore)(accounts?.subscribe ?? noopSubscribe$1, accounts?.getSnapshot ?? noopAccountsSnapshot, accounts?.getSnapshot ?? noopAccountsSnapshot);
58518
60710
  const accountsStage = accountsSnapshot.stage;
60711
+ const accessPrincipal = accountsSnapshot.stage === "authed" ? `${accountsSnapshot.user.id}:${accountsSnapshot.user.role}` : null;
58519
60712
  const adminRoute = isAdminPath(route.pathname, config.route.path);
58520
60713
  const [access, setAccess] = (0, react.useState)();
58521
60714
  const [selectedSubrole, setSelectedSubrole] = (0, react.useState)(null);
@@ -58552,7 +60745,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
58552
60745
  minContentWidth: config.ui.minContentWidth
58553
60746
  });
58554
60747
  (0, react.useEffect)(() => {
58555
- if (accountsSnapshot.stage !== "authed") {
60748
+ if (accessPrincipal === null) {
58556
60749
  setAccess(void 0);
58557
60750
  setSelectedSubrole(null);
58558
60751
  clear();
@@ -58568,8 +60761,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
58568
60761
  live = false;
58569
60762
  };
58570
60763
  }, [
60764
+ accessPrincipal,
58571
60765
  accounts,
58572
- accountsSnapshot,
58573
60766
  props.accessApi,
58574
60767
  clear
58575
60768
  ]);
@@ -59601,7 +61794,7 @@ body[data-dsh-qa-surface="active"] div:has(>[data-shell-overlay])>:not([data-she
59601
61794
  .dsh-qa-sidebar__item-main{appearance:none;display:flex;align-items:center;gap:8px;width:100%;min-width:0;border:0;background:0 0;cursor:pointer;text-align:left;font:inherit;padding:7px 8px;border-radius:8px}
59602
61795
  .dsh-qa-sidebar__item-main:focus-visible{outline:2px solid var(--dsh-qa-accent);outline-offset:-2px}
59603
61796
  .dsh-qa-sidebar__item-delete{appearance:none;position:absolute;top:50%;right:4px;display:flex;align-items:center;justify-content:center;width:26px;height:26px;border:0;background:var(--dsw-alias-bg-layer-2);cursor:pointer;color:var(--dsw-alias-label-tertiary);padding:5px;border-radius:6px;opacity:0;transform:translateY(-50%);transition:opacity .12s}
59604
- .dsh-qa-sidebar__item:hover .dsh-qa-sidebar__item-delete,.dsh-qa-sidebar__item-delete:focus-visible,.dsh-qa-sidebar__item-delete--confirm{opacity:1}
61797
+ .dsh-qa-sidebar__item:hover .dsh-qa-sidebar__item-delete,.dsh-qa-sidebar__item-delete:focus-visible{opacity:1}
59605
61798
  .dsh-qa-sidebar__item-delete:hover{color:var(--dsw-alias-label-primary)}
59606
61799
  .dsh-qa-sidebar__item-audit{appearance:none;flex:none;display:inline-flex;align-items:center;gap:4px;height:22px;margin-right:4px;padding:0 8px;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);font:inherit;font-size:11px;line-height:16px;cursor:pointer;transition:border-color .12s,color .12s}
59607
61800
  .dsh-qa-sidebar__item-audit--with-delete{margin-right:28px}
@@ -59613,7 +61806,6 @@ body[data-dsh-qa-surface="active"] div:has(>[data-shell-overlay])>:not([data-she
59613
61806
  .dsh-qa-sidebar__item-audit-verdict--warn{color:var(--dsw-alias-state-warn-primary)}
59614
61807
  .dsh-qa-sidebar__item-audit-verdict--bad{color:var(--dsw-alias-state-error-primary)}
59615
61808
  .dsh-qa-sidebar__item-delete:focus-visible{outline:2px solid var(--dsh-qa-accent);outline-offset:-2px}
59616
- .dsh-qa-sidebar__item-delete--confirm{color:var(--dsh-qa-error-hover)}
59617
61809
  .dsh-qa-sidebar__item-delete svg{width:14px;height:14px;display:block;fill:none;stroke:currentColor;stroke-width:1.3;stroke-linecap:round;stroke-linejoin:round}
59618
61810
  .dsh-qa-sidebar__item-title{flex:1;min-width:0;overflow:hidden;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:18px;text-overflow:ellipsis;white-space:nowrap}
59619
61811
  .dsh-qa-sidebar__item--active .dsh-qa-sidebar__item-title{color:var(--dsw-alias-label-primary);font-weight:500}
@@ -59680,6 +61872,12 @@ body[data-dsh-qa-surface="active"] div:has(>[data-shell-overlay])>:not([data-she
59680
61872
  .dsh-qa-audit-dialog__body .dsh-audit-json{height:100%;min-height:320px}
59681
61873
  .dsh-qa-modal__body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:6px 18px 18px}
59682
61874
  .dsh-qa-modal__footer{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex:none;padding:12px 18px;border-top:1px solid var(--dsw-alias-border-l2)}
61875
+ .dsh-qa-modal__footer button{appearance:none;padding:8px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);font:inherit;font-size:13px;font-weight:500;line-height:19px;cursor:pointer;transition:border-color .12s,background .12s,color .12s}
61876
+ .dsh-qa-modal__footer button:hover:not(:disabled){border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
61877
+ .dsh-qa-modal__footer button:focus-visible{outline:2px solid var(--dsh-qa-accent);outline-offset:2px}
61878
+ .dsh-qa-modal__footer button:disabled{opacity:.5;cursor:default}
61879
+ .dsh-qa-modal__footer .dsh-qa-modal__primary{border-color:transparent;background:var(--dsh-qa-accent);color:var(--dsh-qa-accent-contrast)}
61880
+ .dsh-qa-modal__footer .dsh-qa-modal__primary:hover:not(:disabled){border-color:transparent;background:var(--dsh-qa-accent-hover);color:var(--dsh-qa-accent-contrast)}
59683
61881
  .dsh-qa-changelog__entry{padding-top:10px}
59684
61882
  .dsh-qa-changelog__version{display:flex;align-items:baseline;gap:8px;margin:0 0 2px;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:20px}
59685
61883
  .dsh-qa-changelog__date{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:16px}
@@ -59790,6 +61988,7 @@ body[data-dsh-qa-surface="active"] div:has(>[data-shell-overlay])>:not([data-she
59790
61988
  .dsh-qa-toolpicker__description{display:-webkit-box;overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;min-width:0;-webkit-box-orient:vertical;-webkit-line-clamp:2}
59791
61989
  .dsh-qa-toolpicker__selected{margin-right:auto;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:17px}
59792
61990
  @media (max-width:720px){.dsh-qa-modal__panel--settings{height:min(640px,calc(100vh - 48px))}.dsh-qa-settings{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr)}.dsh-qa-settings__nav{flex-direction:row;gap:4px;padding:8px 10px;border-right:0;border-bottom:1px solid var(--dsw-alias-border-l2);overflow-x:auto;overflow-y:hidden}.dsh-qa-settings__tab{white-space:nowrap}.dsh-qa-settings__content{padding:12px 14px 0}.dsh-qa-settings__page{padding-bottom:18px}.dsh-qa-settings__actions{margin:auto -14px -18px;padding:10px 14px}}
61991
+ @media (max-width:520px){.dsh-qa-modal{padding:12px}.dsh-qa-modal__footer{align-items:stretch;flex-direction:column-reverse}.dsh-qa-modal__footer button{width:100%}}
59793
61992
  .dsh-qa-surface *{box-sizing:border-box}
59794
61993
  .dsh-qa-surface ::selection{background:var(--dsh-qa-text-select)}
59795
61994
  .dsh-qa-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
@@ -60166,6 +62365,22 @@ a.dsh-qa-srcref:hover,button.dsh-qa-srcref:hover{border-color:var(--dsw-alias-la
60166
62365
  .dsh-qa-md-code__copy:focus-visible{outline:2px solid var(--dsh-qa-accent);outline-offset:2px}
60167
62366
  .dsh-qa-md-code pre{overflow-x:auto;margin:0;padding:16px;border:0;border-radius:0 0 12px 12px;background:transparent;font-family:var(--ds-font-family-code,ui-monospace,SFMono-Regular,Consolas,monospace);font-size:var(--dsw-font-markdown-code-block-font-size,11px);line-height:var(--dsw-font-markdown-code-block-line-height,19px);white-space:pre-wrap;word-break:break-word}
60168
62367
  .dsh-qa-md-code pre code{display:block;padding:0;border:0;background:transparent;font:inherit}
62368
+ .dsh-qa-mermaid{position:relative;overflow:hidden;margin:16px 0;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary)}
62369
+ .dsh-qa-mermaid__toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 10px 8px 14px;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);font-size:12px;line-height:20px}
62370
+ .dsh-qa-mermaid__actions{display:flex;align-items:center;gap:4px;flex-wrap:wrap;justify-content:flex-end}
62371
+ .dsh-qa-mermaid__actions button{appearance:none;padding:3px 8px;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer}
62372
+ .dsh-qa-mermaid__actions button:hover{border-color:var(--dsw-alias-label-dimmed);color:var(--dsw-alias-label-primary)}
62373
+ .dsh-qa-mermaid__actions button:focus-visible{outline:2px solid var(--dsh-qa-accent);outline-offset:1px}
62374
+ .dsh-qa-mermaid__viewport{min-height:180px;max-height:68vh;overflow:auto;overscroll-behavior:contain;padding:20px;background:var(--dsw-alias-bg-layer-1)}
62375
+ .dsh-qa-mermaid__canvas{min-width:320px;margin:auto;transition:width .16s ease}
62376
+ .dsh-qa-mermaid__canvas svg{display:block;width:100%;max-width:none!important;height:auto;margin:auto}
62377
+ .dsh-qa-mermaid__loading{display:grid;place-items:center;min-height:140px;color:var(--dsw-alias-label-tertiary)}
62378
+ .dsh-qa-mermaid>.dsh-qa-md-code{margin:0;border-radius:0;border-top:1px solid var(--dsw-alias-border-l2)}
62379
+ .dsh-qa-mermaid--error{padding:12px}
62380
+ .dsh-qa-mermaid--error>p{margin:0 0 10px;color:var(--dsh-qa-error)}
62381
+ .dsh-qa-mermaid--error>.dsh-qa-md-code{margin:0;border-radius:10px;border-top:0}
62382
+ .dsh-qa-mermaid--expanded{position:fixed;inset:16px;z-index:1000;display:flex;flex-direction:column;margin:0;box-shadow:var(--dsw-shadow-lv3)}
62383
+ .dsh-qa-mermaid--expanded .dsh-qa-mermaid__viewport{flex:1;max-height:none}
60169
62384
  .dsh-qa-md-tok[data-tok="comment"]{color:var(--shiki-token-comment)}
60170
62385
  .dsh-qa-md-tok[data-tok="string"]{color:var(--shiki-token-string)}
60171
62386
  .dsh-qa-md-tok[data-tok="keyword"]{color:var(--shiki-token-keyword)}
@@ -61172,6 +63387,68 @@ ${QA_ROOT_STYLES}`;
61172
63387
  });
61173
63388
  }
61174
63389
  //#endregion
63390
+ //#region src/client/settings/sections/docs.tsx
63391
+ /**
63392
+ * Documentation: which edition of the corpus a question is answered from.
63393
+ *
63394
+ * A published corpus carries several editions of the same module under
63395
+ * `docs/<module>/<version>/…`, and a chat asked about "the product" reads
63396
+ * whichever edition it meets first. A stand that knows which edition it is
63397
+ * about names it here, and `docs_search` stays inside it unless the call itself
63398
+ * names a `version` or narrows `path`. The switch keeps the value while turning
63399
+ * the behaviour off, so a stand can stop defaulting without losing the version
63400
+ * it configured.
63401
+ */
63402
+ const DOCS_PATHS = [["tools", "docsDefaultVersion"], ["tools", "docsDefaultVersionEnabled"]];
63403
+ /** The documentation corpus the QA tools read, and the edition they default to. */
63404
+ function DocsSection(props) {
63405
+ const tools = props.config?.tools;
63406
+ const version = (tools?.docsDefaultVersion ?? "").trim();
63407
+ const enabled = tools?.docsDefaultVersionEnabled ?? false;
63408
+ const disabled = !props.writable;
63409
+ const paths = DOCS_PATHS;
63410
+ const root = (props.effective?.tools.docsRoot ?? "").trim();
63411
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
63412
+ title: "Документация",
63413
+ modified: overriddenAny(props, paths),
63414
+ aside: resetAside(props, paths),
63415
+ children: [
63416
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
63417
+ className: "qa-card-muted",
63418
+ children: "Поиск и чтение документации ходят по корпусу стенда — дереву docs/<модуль>/<версия>/…. Поиск обходит модули раньше служебных каталогов (тех, что начинаются с подчёркивания), а в каждом попадании называет модуль и версию документа."
63419
+ }),
63420
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Toggle, {
63421
+ label: "Версия по умолчанию",
63422
+ hint: "Поиск, которому не назвали версию и не сузили подкаталог, остаётся внутри этой редакции корпуса. Явные version или path сильнее: они решают сами.",
63423
+ checked: enabled,
63424
+ disabled,
63425
+ onChange: (checked) => {
63426
+ props.write(["tools", "docsDefaultVersionEnabled"], checked);
63427
+ }
63428
+ }),
63429
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextField, {
63430
+ label: "Версия",
63431
+ value: tools?.docsDefaultVersion ?? "",
63432
+ disabled,
63433
+ placeholder: "3.8",
63434
+ hint: "Как в пути к документу: 3.8, v2, 2024.1. Пусто — дефолта нет, поиск идёт по всем редакциям. Другое значение Host отклонит: версия, которой нет в дереве, отвечала бы «документа нет».",
63435
+ onChange: (value) => {
63436
+ props.write(["tools", "docsDefaultVersion"], value);
63437
+ }
63438
+ }),
63439
+ enabled && version === "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Notice, {
63440
+ tone: "warn",
63441
+ children: "Флаг включён, а версия не задана: поиск по-прежнему идёт по всем редакциям корпуса."
63442
+ }) : null,
63443
+ props.effective === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Facts, { items: [{
63444
+ label: "Корень документации",
63445
+ value: root === "" ? "docs/ рабочего каталога чата" : root,
63446
+ note: root === "" ? "развёртывание не назвало общий корпус" : "tools.docsRoot развёртывания"
63447
+ }] })
63448
+ ]
63449
+ });
63450
+ }
63451
+ //#endregion
61175
63452
  //#region src/client/settings/sections/embedding.tsx
61176
63453
  /**
61177
63454
  * Embedding: one CSP field with a wide blast radius — an overly generous
@@ -62808,6 +65085,7 @@ ${QA_ROOT_STYLES}`;
62808
65085
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SlashSection, { ...sectionProps }),
62809
65086
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountsSection, { ...sectionProps }),
62810
65087
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SourcesSection, { ...sectionProps }),
65088
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DocsSection, { ...sectionProps }),
62811
65089
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NotesSection, { ...sectionProps }),
62812
65090
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AttachmentsSection, { ...sectionProps }),
62813
65091
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmbeddingSection, { ...sectionProps }),
@@ -63242,21 +65520,21 @@ textarea.qa-card-control{height:auto;padding:8px 12px;line-height:1.5;resize:ver
63242
65520
  skillActivations: (token, sessionId) => policyRemote.accessSkillActivations(token, sessionId)
63243
65521
  };
63244
65522
  const adminApi = {
63245
- overview: (token) => policyRemote.adminOverview(token),
65523
+ overview: (token, signal) => policyRemote.adminOverview(token, signal),
63246
65524
  users: (token, query, cursor, limit) => policyRemote.adminUsers(token, query, cursor, limit),
63247
65525
  user: (token, userId) => policyRemote.adminUser(token, userId),
63248
65526
  updateUser: (token, userId, update) => policyRemote.adminUpdateUser(token, userId, update),
63249
65527
  passwordResetRequests: (token) => policyRemote.adminPasswordResetRequests(token),
63250
65528
  resetPassword: (token, userId, password) => policyRemote.adminResetPassword(token, userId, password),
63251
- conversations: (token, query, cursor, limit) => policyRemote.adminConversations(token, query, cursor, limit),
65529
+ conversations: (token, query, cursor, limit, signal) => policyRemote.adminConversations(token, query, cursor, limit, signal),
63252
65530
  conversation: (token, conversationId) => policyRemote.adminConversation(token, conversationId),
63253
65531
  deleteConversation: (token, conversationId) => policyRemote.adminDeleteConversation(token, conversationId),
63254
65532
  feedback: (token, query, cursor, limit) => policyRemote.adminFeedback(token, query, cursor, limit),
63255
65533
  rateMessage: (token, conversationId, messageId, input) => policyRemote.adminRateMessage(token, conversationId, messageId, input),
63256
- reviewQueue: (token, cursor, limit) => policyRemote.adminReviewQueue(token, cursor, limit),
65534
+ reviewQueue: (token, cursor, limit, signal) => policyRemote.adminReviewQueue(token, cursor, limit, signal),
63257
65535
  queueConversation: (token, conversationId, messageId) => policyRemote.adminQueueConversation(token, conversationId, messageId),
63258
65536
  saveReview: (token, input) => policyRemote.adminSaveReview(token, input),
63259
- metrics: (token) => policyRemote.adminMetrics(token),
65537
+ metrics: (token, signal) => policyRemote.adminMetrics(token, signal),
63260
65538
  audit: (token, query, cursor, limit) => policyRemote.adminAudit(token, query, cursor, limit),
63261
65539
  skills: (token, scope) => policyRemote.adminSkills(token, scope),
63262
65540
  skill: (token, scope, name) => policyRemote.adminSkill(token, scope, name),
@@ -63320,6 +65598,16 @@ textarea.qa-card-control{height:auto;padding:8px 12px;line-height:1.5;resize:ver
63320
65598
  forgetChat: (sessionId) => {
63321
65599
  const snapshot = config.getSnapshot().config;
63322
65600
  new QaChatIndex(window.localStorage, qaStorageNamespace(snapshot)).forgetChat(sessionId);
65601
+ },
65602
+ harvestRatings: async ({ token, accountId, ownedIds }) => {
65603
+ const snapshot = config.getSnapshot().config;
65604
+ await harvestLocalRatings({
65605
+ storage: window.localStorage,
65606
+ namespace: qaStorageNamespace(snapshot),
65607
+ accountId,
65608
+ ownedIds,
65609
+ send: (batch) => policyRemote.adminHarvestFeedback(token, batch)
65610
+ });
63323
65611
  }
63324
65612
  });
63325
65613
  userSession.attach(accounts);
@@ -63468,6 +65756,12 @@ textarea.qa-card-control{height:auto;padding:8px 12px;line-height:1.5;resize:ver
63468
65756
  exports.QaSessionController = QaSessionController;
63469
65757
  exports.apply = apply;
63470
65758
  exports.inject = inject;
65759
+ Object.defineProperty(exports, "katex_exports", {
65760
+ enumerable: true,
65761
+ get: function() {
65762
+ return katex_exports;
65763
+ }
65764
+ });
63471
65765
  exports.matchesQaRoute = matchesQaRoute;
63472
65766
  exports.projectTranscript = projectTranscript;
63473
65767
  return module.exports;