var OS;!function(t){let e;!function(e){let i;!function(e){class i extends t.GUI.BasicDialog{constructor(){super("OwnerDialog",i.scheme)}main(){if(super.main(),this.oview=this.find("ownview"),!this.data.dbhandle)throw new Error(__("Unable to get owner data handle").__());return this.oview.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:async t=>{try{const t=await this.openDialog("PromptDialog",{title:__("Owner"),label:__("Name")});this.data.dbhandle.cache={name:t};const e=await this.data.dbhandle.write(void 0);if(e.error)throw new Error(e.error);await this.owner_refresh()}catch(t){this.error(t.toString(),t)}}},{text:"",iconclass:"fa fa-minus-circle",onbtclick:async t=>{try{const t=this.oview.selectedItem;if(!t)return;if(!await this.ask({text:__("Do you realy want to delete: `{0}`",t.data.text)}))return;const e=t.data.$vfs;let i=await e.remove();if(i.error)throw new Error(i.error.toString());await this.owner_refresh()}catch(t){this.error(t.toString(),t)}}},{text:"",iconclass:"fa fa-pencil-square-o",onbtclick:async t=>{try{const t=this.oview.selectedItem;if(!t)return;const e=await this.openDialog("PromptDialog",{title:__("Owner"),label:__("Name"),value:t.data.name}),i=t.data.$vfs;i.cache={name:e};const a=await i.write(void 0);if(a.error)throw new Error(a.error.toString());await this.owner_refresh()}catch(t){this.error(t.toString(),t)}}}],this.owner_refresh()}async owner_refresh(){const t=await this.data.dbhandle.read();for(let e of t)e.text=e.name;this.oview.data=t}}e.OwnerDialog=i,i.scheme="\n \n \n \n ";class a extends t.GUI.BasicDialog{constructor(){super("DocDialog",a.scheme)}main(){let t;super.main(),this.flist=this.find("file-list"),this.dlist=this.find("dlist"),this.mlist=this.find("mlist"),this.ylist=this.find("ylist"),this.olist=this.find("olist");const e=this.parent;`sqlite://${e.setting.docpath.asFileHandle().genealogy.join("/")}/docify.db@owners`.asFileHandle().read().then(t=>{if(t.error)return this.error(t.error);for(let e of t)e.text=e.name,e.selected=this.data&&this.data.oid===e.id;return this.olist.data=t,this.olist.selectedItem?void 0:this.olist.selected=0}).catch(t=>this.error(__("Unable to fetch owner list: {0}",t.toString()),t)),this.dlist.push({text:"None",value:0});let i=0;for(t=1;t<=31;t++)this.dlist.push({text:""+t,value:t}),this.data&&parseInt(this.data.day)===t&&(i=t);for(this.dlist.selected=i,this.mlist.push({text:"None",value:0}),i=0,t=1;t<=12;t++)this.mlist.push({text:""+t,value:t}),this.data&&parseInt(this.data.month)===t&&(i=t);this.mlist.selected=i,this.ylist.push({text:"None",value:0}),this.ylist.selected=0;for(let t=1960,e=(new Date).getFullYear(),i=1960<=e;i?t<=e:t>=e;i?t++:t--)this.ylist.push({text:""+t,value:t,selected:this.data&&parseInt(this.data.year)===t});if(this.flist.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:t=>this.openDialog(new r,{app:e}).then(t=>(t.text=t.filename,this.flist.push(t)))},{text:"",iconclass:"fa fa-minus-circle",onbtclick:t=>{const e=this.flist.selectedItem;if(e)return this.flist.delete(e)}}],this.flist.onlistselect=async t=>await e.preview(t.data.item.data.path,this.find("preview-canvas")),this.find("btsave").onbtclick=t=>{const e={name:this.find("title").value.trim(),day:this.dlist.selectedItem.data.value,month:this.mlist.selectedItem.data.value,year:this.ylist.selectedItem.data.value,file:Array.from(this.flist.data).map(t=>t.path),note:this.find("note").value.trim(),tags:this.find("tag").value.trim(),oid:parseInt(this.olist.selectedItem.data.id)};return e.name&&""!==e.title?e.file.length>0?(this.handle&&this.handle(e),this.quit()):this.notify(__("Please attach files to the entry")):this.notify(__("Please enter title"))},!this.data)return;this.find("title").value=this.data.name,this.find("note").value=this.data.note,this.find("tag").value=this.data.tags;const a=this.data.file.asFileHandle();return a.text=a.filename,this.flist.data=[a]}}e.DocDialog=a,a.scheme='\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n ';class r extends t.GUI.BasicDialog{constructor(){super("FilePreviewDialog",r.scheme)}main(){super.main(),this.flist=this.find("file-list"),this.flist.buttons=[{text:"",iconclass:"fa fa-refresh",onbtclick:t=>this.refresh()}];const t=this.data.app;return this.flist.onlistselect=async e=>await t.preview(e.data.item.data.path,this.find("preview-canvas")),this.find("btok").onbtclick=t=>{const e=this.flist.selectedItem;return e?(this.handle&&this.handle(e.data),this.quit()):this.quit()},this.refresh()}async refresh(){try{const t=this.data.app,e=await(t.setting.docpath+"/unclassified").asFileHandle().read();if(e.error)return this.error(e.error);for(let t of e.result)t.text=t.filename;return this.flist.data=e.result.filter(t=>"."!==t.filename[0])}catch(t){return this.error(__("Unable to fetch unclassified file list: {0}",t.toString()),t)}}}e.FilePreviewDialog=r,r.scheme='\n \n \n \n \n \n \n \n \n
\n \n \n \n \n '}(i=e.docify||(e.docify={}))}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(t){class e extends t.BaseApplication{constructor(t){super("Docify",t)}async init_db(){try{if(!this.setting.docpath)return this.error(__("No configured docpath"));const t=this.setting.docpath.asFileHandle();this.dbhandle=`sqlite://${t.genealogy.join("/")}/docify.db`.asFileHandle();const e=await this.dbhandle.read();await(""+this.setting.docpath).asFileHandle().mk("unclassified"),await(""+this.setting.docpath).asFileHandle().mk("cache");let i=void 0;if(this.catdb=(this.dbhandle.path+"@categories").asFileHandle(),!e.categories){if(this.dbhandle.cache={name:"TEXT"},i=await this.dbhandle.write("categories"),i.error)throw new Error(i.error);if(this.catdb.cache={name:"Uncategoried"},i=await this.catdb.write(void 0),i.error)throw new Error(i.error)}if(this.ownerdb=(this.dbhandle.path+"@owners").asFileHandle(),!e.owners){if(this.dbhandle.cache={name:"TEXT"},i=await this.dbhandle.write("owners"),i.error)throw new Error(i.error);if(this.ownerdb.cache={name:"None"},i=await this.ownerdb.write(void 0),i.error)throw new Error(i.error)}if(this.docdb=(this.dbhandle.path+"@docs").asFileHandle(),!e.docs&&(this.dbhandle.cache={name:"TEXT NOT NULL",ctime:"INTEGER",day:"INTEGER",month:"INTEGER",year:"INTEGER",cid:"INTEGER DEFAULT 0",oid:"INTEGER DEFAULT 0",file:"TEXT NOT NULL",tags:"TEXT",note:"TEXT",mtime:"INTEGER"},i=await this.dbhandle.write("docs"),i.error))throw new Error(i.error);return await this.cat_refresh()}catch(t){this.error(__("Unable to init database file: {0}",t.toString()),t),this.dbhandle=void 0}}main(){return this.setting.printer||(this.setting.printer=""),pdfjsLib.GlobalWorkerOptions.workerSrc="pkg://libpdfjs/pdf.worker.js".asFileHandle().getlink(),this.catview=this.find("catview"),this.docview=this.find("docview"),this.docpreview=this.find("preview-canvas"),this.docgrid=this.find("docgrid"),this.docgrid.header=[{text:"",width:100},{text:""}],this.find("btdld").onbtclick=async t=>{try{const t=this.docview.selectedItem;if(!t)return;await t.data.file.asFileHandle().download()}catch(t){this.error(__("Unable to download: {0}",t.toString()),t)}},this.find("btopen").onbtclick=async t=>{try{const t=this.docview.selectedItem;if(!t)return;const e=await t.data.file.asFileHandle().meta();if(e.error)throw new Error(e.error);return this._gui.openWith(e.result)}catch(t){this.error(__("Unable to open file: {0}",t.toString()),t)}},this.catview.buttons=[{text:"",iconclass:"fa fa-plus-circle",onbtclick:async t=>{try{const t=await this.openDialog("PromptDialog",{title:__("Category"),label:__("Name")});this.catdb.cache={name:t};const e=await this.catdb.write(void 0);if(e.error)throw new Error(e.error.toString());return await this.cat_refresh()}catch(t){this.error(__("Unable to insert category: {0}",t.toString()),t)}}},{text:"",iconclass:"fa fa-minus-circle",onbtclick:async t=>{try{const t=this.catview.selectedItem;if(!t)return;if(!await this.ask({text:__("Do you realy want to delete: `{0}`",t.data.text)}))return;const e=await this.catdb.remove({where:{id:t.data.id}});if(e.error)throw new Error(e.error.toString());await this.cat_refresh()}catch(t){this.error(__("Unable delete category: {0}",t.toString()),t)}}},{text:"",iconclass:"fa fa-pencil-square-o",onbtclick:async t=>{try{const t=this.catview.selectedItem;if(!t)return;const e=t.data;if(!e)return;const i=await this.openDialog("PromptDialog",{title:__("Category"),label:__("Name"),value:t.data.name}),a=e.$vfs;a.cache={id:parseInt(t.data.id),name:i};const r=await a.write(void 0);if(r.error)throw new Error(r.error.toString());await this.cat_refresh()}catch(t){this.error(__("Unable to update category: {0}",t.toString()),t)}}}],this.docview.onlistselect=async t=>{try{this.clear_preview();const e=t.data.item;if(!e)return;const i=e.data.$vfs,a=await i.read();await this.preview(a.file,this.docpreview);const r=[],s={ctime:"Created on",mtime:"Modified on",note:"Note",tags:"Tags",name:"Title",owner:"Owner",edate:"Effective date",file:"File",size:"Size"};a.edate=`${a.day}/${a.month}/${a.year}`;for(let t in a){let e=a[t];const i=s[t];"ctime"!==t&&"mtime"!=t||(e=new Date(1e3*e).toDateString()),i&&r.push([{text:i},{text:e}])}return this.docgrid.rows=r}catch(t){this.error(__("Unable to fetch document detail: {0}",t.toString()),t)}},this.catview.onlistselect=t=>{this.clear_preview();const e=t.data.item;if(e)return this.update_doclist(e.data.id)},this.find("bt-add-doc").onbtclick=async e=>{try{const e=this.catview.selectedItem;if(!e)return this.notify(__("Please select a category"));const i=await this.openDialog(new t.docify.DocDialog);i.cid=parseInt(e.data.id);const a=Math.floor(Date.now()/1e3);i.ctime=a,i.mtime=a;const r=await this.merge_files(i);i.file=r.path,this.docdb.cache=i;const s=await this.docdb.write(void 0);if(s.error)throw new Error(s.error.toString());s.result&&this.toast(s.result),this.update_doclist(e.data.id),this.clear_preview()}catch(t){this.error(__("Unable to add document: {0}",t.toString()),t)}},this.find("bt-del-doc").onbtclick=async t=>{try{const t=this.docview.selectedItem;if(!t)return;if(!await this.ask({text:__("Do you really want to delete: `{0}`",t.data.name)}))return;let e=await this.docdb.remove({where:{id:t.data.id}});if(e.error)throw new Error(e.error.toString());try{await t.data.file.asFileHandle().remove();const e=await this.get_thumb_path(t.data.file);await e.asFileHandle().remove()}catch(t){console.log(t)}return this.update_doclist(t.data.cid),this.clear_preview()}catch(t){this.error(__("Unable to delete document: {0}",t.tostring()),t)}},this.find("bt-upload-doc").onbtclick=async t=>{try{await(this.setting.docpath+"/unclassified").asFileHandle().upload(),this.toast(__("File uploaded"))}catch(t){this.error(__("Unable to upload document: {0}",t.toString()),t)}},this.find("bt-edit-doc").onbtclick=async e=>{try{const e=this.docview.selectedItem,i=this.catview.selectedItem;if(!e)return;const a=await this.openDialog(new t.docify.DocDialog,e.data);a.cid=parseInt(i.data.id),a.id=e.data.id;const r=Math.floor(Date.now()/1e3);if(a.mtime=r,a.file.includes(e.data.file)&&1==a.file.length)a.file=e.data.file;else{if(!a.file.includes(e.data.file))try{console.log("remove old file",e.data.file),await e.data.file.asFileHandle().remove();const t=await this.get_thumb_path(e.data.file);await t.asFileHandle().remove()}catch(t){console.log(t)}const t=await this.merge_files(a);a.file=t.path}a.mtime=Math.floor(Date.now()/1e3);const s=e.data.$vfs;s.cache=a;const n=await s.write(void 0);if(n.error)throw new Error(n.error);return this.toast(__("Document updated")),this.update_doclist(i.data.id),this.clear_preview()}catch(t){this.error(__("Unable to edit document metadata: {0}",t.toString()))}},this.initialize()}async get_thumb_path(t){const e=t.asFileHandle().path;let i=await this.sha1(e.replace(this.setting.docpath,""));return`${this.setting.docpath}/cache/${i}.png`}async merge_files(t){const e=t.file,i=t.cid.toFixed(1).toString(),a=`${this.setting.docpath}/${i}`.asFileHandle();try{await a.onready()}catch(t){const e=await a.parent().mk(i);if(e.error)throw new Error(e.error.toString());await a.onready()}const r=`${a.path}/${new Date(Date.now()).getTime().toString()}.pdf`.asFileHandle(),s=await PDFLib.PDFDocument.create();let n=[];for(const t of e){const e=await t.asFileHandle().read("binary"),i=await PDFLib.PDFDocument.load(e,{ignoreEncryption:!0}),a=await s.copyPages(i,i.getPageIndices());n=n.concat(a)}for(let t=0;tt.toString(16).padStart(2,"0")).join("")}async genthumb(t){const e=(await this.get_thumb_path(t)).asFileHandle();try{await e.onready()}catch(i){console.log("Try to generate thumb file for",t);const a=this.find("tmp-canvas"),r=a.getContext("2d"),s=await pdfjsLib.getDocument(t.asFileHandle().getlink()).promise,n=await s.getPage(1),o=n.getViewport({scale:.33}),l=window.devicePixelRatio||1;a.width=Math.floor(o.width*l),a.height=Math.floor(o.height*l),a.style.width=Math.floor(o.width)+"px",a.style.height=Math.floor(o.height)+"px";const d={canvasContext:r,transform:1!==l?[l,0,0,l,0,0]:null,viewport:o};await n.render(d).promise;const h=a.toDataURL("image/png");e.cache=h;const c=await e.write("base64");if(c.error)throw new Error(c.error.toString());await e.onready()}return e}async preview(t,e){try{const i=await this.genthumb(t),a=await i.read("binary"),r=new Image;r.onload=()=>{const t=e.getContext("2d");return e.height=r.height,e.width=r.width,t.drawImage(r,0,0)};const s=new Blob([a],{type:i.info.mime});return r.src=URL.createObjectURL(s)}catch(t){this.error(__("Unable to generate document thumbnail: {0}",t.toString()),t)}}cat_refresh(){return new Promise(async(t,e)=>{try{this.docview.data=[],this.clear_preview();const t=await this.catdb.read();for(let e of t)e.text=e.name;return this.catview.data=t}catch(t){e(__e(t))}})}async initialize(){try{if(this.setting.docpath)return await this.init_db();{const t=await this.openDialog("FileDialog",{title:__("Please select a doc path"),type:"dir"});return this.setting.docpath=t.file.path,await this.init_db()}}catch(t){this.error(__("Error initialize database: {0}",t.toString()),t)}}menu(){return[{text:"__(Options)",nodes:[{text:"__(Owners)",id:"owners"},{text:"__(Preview)",id:"preview"},{text:"__(Change doc path)",id:"setdocp"}],onchildselect:t=>this.fileMenuHandle(t.data.item.data.id)}]}fileMenuHandle(e){switch(e){case"owners":return this.openDialog(new t.docify.OwnerDialog,{title:__("Owners"),dbhandle:this.ownerdb});case"preview":return this.openDialog(new t.docify.FilePreviewDialog,{app:this}).then(t=>this.notify(t.path));case"setdocp":return this.setting.docpath=void 0,this.initialize()}}}t.Docify=e,e.dependencies=["pkg://SQLiteDB/libsqlite.js","pkg://libpdfjs/pdf.js","pkg://PDFLib/main.js"]}(e=t.application||(t.application={}))}(OS||(OS={}));