Add docker rename volume tool

This commit is contained in:
Illya Marchenko 2024-09-28 15:16:10 +03:00
parent ee930f96fc
commit f75809c12d
Signed by: stuzer05
GPG Key ID: A6ABAAA9268F9F4F
32 changed files with 703 additions and 627 deletions

@ -2,13 +2,13 @@
require("@rushstack/eslint-patch/modern-module-resolution"); require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = { module.exports = {
"root": true, root: true,
"extends": [ extends: [
"plugin:vue/vue3-essential", "plugin:vue/vue3-essential",
"eslint:recommended", "eslint:recommended",
"@vue/eslint-config-prettier" "@vue/eslint-config-prettier",
], ],
"env": { env: {
"vue/setup-compiler-macros": true "vue/setup-compiler-macros": true,
} },
} };

@ -62,6 +62,9 @@ export default {
'php_array_to_json': 'PHP array to Json', 'php_array_to_json': 'PHP array to Json',
'php_serialize': 'PHP serialize', 'php_serialize': 'PHP serialize',
}, },
'Docker': {
'docker_rename_volume': 'Rename volume',
},
'GO': { 'GO': {
'go_json_to_struct': 'JSON to Go struct', 'go_json_to_struct': 'JSON to Go struct',
// 'sql_tables_to_struct': 'SQL tables Go struct', // 'sql_tables_to_struct': 'SQL tables Go struct',

@ -149,6 +149,15 @@ const router = createRouter({
component: () => import('../views/GoSQLTablesToStruct.vue'), component: () => import('../views/GoSQLTablesToStruct.vue'),
}, },
/**
* Docker
*/
{
path: '/docker_rename_volume',
name: 'docker_rename_volume',
component: () => import('../views/DockerRenameVolume.vue'),
},
/** /**
* SQL manipulation * SQL manipulation
*/ */

@ -0,0 +1,58 @@
<template>
<h2 class="tool-title">Docker rename volume</h2>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="volume_name_old">Old volume name</label>
<input id="volume_name_old" v-model="toolData.volumeNameOld" v-on:keyup="result" type="text">
</div>
<div class="input-group">
<label for="volume_name_new">New volume name</label>
<input id="volume_name_new" v-model="toolData.volumeNameNew" v-on:keyup="result" type="text">
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
<label for="result">Result</label>
<MonacoEditor name="result" language="text" :value="toolResult"></MonacoEditor>
</div>
</template>
<script>
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
components: {
MonacoEditor
},
data() {
return {
toolData: {
volumeNameOld: "",
volumeNameNew: ""
},
toolResult: ""
};
},
methods: {
result() {
if (!this.toolData.volumeNameOld.length) {
this.toolResult = "fill old volume name";
return;
}
if (!this.toolData.volumeNameNew.length) {
this.toolResult = "fill new volume name";
return;
}
this.toolResult = `docker run --rm -v ${this.toolData.volumeNameOld}:/from -v ${this.toolData.volumeNameNew}:/to busybox cp -av /from/. /to`;
}
}
};
</script>
<style lang="scss">
</style>

@ -5,9 +5,11 @@
<div class="input-group"> <div class="input-group">
<label>Dimensions</label> <label>Dimensions</label>
<div style="display: flex"> <div style="display: flex">
<input class="input" v-model="toolData.width" v-on:keyup="result" v-on:change="result" placeholder="500" type="number" style="width: 70px">px <input class="input" v-model="toolData.width" v-on:keyup="result" v-on:change="result" placeholder="500"
type="number" style="width: 70px">px
<span style="padding: 0 10px">x</span> <span style="padding: 0 10px">x</span>
<input class="input" v-model="toolData.height" v-on:keyup="result" v-on:change="result" placeholder="500" type="number" style="width: 70px">px <input class="input" v-model="toolData.height" v-on:keyup="result" v-on:change="result" placeholder="500"
type="number" style="width: 70px">px
</div> </div>
</div> </div>
@ -26,7 +28,8 @@
<div class="input-group"> <div class="input-group">
<label for="result">Result</label> <label for="result">Result</label>
<div :style="{'width': toolData.width, 'height': toolData.height}"> <div :style="{'width': toolData.width, 'height': toolData.height}">
<canvas ref="canvas" :width="toolData.width" :height="toolData.height" style="max-width: 50vw; max-height: 50vh;"></canvas> <canvas ref="canvas" :width="toolData.width" :height="toolData.height"
style="max-width: 50vw; max-height: 50vh;"></canvas>
</div> </div>
</div> </div>
</template> </template>
@ -38,10 +41,10 @@ export default {
toolData: { toolData: {
width: 500, width: 500,
height: 500, height: 500,
color_bg: '#000000', color_bg: "#000000",
color_text: '#ffffff', color_text: "#ffffff"
}, },
toolResult: '', toolResult: ""
}; };
}, },
mounted() { mounted() {
@ -49,7 +52,7 @@ export default {
}, },
methods: { methods: {
result() { result() {
const ctx = this.$refs.canvas.getContext('2d'); const ctx = this.$refs.canvas.getContext("2d");
// Set background color // Set background color
ctx.fillStyle = this.toolData.color_bg; ctx.fillStyle = this.toolData.color_bg;
@ -57,7 +60,7 @@ export default {
// Set text color and font // Set text color and font
ctx.fillStyle = this.toolData.color_text; ctx.fillStyle = this.toolData.color_text;
ctx.font = 'bold 30px Arial'; ctx.font = "bold 30px Arial";
// Draw text on the canvas // Draw text on the canvas
const text = `${this.toolData.width}x${this.toolData.height}`; const text = `${this.toolData.width}x${this.toolData.height}`;
@ -65,9 +68,9 @@ export default {
const x = (this.toolData.width - textWidth) / 2; const x = (this.toolData.width - textWidth) / 2;
const y = this.toolData.height / 2 + 10; const y = this.toolData.height / 2 + 10;
ctx.fillText(text, x, y); ctx.fillText(text, x, y);
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -16,7 +16,7 @@
</template> </template>
<script> <script>
import cronstrue from 'cronstrue'; import cronstrue from "cronstrue";
import MonacoEditor from "@/components/MonacoEditor.vue"; import MonacoEditor from "@/components/MonacoEditor.vue";
export default { export default {
@ -26,15 +26,15 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '* * * * *', data: "* * * * *"
}, },
toolResult: '', toolResult: ""
}; };
}, },
mounted() { mounted() {
this.toolResult = cronstrue.toString(this.toolData.data, { this.toolResult = cronstrue.toString(this.toolData.data, {
use24HourTimeFormat: true, use24HourTimeFormat: true,
verbose: true, verbose: true
}); });
}, },
methods: { methods: {
@ -42,14 +42,14 @@ export default {
try { try {
this.toolResult = cronstrue.toString(this.toolData.data, { this.toolResult = cronstrue.toString(this.toolData.data, {
use24HourTimeFormat: true, use24HourTimeFormat: true,
verbose: true, verbose: true
}); });
} catch (e) { } catch (e) {
this.toolResult = 'invalid syntax'; this.toolResult = "invalid syntax";
} }
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -15,7 +15,8 @@
<label>Strip mime/type</label> <label>Strip mime/type</label>
<div> <div>
<input id="strip_mime" name="strip_mime" v-model="toolData.stripMime" v-on:change="encode" type="checkbox"> <label for="strip_mime">strip mime</label> <input id="strip_mime" name="strip_mime" v-model="toolData.stripMime" v-on:change="encode" type="checkbox"> <label
for="strip_mime">strip mime</label>
</div> </div>
</div> </div>
@ -23,8 +24,10 @@
<label>Mode</label> <label>Mode</label>
<div> <div>
<input id="base64_mode_encode" value="encode" name="base64_mode" v-model="toolData.base64Mode" type="radio"> <label for="base64_mode_encode">file -> base64</label><br> <input id="base64_mode_encode" value="encode" name="base64_mode" v-model="toolData.base64Mode" type="radio">
<input id="base64_mode_decode" value="decode" name="base64_mode" v-model="toolData.base64Mode" type="radio"> <label for="base64_mode_decode">base64 -> file</label> <label for="base64_mode_encode">file -> base64</label><br>
<input id="base64_mode_decode" value="decode" name="base64_mode" v-model="toolData.base64Mode" type="radio">
<label for="base64_mode_decode">base64 -> file</label>
</div> </div>
</div> </div>
@ -50,11 +53,11 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
base64Mode: 'encode', base64Mode: "encode",
stripMime: true, stripMime: true
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
@ -64,7 +67,7 @@ export default {
reader.onload = () => { reader.onload = () => {
if (this.toolData.stripMime) { if (this.toolData.stripMime) {
this.toolResult = reader.result.split(',')[1]; this.toolResult = reader.result.split(",")[1];
} else { } else {
this.toolResult = reader.result; this.toolResult = reader.result;
} }
@ -75,7 +78,7 @@ export default {
} }
}, },
decode() { decode() {
const byteCharacters = atob(this.toolData.data.split(',')[1] ?? this.toolData.data); const byteCharacters = atob(this.toolData.data.split(",")[1] ?? this.toolData.data);
const byteNumbers = new Array(byteCharacters.length); const byteNumbers = new Array(byteCharacters.length);
// create file // create file
@ -84,16 +87,16 @@ export default {
} }
const byteArray = new Uint8Array(byteNumbers); const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: 'application/octet-stream' }); const blob = new Blob([byteArray], { type: "application/octet-stream" });
// download // download
const link = document.createElement('a'); const link = document.createElement("a");
link.href = URL.createObjectURL(blob); link.href = URL.createObjectURL(blob);
link.download = 'file'; link.download = "file";
link.click(); link.click();
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -11,8 +11,10 @@
<label>Mode</label> <label>Mode</label>
<div> <div>
<input id="keyboard_mode_en_ru" value="en-ru" name="keyboard_mode" v-model="toolData.keyboardMode" v-on:change="result" type="radio"> <label for="keyboard_mode_en_ru">en -> ru</label><br> <input id="keyboard_mode_en_ru" value="en-ru" name="keyboard_mode" v-model="toolData.keyboardMode"
<input id="keyboard_mode_ru_en" value="ru-en" name="keyboard_mode" v-model="toolData.keyboardMode" v-on:change="result" type="radio"> <label for="keyboard_mode_ru_en">ru -> en</label> v-on:change="result" type="radio"> <label for="keyboard_mode_en_ru">en -> ru</label><br>
<input id="keyboard_mode_ru_en" value="ru-en" name="keyboard_mode" v-model="toolData.keyboardMode"
v-on:change="result" type="radio"> <label for="keyboard_mode_ru_en">ru -> en</label>
</div> </div>
</div> </div>
@ -35,22 +37,22 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
keyboardMode: 'en-ru', keyboardMode: "en-ru"
}, },
dictionary: { dictionary: {
'en-ru': '`~!@#$%^&qwertyuiop[]asdfghjkl;\'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>?', "en-ru": "`~!@#$%^&qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?",
'ru-en': 'ёЁ!"№;%:?йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,', "ru-en": "ёЁ!\"№;%:?йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,"
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
let data = unproxy(this.toolData.data).split(''); let data = unproxy(this.toolData.data).split("");
const dict = this.dictionary[this.toolData.keyboardMode]; const dict = this.dictionary[this.toolData.keyboardMode];
const dictOpposite = this.dictionary[this.toolData.keyboardMode === 'en-ru' ? 'ru-en' : 'en-ru']; const dictOpposite = this.dictionary[this.toolData.keyboardMode === "en-ru" ? "ru-en" : "en-ru"];
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
const dictPos = dict.indexOf(data[i]); const dictPos = dict.indexOf(data[i]);
@ -59,10 +61,10 @@ export default {
data[i] = unproxy(dictOpposite[dictPos]); data[i] = unproxy(dictOpposite[dictPos]);
} }
this.toolResult = data.join(''); this.toolResult = data.join("");
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -9,10 +9,12 @@
<div class="input-group"> <div class="input-group">
<div> <div>
<input id="flatten" name="flatten" v-model="toolData.flatten" v-on:change="result" type="checkbox"> <label for="flatten">inline type definitions</label> <input id="flatten" name="flatten" v-model="toolData.flatten" v-on:change="result" type="checkbox"> <label
for="flatten">inline type definitions</label>
</div> </div>
<div> <div>
<input id="omitempty" name="omitempty" v-model="toolData.omitempty" v-on:change="result" type="checkbox"> <label for="omitempty">omitempty</label> <input id="omitempty" name="omitempty" v-model="toolData.omitempty" v-on:change="result" type="checkbox"> <label
for="omitempty">omitempty</label>
</div> </div>
</div> </div>
@ -40,13 +42,10 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
let innerTabs = 0; let innerTabs = 0;
let parent = ""; let parent = "";
try try {
{
data = JSON.parse(json.replace(/(:\s*\[?\s*-?\d*)\.0/g, "$1.1")); // hack that forces floats to stay as floats data = JSON.parse(json.replace(/(:\s*\[?\s*-?\d*)\.0/g, "$1.1")); // hack that forces floats to stay as floats
scope = data; scope = data;
} } catch (e) {
catch (e)
{
return { return {
go: "", go: "",
error: e.message error: e.message
@ -65,22 +64,17 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
}; };
function parseScope(scope, depth = 0) function parseScope(scope, depth = 0) {
{ if (typeof scope === "object" && scope !== null) {
if (typeof scope === "object" && scope !== null) if (Array.isArray(scope)) {
{
if (Array.isArray(scope))
{
let sliceType; let sliceType;
const scopeLength = scope.length; const scopeLength = scope.length;
for (let i = 0; i < scopeLength; i++) for (let i = 0; i < scopeLength; i++) {
{
const thisType = goType(scope[i]); const thisType = goType(scope[i]);
if (!sliceType) if (!sliceType)
sliceType = thisType; sliceType = thisType;
else if (sliceType != thisType) else if (sliceType != thisType) {
{
sliceType = mostSpecificPossibleGoType(thisType, sliceType); sliceType = mostSpecificPossibleGoType(thisType, sliceType);
if (sliceType == "any") if (sliceType == "any")
break; break;
@ -94,24 +88,21 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
if (flatten && depth >= 2) if (flatten && depth >= 2)
appender(slice); appender(slice);
else else
append(slice) append(slice);
if (sliceType == "struct") { if (sliceType == "struct") {
const allFields = {}; const allFields = {};
// for each field counts how many times appears // for each field counts how many times appears
for (let i = 0; i < scopeLength; i++) for (let i = 0; i < scopeLength; i++) {
{ const keys = Object.keys(scope[i]);
const keys = Object.keys(scope[i]) for (let k in keys) {
for (let k in keys)
{
let keyname = keys[k]; let keyname = keys[k];
if (!(keyname in allFields)) { if (!(keyname in allFields)) {
allFields[keyname] = { allFields[keyname] = {
value: scope[i][keyname], value: scope[i][keyname],
count: 0 count: 0
} };
} } else {
else {
const existingValue = allFields[keyname].value; const existingValue = allFields[keyname].value;
const currentValue = scope[i][keyname]; const currentValue = scope[i][keyname];
@ -119,7 +110,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
const comparisonResult = compareObjectKeys( const comparisonResult = compareObjectKeys(
Object.keys(currentValue), Object.keys(currentValue),
Object.keys(existingValue) Object.keys(existingValue)
) );
if (!comparisonResult) { if (!comparisonResult) {
keyname = `${keyname}_${uuidv4()}`; keyname = `${keyname}_${uuidv4()}`;
allFields[keyname] = { allFields[keyname] = {
@ -136,63 +127,53 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
// create a common struct with all fields found in the current array // create a common struct with all fields found in the current array
// omitempty dict indicates if a field is optional // omitempty dict indicates if a field is optional
const keys = Object.keys(allFields), struct = {}, omitempty = {}; const keys = Object.keys(allFields), struct = {}, omitempty = {};
for (let k in keys) for (let k in keys) {
{
const keyname = keys[k], elem = allFields[keyname]; const keyname = keys[k], elem = allFields[keyname];
struct[keyname] = elem.value; struct[keyname] = elem.value;
omitempty[keyname] = elem.count != scopeLength; omitempty[keyname] = elem.count != scopeLength;
} }
parseStruct(depth + 1, innerTabs, struct, omitempty); // finally parse the struct !! parseStruct(depth + 1, innerTabs, struct, omitempty); // finally parse the struct !!
} } else if (sliceType == "slice") {
else if (sliceType == "slice") { parseScope(scope[0], depth);
parseScope(scope[0], depth) } else {
}
else {
if (flatten && depth >= 2) { if (flatten && depth >= 2) {
appender(sliceType || "any"); appender(sliceType || "any");
} else { } else {
append(sliceType || "any"); append(sliceType || "any");
} }
} }
} } else {
else
{
if (flatten) { if (flatten) {
if (depth >= 2){ if (depth >= 2) {
appender(parent) appender(parent);
} } else {
else { append(parent);
append(parent)
} }
} }
parseStruct(depth + 1, innerTabs, scope); parseStruct(depth + 1, innerTabs, scope);
} }
} } else {
else { if (flatten && depth >= 2) {
if (flatten && depth >= 2){
appender(goType(scope)); appender(goType(scope));
} } else {
else {
append(goType(scope)); append(goType(scope));
} }
} }
} }
function parseStruct(depth, innerTabs, scope, omitempty) function parseStruct(depth, innerTabs, scope, omitempty) {
{
if (flatten) { if (flatten) {
stack.push( stack.push(
depth >= 2 depth >= 2
? "\n" ? "\n"
: "" : ""
) );
} }
const seenTypeNames = []; const seenTypeNames = [];
if (flatten && depth >= 2) if (flatten && depth >= 2) {
{
const parentType = `type ${parent}`; const parentType = `type ${parent}`;
const scopeKeys = formatScopeKeys(Object.keys(scope)); const scopeKeys = formatScopeKeys(Object.keys(scope));
@ -201,57 +182,50 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
// three or more duplicate keys with different values // three or more duplicate keys with different values
if (parent in seen && compareObjectKeys(scopeKeys, seen[parent])) { if (parent in seen && compareObjectKeys(scopeKeys, seen[parent])) {
stack.pop(); stack.pop();
return return;
} }
seen[parent] = scopeKeys; seen[parent] = scopeKeys;
appender(`${parentType} struct {\n`); appender(`${parentType} struct {\n`);
++innerTabs; ++innerTabs;
const keys = Object.keys(scope); const keys = Object.keys(scope);
for (let i in keys) for (let i in keys) {
{
const keyname = getOriginalName(keys[i]); const keyname = getOriginalName(keys[i]);
indenter(innerTabs) indenter(innerTabs);
const typename = uniqueTypeName(format(keyname), seenTypeNames) const typename = uniqueTypeName(format(keyname), seenTypeNames);
seenTypeNames.push(typename) seenTypeNames.push(typename);
appender(typename+" "); appender(typename + " ");
parent = typename parent = typename;
parseScope(scope[keys[i]], depth); parseScope(scope[keys[i]], depth);
appender(' `json:"'+keyname); appender(" `json:\"" + keyname);
if (allOmitempty || (omitempty && omitempty[keys[i]] === true)) if (allOmitempty || (omitempty && omitempty[keys[i]] === true)) {
{ appender(",omitempty");
appender(',omitempty');
} }
appender('"`\n'); appender("\"`\n");
} }
indenter(--innerTabs); indenter(--innerTabs);
appender("}"); appender("}");
} } else {
else
{
append("struct {\n"); append("struct {\n");
++tabs; ++tabs;
const keys = Object.keys(scope); const keys = Object.keys(scope);
for (let i in keys) for (let i in keys) {
{
const keyname = getOriginalName(keys[i]); const keyname = getOriginalName(keys[i]);
indent(tabs); indent(tabs);
const typename = uniqueTypeName(format(keyname), seenTypeNames) const typename = uniqueTypeName(format(keyname), seenTypeNames);
seenTypeNames.push(typename) seenTypeNames.push(typename);
append(typename+" "); append(typename + " ");
parent = typename parent = typename;
parseScope(scope[keys[i]], depth); parseScope(scope[keys[i]], depth);
append(' `json:"'+keyname); append(" `json:\"" + keyname);
if (allOmitempty || (omitempty && omitempty[keys[i]] === true)) if (allOmitempty || (omitempty && omitempty[keys[i]] === true)) {
{ append(",omitempty");
append(',omitempty');
} }
if (example && scope[keys[i]] !== "" && typeof scope[keys[i]] !== "object") if (example && scope[keys[i]] !== "" && typeof scope[keys[i]] !== "object") {
{ append("\" example:\"" + scope[keys[i]]);
append('" example:"'+scope[keys[i]])
} }
append('"`\n'); append("\"`\n");
} }
indent(--tabs); indent(--tabs);
append("}"); append("}");
@ -260,25 +234,21 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
accumulator += stack.pop(); accumulator += stack.pop();
} }
function indent(tabs) function indent(tabs) {
{
for (let i = 0; i < tabs; i++) for (let i = 0; i < tabs; i++)
go += '\t'; go += "\t";
} }
function append(str) function append(str) {
{
go += str; go += str;
} }
function indenter(tabs) function indenter(tabs) {
{
for (let i = 0; i < tabs; i++) for (let i = 0; i < tabs; i++)
stack[stack.length - 1] += '\t'; stack[stack.length - 1] += "\t";
} }
function appender(str) function appender(str) {
{
stack[stack.length - 1] += str; stack[stack.length - 1] += str;
} }
@ -301,18 +271,17 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
} }
// Sanitizes and formats a string to make an appropriate identifier in Go // Sanitizes and formats a string to make an appropriate identifier in Go
function format(str) function format(str) {
{
str = formatNumber(str); str = formatNumber(str);
let sanitized = toProperCase(str).replace(/[^a-z0-9]/ig, "") let sanitized = toProperCase(str).replace(/[^a-z0-9]/ig, "");
if (!sanitized) { if (!sanitized) {
return "NAMING_FAILED"; return "NAMING_FAILED";
} }
// After sanitizing the remaining characters can start with a number. // After sanitizing the remaining characters can start with a number.
// Run the sanitized string again trough formatNumber to make sure the identifier is Num[0-9] or Zero_... instead of 1. // Run the sanitized string again trough formatNumber to make sure the identifier is Num[0-9] or Zero_... instead of 1.
return formatNumber(sanitized) return formatNumber(sanitized);
} }
// Adds a prefix to a number to make an appropriate identifier in Go // Adds a prefix to a number to make an appropriate identifier in Go
@ -321,11 +290,12 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
return ""; return "";
else if (str.match(/^\d+$/)) else if (str.match(/^\d+$/))
str = "Num" + str; str = "Num" + str;
else if (str.charAt(0).match(/\d/)) else if (str.charAt(0).match(/\d/)) {
{ const numbers = {
const numbers = {'0': "Zero_", '1': "One_", '2': "Two_", '3': "Three_", "0": "Zero_", "1": "One_", "2": "Two_", "3": "Three_",
'4': "Four_", '5': "Five_", '6': "Six_", '7': "Seven_", "4": "Four_", "5": "Five_", "6": "Six_", "7": "Seven_",
'8': "Eight_", '9': "Nine_"}; "8": "Eight_", "9": "Nine_"
};
str = numbers[str.charAt(0)] + str.substr(1); str = numbers[str.charAt(0)] + str.substr(1);
} }
@ -333,27 +303,23 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
} }
// Determines the most appropriate Go type // Determines the most appropriate Go type
function goType(val) function goType(val) {
{
if (val === null) if (val === null)
return "any"; return "any";
switch (typeof val) switch (typeof val) {
{
case "string": case "string":
if (/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(\+\d\d:\d\d|Z)$/.test(val)) if (/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(\+\d\d:\d\d|Z)$/.test(val))
return "time.Time"; return "time.Time";
else else
return "string"; return "string";
case "number": case "number":
if (val % 1 === 0) if (val % 1 === 0) {
{
if (val > -2147483648 && val < 2147483647) if (val > -2147483648 && val < 2147483647)
return "int"; return "int";
else else
return "int64"; return "int64";
} } else
else
return "float64"; return "float64";
case "boolean": case "boolean":
return "bool"; return "bool";
@ -367,8 +333,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
} }
// Given two types, returns the more specific of the two // Given two types, returns the more specific of the two
function mostSpecificPossibleGoType(typ1, typ2) function mostSpecificPossibleGoType(typ1, typ2) {
{
if (typ1.substr(0, 5) == "float" if (typ1.substr(0, 5) == "float"
&& typ2.substr(0, 3) == "int") && typ2.substr(0, 3) == "int")
return typ1; return typ1;
@ -380,8 +345,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
} }
// Proper cases a string according to Go conventions // Proper cases a string according to Go conventions
function toProperCase(str) function toProperCase(str) {
{
// ensure that the SCREAMING_SNAKE_CASE is converted to snake_case // ensure that the SCREAMING_SNAKE_CASE is converted to snake_case
if (str.match(/^[_A-Z0-9]+$/)) { if (str.match(/^[_A-Z0-9]+$/)) {
str = str.toLowerCase(); str = str.toLowerCase();
@ -395,14 +359,12 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
"URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS"
]; ];
return str.replace(/(^|[^a-zA-Z])([a-z]+)/g, function(unused, sep, frag) return str.replace(/(^|[^a-zA-Z])([a-z]+)/g, function(unused, sep, frag) {
{
if (commonInitialisms.indexOf(frag.toUpperCase()) >= 0) if (commonInitialisms.indexOf(frag.toUpperCase()) >= 0)
return sep + frag.toUpperCase(); return sep + frag.toUpperCase();
else else
return sep + frag[0].toUpperCase() + frag.substr(1).toLowerCase(); return sep + frag[0].toUpperCase() + frag.substr(1).toLowerCase();
}).replace(/([A-Z])([a-z]+)/g, function(unused, sep, frag) }).replace(/([A-Z])([a-z]+)/g, function(unused, sep, frag) {
{
if (commonInitialisms.indexOf(sep + frag.toUpperCase()) >= 0) if (commonInitialisms.indexOf(sep + frag.toUpperCase()) >= 0)
return (sep + frag).toUpperCase(); return (sep + frag).toUpperCase();
else else
@ -411,23 +373,23 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
} }
function uuidv4() { function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); var r = Math.random() * 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8);
return v.toString(16); return v.toString(16);
}); });
} }
function getOriginalName(unique) { 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 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; const uuidLength = 36;
if (unique.length >= uuidLength) { if (unique.length >= uuidLength) {
const tail = unique.substr(-uuidLength); const tail = unique.substr(-uuidLength);
if (reLiteralUUID.test(tail)) { if (reLiteralUUID.test(tail)) {
return unique.slice(0, -1 * (uuidLength + 1)) return unique.slice(0, -1 * (uuidLength + 1));
} }
} }
return unique return unique;
} }
function compareObjects(objectA, objectB) { function compareObjects(objectA, objectB) {
@ -459,7 +421,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
for (let i in keys) { for (let i in keys) {
keys[i] = format(keys[i]); keys[i] = format(keys[i]);
} }
return keys return keys;
} }
} }
@ -470,30 +432,30 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
flatten: false, flatten: false,
omitempty: false, omitempty: false
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
if (!this.toolData.data.length) { if (!this.toolData.data.length) {
this.toolResult = ''; this.toolResult = "";
return; return;
} }
const json = jsonToGo(this.toolData.data, "", this.toolData.flatten, false, this.toolData.omitempty); const json = jsonToGo(this.toolData.data, "", this.toolData.flatten, false, this.toolData.omitempty);
if (json.error?.length) { if (json.error?.length) {
this.toolResult = 'invalid json'; this.toolResult = "invalid json";
return; return;
} }
this.toolResult = json.go; this.toolResult = json.go;
} }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -4,21 +4,24 @@
<div class="input-group"> <div class="input-group">
<label for="result">MariaDB</label> <label for="result">MariaDB</label>
<MonacoEditor name="dialects_mariadb" language="sql" :value="toolData.dialects.mariadb" readonly="true" style="height: 500px"></MonacoEditor> <MonacoEditor name="dialects_mariadb" language="sql" :value="toolData.dialects.mariadb" readonly="true"
style="height: 500px"></MonacoEditor>
</div> </div>
<hr class="mt-5 mb-5"> <hr class="mt-5 mb-5">
<div class="input-group"> <div class="input-group">
<label for="result">PostgreSQL</label> <label for="result">PostgreSQL</label>
<MonacoEditor name="dialects_postgresql" language="sql" :value="toolData.dialects.postgresql" readonly="true" style="height: 500px"></MonacoEditor> <MonacoEditor name="dialects_postgresql" language="sql" :value="toolData.dialects.postgresql" readonly="true"
style="height: 500px"></MonacoEditor>
</div> </div>
<hr class="mt-5 mb-5"> <hr class="mt-5 mb-5">
<div class="input-group"> <div class="input-group">
<label for="result">OracleSQL</label> <label for="result">OracleSQL</label>
<MonacoEditor name="dialects_oraclesql" language="sql" :value="toolData.dialects.oraclesql" readonly="true" style="height: 500px"></MonacoEditor> <MonacoEditor name="dialects_oraclesql" language="sql" :value="toolData.dialects.oraclesql" readonly="true"
style="height: 500px"></MonacoEditor>
</div> </div>
</template> </template>
@ -33,123 +36,113 @@ export default {
return { return {
toolData: { toolData: {
dialects: { dialects: {
mariadb: `WITH models AS ( mariadb: `WITH models AS (WITH data AS (SELECT REPLACE(CONCAT(UPPER(SUBSTRING(table_name, 1, 1)),
WITH data AS ( LOWER(SUBSTRING(table_name, 2))), '_',
SELECT '') AS table_name,
REPLACE(CONCAT(UPPER(SUBSTRING(table_name, 1, 1)), LOWER(SUBSTRING(table_name, 2))), '_', '') AS table_name, REPLACE(CONCAT(UPPER(SUBSTRING(column_name, 1, 1)),
REPLACE(CONCAT(UPPER(SUBSTRING(column_name, 1, 1)), LOWER(SUBSTRING(column_name, 2))), '_', '') AS column_name, LOWER(SUBSTRING(column_name, 2))), '_',
CASE data_type '') AS column_name,
WHEN 'timestamp' THEN 'time.Time' CASE data_type
WHEN 'tinyint(1)' THEN 'bool' WHEN 'timestamp' THEN 'time.Time'
WHEN 'bigint' THEN 'int64' WHEN 'tinyint(1)' THEN 'bool'
WHEN 'int' THEN 'int' WHEN 'bigint' THEN 'int64'
WHEN 'tinyint' THEN 'int8' WHEN 'int' THEN 'int'
WHEN 'double' THEN 'float64' WHEN 'tinyint' THEN 'int8'
WHEN 'decimal' THEN 'float32' WHEN 'double' THEN 'float64'
WHEN 'date' THEN 'time.Time' WHEN 'decimal' THEN 'float32'
WHEN 'char' THEN 'string' WHEN 'date' THEN 'time.Time'
WHEN 'varchar' THEN 'string' WHEN 'char' THEN 'string'
WHEN 'text' THEN 'string' WHEN 'varchar' THEN 'string'
WHEN 'mediumtext' THEN 'string' WHEN 'text' THEN 'string'
WHEN 'longtext' THEN 'string' WHEN 'mediumtext' THEN 'string'
WHEN 'enum' THEN 'string' WHEN 'longtext' THEN 'string'
-- add your own type converters as needed or it will default to 'string' WHEN 'enum' THEN 'string'
ELSE CONCAT("UNKNOWN_", data_type) -- add your own type converters as needed or it will default to 'string'
END AS type_info, ELSE CONCAT("UNKNOWN_", data_type)
CONCAT('\`json:"', column_name, '"\`') AS annotation END AS type_info,
FROM information_schema.columns CONCAT('\`json:"', column_name, '"\`') AS annotation
WHERE table_schema IN ('work-euroline.local') FROM information_schema.columns
ORDER BY table_schema, table_name, ordinal_position WHERE table_schema IN ('work-euroline.local')
) ORDER BY table_schema, table_name, ordinal_position)
SELECT table_name, GROUP_CONCAT(CONCAT('\\t', column_name, '\\t', type_info, '\\t', annotation) SEPARATOR '\\n') AS fields SELECT table_name,
FROM data GROUP_CONCAT(CONCAT('\\t', column_name, '\\t', type_info, '\\t', annotation) SEPARATOR '\\n') AS fields
GROUP BY table_name FROM data
) GROUP BY table_name)
SELECT CONCAT('type ', table_name, ' struct {\\n', fields, '\\n}') AS models SELECT CONCAT('type ', table_name, ' struct {\\n', fields, '\\n}') AS models
FROM models FROM models
ORDER BY table_name`, ORDER BY table_name`,
postgresql: `WITH models AS ( postgresql: `WITH models AS (WITH data AS (SELECT replace(initcap(table_name::text), '_', '') table_name,
WITH data AS ( replace(initcap(column_name::text), '_', '') column_name,
SELECT CASE data_type
replace(initcap(table_name::text), '_', '') table_name, WHEN 'timestamp without time zone' THEN 'time.Time'
replace(initcap(column_name::text), '_', '') column_name, WHEN 'timestamp with time zone' THEN 'time.Time'
CASE data_type WHEN 'boolean' THEN 'bool'
WHEN 'timestamp without time zone' THEN 'time.Time' WHEN 'bigint' THEN 'int64'
WHEN 'timestamp with time zone' THEN 'time.Time' WHEN 'integer' THEN 'int'
WHEN 'boolean' THEN 'bool' WHEN 'ARRAY' THEN 'pgtype.Array[string]'
WHEN 'bigint' THEN 'int64' WHEN 'date' THEN 'pgtype.Date'
WHEN 'integer' THEN 'int' WHEN 'character varying' THEN 'string'
WHEN 'ARRAY' THEN 'pgtype.Array[string]' -- add your own type converters as needed or it will default to 'string'
WHEN 'date' THEN 'pgtype.Date' ELSE 'UNKNOWN'
WHEN 'character varying' THEN 'string' END AS type_info,
-- add your own type converters as needed or it will default to 'string' '\`json:"' || column_name || '"\`' AS annotation
ELSE 'UNKNOWN' FROM information_schema.columns
END AS type_info, WHERE table_schema IN ('public')
'\`json:"' || column_name ||'"\`' AS annotation ORDER BY table_schema, table_name, ordinal_position)
FROM information_schema.columns SELECT table_name, STRING_AGG(E'\\t' || column_name || E'\\t' || type_info || E'\\t' || annotation, E '\\n') fields
WHERE table_schema IN ('public') FROM data
ORDER BY table_schema, table_name, ordinal_position GROUP BY table_name)
) SELECT 'type ' || table_name || E ' struct {\\n' || fields || E'\\n}' models
SELECT table_name, STRING_AGG(E'\\t' || column_name || E'\\t' || type_info || E'\\t' || annotation, E'\\n') fields FROM models
FROM data ORDER BY table_name`,
GROUP BY table_name oraclesql: `SELECT 'type ' || table_name || ' struct {' || CHR(10) || fields || CHR(10) || '}' AS models
) FROM (SELECT table_name,
SELECT 'type ' || table_name || E' struct {\\n' || fields || E'\\n}' models REPLACE(RTRIM(XMLAGG(XMLELEMENT(E, CHR(9) || column_name || CHR(9) || type_info ||
FROM models ORDER BY table_name`, CHR(9) || annotation ||
oraclesql: `SELECT CHR(10))).EXTRACT('//text()').GETCLOBVAL(),
'type ' || table_name || ' struct {' || CHR(10) || fields || CHR(10) || '}' AS models CHR(10)), '&quot;', '"') AS fields
FROM FROM (SELECT REPLACE(INITCAP(table_name), '_', '') AS table_name,
( REPLACE(INITCAP(column_name), '_', '') AS column_name,
SELECT CASE data_type
table_name, WHEN 'TIMESTAMP' THEN 'time.Time'
REPLACE(RTRIM(XMLAGG(XMLELEMENT(E, CHR(9) || column_name || CHR(9) || type_info || CHR(9) || annotation || CHR(10))).EXTRACT('//text()').GETCLOBVAL(), CHR(10)), '&quot;', '"') AS fields WHEN 'TIMESTAMP(6)' THEN 'time.Time'
FROM WHEN 'TIMESTAMP WITH TIME ZONE' THEN 'time.Time'
( WHEN 'TIMESTAMP WITH LOCAL TIME ZONE' THEN 'time.Time'
SELECT WHEN 'LONG' THEN 'int64'
REPLACE(INITCAP(table_name), '_', '') AS table_name, WHEN 'NUMBER' THEN
REPLACE(INITCAP(column_name), '_', '') AS column_name, CASE
CASE data_type WHEN data_precision IS NULL AND data_scale = 0 THEN 'int'
WHEN 'TIMESTAMP' THEN 'time.Time' WHEN data_precision IS NOT NULL AND data_scale = 0 THEN 'int64'
WHEN 'TIMESTAMP(6)' THEN 'time.Time' ELSE 'float64'
WHEN 'TIMESTAMP WITH TIME ZONE' THEN 'time.Time' END
WHEN 'TIMESTAMP WITH LOCAL TIME ZONE' THEN 'time.Time' WHEN 'FLOAT' THEN 'float32'
WHEN 'LONG' THEN 'int64' WHEN 'BINARY_FLOAT' THEN 'float32'
WHEN 'NUMBER' THEN WHEN 'BINARY_DOUBLE' THEN 'float64'
CASE WHEN 'CHAR' THEN 'string'
WHEN data_precision IS NULL AND data_scale = 0 THEN 'int' WHEN 'VARCHAR2' THEN 'sql.NullString'
WHEN data_precision IS NOT NULL AND data_scale = 0 THEN 'int64' WHEN 'NCHAR' THEN 'string'
ELSE 'float64' WHEN 'NVARCHAR2' THEN 'string'
END WHEN 'CLOB' THEN 'go_ora.Clob'
WHEN 'FLOAT' THEN 'float32' WHEN 'NCLOB' THEN 'go_ora.Nlob'
WHEN 'BINARY_FLOAT' THEN 'float32' WHEN 'BLOB' THEN 'go_ora.Blob'
WHEN 'BINARY_DOUBLE' THEN 'float64' WHEN 'DATE' THEN 'go_ora.NullTimeStamp'
WHEN 'CHAR' THEN 'string' WHEN 'RAW' THEN '[]byte'
WHEN 'VARCHAR2' THEN 'sql.NullString' WHEN 'UNDEFINED' THEN 'database.OraUNDEFINED'
WHEN 'NCHAR' THEN 'string' -- add your own type converters as needed or it will default to 'string'
WHEN 'NVARCHAR2' THEN 'string' ELSE 'UNKNOWN'
WHEN 'CLOB' THEN 'go_ora.Clob' END AS type_info,
WHEN 'NCLOB' THEN 'go_ora.Nlob' '\`json:"' || column_name || '" db:"' || column_name || '"\`' AS annotation
WHEN 'BLOB' THEN 'go_ora.Blob' FROM all_tab_columns
WHEN 'DATE' THEN 'go_ora.NullTimeStamp' WHERE owner = 'DELOPRO')
WHEN 'RAW' THEN '[]byte' --WHERE type_info = 'UNKNOWN'
WHEN 'UNDEFINED' THEN 'database.OraUNDEFINED' GROUP BY table_name)
-- add your own type converters as needed or it will default to 'string'
ELSE 'UNKNOWN'
END AS type_info,
'\`json:"' || column_name || '" db:"' || column_name || '"\`' AS annotation
FROM all_tab_columns
WHERE owner = 'DELOPRO'
)
--WHERE type_info = 'UNKNOWN'
GROUP BY table_name
)
--WHERE table_name = 'V8EventVw' --WHERE table_name = 'V8EventVw'
ORDER BY table_name`, ORDER BY table_name`
} }
}, }
}; };
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -1,5 +1,5 @@
<template> <template>
/home /home
</template> </template>
<style lang="scss"> <style lang="scss">

@ -3,7 +3,9 @@
<hr class="mt-5 mb-5"> <hr class="mt-5 mb-5">
<div class="input-group"> <div class="input-group">
<label>Team <button @click="addTeamGroup"></button></label> <label>Team
<button @click="addTeamGroup"></button>
</label>
<div class="humans-group" v-for="(group, groupIndex) in toolData.team" :key="groupIndex"> <div class="humans-group" v-for="(group, groupIndex) in toolData.team" :key="groupIndex">
<div v-for="(field, fieldIndex) in group" :key="fieldIndex"> <div v-for="(field, fieldIndex) in group" :key="fieldIndex">
<input class="input" v-model="field.key" v-on:keyup="result" placeholder="Key" type="text"> <input class="input" v-model="field.key" v-on:keyup="result" placeholder="Key" type="text">
@ -23,7 +25,9 @@
<hr class="mt-5 mb-5"> <hr class="mt-5 mb-5">
<div class="input-group"> <div class="input-group">
<label>Thanks <button @click="addThanksGroup"></button></label> <label>Thanks
<button @click="addThanksGroup"></button>
</label>
<div class="humans-group" v-for="(group, groupIndex) in toolData.thanks" :key="groupIndex"> <div class="humans-group" v-for="(group, groupIndex) in toolData.thanks" :key="groupIndex">
<div v-for="(field, fieldIndex) in group" :key="fieldIndex"> <div v-for="(field, fieldIndex) in group" :key="fieldIndex">
<input class="input" v-model="field.key" v-on:keyup="result" placeholder="Key" type="text"> <input class="input" v-model="field.key" v-on:keyup="result" placeholder="Key" type="text">
@ -43,7 +47,9 @@
<hr class="mt-5 mb-5"> <hr class="mt-5 mb-5">
<div class="input-group"> <div class="input-group">
<label>Site info <button @click="addSite"></button></label> <label>Site info
<button @click="addSite"></button>
</label>
<div v-for="(info, fieldIndex) in toolData.site" :key="fieldIndex"> <div v-for="(info, fieldIndex) in toolData.site" :key="fieldIndex">
<input class="input" v-model="info.key" v-on:keyup="result" placeholder="Key" type="text"> <input class="input" v-model="info.key" v-on:keyup="result" placeholder="Key" type="text">
<input class="input" v-model="info.value" v-on:keyup="result" placeholder="Value" type="text"> <input class="input" v-model="info.value" v-on:keyup="result" placeholder="Value" type="text">
@ -56,7 +62,9 @@
<hr class="mt-5 mb-5"> <hr class="mt-5 mb-5">
<div class="input-group"> <div class="input-group">
<label>Import humans.txt <button @click="importHumans">Import</button></label> <label>Import humans.txt
<button @click="importHumans">Import</button>
</label>
<textarea v-model="toolData.importedHumansTxt" style="height: 250px"></textarea> <textarea v-model="toolData.importedHumansTxt" style="height: 250px"></textarea>
</div> </div>
@ -80,20 +88,20 @@ export default {
toolData: { toolData: {
team: [ team: [
[ [
{ key: '', value: '' } { key: "", value: "" }
] ]
], ],
thanks: [ thanks: [
[ [
{ key: '', value: '' } { key: "", value: "" }
] ]
], ],
site: [ site: [
{ key: '', value: '' } { key: "", value: "" }
], ],
importedHumansTxt: '' importedHumansTxt: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
mounted() { mounted() {
@ -105,16 +113,16 @@ export default {
* Team * Team
*/ */
addTeamGroup() { addTeamGroup() {
this.toolData.team.push([{ key: '', value: '' }]); this.toolData.team.push([{ key: "", value: "" }]);
}, },
addTeamField(groupIndex) { addTeamField(groupIndex) {
this.toolData.team[groupIndex].push({ key: '', value: '' }); this.toolData.team[groupIndex].push({ key: "", value: "" });
}, },
removeTeamField(groupIndex, fieldIndex) { removeTeamField(groupIndex, fieldIndex) {
this.toolData.team[groupIndex].splice(fieldIndex, 1); this.toolData.team[groupIndex].splice(fieldIndex, 1);
if (this.toolData.team[groupIndex].length == 0) { if (this.toolData.team[groupIndex].length == 0) {
this.removeTeamGroup(groupIndex) this.removeTeamGroup(groupIndex);
} }
this.result(); this.result();
@ -164,16 +172,16 @@ export default {
* Thank * Thank
*/ */
addThanksGroup() { addThanksGroup() {
this.toolData.thanks.push([{ key: '', value: '' }]); this.toolData.thanks.push([{ key: "", value: "" }]);
}, },
addThanksField(groupIndex) { addThanksField(groupIndex) {
this.toolData.thanks[groupIndex].push({ key: '', value: '' }); this.toolData.thanks[groupIndex].push({ key: "", value: "" });
}, },
removeThanksField(groupIndex, fieldIndex) { removeThanksField(groupIndex, fieldIndex) {
this.toolData.thanks[groupIndex].splice(fieldIndex, 1); this.toolData.thanks[groupIndex].splice(fieldIndex, 1);
if (this.toolData.thanks[groupIndex].length == 0) { if (this.toolData.thanks[groupIndex].length == 0) {
this.removeThanksGroup(groupIndex) this.removeThanksGroup(groupIndex);
} }
this.result(); this.result();
@ -222,7 +230,7 @@ export default {
* Site * Site
*/ */
addSite() { addSite() {
this.toolData.site.push({ label: '', value: '' }); this.toolData.site.push({ label: "", value: "" });
}, },
removeSiteField(fieldIndex) { removeSiteField(fieldIndex) {
this.toolData.site.splice(fieldIndex, 1); this.toolData.site.splice(fieldIndex, 1);
@ -252,7 +260,7 @@ export default {
* Import * Import
*/ */
importHumans() { importHumans() {
const lines = this.toolData.importedHumansTxt.split('\n'); const lines = this.toolData.importedHumansTxt.split("\n");
let currentSection = null; let currentSection = null;
this.toolData.team = []; this.toolData.team = [];
@ -262,29 +270,29 @@ export default {
let currentGroup = []; let currentGroup = [];
for (const line of lines) { for (const line of lines) {
if (line.toLowerCase().startsWith('/* TEAM */'.toLowerCase())) { if (line.toLowerCase().startsWith("/* TEAM */".toLowerCase())) {
currentSection = 'team'; currentSection = "team";
} else if (line.toLowerCase().startsWith('/* THANKS */'.toLowerCase())) { } else if (line.toLowerCase().startsWith("/* THANKS */".toLowerCase())) {
currentSection = 'thanks'; currentSection = "thanks";
} else if (line.toLowerCase().startsWith('/* SITE */'.toLowerCase())) { } else if (line.toLowerCase().startsWith("/* SITE */".toLowerCase())) {
currentSection = 'site'; currentSection = "site";
} else if (line.trim() !== '') { } else if (line.trim() !== "") {
if (currentSection === 'team') { if (currentSection === "team") {
const [key, value] = line.split(':'); const [key, value] = line.split(":");
currentGroup.push({ key: key.trim(), value: value.trim() }); currentGroup.push({ key: key.trim(), value: value.trim() });
} else if (currentSection === 'thanks') { } else if (currentSection === "thanks") {
const [key, value] = line.split(':'); const [key, value] = line.split(":");
currentGroup.push({ key: key.trim(), value: value.trim() }); currentGroup.push({ key: key.trim(), value: value.trim() });
} else if (currentSection === 'site') { } else if (currentSection === "site") {
const [key, value] = line.split(':'); const [key, value] = line.split(":");
this.toolData.site.push({ key: key.trim(), value: value.trim() }); this.toolData.site.push({ key: key.trim(), value: value.trim() });
} }
} else if (line.trim() === '' && currentSection === 'team') { } else if (line.trim() === "" && currentSection === "team") {
if (currentGroup.length > 0) { if (currentGroup.length > 0) {
this.toolData.team.push(currentGroup); this.toolData.team.push(currentGroup);
currentGroup = []; currentGroup = [];
} }
} else if (line.trim() === '' && currentSection === 'thanks') { } else if (line.trim() === "" && currentSection === "thanks") {
if (currentGroup.length > 0) { if (currentGroup.length > 0) {
this.toolData.thanks.push(currentGroup); this.toolData.thanks.push(currentGroup);
currentGroup = []; currentGroup = [];
@ -301,63 +309,63 @@ export default {
* Generate * Generate
*/ */
result() { result() {
let output = ''; let output = "";
if (this.toolData.team.length) { if (this.toolData.team.length) {
output += '/* TEAM */\n'; output += "/* TEAM */\n";
for (const group of this.toolData.team) { for (const group of this.toolData.team) {
let groupOutput = ''; let groupOutput = "";
for (const field of group) { for (const field of group) {
if (field.key.trim() !== '' && field.value.trim() !== '') { if (field.key.trim() !== "" && field.value.trim() !== "") {
groupOutput += `\t${field.key.trim()}: ${field.value.trim()}\n`; groupOutput += `\t${field.key.trim()}: ${field.value.trim()}\n`;
} }
} }
if (groupOutput !== '') { if (groupOutput !== "") {
output += groupOutput + '\n'; output += groupOutput + "\n";
} }
} }
} }
if (this.toolData.thanks.length) { if (this.toolData.thanks.length) {
output += '/* THANKS */\n'; output += "/* THANKS */\n";
for (const group of this.toolData.thanks) { for (const group of this.toolData.thanks) {
let groupOutput = ''; let groupOutput = "";
for (const field of group) { for (const field of group) {
if (field.key.trim() !== '' && field.value.trim() !== '') { if (field.key.trim() !== "" && field.value.trim() !== "") {
groupOutput += `\t${field.key.trim()}: ${field.value.trim()}\n`; groupOutput += `\t${field.key.trim()}: ${field.value.trim()}\n`;
} }
} }
if (groupOutput !== '') { if (groupOutput !== "") {
output += groupOutput + '\n'; output += groupOutput + "\n";
} }
} }
} }
if (this.toolData.site.length) { if (this.toolData.site.length) {
output += '/* SITE */\n'; output += "/* SITE */\n";
for (const info of this.toolData.site) { for (const info of this.toolData.site) {
if (info.key.trim() !== '' && info.value.trim() !== '') { if (info.key.trim() !== "" && info.value.trim() !== "") {
output += `\t${info.key.trim()}: ${info.value.trim()}\n`; output += `\t${info.key.trim()}: ${info.value.trim()}\n`;
} }
} }
} }
this.toolResult = output; this.toolResult = output;
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">
.humans-group { .humans-group {
padding: 10px 0; padding: 10px 0;
} }
.humans-group:nth-child(odd) { .humans-group:nth-child(odd) {
background-color: #f7f7f7; background-color: #f7f7f7;
} }
</style> </style>

@ -25,25 +25,25 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
if (!this.toolData.data.length) { if (!this.toolData.data.length) {
this.toolResult = ''; this.toolResult = "";
} else { } else {
try { try {
this.toolResult = JSON.stringify(JSON.parse(this.toolData.data), null, 4); this.toolResult = JSON.stringify(JSON.parse(this.toolData.data), null, 4);
} catch (e) { } catch (e) {
this.toolResult = 'invalid syntax'; this.toolResult = "invalid syntax";
} }
} }
} }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -25,25 +25,25 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
minify() { minify() {
if (!this.toolData.data.length) { if (!this.toolData.data.length) {
this.toolResult = ''; this.toolResult = "";
} else { } else {
try { try {
this.toolResult = JSON.stringify(JSON.parse(this.toolData.data)); this.toolResult = JSON.stringify(JSON.parse(this.toolData.data));
} catch (e) { } catch (e) {
this.toolResult = 'invalid syntax'; this.toolResult = "invalid syntax";
} }
} }
} }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -9,7 +9,8 @@
<div class="input-group"> <div class="input-group">
<div> <div>
<input id="minify_json" name="minify_json" v-model="toolData.minifyJson" v-on:change="result" type="checkbox"> <label for="minify_json">minify json</label> <input id="minify_json" name="minify_json" v-model="toolData.minifyJson" v-on:change="result" type="checkbox">
<label for="minify_json">minify json</label>
</div> </div>
</div> </div>
@ -22,8 +23,8 @@
</template> </template>
<script> <script>
import axios from 'axios' import axios from "axios";
import { config } from '../../config'; import { config } from "../../config";
import MonacoEditor from "@/components/MonacoEditor.vue"; import MonacoEditor from "@/components/MonacoEditor.vue";
export default { export default {
@ -33,17 +34,17 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
minifyJson: '', minifyJson: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
axios.post(`${config.APP_URL}/api/php/php_array_to_json.php`, { axios.post(`${config.APP_URL}/api/php/php_array_to_json.php`, {
data: this.toolData.data, data: this.toolData.data,
minify_json: this.toolData.minifyJson ? true : false, minify_json: this.toolData.minifyJson ? true : false
}) })
.then((response) => { .then((response) => {
this.toolResult = response.data.data; this.toolResult = response.data.data;
@ -52,7 +53,7 @@ export default {
}); });
} }
} }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -11,8 +11,10 @@
<label for="data_delimiter">Mode</label> <label for="data_delimiter">Mode</label>
<div> <div>
<input id="mode_serialize" value="serialize" name="mode" v-model="toolData.mode" v-on:change="result" type="radio"> <label for="mode_serialize">serialize</label><br> <input id="mode_serialize" value="serialize" name="mode" v-model="toolData.mode" v-on:change="result"
<input id="mode_unserialize" value="unserialize" name="mode" v-model="toolData.mode" v-on:change="result" type="radio"> <label for="mode_unserialize">unserialize</label><br> type="radio"> <label for="mode_serialize">serialize</label><br>
<input id="mode_unserialize" value="unserialize" name="mode" v-model="toolData.mode" v-on:change="result"
type="radio"> <label for="mode_unserialize">unserialize</label><br>
</div> </div>
</div> </div>
@ -25,8 +27,8 @@
</template> </template>
<script> <script>
import axios from 'axios' import axios from "axios";
import { config } from '../../config'; import { config } from "../../config";
import MonacoEditor from "@/components/MonacoEditor.vue"; import MonacoEditor from "@/components/MonacoEditor.vue";
export default { export default {
@ -36,17 +38,17 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
mode: 'serialize', mode: "serialize"
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
axios.post(`${config.APP_URL}/api/php/php_serialize.php`, { axios.post(`${config.APP_URL}/api/php/php_serialize.php`, {
data: this.toolData.data, data: this.toolData.data,
mode: this.toolData.mode, mode: this.toolData.mode
}) })
.then((response) => { .then((response) => {
this.toolResult = response.data; this.toolResult = response.data;
@ -55,7 +57,7 @@ export default {
}); });
} }
} }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -21,7 +21,8 @@
<div class="input-group"> <div class="input-group">
<label for="height">White border:</label> <label for="height">White border:</label>
<input id="quietZone" v-model.number="toolData.options.quietZone" v-on:change="result" v-on:keyup="result" type="number"> <input id="quietZone" v-model.number="toolData.options.quietZone" v-on:change="result" v-on:keyup="result"
type="number">
</div> </div>
<div class="input-group"> <div class="input-group">
@ -49,14 +50,16 @@
<div class="input-group"> <div class="input-group">
<label for="backgroundImageUpload">Background Image Upload:</label> <label for="backgroundImageUpload">Background Image Upload:</label>
<div> <div>
<input type="file" id="backgroundImageUpload" ref="backgroundImageUpload" @change="handleBackgroundImageUpload" accept="image/*"> <input type="file" id="backgroundImageUpload" ref="backgroundImageUpload" @change="handleBackgroundImageUpload"
accept="image/*">
<button @click="removeBackgroundImage">🞩</button> <button @click="removeBackgroundImage">🞩</button>
</div> </div>
</div> </div>
<div class="input-group"> <div class="input-group">
<label for="backgroundImageAlpha">Background Image Alpha:</label> <label for="backgroundImageAlpha">Background Image Alpha:</label>
<input id="backgroundImageAlpha" v-model.number="toolData.options.backgroundImageAlpha" step="0.1" min="0" max="1" v-on:change="result" v-on:keyup="result" type="number"> <input id="backgroundImageAlpha" v-model.number="toolData.options.backgroundImageAlpha" step="0.1" min="0" max="1"
v-on:change="result" v-on:keyup="result" type="number">
</div> </div>
<!-- <!--
@ -78,7 +81,7 @@
</select> </select>
</div> </div>
</div> </div>
<hr class="mt-5 mb-5"> <hr class="mt-5 mb-5">
<div class="input-group"> <div class="input-group">
@ -89,7 +92,7 @@
</template> </template>
<script> <script>
import QRCode from 'easyqrcodejs'; import QRCode from "easyqrcodejs";
import { unproxy } from "../utils/unproxy"; import { unproxy } from "../utils/unproxy";
export default { export default {
@ -97,39 +100,39 @@ export default {
return { return {
toolData: { toolData: {
options: { options: {
text: '', text: "",
width: 256, width: 256,
height: 256, height: 256,
correctLevel: 'L', correctLevel: "L",
logo: '', logo: "",
quietZone: 10, quietZone: 10,
logoBackgroundTransparent: true, logoBackgroundTransparent: true,
backgroundImage: '', backgroundImage: "",
backgroundImageAlpha: 1, backgroundImageAlpha: 1,
autoColor: true, autoColor: true,
drawer: 'canvas', drawer: "canvas"
}, }
}, }
}; };
}, },
mounted() { mounted() {
this.toolData.options.text = ' '; this.toolData.options.text = " ";
this.result(); this.result();
this.toolData.options.text = ''; this.toolData.options.text = "";
}, },
methods: { methods: {
result() { result() {
// Clear previous QR code // Clear previous QR code
this.$refs.qrcodeContainer.innerHTML = ''; this.$refs.qrcodeContainer.innerHTML = "";
let options = unproxy(this.toolData.options); let options = unproxy(this.toolData.options);
// convert correction levels // convert correction levels
options.correctLevel = { options.correctLevel = {
'L': QRCode.CorrectLevel.L, "L": QRCode.CorrectLevel.L,
'M': QRCode.CorrectLevel.M, "M": QRCode.CorrectLevel.M,
'Q': QRCode.CorrectLevel.Q, "Q": QRCode.CorrectLevel.Q,
'H': QRCode.CorrectLevel.H, "H": QRCode.CorrectLevel.H
}[options.correctLevel]; }[options.correctLevel];
console.log(options.correctLevel); console.log(options.correctLevel);
@ -162,15 +165,15 @@ export default {
}, },
removeLogo() { removeLogo() {
this.toolData.options.logo = ''; this.toolData.options.logo = "";
this.result(); this.result();
}, },
removeBackgroundImage() { removeBackgroundImage() {
this.toolData.options.backgroundImage = ''; this.toolData.options.backgroundImage = "";
this.result(); this.result();
}, }
} }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -16,7 +16,7 @@
</template> </template>
<script> <script>
import { format } from 'sql-formatter'; import { format } from "sql-formatter";
import MonacoEditor from "@/components/MonacoEditor.vue"; import MonacoEditor from "@/components/MonacoEditor.vue";
export default { export default {
@ -26,38 +26,38 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
minifyJson: '', minifyJson: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
try { try {
this.toolResult = format(this.toolData.data, { this.toolResult = format(this.toolData.data, {
language: 'sql', language: "sql",
tabWidth: 4, tabWidth: 4,
keywordCase: 'upper', keywordCase: "upper",
functionCase: 'upper', functionCase: "upper",
identifierCase: 'lower', identifierCase: "lower",
linesBetweenQueries: 1, linesBetweenQueries: 1,
paramTypes: { paramTypes: {
custom: [ custom: [
{ regex: String.raw`\{\$?[\w\d\->\[\]]+\}` }, { regex: String.raw`\{\$?[\w\d\->\[\]]+\}` },
{ regex: String.raw`\$[\w\d\->\[\]]+` }, { regex: String.raw`\$[\w\d\->\[\]]+` },
{ regex: String.raw`['"].*['"]` }, { regex: String.raw`['"].*['"]` }
], ],
positional: true, positional: true,
named: [':', '@'], named: [":", "@"]
}, }
}); });
} catch (e) { } catch (e) {
this.toolResult = 'invalid syntax'; this.toolResult = "invalid syntax";
} }
} }
} }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -21,9 +21,12 @@
<label>Wrap in quotes</label> <label>Wrap in quotes</label>
<div> <div>
<input id="wrap_in_quotes_no" value="" name="wrap_in_quotes" v-model="toolData.wrapInQuotes" v-on:change="result" type="radio"> <label for="wrap_in_quotes_no">No</label><br> <input id="wrap_in_quotes_no" value="" name="wrap_in_quotes" v-model="toolData.wrapInQuotes" v-on:change="result"
<input id="wrap_in_quotes_single" value="single" name="wrap_in_quotes" v-model="toolData.wrapInQuotes" v-on:change="result" type="radio"> <label for="wrap_in_quotes_single">Single</label><br> type="radio"> <label for="wrap_in_quotes_no">No</label><br>
<input id="wrap_in_quotes_double" value="double" name="wrap_in_quotes" v-model="toolData.wrapInQuotes" v-on:change="result" type="radio"> <label for="wrap_in_quotes_double">Double</label> <input id="wrap_in_quotes_single" value="single" name="wrap_in_quotes" v-model="toolData.wrapInQuotes"
v-on:change="result" type="radio"> <label for="wrap_in_quotes_single">Single</label><br>
<input id="wrap_in_quotes_double" value="double" name="wrap_in_quotes" v-model="toolData.wrapInQuotes"
v-on:change="result" type="radio"> <label for="wrap_in_quotes_double">Double</label>
</div> </div>
</div> </div>
@ -59,29 +62,29 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
fieldName: '', fieldName: "",
data: '', data: "",
dataDelimiter: '', dataDelimiter: "",
wrapInQuotes: '', wrapInQuotes: "",
chunkBy: 900, chunkBy: 900
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
let data = this.toolData.data let data = this.toolData.data
.split(this.toolData.dataDelimiter ? this.toolData.dataDelimiter : '\n'); .split(this.toolData.dataDelimiter ? this.toolData.dataDelimiter : "\n");
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
let value = data[i]; let value = data[i];
switch (this.toolData.wrapInQuotes) { switch (this.toolData.wrapInQuotes) {
case 'single': case "single":
value = "'" + value.replace("'", "\\'") + "'"; value = "'" + value.replace("'", "\\'") + "'";
break; break;
case 'double': case "double":
value = '"' + value.replace('"', '\\"') + '"'; value = "\"" + value.replace("\"", "\\\"") + "\"";
break; break;
} }
@ -94,13 +97,13 @@ export default {
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
let chunk = data[i]; let chunk = data[i];
data[i] = '(' + chunk.join(',') + ')'; data[i] = "(" + chunk.join(",") + ")";
} }
this.toolResult = '(' + this.toolData.fieldName + ' IN ' + data.join(' OR ' + this.toolData.fieldName + ' IN ') + ')'; this.toolResult = "(" + this.toolData.fieldName + " IN " + data.join(" OR " + this.toolData.fieldName + " IN ") + ")";
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -12,9 +12,13 @@
<input id="data_delimiter" v-model="toolData.dataDelimiter" v-on:keyup="result" placeholder="," type="text"> <input id="data_delimiter" v-model="toolData.dataDelimiter" v-on:keyup="result" placeholder="," type="text">
<div> <div>
<input id="count_mode_characters" value="characters" name="count_mode" v-model="toolData.countMode" v-on:change="result" :disabled="toolData.dataDelimiter.length" type="radio"> <label for="count_mode_characters">characters</label><br> <input id="count_mode_characters" value="characters" name="count_mode" v-model="toolData.countMode"
<input id="count_mode_words" value="words" name="count_mode" v-model="toolData.countMode" v-on:change="result" :disabled="toolData.dataDelimiter.length" type="radio"> <label for="count_mode_words">words</label><br> v-on:change="result" :disabled="toolData.dataDelimiter.length" type="radio"> <label
<input id="count_mode_lines" value="lines" name="count_mode" v-model="toolData.countMode" v-on:change="result" :disabled="toolData.dataDelimiter.length" type="radio"> <label for="count_mode_lines">lines</label> for="count_mode_characters">characters</label><br>
<input id="count_mode_words" value="words" name="count_mode" v-model="toolData.countMode" v-on:change="result"
:disabled="toolData.dataDelimiter.length" type="radio"> <label for="count_mode_words">words</label><br>
<input id="count_mode_lines" value="lines" name="count_mode" v-model="toolData.countMode" v-on:change="result"
:disabled="toolData.dataDelimiter.length" type="radio"> <label for="count_mode_lines">lines</label>
</div> </div>
</div> </div>
@ -36,35 +40,35 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
dataDelimiter: '', dataDelimiter: "",
countMode: 'characters', countMode: "characters"
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
if (!this.toolData.data.length) { if (!this.toolData.data.length) {
this.toolResult = 0; this.toolResult = 0;
}else if (this.toolData.dataDelimiter.length) { } else if (this.toolData.dataDelimiter.length) {
this.toolResult = this.toolData.data.split(this.toolData.dataDelimiter).length; this.toolResult = this.toolData.data.split(this.toolData.dataDelimiter).length;
} else { } else {
switch (this.toolData.countMode) { switch (this.toolData.countMode) {
case 'characters': case "characters":
this.toolResult = this.toolData.data.length; this.toolResult = this.toolData.data.length;
break; break;
case 'words': case "words":
this.toolResult = this.toolData.data.trim().split(/\s+/).length; this.toolResult = this.toolData.data.trim().split(/\s+/).length;
break; break;
case 'lines': case "lines":
this.toolResult = this.toolData.data.split('\n').length; this.toolResult = this.toolData.data.split("\n").length;
break; break;
} }
} }
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -26,9 +26,9 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
@ -37,7 +37,7 @@ export default {
if (word.length <= 3) { if (word.length <= 3) {
this.toolResult = word; this.toolResult = word;
return return;
} }
const firstLetter = word[0]; const firstLetter = word[0];
@ -45,9 +45,9 @@ export default {
const numberOfLetters = word.length - 2; const numberOfLetters = word.length - 2;
this.toolResult = `${firstLetter}${numberOfLetters}${lastLetter}`; this.toolResult = `${firstLetter}${numberOfLetters}${lastLetter}`;
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -21,8 +21,10 @@
<label>Pad position</label> <label>Pad position</label>
<div> <div>
<input id="pad_pos_begin" value="begin" name="pad_pos" v-model="toolData.padPos" v-on:change="result" type="radio"> <label for="pad_pos_begin">begin</label><br> <input id="pad_pos_begin" value="begin" name="pad_pos" v-model="toolData.padPos" v-on:change="result"
<input id="pad_pos_end" value="end" name="pad_pos" v-model="toolData.padPos" v-on:change="result" type="radio"> <label for="pad_pos_end">end</label> type="radio"> <label for="pad_pos_begin">begin</label><br>
<input id="pad_pos_end" value="end" name="pad_pos" v-model="toolData.padPos" v-on:change="result" type="radio">
<label for="pad_pos_end">end</label>
</div> </div>
</div> </div>
@ -30,8 +32,10 @@
<label>Pad by</label> <label>Pad by</label>
<div> <div>
<input id="pad_by_repeat_symbol" value="repeat_symbol" name="pad_by" v-model="toolData.padBy" v-on:change="result" type="radio"> <label for="pad_by_repeat_symbol">repeat symbol</label><br> <input id="pad_by_repeat_symbol" value="repeat_symbol" name="pad_by" v-model="toolData.padBy" v-on:change="result"
<input id="pad_by_string_length" value="string_length" name="pad_by" v-model="toolData.padBy" v-on:change="result" type="radio"> <label for="pad_by_string_length">to string length</label> type="radio"> <label for="pad_by_repeat_symbol">repeat symbol</label><br>
<input id="pad_by_string_length" value="string_length" name="pad_by" v-model="toolData.padBy" v-on:change="result"
type="radio"> <label for="pad_by_string_length">to string length</label>
</div> </div>
</div> </div>
@ -53,25 +57,25 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
padSymbol: '0', padSymbol: "0",
padCount: 3, padCount: 3,
padPos: 'begin', padPos: "begin",
padBy: 'string_length', padBy: "string_length"
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
const lines = this.toolData.data.split('\n'); const lines = this.toolData.data.split("\n");
const paddedLines = lines.map((line) => { const paddedLines = lines.map((line) => {
if (this.toolData.padBy === 'string_length') { if (this.toolData.padBy === "string_length") {
const padLength = Math.max(0, this.toolData.padCount - line.length); const padLength = Math.max(0, this.toolData.padCount - line.length);
const padding = this.toolData.padSymbol.repeat(padLength); const padding = this.toolData.padSymbol.repeat(padLength);
if (this.toolData.padPos === 'begin') { if (this.toolData.padPos === "begin") {
return padding + line; return padding + line;
} else { } else {
return line + padding; return line + padding;
@ -79,7 +83,7 @@ export default {
} else { } else {
const padding = this.toolData.padSymbol.repeat(this.toolData.padCount); const padding = this.toolData.padSymbol.repeat(this.toolData.padCount);
if (this.toolData.padPos === 'begin') { if (this.toolData.padPos === "begin") {
return padding + line; return padding + line;
} else { } else {
return line + padding; return line + padding;
@ -87,10 +91,10 @@ export default {
} }
}); });
this.toolResult = paddedLines.join('\n'); this.toolResult = paddedLines.join("\n");
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -29,17 +29,17 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
this.toolResult = this.toolData.data.split('\n').filter(arrayUnique).join('\n'); this.toolResult = this.toolData.data.split("\n").filter(arrayUnique).join("\n");
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -11,12 +11,17 @@
<label>Mode</label> <label>Mode</label>
<div> <div>
<input id="sort_mode_alpha" value="alpha" name="sort_mode" v-model="toolData.sortMode" v-on:change="result" type="radio"> <label for="sort_mode_alpha">alphabetically</label><br> <input id="sort_mode_alpha" value="alpha" name="sort_mode" v-model="toolData.sortMode" v-on:change="result"
<input id="sort_mode_numerically" value="numerically" name="sort_mode" v-model="toolData.sortMode" v-on:change="result" type="radio"> <label for="sort_mode_numerically">numerically</label><br> type="radio"> <label for="sort_mode_alpha">alphabetically</label><br>
<input id="sort_mode_by_length" value="by_length" name="sort_mode" v-model="toolData.sortMode" v-on:change="result" type="radio"> <label for="sort_mode_by_length">by length</label><br> <input id="sort_mode_numerically" value="numerically" name="sort_mode" v-model="toolData.sortMode"
<input id="sort_mode_random" value="random" name="sort_mode" v-model="toolData.sortMode" v-on:change="result" type="radio"> <label for="sort_mode_random">random</label><br> v-on:change="result" type="radio"> <label for="sort_mode_numerically">numerically</label><br>
<input id="sort_mode_by_length" value="by_length" name="sort_mode" v-model="toolData.sortMode"
v-on:change="result" type="radio"> <label for="sort_mode_by_length">by length</label><br>
<input id="sort_mode_random" value="random" name="sort_mode" v-model="toolData.sortMode" v-on:change="result"
type="radio"> <label for="sort_mode_random">random</label><br>
<br> <br>
<input id="sort_mode_reverse" value="random" name="sort_mode_reverse" v-model="toolData.sortModeReverse" v-on:change="result" type="checkbox"> <label for="sort_mode_reverse">reverse</label> <input id="sort_mode_reverse" value="random" name="sort_mode_reverse" v-model="toolData.sortModeReverse"
v-on:change="result" type="checkbox"> <label for="sort_mode_reverse">reverse</label>
</div> </div>
</div> </div>
@ -38,37 +43,37 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
sortMode: 'alpha', sortMode: "alpha",
sortModeReverse: false, sortModeReverse: false
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
let result = [] let result = [];
const data = this.toolData.data.split('\n'); const data = this.toolData.data.split("\n");
switch (this.toolData.sortMode) { switch (this.toolData.sortMode) {
case 'alpha': case "alpha":
result = data.sort(function(a, b) { result = data.sort(function(a, b) {
return a.localeCompare(b); return a.localeCompare(b);
}); });
break; break;
case 'numerically': case "numerically":
const collator = new Intl.Collator([], {numeric: true}); const collator = new Intl.Collator([], { numeric: true });
result = data.sort(function(a, b) { result = data.sort(function(a, b) {
return collator.compare(a, b); return collator.compare(a, b);
}); });
break; break;
case 'by_length': case "by_length":
result = data.sort(function(a, b) { result = data.sort(function(a, b) {
return a.length - b.length; return a.length - b.length;
}); });
break; break;
case 'random': case "random":
result = data.sort(function(a, b) { result = data.sort(function(a, b) {
return Math.random() - .5; return Math.random() - .5;
}); });
@ -79,10 +84,10 @@ export default {
result = result.reverse(); result = result.reverse();
} }
this.toolResult = result.join('\n'); this.toolResult = result.join("\n");
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -11,8 +11,10 @@
<label>Mode</label> <label>Mode</label>
<div> <div>
<input id="case_mode_lower" value="lower" name="case_mode" v-model="toolData.caseMode" v-on:change="result" type="radio"> <label for="case_mode_lower">to lower</label><br> <input id="case_mode_lower" value="lower" name="case_mode" v-model="toolData.caseMode" v-on:change="result"
<input id="case_mode_upper" value="upper" name="case_mode" v-model="toolData.caseMode" v-on:change="result" type="radio"> <label for="case_mode_upper">to upper</label> type="radio"> <label for="case_mode_lower">to lower</label><br>
<input id="case_mode_upper" value="upper" name="case_mode" v-model="toolData.caseMode" v-on:change="result"
type="radio"> <label for="case_mode_upper">to upper</label>
</div> </div>
</div> </div>
@ -34,25 +36,25 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
caseMode: 'upper', caseMode: "upper"
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
switch (this.toolData.caseMode) { switch (this.toolData.caseMode) {
case 'lower': case "lower":
this.toolResult = this.toolData.data.toLocaleLowerCase(); this.toolResult = this.toolData.data.toLocaleLowerCase();
break; break;
case 'upper': case "upper":
this.toolResult = this.toolData.data.toLocaleUpperCase(); this.toolResult = this.toolData.data.toLocaleUpperCase();
break; break;
} }
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -16,8 +16,8 @@
</template> </template>
<script> <script>
import axios from 'axios' import axios from "axios";
import { config } from '../../config'; import { config } from "../../config";
import MonacoEditor from "@/components/MonacoEditor.vue"; import MonacoEditor from "@/components/MonacoEditor.vue";
export default { export default {
@ -27,27 +27,27 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
const natoAlphabet = { const natoAlphabet = {
'A': 'Alpha', 'B': 'Bravo', 'C': 'Charlie', 'D': 'Delta', "A": "Alpha", "B": "Bravo", "C": "Charlie", "D": "Delta",
'E': 'Echo', 'F': 'Foxtrot', 'G': 'Golf', 'H': 'Hotel', "E": "Echo", "F": "Foxtrot", "G": "Golf", "H": "Hotel",
'I': 'India', 'J': 'Juliett', 'K': 'Kilo', 'L': 'Lima', "I": "India", "J": "Juliett", "K": "Kilo", "L": "Lima",
'M': 'Mike', 'N': 'November', 'O': 'Oscar', 'P': 'Papa', "M": "Mike", "N": "November", "O": "Oscar", "P": "Papa",
'Q': 'Quebec', 'R': 'Romeo', 'S': 'Sierra', 'T': 'Tango', "Q": "Quebec", "R": "Romeo", "S": "Sierra", "T": "Tango",
'U': 'Uniform', 'V': 'Victor', 'W': 'Whiskey', 'X': 'X-ray', "U": "Uniform", "V": "Victor", "W": "Whiskey", "X": "X-ray",
'Y': 'Yankee', 'Z': 'Zulu', "Y": "Yankee", "Z": "Zulu"
}; };
this.toolResult = this.toolData.data.toUpperCase().split('').map(char => natoAlphabet[char] || char).join(' '); this.toolResult = this.toolData.data.toUpperCase().split("").map(char => natoAlphabet[char] || char).join(" ");
} }
} }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -9,10 +9,12 @@
<div class="input-group"> <div class="input-group">
<label for="data_delimiter">Delimiter</label> <label for="data_delimiter">Delimiter</label>
<input id="data_delimiter" v-model="toolData.dataDelimiter" placeholder="," type="text" v-on:keyup="result" :disabled="toolData.dataIsJson"> <input id="data_delimiter" v-model="toolData.dataDelimiter" placeholder="," type="text" v-on:keyup="result"
:disabled="toolData.dataIsJson">
<div> <div>
<input id="data_is_json" name="data_is_json" v-model="toolData.dataIsJson" v-on:change="result" type="checkbox"> <label for="data_is_json">is json</label> <input id="data_is_json" name="data_is_json" v-model="toolData.dataIsJson" v-on:change="result" type="checkbox">
<label for="data_is_json">is json</label>
</div> </div>
</div> </div>
@ -25,8 +27,8 @@
</template> </template>
<script> <script>
import axios from 'axios' import axios from "axios";
import { config } from '../../config'; import { config } from "../../config";
import MonacoEditor from "@/components/MonacoEditor.vue"; import MonacoEditor from "@/components/MonacoEditor.vue";
export default { export default {
@ -36,11 +38,11 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
dataDelimiter: '', dataDelimiter: "",
dataIsJson: false, dataIsJson: false
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
@ -48,7 +50,7 @@ export default {
axios.post(`${config.APP_URL}/api/php/str_to_php_array.php`, { axios.post(`${config.APP_URL}/api/php/str_to_php_array.php`, {
data: this.toolData.data, data: this.toolData.data,
delimiter: this.toolData.dataDelimiter, delimiter: this.toolData.dataDelimiter,
mode: this.toolData.dataIsJson ? 'json' : null, mode: this.toolData.dataIsJson ? "json" : null
}) })
.then((response) => { .then((response) => {
this.toolResult = response.data; this.toolResult = response.data;
@ -57,7 +59,7 @@ export default {
}); });
} }
} }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -9,7 +9,7 @@
<div class="input-group"> <div class="input-group">
<label for="style">Table Style</label> <label for="style">Table Style</label>
<div> <div>
<select id="style" v-model="toolData.selectedStyle" v-on:change="result"> <select id="style" v-model="toolData.selectedStyle" v-on:change="result">
<option value="">Default</option> <option value="">Default</option>
</select> </select>
@ -20,7 +20,8 @@
<label>Transpose table</label> <label>Transpose table</label>
<div> <div>
<input id="transpose" name="transpose" v-model="toolData.transpose" v-on:change="result" type="checkbox"> <label for="transpose">transpose</label> <input id="transpose" name="transpose" v-model="toolData.transpose" v-on:change="result" type="checkbox"> <label
for="transpose">transpose</label>
</div> </div>
</div> </div>
@ -43,17 +44,17 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
selectedStyle: '', selectedStyle: "",
transpose: false, transpose: false
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
let rows = unproxy(this.toolData.data).split('\n'); let rows = unproxy(this.toolData.data).split("\n");
let numCols = rows[0].split('\t').length; let numCols = rows[0].split("\t").length;
// Transpose the table if the option is selected // Transpose the table if the option is selected
if (this.toolData.transpose) { if (this.toolData.transpose) {
@ -61,39 +62,39 @@ export default {
for (let j = 0; j < numCols; j++) { for (let j = 0; j < numCols; j++) {
const newRow = []; const newRow = [];
for (let i = 0; i < rows.length; i++) { for (let i = 0; i < rows.length; i++) {
newRow.push(rows[i].split('\t')[j] || ''); newRow.push(rows[i].split("\t")[j] || "");
} }
transposedData.push(newRow.join('\t')); transposedData.push(newRow.join("\t"));
} }
rows = transposedData; rows = transposedData;
numCols = rows[0].split('\t').length; numCols = rows[0].split("\t").length;
} }
let output = ''; let output = "";
// Generate header row // Generate header row
output += '| ' + rows[0].split('\t').join(' | ') + ' |\n'; output += "| " + rows[0].split("\t").join(" | ") + " |\n";
// Generate separator row based on selected style // Generate separator row based on selected style
switch (this.toolData.selectedStyle) { switch (this.toolData.selectedStyle) {
default: default:
output += '| ' + '-'.repeat(numCols).split('').join(' | ') + ' |\n'; output += "| " + "-".repeat(numCols).split("").join(" | ") + " |\n";
break; break;
} }
// Generate data rows // Generate data rows
for (let i = 1; i < rows.length; i++) { for (let i = 1; i < rows.length; i++) {
if (this.toolData.selectedStyle === 'grid') { if (this.toolData.selectedStyle === "grid") {
output += '| ' + rows[i].split('\t').join(' | ') + ' |\n'; output += "| " + rows[i].split("\t").join(" | ") + " |\n";
} else { } else {
output += '| ' + rows[i].split('\t').join(' | ') + ' |\n'; output += "| " + rows[i].split("\t").join(" | ") + " |\n";
} }
} }
this.toolResult = output; this.toolResult = output;
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -26,32 +26,32 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: ""
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
let output = '{| class="wikitable"\n'; let output = "{| class=\"wikitable\"\n";
const rows = unproxy(this.toolData.data).split('\n'); const rows = unproxy(this.toolData.data).split("\n");
for (let i = 0; i < rows.length; i++) { for (let i = 0; i < rows.length; i++) {
const cells = rows[i].split('\t'); const cells = rows[i].split("\t");
output += '|-\n'; output += "|-\n";
for (let j = 0; j < cells.length; j++) { for (let j = 0; j < cells.length; j++) {
output += i === 0 ? '! ' : '| '; output += i === 0 ? "! " : "| ";
output += cells[j].trim() + '\n'; output += cells[j].trim() + "\n";
} }
} }
output += '|}'; output += "|}";
this.toolResult = output; this.toolResult = output;
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -4,18 +4,20 @@
<table> <table>
<thead> <thead>
<tr> <tr>
<th>Format</th> <th>Format</th>
<th>Date & Time</th> <th>Date & Time</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="(value, format) in currentTimestampFormatted" :key="format"> <tr v-for="(value, format) in currentTimestampFormatted" :key="format">
<td>{{ format }}</td> <td>{{ format }}</td>
<td>{{ value }}</td> <td>{{ value }}</td>
<td><button @click="copyTimestamp(value)">📋</button></td> <td>
</tr> <button @click="copyTimestamp(value)">📋</button>
</td>
</tr>
</tbody> </tbody>
</table> </table>
@ -36,26 +38,28 @@
<div> <div>
<table class="table-date-and-time"> <table class="table-date-and-time">
<thead> <thead>
<tr> <tr>
<th>Year</th> <th>Year</th>
<th>Month</th> <th>Month</th>
<th>Day</th> <th>Day</th>
<th>Hour (24)</th> <th>Hour (24)</th>
<th>Minute</th> <th>Minute</th>
<th>Second</th> <th>Second</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><input type="number" v-model="toolData.inputYear"></td> <td><input type="number" v-model="toolData.inputYear"></td>
<td><input type="number" v-model="toolData.inputMonth"></td> <td><input type="number" v-model="toolData.inputMonth"></td>
<td><input type="number" v-model="toolData.inputDay"></td> <td><input type="number" v-model="toolData.inputDay"></td>
<td><input type="number" v-model="toolData.inputHour"></td> <td><input type="number" v-model="toolData.inputHour"></td>
<td><input type="number" v-model="toolData.inputMinute"></td> <td><input type="number" v-model="toolData.inputMinute"></td>
<td><input type="number" v-model="toolData.inputSecond"></td> <td><input type="number" v-model="toolData.inputSecond"></td>
<td><button @click="convertToUnix">Convert </button></td> <td>
</tr> <button @click="convertToUnix">Convert </button>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
@ -63,22 +67,22 @@
</template> </template>
<script> <script>
import moment from 'moment'; import moment from "moment";
export default { export default {
data() { data() {
return { return {
toolData: { toolData: {
inputTimestamp: '', inputTimestamp: "",
inputYear: moment().year(), inputYear: moment().year(),
inputMonth: moment().month() + 1, inputMonth: moment().month() + 1,
inputDay: moment().day(), inputDay: moment().day(),
inputHour: moment().hour(), inputHour: moment().hour(),
inputMinute: moment().minute(), inputMinute: moment().minute(),
inputSecond: moment().second(), inputSecond: moment().second()
}, },
currentTimestamp: 0, currentTimestamp: 0,
currentTimestampFormatted: {}, currentTimestampFormatted: {}
}; };
}, },
mounted() { mounted() {
@ -86,7 +90,7 @@ export default {
this.currentTimestamp = moment().unix(); this.currentTimestamp = moment().unix();
this.currentTimestampFormatted = { this.currentTimestampFormatted = {
'UTC': moment().utc().format('YYYY-MM-DDTHH:mm:ss[Z]'), "UTC": moment().utc().format("YYYY-MM-DDTHH:mm:ss[Z]"),
// 'UTC (local)': moment().format('YYYY-MM-DDTHH:mm:ssZZ'), // 'UTC (local)': moment().format('YYYY-MM-DDTHH:mm:ssZZ'),
// 'ISO 8601': moment().toISOString(), // 'ISO 8601': moment().toISOString(),
// 'RFC 2822': moment().format('ddd, DD MMM YYYY HH:mm:ss ZZ'), // 'RFC 2822': moment().format('ddd, DD MMM YYYY HH:mm:ss ZZ'),
@ -97,10 +101,10 @@ export default {
// 'RFC 3339': moment().format('YYYY-MM-DDTHH:mm:ssZZ'), // 'RFC 3339': moment().format('YYYY-MM-DDTHH:mm:ssZZ'),
// 'COOKIE': moment().format('dddd, DD-MMM-YYYY HH:mm:ss [UTC]'), // 'COOKIE': moment().format('dddd, DD-MMM-YYYY HH:mm:ss [UTC]'),
// 'RSS': moment().format('ddd, DD MMM YYYY HH:mm:ss ZZ'), // 'RSS': moment().format('ddd, DD MMM YYYY HH:mm:ss ZZ'),
'Unix Epoch': moment().unix(), "Unix Epoch": moment().unix(),
'YYYY-DD-MM': moment().format('YYYY/MM/DD'), "YYYY-DD-MM": moment().format("YYYY/MM/DD"),
'SQL DATETIME': moment().toISOString().replaceAll(/[ZT]|(\.[0-9]{3})/g, ' '), "SQL DATETIME": moment().toISOString().replaceAll(/[ZT]|(\.[0-9]{3})/g, " "),
'YYYY/DD/MM HH:MM:SS AM/PM': moment().format('YYYY/MM/DD HH:mm:ss A'), "YYYY/DD/MM HH:MM:SS AM/PM": moment().format("YYYY/MM/DD HH:mm:ss A")
// 'DD.MM.YYYY HH:MM:SS': moment().format('DD.MM.YYYY HH:mm:ss'), // 'DD.MM.YYYY HH:MM:SS': moment().format('DD.MM.YYYY HH:mm:ss'),
}; };
}; };
@ -142,8 +146,8 @@ export default {
.catch(err => { .catch(err => {
// console.error('Failed to copy: ', err); // console.error('Failed to copy: ', err);
}); });
}, }
}, }
}; };
</script> </script>
@ -151,6 +155,7 @@ export default {
.table-date-and-time th { .table-date-and-time th {
text-align: left; text-align: left;
} }
.table-date-and-time td input { .table-date-and-time td input {
width: 80px; width: 80px;
} }

@ -11,8 +11,10 @@
<label>Mode</label> <label>Mode</label>
<div> <div>
<input id="encode_mode_encode" value="encode" name="encode_mode" v-model="toolData.encodeMode" v-on:change="result" type="radio"> <label for="encode_mode_encode">encode</label><br> <input id="encode_mode_encode" value="encode" name="encode_mode" v-model="toolData.encodeMode"
<input id="encode_mode_decode" value="decode" name="encode_mode" v-model="toolData.encodeMode" v-on:change="result" type="radio"> <label for="encode_mode_decode">decode</label> v-on:change="result" type="radio"> <label for="encode_mode_encode">encode</label><br>
<input id="encode_mode_decode" value="decode" name="encode_mode" v-model="toolData.encodeMode"
v-on:change="result" type="radio"> <label for="encode_mode_decode">decode</label>
</div> </div>
</div> </div>
@ -34,25 +36,25 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
encodeMode: 'decode', encodeMode: "decode"
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
result() { result() {
switch (this.toolData.encodeMode) { switch (this.toolData.encodeMode) {
case 'encode': case "encode":
this.toolResult = this.toolData.data.split('\n').map(encodeURIComponent).join('\n'); this.toolResult = this.toolData.data.split("\n").map(encodeURIComponent).join("\n");
break; break;
case 'decode': case "decode":
this.toolResult = this.toolData.data.split('\n').map(decodeURIComponent).join('\n'); this.toolResult = this.toolData.data.split("\n").map(decodeURIComponent).join("\n");
break; break;
} }
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">

@ -13,10 +13,10 @@
<label for="result">Result</label> <label for="result">Result</label>
<table> <table>
<tbody> <tbody>
<tr v-for="row in toolData.queryParts"> <tr v-for="row in toolData.queryParts">
<td><input :value="row.key" style="width: 100%;" type="text" readonly></td> <td><input :value="row.key" style="width: 100%;" type="text" readonly></td>
<td><input :value="row.value" style="width: 100%;" type="text" readonly></td> <td><input :value="row.value" style="width: 100%;" type="text" readonly></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p v-if="!toolData.queryParts.length">invalid url</p> <p v-if="!toolData.queryParts.length">invalid url</p>
@ -40,10 +40,10 @@ export default {
data() { data() {
return { return {
toolData: { toolData: {
data: '', data: "",
queryParts: [], queryParts: []
}, },
toolResult: '', toolResult: ""
}; };
}, },
methods: { methods: {
@ -63,22 +63,23 @@ export default {
for (let [key, value] of url.searchParams.entries()) { for (let [key, value] of url.searchParams.entries()) {
queryParams.push({ queryParams.push({
key: key, key: key,
value: value, value: value
}); });
} }
this.toolData.queryParts = queryParams.sort((a, b) => { this.toolData.queryParts = queryParams.sort((a, b) => {
return a.key.localeCompare(b.key); return a.key.localeCompare(b.key);
}) });
}, }
}, }
} };
</script> </script>
<style lang="scss"> <style lang="scss">
table tr:nth-child(even) input { table tr:nth-child(even) input {
background-color: #fbfbfb; background-color: #fbfbfb;
} }
table tr:nth-child(odd) input { table tr:nth-child(odd) input {
background-color: #eee; background-color: #eee;
} }