-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
58 lines (54 loc) · 107 KB
/
Copy pathmain.js
File metadata and controls
58 lines (54 loc) · 107 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
"use strict";var we=Object.defineProperty;var $s=Object.getOwnPropertyDescriptor;var _s=Object.getOwnPropertyNames;var zs=Object.prototype.hasOwnProperty;var Ks=(i,n)=>{for(var t in n)we(i,t,{get:n[t],enumerable:!0})},Gs=(i,n,t,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of _s(n))!zs.call(i,s)&&s!==t&&we(i,s,{get:()=>n[s],enumerable:!(e=$s(n,s))||e.enumerable});return i};var Us=i=>Gs(we({},"__esModule",{value:!0}),i);var dr={};Ks(dr,{default:()=>ye});module.exports=Us(dr);var vt=require("obsidian");var Mt="ProjectConfig",Ot="ProjectTask",Ae="Ignore",Be="ProjectTrackerIgnore",G="project-tracker-project",N="project-tracker-list",U="project-tracker-column",Vt=new Set(["tags","position","aliases","cssclasses","project-id","project-file","task-parent","task-name","task-status","task-prioritized","task-labels","task-start","task-due","task-created","task-modified","task-status-modified"]);function rt(i){return i==="none"||i==="label"?i:"status"}function yt(i){return i==="kanban"}var es=require("obsidian");var Ws=["#0969da","#1a7f37","#8250df","#bf3989","#bc4c00","#9a6700","#0e7490","#6e7781"],kt=Ws[0],A="layout-dashboard";function R(){return{backlog:{name:"Backlog",color:"#ffffff",nextStatus:"upcoming",warnStart:!1,warnDue:!0,autoStatusChange:null},upcoming:{name:"Upcoming",color:"#9a6700",nextStatus:"in-progress",warnStart:!1,warnDue:!0,autoStatusChange:null},"in-progress":{name:"In Progress",color:"#0969da",nextStatus:"complete",warnStart:!1,warnDue:!0,autoStatusChange:null},complete:{name:"Completed",color:"#1a7f37",nextStatus:"archived",warnStart:!1,warnDue:!1,autoStatusChange:"30d"},archived:{name:"Archived",color:"#8250df",nextStatus:null,warnStart:!1,warnDue:!1,autoStatusChange:null}}}function He(){return{bug:{name:"Bug",color:"#d1242f"},feature:{name:"Feature",color:"#0969da"},chore:{name:"Chore",color:"#6e7781"}}}function W(){return{status:[],labels:[],prioritized:null,date:null}}function J(){return["title","status","labels","due","created"]}function It(){return{defaultView:"board",openTasksInBoard:!0,views:[{id:"board",name:"Board",type:"kanban",filters:{...W(),status:["upcoming","in-progress","complete"]},groupBy:"status",showDescription:!0,sort:{field:"task-created",dir:"desc"},columns:J()},{id:"backlog",name:"Backlog",type:"table",filters:{...W(),status:["backlog"]},groupBy:"none",showDescription:!1,sort:{field:"task-created",dir:"desc"},columns:J()},{id:"all-tasks",name:"All tasks",type:"table",filters:W(),groupBy:"none",showDescription:!1,sort:{field:"task-created",dir:"desc"},columns:J()}]}}var At=require("obsidian");function Js(i){let n="",t=!1,e=!1,s=0;for(;s<i.length;){let r=i[s];if(t){n+=r,e?e=!1:r==="\\"?e=!0:r==='"'&&(t=!1),s++;continue}if(r==='"'){t=!0,n+=r,s++;continue}if(r==="#"||r==="/"&&i[s+1]==="/"){for(;s<i.length&&i[s]!==`
`;)s++;continue}if(r==="/"&&i[s+1]==="*"){for(s+=2;s<i.length&&!(i[s]==="*"&&i[s+1]==="/");)s++;s+=2;continue}n+=r,s++}return n}function Ys(i){let n="",t=!1,e=!1;for(let s=0;s<i.length;s++){let r=i[s];if(t){n+=r,e?e=!1:r==="\\"?e=!0:r==='"'&&(t=!1);continue}if(r==='"'){t=!0,n+=r;continue}if(r===","){let o=s+1;for(;o<i.length&&/\s/.test(i[o]);)o++;if(i[o]==="}"||i[o]==="]")continue}n+=r}return n}function qs(i){let n="",t=!1,e=!1,s="";for(let r=0;r<i.length;r++){let o=i[r];if(t){n+=o,e?e=!1:o==="\\"?e=!0:o==='"'&&(t=!1,s='"');continue}if(o==='"'){(/^["}\]]$/.test(s)||/[A-Za-z0-9]/.test(s))&&(n+=","),t=!0,n+=o;continue}n+=o,/\s/.test(o)||(s=o)}return n}function $(i){let n=Ys(Js(i)).trim();if(!n)return null;try{return JSON.parse(n)}catch{try{return JSON.parse(qs(n))}catch{return null}}}function Y(i){return JSON.stringify(i,null,2)}function M(i){return i.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"project"}function it(i){return i.replace(/[\\/:*?"<>|#^[\]]/g,"").replace(/\s+/g," ").trim()}function Xs(i,n){return i.length<=n?i:i.slice(0,n).trim()}var Zs=80;function Re(i){return it(Xs(i.trim(),Zs))||"Task"}function $e(i,n){if(!n(i))return i;let t=2;for(;n(`${i} ${t}`);)t++;return`${i} ${t}`}function w(i){return i==null?"":typeof i=="string"?i:typeof i=="number"||typeof i=="boolean"?String(i):Y(i)}var Qs=new Set(["text","list","number","checkbox","date","datetime"]);function _e(i){return typeof i=="string"&&Qs.has(i)}function be(i){return Y({"custom-fields":i.map(n=>({key:n.key,name:n.name,type:n.type,"default-value":O(n.type,n.defaultValue)}))})}function ze(i){if(!Array.isArray(i))return[];let n=[],t=new Set;for(let e of i){let s=e,r=typeof s?.name=="string"?s.name:"",o=typeof s?.key=="string"&&s.key.trim()?s.key.trim():M(r);!o||t.has(o)||(t.add(o),n.push({key:o,name:r||o,type:_e(s?.type)?s.type:"text",defaultValue:O(_e(s?.type)?s.type:"text",s?.["default-value"])}))}return n}function tn(i){let n=O(i.type,i.defaultValue);return n===null?void 0:n}function Ke(i){let n={};for(let t of i){let e=tn(t);e!==void 0&&(n[t.key]=e)}return n}function O(i,n){if(i==="checkbox")return n===!0||n==="true";if(n==null||n==="")return null;if(i==="list"){let t=Array.isArray(n)?n.map(w).filter(Boolean):[w(n)];return t.length?t:null}if(i==="number"){let t=typeof n=="number"?n:Number(w(n).trim());return Number.isFinite(t)?t:null}return w(n)}function en(i){if(i==="list")return[];if(i==="checkbox")return!1;if(i==="text")return null}function Te(i,n,t){for(let e of n){let s=O(e.type,t[e.key]),r=s===null?en(e.type):s;r===void 0?delete i[e.key]:i[e.key]=r}}function Ce(i){return i==null||i===""?"None":Array.isArray(i)?i.length?i.map(w).join(", "):"None":typeof i=="boolean"?i?"Yes":"No":w(i)}var sn=/^(#{1,6})\s+(.*?)\s*$/,nn=/^\s*(`{3,}|~{3,})/;function Nt(i){let n=nn.exec(i);return n?{char:n[1][0],length:n[1].length}:null}function Ge(i,n){return n.char===i.char&&n.length>=i.length}function rn(i){let n=0;for(let t of i.split(`
`)){let e=Nt(t);e?.char==="`"&&(n=Math.max(n,e.length))}return"`".repeat(Math.max(3,n+1))}function E(i){if(!i.startsWith("---"))return{frontmatter:"",body:i};let n=i.split(`
`);for(let t=1;t<n.length;t++)if(n[t].trim()==="---")return{frontmatter:n.slice(0,t+1).join(`
`),body:n.slice(t+1).join(`
`)};return{frontmatter:"",body:i}}function Ue(i){let n=i.split(`
`),t=[],e=null;for(let s=0;s<n.length;s++){let r=Nt(n[s]);if(r){e===null?e=r:Ge(e,r)&&(e=null);continue}if(e!==null)continue;let o=sn.exec(n[s]);if(!o)continue;let a=o[1].length;for(let l=t.length-1;l>=0;l--)t[l].end===-1&&t[l].level>=a&&(t[l].end=s);t.push({name:o[2].trim(),level:a,headingLine:s,start:s+1,end:-1})}for(let s of t)s.end===-1&&(s.end=n.length);return t}function ot(i,n,t=1){let e=n.trim().toLowerCase();return Ue(i).find(s=>s.level===t&&s.name.toLowerCase()===e)??null}function Se(i,n,t=1){let e=ot(i,n,t);return e?i.split(`
`).slice(e.start,e.end).join(`
`).trim():""}function We(i,n){for(let t=n.start;t<n.end;t++){let e=Nt(i[t]);if(e){for(let s=t+1;s<n.end;s++){let r=Nt(i[s]);if(r&&Ge(e,r))return{open:t,contentStart:t+1,contentEnd:s}}return null}}return null}function at(i,n){let t=ot(i,n);if(!t)return null;let e=i.split(`
`),s=We(e,t);return s?e.slice(s.contentStart,s.contentEnd).join(`
`):null}function lt(i,n,t,e="json"){let s=ot(i,n),r=i.split(`
`);if(s){let a=We(r,s);return a?(r.splice(a.contentStart,a.contentEnd-a.contentStart,...t.split(`
`)),r.join(`
`)):(r.splice(s.end,0,"```"+e,...t.split(`
`),"```"),r.join(`
`))}return`${i.replace(/\s+$/,"")}
# ${n}
\`\`\`${e}
${t}
\`\`\`
`}function j(i,n){let t=at(i,n);return t===null?Se(i,n):t}function q(i,n,t){let e=rn(n),s=`${e}${t}`;return n?[`# ${i}`,s,...n.split(`
`),e]:[`# ${i}`,s,e]}function ct(i,n,t,e){let[,...s]=q(n,t,e),r=ot(i,n);if(!r)return`${i.replace(/\s+$/,"")}
# ${n}
${s.join(`
`)}
`;let o=i.split(`
`);return o.splice(r.start,r.end-r.start,...s,""),o.join(`
`)}function Je(i,n,t=1){let e=ot(i,n,t);if(!e)return i;let s=i.split(`
`);return s.splice(e.headingLine,e.end-e.headingLine),s.join(`
`).replace(/\n{3,}/g,`
`)}function Pe(i,n,t){let e=ot(i,"Change Log");if(!e)return`${i.replace(/\s+$/,"")}
# Change Log
### ${n}
${t}
`;let s=i.split(`
`),r=Ue(i).find(a=>a.level===3&&a.name.trim()===n&&a.headingLine>e.headingLine&&a.headingLine<e.end);if(r){let a=r.end;for(;a>r.start&&s[a-1].trim()==="";)a--;return s.splice(a,0,t),s.join(`
`)}let o=e.end;for(;o>e.start&&s[o-1].trim()==="";)o--;return s.splice(o,0,`### ${n}`,t),s.join(`
`)}function X(i,n){return i.metadataCache.getFileCache(n)?.frontmatter??null}function D(i,n,t){return i.fileManager.processFrontMatter(n,t)}var Bt="Status Config",Ht="Label Config",wt="Board Config",Rt="Custom Fields",on={"task-name":!0,"task-status":!0,"task-labels":!0,"task-prioritized":!0,"task-created":!0,"task-modified":!0,"task-start":!0,"task-due":!0},an={prioritized:!0,title:!0,status:!0,labels:!0,start:!0,due:!0,created:!0,modified:!0};function $t(i,n,t,e){t!==null&&t.trim()&&!e&&i.push(`${n} is not valid JSON \u2014 falling back to defaults.`)}function ln(i,n){let t=at(i,Bt),e=$(t??"");$t(n,Bt,t,e);let s=e?.["status-options"];if(!s||typeof s!="object"){let o=R();return{statuses:o,order:Object.keys(o)}}let r={};for(let[o,a]of Object.entries(s))r[o]={name:a?.name??o,color:a?.color??"#6e7781",nextStatus:a?.["next-status"]??null,autoStatusChange:a?.["auto-status-change"]??a?.["auto-stauts-change"]??null,warnStart:a?.["warn-start"]===!0,warnDue:a?.["warn-due"]!==!1};return{statuses:r,order:Object.keys(r)}}function cn(i,n){let t=at(i,Ht),e=$(t??"");$t(n,Ht,t,e);let s=e?.["label-options"];if(!s||typeof s!="object")return{};let r={};for(let[o,a]of Object.entries(s))r[o]={name:a?.name??o,color:a?.color??"#6e7781"};return r}function dn(i,n){let t=at(i,Rt),e=$(t??"");return $t(n,Rt,t,e),ze(e?.["custom-fields"])}function un(i){let n=W();return i&&(Array.isArray(i.status)&&(n.status=i.status.map(String)),Array.isArray(i.labels)&&(n.labels=i.labels.map(String)),typeof i.prioritized=="boolean"&&(n.prioritized=i.prioritized),i.date&&typeof i.date=="object"&&i.date.field&&i.date.op&&(n.date={field:i.date.field,op:i.date.op,value:String(i.date.value??"")})),n}function pn(i,n){let t=i.id??M(i.name??`view-${n+1}`),e=i.type==="kanban"?"kanban":"table",s=(i.columns??[]).filter(o=>o in an),r=i.sort?.field;return{id:t,name:i.name??t,type:e,filters:un(i.filters),groupBy:rt(i["group-by"]),showDescription:typeof i["show-description"]=="boolean"?i["show-description"]:yt(e),sort:{field:r===null||r==="none"?null:r&&r in on?r:"task-created",dir:i.sort?.dir==="asc"?"asc":"desc"},columns:s.length?s:J()}}function fn(i,n){let t=at(i,wt),e=$(t??"");if($t(n,wt,t,e),!e)return It();let s=Array.isArray(e.views)?e.views.map(pn):[];s.length||s.push(...It().views);let r=e["default-view"];return{defaultView:s.some(o=>o.id===r)?r:s[0].id,openTasksInBoard:e["open-tasks-in-board"]!==!1,views:s}}function bt(i){let n={};for(let[t,e]of Object.entries(i))n[t]={name:e.name,color:e.color,"next-status":e.nextStatus,"auto-status-change":e.autoStatusChange,"warn-start":e.warnStart,"warn-due":e.warnDue};return Y({"status-options":n})}function Ye(i){return Y({"label-options":i})}function xe(i){return Y({"default-view":i.defaultView,"open-tasks-in-board":i.openTasksInBoard,views:i.views.map(n=>({id:n.id,name:n.name,type:n.type,filters:n.filters,"group-by":n.groupBy,"show-description":n.showDescription,sort:n.sort,columns:n.columns}))})}function qe(i,n,t){let e=X(i,n),s=n.parent;if(!e||!s)return null;let o=w(e["project-id"]).trim()||M(s.name),a=e["project-color"],l=e["project-icon"],{body:c}=E(t),d=[],{statuses:u,order:h}=ln(c,d);return{id:o,title:j(c,"Project Title").split(`
`)[0]?.trim()||s.name,description:j(c,"Description"),color:typeof a=="string"&&a.trim()?a.trim():kt,icon:typeof l=="string"&&l.trim()?l.trim():A,configFile:n,folder:s,tasksFolderPath:(0,At.normalizePath)(`${s.path}/Tasks`),statuses:u,statusOrder:h,labels:cn(c,d),customFields:dn(c,d),board:fn(c,d),configErrors:d}}async function Xe(i,n,t){await i.vault.process(n.configFile,e=>{let{frontmatter:s,body:r}=E(e),o=lt(r,wt,xe(t));return`${s}
${o}`})}async function Ze(i,n,t){await i.vault.process(n.configFile,e=>{let{frontmatter:s,body:r}=E(e),o=ct(r,"Project Title",t.title,"text");return o=ct(o,"Description",t.description,"md"),j(o,"Notes").trim()||(o=Je(o,"Notes")),o=lt(o,Bt,bt(t.statuses)),o=lt(o,Ht,Ye(t.labels)),o=lt(o,Rt,be(t.customFields)),o=lt(o,wt,xe(t.board)),`${s}
${o}`})}async function Qe(i,n,t){await D(i,n.configFile,e=>{e["project-color"]=t.color,e["project-icon"]=t.icon})}async function ts(i,n){let t=M(n.name),e=Object.keys(n.statuses).length?n.statuses:R(),s=["---","tags:",` - ${Mt}`,`project-id: ${JSON.stringify(t)}`,`project-color: ${JSON.stringify(n.color||kt)}`,`project-icon: ${JSON.stringify(n.icon||A)}`,"---",...q("Project Title",n.name.trim(),"text"),"",...q("Description",n.description.trim(),"md"),"",`# ${Bt}`,"```json",bt(e),"```","",`# ${Ht}`,"```json",Ye(He()),"```","",`# ${Rt}`,"```json",be([]),"```","",`# ${wt}`,"```json",xe(It()),"```",""].join(`
`),r=it(n.name)||"Project",o=(0,At.normalizePath)(`${n.folder.path}/${r} - Config.md`),a=await i.vault.create(o,s);return await i.vault.createFolder((0,At.normalizePath)(`${n.folder.path}/Tasks`)),{configFile:a,projectId:t}}var ss={defaultProjectsFolder:"",autoStatusChange:!0,repairProjectLinks:!0,openTaskAfterCreate:!1,replaceProjectPages:!0,showAdvancedStatuses:!1,projectOrder:[],statusTemplate:bt(R())};function ns(i){let n=$(i.statusTemplate);if(!n?.["status-options"])return R();let t={};for(let[e,s]of Object.entries(n["status-options"])){let r=s;t[e]={name:typeof r.name=="string"?r.name:e,color:typeof r.color=="string"?r.color:"#6e7781",nextStatus:typeof r["next-status"]=="string"?r["next-status"]:null,autoStatusChange:typeof r["auto-status-change"]=="string"?r["auto-status-change"]:null,warnStart:r["warn-start"]===!0,warnDue:r["warn-due"]!==!1}}return Object.keys(t).length?t:R()}var _t=class extends es.PluginSettingTab{constructor(t,e){super(t,e);this.plugin=e}setControlValue(t,e){return Object.assign(this.plugin.settings,{[t]:e}),this.plugin.saveSettings()}getSettingDefinitions(){return[{name:"Default folder for new projects",desc:"Pre-filled in the new project dialog. Leave blank for the vault root.",control:{type:"folder",key:"defaultProjectsFolder",placeholder:"Projects",includeRoot:!0}},{name:"Open new tasks in the editor",desc:"Off keeps you on the board after creating a task.",control:{type:"toggle",key:"openTaskAfterCreate"}},{name:"Replace existing project pages",desc:"Replace any open project page when opening another project.",control:{type:"toggle",key:"replaceProjectPages"}},{name:"Run timed status changes",desc:"Advance tasks to their next status once they have sat in a status longer than its auto-status-change duration.",aliases:["auto status change","schedule"],control:{type:"toggle",key:"autoStatusChange"}},{name:"Keep project links up to date",desc:"On startup, automatically repair broken project file references in tasks.",control:{type:"toggle",key:"repairProjectLinks"}},{type:"group",heading:"Leaflets",items:[{name:"Task column",desc:"Docks a panel listing one status of one project. Each panel keeps its own project, status and card settings, so the button opens another one every time.",render:t=>{t.addButton(e=>e.setButtonText("Open").setCta().onClick(()=>void this.plugin.openTaskColumn()))}},{name:"Projects browser",desc:"Docks the projects list in the sidebar. There is nothing to configure per panel, so this reveals the one that is already open rather than adding another.",render:t=>{t.addButton(e=>e.setButtonText("Open").setCta().onClick(()=>void this.plugin.openProjectsLeaflet()))}}]},{type:"group",heading:"Status template for new projects",cls:"pt-status-template",extraButtons:[t=>t.setIcon("rotate-ccw").setTooltip("Reset to defaults").onClick(()=>{this.setControlValue("statusTemplate",bt(R())).then(()=>this.update())})],items:[{name:"Template",desc:"JSON written into the status config section whenever a project is created.",control:{type:"textarea",key:"statusTemplate",rows:18,validate:t=>$(t)?void 0:"Not valid JSON."}}]}]}};var P=require("obsidian");var _=require("obsidian");function dt(){let i=new Date,n=t=>String(t).padStart(2,"0");return`${i.getFullYear()}-${n(i.getMonth()+1)}-${n(i.getDate())}T${n(i.getHours())}:${n(i.getMinutes())}:${n(i.getSeconds())}`}function zt(){return dt().slice(0,10)}function v(i){if(!i)return null;let n=/^(\d{4})-(\d{2})-(\d{2})$/.exec(i.trim()),t=n?new Date(Number(n[1]),Number(n[2])-1,Number(n[3])):new Date(i);return isNaN(t.getTime())?null:t}function ut(i){if(!i)return null;let n=/^\s*(\d+(?:\.\d+)?)\s*([hdwmy])\s*$/i.exec(i);if(!n)return null;let t=parseFloat(n[1]),e=36e5,s={h:e,d:e*24,w:e*24*7,m:e*24*30,y:e*24*365};return t*s[n[2].toLowerCase()]}function Tt(i){let n=v(i);return n?`${(e=>String(e).padStart(2,"0"))(n.getDate())} ${n.toLocaleString(void 0,{month:"short"})} ${n.getFullYear()}`:""}function rs(i){let n=v(i);return n?new Date(n.getFullYear(),n.getMonth(),n.getDate(),23,59,59).getTime()<Date.now():!1}var hn=/[#[\]`*_~|<>]/;function L(i){let n=i.replace(/\s+/g," ").trim();if(!n)return"None";if(!hn.test(n))return n;let t=n.match(/`+/g)??[],e="`".repeat(Math.max(...t.map(r=>r.length),0)+1),s=n.startsWith("`")||n.endsWith("`")?" ":"";return`${e}${s}${n}${s}${e}`}var Ee="project-file",Kt="task-parent";function is(i,n,t){return`[[${i.metadataCache.fileToLinktext(n,t)}]]`}function os(i,n,t){if(typeof n!="string")return null;let e=/^\s*\[\[([^\]|#]+)/.exec(n)?.[1]?.trim();return e?i.metadataCache.getFirstLinkpathDest(e,t):null}function as(i,n,t){if(!n)return"";let e=i.vault.getAbstractFileByPath(n);return e instanceof _.TFile?is(i,e,t):""}var Gt="md";function ls(i,n,t){return is(i,n.configFile,t)}async function cs(i,n,t){let e=X(i,t.file)?.[Ee];return typeof e=="string"&&mn(i,e,t.file.path,n.configFile)?!1:(await D(i,t.file,s=>{s[Ee]=ls(i,n,t.file.path)}),!0)}function mn(i,n,t,e){return os(i,n,t)?.path===e.path}function B(i){if(i==null)return null;if(i instanceof Date)return i.toISOString().slice(0,19);let n=w(i).trim();return n.length?n:null}function gn(i){return Array.isArray(i)?i.map(n=>w(n).trim()).filter(Boolean):typeof i=="string"?i.split(",").map(n=>n.trim()).filter(Boolean):[]}function V(i){return JSON.stringify(i)}function vn(i){let n={};for(let[t,e]of Object.entries(i))Vt.has(t)||(n[t]=e);return n}function yn(i){let n=j(i,"Description");for(let t of n.split(`
`)){let e=t.trim().replace(/^['"`]|['"`]$/g,"");if(e&&!e.startsWith("#"))return e}return""}function ds(i,n,t){let e=X(i,n);if(!e)return null;let s=B(e["project-id"]);if(!s)return null;let{body:r}=E(t);return{file:n,projectId:s,name:B(e["task-name"])??n.basename,status:B(e["task-status"])??"",prioritized:e["task-prioritized"]===!0,labels:gn(e["task-labels"]),parentPath:os(i,e[Kt],n.path)?.path??null,start:B(e["task-start"]),due:B(e["task-due"]),created:B(e["task-created"]),modified:B(e["task-modified"]),statusModified:B(e["task-status-modified"])??B(e["task-modified"]),descriptionSnippet:yn(r),custom:vn(e)}}function kn(i,n,t){let e=$e(Re(t),s=>!!i.vault.getAbstractFileByPath((0,_.normalizePath)(`${n}/${s}.md`)));return(0,_.normalizePath)(`${n}/${e}.md`)}async function Ct(i,n,t){let e=(0,_.normalizePath)(n.tasksFolderPath);i.vault.getAbstractFileByPath(e)||await i.vault.createFolder(e);let s=dt(),r=n.statuses[t.status]?t.status:n.statusOrder[0]??"",o=n.statuses[r]?.name??r,a=kn(i,e,t.name),l=["---","tags:",` - ${Ot}`,`project-id: ${V(n.id)}`,`${Ee}: ${V(ls(i,n,a))}`,`task-name: ${V(t.name.trim())}`,`task-status: ${V(r)}`,`task-prioritized: ${t.prioritized}`,t.labels.length?`task-labels:
${t.labels.map(u=>` - ${u}`).join(`
`)}`:"task-labels: []",`${Kt}: ${V(as(i,t.parent,a))}`,`task-start: ${t.start?V(t.start):""}`,`task-due: ${t.due?V(t.due):""}`,`task-created: ${V(s)}`,`task-modified: ${V(s)}`,`task-status-modified: ${V(s)}`,"---"].join(`
`),c=[...q("Description",t.description.trim(),Gt),"",...q("Notes","",Gt),"","# Change Log",`### ${zt()}`,`Created with status: ${L(o)}`,""].join(`
`),d=await i.vault.create(a,`${l}
${c}`);return n.customFields.length&&await D(i,d,u=>{Te(u,n.customFields,t.custom)}),d}async function wn(i,n){await D(i,n,t=>{t["task-modified"]=dt()})}async function Z(i,n,t,e){if(t.status===e)return;let s=o=>L(n.statuses[o]?.name??(o||"None")),r=dt();await D(i,t.file,o=>{o["task-status"]=e,o["task-modified"]=r,o["task-status-modified"]=r}),await i.vault.process(t.file,o=>{let{frontmatter:a,body:l}=E(o),c=`Status: ${s(t.status)} > ${s(e)}`,d=Pe(l,zt(),c);return`${a}
${d}`})}async function us(i,n,t){await D(i,n.file,e=>{e["task-prioritized"]=t}),await wn(i,n.file)}function bn(i,n,t){let e=l=>L(i.statuses[l]?.name??l??"None"),s=l=>l.length?l.map(c=>L(i.labels[c]?.name??c)).join(", "):"None",r=[],o=t.name.trim();if(o!==n.name&&r.push(`Title: ${L(n.name)} > ${L(o)}`),t.status!==n.status&&r.push(`Status: ${e(n.status)} > ${e(t.status)}`),t.prioritized!==n.prioritized){let l=c=>c?"Prioritized":"Normal";r.push(`Priority: ${l(n.prioritized)} > ${l(t.prioritized)}`)}if((t.parent??"")!==(n.parentPath??"")){let l=c=>L(c?(c.split("/").pop()??c).replace(/\.md$/,""):"None");r.push(`Parent: ${l(n.parentPath)} > ${l(t.parent)}`)}let a=l=>Tt(l)||"None";(t.start??"")!==(n.start??"")&&r.push(`Start: ${a(n.start)} > ${a(t.start)}`),(t.due??"")!==(n.due??"")&&r.push(`Due: ${a(n.due)} > ${a(t.due)}`),[...t.labels].sort().join(",")!==[...n.labels].sort().join(",")&&r.push(`Labels: ${s(n.labels)} > ${s(t.labels)}`);for(let l of i.customFields){let c=L(Ce(n.custom[l.key])),d=L(Ce(O(l.type,t.custom[l.key])));c!==d&&r.push(`${L(l.name)}: ${c} > ${d}`)}return r}async function ps(i,n,t,e){let s=await i.vault.read(t.file),{body:r}=E(s),o=e.description.trim(),a=e.notes.trim(),l=o!==j(r,"Description").trim(),c=a!==j(r,"Notes").trim(),d=bn(n,t,e);if(l&&d.push("Description updated"),c&&d.push("Notes updated"),!d.length)return{entries:d,descriptionChanged:l,notesChanged:c};let u=e.status!==t.status,h=dt();return await D(i,t.file,p=>{p["task-name"]=e.name.trim(),p["task-status"]=e.status,p["task-prioritized"]=e.prioritized,p["task-labels"]=e.labels;let f=as(i,e.parent,t.file.path);f?p[Kt]=f:delete p[Kt],p["task-start"]=e.start??"",p["task-due"]=e.due??"",Te(p,n.customFields,e.custom),p["task-modified"]=h,u&&(p["task-status-modified"]=h)}),await i.vault.process(t.file,p=>{let{frontmatter:f,body:b}=E(p),x=b;l&&(x=ct(x,"Description",o,Gt)),c&&(x=ct(x,"Notes",a,Gt));let ke=zt();for(let Rs of d)x=Pe(x,ke,Rs);return`${f}
${x}`}),{entries:d,descriptionChanged:l,notesChanged:c}}function fs(i,n){let e=i.statuses[n.status]?.nextStatus;if(!e||e===n.status)return null;let s=i.statuses[e];return s?{key:e,option:s}:(new _.Notice(`Status "${e}" is not defined in this project.`),null)}function Tn(i){return new Set(i.map(n=>n.replace(/^#/,"").toLowerCase()))}function Cn(i){return`${i}${Ae}`}function hs(i){let n=Tn(i);if(n.has(Be.toLowerCase()))return null;let t=e=>n.has(e.toLowerCase())&&!n.has(Cn(e).toLowerCase());return t(Mt)?"project":t(Ot)?"task":null}function Ut(i,n,t){return i?i===n?t:i.startsWith(`${n}/`)?t+i.slice(n.length):null:null}function ms(i){return i?hs((0,P.parseFrontMatterTags)(i.frontmatter)??[]):null}var Wt=class{constructor(n,t){this.app=n;this.plugin=t}projects=new Map;tasks=new Map;listeners=new Set;indexed=!1;movedFiles=new Set;movedFolders=new Set;notify=(0,P.debounce)(()=>{for(let n of this.listeners)n()},80,!0);settle=(0,P.debounce)(()=>void this.reconcile(),50,!0);get ready(){return this.indexed}onChange(n){return this.listeners.add(n),()=>this.listeners.delete(n)}registerEvents(){let{app:n,plugin:t}=this;t.registerEvent(n.metadataCache.on("changed",(e,s,r)=>{this.ingest(e,s,r)&&this.notify()})),t.registerEvent(n.vault.on("delete",e=>{(this.projects.delete(e.path)||this.tasks.delete(e.path))&&this.notify()})),t.registerEvent(n.vault.on("rename",(e,s)=>{this.forget(s,e.path),e instanceof P.TFolder?this.movedFolders.add(e.path):this.movedFiles.add(e.path),this.settle()}))}forget(n,t){for(let e of[this.projects,this.tasks])for(let s of[...e.keys()]){let r=Ut(s,n,t);r&&(e.delete(s),this.movedFiles.add(r))}}async reconcile(){let n=[...this.movedFiles],t=[...this.movedFolders];this.movedFiles.clear(),this.movedFolders.clear();let e=new Map;for(let r of n){let o=this.app.vault.getAbstractFileByPath(r);o instanceof P.TFile&&e.set(o.path,o)}for(let r of t){let o=this.app.vault.getAbstractFileByPath(r);if(o instanceof P.TFolder)for(let a of Sn(o))e.set(a.path,a)}((await Promise.all([...e.values()].map(r=>this.reindexFile(r)))).length||n.length||t.length)&&this.notify()}async reindexAll(){this.projects.clear(),this.tasks.clear(),await Promise.all(this.app.vault.getMarkdownFiles().map(n=>this.reindexFile(n))),this.indexed=!0,this.notify()}async reindexFile(n){let t=this.app.metadataCache.getFileCache(n);return ms(t)===null?this.projects.delete(n.path)||this.tasks.delete(n.path):this.ingest(n,await this.app.vault.cachedRead(n),t)}ingest(n,t,e){let s=ms(e);if(s==="project"){let r=qe(this.app,n,t);if(r)return this.projects.set(n.path,r),!0}else if(s==="task"){let r=ds(this.app,n,t);if(r)return this.tasks.set(n.path,r),!0}return this.projects.delete(n.path)||this.tasks.delete(n.path)}getProjects(){return[...this.projects.values()].sort((n,t)=>n.title.localeCompare(t.title))}getProjectByConfigPath(n){return this.projects.get(n)??null}getProjectById(n){return this.getProjects().find(t=>t.id===n)??null}getProjectForFile(n){let t=null;for(let e of this.projects.values()){let s=`${e.folder.path}/`;(n.path.startsWith(s)||n.path===e.configFile.path)&&(!t||e.folder.path.length>t.folder.path.length)&&(t=e)}return t}getTasks(n){return[...this.tasks.values()].filter(t=>t.projectId===n)}getTaskByPath(n){return this.tasks.get(n)??null}getChildTasks(n){return[...this.tasks.values()].filter(t=>t.parentPath===n)}getAllTasks(){return[...this.tasks.values()]}};function Sn(i){let n=[],t=e=>{for(let s of e.children)s instanceof P.TFolder?t(s):s instanceof P.TFile&&s.extension==="md"&&n.push(s)};return t(i),n}var y=require("obsidian");function Pn(i,n){switch(n){case"task-created":return v(i.created);case"task-modified":return v(i.modified);case"task-start":return v(i.start);case"task-due":return v(i.due);case"task-status-modified":return v(i.statusModified)}}function xn(i,n){let t=Pn(i,n.field);if(!t)return!1;if(n.op==="within-last"||n.op==="older-than"){let s=ut(n.value);if(s==null)return!0;let r=Date.now()-s;return n.op==="within-last"?t.getTime()>=r:t.getTime()<r}let e=v(n.value);return e?n.op==="before"?t.getTime()<e.getTime():t.getTime()>e.getTime():!0}function Jt(i,n,t=""){let e=t.trim().toLowerCase();return i.filter(s=>!(n.status.length&&!n.status.includes(s.status)||n.labels.length&&!n.labels.some(r=>s.labels.includes(r))||n.prioritized!==null&&s.prioritized!==n.prioritized||n.date&&!xn(s,n.date)||e&&!`${s.name} ${s.descriptionSnippet} ${s.labels.join(" ")}`.toLowerCase().includes(e)))}function gs(i,n){let t=new Map(i.map(s=>[s.file.path,s])),e=s=>{let r=new Set,o=s;for(;o&&!r.has(o.file.path);){if(r.add(o.file.path),o.parentPath===n.file.path)return!0;o=o.parentPath?t.get(o.parentPath):void 0}return!1};return i.filter(s=>s.file.path!==n.file.path&&!e(s))}function Yt(i,n){return n.length?i.filter(t=>n.includes(t)):[...i]}function qt(i,n,t){if(n.field===null)return[...i].sort((o,a)=>{let l=v(o.created)?.getTime()??0;return(v(a.created)?.getTime()??0)-l||o.name.localeCompare(a.name)});let e=n.dir==="asc"?1:-1,s=n.field,r=o=>{switch(s){case"task-name":return o.name.toLowerCase();case"task-status":{let a=t.indexOf(o.status);return a===-1?t.length:a}case"task-labels":return o.labels.length?[...o.labels].sort().join(", ").toLowerCase():"\uFFFF";case"task-prioritized":return o.prioritized?0:1;case"task-start":return v(o.start)?.getTime()??Number.POSITIVE_INFINITY;case"task-due":return v(o.due)?.getTime()??Number.POSITIVE_INFINITY;case"task-modified":return v(o.modified)?.getTime()??0;case"task-created":return v(o.created)?.getTime()??0}};return[...i].sort((o,a)=>{let l=r(o),c=r(a);return l<c?-1*e:l>c?1*e:o.name.localeCompare(a.name)})}var T=require("obsidian");var vs=require("obsidian"),m=class{el;component;constructor(n,t={}){this.component=new vs.ButtonComponent(n),this.el=this.component.buttonEl,this.el.setAttr("type","button"),t.class!==void 0&&this.el.addClass(t.class),t.text!==void 0&&this.setText(t.text),t.icon!==void 0&&this.setIcon(t.icon),this.setVariant(t.variant??"normal"),t.tooltip!==void 0&&this.setTooltip(t.tooltip),t.disabled!==void 0&&this.setDisabled(t.disabled),t.onClick&&this.onClick(t.onClick)}setText(n){return this.component.setButtonText(n),this}setIcon(n){return this.component.setIcon(n),this}setVariant(n){return this.component.removeCta(),this.component.removeDestructive(),n==="cta"&&this.component.setCta(),n==="warning"&&this.component.setDestructive(),this}setTooltip(n){return this.component.setTooltip(n),this}setDisabled(n){return this.component.setDisabled(n),this}onClick(n){return this.component.onClick(n),this}};var pt=class{constructor(n){this.move=n}from=null;attach(n,t,e){t.draggable=!0,t.addEventListener("dragstart",s=>{this.from=e,s.dataTransfer?.setData("text/plain",String(e)),s.dataTransfer&&(s.dataTransfer.effectAllowed="move"),s.dataTransfer?.setDragImage(n,12,n.clientHeight/2),window.requestAnimationFrame(()=>{this.from===e&&n.addClass("is-dragging")})}),t.addEventListener("dragend",()=>{this.from=null,n.removeClass("is-dragging")}),n.addEventListener("dragover",s=>{this.from===null||this.from===e||(s.preventDefault(),s.dataTransfer&&(s.dataTransfer.dropEffect="move"),n.addClass("is-drop-target"))}),n.addEventListener("dragleave",s=>{n.contains(s.relatedTarget)||n.removeClass("is-drop-target")}),n.addEventListener("drop",s=>{s.preventDefault(),n.removeClass("is-drop-target");let r=this.from;this.from=null,!(r===null||r===e)&&this.move(r,e)})}};var Q=require("obsidian");var k=class extends Q.Modal{content;subHeaderEl;actionsEl=null;leftEl=null;rightEl=null;constructor(n,t={}){super(n),this.modalEl.addClass("mod-scrollable-content","pt-modal"),Q.Platform.isPhone&&this.modalEl.addClass("mod-lg"),t.width&&!Q.Platform.isPhone&&this.modalEl.style.setProperty("--dialog-width",t.width),t.accent&&(this.modalEl.addClass("pt-modal-accent"),this.modalEl.style.setProperty("--pt-project-color",t.accent));let e=this.titleEl.parentElement??this.modalEl;this.subHeaderEl=e.createDiv({cls:"pt-modal-subheader"}),Q.Platform.isMobile&&this.modalEl.querySelector(":scope > .modal-header-button")?.removeClass("mod-raised"),this.content=this.contentEl,t.header!==void 0&&this.setHeader(t.header),t.subHeader!==void 0&&this.setSubHeader(t.subHeader)}get actionsLeft(){return this.leftEl??=this.actions().createDiv({cls:"mod-secondary pt-modal-actions"}),this.leftEl}get actionsRight(){return this.rightEl??=this.actions().createDiv({cls:"pt-modal-actions"}),this.rightEl}setPrimaryAction(n){return new m(this.actionsRight,{text:n.text,variant:"cta",disabled:n.disabled,onClick:n.onClick})}addCancelAction(n="Cancel"){new m(this.actionsRight,{text:n,onClick:()=>this.close()})}focusOnOpen(n){Q.Platform.isMobile||window.setTimeout(()=>n.focus(),0)}setHeader(n){return this.titleEl.setText(n),this}setSubHeader(n){return this.subHeaderEl.setText(n),this}onClose(){this.contentEl.empty()}actions(){return this.actionsEl??=this.modalEl.createDiv({cls:"modal-button-container"}),this.actionsEl}};function g(i){return i.settingEl.addClass("pt-item-stacked"),i}function Xt(i){return i.settingEl.addClass("pt-item-has-footer"),i.settingEl.createDiv({cls:"pt-item-footer"})}var En={"task-created":"Created","task-modified":"Modified","task-start":"Start","task-due":"Due","task-status-modified":"Status changed"},jn={"within-last":"within the last","older-than":"older than",before:"before",after:"after"},Dn={"task-name":"Title","task-status":"Status","task-labels":"Labels","task-prioritized":"Priority","task-created":"Created date","task-modified":"Modified date","task-start":"Start date","task-due":"Due date"},je={prioritized:"Prioritized",title:"Title",status:"Status",labels:"Labels",start:"Start",due:"Due",created:"Created",modified:"Modified"};function Ln(i){return{...i,filters:{...i.filters,status:[...i.filters.status],labels:[...i.filters.labels],date:i.filters.date?{...i.filters.date}:null},sort:{...i.sort},columns:[...i.columns]}}var Zt=class extends k{constructor(t,e,s,r,o=null){super(t,{header:s===null?"New View":"Configure View",subHeader:e.title,accent:e.color});this.project=e;this.onSave=r;this.onDelete=o;this.isNew=s===null,this.draft=s?Ln(s):{id:`view-${Date.now().toString(36)}`,name:"",type:"table",filters:W(),groupBy:"none",showDescription:yt("table"),sort:{field:"task-created",dir:"desc"},columns:J()}}draft;isNew;bodyEl;onOpen(){this.bodyEl=this.content.createDiv(),this.onDelete&&new m(this.actionsLeft,{text:"Delete view",variant:"warning",onClick:()=>{this.onDelete?.(),this.close()}}),this.addCancelAction(),this.setPrimaryAction({text:this.isNew?"Create view":"Save",onClick:()=>this.submit()}),this.renderBody()}renderBody(){let t=this.content.scrollTop;this.bodyEl.empty(),new T.SettingGroup(this.bodyEl).setHeading("General").addSetting(s=>{g(s).setName("Name").addText(r=>r.setPlaceholder("Backlog").setValue(this.draft.name).onChange(o=>{this.draft.name=o}))}).addSetting(s=>{s.setName("Layout").addDropdown(r=>r.addOptions({table:"Table",kanban:"Board"}).setValue(this.draft.type).onChange(o=>{this.draft.type=o==="kanban"?"kanban":"table",this.isNew&&(this.draft.showDescription=yt(this.draft.type)),this.renderBody()}))}).addSetting(s=>{s.setName("Sort by").setDesc("A table's column headers override this until the view is reopened.").addDropdown(r=>r.addOptions({none:"None",...Dn}).setValue(this.draft.sort.field??"none").onChange(o=>{this.draft.sort.field=o==="none"?null:o})).addDropdown(r=>r.addOptions({desc:"Descending",asc:"Ascending"}).setValue(this.draft.sort.dir).onChange(o=>{this.draft.sort.dir=o==="asc"?"asc":"desc"}))}).addSetting(s=>{s.setName("Show description").setDesc(this.draft.type==="kanban"?"The first line of the task's description, under its name on the card.":"The first line of the task's description, under the task name in the same cell rather than as its own column.").addToggle(r=>r.setValue(this.draft.showDescription).onChange(o=>{this.draft.showDescription=o}))}),this.renderFilters(new T.SettingGroup(this.bodyEl).setHeading("Filters")),this.draft.type==="table"&&new T.SettingGroup(this.bodyEl).setHeading("Table Layout").addSetting(s=>{s.setName("Group by").addDropdown(r=>r.addOptions({none:"Nothing",status:"Status",label:"Label"}).setValue(this.draft.groupBy).onChange(o=>{this.draft.groupBy=rt(o)}))}).addSetting(s=>{g(s).setName("Columns").setDesc("Ticked columns are shown, top to bottom as left to right. Drag to reorder."),this.renderColumnList(s.controlEl)}),this.content.scrollTop=t}renderFilters(t){let e;t.addSetting(d=>{g(d).setName("Statuses").setDesc("Selected statuses are shown, and become the board's columns. Nothing selected means every status."),e=d.controlEl});for(let d of this.project.statusOrder){let u=this.project.statuses[d],h=new m(e,{text:u.name,variant:this.draft.filters.status.includes(d)?"cta":"normal",onClick:()=>{let p=this.draft.filters.status.indexOf(d);p===-1?this.draft.filters.status.push(d):this.draft.filters.status.splice(p,1),h.setVariant(p===-1?"cta":"normal")}})}let s=Object.keys(this.project.labels);if(s.length){let d;t.addSetting(u=>{g(u).setName("Labels").setDesc("Matches tasks carrying any of these."),d=u.controlEl});for(let u of s){let h=this.project.labels[u],p=new m(d,{text:h.name,variant:this.draft.filters.labels.includes(u)?"cta":"normal",onClick:()=>{let f=this.draft.filters.labels.indexOf(u);f===-1?this.draft.filters.labels.push(u):this.draft.filters.labels.splice(f,1),p.setVariant(f===-1?"cta":"normal")}})}}t.addSetting(d=>{d.setName("Prioritized").addDropdown(u=>u.addOptions({any:"Any",yes:"Prioritized only",no:"Not prioritized"}).setValue(this.draft.filters.prioritized===null?"any":this.draft.filters.prioritized?"yes":"no").onChange(h=>{this.draft.filters.prioritized=h==="any"?null:h==="yes"}))}).addSetting(d=>{d.setName("Date filter").addToggle(u=>u.setValue(this.draft.filters.date!==null).onChange(h=>{this.draft.filters.date=h?{field:"task-created",op:"within-last",value:"30d"}:null,this.renderBody()}))});let r=this.draft.filters.date;if(!r)return;let o=t.listEl.createDiv({cls:"pt-config-block pt-date-filter"}),a=r.op==="within-last"||r.op==="older-than";a&&o.createDiv({cls:"pt-modal-status",text:"Durations use h, d, w, m or y \u2014 for example 30d or 2w."});let l=o.createDiv({cls:"pt-date-filter-controls"});new T.DropdownComponent(l).addOptions(En).setValue(r.field).onChange(d=>{r.field=d}),new T.DropdownComponent(l).addOptions(jn).setValue(r.op).onChange(d=>{let u=r.op;r.op=d;let h=u==="within-last"||u==="older-than",p=r.op==="within-last"||r.op==="older-than";h!==p&&(r.value=p?"30d":""),this.renderBody()});let c=new T.TextComponent(l);a||(c.inputEl.type="date"),c.setPlaceholder(a?"30d":"").setValue(r.value).onChange(d=>{r.value=d})}renderColumnList(t){let e=this.draft.columns,s=Object.keys(je).filter(a=>!e.includes(a)),r=t.createDiv({cls:"pt-column-list"}),o=new pt((a,l)=>{let[c]=this.draft.columns.splice(a,1);this.draft.columns.splice(l,0,c),this.renderBody()});e.forEach((a,l)=>{let c=this.renderColumnRow(r,a,!0);o.attach(c,c,l)}),e.length||r.createDiv({cls:"pt-modal-status",text:"No columns shown."});for(let a of s)this.renderColumnRow(r,a,!1)}renderColumnRow(t,e,s){let r=t.createDiv({cls:"pt-column-row"});r.toggleClass("is-shown",s);let o=r.createSpan({cls:"pt-column-grip"});s&&(0,T.setIcon)(o,"grip-vertical");let a=r.createEl("input",{attr:{type:"checkbox","aria-label":je[e]}});return a.checked=s,a.addEventListener("change",()=>{a.checked?this.draft.columns.push(e):this.draft.columns.splice(this.draft.columns.indexOf(e),1),this.renderBody()}),r.createSpan({text:je[e]}),r}submit(){let t=this.draft.name.trim();if(!t){new T.Notice("Give the view a name.");return}if(this.draft.type==="table"&&!this.draft.columns.length){new T.Notice("Pick at least one column.");return}this.draft.name=t,this.isNew&&(this.draft.id=`${M(t)}-${this.draft.id.split("-").pop()}`),this.onSave(this.draft),this.close()}};var St=require("obsidian");var H=require("obsidian");var Fn={score:0,matches:[]},Mn=/^\[\[([^\]]+)\]\]$/,De={text:"text",list:"multitext",number:"number",checkbox:"checkbox",date:"date",datetime:"datetime"},On={text:"align-left",list:"list",number:"binary",checkbox:"check-square",date:"calendar",datetime:"clock"},te=class extends H.AbstractInputSuggest{constructor(t,e,s){super(t,e);this.field=e;this.onCommit=s;this.limit=20}caret(){return ks(this.field)}token(){let e=(this.field.textContent??"").slice(0,this.caret()),s=e.lastIndexOf("[["),r=s===-1?"":e.slice(s+2);if(s!==-1&&!r.includes("]]")&&!r.includes(`
`)){let o=r.indexOf("#");if(o===-1)return{start:s,query:r,kind:"file",path:""};let a=r.slice(0,o).trim();if(a&&this.app.metadataCache.getFirstLinkpathDest(a,""))return{start:s,query:r.slice(o+1),kind:"heading",path:a}}return null}getSuggestions(t){let e=this.token();if(!e)return[];let s=(0,H.prepareFuzzySearch)(e.query),r=a=>e.query?s(a):Fn,o=[];if(e.kind==="heading")for(let a of this.headings(e.path)){let l=r(a.heading);l&&o.push({insert:`[[${e.path}#${a.heading}]]`,display:a.heading,note:e.path,result:l})}else if(e.kind==="file")for(let a of this.app.vault.getMarkdownFiles()){let l=this.app.metadataCache.fileToLinktext(a,"",!0),c=a.parent?.path??"",d=c&&c!=="/"?`${c}/`:"",u=r(l);u&&o.push({insert:`[[${l}]]`,display:l,note:d,result:u});for(let h of this.aliases(a)){let p=r(h);p&&o.push({insert:`[[${h}]]`,display:h,note:`${d}${l}`,result:p})}}return o.sort((a,l)=>l.result.score-a.result.score),o.slice(0,this.limit||o.length)}headings(t){if(!t)return[];let e=this.app.metadataCache.getFirstLinkpathDest(t,"");return e?this.app.metadataCache.getFileCache(e)?.headings??[]:[]}aliases(t){let e=X(this.app,t)?.aliases;return typeof e=="string"?e.trim()?[e.trim()]:[]:Array.isArray(e)?e.map(s=>w(s).trim()).filter(Boolean):[]}renderSuggestion(t,e){e.addClass("mod-complex");let s=e.createDiv({cls:"suggestion-content"});(0,H.renderResults)(s.createDiv({cls:"suggestion-title"}),t.display,t.result),t.note&&s.createDiv({cls:"suggestion-note",text:t.note})}selectSuggestion(t){let e=this.token();if(!e)return;let s=this.field.textContent??"",r=s.slice(this.caret());t.insert.endsWith("]]")&&r.startsWith("]]")&&(r=r.slice(2)),this.field.setText(s.slice(0,e.start)+t.insert+r),Le(this.field,e.start+t.insert.length),this.onCommit(),this.close()}};function ks(i){let n=activeWindow.getSelection();if(!n?.focusNode||!i.contains(n.focusNode))return i.textContent?.length??0;let t=n.getRangeAt(0).cloneRange();return t.selectNodeContents(i),t.setEnd(n.focusNode,n.focusOffset),t.toString().length}function ys(i){Le(i,i.textContent?.length??0)}function Le(i,n){let t=activeDocument.createRange(),e=i.firstChild;e&&e.nodeType===Node.TEXT_NODE?(t.setStart(e,Math.min(n,e.textContent?.length??0)),t.collapse(!0)):(t.selectNodeContents(i),t.collapse(!1));let s=activeWindow.getSelection();s?.removeAllRanges(),s?.addRange(t)}function ws(i,n){i.addEventListener("input",()=>{let t=i.textContent??"",e=ks(i);t.slice(0,e).endsWith("[[")&&(t.slice(e).startsWith("]]")||(i.setText(`${t.slice(0,e)}]]${t.slice(e)}`),Le(i,e),n()))})}function Qt(i){return Array.isArray(i)?i.map(String).filter(Boolean):typeof i=="string"&&i.trim()?[i.trim()]:[]}function Vn(i,n){let t=Mn.exec(n);if(!t){i.setText(n);return}let[e,s]=t[1].split("|");i.createEl("a",{cls:"internal-link",text:s??e,attr:{href:e,"data-href":e}})}function In(i,n,t,e){let s=n.createDiv({cls:"metadata-input-longtext mod-truncate",attr:{contenteditable:"true",tabindex:"0","data-placeholder":e}});s.setText(w(t.get()));let r=()=>t.set(s.textContent??"");s.addEventListener("input",r),s.addEventListener("blur",r),new te(i,s,r),ws(s,r)}function Nn(i,n,t,e){let s=n.createDiv({cls:"multi-select-container"}),r=s.createDiv({cls:"multi-select-input",attr:{contenteditable:"true",tabindex:"0","data-placeholder":e}}),o=()=>{for(let l of Array.from(s.querySelectorAll(".multi-select-pill")))l.remove();Qt(t.get()).forEach((l,c)=>{let d=s.createDiv({cls:"multi-select-pill"});Vn(d.createDiv({cls:"multi-select-pill-content"}),l);let u=d.createDiv({cls:"multi-select-pill-remove-button",attr:{"aria-label":`Remove ${l}`}});(0,H.setIcon)(u,"x"),u.addEventListener("mousedown",h=>{h.preventDefault();let p=Qt(t.get());p.splice(c,1),t.set(p),o()}),s.insertBefore(d,r)})},a=()=>{let l=(r.textContent??"").trim();r.setText(""),l&&(t.set([...Qt(t.get()),l]),o())};new te(i,r,()=>{}),ws(r,()=>{}),r.addEventListener("keydown",l=>{if(l.key==="Enter"){if(l.isComposing||l.defaultPrevented)return;l.preventDefault(),a();return}if(l.key==="Backspace"&&!(r.textContent??"").length){let c=Qt(t.get()),d=c.pop();if(d===void 0)return;l.preventDefault(),t.set(c),o(),r.setText(d),ys(r)}}),r.addEventListener("blur",a),s.addEventListener("mousedown",l=>{l.target===s&&(l.preventDefault(),r.focus(),ys(r))}),o()}function An(i,n,t,e){if(n==="checkbox"){let r=i.createEl("input",{cls:"metadata-input-checkbox",attr:{type:"checkbox"}});r.checked=t.get()===!0,r.addEventListener("change",()=>t.set(r.checked));return}let s=i.createEl("input",{cls:`metadata-input metadata-input-${n==="number"?"number":"text"}`,attr:{type:n==="number"?"number":n==="date"?"date":"datetime-local",placeholder:e}});s.value=w(t.get()),s.addEventListener("input",()=>t.set(s.value))}function Bn(i,n){return i.createDiv({cls:"metadata-property-value",attr:{"data-property-type":De[n]}})}function Fe(i,n,t,e,s=""){t==="list"?Nn(i,n,e,s):t==="text"?In(i,n,e,s):An(n,t,e,s)}function Hn(i,n){let t=i.createDiv({cls:"metadata-property-key"}),e=t.createSpan({cls:"metadata-property-icon",attr:{"aria-label":n.type,"data-property-type":De[n.type]}});(0,H.setIcon)(e,On[n.type]);let s=t.createEl("input",{cls:"metadata-property-key-input",attr:{type:"text",readonly:"true",tabindex:"-1"}});s.value=n.name}function ee(i,n,t,e){if(!t.length)return;let s=n.createDiv({cls:"metadata-container pt-properties"}).createDiv({cls:"metadata-content"});for(let r of t){let o=s.createDiv({cls:"metadata-property",attr:{"data-property-key":r.key,"data-property-type":De[r.type]}});Hn(o,r),Fe(i,Bn(o,r.type),r.type,{get:()=>e[r.key],set:a=>{e[r.key]=a}})}}var bs=require("obsidian"),ft=class extends bs.SuggestModal{constructor(t,e,s){super(t);this.tasks=e;this.onChoose=s;this.setPlaceholder("Search tasks\u2026")}getSuggestions(t){let e=t.toLowerCase();return this.tasks.filter(s=>s.name.toLowerCase().includes(e))}renderSuggestion(t,e){e.createDiv({text:t.name}),e.createEl("small",{cls:"pt-suggest-path",text:t.file.path})}onChooseSuggestion(t){this.onChoose(t)}};var tt=class extends k{constructor(t,e,s,r){super(t,{header:"New Task",subHeader:s.title,accent:s.color});this.plugin=e;this.project=s;let o=r&&s.statuses[r]?r:s.statusOrder[0]??"";this.input={name:"",status:o,prioritized:!1,labels:[],parent:null,start:null,due:null,description:"",custom:Ke(s.customFields)}}input;createButton;onOpen(){let t=new St.SettingGroup(this.content).addSetting(e=>{g(e).setName("Title").addText(s=>{s.setPlaceholder("What needs doing?").onChange(r=>{this.input.name=r,this.createButton.setDisabled(!r.trim())}),this.focusOnOpen(s.inputEl)})}).addSetting(e=>{e.setName("Status").addDropdown(s=>{for(let r of this.project.statusOrder)s.addOption(r,this.project.statuses[r].name);s.setValue(this.input.status).onChange(r=>{this.input.status=r})})}).addSetting(e=>{e.setName("Prioritized").setDesc("Flags the task on the board.").addToggle(s=>s.setValue(!1).onChange(r=>{this.input.prioritized=r}))}).addSetting(e=>{e.setName("Start date").addText(s=>{s.inputEl.type="date",s.onChange(r=>{this.input.start=r||null})})}).addSetting(e=>{e.setName("Due date").addText(s=>{s.inputEl.type="date",s.onChange(r=>{this.input.due=r||null})})});if(this.renderLabels(t),this.renderParent(t),t.addSetting(e=>{g(e).setName("Description").addTextArea(s=>s.setPlaceholder("Describe the work\u2026").onChange(r=>{this.input.description=r}))}),this.project.customFields.length){let e=new St.SettingGroup(this.content).setHeading("Custom Fields");ee(this.app,e.listEl.createDiv({cls:"pt-config-block"}),this.project.customFields,this.input.custom)}this.createButton=this.setPrimaryAction({text:"Create task",disabled:!0,onClick:()=>void this.submit()})}renderParent(t){t.addSetting(e=>{e.setName("Parent task").setDesc("The task this one belongs under.");let s=Xt(e),r=()=>{s.empty(),e.controlEl.empty();let o=this.input.parent?this.plugin.store.getTaskByPath(this.input.parent):null;if(s.toggle(!!o),o){let a=s.createDiv({cls:"pt-task-row is-static"});a.createSpan({cls:"pt-status-dot"}).style.setProperty("--pt-status-color",this.project.statuses[o.status]?.color??"#6e7781"),a.createSpan({cls:"pt-task-row-name",text:o.name})}new m(e.controlEl,{icon:o?"x":"plus",tooltip:o?"Clear parent task":"Assign a parent task",class:o?"pt-clear-button":void 0,onClick:()=>{if(o){this.input.parent=null,r();return}let a=this.plugin.store.getTasks(this.project.id);new ft(this.app,a,l=>{this.input.parent=l.file.path,r()}).open()}})};r()})}renderLabels(t){let e=Object.keys(this.project.labels);if(!e.length)return;let s;t.addSetting(r=>{g(r).setName("Labels"),s=r.controlEl});for(let r of e){let o=this.project.labels[r],a=new m(s,{text:o.name,variant:this.input.labels.includes(r)?"cta":"normal",onClick:()=>{let l=this.input.labels.indexOf(r);l===-1?this.input.labels.push(r):this.input.labels.splice(l,1),a.setVariant(l===-1?"cta":"normal")}})}}async submit(){if(this.input.name.trim()){this.createButton.setDisabled(!0);try{let t=await Ct(this.app,this.project,this.input);this.close(),this.plugin.settings.openTaskAfterCreate?await this.app.workspace.getLeaf(!1).openFile(t):this.project.board.openTasksInBoard&&await this.plugin.openProject(this.project.configFile.path)}catch(t){console.error("Project Tracker: failed to create task",t),new St.Notice(`Could not create the task \u2014 ${String(t)}`),this.createButton.setDisabled(!1)}}}};var S=require("obsidian");var z=class i extends k{constructor(t,e,s,r=null){super(t.app,{header:"Edit Task",subHeader:e.title,accent:e.color});this.plugin=t;this.project=e;this.task=s;this.onBack=r;this.edits={name:s.name,status:s.status,prioritized:s.prioritized,labels:[...s.labels],parent:s.parentPath,start:s.start,due:s.due,description:"",notes:"",custom:{...s.custom}}}edits;changeLog="";loaded=!1;saving=!1;bodyEl;onOpen(){this.bodyEl=this.content.createDiv(),this.bodyEl.createDiv({cls:"pt-modal-status",text:"Loading\u2026"}),this.onBack&&new m(this.actionsLeft,{text:"Back",icon:"arrow-left",onClick:()=>{this.close(),this.onBack?.()}}),new m(this.actionsRight,{text:"Open note",icon:"file-text",onClick:()=>void this.openNote()}),this.setPrimaryAction({text:"Save",onClick:()=>void this.submit()}),this.load()}async load(){try{let{body:t}=E(await this.app.vault.cachedRead(this.task.file));this.edits.description=j(t,"Description"),this.edits.notes=j(t,"Notes"),this.changeLog=Se(t,"Change Log"),this.loaded=!0}catch(t){console.error("Project Tracker: could not read the task note",t),new S.Notice("Could not read the task note."),this.close();return}this.renderBody()}renderBody(){this.bodyEl.empty();let t=new S.SettingGroup(this.bodyEl).addSetting(e=>{g(e).setName("Title").addText(s=>s.setValue(this.edits.name).onChange(r=>{this.edits.name=r}))}).addSetting(e=>{e.setName("Status").addDropdown(s=>{for(let r of this.project.statusOrder)s.addOption(r,this.project.statuses[r].name);this.project.statuses[this.edits.status]||s.addOption(this.edits.status,`${this.edits.status} (unknown)`),s.setValue(this.edits.status).onChange(r=>{this.edits.status=r})})}).addSetting(e=>{e.setName("Prioritized").setDesc("Flags the task on the board.").addToggle(s=>s.setValue(this.edits.prioritized).onChange(r=>{this.edits.prioritized=r}))}).addSetting(e=>{e.setName("Start date").addText(s=>{s.inputEl.type="date",s.setValue(this.edits.start??"").onChange(r=>{this.edits.start=r||null})})}).addSetting(e=>{e.setName("Due date").addText(s=>{s.inputEl.type="date",s.setValue(this.edits.due??"").onChange(r=>{this.edits.due=r||null})})});if(this.renderLabels(t),this.renderParent(t),t.addSetting(e=>{g(e).setName("Description").addTextArea(s=>s.setValue(this.edits.description).onChange(r=>{this.edits.description=r}))}).addSetting(e=>{g(e).setName("Notes").addTextArea(s=>s.setValue(this.edits.notes).onChange(r=>{this.edits.notes=r}))}),this.project.customFields.length){let e=new S.SettingGroup(this.bodyEl).setHeading("Custom Fields");ee(this.app,e.listEl.createDiv({cls:"pt-config-block"}),this.project.customFields,this.edits.custom)}this.renderChildren(this.bodyEl),this.renderChangeLog(this.bodyEl)}openTask(t){let e=()=>{new i(this.plugin,this.project,this.task,this.onBack).open()};this.close(),new i(this.plugin,this.project,t,e).open()}renderParent(t){t.addSetting(e=>{e.setName("Parent task").setDesc("The task this one belongs under.");let s=Xt(e),r=()=>{let a=gs(this.plugin.store.getTasks(this.project.id),this.task);new ft(this.app,a,l=>{this.edits.parent=l.file.path,o()}).open()},o=()=>{s.empty(),e.controlEl.empty();let a=!!this.edits.parent;if(s.toggle(a),a){let l=this.plugin.store.getTaskByPath(this.edits.parent),c=s.createDiv({cls:"pt-task-row"}),d=c.createSpan({cls:"pt-status-dot"});l&&d.style.setProperty("--pt-status-color",this.project.statuses[l.status]?.color??"#6e7781"),c.createSpan({cls:"pt-task-row-name",text:l?.name??"Missing task"});let u=this.edits.parent!==this.task.parentPath;l&&!u?((0,S.setIcon)(c.createSpan({cls:"pt-task-row-open"}),"chevron-right"),c.addEventListener("click",()=>this.openTask(l))):(c.addClass("is-static"),l?c.setAttr("aria-label","Save the task to open this"):c.addClass("is-missing"))}new m(e.controlEl,{icon:a?"x":"plus",tooltip:a?"Clear parent task":"Assign a parent task",class:a?"pt-clear-button":void 0,onClick:()=>{if(!a){r();return}this.edits.parent=null,o()}})};o()})}renderChildren(t){let e=this.plugin.store.getChildTasks(this.task.file.path),s=new S.SettingGroup(t).setHeading("Assigned Children").listEl.createDiv({cls:"pt-config-block pt-task-list"});if(!e.length){s.createDiv({cls:"pt-modal-status",text:"No tasks assigned to this one."});return}for(let r of e){let o=s.createDiv({cls:"pt-task-row"});o.createSpan({cls:"pt-status-dot"}).style.setProperty("--pt-status-color",this.project.statuses[r.status]?.color??"#6e7781"),o.createSpan({cls:"pt-task-row-name",text:r.name}),(0,S.setIcon)(o.createSpan({cls:"pt-task-row-open"}),"chevron-right"),o.addEventListener("click",()=>this.openTask(r))}}renderLabels(t){let e=Object.keys(this.project.labels);if(!e.length)return;let s;t.addSetting(r=>{g(r).setName("Labels"),s=r.controlEl});for(let r of e){let o=this.project.labels[r],a=new m(s,{text:o.name,variant:this.edits.labels.includes(r)?"cta":"normal",onClick:()=>{let l=this.edits.labels.indexOf(r);l===-1?this.edits.labels.push(r):this.edits.labels.splice(l,1),a.setVariant(l===-1?"cta":"normal")}})}}renderChangeLog(t){let e=new S.SettingGroup(t).setHeading("Change Log").listEl.createDiv({cls:"pt-config-block pt-changelog"});if(!this.changeLog.trim()){e.createDiv({cls:"pt-modal-status",text:"Nothing recorded yet."});return}for(let s of this.changeLog.split(`
`).reverse()){let r=s.trim();if(!r)continue;let o=/^#{1,6}\s+(.*)$/.exec(r);o?e.createDiv({cls:"pt-changelog-date",text:o[1]}):e.createDiv({cls:"pt-changelog-entry",text:r})}}async openNote(){let t=this.task.file.path,e=this.app.workspace.getLeavesOfType("markdown").find(s=>s.view.file?.path===t);if(this.close(),e){this.app.workspace.setActiveLeaf(e,{focus:!0}),await this.app.workspace.revealLeaf(e);return}await this.app.workspace.getLeaf(!1).openFile(this.task.file)}async submit(){if(!(!this.loaded||this.saving)){if(!this.edits.name.trim()){new S.Notice("Give the task a title.");return}this.saving=!0;try{let{entries:t}=await ps(this.app,this.project,this.task,this.edits);this.close(),t.length&&new S.Notice(`Logged ${t.length} change${t.length===1?"":"s"}.`)}catch(t){console.error("Project Tracker: failed to save the task",t),new S.Notice("Could not save the task \u2014 see the console for details."),this.saving=!1}}}};var C=require("obsidian");var Rn=/^#[0-9a-f]{6}$/i;function ht(i,n,t){let e=i.createSpan({cls:"pt-color-dot"});e.style.setProperty("--pt-swatch-color",n);let s=e.createEl("input",{attr:{type:"color","aria-label":"Colour"}});Rn.test(n.trim())&&(s.value=n.trim().toLowerCase()),s.addEventListener("input",()=>{e.style.setProperty("--pt-swatch-color",s.value),t(s.value)})}var K=require("obsidian");var $n={score:0,matches:[]},Me=class extends K.SuggestModal{constructor(t,e,s){super(t);this.current=e;this.onChoose=s;this.setPlaceholder("Search icons\u2026"),this.limit=60;let r=new Set;this.icons=[];for(let o of(0,K.getIconIds)()){let a=o.replace(/^lucide-/,"");r.has(a)||(r.add(a),this.icons.push({id:o,label:a}))}this.icons.sort((o,a)=>o.label.localeCompare(a.label))}icons;getSuggestions(t){let e=t.trim();if(!e){let o=this.icons.filter(l=>l.id!==this.current);return[...this.icons.filter(l=>l.id===this.current),...o].map(l=>({...l,result:$n}))}let s=(0,K.prepareFuzzySearch)(e),r=[];for(let o of this.icons){let a=s(o.label);a&&r.push({...o,result:a})}return r.sort((o,a)=>a.result.score-o.result.score),r}renderSuggestion(t,e){e.addClass("mod-complex","pt-icon-option"),(0,K.setIcon)(e.createDiv({cls:"pt-icon-option-preview"}),t.id),e.createDiv({cls:"suggestion-content"}).createDiv({cls:"suggestion-title",text:t.label}),t.id===this.current&&e.createDiv({cls:"suggestion-aux"}).createSpan({cls:"suggestion-flair",text:"Current"})}onChooseSuggestion(t){this.onChoose(t.id)}};function se(i,n,t,e){let s=t,r=new m(n,{icon:s,tooltip:"Change icon",onClick:()=>{new Me(i,s,o=>{s=o,r.setIcon(o),e(o)}).open()}})}var Pt="#6e7781",_n={text:"Text",list:"List",number:"Number",checkbox:"Checkbox",date:"Date",datetime:"Date & time"},et=class extends k{constructor(t,e,s){super(t,{header:"Project Configuration",subHeader:s.title,accent:s.color});this.plugin=e;this.project=s;this.title=s.title,this.description=s.description,this.color=s.color,this.icon=s.icon,this.defaultView=s.board.defaultView,this.openTasksInBoard=s.board.openTasksInBoard,this.statuses=s.statusOrder.map(r=>({originalKey:r,key:r,name:s.statuses[r]?.name??r,color:s.statuses[r]?.color??Pt,nextStatus:s.statuses[r]?.nextStatus??null,autoStatusChange:s.statuses[r]?.autoStatusChange??"",warnStart:s.statuses[r]?.warnStart??!1,warnDue:s.statuses[r]?.warnDue??!1})),this.labels=Object.entries(s.labels).map(([r,o])=>({originalKey:r,key:r,name:o.name,color:o.color})),this.fields=s.customFields.map(r=>({originalKey:r.key,key:r.key,name:r.name,color:Pt,type:r.type,defaultValue:O(r.type,r.defaultValue)}))}title;description;color;icon;defaultView;openTasksInBoard;statuses;labels;fields;bodyEl;focusKey=null;pendingFocus=null;onOpen(){this.bodyEl=this.content.createDiv(),new m(this.actionsRight,{text:"View file",icon:"file-text",onClick:()=>void this.openConfigFile()}),this.setPrimaryAction({text:"Save",onClick:()=>void this.submit()}),this.renderBody()}renderBody(){let t=this.content,e=t.scrollTop;this.bodyEl.empty();let s=this.bodyEl;new C.SettingGroup(s).setHeading("General").addSetting(r=>{g(r).setName("Title").addText(o=>o.setValue(this.title).onChange(a=>{this.title=a,this.setSubHeader(a)})),se(this.app,r.controlEl,this.icon,o=>{this.icon=o})}).addSetting(r=>{r.setName("Project colour").setDesc("Used for the project's icon and card accent."),ht(r.controlEl,this.color,o=>{this.color=o})}).addSetting(r=>{g(r).setName("Description").addTextArea(o=>o.setValue(this.description).onChange(a=>{this.description=a}))}),this.renderBoardSection(s),this.renderStatusSection(s),this.renderLabelSection(s),this.renderFieldSection(s),t.scrollTop=e,this.applyPendingFocus()}applyPendingFocus(){let t=this.pendingFocus;t&&(this.pendingFocus=null,this.focusKey=null,C.Platform.isMobile||(t.focus(),t.select()),t.scrollIntoView({block:"nearest"}))}renderBoardSection(t){new C.SettingGroup(t).setHeading("Board Settings").addSetting(e=>{e.setName("Default view").setDesc("Opened first when the project is opened.").addDropdown(s=>{for(let r of this.project.board.views)s.addOption(r.id,r.name);s.setValue(this.defaultView).onChange(r=>{this.defaultView=r})})}).addSetting(e=>{e.setName("Open tasks in board").setDesc("Return to the board after creating a task from a command.").addToggle(s=>s.setValue(this.openTasksInBoard).onChange(r=>{this.openTasksInBoard=r}))})}renderStatusSection(t){let e=new C.SettingGroup(t).addClass("pt-group-split").setHeading(this.statusHeading()).listEl.createDiv({cls:"pt-config-block"});e.createDiv({cls:"pt-modal-status",text:"Order sets the board's columns. Renaming a status rewrites its key on save, along with every task and view filter that refers to it."});let s=e.createDiv({cls:"pt-config-list"}),r=this.reorderer(this.statuses);this.statuses.forEach((o,a)=>this.renderStatusRow(s,o,a,r)),this.addButton(e,"Add status",()=>{let o=this.uniqueKey("New status",this.takenKeys(this.statuses));this.focusKey=o,this.statuses.push({originalKey:null,key:o,name:"New status",color:Pt,nextStatus:null,autoStatusChange:"",warnStart:!1,warnDue:!1}),this.renderBody()})}statusHeading(){let t=this.plugin.settings.showAdvancedStatuses;return createFragment(e=>{e.createSpan({text:"Statuses"});let s=e.createSpan({cls:"pt-group-advanced",text:t?"Hide Advanced":"Show Advanced",attr:{role:"button",tabindex:"0"}}),r=()=>{this.plugin.settings.showAdvancedStatuses=!t,this.plugin.saveSettings(),this.renderBody()};s.addEventListener("click",r),s.addEventListener("keydown",o=>{o.key!=="Enter"&&o.key!==" "||(o.preventDefault(),r())})})}renderStatusRow(t,e,s,r){let o=t.createDiv({cls:"pt-config-row"}),a=o.createDiv({cls:"pt-config-row-main"});if(r.attach(o,this.renderGrip(a),s),ht(a,e.color,p=>{e.color=p}),this.renderNameField(a,e,this.statuses,"Status name"),this.renderRowActions(a,s,this.statuses,()=>this.statuses.length>1),!this.plugin.settings.showAdvancedStatuses)return;let l=o.createDiv({cls:"pt-config-row-meta"}),c=l.createDiv({cls:"pt-config-field"});c.createSpan({cls:"pt-config-field-label",text:"Next status"});let d=c.createEl("select",{cls:"pt-input-style-flat"});d.createEl("option",{value:"",text:"None"});for(let p of this.statuses)p!==e&&d.createEl("option",{value:p.key,text:p.name||p.key});d.value=e.nextStatus??"",d.addEventListener("change",()=>{e.nextStatus=d.value||null});let u=l.createDiv({cls:"pt-config-field"});u.createSpan({cls:"pt-config-field-label",text:"Auto-advance after"});let h=u.createEl("input",{cls:"pt-config-duration",attr:{type:"text",placeholder:"30d"}});h.value=e.autoStatusChange,h.addEventListener("input",()=>{e.autoStatusChange=h.value}),this.renderCheckField(l,"Warn start date",e.warnStart,p=>{e.warnStart=p}),this.renderCheckField(l,"Warn due date",e.warnDue,p=>{e.warnDue=p})}renderCheckField(t,e,s,r){let o=t.createDiv({cls:"pt-config-field"});o.createSpan({cls:"pt-config-field-label",text:e});let a=o.createEl("input",{cls:"metadata-input-checkbox",attr:{type:"checkbox"}});a.checked=s,a.addEventListener("change",()=>r(a.checked))}renderLabelSection(t){let e=new C.SettingGroup(t).setHeading("Labels").listEl.createDiv({cls:"pt-config-block"}),s=e.createDiv({cls:"pt-config-list"}),r=this.reorderer(this.labels);for(let[o,a]of this.labels.entries()){let l=s.createDiv({cls:"pt-config-row"}),c=l.createDiv({cls:"pt-config-row-main"});r.attach(l,this.renderGrip(c),o),ht(c,a.color,d=>{a.color=d}),this.renderNameField(c,a,this.labels,"Label name"),this.renderRowActions(c,o,this.labels,()=>!0)}this.labels.length||s.createDiv({cls:"pt-modal-status",text:"No labels yet."}),this.addButton(e,"Add label",()=>{let o=this.uniqueKey("New label",this.takenKeys(this.labels));this.focusKey=o,this.labels.push({originalKey:null,key:o,name:"New label",color:Pt}),this.renderBody()})}renderFieldSection(t){let e=new C.SettingGroup(t).setHeading("Custom Fields").listEl.createDiv({cls:"pt-config-block"});e.createDiv({cls:"pt-modal-status",text:"Stored in each task's frontmatter under the field's key. Obsidian owns property types vault-wide, so a new key may need its type set once from a note's Properties panel."});let s=e.createDiv({cls:"pt-config-list"}),r=this.reorderer(this.fields);for(let[o,a]of this.fields.entries()){let l=s.createDiv({cls:"pt-config-row"}),c=l.createDiv({cls:"pt-config-row-main"});r.attach(l,this.renderGrip(c),o),this.renderNameField(c,a,this.fields,"Field name");let d=c.createEl("select",{cls:"pt-config-type pt-input-style-flat"});for(let[p,f]of Object.entries(_n))d.createEl("option",{value:p,text:f});d.value=a.type,d.addEventListener("change",()=>{a.type=d.value,a.defaultValue=O(a.type,a.defaultValue),this.renderBody()}),this.renderRowActions(c,o,this.fields,()=>!0);let h=l.createDiv({cls:"pt-config-row-meta"}).createDiv({cls:"pt-config-field pt-config-default"});h.createSpan({cls:"pt-config-field-label",text:"Default Value"}),Fe(this.app,h.createDiv({cls:"pt-config-default-value"}),a.type,{get:()=>a.defaultValue,set:p=>{a.defaultValue=p}})}this.fields.length||s.createDiv({cls:"pt-modal-status",text:"No custom fields yet."}),this.addButton(e,"Add field",()=>{let o=this.uniqueKey("New field",this.takenKeys(this.fields));this.focusKey=o,this.fields.push({originalKey:null,key:o,name:"New field",color:Pt,type:"text",defaultValue:null}),this.renderBody()})}renderNameField(t,e,s,r){let o=t.createDiv({cls:"pt-config-input"}),a=o.createEl("input",{cls:"pt-config-name",attr:{type:"text",placeholder:r}});a.value=e.name,this.focusKey!==null&&e.key===this.focusKey&&(this.pendingFocus=a);let l=o.createEl("code",{cls:"pt-config-key",text:e.key,attr:{title:e.key}});a.addEventListener("input",()=>{e.name=a.value,e.key=this.deriveKey(e,s),l.setText(e.key),l.setAttr("title",e.key),l.toggleClass("is-renamed",e.originalKey!==null&&e.originalKey!==e.key)})}reorderer(t){return new pt((e,s)=>{let[r]=t.splice(e,1);t.splice(s,0,r),this.renderBody()})}renderGrip(t){let e=t.createSpan({cls:"pt-config-grip",attr:{"aria-label":"Drag to reorder"}});return(0,C.setIcon)(e,"grip-vertical"),e}renderRowActions(t,e,s,r){let o=t.createDiv({cls:"pt-config-actions pt-btn-group"});new m(o,{icon:"trash",tooltip:"Remove",variant:"warning",disabled:!r(),onClick:()=>{s.splice(e,1),this.renderBody()}})}addButton(t,e,s){new m(t,{text:e,onClick:s})}takenKeys(t,e){return new Set(t.filter(s=>s!==e).map(s=>s.key))}deriveKey(t,e){return t.name.trim()?this.uniqueKey(t.name,this.takenKeys(e,t)):t.key}uniqueKey(t,e){let s=M(t);if(!e.has(s))return s;let r=2;for(;e.has(`${s}-${r}`);)r++;return`${s}-${r}`}renames(t){let e=new Map;for(let s of t)s.originalKey&&s.originalKey!==s.key&&e.set(s.originalKey,s.key);return e}async openConfigFile(){let t=this.project.configFile.path,e=this.app.workspace.getLeavesOfType("markdown").find(s=>s.view.file?.path===t);if(this.close(),e){this.app.workspace.setActiveLeaf(e,{focus:!0}),await this.app.workspace.revealLeaf(e);return}await this.app.workspace.getLeaf(!1).openFile(this.project.configFile)}problem(){if(!this.title.trim())return"The project needs a title.";if(!this.statuses.length)return"A project needs at least one status.";for(let t of this.statuses){if(!t.name.trim())return"Every status needs a name.";let e=t.autoStatusChange.trim();if(e&&ut(e)===null)return`"${e}" is not a duration \u2014 use a number with h, d, w, m or y.`}for(let t of this.labels)if(!t.name.trim())return"Every label needs a name.";for(let t of this.fields){if(!t.name.trim())return"Every custom field needs a name.";if(Vt.has(t.key))return`"${t.key}" is a key Project Tracker already uses \u2014 rename that field.`}return null}async submit(){let t=this.problem();if(t){new C.Notice(t);return}let e=this.renames(this.statuses),s=this.renames(this.labels),r=this.renames(this.fields),o=(f,b)=>f.get(b)??b,a=new Set(this.statuses.map(f=>f.key)),l={};for(let f of this.statuses){let b=f.nextStatus?o(e,f.nextStatus):null;l[f.key]={name:f.name.trim(),color:f.color,nextStatus:b&&a.has(b)?b:null,autoStatusChange:f.autoStatusChange.trim()||null,warnStart:f.warnStart,warnDue:f.warnDue}}let c={};for(let f of this.labels)c[f.key]={name:f.name.trim(),color:f.color};let d=this.fields.map(f=>({key:f.key,name:f.name.trim(),type:f.type,defaultValue:O(f.type,f.defaultValue)})),u=this.project.board.views.map(f=>({...f,filters:{...f.filters,status:f.filters.status.map(b=>o(e,b)),labels:f.filters.labels.map(b=>o(s,b))}})),h={defaultView:u.some(f=>f.id===this.defaultView)?this.defaultView:u[0]?.id??this.defaultView,openTasksInBoard:this.openTasksInBoard,views:u};try{await Ze(this.app,this.project,{title:this.title.trim(),description:this.description.trim(),statuses:l,labels:c,customFields:d,board:h}),await Qe(this.app,this.project,{color:this.color,icon:this.icon})}catch(f){console.error("Project Tracker: failed to save the project config",f),new C.Notice("Could not save the config \u2014 see the console for details.");return}let p=await this.migrateTasks(e,s,r);this.close(),(p.changed||p.failed)&&new C.Notice(this.migrationSummary(p))}async migrateTasks(t,e,s){if(!t.size&&!e.size&&!s.size)return{changed:0,failed:0};let r=0,o=0;for(let a of this.plugin.store.getTasks(this.project.id)){let l=t.get(a.status),c=a.labels.some(u=>e.has(u))?a.labels.map(u=>e.get(u)??u):null,d=[...s].filter(([u])=>u in a.custom);if(!(!l&&!c&&!d.length))try{await D(this.app,a.file,u=>{l&&(u["task-status"]=l),c&&(u["task-labels"]=c);for(let[h,p]of d)u[p]=u[h],delete u[h]}),r++}catch(u){console.error(`Project Tracker: could not retarget ${a.file.path}`,u),o++}}return{changed:r,failed:o}}migrationSummary({changed:t,failed:e}){let s=`${t} task${t===1?"":"s"}`;return e?`Updated ${s}, but ${e} could not be written \u2014 see the console.`:`Updated ${s} for the renamed keys.`}};var ie=require("obsidian");var xt=require("obsidian");function zn(i,n,t){let e=n.statuses[t],s=i.createSpan({cls:"pt-status-pill"});return s.style.setProperty("--pt-status-color",e?.color??"#6e7781"),s.createSpan({cls:"pt-status-dot"}),s.createSpan({text:e?.name??t??"No status"}),s}function Oe(i,n,t){if(!t.length)return;let e=i.createDiv({cls:"pt-label-row"});for(let s of t){let r=n.labels[s];e.createSpan({cls:"pt-label",text:r?.name??s}).style.setProperty("--pt-chip-color",r?.color??"#6e7781")}}var Et={start:"calendar-clock",due:"calendar-check",created:"calendar-plus",modified:"calendar-range"};function ne(i,n,t){if(!n)return null;let e=i.createSpan({cls:"pt-date"});return(0,xt.setIcon)(e.createSpan({cls:"pt-date-icon"}),t),e.createSpan({text:Tt(n)}),e}function Ve(i,n,t){let e=t==="start"?n.start:n.due;if(!e||!rs(e))return!1;let s=i.statuses[n.status];return t==="start"?s?.warnStart===!0:s?.warnDue===!0}function Ts(i,n,t){if(!t.start&&!t.due)return;let e=i.createSpan({cls:"pt-date"}),s=!!(t.start&&t.due),r=(o,a)=>{let l=e.createSpan({cls:"pt-date-end"});(0,xt.setIcon)(l.createSpan({cls:"pt-date-icon"}),Et[o]),l.createSpan({text:Tt(a)}),Ve(n,t,o)&&(s?l:e).addClass("is-overdue")};t.start&&r("start",t.start),s&&(0,xt.setIcon)(e.createSpan({cls:"pt-date-arrow"}),"arrow-right"),t.due&&r("due",t.due)}function Kn(i,n,t){let e=ne(i,t.due,Et.due);e&&Ve(n,t,"due")&&e.addClass("is-overdue")}function Gn(i,n,t){let e=ne(i,t.start,Et.start);e&&Ve(n,t,"start")&&e.addClass("is-overdue")}function Un(i,n){ne(i,n,Et.created)}function Wn(i,n){ne(i,n,Et.modified)}function re(i,n,t,e){switch(e){case"status":zn(i,n,t.status);break;case"labels":Oe(i,n,t.labels);break;case"start":Gn(i,n,t);break;case"due":Kn(i,n,t);break;case"created":Un(i,t.created);break;case"modified":Wn(i,t.modified);break}}function jt(i,n){if(!n.prioritized)return;let t=i.createSpan({cls:"pt-priority",attr:{"aria-label":"Prioritized"}});(0,xt.setIcon)(t,"flame")}var Jn=new Set(["start","due","created","modified"]);function Cs(i,n,t,e){if(!e.length)return;let s=i.createDiv({cls:"pt-card-footer"});for(let r of e)re(s,n,t,r);s.childElementCount||s.remove()}function mt(i,n,t,e,s){let r=i.createDiv({cls:"community-item",attr:{role:"button",tabindex:"0"}}),o=r.createDiv({cls:"community-item-name"});if(s.display!=="dock"&&(o.addClass("pt-card-title"),(s.display==="board"||s.columns.includes("prioritized"))&&jt(o,t)),o.createSpan({text:t.name}),s.showDescription&&t.descriptionSnippet&&r.createDiv({cls:"community-item-desc pt-card-desc",text:t.descriptionSnippet}),s.showExtras)if(s.display==="table"){let c=d=>Jn.has(d);Cs(r,n,t,s.columns.filter(d=>!c(d))),Cs(r,n,t,s.columns.filter(c))}else{let c=r.createDiv({cls:"pt-card-footer"});s.display==="dock"&&jt(c,t),Oe(c,n,t.labels),Ts(c,n,t),c.childElementCount||c.remove()}let a=t.parentPath?e.resolveTask(t.parentPath):null;if(a){let c=r.createDiv({cls:"pt-card-parent"});(0,ie.setIcon)(c.createSpan({cls:"pt-card-parent-icon"}),"corner-left-up"),c.createSpan({cls:"pt-card-parent-link",text:a.name}).addEventListener("click",u=>{u.stopPropagation(),e.editTask(a)})}let l=c=>{c.ctrlKey||c.metaKey?e.openTask(t,!0):e.editTask(t)};return r.addEventListener("click",c=>{if(ie.Platform.isMobile){e.showTaskMenu(c,t);return}l(c)}),r.addEventListener("keydown",c=>{c.key!=="Enter"&&c.key!==" "||(c.preventDefault(),l(c))}),r.addEventListener("contextmenu",c=>{c.preventDefault(),e.showTaskMenu(c,t)}),r}var Dt=null;function Ss(i,n,t){let e=n[t];new m(i,{icon:t==="previous"?"chevron-left":"chevron-right",tooltip:t==="previous"?"Previous column":"Next column",class:"pt-column-step",disabled:e===null,onClick:()=>{e&&n.onSelect(e)}})}function Yn(i,n,t,e,s){let r=mt(i,n,t,e,{showDescription:s,showExtras:!0,display:"board"});r.setAttr("draggable","true"),r.addEventListener("dragstart",o=>{Dt=t.file.path,r.addClass("is-dragging"),o.dataTransfer?.setData("text/plain",t.file.path),o.dataTransfer&&(o.dataTransfer.effectAllowed="move")}),r.addEventListener("dragend",()=>{Dt=null,r.removeClass("is-dragging")})}function Ps(i,n,t,e,s,r,o=null){let a=i.createDiv({cls:"pt-board"});if(!e.length){a.createDiv({cls:"pane-empty",text:"No columns to show. This project has no statuses in its Status Config."});return}for(let l of e){let c=n.statuses[l];if(!c)continue;let d=t.filter(f=>f.status===l),u=a.createDiv({cls:"pt-column"});u.style.setProperty("--pt-status-color",c.color);let h=u.createDiv({cls:"pt-column-header"});o&&Ss(h,o,"previous"),h.createSpan({cls:"pt-status-dot"}),h.createSpan({cls:"pt-column-name",text:c.name}),h.createSpan({cls:"pt-column-count",text:String(d.length)}),o?Ss(h,o,"next"):new m(h,{icon:"plus",tooltip:`New task in ${c.name}`,class:"pt-btn-style-flat",onClick:()=>s.createTask(l)});let p=u.createDiv({cls:"pt-column-body"});for(let f of d)Yn(p,n,f,s,r);d.length||p.createDiv({cls:"pane-empty",text:"Nothing here"}),u.addEventListener("dragover",f=>{Dt&&(f.preventDefault(),f.dataTransfer&&(f.dataTransfer.dropEffect="move"),u.addClass("is-drop-target"))}),u.addEventListener("dragleave",f=>{u.contains(f.relatedTarget)||u.removeClass("is-drop-target")}),u.addEventListener("drop",f=>{f.preventDefault(),u.removeClass("is-drop-target");let b=Dt??f.dataTransfer?.getData("text/plain");Dt=null;let x=t.find(ke=>ke.file.path===b);x&&x.status!==l&&s.moveTask(x,l)})}}var gt=require("obsidian");var st={prioritized:"Priority",title:"Title",status:"Status",labels:"Labels",start:"Start",due:"Due",created:"Created",modified:"Modified"};function oe(i){let n=new Set(Object.keys(st)),t=new Set;return i.filter(e=>!n.has(e)||t.has(e)?!1:(t.add(e),!0))}var ae={prioritized:"task-prioritized",title:"task-name",status:"task-status",labels:"task-labels",start:"task-start",due:"task-due",created:"task-created",modified:"task-modified"};var Ie="#6e7781";function le(i,n,t){return t==="label"?Xn(i,n):qn(i,n)}function qn(i,n){let t=new Set(n.map(s=>s.status));return[...i.statusOrder.filter(s=>t.has(s)),...[...t].filter(s=>!i.statuses[s])].map(s=>({key:`status:${s}`,name:i.statuses[s]?.name??s??"No status",color:i.statuses[s]?.color??Ie,tasks:n.filter(r=>r.status===s)})).filter(s=>s.tasks.length>0)}function Xn(i,n){let t=new Set(n.flatMap(o=>o.labels)),s=[...Object.keys(i.labels).filter(o=>t.has(o)),...[...t].filter(o=>!i.labels[o])].map(o=>({key:`label:${o}`,name:i.labels[o]?.name??o,color:i.labels[o]?.color??Ie,tasks:n.filter(a=>a.labels.includes(o))})).filter(o=>o.tasks.length>0),r=n.filter(o=>!o.labels.length);return r.length&&s.push({key:"nolabel",name:"No labels",color:Ie,tasks:r}),s}function Zn(i,n,t,e,s,r){let o=i.createEl("td",{cls:`pt-cell pt-cell-${n}`});switch(n){case"title":{o.createEl("a",{cls:"pt-table-title",text:e.name}).addEventListener("click",l=>{l.preventDefault(),l.ctrlKey||l.metaKey?s.openTask(e,!0):s.editTask(e)}),r&&e.descriptionSnippet&&o.createDiv({cls:"pt-table-desc",text:e.descriptionSnippet});break}case"prioritized":jt(o,e);break;default:re(o,t,e,n)}}function Qn(i,n,t,e,s,r){for(let o of e){let a=i.createEl("tr",{cls:"pt-row"});for(let l of n)Zn(a,l,t,o,s,r);a.addEventListener("contextmenu",l=>{l.preventDefault(),s.showTaskMenu(l,o)})}}function xs(i,n,t,e,s,r){if(gt.Platform.isPhone){let a=i.createDiv({cls:"pt-card-list"});for(let l of e)mt(a,t,l,r,{showDescription:s.showDescription,showExtras:!0,display:"table",columns:n});return}let o=i.createEl("table",{cls:"pt-table"});tr(o,n,s,r),Qn(o.createEl("tbody"),n,t,e,r,s.showDescription)}function tr(i,n,t,e){let s=i.createEl("thead").createEl("tr");for(let r of n){let o=s.createEl("th",{cls:`pt-head pt-head-${r}`}),a=ae[r],l=t.sort.field===a;o.toggleClass("is-sorted",l);let c=o.createEl("button",{cls:"pt-head-button",attr:{type:"button"}});r==="prioritized"?(c.setAttr("aria-label",st[r]),c.setAttr("title",st[r]),(0,gt.setIcon)(c.createSpan(),"flame")):c.createSpan({text:st[r]});let d=c.createSpan({cls:"pt-sort-icon"});l&&(0,gt.setIcon)(d,t.sort.dir==="asc"?"arrow-up":"arrow-down"),c.addEventListener("click",()=>{l?t.sort.dir==="asc"?e.setSort(a,"desc"):e.setSort(null,"desc"):e.setSort(a,"asc")})}}function er(i,n,t,e,s){let r=i.createEl("button",{cls:"bases-group-heading pt-group-header",attr:{type:"button","aria-expanded":String(!e)}});r.toggleClass("is-collapsed",e),(0,gt.setIcon)(r.createSpan({cls:"pt-group-chevron"}),e?"chevron-right":"chevron-down"),r.createSpan({cls:"pt-status-dot"}),r.createSpan({cls:"bases-group-value",text:n}),r.createSpan({cls:"bases-group-property",text:String(t)}),r.addEventListener("click",s)}function Es(i,n,t,e,s){let r=oe(e.columns.length?e.columns:["title","status"]),o=i.createDiv({cls:"pt-table-wrapper"});if(!t.length){o.createDiv({cls:"pane-empty",text:"No tasks match this view."});return}if(e.groupBy==="none"){xs(o,r,n,t,e,s);return}for(let a of le(n,t,e.groupBy)){let l=s.collapsedGroups.has(a.key),c=o.createDiv({cls:"pt-group"});c.style.setProperty("--pt-status-color",a.color),er(c,a.name,a.tasks.length,l,()=>s.toggleGroup(a.key)),!l&&xs(c,r,n,a.tasks,e,s)}}var js=require("obsidian");function Ds(i,n,t,e,s=!0){let r=i.createDiv({cls:"pt-project-page-header"});if(s){let a=r.createDiv({cls:"pt-project-page-heading"});new m(a,{icon:n.icon,tooltip:"Project configuration",onClick:e.onConfigure}),a.createEl("h2",{cls:"pt-project-page-title",text:n.title})}let o=r.createDiv({cls:"pt-project-page-tabs"});for(let a of n.board.views){let l=o.createEl("button",{cls:"pt-project-page-tab",attr:{type:"button"}});l.toggleClass("mod-cta",a.id===t.id),(0,js.setIcon)(l.createSpan({cls:"pt-project-page-tab-icon"}),a.type==="kanban"?"columns-3":"table"),l.createSpan({text:a.name}),l.addEventListener("click",()=>e.onSelectView(a))}new m(o,{icon:"plus",tooltip:"New view",class:"pt-project-page-tab",onClick:e.onNewView})}var ce=require("obsidian");function sr(i,n){let t=i.createDiv({cls:"pt-project-page-toolbar-field"});return t.createSpan({cls:"pt-project-page-toolbar-field-label",text:n}),t}function Ls(i,n,t,e,s={search:!0,group:!0,actions:!0}){let r=i.createDiv({cls:"pt-project-page-toolbar"});s.search&&new ce.SearchComponent(r).setPlaceholder("Filter tasks\u2026").setValue(t).onChange(e.onSearch);let o=r.createDiv({cls:"pt-project-page-toolbar-end"});n.type==="table"&&s.group&&new ce.DropdownComponent(sr(o,"Group")).addOption("none","None").addOption("status","Status").addOption("label","Label").setValue(n.groupBy).onChange(l=>{e.onChangeView({...n,groupBy:rt(l)})}).selectEl.addClass("pt-input-style-flat"),s.actions&&(new m(o,{icon:"sliders-horizontal",tooltip:`Configure "${n.name}"`,class:"pt-btn-style-flat",onClick:e.onConfigure}),new m(o,{text:"New task",variant:"cta",class:"pt-new-task",onClick:e.onNewTask})),o.childElementCount||o.remove(),r.childElementCount||r.remove()}var Fs=require("obsidian");function de(i,n,t,e){let{app:s}=i,r=new Fs.Menu;r.addItem(a=>a.setTitle("Edit task\u2026").setIcon("pencil").onClick(()=>new z(i,t,e).open())),r.addSeparator(),r.addItem(a=>a.setTitle("Open note").setIcon("file-text").onClick(()=>void s.workspace.getLeaf(!1).openFile(e.file))),r.addItem(a=>a.setTitle("Open in new tab").setIcon("file-plus").onClick(()=>void s.workspace.getLeaf(!0).openFile(e.file)));let o=fs(t,e);o&&(r.addSeparator(),r.addItem(a=>a.setTitle(`Advance to ${o.option.name}`).setIcon("arrow-right").onClick(()=>void Z(s,t,e,o.key)))),r.addSeparator();for(let a of t.statusOrder)a!==e.status&&r.addItem(l=>l.setTitle(`Move to ${t.statuses[a].name}`).onClick(()=>void Z(s,t,e,a)));r.addSeparator(),r.addItem(a=>a.setTitle(e.prioritized?"Remove priority":"Mark as prioritized").setIcon("flame").onClick(()=>void us(s,e,!e.prioritized))),r.addItem(a=>a.setTitle("Delete task").setIcon("trash").onClick(()=>void s.fileManager.trashFile(e.file))),r.showAtMouseEvent(n)}var Lt=class extends y.ItemView{constructor(t,e){super(t);this.plugin=e}projectPath=null;activeViewId=null;search="";boardColumn=null;headerText=null;collapsedGroups=new Set;bodyEl=null;footerEl=null;unsubscribe=null;getViewType(){return G}getIcon(){return this.currentProject()?.icon??A}getDisplayText(){return this.currentProject()?.title??"Project"}onPaneMenu(t,e){let s=this.currentProject();if(!s){super.onPaneMenu(t,e);return}let r=this.currentView(s);if(y.Platform.isMobile){let o=r.type==="kanban"?this.boardVisible(s,r)[0]:void 0;t.addItem(l=>l.setSection("action").setTitle("New task").setIcon("plus").onClick(()=>this.host(s).createTask(o))),t.addItem(l=>l.setSection("action").setTitle(`Configure "${r.name}"`).setIcon("sliders-horizontal").onClick(()=>this.openViewEditor(s,r)));let a=this.columnPicker(s,r);a&&this.addColumnMenu(t,a),r.type==="table"&&y.Platform.isPhone&&(this.addSortMenu(t,s,r),this.addGroupMenu(t,s,r)),t.addSeparator()}t.addItem(o=>o.setSection("action").setTitle("Project configuration").setIcon(s.icon).onClick(()=>new et(this.app,this.plugin,s).open())),super.onPaneMenu(t,e)}addColumnMenu(t,e){let s=this.submenuFor(t,"Column","columns-3"),r=[],o=a=>{for(let l of r)l.item.setIcon(l.key===a?"lucide-check":null)};for(let a of e.options)(s??t).addItem(l=>{r.push({key:a.key,item:l}),l.setTitle(a.label).onClick(()=>{e.onSelect(a.key),o(a.key)})});o(e.selected)}addSortMenu(t,e,s){let r=this.submenuFor(t,"Sort","arrow-up-down"),o=[],a=s.sort.field,l=s.sort.dir,c=()=>{for(let u of o)u.field!==a?u.item.setIcon(null):u.item.setIcon(a===null?"lucide-check":l==="asc"?"arrow-up":"arrow-down")},d=(u,h)=>{(r??t).addItem(p=>{o.push({field:h,item:p}),p.setTitle(u).onClick(()=>{l=h!==null&&h===a&&l==="asc"?"desc":"asc",a=h,this.host(e).setSort(h,l),c()})})};d("None",null);for(let u of oe(s.columns))d(st[u],ae[u]);c()}addGroupMenu(t,e,s){let r=this.submenuFor(t,"Group","list-tree"),o=[],a=c=>{for(let d of o)d.item.setIcon(d.key===c?"lucide-check":null)},l=[{key:"none",label:"None"},{key:"status",label:"Status"},{key:"label",label:"Label"}];for(let c of l)(r??t).addItem(d=>{o.push({key:c.key,item:d}),d.setTitle(c.label).onClick(()=>{this.saveView(e,{...this.currentView(e),groupBy:c.key}),a(c.key)})});a(s.groupBy)}submenuFor(t,e,s){let r=null;return t.addItem(o=>{o.setSection("action").setTitle(e).setIcon(s);try{r=o.setSubmenu?.()??null}catch{r=null}r===null&&o.setIsLabel(!0)}),r}getState(){return{projectPath:this.projectPath,activeViewId:this.activeViewId}}async setState(t,e){t?.projectPath&&(this.projectPath=t.projectPath),t?.activeViewId&&(this.activeViewId=t.activeViewId),this.renderShell(),await super.setState(t,e)}async onOpen(){this.unsubscribe=this.plugin.store.onChange(()=>this.renderShell()),this.registerEvent(this.app.vault.on("rename",(t,e)=>{let s=Ut(this.projectPath,e,t.path);s&&(this.projectPath=s,this.app.workspace.requestSaveLayout(),this.currentProject()&&this.renderShell())})),this.renderShell()}async onClose(){this.unsubscribe?.(),this.unsubscribe=null}currentProject(){return this.projectPath?this.plugin.store.getProjectByConfigPath(this.projectPath):null}currentView(t){let e=t.board.views.find(r=>r.id===this.activeViewId);if(e)return e;let s=t.board.views.find(r=>r.id===t.board.defaultView)??t.board.views[0];return this.activeViewId=s?.id??null,s}refreshHeader(){let t=this.getDisplayText();if(t!==this.headerText){this.headerText=t;try{this.titleEl?.setText(t),this.leaf.updateHeader?.()}catch{}}}renderShell(){let t=this.contentEl;t.empty(),t.addClass("pt-project-page"),this.refreshHeader();let e=this.currentProject();if(!e){this.renderMissing(t);return}t.style.setProperty("--pt-project-color",e.color);let s=this.currentView(e);Ds(t,e,s,{onConfigure:()=>new et(this.app,this.plugin,e).open(),onSelectView:r=>{this.activeViewId=r.id,this.boardColumn=null,this.collapsedGroups.clear(),this.app.workspace.requestSaveLayout(),this.renderShell()},onNewView:()=>this.openViewEditor(e,null)},!y.Platform.isMobile),Ls(t,s,this.search,{onSearch:r=>{this.search=r,this.renderBody()},onConfigure:()=>this.openViewEditor(e,s),onChangeView:r=>void this.saveView(e,r),onNewTask:()=>this.host(e).createTask()},{search:!y.Platform.isPhone||s.type==="table",group:!y.Platform.isPhone,actions:!y.Platform.isMobile}),e.configErrors.length&&this.renderConfigErrors(t,e),this.bodyEl=t.createDiv({cls:"pt-project-page-body"}),this.footerEl=t.createDiv({cls:"pt-project-page-footer"}),this.renderBody()}boardVisible(t,e){let s=Yt(t.statusOrder,e.filters.status);return!y.Platform.isPhone||!s.length?s:[this.boardColumn&&s.includes(this.boardColumn)?this.boardColumn:s[0]]}columnCycle(t,e){if(e.type!=="kanban"||!y.Platform.isPhone)return null;let s=Yt(t.statusOrder,e.filters.status),r=s.indexOf(this.boardVisible(t,e)[0]);return r===-1?null:{previous:r>0?s[r-1]:null,next:r<s.length-1?s[r+1]:null,onSelect:o=>{this.boardColumn=o,this.renderBody()}}}columnPicker(t,e){if(e.type!=="kanban"||!y.Platform.isPhone)return null;let s=Yt(t.statusOrder,e.filters.status);if(!s.length)return null;let r=Jt(this.plugin.store.getTasks(t.id),e.filters);return{options:s.map(o=>({key:o,label:`${t.statuses[o]?.name??o} (${r.filter(a=>a.status===o).length})`})),selected:this.boardVisible(t,e)[0],onSelect:o=>{this.boardColumn=o,this.renderBody()}}}renderMissing(t){if(!this.plugin.store.ready){t.createDiv({cls:"pane-empty",text:"Loading\u2026"});return}let e=t.createDiv({cls:"pt-project-page-empty"});e.createDiv({cls:"pane-empty",text:this.projectPath?`Could not find a project config at ${this.projectPath}. It may have been renamed or its ProjectConfig tag removed.`:"Open a project from the Projects list to get started."}),new m(e,{text:"Browse projects",variant:"cta",onClick:()=>void this.plugin.openProjectList()})}renderConfigErrors(t,e){let s=t.createDiv({cls:"pt-project-page-warning"});(0,y.setIcon)(s.createSpan({cls:"pt-project-page-warning-icon"}),"alert-triangle");let r=s.createDiv();for(let a of e.configErrors)r.createDiv({text:a});r.createEl("a",{cls:"pt-project-page-warning-link",text:"Open the config note"}).addEventListener("click",()=>{this.app.workspace.getLeaf(!1).openFile(e.configFile)})}renderBody(){let t=this.bodyEl,e=this.footerEl,s=this.currentProject();if(!t||!e||!s)return;t.empty(),e.empty();let r=this.currentView(s),o=this.host(s),a=this.plugin.store.getTasks(s.id),l=Jt(a,r.filters),c=qt(Jt(a,r.filters,this.search),r.sort,s.statusOrder),d=r.type==="kanban",u=d&&y.Platform.isPhone;t.toggleClass("is-board",d),t.toggleClass("is-table",!d),t.toggleClass("is-single",u),d?Ps(t,s,c,this.boardVisible(s,r),o,r.showDescription,this.columnCycle(s,r)):Es(t,s,c,r,o);let h=a.length-l.length;e.toggleClass("is-hidden",h===0),h>0&&e.setText(h===1?"1 task is hidden by these filters.":`${h} tasks are hidden by these filters.`)}host(t){return{project:t,collapsedGroups:this.collapsedGroups,resolveTask:e=>this.plugin.store.getTaskByPath(e),openTask:(e,s)=>{this.app.workspace.getLeaf(s).openFile(e.file)},editTask:e=>{new z(this.plugin,t,e).open()},showTaskMenu:(e,s)=>de(this.plugin,e,t,s),moveTask:(e,s)=>{Z(this.app,t,e,s)},createTask:e=>{new tt(this.app,this.plugin,t,e).open()},setSort:(e,s)=>{this.saveView(t,{...this.currentView(t),sort:{field:e,dir:s}})},toggleGroup:e=>{this.collapsedGroups.has(e)?this.collapsedGroups.delete(e):this.collapsedGroups.add(e),this.renderBody()}}}openViewEditor(t,e){let s=e!==null&&t.board.views.length>1;new Zt(this.app,t,e,r=>void this.saveView(t,r),s?()=>void this.deleteView(t,e.id):null).open()}async saveView(t,e){let s=[...t.board.views],r=s.findIndex(o=>o.id===e.id);r===-1?s.push(e):s[r]=e,this.activeViewId=e.id,await this.persist(t,{...t.board,views:s})}async deleteView(t,e){let s=t.board.views.filter(r=>r.id!==e);s.length&&(this.activeViewId===e&&(this.activeViewId=s[0].id),await this.persist(t,{...t.board,defaultView:t.board.defaultView===e?s[0].id:t.board.defaultView,views:s}))}async persist(t,e){try{await Xe(this.app,t,e),this.app.workspace.requestSaveLayout()}catch(s){console.error("Project Tracker: failed to save the board config",s),new y.Notice("Could not save the view \u2014 see the console for details.")}}};var I=require("obsidian");var F=require("obsidian");var Ms=require("obsidian"),ue=class extends Ms.AbstractInputSuggest{constructor(t,e,s){super(t,e);this.inputEl=e;this.onPick=s;this.limit=50}getSuggestions(t){let e=t.toLowerCase().trim(),s=this.app.vault.getAllFolders(!0);return(e?s.filter(o=>o.path.toLowerCase().includes(e)):s).sort((o,a)=>{if(e){let l=o.path.toLowerCase().startsWith(e),c=a.path.toLowerCase().startsWith(e);if(l!==c)return l?-1:1}return o.path.localeCompare(a.path)})}renderSuggestion(t,e){e.addClass("pt-folder-suggestion"),e.createDiv({text:t.path==="/"?"Vault root":t.path}),t.children.length?e.createEl("small",{cls:"pt-folder-suggestion-hint",text:`${t.children.length} item${t.children.length===1?"":"s"} inside`}):e.createEl("small",{cls:"pt-folder-suggestion-hint is-empty",text:"empty"})}selectSuggestion(t){let e=t.path==="/"?"":t.path;this.inputEl.value=e,this.inputEl.trigger("input"),this.onPick(t),this.close()}};var nt=class extends k{constructor(t,e){super(t,{header:"New Project"});this.plugin=e}name="";description="";color=kt;icon=A;folderPath="";folderEdited=!1;statusEl;createButton;onOpen(){let t=null;new F.SettingGroup(this.content).setHeading("General").addSetting(e=>{g(e).setName("Project name").addText(s=>{s.setPlaceholder("New project").onChange(r=>{this.name=r,!this.folderEdited&&t&&(this.folderPath=this.suggestedFolder(r),t.value=this.folderPath),this.validate()}),this.focusOnOpen(s.inputEl)}),se(this.app,e.controlEl,this.icon,s=>{this.icon=s})}).addSetting(e=>{e.setName("Project colour").setDesc("Used for the project's icon and card accent. Changeable later from the board."),ht(e.controlEl,this.color,s=>{this.color=s})}).addSetting(e=>{g(e).setName("Description").addTextArea(s=>s.setPlaceholder("What is this project for?").onChange(r=>{this.description=r}))}),new F.SettingGroup(this.content).setHeading("Location").addSetting(e=>{g(e).setName("Folder").setDesc("Must be empty. It will be created if it does not exist yet.").addText(s=>{t=s.inputEl,s.setPlaceholder("Projects/New project").onChange(r=>{this.folderEdited=!0,this.folderPath=r,this.validate()}),new ue(this.app,s.inputEl,()=>{this.folderEdited=!0,this.folderPath=s.inputEl.value,this.validate()})})}),this.statusEl=this.actionsLeft.createDiv({cls:"pt-modal-status"}),this.createButton=this.setPrimaryAction({text:"Create project",onClick:()=>void this.submit()}),this.validate()}suggestedFolder(t){let e=it(t);if(!e)return"";let s=this.plugin.settings.defaultProjectsFolder;return s?`${s}/${e}`:e}problem(){if(!this.name.trim())return"Give the project a name.";if(!it(this.name))return"That name has no usable characters for a file name.";if(!this.folderPath.trim())return"Choose a folder.";let t=this.app.vault.getAbstractFileByPath((0,F.normalizePath)(this.folderPath));return t?t instanceof F.TFolder?t.children.length?`"${t.path}" is not empty \u2014 projects need an empty folder.`:null:"That path is a file, not a folder.":null}validate(){let t=this.problem();this.statusEl.setText(t??""),this.statusEl.toggleClass("is-error",t!==null),this.createButton.setDisabled(t!==null)}async submit(){if(!this.problem()){this.createButton.setDisabled(!0);try{let t=(0,F.normalizePath)(this.folderPath),e=this.app.vault.getAbstractFileByPath(t);if(e||(e=await this.app.vault.createFolder(t)),!(e instanceof F.TFolder))throw new Error("Target path is not a folder.");let{configFile:s}=await ts(this.app,{name:this.name.trim(),description:this.description,color:this.color,icon:this.icon,folder:e,statuses:ns(this.plugin.settings)}),r=await this.plugin.awaitProject(s.path);r&&await this.seedExampleTasks(r),this.close(),await this.plugin.openProject(s.path)}catch(t){console.error("Project Tracker: failed to create project",t),new F.Notice(`Could not create the project \u2014 ${String(t)}`),this.createButton.setDisabled(!1)}}}async seedExampleTasks(t){let e=t.statusOrder[0]??"";await Ct(this.app,t,{name:"First Task",status:e,prioritized:!1,labels:[],parent:null,start:null,due:null,description:"Describe the first piece of work here.",custom:{}});let s=t.statuses[e]?.nextStatus;!s||s===e||!t.statuses[s]||await Ct(this.app,t,{name:"Second Task",status:s,prioritized:!1,labels:[],parent:null,start:null,due:null,description:"Work that is ready to be picked up sits here.",custom:{}})}};var Os=require("obsidian");var Vs={showDescription:!0,showCount:!0},pe=class extends k{constructor(t,e,s){super(t,{header:"Configure Projects"});this.onSave=s;this.draft={...e}}draft;onOpen(){new Os.SettingGroup(this.content).setHeading("Cards").addSetting(t=>{t.setName("Show description").setDesc("The first line of the project's description.").addToggle(e=>e.setValue(this.draft.showDescription).onChange(s=>{this.draft.showDescription=s}))}).addSetting(t=>{t.setName("Show task count").addToggle(e=>e.setValue(this.draft.showCount).onChange(s=>{this.draft.showCount=s}))}),this.addCancelAction(),this.setPrimaryAction({text:"Save",onClick:()=>{this.onSave(this.draft),this.close()}})}};var fe=class{constructor(n,t){this.container=n;this.commit=t;n.addEventListener("dragover",e=>{this.dragged&&(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"),this.slideTo(e.clientX,e.clientY))}),n.addEventListener("drop",e=>{this.dragged&&(e.preventDefault(),this.finish())})}items=[];dragged=null;from=-1;add(n){let t=this.items.length;this.items.push(n),n.draggable=!0,n.addEventListener("dragstart",e=>{this.dragged=n,this.from=t,e.dataTransfer?.setData("text/plain",String(t)),e.dataTransfer&&(e.dataTransfer.effectAllowed="move");let s=n.getBoundingClientRect();e.dataTransfer?.setDragImage(n,e.clientX-s.left,e.clientY-s.top),window.requestAnimationFrame(()=>{this.dragged===n&&n.addClass("is-placeholder")})}),n.addEventListener("dragend",()=>this.finish())}slideTo(n,t){let e=this.dragged;if(!e)return;let s=this.items.find(l=>{if(l===e)return!1;let c=l.getBoundingClientRect();return n>=c.left&&n<=c.right&&t>=c.top&&t<=c.bottom});if(!s)return;let r=s.getBoundingClientRect(),a=n>r.left+r.width/2?s.nextElementSibling:s;a===e||e.nextElementSibling===a||this.slide(()=>this.container.insertBefore(e,a))}slide(n){let t=new Map;for(let s of this.items)t.set(s,s.getBoundingClientRect());n();let e=[];for(let s of this.items){let r=t.get(s);if(!r)continue;let o=s.getBoundingClientRect(),a=r.left-o.left,l=r.top-o.top;!a&&!l||(s.setCssStyles({transition:"none",transform:`translate(${a}px, ${l}px)`}),e.push(s))}if(e.length){this.container.offsetWidth;for(let s of e)s.setCssStyles({transition:"",transform:""})}}finish(){let n=this.dragged;if(!n)return;this.dragged=null,n.removeClass("is-placeholder");let t=this.from;this.from=-1;let e=Array.prototype.indexOf.call(this.container.children,n);e===-1||e===t||this.commit(t,e)}};var Is=require("obsidian");function Ns(i,n,t,e,s,r){let o=i.createDiv({cls:"community-item",attr:{role:"button",tabindex:"0"}});o.style.setProperty("--pt-card-color",n.color);let a=o.createDiv({cls:"community-item-name"});return(0,Is.setIcon)(a.createSpan({cls:"pt-card-icon"}),n.icon),a.createSpan({text:n.title}),s==="page"?nr(o,n,t,e):rr(o,n,t,e),o.addEventListener("click",r),o.addEventListener("keydown",l=>{l.key!=="Enter"&&l.key!==" "||(l.preventDefault(),r())}),o}function nr(i,n,t,e){if(e.showDescription&&n.description&&i.createDiv({cls:"community-item-desc",text:n.description.split(`
`)[0]}),!e.showCount)return;let s=i.createDiv({cls:"pt-card-statuses"}),r=le(n,t,"status");if(!r.length){s.createSpan({cls:"pt-card-status is-empty",text:"No tasks"});return}for(let o of r){let a=s.createSpan({cls:"pt-card-status"});a.style.setProperty("--pt-status-color",o.color),a.createSpan({cls:"pt-status-dot"}),a.createSpan({text:o.name}),a.createSpan({cls:"pt-card-status-count",text:String(o.tasks.length)})}}function rr(i,n,t,e){e.showCount&&i.createDiv({cls:"community-item-author",text:`${t.length} task${t.length===1?"":"s"}`}),e.showDescription&&n.description&&i.createDiv({cls:"community-item-desc",text:n.description.split(`
`)[0]})}function As(i,n){let t=new Map(n.map((r,o)=>[r,o])),e=[],s=[];for(let r of i)(t.has(r.id)?e:s).push(r);return e.sort((r,o)=>(t.get(r.id)??0)-(t.get(o.id)??0)),[...e,...s]}var he=class extends I.ItemView{constructor(t,e){super(t);this.plugin=e}config={...Vs};unsubscribe=null;unsubscribeSettings=null;getViewType(){return N}getIcon(){return"folder-kanban"}getDisplayText(){return"Projects"}getState(){return{...this.config}}async setState(t,e){typeof t?.showDescription=="boolean"&&(this.config.showDescription=t.showDescription),typeof t?.showCount=="boolean"&&(this.config.showCount=t.showCount),this.render(),await super.setState(t,e)}get isDocked(){return this.leaf.getRoot()!==this.app.workspace.rootSplit}get isMobilePage(){return I.Platform.isMobile&&!this.isDocked}onPaneMenu(t,e){this.isMobilePage&&(t.addItem(s=>s.setSection("action").setTitle("New project").setIcon("plus").onClick(()=>new nt(this.app,this.plugin).open())),t.addItem(s=>s.setSection("action").setTitle("Configure this list").setIcon("sliders-horizontal").onClick(()=>this.configure())),t.addSeparator()),super.onPaneMenu(t,e)}async onOpen(){this.unsubscribe=this.plugin.store.onChange(()=>this.render()),this.unsubscribeSettings=this.plugin.onSettingsChange(()=>this.render()),this.render()}async onClose(){this.unsubscribe?.(),this.unsubscribe=null,this.unsubscribeSettings?.(),this.unsubscribeSettings=null}render(){let t=this.contentEl;if(t.empty(),t.addClass("pt-list-view"),this.isMobilePage||this.renderHeader(t),!this.plugin.store.ready){t.createDiv({cls:"pane-empty",text:"Loading\u2026"});return}let e=this.plugin.store.getProjects();if(!e.length){t.createDiv({cls:"pane-empty",text:"No projects yet. Create one against an empty folder \u2014 Project Tracker writes a config note, a Tasks folder and a first task."});return}let s=t.createDiv({cls:"community-modal-search-results"}),r=this.isDocked?"dock":"page",o=As(e,this.plugin.settings.projectOrder),a=this.isDocked?null:this.sortable(s,o);for(let l of o){let c=this.plugin.store.getTasks(l.id),d=Ns(s,l,c,this.config,r,()=>{this.plugin.openProject(l.configFile.path)});a?.add(d),this.isDocked||this.addCardMenu(d,l)}}addCardMenu(t,e){t.addEventListener("contextmenu",s=>{s.preventDefault();let r=new I.Menu;r.addItem(o=>o.setSection("action").setTitle("Open in new tab").setIcon("file-plus").onClick(()=>{this.plugin.openProject(e.configFile.path,{newTab:!0})})),r.addItem(o=>o.setSection("action").setTitle("Project configuration").setIcon(e.icon).onClick(()=>new et(this.app,this.plugin,e).open())),r.showAtMouseEvent(s)})}sortable(t,e){return t.addClass("pt-sortable"),new fe(t,(s,r)=>{let o=[...e],[a]=o.splice(s,1);o.splice(r,0,a),this.plugin.settings.projectOrder=o.map(l=>l.id),this.plugin.saveSettings()})}renderHeader(t){let e=t.createDiv({cls:"pt-list-header"});this.isDocked||(0,I.setIcon)(e.createSpan(),"folder-kanban"),e.createEl("h2",{cls:"pt-list-header-title",text:"Projects"}),this.isDocked||new m(e,{text:"New project",variant:"cta",onClick:()=>new nt(this.app,this.plugin).open()}),this.isDocked?new I.ExtraButtonComponent(e).setIcon("sliders-horizontal").setTooltip("Configure this list").onClick(()=>this.configure()):new m(e,{icon:"sliders-horizontal",tooltip:"Configure this list",class:"pt-btn-style-flat",onClick:()=>this.configure()})}configure(){new pe(this.app,this.config,t=>{this.config=t,this.app.workspace.requestSaveLayout(),this.render()}).open()}};var ve=require("obsidian");var Ne=require("obsidian");var ir={projectId:null,statusKey:null,showDescription:!1,showExtras:!0},me=class extends k{constructor(t,e,s,r){super(t,{header:"Configure Column"});this.projects=e;this.onSave=r;this.draft={...s}}draft;bodyEl;onOpen(){this.bodyEl=this.content.createDiv(),new m(this.actionsLeft,{text:"Clear",onClick:()=>{this.onSave({...ir}),this.close()}}),this.addCancelAction(),this.setPrimaryAction({text:"Save",onClick:()=>{this.onSave(this.draft),this.close()}}),this.renderBody()}renderBody(){if(this.bodyEl.empty(),!this.projects.length){this.bodyEl.createDiv({cls:"pane-empty",text:"No projects found in this vault."});return}let t=this.projects.find(e=>e.id===this.draft.projectId)??this.projects[0];this.draft.projectId=t.id,(!this.draft.statusKey||!t.statuses[this.draft.statusKey])&&(this.draft.statusKey=t.statusOrder[0]??null),new Ne.SettingGroup(this.bodyEl).setHeading("Source").addSetting(e=>{e.setName("Project").addDropdown(s=>{for(let r of this.projects)s.addOption(r.id,r.title);s.setValue(t.id).onChange(r=>{this.draft.projectId=r,this.draft.statusKey=null,this.renderBody()})})}).addSetting(e=>{e.setName("Status").setDesc("The one status this column lists.").addDropdown(s=>{for(let r of t.statusOrder)s.addOption(r,t.statuses[r]?.name??r);s.setValue(this.draft.statusKey??"").onChange(r=>{this.draft.statusKey=r})})}),new Ne.SettingGroup(this.bodyEl).setHeading("Cards").addSetting(e=>{e.setName("Show description").setDesc("The first line of the task's description, under its name.").addToggle(s=>s.setValue(this.draft.showDescription).onChange(r=>{this.draft.showDescription=r}))}).addSetting(e=>{e.setName("Show extras").setDesc("Labels, priority and due date, on the line under the name.").addToggle(s=>s.setValue(this.draft.showExtras).onChange(r=>{this.draft.showExtras=r}))})}};var or={field:"task-created",dir:"desc"},ge=class extends ve.ItemView{constructor(t,e){super(t);this.plugin=e}projectId=null;statusKey=null;showDescription=!1;showExtras=!0;unsubscribe=null;getViewType(){return U}getIcon(){return this.currentProject()?.icon??A}getDisplayText(){return this.currentStatus()?.name??"Task column"}getState(){return{projectId:this.projectId,statusKey:this.statusKey,showDescription:this.showDescription,showExtras:this.showExtras}}async setState(t,e){t?.projectId&&(this.projectId=t.projectId),t?.statusKey&&(this.statusKey=t.statusKey),typeof t?.showDescription=="boolean"&&(this.showDescription=t.showDescription),typeof t?.showExtras=="boolean"&&(this.showExtras=t.showExtras),this.render(),await super.setState(t,e)}async onOpen(){this.unsubscribe=this.plugin.store.onChange(()=>this.render()),this.render()}async onClose(){this.unsubscribe?.(),this.unsubscribe=null}currentProject(){return this.projectId?this.plugin.store.getProjectById(this.projectId):null}currentStatus(){let t=this.currentProject();return!t||!this.statusKey?null:t.statuses[this.statusKey]??null}render(){let t=this.contentEl;if(t.empty(),t.addClass("pt-column-view"),!this.plugin.store.ready)return;let e=this.currentProject(),s=this.currentStatus();if(!e||!s){this.renderHeader(null,null,null),this.renderUnset(t,e);return}let r=qt(this.plugin.store.getTasks(e.id).filter(l=>l.status===this.statusKey),or,e.statusOrder);this.renderHeader(e,s,r.length);let o=t.createDiv({cls:"pt-column-view-body"});if(!r.length){o.createDiv({cls:"pane-empty",text:"Nothing here"});return}let a=this.actions(e);for(let l of r)mt(o,e,l,a,{showDescription:this.showDescription,showExtras:this.showExtras,display:"dock"})}renderHeader(t,e,s){let r=this.contentEl.createDiv({cls:"pt-column-view-header"}),o=r.createDiv({cls:"pt-column-view-heading"});e&&o.createSpan({cls:"pt-status-dot"}).style.setProperty("--pt-status-color",e.color),o.createSpan({cls:"pt-column-view-name",text:e?.name??"Not configured"}),s!==null&&o.createSpan({cls:"pt-column-view-count",text:String(s)}),new ve.ExtraButtonComponent(o).setIcon("sliders-horizontal").setTooltip("Configure this column").onClick(()=>this.configure()),t&&r.createDiv({cls:"pt-column-view-project",text:t.title})}renderUnset(t,e){let s="Choose a project and a status to show here.";this.projectId&&!e?s="That project is no longer in the vault.":e&&this.statusKey&&(s="That status is no longer in this project's config.");let r=t.createDiv({cls:"pane-empty pt-column-view-unset"});r.createDiv({text:s}),new m(r,{text:"Configure",variant:"cta",onClick:()=>this.configure()})}configure(){new me(this.app,this.plugin.store.getProjects(),{projectId:this.projectId,statusKey:this.statusKey,showDescription:this.showDescription,showExtras:this.showExtras},t=>{this.projectId=t.projectId,this.statusKey=t.statusKey,this.showDescription=t.showDescription,this.showExtras=t.showExtras,this.leaf.setViewState({type:U,state:this.getState()}),this.app.workspace.requestSaveLayout(),this.render()}).open()}actions(t){return{resolveTask:e=>this.plugin.store.getTaskByPath(e),openTask:(e,s)=>{this.app.workspace.getLeaf(s).openFile(e.file)},editTask:e=>{new z(this.plugin,t,e).open()},showTaskMenu:(e,s)=>de(this.plugin,e,t,s)}}};var Bs=require("obsidian"),Ft=class extends Bs.SuggestModal{constructor(t,e,s){super(t);this.projects=e;this.onChoose=s;this.setPlaceholder("Search projects\u2026")}getSuggestions(t){let e=t.toLowerCase();return this.projects.filter(s=>s.title.toLowerCase().includes(e)||s.folder.path.toLowerCase().includes(e))}renderSuggestion(t,e){e.createDiv({text:t.title}),e.createEl("small",{cls:"pt-suggest-path",text:t.folder.path})}onChooseSuggestion(t){this.onChoose(t)}};var ar=6*60*60*1e3,lr=i=>new Promise(n=>window.setTimeout(n,i)),Hs="pt-view-active",cr=new Set([G,N,U]),ye=class extends vt.Plugin{store;settingsListeners=new Set;settingTab;async onload(){await this.loadSettings(),this.store=new Wt(this.app,this),this.store.registerEvents(),this.registerView(G,n=>new Lt(n,this)),this.registerView(N,n=>new he(n,this)),this.registerView(U,n=>new ge(n,this)),this.addRibbonIcon("folder-kanban","Projects",()=>void this.openProjectList()),this.settingTab=new _t(this.app,this),this.addSettingTab(this.settingTab),this.registerCommands(),this.app.workspace.onLayoutReady(()=>{this.store.reindexAll().then(()=>this.repairProjectLinks()).then(()=>void this.runAutoStatusChange())}),this.registerInterval(window.setInterval(()=>void this.runAutoStatusChange(),ar)),this.registerEvent(this.app.workspace.on("active-leaf-change",()=>this.markPluginView())),this.registerEvent(this.app.workspace.on("layout-change",()=>this.markPluginView())),this.app.workspace.onLayoutReady(()=>this.markPluginView())}onunload(){document.body.removeClass(Hs)}markPluginView(){let t=this.app.workspace.getMostRecentLeaf(this.app.workspace.rootSplit)?.view.getViewType();document.body.toggleClass(Hs,cr.has(t??""))}registerCommands(){this.addCommand({id:"new-project",name:"New project",callback:()=>new nt(this.app,this).open()}),this.addCommand({id:"new-task",name:"New task",callback:()=>this.promptNewTask()}),this.addCommand({id:"show-projects-leaflet",name:"Open project list dock",callback:()=>void this.openProjectsLeaflet()}),this.addCommand({id:"open-task-column",name:"Open project tasks dock",callback:()=>void this.openTaskColumn()}),this.addCommand({id:"open-projects",name:"Open projects list",callback:()=>void this.openProjectList()}),this.addCommand({id:"open-project",name:"Open project\u2026",callback:()=>{let n=this.store.getProjects();if(!n.length){new vt.Notice("No projects found yet.");return}new Ft(this.app,n,t=>{this.openProject(t.configFile.path)}).open()}})}promptNewTask(){let n=this.activeProject();if(n){new tt(this.app,this,n).open();return}let t=this.store.getProjects();if(!t.length){new vt.Notice("Create a project before adding tasks.");return}new Ft(this.app,t,e=>{new tt(this.app,this,e).open()}).open()}activeProject(){let t=this.app.workspace.getActiveViewOfType(Lt)?.getState().projectPath;if(typeof t=="string"){let s=this.store.getProjectByConfigPath(t);if(s)return s}let e=this.app.workspace.getActiveFile();return e?this.store.getProjectForFile(e):null}async openProject(n,t={}){let e=t.newTab?this.app.workspace.getLeaf("tab"):this.projectLeaf(n);await e.setViewState({type:G,active:!0,state:{projectPath:n}}),await this.app.workspace.revealLeaf(e)}projectLeaf(n){let t=this.app.workspace.getLeavesOfType(G),e=t.find(r=>r.view.getState().projectPath===n);return e||(this.settings.replaceProjectPages?t.find(r=>r.getRoot()===this.app.workspace.rootSplit)??this.app.workspace.getLeaf("tab"):this.app.workspace.getLeaf("tab"))}async openProjectList(){let t=this.app.workspace.getLeavesOfType(N).find(e=>e.getRoot()===this.app.workspace.rootSplit)??this.app.workspace.getLeaf("tab");await t.setViewState({type:N,active:!0}),await this.app.workspace.revealLeaf(t)}async openProjectsLeaflet(){let n=this.app.workspace.getLeavesOfType(N).find(e=>e.getRoot()!==this.app.workspace.rootSplit);if(n){await this.app.workspace.revealLeaf(n);return}let t=this.app.workspace.getRightLeaf(!1);t&&(await t.setViewState({type:N,active:!0}),await this.app.workspace.revealLeaf(t))}async awaitProject(n,t=4e3){let e=Date.now()+t;for(;Date.now()<e;){let s=this.store.getProjectByConfigPath(n);if(s)return s;await lr(100)}return null}async repairProjectLinks(){if(!this.settings.repairProjectLinks)return;let n=new Map(this.store.getProjects().map(t=>[t.id,t]));for(let t of this.store.getAllTasks()){let e=n.get(t.projectId);e&&await cs(this.app,e,t)}}async openTaskColumn(){let n=this.app.workspace.getRightLeaf(!0);n&&(await n.setViewState({type:U,active:!0}),await this.app.workspace.revealLeaf(n))}async runAutoStatusChange(){if(!this.settings.autoStatusChange)return;let n=0;for(let t of this.store.getProjects())for(let e of this.store.getTasks(t.id)){let s=t.statuses[e.status];if(!s?.nextStatus||!t.statuses[s.nextStatus])continue;let r=ut(s.autoStatusChange);if(r===null)continue;let o=v(e.statusModified);!o||Date.now()-o.getTime()<r||(await Z(this.app,t,e,s.nextStatus),n++)}n&&new vt.Notice(`Advanced ${n} task${n===1?"":"s"} on schedule.`)}async loadSettings(){let n=await this.loadData()??{},t={...ss};for(let e of Object.keys(t))e in n&&Object.assign(t,{[e]:n[e]});this.settings=t}async onExternalSettingsChange(){await this.loadSettings(),this.notifySettingsChange()}onSettingsChange(n){return this.settingsListeners.add(n),()=>this.settingsListeners.delete(n)}async saveSettings(){await this.saveData(this.settings),this.notifySettingsChange()}notifySettingsChange(){for(let n of this.settingsListeners)n();this.settingTab.update()}};