@flamingo-stack/openframe-frontend-core 0.0.687 → 0.0.688

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 (125) hide show
  1. package/dist/{chunk-V5REIMSE.js → chunk-2V4KPBNZ.js} +3 -3
  2. package/dist/{chunk-S6SGPLA4.js → chunk-3LBEUJUI.js} +3 -3
  3. package/dist/{chunk-JSXNOXZQ.js → chunk-3SJOXM6Y.js} +4 -4
  4. package/dist/{chunk-3IANMZFS.js → chunk-45HXQ7RV.js} +5 -5
  5. package/dist/{chunk-SR2C5SJJ.js → chunk-4BUPMSLY.js} +3 -3
  6. package/dist/{chunk-DGOUPZJ7.js → chunk-5BZ2FB5K.js} +3 -3
  7. package/dist/{chunk-YNL2NHXH.cjs → chunk-6TNOVWO3.cjs} +5 -5
  8. package/dist/{chunk-YNL2NHXH.cjs.map → chunk-6TNOVWO3.cjs.map} +1 -1
  9. package/dist/{chunk-SQQQVVV2.js → chunk-7XNS6U7B.js} +4 -4
  10. package/dist/{chunk-XF5TJ4P2.cjs → chunk-BJHM2OEY.cjs} +15 -15
  11. package/dist/{chunk-XF5TJ4P2.cjs.map → chunk-BJHM2OEY.cjs.map} +1 -1
  12. package/dist/{chunk-CKQ4ZBDN.cjs → chunk-BN6JXZMA.cjs} +10 -10
  13. package/dist/{chunk-CKQ4ZBDN.cjs.map → chunk-BN6JXZMA.cjs.map} +1 -1
  14. package/dist/{chunk-4THS6V3I.cjs → chunk-CGMBVDEV.cjs} +5 -5
  15. package/dist/{chunk-4THS6V3I.cjs.map → chunk-CGMBVDEV.cjs.map} +1 -1
  16. package/dist/{chunk-RVO77GSL.cjs → chunk-EAYMYMLX.cjs} +12 -12
  17. package/dist/{chunk-RVO77GSL.cjs.map → chunk-EAYMYMLX.cjs.map} +1 -1
  18. package/dist/{chunk-QRZ5LS6A.cjs → chunk-FIZJA2MC.cjs} +22 -22
  19. package/dist/{chunk-QRZ5LS6A.cjs.map → chunk-FIZJA2MC.cjs.map} +1 -1
  20. package/dist/{chunk-RHBFZC6F.cjs → chunk-G3MH262S.cjs} +26 -26
  21. package/dist/{chunk-RHBFZC6F.cjs.map → chunk-G3MH262S.cjs.map} +1 -1
  22. package/dist/{chunk-3ADAUFKK.cjs → chunk-G7PNBP6I.cjs} +26 -26
  23. package/dist/{chunk-3ADAUFKK.cjs.map → chunk-G7PNBP6I.cjs.map} +1 -1
  24. package/dist/{chunk-HHNKNOZU.cjs → chunk-GQTWZL2M.cjs} +5 -5
  25. package/dist/{chunk-HHNKNOZU.cjs.map → chunk-GQTWZL2M.cjs.map} +1 -1
  26. package/dist/{chunk-WIUDKYAQ.cjs → chunk-JJLJH4FH.cjs} +80 -80
  27. package/dist/{chunk-WIUDKYAQ.cjs.map → chunk-JJLJH4FH.cjs.map} +1 -1
  28. package/dist/{chunk-APLL2BVR.js → chunk-JMD52673.js} +2 -2
  29. package/dist/{chunk-JNUL3ZWK.js → chunk-JUNOY5HK.js} +6 -6
  30. package/dist/chunk-JUNOY5HK.js.map +1 -0
  31. package/dist/{chunk-R4MKXLRJ.js → chunk-MC5JRMRE.js} +8 -8
  32. package/dist/{chunk-WMOELYDL.cjs → chunk-MCHGTS3E.cjs} +19 -19
  33. package/dist/{chunk-WMOELYDL.cjs.map → chunk-MCHGTS3E.cjs.map} +1 -1
  34. package/dist/{chunk-CDCUUEL4.cjs → chunk-MNKP6VGT.cjs} +13 -13
  35. package/dist/{chunk-CDCUUEL4.cjs.map → chunk-MNKP6VGT.cjs.map} +1 -1
  36. package/dist/{chunk-4GQ7VWAR.js → chunk-NOA7SLDH.js} +7 -7
  37. package/dist/{chunk-ENIABTA5.js → chunk-O2XJYMZD.js} +6 -6
  38. package/dist/{chunk-3RNG4MJN.cjs → chunk-O5AHLF4Z.cjs} +43 -43
  39. package/dist/{chunk-3RNG4MJN.cjs.map → chunk-O5AHLF4Z.cjs.map} +1 -1
  40. package/dist/{chunk-LL35WZZS.cjs → chunk-OD2WMUAO.cjs} +225 -225
  41. package/dist/{chunk-LL35WZZS.cjs.map → chunk-OD2WMUAO.cjs.map} +1 -1
  42. package/dist/{chunk-BZKDFMZM.cjs → chunk-OZKJZUPF.cjs} +50 -50
  43. package/dist/{chunk-BZKDFMZM.cjs.map → chunk-OZKJZUPF.cjs.map} +1 -1
  44. package/dist/{chunk-UZEW5Z7R.js → chunk-PBDSPANS.js} +5 -5
  45. package/dist/chunk-PBDSPANS.js.map +1 -0
  46. package/dist/{chunk-IJUQQTMV.cjs → chunk-QRA2JXE4.cjs} +9 -9
  47. package/dist/chunk-QRA2JXE4.cjs.map +1 -0
  48. package/dist/{chunk-GXKAWMDT.js → chunk-R4V6AU6R.js} +4 -4
  49. package/dist/{chunk-IR6PWTCL.js → chunk-R7GU5YSO.js} +7 -7
  50. package/dist/{chunk-T32BTPL5.cjs → chunk-SWOS3DDM.cjs} +554 -554
  51. package/dist/{chunk-T32BTPL5.cjs.map → chunk-SWOS3DDM.cjs.map} +1 -1
  52. package/dist/{chunk-SFY2E5DG.js → chunk-T2MHRQZR.js} +6 -6
  53. package/dist/{chunk-DYNWIHFU.cjs → chunk-TOJYEOYP.cjs} +50 -50
  54. package/dist/{chunk-DYNWIHFU.cjs.map → chunk-TOJYEOYP.cjs.map} +1 -1
  55. package/dist/{chunk-A2ZP6WX4.js → chunk-VB4MZWNO.js} +6 -6
  56. package/dist/{chunk-W4CHRA6G.js → chunk-X2DAEWTQ.js} +2 -2
  57. package/dist/{chunk-XEESEFGT.cjs → chunk-XNJRUSBZ.cjs} +3 -3
  58. package/dist/{chunk-XEESEFGT.cjs.map → chunk-XNJRUSBZ.cjs.map} +1 -1
  59. package/dist/{chunk-LROQXUFX.js → chunk-ZHTZ4ALC.js} +5 -5
  60. package/dist/components/case-studies/index.cjs +18 -18
  61. package/dist/components/case-studies/index.js +6 -6
  62. package/dist/components/chat/index.cjs +4 -4
  63. package/dist/components/chat/index.js +3 -3
  64. package/dist/components/contact/index.cjs +7 -7
  65. package/dist/components/contact/index.js +6 -6
  66. package/dist/components/docs/index.cjs +10 -10
  67. package/dist/components/docs/index.js +9 -9
  68. package/dist/components/embeds/index.cjs +7 -7
  69. package/dist/components/embeds/index.js +6 -6
  70. package/dist/components/faq/index.cjs +7 -7
  71. package/dist/components/faq/index.js +6 -6
  72. package/dist/components/features/index.cjs +6 -6
  73. package/dist/components/features/index.js +5 -5
  74. package/dist/components/help-center-pages/index.cjs +90 -90
  75. package/dist/components/help-center-pages/index.js +17 -17
  76. package/dist/components/icons-v2-generated/brand-logos/google-logo-grey-icon.d.ts +8 -0
  77. package/dist/components/icons-v2-generated/brand-logos/google-logo-grey-icon.d.ts.map +1 -0
  78. package/dist/components/icons-v2-generated/brand-logos/index.d.ts +1 -1
  79. package/dist/components/icons-v2-generated/brand-logos/index.d.ts.map +1 -1
  80. package/dist/components/icons-v2-generated/index.cjs +2 -2
  81. package/dist/components/icons-v2-generated/index.cjs.map +1 -1
  82. package/dist/components/icons-v2-generated/index.js +3 -3
  83. package/dist/components/index.cjs +47 -47
  84. package/dist/components/index.js +16 -16
  85. package/dist/components/meeting-scheduler/index.cjs +33 -33
  86. package/dist/components/meeting-scheduler/index.js +5 -5
  87. package/dist/components/navigation/index.cjs +9 -9
  88. package/dist/components/navigation/index.js +8 -8
  89. package/dist/components/onboarding-guides/index.cjs +9 -9
  90. package/dist/components/onboarding-guides/index.js +8 -8
  91. package/dist/components/tickets/index.cjs +10 -10
  92. package/dist/components/tickets/index.js +9 -9
  93. package/dist/components/ui/index.cjs +6 -6
  94. package/dist/components/ui/index.js +5 -5
  95. package/dist/hooks/index.cjs +4 -4
  96. package/dist/hooks/index.js +3 -3
  97. package/dist/index.cjs +11 -11
  98. package/dist/index.js +9 -9
  99. package/package.json +1 -1
  100. package/src/components/icons-v2-generated/brand-logos/{google-logo-1-icon.tsx → google-logo-grey-icon.tsx} +6 -4
  101. package/src/components/icons-v2-generated/brand-logos/index.ts +1 -1
  102. package/src/components/tool-icon.tsx +4 -4
  103. package/dist/chunk-IJUQQTMV.cjs.map +0 -1
  104. package/dist/chunk-JNUL3ZWK.js.map +0 -1
  105. package/dist/chunk-UZEW5Z7R.js.map +0 -1
  106. package/dist/components/icons-v2-generated/brand-logos/google-logo-1-icon.d.ts +0 -8
  107. package/dist/components/icons-v2-generated/brand-logos/google-logo-1-icon.d.ts.map +0 -1
  108. /package/dist/{chunk-V5REIMSE.js.map → chunk-2V4KPBNZ.js.map} +0 -0
  109. /package/dist/{chunk-S6SGPLA4.js.map → chunk-3LBEUJUI.js.map} +0 -0
  110. /package/dist/{chunk-JSXNOXZQ.js.map → chunk-3SJOXM6Y.js.map} +0 -0
  111. /package/dist/{chunk-3IANMZFS.js.map → chunk-45HXQ7RV.js.map} +0 -0
  112. /package/dist/{chunk-SR2C5SJJ.js.map → chunk-4BUPMSLY.js.map} +0 -0
  113. /package/dist/{chunk-DGOUPZJ7.js.map → chunk-5BZ2FB5K.js.map} +0 -0
  114. /package/dist/{chunk-SQQQVVV2.js.map → chunk-7XNS6U7B.js.map} +0 -0
  115. /package/dist/{chunk-APLL2BVR.js.map → chunk-JMD52673.js.map} +0 -0
  116. /package/dist/{chunk-R4MKXLRJ.js.map → chunk-MC5JRMRE.js.map} +0 -0
  117. /package/dist/{chunk-4GQ7VWAR.js.map → chunk-NOA7SLDH.js.map} +0 -0
  118. /package/dist/{chunk-ENIABTA5.js.map → chunk-O2XJYMZD.js.map} +0 -0
  119. /package/dist/{chunk-GXKAWMDT.js.map → chunk-R4V6AU6R.js.map} +0 -0
  120. /package/dist/{chunk-IR6PWTCL.js.map → chunk-R7GU5YSO.js.map} +0 -0
  121. /package/dist/{chunk-SFY2E5DG.js.map → chunk-T2MHRQZR.js.map} +0 -0
  122. /package/dist/{chunk-A2ZP6WX4.js.map → chunk-VB4MZWNO.js.map} +0 -0
  123. /package/dist/{chunk-W4CHRA6G.js.map → chunk-X2DAEWTQ.js.map} +0 -0
  124. /package/dist/{chunk-LROQXUFX.js.map → chunk-ZHTZ4ALC.js.map} +0 -0
  125. /package/src/components/icons-v2/brand-logos/{google-logo-1.svg → google-logo-grey.svg} +0 -0
@@ -4,17 +4,17 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkT32BTPL5cjs = require('./chunk-T32BTPL5.cjs');
7
+ var _chunkSWOS3DDMcjs = require('./chunk-SWOS3DDM.cjs');
8
8
 
9
9
 
10
- var _chunkXF5TJ4P2cjs = require('./chunk-XF5TJ4P2.cjs');
10
+ var _chunkBJHM2OEYcjs = require('./chunk-BJHM2OEY.cjs');
11
11
 
12
12
 
13
- var _chunkLL35WZZScjs = require('./chunk-LL35WZZS.cjs');
13
+ var _chunkOD2WMUAOcjs = require('./chunk-OD2WMUAO.cjs');
14
14
 
15
15
 
16
16
 
17
- var _chunkIJUQQTMVcjs = require('./chunk-IJUQQTMV.cjs');
17
+ var _chunkQRA2JXE4cjs = require('./chunk-QRA2JXE4.cjs');
18
18
 
19
19
 
20
20
 
@@ -32,7 +32,7 @@ var _chunk5R4QMTMLcjs = require('./chunk-5R4QMTML.cjs');
32
32
 
33
33
 
34
34
 
35
- var _chunkYNL2NHXHcjs = require('./chunk-YNL2NHXH.cjs');
35
+ var _chunk6TNOVWO3cjs = require('./chunk-6TNOVWO3.cjs');
36
36
 
37
37
 
38
38
 
@@ -89,7 +89,7 @@ var sourceConfig = {
89
89
  };
90
90
  var SoftwareSourceBadge = ({ source, className }) => {
91
91
  const config = sourceConfig[source] || { label: source, icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk5R4QMTMLcjs.PackageIcon, { className: "h-4 w-4" }) };
92
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunkIJUQQTMVcjs.cn.call(void 0, "inline-flex items-center gap-2 text-ods-text-primary", className), children: [
92
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: _chunkQRA2JXE4cjs.cn.call(void 0, "inline-flex items-center gap-2 text-ods-text-primary", className), children: [
93
93
  config.icon,
94
94
  config.label
95
95
  ] });
@@ -122,9 +122,9 @@ CveLink.displayName = "CveLink";
122
122
  // src/components/platform/ToolBadge.tsx
123
123
 
124
124
  var ToolBadge = ({ toolType, className, iconClassName }) => {
125
- const label = _chunkT32BTPL5cjs.getToolLabel.call(void 0, toolType);
125
+ const label = _chunkSWOS3DDMcjs.getToolLabel.call(void 0, toolType);
126
126
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkX7CEWD6Vcjs.cn.call(void 0, "flex items-center gap-1 text-ods-text-secondary", className), children: [
127
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIJUQQTMVcjs.ToolIcon, { toolType, className: iconClassName, size: 16 }),
127
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQRA2JXE4cjs.ToolIcon, { toolType, className: iconClassName, size: 16 }),
128
128
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-ods-text-primary text-h4", children: label })
129
129
  ] });
130
130
  };
@@ -133,31 +133,31 @@ ToolBadge.displayName = "ToolBadge";
133
133
  // src/components/platform/ShellTypeBadge.tsx
134
134
 
135
135
  var shellIconMap = {
136
- [_chunkT32BTPL5cjs.ShellTypeValues.POWERSHELL]: {
137
- icon: _chunkYNL2NHXHcjs.PowershellLogoGreyIcon,
136
+ [_chunkSWOS3DDMcjs.ShellTypeValues.POWERSHELL]: {
137
+ icon: _chunk6TNOVWO3cjs.PowershellLogoGreyIcon,
138
138
  props: { size: 16, className: "text-ods-text-secondary" }
139
139
  },
140
- [_chunkT32BTPL5cjs.ShellTypeValues.CMD]: {
140
+ [_chunkSWOS3DDMcjs.ShellTypeValues.CMD]: {
141
141
  icon: _chunk5R4QMTMLcjs.CmdIcon,
142
142
  props: { size: 16, color: "var(--color-text-secondary)" }
143
143
  },
144
- [_chunkT32BTPL5cjs.ShellTypeValues.BASH]: {
144
+ [_chunkSWOS3DDMcjs.ShellTypeValues.BASH]: {
145
145
  icon: _chunk5R4QMTMLcjs.BashIcon,
146
146
  props: { size: 16, color: "var(--color-text-secondary)" }
147
147
  },
148
- [_chunkT32BTPL5cjs.ShellTypeValues.PYTHON]: {
149
- icon: _chunkYNL2NHXHcjs.PythonLogoIcon,
148
+ [_chunkSWOS3DDMcjs.ShellTypeValues.PYTHON]: {
149
+ icon: _chunk6TNOVWO3cjs.PythonLogoIcon,
150
150
  props: { size: 16, className: "text-ods-text-secondary" }
151
151
  },
152
- [_chunkT32BTPL5cjs.ShellTypeValues.NUSHELL]: {
152
+ [_chunkSWOS3DDMcjs.ShellTypeValues.NUSHELL]: {
153
153
  icon: _chunk5R4QMTMLcjs.NushellIcon,
154
154
  props: { size: 16, color: "var(--color-text-secondary)" }
155
155
  },
156
- [_chunkT32BTPL5cjs.ShellTypeValues.DENO]: {
156
+ [_chunkSWOS3DDMcjs.ShellTypeValues.DENO]: {
157
157
  icon: _chunk5R4QMTMLcjs.DenoIcon,
158
158
  props: { size: 16, color: "var(--color-text-secondary)" }
159
159
  },
160
- [_chunkT32BTPL5cjs.ShellTypeValues.SHELL]: {
160
+ [_chunkSWOS3DDMcjs.ShellTypeValues.SHELL]: {
161
161
  icon: _chunk5R4QMTMLcjs.ShellIcon,
162
162
  props: { size: 16, color: "var(--color-text-secondary)" }
163
163
  }
@@ -168,7 +168,7 @@ var defaultIconConfig = {
168
168
  };
169
169
  var ShellTypeBadge = ({ shellType, className, iconClassName }) => {
170
170
  const normalizedType = _optionalChain([shellType, 'optionalAccess', _ => _.toUpperCase, 'call', _2 => _2()]);
171
- const label = _chunkT32BTPL5cjs.getShellLabel.call(void 0, normalizedType);
171
+ const label = _chunkSWOS3DDMcjs.getShellLabel.call(void 0, normalizedType);
172
172
  const { icon: IconComponent, props: iconProps } = _nullishCoalesce(shellIconMap[normalizedType], () => ( defaultIconConfig));
173
173
  const defaultIconClassName = "className" in iconProps ? iconProps.className : void 0;
174
174
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkX7CEWD6Vcjs.cn.call(void 0, "flex items-center gap-1", className), children: [
@@ -184,7 +184,7 @@ function formatSupportedPlatforms(platforms) {
184
184
  if (!platforms || platforms.length === 0) {
185
185
  return "All Platforms";
186
186
  }
187
- return platforms.map((platform) => _chunkT32BTPL5cjs.getOSLabel.call(void 0, platform)).join(", ");
187
+ return platforms.map((platform) => _chunkSWOS3DDMcjs.getOSLabel.call(void 0, platform)).join(", ");
188
188
  }
189
189
  function InfoCell({ label, value, avatar, className }) {
190
190
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkX7CEWD6Vcjs.cn.call(void 0, "flex min-w-0 items-center gap-2", className), children: [
@@ -204,7 +204,7 @@ var ScriptInfoSection = ({
204
204
  author,
205
205
  className
206
206
  }) => {
207
- const shellLabel = _chunkT32BTPL5cjs.getShellLabel.call(void 0, shellType);
207
+ const shellLabel = _chunkSWOS3DDMcjs.getShellLabel.call(void 0, shellType);
208
208
  const platformsLabel = formatSupportedPlatforms(supportedPlatforms);
209
209
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkX7CEWD6Vcjs.cn.call(void 0, "overflow-hidden rounded-[6px] border border-ods-border bg-ods-card", className), children: [
210
210
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-b border-ods-border p-4", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1", children: [
@@ -284,7 +284,7 @@ var ScriptArguments = ({
284
284
  disabled,
285
285
  readOnly: isStoredSecret,
286
286
  title: isStoredSecret ? STORED_SECRET_KEY_HINT : void 0,
287
- startAdornment: arg.secret ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkYNL2NHXHcjs.LockIcon, { role: "img", "aria-label": "Secret" }) : void 0
287
+ startAdornment: arg.secret ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6TNOVWO3cjs.LockIcon, { role: "img", "aria-label": "Secret" }) : void 0
288
288
  }
289
289
  )
290
290
  ] }),
@@ -330,7 +330,7 @@ var ScriptArguments = ({
330
330
  onClick: () => handleAdd(),
331
331
  disabled,
332
332
  className: "self-start",
333
- leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkYNL2NHXHcjs.PlusCircleIcon, { className: "text-ods-text-secondary" }),
333
+ leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6TNOVWO3cjs.PlusCircleIcon, { className: "text-ods-text-secondary" }),
334
334
  children: addButtonLabel
335
335
  }
336
336
  ),
@@ -343,7 +343,7 @@ var ScriptArguments = ({
343
343
  onClick: () => handleAdd(true),
344
344
  disabled,
345
345
  className: "self-start",
346
- leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkYNL2NHXHcjs.LockIcon, { className: "text-ods-text-secondary" }),
346
+ leftIcon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6TNOVWO3cjs.LockIcon, { className: "text-ods-text-secondary" }),
347
347
  children: addSecretButtonLabel
348
348
  }
349
349
  )
@@ -451,7 +451,7 @@ function OnboardingWalkthrough({
451
451
  isStepSkipped,
452
452
  allStepsComplete,
453
453
  markMultipleComplete
454
- } = _chunkXF5TJ4P2cjs.useOnboardingState.call(void 0, storageKey);
454
+ } = _chunkBJHM2OEYcjs.useOnboardingState.call(void 0, storageKey);
455
455
  const hasAutoMarkedRef = _react.useRef.call(void 0, false);
456
456
  const autoMarkingInProgressRef = _react.useRef.call(void 0, false);
457
457
  const lastCompletionStatusRef = _react.useRef.call(void 0, null);
@@ -533,7 +533,7 @@ function OnboardingWalkthrough({
533
533
  const isAllComplete = allStepsComplete(steps);
534
534
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkX7CEWD6Vcjs.cn.call(void 0, "w-full space-y-4", className), children: [
535
535
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-start justify-between gap-3 md:flex-row md:items-center md:gap-0", children: [
536
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: _chunkLL35WZZScjs.SECTION_HEADING_CLASS, children: title }),
536
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: _chunkOD2WMUAOcjs.SECTION_HEADING_CLASS, children: title }),
537
537
  isLoadingCompletion ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[48px] w-full animate-pulse rounded-[6px] bg-ods-border md:w-[160px]" }) : isAllComplete ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkF6U2H42Lcjs.Button, { variant: "accent", onClick: handleDismiss, className: "w-full md:w-auto", children: "Close Onboarding" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkF6U2H42Lcjs.Button, { variant: "outline", onClick: handleDismiss, className: "w-full md:w-auto", children: "Skip Onboarding" })
538
538
  ] }),
539
539
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _chunkX7CEWD6Vcjs.cn.call(void 0, spacing), children: steps.map((step) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -562,4 +562,4 @@ function OnboardingWalkthrough({
562
562
 
563
563
 
564
564
  exports.SoftwareInfo = SoftwareInfo; exports.SoftwareSourceBadge = SoftwareSourceBadge; exports.CveLink = CveLink; exports.ToolBadge = ToolBadge; exports.ShellTypeBadge = ShellTypeBadge; exports.ScriptInfoSection = ScriptInfoSection; exports.ScriptArguments = ScriptArguments; exports.OnboardingStepCard = OnboardingStepCard; exports.OnboardingWalkthrough = OnboardingWalkthrough;
565
- //# sourceMappingURL=chunk-RHBFZC6F.cjs.map
565
+ //# sourceMappingURL=chunk-G3MH262S.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-RHBFZC6F.cjs","../src/components/platform/SoftwareInfo.tsx","../src/components/platform/SoftwareSourceBadge.tsx","../src/components/platform/CveLink.tsx","../src/components/platform/ToolBadge.tsx","../src/components/platform/ShellTypeBadge.tsx","../src/components/platform/ScriptInfoSection.tsx","../src/components/platform/ScriptArguments.tsx","../src/components/shared/onboarding/onboarding-step-card.tsx","../src/components/shared/onboarding/onboarding-walkthrough.tsx"],"names":["jsx","jsxs","cn","Fragment"],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-RHBFZC6F.cjs","sourcesContent":[null,"/**\n * SoftwareInfo Component\n *\n * Displays software name with optional vendor information below it.\n * Part of the ODS (OpenFrame Design System) platform components.\n *\n * @example\n * ```tsx\n * <SoftwareInfo name=\"Visual Studio Code\" vendor=\"Microsoft\" />\n * <SoftwareInfo name=\"Chrome\" /> // Without vendor\n * ```\n */\n\nimport type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface SoftwareInfoProps {\n /** Software name (required) */\n name: string;\n /** Software vendor (optional) */\n vendor?: string;\n /** Software version (optional) */\n version?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\nexport const SoftwareInfo: React.FC<SoftwareInfoProps> = ({ name, vendor, version, className }) => {\n return (\n <div className={cn('flex flex-col gap-1', className)}>\n <div className=\"flex items-center gap-2\">\n <div className=\"text-ods-text-primary text-h4\">{name}</div>\n {version && (\n <div className=\"rounded bg-ods-bg-surface px-2 py-1 text-ods-text-secondary text-h6\">{version}</div>\n )}\n </div>\n {vendor && <div className=\"text-ods-text-secondary text-h6\">{vendor}</div>}\n </div>\n );\n};\n\nSoftwareInfo.displayName = 'SoftwareInfo';\n","/**\n * SoftwareSourceBadge Component\n *\n * Displays a badge for software source types from Fleet MDM.\n * Supports all osquery software source types with appropriate styling.\n *\n * Fleet MDM Software Sources:\n * - apps: macOS Applications\n * - chrome_extensions: Chrome Browser Extensions\n * - firefox_addons: Firefox Browser Extensions\n * - safari_extensions: Safari Browser Extensions\n * - ie_extensions: Internet Explorer Extensions\n * - vscode_extensions: VS Code Extensions\n * - atom_packages: Atom Packages\n * - homebrew_packages: Homebrew Packages (macOS)\n * - npm_packages: NPM Packages\n * - python_packages: Python Packages\n * - apt_sources: APT Packages (Debian/Ubuntu)\n * - deb_packages: DEB Packages\n * - rpm_packages: RPM Packages (Red Hat/CentOS)\n * - yum_sources: YUM Packages\n * - portage_packages: Portage Packages (Gentoo)\n * - chocolatey_packages: Chocolatey Packages (Windows)\n * - programs: Windows Programs\n * - pkg_packages: PKG Packages\n *\n * @example\n * ```tsx\n * <SoftwareSourceBadge source=\"apps\" />\n * <SoftwareSourceBadge source=\"chrome_extensions\" />\n * <SoftwareSourceBadge source=\"python_packages\" />\n * ```\n */\n\nimport type React from 'react';\nimport { cn } from '../../utils/common';\nimport { PackageIcon, WindowsIcon, MacOSIcon, LinuxIcon } from '../icons';\n\nexport type SoftwareSource =\n | 'apps'\n | 'chrome_extensions'\n | 'firefox_addons'\n | 'safari_extensions'\n | 'ie_extensions'\n | 'vscode_extensions'\n | 'atom_packages'\n | 'homebrew_packages'\n | 'npm_packages'\n | 'python_packages'\n | 'apt_sources'\n | 'deb_packages'\n | 'rpm_packages'\n | 'yum_sources'\n | 'portage_packages'\n | 'chocolatey_packages'\n | 'programs'\n | 'pkg_packages';\n\nexport interface SoftwareSourceBadgeProps {\n /** Software source type from Fleet MDM */\n source: SoftwareSource;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Maps source types to human-readable labels and icons\n */\nconst sourceConfig: Record<SoftwareSource, { label: string; icon: React.ReactNode }> = {\n apps: { label: 'App', icon: <MacOSIcon className=\"h-4 w-4\" /> },\n chrome_extensions: { label: 'Chrome', icon: <PackageIcon className=\"h-4 w-4\" /> },\n firefox_addons: { label: 'Firefox', icon: <PackageIcon className=\"h-4 w-4\" /> },\n safari_extensions: { label: 'Safari', icon: <PackageIcon className=\"h-4 w-4\" /> },\n ie_extensions: { label: 'IE', icon: <PackageIcon className=\"h-4 w-4\" /> },\n vscode_extensions: { label: 'VS Code', icon: <PackageIcon className=\"h-4 w-4\" /> },\n atom_packages: { label: 'Atom', icon: <PackageIcon className=\"h-4 w-4\" /> },\n homebrew_packages: { label: 'Homebrew', icon: <MacOSIcon className=\"h-4 w-4\" /> },\n npm_packages: { label: 'NPM', icon: <PackageIcon className=\"h-4 w-4\" /> },\n python_packages: { label: 'Python', icon: <PackageIcon className=\"h-4 w-4\" /> },\n apt_sources: { label: 'APT', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n deb_packages: { label: 'DEB', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n rpm_packages: { label: 'RPM', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n yum_sources: { label: 'YUM', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n portage_packages: { label: 'Portage', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n chocolatey_packages: { label: 'Chocolatey', icon: <WindowsIcon className=\"h-4 w-4\" /> },\n programs: { label: 'Windows', icon: <WindowsIcon className=\"h-4 w-4\" /> },\n pkg_packages: { label: 'PKG', icon: <PackageIcon className=\"h-4 w-4\" /> },\n};\n\nexport const SoftwareSourceBadge: React.FC<SoftwareSourceBadgeProps> = ({ source, className }) => {\n const config = sourceConfig[source] || { label: source, icon: <PackageIcon className=\"h-4 w-4\" /> };\n\n return (\n <span className={cn('inline-flex items-center gap-2 text-ods-text-primary', className)}>\n {config.icon}\n {config.label}\n </span>\n );\n};\n\nSoftwareSourceBadge.displayName = 'SoftwareSourceBadge';\n","/**\n * CveLink Component\n *\n * Displays a CVE ID with an external link icon that links to the NIST NVD database.\n * Part of the ODS (OpenFrame Design System) platform components.\n *\n * @example\n * ```tsx\n * <CveLink cveId=\"CVE-2024-1234\" />\n * ```\n */\n\nimport type React from 'react';\nimport { cn } from '../../utils/cn';\nimport { CustomExternalLinkIcon } from '../icons';\n\nexport interface CveLinkProps {\n /** CVE ID (e.g., \"CVE-2024-1234\") */\n cveId: string;\n /** Additional CSS classes */\n className?: string;\n}\n\nexport const CveLink: React.FC<CveLinkProps> = ({ cveId, className }) => {\n const nistUrl = `https://nvd.nist.gov/vuln/detail/${cveId}`;\n\n return (\n <a\n href={nistUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n 'group inline-flex items-center gap-2 text-ods-text-primary transition-colors text-code hover:text-ods-accent',\n className,\n )}\n >\n <span>{cveId}</span>\n <CustomExternalLinkIcon className=\"h-4 w-4 text-ods-text-secondary transition-colors group-hover:text-ods-accent\" />\n </a>\n );\n};\n\nCveLink.displayName = 'CveLink';\n","/**\n * ToolBadge Component\n *\n * Displays a tool type badge with icon for OpenFrame integrated tools.\n * Used in tables to show tool sources like Fleet MDM, MeshCentral, etc.\n *\n * @example\n * ```tsx\n * <ToolBadge toolType=\"OPENFRAME_RMM\" />\n * <ToolBadge toolType=\"FLEET\" />\n * <ToolBadge toolType=\"MESHCENTRAL\" />\n * ```\n */\n\nimport type React from 'react';\nimport type { ToolType } from '../../types/tool.types';\nimport { cn } from '../../utils/cn';\nimport { getToolLabel } from '../../utils/tool-utils';\nimport { ToolIcon } from '../tool-icon';\n\nexport type { ToolType } from '../../types/tool.types';\n\nexport interface ToolBadgeProps {\n /** Tool type */\n toolType: ToolType;\n /** Additional CSS classes */\n className?: string;\n iconClassName?: string;\n}\n\nexport const ToolBadge: React.FC<ToolBadgeProps> = ({ toolType, className, iconClassName }) => {\n const label = getToolLabel(toolType);\n\n return (\n <div className={cn('flex items-center gap-1 text-ods-text-secondary', className)}>\n <ToolIcon toolType={toolType} className={iconClassName} size={16} />\n <span className=\"text-ods-text-primary text-h4\">{label}</span>\n </div>\n );\n};\n\nToolBadge.displayName = 'ToolBadge';\n","/**\n * ShellTypeBadge Component\n *\n * Displays a badge for shell/script types with appropriate icon and label.\n * Supports all RMM shell types.\n */\n\nimport type React from 'react';\nimport { type ShellType, ShellTypeValues } from '../../types/shell.types';\nimport { cn } from '../../utils/cn';\nimport { getShellLabel } from '../../utils/shell-utils';\nimport { BashIcon, CmdIcon, DenoIcon, NushellIcon, ShellIcon } from '../icons';\nimport { PowershellLogoGreyIcon } from '../icons-v2-generated/brand-logos/powershell-logo-grey-icon';\nimport { PythonLogoIcon } from '../icons-v2-generated/brand-logos/python-logo-icon';\n\n/**\n * Shell icon configuration with typed mapping\n */\ninterface ShellIconConfig {\n icon: React.ComponentType<{ size?: number; color?: string; className?: string }>;\n props: { size: number } & ({ className: string } | { color: string });\n}\n\n/**\n * Typed mapping of shell types to their icon configurations\n * Using Record<ShellType, ...> ensures all shell types are covered\n */\nconst shellIconMap: Record<ShellType, ShellIconConfig> = {\n [ShellTypeValues.POWERSHELL]: {\n icon: PowershellLogoGreyIcon,\n props: { size: 16, className: 'text-ods-text-secondary' },\n },\n [ShellTypeValues.CMD]: {\n icon: CmdIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n [ShellTypeValues.BASH]: {\n icon: BashIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n [ShellTypeValues.PYTHON]: {\n icon: PythonLogoIcon,\n props: { size: 16, className: 'text-ods-text-secondary' },\n },\n [ShellTypeValues.NUSHELL]: {\n icon: NushellIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n [ShellTypeValues.DENO]: {\n icon: DenoIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n [ShellTypeValues.SHELL]: {\n icon: ShellIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n} as const;\n\nconst defaultIconConfig: ShellIconConfig = {\n icon: ShellIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n};\n\nexport interface ShellTypeBadgeProps {\n shellType: ShellType;\n className?: string;\n iconClassName?: string;\n}\n\nexport const ShellTypeBadge: React.FC<ShellTypeBadgeProps> = ({ shellType, className, iconClassName }) => {\n const normalizedType = shellType?.toUpperCase() as ShellType;\n const label = getShellLabel(normalizedType);\n const { icon: IconComponent, props: iconProps } = shellIconMap[normalizedType] ?? defaultIconConfig;\n const defaultIconClassName = 'className' in iconProps ? iconProps.className : undefined;\n\n return (\n <div className={cn('flex items-center gap-1', className)}>\n <IconComponent size={16} className={cn(defaultIconClassName, iconClassName)} />\n <span className=\"text-ods-text-primary text-h4\">{label}</span>\n </div>\n );\n};\n\nShellTypeBadge.displayName = 'ShellTypeBadge';\n","/**\n * ScriptInfoSection Component\n *\n * Displays script information in a card with header (title, description)\n * and detail cells (shell type, supported platforms, category, author).\n * Responsive layout: stacks cells on mobile, shows grid on desktop.\n */\n\nimport type React from 'react';\nimport Image from '../../embed-shims/next-image';\nimport { cn } from '../../utils/cn';\nimport { nameInitials } from '../../utils/format';\nimport { getOSLabel } from '../../utils/os-utils';\nimport { getShellLabel } from '../../utils/shell-utils';\n\n/**\n * Props for author avatar display\n */\nexport interface ScriptAuthor {\n /** Author name */\n name: string;\n /** Author initials (used when no photo) */\n initials?: string;\n /** URL to author's photo */\n photoUrl?: string;\n}\n\n/**\n * Props for ScriptInfoSection component\n */\nexport interface ScriptInfoSectionProps {\n /** Script title/name */\n headline: string;\n /** Script description */\n subheadline?: string;\n /** Shell type (POWERSHELL, BASH, CMD, etc.) */\n shellType?: string;\n /** Array of supported platform strings (windows, darwin, linux, etc.) */\n supportedPlatforms?: string[];\n /** Script category */\n category: string;\n /** Author information */\n author?: ScriptAuthor;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Formats supported platforms array into a display string\n * @param platforms - Array of platform strings (e.g., ['windows', 'darwin', 'linux'])\n * @returns Formatted string (e.g., 'Windows, macOS, Linux')\n */\nfunction formatSupportedPlatforms(platforms?: string[]): string {\n if (!platforms || platforms.length === 0) {\n return 'All Platforms';\n }\n return platforms.map(platform => getOSLabel(platform)).join(', ');\n}\n\n/**\n * InfoCell - Single info cell with label and value\n */\ninterface InfoCellProps {\n label: string;\n value: string;\n avatar?: ScriptAuthor;\n className?: string;\n}\n\nfunction InfoCell({ label, value, avatar, className }: InfoCellProps) {\n return (\n <div className={cn('flex min-w-0 items-center gap-2', className)}>\n {/* Avatar for author cell */}\n {avatar && (\n <div className=\"relative size-8 shrink-0 overflow-hidden rounded-full border border-ods-border bg-ods-bg\">\n {avatar.photoUrl ? (\n <Image src={avatar.photoUrl} alt={avatar.name} className=\"object-cover\" fill sizes=\"32px\" unoptimized />\n ) : (\n <div className=\"flex size-full items-center justify-center text-ods-text-secondary text-h6\">\n {avatar.initials || nameInitials(avatar.name)}\n </div>\n )}\n </div>\n )}\n\n {/* Text content */}\n <div className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-ods-text-primary text-h4\" title={value}>\n {value}\n </span>\n <span className=\"truncate text-ods-text-secondary text-h6\">{label}</span>\n </div>\n </div>\n );\n}\n\n/**\n * ScriptInfoSection - Displays script information in a structured card\n *\n * @example\n * ```tsx\n * <ScriptInfoSection\n * title=\"System Backup Script\"\n * description=\"Comprehensive Linux system backup script...\"\n * shellType=\"BASH\"\n * supportedPlatforms={['linux']}\n * category=\"System Maintenance\"\n * author={{ name: 'John Doe', photoUrl: '/avatars/john.jpg' }}\n * />\n * ```\n */\nexport const ScriptInfoSection: React.FC<ScriptInfoSectionProps> = ({\n headline,\n subheadline,\n shellType,\n supportedPlatforms,\n category,\n author,\n className,\n}) => {\n const shellLabel = getShellLabel(shellType);\n const platformsLabel = formatSupportedPlatforms(supportedPlatforms);\n\n return (\n <div className={cn('overflow-hidden rounded-[6px] border border-ods-border bg-ods-card', className)}>\n {/* Header row with title and description */}\n <div className=\"border-b border-ods-border p-4\">\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-ods-text-primary text-h4\">{headline}</h3>\n {subheadline && <p className=\"break-words text-ods-text-secondary text-h6\">{subheadline}</p>}\n </div>\n </div>\n\n {/* Details section with info cells\n - Mobile/Tablet (<lg): 2x2 grid with divider between rows\n - Desktop (lg+): 4 columns in single row\n */}\n {/* First row: Shell Type, Supported Platforms */}\n <div className=\"grid grid-cols-2 gap-4 border-b border-ods-border px-4 py-4 lg:grid-cols-4 lg:border-b-0\">\n <InfoCell label=\"Shell Type\" value={shellLabel} />\n <InfoCell label=\"Supported Platforms\" value={platformsLabel} />\n {/* Desktop only: Category and Author in same row */}\n <InfoCell label=\"Category\" value={category} className=\"hidden lg:flex\" />\n {author && <InfoCell label=\"Added by\" value={author.name} avatar={author} className=\"hidden lg:flex\" />}\n </div>\n {/* Second row (mobile/tablet only): Category, Author */}\n <div className=\"grid grid-cols-2 gap-4 px-4 py-4 lg:hidden\">\n <InfoCell label=\"Category\" value={category} />\n {author && <InfoCell label=\"Added by\" value={author.name} avatar={author} />}\n </div>\n </div>\n );\n};\n\nScriptInfoSection.displayName = 'ScriptInfoSection';\n","/**\n * ScriptArguments Component\n *\n * Displays and manages script arguments as key-value pairs.\n * Each argument has a name (key) and value input field with delete button.\n * Includes an \"Add Script Argument\" button to add new entries.\n */\n\nimport { Trash2 } from 'lucide-react';\nimport type React from 'react';\nimport { cn } from '../../utils/cn';\nimport { LockIcon, PlusCircleIcon } from '../icons-v2-generated';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\n\n/**\n * What an untouched stored secret shows in its value field.\n *\n * Rendered as the field's PLACEHOLDER, never as its value: a mask held in\n * `value` is indistinguishable from something the user typed, and would be\n * submitted back as the secret itself.\n */\nconst SECRET_MASK = '**********';\n\nconst STORED_SECRET_KEY_HINT = \"A stored secret can't be renamed — delete it and add a new one\";\n\n/**\n * Single script argument with key and value\n */\nexport interface ScriptArgument {\n /** Unique identifier for the argument */\n id: string;\n /** Argument name/key */\n key: string;\n /** Argument value (empty string for flag-type arguments) */\n value: string;\n /**\n * A secret pair: the key carries a lock and the value is typed as a password.\n * Meaningful for environment variables only.\n */\n secret?: boolean;\n /**\n * The server holds a value for this secret and does not send it back. While\n * `value` is empty the field shows a mask, so empty means \"keep what is\n * stored\" and typing replaces it.\n *\n * The stored value is bound to the key, which is therefore read-only:\n * renaming would leave the old name holding the secret and the new one\n * holding nothing.\n */\n hasStoredValue?: boolean;\n}\n\n/**\n * Props for ScriptArguments component\n */\nexport interface ScriptArgumentsProps {\n /** Array of script arguments */\n arguments: ScriptArgument[];\n /** Callback when arguments change */\n onArgumentsChange?: (args: ScriptArgument[]) => void;\n /** Placeholder for key input */\n keyPlaceholder?: string;\n /** Placeholder for value input */\n valuePlaceholder?: string;\n /** Label for the add button */\n addButtonLabel?: string;\n /** Label for a second add button that appends a secret pair. Omit to not offer secrets. */\n addSecretButtonLabel?: string;\n /** Whether the component is disabled */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label for the title input */\n titleLabel: string;\n}\n\n/**\n * ScriptArguments - Displays and manages script arguments\n *\n * @example\n * ```tsx\n * <ScriptArguments\n * arguments={[\n * { id: '1', key: 'port', value: '3000' },\n * { id: '2', key: 'verbose', value: '' },\n * ]}\n * onArgumentsChange={(args) => setArguments(args)}\n * />\n * ```\n */\nexport const ScriptArguments: React.FC<ScriptArgumentsProps> = ({\n arguments: args,\n onArgumentsChange,\n keyPlaceholder = 'Enter Key',\n valuePlaceholder = 'Enter Value (empty=flag)',\n addButtonLabel = 'Add Script Argument',\n addSecretButtonLabel,\n disabled = false,\n className,\n titleLabel,\n}) => {\n const handleKeyChange = (id: string, newKey: string) => {\n if (!onArgumentsChange) return;\n const updated = args.map(arg => (arg.id === id ? { ...arg, key: newKey } : arg));\n onArgumentsChange(updated);\n };\n\n const handleValueChange = (id: string, newValue: string) => {\n if (!onArgumentsChange) return;\n const updated = args.map(arg => (arg.id === id ? { ...arg, value: newValue } : arg));\n onArgumentsChange(updated);\n };\n\n const handleDelete = (id: string) => {\n if (!onArgumentsChange) return;\n const updated = args.filter(arg => arg.id !== id);\n onArgumentsChange(updated);\n };\n\n const handleAdd = (secret = false) => {\n if (!onArgumentsChange) return;\n const newArg: ScriptArgument = {\n id: crypto.randomUUID(),\n key: '',\n value: '',\n // Only set on a secret, so a plain pair keeps the shape it always had.\n ...(secret && { secret: true }),\n };\n onArgumentsChange([...args, newArg]);\n };\n\n const isFirstRow = (index: number) => index === 0;\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {args.map((arg, index) => {\n const isStoredSecret = Boolean(arg.secret && arg.hasStoredValue);\n // The mask stands for the stored value, so it goes once the user types a replacement.\n const showsMask = isStoredSecret && !arg.value;\n\n return (\n <div key={arg.id} className=\"flex w-full items-end gap-2\">\n {/* Key input - with label only on first row */}\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n {isFirstRow(index) && <Label spacing=\"tight\">{titleLabel}</Label>}\n <Input\n value={arg.key}\n onChange={e => handleKeyChange(arg.id, e.target.value)}\n placeholder={keyPlaceholder}\n disabled={disabled}\n readOnly={isStoredSecret}\n title={isStoredSecret ? STORED_SECRET_KEY_HINT : undefined}\n startAdornment={arg.secret ? <LockIcon role=\"img\" aria-label=\"Secret\" /> : undefined}\n />\n </div>\n\n {/* Value input with delete button */}\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <Input\n // `new-password` keeps a password manager from filling a saved login into a secret.\n type={arg.secret ? 'password' : undefined}\n autoComplete={arg.secret ? 'new-password' : undefined}\n value={arg.value}\n onChange={e => handleValueChange(arg.id, e.target.value)}\n placeholder={showsMask ? SECRET_MASK : valuePlaceholder}\n disabled={disabled}\n className={cn(\n !arg.value && 'placeholder:text-ods-text-muted',\n // The mask reads as a value that is there, not as a prompt to fill one in.\n showsMask && '[&_input]:placeholder:text-ods-text-primary',\n )}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => handleDelete(arg.id)}\n disabled={disabled}\n aria-label=\"Delete argument\"\n leftIcon={<Trash2 className=\"size-4 md:size-6\" color=\"var(--color-error)\" />}\n />\n </div>\n </div>\n );\n })}\n\n {/* Add buttons - aligned left */}\n <div className=\"flex flex-wrap justify-start gap-[var(--spacing-system-xs)]\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={() => handleAdd()}\n disabled={disabled}\n className=\"self-start\"\n leftIcon={<PlusCircleIcon className=\"text-ods-text-secondary\" />}\n >\n {addButtonLabel}\n </Button>\n {addSecretButtonLabel && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={() => handleAdd(true)}\n disabled={disabled}\n className=\"self-start\"\n leftIcon={<LockIcon className=\"text-ods-text-secondary\" />}\n >\n {addSecretButtonLabel}\n </Button>\n )}\n </div>\n </div>\n );\n};\n\nScriptArguments.displayName = 'ScriptArguments';\n","'use client';\n\nimport React from 'react';\nimport { cn } from '../../../utils/cn';\nimport { Button } from '../../ui/button';\nimport { InteractiveCard } from '../../ui/interactive-card';\nimport { StatusBadge } from '../../ui/status-badge';\n\nexport interface OnboardingStepCardProps {\n step: {\n id: string;\n title: string;\n description: string;\n actionIcon: (color?: string) => React.ReactNode;\n actionText: string;\n completedText: string;\n onAction: () => void | Promise<void>;\n onSkip?: () => void;\n };\n isCompleted: boolean;\n isSkipped: boolean;\n isCheckingCompletion: boolean;\n onAction: () => void | Promise<void>;\n onSkip: () => void;\n className?: string;\n}\n\nexport function OnboardingStepCard({\n step,\n isCompleted,\n isSkipped,\n isCheckingCompletion,\n onAction,\n onSkip,\n className,\n}: OnboardingStepCardProps) {\n const [isProcessing, setIsProcessing] = React.useState(false);\n\n const handleAction = async (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsProcessing(true);\n try {\n await onAction();\n } finally {\n setIsProcessing(false);\n }\n };\n\n const handleSkip = (e: React.MouseEvent) => {\n e.stopPropagation();\n onSkip();\n };\n\n return (\n <InteractiveCard\n clickable={false}\n className={cn(\n 'rounded-[6px] border border-ods-border bg-ods-card',\n 'flex flex-col md:flex-row',\n 'min-h-[80px] md:h-[80px]',\n 'items-start md:items-center',\n 'gap-3 md:gap-4',\n 'px-4 py-4 md:py-0',\n className,\n )}\n >\n {/* Left column - content */}\n <div className=\"flex w-full min-w-0 flex-1 flex-col justify-center gap-1 md:w-auto\">\n <h3 className=\"truncate text-ods-text-primary text-h4\" title={step.title}>\n {step.title}\n </h3>\n <p className=\"h-[20px] truncate text-ods-text-secondary text-h6\" title={step.description}>\n {step.description}\n </p>\n </div>\n\n {/* Right column - action buttons, completed badge, or skipped badge */}\n <div\n className=\"flex w-full shrink-0 items-center justify-start gap-2 md:w-auto md:justify-end\"\n onClick={e => e.stopPropagation()}\n >\n {isCheckingCompletion ? (\n <>\n <div className=\"h-[32px] w-[100px] animate-pulse rounded-[6px] bg-ods-border\" />\n <div className=\"h-[32px] w-[120px] animate-pulse rounded-[6px] bg-ods-border\" />\n </>\n ) : isCompleted ? (\n <>\n <StatusBadge text=\"COMPLETED\" variant=\"card\" colorScheme=\"success\" />\n <Button\n variant=\"outline\"\n onClick={handleAction}\n disabled={isProcessing}\n leftIcon={step.actionIcon('white')}\n >\n {step.completedText}\n </Button>\n </>\n ) : isSkipped ? (\n <>\n <StatusBadge text=\"SKIPPED\" variant=\"card\" colorScheme=\"default\" />\n </>\n ) : (\n <>\n <Button variant=\"outline\" onClick={handleSkip}>\n Skip Step\n </Button>\n <Button variant=\"accent\" onClick={handleAction} disabled={isProcessing} leftIcon={step.actionIcon('black')}>\n {step.actionText}\n </Button>\n </>\n )}\n </div>\n </InteractiveCard>\n );\n}\n","'use client';\n\nimport React, { useRef, useCallback } from 'react';\nimport { useOnboardingState, type OnboardingStepConfig } from '../../../hooks/ui/use-onboarding-state';\nimport { cn } from '../../../utils/cn';\nimport { SECTION_HEADING_CLASS } from '../../layout/page-heading';\nimport { Button } from '../../ui/button';\nimport { OnboardingStepCard } from './onboarding-step-card';\n\nexport interface OnboardingWalkthroughProps {\n steps: OnboardingStepConfig[];\n /** Heading above the steps. Defaults to \"Get Started\". */\n title?: string;\n /**\n * What to render once the walkthrough is dismissed. Receives `restart`,\n * which clears every completed/skipped step and shows the walkthrough\n * again. Omitted: a dismissed walkthrough renders nothing.\n */\n renderDismissed?: (restart: () => void) => React.ReactNode;\n onDismiss?: () => void;\n storageKey?: string;\n className?: string;\n spacing?: string;\n /**\n * Completion status from hook-based checks (e.g., useOnboardingCompletion)\n * Object mapping step IDs to boolean completion status\n */\n completionStatus?: Record<string, boolean>;\n /**\n * Whether completion checks are still loading\n */\n isLoadingCompletion?: boolean;\n}\n\nexport function OnboardingWalkthrough({\n steps,\n title = 'Get Started',\n renderDismissed,\n onDismiss,\n storageKey = 'openframe-onboarding-state',\n className,\n spacing = 'space-y-4',\n completionStatus,\n isLoadingCompletion = false,\n}: OnboardingWalkthroughProps) {\n const {\n state,\n markComplete,\n markSkipped,\n dismissOnboarding,\n resetOnboarding,\n isStepComplete,\n isStepSkipped,\n allStepsComplete,\n markMultipleComplete,\n } = useOnboardingState(storageKey);\n\n // Refs to prevent race conditions - ALL refs must be declared before any conditional returns\n const hasAutoMarkedRef = useRef(false);\n const autoMarkingInProgressRef = useRef(false);\n const lastCompletionStatusRef = useRef<string | null>(null);\n // Ref to track in-flight action handlers - moved here to be before conditional return\n const actionInProgressRef = useRef<Set<string>>(new Set());\n\n // Sync completion status from hooks to localStorage\n // Uses refs to prevent duplicate calls and race conditions\n React.useEffect(() => {\n // Skip if still loading\n if (isLoadingCompletion) {\n hasAutoMarkedRef.current = false; // Reset when loading starts\n return;\n }\n\n // Skip if no completion status\n if (!completionStatus) return;\n\n // Create a stable key from completion status to detect actual changes.\n // An empty state (first load, or after a restart) is keyed by when it was\n // written, so a restart applies the same status again.\n const isFreshState = state.completedSteps.length === 0 && state.skippedSteps.length === 0;\n const statusKey = `${JSON.stringify(completionStatus)}|${isFreshState ? state.lastUpdated : ''}`;\n\n // Skip if we've already processed this exact status\n if (lastCompletionStatusRef.current === statusKey) return;\n\n // Skip if auto-marking is currently in progress\n if (autoMarkingInProgressRef.current) return;\n\n // Find steps that need to be marked complete\n // Read directly from state to avoid stale closure issues\n const completedStepIds = Object.entries(completionStatus)\n .filter(([stepId, isComplete]) => {\n if (!isComplete) return false;\n // Check against current state, not the callback\n return !state.completedSteps.includes(stepId);\n })\n .map(([stepId]) => stepId);\n\n if (completedStepIds.length > 0) {\n // Mark as in progress to prevent concurrent calls\n autoMarkingInProgressRef.current = true;\n\n markMultipleComplete(completedStepIds);\n\n // Update the last processed status key\n lastCompletionStatusRef.current = statusKey;\n\n // Reset the in-progress flag after a short delay\n // This prevents rapid successive calls while allowing future updates\n setTimeout(() => {\n autoMarkingInProgressRef.current = false;\n }, 100);\n } else {\n // Even if no steps to mark, update the status key to prevent re-processing\n lastCompletionStatusRef.current = statusKey;\n }\n }, [\n completionStatus,\n isLoadingCompletion,\n state.completedSteps,\n state.skippedSteps,\n state.lastUpdated,\n markMultipleComplete,\n ]);\n\n // useCallback must be called unconditionally (before any early returns)\n const handleStepAction = useCallback(\n async (step: OnboardingStepConfig) => {\n // Prevent duplicate action handling for the same step\n if (actionInProgressRef.current.has(step.id)) {\n return;\n }\n\n // Mark as in progress\n actionInProgressRef.current.add(step.id);\n\n try {\n await step.onAction();\n\n // Skip if already completed (could have been auto-marked while action was running)\n if (state.completedSteps.includes(step.id)) {\n return;\n }\n\n // Auto-mark Knowledge Base as complete (no verification needed)\n if (step.id === 'knowledge-base') {\n markComplete(step.id);\n return;\n }\n\n // For other steps, re-check completion after action\n if (step.checkComplete) {\n try {\n const isComplete = await step.checkComplete();\n\n // Double-check it wasn't completed while we were checking\n if (isComplete && !state.completedSteps.includes(step.id)) {\n markComplete(step.id);\n }\n } catch (error) {\n console.error(`Error checking completion for \"${step.id}\":`, error);\n }\n }\n } finally {\n // Remove from in-progress set\n actionInProgressRef.current.delete(step.id);\n }\n },\n [state.completedSteps, markComplete],\n );\n\n const handleStepSkip = (step: OnboardingStepConfig) => {\n step.onSkip?.();\n markSkipped(step.id);\n };\n\n const handleDismiss = () => {\n dismissOnboarding();\n onDismiss?.();\n };\n\n // ALL hooks have been called above - now safe to do conditional returns\n // Don't render if dismissed\n if (state.dismissed) {\n return renderDismissed ? <>{renderDismissed(resetOnboarding)}</> : null;\n }\n\n const isAllComplete = allStepsComplete(steps);\n\n return (\n <div className={cn('w-full space-y-4', className)}>\n {/* Header - responsive: stacks on mobile */}\n <div className=\"flex flex-col items-start justify-between gap-3 md:flex-row md:items-center md:gap-0\">\n <h2 className={SECTION_HEADING_CLASS}>{title}</h2>\n\n {isLoadingCompletion ? (\n <div className=\"h-[48px] w-full animate-pulse rounded-[6px] bg-ods-border md:w-[160px]\" />\n ) : isAllComplete ? (\n <Button variant=\"accent\" onClick={handleDismiss} className=\"w-full md:w-auto\">\n Close Onboarding\n </Button>\n ) : (\n <Button variant=\"outline\" onClick={handleDismiss} className=\"w-full md:w-auto\">\n Skip Onboarding\n </Button>\n )}\n </div>\n\n {/* Step cards - no wrapper, direct rendering */}\n <div className={cn(spacing)}>\n {steps.map(step => (\n <OnboardingStepCard\n key={step.id}\n step={step}\n isCompleted={isStepComplete(step.id)}\n isSkipped={isStepSkipped(step.id)}\n isCheckingCompletion={isLoadingCompletion}\n onAction={() => handleStepAction(step)}\n onSkip={() => handleStepSkip(step)}\n />\n ))}\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-G3MH262S.cjs","../src/components/platform/SoftwareInfo.tsx","../src/components/platform/SoftwareSourceBadge.tsx","../src/components/platform/CveLink.tsx","../src/components/platform/ToolBadge.tsx","../src/components/platform/ShellTypeBadge.tsx","../src/components/platform/ScriptInfoSection.tsx","../src/components/platform/ScriptArguments.tsx","../src/components/shared/onboarding/onboarding-step-card.tsx","../src/components/shared/onboarding/onboarding-walkthrough.tsx"],"names":["jsx","jsxs","cn","Fragment"],"mappings":"AAAA,6xBAAY;AACZ;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACxBM,+CAAA;AAHC,IAAM,aAAA,EAA4C,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,UAAU,CAAA,EAAA,GAAM;AACjG,EAAA,uBACE,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAW,kCAAA,qBAAG,EAAuB,SAAS,CAAA,EACjD,QAAA,EAAA;AAAA,oBAAA,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,+BAAA,EAAiC,QAAA,EAAA,KAAA,CAAK,CAAA;AAAA,MACpD,QAAA,mBACC,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,qEAAA,EAAuE,QAAA,EAAA,QAAA,CAAQ;AAAA,IAAA,EAAA,CAElG,CAAA;AAAA,IACC,OAAA,mBAAU,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,iCAAA,EAAmC,QAAA,EAAA,OAAA,CAAO;AAAA,EAAA,EAAA,CACtE,CAAA;AAEJ,CAAA;AAEA,YAAA,CAAa,YAAA,EAAc,cAAA;ADyB3B;AACA;AEE8B;AAD9B,IAAM,aAAA,EAAiF;AAAA,EACrF,IAAA,EAAM,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,kBAAMA,6BAAAA,2BAAC,EAAA,EAAU,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EAC9D,iBAAA,EAAmB,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EAChF,cAAA,EAAgB,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EAC9E,iBAAA,EAAmB,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EAChF,aAAA,EAAe,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACxE,iBAAA,EAAmB,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACjF,aAAA,EAAe,EAAE,KAAA,EAAO,MAAA,EAAQ,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EAC1E,iBAAA,EAAmB,EAAE,KAAA,EAAO,UAAA,EAAY,IAAA,kBAAMA,6BAAAA,2BAAC,EAAA,EAAU,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EAChF,YAAA,EAAc,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACxE,eAAA,EAAiB,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EAC9E,WAAA,EAAa,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,kBAAMA,6BAAAA,2BAAC,EAAA,EAAU,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACrE,YAAA,EAAc,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,kBAAMA,6BAAAA,2BAAC,EAAA,EAAU,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACtE,YAAA,EAAc,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,kBAAMA,6BAAAA,2BAAC,EAAA,EAAU,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACtE,WAAA,EAAa,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,kBAAMA,6BAAAA,2BAAC,EAAA,EAAU,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACrE,gBAAA,EAAkB,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,kBAAMA,6BAAAA,2BAAC,EAAA,EAAU,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EAC9E,mBAAA,EAAqB,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACtF,QAAA,EAAU,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAAA,EACxE,YAAA,EAAc,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG;AAC1E,CAAA;AAEO,IAAM,oBAAA,EAA0D,CAAC,EAAE,MAAA,EAAQ,UAAU,CAAA,EAAA,GAAM;AAChG,EAAA,MAAM,OAAA,EAAS,YAAA,CAAa,MAAM,EAAA,GAAK,EAAE,KAAA,EAAO,MAAA,EAAQ,IAAA,kBAAMA,6BAAAA,6BAAC,EAAA,EAAY,SAAA,EAAU,UAAA,CAAU,EAAG,CAAA;AAElG,EAAA,uBACEC,8BAAAA,MAAC,EAAA,EAAK,SAAA,EAAWC,kCAAAA,sDAAG,EAAwD,SAAS,CAAA,EAClF,QAAA,EAAA;AAAA,IAAA,MAAA,CAAO,IAAA;AAAA,IACP,MAAA,CAAO;AAAA,EAAA,EAAA,CACV,CAAA;AAEJ,CAAA;AAEA,mBAAA,CAAoB,YAAA,EAAc,qBAAA;AFHlC;AACA;AGvEI;AAJG,IAAM,QAAA,EAAkC,CAAC,EAAE,KAAA,EAAO,UAAU,CAAA,EAAA,GAAM;AACvE,EAAA,MAAM,QAAA,EAAU,CAAA,iCAAA,EAAoC,KAAK,CAAA,CAAA;AAGvDD,EAAAA;AAAC,IAAA;AAAA,IAAA;AACO,MAAA;AACC,MAAA;AACH,MAAA;AACO,MAAA;AACT,QAAA;AACA,QAAA;AACF,MAAA;AAEA,MAAA;AAAa,wBAAA;AACW,wBAAA;AAA0F,MAAA;AAAA,IAAA;AACpH,EAAA;AAEJ;AAEsB;AH8EsC;AACA;AIvFxD;AAJ2F;AAC1D,EAAA;AAGd,EAAA;AACwB,oBAAA;AACzB,oBAAA;AAClB,EAAA;AAEJ;AAEwB;AJ0FoC;AACA;AKxDxD;AAjDqD;AACzB,EAAA;AACtB,IAAA;AACkD,IAAA;AAC1D,EAAA;AACuB,EAAA;AACf,IAAA;AACkD,IAAA;AAC1D,EAAA;AACwB,EAAA;AAChB,IAAA;AACkD,IAAA;AAC1D,EAAA;AAC0B,EAAA;AAClB,IAAA;AACkD,IAAA;AAC1D,EAAA;AAC2B,EAAA;AACnB,IAAA;AACkD,IAAA;AAC1D,EAAA;AACwB,EAAA;AAChB,IAAA;AACkD,IAAA;AAC1D,EAAA;AACyB,EAAA;AACjB,IAAA;AACkD,IAAA;AAC1D,EAAA;AACF;AAE2C;AACnC,EAAA;AACkD,EAAA;AAC1D;AAQoG;AACpD,EAAA;AACJ,EAAA;AACQ,EAAA;AACM,EAAA;AAGnC,EAAA;AACQ,oBAAA;AACT,oBAAA;AAClB,EAAA;AAEJ;AAE6B;ALgG+B;AACA;AMxGhD;AAxBoD;AACpB,EAAA;AACjC,IAAA;AACT,EAAA;AACuD,EAAA;AACzD;AAYsE;AAE/C,EAAA;AAGA,IAAA;AAYF,oBAAA;AACG,sBAAA;AAGA,sBAAA;AAClB,IAAA;AACF,EAAA;AAEJ;AAiBoE;AAClE,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACI;AACsC,EAAA;AACM,EAAA;AAG3B,EAAA;AAEF,oBAAA;AAEG,sBAAA;AACe,MAAA;AAEjC,IAAA;AAOe,oBAAA;AACgB,sBAAA;AACb,sBAAA;AAEW,sBAAA;AACA,MAAA;AAC7B,IAAA;AAEe,oBAAA;AACc,sBAAA;AACA,MAAA;AAC7B,IAAA;AACF,EAAA;AAEJ;AAEgC;ANwE4B;AACA;AO3NrC;AAyIX;AA1HQ;AAEW;AAmEiC;AACnD,EAAA;AACX,EAAA;AACiB,EAAA;AACE,EAAA;AACF,EAAA;AACjB,EAAA;AACW,EAAA;AACX,EAAA;AACA,EAAA;AACI;AACoD,EAAA;AAC9B,IAAA;AAC8B,IAAA;AAC7B,IAAA;AAC3B,EAAA;AAE4D,EAAA;AAClC,IAAA;AAC8B,IAAA;AAC7B,IAAA;AAC3B,EAAA;AAEqC,EAAA;AACX,IAAA;AACwB,IAAA;AACvB,IAAA;AAC3B,EAAA;AAEsC,EAAA;AACZ,IAAA;AACO,IAAA;AACP,MAAA;AACjB,MAAA;AACE,MAAA;AAAA;AAEsB,MAAA;AAC/B,IAAA;AACmC,IAAA;AACrC,EAAA;AAEgD,EAAA;AAG3B,EAAA;AACS,IAAA;AACyB,MAAA;AAER,MAAA;AAGX,MAAA;AAEX,wBAAA;AACU,UAAA;AACvBD,0BAAAA;AAAC,YAAA;AAAA,YAAA;AACY,cAAA;AAC8B,cAAA;AAC5B,cAAA;AACb,cAAA;AACU,cAAA;AACc,cAAA;AACKA,cAAAA;AAA8C,YAAA;AAC7E,UAAA;AACF,QAAA;AAGe,wBAAA;AACE,0BAAA;AACZ,YAAA;AAAA,YAAA;AAEiC,cAAA;AACY,cAAA;AACjC,cAAA;AACgC,cAAA;AACJ,cAAA;AACvC,cAAA;AACW,cAAA;AACK,gBAAA;AAAA;AAED,gBAAA;AACf,cAAA;AAAA,YAAA;AAEJ,UAAA;AACAA,0BAAAA;AAAC,YAAA;AAAA,YAAA;AACM,cAAA;AACG,cAAA;AACH,cAAA;AAC6B,cAAA;AAClC,cAAA;AACW,cAAA;AACO,cAAA;AAAwD,YAAA;AAC5E,UAAA;AACF,QAAA;AACF,MAAA;AAEH,IAAA;AAGc,oBAAA;AACbA,sBAAAA;AAAC,QAAA;AAAA,QAAA;AACM,UAAA;AACG,UAAA;AACH,UAAA;AACoB,UAAA;AACzB,UAAA;AACU,UAAA;AACgB,UAAA;AAEzB,UAAA;AAAA,QAAA;AACH,MAAA;AAEEA,MAAAA;AAAC,QAAA;AAAA,QAAA;AACM,UAAA;AACG,UAAA;AACH,UAAA;AACwB,UAAA;AAC7B,UAAA;AACU,UAAA;AACU,UAAA;AAEnB,UAAA;AAAA,QAAA;AACH,MAAA;AAEJ,IAAA;AACF,EAAA;AAEJ;AAE8B;APoI8B;AACA;AQhW1C;AAiEZ;AAxC6B;AACjC,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AAC0B;AAC6B,EAAA;AAEH,EAAA;AAChC,IAAA;AACE,IAAA;AAChB,IAAA;AACa,MAAA;AACf,IAAA;AACqB,MAAA;AACvB,IAAA;AACF,EAAA;AAE4C,EAAA;AACxB,IAAA;AACX,IAAA;AACT,EAAA;AAGEC,EAAAA;AAAC,IAAA;AAAA,IAAA;AACY,MAAA;AACA,MAAA;AACT,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACF,MAAA;AAGA,MAAA;AAAe,wBAAA;AACC,0BAAA;AAGD,0BAAA;AAGf,QAAA;AAGAD,wBAAAA;AAAC,UAAA;AAAA,UAAA;AACW,YAAA;AACsB,YAAA;AAG9B,YAAA;AACiB,8BAAA;AACA,8BAAA;AAGjB,YAAA;AACoB,8BAAA;AAClBA,8BAAAA;AAAC,gBAAA;AAAA,gBAAA;AACS,kBAAA;AACC,kBAAA;AACC,kBAAA;AACuB,kBAAA;AAE3B,kBAAA;AAAA,gBAAA;AACR,cAAA;AAGF,YAAA;AAKkB,8BAAA;AAGA,8BAAA;AAGlB,YAAA;AAAA,UAAA;AAEJ,QAAA;AAAA,MAAA;AAAA,IAAA;AACF,EAAA;AAEJ;ARyT4D;AACA;AS3ajB;AA8LrCC;AA9JgC;AACpC,EAAA;AACQ,EAAA;AACR,EAAA;AACA,EAAA;AACa,EAAA;AACb,EAAA;AACU,EAAA;AACV,EAAA;AACsB,EAAA;AACO;AACvB,EAAA;AACJ,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AAC+B,EAAA;AAGI,EAAA;AACQ,EAAA;AACa,EAAA;AAEN,EAAA;AAI9B,EAAA;AAEK,IAAA;AACI,MAAA;AAC3B,MAAA;AACF,IAAA;AAGuB,IAAA;AAK8B,IAAA;AACA,IAAA;AAGF,IAAA;AAGb,IAAA;AAIkB,IAAA;AAE5B,MAAA;AAEoB,MAAA;AAErB,IAAA;AAEM,IAAA;AAEI,MAAA;AAEE,MAAA;AAGH,MAAA;AAIjB,MAAA;AACoB,QAAA;AAC/B,MAAA;AACD,IAAA;AAE6B,MAAA;AACpC,IAAA;AACC,EAAA;AACD,IAAA;AACA,IAAA;AACM,IAAA;AACA,IAAA;AACA,IAAA;AACN,IAAA;AACD,EAAA;AAGwB,EAAA;AACe,IAAA;AAEU,MAAA;AAC5C,QAAA;AACF,MAAA;AAGuC,MAAA;AAEnC,MAAA;AACkB,QAAA;AAGwB,QAAA;AAC1C,UAAA;AACF,QAAA;AAGkC,QAAA;AACZ,UAAA;AACpB,UAAA;AACF,QAAA;AAGwB,QAAA;AAClB,UAAA;AAC0C,YAAA;AAGJ,YAAA;AAClB,cAAA;AACtB,YAAA;AACc,UAAA;AACkC,YAAA;AAClD,UAAA;AACF,QAAA;AACA,MAAA;AAE0C,QAAA;AAC5C,MAAA;AACF,IAAA;AACmC,IAAA;AACrC,EAAA;AAEuD,EAAA;AACvC,oBAAA;AACK,IAAA;AACrB,EAAA;AAE4B,EAAA;AACR,IAAA;AACN,oBAAA;AACd,EAAA;AAIqB,EAAA;AACME,IAAAA;AAC3B,EAAA;AAE4C,EAAA;AAGvB,EAAA;AAEF,oBAAA;AACE,sBAAA;AAGR,MAAA;AAUT,IAAA;AAIG,oBAAA;AACE,MAAA;AAAA,MAAA;AAEC,QAAA;AACmC,QAAA;AACH,QAAA;AACV,QAAA;AACe,QAAA;AACJ,QAAA;AAAA,MAAA;AANvB,MAAA;AAShB,IAAA;AACF,EAAA;AAEJ;ATwU4D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-G3MH262S.cjs","sourcesContent":[null,"/**\n * SoftwareInfo Component\n *\n * Displays software name with optional vendor information below it.\n * Part of the ODS (OpenFrame Design System) platform components.\n *\n * @example\n * ```tsx\n * <SoftwareInfo name=\"Visual Studio Code\" vendor=\"Microsoft\" />\n * <SoftwareInfo name=\"Chrome\" /> // Without vendor\n * ```\n */\n\nimport type React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface SoftwareInfoProps {\n /** Software name (required) */\n name: string;\n /** Software vendor (optional) */\n vendor?: string;\n /** Software version (optional) */\n version?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\nexport const SoftwareInfo: React.FC<SoftwareInfoProps> = ({ name, vendor, version, className }) => {\n return (\n <div className={cn('flex flex-col gap-1', className)}>\n <div className=\"flex items-center gap-2\">\n <div className=\"text-ods-text-primary text-h4\">{name}</div>\n {version && (\n <div className=\"rounded bg-ods-bg-surface px-2 py-1 text-ods-text-secondary text-h6\">{version}</div>\n )}\n </div>\n {vendor && <div className=\"text-ods-text-secondary text-h6\">{vendor}</div>}\n </div>\n );\n};\n\nSoftwareInfo.displayName = 'SoftwareInfo';\n","/**\n * SoftwareSourceBadge Component\n *\n * Displays a badge for software source types from Fleet MDM.\n * Supports all osquery software source types with appropriate styling.\n *\n * Fleet MDM Software Sources:\n * - apps: macOS Applications\n * - chrome_extensions: Chrome Browser Extensions\n * - firefox_addons: Firefox Browser Extensions\n * - safari_extensions: Safari Browser Extensions\n * - ie_extensions: Internet Explorer Extensions\n * - vscode_extensions: VS Code Extensions\n * - atom_packages: Atom Packages\n * - homebrew_packages: Homebrew Packages (macOS)\n * - npm_packages: NPM Packages\n * - python_packages: Python Packages\n * - apt_sources: APT Packages (Debian/Ubuntu)\n * - deb_packages: DEB Packages\n * - rpm_packages: RPM Packages (Red Hat/CentOS)\n * - yum_sources: YUM Packages\n * - portage_packages: Portage Packages (Gentoo)\n * - chocolatey_packages: Chocolatey Packages (Windows)\n * - programs: Windows Programs\n * - pkg_packages: PKG Packages\n *\n * @example\n * ```tsx\n * <SoftwareSourceBadge source=\"apps\" />\n * <SoftwareSourceBadge source=\"chrome_extensions\" />\n * <SoftwareSourceBadge source=\"python_packages\" />\n * ```\n */\n\nimport type React from 'react';\nimport { cn } from '../../utils/common';\nimport { PackageIcon, WindowsIcon, MacOSIcon, LinuxIcon } from '../icons';\n\nexport type SoftwareSource =\n | 'apps'\n | 'chrome_extensions'\n | 'firefox_addons'\n | 'safari_extensions'\n | 'ie_extensions'\n | 'vscode_extensions'\n | 'atom_packages'\n | 'homebrew_packages'\n | 'npm_packages'\n | 'python_packages'\n | 'apt_sources'\n | 'deb_packages'\n | 'rpm_packages'\n | 'yum_sources'\n | 'portage_packages'\n | 'chocolatey_packages'\n | 'programs'\n | 'pkg_packages';\n\nexport interface SoftwareSourceBadgeProps {\n /** Software source type from Fleet MDM */\n source: SoftwareSource;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Maps source types to human-readable labels and icons\n */\nconst sourceConfig: Record<SoftwareSource, { label: string; icon: React.ReactNode }> = {\n apps: { label: 'App', icon: <MacOSIcon className=\"h-4 w-4\" /> },\n chrome_extensions: { label: 'Chrome', icon: <PackageIcon className=\"h-4 w-4\" /> },\n firefox_addons: { label: 'Firefox', icon: <PackageIcon className=\"h-4 w-4\" /> },\n safari_extensions: { label: 'Safari', icon: <PackageIcon className=\"h-4 w-4\" /> },\n ie_extensions: { label: 'IE', icon: <PackageIcon className=\"h-4 w-4\" /> },\n vscode_extensions: { label: 'VS Code', icon: <PackageIcon className=\"h-4 w-4\" /> },\n atom_packages: { label: 'Atom', icon: <PackageIcon className=\"h-4 w-4\" /> },\n homebrew_packages: { label: 'Homebrew', icon: <MacOSIcon className=\"h-4 w-4\" /> },\n npm_packages: { label: 'NPM', icon: <PackageIcon className=\"h-4 w-4\" /> },\n python_packages: { label: 'Python', icon: <PackageIcon className=\"h-4 w-4\" /> },\n apt_sources: { label: 'APT', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n deb_packages: { label: 'DEB', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n rpm_packages: { label: 'RPM', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n yum_sources: { label: 'YUM', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n portage_packages: { label: 'Portage', icon: <LinuxIcon className=\"h-4 w-4\" /> },\n chocolatey_packages: { label: 'Chocolatey', icon: <WindowsIcon className=\"h-4 w-4\" /> },\n programs: { label: 'Windows', icon: <WindowsIcon className=\"h-4 w-4\" /> },\n pkg_packages: { label: 'PKG', icon: <PackageIcon className=\"h-4 w-4\" /> },\n};\n\nexport const SoftwareSourceBadge: React.FC<SoftwareSourceBadgeProps> = ({ source, className }) => {\n const config = sourceConfig[source] || { label: source, icon: <PackageIcon className=\"h-4 w-4\" /> };\n\n return (\n <span className={cn('inline-flex items-center gap-2 text-ods-text-primary', className)}>\n {config.icon}\n {config.label}\n </span>\n );\n};\n\nSoftwareSourceBadge.displayName = 'SoftwareSourceBadge';\n","/**\n * CveLink Component\n *\n * Displays a CVE ID with an external link icon that links to the NIST NVD database.\n * Part of the ODS (OpenFrame Design System) platform components.\n *\n * @example\n * ```tsx\n * <CveLink cveId=\"CVE-2024-1234\" />\n * ```\n */\n\nimport type React from 'react';\nimport { cn } from '../../utils/cn';\nimport { CustomExternalLinkIcon } from '../icons';\n\nexport interface CveLinkProps {\n /** CVE ID (e.g., \"CVE-2024-1234\") */\n cveId: string;\n /** Additional CSS classes */\n className?: string;\n}\n\nexport const CveLink: React.FC<CveLinkProps> = ({ cveId, className }) => {\n const nistUrl = `https://nvd.nist.gov/vuln/detail/${cveId}`;\n\n return (\n <a\n href={nistUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n 'group inline-flex items-center gap-2 text-ods-text-primary transition-colors text-code hover:text-ods-accent',\n className,\n )}\n >\n <span>{cveId}</span>\n <CustomExternalLinkIcon className=\"h-4 w-4 text-ods-text-secondary transition-colors group-hover:text-ods-accent\" />\n </a>\n );\n};\n\nCveLink.displayName = 'CveLink';\n","/**\n * ToolBadge Component\n *\n * Displays a tool type badge with icon for OpenFrame integrated tools.\n * Used in tables to show tool sources like Fleet MDM, MeshCentral, etc.\n *\n * @example\n * ```tsx\n * <ToolBadge toolType=\"OPENFRAME_RMM\" />\n * <ToolBadge toolType=\"FLEET\" />\n * <ToolBadge toolType=\"MESHCENTRAL\" />\n * ```\n */\n\nimport type React from 'react';\nimport type { ToolType } from '../../types/tool.types';\nimport { cn } from '../../utils/cn';\nimport { getToolLabel } from '../../utils/tool-utils';\nimport { ToolIcon } from '../tool-icon';\n\nexport type { ToolType } from '../../types/tool.types';\n\nexport interface ToolBadgeProps {\n /** Tool type */\n toolType: ToolType;\n /** Additional CSS classes */\n className?: string;\n iconClassName?: string;\n}\n\nexport const ToolBadge: React.FC<ToolBadgeProps> = ({ toolType, className, iconClassName }) => {\n const label = getToolLabel(toolType);\n\n return (\n <div className={cn('flex items-center gap-1 text-ods-text-secondary', className)}>\n <ToolIcon toolType={toolType} className={iconClassName} size={16} />\n <span className=\"text-ods-text-primary text-h4\">{label}</span>\n </div>\n );\n};\n\nToolBadge.displayName = 'ToolBadge';\n","/**\n * ShellTypeBadge Component\n *\n * Displays a badge for shell/script types with appropriate icon and label.\n * Supports all RMM shell types.\n */\n\nimport type React from 'react';\nimport { type ShellType, ShellTypeValues } from '../../types/shell.types';\nimport { cn } from '../../utils/cn';\nimport { getShellLabel } from '../../utils/shell-utils';\nimport { BashIcon, CmdIcon, DenoIcon, NushellIcon, ShellIcon } from '../icons';\nimport { PowershellLogoGreyIcon } from '../icons-v2-generated/brand-logos/powershell-logo-grey-icon';\nimport { PythonLogoIcon } from '../icons-v2-generated/brand-logos/python-logo-icon';\n\n/**\n * Shell icon configuration with typed mapping\n */\ninterface ShellIconConfig {\n icon: React.ComponentType<{ size?: number; color?: string; className?: string }>;\n props: { size: number } & ({ className: string } | { color: string });\n}\n\n/**\n * Typed mapping of shell types to their icon configurations\n * Using Record<ShellType, ...> ensures all shell types are covered\n */\nconst shellIconMap: Record<ShellType, ShellIconConfig> = {\n [ShellTypeValues.POWERSHELL]: {\n icon: PowershellLogoGreyIcon,\n props: { size: 16, className: 'text-ods-text-secondary' },\n },\n [ShellTypeValues.CMD]: {\n icon: CmdIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n [ShellTypeValues.BASH]: {\n icon: BashIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n [ShellTypeValues.PYTHON]: {\n icon: PythonLogoIcon,\n props: { size: 16, className: 'text-ods-text-secondary' },\n },\n [ShellTypeValues.NUSHELL]: {\n icon: NushellIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n [ShellTypeValues.DENO]: {\n icon: DenoIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n [ShellTypeValues.SHELL]: {\n icon: ShellIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n },\n} as const;\n\nconst defaultIconConfig: ShellIconConfig = {\n icon: ShellIcon,\n props: { size: 16, color: 'var(--color-text-secondary)' },\n};\n\nexport interface ShellTypeBadgeProps {\n shellType: ShellType;\n className?: string;\n iconClassName?: string;\n}\n\nexport const ShellTypeBadge: React.FC<ShellTypeBadgeProps> = ({ shellType, className, iconClassName }) => {\n const normalizedType = shellType?.toUpperCase() as ShellType;\n const label = getShellLabel(normalizedType);\n const { icon: IconComponent, props: iconProps } = shellIconMap[normalizedType] ?? defaultIconConfig;\n const defaultIconClassName = 'className' in iconProps ? iconProps.className : undefined;\n\n return (\n <div className={cn('flex items-center gap-1', className)}>\n <IconComponent size={16} className={cn(defaultIconClassName, iconClassName)} />\n <span className=\"text-ods-text-primary text-h4\">{label}</span>\n </div>\n );\n};\n\nShellTypeBadge.displayName = 'ShellTypeBadge';\n","/**\n * ScriptInfoSection Component\n *\n * Displays script information in a card with header (title, description)\n * and detail cells (shell type, supported platforms, category, author).\n * Responsive layout: stacks cells on mobile, shows grid on desktop.\n */\n\nimport type React from 'react';\nimport Image from '../../embed-shims/next-image';\nimport { cn } from '../../utils/cn';\nimport { nameInitials } from '../../utils/format';\nimport { getOSLabel } from '../../utils/os-utils';\nimport { getShellLabel } from '../../utils/shell-utils';\n\n/**\n * Props for author avatar display\n */\nexport interface ScriptAuthor {\n /** Author name */\n name: string;\n /** Author initials (used when no photo) */\n initials?: string;\n /** URL to author's photo */\n photoUrl?: string;\n}\n\n/**\n * Props for ScriptInfoSection component\n */\nexport interface ScriptInfoSectionProps {\n /** Script title/name */\n headline: string;\n /** Script description */\n subheadline?: string;\n /** Shell type (POWERSHELL, BASH, CMD, etc.) */\n shellType?: string;\n /** Array of supported platform strings (windows, darwin, linux, etc.) */\n supportedPlatforms?: string[];\n /** Script category */\n category: string;\n /** Author information */\n author?: ScriptAuthor;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Formats supported platforms array into a display string\n * @param platforms - Array of platform strings (e.g., ['windows', 'darwin', 'linux'])\n * @returns Formatted string (e.g., 'Windows, macOS, Linux')\n */\nfunction formatSupportedPlatforms(platforms?: string[]): string {\n if (!platforms || platforms.length === 0) {\n return 'All Platforms';\n }\n return platforms.map(platform => getOSLabel(platform)).join(', ');\n}\n\n/**\n * InfoCell - Single info cell with label and value\n */\ninterface InfoCellProps {\n label: string;\n value: string;\n avatar?: ScriptAuthor;\n className?: string;\n}\n\nfunction InfoCell({ label, value, avatar, className }: InfoCellProps) {\n return (\n <div className={cn('flex min-w-0 items-center gap-2', className)}>\n {/* Avatar for author cell */}\n {avatar && (\n <div className=\"relative size-8 shrink-0 overflow-hidden rounded-full border border-ods-border bg-ods-bg\">\n {avatar.photoUrl ? (\n <Image src={avatar.photoUrl} alt={avatar.name} className=\"object-cover\" fill sizes=\"32px\" unoptimized />\n ) : (\n <div className=\"flex size-full items-center justify-center text-ods-text-secondary text-h6\">\n {avatar.initials || nameInitials(avatar.name)}\n </div>\n )}\n </div>\n )}\n\n {/* Text content */}\n <div className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-ods-text-primary text-h4\" title={value}>\n {value}\n </span>\n <span className=\"truncate text-ods-text-secondary text-h6\">{label}</span>\n </div>\n </div>\n );\n}\n\n/**\n * ScriptInfoSection - Displays script information in a structured card\n *\n * @example\n * ```tsx\n * <ScriptInfoSection\n * title=\"System Backup Script\"\n * description=\"Comprehensive Linux system backup script...\"\n * shellType=\"BASH\"\n * supportedPlatforms={['linux']}\n * category=\"System Maintenance\"\n * author={{ name: 'John Doe', photoUrl: '/avatars/john.jpg' }}\n * />\n * ```\n */\nexport const ScriptInfoSection: React.FC<ScriptInfoSectionProps> = ({\n headline,\n subheadline,\n shellType,\n supportedPlatforms,\n category,\n author,\n className,\n}) => {\n const shellLabel = getShellLabel(shellType);\n const platformsLabel = formatSupportedPlatforms(supportedPlatforms);\n\n return (\n <div className={cn('overflow-hidden rounded-[6px] border border-ods-border bg-ods-card', className)}>\n {/* Header row with title and description */}\n <div className=\"border-b border-ods-border p-4\">\n <div className=\"flex flex-col gap-1\">\n <h3 className=\"text-ods-text-primary text-h4\">{headline}</h3>\n {subheadline && <p className=\"break-words text-ods-text-secondary text-h6\">{subheadline}</p>}\n </div>\n </div>\n\n {/* Details section with info cells\n - Mobile/Tablet (<lg): 2x2 grid with divider between rows\n - Desktop (lg+): 4 columns in single row\n */}\n {/* First row: Shell Type, Supported Platforms */}\n <div className=\"grid grid-cols-2 gap-4 border-b border-ods-border px-4 py-4 lg:grid-cols-4 lg:border-b-0\">\n <InfoCell label=\"Shell Type\" value={shellLabel} />\n <InfoCell label=\"Supported Platforms\" value={platformsLabel} />\n {/* Desktop only: Category and Author in same row */}\n <InfoCell label=\"Category\" value={category} className=\"hidden lg:flex\" />\n {author && <InfoCell label=\"Added by\" value={author.name} avatar={author} className=\"hidden lg:flex\" />}\n </div>\n {/* Second row (mobile/tablet only): Category, Author */}\n <div className=\"grid grid-cols-2 gap-4 px-4 py-4 lg:hidden\">\n <InfoCell label=\"Category\" value={category} />\n {author && <InfoCell label=\"Added by\" value={author.name} avatar={author} />}\n </div>\n </div>\n );\n};\n\nScriptInfoSection.displayName = 'ScriptInfoSection';\n","/**\n * ScriptArguments Component\n *\n * Displays and manages script arguments as key-value pairs.\n * Each argument has a name (key) and value input field with delete button.\n * Includes an \"Add Script Argument\" button to add new entries.\n */\n\nimport { Trash2 } from 'lucide-react';\nimport type React from 'react';\nimport { cn } from '../../utils/cn';\nimport { LockIcon, PlusCircleIcon } from '../icons-v2-generated';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\n\n/**\n * What an untouched stored secret shows in its value field.\n *\n * Rendered as the field's PLACEHOLDER, never as its value: a mask held in\n * `value` is indistinguishable from something the user typed, and would be\n * submitted back as the secret itself.\n */\nconst SECRET_MASK = '**********';\n\nconst STORED_SECRET_KEY_HINT = \"A stored secret can't be renamed — delete it and add a new one\";\n\n/**\n * Single script argument with key and value\n */\nexport interface ScriptArgument {\n /** Unique identifier for the argument */\n id: string;\n /** Argument name/key */\n key: string;\n /** Argument value (empty string for flag-type arguments) */\n value: string;\n /**\n * A secret pair: the key carries a lock and the value is typed as a password.\n * Meaningful for environment variables only.\n */\n secret?: boolean;\n /**\n * The server holds a value for this secret and does not send it back. While\n * `value` is empty the field shows a mask, so empty means \"keep what is\n * stored\" and typing replaces it.\n *\n * The stored value is bound to the key, which is therefore read-only:\n * renaming would leave the old name holding the secret and the new one\n * holding nothing.\n */\n hasStoredValue?: boolean;\n}\n\n/**\n * Props for ScriptArguments component\n */\nexport interface ScriptArgumentsProps {\n /** Array of script arguments */\n arguments: ScriptArgument[];\n /** Callback when arguments change */\n onArgumentsChange?: (args: ScriptArgument[]) => void;\n /** Placeholder for key input */\n keyPlaceholder?: string;\n /** Placeholder for value input */\n valuePlaceholder?: string;\n /** Label for the add button */\n addButtonLabel?: string;\n /** Label for a second add button that appends a secret pair. Omit to not offer secrets. */\n addSecretButtonLabel?: string;\n /** Whether the component is disabled */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Label for the title input */\n titleLabel: string;\n}\n\n/**\n * ScriptArguments - Displays and manages script arguments\n *\n * @example\n * ```tsx\n * <ScriptArguments\n * arguments={[\n * { id: '1', key: 'port', value: '3000' },\n * { id: '2', key: 'verbose', value: '' },\n * ]}\n * onArgumentsChange={(args) => setArguments(args)}\n * />\n * ```\n */\nexport const ScriptArguments: React.FC<ScriptArgumentsProps> = ({\n arguments: args,\n onArgumentsChange,\n keyPlaceholder = 'Enter Key',\n valuePlaceholder = 'Enter Value (empty=flag)',\n addButtonLabel = 'Add Script Argument',\n addSecretButtonLabel,\n disabled = false,\n className,\n titleLabel,\n}) => {\n const handleKeyChange = (id: string, newKey: string) => {\n if (!onArgumentsChange) return;\n const updated = args.map(arg => (arg.id === id ? { ...arg, key: newKey } : arg));\n onArgumentsChange(updated);\n };\n\n const handleValueChange = (id: string, newValue: string) => {\n if (!onArgumentsChange) return;\n const updated = args.map(arg => (arg.id === id ? { ...arg, value: newValue } : arg));\n onArgumentsChange(updated);\n };\n\n const handleDelete = (id: string) => {\n if (!onArgumentsChange) return;\n const updated = args.filter(arg => arg.id !== id);\n onArgumentsChange(updated);\n };\n\n const handleAdd = (secret = false) => {\n if (!onArgumentsChange) return;\n const newArg: ScriptArgument = {\n id: crypto.randomUUID(),\n key: '',\n value: '',\n // Only set on a secret, so a plain pair keeps the shape it always had.\n ...(secret && { secret: true }),\n };\n onArgumentsChange([...args, newArg]);\n };\n\n const isFirstRow = (index: number) => index === 0;\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {args.map((arg, index) => {\n const isStoredSecret = Boolean(arg.secret && arg.hasStoredValue);\n // The mask stands for the stored value, so it goes once the user types a replacement.\n const showsMask = isStoredSecret && !arg.value;\n\n return (\n <div key={arg.id} className=\"flex w-full items-end gap-2\">\n {/* Key input - with label only on first row */}\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n {isFirstRow(index) && <Label spacing=\"tight\">{titleLabel}</Label>}\n <Input\n value={arg.key}\n onChange={e => handleKeyChange(arg.id, e.target.value)}\n placeholder={keyPlaceholder}\n disabled={disabled}\n readOnly={isStoredSecret}\n title={isStoredSecret ? STORED_SECRET_KEY_HINT : undefined}\n startAdornment={arg.secret ? <LockIcon role=\"img\" aria-label=\"Secret\" /> : undefined}\n />\n </div>\n\n {/* Value input with delete button */}\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <Input\n // `new-password` keeps a password manager from filling a saved login into a secret.\n type={arg.secret ? 'password' : undefined}\n autoComplete={arg.secret ? 'new-password' : undefined}\n value={arg.value}\n onChange={e => handleValueChange(arg.id, e.target.value)}\n placeholder={showsMask ? SECRET_MASK : valuePlaceholder}\n disabled={disabled}\n className={cn(\n !arg.value && 'placeholder:text-ods-text-muted',\n // The mask reads as a value that is there, not as a prompt to fill one in.\n showsMask && '[&_input]:placeholder:text-ods-text-primary',\n )}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => handleDelete(arg.id)}\n disabled={disabled}\n aria-label=\"Delete argument\"\n leftIcon={<Trash2 className=\"size-4 md:size-6\" color=\"var(--color-error)\" />}\n />\n </div>\n </div>\n );\n })}\n\n {/* Add buttons - aligned left */}\n <div className=\"flex flex-wrap justify-start gap-[var(--spacing-system-xs)]\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={() => handleAdd()}\n disabled={disabled}\n className=\"self-start\"\n leftIcon={<PlusCircleIcon className=\"text-ods-text-secondary\" />}\n >\n {addButtonLabel}\n </Button>\n {addSecretButtonLabel && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"small\"\n onClick={() => handleAdd(true)}\n disabled={disabled}\n className=\"self-start\"\n leftIcon={<LockIcon className=\"text-ods-text-secondary\" />}\n >\n {addSecretButtonLabel}\n </Button>\n )}\n </div>\n </div>\n );\n};\n\nScriptArguments.displayName = 'ScriptArguments';\n","'use client';\n\nimport React from 'react';\nimport { cn } from '../../../utils/cn';\nimport { Button } from '../../ui/button';\nimport { InteractiveCard } from '../../ui/interactive-card';\nimport { StatusBadge } from '../../ui/status-badge';\n\nexport interface OnboardingStepCardProps {\n step: {\n id: string;\n title: string;\n description: string;\n actionIcon: (color?: string) => React.ReactNode;\n actionText: string;\n completedText: string;\n onAction: () => void | Promise<void>;\n onSkip?: () => void;\n };\n isCompleted: boolean;\n isSkipped: boolean;\n isCheckingCompletion: boolean;\n onAction: () => void | Promise<void>;\n onSkip: () => void;\n className?: string;\n}\n\nexport function OnboardingStepCard({\n step,\n isCompleted,\n isSkipped,\n isCheckingCompletion,\n onAction,\n onSkip,\n className,\n}: OnboardingStepCardProps) {\n const [isProcessing, setIsProcessing] = React.useState(false);\n\n const handleAction = async (e: React.MouseEvent) => {\n e.stopPropagation();\n setIsProcessing(true);\n try {\n await onAction();\n } finally {\n setIsProcessing(false);\n }\n };\n\n const handleSkip = (e: React.MouseEvent) => {\n e.stopPropagation();\n onSkip();\n };\n\n return (\n <InteractiveCard\n clickable={false}\n className={cn(\n 'rounded-[6px] border border-ods-border bg-ods-card',\n 'flex flex-col md:flex-row',\n 'min-h-[80px] md:h-[80px]',\n 'items-start md:items-center',\n 'gap-3 md:gap-4',\n 'px-4 py-4 md:py-0',\n className,\n )}\n >\n {/* Left column - content */}\n <div className=\"flex w-full min-w-0 flex-1 flex-col justify-center gap-1 md:w-auto\">\n <h3 className=\"truncate text-ods-text-primary text-h4\" title={step.title}>\n {step.title}\n </h3>\n <p className=\"h-[20px] truncate text-ods-text-secondary text-h6\" title={step.description}>\n {step.description}\n </p>\n </div>\n\n {/* Right column - action buttons, completed badge, or skipped badge */}\n <div\n className=\"flex w-full shrink-0 items-center justify-start gap-2 md:w-auto md:justify-end\"\n onClick={e => e.stopPropagation()}\n >\n {isCheckingCompletion ? (\n <>\n <div className=\"h-[32px] w-[100px] animate-pulse rounded-[6px] bg-ods-border\" />\n <div className=\"h-[32px] w-[120px] animate-pulse rounded-[6px] bg-ods-border\" />\n </>\n ) : isCompleted ? (\n <>\n <StatusBadge text=\"COMPLETED\" variant=\"card\" colorScheme=\"success\" />\n <Button\n variant=\"outline\"\n onClick={handleAction}\n disabled={isProcessing}\n leftIcon={step.actionIcon('white')}\n >\n {step.completedText}\n </Button>\n </>\n ) : isSkipped ? (\n <>\n <StatusBadge text=\"SKIPPED\" variant=\"card\" colorScheme=\"default\" />\n </>\n ) : (\n <>\n <Button variant=\"outline\" onClick={handleSkip}>\n Skip Step\n </Button>\n <Button variant=\"accent\" onClick={handleAction} disabled={isProcessing} leftIcon={step.actionIcon('black')}>\n {step.actionText}\n </Button>\n </>\n )}\n </div>\n </InteractiveCard>\n );\n}\n","'use client';\n\nimport React, { useRef, useCallback } from 'react';\nimport { useOnboardingState, type OnboardingStepConfig } from '../../../hooks/ui/use-onboarding-state';\nimport { cn } from '../../../utils/cn';\nimport { SECTION_HEADING_CLASS } from '../../layout/page-heading';\nimport { Button } from '../../ui/button';\nimport { OnboardingStepCard } from './onboarding-step-card';\n\nexport interface OnboardingWalkthroughProps {\n steps: OnboardingStepConfig[];\n /** Heading above the steps. Defaults to \"Get Started\". */\n title?: string;\n /**\n * What to render once the walkthrough is dismissed. Receives `restart`,\n * which clears every completed/skipped step and shows the walkthrough\n * again. Omitted: a dismissed walkthrough renders nothing.\n */\n renderDismissed?: (restart: () => void) => React.ReactNode;\n onDismiss?: () => void;\n storageKey?: string;\n className?: string;\n spacing?: string;\n /**\n * Completion status from hook-based checks (e.g., useOnboardingCompletion)\n * Object mapping step IDs to boolean completion status\n */\n completionStatus?: Record<string, boolean>;\n /**\n * Whether completion checks are still loading\n */\n isLoadingCompletion?: boolean;\n}\n\nexport function OnboardingWalkthrough({\n steps,\n title = 'Get Started',\n renderDismissed,\n onDismiss,\n storageKey = 'openframe-onboarding-state',\n className,\n spacing = 'space-y-4',\n completionStatus,\n isLoadingCompletion = false,\n}: OnboardingWalkthroughProps) {\n const {\n state,\n markComplete,\n markSkipped,\n dismissOnboarding,\n resetOnboarding,\n isStepComplete,\n isStepSkipped,\n allStepsComplete,\n markMultipleComplete,\n } = useOnboardingState(storageKey);\n\n // Refs to prevent race conditions - ALL refs must be declared before any conditional returns\n const hasAutoMarkedRef = useRef(false);\n const autoMarkingInProgressRef = useRef(false);\n const lastCompletionStatusRef = useRef<string | null>(null);\n // Ref to track in-flight action handlers - moved here to be before conditional return\n const actionInProgressRef = useRef<Set<string>>(new Set());\n\n // Sync completion status from hooks to localStorage\n // Uses refs to prevent duplicate calls and race conditions\n React.useEffect(() => {\n // Skip if still loading\n if (isLoadingCompletion) {\n hasAutoMarkedRef.current = false; // Reset when loading starts\n return;\n }\n\n // Skip if no completion status\n if (!completionStatus) return;\n\n // Create a stable key from completion status to detect actual changes.\n // An empty state (first load, or after a restart) is keyed by when it was\n // written, so a restart applies the same status again.\n const isFreshState = state.completedSteps.length === 0 && state.skippedSteps.length === 0;\n const statusKey = `${JSON.stringify(completionStatus)}|${isFreshState ? state.lastUpdated : ''}`;\n\n // Skip if we've already processed this exact status\n if (lastCompletionStatusRef.current === statusKey) return;\n\n // Skip if auto-marking is currently in progress\n if (autoMarkingInProgressRef.current) return;\n\n // Find steps that need to be marked complete\n // Read directly from state to avoid stale closure issues\n const completedStepIds = Object.entries(completionStatus)\n .filter(([stepId, isComplete]) => {\n if (!isComplete) return false;\n // Check against current state, not the callback\n return !state.completedSteps.includes(stepId);\n })\n .map(([stepId]) => stepId);\n\n if (completedStepIds.length > 0) {\n // Mark as in progress to prevent concurrent calls\n autoMarkingInProgressRef.current = true;\n\n markMultipleComplete(completedStepIds);\n\n // Update the last processed status key\n lastCompletionStatusRef.current = statusKey;\n\n // Reset the in-progress flag after a short delay\n // This prevents rapid successive calls while allowing future updates\n setTimeout(() => {\n autoMarkingInProgressRef.current = false;\n }, 100);\n } else {\n // Even if no steps to mark, update the status key to prevent re-processing\n lastCompletionStatusRef.current = statusKey;\n }\n }, [\n completionStatus,\n isLoadingCompletion,\n state.completedSteps,\n state.skippedSteps,\n state.lastUpdated,\n markMultipleComplete,\n ]);\n\n // useCallback must be called unconditionally (before any early returns)\n const handleStepAction = useCallback(\n async (step: OnboardingStepConfig) => {\n // Prevent duplicate action handling for the same step\n if (actionInProgressRef.current.has(step.id)) {\n return;\n }\n\n // Mark as in progress\n actionInProgressRef.current.add(step.id);\n\n try {\n await step.onAction();\n\n // Skip if already completed (could have been auto-marked while action was running)\n if (state.completedSteps.includes(step.id)) {\n return;\n }\n\n // Auto-mark Knowledge Base as complete (no verification needed)\n if (step.id === 'knowledge-base') {\n markComplete(step.id);\n return;\n }\n\n // For other steps, re-check completion after action\n if (step.checkComplete) {\n try {\n const isComplete = await step.checkComplete();\n\n // Double-check it wasn't completed while we were checking\n if (isComplete && !state.completedSteps.includes(step.id)) {\n markComplete(step.id);\n }\n } catch (error) {\n console.error(`Error checking completion for \"${step.id}\":`, error);\n }\n }\n } finally {\n // Remove from in-progress set\n actionInProgressRef.current.delete(step.id);\n }\n },\n [state.completedSteps, markComplete],\n );\n\n const handleStepSkip = (step: OnboardingStepConfig) => {\n step.onSkip?.();\n markSkipped(step.id);\n };\n\n const handleDismiss = () => {\n dismissOnboarding();\n onDismiss?.();\n };\n\n // ALL hooks have been called above - now safe to do conditional returns\n // Don't render if dismissed\n if (state.dismissed) {\n return renderDismissed ? <>{renderDismissed(resetOnboarding)}</> : null;\n }\n\n const isAllComplete = allStepsComplete(steps);\n\n return (\n <div className={cn('w-full space-y-4', className)}>\n {/* Header - responsive: stacks on mobile */}\n <div className=\"flex flex-col items-start justify-between gap-3 md:flex-row md:items-center md:gap-0\">\n <h2 className={SECTION_HEADING_CLASS}>{title}</h2>\n\n {isLoadingCompletion ? (\n <div className=\"h-[48px] w-full animate-pulse rounded-[6px] bg-ods-border md:w-[160px]\" />\n ) : isAllComplete ? (\n <Button variant=\"accent\" onClick={handleDismiss} className=\"w-full md:w-auto\">\n Close Onboarding\n </Button>\n ) : (\n <Button variant=\"outline\" onClick={handleDismiss} className=\"w-full md:w-auto\">\n Skip Onboarding\n </Button>\n )}\n </div>\n\n {/* Step cards - no wrapper, direct rendering */}\n <div className={cn(spacing)}>\n {steps.map(step => (\n <OnboardingStepCard\n key={step.id}\n step={step}\n isCompleted={isStepComplete(step.id)}\n isSkipped={isStepSkipped(step.id)}\n isCheckingCompletion={isLoadingCompletion}\n onAction={() => handleStepAction(step)}\n onSkip={() => handleStepSkip(step)}\n />\n ))}\n </div>\n </div>\n );\n}\n"]}
@@ -8,18 +8,18 @@
8
8
 
9
9
 
10
10
 
11
- var _chunkT32BTPL5cjs = require('./chunk-T32BTPL5.cjs');
11
+ var _chunkSWOS3DDMcjs = require('./chunk-SWOS3DDM.cjs');
12
12
 
13
13
 
14
14
 
15
15
 
16
- var _chunkXF5TJ4P2cjs = require('./chunk-XF5TJ4P2.cjs');
16
+ var _chunkBJHM2OEYcjs = require('./chunk-BJHM2OEY.cjs');
17
17
 
18
18
 
19
19
 
20
20
 
21
21
 
22
- var _chunkLL35WZZScjs = require('./chunk-LL35WZZS.cjs');
22
+ var _chunkOD2WMUAOcjs = require('./chunk-OD2WMUAO.cjs');
23
23
 
24
24
 
25
25
 
@@ -110,14 +110,14 @@ function ContactForm({
110
110
  successToastMessage = "Redirecting you to join our community...",
111
111
  rescue: rescueForm = null
112
112
  } = {}) {
113
- const attachments = _chunkLL35WZZScjs.useChatAttachments.call(void 0, );
114
- const builtInSubmission = _chunkXF5TJ4P2cjs.useContactSubmission.call(void 0, {
113
+ const attachments = _chunkOD2WMUAOcjs.useChatAttachments.call(void 0, );
114
+ const builtInSubmission = _chunkBJHM2OEYcjs.useContactSubmission.call(void 0, {
115
115
  userId,
116
116
  successRedirectUrl,
117
117
  successToastMessage
118
118
  });
119
119
  const [customSubmitting, setCustomSubmitting] = _react.useState.call(void 0, false);
120
- const { honeypotInputProps, getSignals, resetSignals } = _chunkXF5TJ4P2cjs.useHumanitySignals.call(void 0, );
120
+ const { honeypotInputProps, getSignals, resetSignals } = _chunkBJHM2OEYcjs.useHumanitySignals.call(void 0, );
121
121
  const isSubmitting = onCustomSubmit ? customSubmitting : builtInSubmission.isSubmitting;
122
122
  const isSuccess = onCustomSubmit ? false : builtInSubmission.isSuccess;
123
123
  const form = _reacthookform.useForm.call(void 0, {
@@ -143,7 +143,7 @@ function ContactForm({
143
143
  ),
144
144
  [hideFields]
145
145
  );
146
- const rescue = _chunkXF5TJ4P2cjs.useRescuedForm.call(void 0, form, { rescue: rescueForm, fields: rescueFieldNames, getSignals });
146
+ const rescue = _chunkBJHM2OEYcjs.useRescuedForm.call(void 0, form, { rescue: rescueForm, fields: rescueFieldNames, getSignals });
147
147
  const handleFormSubmit = async (data) => {
148
148
  if (isSubmitting) return;
149
149
  if (attachmentsEnabled && attachments.hasInflightUploads) return;
@@ -181,7 +181,7 @@ function ContactForm({
181
181
  className: `flex h-full flex-col ${!noBorder ? "rounded-2xl border border-ods-border md:rounded-3xl" : ""} ${!noPadding ? "p-6 md:p-8 lg:p-10" : ""}`,
182
182
  children: [
183
183
  (title || subtitle) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-6 md:mb-8", children: [
184
- title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: `${_chunkLL35WZZScjs.SECTION_HEADING_CLASS} mb-3 md:mb-4`, children: title }),
184
+ title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: `${_chunkOD2WMUAOcjs.SECTION_HEADING_CLASS} mb-3 md:mb-4`, children: title }),
185
185
  subtitle && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-primary text-h4", children: subtitle })
186
186
  ] }),
187
187
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
@@ -194,13 +194,13 @@ function ContactForm({
194
194
  );
195
195
  }),
196
196
  className: "flex flex-grow flex-col space-y-4 md:space-y-6",
197
- ..._chunkT32BTPL5cjs.HUBSPOT_DO_NOT_COLLECT_FORM_PROPS,
197
+ ..._chunkSWOS3DDMcjs.HUBSPOT_DO_NOT_COLLECT_FORM_PROPS,
198
198
  children: [
199
199
  !showName && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", ...register("name") }),
200
200
  !showEmail && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", ...register("email") }),
201
201
  !showHelpCategory && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", ...register("helpCategory") }),
202
202
  !showMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { type: "hidden", ...register("message") }),
203
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.HoneypotField, { ...honeypotInputProps }),
203
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.HoneypotField, { ...honeypotInputProps }),
204
204
  extraTopField,
205
205
  showNameEmailRow && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6", children: [
206
206
  showName && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
@@ -252,17 +252,17 @@ function ContactForm({
252
252
  {
253
253
  control,
254
254
  name: "companySize",
255
- render: ({ field }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkT32BTPL5cjs.Select, { onValueChange: field.onChange, value: _nullishCoalesce(field.value, () => ( "")), children: [
255
+ render: ({ field }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkSWOS3DDMcjs.Select, { onValueChange: field.onChange, value: _nullishCoalesce(field.value, () => ( "")), children: [
256
256
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
257
- _chunkT32BTPL5cjs.SelectTrigger,
257
+ _chunkSWOS3DDMcjs.SelectTrigger,
258
258
  {
259
259
  id: "companySize",
260
260
  "aria-label": "Company Size",
261
261
  className: "h-12 border-ods-border bg-ods-card px-3 text-ods-text-primary",
262
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectValue, { placeholder: "Select company size" })
262
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectValue, { placeholder: "Select company size" })
263
263
  }
264
264
  ),
265
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectContent, { children: companySizeOptions.map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectItem, { value: opt, children: opt }, opt)) })
265
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectContent, { children: companySizeOptions.map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectItem, { value: opt, children: opt }, opt)) })
266
266
  ] })
267
267
  }
268
268
  ),
@@ -275,17 +275,17 @@ function ContactForm({
275
275
  {
276
276
  control,
277
277
  name: "referralSource",
278
- render: ({ field }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkT32BTPL5cjs.Select, { onValueChange: field.onChange, value: _nullishCoalesce(field.value, () => ( "")), children: [
278
+ render: ({ field }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkSWOS3DDMcjs.Select, { onValueChange: field.onChange, value: _nullishCoalesce(field.value, () => ( "")), children: [
279
279
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
280
- _chunkT32BTPL5cjs.SelectTrigger,
280
+ _chunkSWOS3DDMcjs.SelectTrigger,
281
281
  {
282
282
  id: "referralSource",
283
283
  "aria-label": "Referral Source",
284
284
  className: "h-12 border-ods-border bg-ods-card px-3 text-ods-text-primary",
285
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectValue, { placeholder: "Select an option" })
285
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectValue, { placeholder: "Select an option" })
286
286
  }
287
287
  ),
288
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectContent, { children: referralSourceOptions.map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectItem, { value: opt, children: opt }, opt)) })
288
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectContent, { children: referralSourceOptions.map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectItem, { value: opt, children: opt }, opt)) })
289
289
  ] })
290
290
  }
291
291
  ),
@@ -302,18 +302,18 @@ function ContactForm({
302
302
  {
303
303
  control,
304
304
  name: "helpCategory",
305
- render: ({ field }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkT32BTPL5cjs.Select, { onValueChange: field.onChange, value: _nullishCoalesce(field.value, () => ( "")), children: [
305
+ render: ({ field }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkSWOS3DDMcjs.Select, { onValueChange: field.onChange, value: _nullishCoalesce(field.value, () => ( "")), children: [
306
306
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
307
- _chunkT32BTPL5cjs.SelectTrigger,
307
+ _chunkSWOS3DDMcjs.SelectTrigger,
308
308
  {
309
309
  id: "helpCategory",
310
310
  "aria-label": "Help Category",
311
311
  "aria-required": true,
312
312
  className: "h-12 border-ods-border bg-ods-card px-3 text-ods-text-primary",
313
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectValue, { placeholder: "Choose your main interest" })
313
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectValue, { placeholder: "Choose your main interest" })
314
314
  }
315
315
  ),
316
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectContent, { children: helpCategoryOptions.map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkT32BTPL5cjs.SelectItem, { value: opt, children: opt }, opt)) })
316
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectContent, { children: helpCategoryOptions.map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkSWOS3DDMcjs.SelectItem, { value: opt, children: opt }, opt)) })
317
317
  ] })
318
318
  }
319
319
  ),
@@ -325,7 +325,7 @@ function ContactForm({
325
325
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKWX65373cjs.RequiredMark, {})
326
326
  ] }),
327
327
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
328
- _chunkT32BTPL5cjs.Textarea,
328
+ _chunkSWOS3DDMcjs.Textarea,
329
329
  {
330
330
  id: "message",
331
331
  ...register("message"),
@@ -340,7 +340,7 @@ function ContactForm({
340
340
  ] }),
341
341
  attachmentsEnabled && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
342
342
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
343
- _chunkLL35WZZScjs.ChatAttachmentChipStrip,
343
+ _chunkOD2WMUAOcjs.ChatAttachmentChipStrip,
344
344
  {
345
345
  attachments: attachments.attachments,
346
346
  onRemove: attachments.removeAttachment,
@@ -349,7 +349,7 @@ function ContactForm({
349
349
  ),
350
350
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
351
351
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
352
- _chunkLL35WZZScjs.ChatAttachmentAddButton,
352
+ _chunkOD2WMUAOcjs.ChatAttachmentAddButton,
353
353
  {
354
354
  attachmentsEnabled: true,
355
355
  attachmentsCount: attachments.attachments.length,
@@ -385,4 +385,4 @@ function ContactForm({
385
385
 
386
386
 
387
387
  exports.ContactForm = ContactForm;
388
- //# sourceMappingURL=chunk-3ADAUFKK.cjs.map
388
+ //# sourceMappingURL=chunk-G7PNBP6I.cjs.map