diff --git a/About/build/release/About.zip b/About/build/release/About.zip index 3e18c49..c567b9d 100644 Binary files a/About/build/release/About.zip and b/About/build/release/About.zip differ diff --git a/Antedit/README.md b/Antedit/README.md index eddd226..3d7cca6 100644 --- a/Antedit/README.md +++ b/Antedit/README.md @@ -5,6 +5,7 @@ the editor that powers VS Code. The editor functionality can be extended by its extension mechanism. Extension can be developed/released/isntalled by the editor itself. ### Change logs +- 0.2.5-b: Fix setting bug with new AntOS setting API - 0.2.3-b: Minor changes to adapt the core UI to the new AntOS 2.0.x - 0.2.3-b: Allow reload current file via context menu in case of external changes - 0.2.2-b: Support horizotal scrolling on horizotal tabbars diff --git a/Antedit/build/debug/README.md b/Antedit/build/debug/README.md index eddd226..3d7cca6 100644 --- a/Antedit/build/debug/README.md +++ b/Antedit/build/debug/README.md @@ -5,6 +5,7 @@ the editor that powers VS Code. The editor functionality can be extended by its extension mechanism. Extension can be developed/released/isntalled by the editor itself. ### Change logs +- 0.2.5-b: Fix setting bug with new AntOS setting API - 0.2.3-b: Minor changes to adapt the core UI to the new AntOS 2.0.x - 0.2.3-b: Allow reload current file via context menu in case of external changes - 0.2.2-b: Support horizotal scrolling on horizotal tabbars diff --git a/Antedit/build/debug/main.js b/Antedit/build/debug/main.js index 99b3c5a..c49c98c 100644 --- a/Antedit/build/debug/main.js +++ b/Antedit/build/debug/main.js @@ -1 +1 @@ -var OS;!function(t){let e,i;!function(e){let i;!function(e){class i extends t.API.VFS.BaseFileHandle{constructor(t){super(""),this.path=`${t[0].path} -> ${t[1].path}`,this.cache=t,this.basename=`${t[0].basename} -> ${t[1].basename}`,this.info={type:"file",mime:void 0,size:0,name:this.basename,path:this.path},this.ready=!0}meta(){return new Promise(async(t,e)=>{try{await Promise.all([this.cache[0].meta(),this.cache[1].meta]),t({result:this.info,error:!1})}catch(t){e(t)}})}_rd(t){return new Promise(async(t,e)=>{try{this.cache[0].cache=await this.cache[0].read(),this.cache[1].cache=await this.cache[1].read(),t(this.cache)}catch(t){e(t)}})}_wr(t){return new Promise((t,e)=>{t({result:!0,error:!1})})}setPath(t){}}e.DiffEditorFileHandle=i}(i=e.VFS||(e.VFS={}))}(e=t.API||(t.API={})),function(t){t.BaseEditorModel=class{constructor(t,e,i){this.container=i,this.currfile="Untitled".asFileHandle(),this.tabbar=e,this.editorSetup(i),this.app=t,this.editormux=!1,this.onstatuschange=void 0,this.on("focus",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.on("input",()=>this.editormux?(this.editormux=!1,!1):this.currfile.dirty?void 0:(this.currfile.dirty=!0,this.currfile.text+="*",this.tabbar.update(void 0))),this.on("changeCursor",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.tabbar.ontabselect=t=>this.selecteTab($(t.data.item).index()),this.tabbar.ontabclose=t=>{const e=t.data.item;return!!e&&(e.data.dirty?(this.app.openDialog("YesNoDialog",{title:__("Close tab"),text:__("Close without saving ?")}).then(t=>t?this.closeTab(e):this.focus()),!1):this.closeTab(e))}}findTabByFile(t){const e=this.tabbar.items,i=(()=>{const i=[];for(let a=0;a(t.cache=e||"",this.newTab(t))).catch(e=>this.app.error(__("Unable to open: {0}",t.path),e)):this.newTab(t):this.tabbar.selected=e}write(){this.currfile.cache=this.getValue(),this.currfile.write("text/plain").then(t=>{this.currfile.dirty=!1,this.currfile.text=this.currfile.basename,this.tabbar.update(void 0)}).catch(t=>this.app.error(__("Unable to save file: {0}",this.currfile.path),t))}save(){return this.currfile.cache=this.getValue(),this.currfile.basename?this.write():this.saveAs()}reload(){return new Promise(async(t,e)=>{try{if("Untitled"===this.currfile.path.toString())return t(!0);if(this.currfile.dirty&&!await this.app.openDialog("YesNoDialog",{title:__("File modified"),text:__("Continue without saving ?")}))return t(!0);const e=await this.currfile.read();this.currfile.cache=e||"",this.currfile.dirty=!1,this.currfile.text=this.currfile.basename?this.currfile.basename:this.currfile.path,this.editormux=!0,this.setValue(this.currfile.cache),this.tabbar.update(void 0)}catch(t){this.app.error(__("Unable to open: {0}",this.currfile.path),t),e(t)}})}saveAs(){this.app.openDialog("FileDialog",{title:__("Save as"),file:this.currfile}).then(t=>{let e=t.file.path.asFileHandle();"file"===t.file.type&&(e=e.parent()),this.currfile.setPath(`${e.path}/${t.name}`),this.write()})}dirties(){const t=[];for(let e of Array.from(this.tabbar.items))e.dirty&&t.push(e);return t}set contextmenuHandle(t){this.container.contextmenuHandle=t}closeAll(){this.tabbar.items=[],this.openFile("Untitled".asFileHandle()),this.resetEditor()}isDirty(){return this.dirties().length>0}setTabbarCtxMenu(t,e){this.tabbar.contextmenuHandle=(i,a)=>(a.items=t,a.onmenuselect=t=>{if(e){const a=$(i.target).closest("afx-list-item");e(a[0],t.data.item.data)}},a.show(i))}}}(i=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(e){class i extends t.application.BaseEditorModel{constructor(t,e,i){super(t,e,i)}resetEditor(){}getTexModel(){return{model:this.editor.getModel(),position:this.editor.getPosition()}}setTextModel(t){this.editor.setModel(t.model),t.position&&(this.editor.setPosition(t.position),this.editor.revealLineInCenter(t.position.lineNumber)),this.editor==this._code_editor&&this.editor.updateOptions({readOnly:!1,domReadOnly:!1})}newTextModelFrom(t){if(Array.isArray(t.cache))return{model:{original:this.newTextModelFrom(t.cache[0]).model,modified:this.newTextModelFrom(t.cache[1]).model}};{if("Untitled"===t.path.toString())return{model:monaco.editor.createModel(t.cache,"textplain")};const e=monaco.Uri.parse(t.protocol+"://antedit/file/"+t.genealogy.join("/")),i=monaco.editor.getModel(e);return i?(i.setValue(t.cache),{model:i}):{model:monaco.editor.createModel(t.cache,void 0,e)}}}getModes(){return monaco.languages.getLanguages().map(t=>{const e=t;return t.aliases?e.text=t.aliases[0]:e.text=t.id,t})}setTheme(t){}setMode(t){if(this.editor==this._code_editor)monaco.editor.setModelLanguage(this.editor.getModel(),t.id);else for(const e of this.editor.getModel())monaco.editor.setModelLanguage(e,t.id);this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}get editor(){return Array.isArray(this.currfile.cache)?this._diff_editor:this._code_editor}editorSetup(t){this.code_container=$("
").css("width","100%").css("height","100%"),this.diff_container=$("
").css("width","100%").css("height","100%").css("display","none"),$(t).append(this.code_container),$(t).append(this.diff_container),this._code_editor=monaco.editor.create(this.code_container[0],{value:"",language:"textplain",readOnly:!1,domReadOnly:!1}),this._diff_editor=monaco.editor.createDiffEditor(this.diff_container[0],{readOnly:!0}),i.modes||(i.modes={},monaco.languages.getLanguages().forEach(t=>{i.modes[t.id]=t}))}on(t,e){switch(t){case"input":this._code_editor.onDidChangeModelContent(e);break;case"focus":this._code_editor.onDidFocusEditorText(e),this._diff_editor.getOriginalEditor().onDidFocusEditorText(e),this._diff_editor.getModifiedEditor().onDidFocusEditorText(e);break;case"changeCursor":this._code_editor.onDidChangeCursorPosition(e),this._diff_editor.getOriginalEditor().onDidChangeCursorPosition(e),this._diff_editor.getModifiedEditor().onDidChangeCursorPosition(e)}}resize(){this.editor&&this.editor.layout()}focus(){Array.isArray(this.currfile.cache)?(this.code_container.hide(),this.diff_container.show()):(this.code_container.show(),this.diff_container.hide()),this.editor&&(this.editor.layout(),this.editor.focus())}getModeForPath(t){return{}}getEditorStatus(){let t=void 0;this.editor==this._code_editor?t=this.editor:(t=this.editor.getOriginalEditor(),this.editor.getModifiedEditor().hasTextFocus()&&(t=this.editor.getModifiedEditor()));const e=t.getPosition();let a=void 0;const s=t.getModel();return s&&(a=i.modes[s.getLanguageId()]),{row:e.lineNumber,column:e.column,line:s?s.getLineCount():0,langmode:{text:a?a.aliases[0]:"",mode:a},file:this.currfile.path}}getValue(){return this.editor==this._code_editor?this.editor.getValue():this.currfile.cache}setValue(t){this.editor==this._code_editor&&this.editor.setValue(t)}getEditor(){return this._code_editor}}e.MonacoEditorModel=i}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e,i;!function(t){let e;!function(t){class e extends t.ListViewItemTag{itemlayout(){return{el:"div",children:[{el:"afx-label",ref:"label"},{el:"p",ref:"desc",id:"ext-list-item-d-p"},{el:"p",id:"ext-list-item-b-p",children:[{el:"i",ref:"intall_status"},{el:"afx-button",ref:"btn_remove"},{el:"afx-button",ref:"btn_install"}]}]}}ondatachange(){const t=this.data;if(!t)return;const e=this.refs.label;e.iconclass="bi bi-puzzle",e.text=`${t.text} - v${t.version}`;const i=this.refs.desc;$(i).text(t.description);const a=this.refs.btn_install,s=this.refs.btn_remove;t.installed?($(s).show(),s.iconclass="bi bi-trash-fill",a.iconclass="bi bi-arrow-repeat",$(this.refs.intall_status).text(__("Installed: v{0} ",t.installed).__())):($(s).hide(),a.iconclass="fa bi-cloud-download-fill",$(this.refs.intall_status).text(" "))}init(){this.closable=!1,this.data={};const t=this.refs.btn_install,e=this.refs.btn_remove;t.onbtclick=t=>{this.data.download&&this.data.install_action&&this.data.install_action(this.data.download,t=>{this.data.installed=t,this.update(void 0)})},e.onbtclick=t=>{this.data.installed&&this.data.uninstall_action&&this.data.uninstall_action(this.data.name,()=>{delete this.data.installed,this.update(void 0)})}}reload(t){this.data=this.data}}t.define("afx-antedit-ext-list-item",e)}(e=t.tag||(t.tag={}))}(e=t.GUI||(t.GUI={})),function(e){class i extends e.BaseApplication{constructor(t){super("Antedit",t),this.currdir=void 0,this.diff_buffer=[void 0,void 0]}main(){this.extensions={},this.eum=new a,this.fileview=this.find("fileview"),this.sidebar=this.find("sidebar"),this.sidebar_container=this.find("sidebar-tab-container"),this.bottombar=this.find("bottombar"),this.langstat=this.find("langstat"),this.editorstat=this.find("editorstat"),this.filestat=this.find("current-file-lbl"),this.extension_list_view=this.find("extension-list"),this.logger=new s(this.find("output-tab")),this.split_mode=!0,this.fileview.fetch=t=>new Promise((async function(e,i){let a;a="string"==typeof t?t.asFileHandle():t;try{const t=await a.read();return t.error?i(t.error):e(t.result)}catch(t){return i(__e(t))}}));let e="Untitled".asFileHandle();this.args&&this.args.length>0&&(this.addRecent(this.args[0].path),"dir"===this.args[0].type?this.currdir=this.args[0].path.asFileHandle():(e=this.args[0].path.asFileHandle(),this.currdir=e.parent())),this.setting.recent||(this.setting.recent=[]),this.setting.extension_repos||(this.setting.extension_repos=["https://raw.githubusercontent.com/lxsang/antos-antedit-extensions/master/extensions.json"]);const i=this.find("wrapper");$(i).css("visibility","hidden"),monaco.editor.setTheme("vs-dark");const n=new t.application.MonacoEditorModel(this,this.find("left-tabbar"),this.find("left-editorarea")),o=new t.application.MonacoEditorModel(this,this.find("right-tabbar"),this.find("right-editorarea"));n.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,n)),o.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,o)),this.eum.add(n).add(o),this.eum.onstatuschange=t=>this.updateStatus(t),$(i).css("visibility","visible"),this.setup(),this.eum.active.openFile(e)}get tb_ctxmenu(){return[{text:"__(Close)",id:"close"},{text:"__(Reload)",id:"reload",shortcut:"A-R"},{text:"__(Close All)",id:"close-all"},{text:"__(Move to other side)",id:"mv-side"}]}tabbar_ctx_menu_handle(t,e,i){switch(e.id){case"close":if(!t)return;i.closeTab(t);break;case"close-all":i.closeAll();break;case"reload":this.eum.active.reload();break;case"mv-side":if(!t)return;let e=this.eum.editors[0];i==e&&(e=this.eum.editors[1]),e.openFile(t.data),i.closeTab(t),0==this.split_mode&&this.toggleSplitMode()}}setup(){this.sidebar_container.selectedIndex=0,this.extension_list_view.itemtag="afx-antedit-ext-list-item",this.fileview.onfileopen=t=>{if(t.data&&t.data.path&&(this.addRecent(t.data.path),"dir"!==t.data.type))return this.eum.active.openFile(t.data.path.asFileHandle())},this.fileview.onfileselect=t=>{t.data&&t.data.path&&"dir"!==t.data.type&&this.eum.active.selectFile(t.data.path)},this.on("resize",()=>this.eum.resize()),this.on("focus",()=>this.eum.active.focus()),this.fileview.contextmenuHandle=(t,e)=>{let i=this.fileview.selectedFile;const a=[{text:"__(New file)",id:"new"},{text:"__(New folder)",id:"newdir"},{text:"__(Rename)",id:"rename"},{text:"__(Delete)",id:"delete"},{text:"__(Upload)",id:"upload"}];return i&&"file"===i.type&&(a.push({text:"__(Select for compare)",id:"diff-org"}),a.push({text:"__(Compare with selected)",id:"diff-mod"}),a.push({text:"__(Open to right)",id:"open-right"})),e.items=a,e.onmenuselect=t=>this.ctxFileMenuHandle(t),e.show(t)},this.bindKey("ALT-N",()=>this.menuAction("new")),this.bindKey("ALT-O",()=>this.menuAction("open")),this.bindKey("ALT-F",()=>this.menuAction("opendir")),this.bindKey("CTRL-S",()=>this.menuAction("save")),this.bindKey("ALT-W",()=>this.menuAction("saveas")),this.bindKey("ALT-R",()=>this.eum.active.reload()),$(".list-container",this.find("editor-main-container")).each((t,e)=>{$(e).on("wheel",t=>{e.scrollLeft+=t.originalEvent.deltaY})}),this.on("tab-opened",t=>{const e=$(t).closest(".list-container");e&&e[0]&&(e[0].scrollLeft=e[0].scrollWidth)}),this.fileview.ondragndrop=t=>{if(!t.data.from||!t.data.to)return;const e=t.data.from[0].data.path.asFileHandle(),i=t.data.to.data.path;return e.move(`${i}/${e.basename}`).then((function(a){const s=i,n=e.parent().path;s.lengththis.error(__("Unable to move file/folder"),t))},this.on("filechange",t=>{let{path:e}=t.file;return"file"===t.type&&({path:e}=t.file.parent()),this.fileview.update(e)}),this.find("logger-clear").onbtclick=()=>{this.logger.clear()},void 0===this.setting.showBottomBar&&(this.setting.showBottomBar=!1);const t={name:"Editor",text:__("Editor")},e={name:"langmode",text:__("Change language mode"),shortcut:"CTRL-K"};this.eum.addAction(t,e,async t=>{try{const t=await this.openDialog("SelectionDialog",{title:__("Select language"),data:this.eum.active.getModes()});this.eum.active.setMode(t)}catch(t){console.log(t)}}),$(this.find("txt_ext_search")).keyup(t=>this.extension_search(t)),this.loadExtensionMetaData(),this.toggleSideBar(),this.toggleSplitMode(),this.applyAllSetting()}extension_search(t){let e;const i=this.find("txt_ext_search");switch(t.which){case 37:return t.preventDefault();case 38:return this.extension_list_view.selectPrev(),t.preventDefault();case 39:return t.preventDefault();case 40:return this.extension_list_view.selectNext(),t.preventDefault();case 13:return t.preventDefault();default:var a=i.value,s=[];if(2===a.length)return void(this.extension_list_view.data=this.extension_meta_data);if(a.length<3)return;var n=new RegExp(a,"i");for(e in this.extension_meta_data)this.extension_meta_data[e].text.match(n)&&s.push(this.extension_meta_data[e]);this.extension_list_view.data=s}}refreshExtensionRepositories(){const t=[],e=this.meta().path+"/extensions/extensions.json";for(let i of[e].concat(this.setting.extension_repos))t.push(i.asFileHandle().read("json"));Promise.all(t).then(t=>{const e={};for(let i of t.shift())e[i.name]=i;this.extension_meta_data=[];for(let a of t)for(let t of a)e[t.name]&&(t.installed=e[t.name].version),t.install_action=(e,a)=>{new i.extensions.EditorExtensionMaker(this).installZip(e).then(()=>{this.loadExtensionMetaData(),a&&a(t.version),this.notify(__("Extension '{0}' installed",t.text))}).catch(e=>{this.error(__("Unable to install '{0}': {1}",t.text,e.toString()),e)})},t.uninstall_action=(t,e)=>{new i.extensions.EditorExtensionMaker(this).uninstall(t).then(()=>{this.loadExtensionMetaData(),e&&e(),this.notify(__("Extension '{0}' uninstalled",t))}).catch(e=>{this.error(__("Unable to uninstall '{0}': {1}",t,e.toString()),e)})},this.extension_meta_data.push(t);this.extension_list_view.data=this.extension_meta_data}).catch(t=>{this.error(__("Unable to read extension from repositories: {0}",t.toString()),t)})}updateStatus(t){t||(t=this.eum.active.getEditorStatus()),this.editorstat.text=__("Row {0}, col {1}, lines: {2}",t.row,t.column,t.line),t.langmode&&(this.langstat.text=t.langmode.text),this.filestat.text=t.file;let e=this.scheme;e.apptitle!=t.file&&(e.apptitle=t.file)}toggleSideBar(){this.currdir?($(this.sidebar).show(),this.fileview.path=this.currdir.path,this.refreshExtensionRepositories()):$(this.sidebar).hide(),this.trigger("resize")}showOutput(t=!1){t&&this.showBottomBar(!0),this.bottombar.selectedIndex=0}openDiff(e){const i=new t.API.VFS.DiffEditorFileHandle(e);this.eum.active.openFile(i)}applySetting(t){"showBottomBar"==t&&this.showBottomBar(this.setting.showBottomBar)}showBottomBar(t){this.setting.showBottomBar=t,t?$(this.bottombar).show():$(this.bottombar).hide(),this.trigger("resize")}toggleBottomBar(){this.showBottomBar(!this.setting.showBottomBar)}toggleSplitMode(){const t=this.find("right-panel"),e=this.eum.editors[1],i=this.eum.editors[0];if(this.split_mode){if(e.isDirty())return void this.notify(__("Unable to disable split view: Please save changes of modified files on the right panel"));e.closeAll(),$(t).hide(),this.split_mode=!1,i.focus()}else $(t).show(),this.split_mode=!0,e.openFile("Untitled".asFileHandle()),e.focus();this.trigger("resize")}fileMenu(){const t=this.setting.recent.map(t=>({text:t}));return{text:__("File"),nodes:[{text:__("New"),dataid:"new",shortcut:"A-N"},{text:__("Open Recent"),dataid:"recent",nodes:t,onchildselect:(t,e)=>{const i=t.data.item.data.text.asFileHandle();i.onready().then(t=>{t&&("dir"==t.type?(this.currdir=i,this.toggleSideBar()):this.eum.active.openFile(i))})}},{text:__("Open"),dataid:"open",shortcut:"A-O"},{text:__("Open Folder"),dataid:"opendir",shortcut:"A-F"},{text:__("Save"),dataid:"save",shortcut:"C-S"},{text:__("Save as"),dataid:"saveas",shortcut:"A-W"}],onchildselect:(t,e)=>this.menuAction(t.data.item.data.dataid,e)}}ctxFileMenuHandle(t){const e=t.data.item;if(!e)return;const i=e.data;if(!i)return;let a=this.fileview.selectedFile,s=this.currdir;switch(a&&"dir"===a.type&&(s=a.path.asFileHandle()),a&&"file"===a.type&&(s=a.path.asFileHandle().parent()),i.id){case"new":if(!s)return;this.openDialog("PromptDialog",{title:"__(New file)",label:"__(File name)"}).then(async t=>{const e=`${s.path}/${t}`.asFileHandle();try{return await e.write("text/plain"),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",t.stack),__e(t))}});break;case"newdir":if(!s)return;this.openDialog("PromptDialog",{title:"__(New folder)",label:"__(Folder name)"}).then(async t=>{try{return await s.mk(t),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",s.path),__e(t))}});break;case"rename":if(!a)return;this.openDialog("PromptDialog",{title:"__(Rename)",label:"__(File name)",value:a.filename}).then(async t=>{if(t!==a.filename){a=a.path.asFileHandle(),s=a.parent();try{return await a.move(`${s.path}/${t}`),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to rename: {0}",a.path),__e(t))}}});break;case"delete":if(!a)return;this.openDialog("YesNoDialog",{title:"__(Delete)",iconclass:"fa fa-question-circle",text:__("Do you really want to delete: {0}?",a.filename)}).then(async t=>{if(t){a=a.path.asFileHandle(),s=a.parent();try{return await a.remove(),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to delete: {0}",a.path),__e(t))}}});break;case"upload":if(!s)return;s.upload().then(t=>(this.notify(__("File uploaded to: {0}",s.path)),this.fileview.update(s.path))).catch(t=>this.error(__("Unable to upload file: {e}",t.toString()),__e(t)));break;case"diff-org":if(!a)return;this.diff_buffer[0]=a.path.asFileHandle();break;case"diff-mod":if(!a)return;if(!this.diff_buffer[0])return;this.diff_buffer[1]=a.path.asFileHandle(),this.openDiff(this.diff_buffer);break;case"open-right":if(!a||"dir"===a.type)return;0==this.split_mode&&this.toggleSplitMode(),this.eum.editors[1].openFile(a.path.asFileHandle())}}addRecent(t){this.setting.recent||(this.setting.recent=[]),this.setting.recent.includes(t)||(this.setting.recent.unshift(t),this.setting.recent.length>10&&(this.setting.recent=this.setting.recent.slice(0,10)))}menuAction(t,e){let i=this;switch(e&&(i=e),t){case"new":return i.eum.active.openFile("Untitled".asFileHandle());case"open":return i.openDialog("FileDialog",{title:__("Open file"),mimes:Array.from(i.meta().mimes).filter(t=>"dir"!==t)}).then(t=>{this.addRecent(t.file.path),i.eum.active.openFile(t.file.path.asFileHandle())});case"opendir":return i.openDialog("FileDialog",{title:__("Open folder"),mimes:["dir"]}).then((function(t){return i.addRecent(t.file.path),i.currdir=t.file.path.asFileHandle(),i.toggleSideBar()}));case"save":return i.eum.active.save();case"saveas":return i.eum.active.saveAs();default:return console.log(t)}}cleanup(t){let e;const i=this.eum.dirties();if(0!==i.length)t.preventDefault(),this.openDialog("YesNoDialog",{title:"__(Quit)",text:__("Ignore all unsaved files: {0} ?",(()=>{const t=[];for(e of Array.from(i))t.push(e.filename);return t})().join(", "))}).then(t=>{if(t){for(e of Array.from(i))e.dirty=!1;return this.quit(!1)}});else for(let t in this.extensions)this.extensions[t]&&this.extensions[t].cleanup&&this.extensions[t].cleanup()}menu(){return[this.fileMenu(),{text:"__(View)",nodes:[{text:"__(Toggle bottom bar)",dataid:"bottombar"},{text:"__(Toggle split view)",dataid:"splitview"}],onchildselect:(t,e)=>{switch(t.data.item.data.dataid){case"bottombar":return this.toggleBottomBar();case"splitview":return this.toggleSplitMode()}}}]}loadExtensionMetaData(){this.loadExtensionMetaFromFile(this.meta().path+"/extensions/extensions.json").catch(t=>this.error(__("Cannot load extension meta data"),t))}loadExtensionMetaFromFile(t){return new Promise((e,i)=>{t.asFileHandle().read("json").then(t=>{for(let e of t)for(let t of e.actions)this.eum.addAction(e,t,(t,i)=>{this.loadAndRunExtensionAction(t,i,e.root)});e()}).catch(t=>{i(__e(t))})})}loadAndRunExtensionAction(t,e,a){if(i.extensions[t])this.runExtensionAction(t,e);else{let i=`${this.meta().path}/extensions/${t}/main.js`;a&&(i=a+"/main.js"),this._api.requires(i,!0).then(()=>this.runExtensionAction(t,e)).catch(e=>this.error(__("unable to load extension: {0}",t),e))}}runExtensionAction(t,e){if(!this.extensions[t]){if(!i.extensions[t])return this.error(__("Unable to find extension: {0}",t));this.extensions[t]=new i.extensions[t](this)}if(!this.extensions[t][e])return this.error(__("Unable to find action: {0}",e));this.extensions[t].preload().then(()=>this.extensions[t][e]()).catch(t=>this.error(__("Unable to preload extension"),t))}}e.Antedit=i;class a{constructor(){this.active_editor=void 0,this.models=[]}get editors(){return this.models}set contextmenuHandle(t){for(let e of this.models)e.contextmenuHandle=t}get active(){return this.active_editor}add(t){return this.models.push(t),this.active_editor||(this.active_editor=t),t.on("focus",()=>{this.active_editor=t}),this}addAction(t,e,i){const a={id:`${t.name}:${e.name}`,label:`${t.text.__()}: ${e.text.__()}`,keybindings:[],precondition:null,keybindingContext:null,contextMenuGroupId:t.name,run:()=>i(t.name,e.name)};if(e.shortcut){const t=e.shortcut.split("-");let i=0;for(const e of t)switch(e){case"CTRL":i|=monaco.KeyMod.CtrlCmd;break;case"ALT":i|=monaco.KeyMod.Alt;break;case"SHIFT":i|=monaco.KeyMod.Shift;break;case"SUPPER":i|=monaco.KeyMod.WinCtrl;break;default:const t="Key"+e;monaco.KeyCode[t]?i|=monaco.KeyCode[t]:i=0}0!=i&&a.keybindings.push(i)}for(let t of this.models){const e=t.getEditor();e.getAction(a.id)||e.addAction(a)}}set onstatuschange(t){for(let e of this.models)e.onstatuschange=t}dirties(){let t=[];for(let e of this.models)t=t.concat(e.dirties());return t}resize(){for(let t of this.models)t.resize()}}class s{constructor(t){this.target=t}info(t){this.log("info",t,!0)}warn(t){this.log("warn",t,!0)}error(t){this.log("error",t,!0)}log(t,e,i){let a=$("
").attr("class","code-pad-log-"+t);if(i){let t=new Date,i=t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+" "+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds();a.text(`[${i}]: ${e.__()}`)}else a.text(e.__());$(this.target).append(a),$(this.target).scrollTop($(this.target)[0].scrollHeight)}print(t){t.match(/warn/i)?this.log("warn",t,!1):t.match(/error/i)?this.log("error",t,!1):this.log("info",t,!1)}clear(){$(this.target).empty()}}i.Logger=s,i.dependencies=["pkg://MonacoCore/path.js","pkg://MonacoCore/bundle/app.bundle.js"]}(i=t.application||(t.application={}))}(OS||(OS={})),function(t){class e{constructor(t,e){this.app=e,this.name=t}preload(){return t.API.require(t.application.Antedit.extensions[this.name].dependencies)}basedir(){return`${this.app.meta().path}/extensions/${this.name}`}notify(t){return this.app.notify(t)}error(t,e){return this.app.error(t,e)}logger(){return this.app.setting.showBottomBar?this.app.showOutput(!1):this.app.showOutput(!0),this.app.logger}metadata(e){return new Promise((i,a)=>{if(!this.app.currdir)return a(t.API.throwe(__("Current folder is not found")));`${this.app.currdir.path}/${e}`.asFileHandle().read("json").then(t=>{!t.root&&this.app.currdir&&(t.root=this.app.currdir.path),i(t)}).catch(s=>{this.app.openDialog("FileDialog",{title:__("Select build directory"),root:this.app.currdir.path,mimes:["dir"]}).then(t=>{`${t.file.path}/${e}`.asFileHandle().read("json").then(e=>{e.root||(e.root=t.file.path),i(e)}).catch(t=>a(t))}).catch(e=>a(t.API.throwe(__("Unable to read meta-data"))))})})}}e.dependencies=[],t.application.Antedit.extensions={},t.application.Antedit.EditorBaseExtension=e,t.application.Antedit.extensions.EditorExtensionMaker=class extends e{constructor(t){super("EditorExtensionMaker",t)}create(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(New extension at)",file:{basename:__("ExtensionName")},mimes:["dir"]}).then(t=>this.mktpl(t.file.path,t.name))}build(e){this.logger().clear(),this.metadata("extension.json").then(async i=>{try{const a=await t.API.VFS.cat(i.javascripts.map(t=>`${i.root}/${t}`),"");await(i.root+"/build/debug/main.js").asFileHandle().setCache(a).write("text/plain"),await(i.root+"/build/debug/extension.json").asFileHandle().setCache(i.meta).write("object"),await t.API.VFS.copy(i.copies.map(t=>`${i.root}/${t}`),i.root+"/build/debug"),this.logger().info(__("Files generated in {0}",i.root+"/build/debug")),e&&e()}catch(t){return this.logger().error(__("Unable to build extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}run(){this.logger().clear(),this.metadata("extension.json").then(async e=>{if(!e||!e.meta||!e.meta.name)return this.logger().error(__("Invalid extension meta-data"));try{const i=e.root+"/build/debug/main.js";t.API.shared[i]&&delete t.API.shared[i],await t.API.requires(i),this.app.extensions[e.meta.name]&&this.app.extensions[e.meta.name].cleanup&&this.app.extensions[e.meta.name].cleanup(),this.app.extensions[e.meta.name]=new t.application.Antedit.extensions[e.meta.name](this.app);for(let t of e.meta.actions)this.app.eum.addAction(e.meta,t,(t,i)=>{this.app.loadAndRunExtensionAction(t,i,e.root+"/build")});this.app.eum.active.getEditor().trigger(e.meta.name,"editor.action.quickCommand")}catch(t){return this.logger().error(__("Unable to run extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}release(){this.logger().clear(),this.metadata("extension.json").then(async e=>{this.build(async()=>{try{await t.API.VFS.mkar(e.root+"/build/debug",`${e.root}/build/release/${e.meta.name}.zip`),this.logger().info(__("Archive created at {0}",`${e.root}/build/release/${e.meta.name}.zip`))}catch(t){return this.logger().error(__("Unable to create archive: {0}",t.stack))}})}).catch(t=>this.logger().error(__("Unable to read meta-data: {0}",t.stack)))}install(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(Select extension archive)",mimes:[".*/zip"]}).then(async t=>{try{return await this.installZip(t.file.path),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(t){return this.logger().error(__("Unable to install extension: {0}",t.stack))}})}installFromURL(){this.logger().clear(),this.app.openDialog("PromptDialog",{title:__("Enter URI"),label:__("Please enter extension URI:")}).then(async t=>{if(t)try{return await this.installZip(t),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(e){return this.app.error(__("Unable to install extension: {0}",t))}})}mktpl(e,i){const a=`${e}/${i}`,s=[a,a+"/build",a+"/build/release",a+"/build/debug"],n=[["main.tpl",`${a}/${i}.js`],["meta.tpl",a+"/extension.json"]];t.API.VFS.mkdirAll(s,!0).then(async()=>{try{return await t.API.VFS.mktpl(n,this.basedir(),t=>t.format(i,`${e}/${i}`)),this.app.currdir=a.asFileHandle(),this.app.toggleSideBar(),this.app.eum.active.openFile(`${a}/${i}.js`.asFileHandle())}catch(t){return this.logger().error(__("Unable to create extension template: {0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to create extension directories: {0}",t.stack)))}uninstall(t){return new Promise(async(e,i)=>{try{const i=this.app.meta().path+"/extensions",a=(i+"/extensions.json").asFileHandle(),s=await a.read("json");let n=void 0,o=void 0;for(let e in s)if(s[e].name===t){n=s[e],o=e;break}if(void 0===n)return e();await`${i}/${t}`.asFileHandle().remove(),s.splice(o,1),a.cache=s,await a.write("object"),e()}catch(t){i(t)}})}installZip(e){return new Promise(async(i,a)=>{try{await t.API.requires("os://scripts/jszip.min.js");const a=await e.asFileHandle().read("binary"),s=await JSZip.loadAsync(a),n=await s.file("extension.json").async("uint8array"),o=JSON.parse(new TextDecoder("utf-8").decode(n));await this.uninstall(o.name);const r=this.ext_dir(o.name),l=[r],h=[];for(let t in s.files)s.files[t].dir?l.push(r+"/"+t):"extension.json"!=t&&h.push(t);l.length>0?(await t.API.VFS.mkdirAll(l,!0),await this.installFiles(h,s,o)):await this.installFiles(h,s,o),i()}catch(t){a(__e(t))}})}ext_dir(t){return`${this.app.meta().path}/extensions/${t}`}installFiles(t,e,i){return 0===t.length?this.installMeta(i):new Promise(async(a,s)=>{try{const n=t.splice(0,1)[0],o=`${this.ext_dir(i.name)}/${n}`,r=await e.file(n).async("uint8array"),l=await o.asFileHandle().setCache(new Blob([r],{type:"octet/stream"})).write("text/plain");if(l.error)return s(l.error);await this.installFiles(t,e,i),a()}catch(t){s(__e(t))}})}installMeta(t){return new Promise(async(e,i)=>{const a=(this.ext_dir("")+"/extensions.json").asFileHandle();try{const s=await a.read("json"),n=[];for(let t of s)n.push(t.name);const o=n.indexOf(t.name);o>=0&&s.splice(o,1),s.push(t);try{return await a.setCache(s).write("object"),e()}catch(t){return i(__e(t))}}catch(s){try{return await a.setCache([t]).write("object"),e()}catch(t){return i(__e(t))}}})}}}(OS||(OS={}));
\ No newline at end of file
+var OS;!function(t){let e,i;!function(e){let i;!function(e){class i extends t.API.VFS.BaseFileHandle{constructor(t){super(""),this.path=`${t[0].path} -> ${t[1].path}`,this.cache=t,this.basename=`${t[0].basename} -> ${t[1].basename}`,this.info={type:"file",mime:void 0,size:0,name:this.basename,path:this.path},this.ready=!0}meta(){return new Promise(async(t,e)=>{try{await Promise.all([this.cache[0].meta(),this.cache[1].meta]),t({result:this.info,error:!1})}catch(t){e(t)}})}_rd(t){return new Promise(async(t,e)=>{try{this.cache[0].cache=await this.cache[0].read(),this.cache[1].cache=await this.cache[1].read(),t(this.cache)}catch(t){e(t)}})}_wr(t){return new Promise((t,e)=>{t({result:!0,error:!1})})}setPath(t){}}e.DiffEditorFileHandle=i}(i=e.VFS||(e.VFS={}))}(e=t.API||(t.API={})),function(t){t.BaseEditorModel=class{constructor(t,e,i){this.container=i,this.currfile="Untitled".asFileHandle(),this.tabbar=e,this.editorSetup(i),this.app=t,this.editormux=!1,this.onstatuschange=void 0,this.on("focus",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.on("input",()=>this.editormux?(this.editormux=!1,!1):this.currfile.dirty?void 0:(this.currfile.dirty=!0,this.currfile.text+="*",this.tabbar.update(void 0))),this.on("changeCursor",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.tabbar.ontabselect=t=>this.selecteTab($(t.data.item).index()),this.tabbar.ontabclose=t=>{const e=t.data.item;return!!e&&(e.data.dirty?(this.app.openDialog("YesNoDialog",{title:__("Close tab"),text:__("Close without saving ?")}).then(t=>t?this.closeTab(e):this.focus()),!1):this.closeTab(e))}}findTabByFile(t){const e=this.tabbar.items,i=(()=>{const i=[];for(let a=0;a(t.cache=e||"",this.newTab(t))).catch(e=>this.app.error(__("Unable to open: {0}",t.path),e)):this.newTab(t):this.tabbar.selected=e}write(){this.currfile.cache=this.getValue(),this.currfile.write("text/plain").then(t=>{this.currfile.dirty=!1,this.currfile.text=this.currfile.basename,this.tabbar.update(void 0)}).catch(t=>this.app.error(__("Unable to save file: {0}",this.currfile.path),t))}save(){return this.currfile.cache=this.getValue(),this.currfile.basename?this.write():this.saveAs()}reload(){return new Promise(async(t,e)=>{try{if("Untitled"===this.currfile.path.toString())return t(!0);if(this.currfile.dirty&&!await this.app.openDialog("YesNoDialog",{title:__("File modified"),text:__("Continue without saving ?")}))return t(!0);const e=await this.currfile.read();this.currfile.cache=e||"",this.currfile.dirty=!1,this.currfile.text=this.currfile.basename?this.currfile.basename:this.currfile.path,this.editormux=!0,this.setValue(this.currfile.cache),this.tabbar.update(void 0)}catch(t){this.app.error(__("Unable to open: {0}",this.currfile.path),t),e(t)}})}saveAs(){this.app.openDialog("FileDialog",{title:__("Save as"),file:this.currfile}).then(t=>{let e=t.file.path.asFileHandle();"file"===t.file.type&&(e=e.parent()),this.currfile.setPath(`${e.path}/${t.name}`),this.write()})}dirties(){const t=[];for(let e of Array.from(this.tabbar.items))e.dirty&&t.push(e);return t}set contextmenuHandle(t){this.container.contextmenuHandle=t}closeAll(){this.tabbar.items=[],this.openFile("Untitled".asFileHandle()),this.resetEditor()}isDirty(){return this.dirties().length>0}setTabbarCtxMenu(t,e){this.tabbar.contextmenuHandle=(i,a)=>(a.items=t,a.onmenuselect=t=>{if(e){const a=$(i.target).closest("afx-list-item");e(a[0],t.data.item.data)}},a.show(i))}}}(i=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(e){class i extends t.application.BaseEditorModel{constructor(t,e,i){super(t,e,i)}resetEditor(){}getTexModel(){return{model:this.editor.getModel(),position:this.editor.getPosition()}}setTextModel(t){this.editor.setModel(t.model),t.position&&(this.editor.setPosition(t.position),this.editor.revealLineInCenter(t.position.lineNumber)),this.editor==this._code_editor&&this.editor.updateOptions({readOnly:!1,domReadOnly:!1})}newTextModelFrom(t){if(Array.isArray(t.cache))return{model:{original:this.newTextModelFrom(t.cache[0]).model,modified:this.newTextModelFrom(t.cache[1]).model}};{if("Untitled"===t.path.toString())return{model:monaco.editor.createModel(t.cache,"textplain")};const e=monaco.Uri.parse(t.protocol+"://antedit/file/"+t.genealogy.join("/")),i=monaco.editor.getModel(e);return i?(i.setValue(t.cache),{model:i}):{model:monaco.editor.createModel(t.cache,void 0,e)}}}getModes(){return monaco.languages.getLanguages().map(t=>{const e=t;return t.aliases?e.text=t.aliases[0]:e.text=t.id,t})}setTheme(t){}setMode(t){if(this.editor==this._code_editor)monaco.editor.setModelLanguage(this.editor.getModel(),t.id);else for(const e of this.editor.getModel())monaco.editor.setModelLanguage(e,t.id);this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}get editor(){return Array.isArray(this.currfile.cache)?this._diff_editor:this._code_editor}editorSetup(t){this.code_container=$("
").css("width","100%").css("height","100%"),this.diff_container=$("
").css("width","100%").css("height","100%").css("display","none"),$(t).append(this.code_container),$(t).append(this.diff_container),this._code_editor=monaco.editor.create(this.code_container[0],{value:"",language:"textplain",readOnly:!1,domReadOnly:!1}),this._diff_editor=monaco.editor.createDiffEditor(this.diff_container[0],{readOnly:!0}),i.modes||(i.modes={},monaco.languages.getLanguages().forEach(t=>{i.modes[t.id]=t}))}on(t,e){switch(t){case"input":this._code_editor.onDidChangeModelContent(e);break;case"focus":this._code_editor.onDidFocusEditorText(e),this._diff_editor.getOriginalEditor().onDidFocusEditorText(e),this._diff_editor.getModifiedEditor().onDidFocusEditorText(e);break;case"changeCursor":this._code_editor.onDidChangeCursorPosition(e),this._diff_editor.getOriginalEditor().onDidChangeCursorPosition(e),this._diff_editor.getModifiedEditor().onDidChangeCursorPosition(e)}}resize(){this.editor&&this.editor.layout()}focus(){Array.isArray(this.currfile.cache)?(this.code_container.hide(),this.diff_container.show()):(this.code_container.show(),this.diff_container.hide()),this.editor&&(this.editor.layout(),this.editor.focus())}getModeForPath(t){return{}}getEditorStatus(){let t=void 0;this.editor==this._code_editor?t=this.editor:(t=this.editor.getOriginalEditor(),this.editor.getModifiedEditor().hasTextFocus()&&(t=this.editor.getModifiedEditor()));const e=t.getPosition();let a=void 0;const s=t.getModel();return s&&(a=i.modes[s.getLanguageId()]),{row:e.lineNumber,column:e.column,line:s?s.getLineCount():0,langmode:{text:a?a.aliases[0]:"",mode:a},file:this.currfile.path}}getValue(){return this.editor==this._code_editor?this.editor.getValue():this.currfile.cache}setValue(t){this.editor==this._code_editor&&this.editor.setValue(t)}getEditor(){return this._code_editor}}e.MonacoEditorModel=i}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e,i;!function(t){let e;!function(t){class e extends t.ListViewItemTag{itemlayout(){return{el:"div",children:[{el:"afx-label",ref:"label"},{el:"p",ref:"desc",id:"ext-list-item-d-p"},{el:"p",id:"ext-list-item-b-p",children:[{el:"i",ref:"intall_status"},{el:"afx-button",ref:"btn_remove"},{el:"afx-button",ref:"btn_install"}]}]}}ondatachange(){const t=this.data;if(!t)return;const e=this.refs.label;e.iconclass="bi bi-puzzle",e.text=`${t.text} - v${t.version}`;const i=this.refs.desc;$(i).text(t.description);const a=this.refs.btn_install,s=this.refs.btn_remove;t.installed?($(s).show(),s.iconclass="bi bi-trash-fill",a.iconclass="bi bi-arrow-repeat",$(this.refs.intall_status).text(__("Installed: v{0} ",t.installed).__())):($(s).hide(),a.iconclass="fa bi-cloud-download-fill",$(this.refs.intall_status).text(" "))}init(){this.closable=!1,this.data={};const t=this.refs.btn_install,e=this.refs.btn_remove;t.onbtclick=t=>{this.data.download&&this.data.install_action&&this.data.install_action(this.data.download,t=>{this.data.installed=t,this.update(void 0)})},e.onbtclick=t=>{this.data.installed&&this.data.uninstall_action&&this.data.uninstall_action(this.data.name,()=>{delete this.data.installed,this.update(void 0)})}}reload(t){this.data=this.data}}t.define("afx-antedit-ext-list-item",e)}(e=t.tag||(t.tag={}))}(e=t.GUI||(t.GUI={})),function(e){class i extends e.BaseApplication{constructor(t){super("Antedit",t),this.currdir=void 0,this.diff_buffer=[void 0,void 0]}main(){this.extensions={},this.eum=new a,this.fileview=this.find("fileview"),this.sidebar=this.find("sidebar"),this.sidebar_container=this.find("sidebar-tab-container"),this.bottombar=this.find("bottombar"),this.langstat=this.find("langstat"),this.editorstat=this.find("editorstat"),this.filestat=this.find("current-file-lbl"),this.extension_list_view=this.find("extension-list"),this.logger=new s(this.find("output-tab")),this.split_mode=!0,this.fileview.fetch=t=>new Promise((async function(e,i){let a;a="string"==typeof t?t.asFileHandle():t;try{const t=await a.read();return t.error?i(t.error):e(t.result)}catch(t){return i(__e(t))}}));let e="Untitled".asFileHandle();this.args&&this.args.length>0&&(this.addRecent(this.args[0].path),"dir"===this.args[0].type?this.currdir=this.args[0].path.asFileHandle():(e=this.args[0].path.asFileHandle(),this.currdir=e.parent())),this.setting.recent||(this.setting.recent=[]),this.setting.extension_repos||(this.setting.extension_repos=["https://raw.githubusercontent.com/lxsang/antos-antedit-extensions/master/extensions.json"]);const i=this.find("wrapper");$(i).css("visibility","hidden"),monaco.editor.setTheme("vs-dark");const n=new t.application.MonacoEditorModel(this,this.find("left-tabbar"),this.find("left-editorarea")),o=new t.application.MonacoEditorModel(this,this.find("right-tabbar"),this.find("right-editorarea"));n.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,n)),o.setTabbarCtxMenu(this.tb_ctxmenu,(t,e)=>this.tabbar_ctx_menu_handle(t,e,o)),this.eum.add(n).add(o),this.eum.onstatuschange=t=>this.updateStatus(t),$(i).css("visibility","visible"),this.setup(),this.eum.active.openFile(e)}get tb_ctxmenu(){return[{text:"__(Close)",id:"close"},{text:"__(Reload)",id:"reload",shortcut:"A-R"},{text:"__(Close All)",id:"close-all"},{text:"__(Move to other side)",id:"mv-side"}]}tabbar_ctx_menu_handle(t,e,i){switch(e.id){case"close":if(!t)return;i.closeTab(t);break;case"close-all":i.closeAll();break;case"reload":this.eum.active.reload();break;case"mv-side":if(!t)return;let e=this.eum.editors[0];i==e&&(e=this.eum.editors[1]),e.openFile(t.data),i.closeTab(t),0==this.split_mode&&this.toggleSplitMode()}}setup(){this.sidebar_container.selectedIndex=0,this.extension_list_view.itemtag="afx-antedit-ext-list-item",this.fileview.onfileopen=t=>{if(t.data&&t.data.path&&(this.addRecent(t.data.path),"dir"!==t.data.type))return this.eum.active.openFile(t.data.path.asFileHandle())},this.fileview.onfileselect=t=>{t.data&&t.data.path&&"dir"!==t.data.type&&this.eum.active.selectFile(t.data.path)},this.on("resize",()=>this.eum.resize()),this.on("focus",()=>this.eum.active.focus()),this.fileview.contextmenuHandle=(t,e)=>{let i=this.fileview.selectedFile;const a=[{text:"__(New file)",id:"new"},{text:"__(New folder)",id:"newdir"},{text:"__(Rename)",id:"rename"},{text:"__(Delete)",id:"delete"},{text:"__(Upload)",id:"upload"}];return i&&"file"===i.type&&(a.push({text:"__(Select for compare)",id:"diff-org"}),a.push({text:"__(Compare with selected)",id:"diff-mod"}),a.push({text:"__(Open to right)",id:"open-right"})),e.items=a,e.onmenuselect=t=>this.ctxFileMenuHandle(t),e.show(t)},this.bindKey("ALT-N",()=>this.menuAction("new")),this.bindKey("ALT-O",()=>this.menuAction("open")),this.bindKey("ALT-F",()=>this.menuAction("opendir")),this.bindKey("CTRL-S",()=>this.menuAction("save")),this.bindKey("ALT-W",()=>this.menuAction("saveas")),this.bindKey("ALT-R",()=>this.eum.active.reload()),$(".list-container",this.find("editor-main-container")).each((t,e)=>{$(e).on("wheel",t=>{e.scrollLeft+=t.originalEvent.deltaY})}),this.on("tab-opened",t=>{const e=$(t).closest(".list-container");e&&e[0]&&(e[0].scrollLeft=e[0].scrollWidth)}),this.fileview.ondragndrop=t=>{if(!t.data.from||!t.data.to)return;const e=t.data.from[0].data.path.asFileHandle(),i=t.data.to.data.path;return e.move(`${i}/${e.basename}`).then((function(a){const s=i,n=e.parent().path;s.lengththis.error(__("Unable to move file/folder"),t))},this.on("filechange",t=>{let{path:e}=t.file;return"file"===t.type&&({path:e}=t.file.parent()),this.fileview.update(e)}),this.find("logger-clear").onbtclick=()=>{this.logger.clear()},void 0===this.setting.showBottomBar&&(this.setting.showBottomBar=!1);const t={name:"Editor",text:__("Editor")},e={name:"langmode",text:__("Change language mode"),shortcut:"CTRL-K"};this.eum.addAction(t,e,async t=>{try{const t=await this.openDialog("SelectionDialog",{title:__("Select language"),data:this.eum.active.getModes()});this.eum.active.setMode(t)}catch(t){console.log(t)}}),$(this.find("txt_ext_search")).keyup(t=>this.extension_search(t)),this.loadExtensionMetaData(),this.toggleSideBar(),this.toggleSplitMode()}extension_search(t){let e;const i=this.find("txt_ext_search");switch(t.which){case 37:return t.preventDefault();case 38:return this.extension_list_view.selectPrev(),t.preventDefault();case 39:return t.preventDefault();case 40:return this.extension_list_view.selectNext(),t.preventDefault();case 13:return t.preventDefault();default:var a=i.value,s=[];if(2===a.length)return void(this.extension_list_view.data=this.extension_meta_data);if(a.length<3)return;var n=new RegExp(a,"i");for(e in this.extension_meta_data)this.extension_meta_data[e].text.match(n)&&s.push(this.extension_meta_data[e]);this.extension_list_view.data=s}}refreshExtensionRepositories(){const t=[],e=this.meta().path+"/extensions/extensions.json";for(let i of[e].concat(this.setting.extension_repos))t.push(i.asFileHandle().read("json"));Promise.all(t).then(t=>{const e={};for(let i of t.shift())e[i.name]=i;this.extension_meta_data=[];for(let a of t)for(let t of a)e[t.name]&&(t.installed=e[t.name].version),t.install_action=(e,a)=>{new i.extensions.EditorExtensionMaker(this).installZip(e).then(()=>{this.loadExtensionMetaData(),a&&a(t.version),this.notify(__("Extension '{0}' installed",t.text))}).catch(e=>{this.error(__("Unable to install '{0}': {1}",t.text,e.toString()),e)})},t.uninstall_action=(t,e)=>{new i.extensions.EditorExtensionMaker(this).uninstall(t).then(()=>{this.loadExtensionMetaData(),e&&e(),this.notify(__("Extension '{0}' uninstalled",t))}).catch(e=>{this.error(__("Unable to uninstall '{0}': {1}",t,e.toString()),e)})},this.extension_meta_data.push(t);this.extension_list_view.data=this.extension_meta_data}).catch(t=>{this.error(__("Unable to read extension from repositories: {0}",t.toString()),t)})}updateStatus(t){t||(t=this.eum.active.getEditorStatus()),this.editorstat.text=__("Row {0}, col {1}, lines: {2}",t.row,t.column,t.line),t.langmode&&(this.langstat.text=t.langmode.text),this.filestat.text=t.file;let e=this.scheme;e.apptitle!=t.file&&(e.apptitle=t.file)}toggleSideBar(){this.currdir?($(this.sidebar).show(),this.fileview.path=this.currdir.path,this.refreshExtensionRepositories()):$(this.sidebar).hide(),this.trigger("resize")}showOutput(t=!1){t&&(this.setting.showBottomBar=!0),this.bottombar.selectedIndex=0}openDiff(e){const i=new t.API.VFS.DiffEditorFileHandle(e);this.eum.active.openFile(i)}applySetting(t){"showBottomBar"==t&&this.showBottomBar(this.setting.showBottomBar)}showBottomBar(t){t?$(this.bottombar).show():$(this.bottombar).hide(),this.trigger("resize")}toggleBottomBar(){this.setting.showBottomBar=!this.setting.showBottomBar}toggleSplitMode(){const t=this.find("right-panel"),e=this.eum.editors[1],i=this.eum.editors[0];if(this.split_mode){if(e.isDirty())return void this.notify(__("Unable to disable split view: Please save changes of modified files on the right panel"));e.closeAll(),$(t).hide(),this.split_mode=!1,i.focus()}else $(t).show(),this.split_mode=!0,e.openFile("Untitled".asFileHandle()),e.focus();this.trigger("resize")}fileMenu(){const t=this.setting.recent.map(t=>({text:t}));return{text:__("File"),nodes:[{text:__("New"),dataid:"new",shortcut:"A-N"},{text:__("Open Recent"),dataid:"recent",nodes:t,onchildselect:(t,e)=>{const i=t.data.item.data.text.asFileHandle();i.onready().then(t=>{t&&("dir"==t.type?(this.currdir=i,this.toggleSideBar()):this.eum.active.openFile(i))})}},{text:__("Open"),dataid:"open",shortcut:"A-O"},{text:__("Open Folder"),dataid:"opendir",shortcut:"A-F"},{text:__("Save"),dataid:"save",shortcut:"C-S"},{text:__("Save as"),dataid:"saveas",shortcut:"A-W"}],onchildselect:(t,e)=>this.menuAction(t.data.item.data.dataid,e)}}ctxFileMenuHandle(t){const e=t.data.item;if(!e)return;const i=e.data;if(!i)return;let a=this.fileview.selectedFile,s=this.currdir;switch(a&&"dir"===a.type&&(s=a.path.asFileHandle()),a&&"file"===a.type&&(s=a.path.asFileHandle().parent()),i.id){case"new":if(!s)return;this.openDialog("PromptDialog",{title:"__(New file)",label:"__(File name)"}).then(async t=>{const e=`${s.path}/${t}`.asFileHandle();try{return await e.write("text/plain"),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",t.stack),__e(t))}});break;case"newdir":if(!s)return;this.openDialog("PromptDialog",{title:"__(New folder)",label:"__(Folder name)"}).then(async t=>{try{return await s.mk(t),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to create: {0}",s.path),__e(t))}});break;case"rename":if(!a)return;this.openDialog("PromptDialog",{title:"__(Rename)",label:"__(File name)",value:a.filename}).then(async t=>{if(t!==a.filename){a=a.path.asFileHandle(),s=a.parent();try{return await a.move(`${s.path}/${t}`),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to rename: {0}",a.path),__e(t))}}});break;case"delete":if(!a)return;this.openDialog("YesNoDialog",{title:"__(Delete)",iconclass:"fa fa-question-circle",text:__("Do you really want to delete: {0}?",a.filename)}).then(async t=>{if(t){a=a.path.asFileHandle(),s=a.parent();try{return await a.remove(),this.fileview.update(s.path)}catch(t){return this.error(__("Fail to delete: {0}",a.path),__e(t))}}});break;case"upload":if(!s)return;s.upload().then(t=>(this.notify(__("File uploaded to: {0}",s.path)),this.fileview.update(s.path))).catch(t=>this.error(__("Unable to upload file: {e}",t.toString()),__e(t)));break;case"diff-org":if(!a)return;this.diff_buffer[0]=a.path.asFileHandle();break;case"diff-mod":if(!a)return;if(!this.diff_buffer[0])return;this.diff_buffer[1]=a.path.asFileHandle(),this.openDiff(this.diff_buffer);break;case"open-right":if(!a||"dir"===a.type)return;0==this.split_mode&&this.toggleSplitMode(),this.eum.editors[1].openFile(a.path.asFileHandle())}}addRecent(t){this.setting.recent||(this.setting.recent=[]),this.setting.recent.includes(t)||(this.setting.recent.unshift(t),this.setting.recent.length>10&&(this.setting.recent=this.setting.recent.slice(0,10)))}menuAction(t,e){let i=this;switch(e&&(i=e),t){case"new":return i.eum.active.openFile("Untitled".asFileHandle());case"open":return i.openDialog("FileDialog",{title:__("Open file"),mimes:Array.from(i.meta().mimes).filter(t=>"dir"!==t)}).then(t=>{this.addRecent(t.file.path),i.eum.active.openFile(t.file.path.asFileHandle())});case"opendir":return i.openDialog("FileDialog",{title:__("Open folder"),mimes:["dir"]}).then((function(t){return i.addRecent(t.file.path),i.currdir=t.file.path.asFileHandle(),i.toggleSideBar()}));case"save":return i.eum.active.save();case"saveas":return i.eum.active.saveAs();default:return console.log(t)}}cleanup(t){let e;const i=this.eum.dirties();if(0!==i.length)t.preventDefault(),this.openDialog("YesNoDialog",{title:"__(Quit)",text:__("Ignore all unsaved files: {0} ?",(()=>{const t=[];for(e of Array.from(i))t.push(e.filename);return t})().join(", "))}).then(t=>{if(t){for(e of Array.from(i))e.dirty=!1;return this.quit(!1)}});else for(let t in this.extensions)this.extensions[t]&&this.extensions[t].cleanup&&this.extensions[t].cleanup()}menu(){return[this.fileMenu(),{text:"__(View)",nodes:[{text:"__(Toggle bottom bar)",dataid:"bottombar"},{text:"__(Toggle split view)",dataid:"splitview"}],onchildselect:(t,e)=>{switch(t.data.item.data.dataid){case"bottombar":return this.toggleBottomBar();case"splitview":return this.toggleSplitMode()}}}]}loadExtensionMetaData(){this.loadExtensionMetaFromFile(this.meta().path+"/extensions/extensions.json").catch(t=>this.error(__("Cannot load extension meta data"),t))}loadExtensionMetaFromFile(t){return new Promise((e,i)=>{t.asFileHandle().read("json").then(t=>{for(let e of t)for(let t of e.actions)this.eum.addAction(e,t,(t,i)=>{this.loadAndRunExtensionAction(t,i,e.root)});e()}).catch(t=>{i(__e(t))})})}loadAndRunExtensionAction(t,e,a){if(i.extensions[t])this.runExtensionAction(t,e);else{let i=`${this.meta().path}/extensions/${t}/main.js`;a&&(i=a+"/main.js"),this._api.requires(i,!0).then(()=>this.runExtensionAction(t,e)).catch(e=>this.error(__("unable to load extension: {0}",t),e))}}runExtensionAction(t,e){if(!this.extensions[t]){if(!i.extensions[t])return this.error(__("Unable to find extension: {0}",t));this.extensions[t]=new i.extensions[t](this)}if(!this.extensions[t][e])return this.error(__("Unable to find action: {0}",e));this.extensions[t].preload().then(()=>this.extensions[t][e]()).catch(t=>this.error(__("Unable to preload extension"),t))}}e.Antedit=i;class a{constructor(){this.active_editor=void 0,this.models=[]}get editors(){return this.models}set contextmenuHandle(t){for(let e of this.models)e.contextmenuHandle=t}get active(){return this.active_editor}add(t){return this.models.push(t),this.active_editor||(this.active_editor=t),t.on("focus",()=>{this.active_editor=t}),this}addAction(t,e,i){const a={id:`${t.name}:${e.name}`,label:`${t.text.__()}: ${e.text.__()}`,keybindings:[],precondition:null,keybindingContext:null,contextMenuGroupId:t.name,run:()=>i(t.name,e.name)};if(e.shortcut){const t=e.shortcut.split("-");let i=0;for(const e of t)switch(e){case"CTRL":i|=monaco.KeyMod.CtrlCmd;break;case"ALT":i|=monaco.KeyMod.Alt;break;case"SHIFT":i|=monaco.KeyMod.Shift;break;case"SUPPER":i|=monaco.KeyMod.WinCtrl;break;default:const t="Key"+e;monaco.KeyCode[t]?i|=monaco.KeyCode[t]:i=0}0!=i&&a.keybindings.push(i)}for(let t of this.models){const e=t.getEditor();e.getAction(a.id)||e.addAction(a)}}set onstatuschange(t){for(let e of this.models)e.onstatuschange=t}dirties(){let t=[];for(let e of this.models)t=t.concat(e.dirties());return t}resize(){for(let t of this.models)t.resize()}}class s{constructor(t){this.target=t}info(t){this.log("info",t,!0)}warn(t){this.log("warn",t,!0)}error(t){this.log("error",t,!0)}log(t,e,i){let a=$("
").attr("class","code-pad-log-"+t);if(i){let t=new Date,i=t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+" "+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds();a.text(`[${i}]: ${e.__()}`)}else a.text(e.__());$(this.target).append(a),$(this.target).scrollTop($(this.target)[0].scrollHeight)}print(t){t.match(/warn/i)?this.log("warn",t,!1):t.match(/error/i)?this.log("error",t,!1):this.log("info",t,!1)}clear(){$(this.target).empty()}}i.Logger=s,i.dependencies=["pkg://MonacoCore/path.js","pkg://MonacoCore/bundle/app.bundle.js"]}(i=t.application||(t.application={}))}(OS||(OS={})),function(t){class e{constructor(t,e){this.app=e,this.name=t}preload(){return t.API.require(t.application.Antedit.extensions[this.name].dependencies)}basedir(){return`${this.app.meta().path}/extensions/${this.name}`}notify(t){return this.app.notify(t)}error(t,e){return this.app.error(t,e)}logger(){return this.app.setting.showBottomBar?this.app.showOutput(!1):this.app.showOutput(!0),this.app.logger}metadata(e){return new Promise((i,a)=>{if(!this.app.currdir)return a(t.API.throwe(__("Current folder is not found")));`${this.app.currdir.path}/${e}`.asFileHandle().read("json").then(t=>{!t.root&&this.app.currdir&&(t.root=this.app.currdir.path),i(t)}).catch(s=>{this.app.openDialog("FileDialog",{title:__("Select build directory"),root:this.app.currdir.path,mimes:["dir"]}).then(t=>{`${t.file.path}/${e}`.asFileHandle().read("json").then(e=>{e.root||(e.root=t.file.path),i(e)}).catch(t=>a(t))}).catch(e=>a(t.API.throwe(__("Unable to read meta-data"))))})})}}e.dependencies=[],t.application.Antedit.extensions={},t.application.Antedit.EditorBaseExtension=e,t.application.Antedit.extensions.EditorExtensionMaker=class extends e{constructor(t){super("EditorExtensionMaker",t)}create(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(New extension at)",file:{basename:__("ExtensionName")},mimes:["dir"]}).then(t=>this.mktpl(t.file.path,t.name))}build(e){this.logger().clear(),this.metadata("extension.json").then(async i=>{try{const a=await t.API.VFS.cat(i.javascripts.map(t=>`${i.root}/${t}`),"");await(i.root+"/build/debug/main.js").asFileHandle().setCache(a).write("text/plain"),await(i.root+"/build/debug/extension.json").asFileHandle().setCache(i.meta).write("object"),await t.API.VFS.copy(i.copies.map(t=>`${i.root}/${t}`),i.root+"/build/debug"),this.logger().info(__("Files generated in {0}",i.root+"/build/debug")),e&&e()}catch(t){return this.logger().error(__("Unable to build extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}run(){this.logger().clear(),this.metadata("extension.json").then(async e=>{if(!e||!e.meta||!e.meta.name)return this.logger().error(__("Invalid extension meta-data"));try{const i=e.root+"/build/debug/main.js";t.API.shared[i]&&delete t.API.shared[i],await t.API.requires(i),this.app.extensions[e.meta.name]&&this.app.extensions[e.meta.name].cleanup&&this.app.extensions[e.meta.name].cleanup(),this.app.extensions[e.meta.name]=new t.application.Antedit.extensions[e.meta.name](this.app);for(let t of e.meta.actions)this.app.eum.addAction(e.meta,t,(t,i)=>{this.app.loadAndRunExtensionAction(t,i,e.root+"/build")});this.app.eum.active.getEditor().trigger(e.meta.name,"editor.action.quickCommand")}catch(t){return this.logger().error(__("Unable to run extension:{0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to read meta-data:{0}",t.stack)))}release(){this.logger().clear(),this.metadata("extension.json").then(async e=>{this.build(async()=>{try{await t.API.VFS.mkar(e.root+"/build/debug",`${e.root}/build/release/${e.meta.name}.zip`),this.logger().info(__("Archive created at {0}",`${e.root}/build/release/${e.meta.name}.zip`))}catch(t){return this.logger().error(__("Unable to create archive: {0}",t.stack))}})}).catch(t=>this.logger().error(__("Unable to read meta-data: {0}",t.stack)))}install(){this.logger().clear(),this.app.openDialog("FileDialog",{title:"__(Select extension archive)",mimes:[".*/zip"]}).then(async t=>{try{return await this.installZip(t.file.path),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(t){return this.logger().error(__("Unable to install extension: {0}",t.stack))}})}installFromURL(){this.logger().clear(),this.app.openDialog("PromptDialog",{title:__("Enter URI"),label:__("Please enter extension URI:")}).then(async t=>{if(t)try{return await this.installZip(t),this.logger().info(__("Extension installed")),this.app.loadExtensionMetaData()}catch(e){return this.app.error(__("Unable to install extension: {0}",t))}})}mktpl(e,i){const a=`${e}/${i}`,s=[a,a+"/build",a+"/build/release",a+"/build/debug"],n=[["main.tpl",`${a}/${i}.js`],["meta.tpl",a+"/extension.json"]];t.API.VFS.mkdirAll(s,!0).then(async()=>{try{return await t.API.VFS.mktpl(n,this.basedir(),t=>t.format(i,`${e}/${i}`)),this.app.currdir=a.asFileHandle(),this.app.toggleSideBar(),this.app.eum.active.openFile(`${a}/${i}.js`.asFileHandle())}catch(t){return this.logger().error(__("Unable to create extension template: {0}",t.stack))}}).catch(t=>this.logger().error(__("Unable to create extension directories: {0}",t.stack)))}uninstall(t){return new Promise(async(e,i)=>{try{const i=this.app.meta().path+"/extensions",a=(i+"/extensions.json").asFileHandle(),s=await a.read("json");let n=void 0,o=void 0;for(let e in s)if(s[e].name===t){n=s[e],o=e;break}if(void 0===n)return e();await`${i}/${t}`.asFileHandle().remove(),s.splice(o,1),a.cache=s,await a.write("object"),e()}catch(t){i(t)}})}installZip(e){return new Promise(async(i,a)=>{try{await t.API.requires("os://scripts/jszip.min.js");const a=await e.asFileHandle().read("binary"),s=await JSZip.loadAsync(a),n=await s.file("extension.json").async("uint8array"),o=JSON.parse(new TextDecoder("utf-8").decode(n));await this.uninstall(o.name);const r=this.ext_dir(o.name),l=[r],h=[];for(let t in s.files)s.files[t].dir?l.push(r+"/"+t):"extension.json"!=t&&h.push(t);l.length>0?(await t.API.VFS.mkdirAll(l,!0),await this.installFiles(h,s,o)):await this.installFiles(h,s,o),i()}catch(t){a(__e(t))}})}ext_dir(t){return`${this.app.meta().path}/extensions/${t}`}installFiles(t,e,i){return 0===t.length?this.installMeta(i):new Promise(async(a,s)=>{try{const n=t.splice(0,1)[0],o=`${this.ext_dir(i.name)}/${n}`,r=await e.file(n).async("uint8array"),l=await o.asFileHandle().setCache(new Blob([r],{type:"octet/stream"})).write("text/plain");if(l.error)return s(l.error);await this.installFiles(t,e,i),a()}catch(t){s(__e(t))}})}installMeta(t){return new Promise(async(e,i)=>{const a=(this.ext_dir("")+"/extensions.json").asFileHandle();try{const s=await a.read("json"),n=[];for(let t of s)n.push(t.name);const o=n.indexOf(t.name);o>=0&&s.splice(o,1),s.push(t);try{return await a.setCache(s).write("object"),e()}catch(t){return i(__e(t))}}catch(s){try{return await a.setCache([t]).write("object"),e()}catch(t){return i(__e(t))}}})}}}(OS||(OS={}));
\ No newline at end of file
diff --git a/Antedit/build/debug/package.json b/Antedit/build/debug/package.json
index 9c48649..d955966 100644
--- a/Antedit/build/debug/package.json
+++ b/Antedit/build/debug/package.json
@@ -7,7 +7,7 @@
         "author": "Xuan Sang LE",
         "email": "mrsang@iohub.dev"
     },
-    "version": "0.2.4-b",
+    "version": "0.2.5-b",
     "category": "Development",
     "iconclass": "bi bi-journal-code",
     "mimes": [
diff --git a/Antedit/build/release/Antedit.zip b/Antedit/build/release/Antedit.zip
index f13f8bc..6951c6b 100644
Binary files a/Antedit/build/release/Antedit.zip and b/Antedit/build/release/Antedit.zip differ
diff --git a/Antedit/package.json b/Antedit/package.json
index 9c48649..d955966 100644
--- a/Antedit/package.json
+++ b/Antedit/package.json
@@ -7,7 +7,7 @@
         "author": "Xuan Sang LE",
         "email": "mrsang@iohub.dev"
     },
-    "version": "0.2.4-b",
+    "version": "0.2.5-b",
     "category": "Development",
     "iconclass": "bi bi-journal-code",
     "mimes": [
diff --git a/Antedit/ts/main.ts b/Antedit/ts/main.ts
index 4829621..59a0ed3 100644
--- a/Antedit/ts/main.ts
+++ b/Antedit/ts/main.ts
@@ -561,7 +561,7 @@ namespace OS {
                 this.loadExtensionMetaData();
                 this.toggleSideBar();
                 this.toggleSplitMode();
-                this.applyAllSetting();
+                //this.applyAllSetting();
             }
 
             /**
@@ -718,7 +718,7 @@ namespace OS {
 
             showOutput(toggle: boolean = false): void {
                 if (toggle)
-                    this.showBottomBar(true);
+                    this.setting.showBottomBar = true;
                 this.bottombar.selectedIndex = 0;
             }
             
@@ -749,7 +749,6 @@ namespace OS {
              * @memberof Antedit
              */
             public showBottomBar(v: boolean): void {
-                this.setting.showBottomBar = v;
                 if (v) {
                     $(this.bottombar).show();
                 }
@@ -765,7 +764,7 @@ namespace OS {
              * @memberof Antedit
              */
             private toggleBottomBar(): void {
-                this.showBottomBar(!this.setting.showBottomBar);
+                this.setting.showBottomBar = !this.setting.showBottomBar;
             }
             
             /**
diff --git a/Blogger/build/release/Blogger.zip b/Blogger/build/release/Blogger.zip
index ff1f359..564d0b7 100644
Binary files a/Blogger/build/release/Blogger.zip and b/Blogger/build/release/Blogger.zip differ
diff --git a/CodePad/README.md b/CodePad/README.md
index e943e41..33657bd 100644
--- a/CodePad/README.md
+++ b/CodePad/README.md
@@ -3,5 +3,6 @@ A simple yet powerful code/text editor.
 CodePad is a text editor based on the ACE editor.
 
 ## Change logs
+- v0.1.7-a: fix setting bug using new AntOS setting API
 - v0.1.6-a: adapt to new AntOS v2.0.x
 - v0.1.5-a: CodePad moved out of AntOS based system as regular AntOS package
\ No newline at end of file
diff --git a/CodePad/build/debug/README.md b/CodePad/build/debug/README.md
index e943e41..33657bd 100644
--- a/CodePad/build/debug/README.md
+++ b/CodePad/build/debug/README.md
@@ -3,5 +3,6 @@ A simple yet powerful code/text editor.
 CodePad is a text editor based on the ACE editor.
 
 ## Change logs
+- v0.1.7-a: fix setting bug using new AntOS setting API
 - v0.1.6-a: adapt to new AntOS v2.0.x
 - v0.1.5-a: CodePad moved out of AntOS based system as regular AntOS package
\ No newline at end of file
diff --git a/CodePad/build/debug/main.js b/CodePad/build/debug/main.js
index 5065684..6bbf3b3 100644
--- a/CodePad/build/debug/main.js
+++ b/CodePad/build/debug/main.js
@@ -1 +1 @@
-var ace,OS;!function(t){let e;!function(e){class i extends e.BaseApplication{constructor(t){super("CodePad",t),this.currdir=void 0,this.sdk=void 0}main(){this.extensions={},this.eum=new s,this.fileview=this.find("fileview"),this.sidebar=this.find("sidebar"),this.bottombar=this.find("bottombar"),this.langstat=this.find("langstat"),this.editorstat=this.find("editorstat"),this.filestat=this.find("current-file-lbl"),this.logger=new a(this.find("output-tab")),this.split_mode=!0,this.eum.add(new e.ACEModel(this,this.find("left-tabbar"),this.find("left-editorarea"))).add(new e.ACEModel(this,this.find("right-tabbar"),this.find("right-editorarea"))),this.eum.onstatuschange=t=>this.updateStatus(t),this.fileview.fetch=t=>new Promise((async function(e,i){let s;s="string"==typeof t?t.asFileHandle():t;try{const t=await s.read();return t.error?i(t.error):e(t.result)}catch(t){return i(__e(t))}}));let t="Untitled".asFileHandle();return this.args&&this.args.length>0&&(this.addRecent(this.args[0].path),"dir"===this.args[0].type?this.currdir=this.args[0].path.asFileHandle():(t=this.args[0].path.asFileHandle(),this.currdir=t.parent())),this.setup(),this.eum.active.openFile(t)}setup(){this.setting.recent||(this.setting.recent=[]),this.fileview.onfileopen=t=>{if(t.data&&t.data.path&&"dir"!==t.data.type)return this.addRecent(t.data.path),this.eum.active.openFile(t.data.path.asFileHandle())},this.fileview.onfileselect=t=>{t.data&&t.data.path&&"dir"!==t.data.type&&this.eum.active.selectFile(t.data.path)},this.on("resize",()=>this.eum.resize()),this.on("focus",()=>this.eum.active.focus()),this.eum.contextmenuHandle=(t,e)=>(e.items=[{text:__("Change theme"),onmenuselect:async t=>{try{const t=this.eum.active.getThemes(),e=await this.openDialog("SelectionDialog",{title:__("Select theme"),data:t});this.eum.active.setTheme(e.theme)}catch(t){this.error(__("Unable to set theme"),t)}}},{text:__("Change language mode"),onmenuselect:async t=>{try{const t=this.eum.active.getModes().map(t=>({text:t.text,mode:t.mode})),e=await this.openDialog("SelectionDialog",{title:__("Select language"),data:t});this.eum.active.setMode(e)}catch(t){this.error(__("Unable to set language mode"),t)}}},{text:__("Build with AntOSDK"),shortcut:" (CTRL-ALT-B)",onmenuselect:async t=>{try{this.build()}catch(t){this.error(__("Unable to build with AntOSDK: {0}",t.toString()),t)}}}],e.show(t)),this.fileview.contextmenuHandle=(t,e)=>(e.items=[{text:"__(New file)",id:"new"},{text:"__(New folder)",id:"newdir"},{text:"__(Rename)",id:"rename"},{text:"__(Delete)",id:"delete"}],e.onmenuselect=t=>this.ctxFileMenuHandle(t),e.show(t)),this.bindKey("ALT-N",()=>this.menuAction("new")),this.bindKey("ALT-O",()=>this.menuAction("open")),this.bindKey("ALT-F",()=>this.menuAction("opendir")),this.bindKey("CTRL-S",()=>this.menuAction("save")),this.bindKey("ALT-W",()=>this.menuAction("saveas")),this.bindKey("CTRL-ALT-B",()=>this.build()),this.fileview.ondragndrop=t=>{const e=t.data.from[0].data.path.asFileHandle(),i=t.data.to.data.path;return e.move(`${i}/${e.basename}`).then((function(s){const a=i,o=e.parent().path;a.lengththis.error(__("Unable to move file/folder"),t))},this.on("filechange",t=>{let{path:e}=t.file;return"file"===t.type&&({path:e}=t.file.parent()),this.fileview.update(e)}),this.find("logger-clear").onbtclick=()=>{this.logger.clear()},void 0===this.setting.showBottomBar&&(this.setting.showBottomBar=!1),this.toggleSideBar(),this.toggleSplitMode(),this.applyAllSetting()}build(){this.currdir&&t.API.requires("pkg://libantosdk/main.js").then(async()=>{try{if(!t.API.AntOSDKBuilder)return;this.sdk||(this.sdk=new t.API.AntOSDKBuilder(this.logger,"")),this.logger.clear(),this.showBottomBar(!0);const e=(this.currdir.path+"/build.json").asFileHandle(),i=await e.read("json");i.root=this.currdir.path;const s=Object.keys(i.targets).map(t=>({text:t})),a=await this.openDialog("SelectionDialog",{title:__("Select a build target"),data:s});await this.load(this.sdk.batch([a.text],i))}catch(t){this.logger.error(__("No {0} file found in the current directory, or the file is invalid format","build.json"))}}).catch(t=>{this.logger.error(__("{0} is not installed, please install it: {1}","libantosdk"))})}updateStatus(t){t||(t=this.eum.active.getEditorStatus()),this.editorstat.text=__("Row {0}, col {1}, lines: {2}",t.row+1,t.column+1,t.line),t.langmode&&(this.langstat.text=t.langmode.text),this.filestat.text=t.file;let e=this.scheme;e.apptitle!=t.file&&(e.apptitle=t.file)}toggleSideBar(){this.currdir?($(this.sidebar).show(),this.fileview.path=this.currdir.path):$(this.sidebar).hide(),this.trigger("resize")}showOutput(t=!1){t&&this.showBottomBar(!0),this.bottombar.selectedIndex=0}applySetting(t){"showBottomBar"==t&&this.showBottomBar(this.setting.showBottomBar)}showBottomBar(t){this.setting.showBottomBar=t,t?$(this.bottombar).show():$(this.bottombar).hide(),this.trigger("resize")}toggleBottomBar(){this.showBottomBar(!this.setting.showBottomBar)}toggleSplitMode(){const t=this.find("right-panel"),e=this.eum.editors[1],i=this.eum.editors[0];if(this.split_mode){if(e.isDirty())return void this.notify(__("Unable to disable split view: Please save changes of modified files on the right panel"));e.closeAll(),$(t).hide(),this.split_mode=!1,i.focus()}else $(t).show(),this.split_mode=!0,e.openFile("Untitled".asFileHandle()),e.focus();this.trigger("resize")}fileMenu(){const t=this.setting.recent.map(t=>({text:t}));return{text:__("File"),nodes:[{text:__("New"),dataid:"new",shortcut:"A-N"},{text:__("Open Recent"),dataid:"recent",nodes:t,onchildselect:(t,e)=>{const i=t.data.item.data.text.asFileHandle();i.onready().then(t=>{t&&("dir"==t.type?(this.currdir=i,this.toggleSideBar()):this.eum.active.openFile(i))})}},{text:__("Open"),dataid:"open",shortcut:"A-O"},{text:__("Open Folder"),dataid:"opendir",shortcut:"A-F"},{text:__("Save"),dataid:"save",shortcut:"C-S"},{text:__("Save as"),dataid:"saveas",shortcut:"A-W"}],onchildselect:(t,e)=>this.menuAction(t.data.item.data.dataid,e)}}ctxFileMenuHandle(t){const e=t.data.item;if(!e)return;const i=e.data;if(!i)return;let s=this.fileview.selectedFile,a=this.currdir;switch(s&&"dir"===s.type&&(a=s.path.asFileHandle()),s&&"file"===s.type&&(a=s.path.asFileHandle().parent()),i.id){case"new":if(!a)return;this.openDialog("PromptDialog",{title:"__(New file)",label:"__(File name)"}).then(async t=>{const e=`${a.path}/${t}`.asFileHandle();try{return await e.write("text/plain"),this.fileview.update(a.path)}catch(t){return this.error(__("Fail to create: {0}",t.stack),t)}});break;case"newdir":if(!a)return;this.openDialog("PromptDialog",{title:"__(New folder)",label:"__(Folder name)"}).then(async t=>{try{return await a.mk(t),this.fileview.update(a.path)}catch(t){return this.error(__("Fail to create: {0}",a.path),t)}});break;case"rename":if(!s)return;this.openDialog("PromptDialog",{title:"__(Rename)",label:"__(File name)",value:s.filename}).then(async t=>{if(t!==s.filename){s=s.path.asFileHandle(),a=s.parent();try{return await s.move(`${a.path}/${t}`),this.fileview.update(a.path)}catch(t){return this.error(__("Fail to rename: {0}",s.path),t)}}});break;case"delete":if(!s)return;this.openDialog("YesNoDialog",{title:"__(Delete)",iconclass:"fa fa-question-circle",text:__("Do you really want to delete: {0}?",s.filename)}).then(async t=>{if(t){s=s.path.asFileHandle(),a=s.parent();try{return await s.remove(),this.fileview.update(a.path)}catch(t){return this.error(__("Fail to delete: {0}",s.path),t)}}})}}addRecent(t){this.setting.recent||(this.setting.recent=[]),this.setting.recent.includes(t)||(this.setting.recent.push(t),this.setting.recent.length>10&&(this.setting.recent=this.setting.recent.slice(0,10)))}menuAction(t,e){let i=this;switch(e&&(i=e),t){case"new":return i.eum.active.openFile("Untitled".asFileHandle());case"open":return i.openDialog("FileDialog",{title:__("Open file"),mimes:Array.from(i.meta().mimes).filter(t=>"dir"!==t)}).then(t=>{this.addRecent(t.file.path),i.eum.active.openFile(t.file.path.asFileHandle())});case"opendir":return i.openDialog("FileDialog",{title:__("Open folder"),mimes:["dir"]}).then((function(t){return i.addRecent(t.file.path),i.currdir=t.file.path.asFileHandle(),i.toggleSideBar()}));case"save":return i.eum.active.save();case"saveas":return i.eum.active.saveAs();default:return console.log(t)}}cleanup(t){let e;const i=this.eum.dirties();if(0!==i.length)t.preventDefault(),this.openDialog("YesNoDialog",{title:"__(Quit)",text:__("Ignore all unsaved files: {0} ?",(()=>{const t=[];for(e of Array.from(i))t.push(e.filename);return t})().join(", "))}).then(t=>{if(t){for(e of Array.from(i))e.dirty=!1;return this.quit(!1)}});else for(let t in this.extensions)this.extensions[t].ext&&this.extensions[t].ext.cleanup&&this.extensions[t].ext.cleanup()}menu(){return[this.fileMenu(),{text:"__(View)",nodes:[{text:"__(Toggle bottom bar)",dataid:"bottombar"},{text:"__(Toggle split view)",dataid:"splitview"}],onchildselect:(t,e)=>{switch(t.data.item.data.dataid){case"bottombar":return this.toggleBottomBar();case"splitview":return this.toggleSplitMode()}}}]}}e.CodePad=i;class s{constructor(){this.active_editor=void 0,this.models=[]}get editors(){return this.models}set contextmenuHandle(t){for(let e of this.models)e.contextmenuHandle=t}get active(){return this.active_editor}add(t){return this.models.push(t),this.active_editor||(this.active_editor=t),t.on("focus",()=>{this.active_editor=t}),this}set onstatuschange(t){for(let e of this.models)e.onstatuschange=t}dirties(){let t=[];for(let e of this.models)t=t.concat(e.dirties());return t}resize(){for(let t of this.models)t.resize()}}class a{constructor(t){this.target=t}info(t){this.log("info",t,!0)}warn(t){this.log("warn",t,!0)}error(t){this.log("error",t,!0)}log(t,e,i){let s=$("
").attr("class","code-pad-log-"+t);if(i){let t=new Date,i=t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+" "+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds();s.text(`[${i}]: ${e.__()}`)}else s.text(e.__());$(this.target).append(s),$(this.target).scrollTop($(this.target)[0].scrollHeight)}print(t){this.log("info",t,!1)}clear(){$(this.target).empty()}}i.Logger=a,i.dependencies=["pkg://ACECore/core/ace.js","pkg://ACECore/path.js","pkg://ACECore/core/ext-language_tools.js","pkg://ACECore/core/ext-modelist.js","pkg://ACECore/core/ext-themelist.js"]}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(t){t.BaseEditorModel=class{constructor(t,e,i){this.container=i,this.currfile="Untitled".asFileHandle(),this.tabbar=e,this.editorSetup(i),this.app=t,this.editormux=!1,this.onstatuschange=void 0,this.on("focus",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.on("input",()=>this.editormux?(this.editormux=!1,!1):this.currfile.dirty?void 0:(this.currfile.dirty=!0,this.currfile.text+="*",this.tabbar.update(void 0))),this.on("changeCursor",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.tabbar.ontabselect=t=>this.selecteTab($(t.data.item).index()),this.tabbar.ontabclose=t=>{const e=t.data.item;return!!e&&(e.data.dirty?(this.app.openDialog("YesNoDialog",{title:__("Close tab"),text:__("Close without saving ?")}).then(t=>t?this.closeTab(e):this.focus()),!1):this.closeTab(e))}}findTabByFile(t){const e=this.tabbar.items,i=(()=>{const i=[];for(let s=0;s(t.cache=e||"",this.newTab(t))).catch(e=>this.app.error(__("Unable to open: {0}",t.path),e)):this.newTab(t):this.tabbar.selected=e}write(t){this.currfile.cache=this.getValue(),t.write("text/plain").then(e=>{t.dirty=!1,t.text=t.basename,this.tabbar.update(void 0)}).catch(e=>this.app.error(__("Unable to save file: {0}",t.path),e))}save(){return this.currfile.cache=this.getValue(),this.currfile.basename?this.write(this.currfile):this.saveAs()}saveAs(){this.app.openDialog("FileDialog",{title:__("Save as"),file:this.currfile}).then(t=>{let e=t.file.path.asFileHandle();"file"===t.file.type&&(e=e.parent()),this.currfile.setPath(`${e.path}/${t.name}`),this.write(this.currfile)})}dirties(){const t=[];for(let e of Array.from(this.tabbar.items))e.dirty&&t.push(e);return t}set contextmenuHandle(t){this.container.contextmenuHandle=t}closeAll(){this.tabbar.items=[],this.resetEditor()}isDirty(){return this.dirties().length>0}}}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(t){class e extends t.BaseEditorModel{constructor(t,e,i){ace.require("ace/ext/language_tools"),super(t,e,i),this.modes=ace.require("ace/ext/modelist")}resetEditor(){this.setValue(""),this.editor.getSession().setUndoManager(new ace.UndoManager)}getTexModel(){const t={};return t.cursor=this.editor.getCursorPosition(),t.cache=this.getValue(),t.um=this.editor.session.getUndoManager(),t.langmode=this.mode,t}setTextModel(t){this.editor.getSession().setUndoManager(new ace.UndoManager),this.setValue(t.cache),this.setMode(t.langmode),t.cursor&&this.setCursor(t.cursor),this.editor.getSession().setUndoManager(t.um)}newTextModelFrom(t){const e={};return e.um=new ace.UndoManager,e.cache=t.cache,e.cursor=void 0,"Untitled"!==t.path.toString()?e.langmode=this.getModeForPath(t.path):e.langmode={text:"Text",mode:"ace/mode/text"},e}getModes(){const t=[];let e;for(e of Array.from(this.modes.modes))t.push({text:e.caption,mode:e.mode});return t}setTheme(t){this.editor.setTheme(t)}setCursor(t){this.editor.renderer.scrollCursorIntoView({row:t.row,column:t.column},.5),this.editor.selection.moveTo(t.row,t.column)}setMode(t){this.mode=t,this.editor.getSession().setMode(t.mode)}editorSetup(t){this.editor=ace.edit(t),this.editor.setOptions({enableBasicAutocompletion:!0,enableSnippets:!0,enableLiveAutocompletion:!0,highlightActiveLine:!0,highlightSelectedWord:!0,behavioursEnabled:!0,wrap:!0,fontSize:"10pt",showInvisibles:!0}),this.editor.setTheme("ace/theme/monokai"),this.editor.completers.push({getCompletions(t,e,i,s,a){}}),this.editor.getSession().setUseWrapMode(!0)}on(t,e){switch(t){case"input":case"focus":this.editor.on(t,e);break;case"changeCursor":this.editor.getSession().selection.on(t,e)}}resize(){this.editor.resize()}focus(){this.editor.focus()}getModeForPath(t){const e=this.modes.getModeForPath(t);return{text:e.caption,mode:e.mode}}getEditorStatus(){const t=this.editor.session.selection.getCursor(),e=this.editor.session.getLength();return{row:t.row,column:t.column,line:e,langmode:this.mode,file:this.currfile.path}}getValue(){return this.editor.getValue()}setValue(t){this.editor.setValue(t,-1)}getThemes(){const t=ace.require("ace/ext/themelist"),e=[];for(let i in t.themesByName){const s=t.themesByName[i];e.push({text:s.caption,theme:s.theme})}return e}}t.ACEModel=e}(e=t.application||(t.application={}))}(OS||(OS={}));
\ No newline at end of file
+var ace,OS;!function(t){let e;!function(e){class i extends e.BaseApplication{constructor(t){super("CodePad",t),this.currdir=void 0,this.sdk=void 0}main(){this.extensions={},this.eum=new s,this.fileview=this.find("fileview"),this.sidebar=this.find("sidebar"),this.bottombar=this.find("bottombar"),this.langstat=this.find("langstat"),this.editorstat=this.find("editorstat"),this.filestat=this.find("current-file-lbl"),this.logger=new a(this.find("output-tab")),this.split_mode=!0,this.eum.add(new e.ACEModel(this,this.find("left-tabbar"),this.find("left-editorarea"))).add(new e.ACEModel(this,this.find("right-tabbar"),this.find("right-editorarea"))),this.eum.onstatuschange=t=>this.updateStatus(t),this.fileview.fetch=t=>new Promise((async function(e,i){let s;s="string"==typeof t?t.asFileHandle():t;try{const t=await s.read();return t.error?i(t.error):e(t.result)}catch(t){return i(__e(t))}}));let t="Untitled".asFileHandle();return this.args&&this.args.length>0&&(this.addRecent(this.args[0].path),"dir"===this.args[0].type?this.currdir=this.args[0].path.asFileHandle():(t=this.args[0].path.asFileHandle(),this.currdir=t.parent())),this.setup(),this.eum.active.openFile(t)}setup(){this.setting.recent||(this.setting.recent=[]),this.fileview.onfileopen=t=>{if(t.data&&t.data.path&&"dir"!==t.data.type)return this.addRecent(t.data.path),this.eum.active.openFile(t.data.path.asFileHandle())},this.fileview.onfileselect=t=>{t.data&&t.data.path&&"dir"!==t.data.type&&this.eum.active.selectFile(t.data.path)},this.on("resize",()=>this.eum.resize()),this.on("focus",()=>this.eum.active.focus()),this.eum.contextmenuHandle=(t,e)=>(e.items=[{text:__("Change theme"),onmenuselect:async t=>{try{const t=this.eum.active.getThemes(),e=await this.openDialog("SelectionDialog",{title:__("Select theme"),data:t});this.eum.active.setTheme(e.theme)}catch(t){this.error(__("Unable to set theme"),t)}}},{text:__("Change language mode"),onmenuselect:async t=>{try{const t=this.eum.active.getModes().map(t=>({text:t.text,mode:t.mode})),e=await this.openDialog("SelectionDialog",{title:__("Select language"),data:t});this.eum.active.setMode(e)}catch(t){this.error(__("Unable to set language mode"),t)}}},{text:__("Build with AntOSDK"),shortcut:" (CTRL-ALT-B)",onmenuselect:async t=>{try{this.build()}catch(t){this.error(__("Unable to build with AntOSDK: {0}",t.toString()),t)}}}],e.show(t)),this.fileview.contextmenuHandle=(t,e)=>(e.items=[{text:"__(New file)",id:"new"},{text:"__(New folder)",id:"newdir"},{text:"__(Rename)",id:"rename"},{text:"__(Delete)",id:"delete"}],e.onmenuselect=t=>this.ctxFileMenuHandle(t),e.show(t)),this.bindKey("ALT-N",()=>this.menuAction("new")),this.bindKey("ALT-O",()=>this.menuAction("open")),this.bindKey("ALT-F",()=>this.menuAction("opendir")),this.bindKey("CTRL-S",()=>this.menuAction("save")),this.bindKey("ALT-W",()=>this.menuAction("saveas")),this.bindKey("CTRL-ALT-B",()=>this.build()),this.fileview.ondragndrop=t=>{const e=t.data.from[0].data.path.asFileHandle(),i=t.data.to.data.path;return e.move(`${i}/${e.basename}`).then((function(s){const a=i,o=e.parent().path;a.lengththis.error(__("Unable to move file/folder"),t))},this.on("filechange",t=>{let{path:e}=t.file;return"file"===t.type&&({path:e}=t.file.parent()),this.fileview.update(e)}),this.find("logger-clear").onbtclick=()=>{this.logger.clear()},void 0===this.setting.showBottomBar&&(this.setting.showBottomBar=!1),this.toggleSideBar(),this.toggleSplitMode()}build(){this.currdir&&t.API.requires("pkg://libantosdk/main.js").then(async()=>{try{if(!t.API.AntOSDKBuilder)return;this.sdk||(this.sdk=new t.API.AntOSDKBuilder(this.logger,"")),this.logger.clear(),this.setting.showBottomBar=!0;const e=(this.currdir.path+"/build.json").asFileHandle(),i=await e.read("json");i.root=this.currdir.path;const s=Object.keys(i.targets).map(t=>({text:t})),a=await this.openDialog("SelectionDialog",{title:__("Select a build target"),data:s});await this.load(this.sdk.batch([a.text],i))}catch(t){this.logger.error(__("No {0} file found in the current directory, or the file is invalid format","build.json"))}}).catch(t=>{this.logger.error(__("{0} is not installed, please install it: {1}","libantosdk"))})}updateStatus(t){t||(t=this.eum.active.getEditorStatus()),this.editorstat.text=__("Row {0}, col {1}, lines: {2}",t.row+1,t.column+1,t.line),t.langmode&&(this.langstat.text=t.langmode.text),this.filestat.text=t.file;let e=this.scheme;e.apptitle!=t.file&&(e.apptitle=t.file)}toggleSideBar(){this.currdir?($(this.sidebar).show(),this.fileview.path=this.currdir.path):$(this.sidebar).hide(),this.trigger("resize")}showOutput(t=!1){t&&(this.setting.showBottomBar=!0),this.bottombar.selectedIndex=0}applySetting(t){"showBottomBar"==t&&this.showBottomBar(this.setting.showBottomBar)}showBottomBar(t){t?$(this.bottombar).show():$(this.bottombar).hide(),this.trigger("resize")}toggleBottomBar(){this.setting.showBottomBar=!this.setting.showBottomBar}toggleSplitMode(){const t=this.find("right-panel"),e=this.eum.editors[1],i=this.eum.editors[0];if(this.split_mode){if(e.isDirty())return void this.notify(__("Unable to disable split view: Please save changes of modified files on the right panel"));e.closeAll(),$(t).hide(),this.split_mode=!1,i.focus()}else $(t).show(),this.split_mode=!0,e.openFile("Untitled".asFileHandle()),e.focus();this.trigger("resize")}fileMenu(){const t=this.setting.recent.map(t=>({text:t}));return{text:__("File"),nodes:[{text:__("New"),dataid:"new",shortcut:"A-N"},{text:__("Open Recent"),dataid:"recent",nodes:t,onchildselect:(t,e)=>{const i=t.data.item.data.text.asFileHandle();i.onready().then(t=>{t&&("dir"==t.type?(this.currdir=i,this.toggleSideBar()):this.eum.active.openFile(i))})}},{text:__("Open"),dataid:"open",shortcut:"A-O"},{text:__("Open Folder"),dataid:"opendir",shortcut:"A-F"},{text:__("Save"),dataid:"save",shortcut:"C-S"},{text:__("Save as"),dataid:"saveas",shortcut:"A-W"}],onchildselect:(t,e)=>this.menuAction(t.data.item.data.dataid,e)}}ctxFileMenuHandle(t){const e=t.data.item;if(!e)return;const i=e.data;if(!i)return;let s=this.fileview.selectedFile,a=this.currdir;switch(s&&"dir"===s.type&&(a=s.path.asFileHandle()),s&&"file"===s.type&&(a=s.path.asFileHandle().parent()),i.id){case"new":if(!a)return;this.openDialog("PromptDialog",{title:"__(New file)",label:"__(File name)"}).then(async t=>{const e=`${a.path}/${t}`.asFileHandle();try{return await e.write("text/plain"),this.fileview.update(a.path)}catch(t){return this.error(__("Fail to create: {0}",t.stack),t)}});break;case"newdir":if(!a)return;this.openDialog("PromptDialog",{title:"__(New folder)",label:"__(Folder name)"}).then(async t=>{try{return await a.mk(t),this.fileview.update(a.path)}catch(t){return this.error(__("Fail to create: {0}",a.path),t)}});break;case"rename":if(!s)return;this.openDialog("PromptDialog",{title:"__(Rename)",label:"__(File name)",value:s.filename}).then(async t=>{if(t!==s.filename){s=s.path.asFileHandle(),a=s.parent();try{return await s.move(`${a.path}/${t}`),this.fileview.update(a.path)}catch(t){return this.error(__("Fail to rename: {0}",s.path),t)}}});break;case"delete":if(!s)return;this.openDialog("YesNoDialog",{title:"__(Delete)",iconclass:"fa fa-question-circle",text:__("Do you really want to delete: {0}?",s.filename)}).then(async t=>{if(t){s=s.path.asFileHandle(),a=s.parent();try{return await s.remove(),this.fileview.update(a.path)}catch(t){return this.error(__("Fail to delete: {0}",s.path),t)}}})}}addRecent(t){this.setting.recent||(this.setting.recent=[]),this.setting.recent.includes(t)||(this.setting.recent.push(t),this.setting.recent.length>10&&(this.setting.recent=this.setting.recent.slice(0,10)))}menuAction(t,e){let i=this;switch(e&&(i=e),t){case"new":return i.eum.active.openFile("Untitled".asFileHandle());case"open":return i.openDialog("FileDialog",{title:__("Open file"),mimes:Array.from(i.meta().mimes).filter(t=>"dir"!==t)}).then(t=>{this.addRecent(t.file.path),i.eum.active.openFile(t.file.path.asFileHandle())});case"opendir":return i.openDialog("FileDialog",{title:__("Open folder"),mimes:["dir"]}).then((function(t){return i.addRecent(t.file.path),i.currdir=t.file.path.asFileHandle(),i.toggleSideBar()}));case"save":return i.eum.active.save();case"saveas":return i.eum.active.saveAs();default:return console.log(t)}}cleanup(t){let e;const i=this.eum.dirties();if(0!==i.length)t.preventDefault(),this.openDialog("YesNoDialog",{title:"__(Quit)",text:__("Ignore all unsaved files: {0} ?",(()=>{const t=[];for(e of Array.from(i))t.push(e.filename);return t})().join(", "))}).then(t=>{if(t){for(e of Array.from(i))e.dirty=!1;return this.quit(!1)}});else for(let t in this.extensions)this.extensions[t].ext&&this.extensions[t].ext.cleanup&&this.extensions[t].ext.cleanup()}menu(){return[this.fileMenu(),{text:"__(View)",nodes:[{text:"__(Toggle bottom bar)",dataid:"bottombar"},{text:"__(Toggle split view)",dataid:"splitview"}],onchildselect:(t,e)=>{switch(t.data.item.data.dataid){case"bottombar":return this.toggleBottomBar();case"splitview":return this.toggleSplitMode()}}}]}}e.CodePad=i;class s{constructor(){this.active_editor=void 0,this.models=[]}get editors(){return this.models}set contextmenuHandle(t){for(let e of this.models)e.contextmenuHandle=t}get active(){return this.active_editor}add(t){return this.models.push(t),this.active_editor||(this.active_editor=t),t.on("focus",()=>{this.active_editor=t}),this}set onstatuschange(t){for(let e of this.models)e.onstatuschange=t}dirties(){let t=[];for(let e of this.models)t=t.concat(e.dirties());return t}resize(){for(let t of this.models)t.resize()}}class a{constructor(t){this.target=t}info(t){this.log("info",t,!0)}warn(t){this.log("warn",t,!0)}error(t){this.log("error",t,!0)}log(t,e,i){let s=$("
").attr("class","code-pad-log-"+t);if(i){let t=new Date,i=t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+" "+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds();s.text(`[${i}]: ${e.__()}`)}else s.text(e.__());$(this.target).append(s),$(this.target).scrollTop($(this.target)[0].scrollHeight)}print(t){this.log("info",t,!1)}clear(){$(this.target).empty()}}i.Logger=a,i.dependencies=["pkg://ACECore/core/ace.js","pkg://ACECore/path.js","pkg://ACECore/core/ext-language_tools.js","pkg://ACECore/core/ext-modelist.js","pkg://ACECore/core/ext-themelist.js"]}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(t){t.BaseEditorModel=class{constructor(t,e,i){this.container=i,this.currfile="Untitled".asFileHandle(),this.tabbar=e,this.editorSetup(i),this.app=t,this.editormux=!1,this.onstatuschange=void 0,this.on("focus",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.on("input",()=>this.editormux?(this.editormux=!1,!1):this.currfile.dirty?void 0:(this.currfile.dirty=!0,this.currfile.text+="*",this.tabbar.update(void 0))),this.on("changeCursor",()=>{this.onstatuschange&&this.onstatuschange(this.getEditorStatus())}),this.tabbar.ontabselect=t=>this.selecteTab($(t.data.item).index()),this.tabbar.ontabclose=t=>{const e=t.data.item;return!!e&&(e.data.dirty?(this.app.openDialog("YesNoDialog",{title:__("Close tab"),text:__("Close without saving ?")}).then(t=>t?this.closeTab(e):this.focus()),!1):this.closeTab(e))}}findTabByFile(t){const e=this.tabbar.items,i=(()=>{const i=[];for(let s=0;s(t.cache=e||"",this.newTab(t))).catch(e=>this.app.error(__("Unable to open: {0}",t.path),e)):this.newTab(t):this.tabbar.selected=e}write(t){this.currfile.cache=this.getValue(),t.write("text/plain").then(e=>{t.dirty=!1,t.text=t.basename,this.tabbar.update(void 0)}).catch(e=>this.app.error(__("Unable to save file: {0}",t.path),e))}save(){return this.currfile.cache=this.getValue(),this.currfile.basename?this.write(this.currfile):this.saveAs()}saveAs(){this.app.openDialog("FileDialog",{title:__("Save as"),file:this.currfile}).then(t=>{let e=t.file.path.asFileHandle();"file"===t.file.type&&(e=e.parent()),this.currfile.setPath(`${e.path}/${t.name}`),this.write(this.currfile)})}dirties(){const t=[];for(let e of Array.from(this.tabbar.items))e.dirty&&t.push(e);return t}set contextmenuHandle(t){this.container.contextmenuHandle=t}closeAll(){this.tabbar.items=[],this.resetEditor()}isDirty(){return this.dirties().length>0}}}(e=t.application||(t.application={}))}(OS||(OS={})),function(t){let e;!function(t){class e extends t.BaseEditorModel{constructor(t,e,i){ace.require("ace/ext/language_tools"),super(t,e,i),this.modes=ace.require("ace/ext/modelist")}resetEditor(){this.setValue(""),this.editor.getSession().setUndoManager(new ace.UndoManager)}getTexModel(){const t={};return t.cursor=this.editor.getCursorPosition(),t.cache=this.getValue(),t.um=this.editor.session.getUndoManager(),t.langmode=this.mode,t}setTextModel(t){this.editor.getSession().setUndoManager(new ace.UndoManager),this.setValue(t.cache),this.setMode(t.langmode),t.cursor&&this.setCursor(t.cursor),this.editor.getSession().setUndoManager(t.um)}newTextModelFrom(t){const e={};return e.um=new ace.UndoManager,e.cache=t.cache,e.cursor=void 0,"Untitled"!==t.path.toString()?e.langmode=this.getModeForPath(t.path):e.langmode={text:"Text",mode:"ace/mode/text"},e}getModes(){const t=[];let e;for(e of Array.from(this.modes.modes))t.push({text:e.caption,mode:e.mode});return t}setTheme(t){this.editor.setTheme(t)}setCursor(t){this.editor.renderer.scrollCursorIntoView({row:t.row,column:t.column},.5),this.editor.selection.moveTo(t.row,t.column)}setMode(t){this.mode=t,this.editor.getSession().setMode(t.mode)}editorSetup(t){this.editor=ace.edit(t),this.editor.setOptions({enableBasicAutocompletion:!0,enableSnippets:!0,enableLiveAutocompletion:!0,highlightActiveLine:!0,highlightSelectedWord:!0,behavioursEnabled:!0,wrap:!0,fontSize:"10pt",showInvisibles:!0}),this.editor.setTheme("ace/theme/monokai"),this.editor.completers.push({getCompletions(t,e,i,s,a){}}),this.editor.getSession().setUseWrapMode(!0)}on(t,e){switch(t){case"input":case"focus":this.editor.on(t,e);break;case"changeCursor":this.editor.getSession().selection.on(t,e)}}resize(){this.editor.resize()}focus(){this.editor.focus()}getModeForPath(t){const e=this.modes.getModeForPath(t);return{text:e.caption,mode:e.mode}}getEditorStatus(){const t=this.editor.session.selection.getCursor(),e=this.editor.session.getLength();return{row:t.row,column:t.column,line:e,langmode:this.mode,file:this.currfile.path}}getValue(){return this.editor.getValue()}setValue(t){this.editor.setValue(t,-1)}getThemes(){const t=ace.require("ace/ext/themelist"),e=[];for(let i in t.themesByName){const s=t.themesByName[i];e.push({text:s.caption,theme:s.theme})}return e}}t.ACEModel=e}(e=t.application||(t.application={}))}(OS||(OS={}));
\ No newline at end of file
diff --git a/CodePad/build/debug/package.json b/CodePad/build/debug/package.json
index f7e2c8f..32eae21 100644
--- a/CodePad/build/debug/package.json
+++ b/CodePad/build/debug/package.json
@@ -8,7 +8,7 @@
         "email": "xsang.le@gmail.com",
         "licences": "GPLv3"
     },
-    "version":"0.1.6-b",
+    "version":"0.1.7-b",
     "category":"Development",
     "iconclass":"fa fa-pencil-square-o",
     "dependencies": ["ACECore@1.4.12-r"],
diff --git a/CodePad/build/release/CodePad.zip b/CodePad/build/release/CodePad.zip
index 6a51109..95470ae 100644
Binary files a/CodePad/build/release/CodePad.zip and b/CodePad/build/release/CodePad.zip differ
diff --git a/CodePad/package.json b/CodePad/package.json
index f7e2c8f..32eae21 100644
--- a/CodePad/package.json
+++ b/CodePad/package.json
@@ -8,7 +8,7 @@
         "email": "xsang.le@gmail.com",
         "licences": "GPLv3"
     },
-    "version":"0.1.6-b",
+    "version":"0.1.7-b",
     "category":"Development",
     "iconclass":"fa fa-pencil-square-o",
     "dependencies": ["ACECore@1.4.12-r"],
diff --git a/CodePad/ts/main.ts b/CodePad/ts/main.ts
index 679c5f4..d5fd361 100644
--- a/CodePad/ts/main.ts
+++ b/CodePad/ts/main.ts
@@ -364,7 +364,7 @@ namespace OS {
                 }
                 this.toggleSideBar();
                 this.toggleSplitMode();
-                this.applyAllSetting();
+                //this.applyAllSetting();
             }
 
             /**
@@ -390,7 +390,7 @@ namespace OS {
                                 this.sdk = new (API as any).AntOSDKBuilder(this.logger,"");
                             }
                             this.logger.clear();
-                            this.showBottomBar(true);
+                            this.setting.showBottomBar = true;
                             // check for meta file
                             const meta_file = `${this.currdir.path}/build.json`.asFileHandle();
                             const meta = await meta_file.read("json");
@@ -454,7 +454,7 @@ namespace OS {
 
             showOutput(toggle: boolean = false): void {
                 if (toggle)
-                    this.showBottomBar(true);
+                    this.setting.showBottomBar = true;
                 this.bottombar.selectedIndex = 0;
             }
 
@@ -479,7 +479,6 @@ namespace OS {
              * @memberof CodePad
              */
             public showBottomBar(v: boolean): void {
-                this.setting.showBottomBar = v;
                 if (v) {
                     $(this.bottombar).show();
                 }
@@ -495,7 +494,7 @@ namespace OS {
              * @memberof CodePad
              */
             private toggleBottomBar(): void {
-                this.showBottomBar(!this.setting.showBottomBar);
+                this.setting.showBottomBar = !this.setting.showBottomBar;
             }
 
             private toggleSplitMode(): void {
diff --git a/build.json b/build.json
index 0e9d4a2..75590fa 100644
--- a/build.json
+++ b/build.json
@@ -6,7 +6,7 @@
                     "name": "batch",
                     "data": {
                         "target": "release",
-                        "modules": ["About"]
+                        "modules": ["Blogger"]
                     }
                 }
             ]
diff --git a/packages.json b/packages.json
index 6c977c3..3eee405 100644
--- a/packages.json
+++ b/packages.json
@@ -45,7 +45,7 @@
 		"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/Antedit/README.md",
 		"category": "Development",
 		"author": "Xuan Sang LE",
-		"version": "0.2.4-b",
+		"version": "0.2.5-b",
 		"dependencies": ["MonacoCore@0.33.0-r"],
 		"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/Antedit/build/release/Antedit.zip"
 	},
@@ -69,16 +69,6 @@
 		"dependencies": ["Antunnel@0.2.0-b"],
 		"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/AntunnelPlugins/build/release/AntunnelPlugins.zip"
 	},
-	{
-		"pkgname": "AntunnelTestClient",
-		"name": "AntunnelTestClient",
-		"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/AntunnelTestClient/README.md",
-		"category": "Development",
-		"author": "Dany LE",
-		"version": "0.1.0-a",
-		"dependencies": ["Antunnel@0.2.1-b"],
-		"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/AntunnelTestClient/build/release/AntunnelTestClient.zip"
-	},
 	{
 		"pkgname": "Archive",
 		"name": "Archive",
@@ -95,7 +85,7 @@
 		"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/Blogger/README.md",
 		"category": "Internet",
 		"author": "Xuan Sang LE",
-		"version": "0.2.11-a",
+		"version": "0.2.12-a",
 		"dependencies": ["SimpleMDE@2.18.0-r","Katex@0.11.1-r","SQLiteDB@0.1.0-a"],"mimes":["none"],
 		"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/Blogger/build/release/Blogger.zip"
 	},
@@ -125,7 +115,7 @@
 		"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/CodePad/README.md",
 		"category": "Development",
 		"author": "Xuan Sang LE",
-		"version": "0.1.6-b",
+		"version": "0.1.7-b",
 		"dependencies": ["ACECore@1.4.12-r"],"mimes":["text/.*","[^/]*/json.*","[^/]*/.*ml","[^/]*/javascript","dir"],
 		"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/CodePad/build/release/CodePad.zip"
 	},
@@ -425,8 +415,8 @@
 		"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/SystemControl/README.md",
 		"category": "System",
 		"author": "",
-		"version": "0.1.11-a",
-		"dependencies": ["Antunnel@0.2.1-b"],"version":"0.1.11-a","category":"System","iconclass":"fafa-tachometer","mimes":["none"],
+		"version": "0.1.12-a",
+		"dependencies": ["Antunnel@0.2.1-b"],"version":"0.1.12-a","category":"System","iconclass":"fafa-tachometer","mimes":["none"],
 		"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/SystemControl/build/release/SystemControl.zip"
 	},
 	{
@@ -445,7 +435,7 @@
 		"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/vfsx/README.md",
 		"category": "Library",
 		"author": "Dany LE",
-		"version": "0.1.0-b",
+		"version": "0.1.1-b",
 		"dependencies": [],
 		"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/vfsx/build/release/vfsx.zip"
 	},
diff --git a/release/About.zip b/release/About.zip
index 3e18c49..c567b9d 100644
Binary files a/release/About.zip and b/release/About.zip differ
diff --git a/release/Antedit.md b/release/Antedit.md
index eddd226..3d7cca6 100644
--- a/release/Antedit.md
+++ b/release/Antedit.md
@@ -5,6 +5,7 @@ the editor that powers VS Code.
 The editor functionality can be extended by its extension mechanism.
 Extension can be developed/released/isntalled by the editor itself.
 ### Change logs
+- 0.2.5-b: Fix setting bug with new AntOS setting API
 - 0.2.3-b: Minor changes to adapt the core UI to the new AntOS 2.0.x
 - 0.2.3-b: Allow reload current file via context menu in case of external changes
 - 0.2.2-b: Support horizotal scrolling on horizotal tabbars
diff --git a/release/Antedit.zip b/release/Antedit.zip
index f13f8bc..6951c6b 100644
Binary files a/release/Antedit.zip and b/release/Antedit.zip differ
diff --git a/release/Blogger.zip b/release/Blogger.zip
index ff1f359..564d0b7 100644
Binary files a/release/Blogger.zip and b/release/Blogger.zip differ
diff --git a/release/CodePad.md b/release/CodePad.md
index e943e41..33657bd 100644
--- a/release/CodePad.md
+++ b/release/CodePad.md
@@ -3,5 +3,6 @@ A simple yet powerful code/text editor.
 CodePad is a text editor based on the ACE editor.
 
 ## Change logs
+- v0.1.7-a: fix setting bug using new AntOS setting API
 - v0.1.6-a: adapt to new AntOS v2.0.x
 - v0.1.5-a: CodePad moved out of AntOS based system as regular AntOS package
\ No newline at end of file
diff --git a/release/CodePad.zip b/release/CodePad.zip
index 6a51109..95470ae 100644
Binary files a/release/CodePad.zip and b/release/CodePad.zip differ
diff --git a/release/packages.json b/release/packages.json
index de28a73..cb71e70 100644
--- a/release/packages.json
+++ b/release/packages.json
@@ -1 +1 @@
-[{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libpdfjs.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libpdfjs.zip","category":"Library","dependencies":[],"author":"Xuan Sang LE","version":"2.6.347-r","pkgname":"libpdfjs","name":"PDF JS library"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/AntunnelPlugins.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/AntunnelPlugins.zip","category":"Library","dependencies":["Antunnel@0.2.0-b"],"author":"Dany LE","version":"0.1.2-a","pkgname":"AntunnelPlugins","name":"Antunnel Plugins"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/xTerm.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/xTerm.zip","category":"Library","dependencies":[],"author":"","version":"5.1.0-r","pkgname":"xTerm","name":"xTerm Library"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ServerLogClient.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ServerLogClient.zip","category":"System","dependencies":["Antunnel@0.2.1-b"],"author":"","version":"0.1.3-b","pkgname":"ServerLogClient","name":"Server log monitor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/VizApp.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/VizApp.zip","category":"Graphics","dependencies":["ACECore@1.4.12-r"],"author":"Xuan Sang LE","version":"0.1.0-a","pkgname":"VizApp","name":"Viz editor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/LuaPlayground.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/LuaPlayground.zip","category":"Development","dependencies":["ACECore@1.4.12-r"],"author":"Xuan Sang LE","version":"0.1.1-a","pkgname":"LuaPlayground","name":"LuaPlayground"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Clipper.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Clipper.zip","category":"Utility","dependencies":[],"author":"Xuan Sang LE","version":"0.1.4-a","pkgname":"Clipper","name":"Clipper"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libfabric.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libfabric.zip","category":"Library","dependencies":[],"author":"","version":"4.4.0-r","pkgname":"libfabric","name":"Fabric.js library"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ImageEditor.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ImageEditor.zip","category":"Graphics","dependencies":["libfabric@4.4.0-r"],"author":"Xuan Sang LE","version":"0.1.0-a","pkgname":"ImageEditor","name":"Image editor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Antedit.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Antedit.zip","category":"Development","dependencies":["MonacoCore@0.33.0-r"],"author":"Xuan Sang LE","version":"0.2.4-b","pkgname":"Antedit","name":"Antos Editor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/MonacoCore.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/MonacoCore.zip","category":"Library","dependencies":[],"author":"","version":"0.33.0-r","pkgname":"MonacoCore","name":"Monaco editor core"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/OnlyOffice.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/OnlyOffice.zip","category":"Office","dependencies":[],"author":"Xuan Sang LE","version":"0.1.8-a","pkgname":"OnlyOffice","name":"Office Suite"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/AceDiff.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/AceDiff.zip","category":"Library","dependencies":["ACECore@1.4.12-r"],"author":"","version":"3.0.3-r","pkgname":"AceDiff","name":"AceDiff addon library"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/TinyEditor.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/TinyEditor.zip","category":"Other","dependencies":[],"author":"Xuan Sang LE","version":"0.0.4-a","pkgname":"TinyEditor","name":"Tiny editor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/RemoteDesktop.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/RemoteDesktop.zip","category":"Internet","dependencies":[],"author":"Dany LE","version":"0.1.16-b","pkgname":"RemoteDesktop","name":"WVNC remote desktop"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ACECore.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ACECore.zip","category":"Library","dependencies":[],"author":"","version":"1.4.12-r","pkgname":"ACECore","name":"ACE Editor core"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GPClient.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GPClient.zip","category":"Internet","dependencies":[],"author":"Xuan Sang LE","version":"0.1.4-a","pkgname":"GPClient","name":"Generic Purpose client"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Preview.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Preview.zip","category":"Graphics","dependencies":["libpdfjs@2.6.347-r"],"author":"Xuan Sang LE","version":"0.1.3-a","pkgname":"Preview","name":"Preview"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Blogger.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Blogger.zip","category":"Internet","dependencies":["SimpleMDE@2.18.0-r","Katex@0.11.1-r","SQLiteDB@0.1.0-a"],"author":"Xuan Sang LE","version":"0.2.12-a","pkgname":"Blogger","name":"Blogging application"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/RemoteCamera.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/RemoteCamera.zip","category":"Graphics","dependencies":["libjpeg@0.1.1-a","Antunnel@0.1.8-a"],"author":"","version":"0.1.5-a","pkgname":"RemoteCamera","name":"Remote Camera"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Docify.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Docify.zip","category":"Office","dependencies":["SQLiteDB@0.1.0-a"],"author":"Dany LE","version":"0.1.0-b","pkgname":"Docify","name":"Docify"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/LibreOffice.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/LibreOffice.zip","category":"Office","dependencies":[],"author":"Dany LE","version":"0.1.4-a","pkgname":"LibreOffice","name":"Libre Office Online"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ActivityMonitor.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ActivityMonitor.zip","category":"System","dependencies":[],"author":"Xuan Sang LE","version":"0.0.8-b","pkgname":"ActivityMonitor","name":"Activity monitor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/vTerm.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/vTerm.zip","category":"System","dependencies":["Antunnel@0.2.1-b","xTerm@5.1.0-r"],"author":"Xuan Sang LE","version":"0.1.20-a","pkgname":"vTerm","name":"Virtual Terminal"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/vfsx.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/vfsx.zip","category":"Library","dependencies":[],"author":"Dany LE","version":"0.1.0-b","pkgname":"vfsx","name":"AntOS VFS handles"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/About.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/About.zip","category":"Utility","dependencies":[],"author":"Xuan Sang LE","version":"0.1.2-b","pkgname":"About","name":"About AntOS"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libwvnc.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libwvnc.zip","category":"Library","dependencies":["libjpeg@0.1.1-a"],"author":"","version":"0.1.2-a","pkgname":"libwvnc","name":"libwvnc"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/CodePad.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/CodePad.zip","category":"Development","dependencies":["ACECore@1.4.12-r"],"author":"Xuan Sang LE","version":"0.1.6-b","pkgname":"CodePad","name":"Code"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Booklet.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Booklet.zip","category":"Office","dependencies":["SimpleMDE@2.18.0-r","Katex@0.11.1-r"],"author":"Xuan Sang LE","version":"0.2.5-a","pkgname":"Booklet","name":"Booklet"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Antunnel.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Antunnel.zip","category":"Library","dependencies":[],"author":"Xuan Sang LE","version":"0.2.1-b","pkgname":"Antunnel","name":"Antunnel"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Archive.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Archive.zip","category":"Utility","dependencies":[],"author":"Xuan Sang LE","version":"0.0.4-a","pkgname":"Archive","name":"Archive"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ShowCase.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ShowCase.zip","category":"Utility","dependencies":[],"author":"Xuan Sang LE","version":"0.0.7-a","pkgname":"ShowCase","name":"ShowCase"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libthreejs.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libthreejs.zip","category":"Library","dependencies":[],"author":"","version":"0.0.129-r","pkgname":"libthreejs","name":"libthreejs"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GraphEditor.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GraphEditor.zip","category":"Graphics","dependencies":["ACECore@1.4.12-r"],"author":"Xuan Sang LE","version":"0.1.2-a","pkgname":"GraphEditor","name":"Graph Editor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SystemControl.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SystemControl.zip","category":"System","dependencies":["Antunnel@0.2.1-b"],"author":"","version":"0.1.12-a","pkgname":"SystemControl","name":"System monitoring"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ShaderPlayground.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ShaderPlayground.zip","category":"Development","dependencies":["libthreejs@0.0.129-r"],"author":"Xuan Sang LE","version":"0.0.4-a","pkgname":"ShaderPlayground","name":"OpenGL Shader Playground"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Katex.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Katex.zip","category":"Library","dependencies":[],"author":"","version":"0.11.1-r","pkgname":"Katex","name":"Katex"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libplotly.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libplotly.zip","category":"Library","dependencies":[],"author":"Dany LE","version":"2.6.2-r","pkgname":"libplotly","name":"Plotly"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/DBDecoder.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/DBDecoder.zip","category":"Other","dependencies":[],"author":"","version":"0.0.2-a","pkgname":"DBDecoder","name":"DBDecoder"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SimpleMDE.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SimpleMDE.zip","category":"Library","dependencies":[],"author":"","version":"2.18.0-r","pkgname":"SimpleMDE","name":"EasyMDE"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libantosdk.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libantosdk.zip","category":"Development","dependencies":[],"author":"Xuan Sang LE","version":"0.1.2-b","pkgname":"libantosdk","name":"AntOS SDK builder"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GitGraph.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GitGraph.zip","category":"Development","dependencies":[],"author":"Dany LE","version":"0.1.5-b","pkgname":"GitGraph","name":"GIT Visualization"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/DiffEditor.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/DiffEditor.zip","category":"Development","dependencies":["AceDiff@3.0.3-r"],"author":"","version":"0.1.6-a","pkgname":"DiffEditor","name":"Diff Editor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SQLiteDB.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SQLiteDB.zip","category":"Library","dependencies":[],"author":"Dany LE","version":"0.1.0-a","pkgname":"SQLiteDB","name":"SQLite3 Browser"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/MarkOn.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/MarkOn.zip","category":"Office","dependencies":["SimpleMDE@2.18.0-r"],"author":"Xuan Sang LE","version":"0.1.1-a","pkgname":"MarkOn","name":"Markdown editor"},{"description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Dockman.md","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Dockman.zip","category":"Development","dependencies":[],"author":"Xuan Sang LE","version":"0.1.1-b","pkgname":"Dockman","name":"Remote Docker Manager"}]
\ No newline at end of file
+[{"pkgname":"libpdfjs","name":"PDF JS library","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libpdfjs.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libpdfjs.md","version":"2.6.347-r","author":"Xuan Sang LE"},{"pkgname":"AntunnelPlugins","name":"Antunnel Plugins","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/AntunnelPlugins.zip","dependencies":["Antunnel@0.2.0-b"],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/AntunnelPlugins.md","version":"0.1.2-a","author":"Dany LE"},{"pkgname":"xTerm","name":"xTerm Library","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/xTerm.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/xTerm.md","version":"5.1.0-r","author":""},{"pkgname":"ServerLogClient","name":"Server log monitor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ServerLogClient.zip","dependencies":["Antunnel@0.2.1-b"],"category":"System","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ServerLogClient.md","version":"0.1.3-b","author":""},{"pkgname":"VizApp","name":"Viz editor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/VizApp.zip","dependencies":["ACECore@1.4.12-r"],"category":"Graphics","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/VizApp.md","version":"0.1.0-a","author":"Xuan Sang LE"},{"pkgname":"LuaPlayground","name":"LuaPlayground","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/LuaPlayground.zip","dependencies":["ACECore@1.4.12-r"],"category":"Development","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/LuaPlayground.md","version":"0.1.1-a","author":"Xuan Sang LE"},{"pkgname":"Clipper","name":"Clipper","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Clipper.zip","dependencies":[],"category":"Utility","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Clipper.md","version":"0.1.4-a","author":"Xuan Sang LE"},{"pkgname":"libfabric","name":"Fabric.js library","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libfabric.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libfabric.md","version":"4.4.0-r","author":""},{"pkgname":"ImageEditor","name":"Image editor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ImageEditor.zip","dependencies":["libfabric@4.4.0-r"],"category":"Graphics","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ImageEditor.md","version":"0.1.0-a","author":"Xuan Sang LE"},{"pkgname":"Antedit","name":"Antos Editor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Antedit.zip","dependencies":["MonacoCore@0.33.0-r"],"category":"Development","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Antedit.md","version":"0.2.5-b","author":"Xuan Sang LE"},{"pkgname":"MonacoCore","name":"Monaco editor core","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/MonacoCore.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/MonacoCore.md","version":"0.33.0-r","author":""},{"pkgname":"OnlyOffice","name":"Office Suite","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/OnlyOffice.zip","dependencies":[],"category":"Office","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/OnlyOffice.md","version":"0.1.8-a","author":"Xuan Sang LE"},{"pkgname":"AceDiff","name":"AceDiff addon library","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/AceDiff.zip","dependencies":["ACECore@1.4.12-r"],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/AceDiff.md","version":"3.0.3-r","author":""},{"pkgname":"TinyEditor","name":"Tiny editor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/TinyEditor.zip","dependencies":[],"category":"Other","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/TinyEditor.md","version":"0.0.4-a","author":"Xuan Sang LE"},{"pkgname":"RemoteDesktop","name":"WVNC remote desktop","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/RemoteDesktop.zip","dependencies":[],"category":"Internet","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/RemoteDesktop.md","version":"0.1.16-b","author":"Dany LE"},{"pkgname":"ACECore","name":"ACE Editor core","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ACECore.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ACECore.md","version":"1.4.12-r","author":""},{"pkgname":"GPClient","name":"Generic Purpose client","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GPClient.zip","dependencies":[],"category":"Internet","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GPClient.md","version":"0.1.4-a","author":"Xuan Sang LE"},{"pkgname":"Preview","name":"Preview","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Preview.zip","dependencies":["libpdfjs@2.6.347-r"],"category":"Graphics","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Preview.md","version":"0.1.3-a","author":"Xuan Sang LE"},{"pkgname":"Blogger","name":"Blogging application","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Blogger.zip","dependencies":["SimpleMDE@2.18.0-r","Katex@0.11.1-r","SQLiteDB@0.1.0-a"],"category":"Internet","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Blogger.md","version":"0.2.12-a","author":"Xuan Sang LE"},{"pkgname":"RemoteCamera","name":"Remote Camera","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/RemoteCamera.zip","dependencies":["libjpeg@0.1.1-a","Antunnel@0.1.8-a"],"category":"Graphics","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/RemoteCamera.md","version":"0.1.5-a","author":""},{"pkgname":"Docify","name":"Docify","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Docify.zip","dependencies":["SQLiteDB@0.1.0-a"],"category":"Office","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Docify.md","version":"0.1.0-b","author":"Dany LE"},{"pkgname":"LibreOffice","name":"Libre Office Online","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/LibreOffice.zip","dependencies":[],"category":"Office","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/LibreOffice.md","version":"0.1.4-a","author":"Dany LE"},{"pkgname":"ActivityMonitor","name":"Activity monitor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ActivityMonitor.zip","dependencies":[],"category":"System","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ActivityMonitor.md","version":"0.0.8-b","author":"Xuan Sang LE"},{"pkgname":"vTerm","name":"Virtual Terminal","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/vTerm.zip","dependencies":["Antunnel@0.2.1-b","xTerm@5.1.0-r"],"category":"System","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/vTerm.md","version":"0.1.20-a","author":"Xuan Sang LE"},{"pkgname":"vfsx","name":"AntOS VFS handles","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/vfsx.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/vfsx.md","version":"0.1.1-b","author":"Dany LE"},{"pkgname":"About","name":"About AntOS","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/About.zip","dependencies":[],"category":"Utility","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/About.md","version":"0.1.2-b","author":"Xuan Sang LE"},{"pkgname":"libwvnc","name":"libwvnc","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libwvnc.zip","dependencies":["libjpeg@0.1.1-a"],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libwvnc.md","version":"0.1.2-a","author":""},{"pkgname":"CodePad","name":"Code","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/CodePad.zip","dependencies":["ACECore@1.4.12-r"],"category":"Development","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/CodePad.md","version":"0.1.7-b","author":"Xuan Sang LE"},{"pkgname":"Booklet","name":"Booklet","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Booklet.zip","dependencies":["SimpleMDE@2.18.0-r","Katex@0.11.1-r"],"category":"Office","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Booklet.md","version":"0.2.5-a","author":"Xuan Sang LE"},{"pkgname":"Antunnel","name":"Antunnel","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Antunnel.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Antunnel.md","version":"0.2.1-b","author":"Xuan Sang LE"},{"pkgname":"Archive","name":"Archive","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Archive.zip","dependencies":[],"category":"Utility","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Archive.md","version":"0.0.4-a","author":"Xuan Sang LE"},{"pkgname":"ShowCase","name":"ShowCase","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ShowCase.zip","dependencies":[],"category":"Utility","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ShowCase.md","version":"0.0.7-a","author":"Xuan Sang LE"},{"pkgname":"libthreejs","name":"libthreejs","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libthreejs.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libthreejs.md","version":"0.0.129-r","author":""},{"pkgname":"GraphEditor","name":"Graph Editor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GraphEditor.zip","dependencies":["ACECore@1.4.12-r"],"category":"Graphics","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GraphEditor.md","version":"0.1.2-a","author":"Xuan Sang LE"},{"pkgname":"SystemControl","name":"System monitoring","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SystemControl.zip","dependencies":["Antunnel@0.2.1-b"],"category":"System","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SystemControl.md","version":"0.1.12-a","author":""},{"pkgname":"ShaderPlayground","name":"OpenGL Shader Playground","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ShaderPlayground.zip","dependencies":["libthreejs@0.0.129-r"],"category":"Development","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/ShaderPlayground.md","version":"0.0.4-a","author":"Xuan Sang LE"},{"pkgname":"Katex","name":"Katex","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Katex.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Katex.md","version":"0.11.1-r","author":""},{"pkgname":"libplotly","name":"Plotly","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libplotly.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libplotly.md","version":"2.6.2-r","author":"Dany LE"},{"pkgname":"DBDecoder","name":"DBDecoder","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/DBDecoder.zip","dependencies":[],"category":"Other","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/DBDecoder.md","version":"0.0.2-a","author":""},{"pkgname":"SimpleMDE","name":"EasyMDE","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SimpleMDE.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SimpleMDE.md","version":"2.18.0-r","author":""},{"pkgname":"libantosdk","name":"AntOS SDK builder","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libantosdk.zip","dependencies":[],"category":"Development","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/libantosdk.md","version":"0.1.2-b","author":"Xuan Sang LE"},{"pkgname":"GitGraph","name":"GIT Visualization","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GitGraph.zip","dependencies":[],"category":"Development","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/GitGraph.md","version":"0.1.5-b","author":"Dany LE"},{"pkgname":"DiffEditor","name":"Diff Editor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/DiffEditor.zip","dependencies":["AceDiff@3.0.3-r"],"category":"Development","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/DiffEditor.md","version":"0.1.6-a","author":""},{"pkgname":"SQLiteDB","name":"SQLite3 Browser","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SQLiteDB.zip","dependencies":[],"category":"Library","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/SQLiteDB.md","version":"0.1.0-a","author":"Dany LE"},{"pkgname":"MarkOn","name":"Markdown editor","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/MarkOn.zip","dependencies":["SimpleMDE@2.18.0-r"],"category":"Office","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/MarkOn.md","version":"0.1.1-a","author":"Xuan Sang LE"},{"pkgname":"Dockman","name":"Remote Docker Manager","download":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Dockman.zip","dependencies":[],"category":"Development","description":"https://ci.iohub.dev/public/antos-release/packages/2.0.x/Dockman.md","version":"0.1.1-b","author":"Xuan Sang LE"}]
\ No newline at end of file
diff --git a/release/vfsx.md b/release/vfsx.md
index 7af9f87..d4aafeb 100644
--- a/release/vfsx.md
+++ b/release/vfsx.md
@@ -8,3 +8,4 @@ This package is used mainly by the File application to communicate with differen
 file hosting protocols
 
 ## Change logs
+* v0.1.1-b Use new Task API for tracking task
diff --git a/release/vfsx.zip b/release/vfsx.zip
index e1fb21f..7ded1c6 100644
Binary files a/release/vfsx.zip and b/release/vfsx.zip differ
diff --git a/vfsx/README.md b/vfsx/README.md
index 7af9f87..d4aafeb 100644
--- a/vfsx/README.md
+++ b/vfsx/README.md
@@ -8,3 +8,4 @@ This package is used mainly by the File application to communicate with differen
 file hosting protocols
 
 ## Change logs
+* v0.1.1-b Use new Task API for tracking task
diff --git a/vfsx/build/debug/README.md b/vfsx/build/debug/README.md
index 7af9f87..d4aafeb 100644
--- a/vfsx/build/debug/README.md
+++ b/vfsx/build/debug/README.md
@@ -8,3 +8,4 @@ This package is used mainly by the File application to communicate with differen
 file hosting protocols
 
 ## Change logs
+* v0.1.1-b Use new Task API for tracking task
diff --git a/vfsx/build/debug/package.json b/vfsx/build/debug/package.json
index c1c26c1..ceb2f22 100644
--- a/vfsx/build/debug/package.json
+++ b/vfsx/build/debug/package.json
@@ -6,7 +6,7 @@
         "author": "Dany LE",
         "email": "mrsang@iohub.dev"
     },
-    "version": "0.1.0-b",
+    "version": "0.1.1-b",
     "category": "Library",
     "iconclass": "fa fa-cog",
     "mimes": [
diff --git a/vfsx/build/debug/vfsx.js b/vfsx/build/debug/vfsx.js
index c34a3e8..b580c9d 100644
--- a/vfsx/build/debug/vfsx.js
+++ b/vfsx/build/debug/vfsx.js
@@ -1 +1 @@
-var OS;!function(e){let t;!function(t){let i;!function(i){let a={"gdv://":{id:"root",mime:"dir"}};class r extends i.BaseFileHandle{constructor(t){super(t),r.API_META?(this.isRoot()&&(this.gid="root"),this.cache="",this.local_copy=void 0):e.announcer.oserror(__("Unknown API setting for GAPI"),e.API.throwe("OS.VFS"))}fields(){return"webContentLink, id, name,mimeType,description, kind, parents, properties, iconLink, createdTime, modifiedTime, owners, permissions, fullFileExtension, fileExtension, size, version"}isFolder(){return"application/vnd.google-apps.folder"===this.info.mimeType}load(e){const i=t.mid();return new Promise(async(a,r)=>{t.loading(i,"GAPI");try{let r=await e;return t.loaded(i,"GAPI","OK"),a(r)}catch(e){return t.loaded(i,"GAPI","FAIL"),r(__e(e))}})}sync(t){return new Promise(async(a,r)=>{try{if(this.info&&this.info.version==t.version||"application/vnd.google-apps.folder"===t.mimeType)a(!0);else{await i.mkdirAll(["home://.gdv_cache","home://.gdv_cache/"+t.id],!0);let e=`home://.gdv_cache/${t.id}/${t.version}.${t.fullFileExtension}`.asFileHandle();try{await e.onready()}catch(a){await("home://.gdv_cache/"+t.id).asFileHandle().remove(),await i.mkdirAll(["home://.gdv_cache/"+t.id]);let r=await this.load(gapi.client.drive.files.get({fileId:t.id,alt:"media"}));if(!r.body)throw new Error(__("VFS cannot download file : {0}",this.path).__());e.cache=new Blob([r.body.asUint8Array()],{type:"octet/stream"}),await e.write(t.mimeType)}this.local_copy=e,a(!0)}}catch(t){e.announcer.oserror(t.toString(),t),r(__e(t))}})}meta(){return new Promise(async(t,i)=>{try{if(await this.oninit(),a[this.path]&&(this.gid=a[this.path].id),this.gid){let e=await this.load(gapi.client.drive.files.get({fileId:this.gid,fields:this.fields()}));if(!e.result)throw new Error(__("VFS cannot get meta data for {0}",this.gid).__());e.result.mime=e.result.mimeType,await this.load(this.sync(e.result)),t(e)}else{const e=this.parent().asFileHandle(),i=(await e.meta()).result;a[e.path]={id:i.id,mime:i.mimeType};let r=await this.load(gapi.client.drive.files.list({q:`name = '${this.basename}' and '${i.id}' in parents and trashed = false`,fields:`files(${this.fields()})`}));if(!(r.result.files&&r.result.files.length>0))throw new Error(__("VFS cannot get meta data for {0}",this.path).__());a[this.path]={id:r.result.files[0].id,mime:r.result.files[0].mimeType},r.result.files[0].mime=r.result.files[0].mimeType,this.gid=a[this.path].id,await this.load(this.sync(r.result.files[0])),t({result:r.result.files[0],error:!1})}}catch(t){e.announcer.oserror(t.toString(),t),i(__e(t))}})}oninit(){return new Promise(async(i,n)=>{const o=async function(e){if(e)return i(!0);a={"gdv://":{id:"root",mime:"dir"}};try{let e=await gapi.auth2.getAuthInstance().signIn();i(e)}catch(e){n(__e(e))}};try{if(!r.API_META)throw new Error(__("No GAPI meta found").__());if(t.libready(r.API_META.apilink))gapi.auth2.getAuthInstance().isSignedIn.listen(e=>o(e)),o(gapi.auth2.getAuthInstance().isSignedIn.get());else{if(await this.load(t.requires(r.API_META.apilink,!1)),await this.load(new Promise((e,t)=>{gapi.load("client:auth2",e)})),await this.load(gapi.client.init({apiKey:r.API_META.API_KEY,clientId:r.API_META.CLIENT_ID,discoveryDocs:r.API_META.DISCOVERY_DOCS,scope:r.API_META.SCOPES})),gapi.auth2.getAuthInstance().isSignedIn.listen(e=>o(e)),!await e.GUI.openDialog("YesNoDialog",{title:__("Authentication"),text:__("Would you like to login to GoogleDrive?")}))throw new Error(__("User abort the authentication").__());o(gapi.auth2.getAuthInstance().isSignedIn.get())}}catch(t){e.announcer.oserror(t.toString(),t),n(__e(t))}})}getlink(){if(this.local_copy)return this.local_copy.getlink()}child(e){if(this.isFolder())return`${this.path}/${e}`}_rd(t){return new Promise(async(i,r)=>{try{if(!this.info.id)throw new Error(__("File ID is not valid").__());if(this.isFolder()){let e=await this.load(gapi.client.drive.files.list({q:`'${this.info.id}' in parents and trashed = false`,fields:`files(${this.fields()})`}));if(!e.result.files)throw new Error(__("File {0} not found",this.info.id).__());for(let t of e.result.files)t.path=this.child(t.name),t.mime=t.mimeType,t.filename=t.name,t.type="file",t.gid=t.id,"application/vnd.google-apps.folder"===t.mimeType&&(t.mime="dir",t.type="dir",t.size=0),a[t.path]={id:t.gid,mime:t.mime};i({result:e.result.files,error:!1})}else{if(!this.local_copy)throw new Error(__("Cannot find local copy of file; {0}",this.path).__());i(await this.local_copy.read(t))}}catch(t){e.announcer.oserror(t.toString(),t),r(__e(t))}})}save(t,i){return new Promise(async(a,n)=>{try{const o=gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token,s=new XMLHttpRequest,l=__(r.API_META.uploadlink,t).__();s.open("PATCH",l),s.setRequestHeader("Authorization","Bearer "+o),s.setRequestHeader("Content-Type",i),s.setRequestHeader("Content-Encoding","base64"),s.setRequestHeader("Content-Transfer-Encoding","base64");let d=t=>(e.announcer.oserror(__("VFS cannot save : {0}",this.path),t),n(t));s.onreadystatechange=()=>{if(4===s.readyState){if(200===s.status)return a({result:JSON.parse(s.responseText),error:!1});d(e.API.throwe("OS.VFS"))}},s.onerror=()=>d(e.API.throwe("OS.VFS"));let c=this.cache;"base64"!==i&&(c=await this.b64(i)),s.send(c.replace(/^data:[^;]+;base64,/g,"")),a(!0)}catch(e){n(__e(e))}})}_wr(t,i){return new Promise(async(i,r)=>{try{var n=void 0;if(a[this.path]&&(n=a[this.path].id),n)i(await this.load(this.save(n,t)));else{const e=this.parent().asFileHandle();await e.onready();const r={name:this.basename,mimeType:t,parents:[e.info.id]};let n=await this.load(gapi.client.drive.files.create({resource:r,fields:"id"}));if(!n||!n.result)throw new Error(__("VFS cannot write : {0}",this.path).__());a[this.path]={id:n.result.id,mime:t},i(this.load(this.save(n.result.id,t)))}}catch(t){e.announcer.oserror(t.toString(),t),r(__e(t))}})}_mk(t){return new Promise(async(i,r)=>{try{if(!this.isFolder())throw new Error(__("{0} is not a directory",this.path).__());var n={name:t,parents:[this.info.id],mimeType:"application/vnd.google-apps.folder"};let e=await this.load(gapi.client.drive.files.create({resource:n,fields:"id"}));if(!e||!e.result)throw new Error(__("VFS cannot create : {0}",t).__());a[this.child(t)]={id:e.result.id,mime:"dir"},i(e)}catch(t){e.announcer.oserror(t.toString(),t),r(__e(t))}})}_rm(){return new Promise(async(t,i)=>{try{if(!this.info.id)throw new Error(__("Cannot identify file id of {0}",this.path).__());if(!await this.load(gapi.client.drive.files.delete({fileId:this.info.id})))throw new Error(__("VFS cannot delete : {0}",this.path).__());a[this.path]=null,delete a[this.path],t({result:!0,error:!1})}catch(t){e.announcer.oserror(t.toString(),t),i(__e(t))}})}_mv(t){return new Promise(async(i,a)=>{try{var r=t.asFileHandle().parent().asFileHandle();await r.onready();const e=this.info.parents.join(",");let a=await this.load(gapi.client.drive.files.update({fileId:this.info.id,addParents:r.info.id,removeParents:e,fields:"id"}));if(!a)throw new Error(__("VFS cannot move : {0}",this.path).__());i(a)}catch(t){e.announcer.oserror(t.toString(),t),a(__e(t))}})}_up(){return new Promise(async(t,i)=>{try{if(!this.isFolder())throw new Error(__("Target file should be a folder").__());var a=$("").attr("type","file").css("display","none");a.on("change",async()=>{const e=a[0].files[0],t=this.child(e.name).asFileHandle();return t.cache=e,await this.load(t.write(e.type)),a.remove()}),a.trigger("click")}catch(t){e.announcer.oserror(t.toString(),t),i(__e(t))}})}_down(){return new Promise(async(t,i)=>{try{let i=await this.load(gapi.client.drive.files.get({fileId:this.info.id,alt:"media"}));if(!i.body)throw new Error(__("VFS cannot download file : {0}",this.path).__());let a=[];for(let e=0,t=i.body.length-1,r=0<=t;r?e<=t:e>=t;r?e++:e--)a.push(i.body.charCodeAt(e));let r=new Uint8Array(a);const n=new Blob([r],{type:"octet/stream"});e.API.saveblob(this.basename,n),t(!0)}catch(t){e.announcer.oserror(t.toString(),t),i(__e(t))}})}}i.GoogleDriveHandle=r,r.API_META={CLIENT_ID:"1006507170703-l322pfkrhf9cgta4l4jh2p8ughtc14id.apps.googleusercontent.com",API_KEY:"AIzaSyBZhM5KbARvT10acWC8JQKlRn2WbSsmfLc",apilink:"https://apis.google.com/js/api.js",DISCOVERY_DOCS:["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],SCOPES:"https://www.googleapis.com/auth/drive",uploadlink:"https://www.googleapis.com/upload/drive/v3/files/{0}?uploadType=media",logout:"https://www.google.com/accounts/Logout"},i.register("^gdv$",r),t.onsearch("Google Drive",(function(e){const t=[],i=new RegExp(e,"i");for(let e in a){const r=a[e];if(e.match(i)||r&&r.mime.match(i)){const i=e.asFileHandle();i.text=i.basename,i.mime=r.mime,i.iconclass="fa fa-file","dir"===i.mime&&(i.iconclass="fa fa-folder"),i.complex=!0,i.detail=[{text:i.path}],t.push(i)}}return t})),e.onexit("cleanUpGoogleDrive",(function(){return new Promise(async(e,t)=>{try{if(await"home://.gdv_cache".asFileHandle().remove(),a={"gdv://":{id:"root",mime:"dir"}},!Ant.OS.API.libready(Ant.OS.setting.VFS.gdrive.apilink))return e(!0);const t=gapi.auth2.getAuthInstance();if(!t)throw new Error(__("Unable to get OATH instance").__());t.isSignedIn.get()&&$("