@timeback/sdk 0.1.9 → 0.1.11

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 (163) hide show
  1. package/README.md +10 -8
  2. package/dist/chunk-1cqa51je.js +2 -0
  3. package/dist/chunk-3ew9vn2d.js +2 -0
  4. package/dist/chunk-6b0ppq9d.js +2 -0
  5. package/dist/chunk-92nnwa7t.js +2 -0
  6. package/dist/chunk-bavxzt1k.js +2 -0
  7. package/dist/chunk-c8pw96sp.js +10 -0
  8. package/dist/chunk-edk3nfj7.js +2 -0
  9. package/dist/chunk-g67efaph.js +4 -0
  10. package/dist/chunk-pd91g539.js +1 -0
  11. package/dist/chunk-sgcwg4j6.js +1 -0
  12. package/dist/client/adapters/react/hooks/types.d.ts +2 -29
  13. package/dist/client/adapters/react/hooks/types.d.ts.map +1 -1
  14. package/dist/client/adapters/react/hooks/useTimebackVerification.d.ts.map +1 -1
  15. package/dist/client/adapters/react/index.js +2 -2
  16. package/dist/client/adapters/solid/types.d.ts +2 -29
  17. package/dist/client/adapters/solid/types.d.ts.map +1 -1
  18. package/dist/client/adapters/solid/types.ts +2 -18
  19. package/dist/client/adapters/svelte/stores/client.d.ts.map +1 -1
  20. package/dist/client/adapters/svelte/stores/client.ts +2 -9
  21. package/dist/client/adapters/svelte/stores/profile.d.ts +1 -1
  22. package/dist/client/adapters/svelte/stores/profile.d.ts.map +1 -1
  23. package/dist/client/adapters/svelte/stores/profile.ts +4 -11
  24. package/dist/client/adapters/svelte/stores/verification.d.ts.map +1 -1
  25. package/dist/client/adapters/svelte/stores/verification.ts +1 -10
  26. package/dist/client/adapters/svelte/types.d.ts +1 -29
  27. package/dist/client/adapters/svelte/types.d.ts.map +1 -1
  28. package/dist/client/adapters/vue/provider.d.ts.map +1 -1
  29. package/dist/client/adapters/vue/provider.ts +4 -11
  30. package/dist/client/adapters/vue/types.d.ts +2 -29
  31. package/dist/client/adapters/vue/types.d.ts.map +1 -1
  32. package/dist/client/adapters/vue/types.ts +2 -18
  33. package/dist/client/auth/types.d.ts +1 -1
  34. package/dist/client/index.d.ts +1 -1
  35. package/dist/client/lib/activity/activity.class.d.ts +130 -22
  36. package/dist/client/lib/activity/activity.class.d.ts.map +1 -1
  37. package/dist/client/lib/activity/transport.d.ts +15 -0
  38. package/dist/client/lib/activity/transport.d.ts.map +1 -0
  39. package/dist/client/lib/activity/types.d.ts +53 -0
  40. package/dist/client/lib/activity/types.d.ts.map +1 -0
  41. package/dist/client/lib/utils.d.ts +18 -0
  42. package/dist/client/lib/utils.d.ts.map +1 -1
  43. package/dist/client/lib/utils.ts +109 -0
  44. package/dist/client/namespaces/activity.d.ts +49 -7
  45. package/dist/client/namespaces/activity.d.ts.map +1 -1
  46. package/dist/client/timeback-client.class.d.ts +7 -1
  47. package/dist/client/timeback-client.class.d.ts.map +1 -1
  48. package/dist/client.d.ts +1 -1
  49. package/dist/client.js +1 -1
  50. package/dist/identity.d.ts +2 -5
  51. package/dist/identity.d.ts.map +1 -1
  52. package/dist/identity.js +1 -1
  53. package/dist/index.d.ts +7 -3
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +30 -21
  56. package/dist/server/adapters/express.d.ts.map +1 -1
  57. package/dist/server/adapters/express.js +1 -1
  58. package/dist/server/adapters/native.d.ts.map +1 -1
  59. package/dist/server/adapters/native.js +2 -2
  60. package/dist/server/adapters/nextjs.js +1 -1
  61. package/dist/server/adapters/nuxt.d.ts.map +1 -1
  62. package/dist/server/adapters/nuxt.js +1 -1
  63. package/dist/server/adapters/solid-start.d.ts.map +1 -1
  64. package/dist/server/adapters/solid-start.js +1 -1
  65. package/dist/server/adapters/svelte-kit.d.ts.map +1 -1
  66. package/dist/server/adapters/svelte-kit.js +1 -1
  67. package/dist/server/adapters/tanstack-start.d.ts.map +1 -1
  68. package/dist/server/adapters/tanstack-start.js +1 -1
  69. package/dist/server/adapters/types.d.ts +16 -4
  70. package/dist/server/adapters/types.d.ts.map +1 -1
  71. package/dist/server/adapters/utils.d.ts +1 -1
  72. package/dist/server/adapters/utils.d.ts.map +1 -1
  73. package/dist/server/handlers/activity/attempts.d.ts +1 -1
  74. package/dist/server/handlers/activity/attempts.d.ts.map +1 -1
  75. package/dist/server/handlers/activity/caliper.d.ts +54 -16
  76. package/dist/server/handlers/activity/caliper.d.ts.map +1 -1
  77. package/dist/server/handlers/activity/heartbeat-handler.d.ts +15 -0
  78. package/dist/server/handlers/activity/heartbeat-handler.d.ts.map +1 -0
  79. package/dist/server/handlers/activity/index.d.ts +5 -3
  80. package/dist/server/handlers/activity/index.d.ts.map +1 -1
  81. package/dist/server/handlers/activity/progress.d.ts +2 -2
  82. package/dist/server/handlers/activity/progress.d.ts.map +1 -1
  83. package/dist/server/handlers/activity/schema.d.ts +40 -6
  84. package/dist/server/handlers/activity/schema.d.ts.map +1 -1
  85. package/dist/server/handlers/activity/submit-handler.d.ts +29 -0
  86. package/dist/server/handlers/activity/submit-handler.d.ts.map +1 -0
  87. package/dist/server/handlers/activity/submit.d.ts +44 -0
  88. package/dist/server/handlers/activity/submit.d.ts.map +1 -0
  89. package/dist/server/handlers/activity/types.d.ts +126 -5
  90. package/dist/server/handlers/activity/types.d.ts.map +1 -1
  91. package/dist/server/handlers/identity/handler.d.ts +23 -4
  92. package/dist/server/handlers/identity/handler.d.ts.map +1 -1
  93. package/dist/server/handlers/identity/index.d.ts +2 -2
  94. package/dist/server/handlers/identity/index.d.ts.map +1 -1
  95. package/dist/server/handlers/identity/oidc.d.ts.map +1 -1
  96. package/dist/server/handlers/identity/types.d.ts +0 -6
  97. package/dist/server/handlers/identity/types.d.ts.map +1 -1
  98. package/dist/server/handlers/index.d.ts +3 -3
  99. package/dist/server/handlers/index.d.ts.map +1 -1
  100. package/dist/server/handlers/user/handler.d.ts.map +1 -1
  101. package/dist/server/handlers/user/profile.d.ts.map +1 -1
  102. package/dist/server/handlers/user/types.d.ts +3 -0
  103. package/dist/server/handlers/user/types.d.ts.map +1 -1
  104. package/dist/server/handlers/user/verify.d.ts.map +1 -1
  105. package/dist/server/index.d.ts +1 -1
  106. package/dist/server/index.d.ts.map +1 -1
  107. package/dist/server/lib/hooks.d.ts +20 -0
  108. package/dist/server/lib/hooks.d.ts.map +1 -0
  109. package/dist/server/lib/index.d.ts +4 -2
  110. package/dist/server/lib/index.d.ts.map +1 -1
  111. package/dist/server/lib/logger.d.ts +36 -9
  112. package/dist/server/lib/logger.d.ts.map +1 -1
  113. package/dist/server/lib/resolve.d.ts +1 -1
  114. package/dist/server/lib/resolve.d.ts.map +1 -1
  115. package/dist/server/lib/utils.d.ts +23 -2
  116. package/dist/server/lib/utils.d.ts.map +1 -1
  117. package/dist/server/lib/validation.d.ts +55 -0
  118. package/dist/server/lib/validation.d.ts.map +1 -0
  119. package/dist/server/namespaces/activity/index.d.ts +8 -0
  120. package/dist/server/namespaces/activity/index.d.ts.map +1 -0
  121. package/dist/server/namespaces/activity/record.d.ts +49 -0
  122. package/dist/server/namespaces/activity/record.d.ts.map +1 -0
  123. package/dist/server/namespaces/activity/schema.d.ts +50 -0
  124. package/dist/server/namespaces/activity/schema.d.ts.map +1 -0
  125. package/dist/server/namespaces/user/get-profile.d.ts +32 -0
  126. package/dist/server/namespaces/user/get-profile.d.ts.map +1 -0
  127. package/dist/server/namespaces/user/index.d.ts +8 -0
  128. package/dist/server/namespaces/user/index.d.ts.map +1 -0
  129. package/dist/server/namespaces/user/verify.d.ts +28 -0
  130. package/dist/server/namespaces/user/verify.d.ts.map +1 -0
  131. package/dist/server/timeback-identity.d.ts +3 -3
  132. package/dist/server/timeback.d.ts +5 -3
  133. package/dist/server/timeback.d.ts.map +1 -1
  134. package/dist/server/types.d.ts +407 -14
  135. package/dist/server/types.d.ts.map +1 -1
  136. package/dist/shared/constants.d.ts +7 -0
  137. package/dist/shared/constants.d.ts.map +1 -1
  138. package/dist/shared/constants.ts +51 -0
  139. package/dist/shared/index.d.ts +9 -0
  140. package/dist/shared/index.d.ts.map +1 -0
  141. package/dist/shared/schemas.d.ts +57 -0
  142. package/dist/shared/schemas.d.ts.map +1 -0
  143. package/dist/shared/types.d.ts +287 -18
  144. package/dist/shared/types.d.ts.map +1 -1
  145. package/dist/shared/types.ts +636 -0
  146. package/package.json +7 -10
  147. package/dist/chunk-07j8zre9.js +0 -2
  148. package/dist/chunk-5171mkp2.js +0 -2
  149. package/dist/chunk-63afdp3y.js +0 -8
  150. package/dist/chunk-8gg8n8v9.js +0 -2
  151. package/dist/chunk-9se82640.js +0 -1
  152. package/dist/chunk-agpf1x3g.js +0 -16
  153. package/dist/chunk-hnf0tart.js +0 -2
  154. package/dist/chunk-qr0bbnsr.js +0 -1
  155. package/dist/chunk-whc53e0y.js +0 -11
  156. package/dist/chunk-x9gvef7q.js +0 -1
  157. package/dist/edge.d.ts +0 -13
  158. package/dist/edge.d.ts.map +0 -1
  159. package/dist/edge.js +0 -1
  160. package/dist/server/handlers/activity/handler.d.ts +0 -32
  161. package/dist/server/handlers/activity/handler.d.ts.map +0 -1
  162. package/dist/shared/xp-calculator.d.ts +0 -25
  163. package/dist/shared/xp-calculator.d.ts.map +0 -1
@@ -1,2 +0,0 @@
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};
@@ -1 +0,0 @@
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};
@@ -1,16 +0,0 @@
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};
@@ -1,2 +0,0 @@
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};
@@ -1 +0,0 @@
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};
@@ -1,11 +0,0 @@
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};
@@ -1 +0,0 @@
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};
package/dist/edge.d.ts DELETED
@@ -1,13 +0,0 @@
1
- /**
2
- * Timeback (edge/worker friendly entrypoint)
3
- *
4
- * This entrypoint is intended for runtimes like Cloudflare Workers / workerd.
5
- * It avoids importing Node-only dependencies (notably config loading via `c12`).
6
- *
7
- * It includes identity-only SSO plus a small set of edge-safe helpers.
8
- */
9
- export { createTimebackIdentity } from './server/timeback-identity';
10
- export type { IdentityOnlyConfig, IdentityOnlyInstance, IdentityOnlyHandlers } from './server';
11
- export { toNativeHandler } from './server/adapters/native';
12
- export { ROUTES } from './shared/constants';
13
- //# sourceMappingURL=edge.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"edge.d.ts","sourceRoot":"","sources":["../src/edge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AACnE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE9F,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA"}
package/dist/edge.js DELETED
@@ -1 +0,0 @@
1
- import{a as L,b as G,c as D}from"./chunk-63afdp3y.js";import"./chunk-whc53e0y.js";function V(y){let g=y.trim();if(g==="")return"/";let x=g.indexOf("?");if(x===-1)return g;let C=g.slice(0,x);if(C==="")return"/";return C}function $(y){let g=V(y);if(g!==""&&!g.startsWith("/"))g=`/${g}`;if(g==="/"||g==="")return"";if(g.endsWith("/"))return g.slice(0,-1);return g}function X(y){let g=y.method.toUpperCase(),x=V(y.pathname),C=y.callbackPath?V(y.callbackPath):void 0;if(C&&x===C)return g==="GET"?"identity.callback":null;let I=y.basePath,M=I!==void 0,J=M?$(I):void 0,Q=(f)=>{if(g==="GET"){if(f===G.IDENTITY.SIGNIN)return"identity.signIn";if(f===G.IDENTITY.CALLBACK)return"identity.callback";if(f===G.IDENTITY.SIGNOUT)return"identity.signOut";if(f===G.USER.ME)return"user.me";if(f===G.USER.VERIFY)return"user.verify"}if(g==="POST"){if(f===G.ACTIVITY)return"activity"}return null};if(M&&J!==void 0){if(J!==""&&x===J)return null;if(J!==""&&!x.startsWith(`${J}/`))return null;let f=J===""?x:x.slice(J.length),_=f.startsWith("/")?f:`/${f}`;return Q(_)}if(g==="GET"){if(x.endsWith(G.IDENTITY.SIGNIN))return"identity.signIn";if(x.endsWith(G.IDENTITY.CALLBACK))return"identity.callback";if(x.endsWith(G.IDENTITY.SIGNOUT))return"identity.signOut";if(x.endsWith(G.USER.ME))return"user.me";if(x.endsWith(G.USER.VERIFY))return"user.verify"}if(g==="POST"){if(x.endsWith(G.ACTIVITY))return"activity"}return null}function Y(y){return"handle"in y?y.handle:y}function Z(y){return"activity"in y}function W(y){return"user"in y}function K(y){return typeof y==="object"&&y!==null&&"timeback"in y}function F(y){let{timeback:g,callbackPath:x}=K(y)?y:{timeback:y,callbackPath:void 0},C=Y(g);return(I)=>{let J=new URL(I.url).pathname,Q=I.method,f=X({pathname:J,method:Q,callbackPath:x});if(f==="identity.signIn")return C.identity.signIn(I);if(f==="identity.callback")return C.identity.callback(I);if(f==="identity.signOut")return Promise.resolve(C.identity.signOut());if(f==="user.me"){if(!W(C))return Promise.resolve(L({error:"Not found"},404));return C.user.me(I)}if(f==="user.verify"){if(!W(C))return Promise.resolve(L({error:"Not found"},404));return C.user.verify(I)}if(f==="activity"){if(!Z(C))return Promise.resolve(L({error:"Not found"},404));return C.activity(I)}return Promise.resolve(L({error:"Not found"},404))}}export{F as toNativeHandler,D as createTimebackIdentity,G as ROUTES};
@@ -1,32 +0,0 @@
1
- /**
2
- * Activity Handler
3
- *
4
- * HTTP route handler for activity submissions.
5
- * Orchestrates validation, user resolution, gradebook writes, and Caliper event sending.
6
- */
7
- import { maybeWriteCompletionEntry as maybeWriteCompletionEntryImpl } from './completion';
8
- import { computeProgress as computeProgressImpl } from './progress';
9
- import type { ActivityHandler, ActivityHandlerConfig } from './types';
10
- /**
11
- * Internal dependencies for handler.
12
- *
13
- * This interface enables unit tests to inject mock implementations of
14
- * computeProgress and maybeWriteCompletionEntry without mocking the entire
15
- * TimebackClient.
16
- *
17
- * Not part of the public API - only exposed for testing purposes.
18
- */
19
- interface ActivityHandlerDeps {
20
- computeProgress: typeof computeProgressImpl;
21
- maybeWriteCompletionEntry: typeof maybeWriteCompletionEntryImpl;
22
- }
23
- /**
24
- * Create the activity POST handler.
25
- *
26
- * @param config - Handler configuration
27
- * @param deps - Internal dependencies (for testing only, not part of public API)
28
- * @returns The activity request handler
29
- */
30
- export declare function createActivityHandler(config: ActivityHandlerConfig, deps?: ActivityHandlerDeps): ActivityHandler;
31
- export {};
32
- //# sourceMappingURL=handler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,OAAO,EAAE,yBAAyB,IAAI,6BAA6B,EAAE,MAAM,cAAc,CAAA;AACzF,OAAO,EAAE,eAAe,IAAI,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAKnE,OAAO,KAAK,EACX,eAAe,EACf,qBAAqB,EAGrB,MAAM,SAAS,CAAA;AAQhB;;;;;;;;GAQG;AACH,UAAU,mBAAmB;IAC5B,eAAe,EAAE,OAAO,mBAAmB,CAAA;IAC3C,yBAAyB,EAAE,OAAO,6BAA6B,CAAA;CAC/D;AA+HD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,qBAAqB,EAC7B,IAAI,GAAE,mBAAiC,GACrC,eAAe,CAuLjB"}
@@ -1,25 +0,0 @@
1
- /**
2
- * XP Calculation Utilities
3
- *
4
- * Ported from playcademy `packages/timeback` so SDK users get consistent,
5
- * mastery-based XP behavior.
6
- *
7
- * XP is calculated from duration, accuracy, and attempt number:
8
- *
9
- * \( baseXp = durationMinutes \)
10
- * \( xp = baseXp \times accuracyMultiplier \times attemptMultiplier \)
11
- *
12
- * - Mastery threshold: 80% accuracy required to earn any XP.
13
- * - Perfect bonus: ~100% accuracy earns 1.25x multiplier (floating-point safe).
14
- * - Diminishing returns: attempt 1 = 1.0x, 2 = 0.5x, 3 = 0.25x, 4+ = 0x.
15
- */
16
- /**
17
- * Calculate XP based on duration, accuracy, and attempt number.
18
- *
19
- * @param durationSeconds - Total session duration in seconds
20
- * @param accuracy - Accuracy as decimal (0-1)
21
- * @param attemptNumber - Which attempt this is (1 = first, 2 = first re-attempt, etc.)
22
- * @returns Calculated XP, rounded to nearest tenth
23
- */
24
- export declare function calculateXp(durationSeconds: number, accuracy: number, attemptNumber: number): number;
25
- //# sourceMappingURL=xp-calculator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"xp-calculator.d.ts","sourceRoot":"","sources":["../../src/shared/xp-calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAwDH;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAC1B,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GACnB,MAAM,CAkBR"}