-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.js
More file actions
6 lines (5 loc) · 28 KB
/
Copy pathmain.js
File metadata and controls
6 lines (5 loc) · 28 KB
1
2
3
4
5
6
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
"use strict";var lt=Object.defineProperty;var Gt=Object.getOwnPropertyDescriptor;var Kt=Object.getOwnPropertyNames;var Xt=Object.prototype.hasOwnProperty;var jt=(n,e)=>{for(var t in e)lt(n,t,{get:e[t],enumerable:!0})},zt=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Kt(e))!Xt.call(n,r)&&r!==t&<(n,r,{get:()=>e[r],enumerable:!(i=Gt(e,r))||i.enumerable});return n};var Jt=n=>zt(lt({},"__esModule",{value:!0}),n);var le={};jt(le,{default:()=>st});module.exports=Jt(le);var _=require("obsidian");var Qt=/⏳\[([^|\]]+)\|(?:(stopwatch|countdown)\|)?(running|paused|stopped)\|(\d+)\|(\d+)(?:\|(\d+))?\]/,f=()=>new RegExp(Qt.source,"g"),Zt=/^(\s*>?\s*(?:\d+\.\s|[-+*]\s|#+\s))/;function T(n){return{id:n[1],kind:n[2]??"stopwatch",state:n[3],elapsed:parseInt(n[4],10),startedAt:parseInt(n[5],10),duration:parseInt(n[6]??"0",10)}}function y(n){let e=f(),t=e.exec(n);return t?{...T(t),start:t.index,end:e.lastIndex}:null}function p(n){return`\u23F3[${n.id}|${n.kind}|${n.state}|${n.elapsed}|${n.startedAt}|${n.duration}]`}function W(n,e,t){let i=e>0&&n[e-1]===" ",r=t<n.length&&n[t]===" ";return{from:i?e-1:e,to:r&&!i?t+1:t}}function bt(n,e,t,i){if(i==="cursor"){let r=n.getCursor().ch;n.replaceRange(" "+t,{line:e,ch:r})}else if(i==="head"){let r=n.getLine(e),o=Zt.exec(r),a=o?o[0].length:0;n.replaceRange(t+" ",{line:e,ch:a})}else{let r=n.getLine(e).length;n.replaceRange(" "+t,{line:e,ch:r})}}function D(n,e,t,i,r){n.replaceRange(t,{line:e,ch:i},{line:e,ch:r})}function Y(n,e,t,i){let r=W(n.getLine(e),t,i);n.replaceRange("",{line:e,ch:r.from},{line:e,ch:r.to})}var F=require("@codemirror/view"),Et=require("@codemirror/state"),Q=require("obsidian");var V="obsidian-timer-mutated";function St(){return crypto.randomUUID().slice(0,8)}function m(){return Math.floor(Date.now()/1e3)}function B(n){return Math.max(0,Math.floor(n))}function w(n,e=m()){let t=n.state==="running"?n.elapsed+Math.max(0,e-n.startedAt):n.elapsed;return n.kind==="countdown"?Math.min(B(t),Math.max(0,n.duration)):B(t)}function v(n,e=m()){return n.kind!=="countdown"?0:Math.max(0,n.duration-w(n,e))}function I(n,e=m()){let t=w(n,e);return n.kind==="countdown"&&t>=n.duration?{...n,state:"stopped",elapsed:n.duration,startedAt:e}:{...n,state:"paused",elapsed:t,startedAt:e}}function G(n,e=m()){let t=n.state==="stopped"?0:w(n,e);return{...n,state:"running",elapsed:n.kind==="countdown"?Math.min(t,n.duration):t,startedAt:e}}function h(n,e=m()){return{...n,state:"stopped",elapsed:w(n,e),startedAt:e}}function K(n,e=m()){return{...n,state:"paused",elapsed:0,startedAt:e}}function xt(n,e,t=m()){let i=B(e);return n.kind==="countdown"?{...n,duration:i,elapsed:0,startedAt:t,state:n.state==="stopped"?"paused":n.state}:{...n,elapsed:i,startedAt:t,state:n.state==="stopped"?"paused":n.state}}function b(n){let e=B(n),t=Math.floor(e/3600),i=Math.floor(e%3600/60),r=e%60,o=a=>a.toString().padStart(2,"0");return t>0?`${o(t)}:${o(i)}:${o(r)}`:`${o(i)}:${o(r)}`}function X(n){let e=n.trim();if(!e)return null;if(/^\d+$/.test(e))return parseInt(e,10)*60;let t=e.split(":").map(i=>i.trim());if(!t.every(i=>/^\d+$/.test(i)))return null;if(t.length===2){let[i,r]=t.map(o=>parseInt(o,10));return r>59?null:i*60+r}if(t.length===3){let[i,r,o]=t.map(a=>parseInt(a,10));return r>59||o>59?null:i*3600+r*60+o}return null}function j(n="chime"){try{let e=window.AudioContext||window.webkitAudioContext;if(!e)return;let t=new e,i=t.currentTime;switch(n){case"chime":{[523.25,659.25,783.99].forEach((o,a)=>{let s=t.createOscillator(),c=t.createGain();s.type="sine",s.frequency.setValueAtTime(o,i),c.gain.setValueAtTime(0,i),c.gain.linearRampToValueAtTime(.3,i+.02),c.gain.exponentialRampToValueAtTime(.001,i+.4+a*.15),s.connect(c).connect(t.destination),s.start(i+a*.08),s.stop(i+.6+a*.15)}),setTimeout(()=>t.close(),1200);break}case"bell":{let r=t.createOscillator(),o=t.createGain();r.type="sine",r.frequency.setValueAtTime(830,i),o.gain.setValueAtTime(0,i),o.gain.linearRampToValueAtTime(.35,i+.01),o.gain.exponentialRampToValueAtTime(.001,i+.8),r.connect(o).connect(t.destination),r.start(i),r.stop(i+.8);let a=t.createOscillator(),s=t.createGain();a.type="sine",a.frequency.setValueAtTime(1660,i),s.gain.setValueAtTime(0,i),s.gain.linearRampToValueAtTime(.12,i+.01),s.gain.exponentialRampToValueAtTime(.001,i+.5),a.connect(s).connect(t.destination),a.start(i),a.stop(i+.5),setTimeout(()=>t.close(),1e3);break}case"beep":{let r=t.createOscillator(),o=t.createGain();r.type="sine",r.frequency.setValueAtTime(880,i),o.gain.setValueAtTime(0,i),o.gain.linearRampToValueAtTime(.25,i+.02),o.gain.exponentialRampToValueAtTime(.001,i+.25),r.connect(o).connect(t.destination),r.start(i),r.stop(i+.25),setTimeout(()=>t.close(),400);break}case"digital":{for(let r=0;r<3;r++){let o=t.createOscillator(),a=t.createGain();o.type="square",o.frequency.setValueAtTime(1200,i),a.gain.setValueAtTime(0,i),a.gain.linearRampToValueAtTime(.1,i+r*.15),a.gain.linearRampToValueAtTime(0,i+.1+r*.15),o.connect(a).connect(t.destination),o.start(i+r*.15),o.stop(i+.1+r*.15)}setTimeout(()=>t.close(),600);break}case"marimba":{[392,523.25,659.25].forEach((o,a)=>{let s=t.createOscillator(),c=t.createGain();s.type="sine",s.frequency.setValueAtTime(o,i),c.gain.setValueAtTime(0,i),c.gain.linearRampToValueAtTime(.4,i+.01+a*.15),c.gain.exponentialRampToValueAtTime(.001,i+.3+a*.15),s.connect(c).connect(t.destination),s.start(i+a*.15),s.stop(i+.4+a*.15)}),setTimeout(()=>t.close(),1e3);break}}}catch{}}function z(n){let e=n.kind==="countdown"?n.state==="stopped"?w(n):v(n):w(n),t;return n.state==="running"?t="\u231B":n.state==="stopped"?t="\u23F9\uFE0F":t="\u23F3",`${t}${b(e)}`}function ut(n){let e=n.kind==="countdown"?"Countdown":"Stopwatch",t=n.state.charAt(0).toUpperCase()+n.state.slice(1),i=n.kind==="countdown"?n.state==="stopped"?w(n):v(n):w(n);return`${e} ${t}: ${b(i)}`}function N(n,e,t){e.state==="running"?n.addItem(i=>i.setTitle("Pause").setIcon("pause").onClick(()=>t.replace(I(e,m())))):n.addItem(i=>i.setTitle(e.state==="stopped"?"Start":"Resume").setIcon("play").onClick(()=>t.replace(G(e,m())))),n.addItem(i=>i.setTitle("Stop").setIcon("square").onClick(()=>t.replace(h(e,m())))),n.addItem(i=>i.setTitle("Reset").setIcon("refresh-cw").onClick(()=>t.replace(K(e,m())))),n.addItem(i=>i.setTitle("Change time").setIcon("clock").onClick(()=>t.changeTime())),n.addItem(i=>i.setTitle("Delete").setIcon("trash").onClick(()=>t.remove()))}var L=require("obsidian");function M(n,e,t){let i=e.kind==="countdown"?v(e):w(e);class r extends L.Modal{value=b(i);onOpen(){this.titleEl.setText("Set time"),new L.Setting(this.contentEl).setName("Time").setDesc("mm:ss, hh:mm:ss, or a whole number for minutes").addText(a=>{a.setValue(this.value),a.onChange(s=>this.value=s),a.inputEl.addEventListener("keydown",s=>{s.key==="Enter"&&(s.preventDefault(),this.submit())}),setTimeout(()=>{a.inputEl.focus(),a.inputEl.select()},10)}),new L.Setting(this.contentEl).addButton(a=>a.setButtonText("OK").setCta().onClick(()=>this.submit())).addButton(a=>a.setButtonText("Cancel").onClick(()=>this.close()))}submit(){let a=X(this.value);if(a===null||a<0){new L.Notice("Invalid time format.");return}this.close(),t(xt(e,a,m()))}}new r(n).open()}function J(n,e){let t=null,i=0,r=0,o=()=>{t!==null&&(window.clearTimeout(t),t=null)};n.addEventListener("touchstart",a=>{if(a.touches.length!==1)return;let s=a.touches[0];i=s.clientX,r=s.clientY,t=window.setTimeout(()=>{t=null;let c=new MouseEvent("contextmenu",{bubbles:!0,clientX:s.clientX,clientY:s.clientY});e(c)},500)},{passive:!1}),n.addEventListener("touchmove",a=>{if(t===null)return;let s=a.touches[0],c=s.clientX-i,l=s.clientY-r;c*c+l*l>100&&o()}),n.addEventListener("touchend",o),n.addEventListener("touchcancel",o)}var dt=null,pt=null;function At(n){dt=n}function kt(n){pt=n}function te(n,e,t){let i=n.posAtDOM(e),r=n.state.doc.lineAt(i),o=f(),a;for(;(a=o.exec(r.text))!==null;)if(a[1]===t){let s=r.from+a.index;return{from:s,to:s+a[0].length}}return null}function Mt(){window.dispatchEvent(new CustomEvent(V))}function mt(n,e,t){n.dispatch({changes:{from:e.from,to:e.to,insert:p(t)}}),Mt()}function ee(n,e){let t=n.state.doc.lineAt(e.from),i=W(t.text,e.from-t.from,e.to-t.from);n.dispatch({changes:{from:t.from+i.from,to:t.from+i.to,insert:""}}),Mt()}var ft=class extends F.WidgetType{constructor(t){super();this.data=t}data;interval=null;isFirstRender=!0;eq(t){return this.data.id===t.data.id&&this.data.kind===t.data.kind&&this.data.state===t.data.state&&this.data.elapsed===t.data.elapsed&&this.data.startedAt===t.data.startedAt&&this.data.duration===t.data.duration}toDOM(t){let i=document.createElement("span");i.className=`timer-badge timer-${this.data.kind} timer-${this.data.state}`,i.setAttribute("role","button"),i.setAttribute("tabindex","0"),i.setAttribute("aria-label",ut(this.data));let r=()=>te(t,i,this.data.id),o=()=>{if(this.data.kind!=="countdown"||this.data.state!=="running"||v(this.data)>0)return!1;if(this.isFirstRender)return this.data=h(this.data,m()),!1;let c=r();return c?(new Q.Notice("Timer finished!"),pt?.playCompletionSound&&j(pt.soundType),mt(t,c,h(this.data,m())),this.interval!==null&&(window.clearInterval(this.interval),this.interval=null),!0):!1},a=()=>{o()||(this.isFirstRender=!1,i.className=`timer-badge timer-${this.data.kind} timer-${this.data.state}`,i.textContent=z(this.data),i.setAttribute("aria-label",ut(this.data)))},s=c=>{let l=new Q.Menu;N(l,this.data,{replace:u=>{let d=r();d&&mt(t,d,u)},changeTime:()=>{dt&&M(dt,this.data,u=>{let d=r();d&&mt(t,d,u)})},remove:()=>{let u=r();u&&ee(t,u)}}),l.showAtMouseEvent(c)};return a(),this.data.state==="running"&&(this.interval=window.setInterval(a,1e3)),i.onclick=c=>{c.preventDefault(),c.stopPropagation(),s(c)},i.oncontextmenu=c=>{c.preventDefault(),c.stopPropagation(),s(c)},J(i,s),i}destroy(){this.interval!==null&&(window.clearInterval(this.interval),this.interval=null)}};function Dt(n){let e=new Et.RangeSetBuilder;for(let{from:t,to:i}of n.visibleRanges){let r=n.state.doc.sliceString(t,i),o=f(),a;for(;(a=o.exec(r))!==null;){let s=t+a.index,c=s+a[0].length;e.add(s,c,F.Decoration.replace({widget:new ft(T(a))}))}}return e.finish()}var Rt=F.ViewPlugin.fromClass(class{decorations;constructor(n){this.decorations=Dt(n)}update(n){(n.docChanged||n.viewportChanged)&&(this.decorations=Dt(n.view))}},{decorations:n=>n.decorations});var S=require("obsidian");var nt=require("obsidian");function ne(n){let e=new Date(n);return e.setHours(0,0,0,0),Math.floor(e.getTime()/1e3)}function ie(n){let e=new Date(n),t=e.getDay(),i=t===0?6:t-1;return e.setDate(e.getDate()-i),e.setHours(0,0,0,0),Math.floor(e.getTime()/1e3)}function ht(n){let e=new Date(n*1e3),t=e.getFullYear(),i=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}-${i}-${r}`}function re(n){if(n.size===0)return 0;let e=new Date;e.setHours(0,0,0,0);let t=0,i=new Date(e),r=ht(Math.floor(i.getTime()/1e3));for(n.has(r)||i.setDate(i.getDate()-1);;){let o=ht(Math.floor(i.getTime()/1e3));if(!n.has(o))break;t++,i.setDate(i.getDate()-1)}return t}async function Ct(n){let e=new Date,t=ne(e),i=ie(e),r=[],o=0,a=0,s=0,c=0,l=0,u=0,d=new Map,g=new Map,E=n.vault.getMarkdownFiles();for(let P of E){let q=await n.vault.cachedRead(P);if(!q.includes("\u23F3["))continue;let qt=f(),wt;for(;(wt=qt.exec(q))!==null;){let A=T(wt),ot=A.state==="running",Yt=A.state==="paused";ot&&l++;let yt=Math.floor(e.getTime()/1e3),k=w(A,yt),Bt={...A,effective:k,filePath:P.path};!ot&&!Yt&&(r.push(Bt),s++,k>u&&(u=k),A.kind==="countdown"&&k>=A.duration&&A.duration>0&&c++),d.set(P.path,(d.get(P.path)??0)+k);let ct=ot?yt:A.startedAt,vt=ht(ct);g.set(vt,(g.get(vt)??0)+k),ct>=t&&(o+=k),ct>=i&&(a+=k)}}let $=r.sort((P,q)=>q.startedAt-P.startedAt).slice(0,10),at=re(g);return{sessions:r,todayTotal:o,weekTotal:a,totalSessions:s,completedCountdowns:c,activeTimers:l,streak:at,longestSession:u,byFile:d,byDay:g,recentSessions:$}}function se(n){let e=Math.floor(Date.now()/1e3)-n;return e<60?"just now":e<3600?`${Math.floor(e/60)}m ago`:e<86400?`${Math.floor(e/3600)}h ago`:e<172800?"yesterday":`${Math.floor(e/86400)}d ago`}function Vt(n){let e=n.split("/");return e[e.length-1].replace(/\.md$/,"")}var ae=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];function oe(){let n=new Date,e=new Date(n);e.setHours(0,0,0,0);let t=e.getDay(),i=t===0?6:t-1,r=new Date(e);r.setDate(e.getDate()-i);let o=[];for(let a=0;a<7;a++){let s=new Date(r);s.setDate(r.getDate()+a);let c=s.getFullYear(),l=String(s.getMonth()+1).padStart(2,"0"),u=String(s.getDate()).padStart(2,"0");o.push({key:`${c}-${l}-${u}`,label:ae[a],isToday:s.getTime()===e.getTime()})}return o}function Z(n){if(n===0)return"\u2014";let e=Math.floor(n/3600),t=Math.floor(n%3600/60);return e>0?`${e}h ${t.toString().padStart(2,"0")}m`:`${t}m`}function tt(n,e){let t=n.createDiv({cls:"ta-section"});return t.createDiv({cls:"ta-section-title",text:e}),t}function O(n,e,t,i){let r=n.createDiv({cls:"ta-stat"});r.createSpan({cls:"ta-stat-label",text:e}),r.createSpan({cls:`ta-stat-value ${i??""}`.trim(),text:t})}function It(n,e,t){if(n.empty(),n.addClass("timer-analytics-root"),e.totalSessions===0&&e.activeTimers===0){let s=n.createDiv({cls:"ta-empty"});s.createSpan({text:"No timer data found."}),s.createEl("br"),s.createSpan({text:"Start a timer to see analytics!"});return}let i=tt(n,"Summary");if(O(i,"Today",Z(e.todayTotal)),O(i,"This Week",Z(e.weekTotal)),O(i,"Sessions",String(e.totalSessions)),e.completedCountdowns>0&&O(i,"Completed \u{1F345}",String(e.completedCountdowns)),e.activeTimers>0&&O(i,"Active now",String(e.activeTimers),"ta-active"),e.streak>0&&O(i,"Streak",`${e.streak} day${e.streak>1?"s":""} \u{1F525}`),e.byFile.size>0){let s=tt(n,"By File"),c=[...e.byFile.entries()].sort((u,d)=>d[1]-u[1]).slice(0,10),l=c[0]?.[1]??1;for(let[u,d]of c){let g=s.createDiv({cls:"ta-file-row"});g.addEventListener("click",()=>{t.workspace.openLinkText(u,"")});let E=g.createDiv({cls:"ta-file-info"});E.createSpan({cls:"ta-file-name",text:`\u{1F4C4} ${Vt(u)}`}),E.createSpan({cls:"ta-file-time",text:Z(d)});let at=g.createDiv({cls:"ta-bar-track"}).createDiv({cls:"ta-bar"});at.style.width=`${Math.max(4,d/l*100)}%`}}let r=tt(n,"Weekly Trend"),o=oe(),a=o.reduce((s,c)=>{let l=e.byDay.get(c.key)??0;return l>s?l:s},1);for(let s of o){let c=e.byDay.get(s.key)??0,l=r.createDiv({cls:`ta-week-row ${s.isToday?"ta-today":""}`});l.createSpan({cls:"ta-week-day",text:s.label});let u=l.createDiv({cls:"ta-bar-track"});if(c>0){let d=u.createDiv({cls:"ta-bar"});d.style.width=`${Math.max(4,c/a*100)}%`}l.createSpan({cls:"ta-week-time",text:s.isToday&&c===0?"(today)":Z(c)})}if(e.recentSessions.length>0){let s=tt(n,"Recent Sessions");for(let c of e.recentSessions){let l=s.createDiv({cls:"ta-recent-row"});l.addEventListener("click",()=>{t.workspace.openLinkText(c.filePath,"")});let u=c.kind==="countdown"?"\u{1F345}":"\u23F9\uFE0F";l.createSpan({cls:"ta-recent-icon",text:u}),l.createSpan({cls:"ta-recent-duration",text:b(c.effective)}),l.createSpan({cls:"ta-recent-file",text:Vt(c.filePath)}),l.createSpan({cls:"ta-recent-ago",text:se(c.startedAt)})}}}var R="tag-timer-analytics",et=class extends nt.ItemView{scanning=!1;constructor(e){super(e)}getViewType(){return R}getDisplayText(){return"Timer Analytics"}getIcon(){return"bar-chart-2"}async onOpen(){await this.refresh()}async onClose(){this.contentEl.empty()}async refresh(){if(!this.scanning){this.scanning=!0;try{let e=this.contentEl;e.empty(),e.addClass("timer-analytics-root");let t=e.createDiv({cls:"ta-header"}),i=t.createEl("button",{cls:"ta-refresh clickable-icon",attr:{"aria-label":"Refresh analytics"}});(0,nt.setIcon)(i,"refresh-cw"),i.addEventListener("click",()=>{this.refresh()});let o=new Date().toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"});t.createSpan({cls:"ta-timestamp",text:`Scanned ${o}`});let a=e.createDiv({cls:"ta-body"}),s=await Ct(this.app);It(a,s,this.app)}finally{this.scanning=!1}}}};var Lt={insertPosition:"tail",lastActiveTime:0,defaultCountdownSeconds:1500,playCompletionSound:!1,soundType:"chime",enableAnalytics:!1},it=class extends S.PluginSettingTab{plugin;constructor(e,t){super(e,t),this.plugin=t}display(){let{containerEl:e}=this;e.empty(),e.createEl("h2",{text:"Timer Settings"}),new S.Setting(e).setName("Insert position").setDesc("Where to insert new timers on a line.").addDropdown(t=>t.addOption("tail","End of line").addOption("head","Start of line").addOption("cursor","At cursor").setValue(this.plugin.settings.insertPosition).onChange(async i=>{this.plugin.settings.insertPosition=i,await this.plugin.saveSettings()})),new S.Setting(e).setName("Play sound on completion").setDesc("Play a brief text-editor friendly sound when a countdown finishes.").addToggle(t=>t.setValue(this.plugin.settings.playCompletionSound).onChange(async i=>{this.plugin.settings.playCompletionSound=i,await this.plugin.saveSettings()})),new S.Setting(e).setName("Sound type").setDesc("Which sound to play on countdown completion.").addDropdown(t=>t.addOption("chime","Soft Chime").addOption("bell","Gentle Bell").addOption("beep","Classic Beep").addOption("digital","Digital Alarm").addOption("marimba","Soft Marimba").setValue(this.plugin.settings.soundType).onChange(async i=>{this.plugin.settings.soundType=i,await this.plugin.saveSettings()})),new S.Setting(e).setName("Default countdown").setDesc("Used by Alt+C. Use mm:ss, hh:mm:ss, or a whole number for minutes.").addText(t=>{t.setPlaceholder("25:00"),t.setValue(b(this.plugin.settings.defaultCountdownSeconds));let i=async()=>{let r=X(t.inputEl.value);if(r===null||r<=0){new S.Notice("Invalid countdown."),t.setValue(b(this.plugin.settings.defaultCountdownSeconds));return}this.plugin.settings.defaultCountdownSeconds=r,await this.plugin.saveSettings(),t.setValue(b(r))};t.inputEl.addEventListener("blur",()=>{i()}),t.inputEl.addEventListener("keydown",r=>{r.key==="Enter"&&(r.preventDefault(),i(),t.inputEl.blur())})}),e.createEl("h3",{text:"Advanced"}),new S.Setting(e).setName("Enable analytics panel").setDesc("Show a sidebar panel with time tracking analytics. Requires reopening the analytics view after toggling.").addToggle(t=>t.setValue(this.plugin.settings.enableAnalytics).onChange(async i=>{this.plugin.settings.enableAnalytics=i,await this.plugin.saveSettings(),i?(this.plugin.registerAnalytics(),this.plugin.toggleAnalyticsRibbon(!0)):(this.plugin.toggleAnalyticsRibbon(!1),this.app.workspace.getLeavesOfType(R).forEach(r=>r.detach()))}))}};var U=require("obsidian");function x(n,e,t,i,r,o="stopwatch"){if(i.getMode?.()==="preview"){new U.Notice("Switch to edit mode to use timers.");return}let a=t.getCursor().line,s=y(t.getLine(a));if(!s){if(r!=="toggle"){new U.Notice("No timer found on current line.");return}let l=Math.max(1,e.defaultCountdownSeconds),u={id:St(),kind:o,state:"running",elapsed:0,startedAt:m(),duration:o==="countdown"?l:0};bt(t,a,p(u),e.insertPosition);return}if(r==="delete"){Y(t,a,s.start,s.end),new U.Notice("Timer deleted");return}if(r==="change"){M(n,s,l=>{let u=y(t.getLine(a));if(!u||u.id!==s.id){new U.Notice("Timer moved or deleted.");return}D(t,a,p(l),u.start,u.end)});return}let c;r==="stop"?c=h(s,m()):r==="reset"?c=K(s,m()):c=s.state==="running"?I(s,m()):G(s,m()),D(t,a,p(c),s.start,s.end)}var gt=require("obsidian");function $t(n,e,t,i,r){let o=i.getCursor().line,a=y(i.getLine(o));if(!a){t.addItem(s=>s.setTitle("Start timer").setIcon("play").onClick(()=>x(n,e,i,r,"toggle","stopwatch"))),t.addItem(s=>s.setTitle("Start countdown").setIcon("timer").onClick(()=>x(n,e,i,r,"toggle","countdown")));return}N(t,a,{replace:s=>{let c=y(i.getLine(o));!c||c.id!==a.id||D(i,o,p(s),c.start,c.end)},changeTime:()=>{M(n,a,s=>{let c=y(i.getLine(o));if(!c||c.id!==a.id){new gt.Notice("Timer moved or deleted.");return}D(i,o,p(s),c.start,c.end)})},remove:()=>{let s=y(i.getLine(o));!s||s.id!==a.id||(Y(i,o,s.start,s.end),new gt.Notice("Timer deleted"))}})}var H=require("obsidian");function Pt(n,e,t,i){return n.replace(f(),(...r)=>{let o=T(r);return o.state!=="running"?r[0]:(i&&i.count++,p(t(o,e)))})}function Nt(n,e,t){return Pt(n,e,I,t)}function Tt(n,e=m()){let t=new Set;return n.workspace.getLeavesOfType("markdown").forEach(i=>{if(!(i.view instanceof H.MarkdownView))return;let r=i.view.file;r&&t.add(r.path);let o=i.view.editor;for(let a=0;a<o.lineCount();a++){let s=y(o.getLine(a));s?.state==="running"&&D(o,a,p(I(s,e)),s.start,s.end)}}),t}async function Ft(n,e){let t=e>0?e:m(),i={count:0},r=n.vault.getMarkdownFiles();for(let o of r)if((await n.vault.cachedRead(o)).includes("|running|"))try{await n.vault.process(o,s=>Nt(s,t,i))}catch(s){console.error(`Timer: recovery failed for ${o.path}`,s)}i.count>0&&new H.Notice(`Recovered ${i.count} running timer(s) from previous session.`)}async function Ot(n,e=m()){let t=Tt(n,e),i=n.vault.getMarkdownFiles();for(let r of i)if(!(t.has(r.path)||!(await n.vault.cachedRead(r)).includes("|running|")))try{await n.vault.process(r,a=>Nt(a,e))}catch(a){console.error(`Timer: save failed for ${r.path}`,a)}}async function _t(n,e=m()){let t=new Set,i=0;n.workspace.getLeavesOfType("markdown").forEach(o=>{if(!(o.view instanceof H.MarkdownView))return;let a=o.view.file;a&&t.add(a.path);let s=o.view.editor;for(let c=0;c<s.lineCount();c++){let l=y(s.getLine(c));l?.state==="running"&&(i++,D(s,c,p(h(l,e)),l.start,l.end))}});let r=n.vault.getMarkdownFiles();for(let o of r)if(!(t.has(o.path)||!(await n.vault.cachedRead(o)).includes("|running|")))try{await n.vault.process(o,s=>{let c={count:0},l=Pt(s,e,h,c);return i+=c.count,l})}catch(s){console.error(`Timer: stop failed for ${o.path}`,s)}return i}async function Wt(n,e=m()){let t=0,i=n.vault.getMarkdownFiles();for(let r of i){let o=await n.vault.cachedRead(r);if(!o.includes("|running|"))continue;let a=f(),s=!1,c;for(;(c=a.exec(o))!==null;){let l=T(c);if(l.state==="running"&&l.kind==="countdown"&&v(l,e)===0){s=!0;break}}if(s)try{await n.vault.process(r,l=>l.replace(f(),(...u)=>{let d=T(u);return d.state==="running"&&d.kind==="countdown"&&v(d,e)===0?(t++,p(h(d,e))):u[0]}))}catch(l){console.error(`Timer: expire failed for ${r.path}`,l)}}return t}var C=require("obsidian");var Ut=require("obsidian");function ce(n,e,t){let i=f(),r;for(;(r=i.exec(n))!==null;){if(r[1]!==e)continue;let o=T(r),a=t(o),s=r.index,c=s+r[0].length;if(a===null){let l=W(n,s,c);return n.slice(0,l.from)+n.slice(l.to)}else return n.slice(0,s)+p(a)+n.slice(c)}return n}async function Ht(n,e,t,i){let r=null;try{await n.vault.process(e,o=>ce(o,t,a=>(r=i(a),r)))}catch(o){return console.error("Timer: failed to update timer",o),new Ut.Notice("Failed to update timer."),null}return window.dispatchEvent(new CustomEvent(V)),r}var rt=class extends C.MarkdownRenderChild{constructor(t,i,r,o,a){super(t);this.data=i;this.app=r;this.sourcePath=o;this.settings=a}data;app;sourcePath;settings;interval=null;finishing=!1;isFirstRender=!0;syncInterval(){this.data.state==="running"?this.interval===null&&(this.interval=window.setInterval(()=>this.refresh(),1e3)):this.interval!==null&&(window.clearInterval(this.interval),this.interval=null)}refresh(){if(!this.finishing&&this.data.kind==="countdown"&&this.data.state==="running"&&v(this.data)===0)if(this.isFirstRender)this.data=h(this.data,m());else{this.finishing=!0,new C.Notice("Timer finished!"),this.settings.playCompletionSound&&j(this.settings.soundType),this.mutate(t=>h(t,m())).finally(()=>{this.finishing=!1});return}this.isFirstRender=!1,this.containerEl.className=`timer-badge timer-${this.data.kind} timer-${this.data.state}`,this.containerEl.textContent=z(this.data),this.syncInterval()}async mutate(t){let i=this.app.vault.getAbstractFileByPath(this.sourcePath);if(!(i instanceof C.TFile))return;let r=await Ht(this.app,i,this.data.id,t);r?(this.data=r,this.refresh()):(this.containerEl.remove(),this.interval!==null&&(window.clearInterval(this.interval),this.interval=null))}openMenu(t){let i=new C.Menu;N(i,this.data,{replace:r=>{this.mutate(()=>r)},changeTime:()=>{M(this.app,this.data,r=>{this.mutate(()=>r)})},remove:()=>{this.mutate(()=>null)}}),i.showAtMouseEvent(t)}onload(){this.refresh(),this.containerEl.onclick=t=>{t.preventDefault(),t.stopPropagation(),this.openMenu(t)},this.containerEl.oncontextmenu=t=>{t.preventDefault(),t.stopPropagation(),this.openMenu(t)},J(this.containerEl,t=>this.openMenu(t))}onunload(){this.interval!==null&&(window.clearInterval(this.interval),this.interval=null)}};var st=class extends _.Plugin{settings;beforeUnloadRef=null;timerMutatedRef=null;enforcingLimit=!1;analyticsRegistered=!1;analyticsRibbonIcon=null;async onload(){await this.loadSettings(),At(this.app),kt(this.settings),this.registerEditorExtension(Rt),await Ft(this.app,this.settings.lastActiveTime),this.registerInterval(window.setInterval(()=>{this.settings.lastActiveTime=m(),this.saveSettings(),Wt(this.app)},3e4)),this.beforeUnloadRef=()=>{Tt(this.app)},window.addEventListener("beforeunload",this.beforeUnloadRef),this.timerMutatedRef=()=>{this.saveSettings()},window.addEventListener(V,this.timerMutatedRef),this.registerMarkdownPostProcessor((e,t)=>{let i=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),r=[],o;for(;(o=i.nextNode())!==null;)r.push(o);for(let a of r){let s=a.textContent??"",c=f(),l,u=0,d=!1,g=document.createDocumentFragment();for(;(l=c.exec(s))!==null;){d=!0,l.index>u&&g.append(s.slice(u,l.index));let E=T(l),$=document.createElement("span");$.className=`timer-badge timer-${E.kind} timer-${E.state}`,g.appendChild($),t.addChild(new rt($,E,this.app,t.sourcePath,this.settings)),u=l.index+l[0].length}d&&(u<s.length&&g.append(s.slice(u)),a.parentNode?.replaceChild(g,a))}}),this.registerEvent(this.app.workspace.on("editor-change",e=>{if(this.enforcingLimit)return;let t=e.getCursor().line,r=[...e.getLine(t).matchAll(f())];if(r.length>1){this.enforcingLimit=!0;try{for(let o=r.length-1;o>0;o--){let a=r[o];a.index!==void 0&&e.replaceRange("",{line:t,ch:a.index},{line:t,ch:a.index+a[0].length})}}finally{this.enforcingLimit=!1}}})),this.addCommand({id:"toggle-timer",name:"Toggle timer",hotkeys:[{modifiers:["Mod","Shift"],key:"s"}],editorCallback:(e,t)=>x(this.app,this.settings,e,t,"toggle","stopwatch")}),this.addCommand({id:"toggle-countdown",name:"Start/pause countdown",hotkeys:[{modifiers:["Mod","Shift"],key:"c"}],editorCallback:(e,t)=>x(this.app,this.settings,e,t,"toggle","countdown")}),this.addCommand({id:"stop-timer",name:"Stop timer",editorCallback:(e,t)=>x(this.app,this.settings,e,t,"stop")}),this.addCommand({id:"stop-all-timers",name:"Stop all running timers",callback:async()=>{let e=await _t(this.app);new _.Notice(`Stopped ${e} running timer(s).`)}}),this.addCommand({id:"reset-timer",name:"Reset timer",editorCallback:(e,t)=>x(this.app,this.settings,e,t,"reset")}),this.addCommand({id:"change-timer-time",name:"Change timer/countdown time",editorCallback:(e,t)=>x(this.app,this.settings,e,t,"change")}),this.addCommand({id:"delete-timer",name:"Delete timer",hotkeys:[{modifiers:["Mod","Shift"],key:"d"}],editorCallback:(e,t)=>x(this.app,this.settings,e,t,"delete")}),this.registerEvent(this.app.workspace.on("editor-menu",(e,t,i)=>{i instanceof _.MarkdownView&&$t(this.app,this.settings,e,t,i)})),this.addSettingTab(new it(this.app,this)),this.settings.enableAnalytics&&this.registerAnalytics()}registerAnalytics(){this.analyticsRegistered||(this.analyticsRegistered=!0,this.registerView(R,e=>new et(e)),this.addCommand({id:"open-timer-analytics",name:"Open timer analytics",checkCallback:e=>this.settings.enableAnalytics?(e||this.activateAnalyticsView(),!0):!1}),this.analyticsRibbonIcon=this.addRibbonIcon("bar-chart-2","Timer Analytics",()=>{this.settings.enableAnalytics&&this.activateAnalyticsView()}),this.toggleAnalyticsRibbon(this.settings.enableAnalytics))}toggleAnalyticsRibbon(e){this.analyticsRibbonIcon&&(this.analyticsRibbonIcon.style.display=e?"":"none")}async activateAnalyticsView(){let{workspace:e}=this.app,t=null,i=e.getLeavesOfType(R);if(i.length>0)t=i[0];else{if(t=e.getRightLeaf(!1),!t)return;await t.setViewState({type:R,active:!0})}e.revealLeaf(t)}async onunload(){this.beforeUnloadRef&&(window.removeEventListener("beforeunload",this.beforeUnloadRef),this.beforeUnloadRef=null),this.timerMutatedRef&&(window.removeEventListener(V,this.timerMutatedRef),this.timerMutatedRef=null),await Ot(this.app),this.app.workspace.getLeavesOfType(R).forEach(e=>e.detach())}async loadSettings(){this.settings=Object.assign({},Lt,await this.loadData()),"runningTimerFiles"in this.settings&&(delete this.settings.runningTimerFiles,await this.saveSettings())}async saveSettings(){await this.saveData(this.settings)}};