From 6351d84e16ba8a6d01fdbb7f71c413ec960baf9d Mon Sep 17 00:00:00 2001 From: SVM0N <61781578+SVM0N@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:56:45 +0000 Subject: [PATCH] chore(privacy): remove identity/locale signals and dangling private-doc refs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found by an actual read-through of every 1.1/1.2 file, not keyword search: - src/utils.ts, src/view/chart.ts, esbuild.config.mjs: comments/code named a specific timezone (CEST), keyboard layout (Swedish), and locale code (sv-SE) used only for its date-format side effect — three independent signals triangulating toward the same nationality. Genericized all three; esbuild.config.mjs now formats the build timestamp manually instead of depending on any locale string at all. - main.ts, src/view/table.ts, src/view/toolbar.ts: "iPhone"/"iCloud" framed as the author's own device/sync setup — genericized to "mobile"/ "sync". - main.ts, src/inline-view.ts, src/travel-data.ts, src/travel-view.ts: dangling "see handoff"/"HANDOFF" references to handoff.md, which is gitignored and not part of the public repo. Replaced each with a self-contained inline explanation instead of a pointer nobody can follow. - docs/architecture.md: "Built for the author's book library and habit tracking" softened to describe original use case without first-person ownership framing. - docs/dev-workflow.md: the project-tree diagram was stale (referenced test-mobile-dashboards.mjs and xlsx-to-csv-roundtrip.mjs, both long gone) and garbled (a cut-off local/ bullet with a "hardcoded-path caveat" aside). Rewritten to match the actual current file list. Tests: 115 passed, 0 failed. Typecheck clean. Build unaffected. --- esbuild.config.mjs | 10 ++++++---- main.js | 2 +- main.ts | 11 ++++++----- src/inline-view.ts | 3 ++- src/travel-data.ts | 8 +++++--- src/travel-view.ts | 6 +++--- src/utils.ts | 4 ++-- src/view/chart.ts | 2 +- src/view/table.ts | 2 +- src/view/toolbar.ts | 2 +- 10 files changed, 28 insertions(+), 22 deletions(-) diff --git a/esbuild.config.mjs b/esbuild.config.mjs index 9ea08ee..7f3b801 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -7,10 +7,12 @@ const isWatch = process.argv.includes("--watch"); // (about 50% on the SheetJS-heavy bundle). // Build-time timestamp injected into the bundle. Lets a tiny "Built: …" // menu entry in the plugin show the user which build they're actually -// running — useful on iPhone where iCloud sync of the deployed bundle -// can lag behind the desktop build and there's no obvious way to confirm -// the new code arrived. Format: ISO-ish "YYYY-MM-DD HH:mm" in local time. -const buildTime = new Date().toLocaleString("sv-SE", { hour12: false }).slice(0, 16); +// running — useful on mobile where sync of the deployed bundle can lag +// behind the desktop build and there's no obvious way to confirm the new +// code arrived. Format: "YYYY-MM-DD HH:mm" in local time. +const now = new Date(); +const pad = (n) => String(n).padStart(2, "0"); +const buildTime = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}`; const buildOptions = { entryPoints: ["main.ts"], diff --git a/main.js b/main.js index 59cce19..32047c2 100644 --- a/main.js +++ b/main.js @@ -11,7 +11,7 @@ `)>-1?s.split(` `):s}function Yf(s,t){let{element:e,datasetIndex:n,index:i}=t,o=s.getDatasetMeta(n).controller,{label:r,value:a}=o.getLabelAndValue(i);return{chart:s,label:r,parsed:o.getParsed(i),raw:s.data.datasets[n].data[i],formattedValue:a,dataset:o.getDataset(),dataIndex:i,datasetIndex:n,element:e}}function el(s,t){let e=s.chart.ctx,{body:n,footer:i,title:o}=s,{boxWidth:r,boxHeight:a}=t,l=bt(t.bodyFont),c=bt(t.titleFont),d=bt(t.footerFont),h=o.length,u=i.length,f=n.length,g=St(t.padding),p=g.height,b=0,m=n.reduce((k,S)=>k+S.before.length+S.lines.length+S.after.length,0);if(m+=s.beforeBody.length+s.afterBody.length,h&&(p+=h*c.lineHeight+(h-1)*t.titleSpacing+t.titleMarginBottom),m){let k=t.displayColors?Math.max(a,l.lineHeight):l.lineHeight;p+=f*k+(m-f)*l.lineHeight+(m-1)*t.bodySpacing}u&&(p+=t.footerMarginTop+u*d.lineHeight+(u-1)*t.footerSpacing);let v=0,_=function(k){b=Math.max(b,e.measureText(k).width+v)};return e.save(),e.font=c.string,lt(s.title,_),e.font=l.string,lt(s.beforeBody.concat(s.afterBody),_),v=t.displayColors?r+2+t.boxPadding:0,lt(n,k=>{lt(k.before,_),lt(k.lines,_),lt(k.after,_)}),v=0,e.font=d.string,lt(s.footer,_),e.restore(),b+=g.width,{width:b,height:p}}function Gf(s,t){let{y:e,height:n}=t;return es.height-n/2?"bottom":"center"}function Kf(s,t,e,n){let{x:i,width:o}=n,r=e.caretSize+e.caretPadding;if(s==="left"&&i+o+r>t.width||s==="right"&&i-o-r<0)return!0}function qf(s,t,e,n){let{x:i,width:o}=e,{width:r,chartArea:{left:a,right:l}}=s,c="center";return n==="center"?c=i<=(a+l)/2?"left":"right":i<=o/2?c="left":i>=r-o/2&&(c="right"),Kf(c,s,t,e)&&(c="center"),c}function sl(s,t,e){let n=e.yAlign||t.yAlign||Gf(s,e);return{xAlign:e.xAlign||t.xAlign||qf(s,t,e,n),yAlign:n}}function Xf(s,t){let{x:e,width:n}=s;return t==="right"?e-=n:t==="center"&&(e-=n/2),e}function Qf(s,t,e){let{y:n,height:i}=s;return t==="top"?n+=e:t==="bottom"?n-=i+e:n-=i/2,n}function nl(s,t,e,n){let{caretSize:i,caretPadding:o,cornerRadius:r}=s,{xAlign:a,yAlign:l}=e,c=i+o,{topLeft:d,topRight:h,bottomLeft:u,bottomRight:f}=De(r),g=Xf(t,a),p=Qf(t,l,c);return l==="center"?a==="left"?g+=c:a==="right"&&(g-=c):a==="left"?g-=Math.max(d,u)+i:a==="right"&&(g+=Math.max(h,f)+i),{x:vt(g,0,n.width-t.width),y:vt(p,0,n.height-t.height)}}function Qn(s,t,e){let n=St(e.padding);return t==="center"?s.x+s.width/2:t==="right"?s.x+s.width-n.right:s.x+n.left}function il(s){return se([],fe(s))}function Zf(s,t,e){return ue(s,{tooltip:t,tooltipItems:e,type:"tooltip"})}function ol(s,t){let e=t&&t.dataset&&t.dataset.tooltip&&t.dataset.tooltip.callbacks;return e?s.override(e):s}function At(s,t,e,n){let i=s[t].call(e,n);return typeof i=="undefined"?Ul[t].call(e,n):i}function tg(s,t,e,n){let i=s.indexOf(t);if(i===-1)return Jf(s,t,e,n);let o=s.lastIndexOf(t);return i!==o?e:i}function rl(s){let t=this.getLabels();return s>=0&&sg&&(S=zi(E*S/g/f)*f),et(l)||(x=Math.pow(10,l),S=Math.ceil(S*x)/x),i==="ticks"?(y=Math.floor(p/S)*S,C=Math.ceil(b/S)*S):(y=p,C=b),m&&v&&o&&Yr((a-r)/o,S/1e3)?(E=Math.round(Math.min((a-r)/S,d)),S=(a-r)/E,y=r,C=a):_?(y=m?r:y,C=v?a:C,E=c-1,S=(C-y)/E):(E=(C-y)/S,ps(E,Math.round(E),S/1e3)?E=Math.round(E):E=Math.ceil(E));let D=Math.max(ji(S),ji(y));x=Math.pow(10,et(l)?D:l),y=Math.round(y*x)/x,C=Math.round(C*x)/x;let w=0;for(m&&(u&&y!==r?(e.push({value:r}),ya)break;e.push({value:M})}return v&&u&&C!==a?e.length&&ps(e[e.length-1].value,a,al(a,k,s))?e[e.length-1].value=a:e.push({value:a}):(!v||C===a)&&e.push({value:C}),e}function al(s,t,{horizontal:e,minRotation:n}){let i=zt(n),o=(e?Math.sin(i):Math.cos(i))||.001,r=.75*t*(""+s).length;return Math.min(t/o,r)}function ll(s){return s/Math.pow(10,cn(s))===1}function cl(s,t,e){let n=Math.pow(10,e),i=Math.floor(s/n);return Math.ceil(t/n)-i}function ng(s,t){let e=t-s,n=cn(e);for(;cl(s,t,n)>10;)n++;for(;cl(s,t,n)<10;)n--;return Math.min(n,cn(s))}function ig(s,{min:t,max:e}){t=Lt(s.min,t);let n=[],i=cn(t),o=ng(t,e),r=o<0?Math.pow(10,Math.abs(o)):1,a=Math.pow(10,o),l=i>o?Math.pow(10,i):0,c=Math.round((t-l)*r)/r,d=Math.floor((t-l)/a/10)*a*10,h=Math.floor((c-d)/Math.pow(10,o)),u=Lt(s.min,Math.round((l+d+h*Math.pow(10,o))*r)/r);for(;u=10?h=h<15?15:20:h++,h>=20&&(o++,h=2,r=o>=0?1:r),u=Math.round((l+d+h*Math.pow(10,o))*r)/r;let f=Lt(s.max,u);return n.push({value:f,major:ll(f),significand:h}),n}function Io(s){let t=s.ticks;if(t.display&&s.display){let e=St(t.backdropPadding);return J(t.font&&t.font.size,ut.font.size)+e.height}return 0}function og(s,t,e){return e=dt(e)?e:[e],{w:ea(s,t.string,e),h:e.length*t.lineHeight}}function dl(s,t,e,n,i){return s===n||s===i?{start:t-e/2,end:t+e/2}:si?{start:t-e,end:t}:{start:t,end:t+e}}function rg(s){let t={l:s.left+s._padding.left,r:s.right-s._padding.right,t:s.top+s._padding.top,b:s.bottom-s._padding.bottom},e=Object.assign({},t),n=[],i=[],o=s._pointLabels.length,r=s.options.pointLabels,a=r.centerPointLabels?it/o:0;for(let l=0;lt.r&&(a=(n.end-t.r)/o,s.r=Math.max(s.r,t.r+a)),i.startt.b&&(l=(i.end-t.b)/r,s.b=Math.max(s.b,t.b+l))}function lg(s,t,e){let n=s.drawingArea,{extra:i,additionalAngle:o,padding:r,size:a}=e,l=s.getPointPosition(t,n+i+r,o),c=Math.round(Vn(Ct(l.angle+mt))),d=fg(l.y,a.h,c),h=hg(c),u=ug(l.x,a.w,h);return{visible:!0,x:l.x,y:d,textAlign:h,left:u,top:d,right:u+a.w,bottom:d+a.h}}function cg(s,t){if(!t)return!0;let{left:e,top:n,right:i,bottom:o}=s;return!(Jt({x:e,y:n},t)||Jt({x:e,y:o},t)||Jt({x:i,y:n},t)||Jt({x:i,y:o},t))}function dg(s,t,e){let n=[],i=s._pointLabels.length,o=s.options,{centerPointLabels:r,display:a}=o.pointLabels,l={extra:Io(o)/2,additionalAngle:r?it/i:0},c;for(let d=0;d270||e<90)&&(s-=t),s}function gg(s,t,e){let{left:n,top:i,right:o,bottom:r}=e,{backdropColor:a}=t;if(!et(a)){let l=De(t.borderRadius),c=St(t.backdropPadding);s.fillStyle=a;let d=n-c.left,h=i-c.top,u=o-n+c.width,f=r-i+c.height;Object.values(l).some(g=>g!==0)?(s.beginPath(),ys(s,{x:d,y:h,w:u,h:f,radius:l}),s.fill()):s.fillRect(d,h,u,f)}}function pg(s,t){let{ctx:e,options:{pointLabels:n}}=s;for(let i=t-1;i>=0;i--){let o=s._pointLabelItems[i];if(!o.visible)continue;let r=n.setContext(s.getPointLabelContext(i));gg(e,r,o);let a=bt(r.font),{x:l,y:c,textAlign:d}=o;Ee(e,s._pointLabels[i],l,c+a.lineHeight/2,a,{color:r.color,textAlign:d,textBaseline:"middle"})}}function Kl(s,t,e,n){let{ctx:i}=s;if(e)i.arc(s.xCenter,s.yCenter,t,0,ht);else{let o=s.getPointPosition(0,t);i.moveTo(o.x,o.y);for(let r=1;r=Pt.indexOf(e);o--){let r=Pt[o];if(ci[r].common&&s._adapter.diff(i,n,r)>=t-1)return r}return Pt[e?Pt.indexOf(e):0]}function yg(s){for(let t=Pt.indexOf(s)+1,e=Pt.length;t=t?e[n]:e[i];s[o]=!0}}function xg(s,t,e,n){let i=s._adapter,o=+i.startOf(t[0].value,n),r=t[t.length-1].value,a,l;for(a=o;a<=r;a=+i.add(a,1,n))l=e[a],l>=0&&(t[l].major=!0);return t}function pl(s,t,e){let n=[],i={},o=t.length,r,a;for(r=0;r=s[n].pos&&t<=s[i].pos&&({lo:n,hi:i}=Zt(s,"pos",t)),{pos:o,time:a}=s[n],{pos:r,time:l}=s[i]):(t>=s[n].time&&t<=s[i].time&&({lo:n,hi:i}=Zt(s,"time",t)),{time:o,pos:a}=s[n],{time:r,pos:l}=s[i]);let c=r-o;return c?a+(l-a)*(t-o)/c:a}var Eo,ne,ba,Ch,ei,on,bo,_a,Rh,Rt,je,Ue,oe,Ye,Ae,_s,Ge,Ke,vl,Do,yl,xl,Cl,kt,rn,si,Jn,eu,La,Sl,an,Aa,ii,Ot,vu,Ra,Pa,Oe,Ss,Mo,Yt,To,Na,Ml,tn,Ro,Nu,$u,Hu,ti,Wa,ie,Te,of,Gt,qe,Xe,Pl,Oo,Ya,Il,Nl,ri,$l,tl,$f,ai,zl,ln,Wl,Xn,jl,sn,Ul,nn,Yl,Gl,Jf,eg,ks,Ms,ws,cn,We,Es,Le,ci,Pt,Pe,Ds,ql,Cg,Ql=_i(()=>{ma();Eo=class{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,n,i){let o=e.listeners[i],r=e.duration;o.forEach(a=>a({chart:t,initial:e.initial,numSteps:r,currentStep:Math.min(n-e.start,r)}))}_refresh(){this._request||(this._running=!0,this._request=Ki.call(window,()=>{this._update(),this._request=null,this._running&&this._refresh()}))}_update(t=Date.now()){let e=0;this._charts.forEach((n,i)=>{if(!n.running||!n.items.length)return;let o=n.items,r=o.length-1,a=!1,l;for(;r>=0;--r)l=o[r],l._active?(l._total>n.duration&&(n.duration=l._total),l.tick(t),a=!0):(o[r]=o[o.length-1],o.pop());a&&(i.draw(),this._notify(i,n,t,"progress")),o.length||(n.running=!1,this._notify(i,n,t,"complete"),n.initial=!1),e+=o.length}),this._lastDate=t,e===0&&(this._running=!1)}_getAnims(t){let e=this._charts,n=e.get(t);return n||(n={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,n)),n}listen(t,e,n){this._getAnims(t).listeners[e].push(n)}add(t,e){!e||!e.length||this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){let e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce((n,i)=>Math.max(n,i._duration),0),this._refresh())}running(t){if(!this._running)return!1;let e=this._charts.get(t);return!(!e||!e.running||!e.items.length)}stop(t){let e=this._charts.get(t);if(!e||!e.items.length)return;let n=e.items,i=n.length-1;for(;i>=0;--i)n[i].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}},ne=new Eo,ba="transparent",Ch={boolean(s,t,e){return e>.5?t:s},color(s,t,e){let n=Ji(s||ba),i=n.valid&&Ji(t||ba);return i&&i.valid?i.mix(n,e).hexString():t},number(s,t,e){return s+(t-s)*e}},ei=class{constructor(t,e,n,i){let o=e[n];i=xs([t.to,i,o,t.from]);let r=xs([t.from,o,i]);this._active=!0,this._fn=t.fn||Ch[t.type||typeof r],this._easing=ds[t.easing]||ds.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=n,this._from=r,this._to=i,this._promises=void 0}active(){return this._active}update(t,e,n){if(this._active){this._notify(!1);let i=this._target[this._prop],o=n-this._start,r=this._duration-o;this._start=n,this._duration=Math.floor(Math.max(r,t.duration)),this._total+=o,this._loop=!!t.loop,this._to=xs([t.to,e,i,t.from]),this._from=xs([t.from,i,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){let e=t-this._start,n=this._duration,i=this._prop,o=this._from,r=this._loop,a=this._to,l;if(this._active=o!==a&&(r||e1?2-l:l,l=this._easing(Math.min(1,Math.max(0,l))),this._target[i]=this._fn(o,a,l)}wait(){let t=this._promises||(this._promises=[]);return new Promise((e,n)=>{t.push({res:e,rej:n})})}_notify(t){let e=t?"res":"rej",n=this._promises||[];for(let i=0;i{let o=t[i];if(!st(o))return;let r={};for(let a of e)r[a]=o[a];(dt(o.properties)&&o.properties||[i]).forEach(a=>{(a===i||!n.has(a))&&n.set(a,r)})})}_animateOptions(t,e){let n=e.options,i=Sh(t,n);if(!i)return[];let o=this._createAnimations(i,n);return n.$shared&&_h(t.options.$animations,n).then(()=>{t.options=n},()=>{}),o}_createAnimations(t,e){let n=this._properties,i=[],o=t.$animations||(t.$animations={}),r=Object.keys(e),a=Date.now(),l;for(l=r.length-1;l>=0;--l){let c=r[l];if(c.charAt(0)==="$")continue;if(c==="options"){i.push(...this._animateOptions(t,e));continue}let d=e[c],h=o[c],u=n.get(c);if(h)if(u&&h.active()){h.update(u,d,a);continue}else h.cancel();if(!u||!u.duration){t[c]=d;continue}o[c]=h=new ei(u,t,c,d),i.push(h)}return i}update(t,e){if(this._properties.size===0){Object.assign(t,e);return}let n=this._createAnimations(t,e);if(n.length)return ne.add(this._chart,n),!0}};bo=s=>s==="reset"||s==="none",_a=(s,t)=>t?s:Object.assign({},s),Rh=(s,t,e)=>s&&!t.hidden&&t._stacked&&{keys:ml(e,!0),values:null},Rt=class{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.datasetElementType=new.target.datasetElementType,this.dataElementType=new.target.dataElementType,this.initialize()}initialize(){let t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=po(t.vScale,t),this.addElements(),this.options.fill&&!this.chart.isPluginEnabled("filler")&&console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options")}updateIndex(t){this.index!==t&&Xs(this._cachedMeta),this.index=t}linkScales(){let t=this.chart,e=this._cachedMeta,n=this.getDataset(),i=(h,u,f,g)=>h==="x"?u:h==="r"?g:f,o=e.xAxisID=J(n.xAxisID,mo(t,"x")),r=e.yAxisID=J(n.yAxisID,mo(t,"y")),a=e.rAxisID=J(n.rAxisID,mo(t,"r")),l=e.indexAxis,c=e.iAxisID=i(l,o,r,a),d=e.vAxisID=i(l,r,o,a);e.xScale=this.getScaleForId(o),e.yScale=this.getScaleForId(r),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(c),e.vScale=this.getScaleForId(d)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){let e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){let t=this._cachedMeta;this._data&&Yi(this._data,this),t._stacked&&Xs(t)}_dataCheck(){let t=this.getDataset(),e=t.data||(t.data=[]),n=this._data;if(st(e)){let i=this._cachedMeta;this._data=Eh(e,i)}else if(n!==e){if(n){Yi(n,this);let i=this._cachedMeta;Xs(i),i._parsed=[]}e&&Object.isExtensible(e)&&Qr(e,this),this._syncList=[],this._data=e}}addElements(){let t=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(t.dataset=new this.datasetElementType)}buildOrUpdateElements(t){let e=this._cachedMeta,n=this.getDataset(),i=!1;this._dataCheck();let o=e._stacked;e._stacked=po(e.vScale,e),e.stack!==n.stack&&(i=!0,Xs(e),e.stack=n.stack),this._resyncElements(t),(i||o!==e._stacked)&&(Ca(this,e._parsed),e._stacked=po(e.vScale,e))}configure(){let t=this.chart.config,e=t.datasetScopeKeys(this._type),n=t.getOptionScopes(this.getDataset(),e,!0);this.options=t.createResolver(n,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(t,e){let{_cachedMeta:n,_data:i}=this,{iScale:o,_stacked:r}=n,a=o.axis,l=t===0&&e===i.length?!0:n._sorted,c=t>0&&n._parsed[t-1],d,h,u;if(this._parsing===!1)n._parsed=i,n._sorted=!0,u=i;else{dt(i[t])?u=this.parseArrayData(n,i,t,e):st(i[t])?u=this.parseObjectData(n,i,t,e):u=this.parsePrimitiveData(n,i,t,e);let f=()=>h[a]===null||c&&h[a]p||h=0;--u)if(!g()){this.updateRangeFromParsed(c,t,f,l);break}}return c}getAllParsedValues(t){let e=this._cachedMeta._parsed,n=[],i,o,r;for(i=0,o=e.length;i=0&&tthis.getContext(n,i,e),p=c.resolveNamedOptions(u,f,g,h);return p.$shared&&(p.$shared=l,o[r]=Object.freeze(_a(p,l))),p}_resolveAnimations(t,e,n){let i=this.chart,o=this._cachedDataOpts,r=`animation-${e}`,a=o[r];if(a)return a;let l;if(i.options.animation!==!1){let d=this.chart.config,h=d.datasetAnimationScopeKeys(this._type,e),u=d.getOptionScopes(this.getDataset(),h);l=d.createResolver(u,this.getContext(t,n,e))}let c=new on(i,l&&l.animations);return l&&l._cacheable&&(o[r]=Object.freeze(c)),c}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||bo(t)||this.chart._animationsDisabled}_getSharedOptions(t,e){let n=this.resolveDataElementOptions(t,e),i=this._sharedOptions,o=this.getSharedOptions(n),r=this.includeOptions(e,o)||o!==i;return this.updateSharedOptions(o,e,n),{sharedOptions:o,includeOptions:r}}updateElement(t,e,n,i){bo(i)?Object.assign(t,n):this._resolveAnimations(e,i).update(t,n)}updateSharedOptions(t,e,n){t&&!bo(e)&&this._resolveAnimations(void 0,e).update(t,n)}_setStyle(t,e,n,i){t.active=i;let o=this.getStyle(e,i);this._resolveAnimations(e,n,i).update(t,{options:!i&&this.getSharedOptions(o)||o})}removeHoverStyle(t,e,n){this._setStyle(t,n,"active",!1)}setHoverStyle(t,e,n){this._setStyle(t,n,"active",!0)}_removeDatasetHoverStyle(){let t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){let t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){let e=this._data,n=this._cachedMeta.data;for(let[a,l,c]of this._syncList)this[a](l,c);this._syncList=[];let i=n.length,o=e.length,r=Math.min(o,i);r&&this.parse(0,r),o>i?this._insertElements(i,o-i,t):o{for(c.length+=e,a=c.length-1;a>=r;a--)c[a]=c[a-e]};for(l(o),a=t;ad.controller.options.grouped),o=n.options.stacked,r=[],a=this._cachedMeta.controller.getParsed(e),l=a&&a[n.axis],c=d=>{let h=d._parsed.find(f=>f[n.axis]===l),u=h&&h[d.vScale.axis];if(et(u)||isNaN(u))return!0};for(let d of i)if(!(e!==void 0&&c(d))&&((o===!1||r.indexOf(d.stack)===-1||o===void 0&&d.stack===void 0)&&r.push(d.stack),d.index===t))break;return r.length||r.push(void 0),r}_getStackCount(t){return this._getStacks(void 0,t).length}_getAxisCount(){return this._getAxis().length}getFirstScaleIdForIndexAxis(){let t=this.chart.scales,e=this.chart.options.indexAxis;return Object.keys(t).filter(n=>t[n].axis===e).shift()}_getAxis(){let t={},e=this.getFirstScaleIdForIndexAxis();for(let n of this.chart.data.datasets)t[J(this.chart.options.indexAxis==="x"?n.xAxisID:n.yAxisID,e)]=!0;return Object.keys(t)}_getStackIndex(t,e,n){let i=this._getStacks(t,n),o=e!==void 0?i.indexOf(e):-1;return o===-1?i.length-1:o}_getRuler(){let t=this.options,e=this._cachedMeta,n=e.iScale,i=[],o,r;for(o=0,r=e.data.length;o=0;--n)e=Math.max(e,t[n].size(this.resolveDataElementOptions(n))/2);return e>0&&e}getLabelAndValue(t){let e=this._cachedMeta,n=this.chart.data.labels||[],{xScale:i,yScale:o}=e,r=this.getParsed(t),a=i.getLabelForValue(r.x),l=o.getLabelForValue(r.y),c=r._custom;return{label:n[t]||"",value:"("+a+", "+l+(c?", "+c:"")+")"}}update(t){let e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,n,i){let o=i==="reset",{iScale:r,vScale:a}=this._cachedMeta,{sharedOptions:l,includeOptions:c}=this._getSharedOptions(e,i),d=r.axis,h=a.axis;for(let u=e;u+n[l];if(st(n[t])){let{key:l="value"}=this._parsing;o=c=>+he(n[c],l)}let r,a;for(r=t,a=t+e;r0&&!isNaN(t)?ht*(Math.abs(t)/e):0}getLabelAndValue(t){let e=this._cachedMeta,n=this.chart,i=n.data.labels||[],o=bs(e._parsed[t],n.options.locale);return{label:i[t]||"",value:o}}getMaxBorderWidth(t){let e=0,n=this.chart,i,o,r,a,l;if(!t){for(i=0,o=n.data.datasets.length;it!=="spacing",_indexable:t=>t!=="spacing"&&!t.startsWith("borderDash")&&!t.startsWith("hoverBorderDash")}),K(oe,"overrides",{aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){let e=t.data,{labels:{pointStyle:n,textAlign:i,color:o,useBorderRadius:r,borderRadius:a}}=t.legend.options;return e.labels.length&&e.datasets.length?e.labels.map((l,c)=>{let h=t.getDatasetMeta(0).controller.getStyle(c);return{text:l,fillStyle:h.backgroundColor,fontColor:o,hidden:!t.getDataVisibility(c),lineDash:h.borderDash,lineDashOffset:h.borderDashOffset,lineJoin:h.borderJoinStyle,lineWidth:h.borderWidth,strokeStyle:h.borderColor,textAlign:i,pointStyle:n,borderRadius:r&&(a||h.borderRadius),index:c}}):[]}},onClick(t,e,n){n.chart.toggleDataVisibility(e.index),n.chart.update()}}}});Ye=class extends Rt{initialize(){this.enableOptionSharing=!0,this.supportsDecimation=!0,super.initialize()}update(t){let e=this._cachedMeta,{dataset:n,data:i=[],_dataset:o}=e,r=this.chart._animationsDisabled,{start:a,count:l}=Xi(e,i,r);this._drawStart=a,this._drawCount=l,Qi(e)&&(a=0,l=i.length),n._chart=this.chart,n._datasetIndex=this.index,n._decimated=!!o._decimated,n.points=i;let c=this.resolveDatasetElementOptions(t);this.options.showLine||(c.borderWidth=0),c.segment=this.options.segment,this.updateElement(n,void 0,{animated:!r,options:c},t),this.updateElements(i,a,l,t)}updateElements(t,e,n,i){let o=i==="reset",{iScale:r,vScale:a,_stacked:l,_dataset:c}=this._cachedMeta,{sharedOptions:d,includeOptions:h}=this._getSharedOptions(e,i),u=r.axis,f=a.axis,{spanGaps:g,segment:p}=this.options,b=$e(g)?g:Number.POSITIVE_INFINITY,m=this.chart._animationsDisabled||o||i==="none",v=e+n,_=t.length,k=e>0&&this.getParsed(e-1);for(let S=0;S<_;++S){let x=t[S],y=m?x:{};if(S=v){y.skip=!0;continue}let C=this.getParsed(S),E=et(C[f]),D=y[u]=r.getPixelForValue(C[u],S),w=y[f]=o||E?a.getBasePixel():a.getPixelForValue(l?this.applyStack(a,C,l):C[f],S);y.skip=isNaN(D)||isNaN(w)||E,y.stop=S>0&&Math.abs(C[u]-k[u])>b,p&&(y.parsed=C,y.raw=c.data[S]),h&&(y.options=d||this.resolveDataElementOptions(S,x.active?"active":i)),m||this.updateElement(x,S,y,i),k=C}}getMaxOverflow(){let t=this._cachedMeta,e=t.dataset,n=e.options&&e.options.borderWidth||0,i=t.data||[];if(!i.length)return n;let o=i[0].size(this.resolveDataElementOptions(0)),r=i[i.length-1].size(this.resolveDataElementOptions(i.length-1));return Math.max(n,o,r)/2}draw(){let t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}};K(Ye,"id","line"),K(Ye,"defaults",{datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1}),K(Ye,"overrides",{scales:{_index_:{type:"category"},_value_:{type:"linear"}}});Ae=class extends Rt{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){let e=this._cachedMeta,n=this.chart,i=n.data.labels||[],o=bs(e._parsed[t].r,n.options.locale);return{label:i[t]||"",value:o}}parseObjectData(t,e,n,i){return ro.bind(this)(t,e,n,i)}update(t){let e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}getMinMax(){let t=this._cachedMeta,e={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return t.data.forEach((n,i)=>{let o=this.getParsed(i).r;!isNaN(o)&&this.chart.getDataVisibility(i)&&(oe.max&&(e.max=o))}),e}_updateRadius(){let t=this.chart,e=t.chartArea,n=t.options,i=Math.min(e.right-e.left,e.bottom-e.top),o=Math.max(i/2,0),r=Math.max(n.cutoutPercentage?o/100*n.cutoutPercentage:1,0),a=(o-r)/t.getVisibleDatasetCount();this.outerRadius=o-a*this.index,this.innerRadius=this.outerRadius-a}updateElements(t,e,n,i){let o=i==="reset",r=this.chart,l=r.options.animation,c=this._cachedMeta.rScale,d=c.xCenter,h=c.yCenter,u=c.getIndexAngle(0)-.5*it,f=u,g,p=360/this.countVisibleElements();for(g=0;g{!isNaN(this.getParsed(i).r)&&this.chart.getDataVisibility(i)&&e++}),e}_computeAngle(t,e,n){return this.chart.getDataVisibility(t)?zt(this.resolveDataElementOptions(t,e).angle||n):0}};K(Ae,"id","polarArea"),K(Ae,"defaults",{dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0}),K(Ae,"overrides",{aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){let e=t.data;if(e.labels.length&&e.datasets.length){let{labels:{pointStyle:n,color:i}}=t.legend.options;return e.labels.map((o,r)=>{let l=t.getDatasetMeta(0).controller.getStyle(r);return{text:o,fillStyle:l.backgroundColor,strokeStyle:l.borderColor,fontColor:i,lineWidth:l.borderWidth,pointStyle:n,hidden:!t.getDataVisibility(r),index:r}})}return[]}},onClick(t,e,n){n.chart.toggleDataVisibility(e.index),n.chart.update()}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}});_s=class extends oe{};K(_s,"id","pie"),K(_s,"defaults",{cutout:0,rotation:0,circumference:360,radius:"100%"});Ge=class extends Rt{getLabelAndValue(t){let e=this._cachedMeta.vScale,n=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(n[e.axis])}}parseObjectData(t,e,n,i){return ro.bind(this)(t,e,n,i)}update(t){let e=this._cachedMeta,n=e.dataset,i=e.data||[],o=e.iScale.getLabels();if(n.points=i,t!=="resize"){let r=this.resolveDatasetElementOptions(t);this.options.showLine||(r.borderWidth=0);let a={_loop:!0,_fullLoop:o.length===i.length,options:r};this.updateElement(n,void 0,a,t)}this.updateElements(i,0,i.length,t)}updateElements(t,e,n,i){let o=this._cachedMeta.rScale,r=i==="reset";for(let a=e;a0&&this.getParsed(e-1);for(let k=e;k0&&Math.abs(x[f]-_[f])>m,b&&(y.parsed=x,y.raw=c.data[k]),u&&(y.options=h||this.resolveDataElementOptions(k,S.active?"active":i)),v||this.updateElement(S,k,y,i),_=x}this.updateSharedOptions(h,i,d)}getMaxOverflow(){let t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){let a=0;for(let l=e.length-1;l>=0;--l)a=Math.max(a,e[l].size(this.resolveDataElementOptions(l))/2);return a>0&&a}let n=t.dataset,i=n.options&&n.options.borderWidth||0;if(!e.length)return i;let o=e[0].size(this.resolveDataElementOptions(0)),r=e[e.length-1].size(this.resolveDataElementOptions(e.length-1));return Math.max(i,o,r)/2}};K(Ke,"id","scatter"),K(Ke,"defaults",{datasetElementType:!1,dataElementType:"point",showLine:!1,fill:!1}),K(Ke,"overrides",{interaction:{mode:"point"},scales:{x:{type:"linear"},y:{type:"linear"}}});vl=Object.freeze({__proto__:null,BarController:je,BubbleController:Ue,DoughnutController:oe,LineController:Ye,PieController:_s,PolarAreaController:Ae,RadarController:Ge,ScatterController:Ke});Do=class s{constructor(t){K(this,"options");this.options=t||{}}static override(t){Object.assign(s.prototype,t)}init(){}formats(){return ze()}parse(){return ze()}format(){return ze()}add(){return ze()}diff(){return ze()}startOf(){return ze()}endOf(){return ze()}},yl={_date:Do};xl={evaluateInteractionItems:dn,modes:{index(s,t,e,n){let i=Me(t,s),o=e.axis||"x",r=e.includeInvisible||!1,a=e.intersect?yo(s,i,o,n,r):xo(s,i,o,!1,n,r),l=[];return a.length?(s.getSortedVisibleDatasetMetas().forEach(c=>{let d=a[0].index,h=c.data[d];h&&!h.skip&&l.push({element:h,datasetIndex:c.index,index:d})}),l):[]},dataset(s,t,e,n){let i=Me(t,s),o=e.axis||"xy",r=e.includeInvisible||!1,a=e.intersect?yo(s,i,o,n,r):xo(s,i,o,!1,n,r);if(a.length>0){let l=a[0].datasetIndex,c=s.getDatasetMeta(l).data;a=[];for(let d=0;d{typeof p.beforeLayout=="function"&&p.beforeLayout()});let d=l.reduce((p,b)=>b.box.options&&b.box.options.display===!1?p:p+1,0)||1,h=Object.freeze({outerWidth:t,outerHeight:e,padding:i,availableWidth:o,availableHeight:r,vBoxMaxWidth:o/2/d,hBoxMaxHeight:r/2}),u=Object.assign({},i);_l(u,St(n));let f=Object.assign({maxPadding:u,w:o,h:r,x:i.left,y:i.top},i),g=Xh(l.concat(c),h);en(a.fullSize,f,h,g),en(l,f,h,g),en(c,f,h,g)&&en(l,f,h,g),Jh(f),Ta(a.leftAndTop,f,h,g),f.x+=f.w,f.y+=f.h,Ta(a.rightAndBottom,f,h,g),s.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},lt(a.chartArea,p=>{let b=p.box;Object.assign(b,s.chartArea),b.update(f.w,f.h,{left:0,top:0,right:0,bottom:0})})}},rn=class{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,n){}removeEventListener(t,e,n){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,n,i){return e=Math.max(0,e||t.width),n=n||t.height,{width:e,height:Math.max(0,i?Math.floor(e/i):n)}}isAttached(t){return!0}updateConfig(t){}},si=class extends rn{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}},Jn="$chartjs",eu={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},La=s=>s===null||s==="";Sl=ha?{passive:!0}:!1;an=new Map,Aa=0;ii=class extends rn{acquireContext(t,e){let n=t&&t.getContext&&t.getContext("2d");return n&&n.canvas===t?(su(t,e),n):null}releaseContext(t){let e=t.canvas;if(!e[Jn])return!1;let n=e[Jn].initial;["height","width"].forEach(o=>{let r=n[o];et(r)?e.removeAttribute(o):e.setAttribute(o,r)});let i=n.style||{};return Object.keys(i).forEach(o=>{e.style[o]=i[o]}),e.width=e.width,delete e[Jn],!0}addEventListener(t,e,n){this.removeEventListener(t,e);let i=t.$proxies||(t.$proxies={}),r={attach:ru,detach:au,resize:du}[e]||hu;i[e]=r(t,e,n)}removeEventListener(t,e){let n=t.$proxies||(t.$proxies={}),i=n[e];if(!i)return;({attach:Co,detach:Co,resize:Co}[e]||iu)(t,e,i),n[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,n,i){return da(t,e,n,i)}isAttached(t){let e=t&&Un(t);return!!(e&&e.isConnected)}};Ot=class{constructor(){K(this,"x");K(this,"y");K(this,"active",!1);K(this,"options");K(this,"$animations")}tooltipPosition(t){let{x:e,y:n}=this.getProps(["x","y"],t);return{x:e,y:n}}hasValue(){return $e(this.x)&&$e(this.y)}getProps(t,e){let n=this.$animations;if(!e||!n)return this;let i={};return t.forEach(o=>{i[o]=n[o]&&n[o].active()?n[o]._to:this[o]}),i}};K(Ot,"defaults",{}),K(Ot,"defaultRoutes");vu=s=>s==="left"?"right":s==="right"?"left":s,Ra=(s,t,e)=>t==="top"||t==="left"?s[t]+e:s[t]-e,Pa=(s,t)=>Math.min(t||s,s);Oe=class s extends Ot{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:n,_suggestedMax:i}=this;return t=Lt(t,Number.POSITIVE_INFINITY),e=Lt(e,Number.NEGATIVE_INFINITY),n=Lt(n,Number.POSITIVE_INFINITY),i=Lt(i,Number.NEGATIVE_INFINITY),{min:Lt(t,n),max:Lt(e,i),minDefined:gt(t),maxDefined:gt(e)}}getMinMax(t){let{min:e,max:n,minDefined:i,maxDefined:o}=this.getUserBounds(),r;if(i&&o)return{min:e,max:n};let a=this.getMatchingVisibleMetas();for(let l=0,c=a.length;ln?n:e,n=i&&e>n?e:n,{min:Lt(e,Lt(n,e)),max:Lt(n,Lt(e,n))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){let t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}getLabelItems(t=this.chart.chartArea){return this._labelItems||(this._labelItems=this._computeLabelItems(t))}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){ct(this.options.beforeUpdate,[this])}update(t,e,n){let{beginAtZero:i,grace:o,ticks:r}=this.options,a=r.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=n=Object.assign({left:0,right:0,top:0,bottom:0},n),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+n.left+n.right:this.height+n.top+n.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=ia(this,o,i),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();let l=a=o||n<=1||!this.isHorizontal()){this.labelRotation=i;return}let d=this._getLabelSizes(),h=d.widest.width,u=d.highest.height,f=vt(this.chart.width-h,0,this.maxWidth);a=t.offset?this.maxWidth/n:f/(n-1),h+6>a&&(a=f/(n-(t.offset?.5:1)),l=this.maxHeight-Js(t.grid)-e.padding-Fa(t.title,this.chart.options.font),c=Math.sqrt(h*h+u*u),r=Vn(Math.min(Math.asin(vt((d.highest.height+6)/a,-1,1)),Math.asin(vt(l/c,-1,1))-Math.asin(vt(u/c,-1,1)))),r=Math.max(i,Math.min(o,r))),this.labelRotation=r}afterCalculateLabelRotation(){ct(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){ct(this.options.beforeFit,[this])}fit(){let t={width:0,height:0},{chart:e,options:{ticks:n,title:i,grid:o}}=this,r=this._isVisible(),a=this.isHorizontal();if(r){let l=Fa(i,e.options.font);if(a?(t.width=this.maxWidth,t.height=Js(o)+l):(t.height=this.maxHeight,t.width=Js(o)+l),n.display&&this.ticks.length){let{first:c,last:d,widest:h,highest:u}=this._getLabelSizes(),f=n.padding*2,g=zt(this.labelRotation),p=Math.cos(g),b=Math.sin(g);if(a){let m=n.mirror?0:b*h.width+p*u.height;t.height=Math.min(this.maxHeight,t.height+m+f)}else{let m=n.mirror?0:p*h.width+b*u.height;t.width=Math.min(this.maxWidth,t.width+m+f)}this._calculatePadding(c,d,b,p)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,n,i){let{ticks:{align:o,padding:r},position:a}=this.options,l=this.labelRotation!==0,c=a!=="top"&&this.axis==="x";if(this.isHorizontal()){let d=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1),u=0,f=0;l?c?(u=i*t.width,f=n*e.height):(u=n*t.height,f=i*e.width):o==="start"?f=e.width:o==="end"?u=t.width:o!=="inner"&&(u=t.width/2,f=e.width/2),this.paddingLeft=Math.max((u-d+r)*this.width/(this.width-d),0),this.paddingRight=Math.max((f-h+r)*this.width/(this.width-h),0)}else{let d=e.height/2,h=t.height/2;o==="start"?(d=0,h=t.height):o==="end"&&(d=e.height,h=0),this.paddingTop=d+r,this.paddingBottom=h+r}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){ct(this.options.afterFit,[this])}isHorizontal(){let{axis:t,position:e}=this.options;return e==="top"||e==="bottom"||t==="x"}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){this.beforeTickToLabelConversion(),this.generateTickLabels(t);let e,n;for(e=0,n=t.length;e({width:r[E]||0,height:a[E]||0});return{first:C(0),last:C(e-1),widest:C(x),highest:C(y),widths:r,heights:a}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){let e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);let e=this._startPixel+t*this._length;return Gr(this._alignToPixels?we(this.chart,e,0):e)}getDecimalForPixel(t){let e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){let{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){let e=this.ticks||[];if(t>=0&&ta*i?a/n:l/i:l*i0}_computeGridLineItems(t){let e=this.axis,n=this.chart,i=this.options,{grid:o,position:r,border:a}=i,l=o.offset,c=this.isHorizontal(),h=this.ticks.length+(l?1:0),u=Js(o),f=[],g=a.setContext(this.getContext()),p=g.display?g.width:0,b=p/2,m=function(P){return we(n,P,p)},v,_,k,S,x,y,C,E,D,w,M,L;if(r==="top")v=m(this.bottom),y=this.bottom-u,E=v-b,w=m(t.top)+b,L=t.bottom;else if(r==="bottom")v=m(this.top),w=t.top,L=m(t.bottom)-b,y=v+b,E=this.top+u;else if(r==="left")v=m(this.right),x=this.right-u,C=v-b,D=m(t.left)+b,M=t.right;else if(r==="right")v=m(this.left),D=t.left,M=m(t.right)-b,x=v+b,C=this.left+u;else if(e==="x"){if(r==="center")v=m((t.top+t.bottom)/2+.5);else if(st(r)){let P=Object.keys(r)[0],T=r[P];v=m(this.chart.scales[P].getPixelForValue(T))}w=t.top,L=t.bottom,y=v+b,E=y+u}else if(e==="y"){if(r==="center")v=m((t.left+t.right)/2);else if(st(r)){let P=Object.keys(r)[0],T=r[P];v=m(this.chart.scales[P].getPixelForValue(T))}x=v-b,C=x-u,D=t.left,M=t.right}let O=J(i.ticks.maxTicksLimit,h),V=Math.max(1,Math.ceil(h/O));for(_=0;_0&&(R-=Y/2);break}H={left:R,top:$,width:Y+A.width,height:j+A.height,color:V.backdropColor}}b.push({label:k,font:E,textOffset:M,options:{rotation:p,color:T,strokeColor:U,strokeWidth:F,textAlign:G,textBaseline:L,translation:[S,x],backdrop:H}})}return b}_getXAxisLabelAlignment(){let{position:t,ticks:e}=this.options;if(-zt(this.labelRotation))return t==="top"?"left":"right";let i="center";return e.align==="start"?i="left":e.align==="end"?i="right":e.align==="inner"&&(i="inner"),i}_getYAxisLabelAlignment(t){let{position:e,ticks:{crossAlign:n,mirror:i,padding:o}}=this.options,r=this._getLabelSizes(),a=t+o,l=r.widest.width,c,d;return e==="left"?i?(d=this.right+o,n==="near"?c="left":n==="center"?(c="center",d+=l/2):(c="right",d+=l)):(d=this.right-a,n==="near"?c="right":n==="center"?(c="center",d-=l/2):(c="left",d=this.left)):e==="right"?i?(d=this.left+o,n==="near"?c="right":n==="center"?(c="center",d-=l/2):(c="left",d-=l)):(d=this.left+a,n==="near"?c="left":n==="center"?(c="center",d+=l/2):(c="right",d=this.right)):c="right",{textAlign:c,x:d}}_computeLabelArea(){if(this.options.ticks.mirror)return;let t=this.chart,e=this.options.position;if(e==="left"||e==="right")return{top:0,left:this.left,bottom:t.height,right:this.right};if(e==="top"||e==="bottom")return{top:this.top,left:0,bottom:this.bottom,right:t.width}}drawBackground(){let{ctx:t,options:{backgroundColor:e},left:n,top:i,width:o,height:r}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(n,i,o,r),t.restore())}getLineWidthForValue(t){let e=this.options.grid;if(!this._isVisible()||!e.display)return 0;let i=this.ticks.findIndex(o=>o.value===t);return i>=0?e.setContext(this.getContext(i)).lineWidth:0}drawGrid(t){let e=this.options.grid,n=this.ctx,i=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t)),o,r,a=(l,c,d)=>{!d.width||!d.color||(n.save(),n.lineWidth=d.width,n.strokeStyle=d.color,n.setLineDash(d.borderDash||[]),n.lineDashOffset=d.borderDashOffset,n.beginPath(),n.moveTo(l.x,l.y),n.lineTo(c.x,c.y),n.stroke(),n.restore())};if(e.display)for(o=0,r=i.length;o{this.draw(o)}}]:[{z:n,draw:o=>{this.drawBackground(),this.drawGrid(o),this.drawTitle()}},{z:i,draw:()=>{this.drawBorder()}},{z:e,draw:o=>{this.drawLabels(o)}}]}getMatchingVisibleMetas(t){let e=this.chart.getSortedVisibleDatasetMetas(),n=this.axis+"AxisID",i=[],o,r;for(o=0,r=e.length;o{let o=n||this._getRegistryForType(i);n||o.isForType(i)||o===this.plugins&&i.id?this._exec(t,o,i):lt(i,r=>{let a=n||this._getRegistryForType(r);this._exec(t,a,r)})})}_exec(t,e,n){let i=In(t);ct(n["before"+i],[],n),e[t](n),ct(n["after"+i],[],n)}_getRegistryForType(t){for(let e=0;eo.filter(a=>!r.some(l=>a.plugin.id===l.plugin.id));this._notify(i(e,n),t,"stop"),this._notify(i(n,e),t,"start")}};Na=new Map,Ml=new Set;tn=(s,t,e)=>{let n=he(t,e);n!==void 0&&s.add(n)},Ro=class{constructor(t){this._config=Vu(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Dl(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){let t=this._config;this.clearCache(),El(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return qn(t,()=>[[`datasets.${t}`,""]])}datasetAnimationScopeKeys(t,e){return qn(`${t}.transition.${e}`,()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]])}datasetElementScopeKeys(t,e){return qn(`${t}-${e}`,()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]])}pluginScopeKeys(t){let e=t.id,n=this.type;return qn(`${n}-plugin-${e}`,()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]])}_cachedScopes(t,e){let n=this._scopeCache,i=n.get(t);return(!i||e)&&(i=new Map,n.set(t,i)),i}getOptionScopes(t,e,n){let{options:i,type:o}=this,r=this._cachedScopes(t,n),a=r.get(e);if(a)return a;let l=new Set;e.forEach(d=>{t&&(l.add(t),d.forEach(h=>tn(l,t,h))),d.forEach(h=>tn(l,i,h)),d.forEach(h=>tn(l,ke[o]||{},h)),d.forEach(h=>tn(l,ut,h)),d.forEach(h=>tn(l,$n,h))});let c=Array.from(l);return c.length===0&&c.push(Object.create(null)),Ml.has(e)&&r.set(e,c),c}chartOptionScopes(){let{options:t,type:e}=this;return[t,ke[e]||{},ut.datasets[e]||{},{type:e},ut,$n]}resolveNamedOptions(t,e,n,i=[""]){let o={$shared:!0},{resolver:r,subPrefixes:a}=Ba(this._resolverCache,t,i),l=r;if(Bu(r,e)){o.$shared=!1,n=ce(n)?n():n;let c=this.createResolver(t,n,a);l=Be(r,n,c)}for(let c of e)o[c]=l[c];return o}createResolver(t,e,n=[""],i){let{resolver:o}=Ba(this._resolverCache,t,n);return st(e)?Be(o,e,void 0,i):o}};Nu=s=>st(s)&&Object.getOwnPropertyNames(s).some(t=>ce(s[t]));$u="4.5.1",Hu=["top","bottom","left","right","chartArea"];ti={},Wa=s=>{let t=Tl(s);return Object.values(ti).filter(e=>e.canvas===t).pop()};ie=class{static register(...t){Yt.add(...t),ja()}static unregister(...t){Yt.remove(...t),ja()}constructor(t,e){let n=this.config=new Ro(e),i=Tl(t),o=Wa(i);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas with ID '"+o.canvas.id+"' can be reused.");let r=n.createResolver(n.chartOptionScopes(),this.getContext());this.platform=new(n.platform||wl(i)),this.platform.updateConfig(n);let a=this.platform.acquireContext(i,r.aspectRatio),l=a&&a.canvas,c=l&&l.height,d=l&&l.width;if(this.id=Hr(),this.ctx=a,this.canvas=l,this.width=d,this.height=c,this._options=r,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new To,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=Zr(h=>this.update(h),r.resizeDelay||0),this._dataChanges=[],ti[this.id]=this,!a||!l){console.error("Failed to create chart: can't acquire context from the given item");return}ne.listen(this,"complete",za),ne.listen(this,"progress",zu),this._initialize(),this.attached&&this.update()}get aspectRatio(){let{options:{aspectRatio:t,maintainAspectRatio:e},width:n,height:i,_aspectRatio:o}=this;return et(t)?e&&o?o:i?n/i:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}get registry(){return Yt}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():ao(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return to(this.canvas,this.ctx),this}stop(){return ne.stop(this),this}resize(t,e){ne.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){let n=this.options,i=this.canvas,o=n.maintainAspectRatio&&this.aspectRatio,r=this.platform.getMaximumSize(i,t,e,o),a=n.devicePixelRatio||this.platform.getDevicePixelRatio(),l=this.width?"resize":"attach";this.width=r.width,this.height=r.height,this._aspectRatio=this.aspectRatio,ao(this,a,!0)&&(this.notifyPlugins("resize",{size:r}),ct(n.onResize,[this,r],this),this.attached&&this._doResize(l)&&this.render())}ensureScalesHaveIDs(){let e=this.options.scales||{};lt(e,(n,i)=>{n.id=i})}buildOrUpdateScales(){let t=this.options,e=t.scales,n=this.scales,i=Object.keys(n).reduce((r,a)=>(r[a]=!1,r),{}),o=[];e&&(o=o.concat(Object.keys(e).map(r=>{let a=e[r],l=Ao(r,a),c=l==="r",d=l==="x";return{options:a,dposition:c?"chartArea":d?"bottom":"left",dtype:c?"radialLinear":d?"category":"linear"}}))),lt(o,r=>{let a=r.options,l=a.id,c=Ao(l,a),d=J(a.type,r.dtype);(a.position===void 0||$a(a.position,c)!==$a(r.dposition))&&(a.position=r.dposition),i[l]=!0;let h=null;if(l in n&&n[l].type===d)h=n[l];else{let u=Yt.getScale(d);h=new u({id:l,type:d,ctx:this.ctx,chart:this}),n[h.id]=h}h.init(a,t)}),lt(i,(r,a)=>{r||delete n[a]}),lt(n,r=>{kt.configure(this,r,r.options),kt.addBox(this,r)})}_updateMetasets(){let t=this._metasets,e=this.data.datasets.length,n=t.length;if(t.sort((i,o)=>i.index-o.index),n>e){for(let i=e;ie.length&&delete this._stacks,t.forEach((n,i)=>{e.filter(o=>o===n._dataset).length===0&&this._destroyDatasetMeta(i)})}buildOrUpdateControllers(){let t=[],e=this.data.datasets,n,i;for(this._removeUnreferencedMetasets(),n=0,i=e.length;n{this.getDatasetMeta(e).controller.reset()},this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){let e=this.config;e.update();let n=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),i=this._animationsDisabled=!n.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0})===!1)return;let o=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let r=0;for(let c=0,d=this.data.datasets.length;c{c.reset()}),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(Ha("z","_idx"));let{_active:a,_lastEvent:l}=this;l?this._eventHandler(l,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){lt(this.scales,t=>{kt.removeBox(this,t)}),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){let t=this.options,e=new Set(Object.keys(this._listeners)),n=new Set(t.events);(!Hi(e,n)||!!this._responsiveListeners!==t.responsive)&&(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){let{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(let{method:n,start:i,count:o}of e){let r=n==="_removeElements"?-o:o;Wu(t,i,r)}}_getUniformDataChanges(){let t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];let e=this.data.datasets.length,n=o=>new Set(t.filter(r=>r[0]===o).map((r,a)=>a+","+r.splice(1).join(","))),i=n(0);for(let o=1;oo.split(",")).map(o=>({method:o[1],start:+o[2],count:+o[3]}))}_updateLayout(t){if(this.notifyPlugins("beforeLayout",{cancelable:!0})===!1)return;kt.update(this,this.width,this.height,t);let e=this.chartArea,n=e.width<=0||e.height<=0;this._layers=[],lt(this.boxes,i=>{n&&i.position==="chartArea"||(i.configure&&i.configure(),this._layers.push(...i._layers()))},this),this._layers.forEach((i,o)=>{i._idx=o}),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})!==!1){for(let e=0,n=this.data.datasets.length;e=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){let e=this.ctx,n={meta:t,index:t.index,cancelable:!0},i=go(this,t);this.notifyPlugins("beforeDatasetDraw",n)!==!1&&(i&&Ks(e,i),t.controller.draw(),i&&qs(e),n.cancelable=!1,this.notifyPlugins("afterDatasetDraw",n))}isPointInArea(t){return Jt(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,n,i){let o=xl.modes[e];return typeof o=="function"?o(this,t,n,i):[]}getDatasetMeta(t){let e=this.data.datasets[t],n=this._metasets,i=n.filter(o=>o&&o._dataset===e).pop();return i||(i={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},n.push(i)),i}getContext(){return this.$context||(this.$context=ue(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){let e=this.data.datasets[t];if(!e)return!1;let n=this.getDatasetMeta(t);return typeof n.hidden=="boolean"?!n.hidden:!e.hidden}setDatasetVisibility(t,e){let n=this.getDatasetMeta(t);n.hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,n){let i=n?"show":"hide",o=this.getDatasetMeta(t),r=o.controller._resolveAnimations(void 0,i);gs(e)?(o.data[e].hidden=!n,this.update()):(this.setDatasetVisibility(t,n),r.update(o,{visible:n}),this.update(a=>a.datasetIndex===t?i:void 0))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){let e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),ne.remove(this),t=0,e=this.data.datasets.length;t{e.addEventListener(this,o,r),t[o]=r},i=(o,r,a)=>{o.offsetX=r,o.offsetY=a,this._eventHandler(o)};lt(this.options.events,o=>n(o,i))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});let t=this._responsiveListeners,e=this.platform,n=(l,c)=>{e.addEventListener(this,l,c),t[l]=c},i=(l,c)=>{t[l]&&(e.removeEventListener(this,l,c),delete t[l])},o=(l,c)=>{this.canvas&&this.resize(l,c)},r,a=()=>{i("attach",a),this.attached=!0,this.resize(),n("resize",o),n("detach",r)};r=()=>{this.attached=!1,i("resize",o),this._stop(),this._resize(0,0),n("attach",a)},e.isAttached(this.canvas)?a():r()}unbindEvents(){lt(this._listeners,(t,e)=>{this.platform.removeEventListener(this,e,t)}),this._listeners={},lt(this._responsiveListeners,(t,e)=>{this.platform.removeEventListener(this,e,t)}),this._responsiveListeners=void 0}updateHoverStyle(t,e,n){let i=n?"set":"remove",o,r,a,l;for(e==="dataset"&&(o=this.getDatasetMeta(t[0].datasetIndex),o.controller["_"+i+"DatasetHoverStyle"]()),a=0,l=t.length;a{let a=this.getDatasetMeta(o);if(!a)throw new Error("No dataset found at index "+o);return{datasetIndex:o,element:a.data[r],index:r}});!Gs(n,e)&&(this._active=n,this._lastEvent=null,this._updateHoverStyles(n,e))}notifyPlugins(t,e,n){return this._plugins.notify(this,t,e,n)}isPluginEnabled(t){return this._plugins._cache.filter(e=>e.plugin.id===t).length===1}_updateHoverStyles(t,e,n){let i=this.options.hover,o=(l,c)=>l.filter(d=>!c.some(h=>d.datasetIndex===h.datasetIndex&&d.index===h.index)),r=o(e,t),a=n?t:o(t,e);r.length&&this.updateHoverStyle(r,i.mode,!1),a.length&&i.mode&&this.updateHoverStyle(a,i.mode,!0)}_eventHandler(t,e){let n={event:t,replay:e,cancelable:!0,inChartArea:this.isPointInArea(t)},i=r=>(r.options.events||this.options.events).includes(t.native.type);if(this.notifyPlugins("beforeEvent",n,i)===!1)return;let o=this._handleEvent(t,e,n.inChartArea);return n.cancelable=!1,this.notifyPlugins("afterEvent",n,i),(o||n.changed)&&this.render(),this}_handleEvent(t,e,n){let{_active:i=[],options:o}=this,r=e,a=this._getActiveElements(t,i,n,r),l=jr(t),c=ju(t,this._lastEvent,n,l);n&&(this._lastEvent=null,ct(o.onHover,[t,a,this],this),l&&ct(o.onClick,[t,a,this],this));let d=!Gs(a,i);return(d||e)&&(this._active=a,this._updateHoverStyles(a,i,e)),this._lastEvent=c,d}_getActiveElements(t,e,n,i){if(t.type==="mouseout")return[];if(!n)return e;let o=this.options.hover;return this.getElementsAtEventForMode(t,o.mode,o,i)}};K(ie,"defaults",ut),K(ie,"instances",ti),K(ie,"overrides",ke),K(ie,"registry",Yt),K(ie,"version",$u),K(ie,"getChart",Wa);Te=class extends Ot{constructor(e){super();K(this,"circumference");K(this,"endAngle");K(this,"fullCircles");K(this,"innerRadius");K(this,"outerRadius");K(this,"pixelMargin");K(this,"startAngle");this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,e&&Object.assign(this,e)}inRange(e,n,i){let o=this.getProps(["x","y"],i),{angle:r,distance:a}=Ui(o,{x:e,y:n}),{startAngle:l,endAngle:c,innerRadius:d,outerRadius:h,circumference:u}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],i),f=(this.options.spacing+this.options.borderWidth)/2,g=J(u,c-l),p=ms(r,l,c)&&l!==c,b=g>=ht||p,m=ee(a,d+f,h+f);return b&&m}getCenterPoint(e){let{x:n,y:i,startAngle:o,endAngle:r,innerRadius:a,outerRadius:l}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius"],e),{offset:c,spacing:d}=this.options,h=(o+r)/2,u=(a+l+d+c)/2;return{x:n+Math.cos(h)*u,y:i+Math.sin(h)*u}}tooltipPosition(e){return this.getCenterPoint(e)}draw(e){let{options:n,circumference:i}=this,o=(n.offset||0)/4,r=(n.spacing||0)/2,a=n.circular;if(this.pixelMargin=n.borderAlign==="inner"?.33:0,this.fullCircles=i>ht?Math.floor(i/ht):0,i===0||this.innerRadius<0||this.outerRadius<0)return;e.save();let l=(this.startAngle+this.endAngle)/2;e.translate(Math.cos(l)*o,Math.sin(l)*o);let c=1-Math.sin(Math.min(it,i||0)),d=o*c;e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,qu(e,this,d,r,a),Xu(e,this,d,r,a),e.restore()}};K(Te,"id","arc"),K(Te,"defaults",{borderAlign:"center",borderColor:"#fff",borderDash:[],borderDashOffset:0,borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0,circular:!0,selfJoin:!1}),K(Te,"defaultRoutes",{backgroundColor:"backgroundColor"}),K(Te,"descriptors",{_scriptable:!0,_indexable:e=>e!=="borderDash"});of=typeof Path2D=="function";Gt=class extends Ot{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){let n=this.options;if((n.tension||n.cubicInterpolationMode==="monotone")&&!n.stepped&&!this._pointsUpdated){let i=n.spanGaps?this._loop:this._fullLoop;ca(this._points,n,t,i,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=pa(this,this.options.segment))}first(){let t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){let t=this.segments,e=this.points,n=t.length;return n&&e[t[n-1].end]}interpolate(t,e){let n=this.options,i=t[e],o=this.points,r=fo(this,{property:e,start:i,end:i});if(!r.length)return;let a=[],l=ef(n),c,d;for(c=0,d=r.length;ct!=="borderDash"&&t!=="fill"});qe=class extends Ot{constructor(e){super();K(this,"parsed");K(this,"skip");K(this,"stop");this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,e&&Object.assign(this,e)}inRange(e,n,i){let o=this.options,{x:r,y:a}=this.getProps(["x","y"],i);return Math.pow(e-r,2)+Math.pow(n-a,2)s.replace("rgb(","rgba(").replace(")",", 0.5)"));Il={id:"colors",defaults:{enabled:!0,forceOverride:!1},beforeLayout(s,t,e){if(!e.enabled)return;let{data:{datasets:n},options:i}=s.config,{elements:o}=i,r=Ga(n)||mf(i)||o&&Ga(o)||bf();if(!e.forceOverride&&r)return;let a=pf(s);n.forEach(a)}};Nl={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(s,t,e)=>{if(!e.enabled){Ka(s);return}let n=s.width;s.data.datasets.forEach((i,o)=>{let{_data:r,indexAxis:a}=i,l=s.getDatasetMeta(o),c=r||i.data;if(xs([a,s.options.indexAxis])==="y"||!l.controller.supportsDecimation)return;let d=s.scales[l.xAxisID];if(d.type!=="linear"&&d.type!=="time"||s.options.parsing)return;let{start:h,count:u}=xf(l,c),f=e.threshold||4*n;if(u<=f){Vl(i);return}et(r)&&(i._data=c,delete i.data,Object.defineProperty(i,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(p){this._data=p}}));let g;switch(e.algorithm){case"lttb":g=vf(c,h,u,n,e);break;case"min-max":g=yf(c,h,u,n);break;default:throw new Error(`Unsupported decimation algorithm '${e.algorithm}'`)}i._decimated=g})},destroy(s){Ka(s)}};ri=class{constructor(t){this.x=t.x,this.y=t.y,this.radius=t.radius}pathSegment(t,e,n){let{x:i,y:o,radius:r}=this;return e=e||{start:0,end:ht},t.arc(i,o,r,e.end,e.start,!0),!n.bounds}interpolate(t){let{x:e,y:n,radius:i}=this,o=t.angle;return{x:e+Math.cos(o)*i,y:n+Math.sin(o)*i,angle:o}}};$l={id:"filler",afterDatasetsUpdate(s,t,e){let n=(s.data.datasets||[]).length,i=[],o,r,a,l;for(r=0;r=0;--r){let a=i[r].$filler;a&&(a.line.updateControlPoints(o,a.axis),n&&a.fill&&ko(s.ctx,a,o))}},beforeDatasetsDraw(s,t,e){if(e.drawTime!=="beforeDatasetsDraw")return;let n=s.getSortedVisibleDatasetMetas();for(let i=n.length-1;i>=0;--i){let o=n[i].$filler;Xa(o)&&ko(s.ctx,o,s.chartArea)}},beforeDatasetDraw(s,t,e){let n=t.meta.$filler;!Xa(n)||e.drawTime!=="beforeDatasetDraw"||ko(s.ctx,n,s.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}},tl=(s,t)=>{let{boxHeight:e=t,boxWidth:n=t}=s;return s.usePointStyle&&(e=Math.min(e,t),n=s.pointStyleWidth||Math.min(n,t)),{boxWidth:n,boxHeight:e,itemHeight:Math.max(t,e)}},$f=(s,t)=>s!==null&&t!==null&&s.datasetIndex===t.datasetIndex&&s.index===t.index,ai=class extends Ot{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,n){this.maxWidth=t,this.maxHeight=e,this._margins=n,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){let t=this.options.labels||{},e=ct(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter(n=>t.filter(n,this.chart.data))),t.sort&&(e=e.sort((n,i)=>t.sort(n,i,this.chart.data))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){let{options:t,ctx:e}=this;if(!t.display){this.width=this.height=0;return}let n=t.labels,i=bt(n.font),o=i.size,r=this._computeTitleHeight(),{boxWidth:a,itemHeight:l}=tl(n,o),c,d;e.font=i.string,this.isHorizontal()?(c=this.maxWidth,d=this._fitRows(r,o,a,l)+10):(d=this.maxHeight,c=this._fitCols(r,i,a,l)+10),this.width=Math.min(c,t.maxWidth||this.maxWidth),this.height=Math.min(d,t.maxHeight||this.maxHeight)}_fitRows(t,e,n,i){let{ctx:o,maxWidth:r,options:{labels:{padding:a}}}=this,l=this.legendHitBoxes=[],c=this.lineWidths=[0],d=i+a,h=t;o.textAlign="left",o.textBaseline="middle";let u=-1,f=-d;return this.legendItems.forEach((g,p)=>{let b=n+e/2+o.measureText(g.text).width;(p===0||c[c.length-1]+b+2*a>r)&&(h+=d,c[c.length-(p>0?0:1)]=0,f+=d,u++),l[p]={left:0,top:f,row:u,width:b,height:i},c[c.length-1]+=b+a}),h}_fitCols(t,e,n,i){let{ctx:o,maxHeight:r,options:{labels:{padding:a}}}=this,l=this.legendHitBoxes=[],c=this.columnSizes=[],d=r-t,h=a,u=0,f=0,g=0,p=0;return this.legendItems.forEach((b,m)=>{let{itemWidth:v,itemHeight:_}=Hf(n,e,o,b,i);m>0&&f+_+2*a>d&&(h+=u+a,c.push({width:u,height:f}),g+=u+a,p++,u=f=0),l[m]={left:g,top:f,col:p,width:v,height:_},u=Math.max(u,v),f+=_+a}),h+=u,c.push({width:u,height:f}),h}adjustHitBoxes(){if(!this.options.display)return;let t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:n,labels:{padding:i},rtl:o}}=this,r=He(o,this.left,this.width);if(this.isHorizontal()){let a=0,l=_t(n,this.left+i,this.right-this.lineWidths[a]);for(let c of e)a!==c.row&&(a=c.row,l=_t(n,this.left+i,this.right-this.lineWidths[a])),c.top+=this.top+t+i,c.left=r.leftForLtr(r.x(l),c.width),l+=c.width+i}else{let a=0,l=_t(n,this.top+t+i,this.bottom-this.columnSizes[a].height);for(let c of e)c.col!==a&&(a=c.col,l=_t(n,this.top+t+i,this.bottom-this.columnSizes[a].height)),c.top=l,c.left+=this.left+i,c.left=r.leftForLtr(r.x(c.left),c.width),l+=c.height+i}}isHorizontal(){return this.options.position==="top"||this.options.position==="bottom"}draw(){if(this.options.display){let t=this.ctx;Ks(t,this),this._draw(),qs(t)}}_draw(){let{options:t,columnSizes:e,lineWidths:n,ctx:i}=this,{align:o,labels:r}=t,a=ut.color,l=He(t.rtl,this.left,this.width),c=bt(r.font),{padding:d}=r,h=c.size,u=h/2,f;this.drawTitle(),i.textAlign=l.textAlign("left"),i.textBaseline="middle",i.lineWidth=.5,i.font=c.string;let{boxWidth:g,boxHeight:p,itemHeight:b}=tl(r,h),m=function(x,y,C){if(isNaN(g)||g<=0||isNaN(p)||p<0)return;i.save();let E=J(C.lineWidth,1);if(i.fillStyle=J(C.fillStyle,a),i.lineCap=J(C.lineCap,"butt"),i.lineDashOffset=J(C.lineDashOffset,0),i.lineJoin=J(C.lineJoin,"miter"),i.lineWidth=E,i.strokeStyle=J(C.strokeStyle,a),i.setLineDash(J(C.lineDash,[])),r.usePointStyle){let D={radius:p*Math.SQRT2/2,pointStyle:C.pointStyle,rotation:C.rotation,borderWidth:E},w=l.xPlus(x,g/2),M=y+u;eo(i,D,w,M,r.pointStyleWidth&&g)}else{let D=y+Math.max((h-p)/2,0),w=l.leftForLtr(x,g),M=De(C.borderRadius);i.beginPath(),Object.values(M).some(L=>L!==0)?ys(i,{x:w,y:D,w:g,h:p,radius:M}):i.rect(w,D,g,p),i.fill(),E!==0&&i.stroke()}i.restore()},v=function(x,y,C){Ee(i,C.text,x,y+b/2,c,{strikethrough:C.hidden,textAlign:l.textAlign(C.textAlign)})},_=this.isHorizontal(),k=this._computeTitleHeight();_?f={x:_t(o,this.left+d,this.right-n[0]),y:this.top+d+k,line:0}:f={x:this.left+d,y:_t(o,this.top+k+d,this.bottom-e[0].height),line:0},co(this.ctx,t.textDirection);let S=b+d;this.legendItems.forEach((x,y)=>{i.strokeStyle=x.fontColor,i.fillStyle=x.fontColor;let C=i.measureText(x.text).width,E=l.textAlign(x.textAlign||(x.textAlign=r.textAlign)),D=g+u+C,w=f.x,M=f.y;l.setWidth(this.width),_?y>0&&w+D+d>this.right&&(M=f.y+=S,f.line++,w=f.x=_t(o,this.left+d,this.right-n[f.line])):y>0&&M+S>this.bottom&&(w=f.x=w+e[f.line].width+d,f.line++,M=f.y=_t(o,this.top+k+d,this.bottom-e[f.line].height));let L=l.x(w);if(m(L,M,x),w=Jr(E,w+g+u,_?w+D:this.right,t.rtl),v(l.x(w),M,x),_)f.x+=D+d;else if(typeof x.text!="string"){let O=c.lineHeight;f.y+=Hl(x,O)+d}else f.y+=S}),ho(this.ctx,t.textDirection)}drawTitle(){let t=this.options,e=t.title,n=bt(e.font),i=St(e.padding);if(!e.display)return;let o=He(t.rtl,this.left,this.width),r=this.ctx,a=e.position,l=n.size/2,c=i.top+l,d,h=this.left,u=this.width;if(this.isHorizontal())u=Math.max(...this.lineWidths),d=this.top+c,h=_t(t.align,h,this.right-u);else{let g=this.columnSizes.reduce((p,b)=>Math.max(p,b.height),0);d=c+_t(t.align,this.top,this.bottom-g-t.labels.padding-this._computeTitleHeight())}let f=_t(a,h,h+u);r.textAlign=o.textAlign(Bn(a)),r.textBaseline="middle",r.strokeStyle=e.color,r.fillStyle=e.color,r.font=n.string,Ee(r,e.text,f,d,n)}_computeTitleHeight(){let t=this.options.title,e=bt(t.font),n=St(t.padding);return t.display?e.lineHeight+n.height:0}_getLegendItemAt(t,e){let n,i,o;if(ee(t,this.left,this.right)&&ee(e,this.top,this.bottom)){for(o=this.legendHitBoxes,n=0;ns.chart.options.color,boxWidth:40,padding:10,generateLabels(s){let t=s.data.datasets,{labels:{usePointStyle:e,pointStyle:n,textAlign:i,color:o,useBorderRadius:r,borderRadius:a}}=s.legend.options;return s._getSortedDatasetMetas().map(l=>{let c=l.controller.getStyle(e?0:void 0),d=St(c.borderWidth);return{text:t[l.index].label,fillStyle:c.backgroundColor,fontColor:o,hidden:!l.visible,lineCap:c.borderCapStyle,lineDash:c.borderDash,lineDashOffset:c.borderDashOffset,lineJoin:c.borderJoinStyle,lineWidth:(d.width+d.height)/4,strokeStyle:c.borderColor,pointStyle:n||c.pointStyle,rotation:c.rotation,textAlign:i||c.textAlign,borderRadius:r&&(a||c.borderRadius),datasetIndex:l.index}},this)}},title:{color:s=>s.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:s=>!s.startsWith("on"),labels:{_scriptable:s=>!["generateLabels","filter","sort"].includes(s)}}},ln=class extends Ot{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){let n=this.options;if(this.left=0,this.top=0,!n.display){this.width=this.height=this.right=this.bottom=0;return}this.width=this.right=t,this.height=this.bottom=e;let i=dt(n.text)?n.text.length:1;this._padding=St(n.padding);let o=i*bt(n.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=o:this.width=o}isHorizontal(){let t=this.options.position;return t==="top"||t==="bottom"}_drawArgs(t){let{top:e,left:n,bottom:i,right:o,options:r}=this,a=r.align,l=0,c,d,h;return this.isHorizontal()?(d=_t(a,n,o),h=e+t,c=o-n):(r.position==="left"?(d=n+t,h=_t(a,i,e),l=it*-.5):(d=o-t,h=_t(a,e,i),l=it*.5),c=i-e),{titleX:d,titleY:h,maxWidth:c,rotation:l}}draw(){let t=this.ctx,e=this.options;if(!e.display)return;let n=bt(e.font),o=n.lineHeight/2+this._padding.top,{titleX:r,titleY:a,maxWidth:l,rotation:c}=this._drawArgs(o);Ee(t,e.text,0,0,n,{color:e.color,maxWidth:l,rotation:c,textAlign:Bn(e.align),textBaseline:"middle",translation:[r,a]})}};Wl={id:"title",_element:ln,start(s,t,e){Uf(s,e)},stop(s){let t=s.titleBlock;kt.removeBox(s,t),delete s.titleBlock},beforeUpdate(s,t,e){let n=s.titleBlock;kt.configure(s,n,e),n.options=e},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}},Xn=new WeakMap,jl={id:"subtitle",start(s,t,e){let n=new ln({ctx:s.ctx,options:e,chart:s});kt.configure(s,n,e),kt.addBox(s,n),Xn.set(s,n)},stop(s){kt.removeBox(s,Xn.get(s)),Xn.delete(s)},beforeUpdate(s,t,e){let n=Xn.get(s);kt.configure(s,n,e),n.options=e},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}},sn={average(s){if(!s.length)return!1;let t,e,n=new Set,i=0,o=0;for(t=0,e=s.length;ta+l)/n.size,y:i/o}},nearest(s,t){if(!s.length)return!1;let e=t.x,n=t.y,i=Number.POSITIVE_INFINITY,o,r,a;for(o=0,r=s.length;o0){let t=s[0],e=t.chart.data.labels,n=e?e.length:0;if(this&&this.options&&this.options.mode==="dataset")return t.dataset.label||"";if(t.label)return t.label;if(n>0&&t.dataIndex{let r={before:[],lines:[],after:[]},a=ol(n,o);se(r.before,fe(At(a,"beforeLabel",this,o))),se(r.lines,At(a,"label",this,o)),se(r.after,fe(At(a,"afterLabel",this,o))),i.push(r)}),i}getAfterBody(t,e){return il(At(e.callbacks,"afterBody",this,t))}getFooter(t,e){let{callbacks:n}=e,i=At(n,"beforeFooter",this,t),o=At(n,"footer",this,t),r=At(n,"afterFooter",this,t),a=[];return a=se(a,fe(i)),a=se(a,fe(o)),a=se(a,fe(r)),a}_createItems(t){let e=this._active,n=this.chart.data,i=[],o=[],r=[],a=[],l,c;for(l=0,c=e.length;lt.filter(d,h,u,n))),t.itemSort&&(a=a.sort((d,h)=>t.itemSort(d,h,n))),lt(a,d=>{let h=ol(t.callbacks,d);i.push(At(h,"labelColor",this,d)),o.push(At(h,"labelPointStyle",this,d)),r.push(At(h,"labelTextColor",this,d))}),this.labelColors=i,this.labelPointStyles=o,this.labelTextColors=r,this.dataPoints=a,a}update(t,e){let n=this.options.setContext(this.getContext()),i=this._active,o,r=[];if(!i.length)this.opacity!==0&&(o={opacity:0});else{let a=sn[n.position].call(this,i,this._eventPosition);r=this._createItems(n),this.title=this.getTitle(r,n),this.beforeBody=this.getBeforeBody(r,n),this.body=this.getBody(r,n),this.afterBody=this.getAfterBody(r,n),this.footer=this.getFooter(r,n);let l=this._size=el(this,n),c=Object.assign({},a,l),d=sl(this.chart,n,c),h=nl(n,c,d,this.chart);this.xAlign=d.xAlign,this.yAlign=d.yAlign,o={opacity:1,x:h.x,y:h.y,width:l.width,height:l.height,caretX:a.x,caretY:a.y}}this._tooltipItems=r,this.$context=void 0,o&&this._resolveAnimations().update(this,o),t&&n.external&&n.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,n,i){let o=this.getCaretPosition(t,n,i);e.lineTo(o.x1,o.y1),e.lineTo(o.x2,o.y2),e.lineTo(o.x3,o.y3)}getCaretPosition(t,e,n){let{xAlign:i,yAlign:o}=this,{caretSize:r,cornerRadius:a}=n,{topLeft:l,topRight:c,bottomLeft:d,bottomRight:h}=De(a),{x:u,y:f}=t,{width:g,height:p}=e,b,m,v,_,k,S;return o==="center"?(k=f+p/2,i==="left"?(b=u,m=b-r,_=k+r,S=k-r):(b=u+g,m=b+r,_=k-r,S=k+r),v=b):(i==="left"?m=u+Math.max(l,d)+r:i==="right"?m=u+g-Math.max(c,h)-r:m=this.caretX,o==="top"?(_=f,k=_-r,b=m-r,v=m+r):(_=f+p,k=_+r,b=m+r,v=m-r),S=_),{x1:b,x2:m,x3:v,y1:_,y2:k,y3:S}}drawTitle(t,e,n){let i=this.title,o=i.length,r,a,l;if(o){let c=He(n.rtl,this.x,this.width);for(t.x=Qn(this,n.titleAlign,n),e.textAlign=c.textAlign(n.titleAlign),e.textBaseline="middle",r=bt(n.titleFont),a=n.titleSpacing,e.fillStyle=n.titleColor,e.font=r.string,l=0;lv!==0)?(t.beginPath(),t.fillStyle=o.multiKeyBackground,ys(t,{x:p,y:g,w:c,h:l,radius:m}),t.fill(),t.stroke(),t.fillStyle=r.backgroundColor,t.beginPath(),ys(t,{x:b,y:g+1,w:c-2,h:l-2,radius:m}),t.fill()):(t.fillStyle=o.multiKeyBackground,t.fillRect(p,g,c,l),t.strokeRect(p,g,c,l),t.fillStyle=r.backgroundColor,t.fillRect(b,g+1,c-2,l-2))}t.fillStyle=this.labelTextColors[n]}drawBody(t,e,n){let{body:i}=this,{bodySpacing:o,bodyAlign:r,displayColors:a,boxHeight:l,boxWidth:c,boxPadding:d}=n,h=bt(n.bodyFont),u=h.lineHeight,f=0,g=He(n.rtl,this.x,this.width),p=function(C){e.fillText(C,g.x(t.x+f),t.y+u/2),t.y+=u+o},b=g.textAlign(r),m,v,_,k,S,x,y;for(e.textAlign=r,e.textBaseline="middle",e.font=h.string,t.x=Qn(this,b,n),e.fillStyle=n.bodyColor,lt(this.beforeBody,p),f=a&&b!=="right"?r==="center"?c/2+d:c+2+d:0,k=0,x=i.length;k0&&e.stroke()}_updateAnimationTarget(t){let e=this.chart,n=this.$animations,i=n&&n.x,o=n&&n.y;if(i||o){let r=sn[t.position].call(this,this._active,this._eventPosition);if(!r)return;let a=this._size=el(this,t),l=Object.assign({},r,this._size),c=sl(e,t,l),d=nl(t,l,c,e);(i._to!==d.x||o._to!==d.y)&&(this.xAlign=c.xAlign,this.yAlign=c.yAlign,this.width=a.width,this.height=a.height,this.caretX=r.x,this.caretY=r.y,this._resolveAnimations().update(this,d))}}_willRender(){return!!this.opacity}draw(t){let e=this.options.setContext(this.getContext()),n=this.opacity;if(!n)return;this._updateAnimationTarget(e);let i={width:this.width,height:this.height},o={x:this.x,y:this.y};n=Math.abs(n)<.001?0:n;let r=St(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=n,this.drawBackground(o,t,i,e),co(t,e.textDirection),o.y+=r.top,this.drawTitle(o,t,e),this.drawBody(o,t,e),this.drawFooter(o,t,e),ho(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){let n=this._active,i=t.map(({datasetIndex:a,index:l})=>{let c=this.chart.getDatasetMeta(a);if(!c)throw new Error("Cannot find a dataset at index "+a);return{datasetIndex:a,element:c.data[l],index:l}}),o=!Gs(n,i),r=this._positionChanged(i,e);(o||r)&&(this._active=i,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,n=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;let i=this.options,o=this._active||[],r=this._getActiveElements(t,o,e,n),a=this._positionChanged(r,t),l=e||!Gs(r,o)||a;return l&&(this._active=r,(i.enabled||i.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),l}_getActiveElements(t,e,n,i){let o=this.options;if(t.type==="mouseout")return[];if(!i)return e.filter(a=>this.chart.data.datasets[a.datasetIndex]&&this.chart.getDatasetMeta(a.datasetIndex).controller.getParsed(a.index)!==void 0);let r=this.chart.getElementsAtEventForMode(t,o.mode,o,n);return o.reverse&&r.reverse(),r}_positionChanged(t,e){let{caretX:n,caretY:i,options:o}=this,r=sn[o.position].call(this,t,e);return r!==!1&&(n!==r.x||i!==r.y)}};K(nn,"positioners",sn);Yl={id:"tooltip",_element:nn,positioners:sn,afterInit(s,t,e){e&&(s.tooltip=new nn({chart:s,options:e}))},beforeUpdate(s,t,e){s.tooltip&&s.tooltip.initialize(e)},reset(s,t,e){s.tooltip&&s.tooltip.initialize(e)},afterDraw(s){let t=s.tooltip;if(t&&t._willRender()){let e={tooltip:t};if(s.notifyPlugins("beforeTooltipDraw",{...e,cancelable:!0})===!1)return;t.draw(s.ctx),s.notifyPlugins("afterTooltipDraw",e)}},afterEvent(s,t){if(s.tooltip){let e=t.replay;s.tooltip.handleEvent(t.event,e,t.inChartArea)&&(t.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(s,t)=>t.bodyFont.size,boxWidth:(s,t)=>t.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:Ul},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:s=>s!=="filter"&&s!=="itemSort"&&s!=="external",_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},Gl=Object.freeze({__proto__:null,Colors:Il,Decimation:Nl,Filler:$l,Legend:zl,SubTitle:jl,Title:Wl,Tooltip:Yl}),Jf=(s,t,e,n)=>(typeof t=="string"?(e=s.push(t)-1,n.unshift({index:e,label:t})):isNaN(t)&&(e=null),e);eg=(s,t)=>s===null?null:vt(Math.round(s),0,t);ks=class extends Oe{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){let e=this._addedLabels;if(e.length){let n=this.getLabels();for(let{index:i,label:o}of e)n[i]===o&&n.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if(et(t))return null;let n=this.getLabels();return e=isFinite(e)&&n[e]===t?e:tg(n,t,J(e,t),this._addedLabels),eg(e,n.length-1)}determineDataLimits(){let{minDefined:t,maxDefined:e}=this.getUserBounds(),{min:n,max:i}=this.getMinMax(!0);this.options.bounds==="ticks"&&(t||(n=0),e||(i=this.getLabels().length-1)),this.min=n,this.max=i}buildTicks(){let t=this.min,e=this.max,n=this.options.offset,i=[],o=this.getLabels();o=t===0&&e===o.length-1?o:o.slice(t,e+1),this._valueRange=Math.max(o.length-(n?0:1),1),this._startValue=this.min-(n?.5:0);for(let r=t;r<=e;r++)i.push({value:r});return i}getLabelForValue(t){return rl.call(this,t)}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return typeof t!="number"&&(t=this.parse(t)),t===null?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){let e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}};K(ks,"id","category"),K(ks,"defaults",{ticks:{callback:rl}});Ms=class extends Oe{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return et(t)||(typeof t=="number"||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){let{beginAtZero:t}=this.options,{minDefined:e,maxDefined:n}=this.getUserBounds(),{min:i,max:o}=this,r=l=>i=e?i:l,a=l=>o=n?o:l;if(t){let l=Ut(i),c=Ut(o);l<0&&c<0?a(0):l>0&&c>0&&r(0)}if(i===o){let l=o===0?1:Math.abs(o*.05);a(o+l),t||r(i-l)}this.min=i,this.max=o}getTickLimit(){let t=this.options.ticks,{maxTicksLimit:e,stepSize:n}=t,i;return n?(i=Math.ceil(this.max/n)-Math.floor(this.min/n)+1,i>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${n} would result generating up to ${i} ticks. Limiting to 1000.`),i=1e3)):(i=this.computeTickLimit(),e=e||11),e&&(i=Math.min(e,i)),i}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){let t=this.options,e=t.ticks,n=this.getTickLimit();n=Math.max(2,n);let i={maxTicks:n,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:e.includeBounds!==!1},o=this._range||this,r=sg(i,o);return t.bounds==="ticks"&&Wi(r,this,"value"),t.reverse?(r.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),r}configure(){let t=this.ticks,e=this.min,n=this.max;if(super.configure(),this.options.offset&&t.length){let i=(n-e)/Math.max(t.length-1,1)/2;e-=i,n+=i}this._startValue=e,this._endValue=n,this._valueRange=n-e}getLabelForValue(t){return bs(t,this.chart.options.locale,this.options.ticks.format)}},ws=class extends Ms{determineDataLimits(){let{min:t,max:e}=this.getMinMax(!0);this.min=gt(t)?t:0,this.max=gt(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){let t=this.isHorizontal(),e=t?this.width:this.height,n=zt(this.options.ticks.minRotation),i=(t?Math.sin(n):Math.cos(n))||.001,o=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,o.lineHeight/i))}getPixelForValue(t){return t===null?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}};K(ws,"id","linear"),K(ws,"defaults",{ticks:{callback:vs.formatters.numeric}});cn=s=>Math.floor(de(s)),We=(s,t)=>Math.pow(10,cn(s)+t);Es=class extends Oe{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){let n=Ms.prototype.parse.apply(this,[t,e]);if(n===0){this._zero=!0;return}return gt(n)&&n>0?n:null}determineDataLimits(){let{min:t,max:e}=this.getMinMax(!0);this.min=gt(t)?Math.max(0,t):null,this.max=gt(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this._zero&&this.min!==this._suggestedMin&&!gt(this._userMin)&&(this.min=t===We(this.min,0)?We(this.min,-1):We(this.min,0)),this.handleTickRangeOptions()}handleTickRangeOptions(){let{minDefined:t,maxDefined:e}=this.getUserBounds(),n=this.min,i=this.max,o=a=>n=t?n:a,r=a=>i=e?i:a;n===i&&(n<=0?(o(1),r(10)):(o(We(n,-1)),r(We(i,1)))),n<=0&&o(We(i,-1)),i<=0&&r(We(n,1)),this.min=n,this.max=i}buildTicks(){let t=this.options,e={min:this._userMin,max:this._userMax},n=ig(e,this);return t.bounds==="ticks"&&Wi(n,this,"value"),t.reverse?(n.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),n}getLabelForValue(t){return t===void 0?"0":bs(t,this.chart.options.locale,this.options.ticks.format)}configure(){let t=this.min;super.configure(),this._startValue=de(t),this._valueRange=de(this.max)-de(t)}getPixelForValue(t){return(t===void 0||t===0)&&(t=this.min),t===null||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(de(t)-this._startValue)/this._valueRange)}getValueForPixel(t){let e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}};K(Es,"id","logarithmic"),K(Es,"defaults",{ticks:{callback:vs.formatters.logarithmic,major:{enabled:!0}}});Le=class extends Ms{constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){let t=this._padding=St(Io(this.options)/2),e=this.width=this.maxWidth-t.width,n=this.height=this.maxHeight-t.height;this.xCenter=Math.floor(this.left+e/2+t.left),this.yCenter=Math.floor(this.top+n/2+t.top),this.drawingArea=Math.floor(Math.min(e,n)/2)}determineDataLimits(){let{min:t,max:e}=this.getMinMax(!1);this.min=gt(t)&&!isNaN(t)?t:0,this.max=gt(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/Io(this.options))}generateTickLabels(t){Ms.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map((e,n)=>{let i=ct(this.options.pointLabels.callback,[e,n],this);return i||i===0?i:""}).filter((e,n)=>this.chart.getDataVisibility(n))}fit(){let t=this.options;t.display&&t.pointLabels.display?rg(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,n,i){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((n-i)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,n,i))}getIndexAngle(t){let e=ht/(this._pointLabels.length||1),n=this.options.startAngle||0;return Ct(t*e+zt(n))}getDistanceFromCenterForValue(t){if(et(t))return NaN;let e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(et(t))return NaN;let e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){let e=this._pointLabels||[];if(t>=0&&t{if(h!==0||h===0&&this.min<0){l=this.getDistanceFromCenterForValue(d.value);let u=this.getContext(h),f=i.setContext(u),g=o.setContext(u);mg(this,f,l,r,g)}}),n.display){for(t.save(),a=r-1;a>=0;a--){let d=n.setContext(this.getPointLabelContext(a)),{color:h,lineWidth:u}=d;!u||!h||(t.lineWidth=u,t.strokeStyle=h,t.setLineDash(d.borderDash),t.lineDashOffset=d.borderDashOffset,l=this.getDistanceFromCenterForValue(e.reverse?this.min:this.max),c=this.getPointPosition(a,l),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(c.x,c.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){let t=this.ctx,e=this.options,n=e.ticks;if(!n.display)return;let i=this.getIndexAngle(0),o,r;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(i),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach((a,l)=>{if(l===0&&this.min>=0&&!e.reverse)return;let c=n.setContext(this.getContext(l)),d=bt(c.font);if(o=this.getDistanceFromCenterForValue(this.ticks[l].value),c.showLabelBackdrop){t.font=d.string,r=t.measureText(a.label).width,t.fillStyle=c.backdropColor;let h=St(c.backdropPadding);t.fillRect(-r/2-h.left,-o-d.size/2-h.top,r+h.width,d.size+h.height)}Ee(t,a.label,0,-o,d,{color:c.color,strokeColor:c.textStrokeColor,strokeWidth:c.textStrokeWidth})}),t.restore()}drawTitle(){}};K(Le,"id","radialLinear"),K(Le,"defaults",{display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:vs.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback(t){return t},padding:5,centerPointLabels:!1}}),K(Le,"defaultRoutes",{"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"}),K(Le,"descriptors",{angleLines:{_fallback:"grid"}});ci={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},Pt=Object.keys(ci);Pe=class extends Oe{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e={}){let n=t.time||(t.time={}),i=this._adapter=new yl._date(t.adapters.date);i.init(e),fs(n.displayFormats,i.formats()),this._parseOpts={parser:n.parser,round:n.round,isoWeekday:n.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return t===void 0?null:ul(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){let t=this.options,e=this._adapter,n=t.time.unit||"day",{min:i,max:o,minDefined:r,maxDefined:a}=this.getUserBounds();function l(c){!r&&!isNaN(c.min)&&(i=Math.min(i,c.min)),!a&&!isNaN(c.max)&&(o=Math.max(o,c.max))}(!r||!a)&&(l(this._getLabelBounds()),(t.bounds!=="ticks"||t.ticks.source!=="labels")&&l(this.getMinMax(!1))),i=gt(i)&&!isNaN(i)?i:+e.startOf(Date.now(),n),o=gt(o)&&!isNaN(o)?o:+e.endOf(Date.now(),n)+1,this.min=Math.min(i,o-1),this.max=Math.max(i+1,o)}_getLabelBounds(){let t=this.getLabelTimestamps(),e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],n=t[t.length-1]),{min:e,max:n}}buildTicks(){let t=this.options,e=t.time,n=t.ticks,i=n.source==="labels"?this.getLabelTimestamps():this._generate();t.bounds==="ticks"&&i.length&&(this.min=this._userMin||i[0],this.max=this._userMax||i[i.length-1]);let o=this.min,r=this.max,a=qr(i,o,r);return this._unit=e.unit||(n.autoSkip?fl(e.minUnit,this.min,this.max,this._getLabelCapacity(o)):vg(this,a.length,e.minUnit,this.min,this.max)),this._majorUnit=!n.major.enabled||this._unit==="year"?void 0:yg(this._unit),this.initOffsets(i),t.reverse&&a.reverse(),pl(this,a,this._majorUnit)}afterAutoSkip(){this.options.offsetAfterAutoskip&&this.initOffsets(this.ticks.map(t=>+t.value))}initOffsets(t=[]){let e=0,n=0,i,o;this.options.offset&&t.length&&(i=this.getDecimalForValue(t[0]),t.length===1?e=1-i:e=(this.getDecimalForValue(t[1])-i)/2,o=this.getDecimalForValue(t[t.length-1]),t.length===1?n=o:n=(o-this.getDecimalForValue(t[t.length-2]))/2);let r=t.length<3?.5:.25;e=vt(e,0,r),n=vt(n,0,r),this._offsets={start:e,end:n,factor:1/(e+1+n)}}_generate(){let t=this._adapter,e=this.min,n=this.max,i=this.options,o=i.time,r=o.unit||fl(o.minUnit,e,n,this._getLabelCapacity(e)),a=J(i.ticks.stepSize,1),l=r==="week"?o.isoWeekday:!1,c=$e(l)||l===!0,d={},h=e,u,f;if(c&&(h=+t.startOf(h,"isoWeek",l)),h=+t.startOf(h,c?"day":r),t.diff(n,e,r)>1e5*a)throw new Error(e+" and "+n+" are too far apart with stepSize of "+a+" "+r);let g=i.ticks.source==="data"&&this.getDataTimestamps();for(u=h,f=0;u+p)}getLabelForValue(t){let e=this._adapter,n=this.options.time;return n.tooltipFormat?e.format(t,n.tooltipFormat):e.format(t,n.displayFormats.datetime)}format(t,e){let i=this.options.time.displayFormats,o=this._unit,r=e||i[o];return this._adapter.format(t,r)}_tickFormatFunction(t,e,n,i){let o=this.options,r=o.ticks.callback;if(r)return ct(r,[t,e,n],this);let a=o.time.displayFormats,l=this._unit,c=this._majorUnit,d=l&&a[l],h=c&&a[c],u=n[e],f=c&&h&&u&&u.major;return this._adapter.format(t,i||(f?h:d))}generateTickLabels(t){let e,n,i;for(e=0,n=t.length;e0?a:1}getDataTimestamps(){let t=this._cache.data||[],e,n;if(t.length)return t;let i=this.getMatchingVisibleMetas();if(this._normalized&&i.length)return this._cache.data=i[0].controller.getAllParsedValues(this);for(e=0,n=i.length;e=e&&c<=n&&i.push(c);if(i.length<2)return[{time:e,pos:0},{time:n,pos:1}];for(r=0,a=i.length;ri-o)}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;let e=this.getDataTimestamps(),n=this.getLabelTimestamps();return e.length&&n.length?t=this.normalize(e.concat(n)):t=e.length?e:n,t=this._cache.all=t,t}getDecimalForValue(t){return(Zn(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){let e=this._offsets,n=this.getDecimalForPixel(t)/e.factor-e.end;return Zn(this._table,n*this._tableRange+this._minPos,!0)}};K(Ds,"id","timeseries"),K(Ds,"defaults",Pe.defaults);ql=Object.freeze({__proto__:null,CategoryScale:ks,LinearScale:ws,LogarithmicScale:Es,RadialLinearScale:Le,TimeScale:Pe,TimeSeriesScale:Ds}),Cg=[vl,Pl,Gl,ql]});var Kg={};Xo(Kg,{CardView:()=>As,default:()=>xi});module.exports=Tc(Kg);var ot=require("obsidian"),Cc=Os(ts());var Lc=["AT","BE","CZ","DK","EE","FI","FR","DE","GR","HU","IS","IT","LV","LI","LT","LU","MT","NL","NO","PL","PT","SK","SI","ES","SE","CH"],Ac=[{label:"\u{1F1EA}\u{1F1FA} Schengen 90/180 (example)",scope:{countries:Lc},window:{type:"rolling",days:180},threshold:90,note:"Example rule \u2014 add your own in Settings \u2192 CSV Card View."}],wi={defaultMode:"kanban-genre",notesColumns:["notes","note","Notes","Note","description","Description","review","Review"],statusColumn:"status",categoryColumn:"category",notesSubfolder:"Notes",columnWidths:{},selectColumns:["Category","Type","Rating","Status","rating","type","category","status","Score /5"],fileConfigs:{},residencyRules:Ac,showResidency:!0},fn="xlsx-card-view";var Zo=Os(ts()),gn=require("obsidian"),es=["Image","image","Cover","cover","Poster","poster","Thumbnail","thumbnail","Thumb","thumb","Photo","photo","Picture","picture","Img","img"],ge=["Title","title","Name","name"],ss=["Category","category","Categories","categories","Genre","genre","Genres","genres","Type","type","Types","types","Tag","tag","Tags","tags","Topic","topic","Topics","topics","Subject","subject","Section","section"],ns=["Status","status","State","state","Progress","progress","Stage","stage","Read","read","Watched","watched","Seen","seen","Done","done","Completed","completed"],pe=["Notes","notes","Note","note","Summary","summary","Review","review","Quote","quote","Quotes","quotes","Comment","comment","Comments","comments","Description","description","Annotation","annotation"];function pn(s,t,e){let n=(t!=null?t:"").trim();if(!n)return null;if(/^(https?:|data:)/i.test(n))return n;let i=n.match(/!?\[\[([^\]|]+)(?:\|[^\]]*)?\]\]/);if(i)n=i[1].trim();else{let r=n.match(/!\[[^\]]*\]\(([^)]+)\)/);r&&(n=r[1].trim())}if(/^(https?:|data:)/i.test(n))return n;let o=s.metadataCache.getFirstLinkpathDest(n,e);return o instanceof gn.TFile?s.vault.getResourcePath(o):null}var Rc=15;function Xt(s){return s>=1&&s<=Rc}var Pc=["0","1","true","false","yes","no",""];function is(s){return s.length>0&&s.every(t=>Pc.includes(t))}function os(s){let t=(s!=null?s:"").toLowerCase().trim();return t==="1"||t==="true"||t==="yes"}function me(s=new Date){return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-${String(s.getDate()).padStart(2,"0")}`}function Ie(s){return s.replace(/[\\/:*?"<>|#^[\]]/g,"").replace(/\s+/g," ").trim().slice(0,100)}function Jo(s){return s.toLowerCase().replace(/[^\p{L}\p{N}/_-]+/gu,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function wt(s){var i,o;if(!s||!s.trim())return{headers:[],rows:[]};let t=Zo.default.parse(s,{header:!0,skipEmptyLines:!0}),e=((i=t.meta.fields)!=null?i:[]).map(String),n=((o=t.data)!=null?o:[]).map(r=>{let a={};return e.forEach(l=>{a[l]=r[l]!=null?String(r[l]):""}),a});return{headers:e,rows:n}}function Qt(s,t){if(!s)return s;let e=s.startsWith("./")||s.startsWith("../")||s==="."||s==="..";if(!e&&s.includes("/"))return s;if(!e)return t?`${t}/${s}`:s;let n=t?t.split("/").filter(Boolean):[];for(let i of s.split("/"))if(!(i===""||i===".")){if(i===".."){n.pop();continue}n.push(i)}return n.join("/")}function tr(s,t,e){let n=e==="asc"?1:-1;return[...s].sort((i,o)=>{var u,f;let r=((u=i[t])!=null?u:"").trim(),a=((f=o[t])!=null?f:"").trim();if(!r&&!a)return 0;if(!r)return 1;if(!a)return-1;let l=parseFloat(r),c=parseFloat(a);return(!isNaN(l)&&!isNaN(c)&&/^-?[\d.]/.test(r)&&/^-?[\d.]/.test(a)?l-c:r.localeCompare(a,void 0,{numeric:!0,sensitivity:"base"}))*n})}function Tt(s){return s.split(/[\s_-]+/).map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(" ")}function er(s,t){let e=(s!=null?s:"").trim();if(!e||e.toLowerCase()==="unrated"||e==="\u2014"||e==="-")return"";if(/[★⭐☆]/.test(e))return e;if(/^\d+$/.test(e)){let o=parseInt(e,10);if(o>=1&&o<=5)return"\u2605".repeat(o)}let i=Oc(e,t);return i&&i!==e&&i!=="\u2014"?i:""}function Oc(s,t){var o;let e=t.toLowerCase();if(!["rating","score","score /5"].includes(e))return s;let n=s.toLowerCase().trim();return(o={excellent:"\u2605\u2605\u2605\u2605\u2605",great:"\u2605\u2605\u2605\u2605\u2605",good:"\u2605\u2605\u2605\u2605\u2606",fair:"\u2605\u2605\u2605\u2606\u2606",poor:"\u2605\u2605\u2606\u2606\u2606",bad:"\u2605\u2606\u2606\u2606\u2606",5:"\u2605\u2605\u2605\u2605\u2605",4:"\u2605\u2605\u2605\u2605\u2606",3:"\u2605\u2605\u2605\u2606\u2606",2:"\u2605\u2605\u2606\u2606\u2606",1:"\u2605\u2606\u2606\u2606\u2606",0:"\u2606\u2606\u2606\u2606\u2606",unrated:"\u2014","":"\u2014"}[n])!=null?o:s}function sr(s,t){if(/^(year|released|decade)$/i.test((s!=null?s:"").trim()))return!0;let e=t.map(i=>(i!=null?i:"").trim()).filter(Boolean);return e.length<3?!1:e.filter(i=>/^(1[89]|20)\d{2}$/.test(i)).length/e.length>=.8}function nr(s){let t=(s!=null?s:"").match(/\b(1[89]\d{2}|20\d{2})\b/);return t?`${Math.floor(parseInt(t[1],10)/10)*10}s`:null}function ir(s,t,e){var r;if(!t.length)return null;let n=Math.max(12,t.length/3),i=null,o=1/0;for(let a of s){if(e.has(a))continue;let l=new Set;for(let d of t)((r=d[a])!=null?r:"").split(",").forEach(h=>{let u=h.trim();u&&l.add(u)});if(l.size<2||l.size>n)continue;let c=Math.abs(Math.log(l.size/8));cw.remove());let r=document.body.createDiv({cls:"csv-select-picker"});r.style.position="fixed",r.style.zIndex="9999";let a=()=>{let w=s.getBoundingClientRect(),M=r.offsetHeight||280,L=w.bottom+4+M>window.innerHeight&&w.top-4-M>0;r.style.left=w.left+"px",r.style.top=L?w.top-4-M+"px":w.bottom+4+"px"};a();let l=w=>{!r.contains(w.target)&&w.target!==s&&d()},c=w=>{r.contains(w.target)||d()},d=()=>{r.remove(),document.removeEventListener("mousedown",l),window.removeEventListener("scroll",c,!0),window.removeEventListener("resize",d)},h=r.createEl("input",{cls:"csv-picker-search",type:"text",placeholder:"Search or add\u2026"});h.focus();let u=r.createDiv({cls:"csv-picker-list"}),f=!!(o!=null&&o.multi),g=w=>w.split(",").map(M=>M.trim()).filter(Boolean),p=new Set(f?g(t):[]),b=()=>n([...p].join(", ")),m=f?Array.from(new Set(e.flatMap(g))):Array.from(new Set(e.filter(Boolean))),v=[],_=0,k=()=>{u.querySelectorAll(".csv-picker-item").forEach((w,M)=>{w.toggleClass("csv-picker-item--hover",M===_),M===_&&w.scrollIntoView({block:"nearest"})})},S=w=>{if(!f){n(w.isClear?"":w.value),d();return}w.isClear?p.clear():(p.has(w.value)?p.delete(w.value):p.add(w.value),w.isAdd&&!m.includes(w.value)&&m.push(w.value)),b(),w.isAdd?(h.value="",C("")):C(h.value)},x=w=>f?p.has(w):w===t,y=()=>f?p.size>0:!!t,C=w=>{u.empty(),v=[];let M=w?m.filter(L=>L.toLowerCase().includes(w.toLowerCase())):m;if(y()){v.push({value:"",isClear:!0});let L=u.createDiv({cls:"csv-picker-item csv-picker-clear"});L.setText(f?"\u2715 Clear all":"\u2715 Clear"),L.addEventListener("mousedown",O=>{O.preventDefault(),S({value:"",isClear:!0})})}if(M.forEach(L=>{v.push({value:L});let O=u.createDiv({cls:`csv-picker-item ${x(L)?"active":""}`});O.setText(f?`${p.has(L)?"\u2713 ":""}${L}`:L),O.addEventListener("mousedown",V=>{V.preventDefault(),S({value:L})})}),w&&!m.some(L=>L.toLowerCase()===w.toLowerCase())){v.push({value:w,isAdd:!0});let L=u.createDiv({cls:"csv-picker-item csv-picker-add"});L.setText(`+ Add "${w}"`),L.addEventListener("mousedown",O=>{O.preventDefault(),S({value:w,isAdd:!0})})}!M.length&&!w&&u.createDiv({cls:"csv-picker-empty",text:"No options yet. Type to add."}),_=Math.min(_,Math.max(v.length-1,0)),k()};f&&r.createEl("button",{cls:"csv-picker-done",text:"Done"}).addEventListener("mousedown",w=>{w.preventDefault(),d()}),C(""),a(),h.addEventListener("input",()=>{_=0,C(h.value),a()});let E=typeof window!="undefined"&&((D=window.matchMedia)==null?void 0:D.call(window,"(pointer: coarse)").matches);setTimeout(()=>{document.addEventListener("mousedown",l),E||(window.addEventListener("scroll",c,!0),window.addEventListener("resize",d))},0),h.addEventListener("keydown",w=>{if(w.key==="Escape"){d();return}if(w.key==="ArrowDown"){w.preventDefault(),v.length&&(_=(_+1)%v.length,k());return}if(w.key==="ArrowUp"){w.preventDefault(),v.length&&(_=(_-1+v.length)%v.length,k());return}if(w.key==="Enter")if(w.preventDefault(),v[_])S(v[_]);else{let M=h.value.trim();M&&(n(M),d())}})}async function rs(s,t,e){var l,c;let n=(c=(l=t.parent)==null?void 0:l.path)!=null?c:"",i=n?`${n}/Archive`:"Archive";await s.vault.adapter.exists(i)||await s.vault.adapter.mkdir(i);let o=new Date,r=`${me(o)} ${String(o.getHours()).padStart(2,"0")}${String(o.getMinutes()).padStart(2,"0")}${String(o.getSeconds()).padStart(2,"0")}`,a=`${i}/${t.basename} sync-conflict ${r}.csv`;return await s.vault.adapter.write(a,e),new gn.Notice(`"${t.name}" changed on disk while you were editing (another device?). That version was saved to ${a} \u2014 your edits won.`,1e4),a}function or(s,t,e){return!s[t]||t===e||(s[e]||(s[e]=s[t]),delete s[t]),s}var Fc={source:["confirmed","inferred","conflict"],resolved:["yes","no"]};function rr(s){var t;return(t=Fc[s.trim().toLowerCase()])!=null?t:null}function Et(s){return/(^|[_\s-])(date|due|deadline)([_\s-]|$)/i.test(s.trim())}var mn=/^\d{4}-\d{2}-\d{2}$/;var Vt=require("obsidian");function yn(s,t,e,n,i=Et){let o=i(t)&&(e===""||mn.test(e.slice(0,10))),r=o?e.slice(0,10):e,a=s.createEl("input",{cls:n,type:o?"date":"text",value:r});o||(a.placeholder=t);let l=rr(t);if(l){let c=`csv-dl-${t.toLowerCase().replace(/[^a-z0-9]+/g,"-")}-${Math.random().toString(36).slice(2,7)}`,d=s.createEl("datalist");d.id=c,l.forEach(h=>d.createEl("option",{value:h})),a.setAttr("list",c)}return a}var as=class extends Vt.Modal{constructor(t,e,n,i,o,r,a={},l=()=>!1,c,d,h=Et){super(t),this.headers=e,this.isNotesCol=n,this.isSelectCol=i,this.getColumnValues=o,this.onSubmit=r,this.optionPresets=a,this.isBooleanCol=l,this.isCategoricalCol=c!=null?c:u=>this.isSelectCol(u)||Xt(this.getColumnValues(u).length),this.titleCol=d!=null?d:this.headers.find(u=>["title","name"].includes(u.toLowerCase())),this.isDateCol=h}onOpen(){let{contentEl:t}=this;t.empty(),t.addClass("csv-add-modal"),t.createEl("h2",{text:"Add new entry",cls:"csv-modal-title"});let e=t.createDiv({cls:"csv-modal-form"}),n={};this.headers.forEach(d=>n[d]="");let i=this.titleCol,o=new Map;i&&this.getColumnValues(i).forEach(d=>{let h=d.trim().toLowerCase();h&&!o.has(h)&&o.set(h,d.trim())}),this.headers.forEach(d=>{var b;let h=e.createDiv({cls:"csv-modal-row"});h.createEl("label",{text:Tt(d),cls:"csv-modal-label"});let u=(b=this.optionPresets[d])!=null?b:[],f=d===i,g=xt(d),p=!f&&!this.isNotesCol(d)&&!g&&(u.length>0||this.isCategoricalCol(d));if(this.isBooleanCol(d)){n[d]="0";let m=h.createDiv({cls:"csv-toggle"});m.createDiv({cls:"csv-toggle-knob"}),m.addEventListener("click",()=>{let v=!m.hasClass("is-on");m.toggleClass("is-on",v),n[d]=v?"1":"0"})}else if(this.isNotesCol(d)){let m=h.createEl("textarea",{cls:"csv-modal-textarea",placeholder:"Markdown supported\u2026"});m.addEventListener("input",()=>{n[d]=m.value})}else if(p){let m="__custom__",v=[];[...u,...this.getColumnValues(d)].forEach(S=>{let x=(S!=null?S:"").trim();x&&!v.some(y=>y.toLowerCase()===x.toLowerCase())&&v.push(x)});let _=h.createEl("select",{cls:"csv-modal-select"});_.createEl("option",{text:"\u2014",value:""}),v.forEach(S=>_.createEl("option",{text:S,value:S})),_.createEl("option",{text:"+ Custom\u2026",value:m});let k=h.createEl("input",{cls:"csv-modal-input csv-modal-custom",type:"text",placeholder:`Custom ${Tt(d).toLowerCase()}`});k.hide(),k.addEventListener("input",()=>{n[d]=k.value}),k.addEventListener("keydown",S=>{S.key==="Enter"&&c()}),_.addEventListener("change",()=>{_.value===m?(k.show(),k.focus(),n[d]=k.value):(k.hide(),n[d]=_.value)})}else if(!f&&g&&this.isSelectCol(d)){let v=h.createDiv({cls:"csv-modal-select-wrap"}).createDiv({cls:"csv-select-chip empty"});v.setText("\u2014 click to select \u2014"),v.addEventListener("click",_=>{_.stopPropagation(),It(v,n[d],this.getColumnValues(d),k=>{n[d]=k,v.setText(k||"\u2014 click to select \u2014"),v.toggleClass("empty",!k)},t,{multi:xt(d)})})}else{let m=yn(h,d,"","csv-modal-input",v=>this.isDateCol(v));if(m.addEventListener("input",()=>{n[d]=m.value}),m.addEventListener("keydown",v=>{v.key==="Enter"&&c()}),d===i&&o.size){let v=h.createDiv({cls:"csv-modal-dup-hint"});v.hide(),m.addEventListener("input",()=>{let _=o.get(m.value.trim().toLowerCase());_?(v.setText(`\u26A0 \u201C${_}\u201D is already in this file`),v.show()):v.hide()})}}});let r=t.createDiv({cls:"csv-modal-btns"});r.createEl("button",{text:"Cancel",cls:"csv-modal-cancel"}).addEventListener("click",()=>this.close()),r.createEl("button",{text:"Add entry",cls:"csv-modal-submit"}).addEventListener("click",()=>c());let c=()=>{if(!Object.values(n).some(h=>h.trim())){new Vt.Notice("Fill in at least one field.");return}this.onSubmit(n),this.close()}}onClose(){this.contentEl.empty()}},be=class extends Vt.Modal{constructor(e,n,i,o,r,a,l,c,d,h,u,f,g=()=>!1,p=Et){super(e);this.vvHandler=null;this.row={...n},this.notesCol=i,this.headers=o,this.filePath=r,this.renderComponent=new Vt.Component,this.isNotesCol=a,this.isSelectCol=l,this.getColumnValues=c,this.onSave=d,this.onDelete=h,this.isCategoricalCol=u!=null?u:b=>this.isSelectCol(b)||!Et(b)&&Xt(this.getColumnValues(b).length),this.titleCol=f!=null?f:this.headers.find(b=>["title","name","Title","Name"].includes(b)),this.isBooleanCol=g,this.isDateCol=p,this.modalEl.addClass("csv-note-expander-modal")}onOpen(){var g,p,b,m,v;this.renderComponent.load();let{contentEl:e}=this;e.empty(),e.addClass("csv-note-expander");let n=window.visualViewport;if(n){let _=()=>{this.modalEl.style.setProperty("--csv-modal-vh",`${n.height}px`)};_(),n.addEventListener("resize",_),n.addEventListener("scroll",_),this.vvHandler=_}let i=e.createDiv({cls:"csv-expander-header"});i.createDiv({cls:"csv-expander-title",text:(p=this.row[(g=this.titleCol)!=null?g:this.headers[0]])!=null?p:"\u2014"});let o=i.createDiv({cls:"csv-expander-header-btns"}),r=e.createDiv({cls:"csv-expander-fields"}),a=this.titleCol,l=this.headers.find(_=>["author","Author","director","Director","artist","Artist","creator","Creator"].includes(_));this.headers.forEach(_=>{var y;if(this.isNotesCol(_))return;let k=r.createDiv({cls:"csv-expander-field-row"});if(k.createDiv({cls:"csv-expander-field-label",text:Tt(_)}),this.isBooleanCol(_)){let C=os((y=this.row[_])!=null?y:""),E=k.createDiv({cls:`csv-toggle ${C?"is-on":""}`});E.createDiv({cls:"csv-toggle-knob"}),E.addEventListener("click",()=>{let D=!E.hasClass("is-on");E.toggleClass("is-on",D),this.row[_]=D?"1":"0"});return}let S=xt(_);if(_!==a&&(S?this.isSelectCol(_):this.isCategoricalCol(_))){let C=k.createDiv({cls:`csv-select-chip ${this.row[_]?"":"empty"}`});C.setText(this.row[_]||"\u2014"),C.addEventListener("click",E=>{E.stopPropagation(),It(C,this.row[_],this.getColumnValues(_),D=>{this.row[_]=D,C.setText(D||"\u2014"),C.toggleClass("empty",!D)},e,{multi:xt(_)})})}else{let C=k.createDiv({cls:"csv-expander-field-value",text:this.row[_]||"\u2014"});C.addEventListener("click",()=>{var w;if(C.querySelector("input"))return;C.empty();let E=yn(C,_,(w=this.row[_])!=null?w:"","csv-inline-input",this.isDateCol);E.focus(),E.type==="text"&&E.select(),E.addEventListener("click",M=>M.stopPropagation());let D=()=>{this.row[_]=E.value,C.empty(),C.setText(E.value||"\u2014")};E.addEventListener("blur",D),E.addEventListener("keydown",M=>{M.key==="Enter"&&E.blur(),M.key==="Escape"&&(C.empty(),C.setText(this.row[_]||"\u2014"))})})}});let c=!1,d=this.notesCol&&(b=this.row[this.notesCol])!=null?b:"",h=null;if(this.notesCol){e.createDiv({cls:"csv-expander-divider"}).createDiv({cls:"csv-expander-notes-label",text:this.notesCol});let k=e.createDiv({cls:"csv-expander-rendered markdown-rendered"});k.title="Click to edit";let S=e.createDiv({cls:"csv-expander-editor"});S.style.display="none";let x=()=>{k.empty(),d.trim()?Vt.MarkdownRenderer.render(this.app,d,k,this.filePath,this.renderComponent):k.createDiv({cls:"csv-notes-empty",text:"+ Add note"})};x(),h=S.createEl("textarea",{cls:"csv-expander-textarea"}),h.value=d,h.addEventListener("input",()=>{d=h.value});let y=()=>{c||(c=!0,k.style.display="none",S.style.display="flex",h.value=d,h.focus())},C=()=>{c&&(c=!1,S.style.display="none",k.style.display="",d=h.value,x())};k.addEventListener("click",E=>{if(E.target.closest("a, button, input, textarea, [contenteditable]"))return;let w=window.getSelection();w&&w.toString().length>0||y()}),h.addEventListener("keydown",E=>{E.key==="Escape"&&(E.preventDefault(),h.blur())}),h.addEventListener("blur",C)}let u=e.createDiv({cls:"csv-expander-footer"});if(this.onDelete){let _=String((v=this.row[(m=this.titleCol)!=null?m:this.headers[0]])!=null?v:"").trim();u.createEl("button",{cls:"csv-expander-delete-btn",text:"Delete"}).addEventListener("click",()=>{let k=_||"this entry";window.confirm(`Delete "${k}"? This can't be undone.`)&&(this.onDelete(),this.close())})}let f=u.createDiv({cls:"csv-expander-footer-right"});f.createEl("button",{cls:"csv-modal-cancel",text:"Cancel"}).addEventListener("click",()=>this.close()),f.createEl("button",{cls:"csv-expander-save-btn",text:"Save & close"}).addEventListener("click",()=>{this.notesCol&&(c&&h&&(d=h.value),this.row[this.notesCol]=d),this.onSave(this.row),this.close()})}onClose(){let e=window.visualViewport;e&&this.vvHandler&&(e.removeEventListener("resize",this.vvHandler),e.removeEventListener("scroll",this.vvHandler)),this.vvHandler=null,this.renderComponent.unload(),this.contentEl.empty()}};var bn=class extends Vt.Modal{constructor(t,e,n,i,o,r,a,l,c,d,h,u,f,g=()=>0){super(t),this.headers=e,this.filePath=n,this.current={...i,habitColumns:i.habitColumns?[...i.habitColumns]:void 0,categoricalColumns:i.categoricalColumns?[...i.categoricalColumns]:void 0},this.autoDetectedHabits=o,this.autoDetectedCategorical=r,this.autoDetectedRoles=a,this.availableModes=l,this.onSave=c,this.getHeaders=d,this.getFileCfg=h,this.onAddColumn=u,this.onRemoveColumn=f,this.onCleanupBooleanColumn=g}onOpen(){var O,V,P;let{contentEl:t}=this;t.empty(),t.addClass("csv-add-modal"),t.createEl("h2",{text:"View settings for this file",cls:"csv-modal-title"}),t.createEl("p",{text:"These settings apply only to this file and override the global defaults.",cls:"csv-modal-desc"});let e=t.createDiv({cls:"csv-modal-form"}),n=()=>{this.headers=this.getHeaders();let T=this.getFileCfg();this.current={...T,habitColumns:T.habitColumns?[...T.habitColumns]:void 0,categoricalColumns:T.categoricalColumns?[...T.categoricalColumns]:void 0},this.onOpen()},i=e.createDiv({cls:"csv-modal-row"});i.createEl("label",{text:"Columns",cls:"csv-modal-label"}),i.createEl("p",{cls:"csv-modal-hint",text:`Type and Function are each exclusive per column \u2014 picking one clears it from whichever column held it before. "auto" means it's already doing that by column name, with nothing saved here yet. Card field is independent and can combine with anything. Checkbox columns get a "Clean up" action that rewrites every row to strict 1/0 right away \u2014 not deferred to Save.`});let o=[{value:"text",label:"Text"},{value:"checkbox",label:"Checkbox"},{value:"categorical",label:"Categorical"},{value:"date",label:"Date"}],r=[{value:"",label:"\u2014 no function \u2014"},{value:"title",label:"Title"},{value:"category",label:"Column group (Kanban lanes)"},{value:"status",label:"Row group / Status / Checkmark"},{value:"notes",label:"Notes"},{value:"image",label:"Image (card / kanban thumbnail)"},{value:"anki",label:"Anki card front"}],a=T=>{var H,A,j;let U=(H=this.current.habitColumns)!=null?H:this.autoDetectedHabits,F=(A=this.current.categoricalColumns)!=null?A:this.autoDetectedCategorical,G=(j=this.current.dateColumns)!=null?j:this.headers.filter(Y=>Et(Y));return U.includes(T)?{type:"checkbox",auto:!this.current.habitColumns}:F.includes(T)?{type:"categorical",auto:!this.current.categoricalColumns}:G.includes(T)?{type:"date",auto:!this.current.dateColumns}:{type:"text",auto:!1}},l=(T,U)=>{this.current.habitColumns||(this.current.habitColumns=[...this.autoDetectedHabits]),this.current.categoricalColumns||(this.current.categoricalColumns=[...this.autoDetectedCategorical]),this.current.dateColumns||(this.current.dateColumns=this.headers.filter(F=>Et(F))),this.current.habitColumns=this.current.habitColumns.filter(F=>F!==T),this.current.categoricalColumns=this.current.categoricalColumns.filter(F=>F!==T),this.current.dateColumns=this.current.dateColumns.filter(F=>F!==T),U==="checkbox"?this.current.habitColumns.push(T):U==="categorical"?this.current.categoricalColumns.push(T):U==="date"&&this.current.dateColumns.push(T)},c=(V=(O=this.current.titleColumn)!=null?O:this.autoDetectedRoles.title)!=null?V:this.headers[0],h=i.createDiv({cls:"csv-modal-colcfg-table-wrap"}).createEl("table",{cls:"csv-modal-colcfg-table"}),u=h.createEl("thead").createEl("tr");["Column","Type","Visibility"].forEach(T=>u.createEl("th",{text:T}));let f=h.createEl("tbody"),g=()=>{var U;f.empty();let T=new Set((U=this.current.cardFields)!=null?U:this.headers);this.headers.forEach(F=>{let G=f.createEl("tr"),H=G.createEl("td",{cls:"csv-modal-colcfg-name"});H.createSpan({text:F});let A=H.createEl("button",{cls:"csv-modal-column-remove",text:"\u2715",attr:{title:`Remove "${F}" \u2014 deletes this column's data from every row`}});A.addEventListener("click",()=>{if(A.hasClass("confirm")){this.onRemoveColumn(F),n();return}f.querySelectorAll(".csv-modal-column-remove.confirm").forEach(R=>{R.removeClass("confirm"),R.setText("\u2715")}),A.addClass("confirm"),A.setText("Confirm?"),window.setTimeout(()=>{A.isConnected&&(A.removeClass("confirm"),A.setText("\u2715"))},3e3)});let j=G.createEl("td",{cls:"csv-modal-colcfg-type-cell"});if(F===c)j.createSpan({cls:"csv-modal-colcfg-fixed",text:"Text"});else{let R=j.createEl("select",{cls:"csv-modal-select csv-modal-colcfg-type"}),{type:B,auto:z}=a(F);if(o.forEach(N=>{let W=R.createEl("option",{text:N.label,value:N.value});N.value===B&&(W.selected=!0)}),z&&R.addClass("auto-detected"),R.addEventListener("change",()=>{l(F,R.value),g()}),z&&j.createSpan({cls:"csv-modal-colcfg-auto-badge",text:"auto"}),B==="checkbox"){let N=j.createEl("button",{cls:"csv-modal-colcfg-cleanup-btn",text:"Clean up",attr:{title:`Rewrite every row in "${F}" to strict 1/0 (yes/true/1 \u2192 1, everything else \u2192 0)`}});N.addEventListener("click",()=>{if(N.hasClass("confirm")){let W=this.onCleanupBooleanColumn(F);new Vt.Notice(W>0?`"${F}": normalized ${W} row${W===1?"":"s"} to 1/0.`:`"${F}" is already strict 1/0 \u2014 nothing to change.`);return}f.querySelectorAll(".csv-modal-colcfg-cleanup-btn.confirm").forEach(W=>{W.removeClass("confirm"),W.setText("Clean up")}),N.addClass("confirm"),N.setText("Confirm?"),window.setTimeout(()=>{N.isConnected&&(N.removeClass("confirm"),N.setText("Clean up"))},3e3)})}}let $=G.createEl("td",{cls:"csv-modal-colcfg-card-cell"}).createEl("input",{type:"checkbox"});$.checked=T.has(F),$.addEventListener("change",()=>{this.current.cardFields||(this.current.cardFields=[...this.headers]),$.checked?this.current.cardFields.includes(F)||this.current.cardFields.push(F):this.current.cardFields=this.current.cardFields.filter(R=>R!==F)})})};g();let p=t.createDiv({cls:"csv-modal-section",attr:{style:"margin-top: 24px;"}});p.createEl("h3",{text:"Column Functions",cls:"csv-modal-h3"}),p.createEl("p",{cls:"csv-modal-desc",text:"Assign specific roles to your columns. 'auto' means it's already doing that by column name. Selecting '\u2014 none \u2014' disables the function entirely."});let m=p.createDiv({cls:"csv-modal-colcfg-table-wrap"}).createEl("table",{cls:"csv-modal-colcfg-table"}),v=m.createEl("thead").createEl("tr");["Function","Column"].forEach(T=>v.createEl("th",{text:T}));let _=m.createEl("tbody"),k=()=>{_.empty(),r.forEach(T=>{var Y,$,R,B,z,N,W,I,q,Q,Z,nt;if(T.value==="")return;let U=_.createEl("tr");U.createEl("td",{cls:"csv-modal-colcfg-name"}).setText(T.label);let G=U.createEl("td",{cls:"csv-modal-colcfg-type-cell"}),H=G.createEl("select",{cls:"csv-modal-select csv-modal-colcfg-role"});H.createEl("option",{text:"\u2014 none \u2014",value:""});let A="",j=!1;T.value==="title"?(A=($=(Y=this.current.titleColumn)!=null?Y:this.autoDetectedRoles.title)!=null?$:"",j=this.current.titleColumn===void 0&&!!this.autoDetectedRoles.title):T.value==="category"?(A=(B=(R=this.current.categoryColumn)!=null?R:this.autoDetectedRoles.category)!=null?B:"",j=this.current.categoryColumn===void 0&&!!this.autoDetectedRoles.category):T.value==="status"?(A=(N=(z=this.current.statusColumn)!=null?z:this.autoDetectedRoles.status)!=null?N:"",j=this.current.statusColumn===void 0&&!!this.autoDetectedRoles.status):T.value==="notes"?(A=(I=(W=this.current.notesColumn)!=null?W:this.autoDetectedRoles.notes)!=null?I:"",j=this.current.notesColumn===void 0&&!!this.autoDetectedRoles.notes):T.value==="image"?(A=(Q=(q=this.current.imageColumn)!=null?q:this.autoDetectedRoles.image)!=null?Q:"",j=this.current.imageColumn===void 0&&!!this.autoDetectedRoles.image):T.value==="anki"&&(A=(nt=(Z=this.current.ankiFrontCol)!=null?Z:this.autoDetectedRoles.anki)!=null?nt:"",j=this.current.ankiFrontCol===void 0&&!!this.autoDetectedRoles.anki),this.headers.forEach(X=>{let tt=H.createEl("option",{text:X,value:X});X===A&&(tt.selected=!0)}),j&&A!==""&&H.addClass("auto-detected"),H.addEventListener("change",()=>{let X=H.value;X&&(T.value!=="title"&&this.current.titleColumn===X&&(this.current.titleColumn=void 0),T.value!=="category"&&this.current.categoryColumn===X&&(this.current.categoryColumn=void 0),T.value!=="status"&&this.current.statusColumn===X&&(this.current.statusColumn=void 0),T.value!=="notes"&&this.current.notesColumn===X&&(this.current.notesColumn=void 0),T.value!=="image"&&this.current.imageColumn===X&&(this.current.imageColumn=void 0),T.value!=="anki"&&this.current.ankiFrontCol===X&&(this.current.ankiFrontCol=void 0)),T.value==="title"?this.current.titleColumn=X:T.value==="category"?this.current.categoryColumn=X:T.value==="status"?this.current.statusColumn=X:T.value==="notes"?this.current.notesColumn=X:T.value==="image"?this.current.imageColumn=X:T.value==="anki"&&(this.current.ankiFrontCol=X),k()}),j&&A!==""&&G.createSpan({cls:"csv-modal-colcfg-auto-badge",text:"auto"})})};k();let S=i.createDiv({cls:"csv-modal-add-column"}),x=S.createEl("input",{cls:"csv-modal-input",type:"text",placeholder:"New column name"}),y=S.createEl("button",{cls:"csv-modal-cancel",text:"+ Add column"}),C=()=>{let T=this.onAddColumn(x.value);if(T){new Vt.Notice(T);return}n()};y.addEventListener("click",C),x.addEventListener("keydown",T=>{T.key==="Enter"&&(T.preventDefault(),C())});let E=e.createDiv({cls:"csv-modal-row"});E.createEl("label",{text:"Default view",cls:"csv-modal-label"});let D=E.createEl("select",{cls:"csv-modal-select"}),w=[["\u2014 use global default \u2014",""],...this.availableModes.map(T=>[T.label,T.id])],M=(P=this.current.defaultMode)!=null?P:"";M&&!this.availableModes.some(T=>T.id===M)&&w.push([`${M} (no longer available)`,M]),w.forEach(([T,U])=>{let F=D.createEl("option",{text:T,value:U});M===U&&(F.selected=!0)}),D.addEventListener("change",()=>{this.current.defaultMode=D.value?D.value:void 0});let L=t.createDiv({cls:"csv-modal-btns"});L.createEl("button",{text:"Cancel",cls:"csv-modal-cancel"}).addEventListener("click",()=>this.close()),L.createEl("button",{text:"Save",cls:"csv-modal-submit"}).addEventListener("click",()=>{this.onSave(this.current),this.close()})}onClose(){this.contentEl.empty()}},vn=class extends Vt.Modal{constructor(e,n,i,o,r){super(e);this.title=n;this.initial=i;this.placeholder=o;this.onSubmit=r}onOpen(){let{contentEl:e}=this;e.empty(),e.addClass("csv-add-modal"),e.createEl("h2",{text:this.title,cls:"csv-modal-title"});let n=e.createEl("input",{cls:"csv-modal-field",type:"text"});n.value=this.initial,n.placeholder=this.placeholder,window.setTimeout(()=>{n.focus(),n.select()},0);let i=()=>{let r=n.value.trim();r&&(this.onSubmit(r),this.close())};n.addEventListener("keydown",r=>{r.key==="Enter"&&(r.preventDefault(),i())});let o=e.createDiv({cls:"csv-modal-btns"});o.createEl("button",{text:"Cancel",cls:"csv-modal-cancel"}).addEventListener("click",()=>this.close()),o.createEl("button",{text:"Create",cls:"csv-modal-submit"}).addEventListener("click",i)}onClose(){this.contentEl.empty()}};var Ei=195,Ic={AF:"Afghanistan",AL:"Albania",DZ:"Algeria",AD:"Andorra",AO:"Angola",AR:"Argentina",AM:"Armenia",AU:"Australia",AT:"Austria",AZ:"Azerbaijan",BD:"Bangladesh",BY:"Belarus",BE:"Belgium",BO:"Bolivia",BA:"Bosnia",BW:"Botswana",BR:"Brazil",BG:"Bulgaria",KH:"Cambodia",CM:"Cameroon",CA:"Canada",CL:"Chile",CN:"China",CO:"Colombia",HR:"Croatia",CU:"Cuba",CY:"Cyprus",CZ:"Czechia",DK:"Denmark",DO:"Dominican Rep.",EC:"Ecuador",EG:"Egypt",ET:"Ethiopia",FI:"Finland",FR:"France",GE:"Georgia",DE:"Germany",GH:"Ghana",GR:"Greece",GT:"Guatemala",GY:"Guyana",HT:"Haiti",HN:"Honduras",HU:"Hungary",IS:"Iceland",IN:"India",ID:"Indonesia",IR:"Iran",IQ:"Iraq",IE:"Ireland",IL:"Israel",IT:"Italy",JP:"Japan",JO:"Jordan",KZ:"Kazakhstan",KE:"Kenya",KP:"N. Korea",KR:"S. Korea",KW:"Kuwait",KG:"Kyrgyzstan",LA:"Laos",LV:"Latvia",LB:"Lebanon",LY:"Libya",LI:"Liechtenstein",LT:"Lithuania",LU:"Luxembourg",MY:"Malaysia",ML:"Mali",MT:"Malta",MR:"Mauritania",MX:"Mexico",MD:"Moldova",MN:"Mongolia",ME:"Montenegro",MA:"Morocco",MZ:"Mozambique",MM:"Myanmar",NA:"Namibia",NP:"Nepal",NL:"Netherlands",NZ:"New Zealand",NI:"Nicaragua",NE:"Niger",NG:"Nigeria",NO:"Norway",OM:"Oman",PK:"Pakistan",PA:"Panama",PG:"Papua New Guinea",PY:"Paraguay",PE:"Peru",PH:"Philippines",PL:"Poland",PT:"Portugal",QA:"Qatar",RO:"Romania",RU:"Russia",RW:"Rwanda",SA:"Saudi Arabia",SN:"Senegal",RS:"Serbia",SG:"Singapore",SK:"Slovakia",SI:"Slovenia",SO:"Somalia",ZA:"South Africa",SS:"South Sudan",ES:"Spain",LK:"Sri Lanka",SD:"Sudan",SE:"Sweden",CH:"Switzerland",SY:"Syria",TJ:"Tajikistan",TZ:"Tanzania",TH:"Thailand",TN:"Tunisia",TR:"Turkey",TM:"Turkmenistan",UG:"Uganda",UA:"Ukraine",AE:"UAE",GB:"United Kingdom",US:"United States",UY:"Uruguay",UZ:"Uzbekistan",VN:"Vietnam",YE:"Yemen",ZM:"Zambia",ZW:"Zimbabwe",MC:"Monaco",BZ:"Belize"},Vc={AF:["DZ","AO","BJ","BW","BF","BI","CM","CV","CF","TD","KM","CD","CG","CI","DJ","EG","GQ","ER","ET","GA","GM","GH","GN","GW","KE","LS","LR","LY","MG","MW","ML","MR","MU","MA","MZ","NA","NE","NG","RE","RW","ST","SN","SC","SL","SO","ZA","SS","SD","TZ","TG","TN","UG","ZM","ZW"],AN:["AQ"],AS:["AF","AM","AZ","BH","BD","BT","BN","KH","CN","CY","GE","IN","ID","IR","IQ","IL","JP","JO","KZ","KW","KG","LA","LB","MY","MV","MN","MM","NP","KP","OM","PK","PS","PH","QA","RU","SA","SG","KR","LK","SY","TW","TJ","TH","TL","TR","TM","AE","UZ","VN","YE"],EU:["AL","AD","AT","BY","BE","BA","BG","HR","CZ","DK","EE","FI","FR","DE","GR","HU","IS","IE","IT","XK","LV","LI","LT","LU","MT","MD","MC","ME","NL","MK","NO","PL","PT","RO","RU","SM","RS","SK","SI","ES","SE","CH","UA","GB","VA"],NA:["AG","BS","BB","BZ","CA","CR","CU","DM","DO","SV","GD","GT","HT","HN","JM","MX","NI","PA","KN","LC","VC","TT","US"],OC:["AU","FJ","KI","MH","FM","NR","NZ","PW","PG","WS","SB","TO","TV","VU"],SA:["AR","BO","BR","CL","CO","EC","GY","PY","PE","SR","UY","VE"]},ar={AF:"Africa",AN:"Antarctica",AS:"Asia",EU:"Europe",NA:"N. America",OC:"Oceania",SA:"S. America"},lr={};for(let[s,t]of Object.entries(Vc))for(let e of t)lr[e]=s;function Dt(s){return Ic[s]||s}function jt(s){return!s||s.length!==2?"":String.fromCodePoint(...s.toUpperCase().split("").map(t=>t.charCodeAt(0)+127397))}function Bt(s){if(!s||s.indexOf("?")!==-1)return null;let t=new Date(s+"T12:00:00Z");return isNaN(t.getTime())?null:t}function Fs(s){let t=Bt(s.date_entered),e=Bt(s.date_left);return!t||!e?0:Math.max(Math.round((e.getTime()-t.getTime())/864e5),1)}function cr(s,t=new Date){let e=t.getTime(),n=null,i=-1/0;for(let o of s){let r=Bt(o.date_entered);if(!(!r||r.getTime()>e)){if(o.date_left.trim()!==""){let a=Bt(o.date_left);if(!a||a.getTime()i&&(n=o,i=r.getTime())}}return n}function dr(s){let t=m=>{var v,_,k,S,x,y,C,E;return{date_entered:(v=m.date_entered)!=null?v:"",date_left:(_=m.date_left)!=null?_:"",country:((k=m.country)!=null?k:"").trim().toUpperCase(),city:(S=m.city)!=null?S:"",visa_status:(x=m.visa_status)!=null?x:"",notes:(y=m.notes)!=null?y:"",source:((C=m.source)!=null?C:"").trim().toLowerCase(),resolved:(E=m.resolved)!=null?E:"",_src:m}},e=s.map(t).filter(m=>m.country),n=e.filter(m=>m.source==="confirmed"),i=e.filter(m=>m.source==="inferred"),o=e.filter(m=>m.source==="conflict"),r=[];for(let m of n){let v=Bt(m.date_entered),_=Bt(m.date_left);v&&_&&r.push([v.getTime(),_.getTime()])}let a=m=>{let v=Bt(m.date_entered),_=Bt(m.date_left);if(!v||!_)return!1;let k=v.getTime(),S=_.getTime();return r.some(([x,y])=>k<=y&&S>=x)},l=i.filter(m=>Bt(m.date_entered)&&Bt(m.date_left)&&!a(m)),c=new Set(n.map(m=>m.country)),d=new Set(i.map(m=>m.country)),h=new Set([...d].filter(m=>!c.has(m))),u=new Set([...c,...d]),f=new Map;for(let m of n)f.set(m.country,(f.get(m.country)||0)+Fs(m));let g=[...f.entries()].map(([m,v])=>({iso:m,days:v})).sort((m,v)=>v.days-m.days||Dt(m.iso).localeCompare(Dt(v.iso))),p=g.reduce((m,v)=>m+v.days,0),b=new Set;for(let m of c){let v=lr[m];v&&b.add(v)}return{confirmed:n,inferred:i,conflicts:o,inferredVisible:l,confRanges:r,confirmedCountries:c,inferredOnlyCountries:h,allCountries:u,countryDays:g,totalConfirmedDays:p,visitedContinents:b,worldPct:Math.round(c.size/Ei*100)}}var Di=864e5;function hr(s){if(!s||s.indexOf("?")!==-1)return null;let t=Date.parse(s+"T00:00:00Z");return isNaN(t)?null:t}function Nc(s,t,e,n){let i=Math.max(s,e),o=Math.min(t,n);return o<=i?0:Math.round((o-i)/Di)}function Bc(s,t){var i;let e=s.window;if(e.type==="all-time")return{start:-1/0,end:1/0,label:"all time"};if(e.type==="calendar-year"){let o=new Date(t).getUTCFullYear();return{start:Date.UTC(o,0,1),end:Date.UTC(o+1,0,1),label:`in ${o}`}}let n=(i=e.days)!=null?i:180;return{start:t-n*Di,end:t+Di,label:`in last ${n} days`}}function ur(s,t,e=Date.now()){var d,h,u;let n=(d=s.scope.countries)!=null?d:s.scope.country?[s.scope.country]:[],i=new Set(n.map(f=>f.toUpperCase())),o=new Set(((u=(h=s.exempt)==null?void 0:h.visa_status)!=null?u:[]).map(f=>f.toLowerCase().trim())),r=Bc(s,e),a=0;for(let f of t){if(!i.has((f.country||"").toUpperCase())||o.has((f.visa_status||"").toLowerCase().trim()))continue;let g=hr(f.date_entered),p=hr(f.date_left);g===null||p===null||(a+=Nc(g,p,r.start,r.end))}let l=s.threshold-a,c=a>=s.threshold?"over":a/s.threshold>=.8?"warn":"ok";return{rule:s,used:a,threshold:s.threshold,remaining:l,windowLabel:r.label,status:c}}var fr=["#c9a96e","#4a6fa5","#5ba06e","#a05b8a","#6ea0a0","#a0855b","#7a6ea0","#a06e6e","#6e8fa0","#a09e5b"],$c=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function Hc(){let s=new Map,t=0;return e=>(s.has(e)||s.set(e,fr[t++%fr.length]),s.get(e))}function zc(s){let t=document.body.createDiv({cls:"csv-tv-tooltip"}),e=null,n=(r,a)=>{let c=r+14,d=a+16,h=t.offsetWidth,u=t.offsetHeight;c+h+8>window.innerWidth&&(c=r-h-14),d+u+8>window.innerHeight&&(d=a-u-16),t.style.left=`${Math.max(8,c)}px`,t.style.top=`${Math.max(8,d)}px`},i=r=>{var c,d;let a=(d=(c=r.target)==null?void 0:c.closest("[data-tip]"))!=null?d:null,l=(a==null?void 0:a.getAttribute("data-tip"))||"";if(!a||!l){e&&(e=null,t.removeClass("is-on"));return}a!==e&&(e=a,t.setText(l),t.addClass("is-on")),n(r.clientX,r.clientY)},o=()=>{e=null,t.removeClass("is-on")};return s.addEventListener("pointermove",i),s.addEventListener("pointerleave",o),()=>{s.removeEventListener("pointermove",i),s.removeEventListener("pointerleave",o),t.remove()}}function Mi(s){let t=Fs(s);return t?`${t}d`:"\u2014"}function ls(s){return s||"\u2014"}function Vs(s){return s.createDiv({cls:"csv-tv-table-wrap"}).createEl("table",{cls:"csv-tv-table"})}function Is(s,t,e,n){s.addClass("csv-tv-editable"),s.title="Click to edit";let i=()=>{s.empty(),s.setText(t[e]?t[e]:"\u2014")};i(),s.addEventListener("click",()=>{var r;if(s.querySelector("input"))return;s.empty();let o=yn(s,e,(r=t[e])!=null?r:"","csv-inline-input");o.focus(),o.type==="text"&&o.select(),o.addEventListener("blur",()=>{t[e]=o.value,n(),i()}),o.addEventListener("keydown",a=>{var l;a.key==="Enter"&&o.blur(),a.key==="Escape"&&(o.value=(l=t[e])!=null?l:"",o.blur())})})}async function gr(s,t,e,n=()=>{},i=null,o=()=>{}){let r=dr(t),a=s.createDiv({cls:"csv-tv"});if(!r.confirmed.length&&!r.inferred.length){a.createDiv({cls:"csv-empty-state",text:"No travel rows found. Expected columns: country, date_entered, date_left, source."});return}o(zc(a));let l=null,c=()=>{a.querySelectorAll(".country-path").forEach(f=>{let g=(f.getAttribute("data-iso")||"").toUpperCase();f.classList.toggle("cp-selected",!!l&&g===l)}),a.querySelectorAll(".csv-tv-seg").forEach(f=>{f.classList.toggle("is-dim",!!l&&f.getAttribute("data-iso")!==l)}),a.querySelectorAll("tr[data-iso]").forEach(f=>{f.classList.toggle("is-selected",!!l&&f.getAttribute("data-iso")===l)}),u.empty(),l&&(Uc(u,r,l,()=>d(null)),u.scrollIntoView({behavior:"smooth",block:"nearest"}))},d=f=>{l=f&&f!==l?f:null,c()};Wc(a,r);let h=a.createDiv({cls:"csv-tv-mapwrap"});h.createDiv({cls:"csv-tv-map-loading",text:"Loading map\u2026"});let u=a.createDiv({cls:"csv-tv-detailwrap"});i&&i.length&&Yc(a,r.confirmed,i),Gc(a,r,d),Kc(a,r,d),qc(a,r,n);try{let f=await e();h.empty(),f?jc(h,f,r,d):h.createDiv({cls:"csv-tv-map-loading",text:"World map asset not found (world-map.svg)."})}catch(f){h.empty(),h.createDiv({cls:"csv-tv-map-loading",text:"Couldn't load world map."})}}function Wc(s,t){let e=s.createDiv({cls:"csv-tv-stats"}),n=(c,d,h="")=>{let u=e.createDiv({cls:"csv-tv-stat"});u.createDiv({cls:"csv-tv-stat-label",text:c}),u.createDiv({cls:"csv-tv-stat-value",text:d}),h&&u.createDiv({cls:"csv-tv-stat-sub",text:h})},i=Math.round(t.allCountries.size/Ei*100);n("Countries",String(t.confirmedCountries.size),`${t.worldPct}% of world`),n("Incl. photos",String(t.allCountries.size),`${i}% of world`),n("Continents",`${t.visitedContinents.size} / 7`,[...t.visitedContinents].map(c=>ar[c]||c).sort().join(", ")),n("Confirmed trips",String(t.confirmed.length)),n("Confirmed days",String(t.totalConfirmedDays));let o=new Set(t.confirmed.map(c=>c.city.trim().toLowerCase()).filter(Boolean));o.size&&n("Cities",String(o.size));let r=null,a=0;for(let c of t.confirmed){let d=Fs(c);d>a&&(a=d,r=c)}if(r){let c=r.date_entered.slice(0,4);n("Longest trip",`${a}d`,`${jt(r.country)} ${Dt(r.country)}${c?` \xB7 ${c}`:""}`)}let l=cr(t.confirmed);if(l){let c=Bt(l.date_entered),d=Math.max(1,Math.round((Date.now()-c.getTime())/864e5)+1),h=s.createDiv({cls:"csv-tv-now"});h.createSpan({cls:"csv-tv-now-loc",text:`\u{1F4CD} Currently in ${jt(l.country)} ${Dt(l.country)}`}),h.createSpan({cls:"csv-tv-now-sub",text:` \u2014 since ${l.date_entered} (day ${d})${l.city?` \xB7 ${l.city}`:""}`})}}function jc(s,t,e,n){let i=s.createDiv({cls:"csv-tv-map"});i.innerHTML=t,i.querySelectorAll(".country-path").forEach(r=>{let a=(r.getAttribute("data-iso")||"").toUpperCase();if(r.classList.remove("cp-unvisited","cp-confirmed","cp-inferred"),a&&e.confirmedCountries.has(a)){r.classList.add("cp-confirmed");let l=e.countryDays.find(c=>c.iso===a);r.setAttr("aria-label",`${Dt(a)} \u2014 ${l&&l.days?l.days+"d confirmed":"confirmed"}`),r.setAttr("data-tip",`${Dt(a)}${l&&l.days?" \xB7 "+l.days+"d":""} \xB7 click for trips`)}else a&&e.inferredOnlyCountries.has(a)?(r.classList.add("cp-inferred"),r.setAttr("aria-label",`${Dt(a)} \u2014 photo evidence`),r.setAttr("data-tip",`${Dt(a)} \xB7 photo evidence \xB7 click for trips`)):a?(r.classList.add("cp-unvisited"),r.setAttr("data-tip",Dt(a))):r.classList.add("cp-unvisited");a&&r.addEventListener("click",()=>{e.allCountries.has(a)?n(a):n(null)})}),i.querySelectorAll(".country-path").forEach(r=>{try{let a=r.getBoundingClientRect();a.width&&a.height&&Math.max(a.width,a.height)<12&&r.classList.add("cp-tiny")}catch(a){}});let o=s.createDiv({cls:"csv-tv-map-legend"});o.createSpan({cls:"csv-tv-leg"}).innerHTML=' Confirmed',o.createSpan({cls:"csv-tv-leg"}).innerHTML=' Photo evidence'}function Uc(s,t,e,n){var b,m;let i=s.createDiv({cls:"csv-tv-detail"}),o=i.createDiv({cls:"csv-tv-detail-head"});o.createSpan({cls:"csv-tv-detail-flag",text:jt(e)});let r=o.createDiv({cls:"csv-tv-detail-titles"});r.createDiv({cls:"csv-tv-detail-name",text:Dt(e)});let a=t.confirmed.filter(v=>v.country===e),l=t.inferred.filter(v=>v.country===e),c=(m=(b=t.countryDays.find(v=>v.iso===e))==null?void 0:b.days)!=null?m:0,d=new Set([...a,...l].map(v=>v.city.trim()).filter(Boolean)),h=[];a.length&&h.push(`${a.length} confirmed trip${a.length===1?"":"s"}`),c&&h.push(`${c}d total`),l.length&&h.push(`${l.length} photo-inferred`),d.size&&h.push(`${d.size} cit${d.size===1?"y":"ies"}`),r.createDiv({cls:"csv-tv-detail-sub",text:h.join(" \xB7 ")}),o.createEl("button",{cls:"csv-tv-detail-close",text:"\u2715",title:"Close"}).addEventListener("click",n);let u=xn([...a.map(v=>({r:v,inf:!1,date_entered:v.date_entered})),...l.map(v=>({r:v,inf:!0,date_entered:v.date_entered}))]);if(!u.length)return;let f=Vs(i),g=f.createEl("thead").createEl("tr");["","Entered","Left","Days","City","Visa"].forEach(v=>g.createEl("th",{text:v}));let p=f.createEl("tbody");for(let{r:v,inf:_}of u){let k=p.createEl("tr");k.createEl("td",{text:_?"\u{1F4F7}":"",cls:"csv-tv-flag",attr:_?{"data-tip":"Photo-inferred"}:{}}),k.createEl("td",{text:ls(v.date_entered)}),k.createEl("td",{text:ls(v.date_left)}),k.createEl("td",{text:Mi(v)}),k.createEl("td",{text:v.city}),k.createEl("td",{text:v.visa_status})}}function Yc(s,t,e){s.createDiv({cls:"csv-tv-sec-title",text:"Residency counters"});let n=s.createDiv({cls:"csv-tv-res-grid"});for(let i of e){let o=ur(i,t),r=n.createDiv({cls:`csv-tv-res-card csv-tv-res-${o.status}`});r.createDiv({cls:"csv-tv-res-label",text:i.label});let a=r.createDiv({cls:"csv-tv-res-nums"});a.createSpan({cls:"csv-tv-res-used",text:String(o.used)}),a.createSpan({cls:"csv-tv-res-thresh",text:` / ${o.threshold}`}),a.createSpan({cls:"csv-tv-res-window",text:` ${o.windowLabel}`});let l=r.createDiv({cls:"csv-tv-res-bar"});l.createDiv({cls:"csv-tv-res-fill"}).style.width=`${Math.min(100,Math.round(o.used/o.threshold*100))}%`;let c=o.status==="over"?i.onExceed?`Over \u2014 ${i.onExceed}`:"Limit reached":`${o.remaining} day${o.remaining===1?"":"s"} left`;r.createDiv({cls:"csv-tv-res-status",text:c}),i.note&&r.createDiv({cls:"csv-tv-res-note",text:i.note})}s.createDiv({cls:"csv-tv-res-disclaimer",text:"Indicators only \u2014 not legal or tax advice. Based on confirmed trips."})}function Gc(s,t,e){s.createDiv({cls:"csv-tv-sec-title",text:"Countries visited"});let n=Vs(s),i=n.createEl("thead").createEl("tr");["","Country","Total days"].forEach(r=>i.createEl("th",{text:r}));let o=n.createEl("tbody");for(let{iso:r,days:a}of t.countryDays){let l=o.createEl("tr",{cls:"csv-tv-row-click",attr:{"data-iso":r}});l.createEl("td",{text:jt(r),cls:"csv-tv-flag"}),l.createEl("td",{text:Dt(r)}),l.createEl("td",{text:a?`${a}d`:"\u2014"}),l.addEventListener("click",()=>e(r))}if(t.inferredOnlyCountries.size){let r=s.createDiv({cls:"csv-tv-photo-only"});r.createSpan({text:"\u{1F4F7} Photo evidence only: "}),r.createSpan({text:[...t.inferredOnlyCountries].sort().map(jt).join(" ")})}}function Kc(s,t,e){s.createDiv({cls:"csv-tv-sec-title",text:"Timeline"});let n=Hc(),i=[...t.confirmed.map(c=>({...c,_inf:!1})),...t.inferredVisible.map(c=>({...c,_inf:!0}))].filter(c=>c.date_entered&&c.date_left&&c.date_entered.indexOf("?")===-1),o=new Map;for(let c of i){let d=parseInt(c.date_entered.slice(0,4)),h=parseInt(c.date_left.slice(0,4));if(!(isNaN(d)||isNaN(h)))for(let u=d;u<=h;u++)o.has(u)||o.set(u,[]),o.get(u).push(c)}let r=[...o.keys()].sort((c,d)=>d-c),a=s.createDiv({cls:"csv-tv-timeline"});for(let c of r){let d=new Date(`${c}-01-01T12:00:00Z`).getTime(),h=new Date(`${c}-12-31T12:00:00Z`).getTime(),u=h-d,f=a.createDiv({cls:"csv-tv-tl-year"}),g=0,p=new Set;for(let _ of o.get(c)){if(p.add(_.country),_._inf)continue;let k=Math.max(new Date(_.date_entered+"T12:00:00Z").getTime(),d),S=Math.min(new Date(_.date_left+"T12:00:00Z").getTime(),h);k<=S&&(g+=Math.max(Math.round((S-k)/864e5)+1,1))}let b=f.createDiv({cls:"csv-tv-tl-label"});b.createSpan({text:String(c)}),b.createSpan({cls:"csv-tv-tl-sub",text:`${g?`${g}d \xB7 `:""}${p.size} ${p.size===1?"country":"countries"}`});let m=f.createDiv({cls:"csv-tv-month-row"});$c.forEach(_=>m.createDiv({cls:"csv-tv-month-tick",text:_}));let v=f.createDiv({cls:"csv-tv-track"});for(let _ of o.get(c)){let k=Math.max(new Date(_.date_entered+"T12:00:00Z").getTime(),d),S=Math.min(new Date(_.date_left+"T12:00:00Z").getTime(),h);if(k>S)continue;let x=(k-d)/u*100,y=Math.max((S-k+864e5)/u*100,.5),C=n(_.country),E=v.createDiv({cls:`csv-tv-seg${_._inf?" csv-tv-seg-inf":""}`});E.style.left=`${x}%`,E.style.width=`${y}%`,_._inf?(E.style.borderColor=C,E.style.background=C+"22",E.style.color=C):E.style.background=C,E.setAttr("data-iso",_.country),E.setAttr("data-tip",`${Dt(_.country)} ${_.date_entered} \u2192 ${_.date_left} (${Fs(_)}d)${_.visa_status?" ["+_.visa_status+"]":""}${_._inf?" [photo]":""}`),E.addEventListener("click",()=>e(_.country)),y>4?E.createSpan({cls:"csv-tv-seg-lbl",text:`${jt(_.country)} ${_.country}`}):y>2&&E.createSpan({cls:"csv-tv-seg-lbl",text:jt(_.country)})}}a.createDiv({cls:"csv-tv-tl-legend"}).setText("Confirmed (solid) \xB7 Photo inferred (outlined)")}function xn(s){return[...s].sort((t,e)=>!t.date_entered&&!e.date_entered?0:t.date_entered?e.date_entered?e.date_entered.localeCompare(t.date_entered):-1:1)}function qc(s,t,e){s.createDiv({cls:"csv-tv-sec-title",text:"Confirmed trips"}),s.createDiv({cls:"csv-tv-edit-hint",text:"Dates, city, visa and notes are editable \u2014 click a cell. Edit country in Table view."});let n=Vs(s),i=n.createEl("thead").createEl("tr");["","Country","Entered","Left","Duration","City","Visa","Notes"].forEach(r=>i.createEl("th",{text:r}));let o=n.createEl("tbody");for(let r of xn(t.confirmed)){let a=o.createEl("tr");a.createEl("td",{text:jt(r.country),cls:"csv-tv-flag"}),a.createEl("td",{text:Dt(r.country)}),Is(a.createEl("td"),r._src,"date_entered",e),Is(a.createEl("td"),r._src,"date_left",e),a.createEl("td",{text:Mi(r)}),Is(a.createEl("td"),r._src,"city",e),Is(a.createEl("td"),r._src,"visa_status",e),Is(a.createEl("td"),r._src,"notes",e)}if(t.inferred.length){let r=s.createEl("details",{cls:"csv-tv-details"});r.createEl("summary",{text:`\u{1F4F7} Photo inferred trips (${t.inferred.length})`});let a=Vs(r),l=a.createEl("thead").createEl("tr");["","Country","Entered","Left","Days","City"].forEach(d=>l.createEl("th",{text:d}));let c=a.createEl("tbody");for(let d of xn(t.inferred)){let h=c.createEl("tr");h.createEl("td",{text:jt(d.country),cls:"csv-tv-flag"}),h.createEl("td",{text:Dt(d.country)}),h.createEl("td",{text:ls(d.date_entered)}),h.createEl("td",{text:ls(d.date_left)}),h.createEl("td",{text:Mi(d)}),h.createEl("td",{text:d.city})}}if(t.conflicts.length){let r=s.createEl("details",{cls:"csv-tv-details csv-tv-details-warn"});r.createEl("summary",{text:`\u26A0 ${t.conflicts.length} conflict(s) \u2014 photo evidence contradicts a confirmed entry`});let a=Vs(r),l=a.createEl("thead").createEl("tr");["","Country (photos)","Dates","Detail"].forEach(d=>l.createEl("th",{text:d}));let c=a.createEl("tbody");for(let d of xn(t.conflicts)){let h=c.createEl("tr");h.createEl("td",{text:jt(d.country),cls:"csv-tv-flag"}),h.createEl("td",{text:d.country}),h.createEl("td",{text:`${ls(d.date_entered)} \u2192 ${ls(d.date_left)}`}),h.createEl("td",{text:d.notes})}}}var Nt=require("obsidian"),Cn=class extends Nt.PluginSettingTab{constructor(t,e){super(t,e),this.plugin=e}display(){let{containerEl:t}=this;t.empty(),t.createEl("h2",{text:"DataDeck"}),new Nt.Setting(t).setName("Default view mode").addDropdown(n=>n.addOption("kanban-genre","Kanban").addOption("table","Table").setValue(this.plugin.settings.defaultMode).onChange(async i=>{this.plugin.settings.defaultMode=i,await this.plugin.saveSettings()})),new Nt.Setting(t).setName("Status column name").addText(n=>n.setValue(this.plugin.settings.statusColumn).onChange(async i=>{this.plugin.settings.statusColumn=i,await this.plugin.saveSettings()})),new Nt.Setting(t).setName("Category/Genre column name").addText(n=>n.setValue(this.plugin.settings.categoryColumn).onChange(async i=>{this.plugin.settings.categoryColumn=i,await this.plugin.saveSettings()})),new Nt.Setting(t).setName("Notes column names").setDesc("Comma-separated.").addText(n=>n.setValue(this.plugin.settings.notesColumns.join(", ")).onChange(async i=>{this.plugin.settings.notesColumns=i.split(",").map(o=>o.trim()),await this.plugin.saveSettings()})),new Nt.Setting(t).setName("Select/dropdown columns").setDesc("Comma-separated column names that use a dropdown picker.").addText(n=>n.setValue(this.plugin.settings.selectColumns.join(", ")).onChange(async i=>{this.plugin.settings.selectColumns=i.split(",").map(o=>o.trim()),await this.plugin.saveSettings()})),new Nt.Setting(t).setName("Notes subfolder").addText(n=>n.setPlaceholder("Notes").setValue(this.plugin.settings.notesSubfolder).onChange(async i=>{this.plugin.settings.notesSubfolder=i,await this.plugin.saveSettings()})),new Nt.Setting(t).setName("Reset column widths").addButton(n=>n.setButtonText("Reset").onClick(async()=>{this.plugin.settings.columnWidths={},await this.plugin.saveSettings(),new Nt.Notice("Column widths reset.")})),new Nt.Setting(t).setName("Residency counters (travel view)").setDesc("Show residency / tax day-gauges in the travel view.").addToggle(n=>n.setValue(this.plugin.settings.showResidency!==!1).onChange(async i=>{this.plugin.settings.showResidency=i,await this.plugin.saveSettings()})),t.createEl("h3",{text:"Residency rules"}),t.createEl("p",{cls:"setting-item-description",text:"Each rule counts days in the listed countries within the window, minus exempt visa rows, against the threshold. Counts confirmed trips only. Indicators, not legal/tax advice."});let e=t.createDiv({cls:"csv-rr-wrap"});this.renderResidencyRules(e)}renderResidencyRules(t){var o;t.empty();let e=(o=this.plugin.settings.residencyRules)!=null?o:this.plugin.settings.residencyRules=[],n=()=>void this.plugin.saveSettings();e.forEach((r,a)=>{var m,v,_,k,S,x;let l=t.createDiv({cls:"csv-rr-card"}),c=l.createDiv({cls:"csv-rr-head"}),d=c.createEl("input",{cls:"csv-rr-label",type:"text",value:r.label});d.placeholder="Label (e.g. \u{1F1EA}\u{1F1FA} Schengen 90/180)",d.addEventListener("input",()=>{r.label=d.value,n()});let h=c.createEl("button",{cls:"csv-rr-del",text:"\u2715"});h.setAttr("aria-label","Remove rule"),h.addEventListener("click",async()=>{e.splice(a,1),await this.plugin.saveSettings(),this.renderResidencyRules(t)});let u=l.createDiv({cls:"csv-rr-grid"}),f=(y,C,E,D="")=>{let w=u.createDiv({cls:"csv-rr-field"});w.createEl("label",{text:y});let M=w.createEl("input",{type:"text",value:C});D&&(M.placeholder=D),M.addEventListener("input",()=>{E(M.value),n()})},g=(m=r.scope.countries)!=null?m:r.scope.country?[r.scope.country]:[];f("Countries (ISO-2, comma)",g.join(", "),y=>{r.scope={countries:y.split(",").map(C=>C.trim().toUpperCase()).filter(Boolean)}},"US, GB");let p=u.createDiv({cls:"csv-rr-field"});p.createEl("label",{text:"Window"});let b=p.createEl("select");[["calendar-year","Calendar year"],["rolling","Rolling N days"],["all-time","All time"]].forEach(([y,C])=>{let E=b.createEl("option",{text:C,value:y});r.window.type===y&&(E.selected=!0)}),b.addEventListener("change",()=>{r.window={type:b.value,days:r.window.days},n(),this.renderResidencyRules(t)}),r.window.type==="rolling"&&f("Rolling days",String((v=r.window.days)!=null?v:180),y=>{let C=parseInt(y,10);r.window.days=isNaN(C)?void 0:C},"180"),f("Threshold (days)",String(r.threshold),y=>{let C=parseInt(y,10);r.threshold=isNaN(C)?0:C},"183"),f("Exempt visas (comma)",((k=(_=r.exempt)==null?void 0:_.visa_status)!=null?k:[]).join(", "),y=>{let C=y.split(",").map(E=>E.trim()).filter(Boolean);r.exempt=C.length?{visa_status:C}:void 0},"F-1, J-1"),f("On-exceed label",(S=r.onExceed)!=null?S:"",y=>{r.onExceed=y||void 0},"tax resident"),f("Note",(x=r.note)!=null?x:"",y=>{r.note=y||void 0},"optional caveat")}),t.createDiv({cls:"csv-rr-btns"}).createEl("button",{cls:"csv-rr-add",text:"+ Add rule"}).addEventListener("click",async()=>{e.push({label:"New rule",scope:{countries:[]},window:{type:"calendar-year"},threshold:183}),await this.plugin.saveSettings(),this.renderResidencyRules(t)})}};var ve=require("obsidian"),pr=Os(ts());async function mr(s,t,e,n,i={}){var F,G,H;let o=t.split(` `).map(A=>A.trim()).filter(Boolean),r="";for(let A of o)if(A.startsWith("file:")){r=A.replace("file:","").trim();break}if(!r){e.createEl("p",{text:"Error: No file specified. Use: file: yourfile.csv",cls:"csv-add-error"});return}let a=s.vault.getAbstractFileByPath(n.sourcePath),l=(G=(F=a==null?void 0:a.parent)==null?void 0:F.path)!=null?G:"",c=Qt(r,l),d=s.vault.getAbstractFileByPath(c);if(!d||!(d instanceof ve.TFile)){e.createEl("p",{text:`Error: File not found: ${c}`,cls:"csv-add-error"});return}let h=(H=i[c])!=null?H:{},u=[],f=[];try{let A=await s.vault.read(d),j=wt(A);u=j.headers,f=j.rows}catch(A){e.createEl("p",{text:`Error reading file: ${A}`,cls:"csv-add-error"});return}if(!u.length){e.createEl("p",{text:"Error: No columns found in file",cls:"csv-add-error"});return}let g=A=>{let j=A.toLowerCase();if(["date","day","datum"].includes(j))return!0;let Y=f.slice(0,5).map($=>{var R;return(R=$[A])!=null?R:""});return Y.length>0&&Y.every($=>/^\d{4}-\d{2}-\d{2}$/.test($))},p=A=>{let j=A.toLowerCase();return["notes","note","comments","description","journal"].includes(j)},b=h.habitColumns?h.habitColumns.filter(A=>u.includes(A)):u.filter(A=>!g(A)&&is(f.map(j=>{var Y;return((Y=j[A])!=null?Y:"").toLowerCase().trim()}))),m=u.filter(A=>g(A)),v=u.filter(A=>p(A)),_=u.filter(A=>!b.includes(A)&&!m.includes(A)&&!v.includes(A)),k=h.titleColumn?u.find(A=>A.toLowerCase()===h.titleColumn.toLowerCase()):u.find(A=>["title","name"].includes(A.toLowerCase())),S=e.createDiv({cls:"csv-add-form csv-add-compact"}),x=S.createEl("button",{cls:"csv-add-trigger",text:"+ New entry"});x.style.display="none";let y=S.createDiv({cls:"csv-add-card"}),C=y.createDiv({cls:"csv-add-card-header"});C.createEl("span",{cls:"csv-add-card-title",text:"New entry"});let E=C.createEl("button",{cls:"csv-add-card-close",text:"\xD7"}),D=y.createDiv({cls:"csv-add-rows"}),w={},M={},L=(A,j)=>{let Y=D.createDiv({cls:`csv-add-row csv-add-row-${j}`});return Y.createEl("span",{cls:"csv-add-row-label",text:Tt(A)}),Y};m.forEach(A=>{let Y=L(A,"date").createEl("input",{cls:"csv-add-row-control",type:"date"});Y.value=me(),w[A]=Y}),b.forEach(A=>{M[A]=!1;let Y=L(A,"toggle").createEl("label",{cls:"csv-add-switch"}),$=Y.createEl("input",{type:"checkbox",cls:"csv-add-switch-input"});Y.createEl("span",{cls:"csv-add-switch-track"}),$.addEventListener("change",()=>{M[A]=$.checked}),w[A]=$}),_.forEach(A=>{let j=L(A,"field"),Y=new Set(f.map(R=>{var B;return((B=R[A])!=null?B:"").trim()}).filter(Boolean));if(A!==k&&(h.categoricalColumns?h.categoricalColumns.includes(A):Xt(Y.size))){let R=j.createEl("select",{cls:"csv-add-row-control"});R.createEl("option",{text:"\u2014",value:""}),Array.from(Y).sort().forEach(N=>R.createEl("option",{text:N,value:N})),R.createEl("option",{text:"+ Custom",value:"__custom__"});let B=D.createDiv({cls:"csv-add-row csv-add-row-custom"});B.style.display="none";let z=B.createEl("input",{cls:"csv-add-row-control",type:"text",placeholder:`Custom ${Tt(A).toLowerCase()}`});D.insertBefore(B,j.nextSibling),R.addEventListener("change",()=>{B.style.display=R.value==="__custom__"?"flex":"none",R.value==="__custom__"&&z.focus()}),w[A]=R,w[`${A}__custom`]=z}else w[A]=j.createEl("input",{cls:"csv-add-row-control",type:"text",placeholder:Tt(A)})}),v.forEach(A=>{let j=D.createDiv({cls:"csv-add-row csv-add-row-notes"});j.createEl("span",{cls:"csv-add-row-label",text:Tt(A)}),w[A]=j.createEl("textarea",{cls:"csv-add-row-textarea",placeholder:"Optional notes\u2026"})});let O=y.createEl("button",{text:"Add",cls:"csv-add-submit"}),V=C.querySelector(".csv-add-card-title"),P=()=>{if(!m.length)return;let A=w[m[0]];if(!A)return;let j=A.value,Y=f.find($=>$[m[0]]===j);V&&V.setText(Y?`Updating ${j}`:"New entry"),y.classList.toggle("is-updating",!!Y),O.setText(Y?"Update":"Add"),b.forEach($=>{var z;let R=w[$];if(!R)return;let B=os((z=Y==null?void 0:Y[$])!=null?z:"");R.checked=B,M[$]=B}),[..._,...v].forEach($=>{var z;let R=w[$];if(!R)return;let B=(z=Y==null?void 0:Y[$])!=null?z:"";if(R instanceof HTMLSelectElement){let N=Array.from(R.options).find(q=>q.value===B),W=w[`${$}__custom`],I=W==null?void 0:W.closest(".csv-add-row-custom");N?(R.value=B,I&&(I.style.display="none"),W&&(W.value="")):B?(R.value="__custom__",W&&(W.value=B),I&&(I.style.display="flex")):(R.value="",I&&(I.style.display="none"),W&&(W.value=""))}else R instanceof HTMLTextAreaElement,R.value=B})};if(P(),m.length){let A=w[m[0]];A==null||A.addEventListener("change",P)}let T=()=>{y.style.display="block",x.style.display="none";let A=y.querySelector(".csv-add-row-control");A==null||A.focus()},U=()=>{y.style.display="none",x.style.display=""};x.addEventListener("click",T),E.addEventListener("click",U),O.addEventListener("click",async()=>{let A={};u.forEach(N=>{var W,I,q,Q;b.includes(N)?A[N]=M[N]?"1":"0":w[N]instanceof HTMLSelectElement&&w[N].value==="__custom__"?A[N]=(I=(W=w[`${N}__custom`])==null?void 0:W.value)!=null?I:"":w[N]instanceof HTMLTextAreaElement?A[N]=w[N].value:A[N]=(Q=(q=w[N])==null?void 0:q.value)!=null?Q:""});let j=m.length>0&&m.some(N=>{var W;return((W=A[N])!=null?W:"").trim()}),Y=[..._,...v].some(N=>{var W;return((W=A[N])!=null?W:"").trim()}),$=b.some(N=>M[N]);if(!j&&!Y&&!$){new ve.Notice("Please fill at least one field");return}let R=[];try{let N=await s.vault.read(d);R=wt(N).rows}catch(N){new ve.Notice(`Error reading file: ${N}`);return}let B=!1,z=-1;if(m.length>0){let N=m[0],W=A[N];if(z=R.findIndex(I=>I[N]===W),z>=0){B=!0;let I=R[z];u.forEach(q=>{var Q;(b.includes(q)||((Q=A[q])!=null?Q:"").trim())&&(I[q]=A[q])})}else R.push(A)}else R.push(A);try{let N=pr.default.unparse(R,{columns:u});await s.vault.modify(d,N),new ve.Notice(B?`Updated entry for ${A[m[0]]||""}`:`Added entry to ${d.basename}`),f.length=0,f.push(...R),m.length>0?P():(b.forEach(W=>{M[W]=!1;let I=w[W];I&&(I.checked=!1)}),[..._,...v].forEach(W=>{let I=w[W];I instanceof HTMLSelectElement?I.selectedIndex=0:(I instanceof HTMLTextAreaElement||I)&&(I.value="");let q=w[`${W}__custom`];if(q){q.value="";let Q=q.closest(".csv-add-row-custom");Q&&(Q.style.display="none")}})),setTimeout(async()=>{let W=s.vault.getAbstractFileByPath(n.sourcePath);if(W instanceof ve.TFile){let I=s.workspace.activeLeaf;I&&await I.openFile(W,{state:{mode:"preview"}})}},300)}catch(N){new ve.Notice(`Error saving: ${N}`)}})}function _n(s,t){let e=s.getFilteredRows();s.searchQuery.trim()&&t.createDiv({cls:"csv-search-results",text:`Found ${e.length} of ${s.rows.length} entries`});let i=t.createDiv({cls:"csv-table-wrapper"}).createEl("table",{cls:"csv-table"}),o=i.createEl("thead").createEl("tr");s.headers.forEach(l=>{let c=o.createEl("th");c.setText(l),c.addClass("csv-th-sortable"),s.tableSortCol===l&&c.createSpan({cls:"csv-th-sort-indicator",text:s.tableSortDir==="asc"?" \u25B2":" \u25BC"}),c.title="Click to sort",c.addEventListener("click",g=>{g.target.closest(".csv-col-resize-handle")||(s.tableSortCol!==l?(s.tableSortCol=l,s.tableSortDir="asc"):s.tableSortDir==="asc"?s.tableSortDir="desc":s.tableSortCol=null,s.renderView())});let d=s.settings.columnWidths[l];d&&(c.style.width=d+"px");let h=c.createDiv({cls:"csv-col-resize-handle"}),u=0,f=0;h.addEventListener("pointerdown",g=>{g.preventDefault(),g.stopPropagation(),h.setPointerCapture(g.pointerId),u=g.clientX,f=c.offsetWidth;let p=m=>{c.style.width=Math.max(60,f+m.clientX-u)+"px"},b=m=>{s.settings.columnWidths[l]=Math.max(60,f+m.clientX-u),h.removeEventListener("pointermove",p),h.removeEventListener("pointerup",b),s.persistSettings()};h.addEventListener("pointermove",p),h.addEventListener("pointerup",b)})}),o.createEl("th",{text:""});let r=matchMedia("(pointer: coarse)").matches,a=i.createEl("tbody");e.forEach(l=>{let c=a.createEl("tr");c.addEventListener("contextmenu",u=>s.openRowContextMenu(l,u)),s.headers.forEach(u=>{var g,p;let f=c.createEl("td");if(s.isNotesCol(u)){f.addClass("csv-table-notes-cell");let b=((g=l[u])!=null?g:"").replace(/#{1,6}\s/g,"").replace(/[*_>`]/g,"").split(` -`).filter(_=>_.trim()).slice(0,3).join(" \xB7 "),m=b?b.slice(0,200)+(b.length>200?"\u2026":""):"+ Add note",v=f.createSpan({text:m});b||v.addClass("csv-table-notes-empty"),f.title="Click to open note",f.addEventListener("click",_=>{_.stopPropagation(),s.openNoteExpander(l,u)})}else if(s.isSelectCol(u))s.renderSelectField(f,l,u);else{let b=(p=l[u])!=null?p:"";f.setText(b),b.length>80&&(f.title=b),Ns(s,f,l,u)}});let d=c.createEl("td",{cls:"csv-table-action"}),h=s.notesFileExists(l);d.createEl("button",{cls:`csv-table-notes-btn ${h?"exists":""}`,text:h?"\u{1F4C4}":"\u271A",title:h?"Open notes":"Create notes"}).addEventListener("click",()=>s.openOrCreateNotes(l)),d.createEl("button",{cls:"csv-table-del-btn",text:"\u2715",title:"Delete row (Undo available)"}).addEventListener("click",()=>s.deleteWithUndo(l))}),r||requestAnimationFrame(()=>{a.querySelectorAll("td:not(.csv-table-notes-cell):not(.csv-table-action)").forEach(l=>{l.scrollHeight>l.clientHeight+1&&l.addClass("csv-cell--clipped")})})}function Ns(s,t,e,n){t.addEventListener("click",i=>{var h,u;if(t.querySelector("input"))return;t.empty();let o=(h=s.fileCfg.dateColumns)==null?void 0:h.includes(n),r=((u=e[n])!=null?u:"").trim(),a=o||Et(n)&&(r===""||mn.test(r)),l=a?r.slice(0,10):r,c=t.createEl("input",{cls:"csv-inline-input",value:l,type:a?"date":"text"});c.focus(),a||c.select(),c.addEventListener("click",f=>f.stopPropagation());let d=!1;c.addEventListener("blur",()=>{var f;!d&&c.value!==l&&(e[n]=c.value,s.scheduleSave()),t.empty(),t.setText(((f=e[n])!=null?f:"")||"\u2014")}),c.addEventListener("keydown",f=>{f.key==="Enter"&&c.blur(),f.key==="Escape"&&(d=!0,c.blur())})})}function Sn(s){return!!(s.getCategoryCol()||s.getStatusCol()||br(s)||s.authorKey())}function br(s){return s.resolveCol(["Rating","rating","Score","score","Score /5","Stars","stars"])}function Hs(s){var i;let t=(s!=null?s:"").trim();if(!t)return null;let e=((i=t.match(/★/g))!=null?i:[]).length;if(e>0)return e;let n=parseFloat(t);return isNaN(n)||n<=0?null:Math.min(5,n)}var vr=["watched","read","finished","completed","done","yes","seen"],yr=["watching","reading","in progress","in-progress"],Xc=["dropped","abandoned","dnf"];function Qc(s){let t=s.toLowerCase();return vr.includes(t)?"is-done":yr.includes(t)?"is-progress":Xc.includes(t)?"is-dropped":""}function Bs(s,t){let e=new Map;return s.forEach(n=>t(n).forEach(i=>{var o;return e.set(i,((o=e.get(i))!=null?o:0)+1)})),e}function $s(s,t,e,n){if(!e.length)return;let i=s.createDiv({cls:"csv-stats-section"});i.createDiv({cls:"csv-stats-section-title",text:t});let o=Math.max(...e.map(r=>r.count));e.forEach(r=>{var h;let a=i.createDiv({cls:"csv-stats-bar-row"});a.createDiv({cls:"csv-stats-bar-label",text:r.label,attr:{title:r.label}});let c=a.createDiv({cls:"csv-stats-bar-track"}).createDiv({cls:`csv-stats-bar-fill ${(h=r.cls)!=null?h:""}`});c.style.width=`${Math.max(2,Math.round(r.count/o*100))}%`;let d=n>0?Math.round(r.count/n*100):0;a.createDiv({cls:"csv-stats-bar-count",text:`${r.count} \xB7 ${d}%`}),r.onClick&&(a.addClass("is-clickable"),a.title=`Show "${r.label}" in the library`,a.addEventListener("click",r.onClick))})}function xr(s,t){let e=s.getFilteredRows();if(s.searchQuery.trim()&&t.createDiv({cls:"csv-search-results",text:`Stats over ${e.length} of ${s.rows.length} entries`}),!e.length){t.createEl("p",{text:"No entries to chart.",cls:"csv-empty-state"});return}let n=t.createDiv({cls:"csv-stats-wrap"}),i=s.getStatusCol(),o=s.getCategoryCol(),r=br(s),a=s.authorKey(),l=s.resolveCol(["Year","year"]),c=n.createDiv({cls:"csv-stats-overview"}),d=(u,f)=>{let g=c.createDiv({cls:"csv-stats-chip"});g.createDiv({cls:"csv-stats-chip-value",text:u}),g.createDiv({cls:"csv-stats-chip-label",text:f})};if(d(String(e.length),"entries"),i){let u=e.filter(g=>{var p;return vr.includes(((p=g[i])!=null?p:"").toLowerCase().trim())}).length;u>0&&d(`${u} \xB7 ${Math.round(u/e.length*100)}%`,"done");let f=e.filter(g=>{var p;return yr.includes(((p=g[i])!=null?p:"").toLowerCase().trim())}).length;f>0&&d(String(f),"in progress")}if(o){let u=Bs(e,f=>{var g;return((g=f[o])!=null?g:"").split(",").map(p=>p.trim()).filter(Boolean)});u.size>0&&d(String(u.size),o.toLowerCase()==="genre"||o.toLowerCase()==="genres"?"genres":"categories")}if(r){let u=e.map(f=>Hs(f[r])).filter(f=>f!==null);if(u.length){let f=u.reduce((g,p)=>g+p,0)/u.length;d(`\u2605 ${f.toFixed(1)}`,`avg of ${u.length} rated`)}}let h=(u,f)=>{s.libraryStatusFilter=u!=null?u:"all",s.libraryGenreFilter=f!=null?f:"all",s.mode="library",s.renderView()};if(i){let u=Bs(e,g=>{var b;let p=((b=g[i])!=null?b:"").trim();return p?[p]:[]}),f=Array.from(u.entries()).sort((g,p)=>p[1]-g[1]).map(([g,p])=>({label:g,count:p,cls:Qc(g),onClick:o?()=>h(g,null):void 0}));$s(n,`By ${i.toLowerCase()}`,f,e.length)}if(o){let u=Bs(e,g=>{var p;return((p=g[o])!=null?p:"").split(",").map(b=>b.trim()).filter(Boolean)}),f=Array.from(u.entries()).sort((g,p)=>p[1]-g[1]||g[0].localeCompare(p[0])).slice(0,12).map(([g,p])=>({label:g,count:p,onClick:()=>h(null,g)}));$s(n,`By ${o.toLowerCase()}`,f,e.length)}if(r){let u=new Map,f=0;if(e.forEach(g=>{var m;let p=Hs(g[r]);if(p===null)return;let b=Math.min(5,Math.max(1,Math.round(p)));u.set(b,((m=u.get(b))!=null?m:0)+1),f++}),f>0){let g=[5,4,3,2,1].filter(p=>{var b;return((b=u.get(p))!=null?b:0)>0}).map(p=>({label:"\u2605".repeat(p),count:u.get(p),cls:"is-rating"}));$s(n,"Ratings",g,f)}}if(l){let u=Bs(e,f=>{var p;let g=((p=f[l])!=null?p:"").match(/\d{4}/);return g?[g[0]]:[]});if(u.size>1){let f=Array.from(u.entries()).sort((g,p)=>g[0].localeCompare(p[0])).map(([g,p])=>({label:g,count:p}));$s(n,"By year",f,e.length)}}if(a){let u=Bs(e,g=>{var b;let p=((b=g[a])!=null?b:"").trim();return p?[p]:[]}),f=Array.from(u.entries()).filter(([,g])=>g>1);if(f.length>=2){let g=f.sort((p,b)=>b[1]-p[1]||p[0].localeCompare(b[0])).slice(0,8).map(([p,b])=>({label:p,count:b}));$s(n,`Top ${a.toLowerCase()}s`,g,e.length)}}}function $t(s){let t=s.fileCfg.kanbanGroupCol;if(t&&s.headers.includes(t))return t;let e=s.getCategoryCol();if(e)return e;let n=new Set;s.headers.forEach(r=>{s.isNotesCol(r)&&n.add(r)});let i=s.getDateCol();i&&n.add(i);let o=s.titleKey();return o&&n.add(o),ir(s.headers,s.rows,n)}function kn(s,t){let e=$t(s);if(!e){t.createEl("p",{text:"No groupable column found.",cls:"csv-empty-state"});return}let n=s.getCategoryCol(),i=s.getStatusCol(),o=i===e?null:i,r=s.getFilteredRows();s.searchQuery.trim()&&t.createDiv({cls:"csv-search-results",text:`Found ${r.length} of ${s.rows.length} entries`});let a=t.createDiv({cls:"csv-kanban-groupbar"});a.createSpan({cls:"csv-kanban-groupbar-label",text:"Group by"});let l=a.createEl("select",{cls:"csv-library-filter-select"});s.headers.filter(b=>!s.isNotesCol(b)).forEach(b=>{let m=l.createEl("option",{text:b===n?`${b} (default)`:b,value:b});b===e&&(m.selected=!0)}),l.addEventListener("change",()=>{let b=s.fileCfg;b.kanbanGroupCol=l.value===n?void 0:l.value,s.saveFileCfg(b),s.renderView(!0)});let c=sr(e,r.map(b=>{var m;return(m=b[e])!=null?m:""})),d=b=>{var _;let m=(_=b[e])!=null?_:"",v;if(c){let k=nr(m);v=k?[k]:[]}else v=m.split(",").map(k=>k.trim()).filter(Boolean);return v.length||(v=["\u2014"]),v},h=new Set;r.forEach(b=>d(b).forEach(m=>h.add(m)));let u=Array.from(h).sort();if(!u.length){let b=t.createDiv({cls:"csv-empty-state"});b.createEl("p",{text:s.searchQuery?"No matching entries found.":`No "${e}" values found.`}),s.searchQuery&&b.createEl("button",{cls:"csv-clear-filters-btn",text:"Clear search"}).addEventListener("click",()=>{s.searchQuery="",s.renderView()});return}let f=["In progress","Finished","Not started"],g=o?Array.from(new Set([...f,...r.map(b=>{var m;return(m=b[o])!=null?m:""}).filter(Boolean)])).filter(b=>r.some(m=>{var v;return((v=m[o])!=null?v:"")==b})):[],p=t.createDiv({cls:"csv-kanban-board"});u.forEach(b=>{let m=r.filter(S=>d(S).includes(b));if(!m.length)return;let v=p.createDiv({cls:"csv-kanban-col"}),_=v.createDiv({cls:"csv-kanban-col-header"});_.createDiv({cls:"csv-kanban-col-title",text:b}),_.createDiv({cls:"csv-kanban-col-count",text:String(m.length)});let k=v.createDiv({cls:"csv-kanban-col-body"});if(o&&g.length){g.forEach(y=>{let C=m.filter(D=>{var w;return((w=D[o])!=null?w:"")===y});if(!C.length)return;let E=k.createDiv({cls:"csv-kanban-status-group"});E.createDiv({cls:`csv-kanban-status-label status-${y.toLowerCase().replace(/\s+/g,"-")}`,text:y}),C.forEach(D=>Ti(s,E,D,o,e))});let S=new Set(g),x=m.filter(y=>{var C;return!S.has((C=y[o])!=null?C:"")});if(x.length){let y=k.createDiv({cls:"csv-kanban-status-group"});y.createDiv({cls:"csv-kanban-status-label",text:"\u2014"}),x.forEach(C=>Ti(s,y,C,o,e))}}else m.forEach(S=>Ti(s,k,S,o,e))})}function Ti(s,t,e,n,i){var C,E,D,w,M,L,O,V;let o=t.createDiv({cls:"csv-kanban-card"}),r=s.getNotesCol(),a=(E=(C=s.getImageCol)==null?void 0:C.call(s))!=null?E:null;if(a){let P=pn(s.app,(D=e[a])!=null?D:"",(M=(w=s.file)==null?void 0:w.path)!=null?M:"");if(P){let T=o.createEl("img",{cls:"csv-kanban-card-img",attr:{src:P,loading:"lazy",alt:""}});T.addEventListener("error",()=>T.remove())}}let l=o.createDiv({cls:"csv-kanban-card-title-row"});l.createDiv({cls:`csv-kanban-card-title ${(L=s.isHighlighted)!=null&&L.call(s,e)?"csv-title-highlight":""}`,text:s.getTitle(e)}).addEventListener("click",P=>{P.stopPropagation(),s.openNoteExpander(e,r!=null?r:"")});let d=s.notesFileExists(e);l.createEl("button",{cls:`csv-kanban-notes-icon ${d?"exists":""}`,text:d?"\u{1F4C4}":"+",title:d?"Open notes file":"Create notes file"}).addEventListener("click",P=>{P.stopPropagation(),s.openOrCreateNotes(e)});let u=s.getSubtitle(e);u&&o.createDiv({cls:"csv-kanban-card-sub",text:u});let f=s.titleKey(),g=s.authorKey(),p=new Set([n,f,g,i].filter(Boolean)),b=o.createDiv({cls:"csv-kanban-card-meta"});((O=s.fileCfg.cardFields)!=null?O:s.headers).forEach(P=>{if(!s.headers.includes(P)||p.has(P)||s.isNotesCol(P))return;let T=b.createDiv({cls:"csv-kanban-chip"});if(T.createSpan({cls:"csv-chip-label",text:P+": "}),s.isSelectCol(P)){let U=T.createSpan({cls:`csv-chip-value csv-chip-select${e[P]?"":" csv-chip-value--empty"}`,text:e[P]||"\u2014"});U.addEventListener("click",F=>{F.stopPropagation(),It(U,e[P],s.getColumnValues(P),G=>{e[P]=G,U.setText(G||"\u2014"),U.classList.toggle("csv-chip-value--empty",!G),s.scheduleSave()},s.contentEl,{multi:xt(P)})})}else{let U=e[P]?e[P].length>40?e[P].slice(0,38)+"\u2026":e[P]:"\u2014",F=T.createSpan({cls:`csv-chip-value${e[P]?"":" csv-chip-value--empty"}`,text:U});e[P]&&e[P].length>40&&(F.title=e[P])}});let v=s.getNotesCol(),_=!!(v&&((V=e[v])!=null&&V.trim())),k=o.createDiv({cls:"csv-kanban-notes-preview"});if(_&&v){let P=e[v].replace(/#{1,6}\s/g,"").replace(/[*_>`]/g,"").replace(/\n+/g," ").trim();k.setText(P.slice(0,120)+(P.length>120?"\u2026":"")),k.title="Click to edit"}else k.addClass("csv-kanban-notes-preview--empty"),v&&k.setText("+ Add note");let S=o.createDiv({cls:"csv-kanban-notes-editor"});S.style.display="none";let x=()=>{var j,Y,$;let P=s.contentEl.querySelector(".csv-content-area"),T=(j=P==null?void 0:P.scrollLeft)!=null?j:0,U=(Y=P==null?void 0:P.scrollTop)!=null?Y:0;k.style.display="none",S.style.display="block",S.empty();let F=S.createEl("textarea",{cls:"csv-notes-textarea"});F.value=($=v?e[v]:"")!=null?$:"",F.addEventListener("click",R=>R.stopPropagation()),F.addEventListener("mousedown",R=>R.stopPropagation()),F.addEventListener("input",()=>{F.style.height="auto",F.style.height=F.scrollHeight+"px"});let G=F.value,H=!1,A=R=>{H||(H=!0,y(R,P,T,U))};F.addEventListener("keydown",R=>{R.key==="Escape"&&A(G)}),F.addEventListener("blur",()=>A(F.value)),F.focus({preventScroll:!0}),F.setSelectionRange(0,0),F.scrollTop=0,requestAnimationFrame(()=>{F.style.height="auto",F.style.height=Math.max(120,F.scrollHeight)+"px"})},y=(P,T,U,F)=>{var G;if(v&&P!==((G=e[v])!=null?G:"")&&(e[v]=P,s.scheduleSave()),S.style.display="none",k.style.display="",P.trim()){let H=P.replace(/#{1,6}\s/g,"").replace(/[*_>`]/g,"").replace(/\n+/g," ").trim();k.setText(H.slice(0,120)+(H.length>120?"\u2026":"")),k.removeClass("csv-kanban-notes-preview--empty"),k.title="Click to edit"}else k.addClass("csv-kanban-notes-preview--empty"),k.setText(v?"+ Add note":""),k.removeAttribute("title");T&&(T.scrollLeft=U,T.scrollTop=F,requestAnimationFrame(()=>{T.scrollLeft=U,T.scrollTop=F,requestAnimationFrame(()=>{T.scrollLeft=U,T.scrollTop=F})}),setTimeout(()=>{T.scrollLeft=U,T.scrollTop=F},50))};k.addEventListener("click",P=>{if(P.stopPropagation(),v&&matchMedia("(pointer: coarse)").matches){s.openNoteExpander(e,v);return}x()}),o.addEventListener("contextmenu",P=>s.openRowContextMenu(e,P))}function wn(s,t){var E,D;let e=$t(s),n=s.getStatusCol(),i=(E=s.titleKey())!=null?E:s.headers[0],o=s.authorKey();if(!e){t.createEl("p",{text:"No groupable column found.",cls:"csv-empty-state"});return}let r=new Set;s.rows.forEach(w=>{var L;((L=w[e])!=null?L:"").split(",").map(O=>O.trim()).filter(Boolean).forEach(O=>r.add(O))});let a=new Set;n&&s.rows.forEach(w=>{var L;let M=((L=w[n])!=null?L:"").trim();M&&a.add(M)});let l=t.createDiv({cls:"csv-library-filters"}),c=l.createEl("select",{cls:"csv-library-filter-select"});c.createEl("option",{text:"All",value:"all"});let d=["watched","read","finished","completed","done","yes","seen"],h=["watching","reading","in progress","in-progress"],u=Array.from(a).some(w=>d.includes(w.toLowerCase())),f=Array.from(a).some(w=>h.includes(w.toLowerCase()));(u||f)&&(c.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500",value:"",attr:{disabled:"true"}}),u&&c.createEl("option",{text:"\u2713 Done",value:"__done__"}),f&&c.createEl("option",{text:"\u25D0 In Progress",value:"__inprogress__"}),c.createEl("option",{text:"\u25CB Not Started",value:"__notstarted__"})),a.size>0&&(c.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500",value:"",attr:{disabled:"true"}}),Array.from(a).sort().forEach(w=>{c.createEl("option",{text:w,value:w})})),c.value=s.libraryStatusFilter;let g=l.createEl("select",{cls:"csv-library-filter-select"});g.createEl("option",{text:"All genres",value:"all"}),Array.from(r).sort().forEach(w=>{g.createEl("option",{text:w,value:w})}),g.value=s.libraryGenreFilter;let p=s.resolveCol(["Year","year","Date","date"]),b=s.resolveCol(["Rating","rating","Score","score","Score /5","Stars","stars"]),m=s.resolveCol(["Theme","theme","Tags","tags","Tag","tag","Mood","mood"]),v=(D=s.fileCfg.librarySort)!=null?D:"status",_=l.createEl("select",{cls:"csv-library-filter-select"}),k=[["status","Sort: Status"],["title","Sort: Title"]];b&&k.push(["rating","Sort: Rating"]),p&&k.push(["year","Sort: Year"]),k.forEach(([w,M])=>{let L=_.createEl("option",{text:M,value:w});w===v&&(L.selected=!0)}),_.addEventListener("change",()=>{let w=s.fileCfg;w.librarySort=_.value==="status"?void 0:_.value,s.saveFileCfg(w),s.renderView(!0)});let S=()=>{s.libraryStatusFilter=c.value,s.libraryGenreFilter=g.value,s.renderView(!0)};c.addEventListener("change",S),g.addEventListener("change",S);let x=s.rows.filter(w=>{var M,L;if(s.libraryStatusFilter!=="all"&&n){let O=((M=w[n])!=null?M:"").toLowerCase();if(s.libraryStatusFilter==="__done__"){if(!d.includes(O))return!1}else if(s.libraryStatusFilter==="__inprogress__"){if(!h.includes(O))return!1}else if(s.libraryStatusFilter==="__notstarted__"){if(d.includes(O)||h.includes(O))return!1}else if(O!==s.libraryStatusFilter.toLowerCase())return!1}if(s.libraryGenreFilter!=="all"&&!((L=w[e])!=null?L:"").split(",").map(V=>V.trim().toLowerCase()).includes(s.libraryGenreFilter.toLowerCase()))return!1;if(s.searchQuery.trim()){let O=s.searchQuery.toLowerCase().trim();if(!s.headers.some(V=>{var P;return((P=w[V])!=null?P:"").toLowerCase().includes(O)}))return!1}return!0});(s.libraryStatusFilter!=="all"||s.libraryGenreFilter!=="all"||s.searchQuery.trim())&&t.createDiv({cls:"csv-library-result-count",text:`Showing ${x.length} of ${s.rows.length} entries`});let y={};x.forEach(w=>{var L;let M=s.libraryGenreFilter!=="all"?[s.libraryGenreFilter]:((L=w[e])!=null?L:"Uncategorized").split(",").map(O=>O.trim()).filter(Boolean);M.length===0&&M.push("Uncategorized"),M.forEach(O=>{y[O]||(y[O]=[]),y[O].push(w)})});let C=t.createDiv({cls:"csv-library-sections"});if(Object.keys(y).sort().forEach(w=>{var A,j,Y,$,R;let M=y[w],L=C.createEl("details",{cls:"csv-library-section"}),O=w.toLowerCase(),V=((A=s.fileCfg.collapsedGroups)!=null?A:[]).map(B=>B.toLowerCase());L.open=!((j=s.collapsedGroups)!=null&&j.has(O)||V.includes(O)),L.addEventListener("toggle",()=>{var I;let B=s.fileCfg,z=((I=B.collapsedGroups)!=null?I:[]).map(q=>q.toLowerCase()),N=new Set(z);L.open?N.delete(O):N.add(O);let W=Array.from(N);W.length===z.length&&W.every(q=>z.includes(q))||(B.collapsedGroups=W,s.saveFileCfg(B))});let P=L.createEl("summary",{cls:"csv-library-section-header"});P.innerHTML=`\u25B6 ${w} ${M.length}`;let T=L.createDiv({cls:"csv-library-grid"}),U=(B,z)=>{var N,W;return((N=B[i])!=null?N:"").localeCompare((W=z[i])!=null?W:"")},F=(B,z)=>B===null&&z===null?0:B===null?1:z===null?-1:z-B;M.sort((B,z)=>{var N,W,I,q;if(v==="title")return U(B,z);if(v==="rating"&&b)return F(Hs((N=B[b])!=null?N:""),Hs((W=z[b])!=null?W:""))||U(B,z);if(v==="year"&&p){let Q=Z=>{var X;let nt=((X=Z[p])!=null?X:"").match(/\d{4}/);return nt?parseInt(nt[0],10):null};return F(Q(B),Q(z))||U(B,z)}if(n){let Q=((I=B[n])!=null?I:"").toLowerCase(),Z=((q=z[n])!=null?q:"").toLowerCase(),nt=d.includes(Q),X=d.includes(Z);if(nt!==X)return nt?-1:1;let tt=h.includes(Q),at=h.includes(Z);if(tt!==at)return tt?-1:1}return U(B,z)});let G=(Y=s.fileCfg.cardFields)!=null?Y:s.headers,H=(R=($=s.getImageCol)==null?void 0:$.call(s))!=null?R:null;M.forEach(B=>{var q,Q,Z,nt,X,tt,at,Wt;let z=T.createDiv({cls:"csv-library-card"});if(H){let rt=pn(s.app,(q=B[H])!=null?q:"",(Z=(Q=s.file)==null?void 0:Q.path)!=null?Z:"");if(rt){let pt=z.createEl("img",{cls:"csv-library-card-img",attr:{src:rt,loading:"lazy",alt:""}});pt.addEventListener("error",()=>pt.remove())}}let N=z.createDiv({cls:`csv-library-card-title ${(nt=s.isHighlighted)!=null&&nt.call(s,B)?"csv-title-highlight":""}`});if(n){let rt=((X=B[n])!=null?X:"").toLowerCase();d.includes(rt)&&N.createSpan({cls:"csv-library-done-dot"})}N.createSpan({text:(tt=B[i])!=null?tt:"Untitled"});let W=[],I=[];for(let rt of G){if(!rt)continue;let pt=String((at=B[rt])!=null?at:"").trim();if(pt)if(rt===b){let ft=er(pt,rt);ft&&z.createDiv({cls:"csv-library-card-rating",text:ft})}else if(rt===m)I.push(...pt.split(",").map(ft=>ft.trim()).filter(Boolean));else if(rt===p){let ft=pt.match(/\d{4}/);W.push(ft?ft[0]:pt)}else W.push(pt)}if(W.length&&z.createDiv({cls:"csv-library-card-meta",text:W.join(" \xB7 ")}),s.libraryGenreFilter!=="all"){let rt=((Wt=B[e])!=null?Wt:"").split(",").map(pt=>pt.trim()).filter(pt=>pt&&pt.toLowerCase()!==s.libraryGenreFilter.toLowerCase());I.push(...rt)}if(I.length){let rt=z.createDiv({cls:"csv-library-card-tags"});I.slice(0,3).forEach(pt=>{rt.createSpan({cls:"csv-library-card-tag",text:pt})})}z.addEventListener("click",()=>{var rt;s.openNoteExpander(B,(rt=s.getNotesCol())!=null?rt:"")}),z.addEventListener("contextmenu",rt=>s.openRowContextMenu(B,rt))})}),Object.keys(y).length===0){let w=C.createDiv({cls:"csv-empty-state"});w.createEl("p",{text:"No entries match your filters."}),w.createEl("button",{cls:"csv-clear-filters-btn",text:"Clear filters"}).addEventListener("click",()=>{s.libraryStatusFilter="all",s.libraryGenreFilter="all",s.searchQuery="",s.renderView()})}}var vi=require("obsidian");var ye=require("obsidian"),Zc="http://127.0.0.1:8765",Jc=6;async function Cr(s,t){let e;try{e=await(0,ye.requestUrl)({url:Zc,method:"POST",contentType:"application/json",body:JSON.stringify({action:s,version:Jc,params:t}),throw:!1})}catch(i){throw new Error("Couldn't reach Anki. Is the desktop app open with the AnkiConnect add-on installed?")}let n=e.json;if(n.error)throw new Error(n.error);return n.result}function Ai(s){var t,e,n;return(n=(e=(t=s.titleKey())!=null?t:s.resolveCol(["Quote","Headline","Phrase","Term","Word","Question","Front","Name","Title"]))!=null?e:s.headers[0])!=null?n:null}function td(s){let t=s.fileCfg.ankiFrontCol;return t&&s.headers.includes(t)?t:Ai(s)}function Li(s){return s.replace(/&/g,"&").replace(//g,">")}function ed(s,t,e){return s.headers.filter(n=>{var i;return n!==e&&((i=t[n])!=null?i:"").trim()}).map(n=>`${Li(n)}: ${Li(t[n].trim())}`).join("
")}async function _r(s){if(!s.file)return;let t=td(s);if(!t){new ye.Notice("No column to use as the Anki card front.",6e3);return}let e=s.file.basename,n=s.rows.filter(o=>{var r;return((r=o[t])!=null?r:"").trim()});if(!n.length){new ye.Notice(`Nothing to sync \u2014 no rows with a "${t}" value.`,6e3);return}let i=new ye.Notice(`Syncing ${n.length} cards to Anki deck \u201C${e}\u201D\u2026`,0);try{await Cr("createDeck",{deck:e});let o=n.map(c=>({deckName:e,modelName:"Basic",fields:{Front:Li(c[t].trim()),Back:ed(s,c,t)},options:{allowDuplicate:!1,duplicateScope:"deck"},tags:["datadeck"]})),r=await Cr("addNotes",{notes:o}),a=r.filter(c=>c!=null).length,l=r.length-a;i.hide(),new ye.Notice(`Anki sync: ${a} added${l?`, ${l} already present`:""} (deck \u201C${e}\u201D).`,6e3)}catch(o){i.hide(),new ye.Notice(`Anki sync failed: ${o instanceof Error?o.message:String(o)}`,8e3)}}var Ze=require("obsidian");var Vo=null;async function Qe(){if(Vo)return Vo;let s=await Promise.resolve().then(()=>(Ql(),Xl));return s.Chart.register(s.LineController,s.ScatterController,s.BarController,s.LineElement,s.PointElement,s.BarElement,s.LinearScale,s.CategoryScale,s.Filler,s.Tooltip,s.Legend),Vo=s,s}var Zl={pi:Math.PI,e:Math.E},Jl={sin:Math.sin,cos:Math.cos,tan:Math.tan,asin:Math.asin,acos:Math.acos,atan:Math.atan,sqrt:Math.sqrt,log:Math.log10,ln:Math.log,exp:Math.exp,abs:Math.abs,floor:Math.floor,ceil:Math.ceil,round:Math.round,sign:Math.sign},No={min:Math.min,max:Math.max,pow:Math.pow,atan2:Math.atan2};function _g(s){let t=[],e=0;for(;e{var u;return(u=e[n])!=null?u:null},o=()=>{var u;return(u=e[n++])!=null?u:null};function r(){let u=a();for(;;){let f=i();if((f==null?void 0:f.kind)==="op"&&(f.op==="+"||f.op==="-")){n++;let g=a(),p=u;u=f.op==="+"?m=>p(m)+g(m):m=>p(m)-g(m)}else return u}}function a(){let u=l();for(;;){let f=i();if((f==null?void 0:f.kind)==="op"&&(f.op==="*"||f.op==="/"||f.op==="%")){n++;let g=l(),p=u,b=f.op;u=b==="*"?m=>p(m)*g(m):b==="/"?m=>p(m)/g(m):m=>p(m)%g(m)}else if(f&&(f.kind==="num"||f.kind==="ident"||f.kind==="lparen")){let g=l(),p=u;u=b=>p(b)*g(b)}else return u}}function l(){let u=i();if((u==null?void 0:u.kind)==="op"&&u.op==="-"){n++;let f=l();return g=>-f(g)}return(u==null?void 0:u.kind)==="op"&&u.op==="+"?(n++,l()):c()}function c(){let u=d(),f=i();if((f==null?void 0:f.kind)==="op"&&f.op==="^"){n++;let g=l();return p=>Math.pow(u(p),g(p))}return u}function d(){var f,g,p,b,m;let u=o();if(!u)throw new Error("Unexpected end of formula");if(u.kind==="num"){let v=u.value;return()=>v}if(u.kind==="lparen"){let v=r();if(((f=o())==null?void 0:f.kind)!=="rparen")throw new Error("Missing closing )");return v}if(u.kind==="ident"){if(u.name==="x")return _=>_;if(u.name in Zl){let _=Zl[u.name];return()=>_}let v=((g=i())==null?void 0:g.kind)==="lparen";if(u.name in Jl||u.name in No){if(!v)throw new Error(`${u.name} needs parentheses, e.g. ${u.name}(x)`);n++;let _=r();if(u.name in No){if(((p=o())==null?void 0:p.kind)!=="comma")throw new Error(`${u.name}(a, b) needs two arguments`);let S=r();if(((b=o())==null?void 0:b.kind)!=="rparen")throw new Error("Missing closing )");let x=No[u.name];return y=>x(_(y),S(y))}if(((m=o())==null?void 0:m.kind)!=="rparen")throw new Error("Missing closing )");let k=Jl[u.name];return S=>k(_(S))}throw new Error(`Unknown name "${u.name}" \u2014 use x, pi, e, or a function like sin()`)}throw new Error(`Unexpected "${u.kind==="op"?u.op:u.kind}"`)}let h=r();if(n{var o;let n=0,i=0;for(let r of t){let a=((o=r[e])!=null?o:"").trim();a&&(n++,hn(a)!==null&&i++)}return i>=2&&i/n>=.7})}function Sg(s){let t=s.length;if(t<2)return null;let e=0,n=0,i=0,o=0,r=0;for(let f of s)e+=f.x,n+=f.y,i+=f.x*f.x,o+=f.x*f.y,r+=f.y*f.y;let a=t*i-e*e;if(a===0)return null;let l=(t*o-e*n)/a,c=(n-l*e)/t,d=n/t,h=0,u=0;for(let f of s){let g=f.y-(l*f.x+c);h+=g*g,u+=(f.y-d)*(f.y-d)}return{slope:l,intercept:c,r2:u===0?1:1-h/u}}function kg(s,t){let e=[...s].sort((o,r)=>o.x-r.x),n=t/2,i=0;return e.map(o=>{for(;i{let r=new Date(o);if(t==="month")return new Date(r.getFullYear(),r.getMonth(),1).getTime();let a=(r.getDay()+6)%7;return new Date(r.getFullYear(),r.getMonth(),r.getDate()-a).getTime()},i=new Map;return s.forEach(o=>{var l;let r=n(o.x),a=(l=i.get(r))!=null?l:{sum:0,n:0};a.sum+=o.y,a.n+=1,i.set(r,a)}),[...i.entries()].sort((o,r)=>o[0]-r[0]).map(([o,r])=>({x:o,y:e==="count"?r.n:e==="sum"?r.sum:r.sum/r.n}))}function Ls(s){var n;let t=(n=s.ownerDocument.defaultView)==null?void 0:n.getComputedStyle(s),e=(i,o)=>(t==null?void 0:t.getPropertyValue(i).trim())||o;return{accent:e("--interactive-accent","#378ADD"),muted:e("--text-muted","#888888"),grid:e("--background-modifier-border","rgba(128,128,128,0.25)"),fitLine:e("--text-faint","#999999"),formula:e("--color-orange","#e0883a"),series:[e("--color-blue","#4e79a7"),e("--color-green","#59a14f"),e("--color-red","#e15759"),e("--color-purple","#b07aa1"),e("--color-cyan","#76b7b2"),e("--color-pink","#ff9da7"),e("--color-yellow","#edc948")]}}var Ts=s=>{if(!Number.isFinite(s))return String(s);let t=Math.abs(s);return t!==0&&(t>=1e6||t<.001)?s.toExponential(2):String(Math.round(s*1e3)/1e3)},ec=s=>{let t=new Date(s);return isNaN(t.getTime())?String(s):me(t)};function ui(s,t){var b,m;let e=[],n=s.series.length>1,i=s.series.flatMap(v=>v.points),o=i.map(v=>v.x),r=i.length?Math.min(...o):(b=s.xMin)!=null?b:0,a=i.length?Math.max(...o):(m=s.xMax)!=null?m:10,l=i.filter(v=>v.size!==void 0),c=l.length?Math.min(...l.map(v=>v.size)):0,d=l.length?Math.max(...l.map(v=>v.size)):0,h=(v,_)=>v.size===void 0?_:d===c?7:3+11*Math.sqrt((v.size-c)/(d-c)),u=[];s.series.forEach((v,_)=>{var y;let k=s.connect?[...v.points].sort((C,E)=>C.x-E.x):v.points;if(!k.length)return;let S=n?t.series[_%t.series.length]:t.accent,x=s.connect?3:4;if(((y=s.smoothDays)!=null?y:0)>0?(e.push({type:"scatter",label:v.label||s.yLabel,csvSkipLegend:!0,data:k,backgroundColor:S,borderColor:S,pointRadius:2.5,pointHoverRadius:5}),e.push({type:"line",label:v.label||s.yLabel,data:kg(k,s.smoothDays*864e5),borderColor:S,backgroundColor:S,borderWidth:2,pointRadius:0,pointHitRadius:0,tension:.3})):e.push({type:s.connect?"line":"scatter",label:v.label||s.yLabel,data:k,backgroundColor:S,borderColor:S,borderWidth:1.5,pointRadius:l.length?k.map(C=>h(C,x)):x,pointHoverRadius:l.length?k.map(C=>h(C,x)+2):6,tension:.3}),s.fit==="linear"){let C=Sg(k),E=k.map(M=>M.x),D=Math.min(...E),w=Math.max(...E);if(C&&w>D){e.push({type:"line",label:`${v.label||"Best"} fit`,csvIsFit:!0,data:[{x:D,y:C.slope*D+C.intercept},{x:w,y:C.slope*w+C.intercept}],borderColor:n?S:t.fitLine,borderDash:[6,4],borderWidth:1.5,pointRadius:0,pointHitRadius:0});let M=` \xB7 R\xB2 = ${(Math.round(C.r2*1e3)/1e3).toFixed(3)}`,L=s.xIsDate?`${C.slope*864e5>=0?"+":""}${Ts(C.slope*864e5)} ${s.yLabel}/day${M}`:`y = ${Ts(C.slope)}x ${C.intercept>=0?"+":"\u2212"} ${Ts(Math.abs(C.intercept))}${M}`;u.push(n?`${v.label}: ${L}`:s.xIsDate?`Trend: ${L}`:L)}}});let f=u.length?u.join(" \xB7 "):null,g=null;if(s.formula.trim())try{let v=tc(s.formula),_=[],k=160;for(let S=0;S<=k;S++){let x=r+(a-r)*S/k,y=v(x);Number.isFinite(y)&&_.push({x,y})}_.length&&e.push({type:"line",label:s.formula.trim(),data:_,borderColor:t.formula,borderWidth:1.5,pointRadius:0,pointHitRadius:0,tension:0})}catch(v){g=v instanceof Error?v.message:String(v)}return{config:{type:"scatter",data:{datasets:e},options:{responsive:!0,maintainAspectRatio:!1,scales:{x:{type:"linear",title:{display:!s.xIsDate&&!!s.xLabel,text:s.xLabel,color:t.muted},ticks:{color:t.muted,...s.xIsDate?{callback:v=>ec(Number(v)),maxTicksLimit:8}:{}},grid:{color:t.grid}},y:{title:{display:!!s.yLabel,text:s.yLabel,color:t.muted},ticks:{color:t.muted},grid:{color:t.grid}}},plugins:{legend:{display:e.filter(v=>!v.csvIsFit&&!v.csvSkipLegend).length>1,labels:{color:t.muted,boxWidth:12,filter:v=>{var k;let _=e[(k=v.datasetIndex)!=null?k:-1];return!(_!=null&&_.csvIsFit||_!=null&&_.csvSkipLegend)}}},tooltip:{callbacks:{label:v=>{let _=v.raw,k=s.xIsDate?ec(_.x):Ts(_.x),S=n&&v.dataset.label?`[${v.dataset.label}] `:"",x=_.label?`${_.label}: `:"",y=_.size!==void 0&&s.sizeLabel?` \xB7 ${s.sizeLabel}: ${Ts(_.size)}`:"";return`${S}${x}(${k}, ${Ts(_.y)})${y}`}}}}}},fitText:f,formulaError:g}}var di="(row number)";function $o(s,t,e,n,i,o,r,a){let l=new Map,c=0;return s.forEach((h,u)=>{var v,_,k,S,x;let f=hn((v=h[e])!=null?v:""),g;if(t===di)g=u+1;else if(o){let y=r((_=h[t])!=null?_:"");g=y?y.getTime():null}else g=hn((k=h[t])!=null?k:"");if(g===null||f===null){c++;return}let p=n?((S=h[n])!=null?S:"").trim()||"\u2014":"",b=l.get(p);b||(b=[],l.set(p,b));let m={x:g,y:f,label:a(h)};if(i){let y=hn((x=h[i])!=null?x:"");y!==null&&(m.size=y)}b.push(m)}),{series:[...l.entries()].sort((h,u)=>h[0]==="\u2014"?1:u[0]==="\u2014"?-1:h[0].localeCompare(u[0])).map(([h,u])=>({label:h,points:u})),skipped:c}}function wg(s,t,e){return s.filter(n=>{if(e.has(n))return!1;let i=new Set(t.map(o=>{var r;return((r=o[n])!=null?r:"").trim()}).filter(Boolean));return i.size>=2&&i.size<=10})}function Eg(s,t,e){return s.filter(n=>{if(e.has(n))return!1;let i=new Set(t.map(o=>{var r;return((r=o[n])!=null?r:"").trim()}).filter(Boolean));return i.size>=1&&i.size<=30})}function Ho(s,t,e,n,i){let o=new Map,r=new Set,a=0,l=xt(t);s.forEach(u=>{var m,v,_;let f=0;if(i!=="count"){let k=hn((m=u[e!=null?e:""])!=null?m:"");if(k===null){a++;return}f=k}let g=((v=u[t])!=null?v:"").trim(),p=l?g?g.split(",").map(k=>k.trim()).filter(Boolean):["\u2014"]:[g||"\u2014"],b=n?((_=u[n])!=null?_:"").trim()||"\u2014":"";r.add(b),p.forEach(k=>{var y;let S=o.get(k);S||(S=new Map,o.set(k,S));let x=(y=S.get(b))!=null?y:{sum:0,n:0};x.sum+=f,x.n+=1,S.set(b,x)})});let c=(u,f)=>u==="\u2014"?1:f==="\u2014"?-1:u.localeCompare(f,void 0,{numeric:!0}),d=[...o.keys()].sort(c),h=[...r].sort(c).map(u=>({label:u,values:d.map(f=>{var p;let g=(p=o.get(f))==null?void 0:p.get(u);return!g||g.n===0?0:i==="count"?g.n:i==="sum"?g.sum:g.sum/g.n})}));return{categories:d,series:h,skipped:a}}function zo(s,t,e,n){let i=s.series.length>1;return{type:"bar",data:{labels:s.categories,datasets:s.series.map((o,r)=>({label:o.label||e,data:o.values,backgroundColor:i?n.series[r%n.series.length]:n.accent,borderRadius:3}))},options:{responsive:!0,maintainAspectRatio:!1,scales:{x:{title:{display:!!t,text:t,color:n.muted},ticks:{color:n.muted,autoSkip:!1,maxRotation:60},grid:{display:!1}},y:{beginAtZero:!0,title:{display:!!e,text:e,color:n.muted},ticks:{color:n.muted},grid:{color:n.grid}}},plugins:{legend:{display:i,labels:{color:n.muted,boxWidth:12}}}}}}async function Dg(s,t){var e,n,i,o,r,a;try{let l=t.ownerDocument.createElement("canvas");l.width=t.width,l.height=t.height;let c=l.getContext("2d");if(!c||!l.toBlob){new Ze.Notice("PNG export isn't available here.");return}let d=(e=t.ownerDocument.defaultView)==null?void 0:e.getComputedStyle(t.ownerDocument.body);c.fillStyle=(d==null?void 0:d.getPropertyValue("--background-primary").trim())||"#ffffff",c.fillRect(0,0,l.width,l.height),c.drawImage(t,0,0);let h=await new Promise(m=>l.toBlob(m,"image/png"));if(!h){new Ze.Notice("PNG export failed.");return}let u=(o=(i=(n=s.file)==null?void 0:n.parent)==null?void 0:i.path)!=null?o:"",f=new Date,g=`${me(f)} ${String(f.getHours()).padStart(2,"0")}${String(f.getMinutes()).padStart(2,"0")}`,p=`${(a=(r=s.file)==null?void 0:r.basename)!=null?a:"chart"} chart ${g}.png`,b=(0,Ze.normalizePath)(u?`${u}/${p}`:p);await s.app.vault.createBinary(b,await h.arrayBuffer()),new Ze.Notice(`Saved ${b}`)}catch(l){new Ze.Notice(`PNG export failed: ${l instanceof Error?l.message:String(l)}`,6e3)}}function sc(s,t,e){t.createEl("button",{cls:"csv-cfg-btn csv-chart-export-btn",text:"\u2B07 PNG",title:"Save this chart as a PNG next to the CSV"}).addEventListener("click",()=>{Dg(s,e)})}function fi(s){return s.rows.length>=2&&hi(s.headers,s.rows).length>=1}async function nc(s,t){var z,N,W;let e=s.getFilteredRows(),n=hi(s.headers,s.rows);if(!n.length){t.createEl("p",{text:"No numeric column to chart.",cls:"csv-empty-state"});return}s.searchQuery.trim()&&t.createDiv({cls:"csv-search-results",text:`Chart over ${e.length} of ${s.rows.length} entries`});let i=s.fileCfg,o=s.getDateCol(),r=(z=s.titleKey())!=null?z:s.headers[0],a=new Set([r,...n,...o?[o]:[]]);s.headers.forEach(I=>{s.isNotesCol(I)&&a.add(I)});let l=Eg(s.headers,s.rows,a),c=[...o?[o]:[],...n.filter(I=>I!==o),di,...l],d=i.chartXCol&&c.includes(i.chartXCol)?i.chartXCol:c[0],h=l.includes(d),u=i.chartAgg==="sum"||i.chartAgg==="avg"?i.chartAgg:"count",f=n,g=i.chartYCol&&f.includes(i.chartYCol)?i.chartYCol:(N=f.find(I=>I!==d))!=null?N:f[0],p=i.chartFit==="linear"?"linear":"none",b=(W=i.chartFormula)!=null?W:"",m=t.createDiv({cls:"csv-chart-view"}),v=m.createDiv({cls:"csv-chart-controls"}),_=I=>{s.saveFileCfg({...s.fileCfg,...I}),s.renderViewPreservingScroll()},k=(I,q,Q,Z)=>{let nt=v.createDiv({cls:"csv-chart-control"});nt.createSpan({cls:"csv-chart-control-label",text:I});let X=nt.createEl("select",{cls:"csv-chart-select",attr:{"aria-label":I}});return q.forEach(tt=>{let at=X.createEl("option",{text:tt,value:tt});tt===Q&&(at.selected=!0)}),X.addEventListener("change",()=>Z(X.value)),X};k("X",c,d,I=>_({chartXCol:I})),(!h||u!=="count")&&k(h?`Y (${u})`:"Y",f,g,I=>_({chartYCol:I})),h&&k("Agg",["count","sum","avg"],u,I=>_({chartAgg:I}));let S=new Set([d,g,r]);s.headers.forEach(I=>{s.isNotesCol(I)&&S.add(I)});let x=wg(s.headers,s.rows,S),y="\u2014",C=i.chartHueCol&&x.includes(i.chartHueCol)?i.chartHueCol:null;x.length&&k("Color",[y,...x],C!=null?C:y,I=>_({chartHueCol:I===y?void 0:I}));let E=!h&&d!==di&&(d===o||s.isDateCol(d)),D=E&&(i.chartBucket==="week"||i.chartBucket==="month")?i.chartBucket:null,w=i.chartAgg==="avg"||i.chartAgg==="count"?i.chartAgg:"sum",M=E&&!D&&!!i.chartSmooth;E&&(k("By",["day","week","month"],D!=null?D:"day",I=>_({chartBucket:I==="day"?void 0:I})),D&&k("Agg",["sum","avg","count"],w,I=>_({chartAgg:I})));let L=n.filter(I=>I!==g&&I!==d),O=!h&&!D&&i.chartSizeCol&&L.includes(i.chartSizeCol)?i.chartSizeCol:null;if(!h&&!D&&L.length&&k("Size",[y,...L],O!=null?O:y,I=>_({chartSizeCol:I===y?void 0:I})),h){let I=Ho(e,d,u==="count"?null:g,C,u),q=m.createDiv({cls:"csv-chart-wrap"}),Q=q.createEl("canvas",{cls:"csv-chart-canvas"});if(!I.categories.length){q.remove(),m.createEl("p",{text:`No rows with a "${d}" value to chart.`,cls:"csv-empty-state"});return}I.skipped>0&&m.createDiv({cls:"csv-chart-footer"}).createSpan({cls:"csv-chart-skipped",text:`${I.skipped} row${I.skipped===1?"":"s"} skipped (no numeric value)`});let Z=u==="count"?"count":`${u}(${g})`,nt=zo(I,d,Z,Ls(t));s.chartInstance&&(s.chartInstance.destroy(),s.chartInstance=null);let{Chart:X}=await Qe();if(!Q.isConnected)return;s.chartInstance=new X(Q,nt),sc(s,v,Q);return}v.createEl("button",{cls:`csv-cfg-btn csv-chart-fit-btn ${p==="linear"?"active":""}`,text:"Best fit",title:"Toggle a least-squares fit line"}).addEventListener("click",()=>_({chartFit:p==="linear"?"none":"linear"})),E&&!D&&v.createEl("button",{cls:`csv-cfg-btn csv-chart-smooth-btn ${M?"active":""}`,text:"Smooth",title:"Toggle a 7-day rolling average (raw values stay as dots)"}).addEventListener("click",()=>_({chartSmooth:M?void 0:!0}));let P=v.createDiv({cls:"csv-chart-control csv-chart-formula-wrap"});P.createSpan({cls:"csv-chart-control-label",text:"y ="});let T=P.createEl("input",{cls:"csv-chart-formula-input",type:"text",value:b,placeholder:"overlay, e.g. 2x + 1",attr:{spellcheck:"false",autocomplete:"off",enterkeyhint:"done"}}),U=()=>{T.value.trim()!==b.trim()&&_({chartFormula:T.value})};T.addEventListener("change",U),T.addEventListener("keydown",I=>{I.key==="Enter"&&(I.preventDefault(),T.blur())});let F=$o(e,d,g,C,O,E,I=>s.parseDate(I),I=>s.getTitle(I)),G=F.skipped,H=D?F.series.map(I=>({label:I.label,points:Bo(I.points,D,w)})):F.series,A=m.createDiv({cls:"csv-chart-wrap"}),j=A.createEl("canvas",{cls:"csv-chart-canvas"}),Y=m.createDiv({cls:"csv-chart-footer"});if(!H.some(I=>I.points.length)){A.remove(),Y.remove(),m.createEl("p",{text:`No rows with both "${d}" and "${g}" values to plot.`,cls:"csv-empty-state"});return}let $={series:H,xIsDate:E,xLabel:d===di?"row":d,yLabel:D?w==="count"?`count / ${D}`:`${w}(${g}) / ${D}`:g,connect:E,fit:p,formula:b,sizeLabel:O!=null?O:"",smoothDays:M?7:0},R=ui($,Ls(t));R.fitText&&Y.createSpan({cls:"csv-chart-fit-text",text:R.fitText}),R.formulaError&&Y.createSpan({cls:"csv-chart-formula-error",text:`formula: ${R.formulaError}`}),G>0&&Y.createSpan({cls:"csv-chart-skipped",text:`${G} row${G===1?"":"s"} skipped (no numeric value)`}),s.chartInstance&&(s.chartInstance.destroy(),s.chartInstance=null);let{Chart:B}=await Qe();j.isConnected&&(s.chartInstance=new B(j,R.config),sc(s,v,j))}function gi(s){return s.resolveCol(["Type","type","Kind","kind","Item","item"])}function jo(s){var t;return(t=s.resolveCol(["Project","project","Projects","projects","Area","area"]))!=null?t:$t(s)}function rc(s){return s.resolveCol(["Due","due","Deadline","deadline","Due Date","Due date","due date"])}function pi(s){return s.resolveCol(["Priority","priority","Prio","prio","Importance","importance"])}var Mg=["task","todo","to-do","action",""],Tg=["task","todo","to-do","action","note","idea","reference","ref"],ac=["done","complete","completed","finished","closed","resolved","yes","x","\u2713","true","1"],Lg={high:0,med:1,medium:1,normal:1,low:2};function Fe(s){if(rc(s)||pi(s))return!0;let t=gi(s);return t?s.rows.some(e=>{var n;return Tg.includes(((n=e[t])!=null?n:"").trim().toLowerCase())}):!1}function Wo(s,t,e){var n;return e?ac.includes(((n=t[e])!=null?n:"").trim().toLowerCase()):!1}function ic(s){let t=Lg[(s!=null?s:"").trim().toLowerCase()];return t===void 0?3:t}function oc(s){return(s!=null?s:"").trim()?0:1}function Ag(){return me()}function Rg(s,t){let e=new Map;s.rows.forEach(o=>{var a,l;let r=((a=o[t])!=null?a:"").trim();r&&ac.includes(r.toLowerCase())&&e.set(r,((l=e.get(r))!=null?l:0)+1)});let n="done",i=0;return e.forEach((o,r)=>{o>i&&(n=r,i=o)}),n}function mi(s,t){var D,w;let e=jo(s),n=gi(s),i=s.getStatusCol(),o=rc(s),r=pi(s),a=(D=s.titleKey())!=null?D:s.headers[0],l=t.createDiv({cls:"csv-library-filters"}),c=new Set;e&&s.rows.forEach(M=>{var L;((L=M[e])!=null?L:"").split(",").map(O=>O.trim()).filter(Boolean).forEach(O=>c.add(O))});let d=l.createEl("select",{cls:"csv-library-filter-select"});d.createEl("option",{text:e?"All projects":"All",value:"all"}),Array.from(c).sort().forEach(M=>d.createEl("option",{text:M,value:M})),d.value=s.taskProjectFilter;let h=new Set;n&&s.rows.forEach(M=>{var O;let L=((O=M[n])!=null?O:"").trim();L&&h.add(L)});let u=null;h.size>0&&(u=l.createEl("select",{cls:"csv-library-filter-select"}),u.createEl("option",{text:"All types",value:"all"}),Array.from(h).sort().forEach(M=>u.createEl("option",{text:M,value:M})),u.value=s.taskTypeFilter);let f=()=>{s.taskProjectFilter=d.value,u&&(s.taskTypeFilter=u.value),s.renderView(!0)};d.addEventListener("change",f),u==null||u.addEventListener("change",f);let g=s.searchQuery.toLowerCase().trim(),p=s.rows.filter(M=>{var L,O;return!(s.taskProjectFilter!=="all"&&e&&!((L=M[e])!=null?L:"").split(",").map(P=>P.trim().toLowerCase()).includes(s.taskProjectFilter.toLowerCase())||s.taskTypeFilter!=="all"&&n&&((O=M[n])!=null?O:"").trim().toLowerCase()!==s.taskTypeFilter.toLowerCase()||g&&!s.headers.some(V=>{var P;return((P=M[V])!=null?P:"").toLowerCase().includes(g)}))});(s.taskProjectFilter!=="all"||s.taskTypeFilter!=="all"||g)&&t.createDiv({cls:"csv-library-result-count",text:`Showing ${p.length} of ${s.rows.length} entries`});let b={},m=M=>{var O;return e&&((O=M[e])!=null?O:"").split(",").map(V=>V.trim()).filter(Boolean)[0]||"\u2014"};p.forEach(M=>{var P,T,U;let L=n?((P=M[n])!=null?P:"").trim():"",O=Mg.includes(L.toLowerCase())?"Tasks":L,V=m(M);b[O]||(b[O]={}),((U=(T=b[O])[V])!=null?U:T[V]=[]).push(M)});let v=t.createDiv({cls:"csv-tasks"}),_=Ag(),k=i?Rg(s,i):"done",x=((w=s.fileCfg.cardFields)!=null?w:s.headers).filter(M=>M!==e&&M!==n&&M!==i),y=[];i&&y.push({name:"",cls:"csv-tasks-check-cell"}),x.forEach(M=>{let L="";M===a?L="csv-tasks-name-cell":M===o?L="csv-tasks-due":M===r?L="csv-tasks-priority":s.isNotesCol(M)?L="csv-tasks-generic-cell csv-tasks-notes-cell":L="csv-tasks-generic-cell",y.push({name:M,cls:L})});let C=(M,L)=>{L.sort((O,V)=>{var U,F,G,H,A,j;let P=Wo(s,O,i),T=Wo(s,V,i);if(P!==T)return P?1:-1;if(r){let Y=ic((U=O[r])!=null?U:"")-ic((F=V[r])!=null?F:"");if(Y)return Y}if(o){let Y=oc((G=O[o])!=null?G:"")-oc((H=V[o])!=null?H:"");if(Y)return Y;let $=((A=O[o])!=null?A:"").localeCompare((j=V[o])!=null?j:"");if($)return $}return s.getTitle(O).localeCompare(s.getTitle(V))}),L.forEach(O=>{let V=Wo(s,O,i),P=M.createEl("tr");if(i){let U=P.createEl("td",{cls:"csv-tasks-check-cell"}).createEl("span",{cls:`csv-tasks-check ${V?"is-done":""}`,text:V?"\u2713":""});U.setAttr("title",V?"Mark not done":"Mark done"),U.addEventListener("click",F=>{F.stopPropagation(),O[i]=V?"":k,s.scheduleSave(),s.renderView(!0)})}x.forEach(T=>{var U,F,G;if(T===a)Og(s,P,O,a,V);else if(T===o){let H=P.createEl("td",{cls:"csv-tasks-due csv-tasks-editable"}),A=o?((U=O[o])!=null?U:"").slice(0,10):"";H.setText(A||"\u2014"),A&&!V&&A<_&&H.addClass("csv-tasks-overdue"),Ns(s,H,O,T)}else if(T===r){let H=P.createEl("td",{cls:"csv-tasks-priority csv-tasks-editable",text:r&&O[r]||"\u2014"});H.addEventListener("click",A=>{var Y;A.stopPropagation();let j=Array.from(new Set([...s.getColumnValues(r),"high","medium","low"]));It(H,(Y=O[r])!=null?Y:"",j,$=>{O[r]=$,s.scheduleSave(),s.renderView(!0)},s.contentEl)})}else if(s.isNotesCol(T)){let H=((F=O[T])!=null?F:"").replace(/#{1,6}\s/g,"").replace(/[*_>`]/g,"").replace(/\n+/g," ").trim(),A=H?H.length>50?H.slice(0,48)+"\u2026":H:"\u2014",j=P.createEl("td",{text:A,cls:"csv-tasks-generic-cell csv-tasks-notes-cell csv-tasks-editable"});Ns(s,j,O,T)}else{let H=(G=O[T])!=null?G:"",A=H.length>40?H.slice(0,38)+"\u2026":H,j=P.createEl("td",{text:A||"\u2014",cls:"csv-tasks-generic-cell csv-tasks-editable"});Ns(s,j,O,T)}}),P.addEventListener("contextmenu",T=>s.openRowContextMenu(O,T))})},E=Object.keys(b).sort((M,L)=>M==="Tasks"?-1:L==="Tasks"?1:M.localeCompare(L));if(E.forEach(M=>{Pg(s,v,M==="Tasks"?M:Tt(M),b[M],C,y)}),E.length===0){let M=v.createDiv({cls:"csv-empty-state"});M.createEl("p",{text:g||s.taskProjectFilter!=="all"||s.taskTypeFilter!=="all"?"No entries match your filters.":"No tasks yet."}),(g||s.taskProjectFilter!=="all"||s.taskTypeFilter!=="all")&&M.createEl("button",{cls:"csv-clear-filters-btn",text:"Clear filters"}).addEventListener("click",()=>{s.taskProjectFilter="all",s.taskTypeFilter="all",s.searchQuery="",s.renderView()})}}function Pg(s,t,e,n,i,o){if(Object.keys(n).length===0)return;t.createDiv({cls:"csv-tasks-section-header",text:e});let r=t.createDiv({cls:"csv-tasks-section"});Object.keys(n).sort().forEach(a=>{let l=n[a],c=r.createEl("details",{cls:"csv-tasks-group"});c.open=!0;let d=c.createEl("summary",{cls:"csv-tasks-group-header"});d.innerHTML=`\u25B6 ${a} ${l.length}`;let u=c.createDiv({cls:"csv-tasks-table-wrapper"}).createEl("table",{cls:"csv-tasks-table"}),f=120;o.forEach(m=>{m.cls.includes("check-cell")?f+=30:m.cls.includes("priority")?f+=90:m.cls.includes("due")?f+=150:m.cls.includes("notes-cell")?f+=140:m.cls.includes("generic-cell")&&(f+=150)}),u.style.minWidth=`${f}px`;let p=u.createEl("thead").createEl("tr");o.forEach(m=>p.createEl("th",{text:m.name,cls:m.cls}));let b=u.createEl("tbody");i(b,l)})}function Og(s,t,e,n,i){var h;let o=t.createEl("td",{cls:"csv-tasks-name-cell"}),r=(h=s.isHighlighted)!=null&&h.call(s,e)?"csv-title-highlight":"",a=o.createSpan({cls:`csv-tasks-link ${i?"csv-tasks-done":""} ${r}`,text:e[n]||"Untitled"}),l=s.getNotesCol();a.addEventListener("click",()=>{l?s.openNoteExpander(e,l):s.openOrCreateNotes(e)});let c=s.notesFileExists(e),d=o.createEl("button",{cls:`csv-tasks-page-icon ${c?"exists":""}`,text:c?"\u{1F4C4}":"+"});d.setAttr("title",c?"Open page":"Create page"),d.addEventListener("click",u=>{u.stopPropagation(),s.openOrCreateNotes(e)})}function bi(s){let t=[];return s.isTravelFile()&&t.push({id:"travel",label:"Travel"}),s.hasDateColumn()&&t.push({id:"dashboard",label:"Dashboard"}),Fe(s)&&t.push({id:"tasks",label:"Tasks"}),$t(s)&&(t.push({id:"library",label:"Cards"}),t.push({id:"kanban-genre",label:"Kanban"})),t.push({id:"table",label:"Table"}),s.rows.length>0&&t.push({id:"focus",label:"Focus"}),Sn(s)&&t.push({id:"stats",label:"Stats"}),fi(s)&&t.push({id:"chart",label:"Chart"}),t}function lc(s,t){var u,f,g;let e=t.createDiv({cls:"csv-toolbar"});e.createDiv({cls:"csv-toolbar-title",text:(f=(u=s.file)==null?void 0:u.basename)!=null?f:""});let n=e.createDiv({cls:"csv-toolbar-controls"});n.createDiv({cls:"csv-row-count",text:`${s.rows.length} entries`});let i=n.createDiv({cls:"csv-mode-group"}),o=bi(s),r=i.createEl("select",{cls:"csv-mode-select",attr:{"aria-label":"View mode"}});if(o.forEach(({id:p,label:b})=>{let m=r.createEl("option",{text:b,value:p});s.mode===p&&(m.selected=!0)}),r.addEventListener("change",()=>{s.mode=r.value,s.renderView()}),s.mode!=="dashboard"){let p=n.createEl("button",{cls:"csv-cfg-btn csv-search-toggle",text:"\u{1F50D}",title:"Search"}),b=n.createDiv({cls:"csv-search-wrap"}),m=b.createDiv({cls:"csv-search-input-wrap"}),v=m.createEl("input",{cls:"csv-search-input",type:"text",placeholder:"Search...",value:s.searchQuery,attr:{inputmode:"search",enterkeyhint:"search",autocomplete:"off"}}),_=m.createEl("button",{cls:"csv-search-clear",text:"\xD7",title:"Clear search"});_.toggleClass("is-hidden",!s.searchQuery),b.createEl("button",{cls:"csv-search-done",text:"Done",title:"Dismiss keyboard"}).addEventListener("click",x=>{if(x.preventDefault(),!v.value){e.removeClass("csv-toolbar--search-expanded"),p.removeClass("has-query"),s.searchQuery="",s.renderView(!0);return}v.blur()});let S=null;v.addEventListener("input",x=>{s.searchQuery=x.target.value,_.toggleClass("is-hidden",!s.searchQuery),p.toggleClass("has-query",!!s.searchQuery),S!==null&&window.clearTimeout(S),S=window.setTimeout(()=>{S=null,s.renderView(!0)},120)}),v.addEventListener("keydown",x=>{x.key==="Enter"&&(x.preventDefault(),v.blur())}),_.addEventListener("click",()=>{s.searchQuery="",v.value="",_.addClass("is-hidden"),p.removeClass("has-query"),v.focus({preventScroll:!0}),s.renderView(!0)}),s.searchQuery&&p.addClass("has-query"),p.addEventListener("click",()=>{e.addClass("csv-toolbar--search-expanded"),v.focus({preventScroll:!0})})}if(s.mode==="table"&&s.hasDateColumn()){let p=(g=s.fileCfg.sortNewestFirst)!=null?g:!0;n.createEl("button",{cls:`csv-cfg-btn ${p?"active":""}`,text:p?"\u2193 Newest":"\u2191 Oldest",title:"Toggle sort order"}).addEventListener("click",()=>{var v;let m=s.fileCfg;m.sortNewestFirst=!((v=m.sortNewestFirst)==null||v),s.saveFileCfg(m),s.tableSortCol=null,s.renderViewPreservingScroll()})}let a=()=>{var b,m;let p={title:s.resolveCol(ge),category:s.resolveCol(ss),status:s.resolveCol(ns),notes:s.resolveCol(pe),image:s.resolveCol(es),anki:Ai(s)};new bn(s.app,s.headers,(m=(b=s.file)==null?void 0:b.path)!=null?m:"",s.fileCfg,s.autoDetectBooleanColumns(),s.autoDetectCategoricalColumns(),p,bi(s),v=>{s.saveFileCfg(v),v.defaultMode&&(s.mode=v.defaultMode),s.renderView()},()=>s.headers,()=>s.fileCfg,v=>s.addColumn(v),v=>s.removeColumn(v),v=>s.cleanupBooleanColumn(v)).open()},l=()=>s.backupToArchive(),c=()=>_r(s);n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-secondary",text:"\u2699 Config",title:"Configure this file's columns and views"}).addEventListener("click",a),n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-secondary",text:"\u{1F4BE} Backup",title:"Copy this file to Archive/ with today's date"}).addEventListener("click",l),n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-secondary",text:"\u{1F3B4} Anki",title:"Sync rows to Anki (needs Anki desktop + AnkiConnect)"}).addEventListener("click",c),n.createEl("button",{cls:"csv-add-btn",text:"+ Add"}).addEventListener("click",()=>s.openAddModal()),n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-overflow",text:"\u22EF",title:"More actions"}).addEventListener("click",p=>{let b=new vi.Menu;b.addItem(m=>m.setTitle("Config").setIcon("settings").onClick(a)),b.addItem(m=>m.setTitle("Backup").setIcon("save").onClick(l)),b.addItem(m=>m.setTitle("Sync to Anki").setIcon("layers").onClick(c)),b.addSeparator(),b.addItem(m=>m.setTitle("Built 2026-07-13 11:41").setIcon("info").setDisabled(!0)),b.showAtMouseEvent(p)}),n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-secondary csv-info-btn",text:"\u24D8",title:"Built 2026-07-13 11:41 \u2014 click to confirm"}).addEventListener("click",()=>new vi.Notice("datadeck \u2014 built 2026-07-13 11:41",4e3))}function Fg(s){return s&&typeof s=="object"&&"basename"in s?s:null}var Ig=["Author","author","By","by","Source","source","Speaker","speaker","Artist","artist","Director","director"];async function cc(s,t,e,n){var v,_,k;let i=t.split(` +`).filter(_=>_.trim()).slice(0,3).join(" \xB7 "),m=b?b.slice(0,200)+(b.length>200?"\u2026":""):"+ Add note",v=f.createSpan({text:m});b||v.addClass("csv-table-notes-empty"),f.title="Click to open note",f.addEventListener("click",_=>{_.stopPropagation(),s.openNoteExpander(l,u)})}else if(s.isSelectCol(u))s.renderSelectField(f,l,u);else{let b=(p=l[u])!=null?p:"";f.setText(b),b.length>80&&(f.title=b),Ns(s,f,l,u)}});let d=c.createEl("td",{cls:"csv-table-action"}),h=s.notesFileExists(l);d.createEl("button",{cls:`csv-table-notes-btn ${h?"exists":""}`,text:h?"\u{1F4C4}":"\u271A",title:h?"Open notes":"Create notes"}).addEventListener("click",()=>s.openOrCreateNotes(l)),d.createEl("button",{cls:"csv-table-del-btn",text:"\u2715",title:"Delete row (Undo available)"}).addEventListener("click",()=>s.deleteWithUndo(l))}),r||requestAnimationFrame(()=>{a.querySelectorAll("td:not(.csv-table-notes-cell):not(.csv-table-action)").forEach(l=>{l.scrollHeight>l.clientHeight+1&&l.addClass("csv-cell--clipped")})})}function Ns(s,t,e,n){t.addEventListener("click",i=>{var h,u;if(t.querySelector("input"))return;t.empty();let o=(h=s.fileCfg.dateColumns)==null?void 0:h.includes(n),r=((u=e[n])!=null?u:"").trim(),a=o||Et(n)&&(r===""||mn.test(r)),l=a?r.slice(0,10):r,c=t.createEl("input",{cls:"csv-inline-input",value:l,type:a?"date":"text"});c.focus(),a||c.select(),c.addEventListener("click",f=>f.stopPropagation());let d=!1;c.addEventListener("blur",()=>{var f;!d&&c.value!==l&&(e[n]=c.value,s.scheduleSave()),t.empty(),t.setText(((f=e[n])!=null?f:"")||"\u2014")}),c.addEventListener("keydown",f=>{f.key==="Enter"&&c.blur(),f.key==="Escape"&&(d=!0,c.blur())})})}function Sn(s){return!!(s.getCategoryCol()||s.getStatusCol()||br(s)||s.authorKey())}function br(s){return s.resolveCol(["Rating","rating","Score","score","Score /5","Stars","stars"])}function Hs(s){var i;let t=(s!=null?s:"").trim();if(!t)return null;let e=((i=t.match(/★/g))!=null?i:[]).length;if(e>0)return e;let n=parseFloat(t);return isNaN(n)||n<=0?null:Math.min(5,n)}var vr=["watched","read","finished","completed","done","yes","seen"],yr=["watching","reading","in progress","in-progress"],Xc=["dropped","abandoned","dnf"];function Qc(s){let t=s.toLowerCase();return vr.includes(t)?"is-done":yr.includes(t)?"is-progress":Xc.includes(t)?"is-dropped":""}function Bs(s,t){let e=new Map;return s.forEach(n=>t(n).forEach(i=>{var o;return e.set(i,((o=e.get(i))!=null?o:0)+1)})),e}function $s(s,t,e,n){if(!e.length)return;let i=s.createDiv({cls:"csv-stats-section"});i.createDiv({cls:"csv-stats-section-title",text:t});let o=Math.max(...e.map(r=>r.count));e.forEach(r=>{var h;let a=i.createDiv({cls:"csv-stats-bar-row"});a.createDiv({cls:"csv-stats-bar-label",text:r.label,attr:{title:r.label}});let c=a.createDiv({cls:"csv-stats-bar-track"}).createDiv({cls:`csv-stats-bar-fill ${(h=r.cls)!=null?h:""}`});c.style.width=`${Math.max(2,Math.round(r.count/o*100))}%`;let d=n>0?Math.round(r.count/n*100):0;a.createDiv({cls:"csv-stats-bar-count",text:`${r.count} \xB7 ${d}%`}),r.onClick&&(a.addClass("is-clickable"),a.title=`Show "${r.label}" in the library`,a.addEventListener("click",r.onClick))})}function xr(s,t){let e=s.getFilteredRows();if(s.searchQuery.trim()&&t.createDiv({cls:"csv-search-results",text:`Stats over ${e.length} of ${s.rows.length} entries`}),!e.length){t.createEl("p",{text:"No entries to chart.",cls:"csv-empty-state"});return}let n=t.createDiv({cls:"csv-stats-wrap"}),i=s.getStatusCol(),o=s.getCategoryCol(),r=br(s),a=s.authorKey(),l=s.resolveCol(["Year","year"]),c=n.createDiv({cls:"csv-stats-overview"}),d=(u,f)=>{let g=c.createDiv({cls:"csv-stats-chip"});g.createDiv({cls:"csv-stats-chip-value",text:u}),g.createDiv({cls:"csv-stats-chip-label",text:f})};if(d(String(e.length),"entries"),i){let u=e.filter(g=>{var p;return vr.includes(((p=g[i])!=null?p:"").toLowerCase().trim())}).length;u>0&&d(`${u} \xB7 ${Math.round(u/e.length*100)}%`,"done");let f=e.filter(g=>{var p;return yr.includes(((p=g[i])!=null?p:"").toLowerCase().trim())}).length;f>0&&d(String(f),"in progress")}if(o){let u=Bs(e,f=>{var g;return((g=f[o])!=null?g:"").split(",").map(p=>p.trim()).filter(Boolean)});u.size>0&&d(String(u.size),o.toLowerCase()==="genre"||o.toLowerCase()==="genres"?"genres":"categories")}if(r){let u=e.map(f=>Hs(f[r])).filter(f=>f!==null);if(u.length){let f=u.reduce((g,p)=>g+p,0)/u.length;d(`\u2605 ${f.toFixed(1)}`,`avg of ${u.length} rated`)}}let h=(u,f)=>{s.libraryStatusFilter=u!=null?u:"all",s.libraryGenreFilter=f!=null?f:"all",s.mode="library",s.renderView()};if(i){let u=Bs(e,g=>{var b;let p=((b=g[i])!=null?b:"").trim();return p?[p]:[]}),f=Array.from(u.entries()).sort((g,p)=>p[1]-g[1]).map(([g,p])=>({label:g,count:p,cls:Qc(g),onClick:o?()=>h(g,null):void 0}));$s(n,`By ${i.toLowerCase()}`,f,e.length)}if(o){let u=Bs(e,g=>{var p;return((p=g[o])!=null?p:"").split(",").map(b=>b.trim()).filter(Boolean)}),f=Array.from(u.entries()).sort((g,p)=>p[1]-g[1]||g[0].localeCompare(p[0])).slice(0,12).map(([g,p])=>({label:g,count:p,onClick:()=>h(null,g)}));$s(n,`By ${o.toLowerCase()}`,f,e.length)}if(r){let u=new Map,f=0;if(e.forEach(g=>{var m;let p=Hs(g[r]);if(p===null)return;let b=Math.min(5,Math.max(1,Math.round(p)));u.set(b,((m=u.get(b))!=null?m:0)+1),f++}),f>0){let g=[5,4,3,2,1].filter(p=>{var b;return((b=u.get(p))!=null?b:0)>0}).map(p=>({label:"\u2605".repeat(p),count:u.get(p),cls:"is-rating"}));$s(n,"Ratings",g,f)}}if(l){let u=Bs(e,f=>{var p;let g=((p=f[l])!=null?p:"").match(/\d{4}/);return g?[g[0]]:[]});if(u.size>1){let f=Array.from(u.entries()).sort((g,p)=>g[0].localeCompare(p[0])).map(([g,p])=>({label:g,count:p}));$s(n,"By year",f,e.length)}}if(a){let u=Bs(e,g=>{var b;let p=((b=g[a])!=null?b:"").trim();return p?[p]:[]}),f=Array.from(u.entries()).filter(([,g])=>g>1);if(f.length>=2){let g=f.sort((p,b)=>b[1]-p[1]||p[0].localeCompare(b[0])).slice(0,8).map(([p,b])=>({label:p,count:b}));$s(n,`Top ${a.toLowerCase()}s`,g,e.length)}}}function $t(s){let t=s.fileCfg.kanbanGroupCol;if(t&&s.headers.includes(t))return t;let e=s.getCategoryCol();if(e)return e;let n=new Set;s.headers.forEach(r=>{s.isNotesCol(r)&&n.add(r)});let i=s.getDateCol();i&&n.add(i);let o=s.titleKey();return o&&n.add(o),ir(s.headers,s.rows,n)}function kn(s,t){let e=$t(s);if(!e){t.createEl("p",{text:"No groupable column found.",cls:"csv-empty-state"});return}let n=s.getCategoryCol(),i=s.getStatusCol(),o=i===e?null:i,r=s.getFilteredRows();s.searchQuery.trim()&&t.createDiv({cls:"csv-search-results",text:`Found ${r.length} of ${s.rows.length} entries`});let a=t.createDiv({cls:"csv-kanban-groupbar"});a.createSpan({cls:"csv-kanban-groupbar-label",text:"Group by"});let l=a.createEl("select",{cls:"csv-library-filter-select"});s.headers.filter(b=>!s.isNotesCol(b)).forEach(b=>{let m=l.createEl("option",{text:b===n?`${b} (default)`:b,value:b});b===e&&(m.selected=!0)}),l.addEventListener("change",()=>{let b=s.fileCfg;b.kanbanGroupCol=l.value===n?void 0:l.value,s.saveFileCfg(b),s.renderView(!0)});let c=sr(e,r.map(b=>{var m;return(m=b[e])!=null?m:""})),d=b=>{var _;let m=(_=b[e])!=null?_:"",v;if(c){let k=nr(m);v=k?[k]:[]}else v=m.split(",").map(k=>k.trim()).filter(Boolean);return v.length||(v=["\u2014"]),v},h=new Set;r.forEach(b=>d(b).forEach(m=>h.add(m)));let u=Array.from(h).sort();if(!u.length){let b=t.createDiv({cls:"csv-empty-state"});b.createEl("p",{text:s.searchQuery?"No matching entries found.":`No "${e}" values found.`}),s.searchQuery&&b.createEl("button",{cls:"csv-clear-filters-btn",text:"Clear search"}).addEventListener("click",()=>{s.searchQuery="",s.renderView()});return}let f=["In progress","Finished","Not started"],g=o?Array.from(new Set([...f,...r.map(b=>{var m;return(m=b[o])!=null?m:""}).filter(Boolean)])).filter(b=>r.some(m=>{var v;return((v=m[o])!=null?v:"")==b})):[],p=t.createDiv({cls:"csv-kanban-board"});u.forEach(b=>{let m=r.filter(S=>d(S).includes(b));if(!m.length)return;let v=p.createDiv({cls:"csv-kanban-col"}),_=v.createDiv({cls:"csv-kanban-col-header"});_.createDiv({cls:"csv-kanban-col-title",text:b}),_.createDiv({cls:"csv-kanban-col-count",text:String(m.length)});let k=v.createDiv({cls:"csv-kanban-col-body"});if(o&&g.length){g.forEach(y=>{let C=m.filter(D=>{var w;return((w=D[o])!=null?w:"")===y});if(!C.length)return;let E=k.createDiv({cls:"csv-kanban-status-group"});E.createDiv({cls:`csv-kanban-status-label status-${y.toLowerCase().replace(/\s+/g,"-")}`,text:y}),C.forEach(D=>Ti(s,E,D,o,e))});let S=new Set(g),x=m.filter(y=>{var C;return!S.has((C=y[o])!=null?C:"")});if(x.length){let y=k.createDiv({cls:"csv-kanban-status-group"});y.createDiv({cls:"csv-kanban-status-label",text:"\u2014"}),x.forEach(C=>Ti(s,y,C,o,e))}}else m.forEach(S=>Ti(s,k,S,o,e))})}function Ti(s,t,e,n,i){var C,E,D,w,M,L,O,V;let o=t.createDiv({cls:"csv-kanban-card"}),r=s.getNotesCol(),a=(E=(C=s.getImageCol)==null?void 0:C.call(s))!=null?E:null;if(a){let P=pn(s.app,(D=e[a])!=null?D:"",(M=(w=s.file)==null?void 0:w.path)!=null?M:"");if(P){let T=o.createEl("img",{cls:"csv-kanban-card-img",attr:{src:P,loading:"lazy",alt:""}});T.addEventListener("error",()=>T.remove())}}let l=o.createDiv({cls:"csv-kanban-card-title-row"});l.createDiv({cls:`csv-kanban-card-title ${(L=s.isHighlighted)!=null&&L.call(s,e)?"csv-title-highlight":""}`,text:s.getTitle(e)}).addEventListener("click",P=>{P.stopPropagation(),s.openNoteExpander(e,r!=null?r:"")});let d=s.notesFileExists(e);l.createEl("button",{cls:`csv-kanban-notes-icon ${d?"exists":""}`,text:d?"\u{1F4C4}":"+",title:d?"Open notes file":"Create notes file"}).addEventListener("click",P=>{P.stopPropagation(),s.openOrCreateNotes(e)});let u=s.getSubtitle(e);u&&o.createDiv({cls:"csv-kanban-card-sub",text:u});let f=s.titleKey(),g=s.authorKey(),p=new Set([n,f,g,i].filter(Boolean)),b=o.createDiv({cls:"csv-kanban-card-meta"});((O=s.fileCfg.cardFields)!=null?O:s.headers).forEach(P=>{if(!s.headers.includes(P)||p.has(P)||s.isNotesCol(P))return;let T=b.createDiv({cls:"csv-kanban-chip"});if(T.createSpan({cls:"csv-chip-label",text:P+": "}),s.isSelectCol(P)){let U=T.createSpan({cls:`csv-chip-value csv-chip-select${e[P]?"":" csv-chip-value--empty"}`,text:e[P]||"\u2014"});U.addEventListener("click",F=>{F.stopPropagation(),It(U,e[P],s.getColumnValues(P),G=>{e[P]=G,U.setText(G||"\u2014"),U.classList.toggle("csv-chip-value--empty",!G),s.scheduleSave()},s.contentEl,{multi:xt(P)})})}else{let U=e[P]?e[P].length>40?e[P].slice(0,38)+"\u2026":e[P]:"\u2014",F=T.createSpan({cls:`csv-chip-value${e[P]?"":" csv-chip-value--empty"}`,text:U});e[P]&&e[P].length>40&&(F.title=e[P])}});let v=s.getNotesCol(),_=!!(v&&((V=e[v])!=null&&V.trim())),k=o.createDiv({cls:"csv-kanban-notes-preview"});if(_&&v){let P=e[v].replace(/#{1,6}\s/g,"").replace(/[*_>`]/g,"").replace(/\n+/g," ").trim();k.setText(P.slice(0,120)+(P.length>120?"\u2026":"")),k.title="Click to edit"}else k.addClass("csv-kanban-notes-preview--empty"),v&&k.setText("+ Add note");let S=o.createDiv({cls:"csv-kanban-notes-editor"});S.style.display="none";let x=()=>{var j,Y,$;let P=s.contentEl.querySelector(".csv-content-area"),T=(j=P==null?void 0:P.scrollLeft)!=null?j:0,U=(Y=P==null?void 0:P.scrollTop)!=null?Y:0;k.style.display="none",S.style.display="block",S.empty();let F=S.createEl("textarea",{cls:"csv-notes-textarea"});F.value=($=v?e[v]:"")!=null?$:"",F.addEventListener("click",R=>R.stopPropagation()),F.addEventListener("mousedown",R=>R.stopPropagation()),F.addEventListener("input",()=>{F.style.height="auto",F.style.height=F.scrollHeight+"px"});let G=F.value,H=!1,A=R=>{H||(H=!0,y(R,P,T,U))};F.addEventListener("keydown",R=>{R.key==="Escape"&&A(G)}),F.addEventListener("blur",()=>A(F.value)),F.focus({preventScroll:!0}),F.setSelectionRange(0,0),F.scrollTop=0,requestAnimationFrame(()=>{F.style.height="auto",F.style.height=Math.max(120,F.scrollHeight)+"px"})},y=(P,T,U,F)=>{var G;if(v&&P!==((G=e[v])!=null?G:"")&&(e[v]=P,s.scheduleSave()),S.style.display="none",k.style.display="",P.trim()){let H=P.replace(/#{1,6}\s/g,"").replace(/[*_>`]/g,"").replace(/\n+/g," ").trim();k.setText(H.slice(0,120)+(H.length>120?"\u2026":"")),k.removeClass("csv-kanban-notes-preview--empty"),k.title="Click to edit"}else k.addClass("csv-kanban-notes-preview--empty"),k.setText(v?"+ Add note":""),k.removeAttribute("title");T&&(T.scrollLeft=U,T.scrollTop=F,requestAnimationFrame(()=>{T.scrollLeft=U,T.scrollTop=F,requestAnimationFrame(()=>{T.scrollLeft=U,T.scrollTop=F})}),setTimeout(()=>{T.scrollLeft=U,T.scrollTop=F},50))};k.addEventListener("click",P=>{if(P.stopPropagation(),v&&matchMedia("(pointer: coarse)").matches){s.openNoteExpander(e,v);return}x()}),o.addEventListener("contextmenu",P=>s.openRowContextMenu(e,P))}function wn(s,t){var E,D;let e=$t(s),n=s.getStatusCol(),i=(E=s.titleKey())!=null?E:s.headers[0],o=s.authorKey();if(!e){t.createEl("p",{text:"No groupable column found.",cls:"csv-empty-state"});return}let r=new Set;s.rows.forEach(w=>{var L;((L=w[e])!=null?L:"").split(",").map(O=>O.trim()).filter(Boolean).forEach(O=>r.add(O))});let a=new Set;n&&s.rows.forEach(w=>{var L;let M=((L=w[n])!=null?L:"").trim();M&&a.add(M)});let l=t.createDiv({cls:"csv-library-filters"}),c=l.createEl("select",{cls:"csv-library-filter-select"});c.createEl("option",{text:"All",value:"all"});let d=["watched","read","finished","completed","done","yes","seen"],h=["watching","reading","in progress","in-progress"],u=Array.from(a).some(w=>d.includes(w.toLowerCase())),f=Array.from(a).some(w=>h.includes(w.toLowerCase()));(u||f)&&(c.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500",value:"",attr:{disabled:"true"}}),u&&c.createEl("option",{text:"\u2713 Done",value:"__done__"}),f&&c.createEl("option",{text:"\u25D0 In Progress",value:"__inprogress__"}),c.createEl("option",{text:"\u25CB Not Started",value:"__notstarted__"})),a.size>0&&(c.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500",value:"",attr:{disabled:"true"}}),Array.from(a).sort().forEach(w=>{c.createEl("option",{text:w,value:w})})),c.value=s.libraryStatusFilter;let g=l.createEl("select",{cls:"csv-library-filter-select"});g.createEl("option",{text:"All genres",value:"all"}),Array.from(r).sort().forEach(w=>{g.createEl("option",{text:w,value:w})}),g.value=s.libraryGenreFilter;let p=s.resolveCol(["Year","year","Date","date"]),b=s.resolveCol(["Rating","rating","Score","score","Score /5","Stars","stars"]),m=s.resolveCol(["Theme","theme","Tags","tags","Tag","tag","Mood","mood"]),v=(D=s.fileCfg.librarySort)!=null?D:"status",_=l.createEl("select",{cls:"csv-library-filter-select"}),k=[["status","Sort: Status"],["title","Sort: Title"]];b&&k.push(["rating","Sort: Rating"]),p&&k.push(["year","Sort: Year"]),k.forEach(([w,M])=>{let L=_.createEl("option",{text:M,value:w});w===v&&(L.selected=!0)}),_.addEventListener("change",()=>{let w=s.fileCfg;w.librarySort=_.value==="status"?void 0:_.value,s.saveFileCfg(w),s.renderView(!0)});let S=()=>{s.libraryStatusFilter=c.value,s.libraryGenreFilter=g.value,s.renderView(!0)};c.addEventListener("change",S),g.addEventListener("change",S);let x=s.rows.filter(w=>{var M,L;if(s.libraryStatusFilter!=="all"&&n){let O=((M=w[n])!=null?M:"").toLowerCase();if(s.libraryStatusFilter==="__done__"){if(!d.includes(O))return!1}else if(s.libraryStatusFilter==="__inprogress__"){if(!h.includes(O))return!1}else if(s.libraryStatusFilter==="__notstarted__"){if(d.includes(O)||h.includes(O))return!1}else if(O!==s.libraryStatusFilter.toLowerCase())return!1}if(s.libraryGenreFilter!=="all"&&!((L=w[e])!=null?L:"").split(",").map(V=>V.trim().toLowerCase()).includes(s.libraryGenreFilter.toLowerCase()))return!1;if(s.searchQuery.trim()){let O=s.searchQuery.toLowerCase().trim();if(!s.headers.some(V=>{var P;return((P=w[V])!=null?P:"").toLowerCase().includes(O)}))return!1}return!0});(s.libraryStatusFilter!=="all"||s.libraryGenreFilter!=="all"||s.searchQuery.trim())&&t.createDiv({cls:"csv-library-result-count",text:`Showing ${x.length} of ${s.rows.length} entries`});let y={};x.forEach(w=>{var L;let M=s.libraryGenreFilter!=="all"?[s.libraryGenreFilter]:((L=w[e])!=null?L:"Uncategorized").split(",").map(O=>O.trim()).filter(Boolean);M.length===0&&M.push("Uncategorized"),M.forEach(O=>{y[O]||(y[O]=[]),y[O].push(w)})});let C=t.createDiv({cls:"csv-library-sections"});if(Object.keys(y).sort().forEach(w=>{var A,j,Y,$,R;let M=y[w],L=C.createEl("details",{cls:"csv-library-section"}),O=w.toLowerCase(),V=((A=s.fileCfg.collapsedGroups)!=null?A:[]).map(B=>B.toLowerCase());L.open=!((j=s.collapsedGroups)!=null&&j.has(O)||V.includes(O)),L.addEventListener("toggle",()=>{var I;let B=s.fileCfg,z=((I=B.collapsedGroups)!=null?I:[]).map(q=>q.toLowerCase()),N=new Set(z);L.open?N.delete(O):N.add(O);let W=Array.from(N);W.length===z.length&&W.every(q=>z.includes(q))||(B.collapsedGroups=W,s.saveFileCfg(B))});let P=L.createEl("summary",{cls:"csv-library-section-header"});P.innerHTML=`\u25B6 ${w} ${M.length}`;let T=L.createDiv({cls:"csv-library-grid"}),U=(B,z)=>{var N,W;return((N=B[i])!=null?N:"").localeCompare((W=z[i])!=null?W:"")},F=(B,z)=>B===null&&z===null?0:B===null?1:z===null?-1:z-B;M.sort((B,z)=>{var N,W,I,q;if(v==="title")return U(B,z);if(v==="rating"&&b)return F(Hs((N=B[b])!=null?N:""),Hs((W=z[b])!=null?W:""))||U(B,z);if(v==="year"&&p){let Q=Z=>{var X;let nt=((X=Z[p])!=null?X:"").match(/\d{4}/);return nt?parseInt(nt[0],10):null};return F(Q(B),Q(z))||U(B,z)}if(n){let Q=((I=B[n])!=null?I:"").toLowerCase(),Z=((q=z[n])!=null?q:"").toLowerCase(),nt=d.includes(Q),X=d.includes(Z);if(nt!==X)return nt?-1:1;let tt=h.includes(Q),at=h.includes(Z);if(tt!==at)return tt?-1:1}return U(B,z)});let G=(Y=s.fileCfg.cardFields)!=null?Y:s.headers,H=(R=($=s.getImageCol)==null?void 0:$.call(s))!=null?R:null;M.forEach(B=>{var q,Q,Z,nt,X,tt,at,Wt;let z=T.createDiv({cls:"csv-library-card"});if(H){let rt=pn(s.app,(q=B[H])!=null?q:"",(Z=(Q=s.file)==null?void 0:Q.path)!=null?Z:"");if(rt){let pt=z.createEl("img",{cls:"csv-library-card-img",attr:{src:rt,loading:"lazy",alt:""}});pt.addEventListener("error",()=>pt.remove())}}let N=z.createDiv({cls:`csv-library-card-title ${(nt=s.isHighlighted)!=null&&nt.call(s,B)?"csv-title-highlight":""}`});if(n){let rt=((X=B[n])!=null?X:"").toLowerCase();d.includes(rt)&&N.createSpan({cls:"csv-library-done-dot"})}N.createSpan({text:(tt=B[i])!=null?tt:"Untitled"});let W=[],I=[];for(let rt of G){if(!rt)continue;let pt=String((at=B[rt])!=null?at:"").trim();if(pt)if(rt===b){let ft=er(pt,rt);ft&&z.createDiv({cls:"csv-library-card-rating",text:ft})}else if(rt===m)I.push(...pt.split(",").map(ft=>ft.trim()).filter(Boolean));else if(rt===p){let ft=pt.match(/\d{4}/);W.push(ft?ft[0]:pt)}else W.push(pt)}if(W.length&&z.createDiv({cls:"csv-library-card-meta",text:W.join(" \xB7 ")}),s.libraryGenreFilter!=="all"){let rt=((Wt=B[e])!=null?Wt:"").split(",").map(pt=>pt.trim()).filter(pt=>pt&&pt.toLowerCase()!==s.libraryGenreFilter.toLowerCase());I.push(...rt)}if(I.length){let rt=z.createDiv({cls:"csv-library-card-tags"});I.slice(0,3).forEach(pt=>{rt.createSpan({cls:"csv-library-card-tag",text:pt})})}z.addEventListener("click",()=>{var rt;s.openNoteExpander(B,(rt=s.getNotesCol())!=null?rt:"")}),z.addEventListener("contextmenu",rt=>s.openRowContextMenu(B,rt))})}),Object.keys(y).length===0){let w=C.createDiv({cls:"csv-empty-state"});w.createEl("p",{text:"No entries match your filters."}),w.createEl("button",{cls:"csv-clear-filters-btn",text:"Clear filters"}).addEventListener("click",()=>{s.libraryStatusFilter="all",s.libraryGenreFilter="all",s.searchQuery="",s.renderView()})}}var vi=require("obsidian");var ye=require("obsidian"),Zc="http://127.0.0.1:8765",Jc=6;async function Cr(s,t){let e;try{e=await(0,ye.requestUrl)({url:Zc,method:"POST",contentType:"application/json",body:JSON.stringify({action:s,version:Jc,params:t}),throw:!1})}catch(i){throw new Error("Couldn't reach Anki. Is the desktop app open with the AnkiConnect add-on installed?")}let n=e.json;if(n.error)throw new Error(n.error);return n.result}function Ai(s){var t,e,n;return(n=(e=(t=s.titleKey())!=null?t:s.resolveCol(["Quote","Headline","Phrase","Term","Word","Question","Front","Name","Title"]))!=null?e:s.headers[0])!=null?n:null}function td(s){let t=s.fileCfg.ankiFrontCol;return t&&s.headers.includes(t)?t:Ai(s)}function Li(s){return s.replace(/&/g,"&").replace(//g,">")}function ed(s,t,e){return s.headers.filter(n=>{var i;return n!==e&&((i=t[n])!=null?i:"").trim()}).map(n=>`${Li(n)}: ${Li(t[n].trim())}`).join("
")}async function _r(s){if(!s.file)return;let t=td(s);if(!t){new ye.Notice("No column to use as the Anki card front.",6e3);return}let e=s.file.basename,n=s.rows.filter(o=>{var r;return((r=o[t])!=null?r:"").trim()});if(!n.length){new ye.Notice(`Nothing to sync \u2014 no rows with a "${t}" value.`,6e3);return}let i=new ye.Notice(`Syncing ${n.length} cards to Anki deck \u201C${e}\u201D\u2026`,0);try{await Cr("createDeck",{deck:e});let o=n.map(c=>({deckName:e,modelName:"Basic",fields:{Front:Li(c[t].trim()),Back:ed(s,c,t)},options:{allowDuplicate:!1,duplicateScope:"deck"},tags:["datadeck"]})),r=await Cr("addNotes",{notes:o}),a=r.filter(c=>c!=null).length,l=r.length-a;i.hide(),new ye.Notice(`Anki sync: ${a} added${l?`, ${l} already present`:""} (deck \u201C${e}\u201D).`,6e3)}catch(o){i.hide(),new ye.Notice(`Anki sync failed: ${o instanceof Error?o.message:String(o)}`,8e3)}}var Ze=require("obsidian");var Vo=null;async function Qe(){if(Vo)return Vo;let s=await Promise.resolve().then(()=>(Ql(),Xl));return s.Chart.register(s.LineController,s.ScatterController,s.BarController,s.LineElement,s.PointElement,s.BarElement,s.LinearScale,s.CategoryScale,s.Filler,s.Tooltip,s.Legend),Vo=s,s}var Zl={pi:Math.PI,e:Math.E},Jl={sin:Math.sin,cos:Math.cos,tan:Math.tan,asin:Math.asin,acos:Math.acos,atan:Math.atan,sqrt:Math.sqrt,log:Math.log10,ln:Math.log,exp:Math.exp,abs:Math.abs,floor:Math.floor,ceil:Math.ceil,round:Math.round,sign:Math.sign},No={min:Math.min,max:Math.max,pow:Math.pow,atan2:Math.atan2};function _g(s){let t=[],e=0;for(;e{var u;return(u=e[n])!=null?u:null},o=()=>{var u;return(u=e[n++])!=null?u:null};function r(){let u=a();for(;;){let f=i();if((f==null?void 0:f.kind)==="op"&&(f.op==="+"||f.op==="-")){n++;let g=a(),p=u;u=f.op==="+"?m=>p(m)+g(m):m=>p(m)-g(m)}else return u}}function a(){let u=l();for(;;){let f=i();if((f==null?void 0:f.kind)==="op"&&(f.op==="*"||f.op==="/"||f.op==="%")){n++;let g=l(),p=u,b=f.op;u=b==="*"?m=>p(m)*g(m):b==="/"?m=>p(m)/g(m):m=>p(m)%g(m)}else if(f&&(f.kind==="num"||f.kind==="ident"||f.kind==="lparen")){let g=l(),p=u;u=b=>p(b)*g(b)}else return u}}function l(){let u=i();if((u==null?void 0:u.kind)==="op"&&u.op==="-"){n++;let f=l();return g=>-f(g)}return(u==null?void 0:u.kind)==="op"&&u.op==="+"?(n++,l()):c()}function c(){let u=d(),f=i();if((f==null?void 0:f.kind)==="op"&&f.op==="^"){n++;let g=l();return p=>Math.pow(u(p),g(p))}return u}function d(){var f,g,p,b,m;let u=o();if(!u)throw new Error("Unexpected end of formula");if(u.kind==="num"){let v=u.value;return()=>v}if(u.kind==="lparen"){let v=r();if(((f=o())==null?void 0:f.kind)!=="rparen")throw new Error("Missing closing )");return v}if(u.kind==="ident"){if(u.name==="x")return _=>_;if(u.name in Zl){let _=Zl[u.name];return()=>_}let v=((g=i())==null?void 0:g.kind)==="lparen";if(u.name in Jl||u.name in No){if(!v)throw new Error(`${u.name} needs parentheses, e.g. ${u.name}(x)`);n++;let _=r();if(u.name in No){if(((p=o())==null?void 0:p.kind)!=="comma")throw new Error(`${u.name}(a, b) needs two arguments`);let S=r();if(((b=o())==null?void 0:b.kind)!=="rparen")throw new Error("Missing closing )");let x=No[u.name];return y=>x(_(y),S(y))}if(((m=o())==null?void 0:m.kind)!=="rparen")throw new Error("Missing closing )");let k=Jl[u.name];return S=>k(_(S))}throw new Error(`Unknown name "${u.name}" \u2014 use x, pi, e, or a function like sin()`)}throw new Error(`Unexpected "${u.kind==="op"?u.op:u.kind}"`)}let h=r();if(n{var o;let n=0,i=0;for(let r of t){let a=((o=r[e])!=null?o:"").trim();a&&(n++,hn(a)!==null&&i++)}return i>=2&&i/n>=.7})}function Sg(s){let t=s.length;if(t<2)return null;let e=0,n=0,i=0,o=0,r=0;for(let f of s)e+=f.x,n+=f.y,i+=f.x*f.x,o+=f.x*f.y,r+=f.y*f.y;let a=t*i-e*e;if(a===0)return null;let l=(t*o-e*n)/a,c=(n-l*e)/t,d=n/t,h=0,u=0;for(let f of s){let g=f.y-(l*f.x+c);h+=g*g,u+=(f.y-d)*(f.y-d)}return{slope:l,intercept:c,r2:u===0?1:1-h/u}}function kg(s,t){let e=[...s].sort((o,r)=>o.x-r.x),n=t/2,i=0;return e.map(o=>{for(;i{let r=new Date(o);if(t==="month")return new Date(r.getFullYear(),r.getMonth(),1).getTime();let a=(r.getDay()+6)%7;return new Date(r.getFullYear(),r.getMonth(),r.getDate()-a).getTime()},i=new Map;return s.forEach(o=>{var l;let r=n(o.x),a=(l=i.get(r))!=null?l:{sum:0,n:0};a.sum+=o.y,a.n+=1,i.set(r,a)}),[...i.entries()].sort((o,r)=>o[0]-r[0]).map(([o,r])=>({x:o,y:e==="count"?r.n:e==="sum"?r.sum:r.sum/r.n}))}function Ls(s){var n;let t=(n=s.ownerDocument.defaultView)==null?void 0:n.getComputedStyle(s),e=(i,o)=>(t==null?void 0:t.getPropertyValue(i).trim())||o;return{accent:e("--interactive-accent","#378ADD"),muted:e("--text-muted","#888888"),grid:e("--background-modifier-border","rgba(128,128,128,0.25)"),fitLine:e("--text-faint","#999999"),formula:e("--color-orange","#e0883a"),series:[e("--color-blue","#4e79a7"),e("--color-green","#59a14f"),e("--color-red","#e15759"),e("--color-purple","#b07aa1"),e("--color-cyan","#76b7b2"),e("--color-pink","#ff9da7"),e("--color-yellow","#edc948")]}}var Ts=s=>{if(!Number.isFinite(s))return String(s);let t=Math.abs(s);return t!==0&&(t>=1e6||t<.001)?s.toExponential(2):String(Math.round(s*1e3)/1e3)},ec=s=>{let t=new Date(s);return isNaN(t.getTime())?String(s):me(t)};function ui(s,t){var b,m;let e=[],n=s.series.length>1,i=s.series.flatMap(v=>v.points),o=i.map(v=>v.x),r=i.length?Math.min(...o):(b=s.xMin)!=null?b:0,a=i.length?Math.max(...o):(m=s.xMax)!=null?m:10,l=i.filter(v=>v.size!==void 0),c=l.length?Math.min(...l.map(v=>v.size)):0,d=l.length?Math.max(...l.map(v=>v.size)):0,h=(v,_)=>v.size===void 0?_:d===c?7:3+11*Math.sqrt((v.size-c)/(d-c)),u=[];s.series.forEach((v,_)=>{var y;let k=s.connect?[...v.points].sort((C,E)=>C.x-E.x):v.points;if(!k.length)return;let S=n?t.series[_%t.series.length]:t.accent,x=s.connect?3:4;if(((y=s.smoothDays)!=null?y:0)>0?(e.push({type:"scatter",label:v.label||s.yLabel,csvSkipLegend:!0,data:k,backgroundColor:S,borderColor:S,pointRadius:2.5,pointHoverRadius:5}),e.push({type:"line",label:v.label||s.yLabel,data:kg(k,s.smoothDays*864e5),borderColor:S,backgroundColor:S,borderWidth:2,pointRadius:0,pointHitRadius:0,tension:.3})):e.push({type:s.connect?"line":"scatter",label:v.label||s.yLabel,data:k,backgroundColor:S,borderColor:S,borderWidth:1.5,pointRadius:l.length?k.map(C=>h(C,x)):x,pointHoverRadius:l.length?k.map(C=>h(C,x)+2):6,tension:.3}),s.fit==="linear"){let C=Sg(k),E=k.map(M=>M.x),D=Math.min(...E),w=Math.max(...E);if(C&&w>D){e.push({type:"line",label:`${v.label||"Best"} fit`,csvIsFit:!0,data:[{x:D,y:C.slope*D+C.intercept},{x:w,y:C.slope*w+C.intercept}],borderColor:n?S:t.fitLine,borderDash:[6,4],borderWidth:1.5,pointRadius:0,pointHitRadius:0});let M=` \xB7 R\xB2 = ${(Math.round(C.r2*1e3)/1e3).toFixed(3)}`,L=s.xIsDate?`${C.slope*864e5>=0?"+":""}${Ts(C.slope*864e5)} ${s.yLabel}/day${M}`:`y = ${Ts(C.slope)}x ${C.intercept>=0?"+":"\u2212"} ${Ts(Math.abs(C.intercept))}${M}`;u.push(n?`${v.label}: ${L}`:s.xIsDate?`Trend: ${L}`:L)}}});let f=u.length?u.join(" \xB7 "):null,g=null;if(s.formula.trim())try{let v=tc(s.formula),_=[],k=160;for(let S=0;S<=k;S++){let x=r+(a-r)*S/k,y=v(x);Number.isFinite(y)&&_.push({x,y})}_.length&&e.push({type:"line",label:s.formula.trim(),data:_,borderColor:t.formula,borderWidth:1.5,pointRadius:0,pointHitRadius:0,tension:0})}catch(v){g=v instanceof Error?v.message:String(v)}return{config:{type:"scatter",data:{datasets:e},options:{responsive:!0,maintainAspectRatio:!1,scales:{x:{type:"linear",title:{display:!s.xIsDate&&!!s.xLabel,text:s.xLabel,color:t.muted},ticks:{color:t.muted,...s.xIsDate?{callback:v=>ec(Number(v)),maxTicksLimit:8}:{}},grid:{color:t.grid}},y:{title:{display:!!s.yLabel,text:s.yLabel,color:t.muted},ticks:{color:t.muted},grid:{color:t.grid}}},plugins:{legend:{display:e.filter(v=>!v.csvIsFit&&!v.csvSkipLegend).length>1,labels:{color:t.muted,boxWidth:12,filter:v=>{var k;let _=e[(k=v.datasetIndex)!=null?k:-1];return!(_!=null&&_.csvIsFit||_!=null&&_.csvSkipLegend)}}},tooltip:{callbacks:{label:v=>{let _=v.raw,k=s.xIsDate?ec(_.x):Ts(_.x),S=n&&v.dataset.label?`[${v.dataset.label}] `:"",x=_.label?`${_.label}: `:"",y=_.size!==void 0&&s.sizeLabel?` \xB7 ${s.sizeLabel}: ${Ts(_.size)}`:"";return`${S}${x}(${k}, ${Ts(_.y)})${y}`}}}}}},fitText:f,formulaError:g}}var di="(row number)";function $o(s,t,e,n,i,o,r,a){let l=new Map,c=0;return s.forEach((h,u)=>{var v,_,k,S,x;let f=hn((v=h[e])!=null?v:""),g;if(t===di)g=u+1;else if(o){let y=r((_=h[t])!=null?_:"");g=y?y.getTime():null}else g=hn((k=h[t])!=null?k:"");if(g===null||f===null){c++;return}let p=n?((S=h[n])!=null?S:"").trim()||"\u2014":"",b=l.get(p);b||(b=[],l.set(p,b));let m={x:g,y:f,label:a(h)};if(i){let y=hn((x=h[i])!=null?x:"");y!==null&&(m.size=y)}b.push(m)}),{series:[...l.entries()].sort((h,u)=>h[0]==="\u2014"?1:u[0]==="\u2014"?-1:h[0].localeCompare(u[0])).map(([h,u])=>({label:h,points:u})),skipped:c}}function wg(s,t,e){return s.filter(n=>{if(e.has(n))return!1;let i=new Set(t.map(o=>{var r;return((r=o[n])!=null?r:"").trim()}).filter(Boolean));return i.size>=2&&i.size<=10})}function Eg(s,t,e){return s.filter(n=>{if(e.has(n))return!1;let i=new Set(t.map(o=>{var r;return((r=o[n])!=null?r:"").trim()}).filter(Boolean));return i.size>=1&&i.size<=30})}function Ho(s,t,e,n,i){let o=new Map,r=new Set,a=0,l=xt(t);s.forEach(u=>{var m,v,_;let f=0;if(i!=="count"){let k=hn((m=u[e!=null?e:""])!=null?m:"");if(k===null){a++;return}f=k}let g=((v=u[t])!=null?v:"").trim(),p=l?g?g.split(",").map(k=>k.trim()).filter(Boolean):["\u2014"]:[g||"\u2014"],b=n?((_=u[n])!=null?_:"").trim()||"\u2014":"";r.add(b),p.forEach(k=>{var y;let S=o.get(k);S||(S=new Map,o.set(k,S));let x=(y=S.get(b))!=null?y:{sum:0,n:0};x.sum+=f,x.n+=1,S.set(b,x)})});let c=(u,f)=>u==="\u2014"?1:f==="\u2014"?-1:u.localeCompare(f,void 0,{numeric:!0}),d=[...o.keys()].sort(c),h=[...r].sort(c).map(u=>({label:u,values:d.map(f=>{var p;let g=(p=o.get(f))==null?void 0:p.get(u);return!g||g.n===0?0:i==="count"?g.n:i==="sum"?g.sum:g.sum/g.n})}));return{categories:d,series:h,skipped:a}}function zo(s,t,e,n){let i=s.series.length>1;return{type:"bar",data:{labels:s.categories,datasets:s.series.map((o,r)=>({label:o.label||e,data:o.values,backgroundColor:i?n.series[r%n.series.length]:n.accent,borderRadius:3}))},options:{responsive:!0,maintainAspectRatio:!1,scales:{x:{title:{display:!!t,text:t,color:n.muted},ticks:{color:n.muted,autoSkip:!1,maxRotation:60},grid:{display:!1}},y:{beginAtZero:!0,title:{display:!!e,text:e,color:n.muted},ticks:{color:n.muted},grid:{color:n.grid}}},plugins:{legend:{display:i,labels:{color:n.muted,boxWidth:12}}}}}}async function Dg(s,t){var e,n,i,o,r,a;try{let l=t.ownerDocument.createElement("canvas");l.width=t.width,l.height=t.height;let c=l.getContext("2d");if(!c||!l.toBlob){new Ze.Notice("PNG export isn't available here.");return}let d=(e=t.ownerDocument.defaultView)==null?void 0:e.getComputedStyle(t.ownerDocument.body);c.fillStyle=(d==null?void 0:d.getPropertyValue("--background-primary").trim())||"#ffffff",c.fillRect(0,0,l.width,l.height),c.drawImage(t,0,0);let h=await new Promise(m=>l.toBlob(m,"image/png"));if(!h){new Ze.Notice("PNG export failed.");return}let u=(o=(i=(n=s.file)==null?void 0:n.parent)==null?void 0:i.path)!=null?o:"",f=new Date,g=`${me(f)} ${String(f.getHours()).padStart(2,"0")}${String(f.getMinutes()).padStart(2,"0")}`,p=`${(a=(r=s.file)==null?void 0:r.basename)!=null?a:"chart"} chart ${g}.png`,b=(0,Ze.normalizePath)(u?`${u}/${p}`:p);await s.app.vault.createBinary(b,await h.arrayBuffer()),new Ze.Notice(`Saved ${b}`)}catch(l){new Ze.Notice(`PNG export failed: ${l instanceof Error?l.message:String(l)}`,6e3)}}function sc(s,t,e){t.createEl("button",{cls:"csv-cfg-btn csv-chart-export-btn",text:"\u2B07 PNG",title:"Save this chart as a PNG next to the CSV"}).addEventListener("click",()=>{Dg(s,e)})}function fi(s){return s.rows.length>=2&&hi(s.headers,s.rows).length>=1}async function nc(s,t){var z,N,W;let e=s.getFilteredRows(),n=hi(s.headers,s.rows);if(!n.length){t.createEl("p",{text:"No numeric column to chart.",cls:"csv-empty-state"});return}s.searchQuery.trim()&&t.createDiv({cls:"csv-search-results",text:`Chart over ${e.length} of ${s.rows.length} entries`});let i=s.fileCfg,o=s.getDateCol(),r=(z=s.titleKey())!=null?z:s.headers[0],a=new Set([r,...n,...o?[o]:[]]);s.headers.forEach(I=>{s.isNotesCol(I)&&a.add(I)});let l=Eg(s.headers,s.rows,a),c=[...o?[o]:[],...n.filter(I=>I!==o),di,...l],d=i.chartXCol&&c.includes(i.chartXCol)?i.chartXCol:c[0],h=l.includes(d),u=i.chartAgg==="sum"||i.chartAgg==="avg"?i.chartAgg:"count",f=n,g=i.chartYCol&&f.includes(i.chartYCol)?i.chartYCol:(N=f.find(I=>I!==d))!=null?N:f[0],p=i.chartFit==="linear"?"linear":"none",b=(W=i.chartFormula)!=null?W:"",m=t.createDiv({cls:"csv-chart-view"}),v=m.createDiv({cls:"csv-chart-controls"}),_=I=>{s.saveFileCfg({...s.fileCfg,...I}),s.renderViewPreservingScroll()},k=(I,q,Q,Z)=>{let nt=v.createDiv({cls:"csv-chart-control"});nt.createSpan({cls:"csv-chart-control-label",text:I});let X=nt.createEl("select",{cls:"csv-chart-select",attr:{"aria-label":I}});return q.forEach(tt=>{let at=X.createEl("option",{text:tt,value:tt});tt===Q&&(at.selected=!0)}),X.addEventListener("change",()=>Z(X.value)),X};k("X",c,d,I=>_({chartXCol:I})),(!h||u!=="count")&&k(h?`Y (${u})`:"Y",f,g,I=>_({chartYCol:I})),h&&k("Agg",["count","sum","avg"],u,I=>_({chartAgg:I}));let S=new Set([d,g,r]);s.headers.forEach(I=>{s.isNotesCol(I)&&S.add(I)});let x=wg(s.headers,s.rows,S),y="\u2014",C=i.chartHueCol&&x.includes(i.chartHueCol)?i.chartHueCol:null;x.length&&k("Color",[y,...x],C!=null?C:y,I=>_({chartHueCol:I===y?void 0:I}));let E=!h&&d!==di&&(d===o||s.isDateCol(d)),D=E&&(i.chartBucket==="week"||i.chartBucket==="month")?i.chartBucket:null,w=i.chartAgg==="avg"||i.chartAgg==="count"?i.chartAgg:"sum",M=E&&!D&&!!i.chartSmooth;E&&(k("By",["day","week","month"],D!=null?D:"day",I=>_({chartBucket:I==="day"?void 0:I})),D&&k("Agg",["sum","avg","count"],w,I=>_({chartAgg:I})));let L=n.filter(I=>I!==g&&I!==d),O=!h&&!D&&i.chartSizeCol&&L.includes(i.chartSizeCol)?i.chartSizeCol:null;if(!h&&!D&&L.length&&k("Size",[y,...L],O!=null?O:y,I=>_({chartSizeCol:I===y?void 0:I})),h){let I=Ho(e,d,u==="count"?null:g,C,u),q=m.createDiv({cls:"csv-chart-wrap"}),Q=q.createEl("canvas",{cls:"csv-chart-canvas"});if(!I.categories.length){q.remove(),m.createEl("p",{text:`No rows with a "${d}" value to chart.`,cls:"csv-empty-state"});return}I.skipped>0&&m.createDiv({cls:"csv-chart-footer"}).createSpan({cls:"csv-chart-skipped",text:`${I.skipped} row${I.skipped===1?"":"s"} skipped (no numeric value)`});let Z=u==="count"?"count":`${u}(${g})`,nt=zo(I,d,Z,Ls(t));s.chartInstance&&(s.chartInstance.destroy(),s.chartInstance=null);let{Chart:X}=await Qe();if(!Q.isConnected)return;s.chartInstance=new X(Q,nt),sc(s,v,Q);return}v.createEl("button",{cls:`csv-cfg-btn csv-chart-fit-btn ${p==="linear"?"active":""}`,text:"Best fit",title:"Toggle a least-squares fit line"}).addEventListener("click",()=>_({chartFit:p==="linear"?"none":"linear"})),E&&!D&&v.createEl("button",{cls:`csv-cfg-btn csv-chart-smooth-btn ${M?"active":""}`,text:"Smooth",title:"Toggle a 7-day rolling average (raw values stay as dots)"}).addEventListener("click",()=>_({chartSmooth:M?void 0:!0}));let P=v.createDiv({cls:"csv-chart-control csv-chart-formula-wrap"});P.createSpan({cls:"csv-chart-control-label",text:"y ="});let T=P.createEl("input",{cls:"csv-chart-formula-input",type:"text",value:b,placeholder:"overlay, e.g. 2x + 1",attr:{spellcheck:"false",autocomplete:"off",enterkeyhint:"done"}}),U=()=>{T.value.trim()!==b.trim()&&_({chartFormula:T.value})};T.addEventListener("change",U),T.addEventListener("keydown",I=>{I.key==="Enter"&&(I.preventDefault(),T.blur())});let F=$o(e,d,g,C,O,E,I=>s.parseDate(I),I=>s.getTitle(I)),G=F.skipped,H=D?F.series.map(I=>({label:I.label,points:Bo(I.points,D,w)})):F.series,A=m.createDiv({cls:"csv-chart-wrap"}),j=A.createEl("canvas",{cls:"csv-chart-canvas"}),Y=m.createDiv({cls:"csv-chart-footer"});if(!H.some(I=>I.points.length)){A.remove(),Y.remove(),m.createEl("p",{text:`No rows with both "${d}" and "${g}" values to plot.`,cls:"csv-empty-state"});return}let $={series:H,xIsDate:E,xLabel:d===di?"row":d,yLabel:D?w==="count"?`count / ${D}`:`${w}(${g}) / ${D}`:g,connect:E,fit:p,formula:b,sizeLabel:O!=null?O:"",smoothDays:M?7:0},R=ui($,Ls(t));R.fitText&&Y.createSpan({cls:"csv-chart-fit-text",text:R.fitText}),R.formulaError&&Y.createSpan({cls:"csv-chart-formula-error",text:`formula: ${R.formulaError}`}),G>0&&Y.createSpan({cls:"csv-chart-skipped",text:`${G} row${G===1?"":"s"} skipped (no numeric value)`}),s.chartInstance&&(s.chartInstance.destroy(),s.chartInstance=null);let{Chart:B}=await Qe();j.isConnected&&(s.chartInstance=new B(j,R.config),sc(s,v,j))}function gi(s){return s.resolveCol(["Type","type","Kind","kind","Item","item"])}function jo(s){var t;return(t=s.resolveCol(["Project","project","Projects","projects","Area","area"]))!=null?t:$t(s)}function rc(s){return s.resolveCol(["Due","due","Deadline","deadline","Due Date","Due date","due date"])}function pi(s){return s.resolveCol(["Priority","priority","Prio","prio","Importance","importance"])}var Mg=["task","todo","to-do","action",""],Tg=["task","todo","to-do","action","note","idea","reference","ref"],ac=["done","complete","completed","finished","closed","resolved","yes","x","\u2713","true","1"],Lg={high:0,med:1,medium:1,normal:1,low:2};function Fe(s){if(rc(s)||pi(s))return!0;let t=gi(s);return t?s.rows.some(e=>{var n;return Tg.includes(((n=e[t])!=null?n:"").trim().toLowerCase())}):!1}function Wo(s,t,e){var n;return e?ac.includes(((n=t[e])!=null?n:"").trim().toLowerCase()):!1}function ic(s){let t=Lg[(s!=null?s:"").trim().toLowerCase()];return t===void 0?3:t}function oc(s){return(s!=null?s:"").trim()?0:1}function Ag(){return me()}function Rg(s,t){let e=new Map;s.rows.forEach(o=>{var a,l;let r=((a=o[t])!=null?a:"").trim();r&&ac.includes(r.toLowerCase())&&e.set(r,((l=e.get(r))!=null?l:0)+1)});let n="done",i=0;return e.forEach((o,r)=>{o>i&&(n=r,i=o)}),n}function mi(s,t){var D,w;let e=jo(s),n=gi(s),i=s.getStatusCol(),o=rc(s),r=pi(s),a=(D=s.titleKey())!=null?D:s.headers[0],l=t.createDiv({cls:"csv-library-filters"}),c=new Set;e&&s.rows.forEach(M=>{var L;((L=M[e])!=null?L:"").split(",").map(O=>O.trim()).filter(Boolean).forEach(O=>c.add(O))});let d=l.createEl("select",{cls:"csv-library-filter-select"});d.createEl("option",{text:e?"All projects":"All",value:"all"}),Array.from(c).sort().forEach(M=>d.createEl("option",{text:M,value:M})),d.value=s.taskProjectFilter;let h=new Set;n&&s.rows.forEach(M=>{var O;let L=((O=M[n])!=null?O:"").trim();L&&h.add(L)});let u=null;h.size>0&&(u=l.createEl("select",{cls:"csv-library-filter-select"}),u.createEl("option",{text:"All types",value:"all"}),Array.from(h).sort().forEach(M=>u.createEl("option",{text:M,value:M})),u.value=s.taskTypeFilter);let f=()=>{s.taskProjectFilter=d.value,u&&(s.taskTypeFilter=u.value),s.renderView(!0)};d.addEventListener("change",f),u==null||u.addEventListener("change",f);let g=s.searchQuery.toLowerCase().trim(),p=s.rows.filter(M=>{var L,O;return!(s.taskProjectFilter!=="all"&&e&&!((L=M[e])!=null?L:"").split(",").map(P=>P.trim().toLowerCase()).includes(s.taskProjectFilter.toLowerCase())||s.taskTypeFilter!=="all"&&n&&((O=M[n])!=null?O:"").trim().toLowerCase()!==s.taskTypeFilter.toLowerCase()||g&&!s.headers.some(V=>{var P;return((P=M[V])!=null?P:"").toLowerCase().includes(g)}))});(s.taskProjectFilter!=="all"||s.taskTypeFilter!=="all"||g)&&t.createDiv({cls:"csv-library-result-count",text:`Showing ${p.length} of ${s.rows.length} entries`});let b={},m=M=>{var O;return e&&((O=M[e])!=null?O:"").split(",").map(V=>V.trim()).filter(Boolean)[0]||"\u2014"};p.forEach(M=>{var P,T,U;let L=n?((P=M[n])!=null?P:"").trim():"",O=Mg.includes(L.toLowerCase())?"Tasks":L,V=m(M);b[O]||(b[O]={}),((U=(T=b[O])[V])!=null?U:T[V]=[]).push(M)});let v=t.createDiv({cls:"csv-tasks"}),_=Ag(),k=i?Rg(s,i):"done",x=((w=s.fileCfg.cardFields)!=null?w:s.headers).filter(M=>M!==e&&M!==n&&M!==i),y=[];i&&y.push({name:"",cls:"csv-tasks-check-cell"}),x.forEach(M=>{let L="";M===a?L="csv-tasks-name-cell":M===o?L="csv-tasks-due":M===r?L="csv-tasks-priority":s.isNotesCol(M)?L="csv-tasks-generic-cell csv-tasks-notes-cell":L="csv-tasks-generic-cell",y.push({name:M,cls:L})});let C=(M,L)=>{L.sort((O,V)=>{var U,F,G,H,A,j;let P=Wo(s,O,i),T=Wo(s,V,i);if(P!==T)return P?1:-1;if(r){let Y=ic((U=O[r])!=null?U:"")-ic((F=V[r])!=null?F:"");if(Y)return Y}if(o){let Y=oc((G=O[o])!=null?G:"")-oc((H=V[o])!=null?H:"");if(Y)return Y;let $=((A=O[o])!=null?A:"").localeCompare((j=V[o])!=null?j:"");if($)return $}return s.getTitle(O).localeCompare(s.getTitle(V))}),L.forEach(O=>{let V=Wo(s,O,i),P=M.createEl("tr");if(i){let U=P.createEl("td",{cls:"csv-tasks-check-cell"}).createEl("span",{cls:`csv-tasks-check ${V?"is-done":""}`,text:V?"\u2713":""});U.setAttr("title",V?"Mark not done":"Mark done"),U.addEventListener("click",F=>{F.stopPropagation(),O[i]=V?"":k,s.scheduleSave(),s.renderView(!0)})}x.forEach(T=>{var U,F,G;if(T===a)Og(s,P,O,a,V);else if(T===o){let H=P.createEl("td",{cls:"csv-tasks-due csv-tasks-editable"}),A=o?((U=O[o])!=null?U:"").slice(0,10):"";H.setText(A||"\u2014"),A&&!V&&A<_&&H.addClass("csv-tasks-overdue"),Ns(s,H,O,T)}else if(T===r){let H=P.createEl("td",{cls:"csv-tasks-priority csv-tasks-editable",text:r&&O[r]||"\u2014"});H.addEventListener("click",A=>{var Y;A.stopPropagation();let j=Array.from(new Set([...s.getColumnValues(r),"high","medium","low"]));It(H,(Y=O[r])!=null?Y:"",j,$=>{O[r]=$,s.scheduleSave(),s.renderView(!0)},s.contentEl)})}else if(s.isNotesCol(T)){let H=((F=O[T])!=null?F:"").replace(/#{1,6}\s/g,"").replace(/[*_>`]/g,"").replace(/\n+/g," ").trim(),A=H?H.length>50?H.slice(0,48)+"\u2026":H:"\u2014",j=P.createEl("td",{text:A,cls:"csv-tasks-generic-cell csv-tasks-notes-cell csv-tasks-editable"});Ns(s,j,O,T)}else{let H=(G=O[T])!=null?G:"",A=H.length>40?H.slice(0,38)+"\u2026":H,j=P.createEl("td",{text:A||"\u2014",cls:"csv-tasks-generic-cell csv-tasks-editable"});Ns(s,j,O,T)}}),P.addEventListener("contextmenu",T=>s.openRowContextMenu(O,T))})},E=Object.keys(b).sort((M,L)=>M==="Tasks"?-1:L==="Tasks"?1:M.localeCompare(L));if(E.forEach(M=>{Pg(s,v,M==="Tasks"?M:Tt(M),b[M],C,y)}),E.length===0){let M=v.createDiv({cls:"csv-empty-state"});M.createEl("p",{text:g||s.taskProjectFilter!=="all"||s.taskTypeFilter!=="all"?"No entries match your filters.":"No tasks yet."}),(g||s.taskProjectFilter!=="all"||s.taskTypeFilter!=="all")&&M.createEl("button",{cls:"csv-clear-filters-btn",text:"Clear filters"}).addEventListener("click",()=>{s.taskProjectFilter="all",s.taskTypeFilter="all",s.searchQuery="",s.renderView()})}}function Pg(s,t,e,n,i,o){if(Object.keys(n).length===0)return;t.createDiv({cls:"csv-tasks-section-header",text:e});let r=t.createDiv({cls:"csv-tasks-section"});Object.keys(n).sort().forEach(a=>{let l=n[a],c=r.createEl("details",{cls:"csv-tasks-group"});c.open=!0;let d=c.createEl("summary",{cls:"csv-tasks-group-header"});d.innerHTML=`\u25B6 ${a} ${l.length}`;let u=c.createDiv({cls:"csv-tasks-table-wrapper"}).createEl("table",{cls:"csv-tasks-table"}),f=120;o.forEach(m=>{m.cls.includes("check-cell")?f+=30:m.cls.includes("priority")?f+=90:m.cls.includes("due")?f+=150:m.cls.includes("notes-cell")?f+=140:m.cls.includes("generic-cell")&&(f+=150)}),u.style.minWidth=`${f}px`;let p=u.createEl("thead").createEl("tr");o.forEach(m=>p.createEl("th",{text:m.name,cls:m.cls}));let b=u.createEl("tbody");i(b,l)})}function Og(s,t,e,n,i){var h;let o=t.createEl("td",{cls:"csv-tasks-name-cell"}),r=(h=s.isHighlighted)!=null&&h.call(s,e)?"csv-title-highlight":"",a=o.createSpan({cls:`csv-tasks-link ${i?"csv-tasks-done":""} ${r}`,text:e[n]||"Untitled"}),l=s.getNotesCol();a.addEventListener("click",()=>{l?s.openNoteExpander(e,l):s.openOrCreateNotes(e)});let c=s.notesFileExists(e),d=o.createEl("button",{cls:`csv-tasks-page-icon ${c?"exists":""}`,text:c?"\u{1F4C4}":"+"});d.setAttr("title",c?"Open page":"Create page"),d.addEventListener("click",u=>{u.stopPropagation(),s.openOrCreateNotes(e)})}function bi(s){let t=[];return s.isTravelFile()&&t.push({id:"travel",label:"Travel"}),s.hasDateColumn()&&t.push({id:"dashboard",label:"Dashboard"}),Fe(s)&&t.push({id:"tasks",label:"Tasks"}),$t(s)&&(t.push({id:"library",label:"Cards"}),t.push({id:"kanban-genre",label:"Kanban"})),t.push({id:"table",label:"Table"}),s.rows.length>0&&t.push({id:"focus",label:"Focus"}),Sn(s)&&t.push({id:"stats",label:"Stats"}),fi(s)&&t.push({id:"chart",label:"Chart"}),t}function lc(s,t){var u,f,g;let e=t.createDiv({cls:"csv-toolbar"});e.createDiv({cls:"csv-toolbar-title",text:(f=(u=s.file)==null?void 0:u.basename)!=null?f:""});let n=e.createDiv({cls:"csv-toolbar-controls"});n.createDiv({cls:"csv-row-count",text:`${s.rows.length} entries`});let i=n.createDiv({cls:"csv-mode-group"}),o=bi(s),r=i.createEl("select",{cls:"csv-mode-select",attr:{"aria-label":"View mode"}});if(o.forEach(({id:p,label:b})=>{let m=r.createEl("option",{text:b,value:p});s.mode===p&&(m.selected=!0)}),r.addEventListener("change",()=>{s.mode=r.value,s.renderView()}),s.mode!=="dashboard"){let p=n.createEl("button",{cls:"csv-cfg-btn csv-search-toggle",text:"\u{1F50D}",title:"Search"}),b=n.createDiv({cls:"csv-search-wrap"}),m=b.createDiv({cls:"csv-search-input-wrap"}),v=m.createEl("input",{cls:"csv-search-input",type:"text",placeholder:"Search...",value:s.searchQuery,attr:{inputmode:"search",enterkeyhint:"search",autocomplete:"off"}}),_=m.createEl("button",{cls:"csv-search-clear",text:"\xD7",title:"Clear search"});_.toggleClass("is-hidden",!s.searchQuery),b.createEl("button",{cls:"csv-search-done",text:"Done",title:"Dismiss keyboard"}).addEventListener("click",x=>{if(x.preventDefault(),!v.value){e.removeClass("csv-toolbar--search-expanded"),p.removeClass("has-query"),s.searchQuery="",s.renderView(!0);return}v.blur()});let S=null;v.addEventListener("input",x=>{s.searchQuery=x.target.value,_.toggleClass("is-hidden",!s.searchQuery),p.toggleClass("has-query",!!s.searchQuery),S!==null&&window.clearTimeout(S),S=window.setTimeout(()=>{S=null,s.renderView(!0)},120)}),v.addEventListener("keydown",x=>{x.key==="Enter"&&(x.preventDefault(),v.blur())}),_.addEventListener("click",()=>{s.searchQuery="",v.value="",_.addClass("is-hidden"),p.removeClass("has-query"),v.focus({preventScroll:!0}),s.renderView(!0)}),s.searchQuery&&p.addClass("has-query"),p.addEventListener("click",()=>{e.addClass("csv-toolbar--search-expanded"),v.focus({preventScroll:!0})})}if(s.mode==="table"&&s.hasDateColumn()){let p=(g=s.fileCfg.sortNewestFirst)!=null?g:!0;n.createEl("button",{cls:`csv-cfg-btn ${p?"active":""}`,text:p?"\u2193 Newest":"\u2191 Oldest",title:"Toggle sort order"}).addEventListener("click",()=>{var v;let m=s.fileCfg;m.sortNewestFirst=!((v=m.sortNewestFirst)==null||v),s.saveFileCfg(m),s.tableSortCol=null,s.renderViewPreservingScroll()})}let a=()=>{var b,m;let p={title:s.resolveCol(ge),category:s.resolveCol(ss),status:s.resolveCol(ns),notes:s.resolveCol(pe),image:s.resolveCol(es),anki:Ai(s)};new bn(s.app,s.headers,(m=(b=s.file)==null?void 0:b.path)!=null?m:"",s.fileCfg,s.autoDetectBooleanColumns(),s.autoDetectCategoricalColumns(),p,bi(s),v=>{s.saveFileCfg(v),v.defaultMode&&(s.mode=v.defaultMode),s.renderView()},()=>s.headers,()=>s.fileCfg,v=>s.addColumn(v),v=>s.removeColumn(v),v=>s.cleanupBooleanColumn(v)).open()},l=()=>s.backupToArchive(),c=()=>_r(s);n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-secondary",text:"\u2699 Config",title:"Configure this file's columns and views"}).addEventListener("click",a),n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-secondary",text:"\u{1F4BE} Backup",title:"Copy this file to Archive/ with today's date"}).addEventListener("click",l),n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-secondary",text:"\u{1F3B4} Anki",title:"Sync rows to Anki (needs Anki desktop + AnkiConnect)"}).addEventListener("click",c),n.createEl("button",{cls:"csv-add-btn",text:"+ Add"}).addEventListener("click",()=>s.openAddModal()),n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-overflow",text:"\u22EF",title:"More actions"}).addEventListener("click",p=>{let b=new vi.Menu;b.addItem(m=>m.setTitle("Config").setIcon("settings").onClick(a)),b.addItem(m=>m.setTitle("Backup").setIcon("save").onClick(l)),b.addItem(m=>m.setTitle("Sync to Anki").setIcon("layers").onClick(c)),b.addSeparator(),b.addItem(m=>m.setTitle("Built 2026-07-16 20:56").setIcon("info").setDisabled(!0)),b.showAtMouseEvent(p)}),n.createEl("button",{cls:"csv-cfg-btn csv-cfg-btn-secondary csv-info-btn",text:"\u24D8",title:"Built 2026-07-16 20:56 \u2014 click to confirm"}).addEventListener("click",()=>new vi.Notice("datadeck \u2014 built 2026-07-16 20:56",4e3))}function Fg(s){return s&&typeof s=="object"&&"basename"in s?s:null}var Ig=["Author","author","By","by","Source","source","Speaker","speaker","Artist","artist","Director","director"];async function cc(s,t,e,n){var v,_,k;let i=t.split(` `).map(S=>S.trim()).filter(Boolean),o=S=>{var x,y;return(y=(x=i.find(C=>C.startsWith(S+":")))==null?void 0:x.slice(S.length+1).trim())!=null?y:""},r=o("file");if(!r){e.createEl("p",{text:"Error: No file specified. Use: file: yourfile.csv",cls:"csv-add-error"});return}let a=s.vault.getAbstractFileByPath(n.sourcePath),l=(_=(v=a==null?void 0:a.parent)==null?void 0:v.path)!=null?_:"",c=Qt(r,l),d=Fg(s.vault.getAbstractFileByPath(c));if(!d){e.createEl("p",{text:`Error: File not found: ${c}`,cls:"csv-add-error"});return}let h=[],u=[];try{let S=wt(await s.vault.read(d));h=S.headers,u=S.rows}catch(S){e.createEl("p",{text:`Error reading file: ${S}`,cls:"csv-add-error"});return}if(!u.length){e.createEl("p",{text:"No entries in file.",cls:"csv-add-error"});return}let f=o("field"),g=(k=h.find(S=>S.toLowerCase()===f.toLowerCase()))!=null?k:h[0],p=Ig.map(S=>h.find(x=>x===S)).find(Boolean),b=e.createDiv({cls:"csv-random-card"}),m=()=>{var w;b.empty();let S=u.filter(M=>{var L;return((L=M[g])!=null?L:"").trim()}),x=S.length?S:u,y=x[Math.floor(Math.random()*x.length)];b.createDiv({cls:"csv-random-text",text:y[g]||"\u2014"});let C=p?((w=y[p])!=null?w:"").trim():"";C&&b.createDiv({cls:"csv-random-sub",text:`\u2014 ${C}`});let E=b.createDiv({cls:"csv-random-foot"});E.createSpan({cls:"csv-random-src",text:d.basename}),E.createEl("button",{cls:"csv-random-btn",text:"\u21BB",title:"Another one"}).addEventListener("click",m)};m()}async function dc(s,t){var A,j,Y;let e=s.getDateCol();if(!e){t.createEl("p",{text:"No date column detected.",cls:"csv-empty-state"});return}let n=s.getBooleanColumns(),i=s.getNotesCol(),o=s.formatDate(new Date),r=[...s.rows].sort(($,R)=>{var B,z;return((B=$[e])!=null?B:"").localeCompare((z=R[e])!=null?z:"")});s.selectedDate||(s.selectedDate=o);let a=r.find($=>$[e]===s.selectedDate),l=s.selectedDate===o;t.addClass("csv-dashboard");let c=[...new Set([...r.map($=>$[e]),o])].filter(Boolean).sort(),d=t.createDiv({cls:"csv-dash-nav"});d.createEl("button",{cls:"csv-dash-nav-btn csv-dash-back-btn",text:"\u25C0"}).addEventListener("click",()=>{let $=c.indexOf(s.selectedDate);if($>0)s.selectedDate=c[$-1],s.renderView();else if($===-1&&c.length>0){let R=c.filter(B=>B0&&(s.selectedDate=R[R.length-1],s.renderView())}});let u=d.createDiv({cls:"csv-dash-date"});l&&u.createSpan({cls:"csv-dash-today-dot"});let f=u.createEl("select",{cls:"csv-dash-date-select"});if(c.forEach($=>{let R=f.createEl("option",{text:$,value:$});$===s.selectedDate&&(R.selected=!0)}),f.addEventListener("change",()=>{s.selectedDate=f.value,s.renderView()}),d.createEl("button",{cls:"csv-dash-nav-btn",text:"\u25B6"}).addEventListener("click",()=>{let $=c.indexOf(s.selectedDate);if($>=0&&$B>s.selectedDate);R.length>0&&(s.selectedDate=R[0],s.renderView())}}),l||d.createEl("button",{cls:"csv-dash-today-btn",text:"Today"}).addEventListener("click",()=>{s.selectedDate=o,s.renderView()}),!a){let $=t.createDiv({cls:"csv-dash-add-section"});$.createEl("p",{text:`No entry for ${s.selectedDate}`}),$.createEl("button",{cls:"csv-dash-add-btn",text:`+ Add entry for ${s.selectedDate}`}).addEventListener("click",()=>{let B={};s.headers.forEach(z=>B[z]=""),B[e]=s.selectedDate,s.rows.push(B),s.scheduleSave(),s.renderView()})}if(a){let $=t.createDiv({cls:"csv-dash-habits"});$.createEl("h3",{text:s.selectedDate===o?"Today":s.selectedDate,cls:"csv-dash-section-title"});let R=$.createDiv({cls:"csv-dash-habits-grid"});n.forEach(z=>{let N=s.isTruthy(a[z]),W=R.createDiv({cls:`csv-dash-habit ${N?"checked":""}`}),I=W.createEl("button",{cls:"csv-dash-habit-check",text:N?"\u25CF":"\u25CB"});W.createSpan({cls:"csv-dash-habit-label",text:z}),I.addEventListener("click",()=>{a[z]=N?"0":"1",s.scheduleSave(),s.renderViewPreservingScroll()})});let B=n.filter(z=>s.isTruthy(a[z])).length;if($.createDiv({cls:"csv-dash-habits-count",text:`${B} of ${n.length} complete`}),i&&((A=a[i])!=null&&A.trim())){let z=$.createDiv({cls:"csv-dash-notes-preview"});z.createEl("strong",{text:"Notes: "}),z.createSpan({text:a[i].slice(0,200)+(a[i].length>200?"\u2026":"")})}}let p=t.createDiv({cls:"csv-dash-chart-section"});p.createEl("h3",{text:"Progress",cls:"csv-dash-section-title"});let m=p.createDiv({cls:"csv-dash-chart-wrap"}).createEl("canvas",{cls:"csv-dash-chart"}),v=r.map($=>{var B;return((B=$[e])!=null?B:"").slice(5)}),_=r.map($=>n.filter(R=>s.isTruthy($[R])).length);s.chartInstance&&(s.chartInstance.destroy(),s.chartInstance=null);let{Chart:k}=await Qe();if(!m.isConnected)return;s.chartInstance=new k(m,{type:"line",data:{labels:v,datasets:[{label:"Habits done",data:_,borderColor:"#378ADD",backgroundColor:"rgba(55,138,221,0.08)",borderWidth:1.5,pointRadius:3,tension:.3,fill:!0}]},options:{responsive:!0,maintainAspectRatio:!1,scales:{y:{min:0,max:n.length||8,ticks:{stepSize:1}}},plugins:{tooltip:{enabled:!0}}}});let S=t.createDiv({cls:"csv-dash-stats-section"});S.createEl("h3",{text:"Stats",cls:"csv-dash-section-title"});let x=r.length,y=r.reduce(($,R)=>$+n.filter(B=>s.isTruthy(R[B])).length,0),C=x>0?(y/x).toFixed(1):"0",E=r.filter($=>n.every(R=>s.isTruthy($[R]))).length,D=0,w=0,M=null;for(let $ of r){let R=n.filter(N=>s.isTruthy($[N])).length,B=s.parseDate((j=$[e])!=null?j:""),z=!0;M&&B&&Math.round((B.getTime()-M.getTime())/864e5)!==1&&(z=!1),R>=1&&(z||M===null)?(w++,w>D&&(D=w)):R>=1?(w=1,w>D&&(D=w)):w=0,M=B}let L=0,O=new Date;O.setHours(0,0,0,0);let V=O;for(let $=r.length-1;$>=0;$--){let R=s.parseDate((Y=r[$][e])!=null?Y:"");if(!R)break;let B=Math.round((V.getTime()-R.getTime())/(1e3*60*60*24));if(L===0&&B>1||L>0&&B!==1)break;if(n.filter(N=>s.isTruthy(r[$][N])).length>=1)L++,V=R;else break}let P=S.createDiv({cls:"csv-dash-stats-bar"});P.innerHTML=`${x} days logged \xB7 ${C} avg/day \xB7 ${E} perfect days \xB7 current streak ${L}d \xB7 best streak ${D}d`;let U=t.createDiv({cls:"csv-dash-cards-section"}).createDiv({cls:"csv-dash-cards-grid"}),F=new Date().getFullYear(),G={language:"\u25CB",read:"\u2261",gym:"\u229E",vitamins:"\u2299",cardio:"\u2191",meditate:"\u25CE",challenge:"\u273F",journal:"\u270E",exercise:"\u229E",water:"\u{1F4A7}",sleep:"\u{1F319}",study:"\u{1F4DA}"};n.map($=>{let R=r.filter(I=>s.isTruthy(I[$])),B=R.length>0?R[R.length-1][e]:null,z=new Set;R.forEach(I=>{var Q;let q=s.parseDate((Q=I[e])!=null?Q:"");q&&z.add(q.getFullYear())});let N=r.filter(I=>{var Q;let q=s.parseDate((Q=I[e])!=null?Q:"");return q&&q.getFullYear()===F}),W=N.filter(I=>s.isTruthy(I[$])).length;return{habit:$,doneCount:R.length,doneThisYear:W,totalThisYear:N.length,lastDone:B,years:Array.from(z).sort()}}).sort(($,R)=>!$.lastDone&&!R.lastDone?0:$.lastDone?R.lastDone?R.lastDone.localeCompare($.lastDone):-1:1).forEach(({habit:$,doneCount:R,doneThisYear:B,totalThisYear:z,lastDone:N,years:W})=>{var tt;let I=U.createDiv({cls:"csv-dash-habit-card"}),q=(tt=G[$.toLowerCase()])!=null?tt:"\u25CB",Q=I.createDiv({cls:"csv-dash-habit-card-header"});if(Q.createSpan({cls:"csv-dash-habit-icon",text:q}),Q.createSpan({cls:"csv-dash-habit-card-name",text:Tt($)}),W.length>0&&I.createDiv({cls:"csv-dash-habit-years"}).setText(W.join(" \xB7 ")),I.createDiv({cls:"csv-dash-habit-card-thisyear",text:`${B} of ${z} complete this year`}),I.createDiv({cls:"csv-dash-habit-card-alltime",text:`${R} of ${x} all time`}),N){let at=s.parseDate(N),Wt=at?at.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):N;I.createDiv({cls:"csv-dash-habit-card-last",text:`Last logged: ${Wt}`})}else I.createDiv({cls:"csv-dash-habit-card-last",text:"Never logged"});let Z=x>0?R/x*100:0,X=I.createDiv({cls:"csv-dash-habit-progress"}).createDiv({cls:"csv-dash-habit-progress-bar"});X.style.width=`${Z}%`,I.addEventListener("click",()=>{s.selectedHabit=s.selectedHabit===$?null:$,s.renderViewPreservingScroll()}),s.selectedHabit===$&&I.addClass("selected")}),s.selectedHabit&&n.includes(s.selectedHabit)&&Vg(s,t,r,e,s.selectedHabit)}function Vg(s,t,e,n,i){var D,w,M;let o=t.createDiv({cls:"csv-dash-timeline-section"}),r=o.createDiv({cls:"csv-dash-timeline-header"});r.createEl("h3",{text:`${Tt(i)} Timeline`,cls:"csv-dash-section-title"});let a=r.createEl("select",{cls:"csv-dash-year-select"}),l=new Set;e.forEach(L=>{var V;let O=s.parseDate((V=L[n])!=null?V:"");O&&l.add(O.getFullYear())}),l.add(new Date().getFullYear()),Array.from(l).sort().reverse().forEach(L=>{let O=a.createEl("option",{text:String(L),value:String(L)});L===s.timelineYear&&(O.selected=!0)}),a.addEventListener("change",()=>{s.timelineYear=parseInt(a.value),s.renderViewPreservingScroll()}),r.createEl("button",{cls:"csv-dash-timeline-close",text:"\u2715"}).addEventListener("click",()=>{s.selectedHabit=null,s.renderViewPreservingScroll()});let d=new Map;e.forEach(L=>{var O;d.set((O=L[n])!=null?O:"",s.isTruthy(L[i]))});let h=o.createDiv({cls:"csv-dash-timeline-grid-wrap"}),u=h.createDiv({cls:"csv-dash-timeline-months"});["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"].forEach(L=>u.createSpan({cls:"csv-dash-timeline-month-label",text:L}));let g=h.createDiv({cls:"csv-dash-timeline-calendar"}),p=g.createDiv({cls:"csv-dash-timeline-day-labels"});for(let L=1;L<=31;L++)p.createDiv({cls:"csv-dash-timeline-day-label",text:L%5===0||L===1?String(L):""});for(let L=0;L<12;L++){let O=g.createDiv({cls:"csv-dash-timeline-month-col"}),V=new Date(s.timelineYear,L+1,0).getDate();for(let P=1;P<=31;P++){if(P>V){O.createDiv({cls:"csv-dash-timeline-cell empty"});continue}let T=`${s.timelineYear}-${String(L+1).padStart(2,"0")}-${String(P).padStart(2,"0")}`,U=(D=d.get(T))!=null?D:!1,F=d.has(T),G=new Date(s.timelineYear,L,P)>new Date,H=O.createDiv({cls:`csv-dash-timeline-cell ${G?"future":""} ${U?"done":""} ${F&&!U?"missed":""} ${!F&&!G?"no-entry":""}`});H.title=`${T}: ${G?"Future":U?"\u2713 Done":F?"\u2717 Missed":"No entry"}`}}let b=e.filter(L=>{var V;let O=s.parseDate((V=L[n])!=null?V:"");return O&&O.getFullYear()===s.timelineYear}),m=b.filter(L=>s.isTruthy(L[i])).length,v=b.length,_=0,k=0,S=0,x=null;for(let L of e){let O=s.isTruthy(L[i]),V=s.parseDate((w=L[n])!=null?w:""),P=!0;x&&V&&Math.round((V.getTime()-x.getTime())/864e5)!==1&&(P=!1),O&&(P||x===null)?(S++,S>k&&(k=S)):O?S=1:S=0,x=V}let y=new Date;y.setHours(0,0,0,0);let C=y;for(let L=e.length-1;L>=0;L--){let O=s.parseDate((M=e[L][n])!=null?M:"");if(!O)break;let V=Math.round((C.getTime()-O.getTime())/(1e3*60*60*24));if(_===0&&V>1||_>0&&V!==1)break;if(s.isTruthy(e[L][i]))_++,C=O;else break}let E=o.createDiv({cls:"csv-dash-timeline-stats"});E.innerHTML=`${m} of ${v} in ${s.timelineYear} \xB7 current streak ${_}d \xB7 best streak ${k}d`}function hc(s,t){var v,_,k;let e=s.getFilteredRows();if(s.searchQuery.trim()&&t.createDiv({cls:"csv-search-results",text:`Found ${e.length} of ${s.rows.length} entries`}),!e.length){let S=t.createDiv({cls:"csv-empty-state"});S.createEl("p",{text:s.searchQuery?"No matching entries found.":"No entries yet."}),s.searchQuery&&S.createEl("button",{cls:"csv-clear-filters-btn",text:"Clear search"}).addEventListener("click",()=>{s.searchQuery="",s.renderView()});return}s.focusIndex>=e.length&&(s.focusIndex=e.length-1),s.focusIndex<0&&(s.focusIndex=0);let n=e[s.focusIndex],i=(v=s.titleKey())!=null?v:s.headers[0],o=s.getNotesCol(),r=s.authorKey(),a=t.createDiv({cls:"csv-focus-wrap",attr:{tabindex:"0"}}),l=S=>{s.focusIndex=(S%e.length+e.length)%e.length,s.focusNavPending=!0,s.renderView(!0)},c=a.createDiv({cls:"csv-focus-card"});c.createDiv({cls:"csv-focus-position",text:`${s.focusIndex+1} / ${e.length}`});let d=c.createDiv({cls:`csv-focus-title ${(_=s.isHighlighted)!=null&&_.call(s,n)?"csv-title-highlight":""}`,text:s.getTitle(n)});o&&(d.addClass("is-clickable"),d.title="Open entry",d.addEventListener("click",()=>s.openNoteExpander(n,o)));let h=s.getSubtitle(n);if(h&&c.createDiv({cls:"csv-focus-sub",text:h}),o&&o!==i&&((k=n[o])!=null&&k.trim())){let S=c.createDiv({cls:"csv-focus-notes"});s.renderMarkdownInto(S,n[o])}let u=new Set([i,o,r].filter(Boolean)),f=s.headers.filter(S=>{var x;return!u.has(S)&&((x=n[S])!=null?x:"").trim()});if(f.length){let S=c.createDiv({cls:"csv-focus-meta"});f.forEach(x=>{let y=S.createDiv({cls:"csv-kanban-chip"});if(y.createSpan({cls:"csv-chip-label",text:x+": "}),s.isSelectCol(x)){let C=y.createSpan({cls:"csv-chip-value csv-chip-select",text:n[x]});C.addEventListener("click",E=>{E.stopPropagation(),It(C,n[x],s.getColumnValues(x),D=>{n[x]=D,C.setText(D||"\u2014"),s.scheduleSave()},s.contentEl,{multi:xt(x)})})}else y.createSpan({cls:"csv-chip-value",text:n[x]})})}c.addEventListener("contextmenu",S=>s.openRowContextMenu(n,S));let g=a.createDiv({cls:"csv-focus-nav"}),p=g.createEl("button",{cls:"csv-focus-nav-btn",text:"\u2039",title:"Previous (\u2190)"}),b=g.createEl("button",{cls:"csv-focus-nav-btn csv-focus-nav-rand",text:"\u{1F500}",title:"Random entry"}),m=g.createEl("button",{cls:"csv-focus-nav-btn",text:"\u203A",title:"Next (\u2192)"});p.addEventListener("click",()=>l(s.focusIndex-1)),m.addEventListener("click",()=>l(s.focusIndex+1)),b.addEventListener("click",()=>{if(e.length<2)return;let S=s.focusIndex;for(;S===s.focusIndex;)S=Math.floor(Math.random()*e.length);l(S)}),a.addEventListener("keydown",S=>{S.key==="ArrowLeft"?(S.preventDefault(),l(s.focusIndex-1)):S.key==="ArrowRight"&&(S.preventDefault(),l(s.focusIndex+1))}),(s.focusNavPending||document.activeElement===document.body)&&(s.focusNavPending=!1,a.focus({preventScroll:!0}))}var Ft=require("obsidian"),fc=Os(ts());var Ng=[{id:"table",label:"Table"},{id:"library",label:"Cards"},{id:"kanban-genre",label:"Kanban"}];function uc(s){return s&&typeof s=="object"&&"basename"in s?s:null}function Bg(s){let t=s.split(` `).map(r=>r.trim()).filter(Boolean),e=r=>{var a,l;return(l=(a=t.find(c=>c.toLowerCase().startsWith(r+":")))==null?void 0:a.slice(r.length+1).trim())!=null?l:""},n=e("mode").toLowerCase(),i=n==="kanban"||n==="kanban-genre"?"kanban-genre":n==="cards"||n==="card"||n==="library"?"library":"table",o=parseInt(e("height"),10);return{file:e("file"),mode:i,height:Number.isFinite(o)&&o>0?o:null,collapse:e("collapse").split(",").map(r=>r.trim()).filter(Boolean)}}var Uo=class extends Ft.MarkdownRenderChild{constructor(e,n,i,o,r){super(e);this.file=null;this.headers=[];this.rows=[];this.searchQuery="";this.tableSortCol=null;this.tableSortDir="asc";this.libraryStatusFilter="all";this.libraryGenreFilter="all";this.collapsedGroups=new Set;this.saveTimer=null;this.lastWritten=null;this.contentArea=null;this.app=n,this.settings=i,this.persistSettings=o,this.opts=r,this.mode=r.mode,this.collapsedGroups=new Set(r.collapse.map(a=>a.toLowerCase()))}get renderComponent(){return this}get contentEl(){return this.containerEl}get asView(){return this}async onload(){if(this.containerEl.addClass("csv-inline-view"),!this.opts.file){this.renderError("No file specified. Use: file: yourfile.csv");return}await this.reload()&&(this.renderView(),this.registerEvent(this.app.vault.on("modify",async e=>{if(!this.file||e.path!==this.file.path)return;let n=await this.app.vault.read(this.file);if(n===this.lastWritten)return;this.lastWritten=n;let i=wt(n);this.headers=i.headers,this.rows=i.rows,this.renderView()})),this.registerEvent(this.app.vault.on("rename",(e,n)=>{this.file&&n===this.file.path&&(this.file=uc(e))})))}onunload(){this.saveTimer&&window.clearTimeout(this.saveTimer)}async reload(){let e=uc(this.app.vault.getAbstractFileByPath(this.opts.file));if(!e)return this.renderError(`File not found: ${this.opts.file}`),!1;this.file=e;try{let n=await this.app.vault.read(e),i=wt(n);this.headers=i.headers,this.rows=i.rows,this.lastWritten=n}catch(n){return this.renderError(`Error reading file: ${n instanceof Error?n.message:String(n)}`),!1}return!0}renderError(e){this.containerEl.empty(),this.containerEl.createEl("p",{text:`csv-view: ${e}`,cls:"csv-add-error"})}scheduleSave(){this.saveTimer&&window.clearTimeout(this.saveTimer),this.saveTimer=window.setTimeout(()=>void this.doSave(),600)}async doSave(){if(this.file)try{let e=fc.default.unparse(this.rows,{columns:this.headers});try{let n=await this.app.vault.read(this.file);this.lastWritten!==null&&n!==this.lastWritten&&n!==e&&await rs(this.app,this.file,n)}catch(n){}this.lastWritten=e,await this.app.vault.modify(this.file,e)}catch(e){new Ft.Notice(`Couldn't save ${this.file.name}: ${e instanceof Error?e.message:String(e)}`,8e3)}}get fileCfg(){var e;return this.file?(e=this.settings.fileConfigs[this.file.path])!=null?e:{}:{}}saveFileCfg(e){this.file&&(this.settings.fileConfigs[this.file.path]=e,this.persistSettings())}isHighlighted(e){var n;return((n=this.fileCfg.highlightedTitles)!=null?n:[]).includes(this.getTitle(e))}toggleHighlight(e){let n=this.getTitle(e),i=this.fileCfg,o=i.highlightedTitles?[...i.highlightedTitles]:[],r=o.indexOf(n);r>=0?o.splice(r,1):o.push(n),i.highlightedTitles=o,this.saveFileCfg(i)}resolveCol(e){for(let n of e){let i=this.headers.find(o=>o.toLowerCase()===n.toLowerCase());if(i)return i}return null}getNotesCol(){return this.fileCfg.notesColumn!==void 0?this.fileCfg.notesColumn===""?null:this.fileCfg.notesColumn:this.resolveCol(pe)}isNotesCol(e){let n=this.getNotesCol();return n?e===n:this.settings.notesColumns.some(i=>i.toLowerCase()===e.toLowerCase())}isSelectCol(e){return this.settings.selectColumns.some(n=>n.toLowerCase()===e.toLowerCase())}isCategoricalCol(e){var i;let n=(i=this.titleKey())!=null?i:this.headers[0];return e===n||this.getDateCol()===e||xt(e)?!1:this.fileCfg.categoricalColumns?this.fileCfg.categoricalColumns.includes(e):this.isSelectCol(e)||Xt(this.getColumnValues(e).length)}getStatusCol(){var e;return this.fileCfg.statusColumn!==void 0?this.fileCfg.statusColumn===""?null:(e=this.headers.find(n=>n.toLowerCase()===this.fileCfg.statusColumn.toLowerCase()))!=null?e:null:this.resolveCol(ns)}getCategoryCol(){var e;return this.fileCfg.categoryColumn!==void 0?this.fileCfg.categoryColumn===""?null:(e=this.headers.find(n=>n.toLowerCase()===this.fileCfg.categoryColumn.toLowerCase()))!=null?e:null:this.resolveCol(ss)}titleKey(){var e,n;return this.fileCfg.titleColumn!==void 0?this.fileCfg.titleColumn===""?void 0:(e=this.headers.find(i=>i.toLowerCase()===this.fileCfg.titleColumn.toLowerCase()))!=null?e:void 0:(n=this.resolveCol(ge))!=null?n:void 0}authorKey(){var e;return(e=this.resolveCol(["Author","author","Authors","authors","Director","director","Artist","artist","Creator","creator","By","by"]))!=null?e:void 0}getTitle(e){var i;let n=this.titleKey();return(i=n?e[n]:e[this.headers[0]])!=null?i:"\u2014"}getSubtitle(e){var i;let n=this.authorKey();return n&&(i=e[n])!=null?i:""}getColumnValues(e){return Array.from(new Set(this.rows.map(n=>{var i;return(i=n[e])!=null?i:""}).filter(Boolean))).sort()}getImageCol(){var e;return this.fileCfg.imageColumn!==void 0?this.fileCfg.imageColumn===""?null:(e=this.headers.find(n=>n.toLowerCase()===this.fileCfg.imageColumn.toLowerCase()))!=null?e:null:this.resolveCol(es)}getBooleanColumns(){return this.fileCfg.habitColumns?this.fileCfg.habitColumns.filter(e=>this.headers.includes(e)):this.headers.filter(e=>{if(e===this.getDateCol()||this.isNotesCol(e))return!1;let n=this.rows.map(i=>{var o;return((o=i[e])!=null?o:"").toLowerCase().trim()});return is(n)})}getDateCol(){var o,r;if(this.fileCfg.dateColumns&&this.fileCfg.dateColumns.length>0){let a=this.fileCfg.dateColumns[0];return(o=this.headers.find(l=>l===a))!=null?o:null}if(this.headers.length===0)return null;let e=this.headers[0];if(["date","day","datum"].includes(e.toLowerCase()))return e;let n=/^\d{4}-\d{2}-\d{2}$/,i=this.rows.slice(0,5);return i.length>0&&i.every(a=>{var l;return n.test((l=a[e])!=null?l:"")})?e:(r=this.headers.find(a=>this.isDateCol(a)))!=null?r:null}isDateCol(e){var n;return(n=this.fileCfg.dateColumns)!=null&&n.includes(e)?!0:Et(e)}getFilteredRows(){var i;let e=this.rows;if(this.searchQuery.trim()){let o=this.searchQuery.toLowerCase().trim();e=e.filter(r=>this.headers.some(a=>{var l;return((l=r[a])!=null?l:"").toLowerCase().includes(o)}))}if(this.mode==="table"&&this.tableSortCol&&this.headers.includes(this.tableSortCol)){let o=this.tableSortCol,r=this.tableSortDir;return[...e].sort((a,l)=>{var d,h;let c=((d=a[o])!=null?d:"").localeCompare((h=l[o])!=null?h:"",void 0,{numeric:!0});return r==="asc"?c:-c})}let n=this.getDateCol();if(this.mode==="table"&&n){let o=(i=this.fileCfg.sortNewestFirst)!=null?i:!0;e=[...e].sort((r,a)=>{var c,d;let l=((c=r[n])!=null?c:"").localeCompare((d=a[n])!=null?d:"");return o?-l:l})}return e}notesFilePath(e){var a,l,c;let n=Ie(this.getTitle(e)),i=(c=(l=(a=this.file)==null?void 0:a.parent)==null?void 0:l.path)!=null?c:"",o=this.settings.notesSubfolder.trim(),r=o?i?`${i}/${o}`:o:i;return(0,Ft.normalizePath)(`${r}/${n}.md`)}notesFileExists(e){return!!this.app.vault.getAbstractFileByPath(this.notesFilePath(e))}async openOrCreateNotes(e){var o;let n=this.notesFilePath(e),i=this.app.vault.getAbstractFileByPath(n);if(!i){let a=["---",...this.headers.filter(h=>!this.isNotesCol(h)&&e[h]).map(h=>`${h}: "${e[h].replace(/"/g,'\\"')}"`),"---","",`# ${this.getTitle(e)}`,"",""].join(` `),l=this.headers.find(h=>this.isNotesCol(h)),c=a+(l&&((o=e[l])!=null&&o.trim())?e[l]:""),d=n.substring(0,n.lastIndexOf("/"));d&&!this.app.vault.getAbstractFileByPath(d)&&await this.app.vault.createFolder(d),i=await this.app.vault.create(n,c),new Ft.Notice(`Created: ${i.name}`)}await this.app.workspace.getLeaf("tab").openFile(i)}deleteWithUndo(e){let n=this.rows.indexOf(e);if(n<0)return;this.rows.splice(n,1),this.scheduleSave(),this.renderView();let i=this.getTitle(e)||"entry",o=document.createDocumentFragment();o.createSpan({text:`Deleted \u201C${i}\u201D. `});let r=o.createEl("button",{text:"Undo",cls:"csv-notice-undo"}),a=new Ft.Notice(o,6e3);r.addEventListener("click",()=>{r.hasAttribute("disabled")||(r.setAttribute("disabled","true"),this.rows.splice(Math.min(n,this.rows.length),0,e),this.scheduleSave(),this.renderView(),a.hide(),new Ft.Notice(`Restored \u201C${i}\u201D`,2500))})}openRowContextMenu(e,n){let i=new Ft.Menu;i.addItem(a=>a.setTitle("Open / Create Notes file").setIcon("file-text").onClick(()=>void this.openOrCreateNotes(e))),i.addItem(a=>a.setTitle("Open entry").setIcon("maximize").onClick(()=>{var l;return this.openNoteExpander(e,(l=this.getNotesCol())!=null?l:"")}));let o=this.getStatusCol();if(o){let a=this.getColumnValues(o);a.length&&(i.addSeparator(),a.forEach(l=>{l!==e[o]&&i.addItem(c=>c.setTitle(`Mark as: ${l}`).onClick(()=>{e[o]=l,this.scheduleSave(),this.renderView()}))}))}i.addSeparator();let r=this.isHighlighted(e);i.addItem(a=>a.setTitle(r?"Remove highlight":"Highlight").setIcon("highlighter").onClick(()=>{this.toggleHighlight(e),this.renderView()})),i.addSeparator(),i.addItem(a=>a.setTitle("Delete").setIcon("trash").onClick(()=>this.deleteWithUndo(e))),i.showAtMouseEvent(n)}openNoteExpander(e,n){var i,o;new be(this.app,e,n,this.headers,(o=(i=this.file)==null?void 0:i.path)!=null?o:"",this.isNotesCol.bind(this),this.isSelectCol.bind(this),this.getColumnValues.bind(this),r=>{Object.assign(e,r),this.scheduleSave(),this.renderView()},()=>this.deleteWithUndo(e),this.isCategoricalCol.bind(this),this.titleKey(),r=>this.getBooleanColumns().includes(r),r=>this.isDateCol(r)).open()}openAddModal(){new as(this.app,this.headers,this.isNotesCol.bind(this),this.isSelectCol.bind(this),this.getColumnValues.bind(this),e=>{this.rows.push(e),this.scheduleSave(),this.renderView(),new Ft.Notice(`Added: ${this.getTitle(e)}`)},{},e=>this.getBooleanColumns().includes(e),e=>this.isCategoricalCol(e),this.titleKey(),e=>this.isDateCol(e)).open()}renderSelectField(e,n,i){var a;let o=(a=n[i])!=null?a:"",r=e.createDiv({cls:`csv-select-chip ${o?"":"empty"}`});return r.setText(o||"\u2014"),i.toLowerCase()==="status"&&o&&r.addClass(`status-chip-${o.toLowerCase().replace(/\s+/g,"-")}`),r.addEventListener("click",l=>{var c;l.stopPropagation(),It(r,(c=n[i])!=null?c:"",this.getColumnValues(i),d=>{n[i]=d,r.setText(d||"\u2014"),this.scheduleSave()},this.contentEl)}),r}renderMarkdownInto(e,n){var i,o;Ft.MarkdownRenderer.render(this.app,n,e,(o=(i=this.file)==null?void 0:i.path)!=null?o:"",this.renderComponent)}renderViewPreservingScroll(){this.renderView()}renderView(e=!1){let n=this.containerEl;e?this.contentArea&&this.contentArea.empty():(n.empty(),this.renderToolbar(n),this.contentArea=n.createDiv({cls:"csv-content-area"}),this.opts.height&&(this.contentArea.style.maxHeight=this.opts.height+"px"));let i=this.contentArea;if(i){if(i.toggleClass("csv-content-area--no-yscroll",this.mode==="kanban-genre"||this.mode==="table"),!this.headers.length){i.createDiv({cls:"csv-empty-state"}).createEl("p",{text:"This file is empty."});return}if(this.rows.length===0){let o=i.createDiv({cls:"csv-empty-state"});o.createEl("p",{text:"No entries yet."}),o.createEl("button",{cls:"csv-empty-state-action",text:"+ Add the first entry"}).addEventListener("click",()=>this.openAddModal());return}(this.mode==="library"||this.mode==="kanban-genre")&&!$t(this.asView)&&(this.mode="table"),this.mode==="library"?wn(this.asView,i):this.mode==="kanban-genre"?kn(this.asView,i):_n(this.asView,i)}}renderToolbar(e){var c,d;let n=e.createDiv({cls:"csv-toolbar csv-inline-toolbar"});n.createDiv({cls:"csv-toolbar-title",text:(d=(c=this.file)==null?void 0:c.basename)!=null?d:""}).addEventListener("click",()=>{this.file&&this.app.workspace.getLeaf("tab").openFile(this.file)});let i=n.createDiv({cls:"csv-toolbar-controls"});i.createDiv({cls:"csv-row-count",text:`${this.rows.length} entries`});let o=!!$t(this.asView),r=i.createDiv({cls:"csv-mode-group"});Ng.forEach(({id:h,label:u})=>{if((h==="library"||h==="kanban-genre")&&!o)return;r.createEl("button",{cls:`csv-mode-btn ${this.mode===h?"active":""}`,text:u}).addEventListener("click",()=>{this.mode=h,this.renderView()})});let a=i.createEl("input",{cls:"csv-search-input",type:"text",placeholder:"Search\u2026",value:this.searchQuery,attr:{inputmode:"search",enterkeyhint:"search",autocomplete:"off"}}),l=null;a.addEventListener("input",h=>{this.searchQuery=h.target.value,l!==null&&window.clearTimeout(l),l=window.setTimeout(()=>{l=null,this.renderView(!0)},120)}),i.createEl("button",{cls:"csv-add-btn",text:"+ Add"}).addEventListener("click",()=>this.openAddModal())}};function gc(s,t,e,n){n("csv-view",(i,o,r)=>{var h,u,f;let a=Bg(i),l=(f=(u=(h=s.vault.getAbstractFileByPath(r.sourcePath))==null?void 0:h.parent)==null?void 0:u.path)!=null?f:"",c=a.file?Qt(a.file,l):a.file,d=new Uo(o,s,t,e,{...a,file:c});r.addChild(d)})}var mc=require("obsidian");function $g(s){let t=s.split(` diff --git a/main.ts b/main.ts index fd54391..a5d0f98 100644 --- a/main.ts +++ b/main.ts @@ -45,7 +45,7 @@ let worldMapSvgCache: string | null | undefined = undefined; // Injected by esbuild at build time (see esbuild.config.mjs). Surfaced via // the ⋯ menu so the user can confirm which build is actually loaded — -// handy on iPhone where iCloud sync of the deployed bundle can lag. +// handy on mobile where sync of the deployed bundle can lag. declare const __BUILD_TIME__: string; @@ -207,9 +207,8 @@ export class CardView extends FileView { // ── Title highlight ──────────────────────────────────────────────────────── // Per-file, keyed by the title-column value (like collapsedGroups) rather - // than a row index/id — the CSV has no stable identity column (see the - // optimistic-concurrency TODO in handoff.md), and a value-based key is - // resilient to row reordering/sort changes. + // than a row index/id — the CSV has no stable identity column, and a + // value-based key is resilient to row reordering/sort changes. isHighlighted(row: CSVRow): boolean { return (this.fileCfg.highlightedTitles ?? []).includes(this.getTitle(row)); @@ -778,7 +777,9 @@ export class CardView extends FileView { /** * Load the world-map SVG shipped alongside the plugin. Cached at module * level so it's read once per session (it's ~110 KB). Kept out of the JS - * bundle deliberately — see handoff. Returns null if the asset is missing. + * bundle deliberately — inlining it would only shrink the bundle by + * ~12 KB, not worth the size/complexity tradeoff. Returns null if the + * asset is missing. */ private async loadMapSvg(): Promise { if (worldMapSvgCache !== undefined) return worldMapSvgCache; diff --git a/src/inline-view.ts b/src/inline-view.ts index 9a125d0..1b686c6 100644 --- a/src/inline-view.ts +++ b/src/inline-view.ts @@ -16,7 +16,8 @@ // row menu, the inline note editor, + Add, delete) write back to the source // CSV via app.vault.modify, the same path the full view uses. Other open // views of the same file (a .csv tab, or another csv-view block) re-sync off -// the vault `modify` event. See HANDOFF for the concurrency model. +// the vault `modify` event. This is last-write-wins at the whole-file level — +// no check that the file changed underneath between load and save. import { App, diff --git a/src/travel-data.ts b/src/travel-data.ts index 11c25bc..e1777b6 100644 --- a/src/travel-data.ts +++ b/src/travel-data.ts @@ -4,9 +4,11 @@ // This module is DOM-free and side-effect-free so it can be unit-tested. // The companion `travel-view.ts` renders the model this produces. // -// Source format: the flat `travel_flat.csv` emitted by travel.py — one header, -// uniform rows, with a `source` column (confirmed | inferred | conflict). -// See docs / handoff "Travel / world-map view" for the overlap rules. +// Source format: a flat CSV with one header, uniform rows, and a `source` +// column (confirmed | inferred | conflict). Overlap rule: confirmed rows are +// authoritative — conflict rows are dropped entirely, and an inferred row is +// used only where it doesn't overlap a confirmed range (prevents double- +// counting days a trip is confirmed for). import { CSVRow } from "./types"; diff --git a/src/travel-view.ts b/src/travel-view.ts index f9401f2..8aa5cfd 100644 --- a/src/travel-view.ts +++ b/src/travel-view.ts @@ -4,9 +4,9 @@ // choropleth, per-country day totals, a year-by-year timeline, and the trip // tables (confirmed + collapsed photo-inferred + collapsed conflicts). // -// Coloring rule (see handoff): gold = confirmed countries, blue = countries -// seen only via photo-inferred rows, grey = unvisited. Conflict rows and -// inferred rows overlapping a confirmed range are excluded from map/timeline. +// Coloring rule: gold = confirmed countries, blue = countries seen only via +// photo-inferred rows, grey = unvisited. Conflict rows and inferred rows +// overlapping a confirmed range are excluded from map/timeline. import { CSVRow, ResidencyRule } from "./types"; import { diff --git a/src/utils.ts b/src/utils.ts index f3207e8..9d8547f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -103,8 +103,8 @@ export function isTruthyVal(val: string): boolean { /** * yyyy-mm-dd in *local* time. Everything user-facing must use this rather * than toISOString().slice(0,10) — that's the UTC date, which is yesterday/ - * tomorrow near midnight in any non-UTC timezone (a habit logged at 00:30 - * CEST landed on the previous day's row). + * tomorrow near midnight in any non-UTC timezone (a habit logged just after + * midnight landed on the previous day's row). */ export function localISODate(d: Date = new Date()): string { return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`; diff --git a/src/view/chart.ts b/src/view/chart.ts index c8e9d26..099ad49 100644 --- a/src/view/chart.ts +++ b/src/view/chart.ts @@ -20,7 +20,7 @@ import { localISODate, isMultiValueColName } from "../utils"; /** * Parse a cell into a finite number, or null. Tolerates thousands separators * ("1,234" / "1 234") and a European decimal comma ("3,5") — data typed on a - * Swedish keyboard should chart without a cleanup pass. + * European keyboard layout should chart without a cleanup pass. */ export function parseNumeric(raw: string): number | null { let s = (raw ?? "").trim(); diff --git a/src/view/table.ts b/src/view/table.ts index 0cf6504..e63813c 100644 --- a/src/view/table.ts +++ b/src/view/table.ts @@ -70,7 +70,7 @@ export function renderTable(view: CardView, container: HTMLElement): void { // Skip the clip-detection on touch — the fade gradient it triggers is // a hover affordance and irrelevant without a cursor. Saves N rAFs × N // forced reflows per render on phones (the prime cause of table-view lag - // on iPhone when the file has hundreds of rows). + // on mobile when the file has hundreds of rows). const isTouch = matchMedia("(pointer: coarse)").matches; const tbody = table.createEl("tbody"); filteredRows.forEach((row) => { diff --git a/src/view/toolbar.ts b/src/view/toolbar.ts index fa4f804..12e248f 100644 --- a/src/view/toolbar.ts +++ b/src/view/toolbar.ts @@ -252,7 +252,7 @@ export function renderToolbar(view: CardView, root: HTMLElement): void { menu.addItem(i => i.setTitle("Sync to Anki").setIcon("layers").onClick(openAnki)); menu.addSeparator(); // Build timestamp baked in at compile time. Lets the user confirm on - // iPhone that iCloud has actually synced the latest deploy. + // mobile that sync has actually delivered the latest deploy. menu.addItem(i => i.setTitle(`Built ${__BUILD_TIME__}`).setIcon("info").setDisabled(true)); menu.showAtMouseEvent(e); });