From 7d55ef06a60ba1cf18ae5bc63113d6fa7490d08a Mon Sep 17 00:00:00 2001 From: muwoo <2424880409@qq.com> Date: Fri, 2 Jul 2021 17:12:38 +0800 Subject: [PATCH 01/14] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=BF=AB?= =?UTF-8?q?=E6=8D=B7=E9=94=AE=E8=AE=BE=E7=BD=AE;=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=B6=85=E7=BA=A7=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 + src/main/browsers/index.js | 1 + src/main/browsers/superPanel.js | 54 +++++ src/main/common/common.js | 87 +++++++- src/main/common/config.js | 9 +- src/renderer/App.vue | 14 +- src/renderer/assets/common/utils.js | 29 ++- src/renderer/assets/keycode.js | 194 +++++------------- src/renderer/pages/plugins/index.vue | 10 +- .../pages/search/subpages/settings.vue | 42 +++- src/renderer/store/modules/main.js | 17 +- static/plugins/superPanel/assets/link.png | Bin 0 -> 1049 bytes static/plugins/superPanel/assets/logo.png | Bin 0 -> 8013 bytes static/plugins/superPanel/assets/new.png | Bin 0 -> 345 bytes static/plugins/superPanel/assets/terminal.png | Bin 0 -> 309 bytes static/plugins/superPanel/index.html | 101 +++++++++ static/plugins/superPanel/index.js | 185 +++++++++++++++++ static/preload.js | 11 +- 18 files changed, 586 insertions(+), 172 deletions(-) create mode 100644 src/main/browsers/superPanel.js create mode 100644 static/plugins/superPanel/assets/link.png create mode 100644 static/plugins/superPanel/assets/logo.png create mode 100644 static/plugins/superPanel/assets/new.png create mode 100644 static/plugins/superPanel/assets/terminal.png create mode 100644 static/plugins/superPanel/index.html create mode 100644 static/plugins/superPanel/index.js diff --git a/package.json b/package.json index 40d85db..2c47471 100644 --- a/package.json +++ b/package.json @@ -62,13 +62,17 @@ "download": "^8.0.0", "download-git-repo": "^3.0.2", "electron-store": "^8.0.0", + "is-chinese": "^1.4.2", "keycode": "^2.2.0", "marked": "^2.0.7", + "md5": "^2.3.0", + "mime-types": "^2.1.31", "node-fetch": "^2.6.1", "osx-mouse": "git+https://github.com/Toinane/osx-mouse.git", "puppeteer-core": "^10.0.0", "puppeteer-in-electron": "^3.0.3", "query-string": "^7.0.0", + "request-promise": "^4.2.6", "robotjs": "git+ssh://git@github.com/Toinane/robotjs.git", "semver": "^7.3.5", "sudo-prompt": "^9.2.1", diff --git a/src/main/browsers/index.js b/src/main/browsers/index.js index d2d059d..1c095bb 100644 --- a/src/main/browsers/index.js +++ b/src/main/browsers/index.js @@ -2,4 +2,5 @@ module.exports = () => ({ picker: require("./picker")(), separator: require("./separate")(), capture: require("./capture")(), + superPanel: require("./superPanel")(), }); diff --git a/src/main/browsers/superPanel.js b/src/main/browsers/superPanel.js new file mode 100644 index 0000000..6113bcd --- /dev/null +++ b/src/main/browsers/superPanel.js @@ -0,0 +1,54 @@ +const { BrowserWindow, ipcMain, app } = require("electron"); + +module.exports = () => { + let win; + + let init = (mainWindow) => { + if (win === null || win === undefined) { + createWindow(); + ipcMain.on('superPanel-hidden', () => { + win.hide(); + }); + ipcMain.on('superPanel-setSize', (e, height) => { + win.setSize(250, height); + }); + ipcMain.on('superPanel-openPlugin', (e, args) => { + mainWindow.webContents.send('superPanel-openPlugin', args); + }); + } + }; + + let createWindow = () => { + win = new BrowserWindow({ + frame: false, + autoHideMenuBar: true, + width: 250, + height: 50, + show: false, + alwaysOnTop: true, + webPreferences: { + webSecurity: false, + enableRemoteModule: true, + backgroundThrottling: false, + nodeIntegration: true, + devTools: false, + }, + }); + win.loadURL(`file://${__static}/plugins/superPanel/index.html`); + win.once('ready-to-show', () => win.show()); + win.on("closed", () => { + win = undefined; + }); + // 打包后,失焦隐藏 + win.on('blur', () => { + win.hide(); + }); + }; + + let getWindow = () => win; + + return { + init: init, + getWindow: getWindow, + }; +}; diff --git a/src/main/common/common.js b/src/main/common/common.js index 610aaee..336d7c7 100644 --- a/src/main/common/common.js +++ b/src/main/common/common.js @@ -4,6 +4,7 @@ import { BrowserWindow, clipboard, Notification, + app, } from 'electron'; import Api from './api'; import robot from 'robotjs'; @@ -11,7 +12,9 @@ import './config'; const browsers = require("../browsers")(); const mouseEvents = require("osx-mouse"); -const {picker, separator} = browsers; +const {picker, separator, superPanel} = browsers; +// 需要在超级面板展示的插件 +let optionPlugin = []; let closePicker = (newColor) => { if (picker.getWindow()) { @@ -34,18 +37,88 @@ function registerShortCut(mainWindow) { }); } +const getSelectedText = () => { + return new Promise((resolve) => { + const lastText = clipboard.readText('clipboard'); + + const platform = process.platform; + if (platform === 'darwin') { + robot.keyTap('c', 'command'); + } else { + robot.keyTap('c', 'control'); + } + + setTimeout(() => { + const text = clipboard.readText('clipboard') || '' + const fileUrl = clipboard.read('public.file-url'); + clipboard.writeText(lastText); + + resolve({ + text, + fileUrl + }) + }, 100); + }) +} + export default function init(mainWindow) { + ipcMain.on('optionPlugin', (e, args) => { + optionPlugin = args; + }); const mouseTrack = mouseEvents(); let down_time = 0; + let isPress = false; mouseTrack.on('right-down', () => { + isPress = true; down_time = Date.now(); + const config = global.opConfig.get(); + setTimeout(async () => { + if (isPress) { + const copyResult = await getSelectedText(); + let win = superPanel.getWindow(); + + if (win) { + win.webContents.send('trigger-super-panel', { + ...copyResult, + optionPlugin: optionPlugin.plugins, + }); + } else { + superPanel.init(mainWindow); + win = superPanel.getWindow(); + + win.once('ready-to-show', () => { + win.webContents.send('trigger-super-panel', { + ...copyResult, + optionPlugin: optionPlugin.plugins, + }); + }); + } + const pos = robot.getMousePos(); + win.setPosition(parseInt(pos.x), parseInt(pos.y)); + win.show(); + } + }, config.superPanel.mouseDownTime); }) mouseTrack.on('right-up', () => { - if ((Date.now() - down_time) > 1000) { - new Notification({ title: 'Rubick 通知', body: '长按了' }).show(); + isPress = false; + }); + + // 注册快捷键 + registerShortCut(mainWindow); + + // 设置开机启动 + const config = global.opConfig.get(); + app.setLoginItemSettings({ + openAtLogin: config.perf.common.start, + openAsHidden: true, + }); + + mainWindow.once("ready-to-show", () => { + // 非隐藏式启动需要显示主窗口 + if (!app.getLoginItemSettings().wasOpenedAsHidden) { + mainWindow.show(); } }); - registerShortCut(mainWindow); ipcMain.on('re-register', (event, arg) => { registerShortCut(mainWindow); @@ -55,10 +128,12 @@ export default function init(mainWindow) { mainWindow.setSize(arg.width || 800, arg.height); }); + // 打包后,失焦隐藏 mainWindow.on('blur', () => { - mainWindow.hide(); + app.isPackaged && mainWindow.hide(); }); + // 响应 preload.js 事件 ipcMain.on('msg-trigger', async (event, arg) => { const window = arg.winId ? BrowserWindow.fromId(arg.winId) : mainWindow const operators = arg.type.split('.'); @@ -70,6 +145,7 @@ export default function init(mainWindow) { event.sender.send(`msg-back-${arg.type}`, data); }); + // 窗口分离 ipcMain.on('new-window', (event, arg) => { const opts = { ...arg, @@ -78,6 +154,7 @@ export default function init(mainWindow) { separator.init(opts); }); + // 拾色器 ipcMain.on('start-picker', () => { const mouseTrack = mouseEvents(); picker.init(); diff --git a/src/main/common/config.js b/src/main/common/config.js index c5e8b5a..028ad1b 100644 --- a/src/main/common/config.js +++ b/src/main/common/config.js @@ -20,9 +20,15 @@ let defaultConfig = { search: true, } }, + superPanel: { + baiduAPI: { + key: '', + appid: '', + }, + mouseDownTime: 500 + } } } - global.opConfig = { config: null, get() { @@ -38,7 +44,6 @@ global.opConfig = { } }, set(key, value) { - console.log(opConfig.config); opConfig.config[key] = value; fs.writeFileSync(configPath, JSON.stringify(opConfig.config)); } diff --git a/src/renderer/App.vue b/src/renderer/App.vue index 6a23680..09f51f9 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -80,15 +80,23 @@ export default { } }, mounted() { - // 注册快捷键 - ipcRenderer.send('init-shortcut'); ipcRenderer.on('init-rubick', this.closeTag); ipcRenderer.on('new-window', this.newWindow); + // 超级面板打开插件 + ipcRenderer.on('superPanel-openPlugin', (e, args) => { + this.openPlugin({ + cmd: args.cmd, + plugin: args.plugin, + feature: args.feature, + router: this.$router, + payload: args.data, + }) + }); const searchNd = document.getElementById('search'); searchNd && searchNd.addEventListener('keydown', this.checkNeedInit) }, methods: { - ...mapActions('main', ['onSearch', 'showMainUI']), + ...mapActions('main', ['onSearch', 'showMainUI', 'openPlugin']), ...mapMutations('main', ['commonUpdate']), search(v) { if (!this.searchFn) { diff --git a/src/renderer/assets/common/utils.js b/src/renderer/assets/common/utils.js index d233181..1668661 100644 --- a/src/renderer/assets/common/utils.js +++ b/src/renderer/assets/common/utils.js @@ -4,7 +4,7 @@ import fs from 'fs'; import process from 'child_process'; import Store from 'electron-store'; import downloadFile from 'download'; -import {nativeImage} from 'electron'; +import {nativeImage, ipcRenderer} from 'electron'; import {APP_FINDER_PATH} from './constans'; import {getlocalDataFile} from "../../../main/common/utils"; @@ -57,6 +57,19 @@ async function downloadZip(downloadRepoUrl, name) { const sysFile = { savePlugins(plugins) { + ipcRenderer.send('optionPlugin', { + plugins: plugins.filter((plugin) => { + let hasOption = false; + plugin.features.forEach(fe => { + fe.cmds.forEach(cmd => { + if (cmd.type) { + hasOption = true; + } + }) + }); + return hasOption; + }) + }); store.set('user-plugins', plugins); }, getUserPlugins() { @@ -72,7 +85,7 @@ const sysFile = { } function mergePlugins(plugins) { - return [ + const result = [ ...plugins, ...SYSTEM_PLUGINS.map(plugin => { return { @@ -81,8 +94,18 @@ function mergePlugins(plugins) { sourceFile: '', type: 'system', } - }), + }) ] + + return result.filter((item, i) => { + let targetIndex; + result.forEach((tg, j) => { + if (tg.tag === item.tag && tg.type === 'system') { + targetIndex = j + } + }); + return i === targetIndex; + }); } function find(p, target = 'plugin.json') { diff --git a/src/renderer/assets/keycode.js b/src/renderer/assets/keycode.js index 13adf27..59fcc11 100644 --- a/src/renderer/assets/keycode.js +++ b/src/renderer/assets/keycode.js @@ -18,19 +18,14 @@ export default { 32: 'space', 33: 'page up', 34: 'page down', - 35: 'end', - 36: 'home', - 37: 'left arrow', - 38: 'up arrow', - 39: 'right arrow', - 40: 'down arrow', - 41: 'select', - 42: 'print', - 43: 'execute', - 44: 'Print Screen', - 45: 'insert', - 46: 'delete', - 47: 'help', + 35: 'End', + 36: 'Home', + 37: 'Left', + 38: 'Up', + 39: 'Right', + 40: 'Down', + 45: 'Insert', + 46: 'Delete', 48: '0', 49: '1', 50: '2', @@ -41,130 +36,55 @@ export default { 55: '7', 56: '8', 57: '9', - 58: ':', - 59: 'semicolon (firefox), equals', - 60: '<', - 61: 'equals (firefox)', - 63: 'ß', - 64: '@ (firefox)', - 65: 'a', - 66: 'b', - 67: 'c', - 68: 'd', - 69: 'e', - 70: 'f', - 71: 'g', - 72: 'h', - 73: 'i', - 74: 'j', - 75: 'k', - 76: 'l', - 77: 'm', - 78: 'n', - 79: 'o', - 80: 'p', - 81: 'q', - 82: 'r', - 83: 's', - 84: 't', - 85: 'u', - 86: 'v', - 87: 'w', - 88: 'x', - 89: 'y', - 90: 'z', - 91: 'Windows Key / Left ⌘ / Chromebook Search key', - 92: 'right window key', - 93: 'Windows Menu / Right ⌘', - 95: 'sleep', - 96: 'numpad 0', - 97: 'numpad 1', - 98: 'numpad 2', - 99: 'numpad 3', - 100: 'numpad 4', - 101: 'numpad 5', - 102: 'numpad 6', - 103: 'numpad 7', - 104: 'numpad 8', - 105: 'numpad 9', - 106: 'multiply', - 107: 'add', - 108: 'numpad period (firefox)', - 109: 'subtract', - 110: 'decimal point', - 111: 'divide', - 112: 'f1', - 113: 'f2', - 114: 'f3', - 115: 'f4', - 116: 'f5', - 117: 'f6', - 118: 'f7', - 119: 'f8', - 120: 'f9', - 121: 'f10', - 122: 'f11', - 123: 'f12', - 124: 'f13', - 125: 'f14', - 126: 'f15', - 127: 'f16', - 128: 'f17', - 129: 'f18', - 130: 'f19', - 131: 'f20', - 132: 'f21', - 133: 'f22', - 134: 'f23', - 135: 'f24', - 136: 'f25', - 137: 'f26', - 138: 'f27', - 139: 'f28', - 140: 'f29', - 141: 'f30', - 142: 'f31', - 143: 'f32', - 144: 'num lock', - 145: 'scroll lock', - 151: 'airplane mode', - 160: '^', - 161: '!', - 162: '؛ (arabic semicolon)', - 163: '#', - 164: '$', - 165: 'ù', - 166: 'page backward', - 167: 'page forward', - 168: 'refresh', - 169: 'closing paren (AZERTY)', - 170: '*', - 171: '~ + * key', - 172: 'home key', - 173: 'minus (firefox), mute/unmute', - 174: 'decrease volume level', - 175: 'increase volume level', - 176: 'next', - 177: 'previous', - 178: 'stop', - 179: 'play/pause', - 180: 'e-mail', - 181: 'mute/unmute (firefox)', - 182: 'decrease volume level (firefox)', - 183: 'increase volume level (firefox)', - 186: 'semi-colon / ñ', - 187: 'equal sign', - 188: 'comma', - 189: 'dash', - 190: 'period', - 191: 'forward slash / ç', - 192: 'grave accent / ñ / æ / ö', - 193: '?, / or °', - 194: 'numpad period (chrome)', - 219: 'open bracket', - 220: 'back slash', - 221: 'close bracket / å', - 222: 'single quote / ø / ä', + 65: 'A', + 66: 'B', + 67: 'C', + 68: 'D', + 69: 'E', + 70: 'F', + 71: 'G', + 72: 'H', + 73: 'I', + 74: 'J', + 75: 'K', + 76: 'L', + 77: 'M', + 78: 'N', + 79: 'O', + 80: 'P', + 81: 'Q', + 82: 'R', + 83: 'S', + 84: 'T', + 85: 'U', + 86: 'V', + 87: 'W', + 88: 'X', + 89: 'Y', + 90: 'Z', + 112: 'F1', + 113: 'F2', + 114: 'F3', + 115: 'F4', + 116: 'F5', + 117: 'F6', + 118: 'F7', + 119: 'F8', + 120: 'F9', + 121: 'F10', + 122: 'F11', + 123: 'F12', + 186: ';', + 187: '=', + 188: ',', + 189: '-', + 190: '.', + 191: '/', + 192: '`', + 219: '[', + 220: '\\', + 221: ']', + 222: "'", 223: '`', 224: 'left or right ⌘ key (firefox)', 225: 'altgr', diff --git a/src/renderer/pages/plugins/index.vue b/src/renderer/pages/plugins/index.vue index adf872e..2d7b895 100644 --- a/src/renderer/pages/plugins/index.vue +++ b/src/renderer/pages/plugins/index.vue @@ -30,8 +30,8 @@ export default { mounted() { this.webview = document.querySelector('webview'); this.webview.addEventListener('dom-ready', () => { - this.webview.send('onPluginReady', this.$route.query); - this.webview.send('onPluginEnter', this.$route.query); + this.webview.send('onPluginReady', this.pluginInfo); + this.webview.send('onPluginEnter', this.pluginInfo); }); this.setSubPlaceHolder('Hi, Rubick'); this.webview.addEventListener('ipc-message', (event) => { @@ -74,14 +74,16 @@ export default { ...mapMutations('main', ['setSubPlaceHolder', 'commonUpdate']), }, beforeRouteUpdate() { - this.path = `File://${this.$route.query.sourceFile}` + this.path = `File://${this.$route.query.sourceFile}`; + console.log(this.pluginInfo) + this.webview.send('onPluginEnter', this.pluginInfo); }, beforeDestroy() { const webview = document.querySelector('webview'); webview && webview.send('onPluginOut', this.$route.query) }, computed: { - ...mapState('main', ['searchValue', 'devPlugins']), + ...mapState('main', ['searchValue', 'devPlugins', 'pluginInfo']), pluginDetail() { return (this.devPlugins.filter(plugin => plugin.name === this.query.name)[0] || {}).features }, diff --git a/src/renderer/pages/search/subpages/settings.vue b/src/renderer/pages/search/subpages/settings.vue index 589bdf8..7302761 100644 --- a/src/renderer/pages/search/subpages/settings.vue +++ b/src/renderer/pages/search/subpages/settings.vue @@ -6,13 +6,7 @@ 偏好设置 - 本地启动文件 - - - 全局快捷键 - - - 所有关键字 + 超级面板
@@ -47,6 +41,30 @@
+
+
+
弹出面板
+ + 长按鼠标右键 + +
+
+
长按以下设置的毫秒响应
+ +
+
+
百度搜索配置
+ + + + + + + + +
+ +
@@ -63,7 +81,7 @@ export default { data() { return { currentSelect: [0], - config: JSON.parse(JSON.stringify(opConfig.get())) + config: JSON.parse(JSON.stringify(opConfig.get())), } }, methods: { @@ -96,6 +114,7 @@ export default { deep: true, handler() { opConfig.set('perf', this.config.perf); + opConfig.set('superPanel', this.config.superPanel); ipcRenderer.send('re-register'); } } @@ -111,14 +130,19 @@ export default { height: 100%; display: flex; align-items: flex-start; - background: #F8FAFC; + background: #fff; } .settings-detail { padding: 20px; box-sizing: border-box; flex: 1; + overflow: auto; + height: 100%; .setting-item { margin-bottom: 20px; + .ant-form-item { + margin-bottom: 0; + } .title { color: #6C9FE2; font-size: 15px; diff --git a/src/renderer/store/modules/main.js b/src/renderer/store/modules/main.js index f840c1c..eb667f1 100644 --- a/src/renderer/store/modules/main.js +++ b/src/renderer/store/modules/main.js @@ -22,6 +22,7 @@ const state = { searchValue: '', devPlugins: mergePlugins(sysFile.getUserPlugins() || []), subPlaceHolder: '', + pluginInfo: {}, } const mutations = { @@ -29,7 +30,7 @@ const mutations = { Object.keys(payload).forEach((key) => { state[key] = payload[key]; if (key === 'devPlugins') { - sysFile.savePlugins(payload) + sysFile.savePlugins(payload[key]) } }); }, @@ -236,7 +237,7 @@ const actions = { devPlugins: [pluginConfig, ...state.devPlugins], }); }, - openPlugin({commit}, {cmd, plugin, feature, router}) { + openPlugin({commit}, {cmd, plugin, feature, router, payload}) { if (plugin.type === 'app') { execSync(plugin.action); commit('commonUpdate', { @@ -253,7 +254,7 @@ const actions = { commit('commonUpdate', { selected: { key: 'plugin-container', - name: cmd, + name: cmd.label ? cmd.label : cmd, icon: 'image://' + path.join(plugin.sourceFile, `../${plugin.logo}`), }, searchValue: '', @@ -277,10 +278,20 @@ const actions = { }); return; } + commit('commonUpdate', { + pluginInfo: { + cmd, + ...plugin, + detail: feature, + payload, + } + }); + router.push({ path: '/plugin', query: { ...plugin, + _modify: Date.now(), detail: JSON.stringify(feature) }, }) diff --git a/static/plugins/superPanel/assets/link.png b/static/plugins/superPanel/assets/link.png new file mode 100644 index 0000000000000000000000000000000000000000..e14799b25be21efd9daa9c2d87f359a8bdcbe5c4 GIT binary patch literal 1049 zcmV+!1m^pRP)--W9ml-H5VZi|Zj|?my58 z$Zq$W5N}yTKJ$J5*f>$O*87O)1po&Vb}J&XqLlg`z=d9~_erDT&oNowWSRu}F_(yFvD4{% zo`xfpfY$mUBKmj&;LbE}2^}M%M*z%E5?@62`@X-N^w~h5(P-=p!|*f_-5NI*k#j_J zRz$vXV13{JWfA~cww~whR!Yr_$UG4}3*g3tkDKoRGyf2OKSZEjuWzkXDjxyZn*e`2 z48z54xBFKXkZFuJo6S3Vz21>^BJq&RVHnnzmX-81oZ=+hTDKF>}j34@$^ddrCwO|CiM7W3kr0B_dD62(*~_&=3J* zj3ktMl$qbpQd4W~+Tu%Dc4^~zOH^xJBcjvs7|eV{{6Pki1e8+uwA<}-S-?_=XSocG z_koOas?}=MYPEW4A_8k`Yt=k$vmk-X%zQ%@V{7fbBJyPxfnNdqySj`S;{};x zalj(-r0@H0&w_;KdG{-&+=ew!AHZM_*g!yQy@QC{g=27>a7H3>a&B(!M61>MaWjZC zo6Rj@7``kb&nM=)6h+a2APCM5)@l-v*7`6Jok{`vrz1i{7nD*f?RNW{X_B$lZWodJ z0J!gd0C%Uvf0~)!jK3dsp}Csf^;%zOQV*6RuasBW->=1$(v|SYQ}NhKz2|ukRw|X} zM5K|kT&7BZh}vNoz7_<*nNjm+{wv`e8;!;u5vhsD!|NSk8-T5ephZi_-Ll-#eHFlm zN~tq>)>$qBIn|$uSxI0fvd1PZGf-xrpaNwH6%??rdzpd45*7?lW}u*eh28%KNk5@L TCNeB100000NkvXXu0mjf@hI%# literal 0 HcmV?d00001 diff --git a/static/plugins/superPanel/assets/logo.png b/static/plugins/superPanel/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5373de3fd364cf516d057605d38f26dc010ee007 GIT binary patch literal 8013 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 P00000NkvXXu0mjfyUiWd literal 0 HcmV?d00001 diff --git a/static/plugins/superPanel/assets/new.png b/static/plugins/superPanel/assets/new.png new file mode 100644 index 0000000000000000000000000000000000000000..34eb3b7eab5c2108395a4864dcd7acb5cc589e89 GIT binary patch literal 345 zcmV-f0jB-+fEaniRkY;f!nn%u=#d z@ijPmo+PaRGQ|WC+CoUxS-VD^LIPN+fD}M%!NjNs&}%SLRVG#nNCD6K+7+}WT99VVqamdR7pH&1n{HDG=(&U%nWJPU{?vY;=be#I|l?XRUoPYY}I4N rLt`{%LhN1wU@I0nUJ8V+D7)Sl5+00Ed&|}m%k+tLYU!>2Q-K=R^0+P!0?YHlmNr^*EN+u&k0P#|uU10}00000NkvXX Hu0mjf*OGp- literal 0 HcmV?d00001 diff --git a/static/plugins/superPanel/index.html b/static/plugins/superPanel/index.html new file mode 100644 index 0000000..bb05c7b --- /dev/null +++ b/static/plugins/superPanel/index.html @@ -0,0 +1,101 @@ + + + + + Title + + + + + +
+
+ + 选择的文本 {{selectData.text.length}} 个 +
+
+
+
{{trans.src}}
+
n. {{trans.dst}}
+
+
+
+
+ + {{op.name}} +
+
+
+ + diff --git a/static/plugins/superPanel/index.js b/static/plugins/superPanel/index.js new file mode 100644 index 0000000..6314940 --- /dev/null +++ b/static/plugins/superPanel/index.js @@ -0,0 +1,185 @@ +const {ipcRenderer, nativeImage, remote, clipboard} = require('electron') +const md5 = require("md5"); +const rp = require("request-promise"); +const isChinese = require('is-chinese'); +const path = require('path'); +const fs = require('fs'); +const { spawn } = require ('child_process'); +const mineType = require("mime-types"); + +const opConfig = remote.getGlobal('opConfig'); + +new Vue({ + el: '#app', + data: { + code: '', + current: {}, + selectData: { + translate: {}, + optionPlugin: [], + }, + options: { + translate: [], + common: [ + { + type: 'default', + name: '终端中打开', + icon: './assets/terminal.png', + click: (fileUrl) => { + spawn('open', [ '-a', 'Terminal', fileUrl ]); + } + }, + { + type: 'default', + name: '新建文件', + icon: './assets/new.png', + click: (fileUrl) => { + remote.dialog.showSaveDialog({ + title: "请选择要保存的文件名", + buttonLabel: "保存", + defaultPath: fileUrl.replace('file://', ''), + showsTagField: false, + nameFieldLabel: '', + }).then(result => { + fs.writeFileSync(result.filePath, ''); + }); + } + }, + { + type: 'default', + name: '复制当前路径', + icon: './assets/link.png', + click: (fileUrl) => { + clipboard.writeText(fileUrl.replace('file://', '')) + } + } + ], + selected: [ + { + type: 'default', + name: '复制当前路径', + icon: './assets/link.png', + click: (fileUrl) => { + clipboard.writeText(fileUrl.replace('file://', '')) + } + } + ] + }, + targetOptions: [], + }, + created() { + // 简单唤起超级面板 + ipcRenderer.on('trigger-super-panel', (e, args) => { + this.selectData = args; + const ext = path.extname(this.selectData.fileUrl); + // 剪切板只有文本时,显示翻译 + if (!this.selectData.fileUrl) { + const word = this.selectData.text; + const isCh = isChinese(word); + this.translate(word, isCh ? 'en' : 'zh'); + this.targetOptions = this.options.translate; + } else if (!ext || path.parse(this.selectData.fileUrl).base === 'Desktop') { + // 如果在桌面上或者没有选择任何文件,则展示通用选项 + this.targetOptions = this.options.common; + } else { + // 有文件选择 + this.targetOptions = JSON.parse(JSON.stringify(this.options.selected)); + // 检测上传 + (this.selectData.optionPlugin || []).forEach(plugin => { + plugin.features.forEach(fe => { + fe.cmds.forEach(cmd => { + // 如果是图片,则唤起图片选项 + const regImg = /\.(png|jpg|gif|jpeg|webp)$/; + if (cmd.type === 'img' && regImg.test(ext)) { + console.log(plugin); + this.targetOptions.push({ + type: 'ext', + name: cmd.label, + icon: plugin.icon, + click: (fileUrl) => { + const base64 = this.fileToBase64(fileUrl); + ipcRenderer.send('superPanel-openPlugin', { + cmd: cmd, + plugin: plugin, + feature: fe, + data: base64, + }); + } + }) + } + // 如果是文件,且符合文件正则类型 + if (cmd.type === 'file' && new RegExp(cmd.match).test(ext)) { + this.targetOptions.push({ + type: 'ext', + name: cmd.label, + icon: '', + click: () => { + ipcRenderer.send('superPanel-openPlugin', { + cmd: cmd, + plugin: plugin, + feature: fe, + data: { + isFile: true, + isDirectory: false, + name: path.basename(this.selectData.fileUrl), + path: this.selectData.fileUrl + } + }) + } + }) + } + }) + }); + }); + } + }); + + }, + + methods: { + translate(msg, to) { + const {appid, key} = opConfig.get().superPanel.baiduAPI; + if (!appid || !key) return; + const q = msg; + const salt = parseInt(Math.random() * 1000000000); //加盐 + const sign = md5(appid + q + salt + key); //生成签名 + const params = encodeURI( + `q=${q}&from=auto&to=${to}&appid=${appid}&salt=${salt}&sign=${sign}` + ); + const options = { + uri: `https://fanyi-api.baidu.com/api/trans/vip/translate?${params}`, + }; + return rp(options).then((res) => { + this.$set(this.selectData, 'translate', JSON.parse(res).trans_result) + }) + }, + commonClick(item, fileUrl) { + ipcRenderer.send('superPanel-hidden') + item.click(fileUrl); + }, + + fileToBase64 (filePath) { + let data = fs.readFileSync(filePath.replace('file://', '')); + data = new Buffer(data).toString("base64"); + let base64 = "data:" + mineType.lookup(filePath) + ";base64," + data; + return base64; + }, + + openMainWindow() { + ipcRenderer.send('msg-trigger', { + type: 'showMainWindow', + }); + } + }, + + watch: { + selectData: { + deep: true, + handler() { + this.$nextTick(() => { + ipcRenderer.send('superPanel-setSize', parseInt(getComputedStyle(document.getElementById('app')).height)) + }) + } + } + } +}) diff --git a/static/preload.js b/static/preload.js index 1a0a552..090620e 100644 --- a/static/preload.js +++ b/static/preload.js @@ -43,16 +43,15 @@ function convertImgToBase64(url, callback, outputFormat){ window.utools = window.rubick = { // 事件 onPluginEnter(cb) { - ipcRenderer.once('onPluginEnter', (e, message) => { - const feature = JSON.parse(message.detail) - console.log(feature) - cb({...feature, type: 'text'}) + ipcRenderer.on('onPluginEnter', (e, message) => { + const feature = message.detail; + cb({...feature, type: message.cmd.type ? message.cmd.type : 'text', payload: message.payload}) }) }, onPluginReady(cb) { ipcRenderer.once('onPluginReady', (e, message) => { - const feature = JSON.parse(message.detail) - cb({...feature, type: 'text'}) + const feature = message.detail + cb({...feature, type: message.cmd.type ? message.cmd.type : 'text', payload: message.payload}) }) }, onPluginOut(cb) { From 872f21ae17a8b7ca2d7d5ed74a2cb779d1310c57 Mon Sep 17 00:00:00 2001 From: muwoo <2424880409@qq.com> Date: Fri, 2 Jul 2021 17:47:04 +0800 Subject: [PATCH 02/14] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=BF=AB?= =?UTF-8?q?=E6=8D=B7=E9=94=AE=E8=AE=BE=E7=BD=AE;=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=B6=85=E7=BA=A7=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/common/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/common/common.js b/src/main/common/common.js index 336d7c7..9266ea2 100644 --- a/src/main/common/common.js +++ b/src/main/common/common.js @@ -57,7 +57,7 @@ const getSelectedText = () => { text, fileUrl }) - }, 100); + }, 300); }) } From 9ab64bfa445689185605aa26f6fd0dda54092331 Mon Sep 17 00:00:00 2001 From: muwoo <2424880409@qq.com> Date: Sun, 4 Jul 2021 13:54:22 +0800 Subject: [PATCH 03/14] =?UTF-8?q?ref:=20=E6=90=9C=E7=B4=A2=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E4=BC=98=E5=8C=96=EF=BC=8C=E6=94=AF=E6=8C=81=E6=96=B9?= =?UTF-8?q?=E5=90=91=E9=80=89=E6=8B=A9=E6=90=9C=E7=B4=A2=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81enter=E5=9B=9E=E8=BD=A6=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/App.vue | 42 ++++++++++++++++++++++++++-- src/renderer/pages/plugins/index.vue | 5 ---- src/renderer/store/modules/main.js | 4 +-- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/renderer/App.vue b/src/renderer/App.vue index 09f51f9..2bbdbd3 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -19,6 +19,10 @@ @change="e => search({value: e.target.value})" :value="searchValue" :maxLength="selected && selected.key !== 'plugin-container' ? 0 : 1000" + @keydown.down="(e) => changeCurrent(1)" + @keydown.up="() => changeCurrent(-1)" + @keypress.enter="(e) => targetSearch({value: e.target.value, type: 'enter'})" + @keypress.space="(e) => targetSearch({value: e.target.value, type: 'space'})" >
@@ -29,7 +33,12 @@
- + @@ -51,8 +60,10 @@
@@ -68,7 +79,7 @@ import {mapActions, mapMutations, mapState} from "vuex"; import {ipcRenderer, remote} from "electron"; import {getWindowHeight, debounce} from "./assets/common/utils"; - +const opConfig = remote.getGlobal('opConfig'); const {Menu, MenuItem} = remote; export default { @@ -77,6 +88,8 @@ export default { searchType: this.$route.query.searchType ? 'subWindow' : '', query: this.$route.query, searchFn: null, + config: opConfig.get(), + currentSelect: 0, } }, mounted() { @@ -104,6 +117,26 @@ export default { } this.searchFn(v); }, + targetSearch(action) { + // 在插件界面唤起搜索功能 + if((this.selected && this.selected.key === 'plugin-container') || this.searchType === 'subWindow') { + const webview = document.getElementById('webview'); + if (action.type === 'space') { + if (this.config.perf.common.space) { + webview.send('msg-back-setSubInput', this.searchValue); + } + return; + } + webview.send('msg-back-setSubInput', this.searchValue); + } else if (this.showOptions) { + const item = this.options[this.currentSelect] + item.click(this.$router); + } + }, + changeCurrent(index) { + this.currentSelect = this.currentSelect + index; + }, + renderTitle(title) { const result = title.split(this.searchValue); return `
${result[0]}${this.searchValue}${result[1]}
` @@ -242,6 +275,9 @@ export default { max-height: 500px; overflow: auto; background: #fafafa; + &.active { + background: #DEE2E8; + } } } } diff --git a/src/renderer/pages/plugins/index.vue b/src/renderer/pages/plugins/index.vue index 2d7b895..5438094 100644 --- a/src/renderer/pages/plugins/index.vue +++ b/src/renderer/pages/plugins/index.vue @@ -87,11 +87,6 @@ export default { pluginDetail() { return (this.devPlugins.filter(plugin => plugin.name === this.query.name)[0] || {}).features }, - }, - watch: { - searchValue() { - this.webview.send('msg-back-setSubInput', this.searchValue); - } } } diff --git a/src/renderer/store/modules/main.js b/src/renderer/store/modules/main.js index eb667f1..357e790 100644 --- a/src/renderer/store/modules/main.js +++ b/src/renderer/store/modules/main.js @@ -97,9 +97,9 @@ const actions = { return; } const value = paylpad.value; - // 在插件界面 + // 在插件界面不触发其他功能 if((state.selected && state.selected.key === 'plugin-container') || paylpad.searchType === 'subWindow') { - commit('commonUpdate', {searchValue: value}) + commit('commonUpdate', {searchValue: value}); return; } const fileUrl = clipboard.read('public.file-url').replace('file://', ''); From 4c19362f3ca0892371dd4e7d429ec74d14926b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Mon, 5 Jul 2021 09:39:48 +0800 Subject: [PATCH 04/14] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index ff31877..e98724a 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,19 @@ 基于 electron 的工具箱,媲美 utools的开源插件,已实现 utools 大部分的 API 能力,所以可以做到无缝适配 utools 开源的插件。 之所以做这个工具箱一方面是 utools 本身并未开源,但是公司内部的工具库又无法发布到 utools 插件中,所以为了既要享受 utools 生态又要有定制化需求,我们自己参考 utools 设计,做了 Rubick + +## 支持能力 + +- [x] 支持 uTools 官方文档 90% API,还在更新中,很快可以做到 100% +- [x] 插件化支持 uTools 所有开源插件 +- [x] 支持插件分离 +- [x] 支持系统命令取色、截屏、帮助 +- [x] 支持超级面板,长按右击呼出 +- [x] 支持全局快捷键设置 +- [x] 支持搜索本地已安装 app 或 偏好设置 +- [ ] 支持 Windows +- [ ] 支持 Linux + ![image](https://user-images.githubusercontent.com/21073039/122888869-d6e60d00-d374-11eb-9fb9-2a6e541e389e.png) ## utools 插件支持 From 547702dcc768f15e476b8513fa5a563b490d95de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Mon, 5 Jul 2021 09:40:59 +0800 Subject: [PATCH 05/14] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e98724a..2441ca0 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ - [x] 支持 uTools 官方文档 90% API,还在更新中,很快可以做到 100% - [x] 插件化支持 uTools 所有开源插件 +- [x] 支持远程下载安装插件,支持插件开发者模式 - [x] 支持插件分离 - [x] 支持系统命令取色、截屏、帮助 - [x] 支持超级面板,长按右击呼出 From 5315a912bb86124441e9b49ece8889d8f692b352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Mon, 5 Jul 2021 11:50:00 +0800 Subject: [PATCH 06/14] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2441ca0..370c2ca 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ 基于 electron 的工具箱,媲美 utools的开源插件,已实现 utools 大部分的 API 能力,所以可以做到无缝适配 utools 开源的插件。 之所以做这个工具箱一方面是 utools 本身并未开源,但是公司内部的工具库又无法发布到 utools 插件中,所以为了既要享受 utools 生态又要有定制化需求,我们自己参考 utools 设计,做了 Rubick +## 安装包 +* [Mac OS V0.0.1]() ## 支持能力 From 8362c75c04248719a359972d222ab161dd4d5de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Mon, 5 Jul 2021 11:50:36 +0800 Subject: [PATCH 07/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 370c2ca..42e6ad6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ 之所以做这个工具箱一方面是 utools 本身并未开源,但是公司内部的工具库又无法发布到 utools 插件中,所以为了既要享受 utools 生态又要有定制化需求,我们自己参考 utools 设计,做了 Rubick ## 安装包 -* [Mac OS V0.0.1]() +* [Rubick Mac OS V0.0.1](https://github.com/clouDr-f2e/rubick/releases/download/v0.0.1/rubick2-0.0.1.pkg) ## 支持能力 From 7354bd4463bd431be477a6bb9470a75111281707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Mon, 5 Jul 2021 11:52:43 +0800 Subject: [PATCH 08/14] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 42e6ad6..d415034 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ ![image](https://user-images.githubusercontent.com/21073039/122888869-d6e60d00-d374-11eb-9fb9-2a6e541e389e.png) +## 使用问题 +1. 目前 `Rubick` 插件市场 server 端还没有部署,所以目前看不到插件市场的插件。 +2. 依赖于 `robotjs` dev 环境运行请在 `install` 后执行 `npm run rebuild` + ## utools 插件支持 ### plugin.json 在你觉得合适的地方新建一个文件夹,并创建 `plugin.json` 文件。这是最重要的一个文件,用来说明这个插件将如何与 `rubick` 集成,最基本的格式如下: From fccb1aef33ac4feb92d9797472ecae8af942486a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8E=E5=8C=97?= <805408477@qq.com> Date: Mon, 5 Jul 2021 16:44:03 +0800 Subject: [PATCH 09/14] Update package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 2c47471..28adb6b 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "asar": false, "productName": "rubick2", "appId": "com.example.yourapp2", + "compression":"maximum", "directories": { "output": "build" }, From 8f2b28210f1cd0465eb943d23e0346a1d3ca345f Mon Sep 17 00:00:00 2001 From: muwoo <2424880409@qq.com> Date: Mon, 5 Jul 2021 20:23:06 +0800 Subject: [PATCH 10/14] =?UTF-8?q?bugfix:=20os-mouse=20=E5=9C=A8build?= =?UTF-8?q?=E5=90=8E=E6=97=A0=E6=B3=95=E8=8E=B7=E5=8F=96=E9=BC=A0=E6=A0=87?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E3=80=82=E6=94=B9=E4=B8=BA=20iohook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 18 ++- src/main/common/common.js | 55 ++++---- src/main/common/config.js | 8 +- src/main/index.js | 3 +- src/renderer/main.js | 29 ++++- .../pages/search/subpages/settings.vue | 119 ++++++++++++++++++ static/plugins/superPanel/index.html | 7 +- static/plugins/superPanel/vue.min.js | 6 + 8 files changed, 203 insertions(+), 42 deletions(-) create mode 100644 static/plugins/superPanel/vue.min.js diff --git a/package.json b/package.json index 2c47471..913d9ad 100644 --- a/package.json +++ b/package.json @@ -62,16 +62,18 @@ "download": "^8.0.0", "download-git-repo": "^3.0.2", "electron-store": "^8.0.0", + "iohook": "^0.9.3", "is-chinese": "^1.4.2", "keycode": "^2.2.0", "marked": "^2.0.7", "md5": "^2.3.0", "mime-types": "^2.1.31", "node-fetch": "^2.6.1", - "osx-mouse": "git+https://github.com/Toinane/osx-mouse.git", + "osx-mouse": "^2.0.0", "puppeteer-core": "^10.0.0", "puppeteer-in-electron": "^3.0.3", "query-string": "^7.0.0", + "request": "^2.88.2", "request-promise": "^4.2.6", "robotjs": "git+ssh://git@github.com/Toinane/robotjs.git", "semver": "^7.3.5", @@ -112,6 +114,7 @@ "listr": "^0.14.3", "mini-css-extract-plugin": "0.4.0", "multispinner": "^0.2.1", + "node-abi": "^2.30.0", "node-loader": "^0.6.0", "react": "^17.0.2", "style-loader": "^0.21.0", @@ -125,5 +128,18 @@ "webpack-dev-server": "^3.1.4", "webpack-hot-middleware": "^2.22.2", "webpack-merge": "^4.1.3" + }, + "iohook": { + "targets": [ + "node-83", + "electron-85" + ], + "platforms": [ + "darwin" + ], + "arches": [ + "x64", + "ia32" + ] } } diff --git a/src/main/common/common.js b/src/main/common/common.js index 9266ea2..0e7d332 100644 --- a/src/main/common/common.js +++ b/src/main/common/common.js @@ -65,42 +65,29 @@ export default function init(mainWindow) { ipcMain.on('optionPlugin', (e, args) => { optionPlugin = args; }); - const mouseTrack = mouseEvents(); - let down_time = 0; - let isPress = false; - mouseTrack.on('right-down', () => { - isPress = true; - down_time = Date.now(); - const config = global.opConfig.get(); - setTimeout(async () => { - if (isPress) { - const copyResult = await getSelectedText(); - let win = superPanel.getWindow(); + ipcMain.on('right-down', async (e) => { + const copyResult = await getSelectedText(); + let win = superPanel.getWindow(); - if (win) { - win.webContents.send('trigger-super-panel', { - ...copyResult, - optionPlugin: optionPlugin.plugins, - }); - } else { - superPanel.init(mainWindow); - win = superPanel.getWindow(); + if (win) { + win.webContents.send('trigger-super-panel', { + ...copyResult, + optionPlugin: optionPlugin.plugins, + }); + } else { + superPanel.init(mainWindow); + win = superPanel.getWindow(); - win.once('ready-to-show', () => { - win.webContents.send('trigger-super-panel', { - ...copyResult, - optionPlugin: optionPlugin.plugins, - }); - }); - } - const pos = robot.getMousePos(); - win.setPosition(parseInt(pos.x), parseInt(pos.y)); - win.show(); - } - }, config.superPanel.mouseDownTime); - }) - mouseTrack.on('right-up', () => { - isPress = false; + win.once('ready-to-show', () => { + win.webContents.send('trigger-super-panel', { + ...copyResult, + optionPlugin: optionPlugin.plugins, + }); + }); + } + const pos = robot.getMousePos(); + win.setPosition(parseInt(pos.x), parseInt(pos.y)); + win.show(); }); // 注册快捷键 diff --git a/src/main/common/config.js b/src/main/common/config.js index 028ad1b..b574e47 100644 --- a/src/main/common/config.js +++ b/src/main/common/config.js @@ -26,7 +26,8 @@ let defaultConfig = { appid: '', }, mouseDownTime: 500 - } + }, + global: [] } } global.opConfig = { @@ -37,6 +38,11 @@ global.opConfig = { if (!opConfig.config) { opConfig.config = JSON.parse(fs.readFileSync(configPath) || JSON.stringify(defaultConfig[platform])); } + // 重置 + if (!opConfig.config.perf || !opConfig.config.superPanel || !opConfig.config.global) { + opConfig.config = defaultConfig[platform]; + fs.writeFileSync(configPath, JSON.stringify(opConfig.config)); + } return opConfig.config; } catch (e) { opConfig.config = defaultConfig[platform] diff --git a/src/main/index.js b/src/main/index.js index a25a265..8ed5722 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -11,7 +11,8 @@ const {capture} = require("./browsers")(); if (process.env.NODE_ENV !== 'development') { global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\') } - +// to fix https://github.com/electron/electron/issues/18397 +app.allowRendererProcessReuse = false; let mainWindow const winURL = process.env.NODE_ENV === 'development' ? `http://localhost:9080` diff --git a/src/renderer/main.js b/src/renderer/main.js index bb3136b..15c1555 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -1,6 +1,7 @@ import Vue from 'vue' import axios from 'axios' - +import ioHook from 'iohook'; +import {ipcRenderer, remote} from 'electron'; import App from './App' import router from './router' import store from './store' @@ -8,9 +9,11 @@ import Antd from 'ant-design-vue'; import 'ant-design-vue/dist/antd.css'; +const opConfig = remote.getGlobal('opConfig'); + if (!process.env.IS_WEB) Vue.use(require('vue-electron')) Vue.http = Vue.prototype.$http = axios -Vue.config.productionTip = false +Vue.config.productionTip = false; Vue.use(Antd); @@ -20,4 +23,24 @@ new Vue({ router, store, template: '' -}).$mount('#app') +}).$mount('#app'); + +ioHook.start(false); + +let down_time = 0; +let isPress = false; +ioHook.on('mousedown', (e) => { + if (e.button === 1) return; + isPress = true; + down_time = Date.now(); + const config = opConfig.get(); + setTimeout(async () => { + if (isPress) { + ipcRenderer.send('right-down'); + } + }, config.superPanel.mouseDownTime); +}) +ioHook.on('mouseup', (e) => { + if(e.button === 1) return; + isPress = false; +}); diff --git a/src/renderer/pages/search/subpages/settings.vue b/src/renderer/pages/search/subpages/settings.vue index 7302761..80bf9a0 100644 --- a/src/renderer/pages/search/subpages/settings.vue +++ b/src/renderer/pages/search/subpages/settings.vue @@ -8,6 +8,9 @@ 超级面板 + + 全局快捷键 +
@@ -65,6 +68,54 @@
+
+ + +
按下快捷键,自动搜索对应关键字,当关键字结果完全匹配,且结果唯一时,会直接指向该功能。
+

示例

+ + + + +
{{ item.title }}
+
+
+
+
+
+
+
+
快捷键
+ + +
+ {{ item.key }} +
+
+ +
+
+
功能关键字
+ +
+
+
+ 新增全局快捷功能
+
@@ -82,6 +133,16 @@ export default { return { currentSelect: [0], config: JSON.parse(JSON.stringify(opConfig.get())), + examples: [ + { + title: '快捷键 「 Alt + W」 关键字 「 微信」', + desc: '按下Alt + W 直接打开本地微信应用' + }, + { + title: '快捷键 「 Alt + Q」 关键字 「 取色」', + desc: '按下Alt + Q 直接打开屏幕取色功能' + } + ] } }, methods: { @@ -107,6 +168,34 @@ export default { this.config.perf.shortCut[key] = compose; change = true; } + }, + addConfig() { + this.config.global.push({ + key: '', + value: '' + }); + }, + + changeGlobalKey(e, index) { + let compose; + if(e.altKey && e.keyCode !== 18){ + compose = `Option+${keycodes[e.keyCode].toUpperCase()}`; + } + if(e.ctrlKey && e.keyCode !== 17){ + compose = `Ctrl+${keycodes[e.keyCode].toUpperCase()}`; + } + if(e.shiftKey && e.keyCode !== 16){ + compose = `Shift+${keycodes[e.keyCode].toUpperCase()}`; + } + if(e.metaKey && e.keyCode !== 93){ + compose = `Command+${keycodes[e.keyCode].toUpperCase()}`; + } + if (compose) { + this.$set(this.config.global[index], 'key', compose); + } + }, + changeGlobalValue(index, value) { + this.$set(this.config.global[index], 'value', value); } }, watch: { @@ -170,5 +259,35 @@ export default { } } } + .feature-container { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 10px; + font-size: 14px; + .item { + flex: 1; + + } + .short-cut { + margin-left: 20px; + } + .value { + text-align: center; + border: 1px solid #ddd; + color: #6C9FE2; + font-size: 14px; + height: 24px; + font-weight: lighter; + margin-top: 10px; + } + } + .add-global { + color: #6C9FE2; + margin-top: 20px; + width: 100%; + text-align: center; + cursor: pointer; + } } diff --git a/static/plugins/superPanel/index.html b/static/plugins/superPanel/index.html index bb05c7b..3166fc9 100644 --- a/static/plugins/superPanel/index.html +++ b/static/plugins/superPanel/index.html @@ -4,12 +4,15 @@ Title - + -
+
选择的文本 {{selectData.text.length}} 个 diff --git a/static/plugins/superPanel/vue.min.js b/static/plugins/superPanel/vue.min.js new file mode 100644 index 0000000..5fa4a26 --- /dev/null +++ b/static/plugins/superPanel/vue.min.js @@ -0,0 +1,6 @@ +/*! + * Vue.js v2.6.12 + * (c) 2014-2020 Evan You + * Released under the MIT License. + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Vue=t()}(this,function(){"use strict";var e=Object.freeze({});function t(e){return null==e}function n(e){return null!=e}function r(e){return!0===e}function i(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function o(e){return null!==e&&"object"==typeof e}var a=Object.prototype.toString;function s(e){return"[object Object]"===a.call(e)}function c(e){var t=parseFloat(String(e));return t>=0&&Math.floor(t)===t&&isFinite(e)}function u(e){return n(e)&&"function"==typeof e.then&&"function"==typeof e.catch}function l(e){return null==e?"":Array.isArray(e)||s(e)&&e.toString===a?JSON.stringify(e,null,2):String(e)}function f(e){var t=parseFloat(e);return isNaN(t)?e:t}function p(e,t){for(var n=Object.create(null),r=e.split(","),i=0;i-1)return e.splice(n,1)}}var m=Object.prototype.hasOwnProperty;function y(e,t){return m.call(e,t)}function g(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}var _=/-(\w)/g,b=g(function(e){return e.replace(_,function(e,t){return t?t.toUpperCase():""})}),$=g(function(e){return e.charAt(0).toUpperCase()+e.slice(1)}),w=/\B([A-Z])/g,C=g(function(e){return e.replace(w,"-$1").toLowerCase()});var x=Function.prototype.bind?function(e,t){return e.bind(t)}:function(e,t){function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n};function k(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function A(e,t){for(var n in t)e[n]=t[n];return e}function O(e){for(var t={},n=0;n0,Z=J&&J.indexOf("edge/")>0,G=(J&&J.indexOf("android"),J&&/iphone|ipad|ipod|ios/.test(J)||"ios"===K),X=(J&&/chrome\/\d+/.test(J),J&&/phantomjs/.test(J),J&&J.match(/firefox\/(\d+)/)),Y={}.watch,Q=!1;if(z)try{var ee={};Object.defineProperty(ee,"passive",{get:function(){Q=!0}}),window.addEventListener("test-passive",null,ee)}catch(e){}var te=function(){return void 0===B&&(B=!z&&!V&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),B},ne=z&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function re(e){return"function"==typeof e&&/native code/.test(e.toString())}var ie,oe="undefined"!=typeof Symbol&&re(Symbol)&&"undefined"!=typeof Reflect&&re(Reflect.ownKeys);ie="undefined"!=typeof Set&&re(Set)?Set:function(){function e(){this.set=Object.create(null)}return e.prototype.has=function(e){return!0===this.set[e]},e.prototype.add=function(e){this.set[e]=!0},e.prototype.clear=function(){this.set=Object.create(null)},e}();var ae=S,se=0,ce=function(){this.id=se++,this.subs=[]};ce.prototype.addSub=function(e){this.subs.push(e)},ce.prototype.removeSub=function(e){h(this.subs,e)},ce.prototype.depend=function(){ce.target&&ce.target.addDep(this)},ce.prototype.notify=function(){for(var e=this.subs.slice(),t=0,n=e.length;t-1)if(o&&!y(i,"default"))a=!1;else if(""===a||a===C(e)){var c=Pe(String,i.type);(c<0||s0&&(st((u=e(u,(a||"")+"_"+c))[0])&&st(f)&&(s[l]=he(f.text+u[0].text),u.shift()),s.push.apply(s,u)):i(u)?st(f)?s[l]=he(f.text+u):""!==u&&s.push(he(u)):st(u)&&st(f)?s[l]=he(f.text+u.text):(r(o._isVList)&&n(u.tag)&&t(u.key)&&n(a)&&(u.key="__vlist"+a+"_"+c+"__"),s.push(u)));return s}(e):void 0}function st(e){return n(e)&&n(e.text)&&!1===e.isComment}function ct(e,t){if(e){for(var n=Object.create(null),r=oe?Reflect.ownKeys(e):Object.keys(e),i=0;i0,a=t?!!t.$stable:!o,s=t&&t.$key;if(t){if(t._normalized)return t._normalized;if(a&&r&&r!==e&&s===r.$key&&!o&&!r.$hasNormal)return r;for(var c in i={},t)t[c]&&"$"!==c[0]&&(i[c]=pt(n,c,t[c]))}else i={};for(var u in n)u in i||(i[u]=dt(n,u));return t&&Object.isExtensible(t)&&(t._normalized=i),R(i,"$stable",a),R(i,"$key",s),R(i,"$hasNormal",o),i}function pt(e,t,n){var r=function(){var e=arguments.length?n.apply(null,arguments):n({});return(e=e&&"object"==typeof e&&!Array.isArray(e)?[e]:at(e))&&(0===e.length||1===e.length&&e[0].isComment)?void 0:e};return n.proxy&&Object.defineProperty(e,t,{get:r,enumerable:!0,configurable:!0}),r}function dt(e,t){return function(){return e[t]}}function vt(e,t){var r,i,a,s,c;if(Array.isArray(e)||"string"==typeof e)for(r=new Array(e.length),i=0,a=e.length;idocument.createEvent("Event").timeStamp&&(sn=function(){return cn.now()})}function un(){var e,t;for(an=sn(),rn=!0,Qt.sort(function(e,t){return e.id-t.id}),on=0;onon&&Qt[n].id>e.id;)n--;Qt.splice(n+1,0,e)}else Qt.push(e);nn||(nn=!0,Ye(un))}}(this)},fn.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||o(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){Re(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},fn.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},fn.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},fn.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||h(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var pn={enumerable:!0,configurable:!0,get:S,set:S};function dn(e,t,n){pn.get=function(){return this[t][n]},pn.set=function(e){this[t][n]=e},Object.defineProperty(e,n,pn)}function vn(e){e._watchers=[];var t=e.$options;t.props&&function(e,t){var n=e.$options.propsData||{},r=e._props={},i=e.$options._propKeys=[];e.$parent&&$e(!1);var o=function(o){i.push(o);var a=Me(o,t,n,e);xe(r,o,a),o in e||dn(e,"_props",o)};for(var a in t)o(a);$e(!0)}(e,t.props),t.methods&&function(e,t){e.$options.props;for(var n in t)e[n]="function"!=typeof t[n]?S:x(t[n],e)}(e,t.methods),t.data?function(e){var t=e.$options.data;s(t=e._data="function"==typeof t?function(e,t){le();try{return e.call(t,t)}catch(e){return Re(e,t,"data()"),{}}finally{fe()}}(t,e):t||{})||(t={});var n=Object.keys(t),r=e.$options.props,i=(e.$options.methods,n.length);for(;i--;){var o=n[i];r&&y(r,o)||(a=void 0,36!==(a=(o+"").charCodeAt(0))&&95!==a&&dn(e,"_data",o))}var a;Ce(t,!0)}(e):Ce(e._data={},!0),t.computed&&function(e,t){var n=e._computedWatchers=Object.create(null),r=te();for(var i in t){var o=t[i],a="function"==typeof o?o:o.get;r||(n[i]=new fn(e,a||S,S,hn)),i in e||mn(e,i,o)}}(e,t.computed),t.watch&&t.watch!==Y&&function(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var i=0;i-1:"string"==typeof e?e.split(",").indexOf(t)>-1:(n=e,"[object RegExp]"===a.call(n)&&e.test(t));var n}function An(e,t){var n=e.cache,r=e.keys,i=e._vnode;for(var o in n){var a=n[o];if(a){var s=xn(a.componentOptions);s&&!t(s)&&On(n,o,r,i)}}}function On(e,t,n,r){var i=e[t];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),e[t]=null,h(n,t)}!function(t){t.prototype._init=function(t){var n=this;n._uid=bn++,n._isVue=!0,t&&t._isComponent?function(e,t){var n=e.$options=Object.create(e.constructor.options),r=t._parentVnode;n.parent=t.parent,n._parentVnode=r;var i=r.componentOptions;n.propsData=i.propsData,n._parentListeners=i.listeners,n._renderChildren=i.children,n._componentTag=i.tag,t.render&&(n.render=t.render,n.staticRenderFns=t.staticRenderFns)}(n,t):n.$options=De($n(n.constructor),t||{},n),n._renderProxy=n,n._self=n,function(e){var t=e.$options,n=t.parent;if(n&&!t.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(e)}e.$parent=n,e.$root=n?n.$root:e,e.$children=[],e.$refs={},e._watcher=null,e._inactive=null,e._directInactive=!1,e._isMounted=!1,e._isDestroyed=!1,e._isBeingDestroyed=!1}(n),function(e){e._events=Object.create(null),e._hasHookEvent=!1;var t=e.$options._parentListeners;t&&qt(e,t)}(n),function(t){t._vnode=null,t._staticTrees=null;var n=t.$options,r=t.$vnode=n._parentVnode,i=r&&r.context;t.$slots=ut(n._renderChildren,i),t.$scopedSlots=e,t._c=function(e,n,r,i){return Pt(t,e,n,r,i,!1)},t.$createElement=function(e,n,r,i){return Pt(t,e,n,r,i,!0)};var o=r&&r.data;xe(t,"$attrs",o&&o.attrs||e,null,!0),xe(t,"$listeners",n._parentListeners||e,null,!0)}(n),Yt(n,"beforeCreate"),function(e){var t=ct(e.$options.inject,e);t&&($e(!1),Object.keys(t).forEach(function(n){xe(e,n,t[n])}),$e(!0))}(n),vn(n),function(e){var t=e.$options.provide;t&&(e._provided="function"==typeof t?t.call(e):t)}(n),Yt(n,"created"),n.$options.el&&n.$mount(n.$options.el)}}(wn),function(e){var t={get:function(){return this._data}},n={get:function(){return this._props}};Object.defineProperty(e.prototype,"$data",t),Object.defineProperty(e.prototype,"$props",n),e.prototype.$set=ke,e.prototype.$delete=Ae,e.prototype.$watch=function(e,t,n){if(s(t))return _n(this,e,t,n);(n=n||{}).user=!0;var r=new fn(this,e,t,n);if(n.immediate)try{t.call(this,r.value)}catch(e){Re(e,this,'callback for immediate watcher "'+r.expression+'"')}return function(){r.teardown()}}}(wn),function(e){var t=/^hook:/;e.prototype.$on=function(e,n){var r=this;if(Array.isArray(e))for(var i=0,o=e.length;i1?k(t):t;for(var n=k(arguments,1),r='event handler for "'+e+'"',i=0,o=t.length;iparseInt(this.max)&&On(a,s[0],s,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}}};!function(e){var t={get:function(){return F}};Object.defineProperty(e,"config",t),e.util={warn:ae,extend:A,mergeOptions:De,defineReactive:xe},e.set=ke,e.delete=Ae,e.nextTick=Ye,e.observable=function(e){return Ce(e),e},e.options=Object.create(null),M.forEach(function(t){e.options[t+"s"]=Object.create(null)}),e.options._base=e,A(e.options.components,Tn),function(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(t.indexOf(e)>-1)return this;var n=k(arguments,1);return n.unshift(this),"function"==typeof e.install?e.install.apply(e,n):"function"==typeof e&&e.apply(null,n),t.push(e),this}}(e),function(e){e.mixin=function(e){return this.options=De(this.options,e),this}}(e),Cn(e),function(e){M.forEach(function(t){e[t]=function(e,n){return n?("component"===t&&s(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&"function"==typeof n&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}})}(e)}(wn),Object.defineProperty(wn.prototype,"$isServer",{get:te}),Object.defineProperty(wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(wn,"FunctionalRenderContext",{value:Tt}),wn.version="2.6.12";var En=p("style,class"),Nn=p("input,textarea,option,select,progress"),jn=function(e,t,n){return"value"===n&&Nn(e)&&"button"!==t||"selected"===n&&"option"===e||"checked"===n&&"input"===e||"muted"===n&&"video"===e},Dn=p("contenteditable,draggable,spellcheck"),Ln=p("events,caret,typing,plaintext-only"),Mn=function(e,t){return Hn(t)||"false"===t?"false":"contenteditable"===e&&Ln(t)?t:"true"},In=p("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),Fn="http://www.w3.org/1999/xlink",Pn=function(e){return":"===e.charAt(5)&&"xlink"===e.slice(0,5)},Rn=function(e){return Pn(e)?e.slice(6,e.length):""},Hn=function(e){return null==e||!1===e};function Bn(e){for(var t=e.data,r=e,i=e;n(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(t=Un(i.data,t));for(;n(r=r.parent);)r&&r.data&&(t=Un(t,r.data));return function(e,t){if(n(e)||n(t))return zn(e,Vn(t));return""}(t.staticClass,t.class)}function Un(e,t){return{staticClass:zn(e.staticClass,t.staticClass),class:n(e.class)?[e.class,t.class]:t.class}}function zn(e,t){return e?t?e+" "+t:e:t||""}function Vn(e){return Array.isArray(e)?function(e){for(var t,r="",i=0,o=e.length;i-1?hr(e,t,n):In(t)?Hn(n)?e.removeAttribute(t):(n="allowfullscreen"===t&&"EMBED"===e.tagName?"true":t,e.setAttribute(t,n)):Dn(t)?e.setAttribute(t,Mn(t,n)):Pn(t)?Hn(n)?e.removeAttributeNS(Fn,Rn(t)):e.setAttributeNS(Fn,t,n):hr(e,t,n)}function hr(e,t,n){if(Hn(n))e.removeAttribute(t);else{if(q&&!W&&"TEXTAREA"===e.tagName&&"placeholder"===t&&""!==n&&!e.__ieph){var r=function(t){t.stopImmediatePropagation(),e.removeEventListener("input",r)};e.addEventListener("input",r),e.__ieph=!0}e.setAttribute(t,n)}}var mr={create:dr,update:dr};function yr(e,r){var i=r.elm,o=r.data,a=e.data;if(!(t(o.staticClass)&&t(o.class)&&(t(a)||t(a.staticClass)&&t(a.class)))){var s=Bn(r),c=i._transitionClasses;n(c)&&(s=zn(s,Vn(c))),s!==i._prevClass&&(i.setAttribute("class",s),i._prevClass=s)}}var gr,_r,br,$r,wr,Cr,xr={create:yr,update:yr},kr=/[\w).+\-_$\]]/;function Ar(e){var t,n,r,i,o,a=!1,s=!1,c=!1,u=!1,l=0,f=0,p=0,d=0;for(r=0;r=0&&" "===(h=e.charAt(v));v--);h&&kr.test(h)||(u=!0)}}else void 0===i?(d=r+1,i=e.slice(0,r).trim()):m();function m(){(o||(o=[])).push(e.slice(d,r).trim()),d=r+1}if(void 0===i?i=e.slice(0,r).trim():0!==d&&m(),o)for(r=0;r-1?{exp:e.slice(0,$r),key:'"'+e.slice($r+1)+'"'}:{exp:e,key:null};_r=e,$r=wr=Cr=0;for(;!zr();)Vr(br=Ur())?Jr(br):91===br&&Kr(br);return{exp:e.slice(0,wr),key:e.slice(wr+1,Cr)}}(e);return null===n.key?e+"="+t:"$set("+n.exp+", "+n.key+", "+t+")"}function Ur(){return _r.charCodeAt(++$r)}function zr(){return $r>=gr}function Vr(e){return 34===e||39===e}function Kr(e){var t=1;for(wr=$r;!zr();)if(Vr(e=Ur()))Jr(e);else if(91===e&&t++,93===e&&t--,0===t){Cr=$r;break}}function Jr(e){for(var t=e;!zr()&&(e=Ur())!==t;);}var qr,Wr="__r",Zr="__c";function Gr(e,t,n){var r=qr;return function i(){null!==t.apply(null,arguments)&&Qr(e,i,n,r)}}var Xr=Ve&&!(X&&Number(X[1])<=53);function Yr(e,t,n,r){if(Xr){var i=an,o=t;t=o._wrapper=function(e){if(e.target===e.currentTarget||e.timeStamp>=i||e.timeStamp<=0||e.target.ownerDocument!==document)return o.apply(this,arguments)}}qr.addEventListener(e,t,Q?{capture:n,passive:r}:n)}function Qr(e,t,n,r){(r||qr).removeEventListener(e,t._wrapper||t,n)}function ei(e,r){if(!t(e.data.on)||!t(r.data.on)){var i=r.data.on||{},o=e.data.on||{};qr=r.elm,function(e){if(n(e[Wr])){var t=q?"change":"input";e[t]=[].concat(e[Wr],e[t]||[]),delete e[Wr]}n(e[Zr])&&(e.change=[].concat(e[Zr],e.change||[]),delete e[Zr])}(i),rt(i,o,Yr,Qr,Gr,r.context),qr=void 0}}var ti,ni={create:ei,update:ei};function ri(e,r){if(!t(e.data.domProps)||!t(r.data.domProps)){var i,o,a=r.elm,s=e.data.domProps||{},c=r.data.domProps||{};for(i in n(c.__ob__)&&(c=r.data.domProps=A({},c)),s)i in c||(a[i]="");for(i in c){if(o=c[i],"textContent"===i||"innerHTML"===i){if(r.children&&(r.children.length=0),o===s[i])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===i&&"PROGRESS"!==a.tagName){a._value=o;var u=t(o)?"":String(o);ii(a,u)&&(a.value=u)}else if("innerHTML"===i&&qn(a.tagName)&&t(a.innerHTML)){(ti=ti||document.createElement("div")).innerHTML=""+o+"";for(var l=ti.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;l.firstChild;)a.appendChild(l.firstChild)}else if(o!==s[i])try{a[i]=o}catch(e){}}}}function ii(e,t){return!e.composing&&("OPTION"===e.tagName||function(e,t){var n=!0;try{n=document.activeElement!==e}catch(e){}return n&&e.value!==t}(e,t)||function(e,t){var r=e.value,i=e._vModifiers;if(n(i)){if(i.number)return f(r)!==f(t);if(i.trim)return r.trim()!==t.trim()}return r!==t}(e,t))}var oi={create:ri,update:ri},ai=g(function(e){var t={},n=/:(.+)/;return e.split(/;(?![^(]*\))/g).forEach(function(e){if(e){var r=e.split(n);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t});function si(e){var t=ci(e.style);return e.staticStyle?A(e.staticStyle,t):t}function ci(e){return Array.isArray(e)?O(e):"string"==typeof e?ai(e):e}var ui,li=/^--/,fi=/\s*!important$/,pi=function(e,t,n){if(li.test(t))e.style.setProperty(t,n);else if(fi.test(n))e.style.setProperty(C(t),n.replace(fi,""),"important");else{var r=vi(t);if(Array.isArray(n))for(var i=0,o=n.length;i-1?t.split(yi).forEach(function(t){return e.classList.add(t)}):e.classList.add(t);else{var n=" "+(e.getAttribute("class")||"")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function _i(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(yi).forEach(function(t){return e.classList.remove(t)}):e.classList.remove(t),e.classList.length||e.removeAttribute("class");else{for(var n=" "+(e.getAttribute("class")||"")+" ",r=" "+t+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?e.setAttribute("class",n):e.removeAttribute("class")}}function bi(e){if(e){if("object"==typeof e){var t={};return!1!==e.css&&A(t,$i(e.name||"v")),A(t,e),t}return"string"==typeof e?$i(e):void 0}}var $i=g(function(e){return{enterClass:e+"-enter",enterToClass:e+"-enter-to",enterActiveClass:e+"-enter-active",leaveClass:e+"-leave",leaveToClass:e+"-leave-to",leaveActiveClass:e+"-leave-active"}}),wi=z&&!W,Ci="transition",xi="animation",ki="transition",Ai="transitionend",Oi="animation",Si="animationend";wi&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(ki="WebkitTransition",Ai="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Oi="WebkitAnimation",Si="webkitAnimationEnd"));var Ti=z?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(e){return e()};function Ei(e){Ti(function(){Ti(e)})}function Ni(e,t){var n=e._transitionClasses||(e._transitionClasses=[]);n.indexOf(t)<0&&(n.push(t),gi(e,t))}function ji(e,t){e._transitionClasses&&h(e._transitionClasses,t),_i(e,t)}function Di(e,t,n){var r=Mi(e,t),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===Ci?Ai:Si,c=0,u=function(){e.removeEventListener(s,l),n()},l=function(t){t.target===e&&++c>=a&&u()};setTimeout(function(){c0&&(n=Ci,l=a,f=o.length):t===xi?u>0&&(n=xi,l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?Ci:xi:null)?n===Ci?o.length:c.length:0,{type:n,timeout:l,propCount:f,hasTransform:n===Ci&&Li.test(r[ki+"Property"])}}function Ii(e,t){for(;e.length1}function Ui(e,t){!0!==t.data.show&&Pi(t)}var zi=function(e){var o,a,s={},c=e.modules,u=e.nodeOps;for(o=0;ov?_(e,t(i[y+1])?null:i[y+1].elm,i,d,y,o):d>y&&$(r,p,v)}(p,h,y,o,l):n(y)?(n(e.text)&&u.setTextContent(p,""),_(p,null,y,0,y.length-1,o)):n(h)?$(h,0,h.length-1):n(e.text)&&u.setTextContent(p,""):e.text!==i.text&&u.setTextContent(p,i.text),n(v)&&n(d=v.hook)&&n(d=d.postpatch)&&d(e,i)}}}function k(e,t,i){if(r(i)&&n(e.parent))e.parent.data.pendingInsert=t;else for(var o=0;o-1,a.selected!==o&&(a.selected=o);else if(N(Wi(a),r))return void(e.selectedIndex!==s&&(e.selectedIndex=s));i||(e.selectedIndex=-1)}}function qi(e,t){return t.every(function(t){return!N(t,e)})}function Wi(e){return"_value"in e?e._value:e.value}function Zi(e){e.target.composing=!0}function Gi(e){e.target.composing&&(e.target.composing=!1,Xi(e.target,"input"))}function Xi(e,t){var n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function Yi(e){return!e.componentInstance||e.data&&e.data.transition?e:Yi(e.componentInstance._vnode)}var Qi={model:Vi,show:{bind:function(e,t,n){var r=t.value,i=(n=Yi(n)).data&&n.data.transition,o=e.__vOriginalDisplay="none"===e.style.display?"":e.style.display;r&&i?(n.data.show=!0,Pi(n,function(){e.style.display=o})):e.style.display=r?o:"none"},update:function(e,t,n){var r=t.value;!r!=!t.oldValue&&((n=Yi(n)).data&&n.data.transition?(n.data.show=!0,r?Pi(n,function(){e.style.display=e.__vOriginalDisplay}):Ri(n,function(){e.style.display="none"})):e.style.display=r?e.__vOriginalDisplay:"none")},unbind:function(e,t,n,r,i){i||(e.style.display=e.__vOriginalDisplay)}}},eo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function to(e){var t=e&&e.componentOptions;return t&&t.Ctor.options.abstract?to(zt(t.children)):e}function no(e){var t={},n=e.$options;for(var r in n.propsData)t[r]=e[r];var i=n._parentListeners;for(var o in i)t[b(o)]=i[o];return t}function ro(e,t){if(/\d-keep-alive$/.test(t.tag))return e("keep-alive",{props:t.componentOptions.propsData})}var io=function(e){return e.tag||Ut(e)},oo=function(e){return"show"===e.name},ao={name:"transition",props:eo,abstract:!0,render:function(e){var t=this,n=this.$slots.default;if(n&&(n=n.filter(io)).length){var r=this.mode,o=n[0];if(function(e){for(;e=e.parent;)if(e.data.transition)return!0}(this.$vnode))return o;var a=to(o);if(!a)return o;if(this._leaving)return ro(e,o);var s="__transition-"+this._uid+"-";a.key=null==a.key?a.isComment?s+"comment":s+a.tag:i(a.key)?0===String(a.key).indexOf(s)?a.key:s+a.key:a.key;var c=(a.data||(a.data={})).transition=no(this),u=this._vnode,l=to(u);if(a.data.directives&&a.data.directives.some(oo)&&(a.data.show=!0),l&&l.data&&!function(e,t){return t.key===e.key&&t.tag===e.tag}(a,l)&&!Ut(l)&&(!l.componentInstance||!l.componentInstance._vnode.isComment)){var f=l.data.transition=A({},c);if("out-in"===r)return this._leaving=!0,it(f,"afterLeave",function(){t._leaving=!1,t.$forceUpdate()}),ro(e,o);if("in-out"===r){if(Ut(a))return u;var p,d=function(){p()};it(c,"afterEnter",d),it(c,"enterCancelled",d),it(f,"delayLeave",function(e){p=e})}}return o}}},so=A({tag:String,moveClass:String},eo);function co(e){e.elm._moveCb&&e.elm._moveCb(),e.elm._enterCb&&e.elm._enterCb()}function uo(e){e.data.newPos=e.elm.getBoundingClientRect()}function lo(e){var t=e.data.pos,n=e.data.newPos,r=t.left-n.left,i=t.top-n.top;if(r||i){e.data.moved=!0;var o=e.elm.style;o.transform=o.WebkitTransform="translate("+r+"px,"+i+"px)",o.transitionDuration="0s"}}delete so.mode;var fo={Transition:ao,TransitionGroup:{props:so,beforeMount:function(){var e=this,t=this._update;this._update=function(n,r){var i=Zt(e);e.__patch__(e._vnode,e.kept,!1,!0),e._vnode=e.kept,i(),t.call(e,n,r)}},render:function(e){for(var t=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,i=this.$slots.default||[],o=this.children=[],a=no(this),s=0;s-1?Gn[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:Gn[e]=/HTMLUnknownElement/.test(t.toString())},A(wn.options.directives,Qi),A(wn.options.components,fo),wn.prototype.__patch__=z?zi:S,wn.prototype.$mount=function(e,t){return function(e,t,n){var r;return e.$el=t,e.$options.render||(e.$options.render=ve),Yt(e,"beforeMount"),r=function(){e._update(e._render(),n)},new fn(e,r,S,{before:function(){e._isMounted&&!e._isDestroyed&&Yt(e,"beforeUpdate")}},!0),n=!1,null==e.$vnode&&(e._isMounted=!0,Yt(e,"mounted")),e}(this,e=e&&z?Yn(e):void 0,t)},z&&setTimeout(function(){F.devtools&&ne&&ne.emit("init",wn)},0);var po=/\{\{((?:.|\r?\n)+?)\}\}/g,vo=/[-.*+?^${}()|[\]\/\\]/g,ho=g(function(e){var t=e[0].replace(vo,"\\$&"),n=e[1].replace(vo,"\\$&");return new RegExp(t+"((?:.|\\n)+?)"+n,"g")});var mo={staticKeys:["staticClass"],transformNode:function(e,t){t.warn;var n=Fr(e,"class");n&&(e.staticClass=JSON.stringify(n));var r=Ir(e,"class",!1);r&&(e.classBinding=r)},genData:function(e){var t="";return e.staticClass&&(t+="staticClass:"+e.staticClass+","),e.classBinding&&(t+="class:"+e.classBinding+","),t}};var yo,go={staticKeys:["staticStyle"],transformNode:function(e,t){t.warn;var n=Fr(e,"style");n&&(e.staticStyle=JSON.stringify(ai(n)));var r=Ir(e,"style",!1);r&&(e.styleBinding=r)},genData:function(e){var t="";return e.staticStyle&&(t+="staticStyle:"+e.staticStyle+","),e.styleBinding&&(t+="style:("+e.styleBinding+"),"),t}},_o=function(e){return(yo=yo||document.createElement("div")).innerHTML=e,yo.textContent},bo=p("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),$o=p("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),wo=p("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),Co=/^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,xo=/^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,ko="[a-zA-Z_][\\-\\.0-9_a-zA-Z"+P.source+"]*",Ao="((?:"+ko+"\\:)?"+ko+")",Oo=new RegExp("^<"+Ao),So=/^\s*(\/?)>/,To=new RegExp("^<\\/"+Ao+"[^>]*>"),Eo=/^]+>/i,No=/^",""":'"',"&":"&"," ":"\n"," ":"\t","'":"'"},Io=/&(?:lt|gt|quot|amp|#39);/g,Fo=/&(?:lt|gt|quot|amp|#39|#10|#9);/g,Po=p("pre,textarea",!0),Ro=function(e,t){return e&&Po(e)&&"\n"===t[0]};function Ho(e,t){var n=t?Fo:Io;return e.replace(n,function(e){return Mo[e]})}var Bo,Uo,zo,Vo,Ko,Jo,qo,Wo,Zo=/^@|^v-on:/,Go=/^v-|^@|^:|^#/,Xo=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,Yo=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Qo=/^\(|\)$/g,ea=/^\[.*\]$/,ta=/:(.*)$/,na=/^:|^\.|^v-bind:/,ra=/\.[^.\]]+(?=[^\]]*$)/g,ia=/^v-slot(:|$)|^#/,oa=/[\r\n]/,aa=/\s+/g,sa=g(_o),ca="_empty_";function ua(e,t,n){return{type:1,tag:e,attrsList:t,attrsMap:ma(t),rawAttrsMap:{},parent:n,children:[]}}function la(e,t){Bo=t.warn||Sr,Jo=t.isPreTag||T,qo=t.mustUseProp||T,Wo=t.getTagNamespace||T;t.isReservedTag;zo=Tr(t.modules,"transformNode"),Vo=Tr(t.modules,"preTransformNode"),Ko=Tr(t.modules,"postTransformNode"),Uo=t.delimiters;var n,r,i=[],o=!1!==t.preserveWhitespace,a=t.whitespace,s=!1,c=!1;function u(e){if(l(e),s||e.processed||(e=fa(e,t)),i.length||e===n||n.if&&(e.elseif||e.else)&&da(n,{exp:e.elseif,block:e}),r&&!e.forbidden)if(e.elseif||e.else)a=e,(u=function(e){var t=e.length;for(;t--;){if(1===e[t].type)return e[t];e.pop()}}(r.children))&&u.if&&da(u,{exp:a.elseif,block:a});else{if(e.slotScope){var o=e.slotTarget||'"default"';(r.scopedSlots||(r.scopedSlots={}))[o]=e}r.children.push(e),e.parent=r}var a,u;e.children=e.children.filter(function(e){return!e.slotScope}),l(e),e.pre&&(s=!1),Jo(e.tag)&&(c=!1);for(var f=0;f]*>)","i")),p=e.replace(f,function(e,n,r){return u=r.length,Do(l)||"noscript"===l||(n=n.replace(//g,"$1").replace(//g,"$1")),Ro(l,n)&&(n=n.slice(1)),t.chars&&t.chars(n),""});c+=e.length-p.length,e=p,A(l,c-u,c)}else{var d=e.indexOf("<");if(0===d){if(No.test(e)){var v=e.indexOf("--\x3e");if(v>=0){t.shouldKeepComment&&t.comment(e.substring(4,v),c,c+v+3),C(v+3);continue}}if(jo.test(e)){var h=e.indexOf("]>");if(h>=0){C(h+2);continue}}var m=e.match(Eo);if(m){C(m[0].length);continue}var y=e.match(To);if(y){var g=c;C(y[0].length),A(y[1],g,c);continue}var _=x();if(_){k(_),Ro(_.tagName,e)&&C(1);continue}}var b=void 0,$=void 0,w=void 0;if(d>=0){for($=e.slice(d);!(To.test($)||Oo.test($)||No.test($)||jo.test($)||(w=$.indexOf("<",1))<0);)d+=w,$=e.slice(d);b=e.substring(0,d)}d<0&&(b=e),b&&C(b.length),t.chars&&b&&t.chars(b,c-b.length,c)}if(e===n){t.chars&&t.chars(e);break}}function C(t){c+=t,e=e.substring(t)}function x(){var t=e.match(Oo);if(t){var n,r,i={tagName:t[1],attrs:[],start:c};for(C(t[0].length);!(n=e.match(So))&&(r=e.match(xo)||e.match(Co));)r.start=c,C(r[0].length),r.end=c,i.attrs.push(r);if(n)return i.unarySlash=n[1],C(n[0].length),i.end=c,i}}function k(e){var n=e.tagName,c=e.unarySlash;o&&("p"===r&&wo(n)&&A(r),s(n)&&r===n&&A(n));for(var u=a(n)||!!c,l=e.attrs.length,f=new Array(l),p=0;p=0&&i[a].lowerCasedTag!==s;a--);else a=0;if(a>=0){for(var u=i.length-1;u>=a;u--)t.end&&t.end(i[u].tag,n,o);i.length=a,r=a&&i[a-1].tag}else"br"===s?t.start&&t.start(e,[],!0,n,o):"p"===s&&(t.start&&t.start(e,[],!1,n,o),t.end&&t.end(e,n,o))}A()}(e,{warn:Bo,expectHTML:t.expectHTML,isUnaryTag:t.isUnaryTag,canBeLeftOpenTag:t.canBeLeftOpenTag,shouldDecodeNewlines:t.shouldDecodeNewlines,shouldDecodeNewlinesForHref:t.shouldDecodeNewlinesForHref,shouldKeepComment:t.comments,outputSourceRange:t.outputSourceRange,start:function(e,o,a,l,f){var p=r&&r.ns||Wo(e);q&&"svg"===p&&(o=function(e){for(var t=[],n=0;nc&&(s.push(o=e.slice(c,i)),a.push(JSON.stringify(o)));var u=Ar(r[1].trim());a.push("_s("+u+")"),s.push({"@binding":u}),c=i+r[0].length}return c-1"+("true"===o?":("+t+")":":_q("+t+","+o+")")),Mr(e,"change","var $$a="+t+",$$el=$event.target,$$c=$$el.checked?("+o+"):("+a+");if(Array.isArray($$a)){var $$v="+(r?"_n("+i+")":i)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+Br(t,"$$a.concat([$$v])")+")}else{$$i>-1&&("+Br(t,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+Br(t,"$$c")+"}",null,!0)}(e,r,i);else if("input"===o&&"radio"===a)!function(e,t,n){var r=n&&n.number,i=Ir(e,"value")||"null";Er(e,"checked","_q("+t+","+(i=r?"_n("+i+")":i)+")"),Mr(e,"change",Br(t,i),null,!0)}(e,r,i);else if("input"===o||"textarea"===o)!function(e,t,n){var r=e.attrsMap.type,i=n||{},o=i.lazy,a=i.number,s=i.trim,c=!o&&"range"!==r,u=o?"change":"range"===r?Wr:"input",l="$event.target.value";s&&(l="$event.target.value.trim()"),a&&(l="_n("+l+")");var f=Br(t,l);c&&(f="if($event.target.composing)return;"+f),Er(e,"value","("+t+")"),Mr(e,u,f,null,!0),(s||a)&&Mr(e,"blur","$forceUpdate()")}(e,r,i);else if(!F.isReservedTag(o))return Hr(e,r,i),!1;return!0},text:function(e,t){t.value&&Er(e,"textContent","_s("+t.value+")",t)},html:function(e,t){t.value&&Er(e,"innerHTML","_s("+t.value+")",t)}},isPreTag:function(e){return"pre"===e},isUnaryTag:bo,mustUseProp:jn,canBeLeftOpenTag:$o,isReservedTag:Wn,getTagNamespace:Zn,staticKeys:function(e){return e.reduce(function(e,t){return e.concat(t.staticKeys||[])},[]).join(",")}(ba)},xa=g(function(e){return p("type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap"+(e?","+e:""))});function ka(e,t){e&&($a=xa(t.staticKeys||""),wa=t.isReservedTag||T,function e(t){t.static=function(e){if(2===e.type)return!1;if(3===e.type)return!0;return!(!e.pre&&(e.hasBindings||e.if||e.for||d(e.tag)||!wa(e.tag)||function(e){for(;e.parent;){if("template"!==(e=e.parent).tag)return!1;if(e.for)return!0}return!1}(e)||!Object.keys(e).every($a)))}(t);if(1===t.type){if(!wa(t.tag)&&"slot"!==t.tag&&null==t.attrsMap["inline-template"])return;for(var n=0,r=t.children.length;n|^function(?:\s+[\w$]+)?\s*\(/,Oa=/\([^)]*?\);*$/,Sa=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,Ta={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},Ea={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:[" ","Spacebar"],up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete","Del"]},Na=function(e){return"if("+e+")return null;"},ja={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:Na("$event.target !== $event.currentTarget"),ctrl:Na("!$event.ctrlKey"),shift:Na("!$event.shiftKey"),alt:Na("!$event.altKey"),meta:Na("!$event.metaKey"),left:Na("'button' in $event && $event.button !== 0"),middle:Na("'button' in $event && $event.button !== 1"),right:Na("'button' in $event && $event.button !== 2")};function Da(e,t){var n=t?"nativeOn:":"on:",r="",i="";for(var o in e){var a=La(e[o]);e[o]&&e[o].dynamic?i+=o+","+a+",":r+='"'+o+'":'+a+","}return r="{"+r.slice(0,-1)+"}",i?n+"_d("+r+",["+i.slice(0,-1)+"])":n+r}function La(e){if(!e)return"function(){}";if(Array.isArray(e))return"["+e.map(function(e){return La(e)}).join(",")+"]";var t=Sa.test(e.value),n=Aa.test(e.value),r=Sa.test(e.value.replace(Oa,""));if(e.modifiers){var i="",o="",a=[];for(var s in e.modifiers)if(ja[s])o+=ja[s],Ta[s]&&a.push(s);else if("exact"===s){var c=e.modifiers;o+=Na(["ctrl","shift","alt","meta"].filter(function(e){return!c[e]}).map(function(e){return"$event."+e+"Key"}).join("||"))}else a.push(s);return a.length&&(i+=function(e){return"if(!$event.type.indexOf('key')&&"+e.map(Ma).join("&&")+")return null;"}(a)),o&&(i+=o),"function($event){"+i+(t?"return "+e.value+"($event)":n?"return ("+e.value+")($event)":r?"return "+e.value:e.value)+"}"}return t||n?e.value:"function($event){"+(r?"return "+e.value:e.value)+"}"}function Ma(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var n=Ta[e],r=Ea[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(n)+",$event.key,"+JSON.stringify(r)+")"}var Ia={on:function(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}},bind:function(e,t){e.wrapData=function(n){return"_b("+n+",'"+e.tag+"',"+t.value+","+(t.modifiers&&t.modifiers.prop?"true":"false")+(t.modifiers&&t.modifiers.sync?",true":"")+")"}},cloak:S},Fa=function(e){this.options=e,this.warn=e.warn||Sr,this.transforms=Tr(e.modules,"transformCode"),this.dataGenFns=Tr(e.modules,"genData"),this.directives=A(A({},Ia),e.directives);var t=e.isReservedTag||T;this.maybeComponent=function(e){return!!e.component||!t(e.tag)},this.onceId=0,this.staticRenderFns=[],this.pre=!1};function Pa(e,t){var n=new Fa(t);return{render:"with(this){return "+(e?Ra(e,n):'_c("div")')+"}",staticRenderFns:n.staticRenderFns}}function Ra(e,t){if(e.parent&&(e.pre=e.pre||e.parent.pre),e.staticRoot&&!e.staticProcessed)return Ha(e,t);if(e.once&&!e.onceProcessed)return Ba(e,t);if(e.for&&!e.forProcessed)return za(e,t);if(e.if&&!e.ifProcessed)return Ua(e,t);if("template"!==e.tag||e.slotTarget||t.pre){if("slot"===e.tag)return function(e,t){var n=e.slotName||'"default"',r=qa(e,t),i="_t("+n+(r?","+r:""),o=e.attrs||e.dynamicAttrs?Ga((e.attrs||[]).concat(e.dynamicAttrs||[]).map(function(e){return{name:b(e.name),value:e.value,dynamic:e.dynamic}})):null,a=e.attrsMap["v-bind"];!o&&!a||r||(i+=",null");o&&(i+=","+o);a&&(i+=(o?"":",null")+","+a);return i+")"}(e,t);var n;if(e.component)n=function(e,t,n){var r=t.inlineTemplate?null:qa(t,n,!0);return"_c("+e+","+Va(t,n)+(r?","+r:"")+")"}(e.component,e,t);else{var r;(!e.plain||e.pre&&t.maybeComponent(e))&&(r=Va(e,t));var i=e.inlineTemplate?null:qa(e,t,!0);n="_c('"+e.tag+"'"+(r?","+r:"")+(i?","+i:"")+")"}for(var o=0;o>>0}(a):"")+")"}(e,e.scopedSlots,t)+","),e.model&&(n+="model:{value:"+e.model.value+",callback:"+e.model.callback+",expression:"+e.model.expression+"},"),e.inlineTemplate){var o=function(e,t){var n=e.children[0];if(n&&1===n.type){var r=Pa(n,t.options);return"inlineTemplate:{render:function(){"+r.render+"},staticRenderFns:["+r.staticRenderFns.map(function(e){return"function(){"+e+"}"}).join(",")+"]}"}}(e,t);o&&(n+=o+",")}return n=n.replace(/,$/,"")+"}",e.dynamicAttrs&&(n="_b("+n+',"'+e.tag+'",'+Ga(e.dynamicAttrs)+")"),e.wrapData&&(n=e.wrapData(n)),e.wrapListeners&&(n=e.wrapListeners(n)),n}function Ka(e){return 1===e.type&&("slot"===e.tag||e.children.some(Ka))}function Ja(e,t){var n=e.attrsMap["slot-scope"];if(e.if&&!e.ifProcessed&&!n)return Ua(e,t,Ja,"null");if(e.for&&!e.forProcessed)return za(e,t,Ja);var r=e.slotScope===ca?"":String(e.slotScope),i="function("+r+"){return "+("template"===e.tag?e.if&&n?"("+e.if+")?"+(qa(e,t)||"undefined")+":undefined":qa(e,t)||"undefined":Ra(e,t))+"}",o=r?"":",proxy:true";return"{key:"+(e.slotTarget||'"default"')+",fn:"+i+o+"}"}function qa(e,t,n,r,i){var o=e.children;if(o.length){var a=o[0];if(1===o.length&&a.for&&"template"!==a.tag&&"slot"!==a.tag){var s=n?t.maybeComponent(a)?",1":",0":"";return""+(r||Ra)(a,t)+s}var c=n?function(e,t){for(var n=0,r=0;r':'
',ts.innerHTML.indexOf(" ")>0}var os=!!z&&is(!1),as=!!z&&is(!0),ss=g(function(e){var t=Yn(e);return t&&t.innerHTML}),cs=wn.prototype.$mount;return wn.prototype.$mount=function(e,t){if((e=e&&Yn(e))===document.body||e===document.documentElement)return this;var n=this.$options;if(!n.render){var r=n.template;if(r)if("string"==typeof r)"#"===r.charAt(0)&&(r=ss(r));else{if(!r.nodeType)return this;r=r.innerHTML}else e&&(r=function(e){if(e.outerHTML)return e.outerHTML;var t=document.createElement("div");return t.appendChild(e.cloneNode(!0)),t.innerHTML}(e));if(r){var i=rs(r,{outputSourceRange:!1,shouldDecodeNewlines:os,shouldDecodeNewlinesForHref:as,delimiters:n.delimiters,comments:n.comments},this),o=i.render,a=i.staticRenderFns;n.render=o,n.staticRenderFns=a}}return cs.call(this,e,t)},wn.compile=rs,wn}); From 6a10fa9f4ceaa3bbfca1272074bacfd66dc53c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Mon, 5 Jul 2021 20:26:34 +0800 Subject: [PATCH 11/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d415034..ce62c45 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ 之所以做这个工具箱一方面是 utools 本身并未开源,但是公司内部的工具库又无法发布到 utools 插件中,所以为了既要享受 utools 生态又要有定制化需求,我们自己参考 utools 设计,做了 Rubick ## 安装包 -* [Rubick Mac OS V0.0.1](https://github.com/clouDr-f2e/rubick/releases/download/v0.0.1/rubick2-0.0.1.pkg) +* [Rubick Mac OS V0.0.1](https://github.com/clouDr-f2e/rubick/releases/download/v0.0.1-beta/rubick2-0.0.1.pkg) ## 支持能力 From f748bfa9c02abd1d4248b543857fabb77b4b1b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Mon, 5 Jul 2021 20:55:23 +0800 Subject: [PATCH 12/14] Update README.md --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce62c45..daf8e30 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,17 @@
-

Rubick

+# Rubick + +

+ + release + + + npm + +

+ 基于 electron 的工具箱,媲美 utools的开源插件,已实现 utools 大部分的 API 能力,所以可以做到无缝适配 utools 开源的插件。 之所以做这个工具箱一方面是 utools 本身并未开源,但是公司内部的工具库又无法发布到 utools 插件中,所以为了既要享受 utools 生态又要有定制化需求,我们自己参考 utools 设计,做了 Rubick @@ -23,7 +33,7 @@ - [ ] 支持 Windows - [ ] 支持 Linux -![image](https://user-images.githubusercontent.com/21073039/122888869-d6e60d00-d374-11eb-9fb9-2a6e541e389e.png) +![example.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/94fe23ead2da4707b88773177a571a07~tplv-k3u1fbpfcp-watermark.image) ## 使用问题 1. 目前 `Rubick` 插件市场 server 端还没有部署,所以目前看不到插件市场的插件。 From 064190c3df113e8bee4145267b3d61731ad94548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Mon, 5 Jul 2021 21:20:50 +0800 Subject: [PATCH 13/14] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index daf8e30..c916a2d 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,10 @@ - [ ] 支持 Windows - [ ] 支持 Linux -![example.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/94fe23ead2da4707b88773177a571a07~tplv-k3u1fbpfcp-watermark.image) + +![QQ20210705-210753](https://user-images.githubusercontent.com/21073039/124477360-8770f980-ddd6-11eb-8dc3-ba318223697f.gif) + + ## 使用问题 1. 目前 `Rubick` 插件市场 server 端还没有部署,所以目前看不到插件市场的插件。 From 08a285ed6e128ac44d7a37c73f715244e15354b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=81=B6?= <2424880409@qq.com> Date: Tue, 6 Jul 2021 09:56:52 +0800 Subject: [PATCH 14/14] Update issue templates --- .github/ISSUE_TEMPLATE/bug-report.md | 24 +++++++++++++++++++ .github/ISSUE_TEMPLATE/development-problem.md | 10 ++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 17 +++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/development-problem.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000..7f7de61 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,24 @@ +--- +name: Bug report +about: 报告一个bug +title: '' +labels: bug +assignees: '' + +--- + +**描述一下这个bug** +清楚而简洁地描述了错误是什么 + +**复现方式** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**预期行为** +清晰简明地描述了您预期的发生。 + +**截图** +如果可以,请添加屏幕截图以帮助解释您的问题。 diff --git a/.github/ISSUE_TEMPLATE/development-problem.md b/.github/ISSUE_TEMPLATE/development-problem.md new file mode 100644 index 0000000..140e48d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/development-problem.md @@ -0,0 +1,10 @@ +--- +name: Development Problem +about: 任何开发建议、使用问题、交流学习都可以 +title: '' +labels: help wanted +assignees: '' + +--- + +## 任何开发建议、交流学习都可以 diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..a7e39dd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: 提交一个新特性/功能 +title: '' +labels: feature +assignees: '' + +--- + +**您的功能请求是否与问题相关? 请简单描述.** +清晰简明地描述问题是什么. Ex. I'm always frustrated when [...] + +**请描述一下您想要的解决方案** +清晰简明地描述您想要发生的事情。 + +**描述你考虑过的替代方案** +清晰简洁地描述您所考虑的任何替代解决方案或功能。