cloudcmd 19.1.0 → 19.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sw.js CHANGED
@@ -1,2 +1,2 @@
1
- (()=>{var t={980(t,e,n){"use strict";n.r(e),n.d(e,{default:()=>o,tryToCatch:()=>r});const r=async(t,...e)=>{!function(t){if("function"!=typeof t)throw Error("fn should be a function!")}(t);try{return[null,await t(...e)]}catch(t){return[t]}},o=r},4299(t){"use strict";const e=(t,...n)=>{if(function(t){if("function"!=typeof t)throw Error("fn should be function!")}(t),n.length>=t.length)return t(...n);const r=(...r)=>e(t,...n,...r),o=t.length-n.length-1,i=(t=>[function(e){return t(...arguments)},function(e,n){return t(...arguments)},function(e,n,r){return t(...arguments)},function(e,n,r,o){return t(...arguments)},function(e,n,r,o,i){return t(...arguments)}])(r)[o];return i||r};t.exports=e},5606(t){var e,n,r=t.exports={};function o(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function c(t){if(e===setTimeout)return setTimeout(t,0);if((e===o||!e)&&setTimeout)return e=setTimeout,setTimeout(t,0);try{return e(t,0)}catch(n){try{return e.call(null,t,0)}catch(n){return e.call(this,t,0)}}}!function(){try{e="function"==typeof setTimeout?setTimeout:o}catch(t){e=o}try{n="function"==typeof clearTimeout?clearTimeout:i}catch(t){n=i}}();var s,u=[],a=!1,l=-1;function f(){a&&s&&(a=!1,s.length?u=s.concat(u):l=-1,u.length&&h())}function h(){if(!a){var t=c(f);a=!0;for(var e=u.length;e;){for(s=u,u=[];++l<e;)s&&s[l].run();l=-1,e=u.length}s=null,a=!1,function(t){if(n===clearTimeout)return clearTimeout(t);if((n===i||!n)&&clearTimeout)return n=clearTimeout,clearTimeout(t);try{return n(t)}catch(e){try{return n.call(null,t)}catch(e){return n.call(this,t)}}}(t)}}function d(t,e){this.fun=t,this.array=e}function p(){}r.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];u.push(new d(t,e)),1!==u.length||a||c(h)},d.prototype.run=function(){this.fun.apply(null,this.array)},r.title="browser",r.browser=!0,r.env={},r.argv=[],r.version="",r.versions={},r.on=p,r.addListener=p,r.once=p,r.off=p,r.removeListener=p,r.removeAllListeners=p,r.emit=p,r.prependListener=p,r.prependOnceListener=p,r.listeners=function(t){return[]},r.binding=function(t){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(t){throw new Error("process.chdir is not supported")},r.umask=function(){return 0}},8011(t,e,n){"use strict";const{tryToCatch:r}=n(980);t.exports=r,t.exports.tryToCatch=r}},e={};function n(r){var o=e[r];if(void 0!==o)return o.exports;var i=e[r]={exports:{}};return t[r](i,i.exports,n),i.exports}n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},(()=>{"use strict";const t=n(5606),{tryToCatch:e}=n(8011),r=n(4299),o="development"===t.env.NODE_ENV,i=r((t,e)=>e.waitUntil(t())),c=r((t,e)=>{const{request:n}=e,{url:r}=n,o=s(r);r.endsWith("/")||/\^\/fs/.test(o)||"GET"===n.method&&"basic"===n.type&&(o.startsWith("/api")||/^socket.io/.test(o)||e.respondWith(t(e)))}),s=t=>new URL(t).pathname,u="cloudcmd: Wed Dec 31 2025 14:14:19 GMT+0200 (Eastern European Standard Time)";self.addEventListener("install",i(async function(){console.info(`cloudcmd: sw: install: ${u}`),await self.skipWaiting()})),self.addEventListener("fetch",c(async function(t){const{request:n}=t,{url:r}=n,i=((t,e)=>"/"!==t?e:new Request("/",{credentials:"same-origin"}))(s(r),t.request),c=await caches.open(u),a=await c.match(n);if(!o&&a)return a;const[l,f]=await e(fetch,i,{credentials:"same-origin"});return l?new Response(l.message):(await async function(t,e){return(await caches.open(u)).put(t,e)}(n,f.clone()),f)})),self.addEventListener("activate",i(async function(){console.info(`cloudcmd: sw: activate: ${u}`),await self.clients.claim();const t=await caches.keys(),e=caches.delete.bind(caches);await Promise.all(t.map(e))}))})()})();
1
+ (()=>{var t={980(t,e,n){"use strict";n.r(e),n.d(e,{default:()=>o,tryToCatch:()=>r});const r=async(t,...e)=>{!function(t){if("function"!=typeof t)throw Error("fn should be a function!")}(t);try{return[null,await t(...e)]}catch(t){return[t]}},o=r},4299(t){"use strict";const e=(t,...n)=>{if(function(t){if("function"!=typeof t)throw Error("fn should be function!")}(t),n.length>=t.length)return t(...n);const r=(...r)=>e(t,...n,...r),o=t.length-n.length-1,i=(t=>[function(e){return t(...arguments)},function(e,n){return t(...arguments)},function(e,n,r){return t(...arguments)},function(e,n,r,o){return t(...arguments)},function(e,n,r,o,i){return t(...arguments)}])(r)[o];return i||r};t.exports=e},5606(t){var e,n,r=t.exports={};function o(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function c(t){if(e===setTimeout)return setTimeout(t,0);if((e===o||!e)&&setTimeout)return e=setTimeout,setTimeout(t,0);try{return e(t,0)}catch(n){try{return e.call(null,t,0)}catch(n){return e.call(this,t,0)}}}!function(){try{e="function"==typeof setTimeout?setTimeout:o}catch(t){e=o}try{n="function"==typeof clearTimeout?clearTimeout:i}catch(t){n=i}}();var s,a=[],u=!1,l=-1;function f(){u&&s&&(u=!1,s.length?a=s.concat(a):l=-1,a.length&&h())}function h(){if(!u){var t=c(f);u=!0;for(var e=a.length;e;){for(s=a,a=[];++l<e;)s&&s[l].run();l=-1,e=a.length}s=null,u=!1,function(t){if(n===clearTimeout)return clearTimeout(t);if((n===i||!n)&&clearTimeout)return n=clearTimeout,clearTimeout(t);try{return n(t)}catch(e){try{return n.call(null,t)}catch(e){return n.call(this,t)}}}(t)}}function d(t,e){this.fun=t,this.array=e}function p(){}r.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];a.push(new d(t,e)),1!==a.length||u||c(h)},d.prototype.run=function(){this.fun.apply(null,this.array)},r.title="browser",r.browser=!0,r.env={},r.argv=[],r.version="",r.versions={},r.on=p,r.addListener=p,r.once=p,r.off=p,r.removeListener=p,r.removeAllListeners=p,r.emit=p,r.prependListener=p,r.prependOnceListener=p,r.listeners=function(t){return[]},r.binding=function(t){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(t){throw new Error("process.chdir is not supported")},r.umask=function(){return 0}},8011(t,e,n){"use strict";const{tryToCatch:r}=n(980);t.exports=r,t.exports.tryToCatch=r}},e={};function n(r){var o=e[r];if(void 0!==o)return o.exports;var i=e[r]={exports:{}};return t[r](i,i.exports,n),i.exports}n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},(()=>{"use strict";const t=n(5606),{tryToCatch:e}=n(8011),r=n(4299),o="development"===t.env.NODE_ENV,i=r((t,e)=>e.waitUntil(t())),c=r((t,e)=>{const{request:n}=e,{url:r}=n,o=s(r);r.endsWith("/")||/\^\/fs/.test(o)||"GET"===n.method&&"basic"===n.type&&(o.startsWith("/api")||/^socket.io/.test(o)||e.respondWith(t(e)))}),s=t=>new URL(t).pathname,a="cloudcmd: Mon Jan 12 2026 13:33:12 GMT+0200 (Eastern European Standard Time)";self.addEventListener("install",i(async function(){console.info(`cloudcmd: sw: install: ${a}`),await self.skipWaiting()})),self.addEventListener("fetch",c(async function(t){const{request:n}=t,{url:r}=n,i=((t,e)=>"/"!==t?e:new Request("/",{credentials:"same-origin"}))(s(r),t.request),c=await caches.open(a),u=await c.match(n);if(!o&&u)return u;const[l,f]=await e(fetch,i,{credentials:"same-origin"});return l?new Response(l.message):(await async function(t,e){return(await caches.open(a)).put(t,e)}(n,f.clone()),f)})),self.addEventListener("activate",i(async function(){console.info(`cloudcmd: sw: activate: ${a}`),await self.clients.claim();const t=await caches.keys(),e=caches.delete.bind(caches);await Promise.all(t.map(e))}))})()})();
2
2
  //# sourceMappingURL=sw.js.map
@@ -136,7 +136,7 @@ eval("{/* global DOM */\n\n\n\nconst createElement = __webpack_require__(/*! @cl
136
136
  (module, __unused_webpack_exports, __webpack_require__) {
137
137
 
138
138
  "use strict";
139
- eval("{\n\n/* global CloudCmd */\nconst Util = __webpack_require__(/*! ../../common/util */ \"./common/util.js\");\nconst Images = __webpack_require__(/*! ./images */ \"./client/dom/images.js\");\nconst RESTful = __webpack_require__(/*! ./rest */ \"./client/dom/rest.js\");\nconst Storage = __webpack_require__(/*! ./storage */ \"./client/dom/storage.js\");\nconst renameCurrent = __webpack_require__(/*! ./operations/rename-current */ \"./client/dom/operations/rename-current.js\");\nconst CurrentFile = __webpack_require__(/*! ./current-file */ \"./client/dom/current-file.js\");\nconst DOMTree = __webpack_require__(/*! ./dom-tree */ \"./client/dom/dom-tree.js\");\nconst Cmd = module.exports;\nconst DOM = {\n ...DOMTree,\n ...CurrentFile,\n ...Cmd\n};\nconst CurrentInfo = {};\nDOM.Images = Images;\nDOM.load = __webpack_require__(/*! ./load */ \"./client/dom/load.js\");\nDOM.Files = __webpack_require__(/*! ./files */ \"./client/dom/files.js\");\nDOM.RESTful = RESTful;\nDOM.IO = __webpack_require__(/*! ./io */ \"./client/dom/io/index.js\");\nDOM.Storage = Storage;\nDOM.Dialog = __webpack_require__(/*! ./dialog */ \"./client/dom/dialog.js\");\nDOM.CurrentInfo = CurrentInfo;\nmodule.exports = DOM;\nDOM.uploadDirectory = __webpack_require__(/*! ./directory */ \"./client/dom/directory.js\");\nDOM.Buffer = __webpack_require__(/*! ./buffer */ \"./client/dom/buffer.js\");\nDOM.Events = __webpack_require__(/*! ./events */ \"./client/dom/events/index.js\");\nconst loadRemote = __webpack_require__(/*! ./load-remote */ \"./client/dom/load-remote.js\");\nconst selectByPattern = __webpack_require__(/*! ./select-by-pattern */ \"./client/dom/select-by-pattern.js\");\nconst isString = a => typeof a === 'string';\nconst SELECTED_FILE = 'selected-file';\nconst TabPanel = {\n 'js-left': null,\n 'js-right': null\n};\nmodule.exports.loadRemote = (name, options, callback) => {\n loadRemote(name, options, callback);\n return DOM;\n};\nmodule.exports.loadSocket = callback => {\n DOM.loadRemote('socket', {\n name: 'io'\n }, callback);\n return DOM;\n};\n\n/**\n * create new folder\n *\n */\nmodule.exports.promptNewDir = async function () {\n await promptNew('directory');\n};\n\n/**\n * create new file\n *\n * @typeName\n * @type\n */\nmodule.exports.promptNewFile = async () => {\n await promptNew('file');\n};\nasync function promptNew(typeName) {\n const {\n Dialog\n } = DOM;\n const dir = DOM.getCurrentDirPath();\n const msg = `New ${typeName}` || 'File';\n const getName = () => {\n const name = DOM.getCurrentName();\n if (name === '..') return '';\n return name;\n };\n const name = getName();\n const [cancel, currentName] = await Dialog.prompt(msg, name);\n if (cancel) return;\n const path = `${dir}${currentName}`;\n if (typeName === 'directory') await RESTful.createDirectory(path);else await RESTful.write(path);\n await CloudCmd.refresh({\n currentName\n });\n}\n\n/**\n * get current direcotory name\n */\nmodule.exports.getCurrentDirName = () => {\n const href = DOM.getCurrentDirPath().replace(/\\/$/, '');\n const substr = href.substr(href, href.lastIndexOf('/'));\n return href.replace(`${substr}/`, '') || '/';\n};\n\n/**\n * get current direcotory path\n */\nmodule.exports.getParentDirPath = panel => {\n const path = DOM.getCurrentDirPath(panel);\n const dirName = DOM.getCurrentDirName() + '/';\n const index = path.lastIndexOf(dirName);\n if (path !== '/') return path.slice(0, index);\n return path;\n};\n\n/**\n * get not current direcotory path\n */\nmodule.exports.getNotCurrentDirPath = () => {\n const panel = DOM.getPanel({\n active: false\n });\n return DOM.getCurrentDirPath(panel);\n};\n\n/**\n * unified way to get selected files\n *\n * @currentFile\n */\nmodule.exports.getSelectedFiles = () => {\n const panel = DOM.getPanel();\n const selected = DOM.getByClassAll(SELECTED_FILE, panel);\n return Array.from(selected);\n};\n\n/*\n * unselect all files\n */\nmodule.exports.unselectFiles = files => {\n files = files || DOM.getSelectedFiles();\n Array.from(files).forEach(DOM.toggleSelectedFile);\n};\n\n/**\n * get all selected files or current when none selected\n *\n * @currentFile\n */\nmodule.exports.getActiveFiles = () => {\n const current = DOM.getCurrentFile();\n const files = DOM.getSelectedFiles();\n const name = DOM.getCurrentName(current);\n if (!files.length && name !== '..') return [current];\n return files;\n};\nmodule.exports.getCurrentDate = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n return DOM.getByDataName('js-date', current).textContent;\n};\n\n/**\n * get size\n * @currentFile\n */\nmodule.exports.getCurrentSize = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n\n /* если это папка - возвращаем слово dir вместо размера*/\n const size = DOM.getByDataName('js-size', current).textContent.replace(/^<|>$/g, '');\n return size;\n};\n\n/**\n * get size\n * @currentFile\n */\nmodule.exports.loadCurrentSize = async currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const query = '?size';\n const link = DOM.getCurrentPath(current);\n Images.show.load();\n if (name === '..') return;\n const [, size] = await RESTful.read(link + query);\n DOM.setCurrentSize(size, current);\n Images.hide();\n return current;\n};\n\n/**\n * load hash\n * @callback\n * @currentFile\n */\nmodule.exports.loadCurrentHash = async currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const query = '?hash';\n const link = DOM.getCurrentPath(current);\n const [, data] = await RESTful.read(link + query);\n return data;\n};\n\n/**\n * set size\n * @currentFile\n */\nmodule.exports.setCurrentSize = (size, currentFile) => {\n const current = currentFile || DOM.getCurrentFile();\n const sizeElement = DOM.getByDataName('js-size', current);\n sizeElement.textContent = size;\n};\n\n/**\n * @currentFile\n */\nmodule.exports.getCurrentMode = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const mode = DOM.getByDataName('js-mode', current);\n return mode.textContent;\n};\n\n/**\n * @currentFile\n */\nmodule.exports.getCurrentOwner = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const owner = DOM.getByDataName('js-owner', current);\n return owner.textContent;\n};\n\n/**\n * unified way to get current file content\n *\n * @param currentFile\n */\nmodule.exports.getCurrentData = async currentFile => {\n const {\n Dialog\n } = DOM;\n const Info = DOM.CurrentInfo;\n const current = currentFile || DOM.getCurrentFile();\n const path = DOM.getCurrentPath(current);\n const isDir = DOM.isCurrentIsDir(current);\n if (Info.name === '..') {\n Dialog.alert.noFiles();\n return [Error('No Files')];\n }\n if (isDir) return await RESTful.read(path);\n const [hashNew, hash] = await DOM.checkStorageHash(path);\n if (!hashNew) return [Error(`Can't get hash of a file`)];\n if (hash === hashNew) return [null, await Storage.get(`${path}-data`)];\n const [e, data] = await RESTful.read(path);\n if (e) return [e, null];\n const ONE_MEGABYTE = 1024 ** 2 * 1024;\n const {\n length\n } = data;\n if (hash && length < ONE_MEGABYTE) await DOM.saveDataToStorage(path, data, hashNew);\n return [null, data];\n};\n\n/**\n * unified way to get RefreshButton\n */\nmodule.exports.getRefreshButton = (panel = DOM.getPanel()) => {\n return DOM.getByDataName('js-refresh', panel);\n};\n\n/**\n * select current file\n * @param currentFile\n */\nmodule.exports.selectFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n current.classList.add(SELECTED_FILE);\n return Cmd;\n};\nmodule.exports.unselectFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n current.classList.remove(SELECTED_FILE);\n return Cmd;\n};\nmodule.exports.toggleSelectedFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const name = DOM.getCurrentName(current);\n if (name === '..') return Cmd;\n current.classList.toggle(SELECTED_FILE);\n return Cmd;\n};\nmodule.exports.toggleAllSelectedFiles = () => {\n DOM.getAllFiles().map(DOM.toggleSelectedFile);\n return Cmd;\n};\nmodule.exports.selectAllFiles = () => {\n DOM.getAllFiles().map(DOM.selectFile);\n return Cmd;\n};\nmodule.exports.getAllFiles = () => {\n const panel = DOM.getPanel();\n const files = DOM.getFiles(panel);\n const name = DOM.getCurrentName(files[0]);\n const from = a => a === '..' ? 1 : 0;\n const i = from(name);\n return Array.from(files).slice(i);\n};\n\n/**\n * open dialog with expand selection\n */\nmodule.exports.expandSelection = () => {\n const msg = 'expand';\n const {\n files\n } = CurrentInfo;\n selectByPattern(msg, files);\n};\n\n/**\n * open dialog with shrink selection\n */\nmodule.exports.shrinkSelection = () => {\n const msg = 'shrink';\n const {\n files\n } = CurrentInfo;\n selectByPattern(msg, files);\n};\n\n/**\n * setting history wrapper\n */\nmodule.exports.setHistory = (data, title, url) => {\n const ret = window.history;\n const {\n prefix\n } = CloudCmd;\n url = prefix + url;\n if (ret) history.pushState(data, title, url);\n return ret;\n};\n\n/**\n * selected file check\n *\n * @param currentFile\n */\nmodule.exports.isSelected = selected => {\n if (!selected) return false;\n return DOM.isContainClass(selected, SELECTED_FILE);\n};\n\n/**\n * get link from current (or param) file\n *\n * @param currentFile - current file by default\n */\nmodule.exports.getCurrentLink = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const link = DOM.getByTag('a', current);\n return link[0];\n};\nmodule.exports.getFilenames = files => {\n if (!files) throw Error('AllFiles could not be empty');\n const first = files[0] || DOM.getCurrentFile();\n const name = DOM.getCurrentName(first);\n const allFiles = Array.from(files);\n if (name === '..') allFiles.shift();\n const names = allFiles.map(current => {\n return DOM.getCurrentName(current);\n });\n return names;\n};\n\n/**\n * check storage hash\n */\nmodule.exports.checkStorageHash = async name => {\n const nameHash = `${name}-hash`;\n if (!isString(name)) throw Error('name should be a string!');\n const [loadHash, storeHash] = await Promise.all([DOM.loadCurrentHash(), Storage.get(nameHash)]);\n return [loadHash, storeHash];\n};\n\n/**\n * save data to storage\n *\n * @param name\n * @param data\n * @param hash\n * @param callback\n */\nmodule.exports.saveDataToStorage = async (name, data, hash) => {\n const isDir = DOM.isCurrentIsDir();\n if (isDir) return;\n hash = hash || (await DOM.loadCurrentHash());\n const nameHash = `${name}-hash`;\n const nameData = `${name}-data`;\n await Storage.set(nameHash, hash);\n await Storage.set(nameData, data);\n return hash;\n};\nmodule.exports.getFM = () => DOM.getPanel().parentElement;\nmodule.exports.getPanelPosition = panel => {\n panel = panel || DOM.getPanel();\n return panel.dataset.name.replace('js-', '');\n};\nmodule.exports.getCSSVar = (name, {\n body = document.body\n} = {}) => {\n const bodyStyle = getComputedStyle(body);\n return bodyStyle.getPropertyValue(`--${name}`);\n};\n\n/** function getting panel active, or passive\n * @param options = {active: true}\n */\nmodule.exports.getPanel = options => {\n let files;\n let panel;\n let isLeft;\n let dataName = 'js-';\n const current = DOM.getCurrentFile();\n if (!current) {\n panel = DOM.getByDataName('js-left');\n } else {\n files = current.parentElement;\n panel = files.parentElement;\n isLeft = panel.getAttribute('data-name') === 'js-left';\n }\n\n /* if {active : false} getting passive panel */\n if (options && !options.active) {\n dataName += isLeft ? 'right' : 'left';\n panel = DOM.getByDataName(dataName);\n }\n\n /* if two panels showed\n * then always work with passive\n * panel\n */\n if (window.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH) panel = DOM.getByDataName('js-left');\n if (!panel) throw Error('can not find Active Panel!');\n return panel;\n};\nmodule.exports.getFiles = element => {\n const files = DOM.getByDataName('js-files', element);\n return files.children || [];\n};\n\n/**\n * shows panel right or left (or active)\n */\nmodule.exports.showPanel = active => {\n const panel = DOM.getPanel({\n active\n });\n if (!panel) return false;\n DOM.show(panel);\n return true;\n};\n\n/**\n * hides panel right or left (or active)\n */\nmodule.exports.hidePanel = active => {\n const panel = DOM.getPanel({\n active\n });\n if (!panel) return false;\n return DOM.hide(panel);\n};\n\n/**\n * remove child of element\n * @param pChild\n * @param element\n */\nmodule.exports.remove = (child, element) => {\n const parent = element || document.body;\n parent.removeChild(child);\n return DOM;\n};\n\n/**\n * remove current file from file table\n * @param current\n *\n */\nmodule.exports.deleteCurrent = current => {\n if (!current) DOM.getCurrentFile();\n const parent = current === null || current === void 0 ? void 0 : current.parentElement;\n const name = DOM.getCurrentName(current);\n if (current && name !== '..') {\n const next = current.nextSibling;\n const prev = current.previousSibling;\n DOM.setCurrentFile(next || prev);\n parent.removeChild(current);\n }\n};\n\n/**\n * remove selected files from file table\n * @Selected\n */\nmodule.exports.deleteSelected = selected => {\n selected = selected || DOM.getSelectedFiles();\n if (!selected) return;\n selected.map(DOM.deleteCurrent);\n};\n\n/**\n * rename current file\n *\n * @currentFile\n */\nmodule.exports.renameCurrent = renameCurrent;\n/**\n * unified way to scrollIntoViewIfNeeded\n * (native suporte by webkit only)\n * @param element\n * @param center - to scroll as small as possible param should be false\n */\nmodule.exports.scrollIntoViewIfNeeded = (element, center = false) => {\n if (!element || !element.scrollIntoViewIfNeeded) return;\n element.scrollIntoViewIfNeeded(center);\n};\n\n/* scroll on one page */\nmodule.exports.scrollByPages = (element, pPages) => {\n const ret = (element === null || element === void 0 ? void 0 : element.scrollByPages) && pPages;\n if (ret) element.scrollByPages(pPages);\n return ret;\n};\nmodule.exports.changePanel = () => {\n const Info = CurrentInfo;\n let panel = DOM.getPanel();\n CloudCmd.emit('passive-dir', Info.dirPath);\n const panelPassive = DOM.getPanel({\n active: false\n });\n let name = DOM.getCurrentName();\n const filesPassive = DOM.getFiles(panelPassive);\n let dataName = panel.getAttribute('data-name');\n TabPanel[dataName] = name;\n panel = panelPassive;\n dataName = panel.getAttribute('data-name');\n name = TabPanel[dataName];\n let files;\n let current;\n if (name) {\n current = DOM.getCurrentByName(name, panel);\n if (current) files = current.parentElement;\n }\n if (!files || !files.parentElement) {\n current = DOM.getCurrentByName(name, panel);\n if (!current) [current] = filesPassive;\n }\n DOM.setCurrentFile(current, {\n history: true\n });\n CloudCmd.emit('active-dir', Info.dirPath);\n return DOM;\n};\nmodule.exports.getPackerExt = type => {\n if (type === 'zip') return '.zip';\n return '.tar.gz';\n};\nmodule.exports.goToDirectory = async () => {\n const msg = 'Go to directory:';\n const {\n Dialog\n } = DOM;\n const {\n dirPath\n } = CurrentInfo;\n const [cancel, path = dirPath] = await Dialog.prompt(msg, dirPath);\n if (cancel) return;\n await CloudCmd.changeDir(path);\n};\nmodule.exports.duplicatePanel = async () => {\n const Info = CurrentInfo;\n const {\n isDir\n } = Info;\n const panel = Info.panelPassive;\n const noCurrent = !Info.isOnePanel;\n const getPath = isDir => {\n if (isDir) return Info.path;\n return Info.dirPath;\n };\n const path = getPath(isDir);\n await CloudCmd.changeDir(path, {\n panel,\n noCurrent\n });\n};\nmodule.exports.swapPanels = async () => {\n const Info = CurrentInfo;\n const {\n panel,\n files,\n element,\n panelPassive\n } = Info;\n const path = DOM.getCurrentDirPath();\n const dirPathPassive = DOM.getNotCurrentDirPath();\n let currentIndex = files.indexOf(element);\n await CloudCmd.changeDir(path, {\n panel: panelPassive,\n noCurrent: true\n });\n await CloudCmd.changeDir(dirPathPassive, {\n panel\n });\n const length = Info.files.length - 1;\n if (currentIndex > length) currentIndex = length;\n const el = Info.files[currentIndex];\n DOM.setCurrentFile(el);\n};\nmodule.exports.CurrentInfo = CurrentInfo;\nmodule.exports.updateCurrentInfo = currentFile => {\n const info = DOM.CurrentInfo;\n const current = currentFile || DOM.getCurrentFile();\n const files = current.parentElement;\n const panelPassive = DOM.getPanel({\n active: false\n });\n const filesPassive = DOM.getFiles(panelPassive);\n const name = DOM.getCurrentName(current);\n info.dir = DOM.getCurrentDirName();\n info.dirPath = DOM.getCurrentDirPath();\n info.parentDirPath = DOM.getParentDirPath();\n info.element = current;\n info.ext = Util.getExt(name);\n info.files = Array.from(files.children);\n info.filesPassive = Array.from(filesPassive);\n info.first = files.firstChild;\n info.getData = DOM.getCurrentData;\n info.last = files.lastChild;\n info.link = DOM.getCurrentLink(current);\n info.mode = DOM.getCurrentMode(current);\n info.name = name;\n info.path = DOM.getCurrentPath(current);\n info.panel = files.parentElement || DOM.getPanel();\n info.panelPassive = panelPassive;\n info.size = DOM.getCurrentSize(current);\n info.isDir = DOM.isCurrentIsDir();\n info.isSelected = DOM.isSelected(current);\n info.panelPosition = DOM.getPanel().dataset.name.replace('js-', '');\n info.isOnePanel = info.panel.getAttribute('data-name') === info.panelPassive.getAttribute('data-name');\n};\n\n//# sourceURL=file://cloudcmd/client/dom/index.js\n}");
139
+ eval("{\n\n/* global CloudCmd */\nconst Util = __webpack_require__(/*! ../../common/util */ \"./common/util.js\");\nconst Images = __webpack_require__(/*! ./images */ \"./client/dom/images.js\");\nconst RESTful = __webpack_require__(/*! ./rest */ \"./client/dom/rest.js\");\nconst Storage = __webpack_require__(/*! ./storage */ \"./client/dom/storage.js\");\nconst renameCurrent = __webpack_require__(/*! ./operations/rename-current */ \"./client/dom/operations/rename-current.js\");\nconst CurrentFile = __webpack_require__(/*! ./current-file */ \"./client/dom/current-file.js\");\nconst DOMTree = __webpack_require__(/*! ./dom-tree */ \"./client/dom/dom-tree.js\");\nconst Cmd = module.exports;\nconst DOM = {\n ...DOMTree,\n ...CurrentFile,\n ...Cmd\n};\nconst CurrentInfo = {};\nDOM.Images = Images;\nDOM.load = __webpack_require__(/*! ./load */ \"./client/dom/load.js\");\nDOM.Files = __webpack_require__(/*! ./files */ \"./client/dom/files.js\");\nDOM.RESTful = RESTful;\nDOM.IO = __webpack_require__(/*! ./io */ \"./client/dom/io/index.js\");\nDOM.Storage = Storage;\nDOM.Dialog = __webpack_require__(/*! ./dialog */ \"./client/dom/dialog.js\");\nDOM.CurrentInfo = CurrentInfo;\nmodule.exports = DOM;\nDOM.uploadDirectory = __webpack_require__(/*! ./directory */ \"./client/dom/directory.js\");\nDOM.Buffer = __webpack_require__(/*! ./buffer */ \"./client/dom/buffer.js\");\nDOM.Events = __webpack_require__(/*! ./events */ \"./client/dom/events/index.js\");\nconst loadRemote = __webpack_require__(/*! ./load-remote */ \"./client/dom/load-remote.js\");\nconst selectByPattern = __webpack_require__(/*! ./select-by-pattern */ \"./client/dom/select-by-pattern.js\");\nconst isString = a => typeof a === 'string';\nconst SELECTED_FILE = 'selected-file';\nconst TabPanel = {\n 'js-left': null,\n 'js-right': null\n};\nmodule.exports.loadRemote = (name, options, callback) => {\n loadRemote(name, options, callback);\n return DOM;\n};\nmodule.exports.loadSocket = callback => {\n DOM.loadRemote('socket', {\n name: 'io'\n }, callback);\n return DOM;\n};\n\n/**\n * create new folder\n *\n */\nmodule.exports.promptNewDir = async function () {\n await promptNew('directory');\n};\n\n/**\n * create new file\n *\n * @typeName\n * @type\n */\nmodule.exports.promptNewFile = async () => {\n await promptNew('file');\n};\nasync function promptNew(typeName) {\n const {\n Dialog\n } = DOM;\n const dir = DOM.getCurrentDirPath();\n const msg = `New ${typeName}` || 'File';\n const getName = () => {\n const name = DOM.getCurrentName();\n if (name === '..') return '';\n return name;\n };\n const name = getName();\n const [cancel, currentName] = await Dialog.prompt(msg, name);\n if (cancel) return;\n const path = `${dir}${currentName}`;\n if (typeName === 'directory') await RESTful.createDirectory(path);else await RESTful.write(path);\n await CloudCmd.refresh({\n currentName\n });\n}\n\n/**\n * get current direcotory name\n */\nmodule.exports.getCurrentDirName = () => {\n const href = DOM.getCurrentDirPath().replace(/\\/$/, '');\n const substr = href.substr(href, href.lastIndexOf('/'));\n return href.replace(`${substr}/`, '') || '/';\n};\n\n/**\n * get current direcotory path\n */\nmodule.exports.getParentDirPath = panel => {\n const path = DOM.getCurrentDirPath(panel);\n const dirName = DOM.getCurrentDirName() + '/';\n const index = path.lastIndexOf(dirName);\n if (path !== '/') return path.slice(0, index);\n return path;\n};\n\n/**\n * get not current direcotory path\n */\nmodule.exports.getNotCurrentDirPath = () => {\n const panel = DOM.getPanel({\n active: false\n });\n return DOM.getCurrentDirPath(panel);\n};\n\n/**\n * unified way to get selected files\n *\n * @currentFile\n */\nmodule.exports.getSelectedFiles = () => {\n const panel = DOM.getPanel();\n const selected = DOM.getByClassAll(SELECTED_FILE, panel);\n return Array.from(selected);\n};\n\n/*\n * unselect all files\n */\nmodule.exports.unselectFiles = files => {\n files = files || DOM.getSelectedFiles();\n Array.from(files).forEach(DOM.toggleSelectedFile);\n};\n\n/**\n * get all selected files or current when none selected\n *\n * @currentFile\n */\nmodule.exports.getActiveFiles = () => {\n const current = DOM.getCurrentFile();\n const files = DOM.getSelectedFiles();\n const name = DOM.getCurrentName(current);\n if (!files.length && name !== '..') return [current];\n return files;\n};\nmodule.exports.getCurrentDate = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n return DOM.getByDataName('js-date', current).textContent;\n};\n\n/**\n * get size\n * @currentFile\n */\nmodule.exports.getCurrentSize = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n\n /* если это папка - возвращаем слово dir вместо размера*/\n const size = DOM.getByDataName('js-size', current).textContent.replace(/^<|>$/g, '');\n return size;\n};\n\n/**\n * get size\n * @currentFile\n */\nmodule.exports.loadCurrentSize = async currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const query = '?size';\n const link = DOM.getCurrentPath(current);\n Images.show.load();\n if (name === '..') return;\n const [, size] = await RESTful.read(link + query);\n DOM.setCurrentSize(size, current);\n Images.hide();\n return current;\n};\n\n/**\n * load hash\n * @callback\n * @currentFile\n */\nmodule.exports.loadCurrentHash = async currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const query = '?hash';\n const link = DOM.getCurrentPath(current);\n const [, data] = await RESTful.read(link + query);\n return data;\n};\n\n/**\n * set size\n * @currentFile\n */\nmodule.exports.setCurrentSize = (size, currentFile) => {\n const current = currentFile || DOM.getCurrentFile();\n const sizeElement = DOM.getByDataName('js-size', current);\n sizeElement.textContent = size;\n};\n\n/**\n * @currentFile\n */\nmodule.exports.getCurrentMode = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const mode = DOM.getByDataName('js-mode', current);\n return mode.textContent;\n};\n\n/**\n * @currentFile\n */\nmodule.exports.getCurrentOwner = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const owner = DOM.getByDataName('js-owner', current);\n return owner.textContent;\n};\n\n/**\n * unified way to get current file content\n *\n * @param currentFile\n */\nmodule.exports.getCurrentData = async currentFile => {\n const {\n Dialog\n } = DOM;\n const Info = DOM.CurrentInfo;\n const current = currentFile || DOM.getCurrentFile();\n const path = DOM.getCurrentPath(current);\n const isDir = DOM.isCurrentIsDir(current);\n if (Info.name === '..') {\n Dialog.alert.noFiles();\n return [Error('No Files')];\n }\n if (isDir) return await RESTful.read(path);\n const [hashNew, hash] = await DOM.checkStorageHash(path);\n if (!hashNew) return [Error(`Can't get hash of a file`)];\n if (hash === hashNew) return [null, await Storage.get(`${path}-data`)];\n const [e, data] = await RESTful.read(path);\n if (e) return [e, null];\n const ONE_MEGABYTE = 1024 ** 2 * 1024;\n const {\n length\n } = data;\n if (hash && length < ONE_MEGABYTE) await DOM.saveDataToStorage(path, data, hashNew);\n return [null, data];\n};\n\n/**\n * unified way to get RefreshButton\n */\nmodule.exports.getRefreshButton = (panel = DOM.getPanel()) => {\n return DOM.getByDataName('js-refresh', panel);\n};\n\n/**\n * select current file\n * @param currentFile\n */\nmodule.exports.selectFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n current.classList.add(SELECTED_FILE);\n return Cmd;\n};\nmodule.exports.unselectFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n current.classList.remove(SELECTED_FILE);\n return Cmd;\n};\nmodule.exports.toggleSelectedFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const name = DOM.getCurrentName(current);\n if (name === '..') return Cmd;\n current.classList.toggle(SELECTED_FILE);\n return Cmd;\n};\nmodule.exports.toggleAllSelectedFiles = () => {\n DOM.getAllFiles().map(DOM.toggleSelectedFile);\n return Cmd;\n};\nmodule.exports.selectAllFiles = () => {\n DOM.getAllFiles().map(DOM.selectFile);\n return Cmd;\n};\nmodule.exports.getAllFiles = () => {\n const panel = DOM.getPanel();\n const files = DOM.getFiles(panel);\n const name = DOM.getCurrentName(files[0]);\n const from = a => a === '..' ? 1 : 0;\n const i = from(name);\n return Array.from(files).slice(i);\n};\n\n/**\n * open dialog with expand selection\n */\nmodule.exports.expandSelection = () => {\n const msg = 'expand';\n const {\n files\n } = CurrentInfo;\n selectByPattern(msg, files);\n};\n\n/**\n * open dialog with shrink selection\n */\nmodule.exports.shrinkSelection = () => {\n const msg = 'shrink';\n const {\n files\n } = CurrentInfo;\n selectByPattern(msg, files);\n};\n\n/**\n * setting history wrapper\n */\nmodule.exports.setHistory = (data, title, url) => {\n const ret = window.history;\n const {\n prefix\n } = CloudCmd;\n url = prefix + url;\n if (ret) history.pushState(data, title, url);\n return ret;\n};\n\n/**\n * selected file check\n *\n * @param currentFile\n */\nmodule.exports.isSelected = selected => {\n if (!selected) return false;\n return DOM.isContainClass(selected, SELECTED_FILE);\n};\n\n/**\n * get link from current (or param) file\n *\n * @param currentFile - current file by default\n */\nmodule.exports.getCurrentLink = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const link = DOM.getByTag('a', current);\n return link[0];\n};\nmodule.exports.getFilenames = files => {\n if (!files) throw Error('AllFiles could not be empty');\n const first = files[0] || DOM.getCurrentFile();\n const name = DOM.getCurrentName(first);\n const allFiles = Array.from(files);\n if (name === '..') allFiles.shift();\n const names = allFiles.map(current => {\n return DOM.getCurrentName(current);\n });\n return names;\n};\n\n/**\n * check storage hash\n */\nmodule.exports.checkStorageHash = async name => {\n const nameHash = `${name}-hash`;\n if (!isString(name)) throw Error('name should be a string!');\n const [loadHash, storeHash] = await Promise.all([DOM.loadCurrentHash(), Storage.get(nameHash)]);\n return [loadHash, storeHash];\n};\n\n/**\n * save data to storage\n *\n * @param name\n * @param data\n * @param hash\n * @param callback\n */\nmodule.exports.saveDataToStorage = async (name, data, hash) => {\n const isDir = DOM.isCurrentIsDir();\n if (isDir) return;\n hash = hash || (await DOM.loadCurrentHash());\n const nameHash = `${name}-hash`;\n const nameData = `${name}-data`;\n await Storage.set(nameHash, hash);\n await Storage.set(nameData, data);\n return hash;\n};\nmodule.exports.getFM = () => DOM.getPanel().parentElement;\nmodule.exports.getPanelPosition = panel => {\n panel = panel || DOM.getPanel();\n return panel.dataset.name.replace('js-', '');\n};\nmodule.exports.getCSSVar = (name, {\n body = document.body\n} = {}) => {\n const bodyStyle = getComputedStyle(body);\n return bodyStyle.getPropertyValue(`--${name}`);\n};\n\n/** function getting panel active, or passive\n * @param options = {active: true}\n */\nmodule.exports.getPanel = options => {\n let files;\n let panel;\n let isLeft;\n let dataName = 'js-';\n const current = DOM.getCurrentFile();\n if (!current) {\n panel = DOM.getByDataName('js-left');\n } else {\n files = current.parentElement;\n panel = files.parentElement;\n isLeft = panel.getAttribute('data-name') === 'js-left';\n }\n\n /* if {active : false} getting passive panel */\n if (options && !options.active) {\n dataName += isLeft ? 'right' : 'left';\n panel = DOM.getByDataName(dataName);\n }\n\n /* if two panels showed\n * then always work with passive\n * panel\n */\n if (window.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH) panel = DOM.getByDataName('js-left');\n if (!panel) throw Error('can not find Active Panel!');\n return panel;\n};\nmodule.exports.getFiles = element => {\n const files = DOM.getByDataName('js-files', element);\n return files.children || [];\n};\n\n/**\n * shows panel right or left (or active)\n */\nmodule.exports.showPanel = active => {\n const panel = DOM.getPanel({\n active\n });\n if (!panel) return false;\n DOM.show(panel);\n return true;\n};\n\n/**\n * hides panel right or left (or active)\n */\nmodule.exports.hidePanel = active => {\n const panel = DOM.getPanel({\n active\n });\n if (!panel) return false;\n return DOM.hide(panel);\n};\n\n/**\n * remove child of element\n * @param pChild\n * @param element\n */\nmodule.exports.remove = (child, element) => {\n const parent = element || document.body;\n parent.removeChild(child);\n return DOM;\n};\n\n/**\n * remove current file from file table\n * @param current\n *\n */\nmodule.exports.deleteCurrent = current => {\n if (!current) DOM.getCurrentFile();\n const parent = current === null || current === void 0 ? void 0 : current.parentElement;\n const name = DOM.getCurrentName(current);\n if (current && name !== '..') {\n const next = current.nextSibling;\n const prev = current.previousSibling;\n DOM.setCurrentFile(next || prev);\n parent.removeChild(current);\n }\n};\n\n/**\n * remove selected files from file table\n * @Selected\n */\nmodule.exports.deleteSelected = selected => {\n selected = selected || DOM.getSelectedFiles();\n if (!selected) return;\n selected.map(DOM.deleteCurrent);\n};\n\n/**\n * rename current file\n *\n * @currentFile\n */\nmodule.exports.renameCurrent = renameCurrent;\n/**\n * unified way to scrollIntoViewIfNeeded\n * (native suporte by webkit only)\n * @param element\n * @param center - to scroll as small as possible param should be false\n */\nmodule.exports.scrollIntoViewIfNeeded = (element, center = false) => {\n if (!element || !element.scrollIntoViewIfNeeded) return;\n element.scrollIntoViewIfNeeded(center);\n};\n\n/* scroll on one page */\nmodule.exports.scrollByPages = (element, pPages) => {\n const ret = (element === null || element === void 0 ? void 0 : element.scrollByPages) && pPages;\n if (ret) element.scrollByPages(pPages);\n return ret;\n};\nmodule.exports.changePanel = () => {\n const Info = CurrentInfo;\n let panel = DOM.getPanel();\n CloudCmd.emit('passive-dir', Info.dirPath);\n const panelPassive = DOM.getPanel({\n active: false\n });\n let name = DOM.getCurrentName();\n const filesPassive = DOM.getFiles(panelPassive);\n let dataName = panel.getAttribute('data-name');\n TabPanel[dataName] = name;\n panel = panelPassive;\n dataName = panel.getAttribute('data-name');\n name = TabPanel[dataName];\n let files;\n let current;\n if (name) {\n current = DOM.getCurrentByName(name, panel);\n if (current) files = current.parentElement;\n }\n if (!files || !files.parentElement) {\n current = DOM.getCurrentByName(name, panel);\n if (!current) [current] = filesPassive;\n }\n DOM.setCurrentFile(current, {\n history: true\n });\n CloudCmd.emit('active-dir', Info.dirPath);\n return DOM;\n};\nmodule.exports.getPackerExt = type => {\n if (type === 'zip') return '.zip';\n return '.tar.gz';\n};\nmodule.exports.goToDirectory = async (overrides = {}) => {\n const {\n Dialog\n } = DOM;\n const {\n prompt = Dialog.prompt,\n changeDir = CloudCmd.changeDir\n } = overrides;\n const msg = 'Go to directory:';\n const {\n dirPath\n } = CurrentInfo;\n const [cancel, path = dirPath] = await prompt(msg, dirPath);\n if (cancel) return;\n await changeDir(path);\n};\nmodule.exports.duplicatePanel = async () => {\n const Info = CurrentInfo;\n const {\n isDir\n } = Info;\n const panel = Info.panelPassive;\n const noCurrent = !Info.isOnePanel;\n const getPath = isDir => {\n if (isDir) return Info.path;\n return Info.dirPath;\n };\n const path = getPath(isDir);\n await CloudCmd.changeDir(path, {\n panel,\n noCurrent\n });\n};\nmodule.exports.swapPanels = async () => {\n const Info = CurrentInfo;\n const {\n panel,\n files,\n element,\n panelPassive\n } = Info;\n const path = DOM.getCurrentDirPath();\n const dirPathPassive = DOM.getNotCurrentDirPath();\n let currentIndex = files.indexOf(element);\n await CloudCmd.changeDir(path, {\n panel: panelPassive,\n noCurrent: true\n });\n await CloudCmd.changeDir(dirPathPassive, {\n panel\n });\n const length = Info.files.length - 1;\n if (currentIndex > length) currentIndex = length;\n const el = Info.files[currentIndex];\n DOM.setCurrentFile(el);\n};\nmodule.exports.CurrentInfo = CurrentInfo;\nmodule.exports.updateCurrentInfo = currentFile => {\n const info = DOM.CurrentInfo;\n const current = currentFile || DOM.getCurrentFile();\n const files = current.parentElement;\n const panelPassive = DOM.getPanel({\n active: false\n });\n const filesPassive = DOM.getFiles(panelPassive);\n const name = DOM.getCurrentName(current);\n info.dir = DOM.getCurrentDirName();\n info.dirPath = DOM.getCurrentDirPath();\n info.parentDirPath = DOM.getParentDirPath();\n info.element = current;\n info.ext = Util.getExt(name);\n info.files = Array.from(files.children);\n info.filesPassive = Array.from(filesPassive);\n info.first = files.firstChild;\n info.getData = DOM.getCurrentData;\n info.last = files.lastChild;\n info.link = DOM.getCurrentLink(current);\n info.mode = DOM.getCurrentMode(current);\n info.name = name;\n info.path = DOM.getCurrentPath(current);\n info.panel = files.parentElement || DOM.getPanel();\n info.panelPassive = panelPassive;\n info.size = DOM.getCurrentSize(current);\n info.isDir = DOM.isCurrentIsDir();\n info.isSelected = DOM.isSelected(current);\n info.panelPosition = DOM.getPanel().dataset.name.replace('js-', '');\n info.isOnePanel = info.panel.getAttribute('data-name') === info.panelPassive.getAttribute('data-name');\n};\n\n//# sourceURL=file://cloudcmd/client/dom/index.js\n}");
140
140
 
141
141
  /***/ },
142
142
 
@@ -268,7 +268,7 @@ eval("{\n\nmodule.exports.createBinder = () => {\n let binded = false;\n retur
268
268
  (module, __unused_webpack_exports, __webpack_require__) {
269
269
 
270
270
  "use strict";
271
- eval("{\n\n/* global CloudCmd, DOM */\nconst clipboard = __webpack_require__(/*! @cloudcmd/clipboard */ \"./node_modules/@cloudcmd/clipboard/lib/clipboard.js\");\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst Buffer = __webpack_require__(/*! ../dom/buffer */ \"./client/dom/buffer.js\");\nconst Events = __webpack_require__(/*! ../dom/events */ \"./client/dom/events/index.js\");\nconst KEY = __webpack_require__(/*! ./key */ \"./client/key/key.js\");\nconst vim = __webpack_require__(/*! ./vim */ \"./client/key/vim/index.js\");\nconst setCurrentByChar = __webpack_require__(/*! ./set-current-by-char */ \"./client/key/set-current-by-char.js\");\nconst {\n createBinder\n} = __webpack_require__(/*! ./binder */ \"./client/key/binder.js\");\nconst Info = DOM.CurrentInfo;\nconst Chars = fullstore();\nconst toggleVim = keyCode => {\n const {\n _config,\n config\n } = CloudCmd;\n if (keyCode === KEY.ESC) _config('vim', !config('vim'));\n};\nconst isUndefined = a => typeof a === 'undefined';\nChars([]);\nconst {\n assign\n} = Object;\nconst binder = createBinder();\nmodule.exports = assign(binder, KEY);\nmodule.exports.bind = () => {\n Events.addKey(listener, true);\n binder.setBind();\n};\nmodule.exports._listener = listener;\nfunction getChar(event) {\n /*\n * event.keyIdentifier deprecated in chrome v51\n * but event.key is absent in chrome <= v51\n */\n const {\n key,\n shift,\n keyCode,\n keyIdentifier\n } = event;\n const char = key || fromCharCode(keyIdentifier);\n const symbol = getSymbol(shift, keyCode);\n return [symbol, char];\n}\nasync function listener(event) {\n const {\n keyCode\n } = event;\n\n // strange chrome bug calles listener twice\n // in second time event misses a lot fields\n if (isUndefined(event.altKey)) return;\n const alt = event.altKey;\n const ctrl = event.ctrlKey;\n const meta = event.metaKey;\n const isBetween = keyCode >= KEY.ZERO && keyCode <= KEY.Z;\n const isNumpad = /Numpad/.test(event.code);\n const [symbol, char] = getChar(event);\n if (!binder.isBind()) return;\n toggleVim(keyCode);\n const isVim = CloudCmd.config('vim');\n if (!isVim && !isNumpad && !alt && !ctrl && !meta && (isBetween || symbol)) return setCurrentByChar(char, Chars);\n Chars([]);\n await switchKey(event);\n if (keyCode >= KEY.F1 && keyCode <= KEY.F10) return;\n if (isVim) vim(char, event);\n}\nfunction getSymbol(shift, keyCode) {\n switch (keyCode) {\n case KEY.DOT:\n return '.';\n case KEY.HYPHEN:\n return shift ? '_' : '-';\n case KEY.EQUAL:\n return shift ? '+' : '=';\n }\n return '';\n}\nfunction fromCharCode(keyIdentifier) {\n const code = keyIdentifier.substring(2);\n const hex = parseInt(code, 16);\n return String.fromCharCode(hex);\n}\nasync function switchKey(event) {\n let i;\n let isSelected;\n let prev;\n let next;\n let current = Info.element;\n let dataName;\n const {\n name,\n panel,\n path,\n isDir\n } = Info;\n const {\n Operation,\n changeDir,\n config\n } = CloudCmd;\n const {\n keyCode\n } = event;\n const alt = event.altKey;\n const shift = event.shiftKey;\n const ctrl = event.ctrlKey;\n const meta = event.metaKey;\n const ctrlMeta = ctrl || meta;\n if (current) {\n prev = current.previousSibling;\n next = current.nextSibling;\n }\n switch (keyCode) {\n case KEY.TAB:\n DOM.changePanel();\n event.preventDefault();\n break;\n case KEY.INSERT:\n DOM.toggleSelectedFile(current).setCurrentFile(next);\n break;\n case KEY.INSERT_MAC:\n DOM.toggleSelectedFile(current).setCurrentFile(next);\n break;\n case KEY.DELETE:\n if (shift) Operation.show('delete:silent');else Operation.show('delete');\n break;\n case KEY.ASTERISK:\n DOM.toggleAllSelectedFiles(current);\n break;\n case KEY.PLUS:\n DOM.expandSelection();\n event.preventDefault();\n break;\n case KEY.MINUS:\n DOM.shrinkSelection();\n event.preventDefault();\n break;\n case KEY.F1:\n CloudCmd.Help.show();\n event.preventDefault();\n break;\n case KEY.F2:\n CloudCmd.UserMenu.show();\n break;\n case KEY.F3:\n event.preventDefault();\n if (Info.isDir) await changeDir(path);else if (shift) CloudCmd.View.show(null, {\n raw: true\n });else if (ctrlMeta) CloudCmd.sortPanel('name');else CloudCmd.View.show();\n break;\n case KEY.F4:\n if (config('vim')) CloudCmd.EditFileVim.show();else CloudCmd.EditFile.show();\n event.preventDefault();\n break;\n case KEY.F5:\n if (ctrlMeta) CloudCmd.sortPanel('date');else if (alt) Operation.show('pack');else Operation.show('copy');\n event.preventDefault();\n break;\n case KEY.F6:\n if (ctrlMeta) CloudCmd.sortPanel('size');else if (shift) DOM.renameCurrent(current);else Operation.show('move');\n event.preventDefault();\n break;\n case KEY.F7:\n if (shift) DOM.promptNewFile();else DOM.promptNewDir();\n event.preventDefault();\n break;\n case KEY.F8:\n Operation.show('delete');\n event.preventDefault();\n break;\n case KEY.F9:\n if (alt) Operation.show('extract');else CloudCmd.Menu.show();\n event.preventDefault();\n break;\n case KEY.F10:\n CloudCmd.Config.show();\n event.preventDefault();\n break;\n case KEY.TRA:\n event.preventDefault();\n if (shift) return CloudCmd.Terminal.show();\n CloudCmd.Konsole.show();\n break;\n case KEY.BRACKET_CLOSE:\n CloudCmd.Konsole.show();\n event.preventDefault();\n break;\n case KEY.SPACE:\n event.preventDefault();\n if (!isDir || name === '..') isSelected = true;else isSelected = DOM.isSelected(current);\n if (!isSelected) await DOM.loadCurrentSize(current);\n DOM.toggleSelectedFile(current);\n break;\n case KEY.U:\n if (ctrlMeta) {\n DOM.swapPanels();\n event.preventDefault();\n }\n break;\n\n /* navigation on file table: *\n * in case of pressing button 'up', *\n * select previous row */\n case KEY.UP:\n if (shift) DOM.toggleSelectedFile(current);\n DOM.setCurrentFile(prev);\n event.preventDefault();\n break;\n\n /* in case of pressing button 'down', *\n * select next row */\n case KEY.DOWN:\n if (shift) DOM.toggleSelectedFile(current);\n DOM.setCurrentFile(next);\n event.preventDefault();\n break;\n case KEY.LEFT:\n if (!alt) return;\n event.preventDefault();\n dataName = Info.panel.getAttribute('data-name');\n if (dataName === 'js-right') DOM.duplicatePanel();\n break;\n case KEY.RIGHT:\n if (!alt) return;\n event.preventDefault();\n dataName = Info.panel.getAttribute('data-name');\n if (dataName === 'js-left') DOM.duplicatePanel();\n break;\n\n /* in case of pressing button 'Home', *\n * go to top element */\n case KEY.HOME:\n DOM.setCurrentFile(Info.first);\n event.preventDefault();\n break;\n\n /* in case of pressing button 'End', select last element */\n case KEY.END:\n DOM.setCurrentFile(Info.last);\n event.preventDefault();\n break;\n\n /* если нажали клавишу page down проматываем экран */\n case KEY.PAGE_DOWN:\n DOM.scrollByPages(panel, 1);\n for (i = 0; i < 30; i++) {\n if (!current.nextSibling) break;\n current = current.nextSibling;\n }\n DOM.setCurrentFile(current);\n event.preventDefault();\n break;\n\n /* если нажали клавишу page up проматываем экран */\n case KEY.PAGE_UP:\n DOM.scrollByPages(panel, -1);\n for (i = 0; i < 30; i++) {\n if (!current.previousSibling) break;\n current = current.previousSibling;\n }\n DOM.setCurrentFile(current);\n event.preventDefault();\n break;\n case KEY.ENTER:\n if (Info.isDir) await changeDir(path);else CloudCmd.View.show();\n break;\n case KEY.BACKSPACE:\n CloudCmd.goToParentDir();\n event.preventDefault();\n break;\n case KEY.BACKSLASH:\n if (ctrlMeta) await changeDir('/');\n break;\n case KEY.A:\n if (ctrlMeta) {\n DOM.selectAllFiles();\n event.preventDefault();\n }\n break;\n case KEY.G:\n if (alt) {\n DOM.goToDirectory();\n event.preventDefault();\n }\n break;\n case KEY.M:\n if (ctrlMeta) {\n if (config('vim')) CloudCmd.EditNamesVim.show();else CloudCmd.EditNames.show();\n event.preventDefault();\n }\n break;\n case KEY.P:\n if (!ctrlMeta) return;\n event.preventDefault();\n clipboard.writeText(Info.dirPath).catch(CloudCmd.log);\n break;\n\n /**\n * обновляем страницу,\n * загружаем содержимое каталога\n * при этом данные берём всегда с\n * сервера, а не из кэша\n * (обновляем кэш)\n */\n case KEY.R:\n if (ctrlMeta) {\n CloudCmd.log('reloading page...\\n');\n CloudCmd.refresh();\n event.preventDefault();\n }\n break;\n case KEY.C:\n if (ctrlMeta) Buffer.copy();\n break;\n case KEY.X:\n if (ctrlMeta) Buffer.cut();\n break;\n case KEY.V:\n if (ctrlMeta) Buffer.paste();\n break;\n case KEY.Z:\n if (ctrlMeta) Buffer.clear();\n break;\n case KEY.COLON:\n CloudCmd.CommandLine.show();\n event.preventDefault();\n break;\n\n /* чистим хранилище */\n case KEY.D:\n if (ctrlMeta) {\n CloudCmd.log('clearing storage...');\n await DOM.Storage.clear();\n CloudCmd.log('storage cleared');\n event.preventDefault();\n }\n break;\n case KEY.DOT:\n if (meta && shift) {\n const showDotFiles = !CloudCmd.config('showDotFiles');\n CloudCmd._config('showDotFiles', showDotFiles);\n CloudCmd.refresh();\n await DOM.RESTful.Config.write({\n showDotFiles\n });\n }\n break;\n }\n}\n\n//# sourceURL=file://cloudcmd/client/key/index.js\n}");
271
+ eval("{\n\n/* global CloudCmd, DOM */\nconst clipboard = __webpack_require__(/*! @cloudcmd/clipboard */ \"./node_modules/@cloudcmd/clipboard/lib/clipboard.js\");\nconst {\n fullstore\n} = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.cjs\");\nconst Buffer = __webpack_require__(/*! ../dom/buffer */ \"./client/dom/buffer.js\");\nconst Events = __webpack_require__(/*! ../dom/events */ \"./client/dom/events/index.js\");\nconst KEY = __webpack_require__(/*! ./key */ \"./client/key/key.js\");\nconst vim = __webpack_require__(/*! ./vim */ \"./client/key/vim/index.js\");\nconst setCurrentByChar = __webpack_require__(/*! ./set-current-by-char */ \"./client/key/set-current-by-char.js\");\nconst {\n createBinder\n} = __webpack_require__(/*! ./binder */ \"./client/key/binder.js\");\nconst Info = DOM.CurrentInfo;\nconst Chars = fullstore();\nconst toggleVim = keyCode => {\n const {\n _config,\n config\n } = CloudCmd;\n if (keyCode === KEY.ESC) _config('vim', !config('vim'));\n};\nconst isUndefined = a => typeof a === 'undefined';\nChars([]);\nconst {\n assign\n} = Object;\nconst binder = createBinder();\nmodule.exports = assign(binder, KEY);\nmodule.exports.bind = () => {\n Events.addKey(listener, true);\n binder.setBind();\n};\nmodule.exports._listener = listener;\nfunction getChar(event) {\n /*\n * event.keyIdentifier deprecated in chrome v51\n * but event.key is absent in chrome <= v51\n */\n const {\n key,\n shift,\n keyCode,\n keyIdentifier\n } = event;\n const char = key || fromCharCode(keyIdentifier);\n const symbol = getSymbol(shift, keyCode);\n return [symbol, char];\n}\nasync function listener(event) {\n const {\n keyCode\n } = event;\n\n // strange chrome bug calles listener twice\n // in second time event misses a lot fields\n if (isUndefined(event.altKey)) return;\n const alt = event.altKey;\n const ctrl = event.ctrlKey;\n const meta = event.metaKey;\n const isBetween = keyCode >= KEY.ZERO && keyCode <= KEY.Z;\n const isNumpad = /Numpad/.test(event.code);\n const [symbol, char] = getChar(event);\n if (!binder.isBind()) return;\n toggleVim(keyCode);\n const isVim = CloudCmd.config('vim');\n if (!isVim && !isNumpad && !alt && !ctrl && !meta && (isBetween || symbol)) return setCurrentByChar(char, Chars);\n Chars([]);\n await switchKey(event);\n if (keyCode >= KEY.F1 && keyCode <= KEY.F10) return;\n if (isVim) vim(char, event);\n}\nfunction getSymbol(shift, keyCode) {\n switch (keyCode) {\n case KEY.DOT:\n return '.';\n case KEY.HYPHEN:\n return shift ? '_' : '-';\n case KEY.EQUAL:\n return shift ? '+' : '=';\n }\n return '';\n}\nfunction fromCharCode(keyIdentifier) {\n const code = keyIdentifier.substring(2);\n const hex = parseInt(code, 16);\n return String.fromCharCode(hex);\n}\nasync function switchKey(event) {\n let i;\n let isSelected;\n let prev;\n let next;\n let current = Info.element;\n let dataName;\n const {\n name,\n panel,\n path,\n isDir\n } = Info;\n const {\n Operation,\n changeDir,\n config\n } = CloudCmd;\n const {\n keyCode\n } = event;\n const alt = event.altKey;\n const shift = event.shiftKey;\n const ctrl = event.ctrlKey;\n const meta = event.metaKey;\n const ctrlMeta = ctrl || meta;\n if (current) {\n prev = current.previousSibling;\n next = current.nextSibling;\n }\n switch (keyCode) {\n case KEY.TAB:\n DOM.changePanel();\n event.preventDefault();\n break;\n case KEY.INSERT:\n DOM.toggleSelectedFile(current).setCurrentFile(next);\n break;\n case KEY.INSERT_MAC:\n DOM.toggleSelectedFile(current).setCurrentFile(next);\n break;\n case KEY.DELETE:\n if (shift) Operation.show('delete:silent');else Operation.show('delete');\n break;\n case KEY.ASTERISK:\n DOM.toggleAllSelectedFiles(current);\n break;\n case KEY.PLUS:\n DOM.expandSelection();\n event.preventDefault();\n break;\n case KEY.MINUS:\n DOM.shrinkSelection();\n event.preventDefault();\n break;\n case KEY.F1:\n CloudCmd.Help.show();\n event.preventDefault();\n break;\n case KEY.F2:\n CloudCmd.UserMenu.show();\n break;\n case KEY.F3:\n event.preventDefault();\n if (Info.isDir) await changeDir(path);else if (shift) CloudCmd.View.show(null, {\n raw: true\n });else if (ctrlMeta) CloudCmd.sortPanel('name');else CloudCmd.View.show();\n break;\n case KEY.F4:\n if (config('vim')) CloudCmd.EditFileVim.show();else CloudCmd.EditFile.show();\n event.preventDefault();\n break;\n case KEY.F5:\n if (ctrlMeta) CloudCmd.sortPanel('date');else if (alt) Operation.show('pack');else Operation.show('copy');\n event.preventDefault();\n break;\n case KEY.F6:\n if (ctrlMeta) CloudCmd.sortPanel('size');else if (shift) DOM.renameCurrent(current);else Operation.show('move');\n event.preventDefault();\n break;\n case KEY.F7:\n if (shift) DOM.promptNewFile();else DOM.promptNewDir();\n event.preventDefault();\n break;\n case KEY.F8:\n Operation.show('delete');\n event.preventDefault();\n break;\n case KEY.F9:\n if (alt) Operation.show('extract');else CloudCmd.Menu.show();\n event.preventDefault();\n break;\n case KEY.F10:\n CloudCmd.Config.show();\n event.preventDefault();\n break;\n case KEY.TRA:\n event.preventDefault();\n if (shift) return CloudCmd.Terminal.show();\n CloudCmd.Konsole.show();\n break;\n case KEY.BRACKET_CLOSE:\n CloudCmd.Konsole.show();\n event.preventDefault();\n break;\n case KEY.SPACE:\n event.preventDefault();\n if (!isDir || name === '..') isSelected = true;else isSelected = DOM.isSelected(current);\n if (!isSelected) await DOM.loadCurrentSize(current);\n DOM.toggleSelectedFile(current);\n break;\n case KEY.U:\n if (ctrlMeta) {\n DOM.swapPanels();\n event.preventDefault();\n }\n break;\n\n /* navigation on file table: *\n * in case of pressing button 'up', *\n * select previous row */\n case KEY.UP:\n if (shift) DOM.toggleSelectedFile(current);\n DOM.setCurrentFile(prev);\n event.preventDefault();\n break;\n\n /* in case of pressing button 'down', *\n * select next row */\n case KEY.DOWN:\n if (shift) DOM.toggleSelectedFile(current);\n DOM.setCurrentFile(next);\n event.preventDefault();\n break;\n case KEY.LEFT:\n if (!alt) return;\n event.preventDefault();\n dataName = Info.panel.getAttribute('data-name');\n if (dataName === 'js-right') DOM.duplicatePanel();\n break;\n case KEY.RIGHT:\n if (!alt) return;\n event.preventDefault();\n dataName = Info.panel.getAttribute('data-name');\n if (dataName === 'js-left') DOM.duplicatePanel();\n break;\n\n /* in case of pressing button 'Home', *\n * go to top element */\n case KEY.HOME:\n DOM.setCurrentFile(Info.first);\n event.preventDefault();\n break;\n\n /* in case of pressing button 'End', select last element */\n case KEY.END:\n DOM.setCurrentFile(Info.last);\n event.preventDefault();\n break;\n\n /* если нажали клавишу page down проматываем экран */\n case KEY.PAGE_DOWN:\n DOM.scrollByPages(panel, 1);\n for (i = 0; i < 30; i++) {\n if (!current.nextSibling) break;\n current = current.nextSibling;\n }\n DOM.setCurrentFile(current);\n event.preventDefault();\n break;\n\n /* если нажали клавишу page up проматываем экран */\n case KEY.PAGE_UP:\n DOM.scrollByPages(panel, -1);\n for (i = 0; i < 30; i++) {\n if (!current.previousSibling) break;\n current = current.previousSibling;\n }\n DOM.setCurrentFile(current);\n event.preventDefault();\n break;\n case KEY.ENTER:\n if (Info.isDir) await changeDir(path);else CloudCmd.View.show();\n break;\n case KEY.BACKSPACE:\n CloudCmd.goToParentDir();\n event.preventDefault();\n break;\n case KEY.BACKSLASH:\n if (ctrlMeta) await changeDir('/');\n break;\n case KEY.A:\n if (ctrlMeta) {\n DOM.selectAllFiles();\n event.preventDefault();\n }\n break;\n case KEY.G:\n if (alt) {\n DOM.goToDirectory();\n event.preventDefault();\n }\n break;\n case KEY.M:\n if (ctrlMeta) {\n if (config('vim')) CloudCmd.EditNamesVim.show();else CloudCmd.EditNames.show();\n event.preventDefault();\n }\n break;\n case KEY.P:\n if (!ctrlMeta) return;\n event.preventDefault();\n clipboard.writeText(Info.dirPath).catch(CloudCmd.log);\n break;\n\n /**\n * обновляем страницу,\n * загружаем содержимое каталога\n * при этом данные берём всегда с\n * сервера, а не из кэша\n * (обновляем кэш)\n */\n case KEY.R:\n if (ctrlMeta) {\n CloudCmd.log('reloading page...\\n');\n CloudCmd.refresh();\n event.preventDefault();\n }\n break;\n case KEY.C:\n if (ctrlMeta) Buffer.copy();\n break;\n case KEY.X:\n if (ctrlMeta) Buffer.cut();\n break;\n case KEY.V:\n if (ctrlMeta) Buffer.paste();\n break;\n case KEY.Z:\n if (ctrlMeta) Buffer.clear();\n break;\n case KEY.COLON:\n CloudCmd.CommandLine.show();\n event.preventDefault();\n break;\n\n /* чистим хранилище */\n case KEY.D:\n if (ctrlMeta) {\n CloudCmd.log('clearing storage...');\n await DOM.Storage.clear();\n CloudCmd.log('storage cleared');\n event.preventDefault();\n }\n break;\n case KEY.DOT:\n if (meta && shift) {\n const showDotFiles = !CloudCmd.config('showDotFiles');\n CloudCmd._config('showDotFiles', showDotFiles);\n CloudCmd.refresh();\n await DOM.RESTful.Config.write({\n showDotFiles\n });\n }\n break;\n }\n}\n\n//# sourceURL=file://cloudcmd/client/key/index.js\n}");
272
272
 
273
273
  /***/ },
274
274
 
@@ -301,7 +301,7 @@ eval("{/* global DOM */\n\n\n\nconst {\n escapeRegExp\n} = __webpack_require__(
301
301
  (module, __unused_webpack_exports, __webpack_require__) {
302
302
 
303
303
  "use strict";
304
- eval("{\n\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst limier = __webpack_require__(/*! limier */ \"./node_modules/limier/lib/limier.js\");\nconst searchStore = fullstore([]);\nconst searchIndex = fullstore(0);\nmodule.exports.find = (value, names) => {\n const result = limier(value, names);\n searchStore(result);\n searchIndex(0);\n return result;\n};\nmodule.exports.findNext = () => {\n const names = searchStore();\n const index = next(searchIndex(), names.length);\n searchIndex(index);\n return names[searchIndex()];\n};\nmodule.exports.findPrevious = () => {\n const names = searchStore();\n const index = previous(searchIndex(), names.length);\n searchIndex(index);\n return names[index];\n};\nmodule.exports._next = next;\nmodule.exports._previous = previous;\nfunction next(index, length) {\n if (index === length - 1) return 0;\n return ++index;\n}\nfunction previous(index, length) {\n if (!index) return length - 1;\n return --index;\n}\n\n//# sourceURL=file://cloudcmd/client/key/vim/find.js\n}");
304
+ eval("{\n\nconst {\n fullstore\n} = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.cjs\");\nconst limier = __webpack_require__(/*! limier */ \"./node_modules/limier/lib/limier.js\");\nconst searchStore = fullstore([]);\nconst searchIndex = fullstore(0);\nmodule.exports.find = (value, names) => {\n const result = limier(value, names);\n searchStore(result);\n searchIndex(0);\n return result;\n};\nmodule.exports.findNext = () => {\n const names = searchStore();\n const index = next(searchIndex(), names.length);\n searchIndex(index);\n return names[searchIndex()];\n};\nmodule.exports.findPrevious = () => {\n const names = searchStore();\n const index = previous(searchIndex(), names.length);\n searchIndex(index);\n return names[index];\n};\nmodule.exports._next = next;\nmodule.exports._previous = previous;\nfunction next(index, length) {\n if (index === length - 1) return 0;\n return ++index;\n}\nfunction previous(index, length) {\n if (!index) return length - 1;\n return --index;\n}\n\n//# sourceURL=file://cloudcmd/client/key/vim/find.js\n}");
305
305
 
306
306
  /***/ },
307
307
 
@@ -334,7 +334,7 @@ eval("{\n\n/* global DOM */\nmodule.exports.selectFileNotParent = selectFileNotP
334
334
  (module, __unused_webpack_exports, __webpack_require__) {
335
335
 
336
336
  "use strict";
337
- eval("{\n\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst store = fullstore('');\nconst visual = fullstore(false);\nconst stopVisual = () => {\n visual(false);\n};\nconst end = () => {\n store('');\n};\nconst rmFirst = a => {\n return a.split('').slice(1).join('');\n};\nconst noop = () => {};\nmodule.exports = (key, operations = {}) => {\n const prevStore = store();\n const isVisual = visual();\n const value = store(prevStore.concat(key));\n const {\n escape = noop,\n moveNext = noop,\n movePrevious = noop,\n remove = noop,\n copy = noop,\n paste = noop,\n select = noop,\n find = noop,\n findNext = noop,\n findPrevious = noop,\n makeFile = noop,\n makeDirectory = noop,\n terminal = noop,\n edit = noop\n } = operations;\n if (key === 'Enter') return end();\n if (key === 'Escape') {\n visual(false);\n escape();\n return end();\n }\n if (key === 'j' || key === 'w') {\n const {\n count,\n isDelete,\n isVisual\n } = handleDelete(prevStore);\n !isNaN(count) && moveNext({\n count,\n isVisual,\n isDelete\n });\n return end();\n }\n if (key === 'k' || key === 'b') {\n const {\n count,\n isDelete,\n isVisual\n } = handleDelete(prevStore);\n !isNaN(count) && movePrevious({\n count,\n isVisual,\n isDelete\n });\n return end();\n }\n if (value === 'gg' || key === '^') {\n const {\n isDelete,\n isVisual\n } = handleDelete(prevStore);\n movePrevious({\n count: Infinity,\n isVisual,\n isDelete\n });\n return end();\n }\n if (value === 'md') {\n makeDirectory();\n return end();\n }\n if (value === 'tt') {\n terminal();\n return end();\n }\n if (value === 'e') {\n edit();\n return end();\n }\n if (value === 'mf') {\n makeFile();\n return end();\n }\n if (key === 'd' && (visual() || prevStore === 'd')) {\n stopVisual();\n remove();\n return end();\n }\n if (key === 'G' || key === '$') {\n moveNext({\n count: Infinity,\n isVisual\n });\n return end();\n }\n if (key === 'y') {\n if (!visual()) return end();\n stopVisual();\n copy();\n return end();\n }\n if (/^p$/i.test(key)) {\n paste();\n return end();\n }\n if (/^v$/i.test(key)) {\n visual(!visual());\n select();\n return end();\n }\n if (key === '/') {\n find();\n return end();\n }\n if (key === 'n') {\n findNext();\n return end();\n }\n if (key === 'N') {\n findPrevious();\n return end();\n }\n if (key === ' ') return end();\n};\nfunction handleDelete(prevStore) {\n const isDelete = prevStore[0] === 'd';\n if (isDelete) {\n visual(true);\n prevStore = rmFirst(prevStore);\n }\n const count = getNumber(prevStore);\n const isVisual = visual();\n return {\n count,\n isDelete,\n isVisual\n };\n}\nfunction getNumber(value) {\n if (!value) return 1;\n if (value === 'g') return 1;\n return parseInt(value);\n}\n\n//# sourceURL=file://cloudcmd/client/key/vim/vim.js\n}");
337
+ eval("{\n\nconst {\n fullstore\n} = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.cjs\");\nconst store = fullstore('');\nconst visual = fullstore(false);\nconst stopVisual = () => {\n visual(false);\n};\nconst end = () => {\n store('');\n};\nconst rmFirst = a => {\n return a.split('').slice(1).join('');\n};\nconst noop = () => {};\nmodule.exports = (key, operations = {}) => {\n const prevStore = store();\n const isVisual = visual();\n const value = store(prevStore.concat(key));\n const {\n escape = noop,\n moveNext = noop,\n movePrevious = noop,\n remove = noop,\n copy = noop,\n paste = noop,\n select = noop,\n find = noop,\n findNext = noop,\n findPrevious = noop,\n makeFile = noop,\n makeDirectory = noop,\n terminal = noop,\n edit = noop\n } = operations;\n if (key === 'Enter') return end();\n if (key === 'Escape') {\n visual(false);\n escape();\n return end();\n }\n if (key === 'j' || key === 'w') {\n const {\n count,\n isDelete,\n isVisual\n } = handleDelete(prevStore);\n !isNaN(count) && moveNext({\n count,\n isVisual,\n isDelete\n });\n return end();\n }\n if (key === 'k' || key === 'b') {\n const {\n count,\n isDelete,\n isVisual\n } = handleDelete(prevStore);\n !isNaN(count) && movePrevious({\n count,\n isVisual,\n isDelete\n });\n return end();\n }\n if (value === 'gg' || key === '^') {\n const {\n isDelete,\n isVisual\n } = handleDelete(prevStore);\n movePrevious({\n count: Infinity,\n isVisual,\n isDelete\n });\n return end();\n }\n if (value === 'md') {\n makeDirectory();\n return end();\n }\n if (value === 'tt') {\n terminal();\n return end();\n }\n if (value === 'e') {\n edit();\n return end();\n }\n if (value === 'mf') {\n makeFile();\n return end();\n }\n if (key === 'd' && (visual() || prevStore === 'd')) {\n stopVisual();\n remove();\n return end();\n }\n if (key === 'G' || key === '$') {\n moveNext({\n count: Infinity,\n isVisual\n });\n return end();\n }\n if (key === 'y') {\n if (!visual()) return end();\n stopVisual();\n copy();\n return end();\n }\n if (/^p$/i.test(key)) {\n paste();\n return end();\n }\n if (/^v$/i.test(key)) {\n visual(!visual());\n select();\n return end();\n }\n if (key === '/') {\n find();\n return end();\n }\n if (key === 'n') {\n findNext();\n return end();\n }\n if (key === 'N') {\n findPrevious();\n return end();\n }\n if (key === ' ') return end();\n};\nfunction handleDelete(prevStore) {\n const isDelete = prevStore[0] === 'd';\n if (isDelete) {\n visual(true);\n prevStore = rmFirst(prevStore);\n }\n const count = getNumber(prevStore);\n const isVisual = visual();\n return {\n count,\n isDelete,\n isVisual\n };\n}\nfunction getNumber(value) {\n if (!value) return 1;\n if (value === 'g') return 1;\n return parseInt(value);\n}\n\n//# sourceURL=file://cloudcmd/client/key/vim/vim.js\n}");
338
338
 
339
339
  /***/ },
340
340
 
@@ -455,7 +455,7 @@ eval("{\n\n/* global CloudCmd */\nCloudCmd.EditFileVim = exports;\nconst Events
455
455
  (module, exports, __webpack_require__) {
456
456
 
457
457
  "use strict";
458
- eval("{\n\n/* global CloudCmd, DOM*/\nCloudCmd.EditFile = exports;\nconst Format = __webpack_require__(/*! format-io */ \"./node_modules/format-io/lib/format.js\");\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\nconst supermenu = __webpack_require__(/*! supermenu */ \"./node_modules/supermenu/lib/supermenu.js\");\nconst Info = DOM.CurrentInfo;\nconst {\n Dialog,\n Images\n} = DOM;\nconst {\n config\n} = CloudCmd;\nlet Menu;\nlet MSG_CHANGED;\nconst isLoading = fullstore();\nconst ConfigView = {\n beforeClose: async () => {\n exec.ifExist(Menu, 'hide');\n await isChanged();\n }\n};\nmodule.exports.init = async () => {\n isLoading(true);\n await CloudCmd.Edit();\n const editor = CloudCmd.Edit.getEditor();\n authCheck(editor);\n setListeners(editor);\n isLoading(false);\n};\nfunction getName() {\n const {\n name,\n isDir\n } = Info;\n if (isDir) return `${name}.json`;\n return name;\n}\nmodule.exports.show = async options => {\n if (isLoading()) return;\n const optionsEdit = {\n ...ConfigView,\n ...options\n };\n if (CloudCmd.config('showFileName')) optionsEdit.title = Info.name;\n Images.show.load();\n CloudCmd.Edit.getEditor().setOption('keyMap', 'default');\n const [error, data] = await Info.getData();\n if (error) {\n Images.hide();\n return CloudCmd.Edit;\n }\n const {\n path\n } = Info;\n const name = getName();\n setMsgChanged(name);\n CloudCmd.Edit.getEditor().setValueFirst(path, data).setModeForPath(name).enableKey();\n CloudCmd.Edit.show(optionsEdit);\n return CloudCmd.Edit;\n};\nmodule.exports.hide = hide;\nfunction hide() {\n CloudCmd.Edit.hide();\n}\nfunction setListeners(editor) {\n const element = CloudCmd.Edit.getElement();\n DOM.Events.addOnce('contextmenu', element, setMenu);\n editor.on('save', value => {\n DOM.setCurrentSize(Format.size(value));\n });\n}\nfunction authCheck(spawn) {\n spawn.emit('auth', config('username'), config('password'));\n spawn.on('reject', () => {\n Dialog.alert('Wrong credentials!');\n });\n}\nfunction setMenu(event) {\n const position = {\n x: event.clientX,\n y: event.clientY\n };\n event.preventDefault();\n if (Menu) return;\n const options = {\n beforeShow: params => {\n params.x -= 18;\n params.y -= 27;\n },\n afterClick: () => {\n CloudCmd.Edit.getEditor().focus();\n }\n };\n const element = CloudCmd.Edit.getElement();\n Menu = supermenu(element, options, getMenuData());\n Menu.addContextMenuListener();\n Menu.show(position.x, position.y);\n}\nfunction getMenuData() {\n const editor = CloudCmd.Edit.getEditor();\n return {\n 'Save Ctrl+S': () => {\n editor.save();\n },\n 'Go To Line Ctrl+G': () => {\n editor.goToLine();\n },\n 'Cut Ctrl+X': () => {\n editor.cutToClipboard();\n },\n 'Copy Ctrl+C': () => {\n editor.copyToClipboard();\n },\n 'Paste Ctrl+V': () => {\n editor.pasteFromClipboard();\n },\n 'Delete Del': () => {\n editor.remove('right');\n },\n 'Select All Ctrl+A': () => {\n editor.selectAll();\n },\n 'Close Esc': hide\n };\n}\nfunction setMsgChanged(name) {\n MSG_CHANGED = `Do you want to save changes to ${name}?`;\n}\nmodule.exports.isChanged = isChanged;\nasync function isChanged() {\n const editor = CloudCmd.Edit.getEditor();\n const is = editor.isChanged();\n if (!is) return;\n const [cancel] = await Dialog.confirm(MSG_CHANGED);\n if (cancel) return;\n editor.save();\n}\n\n//# sourceURL=file://cloudcmd/client/modules/edit-file.js\n}");
458
+ eval("{\n\n/* global CloudCmd, DOM*/\nCloudCmd.EditFile = exports;\nconst Format = __webpack_require__(/*! format-io */ \"./node_modules/format-io/lib/format.js\");\nconst {\n fullstore\n} = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.cjs\");\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\nconst supermenu = __webpack_require__(/*! supermenu */ \"./node_modules/supermenu/lib/supermenu.js\");\nconst Info = DOM.CurrentInfo;\nconst {\n Dialog,\n Images\n} = DOM;\nconst {\n config\n} = CloudCmd;\nlet Menu;\nlet MSG_CHANGED;\nconst isLoading = fullstore();\nconst ConfigView = {\n beforeClose: async () => {\n exec.ifExist(Menu, 'hide');\n await isChanged();\n }\n};\nmodule.exports.init = async () => {\n isLoading(true);\n await CloudCmd.Edit();\n const editor = CloudCmd.Edit.getEditor();\n authCheck(editor);\n setListeners(editor);\n isLoading(false);\n};\nfunction getName() {\n const {\n name,\n isDir\n } = Info;\n if (isDir) return `${name}.json`;\n return name;\n}\nmodule.exports.show = async options => {\n if (isLoading()) return;\n const optionsEdit = {\n ...ConfigView,\n ...options\n };\n if (CloudCmd.config('showFileName')) optionsEdit.title = Info.name;\n Images.show.load();\n CloudCmd.Edit.getEditor().setOption('keyMap', 'default');\n const [error, data] = await Info.getData();\n if (error) {\n Images.hide();\n return CloudCmd.Edit;\n }\n const {\n path\n } = Info;\n const name = getName();\n setMsgChanged(name);\n CloudCmd.Edit.getEditor().setValueFirst(path, data).setModeForPath(name).enableKey();\n CloudCmd.Edit.show(optionsEdit);\n return CloudCmd.Edit;\n};\nmodule.exports.hide = hide;\nfunction hide() {\n CloudCmd.Edit.hide();\n}\nfunction setListeners(editor) {\n const element = CloudCmd.Edit.getElement();\n DOM.Events.addOnce('contextmenu', element, setMenu);\n editor.on('save', value => {\n DOM.setCurrentSize(Format.size(value));\n });\n}\nfunction authCheck(spawn) {\n spawn.emit('auth', config('username'), config('password'));\n spawn.on('reject', () => {\n Dialog.alert('Wrong credentials!');\n });\n}\nfunction setMenu(event) {\n const position = {\n x: event.clientX,\n y: event.clientY\n };\n event.preventDefault();\n if (Menu) return;\n const options = {\n beforeShow: params => {\n params.x -= 18;\n params.y -= 27;\n },\n afterClick: () => {\n CloudCmd.Edit.getEditor().focus();\n }\n };\n const element = CloudCmd.Edit.getElement();\n Menu = supermenu(element, options, getMenuData());\n Menu.addContextMenuListener();\n Menu.show(position.x, position.y);\n}\nfunction getMenuData() {\n const editor = CloudCmd.Edit.getEditor();\n return {\n 'Save Ctrl+S': () => {\n editor.save();\n },\n 'Go To Line Ctrl+G': () => {\n editor.goToLine();\n },\n 'Cut Ctrl+X': () => {\n editor.cutToClipboard();\n },\n 'Copy Ctrl+C': () => {\n editor.copyToClipboard();\n },\n 'Paste Ctrl+V': () => {\n editor.pasteFromClipboard();\n },\n 'Delete Del': () => {\n editor.remove('right');\n },\n 'Select All Ctrl+A': () => {\n editor.selectAll();\n },\n 'Close Esc': hide\n };\n}\nfunction setMsgChanged(name) {\n MSG_CHANGED = `Do you want to save changes to ${name}?`;\n}\nmodule.exports.isChanged = isChanged;\nasync function isChanged() {\n const editor = CloudCmd.Edit.getEditor();\n const is = editor.isChanged();\n if (!is) return;\n const [cancel] = await Dialog.confirm(MSG_CHANGED);\n if (cancel) return;\n editor.save();\n}\n\n//# sourceURL=file://cloudcmd/client/modules/edit-file.js\n}");
459
459
 
460
460
  /***/ },
461
461
 
@@ -620,7 +620,7 @@ eval("{\n\n/* global DOM */\n__webpack_require__(/*! domtokenlist-shim */ \"./no
620
620
  (module, exports, __webpack_require__) {
621
621
 
622
622
  "use strict";
623
- eval("{\n\n/* global CloudCmd, gritty */\nconst {\n promisify\n} = __webpack_require__(/*! es6-promisify */ \"./node_modules/es6-promisify/dist/promisify.js\");\nconst {\n tryToCatch\n} = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.cjs\");\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\n__webpack_require__(/*! ../../css/terminal.css */ \"./css/terminal.css\");\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\nconst DOM = __webpack_require__(/*! ../dom */ \"./client/dom/index.js\");\nconst Images = __webpack_require__(/*! ../dom/images */ \"./client/dom/images.js\");\nconst {\n Dialog\n} = DOM;\nconst {\n Key,\n config\n} = CloudCmd;\nCloudCmd.TerminalRun = exports;\nlet Loaded;\nlet Terminal;\nlet Socket;\nconst exitCodeStore = fullstore();\nconst loadAll = async () => {\n const {\n prefix\n } = CloudCmd;\n const prefixGritty = getPrefix();\n const js = `${prefixGritty}/gritty.js`;\n const css = `${prefix}/dist/terminal.css`;\n const [e] = await tryToCatch(load.parallel, [js, css]);\n if (e) {\n const src = e.target.src.replace(window.location.href, '');\n return Dialog.alert(`file ${src} could not be loaded`);\n }\n Loaded = true;\n};\nmodule.exports.init = async () => {\n if (!config('terminal')) return;\n Images.show.load('top');\n await CloudCmd.View();\n await loadAll();\n};\nmodule.exports.show = promisify((options = {}, fn) => {\n if (!Loaded) return fn(null, -1);\n if (!config('terminal')) return;\n create(options);\n CloudCmd.View.show(Terminal.element, {\n afterShow: () => {\n Terminal.focus();\n },\n afterClose: (/* exec.series args */\n ) => {\n fn(null, exitCodeStore());\n }\n });\n});\nmodule.exports.hide = hide;\nfunction hide() {\n CloudCmd.View.hide();\n}\nconst getPrefix = () => CloudCmd.prefix + '/gritty';\nfunction getPrefixSocket() {\n return CloudCmd.prefixSocket + '/gritty';\n}\nconst getEnv = () => ({\n ACTIVE_DIR: DOM.getCurrentDirPath,\n PASSIVE_DIR: DOM.getNotCurrentDirPath,\n CURRENT_NAME: DOM.getCurrentName,\n CURRENT_PATH: DOM.getCurrentPath\n});\nfunction create(createOptions) {\n const {\n cwd = DOM.getCurrentDirPath(),\n command,\n autoClose,\n closeMessage = 'Press any key to close Terminal...'\n } = createOptions;\n const options = {\n cwd,\n env: getEnv(),\n prefix: getPrefixSocket(),\n socketPath: CloudCmd.prefix,\n fontFamily: 'Droid Sans Mono',\n command,\n autoRestart: false\n };\n let commandExit = false;\n const {\n socket,\n terminal\n } = gritty(document.body, options);\n Socket = socket;\n Terminal = terminal;\n Terminal.onKey(({\n domEvent\n }) => {\n const {\n keyCode,\n shiftKey\n } = domEvent;\n if (commandExit) hide();\n if (shiftKey && keyCode === Key.ESC) hide();\n });\n Socket.on('exit', code => {\n exitCodeStore(code);\n if (autoClose) return hide();\n terminal.write(`\\n${closeMessage}`);\n commandExit = true;\n });\n Socket.on('connect', exec.with(authCheck, socket));\n}\nfunction authCheck(spawn) {\n spawn.emit('auth', config('username'), config('password'));\n spawn.on('reject', () => {\n Dialog.alert('Wrong credentials!');\n });\n}\n\n//# sourceURL=file://cloudcmd/client/modules/terminal-run.js\n}");
623
+ eval("{\n\n/* global CloudCmd, gritty */\nconst {\n promisify\n} = __webpack_require__(/*! es6-promisify */ \"./node_modules/es6-promisify/dist/promisify.js\");\nconst {\n tryToCatch\n} = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.cjs\");\nconst {\n fullstore\n} = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.cjs\");\n__webpack_require__(/*! ../../css/terminal.css */ \"./css/terminal.css\");\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\nconst DOM = __webpack_require__(/*! ../dom */ \"./client/dom/index.js\");\nconst Images = __webpack_require__(/*! ../dom/images */ \"./client/dom/images.js\");\nconst {\n Dialog\n} = DOM;\nconst {\n Key,\n config\n} = CloudCmd;\nCloudCmd.TerminalRun = exports;\nlet Loaded;\nlet Terminal;\nlet Socket;\nconst exitCodeStore = fullstore();\nconst loadAll = async () => {\n const {\n prefix\n } = CloudCmd;\n const prefixGritty = getPrefix();\n const js = `${prefixGritty}/gritty.js`;\n const css = `${prefix}/dist/terminal.css`;\n const [e] = await tryToCatch(load.parallel, [js, css]);\n if (e) {\n const src = e.target.src.replace(window.location.href, '');\n return Dialog.alert(`file ${src} could not be loaded`);\n }\n Loaded = true;\n};\nmodule.exports.init = async () => {\n if (!config('terminal')) return;\n Images.show.load('top');\n await CloudCmd.View();\n await loadAll();\n};\nmodule.exports.show = promisify((options = {}, fn) => {\n if (!Loaded) return fn(null, -1);\n if (!config('terminal')) return;\n create(options);\n CloudCmd.View.show(Terminal.element, {\n afterShow: () => {\n Terminal.focus();\n },\n afterClose: (/* exec.series args */\n ) => {\n fn(null, exitCodeStore());\n }\n });\n});\nmodule.exports.hide = hide;\nfunction hide() {\n CloudCmd.View.hide();\n}\nconst getPrefix = () => CloudCmd.prefix + '/gritty';\nfunction getPrefixSocket() {\n return CloudCmd.prefixSocket + '/gritty';\n}\nconst getEnv = () => ({\n ACTIVE_DIR: DOM.getCurrentDirPath,\n PASSIVE_DIR: DOM.getNotCurrentDirPath,\n CURRENT_NAME: DOM.getCurrentName,\n CURRENT_PATH: DOM.getCurrentPath\n});\nfunction create(createOptions) {\n const {\n cwd = DOM.getCurrentDirPath(),\n command,\n autoClose,\n closeMessage = 'Press any key to close Terminal...'\n } = createOptions;\n const options = {\n cwd,\n env: getEnv(),\n prefix: getPrefixSocket(),\n socketPath: CloudCmd.prefix,\n fontFamily: 'Droid Sans Mono',\n command,\n autoRestart: false\n };\n let commandExit = false;\n const {\n socket,\n terminal\n } = gritty(document.body, options);\n Socket = socket;\n Terminal = terminal;\n Terminal.onKey(({\n domEvent\n }) => {\n const {\n keyCode,\n shiftKey\n } = domEvent;\n if (commandExit) hide();\n if (shiftKey && keyCode === Key.ESC) hide();\n });\n Socket.on('exit', code => {\n exitCodeStore(code);\n if (autoClose) return hide();\n terminal.write(`\\n${closeMessage}`);\n commandExit = true;\n });\n Socket.on('connect', exec.with(authCheck, socket));\n}\nfunction authCheck(spawn) {\n spawn.emit('auth', config('username'), config('password'));\n spawn.on('reject', () => {\n Dialog.alert('Wrong credentials!');\n });\n}\n\n//# sourceURL=file://cloudcmd/client/modules/terminal-run.js\n}");
624
624
 
625
625
  /***/ },
626
626
 
@@ -664,7 +664,7 @@ eval("{\n\nmodule.exports = menuFn => {\n const module = {};\n const fn = Func
664
664
  (module, __unused_webpack_exports, __webpack_require__) {
665
665
 
666
666
  "use strict";
667
- eval("{\n\n/* global CloudCmd, DOM */\n__webpack_require__(/*! ../../../css/user-menu.css */ \"./css/user-menu.css\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\nconst {\n tryCatch\n} = __webpack_require__(/*! try-catch */ \"./node_modules/try-catch/lib/try-catch.cjs\");\nconst {\n tryToCatch\n} = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.cjs\");\nconst {\n codeFrameColumns\n} = __webpack_require__(/*! @babel/code-frame */ \"./node_modules/@babel/code-frame/lib/index.js\");\nconst Images = __webpack_require__(/*! ../../dom/images */ \"./client/dom/images.js\");\nconst Dialog = __webpack_require__(/*! ../../dom/dialog */ \"./client/dom/dialog.js\");\nconst getUserMenu = __webpack_require__(/*! ./get-user-menu */ \"./client/modules/user-menu/get-user-menu.js\");\nconst navigate = __webpack_require__(/*! ./navigate */ \"./client/modules/user-menu/navigate.js\");\nconst parseError = __webpack_require__(/*! ./parse-error */ \"./client/modules/user-menu/parse-error.js\");\nconst parseUserMenu = __webpack_require__(/*! ./parse-user-menu */ \"./client/modules/user-menu/parse-user-menu.js\");\nconst {\n runSelected\n} = __webpack_require__(/*! ./run */ \"./client/modules/user-menu/run.js\");\nconst loadCSS = load.css;\nconst sourceStore = fullstore();\nconst Name = 'UserMenu';\nCloudCmd[Name] = module.exports;\nconst {\n Key\n} = CloudCmd;\nmodule.exports.init = async () => {\n await Promise.all([loadCSS(`${CloudCmd.prefix}/dist/user-menu.css`), CloudCmd.View()]);\n};\nmodule.exports.show = show;\nmodule.exports.hide = hide;\nconst {\n CurrentInfo\n} = DOM;\nasync function show() {\n Images.show.load('top');\n const {\n dirPath\n } = CurrentInfo;\n const res = await fetch(`${CloudCmd.prefix}/api/v1/user-menu?dir=${dirPath}`);\n const source = await res.text();\n const [error, userMenu] = tryCatch(getUserMenu, source);\n Images.hide();\n if (error) return Dialog.alert(getCodeFrame({\n error,\n source\n }));\n sourceStore(source);\n const {\n names,\n keys,\n items,\n settings\n } = parseUserMenu(userMenu);\n if (settings.run) return runSelected(settings.select, items, runUserMenu);\n const button = createElement('button', {\n className: 'cloudcmd-user-menu-button',\n innerText: 'User Menu',\n notAppend: true\n });\n const select = createElement('select', {\n className: 'cloudcmd-user-menu',\n innerHTML: fillTemplate(names),\n notAppend: true,\n size: 10\n });\n button.addEventListener('click', onButtonClick(userMenu, select));\n select.addEventListener('dblclick', onDblClick(userMenu));\n select.addEventListener('keydown', onKeyDown({\n keys,\n userMenu\n }));\n const afterShow = () => select.focus();\n const autoSize = true;\n CloudCmd.View.show([button, select], {\n autoSize,\n afterShow\n });\n}\nfunction fillTemplate(options) {\n const result = [];\n for (const option of options) result.push(`<option>${option}</option>`);\n return result.join('');\n}\nfunction hide() {\n CloudCmd.View.hide();\n}\nconst onDblClick = currify(async (items, e) => {\n const {\n value\n } = e.target;\n await runUserMenu(items[value]);\n});\nconst onButtonClick = wraptile(async (items, {\n value\n}) => {\n await runUserMenu(items[value]);\n});\nconst onKeyDown = currify(async ({\n keys,\n userMenu\n}, e) => {\n const {\n keyCode,\n target\n } = e;\n const keyName = e.key.toUpperCase();\n e.preventDefault();\n e.stopPropagation();\n let value;\n if (keyCode === Key.ESC) return hide();\n if (keyCode === Key.ENTER) value = userMenu[target.value];else if (keys[keyName]) value = keys[keyName];else return navigate(target, e);\n await runUserMenu(value);\n});\nconst runUserMenu = async fn => {\n hide();\n const [error] = await tryToCatch(fn, {\n DOM,\n CloudCmd,\n tryToCatch\n });\n if (!error) return;\n const source = sourceStore();\n return Dialog.alert(getCodeFrame({\n error,\n source\n }));\n};\nfunction getCodeFrame({\n error,\n source\n}) {\n const {\n code\n } = error;\n if (!code || code === 'frame') return error.message;\n const [line, column] = parseError(error);\n const start = {\n line,\n column\n };\n const location = {\n start\n };\n const frame = codeFrameColumns(source, location, {\n message: error.message,\n highlightCode: false\n });\n return `<pre>${frame}</pre>`;\n}\n\n//# sourceURL=file://cloudcmd/client/modules/user-menu/index.js\n}");
667
+ eval("{\n\n/* global CloudCmd, DOM */\n__webpack_require__(/*! ../../../css/user-menu.css */ \"./css/user-menu.css\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\nconst {\n fullstore\n} = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.cjs\");\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\nconst {\n tryCatch\n} = __webpack_require__(/*! try-catch */ \"./node_modules/try-catch/lib/try-catch.cjs\");\nconst {\n tryToCatch\n} = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.cjs\");\nconst {\n codeFrameColumns\n} = __webpack_require__(/*! @babel/code-frame */ \"./node_modules/@babel/code-frame/lib/index.js\");\nconst Images = __webpack_require__(/*! ../../dom/images */ \"./client/dom/images.js\");\nconst Dialog = __webpack_require__(/*! ../../dom/dialog */ \"./client/dom/dialog.js\");\nconst getUserMenu = __webpack_require__(/*! ./get-user-menu */ \"./client/modules/user-menu/get-user-menu.js\");\nconst navigate = __webpack_require__(/*! ./navigate */ \"./client/modules/user-menu/navigate.js\");\nconst parseError = __webpack_require__(/*! ./parse-error */ \"./client/modules/user-menu/parse-error.js\");\nconst parseUserMenu = __webpack_require__(/*! ./parse-user-menu */ \"./client/modules/user-menu/parse-user-menu.js\");\nconst {\n runSelected\n} = __webpack_require__(/*! ./run */ \"./client/modules/user-menu/run.js\");\nconst loadCSS = load.css;\nconst sourceStore = fullstore();\nconst Name = 'UserMenu';\nCloudCmd[Name] = module.exports;\nconst {\n Key\n} = CloudCmd;\nmodule.exports.init = async () => {\n await Promise.all([loadCSS(`${CloudCmd.prefix}/dist/user-menu.css`), CloudCmd.View()]);\n};\nmodule.exports.show = show;\nmodule.exports.hide = hide;\nconst {\n CurrentInfo\n} = DOM;\nasync function show() {\n Images.show.load('top');\n const {\n dirPath\n } = CurrentInfo;\n const res = await fetch(`${CloudCmd.prefix}/api/v1/user-menu?dir=${dirPath}`);\n const source = await res.text();\n const [error, userMenu] = tryCatch(getUserMenu, source);\n Images.hide();\n if (error) return Dialog.alert(getCodeFrame({\n error,\n source\n }));\n sourceStore(source);\n const {\n names,\n keys,\n items,\n settings\n } = parseUserMenu(userMenu);\n if (settings.run) return runSelected(settings.select, items, runUserMenu);\n const button = createElement('button', {\n className: 'cloudcmd-user-menu-button',\n innerText: 'User Menu',\n notAppend: true\n });\n const select = createElement('select', {\n className: 'cloudcmd-user-menu',\n innerHTML: fillTemplate(names),\n notAppend: true,\n size: 10\n });\n button.addEventListener('click', onButtonClick(userMenu, select));\n select.addEventListener('dblclick', onDblClick(userMenu));\n select.addEventListener('keydown', onKeyDown({\n keys,\n userMenu\n }));\n const afterShow = () => select.focus();\n const autoSize = true;\n CloudCmd.View.show([button, select], {\n autoSize,\n afterShow\n });\n}\nfunction fillTemplate(options) {\n const result = [];\n for (const option of options) result.push(`<option>${option}</option>`);\n return result.join('');\n}\nfunction hide() {\n CloudCmd.View.hide();\n}\nconst onDblClick = currify(async (items, e) => {\n const {\n value\n } = e.target;\n await runUserMenu(items[value]);\n});\nconst onButtonClick = wraptile(async (items, {\n value\n}) => {\n await runUserMenu(items[value]);\n});\nconst onKeyDown = currify(async ({\n keys,\n userMenu\n}, e) => {\n const {\n keyCode,\n target\n } = e;\n const keyName = e.key.toUpperCase();\n e.preventDefault();\n e.stopPropagation();\n let value;\n if (keyCode === Key.ESC) return hide();\n if (keyCode === Key.ENTER) value = userMenu[target.value];else if (keys[keyName]) value = keys[keyName];else return navigate(target, e);\n await runUserMenu(value);\n});\nconst runUserMenu = async fn => {\n hide();\n const [error] = await tryToCatch(fn, {\n DOM,\n CloudCmd,\n tryToCatch\n });\n if (!error) return;\n const source = sourceStore();\n return Dialog.alert(getCodeFrame({\n error,\n source\n }));\n};\nfunction getCodeFrame({\n error,\n source\n}) {\n const {\n code\n } = error;\n if (!code || code === 'frame') return error.message;\n const [line, column] = parseError(error);\n const start = {\n line,\n column\n };\n const location = {\n start\n };\n const frame = codeFrameColumns(source, location, {\n message: error.message,\n highlightCode: false\n });\n return `<pre>${frame}</pre>`;\n}\n\n//# sourceURL=file://cloudcmd/client/modules/user-menu/index.js\n}");
668
668
 
669
669
  /***/ },
670
670
 
@@ -675,7 +675,7 @@ eval("{\n\n/* global CloudCmd, DOM */\n__webpack_require__(/*! ../../../css/user
675
675
  (module, __unused_webpack_exports, __webpack_require__) {
676
676
 
677
677
  "use strict";
678
- eval("{\n\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst {\n J,\n K,\n UP,\n DOWN\n} = __webpack_require__(/*! ../../key/key.js */ \"./client/key/key.js\");\nconst store = fullstore(1);\nconst isDigit = a => /^\\d+$/.test(a);\nmodule.exports = (el, {\n key,\n keyCode\n}) => {\n if (isDigit(key)) store(Number(key));\n if (keyCode === DOWN || keyCode === J) {\n const count = store();\n store(1);\n return down(el, count);\n }\n if (keyCode === UP || keyCode === K) {\n const count = store();\n store(1);\n return up(el, count);\n }\n};\nfunction down(el, count) {\n const {\n length\n } = el;\n if (el.selectedIndex === length - 1) el.selectedIndex = 0;else el.selectedIndex += count;\n if (el.selectedIndex < 0) el.selectedIndex = length - 1;\n}\nfunction up(el, count) {\n const {\n length\n } = el;\n if (!el.selectedIndex) el.selectedIndex = length - 1;else el.selectedIndex -= count;\n if (el.selectedIndex < 0) el.selectedIndex = 0;\n}\n\n//# sourceURL=file://cloudcmd/client/modules/user-menu/navigate.js\n}");
678
+ eval("{\n\nconst {\n fullstore\n} = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.cjs\");\nconst {\n J,\n K,\n UP,\n DOWN\n} = __webpack_require__(/*! ../../key/key.js */ \"./client/key/key.js\");\nconst store = fullstore(1);\nconst isDigit = a => /^\\d+$/.test(a);\nmodule.exports = (el, {\n key,\n keyCode\n}) => {\n if (isDigit(key)) store(Number(key));\n if (keyCode === DOWN || keyCode === J) {\n const count = store();\n store(1);\n return down(el, count);\n }\n if (keyCode === UP || keyCode === K) {\n const count = store();\n store(1);\n return up(el, count);\n }\n};\nfunction down(el, count) {\n const {\n length\n } = el;\n if (el.selectedIndex === length - 1) el.selectedIndex = 0;else el.selectedIndex += count;\n if (el.selectedIndex < 0) el.selectedIndex = length - 1;\n}\nfunction up(el, count) {\n const {\n length\n } = el;\n if (!el.selectedIndex) el.selectedIndex = length - 1;else el.selectedIndex -= count;\n if (el.selectedIndex < 0) el.selectedIndex = 0;\n}\n\n//# sourceURL=file://cloudcmd/client/modules/user-menu/navigate.js\n}");
679
679
 
680
680
  /***/ },
681
681
 
@@ -774,7 +774,7 @@ eval("{\n\nmodule.exports.btoa = str => {\n if (typeof btoa === 'function') ret
774
774
  (module, __unused_webpack_exports, __webpack_require__) {
775
775
 
776
776
  "use strict";
777
- eval("{\n\nconst rendy = __webpack_require__(/*! rendy */ \"./node_modules/rendy/lib/rendy.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst {\n encode\n} = __webpack_require__(/*! ./entity */ \"./common/entity.js\");\nconst {\n btoa\n} = __webpack_require__(/*! ./base64 */ \"./common/base64.js\");\nconst getHeaderField = currify(_getHeaderField);\n\n/* КОНСТАНТЫ (общие для клиента и сервера)*/\n/* название программы */\nconst NAME = 'Cloud Commander';\nconst FS = '/fs';\nconst Path = store();\nPath('/');\nconst filterOutDotFiles = ({\n showDotFiles\n}) => ({\n name\n}) => {\n if (showDotFiles) return true;\n return !name.startsWith('.');\n};\nmodule.exports.FS = FS;\nmodule.exports.apiURL = '/api/v1';\nmodule.exports.MAX_FILE_SIZE = 500 * 1024;\nmodule.exports.getHeaderField = getHeaderField;\nmodule.exports.getPathLink = getPathLink;\nmodule.exports.getDotDot = getDotDot;\nmodule.exports.formatMsg = (msg, name, status) => {\n status = status || 'ok';\n name = name || '';\n if (name) name = `(\"${name}\")`;\n return `${msg}: ${status}${name}`;\n};\n\n/**\n * Функция возвращает заголовок веб страницы\n * @path\n */\nmodule.exports.getTitle = options => {\n options = options || {};\n const {\n path = Path(),\n name\n } = options;\n const array = [name || NAME, path];\n return array.filter(Boolean).join(' - ');\n};\n\n/** Функция получает адреса каждого каталога в пути\n * возвращаеться массив каталогов\n * @param url - адрес каталога\n */\nfunction getPathLink(url, prefix, template) {\n if (!url) throw Error('url could not be empty!');\n if (!template) throw Error('template could not be empty!');\n const names = url.split('/').slice(1, -1);\n const allNames = ['/', ...names];\n const lines = [];\n const n = allNames.length;\n let path = '/';\n for (let i = 0; i < n; i++) {\n const name = allNames[i];\n const isLast = i === n - 1;\n if (i) path += `${name}/`;\n if (i && isLast) {\n lines.push(`${name}/`);\n continue;\n }\n const slash = i ? '/' : '';\n lines.push(rendy(template, {\n path,\n name,\n slash,\n prefix\n }));\n }\n return lines.join('');\n}\nconst getDataName = name => {\n const encoded = btoa(encodeURI(name));\n return `data-name=\"js-file-${encoded}\" `;\n};\n\n/**\n * Функция строит таблицу файлв из JSON-информации о файлах\n * @param params - информация о файлах\n *\n */\nmodule.exports.buildFromJSON = params => {\n const {\n prefix,\n template,\n sort = 'name',\n order = 'asc',\n showDotFiles\n } = params;\n const templateFile = template.file;\n const templateLink = template.link;\n const json = params.data;\n const path = encode(json.path);\n const {\n files\n } = json;\n\n /*\n * Строим путь каталога в котором мы находимся\n * со всеми подкаталогами\n */\n const htmlPath = getPathLink(path, prefix, template.pathLink);\n let fileTable = rendy(template.path, {\n link: prefix + FS + path,\n fullPath: path,\n path: htmlPath\n });\n const owner = 'owner';\n const mode = 'mode';\n const getFieldName = getHeaderField(sort, order);\n const name = getFieldName('name');\n const size = getFieldName('size');\n const date = getFieldName('date');\n const header = rendy(templateFile, {\n tag: 'div',\n attribute: 'data-name=\"js-fm-header\" ',\n className: 'fm-header',\n type: '',\n name,\n size,\n date,\n owner,\n mode\n });\n\n /* сохраняем путь */\n Path(path);\n fileTable += `${header}<ul data-name=\"js-files\" class=\"files\">`;\n\n /* Если мы не в корне */\n if (path !== '/') {\n const dotDot = getDotDot(path);\n const link = prefix + FS + dotDot;\n const linkResult = rendy(template.link, {\n link,\n title: '..',\n name: '..'\n });\n const dataName = getDataName('..');\n const attribute = `draggable=\"true\" ${dataName}`;\n\n /* Сохраняем путь к каталогу верхнего уровня*/\n fileTable += rendy(template.file, {\n tag: 'li',\n attribute,\n className: '',\n type: 'directory',\n name: linkResult,\n size: '&lt;dir&gt;',\n date: '--.--.----',\n owner: '.',\n mode: '--- --- ---'\n });\n }\n fileTable += files.filter(filterOutDotFiles({\n showDotFiles\n })).map(updateField).map(file => {\n const name = encode(file.name);\n const link = prefix + FS + path + name;\n const {\n type,\n mode,\n date,\n owner,\n size\n } = file;\n const linkResult = rendy(templateLink, {\n link,\n title: name,\n name,\n attribute: getAttribute(file.type)\n });\n const dataName = getDataName(file.name);\n const attribute = `draggable=\"true\" ${dataName}`;\n return rendy(templateFile, {\n tag: 'li',\n attribute,\n className: '',\n type,\n name: linkResult,\n size,\n date,\n owner,\n mode\n });\n }).join('');\n fileTable += '</ul>';\n return fileTable;\n};\nconst updateField = file => ({\n ...file,\n date: file.date || '--.--.----',\n owner: file.owner || 'root',\n size: getSize(file)\n});\nfunction getAttribute(type) {\n if (type === 'directory') return '';\n return 'target=\"_blank\" ';\n}\nmodule.exports._getSize = getSize;\nfunction getSize({\n size,\n type\n}) {\n if (type === 'directory') return '&lt;dir&gt;';\n if (/link/.test(type)) return '&lt;link&gt;';\n return size;\n}\nfunction _getHeaderField(sort, order, name) {\n const arrow = order === 'asc' ? '↑' : '↓';\n if (sort !== name) return name;\n if (sort === 'name' && order === 'asc') return name;\n return `${name}${arrow}`;\n}\nfunction getDotDot(path) {\n // убираем последний слеш и каталог в котором мы сейчас находимся\n const lastSlash = path.substr(path, path.lastIndexOf('/'));\n const dotDot = lastSlash.substr(lastSlash, lastSlash.lastIndexOf('/'));\n if (!dotDot) return '/';\n return dotDot;\n}\n\n//# sourceURL=file://cloudcmd/common/cloudfunc.js\n}");
777
+ eval("{\n\nconst rendy = __webpack_require__(/*! rendy */ \"./node_modules/rendy/lib/rendy.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.cjs\");\nconst {\n encode\n} = __webpack_require__(/*! ./entity */ \"./common/entity.js\");\nconst {\n btoa\n} = __webpack_require__(/*! ./base64 */ \"./common/base64.js\");\nconst getHeaderField = currify(_getHeaderField);\n\n/* КОНСТАНТЫ (общие для клиента и сервера)*/\n/* название программы */\nconst NAME = 'Cloud Commander';\nconst FS = '/fs';\nconst Path = store();\nPath('/');\nconst filterOutDotFiles = ({\n showDotFiles\n}) => ({\n name\n}) => {\n if (showDotFiles) return true;\n return !name.startsWith('.');\n};\nmodule.exports.FS = FS;\nmodule.exports.apiURL = '/api/v1';\nmodule.exports.MAX_FILE_SIZE = 500 * 1024;\nmodule.exports.getHeaderField = getHeaderField;\nmodule.exports.getPathLink = getPathLink;\nmodule.exports.getDotDot = getDotDot;\nmodule.exports.formatMsg = (msg, name, status) => {\n status = status || 'ok';\n name = name || '';\n if (name) name = `(\"${name}\")`;\n return `${msg}: ${status}${name}`;\n};\n\n/**\n * Функция возвращает заголовок веб страницы\n * @path\n */\nmodule.exports.getTitle = options => {\n options = options || {};\n const {\n path = Path(),\n name\n } = options;\n const array = [name || NAME, path];\n return array.filter(Boolean).join(' - ');\n};\n\n/** Функция получает адреса каждого каталога в пути\n * возвращаеться массив каталогов\n * @param url - адрес каталога\n */\nfunction getPathLink(url, prefix, template) {\n if (!url) throw Error('url could not be empty!');\n if (!template) throw Error('template could not be empty!');\n const names = url.split('/').slice(1, -1);\n const allNames = ['/', ...names];\n const lines = [];\n const n = allNames.length;\n let path = '/';\n for (let i = 0; i < n; i++) {\n const name = allNames[i];\n const isLast = i === n - 1;\n if (i) path += `${name}/`;\n if (i && isLast) {\n lines.push(`${name}/`);\n continue;\n }\n const slash = i ? '/' : '';\n lines.push(rendy(template, {\n path,\n name,\n slash,\n prefix\n }));\n }\n return lines.join('');\n}\nconst getDataName = name => {\n const encoded = btoa(encodeURI(name));\n return `data-name=\"js-file-${encoded}\" `;\n};\n\n/**\n * Функция строит таблицу файлв из JSON-информации о файлах\n * @param params - информация о файлах\n *\n */\nmodule.exports.buildFromJSON = params => {\n const {\n prefix,\n template,\n sort = 'name',\n order = 'asc',\n showDotFiles\n } = params;\n const templateFile = template.file;\n const templateLink = template.link;\n const json = params.data;\n const path = encode(json.path);\n const {\n files\n } = json;\n\n /*\n * Строим путь каталога в котором мы находимся\n * со всеми подкаталогами\n */\n const htmlPath = getPathLink(path, prefix, template.pathLink);\n let fileTable = rendy(template.path, {\n link: prefix + FS + path,\n fullPath: path,\n path: htmlPath\n });\n const owner = 'owner';\n const mode = 'mode';\n const getFieldName = getHeaderField(sort, order);\n const name = getFieldName('name');\n const size = getFieldName('size');\n const date = getFieldName('date');\n const header = rendy(templateFile, {\n tag: 'div',\n attribute: 'data-name=\"js-fm-header\" ',\n className: 'fm-header',\n type: '',\n name,\n size,\n date,\n owner,\n mode\n });\n\n /* сохраняем путь */\n Path(path);\n fileTable += `${header}<ul data-name=\"js-files\" class=\"files\">`;\n\n /* Если мы не в корне */\n if (path !== '/') {\n const dotDot = getDotDot(path);\n const link = prefix + FS + dotDot;\n const linkResult = rendy(template.link, {\n link,\n title: '..',\n name: '..'\n });\n const dataName = getDataName('..');\n const attribute = `draggable=\"true\" ${dataName}`;\n\n /* Сохраняем путь к каталогу верхнего уровня*/\n fileTable += rendy(template.file, {\n tag: 'li',\n attribute,\n className: '',\n type: 'directory',\n name: linkResult,\n size: '&lt;dir&gt;',\n date: '--.--.----',\n owner: '.',\n mode: '--- --- ---'\n });\n }\n fileTable += files.filter(filterOutDotFiles({\n showDotFiles\n })).map(updateField).map(file => {\n const name = encode(file.name);\n const link = prefix + FS + path + name;\n const {\n type,\n mode,\n date,\n owner,\n size\n } = file;\n const linkResult = rendy(templateLink, {\n link,\n title: name,\n name,\n attribute: getAttribute(file.type)\n });\n const dataName = getDataName(file.name);\n const attribute = `draggable=\"true\" ${dataName}`;\n return rendy(templateFile, {\n tag: 'li',\n attribute,\n className: '',\n type,\n name: linkResult,\n size,\n date,\n owner,\n mode\n });\n }).join('');\n fileTable += '</ul>';\n return fileTable;\n};\nconst updateField = file => ({\n ...file,\n date: file.date || '--.--.----',\n owner: file.owner || 'root',\n size: getSize(file)\n});\nfunction getAttribute(type) {\n if (type === 'directory') return '';\n return 'target=\"_blank\" ';\n}\nmodule.exports._getSize = getSize;\nfunction getSize({\n size,\n type\n}) {\n if (type === 'directory') return '&lt;dir&gt;';\n if (/link/.test(type)) return '&lt;link&gt;';\n return size;\n}\nfunction _getHeaderField(sort, order, name) {\n const arrow = order === 'asc' ? '↑' : '↓';\n if (sort !== name) return name;\n if (sort === 'name' && order === 'asc') return name;\n return `${name}${arrow}`;\n}\nfunction getDotDot(path) {\n // убираем последний слеш и каталог в котором мы сейчас находимся\n const lastSlash = path.substr(path, path.lastIndexOf('/'));\n const dotDot = lastSlash.substr(lastSlash, lastSlash.lastIndexOf('/'));\n if (!dotDot) return '/';\n return dotDot;\n}\n\n//# sourceURL=file://cloudcmd/common/cloudfunc.js\n}");
778
778
 
779
779
  /***/ },
780
780
 
@@ -961,7 +961,7 @@ eval("{\n\nmodule.exports = ({autoSize, isTitle}) => {\n const classNames = [
961
961
  (module, __unused_webpack_exports, __webpack_require__) {
962
962
 
963
963
  "use strict";
964
- eval("{\n\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\n__webpack_require__(/*! ../css/modal.css */ \"./node_modules/@cloudcmd/modal/css/modal.css\");\nconst parseImages = __webpack_require__(/*! ./parse-images */ \"./node_modules/@cloudcmd/modal/lib/parse-images.js\");\nconst showTitle = __webpack_require__(/*! ./show-title */ \"./node_modules/@cloudcmd/modal/lib/show-title.js\");\nconst query = __webpack_require__(/*! ./query */ \"./node_modules/@cloudcmd/modal/lib/query.js\");\nconst getClassName = __webpack_require__(/*! ./get-class-name */ \"./node_modules/@cloudcmd/modal/lib/get-class-name.js\");\n\nconst noop = () => {};\n\nconst optionsStore = store({});\n\nconst innerHTML = `\n <div class=\"modal-child\" data-name=\"modal-child\">\n <div class=\"modal-close\" data-name=\"modal-close\"></div>\n </div>\n`;\n\nconst addEvent = currify((el, fn, name) => query(el).addEventListener(name, fn));\nconst addAllEvents = (el, fn, names) => names.map(addEvent(el, fn));\n\nconst {isArray} = Array;\n\nmodule.exports.open = (inner, options = {}) => {\n check(inner);\n \n if (query('main'))\n return;\n \n const {\n beforeShow = noop,\n beforeClose = noop,\n afterShow = noop,\n afterClose = noop,\n onOverlayClick = noop,\n autoSize = false,\n index = 0,\n helpers = {},\n title = '',\n } = options;\n \n optionsStore({\n beforeClose,\n afterClose,\n });\n \n beforeShow();\n \n const isImage = isArray(inner);\n const isTitle = helpers.title && title || isImage;\n \n const className = getClassName({autoSize, isTitle});\n \n const el = createElement('div', {\n innerHTML,\n className,\n dataName: 'modal-main',\n });\n \n addAllEvents('main', onMainClick(onOverlayClick), [\n 'click',\n 'contextmenu',\n ]);\n \n query('close').addEventListener('click', close);\n \n const child = query('child');\n \n if (isImage)\n return parseImages(child, inner, {\n index,\n afterShow,\n helpers,\n });\n \n child.appendChild(inner);\n \n if (isTitle)\n showTitle(title, child);\n \n afterShow();\n \n return el;\n};\n\nconst onMainClick = currify((overlayClick, event) => {\n if (event.target !== query('main'))\n return;\n \n close(event);\n overlayClick(event);\n});\n\nconst close = (event) => {\n if (event)\n event.stopPropagation();\n \n const el = query('main');\n \n const {\n beforeClose = noop,\n afterClose = noop,\n } = optionsStore();\n \n if (!el)\n return;\n \n beforeClose();\n \n document.body.removeChild(el);\n \n afterClose();\n};\n\nmodule.exports.close = close;\n\nmodule.exports._optionsStore = optionsStore;\nmodule.exports._onMainClick = onMainClick;\n\nfunction check(inner) {\n if (!inner)\n throw Error('inner should be DOM-element!');\n}\n\n\n\n//# sourceURL=file://cloudcmd/node_modules/@cloudcmd/modal/lib/modal.js\n}");
964
+ eval("{\n\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/@cloudcmd/modal/node_modules/fullstore/lib/fullstore.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\n__webpack_require__(/*! ../css/modal.css */ \"./node_modules/@cloudcmd/modal/css/modal.css\");\nconst parseImages = __webpack_require__(/*! ./parse-images */ \"./node_modules/@cloudcmd/modal/lib/parse-images.js\");\nconst showTitle = __webpack_require__(/*! ./show-title */ \"./node_modules/@cloudcmd/modal/lib/show-title.js\");\nconst query = __webpack_require__(/*! ./query */ \"./node_modules/@cloudcmd/modal/lib/query.js\");\nconst getClassName = __webpack_require__(/*! ./get-class-name */ \"./node_modules/@cloudcmd/modal/lib/get-class-name.js\");\n\nconst noop = () => {};\n\nconst optionsStore = store({});\n\nconst innerHTML = `\n <div class=\"modal-child\" data-name=\"modal-child\">\n <div class=\"modal-close\" data-name=\"modal-close\"></div>\n </div>\n`;\n\nconst addEvent = currify((el, fn, name) => query(el).addEventListener(name, fn));\nconst addAllEvents = (el, fn, names) => names.map(addEvent(el, fn));\n\nconst {isArray} = Array;\n\nmodule.exports.open = (inner, options = {}) => {\n check(inner);\n \n if (query('main'))\n return;\n \n const {\n beforeShow = noop,\n beforeClose = noop,\n afterShow = noop,\n afterClose = noop,\n onOverlayClick = noop,\n autoSize = false,\n index = 0,\n helpers = {},\n title = '',\n } = options;\n \n optionsStore({\n beforeClose,\n afterClose,\n });\n \n beforeShow();\n \n const isImage = isArray(inner);\n const isTitle = helpers.title && title || isImage;\n \n const className = getClassName({autoSize, isTitle});\n \n const el = createElement('div', {\n innerHTML,\n className,\n dataName: 'modal-main',\n });\n \n addAllEvents('main', onMainClick(onOverlayClick), [\n 'click',\n 'contextmenu',\n ]);\n \n query('close').addEventListener('click', close);\n \n const child = query('child');\n \n if (isImage)\n return parseImages(child, inner, {\n index,\n afterShow,\n helpers,\n });\n \n child.appendChild(inner);\n \n if (isTitle)\n showTitle(title, child);\n \n afterShow();\n \n return el;\n};\n\nconst onMainClick = currify((overlayClick, event) => {\n if (event.target !== query('main'))\n return;\n \n close(event);\n overlayClick(event);\n});\n\nconst close = (event) => {\n if (event)\n event.stopPropagation();\n \n const el = query('main');\n \n const {\n beforeClose = noop,\n afterClose = noop,\n } = optionsStore();\n \n if (!el)\n return;\n \n beforeClose();\n \n document.body.removeChild(el);\n \n afterClose();\n};\n\nmodule.exports.close = close;\n\nmodule.exports._optionsStore = optionsStore;\nmodule.exports._onMainClick = onMainClick;\n\nfunction check(inner) {\n if (!inner)\n throw Error('inner should be DOM-element!');\n}\n\n\n\n//# sourceURL=file://cloudcmd/node_modules/@cloudcmd/modal/lib/modal.js\n}");
965
965
 
966
966
  /***/ },
967
967
 
@@ -972,7 +972,7 @@ eval("{\n\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/f
972
972
  (module, __unused_webpack_exports, __webpack_require__) {
973
973
 
974
974
  "use strict";
975
- eval("{\n\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\nconst showTitle = __webpack_require__(/*! ./show-title */ \"./node_modules/@cloudcmd/modal/lib/show-title.js\");\nconst query = __webpack_require__(/*! ./query */ \"./node_modules/@cloudcmd/modal/lib/query.js\");\n\nconst indexStore = store();\nconst helpersStore = store();\n\nconst next = wraptile((img, images) => setImage(indexStore() + 1, img, images));\nconst prev = wraptile((img, images) => setImage(indexStore() - 1, img, images));\n\nconst onload = wraptile((parent, afterShow) => {\n parent.hidden = false;\n afterShow();\n});\n\nconst onKeydown = (img, images) => function keydownListener(e) {\n let i = indexStore();\n \n const ArrowLeft = 37;\n const ArrowRight = 39;\n const Esc = 27;\n \n const {keyCode} = e;\n \n if (keyCode === ArrowLeft)\n --i;\n else if (keyCode === ArrowRight)\n ++i;\n else {\n if (keyCode === Esc)\n return document.body.removeEventListener('keydown', keydownListener);\n \n return;\n }\n \n setImage(i, img, images);\n};\n\nfunction setImage(i, img, images) {\n const n = images.length - 1;\n \n if (i < 0 || i > n)\n return;\n \n indexStore(i);\n \n query('nav-left').hidden = !i;\n query('nav-right').hidden = i === n;\n \n const {\n href,\n title,\n } = images[i];\n \n img.src = href;\n img.title = title;\n img.href = title;\n img.alt = title;\n \n if (helpersStore().title)\n showTitle(title, query('child'));\n}\n\nmodule.exports = parseImages;\n\nfunction parseImages(parent, images, {afterShow, helpers, index}) {\n indexStore(index);\n helpersStore(helpers);\n \n const img = createImage();\n parent.appendChild(img);\n \n parent.hidden = true;\n \n parent.appendChild(createElement('div', {\n className: 'modal-nav modal-nav-left',\n dataName: 'modal-nav-left',\n innerHTML: '<span></span>',\n }));\n \n parent.appendChild(createElement('div', {\n className: 'modal-nav modal-nav-right',\n dataName: 'modal-nav-right',\n innerHTML: '<span data-name=\"modal-next\"></span>',\n }));\n \n setImage(index, img, images);\n addListenerOnce(img, 'load', onload(parent, afterShow));\n \n query('nav-left')\n .addEventListener('click', prev(img, images));\n \n query('nav-right')\n .addEventListener('click', next(img, images));\n \n document.body.addEventListener('keydown', onKeydown(img, images));\n}\n\nfunction createImage() {\n const el = document.createElement('img');\n \n el.className = 'modal-image';\n \n return el;\n}\n\nmodule.exports._rmListener = rmListener;\nfunction rmListener(el, name, fn) {\n return function f(e) {\n fn(e);\n el.removeEventListener(name, f);\n };\n}\n\nmodule.exports._addListenerOnce = addListenerOnce;\nfunction addListenerOnce(el, name, fn) {\n el.addEventListener(name, rmListener(el, name, fn));\n}\n\nmodule.exports._onKeydown = onKeydown;\nmodule.exports._indexStore = indexStore;\nmodule.exports._helpersStore = helpersStore;\nmodule.exports._onload = onload;\n\n\n\n//# sourceURL=file://cloudcmd/node_modules/@cloudcmd/modal/lib/parse-images.js\n}");
975
+ eval("{\n\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/@cloudcmd/modal/node_modules/fullstore/lib/fullstore.js\");\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\nconst showTitle = __webpack_require__(/*! ./show-title */ \"./node_modules/@cloudcmd/modal/lib/show-title.js\");\nconst query = __webpack_require__(/*! ./query */ \"./node_modules/@cloudcmd/modal/lib/query.js\");\n\nconst indexStore = store();\nconst helpersStore = store();\n\nconst next = wraptile((img, images) => setImage(indexStore() + 1, img, images));\nconst prev = wraptile((img, images) => setImage(indexStore() - 1, img, images));\n\nconst onload = wraptile((parent, afterShow) => {\n parent.hidden = false;\n afterShow();\n});\n\nconst onKeydown = (img, images) => function keydownListener(e) {\n let i = indexStore();\n \n const ArrowLeft = 37;\n const ArrowRight = 39;\n const Esc = 27;\n \n const {keyCode} = e;\n \n if (keyCode === ArrowLeft)\n --i;\n else if (keyCode === ArrowRight)\n ++i;\n else {\n if (keyCode === Esc)\n return document.body.removeEventListener('keydown', keydownListener);\n \n return;\n }\n \n setImage(i, img, images);\n};\n\nfunction setImage(i, img, images) {\n const n = images.length - 1;\n \n if (i < 0 || i > n)\n return;\n \n indexStore(i);\n \n query('nav-left').hidden = !i;\n query('nav-right').hidden = i === n;\n \n const {\n href,\n title,\n } = images[i];\n \n img.src = href;\n img.title = title;\n img.href = title;\n img.alt = title;\n \n if (helpersStore().title)\n showTitle(title, query('child'));\n}\n\nmodule.exports = parseImages;\n\nfunction parseImages(parent, images, {afterShow, helpers, index}) {\n indexStore(index);\n helpersStore(helpers);\n \n const img = createImage();\n parent.appendChild(img);\n \n parent.hidden = true;\n \n parent.appendChild(createElement('div', {\n className: 'modal-nav modal-nav-left',\n dataName: 'modal-nav-left',\n innerHTML: '<span></span>',\n }));\n \n parent.appendChild(createElement('div', {\n className: 'modal-nav modal-nav-right',\n dataName: 'modal-nav-right',\n innerHTML: '<span data-name=\"modal-next\"></span>',\n }));\n \n setImage(index, img, images);\n addListenerOnce(img, 'load', onload(parent, afterShow));\n \n query('nav-left')\n .addEventListener('click', prev(img, images));\n \n query('nav-right')\n .addEventListener('click', next(img, images));\n \n document.body.addEventListener('keydown', onKeydown(img, images));\n}\n\nfunction createImage() {\n const el = document.createElement('img');\n \n el.className = 'modal-image';\n \n return el;\n}\n\nmodule.exports._rmListener = rmListener;\nfunction rmListener(el, name, fn) {\n return function f(e) {\n fn(e);\n el.removeEventListener(name, f);\n };\n}\n\nmodule.exports._addListenerOnce = addListenerOnce;\nfunction addListenerOnce(el, name, fn) {\n el.addEventListener(name, rmListener(el, name, fn));\n}\n\nmodule.exports._onKeydown = onKeydown;\nmodule.exports._indexStore = indexStore;\nmodule.exports._helpersStore = helpersStore;\nmodule.exports._onload = onload;\n\n\n\n//# sourceURL=file://cloudcmd/node_modules/@cloudcmd/modal/lib/parse-images.js\n}");
976
976
 
977
977
  /***/ },
978
978
 
@@ -998,6 +998,17 @@ eval("{\n\nconst createElement = __webpack_require__(/*! @cloudcmd/create-elemen
998
998
 
999
999
  /***/ },
1000
1000
 
1001
+ /***/ "./node_modules/@cloudcmd/modal/node_modules/fullstore/lib/fullstore.js"
1002
+ /*!******************************************************************************!*\
1003
+ !*** ./node_modules/@cloudcmd/modal/node_modules/fullstore/lib/fullstore.js ***!
1004
+ \******************************************************************************/
1005
+ (module) {
1006
+
1007
+ "use strict";
1008
+ eval("{\n\nmodule.exports = (value) => {\n const data = {\n value,\n };\n \n return (...args) => {\n const [value] = args;\n \n if (!args.length)\n return data.value;\n \n data.value = value;\n \n return value;\n };\n};\n\n\n\n//# sourceURL=file://cloudcmd/node_modules/@cloudcmd/modal/node_modules/fullstore/lib/fullstore.js\n}");
1009
+
1010
+ /***/ },
1011
+
1001
1012
  /***/ "./node_modules/@cloudcmd/olark/index.js"
1002
1013
  /*!***********************************************!*\
1003
1014
  !*** ./node_modules/@cloudcmd/olark/index.js ***!
@@ -1149,14 +1160,24 @@ eval("{\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/c
1149
1160
 
1150
1161
  /***/ },
1151
1162
 
1163
+ /***/ "./node_modules/fullstore/lib/fullstore.cjs"
1164
+ /*!**************************************************!*\
1165
+ !*** ./node_modules/fullstore/lib/fullstore.cjs ***!
1166
+ \**************************************************/
1167
+ (module, __unused_webpack_exports, __webpack_require__) {
1168
+
1169
+ eval("{const {fullstore} = __webpack_require__(/*! ./fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\n\nmodule.exports = fullstore;\nmodule.exports.fullstore = fullstore;\n\n\n//# sourceURL=file://cloudcmd/node_modules/fullstore/lib/fullstore.cjs\n}");
1170
+
1171
+ /***/ },
1172
+
1152
1173
  /***/ "./node_modules/fullstore/lib/fullstore.js"
1153
1174
  /*!*************************************************!*\
1154
1175
  !*** ./node_modules/fullstore/lib/fullstore.js ***!
1155
1176
  \*************************************************/
1156
- (module) {
1177
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1157
1178
 
1158
1179
  "use strict";
1159
- eval("{\n\nmodule.exports = (value) => {\n const data = {\n value,\n };\n \n return (...args) => {\n const [value] = args;\n \n if (!args.length)\n return data.value;\n \n data.value = value;\n \n return value;\n };\n};\n\n\n\n//# sourceURL=file://cloudcmd/node_modules/fullstore/lib/fullstore.js\n}");
1180
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ fullstore: () => (/* binding */ fullstore)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (fullstore);\n\nfunction fullstore(value) {\n const data = {\n value,\n };\n \n return (...args) => {\n const [value] = args;\n \n if (!args.length)\n return data.value;\n \n data.value = value;\n \n return value;\n };\n};\n\n\n//# sourceURL=file://cloudcmd/node_modules/fullstore/lib/fullstore.js\n}");
1160
1181
 
1161
1182
  /***/ },
1162
1183
 
@@ -1392,7 +1413,18 @@ eval("{__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-ext
1392
1413
  (module, __unused_webpack_exports, __webpack_require__) {
1393
1414
 
1394
1415
  "use strict";
1395
- eval("{\n\n__webpack_require__(/*! ../css/smalltalk.css */ \"./node_modules/smalltalk/css/smalltalk.css\");\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\nconst isBool = (a) => typeof a === 'boolean';\n\nconst keyDown = currify(keyDown_);\n\nconst BUTTON_OK = {\n ok: 'OK',\n};\n\nconst BUTTON_OK_CANCEL = {\n ok: 'OK',\n cancel: 'Cancel',\n};\n\nconst zIndex = store(100);\n\nmodule.exports.alert = (title, msg, options) => {\n const buttons = getButtons(options) || BUTTON_OK;\n return showDialog(title, msg, '', buttons, options);\n};\n\nmodule.exports.prompt = (title, msg, value = '', options) => {\n const type = getType(options);\n const val = String(value).replace(/\"/g, '&quot;');\n \n const valueStr = `<input type=\"${type}\" value=\"${val}\" data-name=\"js-input\">`;\n const buttons = getButtons(options) || BUTTON_OK_CANCEL;\n \n return showDialog(title, msg, valueStr, buttons, options);\n};\n\nmodule.exports.confirm = (title, msg, options) => {\n const buttons = getButtons(options) || BUTTON_OK_CANCEL;\n \n return showDialog(title, msg, '', buttons, options);\n};\n\nmodule.exports.progress = (title, message, options) => {\n const valueStr = `\n <progress value=\"0\" data-name=\"js-progress\" class=\"progress\" max=\"100\"></progress>\n <span data-name=\"js-counter\">0%</span>\n `;\n \n const buttons = {\n cancel: 'Abort',\n };\n \n const promise = showDialog(title, message, valueStr, buttons, options);\n const {ok, dialog} = promise;\n const resolve = ok();\n \n for (const el of find(dialog, ['cancel'])) {\n el.focus();\n }\n \n Object.assign(promise, {\n setProgress(count) {\n const [elProgress] = find(dialog, ['progress']);\n const [elCounter] = find(dialog, ['counter']);\n \n elProgress.value = count;\n elCounter.textContent = `${count}%`;\n \n if (count === 100) {\n remove(dialog);\n resolve();\n }\n },\n \n remove() {\n remove(dialog);\n },\n });\n \n return promise;\n};\n\nfunction getButtons(options = {}) {\n const {buttons} = options;\n \n if (!buttons)\n return null;\n \n return buttons;\n}\n\nfunction getType(options = {}) {\n const {type} = options;\n \n if (type === 'password')\n return 'password';\n \n return 'text';\n}\n\nfunction getTemplate(title, msg, value, buttons) {\n const encodedMsg = msg.replace(/\\n/g, '<br>');\n \n return `<div class=\"page\">\n <div data-name=\"js-close\" class=\"close-button\"></div>\n <header>${title}</header>\n <div class=\"content-area\">${encodedMsg}${value}</div>\n <div class=\"action-area\">\n <div class=\"button-strip\">\n ${parseButtons(buttons)}\n </div>\n </div>\n </div>`;\n}\n\nfunction parseButtons(buttons) {\n const names = Object.keys(buttons);\n const parse = currify((buttons, name, i) => `<button\n tabindex=${i}\n data-name=\"js-${name.toLowerCase()}\">\n ${buttons[name]}\n </button>`);\n \n return names\n .map(parse(buttons))\n .join('');\n}\n\nfunction showDialog(title, msg, value, buttons, options) {\n const ok = store();\n const cancel = store();\n \n const closeButtons = [\n 'cancel',\n 'close',\n 'ok',\n ];\n \n const promise = new Promise((resolve, reject) => {\n const noCancel = options && isBool(options.cancel) && !options.cancel;\n const empty = () => {};\n const rejectError = () => reject(Error());\n \n ok(resolve);\n cancel(noCancel ? empty : rejectError);\n });\n \n const innerHTML = getTemplate(title, msg, value, buttons);\n \n const dialog = createElement('div', {\n innerHTML,\n className: 'smalltalk',\n style: `z-index: ${zIndex(zIndex() + 1)}`,\n });\n \n for (const el of find(dialog, ['ok', 'input']))\n el.focus();\n \n for (const el of find(dialog, ['input'])) {\n el.setSelectionRange(0, value.length);\n }\n \n addListenerAll('click', dialog, closeButtons, (event) => {\n closeDialog(event.target, dialog, ok(), cancel());\n });\n \n for (const event of ['click', 'contextmenu'])\n dialog.addEventListener(event, (e) => {\n e.stopPropagation();\n \n for (const el of find(dialog, ['ok', 'input']))\n el.focus();\n });\n \n dialog.addEventListener('keydown', keyDown(dialog, ok(), cancel()));\n \n return Object.assign(promise, {\n dialog,\n ok,\n });\n}\n\nfunction keyDown_(dialog, ok, cancel, event) {\n const KEY = {\n ENTER: 13,\n ESC: 27,\n TAB: 9,\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n };\n \n const {keyCode} = event;\n const el = event.target;\n \n const namesAll = [\n 'ok',\n 'cancel',\n 'input',\n ];\n const names = find(dialog, namesAll).map(getDataName);\n \n switch(keyCode) {\n case KEY.ENTER:\n closeDialog(el, dialog, ok, cancel);\n event.preventDefault();\n break;\n \n case KEY.ESC:\n remove(dialog);\n cancel();\n break;\n \n case KEY.TAB:\n if (event.shiftKey)\n tab(dialog, names);\n \n tab(dialog, names);\n event.preventDefault();\n break;\n \n default:\n [\n 'left',\n 'right',\n 'up',\n 'down',\n ]\n .filter((name) => keyCode === KEY[name.toUpperCase()])\n .forEach(() => {\n changeButtonFocus(dialog, names);\n });\n \n break;\n }\n \n event.stopPropagation();\n}\n\nfunction getDataName(el) {\n return el\n .getAttribute('data-name')\n .replace('js-', '');\n}\n\nconst getName = (activeName) => {\n if (activeName === 'cancel')\n return 'ok';\n \n return 'cancel';\n};\n\nfunction changeButtonFocus(dialog, names) {\n const active = document.activeElement;\n const activeName = getDataName(active);\n const isButton = /ok|cancel/.test(activeName);\n const count = names.length - 1;\n \n if (activeName === 'input' || !count || !isButton)\n return;\n \n const name = getName(activeName);\n \n for (const el of find(dialog, [name])) {\n el.focus();\n }\n}\n\nconst getIndex = (count, index) => {\n if (index === count)\n return 0;\n \n return index + 1;\n};\n\nfunction tab(dialog, names) {\n const active = document.activeElement;\n const activeName = getDataName(active);\n const count = names.length - 1;\n \n const activeIndex = names.indexOf(activeName);\n const index = getIndex(count, activeIndex);\n \n const name = names[index];\n \n for (const el of find(dialog, [name]))\n el.focus();\n}\n\nfunction closeDialog(el, dialog, ok, cancel) {\n const name = el\n .getAttribute('data-name')\n .replace('js-', '');\n \n if (/close|cancel/.test(name)) {\n cancel();\n remove(dialog);\n \n return;\n }\n \n let value = null;\n \n for (const el of find(dialog, ['input'])) {\n value = el.value;\n }\n \n ok(value);\n remove(dialog);\n}\n\nconst query = currify((element, name) => element.querySelector(`[data-name=\"js-${name}\"]`));\n\nfunction find(element, names) {\n const elements = names\n .map(query(element))\n .filter(Boolean);\n \n return elements;\n}\n\nfunction addListenerAll(event, parent, elements, fn) {\n for (const el of find(parent, elements)) {\n el.addEventListener(event, fn);\n }\n}\n\nfunction remove(dialog) {\n const {parentElement} = dialog;\n \n if (parentElement)\n parentElement.removeChild(dialog);\n}\n\n\n//# sourceURL=file://cloudcmd/node_modules/smalltalk/lib/smalltalk.js\n}");
1416
+ eval("{\n\n__webpack_require__(/*! ../css/smalltalk.css */ \"./node_modules/smalltalk/css/smalltalk.css\");\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst store = __webpack_require__(/*! fullstore */ \"./node_modules/smalltalk/node_modules/fullstore/lib/fullstore.js\");\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\nconst isBool = (a) => typeof a === 'boolean';\n\nconst keyDown = currify(keyDown_);\n\nconst BUTTON_OK = {\n ok: 'OK',\n};\n\nconst BUTTON_OK_CANCEL = {\n ok: 'OK',\n cancel: 'Cancel',\n};\n\nconst zIndex = store(100);\n\nmodule.exports.alert = (title, msg, options) => {\n const buttons = getButtons(options) || BUTTON_OK;\n return showDialog(title, msg, '', buttons, options);\n};\n\nmodule.exports.prompt = (title, msg, value = '', options) => {\n const type = getType(options);\n const val = String(value).replace(/\"/g, '&quot;');\n \n const valueStr = `<input type=\"${type}\" value=\"${val}\" data-name=\"js-input\">`;\n const buttons = getButtons(options) || BUTTON_OK_CANCEL;\n \n return showDialog(title, msg, valueStr, buttons, options);\n};\n\nmodule.exports.confirm = (title, msg, options) => {\n const buttons = getButtons(options) || BUTTON_OK_CANCEL;\n \n return showDialog(title, msg, '', buttons, options);\n};\n\nmodule.exports.progress = (title, message, options) => {\n const valueStr = `\n <progress value=\"0\" data-name=\"js-progress\" class=\"progress\" max=\"100\"></progress>\n <span data-name=\"js-counter\">0%</span>\n `;\n \n const buttons = {\n cancel: 'Abort',\n };\n \n const promise = showDialog(title, message, valueStr, buttons, options);\n const {ok, dialog} = promise;\n const resolve = ok();\n \n for (const el of find(dialog, ['cancel'])) {\n el.focus();\n }\n \n Object.assign(promise, {\n setProgress(count) {\n const [elProgress] = find(dialog, ['progress']);\n const [elCounter] = find(dialog, ['counter']);\n \n elProgress.value = count;\n elCounter.textContent = `${count}%`;\n \n if (count === 100) {\n remove(dialog);\n resolve();\n }\n },\n \n remove() {\n remove(dialog);\n },\n });\n \n return promise;\n};\n\nfunction getButtons(options = {}) {\n const {buttons} = options;\n \n if (!buttons)\n return null;\n \n return buttons;\n}\n\nfunction getType(options = {}) {\n const {type} = options;\n \n if (type === 'password')\n return 'password';\n \n return 'text';\n}\n\nfunction getTemplate(title, msg, value, buttons) {\n const encodedMsg = msg.replace(/\\n/g, '<br>');\n \n return `<div class=\"page\">\n <div data-name=\"js-close\" class=\"close-button\"></div>\n <header>${title}</header>\n <div class=\"content-area\">${encodedMsg}${value}</div>\n <div class=\"action-area\">\n <div class=\"button-strip\">\n ${parseButtons(buttons)}\n </div>\n </div>\n </div>`;\n}\n\nfunction parseButtons(buttons) {\n const names = Object.keys(buttons);\n const parse = currify((buttons, name, i) => `<button\n tabindex=${i}\n data-name=\"js-${name.toLowerCase()}\">\n ${buttons[name]}\n </button>`);\n \n return names\n .map(parse(buttons))\n .join('');\n}\n\nfunction showDialog(title, msg, value, buttons, options) {\n const ok = store();\n const cancel = store();\n \n const closeButtons = [\n 'cancel',\n 'close',\n 'ok',\n ];\n \n const promise = new Promise((resolve, reject) => {\n const noCancel = options && isBool(options.cancel) && !options.cancel;\n const empty = () => {};\n const rejectError = () => reject(Error());\n \n ok(resolve);\n cancel(noCancel ? empty : rejectError);\n });\n \n const innerHTML = getTemplate(title, msg, value, buttons);\n \n const dialog = createElement('div', {\n innerHTML,\n className: 'smalltalk',\n style: `z-index: ${zIndex(zIndex() + 1)}`,\n });\n \n for (const el of find(dialog, ['ok', 'input']))\n el.focus();\n \n for (const el of find(dialog, ['input'])) {\n el.setSelectionRange(0, value.length);\n }\n \n addListenerAll('click', dialog, closeButtons, (event) => {\n closeDialog(event.target, dialog, ok(), cancel());\n });\n \n for (const event of ['click', 'contextmenu'])\n dialog.addEventListener(event, (e) => {\n e.stopPropagation();\n \n for (const el of find(dialog, ['ok', 'input']))\n el.focus();\n });\n \n dialog.addEventListener('keydown', keyDown(dialog, ok(), cancel()));\n \n return Object.assign(promise, {\n dialog,\n ok,\n });\n}\n\nfunction keyDown_(dialog, ok, cancel, event) {\n const KEY = {\n ENTER: 13,\n ESC: 27,\n TAB: 9,\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n };\n \n const {keyCode} = event;\n const el = event.target;\n \n const namesAll = [\n 'ok',\n 'cancel',\n 'input',\n ];\n const names = find(dialog, namesAll).map(getDataName);\n \n switch(keyCode) {\n case KEY.ENTER:\n closeDialog(el, dialog, ok, cancel);\n event.preventDefault();\n break;\n \n case KEY.ESC:\n remove(dialog);\n cancel();\n break;\n \n case KEY.TAB:\n if (event.shiftKey)\n tab(dialog, names);\n \n tab(dialog, names);\n event.preventDefault();\n break;\n \n default:\n [\n 'left',\n 'right',\n 'up',\n 'down',\n ]\n .filter((name) => keyCode === KEY[name.toUpperCase()])\n .forEach(() => {\n changeButtonFocus(dialog, names);\n });\n \n break;\n }\n \n event.stopPropagation();\n}\n\nfunction getDataName(el) {\n return el\n .getAttribute('data-name')\n .replace('js-', '');\n}\n\nconst getName = (activeName) => {\n if (activeName === 'cancel')\n return 'ok';\n \n return 'cancel';\n};\n\nfunction changeButtonFocus(dialog, names) {\n const active = document.activeElement;\n const activeName = getDataName(active);\n const isButton = /ok|cancel/.test(activeName);\n const count = names.length - 1;\n \n if (activeName === 'input' || !count || !isButton)\n return;\n \n const name = getName(activeName);\n \n for (const el of find(dialog, [name])) {\n el.focus();\n }\n}\n\nconst getIndex = (count, index) => {\n if (index === count)\n return 0;\n \n return index + 1;\n};\n\nfunction tab(dialog, names) {\n const active = document.activeElement;\n const activeName = getDataName(active);\n const count = names.length - 1;\n \n const activeIndex = names.indexOf(activeName);\n const index = getIndex(count, activeIndex);\n \n const name = names[index];\n \n for (const el of find(dialog, [name]))\n el.focus();\n}\n\nfunction closeDialog(el, dialog, ok, cancel) {\n const name = el\n .getAttribute('data-name')\n .replace('js-', '');\n \n if (/close|cancel/.test(name)) {\n cancel();\n remove(dialog);\n \n return;\n }\n \n let value = null;\n \n for (const el of find(dialog, ['input'])) {\n value = el.value;\n }\n \n ok(value);\n remove(dialog);\n}\n\nconst query = currify((element, name) => element.querySelector(`[data-name=\"js-${name}\"]`));\n\nfunction find(element, names) {\n const elements = names\n .map(query(element))\n .filter(Boolean);\n \n return elements;\n}\n\nfunction addListenerAll(event, parent, elements, fn) {\n for (const el of find(parent, elements)) {\n el.addEventListener(event, fn);\n }\n}\n\nfunction remove(dialog) {\n const {parentElement} = dialog;\n \n if (parentElement)\n parentElement.removeChild(dialog);\n}\n\n\n//# sourceURL=file://cloudcmd/node_modules/smalltalk/lib/smalltalk.js\n}");
1417
+
1418
+ /***/ },
1419
+
1420
+ /***/ "./node_modules/smalltalk/node_modules/fullstore/lib/fullstore.js"
1421
+ /*!************************************************************************!*\
1422
+ !*** ./node_modules/smalltalk/node_modules/fullstore/lib/fullstore.js ***!
1423
+ \************************************************************************/
1424
+ (module) {
1425
+
1426
+ "use strict";
1427
+ eval("{\n\nmodule.exports = (value) => {\n const data = {\n value,\n };\n \n return (...args) => {\n const [value] = args;\n \n if (!args.length)\n return data.value;\n \n data.value = value;\n \n return value;\n };\n};\n\n\n\n//# sourceURL=file://cloudcmd/node_modules/smalltalk/node_modules/fullstore/lib/fullstore.js\n}");
1396
1428
 
1397
1429
  /***/ },
1398
1430
 
package/dist-dev/sw.js CHANGED
@@ -16,7 +16,7 @@
16
16
  (__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
17
17
 
18
18
  "use strict";
19
- eval("{\n\nconst process = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\nconst {\n tryToCatch\n} = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.cjs\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst isDev = process.env.NODE_ENV === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify((f, e) => e.waitUntil(f()));\nconst respondWith = currify((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Wed Dec 31 2025 14:14:22 GMT+0200 (Eastern European Standard Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nself.addEventListener('install', wait(onInstall));\nself.addEventListener('fetch', respondWith(onFetch));\nself.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await self.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await self.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await tryToCatch(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd/client/sw/sw.js\n}");
19
+ eval("{\n\nconst process = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\nconst {\n tryToCatch\n} = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.cjs\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst isDev = process.env.NODE_ENV === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify((f, e) => e.waitUntil(f()));\nconst respondWith = currify((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Mon Jan 12 2026 13:33:14 GMT+0200 (Eastern European Standard Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nself.addEventListener('install', wait(onInstall));\nself.addEventListener('fetch', respondWith(onFetch));\nself.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await self.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await self.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await tryToCatch(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd/client/sw/sw.js\n}");
20
20
 
21
21
  /***/ },
22
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudcmd",
3
- "version": "19.1.0",
3
+ "version": "19.1.1",
4
4
  "type": "commonjs",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "File manager for the web with console and editor",
@@ -108,7 +108,7 @@
108
108
  "find-up": "^8.0.0",
109
109
  "for-each-key": "^2.0.0",
110
110
  "format-io": "^2.0.0",
111
- "fullstore": "^3.0.0",
111
+ "fullstore": "^4.0.0",
112
112
  "http-auth": "^4.2.1",
113
113
  "inly": "^5.0.0",
114
114
  "jaguar": "^6.0.0",
@@ -156,7 +156,7 @@
156
156
  "@cloudcmd/create-element": "^2.0.0",
157
157
  "@cloudcmd/modal": "^3.0.0",
158
158
  "@cloudcmd/olark": "^3.0.2",
159
- "@cloudcmd/stub": "^4.0.1",
159
+ "@cloudcmd/stub": "^5.0.0",
160
160
  "@iocmd/wait": "^2.1.0",
161
161
  "@putout/eslint-flat": "^3.0.1",
162
162
  "@putout/plugin-cloudcmd": "^4.0.0",
@@ -175,7 +175,7 @@
175
175
  "eslint": "^9.23.0",
176
176
  "eslint-plugin-n": "^17.0.0-4",
177
177
  "eslint-plugin-putout": "^29.0.2",
178
- "globals": "^16.3.0",
178
+ "globals": "^17.0.0",
179
179
  "gritty": "^9.0.0",
180
180
  "gunzip-maybe": "^1.3.1",
181
181
  "html-webpack-plugin": "^5.6.3",
@@ -184,7 +184,7 @@
184
184
  "just-pascal-case": "^3.2.0",
185
185
  "limier": "^3.0.0",
186
186
  "load.js": "^3.0.0",
187
- "madrun": "^11.0.0",
187
+ "madrun": "^12.1.0",
188
188
  "memfs": "^4.2.0",
189
189
  "mini-css-extract-plugin": "^2.9.2",
190
190
  "minor": "^1.2.2",
@@ -207,7 +207,7 @@
207
207
  "smalltalk": "^4.0.0",
208
208
  "style-loader": "^4.0.0",
209
209
  "supermenu": "^4.0.1",
210
- "supertape": "^11.0.4",
210
+ "supertape": "^12.0.0",
211
211
  "tar-stream": "^3.0.0",
212
212
  "unionfs": "^4.0.0",
213
213
  "url-loader": "^4.0.0",