cloudcmd 19.6.7 → 19.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sw.js CHANGED
@@ -311,7 +311,7 @@ const respondWith = currify((f, e) => {
311
311
  e.respondWith(f(e));
312
312
  });
313
313
  const getPathName = url => new URL(url).pathname;
314
- const date = "Thu Feb 26 2026 20:18:18 GMT+0200 (Eastern European Standard Time)";
314
+ const date = "Tue Mar 17 2026 20:43:56 GMT+0200 (Eastern European Standard Time)";
315
315
  const NAME = `cloudcmd: ${date}`;
316
316
  const createRequest = a => new Request(a, {
317
317
  credentials: 'same-origin'
@@ -1613,7 +1613,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
1613
1613
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1614
1614
 
1615
1615
  "use strict";
1616
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ hide: () => (/* binding */ hide),\n/* harmony export */ init: () => (/* binding */ init),\n/* harmony export */ isChanged: () => (/* binding */ isChanged),\n/* harmony export */ show: () => (/* binding */ show)\n/* harmony export */ });\n/* harmony import */ var try_to_catch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n/* harmony import */ var execon__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n/* harmony import */ var supermenu__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! supermenu */ \"./node_modules/supermenu/lib/supermenu.js\");\n/* harmony import */ var multi_rename__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! multi-rename */ \"./node_modules/multi-rename/lib/multi-rename.js\");\n\n\n\n\nconst {\n CloudCmd,\n DOM\n} = globalThis;\nCloudCmd.EditNames = {\n init,\n show,\n hide,\n isChanged\n};\nconst Info = DOM.CurrentInfo;\nconst {\n Dialog\n} = DOM;\nlet Menu;\nconst ConfigView = {\n beforeClose: async () => {\n execon__WEBPACK_IMPORTED_MODULE_1__.ifExist(Menu, 'hide');\n DOM.Events.remove('keydown', keyListener);\n await isChanged();\n }\n};\nasync function init() {\n await CloudCmd.Edit();\n setListeners();\n}\nfunction show(options) {\n const names = getActiveNames().join('\\n');\n const config = {\n ...ConfigView,\n ...options\n };\n if (Info.name === '..' && names.length === 1) return Dialog.alert.noFiles();\n DOM.Events.addKey(keyListener);\n CloudCmd.Edit.getEditor().setValueFirst('edit-names', names).setMode().setOption('keyMap', 'default').disableKey();\n CloudCmd.Edit.show(config);\n return CloudCmd.Edit;\n}\nasync function keyListener(event) {\n const ctrl = event.ctrlKey;\n const meta = event.metaKey;\n const ctrlMeta = ctrl || meta;\n const {\n Key\n } = CloudCmd;\n if (ctrlMeta && event.keyCode === Key.S) {\n hide();\n } else if (ctrlMeta && event.keyCode === Key.P) {\n const [, pattern] = await Dialog.prompt('Apply pattern:', '[n][e]');\n pattern && applyPattern(pattern);\n }\n}\nfunction applyPattern(pattern) {\n const newNames = (0,multi_rename__WEBPACK_IMPORTED_MODULE_3__.multiRename)(pattern, getActiveNames());\n const editor = CloudCmd.Edit.getEditor();\n editor.setValue(newNames.join('\\n'));\n}\nfunction getActiveNames() {\n return DOM.getFilenames(DOM.getActiveFiles());\n}\nfunction hide() {\n CloudCmd.Edit.hide();\n}\nfunction setListeners() {\n const element = CloudCmd.Edit.getElement();\n DOM.Events.addOnce('contextmenu', element, setMenu);\n}\nasync function applyNames() {\n const dir = Info.dirPath;\n const from = getActiveNames();\n const nameIndex = from.indexOf(Info.name);\n const editor = CloudCmd.Edit.getEditor();\n const to = editor.getValue().split('\\n');\n const root = CloudCmd.config('root');\n const response = rename(dir, from, to, root);\n const [error] = await (0,try_to_catch__WEBPACK_IMPORTED_MODULE_0__.tryToCatch)(refresh, to, nameIndex, response);\n if (error) alert(error);\n}\nfunction refresh(to, nameIndex, res) {\n if (res.status === 404) {\n const error = res.text();\n throw error;\n }\n const currentName = to[nameIndex];\n CloudCmd.refresh({\n currentName\n });\n}\nfunction getDir(root, dir) {\n if (root === '/') return dir;\n return root + dir;\n}\nfunction rename(path, from, to, root) {\n const dir = getDir(root, path);\n const {\n prefix\n } = CloudCmd;\n return fetch(`${prefix}/rename`, {\n method: 'put',\n credentials: 'include',\n body: JSON.stringify({\n from,\n to,\n dir\n })\n });\n}\nfunction setMenu(event) {\n const position = {\n x: event.clientX,\n y: event.clientY\n };\n event.preventDefault();\n if (Menu) return;\n const editor = CloudCmd.Edit.getEditor();\n const options = {\n beforeShow: params => {\n params.x -= 18;\n params.y -= 27;\n },\n afterClick: () => {\n editor.focus();\n }\n };\n const menuData = {\n 'Save Ctrl+S': async () => {\n await applyNames();\n hide();\n },\n 'Go To Line Ctrl+G': () => {\n editor.goToLine();\n },\n 'Cut Ctrl+X': () => {\n editor.cutToClipboard();\n },\n 'Copy Ctrl+C': () => {\n editor.copyToClipboard();\n },\n 'Paste Ctrl+V': () => {\n editor.pasteFromClipboard();\n },\n 'Delete Del': () => {\n editor.remove('right');\n },\n 'Select All Ctrl+A': () => {\n editor.selectAll();\n },\n 'Close Esc': hide\n };\n const element = CloudCmd.Edit.getElement();\n Menu = (0,supermenu__WEBPACK_IMPORTED_MODULE_2__.supermenu)(element, options, menuData);\n Menu.addContextMenuListener();\n Menu.show(position.x, position.y);\n}\nasync function isChanged() {\n const editor = CloudCmd.Edit.getEditor();\n const msg = 'Apply new names?';\n if (!editor.isChanged()) return;\n const [cancel] = await Dialog.confirm(msg);\n !cancel && (await applyNames());\n}\n\n//# sourceURL=file://cloudcmd//Users/coderaiser/cloudcmd/client/modules/edit-names.js\n}");
1616
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ hide: () => (/* binding */ hide),\n/* harmony export */ init: () => (/* binding */ init),\n/* harmony export */ isChanged: () => (/* binding */ isChanged),\n/* harmony export */ show: () => (/* binding */ show)\n/* harmony export */ });\n/* harmony import */ var try_to_catch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n/* harmony import */ var execon__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\n/* harmony import */ var supermenu__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! supermenu */ \"./node_modules/supermenu/lib/supermenu.js\");\n/* harmony import */ var multi_rename__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! multi-rename */ \"./node_modules/multi-rename/lib/multi-rename.js\");\n\n\n\n\nconst {\n CloudCmd,\n DOM\n} = globalThis;\nCloudCmd.EditNames = {\n init,\n show,\n hide,\n isChanged\n};\nconst Info = DOM.CurrentInfo;\nconst {\n Dialog\n} = DOM;\nlet Menu;\nconst ConfigView = {\n beforeClose: async () => {\n execon__WEBPACK_IMPORTED_MODULE_1__.ifExist(Menu, 'hide');\n DOM.Events.remove('keydown', keyListener);\n await isChanged();\n }\n};\nasync function init() {\n await CloudCmd.Edit();\n setListeners();\n}\nfunction show(options) {\n const names = getActiveNames().join('\\n');\n const config = {\n ...ConfigView,\n ...options\n };\n if (Info.name === '..' && names.length === 1) return Dialog.alert.noFiles();\n DOM.Events.addKey(keyListener);\n CloudCmd.Edit.getEditor().setValueFirst('edit-names', names).setMode().setOption('keyMap', 'default').disableKey();\n CloudCmd.Edit.show(config);\n return CloudCmd.Edit;\n}\nasync function keyListener(event) {\n const ctrl = event.ctrlKey;\n const meta = event.metaKey;\n const ctrlMeta = ctrl || meta;\n const {\n Key\n } = CloudCmd;\n if (ctrlMeta && event.keyCode === Key.S) {\n hide();\n return;\n }\n if (ctrlMeta && event.keyCode === Key.P) {\n const [, pattern] = await Dialog.prompt('Apply pattern:', '[n][e]');\n pattern && applyPattern(pattern);\n }\n}\nfunction applyPattern(pattern) {\n const newNames = (0,multi_rename__WEBPACK_IMPORTED_MODULE_3__.multiRename)(pattern, getActiveNames());\n const editor = CloudCmd.Edit.getEditor();\n editor.setValue(newNames.join('\\n'));\n}\nfunction getActiveNames() {\n return DOM.getFilenames(DOM.getActiveFiles());\n}\nfunction hide() {\n CloudCmd.Edit.hide();\n}\nfunction setListeners() {\n const element = CloudCmd.Edit.getElement();\n DOM.Events.addOnce('contextmenu', element, setMenu);\n}\nasync function applyNames() {\n const dir = Info.dirPath;\n const from = getActiveNames();\n const nameIndex = from.indexOf(Info.name);\n const editor = CloudCmd.Edit.getEditor();\n const to = editor.getValue().split('\\n');\n const root = CloudCmd.config('root');\n const response = rename(dir, from, to, root);\n const [error] = await (0,try_to_catch__WEBPACK_IMPORTED_MODULE_0__.tryToCatch)(refresh, to, nameIndex, response);\n if (error) alert(error);\n}\nfunction refresh(to, nameIndex, res) {\n if (res.status === 404) {\n const error = res.text();\n throw error;\n }\n const currentName = to[nameIndex];\n CloudCmd.refresh({\n currentName\n });\n}\nfunction getDir(root, dir) {\n if (root === '/') return dir;\n return root + dir;\n}\nfunction rename(path, from, to, root) {\n const dir = getDir(root, path);\n const {\n prefix\n } = CloudCmd;\n return fetch(`${prefix}/rename`, {\n method: 'put',\n credentials: 'include',\n body: JSON.stringify({\n from,\n to,\n dir\n })\n });\n}\nfunction setMenu(event) {\n const position = {\n x: event.clientX,\n y: event.clientY\n };\n event.preventDefault();\n if (Menu) return;\n const editor = CloudCmd.Edit.getEditor();\n const options = {\n beforeShow: params => {\n params.x -= 18;\n params.y -= 27;\n },\n afterClick: () => {\n editor.focus();\n }\n };\n const menuData = {\n 'Save Ctrl+S': async () => {\n await applyNames();\n hide();\n },\n 'Go To Line Ctrl+G': () => {\n editor.goToLine();\n },\n 'Cut Ctrl+X': () => {\n editor.cutToClipboard();\n },\n 'Copy Ctrl+C': () => {\n editor.copyToClipboard();\n },\n 'Paste Ctrl+V': () => {\n editor.pasteFromClipboard();\n },\n 'Delete Del': () => {\n editor.remove('right');\n },\n 'Select All Ctrl+A': () => {\n editor.selectAll();\n },\n 'Close Esc': hide\n };\n const element = CloudCmd.Edit.getElement();\n Menu = (0,supermenu__WEBPACK_IMPORTED_MODULE_2__.supermenu)(element, options, menuData);\n Menu.addContextMenuListener();\n Menu.show(position.x, position.y);\n}\nasync function isChanged() {\n const editor = CloudCmd.Edit.getEditor();\n const msg = 'Apply new names?';\n if (!editor.isChanged()) return;\n const [cancel] = await Dialog.confirm(msg);\n !cancel && (await applyNames());\n}\n\n//# sourceURL=file://cloudcmd//Users/coderaiser/cloudcmd/client/modules/edit-names.js\n}");
1617
1617
 
1618
1618
  /***/ },
1619
1619
 
package/dist-dev/sw.js CHANGED
@@ -37,7 +37,7 @@ eval("{// shim for using process in browser\nvar process = module.exports = {};\
37
37
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
38
38
 
39
39
  "use strict";
40
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var node_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\n/* harmony import */ var try_to_catch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n/* harmony import */ var currify__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\n\n\nconst isDev = \"development\" === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify__WEBPACK_IMPORTED_MODULE_2__((f, e) => e.waitUntil(f()));\nconst respondWith = currify__WEBPACK_IMPORTED_MODULE_2__((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Thu Feb 26 2026 20:18:20 GMT+0200 (Eastern European Standard Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nglobalThis.addEventListener('install', wait(onInstall));\nglobalThis.addEventListener('fetch', respondWith(onFetch));\nglobalThis.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await globalThis.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await globalThis.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await (0,try_to_catch__WEBPACK_IMPORTED_MODULE_1__.tryToCatch)(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd//Users/coderaiser/cloudcmd/client/sw/sw.js\n}");
40
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var node_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\n/* harmony import */ var try_to_catch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n/* harmony import */ var currify__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\n\n\nconst isDev = \"development\" === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify__WEBPACK_IMPORTED_MODULE_2__((f, e) => e.waitUntil(f()));\nconst respondWith = currify__WEBPACK_IMPORTED_MODULE_2__((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Tue Mar 17 2026 20:43:58 GMT+0200 (Eastern European Standard Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nglobalThis.addEventListener('install', wait(onInstall));\nglobalThis.addEventListener('fetch', respondWith(onFetch));\nglobalThis.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await globalThis.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await globalThis.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await (0,try_to_catch__WEBPACK_IMPORTED_MODULE_1__.tryToCatch)(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd//Users/coderaiser/cloudcmd/client/sw/sw.js\n}");
41
41
 
42
42
  /***/ },
43
43
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudcmd",
3
- "version": "19.6.7",
3
+ "version": "19.6.9",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "File manager for the web with console and editor",
@@ -86,7 +86,7 @@
86
86
  "dependencies": {
87
87
  "@babel/plugin-transform-optional-chaining": "^7.21.0",
88
88
  "@cloudcmd/dropbox": "^5.0.1",
89
- "@cloudcmd/fileop": "^9.0.2",
89
+ "@cloudcmd/fileop": "^9.0.5",
90
90
  "@cloudcmd/move-files": "^8.0.0",
91
91
  "@cloudcmd/read-files-sync": "^2.0.0",
92
92
  "@putout/cli-validate-args": "^2.0.0",
@@ -95,7 +95,7 @@
95
95
  "chalk": "^5.3.0",
96
96
  "compression": "^1.7.4",
97
97
  "console-io": "^15.0.1",
98
- "copymitter": "^10.2.0",
98
+ "copymitter": "^10.3.0",
99
99
  "criton": "^2.0.0",
100
100
  "currify": "^4.0.0",
101
101
  "deepmerge": "^4.0.0",
@@ -130,7 +130,7 @@
130
130
  "ponse": "^7.0.0",
131
131
  "pullout": "^5.0.0",
132
132
  "putout": "^42.0.5",
133
- "redzip": "^4.5.1",
133
+ "redzip": "^4.6.1",
134
134
  "rendy": "^5.0.0",
135
135
  "restafary": "^13.0.1",
136
136
  "restbox": "^4.0.0",
@@ -169,7 +169,7 @@
169
169
  "clean-css-loader": "^4.2.1",
170
170
  "codegen.macro": "^4.0.0",
171
171
  "css-loader": "^7.1.2",
172
- "css-minimizer-webpack-plugin": "^7.0.4",
172
+ "css-minimizer-webpack-plugin": "^8.0.0",
173
173
  "css-modules-require-hook": "^4.2.3",
174
174
  "cssnano-preset-default": "^7.0.10",
175
175
  "domtokenlist-shim": "^1.2.0",
@@ -215,7 +215,7 @@
215
215
  "url-loader": "^4.0.0",
216
216
  "util": "^0.12.5",
217
217
  "webpack": "^5.99.9",
218
- "webpack-cli": "^6.0.1",
218
+ "webpack-cli": "^7.0.2",
219
219
  "webpack-merge": "^6.0.1",
220
220
  "webpackbar": "^7.0.0"
221
221
  },
@@ -51,6 +51,7 @@ export default cloudcmd;
51
51
  export function cloudcmd(params) {
52
52
  const p = params || {};
53
53
  const options = p.config || {};
54
+
54
55
  const config = p.configManager || createConfig({
55
56
  configPath,
56
57
  });
package/server/columns.js CHANGED
@@ -35,6 +35,7 @@ export const getColumns = ({isDev = _isDev()} = {}) => {
35
35
  const readFilesSyncMemo = nanomemoize((isDev) => {
36
36
  const dist = getDist(isDev);
37
37
  const columnsDir = path.join(__dirname, '..', dist, 'columns');
38
+
38
39
  const names = fs
39
40
  .readdirSync(columnsDir)
40
41
  .filter(not(isMap));
package/server/config.js CHANGED
@@ -197,6 +197,7 @@ function get(manage, request, response) {
197
197
  async function patch(manage, request, response) {
198
198
  const name = 'config.json';
199
199
  const cache = false;
200
+
200
201
  const options = {
201
202
  name,
202
203
  request,
package/server/route.js CHANGED
@@ -65,6 +65,7 @@ export const _getReadDir = getReadDir;
65
65
  async function route({config, options, request, response}) {
66
66
  const name = ponse.getPathName(request);
67
67
  const gzip = true;
68
+
68
69
  const p = {
69
70
  request,
70
71
  response,
package/server/theme.js CHANGED
@@ -24,6 +24,7 @@ export const getThemes = ({isDev = _isDev()} = {}) => {
24
24
  const readFilesSyncMemo = nanomemoize((isDev) => {
25
25
  const dist = getDist(isDev);
26
26
  const themesDir = path.join(__dirname, '..', dist, 'themes');
27
+
27
28
  const names = fs
28
29
  .readdirSync(themesDir)
29
30
  .filter(not(isMap));
@@ -55,6 +55,7 @@ export const columns = (type, overrides = {}) => {
55
55
  } = overrides;
56
56
 
57
57
  const addQuotes = (a) => `"${a}"`;
58
+
58
59
  const all = Object
59
60
  .keys(getColumns())
60
61
  .concat('');
@@ -75,6 +76,7 @@ export const theme = (type, overrides = {}) => {
75
76
  } = overrides;
76
77
 
77
78
  const addQuotes = (a) => `"${a}"`;
79
+
78
80
  const all = Object
79
81
  .keys(getThemes())
80
82
  .concat('');