@vue-skuilder/platform-ui 0.2.20 → 0.2.21
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/assets/{About-D_Y8nETJ.js → About-WGmpa3iN.js} +2 -2
- package/dist/assets/{About-D_Y8nETJ.js.map → About-WGmpa3iN.js.map} +1 -1
- package/dist/assets/{AdminDashboard-BmDn17Ss.js → AdminDashboard-MZpTJWXj.js} +2 -2
- package/dist/assets/{AdminDashboard-BmDn17Ss.js.map → AdminDashboard-MZpTJWXj.js.map} +1 -1
- package/dist/assets/{ClassroomCtrlPanel-8wCAnEMC.js → ClassroomCtrlPanel-CDBsTwon.js} +2 -2
- package/dist/assets/{ClassroomCtrlPanel-8wCAnEMC.js.map → ClassroomCtrlPanel-CDBsTwon.js.map} +1 -1
- package/dist/assets/{Classrooms-ggGJvaWy.js → Classrooms-D5avRVqi.js} +2 -2
- package/dist/assets/{Classrooms-ggGJvaWy.js.map → Classrooms-D5avRVqi.js.map} +1 -1
- package/dist/assets/{CourseRouter-CovgXvPQ.js → CourseRouter-EIJC7zPf.js} +2 -2
- package/dist/assets/{CourseRouter-CovgXvPQ.js.map → CourseRouter-EIJC7zPf.js.map} +1 -1
- package/dist/assets/{CourseWare-BTFRjgBR-TatStfSg.js → CourseWare-BTFRjgBR-BZ8obQWc.js} +3 -3
- package/dist/assets/{CourseWare-BTFRjgBR-TatStfSg.js.map → CourseWare-BTFRjgBR-BZ8obQWc.js.map} +1 -1
- package/dist/assets/{Courses-BlJ1ZlDL.js → Courses-BNwODqkn.js} +2 -2
- package/dist/assets/{Courses-BlJ1ZlDL.js.map → Courses-BNwODqkn.js.map} +1 -1
- package/dist/assets/{EloModeration-p-Xn20Be.js → EloModeration-CWwBGNY6.js} +2 -2
- package/dist/assets/{EloModeration-p-Xn20Be.js.map → EloModeration-CWwBGNY6.js.map} +1 -1
- package/dist/assets/{JoinCode-CIiUQzhI.js → JoinCode-ChLGQa8O.js} +2 -2
- package/dist/assets/{JoinCode-CIiUQzhI.js.map → JoinCode-ChLGQa8O.js.map} +1 -1
- package/dist/assets/{NewCourseDialog-C3G8i08Y.js → NewCourseDialog-CIypVVdF.js} +2 -2
- package/dist/assets/{NewCourseDialog-C3G8i08Y.js.map → NewCourseDialog-CIypVVdF.js.map} +1 -1
- package/dist/assets/{ReleaseNotes-Cpl2GDhr.js → ReleaseNotes-gdeGomMu.js} +2 -2
- package/dist/assets/{ReleaseNotes-Cpl2GDhr.js.map → ReleaseNotes-gdeGomMu.js.map} +1 -1
- package/dist/assets/{RequestPasswordReset-CuDiWiMB.js → RequestPasswordReset-DcOfICGO.js} +2 -2
- package/dist/assets/{RequestPasswordReset-CuDiWiMB.js.map → RequestPasswordReset-DcOfICGO.js.map} +1 -1
- package/dist/assets/{ResetPassword-xm-JwzQX.js → ResetPassword-B3pelRbU.js} +2 -2
- package/dist/assets/{ResetPassword-xm-JwzQX.js.map → ResetPassword-B3pelRbU.js.map} +1 -1
- package/dist/assets/{Study-DSIJdykk.js → Study-CjRVlNKK.js} +2 -2
- package/dist/assets/{Study-DSIJdykk.js.map → Study-CjRVlNKK.js.map} +1 -1
- package/dist/assets/{TagInformation-C8GSB2n7.js → TagInformation-GJhZGXLS.js} +2 -2
- package/dist/assets/{TagInformation-C8GSB2n7.js.map → TagInformation-GJhZGXLS.js.map} +1 -1
- package/dist/assets/{User-Bmi112ma.js → User-BdCdMuSs.js} +3 -3
- package/dist/assets/{User-Bmi112ma.js.map → User-BdCdMuSs.js.map} +1 -1
- package/dist/assets/{UserStats-aEAyHjG6.js → UserStats-BXyclNMS.js} +2 -2
- package/dist/assets/{UserStats-aEAyHjG6.js.map → UserStats-BXyclNMS.js.map} +1 -1
- package/dist/assets/{VerifyEmail-CjZ5AGqD.js → VerifyEmail-DmxTSdfD.js} +2 -2
- package/dist/assets/{VerifyEmail-CjZ5AGqD.js.map → VerifyEmail-DmxTSdfD.js.map} +1 -1
- package/dist/assets/{chess-E2uOAyQS-CNVwCR5p.js → chess-E2uOAyQS-BQ0OF-jj.js} +2 -2
- package/dist/assets/{chess-E2uOAyQS-CNVwCR5p.js.map → chess-E2uOAyQS-BQ0OF-jj.js.map} +1 -1
- package/dist/assets/chess-Lfm7Fsvs-CWz202O1.js +1 -0
- package/dist/assets/{common-ui.es-CI_-KPH_.js → common-ui.es-ChjTd0d0.js} +5 -5
- package/dist/assets/common-ui.es-ChjTd0d0.js.map +1 -0
- package/dist/assets/{common-ui.es-CNm26Xhf.js → common-ui.es-TM4oEU1b.js} +1 -1
- package/dist/assets/{dist-D7BgmbSl.js → dist-BphpLV0p.js} +3 -3
- package/dist/assets/{dist-D7BgmbSl.js.map → dist-BphpLV0p.js.map} +1 -1
- package/dist/assets/dist-P9Xau7li.js +1 -0
- package/dist/assets/{edit-ui.es-C9_Ri35F.js → edit-ui.es-B-vwdh_S.js} +2 -2
- package/dist/assets/{edit-ui.es-C9_Ri35F.js.map → edit-ui.es-B-vwdh_S.js.map} +1 -1
- package/dist/assets/edit-ui.es-Cs3nBwzs.js +1 -0
- package/dist/assets/{french-Dk7YG8Td-Ba2Pgnoe.js → french-Dk7YG8Td-Bx6fB9mf.js} +2 -2
- package/dist/assets/{french-Dk7YG8Td-Ba2Pgnoe.js.map → french-Dk7YG8Td-Bx6fB9mf.js.map} +1 -1
- package/dist/assets/french-evUMlbbq-Dw4_mkFh.js +1 -0
- package/dist/assets/{index-BEyU565e.js → index-CNyUj65v.js} +4 -4
- package/dist/assets/{index-BEyU565e.js.map → index-CNyUj65v.js.map} +1 -1
- package/dist/assets/{index-q_Phdcvy.css → index-eTdjCxbx.css} +1 -1
- package/dist/assets/{math-B4HbgYf6-DxqtGn5z.js → math-B4HbgYf6-DLPeYhSf.js} +2 -2
- package/dist/assets/{math-B4HbgYf6-DxqtGn5z.js.map → math-B4HbgYf6-DLPeYhSf.js.map} +1 -1
- package/dist/assets/math-DYni7rRl-DfMt7wCc.js +1 -0
- package/dist/assets/piano-BN5Btq91-BdgWiNs_.js +1 -0
- package/dist/assets/{piano-DF1g6yaX-C8XTzRCe.js → piano-DF1g6yaX-SjAf5oVr.js} +2 -2
- package/dist/assets/{piano-DF1g6yaX-C8XTzRCe.js.map → piano-DF1g6yaX-SjAf5oVr.js.map} +1 -1
- package/dist/assets/{pitch-CgGJFkZ1-CT0J_yrL.js → pitch-CgGJFkZ1-DdLlbgje.js} +2 -2
- package/dist/assets/{pitch-CgGJFkZ1-CT0J_yrL.js.map → pitch-CgGJFkZ1-DdLlbgje.js.map} +1 -1
- package/dist/assets/pitch-Dn0iNqiS-D0VDPciM.js +1 -0
- package/dist/assets/{server-Cb-GR5S_.js → server-Dq1qX7bd.js} +2 -2
- package/dist/assets/{server-Cb-GR5S_.js.map → server-Dq1qX7bd.js.map} +1 -1
- package/dist/assets/{sightsing-BFQ7HRig-B5ujMfmF.js → sightsing-BFQ7HRig-D6-76KaZ.js} +2 -2
- package/dist/assets/{sightsing-BFQ7HRig-B5ujMfmF.js.map → sightsing-BFQ7HRig-D6-76KaZ.js.map} +1 -1
- package/dist/assets/sightsing-CJX3k0Fd-DRgeFLpp.js +1 -0
- package/dist/assets/{typing-BevtfWlp-BYARhIGa.js → typing-BevtfWlp-CUr9pIwh.js} +2 -2
- package/dist/assets/{typing-BevtfWlp-BYARhIGa.js.map → typing-BevtfWlp-CUr9pIwh.js.map} +1 -1
- package/dist/assets/typing-k-ojjO7G-D-WEC99L.js +1 -0
- package/dist/assets/{word-work-BOnRlZgd-embqXaxA.js → word-work-BOnRlZgd-B7QQfrf_.js} +2 -2
- package/dist/assets/{word-work-BOnRlZgd-embqXaxA.js.map → word-work-BOnRlZgd-B7QQfrf_.js.map} +1 -1
- package/dist/assets/word-work-Dd6tIKrt-vD65KuAh.js +1 -0
- package/dist/index.html +3 -3
- package/dist/sw.js +1 -1
- package/dist/sw.js.map +1 -1
- package/package.json +7 -7
- package/dist/assets/chess-Lfm7Fsvs-GR_CD_2u.js +0 -1
- package/dist/assets/common-ui.es-CI_-KPH_.js.map +0 -1
- package/dist/assets/dist-DqgsO2z_.js +0 -1
- package/dist/assets/edit-ui.es-PYOF8EKq.js +0 -1
- package/dist/assets/french-evUMlbbq-Ba1_vrEt.js +0 -1
- package/dist/assets/math-DYni7rRl-CMPNovna.js +0 -1
- package/dist/assets/piano-BN5Btq91-DHT1X_bf.js +0 -1
- package/dist/assets/pitch-Dn0iNqiS-DG_PkmpF.js +0 -1
- package/dist/assets/sightsing-CJX3k0Fd-BkU5b51R.js +0 -1
- package/dist/assets/typing-k-ojjO7G-DYS0ZcnT.js +0 -1
- package/dist/assets/word-work-Dd6tIKrt-ConomP2U.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./vue.runtime.esm-bundler-C3q8JS9f.js";import"./common-ui.es-ChjTd0d0.js";import"./dist-leWgtXBf.js";import"./MarkdownRenderer-kStoDRNE-CwICngq1.js";import"./dist-C_sASyZw.js";import"./CourseWare-BTFRjgBR-BZ8obQWc.js";import{t as e}from"./chess-E2uOAyQS-BQ0OF-jj.js";export{e as default};
|
|
@@ -14,7 +14,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
14
14
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function _toConsumableArray(t){return _arrayWithoutHoles(t)||_iterableToArray(t)||_unsupportedIterableToArray(t)||_nonIterableSpread()}var s=r(`a352`),c=r.n(s);function removeNode(t){t.parentElement!==null&&t.parentElement.removeChild(t)}function insertNodeAt(t,n,r){var i=r===0?t.children[0]:t.children[r-1].nextSibling;t.insertBefore(n,i)}var l=r(`dbf1`);r(`13d5`),r(`4fad`),r(`ac1f`),r(`5319`);function cached(t){var n=Object.create(null);return function cachedFn(r){return n[r]||(n[r]=t(r))}}var u=/-(\w)/g,d=cached(function(t){return t.replace(u,function(t,n){return n.toUpperCase()})});r(`5db7`),r(`73d9`);var f=[`Start`,`Add`,`Remove`,`Update`,`End`],p=[`Choose`,`Unchoose`,`Sort`,`Filter`,`Clone`],m=[`Move`],h=[m,f,p].flatMap(function(t){return t}).map(function(t){return`on${t}`}),g={manage:m,manageAndEmit:f,emit:p};function isReadOnly(t){return h.indexOf(t)!==-1}r(`caad`),r(`2ca0`);var _=`a.abbr.address.area.article.aside.audio.b.base.bdi.bdo.blockquote.body.br.button.canvas.caption.cite.code.col.colgroup.data.datalist.dd.del.details.dfn.dialog.div.dl.dt.em.embed.fieldset.figcaption.figure.footer.form.h1.h2.h3.h4.h5.h6.head.header.hgroup.hr.html.i.iframe.img.input.ins.kbd.label.legend.li.link.main.map.mark.math.menu.menuitem.meta.meter.nav.noscript.object.ol.optgroup.option.output.p.param.picture.pre.progress.q.rb.rp.rt.rtc.ruby.s.samp.script.section.select.slot.small.source.span.strong.style.sub.summary.sup.svg.table.tbody.td.template.textarea.tfoot.th.thead.time.title.tr.track.u.ul.var.video.wbr`.split(`.`);function isHtmlTag(t){return _.includes(t)}function isTransition(t){return[`transition-group`,`TransitionGroup`].includes(t)}function isHtmlAttribute(t){return[`id`,`class`,`role`,`style`].includes(t)||t.startsWith(`data-`)||t.startsWith(`aria-`)||t.startsWith(`on`)}function project(t){return t.reduce(function(t,n){var r=_slicedToArray(n,2),i=r[0];return t[i]=r[1],t},{})}function getComponentAttributes(t){var n=t.$attrs,r=t.componentData,i=r===void 0?{}:r;return _objectSpread2(_objectSpread2({},project(Object.entries(n).filter(function(t){var n=_slicedToArray(t,2),r=n[0];return n[1],isHtmlAttribute(r)}))),i)}function createSortableOption(t){var n=t.$attrs,r=t.callBackBuilder,i=project(getValidSortableEntries(n));Object.entries(r).forEach(function(t){var n=_slicedToArray(t,2),r=n[0],a=n[1];g[r].forEach(function(t){i[`on${t}`]=a(t)})});var a=`[data-draggable]${i.draggable||``}`;return _objectSpread2(_objectSpread2({},i),{},{draggable:a})}function getValidSortableEntries(t){return Object.entries(t).filter(function(t){var n=_slicedToArray(t,2),r=n[0];return n[1],!isHtmlAttribute(r)}).map(function(t){var n=_slicedToArray(t,2),r=n[0],i=n[1];return[d(r),i]}).filter(function(t){var n=_slicedToArray(t,2),r=n[0];return n[1],!isReadOnly(r)})}r(`c740`);function _classCallCheck(t,n){if(!(t instanceof n))throw TypeError(`Cannot call a class as a function`)}function _defineProperties(t,n){for(var r=0;r<n.length;r++){var i=n[r];i.enumerable=i.enumerable||!1,i.configurable=!0,`value`in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function _createClass(t,n,r){return n&&_defineProperties(t.prototype,n),r&&_defineProperties(t,r),t}var b=function getHtmlElementFromNode(t){return t.el},x=function addContext(t,n){return t.__draggable_context=n},S=function getContext(t){return t.__draggable_context},C=function(){function ComponentStructure(t){var n=t.nodes,r=n.header,i=n.default,a=n.footer,o=t.root,s=t.realList;_classCallCheck(this,ComponentStructure),this.defaultNodes=i,this.children=[].concat(_toConsumableArray(r),_toConsumableArray(i),_toConsumableArray(a)),this.externalComponent=o.externalComponent,this.rootTransition=o.transition,this.tag=o.tag,this.realList=s}return _createClass(ComponentStructure,[{key:`render`,value:function render(t,n){var r=this.tag,i=this.children;return t(r,n,this._isRootComponent?{default:function _default(){return i}}:i)}},{key:`updated`,value:function updated(){var t=this.defaultNodes,n=this.realList;t.forEach(function(t,r){x(b(t),{element:n[r],index:r})})}},{key:`getUnderlyingVm`,value:function getUnderlyingVm(t){return S(t)}},{key:`getVmIndexFromDomIndex`,value:function getVmIndexFromDomIndex(t,n){var r=this.defaultNodes,i=r.length,a=n.children,o=a.item(t);if(o===null)return i;var s=S(o);if(s)return s.index;if(i===0)return 0;var c=b(r[0]);return t<_toConsumableArray(a).findIndex(function(t){return t===c})?0:i}},{key:`_isRootComponent`,get:function get(){return this.externalComponent||this.rootTransition}}]),ComponentStructure}(),w=r(`8bbf`);function getSlot(t,n){var r=t[n];return r?r():[]}function computeNodes(t){var n=t.$slots,r=t.realList,i=t.getKey,a=r||[],o=_slicedToArray([`header`,`footer`].map(function(t){return getSlot(n,t)}),2),s=o[0],c=o[1],l=n.item;if(!l)throw Error(`draggable element must have an item slot`);var u=a.flatMap(function(t,n){return l({element:t,index:n}).map(function(n){return n.key=i(t),n.props=_objectSpread2(_objectSpread2({},n.props||{}),{},{"data-draggable":!0}),n})});if(u.length!==a.length)throw Error(`Item slot must have only one child`);return{header:s,footer:c,default:u}}function getRootInformation(t){var n=isTransition(t),r=!isHtmlTag(t)&&!n;return{transition:n,externalComponent:r,tag:r?(0,w.resolveComponent)(t):n?w.TransitionGroup:t}}function computeComponentStructure(t){var n=t.$slots,r=t.tag,i=t.realList,a=t.getKey;return new C({nodes:computeNodes({$slots:n,realList:i,getKey:a}),root:getRootInformation(r),realList:i})}function _emit(t,n){var r=this;(0,w.nextTick)(function(){return r.$emit(t.toLowerCase(),n)})}function _manage(t){var n=this;return function(r,i){if(n.realList!==null)return n[`onDrag${t}`](r,i)}}function _manageAndEmit(t){var n=this,r=_manage.call(this,t);return function(i,a){r.call(n,i,a),_emit.call(n,t,i)}}var T=null,E={list:{type:Array,required:!1,default:null},modelValue:{type:Array,required:!1,default:null},itemKey:{type:[String,Function],required:!0},clone:{type:Function,default:function _default(t){return t}},tag:{type:String,default:`div`},move:{type:Function,default:null},componentData:{type:Object,required:!1,default:null}},D=[`update:modelValue`,`change`].concat(_toConsumableArray([].concat(_toConsumableArray(g.manageAndEmit),_toConsumableArray(g.emit)).map(function(t){return t.toLowerCase()})));n.default=(0,w.defineComponent)({name:`draggable`,inheritAttrs:!1,props:E,emits:D,data:function data(){return{error:!1}},render:function render(){try{this.error=!1;var t=this.$slots,n=this.$attrs,r=this.tag,i=this.componentData,a=this.realList,o=this.getKey,s=computeComponentStructure({$slots:t,tag:r,realList:a,getKey:o});this.componentStructure=s;var c=getComponentAttributes({$attrs:n,componentData:i});return s.render(w.h,c)}catch(t){return this.error=!0,(0,w.h)(`pre`,{style:{color:`red`}},t.stack)}},created:function created(){this.list!==null&&this.modelValue!==null&&l.a.error(`modelValue and list props are mutually exclusive! Please set one or another.`)},mounted:function mounted(){var t=this;if(!this.error){var n=this.$attrs,r=this.$el;this.componentStructure.updated();var i=createSortableOption({$attrs:n,callBackBuilder:{manageAndEmit:function manageAndEmit(n){return _manageAndEmit.call(t,n)},emit:function emit(n){return _emit.bind(t,n)},manage:function manage(n){return _manage.call(t,n)}}}),a=r.nodeType===1?r:r.parentElement;this._sortable=new c.a(a,i),this.targetDomElement=a,a.__draggable_component__=this}},updated:function updated(){this.componentStructure.updated()},beforeUnmount:function beforeUnmount(){this._sortable!==void 0&&this._sortable.destroy()},computed:{realList:function realList(){return this.list||this.modelValue},getKey:function getKey(){var t=this.itemKey;return typeof t==`function`?t:function(n){return n[t]}}},watch:{$attrs:{handler:function handler(t){var n=this._sortable;n&&getValidSortableEntries(t).forEach(function(t){var r=_slicedToArray(t,2),i=r[0],a=r[1];n.option(i,a)})},deep:!0}},methods:{getUnderlyingVm:function getUnderlyingVm(t){return this.componentStructure.getUnderlyingVm(t)||null},getUnderlyingPotencialDraggableComponent:function getUnderlyingPotencialDraggableComponent(t){return t.__draggable_component__},emitChanges:function emitChanges(t){var n=this;(0,w.nextTick)(function(){return n.$emit(`change`,t)})},alterList:function alterList(t){if(this.list){t(this.list);return}var n=_toConsumableArray(this.modelValue);t(n),this.$emit(`update:modelValue`,n)},spliceList:function spliceList(){var t=arguments;this.alterList(function spliceList(n){return n.splice.apply(n,_toConsumableArray(t))})},updatePosition:function updatePosition(t,n){this.alterList(function updatePosition(r){return r.splice(n,0,r.splice(t,1)[0])})},getRelatedContextFromMoveEvent:function getRelatedContextFromMoveEvent(t){var n=t.to,r=t.related,i=this.getUnderlyingPotencialDraggableComponent(n);if(!i)return{component:i};var a=i.realList,o={list:a,component:i};return n!==r&&a?_objectSpread2(_objectSpread2({},i.getUnderlyingVm(r)||{}),o):o},getVmIndexFromDomIndex:function getVmIndexFromDomIndex(t){return this.componentStructure.getVmIndexFromDomIndex(t,this.targetDomElement)},onDragStart:function onDragStart(t){this.context=this.getUnderlyingVm(t.item),t.item._underlying_vm_=this.clone(this.context.element),T=t.item},onDragAdd:function onDragAdd(t){var n=t.item._underlying_vm_;if(n!==void 0){removeNode(t.item);var r=this.getVmIndexFromDomIndex(t.newIndex);this.spliceList(r,0,n);var i={element:n,newIndex:r};this.emitChanges({added:i})}},onDragRemove:function onDragRemove(t){if(insertNodeAt(this.$el,t.item,t.oldIndex),t.pullMode===`clone`){removeNode(t.clone);return}var n=this.context,r=n.index,i=n.element;this.spliceList(r,1);var a={element:i,oldIndex:r};this.emitChanges({removed:a})},onDragUpdate:function onDragUpdate(t){removeNode(t.item),insertNodeAt(t.from,t.item,t.oldIndex);var n=this.context.index,r=this.getVmIndexFromDomIndex(t.newIndex);this.updatePosition(n,r);var i={element:this.context.element,oldIndex:n,newIndex:r};this.emitChanges({moved:i})},computeFutureIndex:function computeFutureIndex(t,n){if(!t.element)return 0;var r=_toConsumableArray(n.to.children).filter(function(t){return t.style.display!==`none`}),i=r.indexOf(n.related),a=t.component.getVmIndexFromDomIndex(i);return r.indexOf(T)!==-1||!n.willInsertAfter?a:a+1},onDragMove:function onDragMove(t,n){var r=this.move,i=this.realList;if(!r||!i)return!0;var a=this.getRelatedContextFromMoveEvent(t),o=this.computeFutureIndex(a,t),s=_objectSpread2(_objectSpread2({},this.context),{},{futureIndex:o});return r(_objectSpread2(_objectSpread2({},t),{},{relatedContext:a,draggedContext:s}),n)},onDragEnd:function onDragEnd(){T=null}}})}),fb6a:(function(t,n,r){var i=r(`23e7`),a=r(`861d`),o=r(`e8b5`),s=r(`23cb`),c=r(`50c4`),l=r(`fc6a`),u=r(`8418`),d=r(`b622`),f=r(`1dde`),p=r(`ae40`),m=f(`slice`),h=p(`slice`,{ACCESSORS:!0,0:0,1:2}),g=d(`species`),_=[].slice,b=Math.max;i({target:`Array`,proto:!0,forced:!m||!h},{slice:function slice(t,n){var r=l(this),i=c(r.length),d=s(t,i),f=s(n===void 0?i:n,i),p,m,h;if(o(r)&&(p=r.constructor,typeof p==`function`&&(p===Array||o(p.prototype))?p=void 0:a(p)&&(p=p[g],p===null&&(p=void 0)),p===Array||p===void 0))return _.call(r,d,f);for(m=new(p===void 0?Array:p)(b(f-d,0)),h=0;d<f;d++,h++)d in r&&u(m,h,r[d]);return m.length=h,m}})}),fc6a:(function(t,n,r){var i=r(`44ad`),a=r(`1d80`);t.exports=function(t){return i(a(t))}}),fdbc:(function(t,n){t.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}}),fdbf:(function(t,n,r){t.exports=r(`4930`)&&!Symbol.sham&&typeof Symbol.iterator==`symbol`})}).default})}))(),1),B=(t,n)=>{let r=t.__vccOpts||t;for(let[t,i]of n)r[t]=i;return r},ka={name:`TagInput`,props:{scope:{type:Object,required:!0}}},Aa=[`maxlength`];function K(t,n,r,i,a,o){return r.scope.edit?he((x(),R(`input`,{key:0,"onUpdate:modelValue":n[0]||(n[0]=t=>r.scope.element.text=t),maxlength:r.scope.maxlength,type:`text`,class:`ti-tag-input`,size:`1`,onInput:n[1]||(n[1]=t=>r.scope.validateTag(r.scope.index,t)),onBlur:n[2]||(n[2]=t=>r.scope.performCancelEdit(r.scope.index)),onKeydown:n[3]||(n[3]=t=>r.scope.performSaveEdit(r.scope.index,t))},null,40,Aa)),[[Te,r.scope.element.text]]):U(``,!0)}var ja=B(ka,[[`render`,K],[`__scopeId`,`data-v-a3408643`]]),M=t=>!t.some(t=>{let n=!t.text;n&&console.warn(`Missing property "text"`,t);let r=!1;return t.classes&&(r=typeof t.classes!=`string`),r&&console.warn(`Property "classes" must be type of string`,t),n||r}),F=t=>!t.some(t=>{if(typeof t==`number`){let n=isFinite(t)&&Math.floor(t)===t;return n||console.warn(`Only numerics are allowed for this prop. Found:`,t),!n}else if(typeof t==`string`){let n=/\W|[a-z]|!\d/i.test(t);return n||console.warn(`Only alpha strings are allowed for this prop. Found:`,t),!n}else return console.warn(`Only numeric and string values are allowed. Found:`,t),!1}),Ma={modelValue:{type:String,default:``,required:!0},tags:{type:Array,default:()=>[],validator:M},autocompleteItems:{type:Array,default:()=>[],validator:M},allowEditTags:{type:Boolean,default:!1},autocompleteFilterDuplicates:{default:!0,type:Boolean},addOnlyFromAutocomplete:{type:Boolean,default:!1},autocompleteMinLength:{type:Number,default:1},autocompleteAlwaysOpen:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},placeholder:{type:String,default:`Add Tag`},addOnKey:{type:Array,default:()=>[13],validator:F},saveOnKey:{type:Array,default:()=>[13],validator:F},maxTags:{type:Number},maxlength:{type:Number},validation:{type:Array,default:()=>[],validator(t){return!t.some(t=>{let n=!t.rule;n&&console.warn(`Property "rule" is missing`,t);let r=t.rule&&(typeof t.rule==`string`||t.rule instanceof RegExp||{}.toString.call(t.rule)===`[object Function]`);r||console.warn(`A rule must be type of string, RegExp or function. Found:`,JSON.stringify(t.rule));let i=!t.classes;i&&console.warn(`Property "classes" is missing`,t);let a=t.type&&typeof t.type!=`string`;return a&&console.warn(`Property "type" must be type of string. Found:`,t),!r||n||i||a})}},separators:{type:Array,default:()=>[`;`],validator(t){return!t.some(t=>{let n=typeof t!=`string`;return n&&console.warn(`Separators must be type of string. Found:`,t),n})}},avoidAddingDuplicates:{type:Boolean,default:!0},addOnBlur:{type:Boolean,default:!0},isDuplicate:{type:Function,default:null},addFromPaste:{type:Boolean,default:!0},deleteOnBackspace:{default:!0,type:Boolean},isDraggable:{type:Boolean,default:!1},draggableHandle:{type:Boolean,default:!1},onBeforeAddingTag:Function,onBeforeDeletingTag:Function,onBeforeEditingTag:Function,onBeforeSavingTag:Function};function L(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,`default`)?t.default:t}var Na=L(function e(t,n){if(t===n)return!0;if(t&&n&&typeof t==`object`&&typeof n==`object`){if(t.constructor!==n.constructor)return!1;var r,i,a;if(Array.isArray(t)){if(r=t.length,r!=n.length)return!1;for(i=r;i--!==0;)if(!e(t[i],n[i]))return!1;return!0}if(t.constructor===RegExp)return t.source===n.source&&t.flags===n.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===n.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===n.toString();if(a=Object.keys(t),r=a.length,r!==Object.keys(n).length)return!1;for(i=r;i--!==0;)if(!Object.prototype.hasOwnProperty.call(n,a[i]))return!1;for(i=r;i--!==0;){var o=a[i];if(!e(t[o],n[o]))return!1}return!0}return t!==t&&n!==n}),J=(t,n)=>n.filter(n=>{let{text:r}=t;return typeof n.rule==`string`?!new RegExp(n.rule).test(r):n.rule instanceof RegExp?!n.rule.test(r):{}.toString.call(n.rule)===`[object Function]`?n.rule(t):!1}).map(t=>t.classes),y=t=>JSON.parse(JSON.stringify(t)),W=(t,n)=>{let r=0;for(;r<t.length;){if(n(t[r],r,t))return r;r++}return-1},V=(t,n,r=[],i)=>{t.text===void 0&&(t={text:t});let a=J(t,r),o=W(n,n=>n===t),s=y(n),c=o===-1?y(t):s.splice(o,1)[0];return(i?i(s,c):s.map(t=>t.text).indexOf(c.text)!==-1)&&a.push(`ti-duplicate`),a.length===0?a.push(`ti-valid`):a.push(`ti-invalid`),a},v=(t,...n)=>{t.text===void 0&&(t={text:t});let r=y(t);return r.tiClasses=V(t,...n),r},G=(t,...n)=>t.map(r=>v(r,t,...n)),Pa={name:`VueTagsInput`,components:{TagInput:ja,draggable:Oa.default},props:Ma,emits:[`adding-duplicate`,`before-adding-tag`,`before-deleting-tag`,`before-editing-tag`,`before-saving-tag`,`max-tags-reached`,`saving-duplicate`,`tags-changed`,`tag-clicked`,`update:modelValue`,`update:tags`,`tag-order-changed`,`click`],inheritAttrs:!1,data(){return{tagCenter:[],newTag:null,tagsCopy:[],tagsEditStatus:null,deletionMark:null,deletionMarkTime:null,selectedItem:null,focused:null}},computed:{autocompleteOpen(){return this.autocompleteAlwaysOpen?!0:this.newTag!==null&&this.newTag.length>=this.autocompleteMinLength&&this.filteredAutocompleteItems.length>0&&this.focused},filteredAutocompleteItems(){let t=this.autocompleteItems.map(t=>v(t,this.tags,this.validation,this.isDuplicate));return this.autocompleteFilterDuplicates?t.filter(this.duplicateFilter):t}},methods:{createClasses:V,getSelectedIndex(t){let n=this.filteredAutocompleteItems,r=this.selectedItem,i=n.length-1;if(n.length!==0)return r===null?0:t===`before`&&r===0?i:t===`after`&&r===i?0:t===`after`?r+1:r-1},selectDefaultItem(){this.addOnlyFromAutocomplete&&this.filteredAutocompleteItems.length>0?this.selectedItem=0:this.selectedItem=null},selectItem(t,n){t.preventDefault(),this.selectedItem=this.getSelectedIndex(n)},isSelected(t){return this.selectedItem===t},isMarked(t){return this.deletionMark===t},setTagCenter(t){t&&this.tagCenter.push(t)},invokeDelete(){if(!this.deleteOnBackspace||this.newTag.length>0)return;let t=this.tagsCopy.length-1;this.deletionMark===null?(this.deletionMarkTime=setTimeout(()=>{this.deletionMark=null},1e3),this.deletionMark=t):this.performDeleteTag(t)},addTagsFromPaste(){this.addFromPaste&&setTimeout(()=>this.performAddTags(this.newTag),10)},performEditTag(t){this.allowEditTags&&(this.onBeforeAddingTag||this.editTag(t),this.$emit(`before-editing-tag`,{index:t,tag:this.tagsCopy[t],editTag:()=>this.editTag(t)}))},editTag(t){this.allowEditTags&&(this.toggleEditMode(t),this.focus(t))},toggleEditMode(t){!this.allowEditTags||this.disabled||(this.tagsEditStatus[t]=!this.tagsEditStatus[t])},createChangedTag(t,n){let r=this.tagsCopy[t];r.text=n?n.target.value:this.tagsCopy[t].text,this.tagsCopy[t]=v(r,this.tagsCopy,this.validation,this.isDuplicate)},focus(t){this.$nextTick(()=>{let n=this.tagCenter[t].querySelector(`input.ti-tag-input`);n&&n.focus()})},quote(t){return t.replace(/([()[{*+.$^\\|?])/g,`\\$1`)},cancelEdit(t){this.tags[t]&&(this.tagsCopy[t]=y(v(this.tags[t],this.tags,this.validation,this.isDuplicate)),this.tagsEditStatus[t]=!1)},hasForbiddingAddRule(t){return t.some(t=>{let n=this.validation.find(n=>t===n.classes);return n?n.disableAdd:!1})},createTagTexts(t){let n=new RegExp(this.separators.map(t=>this.quote(t)).join(`|`));return t.split(n).map(t=>({text:t}))},performDeleteTag(t){this.onBeforeDeletingTag||this.deleteTag(t),this.$emit(`before-deleting-tag`,{index:t,tag:this.tagsCopy[t],deleteTag:()=>this.deleteTag(t)})},deleteTag(t){this.disabled||(this.deletionMark=null,clearTimeout(this.deletionMarkTime),this.tagsCopy.splice(t,1),this.$emit(`update:tags`,this.tagsCopy),this.$emit(`tags-changed`,this.tagsCopy))},noTriggerKey(t,n){let r=this[n].indexOf(t.keyCode)!==-1||this[n].indexOf(t.key)!==-1;return r&&t.preventDefault(),!r},performAddTags(t,n,r){if(this.disabled||n&&this.noTriggerKey(n,`addOnKey`))return;let i=[];typeof t==`object`&&(i=[t]),typeof t==`string`&&(i=this.createTagTexts(t)),i=i.filter(t=>t.text.trim().length>0),i.forEach(t=>{t=v(t,this.tags,this.validation,this.isDuplicate),this.onBeforeAddingTag||this.addTag(t,r),this.$emit(`before-adding-tag`,{tag:t,addTag:()=>this.addTag(t,r)})})},duplicateFilter(t){return this.isDuplicate?!this.isDuplicate(this.tagsCopy,t):!this.tagsCopy.find(n=>n.text===t.text)},addTag(t,n=`new-tag-input`){let r=this.filteredAutocompleteItems.map(t=>t.text);this.addOnlyFromAutocomplete&&r.indexOf(t.text)===-1||this.$nextTick(()=>{if(this.maxTags&&this.maxTags<=this.tagsCopy.length)return this.$emit(`max-tags-reached`,t);if(this.avoidAddingDuplicates&&!this.duplicateFilter(t))return this.$emit(`adding-duplicate`,t);this.hasForbiddingAddRule(t.tiClasses)||(this.newTag=``,this.tagsCopy.push(t),this.$emit(`update:tags`,this.tagsCopy),n===`autocomplete`&&this.$refs.newTagInput.focus(),this.$emit(`tags-changed`,this.tagsCopy))})},performSaveTag(t,n){let r=this.tagsCopy[t];this.disabled||n&&this.noTriggerKey(n,`addOnKey`)||r.text.trim().length!==0&&(this[`on-before-saving-tag`]||this.saveTag(t,r),this.$emit(`before-saving-tag`,{index:t,tag:r,saveTag:()=>this.saveTag(t,r)}))},saveTag(t,n){if(this.avoidAddingDuplicates){let r=y(this.tagsCopy),i=r.splice(t,1)[0];if(this.isDuplicate?this.isDuplicate(r,i):r.map(t=>t.text).indexOf(i.text)!==-1)return this.$emit(`saving-duplicate`,n)}this.hasForbiddingAddRule(n.tiClasses)||(this.tagsCopy[t]=n,this.toggleEditMode(t),this.$emit(`update:tags`,this.tagsCopy),this.$emit(`tags-changed`,this.tagsCopy))},tagsEqual(){return!this.tagsCopy.some((t,n)=>!Na(t,this.tags[n]))},updateNewTag(t){let n=t.target.value;this.newTag=n,this.$emit(`update:modelValue`,n)},initTags(){this.tagsCopy=G(this.tags,this.validation,this.isDuplicate),this.tagsEditStatus=y(this.tags).map(()=>!1),this.tagsEqual()||this.$emit(`update:tags`,this.tagsCopy)},blurredOnClick(t){this.$el.contains(t.target)||this.$el.contains(document.activeElement)||this.performBlur(t)},performBlur(){this.addOnBlur&&this.focused&&this.performAddTags(this.newTag),this.focused=!1},tagOrderChanged(){this.$emit(`tag-order-changed`,this.tagsCopy)},performClick(t){if(this.addOnlyFromAutocomplete)return this.$emit(`click`,t),!1;this.selectedItem=null,this.$emit(`click`,t)},getTagIndex(t){return this.tagsCopy.findIndex(n=>n.text===t.text)}},watch:{modelValue(t){this.addOnlyFromAutocomplete||(this.selectedItem=null),this.newTag=t},tags:{handler(){this.initTags()},deep:!0},autocompleteOpen:`selectDefaultItem`},created(){this.newTag=this.modelValue,this.initTags()},mounted(){this.selectDefaultItem(),document.addEventListener(`click`,this.blurredOnClick)},beforeUpdate(){this.tagCenter=[]},unmounted(){document.removeEventListener(`click`,this.blurredOnClick)}},Fa={class:`ti-input`},Ia=[`onClick`],La={class:`ti-content`},Ra={key:0,class:`handle`},za={key:1,class:`ti-tag-left`},Ba=[`onClick`],Va={key:2,class:`ti-tag-right`},Ha={class:`ti-actions`},Ua=[`onClick`],Wa=[`onClick`],Ga={class:`ti-new-tag-input-wrapper`},Ka=[`placeholder`,`value`,`maxlength`,`disabled`],qa={key:1,class:`ti-tags`},Ja=[`onClick`],Ya={class:`ti-content`},Xa={key:0,class:`ti-tag-left`},Za=[`onClick`],Qa={key:1,class:`ti-tag-right`},$a={class:`ti-actions`},eo=[`onClick`],to=[`onClick`],no={class:`ti-new-tag-input-wrapper`},ro=[`placeholder`,`value`,`maxlength`,`disabled`],io=[`onMouseover`],ao=[`onClick`];function ke$1(t,n,r,i,a,o){let c=E(`tag-input`),l=E(`draggable`);return x(),R(`div`,{class:w([`vue-tags-input`,[{"ti-disabled":t.disabled},{"ti-focus":t.focused},t.$attrs.class]]),style:ae(t.$attrs.style)},[I(`div`,Fa,[t.isDraggable?(x(),H(l,{key:0,modelValue:t.tagsCopy,"onUpdate:modelValue":n[9]||(n[9]=n=>t.tagsCopy=n),group:`tags`,class:`ti-tags`,tag:`ul`,draggable:`.item`,handle:t.draggableHandle?`.handle`:``,"ghost-class":`ghost-tag`,"drag-class":`drag-tag`,"item-key":t.getTagIndex,onStart:n[10]||(n[10]=n=>t.drag=!0),onEnd:n[11]||(n[11]=n=>{t.drag=!1,t.tagOrderChanged()})},{item:s(({element:n,index:r})=>[(x(),R(`li`,{key:r,style:ae(n.style),class:w([[{"ti-editing":t.tagsEditStatus[r]},n.tiClasses,n.classes,{"ti-deletion-mark":t.isMarked(r)}],`ti-tag item`]),tabindex:`0`,onClick:i=>t.$emit(`tag-clicked`,{element:n,index:r})},[I(`div`,La,[t.draggableHandle?(x(),R(`span`,Ra,`::`)):U(``,!0),t.$slots[`tag-left`]?(x(),R(`div`,za,[b(t.$slots,`tag-left`,{tag:n,index:r,edit:t.tagsEditStatus[r],performSaveEdit:t.performSaveTag,performDelete:t.performDeleteTag,performCancelEdit:t.cancelEdit,performOpenEdit:t.performEditTag,deletionMark:t.isMarked(r)},void 0,!0)])):U(``,!0),I(`div`,{ref:t.setTagCenter,class:`ti-tag-center`},[t.$slots[`tag-center`]?U(``,!0):(x(),R(`span`,{key:0,class:w({"ti-hidden":t.tagsEditStatus[r]}),onClick:n=>t.performEditTag(r)},N(n.text),11,Ba)),t.$slots[`tag-center`]?U(``,!0):(x(),H(c,{key:1,scope:{edit:t.tagsEditStatus[r],maxlength:t.maxlength,element:n,index:r,validateTag:t.createChangedTag,performCancelEdit:t.cancelEdit,performSaveEdit:t.performSaveTag}},null,8,[`scope`])),b(t.$slots,`tag-center`,{tag:n,index:r,maxlength:t.maxlength,edit:t.tagsEditStatus[r],performSaveEdit:t.performSaveTag,performDelete:t.performDeleteTag,performCancelEdit:t.cancelEdit,validateTag:t.createChangedTag,performOpenEdit:t.performEditTag,deletionMark:t.isMarked(r)},void 0,!0)],512),t.$slots[`tag-right`]?(x(),R(`div`,Va,[b(t.$slots,`tag-right`,{tag:n,index:r,edit:t.tagsEditStatus[r],performSaveEdit:t.performSaveTag,performDelete:t.performDeleteTag,performCancelEdit:t.cancelEdit,performOpenEdit:t.performEditTag,deletionMark:t.isMarked(r)},void 0,!0)])):U(``,!0)]),I(`div`,Ha,[t.$slots[`tag-actions`]?U(``,!0):he((x(),R(`i`,{key:0,class:`ti-icon-undo`,onClick:n=>t.cancelEdit(r)},null,8,Ua)),[[pe,t.tagsEditStatus[r]]]),t.$slots[`tag-actions`]?U(``,!0):he((x(),R(`i`,{key:1,class:`ti-icon-close`,onClick:n=>t.performDeleteTag(r)},null,8,Wa)),[[pe,!t.tagsEditStatus[r]]]),t.$slots[`tag-actions`]?b(t.$slots,`tag-actions`,{key:2,tag:n,index:r,edit:t.tagsEditStatus[r],performSaveEdit:t.performSaveTag,performDelete:t.performDeleteTag,performCancelEdit:t.cancelEdit,performOpenEdit:t.performEditTag,deletionMark:t.isMarked(r)},void 0,!0):U(``,!0)])],14,Ia))]),footer:s(()=>[I(`li`,Ga,[I(`input`,O({ref:`newTagInput`},t.$attrs,{class:[[t.createClasses(t.newTag,t.tags,t.validation,t.isDuplicate)],`ti-new-tag-input`],placeholder:t.placeholder,value:t.newTag,maxlength:t.maxlength,disabled:t.disabled,type:`text`,size:`1`,onKeydown:[n[0]||(n[0]=n=>t.performAddTags(t.filteredAutocompleteItems[t.selectedItem]||t.newTag,n)),n[2]||(n[2]=Se((...n)=>t.invokeDelete&&t.invokeDelete(...n),[`delete`])),n[3]||(n[3]=Se((...n)=>t.performBlur&&t.performBlur(...n),[`tab`])),n[4]||(n[4]=Se(n=>t.selectItem(n,`before`),[`up`])),n[5]||(n[5]=Se(n=>t.selectItem(n,`after`),[`down`]))],onPaste:n[1]||(n[1]=(...n)=>t.addTagsFromPaste&&t.addTagsFromPaste(...n)),onInput:n[6]||(n[6]=(...n)=>t.updateNewTag&&t.updateNewTag(...n)),onFocus:n[7]||(n[7]=n=>t.focused=!0),onClick:n[8]||(n[8]=n=>t.performClick(n))}),null,16,Ka)])]),_:3},8,[`modelValue`,`handle`,`item-key`])):(x(),R(`ul`,qa,[(x(!0),R(ge,null,P(t.tagsCopy,(n,r)=>(x(),R(`li`,{key:r,style:ae(n.style),class:w([[{"ti-editing":t.tagsEditStatus[r]},n.tiClasses,n.classes,{"ti-deletion-mark":t.isMarked(r)}],`ti-tag item`]),tabindex:`0`,onClick:i=>t.$emit(`tag-clicked`,{element:n,index:r})},[I(`div`,Ya,[t.$slots[`tag-left`]?(x(),R(`div`,Xa,[b(t.$slots,`tag-left`,{tag:n,index:r,edit:t.tagsEditStatus[r],performSaveEdit:t.performSaveTag,performDelete:t.performDeleteTag,performCancelEdit:t.cancelEdit,performOpenEdit:t.performEditTag,deletionMark:t.isMarked(r)},void 0,!0)])):U(``,!0),I(`div`,{ref_for:!0,ref:t.setTagCenter,class:`ti-tag-center`},[t.$slots[`tag-center`]?U(``,!0):(x(),R(`span`,{key:0,class:w({"ti-hidden":t.tagsEditStatus[r]}),onClick:n=>t.performEditTag(r)},N(n.text),11,Za)),t.$slots[`tag-center`]?U(``,!0):(x(),H(c,{key:1,scope:{edit:t.tagsEditStatus[r],maxlength:t.maxlength,element:n,index:r,validateTag:t.createChangedTag,performCancelEdit:t.cancelEdit,performSaveEdit:t.performSaveTag}},null,8,[`scope`])),b(t.$slots,`tag-center`,{tag:n,index:r,maxlength:t.maxlength,edit:t.tagsEditStatus[r],performSaveEdit:t.performSaveTag,performDelete:t.performDeleteTag,performCancelEdit:t.cancelEdit,validateTag:t.createChangedTag,performOpenEdit:t.performEditTag,deletionMark:t.isMarked(r)},void 0,!0)],512),t.$slots[`tag-right`]?(x(),R(`div`,Qa,[b(t.$slots,`tag-right`,{tag:n,index:r,edit:t.tagsEditStatus[r],performSaveEdit:t.performSaveTag,performDelete:t.performDeleteTag,performCancelEdit:t.cancelEdit,performOpenEdit:t.performEditTag,deletionMark:t.isMarked(r)},void 0,!0)])):U(``,!0)]),I(`div`,$a,[t.$slots[`tag-actions`]?U(``,!0):he((x(),R(`i`,{key:0,class:`ti-icon-undo`,onClick:n=>t.cancelEdit(r)},null,8,eo)),[[pe,t.tagsEditStatus[r]]]),t.$slots[`tag-actions`]?U(``,!0):he((x(),R(`i`,{key:1,class:`ti-icon-close`,onClick:n=>t.performDeleteTag(r)},null,8,to)),[[pe,!t.tagsEditStatus[r]]]),t.$slots[`tag-actions`]?b(t.$slots,`tag-actions`,{key:2,tag:n,index:r,edit:t.tagsEditStatus[r],performSaveEdit:t.performSaveTag,performDelete:t.performDeleteTag,performCancelEdit:t.cancelEdit,performOpenEdit:t.performEditTag,deletionMark:t.isMarked(r)},void 0,!0):U(``,!0)])],14,Ja))),128)),I(`li`,no,[I(`input`,O({ref:`newTagInput`},t.$attrs,{class:[[t.createClasses(t.newTag,t.tags,t.validation,t.isDuplicate)],`ti-new-tag-input`],placeholder:t.placeholder,value:t.newTag,maxlength:t.maxlength,disabled:t.disabled,type:`text`,size:`1`,onKeydown:[n[12]||(n[12]=n=>t.performAddTags(t.filteredAutocompleteItems[t.selectedItem]||t.newTag,n)),n[14]||(n[14]=Se((...n)=>t.invokeDelete&&t.invokeDelete(...n),[`delete`])),n[15]||(n[15]=Se((...n)=>t.performBlur&&t.performBlur(...n),[`tab`])),n[16]||(n[16]=Se(n=>t.selectItem(n,`before`),[`up`])),n[17]||(n[17]=Se(n=>t.selectItem(n,`after`),[`down`]))],onPaste:n[13]||(n[13]=(...n)=>t.addTagsFromPaste&&t.addTagsFromPaste(...n)),onInput:n[18]||(n[18]=(...n)=>t.updateNewTag&&t.updateNewTag(...n)),onFocus:n[19]||(n[19]=n=>t.focused=!0),onClick:n[20]||(n[20]=n=>t.performClick(n))}),null,16,ro)])]))]),b(t.$slots,`between-elements`,{},void 0,!0),t.autocompleteOpen?(x(),R(`div`,{key:0,class:`ti-autocomplete`,onMouseout:n[21]||(n[21]=n=>t.selectedItem=null)},[b(t.$slots,`autocomplete-header`,{},void 0,!0),I(`ul`,null,[(x(!0),R(ge,null,P(t.filteredAutocompleteItems,(n,r)=>(x(),R(`li`,{key:r,style:ae(n.style),class:w([[n.tiClasses,n.classes,{"ti-selected-item":t.isSelected(r)}],`ti-item`]),onMouseover:n=>t.disabled?!1:t.selectedItem=r},[t.$slots[`autocomplete-item`]?b(t.$slots,`autocomplete-item`,{key:1,item:n,index:r,performAdd:n=>t.performAddTags(n,void 0,`autocomplete`),selected:t.isSelected(r)},void 0,!0):(x(),R(`div`,{key:0,onClick:r=>t.performAddTags(n,void 0,`autocomplete`)},N(n.text),9,ao))],46,io))),128))]),b(t.$slots,`autocomplete-footer`,{},void 0,!0)],32)):U(``,!0)],6)}t(ke$1,`ke`);var oo=B(Pa,[[`render`,ke$1],[`__scopeId`,`data-v-63864685`]]);oo.install=t=>t.component(oo.name,oo),typeof window<`u`&&window.Vue&&window.Vue.use(oo);var so=`modulepreload`,assetsURL=function(t){return`/`+t},co={},lo=function preload(t,n,r){let i=Promise.resolve();if(n&&n.length>0){let t=document.getElementsByTagName(`link`),a=document.querySelector(`meta[property=csp-nonce]`),o=a?.nonce||a?.getAttribute(`nonce`);function allSettled(t){return Promise.all(t.map(t=>Promise.resolve(t).then(t=>({status:`fulfilled`,value:t}),t=>({status:`rejected`,reason:t}))))}i=allSettled(n.map(n=>{if(n=assetsURL(n,r),n in co)return;co[n]=!0;let i=n.endsWith(`.css`),a=i?`[rel="stylesheet"]`:``;if(r)for(let r=t.length-1;r>=0;r--){let a=t[r];if(a.href===n&&(!i||a.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${n}"]${a}`))return;let s=document.createElement(`link`);if(s.rel=i?`stylesheet`:so,i||(s.as=`script`),s.crossOrigin=``,s.href=n,o&&s.setAttribute(`nonce`,o),document.head.appendChild(s),i)return new Promise((t,r)=>{s.addEventListener(`load`,t),s.addEventListener(`error`,()=>r(Error(`Unable to preload CSS for ${n}`)))})}))}function handlePreloadError(t){let n=new Event(`vite:preloadError`,{cancelable:!0});if(n.payload=t,window.dispatchEvent(n),!n.defaultPrevented)throw t}return i.then(n=>{for(let t of n||[])t.status===`rejected`&&handlePreloadError(t.reason);return t().catch(handlePreloadError)})},uo=j({name:`HeatMap`,props:{activityRecords:{type:Array,default:()=>[]},activityRecordsGetter:{type:Function,default:null},inactiveColor:{type:Object,default:()=>({h:0,s:0,l:.9})},activeColor:{type:Object,default:()=>({h:155,s:1,l:.5})},cellSize:{type:Number,default:12},cellMargin:{type:Number,default:3},enableSeasonalColors:{type:Boolean,default:!0}},data(){return{isLoading:!1,localActivityRecords:[],heatmapData:{},weeks:[],tooltipData:null,tooltipStyle:{},maxInRange:0}},computed:{width(){return 53*(this.cellSize+this.cellMargin)},height(){return 7*(this.cellSize+this.cellMargin)},effectiveActivityRecords(){let t=Array.isArray(this.localActivityRecords)&&this.localActivityRecords.length>0,n=t?this.localActivityRecords:this.activityRecords||[];return console.log(`Using effectiveActivityRecords, count:`,n.length,`source:`,t?`local`:`prop`),n}},watch:{activityRecords:{handler(){this.processRecords(),this.createWeeksData()},immediate:!0}},async created(){if(this.activityRecordsGetter)try{this.isLoading=!0,console.log(`Fetching activity records using getter...`);let t=await this.activityRecordsGetter();Array.isArray(t)?(this.localActivityRecords=t.filter(t=>{if(!t||!t.timeStamp)return!1;try{let n=Re(t.timeStamp);return n.isValid()&&n.year()>2e3&&n.year()<2100}catch{return!1}}),console.log(`Received ${t.length} records, ${this.localActivityRecords.length} valid after filtering`),this.processRecords(),this.createWeeksData()):(console.error(`Activity records getter did not return an array:`,t),this.localActivityRecords=[])}catch(t){console.error(`Error fetching activity records:`,t),this.localActivityRecords=[]}finally{this.isLoading=!1}else console.log(`No activityRecordsGetter provided, using direct activityRecords prop`)},methods:{toDateString(t){let n=Re(t);return Re.months()[n.month()]+` `+n.date()},processRecords(){let t=this.effectiveActivityRecords||[];console.log(`Processing ${t.length} records`);let n={};if(t.length===0){console.log(`No records to process`),this.heatmapData=n;return}let r=new Set,i={},a=0,o=0;for(let s=0;s<t.length;s++){let c=t[s];if(!c||typeof c!=`object`||!c.timeStamp){o++;continue}try{let t;if(typeof c.timeStamp==`string`)t=Re(c.timeStamp).format(`YYYY-MM-DD`);else if(typeof c.timeStamp==`number`)t=Re(new Date(c.timeStamp)).format(`YYYY-MM-DD`);else if(typeof c.timeStamp==`object`)t=typeof c.timeStamp.format==`function`?c.timeStamp.format(`YYYY-MM-DD`):c.timeStamp instanceof Date?Re(c.timeStamp).format(`YYYY-MM-DD`):Re(String(c.timeStamp)).format(`YYYY-MM-DD`);else{o++;continue}if(Re(t,`YYYY-MM-DD`,!0).isValid()){n[t]=(n[t]||0)+1,r.add(t);let o=t.substring(0,7);i[o]=(i[o]||0)+1,a++}else o++}catch{o++}}console.log(`Processed ${a} valid dates, ${o} invalid dates`),console.log(`Found ${r.size} unique dates`),console.log(`Date distribution by month:`,i),this.heatmapData=n},createWeeksData(){this.weeks=[],this.maxInRange=0;let t=Re(),n=t.clone().subtract(52,`weeks`),r=n.clone().startOf(`week`);console.log(`Creating weeks data from`,n.format(`YYYY-MM-DD`),`to`,t.format(`YYYY-MM-DD`)),Object.keys(this.heatmapData).length===0&&console.log(`No heatmap data available to display`);let i=Object.keys(this.heatmapData).slice(0,5);for(console.log(`Sample dates in heatmap data:`,i);r.isSameOrBefore(t);){let t=[];for(let n=0;n<7;n++){let n=r.format(`YYYY-MM-DD`),i={date:n,count:this.heatmapData[n]||0};t.push(i),i.count>this.maxInRange&&(this.maxInRange=i.count),r.add(1,`day`)}this.weeks.push(t)}console.log(`Weeks data created, maxInRange:`,this.maxInRange);let a=0,o=0;Object.values(this.heatmapData).forEach(t=>{a++,o+=t}),console.log(`Activity summary: ${o} activities across ${a} days`)},getColor(t){if(this.maxInRange===0)return this.hslToString(this.inactiveColor);let n=t===0?0:Math.min(2*t/this.maxInRange,1),r=this.activeColor;if(this.enableSeasonalColors){let t=Re();t.month()===11&&t.date()>=5?r=Math.random()>.5?{h:350,s:.8,l:.5}:{h:135,s:.8,l:.4}:t.month()===9&&t.date()>=25&&(r=Math.random()>.5?{h:0,s:0,l:0}:Math.random()>.5?{h:30,s:1,l:.5}:{h:270,s:1,l:.5})}let i=r.h,a=this.interpolate(this.inactiveColor.s,r.s,n),o=this.interpolate(this.inactiveColor.l,r.l,n);return this.hslToString({h:i,s:a,l:o})},interpolate(t,n,r){return t+(n-t)*r},hslToString(t){return`hsl(${t.h}, ${t.s*100}%, ${t.l*100}%)`},showTooltip(t,n){this.tooltipData=t,this.tooltipStyle={position:`absolute`,left:`${n.pageX+10}px`,top:`${n.pageY+10}px`}},hideTooltip(){this.tooltipData=null}}}),fo=[`width`,`height`],po=[`transform`],mo=[`y`,`width`,`height`,`fill`,`onMouseover`];function _sfc_render$26(t,n,r,i,a,o){return x(),R(`div`,null,[(x(),R(`svg`,{width:t.width,height:t.height},[(x(!0),R(ge,null,P(t.weeks,(r,i)=>(x(),R(`g`,{key:i,transform:`translate(${i*(t.cellSize+t.cellMargin)}, 0)`},[(x(!0),R(ge,null,P(r,(r,i)=>(x(),R(`rect`,{key:r.date,x:0,y:i*(t.cellSize+t.cellMargin),width:t.cellSize,height:t.cellSize,fill:t.getColor(r.count),onMouseover:n=>t.showTooltip(r,n),onMouseout:n[0]||(n[0]=(...n)=>t.hideTooltip&&t.hideTooltip(...n))},null,40,mo))),128))],8,po))),128))],8,fo)),t.tooltipData?(x(),R(`div`,{key:0,class:`tooltip`,style:ae(t.tooltipStyle)},N(t.tooltipData.count)+` review`+N(t.tooltipData.count===1?``:`s`)+` on `+N(t.toDateString(t.tooltipData.date)),5)):U(``,!0)])}$e(_sfc_render$26,`_sfc_render`);var ho=q(uo,[[`render`,_sfc_render$26],[`__scopeId`,`data-v-ca46239a`]]),_o=j({name:`SkMouseTrap`,props:{refreshInterval:{type:Number,default:500}},data(){return{commands:[],display:!1,intervalId:null}},created(){this.intervalId=window.setInterval(this.refreshState,this.refreshInterval)},beforeUnmount(){this.intervalId!==null&&clearInterval(this.intervalId)},methods:{refreshState(){this.commands=et.commands,this.display=this.commands.length>0}}}),vo={class:`text-caption ml-2`};function _sfc_render$25(t,n,r,i,a,o){let c=E(`v-icon`),l=E(`v-btn`),u=E(`v-toolbar-title`),d=E(`v-toolbar`),p=E(`v-spacer`),m=E(`v-list-item`),h=E(`v-list`),g=E(`v-card`),_=E(`v-dialog`);return t.display?(x(),H(_,{key:0,"max-width":`500px`,transition:`dialog-transition`},{activator:s(({props:t})=>[f(l,O({icon:``,color:`primary`},t),{default:s(()=>[f(c,null,{default:s(()=>n[0]||(n[0]=[A(`mdi-keyboard`)])),_:1})]),_:2},1040)]),default:s(()=>[f(g,null,{default:s(()=>[f(d,{color:`secondary`,dark:``,dense:``},{default:s(()=>[f(u,{class:`text-subtitle-1`},{default:s(()=>n[1]||(n[1]=[A(`Shortcut keys:`)])),_:1})]),_:1}),f(h,{dense:``},{default:s(()=>[(x(!0),R(ge,null,P(t.commands,t=>(x(),H(m,{key:Array.isArray(t.hotkey)?t.hotkey.join(`,`):t.hotkey,class:`py-1`},{default:s(()=>[f(l,{variant:`outlined`,color:`primary`,class:`text-white`,size:`small`},{default:s(()=>[A(N(Array.isArray(t.hotkey)?t.hotkey[0]:t.hotkey),1)]),_:2},1024),f(p),I(`span`,vo,N(t.command),1)]),_:2},1024))),128))]),_:1})]),_:1})]),_:1})):U(``,!0)}$e(_sfc_render$25,`_sfc_render`);var yo=q(_o,[[`render`,_sfc_render$25]]),bo=j({name:`SkMouseTrapToolTip`,props:{hotkey:{type:[String,Array],required:!0},command:{type:String,required:!0},disabled:{type:Boolean,default:!1},position:{type:String,default:`top`},showTooltip:{type:Boolean,default:!0},highlightEffect:{type:String,default:`glow`}},emits:[`hotkey-triggered`],setup(t,{emit:n}){let r=Ce(null),i=Ce(!1);Ce(`hotkey-${Math.random().toString(36).substring(2,15)}`);let a=z(()=>{let n=Array.isArray(t.hotkey)?t.hotkey[0]:t.hotkey;return n.includes(` `)?n.toLowerCase().split(` `).map(t=>t.charAt(0)+t.slice(1)).join(`, `):n.toLowerCase().split(`+`).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(` + `)});le(()=>i.value,n=>{if(!r.value||t.disabled)return;let i=r.value.querySelector(`button, a, input[type="button"], [role="button"]`);i&&(i.style.transition=`all 250ms ease`,n&&t.highlightEffect!==`none`?i.style.filter=`brightness(1.1)`:i.style.filter=``)});let handleKeyDown=t=>{t.key===`Control`&&(i.value=!0)},handleKeyUp=t=>{t.key===`Control`&&(i.value=!1)},handleHotkeyPress=()=>{if(t.disabled||!r.value)return;let i=r.value.querySelector(`button, a, input[type="button"], [role="button"]`);if(i||(i=r.value.querySelector(`v-list-item, .v-list-item, router-link, .router-link, a, [to]`)),!i&&(r.value.hasAttribute(`to`)||r.value.tagName===`A`||r.value.classList.contains(`v-list-item`))&&(i=r.value),!i){let t=r.value.closest(`v-list-item, .v-list-item, a, [to]`);t&&(i=t)}if(i)if(i.hasAttribute(`to`)){let r=i.getAttribute(`to`);if(r&&window.location.pathname!==r){let t=window.$nuxt?.$router||window.$router;t&&typeof t.push==`function`?t.push(r):window.location.pathname=r}n(`hotkey-triggered`,t.hotkey)}else i.click(),n(`hotkey-triggered`,t.hotkey);else console.log(`No clickable element found for hotkey`,t.hotkey),n(`hotkey-triggered`,t.hotkey)},registerHotkey=()=>{t.disabled||et.addBinding({hotkey:t.hotkey,command:t.command,callback:handleHotkeyPress})},unregisterHotkey=()=>{t.disabled||et.removeBinding(t.hotkey)};return le(()=>t.disabled,t=>{t?unregisterHotkey():registerHotkey()}),Ie(()=>{document.addEventListener(`keydown`,handleKeyDown),document.addEventListener(`keyup`,handleKeyUp),registerHotkey()}),C(()=>{document.removeEventListener(`keydown`,handleKeyDown),document.removeEventListener(`keyup`,handleKeyUp),unregisterHotkey()}),{wrapperElement:r,isControlKeyPressed:i,formattedHotkey:a}}});function _sfc_render$24(t,n,r,i,a,o){return x(),R(`div`,{class:w([`sk-mousetrap-tooltip-wrapper`,[t.isControlKeyPressed&&!t.disabled&&t.highlightEffect!==`none`?`sk-mousetrap-highlight-${t.highlightEffect}`:``]]),ref:`wrapperElement`},[b(t.$slots,`default`,{},void 0,!0),f(De,{name:`fade`},{default:s(()=>[t.showTooltip&&t.isControlKeyPressed&&!t.disabled?(x(),R(`div`,{key:0,class:w([`sk-mousetrap-tooltip`,{"sk-mt-tooltip-top":t.position===`top`,"sk-mt-tooltip-bottom":t.position===`bottom`,"sk-mt-tooltip-left":t.position===`left`,"sk-mt-tooltip-right":t.position===`right`}])},N(t.formattedHotkey),3)):U(``,!0)]),_:1})],2)}$e(_sfc_render$24,`_sfc_render`);var xo=q(bo,[[`render`,_sfc_render$24],[`__scopeId`,`data-v-5d6fb09c`]]),{setInstance:So,getInstance:Co,alertUser:wo}=(()=>{let t=null;return{setInstance(n){t=n},getInstance(){return t},alertUser(n){let r=t;if(r){r.addSnack(n);return}console.error(`SnackbarService not found`)}}})(),To=j({name:`SnackbarService`,data(){return{snacks:[],show:[]}},mounted(){So(this)},methods:{addSnack(t){this.snacks.push(t),this.show.push(!0)},close(){this.show.pop(),this.show.push(!1)},getColor(t){if(t.status===Be.ok)return`success`;if(t.status===Be.error)return`error`;if(t.status===Be.warning)return`yellow`}}}),Eo={class:`d-flex align-center justify-space-between w-100`};function _sfc_render$23(t,n,r,i,a,o){let c=E(`v-icon`),l=E(`v-btn`),u=E(`v-snackbar`);return x(),R(`div`,null,[(x(!0),R(ge,null,P(t.snacks,r=>(x(),H(u,{key:t.snacks.indexOf(r),modelValue:t.show[t.snacks.indexOf(r)],"onUpdate:modelValue":n=>t.show[t.snacks.indexOf(r)]=n,timeout:r.timeout,location:`bottom right`,color:t.getColor(r)},{default:s(()=>[I(`div`,Eo,[I(`span`,null,N(r.text),1),f(l,{icon:``,variant:`text`,onClick:n[0]||(n[0]=n=>t.close())},{default:s(()=>[f(c,null,{default:s(()=>n[1]||(n[1]=[A(`mdi-close`)])),_:1})]),_:1})])]),_:2},1032,[`modelValue`,`onUpdate:modelValue`,`timeout`,`color`]))),128))])}$e(_sfc_render$23,`_sfc_render`);var Do=q(To,[[`render`,_sfc_render$23]]),Oo=j({name:`PaginatingToolbar`,props:{pages:{type:Array,required:!0},page:{type:Number,required:!0},title:{type:String,required:!1,default:``},subtitle:{type:String,required:!1,default:``}},emits:[`first`,`prev`,`next`,`last`,`set-page`]}),ko={key:0,class:`ms-2 text-subtitle-2`,"data-cy":`paginating-toolbar-subtitle`};function _sfc_render$22(t,n,r,i,a,o){let c=E(`v-toolbar-title`),l=E(`v-spacer`),u=E(`v-icon`),d=E(`v-btn`),p=E(`v-select`),m=E(`v-toolbar`);return x(),H(m,{density:`compact`},{default:s(()=>[f(c,null,{default:s(()=>[I(`span`,null,N(t.title),1),t.subtitle?(x(),R(`span`,ko,N(t.subtitle),1)):U(``,!0)]),_:1}),f(l),f(d,{variant:`text`,icon:``,color:`secondary`,disabled:t.page==1,onClick:n[0]||(n[0]=n=>t.$emit(`first`))},{default:s(()=>[f(u,null,{default:s(()=>n[5]||(n[5]=[A(`mdi-page-first`)])),_:1})]),_:1},8,[`disabled`]),f(d,{variant:`text`,icon:``,color:`secondary`,disabled:t.page==1,onClick:n[1]||(n[1]=n=>t.$emit(`prev`))},{default:s(()=>[f(u,null,{default:s(()=>n[6]||(n[6]=[A(`mdi-chevron-left`)])),_:1})]),_:1},8,[`disabled`]),f(p,{"model-value":t.page,items:t.pages,class:`pageSelect`,density:`compact`,"hide-details":``,"return-object":!1,variant:`outlined`,"onUpdate:modelValue":n[2]||(n[2]=n=>t.$emit(`set-page`,n))},{selection:s(({item:t})=>[A(N(t.value),1)]),_:1},8,[`model-value`,`items`]),f(d,{variant:`text`,icon:``,color:`secondary`,disabled:t.page==t.pages.length,onClick:n[3]||(n[3]=n=>t.$emit(`next`))},{default:s(()=>[f(u,null,{default:s(()=>n[7]||(n[7]=[A(`mdi-chevron-right`)])),_:1})]),_:1},8,[`disabled`]),f(d,{variant:`text`,icon:``,color:`secondary`,disabled:t.page==t.pages.length,onClick:n[4]||(n[4]=n=>t.$emit(`last`))},{default:s(()=>[f(u,null,{default:s(()=>n[8]||(n[8]=[A(`mdi-page-last`)])),_:1})]),_:1},8,[`disabled`])]),_:1})}$e(_sfc_render$22,`_sfc_render`);var Ao=q(Oo,[[`render`,_sfc_render$22],[`__scopeId`,`data-v-a75fea7e`]]),jo=j({name:`CardSearch`,emits:{search:t=>typeof t==`string`},data(){return{query:``}},methods:{search(){this.$emit(`search`,this.query)}}}),Mo={class:`card-search`};function _sfc_render$21(t,n,r,i,a,o){let s=E(`v-text-field`);return x(),R(`div`,Mo,[f(s,{modelValue:t.query,"onUpdate:modelValue":n[0]||(n[0]=n=>t.query=n),label:`Search for cards...`,"append-icon":`mdi-magnify`,"onClick:append":t.search,onKeydown:Se(t.search,[`enter`])},null,8,[`modelValue`,`onClick:append`,`onKeydown`])])}$e(_sfc_render$21,`_sfc_render`);var No=q(jo,[[`render`,_sfc_render$21]]),Po=j({name:`CardSearchResults`,emits:{"card-selected":t=>typeof t.cardId==`string`&&typeof t.courseId==`string`},props:{query:{type:String,required:!0},dataLayer:{type:Object,required:!0},courseFilter:{type:String,default:null}},data(){return{cards:[],loading:!1,error:null,selectedCardId:null}},watch:{query:{immediate:!0,handler(t){t&&this.fetchResults(t)}}},methods:{async fetchResults(t){this.loading=!0,this.error=null;try{let n=[];if(this.courseFilter)n=[this.courseFilter],console.log(`Filtering search to course: ${this.courseFilter}`);else{let{CourseLookup:t}=await lo(async()=>{let{CourseLookup:t}=await import(`./dist-TKyu-T8A.js`);return{CourseLookup:t}},__vite__mapDeps([0,1,2,3]));n=(await t.allCourseWare()).map(t=>t._id).filter(Boolean),console.log(`Searching across all ${n.length} courses`)}let r=[];for(let i of n){let n=await this.dataLayer.getCourseDB(i).searchCards(t);for(let t of n)r.push({...t,courseId:i})}this.cards=r,console.log(`Search completed: found ${r.length} cards across ${n.length} courses`)}catch(t){this.error=`Error fetching search results.`,console.error(`Search error:`,t)}finally{this.loading=!1}},selectCard(t){this.selectedCardId=t._id,this.$emit(`card-selected`,{cardId:t._id,courseId:t.courseId})}}}),Fo={class:`card-search-results`},Io={key:0},Lo={key:1},Ro={key:2};function _sfc_render$20(t,n,r,i,a,o){let c=E(`v-list-item-title`),l=E(`v-list-item-subtitle`),u=E(`v-list-item`),d=E(`v-list`);return x(),R(`div`,Fo,[t.loading?(x(),R(`div`,Io,`Loading...`)):t.error?(x(),R(`div`,Lo,N(t.error),1)):(x(),R(`div`,Ro,[f(d,null,{default:s(()=>[(x(!0),R(ge,null,P(t.cards,n=>(x(),H(u,{key:n._id,onClick:r=>t.selectCard(n),class:w([{"selected-card":n._id===t.selectedCardId},`cursor-pointer`])},{default:s(()=>[f(c,null,{default:s(()=>[A(N(n._id),1)]),_:2},1024),f(l,null,{default:s(()=>[A(`Course: `+N(n.courseId),1)]),_:2},1024)]),_:2},1032,[`onClick`,`class`]))),128))]),_:1})]))])}$e(_sfc_render$20,`_sfc_render`);var zo=q(Po,[[`render`,_sfc_render$20],[`__scopeId`,`data-v-285e13bd`]]),Bo=j({name:`CardHistoryViewer`,props:{cardId:{type:String,required:!0},courseId:{type:String,required:!0},userId:{type:String,required:!0},userDB:{type:Object,required:!0}},data(){return{history:[],cardHistory:null,bestIntervalHumanized:``,loading:!1,error:null,headers:[{title:`Timestamp`,key:`formattedTimeStamp`},{title:`Interval`,key:`userFriendlyInterval`},{title:`Time Spent (s)`,key:`timeSpentSeconds`},{title:`Correct?`,key:`isCorrect`},{title:`Performance`,key:`performance`},{title:`Prior Attempts`,key:`priorAttemps`},{title:`User Answer`,key:`userAnswer`}]}},watch:{cardId:{immediate:!0,handler(t){t&&this.userDB&&this.fetchHistory()}},userDB:{handler(t){t&&this.cardId&&this.fetchHistory()}}},methods:{async fetchHistory(){this.loading=!0,this.error=null;try{let t=nt(this.courseId,this.cardId),n=await this.userDB.get(t);this.cardHistory=n,this.bestIntervalHumanized=Re.duration(n.bestInterval,`seconds`).humanize();let r=[...n.records].sort((t,n)=>Re(t.timeStamp).valueOf()-Re(n.timeStamp).valueOf());this.history=r.map((t,n)=>{let i=Re(t.timeStamp),a={...t,formattedTimeStamp:i.format(`YYYY-MM-DD HH:mm:ss`),timeSpentSeconds:Math.round(t.timeSpent/1e3),isCorrect:t.isCorrect,performance:t.performance,priorAttemps:t.priorAttemps,userAnswer:t.userAnswer};if(n>0){let t=Re(r[n-1].timeStamp),o=i.diff(t,`seconds`,!0);a.intervalFromPrevious=Math.round(o*100)/100,a.userFriendlyInterval=`${a.intervalFromPrevious} sec (${Re.duration(o,`seconds`).humanize()})`}return a})}catch(t){this.error=`Error fetching card history.`,console.error(t)}finally{this.loading=!1}}}}),Vo={class:`card-history-viewer`},Ho={key:0},Uo={key:1},Wo={key:2,class:`error-message`},Go={key:3};function _sfc_render$19(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-list-item-title`),u=E(`v-list-item-subtitle`),d=E(`v-list-item-content`),p=E(`v-list-item`),m=E(`v-card`),h=E(`v-data-table`);return x(),R(`div`,Vo,[t.userId?(x(),R(`h3`,Ho,`Card History for User: `+N(t.userId),1)):U(``,!0),t.loading?(x(),R(`div`,Uo,`Loading...`)):t.error?(x(),R(`div`,Wo,N(t.error),1)):t.cardHistory?(x(),R(`div`,Go,[f(m,{class:`mb-4`},{default:s(()=>[f(c,null,{default:s(()=>n[0]||(n[0]=[A(`Summary`)])),_:1}),f(p,null,{default:s(()=>[f(d,null,{default:s(()=>[f(l,null,{default:s(()=>[A(`Best Interval: `+N(t.cardHistory.bestInterval)+` seconds (`+N(t.bestIntervalHumanized)+`)`,1)]),_:1}),f(u,null,{default:s(()=>n[1]||(n[1]=[A(`The to-date largest interval between successful card reviews.`)])),_:1})]),_:1})]),_:1}),f(p,null,{default:s(()=>[f(d,null,{default:s(()=>[f(l,null,{default:s(()=>[A(`Lapses: `+N(t.cardHistory.lapses),1)]),_:1}),f(u,null,{default:s(()=>n[2]||(n[2]=[A(`The number of times that a card has been failed in review.`)])),_:1})]),_:1})]),_:1}),f(p,null,{default:s(()=>[f(d,null,{default:s(()=>[f(l,null,{default:s(()=>[A(`Streak: `+N(t.cardHistory.streak),1)]),_:1}),f(u,null,{default:s(()=>n[3]||(n[3]=[A(`The number of consecutive successful impressions on this card.`)])),_:1})]),_:1})]),_:1})]),_:1}),f(h,{headers:t.headers,items:t.history,class:`elevation-1`},null,8,[`headers`,`items`])])):U(``,!0)])}$e(_sfc_render$19,`_sfc_render`);var Ko=q(Bo,[[`render`,_sfc_render$19],[`__scopeId`,`data-v-a4bdfdfb`]]),Displayable=class{constructor(t){if(t.length===0)throw Error(`
|
|
15
15
|
Displayable Constructor was called with no view Data.
|
|
16
16
|
`);validateData(this.dataShapes(),t)}};Je(Displayable,`dataShapes`,void 0),Je(Displayable,`views`,void 0),Je(Displayable,`seedData`,void 0),Je(Displayable,`acceptsUserData`,!0);function validateData(t,n){for(let r=0;r<t.length;r++)t[r].fields.forEach((t,i)=>{console.log(`[Displayable] shape[${r}].field[${i}]:\n ${JSON.stringify(t)}`),n[r][t.name]===void 0&&t.type!==ze.MEDIA_UPLOADS&&console.warn(`[Displayable] missing data`)})}var Question=class extends Displayable{displayedSkill(t,n){console.warn(`Question is running the reference implementation of displayedSkill.
|
|
17
|
-
Consider overriding!`);let r=5e3,i=Math.min(n,10*r),a=i/r,o=i>r?.8**a:1,s=this.isCorrect(t)?1:0;return s*=o,Math.min(s,1)}evaluate(t,n){return{isCorrect:this.isCorrect(t),performance:this.displayedSkill(t,n)}}},getApiBase=()=>{let t=`fallback (empty string)`,n=``;if(!n&&typeof window<`u`&&window.__SKUILDER_CONFIG__?.apiBase){let r=window.__SKUILDER_CONFIG__.apiBase.replace(/\/$/,``);n=r.startsWith(`/`)?r:`/${r}`,t=`window.__SKUILDER_CONFIG__.apiBase`}return console.log(`[authAPI] getApiBase() called`),console.log(`[authAPI] source:`,t),console.log(`[authAPI] result:`,n),n};async function sendVerificationEmail(t,n,r){try{let i={username:t,email:n};r&&(i.origin=r);let a=await fetch(`${getApiBase()}/auth/send-verification`,{method:`POST`,headers:{"Content-Type":`application/json`},credentials:`include`,body:JSON.stringify(i)});if(!a.ok){let t=await a.text();return console.error(`Send verification email error:`,t),{ok:!1,error:`HTTP ${a.status}: ${a.statusText}`}}return await a.json()}catch(t){return console.error(`Send verification email fetch error:`,t),{ok:!1,error:t instanceof Error?t.message:`Network error`}}}async function verifyEmail(t){try{let n=await fetch(`${getApiBase()}/auth/verify`,{method:`POST`,headers:{"Content-Type":`application/json`},credentials:`include`,body:JSON.stringify({token:t})});return n.ok?await n.json()
|
|
17
|
+
Consider overriding!`);let r=5e3,i=Math.min(n,10*r),a=i/r,o=i>r?.8**a:1,s=this.isCorrect(t)?1:0;return s*=o,Math.min(s,1)}evaluate(t,n){return{isCorrect:this.isCorrect(t),performance:this.displayedSkill(t,n)}}},getApiBase=()=>{let t=`fallback (empty string)`,n=``;if(!n&&typeof window<`u`&&window.__SKUILDER_CONFIG__?.apiBase){let r=window.__SKUILDER_CONFIG__.apiBase.replace(/\/$/,``);n=r.startsWith(`/`)?r:`/${r}`,t=`window.__SKUILDER_CONFIG__.apiBase`}return console.log(`[authAPI] getApiBase() called`),console.log(`[authAPI] source:`,t),console.log(`[authAPI] result:`,n),n};async function sendVerificationEmail(t,n,r){try{let i={username:t,email:n};r&&(i.origin=r);let a=await fetch(`${getApiBase()}/auth/send-verification`,{method:`POST`,headers:{"Content-Type":`application/json`},credentials:`include`,body:JSON.stringify(i)});if(!a.ok){let t=await a.text();return console.error(`Send verification email error:`,t),{ok:!1,error:`HTTP ${a.status}: ${a.statusText}`}}return await a.json()}catch(t){return console.error(`Send verification email fetch error:`,t),{ok:!1,error:t instanceof Error?t.message:`Network error`}}}async function verifyEmail(t){try{let n=await fetch(`${getApiBase()}/auth/verify`,{method:`POST`,headers:{"Content-Type":`application/json`},credentials:`include`,body:JSON.stringify({token:t})});if(!n.ok){let t;try{t=(await n.json())?.error}catch{}return{ok:!1,error:t||`HTTP ${n.status}: ${n.statusText}`}}return await n.json()}catch(t){return{ok:!1,error:t instanceof Error?t.message:`Network error`}}}async function resolveLoginIdentifier(t,n){try{let r=await fetch(`${getApiBase()}/auth/resolve-login`,{method:`POST`,headers:{"Content-Type":`application/json`},credentials:`include`,body:JSON.stringify({identifier:t,password:n})});if(!r.ok){let t;try{t=(await r.json())?.error}catch{}return{ok:!1,error:t||`HTTP ${r.status}: ${r.statusText}`}}return await r.json()}catch(t){return{ok:!1,error:t instanceof Error?t.message:`Network error`}}}async function requestPasswordReset(t,n){try{let r={email:t};n&&(r.origin=n);let i=await fetch(`${getApiBase()}/auth/request-reset`,{method:`POST`,headers:{"Content-Type":`application/json`},credentials:`include`,body:JSON.stringify(r)});return i.ok?await i.json():{ok:!1,error:`HTTP ${i.status}: ${i.statusText}`}}catch(t){return{ok:!1,error:t instanceof Error?t.message:`Network error`}}}async function resetPassword(t,n){try{let r=await fetch(`${getApiBase()}/auth/reset-password`,{method:`POST`,headers:{"Content-Type":`application/json`},credentials:`include`,body:JSON.stringify({token:t,newPassword:n})});return r.ok?await r.json():{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`}}catch(t){return{ok:!1,error:t instanceof Error?t.message:`Network error`}}}var qo=j({name:`StudySessionTimer`,props:{timeRemaining:{type:Number,required:!0},sessionTimeLimit:{type:Number,required:!0,default:5},allowAddTime:{type:Boolean,default:!0}},emits:[`add-time`],setup(t,{emit:n}){let r=Ce(!1),i=z(()=>{let n=``,r=t.timeRemaining;r>60&&(n=Math.floor(r/60).toString()+`:`);let i=r%60;return n+=i>=10?i:`0`+i,r<=60&&(n+=` seconds`),n+=` left!`,n}),a=z(()=>t.timeRemaining>60?100*(t.timeRemaining/(60*t.sessionTimeLimit)):100*(t.timeRemaining/60)),o=z(()=>t.timeRemaining>60?`primary`:`orange darken-3`),addSessionTime=()=>{n(`add-time`)};return{hovered:r,formattedTimeRemaining:i,percentageRemaining:a,timerColor:o,addSessionTime}}});function _sfc_render$18(t,n,r,i,a,o){let c=E(`v-icon`),l=E(`v-btn`),u=E(`v-progress-circular`),d=E(`v-tooltip`);return x(),H(d,{location:`right`,"open-delay":0,"close-delay":200,color:`secondary`,class:`text-subtitle-1`},{activator:s(({props:r})=>[I(`div`,O({class:`timer-container`},r,{onMouseenter:n[0]||(n[0]=n=>t.hovered=!0),onMouseleave:n[1]||(n[1]=n=>t.hovered=!1)}),[f(u,{alt:`Time remaining in study session`,size:`64`,width:`8`,rotate:`0`,color:t.timerColor,"model-value":t.percentageRemaining},{default:s(()=>[t.allowAddTime&&t.timeRemaining>0&&t.hovered?(x(),H(l,{key:0,icon:``,color:`transparent`,location:`bottom left`,onClick:t.addSessionTime},{default:s(()=>[f(c,{size:`large`},{default:s(()=>n[2]||(n[2]=[A(`mdi-plus`)])),_:1})]),_:1},8,[`onClick`])):U(``,!0)]),_:1},8,[`color`,`model-value`])],16)]),default:s(()=>[A(` `+N(t.formattedTimeRemaining),1)]),_:1})}$e(_sfc_render$18,`_sfc_render`);var Jo=q(qo,[[`render`,_sfc_render$18],[`__scopeId`,`data-v-5e104ccc`]]),Yo=j({name:`CardViewer`,ref:{},props:{sessionOrder:{type:Number,required:!1,default:0},card_id:{type:String,required:!0,default:``},course_id:{type:String,required:!0,default:``},view:{type:[Function,Object],required:!0},data:{type:Array,required:!0},user_elo:{type:Object,default:()=>({global:{score:1e3,count:0},tags:{},misc:{}})},card_elo:{type:Number,default:1e3},frameless:{type:Boolean,default:!1}},emits:[`emitResponse`,`requestReplan`,`readyToAdvance`],methods:{processResponse(t){console.log(`
|
|
18
18
|
Card was displayed at ${t.timeStamp}
|
|
19
19
|
User spent ${t.timeSpent} milliseconds with the card.
|
|
20
20
|
`),this.$emit(`emitResponse`,t)}}});function _sfc_render$17(t,n,r,i,a,o){let c=E(`v-card`);return t.frameless?(x(),H(T(t.view),{ref:`activeView`,key:t.course_id+`-`+t.card_id+`-`+t.sessionOrder,data:t.data,"modify-difficulty":t.user_elo.global.score-t.card_elo,class:`cardView`,onEmitResponse:n[0]||(n[0]=n=>t.processResponse(n)),onRequestReplan:n[1]||(n[1]=n=>t.$emit(`requestReplan`,n)),onReadyToAdvance:n[2]||(n[2]=n=>t.$emit(`readyToAdvance`))},null,40,[`data`,`modify-difficulty`])):(x(),H(c,{key:1,elevation:`12`},{default:s(()=>[(x(),H(T(t.view),{ref:`activeView`,key:t.course_id+`-`+t.card_id+`-`+t.sessionOrder,data:t.data,"modify-difficulty":t.user_elo.global.score-t.card_elo,class:`cardView ma-2 pa-2`,onEmitResponse:n[3]||(n[3]=n=>t.processResponse(n)),onRequestReplan:n[4]||(n[4]=n=>t.$emit(`requestReplan`,n)),onReadyToAdvance:n[5]||(n[5]=n=>t.$emit(`readyToAdvance`))},null,40,[`data`,`modify-difficulty`]))]),_:1}))}$e(_sfc_render$17,`_sfc_render`);var Xo=q(Yo,[[`render`,_sfc_render$17],[`__scopeId`,`data-v-2d892b82`]]),Zo=j({name:`SessionControllerDebug`,props:{sessionController:{type:Object,required:!0}},setup(t){let n=Ce(0),r=null;Ie(()=>{r=setInterval(()=>{n.value++},500)}),u(()=>{r&&clearInterval(r)});let i=z(()=>(n.value,t.sessionController?t.sessionController.getDebugInfo():{supplyQueue:{length:0,dequeueCount:0,items:[]},failedQueue:{length:0,dequeueCount:0,items:[]},hydratedCache:{count:0,failedCacheSize:0,items:[]}})),fmtScore=t=>t===void 0?``:Number.isFinite(t)?t.toFixed(2):`REQ`;return{debugInfo:i,fmtScore}}}),Qo={class:`debug-section`},$o={class:`debug-header`},es={class:`debug-stats`},ts={class:`text-caption`},ns={class:`text-caption ml-2`},rs={key:0,class:`debug-items`},as={class:`text-caption`},os={class:`text-caption text-grey ml-1`},ss={class:`text-caption ml-1`,style:{color:`#90caf9`}},cs={key:0,class:`text-caption text-grey`},ls={key:1,class:`text-caption text-grey`},us={class:`debug-section`},ds={class:`debug-header`},fs={class:`debug-stats`},ps={class:`text-caption`},ms={class:`text-caption ml-2`},hs={key:0,class:`debug-items`},gs={class:`text-caption`},_s={class:`text-caption text-grey ml-1`},vs={key:0,class:`text-caption text-grey`},ys={key:1,class:`text-caption text-grey`},bs={class:`debug-section`},xs={class:`debug-header`},Ss={class:`debug-stats`},Cs={class:`text-caption`},ws={class:`text-caption ml-2`},Ts={key:0,class:`debug-items`},Es={class:`text-caption`},Ds={key:0,class:`text-caption text-grey`},Os={key:1,class:`text-caption text-grey`};function _sfc_render$16(t,n,r,i,a,o){let c=E(`v-spacer`),l=E(`v-icon`),u=E(`v-card-title`),d=E(`v-col`),p=E(`v-row`),m=E(`v-divider`),h=E(`v-card-text`),g=E(`v-card`);return t.sessionController?(x(),H(g,{key:0,class:`session-debug ma-2`,elevation:`2`},{default:s(()=>[f(u,{class:`text-caption bg-grey-darken-3`},{default:s(()=>[n[1]||(n[1]=A(` Session Controller Debug `)),f(c),f(l,{size:`small`},{default:s(()=>n[0]||(n[0]=[A(`mdi-bug`)])),_:1})]),_:1}),f(h,{class:`pa-2`},{default:s(()=>[f(p,{dense:``},{default:s(()=>[f(d,{cols:`12`,md:`8`},{default:s(()=>[I(`div`,Qo,[I(`div`,$o,[f(l,{size:`x-small`,class:`mr-1`},{default:s(()=>n[2]||(n[2]=[A(`mdi-sort`)])),_:1}),n[3]||(n[3]=I(`strong`,null,`Supply Queue`,-1))]),I(`div`,es,[I(`span`,ts,`Length: `+N(t.debugInfo.supplyQueue.length),1),I(`span`,ns,`Dequeued: `+N(t.debugInfo.supplyQueue.dequeueCount),1)]),t.debugInfo.supplyQueue.items.length>0?(x(),R(`div`,rs,[(x(!0),R(ge,null,P(t.debugInfo.supplyQueue.items.slice(0,8),(n,r)=>(x(),R(`div`,{key:r,class:`debug-item`},[I(`span`,as,N(r)+`: `+N(n.courseID)+`::`+N(n.cardID),1),I(`span`,os,`(`+N(n.status)+`)`,1),I(`span`,ss,N(t.fmtScore(n.score)),1)]))),128)),t.debugInfo.supplyQueue.items.length>8?(x(),R(`div`,cs,` ... +`+N(t.debugInfo.supplyQueue.items.length-8)+` more `,1)):U(``,!0)])):(x(),R(`div`,ls,` (empty) `))])]),_:1}),f(d,{cols:`12`,md:`4`},{default:s(()=>[I(`div`,us,[I(`div`,ds,[f(l,{size:`x-small`,class:`mr-1`},{default:s(()=>n[4]||(n[4]=[A(`mdi-alert-circle`)])),_:1}),n[5]||(n[5]=I(`strong`,null,`Failed Cards Queue`,-1))]),I(`div`,fs,[I(`span`,ps,`Length: `+N(t.debugInfo.failedQueue.length),1),I(`span`,ms,`Dequeued: `+N(t.debugInfo.failedQueue.dequeueCount),1)]),t.debugInfo.failedQueue.items.length>0?(x(),R(`div`,hs,[(x(!0),R(ge,null,P(t.debugInfo.failedQueue.items.slice(0,5),(t,n)=>(x(),R(`div`,{key:n,class:`debug-item`},[I(`span`,gs,N(n)+`: `+N(t.courseID)+`::`+N(t.cardID),1),I(`span`,_s,`(`+N(t.status)+`)`,1)]))),128)),t.debugInfo.failedQueue.items.length>5?(x(),R(`div`,vs,` ... +`+N(t.debugInfo.failedQueue.items.length-5)+` more `,1)):U(``,!0)])):(x(),R(`div`,ys,` (empty) `))])]),_:1})]),_:1}),f(p,{dense:``},{default:s(()=>[f(d,{cols:`12`},{default:s(()=>[f(m,{class:`my-2`}),I(`div`,bs,[I(`div`,xs,[f(l,{size:`x-small`,class:`mr-1`},{default:s(()=>n[6]||(n[6]=[A(`mdi-database`)])),_:1}),n[7]||(n[7]=I(`strong`,null,`Hydrated Cards Cache`,-1))]),I(`div`,Ss,[I(`span`,Cs,`Cached: `+N(t.debugInfo.hydratedCache.count),1),I(`span`,ws,`Failed Cache: `+N(t.debugInfo.hydratedCache.failedCacheSize),1)]),t.debugInfo.hydratedCache.items.length>0?(x(),R(`div`,Ts,[(x(!0),R(ge,null,P(t.debugInfo.hydratedCache.items.slice(0,8),(t,n)=>(x(),R(`div`,{key:n,class:`debug-item d-inline-block mr-3`},[I(`span`,Es,N(t.courseID)+`::`+N(t.cardID),1)]))),128)),t.debugInfo.hydratedCache.items.length>8?(x(),R(`div`,Ds,` ... +`+N(t.debugInfo.hydratedCache.items.length-8)+` more `,1)):U(``,!0)])):(x(),R(`div`,Os,` (empty) `))])]),_:1})]),_:1})]),_:1})]),_:1})):U(``,!0)}$e(_sfc_render$16,`_sfc_render`);var ks=q(Zo,[[`render`,_sfc_render$16],[`__scopeId`,`data-v-641ac170`]]),As={};(function main(t,n,r,i){var a=!!(t.Worker&&t.Blob&&t.Promise&&t.OffscreenCanvas&&t.OffscreenCanvasRenderingContext2D&&t.HTMLCanvasElement&&t.HTMLCanvasElement.prototype.transferControlToOffscreen&&t.URL&&t.URL.createObjectURL),o=typeof Path2D==`function`&&typeof DOMMatrix==`function`,s=(function(){if(!t.OffscreenCanvas)return!1;var n=new OffscreenCanvas(1,1),r=n.getContext(`2d`);r.fillRect(0,0,1,1);var i=n.transferToImageBitmap();try{r.createPattern(i,`no-repeat`)}catch{return!1}return!0})();function noop(){}function promise(r){var i=n.exports.Promise,a=i===void 0?t.Promise:i;return typeof a==`function`?new a(r):(r(noop,noop),null)}var c=(function(t,n){return{transform:function(r){if(t)return r;if(n.has(r))return n.get(r);var i=new OffscreenCanvas(r.width,r.height);return i.getContext(`2d`).drawImage(r,0,0),n.set(r,i),i},clear:function(){n.clear()}}})(s,new Map),l=function(){var t=16,frame,cancel,n={},r=0;return typeof requestAnimationFrame==`function`&&typeof cancelAnimationFrame==`function`?(frame=function(i){var a=Math.random();return n[a]=requestAnimationFrame(function onFrame(o){r===o||r+t-1<o?(r=o,delete n[a],i()):n[a]=requestAnimationFrame(onFrame)}),a},cancel=function(t){n[t]&&cancelAnimationFrame(n[t])}):(frame=function(n){return setTimeout(n,t)},cancel=function(t){return clearTimeout(t)}),{frame,cancel}}(),u=(function(){var t,n,i={};function decorate(t){function execute(n,r){t.postMessage({options:n||{},callback:r})}t.init=function initWorker(n){var r=n.transferControlToOffscreen();t.postMessage({canvas:r},[r])},t.fire=function fireWorker(r,a,o){if(n)return execute(r,null),n;var s=Math.random().toString(36).slice(2);return n=promise(function(a){function workerDone(r){r.data.callback===s&&(delete i[s],t.removeEventListener(`message`,workerDone),n=null,c.clear(),o(),a())}t.addEventListener(`message`,workerDone),execute(r,s),i[s]=workerDone.bind(null,{data:{callback:s}})}),n},t.reset=function resetWorker(){for(var n in t.postMessage({reset:!0}),i)i[n](),delete i[n]}}return function(){if(t)return t;if(!r&&a){var n=[`var CONFETTI, SIZE = {}, module = {};`,`(`+main.toString()+`)(this, module, true, SIZE);`,`onmessage = function(msg) {`,` if (msg.data.options) {`,` CONFETTI(msg.data.options).then(function () {`,` if (msg.data.callback) {`,` postMessage({ callback: msg.data.callback });`,` }`,` });`,` } else if (msg.data.reset) {`,` CONFETTI && CONFETTI.reset();`,` } else if (msg.data.resize) {`,` SIZE.width = msg.data.resize.width;`,` SIZE.height = msg.data.resize.height;`,` } else if (msg.data.canvas) {`,` SIZE.width = msg.data.canvas.width;`,` SIZE.height = msg.data.canvas.height;`,` CONFETTI = module.exports.create(msg.data.canvas);`,` }`,`}`].join(`
|
|
@@ -25,7 +25,7 @@ Displayable Constructor was called with no view Data.
|
|
|
25
25
|
`)}catch(t){console.error(`[StudySession] Error during final session setup:`,t)}if(this.sessionController)try{this.$emit(`session-started`),this.loadCard(await this.sessionController.nextCard())}catch(t){console.error(`[StudySession] Error loading next card:`,t),this.$emit(`session-error`,{message:`Failed to load study card`,error:t})}else console.error(`[StudySession] Cannot load card: session controller not initialized`),this.$emit(`session-error`,{message:`Study session initialization failed`})},countCardViews(t,n){return this.sessionRecord.filter(r=>r.card.course_id===t&&r.card.card_id===n).length},async processResponse(t){this.$emit(`card-response`,t),this.timerIsActive=!0,t.cardID=this.cardID,t.courseID=this.courseID,this.currentCard.records.push(t),console.log(`[StudySession] StudySession.processResponse is running...`);let n=this.logCardRecord(t).catch(t=>{throw console.error(`[StudySession] putCardRecord failed:`,t),t}),r=1,i=1;if(Ze(this.$refs.cardViewer?.$refs.activeView)){let t=this.$refs.cardViewer.$refs.activeView;r=t.maxAttemptsPerView,i=t.maxSessionViews}let a=this.countCardViews(this.courseID,this.cardID),o=await this.sessionController.submitResponse(t,n,this.userCourseRegDoc,this.currentCard,this.courseID,this.cardID,r,i,a);try{this.handleUIFeedback(o)}catch(t){console.error(`[StudySession] Error handling UI feedback: ${t}.\n\nResult: ${JSON.stringify(o)}`)}if(this.replanPending){let t=this.replanOptions,n=t?.label,r=n?` [${n}]`:``;console.log(`[StudySession] Firing deferred replan (post-submitResponse)${r}`),this.replanPending=!1,this.replanOptions=null,this.sessionController.requestReplan(t??void 0),this.$emit(`replan-requested`)}o.deferred?(console.log(`[StudySession] Deferred advance — stashing action: ${o.nextCardAction}`),this.deferredNextCardAction=o.nextCardAction):o.shouldLoadNextCard&&this.loadCard(await this.sessionController.nextCard(o.nextCardAction)),o.shouldClearFeedbackShadow&&this.clearFeedbackShadow()},handleUIFeedback(t){if(t.isCorrect){if(!this.frameless)try{this.$refs.shadowWrapper&&t.performanceScore!==void 0&&(this.$refs.shadowWrapper.setAttribute(`style`,`--r: ${255*(1-t.performanceScore)}; --g:255`),this.$refs.shadowWrapper.classList.add(`correct`))}catch(t){console.warn(`[StudySession] Error setting shadowWrapper style: ${t}`)}this.sessionConfig.likesConfetti&&js({origin:{y:1,x:.25+.5*Math.random()},disableForReducedMotion:!0,angle:60+60*Math.random()})}else if(!this.frameless)try{this.$refs.shadowWrapper&&this.$refs.shadowWrapper.classList.add(`incorrect`)}catch(t){console.warn(`[StudySession] Error setting shadowWrapper style: ${t}`)}},clearFeedbackShadow(){this.frameless||setTimeout(()=>{try{this.$refs.shadowWrapper&&this.$refs.shadowWrapper.classList.remove(`correct`,`incorrect`)}catch(t){console.warn(`[StudySession] Error clearing shadowWrapper style: ${t}`)}},1250)},async logCardRecord(t){console.log(`[StudySession] About to call user.putCardRecord...`);let n=await this.user.putCardRecord(t);return console.log(`[StudySession] user.putCardRecord completed`),n},async loadCard(t){if(this.loading){console.warn(`Attempted to load card while loading another...`);return}if(console.log(`[StudySession] loading: ${JSON.stringify(t)}`),t===null){this.sessionFinished=!0,this.$emit(`session-finished`,this.sessionRecord);return}this.cardType=t.item.status,this.loading=!0,this.cardCount++,this.data=t.data,this.view=de(t.view),this.cardID=t.item.cardID,this.courseID=t.item.courseID,this.card_elo=t.item.elo||1e3,this.sessionRecord.push({card:{course_id:t.item.courseID,card_id:t.item.cardID,card_elo:this.card_elo,tags:t.tags??[]},item:t.item,records:[]}),this.$emit(`card-loaded`,{courseID:t.item.courseID,cardID:t.item.cardID,cardCount:this.cardCount}),this.loading=!1}}}),Ns={key:0,class:`StudySession`},Ps={key:2},Fs={key:3,class:`session-finished-area`},Is={class:`text-h4`},Ls={key:0},Rs={key:4,ref:`shadowWrapper`,class:`card-transition-container`},zs={key:0};function _sfc_render$15(t,n,r,i,a,o){let c=E(`v-spacer`),l=E(`v-progress-circular`),u=E(`v-row`),d=E(`session-controller-debug`),p=E(`heat-map`),m=E(`card-viewer`),h=E(`StudySessionTimer`),g=E(`v-col`),_=E(`SkMouseTrap`);return t.sessionPrepared?(x(),R(`div`,Ns,[t.frameless?U(``,!0):(x(),H(u,{key:0,align:`center`},{default:s(()=>[f(c),t.loading?(x(),H(l,{key:0,color:`primary`,indeterminate:``,size:`32`,width:`4`})):U(``,!0)]),_:1})),t.debugMode?(x(),H(d,{key:1,"session-controller":t.sessionController},null,8,[`session-controller`])):U(``,!0),t.frameless?U(``,!0):(x(),R(`br`,Ps)),t.sessionFinished?(x(),R(`div`,Fs,[b(t.$slots,`session-finished`,{sessionRecord:t.sessionRecord,report:t.sessionController?.report},()=>[I(`div`,Is,[n[1]||(n[1]=I(`p`,null,`Study session finished! Great job!`,-1)),t.sessionController?(x(),R(`p`,Ls,N(t.sessionController.report),1)):U(``,!0),f(p,{"activity-records-getter":()=>t.user.getActivityRecords()},null,8,[`activity-records-getter`])])],!0)])):(x(),R(`div`,Rs,[f(De,{name:t.transitionName,mode:t.resolvedTransitionMode},{default:s(()=>[t.view?(x(),H(m,{ref:`cardViewer`,key:t.cardID,class:w(t.loading?`muted`:``),view:t.view,data:t.data,card_id:t.cardID,course_id:t.courseID,"session-order":t.cardCount,user_elo:t.user_elo(t.courseID),card_elo:t.card_elo,frameless:t.frameless,onEmitResponse:n[0]||(n[0]=n=>t.processResponse(n)),onRequestReplan:t.handleReplanRequest,onReadyToAdvance:t.handleReadyToAdvance},null,8,[`class`,`view`,`data`,`card_id`,`course_id`,`session-order`,`user_elo`,`card_elo`,`frameless`,`onRequestReplan`,`onReadyToAdvance`])):U(``,!0)]),_:1},8,[`name`,`mode`])],512)),t.frameless?U(``,!0):(x(),R(ge,{key:5},[n[2]||(n[2]=I(`br`,null,null,-1)),t.sessionController?(x(),R(`div`,zs,[(x(!0),R(ge,null,P(t.sessionController.failedCount,t=>(x(),R(`span`,{key:t,class:`text-h5`},`•`))),128))])):U(``,!0)],64)),t.hideFooter?U(``,!0):(x(),H(u,{key:6,align:`center`,class:`footer-controls pa-5`},{default:s(()=>[f(g,{cols:`auto`,class:`d-flex flex-grow-0 mr-auto`},{default:s(()=>[f(h,{"time-remaining":t.timeRemaining,"session-time-limit":t.sessionTimeLimit,onAddTime:t.incrementSessionClock},null,8,[`time-remaining`,`session-time-limit`,`onAddTime`])]),_:1}),f(c),f(g,{cols:`auto`,class:`footer-right`},{default:s(()=>[f(_)]),_:1})]),_:1}))])):U(``,!0)}$e(_sfc_render$15,`_sfc_render`);var Bs=q(Ms,[[`render`,_sfc_render$15],[`__scopeId`,`data-v-d6d88dad`]]),Vs=j({name:`MultipleChoiceOption`,components:{MarkdownRenderer:je(()=>lo(()=>import(`./MarkdownRenderer-kStoDRNE-Cdfc9yXz.js`).then(t=>t.n),__vite__mapDeps([4,1,2,5,6])))},props:{content:{type:String,required:!0},selected:{type:Boolean,required:!0},number:{type:Number,required:!0},setSelection:{type:Function,required:!0},submit:{type:Function,required:!0},markedWrong:{type:Boolean,required:!0}},computed:{className(){let t;switch(this.number){case 0:t=`bg-red`;break;case 1:t=`bg-purple`;break;case 2:t=`bg-indigo`;break;case 3:t=`bg-light-blue`;break;case 4:t=`bg-teal`;break;case 5:t=`bg-deep-orange`;break;default:t=`bg-grey`;break}if(this.selected&&!this.markedWrong)return`choice selected ${t} lighten-3 elevation-8`;if(!this.selected&&!this.markedWrong)return`choice not-selected ${t} lighten-4 elevation-1`;if(this.selected&&this.markedWrong)return`choice selected grey lighten-2 elevation-8`;if(!this.selected&&this.markedWrong)return`choice not-selected grey lighten-2 elevation-0`;throw Error(`'selected' and 'markedWrong' props in MultipleChoiceOption are in an impossible configuration.`)}},methods:{select(){this.setSelection(this.number)},submitThisOption(){this.markedWrong||(this.select(),this.submit())}}});function _sfc_render$14(t,n,r,i,a,o){let c=E(`markdown-renderer`),l=E(`v-card`);return x(),H(l,{class:w(`${t.className}`),onMouseover:t.select,onClick:t.submitThisOption},{default:s(()=>[f(c,{md:t.content},null,8,[`md`])]),_:1},8,[`class`,`onMouseover`,`onClick`])}$e(_sfc_render$14,`_sfc_render`);var Hs=q(Vs,[[`render`,_sfc_render$14],[`__scopeId`,`data-v-96de7172`]]),Us=j({name:`RadioMultipleChoice`,components:{MultipleChoiceOption:Hs},extends:Qe,props:{choiceList:{type:Array,required:!0}},data(){return{currentSelection:-1,incorrectSelections:[],containerRef:null,_registeredHotkeys:[]}},watch:{choiceList:{immediate:!0,handler(t){t?.length&&this.bindKeys()}}},mounted(){this.containerRef&&this.containerRef.focus()},unmounted(){this.unbindKeys()},methods:{forwardSelection(){if(!this.choiceIsWrong(this.choiceList[this.currentSelection])&&this.currentSelection!==-1){let t={choiceList:this.choiceList,selection:this.currentSelection};this.submitAnswer(t).isCorrect||this.incorrectSelections.push(this.currentSelection)}},setSelection(t){t<this.choiceList.length&&(this.currentSelection=t)},incrementSelection(){this.currentSelection===-1?this.currentSelection=Math.ceil(this.choiceList.length/2):this.currentSelection=Math.min(this.choiceList.length-1,this.currentSelection+1)},decrementSelection(){this.currentSelection===-1?this.currentSelection=Math.floor(this.choiceList.length/2-1):this.currentSelection=Math.max(0,this.currentSelection-1)},choiceIsWrong(t){let n=!1;return this.incorrectSelections.forEach(r=>{this.choiceList[r]===t&&(n=!0)}),n},bindKeys(){let t=[{hotkey:`left`,callback:this.decrementSelection,command:`Move selection left`},{hotkey:`right`,callback:this.incrementSelection,command:`Move selection right`},{hotkey:`enter`,callback:this.forwardSelection,command:`Submit selection`},...Array.from({length:this.choiceList.length},(t,n)=>({hotkey:(n+1).toString(),callback:()=>this.setSelection(n),command:`Select ${(t=>{switch(t){case 0:return`first`;case 1:return`second`;case 2:return`third`;case 3:return`fourth`;case 4:return`fifth`;case 5:return`sixth`;default:return`${t+1}th`}})(n)} option`}))];et.addBinding(t),this._registeredHotkeys=t.map(t=>t.hotkey)},unbindKeys(){this._registeredHotkeys&&this._registeredHotkeys.forEach(t=>{et.removeBinding(t)})}}}),Ws={ref:`containerRef`,class:`multipleChoice`};function _sfc_render$13(t,n,r,i,a,o){let s=E(`MultipleChoiceOption`);return x(),R(`div`,Ws,[(x(!0),R(ge,null,P(t.choiceList,(n,r)=>(x(),H(s,{key:r,content:n,selected:t.choiceList.indexOf(n)===t.currentSelection,number:t.choiceList.indexOf(n),"set-selection":t.setSelection,submit:t.forwardSelection,"marked-wrong":t.choiceIsWrong(n)},null,8,[`content`,`selected`,`number`,`set-selection`,`submit`,`marked-wrong`]))),128))],512)}$e(_sfc_render$13,`_sfc_render`);var Gs=q(Us,[[`render`,_sfc_render$13]]),Ks=j({name:`TrueFalse`,components:{RadioMultipleChoice:Gs},props:{MouseTrap:{type:Object,required:!0},submit:{type:Function,required:!0}}}),qs={"data-viewable":`TrueFalse`};function _sfc_render$12(t,n,r,i,a,o){let s=E(`RadioMultipleChoice`);return x(),R(`div`,qs,[f(s,{"choice-list":[`True`,`False`],MouseTrap:t.MouseTrap,submit:t.submit},null,8,[`MouseTrap`,`submit`])])}$e(_sfc_render$12,`_sfc_render`);var Js=q(Ks,[[`render`,_sfc_render$12]]),Ys=j({name:`UserInputNumber`,ref:{},extends:Qe,methods:{mounted(){this.$refs.input.focus()},isNumeric(t){return!isNaN(Number.parseFloat(t))},makeNumeric(t){if(typeof t==`string`)return Number.parseFloat(t);throw Error(`Expected a string, got `+typeof t)}}});function _sfc_render$11(t,n,r,i,a,o){let c=E(`v-text-field`),l=E(`v-container`);return x(),H(l,{class:`pa-0`},{default:s(()=>[f(c,{ref:`input`,modelValue:t.answer,"onUpdate:modelValue":n[0]||(n[0]=n=>t.answer=n),"prepend-icon":`edit`,autofocus:t.autofocus,"row-height":`24`,"toggle-keys":`[13,32]`,class:`text-h5`,rules:[t.isNumeric],onKeyup:n[1]||(n[1]=Se(n=>t.submitAnswer(t.makeNumeric(t.answer)),[`enter`]))},null,8,[`modelValue`,`autofocus`,`rules`])]),_:1})}$e(_sfc_render$11,`_sfc_render`);var Xs=q(Ys,[[`render`,_sfc_render$11],[`__scopeId`,`data-v-a56dcd1c`]]),Zs=j({name:`CardLoader`,components:{CardViewer:Xo},props:{sessionOrder:{type:Number,required:!1,default:0},qualified_id:{type:Object,required:!0},viewLookup:{type:Function,required:!0}},data(){return{loading:!0,view:null,data:[],courseID:``,cardID:``}},created(){this.loadCard()},watch:{qualified_id:{immediate:!0,handler(){this.loadCard()}}},methods:{processResponse(t){He(`
|
|
26
26
|
Card was displayed at ${t.timeStamp}
|
|
27
27
|
User spent ${t.timeSpent} milliseconds with the card.
|
|
28
|
-
`),this.$emit(`emitResponse`,t)},async loadCard(){let t=this.qualified_id;console.log(`Card Loader displaying: ${t.courseID}::${t.cardID}`),this.loading=!0;let n=t.courseID,r=t.cardID,i=tt().getCourseDB(n);try{let t=await i.getCourseDoc(r),a=this.viewLookup(t.id_view),o=t.id_displayable_data.map(t=>i.getCourseDoc(t,{attachments:!0,binary:!0})),s=[];for(let t of o){let n=await t;s.unshift(We(n))}this.data=s,this.view=de(a),this.cardID=r,this.courseID=n}catch(t){throw Error(`[CardLoader] Error loading card: ${JSON.stringify(t)}, ${t}`)}finally{this.loading=!1,this.$emit(`card-loaded`)}}}});function _sfc_render$10(t,n,r,i,a,o){let s=E(`card-viewer`);return t.loading?U(``,!0):(x(),H(s,{key:0,class:w([`ma-2`,t.loading?`muted`:``]),view:t.view,data:t.data,card_id:t.cardID,course_id:t.courseID,"session-order":t.sessionOrder,onEmitResponse:n[0]||(n[0]=n=>t.processResponse(n))},null,8,[`class`,`view`,`data`,`card_id`,`course_id`,`session-order`]))}$e(_sfc_render$10,`_sfc_render`);var Qs=q(Zs,[[`render`,_sfc_render$10],[`__scopeId`,`data-v-93f758b5`]]);async function getCurrentUser(){let t=useAuthStore();if(!t.onLoadComplete){let n=200;for(;!t.onLoadComplete&&n>0;)await new Promise(t=>setTimeout(t,50)),n--;if(!t.onLoadComplete)throw Error(`User initialization timed out`)}return tt().getUserDB()}var useAuthStore=()=>{let t=Xe();return t&&qe(t),Ke(`auth`,{state:()=>({_user:void 0,loginAndRegistration:{init:!1,loggedIn:!1,regDialogOpen:!1,loginDialogOpen:!1},onLoadComplete:!1}),actions:{async init(){try{this._user=tt().getUserDB(),this.loginAndRegistration.loggedIn=this._user?this._user.isLoggedIn():!1,this.onLoadComplete=!0,this.loginAndRegistration.init=!0}catch(t){console.error(`Failed to initialize auth store:`,t),this.loginAndRegistration.loggedIn=!1,this.onLoadComplete=!0,this.loginAndRegistration.init=!0}},setLoginDialog(t){this.loginAndRegistration.loginDialogOpen=t},setRegDialog(t){this.loginAndRegistration.regDialogOpen=t},async resetUserData(){try{if(!this._user)throw Error(`No user available for data reset`);let t=await this._user.resetUserData();if(t.status!==`ok`)throw Error(t.error||`Reset failed`);return console.log(`User data reset successfully`),t}catch(t){throw console.error(`Failed to reset user data:`,t),t}}},getters:{currentUser:async()=>getCurrentUser(),isLoggedIn:t=>t.loginAndRegistration.loggedIn,isInitialized:t=>t.loginAndRegistration.init,status:t=>({loggedIn:t.loginAndRegistration.loggedIn,init:t.loginAndRegistration.init,user:t._user})}})()},useConfigStore=()=>{let t=Xe();return t&&qe(t),Ke(`config`,{state:()=>({config:{darkMode:!1,likesConfetti:!1,sessionTimeLimit:5}}),actions:{updateConfig(t){this.config=t},async updateDarkMode(t){this.config.darkMode=t;let n=await getCurrentUser();n&&await n.setConfig({darkMode:t})},async updateLikesConfetti(t){this.config.likesConfetti=t;let n=await getCurrentUser();n&&await n.setConfig({likesConfetti:t})},async updateSessionTimeLimit(t){this.config.sessionTimeLimit=t;let n=await getCurrentUser();n&&await n.setConfig({sessionTimeLimit:t})},async hydrate(){try{let t=await getCurrentUser();if(t){let n=await t.getConfig();console.log(`user config: ${JSON.stringify(n)}`),this.updateConfig(n)}else console.log(`No user logged in, using default config`)}catch(t){console.warn(`Failed to hydrate config store, using defaults:`,t)}},async init(){await this.hydrate()},resetDefaults(){this.config={darkMode:!1,likesConfetti:!1,sessionTimeLimit:5}}}})()};function useAuthUI(){let t=Ce(!0),n=Ce(!1),r=Ce(!1),i=z(()=>r.value?{showLoginRegistration:!1,showLogout:!1,showResetData:!0,logoutLabel:``,resetLabel:`Reset User Data`}:{showLoginRegistration:!0,showLogout:!0,showResetData:!1,logoutLabel:`Log out`,resetLabel:``}),detectSyncStrategy=async()=>{try{t.value=!0,r.value=!(await getCurrentUser()).syncStrategy?.canCreateAccount?.(),n.value=!0}catch(t){console.error(`Failed to detect sync strategy:`,t),r.value=!1,n.value=!0}finally{t.value=!1}};return{config:i,isLoading:t,syncStrategyDetected:n,isLocalOnlyMode:r,detectSyncStrategy}}var $s=q(j({__name:`UserChip`,props:{showLoginButton:{type:Boolean},redirectToPath:{}},setup(t){let n=useRouter(),r=useAuthStore(),i=useConfigStore(),a=useAuthUI(),o=Ce(``),c=Ce([]),l=Ce(!1),u=Ce(``),d=z(()=>u.value===`reset`),resetDialogState=()=>{u.value=``,l.value=!1},p=z(()=>c.value.length>0),m=z(()=>a.config.value||{showLoginRegistration:!0,showLogout:!0,showResetData:!1,logoutLabel:`Log out`,resetLabel:``});Ie(async()=>{o.value=(await getCurrentUser()).getUsername(),await a.detectSyncStrategy()});let gotoSettings=async()=>{n.push(`/u/${(await getCurrentUser()).getUsername()}`)},gotoStats=async()=>{n.push(`/u/${(await getCurrentUser()).getUsername()}/stats`)},dismiss=t=>{let n=c.value.indexOf(t);c.value.splice(n,1)},logout=async()=>{(await r._user.logout()).ok&&(r.loginAndRegistration={init:!0,loggedIn:!1,regDialogOpen:!1,loginDialogOpen:!1},i.resetDefaults(),n.push(`/home`))},executeReset=async()=>{try{await r.resetUserData(),i.resetDefaults(),resetDialogState(),n.push(`/home`)}catch(t){console.error(`Failed to reset user data:`,t)}};return(t,n)=>{let r=E(`v-icon`),i=E(`v-avatar`),a=E(`v-chip`),h=E(`v-list-item-title`),g=E(`v-list-item`),_=E(`v-divider`),b=E(`v-list`),S=E(`v-menu`),C=E(`v-badge`),w=E(`v-card-title`),T=E(`v-text-field`),D=E(`v-card-text`),k=E(`v-spacer`),ee=E(`v-btn`),te=E(`v-card-actions`),ne=E(`v-card`),re=E(`v-dialog`);return x(),R(ge,null,[f(C,{content:c.value.length,"model-value":p.value,color:`accent`,location:`end top`},{default:s(()=>[f(S,{location:`bottom end`,transition:`scale-transition`},{activator:s(({props:t})=>[f(a,O(t,{class:`ma-2`}),{default:s(()=>[f(i,{start:``,class:`bg-primary`},{default:s(()=>[f(r,null,{default:s(()=>n[4]||(n[4]=[A(`mdi-school`)])),_:1})]),_:1}),A(` `+N(o.value),1)]),_:2},1040)]),default:s(()=>[f(b,null,{default:s(()=>[(x(!0),R(ge,null,P(c.value,t=>(x(),H(g,{key:t,onClick:n=>dismiss(t)},{default:s(()=>[f(h,null,{default:s(()=>[A(N(t),1)]),_:2},1024)]),_:2},1032,[`onClick`]))),128)),c.value.length?(x(),H(_,{key:0})):U(``,!0),f(g,{onClick:gotoStats},{prepend:s(()=>[f(r,null,{default:s(()=>n[5]||(n[5]=[A(`mdi-trending-up`)])),_:1})]),default:s(()=>[f(h,null,{default:s(()=>n[6]||(n[6]=[A(`Stats`)])),_:1})]),_:1}),f(g,{onClick:gotoSettings},{prepend:s(()=>[f(r,null,{default:s(()=>n[7]||(n[7]=[A(`mdi-cog`)])),_:1})]),default:s(()=>[f(h,null,{default:s(()=>n[8]||(n[8]=[A(`Settings`)])),_:1})]),_:1}),m.value.showLogout?(x(),H(g,{key:1,onClick:logout},{prepend:s(()=>[f(r,null,{default:s(()=>n[9]||(n[9]=[A(`mdi-logout`)])),_:1})]),default:s(()=>[f(h,null,{default:s(()=>[A(N(m.value.logoutLabel),1)]),_:1})]),_:1})):U(``,!0),m.value.showResetData?(x(),H(g,{key:2,onClick:n[0]||(n[0]=t=>l.value=!0)},{prepend:s(()=>[f(r,null,{default:s(()=>n[10]||(n[10]=[A(`mdi-delete-sweep`)])),_:1})]),default:s(()=>[f(h,null,{default:s(()=>[A(N(m.value.resetLabel),1)]),_:1})]),_:1})):U(``,!0)]),_:1})]),_:1})]),_:1},8,[`content`,`model-value`]),f(re,{modelValue:l.value,"onUpdate:modelValue":n[3]||(n[3]=t=>l.value=t),"max-width":`500px`,persistent:``},{default:s(()=>[f(ne,null,{default:s(()=>[f(w,{class:`text-h5 d-flex align-center`},{default:s(()=>[f(r,{color:`warning`,class:`mr-3`},{default:s(()=>n[11]||(n[11]=[A(`mdi-alert-circle`)])),_:1}),n[12]||(n[12]=A(` Reset All User Data `))]),_:1}),f(D,null,{default:s(()=>[n[13]||(n[13]=I(`p`,{class:`mb-4`},`This will permanently delete:`,-1)),n[14]||(n[14]=I(`ul`,{class:`mb-4`},[I(`li`,null,`All course progress and history`),I(`li`,null,`Scheduled card reviews`),I(`li`,null,`Course registrations`),I(`li`,null,`User preferences`)],-1)),n[15]||(n[15]=I(`p`,{class:`mb-4 text-error font-weight-bold`},`This cannot be undone.`,-1)),f(T,{modelValue:u.value,"onUpdate:modelValue":n[1]||(n[1]=t=>u.value=t),label:`Type "reset" to confirm`,outlined:``,dense:``,onKeyup:n[2]||(n[2]=Se(t=>d.value&&executeReset(),[`enter`]))},null,8,[`modelValue`])]),_:1}),f(te,null,{default:s(()=>[f(k),f(ee,{text:``,onClick:resetDialogState},{default:s(()=>n[16]||(n[16]=[A(`Cancel`)])),_:1}),f(ee,{color:`error`,disabled:!d.value,onClick:executeReset},{default:s(()=>n[17]||(n[17]=[A(` Reset All Data `)])),_:1},8,[`disabled`])]),_:1})]),_:1})]),_:1},8,[`modelValue`])],64)}}}),[[`__scopeId`,`data-v-9a38a213`]]),ec={class:`d-flex flex-column align-start`},tc={class:`mb-2`},nc=q(j({__name:`UserLogin`,props:{redirectTo:{default:`/study`}},emits:[`toggle`,`loginSuccess`,`forgotPassword`],setup(t,{emit:n}){let r=t,i=n,a=useRouter(),o=useRoute(),c=useAuthStore(),l=useConfigStore(),u=Ce(``),d=Ce(``),p=Ce(!1),m=Ce(!1),h=Ce(!1),g=Ce(7e3),_=Ce(void 0),S=z(()=>o.name===`login`),C=z(()=>({color:h.value?`error`:`success`,text:h.value?`Try again`:`Log In`})),initBadLogin=()=>{h.value=!0,wo({text:`Username or password was incorrect.`,status:Be.error,timeout:g.value}),setTimeout(()=>{h.value=!1},g.value)},login=async()=>{m.value=!0,He(`Starting login attempt`),He(`Login attempt for username: ${u.value}`);try{He(`Attempting to get User instance`),_.value=await getCurrentUser(),He(`Got User instance, attempting login`),await _.value.login(u.value,d.value),He(`Login successful`),He(`Initializing user config`),l.init(),He(`User config initialized`),He(`Setting authentication state`),c.loginAndRegistration.loggedIn=!0,He(`Authentication state set, redirecting to: ${r.redirectTo}`),i(`loginSuccess`,r.redirectTo),a.push(r.redirectTo),He(`Login and redirect complete`)}catch(t){He(`Login attempt failed`),He(`Login error details: ${JSON.stringify(t)}`),console.log(`login error: ${JSON.stringify(t)}`),He(`Initiating bad login feedback`),initBadLogin()}He(`Resetting awaiting response state`),m.value=!1},toggle=()=>{He(`Toggling registration / login forms.`),i(`toggle`)},handleForgotPassword=()=>{He(`Forgot password clicked`),S.value?a.push(`/request-reset`):i(`forgotPassword`)};return(t,n)=>{let r=E(`v-card-title`),i=E(`v-text-field`),a=E(`v-btn`),o=E(`v-snackbar`),c=E(`v-icon`),l=E(`router-link`),_=E(`v-form`),w=E(`v-card-text`),T=E(`v-card`);return x(),H(T,null,{default:s(()=>[S.value?U(``,!0):(x(),H(r,{key:0,class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[5]||(n[5]=[A(`Log In`)])),_:1})),f(w,null,{default:s(()=>[f(_,{onsubmit:`return false;`,onSubmit:Oe(login,[`prevent`])},{default:s(()=>[f(i,{id:``,modelValue:u.value,"onUpdate:modelValue":n[0]||(n[0]=t=>u.value=t),autofocus:``,name:`username`,label:`Username`,"prepend-icon":`mdi-account-circle`},null,8,[`modelValue`]),f(i,{modelValue:d.value,"onUpdate:modelValue":n[1]||(n[1]=t=>d.value=t),"prepend-icon":`mdi-lock`,name:`password`,hover:`Show password input`,label:`Enter your password`,hint:``,min:`0`,"append-icon":p.value?`mdi-eye-off`:`mdi-eye`,type:p.value?`text`:`password`,"onClick:append":n[2]||(n[2]=()=>p.value=!p.value)},null,8,[`modelValue`,`append-icon`,`type`]),f(o,{modelValue:h.value,"onUpdate:modelValue":n[4]||(n[4]=t=>h.value=t),location:`bottom right`,timeout:g.value},{default:s(()=>[n[7]||(n[7]=A(` Username or password was incorrect. `)),f(a,{color:`pink`,variant:`text`,onClick:n[3]||(n[3]=t=>h.value=!1)},{default:s(()=>n[6]||(n[6]=[A(`Close`)])),_:1})]),_:1},8,[`modelValue`,`timeout`]),I(`div`,ec,[I(`div`,tc,[f(a,{class:`mr-2`,type:`submit`,loading:m.value,color:C.value.color},{default:s(()=>[f(c,{start:``},{default:s(()=>n[8]||(n[8]=[A(`mdi-lock-open`)])),_:1}),n[9]||(n[9]=A(` Log In `))]),_:1},8,[`loading`,`color`]),S.value?(x(),H(l,{key:0,to:`signup`},{default:s(()=>[f(a,{variant:`text`},{default:s(()=>n[10]||(n[10]=[A(`Create New Account`)])),_:1})]),_:1})):(x(),H(a,{key:1,variant:`text`,onClick:toggle},{default:s(()=>n[11]||(n[11]=[A(`Create New Account`)])),_:1}))]),b(t.$slots,`forgot-password`,{},()=>[I(`a`,{href:`#`,class:`text-caption text-decoration-none`,onClick:Oe(handleForgotPassword,[`prevent`])},` Forgot password? `)],!0)])]),_:3})]),_:3})]),_:3})}}}),[[`__scopeId`,`data-v-563b0048`]]);function validatePassword(t){return t?t.length<6?`Password must be at least 6 characters`:new Set(t).size<2?`Password must contain at least 2 different characters`:``:``}var rc=j({name:`UserRegistration`,props:{onSignupSuccess:{type:Function,required:!1}},emits:[`toggle`,`signup-success`],data(){return{email:``,username:``,password:``,retypedPassword:``,passwordVisible:!1,emailError:!1,emailHint:``,usernameValidationInProgress:!1,usernameError:!1,usernameHint:``,awaitingResponse:!1,badLoginAttempt:!1,userSecret:``,secret:`goons`,user:null,roles:[`Student`,`Teacher`,`Author`],student:!0,teacher:!1,author:!1,authStore:useAuthStore()}},computed:{registrationRoute(){return typeof this.$route.name==`string`&&this.$route.name.toLowerCase()===`signup`},buttonStatus(){return{color:this.badLoginAttempt?`error`:`success`,text:this.badLoginAttempt?`Try again`:`Log In`}},passwordError(){return validatePassword(this.password)},passwordRetypeError(){return console.log(`[RTE]`),this.password===this.retypedPassword?``:`Passwords must match.`}},async created(){this.user=await getCurrentUser()},methods:{toggle(){He(`Toggling registration / login forms.`),this.$emit(`toggle`)},validateEmail(){this.emailError=!1,this.email&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email)?(this.emailError=!0,this.emailHint=`Please enter a valid email address`):this.emailHint=``},validateUsername(){this.usernameError=!1},async createUser(){if(this.awaitingResponse=!0,this.passwordError){wo({text:this.passwordError,status:Be.error}),this.awaitingResponse=!1;return}if(He(`
|
|
28
|
+
`),this.$emit(`emitResponse`,t)},async loadCard(){let t=this.qualified_id;console.log(`Card Loader displaying: ${t.courseID}::${t.cardID}`),this.loading=!0;let n=t.courseID,r=t.cardID,i=tt().getCourseDB(n);try{let t=await i.getCourseDoc(r),a=this.viewLookup(t.id_view),o=t.id_displayable_data.map(t=>i.getCourseDoc(t,{attachments:!0,binary:!0})),s=[];for(let t of o){let n=await t;s.unshift(We(n))}this.data=s,this.view=de(a),this.cardID=r,this.courseID=n}catch(t){throw Error(`[CardLoader] Error loading card: ${JSON.stringify(t)}, ${t}`)}finally{this.loading=!1,this.$emit(`card-loaded`)}}}});function _sfc_render$10(t,n,r,i,a,o){let s=E(`card-viewer`);return t.loading?U(``,!0):(x(),H(s,{key:0,class:w([`ma-2`,t.loading?`muted`:``]),view:t.view,data:t.data,card_id:t.cardID,course_id:t.courseID,"session-order":t.sessionOrder,onEmitResponse:n[0]||(n[0]=n=>t.processResponse(n))},null,8,[`class`,`view`,`data`,`card_id`,`course_id`,`session-order`]))}$e(_sfc_render$10,`_sfc_render`);var Qs=q(Zs,[[`render`,_sfc_render$10],[`__scopeId`,`data-v-93f758b5`]]);async function getCurrentUser(){let t=useAuthStore();if(!t.onLoadComplete){let n=200;for(;!t.onLoadComplete&&n>0;)await new Promise(t=>setTimeout(t,50)),n--;if(!t.onLoadComplete)throw Error(`User initialization timed out`)}return tt().getUserDB()}var useAuthStore=()=>{let t=Xe();return t&&qe(t),Ke(`auth`,{state:()=>({_user:void 0,loginAndRegistration:{init:!1,loggedIn:!1,regDialogOpen:!1,loginDialogOpen:!1},onLoadComplete:!1}),actions:{async init(){try{this._user=tt().getUserDB(),this.loginAndRegistration.loggedIn=this._user?this._user.isLoggedIn():!1,this.onLoadComplete=!0,this.loginAndRegistration.init=!0}catch(t){console.error(`Failed to initialize auth store:`,t),this.loginAndRegistration.loggedIn=!1,this.onLoadComplete=!0,this.loginAndRegistration.init=!0}},setLoginDialog(t){this.loginAndRegistration.loginDialogOpen=t},setRegDialog(t){this.loginAndRegistration.regDialogOpen=t},async resetUserData(){try{if(!this._user)throw Error(`No user available for data reset`);let t=await this._user.resetUserData();if(t.status!==`ok`)throw Error(t.error||`Reset failed`);return console.log(`User data reset successfully`),t}catch(t){throw console.error(`Failed to reset user data:`,t),t}}},getters:{currentUser:async()=>getCurrentUser(),isLoggedIn:t=>t.loginAndRegistration.loggedIn,isInitialized:t=>t.loginAndRegistration.init,status:t=>({loggedIn:t.loginAndRegistration.loggedIn,init:t.loginAndRegistration.init,user:t._user})}})()},useConfigStore=()=>{let t=Xe();return t&&qe(t),Ke(`config`,{state:()=>({config:{darkMode:!1,likesConfetti:!1,sessionTimeLimit:5}}),actions:{updateConfig(t){this.config=t},async updateDarkMode(t){this.config.darkMode=t;let n=await getCurrentUser();n&&await n.setConfig({darkMode:t})},async updateLikesConfetti(t){this.config.likesConfetti=t;let n=await getCurrentUser();n&&await n.setConfig({likesConfetti:t})},async updateSessionTimeLimit(t){this.config.sessionTimeLimit=t;let n=await getCurrentUser();n&&await n.setConfig({sessionTimeLimit:t})},async hydrate(){try{let t=await getCurrentUser();if(t){let n=await t.getConfig();console.log(`user config: ${JSON.stringify(n)}`),this.updateConfig(n)}else console.log(`No user logged in, using default config`)}catch(t){console.warn(`Failed to hydrate config store, using defaults:`,t)}},async init(){await this.hydrate()},resetDefaults(){this.config={darkMode:!1,likesConfetti:!1,sessionTimeLimit:5}}}})()};function useAuthUI(){let t=Ce(!0),n=Ce(!1),r=Ce(!1),i=z(()=>r.value?{showLoginRegistration:!1,showLogout:!1,showResetData:!0,logoutLabel:``,resetLabel:`Reset User Data`}:{showLoginRegistration:!0,showLogout:!0,showResetData:!1,logoutLabel:`Log out`,resetLabel:``}),detectSyncStrategy=async()=>{try{t.value=!0,r.value=!(await getCurrentUser()).syncStrategy?.canCreateAccount?.(),n.value=!0}catch(t){console.error(`Failed to detect sync strategy:`,t),r.value=!1,n.value=!0}finally{t.value=!1}};return{config:i,isLoading:t,syncStrategyDetected:n,isLocalOnlyMode:r,detectSyncStrategy}}var $s=q(j({__name:`UserChip`,props:{showLoginButton:{type:Boolean},redirectToPath:{}},setup(t){let n=useRouter(),r=useAuthStore(),i=useConfigStore(),a=useAuthUI(),o=Ce(``),c=Ce([]),l=Ce(!1),u=Ce(``),d=z(()=>u.value===`reset`),resetDialogState=()=>{u.value=``,l.value=!1},p=z(()=>c.value.length>0),m=z(()=>a.config.value||{showLoginRegistration:!0,showLogout:!0,showResetData:!1,logoutLabel:`Log out`,resetLabel:``});Ie(async()=>{o.value=(await getCurrentUser()).getUsername(),await a.detectSyncStrategy()});let gotoSettings=async()=>{n.push(`/u/${(await getCurrentUser()).getUsername()}`)},gotoStats=async()=>{n.push(`/u/${(await getCurrentUser()).getUsername()}/stats`)},dismiss=t=>{let n=c.value.indexOf(t);c.value.splice(n,1)},logout=async()=>{(await r._user.logout()).ok&&(r.loginAndRegistration={init:!0,loggedIn:!1,regDialogOpen:!1,loginDialogOpen:!1},i.resetDefaults(),n.push(`/home`))},executeReset=async()=>{try{await r.resetUserData(),i.resetDefaults(),resetDialogState(),n.push(`/home`)}catch(t){console.error(`Failed to reset user data:`,t)}};return(t,n)=>{let r=E(`v-icon`),i=E(`v-avatar`),a=E(`v-chip`),h=E(`v-list-item-title`),g=E(`v-list-item`),_=E(`v-divider`),b=E(`v-list`),S=E(`v-menu`),C=E(`v-badge`),w=E(`v-card-title`),T=E(`v-text-field`),D=E(`v-card-text`),k=E(`v-spacer`),ee=E(`v-btn`),te=E(`v-card-actions`),ne=E(`v-card`),re=E(`v-dialog`);return x(),R(ge,null,[f(C,{content:c.value.length,"model-value":p.value,color:`accent`,location:`end top`},{default:s(()=>[f(S,{location:`bottom end`,transition:`scale-transition`},{activator:s(({props:t})=>[f(a,O(t,{class:`ma-2`}),{default:s(()=>[f(i,{start:``,class:`bg-primary`},{default:s(()=>[f(r,null,{default:s(()=>n[4]||(n[4]=[A(`mdi-school`)])),_:1})]),_:1}),A(` `+N(o.value),1)]),_:2},1040)]),default:s(()=>[f(b,null,{default:s(()=>[(x(!0),R(ge,null,P(c.value,t=>(x(),H(g,{key:t,onClick:n=>dismiss(t)},{default:s(()=>[f(h,null,{default:s(()=>[A(N(t),1)]),_:2},1024)]),_:2},1032,[`onClick`]))),128)),c.value.length?(x(),H(_,{key:0})):U(``,!0),f(g,{onClick:gotoStats},{prepend:s(()=>[f(r,null,{default:s(()=>n[5]||(n[5]=[A(`mdi-trending-up`)])),_:1})]),default:s(()=>[f(h,null,{default:s(()=>n[6]||(n[6]=[A(`Stats`)])),_:1})]),_:1}),f(g,{onClick:gotoSettings},{prepend:s(()=>[f(r,null,{default:s(()=>n[7]||(n[7]=[A(`mdi-cog`)])),_:1})]),default:s(()=>[f(h,null,{default:s(()=>n[8]||(n[8]=[A(`Settings`)])),_:1})]),_:1}),m.value.showLogout?(x(),H(g,{key:1,onClick:logout},{prepend:s(()=>[f(r,null,{default:s(()=>n[9]||(n[9]=[A(`mdi-logout`)])),_:1})]),default:s(()=>[f(h,null,{default:s(()=>[A(N(m.value.logoutLabel),1)]),_:1})]),_:1})):U(``,!0),m.value.showResetData?(x(),H(g,{key:2,onClick:n[0]||(n[0]=t=>l.value=!0)},{prepend:s(()=>[f(r,null,{default:s(()=>n[10]||(n[10]=[A(`mdi-delete-sweep`)])),_:1})]),default:s(()=>[f(h,null,{default:s(()=>[A(N(m.value.resetLabel),1)]),_:1})]),_:1})):U(``,!0)]),_:1})]),_:1})]),_:1},8,[`content`,`model-value`]),f(re,{modelValue:l.value,"onUpdate:modelValue":n[3]||(n[3]=t=>l.value=t),"max-width":`500px`,persistent:``},{default:s(()=>[f(ne,null,{default:s(()=>[f(w,{class:`text-h5 d-flex align-center`},{default:s(()=>[f(r,{color:`warning`,class:`mr-3`},{default:s(()=>n[11]||(n[11]=[A(`mdi-alert-circle`)])),_:1}),n[12]||(n[12]=A(` Reset All User Data `))]),_:1}),f(D,null,{default:s(()=>[n[13]||(n[13]=I(`p`,{class:`mb-4`},`This will permanently delete:`,-1)),n[14]||(n[14]=I(`ul`,{class:`mb-4`},[I(`li`,null,`All course progress and history`),I(`li`,null,`Scheduled card reviews`),I(`li`,null,`Course registrations`),I(`li`,null,`User preferences`)],-1)),n[15]||(n[15]=I(`p`,{class:`mb-4 text-error font-weight-bold`},`This cannot be undone.`,-1)),f(T,{modelValue:u.value,"onUpdate:modelValue":n[1]||(n[1]=t=>u.value=t),label:`Type "reset" to confirm`,outlined:``,dense:``,onKeyup:n[2]||(n[2]=Se(t=>d.value&&executeReset(),[`enter`]))},null,8,[`modelValue`])]),_:1}),f(te,null,{default:s(()=>[f(k),f(ee,{text:``,onClick:resetDialogState},{default:s(()=>n[16]||(n[16]=[A(`Cancel`)])),_:1}),f(ee,{color:`error`,disabled:!d.value,onClick:executeReset},{default:s(()=>n[17]||(n[17]=[A(` Reset All Data `)])),_:1},8,[`disabled`])]),_:1})]),_:1})]),_:1},8,[`modelValue`])],64)}}}),[[`__scopeId`,`data-v-9a38a213`]]),ec={class:`d-flex flex-column align-start`},tc={class:`mb-2`},nc=q(j({__name:`UserLogin`,props:{redirectTo:{default:`/study`}},emits:[`toggle`,`loginSuccess`,`forgotPassword`],setup(t,{emit:n}){let r=t,i=n,a=useRouter(),o=useRoute(),c=useAuthStore(),l=useConfigStore(),u=Ce(``),d=Ce(``),p=Ce(!1),m=Ce(!1),h=Ce(!1),g=Ce(7e3),_=Ce(void 0),S=z(()=>o.name===`login`),C=z(()=>({color:h.value?`error`:`success`,text:h.value?`Try again`:`Log In`})),initBadLogin=()=>{h.value=!0,wo({text:`Username or password was incorrect.`,status:Be.error,timeout:g.value}),setTimeout(()=>{h.value=!1},g.value)},login=async()=>{m.value=!0,He(`Starting login attempt`),He(`Login attempt for identifier: ${u.value}`);try{He(`Attempting to get User instance`),_.value=await getCurrentUser(),He(`Got User instance, attempting login`);let t=u.value;if(u.value.includes(`@`)){let n=await resolveLoginIdentifier(u.value,d.value);if(!n.ok||!n.username){He(`Email identifier did not resolve (bad credentials)`),initBadLogin(),m.value=!1;return}t=n.username}await _.value.login(t,d.value),He(`Login successful`),He(`Initializing user config`),l.init(),He(`User config initialized`),He(`Setting authentication state`),c.loginAndRegistration.loggedIn=!0,He(`Authentication state set, redirecting to: ${r.redirectTo}`),i(`loginSuccess`,r.redirectTo),a.push(r.redirectTo),He(`Login and redirect complete`)}catch(t){He(`Login attempt failed`),He(`Login error details: ${JSON.stringify(t)}`),console.log(`login error: ${JSON.stringify(t)}`),He(`Initiating bad login feedback`),initBadLogin()}He(`Resetting awaiting response state`),m.value=!1},toggle=()=>{He(`Toggling registration / login forms.`),i(`toggle`)},handleForgotPassword=()=>{He(`Forgot password clicked`),S.value?a.push(`/request-reset`):i(`forgotPassword`)};return(t,n)=>{let r=E(`v-card-title`),i=E(`v-text-field`),a=E(`v-btn`),o=E(`v-snackbar`),c=E(`v-icon`),l=E(`router-link`),_=E(`v-form`),w=E(`v-card-text`),T=E(`v-card`);return x(),H(T,null,{default:s(()=>[S.value?U(``,!0):(x(),H(r,{key:0,class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[5]||(n[5]=[A(`Log In`)])),_:1})),f(w,null,{default:s(()=>[f(_,{onsubmit:`return false;`,onSubmit:Oe(login,[`prevent`])},{default:s(()=>[f(i,{id:``,modelValue:u.value,"onUpdate:modelValue":n[0]||(n[0]=t=>u.value=t),autofocus:``,name:`username`,label:`Username or email`,"prepend-icon":`mdi-account-circle`},null,8,[`modelValue`]),f(i,{modelValue:d.value,"onUpdate:modelValue":n[1]||(n[1]=t=>d.value=t),"prepend-icon":`mdi-lock`,name:`password`,hover:`Show password input`,label:`Enter your password`,hint:``,min:`0`,"append-icon":p.value?`mdi-eye-off`:`mdi-eye`,type:p.value?`text`:`password`,"onClick:append":n[2]||(n[2]=()=>p.value=!p.value)},null,8,[`modelValue`,`append-icon`,`type`]),f(o,{modelValue:h.value,"onUpdate:modelValue":n[4]||(n[4]=t=>h.value=t),location:`bottom right`,timeout:g.value},{default:s(()=>[n[7]||(n[7]=A(` Username or password was incorrect. `)),f(a,{color:`pink`,variant:`text`,onClick:n[3]||(n[3]=t=>h.value=!1)},{default:s(()=>n[6]||(n[6]=[A(`Close`)])),_:1})]),_:1},8,[`modelValue`,`timeout`]),I(`div`,ec,[I(`div`,tc,[f(a,{class:`mr-2`,type:`submit`,loading:m.value,color:C.value.color},{default:s(()=>[f(c,{start:``},{default:s(()=>n[8]||(n[8]=[A(`mdi-lock-open`)])),_:1}),n[9]||(n[9]=A(` Log In `))]),_:1},8,[`loading`,`color`]),S.value?(x(),H(l,{key:0,to:`signup`},{default:s(()=>[f(a,{variant:`text`},{default:s(()=>n[10]||(n[10]=[A(`Create New Account`)])),_:1})]),_:1})):(x(),H(a,{key:1,variant:`text`,onClick:toggle},{default:s(()=>n[11]||(n[11]=[A(`Create New Account`)])),_:1}))]),b(t.$slots,`forgot-password`,{},()=>[I(`a`,{href:`#`,class:`text-caption text-decoration-none`,onClick:Oe(handleForgotPassword,[`prevent`])},` Forgot password? `)],!0)])]),_:3})]),_:3})]),_:3})}}}),[[`__scopeId`,`data-v-f374a5e9`]]);function validatePassword(t){return t?t.length<6?`Password must be at least 6 characters`:new Set(t).size<2?`Password must contain at least 2 different characters`:``:``}var rc=j({name:`UserRegistration`,props:{onSignupSuccess:{type:Function,required:!1}},emits:[`toggle`,`signup-success`],data(){return{email:``,username:``,password:``,retypedPassword:``,passwordVisible:!1,emailError:!1,emailHint:``,usernameValidationInProgress:!1,usernameError:!1,usernameHint:``,awaitingResponse:!1,badLoginAttempt:!1,userSecret:``,secret:`goons`,user:null,roles:[`Student`,`Teacher`,`Author`],student:!0,teacher:!1,author:!1,authStore:useAuthStore()}},computed:{registrationRoute(){return typeof this.$route.name==`string`&&this.$route.name.toLowerCase()===`signup`},buttonStatus(){return{color:this.badLoginAttempt?`error`:`success`,text:this.badLoginAttempt?`Try again`:`Log In`}},passwordError(){return validatePassword(this.password)},passwordRetypeError(){return console.log(`[RTE]`),this.password===this.retypedPassword?``:`Passwords must match.`}},async created(){this.user=await getCurrentUser()},methods:{toggle(){He(`Toggling registration / login forms.`),this.$emit(`toggle`)},validateEmail(){this.emailError=!1,this.email&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email)?(this.emailError=!0,this.emailHint=`Please enter a valid email address`):this.emailHint=``},validateUsername(){this.usernameError=!1},async createUser(){if(this.awaitingResponse=!0,this.passwordError){wo({text:this.passwordError,status:Be.error}),this.awaitingResponse=!1;return}if(He(`
|
|
29
29
|
User creation
|
|
30
30
|
-------------
|
|
31
31
|
|
|
@@ -33,6 +33,6 @@ Name: ${this.username}
|
|
|
33
33
|
Student: ${this.student}
|
|
34
34
|
Teacher: ${this.teacher}
|
|
35
35
|
Author: ${this.author}
|
|
36
|
-
`),this.password===this.retypedPassword){if(!this.user){console.error(`ERROR: No user object available`);return}this.user.createAccount(this.username,this.password).then(async t=>{if(t.status===Be.ok){if(this.authStore.loginAndRegistration.loggedIn=!0,this.authStore.loginAndRegistration.init=!1,this.authStore.loginAndRegistration.init=!0,this.email)try{await(await getCurrentUser()).setConfig({email:this.email});let t=typeof window<`u`?window.location.origin:void 0,n=await sendVerificationEmail(this.username,this.email,t);n.ok?wo({text:`Account created! Please check your email to verify your account.`,status:Be.ok}):He(`Warning: Failed to send verification email: ${n.error}`)}catch(t){console.error(`Email save/send error:`,t),He(`Warning: Failed to save email or send verification: ${t}`)}this.onSignupSuccess&&(console.log(`[UserRegistration] Calling onSignupSuccess callback`),this.onSignupSuccess({username:this.username})),this.$emit(`signup-success`,{username:this.username})}else t.error===`This username is taken!`?(this.usernameError=!0,this.usernameHint=`Try a different name.`,this.$refs.userNameTextField.focus(),wo({text:`The name ${this.username} is taken!`,status:t.status})):wo({text:t.error,status:t.status})}).catch(t=>{console.error(`[UserRegistration] .catch() called with error:`,t),t&&wo({text:t?.message||t?.error||t?.toString()||`Account creation failed`,status:Be.error})}),this.awaitingResponse=!1}else wo({text:`Passwords do not match.`,status:Be.error}),this.awaitingResponse=!1}}});function _sfc_render$9(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-text-field`),u=E(`v-btn`),d=E(`v-snackbar`),p=E(`v-icon`),m=E(`router-link`),h=E(`v-form`),g=E(`v-card-text`),_=E(`v-card`);return x(),H(_,null,{default:s(()=>[f(c,{class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[7]||(n[7]=[A(` Create an Account `)])),_:1}),f(g,null,{default:s(()=>[f(h,{onSubmit:Oe(t.createUser,[`prevent`])},{default:s(()=>[f(l,{modelValue:t.email,"onUpdate:modelValue":n[0]||(n[0]=n=>t.email=n),name:`email`,label:`Email address`,type:`email`,"prepend-icon":`mdi-email`,error:t.emailError,hint:t.emailHint,onBlur:t.validateEmail},null,8,[`modelValue`,`error`,`hint`,`onBlur`]),f(l,{id:``,ref:`userNameTextField`,modelValue:t.username,"onUpdate:modelValue":n[1]||(n[1]=n=>t.username=n),name:`username`,label:`Choose a Username`,"prepend-icon":`mdi-account-circle`,error:t.usernameError,hint:t.usernameHint,onBlur:t.validateUsername},null,8,[`modelValue`,`error`,`hint`,`onBlur`]),f(l,{modelValue:t.password,"onUpdate:modelValue":n[2]||(n[2]=n=>t.password=n),"prepend-icon":`mdi-lock`,name:`password`,hover:`Show password`,label:`Create a password`,hint:t.passwordError,error:!!t.passwordError,min:`4`,"append-icon":t.passwordVisible?`mdi-eye-off`:`mdi-eye`,type:t.passwordVisible?`text`:`password`,"onClick:append":n[3]||(n[3]=()=>t.passwordVisible=!t.passwordVisible)},null,8,[`modelValue`,`hint`,`error`,`append-icon`,`type`]),f(l,{modelValue:t.retypedPassword,"onUpdate:modelValue":n[4]||(n[4]=n=>t.retypedPassword=n),"prepend-icon":`mdi-lock`,name:`retypedPassword`,hover:`Show password`,label:`Retype your password`,disabled:t.password===``||!!t.passwordError,hint:t.passwordRetypeError,min:`4`,type:t.passwordVisible?`text`:`password`},null,8,[`modelValue`,`disabled`,`hint`,`type`]),f(d,{modelValue:t.badLoginAttempt,"onUpdate:modelValue":n[6]||(n[6]=n=>t.badLoginAttempt=n),location:`bottom right`,timeout:5e3},{default:s(()=>[n[9]||(n[9]=A(` Username or password was incorrect. `)),f(u,{color:`pink`,variant:`text`,onClick:n[5]||(n[5]=n=>t.badLoginAttempt=!1)},{default:s(()=>n[8]||(n[8]=[A(` Close `)])),_:1})]),_:1},8,[`modelValue`]),f(u,{class:`mr-2 my-2`,type:`submit`,loading:t.awaitingResponse,color:t.buttonStatus.color,disabled:!!t.passwordError||t.password!==t.retypedPassword},{default:s(()=>[f(p,{start:``},{default:s(()=>n[10]||(n[10]=[A(`mdi-lock-open`)])),_:1}),n[11]||(n[11]=A(` Create Account `))]),_:1},8,[`loading`,`color`,`disabled`]),t.registrationRoute?(x(),H(m,{key:0,to:`login`},{default:s(()=>[f(u,{variant:`text`},{default:s(()=>n[12]||(n[12]=[A(`Log In`)])),_:1})]),_:1})):(x(),H(u,{key:1,variant:`text`,onClick:t.toggle},{default:s(()=>n[13]||(n[13]=[A(` Log In `)])),_:1},8,[`onClick`]))]),_:1},8,[`onSubmit`])]),_:1})]),_:1})}$e(_sfc_render$9,`_sfc_render`);var ic=q(rc,[[`render`,_sfc_render$9]]),ac=j({name:`RequestPasswordReset`,emits:[`cancel`,`success`],data(){return{email:``,emailError:!1,emailHint:``,isSubmitting:!1,requestSent:!1}},methods:{validateEmail(){this.emailError=!1,this.emailHint=``,this.email&&(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email)||(this.emailError=!0,this.emailHint=`Please enter a valid email address`))},async handleSubmit(){if(this.validateEmail(),!(this.emailError||!this.email)){this.isSubmitting=!0;try{let t=typeof window<`u`?window.location.origin:void 0,n=await requestPasswordReset(this.email,t);n.ok?(this.requestSent=!0,this.$emit(`success`,this.email)):wo({text:n.error||`Failed to send reset email`,status:Be.error})}catch{wo({text:`An unexpected error occurred`,status:Be.error})}finally{this.isSubmitting=!1}}}}}),oc={key:1,class:`text-center`};function _sfc_render$8(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-text-field`),u=E(`v-icon`),d=E(`v-btn`),p=E(`v-form`),m=E(`v-card-text`),h=E(`v-spacer`),g=E(`v-card-actions`),_=E(`v-card`);return x(),H(_,null,{default:s(()=>[f(c,{class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[2]||(n[2]=[A(` Reset Password `)])),_:1}),f(m,{class:`pa-6`},{default:s(()=>[t.requestSent?(x(),R(`div`,oc,[f(u,{color:`success`,size:`64`,class:`mb-4`},{default:s(()=>n[6]||(n[6]=[A(`mdi-email-check`)])),_:1}),n[9]||(n[9]=I(`h3`,{class:`mb-2`},`Check Your Email`,-1)),I(`p`,null,[n[7]||(n[7]=A(` If an account exists with `)),I(`strong`,null,N(t.email),1),n[8]||(n[8]=A(`, you will receive a password reset link shortly. `))]),n[10]||(n[10]=I(`p`,{class:`text-caption mt-4`},`Didn't receive an email? Check your spam folder.`,-1))])):(x(),H(p,{key:0,onSubmit:Oe(t.handleSubmit,[`prevent`])},{default:s(()=>[n[5]||(n[5]=I(`p`,{class:`mb-4`},` Enter your email address and we'll send you a link to reset your password. `,-1)),f(l,{modelValue:t.email,"onUpdate:modelValue":n[0]||(n[0]=n=>t.email=n),name:`email`,label:`Email address`,type:`email`,"prepend-icon":`mdi-email`,error:t.emailError,hint:t.emailHint,disabled:t.isSubmitting,onBlur:t.validateEmail},null,8,[`modelValue`,`error`,`hint`,`disabled`,`onBlur`]),f(d,{type:`submit`,color:`primary`,class:`mt-4`,loading:t.isSubmitting,disabled:!t.email||t.emailError,block:``},{default:s(()=>[f(u,{start:``},{default:s(()=>n[3]||(n[3]=[A(`mdi-email-send`)])),_:1}),n[4]||(n[4]=A(` Send Reset Link `))]),_:1},8,[`loading`,`disabled`])]),_:1},8,[`onSubmit`]))]),_:1}),t.requestSent?U(``,!0):(x(),H(g,{key:0},{default:s(()=>[b(t.$slots,`back-action`,{},()=>[f(d,{variant:`text`,onClick:n[1]||(n[1]=n=>t.$emit(`cancel`))},{default:s(()=>n[11]||(n[11]=[A(` Cancel `)])),_:1})]),f(h)]),_:3}))]),_:3})}$e(_sfc_render$8,`_sfc_render`);var sc=q(ac,[[`render`,_sfc_render$8]]),cc={key:0},lc={key:`login-buttons`},uc={key:`user-chip`},dc=q(j({__name:`UserLoginAndRegistrationContainer`,props:{showLoginButton:{type:Boolean},redirectToPath:{},showRegistration:{type:Boolean},onSignupSuccess:{type:Function}},emits:[`signup-success`],setup(t,{emit:n}){let r=t,i=n,a=useRoute(),o=useAuthStore(),c=useAuthUI();Ie(async()=>{await c.detectSyncStrategy()});let l=z(()=>{if(!a.name||typeof a.name!=`string`)return!0;let t=a.name.toLowerCase();return!(t===`login`||t===`signup`)}),u=z(()=>o.onLoadComplete),d=z(()=>o._user?o._user.getUsername().startsWith(rt):!o.loginAndRegistration.loggedIn),p=z(()=>({...c.config.value||{showLoginRegistration:!0,showLogout:!0,showResetData:!1,logoutLabel:`Log out`,resetLabel:``},...r.showRegistration!==void 0&&{showLoginRegistration:r.showRegistration}})),m=z({get:()=>o.loginAndRegistration.regDialogOpen,set:t=>{o.loginAndRegistration.regDialogOpen=t}}),h=z({get:()=>o.loginAndRegistration.loginDialogOpen,set:t=>{o.loginAndRegistration.loginDialogOpen=t}}),g=Ce(!1),toggle=()=>{if(m.value&&h.value)throw Error(`Registration / Login dialogs both activated.`);if(m.value===h.value)throw Error(`Registration / Login dialogs toggled while both were dormant.`);m.value=!m.value,h.value=!h.value},openResetDialog=()=>{h.value=!1,g.value=!0},closeResetDialog=()=>{g.value=!1},handleSignupSuccess=t=>{m.value=!1,r.onSignupSuccess&&r.onSignupSuccess(t),i(`signup-success`,t)};return(t,n)=>{let r=E(`v-btn`),i=E(`v-dialog`);return u.value&&l.value?(x(),R(`div`,cc,[f(De,{name:`component-fade`,mode:`out-in`},{default:s(()=>[d.value?(x(),R(`div`,lc,[p.value.showLoginRegistration?(x(),H(i,{key:0,modelValue:m.value,"onUpdate:modelValue":n[0]||(n[0]=t=>m.value=t),width:`500px`},{activator:s(({props:t})=>[f(r,O({class:`mr-2`,size:`small`,color:`success`},t),{default:s(()=>n[3]||(n[3]=[A(`Sign Up`)])),_:2},1040)]),default:s(()=>[f(ic,{onToggle:toggle,onSignupSuccess:handleSignupSuccess,"on-signup-success":handleSignupSuccess})]),_:1},8,[`modelValue`])):U(``,!0),f(i,{modelValue:h.value,"onUpdate:modelValue":n[1]||(n[1]=t=>h.value=t),width:`500px`},{activator:s(({props:t})=>[f(r,O({size:`small`,color:`success`},t),{default:s(()=>n[4]||(n[4]=[A(`Log In`)])),_:2},1040)]),default:s(()=>[f(nc,{onToggle:toggle,onForgotPassword:openResetDialog})]),_:1},8,[`modelValue`]),f(i,{modelValue:g.value,"onUpdate:modelValue":n[2]||(n[2]=t=>g.value=t),width:`500px`},{default:s(()=>[f(sc,{onCancel:closeResetDialog,onSuccess:closeResetDialog})]),_:1},8,[`modelValue`])])):(x(),R(`div`,uc,[f($s)]))]),_:1})])):U(``,!0)}}}),[[`__scopeId`,`data-v-5a55bdf0`]]),fc=j({name:`VerifyEmail`,emits:[`verified`,`error`],props:{token:{type:String,default:null}},data(){return{isVerifying:!1,verificationStatus:null,errorMessage:``,username:``}},async mounted(){await this.performVerification()},methods:{async performVerification(){let t=this.token||this.getTokenFromURL();if(!t){this.verificationStatus=`error`,this.errorMessage=`No verification token provided`;return}this.isVerifying=!0;try{let n=await verifyEmail(t);n.ok?(this.verificationStatus=`success`,this.username=n.username||``,wo({text:`Email verified successfully!`,status:Be.ok})):(this.verificationStatus=`error`,this.errorMessage=n.error||`Verification failed`,wo({text:n.error||`Verification failed`,status:Be.error}))}catch{this.verificationStatus=`error`,this.errorMessage=`An unexpected error occurred`,wo({text:`An unexpected error occurred`,status:Be.error})}finally{this.isVerifying=!1}},getTokenFromURL(){return typeof window>`u`?null:new URLSearchParams(window.location.search).get(`token`)}}}),pc={key:0,class:`text-center`},mc={key:1,class:`text-center`},hc={key:0},gc={key:2,class:`text-center`},_c={key:3,class:`text-center`};function _sfc_render$7(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-progress-circular`),u=E(`v-icon`),d=E(`v-card-text`),p=E(`v-spacer`),m=E(`v-btn`),h=E(`v-card-actions`),g=E(`v-card`),_=E(`v-col`),S=E(`v-row`),C=E(`v-container`);return x(),H(C,{class:`fill-height`,fluid:``},{default:s(()=>[f(S,{align:`center`,justify:`center`},{default:s(()=>[f(_,{cols:`12`,sm:`8`,md:`6`},{default:s(()=>[f(g,null,{default:s(()=>[f(c,{class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[2]||(n[2]=[A(` Email Verification `)])),_:1}),f(d,{class:`pa-6`},{default:s(()=>[t.isVerifying?(x(),R(`div`,pc,[f(l,{indeterminate:``,color:`primary`,size:`64`,class:`mb-4`}),n[3]||(n[3]=I(`p`,null,`Verifying your email...`,-1))])):t.verificationStatus===`success`?(x(),R(`div`,mc,[f(u,{color:`success`,size:`64`,class:`mb-4`},{default:s(()=>n[4]||(n[4]=[A(`mdi-check-circle`)])),_:1}),n[5]||(n[5]=I(`h3`,{class:`mb-2`},`Email Verified!`,-1)),n[6]||(n[6]=I(`p`,null,`Your account has been successfully verified.`,-1)),t.username?(x(),R(`p`,hc,`Welcome, `+N(t.username)+`!`,1)):U(``,!0)])):t.verificationStatus===`error`?(x(),R(`div`,gc,[f(u,{color:`error`,size:`64`,class:`mb-4`},{default:s(()=>n[7]||(n[7]=[A(`mdi-alert-circle`)])),_:1}),n[8]||(n[8]=I(`h3`,{class:`mb-2`},`Verification Failed`,-1)),I(`p`,null,N(t.errorMessage),1)])):(x(),R(`div`,_c,[f(u,{color:`warning`,size:`64`,class:`mb-4`},{default:s(()=>n[9]||(n[9]=[A(`mdi-help-circle`)])),_:1}),n[10]||(n[10]=I(`h3`,{class:`mb-2`},`No Verification Token`,-1)),n[11]||(n[11]=I(`p`,null,`Please use the link from your verification email.`,-1))]))]),_:1}),f(h,null,{default:s(()=>[f(p),b(t.$slots,`actions`,{status:t.verificationStatus,username:t.username},()=>[t.verificationStatus===`success`?(x(),H(m,{key:0,color:`primary`,onClick:n[0]||(n[0]=n=>t.$emit(`verified`,t.username))},{default:s(()=>n[12]||(n[12]=[A(` Continue `)])),_:1})):t.verificationStatus===`error`?(x(),H(m,{key:1,variant:`text`,onClick:n[1]||(n[1]=n=>t.$emit(`error`,t.errorMessage))},{default:s(()=>n[13]||(n[13]=[A(` Close `)])),_:1})):U(``,!0)])]),_:3})]),_:3})]),_:3})]),_:3})]),_:3})}$e(_sfc_render$7,`_sfc_render`);var vc=q(fc,[[`render`,_sfc_render$7]]),yc=j({name:`ResetPassword`,emits:[`complete`,`error`],props:{token:{type:String,default:null}},data(){return{password:``,confirmPassword:``,passwordVisible:!1,confirmPasswordError:!1,confirmPasswordHint:``,isSubmitting:!1,isComplete:!1}},computed:{canSubmit(){return this.password.length>=4&&this.confirmPassword.length>=4&&this.password===this.confirmPassword&&!this.confirmPasswordError}},methods:{validateConfirmPassword(){this.confirmPasswordError=!1,this.confirmPasswordHint=``,this.confirmPassword&&this.password!==this.confirmPassword&&(this.confirmPasswordError=!0,this.confirmPasswordHint=`Passwords do not match`)},async handleSubmit(){if(this.validateConfirmPassword(),!this.canSubmit)return;let t=this.token||this.getTokenFromURL();if(!t){wo({text:`No reset token provided. Please use the link from your email.`,status:Be.error}),this.$emit(`error`,`No token`);return}this.isSubmitting=!0;try{let n=await resetPassword(t,this.password);n.ok?(this.isComplete=!0,wo({text:`Password reset successfully!`,status:Be.ok})):(wo({text:n.error||`Failed to reset password`,status:Be.error}),this.$emit(`error`,n.error))}catch{wo({text:`An unexpected error occurred`,status:Be.error}),this.$emit(`error`,`Unexpected error`)}finally{this.isSubmitting=!1}},getTokenFromURL(){return typeof window>`u`?null:new URLSearchParams(window.location.search).get(`token`)}}}),bc={key:1,class:`text-center`};function _sfc_render$6(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-text-field`),u=E(`v-icon`),d=E(`v-btn`),p=E(`v-form`),m=E(`v-card-text`),h=E(`v-spacer`),g=E(`v-card-actions`),_=E(`v-card`),S=E(`v-col`),C=E(`v-row`),w=E(`v-container`);return x(),H(w,{class:`fill-height`,fluid:``},{default:s(()=>[f(C,{align:`center`,justify:`center`},{default:s(()=>[f(S,{cols:`12`,sm:`8`,md:`6`},{default:s(()=>[f(_,null,{default:s(()=>[f(c,{class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[4]||(n[4]=[A(` Set New Password `)])),_:1}),f(m,{class:`pa-6`},{default:s(()=>[t.isComplete?(x(),R(`div`,bc,[f(u,{color:`success`,size:`64`,class:`mb-4`},{default:s(()=>n[8]||(n[8]=[A(`mdi-check-circle`)])),_:1}),n[9]||(n[9]=I(`h3`,{class:`mb-2`},`Password Reset Successful!`,-1)),n[10]||(n[10]=I(`p`,null,`Your password has been updated. You can now log in with your new password.`,-1))])):(x(),H(p,{key:0,onSubmit:Oe(t.handleSubmit,[`prevent`])},{default:s(()=>[n[7]||(n[7]=I(`p`,{class:`mb-4`},`Enter your new password below.`,-1)),f(l,{modelValue:t.password,"onUpdate:modelValue":n[0]||(n[0]=n=>t.password=n),"prepend-icon":`mdi-lock`,name:`password`,label:`New password`,min:`4`,"append-icon":t.passwordVisible?`mdi-eye-off`:`mdi-eye`,type:t.passwordVisible?`text`:`password`,disabled:t.isSubmitting,"onClick:append":n[1]||(n[1]=()=>t.passwordVisible=!t.passwordVisible)},null,8,[`modelValue`,`append-icon`,`type`,`disabled`]),f(l,{modelValue:t.confirmPassword,"onUpdate:modelValue":n[2]||(n[2]=n=>t.confirmPassword=n),"prepend-icon":`mdi-lock`,name:`confirmPassword`,label:`Confirm new password`,min:`4`,type:t.passwordVisible?`text`:`password`,error:t.confirmPasswordError,hint:t.confirmPasswordHint,disabled:t.isSubmitting,onBlur:t.validateConfirmPassword},null,8,[`modelValue`,`type`,`error`,`hint`,`disabled`,`onBlur`]),f(d,{type:`submit`,color:`primary`,class:`mt-4`,loading:t.isSubmitting,disabled:!t.canSubmit,block:``},{default:s(()=>[f(u,{start:``},{default:s(()=>n[5]||(n[5]=[A(`mdi-lock-reset`)])),_:1}),n[6]||(n[6]=A(` Reset Password `))]),_:1},8,[`loading`,`disabled`])]),_:1},8,[`onSubmit`]))]),_:1}),t.isComplete?(x(),H(g,{key:0},{default:s(()=>[f(h),b(t.$slots,`success-action`,{},()=>[f(d,{color:`primary`,onClick:n[3]||(n[3]=n=>t.$emit(`complete`))},{default:s(()=>n[11]||(n[11]=[A(` Continue to Login `)])),_:1})])]),_:3})):U(``,!0)]),_:3})]),_:3})]),_:3})]),_:3})}$e(_sfc_render$6,`_sfc_render`);var xc=q(yc,[[`render`,_sfc_render$6]]),Sc=j({name:`SkTagsInput`,components:{VueTagsInput:oo},props:{courseID:{type:String,required:!0,default:``},cardID:{type:String,required:!1,default:``},hideSubmit:{type:Boolean,required:!1,default:!1}},data(){return{loading:!0,tag:``,tags:[],initialTags:[],availableCourseTags:[],separators:[`;`,`,`,` `],courseDB:null}},computed:{autoCompleteSuggestions(){return this.availableCourseTags.filter(t=>t.name.toLowerCase().indexOf(this.tag.toLowerCase())!==-1).map(t=>({text:t.name,data:{snippet:t.snippet}}))}},watch:{async cardID(){await this.getAppliedTags()},async courseID(){this.courseDB=tt().getCourseDB(this.courseID),await this.updateAvailableCourseTags()}},async created(){this.courseDB=tt().getCourseDB(this.courseID),await this.updateAvailableCourseTags(),await this.getAppliedTags()},methods:{tagsChanged(t){console.log(`[TagsInput] Tags changing: ${JSON.stringify(t)}`),this.tags=t},async getAppliedTags(){this.initialTags=[],this.tags=[];try{(await this.courseDB.getAppliedTags(this.cardID)).rows.forEach(t=>{console.log(`[TagsInput] The following tag is applied:
|
|
37
|
-
\t${JSON.stringify(t)}`),this.tags.push({text:t.value.name,style:``,classes:``})}),this.initialTags=this.tags.map(t=>t.text)}catch(t){console.error(`Error in init-getAppliedTags: ${JSON.stringify(t)}, ${t}`)}finally{this.loading=!1}},async updateAvailableCourseTags(){try{this.availableCourseTags=(await this.courseDB.getCourseTagStubs()).rows.map(t=>t.doc)}catch(t){console.error(`Error in init-availableCourseTags: ${JSON.stringify(t)}`)}},async submit(){console.log(`[TagsInput] tagsInput is submitting...`),this.loading=!0;try{await Promise.all(this.tags.map(async t=>{if(!this.initialTags.includes(t.text))try{await this.courseDB.addTagToCard(this.cardID,t.text),console.log(`[TagsInput] Successfully added tag: ${t.text}`)}catch(n){console.error(`Failed to add tag ${t.text}:`,n)}}))}catch(t){console.error(`Exception adding tags: ${JSON.stringify(t)}`)}try{await Promise.all(this.initialTags.map(async t=>{if(this.tags.filter(n=>n.text===t).length===0)try{await this.courseDB.removeTagFromCard(this.cardID,t),console.log(`[TagsInput] Successfully removed tag: ${t}`)}catch(n){console.error(`Failed to remove tag ${t}:`,n)}}))}catch(t){console.error(`Exception removing tags: ${JSON.stringify(t)}`)}this.loading=!1}}}),Cc={"data-cy":`tags-input`},wc={class:`tag-name`},Tc={key:0,class:`tag-snippet`};function _sfc_render$5(t,n,r,i,a,o){let c=E(`vue-tags-input`),l=E(`v-btn`);return x(),R(`div`,Cc,[f(c,{modelValue:t.tag,"onUpdate:modelValue":n[0]||(n[0]=n=>t.tag=n),tags:t.tags,"autocomplete-items":t.autoCompleteSuggestions,separators:t.separators,"add-on-key":t.separators,onTagsChanged:t.tagsChanged},{"autocomplete-item":s(t=>[I(`div`,{class:w([`autocomplete-item`,{"is-active":t.selected}])},[I(`span`,wc,N(t.item.text),1),t.item.data&&t.item.data.snippet?(x(),R(`span`,Tc,` - `+N(t.item.data.snippet),1)):U(``,!0)],2)]),_:1},8,[`modelValue`,`tags`,`autocomplete-items`,`separators`,`add-on-key`,`onTagsChanged`]),t.hideSubmit?U(``,!0):(x(),H(l,{key:0,color:`success`,loading:t.loading,onClick:t.submit},{default:s(()=>n[1]||(n[1]=[A(`Save Changes`)])),_:1},8,[`loading`,`onClick`]))])}$e(_sfc_render$5,`_sfc_render`);var Ec=q(Sc,[[`render`,_sfc_render$5],[`__scopeId`,`data-v-f7373dc0`]]),Dc=j({name:`CourseCardBrowser`,components:{CardLoader:Qs,TagsInput:Ec,PaginatingToolbar:Ao},props:{courseId:{type:String,required:!0},tagId:{type:String,required:!1,default:``},viewLookupFunction:{type:Function,required:!0,default:()=>(console.warn(`No viewLookupFunction provided to CourseCardBrowser`),null)},editMode:{type:String,required:!1,default:`full`}},data(){return{courseDB:null,page:1,pages:[],cards:[],cardData:{},cardPreview:{},cardElos:{},cardTags:{},internalEditMode:`none`,delBtn:!1,updatePending:!0,userIsRegistered:!1,questionCount:0,tags:[],viewLookup:this.viewLookupFunction}},async created(){try{this.courseDB=tt().getCourseDB(this.courseId),this.tagId?this.questionCount=(await this.courseDB.getTag(this.tagId)).taggedCards.length:this.questionCount=(await this.courseDB.getCourseInfo()).cardCount;for(let t=1;(t-1)*25<this.questionCount;t++)this.pages.push(t);await this.populateTableData()}catch(t){console.error(`Error initializing CourseCardBrowser:`,t)}finally{this.updatePending=!1}},methods:{idQualify(t){return t.includes(`-`)?t:`${this.courseId}-${t}`},idToQualifiedObject(t){if(t.includes(`-`)){let n=t.split(`-`);return{courseID:n[0],cardID:n[1]}}else return{courseID:this.courseId,cardID:t}},first(){this.page=1,this.populateTableData()},prev(){this.page--,this.populateTableData()},next(){this.page++,this.populateTableData()},last(){this.page=this.pages.length,this.populateTableData()},setPage(t){this.page=t,this.populateTableData()},async loadCardTags(t){try{await Promise.all(t.map(async t=>{let n=await this.courseDB.getAppliedTags(t);this.cardTags[t]=n.rows.map(t=>({name:t.value.name,snippet:t.value.snippet,count:t.value.count}))}))}catch(t){console.error(`Error loading card tags:`,t)}},clearSelections(t=``){this.cards.forEach(n=>{n.card.cardID!==t&&(n.isOpen=!1)}),this.internalEditMode=`none`,this.delBtn=!1},async deleteCard(t){console.log(`Deleting card ${t}`);let n=await this.courseDB.removeCard(t);n.ok?(this.cards=this.cards.filter(n=>n.card.cardID!=t),this.clearSelections()):(console.error(`Failed to delete card:\n\n${JSON.stringify(n)}`),wo({text:`Failed to delete card`,status:Be.error}))},async populateTableData(){this.updatePending=!0,this.tagId?this.cards=(await this.courseDB.getTag(this.tagId)).taggedCards.map(t=>({card:{cardID:t,courseID:this.courseId},isOpen:!1,delBtn:!1})):this.cards=(await this.courseDB.getCardsByELO(0,25)).map(t=>({card:t,isOpen:!1,delBtn:!1}));let t=[],n=(await this.courseDB.getCourseDocs(this.cards.map(t=>t.card.cardID),{include_docs:!0})).rows.filter(t=>t.doc?!0:(console.error(`Card ${t.id}.doc not found.\ncard: ${JSON.stringify(t)}`),!1)).map(t=>t.doc);this.cards=this.cards.filter(n=>!t.includes(n.card.cardID)),n.forEach(t=>{t&&t.id_displayable_data&&(this.cardData[t._id]=t.id_displayable_data)});try{await Promise.all(this.cards.map(async t=>{let r=t.card.cardID,i=n.find(t=>t._id==r);if(!i||!i.id_displayable_data){console.error(`No valid data found for card ${r}`);return}let a=this.viewLookupFunction(i.id_view||`default.question.BlanksCard.FillInView`),o=i.id_displayable_data.map(t=>this.courseDB.getCourseDoc(t,{attachments:!1,binary:!0})),s=await Promise.all(o);await Promise.all(s.map(n=>{[].unshift(We(n)),this.cardPreview[t.card.cardID]=a.name?a.name:`Unknown`}))}));let t=this.cards.map(t=>t.card.cardID),r=await this.courseDB.getCardEloData(t);t.forEach((t,n)=>{this.cardElos[t]=r[n]}),await this.loadCardTags(t)}catch(t){console.error(`Error populating table data:`,t)}finally{this.updatePending=!1,this.$forceUpdate()}}}}),Oc={key:0,class:`d-flex justify-center align-center pa-6`},kc={key:1},Ac={key:0,class:`px-4 py-2 bg-blue-grey-lighten-5`},jc={key:0,class:`mt-4`},Mc={class:`mt-4`},Nc={key:0,class:`ml-4`};function _sfc_render$4(t,n,r,i,a,o){let c=E(`v-progress-circular`),l=E(`paginating-toolbar`),u=E(`v-list-item-title`),d=E(`v-list-item-subtitle`),p=E(`v-btn`),m=E(`v-icon`),h=E(`v-speed-dial`),g=E(`v-list-item`),_=E(`card-loader`),b=E(`v-chip`),S=E(`v-chip-group`),C=E(`tags-input`),T=E(`v-list`),D=E(`v-card`);return x(),H(D,null,{default:s(()=>[t.updatePending?(x(),R(`div`,Oc,[f(c,{indeterminate:``,color:`primary`})])):(x(),R(`div`,kc,[f(l,{title:`Exercises`,page:t.page,pages:t.pages,subtitle:`(${t.questionCount})`,onFirst:t.first,onPrev:t.prev,onNext:t.next,onLast:t.last,onSetPage:n[0]||(n[0]=n=>t.setPage(n))},null,8,[`page`,`pages`,`subtitle`,`onFirst`,`onPrev`,`onNext`,`onLast`]),f(T,null,{default:s(()=>[(x(!0),R(ge,null,P(t.cards,r=>(x(),R(ge,{key:r.card.cardID},[f(g,{class:w({"bg-blue-grey-lighten-5":r.isOpen,"elevation-4":r.isOpen}),density:`compact`,"data-cy":`course-card`},{prepend:s(()=>[I(`div`,null,[f(u,{class:w([{"text-blue-grey-darken-1":r.isOpen},`font-weight-medium`])},{default:s(()=>[A(N(t.cardPreview[r.card.cardID]),1)]),_:2},1032,[`class`]),f(d,null,{default:s(()=>[A(` ELO: `+N(t.cardElos[r.card.cardID]?.global?.score||`(unknown)`),1)]),_:2},1024)])]),append:s(()=>[f(h,{modelValue:r.isOpen,"onUpdate:modelValue":t=>r.isOpen=t,location:`left center`,transition:`slide-x-transition`,style:{display:`flex`,"flex-direction":`row-reverse`},persistent:``},{activator:s(({props:n})=>[f(p,O({ref_for:!0},n,{icon:r.isOpen?`mdi-close`:`mdi-plus`,size:`small`,variant:`text`,onClick:n=>t.clearSelections(r.card.cardID)}),null,16,[`icon`,`onClick`])]),default:s(()=>[t.editMode===`full`?(x(),H(p,{key:`tags`,icon:``,size:`small`,variant:t.internalEditMode===`tags`?`elevated`:`outlined`,color:t.internalEditMode===`tags`?`teal`:`teal-darken-3`,onClick:n[1]||(n[1]=Oe(n=>t.internalEditMode=`tags`,[`stop`]))},{default:s(()=>[f(m,null,{default:s(()=>n[4]||(n[4]=[A(`mdi-bookmark`)])),_:1})]),_:1},8,[`variant`,`color`])):U(``,!0),t.editMode===`full`?(x(),H(p,{key:`flag`,icon:``,size:`small`,variant:t.internalEditMode===`flag`?`elevated`:`outlined`,color:t.internalEditMode===`flag`?`error`:`error-darken-3`,onClick:n[2]||(n[2]=Oe(n=>t.internalEditMode=`flag`,[`stop`]))},{default:s(()=>[f(m,null,{default:s(()=>n[5]||(n[5]=[A(`mdi-flag`)])),_:1})]),_:1},8,[`variant`,`color`])):U(``,!0)]),_:2},1032,[`modelValue`,`onUpdate:modelValue`])]),_:2},1032,[`class`]),r.isOpen?(x(),R(`div`,Ac,[f(_,{qualified_id:r.card,"view-lookup":t.viewLookup,class:`elevation-1`},null,8,[`qualified_id`,`view-lookup`]),t.editMode===`readonly`&&t.cardTags[r.card.cardID]?(x(),R(`div`,jc,[f(S,null,{default:s(()=>[(x(!0),R(ge,null,P(t.cardTags[r.card.cardID],t=>(x(),H(b,{key:t.name,size:`small`,color:`primary`,variant:`outlined`},{default:s(()=>[A(N(t.name),1)]),_:2},1024))),128))]),_:2},1024)])):U(``,!0),he(f(C,{"course-i-d":t.courseId,"card-i-d":r.card.cardID,class:`mt-4`},null,8,[`course-i-d`,`card-i-d`]),[[pe,t.internalEditMode===`tags`&&t.editMode===`full`]]),he(I(`div`,Mc,[f(p,{color:`error`,variant:`outlined`,onClick:t=>r.delBtn=!0},{default:s(()=>n[6]||(n[6]=[A(` Delete this card `)])),_:2},1032,[`onClick`]),r.delBtn?(x(),R(`span`,Nc,[n[8]||(n[8]=I(`span`,{class:`mr-2`},`Are you sure?`,-1)),f(p,{color:`error`,variant:`elevated`,onClick:n=>t.deleteCard(r.card.cardID)},{default:s(()=>n[7]||(n[7]=[A(` Confirm `)])),_:2},1032,[`onClick`])])):U(``,!0)],512),[[pe,t.internalEditMode===`flag`&&t.editMode===`full`]])])):U(``,!0)],64))),128))]),_:1}),f(l,{class:`elevation-0`,page:t.page,pages:t.pages,onFirst:t.first,onPrev:t.prev,onNext:t.next,onLast:t.last,onSetPage:n[3]||(n[3]=n=>t.setPage(n))},null,8,[`page`,`pages`,`onFirst`,`onPrev`,`onNext`,`onLast`])]))]),_:1})}$e(_sfc_render$4,`_sfc_render`);var Pc=q(Dc,[[`render`,_sfc_render$4],[`__scopeId`,`data-v-5ecc9d21`]]),Fc=j({name:`CourseInformation`,components:{CourseCardBrowser:Pc},props:{courseId:{type:String,required:!0},viewLookupFunction:{type:Function,required:!1,default:t=>(console.warn(`No viewLookupFunction provided to CourseInformation`),null)},editMode:{type:String,required:!1,default:`full`}},data(){return{courseDB:null,nameRules:[t=>t.length>30?`Course name must be 30 characters or less`:!0],updatePending:!0,courseConfig:{},userIsRegistered:!1,tags:[],user:null}},computed:{},async created(){this.courseDB=tt().getCourseDB(this.courseId),this.user=await getCurrentUser();let t=await this.user.getCourseRegistrationsDoc();this.user.getUsername()===`admin`?this.userIsRegistered=!0:this.userIsRegistered=t.courses.filter(t=>t.courseID===this.courseId&&(t.status===`active`||t.status===void 0)).length===1,this.courseConfig=await this.courseDB.getCourseConfig(),this.tags=(await this.courseDB.getCourseTagStubs()).rows.map(t=>t.doc),this.updatePending=!1},methods:{async register(){He(`Registering for ${this.courseId}`),(await this.user.registerForCourse(this.courseId)).ok&&(this.userIsRegistered=!0)},async drop(){He(`Dropping course ${this.courseId}`),(await this.user.dropCourse(this.courseId)).ok&&(this.userIsRegistered=!1)}}}),Ic={key:0},Lc={class:`text-h4 mb-2`},Rc={class:`text-body-2`},zc={key:0},Bc={key:1};function _sfc_render$3(t,n,r,i,a,o){let c=E(`v-btn`),l=E(`v-icon`),u=E(`v-toolbar-title`),d=E(`v-toolbar-items`),p=E(`v-toolbar`),m=E(`v-chip`),h=E(`v-card-text`),g=E(`v-card`),_=E(`course-card-browser`);return t.updatePending?U(``,!0):(x(),R(`div`,Ic,[b(t.$slots,`header`,{courseConfig:t.courseConfig,courseId:t.courseId},()=>[I(`h1`,Lc,N(t.courseConfig.name),1)],!0),I(`p`,Rc,N(t.courseConfig.description),1),b(t.$slots,`actions`,{userIsRegistered:t.userIsRegistered,courseId:t.courseId,editMode:t.editMode,register:t.register,drop:t.drop},()=>[f(De,{name:`component-fade`,mode:`out-in`},{default:s(()=>[t.userIsRegistered?(x(),R(`div`,zc,[f(c,{color:`success`,"data-cy":`focused-study-session-btn`,class:`me-2`},{default:s(()=>n[0]||(n[0]=[A(`Start ad study session`)])),_:1}),t.editMode===`full`?(x(),H(c,{key:0,"data-cy":`add-content-btn`,color:`indigo-lighten-1`,class:`me-2`},{default:s(()=>[f(l,{start:``},{default:s(()=>n[1]||(n[1]=[A(`mdi-plus`)])),_:1}),n[2]||(n[2]=A(` Add content `))]),_:1})):U(``,!0),t.editMode===`full`?(x(),H(c,{key:1,color:`green-darken-2`,title:`Rank course content for difficulty`,class:`me-2`},{default:s(()=>[f(l,{start:``},{default:s(()=>n[3]||(n[3]=[A(`mdi-format-list-numbered`)])),_:1}),n[4]||(n[4]=A(` Arrange `))]),_:1})):U(``,!0),t.editMode===`full`?(x(),H(c,{key:2,color:`error`,size:`small`,variant:`outlined`,onClick:t.drop},{default:s(()=>n[5]||(n[5]=[A(` Drop this course `)])),_:1},8,[`onClick`])):U(``,!0)])):(x(),R(`div`,Bc,[f(c,{"data-cy":`register-btn`,color:`primary`,class:`me-2`,onClick:t.register},{default:s(()=>n[6]||(n[6]=[A(`Register`)])),_:1},8,[`onClick`]),f(c,{variant:`outlined`,color:`primary`,class:`me-2`},{default:s(()=>n[7]||(n[7]=[A(`Start a trial study session`)])),_:1})]))]),_:1})],!0),b(t.$slots,`additional-content`,{},void 0,!0),f(g,{class:`my-2`},{default:s(()=>[f(p,{density:`compact`},{default:s(()=>[f(u,null,{default:s(()=>n[8]||(n[8]=[A(`Tags`)])),_:1}),f(d,null,{default:s(()=>[f(c,{variant:`text`},{default:s(()=>[A(`(`+N(t.tags.length)+`)`,1)]),_:1})]),_:1})]),_:1}),f(h,null,{default:s(()=>[(x(!0),R(ge,null,P(t.tags,(n,r)=>(x(),R(`span`,{key:r},[b(t.$slots,`tag-link`,{tag:n,courseId:t.courseId},()=>[f(m,{variant:`tonal`,class:`me-2 mb-2`},{default:s(()=>[A(N(n.name),1)]),_:2},1024)],!0)]))),128))]),_:3})]),_:3}),f(_,{class:`my-3`,"course-id":t.courseId,"view-lookup-function":t.viewLookupFunction,"edit-mode":t.editMode},null,8,[`course-id`,`view-lookup-function`,`edit-mode`])]))}$e(_sfc_render$3,`_sfc_render`);var Vc=q(Fc,[[`render`,_sfc_render$3],[`__scopeId`,`data-v-38e9efe1`]]),Hc=j({name:`CardBrowser`,components:{CardViewer:Xo},props:{views:{type:Array,required:!0},data:{type:Array,required:!0},suppressSpinner:{type:Boolean,default:!1}},data(){return{viewIndex:0,previewMode:Ye()}},computed:{spinner(){return this.views.length>1}},created(){console.log(`[CardBrowser] Card browser created. Cards now in 'prewviewMode'`),this.previewMode.setPreviewMode(!0)},unmounted(){console.log(`[CardBrowser] Card browser unmounted. Cards no longer in 'prewviewMode'`),this.previewMode.setPreviewMode(!1)},methods:{incrementView(){this.viewIndex++,this.viewIndex=(this.viewIndex+this.views.length)%this.views.length},decrementView(){this.viewIndex--,this.viewIndex=(this.viewIndex+this.views.length)%this.views.length}}}),Uc={key:0,class:`text-subtitle-1 pa-2`};function _sfc_render$2(t,n,r,i,a,o){let c=E(`CardViewer`),l=E(`v-icon`),u=E(`v-btn`),d=E(`v-row`);return x(),H(d,{column:``,align:`center`,justify:`center`},{default:s(()=>[f(c,{view:t.views[t.viewIndex],data:t.data,course_id:`[browsing]`,card_id:`[browsing]`},null,8,[`view`,`data`]),n[2]||(n[2]=I(`br`,null,null,-1)),n[3]||(n[3]=I(`br`,null,null,-1)),t.suppressSpinner?U(``,!0):(x(),R(`div`,Uc,[t.spinner?(x(),H(u,{key:0,icon:``,variant:`outlined`,color:`primary`,onClick:t.decrementView},{default:s(()=>[f(l,null,{default:s(()=>n[0]||(n[0]=[A(`mdi-chevron-left`)])),_:1})]),_:1},8,[`onClick`])):U(``,!0),A(` `+N(t.views[t.viewIndex].name)+` `,1),t.spinner?(x(),H(u,{key:1,icon:``,variant:`outlined`,color:`primary`,onClick:t.incrementView},{default:s(()=>[f(l,null,{default:s(()=>n[1]||(n[1]=[A(`mdi-chevron-right`)])),_:1})]),_:1},8,[`onClick`])):U(``,!0)]))]),_:1})}$e(_sfc_render$2,`_sfc_render`);var Wc=q(Hc,[[`render`,_sfc_render$2]]),Gc=j({name:`CourseTagFilterWidget`,props:{courseId:{type:String,required:!0},modelValue:{type:Object,default:void 0}},emits:[`update:modelValue`],setup(t,{emit:n}){let r=Ce(!0),i=Ce([]),a=Ce({}),o=Ce(t.modelValue?{...t.modelValue}:Ve()),s=z(()=>i.value.filter(t=>!o.value.include.includes(t))),c=z(()=>Ue(o.value)),fuzzyFilter=(t,n)=>{if(!n)return!0;let r=n.toLowerCase(),i=t.toLowerCase(),a=0;for(let t=0;t<i.length&&a<r.length;t++)i[t]===r[a]&&a++;return a===r.length};le(()=>t.modelValue,t=>{t?o.value={...t}:o.value=Ve()},{deep:!0}),le(o,t=>{n(`update:modelValue`,{...t})},{deep:!0}),le(()=>t.courseId,async t=>{t&&await loadTags()});async function loadTags(){r.value=!0;try{let n=await tt().getCourseDB(t.courseId).getCourseTagStubs();i.value=[],a.value={};for(let t of n.rows)if(t.doc){let n=t.doc;i.value.push(n.name),n.snippet&&(a.value[n.name]=n.snippet)}i.value.sort((t,n)=>t.localeCompare(n))}catch(t){console.error(`[CourseTagFilterWidget] Failed to load tags:`,t),i.value=[],a.value={}}finally{r.value=!1}}return Ie(()=>{t.courseId&&loadTags()}),{loading:r,availableTags:i,availableTagsForExclude:s,tagSnippets:a,localFilter:o,hasActiveFilter:c,fuzzyFilter}}}),Kc={class:`course-tag-filter-widget`},qc={key:0,class:`filter-summary text-caption mt-2`},Jc={key:0},Yc={key:1},Xc={key:2};function _sfc_render$1(t,n,r,i,a,o){let c=E(`v-chip`),l=E(`v-list-item`),u=E(`v-autocomplete`),d=E(`v-icon`);return x(),R(`div`,Kc,[f(u,{modelValue:t.localFilter.include,"onUpdate:modelValue":n[0]||(n[0]=n=>t.localFilter.include=n),items:t.availableTags,loading:t.loading,disabled:t.loading,label:`Include tags`,placeholder:`Type to search tags...`,hint:`Cards must have at least one of these tags`,"persistent-hint":``,multiple:``,chips:``,"closable-chips":``,clearable:``,density:`compact`,variant:`outlined`,class:`mb-2`,"custom-filter":t.fuzzyFilter,"no-data-text":`No matching tags found`},{chip:s(({props:t,item:n})=>[f(c,O(t,{color:`primary`,variant:`tonal`,size:`small`}),{default:s(()=>[A(N(n.raw),1)]),_:2},1040)]),item:s(({props:n,item:r})=>[f(l,O(n,{title:r.raw}),Ne({_:2},[t.tagSnippets[r.raw]?{name:`subtitle`,fn:s(()=>[A(N(t.tagSnippets[r.raw]),1)]),key:`0`}:void 0]),1040,[`title`])]),_:1},8,[`modelValue`,`items`,`loading`,`disabled`,`custom-filter`]),f(u,{modelValue:t.localFilter.exclude,"onUpdate:modelValue":n[1]||(n[1]=n=>t.localFilter.exclude=n),items:t.availableTagsForExclude,loading:t.loading,disabled:t.loading,label:`Exclude tags`,placeholder:`Type to search tags...`,hint:`Cards with these tags will be excluded`,"persistent-hint":``,multiple:``,chips:``,"closable-chips":``,clearable:``,density:`compact`,variant:`outlined`,"custom-filter":t.fuzzyFilter,"no-data-text":`No matching tags found`},{chip:s(({props:t,item:n})=>[f(c,O(t,{color:`error`,variant:`tonal`,size:`small`}),{default:s(()=>[A(N(n.raw),1)]),_:2},1040)]),item:s(({props:n,item:r})=>[f(l,O(n,{title:r.raw}),Ne({_:2},[t.tagSnippets[r.raw]?{name:`subtitle`,fn:s(()=>[A(N(t.tagSnippets[r.raw]),1)]),key:`0`}:void 0]),1040,[`title`])]),_:1},8,[`modelValue`,`items`,`loading`,`disabled`,`custom-filter`]),t.hasActiveFilter?(x(),R(`div`,qc,[f(d,{size:`small`,color:`info`,class:`mr-1`},{default:s(()=>n[2]||(n[2]=[A(`mdi-filter`)])),_:1}),t.localFilter.include.length?(x(),R(`span`,Jc,` Including: `+N(t.localFilter.include.join(`, `)),1)):U(``,!0),t.localFilter.include.length&&t.localFilter.exclude.length?(x(),R(`span`,Yc,` · `)):U(``,!0),t.localFilter.exclude.length?(x(),R(`span`,Xc,` Excluding: `+N(t.localFilter.exclude.join(`, `)),1)):U(``,!0)])):U(``,!0)])}$e(_sfc_render$1,`_sfc_render`);var Zc=q(Gc,[[`render`,_sfc_render$1],[`__scopeId`,`data-v-e1ba963b`]]),Qc={min:0,startingMax:2,absoluteMax:10},$c=`UserTagPreferenceFilter`,el=j({name:`UserTagPreferences`,props:{courseId:{type:String,required:!1,default:``},sliderConfig:{type:Object,required:!1,default:()=>({})}},emits:[`preferences-saved`,`preferences-changed`],data(){return{loading:!0,saving:!1,saveError:``,saveSuccess:!1,preferences:{boost:{}},savedPreferences:{boost:{}},tagMaxRanges:{},availableTags:[],tagToAdd:null,courseDB:null,user:null}},computed:{sliderConfigResolved(){return{min:this.sliderConfig.min??Qc.min,startingMax:this.sliderConfig.startingMax??Qc.startingMax,absoluteMax:this.sliderConfig.absoluteMax??Qc.absoluteMax}},tagNames(){return Object.keys(this.preferences.boost).sort()},globalSliderMax(){let t=Object.values(this.tagMaxRanges);return t.length===0?this.sliderConfigResolved.startingMax:Math.max(...t)},availableTagsToAdd(){let t=new Set(Object.keys(this.preferences.boost));return this.availableTags.filter(n=>!t.has(n.name))},hasChanges(){let t=Object.keys(this.preferences.boost).sort(),n=Object.keys(this.savedPreferences.boost).sort();return t.length!==n.length||t.join(`,`)!==n.join(`,`)?!0:t.some(t=>this.preferences.boost[t]!==this.savedPreferences.boost[t])}},watch:{courseId:{immediate:!0,async handler(t){t?await this.loadPreferences():this.loading=!1}}},methods:{async loadPreferences(){this.loading=!0,this.saveError=``;try{if(this.user=await getCurrentUser()??null,!this.user)throw Error(`User not available`);this.courseDB=tt().getCourseDB(this.courseId),this.availableTags=(await this.courseDB.getCourseTagStubs()).rows.map(t=>t.doc).filter(Boolean);let t=await this.user.getStrategyState(this.courseId,$c);t?this.preferences.boost={...t.boost}:this.preferences.boost={},this.savedPreferences.boost={...this.preferences.boost},this.tagMaxRanges={},Object.keys(this.preferences.boost).forEach(t=>{let n=this.preferences.boost[t],r=this.sliderConfigResolved.startingMax;n>r?this.tagMaxRanges[t]=Math.min(Math.ceil(n),this.sliderConfigResolved.absoluteMax):this.tagMaxRanges[t]=r})}catch(t){console.error(`Failed to load preferences:`,t),this.saveError=`Failed to load preferences. Please try again.`}finally{this.loading=!1}},addTag(t){t&&!(t in this.preferences.boost)&&(this.preferences.boost[t]=1,this.tagMaxRanges[t]=this.sliderConfigResolved.startingMax,this.$emit(`preferences-changed`,this.preferences)),this.$nextTick(()=>{this.tagToAdd=null})},removeTag(t){delete this.preferences.boost[t],delete this.tagMaxRanges[t],this.$emit(`preferences-changed`,this.preferences)},updateBoost(t,n){this.preferences.boost[t]=n,this.$emit(`preferences-changed`,this.preferences)},expandSliderRange(t){let n=this.globalSliderMax;if(n<this.sliderConfigResolved.absoluteMax){let r=n+1;Object.keys(this.tagMaxRanges).forEach(t=>{this.tagMaxRanges[t]=Math.max(this.tagMaxRanges[t],r)}),this.preferences.boost[t]=r,this.$emit(`preferences-changed`,this.preferences)}},formatMultiplier(t){return t===0?`0x`:t<.1?t.toFixed(2)+`x`:t.toFixed(1)+`x`},resetToSaved(){this.preferences.boost={...this.savedPreferences.boost},this.saveSuccess=!1,this.saveError=``,this.tagMaxRanges={},Object.keys(this.preferences.boost).forEach(t=>{let n=this.preferences.boost[t],r=this.sliderConfigResolved.startingMax;n>r?this.tagMaxRanges[t]=Math.min(Math.ceil(n),this.sliderConfigResolved.absoluteMax):this.tagMaxRanges[t]=r})},async savePreferences(){if(!this.user||!this.courseId){this.saveError=`Unable to save - user or course not available`;return}this.saving=!0,this.saveError=``,this.saveSuccess=!1;try{let t={boost:{...this.preferences.boost},updatedAt:new Date().toISOString()};await this.user.putStrategyState(this.courseId,$c,t),this.savedPreferences.boost={...this.preferences.boost},this.saveSuccess=!0,this.$emit(`preferences-saved`,t)}catch(t){console.error(`Failed to save preferences:`,t),this.saveError=`Failed to save preferences. Please try again.`}finally{this.saving=!1}}}}),tl={key:1},nl={class:`mb-6`},rl={class:`text-subtitle-1 font-weight-bold mb-2`},il={class:`d-flex align-center ga-3 w-100`},al={class:`text-body-2 flex-shrink-0`,style:{"min-width":`60px`,"text-align":`right`}},ol={key:2,class:`d-flex justify-center py-8`};function _sfc_render(t,n,r,i,a,o){let c=E(`v-icon`),l=E(`v-card-title`),u=E(`v-card-subtitle`),d=E(`v-alert`),p=E(`v-list-item`),h=E(`v-autocomplete`),g=E(`v-chip`),_=E(`v-slider`),b=E(`v-btn`),S=E(`v-list`),C=E(`v-progress-circular`),w=E(`v-card-text`),T=E(`v-spacer`),O=E(`v-card-actions`),k=E(`v-card`);return x(),H(k,{loading:t.loading},{default:s(()=>[f(l,null,{default:s(()=>[f(c,{start:``},{default:s(()=>n[3]||(n[3]=[A(`mdi-tune`)])),_:1}),n[4]||(n[4]=A(` Learning Preferences `))]),_:1}),t.courseId?(x(),H(u,{key:0},{default:s(()=>n[5]||(n[5]=[A(` Customize how content is presented in this course `)])),_:1})):U(``,!0),f(w,null,{default:s(()=>[t.courseId?t.loading?(x(),R(`div`,ol,[f(C,{indeterminate:``,color:`primary`})])):(x(),R(`div`,tl,[I(`div`,nl,[I(`h3`,rl,[f(c,{start:``,size:`small`},{default:s(()=>n[7]||(n[7]=[A(`mdi-tune-variant`)])),_:1}),n[8]||(n[8]=A(` Tag Preferences `))]),n[10]||(n[10]=I(`p`,{class:`text-body-2 text-medium-emphasis mb-3`},` Adjust how much you want to see cards with specific tags. 0 = exclude, 1 = neutral, higher = prefer more. `,-1)),f(h,{modelValue:t.tagToAdd,"onUpdate:modelValue":[n[0]||(n[0]=n=>t.tagToAdd=n),t.addTag],items:t.availableTagsToAdd,"item-title":`name`,"item-value":`name`,label:`Add tag preference`,placeholder:`Search tags...`,density:`compact`,variant:`outlined`,clearable:``,"hide-details":``,class:`mb-4`},{item:s(({props:t,item:n})=>[f(p,D(m(t)),{subtitle:s(()=>[A(N(n.raw.snippet),1)]),_:2},1040)]),_:1},8,[`modelValue`,`items`,`onUpdate:modelValue`]),t.tagNames.length>0?(x(),H(S,{key:0,class:`mt-4`},{default:s(()=>[(x(!0),R(ge,null,P(t.tagNames,n=>(x(),H(p,{key:n,class:`px-0`},{default:s(()=>[I(`div`,il,[f(g,{size:`small`,variant:`tonal`,class:`flex-shrink-0`,style:{"min-width":`120px`}},{default:s(()=>[A(N(n),1)]),_:2},1024),f(_,{"model-value":t.preferences.boost[n],min:t.sliderConfigResolved.min,max:t.globalSliderMax,step:.01,"hide-details":``,class:`flex-grow-1`,"thumb-label":``,"onUpdate:modelValue":r=>t.updateBoost(n,r)},{"thumb-label":s(({modelValue:n})=>[A(N(t.formatMultiplier(n)),1)]),_:2},1032,[`model-value`,`min`,`max`,`onUpdate:modelValue`]),I(`span`,al,N(t.formatMultiplier(t.preferences.boost[n])),1),f(b,{icon:`mdi-plus`,size:`small`,variant:`text`,density:`compact`,disabled:t.globalSliderMax>=t.sliderConfigResolved.absoluteMax,onClick:r=>t.expandSliderRange(n)},null,8,[`disabled`,`onClick`]),f(b,{icon:`mdi-delete`,size:`small`,variant:`text`,density:`compact`,onClick:r=>t.removeTag(n)},null,8,[`onClick`])])]),_:2},1024))),128))]),_:1})):(x(),H(d,{key:1,type:`info`,variant:`tonal`,class:`mt-4`},{default:s(()=>n[9]||(n[9]=[A(` No tag preferences configured yet. Add tags above to get started. `)])),_:1}))]),t.saveError?(x(),H(d,{key:0,type:`error`,variant:`tonal`,class:`mt-4`,closable:``,"onClick:close":n[1]||(n[1]=n=>t.saveError=``)},{default:s(()=>[A(N(t.saveError),1)]),_:1})):U(``,!0),t.saveSuccess?(x(),H(d,{key:1,type:`success`,variant:`tonal`,class:`mt-4`,closable:``,"onClick:close":n[2]||(n[2]=n=>t.saveSuccess=!1)},{default:s(()=>n[11]||(n[11]=[A(` Preferences saved successfully `)])),_:1})):U(``,!0)])):(x(),H(d,{key:0,type:`info`,variant:`tonal`,class:`mb-4`},{default:s(()=>n[6]||(n[6]=[A(` Select a course to configure your learning preferences. `)])),_:1}))]),_:1}),t.courseId&&!t.loading?(x(),H(O,{key:1},{default:s(()=>[f(T),f(b,{variant:`text`,disabled:!t.hasChanges,onClick:t.resetToSaved},{default:s(()=>n[12]||(n[12]=[A(` Reset `)])),_:1},8,[`disabled`,`onClick`]),f(b,{color:`primary`,variant:`flat`,loading:t.saving,disabled:!t.hasChanges,onClick:t.savePreferences},{default:s(()=>n[13]||(n[13]=[A(` Save Preferences `)])),_:1},8,[`loading`,`disabled`,`onClick`])]),_:1})):U(``,!0)]),_:1},8,[`loading`])}var sl=q(el,[[`render`,_sfc_render],[`__scopeId`,`data-v-8fb14605`]]);export{Js as A,sl as B,$s as C,nc as D,Zc as E,Qs as F,useRoute as G,lo as H,useAuthStore as I,useRouter as K,useConfigStore as L,resetPassword as M,sendVerificationEmail as N,Gs as O,Jo as P,validatePassword as R,Xs as S,ic as T,createRouter as U,sc as V,createWebHistory as W,Ec as _,Do as a,Bs as b,Displayable as c,Pc as d,yo as f,Question as g,zo as h,vc as i,requestPasswordReset as j,Wc as k,xo as l,Xo as m,Hs as n,ks as o,xc as p,ho as r,dc as s,Vc as t,No as u,Ao as v,getCurrentUser as w,Ko as x,wo as y,verifyEmail as z};
|
|
38
|
-
//# sourceMappingURL=common-ui.es-
|
|
36
|
+
`),this.password===this.retypedPassword){if(!this.user){console.error(`ERROR: No user object available`);return}this.user.createAccount(this.username,this.password).then(async t=>{if(t.status===Be.ok){if(this.authStore.loginAndRegistration.loggedIn=!0,this.authStore.loginAndRegistration.init=!1,this.authStore.loginAndRegistration.init=!0,this.email)try{let t=typeof window<`u`?window.location.origin:void 0,n=await sendVerificationEmail(this.username,this.email,t);n.ok?wo({text:`Account created! Please check your email to verify your account.`,status:Be.ok}):He(`Warning: Failed to send verification email: ${n.error}`)}catch(t){console.error(`Email save/send error:`,t),He(`Warning: Failed to save email or send verification: ${t}`)}this.onSignupSuccess&&(console.log(`[UserRegistration] Calling onSignupSuccess callback`),this.onSignupSuccess({username:this.username})),this.$emit(`signup-success`,{username:this.username})}else t.error===`This username is taken!`?(this.usernameError=!0,this.usernameHint=`Try a different name.`,this.$refs.userNameTextField.focus(),wo({text:`The name ${this.username} is taken!`,status:t.status})):wo({text:t.error,status:t.status})}).catch(t=>{console.error(`[UserRegistration] .catch() called with error:`,t),t&&wo({text:t?.message||t?.error||t?.toString()||`Account creation failed`,status:Be.error})}),this.awaitingResponse=!1}else wo({text:`Passwords do not match.`,status:Be.error}),this.awaitingResponse=!1}}});function _sfc_render$9(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-text-field`),u=E(`v-btn`),d=E(`v-snackbar`),p=E(`v-icon`),m=E(`router-link`),h=E(`v-form`),g=E(`v-card-text`),_=E(`v-card`);return x(),H(_,null,{default:s(()=>[f(c,{class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[7]||(n[7]=[A(` Create an Account `)])),_:1}),f(g,null,{default:s(()=>[f(h,{onSubmit:Oe(t.createUser,[`prevent`])},{default:s(()=>[f(l,{modelValue:t.email,"onUpdate:modelValue":n[0]||(n[0]=n=>t.email=n),name:`email`,label:`Email address`,type:`email`,"prepend-icon":`mdi-email`,error:t.emailError,hint:t.emailHint,onBlur:t.validateEmail},null,8,[`modelValue`,`error`,`hint`,`onBlur`]),f(l,{id:``,ref:`userNameTextField`,modelValue:t.username,"onUpdate:modelValue":n[1]||(n[1]=n=>t.username=n),name:`username`,label:`Choose a Username`,"prepend-icon":`mdi-account-circle`,error:t.usernameError,hint:t.usernameHint,onBlur:t.validateUsername},null,8,[`modelValue`,`error`,`hint`,`onBlur`]),f(l,{modelValue:t.password,"onUpdate:modelValue":n[2]||(n[2]=n=>t.password=n),"prepend-icon":`mdi-lock`,name:`password`,hover:`Show password`,label:`Create a password`,hint:t.passwordError,error:!!t.passwordError,min:`4`,"append-icon":t.passwordVisible?`mdi-eye-off`:`mdi-eye`,type:t.passwordVisible?`text`:`password`,"onClick:append":n[3]||(n[3]=()=>t.passwordVisible=!t.passwordVisible)},null,8,[`modelValue`,`hint`,`error`,`append-icon`,`type`]),f(l,{modelValue:t.retypedPassword,"onUpdate:modelValue":n[4]||(n[4]=n=>t.retypedPassword=n),"prepend-icon":`mdi-lock`,name:`retypedPassword`,hover:`Show password`,label:`Retype your password`,disabled:t.password===``||!!t.passwordError,hint:t.passwordRetypeError,min:`4`,type:t.passwordVisible?`text`:`password`},null,8,[`modelValue`,`disabled`,`hint`,`type`]),f(d,{modelValue:t.badLoginAttempt,"onUpdate:modelValue":n[6]||(n[6]=n=>t.badLoginAttempt=n),location:`bottom right`,timeout:5e3},{default:s(()=>[n[9]||(n[9]=A(` Username or password was incorrect. `)),f(u,{color:`pink`,variant:`text`,onClick:n[5]||(n[5]=n=>t.badLoginAttempt=!1)},{default:s(()=>n[8]||(n[8]=[A(` Close `)])),_:1})]),_:1},8,[`modelValue`]),f(u,{class:`mr-2 my-2`,type:`submit`,loading:t.awaitingResponse,color:t.buttonStatus.color,disabled:!!t.passwordError||t.password!==t.retypedPassword},{default:s(()=>[f(p,{start:``},{default:s(()=>n[10]||(n[10]=[A(`mdi-lock-open`)])),_:1}),n[11]||(n[11]=A(` Create Account `))]),_:1},8,[`loading`,`color`,`disabled`]),t.registrationRoute?(x(),H(m,{key:0,to:`login`},{default:s(()=>[f(u,{variant:`text`},{default:s(()=>n[12]||(n[12]=[A(`Log In`)])),_:1})]),_:1})):(x(),H(u,{key:1,variant:`text`,onClick:t.toggle},{default:s(()=>n[13]||(n[13]=[A(` Log In `)])),_:1},8,[`onClick`]))]),_:1},8,[`onSubmit`])]),_:1})]),_:1})}$e(_sfc_render$9,`_sfc_render`);var ic=q(rc,[[`render`,_sfc_render$9]]),ac=j({name:`RequestPasswordReset`,emits:[`cancel`,`success`],data(){return{email:``,emailError:!1,emailHint:``,isSubmitting:!1,requestSent:!1}},methods:{validateEmail(){this.emailError=!1,this.emailHint=``,this.email&&(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email)||(this.emailError=!0,this.emailHint=`Please enter a valid email address`))},async handleSubmit(){if(this.validateEmail(),!(this.emailError||!this.email)){this.isSubmitting=!0;try{let t=typeof window<`u`?window.location.origin:void 0,n=await requestPasswordReset(this.email,t);n.ok?(this.requestSent=!0,this.$emit(`success`,this.email)):wo({text:n.error||`Failed to send reset email`,status:Be.error})}catch{wo({text:`An unexpected error occurred`,status:Be.error})}finally{this.isSubmitting=!1}}}}}),oc={key:1,class:`text-center`};function _sfc_render$8(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-text-field`),u=E(`v-icon`),d=E(`v-btn`),p=E(`v-form`),m=E(`v-card-text`),h=E(`v-spacer`),g=E(`v-card-actions`),_=E(`v-card`);return x(),H(_,null,{default:s(()=>[f(c,{class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[2]||(n[2]=[A(` Reset Password `)])),_:1}),f(m,{class:`pa-6`},{default:s(()=>[t.requestSent?(x(),R(`div`,oc,[f(u,{color:`success`,size:`64`,class:`mb-4`},{default:s(()=>n[6]||(n[6]=[A(`mdi-email-check`)])),_:1}),n[9]||(n[9]=I(`h3`,{class:`mb-2`},`Check Your Email`,-1)),I(`p`,null,[n[7]||(n[7]=A(` If an account exists with `)),I(`strong`,null,N(t.email),1),n[8]||(n[8]=A(`, you will receive a password reset link shortly. `))]),n[10]||(n[10]=I(`p`,{class:`text-caption mt-4`},`Didn't receive an email? Check your spam folder.`,-1))])):(x(),H(p,{key:0,onSubmit:Oe(t.handleSubmit,[`prevent`])},{default:s(()=>[n[5]||(n[5]=I(`p`,{class:`mb-4`},` Enter your email address and we'll send you a link to reset your password. `,-1)),f(l,{modelValue:t.email,"onUpdate:modelValue":n[0]||(n[0]=n=>t.email=n),name:`email`,label:`Email address`,type:`email`,"prepend-icon":`mdi-email`,error:t.emailError,hint:t.emailHint,disabled:t.isSubmitting,onBlur:t.validateEmail},null,8,[`modelValue`,`error`,`hint`,`disabled`,`onBlur`]),f(d,{type:`submit`,color:`primary`,class:`mt-4`,loading:t.isSubmitting,disabled:!t.email||t.emailError,block:``},{default:s(()=>[f(u,{start:``},{default:s(()=>n[3]||(n[3]=[A(`mdi-email-send`)])),_:1}),n[4]||(n[4]=A(` Send Reset Link `))]),_:1},8,[`loading`,`disabled`])]),_:1},8,[`onSubmit`]))]),_:1}),t.requestSent?U(``,!0):(x(),H(g,{key:0},{default:s(()=>[b(t.$slots,`back-action`,{},()=>[f(d,{variant:`text`,onClick:n[1]||(n[1]=n=>t.$emit(`cancel`))},{default:s(()=>n[11]||(n[11]=[A(` Cancel `)])),_:1})]),f(h)]),_:3}))]),_:3})}$e(_sfc_render$8,`_sfc_render`);var sc=q(ac,[[`render`,_sfc_render$8]]),cc={key:0},lc={key:`login-buttons`},uc={key:`user-chip`},dc=q(j({__name:`UserLoginAndRegistrationContainer`,props:{showLoginButton:{type:Boolean},redirectToPath:{},showRegistration:{type:Boolean},onSignupSuccess:{type:Function}},emits:[`signup-success`],setup(t,{emit:n}){let r=t,i=n,a=useRoute(),o=useAuthStore(),c=useAuthUI();Ie(async()=>{await c.detectSyncStrategy()});let l=z(()=>{if(!a.name||typeof a.name!=`string`)return!0;let t=a.name.toLowerCase();return!(t===`login`||t===`signup`)}),u=z(()=>o.onLoadComplete),d=z(()=>o._user?o._user.getUsername().startsWith(rt):!o.loginAndRegistration.loggedIn),p=z(()=>({...c.config.value||{showLoginRegistration:!0,showLogout:!0,showResetData:!1,logoutLabel:`Log out`,resetLabel:``},...r.showRegistration!==void 0&&{showLoginRegistration:r.showRegistration}})),m=z({get:()=>o.loginAndRegistration.regDialogOpen,set:t=>{o.loginAndRegistration.regDialogOpen=t}}),h=z({get:()=>o.loginAndRegistration.loginDialogOpen,set:t=>{o.loginAndRegistration.loginDialogOpen=t}}),g=Ce(!1),toggle=()=>{if(m.value&&h.value)throw Error(`Registration / Login dialogs both activated.`);if(m.value===h.value)throw Error(`Registration / Login dialogs toggled while both were dormant.`);m.value=!m.value,h.value=!h.value},openResetDialog=()=>{h.value=!1,g.value=!0},closeResetDialog=()=>{g.value=!1},handleSignupSuccess=t=>{m.value=!1,r.onSignupSuccess&&r.onSignupSuccess(t),i(`signup-success`,t)};return(t,n)=>{let r=E(`v-btn`),i=E(`v-dialog`);return u.value&&l.value?(x(),R(`div`,cc,[f(De,{name:`component-fade`,mode:`out-in`},{default:s(()=>[d.value?(x(),R(`div`,lc,[p.value.showLoginRegistration?(x(),H(i,{key:0,modelValue:m.value,"onUpdate:modelValue":n[0]||(n[0]=t=>m.value=t),width:`500px`},{activator:s(({props:t})=>[f(r,O({class:`mr-2`,size:`small`,color:`success`},t),{default:s(()=>n[3]||(n[3]=[A(`Sign Up`)])),_:2},1040)]),default:s(()=>[f(ic,{onToggle:toggle,onSignupSuccess:handleSignupSuccess,"on-signup-success":handleSignupSuccess})]),_:1},8,[`modelValue`])):U(``,!0),f(i,{modelValue:h.value,"onUpdate:modelValue":n[1]||(n[1]=t=>h.value=t),width:`500px`},{activator:s(({props:t})=>[f(r,O({size:`small`,color:`success`},t),{default:s(()=>n[4]||(n[4]=[A(`Log In`)])),_:2},1040)]),default:s(()=>[f(nc,{onToggle:toggle,onForgotPassword:openResetDialog})]),_:1},8,[`modelValue`]),f(i,{modelValue:g.value,"onUpdate:modelValue":n[2]||(n[2]=t=>g.value=t),width:`500px`},{default:s(()=>[f(sc,{onCancel:closeResetDialog,onSuccess:closeResetDialog})]),_:1},8,[`modelValue`])])):(x(),R(`div`,uc,[f($s)]))]),_:1})])):U(``,!0)}}}),[[`__scopeId`,`data-v-5a55bdf0`]]),fc=j({name:`VerifyEmail`,emits:[`verified`,`error`],props:{token:{type:String,default:null}},data(){return{isVerifying:!1,verificationStatus:null,errorMessage:``,username:``}},async mounted(){await this.performVerification()},methods:{async performVerification(){let t=this.token||this.getTokenFromURL();if(!t){this.verificationStatus=`error`,this.errorMessage=`No verification token provided`;return}this.isVerifying=!0;try{let n=await verifyEmail(t);n.ok?(this.verificationStatus=`success`,this.username=n.username||``,wo({text:`Email verified successfully!`,status:Be.ok})):(this.verificationStatus=`error`,this.errorMessage=n.error||`Verification failed`,wo({text:n.error||`Verification failed`,status:Be.error}))}catch{this.verificationStatus=`error`,this.errorMessage=`An unexpected error occurred`,wo({text:`An unexpected error occurred`,status:Be.error})}finally{this.isVerifying=!1}},getTokenFromURL(){return typeof window>`u`?null:new URLSearchParams(window.location.search).get(`token`)}}}),pc={key:0,class:`text-center`},mc={key:1,class:`text-center`},hc={key:0},gc={key:2,class:`text-center`},_c={key:3,class:`text-center`};function _sfc_render$7(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-progress-circular`),u=E(`v-icon`),d=E(`v-card-text`),p=E(`v-spacer`),m=E(`v-btn`),h=E(`v-card-actions`),g=E(`v-card`),_=E(`v-col`),S=E(`v-row`),C=E(`v-container`);return x(),H(C,{class:`fill-height`,fluid:``},{default:s(()=>[f(S,{align:`center`,justify:`center`},{default:s(()=>[f(_,{cols:`12`,sm:`8`,md:`6`},{default:s(()=>[f(g,null,{default:s(()=>[f(c,{class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[2]||(n[2]=[A(` Email Verification `)])),_:1}),f(d,{class:`pa-6`},{default:s(()=>[t.isVerifying?(x(),R(`div`,pc,[f(l,{indeterminate:``,color:`primary`,size:`64`,class:`mb-4`}),n[3]||(n[3]=I(`p`,null,`Verifying your email...`,-1))])):t.verificationStatus===`success`?(x(),R(`div`,mc,[f(u,{color:`success`,size:`64`,class:`mb-4`},{default:s(()=>n[4]||(n[4]=[A(`mdi-check-circle`)])),_:1}),n[5]||(n[5]=I(`h3`,{class:`mb-2`},`Email Verified!`,-1)),n[6]||(n[6]=I(`p`,null,`Your account has been successfully verified.`,-1)),t.username?(x(),R(`p`,hc,`Welcome, `+N(t.username)+`!`,1)):U(``,!0)])):t.verificationStatus===`error`?(x(),R(`div`,gc,[f(u,{color:`error`,size:`64`,class:`mb-4`},{default:s(()=>n[7]||(n[7]=[A(`mdi-alert-circle`)])),_:1}),n[8]||(n[8]=I(`h3`,{class:`mb-2`},`Verification Failed`,-1)),I(`p`,null,N(t.errorMessage),1)])):(x(),R(`div`,_c,[f(u,{color:`warning`,size:`64`,class:`mb-4`},{default:s(()=>n[9]||(n[9]=[A(`mdi-help-circle`)])),_:1}),n[10]||(n[10]=I(`h3`,{class:`mb-2`},`No Verification Token`,-1)),n[11]||(n[11]=I(`p`,null,`Please use the link from your verification email.`,-1))]))]),_:1}),f(h,null,{default:s(()=>[f(p),b(t.$slots,`actions`,{status:t.verificationStatus,username:t.username},()=>[t.verificationStatus===`success`?(x(),H(m,{key:0,color:`primary`,onClick:n[0]||(n[0]=n=>t.$emit(`verified`,t.username))},{default:s(()=>n[12]||(n[12]=[A(` Continue `)])),_:1})):t.verificationStatus===`error`?(x(),H(m,{key:1,variant:`text`,onClick:n[1]||(n[1]=n=>t.$emit(`error`,t.errorMessage))},{default:s(()=>n[13]||(n[13]=[A(` Close `)])),_:1})):U(``,!0)])]),_:3})]),_:3})]),_:3})]),_:3})]),_:3})}$e(_sfc_render$7,`_sfc_render`);var vc=q(fc,[[`render`,_sfc_render$7]]),yc=j({name:`ResetPassword`,emits:[`complete`,`error`],props:{token:{type:String,default:null}},data(){return{password:``,confirmPassword:``,passwordVisible:!1,confirmPasswordError:!1,confirmPasswordHint:``,isSubmitting:!1,isComplete:!1}},computed:{canSubmit(){return this.password.length>=4&&this.confirmPassword.length>=4&&this.password===this.confirmPassword&&!this.confirmPasswordError}},methods:{validateConfirmPassword(){this.confirmPasswordError=!1,this.confirmPasswordHint=``,this.confirmPassword&&this.password!==this.confirmPassword&&(this.confirmPasswordError=!0,this.confirmPasswordHint=`Passwords do not match`)},async handleSubmit(){if(this.validateConfirmPassword(),!this.canSubmit)return;let t=this.token||this.getTokenFromURL();if(!t){wo({text:`No reset token provided. Please use the link from your email.`,status:Be.error}),this.$emit(`error`,`No token`);return}this.isSubmitting=!0;try{let n=await resetPassword(t,this.password);n.ok?(this.isComplete=!0,wo({text:`Password reset successfully!`,status:Be.ok})):(wo({text:n.error||`Failed to reset password`,status:Be.error}),this.$emit(`error`,n.error))}catch{wo({text:`An unexpected error occurred`,status:Be.error}),this.$emit(`error`,`Unexpected error`)}finally{this.isSubmitting=!1}},getTokenFromURL(){return typeof window>`u`?null:new URLSearchParams(window.location.search).get(`token`)}}}),bc={key:1,class:`text-center`};function _sfc_render$6(t,n,r,i,a,o){let c=E(`v-card-title`),l=E(`v-text-field`),u=E(`v-icon`),d=E(`v-btn`),p=E(`v-form`),m=E(`v-card-text`),h=E(`v-spacer`),g=E(`v-card-actions`),_=E(`v-card`),S=E(`v-col`),C=E(`v-row`),w=E(`v-container`);return x(),H(w,{class:`fill-height`,fluid:``},{default:s(()=>[f(C,{align:`center`,justify:`center`},{default:s(()=>[f(S,{cols:`12`,sm:`8`,md:`6`},{default:s(()=>[f(_,null,{default:s(()=>[f(c,{class:`text-h5 bg-grey-lighten-2`},{default:s(()=>n[4]||(n[4]=[A(` Set New Password `)])),_:1}),f(m,{class:`pa-6`},{default:s(()=>[t.isComplete?(x(),R(`div`,bc,[f(u,{color:`success`,size:`64`,class:`mb-4`},{default:s(()=>n[8]||(n[8]=[A(`mdi-check-circle`)])),_:1}),n[9]||(n[9]=I(`h3`,{class:`mb-2`},`Password Reset Successful!`,-1)),n[10]||(n[10]=I(`p`,null,`Your password has been updated. You can now log in with your new password.`,-1))])):(x(),H(p,{key:0,onSubmit:Oe(t.handleSubmit,[`prevent`])},{default:s(()=>[n[7]||(n[7]=I(`p`,{class:`mb-4`},`Enter your new password below.`,-1)),f(l,{modelValue:t.password,"onUpdate:modelValue":n[0]||(n[0]=n=>t.password=n),"prepend-icon":`mdi-lock`,name:`password`,label:`New password`,min:`4`,"append-icon":t.passwordVisible?`mdi-eye-off`:`mdi-eye`,type:t.passwordVisible?`text`:`password`,disabled:t.isSubmitting,"onClick:append":n[1]||(n[1]=()=>t.passwordVisible=!t.passwordVisible)},null,8,[`modelValue`,`append-icon`,`type`,`disabled`]),f(l,{modelValue:t.confirmPassword,"onUpdate:modelValue":n[2]||(n[2]=n=>t.confirmPassword=n),"prepend-icon":`mdi-lock`,name:`confirmPassword`,label:`Confirm new password`,min:`4`,type:t.passwordVisible?`text`:`password`,error:t.confirmPasswordError,hint:t.confirmPasswordHint,disabled:t.isSubmitting,onBlur:t.validateConfirmPassword},null,8,[`modelValue`,`type`,`error`,`hint`,`disabled`,`onBlur`]),f(d,{type:`submit`,color:`primary`,class:`mt-4`,loading:t.isSubmitting,disabled:!t.canSubmit,block:``},{default:s(()=>[f(u,{start:``},{default:s(()=>n[5]||(n[5]=[A(`mdi-lock-reset`)])),_:1}),n[6]||(n[6]=A(` Reset Password `))]),_:1},8,[`loading`,`disabled`])]),_:1},8,[`onSubmit`]))]),_:1}),t.isComplete?(x(),H(g,{key:0},{default:s(()=>[f(h),b(t.$slots,`success-action`,{},()=>[f(d,{color:`primary`,onClick:n[3]||(n[3]=n=>t.$emit(`complete`))},{default:s(()=>n[11]||(n[11]=[A(` Continue to Login `)])),_:1})])]),_:3})):U(``,!0)]),_:3})]),_:3})]),_:3})]),_:3})}$e(_sfc_render$6,`_sfc_render`);var xc=q(yc,[[`render`,_sfc_render$6]]),Sc=j({name:`SkTagsInput`,components:{VueTagsInput:oo},props:{courseID:{type:String,required:!0,default:``},cardID:{type:String,required:!1,default:``},hideSubmit:{type:Boolean,required:!1,default:!1}},data(){return{loading:!0,tag:``,tags:[],initialTags:[],availableCourseTags:[],separators:[`;`,`,`,` `],courseDB:null}},computed:{autoCompleteSuggestions(){return this.availableCourseTags.filter(t=>t.name.toLowerCase().indexOf(this.tag.toLowerCase())!==-1).map(t=>({text:t.name,data:{snippet:t.snippet}}))}},watch:{async cardID(){await this.getAppliedTags()},async courseID(){this.courseDB=tt().getCourseDB(this.courseID),await this.updateAvailableCourseTags()}},async created(){this.courseDB=tt().getCourseDB(this.courseID),await this.updateAvailableCourseTags(),await this.getAppliedTags()},methods:{tagsChanged(t){console.log(`[TagsInput] Tags changing: ${JSON.stringify(t)}`),this.tags=t},async getAppliedTags(){this.initialTags=[],this.tags=[];try{(await this.courseDB.getAppliedTags(this.cardID)).rows.forEach(t=>{console.log(`[TagsInput] The following tag is applied:
|
|
37
|
+
\t${JSON.stringify(t)}`),this.tags.push({text:t.value.name,style:``,classes:``})}),this.initialTags=this.tags.map(t=>t.text)}catch(t){console.error(`Error in init-getAppliedTags: ${JSON.stringify(t)}, ${t}`)}finally{this.loading=!1}},async updateAvailableCourseTags(){try{this.availableCourseTags=(await this.courseDB.getCourseTagStubs()).rows.map(t=>t.doc)}catch(t){console.error(`Error in init-availableCourseTags: ${JSON.stringify(t)}`)}},async submit(){console.log(`[TagsInput] tagsInput is submitting...`),this.loading=!0;try{await Promise.all(this.tags.map(async t=>{if(!this.initialTags.includes(t.text))try{await this.courseDB.addTagToCard(this.cardID,t.text),console.log(`[TagsInput] Successfully added tag: ${t.text}`)}catch(n){console.error(`Failed to add tag ${t.text}:`,n)}}))}catch(t){console.error(`Exception adding tags: ${JSON.stringify(t)}`)}try{await Promise.all(this.initialTags.map(async t=>{if(this.tags.filter(n=>n.text===t).length===0)try{await this.courseDB.removeTagFromCard(this.cardID,t),console.log(`[TagsInput] Successfully removed tag: ${t}`)}catch(n){console.error(`Failed to remove tag ${t}:`,n)}}))}catch(t){console.error(`Exception removing tags: ${JSON.stringify(t)}`)}this.loading=!1}}}),Cc={"data-cy":`tags-input`},wc={class:`tag-name`},Tc={key:0,class:`tag-snippet`};function _sfc_render$5(t,n,r,i,a,o){let c=E(`vue-tags-input`),l=E(`v-btn`);return x(),R(`div`,Cc,[f(c,{modelValue:t.tag,"onUpdate:modelValue":n[0]||(n[0]=n=>t.tag=n),tags:t.tags,"autocomplete-items":t.autoCompleteSuggestions,separators:t.separators,"add-on-key":t.separators,onTagsChanged:t.tagsChanged},{"autocomplete-item":s(t=>[I(`div`,{class:w([`autocomplete-item`,{"is-active":t.selected}])},[I(`span`,wc,N(t.item.text),1),t.item.data&&t.item.data.snippet?(x(),R(`span`,Tc,` - `+N(t.item.data.snippet),1)):U(``,!0)],2)]),_:1},8,[`modelValue`,`tags`,`autocomplete-items`,`separators`,`add-on-key`,`onTagsChanged`]),t.hideSubmit?U(``,!0):(x(),H(l,{key:0,color:`success`,loading:t.loading,onClick:t.submit},{default:s(()=>n[1]||(n[1]=[A(`Save Changes`)])),_:1},8,[`loading`,`onClick`]))])}$e(_sfc_render$5,`_sfc_render`);var Ec=q(Sc,[[`render`,_sfc_render$5],[`__scopeId`,`data-v-f7373dc0`]]),Dc=j({name:`CourseCardBrowser`,components:{CardLoader:Qs,TagsInput:Ec,PaginatingToolbar:Ao},props:{courseId:{type:String,required:!0},tagId:{type:String,required:!1,default:``},viewLookupFunction:{type:Function,required:!0,default:()=>(console.warn(`No viewLookupFunction provided to CourseCardBrowser`),null)},editMode:{type:String,required:!1,default:`full`}},data(){return{courseDB:null,page:1,pages:[],cards:[],cardData:{},cardPreview:{},cardElos:{},cardTags:{},internalEditMode:`none`,delBtn:!1,updatePending:!0,userIsRegistered:!1,questionCount:0,tags:[],viewLookup:this.viewLookupFunction}},async created(){try{this.courseDB=tt().getCourseDB(this.courseId),this.tagId?this.questionCount=(await this.courseDB.getTag(this.tagId)).taggedCards.length:this.questionCount=(await this.courseDB.getCourseInfo()).cardCount;for(let t=1;(t-1)*25<this.questionCount;t++)this.pages.push(t);await this.populateTableData()}catch(t){console.error(`Error initializing CourseCardBrowser:`,t)}finally{this.updatePending=!1}},methods:{idQualify(t){return t.includes(`-`)?t:`${this.courseId}-${t}`},idToQualifiedObject(t){if(t.includes(`-`)){let n=t.split(`-`);return{courseID:n[0],cardID:n[1]}}else return{courseID:this.courseId,cardID:t}},first(){this.page=1,this.populateTableData()},prev(){this.page--,this.populateTableData()},next(){this.page++,this.populateTableData()},last(){this.page=this.pages.length,this.populateTableData()},setPage(t){this.page=t,this.populateTableData()},async loadCardTags(t){try{await Promise.all(t.map(async t=>{let n=await this.courseDB.getAppliedTags(t);this.cardTags[t]=n.rows.map(t=>({name:t.value.name,snippet:t.value.snippet,count:t.value.count}))}))}catch(t){console.error(`Error loading card tags:`,t)}},clearSelections(t=``){this.cards.forEach(n=>{n.card.cardID!==t&&(n.isOpen=!1)}),this.internalEditMode=`none`,this.delBtn=!1},async deleteCard(t){console.log(`Deleting card ${t}`);let n=await this.courseDB.removeCard(t);n.ok?(this.cards=this.cards.filter(n=>n.card.cardID!=t),this.clearSelections()):(console.error(`Failed to delete card:\n\n${JSON.stringify(n)}`),wo({text:`Failed to delete card`,status:Be.error}))},async populateTableData(){this.updatePending=!0,this.tagId?this.cards=(await this.courseDB.getTag(this.tagId)).taggedCards.map(t=>({card:{cardID:t,courseID:this.courseId},isOpen:!1,delBtn:!1})):this.cards=(await this.courseDB.getCardsByELO(0,25)).map(t=>({card:t,isOpen:!1,delBtn:!1}));let t=[],n=(await this.courseDB.getCourseDocs(this.cards.map(t=>t.card.cardID),{include_docs:!0})).rows.filter(t=>t.doc?!0:(console.error(`Card ${t.id}.doc not found.\ncard: ${JSON.stringify(t)}`),!1)).map(t=>t.doc);this.cards=this.cards.filter(n=>!t.includes(n.card.cardID)),n.forEach(t=>{t&&t.id_displayable_data&&(this.cardData[t._id]=t.id_displayable_data)});try{await Promise.all(this.cards.map(async t=>{let r=t.card.cardID,i=n.find(t=>t._id==r);if(!i||!i.id_displayable_data){console.error(`No valid data found for card ${r}`);return}let a=this.viewLookupFunction(i.id_view||`default.question.BlanksCard.FillInView`),o=i.id_displayable_data.map(t=>this.courseDB.getCourseDoc(t,{attachments:!1,binary:!0})),s=await Promise.all(o);await Promise.all(s.map(n=>{[].unshift(We(n)),this.cardPreview[t.card.cardID]=a.name?a.name:`Unknown`}))}));let t=this.cards.map(t=>t.card.cardID),r=await this.courseDB.getCardEloData(t);t.forEach((t,n)=>{this.cardElos[t]=r[n]}),await this.loadCardTags(t)}catch(t){console.error(`Error populating table data:`,t)}finally{this.updatePending=!1,this.$forceUpdate()}}}}),Oc={key:0,class:`d-flex justify-center align-center pa-6`},kc={key:1},Ac={key:0,class:`px-4 py-2 bg-blue-grey-lighten-5`},jc={key:0,class:`mt-4`},Mc={class:`mt-4`},Nc={key:0,class:`ml-4`};function _sfc_render$4(t,n,r,i,a,o){let c=E(`v-progress-circular`),l=E(`paginating-toolbar`),u=E(`v-list-item-title`),d=E(`v-list-item-subtitle`),p=E(`v-btn`),m=E(`v-icon`),h=E(`v-speed-dial`),g=E(`v-list-item`),_=E(`card-loader`),b=E(`v-chip`),S=E(`v-chip-group`),C=E(`tags-input`),T=E(`v-list`),D=E(`v-card`);return x(),H(D,null,{default:s(()=>[t.updatePending?(x(),R(`div`,Oc,[f(c,{indeterminate:``,color:`primary`})])):(x(),R(`div`,kc,[f(l,{title:`Exercises`,page:t.page,pages:t.pages,subtitle:`(${t.questionCount})`,onFirst:t.first,onPrev:t.prev,onNext:t.next,onLast:t.last,onSetPage:n[0]||(n[0]=n=>t.setPage(n))},null,8,[`page`,`pages`,`subtitle`,`onFirst`,`onPrev`,`onNext`,`onLast`]),f(T,null,{default:s(()=>[(x(!0),R(ge,null,P(t.cards,r=>(x(),R(ge,{key:r.card.cardID},[f(g,{class:w({"bg-blue-grey-lighten-5":r.isOpen,"elevation-4":r.isOpen}),density:`compact`,"data-cy":`course-card`},{prepend:s(()=>[I(`div`,null,[f(u,{class:w([{"text-blue-grey-darken-1":r.isOpen},`font-weight-medium`])},{default:s(()=>[A(N(t.cardPreview[r.card.cardID]),1)]),_:2},1032,[`class`]),f(d,null,{default:s(()=>[A(` ELO: `+N(t.cardElos[r.card.cardID]?.global?.score||`(unknown)`),1)]),_:2},1024)])]),append:s(()=>[f(h,{modelValue:r.isOpen,"onUpdate:modelValue":t=>r.isOpen=t,location:`left center`,transition:`slide-x-transition`,style:{display:`flex`,"flex-direction":`row-reverse`},persistent:``},{activator:s(({props:n})=>[f(p,O({ref_for:!0},n,{icon:r.isOpen?`mdi-close`:`mdi-plus`,size:`small`,variant:`text`,onClick:n=>t.clearSelections(r.card.cardID)}),null,16,[`icon`,`onClick`])]),default:s(()=>[t.editMode===`full`?(x(),H(p,{key:`tags`,icon:``,size:`small`,variant:t.internalEditMode===`tags`?`elevated`:`outlined`,color:t.internalEditMode===`tags`?`teal`:`teal-darken-3`,onClick:n[1]||(n[1]=Oe(n=>t.internalEditMode=`tags`,[`stop`]))},{default:s(()=>[f(m,null,{default:s(()=>n[4]||(n[4]=[A(`mdi-bookmark`)])),_:1})]),_:1},8,[`variant`,`color`])):U(``,!0),t.editMode===`full`?(x(),H(p,{key:`flag`,icon:``,size:`small`,variant:t.internalEditMode===`flag`?`elevated`:`outlined`,color:t.internalEditMode===`flag`?`error`:`error-darken-3`,onClick:n[2]||(n[2]=Oe(n=>t.internalEditMode=`flag`,[`stop`]))},{default:s(()=>[f(m,null,{default:s(()=>n[5]||(n[5]=[A(`mdi-flag`)])),_:1})]),_:1},8,[`variant`,`color`])):U(``,!0)]),_:2},1032,[`modelValue`,`onUpdate:modelValue`])]),_:2},1032,[`class`]),r.isOpen?(x(),R(`div`,Ac,[f(_,{qualified_id:r.card,"view-lookup":t.viewLookup,class:`elevation-1`},null,8,[`qualified_id`,`view-lookup`]),t.editMode===`readonly`&&t.cardTags[r.card.cardID]?(x(),R(`div`,jc,[f(S,null,{default:s(()=>[(x(!0),R(ge,null,P(t.cardTags[r.card.cardID],t=>(x(),H(b,{key:t.name,size:`small`,color:`primary`,variant:`outlined`},{default:s(()=>[A(N(t.name),1)]),_:2},1024))),128))]),_:2},1024)])):U(``,!0),he(f(C,{"course-i-d":t.courseId,"card-i-d":r.card.cardID,class:`mt-4`},null,8,[`course-i-d`,`card-i-d`]),[[pe,t.internalEditMode===`tags`&&t.editMode===`full`]]),he(I(`div`,Mc,[f(p,{color:`error`,variant:`outlined`,onClick:t=>r.delBtn=!0},{default:s(()=>n[6]||(n[6]=[A(` Delete this card `)])),_:2},1032,[`onClick`]),r.delBtn?(x(),R(`span`,Nc,[n[8]||(n[8]=I(`span`,{class:`mr-2`},`Are you sure?`,-1)),f(p,{color:`error`,variant:`elevated`,onClick:n=>t.deleteCard(r.card.cardID)},{default:s(()=>n[7]||(n[7]=[A(` Confirm `)])),_:2},1032,[`onClick`])])):U(``,!0)],512),[[pe,t.internalEditMode===`flag`&&t.editMode===`full`]])])):U(``,!0)],64))),128))]),_:1}),f(l,{class:`elevation-0`,page:t.page,pages:t.pages,onFirst:t.first,onPrev:t.prev,onNext:t.next,onLast:t.last,onSetPage:n[3]||(n[3]=n=>t.setPage(n))},null,8,[`page`,`pages`,`onFirst`,`onPrev`,`onNext`,`onLast`])]))]),_:1})}$e(_sfc_render$4,`_sfc_render`);var Pc=q(Dc,[[`render`,_sfc_render$4],[`__scopeId`,`data-v-5ecc9d21`]]),Fc=j({name:`CourseInformation`,components:{CourseCardBrowser:Pc},props:{courseId:{type:String,required:!0},viewLookupFunction:{type:Function,required:!1,default:t=>(console.warn(`No viewLookupFunction provided to CourseInformation`),null)},editMode:{type:String,required:!1,default:`full`}},data(){return{courseDB:null,nameRules:[t=>t.length>30?`Course name must be 30 characters or less`:!0],updatePending:!0,courseConfig:{},userIsRegistered:!1,tags:[],user:null}},computed:{},async created(){this.courseDB=tt().getCourseDB(this.courseId),this.user=await getCurrentUser();let t=await this.user.getCourseRegistrationsDoc();this.user.getUsername()===`admin`?this.userIsRegistered=!0:this.userIsRegistered=t.courses.filter(t=>t.courseID===this.courseId&&(t.status===`active`||t.status===void 0)).length===1,this.courseConfig=await this.courseDB.getCourseConfig(),this.tags=(await this.courseDB.getCourseTagStubs()).rows.map(t=>t.doc),this.updatePending=!1},methods:{async register(){He(`Registering for ${this.courseId}`),(await this.user.registerForCourse(this.courseId)).ok&&(this.userIsRegistered=!0)},async drop(){He(`Dropping course ${this.courseId}`),(await this.user.dropCourse(this.courseId)).ok&&(this.userIsRegistered=!1)}}}),Ic={key:0},Lc={class:`text-h4 mb-2`},Rc={class:`text-body-2`},zc={key:0},Bc={key:1};function _sfc_render$3(t,n,r,i,a,o){let c=E(`v-btn`),l=E(`v-icon`),u=E(`v-toolbar-title`),d=E(`v-toolbar-items`),p=E(`v-toolbar`),m=E(`v-chip`),h=E(`v-card-text`),g=E(`v-card`),_=E(`course-card-browser`);return t.updatePending?U(``,!0):(x(),R(`div`,Ic,[b(t.$slots,`header`,{courseConfig:t.courseConfig,courseId:t.courseId},()=>[I(`h1`,Lc,N(t.courseConfig.name),1)],!0),I(`p`,Rc,N(t.courseConfig.description),1),b(t.$slots,`actions`,{userIsRegistered:t.userIsRegistered,courseId:t.courseId,editMode:t.editMode,register:t.register,drop:t.drop},()=>[f(De,{name:`component-fade`,mode:`out-in`},{default:s(()=>[t.userIsRegistered?(x(),R(`div`,zc,[f(c,{color:`success`,"data-cy":`focused-study-session-btn`,class:`me-2`},{default:s(()=>n[0]||(n[0]=[A(`Start ad study session`)])),_:1}),t.editMode===`full`?(x(),H(c,{key:0,"data-cy":`add-content-btn`,color:`indigo-lighten-1`,class:`me-2`},{default:s(()=>[f(l,{start:``},{default:s(()=>n[1]||(n[1]=[A(`mdi-plus`)])),_:1}),n[2]||(n[2]=A(` Add content `))]),_:1})):U(``,!0),t.editMode===`full`?(x(),H(c,{key:1,color:`green-darken-2`,title:`Rank course content for difficulty`,class:`me-2`},{default:s(()=>[f(l,{start:``},{default:s(()=>n[3]||(n[3]=[A(`mdi-format-list-numbered`)])),_:1}),n[4]||(n[4]=A(` Arrange `))]),_:1})):U(``,!0),t.editMode===`full`?(x(),H(c,{key:2,color:`error`,size:`small`,variant:`outlined`,onClick:t.drop},{default:s(()=>n[5]||(n[5]=[A(` Drop this course `)])),_:1},8,[`onClick`])):U(``,!0)])):(x(),R(`div`,Bc,[f(c,{"data-cy":`register-btn`,color:`primary`,class:`me-2`,onClick:t.register},{default:s(()=>n[6]||(n[6]=[A(`Register`)])),_:1},8,[`onClick`]),f(c,{variant:`outlined`,color:`primary`,class:`me-2`},{default:s(()=>n[7]||(n[7]=[A(`Start a trial study session`)])),_:1})]))]),_:1})],!0),b(t.$slots,`additional-content`,{},void 0,!0),f(g,{class:`my-2`},{default:s(()=>[f(p,{density:`compact`},{default:s(()=>[f(u,null,{default:s(()=>n[8]||(n[8]=[A(`Tags`)])),_:1}),f(d,null,{default:s(()=>[f(c,{variant:`text`},{default:s(()=>[A(`(`+N(t.tags.length)+`)`,1)]),_:1})]),_:1})]),_:1}),f(h,null,{default:s(()=>[(x(!0),R(ge,null,P(t.tags,(n,r)=>(x(),R(`span`,{key:r},[b(t.$slots,`tag-link`,{tag:n,courseId:t.courseId},()=>[f(m,{variant:`tonal`,class:`me-2 mb-2`},{default:s(()=>[A(N(n.name),1)]),_:2},1024)],!0)]))),128))]),_:3})]),_:3}),f(_,{class:`my-3`,"course-id":t.courseId,"view-lookup-function":t.viewLookupFunction,"edit-mode":t.editMode},null,8,[`course-id`,`view-lookup-function`,`edit-mode`])]))}$e(_sfc_render$3,`_sfc_render`);var Vc=q(Fc,[[`render`,_sfc_render$3],[`__scopeId`,`data-v-38e9efe1`]]),Hc=j({name:`CardBrowser`,components:{CardViewer:Xo},props:{views:{type:Array,required:!0},data:{type:Array,required:!0},suppressSpinner:{type:Boolean,default:!1}},data(){return{viewIndex:0,previewMode:Ye()}},computed:{spinner(){return this.views.length>1}},created(){console.log(`[CardBrowser] Card browser created. Cards now in 'prewviewMode'`),this.previewMode.setPreviewMode(!0)},unmounted(){console.log(`[CardBrowser] Card browser unmounted. Cards no longer in 'prewviewMode'`),this.previewMode.setPreviewMode(!1)},methods:{incrementView(){this.viewIndex++,this.viewIndex=(this.viewIndex+this.views.length)%this.views.length},decrementView(){this.viewIndex--,this.viewIndex=(this.viewIndex+this.views.length)%this.views.length}}}),Uc={key:0,class:`text-subtitle-1 pa-2`};function _sfc_render$2(t,n,r,i,a,o){let c=E(`CardViewer`),l=E(`v-icon`),u=E(`v-btn`),d=E(`v-row`);return x(),H(d,{column:``,align:`center`,justify:`center`},{default:s(()=>[f(c,{view:t.views[t.viewIndex],data:t.data,course_id:`[browsing]`,card_id:`[browsing]`},null,8,[`view`,`data`]),n[2]||(n[2]=I(`br`,null,null,-1)),n[3]||(n[3]=I(`br`,null,null,-1)),t.suppressSpinner?U(``,!0):(x(),R(`div`,Uc,[t.spinner?(x(),H(u,{key:0,icon:``,variant:`outlined`,color:`primary`,onClick:t.decrementView},{default:s(()=>[f(l,null,{default:s(()=>n[0]||(n[0]=[A(`mdi-chevron-left`)])),_:1})]),_:1},8,[`onClick`])):U(``,!0),A(` `+N(t.views[t.viewIndex].name)+` `,1),t.spinner?(x(),H(u,{key:1,icon:``,variant:`outlined`,color:`primary`,onClick:t.incrementView},{default:s(()=>[f(l,null,{default:s(()=>n[1]||(n[1]=[A(`mdi-chevron-right`)])),_:1})]),_:1},8,[`onClick`])):U(``,!0)]))]),_:1})}$e(_sfc_render$2,`_sfc_render`);var Wc=q(Hc,[[`render`,_sfc_render$2]]),Gc=j({name:`CourseTagFilterWidget`,props:{courseId:{type:String,required:!0},modelValue:{type:Object,default:void 0}},emits:[`update:modelValue`],setup(t,{emit:n}){let r=Ce(!0),i=Ce([]),a=Ce({}),o=Ce(t.modelValue?{...t.modelValue}:Ve()),s=z(()=>i.value.filter(t=>!o.value.include.includes(t))),c=z(()=>Ue(o.value)),fuzzyFilter=(t,n)=>{if(!n)return!0;let r=n.toLowerCase(),i=t.toLowerCase(),a=0;for(let t=0;t<i.length&&a<r.length;t++)i[t]===r[a]&&a++;return a===r.length};le(()=>t.modelValue,t=>{t?o.value={...t}:o.value=Ve()},{deep:!0}),le(o,t=>{n(`update:modelValue`,{...t})},{deep:!0}),le(()=>t.courseId,async t=>{t&&await loadTags()});async function loadTags(){r.value=!0;try{let n=await tt().getCourseDB(t.courseId).getCourseTagStubs();i.value=[],a.value={};for(let t of n.rows)if(t.doc){let n=t.doc;i.value.push(n.name),n.snippet&&(a.value[n.name]=n.snippet)}i.value.sort((t,n)=>t.localeCompare(n))}catch(t){console.error(`[CourseTagFilterWidget] Failed to load tags:`,t),i.value=[],a.value={}}finally{r.value=!1}}return Ie(()=>{t.courseId&&loadTags()}),{loading:r,availableTags:i,availableTagsForExclude:s,tagSnippets:a,localFilter:o,hasActiveFilter:c,fuzzyFilter}}}),Kc={class:`course-tag-filter-widget`},qc={key:0,class:`filter-summary text-caption mt-2`},Jc={key:0},Yc={key:1},Xc={key:2};function _sfc_render$1(t,n,r,i,a,o){let c=E(`v-chip`),l=E(`v-list-item`),u=E(`v-autocomplete`),d=E(`v-icon`);return x(),R(`div`,Kc,[f(u,{modelValue:t.localFilter.include,"onUpdate:modelValue":n[0]||(n[0]=n=>t.localFilter.include=n),items:t.availableTags,loading:t.loading,disabled:t.loading,label:`Include tags`,placeholder:`Type to search tags...`,hint:`Cards must have at least one of these tags`,"persistent-hint":``,multiple:``,chips:``,"closable-chips":``,clearable:``,density:`compact`,variant:`outlined`,class:`mb-2`,"custom-filter":t.fuzzyFilter,"no-data-text":`No matching tags found`},{chip:s(({props:t,item:n})=>[f(c,O(t,{color:`primary`,variant:`tonal`,size:`small`}),{default:s(()=>[A(N(n.raw),1)]),_:2},1040)]),item:s(({props:n,item:r})=>[f(l,O(n,{title:r.raw}),Ne({_:2},[t.tagSnippets[r.raw]?{name:`subtitle`,fn:s(()=>[A(N(t.tagSnippets[r.raw]),1)]),key:`0`}:void 0]),1040,[`title`])]),_:1},8,[`modelValue`,`items`,`loading`,`disabled`,`custom-filter`]),f(u,{modelValue:t.localFilter.exclude,"onUpdate:modelValue":n[1]||(n[1]=n=>t.localFilter.exclude=n),items:t.availableTagsForExclude,loading:t.loading,disabled:t.loading,label:`Exclude tags`,placeholder:`Type to search tags...`,hint:`Cards with these tags will be excluded`,"persistent-hint":``,multiple:``,chips:``,"closable-chips":``,clearable:``,density:`compact`,variant:`outlined`,"custom-filter":t.fuzzyFilter,"no-data-text":`No matching tags found`},{chip:s(({props:t,item:n})=>[f(c,O(t,{color:`error`,variant:`tonal`,size:`small`}),{default:s(()=>[A(N(n.raw),1)]),_:2},1040)]),item:s(({props:n,item:r})=>[f(l,O(n,{title:r.raw}),Ne({_:2},[t.tagSnippets[r.raw]?{name:`subtitle`,fn:s(()=>[A(N(t.tagSnippets[r.raw]),1)]),key:`0`}:void 0]),1040,[`title`])]),_:1},8,[`modelValue`,`items`,`loading`,`disabled`,`custom-filter`]),t.hasActiveFilter?(x(),R(`div`,qc,[f(d,{size:`small`,color:`info`,class:`mr-1`},{default:s(()=>n[2]||(n[2]=[A(`mdi-filter`)])),_:1}),t.localFilter.include.length?(x(),R(`span`,Jc,` Including: `+N(t.localFilter.include.join(`, `)),1)):U(``,!0),t.localFilter.include.length&&t.localFilter.exclude.length?(x(),R(`span`,Yc,` · `)):U(``,!0),t.localFilter.exclude.length?(x(),R(`span`,Xc,` Excluding: `+N(t.localFilter.exclude.join(`, `)),1)):U(``,!0)])):U(``,!0)])}$e(_sfc_render$1,`_sfc_render`);var Zc=q(Gc,[[`render`,_sfc_render$1],[`__scopeId`,`data-v-e1ba963b`]]),Qc={min:0,startingMax:2,absoluteMax:10},$c=`UserTagPreferenceFilter`,el=j({name:`UserTagPreferences`,props:{courseId:{type:String,required:!1,default:``},sliderConfig:{type:Object,required:!1,default:()=>({})}},emits:[`preferences-saved`,`preferences-changed`],data(){return{loading:!0,saving:!1,saveError:``,saveSuccess:!1,preferences:{boost:{}},savedPreferences:{boost:{}},tagMaxRanges:{},availableTags:[],tagToAdd:null,courseDB:null,user:null}},computed:{sliderConfigResolved(){return{min:this.sliderConfig.min??Qc.min,startingMax:this.sliderConfig.startingMax??Qc.startingMax,absoluteMax:this.sliderConfig.absoluteMax??Qc.absoluteMax}},tagNames(){return Object.keys(this.preferences.boost).sort()},globalSliderMax(){let t=Object.values(this.tagMaxRanges);return t.length===0?this.sliderConfigResolved.startingMax:Math.max(...t)},availableTagsToAdd(){let t=new Set(Object.keys(this.preferences.boost));return this.availableTags.filter(n=>!t.has(n.name))},hasChanges(){let t=Object.keys(this.preferences.boost).sort(),n=Object.keys(this.savedPreferences.boost).sort();return t.length!==n.length||t.join(`,`)!==n.join(`,`)?!0:t.some(t=>this.preferences.boost[t]!==this.savedPreferences.boost[t])}},watch:{courseId:{immediate:!0,async handler(t){t?await this.loadPreferences():this.loading=!1}}},methods:{async loadPreferences(){this.loading=!0,this.saveError=``;try{if(this.user=await getCurrentUser()??null,!this.user)throw Error(`User not available`);this.courseDB=tt().getCourseDB(this.courseId),this.availableTags=(await this.courseDB.getCourseTagStubs()).rows.map(t=>t.doc).filter(Boolean);let t=await this.user.getStrategyState(this.courseId,$c);t?this.preferences.boost={...t.boost}:this.preferences.boost={},this.savedPreferences.boost={...this.preferences.boost},this.tagMaxRanges={},Object.keys(this.preferences.boost).forEach(t=>{let n=this.preferences.boost[t],r=this.sliderConfigResolved.startingMax;n>r?this.tagMaxRanges[t]=Math.min(Math.ceil(n),this.sliderConfigResolved.absoluteMax):this.tagMaxRanges[t]=r})}catch(t){console.error(`Failed to load preferences:`,t),this.saveError=`Failed to load preferences. Please try again.`}finally{this.loading=!1}},addTag(t){t&&!(t in this.preferences.boost)&&(this.preferences.boost[t]=1,this.tagMaxRanges[t]=this.sliderConfigResolved.startingMax,this.$emit(`preferences-changed`,this.preferences)),this.$nextTick(()=>{this.tagToAdd=null})},removeTag(t){delete this.preferences.boost[t],delete this.tagMaxRanges[t],this.$emit(`preferences-changed`,this.preferences)},updateBoost(t,n){this.preferences.boost[t]=n,this.$emit(`preferences-changed`,this.preferences)},expandSliderRange(t){let n=this.globalSliderMax;if(n<this.sliderConfigResolved.absoluteMax){let r=n+1;Object.keys(this.tagMaxRanges).forEach(t=>{this.tagMaxRanges[t]=Math.max(this.tagMaxRanges[t],r)}),this.preferences.boost[t]=r,this.$emit(`preferences-changed`,this.preferences)}},formatMultiplier(t){return t===0?`0x`:t<.1?t.toFixed(2)+`x`:t.toFixed(1)+`x`},resetToSaved(){this.preferences.boost={...this.savedPreferences.boost},this.saveSuccess=!1,this.saveError=``,this.tagMaxRanges={},Object.keys(this.preferences.boost).forEach(t=>{let n=this.preferences.boost[t],r=this.sliderConfigResolved.startingMax;n>r?this.tagMaxRanges[t]=Math.min(Math.ceil(n),this.sliderConfigResolved.absoluteMax):this.tagMaxRanges[t]=r})},async savePreferences(){if(!this.user||!this.courseId){this.saveError=`Unable to save - user or course not available`;return}this.saving=!0,this.saveError=``,this.saveSuccess=!1;try{let t={boost:{...this.preferences.boost},updatedAt:new Date().toISOString()};await this.user.putStrategyState(this.courseId,$c,t),this.savedPreferences.boost={...this.preferences.boost},this.saveSuccess=!0,this.$emit(`preferences-saved`,t)}catch(t){console.error(`Failed to save preferences:`,t),this.saveError=`Failed to save preferences. Please try again.`}finally{this.saving=!1}}}}),tl={key:1},nl={class:`mb-6`},rl={class:`text-subtitle-1 font-weight-bold mb-2`},il={class:`d-flex align-center ga-3 w-100`},al={class:`text-body-2 flex-shrink-0`,style:{"min-width":`60px`,"text-align":`right`}},ol={key:2,class:`d-flex justify-center py-8`};function _sfc_render(t,n,r,i,a,o){let c=E(`v-icon`),l=E(`v-card-title`),u=E(`v-card-subtitle`),d=E(`v-alert`),p=E(`v-list-item`),h=E(`v-autocomplete`),g=E(`v-chip`),_=E(`v-slider`),b=E(`v-btn`),S=E(`v-list`),C=E(`v-progress-circular`),w=E(`v-card-text`),T=E(`v-spacer`),O=E(`v-card-actions`),k=E(`v-card`);return x(),H(k,{loading:t.loading},{default:s(()=>[f(l,null,{default:s(()=>[f(c,{start:``},{default:s(()=>n[3]||(n[3]=[A(`mdi-tune`)])),_:1}),n[4]||(n[4]=A(` Learning Preferences `))]),_:1}),t.courseId?(x(),H(u,{key:0},{default:s(()=>n[5]||(n[5]=[A(` Customize how content is presented in this course `)])),_:1})):U(``,!0),f(w,null,{default:s(()=>[t.courseId?t.loading?(x(),R(`div`,ol,[f(C,{indeterminate:``,color:`primary`})])):(x(),R(`div`,tl,[I(`div`,nl,[I(`h3`,rl,[f(c,{start:``,size:`small`},{default:s(()=>n[7]||(n[7]=[A(`mdi-tune-variant`)])),_:1}),n[8]||(n[8]=A(` Tag Preferences `))]),n[10]||(n[10]=I(`p`,{class:`text-body-2 text-medium-emphasis mb-3`},` Adjust how much you want to see cards with specific tags. 0 = exclude, 1 = neutral, higher = prefer more. `,-1)),f(h,{modelValue:t.tagToAdd,"onUpdate:modelValue":[n[0]||(n[0]=n=>t.tagToAdd=n),t.addTag],items:t.availableTagsToAdd,"item-title":`name`,"item-value":`name`,label:`Add tag preference`,placeholder:`Search tags...`,density:`compact`,variant:`outlined`,clearable:``,"hide-details":``,class:`mb-4`},{item:s(({props:t,item:n})=>[f(p,D(m(t)),{subtitle:s(()=>[A(N(n.raw.snippet),1)]),_:2},1040)]),_:1},8,[`modelValue`,`items`,`onUpdate:modelValue`]),t.tagNames.length>0?(x(),H(S,{key:0,class:`mt-4`},{default:s(()=>[(x(!0),R(ge,null,P(t.tagNames,n=>(x(),H(p,{key:n,class:`px-0`},{default:s(()=>[I(`div`,il,[f(g,{size:`small`,variant:`tonal`,class:`flex-shrink-0`,style:{"min-width":`120px`}},{default:s(()=>[A(N(n),1)]),_:2},1024),f(_,{"model-value":t.preferences.boost[n],min:t.sliderConfigResolved.min,max:t.globalSliderMax,step:.01,"hide-details":``,class:`flex-grow-1`,"thumb-label":``,"onUpdate:modelValue":r=>t.updateBoost(n,r)},{"thumb-label":s(({modelValue:n})=>[A(N(t.formatMultiplier(n)),1)]),_:2},1032,[`model-value`,`min`,`max`,`onUpdate:modelValue`]),I(`span`,al,N(t.formatMultiplier(t.preferences.boost[n])),1),f(b,{icon:`mdi-plus`,size:`small`,variant:`text`,density:`compact`,disabled:t.globalSliderMax>=t.sliderConfigResolved.absoluteMax,onClick:r=>t.expandSliderRange(n)},null,8,[`disabled`,`onClick`]),f(b,{icon:`mdi-delete`,size:`small`,variant:`text`,density:`compact`,onClick:r=>t.removeTag(n)},null,8,[`onClick`])])]),_:2},1024))),128))]),_:1})):(x(),H(d,{key:1,type:`info`,variant:`tonal`,class:`mt-4`},{default:s(()=>n[9]||(n[9]=[A(` No tag preferences configured yet. Add tags above to get started. `)])),_:1}))]),t.saveError?(x(),H(d,{key:0,type:`error`,variant:`tonal`,class:`mt-4`,closable:``,"onClick:close":n[1]||(n[1]=n=>t.saveError=``)},{default:s(()=>[A(N(t.saveError),1)]),_:1})):U(``,!0),t.saveSuccess?(x(),H(d,{key:1,type:`success`,variant:`tonal`,class:`mt-4`,closable:``,"onClick:close":n[2]||(n[2]=n=>t.saveSuccess=!1)},{default:s(()=>n[11]||(n[11]=[A(` Preferences saved successfully `)])),_:1})):U(``,!0)])):(x(),H(d,{key:0,type:`info`,variant:`tonal`,class:`mb-4`},{default:s(()=>n[6]||(n[6]=[A(` Select a course to configure your learning preferences. `)])),_:1}))]),_:1}),t.courseId&&!t.loading?(x(),H(O,{key:1},{default:s(()=>[f(T),f(b,{variant:`text`,disabled:!t.hasChanges,onClick:t.resetToSaved},{default:s(()=>n[12]||(n[12]=[A(` Reset `)])),_:1},8,[`disabled`,`onClick`]),f(b,{color:`primary`,variant:`flat`,loading:t.saving,disabled:!t.hasChanges,onClick:t.savePreferences},{default:s(()=>n[13]||(n[13]=[A(` Save Preferences `)])),_:1},8,[`loading`,`disabled`,`onClick`])]),_:1})):U(``,!0)]),_:1},8,[`loading`])}var sl=q(el,[[`render`,_sfc_render],[`__scopeId`,`data-v-8fb14605`]]);export{Js as A,verifyEmail as B,$s as C,nc as D,Zc as E,Jo as F,createWebHistory as G,sc as H,Qs as I,useRoute as K,useAuthStore as L,resetPassword as M,resolveLoginIdentifier as N,Gs as O,sendVerificationEmail as P,useConfigStore as R,Xs as S,ic as T,lo as U,sl as V,createRouter as W,Ec as _,Do as a,Bs as b,Displayable as c,Pc as d,yo as f,Question as g,zo as h,vc as i,requestPasswordReset as j,Wc as k,xo as l,Xo as m,Hs as n,ks as o,xc as p,useRouter as q,ho as r,dc as s,Vc as t,No as u,Ao as v,getCurrentUser as w,Ko as x,wo as y,validatePassword as z};
|
|
38
|
+
//# sourceMappingURL=common-ui.es-ChjTd0d0.js.map
|