cloudcmd 16.1.0 → 16.3.0

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.
Files changed (47) hide show
  1. package/ChangeLog +21 -0
  2. package/HELP.md +4 -1
  3. package/LICENSE +1 -1
  4. package/README.md +1 -1
  5. package/bin/cloudcmd.mjs +13 -12
  6. package/dist/cloudcmd.common.js +2 -2
  7. package/dist/cloudcmd.common.js.map +1 -1
  8. package/dist/cloudcmd.js +1 -1
  9. package/dist/cloudcmd.js.map +1 -1
  10. package/dist/modules/cloud.js +1 -1
  11. package/dist/modules/cloud.js.map +1 -1
  12. package/dist/modules/config.js +1 -1
  13. package/dist/modules/config.js.map +1 -1
  14. package/dist/modules/edit.js +1 -1
  15. package/dist/modules/edit.js.map +1 -1
  16. package/dist/modules/markdown.js +1 -1
  17. package/dist/modules/markdown.js.map +1 -1
  18. package/dist/modules/menu.js +1 -1
  19. package/dist/modules/operation.js +1 -1
  20. package/dist/modules/operation.js.map +1 -1
  21. package/dist/modules/terminal-run.js +1 -1
  22. package/dist/modules/terminal-run.js.map +1 -1
  23. package/dist/modules/upload.js +1 -1
  24. package/dist/modules/user-menu.js +1 -1
  25. package/dist/modules/user-menu.js.map +1 -1
  26. package/dist/modules/view.js +1 -1
  27. package/dist/sw.js +1 -1
  28. package/dist/sw.js.map +1 -1
  29. package/dist-dev/cloudcmd.common.js +4 -4
  30. package/dist-dev/cloudcmd.js +6 -6
  31. package/dist-dev/modules/cloud.js +1 -1
  32. package/dist-dev/modules/config.js +1 -1
  33. package/dist-dev/modules/edit.js +1 -1
  34. package/dist-dev/modules/markdown.js +1 -1
  35. package/dist-dev/modules/operation.js +1 -1
  36. package/dist-dev/modules/terminal-run.js +1 -1
  37. package/dist-dev/modules/user-menu.js +1 -1
  38. package/dist-dev/sw.js +1 -1
  39. package/package.json +5 -5
  40. package/server/cloudcmd.js +5 -5
  41. package/server/config.js +4 -4
  42. package/server/distribute/import.js +2 -2
  43. package/server/markdown/index.js +2 -2
  44. package/server/rest/index.js +2 -2
  45. package/server/route.js +6 -6
  46. package/server/{server.js → server.mjs} +19 -22
  47. package/tmpl/config.hbs +2 -2
package/dist/sw.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["file://cloudcmd/webpack/bootstrap","file://cloudcmd/client/sw/sw.js","file://cloudcmd/node_modules/try-to-catch/lib/try-to-catch.js","file://cloudcmd/node_modules/currify/lib/currify.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","tryToCatch","require","currify","wait","f","e","waitUntil","respondWith","request","url","pathname","getPathName","test","method","a","type","isBasic","URL","NAME","getRequest","Request","credentials","createRequest","self","addEventListener","async","console","info","skipWaiting","event","newRequest","cache","caches","open","response","match","resp","fetch","Response","message","put","addToCache","clone","clients","claim","keys","deleteCache","delete","Promise","all","map","fn","args","Error","check","length","again","args2","count","arguments","b"],"mappings":"aACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QAKfF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,SAIjBlC,EAAoBA,EAAoBmC,EAAI,G,+BC/ErD,MAAMC,EAAaC,EAAQ,GACrBC,EAAUD,EAAQ,GAOlBE,EAAOD,EAAQ,CAACE,EAAGC,IAAMA,EAAEC,UAAUF,MACrCG,EAAcL,EAAQ,CAACE,EAAGC,KAC5B,MAAM,QAACG,GAAWH,GACZ,IAACI,GAAOD,EACRE,EAAWC,EAAYF,GAEzB,MAAMG,KAAKH,IAAQ,SAASG,KAAKF,IATP,QAYnBF,EAZQK,QACNC,IAAiB,UAAXA,EAAEC,KAchBC,CAAQR,KAGT,SAASI,KAAKF,IAGd,aAAaE,KAAKF,IAGtBL,EAAEE,YAAYH,EAAEC,OAGdM,EAAeF,GAAQ,IAAIQ,IAAIR,GAAKC,SAGpCQ,EAAQ,6EAMRC,EAAa,CAACL,EAAGN,IACT,MAANM,EACON,EANQM,IAAM,IAAIM,QAAQN,EAAG,CACxCO,YAAa,gBAONC,CAAc,KAGzBC,KAAKC,iBAAiB,UAAWrB,GAcjCsB,iBACIC,QAAQC,KAAM,0BAAyBT,SAEjCK,KAAKK,kBAhBfL,KAAKC,iBAAiB,QAASjB,GAmB/BkB,eAAuBI,GACnB,MAAM,QAACrB,GAAWqB,GACZ,IAACpB,GAAOD,EACRE,EAAWC,EAAYF,GACvBqB,EAAaX,EAAWT,EAAUmB,EAAMrB,SAExCuB,QAAcC,OAAOC,KAAKf,GAC1BgB,QAAiBH,EAAMI,MAAM3B,GAEnC,GAAc0B,EACV,OAAOA,EAEX,MAAO7B,EAAG+B,SAAcpC,EAAWqC,MAAOP,EAAY,CAClDT,YAAa,gBAGjB,OAAIhB,EACO,IAAIiC,SAASjC,EAAEkC,gBAO9Bd,eAA0BjB,EAAS0B,GAE/B,aADoBF,OAAOC,KAAKf,IACnBsB,IAAIhC,EAAS0B,GAPpBO,CAAWjC,EAAS4B,EAAKM,SAExBN,OAvCXb,KAAKC,iBAAiB,WAAYrB,GAElCsB,iBACIC,QAAQC,KAAM,2BAA0BT,SAElCK,KAAKoB,QAAQC,QACnB,MAAMC,QAAab,OAAOa,OACpBC,EAAcd,OAAOe,OAAOvD,KAAKwC,cAEjCgB,QAAQC,IAAIJ,EAAKK,IAAIJ,S,6BC5D/B/E,EAAOD,QAAU2D,MAAO0B,KAAOC,MAU/B,SAAeD,GACX,GAAkB,mBAAPA,EACP,MAAME,MAAM,4BAXhBC,CAAMH,GAEN,IACI,MAAO,CAAC,WAAYA,KAAMC,IAC5B,MAAM/C,GACJ,MAAO,CAACA,M,6BCNhB,MASMH,EAAU,CAACiD,KAAOC,KAGpB,GAeJ,SAAeD,GACX,GAAkB,mBAAPA,EACP,MAAME,MAAM,0BAnBhBC,CAAMH,GAEFC,EAAKG,QAAUJ,EAAGI,OAClB,OAAOJ,KAAMC,GAEjB,MAAMI,EAAQ,IAAIC,IACPvD,EAAQiD,KAAWC,KAASK,GAGjCC,EAAQP,EAAGI,OAASH,EAAKG,OAAS,EAGxC,MAtBM,CAACJ,GAAO,CAEd,SAAUrC,GAAI,OAAOqC,KAAMQ,YAC3B,SAAU7C,EAAG8C,GAAI,OAAOT,KAAMQ,YAC9B,SAAU7C,EAAG8C,EAAGvF,GAAI,OAAO8E,KAAMQ,YACjC,SAAU7C,EAAG8C,EAAGvF,EAAGC,GAAI,OAAO6E,KAAMQ,YACpC,SAAU7C,EAAG8C,EAAGvF,EAAGC,EAAG+B,GAAI,OAAO8C,KAAMQ,aAc1BvD,CAAEoD,GAAOE,IAEPF,GAGnBzF,EAAOD,QAAUoC","file":"sw.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/dist/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","'use strict';\n\nconst codegen = require('codegen.macro');\nconst tryToCatch = require('try-to-catch');\nconst currify = require('currify');\n\nconst isDev = process.env.NODE_ENV === 'development';\n\nconst isGet = (a) => a.method === 'GET';\nconst isBasic = (a) => a.type === 'basic';\n\nconst wait = currify((f, e) => e.waitUntil(f()));\nconst respondWith = currify((f, e) => {\n const {request} = e;\n const {url} = request;\n const pathname = getPathName(url);\n \n if (/\\/$/.test(url) || /\\^\\/fs/.test(pathname))\n return;\n \n if (!isGet(request))\n return;\n \n if (!isBasic(request))\n return;\n \n if (/^\\/api/.test(pathname))\n return;\n \n if (/^socket.io/.test(pathname))\n return;\n \n e.respondWith(f(e));\n});\n\nconst getPathName = (url) => new URL(url).pathname;\n\nconst date = codegen`module.exports = '\"' + Date() + '\"'`;\nconst NAME = `cloudcmd: ${date}`;\n\nconst createRequest = (a) => new Request(a, {\n credentials: 'same-origin',\n});\n\nconst getRequest = (a, request) => {\n if (a !== '/')\n return request;\n \n return createRequest('/');\n};\n\nself.addEventListener('install', wait(onInstall));\nself.addEventListener('fetch', respondWith(onFetch));\nself.addEventListener('activate', wait(onActivate));\n\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n \n await self.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n \n await Promise.all(keys.map(deleteCache));\n}\n\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n \n await self.skipWaiting();\n}\n\nasync function onFetch(event) {\n const {request} = event;\n const {url} = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n \n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n \n if (!isDev && response)\n return response;\n \n const [e, resp] = await tryToCatch(fetch, newRequest, {\n credentials: 'same-origin',\n });\n \n if (e)\n return new Response(e.message);\n \n await addToCache(request, resp.clone());\n \n return resp;\n}\n\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n","'use strict';\n\nmodule.exports = async (fn, ...args) => {\n check(fn);\n \n try {\n return [null, await fn(...args)];\n } catch(e) {\n return [e];\n }\n};\n\nfunction check(fn) {\n if (typeof fn !== 'function')\n throw Error('fn should be a function!');\n}\n\n","'use strict';\n\nconst f = (fn) => [\n /*eslint no-unused-vars: 0*/\n function (a) {return fn(...arguments);},\n function (a, b) {return fn(...arguments);},\n function (a, b, c) {return fn(...arguments);},\n function (a, b, c, d) {return fn(...arguments);},\n function (a, b, c, d, e) {return fn(...arguments);},\n];\n\nconst currify = (fn, ...args) => {\n check(fn);\n \n if (args.length >= fn.length)\n return fn(...args);\n \n const again = (...args2) => {\n return currify(fn, ...[...args, ...args2]);\n };\n \n const count = fn.length - args.length - 1;\n const func = f(again)[count];\n \n return func || again;\n};\n\nmodule.exports = currify;\n\nfunction check(fn) {\n if (typeof fn !== 'function')\n throw Error('fn should be function!');\n}\n\n"],"sourceRoot":""}
1
+ {"version":3,"sources":["file://cloudcmd/webpack/bootstrap","file://cloudcmd/client/sw/sw.js","file://cloudcmd/node_modules/try-to-catch/lib/try-to-catch.js","file://cloudcmd/node_modules/currify/lib/currify.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","tryToCatch","require","currify","wait","f","e","waitUntil","respondWith","request","url","pathname","getPathName","endsWith","test","method","a","type","isBasic","startsWith","URL","NAME","getRequest","Request","credentials","createRequest","self","addEventListener","async","console","info","skipWaiting","event","newRequest","cache","caches","open","response","match","resp","fetch","Response","message","put","addToCache","clone","clients","claim","keys","deleteCache","delete","Promise","all","map","fn","args","Error","check","length","again","args2","count","arguments","b"],"mappings":"aACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QAKfF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,SAIjBlC,EAAoBA,EAAoBmC,EAAI,G,+BC/ErD,MAAMC,EAAaC,EAAQ,GACrBC,EAAUD,EAAQ,GAOlBE,EAAOD,EAAQ,CAACE,EAAGC,IAAMA,EAAEC,UAAUF,MACrCG,EAAcL,EAAQ,CAACE,EAAGC,KAC5B,MAAM,QAACG,GAAWH,GACZ,IAACI,GAAOD,EACRE,EAAWC,EAAYF,GAEzBA,EAAIG,SAAS,MAAQ,SAASC,KAAKH,IATT,QAYnBF,EAZQM,QACNC,IAAiB,UAAXA,EAAEC,KAchBC,CAAQT,KAGTE,EAASQ,WAAW,SAGpB,aAAaL,KAAKH,IAGtBL,EAAEE,YAAYH,EAAEC,OAGdM,EAAeF,GAAQ,IAAIU,IAAIV,GAAKC,SAGpCU,EAAQ,6EAMRC,EAAa,CAACN,EAAGP,IACT,MAANO,EACOP,EANQO,IAAM,IAAIO,QAAQP,EAAG,CACxCQ,YAAa,gBAONC,CAAc,KAGzBC,KAAKC,iBAAiB,UAAWvB,GAcjCwB,iBACIC,QAAQC,KAAM,0BAAyBT,SAEjCK,KAAKK,kBAhBfL,KAAKC,iBAAiB,QAASnB,GAmB/BoB,eAAuBI,GACnB,MAAM,QAACvB,GAAWuB,GACZ,IAACtB,GAAOD,EACRE,EAAWC,EAAYF,GACvBuB,EAAaX,EAAWX,EAAUqB,EAAMvB,SAExCyB,QAAcC,OAAOC,KAAKf,GAC1BgB,QAAiBH,EAAMI,MAAM7B,GAEnC,GAAc4B,EACV,OAAOA,EAEX,MAAO/B,EAAGiC,SAActC,EAAWuC,MAAOP,EAAY,CAClDT,YAAa,gBAGjB,OAAIlB,EACO,IAAImC,SAASnC,EAAEoC,gBAO9Bd,eAA0BnB,EAAS4B,GAE/B,aADoBF,OAAOC,KAAKf,IACnBsB,IAAIlC,EAAS4B,GAPpBO,CAAWnC,EAAS8B,EAAKM,SAExBN,OAvCXb,KAAKC,iBAAiB,WAAYvB,GAElCwB,iBACIC,QAAQC,KAAM,2BAA0BT,SAElCK,KAAKoB,QAAQC,QACnB,MAAMC,QAAab,OAAOa,OACpBC,EAAcd,OAAOe,OAAOzD,KAAK0C,cAEjCgB,QAAQC,IAAIJ,EAAKK,IAAIJ,S,6BC5D/BjF,EAAOD,QAAU6D,MAAO0B,KAAOC,MAU/B,SAAeD,GACX,GAAkB,mBAAPA,EACP,MAAME,MAAM,4BAXhBC,CAAMH,GAEN,IACI,MAAO,CAAC,WAAYA,KAAMC,IAC5B,MAAMjD,GACJ,MAAO,CAACA,M,6BCNhB,MASMH,EAAU,CAACmD,KAAOC,KAGpB,GAeJ,SAAeD,GACX,GAAkB,mBAAPA,EACP,MAAME,MAAM,0BAnBhBC,CAAMH,GAEFC,EAAKG,QAAUJ,EAAGI,OAClB,OAAOJ,KAAMC,GAEjB,MAAMI,EAAQ,IAAIC,IACPzD,EAAQmD,KAAWC,KAASK,GAGjCC,EAAQP,EAAGI,OAASH,EAAKG,OAAS,EAGxC,MAtBM,CAACJ,GAAO,CAEd,SAAUtC,GAAI,OAAOsC,KAAMQ,YAC3B,SAAU9C,EAAG+C,GAAI,OAAOT,KAAMQ,YAC9B,SAAU9C,EAAG+C,EAAGzF,GAAI,OAAOgF,KAAMQ,YACjC,SAAU9C,EAAG+C,EAAGzF,EAAGC,GAAI,OAAO+E,KAAMQ,YACpC,SAAU9C,EAAG+C,EAAGzF,EAAGC,EAAG+B,GAAI,OAAOgD,KAAMQ,aAc1BzD,CAAEsD,GAAOE,IAEPF,GAGnB3F,EAAOD,QAAUoC","file":"sw.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/dist/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","'use strict';\n\nconst codegen = require('codegen.macro');\nconst tryToCatch = require('try-to-catch');\nconst currify = require('currify');\n\nconst isDev = process.env.NODE_ENV === 'development';\n\nconst isGet = (a) => a.method === 'GET';\nconst isBasic = (a) => a.type === 'basic';\n\nconst wait = currify((f, e) => e.waitUntil(f()));\nconst respondWith = currify((f, e) => {\n const {request} = e;\n const {url} = request;\n const pathname = getPathName(url);\n \n if (url.endsWith('/') || /\\^\\/fs/.test(pathname))\n return;\n \n if (!isGet(request))\n return;\n \n if (!isBasic(request))\n return;\n \n if (pathname.startsWith('/api'))\n return;\n \n if (/^socket.io/.test(pathname))\n return;\n \n e.respondWith(f(e));\n});\n\nconst getPathName = (url) => new URL(url).pathname;\n\nconst date = codegen`module.exports = '\"' + Date() + '\"'`;\nconst NAME = `cloudcmd: ${date}`;\n\nconst createRequest = (a) => new Request(a, {\n credentials: 'same-origin',\n});\n\nconst getRequest = (a, request) => {\n if (a !== '/')\n return request;\n \n return createRequest('/');\n};\n\nself.addEventListener('install', wait(onInstall));\nself.addEventListener('fetch', respondWith(onFetch));\nself.addEventListener('activate', wait(onActivate));\n\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n \n await self.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n \n await Promise.all(keys.map(deleteCache));\n}\n\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n \n await self.skipWaiting();\n}\n\nasync function onFetch(event) {\n const {request} = event;\n const {url} = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n \n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n \n if (!isDev && response)\n return response;\n \n const [e, resp] = await tryToCatch(fetch, newRequest, {\n credentials: 'same-origin',\n });\n \n if (e)\n return new Response(e.message);\n \n await addToCache(request, resp.clone());\n \n return resp;\n}\n\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n","'use strict';\n\nmodule.exports = async (fn, ...args) => {\n check(fn);\n \n try {\n return [null, await fn(...args)];\n } catch(e) {\n return [e];\n }\n};\n\nfunction check(fn) {\n if (typeof fn !== 'function')\n throw Error('fn should be a function!');\n}\n\n","'use strict';\n\nconst f = (fn) => [\n /*eslint no-unused-vars: 0*/\n function (a) {return fn(...arguments);},\n function (a, b) {return fn(...arguments);},\n function (a, b, c) {return fn(...arguments);},\n function (a, b, c, d) {return fn(...arguments);},\n function (a, b, c, d, e) {return fn(...arguments);},\n];\n\nconst currify = (fn, ...args) => {\n check(fn);\n \n if (args.length >= fn.length)\n return fn(...args);\n \n const again = (...args2) => {\n return currify(fn, ...[...args, ...args2]);\n };\n \n const count = fn.length - args.length - 1;\n const func = f(again)[count];\n \n return func || again;\n};\n\nmodule.exports = currify;\n\nfunction check(fn) {\n if (typeof fn !== 'function')\n throw Error('fn should be function!');\n}\n\n"],"sourceRoot":""}
@@ -80,7 +80,7 @@ eval("\n\nlet list = [];\n\nmodule.exports.add = (el, name, fn) => {\n list.pus
80
80
  /***/ (function(module, exports, __webpack_require__) {
81
81
 
82
82
  "use strict";
83
- eval("\n\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/lib/itype.js\");\n\nconst EventStore = __webpack_require__(/*! ./event-store */ \"./client/dom/events/event-store.js\");\n\nmodule.exports = new EventsProto();\n\nfunction EventsProto() {\n const Events = this;\n\n const getEventOptions = eventName => {\n if (eventName !== 'touchstart') return false;\n return {\n passive: true\n };\n };\n\n function parseArgs(eventName, element, listener, callback) {\n let isFunc;\n const args = [eventName, element, listener, callback];\n const EVENT_NAME = 1;\n const ELEMENT = 0;\n const type = itype(eventName);\n\n switch (type) {\n default:\n if (!/element$/.test(type)) throw Error('unknown eventName: ' + type);\n parseArgs(args[EVENT_NAME], args[ELEMENT], listener, callback);\n break;\n\n case 'string':\n isFunc = itype.function(element);\n\n if (isFunc) {\n listener = element;\n element = null;\n }\n\n if (!element) element = window;\n callback(element, [eventName, listener, getEventOptions(eventName)]);\n break;\n\n case 'array':\n for (const name of eventName) {\n parseArgs(name, element, listener, callback);\n }\n\n break;\n\n case 'object':\n for (const name of Object.keys(eventName)) {\n const eventListener = eventName[name];\n parseArgs(name, element, eventListener, callback);\n }\n\n break;\n }\n }\n /**\n * safe add event listener\n *\n * @param type\n * @param element {document by default}\n * @param listener\n */\n\n\n this.add = (type, element, listener) => {\n checkType(type);\n parseArgs(type, element, listener, (element, args) => {\n const [name, fn, options] = args;\n element.addEventListener(name, fn, options);\n EventStore.add(element, name, fn);\n });\n return Events;\n };\n /**\n * safe add event listener\n *\n * @param type\n * @param listener\n * @param element {document by default}\n */\n\n\n this.addOnce = (type, element, listener) => {\n const once = event => {\n Events.remove(type, element, once);\n listener(event);\n };\n\n if (!listener) {\n listener = element;\n element = null;\n }\n\n this.add(type, element, once);\n return Events;\n };\n /**\n * safe remove event listener\n *\n * @param type\n * @param listener\n * @param element {document by default}\n */\n\n\n this.remove = (type, element, listener) => {\n checkType(type);\n parseArgs(type, element, listener, (element, args) => {\n element.removeEventListener(...args);\n });\n return Events;\n };\n /**\n * remove all added event listeners\n *\n * @param listener\n */\n\n\n this.removeAll = () => {\n const events = EventStore.get();\n\n for (const [el, name, fn] of events) el.removeEventListener(name, fn);\n\n EventStore.clear();\n };\n /**\n * safe add event keydown listener\n *\n * @param listener\n */\n\n\n this.addKey = function () {\n const name = 'keydown';\n\n for (var _len = arguments.length, argsArr = new Array(_len), _key = 0; _key < _len; _key++) {\n argsArr[_key] = arguments[_key];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n /**\n * safe remove event click listener\n *\n * @param listener\n */\n\n\n this.rmKey = function () {\n const name = 'keydown';\n\n for (var _len2 = arguments.length, argsArr = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n argsArr[_key2] = arguments[_key2];\n }\n\n const args = [name, ...argsArr];\n return Events.remove(...args);\n };\n /**\n * safe add event click listener\n *\n * @param listener\n */\n\n\n this.addClick = function () {\n const name = 'click';\n\n for (var _len3 = arguments.length, argsArr = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n argsArr[_key3] = arguments[_key3];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n /**\n * safe remove event click listener\n *\n * @param listener\n */\n\n\n this.rmClick = function () {\n const name = 'click';\n\n for (var _len4 = arguments.length, argsArr = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n argsArr[_key4] = arguments[_key4];\n }\n\n const args = [name, ...argsArr];\n return Events.remove(...args);\n };\n\n this.addContextMenu = function () {\n const name = 'contextmenu';\n\n for (var _len5 = arguments.length, argsArr = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {\n argsArr[_key5] = arguments[_key5];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n /**\n * safe add event click listener\n *\n * @param listener\n */\n\n\n this.addError = function () {\n const name = 'error';\n\n for (var _len6 = arguments.length, argsArr = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {\n argsArr[_key6] = arguments[_key6];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n /**\n * safe add load click listener\n *\n * @param listener\n */\n\n\n this.addLoad = function () {\n const name = 'load';\n\n for (var _len7 = arguments.length, argsArr = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {\n argsArr[_key7] = arguments[_key7];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n\n function checkType(type) {\n if (!type) throw Error('type could not be empty!');\n }\n}\n\n//# sourceURL=file://cloudcmd/client/dom/events/index.js");
83
+ eval("\n\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/lib/itype.js\");\n\nconst EventStore = __webpack_require__(/*! ./event-store */ \"./client/dom/events/event-store.js\");\n\nmodule.exports = new EventsProto();\n\nfunction EventsProto() {\n const Events = this;\n\n const getEventOptions = eventName => {\n if (eventName !== 'touchstart') return false;\n return {\n passive: true\n };\n };\n\n function parseArgs(eventName, element, listener, callback) {\n let isFunc;\n const args = [eventName, element, listener, callback];\n const EVENT_NAME = 1;\n const ELEMENT = 0;\n const type = itype(eventName);\n\n switch (type) {\n default:\n if (!type.endsWith('element')) throw Error('unknown eventName: ' + type);\n parseArgs(args[EVENT_NAME], args[ELEMENT], listener, callback);\n break;\n\n case 'string':\n isFunc = itype.function(element);\n\n if (isFunc) {\n listener = element;\n element = null;\n }\n\n if (!element) element = window;\n callback(element, [eventName, listener, getEventOptions(eventName)]);\n break;\n\n case 'array':\n for (const name of eventName) {\n parseArgs(name, element, listener, callback);\n }\n\n break;\n\n case 'object':\n for (const name of Object.keys(eventName)) {\n const eventListener = eventName[name];\n parseArgs(name, element, eventListener, callback);\n }\n\n break;\n }\n }\n /**\n * safe add event listener\n *\n * @param type\n * @param element {document by default}\n * @param listener\n */\n\n\n this.add = (type, element, listener) => {\n checkType(type);\n parseArgs(type, element, listener, (element, args) => {\n const [name, fn, options] = args;\n element.addEventListener(name, fn, options);\n EventStore.add(element, name, fn);\n });\n return Events;\n };\n /**\n * safe add event listener\n *\n * @param type\n * @param listener\n * @param element {document by default}\n */\n\n\n this.addOnce = (type, element, listener) => {\n const once = event => {\n Events.remove(type, element, once);\n listener(event);\n };\n\n if (!listener) {\n listener = element;\n element = null;\n }\n\n this.add(type, element, once);\n return Events;\n };\n /**\n * safe remove event listener\n *\n * @param type\n * @param listener\n * @param element {document by default}\n */\n\n\n this.remove = (type, element, listener) => {\n checkType(type);\n parseArgs(type, element, listener, (element, args) => {\n element.removeEventListener(...args);\n });\n return Events;\n };\n /**\n * remove all added event listeners\n *\n * @param listener\n */\n\n\n this.removeAll = () => {\n const events = EventStore.get();\n\n for (const [el, name, fn] of events) el.removeEventListener(name, fn);\n\n EventStore.clear();\n };\n /**\n * safe add event keydown listener\n *\n * @param listener\n */\n\n\n this.addKey = function () {\n const name = 'keydown';\n\n for (var _len = arguments.length, argsArr = new Array(_len), _key = 0; _key < _len; _key++) {\n argsArr[_key] = arguments[_key];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n /**\n * safe remove event click listener\n *\n * @param listener\n */\n\n\n this.rmKey = function () {\n const name = 'keydown';\n\n for (var _len2 = arguments.length, argsArr = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n argsArr[_key2] = arguments[_key2];\n }\n\n const args = [name, ...argsArr];\n return Events.remove(...args);\n };\n /**\n * safe add event click listener\n *\n * @param listener\n */\n\n\n this.addClick = function () {\n const name = 'click';\n\n for (var _len3 = arguments.length, argsArr = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n argsArr[_key3] = arguments[_key3];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n /**\n * safe remove event click listener\n *\n * @param listener\n */\n\n\n this.rmClick = function () {\n const name = 'click';\n\n for (var _len4 = arguments.length, argsArr = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n argsArr[_key4] = arguments[_key4];\n }\n\n const args = [name, ...argsArr];\n return Events.remove(...args);\n };\n\n this.addContextMenu = function () {\n const name = 'contextmenu';\n\n for (var _len5 = arguments.length, argsArr = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {\n argsArr[_key5] = arguments[_key5];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n /**\n * safe add event click listener\n *\n * @param listener\n */\n\n\n this.addError = function () {\n const name = 'error';\n\n for (var _len6 = arguments.length, argsArr = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {\n argsArr[_key6] = arguments[_key6];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n /**\n * safe add load click listener\n *\n * @param listener\n */\n\n\n this.addLoad = function () {\n const name = 'load';\n\n for (var _len7 = arguments.length, argsArr = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {\n argsArr[_key7] = arguments[_key7];\n }\n\n const args = [name, ...argsArr];\n return Events.add(...args);\n };\n\n function checkType(type) {\n if (!type) throw Error('type could not be empty!');\n }\n}\n\n//# sourceURL=file://cloudcmd/client/dom/events/index.js");
84
84
 
85
85
  /***/ }),
86
86
 
@@ -92,7 +92,7 @@ eval("\n\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/
92
92
  /***/ (function(module, exports, __webpack_require__) {
93
93
 
94
94
  "use strict";
95
- eval("\n/* global CloudCmd */\n\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/lib/itype.js\");\n\nconst {\n promisify\n} = __webpack_require__(/*! es6-promisify */ \"./node_modules/es6-promisify/dist/promisify.mjs\");\n\nconst load = __webpack_require__(/*! ./load */ \"./client/dom/load.js\");\n\nconst RESTful = __webpack_require__(/*! ./rest */ \"./client/dom/rest.js\");\n\nconst Promises = {};\nconst FILES_JSON = 'config|modules';\nconst FILES_HTML = 'file|path|link|pathLink|media';\nconst FILES_HTML_ROOT = 'view/media-tmpl|config-tmpl|upload';\nconst DIR_HTML = '/tmpl/';\nconst DIR_HTML_FS = DIR_HTML + 'fs/';\nconst DIR_JSON = '/json/';\nconst timeout = getTimeoutOnce(2000);\nmodule.exports.get = getFile;\n\nfunction getFile(name) {\n const type = itype(name);\n check(name);\n if (type === 'string') return getModule(name);\n if (type === 'array') return Promise.all(name.map(getFile));\n}\n\nfunction check(name) {\n if (!name) throw Error('name could not be empty!');\n}\n\nfunction getModule(name) {\n const regExpHTML = new RegExp(FILES_HTML + '|' + FILES_HTML_ROOT);\n const regExpJSON = new RegExp(FILES_JSON);\n const isHTML = regExpHTML.test(name);\n const isJSON = regExpJSON.test(name);\n if (!isHTML && !isJSON) return showError(name);\n if (name === 'config') return getConfig();\n const path = getPath(name, isHTML, isJSON);\n return getSystemFile(path);\n}\n\nfunction getPath(name, isHTML, isJSON) {\n let path;\n const regExp = new RegExp(FILES_HTML_ROOT);\n const isRoot = regExp.test(name);\n\n if (isHTML) {\n if (isRoot) path = DIR_HTML + name.replace('-tmpl', '');else path = DIR_HTML_FS + name;\n path += '.hbs';\n } else if (isJSON) {\n path = DIR_JSON + name + '.json';\n }\n\n return path;\n}\n\nfunction showError(name) {\n const str = 'Wrong file name: ' + name;\n const error = Error(str);\n throw error;\n}\n\nconst getSystemFile = promisify((file, callback) => {\n const {\n prefix\n } = CloudCmd;\n if (!Promises[file]) Promises[file] = new Promise((success, error) => {\n const url = prefix + file;\n load.ajax({\n url,\n success,\n error\n });\n });\n Promises[file].then(data => {\n callback(null, data);\n }, error => {\n Promises[file] = null;\n callback(error);\n });\n});\n\nconst getConfig = async () => {\n let is;\n if (!Promises.config) Promises.config = () => {\n is = true;\n return RESTful.Config.read();\n };\n const [, data] = await Promises.config();\n if (data) is = false;\n timeout(() => {\n if (!is) Promises.config = null;\n });\n return data;\n};\n\nfunction getTimeoutOnce(time) {\n let is;\n return callback => {\n if (is) return;\n is = true;\n setTimeout(() => {\n is = false;\n callback();\n }, time);\n };\n}\n\n//# sourceURL=file://cloudcmd/client/dom/files.js");
95
+ eval("\n/* global CloudCmd */\n\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/lib/itype.js\");\n\nconst {\n promisify\n} = __webpack_require__(/*! es6-promisify */ \"./node_modules/es6-promisify/dist/promisify.mjs\");\n\nconst load = __webpack_require__(/*! ./load */ \"./client/dom/load.js\");\n\nconst RESTful = __webpack_require__(/*! ./rest */ \"./client/dom/rest.js\");\n\nconst Promises = {};\nconst FILES_JSON = 'config|modules';\nconst FILES_HTML = 'file|path|link|pathLink|media';\nconst FILES_HTML_ROOT = 'view/media-tmpl|config-tmpl|upload';\nconst DIR_HTML = '/tmpl/';\nconst DIR_HTML_FS = DIR_HTML + 'fs/';\nconst DIR_JSON = '/json/';\nconst timeout = getTimeoutOnce(2000);\nmodule.exports.get = getFile;\n\nfunction getFile(name) {\n const type = itype(name);\n check(name);\n if (type === 'string') return getModule(name);\n if (type === 'array') return Promise.all(name.map(getFile));\n}\n\nfunction check(name) {\n if (!name) throw Error('name could not be empty!');\n}\n\nfunction getModule(name) {\n const regExpHTML = RegExp(FILES_HTML + '|' + FILES_HTML_ROOT);\n const regExpJSON = RegExp(FILES_JSON);\n const isHTML = regExpHTML.test(name);\n const isJSON = regExpJSON.test(name);\n if (!isHTML && !isJSON) return showError(name);\n if (name === 'config') return getConfig();\n const path = getPath(name, isHTML, isJSON);\n return getSystemFile(path);\n}\n\nfunction getPath(name, isHTML, isJSON) {\n let path;\n const regExp = RegExp(FILES_HTML_ROOT);\n const isRoot = regExp.test(name);\n\n if (isHTML) {\n if (isRoot) path = DIR_HTML + name.replace('-tmpl', '');else path = DIR_HTML_FS + name;\n path += '.hbs';\n } else if (isJSON) {\n path = DIR_JSON + name + '.json';\n }\n\n return path;\n}\n\nfunction showError(name) {\n const str = 'Wrong file name: ' + name;\n const error = Error(str);\n throw error;\n}\n\nconst getSystemFile = promisify((file, callback) => {\n const {\n prefix\n } = CloudCmd;\n if (!Promises[file]) Promises[file] = new Promise((success, error) => {\n const url = prefix + file;\n load.ajax({\n url,\n success,\n error\n });\n });\n Promises[file].then(data => {\n callback(null, data);\n }, error => {\n Promises[file] = null;\n callback(error);\n });\n});\n\nconst getConfig = async () => {\n let is;\n if (!Promises.config) Promises.config = () => {\n is = true;\n return RESTful.Config.read();\n };\n const [, data] = await Promises.config();\n if (data) is = false;\n timeout(() => {\n if (!is) Promises.config = null;\n });\n return data;\n};\n\nfunction getTimeoutOnce(time) {\n let is;\n return callback => {\n if (is) return;\n is = true;\n setTimeout(() => {\n is = false;\n callback();\n }, time);\n };\n}\n\n//# sourceURL=file://cloudcmd/client/dom/files.js");
96
96
 
97
97
  /***/ }),
98
98
 
@@ -116,7 +116,7 @@ eval("/* global DOM */\n\n\nconst createElement = __webpack_require__(/*! @cloud
116
116
  /***/ (function(module, exports, __webpack_require__) {
117
117
 
118
118
  "use strict";
119
- eval("\n/* global CloudCmd */\n\nconst Util = __webpack_require__(/*! ../../common/util */ \"./common/util.js\");\n\nconst Images = __webpack_require__(/*! ./images */ \"./client/dom/images.js\");\n\nconst load = __webpack_require__(/*! ./load */ \"./client/dom/load.js\");\n\nconst Files = __webpack_require__(/*! ./files */ \"./client/dom/files.js\");\n\nconst RESTful = __webpack_require__(/*! ./rest */ \"./client/dom/rest.js\");\n\nconst IO = __webpack_require__(/*! ./io */ \"./client/dom/io/index.js\");\n\nconst Storage = __webpack_require__(/*! ./storage */ \"./client/dom/storage.js\");\n\nconst Dialog = __webpack_require__(/*! ./dialog */ \"./client/dom/dialog.js\");\n\nconst renameCurrent = __webpack_require__(/*! ./operations/rename-current */ \"./client/dom/operations/rename-current.js\");\n\nconst CurrentFile = __webpack_require__(/*! ./current-file */ \"./client/dom/current-file.js\");\n\nconst DOMTree = __webpack_require__(/*! ./dom-tree */ \"./client/dom/dom-tree.js\");\n\nconst Cmd = module.exports;\nconst DOM = { ...DOMTree,\n ...CurrentFile,\n ...Cmd\n};\nconst CurrentInfo = {};\nDOM.Images = Images;\nDOM.load = load;\nDOM.Files = Files;\nDOM.RESTful = RESTful;\nDOM.IO = IO;\nDOM.Storage = Storage;\nDOM.Dialog = Dialog;\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\");\n\nconst loadRemote = __webpack_require__(/*! ./load-remote */ \"./client/dom/load-remote.js\");\n\nconst selectByPattern = __webpack_require__(/*! ./select-by-pattern */ \"./client/dom/select-by-pattern.js\");\n\nconst SELECTED_FILE = 'selected-file';\nconst TabPanel = {\n 'js-left': null,\n 'js-right': null\n};\n\nmodule.exports.loadRemote = (name, options, callback) => {\n loadRemote(name, options, callback);\n return DOM;\n};\n\nmodule.exports.loadSocket = callback => {\n DOM.loadRemote('socket', {\n name: 'io'\n }, callback);\n return DOM;\n};\n/**\n * create new folder\n *\n */\n\n\nmodule.exports.promptNewDir = async function () {\n await promptNew('directory');\n};\n/**\n * create new file\n *\n * @typeName\n * @type\n */\n\n\nmodule.exports.promptNewFile = async () => {\n await promptNew('file');\n};\n\nasync function promptNew(typeName) {\n const {\n Dialog\n } = DOM;\n const dir = DOM.getCurrentDirPath();\n const msg = 'New ' + typeName || false;\n\n const getName = () => {\n const name = DOM.getCurrentName();\n if (name === '..') return '';\n return name;\n };\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 * get current direcotory name\n */\n\n\nmodule.exports.getCurrentDirName = () => {\n const href = DOM.getCurrentDirPath().replace(/\\/$/, '');\n const substr = href.substr(href, href.lastIndexOf('/'));\n const ret = href.replace(substr + '/', '') || '/';\n return ret;\n};\n/**\n * get current direcotory path\n */\n\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 * get not current direcotory path\n */\n\n\nmodule.exports.getNotCurrentDirPath = () => {\n const panel = DOM.getPanel({\n active: false\n });\n const path = DOM.getCurrentDirPath(panel);\n return path;\n};\n/**\n * unified way to get selected files\n *\n * @currentFile\n */\n\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 * unselect all files\n */\n\n\nmodule.exports.unselectFiles = files => {\n files = files || DOM.getSelectedFiles();\n Array.from(files).forEach(DOM.toggleSelectedFile);\n};\n/**\n * get all selected files or current when none selected\n *\n * @currentFile\n */\n\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};\n\nmodule.exports.getCurrentDate = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const date = DOM.getByDataName('js-date', current).textContent;\n return date;\n};\n/**\n * get size\n * @currentFile\n */\n\n\nmodule.exports.getCurrentSize = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n /* если это папка - возвращаем слово dir вместо размера*/\n\n const size = DOM.getByDataName('js-size', current).textContent.replace(/^<|>$/g, '');\n return size;\n};\n/**\n * get size\n * @currentFile\n */\n\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 * load hash\n * @callback\n * @currentFile\n */\n\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 * set size\n * @currentFile\n */\n\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 * @currentFile\n */\n\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 * @currentFile\n */\n\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 * unified way to get current file content\n *\n * @param currentFile\n */\n\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\n if (Info.name === '..') {\n Dialog.alert.noFiles();\n return [Error('No Files')];\n }\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 * 1024 * 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 * unified way to get RefreshButton\n */\n\n\nmodule.exports.getRefreshButton = function () {\n let panel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DOM.getPanel();\n return DOM.getByDataName('js-refresh', panel);\n};\n/**\n * select current file\n * @param currentFile\n */\n\n\nmodule.exports.selectFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n current.classList.add(SELECTED_FILE);\n return Cmd;\n};\n\nmodule.exports.unselectFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n current.classList.remove(SELECTED_FILE);\n return Cmd;\n};\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};\n\nmodule.exports.toggleAllSelectedFiles = () => {\n DOM.getAllFiles().map(DOM.toggleSelectedFile);\n return Cmd;\n};\n\nmodule.exports.selectAllFiles = () => {\n DOM.getAllFiles().map(DOM.selectFile);\n return Cmd;\n};\n\nmodule.exports.getAllFiles = () => {\n const panel = DOM.getPanel();\n const files = DOM.getFiles(panel);\n const name = DOM.getCurrentName(files[0]);\n\n const from = a => a === '..' ? 1 : 0;\n\n const i = from(name);\n return Array.from(files).slice(i);\n};\n/**\n * open dialog with expand selection\n */\n\n\nmodule.exports.expandSelection = () => {\n const msg = 'expand';\n const {\n files\n } = CurrentInfo;\n selectByPattern(msg, files);\n};\n/**\n * open dialog with shrink selection\n */\n\n\nmodule.exports.shrinkSelection = () => {\n const msg = 'shrink';\n const {\n files\n } = CurrentInfo;\n selectByPattern(msg, files);\n};\n/**\n * setting history wrapper\n */\n\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 * selected file check\n *\n * @param currentFile\n */\n\n\nmodule.exports.isSelected = selected => {\n if (!selected) return false;\n return DOM.isContainClass(selected, SELECTED_FILE);\n};\n/**\n * get link from current (or param) file\n *\n * @param currentFile - current file by default\n */\n\n\nmodule.exports.getCurrentLink = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const link = DOM.getByTag('a', current);\n return link[0];\n};\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 * check storage hash\n */\n\n\nmodule.exports.checkStorageHash = async name => {\n const nameHash = name + '-hash';\n if (typeof name !== 'string') 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 * save data to storage\n *\n * @param name\n * @param data\n * @param hash\n * @param callback\n */\n\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};\n\nmodule.exports.getFM = () => DOM.getPanel().parentElement;\n\nmodule.exports.getPanelPosition = panel => {\n panel = panel || DOM.getPanel();\n return panel.dataset.name.replace('js-', '');\n};\n/** function getting panel active, or passive\n * @param options = {active: true}\n */\n\n\nmodule.exports.getPanel = options => {\n let files;\n let panel;\n let isLeft;\n let dataName = 'js-';\n const current = DOM.getCurrentFile();\n\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 /* if {active : false} getting passive panel */\n\n\n if (options && !options.active) {\n dataName += isLeft ? 'right' : 'left';\n panel = DOM.getByDataName(dataName);\n }\n /* if two panels showed\n * then always work with passive\n * panel\n */\n\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};\n\nmodule.exports.getFiles = element => {\n const files = DOM.getByDataName('js-files', element);\n return files.children || [];\n};\n/**\n * shows panel right or left (or active)\n */\n\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 * hides panel right or left (or active)\n */\n\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 * remove child of element\n * @param pChild\n * @param element\n */\n\n\nmodule.exports.remove = (child, element) => {\n const parent = element || document.body;\n parent.removeChild(child);\n return DOM;\n};\n/**\n * remove current file from file table\n * @param current\n *\n */\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\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 * remove selected files from file table\n * @Selected\n */\n\n\nmodule.exports.deleteSelected = selected => {\n selected = selected || DOM.getSelectedFiles();\n if (!selected) return;\n selected.map(DOM.deleteCurrent);\n};\n/**\n * rename current file\n *\n * @currentFile\n */\n\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 */\n\nmodule.exports.scrollIntoViewIfNeeded = function (element) {\n let center = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n if (!element || !element.scrollIntoViewIfNeeded) return;\n element.scrollIntoViewIfNeeded(center);\n};\n/* scroll on one page */\n\n\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};\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\n if (name) {\n current = DOM.getCurrentByName(name, panel);\n if (current) files = current.parentElement;\n }\n\n if (!files || !files.parentElement) {\n current = DOM.getCurrentByName(name, panel);\n if (!current) [current] = filesPassive;\n }\n\n DOM.setCurrentFile(current, {\n history: true\n });\n CloudCmd.emit('active-dir', Info.dirPath);\n return DOM;\n};\n\nmodule.exports.getPackerExt = type => {\n if (type === 'zip') return '.zip';\n return '.tar.gz';\n};\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.loadDir({\n path\n });\n};\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\n const getPath = isDir => {\n if (isDir) return Info.path;\n return Info.dirPath;\n };\n\n const path = getPath(isDir);\n await CloudCmd.loadDir({\n path,\n panel,\n noCurrent\n });\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.loadDir({\n path,\n panel: panelPassive,\n noCurrent: true\n });\n await CloudCmd.loadDir({\n path: 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};\n\nmodule.exports.CurrentInfo = CurrentInfo;\n\nmodule.exports.updateCurrentInfo = currentFile => {\n const info = DOM.CurrentInfo;\n const current = currentFile || DOM.getCurrentFile();\n const files = current.parentElement;\n const panel = files.parentElement || DOM.getPanel();\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 = panel;\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");
119
+ eval("\n/* global CloudCmd */\n\nconst Util = __webpack_require__(/*! ../../common/util */ \"./common/util.js\");\n\nconst Images = __webpack_require__(/*! ./images */ \"./client/dom/images.js\");\n\nconst RESTful = __webpack_require__(/*! ./rest */ \"./client/dom/rest.js\");\n\nconst Storage = __webpack_require__(/*! ./storage */ \"./client/dom/storage.js\");\n\nconst renameCurrent = __webpack_require__(/*! ./operations/rename-current */ \"./client/dom/operations/rename-current.js\");\n\nconst CurrentFile = __webpack_require__(/*! ./current-file */ \"./client/dom/current-file.js\");\n\nconst DOMTree = __webpack_require__(/*! ./dom-tree */ \"./client/dom/dom-tree.js\");\n\nconst Cmd = module.exports;\nconst DOM = { ...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\");\n\nconst loadRemote = __webpack_require__(/*! ./load-remote */ \"./client/dom/load-remote.js\");\n\nconst selectByPattern = __webpack_require__(/*! ./select-by-pattern */ \"./client/dom/select-by-pattern.js\");\n\nconst SELECTED_FILE = 'selected-file';\nconst TabPanel = {\n 'js-left': null,\n 'js-right': null\n};\n\nmodule.exports.loadRemote = (name, options, callback) => {\n loadRemote(name, options, callback);\n return DOM;\n};\n\nmodule.exports.loadSocket = callback => {\n DOM.loadRemote('socket', {\n name: 'io'\n }, callback);\n return DOM;\n};\n/**\n * create new folder\n *\n */\n\n\nmodule.exports.promptNewDir = async function () {\n await promptNew('directory');\n};\n/**\n * create new file\n *\n * @typeName\n * @type\n */\n\n\nmodule.exports.promptNewFile = async () => {\n await promptNew('file');\n};\n\nasync function promptNew(typeName) {\n const {\n Dialog\n } = DOM;\n const dir = DOM.getCurrentDirPath();\n const msg = 'New ' + typeName || false;\n\n const getName = () => {\n const name = DOM.getCurrentName();\n if (name === '..') return '';\n return name;\n };\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 * get current direcotory name\n */\n\n\nmodule.exports.getCurrentDirName = () => {\n const href = DOM.getCurrentDirPath().replace(/\\/$/, '');\n const substr = href.substr(href, href.lastIndexOf('/'));\n const ret = href.replace(substr + '/', '') || '/';\n return ret;\n};\n/**\n * get current direcotory path\n */\n\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 * get not current direcotory path\n */\n\n\nmodule.exports.getNotCurrentDirPath = () => {\n const panel = DOM.getPanel({\n active: false\n });\n const path = DOM.getCurrentDirPath(panel);\n return path;\n};\n/**\n * unified way to get selected files\n *\n * @currentFile\n */\n\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 * unselect all files\n */\n\n\nmodule.exports.unselectFiles = files => {\n files = files || DOM.getSelectedFiles();\n Array.from(files).forEach(DOM.toggleSelectedFile);\n};\n/**\n * get all selected files or current when none selected\n *\n * @currentFile\n */\n\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};\n\nmodule.exports.getCurrentDate = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const date = DOM.getByDataName('js-date', current).textContent;\n return date;\n};\n/**\n * get size\n * @currentFile\n */\n\n\nmodule.exports.getCurrentSize = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n /* если это папка - возвращаем слово dir вместо размера*/\n\n const size = DOM.getByDataName('js-size', current).textContent.replace(/^<|>$/g, '');\n return size;\n};\n/**\n * get size\n * @currentFile\n */\n\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 * load hash\n * @callback\n * @currentFile\n */\n\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 * set size\n * @currentFile\n */\n\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 * @currentFile\n */\n\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 * @currentFile\n */\n\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 * unified way to get current file content\n *\n * @param currentFile\n */\n\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\n if (Info.name === '..') {\n Dialog.alert.noFiles();\n return [Error('No Files')];\n }\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 * unified way to get RefreshButton\n */\n\n\nmodule.exports.getRefreshButton = function () {\n let panel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DOM.getPanel();\n return DOM.getByDataName('js-refresh', panel);\n};\n/**\n * select current file\n * @param currentFile\n */\n\n\nmodule.exports.selectFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n current.classList.add(SELECTED_FILE);\n return Cmd;\n};\n\nmodule.exports.unselectFile = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n current.classList.remove(SELECTED_FILE);\n return Cmd;\n};\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};\n\nmodule.exports.toggleAllSelectedFiles = () => {\n DOM.getAllFiles().map(DOM.toggleSelectedFile);\n return Cmd;\n};\n\nmodule.exports.selectAllFiles = () => {\n DOM.getAllFiles().map(DOM.selectFile);\n return Cmd;\n};\n\nmodule.exports.getAllFiles = () => {\n const panel = DOM.getPanel();\n const files = DOM.getFiles(panel);\n const name = DOM.getCurrentName(files[0]);\n\n const from = a => a === '..' ? 1 : 0;\n\n const i = from(name);\n return Array.from(files).slice(i);\n};\n/**\n * open dialog with expand selection\n */\n\n\nmodule.exports.expandSelection = () => {\n const msg = 'expand';\n const {\n files\n } = CurrentInfo;\n selectByPattern(msg, files);\n};\n/**\n * open dialog with shrink selection\n */\n\n\nmodule.exports.shrinkSelection = () => {\n const msg = 'shrink';\n const {\n files\n } = CurrentInfo;\n selectByPattern(msg, files);\n};\n/**\n * setting history wrapper\n */\n\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 * selected file check\n *\n * @param currentFile\n */\n\n\nmodule.exports.isSelected = selected => {\n if (!selected) return false;\n return DOM.isContainClass(selected, SELECTED_FILE);\n};\n/**\n * get link from current (or param) file\n *\n * @param currentFile - current file by default\n */\n\n\nmodule.exports.getCurrentLink = currentFile => {\n const current = currentFile || DOM.getCurrentFile();\n const link = DOM.getByTag('a', current);\n return link[0];\n};\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 * check storage hash\n */\n\n\nmodule.exports.checkStorageHash = async name => {\n const nameHash = name + '-hash';\n if (typeof name !== 'string') 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 * save data to storage\n *\n * @param name\n * @param data\n * @param hash\n * @param callback\n */\n\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};\n\nmodule.exports.getFM = () => DOM.getPanel().parentElement;\n\nmodule.exports.getPanelPosition = panel => {\n panel = panel || DOM.getPanel();\n return panel.dataset.name.replace('js-', '');\n};\n/** function getting panel active, or passive\n * @param options = {active: true}\n */\n\n\nmodule.exports.getPanel = options => {\n let files;\n let panel;\n let isLeft;\n let dataName = 'js-';\n const current = DOM.getCurrentFile();\n\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 /* if {active : false} getting passive panel */\n\n\n if (options && !options.active) {\n dataName += isLeft ? 'right' : 'left';\n panel = DOM.getByDataName(dataName);\n }\n /* if two panels showed\n * then always work with passive\n * panel\n */\n\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};\n\nmodule.exports.getFiles = element => {\n const files = DOM.getByDataName('js-files', element);\n return files.children || [];\n};\n/**\n * shows panel right or left (or active)\n */\n\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 * hides panel right or left (or active)\n */\n\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 * remove child of element\n * @param pChild\n * @param element\n */\n\n\nmodule.exports.remove = (child, element) => {\n const parent = element || document.body;\n parent.removeChild(child);\n return DOM;\n};\n/**\n * remove current file from file table\n * @param current\n *\n */\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\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 * remove selected files from file table\n * @Selected\n */\n\n\nmodule.exports.deleteSelected = selected => {\n selected = selected || DOM.getSelectedFiles();\n if (!selected) return;\n selected.map(DOM.deleteCurrent);\n};\n/**\n * rename current file\n *\n * @currentFile\n */\n\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 */\n\nmodule.exports.scrollIntoViewIfNeeded = function (element) {\n let center = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n if (!element || !element.scrollIntoViewIfNeeded) return;\n element.scrollIntoViewIfNeeded(center);\n};\n/* scroll on one page */\n\n\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};\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\n if (name) {\n current = DOM.getCurrentByName(name, panel);\n if (current) files = current.parentElement;\n }\n\n if (!files || !files.parentElement) {\n current = DOM.getCurrentByName(name, panel);\n if (!current) [current] = filesPassive;\n }\n\n DOM.setCurrentFile(current, {\n history: true\n });\n CloudCmd.emit('active-dir', Info.dirPath);\n return DOM;\n};\n\nmodule.exports.getPackerExt = type => {\n if (type === 'zip') return '.zip';\n return '.tar.gz';\n};\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.loadDir({\n path\n });\n};\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\n const getPath = isDir => {\n if (isDir) return Info.path;\n return Info.dirPath;\n };\n\n const path = getPath(isDir);\n await CloudCmd.loadDir({\n path,\n panel,\n noCurrent\n });\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.loadDir({\n path,\n panel: panelPassive,\n noCurrent: true\n });\n await CloudCmd.loadDir({\n path: 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};\n\nmodule.exports.CurrentInfo = CurrentInfo;\n\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");
120
120
 
121
121
  /***/ }),
122
122
 
@@ -224,7 +224,7 @@ eval("\n\nconst {\n parse,\n stringify\n} = JSON;\n\nmodule.exports.set = asyn
224
224
  /***/ (function(module, exports, __webpack_require__) {
225
225
 
226
226
  "use strict";
227
- eval("\n/* global CloudCmd */\n\nconst {\n eachSeries\n} = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\n\nconst load = __webpack_require__(/*! ./load */ \"./client/dom/load.js\");\n\nconst Images = __webpack_require__(/*! ./images */ \"./client/dom/images.js\");\n\nconst {\n alert\n} = __webpack_require__(/*! ./dialog */ \"./client/dom/dialog.js\");\n\nconst {\n FS\n} = __webpack_require__(/*! ../../common/cloudfunc */ \"./common/cloudfunc.js\");\n\nconst onEnd = wraptile(_onEnd);\nconst loadFile = wraptile(_loadFile);\n\nconst {\n getCurrentDirPath: getPathWhenRootEmpty\n} = __webpack_require__(/*! . */ \"./client/dom/index.js\");\n\nmodule.exports = (dir, files) => {\n if (!files) {\n files = dir;\n dir = getPathWhenRootEmpty();\n }\n\n const n = files.length;\n if (!n) return;\n const array = Array.from(files);\n const {\n name\n } = files[0];\n eachSeries(array, loadFile(dir, n), onEnd(name));\n};\n\nfunction _onEnd(currentName) {\n CloudCmd.refresh({\n currentName\n });\n}\n\nfunction _loadFile(dir, n, file, callback) {\n let i = 0;\n const {\n name\n } = file;\n const path = dir + name;\n const {\n prefixURL\n } = CloudCmd;\n const api = prefixURL + FS;\n\n const percent = function (i, n) {\n let per = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100;\n return Math.round(i * per / n);\n };\n\n const step = n => 100 / n;\n\n ++i;\n load.put(api + path, file).on('error', showError).on('end', callback).on('progress', count => {\n const max = step(n);\n const value = (i - 1) * max + percent(count, 100, max);\n Images.show.load('top');\n Images.setProgress(Math.round(value));\n });\n}\n\nfunction showError(_ref) {\n let {\n message\n } = _ref;\n alert(message);\n}\n\n//# sourceURL=file://cloudcmd/client/dom/upload-files.js");
227
+ eval("\n/* global CloudCmd */\n\nconst {\n eachSeries\n} = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\n\nconst load = __webpack_require__(/*! ./load */ \"./client/dom/load.js\");\n\nconst Images = __webpack_require__(/*! ./images */ \"./client/dom/images.js\");\n\nconst {\n alert\n} = __webpack_require__(/*! ./dialog */ \"./client/dom/dialog.js\");\n\nconst {\n FS\n} = __webpack_require__(/*! ../../common/cloudfunc */ \"./common/cloudfunc.js\");\n\nconst {\n getCurrentDirPath: getPathWhenRootEmpty\n} = __webpack_require__(/*! . */ \"./client/dom/index.js\");\n\nconst loadFile = wraptile(_loadFile);\nconst onEnd = wraptile(_onEnd);\n\nmodule.exports = (dir, files) => {\n if (!files) {\n files = dir;\n dir = getPathWhenRootEmpty();\n }\n\n const n = files.length;\n if (!n) return;\n const array = Array.from(files);\n const {\n name\n } = files[0];\n eachSeries(array, loadFile(dir, n), onEnd(name));\n};\n\nfunction _onEnd(currentName) {\n CloudCmd.refresh({\n currentName\n });\n}\n\nfunction _loadFile(dir, n, file, callback) {\n let i = 0;\n const {\n name\n } = file;\n const path = dir + name;\n const {\n prefixURL\n } = CloudCmd;\n const api = prefixURL + FS;\n\n const percent = function (i, n) {\n let per = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100;\n return Math.round(i * per / n);\n };\n\n const step = n => 100 / n;\n\n ++i;\n load.put(api + path, file).on('error', showError).on('end', callback).on('progress', count => {\n const max = step(n);\n const value = (i - 1) * max + percent(count, 100, max);\n Images.show.load('top');\n Images.setProgress(Math.round(value));\n });\n}\n\nfunction showError(_ref) {\n let {\n message\n } = _ref;\n alert(message);\n}\n\n//# sourceURL=file://cloudcmd/client/dom/upload-files.js");
228
228
 
229
229
  /***/ }),
230
230
 
@@ -163,7 +163,7 @@
163
163
  /***/ (function(module, exports, __webpack_require__) {
164
164
 
165
165
  "use strict";
166
- eval("\n/* global DOM */\n\nconst Emitify = __webpack_require__(/*! emitify */ \"./node_modules/emitify/lib/emitify.js\");\n\nconst inherits = __webpack_require__(/*! inherits */ \"./node_modules/inherits/inherits_browser.js\");\n\nconst rendy = __webpack_require__(/*! rendy */ \"./node_modules/rendy/lib/rendy.js\");\n\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\n\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n\nconst {\n addSlashToEnd\n} = __webpack_require__(/*! format-io */ \"./node_modules/format-io/lib/format.js\");\n\nconst pascalCase = __webpack_require__(/*! just-pascal-case */ \"./node_modules/just-pascal-case/index.js\");\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\nconst isDev = \"development\" === 'development';\n\nconst Images = __webpack_require__(/*! ./dom/images */ \"./client/dom/images.js\");\n\nconst {\n unregisterSW\n} = __webpack_require__(/*! ./sw/register */ \"./client/sw/register.js\");\n\nconst getJsonFromFileTable = __webpack_require__(/*! ./get-json-from-file-table */ \"./client/get-json-from-file-table.js\");\n\nconst Key = __webpack_require__(/*! ./key */ \"./client/key/index.js\");\n\nconst noJS = a => a.replace(/.js$/, '');\n\nconst {\n apiURL,\n formatMsg,\n buildFromJSON\n} = __webpack_require__(/*! ../common/cloudfunc */ \"./common/cloudfunc.js\");\n\nconst loadModule = __webpack_require__(/*! ./load-module */ \"./client/load-module.js\");\n\ninherits(CloudCmdProto, Emitify);\nmodule.exports = new CloudCmdProto(DOM);\nload.addErrorListener((e, src) => {\n const msg = `file ${src} could not be loaded`;\n Images.show.error(msg);\n});\n\nfunction CloudCmdProto(DOM) {\n let Listeners;\n\n const log = function () {\n if (!isDev) return;\n console.log(...arguments);\n };\n\n Emitify.call(this);\n const CloudCmd = this;\n const Info = DOM.CurrentInfo;\n const {\n Storage,\n Files\n } = DOM;\n this.log = log;\n this.prefix = '';\n this.prefixSocket = '';\n this.prefixURL = '';\n this.DIRCLIENT = '/dist/';\n this.DIRCLIENT_MODULES = this.DIRCLIENT + 'modules/';\n this.MIN_ONE_PANEL_WIDTH = 1155;\n this.HOST = location.origin || location.protocol + '//' + location.host;\n const TITLE = 'Cloud Commander';\n this.TITLE = TITLE;\n this.sort = {\n left: 'name',\n right: 'name'\n };\n this.order = {\n left: 'asc',\n right: 'asc'\n };\n /**\n * Функция привязываеться ко всем ссылкам и\n * загружает содержимое каталогов\n *\n * @param params - {\n * paramLink - ссылка\n * needRefresh - необходимость обязательной загрузки данных с сервера\n * panel\n * }\n * @param callback\n */\n\n this.loadDir = async params => {\n const p = params;\n const refresh = p.isRefresh;\n const {\n panel,\n history = true,\n noCurrent,\n currentName\n } = p;\n let panelChanged;\n\n if (!noCurrent && panel && panel !== Info.panel) {\n DOM.changePanel();\n panelChanged = true;\n }\n\n let imgPosition;\n if (panelChanged || refresh || !history) imgPosition = 'top';\n Images.show.load(imgPosition, panel);\n const path = addSlashToEnd(p.path);\n /* загружаем содержимое каталога */\n\n await ajaxLoad(path, {\n refresh,\n history,\n noCurrent,\n currentName\n }, panel);\n };\n /**\n * Конструктор CloudClient, который\n * выполняет весь функционал по\n * инициализации\n */\n\n\n this.init = async (prefix, config) => {\n CloudCmd.prefix = prefix;\n CloudCmd.prefixURL = `${prefix}${apiURL}`;\n CloudCmd.prefixSocket = config.prefixSocket;\n\n CloudCmd.config = key => config[key];\n\n CloudCmd.config.if = currify((key, fn, a) => config[key] && fn(a));\n\n CloudCmd._config = (key, value) => {\n /*\n * should be called from config.js only\n * after successful update on server\n */\n if (key === 'password') return;\n config[key] = value;\n };\n\n if (config.oneFilePanel) CloudCmd.MIN_ONE_PANEL_WIDTH = Infinity;\n if (!document.body.scrollIntoViewIfNeeded) await load.js(prefix + CloudCmd.DIRCLIENT_MODULES + 'polyfill.js');\n await initModules();\n await baseInit();\n await loadStyle();\n CloudCmd.route(location.hash);\n };\n\n async function loadStyle() {\n const {\n prefix\n } = CloudCmd;\n const name = prefix + '/dist/cloudcmd.common.css';\n await load.css(name);\n }\n\n this.route = path => {\n const query = path.split('/');\n if (!path) return;\n const [kebabModule] = query;\n const module = noJS(pascalCase(kebabModule.slice(1)));\n const file = query[1];\n const current = DOM.getCurrentByName(file);\n\n if (file && !current) {\n const msg = formatMsg('set current file', file, 'error');\n CloudCmd.log(msg);\n return;\n }\n\n DOM.setCurrentFile(current);\n CloudCmd.execFromModule(module, 'show');\n };\n\n this.logOut = async () => {\n const url = CloudCmd.prefix + '/logout';\n\n const error = () => document.location.reload();\n\n const {\n prefix\n } = CloudCmd;\n await DOM.Storage.clear();\n unregisterSW(prefix);\n DOM.load.ajax({\n url,\n error\n });\n };\n\n const initModules = async () => {\n CloudCmd.Key = Key;\n CloudCmd.Key.bind();\n const [, modules] = await tryToCatch(Files.get, 'modules');\n const showLoad = Images.show.load;\n const doBefore = {\n edit: showLoad,\n menu: showLoad\n };\n\n const load = (name, path, dobefore) => {\n loadModule({\n name,\n path,\n dobefore\n });\n };\n\n if (!modules) return;\n\n for (const module of modules.local) {\n load(null, module, doBefore[module]);\n }\n };\n\n async function saveCurrentName(currentName) {\n await Storage.set('current-name', currentName);\n }\n\n async function baseInit() {\n const files = DOM.getFiles();\n CloudCmd.on('current-file', DOM.updateCurrentInfo);\n CloudCmd.on('current-name', saveCurrentName);\n const name = await Storage.get('current-name');\n const currentFile = name && DOM.getCurrentByName(name) || files[0];\n /* выделяем строку с первым файлом */\n\n if (files) DOM.setCurrentFile(currentFile, {\n // when hash is present\n // it should be handled with this.route\n // overwre otherwise\n history: !location.hash\n });\n const dirPath = DOM.getCurrentDirPath();\n Listeners = CloudCmd.Listeners;\n Listeners.init();\n const panels = getPanels();\n panels.forEach(Listeners.setOnPanel);\n Listeners.initKeysPanel();\n if (!CloudCmd.config('dirStorage')) return;\n const data = await Storage.get(dirPath);\n if (!data) await Storage.setJson(dirPath, getJsonFromFileTable());\n }\n\n function getPanels() {\n const panels = ['left'];\n if (CloudCmd.config('oneFilePanel')) return panels;\n return [...panels, 'right'];\n }\n\n this.execFromModule = async function (moduleName, funcName) {\n await CloudCmd[moduleName]();\n const func = CloudCmd[moduleName][funcName];\n\n for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n args[_key - 2] = arguments[_key];\n }\n\n func(...args);\n };\n\n this.refresh = async function () {\n let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const {\n panel = Info.panel,\n currentName\n } = options;\n const path = DOM.getCurrentDirPath(panel);\n const isRefresh = true;\n const history = false;\n const noCurrent = options ? options.noCurrent : false;\n await CloudCmd.loadDir({\n path,\n isRefresh,\n history,\n panel,\n noCurrent,\n currentName\n });\n };\n /**\n * Функция загружает json-данные о Файловой Системе\n * через ajax-запрос.\n * @param path - каталог для чтения\n * @param options\n * { refresh, history } - необходимость обновить данные о каталоге\n * @param panel\n * @param callback\n *\n */\n\n\n async function ajaxLoad(path) {\n let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let panel = arguments.length > 2 ? arguments[2] : undefined;\n const {\n RESTful\n } = DOM;\n CloudCmd.log('reading dir: \"' + path + '\";');\n const dirStorage = CloudCmd.config('dirStorage');\n const json = dirStorage && (await Storage.getJson(path));\n const name = options.currentName || Info.name;\n const {\n noCurrent,\n refresh\n } = options;\n if (!refresh && json) return await createFileTable(json, panel, options);\n const position = DOM.getPanelPosition(panel);\n const sort = CloudCmd.sort[position];\n const order = CloudCmd.order[position];\n const query = rendy('?sort={{ sort }}&order={{ order }}', {\n sort,\n order\n });\n const [, newObj] = await RESTful.read(path + query, 'json');\n if (!newObj) return; // that's OK, error handled by RESTful\n\n options.sort = sort;\n options.order = order;\n await createFileTable(newObj, panel, options);\n if (refresh && !noCurrent) DOM.setCurrentByName(name);\n if (!CloudCmd.config('dirStorage')) return;\n Storage.setJson(path, newObj);\n }\n /**\n * Функция строит файловую таблицу\n * @param json - данные о файлах\n * @param panelParam\n * @param history\n * @param callback\n */\n\n\n async function createFileTable(data, panelParam, options) {\n const {\n history,\n noCurrent\n } = options;\n const names = ['file', 'path', 'link', 'pathLink'];\n const [error, [file, path, link, pathLink]] = await tryToCatch(Files.get, names);\n if (error) return DOM.Dialog.alert(error.responseText);\n const panel = panelParam || DOM.getPanel();\n const {\n prefix\n } = CloudCmd;\n const {\n dir,\n name\n } = Info;\n const {\n childNodes\n } = panel;\n let i = childNodes.length;\n\n while (i--) panel.removeChild(panel.lastChild);\n\n panel.innerHTML = buildFromJSON({\n sort: options.sort,\n order: options.order,\n data,\n id: panel.id,\n prefix,\n template: {\n file,\n path,\n pathLink,\n link\n }\n });\n Listeners.setOnPanel(panel);\n\n if (!noCurrent) {\n let current;\n if (name === '..' && dir !== '/') current = DOM.getCurrentByName(dir);\n if (!current) [current] = DOM.getFiles(panel);\n DOM.setCurrentFile(current, {\n history\n });\n CloudCmd.emit('active-dir', Info.dirPath);\n }\n }\n\n this.goToParentDir = async () => {\n const {\n dir,\n dirPath,\n parentDirPath,\n panel\n } = Info;\n if (dirPath === parentDirPath) return;\n const path = parentDirPath;\n await CloudCmd.loadDir({\n path\n });\n const current = DOM.getCurrentByName(dir);\n const [first] = DOM.getFiles(panel);\n DOM.setCurrentFile(current || first, {\n history\n });\n };\n}\n\n//# sourceURL=file://cloudcmd/client/client.js");
166
+ eval("\n/* global DOM */\n\nconst Emitify = __webpack_require__(/*! emitify */ \"./node_modules/emitify/lib/emitify.js\");\n\nconst inherits = __webpack_require__(/*! inherits */ \"./node_modules/inherits/inherits_browser.js\");\n\nconst rendy = __webpack_require__(/*! rendy */ \"./node_modules/rendy/lib/rendy.js\");\n\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\n\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n\nconst {\n addSlashToEnd\n} = __webpack_require__(/*! format-io */ \"./node_modules/format-io/lib/format.js\");\n\nconst pascalCase = __webpack_require__(/*! just-pascal-case */ \"./node_modules/just-pascal-case/index.js\");\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\nconst Images = __webpack_require__(/*! ./dom/images */ \"./client/dom/images.js\");\n\nconst {\n unregisterSW\n} = __webpack_require__(/*! ./sw/register */ \"./client/sw/register.js\");\n\nconst getJsonFromFileTable = __webpack_require__(/*! ./get-json-from-file-table */ \"./client/get-json-from-file-table.js\");\n\nconst Key = __webpack_require__(/*! ./key */ \"./client/key/index.js\");\n\nconst {\n apiURL,\n formatMsg,\n buildFromJSON\n} = __webpack_require__(/*! ../common/cloudfunc */ \"./common/cloudfunc.js\");\n\nconst loadModule = __webpack_require__(/*! ./load-module */ \"./client/load-module.js\");\n\nconst noJS = a => a.replace(/.js$/, '');\n\nconst isDev = \"development\" === 'development';\ninherits(CloudCmdProto, Emitify);\nmodule.exports = new CloudCmdProto(DOM);\nload.addErrorListener((e, src) => {\n const msg = `file ${src} could not be loaded`;\n Images.show.error(msg);\n});\n\nfunction CloudCmdProto(DOM) {\n let Listeners;\n Emitify.call(this);\n const CloudCmd = this;\n const Info = DOM.CurrentInfo;\n const {\n Storage,\n Files\n } = DOM;\n\n this.log = function () {\n if (!isDev) return;\n console.log(...arguments);\n };\n\n this.prefix = '';\n this.prefixSocket = '';\n this.prefixURL = '';\n this.DIRCLIENT = '/dist/';\n this.DIRCLIENT_MODULES = this.DIRCLIENT + 'modules/';\n this.MIN_ONE_PANEL_WIDTH = 1155;\n this.HOST = location.origin || location.protocol + '//' + location.host;\n this.TITLE = 'Cloud Commander';\n this.sort = {\n left: 'name',\n right: 'name'\n };\n this.order = {\n left: 'asc',\n right: 'asc'\n };\n /**\n * Функция привязываеться ко всем ссылкам и\n * загружает содержимое каталогов\n *\n * @param params - {\n * paramLink - ссылка\n * needRefresh - необходимость обязательной загрузки данных с сервера\n * panel\n * }\n * @param callback\n */\n\n this.loadDir = async params => {\n const p = params;\n const refresh = p.isRefresh;\n const {\n panel,\n history = true,\n noCurrent,\n currentName\n } = p;\n let panelChanged;\n\n if (!noCurrent && panel && panel !== Info.panel) {\n DOM.changePanel();\n panelChanged = true;\n }\n\n let imgPosition;\n if (panelChanged || refresh || !history) imgPosition = 'top';\n Images.show.load(imgPosition, panel);\n const path = addSlashToEnd(p.path);\n /* загружаем содержимое каталога */\n\n await ajaxLoad(path, {\n refresh,\n history,\n noCurrent,\n currentName\n }, panel);\n };\n /**\n * Конструктор CloudClient, который\n * выполняет весь функционал по\n * инициализации\n */\n\n\n this.init = async (prefix, config) => {\n CloudCmd.prefix = prefix;\n CloudCmd.prefixURL = `${prefix}${apiURL}`;\n CloudCmd.prefixSocket = config.prefixSocket;\n\n CloudCmd.config = key => config[key];\n\n CloudCmd.config.if = currify((key, fn, a) => config[key] && fn(a));\n\n CloudCmd._config = (key, value) => {\n /*\n * should be called from config.js only\n * after successful update on server\n */\n if (key === 'password') return;\n config[key] = value;\n };\n\n if (config.oneFilePanel) CloudCmd.MIN_ONE_PANEL_WIDTH = Infinity;\n if (!document.body.scrollIntoViewIfNeeded) await load.js(prefix + CloudCmd.DIRCLIENT_MODULES + 'polyfill.js');\n await initModules();\n await baseInit();\n await loadStyle();\n CloudCmd.route(location.hash);\n };\n\n async function loadStyle() {\n const {\n prefix\n } = CloudCmd;\n const name = prefix + '/dist/cloudcmd.common.css';\n await load.css(name);\n }\n\n this.route = path => {\n const query = path.split('/');\n if (!path) return;\n const [kebabModule] = query;\n const module = noJS(pascalCase(kebabModule.slice(1)));\n const file = query[1];\n const current = DOM.getCurrentByName(file);\n\n if (file && !current) {\n const msg = formatMsg('set current file', file, 'error');\n CloudCmd.log(msg);\n return;\n }\n\n DOM.setCurrentFile(current);\n CloudCmd.execFromModule(module, 'show');\n };\n\n this.logOut = async () => {\n const url = CloudCmd.prefix + '/logout';\n\n const error = () => document.location.reload();\n\n const {\n prefix\n } = CloudCmd;\n await DOM.Storage.clear();\n unregisterSW(prefix);\n DOM.load.ajax({\n url,\n error\n });\n };\n\n const initModules = async () => {\n CloudCmd.Key = Key;\n CloudCmd.Key.bind();\n const [, modules] = await tryToCatch(Files.get, 'modules');\n const showLoad = Images.show.load;\n const doBefore = {\n edit: showLoad,\n menu: showLoad\n };\n\n const load = (name, path, dobefore) => {\n loadModule({\n name,\n path,\n dobefore\n });\n };\n\n if (!modules) return;\n\n for (const module of modules.local) {\n load(null, module, doBefore[module]);\n }\n };\n\n async function saveCurrentName(currentName) {\n await Storage.set('current-name', currentName);\n }\n\n async function baseInit() {\n const files = DOM.getFiles();\n CloudCmd.on('current-file', DOM.updateCurrentInfo);\n CloudCmd.on('current-name', saveCurrentName);\n const name = await Storage.get('current-name');\n const currentFile = name && DOM.getCurrentByName(name) || files[0];\n /* выделяем строку с первым файлом */\n\n if (files) DOM.setCurrentFile(currentFile, {\n // when hash is present\n // it should be handled with this.route\n // overwre otherwise\n history: !location.hash\n });\n const dirPath = DOM.getCurrentDirPath();\n Listeners = CloudCmd.Listeners;\n Listeners.init();\n const panels = getPanels();\n panels.forEach(Listeners.setOnPanel);\n Listeners.initKeysPanel();\n if (!CloudCmd.config('dirStorage')) return;\n const data = await Storage.get(dirPath);\n if (!data) await Storage.setJson(dirPath, getJsonFromFileTable());\n }\n\n function getPanels() {\n const panels = ['left'];\n if (CloudCmd.config('oneFilePanel')) return panels;\n return [...panels, 'right'];\n }\n\n this.execFromModule = async function (moduleName, funcName) {\n await CloudCmd[moduleName]();\n const func = CloudCmd[moduleName][funcName];\n\n for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n args[_key - 2] = arguments[_key];\n }\n\n func(...args);\n };\n\n this.refresh = async function () {\n let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const {\n panel = Info.panel,\n currentName\n } = options;\n const path = DOM.getCurrentDirPath(panel);\n const isRefresh = true;\n const history = false;\n const noCurrent = options ? options.noCurrent : false;\n await CloudCmd.loadDir({\n path,\n isRefresh,\n history,\n panel,\n noCurrent,\n currentName\n });\n };\n /**\n * Функция загружает json-данные о Файловой Системе\n * через ajax-запрос.\n * @param path - каталог для чтения\n * @param options\n * { refresh, history } - необходимость обновить данные о каталоге\n * @param panel\n * @param callback\n *\n */\n\n\n async function ajaxLoad(path) {\n let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let panel = arguments.length > 2 ? arguments[2] : undefined;\n const {\n RESTful\n } = DOM;\n CloudCmd.log('reading dir: \"' + path + '\";');\n const dirStorage = CloudCmd.config('dirStorage');\n const json = dirStorage && (await Storage.getJson(path));\n const name = options.currentName || Info.name;\n const {\n noCurrent,\n refresh\n } = options;\n if (!refresh && json) return await createFileTable(json, panel, options);\n const position = DOM.getPanelPosition(panel);\n const sort = CloudCmd.sort[position];\n const order = CloudCmd.order[position];\n const query = rendy('?sort={{ sort }}&order={{ order }}', {\n sort,\n order\n });\n const [, newObj] = await RESTful.read(path + query, 'json');\n if (!newObj) return; // that's OK, error handled by RESTful\n\n options.sort = sort;\n options.order = order;\n await createFileTable(newObj, panel, options);\n if (refresh && !noCurrent) DOM.setCurrentByName(name);\n if (!CloudCmd.config('dirStorage')) return;\n Storage.setJson(path, newObj);\n }\n /**\n * Функция строит файловую таблицу\n * @param json - данные о файлах\n * @param panelParam\n * @param history\n * @param callback\n */\n\n\n async function createFileTable(data, panelParam, options) {\n const {\n history,\n noCurrent\n } = options;\n const names = ['file', 'path', 'link', 'pathLink'];\n const [error, [file, path, link, pathLink]] = await tryToCatch(Files.get, names);\n if (error) return DOM.Dialog.alert(error.responseText);\n const panel = panelParam || DOM.getPanel();\n const {\n prefix\n } = CloudCmd;\n const {\n dir,\n name\n } = Info;\n const {\n childNodes\n } = panel;\n let i = childNodes.length;\n\n while (i--) panel.removeChild(panel.lastChild);\n\n panel.innerHTML = buildFromJSON({\n sort: options.sort,\n order: options.order,\n data,\n id: panel.id,\n prefix,\n template: {\n file,\n path,\n pathLink,\n link\n }\n });\n Listeners.setOnPanel(panel);\n\n if (!noCurrent) {\n let current;\n if (name === '..' && dir !== '/') current = DOM.getCurrentByName(dir);\n if (!current) [current] = DOM.getFiles(panel);\n DOM.setCurrentFile(current, {\n history\n });\n CloudCmd.emit('active-dir', Info.dirPath);\n }\n }\n\n this.goToParentDir = async () => {\n const {\n dir,\n dirPath,\n parentDirPath,\n panel\n } = Info;\n if (dirPath === parentDirPath) return;\n const path = parentDirPath;\n await CloudCmd.loadDir({\n path\n });\n const current = DOM.getCurrentByName(dir);\n const [first] = DOM.getFiles(panel);\n DOM.setCurrentFile(current || first, {\n history\n });\n };\n}\n\n//# sourceURL=file://cloudcmd/client/client.js");
167
167
 
168
168
  /***/ }),
169
169
 
@@ -175,7 +175,7 @@ eval("\n/* global DOM */\n\nconst Emitify = __webpack_require__(/*! emitify */ \
175
175
  /***/ (function(module, exports, __webpack_require__) {
176
176
 
177
177
  "use strict";
178
- eval("\n\n__webpack_require__(/*! ../css/main.css */ \"./css/main.css\");\n\n__webpack_require__(/*! ../css/nojs.css */ \"./css/nojs.css\");\n\n__webpack_require__(/*! ../css/columns/name-size-date.css */ \"./css/columns/name-size-date.css\");\n\n__webpack_require__(/*! ../css/columns/name-size.css */ \"./css/columns/name-size.css\");\n\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\n\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\n\nconst isDev = \"development\" === 'development';\n\nconst {\n registerSW,\n listenSW\n} = __webpack_require__(/*! ./sw/register */ \"./client/sw/register.js\"); // prevent additional loading of emitify\n\n\nwindow.Emitify = __webpack_require__(/*! emitify */ \"./node_modules/emitify/lib/emitify.js\");\n\nmodule.exports = window.CloudCmd = async config => {\n window.Util = __webpack_require__(/*! ../common/util */ \"./common/util.js\");\n window.CloudFunc = __webpack_require__(/*! ../common/cloudfunc */ \"./common/cloudfunc.js\");\n\n const DOM = __webpack_require__(/*! ./dom */ \"./client/dom/index.js\");\n\n window.DOM = DOM;\n window.CloudCmd = __webpack_require__(/*! ./client */ \"./client/client.js\");\n await register(config);\n\n __webpack_require__(/*! ./listeners */ \"./client/listeners/index.js\");\n\n __webpack_require__(/*! ./key */ \"./client/key/index.js\");\n\n __webpack_require__(/*! ./sort */ \"./client/sort.js\");\n\n const prefix = getPrefix(config.prefix);\n window.CloudCmd.init(prefix, config);\n};\n\nfunction getPrefix(prefix) {\n if (!prefix) return '';\n if (!prefix.indexOf('/')) return prefix;\n return `/${prefix}`;\n}\n\nconst onUpdateFound = wraptile(async config => {\n if (isDev) return;\n const {\n DOM\n } = window;\n const prefix = getPrefix(config.prefix);\n await load.js(`${prefix}/dist/cloudcmd.common.js`);\n await load.js(`${prefix}/dist/cloudcmd.js`);\n console.log('cloudcmd: sw: updated');\n DOM.Events.removeAll();\n window.CloudCmd(config);\n});\n\nasync function register(config) {\n const {\n prefix\n } = config;\n const sw = await registerSW(prefix);\n listenSW(sw, 'updatefound', onUpdateFound(config));\n}\n\n//# sourceURL=file://cloudcmd/client/cloudcmd.js");
178
+ eval("\n\n__webpack_require__(/*! ../css/main.css */ \"./css/main.css\");\n\n__webpack_require__(/*! ../css/nojs.css */ \"./css/nojs.css\");\n\n__webpack_require__(/*! ../css/columns/name-size-date.css */ \"./css/columns/name-size-date.css\");\n\n__webpack_require__(/*! ../css/columns/name-size.css */ \"./css/columns/name-size.css\");\n\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\n\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\n\nconst {\n registerSW,\n listenSW\n} = __webpack_require__(/*! ./sw/register */ \"./client/sw/register.js\");\n\nconst isDev = \"development\" === 'development'; // prevent additional loading of emitify\n\nwindow.Emitify = __webpack_require__(/*! emitify */ \"./node_modules/emitify/lib/emitify.js\");\n\nmodule.exports = window.CloudCmd = async config => {\n window.Util = __webpack_require__(/*! ../common/util */ \"./common/util.js\");\n window.CloudFunc = __webpack_require__(/*! ../common/cloudfunc */ \"./common/cloudfunc.js\");\n window.DOM = __webpack_require__(/*! ./dom */ \"./client/dom/index.js\");\n window.CloudCmd = __webpack_require__(/*! ./client */ \"./client/client.js\");\n await register(config);\n\n __webpack_require__(/*! ./listeners */ \"./client/listeners/index.js\");\n\n __webpack_require__(/*! ./key */ \"./client/key/index.js\");\n\n __webpack_require__(/*! ./sort */ \"./client/sort.js\");\n\n const prefix = getPrefix(config.prefix);\n window.CloudCmd.init(prefix, config);\n};\n\nfunction getPrefix(prefix) {\n if (!prefix) return '';\n if (!prefix.indexOf('/')) return prefix;\n return `/${prefix}`;\n}\n\nconst onUpdateFound = wraptile(async config => {\n if (isDev) return;\n const {\n DOM\n } = window;\n const prefix = getPrefix(config.prefix);\n await load.js(`${prefix}/dist/cloudcmd.common.js`);\n await load.js(`${prefix}/dist/cloudcmd.js`);\n console.log('cloudcmd: sw: updated');\n DOM.Events.removeAll();\n window.CloudCmd(config);\n});\n\nasync function register(config) {\n const {\n prefix\n } = config;\n const sw = await registerSW(prefix);\n listenSW(sw, 'updatefound', onUpdateFound(config));\n}\n\n//# sourceURL=file://cloudcmd/client/cloudcmd.js");
179
179
 
180
180
  /***/ }),
181
181
 
@@ -211,7 +211,7 @@ eval("\n\nmodule.exports.createBinder = () => {\n let binded = false;\n return
211
211
  /***/ (function(module, exports, __webpack_require__) {
212
212
 
213
213
  "use strict";
214
- eval("\n/* global CloudCmd, DOM */\n\nconst Info = DOM.CurrentInfo;\n\nconst clipboard = __webpack_require__(/*! @cloudcmd/clipboard */ \"./node_modules/@cloudcmd/clipboard/lib/clipboard.js\");\n\nconst Buffer = __webpack_require__(/*! ../dom/buffer */ \"./client/dom/buffer.js\");\n\nconst Events = __webpack_require__(/*! ../dom/events */ \"./client/dom/events/index.js\");\n\nconst KEY = __webpack_require__(/*! ./key */ \"./client/key/key.js\");\n\nconst vim = __webpack_require__(/*! ./vim */ \"./client/key/vim/index.js\");\n\nconst setCurrentByChar = __webpack_require__(/*! ./set-current-by-char */ \"./client/key/set-current-by-char.js\");\n\nconst {\n createBinder\n} = __webpack_require__(/*! ./binder */ \"./client/key/binder.js\");\n\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\n\nconst Chars = fullstore();\n\nconst toggleVim = keyCode => {\n const {\n _config,\n config\n } = CloudCmd;\n\n if (keyCode === KEY.ESC) {\n _config('vim', !config('vim'));\n }\n};\n\nconst isUndefined = a => typeof a === 'undefined';\n\nChars([]);\nconst {\n assign\n} = Object;\nconst binder = createBinder();\nmodule.exports = assign(binder, KEY);\n\nmodule.exports.bind = () => {\n Events.addKey(listener, true);\n binder.setBind();\n};\n\nmodule.exports._listener = listener;\n\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}\n\nasync function listener(event) {\n const {\n keyCode\n } = event; // strange chrome bug calles listener twice\n // in second time event misses a lot fields\n\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}\n\nfunction getSymbol(shift, keyCode) {\n switch (keyCode) {\n case KEY.DOT:\n return '.';\n\n case KEY.HYPHEN:\n return shift ? '_' : '-';\n\n case KEY.EQUAL:\n return shift ? '+' : '=';\n }\n\n return '';\n}\n\nfunction fromCharCode(keyIdentifier) {\n const code = keyIdentifier.substring(2);\n const hex = parseInt(code, 16);\n const char = String.fromCharCode(hex);\n return char;\n}\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 loadDir,\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\n if (current) {\n prev = current.previousSibling;\n next = current.nextSibling;\n }\n\n switch (keyCode) {\n case KEY.TAB:\n DOM.changePanel();\n event.preventDefault();\n break;\n\n case KEY.INSERT:\n DOM.toggleSelectedFile(current).setCurrentFile(next);\n break;\n\n case KEY.INSERT_MAC:\n DOM.toggleSelectedFile(current).setCurrentFile(next);\n break;\n\n case KEY.DELETE:\n if (shift) Operation.show('delete:silent');else Operation.show('delete');\n break;\n\n case KEY.ASTERISK:\n DOM.toggleAllSelectedFiles(current);\n break;\n\n case KEY.PLUS:\n DOM.expandSelection();\n event.preventDefault();\n break;\n\n case KEY.MINUS:\n DOM.shrinkSelection();\n event.preventDefault();\n break;\n\n case KEY.F1:\n CloudCmd.Help.show();\n event.preventDefault();\n break;\n\n case KEY.F2:\n CloudCmd.UserMenu.show();\n break;\n\n case KEY.F3:\n event.preventDefault();\n if (Info.isDir) await loadDir({\n path\n });else if (shift) CloudCmd.View.show(null, {\n raw: true\n });else if (ctrlMeta) CloudCmd.sortPanel('name');else CloudCmd.View.show();\n break;\n\n case KEY.F4:\n if (config('vim')) CloudCmd.EditFileVim.show();else CloudCmd.EditFile.show();\n event.preventDefault();\n break;\n\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\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\n case KEY.F7:\n if (shift) DOM.promptNewFile();else DOM.promptNewDir();\n event.preventDefault();\n break;\n\n case KEY.F8:\n Operation.show('delete');\n event.preventDefault();\n break;\n\n case KEY.F9:\n if (alt) Operation.show('extract');else CloudCmd.Menu.show();\n event.preventDefault();\n break;\n\n case KEY.F10:\n CloudCmd.Config.show();\n event.preventDefault();\n break;\n\n case KEY.TRA:\n event.preventDefault();\n if (shift) return CloudCmd.Terminal.show();\n CloudCmd.Konsole.show();\n break;\n\n case KEY.BRACKET_CLOSE:\n CloudCmd.Konsole.show();\n event.preventDefault();\n break;\n\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\n case KEY.U:\n if (ctrlMeta) {\n DOM.swapPanels();\n event.preventDefault();\n }\n\n break;\n\n /* navigation on file table: *\n * in case of pressing button 'up', *\n * select previous row */\n\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\n case KEY.DOWN:\n if (shift) DOM.toggleSelectedFile(current);\n DOM.setCurrentFile(next);\n event.preventDefault();\n break;\n\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\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\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\n case KEY.END:\n DOM.setCurrentFile(Info.last);\n event.preventDefault();\n break;\n\n /* если нажали клавишу page down проматываем экран */\n\n case KEY.PAGE_DOWN:\n DOM.scrollByPages(panel, 1);\n\n for (i = 0; i < 30; i++) {\n if (!current.nextSibling) break;\n current = current.nextSibling;\n }\n\n DOM.setCurrentFile(current);\n event.preventDefault();\n break;\n\n /* если нажали клавишу page up проматываем экран */\n\n case KEY.PAGE_UP:\n DOM.scrollByPages(panel, -1);\n\n for (i = 0; i < 30; i++) {\n if (!current.previousSibling) break;\n current = current.previousSibling;\n }\n\n DOM.setCurrentFile(current);\n event.preventDefault();\n break;\n\n case KEY.ENTER:\n if (Info.isDir) await loadDir({\n path\n });else CloudCmd.View.show();\n break;\n\n case KEY.BACKSPACE:\n CloudCmd.goToParentDir();\n event.preventDefault();\n break;\n\n case KEY.BACKSLASH:\n if (ctrlMeta) await loadDir({\n path: '/'\n });\n break;\n\n case KEY.A:\n if (ctrlMeta) {\n DOM.selectAllFiles();\n event.preventDefault();\n }\n\n break;\n\n case KEY.G:\n if (alt) {\n DOM.goToDirectory();\n event.preventDefault();\n }\n\n break;\n\n case KEY.M:\n if (ctrlMeta) {\n if (config('vim')) CloudCmd.EditNamesVim.show();else CloudCmd.EditNames.show();\n event.preventDefault();\n }\n\n break;\n\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\n case KEY.R:\n if (ctrlMeta) {\n CloudCmd.log('reloading page...\\n');\n CloudCmd.refresh();\n event.preventDefault();\n }\n\n break;\n\n case KEY.C:\n if (ctrlMeta) Buffer.copy();\n break;\n\n case KEY.X:\n if (ctrlMeta) Buffer.cut();\n break;\n\n case KEY.V:\n if (ctrlMeta) Buffer.paste();\n break;\n\n case KEY.Z:\n if (ctrlMeta) Buffer.clear();\n break;\n\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\n break;\n }\n}\n\n//# sourceURL=file://cloudcmd/client/key/index.js");
214
+ eval("\n/* global CloudCmd, DOM */\n\nconst clipboard = __webpack_require__(/*! @cloudcmd/clipboard */ \"./node_modules/@cloudcmd/clipboard/lib/clipboard.js\");\n\nconst Buffer = __webpack_require__(/*! ../dom/buffer */ \"./client/dom/buffer.js\");\n\nconst Events = __webpack_require__(/*! ../dom/events */ \"./client/dom/events/index.js\");\n\nconst KEY = __webpack_require__(/*! ./key */ \"./client/key/key.js\");\n\nconst vim = __webpack_require__(/*! ./vim */ \"./client/key/vim/index.js\");\n\nconst setCurrentByChar = __webpack_require__(/*! ./set-current-by-char */ \"./client/key/set-current-by-char.js\");\n\nconst {\n createBinder\n} = __webpack_require__(/*! ./binder */ \"./client/key/binder.js\");\n\nconst fullstore = __webpack_require__(/*! fullstore */ \"./node_modules/fullstore/lib/fullstore.js\");\n\nconst Info = DOM.CurrentInfo;\nconst Chars = fullstore();\n\nconst toggleVim = keyCode => {\n const {\n _config,\n config\n } = CloudCmd;\n\n if (keyCode === KEY.ESC) {\n _config('vim', !config('vim'));\n }\n};\n\nconst isUndefined = a => typeof a === 'undefined';\n\nChars([]);\nconst {\n assign\n} = Object;\nconst binder = createBinder();\nmodule.exports = assign(binder, KEY);\n\nmodule.exports.bind = () => {\n Events.addKey(listener, true);\n binder.setBind();\n};\n\nmodule.exports._listener = listener;\n\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}\n\nasync function listener(event) {\n const {\n keyCode\n } = event; // strange chrome bug calles listener twice\n // in second time event misses a lot fields\n\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}\n\nfunction getSymbol(shift, keyCode) {\n switch (keyCode) {\n case KEY.DOT:\n return '.';\n\n case KEY.HYPHEN:\n return shift ? '_' : '-';\n\n case KEY.EQUAL:\n return shift ? '+' : '=';\n }\n\n return '';\n}\n\nfunction fromCharCode(keyIdentifier) {\n const code = keyIdentifier.substring(2);\n const hex = parseInt(code, 16);\n const char = String.fromCharCode(hex);\n return char;\n}\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 loadDir,\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\n if (current) {\n prev = current.previousSibling;\n next = current.nextSibling;\n }\n\n switch (keyCode) {\n case KEY.TAB:\n DOM.changePanel();\n event.preventDefault();\n break;\n\n case KEY.INSERT:\n DOM.toggleSelectedFile(current).setCurrentFile(next);\n break;\n\n case KEY.INSERT_MAC:\n DOM.toggleSelectedFile(current).setCurrentFile(next);\n break;\n\n case KEY.DELETE:\n if (shift) Operation.show('delete:silent');else Operation.show('delete');\n break;\n\n case KEY.ASTERISK:\n DOM.toggleAllSelectedFiles(current);\n break;\n\n case KEY.PLUS:\n DOM.expandSelection();\n event.preventDefault();\n break;\n\n case KEY.MINUS:\n DOM.shrinkSelection();\n event.preventDefault();\n break;\n\n case KEY.F1:\n CloudCmd.Help.show();\n event.preventDefault();\n break;\n\n case KEY.F2:\n CloudCmd.UserMenu.show();\n break;\n\n case KEY.F3:\n event.preventDefault();\n if (Info.isDir) await loadDir({\n path\n });else if (shift) CloudCmd.View.show(null, {\n raw: true\n });else if (ctrlMeta) CloudCmd.sortPanel('name');else CloudCmd.View.show();\n break;\n\n case KEY.F4:\n if (config('vim')) CloudCmd.EditFileVim.show();else CloudCmd.EditFile.show();\n event.preventDefault();\n break;\n\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\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\n case KEY.F7:\n if (shift) DOM.promptNewFile();else DOM.promptNewDir();\n event.preventDefault();\n break;\n\n case KEY.F8:\n Operation.show('delete');\n event.preventDefault();\n break;\n\n case KEY.F9:\n if (alt) Operation.show('extract');else CloudCmd.Menu.show();\n event.preventDefault();\n break;\n\n case KEY.F10:\n CloudCmd.Config.show();\n event.preventDefault();\n break;\n\n case KEY.TRA:\n event.preventDefault();\n if (shift) return CloudCmd.Terminal.show();\n CloudCmd.Konsole.show();\n break;\n\n case KEY.BRACKET_CLOSE:\n CloudCmd.Konsole.show();\n event.preventDefault();\n break;\n\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\n case KEY.U:\n if (ctrlMeta) {\n DOM.swapPanels();\n event.preventDefault();\n }\n\n break;\n\n /* navigation on file table: *\n * in case of pressing button 'up', *\n * select previous row */\n\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\n case KEY.DOWN:\n if (shift) DOM.toggleSelectedFile(current);\n DOM.setCurrentFile(next);\n event.preventDefault();\n break;\n\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\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\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\n case KEY.END:\n DOM.setCurrentFile(Info.last);\n event.preventDefault();\n break;\n\n /* если нажали клавишу page down проматываем экран */\n\n case KEY.PAGE_DOWN:\n DOM.scrollByPages(panel, 1);\n\n for (i = 0; i < 30; i++) {\n if (!current.nextSibling) break;\n current = current.nextSibling;\n }\n\n DOM.setCurrentFile(current);\n event.preventDefault();\n break;\n\n /* если нажали клавишу page up проматываем экран */\n\n case KEY.PAGE_UP:\n DOM.scrollByPages(panel, -1);\n\n for (i = 0; i < 30; i++) {\n if (!current.previousSibling) break;\n current = current.previousSibling;\n }\n\n DOM.setCurrentFile(current);\n event.preventDefault();\n break;\n\n case KEY.ENTER:\n if (Info.isDir) await loadDir({\n path\n });else CloudCmd.View.show();\n break;\n\n case KEY.BACKSPACE:\n CloudCmd.goToParentDir();\n event.preventDefault();\n break;\n\n case KEY.BACKSLASH:\n if (ctrlMeta) await loadDir({\n path: '/'\n });\n break;\n\n case KEY.A:\n if (ctrlMeta) {\n DOM.selectAllFiles();\n event.preventDefault();\n }\n\n break;\n\n case KEY.G:\n if (alt) {\n DOM.goToDirectory();\n event.preventDefault();\n }\n\n break;\n\n case KEY.M:\n if (ctrlMeta) {\n if (config('vim')) CloudCmd.EditNamesVim.show();else CloudCmd.EditNames.show();\n event.preventDefault();\n }\n\n break;\n\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\n case KEY.R:\n if (ctrlMeta) {\n CloudCmd.log('reloading page...\\n');\n CloudCmd.refresh();\n event.preventDefault();\n }\n\n break;\n\n case KEY.C:\n if (ctrlMeta) Buffer.copy();\n break;\n\n case KEY.X:\n if (ctrlMeta) Buffer.cut();\n break;\n\n case KEY.V:\n if (ctrlMeta) Buffer.paste();\n break;\n\n case KEY.Z:\n if (ctrlMeta) Buffer.clear();\n break;\n\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\n break;\n }\n}\n\n//# sourceURL=file://cloudcmd/client/key/index.js");
215
215
 
216
216
  /***/ }),
217
217
 
@@ -223,7 +223,7 @@ eval("\n/* global CloudCmd, DOM */\n\nconst Info = DOM.CurrentInfo;\n\nconst cli
223
223
  /***/ (function(module, exports, __webpack_require__) {
224
224
 
225
225
  "use strict";
226
- eval("/* global DOM */\n\n\nconst Info = DOM.CurrentInfo;\n\nconst {\n escapeRegExp\n} = __webpack_require__(/*! ../../common/util */ \"./common/util.js\");\n\nmodule.exports = function setCurrentByChar(char, charStore) {\n let firstByName;\n let skipCount = 0;\n let setted = false;\n let i = 0;\n const escapeChar = escapeRegExp(char);\n const regExp = new RegExp('^' + escapeChar + '.*$', 'i');\n const {\n files\n } = Info;\n const chars = charStore();\n const n = chars.length;\n\n while (i < n && char === chars[i]) i++;\n\n if (!i) charStore([]);\n const skipN = skipCount = i;\n charStore(charStore().concat(char));\n const names = DOM.getFilenames(files);\n\n const isTest = a => regExp.test(a);\n\n const isRoot = a => a === '..';\n\n const not = f => a => !f(a);\n\n const setCurrent = name => {\n const byName = DOM.getCurrentByName(name);\n\n if (!skipCount) {\n setted = true;\n DOM.setCurrentFile(byName);\n return true;\n }\n\n if (skipN === skipCount) firstByName = byName;\n --skipCount;\n };\n\n names.filter(isTest).filter(not(isRoot)).some(setCurrent);\n\n if (!setted) {\n DOM.setCurrentFile(firstByName);\n charStore([char]);\n }\n};\n\n//# sourceURL=file://cloudcmd/client/key/set-current-by-char.js");
226
+ eval("/* global DOM */\n\n\nconst {\n escapeRegExp\n} = __webpack_require__(/*! ../../common/util */ \"./common/util.js\");\n\nconst Info = DOM.CurrentInfo;\n\nmodule.exports = function setCurrentByChar(char, charStore) {\n let firstByName;\n let skipCount = 0;\n let setted = false;\n let i = 0;\n const escapeChar = escapeRegExp(char);\n const regExp = new RegExp('^' + escapeChar + '.*$', 'i');\n const {\n files\n } = Info;\n const chars = charStore();\n const n = chars.length;\n\n while (i < n && char === chars[i]) i++;\n\n if (!i) charStore([]);\n const skipN = skipCount = i;\n charStore(charStore().concat(char));\n const names = DOM.getFilenames(files);\n\n const isTest = a => regExp.test(a);\n\n const isRoot = a => a === '..';\n\n const not = f => a => !f(a);\n\n const setCurrent = name => {\n const byName = DOM.getCurrentByName(name);\n\n if (!skipCount) {\n setted = true;\n DOM.setCurrentFile(byName);\n return true;\n }\n\n if (skipN === skipCount) firstByName = byName;\n --skipCount;\n };\n\n names.filter(isTest).filter(not(isRoot)).some(setCurrent);\n\n if (!setted) {\n DOM.setCurrentFile(firstByName);\n charStore([char]);\n }\n};\n\n//# sourceURL=file://cloudcmd/client/key/set-current-by-char.js");
227
227
 
228
228
  /***/ }),
229
229
 
@@ -295,7 +295,7 @@ eval("\n\nmodule.exports = (indexFrom, indexTo, files) => {\n if (indexFrom < i
295
295
  /***/ (function(module, exports, __webpack_require__) {
296
296
 
297
297
  "use strict";
298
- eval("/* global DOM, CloudCmd */\n\n\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/lib/itype.js\");\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n\nconst clipboard = __webpack_require__(/*! @cloudcmd/clipboard */ \"./node_modules/@cloudcmd/clipboard/lib/clipboard.js\");\n\nconst getRange = __webpack_require__(/*! ./get-range */ \"./client/listeners/get-range.js\");\n\nconst getIndex = currify(__webpack_require__(/*! ./get-index */ \"./client/listeners/get-index.js\"));\n\nconst uploadFiles = __webpack_require__(/*! ../dom/upload-files */ \"./client/dom/upload-files.js\");\n\nconst {\n FS\n} = __webpack_require__(/*! ../../common/cloudfunc */ \"./common/cloudfunc.js\");\n\nconst NBSP_REG = RegExp(String.fromCharCode(160), 'g');\nconst SPACE = ' ';\n\nmodule.exports.init = async () => {\n await Promise.all([contextMenu(), dragndrop(), unload(), pop(), resize(), header(), config()]);\n};\n\nCloudCmd.Listeners = module.exports;\n\nconst unselect = event => {\n const isMac = /Mac/.test(window.navigator.platform);\n const {\n shiftKey,\n metaKey,\n ctrlKey\n } = event;\n if (shiftKey || isMac && metaKey || ctrlKey) return;\n DOM.unselectFiles();\n};\n\nconst execAll = currify((funcs, event) => {\n for (const fn of funcs) fn(event);\n});\nconst Info = DOM.CurrentInfo;\nconst {\n Events\n} = DOM;\nconst EventsFiles = {\n mousedown: exec.with(execIfNotUL, setCurrentFileByEvent),\n click: execAll([onClick, unselect]),\n dragstart: exec.with(execIfNotUL, onDragStart),\n dblclick: exec.with(execIfNotUL, onDblClick),\n touchstart: exec.with(execIfNotUL, onTouch)\n};\nlet EXT;\n\nfunction header() {\n const fm = DOM.getFM();\n\n const isDataset = el => el.dataset;\n\n const isPanel = el => {\n return /^js-(left|right)$/.test(el.dataset.name);\n };\n\n Events.addClick(fm, event => {\n const el = event.target;\n const parent = el.parentElement;\n if (parent.dataset.name !== 'js-fm-header') return;\n const name = (el.dataset.name || '').replace('js-', '');\n if (!/^(name|size|date)$/.test(name)) return;\n const panel = getPath(el).filter(isDataset).filter(isPanel).pop();\n CloudCmd.sortPanel(name, panel);\n });\n}\n\nfunction getPath(el) {\n let path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n if (!el) return path;\n return getPath(el.parentElement, path.concat(el));\n}\n\nasync function config() {\n const [, config] = await tryToCatch(DOM.Files.get, 'config');\n const type = config === null || config === void 0 ? void 0 : config.packer;\n EXT = DOM.getPackerExt(type);\n}\n\nmodule.exports.initKeysPanel = () => {\n const keysElement = DOM.getById('js-keyspanel');\n if (!keysElement) return;\n Events.addClick(keysElement, _ref => {\n let {\n target\n } = _ref;\n const {\n id\n } = target;\n\n const operation = name => {\n const {\n Operation\n } = CloudCmd;\n const fn = Operation.show.bind(null, name);\n return fn;\n };\n\n const clickFuncs = {\n 'f1': CloudCmd.Help.show,\n 'f2': CloudCmd.UserMenu.show,\n 'f3': CloudCmd.View.show,\n 'f4': CloudCmd.EditFile.show,\n 'f5': operation('copy'),\n 'f6': operation('move'),\n 'f7': DOM.promptNewDir,\n 'f8': operation('delete'),\n 'f9': CloudCmd.Menu.show,\n 'f10': CloudCmd.Config.show,\n '~': CloudCmd.Konsole.show,\n 'shift~': CloudCmd.Terminal.show,\n 'contact': CloudCmd.Contact.show\n };\n exec(clickFuncs[id]);\n });\n};\n\nconst getPanel = side => {\n if (!itype.string(side)) return side;\n return DOM.getByDataName('js-' + side);\n};\n\nmodule.exports.setOnPanel = side => {\n const panel = getPanel(side);\n const filesElement = DOM.getByDataName('js-files', panel);\n const pathElement = DOM.getByDataName('js-path', panel);\n /* ставим загрузку гифа на клик*/\n\n Events.addClick(pathElement, getPathListener(panel));\n Events.add(filesElement, EventsFiles);\n};\n\nfunction getPathListener(panel) {\n return onPathElementClick.bind(null, panel);\n}\n\nfunction isNoCurrent(panel) {\n const infoPanel = Info.panel;\n if (!infoPanel) return true;\n const namePanel = panel.getAttribute('data-name');\n const nameInfoPanel = infoPanel.getAttribute('data-name');\n return namePanel !== nameInfoPanel;\n}\n\nfunction decodePath(path) {\n const url = CloudCmd.HOST;\n const {\n prefix\n } = CloudCmd;\n const prefixReg = RegExp('^' + prefix + FS);\n return decodeURI(path).replace(url, '').replace(prefixReg, '') // browser doesn't replace % -> %25% do it for him\n .replace('%%', '%25%').replace(NBSP_REG, SPACE) || '/';\n}\n\nasync function onPathElementClick(panel, event) {\n event.preventDefault();\n const element = event.target;\n const attr = element.getAttribute('data-name');\n const noCurrent = isNoCurrent(panel);\n if (attr === 'js-copy-path') return copyPath(element);\n if (attr === 'js-refresh') return CloudCmd.refresh({\n panel,\n noCurrent\n });\n if (attr !== 'js-path-link') return;\n const {\n href\n } = element;\n const path = decodePath(href);\n await CloudCmd.loadDir({\n path,\n isRefresh: false,\n panel: noCurrent ? panel : Info.panel\n });\n}\n\nfunction copyPath(el) {\n clipboard.writeText(el.parentElement.title).then(CloudCmd.log).catch(CloudCmd.log);\n}\n\nfunction execIfNotUL(callback, event) {\n const {\n target\n } = event;\n const {\n tagName\n } = target;\n if (tagName !== 'UL') callback(event);\n}\n\nfunction onClick(event) {\n event.preventDefault();\n changePanel(event.target);\n}\n\nfunction toggleSelect(key, files) {\n const isMac = /Mac/.test(window.navigator.platform);\n if (!key) throw Error('key should not be undefined!');\n const [file] = files;\n if (isMac && key.meta || key.ctrl) return DOM.toggleSelectedFile(file);\n if (key.shift) return files.map(DOM.selectFile);\n}\n\nfunction changePanel(element) {\n const {\n panel\n } = Info;\n const files = DOM.getByDataName('js-files', panel);\n const ul = getULElement(element);\n if (ul !== files) DOM.changePanel();\n}\n\nasync function onDblClick(event) {\n event.preventDefault();\n const current = getLIElement(event.target);\n const isDir = DOM.isCurrentIsDir(current);\n const path = DOM.getCurrentPath(current);\n if (!isDir) return CloudCmd.View.show();\n await CloudCmd.loadDir({\n path\n });\n}\n\nasync function onTouch(event) {\n const current = getLIElement(event.target);\n const isDir = DOM.isCurrentIsDir(current);\n if (!isDir) return;\n const isCurrent = DOM.isCurrentFile(current);\n if (!isCurrent) return;\n await CloudCmd.loadDir({\n path: DOM.getCurrentPath(current)\n });\n}\n/*\n * download file from browser to desktop\n * in Chrome (HTML5)\n */\n\n\nfunction onDragStart(event) {\n const {\n prefixURL\n } = CloudCmd;\n const element = getLIElement(event.target);\n const {\n isDir\n } = Info;\n let link = DOM.getCurrentLink(element);\n let name = DOM.getCurrentName(element);\n /* if it's directory - adding json extension */\n\n if (isDir) {\n name += EXT;\n link = document.createElement('a');\n link.textContent = name;\n link.href = prefixURL + '/pack' + Info.path + EXT;\n }\n\n event.dataTransfer.setData('DownloadURL', 'application/octet-stream' + ':' + name + ':' + link);\n}\n\nfunction getLIElement(element) {\n if (!element) return element;\n\n while (element.tagName !== 'LI') element = element.parentElement;\n\n return element;\n}\n\nfunction getULElement(element) {\n while (element.tagName !== 'UL') element = element.parentElement;\n\n return element;\n}\n\nfunction setCurrentFileByEvent(event) {\n const BUTTON_LEFT = 0;\n const key = {\n alt: event.altKey,\n ctrl: event.ctrlKey,\n meta: event.metaKey,\n shift: event.shiftKey\n };\n const element = getLIElement(event.target);\n const fromName = Info.name;\n DOM.setCurrentFile(element);\n const toName = Info.name;\n let files = [];\n if (key.shift) files = getFilesRange(fromName, toName);else files.push(Info.element);\n if (event.button === BUTTON_LEFT) toggleSelect(key, files);\n}\n\nfunction getFilesRange(from, to) {\n const files = DOM.getAllFiles();\n const names = DOM.getFilenames(files);\n const getNameIndex = getIndex(names);\n const indexFrom = getNameIndex(from);\n const indexTo = getNameIndex(to);\n return getRange(indexFrom, indexTo, files);\n}\n\nfunction contextMenu() {\n const fm = DOM.getFM();\n Events.addOnce('contextmenu', fm, event => {\n CloudCmd.Menu.show({\n x: event.clientX,\n y: event.clientY\n });\n });\n Events.addContextMenu(fm, event => {\n CloudCmd.Menu.ENABLED || event.preventDefault();\n });\n}\n\nfunction dragndrop() {\n const panels = DOM.getByClassAll('panel');\n\n const select = _ref2 => {\n let {\n target\n } = _ref2;\n target.classList.add('selected-panel');\n };\n\n const unselect = _ref3 => {\n let {\n target\n } = _ref3;\n target.classList.remove('selected-panel');\n };\n\n const onDrop = event => {\n const {\n files,\n items\n } = event.dataTransfer;\n const {\n length: filesCount\n } = files;\n event.preventDefault();\n if (filesCount && (!items || !items.length || !items[0].webkitGetAsEntry)) return uploadFiles(files);\n\n const isFile = item => item.kind === 'file';\n\n const dirFiles = Array.from(items).filter(isFile);\n if (dirFiles.length) return DOM.uploadDirectory(dirFiles);\n const {\n Operation\n } = CloudCmd;\n const operation = event.shiftKey ? 'move' : 'copy';\n return Operation.show(operation);\n };\n /**\n * In Mac OS Chrome dropEffect = 'none'\n * so drop do not firing up when try\n * to upload file from download bar\n */\n\n\n const onDragOver = event => {\n const {\n dataTransfer\n } = event;\n const {\n effectAllowed\n } = dataTransfer;\n if (/move|linkMove/.test(effectAllowed)) dataTransfer.dropEffect = 'move';else dataTransfer.dropEffect = 'copy';\n event.preventDefault();\n };\n\n for (const panel of panels) Events.add('dragover', panel, onDragOver).add('drop', panel, onDrop).add('dragenter', select).add(['dragleave', 'drop'], unselect);\n}\n\nfunction unload() {\n DOM.Events.add(['unload', 'beforeunload'], event => {\n const {\n Key\n } = CloudCmd;\n const isBind = Key === null || Key === void 0 ? void 0 : Key.isBind();\n if (isBind) return;\n event.preventDefault();\n return 'Please make sure that you saved all work.';\n });\n}\n\nfunction pop() {\n Events.add('popstate', async _ref4 => {\n let {\n state\n } = _ref4;\n const path = (state || '').replace(FS, '');\n if (!path) return CloudCmd.route(location.hash);\n const history = false;\n await CloudCmd.loadDir({\n path,\n history\n });\n });\n}\n\nfunction resize() {\n Events.add('resize', () => {\n const is = window.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH;\n if (!is) return;\n const {\n panel\n } = Info;\n const isEmptyRoot = !panel;\n if (isEmptyRoot) return;\n const name = panel.getAttribute('data-name');\n const isLeft = name === 'js-left';\n if (isLeft) return;\n DOM.changePanel();\n });\n}\n\n//# sourceURL=file://cloudcmd/client/listeners/index.js");
298
+ eval("/* global DOM, CloudCmd */\n\n\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/lib/itype.js\");\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n\nconst clipboard = __webpack_require__(/*! @cloudcmd/clipboard */ \"./node_modules/@cloudcmd/clipboard/lib/clipboard.js\");\n\nconst getRange = __webpack_require__(/*! ./get-range */ \"./client/listeners/get-range.js\");\n\nconst uploadFiles = __webpack_require__(/*! ../dom/upload-files */ \"./client/dom/upload-files.js\");\n\nconst {\n FS\n} = __webpack_require__(/*! ../../common/cloudfunc */ \"./common/cloudfunc.js\");\n\nconst getIndex = currify(__webpack_require__(/*! ./get-index */ \"./client/listeners/get-index.js\"));\nconst NBSP_REG = RegExp(String.fromCharCode(160), 'g');\nconst SPACE = ' ';\n\nmodule.exports.init = async () => {\n await Promise.all([contextMenu(), dragndrop(), unload(), pop(), resize(), header(), config()]);\n};\n\nCloudCmd.Listeners = module.exports;\n\nconst unselect = event => {\n const isMac = /Mac/.test(window.navigator.platform);\n const {\n shiftKey,\n metaKey,\n ctrlKey\n } = event;\n if (shiftKey || isMac && metaKey || ctrlKey) return;\n DOM.unselectFiles();\n};\n\nconst execAll = currify((funcs, event) => {\n for (const fn of funcs) fn(event);\n});\nconst Info = DOM.CurrentInfo;\nconst {\n Events\n} = DOM;\nconst EventsFiles = {\n mousedown: exec.with(execIfNotUL, setCurrentFileByEvent),\n click: execAll([onClick, unselect]),\n dragstart: exec.with(execIfNotUL, onDragStart),\n dblclick: exec.with(execIfNotUL, onDblClick),\n touchstart: exec.with(execIfNotUL, onTouch)\n};\nlet EXT;\n\nfunction header() {\n const fm = DOM.getFM();\n\n const isDataset = el => el.dataset;\n\n const isPanel = el => {\n return /^js-(left|right)$/.test(el.dataset.name);\n };\n\n Events.addClick(fm, event => {\n const el = event.target;\n const parent = el.parentElement;\n if (parent.dataset.name !== 'js-fm-header') return;\n const name = (el.dataset.name || '').replace('js-', '');\n if (!/^(name|size|date)$/.test(name)) return;\n const panel = getPath(el).filter(isDataset).filter(isPanel).pop();\n CloudCmd.sortPanel(name, panel);\n });\n}\n\nfunction getPath(el) {\n let path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n if (!el) return path;\n return getPath(el.parentElement, path.concat(el));\n}\n\nasync function config() {\n const [, config] = await tryToCatch(DOM.Files.get, 'config');\n const type = config === null || config === void 0 ? void 0 : config.packer;\n EXT = DOM.getPackerExt(type);\n}\n\nmodule.exports.initKeysPanel = () => {\n const keysElement = DOM.getById('js-keyspanel');\n if (!keysElement) return;\n Events.addClick(keysElement, _ref => {\n let {\n target\n } = _ref;\n const {\n id\n } = target;\n\n const operation = name => {\n const {\n Operation\n } = CloudCmd;\n const fn = Operation.show.bind(null, name);\n return fn;\n };\n\n const clickFuncs = {\n 'f1': CloudCmd.Help.show,\n 'f2': CloudCmd.UserMenu.show,\n 'f3': CloudCmd.View.show,\n 'f4': CloudCmd.EditFile.show,\n 'f5': operation('copy'),\n 'f6': operation('move'),\n 'f7': DOM.promptNewDir,\n 'f8': operation('delete'),\n 'f9': CloudCmd.Menu.show,\n 'f10': CloudCmd.Config.show,\n '~': CloudCmd.Konsole.show,\n 'shift~': CloudCmd.Terminal.show,\n 'contact': CloudCmd.Contact.show\n };\n exec(clickFuncs[id]);\n });\n};\n\nconst getPanel = side => {\n if (!itype.string(side)) return side;\n return DOM.getByDataName('js-' + side);\n};\n\nmodule.exports.setOnPanel = side => {\n const panel = getPanel(side);\n const filesElement = DOM.getByDataName('js-files', panel);\n const pathElement = DOM.getByDataName('js-path', panel);\n /* ставим загрузку гифа на клик*/\n\n Events.addClick(pathElement, getPathListener(panel));\n Events.add(filesElement, EventsFiles);\n};\n\nfunction getPathListener(panel) {\n return onPathElementClick.bind(null, panel);\n}\n\nfunction isNoCurrent(panel) {\n const infoPanel = Info.panel;\n if (!infoPanel) return true;\n const namePanel = panel.getAttribute('data-name');\n const nameInfoPanel = infoPanel.getAttribute('data-name');\n return namePanel !== nameInfoPanel;\n}\n\nfunction decodePath(path) {\n const url = CloudCmd.HOST;\n const {\n prefix\n } = CloudCmd;\n const prefixReg = RegExp('^' + prefix + FS);\n return decodeURI(path).replace(url, '').replace(prefixReg, '') // browser doesn't replace % -> %25% do it for him\n .replace('%%', '%25%').replace(NBSP_REG, SPACE) || '/';\n}\n\nasync function onPathElementClick(panel, event) {\n event.preventDefault();\n const element = event.target;\n const attr = element.getAttribute('data-name');\n const noCurrent = isNoCurrent(panel);\n if (attr === 'js-copy-path') return copyPath(element);\n if (attr === 'js-refresh') return CloudCmd.refresh({\n panel,\n noCurrent\n });\n if (attr !== 'js-path-link') return;\n const {\n href\n } = element;\n const path = decodePath(href);\n await CloudCmd.loadDir({\n path,\n isRefresh: false,\n panel: noCurrent ? panel : Info.panel\n });\n}\n\nfunction copyPath(el) {\n clipboard.writeText(el.parentElement.title).then(CloudCmd.log).catch(CloudCmd.log);\n}\n\nfunction execIfNotUL(callback, event) {\n const {\n target\n } = event;\n const {\n tagName\n } = target;\n if (tagName !== 'UL') callback(event);\n}\n\nfunction onClick(event) {\n event.preventDefault();\n changePanel(event.target);\n}\n\nfunction toggleSelect(key, files) {\n const isMac = /Mac/.test(window.navigator.platform);\n if (!key) throw Error('key should not be undefined!');\n const [file] = files;\n if (isMac && key.meta || key.ctrl) return DOM.toggleSelectedFile(file);\n if (key.shift) return files.map(DOM.selectFile);\n}\n\nfunction changePanel(element) {\n const {\n panel\n } = Info;\n const files = DOM.getByDataName('js-files', panel);\n const ul = getULElement(element);\n if (ul !== files) DOM.changePanel();\n}\n\nasync function onDblClick(event) {\n event.preventDefault();\n const current = getLIElement(event.target);\n const isDir = DOM.isCurrentIsDir(current);\n const path = DOM.getCurrentPath(current);\n if (!isDir) return CloudCmd.View.show();\n await CloudCmd.loadDir({\n path\n });\n}\n\nasync function onTouch(event) {\n const current = getLIElement(event.target);\n const isDir = DOM.isCurrentIsDir(current);\n if (!isDir) return;\n const isCurrent = DOM.isCurrentFile(current);\n if (!isCurrent) return;\n await CloudCmd.loadDir({\n path: DOM.getCurrentPath(current)\n });\n}\n/*\n * download file from browser to desktop\n * in Chrome (HTML5)\n */\n\n\nfunction onDragStart(event) {\n const {\n prefixURL\n } = CloudCmd;\n const element = getLIElement(event.target);\n const {\n isDir\n } = Info;\n let link = DOM.getCurrentLink(element);\n let name = DOM.getCurrentName(element);\n /* if it's directory - adding json extension */\n\n if (isDir) {\n name += EXT;\n link = document.createElement('a');\n link.textContent = name;\n link.href = prefixURL + '/pack' + Info.path + EXT;\n }\n\n event.dataTransfer.setData('DownloadURL', 'application/octet-stream' + ':' + name + ':' + link);\n}\n\nfunction getLIElement(element) {\n if (!element) return element;\n\n while (element.tagName !== 'LI') element = element.parentElement;\n\n return element;\n}\n\nfunction getULElement(element) {\n while (element.tagName !== 'UL') element = element.parentElement;\n\n return element;\n}\n\nfunction setCurrentFileByEvent(event) {\n const BUTTON_LEFT = 0;\n const key = {\n alt: event.altKey,\n ctrl: event.ctrlKey,\n meta: event.metaKey,\n shift: event.shiftKey\n };\n const element = getLIElement(event.target);\n const fromName = Info.name;\n DOM.setCurrentFile(element);\n const toName = Info.name;\n let files = [];\n if (key.shift) files = getFilesRange(fromName, toName);else files.push(Info.element);\n if (event.button === BUTTON_LEFT) toggleSelect(key, files);\n}\n\nfunction getFilesRange(from, to) {\n const files = DOM.getAllFiles();\n const names = DOM.getFilenames(files);\n const getNameIndex = getIndex(names);\n const indexFrom = getNameIndex(from);\n const indexTo = getNameIndex(to);\n return getRange(indexFrom, indexTo, files);\n}\n\nfunction contextMenu() {\n const fm = DOM.getFM();\n Events.addOnce('contextmenu', fm, event => {\n CloudCmd.Menu.show({\n x: event.clientX,\n y: event.clientY\n });\n });\n Events.addContextMenu(fm, event => {\n CloudCmd.Menu.ENABLED || event.preventDefault();\n });\n}\n\nfunction dragndrop() {\n const panels = DOM.getByClassAll('panel');\n\n const select = _ref2 => {\n let {\n target\n } = _ref2;\n target.classList.add('selected-panel');\n };\n\n const unselect = _ref3 => {\n let {\n target\n } = _ref3;\n target.classList.remove('selected-panel');\n };\n\n const onDrop = event => {\n const {\n files,\n items\n } = event.dataTransfer;\n const {\n length: filesCount\n } = files;\n event.preventDefault();\n if (filesCount && (!items || !items.length || !items[0].webkitGetAsEntry)) return uploadFiles(files);\n\n const isFile = item => item.kind === 'file';\n\n const dirFiles = Array.from(items).filter(isFile);\n if (dirFiles.length) return DOM.uploadDirectory(dirFiles);\n const {\n Operation\n } = CloudCmd;\n const operation = event.shiftKey ? 'move' : 'copy';\n return Operation.show(operation);\n };\n /**\n * In Mac OS Chrome dropEffect = 'none'\n * so drop do not firing up when try\n * to upload file from download bar\n */\n\n\n const onDragOver = event => {\n const {\n dataTransfer\n } = event;\n const {\n effectAllowed\n } = dataTransfer;\n if (/move|linkMove/.test(effectAllowed)) dataTransfer.dropEffect = 'move';else dataTransfer.dropEffect = 'copy';\n event.preventDefault();\n };\n\n for (const panel of panels) Events.add('dragover', panel, onDragOver).add('drop', panel, onDrop).add('dragenter', select).add(['dragleave', 'drop'], unselect);\n}\n\nfunction unload() {\n DOM.Events.add(['unload', 'beforeunload'], event => {\n const {\n Key\n } = CloudCmd;\n const isBind = Key === null || Key === void 0 ? void 0 : Key.isBind();\n if (isBind) return;\n event.preventDefault();\n return 'Please make sure that you saved all work.';\n });\n}\n\nfunction pop() {\n Events.add('popstate', async _ref4 => {\n let {\n state\n } = _ref4;\n const path = (state || '').replace(FS, '');\n if (!path) return CloudCmd.route(location.hash);\n const history = false;\n await CloudCmd.loadDir({\n path,\n history\n });\n });\n}\n\nfunction resize() {\n Events.add('resize', () => {\n const is = window.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH;\n if (!is) return;\n const {\n panel\n } = Info;\n const isEmptyRoot = !panel;\n if (isEmptyRoot) return;\n const name = panel.getAttribute('data-name');\n const isLeft = name === 'js-left';\n if (isLeft) return;\n DOM.changePanel();\n });\n}\n\n//# sourceURL=file://cloudcmd/client/listeners/index.js");
299
299
 
300
300
  /***/ }),
301
301
 
@@ -307,7 +307,7 @@ eval("/* global DOM, CloudCmd */\n\n\nconst exec = __webpack_require__(/*! execo
307
307
  /***/ (function(module, exports, __webpack_require__) {
308
308
 
309
309
  "use strict";
310
- eval("\n/* global CloudCmd */\n\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n\nconst loadJS = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\").js;\n\nconst pascalCase = __webpack_require__(/*! just-pascal-case */ \"./node_modules/just-pascal-case/index.js\");\n\nconst noJS = a => a.replace(/.js$/, '');\n/**\n * function load modules\n * @params = {name, path, func, dobefore, arg}\n */\n\n\nmodule.exports = function loadModule(params) {\n if (!params) return;\n const {\n path\n } = params;\n const name = path && noJS(pascalCase(path));\n const doBefore = params.dobefore;\n if (CloudCmd[name]) return;\n\n CloudCmd[name] = () => {\n exec(doBefore);\n const {\n prefix\n } = CloudCmd;\n const pathFull = prefix + CloudCmd.DIRCLIENT_MODULES + path + '.js';\n return loadJS(pathFull).then(async () => {\n const newModule = async f => f && f();\n\n const module = CloudCmd[name];\n Object.assign(newModule, module);\n CloudCmd[name] = newModule;\n CloudCmd.log('init', name);\n await module.init();\n return newModule;\n });\n };\n\n CloudCmd[name].show = async function () {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n CloudCmd.log('show', name, args);\n const m = CloudCmd[name];\n const [e, a] = await tryToCatch(m);\n if (e) return console.error(e);\n await a.show(...args);\n };\n};\n\n//# sourceURL=file://cloudcmd/client/load-module.js");
310
+ eval("\n/* global CloudCmd */\n\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n\nconst loadJS = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\").js;\n\nconst pascalCase = __webpack_require__(/*! just-pascal-case */ \"./node_modules/just-pascal-case/index.js\");\n\nconst noJS = a => a.replace(/.js$/, '');\n/**\n * function load modules\n * @params = {name, path, func, dobefore, arg}\n */\n\n\nmodule.exports = function loadModule(params) {\n if (!params) return;\n const {\n path\n } = params;\n const name = path && noJS(pascalCase(path));\n const doBefore = params.dobefore;\n if (CloudCmd[name]) return;\n\n CloudCmd[name] = () => {\n exec(doBefore);\n const {\n prefix\n } = CloudCmd;\n const pathFull = prefix + CloudCmd.DIRCLIENT_MODULES + path + '.js';\n return loadJS(pathFull).then(async () => {\n const newModule = async f => f && f();\n\n const module = CloudCmd[name];\n Object.assign(newModule, module);\n CloudCmd[name] = newModule;\n CloudCmd.log('init', name);\n await module.init();\n return newModule;\n });\n };\n\n CloudCmd[name].show = async function () {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n CloudCmd.log('show', name, args);\n const m = CloudCmd[name];\n const [e, a] = await tryToCatch(m);\n if (e) return console.error(e);\n return await a.show(...args);\n };\n};\n\n//# sourceURL=file://cloudcmd/client/load-module.js");
311
311
 
312
312
  /***/ }),
313
313
 
@@ -163,7 +163,7 @@
163
163
  /***/ (function(module, exports, __webpack_require__) {
164
164
 
165
165
  "use strict";
166
- eval("/* global CloudCmd, filepicker */\n\n\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\n\nconst {\n log\n} = CloudCmd;\n\nconst {\n ajax\n} = __webpack_require__(/*! ../dom/load */ \"./client/dom/load.js\");\n\nconst Files = __webpack_require__(/*! ../dom/files */ \"./client/dom/files.js\");\n\nconst Images = __webpack_require__(/*! ../dom/images */ \"./client/dom/images.js\");\n\nconst upload = currify(_upload);\nconst Name = 'Cloud';\nCloudCmd[Name] = module.exports;\n\nmodule.exports.init = async () => {\n const [modules] = await loadFiles();\n const {\n key\n } = modules.data.FilePicker;\n filepicker.setKey(key);\n Images.hide();\n};\n\nmodule.exports.uploadFile = (filename, data) => {\n const mimetype = '';\n filepicker.store(data, {\n mimetype,\n filename\n }, fpFile => {\n filepicker.exportFile(fpFile, log, log);\n });\n};\n\nmodule.exports.saveFile = callback => {\n filepicker.pick(upload(callback));\n};\n\nfunction _upload(callback, file) {\n const {\n url,\n filename\n } = file;\n const responseType = 'arraybuffer';\n const success = exec.with(callback, filename);\n ajax({\n url,\n responseType,\n success\n });\n}\n\nfunction loadFiles() {\n const js = '//api.filepicker.io/v2/filepicker.js';\n return Promise.all([Files.get('modules'), load.js(js)]);\n}\n\n//# sourceURL=file://cloudcmd/client/modules/cloud.js");
166
+ eval("/* global CloudCmd, filepicker */\n\n\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\n\nconst {\n ajax\n} = __webpack_require__(/*! ../dom/load */ \"./client/dom/load.js\");\n\nconst Files = __webpack_require__(/*! ../dom/files */ \"./client/dom/files.js\");\n\nconst Images = __webpack_require__(/*! ../dom/images */ \"./client/dom/images.js\");\n\nconst {\n log\n} = CloudCmd;\nconst upload = currify(_upload);\nconst Name = 'Cloud';\nCloudCmd[Name] = module.exports;\n\nmodule.exports.init = async () => {\n const [modules] = await loadFiles();\n const {\n key\n } = modules.data.FilePicker;\n filepicker.setKey(key);\n Images.hide();\n};\n\nmodule.exports.uploadFile = (filename, data) => {\n const mimetype = '';\n filepicker.store(data, {\n mimetype,\n filename\n }, fpFile => {\n filepicker.exportFile(fpFile, log, log);\n });\n};\n\nmodule.exports.saveFile = callback => {\n filepicker.pick(upload(callback));\n};\n\nfunction _upload(callback, file) {\n const {\n url,\n filename\n } = file;\n const responseType = 'arraybuffer';\n const success = exec.with(callback, filename);\n ajax({\n url,\n responseType,\n success\n });\n}\n\nfunction loadFiles() {\n const js = '//api.filepicker.io/v2/filepicker.js';\n return Promise.all([Files.get('modules'), load.js(js)]);\n}\n\n//# sourceURL=file://cloudcmd/client/modules/cloud.js");
167
167
 
168
168
  /***/ })
169
169
 
@@ -175,7 +175,7 @@ eval("\n/* global CloudCmd, DOM, io */\n\n__webpack_require__(/*! ../../../css/c
175
175
  /***/ (function(module, exports, __webpack_require__) {
176
176
 
177
177
  "use strict";
178
- eval("\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\nconst isType = currify((type, object, name) => typeof object[name] === type);\nconst isBool = isType('boolean');\nmodule.exports.getElementByName = getElementByName;\n\nfunction getElementByName(selector, element) {\n const str = `[data-name=\"js-${selector}\"]`;\n return element.querySelector(str);\n}\n\nmodule.exports.getName = element => {\n const name = element.getAttribute('data-name').replace(/^js-/, '');\n return name;\n};\n\nmodule.exports.convert = config => {\n const result = config;\n const array = Object.keys(config);\n const filtered = array.filter(isBool(config));\n\n for (const name of filtered) {\n const item = config[name];\n result[name] = setState(item);\n }\n\n return result;\n};\n\nfunction setState(state) {\n if (state) return ' checked';\n return '';\n}\n\nmodule.exports.getValue = (name, element) => {\n const el = getElementByName(name, element);\n const {\n type\n } = el;\n\n switch (type) {\n case 'checkbox':\n return el.checked;\n\n case 'number':\n return Number(el.value);\n\n default:\n return el.value;\n }\n};\n\nmodule.exports.setValue = (name, value, element) => {\n const el = getElementByName(name, element);\n const {\n type\n } = el;\n\n switch (type) {\n case 'checkbox':\n el.checked = value;\n break;\n\n default:\n el.value = value;\n break;\n }\n};\n\n//# sourceURL=file://cloudcmd/client/modules/config/input.js");
178
+ eval("\n\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\nconst isType = currify((type, object, name) => type === typeof object[name]);\nconst isBool = isType('boolean');\nmodule.exports.getElementByName = getElementByName;\n\nfunction getElementByName(selector, element) {\n const str = `[data-name=\"js-${selector}\"]`;\n return element.querySelector(str);\n}\n\nmodule.exports.getName = element => {\n const name = element.getAttribute('data-name').replace(/^js-/, '');\n return name;\n};\n\nmodule.exports.convert = config => {\n const result = config;\n const array = Object.keys(config);\n const filtered = array.filter(isBool(config));\n\n for (const name of filtered) {\n const item = config[name];\n result[name] = setState(item);\n }\n\n return result;\n};\n\nfunction setState(state) {\n if (state) return ' checked';\n return '';\n}\n\nmodule.exports.getValue = (name, element) => {\n const el = getElementByName(name, element);\n const {\n type\n } = el;\n\n switch (type) {\n case 'checkbox':\n return el.checked;\n\n case 'number':\n return Number(el.value);\n\n default:\n return el.value;\n }\n};\n\nmodule.exports.setValue = (name, value, element) => {\n const el = getElementByName(name, element);\n const {\n type\n } = el;\n\n switch (type) {\n case 'checkbox':\n el.checked = value;\n break;\n\n default:\n el.value = value;\n break;\n }\n};\n\n//# sourceURL=file://cloudcmd/client/modules/config/input.js");
179
179
 
180
180
  /***/ }),
181
181
 
@@ -163,7 +163,7 @@
163
163
  /***/ (function(module, exports, __webpack_require__) {
164
164
 
165
165
  "use strict";
166
- eval("/* global CloudCmd */\n\n\nconst {\n promisify\n} = __webpack_require__(/*! es6-promisify */ \"./node_modules/es6-promisify/dist/promisify.mjs\");\n\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\n\nconst loadJS = load.js;\n\nconst {\n MAX_FILE_SIZE: maxSize\n} = __webpack_require__(/*! ../../common/cloudfunc */ \"./common/cloudfunc.js\");\n\nconst {\n time,\n timeEnd\n} = __webpack_require__(/*! ../../common/util */ \"./common/util.js\");\n\nconst Name = 'Edit';\nCloudCmd[Name] = exports;\nconst EditorName = CloudCmd.config('editor');\nlet Loading = true;\nlet Element;\nlet editor;\nconst ConfigView = {\n afterShow: () => {\n editor.moveCursorTo(0, 0).focus();\n }\n};\n\nmodule.exports.init = async () => {\n const element = create();\n await CloudCmd.View();\n await loadFiles(element);\n};\n\nfunction create() {\n const element = createElement('div', {\n style: 'width : 100%;' + 'height : 100%;' + 'font-family: \"Droid Sans Mono\";',\n notAppend: true\n });\n Element = element;\n return element;\n}\n\nfunction checkFn(name, fn) {\n if (typeof fn !== 'function') throw Error(name + ' should be a function!');\n}\n\nfunction initConfig() {\n let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const config = { ...options,\n ...ConfigView\n };\n if (!options.afterShow) return config;\n checkFn('options.afterShow', options.afterShow);\n const afterShow = {\n config\n };\n\n config.afterShow = () => {\n afterShow();\n options.afterShow();\n };\n\n return config;\n}\n\nmodule.exports.show = options => {\n if (Loading) return;\n CloudCmd.View.show(Element, initConfig(options));\n getEditor().setOptions({\n fontSize: 16\n });\n};\n\nmodule.exports.getEditor = getEditor;\n\nfunction getEditor() {\n return editor;\n}\n\nmodule.exports.getElement = () => Element;\n\nmodule.exports.hide = () => {\n CloudCmd.View.hide();\n};\n\nconst loadFiles = async element => {\n const prefix = `${CloudCmd.prefix}/${EditorName}`;\n const socketPath = CloudCmd.prefix;\n const prefixSocket = `${CloudCmd.prefixSocket}/${EditorName}`;\n const url = `${prefix}/${EditorName}.js`;\n time(Name + ' load');\n await loadJS(url);\n const word = promisify(window[EditorName]);\n const [ed] = await tryToCatch(word, element, {\n maxSize,\n prefix,\n prefixSocket,\n socketPath\n });\n timeEnd(Name + ' load');\n editor = ed;\n Loading = false;\n};\n\n//# sourceURL=file://cloudcmd/client/modules/edit.js");
166
+ eval("/* global CloudCmd */\n\n\nconst {\n promisify\n} = __webpack_require__(/*! es6-promisify */ \"./node_modules/es6-promisify/dist/promisify.mjs\");\n\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\nconst load = __webpack_require__(/*! load.js */ \"./node_modules/load.js/lib/load.js\");\n\nconst {\n MAX_FILE_SIZE: maxSize\n} = __webpack_require__(/*! ../../common/cloudfunc */ \"./common/cloudfunc.js\");\n\nconst {\n time,\n timeEnd\n} = __webpack_require__(/*! ../../common/util */ \"./common/util.js\");\n\nconst loadJS = load.js;\nconst Name = 'Edit';\nCloudCmd[Name] = exports;\nconst EditorName = CloudCmd.config('editor');\nlet Loading = true;\nlet Element;\nlet editor;\nconst ConfigView = {\n afterShow: () => {\n editor.moveCursorTo(0, 0).focus();\n }\n};\n\nmodule.exports.init = async () => {\n const element = create();\n await CloudCmd.View();\n await loadFiles(element);\n};\n\nfunction create() {\n const element = createElement('div', {\n style: 'width : 100%;' + 'height : 100%;' + 'font-family: \"Droid Sans Mono\";',\n notAppend: true\n });\n Element = element;\n return element;\n}\n\nfunction checkFn(name, fn) {\n if (typeof fn !== 'function') throw Error(name + ' should be a function!');\n}\n\nfunction initConfig() {\n let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const config = { ...options,\n ...ConfigView\n };\n if (!options.afterShow) return config;\n checkFn('options.afterShow', options.afterShow);\n const afterShow = {\n config\n };\n\n config.afterShow = () => {\n afterShow();\n options.afterShow();\n };\n\n return config;\n}\n\nmodule.exports.show = options => {\n if (Loading) return;\n CloudCmd.View.show(Element, initConfig(options));\n getEditor().setOptions({\n fontSize: 16\n });\n};\n\nmodule.exports.getEditor = getEditor;\n\nfunction getEditor() {\n return editor;\n}\n\nmodule.exports.getElement = () => Element;\n\nmodule.exports.hide = () => {\n CloudCmd.View.hide();\n};\n\nconst loadFiles = async element => {\n const prefix = `${CloudCmd.prefix}/${EditorName}`;\n const socketPath = CloudCmd.prefix;\n const prefixSocket = `${CloudCmd.prefixSocket}/${EditorName}`;\n const url = `${prefix}/${EditorName}.js`;\n time(Name + ' load');\n await loadJS(url);\n const word = promisify(window[EditorName]);\n const [ed] = await tryToCatch(word, element, {\n maxSize,\n prefix,\n prefixSocket,\n socketPath\n });\n timeEnd(Name + ' load');\n editor = ed;\n Loading = false;\n};\n\n//# sourceURL=file://cloudcmd/client/modules/edit.js");
167
167
 
168
168
  /***/ })
169
169
 
@@ -163,7 +163,7 @@
163
163
  /***/ (function(module, exports, __webpack_require__) {
164
164
 
165
165
  "use strict";
166
- eval("\n/* global CloudCmd */\n\nCloudCmd.Markdown = exports;\n\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\nconst Images = __webpack_require__(/*! ../dom/images */ \"./client/dom/images.js\");\n\nconst {\n Markdown\n} = __webpack_require__(/*! ../dom/rest */ \"./client/dom/rest.js\");\n\nconst {\n alert\n} = __webpack_require__(/*! ../dom/dialog */ \"./client/dom/dialog.js\");\n\nmodule.exports.init = async () => {\n Images.show.load('top');\n await CloudCmd.View();\n};\n\nmodule.exports.show = show;\n\nmodule.exports.hide = () => {\n CloudCmd.View.hide();\n};\n\nasync function show(name) {\n let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n const relativeQuery = '?relative';\n const {\n positionLoad,\n relative\n } = options;\n Images.show.load(positionLoad);\n if (relative) name += relativeQuery;\n const [error, innerHTML] = await Markdown.read(name);\n Images.hide();\n if (error) return alert(error.message, {\n cancel: false\n });\n const className = 'help';\n const div = createElement('div', {\n className,\n innerHTML\n });\n CloudCmd.View.show(div);\n}\n\n//# sourceURL=file://cloudcmd/client/modules/markdown.js");
166
+ eval("\n/* global CloudCmd */\n\nCloudCmd.Markdown = exports;\n\nconst createElement = __webpack_require__(/*! @cloudcmd/create-element */ \"./node_modules/@cloudcmd/create-element/lib/create-element.js\");\n\nconst Images = __webpack_require__(/*! ../dom/images */ \"./client/dom/images.js\");\n\nconst {\n Markdown\n} = __webpack_require__(/*! ../dom/rest */ \"./client/dom/rest.js\");\n\nconst {\n alert\n} = __webpack_require__(/*! ../dom/dialog */ \"./client/dom/dialog.js\");\n\nmodule.exports.init = async () => {\n Images.show.load('top');\n await CloudCmd.View();\n};\n\nmodule.exports.show = show;\n\nmodule.exports.hide = () => {\n CloudCmd.View.hide();\n};\n\nasync function show(name) {\n let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n const {\n positionLoad,\n relative\n } = options;\n Images.show.load(positionLoad);\n if (relative) name += '?relative';\n const [error, innerHTML] = await Markdown.read(name);\n Images.hide();\n if (error) return alert(error.message, {\n cancel: false\n });\n const className = 'help';\n const div = createElement('div', {\n className,\n innerHTML\n });\n CloudCmd.View.show(div);\n}\n\n//# sourceURL=file://cloudcmd/client/modules/markdown.js");
167
167
 
168
168
  /***/ })
169
169
 
@@ -211,7 +211,7 @@ eval("\n\nconst {\n getExt\n} = __webpack_require__(/*! ../../../common/util */
211
211
  /***/ (function(module, exports, __webpack_require__) {
212
212
 
213
213
  "use strict";
214
- eval("\n/* global DOM */\n\nconst {\n Dialog,\n Images\n} = DOM;\n\nconst forEachKey = __webpack_require__(/*! for-each-key */ \"./node_modules/for-each-key/lib/for-each-key.js\");\n\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\n\nconst format = __webpack_require__(/*! ./format */ \"./client/modules/operation/format.js\");\n\nmodule.exports = options => emitter => {\n const {\n operation,\n callback,\n noContinue,\n from,\n to\n } = options;\n let done;\n let lastError;\n const onAbort = wraptile(_ref => {\n let {\n emitter,\n operation\n } = _ref;\n emitter.abort();\n const msg = `${operation} aborted`;\n lastError = true;\n Dialog.alert(msg, {\n cancel: false\n });\n });\n const removeListener = emitter.removeListener.bind(emitter);\n const on = emitter.on.bind(emitter);\n const message = format(operation, from, to);\n const progress = Dialog.progress(message);\n progress.catch(onAbort({\n emitter,\n operation\n }));\n const listeners = {\n progress: value => {\n done = value === 100;\n progress.setProgress(value);\n },\n end: () => {\n Images.hide();\n forEachKey(removeListener, listeners);\n progress.remove();\n if (lastError || done) callback();\n },\n error: async error => {\n lastError = error;\n\n if (noContinue) {\n listeners.end(error);\n Dialog.alert(error);\n progress.remove();\n return;\n }\n\n const [cancel] = await Dialog.confirm(error + '\\n Continue?');\n if (!done && !cancel) return emitter.continue();\n emitter.abort();\n progress.remove();\n }\n };\n forEachKey(on, listeners);\n};\n\n//# sourceURL=file://cloudcmd/client/modules/operation/set-listeners.js");
214
+ eval("\n/* global DOM */\n\nconst forEachKey = __webpack_require__(/*! for-each-key */ \"./node_modules/for-each-key/lib/for-each-key.js\");\n\nconst wraptile = __webpack_require__(/*! wraptile */ \"./node_modules/wraptile/lib/wraptile.js\");\n\nconst format = __webpack_require__(/*! ./format */ \"./client/modules/operation/format.js\");\n\nconst {\n Dialog,\n Images\n} = DOM;\n\nmodule.exports = options => emitter => {\n const {\n operation,\n callback,\n noContinue,\n from,\n to\n } = options;\n let done;\n let lastError;\n const onAbort = wraptile(_ref => {\n let {\n emitter,\n operation\n } = _ref;\n emitter.abort();\n const msg = `${operation} aborted`;\n lastError = true;\n Dialog.alert(msg, {\n cancel: false\n });\n });\n const removeListener = emitter.removeListener.bind(emitter);\n const on = emitter.on.bind(emitter);\n const message = format(operation, from, to);\n const progress = Dialog.progress(message);\n progress.catch(onAbort({\n emitter,\n operation\n }));\n const listeners = {\n progress: value => {\n done = value === 100;\n progress.setProgress(value);\n },\n end: () => {\n Images.hide();\n forEachKey(removeListener, listeners);\n progress.remove();\n if (lastError || done) callback();\n },\n error: async error => {\n lastError = error;\n\n if (noContinue) {\n listeners.end(error);\n Dialog.alert(error);\n progress.remove();\n return;\n }\n\n const [cancel] = await Dialog.confirm(error + '\\n Continue?');\n if (!done && !cancel) return emitter.continue();\n emitter.abort();\n progress.remove();\n }\n };\n forEachKey(on, listeners);\n};\n\n//# sourceURL=file://cloudcmd/client/modules/operation/set-listeners.js");
215
215
 
216
216
  /***/ })
217
217