@pie-players/pie-assessment-toolkit 0.3.45 → 0.3.47

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.
package/README.md CHANGED
@@ -1410,7 +1410,11 @@ from tool configuration. Two sanitization layers apply:
1410
1410
  (PIE-94 / WCAG 1.4.10 Reflow at 400% zoom). The wrapper is
1411
1411
  keyboard-scrollable (`tabindex="0"`, `role="region"`) and carries
1412
1412
  the image's `alt` text in its `aria-label`; matching CSS lives in
1413
- `@pie-players/pie-theme` (`components.css`).
1413
+ `@pie-players/pie-theme` (`components.css`). Authored `<table>`
1414
+ elements outside a `pie-*` custom element get the same treatment via
1415
+ `<div class="pie-table-scroll">` so wide data grids reflow into a
1416
+ horizontally scrollable region; the wrapper's `aria-label` is derived
1417
+ from the table's `aria-label` / `aria-labelledby` / `<caption>`.
1414
1418
  - **Tool icons and SSML** - tool-registered icon markup is parsed and
1415
1419
  DOMPurified inside the toolbar at render time; SSML payloads are
1416
1420
  restricted to an allow-listed subset of SSML tags/attributes before
@@ -5332,7 +5332,11 @@ function isExternalIconUrl(icon) {
5332
5332
 
5333
5333
  // dist/components/.ItemToolBar.custom-element.unbundled.js
5334
5334
  import { sanitizeSvgIcon } from "@pie-players/pie-players-shared/security";
5335
- import { createFocusTrap } from "@pie-players/pie-players-shared";
5335
+ import {
5336
+ createFocusTrap,
5337
+ FOCUSABLE_SELECTOR,
5338
+ isProgrammaticFocusTarget
5339
+ } from "@pie-players/pie-players-shared";
5336
5340
 
5337
5341
  // dist/services/tool-config-defaults.js
5338
5342
  var DEFAULT_TOOL_PLACEMENT = {
@@ -6761,10 +6765,12 @@ var calculatorToolRegistration = {
6761
6765
  draggable: true,
6762
6766
  resizable: true,
6763
6767
  closeable: true,
6764
- initialWidth: 720,
6765
- initialHeight: 620,
6766
- minWidth: 360,
6767
- minHeight: 420
6768
+ initialWidth: 380,
6769
+ initialHeight: 420,
6770
+ minWidth: 380,
6771
+ minHeight: 420,
6772
+ initialAlign: "bottom-right",
6773
+ initialMargin: 16
6768
6774
  }
6769
6775
  }
6770
6776
  ],
@@ -8604,6 +8610,7 @@ function ItemToolBar($$anchor, $$props) {
8604
8610
  const FA_PRO_HREFS = ["/_fa-pro/fontawesome.min.css", "/_fa-pro/light.min.css"];
8605
8611
  const FA_FREE_HREF = "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/all.min.css";
8606
8612
  const ROBOTO_HREF = "https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap";
8613
+ const FA_HREF_PATTERN = /font.?awesome|fa-?pro/i;
8607
8614
  let ndsAssetsInstalled = false;
8608
8615
  const ensureNdsAssets = () => {
8609
8616
  if (!isBrowser || ndsAssetsInstalled)
@@ -8615,6 +8622,9 @@ function ItemToolBar($$anchor, $$props) {
8615
8622
  link2.href = ROBOTO_HREF;
8616
8623
  document.head.appendChild(link2);
8617
8624
  }
8625
+ const hostHasFa = Array.from(document.querySelectorAll('link[rel="stylesheet"][href]')).some((link2) => FA_HREF_PATTERN.test(link2.href));
8626
+ if (hostHasFa)
8627
+ return;
8618
8628
  if (!document.querySelector(`link[href="${FA_FREE_HREF}"]`)) {
8619
8629
  const link2 = document.createElement("link");
8620
8630
  link2.rel = "stylesheet";
@@ -8631,7 +8641,6 @@ function ItemToolBar($$anchor, $$props) {
8631
8641
  }
8632
8642
  };
8633
8643
  const FA_TOOLBAR_SHADOW_INSTALLED = "__pieFaToolbarShadowInstalled";
8634
- const FA_HREF_PATTERN = /font.?awesome|fa-?pro/i;
8635
8644
  const installFaInToolbarShadow = (root) => {
8636
8645
  const shadow = root.getRootNode();
8637
8646
  if (!(shadow instanceof ShadowRoot))
@@ -8653,9 +8662,6 @@ function ItemToolBar($$anchor, $$props) {
8653
8662
  const documentFaLinks = Array.from(document.querySelectorAll('link[rel="stylesheet"][href]')).filter((link2) => FA_HREF_PATTERN.test(link2.href));
8654
8663
  for (const link2 of documentFaLinks)
8655
8664
  appendLink(link2.href);
8656
- const shim = document.createElement("style");
8657
- shim.textContent = '.fa-light{font-family:"Font Awesome 6 Free";font-weight:900;}';
8658
- shadow.appendChild(shim);
8659
8665
  };
8660
8666
  const ndsIconButtonAction = (node) => {
8661
8667
  ensureNdsAssets();
@@ -9232,6 +9238,10 @@ function ItemToolBar($$anchor, $$props) {
9232
9238
  let controlsEl = null;
9233
9239
  let closeButtonEl = null;
9234
9240
  let resizeHandleEl = null;
9241
+ let startFocusGuardEl = null;
9242
+ let endFocusGuardEl = null;
9243
+ let focusGuardRedirecting = false;
9244
+ let calculatorBridgeAttached = false;
9235
9245
  let mountedContentElement = null;
9236
9246
  let dragPointerId = null;
9237
9247
  let resizePointerId = null;
@@ -9241,6 +9251,10 @@ function ItemToolBar($$anchor, $$props) {
9241
9251
  let resizeStartHeight = 0;
9242
9252
  let resizeStartX = 0;
9243
9253
  let resizeStartY = 0;
9254
+ let resizeStartShellX = 0;
9255
+ let resizeStartShellY = 0;
9256
+ let resizeCorner = null;
9257
+ const resizeHandleEls = [];
9244
9258
  let x2 = 0;
9245
9259
  let y2 = 0;
9246
9260
  let width = currentArgs.mounted.entry.shell?.initialWidth ?? 720;
@@ -9427,8 +9441,31 @@ function ItemToolBar($$anchor, $$props) {
9427
9441
  const centerShell = () => {
9428
9442
  const viewportW = window.innerWidth;
9429
9443
  const viewportH = window.innerHeight;
9430
- x2 = Math.max(0, Math.round((viewportW - width) / 2));
9431
- y2 = Math.max(0, Math.round((viewportH - height) / 2));
9444
+ const shellConfig = currentArgs.mounted.entry.shell;
9445
+ const align = shellConfig?.initialAlign ?? "center";
9446
+ const margin = shellConfig?.initialMargin ?? 16;
9447
+ const verticalMargin = margin + 60;
9448
+ switch (align) {
9449
+ case "top-left":
9450
+ x2 = margin;
9451
+ y2 = verticalMargin;
9452
+ break;
9453
+ case "top-right":
9454
+ x2 = Math.max(0, viewportW - width - margin);
9455
+ y2 = verticalMargin;
9456
+ break;
9457
+ case "bottom-left":
9458
+ x2 = margin;
9459
+ y2 = Math.max(0, viewportH - height - verticalMargin);
9460
+ break;
9461
+ case "bottom-right":
9462
+ x2 = Math.max(0, viewportW - width - margin);
9463
+ y2 = Math.max(0, viewportH - height - verticalMargin);
9464
+ break;
9465
+ default:
9466
+ x2 = Math.max(0, Math.round((viewportW - width) / 2));
9467
+ y2 = Math.max(0, Math.round((viewportH - height) / 2));
9468
+ }
9432
9469
  applyPositionAndSize();
9433
9470
  };
9434
9471
  const restoreOpenerFocus = () => {
@@ -9464,14 +9501,113 @@ function ItemToolBar($$anchor, $$props) {
9464
9501
  if (!openerEl && active && !shellEl.contains(active)) {
9465
9502
  openerEl = active;
9466
9503
  }
9504
+ const isCalculatorShellTrap = currentArgs.mounted.toolId === "calculator";
9505
+ if (isCalculatorShellTrap && !calculatorBridgeAttached) {
9506
+ document.addEventListener("keydown", onCalculatorBridgeKeydown, true);
9507
+ calculatorBridgeAttached = true;
9508
+ }
9467
9509
  focusTrapCleanup = createFocusTrap(shellEl, {
9468
9510
  initialFocus: closeButtonEl,
9469
9511
  onEscape: () => {
9470
9512
  closeShell();
9471
- }
9513
+ },
9514
+ wrap: !isCalculatorShellTrap,
9515
+ onTabExit: isCalculatorShellTrap ? (direction, event2) => {
9516
+ if (direction === "backward") {
9517
+ if (openerEl?.isConnected) {
9518
+ event2.preventDefault();
9519
+ try {
9520
+ openerEl.focus();
9521
+ } catch {}
9522
+ }
9523
+ return;
9524
+ }
9525
+ const next2 = findFirstQuestionFocusable();
9526
+ if (next2) {
9527
+ event2.preventDefault();
9528
+ try {
9529
+ next2.focus();
9530
+ } catch {}
9531
+ }
9532
+ } : undefined
9472
9533
  });
9473
9534
  };
9535
+ const findFirstQuestionFocusable = () => {
9536
+ const scope = get2(toolbarContext).getScopeElement?.() ?? null;
9537
+ if (!scope)
9538
+ return null;
9539
+ const isExcluded = (el) => {
9540
+ if (get2(toolbarRootElement) && get2(toolbarRootElement).contains(el))
9541
+ return true;
9542
+ if (shellEl && shellEl.contains(el))
9543
+ return true;
9544
+ return false;
9545
+ };
9546
+ const visit = (node2) => {
9547
+ if (node2 instanceof HTMLElement) {
9548
+ if (isExcluded(node2))
9549
+ return null;
9550
+ if (node2.matches?.(FOCUSABLE_SELECTOR) && isProgrammaticFocusTarget(node2)) {
9551
+ return node2;
9552
+ }
9553
+ }
9554
+ const shadow = node2.shadowRoot;
9555
+ if (shadow) {
9556
+ for (let i = 0;i < shadow.children.length; i++) {
9557
+ const found = visit(shadow.children[i]);
9558
+ if (found)
9559
+ return found;
9560
+ }
9561
+ }
9562
+ for (let i = 0;i < node2.children.length; i++) {
9563
+ const found = visit(node2.children[i]);
9564
+ if (found)
9565
+ return found;
9566
+ }
9567
+ return null;
9568
+ };
9569
+ return visit(scope);
9570
+ };
9571
+ const getShellFocusables = () => {
9572
+ if (!shellEl)
9573
+ return [];
9574
+ return Array.from(shellEl.querySelectorAll(FOCUSABLE_SELECTOR)).filter((el) => el !== startFocusGuardEl && el !== endFocusGuardEl).filter(isProgrammaticFocusTarget);
9575
+ };
9576
+ const onCalculatorBridgeKeydown = (event2) => {
9577
+ if (event2.key !== "Tab")
9578
+ return;
9579
+ if (!shellEl || !currentArgs.active)
9580
+ return;
9581
+ const active = getDeepActiveElement();
9582
+ if (!active)
9583
+ return;
9584
+ if (shellEl.contains(active))
9585
+ return;
9586
+ const focusables = getShellFocusables();
9587
+ if (focusables.length === 0)
9588
+ return;
9589
+ if (event2.shiftKey) {
9590
+ const firstQuestion = findFirstQuestionFocusable();
9591
+ if (active !== firstQuestion)
9592
+ return;
9593
+ event2.preventDefault();
9594
+ try {
9595
+ focusables[focusables.length - 1].focus();
9596
+ } catch {}
9597
+ return;
9598
+ }
9599
+ if (active !== openerEl)
9600
+ return;
9601
+ event2.preventDefault();
9602
+ try {
9603
+ focusables[0].focus();
9604
+ } catch {}
9605
+ };
9474
9606
  const removeFocusTrap = () => {
9607
+ if (calculatorBridgeAttached) {
9608
+ document.removeEventListener("keydown", onCalculatorBridgeKeydown, true);
9609
+ calculatorBridgeAttached = false;
9610
+ }
9475
9611
  if (!focusTrapCleanup)
9476
9612
  return;
9477
9613
  const cleanup = focusTrapCleanup;
@@ -9489,25 +9625,28 @@ function ItemToolBar($$anchor, $$props) {
9489
9625
  if (!currentArgs.mounted.entry.shell?.draggable)
9490
9626
  return;
9491
9627
  const target = event2.target;
9492
- if (target.closest("button"))
9493
- return;
9494
- if (!shellEl)
9628
+ if (target.closest("button") || !shellEl)
9495
9629
  return;
9630
+ event2.preventDefault();
9496
9631
  dragPointerId = event2.pointerId;
9497
9632
  dragOffsetX = event2.clientX - x2;
9498
9633
  dragOffsetY = event2.clientY - y2;
9499
9634
  shellEl.setPointerCapture(event2.pointerId);
9500
9635
  bringToFront();
9501
9636
  };
9502
- const onResizePointerDown = (event2) => {
9637
+ const createResizePointerDownHandler = (corner) => (event2) => {
9503
9638
  if (!shellEl || !currentArgs.mounted.entry.shell?.resizable)
9504
9639
  return;
9640
+ event2.preventDefault();
9505
9641
  event2.stopPropagation();
9506
9642
  resizePointerId = event2.pointerId;
9643
+ resizeCorner = corner;
9507
9644
  resizeStartWidth = width;
9508
9645
  resizeStartHeight = height;
9509
9646
  resizeStartX = event2.clientX;
9510
9647
  resizeStartY = event2.clientY;
9648
+ resizeStartShellX = x2;
9649
+ resizeStartShellY = y2;
9511
9650
  shellEl.setPointerCapture(event2.pointerId);
9512
9651
  bringToFront();
9513
9652
  };
@@ -9515,6 +9654,7 @@ function ItemToolBar($$anchor, $$props) {
9515
9654
  if (!shellEl)
9516
9655
  return;
9517
9656
  if (dragPointerId === event2.pointerId) {
9657
+ event2.preventDefault();
9518
9658
  const maxX = Math.max(0, window.innerWidth - width);
9519
9659
  const maxY = Math.max(0, window.innerHeight - height);
9520
9660
  x2 = clamp(event2.clientX - dragOffsetX, 0, maxX);
@@ -9523,13 +9663,39 @@ function ItemToolBar($$anchor, $$props) {
9523
9663
  return;
9524
9664
  }
9525
9665
  if (resizePointerId === event2.pointerId) {
9666
+ event2.preventDefault();
9526
9667
  const shellConfig = currentArgs.mounted.entry.shell;
9527
9668
  const minWidth = shellConfig?.minWidth ?? 320;
9528
9669
  const minHeight = shellConfig?.minHeight ?? 240;
9529
9670
  const maxWidth = shellConfig?.maxWidth ?? window.innerWidth;
9530
9671
  const maxHeight = shellConfig?.maxHeight ?? window.innerHeight;
9531
- width = clamp(resizeStartWidth + (event2.clientX - resizeStartX), minWidth, Math.max(minWidth, Math.min(maxWidth, window.innerWidth - x2)));
9532
- height = clamp(resizeStartHeight + (event2.clientY - resizeStartY), minHeight, Math.max(minHeight, Math.min(maxHeight, window.innerHeight - y2)));
9672
+ const dx = event2.clientX - resizeStartX;
9673
+ const dy = event2.clientY - resizeStartY;
9674
+ if (resizeCorner === "se") {
9675
+ width = clamp(resizeStartWidth + dx, minWidth, Math.max(minWidth, Math.min(maxWidth, window.innerWidth - x2)));
9676
+ height = clamp(resizeStartHeight + dy, minHeight, Math.max(minHeight, Math.min(maxHeight, window.innerHeight - y2)));
9677
+ } else if (resizeCorner === "sw") {
9678
+ const rightEdge = resizeStartShellX + resizeStartWidth;
9679
+ const newWidth = clamp(resizeStartWidth - dx, minWidth, Math.min(maxWidth, rightEdge));
9680
+ x2 = rightEdge - newWidth;
9681
+ width = newWidth;
9682
+ height = clamp(resizeStartHeight + dy, minHeight, Math.max(minHeight, Math.min(maxHeight, window.innerHeight - y2)));
9683
+ } else if (resizeCorner === "ne") {
9684
+ const bottomEdge = resizeStartShellY + resizeStartHeight;
9685
+ width = clamp(resizeStartWidth + dx, minWidth, Math.max(minWidth, Math.min(maxWidth, window.innerWidth - x2)));
9686
+ const newHeight = clamp(resizeStartHeight - dy, minHeight, Math.min(maxHeight, bottomEdge));
9687
+ y2 = bottomEdge - newHeight;
9688
+ height = newHeight;
9689
+ } else if (resizeCorner === "nw") {
9690
+ const rightEdge = resizeStartShellX + resizeStartWidth;
9691
+ const bottomEdge = resizeStartShellY + resizeStartHeight;
9692
+ const newWidth = clamp(resizeStartWidth - dx, minWidth, Math.min(maxWidth, rightEdge));
9693
+ x2 = rightEdge - newWidth;
9694
+ width = newWidth;
9695
+ const newHeight = clamp(resizeStartHeight - dy, minHeight, Math.min(maxHeight, bottomEdge));
9696
+ y2 = bottomEdge - newHeight;
9697
+ height = newHeight;
9698
+ }
9533
9699
  applyShellStyle();
9534
9700
  notifyHostedResize();
9535
9701
  }
@@ -9562,14 +9728,20 @@ function ItemToolBar($$anchor, $$props) {
9562
9728
  shellEl.style.border = "1px solid var(--pie-border-light, #d1d5db)";
9563
9729
  shellEl.style.borderRadius = "12px";
9564
9730
  shellEl.style.boxShadow = "0 10px 40px color-mix(in srgb, var(--pie-black, #000) 25%, transparent)";
9565
- shellEl.style.overflow = "hidden";
9731
+ shellEl.style.overflow = "visible";
9566
9732
  shellEl.style.display = currentArgs.active ? "flex" : "none";
9567
9733
  shellEl.style.flexDirection = "column";
9734
+ shellEl.style.userSelect = "none";
9735
+ shellEl.style.webkitUserSelect = "none";
9736
+ shellEl.style.touchAction = "none";
9737
+ shellEl.setAttribute("draggable", "false");
9738
+ shellEl.addEventListener("dragstart", (e) => e.preventDefault());
9568
9739
  headerEl = document.createElement("div");
9569
9740
  headerEl.className = "pie-tool-shell__header";
9570
9741
  headerEl.style.display = "flex";
9571
9742
  headerEl.style.alignItems = "center";
9572
9743
  headerEl.style.justifyContent = "space-between";
9744
+ headerEl.style.gap = "6px";
9573
9745
  headerEl.style.padding = isCalculatorShell ? "12px 12px 12px 28px" : "10px 12px";
9574
9746
  if (isCalculatorShell) {
9575
9747
  headerEl.style.minHeight = "48px";
@@ -9584,6 +9756,13 @@ function ItemToolBar($$anchor, $$props) {
9584
9756
  }
9585
9757
  headerEl.style.cursor = currentArgs.mounted.entry.shell.draggable === false ? "default" : "move";
9586
9758
  headerEl.style.flex = "0 0 auto";
9759
+ headerEl.style.borderRadius = "12px 12px 0 0";
9760
+ headerEl.style.overflow = "hidden";
9761
+ headerEl.style.userSelect = "none";
9762
+ headerEl.style.webkitUserSelect = "none";
9763
+ headerEl.style.touchAction = "none";
9764
+ headerEl.setAttribute("draggable", "false");
9765
+ headerEl.addEventListener("dragstart", (e) => e.preventDefault());
9587
9766
  titleEl = document.createElement("span");
9588
9767
  titleEl.className = "pie-tool-shell__title";
9589
9768
  titleEl.textContent = currentArgs.mounted.entry.shell.title || currentArgs.mounted.toolId;
@@ -9730,20 +9909,100 @@ function ItemToolBar($$anchor, $$props) {
9730
9909
  contentEl.style.width = "100%";
9731
9910
  contentEl.style.flex = "1 1 auto";
9732
9911
  contentEl.style.minHeight = "0";
9912
+ contentEl.style.overflow = "hidden";
9913
+ contentEl.style.borderRadius = "0 0 12px 12px";
9914
+ if (isCalculatorShell) {
9915
+ const makeFocusGuard = (label) => {
9916
+ const el = document.createElement("div");
9917
+ el.tabIndex = 0;
9918
+ el.setAttribute("aria-hidden", "true");
9919
+ el.setAttribute("data-pie-tool-shell-focus-guard", label);
9920
+ el.style.position = "absolute";
9921
+ el.style.width = "1px";
9922
+ el.style.height = "1px";
9923
+ el.style.padding = "0";
9924
+ el.style.margin = "-1px";
9925
+ el.style.overflow = "hidden";
9926
+ el.style.clipPath = "inset(50%)";
9927
+ el.style.whiteSpace = "nowrap";
9928
+ el.style.border = "0";
9929
+ return el;
9930
+ };
9931
+ startFocusGuardEl = makeFocusGuard("start");
9932
+ endFocusGuardEl = makeFocusGuard("end");
9933
+ startFocusGuardEl.addEventListener("focus", (event2) => {
9934
+ if (focusGuardRedirecting)
9935
+ return;
9936
+ focusGuardRedirecting = true;
9937
+ try {
9938
+ event2.stopPropagation();
9939
+ if (openerEl?.isConnected) {
9940
+ try {
9941
+ openerEl.focus();
9942
+ } catch {}
9943
+ }
9944
+ } finally {
9945
+ queueMicrotask(() => {
9946
+ focusGuardRedirecting = false;
9947
+ });
9948
+ }
9949
+ });
9950
+ endFocusGuardEl.addEventListener("focus", (event2) => {
9951
+ if (focusGuardRedirecting)
9952
+ return;
9953
+ focusGuardRedirecting = true;
9954
+ try {
9955
+ event2.stopPropagation();
9956
+ const next2 = findFirstQuestionFocusable();
9957
+ if (next2) {
9958
+ try {
9959
+ next2.focus();
9960
+ } catch {}
9961
+ }
9962
+ } finally {
9963
+ queueMicrotask(() => {
9964
+ focusGuardRedirecting = false;
9965
+ });
9966
+ }
9967
+ });
9968
+ shellEl.appendChild(startFocusGuardEl);
9969
+ }
9733
9970
  shellEl.appendChild(headerEl);
9734
9971
  shellEl.appendChild(contentEl);
9972
+ if (isCalculatorShell && endFocusGuardEl) {
9973
+ shellEl.appendChild(endFocusGuardEl);
9974
+ }
9735
9975
  if (currentArgs.mounted.entry.shell.resizable !== false) {
9736
- resizeHandleEl = document.createElement("div");
9737
- resizeHandleEl.className = "pie-tool-shell__resize";
9738
- resizeHandleEl.style.position = "absolute";
9739
- resizeHandleEl.style.right = "0";
9740
- resizeHandleEl.style.bottom = "0";
9741
- resizeHandleEl.style.width = "24px";
9742
- resizeHandleEl.style.height = "24px";
9743
- resizeHandleEl.style.cursor = "nwse-resize";
9744
- resizeHandleEl.style.background = "linear-gradient(135deg, transparent 0%, transparent 40%, rgba(0,0,0,0.35) 40%, rgba(0,0,0,0.35) 60%, transparent 60%, transparent 100%)";
9745
- shellEl.appendChild(resizeHandleEl);
9746
- resizeHandleEl.addEventListener("pointerdown", onResizePointerDown);
9976
+ const addResizeHandle = (corner, top, right, bottom, left, cursor, gradientAngle) => {
9977
+ const el = document.createElement("div");
9978
+ el.className = "pie-tool-shell__resize";
9979
+ el.style.position = "absolute";
9980
+ el.style.width = "24px";
9981
+ el.style.height = "24px";
9982
+ el.style.cursor = cursor;
9983
+ el.style.zIndex = "10";
9984
+ el.style.touchAction = "none";
9985
+ el.setAttribute("draggable", "false");
9986
+ if (top !== null)
9987
+ el.style.top = top;
9988
+ if (right !== null)
9989
+ el.style.right = right;
9990
+ if (bottom !== null)
9991
+ el.style.bottom = bottom;
9992
+ if (left !== null)
9993
+ el.style.left = left;
9994
+ if (gradientAngle !== null) {
9995
+ el.style.background = `linear-gradient(${gradientAngle}, transparent 0%, transparent 40%, rgba(0,0,0,0.35) 40%, rgba(0,0,0,0.35) 60%, transparent 60%, transparent 100%)`;
9996
+ }
9997
+ const handler = createResizePointerDownHandler(corner);
9998
+ el.addEventListener("pointerdown", handler);
9999
+ shellEl.appendChild(el);
10000
+ resizeHandleEls.push({ el, handler });
10001
+ };
10002
+ addResizeHandle("se", null, "0", "0", null, "nwse-resize", null);
10003
+ addResizeHandle("nw", "0", null, null, "0", "nwse-resize", "135deg");
10004
+ addResizeHandle("ne", "0", "0", null, null, "nesw-resize", null);
10005
+ addResizeHandle("sw", null, null, "0", "0", "nesw-resize", null);
9747
10006
  }
9748
10007
  headerEl.addEventListener("pointerdown", onHeaderPointerDown);
9749
10008
  shellEl.addEventListener("pointermove", onShellPointerMove);
@@ -9784,10 +10043,15 @@ function ItemToolBar($$anchor, $$props) {
9784
10043
  if (focusTrapCleanup) {
9785
10044
  removeFocusTrap();
9786
10045
  }
9787
- openerEl = null;
9788
- if (resizeHandleEl) {
9789
- resizeHandleEl.removeEventListener("pointerdown", onResizePointerDown);
10046
+ if (calculatorBridgeAttached) {
10047
+ document.removeEventListener("keydown", onCalculatorBridgeKeydown, true);
10048
+ calculatorBridgeAttached = false;
10049
+ }
10050
+ for (const { el, handler } of resizeHandleEls) {
10051
+ el.removeEventListener("pointerdown", handler);
9790
10052
  }
10053
+ openerEl = null;
10054
+ resizeHandleEls.length = 0;
9791
10055
  if (headerEl) {
9792
10056
  headerEl.removeEventListener("pointerdown", onHeaderPointerDown);
9793
10057
  headerEl.onkeydown = null;
@@ -9994,9 +10258,9 @@ function ItemToolBar($$anchor, $$props) {
9994
10258
  append($$anchor7, span_4);
9995
10259
  };
9996
10260
  var alternate_1 = ($$anchor7) => {
9997
- var i = root_5();
9998
- template_effect(() => set_class(i, 1, `icon icon-${get2(item2).icon}`, "svelte-rnx3ie"));
9999
- append($$anchor7, i);
10261
+ var i_1 = root_5();
10262
+ template_effect(() => set_class(i_1, 1, `icon icon-${get2(item2).icon}`, "svelte-rnx3ie"));
10263
+ append($$anchor7, i_1);
10000
10264
  };
10001
10265
  if_block(node_8, ($$render) => {
10002
10266
  if (get2(fallbackIcon))
@@ -10086,9 +10350,9 @@ function ItemToolBar($$anchor, $$props) {
10086
10350
  append($$anchor7, span_7);
10087
10351
  };
10088
10352
  var alternate_3 = ($$anchor7) => {
10089
- var i_1 = root_5();
10090
- template_effect(() => set_class(i_1, 1, `icon icon-${get2(item2).icon}`, "svelte-rnx3ie"));
10091
- append($$anchor7, i_1);
10353
+ var i_2 = root_5();
10354
+ template_effect(() => set_class(i_2, 1, `icon icon-${get2(item2).icon}`, "svelte-rnx3ie"));
10355
+ append($$anchor7, i_2);
10092
10356
  };
10093
10357
  if_block(node_11, ($$render) => {
10094
10358
  if (get2(fallbackIcon))
@@ -39,7 +39,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
39
39
 
40
40
  // ../../node_modules/.bun/speech-rule-engine@5.0.0-rc.1/node_modules/speech-rule-engine/lib/sre.js
41
41
  var require_sre = __commonJS((exports, module) => {
42
- var __dirname = "/Users/eelco.hillenius/dev/prj/pie/pie-players/node_modules/.bun/speech-rule-engine@5.0.0-rc.1/node_modules/speech-rule-engine/lib";
42
+ var __dirname = "/home/runner/work/pie-players/pie-players/node_modules/.bun/speech-rule-engine@5.0.0-rc.1/node_modules/speech-rule-engine/lib";
43
43
  (function(t, e) {
44
44
  typeof exports == "object" && typeof module == "object" ? module.exports = e() : typeof define == "function" && define.amd ? define([], e) : typeof exports == "object" ? exports.SRE = e() : t.SRE = e();
45
45
  })(exports, () => (() => {
@@ -18622,10 +18622,12 @@ var calculatorToolRegistration = {
18622
18622
  draggable: true,
18623
18623
  resizable: true,
18624
18624
  closeable: true,
18625
- initialWidth: 720,
18626
- initialHeight: 620,
18627
- minWidth: 360,
18628
- minHeight: 420
18625
+ initialWidth: 380,
18626
+ initialHeight: 420,
18627
+ minWidth: 380,
18628
+ minHeight: 420,
18629
+ initialAlign: "bottom-right",
18630
+ initialMargin: 16
18629
18631
  }
18630
18632
  }
18631
18633
  ],