@timeback/sdk 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +97 -8
  2. package/dist/chunk-07j8zre9.js +2 -0
  3. package/dist/chunk-5171mkp2.js +2 -0
  4. package/dist/chunk-63afdp3y.js +8 -0
  5. package/dist/chunk-8gg8n8v9.js +2 -0
  6. package/dist/chunk-9se82640.js +1 -0
  7. package/dist/chunk-agpf1x3g.js +16 -0
  8. package/dist/chunk-hnf0tart.js +2 -0
  9. package/dist/chunk-qr0bbnsr.js +1 -0
  10. package/dist/chunk-whc53e0y.js +11 -0
  11. package/dist/chunk-x9gvef7q.js +1 -0
  12. package/dist/client/adapters/react/hooks/types.d.ts +80 -0
  13. package/dist/client/adapters/react/hooks/types.d.ts.map +1 -1
  14. package/dist/client/adapters/react/hooks/useTimebackProfile.d.ts +42 -0
  15. package/dist/client/adapters/react/hooks/useTimebackProfile.d.ts.map +1 -0
  16. package/dist/client/adapters/react/hooks/useTimebackVerification.d.ts +17 -5
  17. package/dist/client/adapters/react/hooks/useTimebackVerification.d.ts.map +1 -1
  18. package/dist/client/adapters/react/index.d.ts +2 -1
  19. package/dist/client/adapters/react/index.d.ts.map +1 -1
  20. package/dist/client/adapters/react/index.js +2 -494
  21. package/dist/client/adapters/react/provider.d.ts.map +1 -1
  22. package/dist/client/adapters/solid/index.d.ts +3 -0
  23. package/dist/client/adapters/solid/index.d.ts.map +1 -1
  24. package/dist/client/adapters/solid/index.ts +12 -0
  25. package/dist/client/adapters/solid/primitives/createTimebackProfile.d.ts +58 -0
  26. package/dist/client/adapters/solid/primitives/createTimebackProfile.d.ts.map +1 -0
  27. package/dist/client/adapters/solid/primitives/createTimebackProfile.ts +209 -0
  28. package/dist/client/adapters/solid/primitives/createTimebackVerification.d.ts +38 -0
  29. package/dist/client/adapters/solid/primitives/createTimebackVerification.d.ts.map +1 -0
  30. package/dist/client/adapters/solid/primitives/createTimebackVerification.ts +173 -0
  31. package/dist/client/adapters/solid/types.d.ts +109 -0
  32. package/dist/client/adapters/solid/types.d.ts.map +1 -0
  33. package/dist/client/adapters/solid/types.ts +110 -0
  34. package/dist/client/adapters/svelte/index.d.ts +2 -1
  35. package/dist/client/adapters/svelte/index.d.ts.map +1 -1
  36. package/dist/client/adapters/svelte/index.ts +11 -2
  37. package/dist/client/adapters/svelte/{stores.d.ts → stores/client.d.ts} +11 -9
  38. package/dist/client/adapters/svelte/stores/client.d.ts.map +1 -0
  39. package/dist/client/adapters/svelte/{stores.ts → stores/client.ts} +24 -52
  40. package/dist/client/adapters/svelte/stores/index.d.ts +10 -0
  41. package/dist/client/adapters/svelte/stores/index.d.ts.map +1 -0
  42. package/dist/client/adapters/svelte/stores/index.ts +22 -0
  43. package/dist/client/adapters/svelte/stores/profile.d.ts +66 -0
  44. package/dist/client/adapters/svelte/stores/profile.d.ts.map +1 -0
  45. package/dist/client/adapters/svelte/stores/profile.ts +168 -0
  46. package/dist/client/adapters/svelte/stores/verification.d.ts +43 -0
  47. package/dist/client/adapters/svelte/stores/verification.d.ts.map +1 -0
  48. package/dist/client/adapters/svelte/stores/verification.ts +208 -0
  49. package/dist/client/adapters/svelte/types.d.ts +35 -0
  50. package/dist/client/adapters/svelte/types.d.ts.map +1 -0
  51. package/dist/client/adapters/vue/composables/useTimebackProfile.d.ts +51 -0
  52. package/dist/client/adapters/vue/composables/useTimebackProfile.d.ts.map +1 -0
  53. package/dist/client/adapters/vue/composables/useTimebackProfile.ts +186 -0
  54. package/dist/client/adapters/vue/composables/useTimebackVerification.d.ts +46 -0
  55. package/dist/client/adapters/vue/composables/useTimebackVerification.d.ts.map +1 -0
  56. package/dist/client/adapters/vue/composables/useTimebackVerification.ts +169 -0
  57. package/dist/client/adapters/vue/index.d.ts +3 -0
  58. package/dist/client/adapters/vue/index.d.ts.map +1 -1
  59. package/dist/client/adapters/vue/index.ts +12 -1
  60. package/dist/client/adapters/vue/types.d.ts +109 -0
  61. package/dist/client/adapters/vue/types.d.ts.map +1 -0
  62. package/dist/client/adapters/vue/types.ts +110 -0
  63. package/dist/client/lib/activity/activity.class.d.ts +5 -5
  64. package/dist/client/lib/activity/activity.class.d.ts.map +1 -1
  65. package/dist/client/lib/user-cache.d.ts +39 -0
  66. package/dist/client/lib/user-cache.d.ts.map +1 -0
  67. package/dist/client/lib/user-cache.ts +168 -0
  68. package/dist/client/lib/utils.d.ts +15 -0
  69. package/dist/client/lib/utils.d.ts.map +1 -1
  70. package/dist/client/namespaces/activity.d.ts +2 -3
  71. package/dist/client/namespaces/activity.d.ts.map +1 -1
  72. package/dist/client.d.ts +1 -1
  73. package/dist/client.js +1 -257
  74. package/dist/edge.js +1 -86271
  75. package/dist/identity.js +1 -86131
  76. package/dist/index.d.ts +2 -2
  77. package/dist/index.js +22 -104883
  78. package/dist/server/adapters/express.js +1 -85973
  79. package/dist/server/adapters/native.js +2 -221
  80. package/dist/server/adapters/nextjs.js +1 -233
  81. package/dist/server/adapters/nuxt.js +1 -86046
  82. package/dist/server/adapters/solid-start.js +1 -85945
  83. package/dist/server/adapters/svelte-kit.js +1 -279
  84. package/dist/server/adapters/tanstack-start.js +1 -85918
  85. package/dist/server/handlers/activity/attempts.d.ts +51 -0
  86. package/dist/server/handlers/activity/attempts.d.ts.map +1 -0
  87. package/dist/server/handlers/activity/caliper.d.ts +46 -5
  88. package/dist/server/handlers/activity/caliper.d.ts.map +1 -1
  89. package/dist/server/handlers/activity/completion.d.ts +43 -0
  90. package/dist/server/handlers/activity/completion.d.ts.map +1 -0
  91. package/dist/server/handlers/activity/handler.d.ts +18 -1
  92. package/dist/server/handlers/activity/handler.d.ts.map +1 -1
  93. package/dist/server/handlers/activity/progress.d.ts +47 -0
  94. package/dist/server/handlers/activity/progress.d.ts.map +1 -0
  95. package/dist/server/handlers/activity/schema.d.ts +1 -2
  96. package/dist/server/handlers/activity/schema.d.ts.map +1 -1
  97. package/dist/server/handlers/activity/types.d.ts +1 -2
  98. package/dist/server/handlers/activity/types.d.ts.map +1 -1
  99. package/dist/server/lib/index.d.ts +1 -1
  100. package/dist/server/lib/index.d.ts.map +1 -1
  101. package/dist/server/lib/utils.d.ts +61 -0
  102. package/dist/server/lib/utils.d.ts.map +1 -1
  103. package/dist/server/timeback.d.ts +2 -2
  104. package/dist/server/timeback.d.ts.map +1 -1
  105. package/dist/server/types.d.ts +7 -1
  106. package/dist/server/types.d.ts.map +1 -1
  107. package/dist/shared/constants.d.ts +19 -0
  108. package/dist/shared/constants.d.ts.map +1 -1
  109. package/dist/shared/types.d.ts +62 -8
  110. package/dist/shared/types.d.ts.map +1 -1
  111. package/dist/shared/xp-calculator.d.ts +25 -0
  112. package/dist/shared/xp-calculator.d.ts.map +1 -0
  113. package/package.json +6 -4
  114. package/dist/client/adapters/svelte/stores.d.ts.map +0 -1
  115. package/dist/server/handlers/activity/gradebook.d.ts +0 -56
  116. package/dist/server/handlers/activity/gradebook.d.ts.map +0 -1
@@ -0,0 +1,2 @@
1
+ class H{params;sendActivity;_startedAt;_isPaused=!1;_pausedAt;_totalPausedMs=0;_ended=!1;constructor(q,z){this.params=q;this.sendActivity=z;this._startedAt=new Date}get startedAt(){return this._startedAt}get isPaused(){return this._isPaused}get elapsedMs(){if(this._ended)return 0;let q=new Date,z=q.getTime()-this._startedAt.getTime()-this._totalPausedMs;if(this._isPaused&&this._pausedAt)z-=q.getTime()-this._pausedAt.getTime();return Math.max(0,z)}_buildPayload(q){let z=new Date,J,Y;if(q.time)J=Math.max(0,Math.round(q.time.active)),Y=Math.max(0,Math.round(q.time.inactive??0));else Y=this._totalPausedMs+(this._isPaused&&this._pausedAt?z.getTime()-this._pausedAt.getTime():0),J=Math.max(0,z.getTime()-this._startedAt.getTime()-Y);let N=q.totalQuestions!==void 0,j=q.correctQuestions!==void 0;if(N!==j)throw Error("Invalid activity metrics: totalQuestions and correctQuestions must be provided together.");if(N&&j&&q.correctQuestions>q.totalQuestions)throw Error("Invalid activity metrics: correctQuestions cannot exceed totalQuestions.");let F={...N?{totalQuestions:q.totalQuestions}:{},...j?{correctQuestions:q.correctQuestions}:{},...q.xpEarned===void 0?{}:{xpEarned:q.xpEarned},...q.masteredUnits===void 0?{}:{masteredUnits:q.masteredUnits}};return{id:this.params.id,name:this.params.name,course:this.params.course,startedAt:this._startedAt.toISOString(),endedAt:z.toISOString(),elapsedMs:J,pausedMs:Y,metrics:F,...q.pctComplete===void 0?{}:{pctComplete:q.pctComplete}}}pause(){if(this._isPaused||this._ended)return;this._isPaused=!0,this._pausedAt=new Date}resume(){if(!this._isPaused||this._ended||!this._pausedAt)return;this._totalPausedMs+=new Date().getTime()-this._pausedAt.getTime(),this._isPaused=!1,this._pausedAt=void 0}async end(q){if(this._ended)return;if(this._ended=!0,this._isPaused&&this._pausedAt)this._totalPausedMs+=new Date().getTime()-this._pausedAt.getTime(),this._isPaused=!1,this._pausedAt=void 0;let z=this._buildPayload(q);await this.sendActivity(z)}}var Z="/api/timeback",X={ACTIVITY:"/activity",IDENTITY:{SIGNIN:"/identity/signin",SIGNOUT:"/identity/signout",CALLBACK:"/identity/callback"},USER:{ME:"/user/me",VERIFY:"/user/verify"}};var D=3,O=[100,300,1000];function _(){if(!(typeof globalThis>"u"?void 0:globalThis.fetch))return;return(z,J)=>globalThis.fetch(z,J)}function $(){return typeof window<"u"}function K(){if(!$())return;return`${window.location.origin}${Z}`}function B(q){return new Promise((z)=>{setTimeout(z,q)})}function C(q,z){if(typeof q==="number")return q;return q[Math.min(z,q.length-1)]??1000}class G{sendActivity;constructor(q){this.sendActivity=q}start(q){return new H(q,this.sendActivity)}}class Q{getBaseURL;constructor(q){this.getBaseURL=q}signIn(){if(!$())throw Error("signIn() requires a browser environment");window.location.href=`${this.getBaseURL()}${X.IDENTITY.SIGNIN}`}}class V{getBaseURL;fetchImpl;constructor(q,z){this.getBaseURL=q;this.fetchImpl=z}async fetch(){if(!$())throw Error("user.fetch() requires a browser environment");let q=await this.fetchImpl(`${this.getBaseURL()}${X.USER.ME}`,{method:"GET",credentials:"include"});if(!q.ok){let z=await q.json().catch(()=>({error:"Unknown error"}));throw Error(z.error??"Failed to fetch user profile")}return q.json()}async verify(){if(!$())throw Error("user.verify() requires a browser environment");let q=await this.fetchImpl(`${this.getBaseURL()}${X.USER.VERIFY}`,{method:"GET",credentials:"include"});if(!q.ok){let J=await q.json().catch(()=>({error:"Unknown error"}));throw Error(J.error??"Failed to verify Timeback user")}let z=await q.json();if(z.verified&&z.timebackId)return{verified:!0,timebackId:z.timebackId};return{verified:!1}}}class W{activity;auth;user;_baseURL;_fetch;constructor(q={}){this._baseURL=q.baseURL;let z=q.fetch??_();if(!z)throw Error("TimebackClient requires a fetch implementation. Provide `fetch` in the constructor config for non-browser runtimes.");let J=q.plugins,Y=Array.isArray(J)?J:J?[J]:[];this._fetch=Y.reduce((N,j)=>j.wrapFetch(N),z),this.activity=new G((N)=>this.sendActivity(N)),this.auth=new Q(()=>this.baseURL),this.user=new V(()=>this.baseURL,this._fetch)}get baseURL(){if(!this._baseURL){let q=K();if(!q)throw Error("Timeback client requires a browser environment for default baseURL. Provide an explicit baseURL for server-side usage.");this._baseURL=q}return this._baseURL}async sendActivity(q){let z=await this._fetch(`${this.baseURL}${X.ACTIVITY}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(q),credentials:"include"});if(!z.ok){let J=await z.json().catch(()=>({error:"Unknown error"}));throw Error(J.error??"Failed to send activity")}}}function n(q={}){let z=q.baseURL??K();return new W({baseURL:z,fetch:q.fetch,plugins:q.plugins})}
2
+ export{D as a,O as b,B as c,C as d,H as e,W as f,n as g};
@@ -0,0 +1 @@
1
+ function k(x,I){let E=I?.batchSize??50;if(E<=0)return[x.slice()];let R=[];for(let $=0;$<x.length;$+=E)R.push(x.slice($,$+E));return R}function q(x){return x.filter((I)=>I.status==="fulfilled").flatMap((I)=>I.value)}function C(...x){return x.map((E)=>E?.trim()).filter((E)=>Boolean(E)).join(" ")||void 0}function D(x){let I=x.lastIndexOf("@");if(I<=0)return"<redacted>";let E=x.slice(0,I),R=x.slice(I+1);return`${E.slice(0,1)}***@${R}`}export{C as t,D as u,k as v,q as w};
@@ -0,0 +1,16 @@
1
+ import{c as P}from"./chunk-qr0bbnsr.js";import{v as c1,w as a1}from"./chunk-9se82640.js";import{M as B1,N as P1}from"./chunk-07j8zre9.js";var t=P1((Q3,T1)=>{var r={to(B,$){if(!$)return`\x1B[${B+1}G`;return`\x1B[${$+1};${B+1}H`},move(B,$){let x="";if(B<0)x+=`\x1B[${-B}D`;else if(B>0)x+=`\x1B[${B}C`;if($<0)x+=`\x1B[${-$}A`;else if($>0)x+=`\x1B[${$}B`;return x},up:(B=1)=>`\x1B[${B}A`,down:(B=1)=>`\x1B[${B}B`,forward:(B=1)=>`\x1B[${B}C`,backward:(B=1)=>`\x1B[${B}D`,nextLine:(B=1)=>"\x1B[E".repeat(B),prevLine:(B=1)=>"\x1B[F".repeat(B),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},p9={up:(B=1)=>"\x1B[S".repeat(B),down:(B=1)=>"\x1B[T".repeat(B)},l9={screen:"\x1B[2J",up:(B=1)=>"\x1B[1J".repeat(B),down:(B=1)=>"\x1B[J".repeat(B),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(B){let $="";for(let x=0;x<B;x++)$+=this.line+(x<B-1?r.up():"");if(B)$+=r.left;return $}};T1.exports={cursor:r,scroll:p9,erase:l9,beep:"\x07"}});var E1=P1((W3,e)=>{var l=process||{},y1=l.argv||[],p=l.env||{},d9=!(!!p.NO_COLOR||y1.includes("--no-color"))&&(!!p.FORCE_COLOR||y1.includes("--color")||l.platform==="win32"||(l.stdout||{}).isTTY&&p.TERM!=="dumb"||!!p.CI),D9=(B,$,x=B)=>(X)=>{let Q=""+X,W=Q.indexOf($,B.length);return~W?B+c9(Q,$,x,W)+$:B+Q+$},c9=(B,$,x,X)=>{let Q="",W=0;do Q+=B.substring(W,X)+x,W=X+$.length,X=B.indexOf($,W);while(~X);return Q+B.substring(W)},g1=(B=d9)=>{let $=B?D9:()=>String;return{isColorSupported:B,reset:$("\x1B[0m","\x1B[0m"),bold:$("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),dim:$("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),italic:$("\x1B[3m","\x1B[23m"),underline:$("\x1B[4m","\x1B[24m"),inverse:$("\x1B[7m","\x1B[27m"),hidden:$("\x1B[8m","\x1B[28m"),strikethrough:$("\x1B[9m","\x1B[29m"),black:$("\x1B[30m","\x1B[39m"),red:$("\x1B[31m","\x1B[39m"),green:$("\x1B[32m","\x1B[39m"),yellow:$("\x1B[33m","\x1B[39m"),blue:$("\x1B[34m","\x1B[39m"),magenta:$("\x1B[35m","\x1B[39m"),cyan:$("\x1B[36m","\x1B[39m"),white:$("\x1B[37m","\x1B[39m"),gray:$("\x1B[90m","\x1B[39m"),bgBlack:$("\x1B[40m","\x1B[49m"),bgRed:$("\x1B[41m","\x1B[49m"),bgGreen:$("\x1B[42m","\x1B[49m"),bgYellow:$("\x1B[43m","\x1B[49m"),bgBlue:$("\x1B[44m","\x1B[49m"),bgMagenta:$("\x1B[45m","\x1B[49m"),bgCyan:$("\x1B[46m","\x1B[49m"),bgWhite:$("\x1B[47m","\x1B[49m"),blackBright:$("\x1B[90m","\x1B[39m"),redBright:$("\x1B[91m","\x1B[39m"),greenBright:$("\x1B[92m","\x1B[39m"),yellowBright:$("\x1B[93m","\x1B[39m"),blueBright:$("\x1B[94m","\x1B[39m"),magentaBright:$("\x1B[95m","\x1B[39m"),cyanBright:$("\x1B[96m","\x1B[39m"),whiteBright:$("\x1B[97m","\x1B[39m"),bgBlackBright:$("\x1B[100m","\x1B[49m"),bgRedBright:$("\x1B[101m","\x1B[49m"),bgGreenBright:$("\x1B[102m","\x1B[49m"),bgYellowBright:$("\x1B[103m","\x1B[49m"),bgBlueBright:$("\x1B[104m","\x1B[49m"),bgMagentaBright:$("\x1B[105m","\x1B[49m"),bgCyanBright:$("\x1B[106m","\x1B[49m"),bgWhiteBright:$("\x1B[107m","\x1B[49m")}};e.exports=g1();e.exports.createColors=g1});import*as f from"tty";var{env:A={},argv:q1=[],platform:o1=""}=typeof process>"u"?{}:process,s1="NO_COLOR"in A||q1.includes("--no-color"),r1="FORCE_COLOR"in A||q1.includes("--color"),t1=o1==="win32",H1=A.TERM==="dumb",e1=f&&f.isatty&&f.isatty(1)&&A.TERM&&!H1,b9="CI"in A&&(("GITHUB_ACTIONS"in A)||("GITLAB_CI"in A)||("CIRCLECI"in A)),B9=!s1&&(r1||t1&&!H1||e1||b9),Y1=(B,$,x,X,Q=$.substring(0,B)+X,W=$.substring(B+x.length),b=W.indexOf(x))=>Q+(b<0?W:Y1(b,W,x,X)),$9=(B,$,x,X,Q)=>B<0?x+$+X:x+Y1(B,$,X,Q)+X,x9=(B,$,x=B,X=B.length+1)=>(Q)=>Q||!(Q===""||Q===void 0)?$9((""+Q).indexOf($,X),Q,B,$,x):"",q=(B,$,x)=>x9(`\x1B[${B}m`,`\x1B[${$}m`,x),W1={reset:q(0,0),bold:q(1,22,"\x1B[22m\x1B[1m"),dim:q(2,22,"\x1B[22m\x1B[2m"),italic:q(3,23),underline:q(4,24),inverse:q(7,27),hidden:q(8,28),strikethrough:q(9,29),black:q(30,39),red:q(31,39),green:q(32,39),yellow:q(33,39),blue:q(34,39),magenta:q(35,39),cyan:q(36,39),white:q(37,39),gray:q(90,39),bgBlack:q(40,49),bgRed:q(41,49),bgGreen:q(42,49),bgYellow:q(43,49),bgBlue:q(44,49),bgMagenta:q(45,49),bgCyan:q(46,49),bgWhite:q(47,49),blackBright:q(90,39),redBright:q(91,39),greenBright:q(92,39),yellowBright:q(93,39),blueBright:q(94,39),magentaBright:q(95,39),cyanBright:q(96,39),whiteBright:q(97,39),bgBlackBright:q(100,49),bgRedBright:q(101,49),bgGreenBright:q(102,49),bgYellowBright:q(103,49),bgBlueBright:q(104,49),bgMagentaBright:q(105,49),bgCyanBright:q(106,49),bgWhiteBright:q(107,49)},X9=({useColor:B=B9}={})=>B?W1:Object.keys(W1).reduce(($,x)=>({...$,[x]:String}),{}),{reset:Ab,bold:N,dim:w,italic:Cb,underline:Nb,inverse:wb,hidden:Pb,strikethrough:Tb,black:yb,red:g,green:Q9,yellow:O,blue:W9,magenta:gb,cyan:Eb,white:kb,gray:mb,bgBlack:Fb,bgRed:vb,bgGreen:hb,bgYellow:fb,bgBlue:pb,bgMagenta:lb,bgCyan:db,bgWhite:Db,blackBright:cb,redBright:ab,greenBright:Z1,yellowBright:ub,blueBright:ib,magentaBright:nb,cyanBright:ob,whiteBright:sb,bgBlackBright:rb,bgRedBright:tb,bgGreenBright:eb,bgYellowBright:b4,bgBlueBright:B4,bgMagentaBright:$4,bgCyanBright:x4,bgWhiteBright:X4}=X9();var q9=["playcademy.config.ts","playcademy.config.js","playcademy.config.json"];function H9(){return Promise.resolve({success:!1,error:"Playcademy config parser not yet implemented."})}function Y9(B){console.log(""),console.log(` ${g("✖")} ${N("Configuration Error")}`),console.log(""),console.log(` ${B}`),console.log(""),console.log(` ${w("Example playcademy.config.ts:")}`),console.log(""),console.log(` ${O("export default {")}`),console.log(` ${O(" name: 'My Playcademy App',")}`),console.log(` ${O(" // TODO: Define schema")}`),console.log(` ${O("}")}`),console.log("")}var c={name:"playcademy",filePatterns:q9,parse:H9,printError:Y9};import{readFile as I9}from"node:fs/promises";import{resolve as L9}from"node:path";import{homedir as J9,platform as G9}from"node:os";import{join as k}from"node:path";import{z as E}from"zod";var Z9=E.object({clientId:E.string().min(1,"Client ID is required"),clientSecret:E.string().min(1,"Client secret is required"),email:E.email("Valid email is required").optional()}),Y4=E.string().min(1,"Client ID is required").regex(/^[a-z0-9]+$/,"Client ID must contain only lowercase letters and numbers").length(26,"Client ID must be exactly 26 characters"),Z4=E.string().min(1,"Client secret is required").regex(/^[a-z0-9]+$/,"Client secret must contain only lowercase letters and numbers").max(53,"Client secret must be less than 53 characters");var J1=["staging","production"];function z9(){let B=J9();switch(G9()){case"darwin":return k(B,".timeback");case"win32":return k(process.env.APPDATA||k(B,"AppData","Roaming"),"timeback");default:return k(process.env.XDG_CONFIG_HOME||k(B,".config"),"timeback")}}var V9=z9(),O4=k(V9,"credentials.json");var R="timeback.config.json",G1="https://timeback.dev/schema.json",a="0.0.0",z1=2,V1=["$schema","name","launchUrl","sensor","defaults","courses"],K1=["subject","grade","courseCode","level","sensor","launchUrl","ids","metadata","overrides"],O1=["staging","production"],U1=["courseType","isSupplemental","isCustom","publishStatus","contactEmail","primaryApp","goals","metrics"],M1=["courseCode","level","metadata"],j1=["staging","production"],S1=["level","sensor","launchUrl","metadata"];import{existsSync as K9}from"node:fs";import{basename as I1,extname as O9,relative as U9,resolve as L1}from"node:path";import{loadConfig as M9}from"c12";function R1(B){return O9(B).toLowerCase()===".json"}async function u(B,$){if($&&!R1($))throw Error(`Config file must be JSON (.json): ${$}`);let x=await M9({cwd:B,name:"timeback",configFile:$??R,rcFile:!1,packageJson:!1,dotenv:!1,envName:!1,extend:!1,omit$Keys:!0,defaults:{},overrides:{}});if(!x.config||Object.keys(x.config).length===0)return null;let X=x.config;if("extends"in X)throw Error("The 'extends' feature is not supported in timeback.config.json. Please inline all configuration.");let{$schema:Q,...W}=X;return{config:W,configFile:x.configFile??L1(B,$??R)}}async function j9(B={}){let $=process.cwd();try{if(B.configPath&&!R1(B.configPath))return{success:!1,error:`Config file must be JSON (.json): ${B.configPath}`};if(B.configPath){let Q=L1($,B.configPath);if(!K9(Q))return{success:!1,error:`Config file not found: ${B.configPath}`}}let x=await u($,B.configPath);if(!x)return{success:!1,error:`No timeback config found. Run ${Z1("timeback init")} to create one.`};let X=P.safeParse(x.config);if(!X.success){let Q=X.error.issues.map((W)=>` - ${W.path.join(".")}: ${W.message}`).join(`
2
+ `);return{success:!1,error:`Invalid config in ${I1(x.configFile)}:
3
+ ${Q}`}}return{success:!0,config:X.data,configPath:x.configFile}}catch(x){return{success:!1,error:`Failed to load ${B.configPath?I1(B.configPath):R}:
4
+ ${x instanceof Error?x.message:String(x)}`}}}function S9(B){return U9(process.cwd(),B)}var R9=[R];function _9(B){let $={staging:[],production:[]};for(let x of J1)$[x]=B.courses.map((X)=>X.ids?.[x]).filter((X)=>!!X);return $}async function A9(B){try{let $=L9(B,"package.json");return JSON.parse(await I9($,"utf-8")).version??a}catch{return a}}async function C9(){let B=process.cwd();try{let $=await u(B);if(!$)return{success:!1,error:`No timeback config found. Create ${R}`};let x=P.safeParse($.config);if(!x.success){let W=x.error.issues.map((b)=>` - ${b.path.join(".")}: ${b.message}`).join(`
5
+ `);return{success:!1,error:`Invalid config in ${R}:
6
+ ${W}`}}let X=await A9(B),Q={...x.data,version:X};return{success:!0,config:{...Q,path:$.configFile,courseIds:_9(Q)}}}catch($){return{success:!1,error:`Failed to load ${R}:
7
+ ${$ instanceof Error?$.message:String($)}`}}}function N9(B){console.log(""),console.log(` ${g("✖")} ${N("Configuration Error")}`),console.log(""),console.log(` ${B}`),console.log(""),console.log(` ${w("Example timeback.config.json:")}`),console.log(""),console.log(` ${O("{")}`),console.log(` ${O(' "$schema": "https://timeback.dev/schema.json",')}`),console.log(` ${O(' "name": "My Timeback App",')}`),console.log(` ${O(' "launchUrl": "https://example.com/play",')}`),console.log(` ${O(' "courses": [')}`),console.log(` ${O(' { "subject": "Math", "grade": 3 }')}`),console.log(` ${O(" ]")}`),console.log(` ${O("}")}`),console.log("")}var i={name:"timeback",filePatterns:R9,parse:C9,printError:N9};function T(B,$){let x={},X=Object.keys(B),Q=B;for(let W of $)if(W in Q&&Q[W]!==void 0)x[W]=Q[W];for(let W of X)if(!(W in x)&&Q[W]!==void 0)x[W]=Q[W];return x}function A1(B){let $={};for(let[x,X]of Object.entries(B))if(X!==void 0)$[x]=X;return $}function w9(B){if(!B)return;let $=A1(B);if(Object.keys($).length===0)return;return T($,O1)}function n(B){if(!B)return;let $=A1(B);if(Object.keys($).length===0)return;return T($,U1)}function P9(B){if(!B)return;let $={};if(B.courseCode)$.courseCode=B.courseCode;if(B.level)$.level=B.level;if(B.metadata){let x=n(B.metadata);if(x)$.metadata=x}if(Object.keys($).length===0)return;return T($,M1)}function _1(B){if(!B)return;let $={};if(B.level)$.level=B.level;if(B.sensor)$.sensor=B.sensor;if(B.launchUrl)$.launchUrl=B.launchUrl;if(B.metadata){let x=n(B.metadata);if(x)$.metadata=x}if(Object.keys($).length===0)return;return T($,S1)}function T9(B){if(!B)return;let $={};if(B.staging){let x=_1(B.staging);if(x)$.staging=x}if(B.production){let x=_1(B.production);if(x)$.production=x}if(Object.keys($).length===0)return;return T($,j1)}function y9(B){let $={subject:B.subject};if(B.grade!==void 0)$.grade=B.grade;if(B.courseCode)$.courseCode=B.courseCode;if(B.level)$.level=B.level;if(B.sensor)$.sensor=B.sensor;if(B.launchUrl)$.launchUrl=B.launchUrl;let x=w9(B.ids);if(x)$.ids=x;let X=n(B.metadata);if(X)$.metadata=X;let Q=T9(B.overrides);if(Q)$.overrides=Q;return T($,K1)}function m(B){let $={$schema:G1,name:B.name};if(B.launchUrl)$.launchUrl=B.launchUrl;if(B.sensor)$.sensor=B.sensor;let x=P9(B.defaults);if(x)$.defaults=x;$.courses=B.courses.map(y9);let X=T($,V1);return JSON.stringify(X,null,z1)+`
8
+ `}function g9(B){if(!B.every((X)=>X.launchUrl!==void 0))return;let x=new Set(B.map((X)=>X.launchUrl).filter(Boolean));return x.size===1?[...x][0]:void 0}function E9(B){if(!B.courses.every((W)=>W.launchUrl!==void 0))return B;let x=B.courses.map((W)=>W.launchUrl);if(new Set(x).size!==1)return B;let Q=x[0];if(B.launchUrl&&B.launchUrl!==Q)return B;return{...B,launchUrl:Q,courses:B.courses.map((W)=>{if(W.launchUrl===Q){let{launchUrl:b,...H}=W;return H}return W})}}import{writeFile as Ub}from"node:fs/promises";import{stdout as k9}from"node:process";var C1=k9.isTTY??!1;var l4=[10251,10265,10297,10296,10300,10292,10278,10279,10247,10255].map((B)=>String.fromCodePoint(B));import{join as w1}from"node:path";var b3=[w1(".timeback","bin"),w1(".local","bin"),"/usr/local/bin/timeback","/opt/homebrew/bin/timeback"];import{existsSync as h9}from"node:fs";import{resolve as f9}from"node:path";function o(B){let $=[{pm:"bun",file:"bun.lockb"},{pm:"bun",file:"bun.lock"},{pm:"pnpm",file:"pnpm-lock.yaml"},{pm:"yarn",file:"yarn.lock"},{pm:"npm",file:"package-lock.json"}];for(let{pm:x,file:X}of $)if(h9(f9(B,X)))return{packageManager:x,reason:"lockfile",lockfile:X};return{packageManager:"npm",reason:"default"}}function s(B,$){switch(B){case"bun":return{cmd:"bunx",args:[$]};case"pnpm":return{cmd:"pnpm",args:["dlx",$]};case"yarn":return{cmd:"yarn",args:["dlx",$]};case"npm":default:return{cmd:"npx",args:["--yes",$]}}}import{spawn as Gb}from"node:child_process";import{existsSync as zb}from"node:fs";import{resolve as Vb}from"node:path";var F=B1(t(),1);import{stdin as a9,stdout as u9}from"node:process";import*as C from"node:readline";function i9({onlyFirst:B=!1}={}){let $=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");return new RegExp($,B?void 0:"g")}var H3=i9();function v1(B){return B&&B.__esModule&&Object.prototype.hasOwnProperty.call(B,"default")?B.default:B}var h1={exports:{}};(function(B){var $={};B.exports=$,$.eastAsianWidth=function(X){var Q=X.charCodeAt(0),W=X.length==2?X.charCodeAt(1):0,b=Q;return 55296<=Q&&Q<=56319&&56320<=W&&W<=57343&&(Q&=1023,W&=1023,b=Q<<10|W,b+=65536),b==12288||65281<=b&&b<=65376||65504<=b&&b<=65510?"F":b==8361||65377<=b&&b<=65470||65474<=b&&b<=65479||65482<=b&&b<=65487||65490<=b&&b<=65495||65498<=b&&b<=65500||65512<=b&&b<=65518?"H":4352<=b&&b<=4447||4515<=b&&b<=4519||4602<=b&&b<=4607||9001<=b&&b<=9002||11904<=b&&b<=11929||11931<=b&&b<=12019||12032<=b&&b<=12245||12272<=b&&b<=12283||12289<=b&&b<=12350||12353<=b&&b<=12438||12441<=b&&b<=12543||12549<=b&&b<=12589||12593<=b&&b<=12686||12688<=b&&b<=12730||12736<=b&&b<=12771||12784<=b&&b<=12830||12832<=b&&b<=12871||12880<=b&&b<=13054||13056<=b&&b<=19903||19968<=b&&b<=42124||42128<=b&&b<=42182||43360<=b&&b<=43388||44032<=b&&b<=55203||55216<=b&&b<=55238||55243<=b&&b<=55291||63744<=b&&b<=64255||65040<=b&&b<=65049||65072<=b&&b<=65106||65108<=b&&b<=65126||65128<=b&&b<=65131||110592<=b&&b<=110593||127488<=b&&b<=127490||127504<=b&&b<=127546||127552<=b&&b<=127560||127568<=b&&b<=127569||131072<=b&&b<=194367||177984<=b&&b<=196605||196608<=b&&b<=262141?"W":32<=b&&b<=126||162<=b&&b<=163||165<=b&&b<=166||b==172||b==175||10214<=b&&b<=10221||10629<=b&&b<=10630?"Na":b==161||b==164||167<=b&&b<=168||b==170||173<=b&&b<=174||176<=b&&b<=180||182<=b&&b<=186||188<=b&&b<=191||b==198||b==208||215<=b&&b<=216||222<=b&&b<=225||b==230||232<=b&&b<=234||236<=b&&b<=237||b==240||242<=b&&b<=243||247<=b&&b<=250||b==252||b==254||b==257||b==273||b==275||b==283||294<=b&&b<=295||b==299||305<=b&&b<=307||b==312||319<=b&&b<=322||b==324||328<=b&&b<=331||b==333||338<=b&&b<=339||358<=b&&b<=359||b==363||b==462||b==464||b==466||b==468||b==470||b==472||b==474||b==476||b==593||b==609||b==708||b==711||713<=b&&b<=715||b==717||b==720||728<=b&&b<=731||b==733||b==735||768<=b&&b<=879||913<=b&&b<=929||931<=b&&b<=937||945<=b&&b<=961||963<=b&&b<=969||b==1025||1040<=b&&b<=1103||b==1105||b==8208||8211<=b&&b<=8214||8216<=b&&b<=8217||8220<=b&&b<=8221||8224<=b&&b<=8226||8228<=b&&b<=8231||b==8240||8242<=b&&b<=8243||b==8245||b==8251||b==8254||b==8308||b==8319||8321<=b&&b<=8324||b==8364||b==8451||b==8453||b==8457||b==8467||b==8470||8481<=b&&b<=8482||b==8486||b==8491||8531<=b&&b<=8532||8539<=b&&b<=8542||8544<=b&&b<=8555||8560<=b&&b<=8569||b==8585||8592<=b&&b<=8601||8632<=b&&b<=8633||b==8658||b==8660||b==8679||b==8704||8706<=b&&b<=8707||8711<=b&&b<=8712||b==8715||b==8719||b==8721||b==8725||b==8730||8733<=b&&b<=8736||b==8739||b==8741||8743<=b&&b<=8748||b==8750||8756<=b&&b<=8759||8764<=b&&b<=8765||b==8776||b==8780||b==8786||8800<=b&&b<=8801||8804<=b&&b<=8807||8810<=b&&b<=8811||8814<=b&&b<=8815||8834<=b&&b<=8835||8838<=b&&b<=8839||b==8853||b==8857||b==8869||b==8895||b==8978||9312<=b&&b<=9449||9451<=b&&b<=9547||9552<=b&&b<=9587||9600<=b&&b<=9615||9618<=b&&b<=9621||9632<=b&&b<=9633||9635<=b&&b<=9641||9650<=b&&b<=9651||9654<=b&&b<=9655||9660<=b&&b<=9661||9664<=b&&b<=9665||9670<=b&&b<=9672||b==9675||9678<=b&&b<=9681||9698<=b&&b<=9701||b==9711||9733<=b&&b<=9734||b==9737||9742<=b&&b<=9743||9748<=b&&b<=9749||b==9756||b==9758||b==9792||b==9794||9824<=b&&b<=9825||9827<=b&&b<=9829||9831<=b&&b<=9834||9836<=b&&b<=9837||b==9839||9886<=b&&b<=9887||9918<=b&&b<=9919||9924<=b&&b<=9933||9935<=b&&b<=9953||b==9955||9960<=b&&b<=9983||b==10045||b==10071||10102<=b&&b<=10111||11093<=b&&b<=11097||12872<=b&&b<=12879||57344<=b&&b<=63743||65024<=b&&b<=65039||b==65533||127232<=b&&b<=127242||127248<=b&&b<=127277||127280<=b&&b<=127337||127344<=b&&b<=127386||917760<=b&&b<=917999||983040<=b&&b<=1048573||1048576<=b&&b<=1114109?"A":"N"},$.characterLength=function(X){var Q=this.eastAsianWidth(X);return Q=="F"||Q=="W"||Q=="A"?2:1};function x(X){return X.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g)||[]}$.length=function(X){for(var Q=x(X),W=0,b=0;b<Q.length;b++)W=W+this.characterLength(Q[b]);return W},$.slice=function(X,Q,W){textLen=$.length(X),Q=Q||0,W=W||1,Q<0&&(Q=textLen+Q),W<0&&(W=textLen+W);for(var b="",H=0,G=x(X),U=0;U<G.length;U++){var z=G[U],J=$.length(z);if(H>=Q-(J==2?1:0))if(H+J<=W)b+=z;else break;H+=J}return b}})(h1);var n9=h1.exports,Y3=v1(n9),o9=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g},Z3=v1(o9);var b1=10,k1=(B=0)=>($)=>`\x1B[${$+B}m`,m1=(B=0)=>($)=>`\x1B[${38+B};5;${$}m`,F1=(B=0)=>($,x,X)=>`\x1B[${38+B};2;${$};${x};${X}m`,Y={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};Object.keys(Y.modifier);var s9=Object.keys(Y.color),r9=Object.keys(Y.bgColor);[...s9,...r9];function t9(){let B=new Map;for(let[$,x]of Object.entries(Y)){for(let[X,Q]of Object.entries(x))Y[X]={open:`\x1B[${Q[0]}m`,close:`\x1B[${Q[1]}m`},x[X]=Y[X],B.set(Q[0],Q[1]);Object.defineProperty(Y,$,{value:x,enumerable:!1})}return Object.defineProperty(Y,"codes",{value:B,enumerable:!1}),Y.color.close="\x1B[39m",Y.bgColor.close="\x1B[49m",Y.color.ansi=k1(),Y.color.ansi256=m1(),Y.color.ansi16m=F1(),Y.bgColor.ansi=k1(b1),Y.bgColor.ansi256=m1(b1),Y.bgColor.ansi16m=F1(b1),Object.defineProperties(Y,{rgbToAnsi256:{value:($,x,X)=>$===x&&x===X?$<8?16:$>248?231:Math.round(($-8)/247*24)+232:16+36*Math.round($/255*5)+6*Math.round(x/255*5)+Math.round(X/255*5),enumerable:!1},hexToRgb:{value:($)=>{let x=/[a-f\d]{6}|[a-f\d]{3}/i.exec($.toString(16));if(!x)return[0,0,0];let[X]=x;X.length===3&&(X=[...X].map((W)=>W+W).join(""));let Q=Number.parseInt(X,16);return[Q>>16&255,Q>>8&255,Q&255]},enumerable:!1},hexToAnsi256:{value:($)=>Y.rgbToAnsi256(...Y.hexToRgb($)),enumerable:!1},ansi256ToAnsi:{value:($)=>{if($<8)return 30+$;if($<16)return 90+($-8);let x,X,Q;if($>=232)x=(($-232)*10+8)/255,X=x,Q=x;else{$-=16;let H=$%36;x=Math.floor($/36)/5,X=Math.floor(H/6)/5,Q=H%6/5}let W=Math.max(x,X,Q)*2;if(W===0)return 30;let b=30+(Math.round(Q)<<2|Math.round(X)<<1|Math.round(x));return W===2&&(b+=60),b},enumerable:!1},rgbToAnsi:{value:($,x,X)=>Y.ansi256ToAnsi(Y.rgbToAnsi256($,x,X)),enumerable:!1},hexToAnsi:{value:($)=>Y.ansi256ToAnsi(Y.hexToAnsi256($)),enumerable:!1}}),Y}var J3=t9();var e9="]";var G3=`${e9}8;;`;var bb=["up","down","left","right","space","enter","cancel"],Bb={actions:new Set(bb),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]])};function f1(B,$){if(typeof B=="string")return Bb.aliases.get(B)===$;for(let x of B)if(x!==void 0&&f1(x,$))return!0;return!1}var $b=globalThis.process.platform.startsWith("win"),z3=Symbol("clack:cancel");function p1({input:B=a9,output:$=u9,overwrite:x=!0,hideCursor:X=!0}={}){let Q=C.createInterface({input:B,output:$,prompt:"",tabSize:1});C.emitKeypressEvents(B,Q),B.isTTY&&B.setRawMode(!0);let W=(b,{name:H,sequence:G})=>{let U=String(b);if(f1([U,H,G],"cancel")){X&&$.write(F.cursor.show),process.exit(0);return}if(!x)return;C.moveCursor($,H==="return"?0:-1,H==="return"?-1:0,()=>{C.clearLine($,1,()=>{B.once("keypress",W)})})};return X&&$.write(F.cursor.hide),B.once("keypress",W),()=>{B.off("keypress",W),X&&$.write(F.cursor.show),B.isTTY&&!$b&&B.setRawMode(!1),Q.terminal=!1,Q.close()}}var xb;xb=new WeakMap;var K=B1(E1(),1),d=B1(t(),1);import S from"node:process";function Qb(){return S.platform!=="win32"?S.env.TERM!=="linux":!!S.env.CI||!!S.env.WT_SESSION||!!S.env.TERMINUS_SUBLIME||S.env.ConEmuTask==="{cmd::Cmder}"||S.env.TERM_PROGRAM==="Terminus-Sublime"||S.env.TERM_PROGRAM==="vscode"||S.env.TERM==="xterm-256color"||S.env.TERM==="alacritty"||S.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var $1=Qb(),Z=(B,$)=>$1?B:$,A3=Z("◆","*"),Wb=Z("■","x"),qb=Z("▲","x"),l1=Z("◇","o"),C3=Z("┌","T"),v=Z("│","|"),N3=Z("└","—"),w3=Z("●",">"),P3=Z("○"," "),T3=Z("◻","[•]"),y3=Z("◼","[+]"),g3=Z("◻","[ ]"),E3=Z("▪","•"),k3=Z("─","-"),m3=Z("╮","+"),F3=Z("├","+"),v3=Z("╯","+"),Hb=Z("●","•"),Yb=Z("◆","*"),Zb=Z("▲","!"),Jb=Z("■","x");var _={message:(B="",{symbol:$=K.default.gray(v)}={})=>{let x=[`${K.default.gray(v)}`];if(B){let[X,...Q]=B.split(`
9
+ `);x.push(`${$} ${X}`,...Q.map((W)=>`${K.default.gray(v)} ${W}`))}process.stdout.write(`${x.join(`
10
+ `)}
11
+ `)},info:(B)=>{_.message(B,{symbol:K.default.blue(Hb)})},success:(B)=>{_.message(B,{symbol:K.default.green(Yb)})},step:(B)=>{_.message(B,{symbol:K.default.green(l1)})},warn:(B)=>{_.message(B,{symbol:K.default.yellow(Zb)})},warning:(B)=>{_.warn(B)},error:(B)=>{_.message(B,{symbol:K.default.red(Jb)})}},h3=`${K.default.gray(v)} `;var d1=({indicator:B="dots"}={})=>{let $=$1?["◒","◐","◓","◑"]:["•","o","O","0"],x=$1?80:120,X=process.env.CI==="true",Q,W,b=!1,H="",G,U=performance.now(),z=(V)=>{let M=V>1?"Something went wrong":"Canceled";b&&Q1(M,V)},J=()=>z(2),j=()=>z(1),I=()=>{process.on("uncaughtExceptionMonitor",J),process.on("unhandledRejection",J),process.on("SIGINT",j),process.on("SIGTERM",j),process.on("exit",z)},u1=()=>{process.removeListener("uncaughtExceptionMonitor",J),process.removeListener("unhandledRejection",J),process.removeListener("SIGINT",j),process.removeListener("SIGTERM",j),process.removeListener("exit",z)},x1=()=>{if(G===void 0)return;X&&process.stdout.write(`
12
+ `);let V=G.split(`
13
+ `);process.stdout.write(d.cursor.move(-999,V.length-1)),process.stdout.write(d.erase.down(V.length))},D=(V)=>V.replace(/\.+$/,""),X1=(V)=>{let M=(performance.now()-V)/1000,L=Math.floor(M/60),y=Math.floor(M%60);return L>0?`[${L}m ${y}s]`:`[${y}s]`},i1=(V="")=>{b=!0,Q=p1(),H=D(V),U=performance.now(),process.stdout.write(`${K.default.gray(v)}
14
+ `);let M=0,L=0;I(),W=setInterval(()=>{if(X&&H===G)return;x1(),G=H;let y=K.default.magenta($[M]);if(X)process.stdout.write(`${y} ${H}...`);else if(B==="timer")process.stdout.write(`${y} ${H} ${X1(U)}`);else{let n1=".".repeat(Math.floor(L)).slice(0,3);process.stdout.write(`${y} ${H}${n1}`)}M=M+1<$.length?M+1:0,L=L<$.length?L+0.125:0},x)},Q1=(V="",M=0)=>{b=!1,clearInterval(W),x1();let L=M===0?K.default.green(l1):M===1?K.default.red(Wb):K.default.red(qb);H=D(V??H),B==="timer"?process.stdout.write(`${L} ${H} ${X1(U)}
15
+ `):process.stdout.write(`${L} ${H}
16
+ `),u1(),Q()};return{start:i1,stop:Q1,message:(V="")=>{H=D(V??H)}}};function D1(B,$,x,X=!1){return new Promise((Q)=>{let W=Gb(B,$,{cwd:x,stdio:X?"ignore":"inherit",shell:process.platform==="win32"});W.on("close",(b)=>Q(b??1)),W.on("error",()=>Q(1))})}function Kb(B){return Vb(B,"node_modules",".bin",process.platform==="win32"?"prettier.cmd":"prettier")}function Ob(B,$){let{packageManager:x}=o(B),X=s(x,"prettier");return D1(X.cmd,[...X.args,...$],B,!0)}async function h(B){let{cwd:$,filePath:x,silent:X=!1,label:Q="file"}=B,W=Kb($),b=["--write",x],H=X?null:d1();H?.start(`Formatting ${Q}...`);try{let G;if(zb(W))G=await D1(W,b,$,!0);else G=await Ob($,b);if(G===0)return H?.stop(`Formatted ${Q}`),!0;if(H?.stop(),!X)_.warn(`Failed to format ${Q}`);return!1}catch{if(H?.stop(),!X)_.warn(`Failed to format ${Q}`);return!1}}async function Mb(B,$,x={}){let{format:X=!1,cwd:Q=process.cwd(),silent:W=!0}=x,b=m($);if(await Ub(B,b,"utf-8"),X)await h({cwd:Q,filePath:B,silent:W})}import{readFile as jb,writeFile as Sb}from"node:fs/promises";async function Ib(B,$,x={}){let{format:X=!1,cwd:Q=process.cwd(),silent:W=!0}=x;try{let b=await jb(B,"utf8"),H=JSON.parse(b);if(!H||typeof H!=="object"||Array.isArray(H))return{success:!1,error:"Config file is not a JSON object."};let{$schema:G,...U}=H,z=P.safeParse(U);if(!z.success)return{success:!1,error:"Config file is invalid; cannot update."};let J={...z.data,...Object.fromEntries(Object.entries($).filter(([,I])=>I!==void 0))},j=P.safeParse(J);if(!j.success)return{success:!1,error:"Update would make config invalid; refusing to write."};if(await Sb(B,m(j.data),"utf8"),X)await h({cwd:Q,filePath:B,silent:W});return{success:!0,config:j.data}}catch(b){return{success:!1,error:b instanceof Error?b.message:"Unknown error"}}}function Lb(B,$){let x={subject:B.subjects?.[0]??"None",grade:B.grades?.[0]??0,ids:{[$]:B.sourcedId}};if(B.courseCode)x.courseCode=B.courseCode;if(B.level)x.level=B.level;if(B.metadata){let X={};if(B.metadata.courseType)X.courseType=B.metadata.courseType;if(B.metadata.isSupplemental!==void 0)X.isSupplemental=B.metadata.isSupplemental;if(B.metadata.isCustom!==void 0)X.isCustom=B.metadata.isCustom;if(B.metadata.publishStatus)X.publishStatus=B.metadata.publishStatus;if(B.metadata.contactEmail)X.contactEmail=B.metadata.contactEmail;if(B.metadata.primaryApp)X.primaryApp=B.metadata.primaryApp;if(B.metadata.goals)X.goals=B.metadata.goals;if(B.metadata.metrics)X.metrics=B.metadata.metrics;if(Object.keys(X).length>0)x.metadata=X}return x}async function Rb(B,$){try{let X=await B.oneroster.courses($).components({where:{status:"active"}}),Q=[];for(let J of X){if(!J.sourcedId)continue;let j=await B.oneroster.courses.componentResources({where:{"courseComponent.sourcedId":J.sourcedId,status:"active"}});for(let I of j)if(I.resource?.sourcedId)Q.push(I.resource.sourcedId)}if(Q.length===0)return;let W=[...new Set(Q)],b=c1(W),H=await Promise.allSettled(b.map((J)=>B.oneroster.resources.listAll({where:{sourcedId:{in:J}}})));if(H.some((J)=>J.status==="rejected"))return;let U=a1(H),z=new Set;for(let J of U){let I=J.metadata?.launchUrl;if(typeof I==="string"&&I.length>0)z.add(I)}if(z.size===1)return[...z][0];return}catch{return}}function _b(B){if(!B.ids)return[];return Object.keys(B.ids).filter(($)=>B.ids?.[$]).map(($)=>({env:$,courseId:B.ids[$]}))}function kB(B={}){return B.playcademy?c:i}export{Ib as updateTimebackConfigFile,Lb as toCourseConfig,i as timebackParser,Mb as saveTimebackConfigFile,c as playcademyParser,E9 as normalizeLaunchUrls,j9 as loadConfig,Rb as inferLaunchUrl,_b as getSyncedCourses,S9 as getRelativeConfigPath,kB as getParser,g9 as getCommonLaunchUrl,m as generateConfigContent};
@@ -0,0 +1,2 @@
1
+ import{createHash as B}from"node:crypto";function F(q){return{course:q,component:`${q}-component`,resource:`${q}-resource`,componentResource:`${q}-cr`}}function G(q){return B("sha256").update(q).digest("hex")}function J(q){if(q==="local"||q==="staging")return"staging";return"production"}function K(q){if(q==="production"||q==="local"||q==="staging")return q;return"staging"}function L(q,w=200,z){let A=new Headers(z);return A.set("Content-Type","application/json"),new Response(JSON.stringify(q),{status:w,headers:A})}function M(q,w){let z=new Headers(w);return z.set("Location",q),new Response(null,{status:302,headers:z})}function N(q){let w=JSON.stringify(q);return btoa(w).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function O(q){let w=q.replace(/-/g,"+").replace(/_/g,"/"),z=atob(w);return JSON.parse(z)}var Q={ACTIVITY:"/activity",IDENTITY:{SIGNIN:"/identity/signin",SIGNOUT:"/identity/signout",CALLBACK:"/identity/callback"},USER:{ME:"/user/me",VERIFY:"/user/verify"}},S=0.999999;
2
+ export{Q as C,S as D,F as E,G as F,J as G,K as H,L as I,M as J,N as K,O as L};
@@ -0,0 +1 @@
1
+ import{z as H}from"zod/v4";import{z as _}from"zod/v4";var jZ=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/,x=_.string().min(1).regex(jZ,"must be a valid ISO 8601 datetime"),b=_.string().min(1).regex(/^\d{4}-\d{2}-\d{2}$/,"must be a valid ISO 8601 date (YYYY-MM-DD)"),L=_.enum(["Reading","Language","Vocabulary","Social Studies","Writing","Science","FastMath","Math","None","Other"]).meta({id:"TimebackSubject",description:"Subject area"}),F=_.union([_.literal(-1),_.literal(0),_.literal(1),_.literal(2),_.literal(3),_.literal(4),_.literal(5),_.literal(6),_.literal(7),_.literal(8),_.literal(9),_.literal(10),_.literal(11),_.literal(12),_.literal(13)]).meta({id:"TimebackGrade",description:"Grade level (-1 = Pre-K, 0 = K, 1-12 = grades, 13 = AP)"}),l=_.enum(["exempt","fully graded","not submitted","partially graded","submitted"]),T=_.enum(["department","school","district","local","state","national"]),C=_.enum(["administrator","aide","guardian","parent","proctor","relative","student","teacher"]),R=_.enum(["administrator","proctor","student","teacher"]),u=_.enum(["qti","text","audio","video","interactive","visual","course-material","assessment-bank"]),d=_.enum(["qti-test","qti-question","qti-stimulus","qti-test-bank"]),N=_.enum(["unit","course","resource-collection"]),c=_.enum(["choice","order","associate","match","hotspot","hottext","select-point","graphic-order","graphic-associate","graphic-gap-match","text-entry","extended-text","inline-choice","upload","slider","drawing","media","custom"]),p=_.enum(["easy","medium","hard"]),E=_.array(_.object({source:_.string(),learningObjectiveIds:_.array(_.string())})),y=_.object({consecutive_failures:_.number().int().min(1).optional(),stagnation_limit:_.number().int().min(1).optional()}).optional(),Wq=_.enum(["powerpath-100","quiz","test-out","placement","unit-test","alpha-read-article"]).nullable(),Xq=_.object({imsx_codeMajor:_.enum(["failure","success"]),imsx_severity:_.enum(["error","warning","status"]),imsx_description:_.string(),imsx_CodeMinor:_.object({imsx_codeMinorField:_.array(_.object({imsx_codeMinorFieldName:_.string(),imsx_codeMinorFieldValue:_.string()}))}).optional()});var PZ=H.object({staging:H.string().meta({description:"Course ID in staging environment"}).optional(),production:H.string().meta({description:"Course ID in production environment"}).optional()}).meta({id:"CourseIds",description:"Environment-specific course IDs (populated by sync)"}),GZ=H.enum(["base","hole-filling","optional"]).meta({id:"CourseType",description:"Course classification type"}),BZ=H.enum(["draft","testing","published","deactivated"]).meta({id:"PublishStatus",description:"Course publication status"}),AZ=H.object({dailyXp:H.number().int().positive().meta({description:"Target XP to earn per day"}).optional(),dailyLessons:H.number().int().positive().meta({description:"Target lessons to complete per day"}).optional(),dailyActiveMinutes:H.number().int().positive().meta({description:"Target active learning minutes per day"}).optional(),dailyAccuracy:H.number().int().min(0).max(100).meta({description:"Target accuracy percentage (0-100)"}).optional(),dailyMasteredUnits:H.number().int().positive().meta({description:"Target units to master per day"}).optional()}).meta({id:"CourseGoals",description:"Daily learning goals for a course"}),hZ=H.object({totalXp:H.number().int().positive().meta({description:"Total XP available in the course"}).optional(),totalLessons:H.number().int().positive().meta({description:"Total number of lessons/activities"}).optional(),totalGrades:H.number().int().positive().meta({description:"Total grade levels covered"}).optional()}).meta({id:"CourseMetrics",description:"Aggregate metrics for a course"}),g=H.object({courseType:GZ.optional(),isSupplemental:H.boolean().meta({description:"Whether this is supplemental to a base course"}).optional(),isCustom:H.boolean().meta({description:"Whether this is a custom course for an individual student"}).optional(),publishStatus:BZ.optional(),contactEmail:H.email().meta({description:"Contact email for course issues"}).optional(),primaryApp:H.string().meta({description:"Primary application identifier"}).optional(),goals:AZ.optional(),metrics:hZ.optional()}).meta({id:"CourseMetadata",description:"Course metadata (matches API metadata object)"}),m=H.object({courseCode:H.string().meta({description:"Course code (e.g., 'MATH101')"}).optional(),level:H.string().meta({description:"Course level (e.g., 'AP', 'Honors')"}).optional(),metadata:g.optional()}).meta({id:"CourseDefaults",description:"Default properties that apply to all courses unless overridden"}),s=H.object({level:H.string().meta({description:"Course level for this environment"}).optional(),sensor:H.url().meta({description:"Caliper sensor endpoint URL for this environment"}).optional(),launchUrl:H.url().meta({description:"LTI launch URL for this environment"}).optional(),metadata:g.optional()}).meta({id:"CourseEnvOverrides",description:"Environment-specific course overrides (non-identity fields)"}),OZ=H.object({staging:s.meta({description:"Overrides for staging environment"}).optional(),production:s.meta({description:"Overrides for production environment"}).optional()}).meta({id:"CourseOverrides",description:"Per-environment course overrides"}),vZ=m.extend({subject:L.meta({description:"Subject area for this course"}),grade:F.meta({description:"Grade level (-1 = Pre-K, 0 = K, 1-12 = grades, 13 = AP)"}).optional(),ids:PZ.nullable().optional(),sensor:H.url().meta({description:"Caliper sensor endpoint URL for this course"}).optional(),launchUrl:H.url().meta({description:"LTI launch URL for this course"}).optional(),overrides:OZ.optional()}).meta({id:"CourseConfig",description:"Configuration for a single course. Must have either grade or courseCode (or both)."}),Hq=H.object({$schema:H.string().meta({description:"JSON Schema reference for editor support"}).optional(),name:H.string().min(1,"App name is required").meta({description:"Display name for your app"}),defaults:m.meta({description:"Default properties applied to all courses"}).optional(),courses:H.array(vZ).min(1,"At least one course is required").meta({description:"Courses available in this app"}),sensor:H.url().meta({description:"Default Caliper sensor endpoint URL for all courses"}).optional(),launchUrl:H.url().meta({description:"Default LTI launch URL for all courses"}).optional()}).meta({id:"TimebackConfig",title:"Timeback Config",description:"Configuration schema for timeback.config.json files"}).refine((U)=>{return U.courses.every((j)=>j.grade!==void 0||j.courseCode!==void 0)},{message:"Each course must have either a grade or a courseCode",path:["courses"]}).refine((U)=>{let v=U.courses.filter((h)=>h.grade!==void 0).map((h)=>`${h.subject}:${h.grade}`);return new Set(v).size===v.length},{message:"Duplicate (subject, grade) pair found; each must be unique",path:["courses"]}).refine((U)=>{let v=U.courses.filter((h)=>h.courseCode!==void 0).map((h)=>h.courseCode);return new Set(v).size===v.length},{message:"Duplicate courseCode found; each must be unique",path:["courses"]}).refine((U)=>{return U.courses.every((j)=>{if(j.sensor!==void 0||U.sensor!==void 0)return!0;return[j.launchUrl,U.launchUrl,j.overrides?.staging?.launchUrl,j.overrides?.production?.launchUrl].filter(Boolean).length>0})},{message:"Each course must have an effective sensor. Either set `sensor` explicitly (top-level or per-course), or provide a `launchUrl` so sensor can be derived from its origin.",path:["courses"]});import{z as K}from"zod/v4";var k=K.object({id:K.string(),type:K.literal("TimebackUser"),email:K.string()}),D=K.object({id:K.string(),type:K.literal("TimebackActivityContext"),subject:L,app:K.object({name:K.string()}),activity:K.object({id:K.string().optional(),name:K.string()}).strict().optional(),course:K.object({id:K.string().optional(),name:K.string()}).strict().optional(),process:K.boolean().optional()}),S=K.object({"@context":K.literal("http://purl.imsglobal.org/ctx/caliper/v1p2"),id:K.string(),type:K.string(),eventTime:x,profile:K.literal("TimebackProfile"),actor:k,action:K.string(),object:D,edApp:K.object({id:K.string(),name:K.string().optional()}).optional()}),o=K.object({type:K.enum(["totalQuestions","correctQuestions","xpEarned","masteredUnits"]),value:K.number()}),IZ=K.object({id:K.string(),type:K.literal("TimebackActivityMetricsCollection"),attempt:K.number().optional(),items:K.array(o),extensions:K.record(K.string(),K.unknown()).optional()}),CZ=S.extend({type:K.literal("ActivityEvent"),action:K.literal("Completed"),generated:IZ}),r=K.object({type:K.enum(["active","inactive","waste","unknown","anti-pattern"]),value:K.number(),subType:K.string().optional()}),kZ=K.object({id:K.string(),type:K.literal("TimebackTimeSpentMetricsCollection"),items:K.array(r)}),DZ=S.extend({type:K.literal("TimeSpentEvent"),action:K.literal("SpentTime"),generated:kZ}),Fq=K.object({actor:k,object:D,metrics:K.array(o).min(1,"metrics must contain at least one metric"),eventTime:x.optional(),metricsId:K.string().optional(),id:K.string().optional(),extensions:K.record(K.string(),K.unknown()).optional(),attempt:K.number().int().min(1).optional(),generatedExtensions:K.object({pctCompleteApp:K.number().optional()}).loose().optional()}).strict(),Lq=K.object({actor:k,object:D,metrics:K.array(r).min(1,"metrics must contain at least one metric"),eventTime:x.optional(),metricsId:K.string().optional(),id:K.string().optional(),extensions:K.record(K.string(),K.unknown()).optional()}).strict(),QZ=K.union([CZ,DZ]),Uq=K.object({sensor:K.string(),sendTime:x,dataVersion:K.literal("http://purl.imsglobal.org/ctx/caliper/v1p2"),data:K.array(QZ)}),MZ=K.enum(["AnnotationProfile","AssessmentProfile","ToolUseProfile","GeneralProfile","FeedbackProfile","MediaProfile","SurveyProfile","ResourceManagementProfile","ForumProfile","AssignableProfile","GradingProfile","ReadingProfile","SessionProfile","SearchProfile","ToolLaunchProfile","TimebackProfile"]),B=K.union([K.string(),K.record(K.string(),K.unknown())]),fZ=K.object({id:K.string(),type:K.string(),extensions:K.object({email:K.email()}).loose()}).strict(),a=K.object({"@context":K.string().optional(),id:K.string(),type:K.string(),actor:K.union([K.string(),fZ,k]),action:K.string(),object:B,eventTime:x,profile:MZ,edApp:B.optional(),generated:B.optional(),target:B.optional(),referrer:B.optional(),group:B.optional(),membership:B.optional(),session:B.optional(),federatedSession:B.optional(),extensions:K.record(K.string(),K.unknown()).optional()}).strict(),jq=K.object({sensor:K.string().min(1,"sensor must be a non-empty string"),sendTime:x,dataVersion:K.literal("http://purl.imsglobal.org/ctx/caliper/v1p2"),data:K.array(a).min(1,"data must contain at least one event")}),Pq=K.object({sensor:K.string().min(1,"sensor must be a non-empty string"),events:K.array(a).min(1,"events must contain at least one event")}),Gq=K.object({limit:K.number().int().positive().optional(),offset:K.number().int().min(0).optional(),sensor:K.string().min(1).optional(),startDate:x.optional(),endDate:x.optional(),actorId:K.string().min(1).optional(),actorEmail:K.email().optional()}).strict();import{z as Y}from"zod/v4";var G=x,Oq=Y.object({id:Y.string(),role:Y.string(),beginDate:G.nullable(),endDate:G.nullable(),metadata:Y.object({goals:Y.object({dailyXp:Y.number().optional()}).optional(),metrics:Y.object({totalXp:Y.number().optional(),totalLessons:Y.number().optional()}).optional()}).optional(),course:Y.object({id:Y.string(),title:Y.string(),subjects:Y.array(Y.string()).nullable(),grades:Y.array(Y.string()).nullable()}),school:Y.object({id:Y.string(),name:Y.string()})}),bZ=Y.object({activityMetrics:Y.object({xpEarned:Y.number(),totalQuestions:Y.number(),correctQuestions:Y.number(),masteredUnits:Y.number()}),timeSpentMetrics:Y.object({activeSeconds:Y.number(),inactiveSeconds:Y.number(),wasteSeconds:Y.number()}),apps:Y.array(Y.string())}),lZ=Y.record(Y.string(),Y.record(Y.string(),bZ)),vq=Y.object({message:Y.string(),enrollmentId:Y.string(),startDate:G,endDate:G,facts:lZ,factsByApp:Y.unknown()}),A=Y.string().trim().min(1),i=Y.object({email:Y.email().optional(),studentId:A.optional()}).superRefine((U,j)=>{if(!U.email&&!U.studentId)j.addIssue({code:Y.ZodIssueCode.custom,message:"must provide either email or studentId",path:["email"]}),j.addIssue({code:Y.ZodIssueCode.custom,message:"must provide either email or studentId",path:["studentId"]})}),Iq=Y.object({subject:A,grade:A,courseId:A,orgSourcedId:A.optional()});var Cq=Y.object({userId:A}),kq=Y.object({sourcedId:A.optional(),role:R.optional(),beginDate:G.optional(),metadata:Y.record(Y.string(),Y.unknown()).optional()}),Dq=Y.object({fields:Y.string().optional(),limit:Y.number().int().positive().optional(),offset:Y.number().int().nonnegative().optional(),sort:Y.string().optional(),orderBy:Y.enum(["asc","desc"]).optional(),filter:Y.string().optional(),search:Y.string().optional(),roles:Y.array(C).min(1),orgSourcedIds:Y.array(A).optional()}),Qq=i.extend({startDate:G,endDate:G,timezone:Y.string().optional()}),Mq=i.extend({weekDate:G,timezone:Y.string().optional()}),fq=Y.object({enrollmentId:A,startDate:G.optional(),endDate:G.optional(),timezone:Y.string().optional()});import{z as q}from"zod/v4";var X=q.string().min(1),V=q.enum(["active","tobedeleted"]),w=q.record(q.string(),q.unknown()).nullable().optional(),$=q.object({sourcedId:X,type:q.string().optional(),href:q.string().optional()}).strict(),P=q.union([b,x]),TZ=q.object({roleType:q.enum(["primary","secondary"]),role:C,org:$,userProfile:q.string().optional(),metadata:w,beginDate:P.optional(),endDate:P.optional()}).strict(),Rq=q.object({sourcedId:X.describe("sourcedId must be a non-empty string"),status:V.optional(),enabledUser:q.boolean(),givenName:X.describe("givenName must be a non-empty string"),familyName:X.describe("familyName must be a non-empty string"),middleName:X.optional(),username:X.optional(),email:q.email().optional(),roles:q.array(TZ).min(1,"roles must include at least one role"),userIds:q.array(q.object({type:X,identifier:X}).strict()).optional(),agents:q.array($).optional(),grades:q.array(F).optional(),identifier:X.optional(),sms:X.optional(),phone:X.optional(),pronouns:X.optional(),password:X.optional(),metadata:w}).strict(),uq=q.object({sourcedId:X.describe("sourcedId must be a non-empty string").optional(),status:V.optional(),title:X.describe("title must be a non-empty string"),org:$,courseCode:X.optional(),subjects:q.array(L).optional(),grades:q.array(F).optional(),level:X.optional(),metadata:w}).strict(),dq=q.object({sourcedId:X.describe("sourcedId must be a non-empty string").optional(),status:V.optional(),title:X.describe("title must be a non-empty string"),terms:q.array($).min(1,"terms must have at least one item"),course:$,org:$,classCode:X.optional(),classType:q.enum(["homeroom","scheduled"]).optional(),location:X.optional(),grades:q.array(F).optional(),subjects:q.array(L).optional(),subjectCodes:q.array(X).optional(),periods:q.array(X).optional(),metadata:w}).strict(),n=q.enum(["true","false"]),Nq=q.object({sourcedId:X.describe("sourcedId must be a non-empty string").optional(),status:V.optional(),user:$,class:$,school:$.optional(),role:C,primary:n.optional(),beginDate:P.optional(),endDate:P.optional(),metadata:w}).strict(),cq=q.object({sourcedId:X.optional(),title:X.describe("title must be a non-empty string"),status:V,weight:q.number().nullable().optional(),metadata:w}).strict(),pq=q.object({sourcedId:X.optional(),title:X.describe("title must be a non-empty string"),class:$,school:$,category:$,assignDate:P,dueDate:P,status:V,description:q.string().optional(),resultValueMin:q.number().nullable().optional(),resultValueMax:q.number().nullable().optional(),scoreScale:$.optional(),metadata:w}).strict(),Eq=q.object({sourcedId:X.optional(),lineItem:$,student:$,class:$.optional(),scoreDate:P,scoreStatus:q.enum(["exempt","fully graded","not submitted","partially graded","submitted"]),score:q.number().nullable().optional(),textScore:q.string().nullable().optional(),status:V,comment:q.string().nullable().optional(),metadata:w}).strict(),yq=q.object({sourcedId:X.optional(),title:X.describe("title must be a non-empty string"),status:V.optional(),type:q.string().optional(),class:$.optional(),course:$.nullable().optional(),scoreScaleValue:q.array(q.object({itemValueLHS:X,itemValueRHS:X,value:q.string().optional(),description:q.string().optional()}).strict()).optional(),minScore:q.number().optional(),maxScore:q.number().optional(),metadata:w}).strict(),sq=q.object({sourcedId:X.optional(),status:V.optional(),dateLastModified:x.optional(),title:X.describe("title must be a non-empty string"),description:q.string().nullable().optional(),class:$.nullable().optional(),parentAssessmentLineItem:$.nullable().optional(),scoreScale:$.nullable().optional(),resultValueMin:q.number().nullable().optional(),resultValueMax:q.number().nullable().optional(),component:$.nullable().optional(),componentResource:$.nullable().optional(),learningObjectiveSet:q.array(q.object({source:q.string(),learningObjectiveIds:q.array(q.string())})).optional().nullable(),course:$.nullable().optional(),metadata:w}).strict(),RZ=q.object({learningObjectiveId:q.string(),score:q.number().optional(),textScore:q.string().optional()}),uZ=q.array(q.object({source:q.string(),learningObjectiveResults:q.array(RZ)})),gq=q.object({sourcedId:X.optional(),status:V.optional(),dateLastModified:x.optional(),metadata:w,assessmentLineItem:$,student:$,score:q.number().nullable().optional(),textScore:q.string().nullable().optional(),scoreDate:q.string().datetime(),scoreScale:$.nullable().optional(),scorePercentile:q.number().nullable().optional(),scoreStatus:q.enum(["exempt","fully graded","not submitted","partially graded","submitted"]),comment:q.string().nullable().optional(),learningObjectiveSet:uZ.nullable().optional(),inProgress:q.string().nullable().optional(),incomplete:q.string().nullable().optional(),late:q.string().nullable().optional(),missing:q.string().nullable().optional()}).strict(),mq=q.object({sourcedId:X.optional(),status:V.optional(),name:X.describe("name must be a non-empty string"),type:T,identifier:X.optional(),parent:$.optional(),metadata:w}).strict(),Sq=q.object({sourcedId:X.optional(),status:V.optional(),name:X.describe("name must be a non-empty string"),type:q.literal("school").optional(),identifier:X.optional(),parent:$.optional(),metadata:w}).strict(),oq=q.object({sourcedId:X.describe("sourcedId must be a non-empty string"),status:V,title:X.describe("title must be a non-empty string"),startDate:P,endDate:P,type:q.enum(["gradingPeriod","semester","schoolYear","term"]),schoolYear:X.describe("schoolYear must be a non-empty string"),org:$,parent:$.optional(),children:q.array($).optional(),metadata:w}).strict(),rq=q.object({sourcedId:X.optional(),title:X.describe("title must be a non-empty string"),courseComponent:$,resource:$,status:V,metadata:w}).strict(),aq=q.object({sourcedId:X.optional(),title:X.describe("title must be a non-empty string"),course:$,status:V,metadata:w}).strict(),iq=q.object({sourcedId:X.describe("sourcedId must be a non-empty string"),role:q.enum(["student","teacher"]),primary:n.optional(),beginDate:P.optional(),endDate:P.optional(),metadata:w}).strict(),nq=q.object({agentSourcedId:X.describe("agentSourcedId must be a non-empty string")}).strict(),eq=q.object({type:X.describe("type must be a non-empty string"),username:X.describe("username must be a non-empty string"),password:q.string().optional(),metadata:w}).strict(),zq=q.object({sourcedId:X.describe("sourcedId must be a non-empty string")}).loose(),O=q.object({type:u,subject:L.nullish(),grades:q.array(F).nullish(),language:q.string().nullish(),xp:q.number().nullish(),url:q.url().nullish(),keywords:q.array(q.string()).nullish(),learningObjectiveSet:E.nullish(),lessonType:q.string().nullish()}).passthrough(),dZ=O.extend({type:q.literal("qti"),subType:d,questionType:c.optional(),difficulty:p.optional()}),NZ=O.extend({type:q.literal("text"),format:q.string(),author:q.string().optional(),pageCount:q.number().optional()}),cZ=O.extend({type:q.literal("audio"),duration:q.string().regex(/^\d{2}:\d{2}:\d{2}(\.\d{2})?$/).optional(),format:q.string(),speaker:q.string().optional()}),pZ=O.extend({type:q.literal("video"),duration:q.string().regex(/^\d{2}:\d{2}:\d{2}(\.\d{2})?$/).optional(),captionsAvailable:q.boolean().optional(),format:q.string()}),EZ=O.extend({type:q.literal("interactive"),launchUrl:q.url().optional(),toolProvider:q.string().optional(),instructionalMethod:q.string().optional(),courseIdOnFail:q.string().nullable().optional(),fail_fast:y}),yZ=O.extend({type:q.literal("visual"),format:q.string(),resolution:q.string().optional()}),sZ=O.extend({type:q.literal("course-material"),subType:N,author:q.string().optional(),format:q.string(),instructionalMethod:q.string().optional()}),gZ=O.extend({type:q.literal("assessment-bank"),resources:q.array(q.string())}),mZ=q.discriminatedUnion("type",[dZ,NZ,cZ,pZ,EZ,yZ,sZ,gZ]),tq=q.object({sourcedId:X.optional(),title:X.describe("title must be a non-empty string"),vendorResourceId:X.describe("vendorResourceId must be a non-empty string"),roles:q.array(q.enum(["primary","secondary"])).optional(),importance:q.enum(["primary","secondary"]).optional(),vendorId:q.string().optional(),applicationId:q.string().optional(),status:V.optional(),metadata:mZ.nullable().optional()}).strict(),SZ=q.object({url:X.describe("courseStructure.url must be a non-empty string"),skillCode:X.describe("courseStructure.skillCode must be a non-empty string"),lessonCode:X.describe("courseStructure.lessonCode must be a non-empty string"),title:X.describe("courseStructure.title must be a non-empty string"),"unit-title":X.describe("courseStructure.unit-title must be a non-empty string"),status:X.describe("courseStructure.status must be a non-empty string"),xp:q.number()}).loose(),ZJ=q.object({course:q.object({sourcedId:X.describe("course.sourcedId must be a non-empty string").optional(),title:X.describe("course.title must be a non-empty string"),org:$,status:V,metadata:w}).strict(),courseStructure:q.record(q.string(),SZ)}).strict(),oZ=q.object({student:$}).loose(),qJ=q.array(oZ).min(1,"results must have at least one item");import{z as J}from"zod/v4";var W=J.string().trim().min(1),rZ=J.enum(["edulastic","mastery-track"]),aZ=J.enum(["powerpath-100","quiz","test-out","placement","unit-test","alpha-read-article"]),z=J.array(F),t=J.record(J.string(),J.unknown()).optional(),ZZ=J.object({courseId:W,lessonTitle:W.optional(),launchUrl:J.url().optional(),toolProvider:rZ,unitTitle:W.optional(),courseComponentSourcedId:W.optional(),vendorId:W.optional(),description:W.optional(),resourceMetadata:t.nullable().optional(),grades:z}),XJ=ZZ.extend({lessonType:J.literal("test-out"),xp:J.number()}),YJ=ZZ.extend({lessonType:J.literal("placement"),courseIdOnFail:W.optional(),xp:J.number().optional()});var e=J.object({courseId:W,lessonType:aZ,lessonTitle:W.optional(),unitTitle:W.optional(),courseComponentSourcedId:W.optional(),resourceMetadata:t.nullable().optional(),xp:J.number().optional(),grades:z.optional(),courseIdOnFail:W.optional()}),_J=J.union([e.extend({testType:J.literal("qti"),qti:J.object({url:J.url(),title:W.optional(),metadata:J.record(J.string(),J.unknown()).optional()})}),e.extend({testType:J.literal("assessment-bank"),assessmentBank:J.object({resources:J.array(J.object({url:J.url(),title:W.optional(),metadata:J.record(J.string(),J.unknown()).optional()}))})})]),$J=J.object({student:W,lesson:W}),HJ=J.object({student:W,lesson:W}),wJ=J.object({courseId:W,userId:W,classId:W.optional()}),I=J.object({type:J.enum(["component","resource"]),id:W}),iZ=J.union([J.object({type:J.literal("set-skipped"),payload:J.object({target:I,value:J.boolean()})}),J.object({type:J.literal("add-custom-resource"),payload:J.object({resource_id:W,parent_component_id:W,skipped:J.boolean().optional()})}),J.object({type:J.literal("move-item-before"),payload:J.object({target:I,reference_id:W})}),J.object({type:J.literal("move-item-after"),payload:J.object({target:I,reference_id:W})}),J.object({type:J.literal("move-item-to-start"),payload:J.object({target:I})}),J.object({type:J.literal("move-item-to-end"),payload:J.object({target:I})}),J.object({type:J.literal("change-item-parent"),payload:J.object({target:I,new_parent_id:W,position:J.enum(["start","end"]).optional()})})]),VJ=J.object({operation:J.array(iZ),reason:W.optional()}),xJ=J.object({studentId:W,componentResourceId:W,result:J.object({status:J.enum(["active","tobedeleted"]),metadata:J.record(J.string(),J.unknown()).optional(),score:J.number().optional(),textScore:W.optional(),scoreDate:W,scorePercentile:J.number().optional(),scoreStatus:l,comment:W.optional(),learningObjectiveSet:J.array(J.object({source:W,learningObjectiveResults:J.array(J.object({learningObjectiveId:W,score:J.number().optional(),textScore:W.optional()}))})).optional(),inProgress:W.optional(),incomplete:W.optional(),late:W.optional(),missing:W.optional()})}),FJ=J.object({student:W,lesson:W,applicationName:W.optional(),testId:W.optional(),skipCourseEnrollment:J.boolean().optional()}),LJ=J.object({student:W,subject:L}),UJ=J.object({student:W,lesson:W}),jJ=J.object({userId:W}),PJ=J.object({userId:W,subject:J.enum(["Math","Reading","Language","Science"])}),GJ=J.object({student:W,subject:L,grade:F,testName:W.optional()}),BJ=J.object({testName:W}),nZ=J.object({student:W,subject:L,grade:F,testName:W.optional()}),AJ=J.object({items:J.array(nZ)}),hJ=J.object({spreadsheetUrl:J.url(),sheet:W}),OJ=J.object({student:W,status:J.enum(["assigned","in_progress","completed","failed","expired","cancelled"]).optional(),subject:W.optional(),grade:F.optional(),limit:J.number().int().positive().max(3000).optional(),offset:J.number().int().nonnegative().optional()}),vJ=J.object({student:W.optional(),status:J.enum(["assigned","in_progress","completed","failed","expired","cancelled"]).optional(),subject:W.optional(),grade:F.optional(),limit:J.number().int().positive().max(3000).optional(),offset:J.number().int().nonnegative().optional()}),IJ=J.object({student:W,question:W,response:J.union([W,J.array(W)]).optional(),responses:J.record(J.string(),J.union([W,J.array(W)])).optional(),lesson:W}),CJ=J.object({student:W,lesson:W,attempt:J.number().int().positive().optional()}),kJ=J.object({student:W,lesson:W}),DJ=J.object({student:W,lesson:W}),QJ=J.object({student:W,lesson:W.optional(),finalized:J.boolean().optional(),toolProvider:W.optional(),attempt:J.number().int().positive().optional()}),MJ=J.object({student:W,lesson:W,applicationName:W.optional()}),fJ=J.object({student:W,subject:L}),bJ=J.object({status:J.enum(["active","tobedeleted"]).optional()});import{z as Z}from"zod/v4";var JZ=Z.enum(["choice","text-entry","extended-text","inline-choice","match","order","associate","select-point","graphic-order","graphic-associate","graphic-gap-match","hotspot","hottext","slider","drawing","media","upload"]),Q=Z.enum(["single","multiple","ordered","record"]),M=Z.enum(["identifier","boolean","integer","float","string","point","pair","directedPair","duration","file","uri"]),eZ=Z.enum(["easy","medium","hard"]),zZ=Z.enum(["linear","nonlinear"]),tZ=Z.enum(["individual","simultaneous"]),f=Z.enum(["show","hide"]),KZ=Z.enum(["test","item","stimulus"]),uJ=Z.enum(["QUESTION","LESSON"]),Zq=Z.object({value:Z.array(Z.string())}).strict(),WZ=Z.object({identifier:Z.string().min(1),cardinality:Q,baseType:M.optional(),correctResponse:Zq}).strict(),XZ=Z.object({identifier:Z.string().min(1),cardinality:Q,baseType:M.optional()}).strict(),YZ=Z.object({identifier:Z.string().min(1),cardinality:Q.optional(),baseType:M,normalMaximum:Z.number().optional(),normalMinimum:Z.number().optional(),defaultValue:Z.object({value:Z.unknown().optional()}).strict().optional()}).strict(),qq=Z.object({outcomeIdentifier:Z.string().min(1),variableIdentifier:Z.string().min(1)}).strict(),_Z=Z.object({templateType:Z.enum(["match_correct","map_response"]),responseDeclarationIdentifier:Z.string().min(1),outcomeIdentifier:Z.string().min(1),correctResponseIdentifier:Z.string().min(1),incorrectResponseIdentifier:Z.string().min(1),inlineFeedback:qq.optional()}).strict(),Jq=Z.object({source:Z.string().min(1),learningObjectiveIds:Z.array(Z.string())}).strict(),$Z=Z.object({subject:Z.string().optional(),grade:F.optional(),difficulty:eZ.optional(),learningObjectiveSet:Z.array(Jq).optional()}).strict(),HZ=Z.object({outcomeIdentifier:Z.string().min(1),identifier:Z.string().min(1),showHide:f,content:Z.string(),title:Z.string()}).strict(),wZ=Z.object({outcomeIdentifier:Z.string().min(1),identifier:Z.string().min(1),showHide:f,content:Z.string(),class:Z.array(Z.string())}).strict(),VZ=Z.object({outcomeIdentifier:Z.string().min(1),identifier:Z.string().min(1),showHide:f,content:Z.string(),class:Z.array(Z.string())}).strict(),xZ=Z.object({href:Z.string().min(1),type:Z.string().min(1)}).strict(),FZ=Z.object({id:Z.string().min(1),support:Z.string(),content:Z.string()}).strict(),dJ=Z.object({page:Z.number().int().positive().optional(),limit:Z.number().int().positive().optional(),sort:Z.string().optional(),order:Z.enum(["asc","desc"]).optional()}).strict(),NJ=Z.object({identifier:Z.string().min(1),title:Z.string().min(1),type:JZ,qtiVersion:Z.string().optional(),timeDependent:Z.boolean().optional(),adaptive:Z.boolean().optional(),responseDeclarations:Z.array(WZ).optional(),outcomeDeclarations:Z.array(XZ).optional(),responseProcessing:_Z.optional(),metadata:$Z.optional(),modalFeedback:Z.array(HZ).optional(),feedbackInline:Z.array(wZ).optional(),feedbackBlock:Z.array(VZ).optional()}).strict(),cJ=Z.object({identifier:Z.string().min(1).optional(),title:Z.string().min(1),type:JZ,qtiVersion:Z.string().optional(),timeDependent:Z.boolean().optional(),adaptive:Z.boolean().optional(),responseDeclarations:Z.array(WZ).optional(),outcomeDeclarations:Z.array(XZ).optional(),responseProcessing:_Z.optional(),metadata:$Z.optional(),modalFeedback:Z.array(HZ).optional(),feedbackInline:Z.array(wZ).optional(),feedbackBlock:Z.array(VZ).optional(),rawXml:Z.string(),content:Z.record(Z.string(),Z.unknown())}).strict(),pJ=Z.object({response:Z.union([Z.string(),Z.array(Z.string())])}).strict(),LZ=Z.object({identifier:Z.string().min(1),href:Z.union([Z.string(),Z.array(Z.string()),Z.array(Z.array(Z.string()))]).optional(),sequence:Z.number().optional()}).strict(),qZ=Z.object({identifier:Z.string().min(1),title:Z.string().min(1),visible:Z.boolean(),required:Z.boolean().optional(),fixed:Z.boolean().optional(),sequence:Z.number().optional(),"qti-assessment-item-ref":Z.array(LZ).optional()}).strict(),UZ=Z.object({identifier:Z.string().min(1),navigationMode:zZ,submissionMode:tZ,"qti-assessment-section":Z.union([qZ,Z.array(qZ)])}).strict(),EJ=Z.object({items:Z.array(LZ).min(1)}).strict(),yJ=Z.object({metadata:Z.record(Z.string(),Z.unknown()).optional()}).strict(),sJ=Z.object({identifier:Z.string().min(1),title:Z.string().min(1),qtiVersion:Z.string().optional(),toolName:Z.string().optional(),toolVersion:Z.string().optional(),timeLimit:Z.number().optional(),maxAttempts:Z.number().optional(),toolsEnabled:Z.record(Z.string(),Z.boolean()).optional(),metadata:Z.record(Z.string(),Z.unknown()).optional(),"qti-test-part":UZ,"qti-outcome-declaration":Z.array(YZ).optional()}).strict(),gJ=Z.object({identifier:Z.string().min(1).optional(),title:Z.string().min(1),qtiVersion:Z.string().optional(),toolName:Z.string().optional(),toolVersion:Z.string().optional(),timeLimit:Z.number().optional(),maxAttempts:Z.number().optional(),toolsEnabled:Z.record(Z.string(),Z.boolean()).optional(),metadata:Z.record(Z.string(),Z.unknown()).optional(),"qti-test-part":UZ,"qti-outcome-declaration":Z.array(YZ).optional()}).strict(),mJ=Z.object({identifier:Z.string().min(1),title:Z.string().min(1),label:Z.string().optional(),language:Z.string().optional(),stylesheet:xZ.optional(),content:Z.string(),catalogInfo:Z.array(FZ).optional(),toolName:Z.string().optional(),toolVersion:Z.string().optional(),metadata:Z.record(Z.string(),Z.unknown()).optional()}).strict(),SJ=Z.object({identifier:Z.string().min(1).optional(),title:Z.string().min(1),label:Z.string().optional(),language:Z.string().optional(),stylesheet:xZ.optional(),content:Z.string(),catalogInfo:Z.array(FZ).optional(),toolName:Z.string().optional(),toolVersion:Z.string().optional(),metadata:Z.record(Z.string(),Z.unknown()).optional()}).strict(),oJ=Z.object({xml:Z.string().optional(),schema:KZ,entityId:Z.string().optional()}).strict(),rJ=Z.object({xml:Z.array(Z.string()),schema:KZ,entityIds:Z.array(Z.string())}).strict(),aJ=Z.object({questionId:Z.string().optional(),userId:Z.string().min(1),feedback:Z.string().min(1),lessonId:Z.string().min(1),humanApproved:Z.boolean().optional()}).strict();export{L as a,F as b,Hq as c};
@@ -0,0 +1,11 @@
1
+ var V=Object.create;var{getPrototypeOf:W,defineProperty:a,getOwnPropertyNames:A,getOwnPropertyDescriptor:q}=Object,F=Object.prototype.hasOwnProperty;var de=(e,t,n)=>{n=e!=null?V(W(e)):{};let r=t||!e||!e.__esModule?a(n,"default",{value:e,enumerable:!0}):n;for(let o of A(e))if(!F.call(r,o))a(r,o,{get:()=>e[o],enumerable:!0});return r},$=new WeakMap,be=(e)=>{var t=$.get(e),n;if(t)return t;if(t=a({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")A(e).map((r)=>!F.call(t,r)&&a(t,r,{get:()=>e[r],enumerable:!(n=q(e,r))||n.enumerable}));return $.set(e,t),t},he=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var K=(e,t)=>{for(var n in t)a(e,n,{get:t[n],enumerable:!0,configurable:!0,set:(r)=>t[n]=()=>r})};var Q=(e,t)=>()=>(e&&(t=e(e=0)),t);var ge=((e)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var ae={};K(ae,{types:()=>oe,promisify:()=>U,log:()=>J,isUndefined:()=>p,isSymbol:()=>se,isString:()=>j,isRegExp:()=>d,isPrimitive:()=>ce,isObject:()=>y,isNumber:()=>H,isNullOrUndefined:()=>fe,isNull:()=>O,isFunction:()=>h,isError:()=>b,isDate:()=>E,isBuffer:()=>ue,isBoolean:()=>C,isArray:()=>R,inspect:()=>l,inherits:()=>_,format:()=>D,deprecate:()=>Y,default:()=>ye,debuglog:()=>v,callbackifyOnRejected:()=>N,callbackify:()=>M,_extend:()=>k,TextEncoder:()=>G,TextDecoder:()=>Z});function D(e,...t){if(!j(e)){var n=[e];for(var r=0;r<t.length;r++)n.push(l(t[r]));return n.join(" ")}var r=0,o=t.length,f=String(e).replace(X,function(s){if(s==="%%")return"%";if(r>=o)return s;switch(s){case"%s":return String(t[r++]);case"%d":return Number(t[r++]);case"%j":try{return JSON.stringify(t[r++])}catch(c){return"[Circular]"}default:return s}});for(var i=t[r];r<o;i=t[++r])if(O(i)||!y(i))f+=" "+i;else f+=" "+l(i);return f}function Y(e,t){if(typeof process>"u"||process?.noDeprecation===!0)return e;var n=!1;function r(...o){if(!n){if(process.throwDeprecation)throw Error(t);else if(process.traceDeprecation)console.trace(t);else console.error(t);n=!0}return e.apply(this,...o)}return r}function x(e,t){var n=l.styles[t];if(n)return"\x1B["+l.colors[n][0]+"m"+e+"\x1B["+l.colors[n][1]+"m";else return e}function ee(e,t){return e}function te(e){var t={};return e.forEach(function(n,r){t[n]=!0}),t}function g(e,t,n){if(e.customInspect&&t&&h(t.inspect)&&t.inspect!==l&&!(t.constructor&&t.constructor.prototype===t)){var r=t.inspect(n,e);if(!j(r))r=g(e,r,n);return r}var o=re(e,t);if(o)return o;var f=Object.keys(t),i=te(f);if(e.showHidden)f=Object.getOwnPropertyNames(t);if(b(t)&&(f.indexOf("message")>=0||f.indexOf("description")>=0))return w(t);if(f.length===0){if(h(t)){var s=t.name?": "+t.name:"";return e.stylize("[Function"+s+"]","special")}if(d(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(E(t))return e.stylize(Date.prototype.toString.call(t),"date");if(b(t))return w(t)}var c="",u=!1,m=["{","}"];if(R(t))u=!0,m=["[","]"];if(h(t)){var I=t.name?": "+t.name:"";c=" [Function"+I+"]"}if(d(t))c=" "+RegExp.prototype.toString.call(t);if(E(t))c=" "+Date.prototype.toUTCString.call(t);if(b(t))c=" "+w(t);if(f.length===0&&(!u||t.length==0))return m[0]+c+m[1];if(n<0)if(d(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");else return e.stylize("[Object]","special");e.seen.push(t);var S;if(u)S=ne(e,t,n,i,f);else S=f.map(function(L){return z(e,t,n,i,L,u)});return e.seen.pop(),ie(S,c,m)}function re(e,t){if(p(t))return e.stylize("undefined","undefined");if(j(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(H(t))return e.stylize(""+t,"number");if(C(t))return e.stylize(""+t,"boolean");if(O(t))return e.stylize("null","null")}function w(e){return"["+Error.prototype.toString.call(e)+"]"}function ne(e,t,n,r,o){var f=[];for(var i=0,s=t.length;i<s;++i)if(B(t,String(i)))f.push(z(e,t,n,r,String(i),!0));else f.push("");return o.forEach(function(c){if(!c.match(/^\d+$/))f.push(z(e,t,n,r,c,!0))}),f}function z(e,t,n,r,o,f){var i,s,c;if(c=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]},c.get)if(c.set)s=e.stylize("[Getter/Setter]","special");else s=e.stylize("[Getter]","special");else if(c.set)s=e.stylize("[Setter]","special");if(!B(r,o))i="["+o+"]";if(!s)if(e.seen.indexOf(c.value)<0){if(O(n))s=g(e,c.value,null);else s=g(e,c.value,n-1);if(s.indexOf(`
2
+ `)>-1)if(f)s=s.split(`
3
+ `).map(function(u){return" "+u}).join(`
4
+ `).slice(2);else s=`
5
+ `+s.split(`
6
+ `).map(function(u){return" "+u}).join(`
7
+ `)}else s=e.stylize("[Circular]","special");if(p(i)){if(f&&o.match(/^\d+$/))return s;if(i=JSON.stringify(""+o),i.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/))i=i.slice(1,-1),i=e.stylize(i,"name");else i=i.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),i=e.stylize(i,"string")}return i+": "+s}function ie(e,t,n){var r=0,o=e.reduce(function(f,i){if(r++,i.indexOf(`
8
+ `)>=0)r++;return f+i.replace(/\u001b\[\d\d?m/g,"").length+1},0);if(o>60)return n[0]+(t===""?"":t+`
9
+ `)+" "+e.join(`,
10
+ `)+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}function R(e){return Array.isArray(e)}function C(e){return typeof e==="boolean"}function O(e){return e===null}function fe(e){return e==null}function H(e){return typeof e==="number"}function j(e){return typeof e==="string"}function se(e){return typeof e==="symbol"}function p(e){return e===void 0}function d(e){return y(e)&&T(e)==="[object RegExp]"}function y(e){return typeof e==="object"&&e!==null}function E(e){return y(e)&&T(e)==="[object Date]"}function b(e){return y(e)&&(T(e)==="[object Error]"||e instanceof Error)}function h(e){return typeof e==="function"}function ce(e){return e===null||typeof e==="boolean"||typeof e==="number"||typeof e==="string"||typeof e==="symbol"||typeof e>"u"}function ue(e){return e instanceof Buffer}function T(e){return Object.prototype.toString.call(e)}function P(e){return e<10?"0"+e.toString(10):e.toString(10)}function pe(){var e=new Date,t=[P(e.getHours()),P(e.getMinutes()),P(e.getSeconds())].join(":");return[e.getDate(),le[e.getMonth()],t].join(" ")}function J(...e){console.log("%s - %s",pe(),D.apply(null,e))}function _(e,t){if(t)e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}function k(e,t){if(!t||!y(t))return e;var n=Object.keys(t),r=n.length;while(r--)e[n[r]]=t[n[r]];return e}function B(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function N(e,t){if(!e){var n=Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}function M(e){if(typeof e!=="function")throw TypeError('The "original" argument must be of type Function');function t(...n){var r=n.pop();if(typeof r!=="function")throw TypeError("The last argument must be of type Function");var o=this,f=function(...i){return r.apply(o,...i)};e.apply(this,n).then(function(i){process.nextTick(f.bind(null,null,i))},function(i){process.nextTick(N.bind(null,i,f))})}return Object.setPrototypeOf(t,Object.getPrototypeOf(e)),Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)),t}var X,v,l,oe=()=>{},le,U,G,Z,ye;var me=Q(()=>{X=/%[sdj%]/g;v=((e={},t={},n)=>((n=typeof process<"u"&&!1)&&(n=n.replace(/[|\\{}()[\]^$+?.]/g,"\\$&").replace(/\*/g,".*").replace(/,/g,"$|^").toUpperCase()),t=new RegExp("^"+n+"$","i"),(r)=>{if(r=r.toUpperCase(),!e[r])if(t.test(r))e[r]=function(...o){console.error("%s: %s",r,pid,D.apply(null,...o))};else e[r]=function(){};return e[r]}))(),l=((e)=>(e.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},e.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},e.custom=Symbol.for("nodejs.util.inspect.custom"),e))(function(e,t,...n){var r={seen:[],stylize:ee};if(n.length>=1)r.depth=n[0];if(n.length>=2)r.colors=n[1];if(C(t))r.showHidden=t;else if(t)k(r,t);if(p(r.showHidden))r.showHidden=!1;if(p(r.depth))r.depth=2;if(p(r.colors))r.colors=!1;if(r.colors)r.stylize=x;return g(r,e,r.depth)});le=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];U=((e)=>(e.custom=Symbol.for("nodejs.util.promisify.custom"),e))(function(e){if(typeof e!=="function")throw TypeError('The "original" argument must be of type Function');if(kCustomPromisifiedSymbol&&e[kCustomPromisifiedSymbol]){var t=e[kCustomPromisifiedSymbol];if(typeof t!=="function")throw TypeError('The "nodejs.util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,kCustomPromisifiedSymbol,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(...n){var r,o,f=new Promise(function(i,s){r=i,o=s});n.push(function(i,s){if(i)o(i);else r(s)});try{e.apply(this,n)}catch(i){o(i)}return f}if(Object.setPrototypeOf(t,Object.getPrototypeOf(e)),kCustomPromisifiedSymbol)Object.defineProperty(t,kCustomPromisifiedSymbol,{value:t,enumerable:!1,writable:!1,configurable:!0});return Object.defineProperties(t,Object.getOwnPropertyDescriptors(e))});({TextEncoder:G,TextDecoder:Z}=globalThis),ye={TextEncoder:G,TextDecoder:Z,promisify:U,log:J,inherits:_,_extend:k,callbackifyOnRejected:N,callbackify:M}});me();export{oe as types,U as promisify,J as log,p as isUndefined,se as isSymbol,j as isString,d as isRegExp,ce as isPrimitive,y as isObject,H as isNumber,fe as isNullOrUndefined,O as isNull,h as isFunction,b as isError,E as isDate,ue as isBuffer,C as isBoolean,R as isArray,l as inspect,_ as inherits,D as format,Y as deprecate,ye as default,v as debuglog,N as callbackifyOnRejected,M as callbackify,k as _extend,G as TextEncoder,Z as TextDecoder};
11
+ export{de as d,be as e,he as f,K as g,Q as h,ge as i,ae as j,me as k};
@@ -0,0 +1 @@
1
+ import{t as c,u as N}from"./chunk-9se82640.js";import{C as V,G as f,I as q,J as P,K as E,L as b}from"./chunk-hnf0tart.js";import{M as g,O as m}from"./chunk-07j8zre9.js";var X=null,x=!1,I=!1;function y(z){let F=z.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${F}$`)}function s(){if(X!==null)return;if(X=[],typeof process>"u"||!process.env?.DEBUG){I=!1;return}I=!0;let z=process.env.DEBUG.trim();if(z==="1"||z==="true"||z==="*"){x=!0;return}let K=z.split(",").map((Q)=>Q.trim()).filter(Boolean);for(let Q of K)if(Q.startsWith("-"))X.push({regex:y(Q.slice(1)),exclude:!0});else X.push({regex:y(Q),exclude:!1});if(!X.some((Q)=>!Q.exclude)&&X.length>0)x=!0}function d(z){if(s(),!I)return!0;if(x){if(z){for(let K of X)if(K.exclude&&K.regex.test(z))return!1}return!0}if(!z)return!1;for(let K of X)if(K.exclude&&K.regex.test(z))return!1;for(let K of X)if(!K.exclude&&K.regex.test(z))return!0;return!1}function C(){return typeof globalThis<"u"&&"window"in globalThis}function T(){if(C())return"browser";if(typeof process<"u"&&process.env){if(process.env.CI||process.env.GITHUB_ACTIONS||process.env.GITLAB_CI||process.env.CIRCLECI||process.env.JENKINS_URL||process.env.BUILDKITE)return"ci"}return"terminal"}var h;if(!C())try{h=(await import("node:util")).inspect}catch{}var Y={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",yellow:"\x1B[33m",blue:"\x1B[34m",cyan:"\x1B[36m"};function t(z){switch(z){case"debug":return Y.blue;case"info":return Y.cyan;case"warn":return Y.yellow;case"error":return Y.red}}function r(z){switch(z){case"debug":return console.debug;case"info":return console.info;case"warn":return console.warn;case"error":return console.error}}function e(z){if(h)return h(z,{depth:null,colors:!0,breakLength:80,compact:!1});return JSON.stringify(z,null,2)}var O=(z)=>{let K=t(z.level),F=r(z.level),Q=z.level.toUpperCase().padEnd(5),W=z.timestamp.toISOString().replace(/\.\d{3}Z$/,""),$=`${Y.dim}[${W}]${Y.reset}`,B=`${K}${Q}${Y.reset}`,Z=z.scope?`${Y.bold}[${z.scope}]${Y.reset} `:"",J=`${$} ${B} ${Z}${z.message}`;if(z.context&&Object.keys(z.context).length>0)F(J,e(z.context));else F(J)};var z6={debug:"[DEBUG]",info:"[INFO]",warn:"[WARN]",error:"[ERROR]"};function K6(z){return Object.entries(z).map(([K,F])=>`${K}=${F6(F)}`).join(" ")}function F6(z){if(typeof z==="string")return z;if(typeof z==="number")return String(z);if(typeof z==="boolean")return String(z);if(z===null)return"null";if(z===void 0)return"undefined";return JSON.stringify(z)}var w=(z)=>{let K=[];if(K.push(z.timestamp.toISOString()),K.push(z6[z.level]),z.scope)K.push(`[${z.scope}]`);if(K.push(z.message),z.context&&Object.keys(z.context).length>0)K.push(K6(z.context));console.log(K.join(" "))};var D=(z)=>{let K={timestamp:z.timestamp.toISOString(),level:z.level,...z.scope&&{scope:z.scope},msg:z.message};if(z.context&&Object.keys(z.context).length>0)Object.assign(K,z.context);console.log(JSON.stringify(K))};var Q6={debug:"color: gray",info:"color: #0ea5e9",warn:"color: #f59e0b",error:"color: #ef4444; font-weight: bold"},W6={debug:"log",info:"info",warn:"warn",error:"error"},S=(z)=>{let K=W6[z.level],F=Q6[z.level],W=`%c${z.scope?`[${z.scope}]`:""} ${z.message}`;if(z.context&&Object.keys(z.context).length>0)console[K](W,F,z.context);else console[K](W,F)};var p=["debug","info","warn","error"];function Z6(z){switch(z){case"terminal":return O;case"ci":return w;case"production":return D;case"browser":return S;case"test":return()=>{}}}function $6(){if(typeof process<"u"&&process.env?.DEBUG)return"debug";return"info"}function B6(z,K){return p.indexOf(z)>=p.indexOf(K)}class A{scope;minLevel;environment;formatter;defaultContext;constructor(z={}){this.scope=z.scope,this.minLevel=z.minLevel??$6(),this.defaultContext=z.defaultContext??{},this.environment=z.environment??T(),this.formatter=Z6(this.environment)}child(z){let K=this.scope?`${this.scope}:${z}`:z;return new A({scope:K,minLevel:this.minLevel,environment:this.environment,defaultContext:{...this.defaultContext}})}withContext(z){return new A({scope:this.scope,minLevel:this.minLevel,environment:this.environment,defaultContext:{...this.defaultContext,...z}})}debug(z,K){this.log("debug",z,K)}info(z,K){this.log("info",z,K)}warn(z,K){this.log("warn",z,K)}error(z,K){this.log("error",z,K)}log(z,K,F){if(z==="debug"&&!d(this.scope))return;if(!B6(z,this.minLevel))return;let Q={level:z,message:K,scope:this.scope,context:F||Object.keys(this.defaultContext).length>0?{...this.defaultContext,...F}:void 0,timestamp:new Date};this.formatter(Q)}}function R(z={}){return new A(z)}function H6(){try{let z=typeof process>"u"?void 0:process.env.DEBUG;return z==="1"||z==="true"}catch{return!1}}function _(z){return R({scope:`timeback:${z}`,minLevel:H6()?"debug":"warn"})}var G=_("sso"),j=_("oidc");var u=new Map;async function U(z){let K=u.get(z);if(K)return K;let F=`${z}/.well-known/openid-configuration`,Q=await fetch(F);if(!Q.ok)throw j.error("Discovery fetch failed",{status:Q.status}),Error(`Failed to fetch OIDC discovery: ${Q.statusText}`);let W=await Q.json();return j.debug("Fetched OIDC discovery document",{authEndpoint:W.authorization_endpoint,tokenEndpoint:W.token_endpoint}),u.set(z,W),W}function k(z){switch(z){case"production":return"https://cognito-idp.us-east-1.amazonaws.com/us-east-1_3uhuoRM3R";case"staging":return"https://cognito-idp.us-east-1.amazonaws.com/us-east-1_5EUwTP9XD";case"local":throw Error("Local environment is not yet supported for OIDC")}}async function L(z){let K=await U(z.issuer),F=new URL(K.authorization_endpoint);return F.searchParams.set("response_type","code"),F.searchParams.set("client_id",z.clientId),F.searchParams.set("redirect_uri",z.redirectUri),F.searchParams.set("scope","openid profile email"),F.searchParams.set("state",z.state),F.toString()}async function X6(z){let K=await U(z.issuer),F=await fetch(K.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",client_id:z.clientId,client_secret:z.clientSecret,code:z.code,redirect_uri:z.redirectUri})});if(!F.ok){let W=await F.text();throw j.error("Token exchange failed",{status:F.status,body:W}),Error(`Token exchange failed: ${F.status} ${W}`)}let Q=await F.json();return j.debug("Received tokens from IdP",{expiresIn:Q.expires_in}),Q}async function Y6(z){let K=await U(z.issuer),F=await fetch(K.userinfo_endpoint,{headers:{Authorization:`Bearer ${z.accessToken}`}});if(!F.ok)throw Error(`UserInfo request failed: ${F.statusText}`);return F.json()}import{TimebackClient as J6}from"@timeback/core";var M=_("resolve");class H extends Error{code;constructor(z,K){super(z);this.code=K;this.name="TimebackUserResolutionError"}}function G6(z){return z.code==="timeback_user_ambiguous"?409:404}function M6(z){return{sub:z.sub,email:z.email,firstName:z.given_name,lastName:z.family_name,pictureUrl:z.picture}}async function i(z,K){let Q=(await z.oneroster.users.list({where:{email:K},limit:2})).data;if(Q.length===0)throw M.warn("No Timeback user found for email",{email:N(K)}),new H(`No Timeback user found with email: ${K}`,"timeback_user_not_found");if(Q.length>1)throw M.error("Multiple Timeback users found for email",{email:N(K),count:Q.length}),new H(`Multiple Timeback users found with email: ${K}`,"timeback_user_ambiguous");let W=Q[0];if(!W.sourcedId)throw new H("Timeback user is missing sourcedId","timeback_user_lookup_failed");return W}async function N6(z){let{env:K,apiCredentials:F,userInfo:Q}=z;if(!Q.email)throw M.error("Missing email in IdP user info",{sub:Q.sub}),new H("IdP did not return an email address, which is required to resolve Timeback identity","missing_email");let W=Q.email;M.debug("Resolving Timeback user by email",{email:N(W),env:K});let $=z.client,B=$??new J6({env:f(K),auth:{clientId:F.clientId,clientSecret:F.clientSecret}});try{let Z=await i(B,W);return{...{id:Z.sourcedId,email:Z.email??W,name:c(Z.givenName,Z.familyName),school:Z.primaryOrg?{id:Z.primaryOrg.sourcedId,name:Z.primaryOrg.name??Z.primaryOrg.sourcedId}:void 0,grade:Z.grades?.length?Math.max(...Z.grades):void 0},claims:M6(Q)}}catch(Z){if(Z instanceof H)throw Z;let J=Z instanceof Error?Z.message:"Unknown error";throw M.error("Failed to lookup Timeback user",{email:N(W),error:J}),new H(`Failed to lookup Timeback user: ${J}`,"timeback_user_lookup_failed")}finally{if(!$)B.close()}}async function j6(z){let{email:K,client:F}=z;M.debug("Looking up Timeback user ID by email",{email:N(K)});try{return(await i(F,K)).sourcedId}catch(Q){if(Q instanceof H)throw Q;let W=Q instanceof Error?Q.message:"Unknown error";throw M.error("Failed to lookup Timeback user",{email:N(K),error:W}),new H(`Failed to lookup Timeback user: ${W}`,"timeback_user_lookup_failed")}}function v(z,K,F,Q){return{error:z,errorCode:K,state:F,req:Q,redirect:P,json:q}}function l(z){try{return b(z)}catch{G.warn("Failed to decode state");return}}function A6(z,K,F,Q,W){let $=K.searchParams.get("error_description");G.error("IdP returned error",{error:z,description:$});let B=Error($??z);if(W)return W(v(B,z,F,Q));return q({error:z},400)}function _6(z,K,F){G.error("Missing authorization code in callback");let Q=Error("Missing authorization code");if(F)return F(v(Q,"missing_code",z,K));return q({error:"Missing authorization code"},400)}async function V6(z){let{req:K,env:F,clientId:Q,buildState:W}=z,$=z.issuer??k(F),B=new URL(K.url),Z=z.redirectUri;if(!Z){let o=B.pathname.replace(V.IDENTITY.SIGNIN,"");Z=`${B.origin}${o}${V.IDENTITY.CALLBACK}`}G.debug("SSO sign-in initiated",{env:F,issuer:$,clientId:Q,redirectUri:Z});let J=W?W({req:K,url:B}):{},n=E(J),a=await L({issuer:$,clientId:Q,redirectUri:Z,state:n});return P(a)}function q6(z){let K=new URL(z.url),F=K.searchParams.get("code"),Q=K.searchParams.get("error"),W=K.searchParams.get("state");G.debug("Received callback from IdP",{hasCode:!!F,error:Q});let $=W?l(W):void 0;return{url:K,code:F,errorParam:Q,state:$}}function O6(z,K){if(K)return K;let F=z.pathname.replace(V.IDENTITY.CALLBACK,"");return`${z.origin}${F}${V.IDENTITY.CALLBACK}`}export{_ as e,G as f,k as g,X6 as h,Y6 as i,H as j,G6 as k,N6 as l,j6 as m,v as n,A6 as o,_6 as p,V6 as q,q6 as r,O6 as s};
@@ -1,3 +1,4 @@
1
+ import type { TimebackProfile } from '../../../../shared/types';
1
2
  /**
2
3
  * Verification state for the current user.
3
4
  */
@@ -12,4 +13,83 @@ export type TimebackVerificationState = {
12
13
  status: 'error';
13
14
  message: string;
14
15
  };
16
+ /**
17
+ * Options for useTimebackVerification hook.
18
+ */
19
+ export interface UseTimebackVerificationOptions {
20
+ /**
21
+ * If false, the hook does nothing and stays in loading state.
22
+ *
23
+ * Use this to delay verification until prerequisites are met
24
+ * (e.g., user exists in your database).
25
+ *
26
+ * @default true
27
+ */
28
+ enabled?: boolean;
29
+ /**
30
+ * Number of retry attempts on failure.
31
+ *
32
+ * This helps handle race conditions where the user may not be
33
+ * fully set up in the backend when verification first runs.
34
+ *
35
+ * Set to 0 to disable retries.
36
+ *
37
+ * @default 3
38
+ */
39
+ retryAttempts?: number;
40
+ /**
41
+ * Delay in ms before each retry attempt.
42
+ *
43
+ * Can be a single number (same delay for all retries) or an array
44
+ * of delays for each attempt (e.g., [100, 300, 1000] for exponential backoff).
45
+ *
46
+ * @default [100, 300, 1000]
47
+ */
48
+ retryDelays?: number | readonly number[];
49
+ }
50
+ /**
51
+ * Profile state for the current user.
52
+ */
53
+ export type TimebackProfileState = {
54
+ status: 'idle';
55
+ } | {
56
+ status: 'loading';
57
+ } | {
58
+ status: 'loaded';
59
+ profile: TimebackProfile;
60
+ } | {
61
+ status: 'error';
62
+ message: string;
63
+ };
64
+ /**
65
+ * Options for the useTimebackProfile hook.
66
+ */
67
+ export interface UseTimebackProfileOptions {
68
+ /**
69
+ * If false, the hook does nothing and stays in idle state.
70
+ *
71
+ * @default true
72
+ */
73
+ enabled?: boolean;
74
+ /**
75
+ * If true, automatically fetch the profile once the user is verified.
76
+ * If false, you must call `fetchProfile()` manually.
77
+ *
78
+ * @default false
79
+ */
80
+ auto?: boolean;
81
+ }
82
+ /**
83
+ * Return value of the useTimebackProfile hook.
84
+ */
85
+ export interface UseTimebackProfileResult {
86
+ /** Current profile state */
87
+ state: TimebackProfileState;
88
+ /** Whether the profile can be fetched (user is verified and client is ready) */
89
+ canFetch: boolean;
90
+ /** Manually trigger a profile fetch. No-op if canFetch is false. */
91
+ fetchProfile: () => void;
92
+ /** Force a re-fetch even if already loaded. No-op if canFetch is false. */
93
+ refresh: () => void;
94
+ }
15
95
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/client/adapters/react/hooks/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAClC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/client/adapters/react/hooks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE/D;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAClC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvC;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC9C;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;CACxC;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC7B;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvC;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC,4BAA4B;IAC5B,KAAK,EAAE,oBAAoB,CAAA;IAE3B,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAA;IAEjB,oEAAoE;IACpE,YAAY,EAAE,MAAM,IAAI,CAAA;IAExB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB"}
@@ -0,0 +1,42 @@
1
+ import type { UseTimebackProfileOptions, UseTimebackProfileResult } from './types';
2
+ /**
3
+ * Fetch the current user's Timeback profile.
4
+ *
5
+ * This hook internally uses `useTimebackVerification` to ensure the user
6
+ * is verified before fetching. When `auto: true`, it automatically fetches
7
+ * the profile once verified. Otherwise, call `fetchProfile()` manually.
8
+ *
9
+ * @param options - Hook options
10
+ * @param options.enabled - If false, the hook does nothing and stays in idle state. Defaults to true.
11
+ * @param options.auto - If true, automatically fetch once verified. Defaults to false.
12
+ * @returns Profile state and fetch methods
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * // Manual fetch
17
+ * function ProfileButton() {
18
+ * const { state, canFetch, fetchProfile } = useTimebackProfile()
19
+ *
20
+ * if (state.status === 'loaded') {
21
+ * return <div>XP: {state.profile.xp}</div>
22
+ * }
23
+ *
24
+ * return (
25
+ * <button onClick={fetchProfile} disabled={!canFetch}>
26
+ * {state.status === 'loading' ? 'Loading...' : 'Load Profile'}
27
+ * </button>
28
+ * )
29
+ * }
30
+ *
31
+ * // Auto-fetch
32
+ * function AutoProfile() {
33
+ * const { state } = useTimebackProfile({ auto: true })
34
+ *
35
+ * if (state.status === 'loading') return <div>Loading...</div>
36
+ * if (state.status === 'loaded') return <div>XP: {state.profile.xp}</div>
37
+ * return null
38
+ * }
39
+ * ```
40
+ */
41
+ export declare function useTimebackProfile(options?: UseTimebackProfileOptions): UseTimebackProfileResult;
42
+ //# sourceMappingURL=useTimebackProfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTimebackProfile.d.ts","sourceRoot":"","sources":["../../../../../src/client/adapters/react/hooks/useTimebackProfile.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAEX,yBAAyB,EACzB,wBAAwB,EACxB,MAAM,SAAS,CAAA;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,GAAE,yBAA8B,GACrC,wBAAwB,CAsH1B"}
@@ -1,17 +1,29 @@
1
- import type { TimebackVerificationState } from './types';
1
+ import type { TimebackVerificationState, UseTimebackVerificationOptions } from './types';
2
2
  /**
3
3
  * Verify the current user against Timeback.
4
4
  *
5
5
  * The hook runs automatically once the Timeback client is available, and
6
6
  * provides a `refresh()` method to retry.
7
7
  *
8
+ * By default, the hook retries failed verification attempts with exponential
9
+ * backoff to handle race conditions (e.g., user not yet created in backend).
10
+ *
8
11
  * @param options - Hook options
9
- * @param options.enabled - If false, the hook does nothing and stays in loading state.
10
12
  * @returns Verification state and a refresh method
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * // Default: auto-verify with retry on mount
17
+ * const { state } = useTimebackVerification()
18
+ *
19
+ * // Delay verification until user exists
20
+ * const { state } = useTimebackVerification({ enabled: !!user })
21
+ *
22
+ * // Disable retries
23
+ * const { state } = useTimebackVerification({ retryAttempts: 0 })
24
+ * ```
11
25
  */
12
- export declare function useTimebackVerification(options?: {
13
- enabled?: boolean;
14
- }): {
26
+ export declare function useTimebackVerification(options?: UseTimebackVerificationOptions): {
15
27
  state: TimebackVerificationState;
16
28
  refresh: () => void;
17
29
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useTimebackVerification.d.ts","sourceRoot":"","sources":["../../../../../src/client/adapters/react/hooks/useTimebackVerification.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAsFxD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG;IAC7E,KAAK,EAAE,yBAAyB,CAAA;IAChC,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB,CA6DA"}
1
+ {"version":3,"file":"useTimebackVerification.d.ts","sourceRoot":"","sources":["../../../../../src/client/adapters/react/hooks/useTimebackVerification.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAA;AAqFxF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,8BAAmC,GAAG;IACtF,KAAK,EAAE,yBAAyB,CAAA;IAChC,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB,CAiGA"}
@@ -41,7 +41,8 @@ export { TimebackClient } from '../../timeback-client.class';
41
41
  export { Activity } from '../../lib/activity';
42
42
  export { TimebackProvider, useTimeback } from './provider';
43
43
  export { useTimebackVerification } from './hooks/useTimebackVerification';
44
- export type { TimebackVerificationState } from './hooks/types';
44
+ export { useTimebackProfile } from './hooks/useTimebackProfile';
45
+ export type { TimebackProfileState, TimebackVerificationState, UseTimebackProfileOptions, UseTimebackProfileResult, UseTimebackVerificationOptions, } from './hooks/types';
45
46
  export { SignInButton } from './SignInButton';
46
47
  export type { SignInButtonProps } from './SignInButton';
47
48
  export type { TimebackIdentity, ActivityParams, ActivityMetrics } from '../../../shared/types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAG5D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAG7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,YAAY,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAA;AAG9D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGvD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAG5D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAG7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAC/D,YAAY,EACX,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,8BAA8B,GAC9B,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGvD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA"}