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");
module.exports = {
"root": true,
"extends": [
root: true,
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/eslint-config-prettier"
"@vue/eslint-config-prettier",
],
"env": {
"vue/setup-compiler-macros": true
}
}
env: {
"vue/setup-compiler-macros": true,
},
};

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

@ -149,6 +149,15 @@ const router = createRouter({
component: () => import('../views/GoSQLTablesToStruct.vue'),
},
/**
* Docker
*/
{
path: '/docker_rename_volume',
name: 'docker_rename_volume',
component: () => import('../views/DockerRenameVolume.vue'),
},
/**
* 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">
<label>Dimensions</label>
<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>
<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>
@ -26,7 +28,8 @@
<div class="input-group">
<label for="result">Result</label>
<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>
</template>
@ -38,10 +41,10 @@ export default {
toolData: {
width: 500,
height: 500,
color_bg: '#000000',
color_text: '#ffffff',
color_bg: "#000000",
color_text: "#ffffff"
},
toolResult: '',
toolResult: ""
};
},
mounted() {
@ -49,7 +52,7 @@ export default {
},
methods: {
result() {
const ctx = this.$refs.canvas.getContext('2d');
const ctx = this.$refs.canvas.getContext("2d");
// Set background color
ctx.fillStyle = this.toolData.color_bg;
@ -57,7 +60,7 @@ export default {
// Set text color and font
ctx.fillStyle = this.toolData.color_text;
ctx.font = 'bold 30px Arial';
ctx.font = "bold 30px Arial";
// Draw text on the canvas
const text = `${this.toolData.width}x${this.toolData.height}`;
@ -65,9 +68,9 @@ export default {
const x = (this.toolData.width - textWidth) / 2;
const y = this.toolData.height / 2 + 10;
ctx.fillText(text, x, y);
},
},
}
}
}
};
</script>
<style lang="scss">

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

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

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

@ -9,10 +9,12 @@
<div class="input-group">
<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>
<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>
@ -40,13 +42,10 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
let innerTabs = 0;
let parent = "";
try
{
try {
data = JSON.parse(json.replace(/(:\s*\[?\s*-?\d*)\.0/g, "$1.1")); // hack that forces floats to stay as floats
scope = data;
}
catch (e)
{
} catch (e) {
return {
go: "",
error: e.message
@ -65,22 +64,17 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
};
function parseScope(scope, depth = 0)
{
if (typeof scope === "object" && scope !== null)
{
if (Array.isArray(scope))
{
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++)
{
for (let i = 0; i < scopeLength; i++) {
const thisType = goType(scope[i]);
if (!sliceType)
sliceType = thisType;
else if (sliceType != thisType)
{
else if (sliceType != thisType) {
sliceType = mostSpecificPossibleGoType(thisType, sliceType);
if (sliceType == "any")
break;
@ -94,24 +88,21 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
if (flatten && depth >= 2)
appender(slice);
else
append(slice)
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)
{
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 {
};
} else {
const existingValue = allFields[keyname].value;
const currentValue = scope[i][keyname];
@ -119,7 +110,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
const comparisonResult = compareObjectKeys(
Object.keys(currentValue),
Object.keys(existingValue)
)
);
if (!comparisonResult) {
keyname = `${keyname}_${uuidv4()}`;
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
// omitempty dict indicates if a field is optional
const keys = Object.keys(allFields), struct = {}, omitempty = {};
for (let k in keys)
{
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 {
} else if (sliceType == "slice") {
parseScope(scope[0], depth);
} else {
if (flatten && depth >= 2) {
appender(sliceType || "any");
} else {
append(sliceType || "any");
}
}
}
else
{
} else {
if (flatten) {
if (depth >= 2){
appender(parent)
}
else {
append(parent)
if (depth >= 2) {
appender(parent);
} else {
append(parent);
}
}
parseStruct(depth + 1, innerTabs, scope);
}
}
else {
if (flatten && depth >= 2){
} else {
if (flatten && depth >= 2) {
appender(goType(scope));
}
else {
} else {
append(goType(scope));
}
}
}
function parseStruct(depth, innerTabs, scope, omitempty)
{
function parseStruct(depth, innerTabs, scope, omitempty) {
if (flatten) {
stack.push(
depth >= 2
? "\n"
: ""
)
);
}
const seenTypeNames = [];
if (flatten && depth >= 2)
{
if (flatten && depth >= 2) {
const parentType = `type ${parent}`;
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
if (parent in seen && compareObjectKeys(scopeKeys, seen[parent])) {
stack.pop();
return
return;
}
seen[parent] = scopeKeys;
appender(`${parentType} struct {\n`);
++innerTabs;
const keys = Object.keys(scope);
for (let i in keys)
{
for (let i in keys) {
const keyname = getOriginalName(keys[i]);
indenter(innerTabs)
const typename = uniqueTypeName(format(keyname), seenTypeNames)
seenTypeNames.push(typename)
indenter(innerTabs);
const typename = uniqueTypeName(format(keyname), seenTypeNames);
seenTypeNames.push(typename);
appender(typename+" ");
parent = typename
appender(typename + " ");
parent = typename;
parseScope(scope[keys[i]], depth);
appender(' `json:"'+keyname);
if (allOmitempty || (omitempty && omitempty[keys[i]] === true))
{
appender(',omitempty');
appender(" `json:\"" + keyname);
if (allOmitempty || (omitempty && omitempty[keys[i]] === true)) {
appender(",omitempty");
}
appender('"`\n');
appender("\"`\n");
}
indenter(--innerTabs);
appender("}");
}
else
{
} else {
append("struct {\n");
++tabs;
const keys = Object.keys(scope);
for (let i in keys)
{
for (let i in keys) {
const keyname = getOriginalName(keys[i]);
indent(tabs);
const typename = uniqueTypeName(format(keyname), seenTypeNames)
seenTypeNames.push(typename)
append(typename+" ");
parent = typename
const typename = uniqueTypeName(format(keyname), seenTypeNames);
seenTypeNames.push(typename);
append(typename + " ");
parent = typename;
parseScope(scope[keys[i]], depth);
append(' `json:"'+keyname);
if (allOmitempty || (omitempty && omitempty[keys[i]] === true))
{
append(',omitempty');
append(" `json:\"" + keyname);
if (allOmitempty || (omitempty && omitempty[keys[i]] === true)) {
append(",omitempty");
}
if (example && scope[keys[i]] !== "" && typeof scope[keys[i]] !== "object")
{
append('" example:"'+scope[keys[i]])
if (example && scope[keys[i]] !== "" && typeof scope[keys[i]] !== "object") {
append("\" example:\"" + scope[keys[i]]);
}
append('"`\n');
append("\"`\n");
}
indent(--tabs);
append("}");
@ -260,25 +234,21 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
accumulator += stack.pop();
}
function indent(tabs)
{
function indent(tabs) {
for (let i = 0; i < tabs; i++)
go += '\t';
go += "\t";
}
function append(str)
{
function append(str) {
go += str;
}
function indenter(tabs)
{
function indenter(tabs) {
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;
}
@ -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
function format(str)
{
function format(str) {
str = formatNumber(str);
let sanitized = toProperCase(str).replace(/[^a-z0-9]/ig, "")
let sanitized = toProperCase(str).replace(/[^a-z0-9]/ig, "");
if (!sanitized) {
return "NAMING_FAILED";
}
// 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.
return formatNumber(sanitized)
return formatNumber(sanitized);
}
// 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 "";
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_"};
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);
}
@ -333,27 +303,23 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
}
// Determines the most appropriate Go type
function goType(val)
{
function goType(val) {
if (val === null)
return "any";
switch (typeof val)
{
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 % 1 === 0) {
if (val > -2147483648 && val < 2147483647)
return "int";
else
return "int64";
}
else
} else
return "float64";
case "boolean":
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
function mostSpecificPossibleGoType(typ1, typ2)
{
function mostSpecificPossibleGoType(typ1, typ2) {
if (typ1.substr(0, 5) == "float"
&& typ2.substr(0, 3) == "int")
return typ1;
@ -380,8 +345,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
}
// 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
if (str.match(/^[_A-Z0-9]+$/)) {
str = str.toLowerCase();
@ -395,14 +359,12 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
"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)
return sep + frag.toUpperCase();
else
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)
return (sep + frag).toUpperCase();
else
@ -411,23 +373,23 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
}
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 "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 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.slice(0, -1 * (uuidLength + 1));
}
}
return unique
return unique;
}
function compareObjects(objectA, objectB) {
@ -459,7 +421,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
for (let i in keys) {
keys[i] = format(keys[i]);
}
return keys
return keys;
}
}
@ -470,30 +432,30 @@ export default {
data() {
return {
toolData: {
data: '',
data: "",
flatten: false,
omitempty: false,
omitempty: false
},
toolResult: '',
toolResult: ""
};
},
methods: {
result() {
if (!this.toolData.data.length) {
this.toolResult = '';
this.toolResult = "";
return;
}
const json = jsonToGo(this.toolData.data, "", this.toolData.flatten, false, this.toolData.omitempty);
if (json.error?.length) {
this.toolResult = 'invalid json';
this.toolResult = "invalid json";
return;
}
this.toolResult = json.go;
}
},
}
}
};
</script>
<style lang="scss">

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

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

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

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

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

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

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

@ -21,7 +21,8 @@
<div class="input-group">
<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 class="input-group">
@ -49,14 +50,16 @@
<div class="input-group">
<label for="backgroundImageUpload">Background Image Upload:</label>
<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>
</div>
</div>
<div class="input-group">
<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>
<!--
@ -78,7 +81,7 @@
</select>
</div>
</div>
<hr class="mt-5 mb-5">
<div class="input-group">
@ -89,7 +92,7 @@
</template>
<script>
import QRCode from 'easyqrcodejs';
import QRCode from "easyqrcodejs";
import { unproxy } from "../utils/unproxy";
export default {
@ -97,39 +100,39 @@ export default {
return {
toolData: {
options: {
text: '',
text: "",
width: 256,
height: 256,
correctLevel: 'L',
logo: '',
correctLevel: "L",
logo: "",
quietZone: 10,
logoBackgroundTransparent: true,
backgroundImage: '',
backgroundImage: "",
backgroundImageAlpha: 1,
autoColor: true,
drawer: 'canvas',
},
},
drawer: "canvas"
}
}
};
},
mounted() {
this.toolData.options.text = ' ';
this.toolData.options.text = " ";
this.result();
this.toolData.options.text = '';
this.toolData.options.text = "";
},
methods: {
result() {
// Clear previous QR code
this.$refs.qrcodeContainer.innerHTML = '';
this.$refs.qrcodeContainer.innerHTML = "";
let options = unproxy(this.toolData.options);
// convert correction levels
options.correctLevel = {
'L': QRCode.CorrectLevel.L,
'M': QRCode.CorrectLevel.M,
'Q': QRCode.CorrectLevel.Q,
'H': QRCode.CorrectLevel.H,
"L": QRCode.CorrectLevel.L,
"M": QRCode.CorrectLevel.M,
"Q": QRCode.CorrectLevel.Q,
"H": QRCode.CorrectLevel.H
}[options.correctLevel];
console.log(options.correctLevel);
@ -162,15 +165,15 @@ export default {
},
removeLogo() {
this.toolData.options.logo = '';
this.toolData.options.logo = "";
this.result();
},
removeBackgroundImage() {
this.toolData.options.backgroundImage = '';
this.toolData.options.backgroundImage = "";
this.result();
},
}
}
}
};
</script>
<style lang="scss">

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

@ -21,9 +21,12 @@
<label>Wrap in quotes</label>
<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_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>
<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_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>
@ -59,29 +62,29 @@ export default {
data() {
return {
toolData: {
fieldName: '',
data: '',
dataDelimiter: '',
wrapInQuotes: '',
chunkBy: 900,
fieldName: "",
data: "",
dataDelimiter: "",
wrapInQuotes: "",
chunkBy: 900
},
toolResult: '',
toolResult: ""
};
},
methods: {
result() {
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++) {
let value = data[i];
switch (this.toolData.wrapInQuotes) {
case 'single':
case "single":
value = "'" + value.replace("'", "\\'") + "'";
break;
case 'double':
value = '"' + value.replace('"', '\\"') + '"';
case "double":
value = "\"" + value.replace("\"", "\\\"") + "\"";
break;
}
@ -94,13 +97,13 @@ export default {
for (let i = 0; i < data.length; 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>
<style lang="scss">

@ -12,9 +12,13 @@
<input id="data_delimiter" v-model="toolData.dataDelimiter" v-on:keyup="result" placeholder="," type="text">
<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_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>
<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_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>
@ -36,35 +40,35 @@ export default {
data() {
return {
toolData: {
data: '',
dataDelimiter: '',
countMode: 'characters',
data: "",
dataDelimiter: "",
countMode: "characters"
},
toolResult: '',
toolResult: ""
};
},
methods: {
result() {
if (!this.toolData.data.length) {
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;
} else {
switch (this.toolData.countMode) {
case 'characters':
case "characters":
this.toolResult = this.toolData.data.length;
break;
case 'words':
case "words":
this.toolResult = this.toolData.data.trim().split(/\s+/).length;
break;
case 'lines':
this.toolResult = this.toolData.data.split('\n').length;
case "lines":
this.toolResult = this.toolData.data.split("\n").length;
break;
}
}
},
},
}
}
}
};
</script>
<style lang="scss">

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

@ -21,8 +21,10 @@
<label>Pad position</label>
<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_end" value="end" name="pad_pos" v-model="toolData.padPos" v-on:change="result" type="radio"> <label for="pad_pos_end">end</label>
<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_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>
@ -30,8 +32,10 @@
<label>Pad by</label>
<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_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>
<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_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>
@ -53,25 +57,25 @@ export default {
data() {
return {
toolData: {
data: '',
padSymbol: '0',
data: "",
padSymbol: "0",
padCount: 3,
padPos: 'begin',
padBy: 'string_length',
padPos: "begin",
padBy: "string_length"
},
toolResult: '',
toolResult: ""
};
},
methods: {
result() {
const lines = this.toolData.data.split('\n');
const lines = this.toolData.data.split("\n");
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 padding = this.toolData.padSymbol.repeat(padLength);
if (this.toolData.padPos === 'begin') {
if (this.toolData.padPos === "begin") {
return padding + line;
} else {
return line + padding;
@ -79,7 +83,7 @@ export default {
} else {
const padding = this.toolData.padSymbol.repeat(this.toolData.padCount);
if (this.toolData.padPos === 'begin') {
if (this.toolData.padPos === "begin") {
return padding + line;
} else {
return line + padding;
@ -87,10 +91,10 @@ export default {
}
});
this.toolResult = paddedLines.join('\n');
},
},
}
this.toolResult = paddedLines.join("\n");
}
}
};
</script>
<style lang="scss">

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

@ -11,12 +11,17 @@
<label>Mode</label>
<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_numerically" value="numerically" name="sort_mode" v-model="toolData.sortMode" 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>
<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_numerically" value="numerically" name="sort_mode" v-model="toolData.sortMode"
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>
<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>
@ -38,37 +43,37 @@ export default {
data() {
return {
toolData: {
data: '',
sortMode: 'alpha',
sortModeReverse: false,
data: "",
sortMode: "alpha",
sortModeReverse: false
},
toolResult: '',
toolResult: ""
};
},
methods: {
result() {
let result = []
const data = this.toolData.data.split('\n');
let result = [];
const data = this.toolData.data.split("\n");
switch (this.toolData.sortMode) {
case 'alpha':
case "alpha":
result = data.sort(function(a, b) {
return a.localeCompare(b);
});
break;
case 'numerically':
const collator = new Intl.Collator([], {numeric: true});
case "numerically":
const collator = new Intl.Collator([], { numeric: true });
result = data.sort(function(a, b) {
return collator.compare(a, b);
});
break;
case 'by_length':
case "by_length":
result = data.sort(function(a, b) {
return a.length - b.length;
});
break;
case 'random':
case "random":
result = data.sort(function(a, b) {
return Math.random() - .5;
});
@ -79,10 +84,10 @@ export default {
result = result.reverse();
}
this.toolResult = result.join('\n');
},
},
}
this.toolResult = result.join("\n");
}
}
};
</script>
<style lang="scss">

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

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

@ -9,10 +9,12 @@
<div class="input-group">
<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>
<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>
@ -25,8 +27,8 @@
</template>
<script>
import axios from 'axios'
import { config } from '../../config';
import axios from "axios";
import { config } from "../../config";
import MonacoEditor from "@/components/MonacoEditor.vue";
export default {
@ -36,11 +38,11 @@ export default {
data() {
return {
toolData: {
data: '',
dataDelimiter: '',
dataIsJson: false,
data: "",
dataDelimiter: "",
dataIsJson: false
},
toolResult: '',
toolResult: ""
};
},
methods: {
@ -48,7 +50,7 @@ export default {
axios.post(`${config.APP_URL}/api/php/str_to_php_array.php`, {
data: this.toolData.data,
delimiter: this.toolData.dataDelimiter,
mode: this.toolData.dataIsJson ? 'json' : null,
mode: this.toolData.dataIsJson ? "json" : null
})
.then((response) => {
this.toolResult = response.data;
@ -57,7 +59,7 @@ export default {
});
}
}
}
};
</script>
<style lang="scss">

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

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

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

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

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