@mathscan/math-exercise-engine 1.1.15 → 1.1.16

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/dist/index.js CHANGED
@@ -231,6 +231,9 @@ const SIDE_PAD = 7;
231
231
  const CSS_VAR_SIDE_PAD = "--nl-side-pad";
232
232
  const NUMBER_LINE_LABELS = ["all", "extremes", "min-only", "max-only", "none"];
233
233
  const NUMBER_LINE_HIGHLIGHT_COLORS = ["blue", "red", "green", "orange", "purple", "yellow"];
234
+ const HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/;
235
+ const isNumberLineHighlightColor = (value) => NUMBER_LINE_HIGHLIGHT_COLORS.includes(value) || HEX_COLOR_REGEX.test(value);
236
+ const highlightColorMessage = (block) => `${block}: color must be one of ${NUMBER_LINE_HIGHLIGHT_COLORS.join(", ")} or a hex value (e.g. "#3B82F6")`;
234
237
  const NUMBER_LINE_DRAG_MODES = ["axis", "inputs"];
235
238
  function getFractionKey(widgetId, part) {
236
239
  return `${widgetId}__${part}`;
@@ -1601,7 +1604,9 @@ const ImageInlineSchema = zod.z.object({
1601
1604
  }),
1602
1605
  alt: zod.z.string(),
1603
1606
  width: zod.z.number().positive().optional(),
1604
- height: zod.z.number().positive().optional()
1607
+ height: zod.z.number().positive().optional(),
1608
+ /** Opt-in: show an expand control that opens the image fullscreen. */
1609
+ fullscreen: zod.z.boolean().optional()
1605
1610
  });
1606
1611
  const VisualFractionInlineSchema = zod.z.object({
1607
1612
  type: zod.z.literal(AST_TYPES.VISUAL_FRACTION),
@@ -1906,10 +1911,8 @@ const NumberLineHighlightSchema = zod.z.object({
1906
1911
  type: zod.z.literal(AST_TYPES.NUMBER_LINE_HIGHLIGHT),
1907
1912
  from: zod.z.number().finite({ message: "HIGHLIGHT: from must be a finite number" }),
1908
1913
  to: zod.z.number().finite({ message: "HIGHLIGHT: to must be a finite number" }),
1909
- color: zod.z.enum(NUMBER_LINE_HIGHLIGHT_COLORS, {
1910
- errorMap: () => ({
1911
- message: `HIGHLIGHT: color must be one of ${NUMBER_LINE_HIGHLIGHT_COLORS.join(", ")}`
1912
- })
1914
+ color: zod.z.string().refine(isNumberLineHighlightColor, {
1915
+ message: highlightColorMessage("HIGHLIGHT")
1913
1916
  }).optional(),
1914
1917
  label: zod.z.string().optional()
1915
1918
  }).refine((d) => d.from < d.to, {
@@ -1928,7 +1931,7 @@ const NumberLineCursorSchema = zod.z.object({
1928
1931
  type: zod.z.literal(AST_TYPES.NUMBER_LINE_CURSOR),
1929
1932
  value: zod.z.number().finite({ message: "CURSOR: value must be a finite number" }).default(0),
1930
1933
  answer: zod.z.number({ required_error: "CURSOR: answer is required" }).finite({ message: "CURSOR: answer must be a finite number" }),
1931
- color: zod.z.string().regex(/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/, {
1934
+ color: zod.z.string().regex(HEX_COLOR_REGEX, {
1932
1935
  message: 'CURSOR: color must be a hex value (e.g. "#3B82F6" or "#F00")'
1933
1936
  }).optional(),
1934
1937
  fillRange: zod.z.boolean().default(false),
@@ -1950,8 +1953,8 @@ const NumberLineArrowSchema = zod.z.object({
1950
1953
  to: zod.z.number().finite({ message: "ARROW: to must be a finite number" }),
1951
1954
  color: zod.z.string().optional(),
1952
1955
  inlines: zod.z.array(InlineNodeSchema)
1953
- }).refine((d) => d.from < d.to, {
1954
- message: "ARROW: from must be less than to"
1956
+ }).refine((d) => d.from !== d.to, {
1957
+ message: "ARROW: from and to must be different"
1955
1958
  });
1956
1959
  function createNumberLineArrow(from, to, inlines, color) {
1957
1960
  return NumberLineArrowSchema.parse({
@@ -2016,7 +2019,9 @@ const NumberLineBlockSchema = zod.z.object({
2016
2019
  }
2017
2020
  }
2018
2021
  for (const arrow of data.arrows ?? []) {
2019
- if (arrow.from < data.min || arrow.to > data.max) {
2022
+ const lo = Math.min(arrow.from, arrow.to);
2023
+ const hi = Math.max(arrow.from, arrow.to);
2024
+ if (lo < data.min || hi > data.max) {
2020
2025
  ctx.addIssue({
2021
2026
  code: zod.z.ZodIssueCode.custom,
2022
2027
  message: `NUMBER_LINE: ARROW range [${arrow.from}, ${arrow.to}] must be within [${data.min}, ${data.max}]`
@@ -3108,7 +3113,8 @@ class NaturalDSLVisitor extends BaseCstVisitor {
3108
3113
  const alt = params.alt;
3109
3114
  const width = params.width;
3110
3115
  const height = params.height;
3111
- return createImage(name, src, alt, { width, height });
3116
+ const fullscreen = params.fullscreen !== void 0 ? params.fullscreen === true || params.fullscreen === "true" : void 0;
3117
+ return createImage(name, src, alt, { width, height, fullscreen });
3112
3118
  }
3113
3119
  visualFraction(ctx) {
3114
3120
  const params = this.visit(ctx.parameterList);
@@ -3330,7 +3336,9 @@ const ImageItemSchema = zod.z.object({
3330
3336
  }),
3331
3337
  alt: zod.z.string(),
3332
3338
  width: zod.z.number().positive().optional(),
3333
- height: zod.z.number().positive().optional()
3339
+ height: zod.z.number().positive().optional(),
3340
+ /** Opt-in: show an expand control that opens the image fullscreen. */
3341
+ fullscreen: zod.z.boolean().optional()
3334
3342
  });
3335
3343
  const SpaceItemSchema = zod.z.object({
3336
3344
  id: zod.z.string(),
@@ -3435,7 +3443,9 @@ const NumberLineHighlightItemSchema = zod.z.object({
3435
3443
  type: zod.z.literal(JSON_TYPES.NUMBER_LINE_HIGHLIGHT),
3436
3444
  from: zod.z.number().finite(),
3437
3445
  to: zod.z.number().finite(),
3438
- color: zod.z.enum(NUMBER_LINE_HIGHLIGHT_COLORS).optional(),
3446
+ color: zod.z.string().refine(isNumberLineHighlightColor, {
3447
+ message: highlightColorMessage("HIGHLIGHT")
3448
+ }).optional(),
3439
3449
  label: zod.z.string().optional()
3440
3450
  });
3441
3451
  const NumberLineCursorItemSchema = zod.z.object({
@@ -3443,7 +3453,7 @@ const NumberLineCursorItemSchema = zod.z.object({
3443
3453
  type: zod.z.literal(JSON_TYPES.NUMBER_LINE_CURSOR),
3444
3454
  value: zod.z.number().finite(),
3445
3455
  answer: zod.z.number().finite(),
3446
- color: zod.z.string().regex(/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/).optional(),
3456
+ color: zod.z.string().regex(HEX_COLOR_REGEX).optional(),
3447
3457
  fillRange: zod.z.boolean(),
3448
3458
  label: zod.z.string().optional()
3449
3459
  });
@@ -9789,7 +9799,8 @@ function transformInline(inline, idGenerator, inlineDragIds) {
9789
9799
  src: inline.src,
9790
9800
  alt: inline.alt,
9791
9801
  ...inline.width !== void 0 && { width: inline.width },
9792
- ...inline.height !== void 0 && { height: inline.height }
9802
+ ...inline.height !== void 0 && { height: inline.height },
9803
+ ...inline.fullscreen !== void 0 && { fullscreen: inline.fullscreen }
9793
9804
  };
9794
9805
  case AST_TYPES.VISUAL_FRACTION:
9795
9806
  return {
@@ -16659,6 +16670,226 @@ const WidgetRenderer = ({
16659
16670
  }
16660
16671
  return null;
16661
16672
  };
16673
+ const ExpandDiamondIcon = () => {
16674
+ const gradientId = React.useId();
16675
+ return /* @__PURE__ */ jsxRuntime.jsxs(
16676
+ "svg",
16677
+ {
16678
+ className: "image-zoom-icon",
16679
+ viewBox: "0 0 60 60",
16680
+ fill: "none",
16681
+ xmlns: "http://www.w3.org/2000/svg",
16682
+ "aria-hidden": "true",
16683
+ focusable: "false",
16684
+ children: [
16685
+ /* @__PURE__ */ jsxRuntime.jsx(
16686
+ "rect",
16687
+ {
16688
+ y: "-1.41531",
16689
+ width: "31.6754",
16690
+ height: "31.6754",
16691
+ rx: "7",
16692
+ transform: "matrix(0.706556 0.707657 -0.706556 0.707657 29.4526 10.0862)",
16693
+ fill: "white"
16694
+ }
16695
+ ),
16696
+ /* @__PURE__ */ jsxRuntime.jsx(
16697
+ "rect",
16698
+ {
16699
+ y: "-1.41531",
16700
+ width: "31.6754",
16701
+ height: "31.6754",
16702
+ rx: "7",
16703
+ transform: "matrix(0.706556 0.707657 -0.706556 0.707657 29.4526 10.0862)",
16704
+ stroke: "#BDAFFE",
16705
+ strokeWidth: "2"
16706
+ }
16707
+ ),
16708
+ /* @__PURE__ */ jsxRuntime.jsx(
16709
+ "rect",
16710
+ {
16711
+ y: "-1.41531",
16712
+ width: "31.6754",
16713
+ height: "31.6754",
16714
+ rx: "7",
16715
+ transform: "matrix(0.706556 0.707657 -0.706556 0.707657 29.4526 10.0862)",
16716
+ stroke: `url(#${gradientId})`,
16717
+ strokeOpacity: "0.3",
16718
+ strokeWidth: "2"
16719
+ }
16720
+ ),
16721
+ /* @__PURE__ */ jsxRuntime.jsxs(
16722
+ "g",
16723
+ {
16724
+ stroke: "currentColor",
16725
+ strokeWidth: "2.5",
16726
+ strokeLinecap: "round",
16727
+ strokeLinejoin: "round",
16728
+ children: [
16729
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M22.45 27 L22.45 23.5 L25.95 23.5" }),
16730
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M34.95 23.5 L38.45 23.5 L38.45 27" }),
16731
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M38.45 36 L38.45 39.5 L34.95 39.5" }),
16732
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M25.95 39.5 L22.45 39.5 L22.45 36" })
16733
+ ]
16734
+ }
16735
+ ),
16736
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
16737
+ "linearGradient",
16738
+ {
16739
+ id: gradientId,
16740
+ x1: "3.84406",
16741
+ y1: "3.97407",
16742
+ x2: "24.7079",
16743
+ y2: "24.8379",
16744
+ gradientUnits: "userSpaceOnUse",
16745
+ children: [
16746
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#FAFAFA" }),
16747
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "1", stopColor: "#8A4899" })
16748
+ ]
16749
+ }
16750
+ ) })
16751
+ ]
16752
+ }
16753
+ );
16754
+ };
16755
+ const CloseIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
16756
+ "svg",
16757
+ {
16758
+ className: "image-lightbox-close-icon",
16759
+ viewBox: "0 0 24 24",
16760
+ fill: "none",
16761
+ xmlns: "http://www.w3.org/2000/svg",
16762
+ "aria-hidden": "true",
16763
+ focusable: "false",
16764
+ children: [
16765
+ /* @__PURE__ */ jsxRuntime.jsx(
16766
+ "path",
16767
+ {
16768
+ d: "M18 6L6 18",
16769
+ stroke: "currentColor",
16770
+ strokeWidth: "2",
16771
+ strokeLinecap: "round",
16772
+ strokeLinejoin: "round"
16773
+ }
16774
+ ),
16775
+ /* @__PURE__ */ jsxRuntime.jsx(
16776
+ "path",
16777
+ {
16778
+ d: "M6 6L18 18",
16779
+ stroke: "currentColor",
16780
+ strokeWidth: "2",
16781
+ strokeLinecap: "round",
16782
+ strokeLinejoin: "round"
16783
+ }
16784
+ )
16785
+ ]
16786
+ }
16787
+ );
16788
+ const ImageItem = ({
16789
+ src,
16790
+ alt,
16791
+ width,
16792
+ height,
16793
+ fullscreen = false
16794
+ }) => {
16795
+ const [isOpen, setIsOpen] = React.useState(false);
16796
+ const triggerRef = React.useRef(null);
16797
+ const closeRef = React.useRef(null);
16798
+ const open = React.useCallback(() => setIsOpen(true), []);
16799
+ const close = React.useCallback(() => setIsOpen(false), []);
16800
+ const isLightboxOpen = isOpen && fullscreen;
16801
+ React.useEffect(() => {
16802
+ if (!isLightboxOpen) return;
16803
+ const onKeyDown = (e) => {
16804
+ if (e.key === "Escape") {
16805
+ e.stopPropagation();
16806
+ close();
16807
+ }
16808
+ };
16809
+ document.addEventListener("keydown", onKeyDown);
16810
+ return () => document.removeEventListener("keydown", onKeyDown);
16811
+ }, [isLightboxOpen, close]);
16812
+ React.useEffect(() => {
16813
+ if (!isLightboxOpen) return;
16814
+ const previous = document.body.style.overflow;
16815
+ document.body.style.overflow = "hidden";
16816
+ return () => {
16817
+ document.body.style.overflow = previous;
16818
+ };
16819
+ }, [isLightboxOpen]);
16820
+ const wasOpen = React.useRef(false);
16821
+ React.useEffect(() => {
16822
+ if (isLightboxOpen) {
16823
+ closeRef.current?.focus();
16824
+ } else if (wasOpen.current) {
16825
+ triggerRef.current?.focus({ preventScroll: true });
16826
+ }
16827
+ wasOpen.current = isLightboxOpen;
16828
+ }, [isLightboxOpen]);
16829
+ const overlay = isLightboxOpen && typeof document !== "undefined" ? reactDom.createPortal(
16830
+ /* @__PURE__ */ jsxRuntime.jsxs(
16831
+ "div",
16832
+ {
16833
+ className: "image-lightbox",
16834
+ role: "dialog",
16835
+ "aria-modal": "true",
16836
+ "aria-label": alt || "Image",
16837
+ onClick: close,
16838
+ children: [
16839
+ /* @__PURE__ */ jsxRuntime.jsx(
16840
+ "button",
16841
+ {
16842
+ ref: closeRef,
16843
+ type: "button",
16844
+ className: "image-lightbox-close",
16845
+ "aria-label": "Close fullscreen image",
16846
+ onClick: close,
16847
+ children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
16848
+ }
16849
+ ),
16850
+ /* @__PURE__ */ jsxRuntime.jsx(
16851
+ "img",
16852
+ {
16853
+ className: "image-lightbox-img",
16854
+ src,
16855
+ alt,
16856
+ onClick: (e) => e.stopPropagation()
16857
+ }
16858
+ )
16859
+ ]
16860
+ }
16861
+ ),
16862
+ document.body
16863
+ ) : null;
16864
+ const img = /* @__PURE__ */ jsxRuntime.jsx(
16865
+ "img",
16866
+ {
16867
+ className: `image-item text-item ${fullscreen ? "image-item-zoomable" : ""}`,
16868
+ src,
16869
+ alt,
16870
+ ...width !== void 0 && { width },
16871
+ ...height !== void 0 && { height },
16872
+ loading: "lazy",
16873
+ ...fullscreen && { onClick: open }
16874
+ }
16875
+ );
16876
+ if (!fullscreen) return img;
16877
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "image-item-wrapper", children: [
16878
+ img,
16879
+ /* @__PURE__ */ jsxRuntime.jsx(
16880
+ "button",
16881
+ {
16882
+ ref: triggerRef,
16883
+ type: "button",
16884
+ className: "image-zoom-btn",
16885
+ "aria-label": alt ? `View "${alt}" fullscreen` : "View image fullscreen",
16886
+ onClick: open,
16887
+ children: /* @__PURE__ */ jsxRuntime.jsx(ExpandDiamondIcon, {})
16888
+ }
16889
+ ),
16890
+ overlay
16891
+ ] });
16892
+ };
16662
16893
  const EPSILON = 10 ** -INTERNAL_PRECISION;
16663
16894
  const cleanFloat = (n) => parseFloat(n.toFixed(INTERNAL_PRECISION));
16664
16895
  const roundTick = (n) => parseFloat(n.toFixed(DISPLAY_PRECISION));
@@ -16712,7 +16943,7 @@ const getPositionWidgetId = (content) => {
16712
16943
  }
16713
16944
  return null;
16714
16945
  };
16715
- const toHighlightColor = (color) => `var(--nl-highlight-${color})`;
16946
+ const toHighlightColor = (color) => color.startsWith("#") ? color : `var(--nl-highlight-${color})`;
16716
16947
  const getBandGeometry = (h, min, max) => {
16717
16948
  const leftPct = toPercent(Math.min(h.from, h.to), min, max);
16718
16949
  const rightPct = toPercent(Math.max(h.from, h.to), min, max);
@@ -17409,24 +17640,27 @@ function getArrowArcLabelTop(widthPct) {
17409
17640
  const arcTop = svgTop + ARROW_ARC_BASE_Y - getArrowArcLift(widthPct);
17410
17641
  return Math.max(0, arcTop - ARROW_ARC_LABEL_OFFSET);
17411
17642
  }
17412
- function getArrowArcPaths(widthPct, svgWidthPx = ARROW_ARC_VIEWBOX_WIDTH) {
17413
- const endX = getArrowArcSvgWidth(svgWidthPx);
17643
+ function getArrowArcPaths(widthPct, svgWidthPx = ARROW_ARC_VIEWBOX_WIDTH, reversed = false) {
17644
+ const width = getArrowArcSvgWidth(svgWidthPx);
17645
+ const startX = reversed ? width : 0;
17646
+ const tipX = reversed ? 0 : width;
17647
+ const sign = reversed ? -1 : 1;
17414
17648
  const controlInset = Math.min(svgWidthPx * 0.18, 48);
17415
17649
  const lift = getArrowArcLift(widthPct);
17416
17650
  const controlY = fmt(ARROW_ARC_BASE_Y - lift);
17417
- const tangentAngle = Math.atan2(ARROW_ARC_BASE_Y - controlY, endX - (endX - controlInset));
17418
- const tx = Math.cos(tangentAngle);
17651
+ const tangentAngle = Math.atan2(ARROW_ARC_BASE_Y - controlY, controlInset);
17652
+ const tx = Math.cos(tangentAngle) * sign;
17419
17653
  const ty = Math.sin(tangentAngle);
17420
- const shaftEndX = fmt(endX - tx * ARROW_ARC_HEAD_LENGTH);
17654
+ const shaftEndX = fmt(tipX - tx * ARROW_ARC_HEAD_LENGTH);
17421
17655
  const shaftEndY = fmt(ARROW_ARC_BASE_Y - ty * ARROW_ARC_HEAD_LENGTH);
17422
17656
  const endControlX = fmt(shaftEndX - tx * controlInset);
17423
17657
  const endControlY = fmt(shaftEndY - ty * controlInset);
17424
- const arcPath = `M 0 ${ARROW_ARC_BASE_Y} C ${fmt(controlInset)} ${controlY} ${endControlX} ${endControlY} ${shaftEndX} ${shaftEndY}`;
17658
+ const arcPath = `M ${fmt(startX)} ${ARROW_ARC_BASE_Y} C ${fmt(startX + sign * controlInset)} ${controlY} ${endControlX} ${endControlY} ${shaftEndX} ${shaftEndY}`;
17425
17659
  const nx = -ty;
17426
17660
  const ny = tx;
17427
- const baseX = endX - tx * ARROW_ARC_HEAD_LENGTH;
17661
+ const baseX = tipX - tx * ARROW_ARC_HEAD_LENGTH;
17428
17662
  const baseY = ARROW_ARC_BASE_Y - ty * ARROW_ARC_HEAD_LENGTH;
17429
- const headPath = `M ${fmt(endX)} ${ARROW_ARC_BASE_Y} L ${fmt(baseX + nx * ARROW_ARC_HEAD_HALF_WIDTH)} ${fmt(baseY + ny * ARROW_ARC_HEAD_HALF_WIDTH)} L ${fmt(baseX - nx * ARROW_ARC_HEAD_HALF_WIDTH)} ${fmt(baseY - ny * ARROW_ARC_HEAD_HALF_WIDTH)} Z`;
17663
+ const headPath = `M ${fmt(tipX)} ${ARROW_ARC_BASE_Y} L ${fmt(baseX + nx * ARROW_ARC_HEAD_HALF_WIDTH)} ${fmt(baseY + ny * ARROW_ARC_HEAD_HALF_WIDTH)} L ${fmt(baseX - nx * ARROW_ARC_HEAD_HALF_WIDTH)} ${fmt(baseY - ny * ARROW_ARC_HEAD_HALF_WIDTH)} Z`;
17430
17664
  return { arcPath, headPath };
17431
17665
  }
17432
17666
  function getArrowArcLayouts(arrows, min, max) {
@@ -17437,9 +17671,10 @@ function getArrowArcLayouts(arrows, min, max) {
17437
17671
  return {
17438
17672
  arrow,
17439
17673
  index,
17440
- leftPct: fromPct,
17441
- rightPct: toPct,
17442
- widthPct: toPct - fromPct,
17674
+ leftPct: Math.min(fromPct, toPct),
17675
+ rightPct: Math.max(fromPct, toPct),
17676
+ widthPct: Math.abs(toPct - fromPct),
17677
+ reversed: toPct < fromPct,
17443
17678
  level: 0
17444
17679
  };
17445
17680
  }).filter((layout) => layout.widthPct > 0).sort((a, b) => a.leftPct - b.leftPct || a.rightPct - b.rightPct || a.index - b.index);
@@ -17476,7 +17711,7 @@ function useElementWidth() {
17476
17711
  return [ref, width];
17477
17712
  }
17478
17713
  const ArrowArc = ({
17479
- layout: { arrow, leftPct, widthPct, level },
17714
+ layout: { arrow, leftPct, widthPct, reversed, level },
17480
17715
  widgets,
17481
17716
  values,
17482
17717
  droppedInputs,
@@ -17488,8 +17723,8 @@ const ArrowArc = ({
17488
17723
  const hasLabel = arrow.content.length > 0;
17489
17724
  const svgWidthPx = getArrowArcSvgWidth(renderedWidthPx);
17490
17725
  const { arcPath, headPath } = React.useMemo(
17491
- () => getArrowArcPaths(widthPct, svgWidthPx),
17492
- [widthPct, svgWidthPx]
17726
+ () => getArrowArcPaths(widthPct, svgWidthPx, reversed),
17727
+ [widthPct, svgWidthPx, reversed]
17493
17728
  );
17494
17729
  return /* @__PURE__ */ jsxRuntime.jsxs(
17495
17730
  "div",
@@ -18245,14 +18480,13 @@ const LayoutRenderer = ({
18245
18480
  }
18246
18481
  case JSON_TYPES.IMAGE:
18247
18482
  return /* @__PURE__ */ jsxRuntime.jsx(
18248
- "img",
18483
+ ImageItem,
18249
18484
  {
18250
- className: "image-item text-item",
18251
18485
  src: item.src,
18252
18486
  alt: item.alt,
18253
- ...item.width !== void 0 && { width: item.width },
18254
- ...item.height !== void 0 && { height: item.height },
18255
- loading: "lazy"
18487
+ width: item.width,
18488
+ height: item.height,
18489
+ fullscreen: item.fullscreen
18256
18490
  }
18257
18491
  );
18258
18492
  case JSON_TYPES.WIDGET_REF: {