提交 e3a9a78f 编写于 作者: N ninecents

清除代码

上级 b27a1553
name: Build Ctool
on: [ push ]
jobs:
deploy:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 16.x ]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Initialize / Install Dependencies
run: |
mkdir temp_release
npm install
- name: Build web
run: |
npm run build -adapter=web
cp -r ./dist ./dist_gh_pages
cd ./dist
zip -r -q ../temp_release/web.zip ./*
cd ../
unzip -l ./temp_release/web.zip
- name: Build chrome
if: startsWith(github.ref, 'refs/tags/')
run: |
npm run build -adapter=chrome
cd ./dist
zip -r -q ../temp_release/chrome.zip ./*
cd ../
- name: Build utools
if: startsWith(github.ref, 'refs/tags/')
run: |
npm run build -adapter=utools
cd ./dist
zip -r -q ../temp_release/utools.zip ./*
cd ../
- name: Build edge
if: startsWith(github.ref, 'refs/tags/')
run: |
npm run build -adapter=edge
cd ./dist
zip -r -q ../temp_release/edge.zip ./*
cd ../
- name: Build firefox
if: startsWith(github.ref, 'refs/tags/')
run: |
npm run build -adapter=firefox
cd ./dist
zip -r -q ../temp_release/firefox.zip ./*
cd ../
- name: Upload build to github
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
prerelease: true
files: |
./temp_release/web.zip
./temp_release/chrome.zip
./temp_release/utools.zip
./temp_release/edge.zip
./temp_release/firefox.zip
- name: Deploy web to gh-pages
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
publish_dir: ./dist_gh_pages
.DS_Store
/node_modules
/temp_release
/desktop/node_modules
/dist
/public/manifest.json
/public/plugin.json
/public/README.md
/id_rsa.pem
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
test.js
/public/background.js
MIT License
Copyright 2017 baiy
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
# 程序开发常用工具
使用过程中的任何问题或者需要新的工具欢迎提交`Issue`,新工具如果可以提供实现代码就完美了O(∩_∩)O
## 先睹为快
![](https://cdn.jsdelivr.net/gh/baiy/Ctool@master/images/v2_1.png)
## 在线使用
<https://baiy.github.io/Ctool/>
## chrome 安装
-[Chrome 应用商店](https://chrome.google.com/webstore/detail/ipfcebkfhpkjeikaammlkcnalknjahmh) 安装
## 微软 Edge 安装
-[微软 Edge 应用商店](https://microsoftedge.microsoft.com/addons/detail/cihekagpnnadjjplgljkmkpcfiopfplc) 安装
## 火狐 Firefox 安装
-[火狐 Firefox 应用商店](https://addons.mozilla.org/zh-CN/firefox/addon/ctool/) 安装
## utools 安装
- [utools](https://u.tools/) 插件中心 搜索 `ctool`
## 开发
```
# 安装依赖
npm install
# 调试
npm run serve -adapter=[chrome|edge|utools|firefox|web]
# 编译
npm run build -adapter=[chrome|edge|utools|firefox|web]
// 编译输出目录: `/dist/`
```
## 功能列表
| 功能 | 说明 |离线使用|
|--------------|-------------------------------------------------------------------------------------------------------------------------------|---|
| 哈希 | `md5`, `sha1`, `sha256`, `sha512`,`sm3` |√|
| 加密/解密 | `AES`,`DES`,`RC4`,`Rabbit`,`TripleDes`,`sm2`,`sm4` |√|
| BASE64编码 | `加密`,`解密`,`支持文件` |√|
| URL编码 | `编码`,`解码` |√|
| 时间戳 | `双向转换`,`毫秒` |√|
| 二维码 | `生成`,`解析` |√|
| 条形码 | `生成` |√|
| 汉字转拼音 | `声调`,`首字母`,`分隔符` |√|
| IP地址查询 | `运营商`,`城市` |×|
| 代码格式化 | `js`, `ts`, `html`, `css`, `less`, `scss`, `graphql`, `vue`, `angular`, `markdown`, `json5`, `xml`, `yaml`, `sql`, `压缩` |√|
| Unicode | `双向转换`,`emoji`,`html 实体`,`css 实体` |√|
| 进制转换 | `2-64进制` |√|
| 正则表达式 | `匹配`,`查找`,`替换` |√|
| 随机字符生成器 | `批量`,`特殊字符` |√|
| 序列化转换 | `json`, `xml`, `yaml`, `phpArray`, `phpSerialize`, `properties` |√|
| 文本差异化对比 | `行`,`单词`,`css` |√|
| crontab校验 | `Crontab`,`规则`,`校验`,`例子` |√|
| websocket调试 | `websocket`,`在线调试` |×|
| 单位换算 | `长度`,`面积`,`体积`,`质量`,`温度`,`压力`,`功率`,`功`,`密度`,`力`,`时间`,`速度`,`数据存储`,`角度` |√|
| 时间计算器 | - |√|
| JSON工具 | `格式化`,`校验`,`压缩`,`转义`,`去除转义`,`Unicode转中文`,`中文转Unicode`,`转GET参数`,`Java`, `C#`, `Go`, `Dart`,`csv`,`table`,`Protobuf`,`jsonpath` |√|
| UUID | `在线生成uuid` |√|
| ascii编码转换 | `十进制`, `十六进制`, `八进制`, `二进制`, `字符串` |√|
| 变量名格式转换 | `Var Name`, `var-name`, `VAR_NAME`, `VarName`, `varName`, `var_name`, `var name` |√|
| jwt解码 | `header`, `payload` |√|
| Hex/String转换 | `hex to string`, `string to hex`, `十六进制转字符串`, `字符串转十六进制` |√|
| Hex/Base64转换 | `hex to Base64`, `Base64 to hex` |√|
| 文本处理 | `大小写转换`, `中英文标点转换`, `简繁转换`, `替换`, `字符统计`, `行去重`, `添加行号`, `行排序`, `过滤行首尾不可见字符`,`过滤空行` |√|
| html编码 | - |√|
| 原码/反码/补码 | `生成` |√|
| ARM/HEX | `互转` |×|
| Bcrypt | `加密`,`验证` |√|
| IP网络计算器 | `子网掩码各个进制表示换算,IP地址进制表示换算` |√|
## 功能列表-yeahmao
| 功能 | 说明 |离线使用|
|--------------|-------------------------------------------------------------------------------------------------------------------------------|---|
| 字节转码 | `x64dbg拷贝的汇编代码`, `美化后`, `字符串格式`, `字节数组格式`,`` |√|
| 常量查看器 | `winerror.h`, `ntstatus.h` |√|
## 功能列表-代码生成器
| 功能 | 说明 |离线使用|
|--------------|-------------------------------------------------------------------------------------------------------------------------------|---|
| GenJson | `k-v字符串列表转换为json`, `excel表中数据转json` |√|
| GenJava | `超长字符串报错`,`StringBuilder ==> str` |√|
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
{
"name": "c-tool",
"version": "1.11.2",
"private": true,
"scripts": {
"serve": "vue-cli-service serve --port 8081",
"dev": "vue-cli-service serve --port 8081",
"build": "vue-cli-service build --no-module",
"lint": "vue-cli-service lint",
"report": "vue-cli-service build --report"
},
"dependencies": {
"@babel/parser": "^7.17.0",
"@prettier/plugin-php": "^0.17.6",
"@typescript-eslint/typescript-estree": "^5.10.2",
"angular-html-parser": "^1.8.0",
"axios": "^0.21.4",
"babel-runtime": "^6.26.0",
"bcryptjs": "^2.4.3",
"bignumber.js": "^9.0.2",
"camel-case": "^4.1.2",
"chinese-simple2traditional": "^1.0.1",
"code-formatter": "0.0.1",
"codemirror": "^5.65.1",
"codemirror-graphql": "^1.2.11",
"core-js": "^3.8.3",
"cosmiconfig": "^7.0.1",
"cron-parser": "^2.16.3",
"cronstrue": "^1.123.0",
"crypto-js": "^3.3.0",
"csv-parse": "^5.0.4",
"csv-stringify": "^6.0.5",
"darkreader": "^4.9.44",
"diff-match-patch": "^1.0.5",
"file": "^0.2.2",
"file-type": "^16.5.3",
"graphql": "15.7.2",
"hexy": "^0.3.4",
"ipinyinjs": "^1.0.0",
"jimp": "^0.16.1",
"js-base64": "^3.7.2",
"js-htmlencode": "^0.3.0",
"js-yaml": "^3.14.1",
"jsbarcode": "^3.11.5",
"json-to-properties": "^1.1.3",
"json5": "^2.2.0",
"jsonlint": "^1.6.3",
"jsonpath-plus": "^6.0.1",
"jsrsasign": "^10.5.1",
"jsrsasign-util": "^1.0.5",
"jwt-decode": "^3.1.2",
"lodash": "^4.17.21",
"mime-types": "^2.1.34",
"moment": "^2.29.1",
"netmask": "^2.0.2",
"pascal-case": "^3.1.2",
"php-array-reader": "^1.3.2",
"phparr": "^0.2.0",
"pluralize": "^8.0.0",
"postcss": "^8.4.6",
"postcss-less": "^5.0.0",
"postcss-scss": "^4.0.3",
"prettier": "^2.5.1",
"prettier-plugin-sql": "^0.3.0",
"properties-to-json": "^0.1.7",
"qrcode": "^1.5.0",
"qrcode-parser": "^1.2.0",
"qs": "^6.10.3",
"serialize-php": "^1.1.2",
"sm-crypto": "^0.3.7",
"system": "^2.0.1",
"typescript": "^4.5.5",
"uglify-js": "3.14.3",
"uuid": "^8.3.2",
"view-design": "^4.7.0",
"vue": "^2.6.14",
"vue-i18n": "^8.27.0",
"vue-router": "^3.5.3",
"vuedraggable": "^2.24.3",
"x2js": "git+https://gitee.com/ltlwill/x2js.git",
"xml-formatter": "^2.6.1"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"less": "^2.7.0",
"less-loader": "^6.0.0",
"node-polyfill-webpack-plugin": "^1.1.4",
"utools-api-types": "^2.3.0",
"vue-cli-plugin-iview": "~2.0.0",
"vue-template-compiler": "^2.6.14"
},
"eslintConfig": {
"root": true,
"env": {
"node": true,
"webextensions": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {
"no-console": "off",
"vue/no-parsing-error": [
2,
{
"x-invalid-end-tag": false
}
]
},
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"globals": {
"__": "writable"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
# preview.yml
autoOpen: false # 打开工作空间时是否自动开启所有应用的预览
apps:
- port: 8081 # 应用的端口
run: npm i && npm run dev # 应用的启动命
command: # 使用此命令启动服务,且不执行run
root: ./ # 应用的启动目录
name: front_end__ctool # 应用名称
description: 我的第一个 App。 # 应用描述
autoOpen: true # 打开工作空间时是否自动开启预览(优先级高于根级 autoOpen
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>加载中...</title>
<style>
* {
box-sizing: border-box;
}
body{
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="page" style="width: 800px;height: 580px;margin: 0 auto;">
<div style="text-align: center;padding-top: 200px;font-size: 16px;color: #666">加载中...</div>
</div>
<script src=index.js></script>
</body>
</html>
\ No newline at end of file
setTimeout(function () {
window.location.href = "tool.html"
}, 1);
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Ctool 程序开发常用工具</title>
</head>
<body>
<div id="page" style="width: 800px;height: 550px;margin: 0 auto;padding: 0 10px;overflow-y:auto;">
<div id="app"></div>
</div>
<div id="clipboard"></div>
</body>
</html>
{
"name": "__MSG_main_manifest_name__",
"description": "__MSG_main_manifest_description__",
"version": "##version##",
"author": "wo@baiy.org",
"offline_enabled": true,
"homepage_url": "https://github.com/baiy/Ctool",
"manifest_version": 2,
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"browser_action": {
"default_icon": "img/icon_chrome.png",
"default_title": "__MSG_main_manifest_default_title__",
"default_popup": "index.html"
},
"background": {
"scripts": ["background.js"]
},
"icons": {
"16": "img/icon_chrome.png",
"48": "img/icon_chrome.png",
"128": "img/icon_chrome.png"
},
"permissions": [
"clipboardWrite",
"clipboardRead",
"*://get.geojs.io/*",
"*://*.baiy.org/*"
],
"commands": {
"panel": {
"description": "__MSG_main_manifest_commands_panel_description__",
"global": true
}
},
"update_url": "http://clients2.google.com/service/update2/crx"
}
let windowId = null;
// 打开独立窗口
const panel = {
create() {
chrome.windows.create({
url: chrome.runtime.getURL("tool.html"),
type: "popup",
width: 810,
left: 200,
top: 200,
height: 610,
}, (w) => {
windowId = w.id
})
},
open() {
if (windowId === null) {
this.create()
} else {
chrome.windows.get(windowId, (w) => {
if (!w) {
this.create()
} else {
chrome.windows.update(windowId, {focused: true})
}
})
}
},
onRemoved(id) {
if (id === windowId) {
windowId = null;
}
}
}
// 注册快捷键
chrome.commands.onCommand.addListener((command) => {
switch (command) {
case "panel":
panel.open()
break;
default:
return;
}
})
// 窗口关闭事件
chrome.windows.onRemoved.addListener((id) => {
panel.onRemoved(id);
})
export const openUrl = (url) => {
// return chrome.tabs.create();
// return chrome.windows.create();
if (url.indexOf('chrome://') === 0){
return chrome.tabs.create({url:url});
}
return window.open(url);
}
\ No newline at end of file
import lsCache from './lscache'
export default {
get(key, def = null) {
let data = lsCache.get(key)
return data ? data : def
},
set(key, value, expiry = 0) {
return lsCache.set(key, value, expiry / 60)
},
remove(key) {
return lsCache.remove(key)
},
// 清理过期
clear() {
return lsCache.flushExpired()
},
getAllKey() {
return lsCache.getAllKey();
}
}
\ No newline at end of file
/**
* lscache library
* Copyright (c) 2011, Pamela Fox
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* https://github.com/pamelafox/lscache
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* jshint undef:true, browser:true, node:true */
// Prefix for all lscache keys
var CACHE_PREFIX = 'lscache-';
// Suffix for the key name on the expiration items in localStorage
var CACHE_SUFFIX = '-cacheexpiration';
// expiration date radix (set to Base-36 for most space savings)
var EXPIRY_RADIX = 10;
// time resolution in milliseconds
var expiryMilliseconds = 60 * 1000;
// ECMAScript max Date (epoch + 1e8 days)
var maxDate = calculateMaxDate(expiryMilliseconds);
var cachedStorage;
var cachedJSON;
var cacheBucket = '';
var warnings = false;
// Determines if localStorage is supported in the browser;
// result is cached for better performance instead of being run each time.
// Feature detection is based on how Modernizr does it;
// it's not straightforward due to FF4 issues.
// It's not run at parse-time as it takes 200ms in Android.
function supportsStorage() {
var key = '__lscachetest__';
var value = key;
if (cachedStorage !== undefined) {
return cachedStorage;
}
// some browsers will throw an error if you try to access local storage (e.g. brave browser)
// hence check is inside a try/catch
try {
if (!localStorage) {
return false;
}
} catch (ex) {
return false;
}
try {
setItem(key, value);
removeItem(key);
cachedStorage = true;
} catch (e) {
// If we hit the limit, and we don't have an empty localStorage then it means we have support
if (isOutOfSpace(e) && localStorage.length) {
cachedStorage = true; // just maxed it out and even the set test failed.
} else {
cachedStorage = false;
}
}
return cachedStorage;
}
// Check to set if the error is us dealing with being out of space
function isOutOfSpace(e) {
return e && (
e.name === 'QUOTA_EXCEEDED_ERR' ||
e.name === 'NS_ERROR_DOM_QUOTA_REACHED' ||
e.name === 'QuotaExceededError'
);
}
// Determines if native JSON (de-)serialization is supported in the browser.
function supportsJSON() {
/*jshint eqnull:true */
if (cachedJSON === undefined) {
cachedJSON = (window.JSON != null);
}
return cachedJSON;
}
/**
* Returns a string where all RegExp special characters are escaped with a \.
* @param {String} text
* @return {string}
*/
function escapeRegExpSpecialCharacters(text) {
return text.replace(/[[\]{}()*+?.\\^$|]/g, '\\$&');
}
/**
* Returns the full string for the localStorage expiration item.
* @param {String} key
* @return {string}
*/
function expirationKey(key) {
return key + CACHE_SUFFIX;
}
/**
* Returns the number of minutes since the epoch.
* @return {number}
*/
function currentTime() {
return Math.floor((new Date().getTime()) / expiryMilliseconds);
}
/**
* Wrapper functions for localStorage methods
*/
function getItem(key) {
return localStorage.getItem(CACHE_PREFIX + cacheBucket + key);
}
function setItem(key, value) {
// Fix for iPad issue - sometimes throws QUOTA_EXCEEDED_ERR on setItem.
localStorage.removeItem(CACHE_PREFIX + cacheBucket + key);
localStorage.setItem(CACHE_PREFIX + cacheBucket + key, value);
}
function removeItem(key) {
localStorage.removeItem(CACHE_PREFIX + cacheBucket + key);
}
function eachKey(fn) {
var prefixRegExp = new RegExp('^' + CACHE_PREFIX + escapeRegExpSpecialCharacters(cacheBucket) + '(.*)');
// Loop in reverse as removing items will change indices of tail
for (var i = localStorage.length - 1; i >= 0; --i) {
var key = localStorage.key(i);
key = key && key.match(prefixRegExp);
key = key && key[1];
if (key && key.indexOf(CACHE_SUFFIX) < 0) {
fn(key, expirationKey(key));
}
}
}
function flushItem(key) {
var exprKey = expirationKey(key);
removeItem(key);
removeItem(exprKey);
}
function flushExpiredItem(key) {
var exprKey = expirationKey(key);
var expr = getItem(exprKey);
if (expr) {
var expirationTime = parseInt(expr, EXPIRY_RADIX);
// Check if we should actually kick item out of storage
if (currentTime() >= expirationTime) {
removeItem(key);
removeItem(exprKey);
return true;
}
}
}
function warn(message, err) {
if (!warnings) return;
if (!('console' in window) || typeof window.console.warn !== 'function') return;
window.console.warn("lscache - " + message);
if (err) window.console.warn("lscache - The error was: " + err.message);
}
function calculateMaxDate(expiryMilliseconds) {
return Math.floor(8.64e15 / expiryMilliseconds);
}
let lscache = {
/**
* Stores the value in localStorage. Expires after specified number of minutes.
* @param {string} key
* @param {Object|string} value
* @param {number} time
* @return true if the value was inserted successfully
*/
set: function (key, value, time) {
if (!supportsStorage()) return false;
// If we don't get a string value, try to stringify
// In future, localStorage may properly support storing non-strings
// and this can be removed.
if (!supportsJSON()) return false;
try {
value = JSON.stringify(value);
} catch (e) {
// Sometimes we can't stringify due to circular refs
// in complex objects, so we won't bother storing then.
return false;
}
try {
setItem(key, value);
} catch (e) {
if (isOutOfSpace(e)) {
// If we exceeded the quota, then we will sort
// by the expire time, and then remove the N oldest
var storedKeys = [];
var storedKey;
eachKey(function (key, exprKey) {
var expiration = getItem(exprKey);
if (expiration) {
expiration = parseInt(expiration, EXPIRY_RADIX);
} else {
// TODO: Store date added for non-expiring items for smarter removal
expiration = maxDate;
}
storedKeys.push({
key: key,
size: (getItem(key) || '').length,
expiration: expiration
});
});
// Sorts the keys with oldest expiration time last
storedKeys.sort(function (a, b) {
return (b.expiration - a.expiration);
});
var targetSize = (value || '').length;
while (storedKeys.length && targetSize > 0) {
storedKey = storedKeys.pop();
warn("Cache is full, removing item with key '" + key + "'");
flushItem(storedKey.key);
targetSize -= storedKey.size;
}
try {
setItem(key, value);
} catch (e) {
// value may be larger than total quota
warn("Could not add item with key '" + key + "', perhaps it's too big?", e);
return false;
}
} else {
// If it was some other error, just give up.
warn("Could not add item with key '" + key + "'", e);
return false;
}
}
// If a time is specified, store expiration info in localStorage
if (time) {
setItem(expirationKey(key), (currentTime() + time).toString(EXPIRY_RADIX));
} else {
// In case they previously set a time, remove that info from localStorage.
removeItem(expirationKey(key));
}
return true;
},
/**
* Retrieves specified value from localStorage, if not expired.
* @param {string} key
* @return {string|Object}
*/
get: function (key) {
if (!supportsStorage()) return null;
// Return the de-serialized item if not expired
if (flushExpiredItem(key)) {
return null;
}
// Tries to de-serialize stored value if its an object, and returns the normal value otherwise.
var value = getItem(key);
if (!value || !supportsJSON()) {
return value;
}
try {
// We can't tell if its JSON or a string, so we try to parse
return JSON.parse(value);
} catch (e) {
// If we can't parse, it's probably because it isn't an object
return value;
}
},
/**
* Removes a value from localStorage.
* Equivalent to 'delete' in memcache, but that's a keyword in JS.
* @param {string} key
*/
remove: function (key) {
if (!supportsStorage()) return;
flushItem(key);
},
/**
* Returns whether local storage is supported.
* Currently exposed for testing purposes.
* @return {boolean}
*/
supported: function () {
return supportsStorage();
},
/**
* Flushes all lscache items and expiry markers without affecting rest of localStorage
*/
flush: function () {
if (!supportsStorage()) return;
eachKey(function (key) {
flushItem(key);
});
},
/**
* Flushes expired lscache items and expiry markers without affecting rest of localStorage
*/
flushExpired: function () {
if (!supportsStorage()) return;
eachKey(function (key) {
flushExpiredItem(key);
});
},
/**
* Appends CACHE_PREFIX so lscache will partition data in to different buckets.
* @param {string} bucket
*/
setBucket: function (bucket) {
cacheBucket = bucket;
},
/**
* Resets the string being appended to CACHE_PREFIX so lscache will use the default storage behavior.
*/
resetBucket: function () {
cacheBucket = '';
},
/**
* @returns {number} The currently set number of milliseconds each time unit represents in
* the set() function's "time" argument.
*/
getExpiryMilliseconds: function () {
return expiryMilliseconds;
},
/**
* Sets the number of milliseconds each time unit represents in the set() function's
* "time" argument.
* Sample values:
* 1: each time unit = 1 millisecond
* 1000: each time unit = 1 second
* 60000: each time unit = 1 minute (Default value)
* 360000: each time unit = 1 hour
* @param {number} milliseconds
*/
setExpiryMilliseconds: function (milliseconds) {
expiryMilliseconds = milliseconds;
maxDate = calculateMaxDate(expiryMilliseconds);
},
/**
* Sets whether to display warnings when an item is removed from the cache or not.
*/
enableWarnings: function (enabled) {
warnings = enabled;
},
getAllKey() {
let all = []
eachKey((key) => {
all.push(key)
})
return all;
}
};
export default lscache;
{
"name": "__MSG_main_manifest_name__",
"description": "__MSG_main_manifest_description__",
"version": "##version##",
"author": "wo@baiy.org",
"offline_enabled": true,
"homepage_url": "https://github.com/baiy/Ctool",
"manifest_version": 2,
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"browser_action": {
"default_icon": "img/icon_chrome.png",
"default_title": "__MSG_main_manifest_default_title__",
"default_popup": "index.html"
},
"background": {
"scripts": ["background.js"]
},
"icons": {
"16": "img/icon_chrome.png",
"48": "img/icon_chrome.png",
"128": "img/icon_chrome.png"
},
"permissions": [
"clipboardWrite",
"clipboardRead",
"*://get.geojs.io/*",
"*://*.baiy.org/*"
],
"commands": {
"panel": {
"description": "__MSG_main_manifest_commands_panel_description__",
"global": true
}
}
}
let windowId = null;
// 打开独立窗口
const panel = {
create() {
browser.windows.create({
url: browser.runtime.getURL("tool.html"),
type: "popup",
}, (w) => {
browser.windows.update(w.id, {
width: 810,
height: 610
});
windowId = w.id
})
},
open() {
if (windowId === null) {
this.create()
} else {
browser.windows.get(windowId, (w) => {
if (!w) {
this.create()
} else {
browser.windows.update(windowId, {focused: true})
}
})
}
},
onRemoved(id) {
if (id === windowId) {
windowId = null;
}
}
}
// 注册快捷键
browser.commands.onCommand.addListener((command) => {
switch (command) {
case "panel":
panel.open()
break;
default:
return;
}
})
// 窗口关闭事件
browser.windows.onRemoved.addListener((id) => {
panel.onRemoved(id);
})
export const openUrl = (url) => {
return browser.tabs.create({url:url});
}
export const getMessage = (messageName, values = {}, placeholders = []) => {
let substitutions = []
placeholders.forEach((key) => {
substitutions.push((key in values) ? values[key] : "")
})
return browser.i18n.getMessage(messageName, substitutions);
}
{
"name": "__MSG_main_manifest_name__",
"description": "__MSG_main_manifest_description__",
"version": "##version##",
"author": "wo@baiy.org",
"homepage_url": "https://github.com/baiy/Ctool",
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"manifest_version": 2,
"browser_action": {
"default_icon": "img/icon_chrome.png",
"default_title": "__MSG_main_manifest_default_title__",
"default_popup": "index.html"
},
"default_locale": "zh_CN",
"background": {
"scripts": ["background.js"]
},
"icons": {
"16": "img/icon_chrome.png",
"48": "img/icon_chrome.png",
"128": "img/icon_chrome.png"
},
"permissions": [
"clipboardWrite",
"clipboardRead",
"*://get.geojs.io/*",
"*://*.baiy.org/*"
],
"commands": {
"_execute_browser_action": {},
"panel": {
"description": "__MSG_main_manifest_commands_panel_description__"
}
}
}
import _ from "lodash"
const PREFIX = "_system_"
const timestamp = () => {
return Math.ceil((Date.parse(new Date()) / 1000))
}
const encode = (value, expiry = 0) => {
return {
v: value,
e: expiry ? expiry + timestamp() : 0,
}
}
const decode = (data) => {
if (
!_.isObject(data)
|| !("v" in data)
|| !("e" in data)
) {
return null;
}
return data
}
const keyName = (key) => {
return `${PREFIX}${key}`
}
export default {
get(key, def = null) {
let data = decode(window.utools.dbStorage.getItem(keyName(key)));
// 不存在/过期
if (data === null || (data.e !== 0 && data.e < timestamp())) {
// 移除过期
if (data !== null) {
this.remove(key)
}
return def;
}
return data.v
},
set(key, value, expiry = 0) {
return window.utools.dbStorage.setItem(
keyName(key),
encode(value, _.toInteger(expiry))
)
},
remove(key) {
return window.utools.dbStorage.removeItem(keyName(key))
},
// 清理过期
clear() {
for (let {_id} of window.utools.db.allDocs(PREFIX)) {
let key = _id.replace(PREFIX, "");
if (key) {
// 获取一次 过期会自动删除
this.get(key)
}
}
return true;
},
getAllKey() {
return window.utools.db.allDocs(PREFIX).map(({_id}) => {
return _id.replace(PREFIX, "");
})
}
}
\ No newline at end of file
export const openUrl = (url) => {
if ("utools" in window && "shellOpenExternal" in window.utools) {
return window.utools.shellOpenExternal(url)
}
return window.open(url);
}
\ No newline at end of file
{
"pluginName": "Ctool",
"description": "Ctool 程序开发常用工具",
"author": "baiy",
"homepage": "https://github.com/baiy/Ctool",
"main": "tool.html",
"version": "##version##",
"logo": "img/icon_utools.png",
"pluginSetting": {
"single": false
},
"development": {
"main": "http://localhost:8081/tool.html"
},
"features": "##features##"
}
\ No newline at end of file
<template>
<div>
<div class="ctool-bottom">
<div class="ctool-bottom-right" style="width: 210px">
<Tooltip class="ctool-bottom-tooltip" transfer :content="$t('main_tool_'+currentTool) + ' -' + $t('main_history')" placement="top">
<Badge v-if="historyLength>0" dot :offset="[6,10]">
<Icon type="md-time" :size="22" @click="historyShow= true"/>
</Badge>
<template v-else>
<Icon type="md-time" :size="22" @click="historyShow= true"/>
</template>
</Tooltip>
<Tooltip class="ctool-bottom-tooltip" transfer content="Github" placement="top">
<Icon type="logo-github" :size="22" @click="openUrl('https://github.com/baiy/Ctool')"/>
</Tooltip>
<Tooltip class="ctool-bottom-tooltip" transfer :content="$t('main_ui_setting')" placement="top">
<Icon type="md-settings" :size="22" @click="settingShow = true"/>
</Tooltip>
<Tooltip class="ctool-bottom-tooltip" transfer :content="$t('main_ui_issues')" placement="top">
<Icon type="md-help-circle" :size="22" @click="openUrl('https://github.com/baiy/Ctool/issues')"/>
</Tooltip>
<Tooltip class="ctool-bottom-tooltip" transfer :content="$t('main_ui_open_full')" placement="top">
<Icon type="md-expand" :size="22" @click="openUrl('_new')" v-if="!isUtools"/>
</Tooltip>
</div>
<div class="ctool-bottom-block" style="margin-right: 210px">
<notice-block/>
</div>
</div>
<Drawer :title="$t('main_ui_setting')" v-model="settingShow" :width="400">
<setting-block v-if="settingShow"></setting-block>
</Drawer>
<Drawer :title="$t('main_tool_'+currentTool)+' - '+$t('main_history')" v-model="historyShow" :width="100">
<History v-if="historyShow" @close="historyShow = false"/>
</Drawer>
</div>
</template>
<script>
import Notice from './notice'
import History from './history'
import {isUtools, openUrl} from '../helper'
import settingBlock from "../views/setting/block"
import model from "../tool/model";
import historyFactory from "../tool/history";
export default {
name: "bottom",
components: {
"notice-block": Notice,
"setting-block": settingBlock,
History
},
data() {
return {
isUtools,
settingShow: false,
historyShow: false,
currentTool: model.getCurrentTool(),
currentToolSetInterval: null,
}
},
computed: {
historyLength() {
return historyFactory(this.currentTool).length()
}
},
created() {
this.currentToolSetInterval = setInterval(() => {
this.currentTool = model.getCurrentTool()
}, 2000);
},
methods: {
openUrl(url) {
openUrl(url === '_new' ? window.location.href : url)
}
},
destroyed() {
if (this.currentToolSetInterval !== null) {
clearInterval(this.currentToolSetInterval);
this.currentToolSetInterval = null
}
},
}
</script>
<style>
.ctool-bottom {
width: 100%;
position: fixed;
bottom: 0;
left: 0;
height: 33px;
padding-top: 2px;
overflow: hidden;
border-top: 1px solid #dcdee2;
background: #FFF;
}
.ctool-bottom-block {
height: 30px;
line-height: 30px;
overflow: hidden;
}
.ctool-bottom-right {
line-height: 30px;
float: right;
text-align: right;
}
.ctool-bottom-right .ivu-icon {
margin-right: 15px;
cursor: pointer;
}
.ctool-bottom-right .ivu-icon:hover {
color: #1abc9c;
}
</style>
<template>
<div>
<Table ref="historyTable" border :columns="columns" :data="lists" :height="tableHeight">
<template slot-scope="{ row }" slot="_value">
<div>{{ stringify(row.value) }}}</div>
</template>
<template slot-scope="{ index }" slot="_op">
<Button type="primary" size="small" @click="view(index)">{{ $t('main_ui_views') }}</Button>
<Button type="primary" style="margin-left: 5px" @click="load(index)" size="small">
{{ $t('main_ui_load') }}
</Button>
</template>
</Table>
<div class="drawer-footer">
<Button type="primary" @click="clear">{{ $t('main_history_clear') }}</Button>
</div>
</div>
</template>
<script>
import model from '../tool/model'
import historyFactory, {setForceLoadHistoryIndex} from "../tool/history";
export default {
name: "history",
data() {
return {
lists: [],
columns: [
{
title: this.$t('main_history_time'),
key: 'time',
width: 180
},
{
title: this.$t('main_history_data'),
slot: '_value',
ellipsis: true,
},
{
title: this.$t('main_history_op'),
slot: '_op',
width: 160
}
],
}
},
computed: {
tableHeight() {
// 设置表格高度
return window.innerHeight - 140
}
},
created() {
let history = historyFactory(this.currentTool())
if (history.length() < 1) {
return this.$Message.error(this.$t('main_history_null').toString())
}
this.lists = history.all()
},
methods: {
currentTool() {
return model.getCurrentTool()
},
stringify(value) {
return JSON.stringify(value)
},
view(index) {
this.$Modal.info({
render: (h) => {
return h('Input', {
props: {
type: "textarea",
rows: 10,
value: JSON.stringify(historyFactory(this.currentTool()).get(index), null, "\t"),
}
})
},
width: 700,
okText: this.$t('main_ui_close')
})
},
load(index) {
setForceLoadHistoryIndex(index)
this.close()
this.$router.push({
path: this.$router.currentRoute.fullPath,
query: {
t: Date.now(),
},
});
},
clear() {
historyFactory(model.getCurrentTool()).clear()
this.close()
},
close(){
this.$emit('close')
}
}
};
</script>
<style scoped>
.drawer-footer {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
background: #fff;
}
</style>
<template>
<div style="position: relative;">
<slot></slot>
<div :style="extraStyle">
<slot name="extra">
<Button v-if="text" :type="type" size="small" @click="buttonClick">{{ text }}</Button>
</slot>
</div>
</div>
</template>
<script>
export default {
name: 'inputBlock',
props: {
text: {
type: String,
default: ""
},
bottom: {
type: String,
default: "4px"
},
top: {
type: String,
default: ""
},
left: {
type: String,
default: ""
},
right: {
type: String,
default: "4px"
},
type:{
type: String,
default: "primary"
}
},
computed:{
extraStyle(){
let css = {
fixed:"position: absolute",
zindex:"z-index:100",
vertical:this.top !== "" ? `top:${this.top}` : `bottom:${this.bottom}`,
horizontal:this.left !== "" ? `left:${this.left}` : `right:${this.right}`,
};
return Object.values(css).join(";")
}
},
methods: {
buttonClick() {
this.$emit('on-default-right-bottom-click');
}
}
};
</script>
<template>
<div class="ctool-notice-block">
<ul class="ctool-notice-ul" :class="{'ctool-notice-animate-up': animateUp}">
<li v-for="(item, index) in listData" :key="index">
<Icon v-if="item.icon.length > 0" :type="item.icon"/>
<span v-html="item.text" @click="open(item)"></span>
</li>
</ul>
</div>
</template>
<script>
import {env, openUrl} from "../helper";
import instance from '../tool/instance'
import cache from "../tool/cache";
import user from "../tool/user";
import axios from "axios";
import _ from "lodash";
import {dispatchWindowResize} from '../tool/event'
import {getCurrentLocale} from "../i18n/index";
const CACHE_NAME = 'notice_item';
const CACHE_EXPIRY = 3600 * 24;
const NOTICE_TYPE = ['info', 'ad', 'hidden'];
const NOTICE_URL_TYPE = ['tool', 'web'];
const handleNoticeItems = ({code, data, info}) => {
if (code !== 0) {
throw new Error(info)
}
let items = [];
for (let item of data) {
if (
!('type' in item)
|| !('text' in item)
|| !('url' in item)
|| !('type' in item.url)
|| !('value' in item.url)
|| !NOTICE_TYPE.includes(item.type)
|| !NOTICE_URL_TYPE.includes(item.url.type)
|| item.text.trim().length < 1
) {
continue;
}
items.push({
type: item.type,
icon: 'icon' in item ? item.icon : "",
text: item.text.trim(),
url: {
type: item.url.type,
value: item.url.value,
},
})
}
return items;
}
const logError = (e) => {
console.log(e)
}
export default {
name: "notice",
data() {
return {
animateUp: false,
// {icon,text,url:{type,value}},
listData: [],
timer: null
}
},
created() {
// 初始化数据
this.load();
},
methods: {
load() {
try {
// 加载缓存
let items = cache.get(CACHE_NAME)
if (items !== null) {
return this.init(items)
}
try {
// 远程加载
axios({
url: 'https://www.baiy.org/chrome_tool/notice/',
responseType: 'json',
params: {
i: getCurrentLocale(),
v: env('version'),
p: env('platform'),
u: user.uid(),
r: Math.random()
}
}).then(({data}) => {
let notices = handleNoticeItems(data);
if (notices.length > 0) {
cache.set(CACHE_NAME, notices, CACHE_EXPIRY)
this.init(notices);
}
}).catch((error) => {
logError(error)
});
} catch (e) {
logError(e)
}
} catch (e) {
logError(e)
}
},
init(notices) {
this.listData = _.cloneDeep(notices.filter((item) => {
return item.type !== "hidden"
}))
if (this.listData.length > 1) {
this.timer = setInterval(this.scrollAnimate, 6000);
}
this.$nextTick(()=>{
dispatchWindowResize()
})
},
scrollAnimate() {
this.animateUp = true
setTimeout(() => {
this.listData.push(this.listData[0])
this.listData.shift()
this.animateUp = false
}, 500)
},
open(item) {
switch (item.url.type) {
case "tool":
instance.enter(item.url.value)
break;
case "web":
openUrl(item.url.value)
break;
}
}
},
destroyed() {
if (this.timer !== null) {
clearInterval(this.timer)
}
}
};
</script>
<style scoped>
.ctool-notice-block {
padding-left: 20px;
height: 28px;
border-radius: 20px;
margin: 0 auto;
overflow: hidden;
}
.ctool-notice-block .ctool-notice-ul li {
width: 100%;
height: 100%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
list-style: none;
line-height: 28px;
/*text-align: right;*/
font-size: 14px;
color: #515a6e;
}
.ctool-notice-animate-up {
transition: all 0.5s ease-in-out;
transform: translateY(-28px);
}
.ctool-notice-block .ctool-notice-ul li span:hover {
font-weight: 400;
text-decoration: underline;
cursor: pointer;
}
.ctool-notice-block .ctool-notice-ul li i {
margin-right: 5px;
}
</style>
<template>
<Form inline :style="style" class="option-block">
<slot></slot>
</Form>
</template>
<script>
export default {
name: 'optionBlock',
props: {
center: {
type: Boolean,
default: false
},
disablePadding: {
type: Boolean,
default: false
}
},
computed: {
style() {
let css = {
padding: !this.disablePadding ? "10px 0" : "0",
};
if (this.center) {
css.textAlign = "center"
}
return css;
}
}
};
</script>
<style>
.option-block .ivu-form-item {
margin-bottom: 0;
}
</style>
// 工具缓存数据过期时间(秒)
const TOOL_DATA_EXPIRY = 3600 * 24
// 徽章过期时间(天)
const BADGE_EXPIRY = 5
// 分类徽章
const BADGE_CATEGORY = []
// 工具徽章
const BADGE_TOOL = []
// 默认常用工具
const DEFAULT_COMMON_TOOL = [
'hash', 'encrypt', 'json', 'base64', 'url', 'timestamp',
'qrCode', 'pinyin', 'ip', 'code', 'unicode',
'text', 'randomString', 'diffs',
]
const category = [
{'name': 'common'},
{'name': 'encryption'},
{'name': 'conversion'},
{'name': 'encoder_decoder'},
{'name': 'check'},
{'name': 'generate'},
{'name': 'other'},
{'name': 'yeahmao'},
{'name': 'code_gen'},
]
const tool = [
{
'name': 'hash',
'cat': ['encryption']
},
{
'name': 'encrypt',
'cat': ['encryption']
},
{'name': 'sign', 'cat': ['encryption', 'check']},
{'name': 'base64', 'cat': ['encryption','encoder_decoder']},
{'name': 'json', 'cat': ['conversion']},
{'name': 'url', 'cat': ['encoder_decoder']},
{'name': 'timestamp', 'cat': ['conversion']},
{'name': 'qrCode', 'cat': ['generate']},
{'name': 'barcode', 'cat': ['generate']},
{'name': 'pinyin', 'cat': ['conversion']},
{'name': 'ip', 'cat': ['other']},
{'name': 'code', 'cat': ['other']},
{'name': 'unicode', 'cat': ['encoder_decoder']},
{'name': 'decimalConvert', 'cat': ['conversion']},
{'name': 'regex', 'cat': ['check']},
{'name': 'randomString', 'cat': ['generate']},
{'name': 'serializeConversion', 'cat': ['conversion']},
{'name': 'diffs', 'cat': ['check']},
{'name': 'crontab', 'cat': ['check']},
{'name': 'websocket', 'cat': ['other']},
{'name': 'unit', 'cat': ['other']},
{'name': 'time', 'cat': ['other']},
{'name': 'uuid', 'cat': ['generate']},
{'name': 'ascii', 'cat': ['conversion']},
{'name': 'variableConversion', 'cat': ['conversion']},
{'name': 'jwt', 'cat': ['encoder_decoder']},
{'name': 'hexString', 'cat': ['conversion']},
{'name': 'hex2base64', 'cat': ['conversion']},
{'name': 'text', 'cat': ['other']},
{'name': 'html', 'cat': ['encoder_decoder']},
{'name': 'binary', 'cat': ['generate']},
{'name': 'armConverter', 'cat': ['conversion']},
{'name': 'bcrypt', 'cat': ['encryption','check']},
{'name': 'ipcalc', 'cat': ['generate']},
// yeahmao
{'name': 'hexConvert', 'cat': ['yeahmao']},
{'name': 'constFinder', 'cat': ['yeahmao']},
// code_gen
{'name': 'codeGenJson', 'cat': ['code_gen']},
{'name': 'codeGenJava', 'cat': ['code_gen']},
]
// 工具类功能配置
const feature = {
qrCode: [
{name: "generate", title: '生成'},
{name: "reader", title: '解析'}
]
}
const utools = {
keyword: {
hash: ['md5', 'sha1', 'sha256', 'sha512', 'sm3'],
encrypt: ['AES', 'DES', 'RC4', 'Rabbit', 'TripleDes', 'sm2', 'sm4'],
jwt: ['jwtDecode'],
hexString: ['hex to string', 'string to hex', '十六进制转字符串', '字符串转十六机制'],
text: ['文本处理', '大小写转换', '中英文标点转换', '简繁转换', '字符替换', '字符统计', '行去重', '添加行号', '行排序', '过滤行首尾不可见字符', '过滤空行'],
sign: ['签名', '验签', 'rsa'],
binary: ['原码', '补码', '反码'],
armConverter: ['ARM', 'HEX'],
serializeConversion:["json","xml","yaml","php array","php serialize","properties"]
},
cmds: {
timestamp: [
{
"type": "regex",
// "label": "", //程序自动根据tool title填充
"match": "/(^\\d{10}(?:\\d{3})?$)|(^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?$)/i",
"minLength": 10,
"maxLength": 25
}
],
qrCode: [
{
"type": "over",
"minLength": 1,
"feature": 'generate' // 适配工具内功能
},
{
"type": "regex",
"match": "/[a-zA-z]+://[^\\s]*/i",
"minLength": 8,
"feature": 'reader' // 适配工具内功能
}
],
ip: [
{
"type": "regex",
"match": "/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/i",
"minLength": 7,
"maxLength": 15
}
],
unicode: [
{
"type": "regex",
"match": "/\\\\u[0-9a-f]{4}/i",
"minLength": 6
}
]
}
}
module.exports = {
category,
tool,
feature,
utools,
toolDataExpiry: TOOL_DATA_EXPIRY,
badgeExpiry: BADGE_EXPIRY,
badgeCategory: BADGE_CATEGORY,
badgeTool: BADGE_TOOL,
defaultCommonTool: DEFAULT_COMMON_TOOL
}
import {v4 as uuidV4} from 'uuid';
import {openUrl as chromiumOpenUrl} from './adapter/chromium/helper';
import {openUrl as utoolsOpenUrl} from './adapter/utools/helper';
import {openUrl as firefoxOpenUrl} from './adapter/firefox/helper';
export const env = (key) => {
return process['ctool'][key] ? process['ctool'][key] : "";
};
export const isChrome = !!env('isChrome')
export const isEdge = !!env('isEdge')
export const isFirefox = !!env('isFirefox')
export const isChromium = !!env('isChromium')
export const isWeb = !!env('isWeb')
export const isUtools = !!env('isUtools')
export const uuid = () => {
return uuidV4().toLowerCase();
}
export const openUrl = (url) => {
if (isChromium) {
return chromiumOpenUrl(url)
}
if (isUtools) {
return utoolsOpenUrl(url)
}
if (isFirefox) {
return firefoxOpenUrl(url)
}
return window.open(url);
};
export const version = env('version').trim()
export const setDisplayMode = (mode) => {
mode = ['light', 'dark', 'auto'].includes(mode) ? mode : 'light'
console.log(`set display mode:${mode}`)
document.getElementsByTagName('html')[0].setAttribute('theme-mode', mode);
}
// 编译语言包
const path = require('path');
const fs = require('fs');
const JSON5 = require('json5')
const _ = require('lodash')
const LOCAL_LISTS = [
{code: '_default', name: "默认(default)"},
{code: "en", name: "English"},
{code: 'zh_CN', name: "简体中文"}
]
// 默认地区
const DEFAULT_LOCALE = 'zh_CN'
// 为空展示地区
const DEFAULT_SHOW_LOCALE = 'en'
const codeToLocale = (code) => {
return code === "_default" ? DEFAULT_LOCALE : code;
}
const placeholder = (message) => {
let placeholders = [];
const result = message.match(new RegExp('{.+?}', 'g'));
if (result !== null) {
result.forEach((item) => {
item = item.replace('{', '').replace('}', '')
if (!placeholders.includes(item)) {
placeholders.push(item)
}
})
}
return placeholders
}
const getLocale = (code) => {
const localeDir = path.join(__dirname, "locales/" + code)
if (!(fs.existsSync(localeDir) && fs.statSync(localeDir).isDirectory())) {
return null;
}
let locale = {}
fs.readdirSync(path.resolve(localeDir)).forEach((file) => {
if (file.indexOf('.i18n.json5') !== -1) {
let type = file.replace('.i18n.json5', '');
let config = JSON5.parse(fs.readFileSync(path.join(__dirname, `locales/${code}/${file}`), 'utf-8'));
// 写入区域
if (type === "main") {
locale[`${type}_locale`] = {message: code}
}
Object.keys(config).forEach(function (key) {
let placeholders = placeholder(config[key])
locale[`${type}_${key}`] = {
message: config[key],
}
if (placeholders.length > 0) {
locale[`${type}_${key}`]["placeholders"] = placeholders
}
});
}
})
return locale;
}
const getAllLocale = () => {
// 所有语言包
let locales = {
lists: LOCAL_LISTS,
default_locale: DEFAULT_LOCALE,
default_show_locale: DEFAULT_SHOW_LOCALE,
detail: {}
}
fs.readdirSync(path.resolve(path.join(__dirname, "locales"))).forEach((code) => {
let locale = getLocale(code)
if (locale !== null) {
locales['detail'][code] = locale;
}
})
checkAllLocale(locales)
return locales
}
const checkAllLocale = (locales) => {
/**
* 检查语言包是否完备
* 确保中文/英文语言包是否一致
*/
const zhKeys = Object.keys(locales['detail']['zh_CN'])
const enKeys = Object.keys(locales['detail']['en'])
const zhDiff = _.difference(zhKeys, enKeys);
if (zhDiff.length > 0) {
throw new Error(`中/英文语言包存在差异[key](英文缺失):${zhDiff.join(',')}`)
}
const enDiff = _.difference(enKeys, zhKeys);
if (enDiff.length > 0) {
throw new Error(`中/英文语言包存在差异[key](中文缺失):${enDiff.join(',')}`)
}
}
const ALL_LOCALE = getAllLocale()
module.exports = {
getLocales() {
return ALL_LOCALE;
},
// 生成运行时语言包
generate() {
fs.writeFileSync(path.join(__dirname, 'locales/build.js'), `export default ${JSON.stringify(ALL_LOCALE, null, 4)}`);
},
getMessage(code, key) {
let locales = ALL_LOCALE['detail']
let locale = codeToLocale(code)
let text = key;
if ((locale in locales) && (key in locales[locale])) {
text = locales[locale][key]['message']
} else if (locale !== DEFAULT_SHOW_LOCALE) {
// 获取默认语言
text = this.getMessage(DEFAULT_SHOW_LOCALE, key)
}
return text;
},
translate(key, values = {}, code = DEFAULT_LOCALE) {
if (!key) return '';
const text = this.getMessage(code, key)
const matchRge = new RegExp('{.+?}', 'g')
const matchString = text.match(matchRge);
const replaceHash = {};
// 获取语言包对应翻译内容
let result = text;
if (matchString) {
matchString.forEach((wildcard) => {
let key = wildcard.replace("{", "").replace("}", '')
if ((key in values) && !(wildcard in replaceHash)) {
replaceHash[wildcard] = values[key]
}
});
}
result = result.replace(matchRge, (replacer) => {
return replacer in replaceHash ? replaceHash[replacer] : replacer;
});
return result;
}
}
import VueI18n from 'vue-i18n'
import Vue from 'vue'
import {getMessage as chromiumGetMessage} from "../adapter/chromium/helper"
import {getMessage as firefoxGetMessage} from "../adapter/firefox/helper"
import {isChromium,isFirefox} from "../helper";
import locales from "./locales/build.js";
Vue.use(VueI18n)
// 区域列表
export const LOCALE_LISTS = locales.lists
export const LOCALE_DETAIL = locales.detail
export const DEFAULT_LOCALE = locales.default_locale
export const DEFAULT_SHOW_LOCALE = locales.default_show_locale
let currentLocale = "";
// 设置当前地区
export const setCurrentLocale = (locale) => {
currentLocale = locale;
}
const getMessage = (code, key) => {
let locale = code === "_default" ? DEFAULT_LOCALE : code;
let text = key;
if ((locale in LOCALE_DETAIL) && (key in LOCALE_DETAIL[locale])) {
text = LOCALE_DETAIL[locale][key]['message']
} else if (locale !== DEFAULT_SHOW_LOCALE) {
// 获取默认语言
text = getMessage(DEFAULT_SHOW_LOCALE, key)
}
return text;
}
const translate = (code, key, values = {}) => {
if (!key) return '';
let locale = code === "_default" ? DEFAULT_LOCALE : code;
if (code === "_default" && (isChromium || isFirefox) ) {
let placeholders = []
if (
(locale in LOCALE_DETAIL)
&& (key in LOCALE_DETAIL[locale])
&& ('placeholders' in LOCALE_DETAIL[locale][key])
) {
placeholders = LOCALE_DETAIL[locale][key]['placeholders']
}
if (isChromium){
return chromiumGetMessage(key, values, placeholders)
}
if (isFirefox){
return firefoxGetMessage(key, values, placeholders)
}
}
let text = getMessage(code, key);
const matchRge = new RegExp('{.+?}', 'g')
const matchString = text.match(matchRge);
const replaceHash = {};
// 获取语言包对应翻译内容
let result = text;
if (matchString) {
matchString.forEach((wildcard) => {
let key = wildcard.replace("{", "").replace("}", '')
if ((key in values) && !(wildcard in replaceHash)) {
replaceHash[wildcard] = values[key]
}
});
}
result = result.replace(matchRge, (replacer) => {
return replacer in replaceHash ? replaceHash[replacer] : replacer;
});
return result;
}
window["__"] = (key, values = {}, locale = null) => {
locale = !locale ? currentLocale : locale
// values 必须是对象
return translate(
(!locale ? currentLocale : locale),
key,
values
)
}
// 获取当前真实区域
export const getCurrentLocale = () => {
return __('main_locale').toString();
}
export const i18n = new VueI18n({
locale: 'zh_CN',
missing: (locale, key, vm, values) => {
if (Array.isArray(values) && values.length === 1) {
if (Array.isArray(values[0])) {
// 数组转对象表示法
let temp = {}
for (let i = 0; i < values[0].length; i++) {
temp[i] = values[0][i]
}
return __(key, temp)
}
return __(key, values[0])
}
return __(key)
}
})
{
"convert": "Convert",
"stringEscape": "stringEscape",
"codeGenFrida": "codeGenFrida",
"codeGenX64dbgIdaVtable": "X64dbgIdaVtable",
}
{
"info_source": "Information Source: ",
"convert": "Convert",
"output": "Output",
"error": "error: {0}"
}
{
"convent": "Convent",
"input_prompt": "Multiple characters are separated by space",
"input_10": "DEC",
"input_16": "HEX",
"input_8": "OCT",
"input_2": "BIN",
"input_string": "String",
"clear": "Clear",
"code_table": "ASCII table",
"yes": "Y",
"no": "N",
"input_null_prompt": "Please enter the corresponding code",
"convent_error": "Conversion exception: {0}",
"is_show": "Is Show",
"description": "Description",
"code_nul": "Null char",
"code_soh": "Start of Heading",
"code_stx": "Start of Text",
"code_etx": "End of Text",
"code_eot": "End of Transmission",
"code_enq": "Enquiry",
"code_ack": "Acknowledgment",
"code_bel": "Bell",
"code_bs": "Back Space",
"code_tab": "Horizontal Tab",
"code_lf": "Line Feed",
"code_vt": "Vertical Tab",
"code_ff": "Form Feed",
"code_cr": "Carriage Return",
"code_so": "Shift Out / X-On",
"code_si": "Shift In / X-Off",
"code_dle": "Data Line Escape",
"code_dc1": "Device Control 1 (oft. XON)",
"code_dc2": "Device Control 2",
"code_dc3": "Device Control 3 (oft. XOFF)",
"code_dc4": "Device Control 4",
"code_nak": "Negative Acknowledgement",
"code_syn": "Synchronous Idle",
"code_etb": "End of Transmit Block",
"code_can": "Cancel",
"code_em": "End of Medium",
"code_sub": "Substitute",
"code_esc": "Escape",
"code_fs": "File Separator",
"code_gs": "Group Separator",
"code_rs": "Record Separator",
"code_us": "Unit Separator",
"code_del": "Delete",
"code_space": "Space",
}
{
"content": "Content",
"background": "Background",
"line_color": "Line Color",
"bar_width": "Bar Width",
"height": "Height",
"margin": "Margin",
"show_text": "Show Text",
"hide": "Hide",
"top": "Top",
"bottom": "Bottom",
"text_align": "Text Align",
"left": "Left",
"center": "Center",
"right": "Right",
"font": "Font",
"bold": "Bold",
"italic": "Italic",
"font_size": "Size",
"text_margin": "Margin",
"invalid_content": "Invalid content"
}
{
"input": "Input",
"encode": "Encode",
"decode": "Decode",
"url_safe": "Url Safe",
"output": "Output",
"error": "error: {0}",
"hex_dump": "Hex Dump",
"setting": "Setting",
"hex_dump_show_mode": "Show Mode",
"hex_dump_format": "Format",
"hex_dump_caps": "Caps Lock",
"hex_dump_caps_lower": "Lower",
"hex_dump_caps_upper": "Upper",
"hex_dump_width": "Width",
"hex_dump_show_mode_hex": "Hex",
"hex_dump_show_mode_text": "Text",
"hex_dump_setting": "Hex Dump Setting",
"hex_dump_format_twos": "Twos",
"hex_dump_format_fours": "Fours",
"hex_dump_format_eights": "Eights",
"hex_dump_format_sixteens": "Sixteens",
"hex_dump_format_none": "None",
}
{
"generate": "Generate",
"password": "String",
"hash_password": "Hash",
"rounds": "Rounds",
"generate_submit": "Generate",
"check": "check",
"check_submit": "Check",
"check_result_success": "Right",
"check_result_error": "Wrong",
"rounds_range": "Rounds range [{0} - {1}]"
}
{
"input": "Input",
"length": "{0} bit",
"true_form": "trueForm",
"inverse": "Inverse",
"complement": "Complement",
"error": "error: {0}"
}
{
"more": "More Languages",
"indent": "Code Indent",
"indent_width": "Indent Space {0}",
"compress": "Compress",
"complete": "Operation Complete",
"error_prompt": "Error Prompt"
}
{
"expression": "Expression",
"execute_time": "Execute Time",
"example": "Example",
"format": "Format",
"execute_time_list": "Execute Time List",
"no": "{0}: {1}",
"symbol": "Symbol",
"description": "Description",
"symbol_description_1": "any value",
"symbol_description_2": "value list separator",
"symbol_description_3": "range of values",
"symbol_description_4": "step values",
}
{
"input_placeholder": "Please enter the number to be converted",
"input": "Input",
"input_type_common": "Common",
"input_type_other": "Other",
"base": "Base-{0}",
"result": "Result {0}",
"alphabet": "64 Alphabet",
"reset": "Reset Default",
"alphabet_length_error": "The conversion alphabet must be 64 bits in length"
}
{
"more": "More Languages",
"collapse":"Collapse Identical",
"beautify":"Beautify"
}
{
"input": "Input",
"password":"Password/Secret Key",
"encrypt": "Encrypt",
"decrypt":"Decrypt",
"generate_secret_key": "Generate Secret Key",
"output":"Output",
"public_key": "Public Key:",
"private_key":"Private Key:",
"secret_key_prompt": "Please save the key pair in time, the current key data cannot be restored after closing the dialog",
"close":"Close",
"failed": "Operation failed with error:{0}"
}
{
"content": "Content",
"uppercase": "Uppercase",
}
{
"input": "assemble",
"output": "Output",
"uppercase": "Uppercase",
}
{
"input": "Input",
"encode":"Encode",
"decode": "Decode",
"output":"Output"
}
{
"input": "Please enter IP address",
"query":"Query",
"local": "Local IP",
"info_source":"IP information source",
"ok": "Query Success",
"error":"Query Fail:{0}"
}
{
ip: "IP Address",
format: "Input Format",
mask: "Subnet Mask",
ip_info: "IP Detail",
ip_info_long: "Long IP",
ip_info_ip8: "Octal IP",
ip_info_ip10: "Decimal IP",
ip_info_ip16: "Hexadecimal IP",
ip_info_ip2: "Binary IP",
mask_info: "Mask Detail",
mask_info_mask: "Subnet Mask",
mask_info_long: "Long Mask",
mask_info_opposite: "Opposite Mask",
mask_info_mask8: "Octal Mask",
mask_info_mask16: "Hexadecimal Mask",
mask_info_mask2: "Binary Mask",
network_info: "Network Detail",
network_export: "Export Available IP",
network_info_available: "Available IP Size",
network_info_size: "All IP Size",
network_info_base: "Base",
network_info_first: "First IP",
network_info_last: "Last IP",
network_info_broadcast: "Broadcast Address",
mask_set_title: "Calculate mask by number of available IP"
}
{
"input": "Input",
"output": "Output",
"json_input_empty": "Please Enter Json Content",
"error": "Exception:{0}",
"format": "Format",
"compress": "Compress",
"escape": "Escape",
"clear_escape": "Unescape",
"add_escape":"Add Escape",
"unicode":"Unicode",
"unicode_to_zh": "Unicode->Zh",
"zh_to_unicode": "Zh->Unicode",
"complete": "Processing is complete",
"get": "Get Query",
"object":"To Object",
"csv": "CSV",
"table":"Table",
"path":"Path",
"add_quote":"Add Quote",
"column_name":"Column Name",
"json_type_json": "Json",
"json_type_keyed": "Keyed",
"json_type_array": "Array",
"json_type_column": "Column Array",
"inline": "Inline"
}
{
"input": "Input",
"decode":"Decode",
"output": "Output",
"decode_fail":"Decode Fail:{0}"
}
{
// ui
"ui_setting": "Settings",
"ui_reset": "Reset",
"ui_views": "View",
"ui_load": "Loading",
"ui_close": "Close",
"ui_issues": "Issues Feedback",
"ui_open_full": "Open Full Screen Tab",
"ui_copy_text_ok": "Copy Success ^o^",
"ui_copy_image_ok": "Image Copied ^o^",
// views
"setting_language": "Language",
"common_tool": "Common Tool",
"unselected_tool": "Unselected Tool",
"keyboard_setting": "Setting Shortcuts",
"display_mode": "Theme",
"display_mode_light": "Light",
"display_mode_dark": "Dark",
"display_mode_auto": "Auto",
"copy_results_to_clipboard": "Copy results to clipboard",
"read_content_from_clipboard": "Read content from clipboard",
"read_clipboard_content_trim": "Read clipboard content trim",
"common_tool_setting": "Common Tool Settings",
"keyboard_firefox_1": "Need to manually set shortcuts",
"keyboard_firefox_2": "Open [Add-ons Manager(about:addons)],Click the setting button on the right side of [Manage your extension],Select [Manage Extension Shortcuts] to modify these shortcuts.",
"keyboard_firefox_3": "Operation Method",
"history": "History",
"history_clear": "Clear history",
"history_time": "Operation time",
"history_data": "Data",
"history_op": "Operation",
"history_null": "History not found",
// category
"category_common": "Common",
"category_encryption": "En/Decrypt",
"category_conversion": "Convert",
"category_encoder_decoder": "En/Decoder",
"category_check": "Validator",
"category_generate": "Generate",
"category_other": "Other",
"category_yeahmao": "yeahmao",
"category_code_gen": "code_gen",
// tool
"tool_hash": "Hash",
"tool_encrypt": "Encrypt & Decrypt",
"tool_sign": "Sign",
"tool_base64": "Base64",
"tool_json": "JSON",
"tool_url": "Url En/Decode",
"tool_timestamp": "Timestamp",
"tool_qrCode": "QR Code",
"tool_pinyin": "Chinese Pinyin",
"tool_ip": "Ip Query",
"tool_code": "Code Formatter ",
"tool_unicode": "Unicode",
"tool_decimalConvert": "Base Convert",
"tool_regex": "Regex",
"tool_randomString": "Random String",
"tool_serializeConversion": "Serialize Convert",
"tool_diffs": "Compare Text",
"tool_crontab": "Crontab",
"tool_websocket": "Websocket",
"tool_unit": "Unit Convert",
"tool_time": "Time Calculator",
"tool_uuid": "UUID",
"tool_ascii": "ASCII",
"tool_variableConversion": "Variable Name",
"tool_jwt": "JWT",
"tool_hexString": "Hex/String",
"tool_hex2base64": "Hex/Base64",
"tool_text": "Text",
"tool_html": "Html En/Decode",
"tool_binary": "trueForm/inverse/complement",
"tool_armConverter": "ARM/HEX",
"tool_bcrypt": "Bcrypt",
"tool_ipcalc": "Ipcalc",
"tool_hexConvert": "hexConvert",
"tool_codeGenJson": "codeGenJson",
"tool_codeGenJava": "codeGenJava",
"tool_constFinder": "constFinder",
// other
"css_main_category_item_style": "padding: 0 10px",
"editor_line_wrapping": "Line Wrapping",
// manifest
"manifest_name": "Ctool Commonly Used Developer Tools",
"manifest_description": "Commonly Used Developer Tools: Hash/Encrypt/Decrypt/Code Convert/Timestamp/Qrcode/IP Query/Code Formatter/Unicode/Regex/...",
"manifest_default_title": "Commonly Used Developer Tools",
"manifest_commands_panel_description": "Open Popup Tool Winodws"
}
{
"input": "Input",
"normal":"No Tone",
"tone": "Have Tone",
"abbr":"First Letter",
"output": "Output",
"delimiter_null":"No Delimiter",
"delimiter_space": "Space Delimiter",
"delimiter_1":"'-' Delimiter",
"delimiter_2": "'_' Delimiter",
"delimiter_3":"'.' Delimiter"
}
{
"generate_title": "Generate",
"generate_input": "Input",
"generate_error": "Generate Error:{0}",
"reader_title": "Reader",
"reader_input": "Please enter the QR code image url or click the button below to upload the image",
"reader_output": "Output",
"reader_error": "Reader Error:{0}",
"reader_parsing_failure": "Image parsing failure",
}
{
"length": "Length",
"amount": "Number of strings",
"delimiter": "Delimiter",
"digital": "Digital",
"lowercase": "Lowercase",
"uppercase": "Uppercase",
"symbol": "Symbol",
"unique": "Unique",
"add_quote": "Add Quote",
"generate": "Generate",
"output": "Output"
}
{
"reference": "Reference",
"expression": "Expression",
"replace_content": "Replace Content",
"replace": "Replace",
"delete": "Delete",
"input": "Input",
"global": "Global",
"ignore_case": "Ignore Case",
"output": "Output",
"output_count": "{0} Total Matches",
"output_emty": "No match result, please check expression",
"error": "Error:{0}",
}
{
"input": "Input",
"output":"output",
"error": "Error:"
}
{
"sign_data": "Sign Data/Verify data",
"verify_code": "Signature after Base64 encoding",
"sign": "Sign",
"verify": "Verify",
"generate_keypair": "Generate Keypair",
"public_key": "PEM Public Key",
"private_key": "PEM Private Key",
"keypair_type": "Type",
"keypair_length": "Length",
"generate_cancel": "Cancel",
"generate_in": "Generate in progress",
"generate": "Generate",
"error_sign_content_empty": "Sign Data/Private Key Required",
"error": "error:{0}",
"error_verify_content_empty": "Base64 Sign/Public Key Required",
"verify_fail": "Verify Fail",
"verify_ok": "Verify Success",
}
{
"content": "Text Content",
"input": "Input",
"resume": "Resume",
"case_conversion": "Case Converter",
"upper_all": "Upper",
"lower_all": "Lower",
"upper_line_start": "Upper Line Start",
"lower_line_start": "lower Line Start",
"upper_word_start": "Upper Word Start",
"lower_word_start": "Lower Word Start",
"punctuation": "Punctuation",
"cn": "CN",
"en": "EN",
"simplified_traditional": "Chinese",
"simplified": "Simplified",
"traditional": "Traditional",
"replace": "Replace",
"line_remove_duplicate": "Line Remove Duplicate",
"line_number": "Line Number",
"line_number_add": "Add",
"line_number_remove": "Remove",
"line_sort": "Line Sort",
"line_sort_asc": "Asc",
"line_sort_desc": "Desc",
"filter": "Filter",
"filter_trim": "(trim) Removes whitespace from both ends of a string",
"filter_blank_line": "Filter blank line",
"filter_all_br": "Filter newlines",
"stat": "Stat",
"stat_explain": "Explain",
"replace_search": "Search",
"replace_replace": "Replace",
"replace_regular": "Regular",
"replace_explain": "You can enter multiple lines, batch replace by line",
"cancel": "Cancel",
"submit": "Submit",
"string_length": "String",
"byte_length": "byte(utf8/gbk)",
"word_length": "Word",
"line_length": "Line",
"zh_length": "(Cn)Char/Punctuation",
"en_length": "(En)Char/Word/Punctuation",
"int_length": "(Number)Char/word",
"ok": "Complete",
"error": "Error:{0}",
"item": "Item",
"explain": "Explain",
"explain_byte_length_utf8_name": "byte utf8",
"explain_byte_length_utf8_info": "Cn Char Length:3",
"explain_byte_length_gbk_name": "byte gbk",
"explain_byte_length_gbk_info": "Cn Char Length:2",
"explain_string_length_name": "String Length",
"explain_string_length_info": "Cn/En Char Length:1 Line Break Length:0",
"explain_word_length_name": "Word",
"explain_word_length_info": "Cn+En Word+punctuation+Number word",
"explain_int_length_name": "Number Char",
"explain_int_length_info": "Number Char Count. For example:'a1024 1024' result:8",
"explain_int_word_length_name": "Number Word",
"explain_int_word_length_info": "For example:'a1024 1024' result:1",
"explain_blank_line_length_name": "Line Length",
"explain_blank_line_length_info": "Blank lines are also included in the number of lines",
"value": "value",
"stat_show": "Word:{0} UTF-8:{1} GBK:{2}"
}
{
"diff_tool": "Difference Calculator",
"and": "And",
"diff": "Diff",
"operation": "Time Operation",
"add": "Add",
"reduce": "Reduce",
"after": "After",
"is": "Is",
"error": "error:{0}",
"error_duration_length": "The year/month interval can only be an integer",
"current_time": "Current Time",
"current_date": "Current Date",
"current_month_date": "Current Month Date",
"current_year_date": "Current Year Date",
"year": "Year",
"month": "Month",
"week": "Week",
"day": "Day",
"hour": "Hour",
"minute": "Minute",
"second": "Second",
analyze: "Time Analyze",
analyze_year: "Year",
analyze_quarter: "Quarter",
analyze_month: "Month",
analyze_year_output: "{year}: Q{quarter},{weekOfYear} Week,{dayOfYear} Day,{hourOfYear} Hour,{minuteOfYear} Minute,{secondOfYear} Second",
analyze_quarter_output: "Q{quarter}:{weekOfQuarter} Week,{dayOfQuarter} Day,{hourOfQuarter} Hour,{minuteOfQuarter} Minute,{secondOfQuarter} Second",
analyze_month_output: "{month}:{weekOfMonth} Week,{hourOfMonth} Hour,{minuteOfMonth} Minute,{secondOfMonth} Second"
}
{
"input": "Input",
"get":"Get Current",
"normal_second": "Normal Second",
"normal_millisecond":"Normal Millisecond",
"unix_second": "Unix Timestamp Second",
"unix_millisecond":"Unix Timestamp Millisecond",
"output": "Output",
"copy":"Copy",
"error_format": "Input Format Error",
"error":"error:{0}",
"format": "Format",
"value":"Value"
}
{
"input": "Input",
"encode": "Encode",
"decode": "Decode",
"mode_default": "Unicode Default",
"mode_wide": "Unicode Wide",
"mode_wide_bracket": "Unicode Wide(Has Bracket)",
"mode_number": "Unicode Number",
"mode_html_10": "HTML-code(Base-10)",
"mode_html_16": "HTML-code(Base-16)",
"mode_css_16": "Css-code(Base-16)",
"ignore_ascii": "Ignore Ascii",
"output": "Output",
"error": "error:{0}"
}
{
"length": "Length",
"area": "Area",
"volume": "Volume",
"weight": "Weight",
"temperature": "Temperature",
"pressure": "Pressure",
"power": "Power",
"work": "Work",
"density": "Density",
"strength": "Strength",
"time": "Time",
"speed": "Speed",
"byte": "Byte",
"angle": "Angle",
"length_km": "kilometres",
"length_m": "metre",
"length_dm": "decimetre",
"length_cm": "centimetre",
"length_mm": "millimetre",
"length_um": "Micrometre",
"length_nm": "Nanometre",
"length_pm": "Picometre",
"length_ly": "Light year",
"length_au": "Astronomical unit",
"length_in": "Inch",
"length_ft": "Foot",
"length_yd": "Yard",
"length_mi": "Mile",
"length_nmi": "Nautical mile",
"length_fm": "Fathom",
"length_fur": "furlong",
"length_cn_li": "lǐ",
"length_cn_zhang": "zhàng",
"length_cn_chi": "chǐ",
"length_cn_cun": "cùn",
"length_cn_fen": "fēn",
"length_cn_li2": "lí",
"length_cn_hao": "háo",
"area_km_2": "Square kilometre",
"area_ha": "Hectare",
"area_are": "Hectare Are",
"area_m_2": "Square metre",
"area_dm_2": "square decimetre",
"area_cm_2": "Square centimetre",
"area_mm_2": "Square millimeter",
"area_acre": "Acre",
"area_mi_2": "Square Acre",
"area_yd_2": "Square Yard",
"area_ft_2": "Square foot",
"area_in_2": "Square inch",
"area_rd_2": "Square rod",
"area_cn_qing": "qǐng",
"area_cn_mu": "mǔ",
"area_cn_fen": "fēn",
"area_cn_chi_2": "Square chǐ",
"area_cn_cun_2": "Square cùn",
"volume_m_3": "Cubic metre",
"volume_dm_3": "cubic decimeter",
"volume_cm_3": "Cubic centimeter",
"volume_mm_3": "Cubic millimeter",
"volume_l": "Litre",
"volume_dl": "deciliter",
"volume_ml": "milliliter",
"volume_cl": "centiliter",
"volume_uL": "microliter",
"volume_hl": "hectolitre",
"volume_ft_3": "Cubic feet",
"volume_in_3": "Cubic inch",
"volume_yd_3": "Cubic yards",
"volume_acre_ft": "acre foot",
"volume_uk_gal": "Uk gallon",
"volume_us_gal": "Us gallon",
"volume_uk_oz": "Uk ounce",
"volume_us_oz": "Us ounce",
"weight_kg": "kilogram",
"weight_g": "gram",
"weight_mg": "Milligrams",
"weight_ug": "microgram",
"weight_t": "Ton",
"weight_q": "Quintal",
"weight_ct": "carat",
"weight_lb": "Pound",
"weight_oz": "ounce",
"weight_gr": "Grain",
"weight_lt": "British long ton",
"weight_st1": "US short ton",
"weight_st2": "Stone",
"weight_uk_cwt": "British long hundredweight",
"weight_us_cwt": "US short hundredweight",
"weight_dr": "Dram",
"weight_cn_dan": "dān",
"weight_cn_jin": "jīn",
"weight_cn_liang": "liǎng",
"weight_cn_qian": "qián",
"temperature_c": "Celsius",
"temperature_f": "Fahrenheit",
"temperature_k": "Kelvin",
"temperature_r": "Rankine_scale",
"temperature_re": "Réaumur_scale",
"pressure_pa": "Pascal",
"pressure_kpa": "KPa",
"pressure_hpa": "HPa",
"pressure_atm": "Standard atmospheric pressure",
"pressure_mmhg": "MmHg",
"pressure_in_hg": "Inch mercury",
"pressure_bar": "bar",
"pressure_mbar": "millibar",
"pressure_psf": "Pounds per square feet",
"pressure_psi": "Pounds per square inch",
"pressure_mmwg": "mmH2O",
"pressure_kgf_cm_2": "Kgf/square centimeter",
"pressure_kgf_m_2": "Kgf/Square meter",
"pressure_mpa": "MPa",
"power_w": "watt",
"power_kw": "kilowatt",
"power_hp": "Imperial horsepower",
"power_ps": "Metric horsepower",
"power_kg_m_s": "Kg·m/sec",
"power_kcal_s": "Kcal/s",
"power_btu_s": "British Thermal Unit/sec",
"power_ft_lb_s": "Feet·lbs/sec",
"power_j_s": "Joule/sec",
"power_n_m_s": "Newton m/s",
"work_j": "joule",
"work_kg_m": "Kg·m",
"work_ps_h": "Metric horsepower·hour",
"work_hp_h": "British horsepower·hour",
"work_kw_h": "Kilowatt hour",
"work_kw_h_": "Spend",
"work_cal": "Card",
"work_kcal": "Kcal",
"work_btu": "British Thermal Unit",
"work_ft_lb": "Foot pound",
"work_kj": "Kilojoule",
"density_kg_cm_3": "Kg/Cubic centimeter",
"density_kg_dm_3": "Kg/cubic decimeter",
"density_kg_m_3": "Kg/Cubic metre",
"density_g_cm_3": "g/Cubic centimeter",
"density_g_dm_3": "g/cubic decimeter",
"density_g_m_3": "g/Cubic metre",
"strength_n": "Newton",
"strength_kn": "Kilogram Newton",
"strength_kgf": "Kilogram force",
"strength_gf": "Keli 克力",
"strength_tf": "Metric ton force",
"strength_lbf": "Pound force",
"strength_kip": "Kilopound force",
"strength_dyn": "Dyne",
"time_yr": "year",
"time_week": "week",
"time_d": "Day",
"time_h": "Hour",
"time_min": "Minute",
"time_s": "Second",
"time_ms": "millisecond",
"time_us": "Microseconds",
"time_ns": "Nanosecond",
"speed_m_s": "metre/Sec",
"speed_km_s": "kilometer/Sec",
"speed_km_h": "kilometer/Hour",
"speed_c": "Speed of light",
"speed_mach": "Maher",
"speed_mile_h": "Mile/hour",
"speed_in_s": "Inch/Sec",
"byte_bit": "Bit",
"byte_b": "byte",
"byte_kb": "Kilobytes",
"byte_mb": "Megabyte",
"byte_gb": "Gigabytes",
"byte_tb": "Terabyte",
"byte_pb": "Petabytes",
"byte_eb": "Exabytes",
"angle_circle": "circle",
"angle_angle": "angle",
"angle_gon": "grade",
"angle_degree": "degree",
"angle_min": "Minute",
"angle_s": "Second",
"angle_rad": "radian",
"angle_mrad": "Milliradian",
"metric_system": "Metric System",
"imperial_units": "Imperial Units",
"chinese_units": "Chinese Units",
"angle_units": "Angle Units",
"radian_units": "Radian Units",
"all": "All"
}
{
"input": "Input",
"encode": "Encode",
"decode": "Decode",
"output": "Output"
}
{
"amount": "Amount",
"delimiter": "Delimiter",
"hyphens": "Hyphens(-)",
"is_upper": "Upper",
"is_add_quote": "Add Quote",
"uint8_array": "Uint8 Array",
"output": "Output"
}
{
"input": "Input",
"input_placeholder":"A line of one"
}
{
"connect": "Connect",
"close": "Close",
"send_content": "Send Content",
"log_content": "Request/Response/Log Content",
"send": "Send",
"copy": "Copy",
"clear": "Clear",
"you": "You",
"server": "Server",
"error_connect": "Ws is not connected yet, or the connection fails, please check",
"error_content": "Send content cannot be empty",
"connect_ok": "Connect Success",
"close_ok": "Close Success",
"error": "error:{0}",
"connect_start": "Connecting:{0}",
"close_start": "Closing:{0}"
}
{
"convert": "转换",
"stringEscape": "字符串转义",
"codeGenFrida": "生成frida代码",
"codeGenX64dbgIdaVtable": "X64dbg断点虚表",
}
{
"info_source": "数据来源:",
"convert": "转换",
"output": "输出",
"error": "错误: {0}"
}
{
"convent": "转换",
"input_prompt": "多个字符用空格分隔",
"input_10": "十进制",
"input_16": "十六进制",
"input_8": "八进制",
"input_2": "二进制",
"input_string": "字符串",
"clear": "清空",
"code_table": "编码表",
"yes": "是",
"no": "否",
"input_null_prompt": "请输入对应的待转换编码",
"convent_error": "转换异常: {0}",
"is_show": "是否显示",
"description": "描述",
"code_nul": "空字符(Null)",
"code_soh": "标题开始",
"code_stx": "本文开始",
"code_etx": "本文结束",
"code_eot": "传输结束",
"code_enq": "请求",
"code_ack": "确认回应",
"code_bel": "响铃",
"code_bs": "退格",
"code_tab": "水平定位符号",
"code_lf": "换行键",
"code_vt": "垂直定位符号",
"code_ff": "换页键",
"code_cr": "归位键",
"code_so": "取消变换(Shift out)",
"code_si": "启用变换(Shift in)",
"code_dle": "跳出数据通讯",
"code_dc1": "设备控制一(XON 启用软件速度控制)",
"code_dc2": "设备控制二",
"code_dc3": "设备控制三(XOFF 停用软件速度控制)",
"code_dc4": "设备控制四",
"code_nak": "确认失败回应",
"code_syn": "同步用暂停",
"code_etb": "区块传输结束",
"code_can": "取消",
"code_em": "连接介质中断",
"code_sub": "替换",
"code_esc": "跳出",
"code_fs": "文件分割符",
"code_gs": "组群分隔符",
"code_rs": "记录分隔符",
"code_us": "单元分隔符",
"code_del": "删除",
"code_space": "空格"
}
{
"content": "内容",
"background": "背景",
"line_color": "线条颜色",
"bar_width": "条码宽",
"height": "条码高",
"margin": "外边距",
"show_text": "文本显示",
"hide": "隐藏",
"top": "上方",
"bottom": "下方",
"text_align": "水平位置",
"left": "居左",
"center": "居中",
"right": "居右",
"font": "字体",
"bold": "粗体",
"italic": "斜体",
"font_size": "大小",
"text_margin": "外边距",
"invalid_content": "无效条码内容"
}
{
"input": "输入",
"encode": "编码",
"decode": "解码",
"url_safe": "Url 安全",
"output": "输出",
"error": "错误: {0}",
"hex_dump": "Hex Dump",
"setting": "配置",
"hex_dump_show_mode":"显示模式",
"hex_dump_format": "格式",
"hex_dump_caps": "大小写",
"hex_dump_caps_lower": "小写",
"hex_dump_caps_upper": "大写",
"hex_dump_width":"宽度",
"hex_dump_show_mode_hex": "十六进制",
"hex_dump_show_mode_text": "文本",
"hex_dump_setting": "十六进制显示配置",
"hex_dump_format_twos": "2位",
"hex_dump_format_fours": "4",
"hex_dump_format_eights": "8位",
"hex_dump_format_sixteens": "16位",
"hex_dump_format_none": "无分隔"
}
{
"generate": "生成",
"password": "明文(String)",
"hash_password": "哈希(Hash)",
"rounds": "Rounds",
"generate_submit": "生成",
"check": "校验",
"check_submit": "校验",
"check_result_success": "正确",
"check_result_error": "错误",
"rounds_range": "Rounds 范围 [{0} - {1}]"
}
{
"input": "输入",
"length": "{0} 位",
"true_form": "原码",
"inverse": "反码",
"complement": "补码",
"error": "错误: {0}"
}
{
"more": "更多语言",
"indent": "代码缩进",
"indent_width": "缩进 空格 {0}",
"compress": "压缩",
"complete": "操作完成",
"error_prompt": "错误提示"
}
{
"expression": "表达式",
"execute_time": "最近执行时间",
"example": "例子",
"format": "格式",
"execute_time_list": "最近10次执行时间",
"no": "第{0}次: {1}",
"symbol": "特殊符号",
"description": "描述",
"symbol_description_1": "代表任何时刻都接受的意思。举例来说,范例一内那个日、月、周都是*,就代表着不论何月、何日的礼拜几的12:00都执行后续命令的意思。",
"symbol_description_2": "代表分隔时段的意思。举例来说,如果要执行的工作是3:00与6:00时,就会是:0 3,6 * * * command时间还是有五列,不过第二列是 3,6 ,代表3与6都适用",
"symbol_description_3": "代表一段时间范围内,举例来说,8点到12点之间的每小时的20分都进行一项工作:20 8-12 * * * command仔细看到第二列变成8-12.代表 8,9,10,11,12 都适用的意思",
"symbol_description_4": "那个n代表数字,即是每隔n单位间隔的意思,例如每五分钟进行一次,则:*/5 * * * * command用*与/5来搭配,也可以写成0-59/5,意思相同",
}
{
"input_placeholder": "请输入待转换数字",
"input": "转换数字",
"input_type_common": "常用",
"input_type_other": "其他",
"base": "{0} 进制",
"result": "转换结果 {0}",
"alphabet": "64位字母表",
"reset": "恢复默认",
"alphabet_length_error": "转换字母表必须是64位长度"
}
{
"more": "更多语言",
"collapse":"折叠相同",
"beautify":"格式化"
}
{
"input": "输入",
"password":"密码/密钥",
"encrypt": "加密",
"decrypt":"解密",
"generate_secret_key": "生成密钥对",
"output":"输出",
"public_key": "公钥:",
"private_key":"私钥:",
"secret_key_prompt": "请及时保存秘钥对, 关闭对话框后无法恢复当前秘钥数据",
"close":"关闭",
"failed": "操作失败:{0}"
}
{
"content": "内容",
"uppercase": "大写字母",
}
{
"input": "输入",
"output": "输出",
"uppercase": "大写字母",
}
{
"input": "输入",
"encode":"编码",
"decode": "解码",
"output":"输出"
}
{
"input": "请输入IP地址",
"query":"查询",
"local": "本地IP",
"info_source":"IP 信息来源",
"ok": "查询成功",
"error":"查询异常:{0}"
}
{
format: "输入格式",
ip: "IP地址",
mask: "掩码",
ip_info: "IP 信息",
ip_info_long: "整型IP",
ip_info_ip8: "点分八进制IP",
ip_info_ip10: "点分十进制IP",
ip_info_ip16: "点分十六进制IP",
ip_info_ip2: "点分二进制IP",
mask_info: "掩码信息",
mask_info_mask: "子网掩码",
mask_info_long: "整型掩码",
mask_info_opposite: "反掩码",
mask_info_mask8: "点分八进制掩码",
mask_info_mask16: "点分十六进制掩码",
mask_info_mask2: "点分二进制掩码",
network_info: "网络信息",
network_export: "导出可用IP",
network_info_available: "可用数量",
network_info_size: "全部数量",
network_info_base: "网络",
network_info_first: "第一个IP",
network_info_last: "最后一个IP",
network_info_broadcast: "广播地址",
mask_set_title: "通过可用IP数量设置掩码"
}
{
"input": "输入",
"output": "输出",
"json_input_empty": "请输入JSON内容",
"error":"异常:{0}",
"format": "格式化",
"compress":"压缩",
"escape": "转义",
"clear_escape":"移除转义",
"add_escape":"添加转义",
"unicode":"Unicode",
"unicode_to_zh": "Unicode转中文",
"zh_to_unicode":"中文转Unicode",
"complete": "处理完成",
"get": "Get参数",
"object":"转实体类",
"csv": "CSV",
"table":"Table",
"path":"Path",
"add_quote":"添加引号",
"column_name":"列名",
"json_type_json": "Json",
"json_type_keyed": "关联对象",
"json_type_array": "数组",
"json_type_column": "列数组",
"inline": "内联(inline)",
}
{
"input": "输入",
"decode":"解码",
"output": "输出",
"decode_fail":"解码失败:{0}"
}
{
// ui
"ui_setting": "设置",
"ui_reset": "重置",
"ui_views": "查看",
"ui_load": "加载",
"ui_close": "关闭",
"ui_issues": "问题反馈",
"ui_open_full": "打开全屏窗口",
"ui_copy_text_ok": "复制成功 ^o^",
"ui_copy_image_ok": "图片已复制 ^o^",
// 界面
"setting_language": "语言",
"common_tool": "常用工具",
"unselected_tool": "未选择工具",
"keyboard_setting": "快捷键设置",
"display_mode": "主题",
"display_mode_light": "浅色",
"display_mode_dark": "深色",
"display_mode_auto": "自动",
"copy_results_to_clipboard": "自动复制结果到剪贴板",
"read_content_from_clipboard": "自动读取剪贴板内容",
"read_clipboard_content_trim": "读取剪贴板内容过滤首尾不可见字符",
"common_tool_setting": "常用工具设置",
"keyboard_firefox_1": "请手动设置快捷键",
"keyboard_firefox_2": "请打开附加组件管理器(about:addons),点击“管理扩展程序”右侧的设置按钮,选择“管理扩展快捷键”来修改这些快捷键。",
"keyboard_firefox_3": "操作方法",
"history": "历史记录",
"history_clear": "清空历史记录",
"history_time": "操作时间",
"history_data": "数据",
"history_op": "操作",
"history_null": "暂无历史记录",
// 分类
"category_common": "常用",
"category_encryption": "加解密",
"category_conversion": "转换",
"category_encoder_decoder": "编解码",
"category_check": "校验",
"category_generate": "生成",
"category_other": "其他",
"category_yeahmao": "夜猫逐梦",
"category_code_gen": "代码生成器",
// 工具
"tool_hash": "哈希(hash)",
"tool_encrypt": "加密/解密",
"tool_sign": "签名/验签",
"tool_base64": "BASE64编码",
"tool_json": "JSON工具",
"tool_url": "URL编码",
"tool_timestamp": "时间戳",
"tool_qrCode": "二维码",
"tool_pinyin": "汉字转拼音",
"tool_ip": "IP地址查询",
"tool_code": "代码格式化",
"tool_unicode": "Unicode",
"tool_decimalConvert": "进制转换",
"tool_regex": "正则表达式",
"tool_randomString": "随机字符生成",
"tool_serializeConversion": "序列化转换",
"tool_diffs": "文本比对",
"tool_crontab": "Crontab",
"tool_websocket": "Websocket",
"tool_unit": "单位换算",
"tool_time": "时间计算器",
"tool_uuid": "UUID生成",
"tool_ascii": "ASCII",
"tool_variableConversion": "变量名",
"tool_jwt": "JWT解码",
"tool_hexString": "Hex/String",
"tool_hex2base64": "Hex/Base64",
"tool_text": "文本处理",
"tool_html": "Html编码",
"tool_binary": "原码/反码/补码",
"tool_armConverter": "ARM/HEX",
"tool_bcrypt": "Bcrypt",
"tool_ipcalc": "IP网络计算器",
"tool_hexConvert": "字节转换",
"tool_codeGenJson": "代码生成Json",
"tool_codeGenJava": "代码生成Java",
"tool_constFinder": "常量查找",
// 其他
"css_main_category_item_style": "padding: 0 20px",
"editor_line_wrapping": "自动换行",
// manifest
"manifest_name": "Ctool 程序开发常用工具",
"manifest_description": "程序开发常用工具,哈希/加解密/编码转换/时间戳/二维码/拼音/IP查询/代码优化/Unicode/正则等...",
"manifest_default_title": "常用开发工具",
"manifest_commands_panel_description": "打开独立工具窗口",
}
{
"input": "输入",
"normal":"无声调",
"tone": "有声调",
"abbr":"首字母",
"output": "输出",
"delimiter_null":"无分隔符",
"delimiter_space": "空格分隔",
"delimiter_1":"'-'中划线分隔",
"delimiter_2": "'_'下划线分隔",
"delimiter_3":"'.'点分隔"
}
{
"generate_title": "二维码生成",
"generate_input": "输入",
"generate_error": "生成错误:{0}",
"reader_title": "二维码解析",
"reader_input": "请输入二维码图片地址或点击下方按钮上传图片",
"reader_output": "输出",
"reader_error": "解析错误:{0}",
"reader_parsing_failure": "图片解析失败",
}
{
"length": "长度",
"amount":"数量",
"delimiter": "分隔符",
"digital":"数字",
"lowercase": "小写字母",
"uppercase":"大写字母",
"symbol": "特殊符号",
"unique":"唯一",
"add_quote": "添加引号",
"generate":"生成",
"output": "输出"
}
{
"reference": "参考",
"expression": "正则表达式",
"replace_content": "替换内容",
"replace": "替换",
"delete": "删除",
"input": "输入待处理内容",
"global": "全局搜索",
"ignore_case": "忽略大小写",
"output": "输出",
"output_count": "共 {0} 个匹配项",
"output_emty": "没有匹配结果,请检查正则",
"error": "错误:{0}",
}
{
"input": "输入",
"output":"输出",
"error": "错误:{0}"
}
{
"sign_data": "待签名内容/验签数据",
"verify_code": "Base64编码后签名",
"sign": "签名",
"verify": "验签",
"generate_keypair": "生成公钥/私钥",
"public_key": "PEM格式公钥",
"private_key": "PEM格式私钥",
"keypair_type": "密钥格式",
"keypair_length": "密钥长度",
"generate_cancel": "取消",
"generate_in": "生成中",
"generate": "生成",
"error_sign_content_empty": "待签名内容/PEM格式私钥 必填",
"error": "错误:{0}",
"error_verify_content_empty": "Base64编码后签名/PEM格式公钥 必填",
"verify_fail": "验签失败",
"verify_ok": "验签成功",
}
{
"content": "文本内容",
"input": "输入",
"resume": "恢复",
"case_conversion": "大小写转换",
"upper_all": "全部大写",
"lower_all": "全部小写",
"upper_line_start": "行首大写",
"lower_line_start": "行首小写",
"upper_word_start": "词首大写",
"lower_word_start": "词首小写",
"punctuation": "中英标点转换",
"cn": "中文",
"en": "英文",
"simplified_traditional": "简繁转换",
"simplified": "简体",
"traditional": "繁体",
"replace": "替换",
"line_remove_duplicate": "行去重",
"line_number": "行号",
"line_number_add": "添加",
"line_number_remove": "移除",
"line_sort": "行排序",
"line_sort_asc": "升序",
"line_sort_desc": "降序",
"filter": "过滤",
"filter_trim": "过滤行首尾不可见字符(trim)",
"filter_blank_line": "过滤多余空行",
"filter_all_br": "过滤换行符",
"stat": "统计",
"stat_explain": "统计说明",
"replace_search": "查找",
"replace_replace": "替换",
"replace_regular": "正则",
"replace_explain": "可输入多行, 按行进行批量替换",
"cancel": "取消",
"submit": "提交",
"string_length": "字符数",
"byte_length": "字节数(utf8/gbk)",
"word_length": "字数",
"line_length": "行数",
"zh_length": "(中文)字数/标点",
"en_length": "(英文)字母/单词/标点",
"int_length": "(数字)字符/单词",
"ok": "完成",
"error": "错误:{0}",
"item": "项目",
"explain": "说明",
"explain_byte_length_utf8_name": "字节数utf8",
"explain_byte_length_utf8_info": "中文字符计3个长度",
"explain_byte_length_gbk_name": "字节数gbk",
"explain_byte_length_gbk_info": "中文字符计2个长度",
"explain_string_length_name": "字符数",
"explain_string_length_info": "中/英文字符均计1个长度 换行符不计入长度",
"explain_word_length_name": "字数",
"explain_word_length_info": "中文字数+英文单词数+中文标点数+英文标点数+数字单词数",
"explain_int_length_name": "数字字符",
"explain_int_length_info": "统计单个数字出现次数 例如:'a1024 1024' 结果为:8",
"explain_int_word_length_name": "数字单词",
"explain_int_word_length_info": "例如:'a1024 1024' 结果为:1 其中:'a1024' 为英文单词 '1024' 为数字单词",
"explain_blank_line_length_name": "行数",
"explain_blank_line_length_info": "空行也会计入行数",
"value": "值",
"stat_show": "字数:{0} UTF-8:{1} GBK:{2}",
}
{
"diff_tool": "差值计算器",
"and": "与",
"diff": "相差",
"operation": "时间操作",
"add": "添加",
"reduce": "减少",
"after": "后",
"is": "为",
"error": "错误:{0}",
"error_duration_length": "年/月间隔只能是整数",
"current_time": "当前时间",
"current_date": "当前日期",
"current_month_date": "当月日期",
"current_year_date": "当年日期",
"year": "年",
"month": "月",
"week": "周",
"day": "日",
"hour": "小时",
"minute": "分钟",
"second": "秒",
analyze: "时间分析",
analyze_year: "年",
analyze_quarter: "季度",
analyze_month: "月",
analyze_year_output: "{year}年:{quarter}季度,{weekOfYear}周,{dayOfYear}天,{hourOfYear}小时,{minuteOfYear}分钟,{secondOfYear}秒",
analyze_quarter_output: "{quarter}季度:{weekOfQuarter}周,{dayOfQuarter}天,{hourOfQuarter}小时,{minuteOfQuarter}分钟,{secondOfQuarter}秒",
analyze_month_output: "{month}月:{weekOfMonth}周,{hourOfMonth}小时,{minuteOfMonth}分钟,{secondOfMonth}秒"
}
{
"input": "输入",
"get":"获取当前",
"normal_second": "标准时间(秒)",
"normal_millisecond":"标准时间(毫秒)",
"unix_second": "Unix时间戳(秒)",
"unix_millisecond":"Unix时间戳(毫秒)",
"output": "输出",
"copy":"复制",
"error_format": "输入时间格式异常",
"error":"错误:{0}",
"format": "格式",
"value":"值"
}
{
"input": "输入",
"encode": "编码",
"decode": "解码",
"mode_default": "Unicode 默认模式",
"mode_wide": "Unicode 宽字符模式",
"mode_wide_bracket": "Unicode 宽字符模式(带大括号)",
"mode_number": "Unicode 编码模式",
"mode_html_10": "Html 实体(10进制)",
"mode_html_16": "Html 实体(16进制)",
"mode_css_16": "Css 实体(16进制)",
"ignore_ascii": "忽略 Ascii 字符",
"output": "输出",
"error": "错误:{0}"
}
{
"length": "长度",
"area": "面积",
"volume": "体积",
"weight": "质量",
"temperature": "温度",
"pressure": "压力",
"power": "功率",
"work": "功/能/热",
"density": "密度",
"strength": "力",
"time": "时间",
"speed": "速度",
"byte": "数据存储",
"angle": "角度",
"length_km": "千米",
"length_m": "米",
"length_dm": "分米",
"length_cm": "厘米",
"length_mm": "毫米",
"length_um": "微米",
"length_nm": "纳米",
"length_pm": "皮米",
"length_ly": "光年",
"length_au": "天文单位",
"length_in": "英寸",
"length_ft": "英尺",
"length_yd": "码",
"length_mi": "英里",
"length_nmi": "海里",
"length_fm": "英寻",
"length_fur": "弗隆",
"length_cn_li": "里",
"length_cn_zhang": "丈",
"length_cn_chi": "尺",
"length_cn_cun": "寸",
"length_cn_fen": "分",
"length_cn_li2": "厘",
"length_cn_hao": "毫",
"area_km_2": "平方千米",
"area_ha": "公顷",
"area_are": "公亩",
"area_m_2": "平方米",
"area_dm_2": "平方分米",
"area_cm_2": "平方厘米",
"area_mm_2": "平方毫米",
"area_acre": "英亩",
"area_mi_2": "平方英里",
"area_yd_2": "平方码",
"area_ft_2": "平方英尺",
"area_in_2": "平方英寸",
"area_rd_2": "平方竿",
"area_cn_qing": "顷",
"area_cn_mu": "亩",
"area_cn_fen": "分",
"area_cn_chi_2": "平方尺",
"area_cn_cun_2": "平方寸",
"volume_m_3": "立方米",
"volume_dm_3": "立方分米",
"volume_cm_3": "立方厘米",
"volume_mm_3": "立方毫米",
"volume_l": "升",
"volume_dl": "分升",
"volume_ml": "毫升",
"volume_cl": "厘升",
"volume_uL": "微升",
"volume_hl": "公石",
"volume_ft_3": "立方英尺",
"volume_in_3": "立方英寸",
"volume_yd_3": "立方码",
"volume_acre_ft": "亩英尺",
"volume_uk_gal": "英制加仑",
"volume_us_gal": "美制加仑",
"volume_uk_oz": "英制液体盎司",
"volume_us_oz": "美制液体盎司",
"weight_kg": "千克",
"weight_g": "克",
"weight_mg": "毫克",
"weight_ug": "微克",
"weight_t": "吨",
"weight_q": "公担",
"weight_ct": "克拉",
"weight_lb": "磅",
"weight_oz": "盎司",
"weight_gr": "格令",
"weight_lt": "长吨",
"weight_st1": "短吨",
"weight_st2": "英石",
"weight_uk_cwt": "英担",
"weight_us_cwt": "美担",
"weight_dr": "打兰",
"weight_cn_dan": "担",
"weight_cn_jin": "斤",
"weight_cn_liang": "两",
"weight_cn_qian": "钱",
"temperature_c": "摄氏度",
"temperature_f": "华氏度",
"temperature_k": "开氏度",
"temperature_r": "兰氏度",
"temperature_re": "列氏度",
"pressure_pa": "帕斯卡",
"pressure_kpa": "千帕",
"pressure_hpa": "百帕",
"pressure_atm": "标准大气压",
"pressure_mmhg": "毫米汞柱",
"pressure_in_hg": "英寸汞柱",
"pressure_bar": "巴",
"pressure_mbar": "毫巴",
"pressure_psf": "磅力/平方英尺",
"pressure_psi": "磅力/平方英寸",
"pressure_mmwg": "毫米水柱",
"pressure_kgf_cm_2": "公斤力/平方厘米",
"pressure_kgf_m_2": "公斤力/平方米",
"pressure_mpa": "兆帕",
"power_w": "瓦",
"power_kw": "千瓦",
"power_hp": "英制马力",
"power_ps": "米制马力",
"power_kg_m_s": "公斤·米/秒",
"power_kcal_s": "千卡/秒",
"power_btu_s": "英热单位/秒",
"power_ft_lb_s": "英尺·磅/秒",
"power_j_s": "焦耳/秒",
"power_n_m_s": "牛顿·米/秒",
"work_j": "焦耳",
"work_kg_m": "公斤·米",
"work_ps_h": "米制马力·时",
"work_hp_h": "英制马力·时",
"work_kw_h": "千瓦·时",
"work_kw_h_": "度",
"work_cal": "卡",
"work_kcal": "千卡",
"work_btu": "英热单位",
"work_ft_lb": "英尺·磅",
"work_kj": "千焦",
"density_kg_cm_3": "千克/立方厘米",
"density_kg_dm_3": "千克/立方分米",
"density_kg_m_3": "千克/立方米",
"density_g_cm_3": "克/立方厘米",
"density_g_dm_3": "克/立方分米",
"density_g_m_3": "克/立方米",
"strength_n": "牛",
"strength_kn": "千牛",
"strength_kgf": "千克力",
"strength_gf": "克力",
"strength_tf": "公吨力",
"strength_lbf": "磅力",
"strength_kip": "千磅力",
"strength_dyn": "达因",
"time_yr": "年",
"time_week": "周",
"time_d": "天",
"time_h": "时",
"time_min": "分",
"time_s": "秒",
"time_ms": "毫秒",
"time_us": "微秒",
"time_ns": "纳秒",
"speed_m_s": "米/秒",
"speed_km_s": "千米/秒",
"speed_km_h": "千米/时",
"speed_c": "光速",
"speed_mach": "马赫",
"speed_mile_h": "英里/时",
"speed_in_s": "英寸/秒",
"byte_bit": "比特",
"byte_b": "字节",
"byte_kb": "千字节",
"byte_mb": "兆字节",
"byte_gb": "千兆字节",
"byte_tb": "太字节",
"byte_pb": "拍字节",
"byte_eb": "艾字节",
"angle_circle": "圆周",
"angle_angle": "直角",
"angle_gon": "百分度",
"angle_degree": "度",
"angle_min": "分",
"angle_s": "秒",
"angle_rad": "弧度",
"angle_mrad": "毫弧度",
"metric_system": "公制",
"imperial_units": "英制",
"chinese_units": "市制",
"angle_units": "角度制",
"radian_units": "弧度制",
"all": "全部"
}
{
"input": "输入",
"encode": "编码",
"decode": "解码",
"output": "输出"
}
{
"amount": "数量",
"delimiter": "分隔符",
"hyphens": "连接符(-)",
"is_upper": "大写",
"is_add_quote": "添加引号",
"uint8_array": "Uint8 Array",
"output": "输出"
}
{
"input": "输入",
"input_placeholder":"一行一个"
}
{
"connect": "连接",
"close": "断开",
"send_content": "发送内容",
"log_content": "交互记录",
"send": "发送",
"copy": "复制全部",
"clear": "清空",
"you": "你",
"server": "服务端",
"error_connect": "ws还没有连接,或者连接失败,请检测",
"error_content": "发送内容不能为空",
"connect_ok": "连接成功",
"close_ok": "断开成功",
"error": "错误:{0}",
"connect_start": "开始连接:{0}",
"close_start": "开始中断:{0}"
}
@import '~view-design/src/styles/index.less';
@import './theme_dark.css';
@primary-color: #1abc9c;
@link-color: #1abc9c;
.ivu-tooltip-content .ivu-tooltip-arrow{
display: none;
}
// 设置代码等宽字体
.CodeMirror-sizer
,.tool-monospace-font-family textarea
,.tool-monospace-font-family input
{
font-family: Consolas, Menlo, monospace, Courier;
}
/* 黑暗模式简单实现 */
html {
background-color: #fff;
}
/* 强制黑暗模 */
html[theme-mode='dark'] {
filter: invert(1) hue-rotate(180deg);
}
html[theme-mode='dark'] img,
html[theme-mode='dark'] picture,
html[theme-mode='dark'] video,
html[theme-mode='dark'] .dark-exclude {
filter: invert(1) hue-rotate(180deg);
}
html[theme-mode='dark'] .ivu-drawer-mask {
filter: invert(1) hue-rotate(180deg);
background-color: rgba(0, 0, 0, .6);
}
/* 自动识别 */
@media (prefers-color-scheme: dark) {
html[theme-mode='auto'] {
filter: invert(1) hue-rotate(180deg);
}
html[theme-mode='auto'] img,
html[theme-mode='auto'] picture,
html[theme-mode='auto'] video,
html[theme-mode='auto'] .dark-exclude {
filter: invert(1) hue-rotate(180deg);
}
html[theme-mode='auto'] .ivu-drawer-mask {
filter: invert(1) hue-rotate(180deg);
background-color: rgba(0, 0, 0, .6);
}
}
import Vue from 'vue'
import ViewUI from 'view-design'
import './statics/theme.less'
import router from './tool.router'
import optionBlock from './components/optionBlock'
import inputBlock from './components/inputBlock'
import {plugin as modelPlugin} from './tool/model'
import cache from './tool/cache'
import setting from './tool/setting'
import App from './tool.vue'
import {isUtools,isWeb} from './helper'
import theme from './tool/theme'
import {setCurrentLocale,i18n} from "./i18n";
const run = () => {
// 设置语言环境
setCurrentLocale(setting.locale())
// 设置显示模式
theme(setting.displayMode())
Vue.config.productionTip = false
Vue.use(ViewUI)
Vue.use(modelPlugin)
Vue.component('option-block', optionBlock);
Vue.component('input-block', inputBlock);
new Vue({
i18n,
router,
render: h => h(App),
}).$mount('#app')
// 清理缓存数据
setTimeout(() => {
cache.clear()
}, 500)
}
(function () {
if (document.body.clientWidth > 900 || isUtools || isWeb) {
const page = document.getElementById('page')
page.style.width = 'auto'
page.style.height = 'auto'
}
if (isUtools) {
window.utools.onPluginReady(() => {
run()
})
} else {
run()
}
})()
import Vue from 'vue'
import Router from 'vue-router'
import {env} from './helper'
import {stringify as qsStringify} from "qs";
import user from "./tool/user";
Vue.use(Router)
export const stat = (action, data = {}) => {
setTimeout(() => {
try {
let img = new Image(1, 1);
img.src = 'https://www.baiy.org/chrome_tool/stat/?' + qsStringify({
v: env('version'),
a: action,
u: user.uid(),
p: env('platform'),
r: Math.random(),
...data
});
} catch (e) {
// todo
}
}, 3000)
};
// 路由配置
const routes = [
{
path: '/tool/base64',
component: r => require(['./views/tool/base64.vue'], r)
},
{
path: '/tool/code',
component: r => require(['./views/tool/code.vue'], r)
},
{
path: '/tool/decimalConvert',
component: r => require(['./views/tool/decimalConvert.vue'], r)
},
{
path: '/tool/diffs',
component: r => require(['./views/tool/diffs.vue'], r)
},
{
path: '/tool/encrypt',
component: r => require(['./views/tool/encrypt.vue'], r)
},
{
path: '/tool/sign',
component: r => require(['./views/tool/sign.vue'], r)
},
{
path: '/tool/hash',
component: r => require(['./views/tool/hash.vue'], r)
},
{
path: '/tool/ip',
component: r => require(['./views/tool/ip.vue'], r)
},
{
path: '/tool/serializeConversion',
component: r => require(['./views/tool/serializeConversion.vue'], r)
},
{
path: '/tool/pinyin',
component: r => require(['./views/tool/pinyin.vue'], r)
},
{
path: '/tool/qrCode',
component: r => require(['./views/tool/qrCode.vue'], r)
},
{
path: '/tool/barcode',
component: r => require(['./views/tool/barcode.vue'], r)
},
{
path: '/tool/randomString',
component: r => require(['./views/tool/randomString.vue'], r)
},
{
path: '/tool/regex',
component: r => require(['./views/tool/regex.vue'], r)
},
{
path: '/tool/timestamp',
component: r => require(['./views/tool/timestamp.vue'], r)
},
{
path: '/tool/unicode',
component: r => require(['./views/tool/unicode.vue'], r)
},
{
path: '/tool/url',
component: r => require(['./views/tool/url.vue'], r)
},
{
path: '/tool/crontab',
component: r => require(['./views/tool/crontab.vue'], r)
},
{
path: '/tool/websocket',
component: r => require(['./views/tool/websocket.vue'], r)
},
{
path: '/tool/unit',
component: r => require(['./views/tool/unit.vue'], r)
},
{
path: '/tool/time',
component: r => require(['./views/tool/time.vue'], r)
},
{
path: '/tool/json',
component: r => require(['./views/tool/json.vue'], r)
},
{
path: '/tool/uuid',
component: r => require(['./views/tool/uuid.vue'], r)
},
{
path: '/tool/ascii',
component: r => require(['./views/tool/ascii.vue'], r)
},
{
path: '/tool/variableConversion',
component: r => require(['./views/tool/variableConversion.vue'], r)
},
{
path: '/tool/jwt',
component: r => require(['./views/tool/jwt.vue'], r)
},
{
path: '/tool/hexString',
component: r => require(['./views/tool/hexString.vue'], r)
},
{
path: '/tool/hex2base64',
component: r => require(['./views/tool/hex2base64.vue'], r)
},
{
path: '/tool/text',
component: r => require(['./views/tool/text.vue'], r)
},
{
path: '/tool/html',
component: r => require(['./views/tool/html.vue'], r)
},
{
path: '/tool/binary',
component: r => require(['./views/tool/binary.vue'], r)
},
{
path: '/tool/armConverter',
component: r => require(['./views/tool/armConverter.vue'], r)
},
{
path: '/tool/bcrypt',
component: r => require(['./views/tool/bcrypt.vue'], r)
},
{
path: '/tool/ipcalc',
component: r => require(['./views/tool/ipcalc.vue'], r)
},
{
path: '/yeahmao/hexConvert',
component: r => require(['./views/yeahmao/hexConvert.vue'], r)
},
{
path: '/yeahmao/constFinder',
component: r => require(['./views/yeahmao/constFinder'], r)
},
{
path: '/yeahmao/code_gen/codeGenJson',
component: r => require(['./views/yeahmao/code_gen/codeGenJson.vue'], r)
},
{
path: '/yeahmao/code_gen/codeGenJava',
component: r => require(['./views/yeahmao/code_gen/codeGenJava.vue'], r)
}
]
const router = new Router({routes})
stat('index')
router.afterEach(to => {
stat('tool', {tool: to.path})
})
export default router
<template>
<div>
<Menu class="tool-category-menu-block" mode="horizontal" theme="light" :active-name="currentCategory" @on-select="categorySelect"
style="height: 45px;line-height: 45px;">
<MenuItem :style="$t('main_css_main_category_item_style')" :name="cat.name" v-for="(cat) in category" :key="cat.name">
<Badge v-if="badgeCategoryIsShow(cat.name)" dot :offset="[15,-10]">
{{ $t('main_category_'+cat.name) }}
</Badge>
<template v-else>
{{ $t('main_category_'+cat.name) }}
</template>
</MenuItem>
</Menu>
<RadioGroup class="tool-select-block" :value="currentTool" @on-change="toolSelect" style="margin: 10px 0 10px 20px;line-height: 30px;">
<Radio :label="tool.name" v-for="(tool) in tools" :key="tool.name">
<Badge v-if="badgeToolIsShow(tool.name)" dot :offset="[5,-5]">
{{ $t('main_tool_'+tool.name) }}
</Badge>
<template v-else>
{{ $t('main_tool_'+tool.name) }}
</template>
</Radio>
</RadioGroup>
<div>
<router-view ref="routerView" v-if="isRouterAlive" :key="$route.path + $route.query.t"/>
</div>
<bottom-block/>
</div>
</template>
<script>
import config from './tool/config'
import {dispatchWindowResize, I18N_CHANGE} from './tool/event'
import instance from './tool/instance'
import BottomBlock from './components/bottom'
import model from './tool/model'
import {isUtools} from './helper'
export default {
components: {
"bottom-block": BottomBlock
},
data() {
return {
isRouterAlive: true,
isUtools: isUtools,
category: config.category,
currentCategory: '',
currentTool: '',
}
},
computed: {
tools() {
return config.getToolByCategory(this.currentCategory)
}
},
watch: {
currentTool(name) {
console.log(name)
model.setCurrentTool(name)
if (['hexConvert', 'constFinder'].indexOf(name) != -1) {
this.$router.push('/yeahmao/' + name)
} else if (['codeGenJson', 'codeGenJava'].indexOf(name) != -1) {
this.$router.push('/yeahmao/code_gen/' + name)
} else {
this.$router.push('/tool/' + name)
}
},
},
created() {
if (this.isUtools) {
window.utools.onPluginEnter(({code, payload, type}) => {
window.utools.showMainWindow()
let tool = "";
let feature = "";
if (code.indexOf('ctool-') !== -1) {
tool = code.replace(/ctool-/g, "")
if (tool.indexOf('-') !== -1) {
let temp = tool.split('-');
tool = temp[0]
feature = temp[1]
}
}
// 写入正则匹配数据到固定数据数据
if (["over","regex"].includes(type) && payload) {
model.setFixeInputData(payload)
}
if (feature) {
// 设置工具内功能
model.setToolCurrentFeature(feature)
}
if (tool && this.currentTool !== tool) {
let cat = config.getToolDefaultCategory(tool);
if (cat) {
model.setCategoryHistory(cat)
model.setToolHistory(cat, tool)
this.currentCategory = cat;
this.currentTool = tool;
}
}
this.reload()
})
}
this.currentCategory = model.getCategoryHistory()
this.currentTool = model.getToolHistory(this.currentCategory)
this.$Message.config({
top: 150,
})
},
mounted() {
instance.set(this)
window.addEventListener(I18N_CHANGE, ()=>{
this.$forceUpdate()
this.$refs.routerView.$forceUpdate()
});
},
methods: {
reload() {
this.isRouterAlive = false
this.$nextTick(() => (this.isRouterAlive = true))
},
categorySelect(name) {
this.currentCategory = name
model.setCategoryHistory(name)
this.currentTool = model.getToolHistory(this.currentCategory)
this.$nextTick(()=>{
dispatchWindowResize()
})
},
toolSelect(name) {
model.setToolHistory(this.currentCategory, name)
this.currentTool = name
},
badgeToolIsShow(tool) {
return config.badgeToolIsShow(tool)
},
badgeCategoryIsShow(cat) {
return config.badgeCategoryIsShow(cat)
},
},
}
</script>
const path = require('path');
const _ = require('lodash');
const fs = require('fs');
const i18nBuild = require('../i18n/build')
// 运行平台适配
let platform = process.env.hasOwnProperty('npm_config_adapter') ? process.env.npm_config_adapter : "";
platform = ['chrome', 'utools', 'edge', 'firefox', 'web'].includes(platform) ? platform : "web"
const IS_CHROME = "chrome" === platform
const IS_EDGE = "edge" === platform
const IS_FIREFOX = "firefox" === platform
const IS_UTOOLS = "utools" === platform
const IS_CHROMIUM = ['chrome', 'edge'].includes(platform)
const IS_WEB = "web" === platform
const toolConfig = require('../config')
const tools = toolConfig.tool
const utoolsConfig = toolConfig.utools
const featureConfig = toolConfig.feature
const getToolFeatureTitle = (name, features = []) => {
for (let i = 0; i < features.length; i++) {
if (features[i]['name'] === name) {
return features[i].title
}
}
return name
}
// 删除文件
const removeFile = (filePath) => {
fs.existsSync(filePath) && fs.unlinkSync(filePath)
}
// 删除目录
const removeDir = function (directoryPath) {
if (fs.existsSync(directoryPath)) {
fs.readdirSync(directoryPath).forEach((file) => {
const curPath = path.join(directoryPath, file);
if (fs.lstatSync(curPath).isDirectory()) {
removeDir(curPath);
} else {
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(directoryPath);
}
};
const chromiumAndFirefoxI18nBuild = ()=>{
// 生成语言包
const locales = i18nBuild.getLocales().detail
const localeDir = path.join(__dirname, '../../public/_locales/')
fs.mkdirSync(localeDir);
Object.keys(locales).forEach((_locale) => {
fs.mkdirSync(path.join(localeDir, _locale));
let messages = {}
Object.keys(locales[_locale]).forEach((key) => {
let message = {
message: locales[_locale][key]['message'].replace(new RegExp("{.+?}", 'g'), (item) => {
return `$${item.replace("{", "").replace("}", "").toUpperCase()}$`;
})
}
if ("placeholders" in locales[_locale][key]) {
message.placeholders = {}
let index = 1;
locales[_locale][key]['placeholders'].forEach((placeholder) => {
message.placeholders[placeholder] = {content: "$" + (index++)}
})
}
messages[key] = message
})
fs.writeFileSync(path.join(localeDir, `${_locale}/messages.json`), JSON.stringify(messages, null, 4));
})
}
const chromeConfigWrite = {
remove() {
},
write() {
if (!IS_CHROME) {
return;
}
fs.writeFileSync(
path.join(__dirname, '../../public/manifest.json'),
fs.readFileSync(path.join(__dirname, "../adapter/chrome/manifest.json")).toString().replace(/##version##/g, process.env.npm_package_version)
);
}
}
const edgeConfigWrite = {
remove() {
},
write() {
if (!IS_EDGE) {
return;
}
fs.writeFileSync(
path.join(__dirname, '../../public/manifest.json'),
fs.readFileSync(path.join(__dirname, "../adapter/edge/manifest.json")).toString().replace(/##version##/g, process.env.npm_package_version)
);
}
}
const chromiumConfigWrite = {
remove() {
removeFile(path.join(__dirname, '../../public/manifest.json'));
removeFile(path.join(__dirname, '../../public/background.js'));
// 移除语言包目录
removeDir(path.join(__dirname, '../../public/_locales/'))
},
write() {
if (!IS_CHROMIUM) {
return;
}
fs.copyFileSync(
path.join(__dirname, "../adapter/chromium/background.js"),
path.join(__dirname, '../../public/background.js')
);
// 生成语言包
chromiumAndFirefoxI18nBuild()
}
}
const firefoxConfigWrite = {
remove() {
removeFile(path.join(__dirname, '../../public/manifest.json'));
removeFile(path.join(__dirname, '../../public/background.js'));
// 移除语言包目录
removeDir(path.join(__dirname, '../../public/_locales/'))
},
write() {
if (!IS_FIREFOX) {
return;
}
fs.copyFileSync(
path.join(__dirname, "../adapter/firefox/background.js"),
path.join(__dirname, '../../public/background.js')
);
fs.writeFileSync(
path.join(__dirname, '../../public/manifest.json'),
fs.readFileSync(path.join(__dirname, "../adapter/firefox/manifest.json")).toString().replace(/##version##/g, process.env.npm_package_version)
);
// 生成语言包
chromiumAndFirefoxI18nBuild()
}
}
const utoolsConfigWrite = {
remove() {
removeFile(path.join(__dirname, '../../public/plugin.json'));
},
write() {
if (!IS_UTOOLS) {
return;
}
let pluginPath = path.join(__dirname, '../../public/plugin.json');
fs.readFile(path.join(__dirname, "../adapter/utools/plugin.json"), 'utf8', function (err, files) {
if (err) return console.log(err);
let utoolsToolFeature = {};
for (let tool of tools) {
// 初始化数据
let code = "ctool-" + tool.name;
let toolTitle = i18nBuild.translate(`main_tool_${tool.name}`)
let toolFeatures = featureConfig.hasOwnProperty(tool.name) ? featureConfig[tool.name] : []
if (!utoolsToolFeature.hasOwnProperty(code)) {
utoolsToolFeature[code] = {
"code": code,
"explain": toolTitle,
"cmds": []
}
if (toolFeatures.length > 0) {
for (let toolFeature of toolFeatures) {
let toolFeatureCode = code + '-' + toolFeature['name']
utoolsToolFeature[toolFeatureCode] = {
"code": toolFeatureCode,
"explain": toolTitle + ' - ' + toolFeature['title'],
"cmds": []
}
}
}
}
// 关键字
let keyword = utoolsConfig['keyword'].hasOwnProperty(tool.name) ? utoolsConfig['keyword'][tool.name] : []
utoolsToolFeature[code].cmds.push(
...Array.from(new Set([tool.name, toolTitle, "ctool-" + tool.name, ...keyword]))
)
// cmds手动配置
let cmds = utoolsConfig['cmds'].hasOwnProperty(tool.name) ? utoolsConfig['cmds'][tool.name] : []
if (!cmds.length) {
continue;
}
for (let _cmd of cmds) {
let cmd = _.cloneDeep(_cmd);
if (!cmd.hasOwnProperty('feature')) {
cmd['label'] = toolTitle
utoolsToolFeature[code].cmds.push(cmd)
continue;
}
let toolFeatureCode = code + '-' + cmd.feature
if (utoolsToolFeature.hasOwnProperty(toolFeatureCode)) {
cmd['label'] = toolTitle + ' - ' + getToolFeatureTitle(cmd.feature, toolFeatures)
delete cmd.feature
utoolsToolFeature[toolFeatureCode].cmds.push(cmd)
}
}
}
let features = [
{
"code": "ctool",
"explain": "程序开发常用工具",
"cmds": ['ctool', '程序开发常用工具']
},
...Object.values(utoolsToolFeature)
];
let result = files
.replace(/##version##/g, process.env.npm_package_version)
.replace(/"##features##"/g, JSON.stringify(features));
fs.writeFileSync(pluginPath, result);
});
}
}
module.exports = {
platform: platform,
isChrome: IS_CHROME,
isChromium: IS_CHROMIUM,
isFirefox: IS_FIREFOX,
isEdge: IS_EDGE,
isWeb: IS_WEB,
isUtools: IS_UTOOLS,
initialize: function () {
// 移除配置文件
chromiumConfigWrite.remove();
chromeConfigWrite.remove();
edgeConfigWrite.remove();
firefoxConfigWrite.remove();
utoolsConfigWrite.remove();
// 添加配置文件
chromiumConfigWrite.write();
chromeConfigWrite.write();
edgeConfigWrite.write();
firefoxConfigWrite.write();
utoolsConfigWrite.write();
// 生成运行时语言包
i18nBuild.generate()
}
}
import db from './db'
import {version} from '../helper'
const cacheVersion = version.split('.').join('');
// 缓存key添加版本号
const cacheNameConvert = function (name) {
return 'v_' + cacheVersion + '_' + name
}
const cache = {
set(name, value, expiry = 0) {
return db.set(cacheNameConvert(name), value, expiry)
},
get(name, defaultValue = null) {
let data = db.get(cacheNameConvert(name))
return data === null ? defaultValue : data
},
remove(name) {
db.remove(cacheNameConvert(name))
return db.remove(cacheNameConvert(name))
},
setNoVersion(name, value, expiry = 0) {
return db.set('nv_' + name, value, expiry)
},
getNoVersion(name, defaultValue = null) {
let data = db.get('nv_' + name)
return data === null ? defaultValue : data
},
removeNoVersion(name) {
return db.remove('nv_' + name)
},
// 清理数据
clear() {
setTimeout(() => {
// 清理过期数据
db.clear();
// 清理过期版本数据
clearExpireVersion();
}, 100);
}
};
const clearExpireVersion = () => {
const cache_version_name = "cache_version";
if (cacheVersion === cache.getNoVersion(cache_version_name)) {
return;
}
cache.setNoVersion(cache_version_name, cacheVersion)
for (let key of db.getAllKey()) {
let c = /^v_(\d+)_/.exec(key)
if (c === null) {
continue;
}
if (cacheVersion !== c[1].trim()) {
db.remove(key)
}
}
}
export default cache
\ No newline at end of file
import {isUtools} from '../helper'
// 剪贴板操作
export const copy = (data,successCallback)=>{
document.querySelector(
'#clipboard').innerHTML = '<textarea id="clipboard-text"></textarea>'
document.querySelector('#clipboard-text').value = data
document.querySelector('#clipboard-text').select()
if (document.execCommand('copy')) {
successCallback && successCallback()
}
document.querySelector('#clipboard').innerHTML = ''
}
export const paste = ()=>{
document.querySelector(
'#clipboard').innerHTML = '<textarea id="clipboard-text"></textarea>'
document.querySelector('#clipboard-text').select()
document.execCommand('paste')
let r = document.querySelector('#clipboard-text').value ||
document.querySelector('#clipboard-text').innerHTML
document.querySelector('#clipboard').innerHTML = ''
return r ? r : ''
}
export const copyImage = (imageBase64,successCallback = "")=>{
if (isUtools && imageBase64){
window.utools.copyImage(imageBase64)
successCallback && successCallback()
}
}
export default {
copy,
paste,
copyImage
}
import {env} from '../helper'
import cache from './cache'
const toolConfig = require('../config')
// 工具缓存数据过期时间(秒)
export const TOOL_DATA_EXPIRY = toolConfig.toolDataExpiry
// 徽章过期时间(天)
export const BADGE_EXPIRY = toolConfig.badgeExpiry
// 分类徽章
export const BADGE_CATEGORY = toolConfig.badgeCategory
// 工具徽章
export const BADGE_TOOL = toolConfig.badgeTool
// 默认常用工具
export const DEFAULT_COMMON_TOOL = toolConfig.defaultCommonTool
const category = toolConfig.category
const tool = toolConfig.tool
// 徽章是否显示
const badgeIsShow = function () {
return (Date.parse((new Date()).toString()) / 1000) - env('updateTime') <
BADGE_EXPIRY * 86400
}
const getUserCommon = function () {
let tools = cache.getNoVersion('user_common')
return tools ? tools : DEFAULT_COMMON_TOOL
}
const setUserCommon = function (tools) {
cache.setNoVersion('user_common', tools)
}
const getToolDefaultCategory = function (name) {
for (let i = 0; i < tool.length; i++) {
if (tool[i].name === name) {
return tool[i].cat[0]
}
}
return ''
}
const getToolByName = (name) => {
for (let item of tool) {
if (name === item.name) {
return item
}
}
return null
}
/**
* @param name
* @param defaultValue
* @return {any}
*/
const getSetting = function (name, defaultValue = null) {
let setting = cache.getNoVersion('setting', {})
return !setting.hasOwnProperty(name) ? defaultValue : setting[name]
}
/**
* @param name
* @param value
* @return {boolean}
*/
const saveSetting = function (name, value) {
let setting = cache.getNoVersion('setting', {})
setting[name] = value
cache.setNoVersion('setting', setting);
return true
}
export default {
tool: tool,
saveSetting,
getSetting,
category,
setUserCommon,
getUserCommon,
getToolByCategory(cat) {
if (cat === 'common') {
return getUserCommon().map((name) => {
return getToolByName(name)
}).filter((item) => {
return item !== null
});
}
return tool.filter((t) => {
return t.cat.includes(cat);
})
},
getToolDefaultCategory,
badgeToolIsShow(tool) {
return badgeIsShow() && BADGE_TOOL.includes(tool)
},
badgeCategoryIsShow(cat) {
return badgeIsShow() && BADGE_CATEGORY.includes(cat)
},
}
import {isUtools} from '../helper'
import utoolsDb from '../adapter/utools/db'
import defaultDb from '../adapter/default/db'
const db = isUtools ? utoolsDb : defaultDb;
export default {
get(key, def = null) {
return db.get(key, def)
},
set(key, value, expiry = 0) {
return db.set(key, value, expiry)
},
remove(key) {
return db.remove(key)
},
// 清理过期
clear() {
return db.clear();
},
getAllKey() {
return db.getAllKey();
}
}
\ No newline at end of file
// 窗口大小调整事件
export const WINDOW_RESIZE = "ctoolWindowResize"
// 语言地区变化事件
export const I18N_CHANGE = "ctoolI18nChange"
export const dispatchWindowResize = () => {
window.dispatchEvent(new CustomEvent(WINDOW_RESIZE));
}
export const dispatchI18nChange = () => {
window.dispatchEvent(new CustomEvent(I18N_CHANGE));
}
// 原生窗口调整事件
window.addEventListener("resize", ()=>{
dispatchWindowResize()
});
import crypto from 'crypto-js'
import moment from 'moment'
import cache from './cache'
import {TOOL_DATA_EXPIRY} from './config'
import _ from "lodash";
let loadHistoryIndex = -1
let forceLoadHistory = false
function queueDataFactory(value) {
return {
'time': moment().format('YYYY-MM-DD HH:mm:ss'),
'hash': crypto.MD5(JSON.stringify(value)).toString(),
'value': value,
}
}
class queue {
data = []
name = ''
max = 10
constructor(name, max = 50) {
this.name = name
this.max = max
// 初始化数据
this.data = cache.get(this.getCacheName(), [])
}
getCacheName() {
return 'tool_data_history_' + this.name
}
push(value) {
// 过滤超大数据
if (JSON.stringify(value).length > 200 * 1024){
console.log("Data Too Big")
return;
}
let item = queueDataFactory(value)
// 删除已有
for (let i = 0; i < this.data.length; i++) {
if (this.data[i].hash === item.hash) {
this.data.splice(i, 1)
}
}
this.data.unshift(item)
// 删除多余
if (this.length() > this.max) {
this.data.pop()
}
cache.set(this.getCacheName(), this.data, TOOL_DATA_EXPIRY)
}
length() {
return this.data.length
}
all() {
return this.data
}
clear() {
cache.remove(this.getCacheName())
}
get(index) {
return _.cloneDeep(this.data.hasOwnProperty(index) ? this.data[index].value : {})
}
current() {
if (loadHistoryIndex < 0) {
return this.get(0)
}
let index = loadHistoryIndex
loadHistoryIndex = -1
return this.get(index)
}
}
const history = (name) => {
return new queue(name)
}
export const setForceLoadHistoryIndex = (index) => {
forceLoadHistory = true
loadHistoryIndex = index
}
export const getForceLoadHistory = (name) => {
if (forceLoadHistory) {
forceLoadHistory = false
let data = history(name).current()
return _.isEmpty(data) ? null : data
}
return null
}
export default history
import config from "./config";
let instance = null;
export default {
set(t) {
if (instance === null) {
instance = t
}
},
get() {
return instance
},
enter(name) {
if (instance !== null) {
let cat = config.getToolDefaultCategory(name);
if (cat) {
instance.categorySelect(cat)
}
instance.toolSelect(name)
}
}
}
\ No newline at end of file
import config from './config'
import clipboard from './clipboard'
import setting from './setting'
import cache from './cache'
import history,{getForceLoadHistory} from './history.js'
import _ from "lodash";
let fixeInputData;
let toolCurrentFeature = "";
const model = {
getCategoryHistory() {
return cache.get('page_category_history', 'common')
},
setCategoryHistory(cat) {
return cache.set('page_category_history', cat)
},
getToolHistory(cat) {
let all = cache.get('category_tool_history', {})
if (all[cat]) {
return all[cat]
}
return config.getToolByCategory(cat)[0]['name']
},
setToolHistory(cat, name) {
let all = cache.get('category_tool_history', {})
all[cat] = name
return cache.set('category_tool_history', all)
},
getCurrentTool() {
return cache.get('current_tool', '')
},
setCurrentTool(name) {
return cache.set('current_tool', name)
},
setFixeInputData: (value) => {
fixeInputData = value;
},
setToolCurrentFeature: (value) => {
toolCurrentFeature = value;
},
getToolCurrentFeature: (def = "") => {
let temp = toolCurrentFeature
toolCurrentFeature = "";
return temp ? temp : def
}
}
// 保存历史记录防抖
let debounceSaveToolData = {};
const debounceSaveToolDataMethod = _.debounce(function () {
return history(debounceSaveToolData['tool']).push(debounceSaveToolData['data'])
}, 1000)
const appendData = async function (check = "",all) {
const result = (data = "") => {
if (data) {
if (
!check
|| (_.isFunction(check) && check(data,all)) // 函数校验
) {
return data
}
}
return ""
}
return new Promise(async (resolve) => {
try {
// 使用固定输入数据
if (fixeInputData) {
let temp = fixeInputData
fixeInputData = ""
return resolve(result(temp))
}
if (setting.autoReadCopy()) {
let paste = (await clipboard.paste()).trim()
if (paste) {
resolve(result(paste))
}
}
resolve(result())
} catch {
resolve(result())
}
});
}
export const plugin = {
install: function (Vue) {
Vue.prototype.$initToolData = function (input = "", inputCheck = "", field = "current", isLoadHistory = true) {
let current = _.cloneDeep(this[field])
//强制使用历史数据
let forceHistory = getForceLoadHistory(model.getCurrentTool())
if (forceHistory){
Object.assign(current, forceHistory)
this[field] = current
return;
}
let inputHistory = ""
let inputDefault = ""
let inputAppend = ""
// 默认数据
if (input && (input in current) && current[input]) {
inputDefault = current[input];
}
// 历史数据
if (isLoadHistory) {
let history = this.$getToolData()
Object.assign(current, history)
if (input && (input in history)) {
inputHistory = history[input]
delete history[input]
}
}
if (!input) {
this[field] = current
return;
}
// 追加剪贴板等数据
appendData(inputCheck,current).then((append) => {
inputAppend = append
this[field] = Object.assign(
current,
{
// 追加数据 > 历史数据 > 默认数据
[input]: inputAppend ? inputAppend : (inputHistory ? inputHistory : inputDefault)
}
)
})
}
Vue.prototype.$getToolData = function () {
return _.cloneDeep(history(model.getCurrentTool()).current())
}
Vue.prototype.$saveToolData = function (data, ignoreDebounce = false) {
if (ignoreDebounce) {
return history(model.getCurrentTool()).push(_.cloneDeep(data))
}
debounceSaveToolData = {tool: model.getCurrentTool(), data: _.cloneDeep(data)}
debounceSaveToolDataMethod()
}
Vue.prototype.$clipboardCopy = function (data, force = false) {
if ((setting.autoSaveCopy() || force)) {
this.$copy(data)
}
}
Vue.prototype.$copy = function (data) {
if (data) {
clipboard.copy(data, () => {
this.$Message.success(this.$t('main_ui_copy_text_ok').toString())
})
}
}
Vue.prototype.$clipboardCopyImages = function (data, force = false) {
if ((setting.autoSaveCopy() || force) && data) {
clipboard.copyImage(data, () => {
this.$Message.success(this.$t('main_ui_copy_image_ok').toString())
})
}
}
},
}
export default model
import config from './config'
export default {
/**
* @param value
* @return {boolean}
*/
autoSaveCopy(value = null) {
if (value === null) {
return config.getSetting('auto_save_copy', true)
}
return config.saveSetting('auto_save_copy', value)
},
/**
* @param value
* @return {boolean}
*/
autoReadCopy(value = null) {
if (value === null) {
return config.getSetting('auto_read_copy', true)
}
return config.saveSetting('auto_read_copy', value)
},
/**
* @param value
* @return {boolean}
*/
autoReadCopyFilter(value = null) {
if (value === null) {
return config.getSetting('auto_read_copy_filter', false)
}
return config.saveSetting('auto_read_copy_filter', value)
},
/**
* @param value
* @return {boolean}
*/
displayMode(value = null) {
if (value === null) {
return config.getSetting('display_mode', 'light')
}
return config.saveSetting('display_mode', value)
},
}
export default (mode) => {
mode = ['light', 'dark', 'auto'].includes(mode) ? mode : 'light'
console.log(`set display mode:${mode}`)
document.getElementsByTagName('html')[0].setAttribute('theme-mode', mode);
}
import cache from './cache'
import {uuid} from '../helper'
const cache_name = "user_uuid"
export default {
uid() {
let id = cache.getNoVersion(cache_name);
if (id === null) {
id = uuid()
cache.setNoVersion(cache_name, id)
}
return id
}
}
\ No newline at end of file
<template>
<div>
<div>
<CellGroup @on-click="open">
<Cell :title="$t('main_common_tool')" name="setting"/>
<Cell v-if="is_chromium || is_firefox" :title="$t('main_keyboard_setting')" name="shortcuts"/>
<Cell :title="$t('main_display_mode')">
<Select v-model="display_mode" slot="extra" transfer>
<Option v-for="item in display_mode_list" :value="item" :key="item">{{ $t('main_display_mode_'+item)}}</Option>
</Select>
</Cell>
<Cell :title="$t('main_setting_language')">
<Select v-model="locale" slot="extra" transfer>
<Option v-for="item in locales" :value="item.code" :key="item.code">{{ item.name }}</Option>
</Select>
</Cell>
</CellGroup>
<CellGroup>
<Cell :title="$t('main_copy_results_to_clipboard')">
<i-switch v-model="auto_save_copy" slot="extra"/>
</Cell>
<Cell :title="$t('main_read_content_from_clipboard')">
<i-switch v-model="auto_read_copy" slot="extra"/>
</Cell>
<Cell :title="$t('main_read_clipboard_content_trim')">
<i-switch v-model="auto_read_copy_filter" slot="extra"/>
</Cell>
</CellGroup>
</div>
<Drawer :title="$t('main_common_tool_setting')" placement="left" v-model="commonShow" :width="100">
<setting-common v-if="commonShow"></setting-common>
</Drawer>
</div>
</template>
<script>
import {isChromium, isFirefox, isUtools, openUrl} from '../../helper'
import theme from '../../tool/theme'
import {LOCALE_LISTS, setCurrentLocale} from '../../i18n'
import setting from '../../tool/setting'
import {dispatchI18nChange} from '../../tool/event'
import common from "./common"
export default {
components: {
"setting-common": common
},
data() {
return {
commonShow: false,
auto_save_copy: true,
auto_read_copy: true,
display_mode: "light",
auto_read_copy_filter: false,
is_chromium: isChromium,
is_utools: isUtools,
is_firefox: isFirefox,
display_mode_list: ["light","dark","auto"],
locales: LOCALE_LISTS,
locale: "",
}
},
watch: {
display_mode(value) {
theme(value)
},
locale(value) {
setCurrentLocale(value)
dispatchI18nChange()
}
},
created() {
this.auto_save_copy = setting.autoSaveCopy()
this.auto_read_copy = setting.autoReadCopy()
this.auto_read_copy_filter = setting.autoReadCopyFilter()
this.display_mode = setting.displayMode()
this.locale = setting.locale()
},
beforeDestroy() {
setting.autoSaveCopy(this.auto_save_copy)
setting.autoReadCopy(this.auto_read_copy)
setting.autoReadCopyFilter(this.auto_read_copy_filter)
setting.displayMode(this.display_mode)
setting.locale(this.locale)
},
methods: {
open(name) {
switch (name) {
case 'shortcuts':
if (this.is_firefox) {
return this.$Notice.success({
title: this.$t('main_keyboard_firefox_1'),
render: h => {
return h('span', [
this.$t('main_keyboard_firefox_2'),
h('a', {
attrs: {
href: 'https://jingyan.baidu.com/article/3ea51489f1d0a713e61bbaff.html',
target: '_blank'
}
}, this.$t('main_keyboard_firefox_3')),
])
}
});
}
openUrl('chrome://extensions/shortcuts')
break
case 'setting':
this.commonShow = true
break
}
}
},
}
</script>
<template>
<div>
<Card :title="$t('main_common_tool')">
<draggable v-model="selected" group="tool">
<Button style="margin: 5px" v-for="name in selected" type="dashed" :key="name">{{$t('main_tool_'+name)}}</Button>
</draggable>
<Button size="small" slot="extra" type="primary" @click="reset">{{$t('main_ui_reset')}}</Button>
</Card>
<Card :title="$t('main_unselected_tool')" style="margin-top: 10px">
<draggable v-model="unselected" group="tool">
<Button style="margin: 5px" v-for="name in unselected" type="dashed" :key="name">{{$t('main_tool_'+name)}}</Button>
</draggable>
</Card>
</div>
</template>
<script>
import config from "../../tool/config"
import {DEFAULT_COMMON_TOOL} from "../../tool/config"
import draggable from "vuedraggable";
export default {
components: {
draggable
},
data() {
return {
style:"",
selected:[],
unselected:[],
tools: [],
}
},
created() {
this.selected = config.getToolByCategory('common').map(function (item) {
return item.name;
});
this.unselected = config.tool.filter(({name})=>{
return !this.selected.includes(name)
}).map(function (item) {
return item.name;
})
},
watch:{
selected(){
config.setUserCommon(this.selected ? this.selected : []);
}
},
methods:{
reset(){
this.selected = DEFAULT_COMMON_TOOL
}
}
}
</script>
<template>
<div class="tool-armConverter">
<Tabs v-model="current.operation">
<TabPane label="ARM to HEX" name="arm_to_hex"/>
<TabPane label="HEX to ARM" name="hex_to_arm"/>
<Alert style="padding: 5px;margin-bottom:0" slot="extra">
{{ $t('armConverter_info_source') }} <a href="https://armconverter.com/" target="_blank">https://armconverter.com/</a>
</Alert>
</Tabs>
<Row :gutter="10">
<Col span="10">
<div class="page-option-input-block" style="margin-bottom: 5px">
<Input v-model="current.offset" placeholder="0 - for branch and LDR put hex value here">
<span slot="prepend">Offset (hex) 0x</span>
</Input>
</div>
<input-block top="5px">
<heightResize :reduce="45" :append="['.page-option-input-block']">
<autoHeightTextarea v-if="isArmToHex" v-model="current.asm_input" :placeholder="inputPlaceholder"/>
<autoHeightTextarea v-else v-model="current.hex_input" :placeholder="inputPlaceholder"/>
</heightResize>
<template slot="extra">
<Button :loading="loading" type="primary" size="small" @click="convert()">{{ $t('armConverter_convert') }}</Button>
</template>
</input-block>
</Col>
<Col span="14">
<Card dis-hover class="page-option-output-block">
<p slot="title">{{ $t('armConverter_output') }}</p>
<div slot="extra">
<Checkbox :disabled="!isArmToHex" v-model="current.prefix_0x">0x</Checkbox>
<Checkbox :disabled="!isArmToHex" v-model="current.swap_endian">GDB/LLDB</Checkbox>
</div>
</Card>
<heightResize :reduce="45" :append="['.page-option-output-block']" @resize="resize">
<input-block :text="'ARM64'+endianPlaceholder" @on-default-right-bottom-click="()=>$copy(outputArm64)">
<autoHeightTextarea :value="outputArm64" :height="outputHeight" :placeholder="'ARM64'+endianPlaceholder"/>
</input-block>
<input-block :text="'ARM'+endianPlaceholder" @on-default-right-bottom-click="()=>$copy(outputArm)">
<autoHeightTextarea style="margin-top: 5px" :value="outputArm" :height="outputHeight" :placeholder="'ARM'+endianPlaceholder"/>
</input-block>
<input-block :text="'ARM Big Endian'" @on-default-right-bottom-click="()=>$copy(outputArmBigEndian)" v-if="!isArmToHex">
<autoHeightTextarea style="margin-top: 5px" :value="outputArmBigEndian" :height="outputHeight" :placeholder="'ARM Big Endian'"/>
</input-block>
<input-block :text="'THUMB'+endianPlaceholder" @on-default-right-bottom-click="()=>$copy(outputThumb)">
<autoHeightTextarea style="margin-top: 5px" :value="outputThumb" :height="outputHeight" :placeholder="'THUMB'+endianPlaceholder"/>
</input-block>
<input-block :text="'THUMB Big Endian'" @on-default-right-bottom-click="()=>$copy(outputThumbBigEndian)" v-if="!isArmToHex">
<autoHeightTextarea style="margin-top: 5px" :value="outputThumbBigEndian" :height="outputHeight" :placeholder="'THUMB Big Endian'"/>
</input-block>
</heightResize>
</Col>
</Row>
</div>
</template>
<script>
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
import axios from "axios";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData()
},
computed: {
isArmToHex() {
return this.current.operation === 'arm_to_hex';
},
endianPlaceholder() {
return this.isArmToHex && this.current.swap_endian ? " Big Endian" : ""
},
inputPlaceholder() {
if (this.isArmToHex) {
return "Input Assembly code:\nNOP\nRET\nB #0x1018DE444\nMOV X0, #0x11FE00000000\nBEQ #0x10020C\nCBNZ R0, #0x682C4"
}
return "Input Hex code:\n40000494\nC0035FD6\nF0 B5 03 AF81b0"
},
outputArm64() {
return this.convertResult('arm64')
},
outputArm() {
return this.convertResult('arm')
},
outputThumb() {
return this.convertResult('thumb')
},
outputArmBigEndian() {
return this.convertResult('armbe')
},
outputThumbBigEndian() {
return this.convertResult('thumbbe')
},
outputHeight() {
return this.isArmToHex ? (this.pageOutputHeight - 10) / 3 : (this.pageOutputHeight - 20) / 5
},
response(){
return this.isArmToHex ? this.current.asm_response : this.current.hex_response
}
},
methods: {
resize(height) {
this.pageOutputHeight = height;
},
convert() {
this.loading = true
try {
let data = {};
if (this.isArmToHex) {
if (!this.current.asm_input){
throw new Error("input error")
}
data = {
"asm": this.current.asm_input,
"offset": this.current.offset,
"arch": ["arm64", "arm", "thumb"]
};
this.current.asm_response = ""
} else {
if (!this.current.hex_input){
throw new Error("input error")
}
data = {
"hex": this.current.hex_input,
"offset": this.current.offset,
"arch": ["arm64", "arm", "armbe", "thumb", "thumbbe"]
};
this.current.hex_response = ""
}
this.request(data)
} catch (error) {
this.loading = false
return this.$Message.error(
this.$t('armConverter_error', [error.message]).toString()
)
}
},
request(data) {
axios({
url: 'https://www.baiy.org/chrome_tool/armconverter/',
method: 'post',
data: JSON.stringify(data),
headers: {'Content-Type': 'application/json'}
}).then(({data}) => {
if (data.code !== 0) {
return this.$Message.error(
this.$t('armConverter_error', [data.info]).toString()
)
}
if (this.isArmToHex){
this.current.asm_response = data.data["hex"]
}
else{
this.current.hex_response = data.data["asm"]
}
this.$saveToolData(this.current);
}).catch((error) => {
return this.$Message.error(
this.$t('armConverter_error', [error.message]).toString()
)
}).then( ()=> {
this.loading = false
});
},
convertResult(field) {
if (!this.response || !(field in this.response)) {
return "";
}
let text = this.response[field][1]
if (
!this.isArmToHex
|| (!this.current.prefix_0x && !this.current.swap_endian)
) {
return text;
}
const size = {
arm64: 4,
arm: 4,
armbe: 4,
thumb: 2,
thumbbe: 2
}
// prefix_0x && swap_endian
return text.split('\n').map((line) => {
return this.swap(line, size[field], this.current.prefix_0x ? "0x" : "")
}).join('\n');
},
swap(text, size, prefix) {
if (!text || text.startsWith('#')) {
// this is an error, not actual code
return text;
}
if (!this.current.swap_endian) {
return prefix + text;
}
const size_chars = size * 2;
let result = '';
for (let i = 0; i < text.length; i += size_chars) {
const chunk = text.slice(i, i + size_chars);
for (let j = chunk.length; j > 0; j -= 2) {
result += chunk.slice(j - 2, j);
}
}
return prefix + result;
}
},
data() {
return {
current: {
operation: "arm_to_hex",
asm_input: "",
hex_input: "",
offset: "",
asm_response: "",
hex_response: "",
prefix_0x: false,
swap_endian: false
},
loading:false,
pageOutputHeight: 100
}
},
}
</script>
<style>
.tool-armConverter .ivu-tabs-bar {
margin-bottom: 8px;
}
.tool-armConverter .ivu-card-head {
line-height: 31px;
height: 31px;
padding: 0 16px;
}
.tool-armConverter .ivu-card-head p {
line-height: 31px;
height: 31px;
font-weight: normal;
color: #515a6e;
}
.tool-armConverter .ivu-card-extra {
top: 3px;
}
.tool-armConverter .ivu-card-bordered {
border-bottom: none;
}
.tool-armConverter .ivu-card-body {
padding: 0;
}
.tool-armConverter .ivu-card {
margin-bottom: 5px;
}
</style>
<template>
<div>
<Tabs v-model="operation">
<TabPane label="转换" name="convent">
<option-block>
<Input v-model="current.data.dec" placeholder="多个字符用空格分隔">
<div slot="prepend" style="width: 100px"><strong>十进制</strong></div>
</Input>
</option-block>
<option-block>
<Input v-model="current.data.hex" placeholder="多个字符用空格分隔">
<div slot="prepend" style="width: 100px"><strong>十六进制</strong></div>
</Input>
</option-block>
<option-block>
<Input v-model="current.data.oct" placeholder="多个字符用空格分隔">
<div slot="prepend" style="width: 100px"><strong>八进制</strong></div>
</Input>
</option-block>
<option-block>
<Input v-model="current.data.bin" placeholder="多个字符用空格分隔">
<div slot="prepend" style="width: 100px"><strong>二进制</strong></div>
</Input>
</option-block>
<option-block>
<Input v-model="current.data.str">
<div slot="prepend" style="width: 100px"><strong>字符串</strong></div>
</Input>
</option-block>
<option-block :style="{textAlign:'center'}">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle()" style="margin-right: 5px">转换</Button>
<Button type="primary" @click="clear()">清空</Button>
</ButtonGroup>
</FormItem>
</option-block>
</TabPane>
<TabPane label="编码表" name="reader">
<Table :columns="referenceColumns" :data="reference">
</Table>
</TabPane>
</Tabs>
</div>
</template>
<script>
import ascii from './library/ascii';
export default {
computed: {
reference() {
let lists = [];
for (let index=0; index < ascii.ascii_map.length; index++) {
let ob = new ascii.Ascii(index,'dec')
let isShow = !ascii.ascii_hidden.hasOwnProperty(ascii.ascii_map[index])
lists.push({
dec:ob.dec(),
hex:ob.hex(),
oct:ob.oct(),
bin:ob.bin(),
str:ob.str(),
show:isShow ? "" : "",
explain:isShow ? ob.str() : ascii.ascii_hidden[ascii.ascii_map[index]]
})
}
return lists;
},
},
created() {
this.current = Object.assign(this.current, this.$getToolData())
},
methods: {
handle() {
let s = "";
let currentType = "";
try {
for (const type of this.types) {
if (this.current.data[type]) {
s = this.current.data[type]
currentType = type
break;
}
}
if (!s){
throw "请输入对应的待转换编码"
}
} catch (err) {
return this.$Message.error("转换异常:" + err);
}
for (const type of this.types) {
this.current.data[type] = ascii.convent(s,currentType,type)
}
this.$saveToolData(this.current);
},
clear() {
for (const type of this.types) {
this.current.data[type] = ""
}
}
},
data() {
return {
types:['str', 'dec', 'hex', 'oct', 'bin'],
current: {
data: {
dec: "",
hex: "",
oct: "",
bin: "",
str: "",
}
},
operation: "convent",
referenceColumns: [
{
title: '十进制',
key: 'dec',
width:100
},
{
title: '十六进制',
key: 'hex',
width:100
},
{
title: '八进制',
key: 'oct',
width:100
},
{
title: '二进制',
key: 'bin',
},
{
title: '字符',
key: 'str',
width:100
},
{
title: '是否可见',
key: 'show',
width:100
},
{
title: '字符说明',
key: 'explain',
}
],
}
}
}
</script>
\ No newline at end of file
<template>
<div>
<div id="barcode-setting">
<Row :gutter="10">
<Col span="12">
<Form :label-width="80">
<FormItem :label="$t('barcode_content')">
<Input v-model="current.text">
<Select v-model="current.format" slot="append" style="width: 100px">
<Option v-for="type in barcodeFormat" :key="type" :value="type">{{ type }}</Option>
</Select>
</Input>
</FormItem>
<Row>
<Col span="12">
<FormItem :label="$t('barcode_background')">
<ColorPicker recommend v-model="current.background"/>
</FormItem>
</Col>
<Col span="12">
<FormItem :label="$t('barcode_line_color')">
<ColorPicker recommend v-model="current.lineColor"/>
</FormItem>
</Col>
</Row>
<FormItem :label="$t('barcode_bar_width')">
<Row>
<Col span="21">
<Slider v-model="current.width" :min="1" :max="4"></Slider>
</Col>
<Col span="3">
<span style="float: right">{{ this.current.width }}</span>
</Col>
</Row>
</FormItem>
<FormItem :label="$t('barcode_height')">
<Row>
<Col span="21">
<Slider v-model="current.height" :min="10" :max="150"></Slider>
</Col>
<Col span="3">
<span style="float: right">{{ this.current.height }}</span>
</Col>
</Row>
</FormItem>
<FormItem :label="$t('barcode_margin')">
<Row>
<Col span="21">
<Slider v-model="current.margin" :min="0" :max="25"></Slider>
</Col>
<Col span="3">
<span style="float: right">{{ this.current.margin }}</span>
</Col>
</Row>
</FormItem>
</Form>
</Col>
<Col span="12">
<Form :label-width="80">
<FormItem :label="$t('barcode_show_text')">
<RadioGroup v-model="current.textPosition" type="button">
<Radio label="close">
<span>{{ $t('barcode_hide') }}</span>
</Radio>
<Radio label="top">
<span>{{ $t('barcode_top') }}</span>
</Radio>
<Radio label="bottom">
<span>{{ $t('barcode_bottom') }}</span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem :label="$t('barcode_text_align')">
<RadioGroup v-model="current.textAlign" type="button">
<Radio :disabled="!showText" label="left">
<span>{{ $t('barcode_left') }}</span>
</Radio>
<Radio :disabled="!showText" label="center">
<span>{{ $t('barcode_center') }}</span>
</Radio>
<Radio :disabled="!showText" label="right">
<span>{{ $t('barcode_right') }}</span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem :label="$t('barcode_font')">
<Row :gutter="10">
<Col span="12">
<Select :disabled="!showText" v-model="current.font">
<Option v-for="font in fontFamily" :key="font" :value="font">{{ font }}</Option>
</Select>
</Col>
<Col span="12">
<CheckboxGroup v-model="current.fontOptions">
<Checkbox :disabled="!showText" label="bold">
<span>{{ $t('barcode_bold') }}</span>
</Checkbox>
<Checkbox :disabled="!showText" label="italic">
<span>{{ $t('barcode_italic') }}</span>
</Checkbox>
</CheckboxGroup>
</Col>
</Row>
</FormItem>
<FormItem :label="$t('barcode_font_size')">
<Row>
<Col span="22">
<Slider :disabled="!showText" v-model="current.fontSize" :min="8"
:max="36"></Slider>
</Col>
<Col span="2">
<span style="float: right">{{ this.current.fontSize }}</span>
</Col>
</Row>
</FormItem>
<FormItem :label="$t('barcode_text_margin')">
<Row>
<Col span="22">
<Slider :disabled="!showText" v-model="current.textMargin" :min="-15"
:max="40"></Slider>
</Col>
<Col span="2">
<span style="float: right">{{ this.current.textMargin }}</span>
</Col>
</Row>
</FormItem>
</Form>
</Col>
</Row>
</div>
<heightResize @resize="resize" ignore :append="['#barcode-setting']">
<div :style="`height: ${outputHeight}px;line-height:${outputHeight}px;text-align: center;vertical-align: middle;`">
<canvas @click="saveImage" :style="`border: ${canvasBorder};vertical-align: middle;`" ref="barcode"
class="barcode" v-show="!validStr" style="cursor:pointer"></canvas>
<p style="color: red" v-show="validStr">{{ validStr }}</p>
</div>
</heightResize>
</div>
</template>
<script>
/**
* @author alvinkwok
* @date 2021/10/30
* 基于jsbarcode生成条形码,可以自定义条码各项属性
* 不支持中文
*/
import JsBarcode from 'jsbarcode'
import heightResize from "./components/heightResize";
export default {
components: {
heightResize
},
created() {
this.$initToolData('text')
},
computed: {
showText() {
return ['top', 'bottom'].includes(this.current.textPosition)
},
canvasBorder() {
if (this.current.background.toUpperCase() === "#FFFFFF") {
return "1px dashed #666"
}
return "1px dashed #fff";
}
},
mounted() {
this.generate()
},
watch: {
current: {
handler() {
this.generate()
},
deep: true
}
},
methods: {
generate() {
// 处理字体样式
let fontOptions = this.current.fontOptions.join(" ")
const barcodeContent = this.current.text ? this.current.text : "Example 1234"
JsBarcode(this.$refs.barcode, barcodeContent, {
format: this.current.format,
width: this.current.width,
height: this.current.height,
margin: this.current.margin,
background: this.current.background,
lineColor: this.current.lineColor,
displayValue: this.showText,
textPosition: this.current.textPosition,
textAlign: this.current.textAlign,
font: this.current.font,
fontOptions: fontOptions,
fontSize: this.current.fontSize,
textMargin: this.current.textMargin,
valid: (valid) => {
this.validStr = !valid ? `"${barcodeContent}" ${this.$t('barcode_invalid_content').toString()}` : "";
if (!this.validStr && this.current.text) {
this.$saveToolData(this.current)
}
}
})
},
saveImage() {
if (!this.validStr && this.current.text) {
this.$clipboardCopyImages(this.$refs.barcode.toDataURL("image/png"), true)
}
},
resize(height){
this.outputHeight = Math.max(250,height)
}
},
data() {
return {
outputHeight:250,
current: {
text: "",
format: "CODE128",
width: 2,
height: 50,
margin: 10,
background: "#FFFFFF",
lineColor: "#000000",
textAlign: "center",
textPosition: "bottom",
font: "monospace",
fontOptions: [],
fontSize: 20,
textMargin: 0
},
validStr: '',
// 条码格式
barcodeFormat: [
"CODE128",
"CODE128A",
"CODE128B",
"CODE128C",
"EAN13",
"EAN8",
"UPC",
"CODE39",
"ITF14",
"ITF",
"MSI",
"MSI10",
"MSI11",
"MSI1010",
"MSI1110",
"pharmacode",
],
fontFamily: [
"monospace",
"Sans-serif",
"Serif",
"Fantasy",
"Cursive"
],
barcodeBase64: "",
}
},
}
</script>
<style scoped>
/**iview原来的formitem太高了,在浏览器直接使用插件时会被撑开,因此需要压缩下高度**/
#barcode-setting .ivu-form-item {
margin-bottom: 2px;
}
</style>
<template>
<heightResize @resize="resize" :reduce="52" ignore>
<Tabs v-model="current.operation">
<TabPane :label="$t('base64_encode')" name="encode">
<div style="position: relative;">
<input-block style="margin-bottom: 10px">
<autoHeightTextarea :height="height1" v-model="current.encode.input"
:placeholder="$t('base64_input')"/>
<template slot="extra">
<updateFile @success="handleUpload"/>
</template>
</input-block>
<disableMask v-if="isEncodeUploadFile" @close="encodeUploadFile = {}">
{{ this.encodeUploadFile.file.name }}
</disableMask>
</div>
<input-block>
<autoHeightTextarea :height="height2" :value="encodeOutput" :placeholder="$t('base64_output')"/>
<template slot="extra">
<Checkbox v-model="current.encode.is_url_safe">{{ $t('base64_url_safe') }}</Checkbox>
</template>
</input-block>
</TabPane>
<TabPane :label="$t('base64_decode')" name="decode">
<input-block style="margin-bottom: 10px">
<autoHeightTextarea :height="height1" v-model="current.decode.input"
:placeholder="$t('base64_input')"/>
</input-block>
<input-block bottom="5px" right="20px">
<autoHeightTextarea :class="isDecodeShowBinaryData ? 'tool-monospace-font-family' : ''"
:height="height2"
:value="decodeError ? decodeError : decodeOutput"
:placeholder="$t('base64_output')"/>
<template slot="extra">
<Button v-if="isExportFile" shape="circle" icon="md-download" @click="exportFile"/>
<Button style="margin-left: 10px" v-if="isDecodeIncludeBinaryData" shape="circle"
icon="md-settings" @click="decodeSetting=true"/>
</template>
</input-block>
</TabPane>
</Tabs>
<Modal v-model="decodeSetting" :title="$t('base64_setting')" footer-hide width="500" draggable :mask="false">
<Form :label-width="120">
<FormItem :label="$t('base64_hex_dump_show_mode')">
<RadioGroup v-model="current.decode.show_mode">
<Radio label="hex">{{ $t('base64_hex_dump_show_mode_hex') }}</Radio>
<Radio label="text">{{ $t('base64_hex_dump_show_mode_text') }}</Radio>
</RadioGroup>
</FormItem>
<template v-if="isHexShowMode">
<Divider plain>{{ $t('base64_hex_dump_setting') }}</Divider>
<FormItem :label="$t('base64_hex_dump_format')">
<RadioGroup v-model="current.decode.hex_dump_option.format">
<Radio label="twos">{{ $t('base64_hex_dump_format_twos') }}</Radio>
<Radio label="fours">{{ $t('base64_hex_dump_format_fours') }}</Radio>
<Radio label="eights">{{ $t('base64_hex_dump_format_eights') }}</Radio>
<Radio label="sixteens">{{ $t('base64_hex_dump_format_sixteens') }}</Radio>
<Radio label="none">{{ $t('base64_hex_dump_format_none') }}</Radio>
</RadioGroup>
</FormItem>
<FormItem :label="$t('base64_hex_dump_caps')">
<RadioGroup v-model="current.decode.hex_dump_option.caps">
<Radio label="lower">{{ $t('base64_hex_dump_caps_lower') }}</Radio>
<Radio label="upper">{{ $t('base64_hex_dump_caps_upper') }}</Radio>
</RadioGroup>
</FormItem>
<FormItem :label="$t('base64_hex_dump_width')">
<InputNumber :min="1" v-model="current.decode.hex_dump_option.width"/>
</FormItem>
</template>
</Form>
</Modal>
</heightResize>
</template>
<script>
import {Base64} from 'js-base64'
import {hexy} from 'hexy'
import mimeType from 'mime-types'
import {fromBuffer as fileTypeFromBuffer} from 'file-type/browser';
import moment from "moment";
import heightResize from "./components/heightResize";
import disableMask from "./components/disableMask.vue";
import autoHeightTextarea from "./components/autoHeightTextarea";
import updateFile from './components/updateFile';
export default {
components: {
updateFile,
heightResize,
disableMask,
autoHeightTextarea
},
created() {
this.$initToolData()
},
computed: {
isEncodeUploadFile() {
return "file" in this.encodeUploadFile
},
encodeOutput() {
// 上传文件
if (this.isEncodeUploadFile) {
return this.encodeUploadFile.base64
}
let input = this.current.encode.input.trim();
if (!input) {
return "";
}
return this.encode(input, {is_url_safe: this.current.encode.is_url_safe})
},
decodeOutput() {
try {
let input = this.decodeBase64Data
if (!input) {
return "";
}
// 二进制数据
if (this.isDecodeShowBinaryData) {
return this.decodeBinaryData(
Buffer.from(input.buffer),
this.current.decode.hex_dump_option
)
}
return new TextDecoder().decode(input)
} catch (e) {
return this.$t('base64_error', [e.message()])
}
},
decodeBase64Data() {
let input = this.current.decode.input.trim()
return this.decode(this.isDecodeFile ? input.split(',')[1] : input)
},
isDecodeFile() {
let input = this.current.decode.input.trim()
return input.indexOf('data:') === 0 && input.indexOf(",") > 4
},
isDecodeShowBinaryData() {
return this.isDecodeIncludeBinaryData && this.isHexShowMode
},
isDecodeIncludeBinaryData() {
return this.decodeBase64Data && this.decodeBase64Data.includes(0)
},
isExportFile() {
return this.isDecodeIncludeBinaryData || this.isDecodeFile
},
isHexShowMode() {
return this.current.decode.show_mode === "hex"
}
},
watch: {
current: {
handler(val) {
if (
(val.operation === "encode" && !val.encode.input)
|| (val.operation === "decode" && !val.decode.input)
) {
return;
}
this.$saveToolData(val)
},
deep: true
}
},
methods: {
handleUpload(file) {
this.current.operation = "encode"
let r = new FileReader()
r.readAsDataURL(file)
r.onloadend = () => {
this.encodeUploadFile = {file: file, base64: r.result}
}
},
encode(data, {is_url_safe = false} = {}) {
return Base64.encode(data, is_url_safe)
},
decode(data) {
try {
this.decodeError = "";
if (!data) {
return false;
}
if (!Base64.isValid(data)) {
throw "input error"
}
return Base64.toUint8Array(data)
} catch (e) {
this.decodeError = this.$t('base64_error', [e.toString()]).toString()
return false;
}
},
decodeBinaryData(buffer, option) {
return hexy(buffer, option)
},
async exportFile() {
if (!this.isExportFile) {
return;
}
let mime = "";
let extension = "";
if (this.isDecodeFile) {
// Data URLs
let arr = this.current.decode.input.trim().split(',')
mime = arr[0].match(/:(.*?);/)[1]
extension = mimeType.extension(mime) ? `.${mimeType.extension(mime)}` : ""
} else {
let type = await fileTypeFromBuffer(this.decodeBase64Data)
if (type) {
mime = type.mime;
extension = type.ext ? `.${type.ext}` : "";
}
}
let objectUrl = window.URL.createObjectURL(new Blob([this.decodeBase64Data], {type: mime}));
let aEle = document.createElement("a");
aEle.download = `ctool-base64-decode-${moment().unix()}${extension}`;
aEle.href = objectUrl;
aEle.click();
aEle.remove();
window.URL.revokeObjectURL(objectUrl);
},
resize(height) {
this.height1 = Math.min(160, Math.ceil(height / 2))
this.height2 = height - this.height1 - 10
}
},
data() {
return {
current: {
encode: {
input: '',
is_url_safe: false,
},
decode: {
input: '',
show_mode: "hex",
hex_dump_option: {
format: "twos",
caps: "lower",
width: 16,
}
},
operation: 'encode',
},
decodeSetting: false,
decodeError: "",
encodeUploadFile: {},
height1: 100,
height2: 100
}
},
}
</script>
<template>
<Tabs v-model="current.operation">
<TabPane :label="$t('bcrypt_generate')" name="generate">
<Input size="large" v-model="current.generate.password">
<span slot="prepend">{{ $t('bcrypt_password') }}</span>
</Input>
<Input size="large" v-model="current.generate.rounds" style="margin-top: 10px">
<span slot="prepend">{{ $t('bcrypt_rounds') }}</span>
</Input>
<Button :disabled="inOperation" long size="large" type="primary" @click="generate" style="margin: 10px 0">
{{ $t('bcrypt_generate_submit') }}
</Button>
<input-block right="8px" top="8px">
<Input size="large" :value="generateError ? generateError : current.generate.hash">
<span slot="prepend">{{ $t('bcrypt_hash_password') }}</span>
</Input>
<template slot="extra">
<Icon style="cursor:pointer" size="24" v-if="!generateError" type="md-copy"
@click="$copy(current.generate.hash)"/>
</template>
</input-block>
</TabPane>
<TabPane :label="$t('bcrypt_check')" name="check">
<Input size="large" v-model="current.check.password" style="margin-bottom: 10px">
<span slot="prepend">{{ $t('bcrypt_password') }}</span>
</Input>
<Input size="large" v-model="current.check.hash">
<span slot="prepend">{{ $t('bcrypt_hash_password') }}</span>
</Input>
<Button :disabled="inOperation" long size="large" type="primary" @click="check" style="margin: 10px 0">{{
$t('bcrypt_check_submit')
}}
</Button>
<div style="margin-top: 20px;text-align: center">
<Tag v-if="this.current.check.result !== ''"
:color="this.current.check.result === true ? 'success' : 'error'">
<template v-if="this.current.check.result === true">
{{ $t('bcrypt_check_result_success') }}
</template>
<template v-else>
{{ $t('bcrypt_check_result_error') }}
</template>
</Tag>
</div>
</TabPane>
</Tabs>
</template>
<script>
import bcrypt from "bcryptjs";
export default {
created() {
this.$initToolData()
},
methods: {
check() {
this.current.check.result = "";
if (!this.current.check.password || !this.current.check.hash) {
return;
}
this.inOperation = true
setTimeout(() => {
bcrypt.compare(this.current.check.password, this.current.check.hash, (err, res) => {
this.current.check.result = !!res
this.inOperation = false
this.saveToolData();
});
}, 300)
},
generate() {
this.generateError = "";
if (!this.current.generate.password || !this.current.generate.rounds) {
return;
}
this.inOperation = true
setTimeout(() => {
try {
const rounds = parseInt(this.current.generate.rounds)
if (rounds < 4 || rounds > 30) {
throw new Error(this.$t('bcrypt_rounds_range', [4, 30]).toString())
}
bcrypt.hash(this.current.generate.password, rounds, (err, hash) => {
if (err) {
this.generateError = err.message
return;
}
this.current.generate.hash = hash
this.saveToolData();
this.inOperation = false
});
} catch (e) {
this.generateError = e.message
this.inOperation = false
}
}, 300)
},
saveToolData() {
this.$saveToolData(this.current)
}
},
data() {
return {
current: {
generate: {
password: '',
rounds: '10',
hash: '',
},
check: {
hash: '',
password: '',
result: "",
},
operation: 'generate',
},
inOperation: false,
generateError: "",
}
},
}
</script>
<template>
<heightResize @resize="resize">
<Row :gutter="10">
<Col span="8">
<input-block top="5px">
<autoHeightTextarea v-model="current.input" :height="inputHeight"
:placeholder="$t('binary_input')"/>
<Select slot="extra" v-model="current.length" style="width:100px">
<Option :value="8">{{ $t('binary_length', [8]) }}</Option>
<Option :value="16">{{ $t('binary_length', [16]) }}</Option>
<Option :value="32">{{ $t('binary_length', [32]) }}</Option>
</Select>
</input-block>
</Col>
<Col span="16">
<input-block top="5px" :text="$t('binary_true_form')"
@on-default-right-bottom-click="()=>$copy(result('trueForm'))">
<autoHeightTextarea :value="result('trueForm')" :height="outputHeight"
:placeholder="$t('binary_true_form')" style="margin-bottom: 10px"/>
</input-block>
<input-block top="5px" :text="$t('binary_inverse')"
@on-default-right-bottom-click="()=>$copy(result('inverse'))">
<autoHeightTextarea :value="result('inverse')" :height="outputHeight"
:placeholder="$t('binary_inverse')" style="margin-bottom: 10px"/>
</input-block>
<input-block top="5px" :text="$t('binary_complement')"
@on-default-right-bottom-click="()=>$copy(result('complement'))">
<autoHeightTextarea :value="result('complement')" :height="outputHeight"
:placeholder="$t('binary_complement')"/>
</input-block>
</Col>
</Row>
</heightResize>
</template>
<script>
import caculate from "./library/binary"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData('input', (data) => {
return /^[\d\-+\n]+$/.test(data)
})
},
methods: {
resize(height) {
this.inputHeight = height
this.outputHeight = Math.ceil((height - 20) / 3)
},
result(type) {
if (this.current.input.trim() === "") {
return ""
}
let output = []
for (let input of this.current.input.trim().split("\n")) {
try {
output.push(caculate(input, this.current.length, type))
} catch (e) {
output.push(this.$t('binary_error', [e.message]).toString())
}
}
this.$saveToolData(this.current)
return output.join("\n");
}
},
data() {
return {
current: {
input: "",
length: 8,
},
inputHeight: 100,
outputHeight: 100
}
},
}
</script>
<template>
<div>
<heightResize :append="['.page-option-block']">
<code-editor ref="editor" showLineWrappingSet="no" v-model="current.content" :language="this.current.lang"></code-editor>
</heightResize>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button
:type="current.lang !== item ? 'primary' : 'warning'"
@click="handle(item)"
v-for="item in buttonLang"
:key="item"
>{{ item }}
</Button>
</ButtonGroup>
</FormItem>
<FormItem>
<Select :placeholder="$t('code_more')" @on-change="(value)=>{handle(value)}">
<Option v-for="item in lang" :value="item" :key="item">{{ item }}</Option>
</Select>
</FormItem>
<FormItem>
<Select :placeholder="$t('code_indent')" v-model="current.tab">
<Option :value="2">{{ $t('code_indent_width',[2]) }}</Option>
<Option :value="4">{{ $t('code_indent_width',[4]) }}</Option>
<Option :value="6">{{ $t('code_indent_width',[6]) }}</Option>
<Option :value="8">{{ $t('code_indent_width',[8]) }}</Option>
</Select>
</FormItem>
<FormItem>
<Checkbox v-model="current.isCompress">{{ $t('code_compress') }}</Checkbox>
</FormItem>
</option-block>
</div>
</template>
<script>
import _ from "lodash";
import codeEditor from "./components/codeEditor";
import heightResize from "./components/heightResize";
export default {
components: {
codeEditor,
heightResize
},
computed: {
buttonLang() {
let data = _.slice(this.lang, 0, 7)
if (this.current.lang && !data.includes(this.current.lang)) {
data.push(this.current.lang)
}
return data
}
},
watch:{
"current.isCompress"(){
if (this.current.lang){
this.handle(this.current.lang)
}
}
},
created() {
this.$initToolData('content')
},
methods: {
handle(language) {
if (this.current.content) {
try {
this.current.lang = language;
if (!this.current.isCompress) {
let option = {tab: this.current.tab}
this.$refs.editor.format(language, option);
} else {
this.$refs.editor.compress(language);
}
this.$saveToolData(this.current);
return this.$Message.success(this.$t('code_complete').toString());
} catch (e) {
console.log(e)
return this.$Modal.error({
title: this.$t('code_error_prompt').toString(),
content: `${e.message}`
});
}
}
},
isCompressChange(value){
if (this.current.lang){
console.log(value)
this.handle(this.current.lang)
}
}
},
data() {
return {
current: {
content: "",
isCompress: false,
lang: "",
tab: 4,
},
lang: [
"html",
"js",
"css",
"xml",
"json",
"sql",
"yaml",
"php",
"ts",
"java",
"scss",
"less",
"graphql",
"markdown",
"vue",
"angular",
],
};
},
};
</script>
<template>
<Input :style="style" class="auto-height-textarea" v-model="textarea" type="textarea"
:placeholder="placeholder"></Input>
</template>
<script>
import _ from "lodash";
// 窗口高度调整 返回工具页面可操作性高度
export default {
name: 'autoHeightTextarea',
props: {
value: {
type: [String, Number],
default: ''
},
placeholder: {
type: String,
default: ''
},
height: {
type: [String, Number],
default: ''
},
},
data() {
return {
textarea: ""
}
},
computed: {
style() {
let css = [];
if (this.height) {
css.push(`height:${this.height}${_.isNumber(this.height) ? 'px' : ''}`)
}
return css.join(";")
}
},
watch: {
textarea(value) {
if (value !== this.value) {
this.$emit('input', value)
}
},
value(value) {
if (value !== this.textarea) {
this.textarea = value
}
}
},
created() {
this.textarea = this.value
}
};
</script>
<style>
.auto-height-textarea, .auto-height-textarea textarea.ivu-input {
height: 100%;
}
</style>
<template>
<input-block right="5px" bottom="5px" :style="style">
<div ref="container" class="code-editor" :style="`height:100%;width:${width}`"></div>
<template slot="extra">
<Checkbox v-if="showLineWrappingSet !== 'null'" v-model="lineWrapping">{{ $t('main_editor_line_wrapping') }}</Checkbox>
</template>
</input-block>
</template>
<script>
import {format} from "../library/formatter";
import {create} from "../library/editor";
export default {
name: 'codeEditor',
props: {
value: {
type: String
},
language: {
type: String,
default: ""
},
enableBorder: {
type: Boolean,
default: true
},
placeholder: {
type: String,
default: ""
},
showLineWrappingSet: {
type: String,
default: "null"
},
height: {
type: String,
default: "100%"
},
hideLineNumbers: {
type: Boolean,
default: false
},
width: {
type: String,
default: "100%"
},
},
computed: {
style() {
let css = [`height:${this.height}`];
if (this.enableBorder) {
css.push("border: 1px solid #dcdee2")
css.push("border-radius: 4px")
}
return css.join(";")
}
},
watch: {
value(newValue) {
if (this.editor !== null && this.editor.getValue() !== newValue) {
this.editor.setValue(newValue)
}
},
language(newValue) {
if (this.editor !== null) {
this.editor.customSetEditorLanguage(newValue);
}
},
lineWrapping(newValue) {
if (this.editor !== null) {
this.editor.setOption("lineWrapping", newValue);
}
}
},
mounted() {
this.initEditor()
},
data() {
return {
editor: null,
lineWrapping: true,
}
},
created() {
if (this.showLineWrappingSet !== 'null') {
this.lineWrapping = this.showLineWrappingSet === 'yes'
}
},
methods: {
initEditor() {
this.editor = create(
this.$refs.container,
this.language,
{
lineNumbers: !this.hideLineNumbers,
lineWrapping: this.lineWrapping,
placeholder: this.placeholder
}
);
this.editor.setValue(this.value)
this.editor.on('change', editor => {
if (this.value !== editor.getValue()) {
this.$emit('input', editor.getValue())
}
})
},
getEditor() {
return this.editor
},
format(lang, option = {}) {
this.$emit('input', format(this.editor.getValue(), lang, false, option))
},
compress(lang) {
this.$emit('input', format(this.editor.getValue(), lang, true))
}
}
};
</script>
<style>
.CodeMirror {
height: 100%;
}
.CodeMirror pre.CodeMirror-placeholder {
color: #999;
}
</style>
<template>
<div ref="container" class="diff-editor" :style="`height:${height};width:${width}`"></div>
</template>
<script>
import {createMerge} from "../library/editor";
export default {
name: 'diffEditor',
props: {
value: {
type: Object
},
language: {
type: String,
default: ""
},
collapse: {
type: Boolean,
default: false
},
height: {
type: String,
default: "100%"
},
width: {
type: String,
default: "100%"
},
},
watch: {
value: {
handler(val) {
if (this.editor !== null) {
this.editor.customSetValue(val)
}
},
deep: true
},
language(newValue) {
if (this.editor !== null) {
this.editor.customSetEditorLanguage(newValue);
}
},
collapse() {
this.reset()
}
},
mounted() {
this.reset()
},
data() {
return {
editor: null,
}
},
methods: {
reset() {
this.$refs.container.innerHTML = "";
this.initEditor();
},
initEditor() {
this.editor = createMerge(this.value, this.$refs.container, this.language, {collapseIdentical: this.collapse ? 2 : false})
this.editor.customChange((original, modified) => {
if (original !== this.value.original || modified !== this.value.modified) {
this.value.original = original
this.value.modified = modified
this.$emit('input', this.value)
}
})
},
}
};
</script>
<style>
.diff-editor .CodeMirror-merge {
border: none;
}
.diff-editor .CodeMirror-merge, .diff-editor .CodeMirror-merge-pane, .diff-editor .CodeMirror-merge .CodeMirror {
height: 100%;
}
</style>
<template>
<div class="tool-disable-mask">
<div>
<div style="line-height: 24px;word-break:break-all;background-color: #fff;padding: 5px 10px;margin: 0 10px">
<slot></slot>
</div>
<div style="text-align: center;margin-top: 10px" v-if="!disableClose">
<Icon type="md-close-circle" style="cursor: pointer;" size="30" color="#FFF" @click="close" />
</div>
</div>
</div>
</template>
<script>
export default {
props:{
disableClose: {
type: Boolean,
default: false
},
},
methods:{
close(){
this.$emit('close')
}
}
};
</script>
<style scoped>
.tool-disable-mask{
position: absolute;
top: 0;
left: 0;
z-index: 8;
width: 100%;
height: 100%;
background-color: rgba(55, 55, 55, 0.2);
display: flex;
display: -webkit-flex;
align-items: center;
justify-content: center;
}
</style>
<template>
<div :style="`height:${height}`">
<slot></slot>
</div>
</template>
<script>
import {WINDOW_RESIZE} from '../../../tool/event'
function getAbsoluteHeight(select) {
let el = document.querySelector(select)
if (el === null) {
return 0;
}
let styles = window.getComputedStyle(el);
let margin = parseFloat(styles['marginTop']) +
parseFloat(styles['marginBottom']);
return Math.ceil(el.offsetHeight + margin);
}
// 窗口高度调整 返回工具页面可操作高度
export default {
name: 'heightResize',
props: {
append: {
type: Array,
default: function () {
return [];
}
},
reduce: {
type: Number,
default: 0
},
remove: {
type: Array,
default: function () {
return [];
}
},
ignore: {
type: Boolean,
default: false
},
},
data() {
return {
height: "auto",
}
},
methods: {
reportWindowSize() {
this.resize()
},
resize() {
let height = window.innerHeight;
let defaultBlock = [".tool-select-block", ".tool-category-menu-block", ".ctool-bottom"]
const filterBlock = defaultBlock.filter((item) => {
return !this.remove.includes(item)
}).concat(this.append)
for (let block of filterBlock) {
height = height - getAbsoluteHeight(block)
}
if (this.reduce > 0){
height = height - this.reduce
}
if (height > 100) {
height = height - 5
}
if (!this.ignore) {
this.height = height + "px"
}
this.$emit('resize', height);
}
},
destroyed() {
window.removeEventListener(WINDOW_RESIZE, this.reportWindowSize);
},
mounted() {
window.addEventListener(WINDOW_RESIZE, this.reportWindowSize);
this.resize();
}
};
</script>
<template>
<div style="display: inline">
<slot></slot>
</div>
</template>
<script>
// 粘贴时 获取剪贴板图片
export default {
name: 'pasteClipboardFlie',
methods: {
reader(event) {
if (!("clipboardData" in event)){
return
}
let items = event.clipboardData && event.clipboardData.items;
let types = event.clipboardData.types || [];
if (items && items.length) {
for (let i = 0; i < items.length; i++) {
if( types[i] === 'Files' ){
// 触发粘贴文件事件
this.$emit('on-paste-file', items[i].getAsFile());
if (items[i].type.indexOf('image') !== -1) {
// 触发粘贴文件事件 输出图片base64
this.$emit('on-paste-image', items[i].getAsFile());
}
return
}
}
}
}
},
destroyed() {
window.removeEventListener("paste", this.reader);
},
mounted() {
window.addEventListener("paste", this.reader);
}
};
</script>
<template>
<div>
<Select @on-change="select" size="small" placeholder="Common" style="width:100px">
<Option v-for="(v,k) in expression" :value="v.regex" :key="k">{{ v.name }}</Option>
</Select>
<Button type="primary" style="margin-left: 5px" size="small" @click="referenceShow=true">Reference</Button>
<Drawer title="Reference" v-model="referenceShow" :width="100">
<Table :columns="referenceColumns" :data="reference">
<template slot-scope="{ row }" slot="_text">
<div v-html="row.text" style="padding: 10px 0"></div>
</template>
</Table>
</Drawer>
</div>
</template>
<script>
export default {
methods: {
select(regex) {
this.$emit('on-select', regex);
}
},
data() {
return {
referenceShow: false,
/* eslint-disable */
expression: [
{
regex: '(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|622((12[6-9]|1[3-9][0-9])|([2-8][0-9][0-9])|(9(([0-1][0-9])|(2[0-5]))))[0-9]{10}|64[4-9][0-9]{13}|65[0-9]{14}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})*',
name: "All major credit cards regex"
},
{regex: '[a-zA-Z0-9]*', name: "Alpha-numeric characters"},
{regex: '[a-zA-Z0-9 ]*', name: "Alpha-numeric characters with spaces"},
{regex: '[a-zA-Z]*', name: "Alphabetic characters"},
{regex: '(3[47][0-9]{13})*', name: "Amex credit card regex"},
{
regex: '((0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2}))*',
name: "Australian Postal Codes"
},
{regex: '([ABCEGHJKLMNPRSTVXY][0-9][A-Z] [0-9][A-Z][0-9])*', name: "Canadian Postal Codes"},
{regex: '(?:AB|BC|MB|N[BLTSU]|ON|PE|QC|SK|YT)*', name: "Canadian Province Abbreviations"},
{
regex: '(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}',
name: "Date (MM/DD/YYYY)"
},
{
regex: '(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])',
name: "Date (YYYY/MM/DD)"
},
{regex: '(3(?:0[0-5]|[68][0-9])[0-9]{11})*', name: "Diner's Club credit card regex"},
{
regex: '((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))*',
name: "IP address regex"
},
{regex: '([a-z])+', name: "Lowercase letters"},
{regex: '([A-Z])+', name: "Uppercase letters"},
{regex: '(5[1-5][0-9]{14})*', name: "MasterCard credit card numbers"},
{regex: '((([0-9]{1})*[- .(]*([0-9]{3})[- .)]*[0-9]{3}[- .]*[0-9]{4})+)*', name: "Phone number regex"},
{regex: '([0-9]{3}[-]*[0-9]{2}[-]*[0-9]{4})*', name: "SSN regex"},
{regex: '([A-Z]{1,2}[0-9][A-Z0-9]? [0-9][ABD-HJLNP-UW-Z]{2})*', name: "UK Postal Codes regex"},
{
regex: '(?:A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])*',
name: "US States regex"
},
{regex: '([0-9]{5}(?:-[0-9]{4})?)*', name: "US ZIP Codes regex"},
{regex: '(4[0-9]{12}(?:[0-9]{3})?)*', name: "Visa credit card numbers"},
{
regex: '(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})',
name: "All major credit cards regex"
},
{regex: '[a-zA-Z0-9]+', name: "alpha-numeric characters"},
{regex: '[a-zA-Z]+', name: "Alphabetic characters"},
{regex: '[ABCEGHJKLMNPRSTVXY][0-9][A-Z] [0-9][A-Z][0-9]', name: "Canadian Postal Codes"},
{regex: '[0-9]+', name: "digits"},
{regex: '[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}', name: "email regex"},
{
regex: '(([0-9]{1})*[- .(]*([0-9]{3})[- .)]*[0-9]{3}[- .]*[0-9]{4})+',
name: "phone number regex"
},
{
regex: '((http|https|ftp)://)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]/+=%&_\.~?\-]*)',
name: "URL regex"
},
{regex: '[0-9]{5}(?:-[0-9]{4})?', name: "US ZIP Codes regex"}
],
/* eslint-enable */
referenceColumns: [
{
title: 'Character',
key: 'name',
width: 120
},
{
title: 'What does it do?',
slot: '_text'
},
],
reference: [
{
"name": "\\",
"text": "Used to indicate that the next character should NOT be interpreted literally. For example, the character 'w' by itself will be interpreted as 'match the character w', but using '\\w' signifies 'match an alpha-numeric character including underscore'. Used to indicate that a metacharacter is to be interpreted literally. For example, the '.' metacharacter means 'match any single character but a new line', but if we would rather match a dot character instead, we would use '\\.'."
},
{
"name": "^",
"text": "Matches the beginning of the input. If in multiline mode, it also matches after a line break character, hence every new line. When used in a set pattern ([^abc]), it negates the set; match anything not enclosed in the brackets"
},
{
"name": "$",
"text": "Matches the end of the input. If in multiline mode, it also matches before a line break character, hence every end of line."
},
{
"name": "*",
"text": "Matches the preceding character 0 or more times."
},
{
"name": "+",
"text": "Matches the preceding character 1 or more times."
},
{
"name": "?",
"text": "Matches the preceding character 0 or 1 time. When used after the quantifiers *, +, ? or {}, makes the quantifier non-greedy; it will match the minimum number of times as opposed to matching the maximum number of times."
},
{
"name": ".",
"text": "Matches any single character except the newline character."
},
{
"name": "(x)",
"text": "Matches 'x' and remembers the match. Also known as capturing parenthesis."
},
{
"name": "(?:x)",
"text": "Matches 'x' but does NOT remember the match. Also known as NON-capturing parenthesis."
},
{
"name": "x(?=y)",
"text": "Matches 'x' only if 'x' is followed by 'y'. Also known as a lookahead."
},
{
"name": "x(?!y)",
"text": "Matches 'x' only if 'x' is NOT followed by 'y'. Also known as a negative lookahead."
},
{
"name": "x|y",
"text": "Matches 'x' OR 'y'."
},
{
"name": "{n}",
"text": "Matches the preceding character exactly n times."
},
{
"name": "{n,m}",
"text": "Matches the preceding character at least n times and at most m times. n and m can be omitted if zero.."
},
{
"name": "[abc]",
"text": "Matches any of the enclosed characters. Also known as a character set. You can create range of characters using the hyphen character such as A-Z (A to Z). Note that in character sets, special characters (., *, +) do not have any special meaning."
},
{
"name": "[^abc]",
"text": "Matches anything NOT enclosed by the brackets. Also known as a negative character set."
},
{
"name": "[\\b]",
"text": "Matches a backspace."
},
{
"name": "\\b",
"text": "Matches a word boundary. Boundaries are determined when a word character is NOT followed or NOT preceded with another word character."
},
{
"name": "\\B",
"text": "Matches a NON-word boundary. Boundaries are determined when two adjacent characters are word characters OR non-word characters."
},
{
"name": "\\cX",
"text": "Matches a control character. X must be between A to Z inclusive."
},
{
"name": "\\d",
"text": "Matches a digit character. Same as [0-9] or [0123456789]."
},
{
"name": "\\D",
"text": "Matches a NON-digit character. Same as [^0-9] or [^0123456789]."
},
{
"name": "\\f",
"text": "Matches a form feed."
},
{
"name": "\\n",
"text": "Matches a line feed."
},
{
"name": "\\r",
"text": "Matches a carriage return."
},
{
"name": "\\s",
"text": "Matches a single white space character. This includes space, tab, form feed and line feed."
},
{
"name": "\\S",
"text": "Matches anything OTHER than a single white space character. Anything other than space, tab, form feed and line feed."
},
{
"name": "\\t",
"text": "Matches a tab."
},
{
"name": "\\v",
"text": "Matches a vertical tab."
},
{
"name": "\\w",
"text": "Matches any alphanumeric character including underscore. Equivalent to [A-Za-z0-9_]."
},
{
"name": "\\W",
"text": "Matches anything OTHER than an alphanumeric character including underscore. Equivalent to [^A-Za-z0-9_]."
},
{
"name": "\\x",
"text": "A back reference to the substring matched by the x parenthetical expression. x is a positive integer."
},
{
"name": "\\0",
"text": "Matches a NULL character."
},
{
"name": "\\xhh",
"text": "Matches a character with the 2-digits hexadecimal code."
},
{
"name": "\\uhhhh",
"text": "Matches a character with the 4-digits hexadecimal code."
}
]
}
}
}
</script>
<template>
<div>
<Select @on-change="select" size="small" placeholder="常用" style="width:80px">
<Option v-for="(v,k) in expression" :value="v.regex" :key="k">{{v.name}}</Option>
</Select>
<Button type="primary" style="margin-left: 5px" size="small" @click="referenceShow=true">参考</Button>
<Drawer title="参考" v-model="referenceShow" :width="100">
<Table :columns="referenceColumns" :data="reference">
<template slot-scope="{ row }" slot="_text">
<div v-html="row.text" style="padding: 10px 0"></div>
</template>
</Table>
</Drawer>
</div>
</template>
<script>
export default {
methods:{
select(regex){
this.$emit('on-select',regex);
}
},
data(){
return {
referenceShow:false,
expression: [
{regex: "[\\u4e00-\\u9fa5]", name:"中文字符"},
{regex: "[^\\x00-\\xff]", name:"双字节字符(包括汉字在内)"},
{regex: "\\n\\s*\\r", name:"空白行"},
{
regex: "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?",
name:"Email地址"},
{regex: "[a-zA-z]+://[^\\s]*", name:"网址URL"},
{regex: "[1][3,4,5,7,8][0-9]{9}", name:"手机"},
{regex: "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}", name:"IP地址"},
{regex: "\\d{3}-\\d{8}|\\d{4}-\\d{7,8}", name:"国内电话号码"},
{regex: "[1-9][0-9]{4,}", name:"腾讯QQ号"},
{regex: "[1-9]\\d{5}(?!\\d)", name:"中国邮政编码"},
{
regex: "([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))",
name:"(年-月-日)格式日期"},
{regex: "[1-9]\\d*", name:"正整数"},
{regex: "-[1-9]\\d*", name:"负整数"},
{regex: "-?[1-9]\\d*", name:"整数"},
{regex: "[1-9]\\d*|0", name:"非负整数(正整数 + 0)"},
{regex: "-[1-9]\\d*|0", name:"非正整数(负整数 + 0)"},
{regex: "[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*", name:"正浮点数"},
{regex: "-[1-9]\\d*\\.\\d*|-0\\.\\d*[1-9]\\d*", name:"负浮点数"},
],
referenceColumns: [
{
title: '字符',
key: 'name',
width: 100
},
{
title: '描述',
slot: '_text'
},
],
reference: [
{
name: "\\",
text: "将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“<code>n</code>”匹配字符“<code>n</code>”。“<code>\\n</code>”匹配一个换行符。串行“<code>\\\\</code>”匹配“<code>\\</code>”而“<code>\\(</code>”则匹配“<code>(</code>”。"
},
{
name: "^",
text: "匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“<code>\\n</code>”或“<code>\\r</code>”之后的位置。"
},
{
name: "$",
text: "匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“<code>\\n</code>”或“<code>\\r</code>”之前的位置。"
},
{
name: "*",
text: "匹配前面的子表达式零次或多次。例如,zo*能匹配“<code>z</code>”以及“<code>zoo</code>”。*等价于{0,}。"
},
{
name: "+",
text: "匹配前面的子表达式一次或多次。例如,“<code>zo+</code>”能匹配“<code>zo</code>”以及“<code>zoo</code>”,但不能匹配“<code>z</code>”。+等价于{1,}。"
},
{
name: "?",
text: "匹配前面的子表达式零次或一次。例如,“<code>do(es)?</code>”可以匹配“<code>does</code>”或“<code>does</code>”中的“<code>do</code>”。?等价于{0,1}。"
},
{
name: "{n}",
text: "n是一个非负整数。匹配确定的n次。例如,“<code>o{2}</code>”不能匹配“<code>Bob</code>”中的“<code>o</code>”,但是能匹配“<code>food</code>”中的两个o。"
},
{
name: "{n,}",
text: "n是一个非负整数。至少匹配n次。例如,“<code>o{2,}</code>”不能匹配“<code>Bob</code>”中的“<code>o</code>”,但能匹配“<code>foooood</code>”中的所有o。“<code>o{1,}</code>”等价于“<code>o+</code>”。“<code>o{0,}</code>”则等价于“<code>o*</code>”。"
},
{
name: "{n,m}",
text: "m和n均为非负整数,其中n&lt;=m。最少匹配n次且最多匹配m次。例如,“<code>o{1,3}</code>”将匹配“<code>fooooood</code>”中的前三个o。“<code>o{0,1}</code>”等价于“<code>o?</code>”。请注意在逗号和两个数之间不能有空格。"
},
{
name: "?",
text: "当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“<code>oooo</code>”,“<code>o+?</code>”将匹配单个“<code>o</code>”,而“<code>o+</code>”将匹配所有“<code>o</code>”。"
},
{
name: ".",
text: "匹配除“<code>\\</code><code>n</code>”之外的任何单个字符。要匹配包括“<code>\\</code><code>n</code>”在内的任何字符,请使用像“<code>(.|\\n)</code>”的模式。"
},
{
name: "(pattern)",
text: "匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“<code>\\(</code>”或“<code>\\)</code>”。"
},
{
name: "(?:pattern)",
text: "匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“<code>(|)</code>”来组合一个模式的各个部分是很有用。例如“<code>industr(?:y|ies)</code>”就是一个比“<code>industry|industries</code>”更简略的表达式。"
},
{
name: "(?=pattern)",
text: "正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“<code>Windows(?=95|98|NT|2000)</code>”能匹配“<code>Windows2000</code>”中的“<code>Windows</code>”,但不能匹配“<code>Windows3.1</code>”中的“<code>Windows</code>”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。"
},
{
name: "(?!pattern)",
text: "正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“<code>Windows(?!95|98|NT|2000)</code>”能匹配“<code>Windows3.1</code>”中的“<code>Windows</code>”,但不能匹配“<code>Windows2000</code>”中的“<code>Windows</code>”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始"
},
{
name: "(?&lt;=pattern)",
text: "反向肯定预查,与正向肯定预查类拟,只是方向相反。例如,“<code>(?&lt;=95|98|NT|2000)Windows</code>”能匹配“<code>2000Windows</code>”中的“<code>Windows</code>”,但不能匹配“<code>3.1Windows</code>”中的“<code>Windows</code>”。"
},
{
name: "(?&lt;!pattern)",
text: "反向否定预查,与正向否定预查类拟,只是方向相反。例如“<code>(?&lt;!95|98|NT|2000)Windows</code>”能匹配“<code>3.1Windows</code>”中的“<code>Windows</code>”,但不能匹配“<code>2000Windows</code>”中的“<code>Windows</code>”。"
},
{
name: "x|y",
text: "匹配x或y。例如,“<code>z|food</code>”能匹配“<code>z</code>”或“<code>food</code>”。“<code>(z|f)ood</code>”则匹配“<code>zood</code>”或“<code>food</code>”。"
},
{
name: "[xyz]",
text: "字符集合。匹配所包含的任意一个字符。例如,“<code>[abc]</code>”可以匹配“<code>plain</code>”中的“<code>a</code>”。"
},
{
name: "[^xyz]",
text: "负值字符集合。匹配未包含的任意字符。例如,“<code>[^abc]</code>”可以匹配“<code>plain</code>”中的“<code>p</code>”。"
},
{
name: "[a-z]",
text: "字符范围。匹配指定范围内的任意字符。例如,“<code>[a-z]</code>”可以匹配“<code>a</code>”到“<code>z</code>”范围内的任意小写字母字符。"
},
{
name: "[^a-z]",
text: "负值字符范围。匹配任何不在指定范围内的任意字符。例如,“<code>[^a-z]</code>”可以匹配任何不在“<code>a</code>”到“<code>z</code>”范围内的任意字符。"
},
{
name: "\\b",
text: "匹配一个单词边界,也就是指单词和空格间的位置。例如,“<code>er\\b</code>”可以匹配“<code>never</code>”中的“<code>er</code>”,但不能匹配“<code>verb</code>”中的“<code>er</code>”。"
},
{
name: "\\B",
text: "匹配非单词边界。“<code>er\\B</code>”能匹配“<code>verb</code>”中的“<code>er</code>”,但不能匹配“<code>never</code>”中的“<code>er</code>”。"
},
{
name: "\\cx",
text: "匹配由x指明的控制字符。例如,<code>\\cM</code>匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“<code>c</code>”字符。"
},
{
name: "\\d",
text: "匹配一个数字字符。等价于[0-9]。"
},
{
name: "\\D",
text: "匹配一个非数字字符。等价于[^0-9]。"
},
{
name: "\\f",
text: "匹配一个换页符。等价于\\x0c和\\cL。"
},
{
name: "\\n",
text: "匹配一个换行符。等价于\\x0a和\\cJ。"
},
{
name: "\\r",
text: "匹配一个回车符。等价于\\x0d和\\cM。"
},
{
name: "\\s",
text: "匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \\f\\n\\r\\t\\v]。"
},
{
name: "\\S",
text: "匹配任何非空白字符。等价于[^ \\f\\n\\r\\t\\v]。"
},
{
name: "\\t",
text: "匹配一个制表符。等价于\\x09和\\cI。"
},
{
name: "\\v",
text: "匹配一个垂直制表符。等价于\\x0b和\\cK。"
},
{
name: "\\w",
text: "匹配包括下划线的任何单词字符。等价于“<code>[A-Za-z0-9_]</code>”。"
},
{
name: "\\W",
text: "匹配任何非单词字符。等价于“<code>[^A-Za-z0-9_]</code>”。"
},
{
name: "\\xn",
text: "匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“<code>\\x41</code>”匹配“<code>A</code>”。“<code>\\x041</code>”则等价于“<code>\\x04&amp;1</code>”。正则表达式中可以使用ASCII编码。."
},
{
name: "\\num",
text: "匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“<code>(.)\\1</code>”匹配两个连续的相同字符。"
},
{
name: "\\n",
text: "标识一个八进制转义值或一个向后引用。如果\\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。"
},
{
name: "\\nm",
text: "标识一个八进制转义值或一个向后引用。如果\\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\\nm将匹配八进制转义值nm。"
},
{
name: "\\nml",
text: "如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。"
},
{
name: "\\un",
text: "匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\\u00A9匹配版权符号(©)。"
}
]
}
}
}
</script>
<template>
<Upload style="display: inline-block" action="#" :before-upload="handleUpload" :format="format" :showUploadList="false">
<Button shape="circle" icon="md-cloud-upload"/>
<template v-if="!disablePaste">
<pasteClipboardFlie v-if="type==='file'" @on-paste-file="handleUpload"/>
<pasteClipboardFlie v-if="type==='image'" @on-paste-image="handleUpload"/>
</template>
</Upload>
</template>
<script>
import pasteClipboardFlie from './pasteClipboardFlie';
export default {
components: {
pasteClipboardFlie,
},
props: {
disablePaste: {
type: Boolean,
default: false
},
type: {
type: String,
default: "file" // file,image
}
},
computed: {
format() {
if (this.type === "image") {
return ['jpg', 'jpeg', 'png']
}
return [];
}
},
methods: {
handleUpload(file) {
this.$emit('success', file)
}
}
};
</script>
<template>
<div>
<Row :gutter="16">
<Col span="12">
<Input v-model="current.input" style="margin-bottom: 16px" class="page-option-input">
<span slot="prepend">{{ $t('crontab_expression') }}</span>
</Input>
<heightResize :append="['.page-option-input']">
<autoHeightTextarea :value="output" :placeholder="$t('crontab_execute_time')"/>
</heightResize>
</Col>
<Col span="12" class="page-option-reference">
<Tabs value="example">
<TabPane :label="$t('crontab_example')" name="example">
<heightResize :reduce="52" @resize="resize">
<Table stripe size="small" :height="referenceHeight" border :columns="example.columns"
:data="example.data"></Table>
</heightResize>
</TabPane>
<TabPane :label="$t('crontab_format')" name="format" style="text-align: center">
<img v-if="locale === 'zh_CN'" src="../../statics/crontab_cn.png" style="height: 300px" alt="">
<img v-else src="../../statics/crontab_en.png" style="height: 300px" alt="">
</TabPane>
<TabPane :label="$t('crontab_symbol')" name="special">
<Table stripe size="small" height="300" :columns="special.columns" :data="special.data"></Table>
</TabPane>
</Tabs>
</Col>
</Row>
</div>
</template>
<script>
import cronstrue from 'cronstrue/i18n';
import parser from 'cron-parser';
import moment from "moment"
import {getCurrentLocale} from "../../i18n";
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
computed: {
locale() {
return getCurrentLocale()
},
output() {
if (!this.current.input) return "";
let list = [];
try {
list.push(this.conversion(this.current.input));
list.push(`\n${this.$t('crontab_execute_time_list')}`);
let interval = parser.parseExpression(this.current.input);
for (let i = 1; i <= 10; i++) {
list.push(this.$t('crontab_no', [i, moment(interval.next().toString()).format("YYYY-MM-DD HH:mm:ss")]))
}
this.$saveToolData(this.current);
} catch (err) {
list.push(err)
}
return list.join("\n");
},
},
created() {
this.$initToolData('input', (data) => {
try {
cronstrue.toString(data)
} catch {
return false
}
return true
})
this.example.data = this.example.data.map((item) => {
return {
example: item,
text: this.conversion(item)
}
})
},
methods: {
conversion(input) {
return cronstrue.toString(input, {locale: this.locale, use24HourTimeFormat: true})
},
resize(height) {
this.referenceHeight = height
}
},
data() {
return {
referenceHeight: 101,
current: {
input: "2 */5 * * 2-5"
},
special: {
columns: [
{title: this.$t('crontab_symbol'), key: 'name', width: 100},
{title: this.$t('crontab_description'), key: 'text'},
],
data: [
{
name: "*",
text: this.$t('crontab_symbol_description_1')
},
{
name: ",",
text: this.$t('crontab_symbol_description_2')
},
{
name: "-",
text: this.$t('crontab_symbol_description_3')
},
{
name: "/n",
text: this.$t('crontab_symbol_description_4')
}
]
},
example: {
columns: [
{title: this.$t('crontab_example'), key: 'example', width: 120},
{title: this.$t('crontab_description'), key: 'text'},
],
data: [
"*/1 * * * *",
"* * * * *",
"*/5 * * * *",
"0 * * * *",
"0 */1 * * *",
"0 7 * * *",
"10 7 * * *",
"0 0 * * *",
"0 0 * * 0",
"0 0 1 * *",
"0 0 1 1 *",
"5 * * * *",
"30 5 * * *",
"30 7 8 * *",
"30 5 8 6 *",
"30 6 * * 0",
"30 3 10,20 * *",
"25 8-11 * * *",
"*/15 * * * *",
"30 6 */10 * *"
]
}
}
}
}
</script>
<template>
<div style="padding: 0 70px">
<option-block>
<Input v-model="current.input" :placeholder="$t('decimalConvert_input_placeholder')">
<div slot="prepend" style="width: 70px"><strong>{{ $t('decimalConvert_input') }}</strong></div>
<Select v-model="current.decimal" slot="append" style="width:100px">
<OptionGroup :label="$t('decimalConvert_input_type_common')">
<Option v-for="v in type.common" :value="v" :key="v">{{
$t('decimalConvert_base', [v])
}}
</Option>
</OptionGroup>
<OptionGroup :label="$t('decimalConvert_input_type_other')">
<Option v-for="v in type.other" :value="v" :key="v">{{
$t('decimalConvert_base', [v])
}}
</Option>
</OptionGroup>
</Select>
</Input>
</option-block>
<option-block v-for="n in [1,2,3,4,5,6]" :key="n">
<Input v-model="current['resultOutput'+n]" readonly>
<div slot="prepend" style="width: 70px">{{ $t('decimalConvert_result', [n]) }}</div>
<Select slot="append" v-model="current['resultDecimal'+n]" style="width:100px">
<OptionGroup :label="$t('decimalConvert_input_type_common')">
<Option v-for="v in type.common" :value="v" :key="v">{{
$t('decimalConvert_base', [v])
}}
</Option>
</OptionGroup>
<OptionGroup :label="$t('decimalConvert_input_type_other')">
<Option v-for="v in type.other" :value="v" :key="v">{{
$t('decimalConvert_base', [v])
}}
</Option>
</OptionGroup>
</Select>
</Input>
</option-block>
<option-block>
<Input v-model="current.alphabet">
<div slot="prepend">{{ $t('decimalConvert_alphabet') }}</div>
<Button slot="append" @click="current.alphabet=alphabet" :disabled="current.alphabet===alphabet">
{{ $t('decimalConvert_reset') }}
</Button>
</Input>
</option-block>
</div>
</template>
<script>
import Radix from './library/radix.js'
const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_@";
export default {
created() {
this.$initToolData('input',(input,current)=>{
try {
const radix = new Radix(current.alphabet);
radix.convent(input, current.decimal, 2, true)
} catch (e) {
return false;
}
return true
})
},
watch: {
convert: function (val) {
if (val.alphabet.length !== 64) {
for (let n = 1; n <= 6; n++) {
this.current['resultOutput' + n] = this.$t('decimalConvert_alphabet_length_error').toString()
}
return;
}
if (!val.input) {
return;
}
const radix = new Radix(val.alphabet);
let isError = false;
for (let n = 1; n <= 6; n++) {
try {
this.current['resultOutput' + n] = radix.convent(val.input, val.decimal, val['resultDecimal' + n], true)
} catch (e) {
isError = true
this.current['resultOutput' + n] = e.toString()
}
}
if (!isError){
this.$saveToolData(this.current);
}
},
},
computed: {
convert() {
return {
input: this.current.input,
decimal: this.current.decimal,
alphabet: this.current.alphabet,
resultDecimal1: this.current.resultDecimal1,
resultDecimal2: this.current.resultDecimal2,
resultDecimal3: this.current.resultDecimal3,
resultDecimal4: this.current.resultDecimal4,
resultDecimal5: this.current.resultDecimal5,
resultDecimal6: this.current.resultDecimal6,
};
},
type() {
let type = {
common: [2, 8, 10, 16],
other: []
}
for (let i = 2; i <= 64; i++) {
type.common.includes(i) || type.other.push(i);
}
return type
}
},
methods: {},
data() {
return {
current: {
input: "",
decimal: 10,
resultOutput1: "",
resultDecimal1: 2,
resultOutput2: "",
resultDecimal2: 8,
resultOutput3: "",
resultDecimal3: 10,
resultOutput4: "",
resultDecimal4: 16,
resultOutput5: "",
resultDecimal5: 60,
resultOutput6: "",
resultDecimal6: 64,
alphabet: alphabet,
},
alphabet: alphabet,
}
},
}
</script>
<template>
<div>
<heightResize :append="['.page-option-block']">
<div style="border: 1px solid #dcdee2; border-radius: 4px;height: 100%;">
<diff-editor ref="editor" :collapse="current.collapse" v-model="current.diff"
:language="current.language"/>
</div>
</heightResize>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button
:type="current.language !== item ? 'primary' : 'warning'"
@click="setLanguage(item)"
v-for="item in buttonLang"
:key="item"
>{{ item }}
</Button>
</ButtonGroup>
</FormItem>
<FormItem>
<Select :placeholder="$t('diffs_more')" @on-change="(value)=>{setLanguage(value)}">
<Option v-for="item in allLang" :value="item" :key="item">{{ item }}</Option>
</Select>
</FormItem>
<FormItem>
<Button type="primary" size="small" @click="format">{{ $t('diffs_beautify') }}</Button>
</FormItem>
<FormItem>
<Checkbox v-model="current.collapse">{{ $t('diffs_collapse') }}</Checkbox>
</FormItem>
</option-block>
</div>
</template>
<script>
import diffEditor from "./components/diffEditor";
import {allLang} from "./library/editor";
import _ from "lodash";
import heightResize from "./components/heightResize";
import {format} from "./library/formatter";
const COMMON_LANG = [
"text",
"html",
"js",
"css",
"json",
"python",
"java",
"php"
]
export default {
components: {
diffEditor,
heightResize
},
computed: {
allLang() {
return allLang
},
buttonLang() {
let data = _.cloneDeep(COMMON_LANG);
if (this.current.language && !data.includes(this.current.language)) {
data.push(this.current.language)
}
return data;
}
},
created() {
this.$initToolData()
},
methods: {
setLanguage(lang) {
this.current.language = lang;
},
format() {
try{
this.current.diff.original = format(this.current.diff.original,this.current.language)
this.current.diff.modified = format(this.current.diff.modified,this.current.language)
} catch (e) {
this.$Message.error(e.message)
}
}
},
watch: {
current: {
handler(newVal) {
if (newVal.diff.original && newVal.diff.modified) {
this.$saveToolData(this.current);
}
},
deep: true
}
},
data() {
return {
current: {
diff: {original: "", modified: ""},
language: "text",
collapse: false
}
}
}
}
</script>
<template>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('encrypt_input')"/>
<option-block class="page-option-block">
<Form :model="formItem" label-position="top">
<Form-item label="算法: ">
<Select v-model="current.type">
<Option v-for="v in type" :value="v" :key="v">{{ v }}</Option>
</Select>
</Form-item>
<Form-item label="密钥: ">
<Select v-model="current.keyFormat">
<Option value="Hex">Hex</Option>
<Option value="Base64">Base64</Option>
<Option value="Password">Password</Option>
</Select>
<Input v-model="current.password" :placeholder="$t('encrypt_password')" type="textarea" :autosize="{minRows: 2, maxRows: 5}"></Input>
</Form-item>
<Form-item label="IV 向量(Hex 格式): ">
<Input v-model="current.iv" :placeholder="$t('iv')" type="textarea" :autosize="{minRows: 3, maxRows: 5}"></Input>
</Form-item>
<Form-item label="加密模式: " v-if="current.type === 'SM2'">
<Select v-model="current.sm2CipherMode">
<Option value="C1C3C2">C1C3C2</Option>
<Option value="C1C2C3">C1C2C3</Option>
</Select>
</Form-item>
<Form-item label="加密模式: " v-else-if="current.type === 'SM4'">
<Select v-model="current.mode">
<Option value="ecb">ECB</Option>
<Option value="cbc">CBC</Option>
</Select>
<Select v-model="current.padding">
<Option value="pkcs#7">Pkcs7</Option>
<Option value="none">NoPadding</Option>
</Select>
</Form-item>
<Form-item label="加密模式: " v-else>
<Select v-model="current.mode">
<Option value="ECB">ECB</Option>
<Option value="CBC">CBC</Option>
<Option value="CFB">CFB</Option>
<Option value="OFB">OFB</Option>
<Option value="CTR">CTR</Option>
</Select>
<Select v-model="current.padding">
<Option value="Pkcs7">Pkcs7</Option>
<Option value="Iso97971">Iso97971</Option>
<Option value="AnsiX923">AnsiX923</Option>
<Option value="Iso10126">Iso10126</Option>
<Option value="ZeroPadding">ZeroPadding</Option>
<Option value="NoPadding">NoPadding</Option>
</Select>
</Form-item>
<Form-item>
<ButtonGroup>
<Button type="primary" @click="handle('encrypt')">{{ $t('encrypt_encrypt') }}</Button>
<Button type="primary" @click="handle('decrypt')">{{ $t('encrypt_decrypt') }}</Button>
<Button type="primary" @click="sm2Generate()" v-if="current.type === 'SM2'">
{{ $t('encrypt_generate_secret_key') }}
</Button>
</ButtonGroup>
</Form-item>
</Form>
</option-block>
<autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('encrypt_output')"/>
</heightResize>
</template>
<script>
import crypto from "crypto-js"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
import { CryptoJS } from 'jsrsasign';
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData('input')
},
methods: {
handle(v) {
const sm2 = require('sm-crypto').sm2
const sm4 = require('sm-crypto').sm4
if (this.current.input) {
try {
let output = ""
switch (this.current.type) {
case "AES":
case "DES":
case "RC4":
case "Rabbit":
case "TripleDES":
if (v === "encrypt") {
if (this.current.keyFormat !== "Password") {
output = crypto[this.current.type].encrypt(
// todo 后续可以考虑支持原文输入的编码格式,以便应对一些二进制格式
this.current.input,
// 转换为 WordArray 形式作为密钥传入
crypto.enc[this.current.keyFormat].parse(this.current.password),
{
// IV 要求为 Hex,按照 Hex 解析为 WordArray
iv: crypto.enc.Hex.parse(this.current.iv),
mode: crypto.mode[this.current.mode],
padding: crypto.pad[this.current.padding]
}
).ciphertext;
} else {
// 兼容 crypto-js 的密码模式
output = crypto[this.current.type].encrypt(this.current.input, this.current.password).toString();
}
} else {
if (this.current.keyFormat !== "Password") {
// crypto-js 要求解密时传入为 CipherParams,使用 CipherText 构建 CipherParams
let cipherData = CryptoJS.lib.CipherParams.create({
ciphertext: crypto.enc.Hex.parse(this.current.input)
});
output = crypto[this.current.type].decrypt(
cipherData,
// 转换为 WordArray 形式作为密钥传入
crypto.enc[this.current.keyFormat].parse(this.current.password),
{
// IV 要求为 Hex,按照 Hex 解析为 WordArray
iv: crypto.enc.Hex.parse(this.current.iv),
mode: crypto.mode[this.current.mode],
padding: crypto.pad[this.current.padding]
}
).toString(crypto.enc.Utf8);
} else {
// 兼容 crypto-js 的密码模式
output = crypto[this.current.type].decrypt(this.current.input, this.current.password).toString(crypto.enc.Utf8);
}
}
break;
case "SM2":
if (v === "encrypt") {
output = sm2.doEncrypt(
this.current.input,
this.current.password,
this.current.sm2CipherMode
);
} else {
output = sm2.doDecrypt(
this.current.input,
this.current.password,
this.current.sm2CipherMode
);
}
break;
case "SM4":
// sm-crypto 要求传入的 key 为 Hex 格式,因此对于非 Hex 格式的数据进行转换
let sm4Key = this.current.password;
if (this.current.keyFormat === "Base64") {
sm4Key = crypto.enc.Hex.stringify(crypto.enc[this.current.keyFormat].parse(this.current.password));
} else if(this.current.keyFormat === "Password") {
// 如果是 Password,按照 Utf8 编码进行处理,转换为 Hex 格式
// 注意因为库的区别,password 模式跟 crypto-js 的处理不一样
sm4Key = crypto.enc.Hex.stringify(crypto.enc.Utf8.parse(this.current.password));
}
if(v === "encrypt") {
// SM4 加密
output = sm4.encrypt(
this.current.input,
sm4Key,
{
mode: this.current.mode.toLowerCase(),
// sm-crypto 传入的 iv 为 Hex 格式
iv: this.current.iv,
padding: this.current.padding
}
);
} else {
// SM4 解密
output = sm4.decrypt(
this.current.input,
sm4Key,
{
mode: this.current.mode.toLowerCase(),
// sm-crypto 传入的 iv 为 Hex 格式
iv: this.current.iv,
padding: this.current.padding
}
);
}
}
if (!output) {
throw new Error("output null")
}
this.current.output = output
} catch (e) {
return this.$Message.error(
this.$t('encrypt_failed', [e.message]).toString()
)
}
this.current.operation = v;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
},
sm2Generate() {
const sm2 = require('sm-crypto').sm2
let keypair = sm2.generateKeyPairHex()
let string = [
this.$t('encrypt_public_key'),
keypair.publicKey,
this.$t('encrypt_private_key'),
keypair.privateKey, '',
this.$t('encrypt_secret_key_prompt')
].join("\n");
this.$Modal.info({
render: (h) => {
return h('Input', {
props: {
value: string,
type: "textarea",
rows: 9
}
})
},
okText: this.$t('encrypt_close'),
width: 600
})
},
resize(height) {
this.inputHeight = Math.min(160, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
}
},
data() {
return {
current: {
input: "",
password: "",
keyFormat: "Hex",
iv: "",
mode:"ECB",
padding:"Pkcs7",
sm2CipherMode: "C1C3C2",
output: "",
type: "AES",
operation: ""
},
type: ["AES", "DES", "RC4", "Rabbit", "TripleDES", "SM2", "SM4"],
inputHeight: 100,
outputHeight: 100
}
},
}
</script>
<template>
<div id="tool-hash">
<Row :gutter="10">
<Col span="10">
<div style="position: relative;">
<input-block>
<heightResize>
<autoHeightTextarea v-model="current.input" :placeholder="$t('hash_content')"/>
</heightResize>
<template slot="extra">
<updateFile @success="handleUpload"/>
<Checkbox style="margin-left: 10px" v-model="current.isUppercase">{{
$t('hash_uppercase')
}}
</Checkbox>
</template>
</input-block>
<disableMask v-if="isUploadFile" @close="uploadFile = {}">
{{ this.uploadFile.file.name }}
</disableMask>
</div>
</Col>
<Col span="14">
<heightResize @resize="resize">
<input-block :style="`margin-top: ${no >0 ? 5 : 0}px;`" :text="type" v-for="(type,no) in types"
:key="type" @on-default-right-bottom-click="()=>$copy(result(type))">
<autoHeightTextarea :value="result(type)" :height="outputHeight" :placeholder="type"/>
</input-block>
</heightResize>
</Col>
</Row>
</div>
</template>
<script>
import crypto from "crypto-js"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
import updateFile from './components/updateFile';
import disableMask from "./components/disableMask.vue";
const sm = require('sm-crypto');
export default {
components: {
updateFile,
heightResize,
autoHeightTextarea,
disableMask
},
created() {
this.$initToolData('input')
},
computed: {
realInput() {
return this.isUploadFile ? this.uploadFile.data : this.current.input
},
md5() {
let result = crypto.MD5(this.realInput).toString();
return this.current.isUppercase ? result.toUpperCase() : result;
},
sha1() {
let result = crypto.SHA1(this.realInput).toString();
return this.current.isUppercase ? result.toUpperCase() : result;
},
sha256() {
let result = crypto.SHA256(this.realInput).toString();
return this.current.isUppercase ? result.toUpperCase() : result;
},
sha512() {
let result = crypto.SHA512(this.realInput).toString();
return this.current.isUppercase ? result.toUpperCase() : result;
},
sm3() {
let result = sm.sm3(this.realInput);
return this.current.isUppercase ? result.toUpperCase() : result;
},
isUploadFile() {
return "file" in this.uploadFile
},
},
watch: {
current: {
handler() {
if (this.current.input) {
this.$saveToolData(this.current);
}
},
deep: true
}
},
methods: {
result(type) {
if (!this.realInput) {
return "";
}
return this[type]
},
resize(height) {
this.outputHeight = (height - 20) / 5
},
handleUpload(file) {
let r = new FileReader()
r.readAsBinaryString(file)
r.onloadend = () => {
let data = crypto.enc.Latin1.parse(r.result);
if (data) {
this.uploadFile = {file, data}
}
}
},
},
data() {
return {
current: {
input: "",
isUppercase: false,
},
uploadFile: {},
types: ['md5', 'sha1', 'sha256', 'sha512', "sm3"],
outputHeight: 100
}
},
}
</script>
<template>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('hexString_input')"/>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('hex')">Base64 -> Hex</Button>
<Button type="primary" @click="handle('base64')">Hex -> Base64</Button>
</ButtonGroup>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUppercase">{{ $t('hexString_uppercase') }}</Checkbox>
</FormItem>
</option-block>
<autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('hexString_output')"/>
</heightResize>
</template>
<script>
import CryptoJS from "crypto-js"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
import {Base64} from 'js-base64'
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData('input')
},
methods: {
handle(type) {
if (this.current.input) {
try {
switch (type) {
case "hex":
if (!Base64.isValid(this.current.input)){
throw new Error("input base64 string invalid")
}
this.current.output = CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(this.current.input));
break;
case "base64":
this.current.output = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(this.current.input));
break;
default:
return;
}
if (this.current.isUppercase && type === "hex") {
this.current.output = this.current.output.toUpperCase()
}
this.current.operation = type;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}catch (e) {
this.$Message.error(e.message)
}
}
},
resize(height) {
this.inputHeight = Math.min(160, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
}
},
data() {
return {
current: {
input: "",
isUppercase: false,
output: "",
operation: ""
},
inputHeight: 100,
outputHeight: 100
}
},
}
</script>
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('hex')">String -> Hex</Button>
<Button type="primary" @click="handle('str')">Hex -> String</Button>
</ButtonGroup>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUppercase">大写字母</Checkbox>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
</template>
<script>
export default {
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
methods: {
handle(type) {
if (this.current.input) {
const convert = (from, to) => str => Buffer.from(str, from).toString(to)
switch (type) {
case "hex":
this.current.output = convert('utf8', 'hex')(this.current.input);
break;
case "str":
this.current.output = convert('hex', 'utf8')(this.current.input.trim().replace(/\s+/g, ""));
break;
default:
return;
}
if (this.current.isUppercase && type === "hex") {
this.current.output = this.current.output.toUpperCase()
}
this.current.operation = type;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
}
},
data() {
return {
current: {
input: "",
isUppercase: false,
output: "",
operation: ""
}
}
},
}
</script>
\ No newline at end of file
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('encode')">编码</Button>
<Button type="primary" @click="handle('decode')">解密</Button>
</ButtonGroup>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
</template>
<script>
export default {
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
methods: {
handle(v) {
if (this.current.input) {
if (v === "encode") {
this.current.output = require('js-htmlencode').htmlEncode(this.current.input);
} else {
this.current.output = require('js-htmlencode').htmlDecode(this.current.input);
}
this.current.operation = v;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
}
},
data() {
return {
current: {
input: "",
output: "",
operation: ""
}
}
},
}
</script>
<template>
<div>
<option-block>
<FormItem>
<Input v-model="current.input" placeholder="请输入ip地址" style="width:200px"></Input>
</FormItem>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle()">查询</Button>
<Button type="primary" @click="local()">本地IP</Button>
</ButtonGroup>
</FormItem>
<FormItem>
<Alert>ip信息来源 <a href="https://get.geojs.io/" target="_blank">https://get.geojs.io/</a></Alert>
</FormItem>
</option-block>
<div style="border: 1px solid #dcdee2;border-radius: 4px;">
<code-editor v-model="current.output" language="json"></code-editor>
</div>
</div>
</template>
<script>
import axios from "axios"
import _ from "lodash"
import codeEditor from "./components/codeEditor";
export default {
components: {
codeEditor,
},
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
methods: {
handle() {
if (this.current.input) {
axios({
url: 'https://get.geojs.io/v1/ip/geo.json',
params: this.current.input !== "localhost" ? {ip: this.current.input} : {}
}).then(({data}) => {
this.current.output = JSON.stringify(_.isArray(data) && data.length < 2 ? data[0] : data,null, 4);
this.$saveToolData(this.current);
this.$Message.success("查询成功")
}).catch((error) => {
return this.$Message.error("ip地址信息查询错误:" + error);
});
}
},
local() {
this.current.input = 'localhost';
this.handle()
}
},
data() {
return {
current: {
input: "",
output: "",
}
}
},
}
</script>
<template>
<div>
<Row :gutter="8" style="margin-bottom: 10px">
<Col span="8" offset="3">
<Input v-model="current.ip">
<span slot="prepend">
{{ $t('ipcalc_ip') }}
</span>
</Input>
</Col>
<Col span="6">
<Input v-model="current.mask">
<span slot="prepend">{{ $t('ipcalc_mask') }}</span>
<Button slot="append" icon="md-settings" @click="maskSet"/>
</Input>
</Col>
<Col span="3">
<Tooltip transfer placement="top" :content="$t('ipcalc_format')" :delay="300">
<Icon type="ios-help-circle-outline" size="22" style="margin-top: 4px;cursor: pointer" @click="show_input_format = true" />
</Tooltip>
</Col>
</Row>
<div v-if="error" style="margin-top: 50px;text-align: center">
<Tag color="error"> {{ error }}</Tag>
</div>
<div class="tool-ipcalc" v-if="ipcalc && !error">
<Card :title="$t('ipcalc_ip_info')">
<span slot="extra">{{ current.ip }}</span>
<CellGroup @on-click="(name)=>$copy(ip[name])">
<Row>
<Col span="7">
<Cell name="ip" :title="ip.ip" :label="$t('ipcalc_ip_info_ip10')"/>
</Col>
<Col span="7">
<Cell name="long" :title="ip.long" :label="$t('ipcalc_ip_info_long')"/>
</Col>
<Col span="10">
<Cell name="ip8" :title="ip.ip8" :label="$t('ipcalc_ip_info_ip8')"/>
</Col>
</Row>
<Row>
<Col span="7">
<Cell name="ip16" :title="ip.ip16" :label="$t('ipcalc_ip_info_ip16')"/>
</Col>
<Col span="10">
<Cell name="ip2" :title="ip.ip2" :label="$t('ipcalc_ip_info_ip2')"/>
</Col>
</Row>
</CellGroup>
</Card>
<Card :title="$t('ipcalc_mask_info')" style="margin: 5px 0">
<span slot="extra">{{ current.mask }}</span>
<CellGroup @on-click="(name)=>$copy(mask[name])">
<Row>
<Col span="6">
<Cell name="bit" :title="mask.bit" :label="$t('ipcalc_mask')"/>
</Col>
<Col span="6">
<Cell name="mask" :title="mask.mask" :label="$t('ipcalc_mask_info_mask')"/>
</Col>
<Col span="6">
<Cell name="long" :title="mask.long" :label="$t('ipcalc_mask_info_long')"/>
</Col>
<Col span="6">
<Cell name="opposite" :title="mask.opposite" :label="$t('ipcalc_mask_info_opposite')"/>
</Col>
</Row>
<Row>
<Col span="6">
<Cell name="mask8" :title="mask.mask8" :label="$t('ipcalc_mask_info_mask8')"/>
</Col>
<Col span="6">
<Cell name="mask16" :title="mask.mask16" :label="$t('ipcalc_mask_info_mask16')"/>
</Col>
<Col span="12">
<Cell name="mask2" :title="mask.mask2" :label="$t('ipcalc_mask_info_mask2')"/>
</Col>
</Row>
</CellGroup>
</Card>
<Card :title="$t('ipcalc_network_info')">
<a href="#" slot="extra" @click.prevent="networkExport">{{ $t("ipcalc_network_export") }}</a>
<CellGroup @on-click="(name)=>$copy(network[name])">
<Row>
<Col span="7">
<Cell name="available" :title="`${network.available}`"
:label="$t('ipcalc_network_info_available')"/>
</Col>
<Col span="7">
<Cell name="size" :title="`${network.size}`" :label="$t('ipcalc_network_info_size')"/>
</Col>
<Col span="10">
<Cell name="base" :title="`${network.base}`" :label="$t('ipcalc_network_info_base')"/>
</Col>
</Row>
<Row>
<Col span="7">
<Cell name="first" :title="`${network.first}`" :label="$t('ipcalc_network_info_first')"/>
</Col>
<Col span="7">
<Cell name="last" :title="`${network.last}`" :label="$t('ipcalc_network_info_last')"/>
</Col>
<Col span="10">
<Cell name="broadcast" :title="`${network.broadcast}`"
:label="$t('ipcalc_network_info_broadcast')"/>
</Col>
</Row>
</CellGroup>
</Card>
</div>
<Modal
v-model="show_input_format"
:title="`${$t('ipcalc_format')}`"
:width="780"
footer-hide
>
<div class="tool-ipcalc">
<Card :title="$t('ipcalc_ip')" style="margin-bottom: 10px">
<CellGroup>
<Row>
<Col span="6">
<Cell title="192.168.0.1" :label="$t('ipcalc_ip_info_ip10')"/>
</Col>
<Col span="6">
<Cell title="3232235521" :label="$t('ipcalc_ip_info_long')"/>
</Col>
<Col span="6">
<Cell title="0300.0250.0000.0001" :label="$t('ipcalc_ip_info_ip8')"/>
</Col>
<Col span="6">
<Cell title="0xC0.0xA8.0x00.0x01" :label="$t('ipcalc_ip_info_ip16')"/>
</Col>
</Row>
<Row>
<Col span="15">
<Cell title="0b11000000.0b10101000.0b00000000.0b00000001" :label="$t('ipcalc_ip_info_ip2')"/>
</Col>
</Row>
</CellGroup>
</Card>
<Card :title="$t('ipcalc_mask')">
<CellGroup>
<Row>
<Col span="6">
<Cell title="24" :label="$t('ipcalc_mask')"/>
</Col>
<Col span="6">
<Cell title="255.255.255.0" :label="$t('ipcalc_mask_info_mask')"/>
</Col>
<Col span="6">
<Cell title="4294967040" :label="$t('ipcalc_mask_info_long')"/>
</Col>
<Col span="6">
<Cell title="0377.0377.0377.0000" :label="$t('ipcalc_mask_info_mask8')"/>
</Col>
</Row>
<Row>
<Col span="6">
<Cell title="0xFF.0xFF.0xFF.0x00" :label="$t('ipcalc_mask_info_mask16')"/>
</Col>
<Col span="15">
<Cell title="0b11111111.0b11111111.0b11111111.0b00000000"
:label="$t('ipcalc_mask_info_mask2')"/>
</Col>
</Row>
</CellGroup>
</Card>
</div>
</Modal>
<Modal
v-model="export_show"
:title="$t('ipcalc_network_export')"
:width="260"
footer-hide
>
<Input :rows="15" :value="export_data" type="textarea"></Input>
</Modal>
</div>
</template>
<script>
import ipcalc, {getMaskBitByAvailable} from "./library/ipcalc"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData()
},
computed: {
ip() {
const ipInfo = this.ipcalc.ipInfo()
return {
ip: ipInfo.ip,
long: ipInfo.long,
ip2: ipInfo.ip2,
ip8: ipInfo.ip8,
ip16: ipInfo.ip16,
}
},
mask() {
const maskInfo = this.ipcalc.maskInfo()
return {
bit: maskInfo.bit,
long: maskInfo.long,
mask: maskInfo.mask,
mask2: maskInfo.mask2,
mask8: maskInfo.mask8,
mask16: maskInfo.mask16,
opposite: maskInfo.opposite,
}
},
network() {
return {
available: this.ipcalc.available(),
size: this.ipcalc.size(),
base: this.ipcalc.base(),
first: this.ipcalc.first(),
last: this.ipcalc.last(),
broadcast: this.ipcalc.broadcast(),
}
}
},
watch: {
current: {
handler() {
this.init()
},
deep: true
}
},
methods: {
init() {
this.error = "";
try {
this.ipcalc = new ipcalc(this.current.ip, this.current.mask)
this.$saveToolData(this.current)
} catch (e) {
this.error = e.message
}
},
networkExport() {
this.export_data = ""
this.ipcalc.netmask.forEach((ip, long, index) => {
this.export_data = `${this.export_data ? this.export_data+"\n" : ""}${index+1}: ${ip}`
})
this.export_show = true
},
maskSet() {
let input = 254
this.$Modal.confirm({
title: this.$t('ipcalc_mask_set_title'),
onOk: () => {
try {
this.current.mask = getMaskBitByAvailable(input)
} catch (e) {
this.$Message.error(e.message)
}
},
render: (h) => {
return h('Input', {
props: {
value: input,
autofocus: true,
},
on: {
input: (val) => {
input = val
}
}
})
}
})
}
},
data() {
return {
current: {
ip: "192.168.0.1",
mask: "24",
},
ipcalc: new ipcalc(),
error: "",
show_input_format: false,
export_show:false,
export_data:""
}
}
}
</script>
<style>
.tool-ipcalc .ivu-card-head {
padding: 5px 10px;
}
.tool-ipcalc .ivu-card-body {
padding: 0 0;
}
.tool-ipcalc .ivu-card-extra {
top: 4px;
}
.tool-ipcalc .ivu-cell {
padding: 7px 16px;
}
.tool-ipcalc .ivu-cell-title {
line-height: 18px;
font-size: 16px;
}
</style>
<template>
<div>
<heightResize :append="['.page-option-block','.tool-json-mode-get']" @resize="resize">
<Row :gutter="10">
<Col :span="24-jsonInputCol" v-if="isMode('from_csv')">
<csvToJson @change="(json)=>current.content = json" @saveToolData="saveToolData" :height="height" v-model="current.from_csv" />
</Col>
<Col :span="24-jsonInputCol" v-if="isMode('from_table')">
<tableToJson @change="(json)=>current.content = json" @saveToolData="saveToolData" :height="height" v-model="current.from_table" />
</Col>
<Col :span="jsonInputCol">
<input-block top="4px">
<code-editor :height="`${height}px`" :placeholder="`${$t('json_input')}JSON`" v-model="current.content" language="json"></code-editor>
<template slot="extra">
<Button shape="circle" icon="md-code" v-if="!isMode('default')" @click="setMode('default')"></Button>
</template>
</input-block>
</Col>
<Col :span="24-jsonInputCol" v-if="isMode('to_csv')">
<jsonToCsv :json="current.content" :height="height" v-model="current.to_csv" @saveToolData="saveToolData" />
</Col>
<Col :span="24-jsonInputCol" v-if="isMode('to_table')">
<jsonToTable :json="current.content" :height="height" v-model="current.to_table" @saveToolData="saveToolData" />
</Col>
<Col :span="24-jsonInputCol" v-if="isMode('object')">
<jsonToObject :json="current.content" :height="height" v-model="current.to_object" @saveToolData="saveToolData" />
</Col>
<Col :span="24-jsonInputCol" v-if="isMode('path')">
<jsonPath :json="current.content" :height="height" v-model="current.path" @saveToolData="saveToolData" />
</Col>
</Row>
</heightResize>
<option-block style="padding-top: 10px" disable-padding class="tool-json-mode-get" v-if="isMode('to_get') || isMode('from_get')">
<Input v-if="isMode('to_get')" type="textarea" :rows="3" :value="getOutput" :placeholder="`Get ${$t('json_output')}`"></Input>
<Input v-else type="textarea" :rows="3" v-model="current.get.input" :placeholder="`Get ${$t('json_input')} var1=value1&var2=value2`"></Input>
</option-block>
<option-block center class="page-option-block">
<FormItem class="tool-json-button">
<ButtonGroup class="tool-json-item">
<Button type="primary" @click="simple('beautify')">{{ $t('json_format') }}</Button>
<Button type="primary" @click="simple('compress')">{{ $t('json_compress') }}</Button>
<Button type="primary" @click="setMode('path')">{{ $t('json_path') }}</Button>
</ButtonGroup>
<Dropdown @on-click="(name)=>simple(name)" class="tool-json-item">
<Button type="primary">
{{ $t('json_escape') }}
<Icon type="ios-arrow-up" />
</Button>
<DropdownMenu slot="list">
<DropdownItem name="escape">{{ $t('json_add_escape') }}</DropdownItem>
<DropdownItem name="clearEscape">{{ $t('json_clear_escape') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
<Dropdown @on-click="(name)=>simple(name)" class="tool-json-item">
<Button type="primary">
{{ $t('json_unicode') }}
<Icon type="ios-arrow-up" />
</Button>
<DropdownMenu slot="list">
<DropdownItem name="unicode2zh">{{ $t('json_unicode_to_zh') }}</DropdownItem>
<DropdownItem name="zh2unicode">{{ $t('json_zh_to_unicode') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
<Button class="tool-json-item" type="primary" @click="setMode('object')">{{ $t('json_object') }}</Button>
<Dropdown @on-click="(name)=>setMode(name)" class="tool-json-item">
<Button type="primary">
{{ $t('json_get') }} / {{ $t('json_csv') }} / {{ $t('json_table') }}
<Icon type="ios-arrow-up" />
</Button>
<DropdownMenu slot="list">
<DropdownItem name="to_get">JSON => Get</DropdownItem>
<DropdownItem name="to_csv">JSON => CSV</DropdownItem>
<DropdownItem name="to_table">JSON => Table</DropdownItem>
<DropdownItem name="from_get">Get => JSON</DropdownItem>
<DropdownItem name="from_csv">CSV => JSON</DropdownItem>
<DropdownItem name="from_table">Table => JSON</DropdownItem>
</DropdownMenu>
</Dropdown>
</FormItem>
</option-block>
</div>
</template>
<script>
import jsonInstance from "./library/json"
import codeEditor from "./components/codeEditor";
import heightResize from "./components/heightResize";
import jsonToObject from "./library/json/components/jsonToObject";
import csvToJson from "./library/json/components/csvToJson";
import tableToJson from "./library/json/components/tableToJson";
import {dispatchWindowResize} from "../../tool/event";
import jsonToCsv from "./library/json/components/jsonToCsv";
import jsonToTable from "./library/json/components/jsonToTable";
import jsonPath from "./library/json/components/jsonPath";
export default {
components: {
jsonToCsv,
jsonToTable,
codeEditor,
heightResize,
csvToJson,
jsonToObject,
tableToJson,
jsonPath
},
computed:{
jsonInputCol(){
if (this.isMode('object')){
return 10
}
if (this.isMode('from_csv') || this.isMode('from_table') || this.isMode('to_csv') || this.isMode('to_table') || this.isMode('path')){
return 12
}
return 24
},
getOutput(){
if (!this.isMode('to_get')){
return "";
}
try {
return jsonInstance.toGet(this.current.content)
} catch (e) {
return this.$t('json_error', [e.message]).toString();
}
},
fromGet(){
if (this.isMode('from_get') && this.current.get.input.trim()){
return this.current.get.input;
}
return "";
}
},
watch:{
fromGet(val){
if (val){
this.errorHandle(()=>{
this.setContentAndSaveToolData(jsonInstance.fromGet(val))
})
}
}
},
created() {
this.$initToolData()
},
methods: {
resize(height){
this.height = height
},
errorHandle(callback){
try {
return callback()
} catch (e) {
this.$Message.error(this.$t('json_error', [e.message]).toString())
}
return ""
},
isMode(mode){
return mode === this.current.mode
},
setMode(mode){
this.current.mode = mode
this.$nextTick(() => {
dispatchWindowResize()
})
},
// 简单处理
simple(type) {
this.errorHandle(()=>{
this.current.content = this.current.content.trim()
if (!this.current.content) {
throw new Error(this.$t('json_json_input_empty').toString())
}
// 保存操作前数据
this.saveToolData(true)
if (!(type in jsonInstance)) {
throw new Error("type error")
}
this.current.content = jsonInstance[type](this.current.content)
this.saveToolData()
this.$Message.success(this.$t('json_complete').toString())
})
},
saveToolData(force = false){
this.$saveToolData(this.current, force)
},
setContentAndSaveToolData(content){
this.current.content = content
this.saveToolData()
}
},
data() {
return {
current: {
content: '',
get: {
input: ""
},
to_object:{},
from_csv:{},
from_table:{},
to_csv:{},
to_table:{},
path:{},
mode: "default"
},
height:100
}
},
}
</script>
<style scoped>
.tool-json-button .ivu-btn {
padding: 0 10px;
}
.tool-json-button .tool-json-item{
margin-right: 5px;
}
</style>
<template>
<heightResize @resize="resize">
<Row :gutter="10">
<Col span="12">
<input-block bottom="4px">
<code-editor :height="editorheight" :placeholder="$t('jwt_input')" hideLineNumbers v-model="current.input"></code-editor>
<template slot="extra">
<Checkbox v-model="current.header">header</Checkbox>
<Checkbox v-model="current.payload">payload</Checkbox>
</template>
</input-block>
</Col>
<Col span="12">
<code-editor :height="editorheight" :placeholder="$t('jwt_output')" :value="output" language="json"></code-editor>
</Col>
</Row>
</heightResize>
</template>
<script>
import jwtDecode from "jwt-decode"
import codeEditor from "./components/codeEditor";
import jsonFormatter from "./library/formatter/json";
import heightResize from "./components/heightResize";
export default {
components: {
codeEditor,
heightResize
},
created() {
this.$initToolData('input')
},
computed: {
output() {
if(!this.current.input.trim()){
return ""
}
try {
let data = {};
if (this.current.header) {
data.header = jwtDecode(this.current.input, {header: true})
}
if (this.current.payload) {
data.payload = jwtDecode(this.current.input)
}
this.$saveToolData(this.current);
return jsonFormatter.objectBeautify(
Object.keys(data).length === 1 ? data[Object.keys(data)[0]] : data,
);
} catch (e) {
return this.$t('jwt_decode_fail',[e.message])
}
}
},
methods:{
resize(height){
this.editorheight = height+"px"
}
},
data() {
return {
current: {
input: "",
header: false,
payload: true,
},
editorheight:"100%",
}
},
}
</script>
// ASCII MAP
import Radix from "./radix.js";
const ASCII_MAP = ['NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL', 'BS', 'TAB', 'LF', 'VT', 'FF', 'CR', 'SO', 'SI',
'DLE', 'DC1', 'DC2', 'DC3', 'DC4', 'NAK', 'SYN', 'ETB', 'CAN', 'EM', 'SUB', 'ESC', 'FS', 'GS', 'RS', 'US',
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[',
'\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 'DEL']
// ASCII 不可显示字符
const ASCII_HIDDEN = {
'NUL': "空字符(Null)",
'SOH': "标题开始",
'STX': "本文开始",
'ETX': "本文结束",
'EOT': "传输结束",
'ENQ': "请求",
'ACK': "确认回应",
'BEL': "响铃",
'BS': "退格",
'TAB': "水平定位符号",
'LF': "换行键",
'VT': "垂直定位符号",
'FF': "换页键",
'CR': "归位键",
'SO': "取消变换(Shift out)",
'SI': "启用变换(Shift in)",
'DLE': "跳出数据通讯",
'DC1': "设备控制一(XON 启用软件速度控制)",
'DC2': "设备控制二",
'DC3': "设备控制三(XOFF 停用软件速度控制)",
'DC4': "设备控制四",
'NAK': "确认失败回应",
'SYN': "同步用暂停",
'ETB': "区块传输结束",
'CAN': "取消",
'EM': "连接介质中断",
'SUB': "替换",
'ESC': "跳出",
'FS': "文件分割符",
'GS': "组群分隔符",
'RS': "记录分隔符",
'US': "单元分隔符",
'DEL': "删除",
}
const radix = new Radix();
class Ascii {
constructor(c, type = "str") {
let dec = -1;
c = c + "";
if (type !== "str"){
c = c.toLowerCase();
}
switch (type) {
case 'str':
dec = ASCII_MAP.indexOf(c)
break;
case 'dec':
dec = radix.convent(c, 10, 10);
break;
case 'hex':
dec = radix.convent(c, 16, 10);
break;
case 'oct':
dec = radix.convent(c, 8, 10);
break;
case 'bin':
dec = radix.convent(c.replace(/\b(0+)/gi, ""), 2, 10);
break;
default:
throw 'type error'
}
if (dec < 0 || dec > 127) {
throw 'input error'
}
this.decData = dec
}
dec() {
return this.decData + ""
}
hex() {
return (radix.convent(this.decData, 10, 16) + "").toUpperCase()
}
oct() {
return radix.convent(this.decData, 10, 8) + ""
}
bin() {
return (radix.convent(this.decData, 10, 2) + "").padStart(8, '0')
}
str() {
return ASCII_MAP[this.decData]
}
}
const convent = (s, currentType, targetType) => {
const types = ['str', 'dec', 'hex', 'oct', 'bin'];
if (!types.includes(currentType) || !types.includes(targetType)) {
throw 'type error'
}
let r = [];
for (const c of s.split(currentType === "str" ? '' : ' ')) {
let ascii = new Ascii(c, currentType);
r.push(ascii[targetType]())
}
return r.join(targetType === "str" ? '' : ' ');
}
export default {
convent,
Ascii,
ascii_map: ASCII_MAP,
ascii_hidden: ASCII_HIDDEN,
}
/**
* @link https://github.com/leizelong/binary
*/
function toFixed(d = '', length = 32, symbol = 0) {
if (d.length < length) {
return symbol + '0'.repeat(length - 1 - d.length) + d;
}
return d;
}
class Binary {
constructor(length) {
this.length = length;
}
getBinary(d) {
return Math.abs(parseInt(d)).toString(2);
}
// 原码
trueForm(d) {
const two = this.getBinary(d);
if (d >= 0) {
return toFixed(two, this.length, 0);
}
return toFixed(two, this.length, 1);
}
// 反码
inverse(d) {
const trueForm = this.trueForm(d);
if (d >= 0) {
return trueForm;
}
let data = '';
// eslint-disable-next-line no-plusplus
for (let index = 0; index < this.length; index++) {
const item = trueForm[index];
if (index === 0) {
data += item;
} else {
data += Math.abs(+item - 1);
}
}
return data;
}
// 补码
complement(d) {
const trueForm = this.trueForm(d);
const inverse = this.inverse(d);
if (d >= 0) {
return trueForm;
}
const valid = inverse.slice(1);
const validTenComplete = parseInt(valid, 2) + 1;
return toFixed(
validTenComplete.toString(2),
this.length,
1
);
}
}
export default (input, length, type) => {
if (!["trueForm", "inverse", "complement"].includes(type)) {
throw new Error("type error")
}
if (![8, 16, 32].includes(length)) {
throw new Error("length error")
}
// 0 特殊处理
if (
input === "0"
|| input === "+0"
|| input === "-0"
) {
if (type === "trueForm") {
return input === "-0" ? ("1" + Array(length).join("0")).slice(0, length - 1) : Array(length).join("0")
}
if (type === "inverse") {
return input === "-0" ? Array(length).join("1") : Array(length).join("0")
}
if (type === "complement") {
return input === "-0" ? Array(length).join("0") : Array(length).join("0")
}
return "";
}
input = parseInt(input);
switch (length) {
case 8:
if (!(input >= -128 && input <= 127)) {
throw new Error('length:8 input:-128 ~ 127')
}
break;
case 16:
if (!(input >= -32768 && input <= 32767)) {
throw new Error('length:16 input:-32768 ~ 32767')
}
break;
case 32:
if (!(input >= -2147483648 && input <= 2147483647)) {
throw new Error('length:32 input:-2147483648 ~ 2147483647')
}
break;
default:
throw new Error('length error')
}
let handle = (new Binary(length))
switch (type) {
case "trueForm":
return handle.trueForm(input)
case "inverse":
return handle.inverse(input)
case "complement":
return handle.complement(input)
}
}
import CodeMirror from 'codemirror';
import "codemirror/lib/codemirror.css";
import 'codemirror/addon/fold/foldcode'
import "codemirror/addon/fold/foldgutter";
import "codemirror/addon/fold/brace-fold";
import "codemirror/addon/fold/comment-fold";
import "codemirror/addon/fold/foldgutter.css";
import 'codemirror/addon/merge/merge'
import 'codemirror/addon/merge/merge.css'
import "codemirror/addon/display/placeholder";
import "codemirror/addon/search/search";
import "codemirror/addon/search/searchcursor";
import "codemirror/addon/search/jump-to-line";
import "codemirror/addon/dialog/dialog";
import "codemirror/addon/dialog/dialog.css";
import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/htmlmixed/htmlmixed.js";
import "codemirror/mode/css/css.js";
import "codemirror/mode/xml/xml.js";
import "codemirror/mode/sql/sql.js";
import "codemirror/mode/php/php.js";
import "codemirror/mode/ruby/ruby.js";
import "codemirror/mode/python/python.js";
import "codemirror/mode/clike/clike.js";
import "codemirror/mode/go/go.js";
import "codemirror/mode/vue/vue.js";
import "codemirror/mode/dart/dart.js";
import "codemirror/mode/markdown/markdown.js";
import "codemirror/mode/yaml/yaml.js";
import "codemirror/mode/protobuf/protobuf.js";
import 'codemirror-graphql/mode';
import DiffMatchPatch from 'diff-match-patch'
if (!("diff_match_patch" in window)) {
window["diff_match_patch"] = DiffMatchPatch
window['DIFF_DELETE'] = -1
window['DIFF_INSERT'] = 1
window['DIFF_EQUAL'] = 0
}
const modes = {
text: "text/plain",
json: "application/json",
js: "application/javascript",
html: "text/html",
xml: "application/xml",
css: "text/css",
less: "text/x-less",
scss: "text/x-scss",
graphql: "graphql",
java: "text/x-java",
ruby: "text/x-ruby",
markdown: "text/x-markdown",
php: "text/x-php",
python: "text/x-python",
sql: "text/x-sql",
yaml: "text/x-yaml",
ts: "application/typescript",
csharp: "text/x-csharp",
go: "text/x-go",
dart: "application/dart",
vue: "text/x-vue",
protobuf: "text/x-protobuf",
};
const modeConversion = (lang) => {
return lang && (lang in modes) ? modes[lang] : 'text/plain'
}
export const allLang = Object.keys(modes)
export const create = (container, lang, option = {}) => {
let editor = CodeMirror(container,
Object.assign({
lineNumbers: true,
lineWrapping: true,
matchBrackets: true,
foldGutter: true,
smartIndent: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
}, option, {mode: modeConversion(lang)})
);
editor['customSetEditorLanguage'] = (lang) => {
editor.setOption("mode", modeConversion(lang));
}
return editor
}
export const createMerge = (data, container, lang, option = {}) => {
let {original, modified} = data
let editor = CodeMirror.MergeView(container,
Object.assign(
{
mode: "application/javascript",
value: original,
orig: modified,
connect: 'align',
allowEditingOriginals: true,
lineNumbers: true,
},
option,
{mode: modeConversion(lang)}
)
);
editor['customSetEditorLanguage'] = (lang) => {
editor.edit.setOption("mode", modeConversion(lang))
editor.right.orig.setOption("mode", modeConversion(lang))
}
editor['customSetValue'] = (value) => {
let {original, modified} = value
if (editor.edit.getValue() !== original || editor.right.orig.getValue() !== modified) {
editor.edit.setValue(original)
editor.right.orig.setValue(modified)
}
}
editor['customChange'] = (callback) => {
editor.edit.on('change', () => {
callback && callback(editor.edit.getValue(), editor.right.orig.getValue())
})
editor.right.orig.on('change', () => {
callback && callback(editor.edit.getValue(), editor.right.orig.getValue())
})
}
return editor
}
import prettier from "prettier/standalone";
import parser from "prettier/parser-babel";
import parserJson5 from "prettier/parser-babel";
import parserTypeScript from "prettier/parser-typescript";
import parserGraphql from "prettier/parser-graphql";
import parserMarkdown from "prettier/parser-markdown";
import parserCss from "prettier/parser-postcss";
import parserYaml from "prettier/parser-yaml";
import parserHtml from "prettier/parser-html";
// import parserJava from "prettier-plugin-java";
import parserSql from "prettier-plugin-sql";
import parserPhp from "@prettier/plugin-php";
// import parserXml from "@prettier/plugin-xml";
//https://github.com/prettier/prettier/issues/6264#issuecomment-507535391
const options = {
js: {parser: "babel", plugins: [parser]},
ts: {parser: "typescript", plugins: [parserTypeScript]},
vue: {parser: "vue", plugins: [parserHtml]},
graphql: {parser: "graphql", plugins: [parserGraphql]},
markdown: {parser: "markdown", plugins: [parserMarkdown]},
css: {parser: "css", plugins: [parserCss]},
less: {parser: "less", plugins: [parserCss]},
scss: {parser: "scss", plugins: [parserCss]},
yaml: {parser: "yaml", plugins: [parserYaml]},
html: {parser: "html", plugins: [parserHtml]},
angular: {parser: "angular", plugins: [parserHtml]},
json: {parser: "json5", plugins: [parserJson5], quoteProps: "preserve", trailingComma: "none"},
// xml: {parser: "xml", plugins: [parserXml]},
sql: {parser: "sql", plugins: [parserSql]},
php: {parser: "php", plugins: [parserPhp]},
// java: {parser: "java", plugins: [parserJava]},
};
export default (code, lang, {tab = 4}) => {
if (!(lang in options)) {
throw new Error(`${lang} can't format`);
}
let langOption = options[lang];
langOption.tabWidth = tab
return prettier.format(code, langOption);
};
import prettier from "prettier/standalone";
import parserHtml from "prettier/parser-html";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserHtml],
parser: "angular",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
import prettier from "prettier/standalone";
import parserCss from "prettier/parser-postcss";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserCss],
parser: "css",
tabWidth: "tab" in option ? option.tab : 4
});
}
// eslint-disable-next-line no-unused-vars
export const compress = (code, options = {}) => {
return code
// .replace(/\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\//g, "") // 移除注释
.replace(/\s+/g, " ").replace(/{\s+/g, "{").replace(/}\s+/g, "}").replace(/;\s+/g, ";").replace(/\/\*\s+/g, "/*").replace(/\*\/\s+/g, "*/")
}
export default {
beautify,compress
}
import prettier from "prettier/standalone";
import parserGraphql from "prettier/parser-graphql";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserGraphql],
parser: "graphql",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
import prettier from "prettier/standalone";
import parserHtml from "prettier/parser-html";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserHtml],
parser: "html",
tabWidth: "tab" in option ? option.tab : 4
});
}
// eslint-disable-next-line no-unused-vars
export const compress = (code, options = {}) => {
let headHTML = "";
code = code.replace(/(\r\n|\n|\r|\t)/gm, "");
code = code.replace(/\s+/g, " ");
code = code.replace(new RegExp("</HEAD", "gi"), '</head');
code = code.replace(new RegExp("</head ", "gi"), '</head');
let bodySplit = "</head>";
let i = code.indexOf(bodySplit) !== -1;
if (i === true) {
let tempo = code.split(new RegExp(bodySplit, 'i'));
headHTML = tempo[0];
code = tempo[1];
} else {
bodySplit = "";
}
code = code.replace(/(\r\n|\n|\r|\t)/gm, "");
code = code.replace(/\s+/g, " ");
return headHTML + bodySplit + '\n' + code;
}
export default {
beautify, compress
}
import js from "./javascript"
import json from "./json"
import ts from "./typescript"
import css from "./css"
import html from "./html"
import sql from "./sql"
import xml from "./xml"
import php from "./php"
import yaml from "./yaml"
import markdown from "./markdown"
import graphql from "./graphql"
import vue from "./vue"
import less from "./less"
import scss from "./scss"
import angular from "./angular"
const methods = {
js,
json,
ts,
vue,
graphql,
markdown,
css,
less,
scss,
yaml,
html,
angular,
xml,
php,
sql
};
// 代码格式化
export const format = (code, lang, isCompress = false, options = {}) => {
let method = isCompress ? "compress" : "beautify";
if (!(lang in methods) || !(method in methods[lang])){
throw new Error(`lang:"${lang}" not support ${method}`);
}
return methods[lang][method](code,options)
};
export default format
import prettier from "prettier/standalone";
import parser from "prettier/parser-babel";
// https://github.com/mishoo/UglifyJS/issues/4878
// eslint-disable-next-line import/no-unresolved, import/extensions, import/no-webpack-loader-syntax
import UglifyJS from './uglify';
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parser],
parser: "babel",
tabWidth: "tab" in option ? option.tab : 4
});
}
// eslint-disable-next-line no-unused-vars
export const compress = (code, options = {}) => {
let result = UglifyJS.minify(code, {
keep_fnames: true,
compress: false,
mangle: false,
output: {
beautify: false,
}
})
if (!("code" in result) || !result.code){
throw new Error("compress error:"+JSON.stringify(result.error))
}
return result.code
}
export default {
beautify,compress
}
import prettier from "prettier/standalone";
import parserJson5 from "prettier/parser-babel";
export const beautify = (code, {tab = 4} = {}) => {
return prettier.format(code, {
parser: "json5",
plugins: [parserJson5],
quoteProps: "preserve",
trailingComma: "none",
tabWidth: tab,
printWidth: 1
})
}
export const objectBeautify = (codeObject, option = {}) => {
return beautify(JSON.stringify(codeObject), option)
}
// eslint-disable-next-line no-unused-vars
export const compress = (code, options = {}) => {
let result = []
for (let i = !1, o = 0, r = (code = code.split("\n").join(" ")).length; o < r; o++) {
let a = code.charAt(o);
i && a === i ? "\\" !== code.charAt(o - 1) && (i = !1) : i || '"' !== a && "'" !== a ? i || " " !== a && "\t" !== a || (a = "") : i = a
result.push(a)
}
return result.join("")
}
export default {
beautify, compress, objectBeautify
}
import prettier from "prettier/standalone";
import parserCss from "prettier/parser-postcss";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserCss],
parser: "less",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
import prettier from "prettier/standalone";
import parser from "prettier/parser-markdown";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parser],
parser: "markdown",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
import prettier from "prettier/standalone";
import phpPlugin from "@prettier/plugin-php/standalone";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [phpPlugin],
parser: "php",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
import prettier from "prettier/standalone";
import parserCss from "prettier/parser-postcss";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserCss],
parser: "scss",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
import prettier from "prettier/standalone";
import parserSql from "prettier-plugin-sql";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserSql],
parser: "sql",
tabWidth: "tab" in option ? option.tab : 4
});
}
// eslint-disable-next-line no-unused-vars
export const compress = (code, options = {}) => {
return code.replace(/\s+/g, " ").replace(/\s+\(/, "(").replace(/\s+\)/, ")")
}
export default {
beautify,compress
}
import prettier from "prettier/standalone";
import parserTypeScript from "prettier/parser-typescript";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserTypeScript],
parser: "typescript",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
因为 它太大了无法显示 source diff 。你可以改为 查看blob
import prettier from "prettier/standalone";
import parserHtml from "prettier/parser-html";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parserHtml],
parser: "vue",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
import xmlFormatter from "xml-formatter"
export const beautify = (code, option = {}) => {
return xmlFormatter(code, {
indentation: " ".repeat("tab" in option ? option.tab : 4),
collapseContent: true,
lineSeparator: '\n'
});
}
// eslint-disable-next-line no-unused-vars
export const compress = (code, options = {}) => {
return xmlFormatter(code, {
indentation: '',
collapseContent: true,
lineSeparator: ''
});
}
export default {
beautify, compress
}
import prettier from "prettier/standalone";
import parser from "prettier/parser-yaml";
export const beautify = (code, option = {}) => {
return prettier.format(code, {
plugins: [parser],
parser: "yaml",
tabWidth: "tab" in option ? option.tab : 4
});
}
export default {
beautify
}
import {ip2long, long2ip, Netmask} from "netmask"
import Radix from "./radix"
const radix = new Radix()
const tryBinaryToDecimal = (ip) => {
if (ip.includes('.') && ip.substr(0, 2).toUpperCase() === "0B") {
return ipConvert(ip, 10, 2, '0b')
}
return ip
}
export const ipConvert = (ip, toRadix = 10, fromRadix = 10, filterPrefix = "") => {
toRadix = parseInt(toRadix, 10);
fromRadix = parseInt(fromRadix, 10);
return ip.split('.').map((item) => {
// 移除前缀
if (
filterPrefix
&& item.length > filterPrefix.length
&& item.substr(0, filterPrefix.length).toUpperCase() === filterPrefix.toUpperCase()
) {
item = item.substr(filterPrefix.length)
}
// 移除补零
item = item.replace(/\b(0+)/gi, "") || "0"
if (toRadix === fromRadix) {
return `${item}`;
}
return `${radix.convent(item, fromRadix, toRadix).padStart(toRadix === 2 ? 8 : (toRadix === 8 ? 4 : 2), '0').toUpperCase()}`
}).join('.')
}
export const getMaskBitByAvailable = (available) => {
available = parseInt(`${available}`, 10);
if (isNaN(available) || available > 0xfffffffe || available < 1) {
throw new Error(`Available Size Invalid`)
}
let bitSize = parseInt(`${Math.log(available) / Math.log(2)}`) + 1;
if ((Math.pow(2, bitSize) - available) < 2) {
bitSize += 1;
}
return 32 - bitSize
}
export default class {
netmask = null
ip = ""
constructor(
ipAddr = "192.168.0.1" // lang/点分[10/8/16]进制
, maskAddr = "24" // 位数/lang/点分[10/8/16]进制
) {
// mask long
if (!`${maskAddr}`.includes('.') && parseInt(`${maskAddr}`, 10) > 32) {
maskAddr = long2ip(maskAddr)
}
// ip/mask 支持二进制
ipAddr = tryBinaryToDecimal(ipAddr)
maskAddr = tryBinaryToDecimal(maskAddr)
this.netmask = new Netmask(`${ipAddr}/${maskAddr}`)
this.ip = `${long2ip(ip2long(ipAddr))}`
}
// 可用地址
available() {
return Math.max(this.netmask.size - 2, 0)
}
// 地址总数
size() {
return this.netmask.size
}
// 网络
base() {
return this.netmask.base
}
first() {
return this.netmask.first
}
last() {
return this.netmask.last
}
broadcast() {
return this.netmask.broadcast || "-"
}
// 当前ip
ipInfo() {
return {
ip: this.ip,
long: `${ip2long(this.ip)}`,
ip2: ipConvert(this.ip, 2),
ip8: ipConvert(this.ip, 8),
ip16: ipConvert(this.ip, 16),
}
}
// 当前掩码
maskInfo() {
const mask = `${long2ip(this.netmask.maskLong)}`;
return {
bit: `${this.netmask.bitmask}`,
long: `${this.netmask.maskLong}`,
mask,
mask2: ipConvert(mask, 2),
mask8: ipConvert(mask, 8),
mask16: ipConvert(mask, 16),
opposite: `${this.netmask.hostmask}`,
}
}
}
function h_initArray() {
this.length = h_initArray.arguments.length;
for (var a = 0; a < this.length; a++) this[a] = h_initArray.arguments[a]
}
function h_from10toradix(a, e) {
var t, u, v = "", l = new h_initArray(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"), n = 0;
if (t = parseInt(a, 10), isNaN(t)) v = "NaN"; else for (v = t < 1 ? "0" : ""; .9 < t;) if (n++, v = l[(u = t) % e] + v, t = Math.floor(u / e), 100 < n) {
v = "NaN";
break
}
return v
}
function h_paddto2(a) {
for (; a.length < 2;) a = "0" + a;
return a
}
function h_paddto8(a) {
for (; a.length < 8;) a = "0" + a;
return a
}
function h_countbitsfromleft(a) {
if (255 == a) return 8;
for (i = 0, bitpat = 65280; i < 8;) {
if (a == (255 & bitpat)) return i;
bitpat >>= 1, i++
}
return Number.NaN
}
function calcNWbits(a) {
sumofbits = 0, tmpvar = parseInt(a.snm_1.value, 10), isNaN(tmpvar) ? a.result.value = "无效" : (bitsfromleft = h_countbitsfromleft(tmpvar), isNaN(bitsfromleft) ? a.result.value = "无效" : (sumofbits += bitsfromleft, tmpvar = parseInt(a.snm_2.value, 10), isNaN(tmpvar) ? a.result.value = "无效" : (bitsfromleft = h_countbitsfromleft(tmpvar), isNaN(bitsfromleft) ? a.result.value = "无效" : (sumofbits += bitsfromleft, tmpvar = parseInt(a.snm_3.value, 10), isNaN(tmpvar) ? a.result.value = "无效" : (bitsfromleft = h_countbitsfromleft(tmpvar), isNaN(bitsfromleft) ? a.result.value = "无效" : (sumofbits += bitsfromleft, tmpvar = parseInt(a.snm_4.value, 10), isNaN(tmpvar) ? a.result.value = "无效" : (bitsfromleft = h_countbitsfromleft(tmpvar), isNaN(bitsfromleft) ? a.result.value = "无效" : (sumofbits += bitsfromleft, a.result.value = sumofbits))))))))
}
function resetform1(a) {
a.result.value = "", a.snm_1.value = 255, a.snm_2.value = 255, a.snm_3.value = 255, a.snm_4.value = 0
}
function h_fillbitsfromleft(a) {
if (8 <= a) return 255;
for (bitpat = 65280; 0 < a;) bitpat >>= 1, a--;
return 255 & bitpat
}
function calcNWmask(a) {
return tmpvar = parseInt(a.bits.value, 10), isNaN(tmpvar) || 32 < tmpvar || tmpvar < 0 ? (a.snm_1.value = "错误", a.snm_2.value = "", a.snm_3.value = "", a.snm_4.value = "", 1) : (a.snm_1.value = 0, a.snm_2.value = 0, a.snm_3.value = 0, a.snm_4.value = 0, 8 <= tmpvar ? (a.snm_1.value = 255, tmpvar -= 8, 8 <= tmpvar ? (a.snm_2.value = 255, tmpvar -= 8, 8 <= tmpvar ? (a.snm_3.value = 255, tmpvar -= 8, a.snm_4.value = h_fillbitsfromleft(tmpvar)) : a.snm_3.value = h_fillbitsfromleft(tmpvar), 0) : (a.snm_2.value = h_fillbitsfromleft(tmpvar), 0)) : (a.snm_1.value = h_fillbitsfromleft(tmpvar), 0))
}
function calcNWmaskForm2(a) {
if (a.hex_1.value = "", a.hex_2.value = "", a.hex_3.value = "", a.hex_4.value = "", 0 != calcNWmask(a)) return 1;
tmpvar = a.snm_1.value, a.hex_1.value = h_paddto2(h_from10toradix(tmpvar, 16)), tmpvar = a.snm_2.value, a.hex_2.value = h_paddto2(h_from10toradix(tmpvar, 16)), tmpvar = a.snm_3.value, a.hex_3.value = h_paddto2(h_from10toradix(tmpvar, 16)), tmpvar = a.snm_4.value, a.hex_4.value = h_paddto2(h_from10toradix(tmpvar, 16))
}
function resetform2(a) {
a.bits.value = 24, a.snm_1.value = "", a.snm_2.value = "", a.snm_3.value = "", a.snm_4.value = "", a.hex_1.value = "", a.hex_2.value = "", a.hex_3.value = "", a.hex_4.value = ""
}
function resetform3(a) {
a.ip_1.value = 10, a.ip_2.value = 0, a.ip_3.value = 0, a.ip_4.value = 255, a.bits_1.value = "", a.bits_2.value = "", a.bits_3.value = "", a.bits_4.value = "", a.hex_1.value = "", a.hex_2.value = "", a.hex_3.value = "", a.hex_4.value = ""
}
function calcBinBits(a) {
a.bits_1.value = "", a.bits_2.value = "", a.bits_3.value = "", a.bits_4.value = "", tmpvar = parseInt(a.ip_1.value, 10), isNaN(tmpvar) || tmpvar < 0 || 255 < tmpvar ? a.bits_1.value = "错误" : (a.bits_1.value = h_paddto8(h_from10toradix(tmpvar, 2)), a.hex_1.value = h_paddto2(h_from10toradix(tmpvar, 16)), tmpvar = parseInt(a.ip_2.value, 10), isNaN(tmpvar) || tmpvar < 0 || 255 < tmpvar ? a.bits_2.value = "错误" : (a.bits_2.value = h_paddto8(h_from10toradix(tmpvar, 2)), a.hex_2.value = h_paddto2(h_from10toradix(tmpvar, 16)), tmpvar = parseInt(a.ip_3.value, 10), isNaN(tmpvar) || tmpvar < 0 || 255 < tmpvar ? a.bits_3.value = "错误" : (a.bits_3.value = h_paddto8(h_from10toradix(tmpvar, 2)), a.hex_3.value = h_paddto2(h_from10toradix(tmpvar, 16)), tmpvar = parseInt(a.ip_4.value, 10), isNaN(tmpvar) || tmpvar < 0 || 255 < tmpvar ? a.bits_4.value = "错误" : (a.bits_4.value = h_paddto8(h_from10toradix(tmpvar, 2)), a.hex_4.value = h_paddto2(h_from10toradix(tmpvar, 16))))))
}
function reset_rest_from4(a) {
a.bcast_1.value = "", a.bcast_2.value = "", a.bcast_3.value = "", a.bcast_4.value = "", a.nwadr_1.value = "", a.nwadr_2.value = "", a.nwadr_3.value = "", a.nwadr_4.value = "", a.firstadr_1.value = "", a.firstadr_2.value = "", a.firstadr_3.value = "", a.firstadr_4.value = "", a.lastadr_1.value = "", a.lastadr_2.value = "", a.lastadr_3.value = "", a.lastadr_4.value = "", a.snm_1.value = "", a.snm_2.value = "", a.snm_3.value = "", a.snm_4.value = "", a.numofaddr.value = ""
}
function resetform4(a) {
a.bits.value = 24, a.ip_1.value = 10, a.ip_2.value = 0, a.ip_3.value = 0, a.ip_4.value = 5, reset_rest_from4(a)
}
function calNBFL(a) {
return reset_rest_from4(a), tmpvar = parseInt(a.ip_1.value, 10), isNaN(tmpvar) || 255 < tmpvar || tmpvar < 0 ? (a.numofaddr.value = "错误", 1) : (tmpvar = parseInt(a.ip_2.value, 10), isNaN(tmpvar) || 255 < tmpvar || tmpvar < 0 ? (a.numofaddr.value = "错误", 1) : (tmpvar = parseInt(a.ip_3.value, 10), isNaN(tmpvar) || 255 < tmpvar || tmpvar < 0 ? (a.numofaddr.value = "错误", 1) : (tmpvar = parseInt(a.ip_4.value, 10), isNaN(tmpvar) || 255 < tmpvar || tmpvar < 0 ? (a.numofaddr.value = "错误", 1) : 0 != calcNWmask(a) ? 1 : (tmpvar = parseInt(a.bits.value, 10), tmpvar < 0 ? (a.numofaddr.value = "错误", 1) : 32 < tmpvar ? (a.numofaddr.value = "错误", 1) : 31 == tmpvar ? (a.numofaddr.value = "two hosts", a.firstadr_1.value = a.ip_1.value & a.snm_1.value, a.firstadr_2.value = a.ip_2.value & a.snm_2.value, a.firstadr_3.value = a.ip_3.value & a.snm_3.value, a.firstadr_4.value = a.ip_4.value & a.snm_4.value, a.lastadr_1.value = a.ip_1.value | 255 & ~a.snm_1.value, a.lastadr_2.value = a.ip_2.value | 255 & ~a.snm_2.value, a.lastadr_3.value = a.ip_3.value | 255 & ~a.snm_3.value, a.lastadr_4.value = a.ip_4.value | 255 & ~a.snm_4.value, 1) : 32 == tmpvar ? (a.numofaddr.value = "one host", a.firstadr_1.value = a.ip_1.value, a.firstadr_2.value = a.ip_2.value, a.firstadr_3.value = a.ip_3.value, a.firstadr_4.value = a.ip_4.value, 1) : (a.numofaddr.value = Math.pow(2, 32 - tmpvar) - 2, a.bcast_1.value = a.ip_1.value | 255 & ~a.snm_1.value, a.bcast_2.value = a.ip_2.value | 255 & ~a.snm_2.value, a.bcast_3.value = a.ip_3.value | 255 & ~a.snm_3.value, a.bcast_4.value = a.ip_4.value | 255 & ~a.snm_4.value, a.nwadr_1.value = a.ip_1.value & a.snm_1.value, a.nwadr_2.value = a.ip_2.value & a.snm_2.value, a.nwadr_3.value = a.ip_3.value & a.snm_3.value, a.nwadr_4.value = a.ip_4.value & a.snm_4.value, a.firstadr_1.value = a.nwadr_1.value, a.firstadr_2.value = a.nwadr_2.value, a.firstadr_3.value = a.nwadr_3.value, a.firstadr_4.value = parseInt(a.nwadr_4.value) + 1, a.lastadr_1.value = a.bcast_1.value, a.lastadr_2.value = a.bcast_2.value, a.lastadr_3.value = a.bcast_3.value, a.lastadr_4.value = parseInt(a.bcast_4.value) - 1, 0)))))
}
function resetform6(a) {
a.numofaddr.value = 5, a.bits.value = "", a.maxaddr.value = "", a.snm_1.value = "", a.snm_2.value = "", a.snm_3.value = "", a.snm_4.value = ""
}
function calcNeeded(a) {
if (tmpvar = parseInt(a.numofaddr.value, 10), isNaN(tmpvar) || 4294967294 < tmpvar || tmpvar < 1) return a.bits.value = "ERR", a.snm_1.value = "", a.snm_2.value = "", a.snm_3.value = "", a.snm_4.value = "", void (a.maxaddr.value = "");
expval = parseInt(Math.log(tmpvar) / Math.log(2)) + 1, maxaddrval = Math.pow(2, expval), maxaddrval - tmpvar < 2 && (expval += 1), a.maxaddr.value = Math.pow(2, expval) - 2, a.bits.value = 32 - expval, calcNWmask(a)
}
function calcAmount(a) {
if (tmpvar = parseInt(a.bits.value, 10), isNaN(tmpvar) || 30 < tmpvar || tmpvar < 0) return a.numofaddr.value = "错误", a.maxaddr.value = "", a.snm_1.value = "", a.snm_2.value = "", a.snm_3.value = "", void (a.snm_4.value = "");
a.maxaddr.value = Math.pow(2, 32 - tmpvar), a.numofaddr.value = Math.pow(2, 32 - tmpvar) - 2, calcNWmask(a)
}
function resetform7(a) {
a.numofaddr.value = "", a.maxaddr.value = "", a.bits.value = 27, a.snm_1.value = "", a.snm_2.value = "", a.snm_3.value = "", a.snm_4.value = ""
}
function resetform8(a) {
a.ip_1.value = 255, a.ip_2.value = 255, a.ip_3.value = 240, a.ip_4.value = 0, a.invert_1.value = "", a.invert_2.value = "", a.invert_3.value = "", a.invert_4.value = ""
}
function calcIpInvert(a) {
a.invert_1.value = "", a.invert_2.value = "", a.invert_3.value = "", a.invert_4.value = "", tmpvar = parseInt(a.ip_1.value, 10), isNaN(tmpvar) ? a.invert_1.value = "NaN" : (a.invert_1.value = 255 & ~tmpvar, tmpvar = parseInt(a.ip_2.value, 10), isNaN(tmpvar) ? a.invert_2.value = "NaN" : (a.invert_2.value = 255 & ~tmpvar, tmpvar = parseInt(a.ip_3.value, 10), isNaN(tmpvar) ? a.invert_3.value = "NaN" : (a.invert_3.value = 255 & ~tmpvar, tmpvar = parseInt(a.ip_4.value, 10), isNaN(tmpvar) ? a.invert_4.value = "NaN" : a.invert_4.value = 255 & ~tmpvar)))
}
function resetform9(a) {
a.dec_1.value = "", a.bin_1.value = "", a.num.value = ""
}
function convertnum_hex(a) {
if (a.dec_1.value = "", a.bin_1.value = "", tmpvar = a.num.value.replace(/0x/i, ""), a.num.value = tmpvar, tmpvar = parseInt(a.num.value, 16), isNaN(tmpvar)) return a.dec_1.value = "NaN", void (a.bin_1.value = "NaN");
a.dec_1.value = tmpvar, a.bin_1.value = h_from10toradix(tmpvar, 2)
}
function resetform10(a) {
a.dec_1.value = "", a.hex_1.value = "", a.num.value = ""
}
function convertnum_bin(a) {
if (a.dec_1.value = "", a.hex_1.value = "", tmpvar = parseInt(a.num.value, 2), isNaN(tmpvar)) return a.dec_1.value = "NaN", void (a.hex_1.value = "NaN");
a.dec_1.value = tmpvar, a.hex_1.value = h_from10toradix(tmpvar, 16)
}
function resetform11(a) {
a.bin_1.value = "", a.hex_1.value = "", a.num.value = ""
}
function convertnum_dec(a) {
if (a.bin_1.value = "", a.hex_1.value = "", tmpvar = parseInt(a.num.value, 10), isNaN(tmpvar)) return a.bin_1.value = "NaN", void (a.hex_1.value = "NaN");
a.hex_1.value = h_from10toradix(tmpvar, 16), a.bin_1.value = h_from10toradix(tmpvar, 2)
}
function resetform12(a) {
a.hex.value = "", a.ip_1.value = "", a.ip_2.value = "", a.ip_3.value = "", a.ip_4.value = "", a.bits_1.value = "", a.bits_2.value = "", a.bits_3.value = "", a.bits_4.value = ""
}
function dot2hex(a) {
a.ip_1.value = "", a.ip_2.value = "", a.ip_3.value = "", a.ip_4.value = "", a.bits_1.value = "", a.bits_2.value = "", a.bits_3.value = "", a.bits_4.value = "", tmpvar = a.hex.value.replace(/0x/i, ""), a.hex.value = tmpvar.substr(0, 8), tmpvar = parseInt(tmpvar, 16), isNaN(tmpvar) ? a.ip_1.value = "输入错误" : (a.hex.value = h_paddto8(a.hex.value), a.ip_1.value = parseInt(a.hex.value.substr(0, 2), 16), a.bits_1.value = h_paddto8(h_from10toradix(a.ip_1.value, 2)), a.ip_2.value = parseInt(a.hex.value.substr(2, 2), 16), a.bits_2.value = h_paddto8(h_from10toradix(a.ip_2.value, 2)), a.ip_3.value = parseInt(a.hex.value.substr(4, 2), 16), a.bits_3.value = h_paddto8(h_from10toradix(a.ip_3.value, 2)), a.ip_4.value = parseInt(a.hex.value.substr(6, 2), 16), a.bits_4.value = h_paddto8(h_from10toradix(a.ip_4.value, 2)))
}
function d2h(a) {
for (var e = a, t = "", u = 0; u < 2; u++) k = 15 & e, t = "0123456789ABCDEF".charAt(k) + t, e >>= 4;
return t
}
function h2d(a) {
for (var e = a.toUpperCase(), t = 0, u = " "; e.length < 4;) e = 0 + e;
for (var v = 0; v < 4; v++) u = e.charAt(v), t = 16 * t + "0123456789ABCDEF".indexOf(u);
return t
}
function d2b(a) {
var e = 0, t = 0, u = 0, v = 0, l = 0, n = 0, r = 0, s = 0;
return 128 & a && (e = 1), 64 & a && (t = 1), 32 & a && (u = 1), 16 & a && (v = 1), 8 & a && (l = 1), 4 & a && (n = 1), 2 & a && (r = 1), 1 & a && (s = 1), "" + e + t + u + v + l + n + r + s
}
function d2bits(a) {
var e = 0;
return 128 & a && (e += 1), 64 & a && (e += 1), 32 & a && (e += 1), 16 & a && (e += 1), 8 & a && (e += 1), 4 & a && (e += 1), 2 & a && (e += 1), 1 & a && (e += 1), e
}
function snmcorrect(a) {
return 255 < (snmcorr = a) && (snmcorr = 255), 253 == a && (snmcorr = 254), 248 < a && a < 252 && (snmcorr = 252), 240 < a && a < 248 && (snmcorr = 248), 224 < a && a < 240 && (snmcorr = 240), 192 < a && a < 224 && (snmcorr = 224), 128 < a && a < 192 && (snmcorr = 192), 0 < a && a < 128 && (snmcorr = 128), a < 0 && (snmcorr = 0), snmcorr
}
function b2d(a) {
for (var e = 0; a.length < 8;) a = "0" + a;
return "1" == a.substring(7, 8) && e++, "1" == a.substring(6, 7) && (e += 2), "1" == a.substring(5, 6) && (e += 4), "1" == a.substring(4, 5) && (e += 8), "1" == a.substring(3, 4) && (e += 16), "1" == a.substring(2, 3) && (e += 32), "1" == a.substring(1, 2) && (e += 64), "1" == a.substring(0, 1) && (e += 128), e
}
function bits2d(a) {
var e = 0;
return 0 < a && (e += 128), 1 < a && (e += 64), 2 < a && (e += 32), 3 < a && (e += 16), 4 < a && (e += 8), 5 < a && (e += 4), 6 < a && (e += 2), 7 < a && (e += 1), e
}
function initPage() {
document.forms[0].elements.length && SetOrder()
}
var code = "unknown", version = 0, platform = "Win", j = 0, i = navigator.userAgent.indexOf("MSIE");
function ClearAll(a) {
a.node.options.selectedIndex = 0, a.network.options.selectedIndex = 0, a.cf[0].checked = !0, a.oct1.value = "", a.oct2.value = "", a.oct3.value = "", a.oct4.value = "", a.snm1.value = "", a.snm2.value = "", a.snm3.value = "", a.snm4.value = "", a.snm1a.value = "", a.snm2a.value = "", a.snm3a.value = "", a.snm4a.value = "", a.snm1c.value = "", a.snm2c.value = "", a.snm3c.value = "", a.snm4c.value = "", a.snm1d.value = "", a.snm2d.value = "", a.snm3d.value = "", a.snm4d.value = "", a.snm1e.value = "", a.snm2e.value = "", a.snm3e.value = "", a.snm4e.value = "", a.oct1a.value = "", a.oct2a.value = "", a.oct3a.value = "", a.oct4a.value = "", a.oct1b.value = "", a.oct2b.value = "", a.oct3b.value = "", a.oct4b.value = "", a.hex1b.value = "", a.hex2b.value = "", a.hex3b.value = "", a.hex4b.value = "", a.bin1b.value = "", a.bin2b.value = "", a.bin3b.value = "", a.bin4b.value = "", a.nw1a.value = "", a.nw2a.value = "", a.nw3a.value = "", a.nw4a.value = "", a.node1a.value = "", a.node2a.value = "", a.node3a.value = "", a.node4a.value = "", a.nwclass.value = "", a.nwclass1.value = "", a.subsuper.value = "", a.nwquant.value = "", a.nodequant.value = "", a.snmbits.value = "", a.broad1a.value = "", a.broad2a.value = "", a.broad3a.value = "", a.broad4a.value = "", a.snmbitsc.value = "", a.dec1b.value = ""
}
function listsubnets(a) {
if (compute(a), "Illegal" != a.nwclass.value) {
if (SubnetWindow = window.open("", "SubnetWindow", "width=600px,scrollbars=yes,menubar=yes,status=yes,resizable=yes"), SubnetWindow.document.write("<h1>网络列表</h1>"), networks = a.nwquant.value, nodes = a.nodequant.value + 2, SubnetWindow.status = "正在生成表格", "子网是" == a.subsuper.value) {
var e = 0;
if (SubnetWindow.status = "正在生成表格", "C类网" == a.nwclass1.value) {
SubnetWindow.document.write("<h2>(网络 " + a.nw1a.value + "." + a.nw2a.value + "." + a.nw3a.value + ".0,掩码"), SubnetWindow.document.write(" " + a.snm1.value + "." + a.snm2.value + "." + a.snm3.value + "." + a.snm4.value + ")</h2>"), SubnetWindow.document.write("<table border=1>"), SubnetWindow.document.write("<tr><td rowspan=2 align=center><b>网络</b></td><td colspan=2 align=center><b>主机</b></td><td rowspan=2 align=center><b>广播地址</b></td></tr>"), SubnetWindow.document.write("<tr><td align=center><b>起始</b></td><td align=center><b>结束</b></td></tr>"), nodes = 256 / networks;
for (var t = 0; t < 256; t += nodes) j = t + 1, topi = t + nodes - 1 & 255, topj = topi - 1, 128 == networks && (topi = (j = t) + nodes - 1 & 255, topj = topi), SubnetWindow.document.write("<tr><td>" + a.oct1.value + "." + a.oct2.value + "." + a.oct3.value + "." + t + "</td><td>" + a.oct1.value + "." + a.oct2.value + "." + a.oct3.value + "." + j + "</td><td>" + a.oct1.value + "." + a.oct2.value + "." + a.oct3.value + "." + topj + "</td><td>" + a.oct1.value + "." + a.oct2.value + "." + a.oct3.value + "." + topi + "</td></tr>")
}
if ("B类网" == a.nwclass1.value) {
SubnetWindow.document.write("<h2>(网络 " + a.nw1a.value + "." + a.nw2a.value + ".0.0,掩码"), SubnetWindow.document.write(" " + a.snm1.value + "." + a.snm2.value + "." + a.snm3.value + "." + a.snm4.value + ")</h2>"), SubnetWindow.document.write("<table border=1>"), SubnetWindow.document.write("<tr><td rowspan=2 align=center><b>网络</b></td><td colspan=2 align=center><b>主机</b></td><td rowspan=2 align=center><b>广播地址</b></td></tr>"), SubnetWindow.document.write("<tr><td align=center><b>起始</b></td><td align=center><b>结束</b></td></tr>"), nodes = 65536 / networks;
for (t = 0; t < 65536; t += nodes) e += 1, i4 = 255 & t, i3 = t / 256 & 255, j = i4 + 1, topi4 = t + nodes - 1 & 255, topi3 = (t + nodes - 1) / 256 & 255, topj = topi4 - 1, 32768 == networks && (j = i4, topi4 = t + nodes - 1 & 255, topj = topi4), SubnetWindow.document.write("<tr><td>" + a.oct1.value + "." + a.oct2.value + "." + i3 + "." + i4 + "</td><td>" + a.oct1.value + "." + a.oct2.value + "." + i3 + "." + j + "</td><td>" + a.oct1.value + "." + a.oct2.value + "." + topi3 + "." + topj + "</td><td>" + a.oct1.value + "." + a.oct2.value + "." + topi3 + "." + topi4 + "</td></tr>"), 256 == e && 512 < networks && (SubnetWindow.document.write("<tr><td>..</td><td>..</td><td>..</td><td>..</td></tr>"), t = 65536 - e * nodes)
}
if ("A类网" == a.nwclass1.value) {
SubnetWindow.document.write("<h2>(网络 " + a.nw1a.value + ".0.0.0,掩码"), SubnetWindow.document.write(" " + a.snm1.value + "." + a.snm2.value + "." + a.snm3.value + "." + a.snm4.value + ")</h2>"), SubnetWindow.document.write("<table border=1>"), SubnetWindow.document.write("<tr><td rowspan=2 align=center><b>网络</b></td><td colspan=2 align=center><b>主机</b></td><td rowspan=2 align=center><b>广播地址</b></td></tr>"), SubnetWindow.document.write("<tr><td align=center><b>起始</b></td><td align=center><b>结束</b></td></tr>"), nodes = 16777216 / networks;
for (t = 0; t < 16777216; t += nodes) e += 1, i4 = 255 & t, i3 = t / 256 & 255, i2 = t / 65536 & 255, j = i4 + 1, topi4 = t + nodes - 1 & 255, topi3 = (t + nodes - 1) / 256 & 255, topi2 = (t + nodes - 1) / 65536 & 255, topj = topi4 - 1, 8388608 == networks && (j = i4, topi4 = t + nodes - 1 & 255, topj = topi4), SubnetWindow.document.write("<tr><td>" + a.oct1.value + "." + i2 + "." + i3 + "." + i4 + "</td><td>" + a.oct1.value + "." + i2 + "." + i3 + "." + j + "</td><td>" + a.oct1.value + "." + topi2 + "." + topi3 + "." + topj + "</td><td>" + a.oct1.value + "." + topi2 + "." + topi3 + "." + topi4 + "</td></tr>"), 256 == e && 512 < networks && (SubnetWindow.document.write("<tr><td>..</td><td>..</td><td>..</td><td>..</td></tr>"), t = 16777216 - e * nodes)
}
}
if ("Supernetted" == a.subsuper.value) {
SubnetWindow.document.write("<h2>(网络 " + a.nw1a.value + "." + a.nw2a.value + "." + a.nw3a.value + ".0,掩码"), SubnetWindow.document.write(" " + a.snm1.value + "." + a.snm2.value + "." + a.snm3.value + "." + a.snm4.value + ")</h2>"), SubnetWindow.document.write("<table border=1>"), SubnetWindow.document.write("<tr><td rowspan=2 align=center><b>网络</b></td><td colspan=2 align=center><b>主机</b></td><td rowspan=2 align=center><b>广播地址</b></td></tr>"), SubnetWindow.document.write("<tr><td align=center><b>起始</b></td><td align=center><b>结束</b></td></tr>");
t = a.nw4a.value + 1;
j = a.broad4a.value - 1, SubnetWindow.document.write("<tr><td>" + a.nw1a.value + "." + a.nw2a.value + "." + a.nw3a.value + "." + a.nw4a.value + "</td><td>" + a.nw1a.value + "." + a.nw2a.value + "." + a.nw3a.value + "." + t + "</td><td>" + a.broad1a.value + "." + a.broad2a.value + "." + a.broad3a.value + "." + j + "</td><td>" + a.broad1a.value + "." + a.broad2a.value + "." + a.broad3a.value + "." + a.broad4a.value + "</td></tr>")
}
SubnetWindow.document.write("</table>"), SubnetWindow.status = "完成"
}
}
function compute2(f) {
var cf = 1, node, nw;
if ("1" == f.cf[1].checked && (cf = f.cf[1].value), "1" == f.cf[2].checked && (cf = f.cf[2].value), "1" == f.cf[3].checked && (cf = f.cf[3].value), "MSIE" == code) node = f.node.value, nw = f.network.value, 0 < node && (nw = 0, f.network.options.selectedIndex = 0, node = eval(eval(node))); else {
var i = f.node.selectedIndex;
node = parseInt(f.node.options[i].value);
var j = f.network.selectedIndex;
nw = parseInt(f.network.options[j].value), 0 < node && (nw = 0, f.network.options.selectedIndex = 0, node = eval(eval(node)))
}
0 == nw && 0 == node && (nw = 1);
var power2 = 2;
if (255 < f.oct1.value && (f.oct1.value = 255), 255 < f.oct2.value && (f.oct2.value = 255), 255 < f.oct3.value && (f.oct3.value = 255), 255 < f.oct4.value && (f.oct4.value = 255), 0 < f.oct1.value && f.oct1.value < 127 && (f.nwclass.value = "A类网"), 127 < f.oct1.value && f.oct1.value < 192 && (f.nwclass.value = "B类网"), 191 < f.oct1.value && f.oct1.value < 224 && (f.nwclass.value = "C类网"), (f.oct1.value < 1 || 223 < f.oct1.value) && (f.nwclass.value = "Illegal", f.nwclass1.value = "", f.subsuper.value = "", f.nwquant.value = 0, f.nodequant.value = 0, f.snm1.value = 0, f.snm2.value = 0, f.snm3.value = 0, f.snm4.value = 0, f.snmbits.value = 0), "A类网" == f.nwclass.value && 1 == cf || 2 == cf && "Illegal" != f.nwclass.value) {
var nwtemp;
for (1 <= nw && (node = 16777216 / nw), 16777216 < node ? (f.nwclass1.value = "", nw = 1073741824 / node, nwtemp = nw, f.snm1.value = 255 & ~(64 / nw - 1), f.snm2.value = 0, f.snm3.value = 0, f.snm4.value = 0, f.subsuper.value = "Supernetted", nw = 1) : (f.nwclass1.value = "A类网", nw = 16777216 / node, nwtemp = nw, f.snm1.value = 255, f.snm2.value = 255 & ~(256 / nw - 1), f.snm3.value = 255 & ~(65536 / nw - 1), f.snm4.value = 255 & ~(16777216 / nw - 1), f.subsuper.value = "子网是", power2 += 6); 1 < nwtemp;) nwtemp /= 2, power2 += 1;
f.nodequant.value = node, f.nwquant.value = nw, f.snmbits.value = "/" + power2
}
if ("B类网" == f.nwclass.value && 1 == cf || 3 == cf && "Illegal" != f.nwclass.value) {
var nwtemp;
for (32768 < nw && (nw = 32768), 1 <= nw && (node = 65536 / nw), 65536 < node ? (f.nwclass1.value = "", nw = 1073741824 / node, nwtemp = nw, f.snm1.value = 255 & ~(64 / nw - 1), f.snm2.value = 255 & ~(16384 / nw - 1), f.snm3.value = 0, f.snm4.value = 0, f.subsuper.value = "Supernetted", nw = 1) : (f.nwclass1.value = "B类网", nw = 65536 / node, nwtemp = nw, f.snm1.value = 255, f.snm2.value = 255, f.snm3.value = 255 & ~(256 / nw - 1), f.snm4.value = 255 & ~(65536 / nw - 1), f.subsuper.value = "子网是", power2 += 14); 1 < nwtemp;) nwtemp /= 2, power2 += 1;
f.nodequant.value = node, f.nwquant.value = nw, f.snmbits.value = "/" + power2
}
if ("C类网" == f.nwclass.value && 1 == cf || 4 == cf && "Illegal" != f.nwclass.value) {
var nwtemp;
for (128 < nw && (nw = 128), 1 <= nw && (node = 256 / nw), 256 < node ? (f.nwclass1.value = "", nw = 1073741824 / node, nwtemp = nw, f.snm1.value = 255 & ~(64 / nw - 1), f.snm2.value = 255 & ~(16384 / nw - 1), f.snm3.value = 255 & ~(4194304 / nw - 1), f.snm4.value = 0, f.subsuper.value = "Supernetted", nw = 1) : (f.nwclass1.value = "C类网", nw = 256 / node, nwtemp = nw, f.snm1.value = 255, f.snm2.value = 255, f.snm3.value = 255, f.snm4.value = 255 & ~(256 / nw - 1), f.subsuper.value = "子网是", power2 += 22); 1 < nwtemp;) nwtemp /= 2, power2 += 1;
f.nodequant.value = node, f.nwquant.value = nw, f.snmbits.value = "/" + power2
}
f.snm1a.value = f.snm1.value, f.snm2a.value = f.snm2.value, f.snm3a.value = f.snm3.value, f.snm4a.value = f.snm4.value, f.oct1a.value = f.oct1.value, f.oct2a.value = f.oct2.value, f.oct3a.value = f.oct3.value, f.oct4a.value = f.oct4.value, f.oct1b.value = f.oct1.value, f.oct2b.value = f.oct2.value, f.oct3b.value = f.oct3.value, f.oct4b.value = f.oct4.value, compute(f), compute3(f), f.snm1c.value = f.snm1.value, f.snm2c.value = f.snm2.value, f.snm3c.value = f.snm3.value, f.snm4c.value = f.snm4.value, computeSNMA(f), f.snm1d.value = f.snm1.value, f.snm2d.value = f.snm2.value, f.snm3d.value = f.snm3.value, f.snm4d.value = f.snm4.value, computeINV1(f), (0 == f.nw1a.value && 0 == f.nw2a.value && 0 == f.nw3a.value && 0 == f.nw4a.value || 255 == f.broad1a.value && 255 == f.broad2a.value && 255 == f.broad3a.value && 255 == f.broad4a.value) && (f.nwclass.value = "Illegal", f.nwclass1.value = "", f.subsuper.value = "", f.nwquant.value = 0, f.nodequant.value = 0, f.snm1.value = 0, f.snm2.value = 0, f.snm3.value = 0, f.snm4.value = 0, f.snmbits.value = 0)
}
function compute(f) {
255 < f.oct1a.value && (f.oct1a.value = 255), 255 < f.oct2a.value && (f.oct2a.value = 255), 255 < f.oct3a.value && (f.oct3a.value = 255), 255 < f.oct4a.value && (f.oct4a.value = 255), 255 < f.snm1a.value && (f.snm1a.value = 255), 255 < f.snm2a.value && (f.snm2a.value = 255), 255 < f.snm3a.value && (f.snm3a.value = 255), 255 < f.snm4a.value && (f.snm4a.value = 255), f.nw1a.value = eval(f.snm1a.value & f.oct1a.value), f.nw2a.value = eval(f.snm2a.value & f.oct2a.value), f.nw3a.value = eval(f.snm3a.value & f.oct3a.value), f.nw4a.value = eval(f.snm4a.value & f.oct4a.value), f.node1a.value = eval(~f.snm1a.value & f.oct1a.value), f.node2a.value = eval(~f.snm2a.value & f.oct2a.value), f.node3a.value = eval(~f.snm3a.value & f.oct3a.value), f.node4a.value = eval(~f.snm4a.value & f.oct4a.value), f.broad1a.value = f.nw1a.value ^ 255 & ~f.snm1a.value, f.broad2a.value = f.nw2a.value ^ 255 & ~f.snm2a.value, f.broad3a.value = f.nw3a.value ^ 255 & ~f.snm3a.value, f.broad4a.value = f.nw4a.value ^ 255 & ~f.snm4a.value
}
function compute3(f) {
255 < f.oct1b.value && (f.oct1b.value = 255), 255 < f.oct2b.value && (f.oct2b.value = 255), 255 < f.oct3b.value && (f.oct3b.value = 255), 255 < f.oct4b.value && (f.oct4b.value = 255), f.bin1b.value = d2b(f.oct1b.value), f.bin2b.value = d2b(f.oct2b.value), f.bin3b.value = d2b(f.oct3b.value), f.bin4b.value = d2b(f.oct4b.value), f.hex1b.value = d2h(f.oct1b.value), f.hex2b.value = d2h(f.oct2b.value), f.hex3b.value = d2h(f.oct3b.value), f.hex4b.value = d2h(f.oct4b.value), f.dec1b.value = eval(16777216 * f.oct1b.value) + eval(65536 * f.oct2b.value) + eval(256 * f.oct3b.value) + eval(f.oct4b.value)
}
function compute4(f) {
f.oct1b.value = b2d(f.bin1b.value), f.oct2b.value = b2d(f.bin2b.value), f.oct3b.value = b2d(f.bin3b.value), f.oct4b.value = b2d(f.bin4b.value), f.hex1b.value = d2h(f.oct1b.value), f.hex2b.value = d2h(f.oct2b.value), f.hex3b.value = d2h(f.oct3b.value), f.hex4b.value = d2h(f.oct4b.value), f.dec1b.value = eval(16777216 * f.oct1b.value) + eval(65536 * f.oct2b.value) + eval(256 * f.oct3b.value) + eval(f.oct4b.value)
}
function compute5(f) {
f.oct1b.value = h2d(f.hex1b.value), f.oct2b.value = h2d(f.hex2b.value), f.oct3b.value = h2d(f.hex3b.value), f.oct4b.value = h2d(f.hex4b.value), f.bin1b.value = d2b(f.oct1b.value), f.bin2b.value = d2b(f.oct2b.value), f.bin3b.value = d2b(f.oct3b.value), f.bin4b.value = d2b(f.oct4b.value), f.dec1b.value = eval(16777216 * f.oct1b.value) + eval(65536 * f.oct2b.value) + eval(256 * f.oct3b.value) + eval(f.oct4b.value)
}
function compute6(a) {
a.oct1b.value = a.dec1b.value >>> 24, a.oct2b.value = a.dec1b.value << 8 >>> 24, a.oct3b.value = a.dec1b.value << 16 >>> 24, a.oct4b.value = a.dec1b.value << 24 >>> 24, a.bin1b.value = d2b(a.oct1b.value), a.bin2b.value = d2b(a.oct2b.value), a.bin3b.value = d2b(a.oct3b.value), a.bin4b.value = d2b(a.oct4b.value), a.hex1b.value = d2h(a.oct1b.value), a.hex2b.value = d2h(a.oct2b.value), a.hex3b.value = d2h(a.oct3b.value), a.hex4b.value = d2h(a.oct4b.value)
}
function computeSNMA(a) {
a.snm1c.value = snmcorrect(a.snm1c.value), a.snm1c.value < 255 ? (a.snm2c.value = 0, a.snm3c.value = 0, a.snm4c.value = 0) : (a.snm2c.value = snmcorrect(a.snm2c.value), a.snm2c.value < 255 ? (a.snm1c.value = 255, a.snm3c.value = 0, a.snm4c.value = 0) : (a.snm3c.value = snmcorrect(a.snm3c.value), a.snm3c.value < 255 ? (a.snm1c.value = 255, a.snm2c.value = 255, a.snm4c.value = 0) : a.snm4c.value = snmcorrect(a.snm4c.value))), bits = 0, bits += d2bits(a.snm1c.value), bits += d2bits(a.snm2c.value), bits += d2bits(a.snm3c.value), bits += d2bits(a.snm4c.value), a.snmbitsc.value = bits
}
function computeSNMB(a) {
a.snmbitsc.value < 0 && (a.snmbitsc.value = 0), 32 < a.snmbitsc.value && (a.snmbitsc.value = 32), a.snm1c.value = bits2d(a.snmbitsc.value), a.snm2c.value = bits2d(a.snmbitsc.value - 8), a.snm3c.value = bits2d(a.snmbitsc.value - 16), a.snm4c.value = bits2d(a.snmbitsc.value - 24)
}
function computeINV1(a) {
a.snm1e.value = 255 & ~a.snm1d.value, a.snm2e.value = 255 & ~a.snm2d.value, a.snm3e.value = 255 & ~a.snm3d.value, a.snm4e.value = 255 & ~a.snm4d.value
}
0 <= i && 0 == j && (code = "MSIE", version = parseFloat(navigator.userAgent.substring(i + 5, i + 9)), j = 1), i = navigator.userAgent.indexOf("Opera"), 0 <= i && 0 == j && (code = "Opera", version = parseFloat(navigator.userAgent.substring(i + 5, i + 11)), j = 1), i = navigator.userAgent.indexOf("Mozilla/"), 0 <= i && 0 == j && (code = "NS", version = parseFloat(navigator.userAgent.substring(i + 8, i + 12))), 0 <= navigator.userAgent.indexOf("Mac") && (platform = "Mac"), 0 <= navigator.userAgent.indexOf("OS/2") && (platform = "OS/2"), 0 <= navigator.userAgent.indexOf("X11") && (platform = "UNIX");
<template>
<input-block right="10px" bottom="40px">
<input-block right="10px" bottom="10px">
<code-editor :height="`${height}px`" :placeholder="`Csv ${$t('json_input')}`" v-model="options.input" language="text"/>
<template slot="extra">
<RadioGroup size="small" v-model="options.type" type="button" button-style="solid">
<Radio :label="item.k" v-for="item in types" :key="item.k">
<span>{{ item.n }}</span>
</Radio>
</RadioGroup>
</template>
</input-block>
<template slot="extra">
<Select size="small" v-model="options.keyed_key" v-if="options.type === 'keyed'" style="width: 150px">
<Option v-for="(key,k) in csvKeys" :key="k" :value="k">{{ key }}</Option>
</Select>
</template>
</input-block>
</template>
<script>
import jsonInstance from "../index";
import codeEditor from "../../../components/codeEditor";
import csvToJsonHandler from '../csvToJson';
export default {
props: {
value: {
type: Object,
default: function () {
return {}
}
},
height: {
type: Number,
default: 100
}
},
components: {
codeEditor
},
created() {
this.options = Object.assign(this.options, this.value)
},
computed: {
csvKeys() {
try {
let input = this.options.input.trim();
if (this.options.type === "keyed" && input) {
let json = csvToJsonHandler(this.options.input)
return Object.keys(json[0])
}
} catch {
//
}
return [];
}
},
watch: {
options: {
handler(val) {
let input = val.input.trim();
if (input) {
try {
const option = {
keyed_key: val.keyed_key,
type: val.type
}
// json变化事件
this.$emit('change', jsonInstance.csvToJson(input, option));
this.$emit('input', val);
// 保存数据
this.$emit('saveToolData');
} catch (e) {
this.$emit('change', this.$t('json_error', [e.message]).toString());
}
}
},
deep: true
}
},
data() {
return {
options: {
input: "",
type: "json",
keyed_key: 0
},
types: [
{k: "json", n: this.$t('json_json_type_json')},
{k: "keyed", n: this.$t('json_json_type_keyed')},
{k: "array", n: this.$t('json_json_type_array')},
{k: "column", n: this.$t('json_json_type_column')},
]
}
},
}
</script>
<template>
<div>
<div style="margin-bottom: 10px">
<Input v-model="options.path">
<span slot="prepend">JsonPath</span>
<Button slot="append" icon="md-help-circle" to="https://goessner.net/articles/JsonPath/" target="_blank"></Button>
</Input>
</div>
<div :style="`height:${height - 42}px`">
<code-editor :value="output" language="json"></code-editor>
</div>
</div>
</template>
<script>
import codeEditor from "../../../components/codeEditor";
import {JSONPath} from "jsonpath-plus";
import jsonInstance from "../../../library/json";
export default {
components: {
codeEditor
},
props: {
value: {
type: Object,
default: function () {
return {}
}
},
json: {
type: String,
default: ""
},
height: {
type: Number,
default: 100
}
},
created() {
this.options = Object.assign(this.options, this.value)
},
computed: {
output() {
try{
const json = this.json.trim();
if (!json || !this.options.path) {
return "";
}
const result = JSONPath({path: this.options.path, json:JSON.parse(json)});
this.$emit('input', this.options);
// 保存数据
this.$emit('saveToolData');
return jsonInstance.beautify(JSON.stringify(result));
}catch (e) {
return e.message
}
},
},
data() {
return {
options: {
path: ""
}
}
},
}
</script>
<template>
<input-block right="10px">
<code-editor :height="`${height}px`" :placeholder="`Csv ${$t('json_output')}`" :value="output"/>
<template slot="extra">
<Checkbox v-model="options.quoted">{{ $t('json_add_quote') }}</Checkbox>
<Checkbox v-model="options.header">{{ $t('json_column_name') }}</Checkbox>
</template>
</input-block>
</template>
<script>
import codeEditor from "../../../components/codeEditor";
import jsonInstance from "../index";
export default {
props: {
value: {
type: Object,
default: function () {
return {}
}
},
json: {
type: String,
default: ""
},
height: {
type: Number,
default: 100
}
},
created() {
this.options = Object.assign(this.options, this.value)
},
components: {
codeEditor,
},
computed: {
output() {
const json = this.json.trim();
if (!json) {
return "";
}
try {
let result = jsonInstance.jsonToCsv(JSON.parse(json), {quoted: this.options.quoted,header:this.options.header})
this.$emit('input', this.options);
// 保存数据
this.$emit('saveToolData');
return result;
} catch (error) {
return this.$t('json_error', [error.message]).toString()
}
}
},
data() {
return {
options: {
quoted: false,
header: true
}
}
},
}
</script>
<template>
<div>
<div v-if="options.type!=='Protobuf'">
<option-block disable-padding>
<Input v-model="options.packageName">
<div slot="prepend">namespace/package</div>
</Input>
</option-block>
<option-block>
<Input v-model="options.className">
<div slot="prepend">class/struct</div>
</Input>
</option-block>
</div>
<input-block top="10px" right="10px">
<input-block bottom="10px" right="10px">
<code-editor :height="`${height - this.topHeight}px`" :placeholder="`Object ${$t('json_output')}`" :value="output"
:language="languages[options.type]"/>
<template slot="extra">
<RadioGroup size="small" v-model="options.type" type="button" button-style="solid">
<Radio :label="type" v-for="(type) in types" :key="type">
<span>{{ type }}</span>
</Radio>
</RadioGroup>
</template>
</input-block>
<template slot="extra">
<Checkbox v-if="options.type==='Protobuf'" v-model="options.inline">{{ $t('json_inline') }}</Checkbox>
</template>
</input-block>
</div>
</template>
<script>
import codeEditor from "../../../components/codeEditor";
import json2Go from '../json2Go'
import json2CSharp from '../json2CSharp'
import json2Protobuf from '../json2Protobuf'
import json2Java from '../json2Java'
import json2php from '../json2php'
import json2Dart from '../json2Dart'
export default {
props: {
value: {
type: Object,
default: function () {
return {}
}
},
json: {
type: String,
default: ""
},
height: {
type: Number,
default: 100
}
},
created() {
this.options = Object.assign(this.options, this.value)
},
components: {
codeEditor,
},
computed: {
topHeight(){
return this.options.type === 'Protobuf' ? 0 : 84
},
output() {
const json = this.json.trim();
if (!json) {
return "";
}
try {
let result = "";
require('jsonlint').parse(json)
switch (this.options.type) {
case "Go":
result = json2Go(json, this.options.className, this.options.packageName).go
break
case "Java":
result = json2Java(JSON.parse(json), this.options.className, this.options.packageName)
break
case "Dart":
result = json2Dart(JSON.parse(json), this.options.className)
break
case "Protobuf":
result = json2Protobuf(json, this.options.inline)
break
case "C#":
result = json2CSharp.convert(JSON.parse(json), this.options.className, this.options.packageName)
break
case "PHP":
result = json2php(json, {
className:this.options.className,
namespace:this.options.packageName,
})
break
default:
throw new Error('language type error')
}
this.$emit('input', this.options);
// 保存数据
this.$emit('saveToolData');
return result;
} catch (error) {
return this.$t('json_error', [error.message]).toString()
}
},
types() {
return Object.keys(this.languages)
}
},
data() {
return {
options: {
type: "Java",
packageName: "pag",
className: "RootName",
inline: true,
},
languages: {
"Java": "java",
"Dart": "dart",
"C#": "csharp",
"Protobuf": "protobuf",
"Go": "go",
"PHP": "php"
},
}
},
}
</script>
<template>
<input-block right="10px">
<code-editor :height="`${height}px`" :placeholder="`Html Table ${$t('json_output')}`" :value="output" language="html"/>
<template slot="extra">
<Checkbox v-model="options.header">{{ $t('json_column_name') }}</Checkbox>
</template>
</input-block>
</template>
<script>
import codeEditor from "../../../components/codeEditor";
import jsonInstance from "../index";
export default {
props: {
value: {
type: Object,
default: function () {
return {}
}
},
json: {
type: String,
default: ""
},
height: {
type: Number,
default: 100
}
},
created() {
this.options = Object.assign(this.options, this.value)
},
components: {
codeEditor,
},
computed: {
output() {
const json = this.json.trim();
if (!json) {
return "";
}
try {
let result = jsonInstance.jsonToTable(JSON.parse(json), {header:this.options.header})
this.$emit('input', this.options);
// 保存数据
this.$emit('saveToolData');
return result;
} catch (error) {
return this.$t('json_error', [error.message]).toString()
}
}
},
data() {
return {
options: {
header: true
}
}
},
}
</script>
<template>
<input-block right="10px" bottom="40px">
<input-block right="10px" bottom="10px">
<code-editor :height="`${height}px`" :placeholder="`Html Table ${$t('json_input')}`" v-model="options.input" language="html"/>
<template slot="extra">
<RadioGroup size="small" v-model="options.type" type="button" button-style="solid">
<Radio :label="item.k" v-for="item in types" :key="item.k">
<span>{{ item.n }}</span>
</Radio>
</RadioGroup>
</template>
</input-block>
<template slot="extra">
<Select size="small" v-model="options.keyed_key" v-if="options.type === 'keyed'" style="width: 150px">
<Option v-for="(key,k) in tableKeys" :key="k" :value="k">{{ key }}</Option>
</Select>
</template>
</input-block>
</template>
<script>
import jsonInstance from "../index";
import codeEditor from "../../../components/codeEditor";
import {tableKeys} from '../tableToJson';
export default {
props: {
value: {
type: Object,
default: function () {
return {}
}
},
height: {
type: Number,
default: 100
}
},
components: {
codeEditor
},
created() {
this.options = Object.assign(this.options, this.value)
},
computed: {
tableKeys() {
try {
let input = this.options.input.trim();
if (this.options.type === "keyed" && input) {
return tableKeys(this.options.input)
}
} catch {
//
}
return [];
}
},
watch: {
options: {
handler(val) {
let input = val.input.trim();
if (input) {
try {
const option = {
keyed_key: val.keyed_key,
type: val.type
}
// json变化事件
this.$emit('change', jsonInstance.tableToJson(input, option));
this.$emit('input', val);
// 保存数据
this.$emit('saveToolData');
} catch (e) {
console.log(e)
this.$emit('change', this.$t('json_error', [e.message]).toString());
}
}
},
deep: true
}
},
data() {
return {
options: {
input: "",
type: "json",
keyed_key: 0
},
types: [
{k: "json", n: this.$t('json_json_type_json')},
{k: "keyed", n: this.$t('json_json_type_keyed')},
{k: "array", n: this.$t('json_json_type_array')},
{k: "column", n: this.$t('json_json_type_column')},
]
}
},
}
</script>
import {parse} from 'csv-parse/sync';
import {jsonOutputFormat} from './helper';
const convert = (csv = "", {type = "json",keyed_key=0} = {}) => {
return jsonOutputFormat(
parse(csv, {columns: true, skip_empty_lines: true}),
type,
keyed_key
)
}
export default convert
export const createTempElement = (innerHTML = "", type = "div", id = "") => {
const el = document.createElement(type);
el.id = id ? id : `ctool-temp-${Math.ceil(Math.random() * 99999)}`
el.style.cssText = "display:none;"
document.body.appendChild(el);
// 移除script标签
el.innerHTML = innerHTML.replace(/<script/gmi, "<xxxxx")
return el;
}
export const jsonOutputFormat = (json, type = "json", keyed_key = 0) => {
if (type === "keyed") {
const keys = Object.keys(json[0])
let result = {}
for (let item of json) {
let item_key = keys[keyed_key]
result[item[item_key]] = item
}
return result
}
if (type === "array") {
let result = json.map((item) => {
return Object.values(item)
})
if (result.length > 0) {
result = [
Object.keys(json[0]),
...result
]
}
return result
}
if (type === "column") {
const keys = Object.keys(json[0])
let result = {}
for (let key of keys) {
result[key] = json.map((item) => {
return item[key]
})
}
return result
}
return json
}
import Unicode from "../unicode";
import formatter from "../formatter/json";
import csvToJson from './csvToJson';
import tableToJson from './tableToJson';
import jsonToTable from './jsonToTable';
import {stringify} from 'csv-stringify/sync';
import {parse as qsParse, stringify as qsStringify} from "qs";
// 校验语法
export const check = (content) => {
require('jsonlint').parse(content)
return content;
}
// 美化
export const beautify = (content) => {
return formatter.beautify(check(content))
}
// 压缩
export const compress = (content) => {
return formatter.compress(content)
}
// unicode2zh
export const unicode2zh = (content) => {
return Unicode.decode(
content.replace(/\\U[0-9a-fA-F]{4}/g, (item) => {
// \Uxxxx=>\uxxxx
return item.replace("\\U", "\\u");
})
)
}
// zh2unicode
export const zh2unicode = (content) => {
if (content) {
let newStr = ''
for (let i = 0; i < content.length; i++) {
let str = content.charAt(i)
newStr += /[\u4e00-\u9fa5]/.test(str) ? '\\u' + str.charCodeAt(0).toString(16) : str
}
return newStr
}
return content
}
// 转义
export const escape = (content) => {
return content.trim().replace(/\\/g, '\\\\').replace(/"/g, '\\"')
}
// 去转义
export const clearEscape = (content) => {
return content.trim().replace(/\\\\/g, '\\').replace(/\\"/g, '"')
}
// 转get参数
export const toGet = (content) => {
check(content)
return qsStringify(JSON.parse(content), {encodeValuesOnly: true})
}
// get转json
export const fromGet = (content) => {
return beautify(JSON.stringify(qsParse(content.trim())))
}
export default {
check,
beautify,
compress,
unicode2zh,
zh2unicode,
escape,
clearEscape,
toGet,
fromGet,
csvToJson: (csv = "", option = {}) => {
return beautify(JSON.stringify(csvToJson(csv, option)))
},
jsonToCsv: (json = [], {quoted = false, header = true} = {}) => {
return stringify(json, {quoted, header})
},
tableToJson: (table = "", option = {}) => {
return beautify(JSON.stringify(tableToJson(table, option)))
},
jsonToTable: (json = [], option = {}) => {
return jsonToTable(json, option)
},
}
export default {
_allClass: [],
format(string, ...replace) {
return string.replace(/\{(\d+)\}/g,
(m, i) => replace[i]
);
},
_genClassCode(obj, name, pag) {
let clas = "// ========= " + name + `.cs file ========= \nnamespace ${pag}\n{\n`;
clas += ` public class ${name}\n {\n`;
for (let n in obj) {
let v = obj[n];
n = n.trim();
clas += ` ${this._genComment(v)} public ${this._genTypeByProp(n, v, pag)} ${n} { get; set; }\n`;
}
clas += " }\n";
clas += "}\n";
this._allClass.push(clas);
return this._allClass.join("\n");
},
_genTypeByProp(name, val, pag) {
switch (Object.prototype.toString.apply(val)) {
case "[object Number]": {
return val.toString().includes(".") ? "double" : "int";
}
case "[object Date]": {
return "DateTime";
}
case "[object Object]": {
name = name.substring(0, 1).toUpperCase() + name.substring(1);
this._genClassCode(val, name, pag);
return name;
}
case "[object Array]": {
return `List <${this._genTypeByProp(name + "Item", val[0], pag)}>`;
}
default: {
return "string";
}
}
},
_genComment(val) {
let commm = typeof (val) == "string" && /.*[\u4e00-\u9fa5]+.*$/.test(val) ? val : "";
return "/// <summary>\n /// " + commm + "\n /// </summary>\n";
},
convert(jsonObj, cls, pag) {
this._allClass = [];
return this._genClassCode(jsonObj, cls, pag);
}
}
// 算法来源 https://github.com/zx1262111739/JsonToDart/blob/main/index.js
let keywrods = "abstract,dynamic,implements,show,as,else,import,static,assert,enum,in,super,async,export,interface,switch,await,extends,is,sync,break,external,library,this,case,factory,mixin,throw,catch,false,new,true,class,final,null,try,const,finally,on,typedef,continue,for,operator,var,covariant,Function,part,void,default,get,rethrow,while,deferred,hide,return,with,do,if,set,yield,List";
let keywrodList = keywrods.split(",");
const caption = (s) => s[0].toUpperCase() + s.substring(1);
// 生成属性名
const generatePropertyName = (name) => {
let nameParts = name.split("_");
let output = nameParts[0];
for (let index = 1; index < nameParts.length; index++) {
output += caption(nameParts[index])
}
if (keywrodList.includes(output)) {
output = "m" + caption(output);
}
return output;
}
// 生成类名
const generateClassName = (name) => {
return name.split("_").map(caption).join("");
}
const convertObjectToClass = (className, obj) => {
let propers = [];
let subClass = [];
for (let key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}
let propertyType = "";
let isArray = false;
let isSubclass = false;
switch (typeof obj[key]) {
case "number":
propertyType = "double";
break;
case "string":
propertyType = "String";
break;
case "boolean":
propertyType = "bool";
break;
case "object":
if (Array.isArray(obj[key])) {
isArray = true;
if (obj[key].length > 0) {
let subObj = obj[key][0];
switch (typeof subObj) {
case "number":
propertyType = "double";
break;
case "string":
propertyType = "String";
break;
case "boolean":
propertyType = "bool";
break;
case "object":
if (Array.isArray(subObj)) {
propertyType = "dynamic";
} else {
isSubclass = true;
propertyType = className + generateClassName(key);
subClass.push(convertObjectToClass(propertyType, subObj));
}
break;
}
} else {
propertyType = "dynamic";
}
} else {
isSubclass = true;
propertyType = className + generateClassName(key);
subClass.push(convertObjectToClass(propertyType, obj[key]));
}
break;
default:
break;
}
if (propertyType !== "") {
propers.push({
key,
"propertyName": generatePropertyName(key),
propertyType,
isSubclass,
isArray,
});
}
}
let output = `class ${className} {\n\n`;
// -- 生成属性
for (let idx in propers) {
let prop = propers[idx];
if (prop.isArray) {
output += ` List<${prop.propertyType}> ${prop.propertyName} = List<${prop.propertyType}>();\n\n`;
} else {
switch (prop.propertyType) {
case "double":
output += ` ${prop.propertyType} ${prop.propertyName} = 0;\n\n`;
break;
case "String":
output += ` ${prop.propertyType} ${prop.propertyName} = "";\n\n`;
break;
case "bool":
output += ` ${prop.propertyType} ${prop.propertyName} = false;\n\n`;
break;
default:
output += ` ${prop.propertyType} ${prop.propertyName} = ${prop.propertyType}();\n\n`;
break;
}
}
}
// -- 生成默认构造方法
output += ` ${className}();\n\n`
// -- 生成FromJson方法
output += ` ${className}.fromJson(Map<String, dynamic> json) {\n\n`;
for (let idx in propers) {
let prop = propers[idx];
// -- 类型检测
if (prop.isArray) {
output += ` if (json["${prop.key}"] != null && json["${prop.key}"] is List) {\n`
} else if (prop.isSubclass) {
output += ` if (json["${prop.key}"] != null && json["${prop.key}"] is Map) {\n`
} else if (prop.propertyType == "double") {
output += ` if (json["${prop.key}"] != null && (json["${prop.key}"] is int || json["${prop.key}"] is double)) {\n`
} else {
output += ` if (json["${prop.key}"] != null && json["${prop.key}"] is ${prop.propertyType}) {\n`
}
if (prop.isArray) {
if (prop.isSubclass) {
output += ` final objs = List<${prop.propertyType}>();\n`;
output += ` for (var item in json["${prop.key}"]) {\n`;
output += ` objs.add(${prop.propertyType}.fromJson(item));\n`;
output += ` }\n`;
output += ` this.${prop.propertyName} = objs;\n`
} else {
output += ` final objs = List<${prop.propertyType}>();\n`;
output += ` for (var item in json["${prop.key}"]) {\n`;
output += ` objs.add(item);\n`;
output += ` }\n`;
output += ` this.${prop.propertyName} = objs;\n`
}
} else if (prop.isSubclass) {
output += ` this.${prop.propertyName} = ${prop.propertyType}.fromJson(json["${prop.key}"]);\n`;
} else if (prop.propertyType == "double") {
output += ` this.${prop.propertyName} = json["${prop.key}"].toDouble();\n`
} else {
output += ` this.${prop.propertyName} = json["${prop.key}"];\n`
}
output += ` }\n`
}
output += ` }\n\n`
// -- 生成ToJson方法
output += ` Map<String, dynamic> toJson() {\n`;
output += ` final map = Map<String, dynamic>();\n`
for (let idx in propers) {
let prop = propers[idx];
output += ` if (this.${prop.propertyName} != null) {\n`
if (prop.isArray && prop.isSubclass) {
output += ` map["${prop.key}"] = this.${prop.propertyName}.map((e) => e.toJson()).toList();\n`;
} else if (prop.isSubclass) {
output += ` map["${prop.key}"] = this.${prop.propertyName}.toJson();\n`
} else {
output += ` map["${prop.key}"] = this.${prop.propertyName};\n`
}
output += ` }\n`
}
output += ` return map;\n`
output += " }\n\n";
output += "}\n\n"
for (let idx in subClass) {
output += subClass[idx];
}
return output;
}
export default (json, typename) => convertObjectToClass(typename, json)
/*
JSON-to-Go
by Matt Holt
https://github.com/mholt/json-to-go
A simple utility to translate JSON into a Go type definition.
*/
export default function (json, typename, pag, flatten = true) {
let data;
let scope;
let go = "";
let tabs = 0;
const seen = {};
const stack = [];
let accumulator = "";
let innerTabs = 0;
let parent = "";
try {
data = JSON.parse(json.replace(/:(\s*\d*)\.0/g, ":$1.1")); // hack that forces floats to stay as floats
scope = data;
} catch (e) {
return {
go: "",
error: e.message
};
}
typename = format(typename || "AutoGenerated");
append(`package ${pag}\n\n`);
append(`type ${typename} `);
parseScope(scope);
return {
go: flatten
? go += accumulator
: go
};
function parseScope(scope, depth = 0) {
if (typeof scope === "object" && scope !== null) {
if (Array.isArray(scope)) {
let sliceType;
const scopeLength = scope.length;
for (let i = 0; i < scopeLength; i++) {
const thisType = goType(scope[i]);
if (!sliceType)
sliceType = thisType;
else if (sliceType !== thisType) {
sliceType = mostSpecificPossibleGoType(thisType, sliceType);
if (sliceType === "interface{}")
break;
}
}
const slice = flatten && ["struct", "slice"].includes(sliceType)
? `[]${parent}`
: `[]`;
if (flatten && depth >= 2)
appender(slice);
else
append(slice)
if (sliceType === "struct") {
const allFields = {};
// for each field counts how many times appears
for (let i = 0; i < scopeLength; i++) {
const keys = Object.keys(scope[i])
for (let k in keys) {
let keyname = keys[k];
if (!(keyname in allFields)) {
allFields[keyname] = {
value: scope[i][keyname],
count: 0
}
} else {
const existingValue = allFields[keyname].value;
const currentValue = scope[i][keyname];
if (compareObjects(existingValue, currentValue)) {
const comparisonResult = compareObjectKeys(
Object.keys(currentValue),
Object.keys(existingValue)
)
if (!comparisonResult) {
keyname = `${keyname}_${uuidv4()}`;
allFields[keyname] = {
value: currentValue,
count: 0
};
}
}
}
allFields[keyname].count++;
}
}
// create a common struct with all fields found in the current array
// omitempty dict indicates if a field is optional
const keys = Object.keys(allFields), struct = {}, omitempty = {};
for (let k in keys) {
const keyname = keys[k], elem = allFields[keyname];
struct[keyname] = elem.value;
omitempty[keyname] = elem.count !== scopeLength;
}
parseStruct(depth + 1, innerTabs, struct, omitempty); // finally parse the struct !!
} else if (sliceType === "slice") {
parseScope(scope[0], depth)
} else {
if (flatten && depth >= 2) {
appender(sliceType || "interface{}");
} else {
append(sliceType || "interface{}");
}
}
} else {
if (flatten) {
if (depth >= 2) {
appender(parent)
} else {
append(parent)
}
}
parseStruct(depth + 1, innerTabs, scope);
}
} else {
if (flatten && depth >= 2) {
appender(goType(scope));
} else {
append(goType(scope));
}
}
}
function parseStruct(depth, innerTabs, scope, omitempty) {
if (flatten) {
stack.push(
depth >= 2
? "\n"
: ""
)
}
if (flatten && depth >= 2) {
const parentType = `type ${parent}`;
const scopeKeys = formatScopeKeys(Object.keys(scope));
// this can only handle two duplicate items
// future improvement will handle the case where there could
// three or more duplicate keys with different values
if (parent in seen && compareObjectKeys(scopeKeys, seen[parent])) {
stack.pop();
return
}
seen[parent] = scopeKeys;
appender(`${parentType} struct {\n`);
++innerTabs;
const keys = Object.keys(scope);
for (let i in keys) {
const keyname = getOriginalName(keys[i]);
indenter(innerTabs)
const typename = format(keyname)
appender(typename + " ");
parent = typename
parseScope(scope[keys[i]], depth);
appender(' `json:"' + keyname);
if (omitempty && omitempty[keys[i]] === true) {
appender(',omitempty');
}
appender('"`\n');
}
indenter(--innerTabs);
appender("}");
} else {
append("struct {\n");
++tabs;
const keys = Object.keys(scope);
for (let i in keys) {
const keyname = getOriginalName(keys[i]);
indent(tabs);
const typename = format(keyname);
append(typename + " ");
parent = typename
parseScope(scope[keys[i]], depth);
append(' `json:"' + keyname);
if (omitempty && omitempty[keys[i]] === true) {
append(',omitempty');
}
append('"`\n');
}
indent(--tabs);
append("}");
}
if (flatten)
accumulator += stack.pop();
}
function indent(tabs) {
for (let i = 0; i < tabs; i++)
go += '\t';
}
function append(str) {
go += str;
}
function indenter(tabs) {
for (let i = 0; i < tabs; i++)
stack[stack.length - 1] += '\t';
}
function appender(str) {
stack[stack.length - 1] += str;
}
// Sanitizes and formats a string to make an appropriate identifier in Go
function format(str) {
if (!str)
return "";
else if (str.match(/^\d+$/))
str = "Num" + str;
else if (str.charAt(0).match(/\d/)) {
const numbers = {
'0': "Zero_", '1': "One_", '2': "Two_", '3': "Three_",
'4': "Four_", '5': "Five_", '6': "Six_", '7': "Seven_",
'8': "Eight_", '9': "Nine_"
};
str = numbers[str.charAt(0)] + str.substr(1);
}
return toProperCase(str).replace(/[^a-z0-9]/ig, "") || "NAMING_FAILED";
}
// Determines the most appropriate Go type
function goType(val) {
if (val === null)
return "interface{}";
switch (typeof val) {
case "string":
if (/\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(\+\d\d:\d\d|Z)/.test(val))
return "time.Time";
else
return "string";
case "number":
if (val % 1 === 0) {
if (val > -2147483648 && val < 2147483647)
return "int";
else
return "int64";
} else
return "float64";
case "boolean":
return "bool";
case "object":
if (Array.isArray(val))
return "slice";
return "struct";
default:
return "interface{}";
}
}
// Given two types, returns the more specific of the two
function mostSpecificPossibleGoType(typ1, typ2) {
if (typ1.substr(0, 5) === "float"
&& typ2.substr(0, 3) === "int")
return typ1;
else if (typ1.substr(0, 3) === "int"
&& typ2.substr(0, 5) === "float")
return typ2;
else
return "interface{}";
}
// Proper cases a string according to Go conventions
function toProperCase(str) {
// https://github.com/golang/lint/blob/5614ed5bae6fb75893070bdc0996a68765fdd275/lint.go#L771-L810
const commonInitialisms = [
"ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP",
"HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA",
"SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "UID", "UUID",
"URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS"
];
return str.replace(/(^|[^a-zA-Z])([a-z]+)/g, function (unused, sep, frag) {
if (commonInitialisms.indexOf(frag.toUpperCase()) >= 0)
return sep + frag.toUpperCase();
else
return sep + frag[0].toUpperCase() + frag.substr(1).toLowerCase();
}).replace(/([A-Z])([a-z]+)/g, function (unused, sep, frag) {
if (commonInitialisms.indexOf(sep + frag.toUpperCase()) >= 0)
return (sep + frag).toUpperCase();
else
return sep + frag;
});
}
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function getOriginalName(unique) {
const reLiteralUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
const uuidLength = 36;
if (unique.length >= uuidLength) {
const tail = unique.substr(-uuidLength);
if (reLiteralUUID.test(tail)) {
return unique.slice(0, -1 * (uuidLength + 1))
}
}
return unique
}
function compareObjects(objectA, objectB) {
const object = "[object Object]";
return Object.prototype.toString.call(objectA) === object
&& Object.prototype.toString.call(objectB) === object;
}
function compareObjectKeys(itemAKeys, itemBKeys) {
const lengthA = itemAKeys.length;
const lengthB = itemBKeys.length;
// nothing to compare, probably identical
if (lengthA === 0 && lengthB === 0)
return true;
// duh
if (lengthA !== lengthB)
return false;
for (let item of itemAKeys) {
if (!itemBKeys.includes(item))
return false;
}
return true;
}
function formatScopeKeys(keys) {
for (let i in keys) {
keys[i] = format(keys[i]);
}
return keys
}
}
\ No newline at end of file
const IMPORT_MAP = {'Date': 'java.util.Date', 'List': 'java.util.List'}
let attrClassAry = [];
import {camelCase} from "camel-case"
function firstToUpperCase(str) {
return str.substr(0, 1).toUpperCase() + str.substr(1);
}
function camelCaseWithFirstCharUpper(input) {
if (!input) {
return ""
}
input = camelCase(input);
return input[0].toUpperCase() + input.substr(1);
}
function isDate(date) {
return new Date(date) !== "Invalid Date" && !isNaN(new Date(date)) && isNaN(+date);
}
function isInt(n) {
return n % 1 === 0;
}
function toBeanText(bean, packageName) {
let beanFields = bean.val;
let className = bean.name;
let importText = "";
let fieldText = "";
let setterText = "";
let typeSet = {};
let shoudImportJackson = false;
let tpl = " public void setA(T a) {\n \
this.a = a;\n \
}\n \
public T getA() {\n \
return a;\n \
}\n";
for (let key in beanFields) {
let camelKey = camelCase(key);
if (camelKey !== key) {
fieldText += ' @JsonProperty("' + key + '")\n';
shoudImportJackson = true;
}
fieldText += " private " + beanFields[key] + " " + camelKey + ";\n";
let type = beanFields[key];
if (type.indexOf("List<") > -1) {
type = beanFields[key].replace('List<', "");
type = type.replace('>', "");
typeSet["List"] = 'true';
}
typeSet[type] = 'true';
let tplMap = {a: camelKey, A: firstToUpperCase(camelKey), T: beanFields[key]};
setterText += tpl.replace(/a|A|T/g, function (matched) {
return tplMap[matched];
});
}
for (let t in typeSet) {
if (IMPORT_MAP[t]) {
importText += "import " + IMPORT_MAP[t] + ";\n";
}
}
if (shoudImportJackson) {
importText += "import org.codehaus.jackson.annotate.JsonIgnoreProperties;\nimport org.codehaus.jackson.annotate.JsonProperty;\n"
}
if (packageName) {
importText = "package " + packageName + ";\n" + importText;
}
return "/*=============="+className+".java file============*/\n"+importText + "\n" + "public class " + className + " {\n" + fieldText + setterText + "}\n\n";
}
function getBeanFieldFromJson(json, className) {
let jsonObject;
let text = JSON.stringify(json);
if (text[0] === "[" && text[text.length - 1] === "]") {
text = '{ "list": ' + text + '}';
jsonObject = JSON.parse(text).list[0];
} else {
jsonObject = JSON.parse(text);
}
let bean = {};
attrClassAry = []
for (let key in jsonObject) {
const val = jsonObject[key];
bean[key] = getTypeFromJsonVal(val, key, attrClassAry);
}
if (!className) {
className = "AtoolBean";
}
bean = {name: className, val: bean};
return [bean, ...attrClassAry];
}
function getTypeFromJsonVal(val, key, attrClassAry) {
if (val && val.replace) {
val = val.replace(/ /g, "");
}
let typeofStr = typeof (val);
if (typeofStr === 'number') {
if (isInt(val)) {
return "int";
} else {
return "double";
}
} else if (typeofStr === 'boolean') {
return typeofStr;
} else if (isDate(val)) {
return "Date";
} else if (!val) {
return "String";
} else if (typeofStr === 'string') {
return "String";
} else {
if (Array.isArray(val)) {
let type = getTypeFromJsonVal(val[0], key, attrClassAry);
return "List<" + type + ">";
} else {
let typeName = camelCaseWithFirstCharUpper(key);
let bean = {};
for (key in val) {
let fieldValue = val[key];
bean[key] = getTypeFromJsonVal(fieldValue, key, attrClassAry);
}
attrClassAry.push({name: typeName, val: bean});
return typeName;
}
}
}
export default (json, cls = "JsonRootBean", pag = "pag.json2bean") => {
let beans = [];
let temp = getBeanFieldFromJson(json, cls);
for (let key in temp) {
beans.push(toBeanText(temp[key], pag));
}
return beans.join("\n");
}
// https://github.com/json-to-proto/json-to-proto.github.io/blob/master/src/convert.ts
const defaultImport = "google/protobuf/any.proto";
const defaultAny = "google.protobuf.Any";
class Result {
constructor(success, error) {
this.success = success;
this.error = error;
}
}
class ProtoPrimitiveType {
constructor(name, complex, merge) {
this.name = name;
this.complex = complex;
this.merge = merge;
}
}
const boolProtoPrimitiveType = new ProtoPrimitiveType("bool", false, false);
const stringProtoPrimitiveType = new ProtoPrimitiveType("string", false, false);
const int64ProtoPrimitiveType = new ProtoPrimitiveType("int64", false, true);
const complexProtoType = new ProtoPrimitiveType(defaultAny, true, false);
class Collector {
constructor() {
this.imports = new Set();
this.messages = [];
this.messageNameSuffixCounter = {};
}
addImport(importPath) {
this.imports.add(importPath);
}
generateUniqueName(source) {
if (this.messageNameSuffixCounter.hasOwnProperty(source)) {
const suffix = this.messageNameSuffixCounter[source];
this.messageNameSuffixCounter[source] = suffix + 1;
return `${source}${suffix}`;
}
this.messageNameSuffixCounter[source] = 1;
return source;
}
addMessage(lines) {
this.messages.push(lines);
}
getImports() {
return this.imports;
}
getMessages() {
return this.messages;
}
}
function addShift(inline) {
if (inline) {
return ` `;
}
return "";
}
function analyze(json, options) {
if (directType(json)) {
return analyzeObject({"first": json}, options);
}
if (Array.isArray(json)) {
return analyzeArray(json, options);
}
return analyzeObject(json, options);
}
function analyzeArray(array, options) {
const inlineShift = addShift(options.inline);
const collector = new Collector();
const lines = [];
const typeName = analyzeArrayProperty("nested", array, collector, inlineShift);
lines.push(` ${typeName} items = 1;`);
return render(collector.getImports(), collector.getMessages(), lines, options);
}
function analyzeObject(json, options) {
const inlineShift = addShift(options.inline);
const collector = new Collector();
const lines = [];
let index = 1;
for (const [key, value] of Object.entries(json)) {
const typeName = analyzeProperty(key, value, collector, inlineShift);
lines.push(` ${typeName} ${key} = ${index};`);
index += 1;
}
return render(collector.getImports(), collector.getMessages(), lines, options);
}
function analyzeArrayProperty(key, value, collector, inlineShift) {
// [] -> any
const length = value.length;
if (length === 0) {
collector.addImport(defaultImport);
return `repeated ${defaultAny}`;
}
// [[...], ...] -> any
const first = value[0];
if (Array.isArray(first)) {
collector.addImport(defaultImport);
return `repeated ${defaultAny}`;
}
if (length > 1) {
const primitive = samePrimitiveType(value);
if (primitive.complex === false) {
return `repeated ${primitive.name}`;
}
}
return `repeated ${analyzeObjectProperty(key, first, collector, inlineShift)}`;
}
function analyzeProperty(key, value, collector, inlineShift) {
if (Array.isArray(value)) {
return analyzeArrayProperty(key, value, collector, inlineShift);
}
return analyzeObjectProperty(key, value, collector, inlineShift);
}
function analyzeObjectProperty(key, value, collector, inlineShift) {
const typeName = analyzeType(value, collector);
if (typeName === "object") {
const messageName = collector.generateUniqueName(toMessageName(key));
addNested(collector, messageName, value, inlineShift);
return messageName;
}
return typeName;
}
function addNested(collector, messageName, source, inlineShift) {
const lines = [];
lines.push(`${inlineShift}message ${messageName} {`);
let index = 1;
for (const [key, value] of Object.entries(source)) {
const typeName = analyzeProperty(key, value, collector, inlineShift);
lines.push(`${inlineShift} ${typeName} ${key} = ${index};`);
index += 1;
}
lines.push(`${inlineShift}}`);
collector.addMessage(lines);
}
function toMessageName(source) {
return source.charAt(0).toUpperCase() + source.substr(1).toLowerCase();
}
function render(imports, messages, lines, options) {
const result = [];
result.push(`syntax = "proto3";`);
if (imports.size > 0) {
result.push("");
for (const importName of imports) {
result.push(`import "${importName}";`);
}
}
result.push("");
if (options.inline) {
result.push("message SomeMessage {");
if (messages.length > 0) {
result.push("");
for (const message of messages) {
result.push(...message);
result.push("");
}
}
result.push(...lines);
result.push("}");
} else {
for (const message of messages) {
result.push(...message);
result.push("");
}
result.push("message SomeMessage {");
result.push(...lines);
result.push("}");
}
return result.join("\n");
}
function directType(value) {
switch (typeof value) {
case "string":
case "number":
case "boolean":
return true;
case "object":
return value === null;
}
return false;
}
function samePrimitiveType(array) {
let current = toPrimitiveType(array[0]);
if (current.complex) {
return current;
}
for (let i = 1; i < array.length; i++) {
const next = toPrimitiveType(array[i]);
if (next.complex) {
return next;
}
current = mergePrimitiveType(current, next);
if (current.complex) {
return current;
}
}
return current;
}
function mergePrimitiveType(a, b) {
if (a.name === b.name) {
return a;
}
if (a.merge && b.merge) {
if (a.name === "double") {
return a;
}
if (b.name === "double") {
return b;
}
if (a.name === "int64") {
return a;
}
if (b.name === "int64") {
return b;
}
if (a.name === "uint64") {
if (b.name === "uint32") {
return a;
}
} else if (b.name === "uint64") {
if (a.name === "uint32") {
return b;
}
}
return int64ProtoPrimitiveType;
}
return complexProtoType;
}
function toPrimitiveType(value) {
switch (typeof value) {
case "string":
return stringProtoPrimitiveType;
case "number":
return new ProtoPrimitiveType(numberType(value), false, true);
case "boolean":
return boolProtoPrimitiveType;
}
return complexProtoType;
}
function analyzeType(value, collector) {
switch (typeof value) {
case "string":
return "string";
case "number":
return numberType(value);
case "boolean":
return "bool";
case "object":
if (value === null) {
collector.addImport(defaultImport);
return defaultAny;
}
return "object";
}
collector.addImport(defaultImport);
return defaultAny;
}
function numberType(value) {
if (value % 1 === 0) {
if (value < 0) {
if (value < -2147483648) {
return "int64";
}
return "int32";
}
if (value > 4294967295) {
return "uint64";
}
return "uint32";
}
return "double";
}
export default (source, inline = true) => {
// hack that forces floats to stay as floats
return analyze(JSON.parse( source.replace(/\.0/g, ".1")), {inline})
}
import {buildConstructor} from "./constructor";
import {buildGetters, buildSetters} from "./getterSetter";
import {buildProperties, getPropertyInfo} from "./property";
import {isScalarType} from "./types";
import {indent} from "./utils";
function getClassInfo(json, className, config, deps) {
const keys = Object.keys(json);
const properties = keys.map((key) => {
let info = getPropertyInfo(key, json[key]);
if (
isScalarType(info.type) ||
isScalarType(info.subtype) ||
info.subtype === null
)
return info;
let depName = info.type === "array" ? info.subtype : info.type;
if (!deps.has(depName)) {
deps.add({
className: depName,
key: key,
value: info.type === "array" ? json[key][0] : json[key],
});
}
return info;
});
return {
className: className,
properties: properties,
};
}
function buildArraySerialization(properties, config, className) {
if (!(config.arraySerialization || config.includeDeps)) {
return "";
}
return (
buildFromArray(properties, config, className) +
buildToArray(properties, config) +
buildToJson(properties, config)
);
}
function buildFromArray(properties, {typedMethods}, className) {
let result = "\n\n";
let declaration = `public static function fromArray(`;
declaration += typedMethods ? "array $data" : "$data";
declaration += !typedMethods ? ")" : "):" + className;
result += indent(declaration + "\n", 1);
result += indent("{\n", 1);
result += indent(`return new ${className}(\n`, 2);
const propertiesCount = properties.length;
properties.forEach((property, i) => {
let content = "";
let isLast = i >= propertiesCount - 1;
if (isScalarType(property.type) || isScalarType(property.subtype)) {
content = `$data["${property.originalName}"]${isLast ? "" : ","}`;
result += indent(content + "\n", 3);
return;
}
if (property.type === "array" && !isScalarType(property.subtype)) {
content += indent("array_map(function($item){\n", 3);
content += indent(`return ${property.subtype}::fromArray($item);\n`, 4);
content += indent(
`},$data["${property.originalName}"])${isLast ? "" : ","}`,
3
);
result += content + "\n";
return;
}
content = `${property.subtype}::fromArray($data["${
property.originalName
}"])${isLast ? "" : ","}`;
result += indent(content + "\n", 3);
});
result += indent(");\n", 2);
result += indent("}\n", 1);
return result;
}
function buildToArray(properties, {typedMethods}) {
let result = "\n";
let declaration = `public function toArray(`;
declaration += !typedMethods ? ")" : "):array";
result += indent(declaration + "\n", 1);
result += indent("{\n", 1);
result += indent(`return [\n`, 2);
const propertiesCount = properties.length;
properties.forEach((property, i) => {
let content = "";
let isLast = i >= propertiesCount - 1;
if (isScalarType(property.type) || isScalarType(property.subtype)) {
content = `"${property.originalName}"=>$this->${property.name}${
isLast ? "" : ","
}`;
result += indent(content + "\n", 3);
return;
}
if (property.type === "array") {
content += indent(
`"${property.originalName}"=>array_map(function($item){\n`,
3
);
content += indent(`return $item->toArray();\n`, 4);
content += indent(`},$this->${property.name})${isLast ? "" : ","}`, 3);
result += content + "\n";
return;
}
content = `"${property.originalName}"=>$this->${property.name}->toArray()${
isLast ? "" : ","
}`;
result += indent(content + "\n", 3);
});
result += indent("];\n", 2);
result += indent("}\n", 1);
return result;
}
function buildToJson(properties, {typedMethods}) {
let result = "\n";
let declaration = `public function toJson(`;
declaration += !typedMethods ? ")" : "):string";
result += indent(declaration + "\n", 1);
result += indent("{\n", 1);
result += indent(`return json_encode($this->toArray(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)\n`, 2);
result += indent("}", 1);
return result;
}
export default (config, deps, json, guessedName = null) => {
const {className, properties} = getClassInfo(
json,
guessedName,
config,
deps
);
let classContent =
buildProperties(properties, config) +
buildConstructor(properties, config) +
buildGetters(properties, config) +
buildSetters(properties, config) +
buildArraySerialization(properties, config, className);
return `class ${className}\n{\n${classContent}\n}\n`;
}
import {indent} from "./utils";
function buildParameters(properties, {typedMethods}) {
let result = "";
const propertiesCount = properties.length;
properties.forEach((property, i) => {
if (typedMethods && property.type !== undefined) {
result += property.type + " "
}
result += "$" + property.name;
if (i < (propertiesCount - 1)) {
result += ", ";
}
})
return result;
}
function buildBody(properties) {
let result = "";
const propertiesCount = properties.length;
properties.forEach((property, i) => {
let line = "";
line += `$this->${property.name} = $${property.name};`;
if (i < (propertiesCount - 1)) {
line += "\n";
}
result += indent(line, 2)
})
return result + "\n";
}
export const buildConstructor = (properties, config) => {
if (!(config.arraySerialization)) {
return "";
}
let result = "\n";
let declaration = "";
declaration += "public function __construct(";
declaration += buildParameters(properties, config);
declaration += ")\n";
result += indent(declaration, 1);
result += indent(`{\n`, 1);
result += buildBody(properties, config);
result += indent("}", 1)
return result;
}
export default () => {
let _deps = [];
let _keys = [];
let _index = 0;
const add = (dep) => {
_keys.push(dep.className);
_deps[dep.className] = dep;
return _inner;
}
const has = (className) => _deps.includes(className)
const all = () => _deps;
const get = () => {
if (Object.keys(_deps).length === 0) return null;
const className = _keys[_index];
const val = _deps[className];
delete _deps[className];
_index++;
return val;
}
const _inner = {
add,
has,
all,
get
}
return _inner;
};
import {camelCase, indent} from "./utils";
function buildSetter(property, {typedMethods}) {
const methodName = camelCase("set" + "_" + property.name);
let result = "";
let declaration = `public function ${methodName}`;
declaration += `(${(typedMethods && property.type !== undefined) ? property.type + " " : ""}$${property.name})`;
result += indent(declaration + "\n", 1);
result += indent("{\n", 1);
result += indent(`$this->${property.name} = $${property.name};\n`, 2);
result += indent(`return $this;\n`, 2);
result += indent("}", 1);
return result;
}
function buildGetter(property, {typedMethods}) {
const prefix = property.type === "bool" ? "is" : "get";
const methodName = camelCase(prefix + "_" + property.name);
let result = "";
let declaration = `public function ${methodName}()`;
if (typedMethods && property.type !== undefined) {
declaration += ":" + property.type;
}
result += indent(declaration + "\n", 1);
result += indent("{\n", 1);
result += indent(`return $this->${property.name};\n`, 2);
result += indent("}", 1);
return result;
}
function buildMethod(callback, properties, config) {
if (!config.getters && !config.setters) return "";
let result = "\n";
const l = properties.length;
properties.forEach((p, i) => {
result += "\n";
result += callback(p, config);
if (i < (l - 1)) {
result += "\n";
}
})
return result;
}
export const buildSetters = (properties, config) => {
if (!config.setters) return "";
return buildMethod(buildSetter, properties, config);
}
export const buildGetters = (properties, config) => {
if (!config.getters) return "";
return buildMethod(buildGetter, properties, config);
}
/**
* https://github.com/dani-gouken/json_to_php
*/
import buildClass from "./class";
import {Visibility} from "./property";
import deps from "./deps";
const defaultConfig = {
className: "",
namespace: "",
visibility: Visibility.PRIVATE,
typedProperties: false,
getters: true,
typedMethods: false,
setters: true,
arraySerialization: true,
includeDeps: true
}
function convert(jsonString, config = {}) {
config = {...defaultConfig, ...config}
if (!config.className) {
config.className = 'ClassName'
}
let json = JSON.parse(jsonString);
if (Array.isArray(json)) {
json = json[0];
}
const res = buildDeps(config, deps().add({
className: config.className,
key: null,
value: json
}));
let result = "";
if (config.namespace) {
result = "namespace " + config.namespace + ";\n\n" + result;
}
if (!config.includeDeps) {
return result + res[0];
}
res.forEach((v, i) => {
if (i !== 0) {
result += "\n\n" + v;
} else {
result += v;
}
});
return result;
}
function buildDeps(config, deps, classes = []) {
let classContent = deps.get();
if (classContent == null) {
return classes;
}
classes.push(buildClass(config, deps, classContent.value, classContent.className));
return buildDeps(config, deps, classes);
}
export default convert;
import {guessType, isScalarType} from "./types";
import {camelCase, indent, isEmpty} from "./utils";
export const Visibility = {
PUBLIC: "public",
PRIVATE: "private",
PROTECTED: "protected"
};
export const buildProperties = (properties, {visibility, typedProperties}) => {
let result = "";
properties.forEach((p) => {
if (p.type){
result += indent(`/** @var ${p.type} */\n`, 1);
}
result += indent(`${visibility}${(p.type && typedProperties) ? " " + p.type : ""} $${p.name};\n`, 1);
});
return result;
}
const subtype = (type, value, key) => {
if (isScalarType(type) || isEmpty(value) || (value === {})) return null;
let subKey = key;
if (type === "array") {
return guessType(
value.length > 0 ? value[0] : null,
subKey,
)
}
return guessType(
value,
subKey,
)
}
export const getPropertyInfo = (key, value) => {
let type = guessType(value, key);
return {
name: camelCase(key),
type: type,
originalName: key,
value: value,
subtype: subtype(type, value, key)
}
}
import {pascalCase} from "./utils";
export const guessType = (value, name) => {
const type = typeof value;
switch (type) {
case "object":
if (Array.isArray(value)) {
return "array";
}
if (value === null) {
return undefined;
}
return pascalCase(name);
case "boolean":
return "bool";
case "number":
return Number.isInteger(value) ? "int" : "float";
case "bigint":
return "int";
case "string":
return "string";
default:
return undefined;
}
}
export const isScalarType = (type) => {
return ["bool", "int", "float", "string"].includes(type) || type === null || type === undefined;
}
import {pascalCase as pascalCaseHandle} from "pascal-case"
import {camelCase as camelCaseHandle} from "camel-case"
export const indent = (string, level = 0, spaceCount = 4) => {
let space = " ".repeat(spaceCount * level);
return space + string;
}
export const isEmpty = (val) => {
return Array.isArray(val) && val.length === 0;
}
export const camelCase = (str) => {
return camelCaseHandle(str)
}
export const pascalCase = (str) => {
return pascalCaseHandle(str)
}
import _ from "lodash";
import {beautify} from "../formatter/html";
const convert = (json = [], {header = true} = {}) => {
if (!_.isArray(json) || json.length < 1) {
return ""
}
let html = ["<table>"];
let keys = Object.keys(json[0])
if (header) {
html.push(
'<thead>',
'<tr>',
...keys.map((item) => {
return `<th>${item}</th>`
}),
'</tr>',
'</thead>'
)
}
html.push("<tbody>")
for (let row of json) {
html.push("<tr>", ...keys.map((item) => {
return `<td>${item in row ? row[item] : ""}</td>`
}), '</tr>');
}
html.push("</tbody></table>")
return beautify(html.join(""))
}
export default convert
import {createTempElement, jsonOutputFormat} from "./helper";
import _ from "lodash";
const nodeFilter = (item) => {
if (item == null) {
return "";
}
const re = new RegExp("</?\\w+((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)/?>", 'igm');
item = item.replace(/\r\n|\r|\n/gmi, ' ');
item = item.replace(/\n|<br>|<br\/>|<br \/>/gmi, '\n');
item = item.replace(re, '');
item = _.unescape(item);
item = item.replace(/&nbsp;/gmi, " ");
return item.trim();
}
export const tableKeys = (table) => {
table = table.trim();
if (!table) {
return [];
}
const tableElement = createTempElement(table).getElementsByTagName('table')[0];
let cells = tableElement.getElementsByTagName('tr')[0].querySelectorAll('td,th');
let result = [];
for (let n = 0; n < cells.length; n++) {
result.push(nodeFilter(cells[n].innerHTML))
}
return result;
}
const convert = (table = "", {
keyed_key = 0,
type = "json"
} = {}) => {
table = table.trim();
if (!table) {
return "";
}
let keys = tableKeys(table)
const rows = createTempElement(table).getElementsByTagName('table')[0].getElementsByTagName('tr')
let result = [];
for (let i = 1; i < rows.length; i++) {
const row = rows[i].querySelectorAll('td');
let resultRow = {}
for (let k = 0; k < keys.length; k++) {
resultRow[keys[k]] = nodeFilter(k in row ? row[k].innerHTML : "")
}
result.push(resultRow)
}
return jsonOutputFormat(
result,
type,
keyed_key
)
}
export default convert
import BigNumber from "bignumber.js";
class Radix {
constructor(formatter = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_@') {
BigNumber.config({ALPHABET: formatter})
}
convent(base, source, target, debug = false) {
if (debug){
BigNumber.DEBUG = true
}
let sourceNum = new BigNumber(base, source);
if (debug){
BigNumber.DEBUG = false
}
return sourceNum.toString(target);
}
}
export default Radix
import jsonToPhpArray from "phparr"
import phpArrayToJson from "php-array-reader"
import phpSerialize from "serialize-php"
import propertiesToJSON from "properties-to-json"
import jsonToPropertiesParser from "json-to-properties/src/scripts/parser"
import yaml from "js-yaml"
import formatter from "./formatter"
import X2JS from "x2js"
export const TYPE = ["json", "xml", "yaml", "phpArray", "phpSerialize", "properties"];
class serializeConversion {
constructor(input, source) {
if (!TYPE.includes(source)) {
throw new Error("source error");
}
try {
switch (source) {
case "json":
this.input = JSON.parse(input);
break;
case "xml":
this.input = (new X2JS()).xml_str2json(input);
if(Object.keys(this.input).length === 1 && Object.keys(this.input).includes('default_root')){
this.input = this.input['default_root'];
}
break
case "yaml":
this.input = yaml.load(input);
break;
case "phpArray":
this.input = phpArrayToJson.fromString(input);
break;
case "phpSerialize":
this.input = phpSerialize.unserialize(input);
break;
case "properties":
console.log(propertiesToJSON(input))
this.input = propertiesToJSON(input);
break;
}
} catch (e) {
throw new Error("源数据转换异常:" + e.message);
}
}
getByTarget(target) {
if (!TYPE.includes(target)) {
throw new Error('target error');
}
try {
switch (target) {
case "json":
return this.getJson();
case "xml":
return this.getXml();
case "yaml":
return this.getYaml();
case "phpArray":
return this.getPhpArray();
case "phpSerialize":
return this.getPhpSerialize();
case "properties":
return this.getProperties();
}
} catch (e) {
throw new Error("目标数据转换错误:" + e.message);
}
}
getJson() {
return JSON.stringify(this.input,null,4)
}
getXml() {
let x2js = new X2JS();
this.input = Object.keys(this.input).length > 1 ? {default_root:this.input} : this.input;
return formatter(x2js.json2xml_str(this.input),'xml');
}
getYaml() {
return yaml.dump(this.input)
}
getProperties() {
return jsonToPropertiesParser.deflate(this.input).join("\n")
}
getPhpArray() {
return jsonToPhpArray(this.input);
}
getPhpSerialize() {
return phpSerialize.serialize(this.input);
}
}
export const conversion = (data, source) => {
return new serializeConversion(data, source)
}
\ No newline at end of file
import { simpleToTradition, traditionToSimple } from "chinese-simple2traditional";
import _ from 'lodash'
const regExpQuote = function (str) {
return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
};
// GBK字符集实际长度计算
function getGbkStrLength(str) {
let realLength = 0;
let len = str.length;
let charCode = -1;
for (let i = 0; i < len; i++) {
charCode = str.charCodeAt(i);
if (charCode >= 0 && charCode <= 128) {
realLength += 1;
} else {
realLength += 2;
}
}
return realLength;
}
class TextHandle {
constructor(text) {
this.text = text;
}
// 大写
upper() {
return this.text.toUpperCase();
}
// 小写
lower() {
return this.text.toLowerCase();
}
// 行首大写
upperLineStart() {
return this.text.split(/\r?\n/).map((str) => {
return str[0].toUpperCase() + str.substr(1)
}).join("\n");
}
// 行首小写
lowerLineStart() {
return this.text.split(/\r?\n/).map((str) => {
return str[0].toLowerCase() + str.substr(1)
}).join("\n");
}
// 词首大写
upperStart() {
return this.text.replace(/\b\w/g, function (str) {
return str.toUpperCase();
});
}
// 词首小写
lowerStart() {
return this.text.replace(/\b\w/g, function (str) {
return str.toLowerCase();
});
}
// 简繁转换
zhTran(type = "simplified") {
if (type === "simplified") {
return simpleToTradition(this.text)
}
return traditionToSimple(this.text)
}
// 替换
replace(search = [], replace = []) {
let text = this.text;
for (let i in search) {
if (search[i]){
text = text.replace(new RegExp(regExpQuote(search[i]), 'g'), (i in replace ? replace[i] : ""));
}
}
return text;
}
// 替换
regularReplace(search, replace) {
let text = this.text;
if (search){
text = text.replace(new RegExp(search, 'g'), replace);
}
return text;
}
// 移除重复行
lineRemoveRepeat() {
return _.uniq(this.text.split("\n")).join("\n")
}
// 移除行号
removeLineIndex() {
return this.text.replace(new RegExp("^\\s*\\d+\\.?", "gm"), "");
}
// 添加行号
addLineIndex() {
return this.text.split('\n').map((line, index) => `${index + 1}. ${line}`).join('\n')
}
// 行排序
lineSort(type = "asc") {
return _.orderBy(this.text.split(/\r?\n/), (item) => item, type).join("\n");
}
// trim
lineTrim() {
return this.text.split(/\r?\n/).map((item) => item.trim()).join("\n")
}
// 移除空行
filterBlankLine() {
return this.text.split(/\r?\n/).filter((item) => {
return item.trim() !== ""
}).join("\n")
}
// 过滤所有换行符
filterAllBr() {
return this.text.replace(/\r?\n|\r/g, " ")
}
// 标点替换
replacePunctuation(type = "zh") {
const zh = ["", "", "", "", "", "", "", "", "", "", "……", "", "", "", "", "", ""]
const en = ['"', '"', "'", "'", ".", ",", ";", ":", "?", "!", "", "-", "~", "(", ")", "<", ">"]
let text = this.text;
for (let i in zh) {
text = text.replace(
new RegExp(regExpQuote(type === "zh" ? en[i] : zh[i]), 'g'),
type === "zh" ? zh[i] : en[i]
);
}
return text
}
// 统计
stat() {
let content = this.text.replace(/\r?\n/g, "\n");
let zh_word = (content.match(/[\u4e00-\u9fa5]/g) || []).length;
let zh_punctuation = (content.match(/[\u3002\uff1f\uff01\uff0c\u3001\uff1b\uff1a\u201c\u201d\u2018\u2019\uff08\uff09\u300a\u300b\u3008\u3009\u3010\u3011\u300e\u300f\u300c\u300d\ufe43\ufe44\u3014\u3015\u2026\u2014\uff5e\ufe4f\uffe5]/g) || []).length;
let int_string = (content.match(/[0-9]/g) || []).length;
let en_string = (content.match(/[A-Za-z]/g) || []).length;
let int_word = (content.match(/\b\d+\b/g) || []).length;
let en_word = (content.match(/\b\w+\b/g) || []).length - int_word;
let en_punctuation = (content.match(/[~`!@#$%^&*()\-_+=|\\[\]{};:"',<.>/?]/g) || []).length;
return {
// 字节数(utf8)
byte_utf8_length: Buffer.byteLength(this.text, 'utf8'),
// 字节数(gbk)
byte_gbk_length: getGbkStrLength(this.text),
// 字符数
string_length: content.replace(/\n/g, "").length,
// 字数
word_length: zh_word + en_word + zh_punctuation + int_word + en_punctuation,
// 中文字数
zh_word,
// 中文标点
zh_punctuation,
// 英文字母
en_string,
// 英文单词
en_word,
// 英文标点
en_punctuation,
// 数字字符
int_string,
// 数字单词
int_word,
// 行数
line_length: this.text ? this.text.split("\n").length : 0
}
}
}
export default (text) => {
return new TextHandle(text)
}
\ No newline at end of file
const unicode_number = "unicode_number";
const html_entity_10 = "html_entity_10";
const html_entity_16 = "html_entity_16";
const unicode_point_default = "unicode_point_default";
const unicode_point_wide = "unicode_point_wide";
const unicode_point_wide_brace = "unicode_point_wide_brace";
const css_entitie = "css_entitie";
export default {
type: {
unicode_point_default,
unicode_point_wide,
unicode_point_wide_brace,
unicode_number,
html_entity_10,
html_entity_16,
css_entitie
},
decode(str, type = unicode_point_default) {
const errorListener = (item, callback) => {
try {
return callback && callback()
} catch (e) {
throw new Error(`${item} 解码异常:${e.message}`)
}
}
switch (type) {
case this.type.unicode_point_default:
return str.replace(/\\u[0-9a-fA-F]{4}/g, (item) => {
return errorListener(item, () => String.fromCodePoint(parseInt(`0x${item.toLowerCase().replace("\\u", "")}`)))
});
case this.type.unicode_point_wide:
return str.replace(/\\u[0-9a-fA-F]{1,6}/g, (item) => {
return errorListener(item, () => String.fromCodePoint(parseInt(`0x${item.toLowerCase().replace("\\u", "")}`)))
});
case this.type.unicode_point_wide_brace:
return str.replace(/\\u{[0-9a-fA-F]{1,6}}/g, (item) => {
return errorListener(item, () => String.fromCodePoint(parseInt(`0x${item.toLowerCase().replace("\\u", "").replace("{", "").replace("}", "")}`)))
});
case this.type.unicode_number:
return str.replace(/U\+[0-9a-fA-F]{1,6}/g, (item) => {
return errorListener(item, () => String.fromCodePoint(parseInt(`0x${item.replace("U", "").toLowerCase().replace("+", "")}`)))
});
case this.type.html_entity_10:
return str.replace(/&#[0-9]+;/g, (item) => {
return errorListener(item, () => String.fromCodePoint(parseInt(`${item.replace("&#", "").replace(";", "")}`)))
});
case this.type.html_entity_16:
return str.replace(/&#x[0-9a-fA-F]{1,6};/g, (item) => {
return errorListener(item, () => String.fromCodePoint(parseInt(`0x${item.replace("&#x", "").toLowerCase().replace(";", "")}`)))
});
case this.type.css_entitie:
return str.replace(/\\[0-9a-fA-F]{1,6}/g, (item) => {
return errorListener(item, () => String.fromCodePoint(parseInt(`0x${item.replace("\\", "").toLowerCase()}`)))
});
}
throw new Error("解码类型异常")
},
encode(string, type = unicode_point_default, ignore_ascii = false) {
let code = []
for (let s of string) {
let decimalStr = s.codePointAt(0).toString(10);
let hexStr = s.codePointAt(0).toString(16);
if (hexStr.length < 3 && ignore_ascii) {
// 忽略ascii字符
code.push(s)
continue;
}
// 补零
let hexRepairStr = this.repair(hexStr);
switch (type) {
case this.type.unicode_point_default:
if (hexStr.length > 4) {
// 宽字符处理
code.push(...this.charToUtf16(s).map((item) => `\\u${item}`))
} else {
code.push(`\\u${hexRepairStr}`);
}
break;
case this.type.unicode_point_wide:
code.push(`\\u${hexRepairStr}`);
break;
case this.type.unicode_point_wide_brace:
code.push(`\\u{${hexStr}}`);
break;
case this.type.unicode_number:
code.push(`U+${hexRepairStr.toUpperCase()}`);
break;
case this.type.html_entity_10:
code.push(`&#${decimalStr};`);
break;
case this.type.html_entity_16:
code.push(`&#x${hexStr};`);
break;
case this.type.css_entitie:
code.push(`\\${hexRepairStr}`);
break;
default:
throw new Error("编码类型异常")
}
}
return code.join("");
},
charToUtf16(str) {
let arr = []
for (let i = 0; i < str.length; i++) {
arr[i] = this.repair(str.charCodeAt(i).toString(16))
}
return arr
},
repair(str) {
return str.length > 3 ? str : `${'0'.repeat(4 - str.length)}${str}`;
}
}
\ No newline at end of file
import _ from 'lodash'
const MAX_NUM = 14 //格式化后的最长限制
const DECIMAL_NUM = 7 //四舍五入时小数点后位数
const EXPONENTIAL_NUM = 4 //科学计数法小数点后位数
const CONFIG = {
"length": {
"name": "长度",
"main": "",
"unit": [
{
"name": "千米",
"zh": "千米",
"en": "km",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
},
{
"name": "",
"zh": "",
"en": "m",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "分米",
"zh": "分米",
"en": "dm",
"calc": (x) => (x * 1) / 0.1,
"init": (x) => (x * 0.1)
},
{
"name": "厘米",
"zh": "厘米",
"en": "cm",
"calc": (x) => (x * 1) / 0.01,
"init": (x) => (x * 0.01)
},
{
"name": "毫米",
"zh": "毫米",
"en": "mm",
"calc": (x) => (x * 1) / 0.001,
"init": (x) => (x * 0.001)
},
{
"name": "微米",
"zh": "微米",
"en": "um",
"calc": (x) => (x * 1) / 0.000001,
"init": (x) => (x * 0.000001)
},
{
"name": "纳米",
"zh": "纳米",
"en": "nm",
"calc": (x) => (x * 1) / 0.000000001,
"init": (x) => (x * 0.000000001)
},
{
"name": "皮米",
"zh": "皮米",
"en": "pm",
"calc": (x) => (x * 1) / 0.000000000001,
"init": (x) => (x * 0.000000000001)
},
{
"name": "光年",
"zh": "光年",
"en": "ly",
"calc": (x) => (x * 1) / 9460730472580800,
"init": (x) => (x * 9460730472580800)
},
{
"name": "天文单位",
"zh": "天文单位",
"en": "AU",
"calc": (x) => (x * 1) / 149597870700,
"init": (x) => (x * 149600000000)
},
{
"name": "英寸",
"zh": "英寸",
"en": "in",
"calc": (x) => (x * 1) / (0.3048 / 12),
"init": (x) => (x * (0.3048 / 12))
},
{
"name": "英尺",
"zh": "英尺",
"en": "ft",
"calc": (x) => (x * 1) / 0.3048,
"init": (x) => (x * 0.3048)
},
{
"name": "",
"zh": "",
"en": "yd",
"calc": (x) => (x * 1) / (0.3048 * 3),
"init": (x) => (x * (0.3048 * 3))
},
{
"name": "英里",
"zh": "英里",
"en": "mi",
"calc": (x) => (x * 1) / (0.3048 * 3 * 1760),
"init": (x) => (x * (0.3048 * 3 * 1760))
},
{
"name": "海里",
"zh": "海里",
"en": "nmi",
"calc": (x) => (x * 1) / 1852,
"init": (x) => (x * 1852)
},
{
"name": "英寻",
"zh": "英寻",
"en": "fm",
"calc": (x) => (x * 1) / 1.8288,
"init": (x) => (x * 1.8288)
},
{
"name": "弗隆",
"zh": "弗隆",
"en": "fur",
"calc": (x) => (x * 1) / 201.168,
"init": (x) => (x * 201.168)
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / 500,
"init": (x) => (x * 500)
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (10 / 3),
"init": (x) => (x * (10 / 3))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (1 / 3),
"init": (x) => (x * (1 / 3))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (0.1 / 3),
"init": (x) => (x * (0.1 / 3))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (0.01 / 3),
"init": (x) => (x * (0.01 / 3))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (0.001 / 3),
"init": (x) => (x * (0.001 / 3))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (0.0001 / 3),
"init": (x) => (x * (0.0001 / 3))
}
],
"special": [],
"group": [
{
"name": "公制",
"list": [
"千米",
"",
"分米",
"厘米",
"毫米",
"微米",
"纳米",
"皮米",
"光年",
"天文单位"
]
},
{
"name": "英制",
"list": [
"英寸",
"英尺",
"",
"英里",
"海里",
"英寻",
"弗隆"
]
},
{
"name": "市制",
"list": [
"",
"",
"",
"",
"",
"",
""
]
}
]
},
"area": {
"name": "面积",
"main": "平方米",
"unit": [
{
"name": "平方千米",
"zh": "平方千米",
"en": "km²",
"calc": (x) => (x * 1) / 1000000,
"init": (x) => (x * 1000000)
},
{
"name": "公顷",
"zh": "公顷",
"en": "ha",
"calc": (x) => (x * 1) / 10000,
"init": (x) => (x * 10000)
},
{
"name": "公亩",
"zh": "公亩",
"en": "are",
"calc": (x) => (x * 1) / 100,
"init": (x) => (x * 100)
},
{
"name": "平方米",
"zh": "平方米",
"en": "",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "平方分米",
"zh": "平方分米",
"en": "dm²",
"calc": (x) => (x * 1) / 0.01,
"init": (x) => (x * 0.01)
},
{
"name": "平方厘米",
"zh": "平方厘米",
"en": "cm²",
"calc": (x) => (x * 1) / 0.0001,
"init": (x) => (x * 0.0001)
},
{
"name": "平方毫米",
"zh": "平方毫米",
"en": "mm²",
"calc": (x) => (x * 1) / 0.000001,
"init": (x) => (x * 0.000001)
},
{
"name": "英亩",
"zh": "英亩",
"en": "acre",
"calc": (x) => (x * 1) / (Math.pow(0.3048, 2) * Math.pow(16.5, 2) * 160),
"init": (x) => (x * (Math.pow(0.3048, 2) * Math.pow(16.5, 2) * 160))
},
{
"name": "平方英里",
"zh": "平方英里",
"en": "sq.mi",
"calc": (x) => (x * 1) / Math.pow((0.3048 * 3 * 1760), 2),
"init": (x) => (x * Math.pow((0.3048 * 3 * 1760), 2))
},
{
"name": "平方码",
"zh": "平方码",
"en": "sq.yd",
"calc": (x) => (x * 1) / (Math.pow(0.3048, 2) * 9),
"init": (x) => (x * (Math.pow(0.3048, 2) * 9))
},
{
"name": "平方英尺",
"zh": "平方英尺",
"en": "sq.ft",
"calc": (x) => (x * 1) / Math.pow(0.3048, 2),
"init": (x) => (x * (Math.pow(0.3048, 2)))
},
{
"name": "平方英寸",
"zh": "平方英寸",
"en": "sq.in",
"calc": (x) => (x * 1) / (Math.pow(0.3048, 2) / 144),
"init": (x) => (x * (Math.pow(0.3048, 2) / 144))
},
{
"name": "平方竿",
"zh": "平方竿",
"en": "sq.rd",
"calc": (x) => (x * 1) / (Math.pow(0.3048, 2) * Math.pow(16.5, 2)),
"init": (x) => (x * (Math.pow(0.3048, 2) * Math.pow(16.5, 2)))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (100 / 0.0015),
"init": (x) => (x * (100 / 0.0015))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (1 / 0.0015),
"init": (x) => (x * (1 / 0.0015))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / (1 / 0.015),
"init": (x) => (x * (1 / 0.015))
},
{
"name": "平方尺",
"zh": "平方尺",
"en": "",
"calc": (x) => (x * 1) / (1 / 9),
"init": (x) => (x * (1 / 9))
},
{
"name": "平方寸",
"zh": "平方寸",
"en": "",
"calc": (x) => (x * 1) / (0.01 / 9),
"init": (x) => (x * (0.01 / 9))
}
],
"special": [],
"group": [
{
"name": "公制",
"list": [
"平方千米",
"公顷",
"公亩",
"平方米",
"平方分米",
"平方厘米",
"平方毫米"
]
},
{
"name": "英制",
"list": [
"英亩",
"平方英里",
"平方码",
"平方英尺",
"平方英寸",
"平方竿"
]
},
{
"name": "市制",
"list": [
"",
"",
"",
"平方尺",
"平方寸"
]
}
]
},
"volume": {
"name": "体积",
"main": "立方米",
"unit": [
{
"name": "立方米",
"zh": "立方米",
"en": "",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "立方分米",
"zh": "立方分米",
"en": "dm³",
"calc": (x) => (x * 1) / 0.001,
"init": (x) => (x * 0.001)
},
{
"name": "立方厘米",
"zh": "立方厘米",
"en": "cm³",
"calc": (x) => (x * 1) / 0.000001,
"init": (x) => (x * 0.000001)
},
{
"name": "立方毫米",
"zh": "立方毫米",
"en": "mm³",
"calc": (x) => (x * 1) / 0.000000001,
"init": (x) => (x * 0.000000001)
},
{
"name": "",
"zh": "",
"en": "l",
"calc": (x) => (x * 1) / 0.001,
"init": (x) => (x * 0.001)
},
{
"name": "分升",
"zh": "分升",
"en": "dl",
"calc": (x) => (x * 1) / 0.0001,
"init": (x) => (x * 0.0001)
},
{
"name": "毫升",
"zh": "毫升",
"en": "ml",
"calc": (x) => (x * 1) / 0.000001,
"init": (x) => (x * 0.000001)
},
{
"name": "厘升",
"zh": "厘升",
"en": "cl",
"calc": (x) => (x * 1) / 0.00001,
"init": (x) => (x * 0.00001)
},
{
"name": "公石",
"zh": "公石",
"en": "hl",
"calc": (x) => (x * 1) / 0.1,
"init": (x) => (x * 0.1)
},
{
"name": "立方英尺",
"zh": "立方英尺",
"en": "cu ft",
"calc": (x) => (x * 1) / 0.0283168,
"init": (x) => (x * 0.0283168)
},
{
"name": "立方英寸",
"zh": "立方英寸",
"en": "cu in",
"calc": (x) => (x * 1) / (0.0283168 / 1728),
"init": (x) => (x * (0.0283168 / 1728))
},
{
"name": "立方码",
"zh": "立方码",
"en": "cu yd",
"calc": (x) => (x * 1) / (0.0283168 * 27),
"init": (x) => (x * (0.0283168 * 27))
},
{
"name": "亩英尺",
"zh": "亩英尺",
"en": "",
"calc": (x) => (x * 1) / (43560 * 1728 * 0.016387064 / 1000),
"init": (x) => (x * (43560 * 1728 * 0.016387064 / 1000))
},
{
"name": "英制加仑",
"zh": "英制加仑",
"en": "uk gal",
"calc": (x) => (x * 1) / 0.00454609188,
"init": (x) => (x * 0.00454609188)
},
{
"name": "美制加仑",
"zh": "美制加仑",
"en": "us gal",
"calc": (x) => (x * 1) / (231 * 0.016387064 / 1000),
"init": (x) => (x * (231 * 0.016387064 / 1000))
},
{
"name": "微升",
"zh": "微升",
"en": "ul",
"calc": (x) => (x * 1) / 0.000000001,
"init": (x) => (x * 0.000000001)
},
{
"name": "英制液体盎司",
"zh": "英制液体盎司",
"en": "oz",
"calc": (x) => (x * 1) / (0.000001 * 28.41),
"init": (x) => (x * 0.000001 * 28.41)
},
{
"name": "美制液体盎司",
"zh": "美制液体盎司",
"en": "oz",
"calc": (x) => (x * 1) / (0.000001 * 29.57),
"init": (x) => (x * 0.000001 * 29.57)
}
],
"special": [],
"group": [
{
"name": "公制",
"list": [
"立方米",
"立方分米",
"立方厘米",
"立方毫米",
"",
"分升",
"毫升",
"厘升",
"公石",
"微升"
]
},
{
"name": "英制",
"list": [
"立方英尺",
"立方英寸",
"立方码",
"亩英尺",
"英制加仑",
"美制加仑",
"英制液体盎司",
"美制液体盎司"
]
}
]
},
"weight": {
"name": "质量",
"main": "千克",
"unit": [
{
"name": "千克",
"zh": "千克",
"en": "kg",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "",
"zh": "",
"en": "g",
"calc": (x) => (x * 1) / 0.001,
"init": (x) => (x * 0.001)
},
{
"name": "毫克",
"zh": "毫克",
"en": "mg",
"calc": (x) => (x * 1) / 0.000001,
"init": (x) => (x * 0.000001)
},
{
"name": "微克",
"zh": "微克",
"en": "μg",
"calc": (x) => (x * 1) / 0.000000001,
"init": (x) => (x * 0.000000001)
},
{
"name": "",
"zh": "",
"en": "t",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
},
{
"name": "公担",
"zh": "公担",
"en": "q",
"calc": (x) => (x * 1) / 100,
"init": (x) => (x * 100)
},
{
"name": "",
"zh": "",
"en": "lb",
"calc": (x) => (x * 1) / 0.45359237,
"init": (x) => (x * 0.45359237)
},
{
"name": "盎司",
"zh": "盎司",
"en": "oz",
"calc": (x) => (x * 1) / (0.45359237 / 16),
"init": (x) => (x * (0.45359237 / 16))
},
{
"name": "克拉",
"zh": "克拉",
"en": "ct",
"calc": (x) => (x * 1) / 0.0002,
"init": (x) => (x * 0.0002)
},
{
"name": "格令",
"zh": "格令",
"en": "gr",
"calc": (x) => (x * 1) / (0.45359237 / 7000),
"init": (x) => (x * (0.45359237 / 7000))
},
{
"name": "长吨",
"zh": "长吨",
"en": "lt",
"calc": (x) => (x * 1) / (0.45359237 * 2240),
"init": (x) => (x * (0.45359237 * 2240))
},
{
"name": "短吨",
"zh": "短吨",
"en": "st",
"calc": (x) => (x * 1) / (0.45359237 * 2000),
"init": (x) => (x * (0.45359237 * 2000))
},
{
"name": "英担",
"zh": "英担",
"en": "",
"calc": (x) => (x * 1) / (0.45359237 * 112),
"init": (x) => (x * (0.45359237 * 112))
},
{
"name": "美担",
"zh": "美担",
"en": "",
"calc": (x) => (x * 1) / (0.45359237 * 100),
"init": (x) => (x * (0.45359237 * 100))
},
{
"name": "英石",
"zh": "英石",
"en": "st",
"calc": (x) => (x * 1) / (0.45359237 * 14),
"init": (x) => (x * (0.45359237 * 14))
},
{
"name": "打兰",
"zh": "打兰",
"en": "dr",
"calc": (x) => (x * 1) / (0.45359237 / 256),
"init": (x) => (x * (0.45359237 / 256))
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / 50,
"init": (x) => (x * 50)
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / 0.5,
"init": (x) => (x * 0.5)
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / 0.05,
"init": (x) => (x * 0.05)
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 1) / 0.005,
"init": (x) => (x * 0.005)
},
{
"name": "",
"zh": "",
"en": "point",
"calc": (x) => (x * 1) / 0.000002,
"init": (x) => (x * 0.000002)
}
],
"special": [],
"group": [
{
"name": "公制",
"list": [
"千克",
"",
"毫克",
"微克",
"",
"公担",
"克拉",
""
]
},
{
"name": "英制",
"list": [
"",
"盎司",
"克拉",
"格令",
"长吨",
"短吨",
"英担",
"美担",
"英石",
"打兰"
]
},
{
"name": "市制",
"list": [
"",
"",
"",
""
]
}
]
},
"temperature": {
"name": "温度",
"main": "开氏度",
"unit": [
{
"name": "摄氏度",
"zh": "摄氏度",
"en": "",
"calc": (x) => (x - 273.15),
"init": (x) => (x * 1) + 273.15
},
{
"name": "华氏度",
"zh": "华氏度",
"en": "",
"calc": (x) => 32 + ((x - 273.15) * 9 / 5),
"init": (x) => (5 * (x - 32) / 9) + 273.15
},
{
"name": "开氏度",
"zh": "开氏度",
"en": "K",
"calc": (x) => (x - 273.15) + 273.15,
"init": (x) => (x - 273.15) + 273.15
},
{
"name": "兰氏度",
"zh": "兰氏度",
"en": "°R",
"calc": (x) => ((x - 273.15) + 273.15) * 1.8,
"init": (x) => (x / 1.8 - 273.15) + 273.15
},
{
"name": "列氏度",
"zh": "列氏度",
"en": "°Re",
"calc": (x) => (x - 273.15) / 1.25,
"init": (x) => (x * 1.25) + 273.15
}
],
"special": [],
"group": [
{
"name": "",
"list": [
"摄氏度",
"华氏度",
"开氏度",
"兰氏度",
"列氏度"
]
}
]
},
"pressure": {
"name": "压力",
"main": "帕斯卡",
"unit": [
{
"name": "帕斯卡",
"zh": "帕斯卡",
"en": "Pa",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "千帕",
"zh": "千帕",
"en": "kpa",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
},
{
"name": "百帕",
"zh": "百帕",
"en": "hpa",
"calc": (x) => (x * 1) / 100,
"init": (x) => (x * 100)
},
{
"name": "标准大气压",
"zh": "标准大气压",
"en": "atm",
"calc": (x) => (x * 1) / 101325,
"init": (x) => (x * 101325)
},
{
"name": "毫米汞柱",
"zh": "毫米汞柱",
"en": "mmHg",
"calc": (x) => (x * 1) / (101325 / 760),
"init": (x) => (x * (101325 / 760))
},
{
"name": "英寸汞柱",
"zh": "英寸汞柱",
"en": "in Hg",
"calc": (x) => (x * 1) / (101325 / 760 * 25.4),
"init": (x) => (x * (101325 / 760 * 25.4))
},
{
"name": "",
"zh": "",
"en": "bar",
"calc": (x) => (x * 1) / 100000,
"init": (x) => (x * 100000)
},
{
"name": "毫巴",
"zh": "毫巴",
"en": "mbar",
"calc": (x) => (x * 1) / 100,
"init": (x) => (x * 100)
},
{
"name": "磅力/平方英尺",
"zh": "磅力/平方英尺",
"en": "psf",
"calc": (x) => (x * 1) / (6894.757 / 144),
"init": (x) => (x * (6894.757 / 144))
},
{
"name": "磅力/平方英寸",
"zh": "磅力/平方英寸",
"en": "psi",
"calc": (x) => (x * 1) / 6894.757,
"init": (x) => (x * 6894.757)
},
{
"name": "毫米水柱",
"zh": "毫米水柱",
"en": "",
"calc": (x) => (x * 1) / (1 / 0.101972),
"init": (x) => (x * (1 / 0.101972))
},
{
"name": "公斤力/平方厘米",
"zh": "公斤力/平方厘米",
"en": "kgf/cm²",
"calc": (x) => (x * 1) / 98066.5,
"init": (x) => (x * 98066.5)
},
{
"name": "公斤力/平方米",
"zh": "公斤力/平方米",
"en": "kgf/㎡",
"calc": (x) => (x * 1) / 9.80665,
"init": (x) => (x * 9.80665)
},
{
"name": "兆帕",
"zh": "兆帕",
"en": "MPa",
"calc": (x) => (x * 1) / 1000000,
"init": (x) => (x * 1000000)
}
],
"special": [],
"group": [
{
"name": "",
"list": [
"帕斯卡",
"兆帕",
"千帕",
"百帕",
"标准大气压",
"毫米汞柱",
"英寸汞柱",
"",
"毫巴",
"磅力/平方英尺",
"磅力/平方英寸",
"毫米水柱",
"公斤力/平方厘米",
"公斤力/平方米"
]
}
]
},
"power": {
"name": "功率",
"main": "",
"unit": [
{
"name": "",
"zh": "",
"en": "W",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "千瓦",
"zh": "千瓦",
"en": "kW",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
},
{
"name": "英制马力",
"zh": "英制马力",
"en": "hp",
"calc": (x) => (x * 1) / 745.699872,
"init": (x) => (x * 745.699872)
},
{
"name": "米制马力",
"zh": "米制马力",
"en": "ps",
"calc": (x) => (x * 1) / (9.80665 * 75),
"init": (x) => (x * (9.80665 * 75))
},
{
"name": "公斤·米/秒",
"zh": "公斤·米/秒",
"en": "kg·m/s",
"calc": (x) => (x * 1) / 9.80665,
"init": (x) => (x * 9.80665)
},
{
"name": "千卡/秒",
"zh": "千卡/秒",
"en": "kcal/s",
"calc": (x) => (x * 1) / 4184.1004,
"init": (x) => (x * 4184.1004)
},
{
"name": "英热单位/秒",
"zh": "英热单位/秒",
"en": "Btu/s",
"calc": (x) => (x * 1) / 1055.05585,
"init": (x) => (x * 1055.05585)
},
{
"name": "英尺·磅/秒",
"zh": "英尺·磅/秒",
"en": "ft·lb/s",
"calc": (x) => (x * 1) / (745.699872 / 550),
"init": (x) => (x * (745.699872 / 550))
},
{
"name": "焦耳/秒",
"zh": "焦耳/秒",
"en": "J/s",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "牛顿·米/秒",
"zh": "牛顿·米/秒",
"en": "N·m/s",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
}
],
"special": [],
"group": [
{
"name": "",
"list": [
"",
"千瓦",
"英制马力",
"米制马力",
"公斤·米/秒",
"千卡/秒",
"英热单位/秒",
"英尺·磅/秒",
"焦耳/秒",
"牛顿·米/秒"
]
}
]
},
"work": {
"name": "功/能/热",
"main": "焦耳",
"unit": [
{
"name": "焦耳",
"zh": "焦耳",
"en": "J",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "公斤·米",
"zh": "公斤·米",
"en": "kg·m",
"calc": (x) => (x * 1) / 9.80392157,
"init": (x) => (x * 9.80392157)
},
{
"name": "米制马力·时",
"zh": "米制马力·时",
"en": "ps·h",
"calc": (x) => (x * 1) / (9.80665 * 75 * 3600),
"init": (x) => (x * (9.80665 * 75 * 3600))
},
{
"name": "英制马力·时",
"zh": "英制马力·时",
"en": "hp·h",
"calc": (x) => (x * 1) / (745.699872 * 3600),
"init": (x) => (x * (745.699872 * 3600))
},
{
"name": "千瓦·时",
"zh": "千瓦·时",
"en": "kW·h",
"calc": (x) => (x * 1) / 3600000,
"init": (x) => (x * 3600000)
},
{
"name": "",
"zh": "",
"en": "kW·h",
"calc": (x) => (x * 1) / 3600000,
"init": (x) => (x * 3600000)
},
{
"name": "",
"zh": "",
"en": "cal",
"calc": (x) => (x * 1) / 4.185851820846,
"init": (x) => (x * 4.185851820846)
},
{
"name": "千卡",
"zh": "千卡",
"en": "kcal",
"calc": (x) => (x * 1) / 4185.851820846,
"init": (x) => (x * 4185.851820846)
},
{
"name": "英热单位",
"zh": "英热单位",
"en": "btu",
"calc": (x) => (x * 1) / 1055.05585262,
"init": (x) => (x * 1055.05585262)
},
{
"name": "英尺·磅",
"zh": "英尺·磅",
"en": "ft·lb",
"calc": (x) => (x * 1) / 1.3557483731,
"init": (x) => (x * 1.3557483731)
},
{
"name": "千焦",
"zh": "千焦",
"en": "kJ",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
}
],
"special": [],
"group": [
{
"name": "焦耳(J)",
"list": [
"焦耳",
"公斤·米",
"米制马力·时",
"英制马力·时",
"千瓦·时",
"",
"",
"千卡",
"英热单位",
"英尺·磅",
"千焦"
]
}
]
},
"density": {
"name": "密度",
"main": "千克/立方米",
"unit": [
{
"name": "千克/立方厘米",
"zh": "千克/立方厘米",
"en": "kg/cm³",
"calc": (x) => (x * 1) / (Math.pow(10, 6)),
"init": (x) => (x * 1000000)
},
{
"name": "千克/立方分米",
"zh": "千克/立方分米",
"en": "kg/dm³",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
},
{
"name": "千克/立方米",
"zh": "千克/立方米",
"en": "kg/m³",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "克/立方厘米",
"zh": "克/立方厘米",
"en": "g/cm³",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
},
{
"name": "克/立方分米",
"zh": "克/立方分米",
"en": "g/dm³",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "克/立方米",
"zh": "克/立方米",
"en": "g/m³",
"calc": (x) => (x * 1000),
"init": (x) => (x * 1) / 1000
}
],
"special": [],
"group": [
{
"name": "",
"list": [
"千克/立方厘米",
"千克/立方分米",
"千克/立方米",
"克/立方厘米",
"克/立方分米",
"克/立方米"
]
}
]
},
"strength": {
"name": "",
"main": "",
"unit": [
{
"name": "",
"zh": "",
"en": "N",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "千牛",
"zh": "千牛",
"en": "kN",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
},
{
"name": "千克力",
"zh": "千克力",
"en": "kgf",
"calc": (x) => (x * 101.971621) / 1000,
"init": (x) => (x * 9.806650)
},
{
"name": "克力",
"zh": "克力",
"en": "gf",
"calc": (x) => (x * 101.971621),
"init": (x) => (x * 9.806650) / 1000
},
{
"name": "公吨力",
"zh": "公吨力",
"en": "tf",
"calc": (x) => (x * 101.971621) / (Math.pow(10, 6)),
"init": (x) => (x * 9806.650000)
},
{
"name": "磅力",
"zh": "磅力",
"en": "lbf",
"calc": (x) => (x * 224.808943) / 1000,
"init": (x) => (x * 4.448222)
},
{
"name": "千磅力",
"zh": "千磅力",
"en": "kip",
"calc": (x) => (x * 224.808943) / (Math.pow(10, 6)),
"init": (x) => (x * 4448.221615)
},
{
"name": "达因",
"zh": "达因",
"en": "dyn",
"calc": (x) => (x * 100000),
"init": (x) => (x * 1) / 100000
}
],
"special": [],
"group": [
{
"name": "",
"list": [
"",
"千牛",
"千克力",
"克力",
"公吨力",
"磅力",
"千磅力",
"达因"
]
}
]
},
"time": {
"name": "时间",
"main": "",
"unit": [
{
"name": "",
"zh": "",
"en": "yr",
"calc": (x) => (x * 31.709792) / (Math.pow(10, 9)),
"init": (x) => (x * 31536000)
},
{
"name": "",
"zh": "",
"en": "week",
"calc": (x) => (x * 1.653439) / (Math.pow(10, 6)),
"init": (x) => (x * 604800)
},
{
"name": "",
"zh": "",
"en": "d",
"calc": (x) => (x * 11.574074) / (Math.pow(10, 6)),
"init": (x) => (x * 86400)
},
{
"name": "",
"zh": "",
"en": "h",
"calc": (x) => (x * 277.777778) / (Math.pow(10, 6)),
"init": (x) => (x * 3600)
},
{
"name": "",
"zh": "",
"en": "min",
"calc": (x) => (x * 16.6666667) / 1000,
"init": (x) => (x * 60)
},
{
"name": "",
"zh": "",
"en": "s",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "毫秒",
"zh": "毫秒",
"en": "ms",
"calc": (x) => (x * 1000),
"init": (x) => (x * 1) / 1000
},
{
"name": "微秒",
"zh": "微秒",
"en": "μs",
"calc": (x) => (x * 1000000),
"init": (x) => (x * 1) / 1000000
},
{
"name": "纳秒",
"zh": "纳秒",
"en": "ns",
"calc": (x) => (x * 1000000000),
"init": (x) => (x * 1) / 1000000000
}
],
"special": [
{
"from": "",
"to": "",
"func": (x) => (x * 60)
}
],
"group": [
{
"name": "",
"list": [
"",
"",
"",
"",
"",
"",
"毫秒",
"微秒",
"纳秒"
]
}
]
},
"speed": {
"name": "速度",
"main": "米/秒",
"unit": [
{
"name": "米/秒",
"zh": "米/秒",
"en": "m/s",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "千米/秒",
"zh": "千米/秒",
"en": "km/s",
"calc": (x) => (x * 1) / 1000,
"init": (x) => (x * 1000)
},
{
"name": "千米/时",
"zh": "千米/时",
"en": "km/h",
"calc": (x) => (x * 3.600000),
"init": (x) => (x * 277.777778) / 1000
},
{
"name": "光速",
"zh": "光速",
"en": "c",
"calc": (x) => (x * 3.335641) / (Math.pow(10, 9)),
"init": (x) => (x * 299792458)
},
{
"name": "马赫",
"zh": "马赫",
"en": "mach",
"calc": (x) => (x * 2.938584) / 1000,
"init": (x) => (x * 340.300000)
},
{
"name": "英里/时",
"zh": "英里/时",
"en": "mile/h",
"calc": (x) => (x * 2.236936),
"init": (x) => (x * 447.040000) / 1000
},
{
"name": "英寸/秒",
"zh": "英寸/秒",
"en": "in/s",
"calc": (x) => (x * 39.370079),
"init": (x) => (x * 25.400000) / 1000
}
],
"special": [],
"group": [
{
"name": "",
"list": [
"米/秒",
"千米/秒",
"千米/时",
"光速",
"马赫",
"英里/时",
"英寸/秒"
]
}
]
},
"byte": {
"name": "数据存储",
"main": "字节",
"unit": [
{
"name": "比特",
"zh": "比特",
"en": "bit",
"calc": (x) => (x * 8),
"init": (x) => (x * 1) / 8
},
{
"name": "字节",
"zh": "字节",
"en": "b",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "千字节",
"zh": "千字节",
"en": "kb",
"calc": (x) => (x * 1) / (Math.pow(2, 10)),
"init": (x) => (x * 1024)
},
{
"name": "兆字节",
"zh": "兆字节",
"en": "mb",
"calc": (x) => (x * 1) / (Math.pow(2, 20)),
"init": (x) => (x * Math.pow(2, 20))
},
{
"name": "千兆字节",
"zh": "千兆字节",
"en": "gb",
"calc": (x) => (x * 1) / (Math.pow(2, 30)),
"init": (x) => (x * Math.pow(2, 30))
},
{
"name": "太字节",
"zh": "太字节",
"en": "tb",
"calc": (x) => (x * 1) / (Math.pow(2, 40)),
"init": (x) => (x * Math.pow(2, 40))
},
{
"name": "拍字节",
"zh": "拍字节",
"en": "pb",
"calc": (x) => (x * 1) / (Math.pow(2, 50)),
"init": (x) => (x * Math.pow(2, 50))
},
{
"name": "艾字节",
"zh": "艾字节",
"en": "eb",
"calc": (x) => (x * 1) / (Math.pow(2, 60)),
"init": (x) => (x * Math.pow(2, 60))
}
],
"special": [],
"group": [
{
"name": "",
"list": [
"比特",
"字节",
"千字节",
"兆字节",
"千兆字节",
"太字节",
"拍字节",
"艾字节"
]
}
]
},
"angle": {
"name": "角度",
"main": "",
"unit": [
{
"name": "圆周",
"zh": "圆周",
"en": "",
"calc": (x) => (x * 2.777778) / 1000,
"init": (x) => (x * 360)
},
{
"name": "直角",
"zh": "直角",
"en": "",
"calc": (x) => (x * 11.111111) / 1000,
"init": (x) => (x * 90)
},
{
"name": "百分度",
"zh": "百分度",
"en": "gon",
"calc": (x) => (x * 1.111111),
"init": (x) => (x * 900) / 1000
},
{
"name": "",
"zh": "",
"en": "°",
"calc": (x) => (x * 1),
"init": (x) => (x * 1)
},
{
"name": "",
"zh": "",
"en": "",
"calc": (x) => (x * 60),
"init": (x) => (x * 16.6666667) / 1000
},
{
"name": "",
"zh": "",
"en": "'",
"calc": (x) => (x * 3600),
"init": (x) => (x * 0.2777778) / 1000
},
{
"name": "弧度",
"zh": "弧度",
"en": "rad",
"calc": (x) => (x * 17.453293) / 1000,
"init": (x) => (x * 57.295780)
},
{
"name": "毫弧度",
"zh": "毫弧度",
"en": "mrad",
"calc": (x) => (x * 17.453293),
"init": (x) => (x * 57.295780) / 1000
}
],
"special": [],
"group": [
{
"name": "角度制",
"list": [
"圆周",
"直角",
"百分度",
"",
"",
""
]
},
{
"name": "弧度制",
"list": [
"弧度",
"毫弧度"
]
}
]
},
}
/*
* 计算
* @uType String, not null, 单位类型(如length, time)
* @num Number, not null, 输入值
* @uFrom String, not null, 原单位
* @uTo String, not null, 目标单位
* @keepOrigin Boolean, null, 保持原始结果(不进行格式化),默认false
*
* return Object, 计算结果
*/
const calculate = function (type, num, from, to, keepOrigin = false) {
let fromUnit = getUnit(type, from)
if (from === to) {
return {
num: keepOrigin ? num : format(num),
unitFirst: fromUnit.zh,
unitSecond: fromUnit.en
}
}
let toUnit = getUnit(type, to)
let special = getSpecial(type, from, to)
if (special !== null) {
num = special(num)
} else {
num = toUnit.calc(fromUnit.init(num))
}
return {
num: keepOrigin ? num : format(num),
unitFirst: toUnit.zh,
unitSecond: toUnit.en
}
}
const getCategory = (type) => {
return CONFIG[type]
}
const getUnit = (type, name) => {
let category = getCategory(type)
for (let i = 0; i < category.unit.length; i++) {
if (name === category.unit[i].name) {
return category.unit[i];
}
}
}
const getSpecial = (type, from, to) => {
let category = getCategory(type)
if (category.special.length > 0) {
for (let i = 0; i < category.special.length; i++) {
if (from === category.special[i].from && to === category.special[i].to) {
return category.special[i].func;
}
}
}
return null;
}
/*
* 对结果进行格式化(内部使用)
*/
const format = function (num) {
//格式策略,整体不超过14位
let strNum = num + '',
isFloat = false,
arr, intPart, decPart
//只有包括.且整数位小于14位才认为是浮点数(便于以后格式化)
if (strNum.indexOf('.') > -1) {
let match = strNum.match(/\.\d+e[+-](\d+)$/)
if (match && match[1]) {
isFloat = match[1] * 1 < (MAX_NUM - 1) ? true : false
} else {
isFloat = true
}
}
//小数处理逻辑
if (isFloat) {
//-1 ~ 1之间的小数
if (num > -1 && num < 1 && num != 0) {
//小数位开始有5个及以上0,转换为科学计数法,计数小数保留四位
if (Math.abs(num) < 0.00001) {
num = exponential(num, EXPONENTIAL_NUM)
} else {
//保留7位小数
num = num.toFixed(DECIMAL_NUM) * 1
}
} else {
arr = strNum.split('.')
intPart = arr[0]
decPart = arr[1]
//整体超长
if (strNum.length > MAX_NUM) {
//整数部分超长
if (intPart.length >= MAX_NUM) {
num = exponential(num, EXPONENTIAL_NUM)
} else {
if (intPart.length < DECIMAL_NUM - 1) {
num = num.toFixed(DECIMAL_NUM) * 1
} else {
num = num.toFixed(MAX_NUM - intPart.length - 1) * 1
}
}
} else {
if (decPart.length > DECIMAL_NUM) {
num = num.toFixed(DECIMAL_NUM) * 1
}
}
}
} else {
if (strNum.length > MAX_NUM) {
num = exponential(num, EXPONENTIAL_NUM)
}
}
return num + ''
}
/*
* 科学计数法快捷函数(内部使用)
*/
const exponential = function (num, n) {
//保留科学计数法小数后n位
let numExp = num.toExponential(n)
//如果计数小数位均为0,去掉
return (numExp + '').match(new RegExp('.0{' + n + '}e')) ? num.toExponential(0) : numExp
}
export default {
//返回某一类的所有配置项
getData: function (type) {
return _.cloneDeep(getCategory(type).group).map((item) => {
item.list = item.list.map((name) => {
let unit = getUnit(type, name)
return {
name,
unit: unit.zh + (unit.en ? ` (${unit.en})` : '')
}
})
return item;
})
},
getMain(type) {
return getCategory(type).main
},
//计算,返回格式化后的结果
calc: function (type, x, from, to) {
return calculate(type, x, from, to)
},
//计算,返回原始结果
calcOrigin: function (type, x, from, to) {
return calculate(type, x, from, to, true)
},
//格式化
format: function (num) {
return format(num)
},
list: () => {
return Object.keys(CONFIG).map((key) => {
return {key, name: CONFIG[key].name}
})
}
}
// 算法来源 https://github.com/netnexus/camelcaseplugin
const SPACE_CASE = 'spaceCaseToPascalCaseSpace' // 转换过程 space case to Camel Case
const PASCAL_CASE_SPACE = 'pascalCaseSpaceToKebabCase' // 转换过程 Camel Case to kebab-case
const KEBAB_CASE = 'kebabCaseToUpperSnakeCase' // 转换过程 kebab-case to SNAKE_CASE
const UPPER_SNAKE_CASE = 'upperSnakeCaseToPascalCase' // 转换过程 SNAKE_CASE to CamelCase
const PASCAL_CASE = 'pascalCaseToCamelCase' // 转换过程 CamelCase to camelCase
const CAMEL_CASE = 'camelCaseToLowerSnakeCase' // 转换过程 camelCase to snake_case
const LOWER_SNAKE_CASE = 'lowerSnakeCaseToSpaceCase' // 转换过程 snake_case to space case
const isUpperCase = (str, first = false) => {
if (first === false) {
return str.toUpperCase() === str;
}
return str.substr(0, 1).toUpperCase() === str.substr(0, 1)
&& (str.length === 1 || str.substr(1, 1).toLowerCase() === str.substr(1, 1));
}
const isLowerCase = (str, first = false) => {
if (first === false) {
return str.toLowerCase() === str;
}
return str.substr(0, 1).toLowerCase() === str.substr(0, 1);
}
const firstToUpper = (str) => {
return str.replace(str[0], str[0].toUpperCase());
}
const firstToLower = (str) => {
return str.replace(str[0], str[0].toLowerCase());
}
const getMethodName = (str) => {
str = str.trim();
if (isLowerCase(str) && str.indexOf('_') !== -1) {
return LOWER_SNAKE_CASE;
}
if (isLowerCase(str) && str.indexOf('-') !== -1) {
return KEBAB_CASE;
}
if (isLowerCase(str) && str.indexOf(' ') !== -1) {
return SPACE_CASE;
}
if (isUpperCase(str, true) && str.indexOf(' ') !== -1) {
return PASCAL_CASE_SPACE;
}
if (isUpperCase(str) && str.indexOf('_') !== -1) {
return UPPER_SNAKE_CASE;
}
if (isUpperCase(str, true) && str.indexOf('_') === -1 && str.indexOf(' ') === -1 && str.indexOf('0') === -1) {
return PASCAL_CASE;
}
return CAMEL_CASE;
}
class Conversion {
constructor(str) {
this.setStr(str);
}
setStr(str) {
this.str = str.trim()
return this;
}
// space case to Camel Case
spaceCaseToPascalCaseSpace() {
return this.str.split(' ').map((str) => {
return firstToUpper(str)
}).join(' ').trim()
}
// Camel Case to kebab-case
pascalCaseSpaceToKebabCase() {
return this.str.replace(/ /g, "-").toLowerCase().trim();
}
// kebab-case to SNAKE_CASE
kebabCaseToUpperSnakeCase() {
return this.str.toUpperCase().replace(/-/g, "_").trim()
}
// SNAKE_CASE to PascalCase
upperSnakeCaseToPascalCase() {
return this.str.split('_').map((str) => {
return firstToUpper(str.toLowerCase())
}).join('').trim()
}
// PascalCase to camelCase
pascalCaseToCamelCase() {
return firstToLower(this.str).trim()
}
// camelCase to snake_case
camelCaseToLowerSnakeCase() {
let temp = "";
for (let i = 0; i < this.str.length; i++) {
let c = this.str.substr(i, 1);
if (isUpperCase(this.str.substr(i, 1))) {
temp = temp + '_';
}
temp = temp + c.toLowerCase();
}
return temp.trim();
}
// snake_case to space case
lowerSnakeCaseToSpaceCase() {
return this.str.replace(/_/g, " ").trim();
}
get() {
let methods = [
SPACE_CASE,
PASCAL_CASE_SPACE,
KEBAB_CASE,
UPPER_SNAKE_CASE,
PASCAL_CASE,
CAMEL_CASE,
LOWER_SNAKE_CASE,
];
let current = methods.indexOf(getMethodName(this.str));
let executeMethods;
if (current === 0) {
executeMethods = methods;
} else {
executeMethods = [...methods.slice(current), ...methods.slice(0, current)]
}
let result = {};
let str = this.str;
for (let i = 0; i < executeMethods.length; i++) {
str = this.setStr(str)[executeMethods[i]](str);
result[executeMethods[i]] = str;
}
return result;
}
}
const resultKey = [
{key: SPACE_CASE, name: 'Var Name'},
{key: PASCAL_CASE_SPACE, name: 'var-name'},
{key: KEBAB_CASE, name: 'VAR_NAME'},
{key: UPPER_SNAKE_CASE, name: 'VarName'},
{key: PASCAL_CASE, name: 'varName'},
{key: CAMEL_CASE, name: 'var_name'},
{key: LOWER_SNAKE_CASE, name: 'var name'},
]
export default {
resultKey,
convent: (str) => {
let result = {
[SPACE_CASE]: [],
[PASCAL_CASE_SPACE]: [],
[KEBAB_CASE]: [],
[UPPER_SNAKE_CASE]: [],
[PASCAL_CASE]: [],
[CAMEL_CASE]: [],
[LOWER_SNAKE_CASE]: [],
};
let list = str.split("\n").map((_str) => {
return _str.trim()
}).filter((_str) => !!_str);
for (let item of list) {
let conversion = new Conversion(item)
let conversionResult = conversion.get()
for (let key of Object.keys(conversionResult)) {
result[key].push(conversionResult[key])
}
}
for (let key of Object.keys(result)) {
result[key] = result[key].join("\n");
}
return result;
}
}
\ No newline at end of file
<template>
<heightResize :append="['.page-option-block']" ignore @resize="resize">
<autoHeightTextarea :height="inputHeight" v-model="current.input" :placeholder="$t('pinyin_input')" />
<option-block class="page-option-block">
<FormItem>
<RadioGroup v-model="current.operation" type="button" button-style="solid">
<Radio label="normal">{{ $t('pinyin_normal') }}</Radio>
<Radio label="tone">{{ $t('pinyin_tone') }}</Radio>
<Radio label="abbr">{{ $t('pinyin_abbr') }}</Radio>
</RadioGroup>
</FormItem>
<FormItem>
<Select v-model="current.delimiter" style="width:200px">
<Option v-for="(d,k) in delimiter" :value="d.v" :key="k">{{ d.n }}</Option>
</Select>
</FormItem>
</option-block>
<autoHeightTextarea :height="outputHeight" :value="output" :placeholder="$t('pinyin_output')" />
</heightResize>
</template>
<script>
import "./pinyin/dict"
import "ipinyinjs"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
function py(type, str, delimiter) {
let pinyin = {
abbr: function (str, delimiter) {
return window.pinyinUtil.getFirstLetter(str).split('').join(delimiter);
},
tone: function (str, delimiter) {
return window.pinyinUtil.getPinyin(str, delimiter);
},
normal: function (str, delimiter) {
return window.pinyinUtil.getPinyin(str, delimiter, false);
}
};
str = str.split("\n");
for (let i = 0; i < str.length; i++) {
str[i] = pinyin[type](str[i], delimiter);
}
return str.join("\n");
}
export default {
components:{
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData('input')
},
computed: {
output() {
let result = "";
if (this.current.input.trim()) {
result = py(
this.current.operation,
this.current.input,
this.current.delimiter === "null" ? "" : (this.current.delimiter === "blank" ? " " : this.current.delimiter)
);
this.$saveToolData(this.current);
}
return result
}
},
methods:{
resize(height){
this.inputHeight = Math.min(Math.ceil(height/2),160);
this.outputHeight = height - this.inputHeight;
}
},
data() {
return {
current: {
input: "",
output: "",
delimiter: "null",
operation: "normal"
},
delimiter: [
{"n": this.$t('pinyin_delimiter_null'), "v": "null"},
{"n": this.$t('pinyin_delimiter_space'), "v": "blank"},
{"n": this.$t('pinyin_delimiter_1'), "v": "-"},
{"n": this.$t('pinyin_delimiter_2'), "v": "_"},
{"n": this.$t('pinyin_delimiter_3'), "v": "."}
],
inputHeight:100,
outputHeight:100,
}
},
}
</script>
window.pinyin_dict_notone = {
"a": "阿啊呵腌嗄吖锕",
"e": "额阿俄恶鹅遏鄂厄饿峨扼娥鳄哦蛾噩愕讹锷垩婀鹗萼谔莪腭锇颚呃阏屙苊轭",
"ai": "爱埃艾碍癌哀挨矮隘蔼唉皑哎霭捱暧嫒嗳瑷嗌锿砹",
"ei": "",
"xi": "系西席息希习吸喜细析戏洗悉锡溪惜稀袭夕洒晰昔牺腊烯熙媳栖膝隙犀蹊硒兮熄曦禧嬉玺奚汐徙羲铣淅嘻歙熹矽蟋郗唏皙隰樨浠忾蜥檄郄翕阋鳃舾屣葸螅咭粞觋欷僖醯鼷裼穸饩舄禊诶菥蓰",
"yi": "一以已意议义益亿易医艺食依移衣异伊仪宜射遗疑毅谊亦疫役忆抑尾乙译翼蛇溢椅沂泄逸蚁夷邑怡绎彝裔姨熠贻矣屹颐倚诣胰奕翌疙弈轶蛾驿壹猗臆弋铱旖漪迤佚翊诒怿痍懿饴峄揖眙镒仡黟肄咿翳挹缢呓刈咦嶷羿钇殪荑薏蜴镱噫癔苡悒嗌瘗衤佾埸圯舣酏劓",
"an": "安案按岸暗鞍氨俺胺铵谙庵黯鹌桉埯犴揞厂广",
"han": "厂汉韩含旱寒汗涵函喊憾罕焊翰邯撼瀚憨捍酣悍鼾邗颔蚶晗菡旰顸犴焓撖",
"ang": "昂仰盎肮",
"ao": "奥澳傲熬凹鳌敖遨鏖袄坳翱嗷拗懊岙螯骜獒鏊艹媪廒聱",
"wa": "瓦挖娃洼袜蛙凹哇佤娲呙腽",
"yu": "于与育余预域予遇奥语誉玉鱼雨渔裕愈娱欲吁舆宇羽逾豫郁寓吾狱喻御浴愉禹俞邪榆愚渝尉淤虞屿峪粥驭瑜禺毓钰隅芋熨瘀迂煜昱汩於臾盂聿竽萸妪腴圄谕觎揄龉谀俣馀庾妤瘐鬻欤鹬阈嵛雩鹆圉蜮伛纡窬窳饫蓣狳肀舁蝓燠",
"niu": "牛纽扭钮拗妞忸狃",
"o": "哦噢喔",
"ba": "把八巴拔伯吧坝爸霸罢芭跋扒叭靶疤笆耙鲅粑岜灞钯捌菝魃茇",
"pa": "怕帕爬扒趴琶啪葩耙杷钯筢",
"pi": "被批副否皮坏辟啤匹披疲罢僻毗坯脾譬劈媲屁琵邳裨痞癖陂丕枇噼霹吡纰砒铍淠郫埤濞睥芘蚍圮鼙罴蜱疋貔仳庀擗甓陴",
"bi": "比必币笔毕秘避闭佛辟壁弊彼逼碧鼻臂蔽拂泌璧庇痹毙弼匕鄙陛裨贲敝蓖吡篦纰俾铋毖筚荸薜婢哔跸濞秕荜愎睥妣芘箅髀畀滗狴萆嬖襞舭",
"bai": "百白败摆伯拜柏佰掰呗擘捭稗",
"bo": "波博播勃拨薄佛伯玻搏柏泊舶剥渤卜驳簿脖膊簸菠礴箔铂亳钵帛擘饽跛钹趵檗啵鹁擗踣",
"bei": "北被备倍背杯勃贝辈悲碑臂卑悖惫蓓陂钡狈呗焙碚褙庳鞴孛鹎邶鐾",
"ban": "办版半班般板颁伴搬斑扮拌扳瓣坂阪绊钣瘢舨癍",
"pan": "判盘番潘攀盼拚畔胖叛拌蹒磐爿蟠泮袢襻丬",
"bin": "份宾频滨斌彬濒殡缤鬓槟摈膑玢镔豳髌傧",
"bang": "帮邦彭旁榜棒膀镑绑傍磅蚌谤梆浜蒡",
"pang": "旁庞乓磅螃彷滂逄耪",
"beng": "泵崩蚌蹦迸绷甭嘣甏堋",
"bao": "报保包宝暴胞薄爆炮饱抱堡剥鲍曝葆瀑豹刨褒雹孢苞煲褓趵鸨龅勹",
"bu": "不部步布补捕堡埔卜埠簿哺怖钚卟瓿逋晡醭钸",
"pu": "普暴铺浦朴堡葡谱埔扑仆蒲曝瀑溥莆圃璞濮菩蹼匍噗氆攵镨攴镤",
"mian": "面棉免绵缅勉眠冕娩腼渑湎沔黾宀眄",
"po": "破繁坡迫颇朴泊婆泼魄粕鄱珀陂叵笸泺皤钋钷",
"fan": "反范犯繁饭泛翻凡返番贩烦拚帆樊藩矾梵蕃钒幡畈蘩蹯燔",
"fu": "府服副负富复福夫妇幅付扶父符附腐赴佛浮覆辅傅伏抚赋辐腹弗肤阜袱缚甫氟斧孚敷俯拂俘咐腑孵芙涪釜脯茯馥宓绂讣呋罘麸蝠匐芾蜉跗凫滏蝮驸绋蚨砩桴赙菔呒趺苻拊阝鲋怫稃郛莩幞祓艴黻黼鳆",
"ben": "本体奔苯笨夯贲锛畚坌",
"feng": "风丰封峰奉凤锋冯逢缝蜂枫疯讽烽俸沣酆砜葑唪",
"bian": "变便边编遍辩鞭辨贬匾扁卞汴辫砭苄蝙鳊弁窆笾煸褊碥忭缏",
"pian": "便片篇偏骗翩扁骈胼蹁谝犏缏",
"zhen": "镇真针圳振震珍阵诊填侦臻贞枕桢赈祯帧甄斟缜箴疹砧榛鸩轸稹溱蓁胗椹朕畛浈",
"biao": "表标彪镖裱飚膘飙镳婊骠飑杓髟鳔灬瘭",
"piao": "票朴漂飘嫖瓢剽缥殍瞟骠嘌莩螵",
"huo": "和活或货获火伙惑霍祸豁嚯藿锪蠖钬耠镬夥灬劐攉",
"bie": "别鳖憋瘪蹩",
"min": "民敏闽闵皿泯岷悯珉抿黾缗玟愍苠鳘",
"fen": "分份纷奋粉氛芬愤粪坟汾焚酚吩忿棼玢鼢瀵偾鲼",
"bing": "并病兵冰屏饼炳秉丙摒柄槟禀枋邴冫",
"geng": "更耕颈庚耿梗埂羹哽赓绠鲠",
"fang": "方放房防访纺芳仿坊妨肪邡舫彷枋鲂匚钫",
"xian": "现先县见线限显险献鲜洗宪纤陷闲贤仙衔掀咸嫌掺羡弦腺痫娴舷馅酰铣冼涎暹籼锨苋蚬跹岘藓燹鹇氙莶霰跣猃彡祆筅",
"fou": "不否缶",
"ca": "拆擦嚓礤",
"cha": "查察差茶插叉刹茬楂岔诧碴嚓喳姹杈汊衩搽槎镲苴檫馇锸猹",
"cai": "才采财材菜彩裁蔡猜踩睬",
"can": "参残餐灿惨蚕掺璨惭粲孱骖黪",
"shen": "信深参身神什审申甚沈伸慎渗肾绅莘呻婶娠砷蜃哂椹葚吲糁渖诜谂矧胂",
"cen": "参岑涔",
"san": "三参散伞叁糁馓毵",
"cang": "藏仓苍沧舱臧伧",
"zang": "藏脏葬赃臧奘驵",
"chen": "称陈沈沉晨琛臣尘辰衬趁忱郴宸谌碜嗔抻榇伧谶龀肜",
"cao": "草操曹槽糙嘈漕螬艚屮",
"ce": "策测册侧厕栅恻",
"ze": "责则泽择侧咋啧仄箦赜笮舴昃迮帻",
"zhai": "债择齐宅寨侧摘窄斋祭翟砦瘵哜",
"dao": "到道导岛倒刀盗稻蹈悼捣叨祷焘氘纛刂帱忉",
"ceng": "层曾蹭噌",
"zha": "查扎炸诈闸渣咋乍榨楂札栅眨咤柞喳喋铡蚱吒怍砟揸痄哳齄",
"chai": "差拆柴钗豺侪虿瘥",
"ci": "次此差词辞刺瓷磁兹慈茨赐祠伺雌疵鹚糍呲粢",
"zi": "资自子字齐咨滋仔姿紫兹孜淄籽梓鲻渍姊吱秭恣甾孳訾滓锱辎趑龇赀眦缁呲笫谘嵫髭茈粢觜耔",
"cuo": "措错磋挫搓撮蹉锉厝嵯痤矬瘥脞鹾",
"chan": "产单阐崭缠掺禅颤铲蝉搀潺蟾馋忏婵孱觇廛谄谗澶骣羼躔蒇冁",
"shan": "山单善陕闪衫擅汕扇掺珊禅删膳缮赡鄯栅煽姗跚鳝嬗潸讪舢苫疝掸膻钐剡蟮芟埏彡骟",
"zhan": "展战占站崭粘湛沾瞻颤詹斩盏辗绽毡栈蘸旃谵搌",
"xin": "新心信辛欣薪馨鑫芯锌忻莘昕衅歆囟忄镡",
"lian": "联连练廉炼脸莲恋链帘怜涟敛琏镰濂楝鲢殓潋裢裣臁奁莶蠊蔹",
"chang": "场长厂常偿昌唱畅倡尝肠敞倘猖娼淌裳徜昶怅嫦菖鲳阊伥苌氅惝鬯",
"zhang": "长张章障涨掌帐胀彰丈仗漳樟账杖璋嶂仉瘴蟑獐幛鄣嫜",
"chao": "超朝潮炒钞抄巢吵剿绰嘲晁焯耖怊",
"zhao": "着照招找召朝赵兆昭肇罩钊沼嘲爪诏濯啁棹笊",
"zhou": "调州周洲舟骤轴昼宙粥皱肘咒帚胄绉纣妯啁诌繇碡籀酎荮",
"che": "车彻撤尺扯澈掣坼砗屮",
"ju": "车局据具举且居剧巨聚渠距句拒俱柜菊拘炬桔惧矩鞠驹锯踞咀瞿枸掬沮莒橘飓疽钜趄踽遽琚龃椐苣裾榘狙倨榉苴讵雎锔窭鞫犋屦醵",
"cheng": "成程城承称盛抢乘诚呈净惩撑澄秤橙骋逞瞠丞晟铛埕塍蛏柽铖酲裎枨",
"rong": "容荣融绒溶蓉熔戎榕茸冗嵘肜狨蝾",
"sheng": "生声升胜盛乘圣剩牲甸省绳笙甥嵊晟渑眚",
"deng": "等登邓灯澄凳瞪蹬噔磴嶝镫簦戥",
"zhi": "制之治质职只志至指织支值知识直致执置止植纸拓智殖秩旨址滞氏枝芝脂帜汁肢挚稚酯掷峙炙栉侄芷窒咫吱趾痔蜘郅桎雉祉郦陟痣蛭帙枳踯徵胝栀贽祗豸鸷摭轵卮轾彘觯絷跖埴夂黹忮骘膣踬",
"zheng": "政正证争整征郑丁症挣蒸睁铮筝拯峥怔诤狰徵钲",
"tang": "堂唐糖汤塘躺趟倘棠烫淌膛搪镗傥螳溏帑羰樘醣螗耥铴瑭",
"chi": "持吃池迟赤驰尺斥齿翅匙痴耻炽侈弛叱啻坻眙嗤墀哧茌豉敕笞饬踟蚩柢媸魑篪褫彳鸱螭瘛眵傺",
"shi": "是时实事市十使世施式势视识师史示石食始士失适试什泽室似诗饰殖释驶氏硕逝湿蚀狮誓拾尸匙仕柿矢峙侍噬嗜栅拭嘘屎恃轼虱耆舐莳铈谥炻豕鲥饣螫酾筮埘弑礻蓍鲺贳",
"qi": "企其起期气七器汽奇齐启旗棋妻弃揭枝歧欺骑契迄亟漆戚岂稽岐琦栖缉琪泣乞砌祁崎绮祺祈凄淇杞脐麒圻憩芪伎俟畦耆葺沏萋骐鳍綦讫蕲屺颀亓碛柒啐汔綮萁嘁蛴槭欹芑桤丌蜞",
"chuai": "揣踹啜搋膪",
"tuo": "托脱拓拖妥驼陀沱鸵驮唾椭坨佗砣跎庹柁橐乇铊沲酡鼍箨柝",
"duo": "多度夺朵躲铎隋咄堕舵垛惰哆踱跺掇剁柁缍沲裰哚隳",
"xue": "学血雪削薛穴靴谑噱鳕踅泶彐",
"chong": "重种充冲涌崇虫宠忡憧舂茺铳艟",
"chou": "筹抽绸酬愁丑臭仇畴稠瞅踌惆俦瘳雠帱",
"qiu": "求球秋丘邱仇酋裘龟囚遒鳅虬蚯泅楸湫犰逑巯艽俅蝤赇鼽糗",
"xiu": "修秀休宿袖绣臭朽锈羞嗅岫溴庥馐咻髹鸺貅",
"chu": "出处础初助除储畜触楚厨雏矗橱锄滁躇怵绌搐刍蜍黜杵蹰亍樗憷楮",
"tuan": "团揣湍疃抟彖",
"zhui": "追坠缀揣椎锥赘惴隹骓缒",
"chuan": "传川船穿串喘椽舛钏遄氚巛舡",
"zhuan": "专转传赚砖撰篆馔啭颛",
"yuan": "元员院原源远愿园援圆缘袁怨渊苑宛冤媛猿垣沅塬垸鸳辕鸢瑗圜爰芫鼋橼螈眢箢掾",
"cuan": "窜攒篡蹿撺爨汆镩",
"chuang": "创床窗闯幢疮怆",
"zhuang": "装状庄壮撞妆幢桩奘僮戆",
"chui": "吹垂锤炊椎陲槌捶棰",
"chun": "春纯醇淳唇椿蠢鹑朐莼肫蝽",
"zhun": "准屯淳谆肫窀",
"cu": "促趋趣粗簇醋卒蹴猝蹙蔟殂徂",
"dun": "吨顿盾敦蹲墩囤沌钝炖盹遁趸砘礅",
"qu": "区去取曲趋渠趣驱屈躯衢娶祛瞿岖龋觑朐蛐癯蛆苣阒诎劬蕖蘧氍黢蠼璩麴鸲磲",
"xu": "需许续须序徐休蓄畜虚吁绪叙旭邪恤墟栩絮圩婿戌胥嘘浒煦酗诩朐盱蓿溆洫顼勖糈砉醑",
"chuo": "辍绰戳淖啜龊踔辶",
"zu": "组族足祖租阻卒俎诅镞菹",
"ji": "济机其技基记计系期际及集级几给积极己纪即继击既激绩急奇吉季齐疾迹鸡剂辑籍寄挤圾冀亟寂暨脊跻肌稽忌饥祭缉棘矶汲畸姬藉瘠骥羁妓讥稷蓟悸嫉岌叽伎鲫诘楫荠戟箕霁嵇觊麂畿玑笈犄芨唧屐髻戢佶偈笄跽蒺乩咭赍嵴虮掎齑殛鲚剞洎丌墼蕺彐芰哜",
"cong": "从丛匆聪葱囱琮淙枞骢苁璁",
"zong": "总从综宗纵踪棕粽鬃偬枞腙",
"cou": "凑辏腠楱",
"cui": "衰催崔脆翠萃粹摧璀瘁悴淬啐隹毳榱",
"wei": "为位委未维卫围违威伟危味微唯谓伪慰尾魏韦胃畏帷喂巍萎蔚纬潍尉渭惟薇苇炜圩娓诿玮崴桅偎逶倭猥囗葳隗痿猬涠嵬韪煨艉隹帏闱洧沩隈鲔軎",
"cun": "村存寸忖皴",
"zuo": "作做座左坐昨佐琢撮祚柞唑嘬酢怍笮阼胙",
"zuan": "钻纂攥缵躜",
"da": "大达打答搭沓瘩惮嗒哒耷鞑靼褡笪怛妲",
"dai": "大代带待贷毒戴袋歹呆隶逮岱傣棣怠殆黛甙埭诒绐玳呔迨",
"tai": "大台太态泰抬胎汰钛苔薹肽跆邰鲐酞骀炱",
"ta": "他它她拓塔踏塌榻沓漯獭嗒挞蹋趿遢铊鳎溻闼",
"dan": "但单石担丹胆旦弹蛋淡诞氮郸耽殚惮儋眈疸澹掸膻啖箪聃萏瘅赕",
"lu": "路六陆录绿露鲁卢炉鹿禄赂芦庐碌麓颅泸卤潞鹭辘虏璐漉噜戮鲈掳橹轳逯渌蓼撸鸬栌氇胪镥簏舻辂垆",
"tan": "谈探坦摊弹炭坛滩贪叹谭潭碳毯瘫檀痰袒坍覃忐昙郯澹钽锬",
"ren": "人任认仁忍韧刃纫饪妊荏稔壬仞轫亻衽",
"jie": "家结解价界接节她届介阶街借杰洁截姐揭捷劫戒皆竭桔诫楷秸睫藉拮芥诘碣嗟颉蚧孑婕疖桀讦疥偈羯袷哜喈卩鲒骱",
"yan": "研严验演言眼烟沿延盐炎燕岩宴艳颜殷彦掩淹阎衍铅雁咽厌焰堰砚唁焉晏檐蜒奄俨腌妍谚兖筵焱偃闫嫣鄢湮赝胭琰滟阉魇酽郾恹崦芫剡鼹菸餍埏谳讠厣罨",
"dang": "当党档荡挡宕砀铛裆凼菪谠",
"tao": "套讨跳陶涛逃桃萄淘掏滔韬叨洮啕绦饕鼗",
"tiao": "条调挑跳迢眺苕窕笤佻啁粜髫铫祧龆蜩鲦",
"te": "特忑忒铽慝",
"de": "的地得德底锝",
"dei": "",
"di": "的地第提低底抵弟迪递帝敌堤蒂缔滴涤翟娣笛棣荻谛狄邸嘀砥坻诋嫡镝碲骶氐柢籴羝睇觌",
"ti": "体提题弟替梯踢惕剔蹄棣啼屉剃涕锑倜悌逖嚏荑醍绨鹈缇裼",
"tui": "推退弟腿褪颓蜕忒煺",
"you": "有由又优游油友右邮尤忧幼犹诱悠幽佑釉柚铀鱿囿酉攸黝莠猷蝣疣呦蚴莸莜铕宥繇卣牖鼬尢蚰侑",
"dian": "电点店典奠甸碘淀殿垫颠滇癫巅惦掂癜玷佃踮靛钿簟坫阽",
"tian": "天田添填甜甸恬腆佃舔钿阗忝殄畋栝掭",
"zhu": "主术住注助属逐宁著筑驻朱珠祝猪诸柱竹铸株瞩嘱贮煮烛苎褚蛛拄铢洙竺蛀渚伫杼侏澍诛茱箸炷躅翥潴邾槠舳橥丶瘃麈疰",
"nian": "年念酿辗碾廿捻撵拈蔫鲶埝鲇辇黏",
"diao": "调掉雕吊钓刁貂凋碉鲷叼铫铞",
"yao": "要么约药邀摇耀腰遥姚窑瑶咬尧钥谣肴夭侥吆疟妖幺杳舀窕窈曜鹞爻繇徭轺铫鳐崾珧",
"die": "跌叠蝶迭碟爹谍牒耋佚喋堞瓞鲽垤揲蹀",
"she": "设社摄涉射折舍蛇拾舌奢慑赦赊佘麝歙畲厍猞揲滠",
"ye": "业也夜叶射野液冶喝页爷耶邪咽椰烨掖拽曳晔谒腋噎揶靥邺铘揲",
"xie": "些解协写血叶谢械鞋胁斜携懈契卸谐泄蟹邪歇泻屑挟燮榭蝎撷偕亵楔颉缬邂鲑瀣勰榍薤绁渫廨獬躞",
"zhe": "这者着著浙折哲蔗遮辙辄柘锗褶蜇蛰鹧谪赭摺乇磔螫",
"ding": "定订顶丁鼎盯钉锭叮仃铤町酊啶碇腚疔玎耵",
"diu": "丢铥",
"ting": "听庭停厅廷挺亭艇婷汀铤烃霆町蜓葶梃莛",
"dong": "动东董冬洞懂冻栋侗咚峒氡恫胴硐垌鸫岽胨",
"tong": "同通统童痛铜桶桐筒彤侗佟潼捅酮砼瞳恸峒仝嗵僮垌茼",
"zhong": "中重种众终钟忠仲衷肿踵冢盅蚣忪锺舯螽夂",
"dou": "都斗读豆抖兜陡逗窦渎蚪痘蔸钭篼",
"du": "度都独督读毒渡杜堵赌睹肚镀渎笃竺嘟犊妒牍蠹椟黩芏髑",
"duan": "断段短端锻缎煅椴簖",
"dui": "对队追敦兑堆碓镦怼憝",
"rui": "瑞兑锐睿芮蕊蕤蚋枘",
"yue": "月说约越乐跃兑阅岳粤悦曰钥栎钺樾瀹龠哕刖",
"tun": "吞屯囤褪豚臀饨暾氽",
"hui": "会回挥汇惠辉恢徽绘毁慧灰贿卉悔秽溃荟晖彗讳诲珲堕诙蕙晦睢麾烩茴喙桧蛔洄浍虺恚蟪咴隳缋哕",
"wu": "务物无五武午吴舞伍污乌误亡恶屋晤悟吾雾芜梧勿巫侮坞毋诬呜钨邬捂鹜兀婺妩於戊鹉浯蜈唔骛仵焐芴鋈庑鼯牾怃圬忤痦迕杌寤阢",
"ya": "亚压雅牙押鸭呀轧涯崖邪芽哑讶鸦娅衙丫蚜碣垭伢氩桠琊揠吖睚痖疋迓岈砑",
"he": "和合河何核盖贺喝赫荷盒鹤吓呵苛禾菏壑褐涸阂阖劾诃颌嗬貉曷翮纥盍",
"wo": "我握窝沃卧挝涡斡渥幄蜗喔倭莴龌肟硪",
"en": "恩摁蒽",
"n": "嗯唔",
"er": "而二尔儿耳迩饵洱贰铒珥佴鸸鲕",
"fa": "发法罚乏伐阀筏砝垡珐",
"quan": "全权券泉圈拳劝犬铨痊诠荃醛蜷颧绻犭筌鬈悛辁畎",
"fei": "费非飞肥废菲肺啡沸匪斐蜚妃诽扉翡霏吠绯腓痱芾淝悱狒榧砩鲱篚镄",
"pei": "配培坏赔佩陪沛裴胚妃霈淠旆帔呸醅辔锫",
"ping": "平评凭瓶冯屏萍苹乒坪枰娉俜鲆",
"fo": "",
"hu": "和护许户核湖互乎呼胡戏忽虎沪糊壶葫狐蝴弧瑚浒鹄琥扈唬滹惚祜囫斛笏芴醐猢怙唿戽槲觳煳鹕冱瓠虍岵鹱烀轷",
"ga": "夹咖嘎尬噶旮伽尕钆尜",
"ge": "个合各革格歌哥盖隔割阁戈葛鸽搁胳舸疙铬骼蛤咯圪镉颌仡硌嗝鬲膈纥袼搿塥哿虼",
"ha": "哈蛤铪",
"xia": "下夏峡厦辖霞夹虾狭吓侠暇遐瞎匣瑕唬呷黠硖罅狎瘕柙",
"gai": "改该盖概溉钙丐芥赅垓陔戤",
"hai": "海还害孩亥咳骸骇氦嗨胲醢",
"gan": "干感赶敢甘肝杆赣乾柑尴竿秆橄矸淦苷擀酐绀泔坩旰疳澉",
"gang": "港钢刚岗纲冈杠缸扛肛罡戆筻",
"jiang": "将强江港奖讲降疆蒋姜浆匠酱僵桨绛缰犟豇礓洚茳糨耩",
"hang": "行航杭巷夯吭桁沆绗颃",
"gong": "工公共供功红贡攻宫巩龚恭拱躬弓汞蚣珙觥肱廾",
"hong": "红宏洪轰虹鸿弘哄烘泓訇蕻闳讧荭黉薨",
"guang": "广光逛潢犷胱咣桄",
"qiong": "穷琼穹邛茕筇跫蛩銎",
"gao": "高告搞稿膏糕镐皋羔锆杲郜睾诰藁篙缟槁槔",
"hao": "好号毫豪耗浩郝皓昊皋蒿壕灏嚎濠蚝貉颢嗥薅嚆",
"li": "理力利立里李历例离励礼丽黎璃厉厘粒莉梨隶栗荔沥犁漓哩狸藜罹篱鲤砺吏澧俐骊溧砾莅锂笠蠡蛎痢雳俪傈醴栎郦俚枥喱逦娌鹂戾砬唳坜疠蜊黧猁鬲粝蓠呖跞疬缡鲡鳢嫠詈悝苈篥轹",
"jia": "家加价假佳架甲嘉贾驾嫁夹稼钾挟拮迦伽颊浃枷戛荚痂颉镓笳珈岬胛袈郏葭袷瘕铗跏蛱恝哿",
"luo": "落罗络洛逻螺锣骆萝裸漯烙摞骡咯箩珞捋荦硌雒椤镙跞瘰泺脶猡倮蠃",
"ke": "可科克客刻课颗渴壳柯棵呵坷恪苛咳磕珂稞瞌溘轲窠嗑疴蝌岢铪颏髁蚵缂氪骒钶锞",
"qia": "卡恰洽掐髂袷咭葜",
"gei": "",
"gen": "根跟亘艮哏茛",
"hen": "很狠恨痕哏",
"gou": "构购够句沟狗钩拘勾苟垢枸篝佝媾诟岣彀缑笱鞲觏遘",
"kou": "口扣寇叩抠佝蔻芤眍筘",
"gu": "股古顾故固鼓骨估谷贾姑孤雇辜菇沽咕呱锢钴箍汩梏痼崮轱鸪牯蛊诂毂鹘菰罟嘏臌觚瞽蛄酤牿鲴",
"pai": "牌排派拍迫徘湃俳哌蒎",
"gua": "括挂瓜刮寡卦呱褂剐胍诖鸹栝呙",
"tou": "投头透偷愉骰亠",
"guai": "怪拐乖",
"kuai": "会快块筷脍蒯侩浍郐蒉狯哙",
"guan": "关管观馆官贯冠惯灌罐莞纶棺斡矜倌鹳鳏盥掼涫",
"wan": "万完晚湾玩碗顽挽弯蔓丸莞皖宛婉腕蜿惋烷琬畹豌剜纨绾脘菀芄箢",
"ne": "呢哪呐讷疒",
"gui": "规贵归轨桂柜圭鬼硅瑰跪龟匮闺诡癸鳜桧皈鲑刽晷傀眭妫炅庋簋刿宄匦",
"jun": "军均俊君峻菌竣钧骏龟浚隽郡筠皲麇捃",
"jiong": "窘炯迥炅冂扃",
"jue": "决绝角觉掘崛诀獗抉爵嚼倔厥蕨攫珏矍蹶谲镢鳜噱桷噘撅橛孓觖劂爝",
"gun": "滚棍辊衮磙鲧绲丨",
"hun": "婚混魂浑昏棍珲荤馄诨溷阍",
"guo": "国过果郭锅裹帼涡椁囗蝈虢聒埚掴猓崞蜾呙馘",
"hei": "黑嘿嗨",
"kan": "看刊勘堪坎砍侃嵌槛瞰阚龛戡凵莰",
"heng": "衡横恒亨哼珩桁蘅",
"mo": "万没么模末冒莫摩墨默磨摸漠脉膜魔沫陌抹寞蘑摹蓦馍茉嘿谟秣蟆貉嫫镆殁耱嬷麽瘼貊貘",
"peng": "鹏朋彭膨蓬碰苹棚捧亨烹篷澎抨硼怦砰嘭蟛堋",
"hou": "后候厚侯猴喉吼逅篌糇骺後鲎瘊堠",
"hua": "化华划话花画滑哗豁骅桦猾铧砉",
"huai": "怀坏淮徊槐踝",
"huan": "还环换欢患缓唤焕幻痪桓寰涣宦垸洹浣豢奂郇圜獾鲩鬟萑逭漶锾缳擐",
"xun": "讯训迅孙寻询循旬巡汛勋逊熏徇浚殉驯鲟薰荀浔洵峋埙巽郇醺恂荨窨蕈曛獯",
"huang": "黄荒煌皇凰慌晃潢谎惶簧璜恍幌湟蝗磺隍徨遑肓篁鳇蟥癀",
"nai": "能乃奶耐奈鼐萘氖柰佴艿",
"luan": "乱卵滦峦鸾栾銮挛孪脔娈",
"qie": "切且契窃茄砌锲怯伽惬妾趄挈郄箧慊",
"jian": "建间件见坚检健监减简艰践兼鉴键渐柬剑尖肩舰荐箭浅剪俭碱茧奸歼拣捡煎贱溅槛涧堑笺谏饯锏缄睑謇蹇腱菅翦戬毽笕犍硷鞯牮枧湔鲣囝裥踺搛缣鹣蒹谫僭戋趼楗",
"nan": "南难男楠喃囡赧腩囝蝻",
"qian": "前千钱签潜迁欠纤牵浅遣谦乾铅歉黔谴嵌倩钳茜虔堑钎骞阡掮钤扦芊犍荨仟芡悭缱佥愆褰凵肷岍搴箝慊椠",
"qiang": "强抢疆墙枪腔锵呛羌蔷襁羟跄樯戕嫱戗炝镪锖蜣",
"xiang": "向项相想乡象响香降像享箱羊祥湘详橡巷翔襄厢镶飨饷缃骧芗庠鲞葙蟓",
"jiao": "教交较校角觉叫脚缴胶轿郊焦骄浇椒礁佼蕉娇矫搅绞酵剿嚼饺窖跤蛟侥狡姣皎茭峤铰醮鲛湫徼鹪僬噍艽挢敫",
"zhuo": "着著缴桌卓捉琢灼浊酌拙茁涿镯淖啄濯焯倬擢斫棹诼浞禚",
"qiao": "桥乔侨巧悄敲俏壳雀瞧翘窍峭锹撬荞跷樵憔鞘橇峤诮谯愀鞒硗劁缲",
"xiao": "小效销消校晓笑肖削孝萧俏潇硝宵啸嚣霄淆哮筱逍姣箫骁枭哓绡蛸崤枵魈",
"si": "司四思斯食私死似丝饲寺肆撕泗伺嗣祀厮驷嘶锶俟巳蛳咝耜笥纟糸鸶缌澌姒汜厶兕",
"kai": "开凯慨岂楷恺揩锴铠忾垲剀锎蒈",
"jin": "进金今近仅紧尽津斤禁锦劲晋谨筋巾浸襟靳瑾烬缙钅矜觐堇馑荩噤廑妗槿赆衿卺",
"qin": "亲勤侵秦钦琴禽芹沁寝擒覃噙矜嗪揿溱芩衾廑锓吣檎螓",
"jing": "经京精境竞景警竟井惊径静劲敬净镜睛晶颈荆兢靖泾憬鲸茎腈菁胫阱旌粳靓痉箐儆迳婧肼刭弪獍",
"ying": "应营影英景迎映硬盈赢颖婴鹰荧莹樱瑛蝇萦莺颍膺缨瀛楹罂荥萤鹦滢蓥郢茔嘤璎嬴瘿媵撄潆",
"jiu": "就究九酒久救旧纠舅灸疚揪咎韭玖臼柩赳鸠鹫厩啾阄桕僦鬏",
"zui": "最罪嘴醉咀蕞觜",
"juan": "卷捐圈眷娟倦绢隽镌涓鹃鄄蠲狷锩桊",
"suan": "算酸蒜狻",
"yun": "员运云允孕蕴韵酝耘晕匀芸陨纭郧筠恽韫郓氲殒愠昀菀狁",
"qun": "群裙逡麇",
"ka": "卡喀咖咔咯佧胩",
"kang": "康抗扛慷炕亢糠伉钪闶",
"keng": "坑铿吭",
"kao": "考靠烤拷铐栲尻犒",
"ken": "肯垦恳啃龈裉",
"yin": "因引银印音饮阴隐姻殷淫尹荫吟瘾寅茵圻垠鄞湮蚓氤胤龈窨喑铟洇狺夤廴吲霪茚堙",
"kong": "空控孔恐倥崆箜",
"ku": "苦库哭酷裤枯窟挎骷堀绔刳喾",
"kua": "跨夸垮挎胯侉",
"kui": "亏奎愧魁馈溃匮葵窥盔逵睽馗聩喟夔篑岿喹揆隗傀暌跬蒉愦悝蝰",
"kuan": "款宽髋",
"kuang": "况矿框狂旷眶匡筐邝圹哐贶夼诳诓纩",
"que": "确却缺雀鹊阙瘸榷炔阕悫",
"kun": "困昆坤捆琨锟鲲醌髡悃阃",
"kuo": "扩括阔廓蛞",
"la": "拉落垃腊啦辣蜡喇剌旯砬邋瘌",
"lai": "来莱赖睐徕籁涞赉濑癞崃疠铼",
"lan": "兰览蓝篮栏岚烂滥缆揽澜拦懒榄斓婪阑褴罱啉谰镧漤",
"lin": "林临邻赁琳磷淋麟霖鳞凛拎遴蔺吝粼嶙躏廪檩啉辚膦瞵懔",
"lang": "浪朗郎廊狼琅榔螂阆锒莨啷蒗稂",
"liang": "量两粮良辆亮梁凉谅粱晾靓踉莨椋魉墚",
"lao": "老劳落络牢捞涝烙姥佬崂唠酪潦痨醪铑铹栳耢",
"mu": "目模木亩幕母牧莫穆姆墓慕牟牡募睦缪沐暮拇姥钼苜仫毪坶",
"le": "了乐勒肋叻鳓嘞仂泐",
"lei": "类累雷勒泪蕾垒磊擂镭肋羸耒儡嫘缧酹嘞诔檑",
"sui": "随岁虽碎尿隧遂髓穗绥隋邃睢祟濉燧谇眭荽",
"lie": "列烈劣裂猎冽咧趔洌鬣埒捩躐",
"leng": "冷愣棱楞塄",
"ling": "领令另零灵龄陵岭凌玲铃菱棱伶羚苓聆翎泠瓴囹绫呤棂蛉酃鲮柃",
"lia": "",
"liao": "了料疗辽廖聊寥缪僚燎缭撂撩嘹潦镣寮蓼獠钌尥鹩",
"liu": "流刘六留柳瘤硫溜碌浏榴琉馏遛鎏骝绺镏旒熘鹨锍",
"lun": "论轮伦仑纶沦抡囵",
"lv": "率律旅绿虑履吕铝屡氯缕滤侣驴榈闾偻褛捋膂稆",
"lou": "楼露漏陋娄搂篓喽镂偻瘘髅耧蝼嵝蒌",
"mao": "贸毛矛冒貌茂茅帽猫髦锚懋袤牦卯铆耄峁瑁蟊茆蝥旄泖昴瞀",
"long": "龙隆弄垄笼拢聋陇胧珑窿茏咙砻垅泷栊癃",
"nong": "农浓弄脓侬哝",
"shuang": "双爽霜孀泷",
"shu": "术书数属树输束述署朱熟殊蔬舒疏鼠淑叔暑枢墅俞曙抒竖蜀薯梳戍恕孰沭赎庶漱塾倏澍纾姝菽黍腧秫毹殳疋摅",
"shuai": "率衰帅摔甩蟀",
"lve": "略掠锊",
"ma": "么马吗摩麻码妈玛嘛骂抹蚂唛蟆犸杩",
"me": "么麽",
"mai": "买卖麦迈脉埋霾荬劢",
"man": "满慢曼漫埋蔓瞒蛮鳗馒幔谩螨熳缦镘颟墁鞔",
"mi": "米密秘迷弥蜜谜觅靡泌眯麋猕谧咪糜宓汨醚嘧弭脒冖幂祢縻蘼芈糸敉",
"men": "们门闷瞒汶扪焖懑鞔钔",
"mang": "忙盲茫芒氓莽蟒邙硭漭",
"meng": "蒙盟梦猛孟萌氓朦锰檬勐懵蟒蜢虻黾蠓艨甍艋瞢礞",
"miao": "苗秒妙描庙瞄缪渺淼藐缈邈鹋杪眇喵",
"mou": "某谋牟缪眸哞鍪蛑侔厶",
"miu": "缪谬",
"mei": "美没每煤梅媒枚妹眉魅霉昧媚玫酶镁湄寐莓袂楣糜嵋镅浼猸鹛",
"wen": "文问闻稳温纹吻蚊雯紊瘟汶韫刎璺玟阌",
"mie": "灭蔑篾乜咩蠛",
"ming": "明名命鸣铭冥茗溟酩瞑螟暝",
"na": "内南那纳拿哪娜钠呐捺衲镎肭",
"nei": "内那哪馁",
"nuo": "难诺挪娜糯懦傩喏搦锘",
"ruo": "若弱偌箬",
"nang": "囊馕囔曩攮",
"nao": "脑闹恼挠瑙淖孬垴铙桡呶硇猱蛲",
"ni": "你尼呢泥疑拟逆倪妮腻匿霓溺旎昵坭铌鲵伲怩睨猊",
"nen": "嫩恁",
"neng": "",
"nin": "您恁",
"niao": "鸟尿溺袅脲茑嬲",
"nie": "摄聂捏涅镍孽捻蘖啮蹑嗫臬镊颞乜陧",
"niang": "娘酿",
"ning": "宁凝拧泞柠咛狞佞聍甯",
"nu": "努怒奴弩驽帑孥胬",
"nv": "女钕衄恧",
"ru": "入如女乳儒辱汝茹褥孺濡蠕嚅缛溽铷洳薷襦颥蓐",
"nuan": "",
"nve": "虐疟",
"re": "热若惹喏",
"ou": "区欧偶殴呕禺藕讴鸥瓯沤耦怄",
"pao": "跑炮泡抛刨袍咆疱庖狍匏脬",
"pou": "剖掊裒",
"pen": "喷盆湓",
"pie": "瞥撇苤氕丿",
"pin": "品贫聘频拼拚颦姘嫔榀牝",
"se": "色塞瑟涩啬穑铯槭",
"qing": "情青清请亲轻庆倾顷卿晴氢擎氰罄磬蜻箐鲭綮苘黥圊檠謦",
"zan": "赞暂攒堑昝簪糌瓒錾趱拶",
"shao": "少绍召烧稍邵哨韶捎勺梢鞘芍苕劭艄筲杓潲",
"sao": "扫骚嫂梢缫搔瘙臊埽缲鳋",
"sha": "沙厦杀纱砂啥莎刹杉傻煞鲨霎嗄痧裟挲铩唼歃",
"xuan": "县选宣券旋悬轩喧玄绚渲璇炫萱癣漩眩暄煊铉楦泫谖痃碹揎镟儇",
"ran": "然染燃冉苒髯蚺",
"rang": "让壤攘嚷瓤穰禳",
"rao": "绕扰饶娆桡荛",
"reng": "仍扔",
"ri": "",
"rou": "肉柔揉糅鞣蹂",
"ruan": "软阮朊",
"run": "润闰",
"sa": "萨洒撒飒卅仨脎",
"suo": "所些索缩锁莎梭琐嗦唆唢娑蓑羧挲桫嗍睃",
"sai": "思赛塞腮噻鳃",
"shui": "说水税谁睡氵",
"sang": "桑丧嗓搡颡磉",
"sen": "",
"seng": "",
"shai": "筛晒",
"shang": "上商尚伤赏汤裳墒晌垧觞殇熵绱",
"xing": "行省星腥猩惺兴刑型形邢饧醒幸杏性姓陉荇荥擤悻硎",
"shou": "收手受首售授守寿瘦兽狩绶艏扌",
"shuo": "说数硕烁朔铄妁槊蒴搠",
"su": "速素苏诉缩塑肃俗宿粟溯酥夙愫簌稣僳谡涑蔌嗉觫",
"shua": "刷耍唰",
"shuan": "栓拴涮闩",
"shun": "顺瞬舜吮",
"song": "送松宋讼颂耸诵嵩淞怂悚崧凇忪竦菘",
"sou": "艘搜擞嗽嗖叟馊薮飕嗾溲锼螋瞍",
"sun": "损孙笋荪榫隼狲飧",
"teng": "腾疼藤滕誊",
"tie": "铁贴帖餮萜",
"tu": "土突图途徒涂吐屠兔秃凸荼钍菟堍酴",
"wai": "外歪崴",
"wang": "王望往网忘亡旺汪枉妄惘罔辋魍",
"weng": "翁嗡瓮蓊蕹",
"zhua": "抓挝爪",
"yang": "样养央阳洋扬杨羊详氧仰秧痒漾疡泱殃恙鸯徉佯怏炀烊鞅蛘",
"xiong": "雄兄熊胸凶匈汹芎",
"yo": "哟唷",
"yong": "用永拥勇涌泳庸俑踊佣咏雍甬镛臃邕蛹恿慵壅痈鳙墉饔喁",
"za": "杂扎咱砸咋匝咂拶",
"zai": "在再灾载栽仔宰哉崽甾",
"zao": "造早遭枣噪灶燥糟凿躁藻皂澡蚤唣",
"zei": "",
"zen": "怎谮",
"zeng": "增曾综赠憎锃甑罾缯",
"zhei": "",
"zou": "走邹奏揍诹驺陬楱鄹鲰",
"zhuai": "转拽",
"zun": "尊遵鳟樽撙",
"dia": "",
"nou": ""
};
window.pinyin_dict_withtone = "yī,dīng zhēng,kǎo qiǎo yú,qī,shàng,xià,hǎn,wàn mò,zhàng,sān,shàng shǎng,xià,qí jī,bù fǒu,yǔ yù yú,miǎn,gài,chǒu,chǒu,zhuān,qiě jū,pī,shì,shì,qiū,bǐng,yè,cóng,dōng,sī,chéng,diū,qiū,liǎng,diū,yǒu,liǎng,yán,bìng,sāng sàng,gǔn,jiū,gè gě,yā,pán,zhōng zhòng,jǐ,jiè,fēng,guàn kuàng,chuàn,chǎn,lín,zhuó,zhǔ,bā,wán,dān,wéi wèi,zhǔ,jǐng,lì lí,jǔ,piě,fú,yí jí,yì,nǎi,wǔ,jiǔ,jiǔ,tuō zhé,me yāo mó ma,yì,yī,zhī,wū,zhà,hū,fá,lè yuè,yín,pīng,pāng,qiáo,hǔ,guāi,chéng shèng,chéng shèng,yǐ,háo yǐ,yǐ,miē niè,jiǔ,qǐ,yě,xí,xiāng,gài,jiǔ,xià,hù,shū,dǒu,shǐ,jī,náng,jiā,none,shí,none,hū,mǎi,luàn,none,rǔ,xué,yǎn,fǔ,shā,nǎ,qián,suǒ,yú,zhù,zhě,qián gān,zhì luàn,guī,qián,luàn,lǐn lìn,yì,jué,le liǎo,gè mā,yú yǔ,zhēng,shì,shì,èr,chù,yú,kuī,yú,yún,hù,qí,wǔ,jǐng,sì,suì,gèn,gèn,yà,xiē suò,yà,qí zhāi,yā yà,jí qì,tóu,wáng wú,kàng,dà,jiāo,hài,yì,chǎn,hēng pēng,mǔ,ye,xiǎng,jīng,tíng,liàng,xiǎng,jīng,yè,qīn qìng,bó,yòu,xiè,dǎn dàn,lián,duǒ,wěi mén,rén,rén,jí,jí,wáng,yì,shén shí,rén,lè,dīng,zè,jǐn jìn,pū pú,chóu qiú,bā,zhǎng,jīn,jiè,bīng,réng,cóng zòng,fó,jīn sǎn,lún,bīng,cāng,zī zǐ zǎi,shì,tā,zhàng,fù,xiān,xiān,tuō chà duó,hóng,tóng,rèn,qiān,gǎn hàn,yì gē,bó,dài,líng lǐng lìng,yǐ,chào,cháng zhǎng,sā,cháng,yí,mù,mén,rèn,fǎn,chào miǎo,yǎng áng,qián,zhòng,pǐ pí,wò,wǔ,jiàn,jià jiè jie,yǎo fó,fēng,cāng,rèn rén,wáng,fèn bīn,dī,fǎng,zhōng,qǐ,pèi,yú,diào,dùn,wěn,yì,xǐn,kàng,yī,jí,ài,wǔ,jì qí,fú,fá,xiū xǔ,jìn yín,pī,dǎn,fū,tǎng,zhòng,yōu,huǒ,huì kuài,yǔ,cuì,yún,sǎn,wěi,chuán zhuàn,chē jū,yá,qiàn,shāng,chāng,lún,cāng chen,xùn,xìn,wěi,zhù,chǐ,xián xuán,nú nǔ,bó bǎi bà,gū gù,nǐ,nǐ nì,xiè,bàn,xù,líng,zhòu,shēn,qū,sì cì,bēng,sì shì,qié jiā gā,pī,yì,sì,yǐ chì,zhēng,diàn tián,hān gàn,mài,dàn,zhù,bù,qū,bǐ,zhāo shào,cǐ,wèi,dī,zhù,zuǒ,yòu,yǎng,tǐ tī bèn,zhàn diān,hé hē hè,bì,tuó,shé,yú,yì dié,fó fú bì bó,zuò,gōu kòu,nìng,tóng,nǐ,xiān,qú,yōng yòng,wǎ,qiān,yòu,kǎ,bāo,pèi,huí huái,gé,lǎo,xiáng,gé,yáng,bǎi,fǎ,mǐng,jiā,èr nài,bìng,jí,hěn,huó,guǐ,quán,tiāo,jiǎo,cì,yì,shǐ,xíng,shēn,tuō,kǎn,zhí,gāi,lái,yí,chǐ,kuǎ,gōng,lì,yīn,shì,mǐ,zhū,xù,yòu,ān,lù,móu,ér,lún,dòng tóng tǒng,chà,chì,xùn,gōng gòng,zhōu,yī,rú,cún jiàn,xiá,sì,dài,lǚ,ta,jiǎo yáo,zhēn,cè zè zhāi,qiáo,kuài,chái,nìng,nóng,jǐn,wǔ,hóu hòu,jiǒng,chěng tǐng,zhèn zhēn,zuò,hào,qīn,lǚ,jú,shù dōu,tǐng,shèn,tuó tuì,bó,nán,xiāo,biàn pián,tuǐ,yǔ,xì,cù,é,qiú,xú,guàng,kù,wù,jùn,yì,fǔ,liáng,zǔ,qiào xiào,lì,yǒng,hùn,jìng,qiàn,sàn,pěi,sú,fú,xī,lǐ,fǔ,pīng,bǎo,yú yù shù,sì qí,xiá,xìn shēn,xiū,yǔ,dì,chē jū,chóu,zhì,yǎn,liǎ,lì,lái,sī,jiǎn,xiū,fǔ,huò,jù,xiào,pái,jiàn,biào,chù tì,fèi,fèng,yà,ǎn,bèi,yù,xīn,bǐ,hǔ chí,chāng,zhī,bìng,jiù,yáo,cuì zú,liǎ,wǎn,lái,cāng,zǒng,gè gě,guān,bèi,tiǎn,shū,shū,mén,dǎo dào,tán tàn,jué juè,chuí,xìng,péng,tǎng cháng,hòu,yǐ,qī,tì,gàn,liàng jìng,jiè,suī,chàng chāng,jié,fǎng,zhí,kōng kǒng,juàn,zōng,jù,qiàn,ní,lún,zhuō,wō wēi,luǒ,sōng,lèng,hùn,dōng,zì,bèn,wǔ,jù,nǎi,cǎi,jiǎn,zhài,yē,zhí,shà,qīng,nìng,yīng,chēng chèn,qián,yǎn,ruǎn,zhòng tóng,chǔn,jiǎ jià,jì jié,wěi,yú,bǐng bìng,ruò,tí,wēi,piān,yàn,fēng,tǎng dàng,wò,è,xié,chě,shěng,kǎn,dì,zuò,chā,tíng,bèi,xiè,huáng,yǎo,zhàn,chǒu qiào,ān,yóu,jiàn,xū,zhā,cī,fù,bī,zhì,zǒng,miǎn,jí,yǐ,xiè,xún,cāi sī,duān,cè zè zhāi,zhēn,ǒu,tōu,tōu,bèi,zá zǎ,lǚ lóu,jié,wěi,fèn,cháng,kuǐ guī,sǒu,zhì sī,sù,xiā,fù,yuàn yuán,rǒng,lì,nù,yùn,jiǎng gòu,mà,bàng,diān,táng,hào,jié,xī xì,shān,qiàn jiān,què jué,cāng chen,chù,sǎn,bèi,xiào,róng,yáo,tà tàn,suō,yǎng,fá,bìng,jiā,dǎi,zài,tǎng,gǔ,bīn,chǔ,nuó,cān càn,lěi,cuī,yōng,zāo cáo,zǒng,péng,sǒng,ào,chuán zhuàn,yǔ,zhài,qī còu,shāng,chuǎng,jìng,chì,shǎ,hàn,zhāng,qīng,yān yàn,dì,xiè,lǚ lóu,bèi,piào biāo,jǐn jìn,liàn,lù,màn,qiān,xiān,tǎn tàn,yíng,dòng,zhuàn,xiàng,shàn,qiáo,jiǒng,tuǐ tuí,zǔn,pú,xī,láo,chǎng,guāng,liáo,qī,chēng dēng,zhàn zhuàn chán,wěi,jī,bō,huì,chuǎn,tiě jiàn,dàn,jiǎo yáo,jiù,sēng,fèn,xiàn,yù jú,è wù wū,jiāo,jiàn,tóng zhuàng,lǐn,bó,gù,xiān,sù,xiàn,jiāng,mǐn,yè,jìn,jià jie,qiào,pì,fēng,zhòu,ài,sài,yí,jùn,nóng,chán tǎn shàn,yì,dāng dàng,jǐng,xuān,kuài,jiǎn,chù,dān dàn,jiǎo,shǎ,zài,càn,bīn bìn,án àn,rú,tái,chóu,chái,lán,nǐ yì,jǐn,qiàn,méng,wǔ,níng,qióng,nǐ,cháng,liè,lěi,lǚ,kuǎng,bào,yù,biāo,zǎn,zhì,sì,yōu,háo,qìng,chèn,lì,téng,wěi,lǒng lóng lòng,chǔ,chán chàn,ráng xiāng,shū,huì xié,lì,luó,zǎn,nuó,tǎng,yǎn,léi,nàng nāng,ér,wù,yǔn,zān,yuán,xiōng,chōng,zhào,xiōng,xiān,guāng,duì ruì yuè,kè,duì ruì yuè,miǎn,tù,cháng zhǎng,ér,duì ruì yuè,ér,qīn,tù,sì,yǎn,yǎn,shǐ,shí kè,dǎng,qiān,dōu,fēn,máo,shēn,dōu,bǎi kè,jīng,lǐ,huǎng,rù,wáng,nèi,quán,liǎng,yú shù,bā,gōng,liù lù,xī,han,lán,gòng gōng,tiān,guān,xīng xìng,bīng,qí jī,jù,diǎn,zī cí,fēn,yǎng,jiān,shòu,jì,yì,jì,chǎn,jiōng,mào,rǎn,nèi nà,yuán,mǎo,gāng,rǎn,cè,jiōng,cè,zài,guǎ,jiǒng,mào,zhòu,mào mò,gòu,xú,miǎn,mì,rǒng,yín yóu,xiě,kǎn,jūn,nóng,yí,mí,shì,guān guàn,měng,zhǒng,zuì,yuān,míng,kòu,lín,fù,xiě,mì,bīng,dōng,tài,gāng,féng píng,bīng,hù,chōng chòng,jué,yà,kuàng,yě,lěng,pàn,fā,mǐn,dòng,xiǎn,liè,qià,jiān,jìng chēng,sōu,měi,tú,qī,gù,zhǔn,sōng,jìng chēng,liáng liàng,qìng,diāo,líng,dòng,gàn,jiǎn,yīn,còu,ái,lì,cāng,mǐng,zhǔn,cuī,sī,duó,jìn,lǐn,lǐn,níng,xī,dú,jī jǐ,fán,fán,fán,fèng,jū,chù chǔ,zhēng,fēng,mù,zhǐ,fú,fēng,píng,fēng,kǎi,huáng,kǎi,gān,dèng,píng,kǎn qiǎn,xiōng,kuài,tū,āo wā,chū,jī,dàng,hán,hán,záo,dāo,diāo,dāo,rèn,rèn,chuāng,fēn fèn,qiē qiè,yì,jī,kān,qiàn,cǔn,chú,wěn,jī,dǎn,xíng,huá huà,wán,jué,lí,yuè,liè,liú,zé,gāng,chuàng chuāng,fú,chū,qù,diāo,shān,mǐn,líng,zhōng,pàn,bié biè,jié,jié,páo bào,lì,shān,bié biè,chǎn chàn,jǐng,guā,gēng,dào,chuàng,kuī,kū,duò,èr,zhì,shuā shuà,quàn xuàn,chà shā,cì cī,kè,jié,guì,cì,guì,kǎi,duò,jì,tì,jǐng,dōu,luǒ,zé,yuān,cuò,xiāo xuē,kēi kè,là lá,qián,chà shā,chuàng,guǎ,jiàn,cuò,lí,tī,fèi,pōu,chǎn chàn,qí,chuàng,zì,gāng,wān,bāo bō,jī,duō,qíng,yǎn shàn,dū zhuó,jiàn,jì,bāo bō,yān,jù,huò,shèng,jiǎn,duó,zhì duān,wū,guǎ,fù pì,shèng,jiàn,gē,dá zhá,kǎi,chuàng chuāng,chuán,chǎn,tuán zhuān,lù jiū,lí,pēng,shān,piāo,kōu,jiǎo chāo,guā,qiāo,jué,huá huà,zhā zhá,zhuó,lián,jù,pī pǐ,liú,guì,jiǎo chāo,guì,jiàn,jiàn,tāng,huō,jì,jiàn,yì,jiàn,zhì,chán,zuān,mó,lí,zhú,lì,yà,quàn,bàn,gōng,jiā,wù,mài,liè,jìn jìng,kēng,xié liè,zhǐ,dòng,zhù chú,nǔ,jié,qú,shào,yì,zhǔ,miǎo,lì,jìn jìng,láo,láo,juàn,kǒu,yáng,wā,xiào,móu,kuāng,jié,liè,hé,shì,kè,jìn jìng,gào,bó bèi,mǐn,chì,láng,yǒng,yǒng,miǎn,kè,xūn,juàn juān,qíng,lù,bù,měng,chì,lè lēi,kài,miǎn,dòng,xù,xù,kān,wù,yì,xūn,wěng yǎng,shèng,láo,mù,lù,piāo,shì,jì,qín,jiàng,jiǎo chāo,quàn,xiàng,yì,qiāo,fān,juān,tóng dòng,jù,dān,xié,mài,xūn,xūn,lǜ,lì,chè,ráng xiāng,quàn,bāo,sháo,yún,jiū,bào,gōu gòu,wù,yún,none,xiōng,gài,gài,bāo,cōng,yì,xiōng,pēng,jū,táo yáo,gé,pú,è,páo,fú,gōng,dá,jiù,gōng,bǐ,huà huā,běi bèi,nǎo,chí shi,fāng,jiù,yí,zā,jiàng,kàng,jiàng,kuāng,hū,xiá,qū,fán,guǐ,qiè,zāng cáng,kuāng,fěi,hū,yǔ,guǐ,kuì guì,huì,dān,kuì guì,lián,lián,suǎn,dú,jiù,jué,xì,pǐ,qū ōu,yī,kē qià,yǎn yàn,biǎn,nì,qū ōu,shí,xùn,qiān,niàn,sà,zú,shēng,wǔ,huì,bàn,shì,xì,wàn,huá huà huā,xié,wàn,bēi,zú cù,zhuó,xié,dān shàn chán,mài,nán nā,dān,jí,bó,shuài lǜ,bǔ bo,guàn kuàng,biàn,bǔ,zhān zhàn,qiǎ kǎ,lú,yǒu,lǔ,xī,guà,wò,xiè,jié,jié,wèi,yǎng áng,qióng,zhī,mǎo,yìn,wēi,shào,jí,què,luǎn,chǐ,juàn juǎn,xiè,xù,jǐn,què,wù,jí,è,qīng,xī,sān,chǎng ān hàn,wēi yán,è,tīng,lì,zhé zhái,hàn àn,lì,yǎ,yā yà,yàn,shè,dǐ,zhǎ zhǎi,páng,none,qiè,yá,zhì shī,cè,máng,tí,lí,shè,hòu,tīng,zuī,cuò,fèi,yuán,cè,yuán,xiāng,yǎn,lì,jué,shà xià,diān,chú,jiù,jǐn,áo,guǐ,yàn,sī,lì,chǎng,qiān lán,lì,yán,yǎn,yuán,sī mǒu,gōng hóng,lín miǎo,róu qiú,qù,qù,none,lěi,dū,xiàn xuán,zhuān,sān,cān shēn cēn sān,cān shēn cēn sān,cān shēn cēn sān,cān shēn cēn sān,ài yǐ,dài,yòu,chā chá chǎ,jí,yǒu,shuāng,fǎn,shōu,guái,bá,fā fà,ruò,lì,shū,zhuó yǐ lì jué,qǔ,shòu,biàn,xù,jiǎ,pàn,sǒu,jí,wèi yù,sǒu,dié,ruì,cóng,kǒu,gǔ,jù gōu,lìng,guǎ,tāo dāo,kòu,zhī zhǐ,jiào,zhào shào,bā,dīng,kě kè,tái tāi,chì,shǐ,yòu,qiú,pǒ,yè xié,hào háo,sī,tàn,chǐ,lè,diāo,jī,none,hōng hóng,miē,xū yù,máng,chī,gè gě,xuān sòng,yāo,zǐ,hé gě,jí,diào,dòu cùn,tóng tòng,míng,hòu,lì,tǔ tù,xiàng,zhà zhā,xià hè,yē,lǚ,yā ā,ma má mǎ,ǒu,huō,yī,jūn,chǒu,lìn,tūn,yín,fèi,pǐ bǐ,qìn,qìn,jiè gè,bù,fǒu pǐ,bā ba,dūn,fēn,é huā,hán,tīng,háng kēng,shǔn,qǐ,hóng,zhī zī,yǐn shěn,wú,wú,chǎo chāo,nà nè,xuè chuò jué,xī,chuī,dōu rú,wěn,hǒu,hǒu hōng ōu,wú yù,gào,yā ya,jùn,lǚ,è,gé,wěn,dāi,qǐ,chéng,wú,gào,fū,jiào,hōng,chǐ,shēng,nà nè,tūn tiān,fǔ,yì,dāi,ǒu ōu òu,lì,bei bài,yuán yún yùn,wā guǎ guō,huá qì,qiāng qiàng,wū,è,shī,juǎn,pěn,wěn mǐn,ní ne,m,líng,rán,yōu,dǐ,zhōu,shì,zhòu,tiè chè,xì,yì,qì zhī,píng,zǐ cī,guā gū guǎ,zī cī,wèi,xǔ hǒu gòu,hē a kē,náo,xiā,pēi,yì,xiāo háo,shēn,hū,mìng,dá dàn,qū,jǔ zuǐ,xián gān,zā,tuō,duō,pǒu,páo,bì,fú,yǎng,hé hè,zǎ zé zhā,hé hè huó huò hú,hāi,jiù,yǒng,fù,dā,zhòu,wǎ,kǎ,gū,kā gā,zuo,bù,lóng,dōng,níng,tuō,sī,xiàn xián,huò,qì,èr,è,guāng,zhà,dié xī,yí,liě liē lié lie,zī,miē,mī,zhǐ,yǎo,jī xī qià,zhòu,kǎ luò gē,shù xún,zá zǎ,xiào,ké hāi,huī,kuā,huài shì,táo,xián,è àn,xuǎn xuān,xiū,wā guǎ guō,yān yàn yè,lǎo,yī,āi,pǐn,shěn,tóng,hōng hǒng hòng,xiōng,duō,wā wa,hā hǎ hà,zāi,yòu,diè dì,pài,xiǎng,āi,gén hěn,kuāng,yǎ yā,dā,xiāo,bì,yuě huì,nián,huá huā,xíng,kuài,duǒ,fēn,jì jiē zhāi,nóng,mōu,yō yo,hào,yuán yún yùn,lòng,pǒu,máng,gē,ó ò é,chī,shào,li lǐ lī,nǎ něi na né,zú,hè,kū,xiào,xiàn,láo,pò bā bō,zhé,zhā,liàng láng,bā,miē,liè lǜ,suī,fú,bǔ,hān,hēng,gěng,chuò yuè,gě jiā,yòu,yàn,gū,gū,bei bài,hán hàn,suō,chún,yì,āi ài,jiá qiǎn,tǔ tù,dàn xián yán,wǎn,lì,xī,táng,zuò,qiú,chē,wù wú ń,zào,yǎ,dōu,qǐ,dí,qìn,mà,none,gòng hǒng gǒng,dǒu,none,lào láo,liǎng,suǒ,zào,huàn,léng,shā,jī,zǔ,wō wěi,fěng,jìn yín,hǔ xià,qì,shòu,wéi,shuā,chàng,ér wā,lì,qiàng,ǎn,jiè zé jí,yō,niàn,yū,tiǎn,lài,shà,xī,tuò,hū,ái,zhōu zhāo tiào,gòu,kěn,zhuó,zhuó zhào,shāng,dí,hèng,lán lín,a ā á ǎ à,cǎi,qiāng,zhūn tūn xiāng duǐ,wǔ,wèn,cuì qi,shà jié dié tì,gǔ,qǐ,qǐ,táo,dàn,dàn,yuē wā,zǐ cǐ,bǐ tú,cuì,chuò chuài,hé,yǎ yā,qǐ,zhé,fēi,liǎng,xián,pí,shá,lā la,zé,qíng yīng,guà,pā,zé shì,sè,zhuàn,niè,guō,luō luó luo,yán,dī,quán,tān chǎn tuō,bo,dìng,lāng,xiào,none,táng,chì,tí,ān án,jiū,dàn,kā,yóng,wèi,nán,shàn,yù,zhé,lǎ,jiē,hóu,hǎn,dié zhá,zhōu,chái,wāi,nuò rě,huò guó xù,yīn,zá zǎ,yāo,ō wō,miǎn,hú,yǔn,chuǎn,huì,huàn,huàn yuán xuǎn hé,xǐ,hē hè yè,jī,kuì,zhǒng chuáng,wéi wèi,shà,xǔ,huáng,duó zhà,yán,xuān,liàng,yù,sāng sàng,chī,qiáo jiāo,yàn,dān shàn chán,pèn bēn,cān sūn qī,lí,yō yo,zhā chā,wēi,miāo,yíng,pēn pèn,bǔ,kuí,xí,yù,jiē,lóu lou,kù,zào qiāo,hù,tí,yáo,hè xiāo xiào hù,shà á,xiù,qiāng qiàng,sè,yōng,sù,gòng hǒng gǒng,xié,yì ài,suō,má mǎ ma,chā,hài,kē kè,tà dā,sǎng,chēn,rù,sōu,wā gǔ,jī,bēng pǎng,wū,xián qiàn qiè,shì,gé,zī,jiē,lào,wēng,wà,sì,chī,háo,suō,jiā lún,hāi hēi,suǒ,qín,niè,hē,zi,sǎi,ň,gě,ná,diǎ,ǎi ài āi,qiāng,tōng,bì,áo,áo,lián,zuī suī,zhē zhè zhù zhe,mò,sòu,sǒu,tǎn,dí,qī,jiào,chōng,jiào dǎo,kǎi gě,tàn,shān càn,cáo,jiā,ái,xiào,piāo,lóu lou,gā gá gǎ,gǔ,xiāo jiāo,hū,huì,guō,ǒu,xiān,zé,cháng,xū shī,pó,dē dēi,ma má,mà,hú,lei lē,dū,gā gá gǎ,tāng,yě,bēng,yīng,sāi,jiào,mì,xiào,huá huā,mǎi,rán,zuō,pēng,lào láo,xiào,jī,zhǔ,cháo zhāo,kuì,zuǐ,xiāo,sī,háo,fǔ ,liáo,qiáo qiào,xī,chù xù shòu,tān chǎn,dàn tán,hēi mò,xùn,ě,zūn,fān bo,chī,huī,zǎn,chuáng,cù zā hé,dàn,jué,tūn kuò,cēng,jiào,yē,xī,qì,háo,lián,xū shī,dēng,huī,yín,pū,juē,qín,xún,niè,lū,sī,yǎn,yīng,dā,zhān,ō,zhòu zhuó,jìn,nóng,yuě huì,xiè,qì,è,zào,yī,shì,jiào qiào chī,yuàn,ǎi ài āi,yōng yǒng,jué xué,kuài,yǔ,pēn pèn,dào,gá,xīn hěn hèn,dūn,dāng,xīn,sāi,pī,pǐ,yīn,zuǐ,níng,dí,làn,tà,huò ǒ,rú,hāo,hè xià,yàn,duō,xiù pì,zhōu chóu,jì jiē zhāi,jìn,háo,tì,cháng,xūn,mē,cā chā,tì,lū,huì,bó pào bào,yōu,niè,yín,hù,mèi me mò,hōng,zhé,lí,liú,xié hái,náng,xiāo,mō,yàn,lì,lú,lóng,pó,dàn,chèn,pín,pǐ,xiàng,huò,mè,xī,duǒ,kù,yán,chán,yīng,rǎng rāng,diǎn,lá,tà,xiāo,jiáo jué jiào,chuò,huàn huān,huò,zhuàn,niè,xiāo,zá cà,lí,chǎn,chài,lì,yì,luō luó luo,náng nāng,zá zàn cān,sū,xǐ,zèng,jiān,yàn zá niè,zhǔ,lán,niè,nāng,lǎn,luó luō luo,wéi guó,huí,yīn,qiú,sì,nín,jiǎn nān,huí,xìn,yīn,nān,tuán,tuán,dùn tún,kàng,yuān,jiǒng,piān,yún,cōng,hú,huí,yuán,é,guó,kùn,cōng,wéi tōng,tú,wéi,lún,guó,qūn,rì,líng,gù,guó,tāi,guó,tú,yòu,guó,yín,hùn,pǔ,yǔ,hán,yuán,lún,quān juàn juān,yǔ,qīng,guó,chuán chuí,wéi,yuán,quān juàn juān,kū,pǔ,yuán,yuán,yà,tuān,tú,tú,tuán,lüè,huì,yì,huán yuán,luán,luán,tǔ,yà,tǔ,tǐng,shèng,pú,lù,kuài,yā,zài,wéi xū,gē,yù zhūn,wū,guī,pǐ,yí,dì de,qiān sú,qiān,zhèn,zhuó,dàng,qià,xià,shān,kuàng,cháng chǎng,qí yín,niè,mò,jī,jiá,zhǐ,zhǐ zhì,bǎn,xūn,yì,qǐn,méi fén,jūn,rǒng kēng,tún dùn,fāng fáng,bèn fèn,bèn,tān,kǎn,huài pēi pī péi,zuò,kēng,bì,jǐng,dì làn,jīng,jì,kuài,dǐ,jīng,jiān,tán,lì,bà,wù,fén,zhuì,pō,pǎn bàn,táng,kūn,qū,tǎn,zhǐ,tuó,gān,píng,diàn,guà,ní,tái,pī,jiōng,yǎng,fó,ào,lù,qiū,mù mǔ,kē kě,gòu,xuè,fá,dǐ chí,chè,líng,zhù,fù,hū,zhì,chuí,lā,lǒng,lǒng,lú,ào,dài,páo,mín,xíng,dòng tóng,jì,hè,lǜ,cí,chǐ,lěi,gāi,yīn,hòu,duī,zhào,fú,guāng,yáo,duǒ duò,duǒ duò,guǐ,chá,yáng,yín,fá,gòu,yuán,dié,xié,kěn,shǎng,shǒu,è,bìng,diàn,hóng,yà,kuǎ,dá,kǎ,dàng,kǎi,háng,nǎo,ǎn,xīng,xiàn,yuàn huán,bāng,póu fú,bà,yì,yìn,hàn,xù,chuí,cén,gěng,āi,běng fēng,dì fáng,què jué,yǒng,jùn,xiá jiā,dì,mái mán,làng,juǎn,chéng,yán shān,qín jīn,zhé,liè,liè,pǔ bù,chéng,huā,bù,shí,xūn,guō,jiōng,yě,niàn,dī,yù,bù,yà,quán,suì sù,pí pì,qīng zhēng,wǎn wān,jù,lǔn,zhēng chéng,kōng,chǒng shǎng,dōng,dài,tán tàn,ǎn,cǎi cài,chù tòu,běng,xiàn kǎn,zhí,duǒ,yì shì,zhí,yì,péi,jī,zhǔn,qí,sào sǎo,jù,ní,kū,kè,táng,kūn,nì,jiān,duī,jīn,gāng,yù,è,péng bèng,gù,tù,lèng líng,fāng,yá,qiàn zàn jiàn,kūn,àn,shēn,duò huī,nǎo,tū,chéng,yīn,huán,bì,liàn,guō,dié,zhuàn,hòu,bǎo bǔ pù,bǎo,yú,dī,máo móu wǔ,jiē,ruán,è ài yè,gèng,kān,zōng,yú,huáng,è,yáo,yàn,bào,jí,méi,cháng chǎng,dǔ,tuó,yìn,féng,zhòng,jiè,jīn,fēng,gāng,chuǎn,jiǎn,píng,lěi,jiǎng,huāng,léng,duàn,wān,xuān,jì,jí,kuài,yíng,tā,chéng,yǒng,kǎi,sù,sù,shí,mì,tǎ,wěng,chéng,tú,táng,què,zhǒng,lì,péng,bàng,sāi sài sè,zàng,duī,tián,wù,zhèng,xūn,gé,zhèn,ài,gōng,yán,xiàn,tián zhèn,yuán,wēn,xiè,liù,hǎi,lǎng,cháng chǎng,péng,bèng,chén,lù,lǔ,ōu qiū,qiàn zàn jiàn,méi,mò,zhuān tuán,shuǎng,shú,lǒu,chí,màn,biāo,jìng,qī,shù,zhì dì,zhàng,kàn,yōng,diàn,chěn,zhǐ zhuó,xì,guō,qiǎng,jìn,dì,shāng,mù,cuī,yàn,tǎ,zēng,qián,qiáng,liáng,wèi,zhuì,qiāo,zēng,xū,shàn,shàn,fá,pú,kuài tuí,tuǎn dǒng,fán,qiáo què,mò,dūn,dūn,zūn dūn,dì,shèng,duò huī,duò,tán,dèng,wú,fén,huáng,tán,dā,yè,zhù,jiàn,ào,qiáng,jī,qiāo áo,kěn,yì tú,pí,bì,diàn,jiāng,yě,yōng,xué bó jué,tán,lǎn,jù,huài,dàng,rǎng,qiàn,xūn,xiàn làn,xǐ,hè,ài,yā yà,dǎo,háo,ruán,jìn,lěi,kuàng,lú,yán,tán,wéi,huài,lǒng,lǒng,ruǐ,lì,lín,rǎng,chán,xūn,yán,lěi,bà,wān,shì,rén,san,zhuàng,zhuàng,shēng,yī,mài,ké qiào,zhù,zhuàng,hú,hú,kǔn,yī,hú,xù,kǔn,shòu,mǎng,cún,shòu,yī,zhǐ zhōng,gǔ yíng,chǔ chù,jiàng xiáng,féng fēng páng,bèi,zhāi,biàn,suī,qūn,líng,fù,cuò,xià,xiòng xuàn,xiè,náo,xià,kuí,xī,wài,yuàn wǎn wān yuān,mǎo wǎn,sù,duō,duō,yè,qíng,wài,gòu,gòu,qì,mèng,mèng,yín,huǒ,chěn,dà dài tài,cè,tiān,tài,fū fú,guài,yāo,yāng,hāng bèn,gǎo,shī,tāo běn,tài,tóu tou,yǎn tāo,bǐ,yí,kuā kuà,jiā jiá gā xiá,duó,huà,kuǎng,yǔn,jiā jiá gā xiá,bā,ēn,lián,huàn,dī tì,yǎn yān,pào,juàn,qí jī,nài,fèng,xié,fèn,diǎn,quān juàn,kuí,zòu,huàn,qì qiè xiè,kāi,shē chǐ zhà,bēn bèn,yì,jiǎng,tào,zàng zhuǎng,běn,xī,huǎng,fěi,diāo,xùn zhuì,bēng,diàn,ào,shē,wěng,pò hǎ tǎi,ào yù,wù,ào yù,jiǎng,lián,duó,yūn,jiǎng,shì,fèn,huò,bì,luán,duǒ chě,nǚ rǔ,nú,dǐng dīng tiǎn,nǎi,qiān,jiān,tā jiě,jiǔ,nuán,chà,hǎo hào,xiān,fàn,jǐ,shuò,rú,fēi pèi,wàng,hóng,zhuāng,fù,mā,dān,rèn,fū yōu,jìng,yán,hài jiè,wèn,zhōng,pā,dù,jì,kēng háng,zhòng,yāo,jìn,yún,miào,fǒu pēi pī,chī,yuè jué,zhuāng,niū,yàn,nà nàn,xīn,fén,bǐ,yú,tuǒ,fēng,wàn yuán,fáng,wǔ,yù,guī,dù,bá,nī,zhóu,zhuó,zhāo,dá,nǐ nǎi,yuàn,tǒu,xián xuán xù,zhí yì,ē,mèi,mò,qī qì,bì,shēn,qiè,ē,hé,xǔ xū,fá,zhēng,mín,bàn,mǔ,fū fú,líng,zǐ,zǐ,shǐ,rǎn,shān shàn,yāng,mán,jiě,gū,sì,xìng,wěi wēi,zī,jù,shān shàn,pīn,rèn,yáo,dòng,jiāng,shū,jí,gāi,xiàng,huá huó,juān,jiāo xiáo,gòu dù,mǔ lǎo,jiān,jiān,yí,nián niàn,zhí,zhěn,jī,xiàn,héng,guāng,jūn xún,kuā hù,yàn,mǐng,liè,pèi,è yà,yòu,yán,chà,shēn xiān,yīn,shí,guǐ,quán,zī,sōng,wēi,hóng,wá,lóu,yà,ráo rǎo,jiāo,luán,pīng,xiàn,shào shāo,lǐ,chéng shèng,xiē,máng,fū,suō,wǔ mǔ,wěi,kè,chuò lài,chuò,tǐng,niáng,xíng,nán,yú,nà nuó,pōu bǐ,něi suī,juān,shēn,zhì,hán,dì,zhuāng,é,pín,tuì,mǎn,miǎn,wú wù yú,yán,wǔ,xī āi,yán,yú,sì,yú,wā,lì,xián,jū,qǔ,zhuì shuì,qī,xián,zhuó,dōng dòng,chāng,lù,ǎi ái è,ē ě,ē,lóu,mián,cóng,pǒu péi bù,jú,pó,cǎi,líng,wǎn,biǎo,xiāo,shū,qǐ,huī,fù fàn,wǒ,wǒ,tán,fēi,fēi,jié,tiān,ní nǐ,quán juàn,jìng,hūn,jīng,qiān jǐn,diàn,xìng,hù,wān wà,lái lài,bì,yīn,zhōu chōu,chuò nào,fù,jìng,lún,nüè,lán,hùn kūn,yín,yà,jū,lì,diǎn,xián,huā,huà,yīng,chán,shěn,tíng,dàng yáng,yǎo,wù,nàn,ruò chuò,jiǎ,tōu yú,xù,yù yú,wéi wěi,dì tí,róu,měi,dān,ruǎn nèn,qīn,huī,wò,qián,chūn,miáo,fù,jiě,duān,yí pèi,zhòng,méi,huáng,mián miǎn,ān,yīng,xuān,jiē,wēi,mèi,yuàn yuán,zhēng,qiū,tí,xiè,tuó duò,liàn,mào,rǎn,sī,piān,wèi,wā,cù,hú,ǎo,jié,bǎo,xū,tōu yú,guī,chú zòu,yáo,pì,xí,yuán,yìng,róng,rù,chī,liú,měi,pán,ǎo,mā,gòu,kuì,qín shēn,jià,sǎo,zhēn zhěn,yuán,jiē suǒ,róng,míng mǐng,yīng,jí,sù,niǎo,xián,tāo,páng,láng,nǎo,biáo,ài,pì,pín,yì,piáo piāo,yù,léi,xuán,màn,yī,zhāng,kāng,yōng,nì,lí,dí,guī,yān,jǐn jìn,zhuān,cháng,zé,hān nǎn,nèn,lào,mó,zhē,hù,hù,ào,nèn,qiáng,mā má,piè,gū,wǔ,qiáo,tuǒ,zhǎn,miáo,xián,xián,mò,liáo,lián,huà,guī,dēng,zhí,xū,yī,huà,xī,kuì,ráo rǎo,xī,yàn,chán,jiāo,měi,fàn,fān,xiān yǎn jìn,yì,huì,jiào,fù,shì,bì,shàn,suì,qiáng,liǎn,huán xuān qióng,xīn,niǎo,dǒng,yǐ,cān,ài,niáng,níng,mó,tiǎo,chóu,jìn,cí,yú,pín,róng,rú,nǎi,yān yàn,tái,yīng,qiàn,niǎo,yuè,yíng,mián,bí,mó,shěn,xìng,nì,dú,liǔ,yuān,lǎn,yàn,shuāng,líng,jiǎo,niáng,lǎn,xiān qiān,yīng,shuāng,xié huī,huān quán,mǐ,lí lì,luán,yǎn,zhú chuò,lǎn,zǐ,jié,jué,jué,kǒng,yùn,zī mā,zì,cún,sūn xùn,fú,bèi,zī,xiào,xìn,mèng,sì,tāi,bāo,jì,gū,nú,xué,yòu niū,zhuǎn,hái,luán,sūn xùn,nāo,miē,cóng,qiān,shú,chán càn,yā,zī,nǐ,fū,zī,lí,xué,bò,rú,nái,niè,niè,yīng,luán,mián,níng nìng zhù,rǒng,tā,guǐ,zhái,qióng,yǔ,shǒu,ān,tū jiā,sòng,wán,ròu,yǎo,hóng,yí,jǐng,zhūn,mì fú,zhǔ,dàng,hóng,zōng,guān,zhòu,dìng,wǎn yuān,yí,bǎo,shí,shí,chǒng,shěn,kè,xuān,shì,yòu,huàn,yí,tiǎo,shǐ,xiàn,gōng,chéng,qún,gōng,xiāo,zǎi,zhà,bǎo shí,hài,yàn,xiāo,jiā jia jie,shěn,chén,róng,huāng huǎng,mì,kòu,kuān,bīn,sù xiǔ xiù,cǎi cài,zǎn,jì,yuān,jì,yín,mì,kòu,qīng,hè,zhēn,jiàn,fù,níng nìng,bǐng bìng,huán,mèi,qǐn,hán,yù,shí,níng nìng,jìn qǐn,níng nìng,zhì,yǔ,bǎo,kuān,níng nìng,qǐn,mò,chá,jù lóu,guǎ,qǐn,hū,wù,liáo,shí,níng nìng,zhài,shěn,wěi,xiě xiè,kuān,huì,liáo,jùn,huán,yì,yí,bǎo,qīn qìn,chǒng,bǎo,fēng,cùn,duì,sì,xún,dǎo,lüè luó,duì,shòu,pǒ,fēng,zhuān,fū,shè yè yì,kēi kè,jiāng jiàng,jiāng jiàng,zhuān,wèi yù,zūn,xún,shù zhù,duì,dǎo,xiǎo,jié jí,shǎo shào,ěr,ěr,ěr,gǎ,jiān,shú,chén,shàng,shàng,mó,gá,cháng,liáo,xiǎn,xiǎn,hùn,yóu,wāng,yóu,liào,liào,yáo,lóng máng méng páng,wāng,wāng,wāng,gà,yáo,duò,kuì kuǐ,zhǒng,jiù,gān,gǔ,gān,tuí,gān,gān,shī,yǐn,chǐ chě,kāo,ní,jìn jǐn,wěi yǐ,niào suī,jú,pì,céng,xì,bī,jū,jiè,tián,qū,tì,jiè,wū,diǎo,shī,shǐ,píng bǐng,jī,xiè,zhěn,xì,ní,zhǎn,xī,wěi,mǎn,ē,lòu,pǐng bǐng,tì,fèi,shǔ zhǔ,xiè tì,tú,lǚ,lǚ,xǐ,céng,lǚ,jù,xiè,jù,juē,liáo,juē,shǔ zhǔ,xì,chè cǎo,tún zhūn,nì jǐ,shān,wā,xiān,lì,àn,huì,huì,hóng lóng,yì,qǐ,rèn,wù,hàn àn,shēn,yǔ,chū,suì,qǐ kǎi,none,yuè,bǎn,yǎo,áng,yá,wù,jié,è,jí,qiān,fén,wán,qí,cén,qián,qí,chà,jiè,qū,gǎng,xiàn,ào,lán,dǎo,bā,zuò,zuò,yǎng,jù,gāng,kě,gǒu,xuè,pō,lì,tiáo,jū jǔ,yán,fú,xiù,jiǎ,lǐng líng,tuó,pī,ào,dài,kuàng,yuè,qū,hù,pò,mín,àn,tiáo,lǐng líng,dī,píng,dōng,zhān,kuī,xiù,mǎo,tóng,xué,yì,biàn,hé,kè bā,luò,é,fù niè,xún,dié,lù,ěn,ér,gāi,quán,tóng dòng,yí,mǔ,shí,ān,wéi,huán,zhì shì,mì,lǐ,fǎ,tóng,wéi,yòu,qiǎ,xiá,lǐ,yáo,jiào qiáo,zhēng,luán,jiāo,é,é,yù,xié yé,bū,qiào,qún,fēng,fēng,náo,lǐ,yōu,xiàn,róng,dǎo,shēn,chéng,tú,gěng,jùn,gào,xiá,yín,wú,lǎng,kàn,láo,lái,xiǎn,què,kōng,chóng,chóng,tà,lín,huà,jū,lái,qí,mín,kūn,kūn,zú cuì,gù,cuī,yá,yá,gǎng gāng,lún,lún,líng léng,jué,duǒ,zhēng,guō,yín,dōng dòng,hán,zhēng,wěi,xiáo,pí bǐ,yān,sōng,jié,bēng,zú,jué,dōng,zhǎn chán,gù,yín,zī,zè,huáng,yú,wǎi wēi,yáng dàng,fēng,qiú,yáng,tí,yǐ,zhì shì,shì dié,zǎi,yǎo,è,zhù,kān zhàn,lǜ,yǎn,měi,hán,jī,jī,huàn,tíng,shèng,méi,qiàn kàn,wù máo,yú,zōng,lán,kě jié,yán,yán,wēi wěi,zōng,chá,suì,róng,kē,qīn,yú,qí,lǒu,tú,cuī,xī,wěng,cāng,dàng táng,róng yíng,jié,kǎi ái,liú,wù,sōng,kāo qiāo,zī,wéi,bēng,diān,cuó,qīn qiǎn,yǒng,niè,cuó,jǐ,shí,ruò,sǒng,zǒng,jiàng,liáo,kāng,chǎn,dié dì,cēn,dǐng,tū,lǒu,zhàng,zhǎn chán,zhǎn chán,áo ào,cáo,qū,qiāng,wěi,zuǐ,dǎo,dǎo,xí,yù,pǐ pèi,lóng,xiàng,céng,bō,qīn,jiāo,yān,láo,zhàn,lín,liáo,liáo,qín,dèng,tuò,zūn,jiào qiáo,jué guì,yáo,jiāo,yáo,jué,zhān shàn,yì,xué,náo,yè,yè,yí,niè,xiǎn,jí,xiè jiè,kě jié,guī xī juàn,dì,ào,zuì,wēi,yí,róng,dǎo,lǐng,jié,yǔ,yuè,yǐn,rū,jié,lì liè,guī xī juàn,lóng,lóng,diān,yíng hōng,xī,jú,chán,yǐng,kuī,yán,wēi,náo,quán,chǎo,cuán,luán,diān,diān,niè,yán,yán,yǎn,kuí,yǎn,chuān,kuài,chuān,zhōu,huāng,jīng xíng,xún,cháo,cháo,liè,gōng,zuǒ,qiǎo,jù,gǒng,none,wū,gū,gū,chà chā chāi cī,qiú,qiú,jǐ,yǐ,sì,bā,zhī,zhāo,xiàng hàng,yí,jǐn,xùn,juàn juǎn,bā,xùn,jīn,fú,zā,bì,shì,bù,dīng,shuài,fān,niè,shī,fēn,pà,zhǐ,xī,hù,dàn,wéi,zhàng,tǎng nú,dài,mò wà,pèi,pà,tiè tiě tiē,fú,lián,zhì,zhǒu,bó,zhì,dì,mò,yì,yì,píng,qià,juàn juǎn,rú,shuài,dài,zhēn,shuì,qiāo,zhēn,shī,qún,xí,bāng,dài,guī,chóu dào,píng,zhàng,jiǎn jiān sàn,wān,dài,wéi,cháng,shà qiè,qí jì,zé,guó,mào,zhǔ,hóu,zhēn,zhèng,mì,wéi,wò,fú,yì,bāng,píng,dié,gōng,pán,huǎng,tāo,mì,jià,téng,huī,zhōng,shān qiāo shēn,màn,mù,biāo,guó,zé,mù,bāng,zhàng,jǐng,chǎn chàn,fú,zhì,hū,fān,chuáng zhuàng,bì,bì,zhǎng,mì,qiāo,chān chàn,fén,méng,bāng,chóu dào,miè,chú,jié,xiǎn,lán,gān gàn,píng,nián,jiān,bìng bīng,bìng bīng,xìng,gàn,yāo,huàn,yòu,yōu,jī jǐ,guǎng ān,pǐ,tīng,zè,guǎng,zhuāng,mó mā me,qìng,bì,qín,dùn tún,chuáng,guǐ,yǎ,bài tīng,jiè,xù,lú,wǔ,zhuāng,kù,yīng yìng,dǐ de,páo,diàn,yā,miào,gēng,cì,fǔ,tóng,páng,fèi,xiáng,yǐ,zhì,tiāo,zhì,xiū,dù duó,zuò,xiāo,tú,guǐ,kù,máng méng páng,tíng,yóu,bū,bìng píng,chěng,lái,bēi,jī cuò,ān,shù,kāng,yōng,tuǒ,sōng,shù,qǐng,yù,yǔ,miào,sōu,cè,xiāng,fèi,jiù,è,guī wěi huì,liù,shà xià,lián,láng,sōu,zhì,bù,qǐng,jiù,jiù,jǐn qín,áo,kuò,lóu,yìn,liào,dài,lù,yì,chú,chán,tú,sī,xīn,miào,chǎng,wǔ,fèi,guǎng,kù,kuài,bì,qiáng sè,xiè,lǐn,lǐn,liáo,lú,jì,yǐng,xiān,tīng,yōng,lí,tīng,yǐn yìn,xún,yán,tíng,dí,pò pǎi,jiàn,huí,nǎi,huí,gǒng,niàn,kāi,biàn,yì,qì,nòng lòng,fèn,jǔ,yǎn,yì,zàng,bì,yì,yī,èr,sān,shì,èr,shì,shì,gōng,diào,yǐn,hù,fú,hóng,wū,tuí,chí,jiàng,bà,shěn,dì tì tuí,zhāng,jué zhāng,tāo,fǔ,dǐ,mí mǐ,xián,hú,chāo,nǔ,jìng,zhěn,yi,mǐ,juàn quān,wān,shāo,ruò,xuān yuān,jìng,diāo,zhāng,jiàng,qiáng qiǎng jiàng,péng,dàn tán,qiáng qiǎng jiàng,bì,bì,shè,dàn tán,jiǎn,gòu,gē,fā,bì,kōu,jiǎn,biè,xiāo,dàn tán,guō,qiáng qiǎng jiàng,hóng,mí mǐ,guō,wān,jué,jì xuě,jì,guī,dāng dàng,lù,lù,tuàn,huì,zhì,huì,huì,yí,yí,yí,yí,huò,huò,shān xiǎn,xíng,wén,tóng,yàn,yàn,yù,chī,cǎi,biāo,diāo,bīn,péng bāng,yǒng,piāo piào,zhāng,yǐng,chī,chì,zhuó bó,tuǒ yí,jí,páng fǎng,zhōng,yì,wǎng,chè,bǐ,dī,líng,fù,wǎng,zhēng,cú,wǎng,jìng,dài dāi,xī,xùn,hěn,yáng,huái,lǜ,hòu,wàng jiā wā,chěng zhèng,zhì,xú,jìng,tú,cóng,cóng,lài lái,cóng,dé děi de,pái,xǐ,dōng,jì,cháng,zhì,cóng zòng,zhōu,lái lài,yù,xiè,jiè,jiàn,shì tǐ,jiǎ xiá,biàn,huáng,fù,xún,wěi,páng,yáo,wēi,xī,zhēng,piào,tí chí,dé,zhǐ zhēng,zhǐ zhēng,bié,dé,zhǒng chōng,chè,jiǎo yáo,huì,jiǎo jiào,huī,méi,lòng lǒng,xiāng,bào,qú jù,xīn,xīn,bì,yì,lè,rén,dāo,dìng tìng,gǎi,jì,rěn,rén,chàn,tǎn,tè,tè tuī,gān hàn,yì qì,shì tài,cǔn,zhì,wàng,máng,xī liě,fān,yīng yìng,tiǎn,mǐn wěn mín,mǐn wěn mín,zhōng,chōng,wù,jí,wǔ,xì,jiá,yōu,wán,cōng,sōng zhōng,kuài,yù shū,biàn,zhì,qí shì,cuì,chén,tài,tún zhūn dùn,qián qín,niàn,hún,xiōng,niǔ,kuáng wǎng,xiān,xīn,kāng hàng,hū,kài xì,fèn,huái,tài,sǒng,wǔ,òu,chàng,chuàng,jù,yì,bǎo bào,chāo,mín mén,pēi,zuò zhà,zěn,yàng,kòu jù,bàn,nù,náo niú,zhēng,pà,bù,tiē zhān,hù gù,hù,cū jù zū,dá,lián,sī sāi,yóu chóu,dì,dài,yí,tū dié,yóu,fū,jí,pēng,xìng,yuàn,ní,guài,fú,xì,bì,yōu yào,qiè,xuàn,cōng,bǐng,huǎng,xù xuè,chù,bì pī,shù,xī shù,tān,yǒng,zǒng,duì,mì,zhǐ,yì,shì,nèn nín,xún,shì,xì,lǎo,héng,kuāng,móu,zhǐ,xié,liàn,tiāo yáo,huǎng,dié,hào,kǒng,guǐ,héng,xī qī xù,xiào jiǎo,shù,sī,hū kuā,qiū,yàng,huì,huí,chì,jiá,yí,xiōng,guài,lìn,huī,zì,xù,chǐ,shàng,nǜ,hèn,ēn,kè,dòng,tián,gōng,quán zhuān,xī,qià,yuè,pēng,kěn,dé,huì,è wù ě wū,qiū,tòng,yān,kǎi,cè,nǎo,yùn,máng,yǒng,yǒng,yuān juàn,pī pǐ,kǔn,qiǎo qiāo,yuè,yù shū,tú,jiè kè,xī,zhé,lìn,tì,hàn,hào jiào,qiè,tì,bù,yì,qiàn,huǐ,xī,bèi,mán mèn,yī yì,hēng hèng,sǒng,quān,chěng,kuī lǐ,wù,wù,yōu,lí,liàng,huàn,cōng,yì niàn,yuè,lì,nín,nǎo,è,què,xuán,qiān,wù,mǐn,cóng,fěi,bēi,dé,cuì,chàng,mèn mēn,lì,jì,guàn,guàn,xìng,dào,qī,kōng kǒng,tiǎn,lǔn lùn,xī,kǎn,gǔn,nì,qíng,chóu,dūn,guǒ,zhān,jīng,wǎn,yuān wǎn,jīn,jì,lán lín,yù xù,huò,hé hè,juàn quán,tán dàn,tì,tì,niàn,wǎng,chuò chuì,hū,hūn mèn,xī,chǎng,xīn,wéi,huì,è wù ě wū,suǒ ruǐ,zǒng,jiān,yǒng,diàn,jù,cǎn,chéng,dé,bèi,qiè,cán,dàn dá,guàn,duò,nǎo,yùn,xiǎng,zhuì,dié,huáng,chǔn,qióng,rě,xīng,cè,biǎn,mǐn,zōng,tí shì,qiǎo,chóu,bèi,xuān,wēi,gé,qiān,wěi,yù,yú tōu,bì,xuān,huàn,mǐn,bì,yì,miǎn,yǒng,qì kài,dàng shāng táng yáng,yīn,è,chén xìn dān,mào,kè qià,kè,yú,ài,qiè,yǎn,nuò,gǎn,yùn,còng sōng,sāi sī sǐ,lèng,fèn,yīng,kuì,kuì,què,gōng gòng hǒng,yún,sù,sù shuò,qí,yáo yào,sǒng,huàng,jí,gǔ,jù,chuàng,nì,xié,kǎi,zhěng,yǒng,cǎo,xùn,shèn,bó,kài xì,yuàn,xì xié,hùn,yǒng,yǎng,lì,cǎo sāo,tāo,yīn,cí,xù chù,qiàn qiè,tài,huāng,yùn,shèn,mǐng,gōng gòng hǒng,shè,cáo cóng,piāo,mù,mù,guó,chì,cǎn,cán,cán,cuī,mín,tè,zhāng,tòng,ào áo,shuǎng,màn,guàn,què,zào,jiù,huì,kǎi,lián liǎn,òu,sǒng,qín jìn jǐn,yìn,lǜ,shāng,wèi,tuán,mán,qiān,shè,yōng,qìng,kāng,dì chì,zhí zhé,lóu lǚ,juàn,qī,qī,yù,píng,liáo,còng,yōu,chōng,zhī zhì,tòng,chēng,qì,qū,péng,bèi,biē,qióng,jiāo,zēng,chì,lián,píng,kuì,huì,qiáo,chéng dèng zhèng,yìn,yìn,xǐ xī,xǐ,dàn dá,tán,duò,duì,duì dùn tūn,sù,jué,cè,xiāo jiāo,fān,fèn,láo,lào láo,chōng,hān,qì,xián xiàn,mǐn,jǐng,liǎo liáo,wǔ,cǎn,jué,cù,xiàn,tǎn,shéng,pī,yì,chù,xiān,náo nǎo náng,dàn,tǎn,jǐng jìng,sōng,hàn,jiǎo jǐ,wèi,xuān huān,dǒng,qín,qín,jù,cǎo sāo sào,kěn,xiè,yīng yìng,ào,mào,yì,lǐn,sè,jùn,huái,mèn,lǎn,ài,lǐn,yān,guō,xià,chì,yǔ yú,yìn,dāi,mèng méng měng,ài yì nǐ,méng měng,duì,qí jī jì,mǒ,lán xiàn,mèn,chóu,zhì,nuò,nuò,yān,yǎng,bó,zhì,kuàng,kuǎng,yōu yǒu,fū,liú liǔ,miè,chéng,huì,chàn,měng,lǎn,huái,xuán,ràng,chàn,jì,jù,huān,shè,yì,liàn,nǎn,mí mó,tǎng,jué,gàng zhuàng,gàng zhuàng,gàng zhuàng,gē,yuè,wù,jiān,xū,shù,róng,xì hū,chéng,wǒ,jiè,gē,jiān,qiāng,huò,qiāng qiàng,zhàn,dòng,qī,jiá,dié,zéi,jiá,jǐ,zhí,kān,jí,kuí,gài,děng,zhàn,qiāng qiàng,gē,jiǎn,jié,yù,jiǎn,yǎn,lù,xì hū,zhàn,xì hū,xì hū,chuō,dài,qú,hù,hù,hù,è,shì,tì,mǎo,hù,lì,fáng,suǒ,biǎn piān,diàn,jiōng,shǎng jiōng,yí,yǐ,shàn shān,hù,fēi,yǎn,shǒu,shǒu,cái,zā zhā zhá,qiú,lè lì cái,pū,bā pá,dǎ dá,rēng,fǎn fú,rù,zài,tuō,zhàng,diǎo dí yuē lì,káng gāng,yū wū,yū wū kū,hàn,shēn,chā,tuō chǐ yǐ,gǔ xì gē jié,kòu,wù,dèn,qiān,zhí,rèn,kuò,mén,sǎo sào,yáng,niǔ,bàn,chě,rǎo,xī chā qì,qián qín,bān,jiá,yú,fú,bā ào,xī zhé,pī,zhǐ,zhì sǔn kǎn,è,dèn,zhǎo,chéng,jì,yǎn,kuáng wǎng zài,biàn,chāo,jū,wěn,hú gǔ,yuè,jué,bǎ bà,qìn,dǎn shěn,zhěng,yǔn,wán,nè nì ruì nà,yì,shū,zhuā,póu,tóu,dǒu,kàng,zhē zhé shé,póu pōu fū,fǔ,pāo,bá,ǎo ào niù,zé,tuán,kōu,lūn lún,qiāng qiǎng chēng,yún,hù,bào,bǐng,zhǐ zhǎi,pēng,nán,bù pū,pī,tái,yǎo tāo,zhěn,zhā,yāng,bào,hē hè qiā,nǐ ní,yè,dǐ,chì,pī pēi,jiā,mǒ mò mā,mèi,chēn,yā,chōu,qū,mǐn,zhù,jiā yá,fú bì,zhǎ,zhǔ,dān dàn dǎn,chāi cā,mǔ,niān,lā lá,fǔ,pāo,bàn pàn,pāi,līn,ná,guǎi,qián,jù,tuò tà zhí,bá,tuō,tuō,ǎo ào niù,jū gōu,zhuō,pàn pīn fān,zhāo,bài,bài,dǐ,nǐ,jù,kuò,lǒng,jiǎn,qiǎ,yōng,lán,níng nǐng nìng,bō,zé zhái,qiān,hén,kuò guā,shì,jié jiá,zhěng,nǐn,gǒng,gǒng,quán,shuān,cún zùn,zā zǎn,kǎo,yí chǐ hài,xié,cè sè chuò,huī,pīn,zhuài zhuāi yè,shí shè,ná,bāi,chí,guà,zhì,kuò guāng,duò,duǒ duò,zhǐ,qiè,àn,nòng,zhèn,gé,jiào jiāo,kuà kū,dòng,rú ná,tiāo tiǎo,liè,zhā,lǚ,dié shè,wā,jué,liě,jǔ,zhì,luán,yà yǎ,zhuā wō,tà,xié jiā,náo,dǎng dàng,jiǎo,zhèng zhēng,jǐ,huī,xián,yǔ,āi ái,tuō shuì,nuó,cuò,bó,gěng,tǐ tì,zhèn,chéng,suō shā,suō shā,kēng qiān,měi,nòng,jú,bàng péng,jiǎn,yì,tǐng,shān,ruó,wǎn,xié jiā,chā,péng,jiǎo kù,wǔ,jùn,jiù,tǒng,kǔn,huò chì,tú shū chá,zhuō,póu pōu fū,luō lǚ,bā,hàn,shāo shào,niē,juān,zè,shù sǒng sōu,yé yú,jué zhuó,bǔ,wán,bù pú zhì,zùn,yè,zhāi,lǚ,sōu,tuō shuì,lāo,sǔn,bāng,jiǎn,huàn,dǎo,wěi,wàn wǎn wān yù,qín,pěng,shě,liè,mín,mén,fǔ fù bǔ,bǎi,jù jū,dáo,wǒ luò luǒ,ái,juǎn quán,yuè,zǒng,chēn,chuí,jié,tū,bèn,nà,niǎn niē,ruó wěi ré,zuó,wò xiá,qī,xiān,chéng,diān,sǎo sào,lūn lún,qìng qiàn,gāng,duō,shòu,diào,pǒu póu,dǐ,zhǎng,hùn,jǐ,tāo,qiā,qí,pái pǎi,shū,qiān wàn,líng,yè yē,yà yǎ,jué,zhēng zhèng,liǎng,guà,nǐ niè yì,huò xù,shàn yàn yǎn,zhěng dìng,lüè,cǎi,tàn,chè,bīng,jiē,tì,kòng,tuī,yǎn,cuò,zōu zhōu chōu,jū,tiàn,qián,kèn,bāi,pá,jiē,lǔ,guó,mìng,jié,zhì,dǎn shàn,mēng,chān xiān càn shǎn,sāo,guàn,pèng,yuàn,nuò,jiǎn,zhēng kēng,jiū yóu,jiǎn jiān,yú,yán,kuí,nǎn,hōng,róu,pì chè,wēi,sāi zǒng cāi,zòu,xuān,miáo,tí dī dǐ,niē,chā,shì,zǒng sōng,zhèn zhēn,yī,xún,huáng yóng,biǎn,yáng,huàn,yǎn,zǎn zuàn,ǎn,xū jū,yà,wò,ké qiā,chuǎi chuài chuāi tuán zhuī,jí,tì dì,là lá,là,chéng,kāi,jiū,jiū,tú,jiē qì,huī,gèn,chòng dǒng,xiāo,shé dié yè,xiē,yuán,qián jiàn jiǎn,yé,chā,zhā,bēi,yáo,wēi,bèng,lǎn,wèn,qìn,chān,gē gé,lǒu lōu,zǒng,gèn,jiǎo,gòu,qìn,róng,què,chōu zǒu,chuāi,zhǎn,sǔn,sūn,bó,chù,róng náng nǎng,bàng péng,cuō,sāo,kē è,yáo,dǎo,zhī,nù nuò nòu,lā xié xiàn,jiān,sōu,qiǔ,gǎo,xiǎn xiān,shuò,sǎng,jìn,miè,è,chuí,nuò,shān,tà,jié zhé,táng,pán bān pó,bān,dā,lì,tāo,hú,zhì nái,wā wǎ wà,huá,qiān,wèn,qiāng qiǎng chēng,tián shēn,zhēn,è,xié,ná nuò,quán,chá,zhà,gé,wǔ,èn,shè,gāng,shè niè,shū,bǎi,yáo,bìn,sōu,tān,sà shā shǎi,chǎn sùn,suō,jiū liú liáo jiǎo náo,chōng,chuāng,guó,bìng,féng pěng,shuāi,dì tú zhí,qì jì chá,sōu sǒng,zhāi,liǎn liàn,chēng,chī,guàn,lù,luò,lǒu lōu,zǒng,gài xì,hù chū,zhā,qiāng,tàng,huà,cuī,zhì nái,mó mā,jiāng qiàng,guī,yǐng,zhí,áo qiáo,zhì,niè chè,mán màn,chàn cán,kōu,chū,sè mí sù,tuán,jiǎo chāo,mō,mó,zhé,chān xiān càn shǎn,kēng qiān,biào biāo,jiàng,yáo,gòu,qiān,liào,jī,yīng,juē jué,piē,piē piě,lāo,dūn,xiàn,ruán,guì,zǎn zān zēn qián,yī,xián,chēng,chēng,sā sǎ,náo,hòng,sī,hàn,héng guàng,dā,zǔn,niǎn,lǐn,zhěng chéng,huī wéi,zhuàng,jiǎo,jǐ,cāo,dǎn,dǎn shàn,chè,bō,chě,juē,xiāo sōu,liāo liáo,bèn,fǔ,qiào,bō,cuō zuǒ,zhuó,zhuàn,wěi tuǒ,pū,qìn,dūn,niǎn,huá,xié,lū,jiǎo,cuān,tà,hàn,qiào yāo jī,zhuā wō,jiǎn,gǎn,yōng,léi lèi,nǎng,lǔ,shàn,zhuó,zé zhái,pǔ,chuò,jī,dǎng dàng,sè,cāo,qíng,qíng jǐng,huàn,jiē,qín,kuǎi,dān dàn,xié,qiā jiā yè,pǐ bò,bò bāi,ào,jù jū,yè,è,mēng,sòu sǒu,mí,jǐ,tái,zhuó,dǎo,xǐng,lǎn,cā,jǔ,yē,rǔ,yè,yè,nǐ,huò,jié,bìn,níng nǐng nìng,gē gé,zhì,zhì jié,kuò,mó,jiàn,xié,liè là,tān,bǎi,sòu sǒu,lū,lì luò yuè,rǎo,tī zhì zhāi,pān,yǎng,léi lèi,cā sǎ,shū,zǎn,niǎn,xiǎn,jùn pèi,huō,lì luò,là lài,huàn,yíng,lú luó,lǒng,qiān,qiān,zǎn cuán,qiān,lán,xiān jiān,yīng,méi,rǎng,chān,wěng,cuān,xié,shè niè,luó,jùn,mí mǐ mó,chī,zǎn cuán,luán,tān,zuàn,lì shài,diān,wā,dǎng,jiǎo,jué,lǎn,lì luǒ,nǎng,zhī,guì,guǐ guì,qī yǐ jī,xún,pū,pū,shōu,kǎo,yōu,gǎi,yǐ,gōng,gān hàn,bān,fàng,zhèng,pò,diān,kòu,mǐn,wù móu,gù,hé,cè,xiào,mǐ,chù shōu,gé guó è,dí,xù,jiào jiāo,mǐn,chén,jiù,shēn,duó duì,yǔ,chì,áo,bài,xù,jiào jiāo,duó duì,liǎn,niè,bì,chǎng,diǎn,duō què,yì,gǎn,sàn sǎn,kě,yàn,dūn duì,qī yǐ jī,tǒu,xiào xué,duō què,jiǎo,jìng,yáng,xiá,mǐn,shù shǔ shuò,ái zhú,qiāo,ái zhú,zhěng,dí,chén,fū,shù shǔ shuò,liáo,qū,xiòng xuàn,yǐ,jiǎo,shàn,jiǎo,zhuó zhú,yì dù,liǎn,bì,lí tái,xiào,xiào,wén,xué,qí,qí,zhāi,bīn,jué jiào,zhāi,láng,fěi fēi,bān,bān,lán,yǔ zhōng,lán,wěi mén,dǒu dòu,shēng,liào,jiǎ,hú,xié,jiǎ,yǔ,zhēn,jiào,wò guǎn,tǒu tiǎo,dòu,jīn,chì,yín zhì,fǔ,qiāng,zhǎn,qú,zhuó,zhǎn,duàn,zhuó,sī,xīn,zhuó,zhuó,qín,lín,zhuó,chù,duàn,zhú,fāng,chǎn jiè,háng,yú wū,shī,pèi,liú yóu,mèi,páng bàng,qí,zhān,máo mào,lǚ,pèi,pī bì,liú,fū,fǎng,xuán xuàn,jīng,jīng,nǐ,zú,zhào,yǐ,liú,shāo,jiàn,yú,yǐ,qí,zhì,fān,piāo,fān,zhān,kuài,suì,yú,wú,jì,jì,jì,huò,rì,dàn,jiù,zhǐ,zǎo,xié,tiāo,xún,xù,gā,lá,gàn hàn,hàn,tái yīng,dì dí de,xù xū,chǎn,shí,kuàng,yáng,shí,wàng,mín,mín,tūn zhùn,chūn,wù wǔ,yún,bèi,áng,zè,bǎn,jié,kūn,shēng,hù,fǎng,hào,guì,chāng,xuān,míng,hūn,fēn,qǐn,hū,yì,xī,xīn,yán,zè,fǎng,tán,shèn,jù,yáng,zǎn,bǐng,xīng,yìng,xuàn,pò,zhěn,líng,chūn,hào,mèi,zuó,mò,biàn,xù,hūn,zhāo,zòng,shì,shì,yù,fèi,dié yì,mǎo,nì,chǎng,wēn,dōng,ǎi,bǐng,áng,zhòu,lóng,xiǎn,kuàng,tiǎo,cháo,shí,huǎng huàng,huǎng,xuān,kuí,xù kuā,jiǎo,jìn,zhì,jìn,shǎng,tóng,hǒng,yàn,gāi,xiǎng,shài,xiǎo,yè,yùn yūn,huī,hán,hàn,jùn,wǎn,xiàn,kūn,zhòu,xī,shèng chéng,shèng,bū,zhé,zhé,wù,wǎn,huì,hào,chén,wǎn,tiǎn,zhuó,zuì,zhǒu,pǔ,jǐng yǐng,xī,shǎn,nǐ,xī,qíng,qǐ dù,jīng,guǐ,zhěng,yì,zhì,àn ǎn yǎn,wǎn,lín,liàng,chēng,wǎng wàng,xiǎo,zàn,fēi,xuān,xuǎn,yí,xiá,yùn yūn,huī,xǔ,mǐn mín,kuí,yē,yìng,shǔ dǔ,wěi,shǔ,qíng,mào,nán,jiǎn lán,nuǎn,àn,yáng,chūn,yáo,suǒ,pǔ,míng,jiǎo,kǎi,hào,wěng,chàng,qì,hào,yàn,lì,ài,jì,jì,mèn,zàn,xiè,hào,mù,mù,cōng,nì,zhāng,huì,bào pù,hàn,xuán,chuán,liáo,xiān,tǎn,jǐng,piē,lín,tūn,xī xǐ,yì,jì,huàng,dài,yè,yè,lì,tán,tóng,xiǎo,fèi,shěn,zhào,hào,yì,xiàng,xīng,shēn,jiǎo,bào,jìng,yàn,ài,yè,rú,shǔ,méng,xūn,yào,pù bào,lì,chén,kuàng,dié,liǎo,yàn,huò,lú,xī,róng,lóng,nǎng,luǒ,luán,shài,tǎng,yǎn,zhú,yuē,yuē,qū qǔ,yè,gēng gèng,yè,hū hù,hé,shū,cáo,cáo,shēng,màn,zēng céng,zēng céng,tì,zuì,cǎn qián jiàn,xù,huì kuài,yǐn,qiè hé,fēn,bì pí,yuè,yǒu yòu,ruǎn,péng,fén bān,fú fù,líng,fěi kū,qú xù chǔn,tì,nǜ gǎ,tiǎo,shuò,zhèn,lǎng,lǎng,juān zuī,míng,huāng máng wáng,wàng,tūn,zhāo cháo,jī,qī jī,yīng,zōng,wàng,tóng chuáng,lǎng,láo,méng,lóng,mù,pìn děng,wèi,mò,běn,zhá,shù shú zhú,shù shú zhú,none,zhū shú,rén,bā,pǔ pò pō piáo,duǒ,duǒ,dāo tiáo mù,lì,qiú guǐ,jī,jiū,bǐ,xiǔ,chéng chēng,cì,shā,rù,zá,quán,qiān,yú wū,gān gǎn,wū,chā chà,shā,xún,fán,wù,zǐ,lǐ,xìng,cái,cūn,rèn ér,sháo biāo,tuō zhé,dì duò,zhàng,máng,chì,yì,gū gài,gōng,dù,yí lì lí duò tuò,qǐ,shù,gàng gāng,tiáo tiāo,jié,mián,wàn,lái,jiǔ,máng,yáng,mà mǎ,miǎo,sì zhǐ xǐ,yuán wán,háng,fèi bèi,bēi,jié,dōng,gǎo,yǎo,xiān,chǔ,chūn,pá,shū duì,huà,xīn,niǔ chǒu,zhù,chǒu,sōng,bǎn,sōng,jí,wò yuè,jìn,gòu,jī,máo,pí,pī mì,wǎng,àng,fāng bìng,fén,yì,fú fū,nán,xī,hù dǐ,yā,dōu,xín,zhěn,yǎo yāo,lín,ruì,ě è,méi,zhào,guǒ,zhī qí,cōng zōng,yùn,huà,shēng,shū,zǎo,dì duò,lì,lú,jiǎn,chéng,sōng,qiāng,fēng,zhān,xiāo,xiān zhēn,kū,píng,sì tái,xǐ,zhǐ,guǎi,xiāo,jià,jiā,jǔ gǒu,bāo fú,mò,yì xiè,yè,yè,shì,niè,bǐ,tuó duò,yí duò lí,líng,bǐng,nǐ chì,lā,hé,pán bàn,fán,zhōng,dài,cí,yǎng yàng yāng yīng,fū fǔ fù,bǎi bó bò,mǒu,gān,qī,rǎn,róu,mào,sháo shào,sōng,zhè,xiá,yòu yóu,shēn,guì jǔ,tuò,zuò zhà,nán,níng,yǒng,dǐ chí,zhì dié,zhā zǔ zū,chá zhā,dàn,gū,bù pū,jiù,āo ào,fú,jiǎn,bā fú pèi bó biē,duò zuó wù,kē,nài,zhù,bì bié,liǔ,chái,shān,sì,zhù,bēi pēi,shì fèi,guǎi,chá zhā,yǎo,chēng,jiù,shì,zhī,liǔ,méi,lì,róng,zhà shān shi cè,zǎo,biāo,zhàn,zhì,lóng,dòng,lú,shēng,lì yuè,lán,yǒng,shù,xún,shuān,qì qiè,chén,qī xī,lì,yí,xiáng,zhèn,lì,sè,guā tiǎn,kān,bēn bīng,rěn,xiào jiào,bǎi,rěn,bìng,zī,chóu,yì xiè,cì,xǔ,zhū,jiàn zùn,zuì,ér,ěr,yǒu yù,fá,gǒng,kǎo,lǎo,zhān,liè,yīn,yàng,hé hú,gēn,zhī yì,shì,gé,zāi,luán,fú,jié,héng háng,guì,táo,guāng guàng,wéi,kuàng,rú,àn,ān,juàn,yí tí,zhuō,kū,zhì,qióng,tóng,sāng,sāng,huán,jié jú,jiù,xuè,duò,chuí,yú móu,zā zǎn,none,yīng,jié,liǔ,zhàn,yā,ráo náo,zhēn,dàng,qī,qiáo,huà,guì huì,jiǎng,zhuāng,xún,suō,shā,chén zhèn,bēi,tīng yíng,guā,jìng,bó,bèn fàn,fú,ruí,tǒng,jué,xī,láng,liǔ,fēng fèng,qī,wěn,jūn,gǎn,sù yìn,liáng,qiú,tǐng tìng,yǒu,méi,bāng,lòng,pēng,zhuāng,dì,xuān juān xié,tú chá,zào,āo yòu,gù,bì,dí,hán,zǐ,zhī,rèn ér,bèi,gěng,jiǎn,huàn,wǎn,nuó,jiā,tiáo tiāo,jì,xiāo,lǚ,kuǎn,shāo sào,chén,fēn,sōng,mèng,wú,lí,sì qǐ,dòu,qǐn,yǐng,suō,jū,tī,xiè,kǔn,zhuō,shū,chān yán,fàn,wěi,jìng,lí,bīn bīng,xià,fó,chóu táo dào,zhì,lái,lián liǎn,jiǎn,zhuō,líng,lí,qì,bǐng,lún,cōng sōng,qiàn,mián,qí,qí,cǎi,gùn hùn,chán,dé zhé,fěi,pái bèi pèi,bàng,bàng pǒu bèi bēi,hūn,zōng,chéng,zǎo,jí,lì liè,péng,yù,yù,gù,jùn,dòng,táng,gāng,wǎng,dì dài tì,què,fán,chēng,zhàn,qǐ,yuān,yǎn yàn,yù,quān juàn,yì,sēn,rěn shěn,chuí,léng lēng líng,qī,zhuō,fú sù,kē,lái,zōu sǒu,zōu,zhào zhuō,guān,fēn,fén,chēn shēn,qíng,ní nǐ,wǎn,guǒ,lù,háo,jiē qiè,yǐ yī,chóu zhòu diāo,jǔ,jú,chéng shèng,zú cuì,liáng,qiāng kōng,zhí,zhuī chuí,yā,jū,bēi,jiāo,zhuó,zī,bīn,péng,dìng,chǔ,chāng,mēn,huā,jiǎn,guī,xì,dú,qiàn,dào,guì,diǎn,luó,zhī,quān juàn quán,mìng,fǔ,gēng,pèng,shàn,yí,tuǒ,sēn,duǒ chuán,yē,fù,wěi huī,wēi,duàn,jiǎ jiā,zōng,jiān hán,yí,zhēn shèn,xí,yà,yǎn,chuán,jiān,chūn,yǔ,hé,zhā chá,wò,piān,bī,yāo,guō kuǎ,xū,ruò,yáng,là,yán,běn,huī,kuí,jiè,kuí,sī,fēng,xiē,tuǒ,jí zhì,jiàn,mù,máo,chǔ,kǔ hù,hú,liàn,léng,tíng,nán,yú,yóu yǒu,méi,sǒng cōng,xuàn yuán,xuàn,yǎng yàng yīng,zhēn,pián,dié yè,jí,jiē,yè,chǔ,shǔn dùn,yú,còu zòu,wēi,méi,dì dǐ shì,jí,jié,kǎi jiē,qiū,yíng,róu ròu,huáng,lóu,lè yuè,quán,xiāng,pǐn,shǐ,gài,tán,lǎn,wēn yùn,yú,chèn,lǘ,jǔ,shén,chū,bī pi,xiè,jiǎ,yì,zhǎn niǎn zhèn,fú fù bó,nuò,mì,láng,róng,gǔ,jiàn jìn,jǔ,tā,yǎo,zhēn,bǎng bàng,shā xiè,yuán,zǐ,míng,sù,jià,yáo,jié,huàng,gàn,fěi,zhà,qián,mà mā,sǔn,yuán,xiè,róng,shí,zhī,cuī,wēn,tíng,liú,róng,táng,què,zhāi,sì,shèng,tà,kē,xī,gù,qī,gǎo,gǎo,sūn,pán,tāo,gé,chūn,diān,nòu,jí,shuò,gòu,chuí,qiāng,chá,qiǎn lián xiàn,huái,méi,xù,gàng,gāo,zhuō,tuó,qiáo,yàng,diān zhěn zhēn,jiǎ,jiàn kǎn,zuì,dǎo,lóng,bīn bīng,zhū,sāng,xí dié,jī guī,lián liǎn,huì,róng yōng,qiàn,guǒ,gài,gài,tuán shuàn quán,huà,qì sè,sēn,cuī zhǐ,pèng,yǒu chǎo,hú,jiǎng,hù,huàn,guì,niè,yì,gāo,kāng,guī,guī,cáo,màn wàn,jǐn,dī,zhuāng,lè yuè yào lào,láng,chén,cōng zōng,lí chī,xiū,qíng,shǎng,fán,tōng,guàn,zé,sù,léi lěi,lǔ,liáng,mì,lóu,cháo jiǎo chāo,sù,kē,chū,táng,biāo,lù,jiū liáo,zhè,zhā,shū,zhāng,mán,mó mú,niǎo mù,yàng,tiáo,péng,zhù,shā xiè,xī,quán,héng hèng,jiān,cōng,jī,yān,qiáng,xuě,yīng,èr,xún,zhí,qiáo,zuī,cóng,pǔ,shù,huà,guì,zhēn,zūn,yuè,shàn,xī,chūn,diàn,fá fèi,gǎn,mó,wú,qiāo,ráo náo,lìn,liú,qiáo,xiàn,rùn,fǎn,zhǎn jiǎn,tuó,liáo,yún,shùn,tuí dūn,chēng,táng chēng,méng,jú,chéng,sù qiū,jué,jué,tán diàn,huì,jī,nuó,xiàng,tuǒ,níng,ruǐ,zhū,tóng chuáng,zēng céng,fén fèn fèi,qióng,rǎn yān,héng hèng,qián,gū,liǔ,lào,gāo,chú,xǐ,shèng,zǐ,zān,jǐ,dōu,jīng,lǔ,xiàn,cū chu,yuán,tà,shū qiāo,jiāng,tán,lǐn,nóng,yǐn,xí,huì,shān,zuì,xuán,chēng,gàn,jū,zuì,yì,qín,pǔ,yán,léi,fēng,huǐ,dàng,jì,suì,bò,píng bò,chéng,chǔ,zhuā,guì huì,jí,jiě,jiǎ,qíng,zhái shì tú,jiǎn,qiáng,dào,yǐ,biāo biǎo,sōng,shē,lǐn,lì,chá,méng,yín,chóu táo dǎo,tái,mián,qí,tuán,bīn bīng,huò,jì,qiān lián,nǐ mí,níng,yī,gǎo,jiàn kǎn,yǐn,nòu ruǎn rú,qǐng,yǎn,qí,mì,zhào,guì,chūn,jī jì,kuí,pó,dèng,chú,gé,mián,yōu,zhì,huǎng guǒ gǔ,qiān,lěi,léi lěi,sà,lǔ,lì,cuán,lǜ chū,miè mèi,huì,ōu,lǘ,zhì,gāo,dú,yuán,lì yuè,fèi,zhuó zhù,sǒu,lián liǎn,jiàng,chú,qìng,zhū,lú,yán,lì,zhū,chèn,jué jì,è,sū,huái guī,niè,yù,lóng,là lài,qiáo,xiǎn,guī,jǔ,xiāo,líng,yīng,jiān,yǐn,yòu yóu,yíng,xiāng,nóng,bó,chán zhàn,lán,jǔ,shuāng,shè,wéi zuì,cóng,quán,qú,cáng,jiù,yù,luó,lì,cuán,luán,dǎng,qú,yán,lǎn,lán,zhú,léi,lǐ,bà,náng,yù,líng,guàn,qiàn,cì,huān,xīn,yú,yù yì,qiān xiān,ōu,xū,chāo,chù qù xì,qì,kài ài,yì yīn,jué,xì kài,xù,hē,yù,kuài,láng,kuǎn,shuò sòu,xī,èi ǎi,qī,qī,xū chuā,chǐ chuài,qīn,kuǎn,kǎn qiàn,kuǎn,kǎn kè,chuǎn chuán,shà,guā,yān yīn,xīn,xiē,yú,qiàn,xiāo,yē,gē,wū,tàn,jìn qūn,ōu,hū,tì,huān,xū,pēn,xǐ,xiào,xū,xī shè,shàn,liǎn hān,chù,yì,è,yú,chuò,huān,zhǐ,zhèng zhēng,cǐ,bù,wǔ,qí,bù,bù,wāi,jù,qián,zhì chí,sè,chǐ,sè shà,zhǒng,suì,suì,lì,zé,yú,lì,guī,dǎi,è,sǐ,jiān,zhé,mò wěn,mò,yāo,mò,cú,yāng,tiǎn,shēng,dài,shāng,xù,xùn,shū,cán,jǐng,piǎo,qià,qiú,sù,qíng jìng,yǔn,liàn,yì,fǒu bó,zhí shi,yè yān yàn,cán,hūn mèi,dān,jí,dié,zhēn,yǔn,wēn,chòu,bìn,tì,jìn,shāng,yín,chī,jiù,kuì huì,cuàn,yì,dān,dù,jiāng,liàn,bìn,dú,jiān,jiān,shū,ōu,duàn,zhù,yīn yān yǐn,qìng kēng shēng,yì,shā,ké qiào,ké qiào,xiáo yáo xiào,xùn,diàn,huǐ,huǐ,gǔ,qiāo,jī,yì,ōu,huǐ,duàn,yī,xiāo,wú,guàn wān,mǔ,měi,měi,ǎi,jiě,dú dài,yù,bǐ,bì,bì,pí,pí,bì,chán,máo,háo,cǎi,bǐ,liě,jiā,zhān,sāi,mù,tuò,xún xùn,ěr,róng,xiǎn,jū,mú,háo,qiú,dòu nuò,shā,tǎn,péi,jū,duō,cuì,bī,sān,sān,mào,sāi suī,shū,shū,tuò,hé,jiàn,tà,sān,lǘ,mú,máo,tóng,rǒng,chǎng,pǔ,lǔ,zhān,sào,zhān,méng,lǔ,qú,dié,shì zhī,dī dǐ,mín,jué,méng máng,qì,piē,nǎi,qì,dāo,xiān,chuān,fēn,yáng rì,nèi,nèi,fú,shēn,dōng,qīng,qì,yīn,xī,hài,yǎng,ān,yà,kè,qīng,yà,dōng,dàn,lǜ,qíng,yǎng,yūn,yūn,shuǐ,shuǐ,zhěng chéng zhèng,bīng,yǒng,dàng,shuǐ,lè,nì,tǔn,fàn,guǐ jiǔ,tīng,zhī,qiú,bīn pà pā,zè,miǎn,cuān,huì,diāo,hàn,chà,zhuó què,chuàn,wán,fàn,tài dà,xī,tuō,máng,qiú,qì,shàn,pìn,hàn hán,qiān,wū,wū,xùn,sì,rǔ,gǒng,jiāng,chí,wū,tu,jiǔ,tāng shāng,zhī jì,zhǐ,qiān,mì,gǔ yù,wāng,jǐng,jǐng,ruì,jūn,hóng,tài,tài,jí,biàn,biàn,gàn hán cén,wèn mén,zhōng,fāng pāng,xiōng,jué,hǔ huǎng,niú yóu,qì,fén,xù,xù,qìn,yí,wò,yún,yuán,hàng,yǎn,shěn chén,chén,dàn,yóu,dùn,hù,huò,qī,mù,nǜ niǔ,méi mò,tà dá,miǎn,mì wù,chōng,hóng pāng,bǐ,shā shà,zhǐ,pèi,pàn,zhuǐ zǐ,zā,gōu,pài,méi mò,zé,fēng,òu ōu,lì,lún,cāng,fēng,wéi,hù,mò,mèi,shù,jǔ jù,zá,tuō duó,tuó,tuó duò,hé,lì,mǐ lì,yí chí,fā,fèi,yóu,tián,zhì,zhǎo,gū,zhān,yán,sī,kuàng,jiǒng,jū,xiè yì,qiú,yì dié,jiā,zhōng,quán,bó pō,huì,mì bì,bēn bèn,zé,chù shè,lè,yōu yòu āo,gū,hóng,gān,fǎ,mǎo,sì,hū,pēng píng,cǐ,fàn,zhī,sù,nìng,chēng,líng,pào pāo,bō,qì,sì,ní nì,jú,yuè sà,zhù,shēng,lèi,xuàn,jué xuè,fú,pàn,mǐn,tài,yāng,jǐ,yǒng,guàn,bèng,xué,lóng shuāng,lú,dàn,luò pō,xiè,pō,zé shì,jīng,yín,pán,jié,yè,huī,huí,zài,chéng,yīn,wéi,hòu,jiàn,yáng,liè,sì,jì,ér,xíng,fú fù,sǎ xǐ,sè qì zì,zhǐ,yìn,wú,xǐ xiǎn,kǎo kào,zhū,jiàng,luò,luò,àn yàn è,dòng,yí,sì,lěi lèi,yī,mǐ,quán,jīn,pò,wěi,xiáo,xiè,hóng,xù,sù shuò,kuāng,táo,qiè jié,jù,ěr,zhōu,rù,píng,xún,xiōng,zhì,guāng,huán,míng,huó,wā,qià,pài,wū,qū,liú,yì,jiā,jìng,qiǎn jiān,jiāng jiàng,jiāo,zhēn,shī,zhuó,cè,fá,kuài huì,jì jǐ,liú,chǎn,hún,hǔ xǔ,nóng,xún,jìn,liè,qiú,wěi,zhè,jùn xùn,hán,bāng,máng,zhuó,yōu dí,xī,bó,dòu,huàn,hóng,yì,pǔ,yǐng chéng yíng,lǎn,hào,làng,hǎn,lǐ,gēng,fú,wú,lì,chún,féng hóng,yì,yù,tóng,láo,hǎi,jìn,jiā,chōng,jiǒng jiōng,měi,suī něi,chēng,pèi,xiàn,shèn,tú,kùn,pīng,niè,hàn,jīng,xiāo,shè,niǎn,tū,yǒng chōng,xiào,xián,tǐng,é,sù,tūn yūn,juān,cén,tì,lì,shuì,sì,lèi,shuì,tāo,dú,lào,lái,lián,wéi,wō guō,yún,huàn,dí,hēng,rùn,jiàn,zhǎng zhàng,sè,fú,guān,xìng,shòu tāo,shuàn,yá,chuò,zhàng,yè,kōng náng,wǎn wò yuān,hán,tuō tuò,dōng,hé,wō,jū,shè,liáng liàng,hūn,tà,zhuō,diàn,qiè jí,dé,juàn,zī,xī,xiáo,qí,gǔ,guǒ guàn,yān,lín lìn,tǎng chǎng,zhōu,pěng,hào,chāng,shū,qī,fāng,zhí,lù,nào chuò zhuō,jú,táo,cóng,lèi,zhè,píng péng,féi,sōng,tiǎn,pì pèi,dàn,yù xù,ní,yū,lù,gàn,mì,jìng chēng,líng,lún,yín,cuì,qú,huái,yù,niǎn shěn,shēn,biāo hǔ,chún zhūn,hū,yuān,lái,hùn hún,qīng,yān,qiǎn,tiān,miǎo,zhǐ,yǐn,bó,bèn,yuān,wèn mín,ruò rè luò,fēi,qīng,yuān,kě,jì jǐ,shè,yuān,sè,lù,zì,dú dòu,yī,jiàn jiān,miǎn shéng,pài,xī,yú,yuān,shěn,shèn,róu,huàn,zhǔ,jiǎn,nuǎn nuán,yú,qiú wù,tíng tīng,qú jù,dù,fēng,zhā,bó,wò,wō guō,tí dī dì,wěi,wēn,rú,xiè,cè,wèi,hé,gǎng jiǎng,yān yǎn,hóng,xuàn,mǐ,kě,máo,yīng,yǎn,yóu,hōng qìng,miǎo,shěng,měi,zāi,hún,nài,guǐ,chì,è,pài,méi,liàn,qì,qì,méi,tián,còu,wéi,cān,tuān,miǎn,huì mǐn xū,pò,xǔ xū,jí,pén,jiān,jiǎn,hú,fèng,xiāng,yì,yìn,zhàn,shí,jiē,zhēn,huáng,tàn,yú,bì,mǐn hūn,shī,tū,shēng,yǒng,jú,dòng,tuàn nuǎn,qiū jiǎo,qiū jiǎo,qiú,yān yīn,tāng shāng,lóng,huò,yuán,nǎn,bàn pán,yǒu,quán,zhuāng hún,liàng,chán,xián,chún,niè,zī,wān,shī,mǎn,yíng,là,kuì huì,féng hóng,jiàn jiān,xù,lóu,wéi,gài,bō,yíng,pō,jìn,yàn guì,táng,yuán,suǒ,yuán,lián liǎn nián xián xiàn,yǎo,méng,zhǔn,chéng,kè,tài,dá tǎ,wā,liū liù,gōu,sāo,míng,zhà,shí,yì,lùn,mǎ,pǔ,wēi,lì,zāi,wù,xī,wēn,qiāng,zé,shī,sù,ái,zhēn qín,sōu,yún,xiù,yīn,róng,hùn,sù,suò,nì niào,tā,shī,rù,āi,pàn,chù xù,chú,pāng,wěng wēng,cāng,miè,gé,diān,hào xuè,huàng,qì xì xiē,zī,dí,zhì,xíng yíng,fǔ,jié,huá,gē,zǐ,tāo,téng,suī,bì,jiào,huì,gǔn,yín,zé hào,lóng,zhì,yàn,shè,mǎn,yíng,chún,lǜ,làn,luán,yáo,bīn,tān,yù,xiǔ,hù,bì,biāo,zhì,jiàng,kòu,shèn,shāng,dī,mì,áo,lǔ,hǔ xǔ,hū,yōu,chǎn,fàn,yōng,gǔn,mǎn,qǐng,yú,piāo piǎo piào,jì,yá,cháo,qī,xǐ,jì,lù,lóu,lóng,jǐn,guó,cóng sǒng,lòu,zhí,gài,qiáng,lí,yǎn,cáo,jiào,cōng,chún,tuán zhuān,òu ōu,téng,yě,xí,mì,táng,mò,shāng,hàn,lián,lǎn,wā,chí,gān,féng péng,xuán,yī,màn,zì,mǎng,kāng,luò tà,bēn pēng,shù,zhǎng zhàng,zhāng,chóng zhuàng,xù,huàn,huǒ huò kuò,jiàn jiān,yān,shuǎng,liáo liú,cuǐ cuī,tí,yàng,jiāng jiàng,cóng zǒng,yǐng,hóng,xiǔ,shù,guàn,yíng,xiāo,cóng zōng,kūn,xù,liàn,zhì,wéi,pì piē,yù,jiào qiáo,pō,dàng xiàng,huì,jié,wǔ,pá,jí,pān,wéi,sù,qián,qián,xī yà,lù,xì,xùn,dùn,huáng guāng,mǐn,rùn,sù,lǎo lào liáo,zhēn,cōng zòng,yì,zhí zhì,wān,tān shàn,tán,cháo,xún,kuì huì,yē,shào,tú zhā,zhū,sàn sǎ,hēi,bì,shān,chán,chán,shǔ,tóng,pū,lín,wéi,sè,sè,chéng,jiǒng,chéng dèng,huà,jiāo,lào,chè,gǎn,cūn cún,jǐng,sī,shù zhù,péng,hán,yún,liū liù,hòng gǒng,fú,hào,hé,xián,jiàn,shān,xì,ào yù,lǔ,lán,nìng,yú,lǐn,miǎn shéng,zǎo,dāng,huàn,zé shì,xiè,yù,lǐ,shì,xué,líng,wàn màn,zī,yōng yǒng,kuài huì,càn,liàn,diàn,yè,ào,huán,zhēn,chán,màn,gǎn,dàn tán,yì,suì,pì,jù,tà,qín,jī,zhuó,lián,nóng,guō wō,jìn,fén pēn,sè,jí shà,suī,huì huò,chǔ,tà,sōng,dǐng tìng,sè,zhǔ,lài,bīn,lián,mǐ nǐ,shī,shù,mì,nìng,yíng,yíng,méng,jìn,qí,bì pì,jì jǐ,háo,rú,cuì zuǐ,wò,tāo,yǐn,yīn,duì,cí,huò hù,qìng,làn,jùn xùn,ǎi kài kè,pú,zhuó zhào,wéi,bīn,gǔ,qián,yíng,bīn,kuò,fèi,cāng,mè,jiàn jiān,wěi duì,luò pō,zàn cuán,lǜ,lì,yōu,yǎng yàng,lǔ,sì,zhì,yíng,dú dòu,wǎng wāng,huī,xiè,pán,shěn,biāo,chán,miè mò,liú,jiān,pù bào,sè,chéng dèng,gǔ,bīn,huò,xiàn,lú,qìn,hàn,yíng,róng,lì,jìng,xiāo,yíng,suǐ,wěi duì,xiè,huái wāi,xuè,zhū,lóng shuāng,lài,duì,fàn,hú,lài,shū,lián,yíng,mí,jì,liàn,jiàn zùn,yīng yǐng yìng,fèn,lín,yì,jiān,yuè,chán,dài,ráng nǎng,jiǎn,lán,fán,shuàng,yuān,zhuó jiào zé,fēng,shè,lěi,lán,cóng,qú,yōng,qián,fǎ,guàn,jué,yàn,hào,yíng,sǎ,zàn cuán,luán luàn,yàn,lí,mǐ,shàn,tān,dǎng tǎng,jiǎo,chǎn,yíng,hào,bà,zhú,lǎn,lán,nǎng,wān,luán,xún quán quàn,xiǎn,yàn,gàn,yàn,yù,huǒ,huǒ biāo,miè,guāng,dēng,huī,xiāo,xiāo,huī,hōng,líng,zào,zhuàn,jiǔ,zhà yù,xiè,chì,zhuó,zāi,zāi,càn,yáng,qì,zhōng,fén bèn,niǔ,jiǒng guì,wén,pū,yì,lú,chuī,pī,kài,pàn,yán,yán,pàng fēng,mù,chǎo,liào,quē,kàng,dùn,guāng,xìn,zhì,guāng,guāng,wěi,qiàng,biān,dá,xiá,zhēng,zhú,kě,zhào zhāo,fú,bá,xiè,xiè,lìng,zhuō chù,xuàn,jù,tàn,páo bāo pào,jiǒng,páo fǒu,tái,tái,bǐng,yǎng,tōng,shǎn qián shān,zhù,zhà zhá,diǎn,wéi wèi,shí,liàn,chì,huǎng,zhōu,hū,shuò,làn,tīng,jiǎo yào,xù,héng,quǎn,liè,huàn,yáng yàng,xiāo,xiū,xiǎn,yín,wū,zhōu,yáo,shì,wēi,tóng dòng,miè,zāi,kài,hōng,lào luò,xiá,zhú,xuǎn,zhēng,pò,yān,huí huǐ,guāng,chè,huī,kǎo,jù,fán,shāo,yè,huì,none,tàng,jìn,rè,liè,xī,fú páo,jiǒng,xiè chè,pǔ,tīng,zhuó,tǐng,wán,hǎi,pēng,lǎng,yàn,xù,fēng,chì,róng,hú,xī,shū,hè,xūn hūn,kù,juān yè,xiāo,xī,yān,hàn,zhuàng,qū jùn,dì,xiè chè,jí qì,wù,yān,lǚ,hán,yàn,huàn,mèn,jú,dào,bèi,fén,lìn,kūn,hùn,tūn,xī,cuì,wú,hōng,chǎo jù,fǔ,wò ài,jiāo,zǒng cōng,fèng,píng,qióng,ruò,xī yì,qióng,xìn,zhuō chāo,yàn,yàn,yì,jué,yù,gàng,rán,pí,xiǒng yīng,gàng,shēng,chàng,shāo,xiǒng yīng,niǎn,gēng,qū,chén,hè,kuǐ,zhǒng,duàn,xiā,huī yùn xūn,fèng,liàn,xuān,xīng,huáng,jiǎo qiāo,jiān,bì,yīng,zhǔ,wěi,tuān,shǎn qián shān,xī yí,nuǎn,nuǎn,chán,yān,jiǒng,jiǒng,yù,mèi,shā shà,wèi,yè zhá,jìn,qióng,róu,méi,huàn,xù,zhào,wēi,fán,qiú,suì,yáng yàng,liè,zhǔ,jiē,zào,guā,bāo,hú,yūn yǔn,nǎn,shì,huǒ,biān,gòu,tuì,táng,chǎo,shān,ēn yūn,bó,huǎng,xié,xì,wù,xī,yūn yǔn,hé,hè xiāo,xī,yún,xióng,xióng,shǎn,qióng,yào,xūn xùn,mì,lián,yíng,wǔ,róng,gòng,yàn,qiàng,liū,xī,bì,biāo,cōng zǒng,lù āo,jiān,shú,yì,lóu,péng fēng,suī cuǐ,yì,tēng,jué,zōng,yù,hù,yí,zhì,āo áo,wèi,liǔ,hàn rǎn,ōu ǒu,rè,jiǒng,màn,kūn,shāng,cuàn,zèng,jiān,xī,xī,xī,yì,xiào,chì,huáng huǎng,chǎn dǎn chàn,yè,tán,rán,yàn,xún,qiāo,jùn,dēng,dùn,shēn,jiāo qiáo jué zhuó,fén,sī,liáo liǎo,yù,lín,tóng dòng,shāo,fén,fán,yàn yān,xún,làn,měi,tàng,yì,jiǒng,mèn,zhǔ,jiǎo,yíng,yù,yì,xué,lán,tài liè,zào,càn,suì,xī,què,zǒng,lián,huǐ,zhú,xiè,líng,wēi,yì,xié,zhào,huì,dá,nóng,lán,xū,xiǎn,hè,xūn,jìn,chóu,dào,yào,hè,làn,biāo,róng yíng,lì liè,mò,bào,ruò,lǜ,là liè,āo,xūn xùn,kuàng huǎng,shuò,liáo liǎo,lì,lú,jué,liáo liǎo,yàn xún,xī,xiè,lóng,yè,cān,rǎng,yuè,làn,cóng,jué,chóng,guàn,qú,chè,mí,tǎng,làn,zhú,lǎn làn,líng,cuàn,yù,zhǎo zhuǎ,zhǎo zhuǎ,pá,zhēng,páo,chēng chèn,yuán,ài,wéi wèi,han,jué,jué,fù fǔ,yé,bà,diē,yé,yáo,zǔ,shuǎng,ěr,pán,chuáng,kē,zāng,dié,qiāng,yōng,qiáng,piàn piān,bǎn,pàn,cháo,jiān,pái,dú,chuāng,yú,zhá,biān miàn,dié,bǎng,bó,chuāng,yǒu,yǒu yōng,dú,yá,chēng chèng,niú,niú,pìn,jiū lè,móu mù,tā,mǔ,láo,rèn,māng,fāng,máo,mù,gāng,wù,yàn,gē qiú,bèi,sì,jiàn,gǔ,yòu chōu,kē,shēng,mǔ,dǐ,qiān,quàn,quán,zì,tè,xī,máng,kēng,qiān,wǔ,gù,xī,lí,lí,pǒu,jī,gāng,zhí tè,bēn,quán,chún,dú,jù,jiā,jiān qián,fēng,piān,kē,jú,kào,chú,xì,bèi,luò,jiè,má,sān,wèi,máo lí,dūn,tóng,qiáo,jiàng,xī,lì,dú,liè,pái,piāo,bào,xī,chōu,wéi,kuí,chōu,quǎn,quǎn,quǎn bá,fàn,qiú,jǐ,chái,zhuó bào,hān àn,gē,zhuàng,guǎng,mǎ,yóu,kàng gǎng,pèi fèi,hǒu,yà,yín,huān fān,zhuàng,yǔn,kuáng,niǔ,dí,kuáng,zhòng,mù,bèi,pī,jú,yí quán chí,shēng xīng,páo,xiá,tuó yí,hú,líng,fèi,pī,nǐ,yǎo,yòu,gǒu,xuè,jū,dàn,bó,kǔ,xiǎn,níng,huán huān,hěn,jiǎo,hé mò,zhào,jié,xùn,shān,tà shì,róng,shòu,tóng dòng,lǎo,dú,xiá,shī,kuài,zhēng,yù,sūn,yú,bì,máng dòu,xī shǐ,juàn,lí,xiá,yín,suān,láng,bèi,zhì,yán,shā,lì,hàn,xiǎn,jīng,pái,fēi,xiāo,bài pí,qí,ní,biāo,yìn,lái,liè,jiān yàn,qiāng,kūn,yàn,guō,zòng,mí,chāng,yī yǐ,zhì,zhēng,yá wèi,měng,cāi,cù,shē,liè,diǎn,luó,hú,zōng,hú,wěi,fēng,wō,yuán,xīng,zhū,māo máo,wèi,chuàn chuān,xiàn,tuān tuàn,yà jiá qiè,náo,xiē hè gé hài,jiā,hóu,biān piàn,yóu,yóu,méi,chá,yáo,sūn,bó pò,míng,huá,yuán,sōu,mǎ,huán,dāi,yù,shī,háo,qiāng,yì,zhēn,cāng,háo gāo,màn,jìng,jiǎng,mò,zhāng,chán,áo,áo,háo,suǒ,fén fèn,jué,bì,bì,huáng,pú,lín lìn,xù,tóng,yào xiāo,liáo,shuò xī,xiāo,shòu,dūn,jiào,gé liè xiē,juàn,dú,huì,kuài,xiǎn,xiè,tǎ,xiǎn,xūn,níng,biān piàn,huò,nòu rú,méng,liè,náo nǎo yōu,guǎng,shòu,lú,tǎ,xiàn,mí,ráng,huān,náo yōu,luó,xiǎn,qí,jué,xuán,miào,zī,shuài lǜ,lú,yù,sù,wáng wàng,qiú,gǎ,dīng,lè,bā,jī,hóng,dì,chuàn,gān,jiǔ,yú,qǐ,yú,chàng yáng,mǎ,hóng,wǔ,fū,mín wén,jiè,yá,bīn fēn,biàn,bàng,yuè,jué,mén yǔn,jué,wán,jiān qián,méi,dǎn,pín,wěi,huán,xiàn,qiāng cāng,líng,dài,yì,án gān,píng,diàn,fú,xuán xián,xǐ,bō,cī cǐ,gǒu,jiǎ,sháo,pò,cí,kē,rǎn,shēng,shēn,yí tāi,zǔ jù,jiā,mín,shān,liǔ,bì,zhēn,zhēn,jué,fà,lóng,jīn,jiào,jiàn,lì,guāng,xiān,zhōu,gǒng,yān,xiù,yáng,xǔ,luò,sù,zhū,qín,yín kèn,xún,bǎo,ěr,xiàng,yáo,xiá,héng,guī,chōng,xù,bān,pèi,lǎo,dāng,yīng,hún huī,wén,é,chéng,dì tí,wǔ,wú,chéng,jùn,méi,bèi,tǐng,xiàn,chù,hán,xuán qióng,yán,qiú,xuàn,láng,lǐ,xiù,fú fū,liú,yá,xī,líng,lí,jīn,liǎn,suǒ,suǒ,fēng,wán,diàn,pín bǐng,zhǎn,cuì sè,mín,yù,jū,chēn,lái,mín,shèng,wéi yù,tiǎn tiàn,shū,zhuó zuó,běng pěi,chēng,hǔ,qí,è,kūn,chāng,qí,běng,wǎn,lù,cóng,guǎn,yǎn,diāo,bèi,lín,qín,pí,pá,què,zhuó,qín,fà,jīn,qióng,dǔ,jiè,hún huī,yǔ,mào,méi,chūn,xuān,tí,xīng,dài,róu,mín,jiān,wěi,ruǎn,huàn,xié jiē,chuān,jiǎn,zhuàn,chàng yáng,liàn,quán,xiá,duàn,yuàn,yé,nǎo,hú,yīng,yú,huáng,ruì,sè,liú,shī,róng,suǒ,yáo,wēn,wǔ,zhēn,jìn,yíng yǐng,mǎ,tāo,liú,táng,lì,láng,guī,tiàn tián zhèn,qiāng cāng,cuō,jué,zhǎo,yáo,ài,bīn pián,tú shū,cháng,kūn,zhuān,cōng,jǐn,yī,cuǐ,cōng,qí,lí,jǐng,zǎo suǒ,qiú,xuán,áo,liǎn,mén,zhāng,yín,yè,yīng,zhì,lù,wú,dēng,xiù,zēng,xún,qú,dàng,lín,liáo,qióng jué,sù,huáng,guī,pú,jǐng,fán,jīn,liú,jī,huì,jǐng,ài,bì,càn,qú,zǎo,dāng,jiǎo,guǎn,tǎn,huì kuài,huán,sè,suì,tián,chǔ,yú,jìn,lú fū,bīn pián,shú,wèn,zuǐ,lán,xǐ,jì zī,xuán,ruǎn,wò,gài,léi,dú,lì,zhì,róu,lí,zàn,qióng,tì,guī,suí,là,lóng,lú,lì,zàn,làn,yīng,mí xǐ,xiāng,qióng wěi wèi,guàn,dào,zàn,huán yè yà,guā,bó,dié,bó páo,hù,zhí hú,piáo,bàn,ráng,lì,wǎ wà,none,xiáng hóng,qián wǎ,bǎn,pén,fǎng,dǎn,wèng,ōu,none,none,wa,hú,líng,yí,píng,cí,none,juàn juān,cháng,chī,none,dàng,wā,bù,zhuì,píng,biān,zhòu,zhēn,none,cí,yīng,qì,xián,lǒu,dì,ōu,méng,zhuān,bèng,lìn,zèng,wǔ,pì,dān,wèng,yīng,yǎn,gān,dài,shèn shén,tián,tián,hán,cháng,shēng,qíng,shēn,chǎn,chǎn,ruí,shēng,sū,shēn,yòng,shuǎi,lù,fǔ,yǒng,béng,béng,níng nìng,tián,yóu,jiǎ,shēn,yóu zhá,diàn,fú,nán,diàn tián shèng,pīng,tǐng dīng,huà,tǐng dīng,zhèn,zāi zī,méng,bì,bì qí,mǔ,xún,liú,chàng,mǔ,yún,fàn,fú,gēng,tián,jiè,jiè,quǎn,wèi,fú bì,tián,mǔ,none,pàn,jiāng,wā,dá fú,nán,liú,běn,zhěn,xù chù,mǔ,mǔ,cè jì,zāi zī,gāi,bì,dá,zhì chóu shì,lüè,qí,lüè,fān pān,yī,fān pān,huà,shē yú,shē,mǔ,jùn,yì,liú,shē,dié,chóu,huà,dāng dàng dǎng,zhuì,jī,wǎn,jiāng jiàng,chéng,chàng,tuǎn,léi,jī,chā,liú,dié,tuǎn,lín lìn,jiāng,jiāng qiáng,chóu,pì,dié,dié,pǐ yǎ shū,jié qiè,dàn,shū,shū,zhì dì,yí nǐ,nè,nǎi,dīng,bǐ,jiē,liáo,gāng,gē yì,jiù,zhǒu,xià,shàn,xū,nüè yào,lì lài,yáng,chèn,yóu,bā,jiè,jué xuè,qí,yǎ xiā,cuì,bì,yì,lì,zòng,chuāng,fēng,zhù,pào,pí,gān,kē,cī,xuē,zhī,dǎn,zhěn,fá biǎn,zhǐ,téng,jū,jí,fèi féi,gōu,shān diàn,jiā,xuán,zhà,bìng,niè,zhèng zhēng,yōng,jìng,quán,téng chóng,tōng tóng,yí,jiē,wěi yòu yù,huí,tān shǐ,yǎng,zhì,zhì,hén,yǎ,mèi,dòu,jìng,xiāo,tòng,tū,máng,pǐ,xiāo,suān,pū pù,lì,zhì,cuó,duó,wù,shā,láo,shòu,huàn,xián,yì,bēng péng,zhàng,guǎn,tán,fèi féi,má,má lìn,chī,jì,tiǎn diàn,ān yè è,chì,bì,bì,mín,gù,duī,kē ē,wěi,yū,cuì,yǎ,zhú,cù,dàn dān,shèn,zhǒng,zhì chì,yù,hóu,fēng,là,yáng,chén,tú,yǔ,guō,wén,huàn,kù,jiǎ xiá xiā,yīn,yì,lòu,sào,jué,chì,xī,guān,yì,wēn,jí,chuāng,bān,huì lěi,liú,chài cuó,shòu,nüè yào,diān chēn,dá da,biē biě,tān,zhàng,biāo,shèn,cù,luǒ,yì,zòng,chōu,zhàng,zhài,sòu,sè,qué,diào,lòu,lòu,mò,qín,yǐn,yǐng,huáng,fú,liáo,lóng,qiáo jiào,liú,láo,xián,fèi,dàn dān,yìn,hè,ái,bān,xián,guān,guì wēi,nòng nóng,yù,wēi,yì,yōng,pǐ,lěi,lì lài,shǔ,dàn,lǐn,diàn,lǐn,lài,biē biě,jì,chī,yǎng,xuǎn,jiē,zhēng,mèng,lì,huò,lài,jī,diān,xuǎn,yǐng,yǐn,qú,yōng,tān,diān,luǒ,luán,luán,bō,bō bǒ,guǐ,bá,fā,dēng,fā,bái,bǎi,qié,jí bī,zào,zào,mào,de dí dì,pā bà,jiē,huáng,guī,cǐ,líng,gāo háo,mò,jí,jiǎo,pěng,gāo yáo,ái,é,hào,hàn,bì,wǎn,chóu,qiàn,xī,ái,xiǎo,hào,huàng,hào,zé,cuǐ,hào,xiǎo,yè,pó,hào,jiǎo,ài,xīng,huàng,lì luò bō,piǎo,hé,jiào,pí,gǎn,pào,zhòu,jūn,qiú,cūn,què,zhā,gǔ,jūn,jūn,zhòu,zhā cǔ,gǔ,zhāo zhǎn dǎn,dú,mǐn,qǐ,yíng,yú,bēi,diào,zhōng,pén,hé,yíng,hé,yì,bō,wǎn,hé,àng,zhǎn,yán,jiān jiàn,hé,yū,kuī,fàn,gài gě hé,dào,pán,fǔ,qiú,shèng chéng,dào,lù,zhǎn,méng,lí,jìn,xù,jiān jiàn,pán,guàn,ān,lú,xǔ,zhōu chóu,dàng,ān,gǔ,lì,mù,dīng,gàn,xū,máng,máng wàng,zhí,qì,yuǎn,xián tián,xiāng xiàng,dǔn,xīn,xì pǎn,pàn,fēng,dùn,mín,míng,shěng xǐng,shì,yún hùn,miǎn,pān,fǎng,miǎo,dān,méi,mào,kàn kān,xiàn,kōu,shì,yāng yǎng yìng,zhēng,yǎo āo ǎo,shēn,huò,dà,zhěn,kuàng,jū xū kōu,shèn,yí chì,shěng,mèi,mò miè,zhù,zhēn,zhēn,mián,shì,yuān,dié tì,nì,zì,zì,chǎo,zhǎ,xuàn,bǐng fǎng,pàng pán,lóng,guì suī,tóng,mī mí,dié zhì,dì,nè,míng,xuàn shùn xún,chī,kuàng,juàn,móu,zhèn,tiào,yáng,yǎn,mò,zhòng,mò,zhuó zháo zhāo zhe,zhēng,méi,suō,qiáo shào xiāo,hàn,huǎn,dì,chěng,cuó zhuài,juàn,é,miǎn,xiàn,xī,kùn,lài,jiǎn,shǎn,tiǎn,gùn,wān,lèng,shì,qióng,lì,yá,jīng,zhēng,lí,lài,suì zuì,juàn,shuì,huī suī,dū,bì,bì pì,mù,hūn,nì,lù,yì zé gāo,jié,cǎi,zhǒu,yú,hūn,mà,xià,xǐng xìng,huī,hùn,zāi,chǔn,jiān,mèi,dǔ,hóu,xuān,tí,kuí,gāo,ruì,mào,xù,fá,wò,miáo,chǒu,guì wèi kuì,mī mí,wěng,kòu jì,dàng,chēn,kē,sǒu,xiā,qióng huán,mò,míng,mán mén,fèn,zé,zhàng,yì,diāo dōu,kōu,mò,shùn,cōng,lóu lǘ lou,chī,mán mén,piǎo,chēng,guī,méng měng,wàn,rún shùn,piē,xī,qiáo,pú,zhǔ,dèng,shěn,shùn,liǎo liào,chè,xián jiàn,kàn,yè,xuè,tóng,wǔ mí,lín,guì kuì,jiàn,yè,ài,huì,zhān,jiǎn,gǔ,zhào,qú jù,wéi,chǒu,sào,nǐng chēng,xūn,yào,huò yuè,mēng,mián,pín,mián,lěi,kuàng guō,jué,xuān,mián,huò,lú,méng měng,lóng,guàn quán,mǎn mán,xǐ,chù,tǎng,kàn,zhǔ,máo,jīn qín guān,jīn qín guān,yù xù jué,shuò,zé,jué,shǐ,yǐ,shěn,zhī zhì,hóu hòu,shěn,yǐng,jǔ,zhōu,jiǎo jiáo,cuó,duǎn,ǎi,jiǎo jiáo,zēng,yuē,bà,shí dàn,dìng,qì,jī,zǐ,gān,wù,zhé,kū,gāng qiāng kòng,xī,fán,kuàng,dàng,mǎ,shā,dān,jué,lì,fū,mín,è,xū huā,kāng,zhǐ,qì qiè,kǎn,jiè,pīn bīn fēn,è,yà,pī,zhé,yán yàn,suì,zhuān,chē,dùn,wǎ,yàn,jīn,fēng,fǎ,mò,zhǎ,jū,yù,kē luǒ,tuó,tuó,dǐ,zhài,zhēn,ě,fú fèi,mǔ,zhù zhǔ,lì lā lá,biān,nǔ,pīng,pēng,líng,pào,lè,pò,bō,pò,shēn,zá,ài,lì,lóng,tóng,yòng,lì,kuàng,chǔ,kēng,quán,zhū,kuāng guāng,guī,è,náo,qià,lù,wěi guì,ài,luò gè,kèn xiàn gǔn yǐn,xíng,yán yàn,dòng,pēng píng,xī,lǎo,hóng,shuò shí,xiá,qiāo,qíng,wéi wèi ái,qiáo,yì,kēng,xiāo,què kè kù,chàn,láng,hōng,yù,xiāo,xiá,mǎng bàng,luò lòng,yǒng tóng,chē,chè,wò,liú,yìng,máng,què,yàn,shā,kǔn,yù,chì,huā,lǔ,chěn,jiǎn,nüè,sōng,zhuó,kēng kěng,péng,yān yǎn,zhuì chuí duǒ,kōng,chēng,qí,zòng cóng,qìng,lín,jūn,bō,dìng,mín,diāo,jiān zhàn,hè,lù liù,ài,suì,què xī,léng,bēi,yín,duì,wǔ,qí,lún lǔn lùn,wǎn,diǎn,náo gāng,bèi,qì,chěn,ruǎn,yán,dié,dìng,zhóu,tuó,jié yà,yīng,biǎn,kè,bì,wěi wèi,shuò shí,zhēn,duàn,xiá,dàng,tí dī,nǎo,pèng,jiǎn,dì,tàn,chá chā,tián,qì,dùn,fēng,xuàn,què,què qiāo,mǎ,gōng,niǎn,sù xiè,é,cí,liú liù,sī tí,táng,bàng páng,huá kě gū,pī,kuǐ wěi,sǎng,lěi,cuō,tián,xiá qià yà,xī,lián qiān,pán,wèi ái gài,yǔn,duī,zhé,kē,lá lā,zhuān,yáo,gǔn,zhuān,chán,qì,áo qiāo,pēng pèng,liù,lǔ,kàn,chuǎng,chěn,yīn yǐn,lěi léi,biāo,qì,mó mò,qì zhú,cuī,zōng,qìng,chuò,lún,jī,shàn,láo luò,qú,zēng,dèng,jiàn,xì,lín,dìng,diàn,huáng,pán bō,jí shé,qiāo,dī,lì,jiàn,jiāo,xī,zhǎng,qiáo,dūn,jiǎn,yù,zhuì,hé qiāo qiào,kè huò,zé,léi lěi,jié,chǔ,yè,què hú,dàng,yǐ,jiāng,pī,pī,yù,pīn,è qì,ài,kē,jiān,yù,ruǎn,méng,pào,cí,bō,yǎng,miè,cǎ,xián xín,kuàng,léi lěi lèi,lěi,zhì,lì,lì,fán,què,pào,yīng,lì,lóng,lóng,mò,bó,shuāng,guàn,jiān,cǎ,yán yǎn,shì,shì,lǐ,réng,shè,yuè,sì,qí,tā,mà,xiè,yāo,xiān,zhǐ qí,qí,zhǐ,bēng fāng,duì,zhòng,rèn,yī,shí,yòu,zhì,tiáo,fú,fù,mì bì,zǔ,zhī,suàn,mèi,zuò,qū,hù,zhù,shén,suì,cí,chái,mí,lǚ,yǔ,xiáng,wú,tiāo,piào piāo,zhù,guǐ,xiá,zhī,jì zhài,gào,zhēn,gào,shuì lèi,jìn,shèn,gāi,kǔn,dì,dǎo,huò,táo,qí,gù,guàn,zuì,líng,lù,bǐng,jīn jìn,dǎo,zhí,lù,chán shàn,bì pí,chǔ,huī,yǒu,xì,yīn,zī,huò,zhēn,fú,yuàn,xú,xiǎn,shāng yáng,tí zhǐ,yī,méi,sī,dì,bèi,zhuó,zhēn,yíng,jì,gào,táng,sī,mà,tà,fù,xuān,qí,yù,xǐ,jī jì,sì,shàn chán,dàn,guì,suì,lǐ,nóng,mí,dǎo,lì,ráng,yuè,tí,zàn,lèi,róu,yǔ,yú yù ǒu,lí,xiè,qín,hé,tū,xiù,sī,rén,tū,zǐ zì,chá ná,gǎn,yì zhí,xiān,bǐng,nián,qiū,qiū,zhǒng zhòng chóng,fèn,hào mào,yún,kē,miǎo,zhī,jīng,bǐ,zhǐ,yù,mì bì,kù kū,bàn,pī,ní nì,lì,yóu,zū,pī,bó,líng,mò,chèng,nián,qín,yāng,zuó,zhì,dī,shú,jù,zǐ,huó kuò,jī,chēng chèn chèng,tóng,shì zhì,huó kuò,huō,yīn,zī,zhì,jiē,rěn,dù,yí,zhū,huì,nóng,fù pū,xī,gǎo,láng,fū,xùn zè,shuì,lǚ,kǔn,gǎn,jīng,tí,chéng,tú shǔ,shāo shào,shuì,yà,lǔn,lù,gū,zuó,rěn,zhùn zhǔn,bàng,bài,jī qí,zhī,zhì,kǔn,léng lēng líng,péng,kē,bǐng,chóu,zuì zú sū,yù,sū,lüè,xiāng,yī,xì qiè,biǎn,jì,fú,pì bì,nuò,jiē,zhǒng zhòng,zōng zǒng,xǔ xū,chēng chèn chèng,dào,wěn,xián jiān liàn,zī jiū,yù,jì,xù,zhěn,zhì,dào,jià,jī qǐ,gǎo,gǎo,gǔ,róng,suì,ròng,jì,kāng,mù,cǎn shān cēn,mén méi,zhì,jì,lù,sū,jī,yǐng,wěn,qiū,sè,hè,yì,huáng,qiè,jǐ jì,suì,xiāo rào,pú,jiāo,zhuō bó,tóng zhǒng,zuō,lǔ,suì,nóng,sè,huì,ráng,nuò,yǔ,pīn,jì,tuí,wěn,chēng chèn chèng,huò,kuàng,lǚ,biāo pāo,sè,ráng,zhuō jué,lí,cuán zàn,xué,wā,jiū,qióng,xī,qióng,kōng kòng kǒng,yū yǔ,shēn,jǐng,yào,chuān,zhūn,tū,láo,qiè,zhǎi,yǎo,biǎn,báo,yǎo,bìng,wā,zhú kū,jiào liáo liù,qiào,diào,wū,wā guī,yáo,zhì,chuāng,yào,tiǎo yáo,jiào,chuāng,jiǒng,xiāo,chéng,kòu,cuàn,wō,dàn,kū,kē,zhuó,huò,sū,guān,kuī,dòu,zhuō,yìn xūn,wō,wā,yà yē,yú,jù,qióng,yáo,yáo,tiǎo,cháo,yǔ,tián diān yǎn,diào,jù,liào,xī,wù,kuī,chuāng,chāo kē,kuǎn cuàn,kuǎn cuàn,lóng,chēng chèng,cuì,liáo,zào,cuàn,qiào,qióng,dòu,zào,lǒng,qiè,lì,chù,shí,fù,qiān,chù qì,hóng,qí,háo,shēng,fēn,shù,miào,qǔ kǒu,zhàn,zhù,líng,lóng,bìng,jìng,jìng,zhāng,bǎi,sì,jùn,hóng,tóng,sǒng,jìng zhěn,diào,yì,shù,jìng,qǔ,jié,píng,duān,lí,zhuǎn,céng zēng,dēng,cūn,wāi,jìng,kǎn kàn,jìng,zhú,zhú dǔ,lè jīn,péng,yú,chí,gān,máng,zhú,wán,dǔ,jī,jiǎo jiào,bā,suàn,jí,qǐn,zhào,sǔn,yá,zhuì ruì,yuán,hù,háng hàng,xiào,cén jìn hán,pí bì,bǐ,jiǎn,yǐ,dōng,shān,shēng,dā xiá nà,dí,zhú,nà,chī,gū,lì,qiè,mǐn,bāo,tiáo,sì,fú,cè,bèn,fá,dá,zǐ,dì,líng,zuó zé,nú,fú fèi,gǒu,fán,jiā,gě,fàn,shǐ,mǎo,pǒ,tì,jiān,qióng,lóng lǒng,mǐn,biān,luò,guì,qū,chí,yīn,yào,xiǎn,bǐ,qióng,kuò,děng,jiǎo jiào,jīn,quán,sǔn,rú,fá,kuāng,zhù zhú,tǒng,jī,dá dā,háng,cè,zhòng,kòu,lái,bì,shāi,dāng,zhēng,cè,fū,yún jūn,tú,pá,lí,láng làng,jǔ,guǎn,jiǎn,hán,tǒng,xiá,zhì zhǐ,chéng,suàn,shì,zhù,zuó,xiǎo,shāo,tíng,cè,yán,gào,kuài,gān,chóu,kuāng,gàng,yún,o,qiān,xiǎo,jiǎn,póu bù fú pú,lái,zōu,pái bēi,bì,bì,gè,tái chí,guǎi dài,yū,jiān,zhào dào,gū,chí,zhēng,qìng jīng,shà,zhǒu,lù,bó,jī,lín lǐn,suàn,jùn qūn,fú,zhá,gū,kōng,qián,quān,jùn,chuí,guǎn,wǎn yuān,cè,zú,pǒ,zé,qiè,tuò,luó,dān,xiāo,ruò,jiàn,xuān,biān,sǔn,xiāng,xiǎn,píng,zhēn,xīng,hú,shī yí,zhù,yuē yào chuò,chūn,lǜ,wū,dǒng,shuò xiāo qiào,jí,jié,huáng,xīng,mèi,fàn,chuán,zhuàn,piān,fēng,zhù zhú,hóng,qiè,hóu,qiū,miǎo,qiàn,gū,kuì,yì,lǒu,yún,hé,táng,yuè,chōu,gāo,fěi,ruò,zhēng,gōu,niè,qiàn,xiǎo,cuàn,gōng gǎn lǒng,péng páng,dǔ,lì,bì,zhuó huò,chú,shāi,chí,zhù,qiāng cāng,lóng lǒng,lán,jiǎn jiān,bù,lí,huì,bì,zhú dí,cōng,yān,péng,cēn zān cǎn,zhuàn zuàn suǎn,pí,piǎo biāo,dōu,yù,miè,tuán zhuān,zé,shāi,guó guì,yí,hù,chǎn,kòu,cù,píng,zào,jī,guǐ,sù,lǒu,cè jí,lù,niǎn,suō,cuàn,diāo,suō,lè,duàn,zhù,xiāo,bó,mì miè,shāi sī,dàng,liáo,dān,diàn,fǔ,jiǎn,mǐn,kuì,dài,jiāo,dēng,huáng,sǔn zhuàn,láo,zān,xiāo,lù,shì,zān,qí,pái,qí,pái,gǎn gàn,jù,lù,lù,yán,bò bǒ,dāng,sài,zhuā,gōu,qiān,lián,bù bó,zhòu,lài,shi,lán,kuì,yú,yuè,háo,zhēn jiān,tái,tì,niè,chóu,jí,yí,qí,téng,zhuàn,zhòu,fān pān biān,sǒu shǔ,zhòu,qiān,zhuó,téng,lù,lú,jiǎn jiān,tuò,yíng,yù,lài,lóng lǒng,qiè,lián,lán,qiān,yuè,zhōng,qú,lián,biān,duàn,zuǎn,lí,shāi,luó,yíng,yuè,zhuó,yù,mǐ,dí,fán,shēn,zhé,shēn,nǚ,hé,lèi,xiān,zǐ,ní,cùn,zhàng,qiān,zhāi,bǐ,bǎn,wù,shā chǎo,kāng jīng,róu,fěn,bì,cuì,yǐn,zhé,mǐ,tà,hù,bā,lì,gān,jù,pò,yù,cū,zhān,zhòu,chī,sù,tiào,lì,xī,sù,hóng,tóng,zī cí,cè sè,yuè,zhōu yù,lín,zhuāng,bǎi,lāo,fèn,ér,qū,hé,liáng,xiàn,fū fú,liáng,càn,jīng,lǐ,yuè,lù,jú,qí,cuì,bài,zhāng,lín,zòng,jīng,guǒ,huā,sǎn shēn,shēn,táng,biān biǎn,róu,miàn,hóu,xǔ,zòng,hū hú hù,jiàn,zān,cí,lí,xiè,fū,nuò,bèi,gǔ gòu,xiǔ,gāo,táng,qiǔ,jiā,cāo,zhuāng,táng,mí méi,sǎn shēn,fèn,zāo,kāng,jiàng,mó,sǎn shēn,sǎn,nuò,xī,liáng,jiàng,kuài,bó,huán,shǔ,zòng,xiàn,nuò,tuán,niè,lì,zuò,dí,niè,tiào,làn,mì sī,sī,jiū jiǔ,xì jì,gōng,zhēng zhěng,jiū,gōng,jì,chà chǎ,zhòu,xún,yuē yāo,hóng gōng,yū,hé gē,wán,rèn,wěn,wén wèn,qiú,nà,zī,tǒu,niǔ,fóu,jì jié jiè,shū,chún,pī pí bǐ,zhèn,shā,hóng,zhǐ,jí,fēn,yún,rèn,dǎn,jīn jìn,sù,fǎng,suǒ,cuì,jiǔ,zhā zā,hā,jǐn,fū fù,zhì,qī,zǐ,chōu chóu,hóng,zhā zā,léi lěi lèi,xì,fú,xiè,shēn,bō bì,zhù,qū qǔ,líng,zhù,shào,gàn,yǎng,fú,tuó,zhěn tiǎn,dài,chù,shī,zhōng,xián,zǔ,jiōng jiǒng,bàn,qú,mò,shù,zuì,kuàng,jīng,rèn,háng,xiè,jié jiē,zhū,chóu,guà kuā,bǎi mò,jué,kuàng,hú,cì,huán gēng,gēng,tāo,xié jié,kù,jiǎo,quán shuān,gǎi ǎi,luò lào,xuàn,bēng bīng pēng,xiàn,fú,gěi jǐ,tōng tóng dòng,róng,tiào diào dào,yīn,lěi lèi léi,xiè,juàn,xù,gāi hài,dié,tǒng,sī,jiàng,xiáng,huì,jué,zhí,jiǎn,juàn,chī zhǐ,miǎn wèn mán wàn,zhèn,lǚ,chéng,qiú,shū,bǎng,tǒng,xiāo,huán huàn wàn,qīn xiān,gěng,xū,tí tì,xiù,xié,hóng,xì,fú,tīng,suí,duì,kǔn,fū,jīng,hù,zhī,yán xiàn,jiǒng,féng,jì,xù,rěn,zōng zèng,lín chēn,duǒ,lì liè,lǜ,jīng,chóu,quǎn,shào,qí,qí,zhǔn zhùn,jī qí,wǎn,qiàn qīng zhēng,xiàn,shòu,wéi,qìng qǐ,táo,wǎn,gāng,wǎng,bēng běng bèng,zhuì,cǎi,guǒ,cuì,lún guān,liǔ,qǐ,zhàn,bì,chuò chāo,líng,mián,qī,jī,tián tǎn chān,zōng,gǔn,zōu,xī,zī,xìng,liǎng,jǐn,fēi,ruí,mín,yù,zǒng,fán,lǜ lù,xù,yīng,shàng,zī,xù,xiāng,jiān,kè,xiàn,ruǎn ruàn,mián,jī qī,duàn,chóng zhòng,dì,mín,miáo máo,yuán,xiè yè,bǎo,sī,qiū,biān,huǎn,gēng gèng,zǒng,miǎn,wèi,fù,wěi,tōu xū shū,gōu,miǎo,xié,liàn,zōng zòng,biàn pián,gǔn yùn,yīn,tí,guā wō,zhì,yùn yūn wēn,chēng,chán,dài,xié,yuán,zǒng,xū,shéng,wēi,gēng gèng,xuān,yíng,jìn,yì,zhuì,nì,bāng bàng,gǔ hú,pán,zhòu,jiān,cī cuò suǒ,quán,shuǎng,yùn yūn wēn,xiá,cuī suī shuāi,xì,róng rǒng ròng,tāo,fù,yún,zhěn,gǎo,rù,hú,zài zēng,téng,xiàn xuán,sù,zhěn,zòng,tāo,huǎng,cài,bì,féng fèng,cù,lí,suō sù,yǎn yǐn,xǐ,zòng zǒng,léi,zhuàn juàn,qiàn,màn,zhí,lǚ,mù mò,piǎo piāo,lián,mí,xuàn,zǒng,jì,shān,suì,fán pó,lǜ,bēng běng bèng,yī,sāo,móu miù miào mù liǎo,yáo yóu zhòu,qiǎng,shéng,xiān,jì,zōng zòng,xiù,rán,xuàn,suì,qiāo,zēng zèng,zuǒ,zhī zhì,shàn,sǎn,lín,jú jué,fān,liáo,chuō chuò,zūn zǔn,jiàn,rào,chǎn chán,ruǐ,xiù,huì huí,huà,zuǎn,xī,qiǎng,wén,da,shéng,huì,xì jì,sè,jiǎn,jiāng,huán,qiāo sāo,cōng,xiè,jiǎo zhuó,bì,dàn tán chán,yì,nǒng,suì,yì,shā,rú,jì,bīn,qiǎn,lán,pú fú,xūn,zuǎn,zī,péng,yào lì,mò,lèi,xiè,zuǎn,kuàng,yōu,xù,léi,xiān,chán,jiǎo,lú,chán,yīng,cái,xiāng rǎng,xiān,zuī,zuǎn,luò,lí xǐ lǐ sǎ,dào,lǎn,léi,liàn,sī,jiū,yū,hóng gōng,zhòu,xiān qiàn,hé gē,yuē yāo,jí,wán,kuàng,jì jǐ,rèn,wěi,yún,hóng,chún,pī pí bǐ,shā,gāng,nà,rèn,zòng zǒng,lún guān,fēn,zhǐ,wén wèn,fǎng,zhù,zhèn,niǔ,shū,xiàn,gàn,xiè,fú,liàn,zǔ,shēn,xì,zhī zhì,zhōng,zhòu,bàn,fú,chù,shào,yì,jīng,dài,bǎng,róng,jié jiē,kù,rào,dié,háng,huì,gěi jǐ,xuàn,jiàng,luò lào,jué,jiǎo,tǒng,gěng,xiāo,juàn,xiù,xì,suí,tāo,jì,tí tì,jì,xù,líng,yīng,xù,qǐ,fēi,chuò chāo,shàng,gǔn,shéng,wéi,mián,shòu,bēng běng bèng,chóu,táo,liǔ,quǎn,zōng zèng,zhàn,wǎn,lǜ lù,zhuì,zī,kè,xiāng,jiān,miǎn,lǎn,tí,miǎo,jī qī,yùn yūn wēn,huì huí,sī,duǒ,duàn,biàn pián,xiàn,gōu,zhuì,huǎn,dì,lǚ,biān,mín,yuán,jìn,fù,rù,zhěn,féng fèng,cuī suī shuāi,gǎo,chán,lí,yì,jiān,bīn,piǎo piāo,màn,léi,yīng,suō sù,móu miù miào mù liǎo,sāo,xié,liáo,shàn,zēng zèng,jiāng,qiǎn,qiāo sāo,huán,jiǎo zhuó,zuǎn,fǒu,xiè,gāng,fǒu,quē,fǒu,quē,bō,píng,xiàng,zhào,gāng,yīng,yīng,qìng,xià,guàn,zūn,tán,chēng,qì,wèng,yīng,léi,tán,lú,guàn,wǎng,wǎng,wǎng,wǎng,hǎn,wǎng,luó,fú,shēn,fá,gū,zhǔ,jū,máo,gǔ,mín,gāng,bà ba pí,guà,tí,juàn,fú,shēn,yǎn,zhào,zuì,guǎi guà,zhuó,yù,zhì,ǎn,fá,lǎn,shǔ,sī,pí,mà,liǔ,bà ba pí,fá,lí,cháo,wèi,bì,jì,zēng,chōng,liǔ,jī,juàn,mì,zhào,luó,pí,jī,jī,luán,yáng xiáng,mǐ,qiāng,dá,měi,yáng xiáng,líng,yǒu,fén,bā,gāo,yàng,gǔ,qiāng,zāng,měi gāo,líng,yì xī,zhù,dī,xiū,qiǎng,yí,xiàn,róng,qún,qún,qiǎng,huán,suō,xiàn,yì,yōu,qiāng kòng,qián xián yán,yú,gēng,jié,tāng,yuán,xī,fán,shān,fén,shān,liǎn,léi,gēng,nóu,qiàng,chàn,yǔ,hóng gòng,yì,chōng,wēng,fēn,hóng,chì,chì,cuì,fú,xiá,běn,yì,là,yì,pī bì pō,líng,liù,zhì,qú yù,xí,xié,xiáng,xī,xī,ké,qiáo qiào,huì,huī,xiāo,shà,hóng,jiāng,dí zhái,cuì,fěi,dào zhōu,shà,chì,zhù,jiǎn,xuān,chì,piān,zōng,wán,huī,hóu,hé,hè,hàn,áo,piāo,yì,lián,hóu qú,áo,lín,pěn,qiáo qiào,áo,fān,yì,huì,xuān,dào,yào,lǎo,lǎo,kǎo,mào,zhě,qí shì,gǒu,gǒu,gǒu,dié,dié,ér,shuǎ,ruǎn nuò,ér nài,nài,duān zhuān,lěi,tīng,zǐ,gēng,chào,hào,yún,bà pá,pī,sì chí,sì,qù chú,jiā,jù,huō,chú,lào,lún lǔn,jí jiè,tǎng,ǒu,lóu,nòu,jiǎng,pǎng,zhá zé,lóu,jī,lào,huò,yōu,mò,huái,ěr,yì,dīng,yé yē,dā,sǒng,qín,yún yíng,chǐ,dān,dān,hóng,gěng,zhí,pàn,niè,dān,zhěn,chè,líng,zhēng,yǒu,wà tuǐ zhuó,liáo,lóng,zhí,níng,tiāo,ér nǜ,yà,tiē zhé,guō,xù,lián,hào,shèng,liè,pìn,jīng,jù,bǐ,dǐ zhì,guó,wén,xù,pīng,cōng,dìng,ní,tíng,jǔ,cōng,kuī,lián,kuì,cōng,lián,wēng,kuì,lián,lián,cōng,áo,shēng,sǒng,tīng,kuì,niè,zhí,dān,níng,qié,nǐ jiàn,tīng,tīng,lóng,yù,yù,zhào,sì,sù,yì,sù,sì,zhào,zhào,ròu,yì,lèi lē,jī,qiú,kěn,cào,gē,bó dí,huàn,huāng,chǐ,rèn,xiāo xiào,rǔ,zhǒu,yuān,dù dǔ,gāng,róng chēn,gān,chāi,wò,cháng,gǔ,zhī,qín hán hàn,fū,féi,bān,pēi,pàn,jiān,fáng,zhūn chún,yóu,nà,āng,kěn,rán,gōng,yù,wěn,yáo,qí,pí bǐ bì,qiǎn,xī,xī,fèi,kěn,jǐng,tài,shèn,zhǒng,zhàng,xié,shèn,wèi,zhòu,dié,dǎn,fèi bì,bá,bó,qú,tián,bèi bēi,guā,tāi,zǐ fèi,fěi kū,zhī,nì,píng pēng,zì,fū fú zhǒu,pàn,zhēn,xián,zuò,pēi,jiǎ,shèng,zhī,bāo,mǔ,qū,hú,qià,chǐ,yìn,xū,yāng,lóng,dòng,kǎ,lú,jìng,nǔ,yān,pāng,kuà,yí,guāng,hǎi,gē gé,dòng,chī,jiāo,xiōng,xiōng,ér,àn,héng,pián,néng nài,zì,guī kuì,zhēng,tiǎo,zhī,cuì,méi,xié,cuì,xié,mài,mài mò,jǐ,xié,nín,kuài,sà,zàng,qí,nǎo,mǐ,nóng,luán,wàn,bó,wěn,wǎn,xiū,jiǎo,jìng,róu,hēng,cuǒ,liè,shān,tǐng,méi,chún,shèn,jiá,none,juān,cù,xiū,xìn,tuō,pāo,chéng,něi,fǔ,dòu,tuō,niào,nǎo,pǐ,gǔ,luó,lì,liǎn,zhàng,cuī,jiē,liǎng,shuí,pí,biāo,lún,pián,guò,juàn,chuí,dàn,tiǎn,něi,jīng,nái,là xī,yè,ā yān,rèn,shèn,zhuì,fǔ,fǔ,jū,féi,qiāng,wàn,dòng,pí,guó,zōng,dìng,wò,méi,ruǎn,zhuàn,chì,còu,luó,ǒu,dì,ān,xīng,nǎo,shù,shuàn,nǎn,yùn,zhǒng,róu,è,sāi,tú,yāo,jiàn,wěi,jiǎo,yú,jiā,duàn,bì,cháng,fù,xiàn,nì,miǎn,wà,téng,tuǐ,bǎng,qiǎn,lǚ,wà,shòu,táng,sù,zhuì,gé,yì,bó,liáo,jí,pí,xié,gāo gào,lǚ,bìn,ōu,cháng,lù biāo,guó,pāng,chuái,biāo,jiǎng,fū,táng,mó,xī,zhuān chuán chún zhuǎn,lǜ,jiāo,yìng,lǘ,zhì,xuě,cūn,lìn,tóng,péng,nì,chuài,liáo,cuì,kuì,xiāo,tēng,fán pán,zhí,jiāo,shàn,hū wǔ,cuì,rùn,xiāng,suǐ,fèn,yīng,shān dàn,zhuā,dǎn,kuài,nóng,tún,lián,bì bei,yōng,jué,chù,yì,juǎn,là gé,liǎn,sāo sào,tún,gǔ,qí,cuì,bìn,xūn,nào,wò yuè,zàng,xiàn,biāo,xìng,kuān,là,yān,lú,huò,zā,luǒ,qú,zàng,luán,ní luán,zā,chén,qiān xián,wò,guàng jiǒng,zāng zàng cáng,lín,guǎng jiǒng,zì,jiǎo,niè,chòu xiù,jì,gāo,chòu,mián biān,niè,zhì,zhì,gé,jiàn,dié zhí,zhī jìn,xiū,tái,zhēn,jiù,xiàn,yú,chā,yǎo,yú,chōng,xì,xì,jiù,yú,yǔ,xīng,jǔ,jiù,xìn,shé,shè,shè,jiǔ,shì,tān,shū,shì,tiǎn,tàn,pù,pù,guǎn,huà,tiàn,chuǎn,shùn,xiá,wǔ,zhōu,dāo,chuán,shān,yǐ,fán,pā,tài,fán,bǎn,chuán,háng,fǎng,bān,bǐ,lú,zhōng,jiàn,cāng,líng,zhú,zé,duò,bó,xián,gě,chuán,xiá,lú,qióng,páng,xī,kuā,fú,zào,féng,lí,shāo,yú,láng,tǐng,yù,wěi,bó,měng,niàn,jū,huáng,shǒu,kè,biàn,mù,dié,dào,bàng,chā,yì,sōu,cāng,cáo,lóu,dài,xuě,yào,chōng,dēng,dāng,qiáng,lǔ,yǐ,jí,jiàn,huò,méng,qí,lǔ,lú,chán,shuāng,gèn,liáng,jiān,jiān,sè,yàn,fú,pīng,yàn,yàn,cǎo,ǎo,yì,lè,dǐng,jiāo qiú,ài,nǎi,tiáo,qiú,jié jiē,péng,wán,yì,chā,mián,mǐ,gǎn,qiān,yù,yù,sháo,xiōng,dù,hù xià,qǐ,máng,zì zǐ,huì hū,suī,zhì,xiāng,bì pí,fú,tún chūn,wěi,wú,zhī,qì,shān,wén,qiàn,rén,fú,kōu,jiè gài,lú,xù zhù,jī,qín,qí,yuán yán,fēn,bā,ruì,xīn xìn,jì,huā,lún huā,fāng,wù hū,jué,gōu gǒu,zhǐ,yún,qín,ǎo,chú,máo mào,yá,fèi fú,rèng,háng,cōng,chán yín,yǒu,biàn,yì,qiē,wěi,lì,pǐ,è,xiàn,cháng,cāng,zhù,sū sù,dì tí,yuàn,rǎn,líng,tái tāi,tiáo sháo,dí,miáo,qǐng,lì jī,yòng,kē hē,mù,bèi,bāo,gǒu,mín,yǐ,yǐ,jù qǔ,piě,ruò rě,kǔ,zhù níng,nǐ,pā bó,bǐng,shān shàn,xiú,yǎo,xiān,běn,hóng,yīng,zuó zhǎ,dōng,jū chá,dié,nié,gān,hū,píng pēng,méi,fú,shēng ruí,gū,bì,wèi,fú,zhuó,mào,fàn,qié,máo,máo,bá,zǐ,mò,zī,zhǐ,chí,jì,jīng,lóng,cōng,niǎo,yuán,xué,yíng,qióng,gè,míng,lì,róng,yìn,gèn,qiàn,chǎi,chén,yù,hāo,zì,liè,wú,jì,guī,cì,jiǎn,cí,hòu,guāng,máng,chá,jiāo,jiāo,fú,yú,zhū,zī,jiāng,huí,yīn,chá,fá,róng,rú,chōng,mǎng,tóng,zhòng,qiān,zhú,xún,huán,fū,quán,gāi,dá,jīng,xìng,chuǎn,cǎo,jīng,ér,àn,qiáo,chí,rěn,jiàn,yí tí,huāng,píng,lì,jīn,lǎo,shù,zhuāng,dá,jiá,ráo,bì,cè,qiáo,huì,jì,dàng,zì,róng,hūn,xíng yīng,luò,yíng,qián xún,jìn,sūn,yīn yìn,mǎi,hóng,zhòu,yào,dù,wěi,lí,dòu,fū,rěn,yín,hé,bí,bù,yǔn,dí,tú,suī,suī,chéng,chén,wú,bié,xī,gěng,lì,pú,zhù,mò,lì,zhuāng,zuó,tuō,qiú,suō shā,suō,chén,péng fēng,jǔ,méi,méng,xìng,jìng,chē,shēn xīn,jūn,yán,tíng,yóu,cuò,guān guǎn wǎn,hàn,yǒu,cuò,jiá,wáng,sù yóu,niǔ,shāo xiāo,xiàn,làng liáng,fú piǎo,é,mò mù,wèn wǎn miǎn,jié,nán,mù,kǎn,lái,lián,shì shí,wō,tù tú,xiān liǎn,huò,yóu,yíng,yīng,gòng,chún,mǎng,mǎng,cì,wǎn yùn,jīng,dì,qú,dōng,jiān,zōu chù,gū,lā,lù,jú,wèi,jūn jùn,niè rěn,kūn,hé,pú,zī zì zāi,gǎo,guǒ,fú,lún,chāng,chóu,sōng,chuí,zhàn,mén,cài,bá,lí,tù tú,bō,hàn,bào,qìn,juǎn,xī,qín,dǐ,jiē shà,pú,dàng,jǐn,qiáo zhǎo,tái zhī chí,gēng,huá huà huā,gū,líng,fēi fěi,qín qīn jīn,ān,wǎng,běng,zhǒu,yān,zū,jiān,lǐn má,tǎn,shū,tián tiàn,dào,hǔ,qí,hé,cuì,táo,chūn,bì,cháng,huán,fèi,lái,qī,méng,píng,wěi,dàn,shà,huán,yǎn,yí,tiáo,qí,wǎn,cè,nài,zhěn,tuò,jiū,tiē,luó,bì,yì,pān,bó,pāo,dìng,yíng,yíng,yíng,xiāo,sà,qiū,kē,xiāng,wàn,yǔ,yú,fù,liàn,xuān,xuān,nǎn,cè,wō,chǔn,shāo,yú,biān,mào,ān,è,là luò lào,yíng,kuò,kuò,jiāng,miǎn,zuò,zuò,zū,bǎo,róu,xǐ,yè,ān,qú,jiān,fú,lǜ,jīng,pén,fēng,hóng,hóng,hóu,xìng,tū,zhù zhuó zhe,zī,xiāng,shèn,gé gě,qiā,qíng,mǐ,huáng,shēn,pú,gài,dǒng,zhòu,qián,wěi,bó,wēi,pā,jì,hú,zàng,jiā,duàn,yào,jùn,cōng,quán,wēi,zhēn,kuí,tíng,hūn,xǐ,shī,qì,lán,zōng,yāo,yuān,méi,yūn,shù,dì,zhuàn,guān,rǎn,xuē,chǎn,kǎi,kuì kuài,huā,jiǎng,lóu,wěi,pài,yòng,sōu,yīn,shī,chún,shì shí,yūn,zhēn,làng,rú ná,mēng méng měng,lì,quē,suàn,yuán huán,lì,jǔ,xī,bàng,chú,xú shú,tú,liú,huò,diǎn,qiàn,zū jù,pò,cuó,yuān,chú,yù,kuǎi,pán,pú,pú,nà,shuò,xí xì,fén,yún,zhēng,jiān,jí,ruò,cāng,ēn,mí,hāo,sūn,zhēn,míng,sōu sǒu,xù,liú,xí,gū,láng,róng,wěng,gài gě hé,cuò,shī,táng,luǒ,rù,suō,xuān,bèi,yǎo zhuó,guì,bì,zǒng,gǔn,zuò,tiáo,cè,pèi,lán,dàn,jì,lí,shēn,lǎng,yù,líng,yíng,mò,diào tiáo dí,tiáo,mǎo,tōng,zhú,péng,ān,lián,cōng,xǐ,píng,qiū xū fū,jǐn,chún,jié,wéi,tuī,cáo,yù,yì,zí jú,liǎo lù,bì,lǔ,xù,bù,zhāng,léi,qiáng,màn,yán,líng,jì,biāo,gǔn,hàn,dí,sù,lù,shè,shāng,dí,miè,hūn,màn wàn,bo,dì,cuó,zhè,shēn,xuàn,wèi,hú,áo,mǐ,lóu,cù,zhōng,cài,pó,jiǎng,mì,cōng,niǎo,huì,juàn,yín,jiān,niān,shū,yīn,guó,chén,hù,shā,kòu,qiàn,má,zàng,zé,qiáng,dōu,liǎn,lìn,kòu,ǎi,bì,lí,wěi,jí,qián xún,shèng,fán,méng,ǒu,chǎn,diǎn,xùn,jiāo,ruǐ,ruǐ,lěi,yú,qiáo,zhū,huá,jiān,mǎi,yún,bāo,yóu,qú,lù,ráo,huì,è,tí,fěi,jué,zuì,fà,rú,fén,kuì,shùn,ruí,yǎ,xū,fù,jué,dàng,wú,dǒng,sī,xiāo,xì,sà,yùn,shāo,qí,jiān,yùn,sūn,líng,yù,xiá,wèng,jí,hòng,sì,nóng,lěi,xuān,yùn,yù,xí xiào,hào,báo bó bò,hāo,ài,wēi,huì,huì,jì,cí zī,xiāng,wàn luàn,miè,yì,léng,jiāng,càn,shēn,qiáng sè,lián,kē,yuán,dá,tì,tāng,xuē,bì,zhān,sūn,xiān liǎn,fán,dǐng,xiè,gǔ,xiè,shǔ,jiàn,hāo kǎo,hōng,sà,xīn,xūn,yào,bài,sǒu,shǔ,xūn,duì,pín,yuǎn wěi,níng,chóu zhòu,mái wō,rú,piáo,tái,jì qí,zǎo,chén,zhēn,ěr,nǐ,yíng,gǎo,cóng,xiāo hào,qí,fá,jiǎn,xù yù xū,kuí,jiè jí,biǎn,diào zhuó,mí,lán,jìn,cáng zàng,miǎo,qióng,qì,xiǎn,liáo,ǒu,xián,sù,lǘ,yì,xù,xiě,lí,yì,lǎ,lěi,jiào,dí,zhǐ,bēi,téng,yào,mò,huàn,biāo pāo,fān,sǒu,tán,tuī,qióng,qiáo,wèi,liú liǔ,huì huí,ōu,gǎo,yùn,bǎo,lì,shǔ,zhū chú,ǎi,lìn,zǎo,xuān,qìn,lài,huò,tuò,wù,ruǐ,ruǐ,qí,héng,lú,sū,tuí,máng,yùn,pín píng,yù,xūn,jì,jiōng,xuān,mó,qiū,sū,jiōng,péng,niè,bò,ráng,yì,xiǎn,yú,jú,liǎn,liǎn,yǐn,qiáng,yīng,lóng,tǒu,huā,yuè,lìng,qú,yáo,fán,mí,lán,guī,lán,jì,dàng,màn,lèi,léi,huī,fēng,zhī,wèi,kuí,zhàn,huái,lí,jì,mí,lěi,huài,luó,jī,kuí,lù,jiān,sà,téng,léi,quǎn,xiāo,yì,luán,mén,biē,hū,hǔ,lǔ,nüè,lǜ,sī,xiāo,qián,chǔ,hū,xū,cuó,fú,xū,xū,lǔ,hǔ,yú,hào,jiāo,jù,guó,bào,yán,zhàn,zhàn,kuī,bīn,xì,shù,chóng,qiú,diāo,jǐ,qiú,dīng,shī,xiā,jué,zhé,shé,yú,hán,zǐ,hóng,huǐ,méng,gè,suī,xiā,chài,shí,yǐ,mǎ mā mà,xiǎng,fāng bàng,è,bā,chǐ,qiān,wén,wén,ruì,bàng bèng,pí,yuè,yuè,jūn,qí,tóng,yǐn,qí zhǐ,cán,yuán wán,jué quē,huí,qín qián,qí,zhòng,yá,háo,mù,wáng,fén,fén,háng,gōng zhōng,zǎo,fù fǔ,rán,jiè,fú,chī,dǒu,bào,xiǎn,ní,dài dé,qiū,yóu,zhà,píng,chí,yòu,kē,hān,jù,lì,fù,rán,zhá,gǒu qú xù,pí,pí bǒ,xián,zhù,diāo,bié,bīng,gū,zhān,qū,shé yí,tiě,líng,gǔ,dàn,tún,yíng,lì,chēng,qū,móu,gé luò,cì,huí,huí,máng bàng,fù,yáng,wā,liè,zhū,yī,xián,kuò,jiāo,lì,yì xǔ,píng,jié,gé há,shé,yí,wǎng,mò,qióng,qiè ní,guǐ,qióng,zhì,mán,lǎo,zhé,jiá,náo,sī,qí,xíng,jiè,qiú,xiāo,yǒng,jiá,tuì,chē,bèi,é yǐ,hàn,shǔ,xuán,fēng,shèn,shèn,fǔ,xiǎn,zhé,wú,fú,lì,láng,bì,chú,yuān,yǒu,jié,dàn,yán,tíng,diàn,tuì,huí,wō,zhī,zhōng,fēi,jū,mì,qí,qí,yù,jùn,là,měng,qiāng,sī,xī,lún,lì,dié,tiáo,táo,kūn,hán,hàn,yù,bàng,féi,pí,wēi,dūn,yì,yuān,suò,quán,qiǎn,ruì,ní,qīng,wèi,liǎng,guǒ,wān,dōng,è,bǎn,dì,wǎng,cán,yǎng,yíng,guō,chán,dìng,là,kē,jí,xiē,tíng,mào,xū,mián,yú,jiē,shí,xuān,huáng,yǎn,biān,róu,wēi,fù,yuán,mèi,wèi,fú,rú,xié,yóu,qiú,máo,xiā,yīng,shī,chóng,tāng,zhū,zōng,dì,fù,yuán,kuí,méng,là,dài,hú,qiū,dié,lì,wō,yūn,qǔ,nǎn,lóu,chūn,róng,yíng,jiāng,bān,láng,páng,sī,xī,cì,xī qī,yuán,wēng,lián,sǒu,bān,róng,róng,jí,wū,xiù,hàn,qín,yí,bī pí,huá,táng,yǐ,dù,nài něng,hé xiá,hú,guì huǐ,mǎ mā mà,míng,yì,wén,yíng,téng,zhōng,cāng,sāo,qí,mǎn,dāo,shāng,shì zhē,cáo,chī,dì,áo,lù,wèi,dié zhì,táng,chén,piāo,qú jù,pí,yú,chán jiàn,luó,lóu,qǐn,zhōng,yǐn,jiāng,shuài,wén,xiāo,wàn,zhé,zhè,má mò,má,guō,liú,máo,xī,cōng,lí,mǎn,xiāo,chán,zhāng,mǎng měng,xiàng,mò,zuī,sī,qiū,tè,zhí,péng,péng,jiǎo,qú,biē bié,liáo,pán,guǐ,xǐ,jǐ,zhuān,huáng,fèi bēn,láo liáo,jué,jué,huì,yín xún,chán,jiāo,shàn,náo,xiāo,wú,chóng,xún,sī,chú,chēng,dāng,lí,xiè,shàn,yǐ,jǐng,dá,chán,qì,cī,xiǎng,shè,luǒ,qín,yíng,chài,lì,zéi,xuān,lián,zhú,zé,xiē,mǎng,xiè,qí,róng,jiǎn,měng,háo,rú,huò,zhuó,jié,pín,hē,miè,fán,lěi,jié,là,mǐn,lǐ,chǔn,lì,qiū,niè,lú,dù,xiāo,zhū,lóng,lí,lóng,fēng,yē,pí,náng,gǔ,juān,yīng,shǔ,xī,cán,qú,quán,dù,cán,mán,qú,jié,zhú,zhuó,xiě xuè,huāng,nǜ,pēi,nǜ,xìn,zhòng,mài,ěr,kè,miè,xì,háng xíng,yǎn,kàn,yuàn,qú,líng,xuàn,shù,xián,tòng,xiàng,jiē,xián,yá,hú,wèi,dào,chōng,wèi,dào,zhūn,héng,qú,yī,yī,bǔ,gǎn,yú,biǎo,chà,yì,shān,chèn,fū,gǔn,fēn,shuāi cuī,jié,nà,zhōng,dǎn,rì,zhòng,zhōng,jiè,zhǐ,xié,rán,zhī,rèn,qīn,jīn,jūn,yuán,mèi,chài,ǎo,niǎo,huī,rán,jiā,tuó tuō,lǐng líng,dài,bào páo pào,páo,yào,zuò,bì,shào,tǎn,jù jiē,hè kè,xué,xiù,zhěn,yí yì,pà,fú,dī,wà,fù,gǔn,zhì,zhì,rán,pàn,yì,mào,tuō,nà jué,gōu,xuàn,zhé,qū,bèi pī,yù,xí,mí,bó,bō,fú,chǐ nuǒ,chǐ qǐ duǒ nuǒ,kù,rèn,péng,jiá jié qiā,jiàn zùn,bó mò,jié,ér,gē,rú,zhū,guī guà,yīn,cái,liè liě,kǎ,háng,zhuāng,dāng,xū,kūn,kèn,niǎo,shù,jiá,kǔn,chéng chěng,lǐ,juān,shēn,póu,gé jiē,yì,yù,zhěn,liú,qiú,qún,jì,yì,bǔ,zhuāng,shuì,shā,qún,lǐ,lián,liǎn,kù,jiǎn,bāo,chān,bì pí,kūn,táo,yuàn,líng,chǐ,chāng,chóu dāo,duō,biǎo,liǎng,cháng shang,péi,péi,fēi,yuān gǔn,luǒ,guǒ,yǎn ān,dú,xī tì,zhì,jū,yǐ,qí,guǒ,guà,kèn,qī,tì,tí,fù,chóng,xiè,biǎn,dié,kūn,duān,xiù,xiù,hè,yuàn,bāo,bǎo,fù fú,yú,tuàn,yǎn,huī,bèi,zhǔ,lǚ,páo,dān,yùn,tā,gōu,dā,huái,róng,yuán,rù,nài,jiǒng,suǒ,bān,tuì tùn,chǐ,sǎng,niǎo,yīng,jiè,qiān,huái,kù,lián,lán,lí,zhě,shī,lǚ,yì,diē,xiè,xiān,wèi,biǎo,cáo,jì,qiǎng,sēn,bāo,xiāng,bì,fú,jiǎn,zhuàn,jiǎn,cuì,jí,dān,zá,fán,bó,xiàng,xín,bié,ráo,mǎn,lán,ǎo,zé,guì,cào,suì,nóng,chān,liǎn,bì,jīn,dāng,shǔ,tǎn,bì,lán,fú,rú,zhǐ,dùi,shǔ,wà,shì,bǎi,xié,bó,chèn,lǎi,lóng,xí,xiān,lán,zhě,dài,jǔ,zàn,shī,jiǎn,pàn,yì,lán,yà,xī,yà,yào yāo,fěng,tán qín,fù,fiào,fù,bà pò,hé,jī,jī,jiàn xiàn,guān guàn,biàn,yàn,guī,jué jiào,piǎn,mào,mì,mì,piē miè,shì,sì,chān,zhěn,jué jiào,mì,tiào,lián,yào,zhì,jūn,xī,shǎn,wēi,xì,tiǎn,yú,lǎn,è,dǔ,qīn qìng,pǎng,jì,míng,yíng yǐng,gòu,qū qù,zhàn zhān,jìn,guān guàn,dèng,jiàn biǎn,luó luǎn,qù qū,jiàn,wéi,jué jiào,qù qū,luó,lǎn,shěn,dí,guān guàn,jiàn xiàn,guān guàn,yàn,guī,mì,shì,chān,lǎn,jué jiào,jì,xí,dí,tiǎn,yú,gòu,jìn,qù qū,jiǎo jué,qiú,jīn,cū,jué,zhì,chào,jí,gū,dàn,zī zuǐ,dǐ,shāng,huà xiè,quán,gé,shì,jiě jiè xiè,guǐ,gōng,chù,jiě jiè xiè,hùn,qiú,xīng,sù,ní,jī qí,jué,zhì,zhā,bì,xīng,hú,shāng,gōng,zhì,xué hù,chù,xī,yí,lì lù,jué,xī,yàn,xī,yán,yán,dìng,fù,qiú,qiú,jiào,hōng,jì,fàn,xùn,diào,hòng,chài,tǎo,xū,jié,dàn,rèn,xùn,yín,shàn,qì,tuō,jì,xùn,yín,é,fēn,yà,yāo,sòng,shěn,yín,xīn,jué,xiáo,nè,chén,yóu,zhǐ,xiōng,fǎng,xìn,chāo,shè,yán,sǎ,zhùn,xū,yì,yì,sù,chī,hē,shēn,hé,xù,zhěn,zhù,zhèng,gòu,zī,zǐ,zhān,gǔ,fù,jiǎn,dié,líng,dǐ,yàng,lì,náo,pàn,zhòu,gàn,yì,jù,yào,zhà,tuó,yí,qǔ,zhào,píng,bì,xiòng,qū,bá,dá,zǔ,tāo,zhǔ,cí,zhé,yǒng,xǔ,xún,yì,huǎng,hé,shì,chá,xiào,shī,hěn,chà,gòu,guǐ,quán,huì,jié,huà,gāi,xiáng,wēi,shēn,chóu,tóng,mí,zhān,míng,luò,huī,yán,xiōng,guà,èr,bìng,tiǎo diào,yí chǐ chì,lěi,zhū,kuāng,kuā kuà,wū,yù,téng,jì,zhì,rèn,cù,lǎng làng,é,kuáng,ēi éi ěi èi xī,shì,tǐng,dàn,bèi bó,chán,yòu,kēng,qiào,qīn,shuà,ān,yǔ yù,xiào,chéng,jiè,xiàn,wū,wù,gào,sòng,bū,huì,jìng,shuō shuì yuè,zhèn,shuō shuì yuè,dú,huā,chàng,shuí shéi,jié,kè,qū juè,cóng,xiáo,suì,wǎng,xián,fěi,chī lài,tà,yì,nì ná,yín,diào tiáo,pǐ bēi,zhuó,chǎn,chēn,zhūn,jì jī,qī,tán,zhuì,wěi,jū,qǐng,dǒng,zhèng,zé zuò zhǎ cuò,zōu,qiān,zhuó,liàng,jiàn,chù jí,xià háo,lùn lún,shěn,biǎo,huà,biàn,yú,dié,xū,piǎn,shì dì,xuān,shì,hùn,huà guā,è,zhòng,dì,xié,fú,pǔ,tíng,jiàn,qǐ,yù,zī,zhuān,xǐ shāi āi,huì,yīn,ān,xián,nán nàn,chén,fěng,zhū,yáng,yàn,huáng,xuān,gé,nuò,xǔ,móu,yè,wèi,xīng,téng,zhōu,shàn,jiǎn,bó,kuì,huǎng,huò,gē,yíng,mí,xiǎo,mì,xǐ,qiāng,chēn,xuè,tí,sù,bàng,chí,qiān,shì,jiǎng,yuán,xiè,hè,tāo,yáo,yáo,lū,yú,biāo,còng,qǐng,lí,mó,mó,shāng,zhé,miù,jiǎn,zé,jiē,lián,lóu,càn,ōu,gùn,xí,zhuó,áo,áo,jǐn,zhé,yí,hū,jiàng,mán,cháo,hàn,huá,chǎn,xū,zēng,sè,xī,zhā,duì,zhèng,náo,lán,é,yīng,jué,jī,zǔn,jiǎo,bò,huì,zhuàn,wú,zèn,zhá,shí,qiáo,tán,jiàn,pǔ,shéng,xuān,zào,tán,dǎng,suì,xiǎn,jī,jiào,jǐng,zhàn,nóng,yī,ǎi,zhān,pì,huǐ,huà,yì,yì,shàn,ràng,ròu,qiǎn,duì,tà,hù,zhōu,háo,ài,yīng,jiān,yù,jiǎn,huì,dú,zhé,juàn xuān,zàn,lěi,shěn,wèi,chǎn,lì,yí tuī,biàn,zhé,yàn,è,chóu,wèi,chóu,yào,chán,ràng,yǐn,lán,chèn,xié,niè,huān,zàn,yì,dǎng,zhán,yàn,dú,yán,jì,dìng,fù,rèn,jī,jié,hòng,tǎo,ràng,shàn,qì,tuō,xùn,yì,xùn,jì,rèn,jiǎng,huì,ōu,jù,yà,nè,xǔ hǔ,é,lùn lún,xiōng,sòng,fěng,shè,fǎng,jué,zhèng,gǔ,hē,píng,zǔ,shí zhì,xiòng,zhà,sù,zhěn,dǐ,zhōu,cí,qū,zhào,bì,yì,yí dài,kuāng,lěi,shì,guà,shī,jié jí,huī,chéng,zhū,shēn,huà,dàn,gòu,quán,guǐ,xún,yì,zhèng,gāi,xiáng yáng,chà,hùn,xǔ,zhōu chóu,jiè,wū,yǔ yù,qiào,wù,gào,yòu,huì,kuáng,shuō shuì yuè,sòng,ēi éi ěi èi xī,qǐng,zhū,zōu,nuò,dú dòu,zhuó,fěi,kè,wěi,yú,shuí,shěn,tiáo diào zhōu,chǎn,liàng,zhūn,suì,tán,shěn,yì,móu,chén,dié,huǎng,jiàn,xié,xuè,yè,wèi,è,yù,xuān,chán,zī,ān,yàn,dì,mí,piǎn,xū,mó,dǎng,sù,xiè,yáo,bàng,shì,qiān,mì,jǐn,mán,zhé,jiǎn,miù,tán,zèn,qiáo,lán,pǔ,jué,yàn,qiǎn,zhān,chèn,gǔ,qiān,hóng,xiā,jí,hóng,hān,hōng,xī,xī,huō huò huá,liáo,hǎn,dú,lóng,dòu,jiāng,qǐ,chǐ,lǐ,dēng,wān,bī,shù,xiàn,fēng,zhì,zhì,yàn,yàn,shǐ,chù,huī,tún,yì,tún,yì,jiān,bā,hòu,è,chú,xiàng,huàn,jiān yàn,kěn,gāi,jù,fú,xī,bīn,háo,yù,zhū,jiā,fén,xī,hù,wēn,huán,bīn,dí,zōng,fén,yì,zhì,bào,chái,àn,pí,nà,pī,gǒu,nà,yòu,diāo,mò,sì,xiū,huán huān,kěn kūn,hé mò,hé háo mò,mò,àn,mào,lí,ní,bǐ,yǔ,jiā,tuān tuàn,māo máo,pí,xī,yì,jù lóu,mò,chū,tán,huān,jué,bèi,zhēn,yuán yún yùn,fù,cái,gòng,tè,yì yí,háng,wán,pín,huò,fàn,tān,guàn,zé zhài,zhì,èr,zhù,shì,bì,zī,èr,guì,piǎn,biǎn,mǎi,dài tè,shèng,kuàng,fèi,tiē,yí,chí,mào,hè,bì bēn,lù,lìn,huì,gāi,pián,zī,jiǎ gǔ jià,xù,zéi,jiǎo,gāi,zāng,jiàn,yīng,jùn,zhèn,shē,bīn,bīn,qiú,shē,chuàn,zāng,zhōu,lài,zàn,cì,chēn,shǎng,tiǎn,péi,gēng,xián,mài,jiàn,suì,fù,dǎn,cóng,cóng,zhì,jī,zhàng,dǔ,jìn,xiōng mín,chǔn,yǔn,bǎo,zāi,lài,fèng,càng,jī,shèng,ài,zhuàn zuàn,fù,gòu,sài,zé,liáo,yì,bài,chěn,wàn zhuàn,zhì,zhuì,biāo,yūn,zèng,dàn,zàn,yàn,pú,shàn,wàn,yíng,jìn,gàn,xián,zāng,bì,dú,shú,yàn,shǎng,xuàn,lòng,gàn,zāng,bèi,zhēn,fù,yuán yùn,gòng,cái,zé,xián,bài,zhàng,huò,zhì,fàn,tān,pín,biǎn,gòu,zhù,guàn,èr,jiàn,bì bēn,shì,tiē,guì,kuàng,dài,mào,fèi,hè,yí,zéi,zhì,gǔ jiǎ,huì,zī,lìn,lù,zāng,zī,gāi,jìn,qiú,zhèn,lài,shē,fù,dǔ,jī,shú,shǎng,cì,bì,zhōu,gēng,péi,dǎn,lài,fèng,zhuì,fù,zhuàn,sài,zé,yàn,zàn,yūn,zèng,shàn,yíng,gàn,chì,xī,shè,nǎn,tóng,xì,chēng,hè,chēng,zhě,xiá,táng,zǒu,zǒu,lì,jiū,fù,zhào,gǎn,qǐ,shàn,qióng,yǐn,xiǎn,zī,jué,qǐn,chí,cī,chèn,chèn,dié tú,qiè jū,chāo,dī,xì,zhān,jué,yuè,qū cù,jí jié,qū,chú,guā huó,xuè,zī,tiào,duǒ,liè,gǎn,suō,cù,xí,zhào,sù,yǐn,jú,jiàn,què qì jí,tàng tāng,chuō zhuó,cuǐ,lù,qù cù,dàng,qiū,zī,tí,qū cù,chì,huáng,qiáo,qiāo,jiào,zào,tì yuè,ěr,zǎn,zǎn,zú,pā,bào bō,kuà wù,kē,dǔn,jué guì,fū,chěn,jiǎn,fāng fàng páng,zhǐ,tā,yuè,bà páo,qí qǐ,yuè,qiāng qiàng,tuò,tái,yì,jiàn chén,líng,mèi,bá,diē,kū,tuó,jiā,cī cǐ,pǎo páo,qiǎ,zhù,jū,diǎn tiē dié,zhí,fū,pán bàn,jū jù qiè,shān,bǒ,ní,jù,lì luò,gēn,yí,jì,dài duò duō chí,xiǎn,jiāo,duò,zhū,quán,kuà,zhuǎi,guì,qióng,kuǐ,xiáng,dié,lù,pián bèng,zhì,jié,tiào táo,cǎi,jiàn,dá,qiāo,bì,xiān,duò,jī,jú,jì,shū chōu,tú,chuò,jìng,niè,xiāo,bù,xué,qūn,mǔ,shū,liáng liàng,yǒng,jiǎo,chóu,qiāo,móu,tà,jiàn,jī,wō,wěi,chuō,jié,jí,niè,jū,niè,lún,lù,lèng,huái,jù,chí,wǎn,quán,tī,bó,zú,qiè,qī,cù,zōng,cǎi,zōng,pèng,zhì,zhēng,diǎn,zhí,yú,duó,dùn,chuǎn,yǒng,zhǒng,dì,zhě,chěn,chuài,jiàn,guā,táng,jǔ,fú,cù,dié,pián,róu,nuò,tí,chǎ,tuǐ,jiǎn,dǎo,cuō,xī,tà,qiāng,niǎn,diān,tí,jí,niè,pán,liū,zàn,bì,chōng,lù,liáo,cù,tāng,dài,sù,xǐ,kuǐ,jì,zhí,qiāng,dí,pán,zōng,lián,bèng,zāo,niǎn,bié,tuí,jú,dēng,cèng,xiān,fán,chú,zhōng,dūn,bō,cù,cù,jué juě,jué,lìn,tà,qiāo,qiāo,pǔ,liāo,dūn,cuān,guàn,zào,tà,bì,bì,zhú,jù,chú,qiào,dǔn,chóu,jī,wǔ,yuè,niǎn,lìn,liè,zhí,lì luò,zhì,chán,chú,duàn,wèi,lóng lǒng,lìn,xiān,wèi,zuān,lán,xiè,ráng,sǎ xiè,niè,tà,qú,jí,cuān,zuān,xǐ,kuí,jué,lìn,shēn,gōng,dān,fēn,qū,tǐ,duǒ,duǒ,gōng,láng,rěn,luǒ,ǎi,jī,jū,tǎng,kōng,lào,yǎn,měi,kāng,qū,lóu,lào,duǒ,zhí,yàn,tǐ,dào,yīng,yù,chē jū,yà zhá gá,guǐ,jūn,wèi,yuè,xìn xiàn,dài,xuān,fàn guǐ,rèn,shān,kuáng,shū,tún,chén,dài,è,nà,qí,máo,ruǎn,kuáng,qián,zhuàn zhuǎn,hōng,hū,qú,kuàng,dǐ,líng,dài,āo ào,zhěn,fàn,kuāng,yǎng,pēng,bèi,gū,gū,páo,zhù,rǒng,è,bá,zhóu zhòu,zhǐ,yáo,kē kě,yì dié,qīng,shì,píng,ér,gǒng,jú,jiào,guāng,lù,kǎi,quán,zhōu,zài,zhì,shē,liàng,yù,shāo,yóu,wàn,yǐn,zhé,wǎn,fǔ,qīng,zhōu,ní,líng,zhé,hàn,liàng,zī,huī,wǎng,chuò,guǒ,kǎn,yǐ,péng,qiàn,gǔn,niǎn,píng,guǎn,bèi,lún,pái,liáng,ruǎn,róu,jí,yáng,xián,chuán,còu,chūn,gé,yóu,hōng,shū,fù,zī,fú,wēn,fàn,zhǎn,yú,wēn,tāo,gǔ,zhēn,xiá,yuán,lù,jiāo,cháo,zhuǎn,wèi,hūn,xuě,zhé,jiào,zhàn,bú,lǎo,fén,fān,lín,gé,sè,kǎn,huàn,yǐ,jí,duì,ér,yú,jiàn,hōng,léi,pèi,lì,lì,lú,lìn,chē jū,yà,guǐ,xuān,dài,rèn,zhuǎn zhuàn zhuǎi,è,lún,ruǎn,hōng,gū,kē,lú,zhóu zhòu,zhǐ,yì,hū,zhěn,lì,yáo,qīng,shì,zǎi zài,zhì,jiào,zhōu,quán,lù,jiào,zhé,fǔ,liàng,niǎn,bèi,huī,gǔn,wǎng,liáng,chuò,zī,còu,fú,jí,wēn,shū,pèi,yuán,xiá,zhǎn niǎn,lù,zhé,lín,xīn,gū,cí,cí,bì pì,zuì,biàn,là,là,cí,xuē,bàn,biàn,biàn,biàn,xuē,biàn,bān,cí,biàn,biàn,chén,rǔ,nóng,nóng,zhěn,chuò,chuò,yī,réng,biān,dào biān,shi,yū,liáo,dá,chān,gān,qiān,yū,yū,qì,xùn,yǐ yí,guò guo guō,mài,qī,zā,wàng kuāng,tù,zhūn,yíng,dá,yùn,jìn,háng,yà,fǎn,wǔ,dá,é,huán hái,zhè zhèi,dá,jìn,yuǎn yuàn,wéi,lián,chí,chè,chí,tiáo,zhì lì,yǐ yí,jiǒng,jiā,chén,dài,ěr,dí,pò pǎi,zhù wǎng,dié,zé,táo,shù,yǐ yí,qù,jìng,huí,dòng,yòu,mí,bèng,jì,nǎi,yí,jié,zhuī duī,liè,xùn,tuì,sòng,shì,táo,páng,hòu,nì,dùn,jiǒng,xuǎn,xùn,bū,yōu,xiāo,qiú,tòu,zhú,qiú,dì,dì,tú,jìng,tì,dòu,yǐ,zhè,tōng,guàng,wǔ,shì,chěng,sù,zào,qūn,féng,lián,suò,huí,lǐ,gǔ,lái,bèn,cuò,zhú,bèng,huàn,dài,lù,yóu,zhōu,jìn,yù,chuō,kuí,wēi,tì,yì,dá,yuǎn,luó,bī,nuò,yú,dàng,suí,dùn,suì,yǎn,chuán,chí,dì tí,yù,shí,zhēn,yóu,yùn,è,biàn,guò,è,xiá,huáng,qiú,dào,dá,wéi,nán,yí,gòu,yáo,chòu,liù,xùn,tà,dì,chí,yuǎn,sù,tà,qiǎn,mǎ,yáo,guàn,zhāng,áo,shì,cà,chì,sù,zāo,zhē,dùn,dì,lóu,chí,cuō,lín,zūn,rào,qiān,xuǎn,yù,yí,è,liáo,jù,shì,bì,yāo,mài,xiè,suì,huán hái,zhān,téng,ěr,miǎo,biān,biān,lā,lí chí,yuán,yáo,luó,lǐ,yì,tíng,dèng,qǐ,yōng,shān,hán,yú,máng,rú,qióng,xī,kuàng,fū,kàng háng,bīn,fāng,xíng,nà nǎ nèi nā,xīn,shěn,bāng,yuán,cūn,huǒ,xié yá yé yú xú,bāng,wū,jù,yóu,hán,tái,qiū,bì,pī,bǐng,shào,bèi,wǎ,dǐ,zōu,yè,lín,kuāng,guī,zhū,shī,kū,yù,gāi hái,hé,qiè xì,zhì,jí,xún huán,hòu,xíng,jiāo,xí,guī,nà,láng làng,jiá,kuài,zhèng,láng,yùn,yán,chéng,dòu,xī,lǚ,fǔ,wú,fú,gào,hǎo,láng,jiá,gěng,jùn,yǐng,bó,xì,bèi,lì zhí,yún,bù,xiáo ǎo,qī,pí,qīng,guō,zhōu,tán,zōu,píng,lái,ní,chēn,yóu,bù,xiāng,dān,jú,yōng,qiāo,yī,dū dōu,yǎn,méi,ruò,bèi,è,shū,juàn,yǔ,yùn,hóu,kuí,xiāng,xiāng,sōu,táng,míng,xī,rǔ,chù,zī,zōu,yì,wū,xiāng,yún,hào,yōng,bǐ,mào,cháo,fū,liǎo,yín,zhuān,hù,qiāo,yān,zhāng,màn,qiāo,xǔ,dèng,bì,xún,bì,zēng,wéi,zhèng,mào,shàn,lín,pó,dān,méng,yè,cào,kuài,fēng,méng,zōu,kuàng,liǎn,zàn,chán,yōu,qí,yàn,chán,zàn,líng,huān,xī,fēng,zàn,lì,yǒu,dīng dǐng,qiú,zhuó,pèi,zhòu,yǐ,gān,yú,jiǔ,yǎn,zuì,máo,dān,xù,dòu,zhēn,fēn,yuán,fū,yùn,tài,tiān,qiǎ,tuó,zuò,hān,gū,sū,pō,chóu,zài,mǐng,lào,chuò,chóu,yòu,tóng,zhǐ,xiān,jiàng,chéng,yìn,tú,jiào,méi,kù,suān,lèi,pú,zuì,hǎi,yàn,shī,niàng niàn niáng,wéi,lù,lǎn,yān,táo,pēi,zhǎn,chún,tán dàn,zuì,zhuì,cù,kūn,tí tǐ,xián,dū,hú,xǔ,xǐng,tǎn,qiú chōu,chún,yùn,pō fā,kē,sōu,mí,quán,chǒu,cuō,yùn,yòng,àng,zhà,hǎi,táng,jiàng,piǎo,chǎn chěn,yù,lí,zāo,láo,yī,jiàng,bú,jiào,xī,tán,pō fā,nóng,yì shì,lǐ,jù,yàn liǎn xiān,yì,niàng,rú,xūn,chóu,yàn,líng,mí,mí,niàng,xìn,jiào,shī,mí,yàn,biàn,cǎi cài,shì,yòu,shì,shì,lǐ,zhòng chóng,yě,liáng liàng,lí xǐ xī,jīn,jīn,gá,yǐ,liǎo liào,dāo,zhāo,dīng dìng,pō,qiú,hé,fǔ,zhēn,zhí,bā,luàn,fǔ,nǎi,diào,shān shàn,qiǎo jiǎo,kòu,chuàn,zǐ,fán,huá yú,huá wū,hàn,gāng,qí,máng,rì rèn jiàn,dì dài,sì,xì,yì,chāi,shī yí,tǔ,xī,nǚ,qiān,qiú,rì rèn jiàn,pī zhāo,yé yá,jīn,bǎ,fāng,chén,xíng,dǒu,yuè,qiān,fū,bù,nà,xīn,é,jué,dùn,gōu,yǐn,qián,bǎn,sà,rèn,chāo,niǔ,fēn,yǔn,yǐ,qín,pī,guō,hóng,yín,jūn,diào,yì,zhōng,xǐ,gài,rì,huǒ,tài,kàng,yuán,lú,è,qín,duó,zī,ní,tú,shì,mín,gū,kē,líng,bǐng,sì,gǔ,bó,pí,yù,sì,zuó,bū,yóu,diàn,jiǎ,zhēn,shǐ,shì,tiě,jù,zuān,shī,tā,xuàn,zhāo,bào,hé,bì,shēng,chú,shí,bó,zhù,chì,zā,pǒ,tóng,qián,fú,zhǎi,mǎo,qiān,fú,lì,yuè,pī,yāng,bàn,bō,jié,gōu,shù,zhēng,mǔ,xǐ,xǐ,dì,jiā,mù,tǎn,shén,yǐ,sī,kuàng,kǎ,běi,jiàn,tóng,xíng,hóng,jiǎo,chǐ,ěr,gè,bǐng píng,shì,máo,hā,yín,jūn,zhōu,chòng,xiǎng jiōng,tóng,mò,lèi,jī,yù sì,xù huì,rén rěn,zùn,zhì,qióng,shàn shuò,chì lì,xiǎn xǐ,xíng,quán,pī,tiě,zhū,hóu xiàng,míng,kuǎ,diào tiáo yáo,xiān kuò tiǎn guā,xián,xiū,jūn,chā,lǎo,jí,pǐ,rú,mǐ,yī,yīn,guāng,ǎn,diū,yǒu,sè,kào,qián,luán,sī,āi,diào,hàn,ruì,shì zhì,kēng,qiú,xiāo,zhé niè,xiù,zàng,tī,cuò,xiān kuò tiǎn guā,hòng gǒng,zhōng yōng,tōu tù dòu,lǚ,méi méng,láng,wàn jiǎn,xīn,yún,bèi,wù,sù,yù,chán,tǐng dìng,bó,hàn,jiá,hóng,juān jiān cuān,fēng,chān,wǎn,zhì,sī tuó,xuān juān juàn,huá wú wū,wú,tiáo,kuàng,zhuó chuò,lüè,xíng xìng jīng,qǐn,shèn,hán,lüè,yé,chú,zèng,jū jú,xiàn,é,máng,pū pù,lí,pàn,ruì,chéng,gào,lǐ,tè,bīng,zhù,zhèn,tū,liǔ,zuì niè,jù jū,chǎng,yuǎn yuān wǎn wān,jiān jiàn,gāng gàng,diào,táo,shǎng,lún,kè,líng,pī,lù,lí,qīng,péi,juǎn,mín,zuì,péng,àn,pī,xiàn,yā,zhuī,lèi,ā,kōng,tà,kūn,dú,nèi,chuí,zī,zhēng,bēn,niè,cóng,chún,tán,dìng,qí,qián,zhuì,jī,yù,jǐn,guǎn,máo,chāng,tiǎn,xī,liàn,diāo,gù,cuò,shù,zhēn,lù,měng,lù,huā,biǎo,gá,lái,kěn,fāng,bū,nài,wàn,zàn,hǔ,dé,xiān,piān,huò,liàng,fǎ,mén,kǎi,yāng,chí,liàn,guō,xiǎn,dù,tú,wéi,zōng,fù,róu,jí,è,jūn,chěn,tí,zhá,hù,yáng,duàn,xiá,yú,kēng,shēng,huáng,wěi,fù,zhāo,chā,qiè,shī,hōng,kuí,nuò,móu,qiāo,qiāo,hóu,tōu,cōng,huán,yè,mín,jiàn,duān,jiàn,sī,kuí,hú,xuān,zhě,jié,zhēn,biān,zhōng,zī,xiū,yé,měi,pài,āi,jiè,qián,méi,cuō chā,dā tà,bàng,xiá,lián,suǒ sè,kài,liú,yáo zú,yè tà gé,nòu,wēng,róng,táng,suǒ,qiāng chēng,gé lì,shuò,chuí,bó,pán,dā,bī bì pī,sǎng,gāng,zī,wū,yíng,huàng,tiáo,liú liù,kǎi,sǔn,shā,sōu,wàn jiǎn,gǎo hào,zhèn,zhèn,láng,yì,yuán,tǎng,niè,xí,jiā,gē,mǎ,juān,sòng,zǔ,suǒ,xià,fēng,wēn,ná,lǔ,suǒ,ōu,zú chuò,tuán,xiū xiù,guàn,xuàn,liàn,shòu sōu,ào,mǎn,mò,luó,bì,wèi,liú,dí dī,sǎn qiāo càn,cōng,yí,lù áo,áo,kēng,qiāng,cuī,qī,shǎng,tāng táng,màn,yōng,chǎn,fēng,jìng,biāo,shù,lòu,xiù,cōng,lóng,zàn,jiàn zàn,cáo,lí,xià,xī,kāng,shuǎng,bèng,zhāng,qiān,zhēng,lù,huá,jí,pú,huì suì ruì,qiǎng qiāng,pō,lín,sè,xiù,sǎn xiàn sà,chēng,guì,sī,liú,náo,huáng,piě,suì,fán,qiáo,quān,xī,tàng,xiàng,jué,jiāo,zūn,liào,qì,láo,duī,xín,zān,jī,jiǎn,zhōng,dèng,yā,yǐng,duī,jué,nòu,zān,pǔ,tiě,fán,chēng,dǐng,shàn,kāi,jiǎn,fèi,suì,lǔ,juān,huì,yù,lián,zhuō,qiāo,jiàn,zhuó,léi,bì,tiě,huán,yè,duó,guò,dāng chēng,jù,fén,dá,bèi,yì,ài,zōng,xùn,diào,zhù,héng,zhuì,jī,niè,hé,huò,qīng,bīn,yīng,guì,níng,xū,jiàn,jiàn,qiǎn,chǎ,zhì,miè,lí,léi,jī,zuān,kuàng,shǎng,péng,là,dú,shuò,chuò,lǜ,biāo,bào,lǔ,xián,kuān,lóng,è,lú,xīn,jiàn,lán,bó,jiān,yuè,chán,xiāng,jiàn,xī,guàn,cáng,niè,lěi,cuān,qú,pàn,luó,zuān,luán,záo,niè,jué,tǎng,zhú,làn,jīn,gá,yǐ,zhēn,dīng dìng,zhāo,pō,liǎo liào,tǔ,qiān,chuàn,shān shàn,sà xì,fán,diào,mén,nǚ,yáng,chāi,xíng,gài,bù,tài,jù,dùn,chāo,zhōng,nà,bèi,gāng gàng,bǎn,qián,yuè yào,qīn,jūn,wū,gōu,kàng,fāng,huǒ,dǒu,niǔ,bǎ pá,yù,qián,zhēng zhèng,qián,gǔ,bō,kē,pǒ,bū,bó,yuè,zuān zuàn,mù,tǎn,jiǎ,diàn tián,yóu,tiě,bó,líng,shuò,qiān yán,mǎo,bào,shì,xuàn,tā tuó,bì,ní,pí pī,duó,xíng,kào,lǎo,ěr,máng,yā yà,yǒu,chéng,jiá,yé,náo,zhì,dāng chēng,tóng,lǚ,diào,yīn,kǎi,zhá,zhū,xiǎn xǐ,tǐng dìng,diū,xiān kuò tiǎn guā,huá,quán,shā,hā kē,diào tiáo yáo,gè,míng,zhēng,sè,jiǎo,yī,chǎn,chòng,tàng tāng,ǎn,yín,rú,zhù,láo,pū pù,wú,lái,tè,liàn,kēng,xiāo,suǒ,lǐ,zèng,chú,guō,gào,é,xiù,cuò,lüè,fēng,xīn,liǔ,kāi,jiǎn,ruì,tī,láng,qǐn,jū,ā,qiāng,zhě,nuò,cuò,máo,bēn,qí,dé,kè,kūn,chāng,xī,gù,luó,chuí,zhuī,jǐn,zhì,xiān,juǎn,huò,péi,tán,dìng,jiàn,jù,měng,zī,qiè,yīng,kǎi,qiāng,sī,è,chā,qiāo,zhōng,duàn,sōu,huáng,huán,āi,dù,měi,lòu,zī,fèi,méi,mò,zhèn,bó,gé,niè,tǎng,juān,niè,ná,liú,gǎo,bàng,yì,jiā,bīn,róng,biāo,tāng,màn,luó,bèng,yōng,jìng,dí,zú,xuàn,liú,xín,jué,liào,pú,lǔ,duī,lán,pǔ,cuān,qiǎng,dèng,huò,léi,huán,zhuó,lián,yì,chǎ,biāo,là,chán,xiāng,cháng zhǎng,cháng,jiǔ,ǎo,dié,jié,liǎo,mí,cháng zhǎng,mén,mà,shuān,shǎn,huò shǎn,mén,yán,bì,hàn bì,bì,shān,kāi,kāng kàng,bēng,hóng,rùn,sàn,xián,xián jiān jiàn,jiān jiàn,mǐn,xiā xiǎ,shuǐ,dòu,zhá,nào,zhān,pēng pèng,xiǎ kě,líng,biàn guān,bì,rùn,hé,guān,gé,hé gé,fá,chù,hòng xiàng,guī,mǐn,sē xī,kǔn,làng,lǘ,tíng tǐng,shà,jú,yuè,yuè,chǎn,qù,lìn,chāng,shā,kǔn,yān,wén,yán,è yān,hūn,yù,wén,hòng,bāo,hòng juǎn xiàng,qù,yǎo,wén,bǎn pàn,àn,wéi,yīn,kuò,què,lán,dū shé,quán,fēng,tián,niè,tà,kǎi,hé,què quē,chuǎng,guān,dòu,qǐ,kuī,táng tāng chāng,guān,piáo,kàn hǎn,xì sè tà,huì,chǎn,pì,dāng dàng,huán,tà,wén,tā,mén,shuān,shǎn,yán,hàn bì,bì,wèn,chuǎng,rùn,wéi,xián,hóng,jiān jiàn,mǐn,kàng kāng,mèn mēn,zhá,nào,guī,wén,tà,mǐn,lǘ,kǎi,fá,gé,hé,kǔn,jiū,yuè,làng,dū shé,yù,yān,chāng,xì,wén,hūn,yán,è,chǎn,lán,qù,huì,kuò,què,hé,tián,tà,quē què,kàn,huán,fù,fǔ,lè,duì,xìn,qiān,wù,yì,tuó,yīn,yáng,dǒu,è,shēng,bǎn,péi,kēng,yǔn,ruǎn,zhǐ,pí,jǐng,fáng,yáng,yīn,zhèn,jiē,chēng,è,qū,dǐ,zǔ,zuò,diàn,lín,ā ē,tuó,tuó,bēi pí pō,bǐng,fù,jì,lù,lǒng,chén,xíng,duò,lòu,mò,jiàng xiáng,shū,duò,xiàn,ér,guǐ,yū,gāi,shǎn,jùn,qiào,xíng,chún,wǔ,bì,xiá,shǎn,shēng,zhì,pū,dǒu,yuàn,zhèn,chú,xiàn,dǎo,niè,yǔn,xiǎn,péi,fèi,zōu,qí,duì,lún,yīn,jū,chuí,chén,pī,líng,táo,xiàn,lù,shēng,xiǎn,yīn,zhǔ,yáng,réng,xiá,chóng,yàn yǎn,yīn,yú yáo shù,dī,yú,lóng,wēi,wēi,niè,duì zhuì,suí duò,àn,huáng,jiē,suí,yǐn yìn,qí gāi ái,yǎn,huī duò,gé,yǔn,wù,wěi kuí,ài,xì,táng,jì,zhàng,dǎo,áo,xì,yǐn yìn,sà,rǎo,lín,tuí,dèng,pí,suì,suí,ào yù,xiǎn,fén,nǐ,ér,jī,dǎo,xí,yǐn yìn,zhì,huī duò,lǒng,xī,lì dài,lì dài,lì dài,zhuī cuī wéi,hú hè,zhī,sǔn,jùn juàn,nán nàn nuó,yì,què qiāo qiǎo,yàn,qín,jiān,xióng,yǎ,jí,gù,huán,zhì,gòu,jùn juàn,cí,yōng,jū,chú,hū,zá,luò,yú,chóu,diāo,suī,hàn,huò,shuāng,guàn huán,chú,zá,yōng,jī,guī xī,chóu,liù,lí,nán nàn nuó,yù,zá,chóu,jí,yǔ yù,yú,xuě,nǎ,fǒu,sè xí,mù,wén,fēn,pāng,yún,lì,chì,yāng,líng,léi,án,báo,wù méng,diàn,dàng,hū hù,wù,diào,xū,jì,mù,chén,xiāo,zhá,tíng,zhèn,pèi,méi,líng,qī,zhōu,huò,shà,fēi,hóng,zhān,yīn,ní,shù,tún,lín,líng,dòng,yīng,wù,líng,shuāng,líng,xiá,hóng,yīn,mài,mài,yǔn,liù,mèng,bīn,wù,wèi,kuò,yín,xí,yì,ǎi,dàn,tèng,xiàn,yù,lòu lù,lóng,dài,jí,pāng,yáng,bà,pī,wēi,fēng,xì,jì,mái,méng,méng,léi,lì,huò,ǎi,fèi,dài,lóng,lìng,ài,fēng,lì,bǎo,hè,hè,hè,bìng,qīng,qīng,jìng liàng,tiān,zhèng,jìng,chēng,qìng,jìng,jìng,diàn,jìng,tiān,fēi,fēi,kào,mí,miàn,miàn,pào,yè,miǎn,huì,yè,gé,dīng,chá,jiān,rèn,dí,dù,wù,rèn,qín,jìn,xuē,niǔ,bǎ,yǐn,sǎ,nà,mò,zǔ,dá,bàn,xiè,yào,táo,bèi,jiē,hóng,páo,yāng yàng,bǐng,yīn,gé tà sǎ,táo,jié jí,xié,ān,ān,hén,gǒng,qiǎ,dá,qiáo,tīng,mán mèn,biān yìng,suī,tiáo,qiào shāo,xuān juān,kòng,běng,tà,shàng zhǎng,bǐng pí bì bēi,kuò,jū,la,xiè dié,róu,bāng,ēng,qiū,qiū,hé,qiào,mù móu,jū,jiàn jiān,biān,dī,jiān,wēn yùn,tāo,gōu,tà,bèi,xié,pán,gé,bì bǐng,kuò,tāng,lóu,guì,qiáo,xuē,jī,jiān,jiāng,chàn,dá,huò,xiǎn,qiān,dú,wā,jiān,lán,wéi,rèn,fú,mèi wà,quàn,gé,wěi,qiào,hán,chàng,kuò,rǒu,yùn,shè xiè,wěi,gé,bài,tāo,gōu,yùn,gāo,bì,wěi,suì,dú,wà,dú,wéi,rèn,fú,hán,wěi,yùn wēn,tāo,jiǔ,jiǔ,xiān,xiè,xiān,jī,yīn,zá,yùn,sháo,lè,péng,huáng,yīng,yùn,péng,ān,yīn,xiǎng,hù,yè,dǐng,qǐng,qiú,xiàng,shùn,hān,xū,yí,xù,ě,sòng,kuǐ,qí,háng,yù,wán,bān,dùn,dí,dān,pàn,pō,lǐng,chè,jǐng,lèi,hé,qiāo,è,é,wěi,jié,kuò,shěn,yí,yí,kē,duǐ,yǔ,pīng,lèi,fǔ,jiá,tóu,huì,kuí,jiá,luō,tǐng,chēng,yǐng,jūn,hú,hàn,jǐng,tuí,tuí,bīn,lài,tuí,zī,zī,chuí,dìng,lài,tán,hàn,qiān,kē,cuì,jiǒng,qīn,yí,sāi,tí,é,è,yán,wèn,kǎn,yóng,zhuān,yán,xiǎn,xìn,yǐ,yuàn,sǎng,diān,diān,jiǎng,kuī,lèi,láo,piǎo,wài,mān,cù,yáo,hào,qiáo,gù,xùn,yǎn,huì,chàn,rú,méng,bīn,xiǎn,pín,lú,lǎn,niè,quán,yè,dǐng,qǐng,hān,xiàng,shùn,xū,xū,wán,gù,dùn,qí,bān,sòng,háng,yù,lú,lǐng,pō,jǐng gěng,jié xié jiá,jiá,tǐng,hé gé,yǐng,jiǒng,kē,yí,pín bīn,huì,tuí,hàn,yǐng,yǐng,kē,tí,yóng,è,zhuān,yán,é,niè,mān,diān,sǎng,hào,lèi,chàn zhàn,rú,pín,quán,fēng fěng,biāo diū,guā,fú,xiā,zhǎn,biāo,sà,bá fú,tái,liè,guā,xuàn,xiāo,jù,biāo,sī,wěi,yáng,yáo,sōu,kǎi,sāo sōu,fān,liú,xí,liù liáo,piāo,piāo,liú,biāo,biāo,biāo,liáo,biāo,sè,fēng,xiū,fēng fěng,yáng,zhǎn,biāo,sà,jù,sī,sōu,yáo,liú,piāo,biāo,biāo,fēi,fān,fēi,fēi,shí sì yì,shí,cān,jī,dìng,sì,tuō,zhān,sūn,xiǎng,tún,rèn,yù,yǎng juàn,chì,yǐn yìn,fàn,fàn,sūn,yǐn yìn,zhù tǒu,yí sì,zuò zé zhā,bì,jiě,tāo,bǎo,cí,tiè,sì,bǎo,shì,duò,hài,rèn,tiǎn,jiǎo,hé,bǐng,yáo,tóng,cí,xiǎng,yǎng,juàn,ěr,yàn,lè,xī,cān,bō,něi,è,bū,jùn,dòu,sù,yú,shì,yáo,hún,guǒ,shì,jiàn,chuò,bǐng,xiàn,bù,yè,dàn,fēi,zhāng,wèi,guǎn,è,nuǎn,yùn,hú,huáng,tiè,huì,jiān,hóu,ài,xíng,fēn,wèi,gǔ,chā,sòng,táng,bó,gāo,xì,kuì,liù,sōu,táo,yè,wēn,mó,táng,mán,bì,yù,xiū,jǐn,sǎn,kuì,zhuàn,shàn,xī,dàn,yì,jī,ráo,chēng,yōng,tāo,wèi,xiǎng,zhān,fēn,hài,méng,yàn,mó,chán,xiǎng náng,luó,zàn,náng,shí,dìng,jī,tuō,xíng,tún,xì,rèn,yù,chì,fàn,yǐn,jiàn,shì,bǎo,sì,duò,yí,ěr,ráo,xiǎng,hé,gē le,jiǎo,xī,bǐng,bō,dòu,è,yú,něi,jùn,guǒ,hún,xiàn,guǎn,chā,kuì,gǔ,sōu,chán,yè,mó,bó,liù liú,xiū,jǐn,mán,sǎn,zhuàn,náng nǎng,shǒu,kuí,guó,xiāng,fēn,bó,ní,bì,bó,tú,hān,fēi,jiān,ān,ài,fù,xiān,yūn wò,xīn,fén,pīn,xīn,mǎ,yù,féng píng,hàn hán,dí,tuó duò,tuō zhé,chí,xùn,zhù,zhī shì,pèi,xìn jìn,rì,sà,yǔn,wén,zhí,dǎn dàn,lú,yóu,bó,bǎo,jué kuài,tuó duò,yì,qū,wén,qū,jiōng,pǒ,zhāo,yuān,pēng,zhòu,jù,zhù,nú,jū,pī,zǎng,jià,líng,zhěn,tái dài,fù,yǎng,shǐ,bì,tuó,tuó,sì,liú,mà,pián,táo,zhì,róng,téng,dòng,xún xuān,quán,shēn,jiōng,ěr,hài,bó,zhū,yīn,luò,zhōu,dàn,hài,liú,jú,sǒng,qīn,máng,liáng láng,hàn,tú,xuān,tuì,jùn,ě,chěng,xīng,sì,lù,zhuī,zhōu,shè,pián,kūn,táo,lái,zōng,kè,qí,qí,yàn,fēi,sāo,yàn,gé,yǎo,wù,piàn,cōng,piàn,qián,fēi,huáng,qián,huō,yú,tí,quán,xiá,zōng,kuí,róu,sī,guā,tuó,guī,sōu,qiān,chéng,zhì,liú,péng,téng,xí,cǎo,dú,yàn,yuán,zōu,sāo,shàn,qí,zhì,shuāng,lù,xí,luó,zhāng,mò,ào,cān,piào,cōng,qū,bì,zhì,yù,xū,huá,bō,sù,xiāo,lín,zhàn,dūn,liú,tuó,céng,diàn,jiāo,tiě,yàn,luó,zhān,jīng,yì,yè,tuó,pīn,zhòu,yàn,lóng,lǘ,téng,xiāng,jì,shuāng,jú,xí,huān,lí,biāo,mǎ,yù,tuó,xùn,chí,qū,rì,bó,lǘ,zǎng,shǐ,sì,fù,jū,zōu,zhù,tuó,nú,jià,yì,tái,xiāo,mà,yīn,jiāo,huá,luò,hài,pián,biāo,lí,chěng,yàn,xīng,qīn,jùn,qí,qí,kè,zhuī,zōng,sù,cān,piàn,zhì,kuí,sāo sǎo,wù,áo,liú,qiān,shàn,piào biāo,luó,cōng,chǎn,zhòu,jì,shuāng,xiāng,gǔ gū,wěi,wěi,wěi,yú,gàn,yì,āng,tóu,jiè,bào,bèi mó,cī,tǐ,dǐ,kū,hái,qiāo xiāo,hóu,kuà,gé,tuǐ,gěng,pián,bì,kē,qià,yú,suí,lóu,bó,xiāo,bǎng,bó jué,cī,kuān,bìn,mó,liáo,lóu,xiāo,dú,zāng,suǐ,tǐ tī,bìn,kuān,lú,gāo,gāo,qiào,kāo,qiǎo,láo,sào,biāo,kūn,kūn,dí,fǎng,xiū,rán,máo,dàn,kūn,bìn,fà,tiáo,pī,zī,fà,rán,tì,bào,bì pǒ,máo méng,fú,ér,èr,qū,gōng,xiū,kuò yuè,jì,péng,zhuā,shāo,shā,tì,lì,bìn,zōng,tì,péng,sōng,zhēng,quán,zōng,shùn,jiǎn,duǒ,hú,là,jiū,qí,lián,zhěn,bìn,péng,mà,sān,mán,mán,sēng,xū,liè,qiān,qiān,nóng,huán,kuò,níng,bìn,liè,ráng,dòu,dòu,nào,hòng,xì,dòu,kàn,dòu,dòu,jiū,chàng,yù,yù,gé lì,yàn,fǔ,zèng,guī,zōng,liù,guī,shāng,yù,guǐ,mèi,jì,qí,gà,kuí,hún,bá,pò,mèi,xū,yǎn,xiāo,liǎng,yù,tuí,qī,wǎng,liǎng,wèi,gān,chī,piāo,bì,mó,jī,xū,chǒu,yǎn,zhān,yú,dāo,rén,jì,bā bà,hóng,tuō,diào,jǐ,yú,é,jì,shā,háng,tún,mò,jiè,shěn,bǎn,yuán,pí,lǔ,wén,hú,lú,zā,fáng,fén,nà,yóu,piàn,mó,hé,xiá,qū,hān,pī,líng,tuó,bà,qiú,píng,fú,bì,cǐ jì,wèi,jū,diāo,bó bà,yóu,gǔn,pí,nián,xīng,tái,bào,fù,zhǎ zhà,jù,gū,shí,dōng,chou dài,tǎ,jié,shū,hòu,xiǎng,ér,ān,wéi,zhào,zhū,yìn,liè,luò gé,tóng,yí,yì,bìng,wěi,jiāo,kū,guī xié wā kuí,xiān xiǎn,gé,huí,lǎo,fú,kào,xiū,tuō,jūn,tí,miǎn,shāo,zhǎ,suō,qīn,yú,něi,zhé,gǔn,gěng,sū,wú,qiú,shān,pū bū,huàn,tiáo,lǐ,shā,shā,kào,méng,chéng,lí,zǒu,xī,yǒng,shēn,zī,qí,qīng,xiǎng,něi,chún,jì,diāo,qiè,gù,zhǒu,dōng,lái,fēi,ní,yì sī,kūn,lù,jiù,chāng,jīng,lún,líng,zōu,lí,měng,zōng,zhì,nián,hǔ,yú,dǐ,shī,shēn,huàn,tí,hóu,xīng,zhū,là,zōng,jì,biān,biān,huàn,quán,zéi,wēi,wēi,yú,chūn,róu,dié,huáng,liàn,yǎn,qiū,qiū,jiǎn,bī,è,yáng,fù,sāi,jiān,xiā,tuǒ,hú,shì,ruò,xuān,wēn,jiān,hào,wū,páng,sāo,liú,mǎ,shí,shī,guān,zī,téng,tǎ,yáo,è,yóng,qián,qí,wēn,ruò,shén,lián,áo,lè,huī,mǐn,jì,tiáo,qū,jiān,shēn,mán,xí,qiú,piào,jì,jì,zhú,jiāng,xiū,zhuān,yōng,zhāng,kāng,xuě,biē,yù,qū,xiàng,bō,jiǎo,xún,sù,huáng,zūn,shàn,shàn,fān,guì,lín,xún,yáo,xǐ,zēng,xiāng,fèn,guān,hòu,kuài,zéi,sāo,zhān,gǎn,guì,yìng,lǐ,cháng,léi,shǔ,ài,rú,jì,xù,hù,shǔ,lǐ,liè,lè,miè,zhēn,xiǎng,è,lú,guàn,lí,xiān,yú,dāo,jǐ,yóu,tún,lǔ,fáng,bā bà,hé gě,bà,píng,nián,lú,yóu,zhǎ zhà,fù,bó bà,bào,hòu,pí,tái,guī xié,jié,kào,wěi,ér,tóng,zéi,hòu,kuài,jì,jiāo,xiān xiǎn,zhǎ,xiǎng,xún,gěng,lí,lián,jiān,lǐ,shí,tiáo,gǔn,shā,huàn,jūn,jì,yǒng,qīng,líng,qí,zōu,fēi,kūn,chāng,gù,ní,nián,diāo,jīng,shēn,shī,zī,fèn,dié,bī,cháng,tí,wēn,wēi,sāi xǐ,è,qiū,fù,huáng,quán,jiāng,biān,sāo,áo,qí,tǎ,guān,yáo,páng,jiān,lè,biào,xuě,biē,mán,mǐn,yōng,wèi,xí,guì jué,shàn,lín,zūn,hù,gǎn,lǐ,zhān shàn,guǎn,niǎo diǎo,yǐ,fú,lì,jiū,bú,yàn,fú,diāo zhāo,jī,fèng,rù,gān hàn yàn,shī,fèng,míng,bǎo,yuān,zhī,hù,qín,fū guī,bān fén,wén,jiān qiān zhān,shī,yù,fǒu,yāo,jué,jué,pǐ,huān,zhèn,bǎo,yàn,yā,zhèng,fāng,fèng,wén,ōu,dài,jiā,rú,líng,miè,fú,tuó,mín,lì,biǎn,zhì,gē,yuān,cí,qú,xiāo,chī,dàn,jū,yāo,gū,zhōng,yù,yāng,yù,yā,dié,yù,tián,yīng,duī,wū,ér,guā,ài,zhī,yàn,héng,xiāo,jiá,liè,zhū,yáng,yí,hóng,lù,rú,móu,gē,rén,jiāo,xiū,zhōu,chī,luò,héng,nián,ě,luán,jiá,jì,tú,huān,tuǒ,bū,wú,jiān,yù,bó,jùn,jùn,bī,xī,jùn,jú,tū,jìng,tí,é,é,kuáng,hú,wǔ,shēn,lài,zān,pàn,lù,pí,shū,fú,ān,zhuó,péng,qín,qiān,bēi,diāo,lù,què,jiān,jú,tù,yā,yuān,qí,lí,yè,zhuī,kōng,duò,kūn,shēng,qí,jīng,yì,yì,jīng,zī,lái,dōng,qī,chún,gēng,jū,qū,yì,zūn,jī,shù,yīng,chì,miáo,róu,ān,qiū,tí chí,hú,tí chí,è,jiē,máo,fú bì,chūn,tú,yǎn,hé jiè,yuán,piān biǎn,kūn,méi,hú,yīng,chuàn zhì,wù,jú,dōng,cāng qiāng,fǎng,hè hú,yīng,yuán,xiān,wēng,shī,hè,chú,táng,xiá,ruò,liú,jī,gǔ hú,jiān,sǔn xùn,hàn,cí,cí,yì,yào,yàn,jī,lì,tián,kòu,tī,tī,yì,tú,mǎ,xiāo,gāo,tián,chén,jì,tuán,zhè,áo,yǎo,yī,ōu,chì,zhì,liù,yōng,lóu lǚ,bì,shuāng,zhuó,yú,wú,jué,yín,tí,sī,jiāo,yì,huá,bì,yīng,sù,huáng,fán,jiāo,liáo,yàn,gāo,jiù,xián,xián,tú,mǎi,zūn,yù,yīng,lù,tuán,xián,xué,yì,pì,zhǔ,luó,xī,yì,jī,zé,yú,zhān,yè,yáng,pì,níng,hù,mí,yīng,méng,dí,yuè,yù,lěi,bǔ,lú,hè,lóng,shuāng,yuè,yīng,guàn,qú,lí,luán,niǎo,jiū,jī,yuān,míng,shī,ōu,yā,cāng,bǎo,zhèn,gū,dōng,lú,yā,xiāo,yāng,líng,chī,qú,yuān,xué,tuó,sī,zhì,ér,guā,xiū,héng,zhōu,gē,luán,hóng,wú,bó,lí,juān,hú,é,yù,xián,tí,wǔ,què,miáo,ān,kūn,bēi,péng,qiān,chún,gēng,yuān,sù,hú,hé,è,gǔ,qiū,cí,méi,wù,yì,yào,wēng,liú,jī,yì,jiān,hè,yī,yīng,zhè,liù,liáo,jiāo,jiù,yù,lù,huán,zhān,yīng,hù,méng,guàn,shuāng,lǔ,jīn,líng,jiǎn,xián,cuó,jiǎn,jiǎn,yán,cuó,lù,yōu,cū,jǐ,páo biāo,cū,páo,zhù cū,jūn qún,zhǔ,jiān,mí,mí,yǔ,liú,chén,jūn,lín,ní,qí,lù,jiù,jūn,jīng,lí lì,xiāng,xián,jiā,mí,lì,shè,zhāng,lín,jīng,qí,líng,yán,cū,mài,mài,hé,chǎo,fū,miàn,miàn,fū,pào,qù,qū,móu,fū,xiàn,lái,qū,miàn,chi,fēng,fū,qū,miàn,má,mó me,mó me,huī,mí,zōu,nún,fén,huáng,huáng,jīn,guāng,tiān,tǒu,hóng,huà,kuàng,hóng,shǔ,lí,nián,chī,hēi,hēi,yì,qián,dǎn,xì,tún,mò,mò,qián,dài,chù,yǒu,diǎn,yī,xiá,yǎn,qū,měi,yǎn,qíng,yuè,lí,dǎng,dú,cǎn,yān,yǎn,yǎn,dàn shèn,àn,zhěn yān,dài,cǎn,yī,méi,dǎn zhǎn,yǎn,dú,lú,zhǐ,fěn,fú,fǔ,mǐn miǎn měng,mǐn miǎn měng,yuán,cù,qù,cháo,wā,zhū,zhī,měng,áo,biē,tuó,bì,yuán,cháo,tuó,dǐng,mì,nài,dǐng,zī,gǔ,gǔ,dōng,fén,táo,yuān,pí,chāng,gāo,cào,yuān,tāng,tēng,shǔ,shǔ,fén,fèi,wén,bá,diāo,tuó,zhōng,qú,shēng,shí,yòu,shí,tíng,wú,jú,jīng,hún,jú,yǎn,tū,sī,xī,xiàn,yǎn,léi,bí,yào,qiú,hān,wù,wù,hōu,xiè,è,zhā,xiù,wèng,zhā,nòng,nàng,qí zhāi,zhāi,jì,zī,jí,jī,qí jì zī zhāi,jī,chǐ,chèn,chèn,hé,yá,yīn,xiè,bāo,zé,xiè,zī,chī,yàn,jǔ,tiáo,líng,líng,chū,quán,xiè,yín,niè,jiù,yǎo,chuò,yǔn,yǔ,chǔ,yǐ,ní,zé,zōu,qǔ,yǔn,yǎn,yú,è,wò,yì,cī,zōu,diān,chǔ,jìn,yà,chǐ,chèn,hé,yín kěn,jǔ,líng,bāo,tiáo,zī,yín kěn,yǔ,chuò,qǔ,wò,lóng lǒng,páng,gōng wò,páng,yǎn,lóng,lóng lǒng,gōng,kān,dá,líng,dá,lóng,gōng,kān,guī jūn qiū,qiū,biē,guī jūn qiū,yuè,chuī,hé,jiǎo,xié,yù";
\ No newline at end of file
<template>
<div>
<Tabs v-model="current.operation">
<TabPane :label="$t('qrCode_generate_title')" name="generate">
<Row :gutter="16">
<Col span="14">
<heightResize :reduce="52">
<autoHeightTextarea v-model="current.generateInput" :placeholder="$t('qrCode_generate_input')" />
</heightResize>
</Col>
<Col span="10">
<heightResize :reduce="52">
<div class="tool-qrcode-block" v-if="generateOutput">
<img v-if="generateOutput.startsWith('data:')" @click="()=>$clipboardCopyImages(generateOutput)" style="width:70%;min-width:300px;cursor:pointer;" :src="generateOutput" />
<p v-else>{{ generateOutput }}</p>
</div>
</heightResize>
</Col>
</Row>
</TabPane>
<TabPane :label="$t('qrCode_reader_title')" name="reader">
<Row :gutter="16">
<Col span="14">
<input-block style="margin-bottom: 10px" class="tool-reader-input">
<Input v-model="current.readerInput" :rows="5" type="textarea" :placeholder="$t('qrCode_reader_input')" />
<updateFile slot="extra" type="image" @success="handleUpload" />
</input-block>
<heightResize :reduce="52" :append="['.tool-reader-input']">
<autoHeightTextarea :value="readerOutput" :placeholder="$t('qrCode_reader_output')" />
</heightResize>
</Col>
<Col span="10" >
<heightResize :reduce="52">
<div class="tool-qrcode-block" v-html="readerInputImg"></div>
</heightResize>
</Col>
</Row>
</TabPane>
</Tabs>
</div>
</template>
<script>
import generator from 'qrcode'
import qrcodeParser from 'qrcode-parser'
import model from '../../tool/model'
import Jimp from 'jimp';
import updateFile from './components/updateFile';
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
updateFile,
heightResize,
autoHeightTextarea
},
computed: {
readerInputImg() {
if (this.current.readerInput) {
return `<img style="width:70%;min-width:300px;" src="${this.current.readerInput}" />`
}
return ''
}
},
watch: {
"current.generateInput"() {
this.generate()
},
"current.readerInput"() {
this.reader()
}
},
created() {
let feature = model.getToolCurrentFeature('generate')
if (feature === 'generate') {
this.current.operation = feature;
this.$initToolData('generateInput')
} else if (feature === 'reader') {
this.current.operation = feature;
this.$initToolData('readerInput')
} else {
this.$initToolData()
}
},
methods: {
generate() {
if (!this.current.generateInput) {
this.generateOutput = "";
return;
}
generator.toDataURL(this.current.generateInput, (error, url) => {
if (error) {
this.generateOutput = this.$t("qrCode_generate_error", [error]);
return;
}
this.generateOutput = url
this.$saveToolData(this.current)
})
},
reader() {
if (!this.current.readerInput) {
this.readerOutput = "";
return
}
this.getReaderImagePngBase64(this.current.readerInput).then((result) => {
this.readerOutput = result
this.$saveToolData(this.current)
}).catch(e => {
this.readerOutput = this.$t('qrCode_reader_error', [e.message])
})
},
getReaderImagePngBase64(input) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', input);
xhr.responseType = 'blob';
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
let blob = xhr.response;
const myReader = new FileReader();
myReader.readAsArrayBuffer(blob);
myReader.addEventListener('loadend', e => {
const buffer = e.target.result;
try {
Jimp.read(buffer, (err, image) => {
if (err) {
return reject(err);
}
image.getBase64Async("image/png").then((img) => {
return qrcodeParser(img)
}).then((c) => {
resolve(c.data)
}).catch((e) => {
reject(e);
})
});
} catch (e) {
reject(e);
}
});
} else {
reject(new Error(this.$t('qrCode_reader_parsing_failure').toString()));
}
};
xhr.onerror = () => reject(new Error(this.$t('qrCode_reader_parsing_failure').toString()));
xhr.send();
})
},
handleUpload(file) {
if (this.current.operation !== "reader"){
return;
}
let r = new FileReader()
r.readAsDataURL(file)
r.onloadend = () => {
this.current.readerInput = r.result
}
return false
}
},
data() {
return {
readerOutput: "",
generateOutput: "",
current: {
generateInput: '',
readerInput: '',
operation: 'generate',
},
}
},
}
</script>
<style>
.tool-qrcode-block {
height: 100%;
display: flex;
display: -webkit-flex;
align-items: center;
justify-content: center;
}
</style>
<template>
<div>
<div class="page-option-block">
<Row :gutter="16">
<Col span="8">
<Input v-model="current.length" type="number">
<div slot="prepend" style="width: 70px">{{ $t('randomString_length') }}</div>
</Input>
</Col>
<Col span="8">
<Input v-model="current.amount" type="number">
<div slot="prepend" style="width: 70px">{{ $t('randomString_amount') }}</div>
</Input>
</Col>
<Col span="8">
<Input v-model="current.delimiter">
<div slot="prepend" style="width: 70px">{{ $t('randomString_delimiter') }}</div>
</Input>
</Col>
</Row>
<option-block>
<FormItem>
<Checkbox v-model="current.isDigital">{{ $t('randomString_digital') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isLowercase">{{ $t('randomString_lowercase') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUppercase">{{ $t('randomString_uppercase') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isSymbol">{{ $t('randomString_symbol') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUnique">{{ $t('randomString_unique') }}</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isAddQuote">{{ $t('randomString_add_quote') }}</Checkbox>
</FormItem>
<FormItem>
<Button type="primary" @click="handle()">{{ $t('randomString_generate') }}</Button>
</FormItem>
</option-block>
</div>
<heightResize :append="['.page-option-block']">
<autoHeightTextarea :value="current.output" :placeholder="$t('randomString_output')" />
</heightResize>
</div>
</template>
<script>
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components:{
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData()
},
mounted() {
if (!this.current.output){
this.handle()
}
},
methods: {
handle() {
let chars = "";
if (this.current.isDigital) chars += "0123456789";
if (this.current.isLowercase) chars += "abcdefghijklmnopqrstuvwxyz";
if (this.current.isUppercase) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (this.current.isSymbol) chars += "`~!@#$%^&*()-_=+[{]}|;:',<.>/?";
let randomStringLists = [];
for (let i = 0, l = this.current.amount; i < l; i++) {
let _chars = chars.split(""),
random_string = "";
for (let j = 0, k = this.current.length; j < k; j++) {
if (_chars.length < 1) break;
let index = Math.floor(Math.random() * _chars.length);
random_string += _chars[index];
if (this.current.isUnique) _chars.splice(index, 1);
}
randomStringLists.push(this.current.isAddQuote ? '"'+random_string+'"' : random_string);
}
this.current.output = randomStringLists.join(this.current.delimiter.replace(/\\n/, "\n"));
this.$saveToolData(this.current);
}
},
data() {
return {
current: {
length: 8,
amount: 10,
delimiter: ",\\n",
isDigital: true,
isLowercase: true,
isUppercase: true,
isSymbol: false,
isUnique: true,
isAddQuote: false,
output: "",
}
}
},
}
</script>
<template>
<div>
<Row :gutter="16" style="margin-bottom: 10px" class="page-option-block">
<Col span="12">
<input-block>
<Input type="textarea" :rows="3" v-model="current.input" :placeholder="$t('regex_expression')" />
<template slot="extra">
<referenceZh @on-select="(regex)=>current.input=regex" v-if="locale === 'zh_CN'" />
<referenceEn @on-select="(regex)=>current.input=regex" v-else />
</template>
</input-block>
</Col>
<Col span="12">
<input-block>
<Input v-model="current.replace" type="textarea" :rows="3" :placeholder="$t('regex_replace_content')" :disabled="current.isDelete === 1" />
<template slot="extra">
<RadioGroup v-model="current.isDelete">
<Radio :label="0">
{{ $t('regex_replace') }}
</Radio>
<Radio :label="1">
{{ $t('regex_delete') }}
</Radio>
</RadioGroup>
</template>
</input-block>
</Col>
</Row>
<heightResize :append="['.page-option-block']" @resize="resize">
<Row :gutter="16">
<Col span="12">
<input-block>
<autoHeightTextarea :height="height" v-model="current.content" :placeholder="$t('regex_input')"/>
<template slot="extra">
<Checkbox v-model="current.isGlobal">{{ $t('regex_global') }}</Checkbox>
<Checkbox v-model="current.isIgnoreCase">{{ $t('regex_ignore_case') }}</Checkbox>
</template>
</input-block>
</Col>
<Col span="12">
<autoHeightTextarea :height="height" :value="output" :placeholder="$t('regex_output')"/>
</Col>
</Row>
</heightResize>
</div>
</template>
<script>
import autoHeightTextarea from "./components/autoHeightTextarea";
import heightResize from "./components/heightResize";
import referenceEn from "./components/regex/referenceEn";
import referenceZh from "./components/regex/referenceZh";
import {getCurrentLocale} from "../../i18n";
export default {
components: {
autoHeightTextarea,
heightResize,
referenceEn,
referenceZh
},
created() {
this.$initToolData()
},
computed: {
locale() {
return getCurrentLocale()
},
replaceContent(){
if (!this.current.isDelete && !this.current.replace){
return false
}
return this.current.isDelete ? "" : this.current.replace;
},
output() {
let result = "";
try {
if (!this.current.input || !this.current.content) {
return result;
}
let reg = new RegExp(
this.current.input, (this.current.isIgnoreCase ? 'i' : '') + (this.current.isGlobal ? 'g' : '')
);
if (this.replaceContent !== false) {
result = this.current.content.replace(reg, this.replaceContent);
} else {
let arr = this.current.content.match(reg);
let string = '';
if (arr) {
string += this.$t('regex_output_count', [arr.length]) + "\n";
for (let i = 0; i < arr.length; i++) {
string += ("$" + i + " -> " + arr[i]) + "\r\n";
}
} else {
string = this.$t('regex_output_emty');
}
result = string
}
this.$saveToolData(this.current);
} catch (e) {
result = this.$t('regex_error', [e.message])
}
return result
}
},
methods: {
resize(height) {
this.height = height;
}
},
data() {
return {
current: {
input: "[\\dheo]",
content: ((new Date).getFullYear()) + " hello WORLD 你好世界",
output: "",
replace: "",
isGlobal: true,
isIgnoreCase: true,
isDelete: 0,
},
height: 100
}
},
}
</script>
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<FormItem>
<Select v-model="current.source" style="width:200px">
<Option v-for="v in type" :value="v" :key="v">源数据:{{ v }}</Option>
</Select>
</FormItem>
<FormItem>
<Select v-model="current.target" style="width:200px">
<Option v-for="v in type" :value="v" :key="v">目标数据:{{ v }}</Option>
</Select>
</FormItem>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle()">转换</Button>
</ButtonGroup>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
</template>
<script>
import {TYPE as conversionType,conversion} from "./library/serializeConversion"
export default {
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
methods: {
handle() {
if (this.current.input) {
try {
this.current.output = conversion(this.current.input,this.current.source).getByTarget(this.current.target);
} catch (e) {
this.$Message.error(e.message);
return;
}
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
}
},
data() {
return {
current: {
input: "",
output: "",
source: "json",
target: "xml"
},
type: conversionType,
}
},
}
</script>
\ No newline at end of file
<template>
<div>
<heightResize :append="['.page-option-block']" ignore @resize="resize">
<Row :gutter="10">
<Col span="12">
<input-block top="5px" type="default" :text="$t('sign_sign_data')" @on-default-right-bottom-click="()=>copy('signData')">
<autoHeightTextarea :height="height1" v-model="current.signData"></autoHeightTextarea>
</input-block>
</Col>
<Col span="12">
<input-block top="5px" type="default" :text="$t('sign_verify_code')" @on-default-right-bottom-click="()=>copy('verifyCode')">
<autoHeightTextarea :height="height1" v-model="current.verifyCode"></autoHeightTextarea>
</input-block>
</Col>
</Row>
<option-block class="page-option-block" center>
<FormItem>
<Select v-model="current.algorithm" style="width: 200px">
<Option v-for="v in algorithm" :value="v" :key="v">{{ v }}</Option>
</Select>
</FormItem>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="sign()">{{ $t('sign_sign') }}</Button>
<Button type="primary" @click="verify()">{{ $t('sign_verify') }}</Button>
</ButtonGroup>
</FormItem>
<FormItem>
<Button type="default" @click="openGenerateKeypairBlock()">{{ $t('sign_generate_keypair') }}</Button>
</FormItem>
</option-block>
<Row :gutter="10">
<Col span="12">
<input-block top="5px" type="default" :text="$t('sign_public_key')" @on-default-right-bottom-click="()=>copy('publicKey')">
<autoHeightTextarea :height="height2" v-model="current.publicKey"></autoHeightTextarea>
</input-block>
</Col>
<Col span="12">
<input-block top="5px" type="default" :text="$t('sign_private_key')" @on-default-right-bottom-click="()=>copy('privateKey')">
<autoHeightTextarea :height="height2" v-model="current.privateKey"></autoHeightTextarea>
</input-block>
</Col>
</Row>
</heightResize>
<Modal v-model="generateKeypairData.show" :title="$t('sign_generate_keypair')">
<Form :label-width="80">
<FormItem :label="$t('sign_keypair_type')">
<Select v-model="generateKeypairData.type">
<Option value="PKCS8PRV">PKCS#8</Option>
<Option value="PKCS1PRV">PKCS#1</Option>
</Select>
</FormItem>
<FormItem :label="$t('sign_keypair_length')">
<Select v-model="generateKeypairData.length">
<Option :value="512">512 bit</Option>
<Option :value="1024">1024 bit</Option>
<Option :value="2048">2048 bit</Option>
<Option :value="4096">4096 bit</Option>
</Select>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="generateKeypairData.show = false">{{ $t('sign_generate_cancel') }}</Button>
<Button type="primary" disabled v-if="generateKeypairData.loading">{{ $t('sign_generate_in') }}</Button>
<Button v-else type="primary" @click="generateKeypair()">{{ $t('sign_generate') }}</Button>
</div>
</Modal>
</div>
</template>
<script>
import rs from "jsrsasign";
import autoHeightTextarea from "./components/autoHeightTextarea";
import heightResize from "./components/heightResize";
export default {
components:{
autoHeightTextarea,
heightResize
},
created() {
this.$initToolData()
},
methods: {
sign() {
try {
if (!this.current.signData || !this.current.privateKey){
throw new Error(this.$t('sign_error_sign_content_empty').toString())
}
let rsaPrivateKey = rs.KEYUTIL.getKey(this.current.privateKey)
let sign = new rs.KJUR.crypto.Signature({alg: this.current.algorithm})
sign.init(rsaPrivateKey)
sign.updateString(this.current.signData)
let signResult = sign.sign()
// 转为base64
this.current.verifyCode = rs.hex2b64(signResult)
// 自动复制签名结果到剪切板
this.$clipboardCopy(this.current.verifyCode);
// 保存历史记录
this.$saveToolData(this.current);
}catch (e){
this.$Message.error(this.$t('sign_error',[e.message]).toString())
}
},
verify() {
try {
if (!this.current.verifyCode || !this.current.publicKey){
throw new Error(this.$t('sign_error_verify_content_empty').toString())
}
let rsaPublicKey = rs.KEYUTIL.getKey(this.current.publicKey)
let sign = new rs.KJUR.crypto.Signature({alg: this.current.algorithm})
sign.init(rsaPublicKey)
sign.updateString(this.current.signData)
let hexData = rs.b64tohex(this.current.verifyCode)
let verifyResult = sign.verify(hexData)
if (!verifyResult) {
throw new Error(this.$t('sign_verify_fail').toString())
}
// 保存历史记录
this.$saveToolData(this.current);
this.$Message.info(this.$t('sign_verify_ok').toString())
}catch (e){
this.$Message.error(this.$t('sign_error',[e.message]).toString())
}
},
generateKeypair() {
this.generateKeypairData.loading = true;
setTimeout(() => {
try {
const rsaKeypair = rs.KEYUTIL.generateKeypair("RSA", this.generateKeypairData.length);
this.current.privateKey = rs.KEYUTIL.getPEM(rsaKeypair.prvKeyObj, this.generateKeypairData.type)
this.current.publicKey = rs.KEYUTIL.getPEM(rsaKeypair.pubKeyObj)
this.generateKeypairData.show = false
} catch (e) {
this.$Message.error(this.$t('sign_error',[e.message]).toString())
}
this.generateKeypairData.loading = false;
}, 500)
},
openGenerateKeypairBlock() {
this.generateKeypairData.show = true;
this.generateKeypairData.loading = false;
this.generateKeypairData.type = "PKCS8PRV";
this.generateKeypairData.length = 2048;
},
resize(height){
this.height1 = Math.min(160,Math.ceil(height/2))
this.height2 = height - this.height1
},
copy(type){
if ((type in this.current) && this.current[type]){
this.$copy(this.current[type],true);
}
}
},
data() {
return {
current: {
signData: '',
privateKey: '',
publicKey: '',
verifyCode: '',
algorithm: 'MD5withRSA'
},
algorithm: ["MD5withRSA", "SHA1withRSA", "SHA256withRSA", "SHA512withRSA"],
generateKeypairData: {
show: false,
loading: false,
length: 2048,
type: "PKCS8PRV",
},
height1:100,
height2:100,
}
}
}
</script>
<template>
<div>
<input-block right="15px" bottom="10px">
<heightResize :append="['.page-option-block']">
<autoHeightTextarea v-model="current.content" :placeholder="$t('text_input')"></autoHeightTextarea>
</heightResize>
<template slot="extra">
<Button type="dashed" @click="statShow = true" size="small">
{{ $t('text_stat_show',[stat.word_length,stat.byte_utf8_length,stat.byte_gbk_length]) }}
<Icon type="ios-more" />
</Button>
</template>
</input-block>
<option-block class="page-option-block">
<FormItem v-if="current.original.length > 0">
<Button type="default" :size="buttonSize"
@click="[current.content,current.original]=[current.original,current.content]">
{{ $t('text_resume') }}
</Button>
</FormItem>
<FormItem>
<Dropdown @on-click="(item)=>handle(item)" transfer>
<Button :size="buttonSize" type="primary">
{{ $t('text_case_conversion') }}
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="upper">{{ $t('text_upper_all') }}</DropdownItem>
<DropdownItem name="lower">{{ $t('text_lower_all') }}</DropdownItem>
<DropdownItem name="upperLineStart">{{ $t('text_upper_line_start') }}</DropdownItem>
<DropdownItem name="lowerLineStart">{{ $t('text_lower_line_start') }}</DropdownItem>
<DropdownItem name="upperStart">{{ $t('text_upper_word_start') }}</DropdownItem>
<DropdownItem name="lowerStart">{{ $t('text_lower_word_start') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
</FormItem>
<FormItem>
<Dropdown @on-click="(item)=>handle('replacePunctuation',item)" transfer>
<Button :size="buttonSize" type="primary">
{{ $t('text_punctuation') }}
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="en">{{ $t('text_cn') }} -> {{ $t('text_en') }}</DropdownItem>
<DropdownItem name="zh">{{ $t('text_en') }} -> {{ $t('text_cn') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
</FormItem>
<FormItem>
<Dropdown @on-click="(item)=>handle('zhTran',item)" transfer>
<Button :size="buttonSize" type="primary">
{{ $t('text_simplified_traditional') }}
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="simplified">{{ $t('text_simplified') }} -> {{ $t('text_traditional') }}</DropdownItem>
<DropdownItem name="traditional">{{ $t('text_traditional') }} -> {{ $t('text_simplified') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
</FormItem>
<FormItem>
<Button :size="buttonSize" type="primary" @click="replace.show = true">{{ $t('text_replace') }}</Button>
</FormItem>
<FormItem>
<Button :size="buttonSize" type="primary" @click="handle('lineRemoveRepeat')">
{{ $t('text_line_remove_duplicate') }}
</Button>
</FormItem>
<FormItem>
<Dropdown @on-click="(item)=>handle(item)" transfer>
<Button :size="buttonSize" type="primary">
{{ $t('text_line_number') }}
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="addLineIndex">{{ $t('text_line_number_add') }}</DropdownItem>
<DropdownItem name="removeLineIndex">{{ $t('text_line_number_remove') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
</FormItem>
<FormItem>
<Dropdown @on-click="(item)=>handle('lineSort',item)" transfer>
<Button :size="buttonSize" type="primary">
{{ $t('text_line_sort') }}
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="asc">{{ $t('text_line_sort_asc') }}</DropdownItem>
<DropdownItem name="desc">{{ $t('text_line_sort_desc') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
</FormItem>
<FormItem>
<Dropdown @on-click="(item)=>handle(item)" transfer>
<Button :size="buttonSize" type="primary">
{{ $t('text_filter') }}
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="lineTrim">{{ $t('text_filter_trim') }}</DropdownItem>
<DropdownItem name="filterBlankLine">{{ $t('text_filter_blank_line') }}</DropdownItem>
<DropdownItem name="filterAllBr">{{ $t('text_filter_all_br') }}</DropdownItem>
</DropdownMenu>
</Dropdown>
</FormItem>
<FormItem>
<Button :size="buttonSize" type="primary" @click="handleStringEscape()">
{{ $t('stringEscape') }}
<!-- <Icon type="ios-arrow-down"></Icon> -->
</Button>
</FormItem>
</option-block>
<Modal v-model="statShow" :styles="{top: '20px'}" width="700" footer-hide>
<Tabs value="stat">
<TabPane :label="$t('text_stat')" name="stat">
<Table :columns="statColumns" stripe border size="small" :data="statTable" />
</TabPane>
<TabPane :label="$t('text_stat_explain')" name="explain">
<Table :columns="statExplain.columns" border stripe size="small" :data="statExplain.data"/>
</TabPane>
</Tabs>
</Modal>
<Modal v-model="replace.show" width="600" :title="$t('text_replace')">
<Form label-position="top">
<Row :gutter="16">
<Col span="12">
<FormItem :label="$t('text_replace_search')">
<input-block>
<Input v-model="replace.search" :rows="6" type="textarea"></Input>
<template slot="extra">
<Checkbox v-model="replace.regular">{{ $t('text_replace_regular') }}
</Checkbox>
</template>
</input-block>
</FormItem>
</Col>
<Col span="12">
<FormItem :label="$t('text_replace_replace')">
<Input v-model="replace.replace" :rows="6" type="textarea"></Input>
</FormItem>
</Col>
</Row>
</Form>
<Alert v-if="!replace.regular">{{ $t('text_replace_explain') }}</Alert>
<div slot="footer">
<Button type="text" @click="replace.show = false">{{ $t('text_cancel') }}</Button>
<Button type="primary" @click="replaceRun()">{{ $t('text_submit') }}</Button>
</div>
</Modal>
</div>
</template>
<script>
import TextHandle from './library/text'
import autoHeightTextarea from "./components/autoHeightTextarea";
import heightResize from "./components/heightResize";
export default {
components:{
autoHeightTextarea,
heightResize
},
created() {
this.$initToolData('content')
},
computed: {
stat(){
return TextHandle(this.current.content).stat()
},
statTable() {
let stat = TextHandle(this.current.content).stat();
return [
{
name1: this.$t('text_string_length'), value1: stat.string_length,
name2: this.$t('text_byte_length'), value2: `${stat.byte_utf8_length} / ${stat.byte_gbk_length}`
},
{
name1: this.$t('text_word_length'), value1: stat.word_length,
name2: this.$t('text_line_length'), value2: stat.line_length
},
{
name1: this.$t('text_zh_length'), value1: `${stat.zh_word} / ${stat.zh_punctuation}`,
name2: this.$t('text_en_length'), value2: `${stat.en_string} / ${stat.en_word} / ${stat.en_punctuation}`
},
{
name1: this.$t('text_int_length'), value1: `${stat.int_string} / ${stat.int_word}`,
name2: '-', value2: '-'
},
]
}
},
methods: {
handle(method, ...parameter) {
try {
let result = TextHandle(this.current.content)[method](...parameter)
this.current.original = this.current.content;
this.current.content = result;
this.$saveToolData(this.current);
this.$Message.success(this.$t('text_ok').toString())
} catch (e) {
this.$Message.error(this.$t('text_error',[e.message]).toString())
}
},
replaceRun() {
if (this.replace.regular){
this.handle('regularReplace', this.replace.search, this.replace.replace)
}
else{
this.handle('replace', this.replace.search.split(/\r?\n/), this.replace.replace.split(/\r?\n/))
}
this.replace.show = false
},
handleStringEscape() {
console.log(this.current.content);
this.current.content = this.current.content.replace(/\\/g, `\\\\`);
}
},
data() {
return {
replace: {
show: false,
search: "",
replace: "",
regular: false
},
current: {
content: "",
original: "",
},
statShow:false,
statExplain: {
columns: [
{
title: this.$t('text_item'),
key: 'name',
width: 200
},
{
title: this.$t('text_explain'),
key: 'explain',
},
],
data: [
{name: this.$t('text_explain_byte_length_utf8_name'), explain: this.$t('text_explain_byte_length_utf8_info')},
{name: this.$t('text_explain_byte_length_gbk_name'), explain: this.$t('text_explain_byte_length_gbk_info')},
{name: this.$t('text_explain_string_length_name'), explain: this.$t('text_explain_string_length_info')},
{name: this.$t('text_explain_word_length_name'), explain: this.$t('text_explain_word_length_info')},
{name: this.$t('text_explain_int_length_name'), explain: this.$t('text_explain_int_length_info')},
{name: this.$t('text_explain_int_word_length_name'), explain: this.$t('text_explain_int_word_length_info')},
{name: this.$t('text_explain_blank_line_length_name'), explain: this.$t('text_explain_blank_line_length_info')},
]
},
statColumns: [
{
title: this.$t('text_item'),
key: 'name1',
width: 200
},
{
title: this.$t('text_value'),
key: 'value1',
align: "right"
},
{
title: this.$t('text_item'),
key: 'name2',
width: 200
},
{
title: this.$t('text_value'),
key: 'value2',
align: "right"
},
],
buttonSize: "small",
}
},
}
</script>
<style>
.ctool-stat-block .ivu-modal-body {
padding: 0;
}
</style>
<template>
<div>
<Tabs name="default">
<TabPane :label="$t('time_diff_tool')" name="default">
<option-block disable-padding>
<FormItem>
<DatePicker transfer v-model="current.poor.input1" :options="options" type="datetime"
format="yyyy-MM-dd HH:mm:ss"></DatePicker>
</FormItem>
<FormItem>
{{ $t('time_and') }}
</FormItem>
<FormItem>
<DatePicker transfer v-model="current.poor.input2" :options="options" type="datetime"
format="yyyy-MM-dd HH:mm:ss"></DatePicker>
</FormItem>
<FormItem>
{{ $t('time_diff') }}
</FormItem>
<FormItem>
<Input v-model="poor">
<Select transfer v-model="current.poor.unit" slot="append" style="width: 80px">
<Option v-for="v in poorUnit" :value="v.v" :key="v.v">{{ v.n }}</Option>
</Select>
</Input>
</FormItem>
</option-block>
</TabPane>
</Tabs>
<Tabs name="default">
<TabPane :label="$t('time_operation')" name="default">
<option-block disable-padding>
<FormItem>
<DatePicker transfer v-model="current.duration.input" :options="options" type="datetime"
format="yyyy-MM-dd HH:mm:ss"></DatePicker>
</FormItem>
<FormItem>
<Select transfer v-model="current.duration.type" style="width: 100px">
<Option value="+">{{ $t('time_add') }}</Option>
<Option value="-">{{ $t('time_reduce') }}</Option>
</Select>
</FormItem>
<FormItem>
<Input v-model="current.duration.length" type="number" number>
<Select transfer v-model="current.duration.unit" slot="append" style="width: 80px">
<Option v-for="v in poorUnit" :value="v.v" :key="v.v">{{ v.n }}</Option>
</Select>
</Input>
</FormItem>
<FormItem>
{{ $t('time_after') }}, {{ $t('time_is') }} <strong>{{ duration }}</strong>
</FormItem>
</option-block>
</TabPane>
</Tabs>
<Tabs name="default">
<TabPane :label="$t('time_analyze')" name="default">
<option-block disable-padding>
<FormItem>
<DatePicker transfer v-model="current.analyze.input" :options="options" type="datetime"
format="yyyy-MM-dd HH:mm:ss"></DatePicker>
</FormItem>
<FormItem>
<Select transfer v-model="current.analyze.type" style="width: 90px">
<Option value="year">{{ $t('time_analyze_year') }}</Option>
<Option value="quarter">{{ $t('time_analyze_quarter') }}</Option>
<Option value="month">{{ $t('time_analyze_month') }}</Option>
</Select>
</FormItem>
<FormItem>
{{ analyze }}
</FormItem>
</option-block>
</TabPane>
</Tabs>
</div>
</template>
<script>
import moment from 'moment'
export default {
created() {
this.$initToolData()
},
computed: {
analyze() {
let input = moment(this.current.analyze.input)
let output = "";
const year = input.year();
const quarter = input.quarter();
if (this.current.analyze.type === "quarter") {
const quarterDate = moment(`${input.year()}-${(quarter - 1) * 3 + 1}-01`);
const weekOfQuarter = Math.ceil((input.unix() - quarterDate.unix()) / (86400 * 7));
const dayOfQuarter = Math.ceil((input.unix() - quarterDate.unix()) / 86400);
const hourOfQuarter = Math.ceil((input.unix() - quarterDate.unix()) / 3600);
const minuteOfQuarter = Math.ceil((input.unix() - quarterDate.unix()) / 60);
const secondOfQuarter = input.unix() - quarterDate.unix();
output = this.$t('time_analyze_quarter_output', {
quarter,
weekOfQuarter,
dayOfQuarter,
hourOfQuarter,
minuteOfQuarter,
secondOfQuarter
});
}
if (this.current.analyze.type === "month") {
const month = input.month() + 1
const monthDate = moment(`${input.year()}-${month}-01`);
const weekOfMonth = Math.ceil((input.unix() - monthDate.unix()) / (86400 * 7));
const hourOfMonth = Math.ceil((input.unix() - monthDate.unix()) / 3600);
const minuteOfMonth = Math.ceil((input.unix() - monthDate.unix()) / 60);
const secondOfMonth = input.unix() - monthDate.unix();
output = this.$t('time_analyze_month_output', {
month,
weekOfMonth,
hourOfMonth,
minuteOfMonth,
secondOfMonth
});
}
if (this.current.analyze.type === "year"){
const yearDate = moment(input.year() + '-01-01');
const weekOfYear = input.isoWeek();
const dayOfYear = input.dayOfYear();
const hourOfYear = Math.ceil((input.unix() - yearDate.unix()) / 3600);
const minuteOfYear = Math.ceil((input.unix() - yearDate.unix()) / 60);
const secondOfYear = input.unix() - yearDate.unix();
output = this.$t('time_analyze_year_output', {
year,
quarter,
weekOfYear,
dayOfYear,
hourOfYear,
minuteOfYear,
secondOfYear
});
}
this.saveToolData()
return output;
},
poor() {
let a = moment(this.current.poor.input1)
let b = moment(this.current.poor.input2)
this.saveToolData()
return b.diff(a, this.current.poor.unit)
},
duration() {
if (!this.current.duration.length) {
return "";
}
let rate = this.getRate(this.current.duration.unit)
let result;
if (rate === 0) {
if (!Number.isInteger(this.current.duration.length)) {
return this.$t('time_error', [this.$t('time_error_duration_length')])
}
const type = this.current.duration.type === '+' ? 'add' : 'subtract'
result = moment(this.current.duration.input)[type](this.current.duration.length, this.current.duration.unit)
} else {
result = moment(
moment(this.current.duration.input).unix() * 1000
+ (rate * this.current.duration.length) * (this.current.duration.type === '+' ? 1 : -1)
)
}
this.saveToolData()
return result.format('YYYY-MM-DD HH:mm:ss');
},
},
methods: {
saveToolData(){
this.current.poor.input1 = moment(this.current.poor.input1).format('YYYY-MM-DD HH:mm:ss')
this.current.poor.input2 = moment(this.current.poor.input2).format('YYYY-MM-DD HH:mm:ss')
this.current.duration.input = moment(this.current.duration.input).format('YYYY-MM-DD HH:mm:ss')
this.current.analyze.input = moment(this.current.analyze.input).format('YYYY-MM-DD HH:mm:ss')
this.$saveToolData(this.current)
},
getRate(unit) {
for (let item of this.poorUnit) {
if (item.v === unit) {
return parseInt(item.rate)
}
}
return 0;
}
},
data() {
return {
options: {
shortcuts: [
{
text: this.$t('time_current_time'),
value() {
return moment().toDate()
},
},
{
text: this.$t('time_current_date'),
value() {
return moment(moment().format('YYYY-MM-DD')).toDate()
},
},
{
text: this.$t('time_current_month_date'),
value() {
return moment(moment().format('YYYY-MM-01')).toDate()
},
},
{
text: this.$t('time_current_year_date'),
value() {
return moment(moment().format('YYYY-01-01')).toDate()
},
},
],
},
poorUnit: [
{v: 'years', n: this.$t('time_year'), rate: 0},
{v: 'months', n: this.$t('time_month'), rate: 0},
{v: 'weeks', n: this.$t('time_week'), rate: 1000 * 60 * 60 * 24 * 7},
{v: 'days', n: this.$t('time_day'), rate: 1000 * 60 * 60 * 24},
{v: 'hours', n: this.$t('time_hour'), rate: 1000 * 60 * 60},
{v: 'minutes', n: this.$t('time_minute'), rate: 1000 * 60},
{v: 'seconds', n: this.$t('time_second'), rate: 1000},
],
current: {
poor: {
input1: moment(moment().format('YYYY-MM-DD')).toDate(),
input2: moment(moment().format('YYYY-MM-DD')).add(1, 'd').toDate(),
unit: 'seconds',
},
duration: {
input: moment(moment().format('YYYY-MM-DD')).toDate(),
unit: 'days',
type: '+',
length: 1,
},
analyze: {
type: "year",
input: moment(moment().format('YYYY-MM-DD')).toDate()
}
}
}
},
}
</script>
<template>
<heightResize class="tool-timestamp-page">
<div class="tool-timestamp-block">
<option-block>
<input-block bottom="8px" right="8px">
<Input size="large" v-model="current.input">
<span slot="prepend">{{ $t('timestamp_input') }}</span>
</Input>
<template slot="extra">
<Dropdown @on-click="currentTime" transfer>
<Button size="small" type="primary">
{{ $t('timestamp_get') }}
<Icon type="ios-arrow-down"></Icon>
</Button>
<DropdownMenu slot="list">
<DropdownItem name="normalSecond">{{ $t('timestamp_normal_second') }}</DropdownItem>
<DropdownItem name="normalMillisecond">{{
$t('timestamp_normal_millisecond')
}}
</DropdownItem>
<DropdownItem name="unixSecond">{{ $t('timestamp_unix_second') }}</DropdownItem>
<DropdownItem name="unixMillisecond">{{
$t('timestamp_unix_millisecond')
}}
</DropdownItem>
</DropdownMenu>
</Dropdown>
</template>
</input-block>
</option-block>
<option-block>
<input-block bottom="8px" right="8px">
<Input size="large" :value="output">
<span slot="prepend">{{ $t('timestamp_output') }}</span>
</Input>
<template slot="extra">
<Button size="small" type="primary" @click="()=>$copy(output)">{{
$t('timestamp_copy')
}}
</Button>
</template>
</input-block>
</option-block>
<Table :columns="exampleColumns" stripe border size="small" :data="example">
<template slot-scope="{ row }" slot="_value">
<Button size="small" type="text" @click="()=>$copy(row.value)">{{ row.value }}</Button>
</template>
</Table>
</div>
</heightResize>
</template>
<script>
import moment from 'moment'
import heightResize from "./components/heightResize";
let inputType = {
'normalSecond': 1,
'normalMillisecond': 2,
'unixSecond': 3,
'unixMillisecond': 4,
'error': 0,
}
export default {
components: {
heightResize
},
created() {
this.$initToolData('input', (data) => {
return (
(new RegExp(/^\d+-\d+-\d+ \d+:\d+:\d+$/)).test(data)
|| (new RegExp(/^\d+-\d+-\d+ \d+:\d+:\d+\.\d+$/)).test(data)
|| (new RegExp(/^\d{10}$/)).test(data)
|| (new RegExp(/^\d{13}$/)).test(data)
)
})
},
mounted() {
this.timer = setInterval(() => {
this.timestamp = moment().format('x')
}, 100);
},
beforeDestroy() {
clearInterval(this.timer);
},
computed: {
example() {
let time = moment(parseInt(this.timestamp))
return [
{format: this.$t('timestamp_normal_second'), value: time.format('YYYY-MM-DD HH:mm:ss')},
{format: this.$t('timestamp_unix_second'), value: time.format('X')},
{format: this.$t('timestamp_normal_millisecond'), value: time.format('YYYY-MM-DD HH:mm:ss.SSS')},
{format: this.$t('timestamp_unix_millisecond'), value: time.format('x')},
]
},
output() {
let result = "";
if (!this.current.input) {
return result;
}
try {
let type = function (input) {
if ((new RegExp(/^\d+-\d+-\d+ \d+:\d+:\d+$/)).test(input)) {
return inputType.normalSecond
}
if ((new RegExp(/^\d+-\d+-\d+ \d+:\d+:\d+\.\d+$/)).test(input)) {
return inputType.normalMillisecond
}
if ((new RegExp(/^\d{10}$/)).test(input)) {
return inputType.unixSecond
}
if ((new RegExp(/^\d{13}$/)).test(input)) {
return inputType.unixMillisecond
}
return inputType.error
}(this.current.input.trim())
if (type === inputType.error) {
throw new Error(this.$t('timestamp_error_format').toString())
}
switch (type) {
case inputType.normalSecond:
result = moment(this.current.input).format('X')
break
case inputType.normalMillisecond:
result = moment(this.current.input).format('x')
break
case inputType.unixSecond:
result = moment(parseInt(this.current.input) * 1000).format('YYYY-MM-DD HH:mm:ss')
break
case inputType.unixMillisecond:
result = moment(parseInt(this.current.input)).format('YYYY-MM-DD HH:mm:ss.SSS')
break
}
this.$saveToolData(this.current)
} catch (e) {
result = this.$t('timestamp_error', [e.message])
}
return result;
}
},
methods: {
currentTime(type) {
if (type === "normalSecond") {
this.current.input = moment().format('YYYY-MM-DD HH:mm:ss')
} else if (type === "normalMillisecond") {
this.current.input = moment().format('YYYY-MM-DD HH:mm:ss.SSS')
} else if (type === "unixSecond") {
this.current.input = moment().format('X')
} else {
this.current.input = moment().format('x')
}
},
},
data() {
return {
current: {
input: moment().format('YYYY-MM-DD HH:mm:ss')
},
timer: null,
timestamp: 0,
exampleColumns: [
{
title: this.$t('timestamp_format'),
key: 'format',
width: 200
},
{
title: this.$t('timestamp_value'),
slot: '_value',
}
]
}
},
}
</script>
<style>
.tool-timestamp-page {
display: flex;
display: -webkit-flex;
align-items: center;
justify-content: center;
}
.tool-timestamp-block {
width: 600px;
}
</style>
<template>
<div>
<Input v-model="current.input" :rows="7" type="textarea" placeholder="内容"></Input>
<option-block>
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('encode')">字符转Unicode(编码)</Button>
<Button type="primary" @click="handle('decode')">Unicode转字符(解码)</Button>
</ButtonGroup>
</FormItem>
<FormItem>
<Select v-model="current.type" style="width:250px">
<Option value="unicode_point_default">Unicode 默认模式 \u[0-9a-f]{4}</Option>
<Option value="unicode_point_wide">Unicode 宽字符模式 \u[0-9a-f]{4,6}</Option>
<Option value="unicode_point_wide_brace">Unicode 宽字符模式(带大括号) \u{[0-9a-f]{4,6}}</Option>
<Option value="unicode_number">Unicode 编码模式 U+[0-9A-F]{4,6}</Option>
<Option value="html_entity_10">html 实体(10进制) &amp;#[0-9]+;</Option>
<Option value="html_entity_16">html 实体(16进制) &amp;#x[0-9a-f]{1,6};</Option>
<Option value="css_entitie">css 实体(16进制) \[0-9a-f]{4,6}</Option>
</Select>
</FormItem>
<FormItem v-if="!disable_ignore_ascii_select.includes(current.type)">
<Checkbox v-model="current.ignore_ascii">禁止 ASCII 字符编码</Checkbox>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="7" type="textarea" placeholder="结果"></Input>
</div>
</template>
<script>
import Unicode from "./library/unicode"
export default {
created() {
this.current = Object.assign(this.current, this.$getToolData("input"))
},
methods: {
handle(operation) {
if (this.current.input) {
try {
if (operation === "encode") {
this.current.output = Unicode.encode(
this.current.input,
this.current.type,
this.disable_ignore_ascii_select.includes(this.current.type) ? false : this.current.ignore_ascii
);
} else {
this.current.output = Unicode.decode(this.current.input, this.current.type);
}
} catch (e) {
return this.$Message.error(e.message)
}
this.current.operation = operation;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
}
},
data() {
return {
current: {
input: "",
output: "",
operation: "",
type: "unicode_point_default",
ignore_ascii: true,
},
disable_ignore_ascii_select: ['unicode_point_wide', 'unicode_number', 'css_entitie']
}
},
}
</script>
\ No newline at end of file
<template>
<div>
<option-block style="text-align: center">
<FormItem>
<RadioGroup v-model="type" type="button" button-style="solid">
<Radio :style="radioGroupStyle" :label="v.key" v-for="v in categories" :key="v.key">{{ v.name }}
</Radio>
</RadioGroup>
</FormItem>
</option-block>
<option-block style="text-align: center">
<FormItem>
<Input v-model="current.input" type="number"></Input>
</FormItem>
<FormItem>
<Select v-model="current.from" style="width:200px">
<template v-if="groups.length > 1">
<OptionGroup :label="group.name" v-for="group in groups" :key="group.key">
<Option v-for="unit in group.list" :value="unit" :key="unit">{{ unitName(unit) }}</Option>
</OptionGroup>
</template>
<template v-else>
<Option v-for="unit in groups[0].list" :value="unit" :key="unit">{{ unitName(unit) }}</Option>
</template>
</Select>
</FormItem>
<FormItem>
<Button icon="md-code-working" @click="exchange()"></Button>
</FormItem>
<FormItem>
<Select v-model="current.to" style="width:200px">
<Option value="all">{{ $t('unit_all') }}</Option>
<template v-if="groups.length > 1">
<OptionGroup :label="group.name" v-for="group in groups" :key="group.key">
<Option v-for="unit in group.list" :value="unit" :key="unit">{{ unitName(unit) }}</Option>
</OptionGroup>
</template>
<template v-else>
<Option v-for="unit in groups[0].list" :value="unit" :key="unit">{{ unitName(unit) }}</Option>
</template>
</Select>
</FormItem>
</option-block>
<div style="padding: 0 30px; min-height: 200px">
<template v-if="assignResult !== null">
<div style="text-align: center;margin-top: 30px;font-size: 18px;font-weight: bold">
<span style="color: red">{{ current.input }}</span> {{ unitName(current.from) }} = <span
style="color: red">{{ assignResult }}</span>
{{ unitName(current.to) }}
</div>
</template>
<CellGroup v-if="current.to === 'all'">
<Row :gutter="16">
<Col span="12" v-for="(result,unitKey) in output" :key="unitKey">
<Cell :title="result" :extra="unitName(unitKey)"/>
</Col>
</Row>
</CellGroup>
</div>
</div>
</template>
<script>
import U from './library/unit'
import {getCurrentLocale} from "../../i18n";
export default {
created() {
let history = this.$getToolData()
this.type = this.current.type = history['type'] ? history['type'] : 'temperature'
this.getToolData(this.type)
},
computed: {
radioGroupStyle() {
return getCurrentLocale() === "en" ? "padding: 0 5px" : "padding: 0 10px";
},
categories() {
return U.CONFIG.map((category) => {
return {name: category.name, key: category.key}
})
},
groups() {
return U.getCategory(this.current.type).group
},
isShowResult() {
return this.current.from && this.current.type && this.current.input
},
output() {
let result = {}
if (this.isShowResult) {
this.saveToolData()
for (let unit of U.getCategory(this.current.type).unit) {
result[unit.key] = U.calculate(
this.current.type,
this.current.input,
this.current.from,
unit.key
)
}
}
return result
},
assignResult() {
if (this.current.to !== 'all') {
if (this.current.to in this.output) {
return this.output[this.current.to]
}
}
return null
}
},
watch:{
type(value){
this.handle(value)
}
},
methods: {
handle(v) {
this.getToolData(v)
},
saveToolData() {
let history = this.$getToolData()
history.type = this.current.type
history.data = history.data ? history.data : {}
history.data[history.type] = {
from: this.current.from,
to: this.current.to,
input: this.current.input,
}
this.$saveToolData(history)
},
getToolData(type) {
let history = this.$getToolData()
let unitHistory = history['data'] && history['data'][type] ? history['data'][type] : null
this.current = Object.assign(this.current, {
from : unitHistory ? unitHistory.from : U.getCategory(type).main,
to : unitHistory ? unitHistory.to : 'all',
input : unitHistory ? unitHistory.input : '',
type : type
})
},
exchange() {
if (this.current.to === 'all') {
return
}
if (!this.current.from || !this.current.to) {
return
}
[this.current.from, this.current.to] = [this.current.to, this.current.from]
},
unitName(unitKey) {
let unit = U.getUnit(this.current.type, unitKey)
return `${unit.name} (${unit['unit']})`
}
},
data() {
return {
current: {
type: '',
from: '',
to: '',
input: '',
},
type:"",
}
},
}
</script>
<template>
<heightResize :append="['.page-option-block']" ignore @resize="resize">
<autoHeightTextarea :height="inputHeight" v-model="current.input" :placeholder="$t('url_input')" />
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle('encode')">{{ $t('url_encode') }}</Button>
<Button type="primary" @click="handle('decode')">{{ $t('url_decode') }}</Button>
</ButtonGroup>
</FormItem>
</option-block>
<autoHeightTextarea :height="outputHeight" :value="current.output" :placeholder="$t('url_output')" />
</heightResize>
</template>
<script>
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components:{
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData('input')
},
methods: {
handle(v) {
if (this.current.input) {
this.current.output = v === "encode" ? encodeURIComponent(this.current.input) : decodeURIComponent(this.current.input);
this.current.operation = v;
this.$clipboardCopy(this.current.output);
this.$saveToolData(this.current);
}
},
resize(height){
this.inputHeight = Math.min(160,Math.ceil(height/2));
this.outputHeight = height - this.inputHeight;
}
},
data() {
return {
current: {
input: "",
output: "",
operation: ""
},
inputHeight:100,
outputHeight:100,
}
},
}
</script>
<template>
<div>
<option-block>
<FormItem style="width: 140px">
<Input v-model="current.amount">
<div slot="prepend">生成数量</div>
</Input>
</FormItem>
<FormItem style="width: 140px">
<Input v-model="current.delimiter">
<div slot="prepend">分隔符</div>
</Input>
</FormItem>
<FormItem>
<Checkbox v-model="current.filterLine">过滤中划线(-)</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUpper">大写</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.isAddQuote">添加引号</Checkbox>
</FormItem>
<FormItem>
<Checkbox v-model="current.uint8Array">Uint8 Array</Checkbox>
</FormItem>
<FormItem>
<Button type="primary" @click="handle()">生成</Button>
</FormItem>
</option-block>
<Input v-model="current.output" :rows="14" type="textarea" placeholder="结果"></Input>
</div>
</template>
<script>
import {parse as uuidParse, v4 as uuidV4} from 'uuid';
export default {
created() {
this.current = Object.assign(this.current, this.$getToolData())
},
methods: {
handle() {
let result = [];
for (let i = 0, l = this.current.amount; i < l; i++) {
result.push(this.current.isAddQuote ? '"' + this.generate() + '"' : this.generate());
}
this.current.output = result.join(this.current.delimiter.replace(/\\n/g, "\n"));
this.$saveToolData(this.current);
},
generate() {
let uuid = uuidV4()
if (this.current.uint8Array) {
return "[" + uuidParse(uuid).toString() + "]"
}
if (this.current.filterLine) {
uuid = uuid.replace(/-/g, "")
}
uuid = this.current.isUpper ? uuid.toUpperCase() : uuid.toLowerCase()
return uuid;
}
},
data() {
return {
current: {
amount: 10,
delimiter: ",\\n",
filterLine: false,
isAddQuote: false,
isUpper: false,
uint8Array: false,
output: ""
}
}
},
}
</script>
\ No newline at end of file
<template>
<heightResize ignore @resize="resize">
<Row :gutter="10">
<Col span="6">
<input-block top="4px" :text="$t('variableConversion_input')">
<autoHeightTextarea :height="height1" v-model="current.input" :placeholder="$t('variableConversion_input_placeholder')" />
</input-block>
</Col>
<Col span="6" v-for="(item,key) in resultColumns" :key="key" :style="`margin-top: ${key > 2 ? '10px' : '0'}`">
<input-block top="4px" type="default" :text="item.title" @on-default-right-bottom-click="()=>$copy(output[item.key])">
<autoHeightTextarea :height="key > 2 ? height2 : height1" :value="output[item.key]" :placeholder="item.title" />
</input-block>
</Col>
</Row>
</heightResize>
</template>
<script>
import varCamelCase from "./library/varCamelCase"
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
computed: {
resultColumns() {
return varCamelCase.resultKey.map((item) => {
return {
title: item.name,
key: item.key
}
});
},
output() {
let result = varCamelCase.convent(this.current.input)
this.$saveToolData(this.current);
return result;
}
},
created() {
this.$initToolData('input')
},
methods: {
resize(height) {
this.height1 = Math.ceil(height/2);
this.height2 = height - this.height1 - 10;
}
},
data() {
return {
current: {
input: ""
},
height1: 100,
height2: 100
}
},
}
</script>
<template>
<div>
<Input v-model="current.url" class="page-option-block" style="margin-bottom: 10px">
<span slot="prepend">
<Badge style="margin-left:10px" :status="status ? 'success' : 'error'"/>
</span>
<Button slot="append" v-if="!status" @click="handle()">{{ $t('websocket_connect') }}</Button>
<Button slot="append" v-else @click="handle()">{{ $t('websocket_close') }}</Button>
</Input>
<Row :gutter="10">
<Col span="10">
<input-block top="7px" right="7px">
<heightResize :append="['.page-option-block']">
<autoHeightTextarea v-model="sendContent" :placeholder="$t('websocket_send_content')"/>
</heightResize>
<template slot="extra">
<Button :disabled="!status" type="primary" size="small" @click="send">{{
$t('websocket_send')
}}
</Button>
</template>
</input-block>
</Col>
<Col span="14">
<input-block top="7px" right="7px" :text="$t('websocket_send')" @on-default-right-bottom-click="send">
<heightResize :append="['.page-option-block']" @resize="logHeightSet">
<Card>
<div class="lists-block" id="log"
:style="`height: ${logHeight}px;overflow: hidden;overflow-y:auto;`">
<div v-if="lists.length === 0" style="font-size: 14px;color: #999999">
{{ $t('websocket_log_content') }}
</div>
<div v-else v-for="(item,key) in lists" :key="key" class="item-wrap">
<div class="item" v-if="item.type === 'send'" style="color:green">
{{ $t('websocket_you') }} {{ item.time }}
</div>
<div class="item" v-else-if="item.type === 'accept'" style="color:blue">
{{ $t('websocket_server') }} {{ item.time }}
</div>
<div class="item" v-else>
{{ item.time }}
</div>
<div class="item">
<Icon type="md-copy" @click="$copy(item.content)"/>
<pre class="item-content">{{ item.content }}</pre>
</div>
</div>
</div>
</Card>
</heightResize>
<template slot="extra">
<Button style="margin-right: 5px" size="small" type="primary" @click="copyAll()">
{{ $t('websocket_copy') }}
</Button>
<Button size="small" type="primary" @click="clear()">{{ $t('websocket_clear') }}</Button>
</template>
</input-block>
</Col>
</Row>
</div>
</template>
<script>
import moment from 'moment'
import heightResize from "./components/heightResize";
import autoHeightTextarea from "./components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData()
},
methods: {
handle() {
if (this.status) {
return this.close();
}
return this.connect();
},
connect() {
if (!this.current.url.trim()) {
return
}
this.$saveToolData(this.current);
this.log(this.$t('websocket_connect_start', [this.current.url]).toString())
let websocket = new WebSocket(this.current.url);
websocket.onopen = (evt) => {
this.onOpen(evt)
};
websocket.onclose = (evt) => {
this.onClose(evt)
};
websocket.onmessage = (evt) => {
this.onMessage(evt)
};
websocket.onerror = (evt) => {
this.onError(evt)
};
this.ws = websocket;
},
close() {
this.log(this.$t('websocket_close_start', [this.current.url]).toString())
this.ws.close();
},
clear() {
this.lists = [];
},
log(content, type = "other") {
this.lists.push({content, type, time: moment().format("YYYY-MM-DD HH:mm:ss")});
this.$nextTick(() => {
let log = document.getElementById('log');
log.scrollTop = log.scrollHeight;
})
},
copyAll() {
this.$copy(JSON.stringify(this.lists));
},
send() {
try {
if (!this.status) {
throw new Error(this.$t('websocket_error_connect').toString())
}
if (!this.sendContent) {
throw new Error(this.$t('websocket_error_content').toString())
}
this.ws.send(this.sendContent);
this.log(this.sendContent, 'send')
} catch (e) {
this.log(this.$t('websocket_error', [e.message]).toString())
}
},
onOpen() {
this.status = true;
this.log(this.$t('websocket_connect_ok').toString())
},
onClose() {
this.status = false;
this.log(this.$t('websocket_close_ok').toString())
},
onMessage(evt) {
this.log(evt.data, 'accept')
},
onError(evt) {
this.log(this.$t('websocket_error', [evt.data()]).toString())
},
logHeightSet(height) {
this.logHeight = Math.max(height - 34, 100)
}
},
data() {
return {
current: {
url: "wss://echo.websocket.events",
},
status: false,
wx: null,
sendContent: "",
lists: [],
logHeight: 100,
}
},
}
</script>
<style lang="less" scoped>
.lists-block {
font-size: 14px;
line-height: 28px;
}
.item {
position: relative;
&-wrap:not(:first-child) {
margin-top: 16px;
}
& /deep/ .ivu-icon {
position: absolute;
right: 8px;
top: 8px;
padding: 8px;
cursor: pointer;
background-color: #fff;
border-radius: 5px;
}
&-content {
margin: 0;
overflow: auto;
padding: 8px;
background-color: #f0f0f0;
border-radius: 5px;
line-height: 1.3;
}
}
</style>
<template>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('hexString_input')"/>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="codeGenString()">{{ $t('allMy_convert') }}</Button>
<!-- <Button type="primary" @click="handle('str')">Hex -> String</Button> -->
</ButtonGroup>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUppercase">{{ $t('hexString_uppercase') }}</Checkbox>
</FormItem>
</option-block>
<!-- <span>美化的内容&nbsp;&nbsp;&nbsp;&nbsp;</span><input class="input_width_100" type="text" v-model="current.output_beautiful">
<br>
<span>字符串格式&nbsp;&nbsp;&nbsp;&nbsp;</span><input class="input_width_100" type="text" v-model="current.output_str">
<br>
<span>字节数组格式:</span><input class="input_width_100" type="text" v-model="current.output_bytes"> -->
<autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('hexString_output')"/>
</heightResize>
</template>
<script>
import heightResize from "../../tool/components/heightResize";
import autoHeightTextarea from "../../tool/components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData('input')
},
methods: {
codeGenString() {
console.log('enter...')
var ret = 'StringBuilder sb = new StringBuilder();\n'
if (this.current.input) {
var lst = []
var max_length = 65500;
var count = Math.floor(this.current.input.length / max_length);
let index = 0;
for (; index < count; index++) {
lst.push(
this.current.input.substr(index * max_length, max_length)
)
}
lst.push(
this.current.input.substring(index * max_length, this.current.input.length)
)
for (let index = 0; index < lst.length; index++) {
const element = lst[index];
ret += 'sb.append("' + element + '");\n';
}
ret += '\nString str = sb.toString();'
}
console.log('leave...', ret)
this.current.output = ret
},
resize(height) {
this.inputHeight = Math.min(320, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
// this.outputHeight = 180
}
},
data() {
return {
current: {
input: "",
isUppercase: false,
output_beautiful: "", // 一行,全字节内容,美化的内容
output_str: "", // 字符串格式
output_bytes: "", // 字节数组格式
output: "",
operation: ""
},
inputHeight: 100,
outputHeight: 100
}
},
}
</script>
<style scoped>
.input_width_100 {
width: 80%;
margin: 8px 0;
}
</style>
\ No newline at end of file
<template>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('hexString_input')"/>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="codeGenJson()">{{ $t('allMy_convert') }}</Button>
<Button type="primary" @click="winError()"> winerror.h </Button>
<Button type="primary" @click="codeGenFrida()">{{ $t('allMy_codeGenFrida') }}</Button>
<Button type="primary" @click="codeGenX64dbgIdaVtable()">{{ $t('allMy_codeGenX64dbgIdaVtable') }}</Button>
<!-- <Button type="primary" @click="handle('str')">Hex -> String</Button> -->
</ButtonGroup>
</FormItem>
<FormItem>
<Checkbox v-model="current.isFormat">{{ $t('hexString_uppercase') }}</Checkbox>
</FormItem>
</option-block>
<!-- <span>美化的内容&nbsp;&nbsp;&nbsp;&nbsp;</span><input class="input_width_100" type="text" v-model="current.output_beautiful">
<br>
<span>字符串格式&nbsp;&nbsp;&nbsp;&nbsp;</span><input class="input_width_100" type="text" v-model="current.output_str">
<br>
<span>字节数组格式:</span><input class="input_width_100" type="text" v-model="current.output_bytes"> -->
<autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('hexString_output')"/>
</heightResize>
</template>
<script>
import heightResize from "../../tool/components/heightResize";
import autoHeightTextarea from "../../tool/components/autoHeightTextarea";
export default {
data() {
return {
current: {
input: `
123033 31
123034 31
123035 32
`,
isFormat: false,
output_beautiful: "", // 一行,全字节内容,美化的内容
output_str: "", // 字符串格式
output_bytes: "", // 字节数组格式
output: "",
operation: ""
},
inputHeight: 100,
outputHeight: 100
}
},
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData('input')
},
methods: {
codeGenJsonOld() {
console.log('enter...')
var objJson = {}
if (this.current.input) {
var lines = this.current.input.split('\n');
lines.forEach(line => {
console.log(line)
var items = line.split(' ')
function del_space(s) {
return (s && s.trim());
}
// 去除空字符串
items = items.filter(del_space)
if (items.length != 2) {
console.log(items)
}
objJson[items[0]] = items[1]
})
}
console.log('leave...', objJson)
this.current.output = JSON.stringify(objJson)
},
codeGenJson() {
console.log('enter...')
var objJson = {}
if (this.current.input) {
var lines = this.current.input.split('\n');
lines.forEach(line => {
console.log(line)
line = line.trim().replace(/\s+/g, ' ')
var items = line.split(' ')
if (items.length != 2) {
console.log(items)
return
}
objJson[items[0]] = items[1]
})
}
console.log('leave...', objJson)
this.current.output = JSON.stringify(objJson, null, 4)
},
winError() {
var objJson = [];
// // (.*)\n//\n#define (\S+)\s+(\d+)L/g
var r = /\/\/ (.*)\n\/\/\n#define (\S+)\s+(\d+)L/g;
var a = null;
while ((a = r.exec(this.current.input))) { //循环执行匹配操作
console.log("匹配文本 = " + a[0] + " a.index = " + a.index + " r.lastIndex = " + r.lastIndex); //显示每次匹配后返回的数组信息
var [_, desc, k, v] = a;
objJson.push({desc: desc, k: k, v: v});
}
this.current.output = JSON.stringify(objJson);
console.log(Object.keys(objJson).length);
},
codeGenFrida_item(func, params) {
var js = `/*\n` + this.current.input.replace('\n\n', '\n') + `\n*/
Interceptor.attach(Module.getExportByName('ntdll.dll', '`+ func + `'), {
onEnter(args) {
`
// var lpExistingFileName = args[0];
// var lpNewFileName = args[1];
var lst_params = [];
params.map( (val, index) => {
var pType = val[1];
var pName = val[2];
js += ` var ` + pName + ` = args[` + index + `];\n`
lst_params.push(pName);
});
// console.log(lpExistingFileName, lpNewFileName, bFailIfExists)
js += ` console.log('>>> ` + func + ' >>> ' + lst_params.join(' ') + ` = ', ` + lst_params.toString() +`);`
js += `
},
onLeave(retval) {
console.log('>>> ` + func + ` >>> retval = ', retval);
}
});
`
return js;
},
codeGenFrida() {
/*
NTSYSCALLAPI
NTSTATUS
NTAPI
NtGetContextThread(
_In_ HANDLE ThreadHandle,
_Inout_ PCONTEXT ThreadContext
);
*/
var r = /\n(.*)\(([\s\S]*)\);/mg;
var input = this.current.input;
var a = r.exec(input);
if (a) {
var func = a[1];
var params = a[2];
params = params.split(',').map(v=>{return v.trim().split(' ')})
console.log(func, params);
this.current.output = this.codeGenFrida_item(func, params);
}
},
resize(height) {
this.inputHeight = Math.min(320, Math.ceil(height / 2))
this.outputHeight = height - this.inputHeight
// this.outputHeight = 180
},
// .rdata:007FB580 dd offset sub_4D8780
// .rdata:007FB584 dd offset sub_4D8E20
// ==>
// SetBPX leigod.exe:$0xD8780;SetBPX leigod.exe:$0xD8E20;
codeGenX64dbgIdaVtable() {
var r = /dd offset sub_(\S{6})/mg;
var input = this.current.input;
var a = r.exec(input);
// if (a) {
// var addr = a[1];
// var addr_int = parseInt(addr, 16);
// var addr_v = '0x' + Number(addr_int-0x400000).toString(16);
// console.log(addr, addr_int, addr_v);
// }
var out = '';
while ((a = r.exec(this.current.input))) { //循环执行匹配操作
var addr = a[1];
var addr_int = parseInt(addr, 16);
var addr_v = '0x' + Number(addr_int-0x400000).toString(16);
out += 'SetBPX leigod.exe:$' + addr_v + '; '
}
this.current.output = out;
}
},
}
</script>
<style scoped>
.input_width_100 {
width: 80%;
margin: 8px 0;
}
</style>
\ No newline at end of file
因为 它太大了无法显示 source diff 。你可以改为 查看blob
<template>
<heightResize ignore :append="['.page-option-block']" @resize="resize">
<autoHeightTextarea v-model="current.input" :height="inputHeight" :placeholder="$t('hexString_input')"/>
<option-block class="page-option-block">
<FormItem>
<ButtonGroup>
<Button type="primary" @click="handle()">{{ $t('allMy_convert') }}</Button>
<!-- <Button type="primary" @click="handle('str')">Hex -> String</Button> -->
</ButtonGroup>
</FormItem>
<FormItem>
<Checkbox v-model="current.isUppercase">{{ $t('hexString_uppercase') }}</Checkbox>
</FormItem>
</option-block>
<span>美化的内容&nbsp;&nbsp;&nbsp;&nbsp;</span><input class="input_width_100" type="text" v-model="current.output_beautiful">
<br>
<span>字符串格式&nbsp;&nbsp;&nbsp;&nbsp;</span><input class="input_width_100" type="text" v-model="current.output_str">
<br>
<span>字节数组格式:</span><input class="input_width_100" type="text" v-model="current.output_bytes">
<autoHeightTextarea :value="current.output" :height="outputHeight" :placeholder="$t('hexString_output')"/>
</heightResize>
</template>
<script>
import heightResize from "../tool/components/heightResize";
import autoHeightTextarea from "../tool/components/autoHeightTextarea";
export default {
components: {
heightResize,
autoHeightTextarea
},
created() {
this.$initToolData('input')
},
methods: {
handle() {
console.log('enter...')
var bytes = ''
if (this.current.input) {
var lines = this.current.input.split('\n');
lines.forEach(line => {
console.log(line)
var items = line.split('|')
if (items.length != 4) {
return
}
bytes += items[1]
// items.forEach(item => {
// console.log(item)
// })
})
}
console.log('leave...', bytes)
this.current.output = bytes
//
this.current.output_beautiful = bytes.replaceAll(':', '').replaceAll(' ', '')
if (this.current.output_beautiful.length % 2 == 1) {
alert('数据有误,请检查后再尝试')
return;
}
var lst = []
for (var i = 0; i < this.current.output_beautiful.length / 2; ++i) {
lst.push(this.current.output_beautiful.slice(2*i, 2*i + 2))
}
this.current.output_str = ''
lst.forEach(item => {
this.current.output_str += '\\x' + item;
})
this.current.output_bytes = ''
lst.forEach(item => {
this.current.output_bytes += '0x' + item + ', ';
})
},
resize(height) {
this.inputHeight = Math.min(320, Math.ceil(height / 2))
// this.outputHeight = height - this.inputHeight
this.outputHeight = 180
}
},
data() {
return {
current: {
input: "",
isUppercase: false,
output_beautiful: "", // 一行,全字节内容,美化的内容
output_str: "", // 字符串格式
output_bytes: "", // 字节数组格式
output: "",
operation: ""
},
inputHeight: 100,
outputHeight: 100
}
},
}
</script>
<style scoped>
.input_width_100 {
width: 80%;
margin: 8px 0;
}
</style>
\ No newline at end of file
const {defineConfig} = require('@vue/cli-service')
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
const adapter = require('./src/tool/adapter');
const pages = {
tool: {
entry: 'src/tool.js',
template: 'public/tool.html',
}
}
const config = {
productionSourceMap: false,
publicPath: "./",
pages: pages,
chainWebpack: config => {
config.plugin('define').tap(args => {
args[0]['process.ctool'] = JSON.stringify({
version: process.env.npm_package_version,
updateTime: Date.parse((new Date()).toString()) / 1000,
platform: adapter.platform,
isChrome: adapter.isChrome,
isFirefox: adapter.isFirefox,
isEdge: adapter.isEdge,
isChromium: adapter.isChromium,
isWeb: adapter.isWeb,
isUtools: adapter.isUtools,
});
return args
})
if (process.env.NODE_ENV === 'production') {
// 独立打包js 防止js文件过大 影响相关平台审核
config.optimization.splitChunks({
cacheGroups: {
codemirror: {
test: /[\\/]node_modules[\\/]codemirror[\\/]/,
name: 'codemirror',
chunks: 'all',
priority: 100,
reuseExistingChunk: true,
enforce: true
},
prettier: {
test: /[\\/]node_modules[\\/](prettier|@prettier|prettier-plugin-sql|sql-formatter)[\\/]/,
name: 'prettier',
chunks: 'all',
priority: 99,
reuseExistingChunk: true,
enforce: true
},
prettierParserTypescript: {
test: /[\\/]node_modules[\\/]prettier[\\/]parser-typescript\.js/,
name: 'prettier-parser-typescript',
chunks: 'all',
priority: 100,
reuseExistingChunk: true,
enforce: true
},
nodeSqlQarser: {
test: /[\\/]node_modules[\\/](node-sql-parser)[\\/]/,
name: 'node-sql-qarser',
chunks: 'all',
priority: 100,
reuseExistingChunk: true,
enforce: true
},
uglify: {
test: /[\\/]src[\\/]views[\\/]tool[\\/]library[\\/]formatter[\\/]uglify\.js/,
name: 'uglify',
chunks: 'all',
priority: 100,
enforce: true
}
}
})
}
},
configureWebpack: {
plugins: [new NodePolyfillPlugin()],
resolve: {
fallback: {
fs: false
}
}
},
css: {
loaderOptions: {
less: {
lessOptions: {
javascriptEnabled: true,
}
}
}
},
lintOnSave: false,
devServer: {
// disableHostCheck: true,
// host: '0.0.0.0',
allowedHosts: [
'datasea.cn',
'preview-62e00738167f7e3ed361db3c-6354405c78a0a92e29958ee5-8081.datasea.cn'
],
}
}
adapter.initialize()
module.exports = defineConfig(config)
# 任务一:GitCode平台基础操作
## 一、任务步骤
| 步骤 | 步骤名称 | 步骤描述 | 示意图 |
| ---- | ---- | ---- | ---- |
| 1 | Fork项目 | 从[项目列表](#五项目列表)fork感兴趣的开源项目,Fork完成即完成步骤1 | ![](https://gitcode.net/theo789/upload_project/uploads/149ed2bf8dc709da03af8a86176d92d0/image.png) |
| 2 | 创建issue | 在fork的项目中提交issue表单,说明fork理由 | ![](https://gitcode.net/theo789/upload_project/uploads/508b1d5cf4df84fe60ca0bf33c00957c/image.png) |
| 3 | 项目star | 在fork的项目中完成star动作 | ![](https://gitcode.net/theo789/upload_project/uploads/e19f6014236c9ff82d805042e7184e18/image.png)|
**特殊说明:**
- 提交issue表单必须是有意义的话语,如“111”、“222”、“abc”等无意义的issue不算完成任务。
- fork项目的issue和star对优质开源项目有一定参考意义,希望大家认真对待。
## 二、奖品发放规则
每天给前一天完成任务的用户发放奖品
## 三、活动交流
开源活动官方交流群(仅参与者之间讨论和交流)。扫码进入选手沟通群。活动重要节点通知会在群内第一时间告知,请所有参与者尽量加群。
![](https://file.iviewui.com/asd/cloud-ide/cloud-ide-1.png)
## 四、活动点评
### 活动建议
如果大家对本次活动有建议,可以直接在本项目中提交issue,我们会认真对待每一个评论,非常感谢大家!!!
### 活动点赞👍
如果大家喜欢本次开源挑战赛活动,可以点击本项目的star,我们会根据大家的star数作为后期是否长期举办的重要依据,非常感谢大家!!!
## 五、开源项目建议
CSDN官方开源运营会随时增加优质开源项目,如大家有推荐的开源项目可通过[Issue表单](https://gitcode.net/gitcode/1024opensource/-/issues/new?issue%5Bassignee_id%5D=&issue%5Bmilestone_id%5D=)提交到本项目中,利用开源方式发现更多开源优质项目。
## 六、项目列表
1. [free-programming-books](https://gitcode.net/mirrors/EbookFoundation/free-programming-books)
1. [Java程序员必读书单, 超1000本PDF](https://gitcode.net/mirrors/itwanger/JavaBooks)
1. [labuladong 的算法小抄
](https://gitcode.net/mirrors/labuladong/fucking-algorithm)
1. [Java学习+面试指南](https://gitcode.net/mirrors/Snailclimb/JavaGuide)
1. [一款使用 Vue+Spring Boot 开发的前后端分离项目](https://gitcode.net/mirrors/antabot/white-jotter)
1. [2004-2020美赛O奖论文](https://gitcode.net/mirrors/dick20/mcm-icm)
1. [Python - 100天从新手到大师](https://gitcode.net/mirrors/jackfrued/Python-100-Days)
1. [Java处理Excel工具](https://gitcode.net/mirrors/alibaba/easyexcel)
1. [SpringBoot+MyBatis实现的电商管理系统](https://gitcode.net/mirrors/macrozheng/mall)
1. [SpringBoot+Vue开发的微人事系统vhr](https://gitcode.net/mirrors/lenve/vhr)
1. [阿里巴巴 MySQL binlog 增量订阅&消费组件canal](https://gitcode.net/mirrors/alibaba/canal)
1. [FASTJSON2为下一个十年提供的高性能的JSON库](https://gitcode.net/mirrors/alibaba/fastjson2)
1. [阿里巴巴分布式数据库同步系统otter](https://gitcode.net/mirrors/alibaba/otter)
1. [微服务框架Dubbo](https://gitcode.net/mirrors/alibaba/dubbo)
1. [DataX阿里云DataWorks数据集成的开源版本](https://gitcode.net/mirrors/alibaba/datax)
1. [Sentinel面向云原生微服务的高可用流控防护组件](https://gitcode.net/mirrors/alibaba/sentinel)
1. [应用性能监控系统Skywalking](https://gitcode.net/mirrors/apache/incubator-skywalking)
1. [前端可视化项目Echarts](https://gitcode.net/mirrors/apache/echarts)
1. [数据可视化系统superset](https://gitcode.net/mirrors/apache/superset)
1. [ZooKeeper提供分布式配置服务、同步服务和命名注册](https://gitcode.net/mirrors/apache/zookeeper)
1. [Oceanbase企业级原生分布式数据库](https://gitcode.net/oceanbase/oceanbase)
1. [TDengine一个高效的存储、查询、分析时序大数据的平台](https://gitcode.net/taosdata/tdengine)
1. [MegEngine一个快速、可拓展、易于使用且支持自动求导的深度学习框架](https://gitcode.net/megvii/megengine)
1. [RT-Thread一个集实时操作系统(RTOS)内核、中间件组件的物联网操作系统](https://gitcode.net/rt-thread/rt-thread)
1. [](https://gitcode.net/paddlepaddle/Paddle)
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
1. []()
# 任务二:开源项目开发与运行
## 一、任务介绍
1024程序员节结合开源大趋势,开发者可根据自己情况选择业界知名开源项目或自研可开源项目结合GitCode和Cloud IDE进行开发与适配,需要在IDE中能够运行起来为标准获得CSDN定制书包奖励。
## 二、任务步骤
| 顺序 | 步骤名称 | 步骤描述 | 示意图 |
| ---- | ---- | ---- | ---- |
| 1 | 任务报名 | Fork创建项目,在项目中右上角点击Fork按钮,完成后即报名成功 | ![](https://gitcode.net/gitcode/1024opensource/uploads/8db3366911695d7e1c6851833634deb7/%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_f43ff07c-d546-4dc3-8e00-07fde528d955.png) |
| 2 | 项目导入 | 上传开源项目或自研可开源项目至Fork项目中 | ![](https://gitcode.net/theo789/upload_project/uploads/9280a335d186801ece171b56ee83ad0c/image.png) |
| 3 | IDE打开项目 | 使用Cloud IDE打开项目,Fork项目链接地址中快速启动IDE | ![](https://gitcode.net/theo789/upload_project/uploads/ca739c3c5252cd6f25d0e4d01656afbf/image.png) |
| 4 | IDE中项目运行 | 项目下载完成后,需要下载对应扩展,需要能够运行启动项目 | 前端项目可执行预览,后端项目可展示启动 ![](https://gitcode.net/theo789/upload_project/uploads/4fabe699f2ae7d3870a0562a44ae2505/image.png) |
| 5 | 配置自动运行脚本 | 编写preview.xml文件,能够让项目自动运行 | 可参考 [前端项目2048](https://gitcode.net/cloud-ide/2048)[后端项目CnOCR](https://gitcode.net/cloud-ide/cnocr)|
| 6 | 回传至开源项目 | 完成项目开发后,使用IDE的Git操作完成push代码 | ![](https://gitcode.net/theo789/upload_project/uploads/f29bf06cd2b96e07b67b47873fbe278f/image.png) |
| 7 | 项目完成 | 至此项目已完成开发和运行,即可等待CSDN官方确认奖励 | 希望大家都可以获得CSDN定制书包 ![](https://img-home.csdnimg.cn/images/20221013053300.png) |
## 三、奖品发放规则
**奖品发放时间点**
| 次数 | 公布中奖名单 |
| ------ | ------ |
| 第一次 | 2022-10-31 |
| 第二次 | 2022-11-07 |
| 第三次 | 2022-11-14 |
**活动参与和获奖规则**
- 本项任务,开发者只能获得一次奖励任务。
- 获奖开发者会通过私信或短信通知用户填写收货地址。
- 发货时间:活动结束后30个工作日内发货
## 四、活动交流
开源活动官方交流群(仅参与者之间讨论和交流)。扫码进入选手沟通群。活动重要节点通知会在群内第一时间告知,请所有参与者尽量加群。
![](https://file.iviewui.com/asd/cloud-ide/cloud-ide-1.png)
## 五、活动点评
### 活动建议
如果大家对本次活动有建议,可以直接在本项目中提交issue,我们会认真对待每一个评论,非常感谢大家!!!
### 活动点赞👍
如果大家喜欢本次开源挑战赛活动,可以点击本项目的star,我们会根据大家的star数作为后期是否长期举办的重要依据,非常感谢大家!!!
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册