@vue-skuilder/standalone-ui 0.1.40 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.html CHANGED
@@ -9,11 +9,11 @@
9
9
  href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons"
10
10
  rel="stylesheet"
11
11
  />
12
- <script type="module" crossorigin src="/assets/index-Di-iurxs.js"></script>
12
+ <script type="module" crossorigin src="/assets/index-5H45bc-8.js"></script>
13
13
  <link rel="modulepreload" crossorigin href="/assets/dist-DCANvFNh.js">
14
- <link rel="modulepreload" crossorigin href="/assets/dist-BoYWClge.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/dist-B6gIbmvQ.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/MarkdownRenderer-DoVbFpA6-DYVMsbBP.js">
16
- <link rel="modulepreload" crossorigin href="/assets/common-ui.es-Dli7wjjJ.js">
16
+ <link rel="modulepreload" crossorigin href="/assets/common-ui.es-B6UqZKxa.js">
17
17
  <link rel="stylesheet" crossorigin href="/assets/common-ui-BY2Ut5jf.css">
18
18
  <link rel="stylesheet" crossorigin href="/assets/index-CwbD9tGY.css">
19
19
  </head>
@@ -369,7 +369,7 @@ Currently logged-in as ${this._username}.`);let u=await this.syncStrategy.create
369
369
  if (doc._id && doc._id.indexOf('card_review') === 0 && doc.courseId && doc.cardId) {
370
370
  emit(doc._id, doc.courseId + '-' + doc.cardId);
371
371
  }
372
- }`}}}]),t),userCoursesDoc=`CourseRegistrations`,userClassroomsDoc=`ClassroomRegistrations`}}),init_common=__esm({"src/impl/common/index.ts"(){"use strict";init_SyncStrategy(),init_BaseUserDB(),init_userDBHelpers()}}),PouchDataLayerProvider_exports={},__export(PouchDataLayerProvider_exports,{CouchDataLayerProvider:()=>CouchDataLayerProvider}),init_PouchDataLayerProvider=__esm({"src/impl/couch/PouchDataLayerProvider.ts"(){"use strict";init_logger(),init_dataDirectory(),init_auth(),init_adminDB2(),init_classroomDB2(),init_courseDB(),init_CourseSyncService(),init_common(),init_CouchDBSyncStrategy(),CouchDataLayerProvider=class{constructor(t){_defineProperty$2(this,`initialized`,!1),_defineProperty$2(this,`userDB`,void 0),_defineProperty$2(this,`currentUsername`,``),_defineProperty$2(this,`_courseIDs`,[]),t&&(this._courseIDs=t)}async initialize(){if(!this.initialized){if(typeof process<`u`&&process.versions!=null&&process.versions.node!=null){logger.info(`CouchDataLayerProvider: Running in Node.js environment, creating guest UserDB for testing.`),await initializeDataDirectory();let t=new CouchDBSyncStrategy;this.userDB=await BaseUser.instance(t)}else{let t=new CouchDBSyncStrategy;this.userDB=await BaseUser.instance(t),this.currentUsername=this.userDB.getUsername(),logger.debug(`Current username: ${this.currentUsername}`)}this.initialized=!0}}async teardown(){this.initialized=!1}getUserDB(){return this.userDB}getCourseDB(t){let c=CourseSyncService.getInstance().getLocalDB(t);return new CourseDB(t,async()=>this.getUserDB(),c??void 0)}async ensureCourseSynced(t,c){return CourseSyncService.getInstance().ensureSynced(t,c)}getCoursesDB(){return new CoursesDB(this._courseIDs)}async getClassroomDB(t,c){return c===`student`?await StudentClassroomDB.factory(t,this.getUserDB()):await TeacherClassroomDB.factory(t)}getAdminDB(){return new AdminDB}async createUserReaderForUser(t){let c=await getLoggedInUsername();if(c!==`admin`)throw Error(`Unauthorized: Only admin users can access other users' data`);logger.info(`Admin user '${c}' requesting UserDBReader for '${t}'`);let u=new CouchDBSyncStrategy;return await BaseUser.instance(u,t)}isReadOnly(){return!1}}}}),init_StaticDataUnpacker=__esm({"src/impl/static/StaticDataUnpacker.ts"(){"use strict";init_logger(),init_core(),pathUtils={isAbsolute:t=>!!(/^[a-zA-Z]:[\\/]/.test(t)||/^\\\\/.test(t)||t.startsWith(`/`))},nodeFS=null;try{typeof window>`u`&&typeof process<`u`&&process.versions?.node&&(nodeFS=eval(`require`)(`fs`))}catch{}StaticDataUnpacker=class{constructor(t,c){_defineProperty$2(this,`manifest`,void 0),_defineProperty$2(this,`basePath`,void 0),_defineProperty$2(this,`documentCache`,new Map),_defineProperty$2(this,`chunkCache`,new Map),_defineProperty$2(this,`indexCache`,new Map),this.manifest=t,this.basePath=c}async getDocument(t){if(this.documentCache.has(t)){let c=this.documentCache.get(t);return await this.hydrateAttachments(c)}let c=await this.findChunkForDocument(t);if(!c)throw logger.error(`Document ${t} not found in any chunk. Available chunks:`,this.manifest.chunks.map(t=>`${t.id} (${t.docType}): ${t.startKey} - ${t.endKey}`)),Error(`Document ${t} not found in any chunk`);if(await this.loadChunk(c.id),this.documentCache.has(t)){let c=this.documentCache.get(t);return await this.hydrateAttachments(c)}throw logger.error(`Document ${t} not found in chunk ${c.id}`),Error(`Document ${t} not found in chunk ${c.id}`)}async getAllDocumentsByPrefix(t){let c=this.manifest.chunks.filter(c=>{let u=t+`￰`;return c.startKey<=u&&c.endKey>=t});if(c.length===0)return logger.debug(`[StaticDataUnpacker] No chunks found for prefix: ${t}`),[];await Promise.all(c.map(t=>this.loadChunk(t.id)));let u=[];for(let[c,d]of this.documentCache.entries())c.startsWith(t)&&u.push(await this.hydrateAttachments(d));return logger.debug(`[StaticDataUnpacker] Found ${u.length} documents with prefix: ${t}`),u}async queryByElo(t,c=25){let u=await this.loadIndex(`elo`);if(!u||!u.sorted)return logger.warn(`ELO index not found or malformed, returning empty results`),[];let d=u.sorted,m=0,g=0,b=d.length-1;for(;g<=b;){let c=Math.floor((g+b)/2);d[c].elo<t?g=c+1:b=c-1}m=g;let S=[],C=Math.floor(c/2);for(let t=Math.max(0,m-C);t<m&&S.length<c;t++)S.push(d[t].cardId);for(let t=m;t<d.length&&S.length<c;t++)S.push(d[t].cardId);return S}async getTagsIndex(){try{return await this.loadIndex(`tags`)}catch{return{byCard:{},byTag:{}}}}getDocTypeFromId(t){for(let c in DocTypePrefixes){let u=DocTypePrefixes[c];if(t.startsWith(`${u}-`))return c}}async findChunkForDocument(t){let c=this.getDocTypeFromId(t);if(c){let u=this.manifest.chunks.filter(t=>t.docType===c);for(let c of u)if(t>=c.startKey&&t<=c.endKey&&await this.verifyDocumentInChunk(t,c))return c}else{for(let c of this.manifest.chunks)if(t>=c.startKey&&t<=c.endKey&&await this.verifyDocumentInChunk(t,c))return c;let c=this.manifest.chunks.filter(t=>t.docType!==`CARD`&&t.docType!==`DISPLAYABLE_DATA`&&t.docType!==`TAG`);for(let u of c)if(t>=u.startKey&&t<=u.endKey&&await this.verifyDocumentInChunk(t,u))return u;return}}async verifyDocumentInChunk(t,c){try{return await this.loadChunk(c.id),this.documentCache.has(t)}catch{return!1}}async loadChunk(t){if(this.chunkCache.has(t))return;let c=this.manifest.chunks.find(c=>c.id===t);if(!c)throw Error(`Chunk ${t} not found in manifest`);try{let u=`${this.basePath}/${c.path}`;logger.debug(`Loading chunk from ${u}`);let d;if(this.isLocalPath(u)&&nodeFS){let t=await nodeFS.promises.readFile(u,`utf8`);d=JSON.parse(t)}else{let c=await fetch(u);if(!c.ok)throw Error(`Failed to fetch chunk ${t}: ${c.status} ${c.statusText}`);d=await c.json()}this.chunkCache.set(t,d);for(let t of d)t._id&&this.documentCache.set(t._id,t);logger.debug(`Loaded ${d.length} documents from chunk ${t}`)}catch(c){throw logger.error(`Failed to load chunk ${t}:`,c),c}}async loadIndex(t){if(this.indexCache.has(t))return this.indexCache.get(t);let c=this.manifest.indices.find(c=>c.name===t);if(!c)throw Error(`Index ${t} not found in manifest`);try{let u=`${this.basePath}/${c.path}`;logger.debug(`Loading index from ${u}`);let d;if(this.isLocalPath(u)&&nodeFS){let t=await nodeFS.promises.readFile(u,`utf8`);d=JSON.parse(t)}else{let c=await fetch(u);if(!c.ok)throw Error(`Failed to fetch index ${t}: ${c.status} ${c.statusText}`);d=await c.json()}return this.indexCache.set(t,d),logger.debug(`Loaded index ${t}`),d}catch(c){throw logger.error(`Failed to load index ${t}:`,c),c}}async getRawDocument(t){if(this.documentCache.has(t))return this.documentCache.get(t);let c=await this.findChunkForDocument(t);if(!c)throw logger.error(`Document ${t} not found in any chunk. Available chunks:`,this.manifest.chunks.map(t=>`${t.id} (${t.docType}): ${t.startKey} - ${t.endKey}`)),Error(`Document ${t} not found in any chunk`);if(await this.loadChunk(c.id),this.documentCache.has(t))return this.documentCache.get(t);throw logger.error(`Document ${t} not found in chunk ${c.id}`),Error(`Document ${t} not found in chunk ${c.id}`)}getAttachmentUrl(t,c){return`${this.basePath}/attachments/${t}/${c}`}async getAttachmentPath(t,c){try{let u=await this.getRawDocument(t);if(u._attachments&&u._attachments[c]){let t=u._attachments[c];if(t.path)return`${this.basePath}/${t.path}`}return null}catch{return null}}async getAttachmentBlob(t,c){let u=await this.getAttachmentPath(t,c);if(!u)return null;try{if(this.isLocalPath(u)&&nodeFS)return await nodeFS.promises.readFile(u);{let d=await fetch(u);if(!d.ok)throw Error(`Failed to fetch attachment ${t}/${c}: ${d.status} ${d.statusText}`);return await d.blob()}}catch(u){return logger.error(`Failed to load attachment ${t}/${c}:`,u),null}}async hydrateAttachments(t){let c=t;if(!c._attachments)return t;let u=JSON.parse(JSON.stringify(t));for(let[t,d]of Object.entries(c._attachments)){let m=d;if(m.path)try{let d=await this.getAttachmentBlob(c._id,t);d?typeof window<`u`&&window.URL?u._attachments[t]={...m,data:d,stub:!1}:u._attachments[t]={...m,buffer:d}:logger.warn(`[hydrateAttachments] getAttachmentBlob returned null for ${c._id}/${t}. Skipping hydration for this attachment.`)}catch(u){logger.warn(`[hydrateAttachments] Failed to hydrate attachment ${c._id}/${t}:`,u)}else logger.debug(`[hydrateAttachments] Attachment ${t} for doc ${c._id} has no path. Skipping blob conversion.`)}return u}clearCaches(){this.documentCache.clear(),this.chunkCache.clear(),this.indexCache.clear()}getCacheStats(){return{documents:this.documentCache.size,chunks:this.chunkCache.size,indices:this.indexCache.size}}isLocalPath(t){return!t.startsWith(`http://`)&&!t.startsWith(`https://`)&&(pathUtils.isAbsolute(t)||t.startsWith(`./`)||t.startsWith(`../`))}}}}),init_courseDB2=__esm({"src/impl/static/courseDB.ts"(){"use strict";init_types_legacy(),init_logger(),init_defaults(),init_PipelineAssembler(),StaticCourseDB=class{constructor(t,c,u,d){_defineProperty$2(this,`_pendingHints`,null),this.courseId=t,this.unpacker=c,this.userDB=u,this.manifest=d}getCourseID(){return this.courseId}async getCourseConfig(){if(this.manifest.courseConfig!=null)return this.manifest.courseConfig;throw Error(`Course config not found for course ${this.courseId}`)}async updateCourseConfig(t){throw Error(`Cannot update course config in static mode`)}async getCourseInfo(){return{cardCount:this.manifest.chunks.filter(t=>t.docType===`CARD`).reduce((t,c)=>t+c.documentCount,0),registeredUsers:0}}async getCourseDoc(t,c){return this.unpacker.getDocument(t)}async getCourseDocs(t,c){let u=await Promise.all(t.map(async t=>{try{return{id:t,key:t,value:{rev:`1-static`},doc:await this.unpacker.getDocument(t)}}catch{return{key:t,error:`not_found`}}}));return{total_rows:t.length,offset:0,rows:u}}async getCardsByELO(t,c){return(await this.unpacker.queryByElo(t,c||25)).map(t=>{let[c,u,d]=t.split(`-`);return{courseID:c,cardID:u,elo:d?parseInt(d):void 0}})}async getCardEloData(t){return await Promise.all(t.map(async t=>{try{return(await this.unpacker.getDocument(t)).elo||{global:{score:1e3,count:0},tags:{},misc:{}}}catch{return{global:{score:1e3,count:0},tags:{},misc:{}}}}))}async updateCardElo(t,c){return{ok:!0,id:t,rev:`1-static`}}async getCardsCenteredAtELO(t,c){let u=typeof t.elo==`number`?t.elo:1e3;if(t.elo===`user`)try{let t=(await this.userDB.getCourseRegistrationsDoc()).courses.find(t=>t.courseID===this.courseId);t&&typeof t.elo==`object`&&(u=t.elo.global.score)}catch{u=1e3}else t.elo===`random`&&(u=800+Math.random()*400);let d=(await this.unpacker.queryByElo(u,t.limit*2)).map(t=>({cardID:t,courseID:this.courseId}));return c&&(d=d.filter(c)),d.slice(0,t.limit).map(t=>({status:`new`,cardID:t.cardID,contentSourceType:`course`,contentSourceID:this.courseId,courseID:this.courseId}))}async getAppliedTags(t){try{let c=await this.unpacker.getTagsIndex(),u=c.byCard[t]||[],d=await Promise.all(u.map(async u=>{let d=`TAG-${u}`;try{let c=await this.unpacker.getDocument(d);return{id:d,key:t,value:{name:c.name,snippet:c.snippet,count:c.taggedCards?.length||0}}}catch(m){if(m&&m.status===404)logger.warn(`Tag document not found for ${u}, creating stub`);else throw logger.error(`Error getting tag document for ${u}:`,m),m;return{id:d,key:t,value:{name:u,snippet:`Tag: ${u}`,count:c.byTag[u]?.length||0}}}}));return{total_rows:d.length,offset:0,rows:d}}catch(c){return logger.error(`Error getting applied tags for card ${t}:`,c),{total_rows:0,offset:0,rows:[]}}}async getAppliedTagsBatch(t){let c=await this.unpacker.getTagsIndex(),u=new Map;for(let d of t)u.set(d,c.byCard[d]||[]);return u}async getAllCardIds(){let t=await this.unpacker.getTagsIndex();return Object.keys(t.byCard)}async addTagToCard(t,c){throw Error(`Cannot modify tags in static mode`)}async removeTagFromCard(t,c){throw Error(`Cannot modify tags in static mode`)}async createTag(t){throw Error(`Cannot create tags in static mode`)}async getTag(t){return this.unpacker.getDocument(`TAG-${t}`)}async updateTag(t){throw Error(`Cannot update tags in static mode`)}async getCourseTagStubs(){try{let t=await this.unpacker.getTagsIndex();if(!t||!t.byTag)return logger.warn(`Tags index not found or empty`),{total_rows:0,offset:0,rows:[]};let c=Object.keys(t.byTag),u=await Promise.all(c.map(async c=>{let u=t.byTag[c]||[],d=`TAG-${c}`;try{return{id:d,key:d,value:{rev:`1-static`},doc:await this.unpacker.getDocument(d)}}catch(t){if(t&&t.status===404)return logger.warn(`Tag document not found for ${c}, creating stub`),{id:d,key:d,value:{rev:`1-static`},doc:{_id:d,_rev:`1-static`,course:this.courseId,docType:`TAG`,name:c,snippet:`Tag: ${c}`,wiki:``,taggedCards:u,author:`system`}};throw logger.error(`Error getting tag document for ${c}:`,t),t}}));return{total_rows:u.length,offset:0,rows:u}}catch(t){return logger.error(`Failed to get course tag stubs:`,t),{total_rows:0,offset:0,rows:[]}}}async addNote(t,c,u,d,m,g,b){return{status:Status.error,message:`Cannot add notes in static mode`}}async removeCard(t){throw Error(`Cannot remove cards in static mode`)}async getInexperiencedCards(){return[]}async getNavigationStrategy(t){try{return await this.unpacker.getDocument(t)}catch(c){throw logger.error(`[static/courseDB] Strategy ${t} not found: ${c}`),c}}async getAllNavigationStrategies(){let t=DocTypePrefixes.NAVIGATION_STRATEGY;try{return await this.unpacker.getAllDocumentsByPrefix(t)}catch(t){return logger.warn(`[static/courseDB] Error loading navigation strategies: ${t}`),[]}}async addNavigationStrategy(t){throw Error(`Cannot add navigation strategies in static mode`)}async updateNavigationStrategy(t,c){throw Error(`Cannot update navigation strategies in static mode`)}async createNavigator(t){try{let c=await this.getAllNavigationStrategies();if(c.length===0)return logger.debug(`[static/courseDB] No strategy documents found, using default Pipeline(Composite(ELO, SRS), [eloDistanceFilter])`),createDefaultPipeline(t,this);let{pipeline:u,generatorStrategies:d,filterStrategies:m,warnings:g}=await new PipelineAssembler().assemble({strategies:c,user:t,course:this});for(let t of g)logger.warn(`[PipelineAssembler] ${t}`);return u?(logger.debug(`[static/courseDB] Using assembled pipeline with ${d.length} generator(s) and ${m.length} filter(s)`),u):(logger.debug(`[static/courseDB] Pipeline assembly failed, using default pipeline`),createDefaultPipeline(t,this))}catch(t){throw logger.error(`[static/courseDB] Error creating navigator: ${t}`),t}}setEphemeralHints(t){this._pendingHints=t}async getWeightedCards(t){try{let c=await this.createNavigator(this.userDB);return this._pendingHints&&(c.setEphemeralHints(this._pendingHints),this._pendingHints=null),c.getWeightedCards(t)}catch(t){throw logger.error(`[static/courseDB] Error getting weighted cards: ${t}`),t}}getAttachmentUrl(t,c){return this.unpacker.getAttachmentUrl(t,c)}async getAttachmentBlob(t,c){return this.unpacker.getAttachmentBlob(t,c)}async searchCards(t){return[]}async find(t){return{docs:[],warning:`Find operations not supported in static mode`}}}}}),init_coursesDB=__esm({"src/impl/static/coursesDB.ts"(){"use strict";init_logger(),StaticCoursesDB=class{constructor(t,c){this.manifests=t,this.dependencyNameToCourseId=c}async getCourseConfig(t){let c=this.manifests[t];if(!c&&this.dependencyNameToCourseId){let u=this.dependencyNameToCourseId.get(t);u&&(c=this.manifests[u])}if(!c)throw logger.warn(`Course manifest for ${t} not found`),Error(`Course ${t} not found`);if(c.courseConfig)return c.courseConfig;throw logger.warn(`Course config not found in manifest for course ${t}`),Error(`Course config not found for course ${t}`)}async getCourseList(){return Object.keys(this.manifests).map(t=>({courseID:t,name:this.manifests[t].courseName}))}async disambiguateCourse(t,c){logger.warn(`Cannot disambiguate courses in static mode`)}}}}),init_NoOpSyncStrategy=__esm({"src/impl/static/NoOpSyncStrategy.ts"(){"use strict";init_common(),NoOpSyncStrategy=class{constructor(){_defineProperty$2(this,`currentUsername`,accomodateGuest().username)}setupRemoteDB(t){return getLocalUserDB(t)}getWriteDB(t){return getLocalUserDB(t)}startSync(t,c){}stopSync(){}canCreateAccount(){return!1}canAuthenticate(){return!1}async createAccount(t,c){throw Error(`Account creation not supported in static mode. Use local account switching instead.`)}async authenticate(t,c){throw Error(`Remote authentication not supported in static mode. Use local account switching instead.`)}async logout(){return this.currentUsername=accomodateGuest().username,{ok:!0}}async getCurrentUsername(){return this.currentUsername}setCurrentUsername(t){this.currentUsername=t}}}}),StaticDataLayerProvider_exports={},__export(StaticDataLayerProvider_exports,{StaticDataLayerProvider:()=>StaticDataLayerProvider}),init_StaticDataLayerProvider=__esm({"src/impl/static/StaticDataLayerProvider.ts"(){"use strict";init_logger(),init_StaticDataUnpacker(),init_courseDB2(),init_coursesDB(),init_common(),init_NoOpSyncStrategy(),StaticDataLayerProvider=class{constructor(t){_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`initialized`,!1),_defineProperty$2(this,`courseUnpackers`,new Map),_defineProperty$2(this,`manifests`,{}),_defineProperty$2(this,`dependencyNameToCourseId`,new Map),this.config={localStoragePrefix:t.localStoragePrefix||`skuilder-static`,rootManifest:t.rootManifest||{dependencies:{}},rootManifestUrl:t.rootManifestUrl||`/`}}async resolveCourseDependencies(){logger.info(`[StaticDataLayerProvider] Starting course dependency resolution...`);let t=this.config.rootManifest;for(let[c,u]of Object.entries(t.dependencies||{}))try{logger.debug(`[StaticDataLayerProvider] Resolving dependency: ${c} from ${u}`);let t=new URL(u,this.config.rootManifestUrl).href,d=await fetch(t);if(!d.ok)throw Error(`Failed to fetch course manifest for ${c}`);let m=await d.json();if(m.content&&m.content.manifest){let u=new URL(`.`,t).href,d=new URL(m.content.manifest,t).href,g=await fetch(d);if(!g.ok)throw Error(`Failed to fetch final content manifest for ${c} at ${d}`);let b=await g.json(),S=b.courseId||b.courseConfig?.courseID;if(!S)throw Error(`Course manifest for ${c} missing courseId`);this.manifests[S]=b;let C=new StaticDataUnpacker(b,u);this.courseUnpackers.set(S,C),this.dependencyNameToCourseId.set(c,S),logger.info(`[StaticDataLayerProvider] Successfully resolved and prepared course: ${c} (courseId: ${S})`)}}catch(t){logger.error(`[StaticDataLayerProvider] Failed to resolve dependency ${c}:`,t)}logger.info(`[StaticDataLayerProvider] Course dependency resolution complete.`)}async initialize(){this.initialized||(logger.info(`Initializing static data layer provider`),await this.resolveCourseDependencies(),this.initialized=!0)}async teardown(){this.courseUnpackers.clear(),this.initialized=!1}getUserDB(){let t=new NoOpSyncStrategy;return BaseUser.Dummy(t)}getCourseDB(t){let c=this.courseUnpackers.get(t),u=t;if(!c){let d=this.dependencyNameToCourseId.get(t);d&&(c=this.courseUnpackers.get(d),u=d)}if(!c)throw Error(`Course ${t} not found or failed to initialize in static data layer.`);let d=this.manifests[u];return new StaticCourseDB(u,c,this.getUserDB(),d)}getCoursesDB(){return new StaticCoursesDB(this.manifests,this.dependencyNameToCourseId)}async getClassroomDB(t,c){throw Error(`Classrooms not supported in static mode`)}getAdminDB(){throw Error(`Admin functions not supported in static mode`)}async createUserReaderForUser(t){return logger.warn(`StaticDataLayerProvider: Multi-user access not supported in static mode`),logger.warn(`Request: trying to access data for ${t}`),logger.warn(`Returning current user's data instead`),this.getUserDB()}isReadOnly(){return!0}}}}),init_factory=__esm({"src/factory.ts"(){"use strict";init_common(),init_logger(),init_navigators(),NOT_SET=`NOT_SET`,ENV={COUCHDB_SERVER_PROTOCOL:NOT_SET,COUCHDB_SERVER_URL:NOT_SET,LOCAL_STORAGE_PREFIX:``},dataLayerInstance=null}}),init_TagFilteredContentSource=__esm({"src/study/TagFilteredContentSource.ts"(){"use strict";init_courseDB(),init_logger(),TagFilteredContentSource=class{constructor(t,c,u){_defineProperty$2(this,`courseId`,void 0),_defineProperty$2(this,`filter`,void 0),_defineProperty$2(this,`user`,void 0),_defineProperty$2(this,`resolvedCardIds`,null),this.courseId=t,this.filter=c,this.user=u,logger.info(`[TagFilteredContentSource] Created for course "${t}" with filter:`,JSON.stringify(c))}async resolveFilteredCardIds(){if(this.resolvedCardIds!==null)return this.resolvedCardIds;let t=new Set;if(this.filter.include.length>0)for(let c of this.filter.include)try{(await getTag(this.courseId,c)).taggedCards.forEach(c=>t.add(c))}catch(t){logger.warn(`[TagFilteredContentSource] Could not resolve tag "${c}" for inclusion:`,t)}if(t.size===0&&this.filter.include.length>0)return logger.warn(`[TagFilteredContentSource] No cards found for include tags: ${this.filter.include.join(`, `)}`),this.resolvedCardIds=new Set,this.resolvedCardIds;let c=new Set;if(this.filter.exclude.length>0)for(let t of this.filter.exclude)try{(await getTag(this.courseId,t)).taggedCards.forEach(t=>c.add(t))}catch(c){logger.warn(`[TagFilteredContentSource] Could not resolve tag "${t}" for exclusion:`,c)}let u=new Set;for(let d of t)c.has(d)||u.add(d);return logger.info(`[TagFilteredContentSource] Resolved ${u.size} cards (included: ${t.size}, excluded: ${c.size})`),this.resolvedCardIds=u,u}async getWeightedCards(t){if(!hasActiveFilter(this.filter))return logger.warn(`[TagFilteredContentSource] getWeightedCards called with no active filter`),{cards:[]};let c=await this.resolveFilteredCardIds(),u=await this.user.getActiveCards(),d=new Set(u.map(t=>t.cardID)),m=[];for(let u of c)if(d.has(u)||m.push({cardId:u,courseId:this.courseId,score:1,provenance:[{strategy:`tagFilter`,strategyName:`Tag Filter`,strategyId:`TAG_FILTER`,action:`generated`,score:1,reason:`Tag-filtered new card (tags: ${this.filter.include.join(`, `)})`}]}),m.length>=t)break;logger.info(`[TagFilteredContentSource] Found ${m.length} new cards matching filter`);let g=await this.user.getPendingReviews(this.courseId),b=g.filter(t=>c.has(t.cardId));return logger.info(`[TagFilteredContentSource] Found ${b.length} pending reviews matching filter (of ${g.length} total)`),{cards:[...b.map(t=>({cardId:t.cardId,courseId:t.courseId,score:1,reviewID:t._id,provenance:[{strategy:`tagFilter`,strategyName:`Tag Filter`,strategyId:`TAG_FILTER`,action:`generated`,score:1,reason:`Tag-filtered review (tags: ${this.filter.include.join(`, `)})`}]})),...m].slice(0,t)}}clearCache(){this.resolvedCardIds=null}getCourseId(){return this.courseId}getFilter(){return this.filter}}}}),init_contentSource=__esm({"src/core/interfaces/contentSource.ts"(){"use strict";init_factory(),init_classroomDB2(),init_TagFilteredContentSource()}}),init_courseDB3=__esm({"src/core/interfaces/courseDB.ts"(){"use strict";}}),init_dataLayerProvider=__esm({"src/core/interfaces/dataLayerProvider.ts"(){"use strict";}}),init_userDB=__esm({"src/core/interfaces/userDB.ts"(){"use strict";}}),init_interfaces=__esm({"src/core/interfaces/index.ts"(){"use strict";init_adminDB(),init_classroomDB(),init_contentSource(),init_courseDB3(),init_dataLayerProvider(),init_userDB()}}),init_user=__esm({"src/core/types/user.ts"(){"use strict";}}),init_strategyState=__esm({"src/core/types/strategyState.ts"(){"use strict";}}),init_userOutcome=__esm({"src/core/types/userOutcome.ts"(){"use strict";}}),init_cardProcessor=__esm({"src/core/bulkImport/cardProcessor.ts"(){"use strict";init_logger()}}),init_types3=__esm({"src/core/bulkImport/types.ts"(){"use strict";}}),init_bulkImport=__esm({"src/core/bulkImport/index.ts"(){"use strict";init_cardProcessor(),init_types3()}}),init_UserDBDebugger=__esm({"src/core/UserDBDebugger.ts"(){"use strict";init_logger(),init_factory(),init_types_legacy(),init_userDBHelpers(),userDBDebugAPI={showUser(){let t=getUserDB();t&&(console.group(`👤 User Information`),logger.info(`Username: ${t.getUsername()}`),logger.info(`Logged in: ${t.isLoggedIn()?`Yes ✅`:`No (Guest) ❌`}`),t.getConfig().then(t=>{logger.info(`Configuration:`),logger.info(JSON.stringify(t,null,2))}).catch(t=>{logger.info(`Error loading config: ${t.message}`)}).finally(()=>{console.groupEnd()}))},async showScheduledReviews(t){let c=getUserDB();if(c)try{let u=await c.getPendingReviews(t);if(console.group(`\u{1F4C5} Scheduled Reviews${t?` (${t})`:``}`),logger.info(`Total: ${u.length}`),u.length>0){let t=new Map;for(let c of u)t.has(c.courseId)||t.set(c.courseId,[]),t.get(c.courseId).push(c);for(let[c,u]of t){console.group(`Course: ${c} (${u.length} reviews)`);let t=u.sort((t,c)=>{let u=typeof t.reviewTime==`string`?t.reviewTime:t.reviewTime.toISOString(),d=typeof c.reviewTime==`string`?c.reviewTime:c.reviewTime.toISOString();return new Date(u).getTime()-new Date(d).getTime()});for(let c of t.slice(0,10)){let t=typeof c.reviewTime==`string`?c.reviewTime:c.reviewTime.toISOString();logger.info(` ${c.cardId.slice(0,12)}... @ ${formatTimestamp(t)} [${c.scheduledFor}/${c.schedulingAgentId}]`)}t.length>10&&logger.info(` ... and ${t.length-10} more`),console.groupEnd()}}console.groupEnd()}catch(t){logger.info(`Error loading scheduled reviews: ${t.message}`)}},async showCourseRegistrations(){let t=getUserDB();if(t)try{let c=await t.getActiveCourses();console.group(`📚 Course Registrations`),logger.info(`Total: ${c.length}`),c.length>0&&console.table(c.map(t=>({courseId:t.courseID,status:t.status||`active`,elo:typeof t.elo==`number`?t.elo.toFixed(0):t.elo?.global?.score?.toFixed(0)||`N/A`}))),console.groupEnd()}catch(t){logger.info(`Error loading course registrations: ${t.message}`)}},async showCardHistory(t){let c=getRawDB();if(c)try{let u=(await filterAllDocsByPrefix(c,DocTypePrefixes.CARDRECORD)).rows.filter(c=>c.doc&&c.doc.cardID===t).map(t=>t.doc);if(console.group(`\u{1F3B4} Card History: ${t}`),logger.info(`Total interactions: ${u.length}`),u.length>0){let t=u.sort((t,c)=>new Date(c.timestamp).getTime()-new Date(t.timestamp).getTime());console.table(t.slice(0,20).map(t=>({time:formatTimestamp(t.timestamp),outcome:t.outcome||`N/A`,duration:t.duration?`${(t.duration/1e3).toFixed(1)}s`:`N/A`,courseId:t.courseId}))),t.length>20&&logger.info(`... and ${t.length-20} more interactions`)}console.groupEnd()}catch(t){logger.info(`Error loading card history: ${t.message}`)}},async queryByType(t,c=50){let u=getRawDB();if(u)try{let d=DocTypePrefixes[DocType[t]];if(!d){logger.info(`Unknown document type: ${t}`);return}let m=await filterAllDocsByPrefix(u,d);if(console.group(`\u{1F4C4} Documents: ${t}`),logger.info(`Total: ${m.rows.length}`),logger.info(`Prefix: ${d}`),m.rows.length>0){logger.info(`Sample documents:`);let t=m.rows.slice(0,Math.min(c,m.rows.length));for(let c of t)logger.info(`
372
+ }`}}}]),t),userCoursesDoc=`CourseRegistrations`,userClassroomsDoc=`ClassroomRegistrations`}}),init_common=__esm({"src/impl/common/index.ts"(){"use strict";init_SyncStrategy(),init_BaseUserDB(),init_userDBHelpers()}}),PouchDataLayerProvider_exports={},__export(PouchDataLayerProvider_exports,{CouchDataLayerProvider:()=>CouchDataLayerProvider}),init_PouchDataLayerProvider=__esm({"src/impl/couch/PouchDataLayerProvider.ts"(){"use strict";init_logger(),init_dataDirectory(),init_auth(),init_adminDB2(),init_classroomDB2(),init_courseDB(),init_CourseSyncService(),init_common(),init_CouchDBSyncStrategy(),CouchDataLayerProvider=class{constructor(t){_defineProperty$2(this,`initialized`,!1),_defineProperty$2(this,`userDB`,void 0),_defineProperty$2(this,`currentUsername`,``),_defineProperty$2(this,`_courseIDs`,[]),t&&(this._courseIDs=t)}async initialize(){if(!this.initialized){if(typeof process<`u`&&process.versions!=null&&process.versions.node!=null){logger.info(`CouchDataLayerProvider: Running in Node.js environment, creating guest UserDB for testing.`),await initializeDataDirectory();let t=new CouchDBSyncStrategy;this.userDB=await BaseUser.instance(t)}else{let t=new CouchDBSyncStrategy;this.userDB=await BaseUser.instance(t),this.currentUsername=this.userDB.getUsername(),logger.debug(`Current username: ${this.currentUsername}`)}this.initialized=!0}}async teardown(){this.initialized=!1}getUserDB(){return this.userDB}getCourseDB(t){let c=CourseSyncService.getInstance().getLocalDB(t);return new CourseDB(t,async()=>this.getUserDB(),c??void 0)}async ensureCourseSynced(t,c){return CourseSyncService.getInstance().ensureSynced(t,c)}getCoursesDB(){return new CoursesDB(this._courseIDs)}async getClassroomDB(t,c){return c===`student`?await StudentClassroomDB.factory(t,this.getUserDB()):await TeacherClassroomDB.factory(t)}getAdminDB(){return new AdminDB}async createUserReaderForUser(t){let c=await getLoggedInUsername();if(c!==`admin`)throw Error(`Unauthorized: Only admin users can access other users' data`);logger.info(`Admin user '${c}' requesting UserDBReader for '${t}'`);let u=new CouchDBSyncStrategy;return await BaseUser.instance(u,t)}isReadOnly(){return!1}}}}),init_StaticDataUnpacker=__esm({"src/impl/static/StaticDataUnpacker.ts"(){"use strict";init_logger(),init_core(),pathUtils={isAbsolute:t=>!!(/^[a-zA-Z]:[\\/]/.test(t)||/^\\\\/.test(t)||t.startsWith(`/`))},nodeFS=null;try{typeof window>`u`&&typeof process<`u`&&process.versions?.node&&(nodeFS=eval(`require`)(`fs`))}catch{}StaticDataUnpacker=class{constructor(t,c){_defineProperty$2(this,`manifest`,void 0),_defineProperty$2(this,`basePath`,void 0),_defineProperty$2(this,`documentCache`,new Map),_defineProperty$2(this,`chunkCache`,new Map),_defineProperty$2(this,`indexCache`,new Map),this.manifest=t,this.basePath=c}async getDocument(t){if(this.documentCache.has(t)){let c=this.documentCache.get(t);return await this.hydrateAttachments(c)}let c=await this.findChunkForDocument(t);if(!c)throw logger.error(`Document ${t} not found in any chunk. Available chunks:`,this.manifest.chunks.map(t=>`${t.id} (${t.docType}): ${t.startKey} - ${t.endKey}`)),Error(`Document ${t} not found in any chunk`);if(await this.loadChunk(c.id),this.documentCache.has(t)){let c=this.documentCache.get(t);return await this.hydrateAttachments(c)}throw logger.error(`Document ${t} not found in chunk ${c.id}`),Error(`Document ${t} not found in chunk ${c.id}`)}async getAllDocumentsByPrefix(t){let c=this.manifest.chunks.filter(c=>{let u=t+`￰`;return c.startKey<=u&&c.endKey>=t});if(c.length===0)return logger.debug(`[StaticDataUnpacker] No chunks found for prefix: ${t}`),[];await Promise.all(c.map(t=>this.loadChunk(t.id)));let u=[];for(let[c,d]of this.documentCache.entries())c.startsWith(t)&&u.push(await this.hydrateAttachments(d));return logger.debug(`[StaticDataUnpacker] Found ${u.length} documents with prefix: ${t}`),u}async queryByElo(t,c=25){let u=await this.loadIndex(`elo`);if(!u||!u.sorted)return logger.warn(`ELO index not found or malformed, returning empty results`),[];let d=u.sorted,m=0,g=0,b=d.length-1;for(;g<=b;){let c=Math.floor((g+b)/2);d[c].elo<t?g=c+1:b=c-1}m=g;let S=[],C=Math.floor(c/2);for(let t=Math.max(0,m-C);t<m&&S.length<c;t++)S.push(d[t].cardId);for(let t=m;t<d.length&&S.length<c;t++)S.push(d[t].cardId);return S}async getTagsIndex(){try{return await this.loadIndex(`tags`)}catch{return{byCard:{},byTag:{}}}}getDocTypeFromId(t){for(let c in DocTypePrefixes){let u=DocTypePrefixes[c];if(t.startsWith(`${u}-`))return c}}async findChunkForDocument(t){let c=this.getDocTypeFromId(t);if(c){let u=this.manifest.chunks.filter(t=>t.docType===c);for(let c of u)if(t>=c.startKey&&t<=c.endKey&&await this.verifyDocumentInChunk(t,c))return c}else{for(let c of this.manifest.chunks)if(t>=c.startKey&&t<=c.endKey&&await this.verifyDocumentInChunk(t,c))return c;let c=this.manifest.chunks.filter(t=>t.docType!==`CARD`&&t.docType!==`DISPLAYABLE_DATA`&&t.docType!==`TAG`);for(let u of c)if(t>=u.startKey&&t<=u.endKey&&await this.verifyDocumentInChunk(t,u))return u;return}}async verifyDocumentInChunk(t,c){try{return await this.loadChunk(c.id),this.documentCache.has(t)}catch{return!1}}async loadChunk(t){if(this.chunkCache.has(t))return;let c=this.manifest.chunks.find(c=>c.id===t);if(!c)throw Error(`Chunk ${t} not found in manifest`);try{let u=`${this.basePath}/${c.path}`;logger.debug(`Loading chunk from ${u}`);let d;if(this.isLocalPath(u)&&nodeFS){let t=await nodeFS.promises.readFile(u,`utf8`);d=JSON.parse(t)}else{let c=await fetch(u);if(!c.ok)throw Error(`Failed to fetch chunk ${t}: ${c.status} ${c.statusText}`);d=await c.json()}this.chunkCache.set(t,d);for(let t of d)t._id&&this.documentCache.set(t._id,t);logger.debug(`Loaded ${d.length} documents from chunk ${t}`)}catch(c){throw logger.error(`Failed to load chunk ${t}:`,c),c}}async loadIndex(t){if(this.indexCache.has(t))return this.indexCache.get(t);let c=this.manifest.indices.find(c=>c.name===t);if(!c)throw Error(`Index ${t} not found in manifest`);try{let u=`${this.basePath}/${c.path}`;logger.debug(`Loading index from ${u}`);let d;if(this.isLocalPath(u)&&nodeFS){let t=await nodeFS.promises.readFile(u,`utf8`);d=JSON.parse(t)}else{let c=await fetch(u);if(!c.ok)throw Error(`Failed to fetch index ${t}: ${c.status} ${c.statusText}`);d=await c.json()}return this.indexCache.set(t,d),logger.debug(`Loaded index ${t}`),d}catch(c){throw logger.error(`Failed to load index ${t}:`,c),c}}async getRawDocument(t){if(this.documentCache.has(t))return this.documentCache.get(t);let c=await this.findChunkForDocument(t);if(!c)throw logger.error(`Document ${t} not found in any chunk. Available chunks:`,this.manifest.chunks.map(t=>`${t.id} (${t.docType}): ${t.startKey} - ${t.endKey}`)),Error(`Document ${t} not found in any chunk`);if(await this.loadChunk(c.id),this.documentCache.has(t))return this.documentCache.get(t);throw logger.error(`Document ${t} not found in chunk ${c.id}`),Error(`Document ${t} not found in chunk ${c.id}`)}getAttachmentUrl(t,c){return`${this.basePath}/attachments/${t}/${c}`}async getAttachmentPath(t,c){try{let u=await this.getRawDocument(t);if(u._attachments&&u._attachments[c]){let t=u._attachments[c];if(t.path)return`${this.basePath}/${t.path}`}return null}catch{return null}}async getAttachmentBlob(t,c){let u=await this.getAttachmentPath(t,c);if(!u)return null;try{if(this.isLocalPath(u)&&nodeFS)return await nodeFS.promises.readFile(u);{let d=await fetch(u);if(!d.ok)throw Error(`Failed to fetch attachment ${t}/${c}: ${d.status} ${d.statusText}`);return await d.blob()}}catch(u){return logger.error(`Failed to load attachment ${t}/${c}:`,u),null}}async hydrateAttachments(t){let c=t;if(!c._attachments)return t;let u=JSON.parse(JSON.stringify(t));for(let[t,d]of Object.entries(c._attachments)){let m=d;if(m.path)try{let d=await this.getAttachmentBlob(c._id,t);d?typeof window<`u`&&window.URL?u._attachments[t]={...m,data:d,stub:!1}:u._attachments[t]={...m,buffer:d}:logger.warn(`[hydrateAttachments] getAttachmentBlob returned null for ${c._id}/${t}. Skipping hydration for this attachment.`)}catch(u){logger.warn(`[hydrateAttachments] Failed to hydrate attachment ${c._id}/${t}:`,u)}else logger.debug(`[hydrateAttachments] Attachment ${t} for doc ${c._id} has no path. Skipping blob conversion.`)}return u}clearCaches(){this.documentCache.clear(),this.chunkCache.clear(),this.indexCache.clear()}getCacheStats(){return{documents:this.documentCache.size,chunks:this.chunkCache.size,indices:this.indexCache.size}}isLocalPath(t){return!t.startsWith(`http://`)&&!t.startsWith(`https://`)&&(pathUtils.isAbsolute(t)||t.startsWith(`./`)||t.startsWith(`../`))}}}}),init_courseDB2=__esm({"src/impl/static/courseDB.ts"(){"use strict";init_types_legacy(),init_logger(),init_defaults(),init_PipelineAssembler(),StaticCourseDB=class{constructor(t,c,u,d){_defineProperty$2(this,`_pendingHints`,null),this.courseId=t,this.unpacker=c,this.userDB=u,this.manifest=d}getCourseID(){return this.courseId}async getCourseConfig(){if(this.manifest.courseConfig!=null)return this.manifest.courseConfig;throw Error(`Course config not found for course ${this.courseId}`)}async updateCourseConfig(t){throw Error(`Cannot update course config in static mode`)}async getCourseInfo(){return{cardCount:this.manifest.chunks.filter(t=>t.docType===`CARD`).reduce((t,c)=>t+c.documentCount,0),registeredUsers:0}}async getCourseDoc(t,c){return this.unpacker.getDocument(t)}async getCourseDocs(t,c){let u=await Promise.all(t.map(async t=>{try{return{id:t,key:t,value:{rev:`1-static`},doc:await this.unpacker.getDocument(t)}}catch{return{key:t,error:`not_found`}}}));return{total_rows:t.length,offset:0,rows:u}}async getCardsByELO(t,c){return(await this.unpacker.queryByElo(t,c||25)).map(t=>{let[c,u,d]=t.split(`-`);return{courseID:c,cardID:u,elo:d?parseInt(d):void 0}})}async getCardEloData(t){return await Promise.all(t.map(async t=>{try{return(await this.unpacker.getDocument(t)).elo||{global:{score:1e3,count:0},tags:{},misc:{}}}catch{return{global:{score:1e3,count:0},tags:{},misc:{}}}}))}async updateCardElo(t,c){return{ok:!0,id:t,rev:`1-static`}}async getCardsCenteredAtELO(t,c){let u=typeof t.elo==`number`?t.elo:1e3;if(t.elo===`user`)try{let t=(await this.userDB.getCourseRegistrationsDoc()).courses.find(t=>t.courseID===this.courseId);t&&typeof t.elo==`object`&&(u=t.elo.global.score)}catch{u=1e3}else t.elo===`random`&&(u=800+Math.random()*400);let d=(await this.unpacker.queryByElo(u,t.limit*2)).map(t=>({cardID:t,courseID:this.courseId}));return c&&(d=d.filter(c)),d.slice(0,t.limit).map(t=>({status:`new`,cardID:t.cardID,contentSourceType:`course`,contentSourceID:this.courseId,courseID:this.courseId}))}async getAppliedTags(t){try{let c=await this.unpacker.getTagsIndex(),u=c.byCard[t]||[],d=await Promise.all(u.map(async u=>{let d=`TAG-${u}`;try{let c=await this.unpacker.getDocument(d);return{id:d,key:t,value:{name:c.name,snippet:c.snippet,count:c.taggedCards?.length||0}}}catch(m){if(m&&m.status===404)logger.warn(`Tag document not found for ${u}, creating stub`);else throw logger.error(`Error getting tag document for ${u}:`,m),m;return{id:d,key:t,value:{name:u,snippet:`Tag: ${u}`,count:c.byTag[u]?.length||0}}}}));return{total_rows:d.length,offset:0,rows:d}}catch(c){return logger.error(`Error getting applied tags for card ${t}:`,c),{total_rows:0,offset:0,rows:[]}}}async getAppliedTagsBatch(t){let c=await this.unpacker.getTagsIndex(),u=new Map;for(let d of t)u.set(d,c.byCard[d]||[]);return u}async getAllCardIds(){let t=await this.unpacker.getTagsIndex();return Object.keys(t.byCard)}async addTagToCard(t,c){throw Error(`Cannot modify tags in static mode`)}async removeTagFromCard(t,c){throw Error(`Cannot modify tags in static mode`)}async createTag(t){throw Error(`Cannot create tags in static mode`)}async getTag(t){return this.unpacker.getDocument(`TAG-${t}`)}async updateTag(t){throw Error(`Cannot update tags in static mode`)}async getCourseTagStubs(){try{let t=await this.unpacker.getTagsIndex();if(!t||!t.byTag)return logger.warn(`Tags index not found or empty`),{total_rows:0,offset:0,rows:[]};let c=Object.keys(t.byTag),u=await Promise.all(c.map(async c=>{let u=t.byTag[c]||[],d=`TAG-${c}`;try{return{id:d,key:d,value:{rev:`1-static`},doc:await this.unpacker.getDocument(d)}}catch(t){if(t&&t.status===404)return logger.warn(`Tag document not found for ${c}, creating stub`),{id:d,key:d,value:{rev:`1-static`},doc:{_id:d,_rev:`1-static`,course:this.courseId,docType:`TAG`,name:c,snippet:`Tag: ${c}`,wiki:``,taggedCards:u,author:`system`}};throw logger.error(`Error getting tag document for ${c}:`,t),t}}));return{total_rows:u.length,offset:0,rows:u}}catch(t){return logger.error(`Failed to get course tag stubs:`,t),{total_rows:0,offset:0,rows:[]}}}async addNote(t,c,u,d,m,g,b){return{status:Status.error,message:`Cannot add notes in static mode`}}async removeCard(t){throw Error(`Cannot remove cards in static mode`)}async getInexperiencedCards(){return[]}async getNavigationStrategy(t){try{return await this.unpacker.getDocument(t)}catch(c){throw logger.error(`[static/courseDB] Strategy ${t} not found: ${c}`),c}}async getAllNavigationStrategies(){let t=DocTypePrefixes.NAVIGATION_STRATEGY;try{return await this.unpacker.getAllDocumentsByPrefix(t)}catch(t){return logger.warn(`[static/courseDB] Error loading navigation strategies: ${t}`),[]}}async addNavigationStrategy(t){throw Error(`Cannot add navigation strategies in static mode`)}async updateNavigationStrategy(t,c){throw Error(`Cannot update navigation strategies in static mode`)}async createNavigator(t){try{let c=await this.getAllNavigationStrategies();if(c.length===0)return logger.debug(`[static/courseDB] No strategy documents found, using default Pipeline(Composite(ELO, SRS), [eloDistanceFilter])`),createDefaultPipeline(t,this);let{pipeline:u,generatorStrategies:d,filterStrategies:m,warnings:g}=await new PipelineAssembler().assemble({strategies:c,user:t,course:this});for(let t of g)logger.warn(`[PipelineAssembler] ${t}`);return u?(logger.debug(`[static/courseDB] Using assembled pipeline with ${d.length} generator(s) and ${m.length} filter(s)`),u):(logger.debug(`[static/courseDB] Pipeline assembly failed, using default pipeline`),createDefaultPipeline(t,this))}catch(t){throw logger.error(`[static/courseDB] Error creating navigator: ${t}`),t}}setEphemeralHints(t){this._pendingHints=t}async getWeightedCards(t){try{let c=await this.createNavigator(this.userDB);return this._pendingHints&&(c.setEphemeralHints(this._pendingHints),this._pendingHints=null),c.getWeightedCards(t)}catch(t){throw logger.error(`[static/courseDB] Error getting weighted cards: ${t}`),t}}getAttachmentUrl(t,c){return this.unpacker.getAttachmentUrl(t,c)}async getAttachmentBlob(t,c){return this.unpacker.getAttachmentBlob(t,c)}async searchCards(t){return[]}async find(t){return{docs:[],warning:`Find operations not supported in static mode`}}}}}),init_coursesDB=__esm({"src/impl/static/coursesDB.ts"(){"use strict";init_logger(),StaticCoursesDB=class{constructor(t,c){this.manifests=t,this.dependencyNameToCourseId=c}async getCourseConfig(t){let c=this.manifests[t];if(!c&&this.dependencyNameToCourseId){let u=this.dependencyNameToCourseId.get(t);u&&(c=this.manifests[u])}if(!c)throw logger.warn(`Course manifest for ${t} not found`),Error(`Course ${t} not found`);if(c.courseConfig)return c.courseConfig;throw logger.warn(`Course config not found in manifest for course ${t}`),Error(`Course config not found for course ${t}`)}async getCourseList(){return Object.keys(this.manifests).map(t=>({courseID:t,name:this.manifests[t].courseName}))}async disambiguateCourse(t,c){logger.warn(`Cannot disambiguate courses in static mode`)}}}}),init_NoOpSyncStrategy=__esm({"src/impl/static/NoOpSyncStrategy.ts"(){"use strict";init_common(),NoOpSyncStrategy=class{constructor(){_defineProperty$2(this,`currentUsername`,accomodateGuest().username)}setupRemoteDB(t){return getLocalUserDB(t)}getWriteDB(t){return getLocalUserDB(t)}startSync(t,c){}stopSync(){}canCreateAccount(){return!1}canAuthenticate(){return!1}async createAccount(t,c){throw Error(`Account creation not supported in static mode. Use local account switching instead.`)}async authenticate(t,c){throw Error(`Remote authentication not supported in static mode. Use local account switching instead.`)}async logout(){return this.currentUsername=accomodateGuest().username,{ok:!0}}async getCurrentUsername(){return this.currentUsername}setCurrentUsername(t){this.currentUsername=t}}}}),StaticDataLayerProvider_exports={},__export(StaticDataLayerProvider_exports,{StaticDataLayerProvider:()=>StaticDataLayerProvider}),init_StaticDataLayerProvider=__esm({"src/impl/static/StaticDataLayerProvider.ts"(){"use strict";init_logger(),init_StaticDataUnpacker(),init_courseDB2(),init_coursesDB(),init_common(),init_NoOpSyncStrategy(),StaticDataLayerProvider=class{constructor(t){_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`initialized`,!1),_defineProperty$2(this,`courseUnpackers`,new Map),_defineProperty$2(this,`manifests`,{}),_defineProperty$2(this,`dependencyNameToCourseId`,new Map),this.config={localStoragePrefix:t.localStoragePrefix||`skuilder-static`,rootManifest:t.rootManifest||{dependencies:{}},rootManifestUrl:t.rootManifestUrl||`/`}}async resolveCourseDependencies(){logger.info(`[StaticDataLayerProvider] Starting course dependency resolution...`);let t=this.config.rootManifest;for(let[c,u]of Object.entries(t.dependencies||{}))try{logger.debug(`[StaticDataLayerProvider] Resolving dependency: ${c} from ${u}`);let t=new URL(u,this.config.rootManifestUrl).href,d=await fetch(t);if(!d.ok)throw Error(`Failed to fetch course manifest for ${c}`);let m=await d.json();if(m.content&&m.content.manifest){let u=new URL(`.`,t).href,d=new URL(m.content.manifest,t).href,g=await fetch(d);if(!g.ok)throw Error(`Failed to fetch final content manifest for ${c} at ${d}`);let b=await g.json(),S=b.courseId||b.courseConfig?.courseID;if(!S)throw Error(`Course manifest for ${c} missing courseId`);this.manifests[S]=b;let C=new StaticDataUnpacker(b,u);this.courseUnpackers.set(S,C),this.dependencyNameToCourseId.set(c,S),logger.info(`[StaticDataLayerProvider] Successfully resolved and prepared course: ${c} (courseId: ${S})`)}}catch(t){logger.error(`[StaticDataLayerProvider] Failed to resolve dependency ${c}:`,t)}logger.info(`[StaticDataLayerProvider] Course dependency resolution complete.`)}async initialize(){this.initialized||(logger.info(`Initializing static data layer provider`),await this.resolveCourseDependencies(),this.initialized=!0)}async teardown(){this.courseUnpackers.clear(),this.initialized=!1}getUserDB(){let t=new NoOpSyncStrategy;return BaseUser.Dummy(t)}getCourseDB(t){let c=this.courseUnpackers.get(t),u=t;if(!c){let d=this.dependencyNameToCourseId.get(t);d&&(c=this.courseUnpackers.get(d),u=d)}if(!c)throw Error(`Course ${t} not found or failed to initialize in static data layer.`);let d=this.manifests[u];return new StaticCourseDB(u,c,this.getUserDB(),d)}getCoursesDB(){return new StaticCoursesDB(this.manifests,this.dependencyNameToCourseId)}async getClassroomDB(t,c){throw Error(`Classrooms not supported in static mode`)}getAdminDB(){throw Error(`Admin functions not supported in static mode`)}async createUserReaderForUser(t){return logger.warn(`StaticDataLayerProvider: Multi-user access not supported in static mode`),logger.warn(`Request: trying to access data for ${t}`),logger.warn(`Returning current user's data instead`),this.getUserDB()}isReadOnly(){return!0}}}}),init_factory=__esm({"src/factory.ts"(){"use strict";init_common(),init_logger(),init_navigators(),NOT_SET=`NOT_SET`,ENV={COUCHDB_SERVER_PROTOCOL:NOT_SET,COUCHDB_SERVER_URL:NOT_SET,LOCAL_STORAGE_PREFIX:``},dataLayerInstance=null}}),init_TagFilteredContentSource=__esm({"src/study/TagFilteredContentSource.ts"(){"use strict";init_courseDB(),init_logger(),TagFilteredContentSource=class{constructor(t,c,u){_defineProperty$2(this,`courseId`,void 0),_defineProperty$2(this,`filter`,void 0),_defineProperty$2(this,`user`,void 0),_defineProperty$2(this,`resolvedCardIds`,null),this.courseId=t,this.filter=c,this.user=u,logger.info(`[TagFilteredContentSource] Created for course "${t}" with filter:`,JSON.stringify(c))}async resolveFilteredCardIds(){if(this.resolvedCardIds!==null)return this.resolvedCardIds;let t=new Set;if(this.filter.include.length>0)for(let c of this.filter.include)try{(await getTag(this.courseId,c)).taggedCards.forEach(c=>t.add(c))}catch(t){logger.warn(`[TagFilteredContentSource] Could not resolve tag "${c}" for inclusion:`,t)}if(t.size===0&&this.filter.include.length>0)return logger.warn(`[TagFilteredContentSource] No cards found for include tags: ${this.filter.include.join(`, `)}`),this.resolvedCardIds=new Set,this.resolvedCardIds;let c=new Set;if(this.filter.exclude.length>0)for(let t of this.filter.exclude)try{(await getTag(this.courseId,t)).taggedCards.forEach(t=>c.add(t))}catch(c){logger.warn(`[TagFilteredContentSource] Could not resolve tag "${t}" for exclusion:`,c)}let u=new Set;for(let d of t)c.has(d)||u.add(d);return logger.info(`[TagFilteredContentSource] Resolved ${u.size} cards (included: ${t.size}, excluded: ${c.size})`),this.resolvedCardIds=u,u}async getWeightedCards(t){if(!hasActiveFilter(this.filter))return logger.warn(`[TagFilteredContentSource] getWeightedCards called with no active filter`),{cards:[]};let c=await this.resolveFilteredCardIds(),u=await this.user.getActiveCards(),d=new Set(u.map(t=>t.cardID)),m=[];for(let u of c)if(d.has(u)||m.push({cardId:u,courseId:this.courseId,score:1,provenance:[{strategy:`tagFilter`,strategyName:`Tag Filter`,strategyId:`TAG_FILTER`,action:`generated`,score:1,reason:`Tag-filtered new card (tags: ${this.filter.include.join(`, `)})`}]}),m.length>=t)break;logger.info(`[TagFilteredContentSource] Found ${m.length} new cards matching filter`);let g=await this.user.getPendingReviews(this.courseId),b=g.filter(t=>c.has(t.cardId));return logger.info(`[TagFilteredContentSource] Found ${b.length} pending reviews matching filter (of ${g.length} total)`),{cards:[...b.map(t=>({cardId:t.cardId,courseId:t.courseId,score:1,reviewID:t._id,provenance:[{strategy:`tagFilter`,strategyName:`Tag Filter`,strategyId:`TAG_FILTER`,action:`generated`,score:1,reason:`Tag-filtered review (tags: ${this.filter.include.join(`, `)})`}]})),...m].slice(0,t)}}clearCache(){this.resolvedCardIds=null}getCourseId(){return this.courseId}getFilter(){return this.filter}}}}),init_contentSource=__esm({"src/core/interfaces/contentSource.ts"(){"use strict";init_factory(),init_classroomDB2(),init_TagFilteredContentSource()}}),init_courseDB3=__esm({"src/core/interfaces/courseDB.ts"(){"use strict";}}),init_dataLayerProvider=__esm({"src/core/interfaces/dataLayerProvider.ts"(){"use strict";}}),init_userDB=__esm({"src/core/interfaces/userDB.ts"(){"use strict";}}),init_interfaces=__esm({"src/core/interfaces/index.ts"(){"use strict";init_adminDB(),init_classroomDB(),init_contentSource(),init_courseDB3(),init_dataLayerProvider(),init_userDB()}}),init_user=__esm({"src/core/types/user.ts"(){"use strict";}}),init_strategyState=__esm({"src/core/types/strategyState.ts"(){"use strict";}}),init_userOutcome=__esm({"src/core/types/userOutcome.ts"(){"use strict";}}),init_cardProcessor=__esm({"src/core/bulkImport/cardProcessor.ts"(){"use strict";init_logger()}}),init_types3=__esm({"src/core/bulkImport/types.ts"(){"use strict";}}),init_bulkImport=__esm({"src/core/bulkImport/index.ts"(){"use strict";init_cardProcessor(),init_types3()}}),init_UserDBDebugger=__esm({"src/core/UserDBDebugger.ts"(){"use strict";init_logger(),init_factory(),init_types_legacy(),init_userDBHelpers(),userDBDebugAPI={showUser(){let t=getUserDB();t&&(console.group(`👤 User Information`),logger.info(`Username: ${t.getUsername()}`),logger.info(`Logged in: ${t.isLoggedIn()?`Yes ✅`:`No (Guest) ❌`}`),t.getConfig().then(t=>{logger.info(`Configuration:`),logger.info(JSON.stringify(t,null,2))}).catch(t=>{logger.info(`Error loading config: ${t.message}`)}).finally(()=>{console.groupEnd()}))},async showScheduledReviews(t){let c=getUserDB();if(!c){logger.info(`[UserDB Debug] Data layer not available`);return}logger.info(`[UserDB Debug] Fetching pending reviews${t?` for course: ${t}`:``}...`);try{let u=await c.getPendingReviews(t);if(logger.info(`[UserDB Debug] Got ${u.length} reviews`),console.group(`\u{1F4C5} Scheduled Reviews${t?` (${t})`:``}`),logger.info(`Total: ${u.length}`),u.length>0){let t=new Map;for(let c of u)t.has(c.courseId)||t.set(c.courseId,[]),t.get(c.courseId).push(c);for(let[c,u]of t){console.group(`Course: ${c} (${u.length} reviews)`);let t=u.sort((t,c)=>{let u=typeof t.reviewTime==`string`?t.reviewTime:t.reviewTime.toISOString(),d=typeof c.reviewTime==`string`?c.reviewTime:c.reviewTime.toISOString();return new Date(u).getTime()-new Date(d).getTime()});for(let c of t.slice(0,10)){let t=typeof c.reviewTime==`string`?c.reviewTime:c.reviewTime.toISOString();logger.info(` ${c.cardId.slice(0,12)}... @ ${formatTimestamp(t)} [${c.scheduledFor}/${c.schedulingAgentId}]`)}t.length>10&&logger.info(` ... and ${t.length-10} more`),console.groupEnd()}}console.groupEnd()}catch(t){logger.info(`Error loading scheduled reviews: ${t.message}`)}},async showCourseRegistrations(){let t=getUserDB();if(t)try{let c=await t.getActiveCourses();console.group(`📚 Course Registrations`),logger.info(`Total: ${c.length}`),c.length>0&&console.table(c.map(t=>({courseId:t.courseID,status:t.status||`active`,elo:typeof t.elo==`number`?t.elo.toFixed(0):t.elo?.global?.score?.toFixed(0)||`N/A`}))),console.groupEnd()}catch(t){logger.info(`Error loading course registrations: ${t.message}`)}},async showCardHistory(t){let c=getRawDB();if(c)try{let u=(await filterAllDocsByPrefix(c,DocTypePrefixes.CARDRECORD)).rows.filter(c=>c.doc&&c.doc.cardID===t).map(t=>t.doc);if(console.group(`\u{1F3B4} Card History: ${t}`),logger.info(`Total interactions: ${u.length}`),u.length>0){let t=u.sort((t,c)=>new Date(c.timestamp).getTime()-new Date(t.timestamp).getTime());console.table(t.slice(0,20).map(t=>({time:formatTimestamp(t.timestamp),outcome:t.outcome||`N/A`,duration:t.duration?`${(t.duration/1e3).toFixed(1)}s`:`N/A`,courseId:t.courseId}))),t.length>20&&logger.info(`... and ${t.length-20} more interactions`)}console.groupEnd()}catch(t){logger.info(`Error loading card history: ${t.message}`)}},async queryByType(t,c=50){let u=getRawDB();if(u)try{let d=DocTypePrefixes[DocType[t]];if(!d){logger.info(`Unknown document type: ${t}`);return}let m=await filterAllDocsByPrefix(u,d);if(console.group(`\u{1F4C4} Documents: ${t}`),logger.info(`Total: ${m.rows.length}`),logger.info(`Prefix: ${d}`),m.rows.length>0){logger.info(`Sample documents:`);let t=m.rows.slice(0,Math.min(c,m.rows.length));for(let c of t)logger.info(`
373
373
  ${c.id}:`),logger.info(JSON.stringify(c.doc,null,2));m.rows.length>c&&logger.info(`
374
374
  ... and ${m.rows.length-c} more documents`)}console.groupEnd()}catch(t){logger.info(`Error querying documents: ${t.message}`)}},async dbInfo(){let t=getRawDB();if(t)try{let c=await t.info();console.group(`ℹ️ Database Information`),logger.info(`Database name: ${c.db_name}`),logger.info(`Total documents: ${c.doc_count}`),logger.info(`Update sequence: ${c.update_seq}`),`disk_size`in c&&logger.info(`Disk size: ${(c.disk_size||0)/1024/1024} MB`),logger.info(`
375
375
  Document counts by type:`);let u=await t.allDocs({include_docs:!1}),d=new Map;for(let t of u.rows){let c=`other`;for(let[u,d]of Object.entries(DocTypePrefixes))if(t.id.startsWith(d)){c=u;break}d.set(c,(d.get(c)||0)+1)}console.table(Array.from(d.entries()).sort((t,c)=>c[1]-t[1]).map(([t,c])=>({type:t,count:c}))),console.groupEnd()}catch(t){logger.info(`Error getting database info: ${t.message}`)}},listDocTypes(){console.group(`📋 Available Document Types`),logger.info(`Use with queryByType(type):`);for(let[t,c]of Object.entries(DocTypePrefixes))logger.info(` ${t.padEnd(30)} \u2192 prefix: "${c}"`);console.groupEnd()},async export(t=!1){let c=getRawDB(),u=getUserDB();if(!c||!u)return`{}`;try{let d={username:u.getUsername(),loggedIn:u.isLoggedIn(),timestamp:new Date().toISOString()};if(t){let t=await c.allDocs({include_docs:!0});d.documents=t.rows.map(t=>({id:t.id,doc:t.doc})),d.totalDocs=t.rows.length}else{let t=await c.allDocs({include_docs:!1});d.totalDocs=t.rows.length;let u=new Map;for(let c of t.rows){let t=`other`;for(let[u,d]of Object.entries(DocTypePrefixes))if(c.id.startsWith(d)){t=u;break}u.set(t,(u.get(t)||0)+1)}d.docCounts=Object.fromEntries(u)}let m=JSON.stringify(d,null,2);return logger.info(`[UserDB Debug] Database info exported. Copy the returned string or use:`),logger.info(` copy(window.skuilder.userdb.export())`),t||logger.info(` For full content export: window.skuilder.userdb.export(true)`),m}catch(t){return logger.info(`Error exporting database: ${t.message}`),`{}`}},async raw(t){let c=getRawDB();if(c)try{let u=await t(c);logger.info(`[UserDB Debug] Query result:`),logger.info(u)}catch(t){logger.info(`[UserDB Debug] Query error: ${t.message}`)}},help(){logger.info(`
@@ -455,7 +455,7 @@ Example:
455
455
  `;if(!c)for(let t of T){let c={cardID:t.cardId,courseID:t.courseId,contentSourceType:`course`,contentSourceID:t.courseId,reviewID:t.reviewID,status:`review`};this.reviewQ.add(c,c.cardID),D+=`Review: ${t.courseId}::${t.cardId} (score: ${t.score.toFixed(2)})
456
456
  `}let O=E.filter(t=>t.score>=_SessionController.WELL_INDICATED_SCORE).length,Or=[];for(let t of E){let c={cardID:t.cardId,courseID:t.courseId,contentSourceType:`course`,contentSourceID:t.courseId,status:`new`};Or.push(c),D+=`New: ${t.courseId}::${t.cardId} (score: ${t.score.toFixed(2)})
457
457
  `}if(u){let t=this.newQ.mergeToFront(Or,t=>t.cardID);D+=`Additive merge: ${t} new cards added to front of newQ
458
- `}else if(c)this.newQ.replaceAll(Or,t=>t.cardID);else for(let t of Or)this.newQ.add(t,t.cardID);return this.log(D),O}_getItemsToHydrate(){let t=[],c=2;for(let c=0;c<Math.min(2,this.reviewQ.length);c++)t.push(this.reviewQ.peek(c));for(let c=0;c<Math.min(2,this.newQ.length);c++)t.push(this.newQ.peek(c));for(let c=0;c<Math.min(2,this.failedQ.length);c++)t.push(this.failedQ.peek(c));return t}_selectNextItemToHydrate(){let t=Math.random(),c=.1,u=.75;if(this.reviewQ.length===0&&this.failedQ.length===0&&this.newQ.length===0||this._secondsRemaining<2&&this.failedQ.length===0&&this._minCardsGuarantee<=0)return null;if(this._secondsRemaining<=0&&this._minCardsGuarantee<=0)return this.failedQ.length>0?this.failedQ.peek(0):null;if(this.newQ.dequeueCount<this.sources.length&&this.newQ.length)return this.newQ.peek(0);let d=this.estimateCleanupTime(),m=this.estimateReviewTime();return this._secondsRemaining-(d+m)>20?(c=.5,u=.9):this._secondsRemaining-d>20?(c=.05,u=.9):(c=.01,u=.1),this.failedQ.length===0&&(u=1),this.reviewQ.length===0&&(c=u),t<c&&this.newQ.length?this.newQ.peek(0):t<u&&this.reviewQ.length?this.reviewQ.peek(0):this.failedQ.length?this.failedQ.peek(0):(this.log(`No more cards available for the session!`),null)}async nextCard(t=`dismiss-success`){if(this.dismissCurrentCard(t),this._minCardsGuarantee>0&&(this._minCardsGuarantee--,this.log(`[CardGuarantee] ${this._minCardsGuarantee} guaranteed cards remaining`)),this._replanPromise&&this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0&&(this.log(`nextCard: queues empty, awaiting in-flight replan before drawing`),await this._replanPromise),this.newQ.length<=1&&this._secondsRemaining>0&&!this._replanPromise){this._suppressQualityReplan=!1;let t=this.reviewQ.length+this.failedQ.length;this.log(`[AutoReplan:depletion] newQ has ${this.newQ.length} card(s) (${t} in other queues) with ${this._secondsRemaining}s remaining. Triggering background replan.`),this.requestReplan()}if(!this._suppressQualityReplan&&this._wellIndicatedRemaining<=3&&this.newQ.length>0&&!this._replanPromise&&(this.log(`[AutoReplan:quality] ${this._wellIndicatedRemaining} well-indicated cards remaining (newQ: ${this.newQ.length}). Triggering background replan.`),this.requestReplan()),this._secondsRemaining<=0&&this.failedQ.length===0&&this._minCardsGuarantee<=0)return this._currentCard=null,endSessionTracking(),null;let c=3,u=250,d=0;for(;this._secondsRemaining>0&&this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0;)if(this.log(`[WedgeBreaker] All queues empty with ${this._secondsRemaining}s remaining. Running pipeline (attempt ${d+1}/3).`),await this._replanUncoalesced({label:`wedge-breaker`}),this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0){if(d++,d>=3){this.log(`[WedgeBreaker] Pipeline returned no content 3 consecutive times. Giving up; session will end.`);break}await new Promise(t=>setTimeout(t,250))}else d=0;let m=20;for(let t=0;t<20;t++){let t=this._selectNextItemToHydrate();if(!t)return this._currentCard=null,endSessionTracking(),null;let c=this.hydrationService.getHydratedCard(t.cardID);if(c||(c=await this.hydrationService.waitForCard(t.cardID)),this.removeItemFromQueue(t),c){await this.hydrationService.ensureHydratedCards(),this._currentCard=c;let u=t.status===`review`||t.status===`failed-review`?`review`:t.status===`new`||t.status===`failed-new`?`new`:`failed`,d=t.status.startsWith(`failed`)?`failedQ`:t.status===`review`?`reviewQ`:`newQ`;return recordCardPresentation(t.cardID,t.courseID,this.courseNameCache.get(t.courseID),u,d),snapshotQueues(this.reviewQ.length,this.newQ.length,this.failedQ.length),c}this.log(`Skipping card ${t.cardID}: hydration failed, trying next`),isReview(t)&&this.srsService.removeReview(t.reviewID)}return this.log(`Exhausted 20 skip attempts finding a hydratable card`),this._currentCard=null,endSessionTracking(),null}async submitResponse(t,c,u,d,m,g,b,S,C){let w={...d.item};return await this.services.response.processResponse(t,c,w,u,d,m,g,b,S,C)}dismissCurrentCard(t=`dismiss-success`){if(this._currentCard)if(t===`dismiss-success`)this.hydrationService.removeCard(this._currentCard.item.cardID);else if(t===`marked-failed`){let t;t=isReview(this._currentCard.item)?{cardID:this._currentCard.item.cardID,courseID:this._currentCard.item.courseID,contentSourceID:this._currentCard.item.contentSourceID,contentSourceType:this._currentCard.item.contentSourceType,status:`failed-review`,reviewID:this._currentCard.item.reviewID}:{cardID:this._currentCard.item.cardID,courseID:this._currentCard.item.courseID,contentSourceID:this._currentCard.item.contentSourceID,contentSourceType:this._currentCard.item.contentSourceType,status:`failed-new`},this.failedQ.add(t,t.cardID)}else (t===`dismiss-error`||t===`dismiss-failed`)&&this.hydrationService.removeCard(this._currentCard.item.cardID)}removeItemFromQueue(t){this.reviewQ.peek(0)?.cardID===t.cardID?this.reviewQ.dequeue(t=>t.cardID):this.newQ.peek(0)?.cardID===t.cardID?(this.newQ.dequeue(t=>t.cardID),this._wellIndicatedRemaining>0&&this._wellIndicatedRemaining--):this.failedQ.peek(0)?.cardID===t.cardID&&this.failedQ.dequeue(t=>t.cardID)}async endSession(){if(!this._sessionRecord||this._sessionRecord.length===0)return;let t=this._sessionRecord.flatMap(t=>t.records).filter(t=>t.userAnswer!==void 0);if(t.length===0)return;let c=null,u=[];for(let t of this.sources)if(t.getOrchestrationContext){try{c=await t.getOrchestrationContext(),t.getStrategyIds&&u.push(...t.getStrategyIds())}catch(t){logger.warn(`[SessionController] Failed to get orchestration context: ${t}`)}if(c)break}if(!c){logger.debug(`[SessionController] No orchestration context available, skipping outcome recording`);return}let d=new Date().toISOString(),m=new Date(this.startTime).toISOString();await recordUserOutcome(c,m,d,t,u)}},_defineProperty$2(_SessionController2,`MIN_WELL_INDICATED`,5),_defineProperty$2(_SessionController2,`WELL_INDICATED_SCORE`,.1),_SessionController2),init_TagFilteredContentSource(),init_factory()}));function useRouter(){return inject(routerKey)}function useRoute(t){return inject(routeLocationKey)}var isArray,NavigationType,NavigationDirection,NavigationFailureSymbol,NavigationFailureType,matchedRouteKey,viewDepthKey,routerKey,routeLocationKey,routerViewLocationKey,init_vue_router=__esmMin((()=>{init_vue_runtime_esm_bundler(),Array.isArray,(function(t){t.pop=`pop`,t.push=`push`})(NavigationType||(NavigationType={})),(function(t){t.back=`back`,t.forward=`forward`,t.unknown=``})(NavigationDirection||(NavigationDirection={})),Symbol(process.env.NODE_ENV===`production`?``:`navigation failure`),(function(t){t[t.aborted=4]=`aborted`,t[t.cancelled=8]=`cancelled`,t[t.duplicated=16]=`duplicated`})(NavigationFailureType||(NavigationFailureType={})),Symbol(process.env.NODE_ENV===`production`?``:`router view location matched`),Symbol(process.env.NODE_ENV===`production`?``:`router view depth`),routerKey=Symbol(process.env.NODE_ENV===`production`?``:`router`),routeLocationKey=Symbol(process.env.NODE_ENV===`production`?``:`route location`),Symbol(process.env.NODE_ENV===`production`?``:`router view location`)})),init_style=__esmMin((()=>{}));function registerRuntimeHelpers(t){Object.getOwnPropertySymbols(t).forEach(c=>{helperNameMap[c]=t[c]})}function createRoot(t,c=``){return{type:0,source:c,children:t,helpers:new Set,components:[],directives:[],hoists:[],imports:[],cached:[],temps:0,codegenNode:void 0,loc:locStub}}function createVNodeCall(t,c,u,d,m,g,b,S=!1,C=!1,w=!1,T=locStub){return t&&(S?(t.helper(OPEN_BLOCK),t.helper(getVNodeBlockHelper(t.inSSR,w))):t.helper(getVNodeHelper(t.inSSR,w)),b&&t.helper(WITH_DIRECTIVES)),{type:13,tag:c,props:u,children:d,patchFlag:m,dynamicProps:g,directives:b,isBlock:S,disableTracking:C,isComponent:w,loc:T}}function createArrayExpression(t,c=locStub){return{type:17,loc:c,elements:t}}function createObjectExpression(t,c=locStub){return{type:15,loc:c,properties:t}}function createObjectProperty(t,c){return{type:16,loc:locStub,key:isString$1(t)?createSimpleExpression(t,!0):t,value:c}}function createSimpleExpression(t,c=!1,u=locStub,d=0){return{type:4,loc:u,content:t,isStatic:c,constType:c?3:d}}function createInterpolation(t,c){return{type:5,loc:c,content:isString$1(t)?createSimpleExpression(t,!1,c):t}}function createCompoundExpression(t,c=locStub){return{type:8,loc:c,children:t}}function createCallExpression(t,c=[],u=locStub){return{type:14,loc:u,callee:t,arguments:c}}function createFunctionExpression(t,c=void 0,u=!1,d=!1,m=locStub){return{type:18,params:t,returns:c,newline:u,isSlot:d,loc:m}}function createConditionalExpression(t,c,u,d=!0){return{type:19,test:t,consequent:c,alternate:u,newline:d,loc:locStub}}function createCacheExpression(t,c,u=!1,d=!1){return{type:20,index:t,value:c,needPauseTracking:u,inVOnce:d,needArraySpread:!1,loc:locStub}}function createBlockStatement(t){return{type:21,body:t,loc:locStub}}function createTemplateLiteral(t){return{type:22,elements:t,loc:locStub}}function createIfStatement(t,c,u){return{type:23,test:t,consequent:c,alternate:u,loc:locStub}}function createAssignmentExpression(t,c){return{type:24,left:t,right:c,loc:locStub}}function createSequenceExpression(t){return{type:25,expressions:t,loc:locStub}}function createReturnStatement(t){return{type:26,returns:t,loc:locStub}}function getVNodeHelper(t,c){return t||c?CREATE_VNODE:CREATE_ELEMENT_VNODE}function getVNodeBlockHelper(t,c){return t||c?CREATE_BLOCK:CREATE_ELEMENT_BLOCK}function convertToBlock(t,{helper:c,removeHelper:u,inSSR:d}){t.isBlock||(t.isBlock=!0,u(getVNodeHelper(d,t.isComponent)),c(OPEN_BLOCK),c(getVNodeBlockHelper(d,t.isComponent)))}function isTagStartChar(t){return t>=97&&t<=122||t>=65&&t<=90}function isWhitespace(t){return t===32||t===10||t===9||t===12||t===13}function isEndOfTagSection(t){return t===47||t===62||isWhitespace(t)}function toCharCodes(t){let c=new Uint8Array(t.length);for(let u=0;u<t.length;u++)c[u]=t.charCodeAt(u);return c}function getCompatValue(t,{compatConfig:c}){let u=c&&c[t];return t===`MODE`?u||3:u}function isCompatEnabled(t,c){let u=getCompatValue(`MODE`,c),d=getCompatValue(t,c);return u===3?d===!0:d!==!1}function checkCompatEnabled(t,c,u,...d){let m=isCompatEnabled(t,c);return process.env.NODE_ENV!==`production`&&m&&warnDeprecation(t,c,u,...d),m}function warnDeprecation(t,c,u,...d){if(getCompatValue(t,c)===`suppress-warning`)return;let{message:m,link:g}=deprecationData[t],b=`(deprecation ${t}) ${typeof m==`function`?m(...d):m}${g?`
458
+ `}else if(c)this.newQ.replaceAll(Or,t=>t.cardID);else for(let t of Or)this.newQ.add(t,t.cardID);return this.log(D),O}_getItemsToHydrate(){let t=[],c=2;for(let c=0;c<Math.min(2,this.reviewQ.length);c++)t.push(this.reviewQ.peek(c));for(let c=0;c<Math.min(2,this.newQ.length);c++)t.push(this.newQ.peek(c));for(let c=0;c<Math.min(2,this.failedQ.length);c++)t.push(this.failedQ.peek(c));return t}_selectNextItemToHydrate(){let t=Math.random(),c=.1,u=.75;if(this.reviewQ.length===0&&this.failedQ.length===0&&this.newQ.length===0||this._secondsRemaining<2&&this.failedQ.length===0&&this._minCardsGuarantee<=0)return null;if(this._secondsRemaining<=0&&this._minCardsGuarantee<=0)return this.failedQ.length>0?this.failedQ.peek(0):null;if(this.newQ.dequeueCount<this.sources.length&&this.newQ.length)return this.newQ.peek(0);let d=this.estimateCleanupTime(),m=this.estimateReviewTime();return this._secondsRemaining-(d+m)>20?(c=.5,u=.9):this._secondsRemaining-d>20?(c=.05,u=.9):(c=.01,u=.1),this.failedQ.length===0&&(u=1),this.reviewQ.length===0&&(c=u),t<c&&this.newQ.length?this.newQ.peek(0):t<u&&this.reviewQ.length?this.reviewQ.peek(0):this.failedQ.length?this.failedQ.peek(0):(this.log(`No more cards available for the session!`),null)}async nextCard(t=`dismiss-success`){if(this.dismissCurrentCard(t),this._minCardsGuarantee>0&&(this._minCardsGuarantee--,this.log(`[CardGuarantee] ${this._minCardsGuarantee} guaranteed cards remaining`)),this._replanPromise&&this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0&&(this.log(`nextCard: queues empty, awaiting in-flight replan before drawing`),await this._replanPromise),this.newQ.length<=_SessionController.DEPLETION_PREFETCH_THRESHOLD&&this._secondsRemaining>0&&!this._replanPromise){this._suppressQualityReplan=!1;let t=this.reviewQ.length+this.failedQ.length;this.log(`[AutoReplan:depletion] newQ has ${this.newQ.length} card(s) (${t} in other queues) with ${this._secondsRemaining}s remaining. Triggering background replan.`),this.requestReplan()}if(!this._suppressQualityReplan&&this._wellIndicatedRemaining<=3&&this.newQ.length>0&&!this._replanPromise&&(this.log(`[AutoReplan:quality] ${this._wellIndicatedRemaining} well-indicated cards remaining (newQ: ${this.newQ.length}). Triggering background replan.`),this.requestReplan()),this._secondsRemaining<=0&&this.failedQ.length===0&&this._minCardsGuarantee<=0)return this._currentCard=null,endSessionTracking(),null;let c=3,u=250,d=0;for(;this._secondsRemaining>0&&this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0;)if(this.log(`[WedgeBreaker] All queues empty with ${this._secondsRemaining}s remaining. Running pipeline (attempt ${d+1}/3).`),await this._replanUncoalesced({label:`wedge-breaker`}),this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0){if(d++,d>=3){this.log(`[WedgeBreaker] Pipeline returned no content 3 consecutive times. Giving up; session will end.`);break}await new Promise(t=>setTimeout(t,250))}else d=0;let m=20;for(let t=0;t<20;t++){let t=this._selectNextItemToHydrate();if(!t)return this._currentCard=null,endSessionTracking(),null;let c=this.hydrationService.getHydratedCard(t.cardID);if(c||(c=await this.hydrationService.waitForCard(t.cardID)),this.removeItemFromQueue(t),c){await this.hydrationService.ensureHydratedCards(),this._currentCard=c;let u=t.status===`review`||t.status===`failed-review`?`review`:t.status===`new`||t.status===`failed-new`?`new`:`failed`,d=t.status.startsWith(`failed`)?`failedQ`:t.status===`review`?`reviewQ`:`newQ`;return recordCardPresentation(t.cardID,t.courseID,this.courseNameCache.get(t.courseID),u,d),snapshotQueues(this.reviewQ.length,this.newQ.length,this.failedQ.length),c}this.log(`Skipping card ${t.cardID}: hydration failed, trying next`),isReview(t)&&this.srsService.removeReview(t.reviewID)}return this.log(`Exhausted 20 skip attempts finding a hydratable card`),this._currentCard=null,endSessionTracking(),null}async submitResponse(t,c,u,d,m,g,b,S,C){let w={...d.item};return await this.services.response.processResponse(t,c,w,u,d,m,g,b,S,C)}dismissCurrentCard(t=`dismiss-success`){if(this._currentCard)if(t===`dismiss-success`)this.hydrationService.removeCard(this._currentCard.item.cardID);else if(t===`marked-failed`){let t;t=isReview(this._currentCard.item)?{cardID:this._currentCard.item.cardID,courseID:this._currentCard.item.courseID,contentSourceID:this._currentCard.item.contentSourceID,contentSourceType:this._currentCard.item.contentSourceType,status:`failed-review`,reviewID:this._currentCard.item.reviewID}:{cardID:this._currentCard.item.cardID,courseID:this._currentCard.item.courseID,contentSourceID:this._currentCard.item.contentSourceID,contentSourceType:this._currentCard.item.contentSourceType,status:`failed-new`},this.failedQ.add(t,t.cardID)}else (t===`dismiss-error`||t===`dismiss-failed`)&&this.hydrationService.removeCard(this._currentCard.item.cardID)}removeItemFromQueue(t){this.reviewQ.peek(0)?.cardID===t.cardID?this.reviewQ.dequeue(t=>t.cardID):this.newQ.peek(0)?.cardID===t.cardID?(this.newQ.dequeue(t=>t.cardID),this._wellIndicatedRemaining>0&&this._wellIndicatedRemaining--):this.failedQ.peek(0)?.cardID===t.cardID&&this.failedQ.dequeue(t=>t.cardID)}async endSession(){if(!this._sessionRecord||this._sessionRecord.length===0)return;let t=this._sessionRecord.flatMap(t=>t.records).filter(t=>t.userAnswer!==void 0);if(t.length===0)return;let c=null,u=[];for(let t of this.sources)if(t.getOrchestrationContext){try{c=await t.getOrchestrationContext(),t.getStrategyIds&&u.push(...t.getStrategyIds())}catch(t){logger.warn(`[SessionController] Failed to get orchestration context: ${t}`)}if(c)break}if(!c){logger.debug(`[SessionController] No orchestration context available, skipping outcome recording`);return}let d=new Date().toISOString(),m=new Date(this.startTime).toISOString();await recordUserOutcome(c,m,d,t,u)}},_defineProperty$2(_SessionController2,`MIN_WELL_INDICATED`,5),_defineProperty$2(_SessionController2,`WELL_INDICATED_SCORE`,.1),_defineProperty$2(_SessionController2,`DEPLETION_PREFETCH_THRESHOLD`,3),_SessionController2),init_TagFilteredContentSource(),init_factory()}));function useRouter(){return inject(routerKey)}function useRoute(t){return inject(routeLocationKey)}var isArray,NavigationType,NavigationDirection,NavigationFailureSymbol,NavigationFailureType,matchedRouteKey,viewDepthKey,routerKey,routeLocationKey,routerViewLocationKey,init_vue_router=__esmMin((()=>{init_vue_runtime_esm_bundler(),Array.isArray,(function(t){t.pop=`pop`,t.push=`push`})(NavigationType||(NavigationType={})),(function(t){t.back=`back`,t.forward=`forward`,t.unknown=``})(NavigationDirection||(NavigationDirection={})),Symbol(process.env.NODE_ENV===`production`?``:`navigation failure`),(function(t){t[t.aborted=4]=`aborted`,t[t.cancelled=8]=`cancelled`,t[t.duplicated=16]=`duplicated`})(NavigationFailureType||(NavigationFailureType={})),Symbol(process.env.NODE_ENV===`production`?``:`router view location matched`),Symbol(process.env.NODE_ENV===`production`?``:`router view depth`),routerKey=Symbol(process.env.NODE_ENV===`production`?``:`router`),routeLocationKey=Symbol(process.env.NODE_ENV===`production`?``:`route location`),Symbol(process.env.NODE_ENV===`production`?``:`router view location`)})),init_style=__esmMin((()=>{}));function registerRuntimeHelpers(t){Object.getOwnPropertySymbols(t).forEach(c=>{helperNameMap[c]=t[c]})}function createRoot(t,c=``){return{type:0,source:c,children:t,helpers:new Set,components:[],directives:[],hoists:[],imports:[],cached:[],temps:0,codegenNode:void 0,loc:locStub}}function createVNodeCall(t,c,u,d,m,g,b,S=!1,C=!1,w=!1,T=locStub){return t&&(S?(t.helper(OPEN_BLOCK),t.helper(getVNodeBlockHelper(t.inSSR,w))):t.helper(getVNodeHelper(t.inSSR,w)),b&&t.helper(WITH_DIRECTIVES)),{type:13,tag:c,props:u,children:d,patchFlag:m,dynamicProps:g,directives:b,isBlock:S,disableTracking:C,isComponent:w,loc:T}}function createArrayExpression(t,c=locStub){return{type:17,loc:c,elements:t}}function createObjectExpression(t,c=locStub){return{type:15,loc:c,properties:t}}function createObjectProperty(t,c){return{type:16,loc:locStub,key:isString$1(t)?createSimpleExpression(t,!0):t,value:c}}function createSimpleExpression(t,c=!1,u=locStub,d=0){return{type:4,loc:u,content:t,isStatic:c,constType:c?3:d}}function createInterpolation(t,c){return{type:5,loc:c,content:isString$1(t)?createSimpleExpression(t,!1,c):t}}function createCompoundExpression(t,c=locStub){return{type:8,loc:c,children:t}}function createCallExpression(t,c=[],u=locStub){return{type:14,loc:u,callee:t,arguments:c}}function createFunctionExpression(t,c=void 0,u=!1,d=!1,m=locStub){return{type:18,params:t,returns:c,newline:u,isSlot:d,loc:m}}function createConditionalExpression(t,c,u,d=!0){return{type:19,test:t,consequent:c,alternate:u,newline:d,loc:locStub}}function createCacheExpression(t,c,u=!1,d=!1){return{type:20,index:t,value:c,needPauseTracking:u,inVOnce:d,needArraySpread:!1,loc:locStub}}function createBlockStatement(t){return{type:21,body:t,loc:locStub}}function createTemplateLiteral(t){return{type:22,elements:t,loc:locStub}}function createIfStatement(t,c,u){return{type:23,test:t,consequent:c,alternate:u,loc:locStub}}function createAssignmentExpression(t,c){return{type:24,left:t,right:c,loc:locStub}}function createSequenceExpression(t){return{type:25,expressions:t,loc:locStub}}function createReturnStatement(t){return{type:26,returns:t,loc:locStub}}function getVNodeHelper(t,c){return t||c?CREATE_VNODE:CREATE_ELEMENT_VNODE}function getVNodeBlockHelper(t,c){return t||c?CREATE_BLOCK:CREATE_ELEMENT_BLOCK}function convertToBlock(t,{helper:c,removeHelper:u,inSSR:d}){t.isBlock||(t.isBlock=!0,u(getVNodeHelper(d,t.isComponent)),c(OPEN_BLOCK),c(getVNodeBlockHelper(d,t.isComponent)))}function isTagStartChar(t){return t>=97&&t<=122||t>=65&&t<=90}function isWhitespace(t){return t===32||t===10||t===9||t===12||t===13}function isEndOfTagSection(t){return t===47||t===62||isWhitespace(t)}function toCharCodes(t){let c=new Uint8Array(t.length);for(let u=0;u<t.length;u++)c[u]=t.charCodeAt(u);return c}function getCompatValue(t,{compatConfig:c}){let u=c&&c[t];return t===`MODE`?u||3:u}function isCompatEnabled(t,c){let u=getCompatValue(`MODE`,c),d=getCompatValue(t,c);return u===3?d===!0:d!==!1}function checkCompatEnabled(t,c,u,...d){let m=isCompatEnabled(t,c);return process.env.NODE_ENV!==`production`&&m&&warnDeprecation(t,c,u,...d),m}function warnDeprecation(t,c,u,...d){if(getCompatValue(t,c)===`suppress-warning`)return;let{message:m,link:g}=deprecationData[t],b=`(deprecation ${t}) ${typeof m==`function`?m(...d):m}${g?`
459
459
  Details: ${g}`:``}`,S=SyntaxError(b);S.code=t,u&&(S.loc=u),c.onWarn(S)}function defaultOnError(t){throw t}function defaultOnWarn(t){process.env.NODE_ENV!==`production`&&console.warn(`[Vue warn] ${t.message}`)}function createCompilerError(t,c,u,d){let m=process.env.NODE_ENV===`production`?`https://vuejs.org/error-reference/#compiler-${t}`:(u||errorMessages)[t]+(d||``),g=SyntaxError(String(m));return g.code=t,g.loc=c,g}function walkIdentifiers(t,c,u=!1,d=[],m=Object.create(null)){}function isReferencedIdentifier(t,c,u){return!1}function isInDestructureAssignment(t,c){if(t&&(t.type===`ObjectProperty`||t.type===`ArrayPattern`)){let t=c.length;for(;t--;){let u=c[t];if(u.type===`AssignmentExpression`)return!0;if(u.type!==`ObjectProperty`&&!u.type.endsWith(`Pattern`))break}}return!1}function isInNewExpression(t){let c=t.length;for(;c--;){let u=t[c];if(u.type===`NewExpression`)return!0;if(u.type!==`MemberExpression`)break}return!1}function walkFunctionParams(t,c){for(let u of t.params)for(let t of extractIdentifiers(u))c(t)}function walkBlockDeclarations(t,c){for(let u of t.body)if(u.type===`VariableDeclaration`){if(u.declare)continue;for(let t of u.declarations)for(let u of extractIdentifiers(t.id))c(u)}else if(u.type===`FunctionDeclaration`||u.type===`ClassDeclaration`){if(u.declare||!u.id)continue;c(u.id)}else isForStatement(u)&&walkForStatement(u,!0,c)}function isForStatement(t){return t.type===`ForOfStatement`||t.type===`ForInStatement`||t.type===`ForStatement`}function walkForStatement(t,c,u){let d=t.type===`ForStatement`?t.init:t.left;if(d&&d.type===`VariableDeclaration`&&(d.kind===`var`?c:!c))for(let t of d.declarations)for(let c of extractIdentifiers(t.id))u(c)}function extractIdentifiers(t,c=[]){switch(t.type){case`Identifier`:c.push(t);break;case`MemberExpression`:let u=t;for(;u.type===`MemberExpression`;)u=u.object;c.push(u);break;case`ObjectPattern`:for(let u of t.properties)u.type===`RestElement`?extractIdentifiers(u.argument,c):extractIdentifiers(u.value,c);break;case`ArrayPattern`:t.elements.forEach(t=>{t&&extractIdentifiers(t,c)});break;case`RestElement`:extractIdentifiers(t.argument,c);break;case`AssignmentPattern`:extractIdentifiers(t.left,c);break}return c}function unwrapTSNode(t){return TS_NODE_TYPES.includes(t.type)?unwrapTSNode(t.expression):t}function isCoreComponent(t){switch(t){case`Teleport`:case`teleport`:return TELEPORT;case`Suspense`:case`suspense`:return SUSPENSE;case`KeepAlive`:case`keep-alive`:return KEEP_ALIVE;case`BaseTransition`:case`base-transition`:return BASE_TRANSITION}}function advancePositionWithClone(t,c,u=c.length){return advancePositionWithMutation({offset:t.offset,line:t.line,column:t.column},c,u)}function advancePositionWithMutation(t,c,u=c.length){let d=0,m=-1;for(let t=0;t<u;t++)c.charCodeAt(t)===10&&(d++,m=t);return t.offset+=u,t.line+=d,t.column=m===-1?t.column+u:u-m,t}function assert(t,c){if(!t)throw Error(c||`unexpected compiler condition`)}function findDir(t,c,u=!1){for(let d=0;d<t.props.length;d++){let m=t.props[d];if(m.type===7&&(u||m.exp)&&(isString$1(c)?m.name===c:c.test(m.name)))return m}}function findProp(t,c,u=!1,d=!1){for(let m=0;m<t.props.length;m++){let g=t.props[m];if(g.type===6){if(u)continue;if(g.name===c&&(g.value||d))return g}else if(g.name===`bind`&&(g.exp||d)&&isStaticArgOf(g.arg,c))return g}}function isStaticArgOf(t,c){return!!(t&&isStaticExp(t)&&t.content===c)}function hasDynamicKeyVBind(t){return t.props.some(t=>t.type===7&&t.name===`bind`&&(!t.arg||t.arg.type!==4||!t.arg.isStatic))}function isText$1(t){return t.type===5||t.type===2}function isVSlot(t){return t.type===7&&t.name===`slot`}function isTemplateNode(t){return t.type===1&&t.tagType===3}function isSlotOutlet(t){return t.type===1&&t.tagType===2}function getUnnormalizedProps(t,c=[]){if(t&&!isString$1(t)&&t.type===14){let u=t.callee;if(!isString$1(u)&&propsHelperSet.has(u))return getUnnormalizedProps(t.arguments[0],c.concat(t))}return[t,c]}function injectProp(t,c,u){let d,m=t.type===13?t.props:t.arguments[2],g=[],b;if(m&&!isString$1(m)&&m.type===14){let t=getUnnormalizedProps(m);m=t[0],g=t[1],b=g[g.length-1]}if(m==null||isString$1(m))d=createObjectExpression([c]);else if(m.type===14){let t=m.arguments[0];!isString$1(t)&&t.type===15?hasProp(c,t)||t.properties.unshift(c):m.callee===TO_HANDLERS?d=createCallExpression(u.helper(MERGE_PROPS),[createObjectExpression([c]),m]):m.arguments.unshift(createObjectExpression([c])),!d&&(d=m)}else m.type===15?(hasProp(c,m)||m.properties.unshift(c),d=m):(d=createCallExpression(u.helper(MERGE_PROPS),[createObjectExpression([c]),m]),b&&b.callee===GUARD_REACTIVE_PROPS&&(b=g[g.length-2]));t.type===13?b?b.arguments[0]=d:t.props=d:b?b.arguments[0]=d:t.arguments[2]=d}function hasProp(t,c){let u=!1;if(t.key.type===4){let d=t.key.content;u=c.properties.some(t=>t.key.type===4&&t.key.content===d)}return u}function toValidAssetId(t,c){return`_${c}_${t.replace(/[^\w]/g,(c,u)=>c===`-`?`_`:t.charCodeAt(u).toString())}`}function hasScopeRef(t,c){if(!t||Object.keys(c).length===0)return!1;switch(t.type){case 1:for(let u=0;u<t.props.length;u++){let d=t.props[u];if(d.type===7&&(hasScopeRef(d.arg,c)||hasScopeRef(d.exp,c)))return!0}return t.children.some(t=>hasScopeRef(t,c));case 11:return hasScopeRef(t.source,c)?!0:t.children.some(t=>hasScopeRef(t,c));case 9:return t.branches.some(t=>hasScopeRef(t,c));case 10:return hasScopeRef(t.condition,c)?!0:t.children.some(t=>hasScopeRef(t,c));case 4:return!t.isStatic&&isSimpleIdentifier(t.content)&&!!c[t.content];case 8:return t.children.some(t=>isObject$1(t)&&hasScopeRef(t,c));case 5:case 12:return hasScopeRef(t.content,c);case 2:case 3:case 20:return!1;default:return process.env.NODE_ENV,!1}}function getMemoedVNodeCall(t){return t.type===14&&t.callee===WITH_MEMO?t.arguments[1].returns:t}function parseForExpression(t){let c=t.loc,u=t.content,d=u.match(forAliasRE);if(!d)return;let[,m,g]=d,createAliasExpression=(t,u,d=!1)=>{let m=c.start.offset+u;return createExp(t,!1,getLoc(m,m+t.length),0,d?1:0)},b={source:createAliasExpression(g.trim(),u.indexOf(g,m.length)),value:void 0,key:void 0,index:void 0,finalized:!1},S=m.trim().replace(stripParensRE,``).trim(),C=m.indexOf(S),w=S.match(forIteratorRE);if(w){S=S.replace(forIteratorRE,``).trim();let t=w[1].trim(),c;if(t&&(c=u.indexOf(t,C+S.length),b.key=createAliasExpression(t,c,!0)),w[2]){let d=w[2].trim();d&&(b.index=createAliasExpression(d,u.indexOf(d,b.key?c+t.length:C+S.length),!0))}}return S&&(b.value=createAliasExpression(S,C,!0)),b}function getSlice(t,c){return currentInput.slice(t,c)}function endOpenTag(t){tokenizer.inSFCRoot&&(currentOpenTag.innerLoc=getLoc(t+1,t+1)),addNode(currentOpenTag);let{tag:c,ns:u}=currentOpenTag;u===0&&currentOptions.isPreTag(c)&&inPre++,currentOptions.isVoidTag(c)?onCloseTag(currentOpenTag,t):(stack.unshift(currentOpenTag),(u===1||u===2)&&(tokenizer.inXML=!0)),currentOpenTag=null}function onText(t,c,u){{let c=stack[0]&&stack[0].tag;c!==`script`&&c!==`style`&&t.includes(`&`)&&(t=currentOptions.decodeEntities(t,!1))}let d=stack[0]||currentRoot,m=d.children[d.children.length-1];m&&m.type===2?(m.content+=t,setLocEnd(m.loc,u)):d.children.push({type:2,content:t,loc:getLoc(c,u)})}function onCloseTag(t,c,u=!1){u?setLocEnd(t.loc,backTrack(c,60)):setLocEnd(t.loc,lookAhead(c,62)+1),tokenizer.inSFCRoot&&(t.children.length?t.innerLoc.end=extend$2({},t.children[t.children.length-1].loc.end):t.innerLoc.end=extend$2({},t.innerLoc.start),t.innerLoc.source=getSlice(t.innerLoc.start.offset,t.innerLoc.end.offset));let{tag:d,ns:m,children:g}=t;if(inVPre||(d===`slot`?t.tagType=2:isFragmentTemplate(t)?t.tagType=3:isComponent(t)&&(t.tagType=1)),tokenizer.inRCDATA||(t.children=condenseWhitespace(g)),m===0&&currentOptions.isIgnoreNewlineTag(d)){let t=g[0];t&&t.type===2&&(t.content=t.content.replace(/^\r?\n/,``))}m===0&&currentOptions.isPreTag(d)&&inPre--,currentVPreBoundary===t&&(inVPre=tokenizer.inVPre=!1,currentVPreBoundary=null),tokenizer.inXML&&(stack[0]?stack[0].ns:currentOptions.ns)===0&&(tokenizer.inXML=!1);{let c=t.props;if(process.env.NODE_ENV!==`production`&&isCompatEnabled(`COMPILER_V_IF_V_FOR_PRECEDENCE`,currentOptions)){let u=!1,d=!1;for(let m=0;m<c.length;m++){let g=c[m];if(g.type===7&&(g.name===`if`?u=!0:g.name===`for`&&(d=!0)),u&&d){warnDeprecation(`COMPILER_V_IF_V_FOR_PRECEDENCE`,currentOptions,t.loc);break}}}if(!tokenizer.inSFCRoot&&isCompatEnabled(`COMPILER_NATIVE_TEMPLATE`,currentOptions)&&t.tag===`template`&&!isFragmentTemplate(t)){process.env.NODE_ENV!==`production`&&warnDeprecation(`COMPILER_NATIVE_TEMPLATE`,currentOptions,t.loc);let c=stack[0]||currentRoot,u=c.children.indexOf(t);c.children.splice(u,1,...t.children)}let u=c.find(t=>t.type===6&&t.name===`inline-template`);u&&checkCompatEnabled(`COMPILER_INLINE_TEMPLATE`,currentOptions,u.loc)&&t.children.length&&(u.value={type:2,content:getSlice(t.children[0].loc.start.offset,t.children[t.children.length-1].loc.end.offset),loc:u.loc})}}function lookAhead(t,c){let u=t;for(;currentInput.charCodeAt(u)!==c&&u<currentInput.length-1;)u++;return u}function backTrack(t,c){let u=t;for(;currentInput.charCodeAt(u)!==c&&u>=0;)u--;return u}function isFragmentTemplate({tag:t,props:c}){if(t===`template`){for(let t=0;t<c.length;t++)if(c[t].type===7&&specialTemplateDir.has(c[t].name))return!0}return!1}function isComponent({tag:t,props:c}){if(currentOptions.isCustomElement(t))return!1;if(t===`component`||isUpperCase(t.charCodeAt(0))||isCoreComponent(t)||currentOptions.isBuiltInComponent&&currentOptions.isBuiltInComponent(t)||currentOptions.isNativeTag&&!currentOptions.isNativeTag(t))return!0;for(let t=0;t<c.length;t++){let u=c[t];if(u.type===6){if(u.name===`is`&&u.value&&(u.value.content.startsWith(`vue:`)||checkCompatEnabled(`COMPILER_IS_ON_ELEMENT`,currentOptions,u.loc)))return!0}else if(u.name===`bind`&&isStaticArgOf(u.arg,`is`)&&checkCompatEnabled(`COMPILER_IS_ON_ELEMENT`,currentOptions,u.loc))return!0}return!1}function isUpperCase(t){return t>64&&t<91}function condenseWhitespace(t,c){let u=currentOptions.whitespace!==`preserve`,d=!1;for(let c=0;c<t.length;c++){let m=t[c];if(m.type===2)if(inPre)m.content=m.content.replace(windowsNewlineRE,`
460
460
  `);else if(isAllWhitespace(m.content)){let g=t[c-1]&&t[c-1].type,b=t[c+1]&&t[c+1].type;!g||!b||u&&(g===3&&(b===3||b===1)||g===1&&(b===3||b===1&&hasNewlineChar(m.content)))?(d=!0,t[c]=null):m.content=` `}else u&&(m.content=condense(m.content))}return d?t.filter(Boolean):t}function isAllWhitespace(t){for(let c=0;c<t.length;c++)if(!isWhitespace(t.charCodeAt(c)))return!1;return!0}function hasNewlineChar(t){for(let c=0;c<t.length;c++){let u=t.charCodeAt(c);if(u===10||u===13)return!0}return!1}function condense(t){let c=``,u=!1;for(let d=0;d<t.length;d++)isWhitespace(t.charCodeAt(d))?u||(c+=` `,u=!0):(c+=t[d],u=!1);return c}function addNode(t){(stack[0]||currentRoot).children.push(t)}function getLoc(t,c){return{start:tokenizer.getPos(t),end:c==null?c:tokenizer.getPos(c),source:c==null?c:getSlice(t,c)}}function cloneLoc(t){return getLoc(t.start.offset,t.end.offset)}function setLocEnd(t,c){t.end=tokenizer.getPos(c),t.source=getSlice(t.start.offset,c)}function dirToAttr(t){let c={type:6,name:t.rawName,nameLoc:getLoc(t.loc.start.offset,t.loc.start.offset+t.rawName.length),value:void 0,loc:t.loc};if(t.exp){let u=t.exp.loc;u.end.offset<t.loc.end.offset&&(u.start.offset--,u.start.column--,u.end.offset++,u.end.column++),c.value={type:2,content:t.exp.content,loc:u}}return c}function createExp(t,c=!1,u,d=0,m=0){return createSimpleExpression(t,c,u,d)}function emitError(t,c,u){currentOptions.onError(createCompilerError(t,getLoc(c,c),void 0,u))}function reset(){tokenizer.reset(),currentOpenTag=null,currentProp=null,currentAttrValue=``,currentAttrStartIndex=-1,currentAttrEndIndex=-1,stack.length=0}function baseParse(t,c){if(reset(),currentInput=t,currentOptions=extend$2({},defaultParserOptions),c){let t;for(t in c)c[t]!=null&&(currentOptions[t]=c[t])}if(process.env.NODE_ENV!==`production`&&!currentOptions.decodeEntities)throw Error(`[@vue/compiler-core] decodeEntities option is required in browser builds.`);tokenizer.mode=currentOptions.parseMode===`html`?1:currentOptions.parseMode===`sfc`?2:0,tokenizer.inXML=currentOptions.ns===1||currentOptions.ns===2;let u=c&&c.delimiters;u&&(tokenizer.delimiterOpen=toCharCodes(u[0]),tokenizer.delimiterClose=toCharCodes(u[1]));let d=currentRoot=createRoot([],t);return tokenizer.parse(currentInput),d.loc=getLoc(0,t.length),d.children=condenseWhitespace(d.children),currentRoot=null,d}function cacheStatic(t,c){walk(t,void 0,c,isSingleElementRoot(t,t.children[0]))}function isSingleElementRoot(t,c){let{children:u}=t;return u.length===1&&c.type===1&&!isSlotOutlet(c)}function walk(t,c,u,d=!1,m=!1){let{children:g}=t,b=[];for(let c=0;c<g.length;c++){let S=g[c];if(S.type===1&&S.tagType===0){let t=d?0:getConstantType(S,u);if(t>0){if(t>=2){S.codegenNode.patchFlag=-1,b.push(S);continue}}else{let t=S.codegenNode;if(t.type===13){let c=t.patchFlag;if((c===void 0||c===512||c===1)&&getGeneratedPropsConstantType(S,u)>=2){let c=getNodeProps(S);c&&(t.props=u.hoist(c))}t.dynamicProps&&(t.dynamicProps=u.hoist(t.dynamicProps))}}}else if(S.type===12&&(d?0:getConstantType(S,u))>=2){b.push(S);continue}if(S.type===1){let c=S.tagType===1;c&&u.scopes.vSlot++,walk(S,t,u,!1,m),c&&u.scopes.vSlot--}else if(S.type===11)walk(S,t,u,S.children.length===1,!0);else if(S.type===9)for(let c=0;c<S.branches.length;c++)walk(S.branches[c],t,u,S.branches[c].children.length===1,m)}let S=!1;if(b.length===g.length&&t.type===1){if(t.tagType===0&&t.codegenNode&&t.codegenNode.type===13&&isArray$3(t.codegenNode.children))t.codegenNode.children=getCacheExpression(createArrayExpression(t.codegenNode.children)),S=!0;else if(t.tagType===1&&t.codegenNode&&t.codegenNode.type===13&&t.codegenNode.children&&!isArray$3(t.codegenNode.children)&&t.codegenNode.children.type===15){let c=getSlotNode(t.codegenNode,`default`);c&&(c.returns=getCacheExpression(createArrayExpression(c.returns)),S=!0)}else if(t.tagType===3&&c&&c.type===1&&c.tagType===1&&c.codegenNode&&c.codegenNode.type===13&&c.codegenNode.children&&!isArray$3(c.codegenNode.children)&&c.codegenNode.children.type===15){let u=findDir(t,`slot`,!0),d=u&&u.arg&&getSlotNode(c.codegenNode,u.arg);d&&(d.returns=getCacheExpression(createArrayExpression(d.returns)),S=!0)}}if(!S)for(let t of b)t.codegenNode=u.cache(t.codegenNode);function getCacheExpression(t){let c=u.cache(t);return m&&u.hmr&&(c.needArraySpread=!0),c}function getSlotNode(t,c){if(t.children&&!isArray$3(t.children)&&t.children.type===15){let u=t.children.properties.find(t=>t.key===c||t.key.content===c);return u&&u.value}}b.length&&u.transformHoist&&u.transformHoist(g,u,t)}function getConstantType(t,c){let{constantCache:u}=c;switch(t.type){case 1:if(t.tagType!==0)return 0;let d=u.get(t);if(d!==void 0)return d;let m=t.codegenNode;if(m.type!==13||m.isBlock&&t.tag!==`svg`&&t.tag!==`foreignObject`&&t.tag!==`math`)return 0;if(m.patchFlag===void 0){let d=3,g=getGeneratedPropsConstantType(t,c);if(g===0)return u.set(t,0),0;g<d&&(d=g);for(let m=0;m<t.children.length;m++){let g=getConstantType(t.children[m],c);if(g===0)return u.set(t,0),0;g<d&&(d=g)}if(d>1)for(let m=0;m<t.props.length;m++){let g=t.props[m];if(g.type===7&&g.name===`bind`&&g.exp){let m=getConstantType(g.exp,c);if(m===0)return u.set(t,0),0;m<d&&(d=m)}}if(m.isBlock){for(let c=0;c<t.props.length;c++)if(t.props[c].type===7)return u.set(t,0),0;c.removeHelper(OPEN_BLOCK),c.removeHelper(getVNodeBlockHelper(c.inSSR,m.isComponent)),m.isBlock=!1,c.helper(getVNodeHelper(c.inSSR,m.isComponent))}return u.set(t,d),d}else return u.set(t,0),0;case 2:case 3:return 3;case 9:case 11:case 10:return 0;case 5:case 12:return getConstantType(t.content,c);case 4:return t.constType;case 8:let g=3;for(let u=0;u<t.children.length;u++){let d=t.children[u];if(isString$1(d)||isSymbol(d))continue;let m=getConstantType(d,c);if(m===0)return 0;m<g&&(g=m)}return g;case 20:return 2;default:return process.env.NODE_ENV,0}}function getConstantTypeOfHelperCall(t,c){if(t.type===14&&!isString$1(t.callee)&&allowHoistedHelperSet.has(t.callee)){let u=t.arguments[0];if(u.type===4)return getConstantType(u,c);if(u.type===14)return getConstantTypeOfHelperCall(u,c)}return 0}function getGeneratedPropsConstantType(t,c){let u=3,d=getNodeProps(t);if(d&&d.type===15){let{properties:t}=d;for(let d=0;d<t.length;d++){let{key:m,value:g}=t[d],b=getConstantType(m,c);if(b===0)return b;b<u&&(u=b);let S;if(S=g.type===4?getConstantType(g,c):g.type===14?getConstantTypeOfHelperCall(g,c):0,S===0)return S;S<u&&(u=S)}}return u}function getNodeProps(t){let c=t.codegenNode;if(c.type===13)return c.props}function createTransformContext(t,{filename:c=``,prefixIdentifiers:u=!1,hoistStatic:d=!1,hmr:m=!1,cacheHandlers:g=!1,nodeTransforms:b=[],directiveTransforms:S={},transformHoist:C=null,isBuiltInComponent:w=NOOP,isCustomElement:T=NOOP,expressionPlugins:E=[],scopeId:D=null,slotted:O=!0,ssr:Or=!1,inSSR:kr=!1,ssrCssVars:Ar=``,bindingMetadata:jr=EMPTY_OBJ,inline:Mr=!1,isTS:Nr=!1,onError:Pr=defaultOnError,onWarn:Fr=defaultOnWarn,compatConfig:Ir}){let Lr=c.replace(/\?.*$/,``).match(/([^/\\]+)\.\w+$/),Rr={filename:c,selfName:Lr&&capitalize(camelize(Lr[1])),prefixIdentifiers:u,hoistStatic:d,hmr:m,cacheHandlers:g,nodeTransforms:b,directiveTransforms:S,transformHoist:C,isBuiltInComponent:w,isCustomElement:T,expressionPlugins:E,scopeId:D,slotted:O,ssr:Or,inSSR:kr,ssrCssVars:Ar,bindingMetadata:jr,inline:Mr,isTS:Nr,onError:Pr,onWarn:Fr,compatConfig:Ir,root:t,helpers:new Map,components:new Set,directives:new Set,hoists:[],imports:[],cached:[],constantCache:new WeakMap,temps:0,identifiers:Object.create(null),scopes:{vFor:0,vSlot:0,vPre:0,vOnce:0},parent:null,grandParent:null,currentNode:t,childIndex:0,inVOnce:!1,helper(t){let c=Rr.helpers.get(t)||0;return Rr.helpers.set(t,c+1),t},removeHelper(t){let c=Rr.helpers.get(t);if(c){let u=c-1;u?Rr.helpers.set(t,u):Rr.helpers.delete(t)}},helperString(t){return`_${helperNameMap[Rr.helper(t)]}`},replaceNode(t){if(process.env.NODE_ENV!==`production`){if(!Rr.currentNode)throw Error(`Node being replaced is already removed.`);if(!Rr.parent)throw Error(`Cannot replace root node.`)}Rr.parent.children[Rr.childIndex]=Rr.currentNode=t},removeNode(t){if(process.env.NODE_ENV!==`production`&&!Rr.parent)throw Error(`Cannot remove root node.`);let c=Rr.parent.children,u=t?c.indexOf(t):Rr.currentNode?Rr.childIndex:-1;if(process.env.NODE_ENV!==`production`&&u<0)throw Error(`node being removed is not a child of current parent`);!t||t===Rr.currentNode?(Rr.currentNode=null,Rr.onNodeRemoved()):Rr.childIndex>u&&(Rr.childIndex--,Rr.onNodeRemoved()),Rr.parent.children.splice(u,1)},onNodeRemoved:NOOP,addIdentifiers(t){},removeIdentifiers(t){},hoist(t){isString$1(t)&&(t=createSimpleExpression(t)),Rr.hoists.push(t);let c=createSimpleExpression(`_hoisted_${Rr.hoists.length}`,!1,t.loc,2);return c.hoisted=t,c},cache(t,c=!1,u=!1){let d=createCacheExpression(Rr.cached.length,t,c,u);return Rr.cached.push(d),d}};return Rr.filters=new Set,Rr}function transform(t,c){let u=createTransformContext(t,c);traverseNode(t,u),c.hoistStatic&&cacheStatic(t,u),c.ssr||createRootCodegen(t,u),t.helpers=new Set([...u.helpers.keys()]),t.components=[...u.components],t.directives=[...u.directives],t.imports=u.imports,t.hoists=u.hoists,t.temps=u.temps,t.cached=u.cached,t.transformed=!0,t.filters=[...u.filters]}function createRootCodegen(t,c){let{helper:u}=c,{children:d}=t;if(d.length===1){let u=d[0];if(isSingleElementRoot(t,u)&&u.codegenNode){let d=u.codegenNode;d.type===13&&convertToBlock(d,c),t.codegenNode=d}else t.codegenNode=u}else if(d.length>1){let m=64;process.env.NODE_ENV!==`production`&&d.filter(t=>t.type!==3).length===1&&(m|=2048),t.codegenNode=createVNodeCall(c,u(FRAGMENT),void 0,t.children,m,void 0,void 0,!0,void 0,!1)}}function traverseChildren(t,c){let u=0,nodeRemoved=()=>{u--};for(;u<t.children.length;u++){let d=t.children[u];isString$1(d)||(c.grandParent=c.parent,c.parent=t,c.childIndex=u,c.onNodeRemoved=nodeRemoved,traverseNode(d,c))}}function traverseNode(t,c){c.currentNode=t;let{nodeTransforms:u}=c,d=[];for(let m=0;m<u.length;m++){let g=u[m](t,c);if(g&&(isArray$3(g)?d.push(...g):d.push(g)),c.currentNode)t=c.currentNode;else return}switch(t.type){case 3:c.ssr||c.helper(CREATE_COMMENT);break;case 5:c.ssr||c.helper(TO_DISPLAY_STRING);break;case 9:for(let u=0;u<t.branches.length;u++)traverseNode(t.branches[u],c);break;case 10:case 11:case 1:case 0:traverseChildren(t,c);break}c.currentNode=t;let m=d.length;for(;m--;)d[m]()}function createStructuralDirectiveTransform(t,c){let u=isString$1(t)?c=>c===t:c=>t.test(c);return(t,d)=>{if(t.type===1){let{props:m}=t;if(t.tagType===3&&m.some(isVSlot))return;let g=[];for(let b=0;b<m.length;b++){let S=m[b];if(S.type===7&&u(S.name)){m.splice(b,1),b--;let u=c(t,S,d);u&&g.push(u)}}return g}}}function createCodegenContext(t,{mode:c=`function`,prefixIdentifiers:u=c===`module`,sourceMap:d=!1,filename:m=`template.vue.html`,scopeId:g=null,optimizeImports:b=!1,runtimeGlobalName:S=`Vue`,runtimeModuleName:C=`vue`,ssrRuntimeModuleName:w=`vue/server-renderer`,ssr:T=!1,isTS:E=!1,inSSR:D=!1}){let O={mode:c,prefixIdentifiers:u,sourceMap:d,filename:m,scopeId:g,optimizeImports:b,runtimeGlobalName:S,runtimeModuleName:C,ssrRuntimeModuleName:w,ssr:T,isTS:E,inSSR:D,source:t.source,code:``,column:1,line:1,offset:0,indentLevel:0,pure:!1,map:void 0,helper(t){return`_${helperNameMap[t]}`},push(t,c=-2,u){O.code+=t},indent(){newline(++O.indentLevel)},deindent(t=!1){t?--O.indentLevel:newline(--O.indentLevel)},newline(){newline(O.indentLevel)}};function newline(t){O.push(`
461
461
  `+` `.repeat(t),0)}return O}function generate(t,c={}){let u=createCodegenContext(t,c);c.onContextCreated&&c.onContextCreated(u);let{mode:d,push:m,prefixIdentifiers:g,indent:b,deindent:S,newline:C,scopeId:w,ssr:T}=u,E=Array.from(t.helpers),D=E.length>0,O=!g&&d!==`module`;if(genFunctionPreamble(t,u),m(`function ${T?`ssrRender`:`render`}(${(T?[`_ctx`,`_push`,`_parent`,`_attrs`]:[`_ctx`,`_cache`]).join(`, `)}) {`),b(),O&&(m(`with (_ctx) {`),b(),D&&(m(`const { ${E.map(aliasHelper).join(`, `)} } = _Vue