1import { o as e } from "./rolldown-runtime-CEFd7nDs.js"; 2import { C as t, E as n, O as r, T as i, k as a, n as o } from "./react-BP4GhFtr.js"; 3import { C as s, Dt as c, E as l, Et as u, Hr as d, I as f, L as p, T as m, Ur as h, Vr as g, Wr as _, Xr as v, _ as y, a as b, c as x, k as S, l as C, m as w, mt as T, r as E, s as D, t as O, x as k } from "./PillButton-CyrUwzav.js"; 4import { t as ee } from "./useIntl-BvTQrSJV.js"; 5import { t as A } from "./useMediaQuery-CH1FtD4N.js"; 6import { At as te, D as ne, F as re, Ht as ie, It as ae, O as j, Vt as M, Xt as oe, Zt as se, b as ce, ct as le, h as ue, kt as de, m as fe, o as pe, vt as me, z as he } from "./PinturaEditorContext-C8ThvzKM.js"; 7import { n as ge, t as _e } from "./RadioGroup-D3vceML-.js"; 8import { t as ve } from "./IconButton-BjIFdJub.js"; 9import { t as ye } from "./AppBar-CZSpBdSL.js"; 10import { t as N } from "./Autocomplete-BQdrBc22.js"; 11import { t as be } from "./Tooltip-2t39vvxO.js"; 12import { t as P } from "./Chip-JOkHU5wa.js"; 13import { h as xe, t as Se } from "./Select-D5hJnYnp.js"; 14import { t as Ce } from "./SplitButton-RB_YlK51.js"; 15import { t as we } from "./Checkbox-CYLexh3I.js"; 16import { i as Te, t as Ee } from "./DialogContent-BtxfYCvO.js"; 17import { t as De } from "./DirtyModal-Bm_OGwXm.js"; 18import { t as Oe } from "./DialogTitle-BUKCnv2D.js"; 19import { t as F } from "./MenuItem-CMbv2T7h.js"; 20import { i as I, t as ke } from "./TextField-APCza6VQ.js"; 21import { t as L } from "./FormControlLabel-V4YhUygp.js"; 22import { t as R } from "./Grid-CXZRpbgH.js"; 23import { t as Ae } from "./InputAdornment-CSmP1dc0.js"; 24import { t as z } from "./LinearProgress-xK3z-Adm.js"; 25import { t as je } from "./Link-CUSyhtmX.js"; 26import { t as Me } from "./Switch-1M1o-LZl.js"; 27import { r as B, t as Ne } from "./Tabs-BQ7H7sFx.js"; 28import { t as V } from "./TableCell-lerOY5er.js"; 29import { i as H, n as Pe, r as Fe, t as Ie } from "./TableRow-BdjWomXI.js"; 30import { t as Le } from "./TableContainer-BzhCPMfC.js"; 31import { t as Re } from "./Toolbar-CwHubAdC.js"; 32import { C as ze, Ot as U, Z as W, a as G, gt as Be, h as Ve, kt as He } from "./free-solid-svg-icons-cXWvZHQ_.js"; 33import { t as Ue } from "./aiGate-CX5yaEsB.js"; 34import { t as K } from "./TypographyIntl-GE1svvsP.js"; 35import { t as We } from "./DateTimePicker-t4NErdk5.js"; 36import { p as Ge } from "./chunk-62JRHF6Z-DMyCiZws.js"; 37import { c as Ke, o as qe } from "./Util-Cd2757Fs.js"; 38import { t as Je } from "./CloseButton-DKr3ZWZl.js"; 39import { t as Ye } from "./ConfirmationModal-D1_BhSdl.js"; 40import { Cr as Xe, G as Ze, Ht as Qe, It as $e, Kt as et, Lt as tt, M as nt, Q as rt, R as q, Sr as J, Ut as it, Vt as at, Xt as ot, at as st, ct, lt, qt as ut, r as dt, st as ft, ut as Y, z as X } from "./BuilderApi-BSRhNmHS.js"; 41import { a as pt, r as mt, t as ht } from "./FontList-BGBhgjQL.js"; 42import { n as gt, t as _t } from "./Preview-WJ1H677d.js"; 43import { n as vt, r as yt } from "./cardScheduling-ClIRqW-J.js"; 44import { t as bt } from "./ids-D3nfzBXu.js"; 45import { c as xt, n as St, o as Ct, u as wt } from "./MobiHost-DPy_1cxv.js"; 46import { a as Tt } from "./ContentTab-DDSrO16b.js"; 47import { t as Et } from "./NavPrompt-DuEYMv6h.js"; 48import { t as Dt } from "./ImageSetter-BzOAp2S1.js"; 49_(), d(); 50var Z = /* @__PURE__ */ e(a()); 51u(), f(); 52var Q = n(), Ot = [ 53 "addEndListener", 54 "appear", 55 "children", 56 "easing", 57 "in", 58 "onEnter", 59 "onEntered", 60 "onEntering", 61 "onExit", 62 "onExited", 63 "onExiting", 64 "style", 65 "timeout", 66 "TransitionComponent" 67], kt = { 68 entering: { transform: "none" }, 69 entered: { transform: "none" } 70}, At = /*#__PURE__*/ Z.forwardRef(function(e, t) { 71 let n = T(), r = {
72 enter: n.transitions.duration.enteringScreen, 73 exit: n.transitions.duration.leavingScreen 74 }, { addEndListener: i, appear: a = !0, children: o, easing: s, in: u, onEnter: d, onEntered: f, onEntering: _, onExit: v, onExited: y, onExiting: b, style: x, timeout: C = r, TransitionComponent: w = S } = e, E = g(e, Ot), D = Z.useRef(null), O = p(D, c(o), t), k = (e) => (t) => { 75 if (e) { 76 let n = D.current; 77 t === void 0 ? e(n) : e(n, t); 78 } 79 }, ee = k(_), A = k((e, t) => { 80 l(e); 81 let r = m({ 82 style: x, 83 timeout: C, 84 easing: s 85 }, { mode: "enter" }); 86 e.style.webkitTransition = n.transitions.create("transform", r), e.style.transition = n.transitions.create("transform", r), d && d(e, t); 87 }), te = k(f), ne = k(b), re = k((e) => { 88 let t = m({ 89 style: x, 90 timeout: C, 91 easing: s 92 }, { mode: "exit" }); 93 e.style.webkitTransition = n.transitions.create("transform", t), e.style.transition = n.transitions.create("transform", t), v && v(e); 94 }), ie = k(y); 95 return /*#__PURE__*/ (0, Q.jsx)(w, h({ 96 appear: a, 97 in: u, 98 nodeRef: D, 99 onEnter: A, 100 onEntered: te, 101 onEntering: ee, 102 onExit: re, 103 onExited: ie, 104 onExiting: ne, 105 addEndListener: (e) => { 106 i && i(D.current, e); 107 }, 108 timeout: C 109 }, E, { children: (e, t) => /*#__PURE__*/ Z.cloneElement(o, h({ 110 style: h({ 111 transform: "scale(0)", 112 visibility: e === "exited" && !u ? "hidden" : void 0 113 }, kt[e], x, o.props.style), 114 ref: O 115 }, t)) })); 116}), jt = { 117 colors: { 118 primaryColor: { 119 variable: "--primaryColor", 120 value: null 121 }, 122 secondaryColor1: { 123 variable: "--secondaryColor1", 124 value: null 125 }, 126 secondaryColor2: { 127 variable: "--secondaryColor2", 128 value: null 129 }, 130 secondaryColor3: { 131 variable: "--secondaryColor3", 132 value: null 133 }, 134 secondaryColor4: { 135 variable: "--secondaryColor4", 136 value: null 137 }, 138 secondaryColor5: { 139 variable: "--secondaryColor5", 140 value: null 141 } 142 }, 143 globalFont: { 144 fontFamily: { value: null }, 145 color: { value: null } 146 }, 147 heading: { 148 fontFamily: { 149 variable: "--headingFontFamily", 150 value: null 151 }, 152 fontSize: { 153 variable: "--headingFontSize", 154 value: null 155 }, 156 color: { 157 variable: "--headingColor", 158 value: null 159 }, 160 fontWeight: { 161 variable: "--headingFontWeight", 162 value: null 163 }, 164 fontStyle: { 165 variable: "--headingFontStyle", 166 value: null 167 }, 168 textDecoration: { 169 variable: "--headingTextDecoration", 170 value: null 171 } 172 }, 173 subheading: { 174 fontFamily: { 175 variable: "--subheadingFontFamily", 176 value: null 177 }, 178 fontSize: { 179 variable: "--subheadingFontSize", 180 value: null 181 }, 182 color: { 183 variable: "--subheadingColor", 184 value: null 185 }, 186 fontWeight: { 187 variable: "--subheadingFontWeight", 188 value: null 189 }, 190 fontStyle: { 191 variable: "--subheadingFontStyle", 192 value: null 193 }, 194 textDecoration: { 195 variable: "--subheadingTextDecoration", 196 value: null 197 } 198 }, 199 paragraph: { 200 fontFamily: { 201 variable: "--paragraphFontFamily", 202 value: null 203 }, 204 fontSize: { 205 variable: "--paragraphFontSize", 206 value: null 207 }, 208 color: { 209 variable: "--paragraphColor", 210 value: null 211 }, 212 fontWeight: { 213 variable: "--paragraphFontWeight", 214 value: null 215 }, 216 fontStyle: { 217 variable: "--paragraphFontStyle", 218 value: null 219 }, 220 textDecoration: { 221 variable: "--paragraphTextDecoration", 222 value: null 223 }, 224 lineHeight: { 225 variable: "--paragraphLineHeight", 226 value: null 227 } 228 } 229}; 230//#endregion 231//#region Components/Builder/exportHelpers.jsx 232function Mt(e, t) { 233 if (e) return e; 234 if (!t) return "Unknown video"; 235 try { 236 let e = new URL(t).pathname.split("/").pop(); 237 return decodeURIComponent(e) || "Unknown video"; 238 } catch { 239 let e = t.split("/"); 240 return e[e.length - 1] || "Unknown video"; 241 } 242} 243var Nt = /^[0-9a-f-]+\.\w+$/i, Pt = { 244 largeVideo: "Large Video (>100MB)", 245 embeddedVideo: "Embedded Video", 246 eLearning: "SCORM", 247 customCode: "Embedded Code" 248}; 249function Ft(e) { 250 let t = e?.course?.modules, n = { 251 hasCustomCode: !1, 252 hasElearning: !1, 253 hasEmbeddedVid: !1, 254 hasLargeVid: !1, 255 forbiddenDetails: [] 256 }; 257 if (!t?.length) return n; 258 let r = n.forbiddenDetails; 259 return t.forEach((e, t) => { 260 let i = e.header || `Module ${t + 1}`;
261 e.items.forEach((e, t) => { 262 let a = t + 1; 263 e.columns.forEach((e) => { 264 if (e.type === "video") e.props?.large === !0 && (n.hasLargeVid = !0, r.push({ 265 moduleName: i, 266 elementNumber: a, 267 name: Mt(e.props.imageName, e.props.progressiveUrl), 268 type: "largeVideo", 269 typeLabel: Pt.largeVideo, 270 progressiveUrl: e.props.progressiveUrl, 271 sizeMB: e.props.blobSize ? Math.round(e.props.blobSize / 1e6) : null 272 })), e.props?.videoType === "embed" && (n.hasEmbeddedVid = !0, r.push({ 273 moduleName: i, 274 elementNumber: a, 275 name: "Embedded Video", 276 type: "embeddedVideo", 277 typeLabel: Pt.embeddedVideo 278 })); 279 else if (e.type === "eLearning") n.hasElearning = !0, r.push({ 280 moduleName: i, 281 elementNumber: a, 282 name: e.props?.fileName || "SCORM Upload", 283 type: "eLearning", 284 typeLabel: Pt.eLearning 285 }); 286 else if (e.type === "customCode") n.hasCustomCode = !0, r.push({ 287 moduleName: i, 288 elementNumber: a, 289 name: "Custom Code", 290 type: "customCode", 291 typeLabel: Pt.customCode 292 }); 293 else if (e.type === "accordion" || e.type === "tabs" || e.type === "carousel") { 294 let t = lt[e.type]?.[0]?.subItemLabel || "Item"; 295 (e.props?.cards ?? e.props?.drawers ?? e.props?.tabs ?? e.props?.slides ?? []).forEach((e, o) => { 296 let s = `${a}-${t} ${o + 1}`; 297 (e.large === !0 || e.blobSize && e.blobSize > 1e8) && (n.hasLargeVid = !0, r.push({ 298 moduleName: i, 299 elementNumber: s, 300 name: Mt(e.imageName, e.progressiveUrl), 301 type: "largeVideo", 302 typeLabel: Pt.largeVideo, 303 progressiveUrl: e.progressiveUrl, 304 sizeMB: e.blobSize ? Math.round(e.blobSize / 1e6) : null 305 })), e.theme?.includes("video") && e.videoType === "embed" && (n.hasEmbeddedVid = !0, r.push({ 306 moduleName: i, 307 elementNumber: s, 308 name: "Embedded Video", 309 type: "embeddedVideo", 310 typeLabel: Pt.embeddedVideo 311 })); 312 }); 313 } 314 }); 315 }); 316 }), n.hasLargeVid ||= It(e), n; 317} 318function It(e) { 319 if (!e?.course) return !1; 320 function t(e) { 321 if (!e || typeof e != "object") return !1; 322 if (e.large === !0) return !0; 323 for (let n in e) { 324 if (!e.hasOwnProperty(n)) continue; 325 let r = e[n]; 326 if (Array.isArray(r)) { 327 for (let e of r) if (t(e)) return !0; 328 } else if (typeof r == "object" && r && t(r)) return !0; 329 } 330 return !1; 331 } 332 return t(e.course); 333} 334function Lt(e) { 335 let [t, n] = (0, Z.useState)(e || []), { get: r } = v("/Media/GetBlobMetadata", { cachePolicy: "no-cache" }), i = (0, Z.useMemo)(() => { 336 if (!e?.length) return []; 337 let t = []; 338 for (let n = 0; n < e.length; n++) { 339 let r = e[n]; 340 r.type === "largeVideo" && r.progressiveUrl && (!r.name || Nt.test(r.name)) && t.push(n); 341 } 342 return t; 343 }, [e]); 344 return (0, Z.useEffect)(() => { 345 if (!e?.length) { 346 n([]); 347 return; 348 } 349 if (i.length === 0) { 350 n(e); 351 return; 352 } 353 let t = !1; 354 async function a() { 355 let a = await Promise.all(i.map(async (t) => { 356 let n = e[t]; 357 try { 358 let e = await r("?url=" + encodeURIComponent(n.progressiveUrl)); 359 if (e?.success && e.bm?.ImageName) return { 360 idx: t, 361 name: e.bm.ImageName 362 }; 363 } catch {} 364 return null; 365 })); 366 if (t) return; 367 let o = [...e]; 368 for (let e of a) e && (o[e.idx] = { 369 ...o[e.idx], 370 name: e.name 371 }); 372 n(o); 373 } 374 return a(), () => { 375 t = !0; 376 }; 377 }, [e, i]), t; 378} 379var Rt = { 380 fontWeight: "var(--font-weight-semibold)", 381 fontSize: "var(--font-size-sm)", 382 color: "var(--ui-color-text)", 383 borderBottom: "none" 384}, zt = { 385 fontSize: "var(--font-size-sm)", 386 color: "var(--ui-color-text)", 387 borderBottom: "none" 388}; 389function Bt({ details: e }) { 390 return e?.length ? /* @__PURE__ */ (0, Q.jsx)(Le, { 391 sx: { 392 mt: 1, 393 maxWidth: 700 394 }, 395 children: /* @__PURE__ */ (0, Q.jsxs)(H, { 396 size: "small", 397 children: [/* @__PURE__ */ (0, Q.jsx)(Pe, { children: /* @__PURE__ */ (0, Q.jsxs)(Ie, { children: [
398 /* @__PURE__ */ (0, Q.jsx)(V, { 399 sx: Rt, 400 children: "Module" 401 }), 402 /* @__PURE__ */ (0, Q.jsx)(V, { 403 sx: Rt, 404 children: "Element" 405 }), 406 /* @__PURE__ */ (0, Q.jsx)(V, { 407 sx: Rt, 408 children: "Type" 409 }), 410 /* @__PURE__ */ (0, Q.jsx)(V, { 411 sx: Rt, 412 children: "Name" 413 }), 414 /* @__PURE__ */ (0, Q.jsx)(V, { 415 sx: Rt, 416 children: "Size" 417 }) 418 ] }) }), /* @__PURE__ */ (0, Q.jsx)(Fe, { children: e.map((e, t) => /* @__PURE__ */ (0, Q.jsxs)(Ie, { children: [ 419 /* @__PURE__ */ (0, Q.jsx)(V, { 420 sx: zt, 421 children: e.moduleName 422 }), 423 /* @__PURE__ */ (0, Q.jsx)(V, { 424 sx: zt, 425 children: e.elementNumber 426 }), 427 /* @__PURE__ */ (0, Q.jsx)(V, { 428 sx: zt, 429 children: e.typeLabel 430 }), 431 /* @__PURE__ */ (0, Q.jsx)(V, { 432 sx: zt, 433 children: e.name 434 }), 435 /* @__PURE__ */ (0, Q.jsx)(V, { 436 sx: zt, 437 children: e.sizeMB == null ? "" : `${e.sizeMB} MB` 438 }) 439 ] }, t)) })] 440 }) 441 }) : null; 442} 443//#endregion 444//#region Components/Builder/SaveAndPublish.jsx 445function Vt({ saveFunction: e, exportFunction: n, handleConfirmExport: r, handleConfirmPublish: i, handleConfirmUnpublish: a, handleConfirmRevert: o, handleSyncLinkedCourses: s, syncFunction: c, leaveConfirmationScreen: l }) { 446 let [u, d] = pe(); 447 (0, Z.useContext)(Tt); 448 let { card: f, setCardField: p, dirty: m, setDirty: h } = J(), { enqueueSnackbar: g } = b(), { formatMessage: _ } = ee(), [x] = t(), { post: S } = v(`/Builder/Unpublish/${f.CardId}`, { 449 cachePolicy: "no-cache", 450 headers: { RequestVerificationToken: x } 451 }), { post: C } = v(`/workday/sync-course/${f.CardId}`, { 452 cachePolicy: "no-cache", 453 headers: { RequestVerificationToken: x } 454 }), { post: w } = v(`/workday/sync-completions/${f.CardId}`, { 455 cachePolicy: "no-cache", 456 headers: { RequestVerificationToken: x } 457 }), { configuration: T } = E(); 458 (0, Z.useMemo)(() => It(f), [f]); 459 var D = window.location.hash === "#ConfirmExport" && r != null, O = window.location.hash === "#SyncLinkedCourses"; 460 (0, Z.useEffect)(() => { 461 if (m) { 462 let e = (e) => (e.returnValue = "Anything you wanna put here!", "Anything here as well, doesn't matter!"); 463 return window.addEventListener("beforeunload", e), () => { 464 window.removeEventListener("beforeunload", e); 465 }; 466 } 467 }, [m]); 468 async function k(e) { 469 try { 470 if (e === "builder.save.Unpublish") a(); 471 else if (e === "builder.save.Publish") i(); 472 else if (e === "builder.save.Export" || e === "builder.save.ExportPdf") r(); 473 else if (e === "builder.save.ConfirmExport") try { 474 d(!0), await n(); 475 } finally { 476 d(!1), l(); 477 } 478 else if (e === "builder.save.SyncLinkedCourses") s(); 479 else if (e === "builder.save.ConfirmSync" || e === "builder.save.ConfirmSyncUnmodified") try { 480 d(!0), await (e === "builder.save.ConfirmSync" ? c.syncAll() : c.syncUnmodifiedOnly()); 481 } finally { 482 d(!1); 483 } 484 else if (e === "builder.save.RevertToPublished") try { 485 o(); 486 } finally { 487 d(!1); 488 } 489 else if (e === "builder.save.SyncWorkday") try { 490 d(!0); 491 let e = await C(""); 492 if (e?.success) { 493 let t = _({ id: "builder.save.SyncWorkdaySuccess" }); 494 e.enrollments && (t += ` (${e.enrollments.enrolled} enrolled, ${e.enrollments.skipped} skipped${e.enrollments.failed > 0 ? `, ${e.enrollments.failed} failed` : ""})`), g(t, { variant: "success" }), e.workdayCourseId && p({ Description: `workdayId: ${e.workdayCourseId}` }); 495 } else g(e?.message || _({ id: "builder.save.SyncWorkdayFailed" }), { variant: "error" }); 496 } finally { 497 d(!1); 498 } 499 else if (e === "builder.save.SyncWorkdayCompletions") { 500 if (!window.confirm("Send Workday completions for every learner who has already completed this course?")) return; 501 try { 502 d(!0); 503 let e = await w(""); 504 e?.success ? g(`Queued ${e.count ?? 0} Workday completions`, { variant: "success" }) : g(e?.message || "Failed to send Workday completions", { variant: "error" }); 505 } finally { 506 d(!1); 507 } 508 } else throw `Unknown option: ${e}`; 509 } catch (e) { 510 console.log("error", e), g(e || _({ id: "GenericError" }), { variant: "error" }); 511 return; 512 } 513 } 514 var A = []; 515 return D ? A = ["builder.save.ConfirmExport"] : O ? A = c?.hasModified ? ["builder.save.ConfirmSync", "builder.save.ConfirmSyncUnmodified"] : ["builder.save.ConfirmSync"] : (T?.User?.Entitlements?.includes("content.publisher") || T?.User?.UserRoles?.some((e) => e.RoleId == "0" || e.RoleId == "1") ? (A = ["builder.save.Publish"], f.CurrentlyPublished && (A.push("builder.save.Unpublish"), f.IsPublished || A.push("builder.save.RevertToPublished"))) : (T?.User?.Entitlements?.includes("content.author"), f.CurrentlyPublished && !f.IsPublished && (A = ["builder.save.RevertToPublished"])), s && f.CurrentlyPublished && f.hasLinkedCourses && A.push("builder.save.SyncLinkedCourses"), r && A.push("builder.save.Export"), T?.workdayEnabled && f.CurrentlyPublished && (T?.User?.Entitlements?.includes("workday.sync") || T?.User?.Entitlements?.includes("developer")) && (A.push("builder.save.SyncWorkday"), A.push("builder.save.SyncWorkdayCompletions"))), /* @__P
515URE__ */ (0, Q.jsx)(y, { 516 sx: { 517 display: "flex", 518 alignItems: "center", 519 ml: 2 520 }, 521 children: /* @__PURE__ */ (0, Q.jsx)(Ce, { 522 options: A, 523 onClick: k, 524 sx: { "& .MuiButton-root": { textTransform: "none" } } 525 }) 526 }); 527} 528//#endregion 529//#region Components/Builder/CancelButton.jsx 530function Ht({ handleConfirmExport: e, handleConfirmCanceled: n, dirtyModalCallback: r, setDirtyModalCallback: i }) { 531 let a = Ge(), o = (0, Z.useContext)(Tt), { card: s, dirty: c } = J(), [l] = t(), { configuration: u, isAdmin: d } = E(), { courseIsEditableByAccount: f } = (0, Z.useContext)(Xe); 532 var p = window.location.hash === "#ConfirmPublish", m = window.location.hash === "#ConfirmUnpublish", h = window.location.hash === "#ConfirmExport", g = window.location.hash === "#SyncLinkedCourses"; 533 (0, Z.useEffect)(() => { 534 if (d && f && c && !r) { 535 let e = (e) => (e.returnValue = "Anything you wanna put here!", "Anything here as well, doesn't matter!"); 536 return window.addEventListener("beforeunload", e), () => { 537 window.removeEventListener("beforeunload", e); 538 }; 539 } 540 }, [c]); 541 function _(e) { 542 if (c && r === void 0) return i({ fn: e }), !1; 543 e(); 544 } 545 function v() { 546 o.isActive() && (o.complete(), localStorage.setItem("builderTour", !0)), a("/Content"); 547 } 548 var b = []; 549 p ? b = ["builder.save.ConfirmPublish"] : m ? b = ["builder.save.ConfirmUnpublish"] : h ? b = ["builder.save.ConfirmExport"] : (u?.User?.Entitlements?.includes("content.publisher") || u?.User?.UserRoles?.some((e) => e.RoleId == "0" || e.RoleId == "1") ? (b = ["builder.save.Publish", "builder.save.Save"], s.CurrentlyPublished && b.push("builder.save.Unpublish")) : b = (u?.User?.Entitlements?.includes("content.author"), ["builder.save.Save"]), e && b.push("builder.save.Export")); 550 let x = p || m || h || g; 551 return d === !0 ? /* @__PURE__ */ (0, Q.jsxs)(y, { 552 sx: { 553 display: "flex", 554 alignItems: "center" 555 }, 556 children: [/* @__PURE__ */ (0, Q.jsx)(Je, { onClick: x ? n : (() => _(v)) }), !p && r && /* @__PURE__ */ (0, Q.jsx)(De, { 557 handleCancel: () => i(), 558 handleConfirm: () => r.fn() 559 })] 560 }) : /* @__PURE__ */ (0, Q.jsx)(y, { children: /* @__PURE__ */ (0, Q.jsx)(Je, { onClick: () => logOut() }) }); 561} 562//#endregion
563//#region Components/Course/editors/aiHelpers.jsx 564function Ut(e) { 565 if (!e || typeof e != "string") return { 566 texts: [], 567 isHtml: !1 568 }; 569 if (!/<[^>]+>/.test(e)) return { 570 texts: [e], 571 isHtml: !1 572 }; 573 let t = new DOMParser().parseFromString(e, "text/html"), n = [], r = document.createTreeWalker(t.body, NodeFilter.SHOW_TEXT, { acceptNode: (e) => e.nodeValue ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT }), i; 574 for (; i = r.nextNode();) n.push(i.nodeValue); 575 return { 576 texts: n, 577 isHtml: !0, 578 originalHtml: e 579 }; 580} 581function Wt(e, t) { 582 let n = new DOMParser().parseFromString(e, "text/html"), r = 0, i = document.createTreeWalker(n.body, NodeFilter.SHOW_TEXT, { acceptNode: (e) => e.nodeValue ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT }), a; 583 for (; a = i.nextNode();) r < t.length && (a.nodeValue = t[r++]); 584 return n.body.querySelectorAll("[style*=\"text-align\"]").forEach((e) => { 585 e.style.textAlign === "left" && (e.style.textAlign = "start"); 586 }), n.body.innerHTML; 587} 588function Gt() { 589 let { card: e, setCardField: n } = J(), [r] = t(), { configuration: a } = E(), { enqueueSnackbar: o } = b(), { formatMessage: s } = ee(), c = Ge(), l = dt(), { importModule: u, exportModule: d } = st(), f = e.course.modules, p = (0, Z.useRef)(f), { authRequest: m } = i(), h = (0, Z.useRef)(l), { post: g } = v("/llm/Translate", { 590 cachePolicy: "no-cache", 591 headers: { RequestVerificationToken: r } 592 }), { get: _ } = v("/llm/GetSupportedLanguages", { cachePolicy: "no-cache" }); 593 (0, Z.useEffect)(() => { 594 h.current = l; 595 }, [l]), (0, Z.useEffect)(() => { 596 p.current = f; 597 }, [f]); 598 async function y() { 599 let e = await _(); 600 if (e) { 601 if (e.success) { 602 let t = e.languages; 603 return t.sort((e, t) => e.englishName.localeCompare(t.englishName)), t; 604 } 605 throw e.message; 606 } 607 return null; 608 } 609 async function x(t) { 610 let r = /* @__PURE__ */ new Map(), i = []; 611 ft(e, (e, t, n) => { 612 let a = t[n]; 613 if (console.log("Original format is:", a), a) { 614 let { texts: e, isHtml: t, originalHtml: n } = Ut(a); 615 r.set(a, { 616 texts: e, 617 isHtml: t, 618 originalHtml: n 619 }), i.push(...e); 620 } 621 }); 622 let a = await g({ 623 LanguageCode: t, 624 Text: i 625 }); 626 if (!a.success) { 627 o(a.message || s({ id: "GenericError" }), { variant: "error" }); 628 return; 629 } 630 let l = a.translations, u = 0, d = { ...e }; 631 ft(d, (e, t, n) => { 632 let a = t[n]; 633 if (!a) return; 634 let o = r.get(a); 635 if (!o) return; 636 let { texts: s, isHtml: c, originalHtml: d } = o, f = s.map(() => { 637 let e = l[i[u]]; 638 return u++, e || ""; 639 }); 640 if (t[n] = c ? Wt(d, f) : f[0] || a, { 641 card: "Header", 642 lesson: "header", 643 quiz: "header" 644 }[e] === n) { 645 let e = t[n]; 646 t[n] = new DOMParser().parseFromString(e, "text/html").body.textContent; 647 } 648 }), d.aiTranslateAcknowledged = !1, n(d), c("#", { replace: !0 }); 649 } 650 async function S() { 651 let t = p.current, n = h.current.handleAddModule("quiz", !1, { initialProps: { 652 generating: !0, 653 aiAcknowledged: !1 654 } }); 655 if (!n) return; 656 let r = n.id, i = [...t, n], s = C(i, i.length - 1); 657 if (!s) { 658 o("No text found in lessons to generate a quiz.", { variant: "error" }), h.current.deleteModule(r); 659 return; 660 } 661 try { 662 let t = await m({ 663 method: "post", 664 url: `${a.lmPythonAppUrl}/GenerateQuizQuestions`, 665 data: { 666 modules: s, 667 elementSchemas: rt() 668 }, 669 headers: { 670 "Cache-Control": "no-cache", 671 Pragma: "no-cache", 672 Expires: "0" 673 } 674 }); 675 if (t.data?.success) { 676 let n = t.data.quiz; 677 u(n), it(n, e.course.defaultStyles); 678 let { updateModule: i, setActiveModuleId: a } = h.current; 679 i(r, { 680 ...n, 681 id: r 682 }), o(/* @__PURE__ */ (0, Q.jsxs)("div", { children: [ 683 "AI quiz generated. ", 684 /* @__PURE__ */ (0, Q.jsx)("a", { 685 href: "#", 686 onClick: () => { 687 c("#MainView", { replace: !0 }), a(r); 688 }, 689 children: "View it here" 690 }), 691 "." 692 ] })); 693 } else o(t.data?.message || "Error generating quiz", { variant: "error" }), h.current.deleteModule(r); 694 } catch (e) { 695 console.error("Error generating quiz:", e); 696 let t = e.response?.data?.message || e.message || "Error generating quiz"; 697 o(t, { variant: "error" }), h.current.deleteModule(r); 698 } 699 } 700 function C(e, t) { 701 let n = []; 702 for (let r = t - 1; r >= 0 && e[r].type !== "quiz"; r--) e[r].type === "lesson" && n.push(e[r]); 703 n.length === 0 && (n = e.filter((e) => e.type === "lesson")), n = JSON.parse(JSON.stringify(n)), n.reverse(); 704 let r = !1; 705 for (let e of n) ct(e, (e, t, n) => { 706 if (e !== "lesson") { 707 let e = t[n]; 708 e && (r = !0, e = ot(e) ?? e, t[n] = e); 709 } 710 }); 711 return r ? n.map((e) => d(e)) : null; 712 } 713 return { 714 translateCourse: x,
715 getSupportedLanguages: y, 716 generateQuiz: S 717 }; 718} 719//#endregion 720//#region Components/Course/editors/LanguageSelector.jsx 721var Kt = ({ languageCode: e, setLanguageCode: t, sx: n }) => { 722 let r = Gt(), [i, a] = (0, Z.useState)(); 723 if ((0, Z.useEffect)(() => { 724 async function e() { 725 let e = await r.getSupportedLanguages(); 726 if (e) { 727 let t = e.map((e) => ({ 728 label: `${e.englishName} (${e.name})`, 729 id: e.code 730 })); 731 a(t); 732 } else a([]); 733 } 734 e(); 735 }, []), !i) return null; 736 let o = e ? i.find((t) => t.id === e) : null; 737 return /* @__PURE__ */ (0, Q.jsxs)("div", { 738 style: { 739 display: "flex", 740 alignItems: "center", 741 gap: "1em" 742 }, 743 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 744 sx: { color: "var(--ui-color-text)" }, 745 children: "Language:" 746 }), /* @__PURE__ */ (0, Q.jsx)(N, { 747 options: i, 748 sx: { width: "20em" }, 749 renderInput: (t) => /* @__PURE__ */ (0, Q.jsx)(ke, { 750 ...t, 751 placeholder: e ? "" : "Default", 752 sx: { my: 2 }, 753 size: "small" 754 }), 755 onChange: (e, n) => t(n?.id), 756 value: o 757 })] 758 }); 759}, qt = { 760 width: "25em", 761 "& fieldset legend span.notranslate": { 762 display: "inline-block", 763 width: 0 764 }, 765 "& .MuiInputBase-input.MuiAutocomplete-inputFocused:focus": { 766 pl: .625, 767 pb: .9375, 768 pt: .9375 769 } 770}; 771function Jt() { 772 let { enqueueSnackbar: e } = b(), [n] = t(), { get: r } = v("/Builder/GetDraftTrends", { cachePolicy: "no-cache" }), { post: i } = v("/Builder/GetAvailableTrends", { 773 cachePolicy: "no-cache", 774 headers: { RequestVerificationToken: n } 775 }), [a, o] = (0, Z.useState)(null), [s, c] = (0, Z.useState)(""), l = Ke(s), { card: u, setCardField: d } = J(), [f, p] = (0, Z.useState)(); 776 (0, Z.useEffect)(() => { 777 async function t() { 778 var t = u.Trends; 779 if (!t) { 780 var n = await r(`?versionId=${u.VersionId}`); 781 if (!n) return; 782 n.success ? (t = n.trends, d({ Trends: n.trends }, !0)) : e(n.message || "error", { variant: "error" }); 783 }
784 if (a === null || s === l) { 785 var c = { 786 searchCriteria: s, 787 trends: [...t] 788 }, n = await i(c); 789 if (!n) return; 790 n.success && o(n.trends); 791 } 792 } 793 t(); 794 }, [l]); 795 function m(e, t) { 796 c(t); 797 } 798 function h(e) { 799 e.key === "Enter" && g(e, e.target.value); 800 } 801 function g(e, t) { 802 if (t) { 803 t ||= s; 804 var n = [...u.Trends]; 805 t && !n.includes(t) && (n.push(t), d({ Trends: n })), t && a && a.includes(t) && o(a.filter((e) => e != t)), c(""); 806 } 807 } 808 function _() { 809 if (f) { 810 var e = [...u.Trends]; 811 e = e.filter((e) => e != f), d({ Trends: e }), p(null); 812 } 813 } 814 function S() { 815 c(""); 816 } 817 function w(e, t) { 818 if (!t) return; 819 t = t.replace(/ /g, "\xA0"); 820 var n = s.replace(/ /g, "\xA0"); 821 let r = t.split(RegExp(`(${n})`, "gi")).map((e, t) => e.toLowerCase() === n.toLowerCase() ? /* @__PURE__ */ (0, Q.jsx)("b", { children: e }, t) : e); 822 return /* @__PURE__ */ (0, Q.jsx)("li", { 823 ...e, 824 children: r 825 }); 826 } 827 return /* @__PURE__ */ (0, Q.jsxs)(C, { children: [/* @__PURE__ */ (0, Q.jsx)(C, { 828 direction: "row", 829 children: /* @__PURE__ */ (0, Q.jsx)(N, { 830 freeSolo: !0, 831 options: a || [], 832 filterOptions: (e) => e, 833 renderOption: w, 834 value: s, 835 inputValue: s, 836 onInputChange: m, 837 onChange: g, 838 renderInput: (e) => /* @__PURE__ */ (0, Q.jsx)(ke, { 839 ...e, 840 variant: "outlined", 841 sx: qt, 842 onKeyPress: h, 843 inputProps: { 844 maxLength: 128, 845 ...e.inputProps 846 }, 847 InputProps: { 848 ...e?.InputProps, 849 endAdornment: /* @__PURE__ */ (0, Q.jsx)(Ae, { 850 position: "end", 851 children: s ? /* @__PURE__ */ (0, Q.jsx)(x, { 852 icon: oe, 853 onClick: S 854 }) : /* @__PURE__ */ (0, Q.jsx)(x, { icon: me }) 855 }), 856 placeholder: "Search current trends" 857 } 858 }) 859 }) 860 }
860), /* @__PURE__ */ (0, Q.jsx)(y, { 861 sx: { mt: 2 }, 862 children: u.Trends?.map((e, t) => /* @__PURE__ */ (0, Q.jsx)(At, { 863 appear: !!u.Trends, 864 in: !!e && f !== e, 865 onExited: _, 866 children: /* @__PURE__ */ (0, Q.jsx)(P, { 867 label: e, 868 onDelete: () => p(e), 869 sx: { mr: 2 } 870 }, e) 871 }, e)) 872 })] }); 873} 874//#endregion 875//#region Components/Shared/DateTimeField.jsx 876var Yt = { 877 pl: 1, 878 "& input.MuiInputBase-input": { pl: 1 } 879}; 880function Xt({ value: e, onChange: t, ...n }) { 881 let [r, i] = (0, Z.useState)(!1); 882 return /* @__PURE__ */ (0, Q.jsx)(We, { 883 open: r, 884 value: e, 885 onChange: t, 886 onClose: () => i(!1), 887 renderInput: (e) => /* @__PURE__ */ (0, Q.jsx)(ke, { 888 ...e, 889 onClick: () => i(!0), 890 inputProps: { 891 ...e.inputProps, 892 readOnly: !0 893 }, 894 sx: Yt 895 }), 896 componentsProps: { actionBar: { actions: [ 897 "clear", 898 "cancel", 899 "accept" 900 ] } }, 901 ...n 902 }); 903} 904//#endregion 905//#region Components/Builder/Settings.jsx 906var Zt = { 907 fontWeight: "var(--font-weight-medium)", 908 color: "var(--ui-color-text)" 909}, Qt = { 910 fontSize: "smaller", 911 fontWeight: "var(--font-weight-regular)", 912 color: "var(--ui-color-text)", 913 fontStyle: "italic" 914}, $t = { 915 display: "flex", 916 justifyContext: "flex-start", 917 alignItems: "center" 918}, en = { 919 mt: 2, 920 "& > .MuiGrid-item": { 921 color: "var(--ui-color-text-header)", 922 backgroundColor: "var(--ui-color-surface-paper)", 923 justifyContent: "center", 924 justifySelf: "center", 925 my: 1, 926 py: 2 927 }, 928 "& > .MuiGrid-item > *": { pl: 2 } 929}, tn = { "& fieldset legend span.notranslate": { 930 display: "inline-block", 931 width: 0 932} }; 933function nn({ children: e, ...t }) { 934 let { card: n, setCardField: r } = J(), { disableTabs: i } = t; 935 function a(e) { 936 "0123456789".includes(e.key) || e.preventDefault(); 937 } 938 var o = vt(n); 939 return /* @__PURE__ */ (0, Q.jsxs)(R, { 940 container: !0, 941 spacing: 2, 942 sx: en, 943 children: [ 944 /* @__PURE__ */ (0, Q.jsx)($, { 945 sectionTitle: "builder.settings.general", 946 sectionDescription: "builder.settings.general.desc", 947 children: /* @__PURE__ */ (0, Q.jsx)(R, { 948 container: !0, 949 children: /* @__PURE__ */ (0, Q.jsx)(rn, { 950 getFieldValue: (e) => n[e], 951 setFieldValue: (e, t) => r({ [e]: t }) 952 }) 953 }) 954 }), 955 e, 956 /* @__PURE__ */ (0, Q.jsx)($, { 957 sectionTitle: "builder.settings.availability", 958 sectionDescription: "builder.settings.availability.desc", 959 disabled: i, 960 children: /* @__PURE__ */ (0, Q.jsxs)(C, { 961 direction: "row", 962 children: [/* @__PURE__ */ (0, Q.jsxs)(C, { 963 direction: "column", 964 spacing: 2, 965 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 966 sx: { 967 height: "28px", 968 ...Qt 969 }, 970 id: "builder.settings.publishDate" 971 }), /* @__PURE__ */ (0, Q.jsx)(K, { 972 sx: { 973 height: "28px", 974 ...Qt 975 }, 976 id: "builder.settings.expireDate" 977 })] 978 }), /* @__PURE__ */ (0, Q.jsxs)(C, { 979 direction: "column", 980 spacing: 2, 981 children: [/* @__PURE__ */ (0, Q.jsx)(Xt, { 982 value: n.PublishDate, 983 onChange: (e) => { 984 r({ PublishDate: e }); 985 } 986 }), /* @__PURE__ */ (0, Q.jsx)(Xt, { 987 value: n.GoDeadDate, 988 onChange: (e) => r({ GoDeadDate: e }) 989 })] 990 })] 991 }) 992 }), 993 /* @__PURE__ */ (0, Q.jsx)($, { 994 sectionTitle: "builder.settings.visibility", 995 sectionDescription: "builder.settings.visibility.desc", 996 disabled: i, 997 children: /* @__PURE__ */ (0, Q.jsxs)(C, { 998 direction: "column", 999 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 1000 sx: $t, 1001 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1002 sx: Qt, 1003 id: "builder.settings.hide" 1004 }), /* @__PURE__ */ (0, Q.jsx)(Me, { 1005 disabled: o, 1006 checked: o || n.Hidden, 1007 onChange: (e) => r({ Hidden: e.target.checked }) 1008 })] 1009 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 1010 sx: $t, 1011 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1012 sx: Qt, 1013 id: "builder.settings.searchHide" 1014 }), /* @__PURE__ */ (0, Q.jsx)(Me, { 1015 disabled: o, 1016 checked: o || n.SearchHidden, 1017 onChange: (e) => r({ SearchHidden: e.target.checked }) 1018 })] 1019 })] 1020 }) 1021 }),
1022 /* @__PURE__ */ (0, Q.jsxs)($, { 1023 sectionTitle: "builder.settings.duration", 1024 sectionDescription: "builder.settings.duration.desc", 1025 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1026 sx: Qt, 1027 id: "builder.settings.duration.estimate" 1028 }), /* @__PURE__ */ (0, Q.jsx)(ke, { 1029 InputProps: { sx: { width: "5em" } }, 1030 inputProps: { maxLength: 4 }, 1031 onKeyPress: a, 1032 sx: tn, 1033 value: n.DurationEstimate ?? "", 1034 onChange: (e) => r({ DurationEstimate: e.target.value || null }) 1035 })] 1036 }), 1037 /* @__PURE__ */ (0, Q.jsx)($, { 1038 sectionTitle: "builder.settings.trends", 1039 sectionDescription: "builder.settings.trends.desc", 1040 children: /* @__PURE__ */ (0, Q.jsx)(Jt, {}) 1041 }) 1042 ] 1043 }); 1044} 1045function rn({ getFieldValue: e, setFieldValue: t }) { 1046 return /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsx)(R, { 1047 item: !0, 1048 xs: 6, 1049 children: /* @__PURE__ */ (0, Q.jsxs)(C, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1050 sx: { 1051 display: "inline", 1052 pr: 1, 1053 ...Zt 1054 }, 1055 id: "builder.settings.coverImage" 1056 }), /* @__PURE__ */ (0, Q.jsx)(y, { 1057 sx: { display: "inline-flex" }, 1058 children: /* @__PURE__ */ (0, Q.jsx)(Dt, { 1059 imagePath: e("HeaderImagePath"), 1060 setter: (e) => t("HeaderImagePath", e) 1061 }) 1062 })] }) 1063 }
1063), /* @__PURE__ */ (0, Q.jsxs)(R, { 1064 item: !0, 1065 xs: 3, 1066 children: [ 1067 /* @__PURE__ */ (0, Q.jsx)(K, { 1068 sx: Zt, 1069 id: "builder.settings.header" 1070 }), 1071 /* @__PURE__ */ (0, Q.jsx)(ke, { 1072 autoFocus: !0, 1073 inputProps: { maxLength: 255 }, 1074 sx: { 1075 mb: 1, 1076 width: "25em" 1077 }, 1078 value: e("Header") ?? "", 1079 onChange: (e) => t("Header", e.target.value) 1080 }), 1081 /* @__PURE__ */ (0, Q.jsx)(K, { 1082 sx: Zt, 1083 id: "builder.settings.description" 1084 }), 1085 /* @__PURE__ */ (0, Q.jsx)(ke, { 1086 multiline: !0, 1087 size: "normal", 1088 value: e("Description") ?? "", 1089 onChange: (e) => t("Description", e.target.value), 1090 sx: { width: "30em" }, 1091 InputProps: { sx: { m: 0 } }, 1092 inputProps: { maxLength: 512 } 1093 }) 1094 ] 1095 })] }); 1096} 1097var an = { 1098 fontSize: "smaller", 1099 fontWeight: "300", 1100 color: "var(--ui-color-text)", 1101 fontStyle: "italic" 1102}, on = { 1103 my: 1, 1104 fontWeight: "var(--font-weight-medium)", 1105 fontStyle: "italic", 1106 color: "var(--ui-color-text-header)" 1107}; 1108function $({ sectionTitle: e, sectionDescription: t, sx: n, children: r, disabled: i }) { 1109 return /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsxs)(R, { 1110 item: !0, 1111 xs: 2, 1112 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1113 sx: on, 1114 id: e 1115 }), /* @__PURE__ */ (0, Q.jsx)(K, { 1116 sx: an, 1117 id: t 1118 })] 1119 }
1119), /* @__PURE__ */ (0, Q.jsx)(R, { 1120 item: !0, 1121 xs: 10, 1122 sx: { 1123 ...n, 1124 pointerEvents: i ? "none" : "auto", 1125 opacity: i ? .5 : 1 1126 }, 1127 children: r 1128 })] }); 1129} 1130//#endregion 1131//#region Components/Course/CourseSettings.jsx 1132var sn = { 1133 fontWeight: "var(--font-weight-medium)", 1134 color: "var(--ui-color-text)" 1135}, cn = { 1136 fontSize: "smaller", 1137 fontWeight: "var(--font-weight-regular)", 1138 color: "var(--ui-color-text)", 1139 fontStyle: "italic" 1140}, ln = { 1141 display: "flex", 1142 alignItems: "flex-start", 1143 "& .MuiRadio-root": { py: 0 } 1144}, un = { 1145 height: "2.2em", 1146 minWidth: "10em", 1147 "& .MuiSelect-select": { py: 0 } 1148}; 1149function dn({ intlPrefix: e, ...n }) { 1150 let { card: r, setCardField: a, dirty: o } = J(), { getAccessToken: s } = i(), c = r.course, l = Gt(), [u] = t(), { configuration: d } = E(), { post: f } = v("/course/Duplicate", { 1151 cachePolicy: "no-cache", 1152 headers: { RequestVerificationToken: u }, 1153 interceptors: { request: async ({ options: e }) => { 1154 let t = await s(); 1155 return t && (e.headers.Authorization = `Bearer ${t}`), e; 1156 } } 1157 }), p = (0, Z.useMemo)(() => Ft(r), [r]), m = Lt(p.forbiddenDetails), h = !p.hasCustomCode && !p.hasElearning && !p.hasEmbeddedVid && !p.hasLargeVid, g = c.languageCode, _ = !Ue(d?.User?.Entitlements), [b, x] = Z.useState(!1); 1158 function S(e, t) { 1159 var n = typeof e == "object" ? e : { [e]: t }, r = { 1160 ...c, 1161 ...n 1162 }; 1163 let i = "languageCode" in n; 1164 a({ course: r }, i); 1165 } 1166 let w = async () => { 1167 x(!0); 1168 try { 1169 await l.translateCourse(g); 1170 } finally { 1171 x(!1); 1172 } 1173 }, T = async () => { 1174 x(!0); 1175 try { 1176 let e = await f(`?versionId=${r.VersionId}&lang=${g}`); 1177 if (e?.success) { 1178 let t = window.location.href, n = new URL(t), i = n.pathname.split("/"), a = i.findIndex((e) => bt(e, r.VersionId)); 1179 a !== -1 && (i[a] = e.Card.VersionId), n.pathname = i.join("/"), n.searchParams.set("lang", g), n.hash = ""; 1180 let o = n.toString(); 1181 window.open(o, "_blank"); 1182 } else console.error("Failed to duplicate course:", e?.message || "Unknown error"), alert(`Error: ${e?.message || "Failed to duplicate course"}`); 1183 } catch (e) { 1184 console.error("Error duplicating course:", e), alert(`Error: ${e.message}`); 1185 } finally { 1186 x(!1); 1187 } 1188 }; 1189 return /* @__PURE__ */ (0, Q.jsxs)(nn, { 1190 intlPrefix: "courses.settings", 1191 ...n, 1192 children: [ 1193 /* @__PURE__ */ (0, Q.jsx)($, { 1194 sectionTitle: "builder.settings.sequence", 1195 sectionDescription: "builder.settings.sequence.desc", 1196 children: /* @__PURE__ */ (0, Q.jsx)(C, { 1197 direction: "row", 1198 children: /* @__PURE__ */ (0, Q.jsx)(I, { children: /* @__PURE__ */ (0, Q.jsxs)(_e, { 1199 value: String(c.forcedOrder ?? !1), 1200 onChange: (e, t) => S("forcedOrder", t), 1201 children: [/* @__PURE__ */ (0, Q.jsx)(L, { 1202 value: "false", 1203 sx: ln, 1204 control: /* @__PURE__ */ (0, Q.jsx)(ge, {}), 1205 label: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1206 sx: sn, 1207 id: "courses.settings.anyOrder" 1208 }), /* @__PURE__ */ (0, Q.jsx)(K, { 1209 sx: cn, 1210 id: "courses.settings.anyOrderDesc" 1211 })] }) 1212 }), /* @__PURE__ */ (0, Q.jsx)(L, { 1213 value: "true", 1214 sx: ln, 1215 control: /* @__PURE__ */ (0, Q.jsx)(ge, {}), 1216 label: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1217 sx: sn, 1218 id: "courses.settings.sequential" 1219 }), /* @__PURE__ */ (0, Q.jsx)(K, { 1220 sx: cn, 1221 id: "courses.settings.sequentialDesc" 1222 })] }) 1223 })] 1224 }) }) 1225 }) 1226 }), 1227 /* @__PURE__ */ (0, Q.jsx)($, { 1228 sectionTitle: "builder.settings.completion", 1229 sectionDescription: "builder.settings.completion.desc", 1230 children: /* @__PURE__ */ (0, Q.jsx)(fn, { 1231 getFieldValue: (e) => r.course[e], 1232 setFieldValue: S 1233 }) 1234 }), 1235 /* @__PURE__ */ (0, Q.jsx)($, { 1236 sectionTitle: "builder.settings.offline", 1237 sectionDescription: "builder.settings.offline.desc", 1238 children: h ? /* @__PURE__ */ (0, Q.jsx)(C, { 1239 direction: "row", 1240 children: /* @__PURE__ */ (0, Q.jsx)(I, { children: /* @__PURE__ */ (0, Q.jsxs)(_e, { 1241 value: r.OfflineAccess ?? !1, 1242 onChange: (e, t) => { 1243 a({ OfflineAccess: t == "true" }); 1244 }, 1245 children: [/* @__PURE__ */ (0, Q.jsx)(L, { 1246 value: !1, 1247 sx: ln, 1248 control: /* @__PURE__ */ (0, Q.jsx)(ge, {}), 1249 label: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1250 sx: sn, 1251 id: "courses.settings.offline.noDownload" 1252 }
1252), /* @__PURE__ */ (0, Q.jsx)(K, { 1253 sx: cn, 1254 id: "courses.settings.offline.noDownload.desc" 1255 })] }) 1256 }), /* @__PURE__ */ (0, Q.jsx)(L, { 1257 value: !0, 1258 sx: ln, 1259 control: /* @__PURE__ */ (0, Q.jsx)(ge, {}), 1260 label: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1261 sx: sn, 1262 id: "courses.settings.offline.download" 1263 }), /* @__PURE__ */ (0, Q.jsx)(K, { 1264 sx: cn, 1265 id: "courses.settings.offline.download.desc" 1266 })] }) 1267 })] 1268 }) }) 1269 }) : /* @__PURE__ */ (0, Q.jsxs)(C, { 1270 direction: "column", 1271 children: [ 1272 /* @__PURE__ */ (0, Q.jsx)(K, { 1273 sx: sn, 1274 id: "builder.settings.no-offline" 1275 }), 1276 /* @__PURE__ */ (0, Q.jsx)(K, { 1277 sx: cn, 1278 id: "builder.settings.forbidden-header" 1279 }), 1280 /* @__PURE__ */ (0, Q.jsx)(Bt, { details: m }) 1281 ] 1282 }) 1283 }), 1284 b && /* @__PURE__ */ (0, Q.jsx)(y, { 1285 sx: { 1286 position: "fixed", 1287 top: 0, 1288 left: 0, 1289 width: "100vw", 1290 height: "100vh", 1291 bgcolor: "rgba(0,0,0,0.3)", 1292 zIndex: 2e3, 1293 display: "flex", 1294 alignItems: "center", 1295 justifyContent: "center" 1296 }, 1297 children: /* @__PURE__ */ (0, Q.jsx)(se, { 1298 size: 64, 1299 thickness: 5 1300 }) 1301 }), 1302 _ && /* @__PURE__ */ (0, Q.jsxs)($, { 1303 sectionTitle: "builder.assistant.aiTranslate.label", 1304 sectionDescription: "builder.assistant.aiTranslate.subtext", 1305 children: [/* @__PURE__ */ (0, Q.jsx)(Kt, { 1306 languageCode: g, 1307 setLanguageCode: (e) => S("languageCode", e), 1308 sx: { mb: 2 } 1309 }), /* @__PURE__ */ (0, Q.jsxs)(C, { 1310 direction: "row", 1311 spacing: 3, 1312 children: [/* @__PURE__ */ (0, Q.jsx)(O, { 1313 disabled: !g || b, 1314 onClick: w, 1315 icon: Be, 1316 sx: { 1317 width: "auto", 1318 float: "right", 1319 "&:disabled": { opacity: .5 }, 1320 whiteSpace: "nowrap", 1321 px: 3 1322 }, 1323 title: "Update Course", 1324 children: "Update Course" 1325 }), /* @__PURE__ */ (0, Q.jsx)(be, { 1326 title: o ? /* @__PURE__ */ (0, Q.jsx)(D, { id: "builder.assistant.aiTranslate.unsavedError" }) : "", 1327 arrow: !0, 1328 children: /* @__PURE__ */ (0, Q.jsx)("span", { children: /* @__PURE__ */ (0, Q.jsx)(O, { 1329 disabled: !g || b || o, 1330 onClick: T, 1331 icon: te, 1332 sx: { 1333 width: "auto", 1334 float: "right", 1335 "&:disabled": { opacity: .5 }, 1336 whiteSpace: "nowrap", 1337 px: 3 1338 }, 1339 title: "Create New Course", 1340 children: "Create New Course" 1341 }) }) 1342 })] 1343 })] 1344 }) 1345 ] 1346 }); 1347} 1348function fn({ getFieldValue: e, setFieldValue: t, mode: n = "" }) { 1349 let { card: r } = J(), { configuration: i } = E(), a = r.course, o = n === "export"; 1350 i?.User?.Entitlements?.includes("developer"); 1351 let s = a.modules.filter((e) => e.type === "quiz"), c = a.modules.filter((e) => e.type === "skillcheck"), l = e("completionType"); 1352 o && l === "skillcheck" && (l = "lesson"); 1353 function u(e) { 1354 var n = e.target.value; 1355 if (n) { 1356 var r = parseInt(n); 1357 if (r < 0 || r > 100) return; 1358 } 1359 t("completionPercent", n); 1360 } 1361 (0, Z.useEffect)(() => { 1362 l === "quiz" && !e("completionQuiz") && s.length > 0 && t("completionQuiz", s[s.length - 1].id), l === "skillcheck" && !e("completionSkillcheck") && c.length > 0 && t("completionSkillcheck", c[c.length - 1].id); 1363 }, [l]); 1364 function d(e) { 1365 var n = e.target.value; 1366 t("completionQuiz", n); 1367 } 1368 function f(e) { 1369 var n = e.target.value; 1370 t("completionSkillcheck", n); 1371 } 1372 function p(e) { 1373 "0123456789".includes(e.key) || e.preventDefault(); 1374 } 1375 return /* @__PURE__ */ (0, Q.jsxs)(C, { 1376 direction: "row", 1377 children: [/* @__PURE__ */ (0, Q.jsx)(I, { children: /* @__PURE__ */ (0, Q.jsxs)(_e, { 1378 value: l || "", 1379 onChange: (e, n) => { 1380 let r = { completionType: n }; 1381 (n === "quiz" || n === "skillcheck") && (r.completionPercent = "100"), t(r); 1382 }, 1383 children: [
1384 /* @__PURE__ */ (0, Q.jsx)(L, { 1385 value: "lesson", 1386 sx: ln, 1387 control: /* @__PURE__ */ (0, Q.jsx)(ge, {}), 1388 label: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1389 sx: sn, 1390 id: "courses.settings.courseCompletion" 1391 }), /* @__PURE__ */ (0, Q.jsx)(K, { 1392 sx: cn, 1393 id: "courses.settings.courseCompletionDesc" 1394 })] }) 1395 }), 1396 /* @__PURE__ */ (0, Q.jsx)(L, { 1397 value: "quiz", 1398 sx: ln, 1399 control: /* @__PURE__ */ (0, Q.jsx)(ge, { disabled: s.length === 0 }), 1400 label: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1401 sx: sn, 1402 id: "courses.settings.quizResults" 1403 }), /* @__PURE__ */ (0, Q.jsx)(K, { 1404 sx: cn, 1405 id: "courses.settings.quizResultsDesc" 1406 })] }) 1407 }), 1408 /* @__PURE__ */ (0, Q.jsx)(L, { 1409 value: "skillcheck", 1410 sx: ln, 1411 control: /* @__PURE__ */ (0, Q.jsx)(ge, { disabled: c.length === 0 || o }), 1412 label: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [ 1413 /* @__PURE__ */ (0, Q.jsx)(K, { 1414 sx: sn, 1415 id: "courses.settings.skillcheckResults" 1416 }), 1417 !o && /* @__PURE__ */ (0, Q.jsx)(K, { 1418 sx: cn, 1419 id: "courses.settings.skillcheckResultsDesc" 1420 }),
1421 o && /* @__PURE__ */ (0, Q.jsx)(K, { 1422 sx: cn, 1423 id: "courses.settings.skillcheckResultsExportDesc" 1424 }) 1425 ] }) 1426 }) 1427 ] 1428 }) }), /* @__PURE__ */ (0, Q.jsxs)(C, { 1429 direction: "column", 1430 justifyContent: "space-evenly", 1431 children: [ 1432 /* @__PURE__ */ (0, Q.jsx)(ke, { 1433 value: e("completionPercent") || "", 1434 InputProps: { sx: { width: "5em" } }, 1435 inputProps: { maxLength: 3 }, 1436 onKeyPress: p, 1437 onChange: u, 1438 disabled: l !== "lesson" 1439 }), 1440 /* @__PURE__ */ (0, Q.jsx)(Se, { 1441 value: e("completionQuiz") || "", 1442 onChange: d, 1443 sx: un, 1444 disabled: l !== "quiz", 1445 children: s.map((e, t) => /* @__PURE__ */ (0, Q.jsx)(F, { 1446 value: e.id, 1447 children: e.header 1448 }, e.id)) 1449 }), 1450 /* @__PURE__ */ (0, Q.jsx)(Se, { 1451 value: e("completionSkillcheck") || "", 1452 onChange: f, 1453 sx: un, 1454 disabled: l !== "skillcheck" || o, 1455 children: c.map((e, t) => /* @__PURE__ */ (0, Q.jsx)(F, { 1456 value: e.id, 1457 children: e.header 1458 }, e.id)) 1459 }) 1460 ] 1461 })] 1462 }); 1463} 1464//#endregion 1465//#region Components/Course/modifiers/pdfPrintStyles.js 1466var pn = "\n/* PDF-specific column layout fixes */\n.columns-wrapper {\n display: flex !important;\n flex-direction: row !important;\n align-items: flex-start !important;\n gap: 20px !important;\n width: 100% !important;\n}\n\n.module-column {\n flex: 1 !important;\n min-width: 0 !important;\n overflow: hidden !important;\n box-sizing: border-box !important;\n}\n\n/* Prevent text overflow in columns */\n.paragraph-column .primary-text {\n word-wrap: break-word !important;\n overflow-wrap: break-word !important;\n hyphens: auto !important;\n max-width: 100% !important;\n}\n\n/* Image column sizing */\n.image-column img {\n max-width: 100% !important;\n height: auto !important;\n display: block !important;\n}\n\n/* Ensure proper spacing for side-by-side content */\n.module-row {\n margin-bottom: 20px !important;\n page-break-inside: avoid !important;\n}\n\n/* Fix for specific multi-column layouts */\n.pdf-column-0,\n.pdf-column-1,\n.pdf-column-2 {\n flex: 1 !important;\n margin-right: 15px !important;\n}\n\n.pdf-column-0:last-child,\n.pdf-column-1:last-child,\n.pdf-column-2:last-child {\n margin-right: 0 !important;\n}\n\n/* Prevent text from overflowing container bounds */\np, span, div {\n max-width: 100% !important;\n box-sizing: border-box !important;\n}\n\n/* Ensure flex items don't shrink too much */\n.cbiv-element {\n min-width: 0 !important;\n flex-shrink: 1 !important;\n}\n\n/* Remove 3D transform artifacts from flipcard previews in PDF */\n.flipcard,\n.flipcard-inner {\n transform: none !important;\n transform-style: flat !important;\n perspective: none !important;\n backface-visibility: visible !important;\n}\n\n/* Hide flip icon in PDF â not interactive */\n.flip-icon {\n display: none !important;\n}\n\n/* Remove separator border lines that appear as artifacts */\n.pdf-interactive-separator {\n border: none !important;\n}\n\n/* Quiz preview cleanup for PDF */\n.hidden-preview-quiz .feedback,\n.hidden-preview-quiz .correct-feedback,\n.hidden-preview-quiz .incorrect-feedback {\n display: none !important;\n}\n\n/* Ensure hotspot markers are visible â disable animations only, preserve transforms */\n.marker,\n.marker-border {\n opacity: 1 !important;\n animation: none !important;\n}\n\n/* marker-content uses fadeInGrow (starts at scale(0) + opacity:0) â override both */\n.marker-content {\n opacity: 1 !important;\n animation: none !important;\n transform: scale(1) !important;\n}\n\n/* Disable fade-in animations that hide elements before they animate */\n.cbiv-element:not(.fade-in) {\n opacity: 1 !important;\n}\n\n.fade-in > * {\n animation: none !important;\n opacity: 1 !important;\n}\n", mn = "course-player-shadow-dom", hn = 200, gn = 50; 1467async function _n(e = gn) { 1468 for (let t = 0; t < e; t++) { 1469 let e = document.getElementById(mn); 1470 if (e?.shadowRoot) return e; 1471 await new Promise((e) => setTimeout(e, hn)); 1472 } 1473 throw Error("PDF preview did not load in time. Please try again."); 1474} 1475async function vn(e, t = gn) { 1476 for (let n = 0; n < t; n++) { 1477 let t = e.querySelector("#course-module"); 1478 if (t?.children?.length > 0) return t; 1479 await new Promise((e) => setTimeout(e, hn)); 1480 } 1481 throw Error("Course content did not render in time. Please try again."); 1482} 1483function yn(e) { 1484 let t = []; 1485 if (e.adoptedStyleSheets?.length > 0) for (let n of e.adoptedStyleSheets) try { 1486 t.push(Array.from(n.cssRules).map((e) => e.cssText).join("\n")); 1487 } catch {} 1488 for (let n of e.querySelectorAll("style")) n.textContent && t.push(n.textContent); 1489 if (e.styleSheets) for (let n of e.styleSheets) try { 1490 t.push(Array.from(n.cssRules).map((e) => e.cssText).join("\n")); 1491 } catch {} 1492 return [...new Set(t.filter(Boolean))].join("\n"); 1493} 1494function bn(e) { 1495 let t = e.cloneNode(!0); 1496 return t.querySelectorAll("script, noscript, [aria-hidden=\"true\"]").forEach((e) =>
1496 e.remove()), t.querySelectorAll("[style*=\"display: none\"], [style*=\"display:none\"]").forEach((e) => e.remove()), t.querySelectorAll("*").forEach((e) => { 1497 for (let t of [...e.attributes]) t.name.startsWith("data-") && t.name !== "data-testid" && e.removeAttribute(t.name); 1498 }), t.outerHTML; 1499} 1500async function xn() { 1501 let e = await _n(); 1502 return { 1503 courseHtml: bn(await vn(e.shadowRoot)), 1504 documentStyles: yn(e.shadowRoot) 1505 }; 1506} 1507function Sn(e) { 1508 return e.endsWith(".pdf") ? e : `${e}.pdf`; 1509} 1510function Cn(e, t) { 1511 let n = window.URL.createObjectURL(e), r = document.createElement("a"); 1512 r.href = n, r.download = t, document.body.appendChild(r), r.click(), document.body.removeChild(r), window.URL.revokeObjectURL(n); 1513} 1514var wn = () => { 1515 let { authRequest: e } = i(), { configuration: t } = E(), { enqueueSnackbar: n } = b(); 1516 return { exportToPDF: (0, Z.useCallback)(async (r = "export.pdf") => { 1517 try { 1518 let { courseHtml: n, documentStyles: i } = await xn(), a = `${i}\n${pn}`, o = await e({ 1519 method: "post", 1520 url: `${t.lmLinuxNodeFunctionsUrl}/exportToPdf`, 1521 data: JSON.stringify({ 1522 html: n, 1523 styles: { 1524 width: "100%", 1525 margin: "0", 1526 padding: "20px", 1527 background: "white" 1528 }, 1529 inlineStyles: a, 1530 origin: window.location.origin 1531 }), 1532 responseType: "blob" 1533 }); 1534 if (o.status !== 200) throw Error(`Server returned status ${o.status}`); 1535 let s = o.data; 1536 if (!s || s.size === 0) throw Error("Server returned an empty PDF"); 1537 Cn(s, Sn(r)); 1538 } catch (e) { 1539 console.error("PDF export failed:", e); 1540 let t = e.response?.data?.message || e.message || "An unexpected error occurred while generating the PDF"; 1541 throw n(t, { variant: "error" }), e; 1542 } 1543 }, [ 1544 e, 1545 t, 1546 n 1547 ]) }; 1548}, Tn = { 1549 mt: 2, 1550 "& > .MuiGrid-item": { 1551 color: "var(--ui-color-text-header)", 1552 backgroundColor: "var(--ui-color-surface-paper)", 1553 justifyContent: "center", 1554 justifySelf: "center", 1555 my: 1, 1556 py: 2 1557 }, 1558 "& > .MuiGrid-item > *": { ml: 2 } 1559}, En = { 1560 fontWeight: "var(--font-weight-medium)", 1561 color: "var(--ui-color-text)", 1562 mb: 1 1563}, Dn = { 1564 height: "2.2em", 1565 width: "20em", 1566 mr: 2, 1567 my: 1 1568}, On = { 1569 fontSize: "smaller", 1570 fontWeight: "var(--font-weight-regular)", 1571 color: "var(--ui-color-text)", 1572 fontStyle: "italic" 1573}, kn = (0, Z.forwardRef)(function(e, n) { 1574 let { card: r } = J(), [i] = t(), { enqueueSnackbar: a } = b(), { formatMessage: o } = ee(), { exportToPDF: s } = wn(i), c = (0, Z.useMemo)(() => Ft(r), [r]), l = Lt((0, Z.useMemo)(() => c.forbiddenDetails?.filter((e) => e.type === "largeVideo") || [], [c.forbiddenDetails])), u = c.hasLargeVid, d = () => u ? "pdf" : "launch", [f, p] = (0, Z.useState)({ 1575 ...r, 1576 course: { 1577 ...r.course, 1578 exportType: d(), 1579 scormReporting: r.course.completionType === "quiz" ? "passed" : "completed" 1580 } 1581 }), { post: m } = v("/Course/ExportCourse", { 1582 cachePolicy: "no-cache", 1583 headers: { RequestVerificationToken: i } 1584 }); 1585 (0, Z.useEffect)(() => { 1586 n.current = h; 1587 }); 1588 async function h() { 1589 let { assets: e, courseWithAssets: t } = gt(f, !0); 1590 f.course = { 1591 ...f.course, 1592 ...t 1593 }, f.AssetsJson = JSON.stringify(e); 1594 let n = JSON.stringify(f.course); 1595 if (f.Json = n, f.course.exportType === "pdf") try { 1596 await s(f.Header ?? "Course"), console.log("PDF generation completed."); 1597 return; 1598 } catch (e) { 1599 console.error("Error generating PDF:", e); 1600 return; 1601 } 1602 let r = await m("", f); 1603 r && (r.success ? (a(o({ id: "builder.save.ExportedSuccessfully" })), window.open(r.url)) : a(r.message || "error", { variant: "error" })); 1604 } 1605 let g = (e) => f[e], _ = (e, t) => p({ 1606 ...f, 1607 [e]: t 1608 }), y = (e) => g("course")[e], S = (e, t) => _("course", { 1609 ...f.course, 1610 ...typeof e == "object" ? e : { [e]: t } 1611 }); 1612 return /* @__PURE__ */ (0, Q.jsxs)(R, { 1613 container: !0, 1614 spacing: 2, 1615 sx: Tn, 1616 children: [ 1617 /* @__PURE__ */ (0, Q.jsx)(rn, { 1618 getFieldValue: g, 1619 setFieldValue: _ 1620 }), 1621 /* @__PURE__ */ (0, Q.jsx)(R, { 1622 item: !0, 1623 xs: 12, 1624 children: /* @__PURE__ */ (0, Q.jsxs)(C, { children: [ 1625 /* @__PURE__ */ (0, Q.jsx)(K, { 1626 id: "builder.export.exportsettings", 1627 sx: En 1628 }),
1629 /* @__PURE__ */ (0, Q.jsxs)(Se, { 1630 value: y("exportType"), 1631 onChange: (e) => S("exportType", e.target.value), 1632 sx: Dn, 1633 children: [ 1634 /* @__PURE__ */ (0, Q.jsx)(F, { 1635 value: "launch", 1636 disabled: u, 1637 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.export.optionlaunch" }) 1638 }), 1639 /* @__PURE__ */ (0, Q.jsx)(F, { 1640 value: "scorm12", 1641 disabled: u, 1642 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.export.optionscorm12" }) 1643 }), 1644 /* @__PURE__ */ (0, Q.jsx)(F, { 1645 value: "scorm2004", 1646 disabled: u, 1647 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.export.optionscorm2004" }) 1648 }), 1649 /* @__PURE__ */ (0, Q.jsx)(F, { 1650 value: "pdf", 1651 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.export.optionpdf" }) 1652 }) 1653 ] 1654 }), 1655 u && /* @__PURE__ */ (0, Q.jsxs)(C, { 1656 direction: "column", 1657 sx: { 1658 mt: 2, 1659 mb: 2 1660 }, 1661 children: [ 1662 /* @__PURE__ */ (0, Q.jsxs)(C, { 1663 direction: "row", 1664 alignItems: "center", 1665 spacing: 1, 1666 children: [/* @__PURE__ */ (0, Q.jsx)(x, { 1667 icon: ne, 1668 style: { 1669 color: "var(--ui-color-warning)", 1670 fontSize: "1.2em" 1671 } 1672 }), /* @__PURE__ */ (0, Q.jsx)(K, { 1673 sx: En, 1674 id: "builder.export.no-elearning-export" 1675 })] 1676 }), 1677 /* @__PURE__ */ (0, Q.jsx)(K, { 1678 sx: On, 1679 id: "builder.export.forbidden-header" 1680 }), 1681 /* @__PURE__ */ (0, Q.jsx)(Bt, { details: l }) 1682 ] 1683 }), 1684 r.course.modules.some((e) =>
1684 e.type === "skillcheck") && /* @__PURE__ */ (0, Q.jsx)(k, { 1685 sx: On, 1686 children: "Skill Checks will not be included in the export." 1687 }) 1688 ] }) 1689 }), 1690 y("exportType") !== "pdf" && /* @__PURE__ */ (0, Q.jsx)(R, { 1691 item: !0, 1692 xs: 12, 1693 children: /* @__PURE__ */ (0, Q.jsxs)(C, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1694 id: "builder.export.completion", 1695 sx: En 1696 }), /* @__PURE__ */ (0, Q.jsx)(fn, { 1697 getFieldValue: y, 1698 setFieldValue: S, 1699 mode: "export" 1700 })] }) 1701 }), 1702 ["scorm12"].includes(y("exportType")) && /* @__PURE__ */ (0, Q.jsx)(R, { 1703 item: !0, 1704 xs: 12, 1705 children: /* @__PURE__ */ (0, Q.jsxs)(C, { children: [/* @__PURE__ */ (0, Q.jsx)(K, { 1706 id: "builder.export.reporting", 1707 sx: En 1708 }), /* @__PURE__ */ (0, Q.jsxs)(Se, { 1709 value: y("scormReporting"), 1710 onChange: (e) => S("scormReporting", e.target.value), 1711 sx: Dn, 1712 children: [/* @__PURE__ */ (0, Q.jsx)(F, { 1713 value: "passed", 1714 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.export.scormpassed" }) 1715 }), /* @__PURE__ */ (0, Q.jsx)(F, { 1716 value: "completed", 1717 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.export.scormcompleted" }) 1718 })] 1719 })] }) 1720 }), 1721 y("exportType") === "pdf" && /* @__PURE__ */ (0, Q.jsx)("div", { 1722 id: "exportcourse-preview", 1723 style: { 1724 position: "absolute", 1725 top: "-9999px", 1726 left: "-9999px", 1727 visibility: "hidden" 1728 }, 1729 children: /* @__PURE__ */ (0, Q.jsx)(_t, { isExportCoursePreview: !0 }) 1730 }) 1731 ] 1732 }); 1733}), An = { 1734 mt: 2, 1735 "& > .MuiGrid-item": { 1736 color: "var(--ui-color-text-header)", 1737 backgroundColor: "white", 1738 justifyContent: "center", 1739 justifySelf: "center", 1740 my: 1, 1741 py: 2 1742 }, 1743 "& > .MuiGrid-item > *": { ml: 2 } 1744}, jn = { 1745 fontWeight: "var(--font-weight-medium)", 1746 color: "var(--ui-color-text)", 1747 mb: 1 1748}, Mn = { 1749 "& .MuiTableCell-head": { 1750 fontWeight: "var(--font-weight-semibold)", 1751 fontSize: "var(--font-size-base)", 1752 backgroundColor: "#efefef !important", 1753 color: "var(--ui-color-text)", 1754 zIndex: 2 1755 }, 1756 "& .MuiTableCell-body": { 1757 fontSize: "var(--font-size-base)", 1758 color: "var(--ui-color-text)" 1759 }, 1760 "& .MuiTableBody-root .MuiTableRow-root:nth-of-type(odd)": { backgroundColor: "#fafafa" }, 1761 "& .MuiTableBody-root .MuiTableRow-root:nth-of-type(even)": { backgroundColor: "#ffffff" }, 1762 "& .MuiTableRow-root:last-child .MuiTableCell-body": { borderBottom: "none" } 1763}, Nn = (0, Z.forwardRef)(function({ onHasModifiedChange: e }, n) { 1764 let { card: r } = J(), [i] = t(), { enqueueSnackbar: a } = b(), { formatMessage: o } = ee(), [s, c] = (0, Z.useState)(null), [l, u] = (0, Z.useState)(null), [d, f] = (0, Z.useState)(!0), [p, m] = (0, Z.useState)(!1), { get: h } = v(`/Course/GetLinkedCourses/${r.CardId}`, { cachePolicy: "no-cache" }), { post: g } = v(`/Course/SyncLinkedCourses/${r.CardId}`, { 1765 cachePolicy: "no-cache", 1766 headers: { RequestVerificationToken: i } 1767 }), { post: _ } = v(`/Course/SyncLinkedCourses/${r.CardId}?unmodifiedOnly=true`, { 1768 cachePolicy: "no-cache", 1769 headers: { RequestVerificationToken: i } 1770 }); 1771 (0, Z.useEffect)(() => { 1772 T().catch((e) => console.log("error loading linked courses", e)).finally(() => f(!1)); 1773 }, []), (0, Z.useEffect)(() => { 1774 n.current = { 1775 syncAll: D, 1776 syncUnmodifiedOnly: O 1777 }; 1778 }); 1779 let S = s?.filter((e) => e.hasBeenModified).length ?? 0, w = S > 0; 1780 (0, Z.useEffect)(() => { 1781 e?.(w); 1782 }, [w]); 1783 async function T() { 1784 let e = await h(); 1785 e?.success && (c(e.linkedCourses), u(e.copiedFrom)); 1786 } 1787 async function E(e, t) { 1788 m(!0); 1789 try { 1790 let n = await e(""); 1791 if (n?.success) { 1792 let e = n.errors > 0 ? o({ id: "builder.sync.completedWithErrors" }, { 1793 completed: n.completed, 1794 errors: n.errors 1795 }) : o({ id: t }, { completed: n.completed }); 1796 a(e, { variant: n.errors > 0 ? "warning" : "success" }), await T(); 1797 } else a(n?.message || o({ id: "GenericError" }), { variant: "error" }); 1798 } finally { 1799 m(!1); 1800 } 1801 } 1802 async function D() { 1803 await E(g, "builder.sync.started"); 1804 } 1805 async function O() { 1806 await E(_, "builder.sync.startedUnmodified"); 1807 } 1808 return /* @__PURE__ */ (0, Q.jsx)(R, { 1809 container: !0, 1810 spacing: 2, 1811 sx: An, 1812 children: /* @__PURE__ */ (0, Q.jsx)(R, { 1813 item: !0, 1814 xs: 12, 1815 children: /* @__PURE__ */ (0, Q.jsxs)(C, { children: [
1816 /* @__PURE__ */ (0, Q.jsx)(K, { 1817 id: "builder.sync.title", 1818 sx: jn 1819 }), 1820 /* @__PURE__ */ (0, Q.jsx)(k, { 1821 sx: { 1822 fontSize: "smaller", 1823 color: "var(--ui-color-text)", 1824 fontStyle: "italic", 1825 mb: 2 1826 }, 1827 children: o({ id: "builder.sync.description" }) 1828 }), 1829 d && /* @__PURE__ */ (0, Q.jsx)(y, { 1830 sx: { 1831 display: "flex", 1832 justifyContent: "center", 1833 py: 4 1834 }, 1835 children: /* @__PURE__ */ (0, Q.jsx)(se, {}) 1836 }), 1837 !d && (!s || s.length === 0) && /* @__PURE__ */ (0, Q.jsx)(K, { 1838 id: "builder.sync.noLinkedCourses", 1839 sx: { 1840 color: "var(--ui-color-text)", 1841 py: 2 1842 } 1843 }), 1844 !d && l && /* @__PURE__ */ (0, Q.jsxs)(C, { 1845 direction: "row", 1846 alignItems: "center", 1847 spacing: 2, 1848 sx: { 1849 mb: 2, 1850 p: 2, 1851 backgroundColor: "#efefef", 1852 borderRadius: "var(--radius-md)" 1853 }, 1854 children: [/* @__PURE__ */ (0, Q.jsx)(x, { 1855 icon: ne, 1856 style: { 1857 color: "var(--ui-color-warning)", 1858 fontSize: "40px", 1859 flexShrink: 0 1860 } 1861 }), /* @__PURE__ */ (0, Q.jsxs)(y, { children: [/* @__PURE__ */ (0, Q.jsxs)(k, { 1862 sx: { 1863 fontSize: "smaller", 1864 fontWeight: "var(--font-weight-medium)", 1865 color: "var(--ui-color-text)", 1866 mb: .5 1867 }, 1868 children: [ 1869 o({ id: "builder.sync.copiedFrom" }), 1870 " ", 1871 /* @__PURE__ */ (0, Q.jsx)("strong", { children: l.header }), 1872 " in ", 1873 /* @__PURE__ */ (0, Q.jsx)("strong", { children: l.accountName }) 1874 ] 1875 }), /* @__PURE__ */ (0, Q.jsx)(k, { 1876 sx: { 1877 fontSize: "smaller", 1878 color: "var(--ui-color-text)", 1879 fontStyle: "italic" 1880 }, 1881 children: o({ id: "builder.sync.copiedFromHint" }) 1882 })] })] 1883 }), 1884 !d && s?.length > 0 && /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [
1885 p && /* @__PURE__ */ (0, Q.jsxs)(y, { 1886 sx: { mb: 2 }, 1887 children: [/* @__PURE__ */ (0, Q.jsx)(k, { 1888 sx: { 1889 fontSize: "var(--font-size-base)", 1890 color: "var(--ui-color-text)", 1891 mb: 1 1892 }, 1893 children: o({ id: "builder.sync.inProgress" }, { count: s.length }) 1894 }), /* @__PURE__ */ (0, Q.jsx)(z, {})] 1895 }), 1896 /* @__PURE__ */ (0, Q.jsx)(k, { 1897 sx: { 1898 fontSize: "var(--font-size-base)", 1899 color: "var(--ui-color-text)", 1900 mb: w ? .5 : 1 1901 }, 1902 children: o({ id: "builder.sync.totalCourses" }, { count: s.length }) 1903 }), 1904 w && /* @__PURE__ */ (0, Q.jsxs)(k, { 1905 sx: { 1906 fontSize: "var(--font-size-sm)", 1907 color: "var(--ui-color-warning)", 1908 mb: 1 1909 }, 1910 children: [/* @__PURE__ */ (0, Q.jsx)(x, { 1911 icon: M, 1912 style: { 1913 fontSize: "var(--font-size-base)", 1914 verticalAlign: "text-bottom", 1915 marginRight: "4px" 1916 } 1917 }), o({ id: "builder.sync.modifiedWarning" }, { count: S })] 1918 }), 1919 /* @__PURE__ */ (0, Q.jsx)(Le, { 1920 sx: { 1921 border: "1px solid var(--color-gray-light)", 1922 borderRadius: "var(--radius-md)", 1923 maxHeight: "50vh", 1924 maxWidth: "calc(100vw - 120px)", 1925 overflow: "auto", 1926 opacity: p ? .5 : 1, 1927 pointerEvents: p ? "none" : "auto", 1928 transition: "opacity var(--motion-base)" 1929 }, 1930 children: /* @__PURE__ */ (0, Q.jsxs)(H, { 1931 stickyHeader: !0, 1932 size: "small", 1933 sx: Mn, 1934 children: [/* @__PURE__ */ (0, Q.jsx)(Pe, { children: /* @__PURE__ */ (0, Q.jsxs)(Ie, { children: [ 1935 /* @__PURE__ */ (0, Q.jsx)(V, { children: o({ id: "builder.sync.accountName" }) }), 1936 /* @__PURE__ */ (0, Q.jsx)(V, { children: o({ id: "builder.sync.courseName" }) }), 1937 /* @__PURE__ */ (0, Q.jsx)(V, { 1938 align: "center", 1939 children: o({ id: "builder.sync.publishedDate" }) 1940 }), 1941 /* @__PURE__ */ (0, Q.jsx)(V, { 1942 align: "center", 1943 children: o({ id: "builder.sync.status" }) 1944 }) 1945 ] }) }
1945), /* @__PURE__ */ (0, Q.jsx)(Fe, { children: s.map((e) => /* @__PURE__ */ (0, Q.jsxs)(Ie, { children: [ 1946 /* @__PURE__ */ (0, Q.jsx)(V, { children: e.accountName }), 1947 /* @__PURE__ */ (0, Q.jsx)(V, { children: e.header }), 1948 /* @__PURE__ */ (0, Q.jsx)(V, { 1949 align: "center", 1950 children: e.publishDate ? new Date(e.publishDate).toLocaleDateString() : "â" 1951 }), 1952 /* @__PURE__ */ (0, Q.jsx)(V, { 1953 align: "center", 1954 children: e.hasBeenModified ? /* @__PURE__ */ (0, Q.jsx)(P, { 1955 icon: /* @__PURE__ */ (0, Q.jsx)(x, { icon: M }), 1956 label: o({ id: "builder.sync.modified" }), 1957 size: "small", 1958 color: "warning", 1959 variant: "outlined" 1960 }) : /* @__PURE__ */ (0, Q.jsx)(P, { 1961 label: o({ id: "builder.sync.unmodified" }), 1962 size: "small", 1963 color: "success", 1964 variant: "outlined" 1965 }) 1966 }) 1967 ] }, e.cardId)) })] 1968 }) 1969 }) 1970 ] }) 1971 ] }) 1972 }) 1973 }); 1974}), Pn = (e) => { 1975 let t = new Date(e), n = Math.round(((/* @__PURE__ */ new Date()).getTime() - t.getTime()) / 1e3), r = Math.round(n / 60), i = Math.round(r / 60), a = Math.round(i / 24), o = Math.round(a / 7); 1976 return r < 1 ? "0m" : r < 60 ? `${r}m` : i < 24 ? `${i}h` : a < 7 ? `${a}d` : `${o}w`; 1977}, Fn = "@font-face{font-family:swiper-icons;src:url(\"data:application/font-woff;charset=utf-8;base64, d09GRgABAAAAAAZgABAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAGRAAAABoAAAAci6qHkUdERUYAAAWgAAAAIwAAACQAYABXR1BPUwAABhQAAAAuAAAANuAY7+xHU1VCAAAFxAAAAFAAAABm2fPczU9TLzIAAAHcAAAASgAAAGBP9V5RY21hcAAAAkQAAACIAAABYt6F0cBjdnQgAAACzAAAAAQAAAAEABEBRGdhc3AAAAWYAAAACAAAAAj//wADZ2x5ZgAAAywAAADMAAAD2MHtryVoZWFkAAABbAAAADAAAAA2E2+eoWhoZWEAAAGcAAAAHwAAACQC9gDzaG10eAAAAigAAAAZAAAArgJkABFsb2NhAAAC0AAAAFoAAABaFQAUGG1heHAAAAG8AAAAHwAAACAAcABAbmFtZQAAA/gAAAE5AAACXvFdBwlwb3N0AAAFNAAAAGIAAACE5s74hXjaY2BkYGAAYpf5Hu/j+W2+MnAzMYDAzaX6QjD6/4//Bxj5GA8AuRwMYGkAPywL13jaY2BkYGA88P8Agx4j+/8fQDYfA1AEBWgDAIB2BOoAeNpjYGRgYNBh4GdgYgABEMnIABJzYNADCQAACWgAsQB42mNgYfzCOIGBlYGB0YcxjYGBwR1Kf2WQZGhhYGBiYGVmgAFGBiQQkOaawtDAoMBQxXjg/wEGPcYDDA4wNUA2CCgwsAAAO4EL6gAAeNpj2M0gyAACqxgGNWBkZ2D4/wMA+xkDdgAAAHjaY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMOgyWDLEM1T9/w8UBfEMgLzE////P/5//f/V/xv+r4eaAAeMbAxwIUYmIMHEgKYAYjUcsDAwsLKxc3BycfPw8jEQA/gZBASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTQZBgMAAMR+E+gAEQFEAAAAKgAqACoANAA+AEgAUgBcAGYAcAB6AIQAjgCYAKIArAC2AMAAygDUAN4A6ADyAPwBBgEQARoBJAEuATgBQgFMAVYBYAFqAXQBfgGIAZIBnAGmAbIBzgHsAAB42u2NMQ6CUAyGW568x9AneYYgm4MJbhKFaExIOAVX8ApewSt4Bic4AfeAid3VOBixDxfPYEza5O+Xfi04YADggiUIULCuEJK8VhO4bSvpdnktHI5QCYtdi2sl8ZnXaHlqUrNKzdKcT8cjlq+rwZSvIVczNiezsfnP/uznmfPFBNODM2K7MTQ45YEAZqGP81AmGGcF3iPqOop0r1SPTaTbVkfUe4HXj97wYE+yNwWYxwWu4v1ugWHgo3S1XdZEVqWM7ET0cfnLGxWfkgR42o2PvWrDMBSFj/IHLaF0zKjRgdiVMwScNRAoWUoH78Y2icB/yIY09An6AH2Bdu/UB+yxopYshQiEvnvu0dURgDt8QeC8PDw7Fpji3fEA4z/PEJ6YOB5hKh4dj3EvXhxPqH/SKUY3rJ7srZ4FZnh1PMAtPhwP6fl2PMJMPDgeQ4rY8YT6Gzao0eAEA409DuggmTnFnOcSCiEiLMgxCiTI6Cq5DZUd3Qmp10vO0LaLTd2cjN4fOumlc7lUYbSQcZFkutRG7g6JKZKy0RmdLY680CDnEJ+UMkpFFe1RN7nxdVpXrC4aTtnaurOnYercZg2YVmLN/d/gczfEimrE/fs/bOuq29Zmn8tloORaXgZgGa78yO9/cnXm2BpaGvq25Dv9S4E9+5SIc9PqupJKhYFSSl47+Qcr1mYNAAAAeNptw0cKwkAAAMDZJA8Q7OUJvkLsPfZ6zFVERPy8qHh2YER+3i/BP83vIBLLySsoKimrqKqpa2hp6+jq6RsYGhmbmJqZSy0sraxtbO3sHRydnEMU4uR6yx7JJXveP7WrDycAAAAAAAH//wACeNpjYGRgYOABYhkgZgJCZgZNBkYGLQZtIJsFLMYAAAw3ALgAeNolizEKgDAQBCchRbC2sFER0YD6qVQiBCv/H9ezGI6Z5XBAw8CBK/m5iQQVauVbXLnOrMZv2oLdKFa8Pjuru2hJzGabmOSLzNMzvutpB3N42mNgZGBg4GKQYzBhYMxJLMlj4GBgAYow/P/PAJJhLM6sSoWKfWCAAwDAjgbRAAB42mNgYGBkAIIbCZo5IPrmUn0hGA0AO8EFTQAA\");font-weight:400;font-style:normal}:root{--swiper-theme-color:#007aff}.swiper{z-index:1;margin-left:auto;margin-right:auto;padding:0;list-style:none;display:block;position:relative;overflow:clip}.swiper-vertical>.swiper-wrapper{flex-direction:column}.swiper-wrapper{z-index:1;width:100%;height:100%;transition-property:transform;transition-timing-function:var(--swiper-wrapper-transition-timing-function,initial);box-sizing:content-box;display:flex;position:relative}.swiper-android .swiper-slide,.swiper-ios .swiper-slide,.swiper-wrapper{transform:translate(0,0)}.swiper-horizontal{touch-action:pan-y}.swiper-vertical{touch-action:pan-x}.swiper-slide{flex-shrink:0;width:100%;height:100%;transition-property:transform;display:block;position:relative}.swiper-slide-invisible-blank{visibility:hidden}.swiper-autoheight,.swiper-autoheight .swiper-slide{height:auto}.swiper-autoheight .swiper-wrapper{align-items:flex-start;transition-property:transform,height}.swiper-backface-hidden .swiper-slide{backface-visibility:hidden;transform:translateZ(0)}.swiper-3d.swiper-css-mode .swiper-wrapper{perspective:1200px}.swiper-3d .swiper-wrapper{transform-style:preserve-3d}.swiper-3d{perspective:1200px}.swiper-3d .swiper-cube-shadow,.swiper-3d .swiper-slide{transform-style:preserve-3d}.swiper-css-mode>.swiper-wrapper{scrollbar-width:none;-ms-overflow-style:none;overflow:auto}.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar{display:none}.swiper-css-mode>.swiper-wrapper>.swiper-slide{scroll-snap-align:start start}.swiper-css-mode.swiper-horizontal>.swiper-wrapper{scroll-snap-type:x mandatory}.swiper-css-mode.swiper-vertical>.swiper-wrapper{scroll-snap-type:y mandatory}.swiper-css-mode.swiper-free-mode>.swiper-wrapper{scroll-snap-type:none}.swiper-css-mode.swiper-free-mode>.swiper-wrapper>.swiper-slide{scroll-snap-align:none}.swiper-css-mode.swiper-centered>.swiper-wrapper:before{content:\"\";flex-shrink:0;order:9999}.swiper-css-mode.swiper-centered>.swiper-wrapper>.swiper-slide{scroll-snap-align:center center;scroll-snap-stop:always}.swiper-css-mode.swiper-centered.swiper-horizontal>.swiper-wrapper>.swiper-slide:first-child{margin-inline-start:var(--swiper-centered-offset-before)}.swiper-css-mode.swiper-centered.swiper-horizontal>.swiper-wrapper:before{height:100%;min-height:1px;width:var(--swiper-centered-offset-after)}.swiper-css-mode.swiper-centered.swiper-vertical>.swiper-wrapper>.swiper-slide:first-child{margin-block-start:var(--swiper-centered-offset-before)}.swiper-css-mode.swiper-centered.swiper-vertical>.swiper-wrapper:before{width:100%;min-width:1px;height:var(--swiper-centered-offset-after)}.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top{pointer-events:none;z-index:10;width:100%;height:100%;position:absolute;top:0;left:0}.swiper-3d .swiper-slide-shadow{background:#00000026}.swiper-3d .swiper-slide-shadow-left{background-image:linear-gradient(270deg,#00000080,#0000)}.swiper-3d .swiper-slide-shadow-right{background-image:linear-gradient(90deg,#00000080,#0000)}.swiper-3d .swiper-slide-shadow-top{background-image:linear-gradient(#0000,#00000080)}.swiper-3d .swiper-slide-shadow-bottom{background-image:linear-gradient(#00000080,#0000)}.swiper-lazy-preloader{z-index:10;transform-origin:50%;box-sizing:border-box;border:4px solid var(--swiper-preloader-color,var(--swiper-theme-color));border-top-color:#0000;border-radius:50%;width:42px;height:42px;margin-top:-21px;margin-left:-21px;position:absolute;top:50%;left:50%}.swiper-watch-progress .swiper-slide-visible .swiper-lazy-preloader,.swiper:not(.swiper-watch-progress) .swiper-lazy-preloader{animation:1s linear infinite swiper-preloader-spin}.swiper-lazy-preloader-white{--swiper-preloader-color:#fff}.swiper-lazy-preloader-black{--swiper-preloader-color:#000}@keyframes swiper-preloader-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}", In = { 1978 "& .MuiDialog-paper": { 1979 p: 2, 1980 borderRadius: "var(--radius-lg)", 1981 maxWidth: "800px" 1982 }, 1983 "& .MuiDialogContent-root": { padding: "20px 10px 0px 10px" } 1984}, Ln = { 1985 color: "var(--ui-color-text-hdr)", 1986 fontFamily: "Open Sans", 1987 fontSize: "var(--font-size-md)", 1988 whiteSpace: "pre-wrap" 1989}, Rn = { 1990 color: "var(--ui-color-text-hdr)", 1991 fontFamily: "Open Sans", 1992 fontSize: "var(--font-size-md)", 1993 fontWeight: "var(--font-weight-semibold)", 1994 whiteSpace: "pre-wrap", 1995 mb: 1 1996}; 1997function zn({ ackType: e, show: n = !0, onClose: r = (e) => {}, titleIcon: i, note: a = null }) { 1998 let o = (0, Z.useRef)(), { enqueueSnackbar: s } = b(), [c] = t(), { configuration: l, refreshConfiguration: u } = E(), { post: d } = v("/users/dismiss", { headers: { RequestVerificationToken: c } }); 1999 async function f() { 2000 if (o.current.checked) { 2001 var t = await d(`?type=${e}`); 2002 t?.success ? u() : s(t?.message || "error", { variant: "error" }); 2003 } 2004 r(o.current.checked); 2005 } 2006 let p = !l?.User?.Entitlements?.includes(`dismiss.${e}`) && n;
2007 return l != null && /* @__PURE__ */ (0, Q.jsx)(Te, { 2008 open: p, 2009 onClose: f, 2010 sx: In, 2011 children: /* @__PURE__ */ (0, Q.jsxs)(Ee, { children: [/* @__PURE__ */ (0, Q.jsx)(Je, { 2012 sx: { 2013 position: "absolute", 2014 right: 8, 2015 top: 8 2016 }, 2017 onClick: f 2018 }), /* @__PURE__ */ (0, Q.jsxs)(R, { 2019 container: !0, 2020 spacing: 2, 2021 alignItems: "flex-start", 2022 children: [ 2023 /* @__PURE__ */ (0, Q.jsx)(R, { 2024 item: !0, 2025 xs: "auto", 2026 children: i 2027 }), 2028 /* @__PURE__ */ (0, Q.jsxs)(R, { 2029 item: !0, 2030 xs: !0, 2031 children: [ 2032 /* @__PURE__ */ (0, Q.jsx)(K, { 2033 sx: Rn, 2034 id: `builder.acknowledge.title.${e}` 2035 }), 2036 /* @__PURE__ */ (0, Q.jsx)(K, { 2037 sx: Ln, 2038 id: `builder.acknowledge.${e}` 2039 }), 2040 a && /* @__PURE__ */ (0, Q.jsx)(y, { 2041 sx: { mt: 2 }, 2042 children: a 2043 }) 2044 ] 2045 }), 2046 /* @__PURE__ */ (0, Q.jsx)(R, { 2047 item: !0, 2048 xs: 12, 2049 children: /* @__PURE__ */ (0, Q.jsxs)(C, { 2050 direction: "row", 2051 justifyContent: "space-between", 2052 alignItems: "center", 2053 sx: { mt: 2 }, 2054 children: [/* @__PURE__ */ (0, Q.jsx)(L, { 2055 label: "Don't show this message again", 2056 control: /* @__PURE__ */ (0, Q.jsx)(we, { inputRef: o }) 2057 }), /* @__PURE__ */ (0, Q.jsx)(O, { 2058 variant: "contained", 2059 onClick: f, 2060 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: `builder.acknowledge.review.${e}` }) 2061 })] 2062 }) 2063 }) 2064 ] 2065 })] }) 2066 }); 2067} 2068//#endregion 2069//#region Components/Builder/TemplateAcknowledgmentDialog.jsx 2070function Bn(e) { 2071 let t = new URLSearchParams(window.location.search).get("fromTemplate") === "true", [n, r] = (0, Z.useState)(t), i = Ge(); 2072 function a() { 2073 let e = new URLSearchParams(window.location.search); 2074 e.delete("fromTemplate"); 2075 let t = `${window.location.pathname}?${e.toString()}`; 2076 i(t, { replace: !0 }), r(!1); 2077 } 2078 return /* @__PURE__ */ (0, Q.jsx)(zn, { 2079 ackType: "templateAck", 2080 onClose: a, 2081 show: n, 2082 titleIcon: /* @__PURE__ */ (0, Q.jsx)(x, { 2083 icon: fe, 2084 style: { 2085 fontSize: "56px", 2086 color: "var(--color-teal)" 2087 } 2088 }) 2089 }); 2090} 2091//#endregion 2092//#region Components/Builder/KeyHandler.jsx 2093function Vn(e, t, n, r, i, a) { 2094 let { enqueueSnackbar: o } = b(), { formatMessage: s } = ee(), c = Ge(), { card: l, setCardField: u, dirty: d, setDirty: f } = J(), [p, m] = (0, Z.useState)(!1), [h, g] = (0, Z.useState)(!1); 2095 (0, Z.useEffect)(() => { 2096 let e = _; 2097 return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e); 2098 }); 2099 async function _(d) { 2100 if (d.ctrlKey && d.key === "s") { 2101 if (d.preventDefault(), d.stopPropagation(), a && a()) return; 2102 try { 2103 var h = await e(!1); 2104 if (f(!1), h.VersionId && l.VersionId !== h.VersionId) { 2105 var _ = window.location.pathname.replace(l.VersionId, h.VersionId); 2106 c(_, { replace: !0 }), u({ 2107 VersionId: h.VersionId, 2108 IsPublished: !1 2109 }, !0); 2110 } 2111 o(s({ id: "builder.save.SavedSuccessfully" })); 2112 } catch (e) { 2113 o(e || "error", { variant: "error" }); 2114 } 2115 } else d.ctrlKey && d.key === "p" ? (d.preventDefault(), d.stopPropagation(), t ? n(r) : i()) : d.ctrlKey && d.shiftKey && d.key.toLowerCase() === "x" ? (d.preventDefault(), d.stopPropagation(), m(!0)) : p === !0 && d.key && (d.key.toUpperCase() === "M" ? (d.preventDefault(), m(!1), g(!0)) : m(!1)); 2116 } 2117 return h ? /* @__PURE__ */ (0, Q.jsx)(Hn, { onClose: () => g(!1) }) : null; 2118} 2119function Hn({ onClose: e }) { 2120 let { card: t } = J(), [n, r] = (0, Z.useState)(t.CardType === "Course" ? 0 : 1); 2121 return /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [/* @__PURE__ */ (0, Q.jsx)("link", { 2122 href: "/css/shared/shared.css", 2123 rel: "stylesheet" 2124 }
2124), /* @__PURE__ */ (0, Q.jsxs)(Te, { 2125 open: !0, 2126 onClose: e, 2127 variant: "lm-themed", 2128 sx: { 2129 m: 1, 2130 maxHeight: "90vh", 2131 minHeight: "90vh" 2132 }, 2133 children: [ 2134 /* @__PURE__ */ (0, Q.jsxs)(Oe, { children: [ 2135 /* @__PURE__ */ (0, Q.jsx)(k, { 2136 className: "title", 2137 children: "Maintenance Functions" 2138 }), 2139 /* @__PURE__ */ (0, Q.jsx)(Je, { 2140 onClick: e, 2141 sx: { 2142 position: "absolute", 2143 right: 8, 2144 top: 8 2145 } 2146 }), 2147 /* @__PURE__ */ (0, Q.jsxs)(Ne, { 2148 value: n, 2149 onChange: (e, t) => r(t), 2150 children: [/* @__PURE__ */ (0, Q.jsx)(B, { 2151 disabled: t.CardType !== "Course", 2152 label: "JSON" 2153 }), /* @__PURE__ */ (0, Q.jsx)(B, { label: "Word Search" })] 2154 }) 2155 ] }), 2156 /* @__PURE__ */ (0, Q.jsxs)(Ee, { children: [n === 0 && t.CardType === "Course" && /* @__PURE__ */ (0, Q.jsx)(Un, {}), n === 1 && /* @__PURE__ */ (0, Q.jsx)(Wn, { words: [ 2157 "GABE", 2158 "CYRUS", 2159 "JOBO", 2160 "VICTORIA", 2161 "NICK", 2162 "HIMANSHU", 2163 "AVIRAJ", 2164 "DRILL" 2165 ] })] }), 2166 /* @__PURE__ */ (0, Q.jsx)(O, { 2167 onClick: e, 2168 sx: { 2169 width: "100%", 2170 m: 2, 2171 ml: "auto" 2172 }, 2173 children: "Close" 2174 }) 2175 ] 2176 })] }); 2177} 2178function Un() { 2179 let { enqueueSnackbar: e } = b(), { card: t, setCardField: n } = J(), [r, i] = (0, Z.useState)(JSON.stringify(t.course || {}, null, 2)); 2180 function a() { 2181 if (r) { 2182 let e = JSON.parse(r); 2183 n({ course: e }); 2184 } 2185 } 2186 function o() { 2187 navigator.clipboard.writeText(r), e("Copied"); 2188 } 2189 return /* @__PURE__ */ (0, Q.jsx)(Q.Fragment, { children: /* @__PURE__ */ (0, Q.jsxs)(y, { 2190 sx: { 2191 display: "flex", 2192 flexDirection: "column", 2193 gap: 2, 2194 my: 1 2195 }, 2196 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 2197 sx: { 2198 display: "flex", 2199 gap: 2 2200 }, 2201 children: [/* @__PURE__ */ (0, Q.jsx)(ve, { 2202 onClick: o, 2203 title: "Copy to Clipboard", 2204 children: /* @__PURE__ */ (0, Q.jsx)(x, { icon: re }) 2205 }), /* @__PURE__ */ (0, Q.jsx)(O, { 2206 onClick: a, 2207 sx: { m: 0 }, 2208 children: "Import" 2209 })] 2210 }), /* @__PURE__ */ (0, Q.jsx)(y, { children: /* @__PURE__ */ (0, Q.jsx)(xe, { 2211 minRows: 20, 2212 sx: { 2213 fontFamily: "monospace", 2214 fontSize: 14, 2215 overflow: "auto" 2216 }, 2217 defaultValue: r, 2218 onChange: (e) => i(e.target.value) 2219 }) })] 2220 }) }); 2221} 2222var Wn = ({ words: e, gridSize: t = 10 }) => { 2223 let [n, r] = (0, Z.useState)([]), [i, a] = (0, Z.useState)([]), [o, s] = (0, Z.useState)(e.length), [c, l] = (0, Z.useState)([]), [u, d] = (0, Z.useState)(!1); 2224 (0, Z.useEffect)(() => { 2225 o === 0 && alert("You win!"), r(g(e.map((e) => e.toUpperCase()), t)), s(e.length), a([]); 2226 }, [ 2227 e, 2228 t, 2229 o === 0 2230 ]); 2231 let f = (e, t) => { 2232 l([[e, t]]), d(!0); 2233 }, p = (e, t) => { 2234 if (!u || c.length === 0 || c.some(([n, r]) => n === e && r === t)) return; 2235 let [n, r] = c[0]; 2236 if (c.length === 1) { 2237 l((n) => [...n, [e, t]]); 2238 return; 2239 } 2240 let [i, a] = c[1], o = i - n, s = a - r, d = o === 0, f = s === 0, p = Math.abs(o) === Math.abs(s), m = e - n, h = t - r; 2241 (d && m === 0 || f && h === 0 || p && Math.abs(m) === Math.abs(h)) && l((n) => [...n, [e, t]]); 2242 }, m = () => { 2243 d(!1), h(), l([]); 2244 }, h = () => { 2245 let t = c.map(([e, t]) => n[e][t].letter).join(""), l = t.split("").reverse().join(""); 2246 (e.includes(t) || e.includes(l)) && !i.includes(t) && !i.includes(l) && (console.log("found word!", t), a((e) => [...e, t]), s(o - 1), r((e) => { 2247 let t = e.map((e) => e.map((e) => ({ ...e }))); 2248 return c.forEach(([e, n]) => { 2249 t[e][n].found = !0; 2250 }), t; 2251 })); 2252 }, g = (e, t) => { 2253 let n = Array.from({ length: t }, () => Array(t).fill({ 2254 letter: "", 2255 found: !1 2256 })), r = [ 2257 [0, 1], 2258 [1, 0], 2259 [1, 1], 2260 [1, -1], 2261 [-1, 1], 2262 [-1, -1], 2263 [0, -1], 2264 [-1, 0] 2265 ]; 2266 e.forEach((e) => { 2267 for (let i = 0; i < 100; i++) { 2268 let i = Math.floor(Math.random() * t), a = Math.floor(Math.random() * t), [o, s] = r[Math.floor(Math.random() * r.length)], c = !0, l = []; 2269 for (let r = 0; r < e.length; r++) { 2270 let u = i + r * o, d = a + r * s; 2271 if (u < 0 || u >= t || d < 0 || d >= t || n[u][d].letter !== "" && n[u][d].letter !== e[r]) { 2272 c = !1; 2273 break; 2274 } 2275 l.push([u, d]); 2276 } 2277 if (c) { 2278 l.forEach(([t, r], i) => n[t][r] = { 2279 letter: e[i], 2280 found: !1 2281 }); 2282 return; 2283 } 2284 } 2285 }); 2286 for (let e = 0; e < t; e++) for (let r = 0; r < t; r++) n[e][r].letter === "" && (n[e][r] = { 2287 letter: String.fromCharCode(65 + Math.floor(Math.random() * 26)), 2288 found: !1 2289 }); 2290 return n; 2291 }; 2292 return /* @__PURE__ */ (0, Q.jsxs)("div", { 2293 style: { 2294 width: "100%", 2295 display: "flex" 2296 }, 2297 children: [/* @__PURE__ */ (0, Q.jsx)("div", { 2298 style: { 2299 display: "grid", 2300 gridTemplateColumns: `repeat(${t}, 30px)`,
2301 gap: "6px" 2302 }, 2303 onMouseUp: m, 2304 children: n.map((e, t) => e.map(({ letter: e, found: n }, r) => /* @__PURE__ */ (0, Q.jsx)("div", { 2305 style: { 2306 width: "25px", 2307 height: "25px", 2308 display: "flex", 2309 alignItems: "center", 2310 justifyContent: "center", 2311 border: "1px solid lightgrey", 2312 fontSize: "var(--font-size-md)", 2313 fontWeight: "var(--font-weight-bold)", 2314 color: n ? "lightgrey" : "grey", 2315 backgroundColor: c.some(([e, n]) => e === t && n === r) ? "lightblue" : "white", 2316 cursor: "pointer", 2317 userSelect: "none" 2318 }, 2319 onMouseDown: () => f(t, r), 2320 onMouseEnter: () => p(t, r), 2321 children: e 2322 }, `${t}-${r}`))) 2323 }), /* @__PURE__ */ (0, Q.jsxs)("div", { 2324 style: { 2325 margin: "0 0 0 auto", 2326 maxWidth: "30%" 2327 }, 2328 children: [/* @__PURE__ */ (0, Q.jsx)("p", { 2329 style: { 2330 fontSize: "var(--font-size-md)", 2331 fontWeight: "var(--font-weight-bold)" 2332 }, 2333 children: "Find the LearnerMobile developers!" 2334 }), /* @__PURE__ */ (0, Q.jsxs)("h5", { children: ["Remaining Words: ", o] })] 2335 })] 2336 }); 2337}; 2338//#endregion 2339//#region Components/Builder/Pb3AcknowledgmentDialog.jsx 2340function Gn(e) { 2341 let t = new URLSearchParams(window.location.search), n = t.get("fromPb3") === "true", r = t.get("pb3Type") ?? "page", i = t.get("pb3VersionId"), [a, o] = (0, Z.useState)(n), s = Ge(); 2342 function c() { 2343 let e = new URLSearchParams(window.location.search); 2344 e.delete("fromPb3"), e.delete("pb3VersionId"), e.delete("pb3Type"); 2345 let t = `${window.location.pathname}?${e.toString()}`; 2346 s(t, { replace: !0 }), o(!1); 2347 } 2348 let l = /* @__PURE__ */ (0, Q.jsx)(x, { 2349 icon: ue, 2350 style: { 2351 fontSize: "80px", 2352 color: "var(--color-teal)", 2353 marginTop: "-14px" 2354 } 2355 }), u = /* @__PURE__ */ (0, Q.jsxs)("i", { children: [ 2356 "For reference, view ", 2357 r == "LearnLists" ? "playlist" : r?.toLowerCase(), 2358 " in old builder ", 2359 /* @__PURE__ */ (0, Q.jsx)("a", { 2360 href: `/${r}/Edit/${i}`, 2361 target: "_blank", 2362 children: "here" 2363 }), 2364 ". " 2365 ] }); 2366 return /* @__PURE__ */ (0, Q.jsx)(zn, { 2367 ackType: `pb3Ack${r}`, 2368 onClose: c, 2369 show: a, 2370 titleIcon: l, 2371 note: u 2372 }); 2373} 2374//#endregion 2375//#region Components/Builder/CourseLockedBanner.jsx 2376function Kn({ editableByAccountName: e }) { 2377 let { formatMessage: t } = ee(); 2378 return e ? /* @__PURE__ */ (0, Q.jsxs)(y, { 2379 sx: { 2380 border: "2px solid var(--ui-color-warning)", 2381 borderRadius: "var(--radius-md)", 2382 padding: "1rem", 2383 margin: "1rem", 2384 display: "flex", 2385 alignItems: "center" 2386 }, 2387 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2388 sx: { 2389 display: "flex", 2390 marginRight: ".8rem" 2391 }, 2392 children: /* @__PURE__ */ (0, Q.jsx)(x, { 2393 icon: U, 2394 style: { 2395 color: "var(--ui-color-warning)", 2396 fontSize: "2rem" 2397 } 2398 }) 2399 }), /* @__PURE__ */ (0, Q.jsx)(y, { 2400 sx: { flex: 1 }, 2401 children: /* @__PURE__ */ (0, Q.jsx)(k, { 2402 sx: { fontSize: "var(--font-size-md)" }, 2403 children: t({ id: "builder.courseLocked.banner" }, { editableByAccountName: e }) 2404 }) 2405 })] 2406 }) : null; 2407} 2408//#endregion 2409//#region Components/Course/defaultstyles/TypographySection.jsx 2410var qn = /* @__PURE__ */ e(r(), 1), Jn = ({ typographyType: e, fontFamily: t, setFontFamily: n, fontSize: r, setFontSize: i, color: a, setColor: o, fontWeight: s, setFontWeight: c, fontStyle: l, setFontStyle: u, textDecoration: d, setTextDecoration: f, lineHeight: p, setLineHeight: m, styles: h }) => { 2411 let g = a, _ = et(h, g); 2412 return _ && (g = _.value), /* @__PURE__ */ (0, Q.jsxs)(y, { 2413 className: "style-subsection", 2414 sx: { flex: 1 }, 2415 children: [/* @__PURE__ */ (0, Q.jsx)(K, { id: `builder.styles.typography.${e}` }), /* @__PURE__ */ (0, Q.jsxs)(y, { 2416 sx: { 2417 display: "flex", 2418 flexDirection: "column", 2419 gap: ".7rem" 2420 }, 2421 children: [
2422 /* @__PURE__ */ (0, Q.jsxs)(y, { 2423 className: "style-row", 2424 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2425 sx: { flex: .2 }, 2426 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: `builder.styles.typography.${e}.font` }) 2427 }), /* @__PURE__ */ (0, Q.jsx)(y, { 2428 sx: { 2429 flex: .8, 2430 display: "flex", 2431 justifyContent: "end" 2432 }, 2433 children: /* @__PURE__ */ (0, Q.jsx)(I, { 2434 size: "small", 2435 children: /* @__PURE__ */ (0, Q.jsx)(ht, { 2436 sx: { width: "100%" }, 2437 displayEmpty: !0, 2438 onChange: (e, t) => { 2439 n(e.target.value); 2440 }, 2441 value: t, 2442 children: /* @__PURE__ */ (0, Q.jsx)(F, { 2443 value: null, 2444 sx: { height: "2.2em" } 2445 }, "no-font-family") 2446 }) 2447 }) 2448 })] 2449 }), 2450 /* @__PURE__ */ (0, Q.jsxs)(y, { 2451 className: "style-row", 2452 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2453 sx: { flex: .2 }, 2454 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: `builder.styles.typography.${e}.size` }) 2455 }), /* @__PURE__ */ (0, Q.jsx)(y, { 2456 sx: { 2457 flex: .8, 2458 display: "flex", 2459 justifyContent: "end" 2460 }, 2461 children: /* @__PURE__ */ (0, Q.jsx)(I, { 2462 size: "small", 2463 children: /* @__PURE__ */ (0, Q.jsxs)(Se, { 2464 sx: { width: "80px" }, 2465 value: r ? parseInt(r) : "", 2466 onChange: (e) => { 2467 e.target.value ? i(`${e.target.value}px`) : i(null); 2468 }, 2469 children: [/* @__PURE__ */ (0, Q.jsx)(F, { 2470 value: null, 2471 sx: { height: "2.2em" } 2472 }, "no-font-size"), tt.map((e) => /* @__PURE__ */ (0, Q.jsx)(F, { 2473 value: e, 2474 children: e 2475 }, e))] 2476 }) 2477 }) 2478 })] 2479 }),
2480 /* @__PURE__ */ (0, Q.jsxs)(y, { 2481 className: "style-row", 2482 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2483 sx: { flex: .2 }, 2484 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: `builder.styles.typography.${e}.color` }) 2485 }), /* @__PURE__ */ (0, Q.jsx)(y, { 2486 sx: { 2487 flex: .8, 2488 display: "flex", 2489 justifyContent: "end" 2490 }, 2491 children: /* @__PURE__ */ (0, Q.jsx)($e, { 2492 isAdd: !g, 2493 color: g, 2494 setColor: (e) => { 2495 o(e); 2496 }, 2497 styleColors: h.colors 2498 }) 2499 })] 2500 }), 2501 /* @__PURE__ */ (0, Q.jsxs)(y, { 2502 className: "style-row", 2503 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2504 sx: { flex: .2 }, 2505 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: `builder.styles.typography.${e}.style` }) 2506 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 2507 sx: { 2508 display: "flex", 2509 gap: ".25rem", 2510 flex: .8, 2511 justifyContent: "end" 2512 }, 2513 children: [ 2514 /* @__PURE__ */ (0, Q.jsx)(w, { 2515 onClick: () => c(s === "bold" ? null : "bold"), 2516 sx: { 2517 border: `${s === "bold" ? "2px" : "1px"} solid ${s === "bold" ? "var(--ui-color-text)" : "var(--ui-color-text-label)"}`, 2518 minWidth: "unset", 2519 width: "2.5rem", 2520 height: "2.5rem", 2521 borderRadius: "var(--radius-sm)", 2522 color: "var(--ui-color-text)" 2523 }, 2524 children: /* @__PURE__ */ (0, Q.jsx)(x, { icon: Ve }) 2525 }), 2526 /* @__PURE__ */ (0, Q.jsx)(w, { 2527 onClick: () => u(l === "italic" ? null : "italic"), 2528 sx: { 2529 border: `${l === "italic" ? "2px" : "1px"} solid ${l === "italic" ? "var(--ui-color-text)" : "var(--ui-color-text-label)"}`, 2530 minWidth: "unset", 2531 width: "2.5rem", 2532 height: "2.5rem", 2533 borderRadius: "var(--radius-sm)", 2534 color: "var(--ui-color-text)" 2535 }, 2536 children: /* @__PURE__ */ (0, Q.jsx)(x, { icon: W }) 2537 }), 2538 /* @__PURE__ */ (0, Q.jsx)(w, { 2539 onClick: () => f(d === "underline" ? null : "underline"), 2540 sx: { 2541 border: `${d === "underline" ? "2px" : "1px"} solid ${d === "underline" ? "var(--ui-color-text)" : "var(--ui-color-text-label)"}`, 2542 minWidth: "unset", 2543 width: "2.5rem", 2544 height: "2.5rem", 2545 borderRadius: "var(--radius-sm)", 2546 color: "var(--ui-color-text)" 2547 }, 2548 children: /* @__PURE__ */ (0, Q.jsx)(x, { icon: He }) 2549 }) 2550 ] 2551 })] 2552 }), 2553 e === "paragraph" && /* @__PURE__ */ (0, Q.jsxs)(y, { 2554 className: "style-row", 2555 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2556 sx: { flex: .2 }, 2557 children: /* @__PURE__ */ (0, Q.jsx)(K, { 2558 id: `builder.styles.typography.${e}.lineHeight`, 2559 sx: { whiteSpace: "nowrap" } 2560 }) 2561 }), /* @__PURE__ */ (0, Q.jsx)(y, { 2562 sx: { 2563 flex: .8, 2564 display: "flex", 2565 justifyContent: "end" 2566 }, 2567 children: /* @__PURE__ */ (0, Q.jsx)(I, { 2568 size: "small", 2569 children: /* @__PURE__ */ (0, Q.jsxs)(Se, { 2570 sx: { width: "80px" }, 2571 value: p ?? "", 2572 onChange: (e) => { 2573 m(e.target.value); 2574 }, 2575 children: [/* @__PURE__ */ (0, Q.jsx)(F, { 2576 value: null, 2577 sx: { height: "2.2em" } 2578 }, "no-line-height"), at.map((e) => /* @__PURE__ */ (0, Q.jsx)(F, { 2579 value: e, 2580 children: e 2581 }, e))] 2582 }) 2583 }) 2584 })] 2585 }) 2586 ] 2587 })] 2588 }); 2589}, Yn = ({ componentType: e, previewContainerRef: t, defaultStyles: n }) => { 2590 let [r, i] = (0, Z.useState)(null); 2591 return (0, Z.useEffect)(() => { 2592 if (t.current) { 2593 let e = t.current.clientWidth; 2594 i(800 > e ? 1 / (800 / e) : 1); 2595 } 2596 }
2596, []), /* @__PURE__ */ (0, Q.jsx)(Q.Fragment, { children: r && /* @__PURE__ */ (0, Q.jsxs)("div", { 2597 className: "preview-root", 2598 style: { 2599 position: "relative", 2600 width: "800px", 2601 zoom: `${r}`, 2602 margin: "auto" 2603 }, 2604 children: [n && /* @__PURE__ */ (0, Q.jsx)("style", { children: ` 2605 :root { 2606 ${ut(n)} 2607 } 2608 2609 .preview-root .cbiv-element { 2610 height: auto !important; 2611 } 2612 ` }), /* @__PURE__ */ (0, Q.jsx)("div", { 2613 style: { 2614 maxWidth: "800px", 2615 width: "100%" 2616 }, 2617 children: lt[e].map((t) => { 2618 let r = structuredClone(t.props), i = { 2619 id: crypto.randomUUID(), 2620 type: t.type, 2621 gridWidth: t.gridWidth, 2622 props: { ...r } 2623 }; 2624 return Qe(i, n), /* @__PURE__ */ (0, Q.jsx)("div", { 2625 style: { 2626 width: lt[e].length === 1 ? "100%" : "50%", 2627 position: "relative", 2628 height: "auto" 2629 }, 2630 children: Y(i) 2631 }, i.id); 2632 }) 2633 })] 2634 }) }); 2635}, Xn = ({ styles: e }) => { 2636 let t = (0, Z.useRef)(null), n = (0, Z.useRef)(null), r = (0, Z.useRef)(null), i = (0, Z.useRef)(null), a = e; 2637 a.heading && (a.heading.title = "Example Heading"), a.subheading && (a.subheading.title = "Example Subheading"), a.paragraph && (a.paragraph.title = "This is paragraph text that demonstrates the current typography settings."); 2638 let o = pt().find((t) => t.style === e.globalFont?.fontFamily?.value); 2639 return /* @__PURE__ */ (0, Q.jsxs)(y, { 2640 className: "previewer-root", 2641 sx: { 2642 display: "flex", 2643 flexDirection: "column", 2644 gap: "1rem" 2645 }, 2646 children: [ 2647 o?.name && /* @__PURE__ */ (0, Q.jsxs)(k, { 2648 sx: { 2649 fontFamily: `${e.globalFont.fontFamily.value}`, 2650 color: "var(--ui-color-text)", 2651 fontWeight: "var(--font-weight-regular)", 2652 fontSize: "1.8rem" 2653 }, 2654 children: [o.name, " font"] 2655 }), 2656 [ 2657 e.heading, 2658 e.subheading, 2659 e.paragraph 2660 ].map((e, t) => { 2661 let n = e.color?.value, r = et(a, n); 2662 return r && (n = r.value), /* @__PURE__ */ (0, Q.jsx)(y, { children: /* @__PURE__ */ (0, Q.jsx)(k, { 2663 sx: { 2664 fontFamily: e.fontFamily.value, 2665 fontSize: e.fontSize.value, 2666 color: n, 2667 fontWeight: e.fontWeight?.value, 2668 fontStyle: e.fontStyle?.value, 2669 textDecoration: e.textDecoration?.value, 2670 lineHeight: e.lineHeight?.value, 2671 width: t == 2 ? "600px" : "100%" 2672 }, 2673 children: e.title 2674 }) }, t); 2675 }), 2676 /* @__PURE__ */ (0, Q.jsxs)(y, { 2677 className: "element-previews", 2678 sx: (e) => ({ 2679 display: "grid", 2680 gridTemplateColumns: "275px 275px", 2681 gridTemplateRows: "1fr 1fr", 2682 gap: "2rem", 2683 padding: ".5rem", 2684 maxWidth: "800px", 2685 [e.breakpoints.down("800")]: { 2686 gridTemplateColumns: "1fr", 2687 gridTemplateRows: "repeat(4, 1fr)" 2688 }, 2689 "& .element-preview": { 2690 display: "flex", 2691 justifyContent: "center", 2692 alignItems: "center", 2693 backgroundColor: "white", 2694 borderRadius: "var(--radius-md)", 2695 boxShadow: "var(--elevation-2)", 2696 padding: "0 1rem", 2697 maxWidth: "250px", 2698 height: "185px", 2699 overflowX: "auto" 2700 } 2701 }), 2702 children: [ 2703 /* @__PURE__ */ (0, Q.jsx)(y, { 2704 className: "element-preview", 2705 ref: t, 2706 children: /* @__PURE__ */ (0, Q.jsx)(Yn, { 2707 componentType: "table", 2708 previewContainerRef: t, 2709 defaultStyles: e 2710 }) 2711 }), 2712 /* @__PURE__ */ (0, Q.jsx)(y, { 2713 className: "element-preview", 2714 ref: n, 2715 children: /* @__PURE__ */ (0, Q.jsx)(Yn, { 2716 componentType: "highlight2", 2717 previewContainerRef: n, 2718 defaultStyles: e 2719 }) 2720 }), 2721 /* @__PURE__ */ (0, Q.jsx)(y, { 2722 className: "element-preview", 2723 ref: r, 2724 children: /* @__PURE__ */ (0, Q.jsx)(Yn, { 2725 componentType: "forcedCompletion", 2726 previewContainerRef: r, 2727 defaultStyles: e 2728 }) 2729 }), 2730 /* @__PURE__ */ (0, Q.jsx)(y, { 2731 className: "element-preview", 2732 ref: i, 2733 children: /* @__PURE__ */ (0, Q.jsx)(Yn, { 2734 componentType: "quote3", 2735 previewContainerRef: i, 2736 defaultStyles: e 2737 }) 2738 }) 2739 ] 2740 }) 2741 ] 2742 }); 2743}, Zn = (e) => ({ 2744 display: "flex", 2745 height: "100%", 2746 gap: 1, 2747 [e.breakpoints.down("1500")]: { flexDirection: "column" }, 2748 "& .style-section": { 2749 border: "1px solid var(--color-teal)", 2750 borderRadius: "var(--radius-sm)", 2751 flex: 1, 2752 padding: "1rem 1rem 1.4rem 1rem", 2753 "& > .MuiTypography-root": { 2754 color: "var(--ui-color-heavily-emphasized)", 2755 fontSize: "var(--font-size-lg)", 2756 fontWeight: "var(--font-weight-bold)", 2757 paddingBottom: "1rem" 2758 } 2759 }, 2760 "& .style-section.typography": { flex: 0 }, 2761 "& .style-section .style-row": { 2762 display: "flex", 2763 justifyContent: "space-between", 2764 alignItems: "center", 2765 gap: "1rem" 2766 }, 2767 "& .style-section .style-subsection": { 2768 borderRight: "1px solid #7F7F7F", 2769 paddingRight: "1rem", 2770 [e.breakpoints.down("800")]: { 2771 borderRight: "none", 2772 paddingRight: "0" 2773 } 2774 }, 2775 "& .style-section .style-subsection:last-of-type": { borderRight: "none" }, 2776 "& .style-section .style-subsection > .MuiTypography-root": { paddingBottom: "1.4rem" }, 2777 "& .style-section .style-row .MuiFormControl-root": { 2778 minWidth: "100%", 2779 display: "flex", 2780 alignItems: "end" 2781 } 2782}); 2783function Qn({ intlPrefix: e, onDirtyStyles: t, ...n }) { 2784 let { card: r, setCardField: i } = J(), a = r.course, o = { 2785 styles: structuredClone(a.defaultStyles ?? jt), 2786 isDirty: !1 2787 }, [s, c] = (0, Z.useReducer)(h, o), { styles: l, isDirty: u } = s; 2788 (0, Z.useEffect)(() => { 2789 t && t(u); 2790 }, [u, t]), (0, Z.useEffect)(() => { 2791 u || c({ 2792 type: "SYNC_FROM_COURSE", 2793 payload: a.defaultStyles ?? jt 2794 }); 2795 }, [a.defaultStyles]); 2796 let d = l.globalFont?.color?.value, f = et(l, d); 2797 f && (d = f.value); 2798 let p = () => { 2799 let e = { ...a };
2800 e.modules.forEach((e) => { 2801 it(e, l); 2802 }), m([{ 2803 name: "course", 2804 value: e 2805 }, { 2806 name: "defaultStyles", 2807 value: l 2808 }]), c({ type: "RESET_DIRTY" }), window.location.hash = "MainView"; 2809 }; 2810 function m(e) { 2811 let t = { ...a }; 2812 e.forEach((e, n) => { 2813 t[e.name] = e.value; 2814 }), i({ course: t }); 2815 } 2816 function h(e, t) { 2817 switch (t.type) { 2818 case "SET_STYLE": { 2819 let { path: n, value: r } = t.payload, i = g(e.styles, n, r), a = JSON.stringify(i) !== JSON.stringify(e.styles), o = e.isDirty || a; 2820 return { 2821 ...e, 2822 styles: i, 2823 isDirty: o 2824 }; 2825 } 2826 case "RESET_DIRTY": return { 2827 ...e, 2828 isDirty: !1 2829 }; 2830 case "SYNC_FROM_COURSE": return { 2831 ...e, 2832 styles: structuredClone(t.payload), 2833 isDirty: !1 2834 }; 2835 default: return e; 2836 } 2837 } 2838 function g(e, t, n) { 2839 let r = t.split("."), i = structuredClone(e), a = i; 2840 return r.forEach((e, t) => { 2841 t === r.length - 1 ? typeof a[e] == "object" ? a[e].value = n : a[e] = n : a = a[e]; 2842 }), i; 2843 } 2844 function _(e, t, n) { 2845 c({ 2846 type: "SET_STYLE", 2847 payload: { 2848 path: `${e}.${t}`, 2849 value: n 2850 } 2851 }); 2852 } 2853 let v = document.getElementById("apply-styles-portal"); 2854 return /* @__PURE__ */ (0, Q.jsxs)(y, { 2855 className: "course-styles", 2856 sx: Zn, 2857 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 2858 sx: { 2859 display: "flex", 2860 flexDirection: "column", 2861 flex: 1, 2862 gap: 1.5, 2863 padding: "1.5rem 2rem 1rem 24px" 2864 }, 2865 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 2866 sx: (e) => ({ 2867 display: "flex", 2868 gap: 1.5, 2869 [e.breakpoints.down("800")]: { flexDirection: "column" } 2870 }), 2871 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 2872 className: "style-section colors", 2873 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 2874 id: "builder.styles.colors", 2875 variant: "h2" 2876 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 2877 sx: { 2878 display: "flex", 2879 flexDirection: "column", 2880 gap: "1rem" 2881 }, 2882 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 2883 className: "style-row", 2884 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2885 sx: { flex: .2 }, 2886 children: /* @__PURE__ */ (0, Q.jsx)(be, { 2887 placement: "left", 2888 arrow: !0, 2889 title: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.styles.colors.primary.tooltip" }), 2890 children: /* @__PURE__ */ (0, Q.jsxs)(y, { 2891 sx: { 2892 display: "flex", 2893 alignItems: "center", 2894 gap: ".5rem" 2895 }, 2896 children: [/* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.styles.colors.primary" }), /* @__PURE__ */ (0, Q.jsx)(x, { 2897 icon: j, 2898 className: "lb-help-icon" 2899 })] 2900 }) 2901 }) 2902 }), /* @__PURE__ */ (0, Q.jsx)(y, { 2903 sx: { 2904 flex: .8, 2905 display: "flex", 2906 justifyContent: "end" 2907 }, 2908 children: /* @__PURE__ */ (0, Q.jsx)($e, { 2909 color: l.colors?.primaryColor?.value, 2910 isAdd: !l.colors?.primaryColor?.value, 2911 setColor: (e) => { 2912 _("colors", "primaryColor", e); 2913 }, 2914 disableStyleColors: !0 2915 }) 2916 })] 2917 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 2918 className: "style-row", 2919 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2920 sx: { flex: .2 }, 2921 children: /* @__PURE__ */ (0, Q.jsx)(be, { 2922 placement: "left", 2923 arrow: !0, 2924 title: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.styles.colors.secondary.tooltip" }), 2925 children: /* @__PURE__ */ (0, Q.jsxs)(y, { 2926 sx: { 2927 display: "flex", 2928 alignItems: "center", 2929 gap: ".5rem" 2930 }, 2931 children: [/* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.styles.colors.secondary" }), /* @__PURE__ */ (0, Q.jsx)(x, { 2932 icon: j, 2933 className: "lb-help-icon" 2934 })] 2935 }) 2936 }) 2937 }), /* @__PURE__ */ (0, Q.jsx)(y, { 2938 sx: { 2939 display: "flex", 2940 gap: "1rem" 2941 }, 2942 children: [ 2943 l.colors?.secondaryColor1, 2944 l.colors?.secondaryColor2, 2945 l.colors?.secondaryColor3, 2946 l.colors?.secondaryColor4, 2947 l.colors?.secondaryColor5
2948 ].filter(Boolean).map((e, t) => /* @__PURE__ */ (0, Q.jsx)(y, { 2949 sx: { 2950 flex: .8, 2951 display: "flex", 2952 justifyContent: "end" 2953 }, 2954 children: /* @__PURE__ */ (0, Q.jsx)($e, { 2955 color: e.value, 2956 label: t + 1, 2957 isAdd: !e.value, 2958 setColor: (e) => { 2959 _("colors", `secondaryColor${t + 1}`, e); 2960 }, 2961 disableStyleColors: !0 2962 }) 2963 }, t)) 2964 })] 2965 })] 2966 })] 2967 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 2968 className: "style-section global-font", 2969 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 2970 id: "builder.styles.globalFont", 2971 variant: "h2" 2972 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 2973 sx: { 2974 display: "flex", 2975 flexDirection: "column", 2976 gap: "1rem" 2977 }, 2978 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 2979 className: "style-row", 2980 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 2981 sx: { flex: .2 }, 2982 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.styles.typography.heading.font" }) 2983 }), /* @__PURE__ */ (0, Q.jsx)(y, { 2984 sx: { 2985 flex: .8, 2986 display: "flex", 2987 justifyContent: "end" 2988 }, 2989 children: /* @__PURE__ */ (0, Q.jsx)(I, { 2990 size: "small", 2991 children: /* @__PURE__ */ (0, Q.jsx)(ht, { 2992 sx: { width: "100%" }, 2993 displayEmpty: !0, 2994 onChange: (e, t) => { 2995 _("globalFont", "fontFamily", e.target.value), _("heading", "fontFamily", e.target.value), _("subheading", "fontFamily", e.target.value), _("paragraph", "fontFamily", e.target.value); 2996 }, 2997 value: l.globalFont?.fontFamily?.value, 2998 children: /* @__PURE__ */ (0, Q.jsx)(F, { 2999 value: null, 3000 sx: { height: "2.2em" } 3001 }, "no-global-font-family") 3002 }) 3003 }) 3004 })] 3005 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 3006 className: "style-row", 3007 children: [/* @__PURE__ */ (0, Q.jsx)(y, { 3008 sx: { flex: .2 }, 3009 children: /* @__PURE__ */ (0, Q.jsx)(K, { id: "builder.styles.typography.heading.color" }) 3010 }), /* @__PURE__ */ (0, Q.jsx)(y, { 3011 sx: { 3012 flex: .8, 3013 display: "flex", 3014 justifyContent: "end" 3015 }, 3016 children: /* @__PURE__ */ (0, Q.jsx)($e, { 3017 isAdd: !d, 3018 color: d, 3019 setColor: (e) => { 3020 _("globalFont", "color", e), _("heading", "color", e), _("subheading", "color", e), _("paragraph", "color", e); 3021 }, 3022 styleColors: l.colors 3023 }) 3024 })] 3025 })] 3026 })] 3027 })] 3028 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 3029 className: "style-section typography", 3030 children: [/* @__PURE__ */ (0, Q.jsx)(K, { 3031 id: "builder.styles.typography", 3032 variant: "h2" 3033 }), /* @__PURE__ */ (0, Q.jsx)(y, { 3034 sx: (e) => ({ 3035 display: "flex", 3036 gap: "1rem", 3037 [e.breakpoints.down("800")]: { flexDirection: "column" } 3038 }), 3039 children: Object.entries({ 3040 heading: l.heading, 3041 subheading: l.subheading, 3042 paragraph: l.paragraph 3043 }).map(([e, t]) => /* @__PURE__ */ (0, Q.jsx)(Jn, { 3044 typographyType: e, 3045 fontFamily: t.fontFamily.value, 3046 setFontFamily: (t) => _(e, "fontFamily", t), 3047 fontSize: t.fontSize.value, 3048 setFontSize: (t) => _(e, "fontSize", t), 3049 color: t.color.value, 3050 setColor: (t) => _(e, "color", t), 3051 fontWeight: t.fontWeight.value, 3052 setFontWeight: (t) => _(e, "fontWeight", t), 3053 fontStyle: t.fontStyle.value, 3054 setFontStyle: (t) => _(e, "fontStyle", t), 3055 textDecoration: t.textDecoration.value, 3056 setTextDecoration: (t) => _(e, "textDecoration", t), 3057 lineHeight: t.lineHeight?.value, 3058 setLineHeight: (t) => _(e, "lineHeight", t), 3059 styles: l 3060 }, e)) 3061 })] 3062 })] 3063 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 3064 sx: (e) => ({ 3065 flex: 1, 3066 padding: "1.5rem 1rem 1rem 0", 3067 overflowY: "auto", 3068 [e.breakpoints.down("1500")]: { 3069 overflowY: "unset", 3070 padding: "1rem" 3071 } 3072 }), 3073 children: [
3074 /* @__PURE__ */ (0, Q.jsx)(K, { 3075 id: "builder.styles.preview", 3076 sx: { 3077 color: "var(--ui-color-heavily-emphasized)", 3078 fontSize: "var(--font-size-xl)", 3079 fontWeight: "var(--font-weight-bold)", 3080 paddingBottom: "1rem", 3081 lineHeight: "1" 3082 } 3083 }), 3084 /* @__PURE__ */ (0, Q.jsx)(Xn, { styles: l }), 3085 /* @__PURE__ */ (0, Q.jsx)(Q.Fragment, { children: v !== null && (0, qn.createPortal)(/* @__PURE__ */ (0, Q.jsx)(O, { 3086 variant: "contained", 3087 sx: { 3088 width: "auto", 3089 px: 3 3090 }, 3091 onClick: p, 3092 children: "Apply" 3093 }), v) }) 3094 ] 3095 })] 3096 }); 3097} 3098//#endregion 3099//#region Components/Builder/Builder.jsx 3100var $n = (0, Z.lazy)(() => import("./Channels-qbh1aKl8.js")), er = (0, Z.lazy)(() => import("./Assignments-C1XfOed4.js")), tr = (0, Z.lazy)(() => import("./Achievements-DLP4BmSa.js")), nr = { 3101 boxShadow: "none", 3102 backgroundColor: "var(--ui-color-nav-background)" 3103}, rr = { 3104 pr: 3, 3105 fontSize: "var(--font-size-lg)", 3106 fontWeight: "var(--font-weight-regular)", 3107 color: "var(--ui-color-text)", 3108 cursor: "pointer", 3109 wordBreak: "break-word" 3110}, ir = { 3111 fontSize: "var(--font-size-sm)", 3112 fontStyle: "italic", 3113 display: "flex", 3114 alignItems: "center", 3115 gap: "4px" 3116}; 3117function ar({ tabTitlesPrefix: e, slots: n, saveFunction: r, loadFunction: a, allowsExport: o, disableTabs: s, isInStreamingMode: c }) { 3118 (0, Z.useState)(() => { 3119 mt(); 3120 }); 3121 let l = (0, Z.useRef)(), u = (0, Z.useRef)(), [d, f] = (0, Z.useState)(!1), p = Ge(), [m, h] = (0, Z.useState)(dt()), [g, _] = (0, Z.useState)(), [S, C] = (0, Z.useState)(!0), [w, T] = pe(), { card: O, setCardField: te, dirty: ne, setDirty: re } = J(), { enqueueSnackbar: j } = b(), { formatMessage: M } = ee(), oe = O.LastSavedDate, ue = O.savedInCurrentSession || !1, [fe, me] = (0, Z.useState)(null), [ge, _e] = (0, Z.useState)(/* @__PURE__ */ new Date()), [ve, N] = (0, Z.useState)(!1), [be, P] = (0, Z.useState)(null), [xe, Se] = (0, Z.useState)(!1), [Ce, we] = (0, Z.useState)(!1), [Te, Ee] = (0, Z.useState)(null), [Oe, F] = (0, Z.useState)(), [I] = t(), { post: ke } = v(`/Builder/Unpublish/${O.CardId}`, { 3122 cachePolicy: "no-cache", 3123 headers: { RequestVerificationToken: I } 3124 }), { delete: L } = v(`/Builder/RevertDraft?versionId=${O.VersionId}`, { 3125 cachePolicy: "no-cache", 3126 headers: { RequestVerificationToken: I } 3127 }), R = m === "ConfirmExport" || m === "SyncLinkedCourses", Ae = m === "Preview", z = A("(max-width:1220px)"), { configuration: Me, refreshConfiguration: V, isAdmin: H } = E(), { courseIsEditableByAccount: Pe } = (0, Z.useContext)(Xe), Fe = Me?.User?.UserRoles?.some((e) => e.RoleId == "0" || e.RoleId == "1"), Ie = Me?.User?.UserRoles?.some((e) => e.RoleId == "2"), Le = Fe || Ie && (Me?.User?.Entitlements?.includes("content.publisher") || Me?.User?.Entitlements?.includes("content.author")), U = !!O.CourseAccountId && !!Me?.AccountId && !bt(O.CourseAccountId, Me.AccountId), W = O.CourseAccountName || O.CourseAccountId, G = Me?.AccountName || "", Be = Pe ? "" : O.EditableByAccountName || M({ id: "builder.courseLocked.fallbackOwner" }), { onAccountSwitch: Ve } = i(); 3128 (0, Z.useEffect)(() => Ve(() => V()), [Ve, V]); 3129 let He = Vn(r, Ae, h, g, nt, () => U ? (P("save"), N(!0), !0) : !1); 3130 (0, Z.useEffect)(() => (window.__accountMismatch = !!U, window.__courseAccountName = W || "", window.__currentAccountName = G, () => { 3131 delete window.__accountMismatch, delete window.__courseAccountName, delete window.__currentAccountName; 3132 }), [ 3133 U, 3134 W, 3135 G 3136 ]), (0, Z.useEffect)(() => { 3137 if (!U) return; 3138 let e = window.ShowMediaGallery, t = window.EditHeaderImage; 3139 return window.ShowMediaGallery = function() { 3140 alert(`This action is disabled. This course belongs to ${W}, but you are logged into ${G || "a different account"}.`); 3141 }, window.EditHeaderImage = function() { 3142 alert(`This action is disabled. This course belongs to ${W}, but you are logged into ${G || "a different account"}.`); 3143 }, () => { 3144 e && (window.ShowMediaGallery = e), t && (window.EditHeaderImage = t); 3145 }; 3146 }, [ 3147 U, 3148 W, 3149 G 3150 ]); 3151 let Ue = ne && fe && (ge.getTime() - fe.getTime()) / 36e5 >= 1; 3152 (0, Z.useEffect)(() => { 3153 let e = setInterval(() => { 3154 _e(/* @__PURE__ */ new Date()); 3155 }, 6e4); 3156 return () => clearInterval(e); 3157 }, []), (0, Z.useEffect)(() => { 3158 ne && !fe ? me(/* @__PURE__ */ new Date()) : ne || me(null); 3159 }, [ne, fe]); 3160 function K() { 3161 return ne ? oe ? Ue ? { 3162 message: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [ 3163 "Last Saved ", 3164 Pn(oe), 3165 " ago. ",
3166 /* @__PURE__ */ (0, Q.jsx)("span", { 3167 style: { 3168 textDecoration: "underline", 3169 cursor: "pointer" 3170 }, 3171 onClick: rt, 3172 children: "Save Now" 3173 }) 3174 ] }), 3175 color: "var(--ui-color-accent)" 3176 } : { 3177 message: `Last Saved ${Pn(oe)} ago`, 3178 color: "var(--ui-color-text-secondary)" 3179 } : Ue ? { 3180 message: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: ["Unsaved. ", /* @__PURE__ */ (0, Q.jsx)("span", { 3181 style: { 3182 textDecoration: "underline", 3183 cursor: "pointer" 3184 }, 3185 onClick: rt, 3186 children: "Save Now" 3187 })] }), 3188 color: "var(--ui-color-accent)" 3189 } : { 3190 message: "Unsaved", 3191 color: "var(--ui-color-accent)" 3192 } : oe ? ue ? { 3193 message: `Saved ${Pn(oe)} ago`, 3194 color: "var(--ui-color-text-secondary)" 3195 } : { 3196 message: `Last Saved on ${new Date(oe).toLocaleDateString("en-US")}`, 3197 color: "var(--ui-color-text-secondary)" 3198 } : { 3199 message: "Saved", 3200 color: "var(--ui-color-text-secondary)" 3201 }; 3202 } 3203 let We = (0, Z.useMemo)(() => { 3204 if (O.IsLatestVersion === !1 && O.LatestVersionId) { 3205 let e = qe(O.LatestVersionId); 3206 return { 3207 show: !0, 3208 message: /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: ["Outdated version. ", /* @__PURE__ */ (0, Q.jsx)(je, { 3209 href: e, 3210 sx: { 3211 color: "var(--ui-color-primary1)", 3212 textDecoration: "underline" 3213 }, 3214 children: "Click here to load the latest version" 3215 })] }), 3216 color: "var(--ui-color-warning)" 3217 }; 3218 } 3219 return { show: !1 }; 3220 }, [O.IsLatestVersion, O.LatestVersionId]); 3221 function Ke() { 3222 !H || !Pe || h("Settings"); 3223 } 3224 function Je() { 3225 H && (P("publish"), N(!0)); 3226 } 3227 function Ze() { 3228 H && (P("unpublish"), N(!0)); 3229 } 3230 function Qe() { 3231 H && (P("revert"), N(!0)); 3232 } 3233 function $e() { 3234 H && o && (_(m), h("ConfirmExport")); 3235 } 3236 function et() { 3237 H && (_(m), h("SyncLinkedCourses")); 3238 } 3239 function tt(e) { 3240 H && (h(g), _(null)); 3241 } 3242 function nt() { 3243 H && (_(m), h("Preview")); 3244 } 3245 function rt() { 3246 if (H) { 3247 if (U) { 3248 P("save"), N(!0); 3249 return; 3250 } 3251 q(); 3252 } 3253 } 3254 async function q() { 3255 if (H) try { 3256 T(!0); 3257 var e = await r(!1); 3258 re(!1); 3259 let n = /* @__PURE__ */ new Date(); 3260 if (te({ 3261 LastSavedDate: n, 3262 savedInCurrentSession: !0 3263 }, !0), me(null), j(M({ id: "builder.save.SavedSuccessfully" })), e.VersionId && O.VersionId !== e.VersionId) { 3264 var t = window.location.pathname.replace(O.VersionId, e.VersionId); 3265 p(t), te({ 3266 VersionId: e.VersionId, 3267 IsPublished: !1, 3268 LastSavedDate: n, 3269 savedInCurrentSession: !0 3270 }, !0); 3271 } 3272 } catch (e) { 3273 console.log("error", e), j(e || M({ id: "GenericError" }), { variant: "error" }); 3274 } finally { 3275 T(!1); 3276 } 3277 } 3278 function it() { 3279 N(!1); 3280 } 3281 function at() { 3282 let e = be; 3283 N(!1), e === "publish" ? ot() : e === "unpublish" ? ct() : e === "revert" ? lt() : e === "save" && q(); 3284 } 3285 async function ot() { 3286 try { 3287 T(!0); 3288 var e = await r(!0); 3289 re(!1), j(M({ id: "builder.save.PublishedSuccessfully" })), await new Promise((e) => setTimeout(e, 100)), e?.reauthenticated ? window.location.href = "/Content" : ut(); 3290 } catch (e) { 3291 console.log("error", e), j(e || M({ id: "GenericError" }), { variant: "error" }); 3292 } finally { 3293 T(!1); 3294 } 3295 } 3296 async function st() { 3297 var e = await ke(""); 3298 if (!e.success) throw e.message; 3299 } 3300 async function ct() { 3301 try { 3302 T(!0), await st(), console.log("Unpublish confirmed - implement unpublish logic here"), re(!1), j(M({ id: "builder.save.UnpublishedSuccessfully" })), window.location.reload(); 3303 } catch (e) { 3304 console.log("error", e), j(e || M({ id: "GenericError" }), { variant: "error" }); 3305 } finally { 3306 T(!1); 3307 } 3308 } 3309 async function lt() { 3310 try { 3311 T(!0); 3312 let e = await L(); 3313 if (!e.success) throw Error(e.message || "Failed to revert to published version"); 3314 if (re(!1), j(M({ id: "builder.save.RevertedSuccessfully" })), e.versionId) { 3315 let t = window.location.pathname.replace(O.VersionId, e.versionId); 3316 window.location.href = t; 3317 } else ut(); 3318 } catch (e) { 3319 console.log("error", e); 3320 let t = e instanceof Error ? e.message : e; 3321 j(t || M({ id: "GenericError" }), { variant: "error" }); 3322 } finally { 3323 T(!1); 3324 } 3325 } 3326 function ut() { 3327 p("/Content"); 3328 } 3329 (0, Z.useEffect)(() => { 3330 C(!1); 3331 }, [R]), (0, Z.useEffect)(() => { 3332 var e = "#" + (m || ""); 3333 p(window.location.search + e, { replace: !0 }); 3334 }, [m]); 3335 var n = { 3336 MainView: null, 3337 Settings: null, 3338 Styles: null, 3339 Channels: /* @__PURE__ */ (0, Q.jsx)($n, { 3340 accountMismatch: U, 3341 courseAccountName: W, 3342 currentAccountName: G 3343 }), 3344 Assignments: /* @__PURE__ */ (0, Q.jsx)(er, { 3345 cardId: O.CardId, 3346 accountMismatch: U, 3347 courseAccountName: W, 3348 currentAccountName: G 3349 }), 3350 Achievements: /* @__PURE__ */ (0, Q.jsx)(tr, { 3351 cardId: O.CardId, 3352 accountMismatch: U, 3353 courseAccountName: W, 3354 currentAccountName: G 3355 }), 3356 Preview: /* @__PURE__ */ (0, Q.jsx)(_t, { 3357 saveFunction: r, 3358 handleExitPreview: tt 3359 }), 3360 SaveAndPublish: /* @__PURE__ */ (0, Q.jsx)(Vt, { 3361 leaveConfirmationScreen: tt, 3362 handleConfirmPublish: Je, 3363 handleConfirmUnpublish: Ze, 3364 handleConfirmRevert: Qe, 3365 handleConfirmExport: o && l ? $e : null, 3366 exportFunction: async () => await l?.current(), 3367 handleSyncLinkedCourses: et, 3368 syncFunction: { 3369 syncAll: async () => await u?.current?.syncAll(), 3370 syncUnmodifiedOnly: async () => await u?.current?.syncUnmodifiedOnly(), 3371 hasModified: d 3372 }, 3373 saveFunction: r, 3374 loadFunction: a 3375 }),
3376 ConfirmExport: o ? /* @__PURE__ */ (0, Q.jsx)(kn, { ref: l }) : null, 3377 SyncLinkedCourses: /* @__PURE__ */ (0, Q.jsx)(Nn, { 3378 ref: u, 3379 onHasModifiedChange: f 3380 }), 3381 CancelButton: /* @__PURE__ */ (0, Q.jsx)(Ht, { 3382 handleConfirmCanceled: tt, 3383 handleConfirmExport: o && l ? $e : null, 3384 dirtyModalCallback: Oe, 3385 setDirtyModalCallback: F 3386 }), 3387 ...n 3388 }; 3389 function dt() { 3390 var e = document.URL.split("#"); 3391 return e.length > 1 && e[1] ? e[1] === "ConfirmExport" && !o ? "MainView" : e[1] : "MainView"; 3392 } 3393 var ft = []; 3394 Ae || (ft = [ 3395 n.MainView && /* @__PURE__ */ (0, Q.jsx)(B, { 3396 value: "MainView", 3397 icon: /* @__PURE__ */ (0, Q.jsx)(x, { 3398 icon: de, 3399 style: { fontSize: "var(--font-size-2xl)" } 3400 }), 3401 label: /* @__PURE__ */ (0, Q.jsx)(D, { id: `${e}MainView` }) 3402 }, "MainView"), 3403 H && Pe && n.Settings && /* @__PURE__ */ (0, Q.jsx)(B, { 3404 value: "Settings", 3405 icon: /* @__PURE__ */ (0, Q.jsx)(x, { 3406 icon: le, 3407 style: { fontSize: "var(--font-size-2xl)" } 3408 }), 3409 label: /* @__PURE__ */ (0, Q.jsx)(D, { id: "builder.tabs.Settings" }), 3410 disabled: c 3411 }, "Settings"), 3412 n.Channels && /* @__PURE__ */ (0, Q.jsx)(B, { 3413 value: "Channels", 3414 icon: /* @__PURE__ */ (0, Q.jsx)(x, { 3415 icon: he, 3416 style: { fontSize: "var(--font-size-2xl)" } 3417 }), 3418 label: /* @__PURE__ */ (0, Q.jsx)(D, { id: "builder.tabs.Channels" }), 3419 disabled: c 3420 }, "Channels"), 3421 n.Assignments && /* @__PURE__ */ (0, Q.jsx)(B, { 3422 value: "Assignments", 3423 icon: /* @__PURE__ */ (0, Q.jsx)(x, { 3424 icon: ce, 3425 style: { fontSize: "var(--font-size-2xl)" } 3426 }), 3427 label: /* @__PURE__ */ (0, Q.jsx)(D, { id: "builder.tabs.Assignments" }), 3428 disabled: s || c 3429 }, "Assignments"), 3430 n.Achievements && /* @__PURE__ */ (0, Q.jsx)(B, { 3431 value: "Achievements", 3432 icon: /* @__PURE__ */ (0, Q.jsx)(x, { 3433 icon: ie, 3434 style: { fontSize: "var(--font-size-2xl)" } 3435 }), 3436 label: /* @__PURE__ */ (0, Q.jsx)(D, { id: "builder.tabs.Achievements" }), 3437 disabled: s || c 3438 }, "Achievements"), 3439 H && Pe && n.Styles && /* @__PURE__ */ (0, Q.jsx)(B, { 3440 value: "Styles", 3441 icon: /* @__PURE__ */ (0, Q.jsx)(x, { 3442 icon: ae, 3443 style: { fontSize: "var(--font-size-2xl)" } 3444 }), 3445 label: /* @__PURE__ */ (0, Q.jsx)(D, { id: "builder.tabs.Styles" }), 3446 disabled: c 3447 }, "Styles") 3448 ]); 3449 var Y = m; 3450 !n[Y] && ft.length > 0 && (Y = "MainView"); 3451 var X = window.location.pathname; 3452 return /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [ 3453 /* @__PURE__ */ (0, Q.jsx)(Et, { 3454 when: ne && !Oe, 3455 message: (e) => e.pathname.substring(0, e.pathname.lastIndexOf("/")) === X.substring(0, X.lastIndexOf("/")) ? null : "Are you sure you want to leave without saving?" 3456 }), 3457 /* @__PURE__ */ (0, Q.jsx)("link", { 3458 href: "/css/course-builder/course-builder-reset.css", 3459 rel: "stylesheet" 3460 }), 3461 /* @__PURE__ */ (0, Q.jsx)("style", { 3462 type: "text/css", 3463 children: Fn 3464 }), 3465 z && /* @__PURE__ */ (0, Q.jsx)("style", { children: "\n header ul.side-nav {\n display: none;\n }\n\n #secondary-nav-tabs a.button-collapse.top-nav {\n display: none;\n }\n\n #secondary-nav-tabs .settings-dropdown-container {\n margin-left: 96px;\n }\n\n nav .lm-logo {\n display: flex;\n }\n " }), 3466 /* @__PURE__ */ (0, Q.jsx)("style", { children: "\n .lm-logo .full-logo {\n display: none;\n }\n\n .lm-logo .small-logo {\n display: inline-block;\n }\n " }), 3467 /* @__PURE__ */ (0, Q.jsxs)(y, { 3468 id: "builder-root", 3469 sx: { 3470 height: "calc(100vh - var(--ui-nav-tabs-height))", 3471 overflow: "hidden", 3472 display: "flex", 3473 flexFlow: "row", 3474 position: "relative" 3475 }, 3476 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 3477 className: "settings-sidebar", 3478 sx: { 3479 width: "96px", 3480 backgroundColor: "var(--color-teal)", 3481 display: "flex", 3482 flexDirection: "column", 3483 "& .MuiTabs-root .MuiTab-root": { 3484 display: "flex", 3485 justifyContent: "center", 3486 alignItems: "center", 3487 textTransform: "none", 3488 fontSize: "var(--font-size-xs)", 3489 color: "white", 3490 width: "100%", 3491 height: "96px", 3492 padding: "0", 3493 minWidth: "100%" 3494 }, 3495 "& .MuiTabs-root .MuiTab-root.Mui-disabled": { 3496 cursor: "not-allowed", 3497 opacity: ".5" 3498 }, 3499 "& .MuiTab-root:hover": { background: "var(--ui-color-primary2)" }, 3500 "& .MuiButtonBase-root.Mui-selected": { 3501 background: "var(--ui-color-primary2)", 3502 color: "white" 3503 }, 3504 "& .MuiTab-iconWrapper": { 3505 width: "1.6rem", 3506 marginBottom: ".7rem" 3507 } 3508 }, 3509 children: [/* @__PURE__ */ (0, Q.jsx)(y, { sx: { 3510 height: "2rem", 3511 background: "var(--ui-color-nav-background)" 3512 } }
3512), H && /* @__PURE__ */ (0, Q.jsx)(Ne, { 3513 TabIndicatorProps: { sx: { display: "none" } }, 3514 sx: { 3515 "& .MuiTabs-flexContainer": { 3516 flexWrap: "wrap", 3517 justifyContent: "center" 3518 }, 3519 "& .MuiTab-root": { minWidth: "auto" }, 3520 "& .MuiTabs-scroller": { 3521 display: "flex", 3522 justifyContent: "center" 3523 } 3524 }, 3525 variant: z ? "fullWidth" : "standard", 3526 value: Y, 3527 onChange: (e, t) => { 3528 xe ? (Ee(t), we(!0)) : h(t); 3529 }, 3530 children: ft 3531 })] 3532 }), /* @__PURE__ */ (0, Q.jsxs)(y, { 3533 sx: { 3534 flex: 1, 3535 display: "flex", 3536 flexDirection: "column" 3537 }, 3538 children: [ 3539 !Ae && /* @__PURE__ */ (0, Q.jsx)(ye, { 3540 position: "static", 3541 sx: nr, 3542 children: /* @__PURE__ */ (0, Q.jsxs)(Re, { 3543 className: "builder-toolbar", 3544 sx: { 3545 display: "flex", 3546 flexDirection: z ? "column" : "row", 3547 justifyContent: z ? "center" : "space-between", 3548 pr: 2, 3549 pl: "var(--ui-builder-alignment-padding)", 3550 background: "var(--ui-color-surface-paper)", 3551 borderTopLeftRadius: "10px" 3552 }, 3553 disableGutters: !0, 3554 children: [ 3555 /* @__PURE__ */ (0, Q.jsxs)(y, { 3556 sx: { 3557 ml: 0, 3558 mt: 1.25, 3559 mb: 1.25, 3560 display: "flex", 3561 alignItems: "center", 3562 gap: "var(--ui-builder-alignment-padding)", 3563 justifyContent: z ? "center" : "" 3564 }, 3565 children: [
3566 O.HeaderImagePath && /* @__PURE__ */ (0, Q.jsx)(y, { 3567 component: "img", 3568 src: O.HeaderImagePath, 3569 sx: { 3570 height: "48px", 3571 aspectRatio: "16/9" 3572 }, 3573 onClick: Ke 3574 }), 3575 /* @__PURE__ */ (0, Q.jsxs)(y, { 3576 sx: { 3577 display: "flex", 3578 flexDirection: "column", 3579 justifyContent: z ? "center" : "flex-start" 3580 }, 3581 children: [ 3582 /* @__PURE__ */ (0, Q.jsx)(k, { 3583 sx: rr, 3584 onClick: Ke, 3585 children: O.Header || /* @__PURE__ */ (0, Q.jsx)(D, { id: "builder.appBar.noTitle" }) 3586 }), 3587 n.HeaderBadge, 3588 We.show && /* @__PURE__ */ (0, Q.jsxs)(k, { 3589 sx: { 3590 ...ir, 3591 color: We.color, 3592 fontWeight: "var(--font-weight-semibold)" 3593 }, 3594 children: [/* @__PURE__ */ (0, Q.jsx)(x, { 3595 icon: ze, 3596 style: { 3597 color: "var(--ui-color-warning)", 3598 fontSize: "var(--font-size-base)" 3599 } 3600 }), We.message] 3601 }), 3602 /* @__PURE__ */ (0, Q.jsxs)(k, { 3603 sx: { 3604 ...ir, 3605 color: K().color 3606 }, 3607 children: [Ue && /* @__PURE__ */ (0, Q.jsx)(x, { 3608 icon: ze, 3609 style: { 3610 color: "var(--ui-color-warning)", 3611 fontSize: "var(--font-size-base)" 3612 } 3613 }), K().message] 3614 }) 3615 ] 3616 }), 3617 z && /* @__PURE__ */ (0, Q.jsx)(y, { 3618 style: { 3619 position: "absolute", 3620 right: "16px" 3621 }, 3622 children: n.CancelButton 3623 }) 3624 ] 3625 }), 3626 /* @__PURE__ */ (0, Q.jsx)(y, { 3627 sx: { display: Y === "Styles" ? "initial" : "none" }, 3628 children: /* @__PURE__ */ (0, Q.jsx)(y, { 3629 sx: { 3630 display: "flex", 3631 gap: "16px" 3632 }, 3633 children: /* @__PURE__ */ (0, Q.jsx)("div", { id: "apply-styles-portal" }) 3634 }) 3635 }), 3636 /* @__PURE__ */ (0, Q.jsxs)(y, { 3637 sx: { display: Y === "Styles" ? "none" : "flex" }, 3638 children: [Y !== "Styles" && /* @__PURE__ */ (0, Q.jsxs)(Q.Fragment, { children: [H && n.Preview && !R && /* @__PURE__ */ (0, Q.jsx)(Ne, { 3639 TabIndicatorProps: { sx: { display: "none" } }, 3640 variant: z ? "fullWidth" : "standard", 3641 value: "Save", 3642 onChange: (e, t) => h(t), 3643 style: { marginRight: Le ? "" : "10px" }, 3644 sx: { 3645 width: "max-content", 3646 "& .MuiTab-root": Ue ? { 3647 backgroundColor: "var(--ui-color-warning) !important", 3648 color: "var(--ui-color-accent) !important", 3649 "&:hover": { 3650 backgroundColor: "var(--ui-color-warning) !important", 3651 color: "var(--ui-color-accent) !important", 3652 opacity: .8 3653 } 3654 } : {} 3655 }, 3656 children: /* @__PURE__ */ (0, Q.jsx)(B, { 3657 disableRipple: !1, 3658 onClick: c ? void 0 : q, 3659 variant: "filled", 3660 value: "Save", 3661 label: /* @__PURE__ */ (0, Q.jsx)(D, { id: "builder.save.Save" }), 3662 disabled: c 3663 }, "Save") 3664 }), Le && (c ? /* @__PURE__ */ (0, Q.jsx)(y, { 3665 sx: { 3666 display: "flex", 3667 alignItems: "center", 3668 opacity: .5, 3669 pointerEvents: "none" 3670 }, 3671 children: n.SaveAndPublish 3672 }) : n.SaveAndPublish)] }), !z && n.CancelButton] 3673 }) 3674 ] 3675 }) 3676 }), 3677 /* @__PURE__ */ (0, Q.jsxs)(y, { 3678 sx: { 3679 overflowY: "auto", 3680 flex: 1 3681 }, 3682 children: [/* @__PURE__ */ (0, Q.jsx)(Kn, { editableByAccountName: Be }), /* @__PURE__ */ (0, Q.jsx)(Z.Suspense, { 3683 fallback: /* @__PURE__ */ (0, Q.jsx)(y, { 3684 sx: { 3685 display: "flex", 3686 justifyContent: "center", 3687 p: 4 3688 }, 3689 children: /* @__PURE__ */ (0, Q.jsx)(se, {}) 3690 }),
3691 children: Y === "Styles" ? /* @__PURE__ */ (0, Q.jsx)(Qn, { onDirtyStyles: (e) => Se(e) }) : n[Y] 3692 })] 3693 }), 3694 /* @__PURE__ */ (0, Q.jsx)(Gn, {}), 3695 /* @__PURE__ */ (0, Q.jsx)(Bn, {}), 3696 /* @__PURE__ */ (0, Q.jsx)(Ye, { 3697 open: ve, 3698 type: be, 3699 onConfirm: at, 3700 onCancel: it, 3701 onExited: () => P(null), 3702 accountMismatch: U, 3703 courseAccountName: W, 3704 currentAccountName: G 3705 }), 3706 Ce && /* @__PURE__ */ (0, Q.jsx)(De, { 3707 type: "styles", 3708 handleConfirm: () => { 3709 h(Te), we(!1); 3710 }, 3711 handleCancel: () => we(!1) 3712 }) 3713 ] 3714 })] 3715 }), 3716 He 3717 ] }); 3718} 3719//#endregion 3720//#region Components/Builder/Sidebar.jsx 3721var or = { 3722 position: "relative", 3723 overflow: "hidden", 3724 display: "flex", 3725 flexDirection: "column", 3726 height: "100%", 3727 minWidth: { 3728 md: "22em", 3729 xl: "30em" 3730 } 3731}, sr = { 3732 overflowY: "auto", 3733 pr: "1em", 3734 display: "flex", 3735 flexDirection: "column", 3736 flexGrow: 1, 3737 "& > div.menu-items": { height: "100%" } 3738}; 3739function cr({ tabTitlesPrefix: e, children: t, sx: n, value: r, handleTabChange: i, collapsible: a = !1, compact: o = !1, tabIcons: c, onManualCollapse: l, ...u }) { 3740 let [d, f] = (0, Z.useState)(0), [p, m] = (0, Z.useState)(!1), h = (0, Z.useRef)(null), g = r === void 0 ? d : r; 3741 (0, Z.useEffect)(() => { 3742 h.current && (h.current.scrollTop = 0); 3743 }, [g]), (0, Z.useEffect)(() => { 3744 o || m(!1); 3745 }, [o]); 3746 var _ = Array.isArray(t) ? t.filter((e) => e !== null) : t; 3747 function v(e, t) { 3748 f(t); 3749 } 3750 let b = i || v; 3751 function S(e) { 3752 b(null, e), m(!0); 3753 } 3754 function C() { 3755 o && p ? m(!1) : !o && l && l(); 3756 } 3757 let w = /* @__PURE__ */ (0, Q.jsx)(Ne, { 3758 variant: "scrollable", 3759 value: g, 3760 onChange: b, 3761 sx: a ? { 3762 flex: 1, 3763 minWidth: 0 3764 } : void 0, 3765 children: Z.Children.map(_, (t, n) => /* @__PURE__ */ (0, Q.jsx)(B, { 3766 sx: { textTransform: "unset" }, 3767 disableRipple: !0, 3768 disabled: t?.props?.disabled, 3769 id: `sidebar-tab-${n}`, 3770 label: /* @__PURE__ */ (0, Q.jsx)(D, { id: `${e}${n}` }) 3771 }, n)) 3772 }), T = /* @__PURE__ */ (0, Q.jsx)(s, { 3773 ref: h, 3774 className: "sidebar-presenter", 3775 sx: sr, 3776 children: Z.Children.toArray(t)[g] 3777 }); 3778 if (!a) return /* @__PURE__ */ (0, Q.jsxs)(y, { 3779 sx: { 3780 ...or, 3781 ...n 3782 }, 3783 children: [w, T] 3784 }); 3785 let E = o && !p; 3786 return /* @__PURE__ */ (0, Q.jsxs)(y, { 3787 sx: { ...n }, 3788 className: `sidebar-collapsible ${E ? "is-rail" : "is-expanded"}`, 3789 children: [/* @__PURE__ */ (0, Q.jsx)("div", { 3790 className: "sidebar-rail", 3791 children: (c || []).map((t, n) => { 3792 let r = n === g; 3793 return /* @__PURE__ */ (0, Q.jsx)(be, { 3794 title: /* @__PURE__ */ (0, Q.jsx)(D, { id: `${e}${n}` }), 3795 placement: "right", 3796 enterDelay: 500, 3797 enterNextDelay: 500, 3798 children: /* @__PURE__ */ (0, Q.jsx)(ve, { 3799 size: "small", 3800 onClick: () => S(n), 3801 className: `sidebar-rail-icon${r ? " is-active" : ""}`, 3802 children: /* @__PURE__ */ (0, Q.jsx)(x, { 3803 icon: t, 3804 style: { 3805 width: 16, 3806 height: 16 3807 } 3808 }) 3809 }) 3810 }, n); 3811 }) 3812 }), /* @__PURE__ */ (0, Q.jsxs)("div", { 3813 className: "sidebar-tabs", 3814 children: [/* @__PURE__ */ (0, Q.jsxs)(y, { 3815 sx: { 3816 display: "flex", 3817 alignItems: "center", 3818 flexShrink: 0 3819 }, 3820 children: [w, /* @__PURE__ */ (0, Q.jsx)(be, { 3821 title: /* @__PURE__ */ (0, Q.jsx)(D, { 3822 id: "sidebar.collapse", 3823 defaultMessage: "Collapse" 3824 }), 3825 placement: "left", 3826 enterDelay: 500, 3827 enterNextDelay: 500, 3828 children: /* @__PURE__ */ (0, Q.jsx)(ve, { 3829 size: "small", 3830 onClick: C, 3831 sx: { 3832 flexShrink: 0, 3833 mr: .5 3834 }, 3835 children: /* @__PURE__ */ (0, Q.jsx)(x, { 3836 icon: G, 3837 style: { 3838 width: 16, 3839 height: 16 3840 } 3841 }) 3842 }) 3843 })] 3844 }), T] 3845 })] 3846 }); 3847} 3848//#endregion 3849//#region Components/Mobi/MobiAdapterMount.tsx 3850function lr({ adapter: e }) { 3851 let t = (0, Z.useContext)(St), n = (0, Z.useRef)(null), r = (0, Z.useRef)(e); 3852 return r.current = e, (0, Z.useEffect)(() => { 3853 if (!t) return; 3854 let e = t.register(r.current); 3855 return n.current = e, () => { 3856 n.current = null, t.unregister(e); 3857 }; 3858 }, [t]), (0, Z.useEffect)(() => { 3859 t && n.current != null && t.update(n.current, e); 3860 }, [t, e]), null; 3861} 3862//#endregion 3863//#region Components/Builder/mobi/cardMetadataTools.ts 3864var ur = { 3865 getDescription: "Read the current course-level metadata (title, cover image URL, description). The same values are already in courseContext.courseMetadata â only call this tool if you need to confirm the latest state after an update.", 3866 updateDescription: "Update course-level metadata: title (header), cover image URL (headerImagePath), or description. Pass only the fields you want to change; omitted fields are left untouched. Empty string is allowed and clears the field. For a \"generate a new cover image from <prompt>\" request, first call generate_image to get a URL, then call this tool with that URL as headerImagePath. Description is plain text. Use this for whole-course shell changes â not for module or element edits.", 3867 headerParam: "Course title shown in the top app bar.", 3868 imageParam: "URL of the course cover image.", 3869 descriptionParam: "Plain-text course description shown on publish." 3870}; 3871function dr(e) { 3872 if (e.toolPrefix === "course") return ur; 3873 let { noun: t } = e; 3874 return { 3875 getDescription: `Read the current ${t}-level metadata (title, cover image URL, description). Only call this tool if you need to confirm the latest state after an update.`, 3876 updateDescription: `Update ${t}-level metadata: title (header), cover image URL (headerImagePath), or description. Pass only the fields you want to change; omitted fields are left untouched. Empty string is allowed and clears the field. For a "generate a new cover image from <prompt>" request, first call generate_image to get a URL, then call this tool with that URL as headerImagePath. Description is plain text. Use this for ${t}-level shell changes only.`, 3877 headerParam: `${t[0].toUpperCase()}${t.slice(1)} title shown in the top app bar.`, 3878 imageParam: `URL of the ${t} cover image.`, 3879 descriptionParam: `Plain-text ${t} description shown on publish.` 3880 }; 3881} 3882function fr(e, t) { 3883 let n = dr(t), r = `get_${t.toolPrefix}_metadata`, i = `update_${t.toolPrefix}_metadata`; 3884 return { 3885 [r]: { 3886 definition: { 3887 name: r, 3888 description: n.getDescription, 3889 parameters: { 3890 type: "object", 3891 properties: {}, 3892 required: [] 3893 } 3894 }, 3895 handler: () => { 3896 let t = e.current.card; 3897 return X({ 3898 header: t?.Header ?? "", 3899 headerImagePath: t?.HeaderImagePath ?? "", 3900 description: t?.Description ?? "" 3901 }); 3902 }, 3903 isFrontend: !0 3904 }, 3905 [i]: { 3906 definition: { 3907 name: i, 3908 description: n.updateDescription, 3909 parameters: { 3910 type: "object", 3911 properties: { 3912 header: { 3913 type: "string", 3914 description: n.headerParam 3915 }, 3916 headerImagePath: { 3917 type: "string", 3918 description: n.imageParam 3919 }, 3920 description: { 3921 type: "string", 3922 description: n.descriptionParam 3923 } 3924 }, 3925 required: [] 3926 } 3927 }, 3928 handler: (t) => { 3929 let { header: n, headerImagePath: r, description: i } = t ?? {}, a = e.current.setCardField; 3930 if (!a) return q("Card model not available"); 3931 let o = {}; 3932 if (n !== void 0) { 3933 if (typeof n != "string") return q("header must be a string"); 3934 o.Header = n; 3935 } 3936 if (r !== void 0) { 3937 if (typeof r != "string") return q("headerImagePath must be a string"); 3938 o.HeaderImagePath = nt(r); 3939 } 3940 if (i !== void 0) { 3941 if (typeof i != "string") return q("description must be a string"); 3942 o.Description = i; 3943 } 3944 return Object.keys(o).length === 0 ? q("No fields provided. Pass at least one of: header, headerImagePath, description.") : (a(o), e.current.setDirty?.(!0), X({ updated: Object.keys(o) })); 3945 }, 3946 isFrontend: !0 3947 } 3948 }; 3949} 3950//#endregion 3951//#region Components/Builder/mobi/assignmentTools.ts 3952var pr = [ 3953 "Department", 3954 "JobTitle", 3955 "Location", 3956 "ManagerEmail", 3957 "Group" 3958], mr = { cardId: { 3959 type: "string", 3960 description: "Card to operate on. Omit for the card currently open in the builder. When targeting a DIFFERENT card than the open one, state that card to the user first." 3961} }; 3962function hr(e, t, n = {}) { 3963 let r = n.getJson ?? xt(), i = n.postJson ?? wt(t), a = n.invalidate ?? Ct, s = (t) => { 3964 let n = t?.cardId; 3965 if (typeof n == "string" && n.trim()) return n.trim(); 3966 let r = e?.current?.card?.CardId; 3967 return typeof r == "string" && r ? r : null; 3968 }, c = () => q("No card in context â pass cardId explicitly (e.g. an id from find_courses)."), l = async (e) => { 3969 let t = await r("/Assignment/GetRuleValues?ruleField=Group"); 3970 if (t?.success === !1) return { error: t.message ?? "Failed to load groups" }; 3971 let n = t?.values ?? [], i = n.find((t) => t.Key === e || (t.Value ?? "").toLowerCase() === e.toLowerCase()); 3972 return i?.Key ? { id: i.Key } : { error: `Unknown group "${e}". Valid groups: ${n.map((e) =>
3972 e.Value).filter(Boolean).join(", ") || "(none)"}.` }; 3973 }; 3974 return { 3975 get_assignment_rules: { 3976 definition: { 3977 name: "get_assignment_rules", 3978 description: "List the automatic assignment rules on a card: each rule's id, criteria (field/value, or all-learners when empty), due-date configuration, and start/end window. Call before deleting a rule.", 3979 parameters: { 3980 type: "object", 3981 properties: { ...mr }, 3982 required: [] 3983 } 3984 }, 3985 handler: async (e) => { 3986 let t = s(e); 3987 if (!t) return c(); 3988 try { 3989 let e = await r(`/Assignment/GetRulesForCard?cardId=${encodeURIComponent(t)}`); 3990 return e?.success === !1 ? q(e.message ?? "Failed to load rules") : X({ 3991 cardId: t, 3992 rules: e?.rules ?? [] 3993 }); 3994 } catch (e) { 3995 return q(`Failed to load assignment rules: ${e.message}`); 3996 } 3997 }, 3998 isFrontend: !0, 3999 category: "assignments" 4000 }, 4001 get_assignment_rule_fields: { 4002 definition: { 4003 name: "get_assignment_rule_fields", 4004 description: "List the learner attributes assignment-rule criteria can match on (e.g. Department, JobTitle, Location, ManagerEmail, Group).", 4005 parameters: { 4006 type: "object", 4007 properties: {}, 4008 required: [] 4009 } 4010 }, 4011 handler: async () => { 4012 try { 4013 let e = await r("/Assignment/GetRuleFields"); 4014 return X({ fields: e }); 4015 } catch (e) { 4016 return q(`Failed to load rule fields: ${e.message}`); 4017 } 4018 }, 4019 isFrontend: !0, 4020 category: "assignments" 4021 }, 4022 get_assignment_rule_values: { 4023 definition: { 4024 name: "get_assignment_rule_values", 4025 description: "List the existing values for a rule field (the account's actual departments, job titles, â¦). ALWAYS call this before save_assignment_rule and copy an EXACT returned value â never invent one; a value that matches no learners assigns nothing. Entries are {Key, Value} pairs: Value is the display name to show the user; Key is what the rule stores (for Group, Key is the group id â save_assignment_rule accepts either and normalizes names to the id).", 4026 parameters: { 4027 type: "object", 4028 properties: { ruleField: { 4029 type: "string", 4030 enum: [...pr], 4031 description: "Which learner attribute to list values for." 4032 } }, 4033 required: ["ruleField"] 4034 } 4035 }, 4036 handler: async (e) => { 4037 let t = e?.ruleField; 4038 if (typeof t != "string" || !pr.includes(t)) return q(`ruleField must be one of: ${pr.join(", ")}`);
4039 try { 4040 let e = await r(`/Assignment/GetRuleValues?ruleField=${encodeURIComponent(t)}`); 4041 return e?.success === !1 ? q(e.message ?? "Failed to load values") : X({ 4042 ruleField: t, 4043 values: e?.values ?? [] 4044 }); 4045 } catch (e) { 4046 return q(`Failed to load rule values: ${e.message}`); 4047 } 4048 }, 4049 isFrontend: !0, 4050 category: "assignments" 4051 }, 4052 save_assignment_rule: { 4053 definition: { 4054 name: "save_assignment_rule", 4055 description: "Create an automatic assignment rule on a card. TAKES EFFECT IMMEDIATELY on save. Rules CANNOT be edited â to change one, delete it (delete_assignment_rule) and create a new one. Criteria: pass ruleField + ruleValue (value copied EXACTLY from get_assignment_rule_values). Omitting BOTH creates an ALL-LEARNERS rule â confirm that scope with the user before calling. Due dates: dueDateType \"none\" (default), \"absolute\" (requires dueDate ISO date), or \"relative\" (requires durationNumber = days after assignment). currentLearners: false (default) assigns only learners who match AFTER the rule exists; true also assigns everyone matching right now.", 4056 parameters: { 4057 type: "object", 4058 properties: { 4059 ...mr, 4060 ruleField: { 4061 type: "string", 4062 enum: [...pr] 4063 }, 4064 ruleValue: { 4065 type: "string", 4066 description: "Exact value from get_assignment_rule_values. For Group, the group name or id (names are normalized to the id)." 4067 }, 4068 dueDateType: { 4069 type: "string", 4070 enum: [ 4071 "none", 4072 "absolute", 4073 "relative" 4074 ] 4075 }, 4076 dueDate: { 4077 type: "string", 4078 description: "ISO date â required when dueDateType is \"absolute\"." 4079 }, 4080 durationNumber: { 4081 type: "number", 4082 description: "Days after assignment â required when dueDateType is \"relative\"." 4083 }, 4084 currentLearners: { type: "boolean" }, 4085 startDate: { 4086 type: "string", 4087 description: "ISO date the rule starts applying (optional)." 4088 }, 4089 endDate: { 4090 type: "string", 4091 description: "ISO date the rule stops applying (optional)." 4092 } 4093 }, 4094 required: [] 4095 } 4096 }, 4097 handler: async (e) => { 4098 let t = e ?? {}, n = s(t); 4099 if (!n) return c(); 4100 if (typeof t.id == "string" && t.id.trim()) return q("Assignment rules cannot be edited â delete the rule (delete_assignment_rule) and create a new one."); 4101 let r = t.dueDateType ?? "none"; 4102 if (![ 4103 "none", 4104 "absolute", 4105 "relative" 4106 ].includes(r)) return q("dueDateType must be one of: none, absolute, relative"); 4107 if (r === "absolute" && typeof t.dueDate != "string") return q("dueDateType \"absolute\" requires dueDate (ISO date)"); 4108 let u = t.durationNumber; 4109 if (r === "relative" && (typeof u != "number" || !(u > 0))) return q("dueDateType \"relative\" requires durationNumber > 0"); 4110 let d = typeof t.ruleField == "string" && t.ruleField.length > 0; 4111 if (d !== (typeof t.ruleValue == "string" && t.ruleValue.length > 0)) return q("Pass BOTH ruleField and ruleValue, or NEITHER (all-learners rule)."); 4112 if (d && !pr.includes(t.ruleField)) return q(`ruleField must be one of: ${pr.join(", ")}`); 4113 let f = t.startDate ?? null, p = t.endDate ?? null; 4114 if (f && p && new Date(f) > new Date(p)) return q("startDate must be on or before endDate"); 4115 let m = t.ruleValue; 4116 if (d && t.ruleField === "Group") try { 4117 let e = await l(t.ruleValue); 4118 if ("error" in e) return q(e.error); 4119 m = e.id; 4120 } catch (e) { 4121 return q(`Failed to resolve group: ${e.message}`); 4122 } 4123 let h = { 4124 Id: "", 4125 CardId: n, 4126 NewLearners: !0, 4127 CurrentLearners: t.currentLearners === !0, 4128 StartDate: f, 4129 EndDate: p, 4130 DueDateType: r, 4131 DueDate: r === "absolute" ? t.dueDate : null, 4132 DurationNumber: r === "relative" ? u : null, 4133 UnassignDateType: "none", 4134 UnassignDueDate: null, 4135 UnassignDurationNumber: null, 4136 AutoUnassign: !0, 4137 Criteria: d ? [{ 4138 RuleField: t.ruleField, 4139 RuleValue: m 4140 }] : [{}] 4141 };
4142 try { 4143 let e = await i("/Assignment/SaveRule", h); 4144 return e?.success ? (a(o.cardAssignments(n)), X({ 4145 cardId: n, 4146 rule: { 4147 criteria: d ? `${t.ruleField} = ${t.ruleValue}` : "ALL learners", 4148 dueDateType: r, 4149 currentLearners: t.currentLearners === !0 4150 } 4151 })) : q(e?.message ?? "Server rejected the rule"); 4152 } catch (e) { 4153 return q(`Failed to save rule: ${e.message}`); 4154 } 4155 }, 4156 isFrontend: !0, 4157 category: "assignments" 4158 }, 4159 delete_assignment_rule: { 4160 definition: { 4161 name: "delete_assignment_rule", 4162 description: "Delete an assignment rule. TAKES EFFECT IMMEDIATELY. Call get_assignment_rules first, confirm with the user WHICH rule, and pass its id.", 4163 parameters: { 4164 type: "object", 4165 properties: { 4166 ...mr, 4167 ruleId: { 4168 type: "string", 4169 description: "Rule id from get_assignment_rules." 4170 } 4171 }, 4172 required: ["ruleId"] 4173 } 4174 }, 4175 handler: async (e) => { 4176 let t = e ?? {}, n = s(t); 4177 if (!n) return c(); 4178 if (typeof t.ruleId != "string" || !t.ruleId) return q("ruleId is required"); 4179 try { 4180 let e = await i("/Assignment/DeleteRule", { 4181 Id: t.ruleId, 4182 CardId: n 4183 }); 4184 return e?.success ? (a(o.cardAssignments(n)), X({ deleted: t.ruleId })) : q(e?.message ?? "Server rejected the delete"); 4185 } catch (e) { 4186 return q(`Failed to delete rule: ${e.message}`); 4187 } 4188 }, 4189 isFrontend: !0, 4190 category: "assignments" 4191 }, 4192 find_learners_for_assignment: { 4193 definition: { 4194 name: "find_learners_for_assignment", 4195 description: "Search the account's learners by name/username for assignment work on a card. Returns each learner's id (pass it to set_learner_assignment), name, assigned state, due date, and completion. `search` is REQUIRED and must be non-empty â there is no \"list everyone\" mode; for account-wide operations use bulk_edit_learner_assignments filters instead.", 4196 parameters: { 4197 type: "object", 4198 properties: { 4199 ...mr, 4200 search: { 4201 type: "string", 4202 description: "Name/username fragment. Required, non-empty." 4203 }, 4204 page: { 4205 type: "number", 4206 description: "Result page, starting at 1. Omit for the default: all matches in one response (up to the server limit of 100)." 4207 } 4208 }, 4209 required: ["search"] 4210 } 4211 }, 4212 handler: async (e) => { 4213 let t = e ?? {}, n = s(t); 4214 if (!n) return c(); 4215 let i = typeof t.search == "string" ? t.search.trim() : ""; 4216 if (!i) return q("search is required and must be non-empty"); 4217 let a = typeof t.page == "number" && t.page > 0 ? Math.floor(t.page) : null; 4218 try { 4219 let e = `/Assignment/GetLearnersForAssignment?cardId=${encodeURIComponent(n)}&search=${encodeURIComponent(i)}` + (a === null ? "" : `&selectedPage=${a - 1}`), t = await r(e); 4220 return t?.success === !1 ? q(t.message ?? "Search failed") : X({ 4221 cardId: n, 4222 ...a === null ? {} : { page: a }, 4223 ...t 4224 }); 4225 } catch (e) { 4226 return q(`Learner search failed: ${e.message}`); 4227 } 4228 }, 4229 isFrontend: !0, 4230 category: "assignments" 4231 }, 4232 set_learner_assignment: { 4233 definition: { 4234 name: "set_learner_assignment", 4235 description: "Assign or unassign ONE learner on a card. TAKES EFFECT IMMEDIATELY. learnerId is the `id` from find_learners_for_assignment. Optional dueDate (ISO date) â applies only when assigning; it is ignored on unassign. forceReassignment re-assigns a learner who already completed the card.", 4236 parameters: { 4237 type: "object", 4238 properties: { 4239 ...mr, 4240 learnerId: { 4241 type: "string", 4242 description: "Learner id from find_learners_for_assignment." 4243 }, 4244 assigned: { 4245 type: "boolean", 4246 description: "true = assign, false = unassign." 4247 }, 4248 dueDate: { 4249 type: "string", 4250 description: "ISO due date (optional)." 4251 }, 4252 forceReassignment: { type: "boolean" } 4253 }, 4254 required: ["learnerId", "assigned"] 4255 } 4256 }, 4257 handler: async (e) => { 4258 let t = e ?? {}, n = s(t); 4259 if (!n) return c(); 4260 if (typeof t.learnerId != "string" || !t.learnerId) return q("learnerId is required"); 4261 if (typeof t.assigned != "boolean") return q("assigned must be a boolean");
4262 try { 4263 let e = await i("/Assignment/SaveLearnerAssignment", { 4264 id: t.learnerId, 4265 cardId: n, 4266 assigned: t.assigned, 4267 dueDate: t.assigned && typeof t.dueDate == "string" ? t.dueDate : null, 4268 forceReassignment: t.forceReassignment === !0 4269 }); 4270 return e?.success ? (a(o.learnerAssignments(n)), X({ 4271 learnerId: t.learnerId, 4272 cardId: n, 4273 assigned: t.assigned 4274 })) : q(e?.message ?? "Server rejected the assignment"); 4275 } catch (e) { 4276 return q(`Failed to save assignment: ${e.message}`); 4277 } 4278 }, 4279 isFrontend: !0, 4280 category: "assignments" 4281 }, 4282 bulk_edit_learner_assignments: { 4283 definition: { 4284 name: "bulk_edit_learner_assignments", 4285 description: "Assign or unassign EVERY learner matching a filter â a mass mutation that TAKES EFFECT IMMEDIATELY. REQUIRED WORKFLOW: state the filter and its expected scope to the user, get their explicit confirmation, and only then call with confirmed: true. The call is rejected without it. Filters combine (AND): search, department, jobTitle, location, managerEmail, group, assignedFilter (true = currently assigned only, false = currently unassigned only). NO filters = the ENTIRE account.", 4286 parameters: { 4287 type: "object", 4288 properties: { 4289 ...mr, 4290 confirmed: { 4291 type: "boolean", 4292 description: "Must be true, and only after the user explicitly confirmed the operation and its scope." 4293 }, 4294 assigned: { 4295 type: "boolean", 4296 description: "true = assign matches, false = unassign matches." 4297 }, 4298 search: { type: "string" }, 4299 department: { type: "string" }, 4300 jobTitle: { type: "string" }, 4301 location: { type: "string" }, 4302 managerEmail: { type: "string" }, 4303 group: { 4304 type: "string", 4305 description: "Group name or id â names are resolved to the account's group id." 4306 }, 4307 assignedFilter: { type: "boolean" }, 4308 setDueDate: { type: "boolean" }, 4309 dueDate: { 4310 type: "string", 4311 description: "ISO due date â used when setDueDate is true." 4312 }, 4313 forceReassignment: { type: "boolean" } 4314 }, 4315 required: ["assigned", "confirmed"] 4316 } 4317 }, 4318 handler: async (e) => { 4319 let t = e ?? {}, n = s(t); 4320 if (!n) return c(); 4321 if (t.confirmed !== !0) return q("Bulk edit not confirmed. State the filter and expected scope to the user, get explicit confirmation, then call again with confirmed: true."); 4322 if (typeof t.assigned != "boolean") return q("assigned must be a boolean"); 4323 let r = null; 4324 if (typeof t.group == "string" && t.group.trim()) try { 4325 let e = await l(t.group.trim()); 4326 if ("error" in e) return q(e.error); 4327 r = e.id; 4328 } catch (e) { 4329 return q(`Failed to resolve group: ${e.message}`); 4330 } 4331 try { 4332 let e = { 4333 cardId: n, 4334 search: t.search ?? null, 4335 department: t.department ?? null, 4336 jobTitle: t.jobTitle ?? null, 4337 location: t.location ?? null, 4338 managerEmail: t.managerEmail ?? null, 4339 group: r, 4340 assignedFilter: typeof t.assignedFilter == "boolean" ? t.assignedFilter : null, 4341 assigned: t.assigned, 4342 setDueDate: t.setDueDate === !0, 4343 dueDate: typeof t.dueDate == "string" ? t.dueDate : null, 4344 forceReassignment: t.forceReassignment === !0, 4345 bulkTable: [] 4346 }, s = await i("/Assignment/BulkEditLearnerAssignments", e); 4347 return s?.success ? (a(o.learnerAssignments(n)), X({ 4348 cardId: n, 4349 assigned: t.assigned, 4350 filtersApplied: Object.keys(t).filter((e) => ![ 4351 "confirmed", 4352 "cardId", 4353 "assigned" 4354 ].includes(e) && t[e] != null) 4355 })) : q(s?.message ?? "Server rejected the bulk edit"); 4356 } catch (e) { 4357 return q(`Bulk edit failed: ${e.message}`); 4358 } 4359 }, 4360 isFrontend: !0, 4361 category: "assignments" 4362 } 4363 }; 4364} 4365//#endregion 4366//#region Components/Builder/mobi/channelTools.ts 4367var gr = (e, t) => { 4368 let n = new Set(t); 4369 return new Set(e).size === n.size && e.every((e) => n.has(e)); 4370}, _r = (e) => e?.CurrentlyPublished ? "This card is currently published. Channel changes are saved as a DRAFT and reach learners only after the card is republished â remind the user." : void 0; 4371function vr(e, t, n = {}) { 4372 let r = n.getJson ?? xt(), i = n.postJson ?? wt(t), a = n.invalidate ?? Ct, s = async () => (await r("/Builder/GetAvailableChannels"))?.channels ?? [], c = (e) => e.map((e) => ({ 4373 id: e.Id, 4374 name: e.Name 4375 })), l = (e, t) => e.map((e) => ({ 4376 id: e, 4377 name: t.find((t) => t.Id === e)?.Name ?? "(unknown channel)" 4378 })); 4379 return { 4380 get_card_channels: { 4381 definition: { 4382 name: "get_card_channels", 4383 description: "Read which channels this card belongs to. Returns TWO layers: `savedChannels` (what the server has for the draft) and `pendingChannels` (unsaved local edits, null when there are none), plus `effectiveChannels` (what saving right now would persist). Call before set_card_channels so you can pass the COMPLETE final list.", 4384 parameters: { 4385 type: "object", 4386 properties: {}, 4387 required: [] 4388 } 4389 }, 4390 handler: async () => { 4391 let t = e.current.card, n = t?.CardId; 4392 if (!n) return q("No card is open");
4393 try { 4394 let [e, i] = await Promise.all([r(`/Builder/GetDraftChannels?cardId=${encodeURIComponent(n)}`), s()]), a = e?.channels ?? [], o = t?.Channels ?? null, c = o !== null && !gr(o, a); 4395 return X({ 4396 savedChannels: l(a, i), 4397 pendingChannels: c ? l(o, i) : null, 4398 hasUnsavedChanges: c, 4399 effectiveChannels: l(o ?? a, i) 4400 }); 4401 } catch (e) { 4402 return q(`Failed to load channels: ${e.message}`); 4403 } 4404 }, 4405 isFrontend: !0, 4406 category: "channels" 4407 }, 4408 get_available_channels: { 4409 definition: { 4410 name: "get_available_channels", 4411 description: "List the account's channels (id + name). Use the names when talking to the user and pass names or ids to set_card_channels.", 4412 parameters: { 4413 type: "object", 4414 properties: {}, 4415 required: [] 4416 } 4417 }, 4418 handler: async () => { 4419 try { 4420 return X({ channels: c(await s()) }); 4421 } catch (e) { 4422 return q(`Failed to load available channels: ${e.message}`); 4423 } 4424 }, 4425 isFrontend: !0, 4426 category: "channels" 4427 }, 4428 set_card_channels: { 4429 definition: { 4430 name: "set_card_channels", 4431 description: "Replace the card's channel list with the COMPLETE final list â this is a FULL REPLACEMENT, not an add/remove delta, so call get_card_channels first and include every channel that should remain. Accepts channel names (case-insensitive) or ids. This is a LOCAL change: it takes effect when the user saves the card. To remove the card from ALL channels pass an empty list AND clearAll: true â only after the user explicitly asked for that.", 4432 parameters: { 4433 type: "object", 4434 properties: { 4435 channels: { 4436 type: "array", 4437 items: { type: "string" }, 4438 description: "The complete final list of channel names or ids." 4439 }, 4440 clearAll: { 4441 type: "boolean", 4442 description: "Required (true) when channels is empty â confirms intentional removal from all channels." 4443 } 4444 }, 4445 required: ["channels"] 4446 } 4447 }, 4448 handler: async (t) => { 4449 let n = t ?? {}, r = e.current.card, i = e.current.setCardField; 4450 if (!r?.CardId || !i) return q("No card is open"); 4451 if (!Array.isArray(n.channels) || n.channels.some((e) => typeof e != "string")) return q("channels must be an array of strings (names or ids)"); 4452 let a = n.channels.map((e) => e.trim()).filter(Boolean); 4453 if (a.length === 0) return n.clearAll === !0 ? (i({ Channels: [] }), e.current.setDirty?.(!0), X({ 4454 channels: [], 4455 note: "Local change â takes effect when the user saves the card.", 4456 ..._r(r) ? { warning: _r(r) } : {} 4457 })) : q("An empty list removes the card from ALL channels. If the user explicitly asked for that, call again with clearAll: true."); 4458 try { 4459 let t = await s(), n = [], o = []; 4460 for (let e of a) { 4461 let r = t.find((t) => t.Id === e || t.Name.toLowerCase() === e.toLowerCase()); 4462 r ? n.includes(r.Id) || n.push(r.Id) : o.push(e); 4463 } 4464 return o.length > 0 ? q(`Unknown channel(s): ${o.join(", ")}. Valid channels: ${t.map((e) => e.Name).join(", ")}. Use create_channel first if a new channel is needed.`) : (i({ Channels: n }), e.current.setDirty?.(!0), X({ 4465 channels: l(n, t), 4466 note: "Local change â takes effect when the user saves the card.", 4467 ..._r(r) ? { warning: _r(r) } : {} 4468 })); 4469 } catch (e) { 4470 return q(`Failed to set channels: ${e.message}`); 4471 } 4472 }, 4473 isFrontend: !0, 4474 category: "channels" 4475 }, 4476 create_channel: { 4477 definition: { 4478 name: "create_channel", 4479 description: "Create a new channel in the account. TAKES EFFECT IMMEDIATELY. Does NOT add this card to the new channel â follow with set_card_channels (including the existing channels plus the new one).", 4480 parameters: { 4481 type: "object", 4482 properties: { name: { 4483 type: "string", 4484 description: "Name for the new channel." 4485 } }, 4486 required: ["name"] 4487 } 4488 }, 4489 handler: async (e) => { 4490 let t = typeof e?.name == "string" ? e.name.trim() : ""; 4491 if (!t) return q("name is required and must be non-empty"); 4492 try { 4493 let e = await i(`/Builder/AddChannel/${encodeURIComponent(t)}`); 4494 return e?.success === !1 ? q(e.message ?? "Server rejected the channel") : (a(o.channelsList), X({ 4495 created: e?.channel ? { 4496 id: e.channel.Id, 4497 name: e.channel.Name 4498 } : { name: t }, 4499 note: "The card is NOT in this channel yet â use set_card_channels to add it." 4500 })); 4501 } catch (e) { 4502 return q(`Failed to create channel: ${e.message}`); 4503 } 4504 }, 4505 isFrontend: !0, 4506 category: "channels" 4507 } 4508 }; 4509} 4510//#endregion 4511//#region Components/Builder/mobi/cardSettingsTools.ts 4512var yr = (e) => e ? e.toISOString() : null; 4513function br(e) { 4514 if (e == null || e === "") return null; 4515 let t = Number(e); 4516 return Number.isFinite(t) ? t : null; 4517} 4518function xr(e, t) { 4519 let { noun: n, toolPrefix: r, warnRepublishWhenPublished: i, extra: a } = t, o = `get_${r}_settings`, s = `update_${r}_settings`, c = `Local change â takes effect when the user saves the ${n}.`, l = [ 4520 "hidden", 4521 "searchHidden", 4522 "durationEstimate", 4523 "publishDate", 4524 "goDeadDate", 4525 ...a?.keys ?? [] 4526 ]; 4527 return { 4528 [o]: { 4529 definition: { 4530 name: o, 4531 description: `Read the current ${n} settings: hidden (hidden from channel view), searchHidden (hidden from search), durationEstimate (estimated minutes to complete, null = unset), publishDate / goDeadDate (ISO 8601 go-live / expiry instants, null = unset), and scheduled (true when publishDate is in the future â the ${n} is forced hidden until it goes live).` + (a ? ` ${a.getDescription}` : ""), 4532 parameters: { 4533 type: "object", 4534 properties: {}, 4535 required: [] 4536 } 4537 }, 4538 handler: () => { 4539 let t = e.current.card; 4540 if (!t) return q(`${n} not loaded`); 4541 let r = yt(t.PublishDate), i = !!r && r.getTime() > Date.now(); 4542 return X({ 4543 hidden: !!t.Hidden, 4544 searchHidden: !!t.SearchHidden, 4545 durationEstimate: br(t.DurationEstimate), 4546 publishDate: yr(r), 4547 goDeadDate: yr(yt(t.GoDeadDate)), 4548 scheduled: i, 4549 ...i ? { note: `Scheduled: this ${n} is forced hidden from channel view and search until publishDate; hidden/searchHidden cannot be changed while scheduled.` } : {}, 4550 ...a ? a.read() : {} 4551 }); 4552 }, 4553 isFrontend: !0 4554 }, 4555 [s]: { 4556 definition: { 4557 name: s, 4558 description: `Update ${n} settings: visibility (hidden / searchHidden), estimated duration, and publish/expire dates. Pass only the fields you want to change; omitted fields are left untouched. A ${n} with a future publishDate is forced hidden from channel view and search until it goes live â hidden/searchHidden cannot be changed while scheduled. ` + (a ? `${a.updateDescription} ` : "") + `LOCAL change â takes effect when the user saves the ${n}.`, 4559 parameters: { 4560 type: "object", 4561 properties: { 4562 hidden: { 4563 type: "boolean", 4564 description: `true hides the ${n} from learners' channel view.` 4565 }, 4566 searchHidden: { 4567 type: "boolean", 4568 description: `true hides the ${n} from learners' search results.` 4569 }, 4570 durationEstimate: { 4571 type: ["integer", "null"], 4572 description: "Estimated minutes to complete (0-9999). null clears the estimate." 4573 }, 4574 publishDate: { 4575 type: ["string", "null"], 4576 description: `ISO 8601 date-time when the ${n} goes live. A future value schedules it (forced hidden until then). null clears the schedule.` 4577 }, 4578 goDeadDate: { 4579 type: ["string", "null"], 4580 description: `ISO 8601 date-time when the ${n} expires for learners. null clears it.` 4581 }, 4582 ...a?.updateProperties ?? {} 4583 }, 4584 required: [] 4585 } 4586 }, 4587 handler: (t) => { 4588 let r = t ?? {}, { card: o, setCardField: s, setDirty: u } = e.current; 4589 if (!o || !s) return q(`${n} not loaded`);
4590 if (!l.some((e) => r[e] !== void 0)) return q(`No fields provided. Pass at least one of: ${l.join(", ")}.`); 4591 let d = {}, f = yt(o.PublishDate); 4592 if (r.publishDate !== void 0) { 4593 if (r.publishDate === null) d.PublishDate = null, f = null; 4594 else { 4595 let e = typeof r.publishDate == "string" ? yt(r.publishDate) : null; 4596 if (!e) return q("publishDate must be an ISO 8601 date-time string, or null to clear"); 4597 d.PublishDate = e, f = e; 4598 } 4599 } 4600 let p = yt(o.GoDeadDate); 4601 if (r.goDeadDate !== void 0) { 4602 if (r.goDeadDate === null) d.GoDeadDate = null, p = null; 4603 else { 4604 let e = typeof r.goDeadDate == "string" ? yt(r.goDeadDate) : null; 4605 if (!e) return q("goDeadDate must be an ISO 8601 date-time string, or null to clear"); 4606 d.GoDeadDate = e, p = e; 4607 } 4608 } 4609 let m = !!f && f.getTime() > Date.now(); 4610 if (m && (r.hidden !== void 0 || r.searchHidden !== void 0)) return q(`This ${n} is scheduled to go live on ${f.toISOString()} â until then it is forced hidden from channel view and search, so hidden/searchHidden cannot be changed. Change or clear publishDate first.`); 4611 if (r.hidden !== void 0) { 4612 if (typeof r.hidden != "boolean") return q("hidden must be a boolean"); 4613 d.Hidden = r.hidden; 4614 } 4615 if (r.searchHidden !== void 0) { 4616 if (typeof r.searchHidden != "boolean") return q("searchHidden must be a boolean"); 4617 d.SearchHidden = r.searchHidden; 4618 } 4619 if (r.durationEstimate !== void 0) { 4620 if (r.durationEstimate === null) d.DurationEstimate = null; 4621 else if (typeof r.durationEstimate != "number" || !Number.isInteger(r.durationEstimate) || r.durationEstimate < 0 || r.durationEstimate > 9999) return q("durationEstimate must be an integer 0-9999 (estimated minutes), or null to clear"); 4622 else d.DurationEstimate = String(r.durationEstimate); 4623 } 4624 if (a) { 4625 let e = a.apply(r); 4626 if (typeof e == "string") return q(e); 4627 Object.assign(d, e); 4628 } 4629 s(d), u?.(!0); 4630 let h = i && o.CurrentlyPublished ? `This ${n} is currently published. Settings changes are saved as a DRAFT and reach learners only after it is republished â remind the user.` : f && p && p.getTime() <= f.getTime() ? "goDeadDate is on or before publishDate â the " + n + " would expire before (or as) it goes live. Confirm the dates with the user." : void 0; 4631 return X({ 4632 updated: l.filter((e) => r[e] !== void 0), 4633 note: c + (m ? ` publishDate is in the future â the ${n} is hidden from channel view and search until it goes live.` : ""), 4634 ...h ? { warning: h } : {} 4635 }); 4636 }, 4637 isFrontend: !0 4638 } 4639 }; 4640} 4641var Sr = [ 4642 "lesson", 4643 "quiz", 4644 "skillcheck" 4645]; 4646function Cr(e, t) { 4647 let n = () => e.current?.courseRef?.current ?? t.current.card?.course ?? null, r = (e, t) => (e.modules ?? []).filter((e) => e?.type === t).map((e) => ({ 4648 id: e.id, 4649 header: e.header ?? "" 4650 })), i = (e) => e.map((e) => `${e.id} ("${e.header}")`).join(", "), a = { 4651 keys: [ 4652 "forcedOrder", 4653 "completionType", 4654 "completionPercent", 4655 "completionQuiz", 4656 "completionSkillcheck" 4657 ], 4658 getDescription: "Also returns forcedOrder (learners must complete lessons in order), completionType / completionPercent / completionQuiz / completionSkillcheck (how learners complete the course), and the availableQuizzes / availableSkillchecks rosters ({id, header}).", 4659 updateDescription: "Course-specific: forcedOrder (true = Sequential, false = Any Order) and completion â completionType \"lesson\" (finish completionPercent % of each lesson), \"quiz\" (pass the completionQuiz quiz), or \"skillcheck\" (pass the completionSkillcheck skill check). Setting completionType to \"quiz\"/\"skillcheck\" defaults completionPercent to 100 and, when unset, the target to the LAST quiz/skill check in the course â call get_course_settings first for the rosters.", 4660 updateProperties: { 4661 forcedOrder: { 4662 type: "boolean", 4663 description: "true = learners must complete lessons in order (Sequential); false = Any Order." 4664 }, 4665 completionType: { 4666 type: "string", 4667 enum: [...Sr], 4668 description: "How learners complete the course: \"lesson\" (percentage of each lesson), \"quiz\"
4668(passing score on a quiz), or \"skillcheck\" (passing score on a skill check)." 4669 }, 4670 completionPercent: { 4671 type: "integer", 4672 description: "Percent 0-100. With completionType \"lesson\": the share of each lesson to finish." 4673 }, 4674 completionQuiz: { 4675 type: "string", 4676 description: "Module id of the quiz that completes the course (see availableQuizzes)." 4677 }, 4678 completionSkillcheck: { 4679 type: "string", 4680 description: "Module id of the skill check that completes the course (see availableSkillchecks)." 4681 } 4682 }, 4683 read: () => { 4684 let e = n(); 4685 return e ? { 4686 forcedOrder: e.forcedOrder === !0 || e.forcedOrder === "true", 4687 completionType: e.completionType ?? null, 4688 completionPercent: br(e.completionPercent), 4689 completionQuiz: e.completionQuiz ?? null, 4690 completionSkillcheck: e.completionSkillcheck ?? null, 4691 availableQuizzes: r(e, "quiz"), 4692 availableSkillchecks: r(e, "skillcheck") 4693 } : {}; 4694 }, 4695 apply: (t) => { 4696 if (!a.keys.some((e) => t[e] !== void 0)) return {}; 4697 let o = n(); 4698 if (!o) return "Course not loaded"; 4699 let s = r(o, "quiz"), c = r(o, "skillcheck"), l = {}; 4700 if (t.forcedOrder !== void 0) { 4701 if (typeof t.forcedOrder != "boolean") return "forcedOrder must be a boolean"; 4702 l.forcedOrder = t.forcedOrder ? "true" : "false"; 4703 } 4704 if (t.completionType !== void 0) { 4705 let e = t.completionType; 4706 if (typeof e != "string" || !Sr.includes(e)) return `completionType must be one of: ${Sr.join(", ")}`; 4707 if (e === "quiz" && s.length === 0) return "This course has no quiz modules â add a quiz before setting completionType to \"quiz\"."; 4708 if (e === "skillcheck" && c.length === 0) return "This course has no skill-check modules â add one before setting completionType to \"skillcheck\"."; 4709 l.completionType = e, (e === "quiz" || e === "skillcheck") && (t.completionPercent === void 0 && (l.completionPercent = "100"), e === "quiz" && t.completionQuiz === void 0 && !o.completionQuiz && (l.completionQuiz = s[s.length - 1].id), e === "skillcheck" && t.completionSkillcheck === void 0 && !o.completionSkillcheck && (l.completionSkillcheck = c[c.length - 1].id)); 4710 } 4711 if (t.completionPercent !== void 0) { 4712 let e = t.completionPercent; 4713 if (typeof e != "number" || !Number.isInteger(e) || e < 0 || e > 100) return "completionPercent must be an integer 0-100"; 4714 l.completionPercent = String(e); 4715 } 4716 if (t.completionQuiz !== void 0) { 4717 if (typeof t.completionQuiz != "string" || !s.some((e) => e.id === t.completionQuiz)) return s.length === 0 ? "This course has no quiz modules." : `completionQuiz must be one of the course's quiz module ids: ${i(s)}`; 4718 l.completionQuiz = t.completionQuiz; 4719 } 4720 if (t.completionSkillcheck !== void 0) { 4721 if (typeof t.completionSkillcheck != "string" || !c.some((e) => e.id === t.completionSkillcheck)) return c.length === 0 ? "This course has no skill-check modules." : `completionSkillcheck must be one of the course's skill-check module ids: ${i(c)}`; 4722 l.completionSkillcheck = t.completionSkillcheck; 4723 } 4724 Ze(o); 4725 let u = { 4726 ...n() ?? o, 4727 ...l 4728 }; 4729 return e.current?.courseRef && (e.current.courseRef.current = u), { course: u }; 4730 } 4731 }; 4732 return xr(t, { 4733 noun: "course", 4734 toolPrefix: "course", 4735 extra: a 4736 }); 4737} 4738//#endregion 4739//#region Components/Builder/mobi/writeSemanticsContext.ts 4740var wr = "CARD-MANAGEMENT WRITE SEMANTICS (assignments / channels / achievements tool libraries): assignment and achievement tools write to the SERVER IMMEDIATELY when called â there is no save step, so confirm scope with the user before saving/deleting rules, bulk-editing assignments, or publishing achievements. Channel changes are LOCAL until the user saves; on currently-published content they reach learners only after the user republishes â say so when it applies."; 4741//#endregion 4742export { jt as _, hr as a, cr as c, zn as d, Pn as f, Gt as g, $ as h, vr as i, ar as l, nn as m, xr as n, fr as o, dn as p, Cr as r, lr as s, wr as t, Qn as u };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.