@evotecit/canopyx 0.3.16 → 0.3.20

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 (150) hide show
  1. package/CanopyX.Html/Assets/canopyx-board.css +50 -0
  2. package/CanopyX.Html/Assets/canopyx-board.js +39 -0
  3. package/CanopyX.Html/Assets/canopyx-buckets.js +15 -0
  4. package/CanopyX.Html/Assets/canopyx-calculations.css +7 -0
  5. package/CanopyX.Html/Assets/canopyx-calculations.js +52 -0
  6. package/CanopyX.Html/Assets/canopyx-calendar-edit.js +3 -3
  7. package/CanopyX.Html/Assets/canopyx-calendar.css +74 -80
  8. package/CanopyX.Html/Assets/canopyx-calendar.js +26 -31
  9. package/CanopyX.Html/Assets/canopyx-cell-range.css +4 -4
  10. package/CanopyX.Html/Assets/canopyx-cell-range.js +16 -14
  11. package/CanopyX.Html/Assets/canopyx-changes.css +61 -79
  12. package/CanopyX.Html/Assets/canopyx-changes.js +18 -15
  13. package/CanopyX.Html/Assets/canopyx-column-groups.css +5 -1
  14. package/CanopyX.Html/Assets/canopyx-column-groups.js +15 -9
  15. package/CanopyX.Html/Assets/canopyx-compare.css +37 -0
  16. package/CanopyX.Html/Assets/canopyx-compare.js +12 -0
  17. package/CanopyX.Html/Assets/canopyx-data.js +3 -3
  18. package/CanopyX.Html/Assets/canopyx-detail-rows.css +4 -4
  19. package/CanopyX.Html/Assets/canopyx-detail-rows.js +1 -1
  20. package/CanopyX.Html/Assets/canopyx-editing.css +5 -5
  21. package/CanopyX.Html/Assets/canopyx-editing.js +2 -2
  22. package/CanopyX.Html/Assets/canopyx-enhance.js +5 -5
  23. package/CanopyX.Html/Assets/canopyx-export.js +54 -13
  24. package/CanopyX.Html/Assets/canopyx-facets.css +32 -22
  25. package/CanopyX.Html/Assets/canopyx-facets.js +19 -15
  26. package/CanopyX.Html/Assets/canopyx-filter-editor.css +75 -89
  27. package/CanopyX.Html/Assets/canopyx-filter-editor.js +20 -16
  28. package/CanopyX.Html/Assets/canopyx-flow-checks.css +3 -3
  29. package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
  30. package/CanopyX.Html/Assets/canopyx-flow-command.css +3 -3
  31. package/CanopyX.Html/Assets/canopyx-flow-command.js +1 -1
  32. package/CanopyX.Html/Assets/canopyx-flow-dialog.css +4 -4
  33. package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
  34. package/CanopyX.Html/Assets/canopyx-flow-drafts.css +2 -2
  35. package/CanopyX.Html/Assets/canopyx-flow-drafts.js +1 -1
  36. package/CanopyX.Html/Assets/canopyx-flow-entry.css +142 -17
  37. package/CanopyX.Html/Assets/canopyx-flow-entry.js +5 -5
  38. package/CanopyX.Html/Assets/canopyx-flow-host.css +2 -2
  39. package/CanopyX.Html/Assets/canopyx-flow-host.js +1 -1
  40. package/CanopyX.Html/Assets/canopyx-flow-module.mjs +5 -5
  41. package/CanopyX.Html/Assets/canopyx-flow-pick.css +4 -4
  42. package/CanopyX.Html/Assets/canopyx-flow-pick.js +1 -1
  43. package/CanopyX.Html/Assets/canopyx-flow-preview.css +1 -1
  44. package/CanopyX.Html/Assets/canopyx-flow-preview.js +1 -1
  45. package/CanopyX.Html/Assets/canopyx-flow-records.css +2 -2
  46. package/CanopyX.Html/Assets/canopyx-flow-records.js +1 -1
  47. package/CanopyX.Html/Assets/canopyx-flow-tasks.css +4 -4
  48. package/CanopyX.Html/Assets/canopyx-flow-tasks.js +1 -1
  49. package/CanopyX.Html/Assets/canopyx-flow.css +41 -41
  50. package/CanopyX.Html/Assets/canopyx-flow.js +1 -1
  51. package/CanopyX.Html/Assets/canopyx-format-editor.css +9 -9
  52. package/CanopyX.Html/Assets/canopyx-format-editor.js +2 -2
  53. package/CanopyX.Html/Assets/canopyx-formatting.css +13 -13
  54. package/CanopyX.Html/Assets/canopyx-formatting.js +12 -11
  55. package/CanopyX.Html/Assets/canopyx-forms.css +3 -3
  56. package/CanopyX.Html/Assets/canopyx-forms.js +1 -1
  57. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +220 -155
  58. package/CanopyX.Html/Assets/canopyx-grid-options.css +8 -8
  59. package/CanopyX.Html/Assets/canopyx-grid-options.js +9 -2
  60. package/CanopyX.Html/Assets/canopyx-grid.css +285 -150
  61. package/CanopyX.Html/Assets/canopyx-grid.js +220 -155
  62. package/CanopyX.Html/Assets/canopyx-grouping.css +23 -16
  63. package/CanopyX.Html/Assets/canopyx-grouping.js +24 -17
  64. package/CanopyX.Html/Assets/canopyx-highlight.css +10 -10
  65. package/CanopyX.Html/Assets/canopyx-highlight.js +1 -1
  66. package/CanopyX.Html/Assets/canopyx-interactive.css +215 -91
  67. package/CanopyX.Html/Assets/canopyx-interactive.js +47 -52
  68. package/CanopyX.Html/Assets/canopyx-labels-de.js +177 -9
  69. package/CanopyX.Html/Assets/canopyx-labels-es.js +177 -9
  70. package/CanopyX.Html/Assets/canopyx-labels-fr.js +176 -8
  71. package/CanopyX.Html/Assets/canopyx-labels-it.js +176 -8
  72. package/CanopyX.Html/Assets/canopyx-labels-pl.js +176 -8
  73. package/CanopyX.Html/Assets/canopyx-layouts.css +49 -21
  74. package/CanopyX.Html/Assets/canopyx-layouts.js +36 -14
  75. package/CanopyX.Html/Assets/canopyx-link.css +3 -3
  76. package/CanopyX.Html/Assets/canopyx-link.js +4 -4
  77. package/CanopyX.Html/Assets/canopyx-links.js +2 -2
  78. package/CanopyX.Html/Assets/canopyx-live.css +3 -5
  79. package/CanopyX.Html/Assets/canopyx-live.js +3 -3
  80. package/CanopyX.Html/Assets/canopyx-matrix.css +32 -39
  81. package/CanopyX.Html/Assets/canopyx-matrix.js +11 -11
  82. package/CanopyX.Html/Assets/canopyx-module.mjs +47 -52
  83. package/CanopyX.Html/Assets/canopyx-office-export.js +2936 -0
  84. package/CanopyX.Html/Assets/canopyx-pager.css +1 -1
  85. package/CanopyX.Html/Assets/canopyx-pager.js +1 -1
  86. package/CanopyX.Html/Assets/canopyx-path.css +45 -0
  87. package/CanopyX.Html/Assets/canopyx-path.js +28 -0
  88. package/CanopyX.Html/Assets/canopyx-pivot.css +75 -0
  89. package/CanopyX.Html/Assets/canopyx-pivot.js +72 -0
  90. package/CanopyX.Html/Assets/canopyx-plan.css +63 -0
  91. package/CanopyX.Html/Assets/canopyx-plan.js +71 -0
  92. package/CanopyX.Html/Assets/canopyx-presenters.js +2 -2
  93. package/CanopyX.Html/Assets/canopyx-record-panel.css +51 -45
  94. package/CanopyX.Html/Assets/canopyx-record-panel.js +30 -22
  95. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +262 -197
  96. package/CanopyX.Html/Assets/canopyx-reporting.css +300 -164
  97. package/CanopyX.Html/Assets/canopyx-reporting.js +262 -197
  98. package/CanopyX.Html/Assets/canopyx-stack.css +35 -0
  99. package/CanopyX.Html/Assets/canopyx-stack.js +24 -0
  100. package/CanopyX.Html/Assets/canopyx-time-slider.css +18 -0
  101. package/CanopyX.Html/Assets/canopyx-time-slider.js +27 -0
  102. package/CanopyX.Html/Assets/canopyx-timeline.css +19 -19
  103. package/CanopyX.Html/Assets/canopyx-timeline.js +6 -5
  104. package/CanopyX.Html/Assets/canopyx-tree-tools.css +47 -46
  105. package/CanopyX.Html/Assets/canopyx-tree-tools.js +15 -12
  106. package/CanopyX.Html/Assets/canopyx-ui-menu.css +41 -0
  107. package/CanopyX.Html/Assets/canopyx-ui-menu.js +64 -0
  108. package/CanopyX.Html/Assets/canopyx-ui-navigation.css +73 -0
  109. package/CanopyX.Html/Assets/canopyx-ui-navigation.js +39 -0
  110. package/CanopyX.Html/Assets/canopyx-ui-overlays.css +79 -0
  111. package/CanopyX.Html/Assets/canopyx-ui-overlays.js +45 -0
  112. package/CanopyX.Html/Assets/canopyx-ui-picker.css +12 -0
  113. package/CanopyX.Html/Assets/canopyx-ui-picker.js +6 -0
  114. package/CanopyX.Html/Assets/canopyx-ui-stepper.css +174 -0
  115. package/CanopyX.Html/Assets/canopyx-ui-stepper.js +48 -0
  116. package/CanopyX.Html/Assets/canopyx-ui-tabs.css +153 -0
  117. package/CanopyX.Html/Assets/canopyx-ui-tabs.js +47 -0
  118. package/CanopyX.Html/Assets/canopyx-values.css +5 -0
  119. package/CanopyX.Html/Assets/canopyx-values.js +13 -0
  120. package/CanopyX.Html/Assets/canopyx-view-intents.css +12 -0
  121. package/CanopyX.Html/Assets/canopyx-view-intents.js +56 -0
  122. package/CanopyX.Html/Assets/canopyx.css +212 -85
  123. package/CanopyX.Html/Assets/canopyx.js +38 -26
  124. package/JavaScript/board.d.ts +30 -0
  125. package/JavaScript/changes.d.ts +4 -1
  126. package/JavaScript/column-groups.d.ts +24 -4
  127. package/JavaScript/facets.d.ts +5 -3
  128. package/JavaScript/grid.d.ts +161 -17
  129. package/JavaScript/hosts.d.ts +16 -1
  130. package/JavaScript/index.d.ts +4 -2
  131. package/JavaScript/locales/de.mjs +177 -9
  132. package/JavaScript/locales/es.mjs +177 -9
  133. package/JavaScript/locales/fr.mjs +176 -8
  134. package/JavaScript/locales/it.mjs +176 -8
  135. package/JavaScript/locales/pl.mjs +176 -8
  136. package/JavaScript/matrix.d.ts +4 -1
  137. package/JavaScript/path.d.ts +33 -0
  138. package/JavaScript/pivot.d.ts +135 -0
  139. package/JavaScript/plan.d.ts +23 -0
  140. package/JavaScript/protocol.d.ts +18 -3
  141. package/JavaScript/records.d.ts +4 -0
  142. package/JavaScript/stack.d.ts +28 -0
  143. package/JavaScript/time-slider.d.ts +58 -0
  144. package/JavaScript/ui.d.ts +261 -0
  145. package/JavaScript/view-intents.d.ts +45 -0
  146. package/README.md +76 -187
  147. package/README.nuget.md +63 -87
  148. package/ThirdParty/OfficeIMO/LICENSE +21 -0
  149. package/ThirdParty/OfficeIMO/README.md +13 -0
  150. package/package.json +76 -3
@@ -1,15 +1,13 @@
1
1
  /* The change views: a text diff,a change list and a propagation view (docs/changes.md). Tones mark what changed,and each change also
2
2
  has a sign,a badge or a symbol,so none relies on colour alone. */
3
- .cx-diff,.cx-changes,.cx-prop{--cx-size-112px:112px;--cx-size-150px:150px;--cx-chg-tint:9%;--cx-chg-strong:28%;min-width:0;color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem))/1.4 var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);}
3
+ .cx-diff,.cx-changes,.cx-prop{--cx-size-112px:112px;--cx-size-150px:150px;--cx-chg-tint:9%;--cx-chg-strong:28%;min-width:0;color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));font:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem))/1.4 var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);}
4
4
  @media screen{.cx-host[data-cx-theme="dark"] :is(.cx-diff,.cx-changes,.cx-prop){--cx-chg-tint:15%;--cx-chg-strong:36%;}}
5
5
  @media screen and (prefers-color-scheme:dark){.cx-host[data-cx-theme="auto"] :is(.cx-diff,.cx-changes,.cx-prop){--cx-chg-tint:15%;--cx-chg-strong:36%;}}
6
6
  .cx-change-host:is([data-cx-height],[style*="height"]) > :is(.cx-diff,.cx-changes,.cx-prop){height:100%;overflow:auto;}
7
7
  :is(.cx-diff,.cx-changes,.cx-prop) [hidden]{display:none !important;}
8
8
  .cx-chg-ico{width:var(--cx-size-16px);height:var(--cx-size-16px);flex:none;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;}
9
- .cx-diff-btn,.cx-chg-action,.cx-chg-more{display:inline-flex;align-items:center;justify-content:center;gap:var(--cx-size-6px);box-sizing:border-box;min-width:var(--cx-size-30px);min-height:var(--cx-size-30px);
10
- padding:0 var(--cx-size-8px);font:inherit;font-size:var(--cx-size-13px);color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);cursor:pointer;}
11
- :is(.cx-diff-btn,.cx-chg-action,.cx-chg-more,.cx-chg-kind,.cx-chg-toggle,.cx-chg-hashbtn):hover{background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
12
- :is(.cx-diff-btn,.cx-chg-action,.cx-chg-more,.cx-chg-kind,.cx-chg-toggle,.cx-chg-hashbtn,.cx-diff-segbtn,.cx-diff-expand):focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
9
+ :is(.cx-chg-toggle,.cx-chg-hashbtn):hover{background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
10
+ :is(.cx-chg-toggle,.cx-chg-hashbtn,.cx-diff-expand):focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
13
11
  .cx-diff-btn.cx-diff-done{border-color:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));color:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
14
12
  .cx-diff{position:relative;display:flex;flex-direction:column;gap:var(--cx-size-8px);max-height:100%;}
15
13
  .cx-diff-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--cx-size-8px) var(--cx-size-12px);}
@@ -19,60 +17,56 @@ padding:0 var(--cx-size-8px);font:inherit;font-size:var(--cx-size-13px);color:va
19
17
  .cx-diff-plus{color:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
20
18
  .cx-diff-minus{color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
21
19
  .cx-diff-tools{display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-6px);}
22
- .cx-diff-seg{display:inline-flex;border:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);overflow:hidden;}
23
- .cx-diff-segbtn{min-height:var(--cx-size-30px);padding:0 var(--cx-size-10px);font:inherit;font-size:var(--cx-size-13px);color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border:0;cursor:pointer;}
24
- .cx-diff-segbtn + .cx-diff-segbtn{border-inline-start:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));}
25
- .cx-diff-segbtn[aria-checked="true"]{background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));font-weight:600;}
26
20
  .cx-diff-notes{display:grid;gap:var(--cx-size-4px);}
27
- .cx-diff-note{padding:var(--cx-size-6px) var(--cx-size-10px);font-size:var(--cx-size-13px);color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));border-inline-start:var(--cx-size-3px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-sm,4px);}
21
+ .cx-diff-note{padding:var(--cx-size-6px) var(--cx-size-10px);font-size:var(--cx-size-13px);color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));border-inline-start:var(--cx-size-3px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-sm,4px);}
28
22
  .cx-diff-note:is(.cx-tone-info,.cx-tone-warning,.cx-tone-danger,.cx-tone-success){border-inline-start-color:var(--cx-chg-note);}
29
23
  .cx-diff-note.cx-tone-info{--cx-chg-note:var(--hfx-color-status-info-fg,light-dark(#2b5fc0,#74a2f7));}
30
24
  .cx-diff-note.cx-tone-warning{--cx-chg-note:var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640));}
31
25
  .cx-diff-note.cx-tone-danger{--cx-chg-note:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
32
26
  .cx-diff-note.cx-tone-success{--cx-chg-note:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
33
- .cx-diff-state{padding:var(--cx-size-16px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));text-align:center;border:var(--cx-size-1px) dashed var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
34
- .cx-diff-scroll{position:relative;flex:0 1 auto;min-height:0;max-height:var(--cx-diff-max-height,70vh);overflow:auto;background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));
27
+ .cx-diff-state{padding:var(--cx-size-16px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));text-align:center;border:var(--cx-size-1px) dashed var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
28
+ .cx-diff-scroll{position:relative;flex:0 1 auto;min-height:0;max-height:var(--cx-diff-max-height,70vh);overflow:auto;background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));border:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));
35
29
  border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));font-family:var(--hfx-font-mono,"Cascadia Mono","Cascadia Code",Consolas,"SFMono-Regular",Menlo,monospace);font-size:var(--cx-size-12px);overscroll-behavior:contain;}
36
30
  .cx-change-host:is([data-cx-height],[style*="height"]) .cx-diff-scroll{flex:1 1 auto;max-height:none;}
37
31
  .cx-diff-frame{position:relative;display:flex;flex-direction:column;flex:0 1 auto;min-height:0;}
38
32
  .cx-change-host:is([data-cx-height],[style*="height"]) .cx-diff-frame{flex:1 1 auto;}
39
33
  .cx-diff-edge{position:absolute;top:calc(var(--cx-size-1px) + var(--cx-diff-head,0px));bottom:calc(var(--cx-size-1px) + var(--cx-diff-bar-x,0px));width:var(--cx-size-32px);z-index:3;pointer-events:none;
40
- --cx-diff-shade:color-mix(in srgb,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)) 26%,transparent);--cx-diff-line:color-mix(in srgb,var(--hfx-color-accent,light-dark(#11776f,#37c9b8)) 70%,transparent);}
34
+ --cx-diff-shade:color-mix(in srgb,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))) 26%,transparent);--cx-diff-line:color-mix(in srgb,var(--hfx-color-accent,light-dark(#11776f,#37c9b8)) 70%,transparent);}
41
35
  .cx-diff-edge-start{inset-inline-start:var(--cx-size-1px);background:linear-gradient(to right,var(--cx-diff-shade),transparent);border-inline-start:var(--cx-size-2px) solid var(--cx-diff-line);}
42
36
  .cx-diff-edge-end{inset-inline-end:calc(var(--cx-size-1px) + var(--cx-diff-bar-y,0px));background:linear-gradient(to left,var(--cx-diff-shade),transparent);border-inline-end:var(--cx-size-2px) solid var(--cx-diff-line);}
43
37
  .cx-diff-edge-start:dir(rtl){background:linear-gradient(to left,var(--cx-diff-shade),transparent);}
44
38
  .cx-diff-edge-end:dir(rtl){background:linear-gradient(to right,var(--cx-diff-shade),transparent);}
45
39
  :is(.cx-diff,.cx-changes) [data-cx-tip]{position:relative;}
46
40
  :is(.cx-diff,.cx-changes) [data-cx-tip]:not([data-cx-tip-off]):focus-visible::after{content:attr(data-cx-tip);position:absolute;bottom:calc(100% + var(--cx-size-6px));inset-inline-end:0;z-index:6;padding:var(--cx-size-2px) var(--cx-size-8px);
47
- font-size:var(--cx-size-12px);font-weight:400;line-height:1.4;white-space:nowrap;color:var(--hfx-color-surface,light-dark(#ffffff,#16181c));background:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));border-radius:var(--hfx-radius-sm,4px);pointer-events:none;}
41
+ font-size:var(--cx-size-12px);font-weight:400;line-height:1.4;white-space:nowrap;color:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));background:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));border-radius:var(--hfx-radius-sm,4px);pointer-events:none;}
48
42
  @media (hover:hover){
49
43
  :is(.cx-diff,.cx-changes) [data-cx-tip]:not([data-cx-tip-off]):hover::after{content:attr(data-cx-tip);position:absolute;bottom:calc(100% + var(--cx-size-6px));inset-inline-end:0;z-index:6;padding:var(--cx-size-2px) var(--cx-size-8px);
50
- font-size:var(--cx-size-12px);font-weight:400;line-height:1.4;white-space:nowrap;color:var(--hfx-color-surface,light-dark(#ffffff,#16181c));background:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));border-radius:var(--hfx-radius-sm,4px);pointer-events:none;}
44
+ font-size:var(--cx-size-12px);font-weight:400;line-height:1.4;white-space:nowrap;color:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));background:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));border-radius:var(--hfx-radius-sm,4px);pointer-events:none;}
51
45
  }
52
46
  .cx-diff-tools [data-cx-tip]::after{bottom:auto !important;top:calc(100% + var(--cx-size-6px));}
53
47
  .cx-diff-scroll:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:calc(var(--cx-size-2px) * -1);}
54
- .cx-diff-columns{position:sticky;top:0;z-index:2;display:grid;grid-template-columns:1fr 1fr;background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));
55
- font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
48
+ .cx-diff-columns{position:sticky;top:0;z-index:2;display:grid;grid-template-columns:1fr 1fr;background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));
49
+ font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
56
50
  .cx-diff-colhead{padding:var(--cx-size-4px) var(--cx-size-10px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
57
- .cx-diff-colhead + .cx-diff-colhead{border-inline-start:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
51
+ .cx-diff-colhead + .cx-diff-colhead{border-inline-start:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
58
52
  .cx-diff-canvas{position:relative;}
59
53
  .cx-diff-row{position:absolute;top:0;inset-inline-start:0;width:100%;height:20px;display:grid;grid-template-columns:var(--cx-diff-num) var(--cx-diff-num) 2ch minmax(0,1fr);line-height:20px;contain:layout style;}
60
54
  .cx-diff-split .cx-diff-pairrow{grid-template-columns:var(--cx-diff-num) minmax(0,1fr) var(--cx-diff-num) minmax(0,1fr);}
61
- .cx-diff-num{padding:0 var(--cx-size-8px);text-align:end;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-variant-numeric:tabular-nums;user-select:none;}
62
- .cx-diff-pairrow .cx-diff-num:nth-child(3){border-inline-start:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
63
- .cx-diff-sign{text-align:center;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));user-select:none;}
55
+ .cx-diff-num{padding:0 var(--cx-size-8px);text-align:end;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-variant-numeric:tabular-nums;user-select:none;}
56
+ .cx-diff-pairrow .cx-diff-num:nth-child(3){border-inline-start:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
57
+ .cx-diff-sign{text-align:center;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));user-select:none;}
64
58
  .cx-diff-code{padding-inline:var(--cx-size-6px) var(--cx-size-16px);white-space:pre;overflow:hidden;tab-size:4;}
65
59
  .cx-diff-del{--cx-chg-diff:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
66
60
  .cx-diff-add{--cx-chg-diff:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
67
- .cx-diff-row:is(.cx-diff-del,.cx-diff-add),.cx-diff-pairrow .cx-diff-code:is(.cx-diff-del,.cx-diff-add){background:color-mix(in srgb,var(--cx-chg-diff) var(--cx-chg-tint),var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
61
+ .cx-diff-row:is(.cx-diff-del,.cx-diff-add),.cx-diff-pairrow .cx-diff-code:is(.cx-diff-del,.cx-diff-add){background:color-mix(in srgb,var(--cx-chg-diff) var(--cx-chg-tint),var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));}
68
62
  .cx-diff-row:is(.cx-diff-del,.cx-diff-add) :is(.cx-diff-num,.cx-diff-sign),.cx-diff-pairrow .cx-diff-num:is(.cx-diff-del,.cx-diff-add){
69
- color:color-mix(in srgb,var(--cx-chg-diff) 70%,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));background:color-mix(in srgb,var(--cx-chg-diff) calc(var(--cx-chg-tint) * 1.8),var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
70
- .cx-diff-mark{color:inherit;text-decoration:none;border-radius:var(--cx-size-2px);background:color-mix(in srgb,var(--cx-chg-diff) var(--cx-chg-strong),var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
71
- .cx-diff-blank{background:repeating-linear-gradient(135deg,transparent 0 var(--cx-size-5px),color-mix(in srgb,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)) 55%,transparent) var(--cx-size-5px) var(--cx-size-6px));}
72
- .cx-diff-gaprow{background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
63
+ color:color-mix(in srgb,var(--cx-chg-diff) 70%,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))));background:color-mix(in srgb,var(--cx-chg-diff) calc(var(--cx-chg-tint) * 1.8),var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));}
64
+ .cx-diff-mark{color:inherit;text-decoration:none;border-radius:var(--cx-size-2px);background:color-mix(in srgb,var(--cx-chg-diff) var(--cx-chg-strong),var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));}
65
+ .cx-diff-blank{background:repeating-linear-gradient(135deg,transparent 0 var(--cx-size-5px),color-mix(in srgb,var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30))) 55%,transparent) var(--cx-size-5px) var(--cx-size-6px));}
66
+ .cx-diff-gaprow{background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
73
67
  .cx-diff-gap{grid-column:1 / -1;display:flex;align-items:center;gap:var(--cx-size-6px);padding:0 var(--cx-size-10px);font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--cx-size-12px);}
74
68
  .cx-diff-expand{min-height:20px;padding:0 var(--cx-size-4px);font:inherit;color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));background:none;border:0;border-radius:var(--hfx-radius-sm,4px);cursor:pointer;}
75
- .cx-diff-expand::before{content:"\22EF ";color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
69
+ .cx-diff-expand::before{content:"\22EF ";color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
76
70
  .cx-diff-expand:hover{text-decoration:underline;}
77
71
  .cx-diff-current{box-shadow:inset var(--cx-size-3px) 0 0 var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
78
72
  .cx-diff-current:dir(rtl){box-shadow:inset calc(var(--cx-size-3px) * -1) 0 0 var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
@@ -81,48 +75,36 @@ color:color-mix(in srgb,var(--cx-chg-diff) 70%,var(--hfx-color-text,light-dark(#
81
75
  .cx-changes{container-type:inline-size;display:flex;flex-direction:column;gap:var(--cx-size-8px);}
82
76
  .cx-chg-bar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-8px) var(--cx-size-12px);}
83
77
  .cx-chg-kinds{display:flex;flex-wrap:wrap;gap:var(--cx-size-6px);}
84
- .cx-chg-kind{display:inline-flex;align-items:center;gap:var(--cx-size-6px);min-height:var(--cx-size-30px);padding:0 var(--cx-size-8px) 0 var(--cx-size-4px);font:inherit;color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));
85
- background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border:var(--cx-size-1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));cursor:pointer;}
86
- .cx-chg-kind[aria-pressed="true"]{border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));}
78
+ .cx-chg-kind{padding-inline-start:var(--hfx-space-1,0.25rem);}
87
79
  .cx-chg-count{font-size:var(--cx-size-13px);font-weight:600;font-variant-numeric:tabular-nums;}
88
80
  .cx-chg-switch{display:inline-flex;align-items:center;gap:var(--cx-size-6px);min-height:var(--cx-size-30px);font-size:var(--cx-size-13px);cursor:pointer;}
89
- .cx-chg-switch input{width:var(--cx-size-16px);height:var(--cx-size-16px);margin:0;accent-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
90
- .cx-chg-summary{margin-inline-start:auto;font-size:var(--cx-size-13px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-variant-numeric:tabular-nums;}
81
+ .cx-chg-summary{margin-inline-start:auto;font-size:var(--cx-size-13px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-variant-numeric:tabular-nums;}
91
82
  .cx-chg-printnote{display:none;}
92
83
  .cx-chg-tools{display:flex;flex-wrap:wrap;gap:var(--cx-size-6px);}
93
84
  .cx-chg-summary:empty ~ .cx-chg-tools{margin-inline-start:auto;}
94
85
  a.cx-chg-action{text-decoration:none;}
95
86
  .cx-chg-panel{display:grid;gap:var(--cx-size-6px);max-width:var(--cx-size-640px);margin:0 var(--cx-size-12px) var(--cx-size-10px) calc(var(--cx-size-30px) + var(--cx-size-16px));padding:var(--cx-size-10px) var(--cx-size-12px);
96
- background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
87
+ background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
97
88
  .cx-chg-barpanel > .cx-chg-panel{margin:var(--cx-size-8px) 0 0;}
98
89
  .cx-chg-asklabel{font-size:var(--cx-size-13px);font-weight:600;}
99
- .cx-chg-reasonbox{box-sizing:border-box;width:100%;min-height:var(--cx-size-56px);padding:var(--cx-size-6px) var(--cx-size-8px);font:inherit;font-size:var(--cx-size-13px);color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));
100
- border:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);resize:vertical;}
101
- .cx-chg-reasonbox:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
90
+ .cx-chg-reasonbox{inline-size:100%;resize:vertical;}
102
91
  .cx-chg-reasonbox[aria-invalid="true"]{border-color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
103
- .cx-chg-hint{font-size:var(--cx-size-12px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
92
+ .cx-chg-hint{font-size:var(--cx-size-12px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
104
93
  .cx-chg-askerror{font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
105
94
  .cx-chg-askerror:empty{display:none;}
106
95
  .cx-chg-askbtns{display:flex;flex-wrap:wrap;gap:var(--cx-size-6px);}
107
- .cx-chg-action.cx-chg-primary{color:var(--hfx-color-accent-contrast,light-dark(#ffffff,#0c0d10));background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
108
96
  .cx-chg-note{margin:0;font-size:var(--cx-size-13px);}
109
- .cx-chg-badge{display:inline-flex;align-items:center;box-sizing:border-box;max-width:100%;min-height:var(--cx-size-22px);padding:0 var(--cx-size-8px);overflow:hidden;font-size:var(--cx-size-12px);font-weight:600;
110
- white-space:nowrap;text-overflow:ellipsis;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));border:var(--cx-size-1px) solid currentColor;border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
111
- .cx-chg-badge.cx-tone-success{color:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
112
- .cx-chg-badge.cx-tone-danger{color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
113
- .cx-chg-badge.cx-tone-info{color:var(--hfx-color-status-info-fg,light-dark(#2b5fc0,#74a2f7));}
114
- .cx-chg-badge.cx-tone-warning{color:var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640));}
115
- .cx-chg-badge.cx-toned{color:var(--cx-t);}
97
+ .cx-chg-badge{max-width:100%;overflow:hidden;text-overflow:ellipsis;}
116
98
  .cx-chg-list,.cx-chg-sublist,.cx-chg-reasons{list-style:none;margin:0;padding:0;}
117
- .cx-chg-list{border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));}
118
- .cx-chg-folder{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--cx-size-6px);padding:var(--cx-size-6px) var(--cx-size-12px);background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
119
- .cx-chg-group + .cx-chg-group .cx-chg-folder{border-top:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
99
+ .cx-chg-list{border:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
100
+ .cx-chg-folder{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--cx-size-6px);padding:var(--cx-size-6px) var(--cx-size-12px);background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
101
+ .cx-chg-group + .cx-chg-group .cx-chg-folder{border-top:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
120
102
  .cx-chg-foldername{font-family:var(--hfx-font-mono,"Cascadia Mono","Cascadia Code",Consolas,"SFMono-Regular",Menlo,monospace);font-size:var(--cx-size-12px);font-weight:600;overflow-wrap:anywhere;}
121
- .cx-chg-foldercount{font-size:var(--cx-size-12px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
122
- .cx-chg-item + .cx-chg-item{border-top:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
103
+ .cx-chg-foldercount{font-size:var(--cx-size-12px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
104
+ .cx-chg-item + .cx-chg-item{border-top:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
123
105
  .cx-chg-row{display:grid;grid-template-columns:var(--cx-size-30px) var(--cx-size-112px) minmax(0,1fr) auto auto;grid-template-areas:"toggle badge main meta actions";align-items:center;
124
106
  column-gap:var(--cx-size-10px);row-gap:var(--cx-size-4px);padding:var(--cx-size-6px) var(--cx-size-12px) var(--cx-size-6px) var(--cx-size-6px);}
125
- .cx-chg-toggle{grid-area:toggle;display:inline-flex;align-items:center;justify-content:center;width:var(--cx-size-30px);height:var(--cx-size-30px);padding:0;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));background:none;border:0;border-radius:var(--hfx-radius-sm,4px);cursor:pointer;}
107
+ .cx-chg-toggle{grid-area:toggle;display:inline-flex;align-items:center;justify-content:center;width:var(--cx-size-30px);height:var(--cx-size-30px);padding:0;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));background:none;border:0;border-radius:var(--hfx-radius-sm,4px);cursor:pointer;}
126
108
  .cx-chg-toggle .cx-chg-ico{transition:transform .12s;}
127
109
  .cx-chg-toggle[aria-expanded="true"] .cx-chg-ico{transform:rotate(90deg);}
128
110
  .cx-chg-toggle:dir(rtl) .cx-chg-ico{transform:scaleX(-1);}
@@ -131,10 +113,10 @@ column-gap:var(--cx-size-10px);row-gap:var(--cx-size-4px);padding:var(--cx-size-
131
113
  .cx-chg-main{grid-area:main;min-width:0;display:grid;gap:var(--cx-size-2px);}
132
114
  .cx-chg-title{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--cx-size-2px) var(--cx-size-8px);min-width:0;}
133
115
  .cx-chg-name{font-family:var(--hfx-font-mono,"Cascadia Mono","Cascadia Code",Consolas,"SFMono-Regular",Menlo,monospace);font-size:var(--cx-size-13px);font-weight:600;overflow-wrap:anywhere;}
134
- .cx-chg-from,.cx-chg-sub{font-size:var(--cx-size-12px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));overflow-wrap:anywhere;}
116
+ .cx-chg-from,.cx-chg-sub{font-size:var(--cx-size-12px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));overflow-wrap:anywhere;}
135
117
  .cx-chg-flags{display:flex;flex-wrap:wrap;gap:var(--cx-size-4px);}
136
118
  .cx-chg-flag{display:inline-flex;align-items:center;gap:var(--cx-size-4px);padding:var(--cx-size-1px) var(--cx-size-8px) var(--cx-size-1px) var(--cx-size-6px);font-size:var(--cx-size-12px);font-weight:600;
137
- color:var(--cx-chg-flag,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));background:color-mix(in srgb,var(--cx-chg-flag,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))) 12%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));border-radius:var(--hfx-radius-sm,4px);}
119
+ color:var(--cx-chg-flag,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))));background:color-mix(in srgb,var(--cx-chg-flag,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)))) 12%,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));border-radius:var(--hfx-radius-sm,4px);}
138
120
  .cx-chg-flag .cx-chg-ico{width:var(--cx-size-12px);height:var(--cx-size-12px);}
139
121
  .cx-chg-flag.cx-tone-warning,.cx-chg-reason.cx-tone-warning{--cx-chg-flag:var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640));}
140
122
  .cx-chg-flag.cx-tone-danger,.cx-chg-reason.cx-tone-danger{--cx-chg-flag:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
@@ -144,26 +126,26 @@ color:var(--cx-chg-flag,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));backg
144
126
  .cx-chg-size{text-align:end;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));}
145
127
  .cx-chg-hash{display:inline-flex;align-items:center;gap:var(--cx-size-2px);min-width:calc(var(--cx-size-150px) + var(--cx-size-56px));white-space:nowrap;}
146
128
  .cx-chg-hashbtn{padding:var(--cx-size-1px) var(--cx-size-4px);font-family:var(--hfx-font-mono,"Cascadia Mono","Cascadia Code",Consolas,"SFMono-Regular",Menlo,monospace);font-size:var(--cx-size-12px);color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));background:none;border:0;border-radius:var(--hfx-radius-sm,4px);cursor:copy;}
147
- .cx-chg-arrow{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
129
+ .cx-chg-arrow{color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
148
130
  .cx-chg-actions{grid-area:actions;display:flex;gap:var(--cx-size-4px);justify-content:flex-end;}
149
- .cx-chg-action:not(.cx-chg-textaction){padding:0;width:var(--cx-size-30px);}
131
+ .cx-chg-action:not(.cx-chg-textaction){padding:0;inline-size:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));}
150
132
  .cx-chg-detail{display:grid;gap:var(--cx-size-10px);padding:var(--cx-size-4px) var(--cx-size-12px) var(--cx-size-12px) calc(var(--cx-size-30px) + var(--cx-size-16px));}
151
- .cx-chg-dhead{font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));text-transform:uppercase;letter-spacing:var(--cx-size-d04em);}
133
+ .cx-chg-dhead{font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));text-transform:uppercase;letter-spacing:var(--cx-size-d04em);}
152
134
  .cx-chg-reasons{display:grid;gap:var(--cx-size-4px);font-size:var(--cx-size-13px);}
153
- .cx-chg-reason{color:var(--cx-chg-flag,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
135
+ .cx-chg-reason{color:var(--cx-chg-flag,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))));}
154
136
  .cx-chg-facts{border-collapse:collapse;font-size:var(--cx-size-13px);width:100%;max-width:var(--cx-size-640px);}
155
- .cx-chg-facts :is(th,td){padding:var(--cx-size-4px) var(--cx-size-10px);text-align:start;vertical-align:top;border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
156
- .cx-chg-facts thead th{font-size:var(--cx-size-12px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-weight:600;background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
157
- .cx-chg-facts tbody th{font-weight:400;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));white-space:nowrap;}
137
+ .cx-chg-facts :is(th,td){padding:var(--cx-size-4px) var(--cx-size-10px);text-align:start;vertical-align:top;border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
138
+ .cx-chg-facts thead th{font-size:var(--cx-size-12px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-weight:600;background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
139
+ .cx-chg-facts tbody th{font-weight:400;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));white-space:nowrap;}
158
140
  .cx-chg-mono{font-family:var(--hfx-font-mono,"Cascadia Mono","Cascadia Code",Consolas,"SFMono-Regular",Menlo,monospace);font-size:var(--cx-size-12px);overflow-wrap:anywhere;}
159
141
  .cx-chg-changed{font-weight:600;}
160
- .cx-chg-factnote{margin-top:var(--cx-size-2px);font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--cx-size-12px);font-weight:400;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
142
+ .cx-chg-factnote{margin-top:var(--cx-size-2px);font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--cx-size-12px);font-weight:400;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
161
143
  .cx-chg-facts.cx-chg-onevalue :is(th,td):first-child{width:28%;}
162
144
  .cx-chg-facts td.cx-tone-warning{color:var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640));}
163
145
  .cx-chg-facts td.cx-tone-danger{color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
164
146
  .cx-chg-facts td.cx-tone-success{color:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
165
147
  .cx-chg-diff{--cx-diff-max-height:var(--cx-size-480px);min-width:0;}
166
- .cx-chg-empty{padding:var(--cx-size-16px);text-align:center;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));border:var(--cx-size-1px) dashed var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
148
+ .cx-chg-empty{padding:var(--cx-size-16px);text-align:center;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));border:var(--cx-size-1px) dashed var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
167
149
  .cx-chg-more{align-self:flex-start;}
168
150
  @container (max-width:700px){
169
151
  .cx-chg-row{grid-template-columns:var(--cx-size-30px) minmax(0,1fr) auto;grid-template-areas:"toggle badge actions" ". main main" ". meta meta";}
@@ -175,42 +157,42 @@ color:var(--cx-chg-flag,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));backg
175
157
  .cx-prop{container-type:inline-size;display:flex;flex-direction:column;gap:var(--cx-size-10px);}
176
158
  .cx-prop-head{display:flex;flex-wrap:wrap;align-items:center;gap:var(--cx-size-6px) var(--cx-size-10px);}
177
159
  .cx-prop-summary{font-size:var(--cx-size-14px);}
178
- :is(.cx-prop-state,.cx-prop-key,.cx-prop-badge){display:inline-flex;align-items:center;gap:var(--cx-size-4px);font-weight:600;color:var(--cx-chg-state,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
179
- .cx-prop-state{padding:var(--cx-size-2px) var(--cx-size-8px) var(--cx-size-2px) var(--cx-size-6px);border-radius:var(--hfx-radius-sm,4px);background:color-mix(in srgb,var(--cx-chg-state,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))) 10%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
180
- .cx-prop-badge.cx-prop-attn{padding:0 var(--cx-size-6px) 0 var(--cx-size-4px);border-radius:var(--hfx-radius-sm,4px);background:color-mix(in srgb,var(--cx-chg-state) 12%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
160
+ :is(.cx-prop-state,.cx-prop-key,.cx-prop-badge){display:inline-flex;align-items:center;gap:var(--cx-size-4px);font-weight:600;color:var(--cx-chg-state,var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d))));}
161
+ .cx-prop-state{padding:var(--cx-size-2px) var(--cx-size-8px) var(--cx-size-2px) var(--cx-size-6px);border-radius:var(--hfx-radius-sm,4px);background:color-mix(in srgb,var(--cx-chg-state,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)))) 10%,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));}
162
+ .cx-prop-badge.cx-prop-attn{padding:0 var(--cx-size-6px) 0 var(--cx-size-4px);border-radius:var(--hfx-radius-sm,4px);background:color-mix(in srgb,var(--cx-chg-state) 12%,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));}
181
163
  :is(.cx-prop-state,.cx-prop-key,.cx-prop-badge,.cx-prop-fill).cx-tone-success{--cx-chg-state:var(--hfx-color-status-good-fg,light-dark(#177345,#4cc78a));}
182
164
  :is(.cx-prop-state,.cx-prop-key,.cx-prop-badge,.cx-prop-fill).cx-tone-warning{--cx-chg-state:var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640));}
183
165
  :is(.cx-prop-state,.cx-prop-key,.cx-prop-badge,.cx-prop-fill).cx-tone-danger{--cx-chg-state:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
184
- :is(.cx-prop-state,.cx-prop-key,.cx-prop-badge,.cx-prop-fill).cx-tone-muted{--cx-chg-state:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
166
+ :is(.cx-prop-state,.cx-prop-key,.cx-prop-badge,.cx-prop-fill).cx-tone-muted{--cx-chg-state:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
185
167
  .cx-prop-counts{display:flex;flex-wrap:wrap;gap:var(--cx-size-4px) var(--cx-size-16px);margin:0;padding:0;list-style:none;font-size:var(--cx-size-13px);}
186
168
  .cx-prop-count{display:inline-flex;align-items:center;gap:var(--cx-size-6px);}
187
- .cx-prop-key{font-weight:400;color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
169
+ .cx-prop-key{font-weight:400;color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
188
170
  .cx-prop-key .cx-chg-ico{color:var(--cx-chg-state);}
189
171
  .cx-prop-number{font-weight:600;font-variant-numeric:tabular-nums;}
190
- .cx-prop-table{width:100%;border-collapse:collapse;font-size:var(--cx-size-13px);background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));border:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
191
- .cx-prop-table :is(th,td){padding:var(--cx-size-6px) var(--cx-size-10px);text-align:start;vertical-align:top;border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
192
- .cx-prop-table thead th{font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));white-space:nowrap;}
172
+ .cx-prop-table{width:100%;border-collapse:collapse;font-size:var(--cx-size-13px);background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));border:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
173
+ .cx-prop-table :is(th,td){padding:var(--cx-size-6px) var(--cx-size-10px);text-align:start;vertical-align:top;border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
174
+ .cx-prop-table thead th{font-size:var(--cx-size-12px);font-weight:600;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));white-space:nowrap;}
193
175
  .cx-prop-table tbody th{font-weight:600;}
194
176
  .cx-prop-group th{font-size:var(--cx-size-12px);font-weight:600;background:var(--hfx-color-row-alt,light-dark(#fafafa,#1d1f23));}
195
- .cx-prop-groupcount{font-weight:400;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
177
+ .cx-prop-groupcount{font-weight:400;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
196
178
  .cx-prop-name{margin-inline-end:var(--cx-size-6px);}
197
- .cx-prop-source{display:inline-block;padding:0 var(--cx-size-6px);font-size:var(--cx-size-11px);font-weight:600;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));border:var(--cx-size-1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
198
- .cx-prop-sub,.cx-prop-delay,.cx-prop-none{display:block;font-size:var(--cx-size-12px);font-weight:400;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
179
+ .cx-prop-source{display:inline-block;padding:0 var(--cx-size-6px);font-size:var(--cx-size-11px);font-weight:600;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));border:var(--cx-size-1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));}
180
+ .cx-prop-sub,.cx-prop-delay,.cx-prop-none{display:block;font-size:var(--cx-size-12px);font-weight:400;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
199
181
  .cx-prop-first,.cx-prop-last{white-space:nowrap;font-variant-numeric:tabular-nums;}
200
182
  .cx-prop-lanecell{width:var(--cx-size-160px);vertical-align:middle !important;}
201
183
  .cx-prop-lane{position:relative;height:var(--cx-size-8px);min-width:var(--cx-size-92px);background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));overflow:hidden;}
202
- .cx-prop-fill{height:100%;background:color-mix(in srgb,var(--cx-chg-state,var(--hfx-color-text-muted,light-dark(#626770,#8f949d))) 70%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));border-radius:inherit;}
203
- .cx-prop-fill.cx-prop-open{background:repeating-linear-gradient(135deg,color-mix(in srgb,var(--cx-chg-state) 55%,var(--hfx-color-surface,light-dark(#ffffff,#16181c))) 0 var(--cx-size-4px),transparent var(--cx-size-4px) var(--cx-size-8px));}
184
+ .cx-prop-fill{height:100%;background:color-mix(in srgb,var(--cx-chg-state,var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)))) 70%,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));border-radius:inherit;}
185
+ .cx-prop-fill.cx-prop-open{background:repeating-linear-gradient(135deg,color-mix(in srgb,var(--cx-chg-state) 55%,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)))) 0 var(--cx-size-4px),transparent var(--cx-size-4px) var(--cx-size-8px));}
204
186
  @container (max-width:560px){
205
187
  .cx-prop-table thead{display:none;}
206
188
  .cx-prop-table,.cx-prop-table tbody{display:block;}
207
- .cx-prop-table tr{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"name state" "first last" "lane lane";column-gap:var(--cx-size-10px);padding:var(--cx-size-8px) var(--cx-size-10px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
189
+ .cx-prop-table tr{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"name state" "first last" "lane lane";column-gap:var(--cx-size-10px);padding:var(--cx-size-8px) var(--cx-size-10px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
208
190
  .cx-prop-table tr.cx-prop-group{display:block;padding:var(--cx-size-6px) var(--cx-size-10px);background:var(--hfx-color-row-alt,light-dark(#fafafa,#1d1f23));}
209
191
  .cx-prop-table :is(th,td){display:block;padding:0;border:0;}
210
192
  .cx-prop-row > th{grid-area:name;}
211
193
  .cx-prop-statecell{grid-area:state;text-align:end;}
212
194
  .cx-prop-first{grid-area:first;margin-top:var(--cx-size-4px);}
213
- .cx-prop-last{grid-area:last;margin-top:var(--cx-size-4px);text-align:end;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
195
+ .cx-prop-last{grid-area:last;margin-top:var(--cx-size-4px);text-align:end;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
214
196
  .cx-prop-lanecell{grid-area:lane;width:auto;margin-top:var(--cx-size-6px);}
215
197
  }
216
198
  @media print{
@@ -222,9 +204,9 @@ color:var(--cx-chg-flag,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));backg
222
204
  .cx-diff,.cx-changes,.cx-prop{-webkit-print-color-adjust:exact;print-color-adjust:exact;}
223
205
  .cx-diff-printtable{width:100%;border-collapse:collapse;font-family:var(--hfx-font-mono,"Cascadia Mono","Cascadia Code",Consolas,"SFMono-Regular",Menlo,monospace);font-size:var(--cx-size-11px);}
224
206
  .cx-diff-printtable td{padding:0 var(--cx-size-4px);vertical-align:top;}
225
- .cx-diff-printtable :is(.cx-diff-num,.cx-diff-sign){width:1%;white-space:nowrap;text-align:end;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
207
+ .cx-diff-printtable :is(.cx-diff-num,.cx-diff-sign){width:1%;white-space:nowrap;text-align:end;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));}
226
208
  .cx-diff-printtable .cx-diff-code{white-space:pre-wrap;word-break:break-all;}
227
- .cx-diff-printtable tr:is(.cx-diff-del,.cx-diff-add){background:color-mix(in srgb,var(--cx-chg-diff) 12%,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
209
+ .cx-diff-printtable tr:is(.cx-diff-del,.cx-diff-add){background:color-mix(in srgb,var(--cx-chg-diff) 12%,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));}
228
210
  .cx-chg-row{grid-template-columns:var(--cx-size-112px) minmax(0,1fr) auto;grid-template-areas:"badge main meta";}
229
211
  .cx-chg-facts{table-layout:fixed;max-width:none;}
230
212
  .cx-chg-facts thead th:first-child{width:28%;}
@@ -1,4 +1,7 @@
1
- (function(global){"use strict";const installed=new WeakSet();const part={version:"2810fb06a78b85e3",install(context){if(installed.has(context.CHANGES_IMPL))return;const{CHANGES_IMPL,h,setText,fill,plural,numberFormat,gridFreeze,toneOf,applyTone,svgIcon,PROTOCOL}=context;const CHANGE_LABELS={changeInline:"Inline",changeSplit:"Side by side",changeLayout:"Layout",changeCopyDiff:"Copy diff",changeCopied:"Copied",changeCopyFailed:"Could not copy",changeNext:"Next change",changePrevious:"Previous change",changePosition:"Change {index} of {count}",changeShowLines:"[one]Show {count} more line[other]Show {count} more lines",changeHiddenLines:"[one]{count} unchanged line not included[other]{count} unchanged lines not included",changeLineCounts:"Lines added: {added}, removed: {removed}",changeLineAdded:"Added line {line}",changeLineRemoved:"Removed line {line}",changeLineContext:"Line {line}",changeBefore:"Before",changeAfter:"After",changeBinary:"Binary file: compared by size and hash, not by lines.",changeUnavailable:"The content of this file is not available.",changeIdentical:"The text did not change.",changeTruncated:"Some changes are not shown: the comparison was too large.",changeTooLarge:"These texts are too long to compare here.",changeDiffOf:"Changes in {name}",changeAdded:"Added",changeRemoved:"Removed",changeModified:"Modified",changeRenamed:"Renamed",changeFlaggedOnly:"Flagged only",changeFlaggedCount:"{count} flagged",changeNoItems:"No changes to show.",changeSize:"Size",changeHash:"Hash",changeTime:"Time",changeCopyHash:"Copy the full hash",changeDetails:"Details of {name}",changeFileCount:"[one]{count} file[other]{count} files",changeFrom:"from {path}",changeShowMore:"Show more",changeFlags:"Flags",changeFacts:"Details",changeRoot:"Top level",changeShown:"{shown} of {total} shown",changeFilter:"Show changes",changeActions:"Actions for {name}",changeConverged:"Converged",changePropagating:"Propagating",changeFault:"Fault",changeUnknown:"Unknown",changeReplica:"Replica",changeState:"State",changeFirstSeen:"First seen",changeLastSeen:"Last seen",changeTimeline:"Delay",changeNotSeen:"Not seen yet",changeDelay:"+{duration}",changeSource:"Source",changeProgress:"{converged} of {total} have the change",changeSeconds:"{count} s",changeMinutes:"{count} min",changeHours:"{count} h",changeDays:"{count} d",changeUtcTime:"{time} UTC",changeExportCsv:"Export CSV",changeExportJson:"Export JSON",changeReason:"Reason",changeReasonHint:"{action}: say why. The reason is kept with the action.",changeReasonRequired:"Enter a reason first.",changeCancel:"Cancel",changeUnclaimed:"This page cannot carry out “{action}” itself. Copy the request to pass it on.",changeCopyRequest:"Copy request",changeFiltered:"Filtered: {filters}",changePrintLimit:"[one]{count} more line is not printed.[other]{count} more lines are not printed."};function changeLabels(...sources){const labels={...CHANGE_LABELS};for(const source of sources){if(source==null)continue;if(typeof source!=="object"||Array.isArray(source))changeFail("labels must be an object of strings");for(const[name,text]of Object.entries(source)){if(!Object.hasOwn(labels,name)){if(/^change[A-Z]/.test(name)) changeFail("there is no change label '" + name + "'"); continue; }
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"7d9a526aa07a8838",install(context){if(installed.has(context.CHANGES_IMPL))return;const{CHANGES_IMPL,h,setText,fill,plural,numberFormat,gridFreeze,toneOf,applyTone,svgIcon,PROTOCOL}=context;function humanTimeFormat(lang,local,utcTemplate){const formatter=new Intl.DateTimeFormat(lang||undefined,{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hourCycle:"h23",timeZone:local?undefined:"UTC",...(local?{timeZoneName:"short"}:{})});return{format(value){const parts=formatter.formatToParts(new Date(value));const text=parts.map((part,index)=>part.type==="literal"&&parts[index+1]?.type==="timeZoneName"?part.value.replace(/\s/g,"\u00a0"):part.value).join("");
2
+ return local?text:fill(utcTemplate||"{time} UTC",{time:text}).replace(/ (\S+)$/,"\u00a0$1");
3
+ }}}
4
+ const CHANGE_LABELS={changeInline:"Inline",changeSplit:"Side by side",changeLayout:"Layout",changeCopyDiff:"Copy diff",changeCopied:"Copied",changeCopyFailed:"Could not copy",changeNext:"Next change",changePrevious:"Previous change",changePosition:"Change {index} of {count}",changeShowLines:"[one]Show {count} more line[other]Show {count} more lines",changeHiddenLines:"[one]{count} unchanged line not included[other]{count} unchanged lines not included",changeLineCounts:"Lines added: {added}, removed: {removed}",changeLineAdded:"Added line {line}",changeLineRemoved:"Removed line {line}",changeLineContext:"Line {line}",changeBefore:"Before",changeAfter:"After",changeBinary:"Binary file: compared by size and hash, not by lines.",changeUnavailable:"The content of this file is not available.",changeIdentical:"The text did not change.",changeTruncated:"Some changes are not shown: the comparison was too large.",changeTooLarge:"These texts are too long to compare here.",changeDiffOf:"Changes in {name}",changeAdded:"Added",changeRemoved:"Removed",changeModified:"Modified",changeRenamed:"Renamed",changeFlaggedOnly:"Flagged only",changeFlaggedCount:"{count} flagged",changeNoItems:"No changes to show.",changeSize:"Size",changeHash:"Hash",changeTime:"Time",changeCopyHash:"Copy the full hash",changeDetails:"Details of {name}",changeFileCount:"[one]{count} file[other]{count} files",changeFrom:"from {path}",changeShowMore:"Show more",changeFlags:"Flags",changeFacts:"Details",changeRoot:"Top level",changeShown:"{shown} of {total} shown",changeFilter:"Show changes",changeActions:"Actions for {name}",changeConverged:"Converged",changePropagating:"Propagating",changeFault:"Fault",changeUnknown:"Unknown",changeReplica:"Replica",changeState:"State",changeFirstSeen:"First seen",changeLastSeen:"Last seen",changeTimeline:"Delay",changeNotSeen:"Not seen yet",changeDelay:"+{duration}",changeSource:"Source",changeProgress:"{converged} of {total} have the change",changeSeconds:"{count} s",changeMinutes:"{count} min",changeHours:"{count} h",changeDays:"{count} d",changeUtcTime:"{time} UTC",changeExportCsv:"Export CSV",changeExportJson:"Export JSON",changeReason:"Reason",changeReasonHint:"{action}: say why. The reason is kept with the action.",changeReasonRequired:"Enter a reason first.",changeCancel:"Cancel",changeUnclaimed:"This page cannot carry out “{action}” itself. Copy the request to pass it on.",changeCopyRequest:"Copy request",changeFiltered:"Filtered: {filters}",changePrintLimit:"[one]{count} more line is not printed.[other]{count} more lines are not printed."};function changeLabels(...sources){const labels={...CHANGE_LABELS};for(const source of sources){if(source==null)continue;if(typeof source!=="object"||Array.isArray(source))changeFail("labels must be an object of strings");for(const[name,text]of Object.entries(source)){if(!Object.hasOwn(labels,name)){if(/^change[A-Z]/.test(name)) changeFail("there is no change label '" + name + "'"); continue; }
2
5
  if(typeof text!=="string"||!/\S/.test(text)) changeFail("label '" + name + "' must be a string with visible text");
3
6
  labels[name]=text}}
4
7
  return Object.freeze(labels)}
@@ -37,7 +40,7 @@ return Object.freeze(values)}
37
40
  function changeDiffChecked(diff){changeLabels(diff.labels);return diff}
38
41
  function changesDocument(input){const doc=changeEnvelope(input,"changes",["id","label","actions","toolbar","values","exports","items","groupByFolder","flaggedOnly","expandFlagged","hashLength","pageSize","timeZone","labels"]);changeLabels(doc.labels);const actionIds=new Set(),actions=changeList(doc.actions,"actions",8).map(entry=>changeAction(entry,actionIds));const barIds=new Set(actionIds),listValues=changeValues(doc.values,"the change list"),toolbar=changeList(doc.toolbar,"toolbar",8).map(entry=>{const action=changeAction(entry,barIds),key=action.copy??action.link;if(action.reveal!=="none")changeFail("the bar action '"+action.id+"' has no item to reveal");if(key!==null&&!Object.hasOwn(listValues,key))changeFail("the bar action '"+action.id+"' uses the list value '"+key+"', which the list does not have");return action});const exports=changeList(doc.exports,"exports",2);if(exports.some(name=>name!=="csv"&&name!=="json")||new Set(exports).size!==exports.length)changeFail("exports are csv and json, each once");const ids=new Set(),items=changeList(doc.items,"items",10000).map((entry,index)=>{const item=changeKeys(entry,["id","kind","path","previousPath","kindLabel","secondary","before","after","facts","flags","diff","actions","values"],"an item");const id=changeId(item.id,"an item id"),what="the item '"+id+"'";if(ids.has(id))changeFail(what+" appears twice");ids.add(id);const kind=changeEnum(item.kind,CHANGE_KINDS,what+" kind"),path=changeLine(item.path,what+" path",2048),previousPath=changeLine(item.previousPath,what+" previous path",2048);if(kind===undefined||path===null||!/\S/.test(path)) changeFail(what + " needs a kind and a path");
39
42
  if(kind==="renamed"&&previousPath===null||(kind==="added"||kind==="removed")&&previousPath!==null)changeFail(what+" has a previous path only when it is renamed or modified, and always when renamed");const facts=changeList(item.facts,what+" facts",32).map(value=>{const fact=changeKeys(value,["label","before","after","tone","note"],"a fact");if(fact.before===undefined&&fact.after===undefined)changeFail(what+" has a fact without a value");return Object.freeze({label:changeText(fact.label,"a fact label",200),before:changeText(fact.before,"a fact value",2000,true),after:changeText(fact.after,"a fact value",2000,true),tone:changeTone(fact.tone,"a fact"),note:changeText(fact.note,"a fact note",500,true)})});const flagIds=new Set(),flags=changeList(item.flags,what+" flags",16).map(value=>{const flag=changeKeys(value,["id","label","reason","tone"],"a flag"),flagId=changeId(flag.id,"a flag id",64);if(flagIds.has(flagId))changeFail(what+" has the flag '"+flagId+"' twice");flagIds.add(flagId);return Object.freeze({id:flagId,label:changeText(flag.label,"a flag label",64),reason:changeText(flag.reason,"a flag reason",500),tone:changeTone(flag.tone,"a flag")||"warning"})});const offered=changeList(item.actions,what+" actions",8);for(const action of offered)if(!actionIds.has(action))changeFail(what+" offers the undeclared action '"+action+"'");const values=changeValues(item.values,what);return Object.freeze({id,index,kind,path,previousPath,kindLabel:changeText(item.kindLabel,what+" kind label",64,true),secondary:changeText(item.secondary,what+" secondary text",200,true),before:changeVersion(item.before,what+" before"),after:changeVersion(item.after,what+" after"),facts:Object.freeze(facts),flags:Object.freeze(flags),diff:item.diff===undefined?null:changeDiffChecked(diffBody(item.diff,what+" diff")),actions:Object.freeze([...offered]),values})});return Object.freeze({id:changeId(doc.id,"the change list id"),label:changeText(doc.label,"the label",200),actions:Object.freeze(actions),toolbar:Object.freeze(toolbar),values:listValues,exports:Object.freeze([...exports]),items:Object.freeze(items),groupByFolder:doc.groupByFolder!==false&&changeFlag(doc.groupByFolder??true,"groupByFolder"),flaggedOnly:changeFlag(doc.flaggedOnly,"flaggedOnly"),expandFlagged:changeFlag(doc.expandFlagged,"expandFlagged"),hashLength:changeInteger(doc.hashLength,"hashLength",4,64,8),pageSize:changeInteger(doc.pageSize,"pageSize",10,1000,200),local:changeEnum(doc.timeZone,["utc","local"],"timeZone","utc")==="local",labels:doc.labels})}
40
- function propagationDocument(input){const doc=changeEnvelope(input,"propagation",["id","label","start","asOf","state","summary","title","groupCount","witnesses","timeZone","labels"]);const start=changeTime(doc.start,"start"),asOf=changeTime(doc.asOf,"asOf");if(start!==null&&asOf!==null&&start>asOf)changeFail("a propagation view starts before its evidence time");const groupCount=changeText(doc.groupCount,"the group count",200,true);if(groupCount!==null&&!changePluralText(groupCount))changeFail("the group count needs {count} in every form, and plural forms that end with [other]");const ids=new Set(),witnesses=changeList(doc.witnesses,"witnesses",2000).map(entry=>{const witness=changeKeys(entry,["id","label","secondary","state","firstSeen","lastSeen","note","source","group"],"a replica"),id=changeId(witness.id,"a replica id");if(ids.has(id))changeFail("the replica '"+id+"' appears twice");ids.add(id);const firstSeen=changeTime(witness.firstSeen,"firstSeen"),lastSeen=changeTime(witness.lastSeen,"lastSeen");if(firstSeen!==null&&lastSeen!==null&&firstSeen>lastSeen)changeFail("the replica '"+id+"' was first seen after it last reported");const state=changeEnum(witness.state,PROPAGATION_STATES,"a replica state");if(state===undefined)changeFail("the replica '"+id+"' needs a state");return Object.freeze({id,label:changeText(witness.label,"a replica label",200),secondary:changeText(witness.secondary,"a replica's secondary text",200,true),state,firstSeen,lastSeen,note:changeText(witness.note,"a replica note",500,true),source:changeFlag(witness.source,"source"),group:changeText(witness.group,"a replica group",200,true)})});if(!witnesses.length)changeFail("a propagation view has 1 to 2000 replicas");return Object.freeze({id:changeId(doc.id,"the propagation id"),label:changeText(doc.label,"the label",200),start,asOf,state:changeEnum(doc.state,PROPAGATION_STATES,"state",null),summary:changeText(doc.summary,"the summary",500,true),title:changeText(doc.title,"the title",200,true),groupCount,witnesses:Object.freeze(witnesses),local:changeEnum(doc.timeZone,["utc","local"],"timeZone","utc")==="local",labels:doc.labels})}
43
+ function propagationDocument(input){const doc=changeEnvelope(input,"propagation",["id","label","start","asOf","state","summary","title","groupCount","witnesses","timeZone","labels","timeSlider"]);const start=changeTime(doc.start,"start"),asOf=changeTime(doc.asOf,"asOf");if(start!==null&&asOf!==null&&start>asOf)changeFail("a propagation view starts before its evidence time");const groupCount=changeText(doc.groupCount,"the group count",200,true);if(groupCount!==null&&!changePluralText(groupCount))changeFail("the group count needs {count} in every form, and plural forms that end with [other]");const ids=new Set(),witnesses=changeList(doc.witnesses,"witnesses",2000).map(entry=>{const witness=changeKeys(entry,["id","label","secondary","state","firstSeen","lastSeen","note","source","group"],"a replica"),id=changeId(witness.id,"a replica id");if(ids.has(id))changeFail("the replica '"+id+"' appears twice");ids.add(id);const firstSeen=changeTime(witness.firstSeen,"firstSeen"),lastSeen=changeTime(witness.lastSeen,"lastSeen");if(firstSeen!==null&&lastSeen!==null&&firstSeen>lastSeen)changeFail("the replica '"+id+"' was first seen after it last reported");const state=changeEnum(witness.state,PROPAGATION_STATES,"a replica state");if(state===undefined)changeFail("the replica '"+id+"' needs a state");return Object.freeze({id,label:changeText(witness.label,"a replica label",200),secondary:changeText(witness.secondary,"a replica's secondary text",200,true),state,firstSeen,lastSeen,note:changeText(witness.note,"a replica note",500,true),source:changeFlag(witness.source,"source"),group:changeText(witness.group,"a replica group",200,true)})});if(!witnesses.length)changeFail("a propagation view has 1 to 2000 replicas");return Object.freeze({id:changeId(doc.id,"the propagation id"),label:changeText(doc.label,"the label",200),start,asOf,state:changeEnum(doc.state,PROPAGATION_STATES,"state",null),summary:changeText(doc.summary,"the summary",500,true),title:changeText(doc.title,"the title",200,true),groupCount,witnesses:Object.freeze(witnesses),local:changeEnum(doc.timeZone,["utc","local"],"timeZone","utc")==="local",labels:doc.labels})}
41
44
  const CHANGE_UNITS=["B","KB","MB","GB","TB"];function changeSize(bytes,lang){if(bytes<1024)return numberFormat(lang,0,0).format(bytes)+ " B";let value=bytes,unit=0;while(value>=1024&&unit<CHANGE_UNITS.length-1){value /= 1024; unit++; }
42
45
  return numberFormat(lang,0,1).format(value)+ " "+CHANGE_UNITS[unit]}
43
46
  const changePad=value=>(value<10?"0":"")+ value;function changeTimeText(ms,local,labels){const d=new Date(ms),get=local?["getFullYear","getMonth","getDate","getHours","getMinutes"]:["getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes"];const[year,month,day,hours,minutes]=get.map(name=>d[name]());const text=String(year).padStart(4,"0")+ "-"+changePad(month+1)+ "-"+changePad(day)+ " "+changePad(hours)+ ":"+changePad(minutes);return local?text:fill(labels.changeUtcTime,{time:text})}
@@ -97,7 +100,7 @@ class DiffView{constructor(host,options,doc){this.host=host;this.options=options
97
100
  emit(name,detail,callback){const event=new CustomEvent("canopyx:"+name,{detail,bubbles:true});this.host.dispatchEvent(event);if(typeof this.options[callback]==="function"){try{this.options[callback](detail,event)}catch(error){this.host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error,hook:callback},bubbles:true}))}}}
98
101
  prepare(){const doc=this.doc;this.tooLarge=doc.content==="text"&&!doc.hunks.length&&(doc.left.length>DIFF_CLIENT_LINES||doc.right.length>DIFF_CLIENT_LINES);this.hunks=doc.content!=="text"||this.tooLarge?[]:doc.hunks.length?doc.hunks:diffHunks(doc.left,doc.right,doc.context);const built=diffRows(doc,this.hunks);this.rows=built.rows;this.added=built.added;this.removed=built.removed}
99
102
  build(){const doc=this.doc,labels=this.labels,signal=this.lifetime.signal;const root=this.root=h("div","cx-diff");const head=h("div","cx-diff-head"),title=this.titleBox=h("div","cx-diff-title"),tools=this.tools=h("div","cx-diff-tools");head.append(title,tools);this.notes=h("div","cx-diff-notes");this.state=h("div","cx-diff-state");this.state.hidden=true;const scroll=this.scroll=h("div","cx-diff-scroll");scroll.tabIndex=0;scroll.setAttribute("role","table");this.columns=h("div","cx-diff-columns");this.columns.setAttribute("role","row");this.columns.setAttribute("aria-rowindex","1");this.canvas=h("div","cx-diff-canvas");this.canvas.setAttribute("role","rowgroup");scroll.append(this.columns,this.canvas);this.live=h("div","cx-sr-only");this.live.setAttribute("aria-live","polite");this.print=h("div","cx-diff-print");const frame=this.frameBox=h("div","cx-diff-frame");this.edgeStart=h("div","cx-diff-edge cx-diff-edge-start");this.edgeEnd=h("div","cx-diff-edge cx-diff-edge-end");this.edgeStart.hidden=this.edgeEnd.hidden=true;frame.append(scroll,this.edgeStart,this.edgeEnd);root.append(head,this.notes,this.state,frame,this.live,this.print);this.host.appendChild(root);this.probe=h("span","cx-diff-probe");setText(this.probe,"0000000000");root.appendChild(this.probe);this.buildTools();changeTips(root,signal);scroll.addEventListener("scroll",()=>{this.schedule();this.edges()},{passive:true,signal});scroll.addEventListener("keydown",event=>this.onKey(event),{signal});scroll.addEventListener("click",event=>this.onClick(event),{signal});global.addEventListener("beforeprint",()=>this.renderPrint(),{signal});this.resize=new ResizeObserver(()=>{if(!this.destroyed)this.layout()});this.resize.observe(root);this.refresh();if(changesInPrint())this.renderPrint()}
100
- buildTools(){const labels=this.labels,tools=this.tools,signal=this.lifetime.signal;const group=this.layoutGroup=h("div","cx-diff-seg");group.setAttribute("role","radiogroup");group.setAttribute("aria-label",labels.changeLayout);this.layoutButtons=["inline","split"].map(mode=>{const button=h("button","cx-diff-segbtn");button.type="button";button.setAttribute("role","radio");button._mode=mode;setText(button,mode==="inline"?labels.changeInline:labels.changeSplit);button.addEventListener("click",()=>this.setLayout(mode),{signal});button.addEventListener("keydown",event=>{if(!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(event.key))return;event.preventDefault();const next=mode==="inline"?"split":"inline";this.setLayout(next);this.layoutButtons.find(item=>item._mode===next).focus()},{signal});group.appendChild(button);return button});const button=(label,icon,action,text)=>{const element=h("button","cx-diff-btn");element.type="button";element.appendChild(changeIcon(icon));if(text){const name=h("span");setText(name,label);element.appendChild(name)}else{element.setAttribute("aria-label",label);element.setAttribute("data-cx-tip",label)}
103
+ buildTools(){const labels=this.labels,tools=this.tools,signal=this.lifetime.signal;const group=this.layoutGroup=h("div","cx-segmented cx-diff-seg");group.dataset.size="sm";group.setAttribute("role","radiogroup");group.setAttribute("aria-label",labels.changeLayout);this.layoutButtons=["inline","split"].map(mode=>{const button=h("button","cx-diff-segbtn");button.type="button";button.setAttribute("role","radio");button._mode=mode;setText(button,mode==="inline"?labels.changeInline:labels.changeSplit);button.addEventListener("click",()=>this.setLayout(mode),{signal});button.addEventListener("keydown",event=>{if(!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(event.key))return;event.preventDefault();const next=mode==="inline"?"split":"inline";this.setLayout(next);this.layoutButtons.find(item=>item._mode===next).focus()},{signal});group.appendChild(button);return button});const button=(label,icon,action,text)=>{const element=h("button","cx-btn cx-diff-btn");element.type="button";element.dataset.size="sm";element.appendChild(changeIcon(icon));if(text){const name=h("span");setText(name,label);element.appendChild(name)}else{element.dataset.icon="";element.setAttribute("aria-label",label);element.setAttribute("data-cx-tip",label)}
101
104
  element.addEventListener("click",action,{signal});return element};this.prevButton=button(labels.changePrevious,"up",()=>this.move(-1));this.nextButton=button(labels.changeNext,"down",()=>this.move(1));this.copyButton=button(labels.changeCopyDiff,"copy",()=>this.copy(),true);tools.append(group,this.prevButton,this.nextButton,this.copyButton)}
102
105
  refresh(){const doc=this.doc,labels=this.labels,title=this.titleBox;title.replaceChildren();const name=h("span","cx-diff-path");setText(name,doc.path?(doc.previousPath&&doc.previousPath!==doc.path?doc.previousPath+" → "+doc.path:doc.path):doc.label);title.appendChild(name);if(doc.content==="text"&&!this.tooLarge){const stats=h("span","cx-diff-stats"),plus=h("span","cx-diff-plus"),minus=h("span","cx-diff-minus");setText(plus,"+"+this.format.format(this.added));setText(minus,"−"+this.format.format(this.removed));const spoken=h("span","cx-sr-only");setText(spoken,fill(labels.changeLineCounts,{added:this.format.format(this.added),removed:this.format.format(this.removed)}));plus.setAttribute("aria-hidden","true");minus.setAttribute("aria-hidden","true");stats.append(plus,minus,spoken);title.appendChild(stats)}
103
106
  const notes=[];for(const note of doc.notes)notes.push([note.text,note.tone||"info"]);if(doc.truncated)notes.push([labels.changeTruncated,"warning"]);if(doc.message&&doc.content==="text")notes.push([doc.message,"info"]);this.notes.replaceChildren(...notes.map(([text,tone])=>{const note=h("div","cx-diff-note");applyTone(note,"cx-diff-note",toneOf(tone));setText(note,text);return note}));this.notes.hidden=!notes.length;const empty=doc.content!=="text"?doc.message||(doc.content==="binary"?labels.changeBinary:doc.content==="identical"?labels.changeIdentical:labels.changeUnavailable)
@@ -134,13 +137,13 @@ if(written>5000){const rest=this.rows.slice(5000).reduce((sum,row)=>sum +(row.t=
134
137
  table.appendChild(body);this.print.replaceChildren(table)},getHunks(){return this.hunks.map(hunk=>({before:hunk.before,after:hunk.after,lines:hunk.lines.map(line=>(line.kind==="="?" ":line.kind)+ line.text)}))},update(view){this.doc=diffDocument(view);this.labels=changeLabels(this.options.baseLabels,this.doc.labels,this.options.labels);this.source=view;this.current=-1;this.prepare();this.refresh()}});function diffCreate(host,options,doc){const view=new DiffView(host,options,doc);const impl={ready:Promise.resolve().then(()=>{if(view.destroyed)return impl;host.setAttribute("data-cx-ready","");view.emit("diffReady",{diff:view.doc.id},"onReady");return impl}),document:()=>view.source||options.view,getLayout:()=>view.shown,setLayout:mode=>view.setLayout(mode),next:()=>view.move(1),previous:()=>view.move(-1),expandAll:()=>view.expandAll(),copy:()=>view.copy(),getHunks:()=>view.getHunks(),update:next=>view.update(next),destroy:()=>{if(view.destroyed)return;view.destroyed=true;view.lifetime.abort();view.resize.disconnect();cancelAnimationFrame(view.frame);clearTimeout(view.copyTimer);view.root.remove();host.removeAttribute("data-cx-ready")}};return impl}
135
138
  class ChangeListView{constructor(host,options){this.host=host;this.options=options;this.lifetime=new AbortController();this.doc=changesDocument(options.view);this.labels=changeLabels(this.doc.labels,options.labels);this.lang=host.closest("[lang]")?.getAttribute("lang")||document.documentElement.lang||"en";this.format=numberFormat(this.lang);this.kinds=new Set();this.flaggedOnly=this.doc.flaggedOnly;this.limit=this.doc.pageSize;this.diffs=new Map();this.open=new Set(this.doc.expandFlagged?this.doc.items.filter(item=>item.flags.length).map(item=>item.id):[]);if(options.state)this.applyState(options.state,false);this.build()}
136
139
  emit(name,detail,callback){const event=new CustomEvent("canopyx:"+name,{detail,bubbles:true});this.host.dispatchEvent(event);if(typeof this.options[callback]==="function"){try{this.options[callback](detail,event)}catch(error){this.host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error,hook:callback},bubbles:true}))}}}
137
- build(){const signal=this.lifetime.signal;const root=this.root=h("div","cx-changes");this.bar=h("div","cx-chg-bar");this.list=h("ul","cx-chg-list");this.list.setAttribute("aria-label",this.doc.label);this.empty=h("div","cx-chg-empty");this.empty.hidden=true;this.more=h("button","cx-chg-more");this.more.type="button";this.more.hidden=true;this.live=h("div","cx-sr-only");this.live.setAttribute("aria-live","polite");this.barPanel=h("div","cx-chg-barpanel");root.append(this.bar,this.barPanel,this.list,this.empty,this.more,this.live);this.host.appendChild(root);root.addEventListener("click",event=>this.onClick(event),{signal});root.addEventListener("keydown",event=>this.onKey(event),{signal});changeTips(root,signal);root.addEventListener("change",event=>{if(event.target===this.flagSwitch){this.applyState({flaggedOnly:event.target.checked});this.flagSwitch?.focus()}},{signal});this.more.addEventListener("click",()=>{const shown=new Set([...this.list.querySelectorAll("[data-cx-item]")].map(item=>item.getAttribute("data-cx-item")));this.limit +=this.doc.pageSize;this.render();if(this.more.hidden)[...this.list.querySelectorAll("[data-cx-item]")].find(item=>!shown.has(item.getAttribute("data-cx-item")))?.querySelector(".cx-chg-toggle")?.focus()},{signal});this.printing=changesInPrint();global.addEventListener("beforeprint",()=>{this.printing=true;this.render()},{signal});global.addEventListener("afterprint",()=>{this.printing=false;this.render()},{signal});this.render()}
140
+ build(){const signal=this.lifetime.signal;const root=this.root=h("div","cx-changes");this.bar=h("div","cx-chg-bar");this.list=h("ul","cx-chg-list");this.list.setAttribute("aria-label",this.doc.label);this.empty=h("div","cx-chg-empty");this.empty.hidden=true;this.more=h("button","cx-btn cx-chg-more");this.more.dataset.size="sm";this.more.type="button";this.more.hidden=true;this.live=h("div","cx-sr-only");this.live.setAttribute("aria-live","polite");this.barPanel=h("div","cx-chg-barpanel");root.append(this.bar,this.barPanel,this.list,this.empty,this.more,this.live);this.host.appendChild(root);root.addEventListener("click",event=>this.onClick(event),{signal});root.addEventListener("keydown",event=>this.onKey(event),{signal});changeTips(root,signal);root.addEventListener("change",event=>{if(event.target===this.flagSwitch){this.applyState({flaggedOnly:event.target.checked});this.flagSwitch?.focus()}},{signal});this.more.addEventListener("click",()=>{const shown=new Set([...this.list.querySelectorAll("[data-cx-item]")].map(item=>item.getAttribute("data-cx-item")));this.limit +=this.doc.pageSize;this.render();if(this.more.hidden)[...this.list.querySelectorAll("[data-cx-item]")].find(item=>!shown.has(item.getAttribute("data-cx-item")))?.querySelector(".cx-chg-toggle")?.focus()},{signal});this.printing=changesInPrint();global.addEventListener("beforeprint",()=>{this.printing=true;this.render()},{signal});global.addEventListener("afterprint",()=>{this.printing=false;this.render()},{signal});this.render()}
138
141
  visible(){return this.doc.items.filter(item=>(!this.kinds.size||this.kinds.has(item.kind))&&(!this.flaggedOnly||item.flags.length))}
139
142
  folders(items){if(!this.doc.groupByFolder)return[["","",items]];const groups=new Map();for(const item of items){const folder=changePath(item.path)[0],key=folder.replace(/\\/g, "/");
140
143
  if(!groups.has(key))groups.set(key,[key,folder,[]]);groups.get(key)[2].push(item)}
141
144
  return[...groups.values()].sort((a,b)=>a[0]<b[0]?-1:a[0]>b[0]?1:0)}
142
- renderBar(){const labels=this.labels,items=this.doc.items,kinds=h("div","cx-chg-kinds");kinds.setAttribute("role","group");kinds.setAttribute("aria-label",labels.changeFilter);for(const kind of CHANGE_KINDS){const count=items.filter(item=>item.kind===kind).length;if(!count)continue;const button=h("button","cx-chg-kind"),badge=h("span"),number=h("span","cx-chg-count");button.type="button";button._kind=kind;button.setAttribute("aria-pressed",String(this.kinds.has(kind)));applyTone(badge,"cx-chg-badge",toneOf(CHANGE_TONES[kind]));setText(badge,labels["change"+kind[0].toUpperCase()+ kind.slice(1)]);setText(number,this.format.format(count));button.append(badge,number);kinds.appendChild(button)}
143
- const children=[kinds],flagged=items.filter(item=>item.flags.length).length;if(flagged){const label=h("label","cx-chg-switch"),box=this.flagSwitch=h("input"),text=h("span");box.type="checkbox";box.checked=this.flaggedOnly;setText(text,labels.changeFlaggedOnly+" · "+changeCount(labels.changeFlaggedCount,flagged,this.lang,{count:this.format.format(flagged)}));label.append(box,text);children.push(label)}
145
+ renderBar(){const labels=this.labels,items=this.doc.items,kinds=h("div","cx-chg-kinds");kinds.setAttribute("role","group");kinds.setAttribute("aria-label",labels.changeFilter);for(const kind of CHANGE_KINDS){const count=items.filter(item=>item.kind===kind).length;if(!count)continue;const button=h("button","cx-chip cx-chg-kind"),badge=h("span"),number=h("span","cx-chg-count");button.type="button";button._kind=kind;button.setAttribute("aria-pressed",String(this.kinds.has(kind)));applyTone(badge,"cx-pill cx-chg-badge",toneOf(CHANGE_TONES[kind]));setText(badge,labels["change"+kind[0].toUpperCase()+ kind.slice(1)]);setText(number,this.format.format(count));button.append(badge,number);kinds.appendChild(button)}
146
+ const children=[kinds],flagged=items.filter(item=>item.flags.length).length;if(flagged){const label=h("label","cx-chg-switch"),box=this.flagSwitch=h("input","cx-check"),text=h("span");box.type="checkbox";box.checked=this.flaggedOnly;setText(text,labels.changeFlaggedOnly+" · "+changeCount(labels.changeFlaggedCount,flagged,this.lang,{count:this.format.format(flagged)}));label.append(box,text);children.push(label)}
144
147
  const summary=h("span","cx-chg-summary"),shown=Math.min(this.visible().length,this.shownLimit());setText(summary,shown===items.length?"":fill(labels.changeShown,{shown:this.format.format(shown),total:this.format.format(items.length)}));const filters=[...CHANGE_KINDS.filter(kind=>this.kinds.has(kind)).map(kind=>labels["change"+kind[0].toUpperCase()+ kind.slice(1)]),...(this.flaggedOnly?[labels.changeFlaggedOnly]:[])];const printed=h("span","cx-chg-printnote");setText(printed,filters.length?fill(labels.changeFiltered,{filters:filters.join(", ")}):"");children.push(summary,printed);const tools=this.tools();if(tools)children.push(tools);this.bar.replaceChildren(...children)}
145
148
  shownLimit(){return this.printing?Math.max(this.limit,2000):this.limit}
146
149
  render(){const focused=document.activeElement&&this.root.contains(document.activeElement)?document.activeElement.closest("[data-cx-item]")?.getAttribute("data-cx-item"):null;this.renderBar();const items=this.visible(),shown=items.slice(0,this.shownLimit()),labels=this.labels,rows=[];for(const[key,folder,members]of this.folders(shown)){if(this.doc.groupByFolder){const group=h("li","cx-chg-group"),title=h("div","cx-chg-folder"),name=h("span","cx-chg-foldername"),count=h("span","cx-chg-foldercount"),list=h("ul","cx-chg-sublist");setText(name,folder||labels.changeRoot);setText(count,changeCount(labels.changeFileCount,members.length,this.lang,{count:this.format.format(members.length)}));title.append(name,count);list.setAttribute("aria-label",folder||labels.changeRoot);for(const item of members)list.appendChild(this.row(item));group.append(title,list);rows.push(group)}else{for(const item of members)rows.push(this.row(item))}}
@@ -153,7 +156,7 @@ getState(){return gridFreeze({kinds:[...this.kinds],flaggedOnly:this.flaggedOnly
153
156
  toggle(id,open){const item=this.doc.items.find(entry=>entry.id===id);if(!item)return false;const next=open===undefined?!this.open.has(id):!!open;if(next===this.open.has(id))return true;if(next)this.open.add(id);else this.open.delete(id);this.render();this.emit("changeToggle",{list:this.doc.id,item:id,open:next},"onToggle");return true}
154
157
  focusItem(id){const toggle=[...this.list.querySelectorAll(".cx-chg-toggle")].find(button=>button.closest("[data-cx-item]").getAttribute("data-cx-item")===id);if(!toggle)return false;toggle.focus();return true}
155
158
  update(view){this.doc=changesDocument(view);this.labels=changeLabels(this.doc.labels,this.options.labels);this.source=view;this.open=new Set([...this.open].filter(id=>this.doc.items.some(item=>item.id===id)));for(const diff of this.diffs.values())diff.destroy();this.diffs.clear();this.limit=this.doc.pageSize;this.pending=null;this.list.setAttribute("aria-label",this.doc.label);this.render()}}
156
- Object.assign(ChangeListView.prototype,{row(item){const labels=this.labels,doc=this.doc,open=this.open.has(item.id),[folder,name]=changePath(item.path);const li=h("li","cx-chg-item" +(item.flags.length?" cx-chg-flagged":"")),row=h("div","cx-chg-row");li.setAttribute("data-cx-item",item.id);const toggle=h("button","cx-chg-toggle"),detailId=(this.host.id||"cx-changes")+ "-"+this.uid()+ "-detail";toggle.type="button";toggle.setAttribute("aria-expanded",String(open));toggle.setAttribute("aria-label",fill(labels.changeDetails,{name:doc.groupByFolder?name:item.path}));toggle.appendChild(changeIcon("chevron"));const badge=h("span");applyTone(badge,"cx-chg-badge",toneOf(CHANGE_TONES[item.kind]));setText(badge,item.kindLabel||labels["change"+item.kind[0].toUpperCase()+ item.kind.slice(1)]);const main=h("div","cx-chg-main"),title=h("div","cx-chg-title"),nameText=h("span","cx-chg-name");setText(nameText,doc.groupByFolder?name:item.path);nameText.title=item.path;title.appendChild(nameText);if(item.previousPath){const from=h("span","cx-chg-from");setText(from,fill(labels.changeFrom,{path:item.previousPath}));title.appendChild(from)}
159
+ Object.assign(ChangeListView.prototype,{row(item){const labels=this.labels,doc=this.doc,open=this.open.has(item.id),[folder,name]=changePath(item.path);const li=h("li","cx-chg-item" +(item.flags.length?" cx-chg-flagged":"")),row=h("div","cx-chg-row");li.setAttribute("data-cx-item",item.id);const toggle=h("button","cx-chg-toggle"),detailId=(this.host.id||"cx-changes")+ "-"+this.uid()+ "-detail";toggle.type="button";toggle.setAttribute("aria-expanded",String(open));toggle.setAttribute("aria-label",fill(labels.changeDetails,{name:doc.groupByFolder?name:item.path}));toggle.appendChild(changeIcon("chevron"));const badge=h("span");applyTone(badge,"cx-pill cx-chg-badge",toneOf(CHANGE_TONES[item.kind]));setText(badge,item.kindLabel||labels["change"+item.kind[0].toUpperCase()+ item.kind.slice(1)]);const main=h("div","cx-chg-main"),title=h("div","cx-chg-title"),nameText=h("span","cx-chg-name");setText(nameText,doc.groupByFolder?name:item.path);nameText.title=item.path;title.appendChild(nameText);if(item.previousPath){const from=h("span","cx-chg-from");setText(from,fill(labels.changeFrom,{path:item.previousPath}));title.appendChild(from)}
157
160
  main.appendChild(title);if(item.flags.length){const flags=h("div","cx-chg-flags");for(const flag of item.flags){const chip=h("span");applyTone(chip,"cx-chg-flag",toneOf(flag.tone));chip.title=flag.reason;chip.append(changeIcon("flag"),document.createTextNode(flag.label));flags.appendChild(chip)}
158
161
  main.appendChild(flags)}
159
162
  const second=[item.secondary,(item.after||item.before)?.time!=null?changeTimeText((item.after||item.before).time,doc.local,labels):null].filter(Boolean);if(second.length){const line=h("div","cx-chg-sub");setText(line,second.join(" · "));main.appendChild(line)}
@@ -186,17 +189,17 @@ function changeExportDiff(diff){if(!diff)return null;let hunks=diff.hunks;const
186
189
  function changeExportVersion(version){return version?{size:version.size,hash:version.hash,time:changeIso(version.time)}:null}
187
190
  function changeExportItem(item){return{id:item.id,kind:item.kind,kindLabel:item.kindLabel,path:item.path,previousPath:item.previousPath,secondary:item.secondary,before:changeExportVersion(item.before),after:changeExportVersion(item.after),flags:item.flags.map(flag=>({id:flag.id,label:flag.label,reason:flag.reason,tone:flag.tone})),facts:item.facts.map(fact=>({label:fact.label,before:fact.before,after:fact.after,note:fact.note})),values:{...item.values},diff:changeExportDiff(item.diff)}}
188
191
  function changeCsv(items){const keys=[...new Set(items.flatMap(item=>Object.keys(item.values)))].sort();const head=["kind","kindLabel","path","previousPath","secondary","sizeBefore","sizeAfter","hashBefore","hashAfter","timeBefore","timeAfter","flags","facts"].concat(keys.map(key=>"values."+key));const rows=[head].concat(items.map(item=>[item.kind,item.kindLabel,item.path,item.previousPath,item.secondary,item.before?.size,item.after?.size,item.before?.hash,item.after?.hash,changeIso(item.before?.time),changeIso(item.after?.time),item.flags.map(flag=>flag.label+": "+flag.reason).join(" | "),item.facts.map(fact=>fact.label+": " +(fact.before??"")+(fact.before!=null&&fact.after!=null?" → ":"")+(fact.after??"")+(fact.note?" ("+fact.note+")":"")).join(" | ")].concat(keys.map(key=>item.values[key]))));return rows.map(row=>row.map(changeCsvField).join(",")).join("\r\n")+ "\r\n"}
189
- Object.assign(ChangeListView.prototype,{actionControl(action,item){if(item&&item.actions.length&&!item.actions.includes(action.id))return null;const values=item?item.values:this.doc.values;const value=key=>key===null?null:item&&key==="path"?item.path:item&&key==="previousPath"?item.previousPath:values[key]??null;if(action.copy!==null&&value(action.copy)===null)return null;const href=action.link===null?null:changeHref(value(action.link));if(action.link!==null&&href===null)return null;if(action.reveal==="diff"&&!item.diff)return null;const control=h(href?"a":"button","cx-chg-action" +(action.icon==="none"||!item?" cx-chg-textaction":""));if(href)control.href=href;else control.type="button";control._action=action;control._item=item;control.setAttribute("data-cx-action",action.id);if(action.icon!=="none")control.appendChild(changeIcon(action.icon));if(action.icon==="none"||!item)control.appendChild(document.createTextNode(action.label));else{control.setAttribute("aria-label",action.label);control.setAttribute("data-cx-tip",action.label)}
192
+ Object.assign(ChangeListView.prototype,{actionControl(action,item){if(item&&item.actions.length&&!item.actions.includes(action.id))return null;const values=item?item.values:this.doc.values;const value=key=>key===null?null:item&&key==="path"?item.path:item&&key==="previousPath"?item.previousPath:values[key]??null;if(action.copy!==null&&value(action.copy)===null)return null;const href=action.link===null?null:changeHref(value(action.link));if(action.link!==null&&href===null)return null;if(action.reveal==="diff"&&!item.diff)return null;const control=h(href?"a":"button","cx-btn cx-chg-action" +(action.icon==="none"||!item?" cx-chg-textaction":""));control.dataset.size="sm";if(href)control.href=href;else control.type="button";control._action=action;control._item=item;control.setAttribute("data-cx-action",action.id);if(action.icon!=="none")control.appendChild(changeIcon(action.icon));if(action.icon==="none"||!item)control.appendChild(document.createTextNode(action.label));else{control.setAttribute("aria-label",action.label);control.setAttribute("data-cx-tip",action.label)}
190
193
  if(action.reason)control.setAttribute("aria-expanded",String(!!(this.pending&&this.pending.mode==="ask"&&this.pending.action===action&&this.pending.item===item)));return control},tools(){const tools=h("div","cx-chg-tools");tools.setAttribute("role","group");tools.setAttribute("aria-label",fill(this.labels.changeActions,{name:this.doc.label}));for(const action of this.doc.toolbar){const control=this.actionControl(action,null);if(control)tools.appendChild(control)}
191
- for(const format of this.doc.exports){const button=h("button","cx-chg-action cx-chg-textaction cx-chg-export");button.type="button";button._export=format;button.append(changeIcon("download"),document.createTextNode(format==="csv"?this.labels.changeExportCsv:this.labels.changeExportJson));tools.appendChild(button)}
194
+ for(const format of this.doc.exports){const button=h("button","cx-btn cx-chg-action cx-chg-textaction cx-chg-export");button.type="button";button.dataset.size="sm";button._export=format;button.append(changeIcon("download"),document.createTextNode(format==="csv"?this.labels.changeExportCsv:this.labels.changeExportJson));tools.appendChild(button)}
192
195
  return tools.childNodes.length?tools:null},detailOf(action,item,extra){return Object.assign({list:this.doc.id,action:action.id,item:item?item.id:null,kind:item?item.kind:null,path:item?item.path:null,previousPath:item?item.previousPath:null,values:{...(item?item.values:this.doc.values)},copied:null},extra)},request(detail){const event=new CustomEvent("canopyx:changeAction",{detail,bubbles:true,cancelable:true});this.host.dispatchEvent(event);let claimed=event.defaultPrevented;if(typeof this.options.onAction==="function"){try{this.options.onAction(detail,event);claimed=true}catch(error){this.host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error,hook:"onAction"},bubbles:true}))}}
193
196
  return claimed},async act(action,item,control){if(action.copy!==null){const key=action.copy,copied=await this.copyText(item&&key==="path"?item.path:item&&key==="previousPath"?item.previousPath:(item?item.values:this.doc.values)[key]);if(!this.destroyed)this.emit("changeAction",this.detailOf(action,item,{copied}),"onAction");return}
194
197
  if(action.link!==null){this.emit("changeAction",this.detailOf(action,item,{href:control.getAttribute("href")}),"onAction");return}
195
198
  if(action.reveal!=="none"){this.reveal(item.id,action.reveal);this.emit("changeAction",this.detailOf(action,item,{reveal:action.reveal}),"onAction");return}
196
199
  if(action.reason){this.pending={mode:"ask",action,item,text:"",error:false};this.render();this.focusPanel();return}
197
200
  this.send(action,item,null)},send(action,item,reason){const detail=this.detailOf(action,item,reason===null?{}:{reason});const claimed=this.request(detail);if(this.destroyed)return;if(item?!this.doc.items.includes(item):!this.doc.toolbar.includes(action)){this.pending=null;this.render();return}
198
- this.pending=claimed?null:{mode:"note",action,item,detail};this.render();if(this.pending)this.focusPanel();else this.focusAction(action,item)},reveal(id,what){this.toggle(id,true);const box=this.list.querySelector("[data-cx-item=\""+CSS.escape(id)+ "\"] > .cx-chg-detail");if(!box)return;const target=what==="diff"?box.querySelector(".cx-chg-diff .cx-diff-scroll")||box:box;if(target===box)box.tabIndex=-1;target.scrollIntoView?.({block:"nearest"});target.focus({preventScroll:true})},panel(){this.panelLife?.abort();this.panelLife=new AbortController();const pending=this.pending,labels=this.labels,signal=this.panelLife.signal,box=h("div","cx-chg-panel");box.setAttribute("role","group");box.setAttribute("aria-label",pending.action.label);const cancel=h("button","cx-chg-action cx-chg-textaction");cancel.type="button";setText(cancel,labels.changeCancel);cancel.addEventListener("click",()=>{const{action,item}=pending;this.pending=null;this.render();this.focusAction(action,item)},{signal});if(pending.mode==="note"){const text=h("p","cx-chg-note"),copy=h("button","cx-chg-action cx-chg-textaction");copy.type="button";setText(text,fill(labels.changeUnclaimed,{action:pending.action.label}));copy.append(changeIcon("copy"),document.createTextNode(labels.changeCopyRequest));copy.addEventListener("click",()=>this.copyText(JSON.stringify(pending.detail,null,2)),{signal});const buttons=h("div","cx-chg-askbtns");buttons.append(copy,cancel);box.append(text,buttons);return box}
199
- const id=(this.host.id||"cx-changes")+ "-reason-"+this.uid(),field=h("textarea","cx-chg-reasonbox"),label=h("label","cx-chg-asklabel"),hint=h("div","cx-chg-hint");field.id=id;field.rows=2;field.maxLength=1000;field.value=pending.text;field.setAttribute("aria-describedby",id+"-hint");label.htmlFor=id;setText(label,labels.changeReason);hint.id=id+"-hint";setText(hint,fill(labels.changeReasonHint,{action:pending.action.label}));const error=h("div","cx-chg-askerror");error.setAttribute("role","alert");setText(error,pending.error?labels.changeReasonRequired:"");if(pending.error)field.setAttribute("aria-invalid","true");const confirm=h("button","cx-chg-action cx-chg-textaction cx-chg-primary");confirm.type="button";setText(confirm,pending.action.label);const submit=()=>{const reason=field.value.trim();if(!reason){pending.error=true;pending.text=field.value;this.render();this.focusPanel();return}
201
+ this.pending=claimed?null:{mode:"note",action,item,detail};this.render();if(this.pending)this.focusPanel();else this.focusAction(action,item)},reveal(id,what){this.toggle(id,true);const box=this.list.querySelector("[data-cx-item=\""+CSS.escape(id)+ "\"] > .cx-chg-detail");if(!box)return;const target=what==="diff"?box.querySelector(".cx-chg-diff .cx-diff-scroll")||box:box;if(target===box)box.tabIndex=-1;target.scrollIntoView?.({block:"nearest"});target.focus({preventScroll:true})},panel(){this.panelLife?.abort();this.panelLife=new AbortController();const pending=this.pending,labels=this.labels,signal=this.panelLife.signal,box=h("div","cx-chg-panel");box.setAttribute("role","group");box.setAttribute("aria-label",pending.action.label);const cancel=h("button","cx-btn cx-chg-action cx-chg-textaction");cancel.type="button";cancel.dataset.size="sm";setText(cancel,labels.changeCancel);cancel.addEventListener("click",()=>{const{action,item}=pending;this.pending=null;this.render();this.focusAction(action,item)},{signal});if(pending.mode==="note"){const text=h("p","cx-chg-note"),copy=h("button","cx-btn cx-chg-action cx-chg-textaction");copy.type="button";copy.dataset.size="sm";setText(text,fill(labels.changeUnclaimed,{action:pending.action.label}));copy.append(changeIcon("copy"),document.createTextNode(labels.changeCopyRequest));copy.addEventListener("click",()=>this.copyText(JSON.stringify(pending.detail,null,2)),{signal});const buttons=h("div","cx-chg-askbtns");buttons.append(copy,cancel);box.append(text,buttons);return box}
202
+ const id=(this.host.id||"cx-changes")+ "-reason-"+this.uid(),field=h("textarea","cx-textarea cx-chg-reasonbox"),label=h("label","cx-chg-asklabel"),hint=h("div","cx-chg-hint");field.id=id;field.rows=2;field.maxLength=1000;field.value=pending.text;field.setAttribute("aria-describedby",id+"-hint");label.htmlFor=id;setText(label,labels.changeReason);hint.id=id+"-hint";setText(hint,fill(labels.changeReasonHint,{action:pending.action.label}));const error=h("div","cx-chg-askerror");error.setAttribute("role","alert");setText(error,pending.error?labels.changeReasonRequired:"");if(pending.error)field.setAttribute("aria-invalid","true");const confirm=h("button","cx-btn cx-chg-action cx-chg-textaction cx-chg-primary");confirm.dataset.variant="primary";confirm.dataset.size="sm";confirm.type="button";setText(confirm,pending.action.label);const submit=()=>{const reason=field.value.trim();if(!reason){pending.error=true;pending.text=field.value;this.render();this.focusPanel();return}
200
203
  this.send(pending.action,pending.item,reason)};confirm.addEventListener("click",submit,{signal});field.addEventListener("input",()=>{pending.text=field.value},{signal});field.addEventListener("keydown",event=>{if(event.key==="Escape"){event.preventDefault();event.stopPropagation();cancel.click()}
201
204
  else if(event.key==="Enter"&&(event.ctrlKey||event.metaKey)){event.preventDefault();submit()}},{signal});const buttons=h("div","cx-chg-askbtns");buttons.append(confirm,cancel);box.append(label,field,hint,error,buttons);return box},focusPanel(){const target=this.root.querySelector(".cx-chg-panel :is(textarea, button)");if(target)target.focus()},focusAction(action,item){const scope=item?this.list.querySelector("[data-cx-item=\""+CSS.escape(item.id)+ "\"] > .cx-chg-row"):this.bar;scope?.querySelector("[data-cx-action=\""+CSS.escape(action.id)+ "\"]")?.focus()},exportItems(format){const items=this.folders(this.visible()).flatMap(group=>group[2]),name=(this.doc.id.replace(/[^\w.-]+/g, "-") || "changes") + "." + format;
202
205
  const text=format==="csv"?""+changeCsv(items)
@@ -204,7 +207,7 @@ const text=format==="csv"?""+changeCsv(items)
204
207
  emit(name,detail,callback){const event=new CustomEvent("canopyx:"+name,{detail,bubbles:true});this.host.dispatchEvent(event);if(typeof this.options[callback]==="function"){try{this.options[callback](detail,event)}catch(error){this.host.dispatchEvent(new CustomEvent("canopyx:error",{detail:{error,hook:callback},bubbles:true}))}}}
205
208
  stateText(state){return this.labels["change"+state[0].toUpperCase()+ state.slice(1)]}
206
209
  badge(state,className){const badge=h("span"),[icon,tone]=PROPAGATION_LOOK[state];applyTone(badge,className +(state==="fault"||state==="propagating"?" cx-prop-attn":""),toneOf(tone));const text=h("span");setText(text,this.stateText(state));badge.append(changeIcon(icon),text);return badge}
207
- render(){const doc=this.doc,labels=this.labels,witnesses=doc.witnesses;const seen=witnesses.map(witness=>witness.firstSeen).filter(time=>time!==null),reports=witnesses.flatMap(witness=>[witness.firstSeen,witness.lastSeen]).filter(time=>time!==null);const start=doc.start??(seen.length?Math.min(...seen):null),end=doc.asOf??(reports.length?Math.max(...reports):null),span=start!==null&&end!==null?Math.max(1,end-start):0;const overall=doc.state||witnesses.reduce((worst,witness)=>PROPAGATION_RANK[witness.state]>PROPAGATION_RANK[worst]?witness.state:worst,"converged");const converged=witnesses.filter(witness=>witness.state==="converged").length;const head=h("div","cx-prop-head"),summary=h("span","cx-prop-summary"),counts=h("ul","cx-prop-counts");setText(summary,doc.summary||fill(labels.changeProgress,{converged:this.format.format(converged),total:this.format.format(witnesses.length)}));head.append(this.badge(overall,"cx-prop-state"),summary);for(const state of PROPAGATION_STATES){const count=witnesses.filter(witness=>witness.state===state).length;if(!count)continue;const item=h("li","cx-prop-count"),badge=this.badge(state,"cx-prop-key"),number=h("span","cx-prop-number");setText(number,this.format.format(count));item.append(badge,number);counts.appendChild(item)}
210
+ render(){const doc=this.doc,labels=this.labels,witnesses=doc.witnesses;this.timeFormat=humanTimeFormat(this.lang,doc.local,labels.changeUtcTime);const seen=witnesses.map(witness=>witness.firstSeen).filter(time=>time!==null),reports=witnesses.flatMap(witness=>[witness.firstSeen,witness.lastSeen]).filter(time=>time!==null);const start=doc.start??(seen.length?Math.min(...seen):null),end=doc.asOf??(reports.length?Math.max(...reports):null),span=start!==null&&end!==null?Math.max(1,end-start):0;const overall=doc.state||witnesses.reduce((worst,witness)=>PROPAGATION_RANK[witness.state]>PROPAGATION_RANK[worst]?witness.state:worst,"converged");const converged=witnesses.filter(witness=>witness.state==="converged").length;const head=h("div","cx-prop-head"),summary=h("span","cx-prop-summary"),counts=h("ul","cx-prop-counts");setText(summary,doc.summary||fill(labels.changeProgress,{converged:this.format.format(converged),total:this.format.format(witnesses.length)}));head.append(this.badge(overall,"cx-prop-state"),summary);for(const state of PROPAGATION_STATES){const count=witnesses.filter(witness=>witness.state===state).length;if(!count)continue;const item=h("li","cx-prop-count"),badge=this.badge(state,"cx-prop-key"),number=h("span","cx-prop-number");setText(number,this.format.format(count));item.append(badge,number);counts.appendChild(item)}
208
211
  counts.setAttribute("aria-label",labels.changeState);const table=h("table","cx-prop-table"),thead=h("thead"),heads=h("tr");table.setAttribute("aria-label",doc.label);for(const text of[doc.title||labels.changeReplica,labels.changeState,labels.changeFirstSeen,labels.changeLastSeen,labels.changeTimeline]){const th=h("th");th.scope="col";setText(th,text);heads.appendChild(th)}
209
212
  thead.appendChild(heads);table.appendChild(thead);const groups=new Map();for(const witness of witnesses){if(!groups.has(witness.group))groups.set(witness.group,[]);groups.get(witness.group).push(witness)}
210
213
  for(const[group,members]of groups){const body=h("tbody");if(group!==null){const tr=h("tr","cx-prop-group"),th=h("th"),count=h("span","cx-prop-groupcount");th.scope="rowgroup";th.colSpan=5;setText(th,group);setText(count," · "+changeCount(doc.groupCount||"{count}",members.length,this.lang,{count:this.format.format(members.length)}));th.appendChild(count);tr.appendChild(th);body.appendChild(tr)}
@@ -213,9 +216,9 @@ this.root.replaceChildren(head,counts,table)}
213
216
  row(witness,start,span){const labels=this.labels,tr=h("tr","cx-prop-row cx-prop-"+witness.state),name=h("th"),state=h("td","cx-prop-statecell"),first=h("td","cx-prop-first"),last=h("td","cx-prop-last"),lane=h("td","cx-prop-lanecell");name.scope="row";const label=h("span","cx-prop-name");setText(label,witness.label);name.appendChild(label);if(witness.source){const mark=h("span","cx-prop-source");setText(mark,labels.changeSource);name.appendChild(mark)}
214
217
  if(witness.secondary){const sub=h("span","cx-prop-sub");setText(sub,witness.secondary);name.appendChild(sub)}
215
218
  state.appendChild(this.badge(witness.state,"cx-prop-badge"));if(witness.note){const note=h("span","cx-prop-sub");setText(note,witness.note);state.appendChild(note)}
216
- let delay=null;if(witness.firstSeen!==null){const time=h("span");setText(time,changeTimeText(witness.firstSeen,this.doc.local,labels));first.appendChild(time);if(start!==null&&!witness.source){delay=fill(labels.changeDelay,{duration:changeDuration(witness.firstSeen-start,labels,this.format)});const sub=h("span","cx-prop-delay");setText(sub,delay);first.appendChild(sub)}}else{const none=h("span","cx-prop-none");setText(none,labels.changeNotSeen);first.appendChild(none)}
217
- setText(last,witness.lastSeen!==null?changeTimeText(witness.lastSeen,this.doc.local,labels):"");const track=h("div","cx-prop-lane"),fillBar=h("div","cx-prop-fill");track.setAttribute("aria-hidden","true");const reached=witness.firstSeen!==null&&span?Math.min(1,Math.max(0,(witness.firstSeen-start)/ span)) : witness.state === "unknown" || !span ? 0 : 1;
219
+ let delay=null;if(witness.firstSeen!==null){const time=h("span");setText(time,this.timeFormat.format(witness.firstSeen));first.appendChild(time);if(start!==null&&!witness.source){delay=fill(labels.changeDelay,{duration:changeDuration(witness.firstSeen-start,labels,this.format)});const sub=h("span","cx-prop-delay");setText(sub,delay);first.appendChild(sub)}}else{const none=h("span","cx-prop-none");setText(none,labels.changeNotSeen);first.appendChild(none)}
220
+ setText(last,witness.lastSeen!==null?this.timeFormat.format(witness.lastSeen):"");const track=h("div","cx-prop-lane"),fillBar=h("div","cx-prop-fill");track.setAttribute("aria-hidden","true");const reached=witness.firstSeen!==null&&span?Math.min(1,Math.max(0,(witness.firstSeen-start)/ span)) : witness.state === "unknown" || !span ? 0 : 1;
218
221
  fillBar.style.width=(reached*100).toFixed(1)+ "%";applyTone(fillBar,"cx-prop-fill" +(witness.firstSeen===null&&witness.state!=="unknown"?" cx-prop-open":""),toneOf(PROPAGATION_LOOK[witness.state][1]));track.appendChild(fillBar);if(delay)track.title=delay;lane.appendChild(track);tr.append(name,state,first,last,lane);return tr}
219
222
  update(view){this.doc=propagationDocument(view);this.labels=changeLabels(this.doc.labels,this.options.labels);this.source=view;this.render()}}
220
223
  function propagationCreate(host,options){const view=new PropagationView(host,options);const impl={ready:Promise.resolve().then(()=>{if(view.destroyed)return impl;host.setAttribute("data-cx-ready","");view.emit("propagationReady",{propagation:view.doc.id},"onReady");return impl}),document:()=>view.source||options.view,update:next=>view.update(next),destroy:()=>{if(view.destroyed)return;view.destroyed=true;view.lifetime.abort();view.root.remove();host.removeAttribute("data-cx-ready")}};return impl}
221
- Object.assign(CHANGES_IMPL,{diff:diffCreate,changes:changeListCreate,propagation:propagationCreate});installed.add(context.CHANGES_IMPL)}};(global.CanopyXParts||=[]).push(["changes",part])})(typeof window!=="undefined"?window:globalThis);
224
+ Object.assign(CHANGES_IMPL,{diff:diffCreate,changes:changeListCreate,propagation:propagationCreate,validatePropagation:propagationDocument});installed.add(context.CHANGES_IMPL)}};(global.CanopyXParts||=[]).push(["changes",part])})(typeof window!=="undefined"?window:globalThis);
@@ -1,12 +1,16 @@
1
1
  /* Column groups: header rows above the column headers (canopyx.column-groups.source),and the nested Columns menu. */
2
2
  .cx-data-grid .cx-hgroup-row{height:var(--hfx-table-header-height,calc(40px - var(--cx-compact,0) * 8px));}
3
3
  .cx-data-grid.cx-phone .cx-hgroup-row{height:var(--cx-size-32px);}
4
- .cx-data-grid .cx-hgroup{overflow:visible;justify-content:flex-start;border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));}
4
+ .cx-data-grid .cx-hgroup{overflow:visible;justify-content:flex-start;border-bottom:var(--cx-size-1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
5
5
  .cx-data-grid .cx-hgroup::after{top:0;bottom:0;}
6
6
  .cx-data-grid .cx-hgroup-row .cx-hcell:last-child::after{display:block;}
7
7
  .cx-data-grid .cx-hgroup-row .cx-hcell:last-child:not(.cx-hgroup)::after,.cx-data-grid .cx-hgroup-pad::after{display:none;}
8
8
  .cx-data-grid .cx-hgroup-title{position:sticky;left:calc(var(--cx-pin-left-w,0px) + var(--hfx-cell-padding-x,calc(12px - var(--cx-compact,0) * 4px)));min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
9
9
  .cx-data-grid .cx-hgroup[data-cx-pin] .cx-hgroup-title{position:static;}
10
+ .cx-data-grid .cx-hband{background:color-mix(in srgb,var(--hfx-color-accent,light-dark(#11776f,#37c9b8)) 8%,var(--cx-grid-header,var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317))));font-weight:var(--hfx-table-header-weight,var(--hfx-weight-semibold,600));border-inline-end:var(--hfx-border-width,1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
11
+ .cx-data-grid .cx-hband::after{display:none;}
12
+ .cx-data-grid .cx-hband-continuation .cx-hgroup-title{text-decoration:underline dotted;text-underline-offset:var(--cx-size-4px);}
13
+ .cx-data-grid .cx-hband-continuation .cx-hgroup-title::before{content:"↳ ";}
10
14
  .cx-data-grid .cx-hgroup .cx-column-move{flex:none;}
11
15
  .cx-data-grid .cx-hgroup.cx-drop-before{box-shadow:inset var(--cx-size-2px) 0 var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
12
16
  .cx-data-grid .cx-hgroup.cx-drop-after{box-shadow:inset var(--cx-size-neg-2px) 0 var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}