stickyflow 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/binding/index.cjs +9 -9
  3. package/dist/binding/index.d.cts +4 -4
  4. package/dist/binding/index.d.ts +4 -4
  5. package/dist/binding/index.js +3 -3
  6. package/dist/{chunk-5PJ55GPG.cjs → chunk-5G3BEXQU.cjs} +1069 -713
  7. package/dist/chunk-5G3BEXQU.cjs.map +1 -0
  8. package/dist/{chunk-EGUPN56K.js → chunk-BFQWCOEC.js} +3 -3
  9. package/dist/{chunk-EGUPN56K.js.map → chunk-BFQWCOEC.js.map} +1 -1
  10. package/dist/{chunk-KRSX4UZ7.cjs → chunk-F24JURN2.cjs} +293 -46
  11. package/dist/chunk-F24JURN2.cjs.map +1 -0
  12. package/dist/{chunk-TECWZVIM.cjs → chunk-FXGXUWSI.cjs} +23 -23
  13. package/dist/{chunk-TECWZVIM.cjs.map → chunk-FXGXUWSI.cjs.map} +1 -1
  14. package/dist/{chunk-HRU6VOEC.js → chunk-G6IW2IX3.js} +44 -7
  15. package/dist/chunk-G6IW2IX3.js.map +1 -0
  16. package/dist/{chunk-SDOHUNBW.js → chunk-Q6QLU6YQ.js} +428 -72
  17. package/dist/chunk-Q6QLU6YQ.js.map +1 -0
  18. package/dist/{chunk-VPNOVRWP.js → chunk-RQYZNW2I.js} +262 -15
  19. package/dist/chunk-RQYZNW2I.js.map +1 -0
  20. package/dist/{chunk-L7CEX5JV.js → chunk-UB2ANTWF.js} +4 -4
  21. package/dist/{chunk-L7CEX5JV.js.map → chunk-UB2ANTWF.js.map} +1 -1
  22. package/dist/{chunk-LSEMXRB5.cjs → chunk-UHKFJBY5.cjs} +44 -7
  23. package/dist/chunk-UHKFJBY5.cjs.map +1 -0
  24. package/dist/{chunk-SCD3AHMY.cjs → chunk-WZA3DJJH.cjs} +15 -15
  25. package/dist/{chunk-SCD3AHMY.cjs.map → chunk-WZA3DJJH.cjs.map} +1 -1
  26. package/dist/index.cjs +36 -36
  27. package/dist/index.d.cts +5 -5
  28. package/dist/index.d.ts +5 -5
  29. package/dist/index.js +5 -5
  30. package/dist/interaction/index.cjs +240 -237
  31. package/dist/interaction/index.cjs.map +1 -1
  32. package/dist/interaction/index.d.cts +3 -3
  33. package/dist/interaction/index.d.ts +3 -3
  34. package/dist/interaction/index.js +6 -3
  35. package/dist/interaction/index.js.map +1 -1
  36. package/dist/{render-DU4lYbRl.d.cts → render-BDO4S5uF.d.cts} +16 -0
  37. package/dist/{render-DU4lYbRl.d.ts → render-BDO4S5uF.d.ts} +16 -0
  38. package/dist/{runtime-Bkv7QW7H.d.cts → runtime-C-C5v9po.d.cts} +2 -2
  39. package/dist/{runtime-DJ4K4_HZ.d.ts → runtime-lCAfU-1Q.d.ts} +2 -2
  40. package/dist/{runtimeTypes-C1shzoyr.d.ts → runtimeTypes-B7p6b1Bi.d.cts} +2 -2
  41. package/dist/{runtimeTypes-BvJBZLkr.d.cts → runtimeTypes-BDA_CfWh.d.ts} +2 -2
  42. package/dist/stickyflow-diagram.global.js +197 -44
  43. package/dist/stickyflow-diagram.global.js.map +1 -1
  44. package/dist/{types-B5jrEEcF.d.cts → types-CZJzycKw.d.cts} +1 -1
  45. package/dist/{types-B7IkZ0w4.d.ts → types-Dp8JVZLB.d.ts} +1 -1
  46. package/dist/viewer/index.cjs +9 -9
  47. package/dist/viewer/index.d.cts +4 -4
  48. package/dist/viewer/index.d.ts +4 -4
  49. package/dist/viewer/index.js +4 -4
  50. package/dist/web-component/index.cjs +6 -6
  51. package/dist/web-component/index.d.cts +2 -2
  52. package/dist/web-component/index.d.ts +2 -2
  53. package/dist/web-component/index.js +4 -4
  54. package/package.json +1 -1
  55. package/dist/chunk-5PJ55GPG.cjs.map +0 -1
  56. package/dist/chunk-HRU6VOEC.js.map +0 -1
  57. package/dist/chunk-KRSX4UZ7.cjs.map +0 -1
  58. package/dist/chunk-LSEMXRB5.cjs.map +0 -1
  59. package/dist/chunk-SDOHUNBW.js.map +0 -1
  60. package/dist/chunk-VPNOVRWP.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunk5PJ55GPG_cjs = require('./chunk-5PJ55GPG.cjs');
4
- var chunkSCD3AHMY_cjs = require('./chunk-SCD3AHMY.cjs');
5
- var chunkLSEMXRB5_cjs = require('./chunk-LSEMXRB5.cjs');
3
+ var chunk5G3BEXQU_cjs = require('./chunk-5G3BEXQU.cjs');
4
+ var chunkWZA3DJJH_cjs = require('./chunk-WZA3DJJH.cjs');
5
+ var chunkUHKFJBY5_cjs = require('./chunk-UHKFJBY5.cjs');
6
6
 
7
7
  // src/runtime/viewer/components/rollingNumberDom.ts
8
8
  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
@@ -162,12 +162,12 @@ function componentDigits(surface) {
162
162
  function componentStyle(surface) {
163
163
  const encoded = surface.getAttribute("data-sf-widget-style");
164
164
  if (!encoded) {
165
- return chunkLSEMXRB5_cjs.DEFAULT_ROLLING_NUMBER_STYLE;
165
+ return chunkUHKFJBY5_cjs.DEFAULT_ROLLING_NUMBER_STYLE;
166
166
  }
167
167
  try {
168
- return { ...chunkLSEMXRB5_cjs.DEFAULT_ROLLING_NUMBER_STYLE, ...JSON.parse(encoded) };
168
+ return { ...chunkUHKFJBY5_cjs.DEFAULT_ROLLING_NUMBER_STYLE, ...JSON.parse(encoded) };
169
169
  } catch {
170
- return chunkLSEMXRB5_cjs.DEFAULT_ROLLING_NUMBER_STYLE;
170
+ return chunkUHKFJBY5_cjs.DEFAULT_ROLLING_NUMBER_STYLE;
171
171
  }
172
172
  }
173
173
  function positiveInteger(value) {
@@ -191,7 +191,7 @@ function setRollingNumber(surface, value, animate) {
191
191
  return false;
192
192
  }
193
193
  const previousValue = surface.getAttribute("data-sf-widget-value") ?? "";
194
- const nextValue = chunkLSEMXRB5_cjs.formatRollingNumber(value, positiveInteger(surface.getAttribute("data-sf-widget-digits")));
194
+ const nextValue = chunkUHKFJBY5_cjs.formatRollingNumber(value, positiveInteger(surface.getAttribute("data-sf-widget-digits")));
195
195
  if (previousValue === nextValue) {
196
196
  return true;
197
197
  }
@@ -299,7 +299,7 @@ var WHITE = [255, 255, 255];
299
299
  function shade(node, bump, target) {
300
300
  const base = fills.get(node) ?? node.getAttribute("fill") ?? "";
301
301
  fills.set(node, base);
302
- const rgb = chunkLSEMXRB5_cjs.parseHexRgb(base);
302
+ const rgb = chunkUHKFJBY5_cjs.parseHexRgb(base);
303
303
  if (!rgb) {
304
304
  return;
305
305
  }
@@ -362,7 +362,7 @@ function placeKnob(svg, ruler) {
362
362
  function liftLabels(svg, ruler) {
363
363
  const { id, params, horizontal, extent, inset, progress, depth } = ruler;
364
364
  const { min, max } = rangeOf(params);
365
- const peak = (typeof params.peak === "string" ? chunkLSEMXRB5_cjs.parseHexRgb(params.peak) : null) ?? WHITE;
365
+ const peak = (typeof params.peak === "string" ? chunkUHKFJBY5_cjs.parseHexRgb(params.peak) : null) ?? WHITE;
366
366
  const spread = positive(params.spread, 0.07) * extent;
367
367
  const start = inset * extent;
368
368
  const span = (1 - 2 * inset) * extent;
@@ -690,7 +690,7 @@ function mountDisplay(container, svgString) {
690
690
  }
691
691
 
692
692
  // src/runtime/viewer/events.ts
693
- var Emitter2 = class extends chunkSCD3AHMY_cjs.Emitter {
693
+ var Emitter2 = class extends chunkWZA3DJJH_cjs.Emitter {
694
694
  };
695
695
 
696
696
  // src/runtime/viewer/export/raster.ts
@@ -780,11 +780,11 @@ function svgElement(document, name, attributes) {
780
780
  function readComponentStyle(surface) {
781
781
  try {
782
782
  return {
783
- ...chunkLSEMXRB5_cjs.DEFAULT_ROLLING_NUMBER_STYLE,
783
+ ...chunkUHKFJBY5_cjs.DEFAULT_ROLLING_NUMBER_STYLE,
784
784
  ...JSON.parse(surface.getAttribute("data-sf-widget-style") ?? "{}")
785
785
  };
786
786
  } catch {
787
- return chunkLSEMXRB5_cjs.DEFAULT_ROLLING_NUMBER_STYLE;
787
+ return chunkUHKFJBY5_cjs.DEFAULT_ROLLING_NUMBER_STYLE;
788
788
  }
789
789
  }
790
790
  function cellsOf(box, plain, fontSize = 0) {
@@ -924,7 +924,7 @@ function serializeSvgSnapshot(svg, captures) {
924
924
  // src/runtime/viewer/interaction/changeFlash.ts
925
925
  function createChangeFlash(svg) {
926
926
  const timers = /* @__PURE__ */ new Map();
927
- const flash = (ownerIds, color2 = chunkSCD3AHMY_cjs.CHANGE_COLOR) => {
927
+ const flash = (ownerIds, color2 = chunkWZA3DJJH_cjs.CHANGE_COLOR) => {
928
928
  const ids = [...new Set(ownerIds)];
929
929
  if (ids.length === 0) {
930
930
  return;
@@ -932,7 +932,7 @@ function createChangeFlash(svg) {
932
932
  const doc = svg.ownerDocument;
933
933
  const reducedMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
934
934
  for (const id of ids) {
935
- const primary = chunkSCD3AHMY_cjs.findOwnerNode(svg, id, chunkSCD3AHMY_cjs.isPrimary);
935
+ const primary = chunkWZA3DJJH_cjs.findOwnerNode(svg, id, chunkWZA3DJJH_cjs.isPrimary);
936
936
  if (!primary) {
937
937
  continue;
938
938
  }
@@ -943,10 +943,10 @@ function createChangeFlash(svg) {
943
943
  for (const stale of svg.querySelectorAll(`[data-sf-change-overlay="${CSS.escape(id)}"]`)) {
944
944
  stale.remove();
945
945
  }
946
- const overlay = primary.getAttribute("data-sf-role") === "link" ? chunkSCD3AHMY_cjs.linkChangeOverlay(doc, primary, id, color2) : chunkSCD3AHMY_cjs.shapeChangeOverlay(doc, primary, id, color2);
946
+ const overlay = primary.getAttribute("data-sf-role") === "link" ? chunkWZA3DJJH_cjs.linkChangeOverlay(doc, primary, id, color2) : chunkWZA3DJJH_cjs.shapeChangeOverlay(doc, primary, id, color2);
947
947
  svg.appendChild(overlay);
948
- chunkSCD3AHMY_cjs.startChangeFade(overlay, reducedMotion);
949
- const duration = reducedMotion ? chunkSCD3AHMY_cjs.REDUCED_MOTION_DURATION_MS : chunkSCD3AHMY_cjs.FLASH_DURATION_MS;
948
+ chunkWZA3DJJH_cjs.startChangeFade(overlay, reducedMotion);
949
+ const duration = reducedMotion ? chunkWZA3DJJH_cjs.REDUCED_MOTION_DURATION_MS : chunkWZA3DJJH_cjs.FLASH_DURATION_MS;
950
950
  timers.set(
951
951
  id,
952
952
  setTimeout(() => {
@@ -1033,7 +1033,7 @@ var OwnerPointerController = class {
1033
1033
  this.#selection = selection;
1034
1034
  }
1035
1035
  hover(event) {
1036
- const owner = chunkSCD3AHMY_cjs.resolveOwner(event.target);
1036
+ const owner = chunkWZA3DJJH_cjs.resolveOwner(event.target);
1037
1037
  this.#emitter.emit(
1038
1038
  "ownerHover",
1039
1039
  owner ? { diagramId: this.#diagramId, owner, modifiers: modifiersOf(event) } : { diagramId: this.#diagramId, owner: null }
@@ -1041,7 +1041,7 @@ var OwnerPointerController = class {
1041
1041
  }
1042
1042
  select(event) {
1043
1043
  const target = event.target;
1044
- const owner = chunkSCD3AHMY_cjs.resolveOwner(target);
1044
+ const owner = chunkWZA3DJJH_cjs.resolveOwner(target);
1045
1045
  if (!owner) {
1046
1046
  this.#clearWhenOutsideOverlay(target);
1047
1047
  return;
@@ -1062,7 +1062,7 @@ var OwnerPointerController = class {
1062
1062
  owner,
1063
1063
  modifiers
1064
1064
  });
1065
- const node = chunkSCD3AHMY_cjs.findOwnerNode(this.#svg, owner.id, chunkSCD3AHMY_cjs.isPrimary);
1065
+ const node = chunkWZA3DJJH_cjs.findOwnerNode(this.#svg, owner.id, chunkWZA3DJJH_cjs.isPrimary);
1066
1066
  if (node && !node.hasAttribute("tabindex")) {
1067
1067
  node.setAttribute("tabindex", "-1");
1068
1068
  }
@@ -1090,12 +1090,12 @@ var PointerInteractionSession = class {
1090
1090
  }
1091
1091
  #onPointerDown = (event) => {
1092
1092
  const target = event.target;
1093
- const overContent = Boolean(chunkSCD3AHMY_cjs.resolveOwner(target)) || isSelectionOverlayControl(target);
1093
+ const overContent = Boolean(chunkWZA3DJJH_cjs.resolveOwner(target)) || isSelectionOverlayControl(target);
1094
1094
  this.#down = {
1095
1095
  x: event.clientX,
1096
1096
  y: event.clientY,
1097
1097
  moved: false,
1098
- panable: chunkSCD3AHMY_cjs.isCameraGesture(event) || !overContent
1098
+ panable: chunkWZA3DJJH_cjs.isCameraGesture(event) || !overContent
1099
1099
  };
1100
1100
  };
1101
1101
  #onPointerMove = (event) => {
@@ -1123,7 +1123,7 @@ var PointerInteractionSession = class {
1123
1123
  if (!this.#down.moved) {
1124
1124
  return false;
1125
1125
  }
1126
- if (this.#down.panable && chunkSCD3AHMY_cjs.isCameraGesture(event)) {
1126
+ if (this.#down.panable && chunkWZA3DJJH_cjs.isCameraGesture(event)) {
1127
1127
  this.#display.panBy(event.movementX, event.movementY);
1128
1128
  }
1129
1129
  return true;
@@ -1147,15 +1147,15 @@ function paintSelectionOverlays(svg, selectedIds, owners) {
1147
1147
  }
1148
1148
  const document = svg.ownerDocument;
1149
1149
  for (const id of selectedIds) {
1150
- const primary = chunkSCD3AHMY_cjs.findOwnerNode(svg, id, chunkSCD3AHMY_cjs.isPrimary);
1150
+ const primary = chunkWZA3DJJH_cjs.findOwnerNode(svg, id, chunkWZA3DJJH_cjs.isPrimary);
1151
1151
  if (!primary) {
1152
1152
  continue;
1153
1153
  }
1154
1154
  const owner = owners.get(id);
1155
- const overlay = owner?.role === "link" ? chunkSCD3AHMY_cjs.linkSelectionOverlay(document, primary, id, svg) : owner?.role === "path" ? chunkSCD3AHMY_cjs.pathSelectionOverlay(document, primary, id, svg) : owner?.role === "isometric" ? chunkSCD3AHMY_cjs.isometricSelectionOverlay(document, primary, id, svg) : chunkSCD3AHMY_cjs.shapeSelectionOverlay(document, primary, id, svg, owner ? chunkSCD3AHMY_cjs.DERIVED_HEIGHT_ROLES.has(owner.role) : false);
1155
+ const overlay = owner?.role === "link" ? chunkWZA3DJJH_cjs.linkSelectionOverlay(document, primary, id, svg) : owner?.role === "path" ? chunkWZA3DJJH_cjs.pathSelectionOverlay(document, primary, id, svg) : owner?.role === "isometric" ? chunkWZA3DJJH_cjs.isometricSelectionOverlay(document, primary, id, svg) : chunkWZA3DJJH_cjs.shapeSelectionOverlay(document, primary, id, svg, owner ? chunkWZA3DJJH_cjs.DERIVED_HEIGHT_ROLES.has(owner.role) : false);
1156
1156
  svg.appendChild(overlay);
1157
1157
  if (owner?.role === "shape" && selectedIds.size === 1) {
1158
- svg.appendChild(chunkSCD3AHMY_cjs.quickDuplicateBubbles(document, primary, id, svg));
1158
+ svg.appendChild(chunkWZA3DJJH_cjs.quickDuplicateBubbles(document, primary, id, svg));
1159
1159
  }
1160
1160
  }
1161
1161
  }
@@ -1194,7 +1194,7 @@ var SelectionController = class {
1194
1194
  selectIds(ids) {
1195
1195
  for (const id of ids) {
1196
1196
  const element = this.#svg.querySelector(`[data-sf-id="${CSS.escape(id)}"]`);
1197
- const owner = chunkSCD3AHMY_cjs.resolveOwner(element);
1197
+ const owner = chunkWZA3DJJH_cjs.resolveOwner(element);
1198
1198
  if (owner) {
1199
1199
  this.remember(owner);
1200
1200
  }
@@ -1206,7 +1206,7 @@ var SelectionController = class {
1206
1206
  // src/runtime/viewer/interaction/wheel.ts
1207
1207
  function bindWheelZoom(display, selection) {
1208
1208
  const onWheel = (event) => {
1209
- if (!chunkSCD3AHMY_cjs.isCameraGesture(event)) {
1209
+ if (!chunkWZA3DJJH_cjs.isCameraGesture(event)) {
1210
1210
  return;
1211
1211
  }
1212
1212
  event.preventDefault();
@@ -2971,9 +2971,7 @@ float roundedBoxDistance(vec2 point, vec2 halfSize, float radius) {
2971
2971
  }
2972
2972
 
2973
2973
  float random(vec2 point) {
2974
- vec3 value = fract(vec3(point.xyx) * 0.1031);
2975
- value += dot(value, value.yzx + 33.33);
2976
- return fract((value.x + value.y) * value.z);
2974
+ return fract(sin(dot(mod(point, 289.0), vec2(127.1, 311.7))) * 43758.5453123);
2977
2975
  }
2978
2976
 
2979
2977
  void main() {
@@ -3584,6 +3582,218 @@ var violetGlassLightProgram = {
3584
3582
  fragmentSource: fragmentSource26
3585
3583
  };
3586
3584
 
3585
+ // src/runtime/viewer/shaders/builtins/vortex.ts
3586
+ var fragmentSource27 = `
3587
+ precision highp float;
3588
+
3589
+ uniform float uTime;
3590
+ uniform float uSpeed;
3591
+ uniform float uIntensity;
3592
+ uniform float uRings;
3593
+ uniform float uRingWidth;
3594
+ uniform float uTwist;
3595
+ uniform float uArms;
3596
+ uniform float uWobble;
3597
+ uniform float uVariation;
3598
+ uniform float uOffsetX;
3599
+ uniform float uOffsetY;
3600
+ uniform float uSquash;
3601
+ uniform float uEye;
3602
+ uniform float uAngle;
3603
+ uniform float uSpread;
3604
+ uniform float uGlow;
3605
+ uniform float uGloss;
3606
+ uniform float uGlossHeight;
3607
+ uniform float uVignette;
3608
+ uniform float uGrain;
3609
+ uniform vec3 uColor;
3610
+ uniform vec3 uAccent;
3611
+ uniform vec3 uCool;
3612
+ varying vec2 vUv;
3613
+
3614
+ float hash(vec2 p) {
3615
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
3616
+ }
3617
+
3618
+ void main() {
3619
+ vec2 p = vUv * 2.0 - 1.0;
3620
+ float edge = length(p);
3621
+ if (edge > 1.0) discard;
3622
+
3623
+ float time = uTime * max(uSpeed, 0.0);
3624
+
3625
+ // The rings are measured from a middle that can lie off the middle of the face, and squeezed to give a little depth.
3626
+ vec2 q = p - vec2(uOffsetX, uOffsetY);
3627
+ q.y /= max(uSquash, 0.2);
3628
+ float radius = length(q);
3629
+ float around = atan(q.y, q.x);
3630
+ float turn = around / 6.2831853;
3631
+ // The twist turns the pattern more the nearer it is to the middle. The rings themselves stay round.
3632
+ float angle = around + uTwist * pow(1.0 - radius, 2.0) * 3.0 + time * 0.3 * (1.0 - radius);
3633
+
3634
+ // The phase of the rings: outwards from the middle, drifting inwards with time. Whole arms make the rings join into a spiral, and a
3635
+ // whole number leaves no seam. The wobble bends the rings so no two are alike.
3636
+ float bend = uWobble * (0.12 * sin(angle * 2.0 + time * 0.6 + radius * 3.0) + 0.06 * sin(angle * 3.0 - time * 0.45));
3637
+ float phase = (radius + bend) * uRings - time * 0.25 + floor(uArms + 0.5) * turn;
3638
+ float away = abs(fract(phase) - 0.5);
3639
+ float width = mix(0.04, 0.32, clamp(uRingWidth, 0.0, 1.0));
3640
+ // Every ring has a brightness of its own, so a few stand out and the others are faint.
3641
+ float own = mix(1.0, 0.25 + 1.0 * hash(vec2(floor(phase), 3.7)), clamp(uVariation, 0.0, 1.0));
3642
+ float ring = exp(-pow(away / width, 2.0)) * own;
3643
+ float fineAway = abs(fract(phase * 2.3 + 0.5) - 0.5);
3644
+ float fine = exp(-pow(fineAway / (width * 0.8), 2.0)) * 0.5;
3645
+ float halo = exp(-pow(away / (width * 3.0), 2.0));
3646
+
3647
+ // Rings fade in from the eye and out towards the rim, and some arcs of a ring are brighter than the rest.
3648
+ float envelope = smoothstep(uEye, uEye + 0.3, radius) * (1.0 - smoothstep(0.72, 1.05, edge));
3649
+ float arcs = 0.45 + 0.55 * (0.5 + 0.5 * sin(angle * 2.0 + radius * 4.0 + time * 0.5 + 1.0));
3650
+
3651
+ // One side of the face is warm and the other cool, and the spread says how sharp the change is.
3652
+ float side = cos(angle - radians(uAngle));
3653
+ float warm = mix(0.5, smoothstep(-0.7, 0.9, side), clamp(uSpread, 0.0, 1.0));
3654
+ vec3 hue = mix(uCool, uAccent, warm);
3655
+
3656
+ vec3 color = uColor * (0.4 + 0.5 * (1.0 - edge));
3657
+ color += hue * (ring * 0.9 + fine * 0.3) * envelope * arcs * uGlow;
3658
+ color += hue * halo * envelope * 0.1 * uGlow;
3659
+ // The dark eye.
3660
+ color *= 0.55 + 0.45 * smoothstep(0.0, uEye + 0.12, radius);
3661
+
3662
+ // A soft light on the glass at the bottom, with a clear lower edge.
3663
+ float below = smoothstep(-1.0 + uGlossHeight, -1.0 + uGlossHeight * 0.35, p.y);
3664
+ float across = 1.0 - smoothstep(0.45, 1.0, abs(p.x));
3665
+ color += mix(uCool, vec3(1.0), 0.5) * below * across * uGloss;
3666
+
3667
+ color *= 1.0 - smoothstep(0.55, 1.0, edge) * uVignette;
3668
+ color += (hash(gl_FragCoord.xy + time) - 0.5) * uGrain;
3669
+
3670
+ float alpha = 1.0 - smoothstep(0.985, 1.0, edge);
3671
+ gl_FragColor = vec4(clamp(color * max(uIntensity, 0.0), 0.0, 1.0), alpha);
3672
+ }
3673
+ `;
3674
+ var vortexProgram = {
3675
+ name: "vortex",
3676
+ fragmentSource: fragmentSource27,
3677
+ defaultParameters: {
3678
+ speed: 0.3,
3679
+ intensity: 1,
3680
+ rings: 12,
3681
+ ringWidth: 0.28,
3682
+ twist: 0.6,
3683
+ arms: 0,
3684
+ wobble: 0.12,
3685
+ variation: 0.85,
3686
+ offsetX: 0,
3687
+ offsetY: 0,
3688
+ squash: 1,
3689
+ eye: 0.3,
3690
+ angle: 215,
3691
+ spread: 0.6,
3692
+ glow: 0.6,
3693
+ gloss: 0.45,
3694
+ glossHeight: 0.4,
3695
+ vignette: 0.6,
3696
+ grain: 0.02,
3697
+ color: "#05060f",
3698
+ accent: "#e0368f",
3699
+ cool: "#3d4bff"
3700
+ }
3701
+ };
3702
+
3703
+ // src/runtime/viewer/shaders/builtins/waves.ts
3704
+ var fragmentSource28 = `
3705
+ precision highp float;
3706
+
3707
+ uniform float uTime;
3708
+ uniform float uSpeed;
3709
+ uniform float uIntensity;
3710
+ uniform float uLayers;
3711
+ uniform float uLevel;
3712
+ uniform float uAmplitude;
3713
+ uniform float uFrequency;
3714
+ uniform float uTilt;
3715
+ uniform float uSoftness;
3716
+ uniform float uEdge;
3717
+ uniform float uShade;
3718
+ uniform float uGlow;
3719
+ uniform float uVignette;
3720
+ uniform float uGrain;
3721
+ uniform vec3 uColor;
3722
+ uniform vec3 uAccent;
3723
+ uniform vec3 uCool;
3724
+ uniform vec3 uHighlight;
3725
+ varying vec2 vUv;
3726
+
3727
+ float hash(vec2 p) {
3728
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
3729
+ }
3730
+
3731
+ void main() {
3732
+ vec2 p = vUv * 2.0 - 1.0;
3733
+ float edge = length(p);
3734
+ if (edge > 1.0) discard;
3735
+
3736
+ float time = uTime * max(uSpeed, 0.0);
3737
+ float angle = radians(uTilt);
3738
+ vec2 q = vec2(cos(angle) * p.x - sin(angle) * p.y, sin(angle) * p.x + cos(angle) * p.y);
3739
+
3740
+ // The ground, a little lighter in the middle.
3741
+ vec3 color = uColor * (0.6 + 0.4 * (1.0 - edge));
3742
+ float count = clamp(uLayers, 1.0, 8.0);
3743
+ float soft = max(uSoftness, 0.004);
3744
+
3745
+ // The layers lie one behind the other, the farthest first. Each one fills the area under a wave line, and the line itself catches the light.
3746
+ for (int i = 0; i < 8; i++) {
3747
+ float index = float(i);
3748
+ if (index >= count) break;
3749
+ float depth = index / max(count - 1.0, 1.0);
3750
+ float base = uLevel + mix(0.5, -0.55, depth);
3751
+ float swing = uAmplitude * (0.55 + 0.45 * depth);
3752
+ float line = base
3753
+ + swing * 0.6 * sin(q.x * uFrequency * (1.0 + 0.3 * index) + index * 1.7 + time * (0.4 + 0.08 * index))
3754
+ + swing * 0.4 * sin(q.x * uFrequency * 2.1 - index * 2.3 - time * 0.3);
3755
+ float under = smoothstep(soft, -soft, q.y - line);
3756
+ // A layer is lit at its crest and falls into shadow below it, so it reads as a fold of cloth and not as a flat band.
3757
+ float sink = clamp((line - q.y) / 0.35, 0.0, 1.0);
3758
+ vec3 layer = mix(uAccent, uCool, depth) * mix(1.15, 1.0 - 0.6 * uShade, sink);
3759
+ color = mix(color, layer, under * (0.5 + 0.2 * depth));
3760
+ float crest = exp(-pow((q.y - line) / (0.012 + soft * 0.5), 2.0));
3761
+ color += uHighlight * crest * uEdge * (0.35 + 0.65 * (1.0 - depth));
3762
+ }
3763
+
3764
+ // A soft light over the surface, and a dark edge.
3765
+ color += uHighlight * uGlow * 0.18 * exp(-pow((q.y - 0.55) / 0.45, 2.0));
3766
+ color *= 1.0 - smoothstep(0.6, 1.0, edge) * uVignette;
3767
+ color += (hash(gl_FragCoord.xy + time) - 0.5) * uGrain;
3768
+
3769
+ float alpha = 1.0 - smoothstep(0.985, 1.0, edge);
3770
+ gl_FragColor = vec4(clamp(color * max(uIntensity, 0.0), 0.0, 1.0), alpha);
3771
+ }
3772
+ `;
3773
+ var wavesProgram = {
3774
+ name: "waves",
3775
+ fragmentSource: fragmentSource28,
3776
+ defaultParameters: {
3777
+ speed: 0.25,
3778
+ intensity: 1,
3779
+ layers: 5,
3780
+ level: 0,
3781
+ amplitude: 0.14,
3782
+ frequency: 3.2,
3783
+ tilt: -12,
3784
+ softness: 0.05,
3785
+ edge: 0.5,
3786
+ shade: 0.6,
3787
+ glow: 0.5,
3788
+ vignette: 0.4,
3789
+ grain: 0.02,
3790
+ color: "#0e0828",
3791
+ accent: "#6b3fd4",
3792
+ cool: "#2f5fe0",
3793
+ highlight: "#b9a0ff"
3794
+ }
3795
+ };
3796
+
3587
3797
  // src/runtime/viewer/shaders/programs.ts
3588
3798
  var builtins = [
3589
3799
  orbProgram,
@@ -3611,7 +3821,9 @@ var builtins = [
3611
3821
  lightBandProgram,
3612
3822
  silkFoldsProgram,
3613
3823
  glowCardProgram,
3614
- glassDotsProgram
3824
+ glassDotsProgram,
3825
+ vortexProgram,
3826
+ wavesProgram
3615
3827
  ];
3616
3828
  var programs = new Map(builtins.map((program) => [program.name, program]));
3617
3829
  function registerShaderProgram(program) {
@@ -3792,9 +4004,9 @@ function compile(gl, type, source) {
3792
4004
  }
3793
4005
  return shader;
3794
4006
  }
3795
- function linkProgram(gl, fragmentSource27) {
4007
+ function linkProgram(gl, fragmentSource29) {
3796
4008
  const vertex = compile(gl, gl.VERTEX_SHADER, VERTEX_SOURCE);
3797
- const fragment = compile(gl, gl.FRAGMENT_SHADER, fragmentSource27);
4009
+ const fragment = compile(gl, gl.FRAGMENT_SHADER, fragmentSource29);
3798
4010
  if (!vertex || !fragment) {
3799
4011
  if (vertex) {
3800
4012
  gl.deleteShader(vertex);
@@ -3895,6 +4107,7 @@ function createSurface(canvas) {
3895
4107
  const baseFill = baseGeometry?.getAttribute("fill");
3896
4108
  baseGeometry?.setAttribute("fill", "none");
3897
4109
  return {
4110
+ programName: definition.name,
3898
4111
  owner,
3899
4112
  canvas,
3900
4113
  gl,
@@ -3931,6 +4144,22 @@ function releaseSurface(surface) {
3931
4144
  surface.baseGeometry.setAttribute("fill", surface.baseFill);
3932
4145
  }
3933
4146
  }
4147
+ function refreshSurface(surface, svg) {
4148
+ const owner = surface.canvas.closest("[data-sf-shader]");
4149
+ const name = owner?.getAttribute("data-sf-shader");
4150
+ const definition = name ? shaderProgram(name) : void 0;
4151
+ if (!owner || !svg.contains(surface.canvas) || !definition) {
4152
+ return false;
4153
+ }
4154
+ if (definition.name !== surface.programName || definition.replacesBaseFill || surface.baseGeometry) {
4155
+ return false;
4156
+ }
4157
+ surface.owner = owner;
4158
+ surface.parameters = { ...definition.defaultParameters, ...parametersOf(owner) };
4159
+ surface.surfacePadding = surfacePaddingOf(owner);
4160
+ surface.shapeColor = color(owner.getAttribute("data-sf-shader-fill") ?? void 0, [1, 1, 1]);
4161
+ return true;
4162
+ }
3934
4163
 
3935
4164
  // src/runtime/viewer/shaders/reactiveLightField.ts
3936
4165
  function geometryOf(surface) {
@@ -4245,8 +4474,12 @@ function rememberSurfaces(surfaces) {
4245
4474
  })
4246
4475
  );
4247
4476
  }
4248
- function createSurfaces(svg, memory) {
4477
+ function createSurfaces(svg, memory, kept) {
4249
4478
  return [...svg.querySelectorAll("canvas[data-sf-shader-canvas]")].flatMap((canvas) => {
4479
+ const keptSurface = kept.get(canvas);
4480
+ if (keptSurface) {
4481
+ return [keptSurface];
4482
+ }
4250
4483
  const surface = createSurface(canvas);
4251
4484
  const ownerId = surface?.owner.getAttribute("data-sf-id");
4252
4485
  const previous = ownerId ? memory.get(ownerId) : void 0;
@@ -4301,9 +4534,20 @@ var ShaderSurfaces = class {
4301
4534
  }
4302
4535
  refresh() {
4303
4536
  const memory = rememberSurfaces(this.surfaces);
4304
- this.stop();
4537
+ this.cancelFrame();
4538
+ const kept = /* @__PURE__ */ new Map();
4539
+ for (const surface of this.surfaces) {
4540
+ if (refreshSurface(surface, this.svg)) {
4541
+ kept.set(surface.canvas, surface);
4542
+ }
4543
+ }
4544
+ for (const surface of this.surfaces) {
4545
+ if (!kept.has(surface.canvas)) {
4546
+ releaseSurface(surface);
4547
+ }
4548
+ }
4305
4549
  const generation = ++this.backdropGeneration;
4306
- this.surfaces = createSurfaces(this.svg, memory);
4550
+ this.surfaces = createSurfaces(this.svg, memory, kept);
4307
4551
  updateReactiveLightFields(this.surfaces);
4308
4552
  this.captureBackdrops(generation);
4309
4553
  if (this.surfaces.length > 0) {
@@ -4329,11 +4573,14 @@ var ShaderSurfaces = class {
4329
4573
  }
4330
4574
  this.frame = this.view?.requestAnimationFrame(this.draw);
4331
4575
  };
4332
- stop() {
4576
+ cancelFrame() {
4333
4577
  if (this.frame !== void 0) {
4334
4578
  this.view?.cancelAnimationFrame(this.frame);
4335
4579
  this.frame = void 0;
4336
4580
  }
4581
+ }
4582
+ stop() {
4583
+ this.cancelFrame();
4337
4584
  for (const surface of this.surfaces) {
4338
4585
  releaseSurface(surface);
4339
4586
  }
@@ -4392,21 +4639,21 @@ function mountShaderSurfaces(svg) {
4392
4639
 
4393
4640
  // src/runtime/viewer/source.ts
4394
4641
  function renderViewerSource(next, defaultRenderOptions) {
4395
- const svg = next.svg ?? (next.source != null ? chunk5PJ55GPG_cjs.render(next.source, { ...next.renderOptions ?? defaultRenderOptions, linkHitAreas: true }).svg : null);
4642
+ const svg = next.svg ?? (next.source != null ? chunk5G3BEXQU_cjs.render(next.source, { ...next.renderOptions ?? defaultRenderOptions, linkHitAreas: true }).svg : null);
4396
4643
  if (svg == null) {
4397
4644
  throw new Error("createViewer: provide either `source` (SFL) or `svg`.");
4398
4645
  }
4399
4646
  return svg;
4400
4647
  }
4401
4648
  function assertCreateViewerContract(svg) {
4402
- const version = chunkSCD3AHMY_cjs.parseContractVersion(svg);
4403
- if (!chunkSCD3AHMY_cjs.isContractCompatible(version)) {
4649
+ const version = chunkWZA3DJJH_cjs.parseContractVersion(svg);
4650
+ if (!chunkWZA3DJJH_cjs.isContractCompatible(version)) {
4404
4651
  throw new Error(`createViewer: incompatible DOM contract (svg=${version}). Renderer and viewer versions differ.`);
4405
4652
  }
4406
4653
  }
4407
4654
  function assertViewerUpdateContract(svg) {
4408
- const version = chunkSCD3AHMY_cjs.parseContractVersion(svg);
4409
- if (!chunkSCD3AHMY_cjs.isContractCompatible(version)) {
4655
+ const version = chunkWZA3DJJH_cjs.parseContractVersion(svg);
4656
+ if (!chunkWZA3DJJH_cjs.isContractCompatible(version)) {
4410
4657
  throw new Error(`viewer.update: incompatible DOM contract (svg=${version}). Renderer and viewer versions differ.`);
4411
4658
  }
4412
4659
  }
@@ -4640,7 +4887,7 @@ function trackScales(wiring, event) {
4640
4887
  }
4641
4888
  function driveValue(wiring, id, event) {
4642
4889
  const { runtime, svg } = wiring;
4643
- const kind = chunkLSEMXRB5_cjs.getComponentDescriptor(runtime.graph.elements.get(id)?.componentType)?.interaction;
4890
+ const kind = chunkUHKFJBY5_cjs.getComponentDescriptor(runtime.graph.elements.get(id)?.componentType)?.interaction;
4644
4891
  if (kind !== "slide" && kind !== "pick" && kind !== "turn" && kind !== "range") {
4645
4892
  return;
4646
4893
  }
@@ -4779,5 +5026,5 @@ exports.connectInteraction = connectInteraction;
4779
5026
  exports.createViewer = createViewer;
4780
5027
  exports.registerShaderProgram = registerShaderProgram;
4781
5028
  exports.shaderProgram = shaderProgram;
4782
- //# sourceMappingURL=chunk-KRSX4UZ7.cjs.map
4783
- //# sourceMappingURL=chunk-KRSX4UZ7.cjs.map
5029
+ //# sourceMappingURL=chunk-F24JURN2.cjs.map
5030
+ //# sourceMappingURL=chunk-F24JURN2.cjs.map