Compare commits

..

134 Commits

Author SHA1 Message Date
Corentin Thomasset
d87091b23f chore(config): no index 2022-04-23 00:48:31 +02:00
Dante-DaCapo
b65b69dd97 fix: GitMemo displayed commands 2022-03-02 14:36:50 +01:00
Corentin Thomasset
5bd5d2c2f3 1.7.0 2020-07-23 23:25:52 +02:00
Corentin Thomasset
55dffa5635 feat: crontab generator
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-23 23:25:15 +02:00
Corentin Thomasset
baee5e6656 1.6.0 2020-07-22 13:05:46 +02:00
Corentin Thomasset
df5804c71d chore: changelog version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-22 13:05:35 +02:00
dependabot[bot]
8e99a0a783 chore(deps): bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-22 13:04:27 +02:00
Corentin Thomasset
6e22b12494 feat: base64 generator
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-22 13:02:33 +02:00
Corentin THOMASSET
aaa154d0b8 chore: updated roadmap 2020-07-20 10:26:54 +02:00
Corentin Thomasset
37b28c8d21 docs: updated README.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-08 20:18:34 +02:00
Corentin Thomasset
06aac238b2 fix: array to bool in rules
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-08 20:03:22 +02:00
Corentin Thomasset
a282c526c1 feat: BIP39 generator
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-08 19:54:55 +02:00
Corentin Thomasset
19eafdbe37 doc: fixed link in CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-08 19:54:33 +02:00
Corentin Thomasset
635552fbce 1.5.2 2020-07-08 13:37:39 +02:00
Corentin Thomasset
7f8404645d chore: version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-08 13:37:35 +02:00
Corentin Thomasset
66c569f886 chore: pwa auto update
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-07-08 13:35:24 +02:00
Corentin Thomasset
f02a816eaa docs: updated README.md 2020-06-23 13:19:44 +02:00
Corentin Thomasset
f0d8a3ad26 feat: humans.txt
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-23 10:30:57 +02:00
Corentin Thomasset
f91a2a1343 Merge branch 'master' of github.com:CorentinTh/it-tools 2020-06-23 10:18:31 +02:00
Corentin Thomasset
845d106927 1.5.1 2020-06-23 10:16:45 +02:00
Corentin Thomasset
25bbf9b5f3 chore: CHANGELOG.md version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-23 10:16:35 +02:00
Corentin Thomasset
853e24ca75 chore: updated CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-23 10:15:58 +02:00
Corentin Thomasset
41fadc7334 1.5.0 2020-06-23 10:15:58 +02:00
Corentin Thomasset
19ab6d06c3 chore: updated version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-23 10:15:58 +02:00
Corentin Thomasset
d92c46c60b feat: history mode
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-23 10:10:58 +02:00
Corentin Thomasset
ed176c7b8c 1.5.0 2020-06-23 09:40:58 +02:00
Corentin Thomasset
e152651a4b chore: updated version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-23 09:40:50 +02:00
Corentin Thomasset
a20858dfb8 feat: added qr-code generator
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-23 00:01:14 +02:00
Corentin Thomasset
b75603f311 docs: create tool guideline
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-22 21:15:50 +02:00
Corentin Thomasset
d27c133a66 fix: CHANGELOG.md version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-22 20:55:16 +02:00
Corentin Thomasset
bd64eb9dbe 1.4.0 2020-06-22 20:54:35 +02:00
Corentin Thomasset
ac54250e8a refactor: changed app title
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-22 20:53:53 +02:00
Corentin Thomasset
e0e7715ce6 feat: added canonical url
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-22 18:42:19 +02:00
Corentin Thomasset
aa3a424f10 docs: updated README.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-21 18:45:12 +02:00
Corentin Thomasset
03e073d4f0 feat: git memo
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-21 18:42:19 +02:00
Corentin Thomasset
cb0e3f91db feat: git memo
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-21 18:34:17 +02:00
Corentin Thomasset
c8c0dceb21 refactor: globalised code style
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-21 18:33:56 +02:00
Corentin Thomasset
ba5e07d063 refactor: home page layout
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-21 18:33:17 +02:00
Corentin Thomasset
9e94a985ca feat: ga monitor app version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-21 18:32:44 +02:00
Corentin Thomasset
a14a7338f8 feat: added call to action
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-21 18:31:56 +02:00
Corentin Thomasset
b65472ce96 feat: condensed + colored sidenav
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-21 11:31:22 +02:00
Corentin Thomasset
87f269a792 Merge branch 'master' of github.com:CorentinTh/it-tools 2020-06-15 22:26:00 +02:00
Corentin Thomasset
27f957a098 fix: added version in CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:22:37 +02:00
Corentin Thomasset
551738f559 1.3.0 2020-06-15 22:12:46 +02:00
Corentin Thomasset
8f7b7f628e docs: checked Lorem ipsum generator in roadmap
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
46514cf71b feat: fixed icons width in sidebar
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
78157b4cb5 feat: fixed icons width in sidebar
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
bf4260f926 docs: checked markdown editor in roadmap
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
9fc566e55a refactor: now using marked for changelog
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
507d961cd8 feat: added MarkdownEditor.vue
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
0631a7f750 chore: added stuff to roadmap
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
99ffe08d01 chore: update CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
fcc1335f97 refactor: removed lazyLoad method
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin THOMASSET
3988d33218 chore: updated changelog 2020-06-15 22:12:46 +02:00
Alexander Janke
ecb4b1bb7b Use vue-typecast
https://vuejs.org/v2/guide/forms.html#number
2020-06-15 22:12:46 +02:00
Corentin Thomasset
b63c4b5415 refactor: lazy-loading tools routes
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
26bda68f41 fix: ordered contributors by contribution count
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
f9f80b4e3a fix: replace next by version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:12:46 +02:00
Corentin Thomasset
f50c5cb91b 1.3.0 2020-06-15 22:10:09 +02:00
Corentin Thomasset
da1da1d269 docs: checked Lorem ipsum generator in roadmap
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
4129169e2b feat: fixed icons width in sidebar
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
cffbfe3e39 feat: fixed icons width in sidebar
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
583ce878d2 docs: checked markdown editor in roadmap
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
c179f6a800 refactor: now using marked for changelog
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
7944fd9f17 feat: added MarkdownEditor.vue
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
84763e1d5f chore: added stuff to roadmap
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
ab56a3b598 chore: update CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
b7d7454df5 refactor: removed lazyLoad method
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin THOMASSET
b730c1d1b4 chore: updated changelog 2020-06-15 22:10:08 +02:00
Alexander Janke
f6da2a44e5 Use vue-typecast
https://vuejs.org/v2/guide/forms.html#number
2020-06-15 22:10:08 +02:00
Corentin Thomasset
89713c4986 refactor: lazy-loading tools routes
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
3401fa4cf1 fix: ordered contributors by contribution count
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
2a7abceba1 fix: replace next by version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-15 22:10:08 +02:00
Corentin Thomasset
cd9a2318fd fix: added parseFloat in isInt
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-09 08:22:26 +02:00
Corentin Thomasset
0ebe60e21e 1.2.1 2020-06-09 08:22:26 +02:00
Corentin Thomasset
634147f0b3 chore: update CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-09 08:22:26 +02:00
dotvirus
318691837e Use Number.isInteger 2020-06-09 08:22:26 +02:00
Corentin Thomasset
17f3e7de35 refactor: proper validation rules
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-09 08:22:26 +02:00
Corentin Thomasset
aa4fb5ffff fix: added quantity validation rules
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-09 08:22:26 +02:00
Corentin Thomasset
e51a37844a 1.2.0 2020-06-08 19:15:52 +02:00
Corentin Thomasset
6d8db0a5d5 chore: updated CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-08 19:15:52 +02:00
Corentin Thomasset
84e727a43a feat: can generate multiple uuids
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-08 19:15:52 +02:00
Corentin Thomasset
6f7c399823 refactor: removed 404 page from tools roadmap
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-08 19:15:52 +02:00
dependabot[bot]
3777eb941d chore(deps): bump websocket-extensions from 0.1.3 to 0.1.4
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-06-08 19:15:52 +02:00
Corentin Thomasset
dd41bdc57c chore: updated CHANGELOG.md version
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-08 12:02:02 +02:00
Corentin Thomasset
48d0815524 1.1.0 2020-06-08 11:59:52 +02:00
Corentin Thomasset
efe62bb3cf fix: color picker now updates fields
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-08 11:58:09 +02:00
Corentin Thomasset
48376c17b2 docs: updated README.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-08 00:54:25 +02:00
Corentin Thomasset
458309c563 chore: updated CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-08 00:54:04 +02:00
Corentin Thomasset
fba0701df2 feat: contributors + changelogs in about page
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-08 00:31:07 +02:00
Corentin Thomasset
b013903c41 refactor: cleaner 404 page
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 23:13:08 +02:00
Corentin Thomasset
432ac7dd1c feat: 404 handler + page
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 23:11:18 +02:00
Corentin Thomasset
12a0d93c85 fix: added links in CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 19:29:54 +02:00
Corentin Thomasset
8c16d5f691 1.0.1 2020-06-07 19:27:41 +02:00
Corentin Thomasset
3c0c2bd14f chore: added CHANGELOG.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 19:27:30 +02:00
Corentin Thomasset
f729eacdc5 docs: updated roadmap
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 19:20:00 +02:00
Corentin Thomasset
b46ae1a89e fix: removed history mode for router to prevent 404 on route direct access
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 19:20:00 +02:00
Corentin Thomasset
45112d1b33 feat: prevent non-integer bases
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 19:20:00 +02:00
Corentin Thomasset
0bf13326c8 refactor: proper icons
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 14:40:40 +02:00
Corentin Thomasset
e5ffb4b946 fix: added router in vue analytics
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 14:06:29 +02:00
Corentin Thomasset
a110a6b212 feat: added google analytics
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 14:01:30 +02:00
Corentin Thomasset
596753ce42 1.0.0 2020-06-07 13:39:45 +02:00
Corentin Thomasset
803dabece3 docs: updated README.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
f15ae7c959 fix: proper checklist
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
6dca9bb1bf docs: updated README.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
9486c71d2b refactor: updated banner.png
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
42864770d7 docs: removed previous title
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
8fab4264b8 docs: added logo in README.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
d7e0c4a16f chore: added LICENSE
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
ea4c87f6f3 chore: added CONTRIBUTING.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
360faf285e chore: added CODE_OF_CONDUCT.md
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
db48322ec3 feat: dynamic title/description
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
c4bfad764c refactor: indent/format
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
4801519b9f fix: input date format not updating
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
5ec4c26f01 refactor: inputs length
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
b3d63734f0 feat: abstract
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
9f4a257599 refactor: cleaned ColorConverter
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
3e5a26c54c refactor: using "color-convert" in ColorConverter
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
332cd33196 feat: ColorConverter
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
44c9157cec feat: ColorConverter
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
40b2695c8d refactor: font awesome 5 icons
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
55668ea312 feat: home page
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
77a6f20b2b feat: UuidGenerator
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
407669def2 feat: BaseConverter
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
8c78e8ad77 feat: TextStats + better searchbar
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
85587beb0d feat: TextCypher
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
805716910a feat: FileUploader + Base64
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
Corentin Thomasset
e67e4cf547 feat: searchbar in menu on small screens
Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
CorentinTh
716cfb69e3 feat: search bar 2020-06-07 13:39:45 +02:00
CorentinTh
d9f6c55a79 feat: urlencoder + file in base64 2020-06-07 13:39:45 +02:00
CorentinTh
ee4eb30ca2 feat: improved date converter input 2020-06-07 13:39:45 +02:00
CorentinTh
5a06d89bcc feat: DateConverter
Signed-off-by: CorentinTh <corentin.thomasset74@gmail.com>
2020-06-07 13:39:45 +02:00
CorentinTh
d1db2c8601 feat: TokenGenerator + Hash 2020-06-07 13:39:45 +02:00
Corentin THOMASSET
1fba5c42e1 chore: update issue templates 2020-06-06 23:01:43 +02:00
54 changed files with 1810 additions and 264 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG] My bug title"
labels: bug
assignees: CorentinTh
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

54
CHANGELOG.md Normal file
View File

@@ -0,0 +1,54 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Next
- [feat] [Crontab friendly generator](https://it-tools.tech/crontab-generator)
## 1.6.0
- [feat] [BIP39 generator](https://it-tools.tech/bip39-generator)
- [feat] [Base 64 converter](https://it-tools.tech/base64-string-converter)
## 1.5.2
- [feat] [humans.txt](https://it-tools.tech/humans.txt)
- [feat] pwa auto update on new changes
## 1.5.1
- [feat] switched back to history mode (no more '#' in url)
## 1.5.0
- [feat] added [qr-code generator](https://it-tools.tech/qrcode-generator)
## 1.4.0
- [ui] condensed + colored sidenav
- [feat] added [git memo](https://it-tools.tech/git-memo)
- [refactor] changed app title
## 1.3.0
- [fix] [GithubContributors] ordered contributors by contribution count
- [refactor] used vue-typecasting for number inputs
- [feat] lazy loading tools routes
- [feat] added [markdown editor](https://it-tools.tech/markdown-editor)
- [feat] added [lorem ipsum generator](https://it-tools.tech/lorem-ipsum-generator)
## 1.2.1
- [fix] [UuidGenerator] added quantity validation rules
- [refactor] better isInt checker
## 1.2.0
- [feat] [UuidGenerator] can generate multiple uuids
## 1.1.0
- [feat] 404 route + page
- [feat] changelog in the About page
- [feat] contributors list in the About page
- [fix] [ColorConverter] color picker now updates fields
## 1.0.1
- [chore] added changelog
- [fix] [BaseConverter] prevented non-integer bases
- [fix] remove history move (incompatible with vercel.com)
## 1.0.0
- First release

View File

@@ -2,7 +2,7 @@
Aggregated set of useful tools that every developer may need once in a while. Available [here](https://it-tools.tech).
## Functionality/roadmap
## Functionalities roadmap
Here is an unordered list of the current functionalities, and some that may come.
- [x] Token generator
@@ -15,13 +15,23 @@ Here is an unordered list of the current functionalities, and some that may come
- [x] Url encoder
- [x] Base 64 generator
- [x] Text information
- [ ] Lorem ipsum text generator
- [x] Markdown editor
- [x] Lorem ipsum text generator
- [x] Git memo (cheat sheet)
- [x] QR code generator
- [x] Bip39 pass-phrase generator
- [x] Base 64 string converter
- [x] Crontab friendly generator
- [ ] CSS memo (cheat sheet)
- [ ] REGEX memo (cheat sheet) + tester?
- [ ] Minify/un-minify
- [ ] Image exif editor/remover
- [ ] QR code generator
- [ ] Bip39 pass-phrase generator
- [ ] Crontab friendly generator
- [ ] Image format converter?
- [ ] Image cropper
- [ ] Image resizer
- [ ] HTTP client (w/ axios + cors proxy)
- [ ] Math expression evaluator
- [ ] Math expression graph
You have an idea of a tool? Submit a feature request!
@@ -44,10 +54,33 @@ npm run lint
## Contribute
**Pull requests are welcome !** Feel free to contribute.
### Add a tool
To add a tool you just have to create a vue component in [src/routes/tools](./src/routes/tools), example:
```vue
<template>
<v-card class="single-card">
<v-card-title>My component</v-card-title>
<v-card-text>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</v-card-text>
</v-card>
</template>
<script>
export default {
name: "My component"
}
</script>
<style scoped lang="less">
</style>
```
Then, update the file [router.js](./src/router.js) specifying info of the component.
Use [fontawesome 5](https://fontawesome.com/icons?d=gallery&m=free) for icons.
## Credits
Coded with ❤️ by [Corentin Thomasset](//corentin-thomasset.fr).
This project is continuously deployed using [vercel.com](https://vercel.com).
## License
This project is under the [MIT license](LICENSE).
This project is under the [MIT license](LICENSE).

112
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "it-tools",
"version": "1.0.0",
"version": "1.7.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2483,6 +2483,24 @@
"file-uri-to-path": "1.0.0"
}
},
"bip39": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz",
"integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==",
"requires": {
"@types/node": "11.11.6",
"create-hash": "^1.1.0",
"pbkdf2": "^3.0.9",
"randombytes": "^2.0.1"
},
"dependencies": {
"@types/node": {
"version": "11.11.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz",
"integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ=="
}
}
},
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -3023,7 +3041,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
"integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
"dev": true,
"requires": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
@@ -3139,6 +3156,12 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"highlight.js": {
"version": "9.18.1",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz",
"integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==",
"dev": true
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
@@ -3676,7 +3699,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
"cipher-base": "^1.0.1",
"inherits": "^2.0.1",
@@ -3689,7 +3711,6 @@
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
"cipher-base": "^1.0.3",
"create-hash": "^1.1.0",
@@ -3699,6 +3720,16 @@
"sha.js": "^2.4.8"
}
},
"cron-validator": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/cron-validator/-/cron-validator-1.1.1.tgz",
"integrity": "sha512-vfZb05w/wezuwPZBDvdIBmJp2BvuJExHeyKRa5oBqD2ZDXR61hb3QgPc/3ZhBEQJlAy8Jlnn5XC/JCT3IDqxwg=="
},
"cronstrue": {
"version": "1.96.0",
"resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-1.96.0.tgz",
"integrity": "sha512-kNuuN0AXqspm+jlpwiecFSFBrG5dYBaL5EaW5MEjGAh4IFT/jbKwKCNhzWb8N5NulKQUHEDN7w98GjoAm6PmMg=="
},
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -4373,6 +4404,11 @@
"domelementtype": "1"
}
},
"dompurify": {
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.0.11.tgz",
"integrity": "sha512-qVoGPjIW9IqxRij7klDQQ2j6nSe4UNWANBhZNLnsS7ScTtLb+3YdxkRY8brNTpkUiTtcXsCJO+jS0UCDfenLuA=="
},
"domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
@@ -6214,7 +6250,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
"integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
"dev": true,
"requires": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
@@ -6253,12 +6288,6 @@
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
"dev": true
},
"highlight.js": {
"version": "9.18.1",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz",
"integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==",
"dev": true
},
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -6628,8 +6657,7 @@
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"inquirer": {
"version": "7.1.0",
@@ -7913,9 +7941,9 @@
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true
},
"lodash._reinterpolate": {
@@ -8103,11 +8131,15 @@
"object-visit": "^1.0.0"
}
},
"marked": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-1.1.0.tgz",
"integrity": "sha512-EkE7RW6KcXfMHy2PA7Jg0YJE1l8UPEZE8k45tylzmZM30/r1M1MUXWQfJlrSbsTeh7m/XTwHbWUENvAJZpp1YA=="
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
"integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
"dev": true,
"requires": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1",
@@ -9084,7 +9116,6 @@
"version": "3.0.17",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
"integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
"dev": true,
"requires": {
"create-hash": "^1.1.2",
"create-hmac": "^1.1.4",
@@ -9980,6 +10011,11 @@
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
},
"qrcode.vue": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-1.7.0.tgz",
"integrity": "sha512-R7t6Y3fDDtcU7L4rtqwGUDP9xD64gJhIwpfjhRCTKmBoYF6SS49PIJHRJ048cse6OI7iwTwgyy2C46N9Ygoc6g=="
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
@@ -10018,7 +10054,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"requires": {
"safe-buffer": "^5.1.0"
}
@@ -10051,6 +10086,29 @@
"unpipe": "1.0.0"
}
},
"raw-loader": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.1.tgz",
"integrity": "sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",
"schema-utils": "^2.6.5"
},
"dependencies": {
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
}
}
},
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@@ -10428,7 +10486,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
"integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
"dev": true,
"requires": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1"
@@ -10475,8 +10532,7 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safe-regex": {
"version": "1.1.0",
@@ -10737,7 +10793,6 @@
"version": "2.4.11",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true,
"requires": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
@@ -12117,6 +12172,11 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
},
"vue-analytics": {
"version": "5.22.1",
"resolved": "https://registry.npmjs.org/vue-analytics/-/vue-analytics-5.22.1.tgz",
"integrity": "sha512-HPKQMN7gfcUqS5SxoO0VxqLRRSPkG1H1FqglsHccz6BatBatNtm/Vyy8brApktZxNCfnAkrSVDpxg3/FNDeOgQ=="
},
"vue-cli-plugin-vuetify": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.0.5.tgz",
@@ -12713,9 +12773,9 @@
}
},
"websocket-extensions": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
"dev": true
},
"which": {

View File

@@ -1,7 +1,7 @@
{
"name": "it-tools",
"description": "",
"version": "1.0.0",
"version": "1.7.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@@ -10,12 +10,19 @@
},
"dependencies": {
"axios": "^0.19.2",
"bip39": "^3.0.2",
"color-convert": "^2.0.1",
"color-name": "^1.1.4",
"core-js": "^3.6.4",
"cron-validator": "^1.1.1",
"cronstrue": "^1.96.0",
"dompurify": "^2.0.11",
"marked": "^1.1.0",
"qrcode.vue": "^1.7.0",
"register-service-worker": "^1.7.1",
"roboto-fontface": "*",
"vue": "^2.6.11",
"vue-analytics": "^5.22.1",
"vue-cryptojs": "^2.1.4",
"vue-headful": "^2.1.0",
"vue-router": "^3.1.6",
@@ -35,6 +42,7 @@
"less": "^3.0.4",
"less-loader": "^5.0.0",
"lint-staged": "^9.5.0",
"raw-loader": "^4.0.1",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-vuetify": "~2.0.5",

9
public/browserconfig.xml Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="./img/icons/mstile-150x150.png"/>
<TileColor>#2d89ef</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 15 KiB

5
public/humans.txt Normal file
View File

@@ -0,0 +1,5 @@
/* TEAM */
Developer: Corentin Thomasset
Site: https://github.com/CorentinTh
Twitter: @cthmsst

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -2,148 +2,50 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="16.000000pt" height="16.000000pt" viewBox="0 0 16.000000 16.000000"
width="1024.000000pt" height="1024.000000pt" viewBox="0 0 1024.000000 1024.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,16.000000) scale(0.000320,-0.000320)"
<g transform="translate(0.000000,1024.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M18 46618 c45 -75 122 -207 122 -211 0 -2 25 -45 55 -95 30 -50 55
-96 55 -102 0 -5 5 -10 10 -10 6 0 10 -4 10 -9 0 -5 73 -135 161 -288 89 -153
173 -298 187 -323 14 -25 32 -57 41 -72 88 -149 187 -324 189 -335 2 -7 8 -13
13 -13 5 0 9 -4 9 -10 0 -5 46 -89 103 -187 175 -302 490 -846 507 -876 8 -16
20 -36 25 -45 28 -46 290 -498 339 -585 13 -23 74 -129 136 -236 61 -107 123
-215 137 -240 14 -25 29 -50 33 -56 5 -5 23 -37 40 -70 18 -33 38 -67 44 -75
11 -16 21 -33 63 -109 14 -25 29 -50 33 -56 4 -5 21 -35 38 -65 55 -100 261
-455 269 -465 4 -5 14 -21 20 -35 15 -29 41 -75 103 -180 24 -41 52 -88 60
-105 9 -16 57 -100 107 -185 112 -193 362 -626 380 -660 8 -14 23 -38 33 -55
11 -16 23 -37 27 -45 4 -8 26 -46 48 -85 23 -38 53 -90 67 -115 46 -81 64
-113 178 -310 62 -107 121 -210 132 -227 37 -67 56 -99 85 -148 16 -27 32 -57
36 -65 4 -8 15 -27 25 -42 9 -15 53 -89 96 -165 44 -76 177 -307 296 -513 120
-206 268 -463 330 -570 131 -227 117 -203 200 -348 36 -62 73 -125 82 -140 10
-15 21 -34 25 -42 4 -8 20 -37 36 -65 17 -27 38 -65 48 -82 49 -85 64 -111 87
-153 13 -25 28 -49 32 -55 4 -5 78 -134 165 -285 87 -151 166 -288 176 -305
10 -16 26 -43 35 -59 9 -17 125 -217 257 -445 132 -229 253 -441 270 -471 17
-30 45 -79 64 -108 18 -29 33 -54 33 -57 0 -2 20 -37 44 -77 24 -40 123 -212
221 -383 97 -170 190 -330 205 -355 16 -25 39 -65 53 -90 13 -25 81 -144 152
-265 70 -121 137 -238 150 -260 12 -22 37 -65 55 -95 18 -30 43 -73 55 -95 12
-22 48 -85 80 -140 77 -132 163 -280 190 -330 13 -22 71 -123 130 -225 59
-102 116 -199 126 -217 10 -17 29 -50 43 -72 15 -22 26 -43 26 -45 0 -2 27
-50 60 -106 33 -56 60 -103 60 -105 0 -2 55 -98 90 -155 8 -14 182 -316 239
-414 13 -22 45 -79 72 -124 27 -46 49 -86 49 -89 0 -2 14 -24 30 -48 16 -24
30 -46 30 -49 0 -5 74 -135 100 -176 5 -8 24 -42 43 -75 50 -88 58 -101 262
-455 104 -179 199 -345 213 -370 14 -25 28 -49 32 -55 4 -5 17 -26 28 -45 10
-19 62 -109 114 -200 114 -197 133 -230 170 -295 16 -27 33 -57 38 -65 17 -28
96 -165 103 -180 4 -8 16 -28 26 -45 10 -16 77 -131 148 -255 72 -124 181
-313 243 -420 62 -107 121 -209 131 -227 35 -62 323 -560 392 -678 38 -66 83
-145 100 -175 16 -30 33 -59 37 -65 4 -5 17 -27 29 -47 34 -61 56 -100 90
-156 17 -29 31 -55 31 -57 0 -2 17 -32 39 -67 21 -35 134 -229 251 -433 117
-203 235 -407 261 -451 27 -45 49 -85 49 -88 0 -4 8 -19 19 -34 15 -21 200
-341 309 -533 10 -19 33 -58 51 -87 17 -29 31 -54 31 -56 0 -2 25 -44 55 -94
30 -50 55 -95 55 -98 0 -4 6 -15 14 -23 7 -9 27 -41 43 -71 17 -30 170 -297
342 -594 171 -296 311 -542 311 -547 0 -5 5 -9 10 -9 6 0 10 -4 10 -10 0 -5
22 -47 49 -92 27 -46 58 -99 68 -118 24 -43 81 -140 93 -160 5 -8 66 -114 135
-235 69 -121 130 -227 135 -235 12 -21 259 -447 283 -490 10 -19 28 -47 38
-62 11 -14 19 -29 19 -32 0 -3 37 -69 83 -148 99 -170 305 -526 337 -583 13
-22 31 -53 41 -70 11 -16 22 -37 26 -45 7 -14 82 -146 103 -180 14 -24 181
-311 205 -355 13 -22 46 -80 75 -130 29 -49 64 -110 78 -135 14 -25 51 -88 82
-140 31 -52 59 -102 63 -110 4 -8 18 -33 31 -55 205 -353 284 -489 309 -535
17 -30 45 -78 62 -106 18 -28 36 -60 39 -72 4 -12 12 -22 17 -22 5 0 9 -4 9
-10 0 -5 109 -197 241 -427 133 -230 250 -431 259 -448 51 -90 222 -385 280
-485 37 -63 78 -135 92 -160 14 -25 67 -117 118 -205 51 -88 101 -175 111
-193 34 -58 55 -95 149 -257 51 -88 101 -173 110 -190 9 -16 76 -131 147 -255
72 -124 140 -241 151 -260 61 -108 281 -489 355 -615 38 -66 77 -133 87 -150
35 -63 91 -161 100 -175 14 -23 99 -169 128 -220 54 -97 135 -235 142 -245 4
-5 20 -32 35 -60 26 -48 238 -416 276 -480 10 -16 26 -46 37 -65 30 -53 382
-661 403 -695 10 -16 22 -37 26 -45 4 -8 26 -48 50 -88 24 -41 43 -75 43 -77
0 -2 22 -40 50 -85 27 -45 50 -84 50 -86 0 -3 38 -69 83 -147 84 -142 302
-520 340 -587 10 -19 34 -60 52 -90 18 -30 44 -75 57 -100 14 -25 45 -79 70
-120 25 -41 56 -96 70 -121 14 -25 77 -133 138 -240 62 -107 122 -210 132
-229 25 -43 310 -535 337 -581 11 -19 26 -45 34 -59 17 -32 238 -414 266 -460
11 -19 24 -41 28 -49 3 -7 75 -133 160 -278 84 -146 153 -269 153 -274 0 -5 5
-9 10 -9 6 0 10 -4 10 -10 0 -5 82 -150 181 -322 182 -314 201 -346 240 -415
12 -21 80 -139 152 -263 71 -124 141 -245 155 -270 14 -25 28 -49 32 -55 6 -8
145 -248 220 -380 37 -66 209 -362 229 -395 11 -19 24 -42 28 -49 4 -8 67
-118 140 -243 73 -125 133 -230 133 -233 0 -2 15 -28 33 -57 19 -29 47 -78 64
-108 17 -30 53 -93 79 -139 53 -90 82 -141 157 -272 82 -142 115 -199 381
-659 142 -245 268 -463 281 -485 12 -22 71 -125 132 -230 60 -104 172 -298
248 -430 76 -132 146 -253 156 -270 11 -16 22 -36 26 -44 3 -8 30 -54 60 -103
29 -49 53 -91 53 -93 0 -3 18 -34 40 -70 22 -36 40 -67 40 -69 0 -2 37 -66 81
-142 45 -77 98 -168 119 -204 20 -36 47 -81 58 -100 12 -19 27 -47 33 -62 6
-16 15 -28 20 -28 5 0 9 -4 9 -9 0 -6 63 -118 140 -251 77 -133 140 -243 140
-245 0 -2 18 -33 41 -70 22 -37 49 -83 60 -101 10 -19 29 -51 40 -71 25 -45
109 -189 126 -218 7 -11 17 -29 22 -40 6 -11 22 -38 35 -60 14 -22 37 -62 52
-90 14 -27 35 -62 45 -77 11 -14 19 -29 19 -32 0 -3 18 -35 40 -71 22 -36 40
-67 40 -69 0 -2 19 -35 42 -72 23 -38 55 -94 72 -124 26 -47 139 -244 171
-298 6 -9 21 -36 34 -60 28 -48 37 -51 51 -19 6 12 19 36 29 52 10 17 27 46
38 65 11 19 104 181 208 360 103 179 199 345 213 370 14 25 42 74 64 109 21
34 38 65 38 67 0 2 18 33 40 69 22 36 40 67 40 69 0 3 177 310 199 346 16 26
136 234 140 244 2 5 25 44 52 88 27 44 49 81 49 84 0 2 18 34 40 70 22 36 40
67 40 69 0 2 20 36 43 77 35 58 169 289 297 513 9 17 50 86 90 155 40 69 86
150 103 180 16 30 35 62 41 70 6 8 16 24 22 35 35 64 72 129 167 293 59 100
116 199 127 220 11 20 30 53 41 72 43 72 1070 1850 1121 1940 14 25 65 113
113 195 48 83 96 166 107 185 10 19 28 50 38 68 11 18 73 124 137 235 64 111
175 303 246 427 71 124 173 299 225 390 52 91 116 202 143 248 27 45 49 85 49
89 0 4 6 14 14 22 7 9 28 43 46 76 26 47 251 436 378 655 11 19 29 51 40 70
11 19 101 176 201 348 99 172 181 317 181 323 0 5 5 9 10 9 6 0 10 5 10 11 0
6 8 23 18 37 11 15 32 52 49 82 16 30 130 228 253 440 122 212 234 405 248
430 13 25 39 70 57 100 39 65 69 117 130 225 25 44 50 87 55 95 12 19 78 134
220 380 61 107 129 224 150 260 161 277 222 382 246 425 15 28 47 83 71 123
24 41 43 78 43 83 0 5 4 9 8 9 4 0 13 12 19 28 7 15 23 45 36 67 66 110 277
478 277 483 0 3 6 13 14 21 7 9 27 41 43 71 17 30 45 80 63 110 34 57 375 649
394 685 6 11 16 27 22 35 6 8 26 42 44 75 18 33 41 74 51 90 10 17 24 41 32
55 54 97 72 128 88 152 11 14 19 28 19 30 0 3 79 141 175 308 96 167 175 305
175 308 0 3 6 13 14 21 7 9 26 39 41 66 33 60 276 483 338 587 24 40 46 80 50
88 4 8 13 24 20 35 14 23 95 163 125 215 11 19 52 91 92 160 40 69 80 139 90
155 9 17 103 179 207 360 105 182 200 346 211 365 103 181 463 802 489 845 7
11 15 27 19 35 4 8 29 51 55 95 64 110 828 1433 848 1470 9 17 24 41 33 55 9
14 29 48 45 77 15 28 52 93 82 145 30 51 62 107 71 123 17 30 231 398 400 690
51 88 103 179 115 202 12 23 26 48 32 55 6 7 24 38 40 68 17 30 61 107 98 170
37 63 84 144 103 180 19 36 41 72 48 81 8 8 14 18 14 21 0 4 27 51 59 106 32
55 72 124 89 154 16 29 71 125 122 213 51 88 104 180 118 205 13 25 28 50 32
55 4 6 17 26 28 45 11 19 45 80 77 135 31 55 66 116 77 135 11 19 88 152 171
295 401 694 620 1072 650 1125 11 19 87 152 170 295 83 143 158 273 166 288 9
16 21 36 26 45 6 9 31 52 55 96 25 43 54 94 66 115 11 20 95 164 186 321 91
157 173 299 182 315 9 17 26 46 37 65 12 19 66 114 121 210 56 96 108 186 117
200 8 14 24 40 34 59 24 45 383 664 412 713 5 9 17 29 26 45 15 28 120 210
241 419 36 61 68 117 72 125 4 8 12 23 19 34 35 57 245 420 262 453 11 20 35
61 53 90 17 29 32 54 32 56 0 3 28 51 62 108 33 57 70 119 80 138 10 19 23 42
28 50 5 8 32 53 59 100 27 47 149 258 271 470 122 212 234 405 248 430 30 53
62 108 80 135 6 11 15 27 19 35 4 8 85 150 181 315 96 165 187 323 202 350 31
56 116 202 130 225 5 8 25 42 43 75 19 33 92 159 162 280 149 257 157 271 202
350 19 33 38 67 43 75 9 14 228 392 275 475 12 22 55 96 95 165 40 69 80 139
90 155 24 42 202 350 221 383 9 15 27 47 41 72 14 25 75 131 136 236 61 106
121 210 134 232 99 172 271 470 279 482 5 8 23 40 40 70 18 30 81 141 142 245
60 105 121 210 135 235 14 25 71 124 127 220 56 96 143 247 194 335 51 88 96
167 102 175 14 24 180 311 204 355 23 43 340 590 356 615 5 8 50 87 101 175
171 301 517 898 582 1008 25 43 46 81 46 83 0 2 12 23 27 47 14 23 40 67 56
97 16 30 35 62 42 70 7 8 15 22 18 30 4 8 20 38 37 65 16 28 33 57 37 65 6 12
111 196 143 250 5 8 55 95 112 193 57 98 113 195 126 215 12 20 27 46 32 57 6
11 14 27 20 35 5 8 76 130 156 270 80 140 165 287 187 325 23 39 52 90 66 115
13 25 30 52 37 61 8 8 14 18 14 21 0 4 41 77 92 165 50 87 175 302 276 478
101 176 208 360 236 408 28 49 67 117 86 152 19 35 41 70 48 77 6 6 12 15 12
19 0 7 124 224 167 291 12 21 23 40 23 42 0 2 21 40 46 83 26 43 55 92 64 109
54 95 327 568 354 614 19 30 45 75 59 100 71 128 82 145 89 148 4 2 8 8 8 13
0 5 42 82 94 172 311 538 496 858 518 897 14 25 40 70 58 100 18 30 42 71 53
90 10 19 79 139 152 265 73 127 142 246 153 265 10 19 43 76 72 125 29 50 63
108 75 130 65 116 80 140 87 143 4 2 8 8 8 12 0 8 114 212 140 250 6 8 14 24
20 35 5 11 54 97 108 190 l100 170 -9611 3 c-5286 1 -9614 -1 -9618 -5 -5 -6
-419 -719 -619 -1068 -89 -155 -267 -463 -323 -560 -38 -66 -81 -140 -95 -165
-31 -56 -263 -457 -526 -910 -110 -190 -224 -388 -254 -440 -29 -52 -61 -109
-71 -125 -23 -39 -243 -420 -268 -465 -11 -19 -204 -352 -428 -740 -224 -388
-477 -826 -563 -975 -85 -148 -185 -322 -222 -385 -37 -63 -120 -207 -185
-320 -65 -113 -177 -306 -248 -430 -72 -124 -172 -297 -222 -385 -51 -88 -142
-245 -202 -350 -131 -226 -247 -427 -408 -705 -65 -113 -249 -432 -410 -710
-160 -278 -388 -673 -506 -877 -118 -205 -216 -373 -219 -373 -3 0 -52 82
-109 183 -58 100 -144 250 -192 332 -95 164 -402 696 -647 1120 -85 149 -228
396 -317 550 -212 365 -982 1700 -1008 1745 -10 19 -43 76 -72 125 -29 50 -64
110 -77 135 -14 25 -63 110 -110 190 -47 80 -96 165 -110 190 -14 25 -99 171
-188 325 -89 154 -174 300 -188 325 -13 25 -64 113 -112 195 -48 83 -140 242
-205 355 -65 113 -183 317 -263 454 -79 137 -152 264 -163 282 -50 89 -335
583 -354 614 -12 19 -34 58 -50 85 -15 28 -129 226 -253 440 -124 215 -235
408 -247 430 -12 22 -69 121 -127 220 -58 99 -226 389 -373 645 -148 256 -324
561 -392 678 -67 117 -134 232 -147 255 -13 23 -33 59 -46 80 l-22 37 -9615 0
-9615 0 20 -32z"/>
<path d="M4368 10130 c-61 -11 -108 -40 -141 -87 -28 -42 -61 -135 -71 -203
-4 -25 -22 -126 -41 -225 -18 -99 -38 -220 -43 -270 -17 -154 -83 -600 -90
-606 -11 -10 -563 -242 -576 -242 -6 0 -210 157 -452 349 -242 193 -457 361
-478 374 -104 63 -210 33 -351 -100 -33 -31 -96 -83 -140 -116 -93 -69 -300
-273 -544 -537 -327 -355 -390 -449 -377 -565 8 -65 32 -104 156 -252 104
-125 402 -513 518 -677 l73 -102 -76 -144 c-53 -102 -90 -189 -125 -300 -50
-153 -50 -155 -82 -161 -18 -3 -287 -44 -598 -91 -311 -47 -583 -92 -605 -101
-54 -21 -72 -39 -109 -109 l-31 -60 0 -790 0 -790 30 -44 c60 -88 68 -90 742
-193 329 -50 600 -92 601 -94 2 -1 14 -45 28 -96 34 -135 64 -212 156 -396
l81 -163 -35 -37 c-19 -20 -75 -89 -123 -152 -49 -63 -139 -178 -200 -255 -61
-77 -131 -169 -155 -205 -24 -36 -75 -102 -113 -147 -52 -62 -74 -98 -88 -144
-41 -132 -20 -197 118 -369 189 -235 897 -930 1030 -1011 48 -29 65 -33 115
-32 73 1 65 -4 620 429 l427 334 150 -74 c82 -42 209 -98 282 -126 73 -28 134
-52 136 -53 1 -2 45 -268 98 -592 52 -325 103 -614 113 -644 14 -44 28 -63 74
-102 53 -44 61 -48 130 -54 40 -3 393 -5 783 -3 l710 3 55 32 c31 17 65 42 77
55 32 34 70 178 88 334 9 76 17 140 19 143 9 15 75 435 81 516 7 95 33 306 38
311 2 2 70 28 153 58 82 30 215 86 297 124 l147 71 438 -348 c240 -191 457
-361 482 -377 25 -17 63 -34 85 -37 50 -8 130 15 165 47 14 13 61 47 105 76
44 29 130 101 190 159 61 59 131 122 156 141 25 19 64 59 85 88 21 30 64 77
94 104 88 80 287 297 338 368 25 36 67 88 92 115 76 82 102 130 108 201 4 54
1 69 -24 118 -15 31 -52 84 -82 118 -30 34 -72 87 -95 117 -113 157 -345 461
-378 498 -21 23 -52 66 -68 96 -17 29 -46 71 -64 92 l-34 39 48 101 c41 86
137 325 185 461 l15 41 612 92 c337 51 623 99 637 106 33 18 100 116 111 163
11 46 11 1502 0 1558 -4 23 -26 65 -50 96 -39 53 -46 57 -109 72 -37 9 -317
54 -622 102 -305 47 -558 89 -562 92 -3 4 -40 93 -82 197 -41 105 -100 246
-130 314 l-55 125 38 45 c20 25 52 73 70 106 19 33 57 87 85 120 29 33 77 96
108 140 31 44 97 130 148 190 51 61 105 135 120 165 15 30 43 69 60 85 72 67
107 156 92 237 -6 29 -28 70 -69 125 -34 45 -75 106 -92 135 -53 93 -905 937
-1010 1003 -59 36 -178 21 -231 -29 -28 -27 -649 -508 -871 -674 l-56 -42
-139 63 c-76 35 -204 90 -284 122 -80 32 -149 61 -153 65 -4 4 -51 290 -103
636 l-95 629 -32 33 c-18 18 -54 47 -82 65 l-50 32 -740 2 c-407 0 -761 -3
-787 -7z m1022 -3360 c119 -22 329 -88 441 -139 143 -65 424 -286 520 -408 29
-38 74 -90 100 -118 72 -77 123 -170 188 -342 100 -265 131 -417 131 -638 0
-239 -32 -394 -138 -671 -58 -151 -105 -232 -208 -361 -162 -202 -379 -381
-609 -501 -67 -35 -301 -102 -440 -126 -118 -21 -395 -21 -501 -1 -147 28
-377 97 -453 135 -195 98 -474 328 -622 514 -86 108 -219 386 -276 579 l-28
92 0 325 c0 324 0 325 28 427 30 111 89 258 169 416 85 171 303 398 553 576
89 64 135 88 240 129 262 101 398 129 626 131 127 1 192 -4 279 -19z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -5,17 +5,20 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<meta itemprop="name">
<meta property="og:title">
<meta name="twitter:title">
<meta name="description"/>
<meta itemprop="description">
<meta property="og:description">
<meta name="twitter:description">
<meta itemprop="image">
<meta property="og:image">
<meta name="twitter:image">
<title>IT Tools - Set of handy developer tools</title>
<link rel="canonical" href="https://it-tools.tech">
<meta itemprop="name" content="IT-Tools">
<meta property="og:title" content="IT-Tools">
<meta name="twitter:title" content="IT-Tools">
<meta name="description" content="Aggregated set of useful tools that every developer may need once in a while.">
<meta itemprop="description" content="Aggregated set of useful tools that every developer may need once in a while.">
<meta property="og:description" content="Aggregated set of useful tools that every developer may need once in a while.">
<meta name="twitter:description" content="Aggregated set of useful tools that every developer may need once in a while.">
<meta itemprop="image" content="/img/banner.png">
<meta property="og:image" content="/img/banner.png">
<meta name="twitter:image" content="/img/banner.png">
<link rel="author" href="humans.txt" />
<meta name="robots" content="noindex">
</head>
<body>
<noscript>

19
public/manifest.json Normal file
View File

@@ -0,0 +1,19 @@
{
"name": "IT Tools",
"short_name": "IT Tools",
"icons": [
{
"src": "./img/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./img/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#4bae50",
"background_color": "#121212",
"display": "standalone"
}

View File

@@ -1,2 +1,2 @@
User-agent: *
Disallow:
Disallow: *

View File

@@ -1,23 +1,24 @@
<template>
<v-app id="inspire">
<vue-headful
:title="currentRoute ? `${currentRoute.text} - IT-Tools` : 'IT-Tools'"
:description="currentRoute ? currentRoute.description: 'Aggregated set of useful tools that every developer may need once in a while.'"
:keywords="currentRoute ? currentRoute.keywords: null"
image="/img/banner.png"
:title="currentRoute ? `${currentRoute.text} - IT Tools` : 'IT Tools - Set of handy developer tools'"
:description="currentRoute ? currentRoute.description: 'Aggregated set of useful tools that every developer may need once in a while.'"
:keywords="currentRoute ? currentRoute.keywords: null"
image="/img/banner.png"
/>
<v-navigation-drawer v-model="drawer" app clipped>
<template v-slot:prepend>
<SearchBar class="hidden-sm-and-up"/>
</template>
<SearchBar class="hidden-sm-and-up" />
<v-list dense>
<v-list dense id="navigation-list">
<div v-for="section in items" :key="section.title">
<v-subheader class="mt-4 pl-4">{{section.title}}</v-subheader>
<v-list-item v-for="item in section.child" :key="item.text" :to="item.path">
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
<v-icon style="width: 1.25em">{{ item.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
@@ -99,7 +100,7 @@
appVersion: 'v' + process.env.APPLICATION_VERSION,
drawer: null,
items: toolsComponents,
currentRoute:{}
currentRoute: {}
}),
mounted() {
this.setTitle()
@@ -107,14 +108,14 @@
created() {
this.$vuetify.theme.dark = true
},
methods:{
setTitle(){
methods: {
setTitle() {
const path = this.$router.currentRoute.path;
this.currentRoute = toolsComponents.map(p => p.child).flat().find(p => p.path === path)
}
},
watch:{
'$route'(){
watch: {
'$route'() {
this.setTitle()
}
}
@@ -125,6 +126,51 @@
html {
overflow-y: auto !important;
}
code{
background-color: rgba(0, 0, 0, 0.15) !important;
box-shadow: none !important;
color: #9a9a9a !important;
font-weight: normal !important;
}
.pretty-scrollbar{
&::-webkit-scrollbar {
width: 5px!important;
height: 5px !important;
}
/* Track */
&::-webkit-scrollbar-track {
opacity: 0 !important;
}
/* Handle */
&::-webkit-scrollbar-thumb {
background: rgba(241, 241, 241, 0.10) !important;
border-radius: 10px;
}
/* Handle on hover */
&::-webkit-scrollbar-thumb:hover {
background: rgba(241, 241, 241, 0.20)!important;
}
}
#navigation-list{
div:first-child .v-subheader{
margin-top: 0 !important;
}
.v-list-item__action{
margin: 8px 25px 8px 0;
.v-icon{
color: #4CAF50 !important;
}
}
}
.v-navigation-drawer__content{
.pretty-scrollbar;
}
.single-card {
width: 100%;

View File

@@ -4,7 +4,9 @@
<p class="text-justify">
Welcome to <strong>IT-Tools</strong>! This wonderful website, originally created with by
<a href="//corentin-thomasset.fr">Corentin Thomasset</a>, aggregate a set of useful tools
that every developer may need once in a while.
that every developer may need once in a while. And don't forget to add <strong>IT-Tools</strong> to your
shortcut bar (press <code>{{ isMacOS ? 'Cmd' : 'Ctrl' }} +
D</code>).
</p>
@@ -30,7 +32,10 @@
<script>
export default {
name: "Abstract"
name: "Abstract",
data: () => ({
isMacOS: navigator.platform.toUpperCase().indexOf('MAC') >= 0
})
}
</script>

View File

@@ -0,0 +1,58 @@
<template>
<v-text-field v-model="color" hide-details class="ma-0 pa-0" outlined :label="label" v-on:input="$emit('input', color)">
<template v-slot:append>
<v-menu v-model="menu" top nudge-bottom="101" nudge-left="16" :close-on-content-click="false">
<template v-slot:activator="{ on }">
<div :style="swatchStyle" v-on="on" />
</template>
<v-card>
<v-card-text class="pa-0">
<v-color-picker v-model="color" flat v-on:input="$emit('input', color)"/>
</v-card-text>
</v-card>
</v-menu>
</template>
</v-text-field>
</template>
<script>
// From: https://codepen.io/JamieCurnow/pen/KKPjraK
export default {
name: "ColorInput",
props:{
value: {
type: String,
default: '#FFFFFF'
},
label:String
},
data: () => ({
menu: false,
color:''
}),
mounted() {
this.color = this.value
},
computed: {
swatchStyle() {
const { color, menu } = this
return {
backgroundColor: color,
cursor: 'pointer',
height: '30px',
width: '30px',
borderRadius: menu ? '50%' : '4px',
transition: 'border-radius 200ms ease-in-out'
}
}
}
}
</script>
<style scoped lang="less">
::v-deep .v-input__append-inner{
margin-top: 13px;
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<div class="copyable-code-content" @click="copy($slots.default[0].text)">
<pre class="pretty-scrollbar"><slot></slot></pre>
<v-icon>far fa-copy</v-icon>
</div>
</template>
<script>
import {copyable} from "../mixins/copyable.mixin";
export default {
name: "CopyableCodeContent",
mixins: [copyable]
}
</script>
<style lang="less" scoped>
.copyable-code-content {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.1);
border-radius: 4px;
padding: 8px 15px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
pre {
flex: 1;
overflow-x: auto;
}
.v-icon {
opacity: 0;
}
&:hover {
.v-icon {
opacity: 1;
}
}
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<div class="github-contributor">
<div v-if="loading" class="text-center pt-3 pb-3">
<v-progress-circular indeterminate />
</div>
<v-list v-else class="pa-0">
<v-list-item v-for="(contributor, i) in contributors" :key="i" :href="contributor.html_url">
<v-list-item-avatar>
<v-img :src="contributor.avatar_url"></v-img>
</v-list-item-avatar>
<v-list-item-content>
{{contributor.login}}
</v-list-item-content>
</v-list-item>
</v-list>
</div>
</template>
<script>
const baseUrl = 'https://api.github.com/repos/$repo$/contributors'
import axios from 'axios'
export default {
name: "GithubContributors",
props: ['repo'],
data: () => ({
contributors: [],
loading: true,
hasError: false
}),
mounted() {
const url = baseUrl.replace('$repo$', this.repo)
axios
.get(url)
.then(({data}) => {
this.contributors = data.sort((a, b) => b.contributions - a.contributions)
this.loading = false
})
.catch(() => this.hasError = true)
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,73 @@
<template>
<div class="memo-viewer" v-bind:style="{ columns: `auto ${colWidth}` }">
<div class="section" v-for="(group,i) in memo" :key="i">
<h2>{{group.section}}</h2>
<div class="tip" v-for="(tips,i) in group.child" :key="i">
<v-card>
<v-card-text>
<template v-for="tip in (Array.isArray(tips) ? tips : [tips])">
<p :key="tip.text">{{tip.text}}</p>
<CopyableCodeContent class="code" :key="tip.code">{{tip.code}}</CopyableCodeContent>
</template>
</v-card-text>
</v-card>
</div>
</div>
</div>
</template>
<script>
import CopyableCodeContent from "./CopyableCodeContent";
export default {
name: "MemoViewer",
props: {
memo: Array,
colWidth: {
type: String,
default: '400px'
}
},
components: {
CopyableCodeContent
}
}
</script>
<style lang="less" scoped>
.memo-viewer {
column-gap: 30px;
column-rule: 1px solid #37373961;
column-fill: auto;
}
.section {
break-inside: avoid-column;
display: inline-block;
margin-bottom: 20px;
width: 100%;
h2 {
margin: 25px 0 15px;
display: inline-block;
}
.tip {
margin: 20px 0;
.v-card{
background-color: rgba(47, 46, 46, 0.44);
}
p {
margin-bottom: 10px;
&:not(:first-child){
margin-top: 16px;
}
}
}
}
</style>

View File

@@ -8,6 +8,7 @@ import '@fortawesome/fontawesome-free/css/all.css'
import './plugins/crypto-js'
import './plugins/toast-snackbar'
import './plugins/vue-headful'
import './plugins/vue-analytics'
Vue.config.productionTip = false

View File

@@ -0,0 +1,10 @@
import {copyToClipboard} from "../utils/helpers";
export const copyable = {
methods: {
copy(text, toastText = 'Copied to clipboard !'){
copyToClipboard(text);
this.$toast.success(toastText)
}
}
}

View File

@@ -0,0 +1,16 @@
import Vue from 'vue'
import VueAnalytics from 'vue-analytics'
import router from "../router";
if(process.env.VUE_APP_GANALYTICS){
Vue.use(VueAnalytics, {
id: process.env.VUE_APP_GANALYTICS,
router,
set:[
{
field: 'dimension1',
value: process.env.APPLICATION_VERSION
}
]
})
}

View File

@@ -20,7 +20,8 @@ if (process.env.NODE_ENV === 'production') {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
console.log('New content is available; hard refresh.');
window.location.reload(true);
},
offline () {
console.log('No internet connection found. App is running in offline mode.')

View File

@@ -1,20 +1,9 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './routes/Home.vue'
import TokenGenerator from "./routes/tools/TokenGenerator";
import Hash from "./routes/tools/Hash";
import DateConverter from "./routes/tools/DateConverter";
import UrlEncoder from "./routes/tools/UrlEncoder";
import FileToBase64 from "./routes/tools/FileToBase64";
import TextCypher from "./routes/tools/TextCypher";
import TextStats from "./routes/tools/TextStats";
import BaseConverter from "./routes/tools/BaseConverter";
import UuidGenerator from "./routes/tools/UuidGenerator";
import ColorConverter from "./routes/tools/ColorConverter";
Vue.use(VueRouter)
const toolsComponents = [
{
title: 'Crypto',
@@ -23,7 +12,7 @@ const toolsComponents = [
icon: 'fa-key',
text: 'Token generator',
path: '/token-generator',
component: TokenGenerator,
component: () => import('./routes/tools/TokenGenerator'),
keywords: ['token', 'random', 'string', 'alphanumeric'],
description: 'Generate random tokens.'
},
@@ -31,14 +20,14 @@ const toolsComponents = [
icon: 'fa-fingerprint',
text: 'Uuid generator',
path: '/uuid-generator',
component: UuidGenerator,
component: () => import('./routes/tools/UuidGenerator'),
keywords: ['token', 'v4', 'string', 'alphanumeric']
},
{
icon: 'fa-font',
text: 'Hash text',
path: '/hash',
component: Hash,
component: () => import('./routes/tools/Hash'),
keywords: ['md5', 'sha1', 'sha256', 'sha224', 'sha512', 'sha384', 'sha3', 'ripemd160', 'random']
},
@@ -46,9 +35,16 @@ const toolsComponents = [
icon: 'fa-lock',
text: 'Cypher/uncypher text',
path: '/cypher',
component: TextCypher,
component: () => import('./routes/tools/TextCypher'),
keywords: ['aes', 'tripledes', 'rabbit', 'rabbitlegacy', 'rc4']
},
{
icon: 'fa-file-word',
text: 'BIP39 passphrase generator',
path: '/bip39-generator',
component: () => import('./routes/tools/BIP39Generator'),
keywords: []
},
],
},
{
@@ -58,21 +54,21 @@ const toolsComponents = [
icon: 'fa-calendar',
text: 'Date/Time converter',
path: '/date-converter',
component: DateConverter,
component: () => import('./routes/tools/DateConverter'),
keywords: ['locale', 'format', 'iso 8601', 'utc', 'timestamp', 'unix', 'year', 'month', 'day', 'hours', 'minutes', 'seconds']
},
{
icon: 'fa-exchange-alt',
text: 'Base converter',
path: '/base-converter',
component: BaseConverter,
component: () => import('./routes/tools/BaseConverter'),
keywords: ['binary', 'hexadecimal', 'decimal']
},
{
icon: 'fa-palette',
text: 'Color picker/converter',
path: '/color-picker-converter',
component: ColorConverter,
component: () => import('./routes/tools/ColorConverter'),
keywords: ['rgb', 'rgba', 'hexadecimal', 'hsla', 'red', 'green', 'blue', 'alpha']
},
],
@@ -84,28 +80,79 @@ const toolsComponents = [
icon: 'fa-link',
text: 'URL encode/decode',
path: '/url-encoder',
component: UrlEncoder,
component: () => import('./routes/tools/UrlEncoder'),
keywords: ['%20']
},
{
icon: 'fa-file-export',
text: 'File to Base64',
path: '/file-to-base64',
component: FileToBase64
component: () => import('./routes/tools/FileToBase64')
},
{
icon: 'fa-file-alt',
text: 'Base64 string converter',
path: '/base64-string-converter',
component: () => import('./routes/tools/StringToBase64')
}
],
},
{
title: 'Text',
child: [
{
icon: 'fa-align-left',
text: 'Text stats',
path: '/text-stats',
component: () => import('./routes/tools/TextStats'),
keywords: ['word', 'count', 'size', 'bytes', 'length']
},
{
icon: 'fab fa-markdown',
text: 'Markdown editor',
path: '/markdown-editor',
component: () => import('./routes/tools/MarkdownEditor'),
keywords: ['text', 'html', 'markdown']
},
{
icon: 'fa-align-justify',
text: 'Lorem ipsum generator',
path: '/lorem-ipsum-generator',
component: () => import('./routes/tools/LoremIpsumGenerator'),
keywords: ['text', 'dolor', 'sit', 'placeholder', 'fill', 'dummy']
}
],
},
{
title: 'Memos',
child: [
{
text: 'Git memo',
path: '/git-memo',
icon: 'fa-code-branch',
component: () => import('./routes/tools/GitMemo'),
keywords: ['git', 'push', 'rebase', 'merge', 'tag', 'commit', 'checkout']
}
]
},
{
title: 'Miscellaneous',
child: [
{
icon: 'fa-align-left\n',
text: 'Text stats',
path: '/text-stats',
component: TextStats,
keywords: ['word', 'count', 'size', 'bytes', 'length']
text: 'Crontab generator',
path: '/crontab-generator',
icon: 'fa-clock',
component: () => import('./routes/tools/CrontabGenerator'),
keywords: ['Cron', 'Schedule']
},
],
{
text: 'QR Code generator',
path: '/qrcode-generator',
icon: 'fa-qrcode',
component: () => import('./routes/tools/QRCodeGenerator'),
keywords: []
}
]
}
];
@@ -121,12 +168,17 @@ const routes = [
path: '/about',
name: 'About',
component: () => import('./routes/About.vue')
},
{
path: '*',
name: '404',
component: () => import('./routes/NotFound.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
mode: 'history',
routes
});

View File

@@ -1,19 +1,63 @@
<template>
<v-card class="single-card">
<v-card-title>About</v-card-title>
<v-card-text>
<Abstract />
</v-card-text>
</v-card>
<div>
<v-row justify="center" align="center">
<v-col cols="12" xl="12">
<v-card class="single-card">
<v-card-title>About</v-card-title>
<v-card-text>
<Abstract/>
</v-card-text>
</v-card>
</v-col>
</v-row>
<v-row justify="center">
<v-col cols="12" md="5" sm="12">
<v-card>
<v-card-title>Contributors</v-card-title>
<github-contributors repo="CorentinTh/it-tools"/>
</v-card>
</v-col>
<v-col cols="12" md="7" sm="12">
<v-card>
<v-card-title>Changelog</v-card-title>
<v-card-text>
<div v-html="changelog" class="changelog">
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import Abstract from "../components/Abstract";
import Abstract from "../components/Abstract";
import GithubContributors from "../components/GithubContributors";
import changelog from "../../CHANGELOG.md"
import marked from 'marked'
import DOMPurify from 'dompurify';
export default {
name: "About",
components : {
Abstract
},
}
</script>
export default {
name: "About",
data: () => ({
changelog: []
}),
mounted() {
this.changelog = DOMPurify.sanitize(marked('##' + changelog.replace(/^(.*?)##/s, '')));
},
components: {
Abstract,
GithubContributors
},
}
</script>
<style scoped lang="less">
::v-deep {
.changelog {
h2 {
margin-top: 10px;
}
}
}
</style>

View File

@@ -9,9 +9,7 @@
</v-card-text>
</v-card>
</v-col>
</v-row>
<v-row justify="center" align="center">
<v-col cols="12" lg="8" md="12">
<v-col cols="12" lg="5" md="12">
<v-card class="card-auto">
<v-card-text>
<div class="card-wrapper ">
@@ -56,7 +54,7 @@
flex-wrap: wrap;
div {
flex: 0 1 20%;
flex: 0 1 33%;
@media only screen and (max-width: 800px) {
flex: 0 1 33%;

54
src/routes/NotFound.vue Normal file
View File

@@ -0,0 +1,54 @@
<template>
<div class="e404">
<div class="e404-image">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 100 511.999 300" xml:space="preserve">
<g><path d="M140.61,273.063h-5.956v-22.69c0-11.623-10.593-19.433-26.358-19.433s-26.357,7.81-26.357,19.433v22.69H65.571 l25.677-100.707c1.101-2.746,1.194-5.749,1.186-8.392l-0.001-0.284c0-15.632-22.966-20.737-30.881-20.737 c-10.132,0-18.414,5.148-22.723,14.123c-0.199,0.415-0.359,0.847-0.481,1.29C0,298.98,0,300.981,0,302.305 c0,12.096,8.537,20.876,20.297,20.876H33.97c4.2,0,7.604-3.405,7.604-7.604c0-4.199-3.404-7.604-7.604-7.604H20.297 c-3.184,0-4.887-1.694-5.072-5.04c1.954-8.608,23.256-87.252,37.593-139.831c1.785-3.288,4.721-4.954,8.734-4.954 c5.289,0,14.355,3.338,15.673,5.732l0.001,0.128c0.001,0.584,0.006,2.084-0.132,2.756c-0.178,0.397-0.321,0.809-0.43,1.231 L48.417,278.788c-0.58,2.275-0.076,4.69,1.365,6.544c1.44,1.854,3.656,2.938,6.004,2.938h33.757c4.2,0,7.604-3.405,7.604-7.604 v-30.294c0-2.528,5.766-4.225,11.149-4.225c5.481,0,11.15,1.581,11.15,4.225v30.294c0,4.199,3.404,7.604,7.604,7.604h13.56 c2.252,0,4.226,4.671,4.226,9.996c0,5.013-3.022,9.171-4.382,9.708H127.05c-4.2,0-7.604,3.405-7.604,7.604v34.045 c0,1.954-4.872,4.225-11.15,4.225c-6.467,0-11.149-2.523-11.149-4.225v-34.045c0-4.199-3.404-7.604-7.604-7.604H59.318 c-4.2,0-7.604,3.405-7.604,7.604c0,4.199,3.404,7.604,7.604,7.604h22.621v26.441c0,11.26,11.086,19.433,26.357,19.433 c15.52,0,26.358-7.991,26.358-19.433v-26.441h5.956c9.192,0,19.434-10.232,19.434-24.916 C160.043,283.663,151.87,273.063,140.61,273.063z"/></g>
<g><path d="M492.566,273.063h-5.956v-22.69c0-11.623-10.593-19.433-26.358-19.433s-26.357,7.81-26.357,19.433v22.69h-16.368 l25.679-100.708c1.1-2.745,1.193-5.75,1.185-8.393l-0.001-0.281c0-15.632-22.966-20.737-30.881-20.737 c-10.132,0-18.415,5.148-22.724,14.123c-0.199,0.415-0.359,0.847-0.481,1.29c0,0-4.869,17.852-11.125,40.898 c0,0.001,0,0.002-0.001,0.003l-7.879,29.071c-19.345,71.527-19.345,72.449-19.345,73.978c0,12.096,8.537,20.876,20.298,20.876 h61.64v26.441c0,11.26,11.085,19.433,26.357,19.433c15.52,0,26.358-7.991,26.358-19.433v-26.441h5.956 c9.192,0,19.434-10.232,19.434-24.915C512,283.663,503.826,273.063,492.566,273.063z M492.41,307.974h-13.404 c-4.2,0-7.604,3.405-7.604,7.604v34.045c0,1.954-4.872,4.225-11.15,4.225c-6.467,0-11.149-2.523-11.149-4.225v-34.045 c0-4.199-3.404-7.604-7.604-7.604h-69.244c-3.183,0-4.887-1.694-5.073-5.037c0.677-2.966,4.201-16.655,18.801-70.634l7.877-29.064 c5.504-20.276,9.934-36.53,10.916-40.133c1.785-3.288,4.721-4.954,8.735-4.954c5.289,0,14.354,3.338,15.673,5.732l0.001,0.124 c0.001,0.585,0.006,2.09-0.133,2.762c-0.177,0.396-0.32,0.808-0.429,1.23l-28.249,110.79c-0.58,2.275-0.076,4.69,1.365,6.544 c1.44,1.854,3.656,2.938,6.004,2.938H441.5c4.2,0,7.604-3.405,7.604-7.604v-30.294c0-2.528,5.766-4.225,11.149-4.225 c5.481,0,11.15,1.581,11.15,4.225v30.294c0,4.199,3.404,7.604,7.604,7.604h13.56c2.252,0,4.226,4.671,4.226,9.996 C496.792,303.281,493.769,307.437,492.41,307.974z"/></g>
<g><path d="M330.892,206.939c-2.512-3.363-7.279-4.051-10.642-1.536c-3.362,2.515-4.05,7.281-1.535,10.643 c10.168,13.597,15.542,29.786,15.542,46.818c0,43.149-35.104,78.252-78.252,78.252c-43.15,0-78.253-35.104-78.253-78.252 c0-43.149,35.104-78.253,78.253-78.253c17.152,0,33.434,5.444,47.083,15.744c3.353,2.53,8.122,1.863,10.651-1.49 c2.529-3.352,1.862-8.12-1.49-10.65c-16.311-12.307-35.76-18.812-56.245-18.812c-51.534,0-93.461,41.927-93.461,93.461 s41.927,93.46,93.461,93.46c51.534,0,93.46-41.926,93.46-93.46C349.464,242.523,343.042,223.185,330.892,206.939z"/></g>
<g><path d="M296.624,292.726l-29.863-29.863L296.624,233c2.968-2.969,2.968-7.783-0.002-10.753c-2.971-2.97-7.784-2.97-10.754,0 l-29.863,29.863l-29.863-29.863c-2.971-2.97-7.784-2.97-10.754,0c-2.97,2.97-2.97,7.784,0,10.753l29.863,29.863l-29.863,29.863 c-2.97,2.97-2.97,7.784,0,10.753c1.485,1.484,3.432,2.227,5.378,2.227c1.946,0,3.892-0.742,5.377-2.227l29.863-29.863 l29.863,29.863c1.485,1.484,3.432,2.227,5.377,2.227s3.892-0.742,5.378-2.227C299.593,300.51,299.593,295.695,296.624,292.726z"/></g>
</svg>
</div>
<div class="separator"></div>
<div class="e404-description">
Page not found, sorry.
</div>
<v-btn color="primary" @click="$router.go(-1)">Back</v-btn>
</div>
</template>
<script>
export default {
name: "404.vue"
}
</script>
<style scoped lang="less">
.e404 {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.e404-image {
width: 200px;
svg {
fill: #ffffff;
opacity: 0.3;
}
}
.separator {
width: 60px;
height: 3px;
border-radius: 5px;
background-color: #4CAF50;
}
.e404-description {
font-size: 30px;
opacity: 0.9;
margin: 15px 0;
}
}
</style>

View File

@@ -0,0 +1,99 @@
<template>
<v-card class="single-card">
<v-card-title>BIP39 passphrase generator</v-card-title>
<v-card-text>
<v-select
outlined
label="Language"
@change="languageChanged"
:items="languageList"
v-model="language"
/>
<v-text-field
outlined
v-model="entropy"
label="Entropy"
append-icon="fa-clipboard"
@click:append="copy(entropy)"
:rules="rules.entropy"
ref="entropy"
/>
<v-text-field
outlined
v-model="passphrase"
label="Passphrase"
append-icon="fa-clipboard"
@click:append="copy(passphrase)"
:rules="rules.passphrase"
ref="passphrase"
/>
<div class="text-center">
<v-btn @click="refresh">refresh</v-btn>
</div>
</v-card-text>
</v-card>
</template>
<script>
import * as bip39 from "bip39";
import {copyable} from "../../mixins/copyable.mixin";
const shuffle = (str) => str.split('').sort(() => 0.5 - Math.random()).join('');
const getRandomBuffer = () => {
return Buffer.from(shuffle('0123456789abcdef'.repeat(16)).substring(0, 32), 'hex');
}
export default {
name: 'BIP39Generator',
mixins: [copyable],
data: () => ({
buffer: getRandomBuffer(),
languageList: Object.keys(bip39.wordlists).filter(k => !k.match(/[A-Z]{2}/)).map(k => ({text: k.split('_').map(k => k.charAt(0).toUpperCase() + k.slice(1)).join(' '), value:k})),
language: 'english',
rules: {
passphrase: [
v => (!!v && bip39.validateMnemonic(v)) || 'Invalid mnemonic.'
],
entropy: [
v => (!!v && !!v.match(/[0-9a-fA-F]{32}/)) || 'Invalid entropy.'
]
}
}),
methods:{
refresh(){
this.buffer = getRandomBuffer();
},
languageChanged(){
bip39.setDefaultWordlist(this.language);
this.passphrase = bip39.entropyToMnemonic(this.buffer)
}
},
computed: {
entropy: {
get() {
return this.buffer.toString('hex')
},
set(value) {
if(this.$refs.entropy.validate()) {
this.buffer = Buffer.from(value, 'hex')
}
}
},
passphrase: {
get() {
return bip39.entropyToMnemonic(this.buffer)
},
set(value) {
if(this.$refs.passphrase.validate()){
this.buffer = Buffer.from(bip39.mnemonicToEntropy(value), 'hex')
}
}
}
}
}
</script>
<style scoped>
</style>

View File

@@ -8,7 +8,8 @@
label="Input base"
outlined
type="number"
v-model="inputBase"
v-model.number="inputBase"
ref="inputBase"
hide-details="auto"
:rules="baseRules"
/>
@@ -32,7 +33,8 @@
label="Output base"
outlined
type="number"
v-model="outputBase"
v-model.number="outputBase"
ref="outputBase"
:rules="baseRules"
/>
</v-col>
@@ -54,7 +56,7 @@
</template>
<script>
import {copyToClipboard} from "../../utils/helpers";
import {copyToClipboard, isInt} from "../../utils/helpers";
const convertBase = (value, fromBase, toBase) => {
const range = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/'.split('');
@@ -83,12 +85,17 @@
inputBase: 10,
outputBase: 16,
baseRules: [
v => isInt(v) || 'Base should be an integer',
v => !!v || 'Required',
v => v > 1 || 'Base should be > 1',
v => v <= 64 || 'Base should be <= 64',
v => v <= 64 || 'Base should be <= 64'
],
isMounted: false
}
},
mounted() {
this.isMounted = true;
},
methods: {
copy() {
copyToClipboard(this.outputNumber);
@@ -97,10 +104,14 @@
},
computed: {
outputNumber() {
try{
return convertBase(this.inputNumber, this.inputBase, this.outputBase)
}catch (e) {
return e.message;
if(this.isMounted && this.$refs.inputBase.validate() && this.$refs.outputBase.validate()){
try{
return convertBase(this.inputNumber, this.inputBase, this.outputBase)
}catch (e) {
return e.message;
}
}else {
return ''
}
}
}

View File

@@ -11,6 +11,7 @@
hide-inputs
mode="rgba"
v-model="rgbPicker"
@input="(v) => updateColors(v, 'picker')"
/>
</v-col>
<v-col cols="12" sm="6" align="center">
@@ -116,7 +117,7 @@
this.keyword = convert.rgb.keyword(r, g, b);
},
updateColors(value, fromType) {
if (this.$refs[fromType].validate()) {
if (fromType === 'picker' || this.$refs[fromType].validate()) {
if (fromType === 'rgb') {
const [r, g, b] = value.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).slice(1).map(v => parseInt(v));
this.rgbPicker = {r, g, b}
@@ -150,6 +151,13 @@
} catch (ignored) {
// ignored
}
} else if (fromType === 'picker') {
const {r, g, b} = value;
this.setRGB(r, g, b);
this.setHEX(r, g, b);
this.setHSL(r, g, b);
this.setKeyword(r, g, b);
}
}
}

View File

@@ -0,0 +1,221 @@
<template>
<v-row justify="center" align="center">
<v-col cols="12" xl="5" lg="5" md="12">
<v-card>
<v-card-title>Crontab generator</v-card-title>
<v-card-text>
<div class="result">{{cronString}}</div>
<v-text-field
ref="cron"
class="cron-wrapper"
outlined
v-model="cron"
label="Cron"
append-icon="fa-copy"
@click:append="copy(cron)"
:rules="[isCronValid]"
hide-details="auto"
/>
<v-checkbox
hide-details
label="Verbose"
v-model="cronstrueConfig.verbose"
/>
<v-checkbox
hide-details
label="Use 24 hour time format"
v-model="cronstrueConfig.use24HourTimeFormat"
/>
<v-checkbox
hide-details
label="Day of the week start a index 0"
v-model="cronstrueConfig.dayOfWeekStartIndexZero"
/>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" xl="6" lg="7" md="12">
<v-card>
<v-card-title>Crontab helper</v-card-title>
<v-card-text>
<div class="text-center">
<pre>
day of week (0 - 6, sunday=0) OR sun,mon ...
| month (1 - 12) OR jan,feb,mar,apr ...
| | day of month (1 - 31)
| | | hour (0 - 23)
| | | | minute (0 - 59)
| | | | |
* * * * * command
</pre>
</div>
<br>
<v-simple-table dense>
<template v-slot:default>
<thead>
<tr>
<th class="text-left">Symbol</th>
<th class="text-left">Meaning</th>
<th class="text-left">Example</th>
<th class="text-left">Equivalent</th>
</tr>
</thead>
<tbody>
<tr>
<td>*</td>
<td>Any value</td>
<td>
<pre>* * * *</pre>
</td>
<td>Every minute</td>
</tr>
<tr>
<td>-</td>
<td>Range of values</td>
<td>
<pre>1-10 * * *</pre>
</td>
<td>Minutes 1 through 10</td>
</tr>
<tr>
<td>,</td>
<td>List of values</td>
<td>
<pre>1,10 * * *</pre>
</td>
<td>At minutes 1 and 10</td>
</tr>
<tr>
<td>/</td>
<td>Step values</td>
<td>
<pre>*/10 * * *</pre>
</td>
<td>Every 10 minutes</td>
</tr>
<tr>
<td>@yearly</td>
<td>Once every year at midnight of 1 January</td>
<td>
<pre>@yearly</pre>
</td>
<td>0 0 1 1 *</td>
</tr>
<tr>
<td>@annually</td>
<td>Same as @yearly</td>
<td>
<pre>@annually</pre>
</td>
<td>0 0 1 1 *</td>
</tr>
<tr>
<td>@monthly</td>
<td>Once a month at midnight on the first day</td>
<td>
<pre>@monthly</pre>
</td>
<td>0 0 1 * *</td>
</tr>
<tr>
<td>@weekly</td>
<td>Once a week at midnight on Sunday morning</td>
<td>
<pre>@weekly</pre>
</td>
<td>0 0 * * 0</td>
</tr>
<tr>
<td>@daily</td>
<td>Once a day at midnight</td>
<td>
<pre>@daily</pre>
</td>
<td>0 0 * * *</td>
</tr>
<tr>
<td>@midnight</td>
<td>Same as @daily</td>
<td>
<pre>@midnight</pre>
</td>
<td>0 0 * * *</td>
</tr>
<tr>
<td>@hourly</td>
<td>Once an hour at the beginning of the hour</td>
<td>
<pre>@hourly</pre>
</td>
<td>0 * * * *</td>
</tr>
<tr>
<td>@reboot</td>
<td>Run at startup</td>
<td></td>
<td></td>
</tr>
</tbody>
</template>
</v-simple-table>
</v-card-text>
</v-card>
</v-col>
</v-row>
</template>
<script>
import {copyable} from "../../mixins/copyable.mixin";
import cronstrue from 'cronstrue';
import * as CronValidator from 'cron-validator'
export default {
name: "CrontabGenerator",
mixins: [copyable],
data: () => ({
cron: '* * * * *',
cronstrueConfig: {
verbose: true,
dayOfWeekStartIndexZero: true,
use24HourTimeFormat: true,
throwExceptionOnParseError: true
}
}),
methods: {
isCronValid(v) {
return CronValidator.isValidCron(v, {allowBlankDay: true, alias: true});
}
},
computed: {
cronString() {
if (this.isCronValid(this.cron)) {
return cronstrue.toString(this.cron, this.cronstrueConfig)
} else {
return ' '
}
}
}
}
</script>
<style scoped lang="less">
::v-deep .cron-wrapper input {
text-align: center;
font-size: 22px;
font-family: Consolas, monospace;
}
.result {
text-align: center;
font-size: 18px;
margin-bottom: 22px;
}
.text-center{
pre{
display: inline-block;
text-align: left;
}
}
</style>

View File

@@ -0,0 +1,150 @@
<template>
<v-row>
<v-col cols="12" xl="12">
<v-card>
<v-card-title>Git Memo</v-card-title>
<v-card-text>
<MemoViewer :memo="tips"/>
</v-card-text>
</v-card>
</v-col>
</v-row>
</template>
<script>
import MemoViewer from "../../components/MemoViewer";
export default {
name: "GitMemo",
data: () => ({
tips: [
{
section: 'Get started',
child: [
{
text: 'Create a git repo',
code: 'git init'
},
{
text: 'Clone an existing repository',
code: 'git clone [repo url]'
},
{
text: 'Add current files to next commit',
code: 'git add .'
},
{
text: 'Commit tracked files changes',
code: 'git commit -am "[commit message]"'
},
{
text: 'List files that has changed',
code: 'git status'
},
{
text: 'List changes in tracked files',
code: 'git diff'
}
]
},
{
section: 'Basic configuration',
child: [
{
text: 'Set the name that will be associated to every operation',
code: 'git config --global user.name "[nom]"'
},
{
text: 'Set the email address that will be associated to every operation',
code: 'git config --global user.email "[email]"'
},
{
text: 'Tell git to always push tags',
code: 'git config --global push.followTags true'
}
]
},
{
section: 'I\'ve made a mistake',
child: [
{
text: 'Change last commit message',
code: 'git commit --amend'
},
{
text: 'Undo most recent commit and keep changes',
code: 'git reset HEAD~1'
},
{
text: 'Undo most recent commit and get rid of changes',
code: 'git reset HEAD~1 --hard'
},
{
text: 'Reset branch to remote state',
code: 'git fetch origin\ngit reset --hard origin/[branch-name]'
}
]
},
{
section: 'Setup SSH',
child: [
[
{
text: '1). Generate an SSH key.',
code: 'ssh-keygen -t rsa -b 4096 -C "[email]"'
},
{
text: '2). Start the ssh-agent in the background.',
code: 'eval "$(ssh-agent -s)"'
},
{
text: '3). Add your SSH private key to the ssh-agent.',
code: 'ssh-add ~/.ssh/id_rsa'
},
{
text: '4). Add your SSH public key to your git server (for github: Settings -> SSH and GPG keys)',
code: 'cat ~/.ssh/id_rsa.pub'
},
{
text: '5). (Optional) Testing your SSH connection',
code: 'ssh -T git@github.com'
},
]
]
},
{
section: 'Merge and rebase',
child: [
{
text: 'Merge a branch into the current',
code: 'git merge [branch]'
},
{
text: 'Abort merge (conflicts)',
code: 'git merge --abort'
},
{
text: 'Continue merge after resolving conflicts',
code: 'git merge --continue'
},
{
text: 'Rebase a branch into the current',
code: 'git rebase [branch]'
},
{
text: 'Continue rebase after resolving conflicts',
code: 'git rebase --continue'
},
]
},
]
}),
components: {
MemoViewer
}
}
</script>
<style lang="less" scoped>
</style>

View File

@@ -0,0 +1,94 @@
<template>
<v-row justify="center" align="center" class="lorem-ipsum-generator">
<v-col cols="12" xl="5" lg="6" md="12">
<v-card>
<v-card-title>Lorem ipsum generator</v-card-title>
<v-card-text>
<v-slider v-model="paragraphs" min="1" max="20" label="Paragraphs" thumb-label/>
<v-range-slider v-model="sentencePerParagraph" min="1" max="50" label="Sentences per paragraph"
thumb-label/>
<v-range-slider v-model="wordPerSentence" min="1" max="50" label="Words per sentence" thumb-label hide-details/>
<v-checkbox v-model="startWithLoremIpsum" label="Start with 'Lorem ipsum ...'" hide-details/>
<v-checkbox v-model="asHTML" label="As HTML" hide-details/>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" xl="5" lg="6" md="12">
<v-card>
<v-card-text>
<v-textarea outlined readonly hide-details="auto" v-model="loremIpsum" rows="15"
class="text-justify"></v-textarea>
<div class="text-center mt-4">
<v-btn depressed @click="copy()">Copy</v-btn>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</template>
<script>
import {copyToClipboard, randFromArray, randIntFromInterval} from "../../utils/helpers";
const vocabulary = ['a', 'ac', 'accumsan', 'ad', 'adipiscing', 'aenean', 'aliquam', 'aliquet', 'amet', 'ante', 'aptent', 'arcu', 'at', 'auctor', 'bibendum', 'blandit', 'class', 'commodo', 'condimentum', 'congue', 'consectetur', 'consequat', 'conubia', 'convallis', 'cras', 'cubilia', 'cum', 'curabitur', 'curae', 'dapibus', 'diam', 'dictum', 'dictumst', 'dignissim', 'dolor', 'donec', 'dui', 'duis', 'egestas', 'eget', 'eleifend', 'elementum', 'elit', 'enim', 'erat', 'eros', 'est', 'et', 'etiam', 'eu', 'euismod', 'facilisi', 'faucibus', 'felis', 'fermentum', 'feugiat', 'fringilla', 'fusce', 'gravida', 'habitant', 'habitasse', 'hac', 'hendrerit', 'himenaeos', 'iaculis', 'id', 'imperdiet', 'in', 'inceptos', 'integer', 'interdum', 'ipsum', 'justo', 'lacinia', 'lacus', 'laoreet', 'lectus', 'leo', 'ligula', 'litora', 'lobortis', 'lorem', 'luctus', 'maecenas', 'magna', 'magnis', 'malesuada', 'massa', 'mattis', 'mauris', 'metus', 'mi', 'molestie', 'mollis', 'montes', 'morbi', 'mus', 'nam', 'nascetur', 'natoque', 'nec', 'neque', 'netus', 'nisi', 'nisl', 'non', 'nostra', 'nulla', 'nullam', 'nunc', 'odio', 'orci', 'ornare', 'parturient', 'pellentesque', 'penatibus', 'per', 'pharetra', 'phasellus', 'placerat', 'platea', 'porta', 'porttitor', 'posuere', 'potenti', 'praesent', 'pretium', 'primis', 'proin', 'pulvinar', 'purus', 'quam', 'quis', 'quisque', 'rhoncus', 'ridiculus', 'risus', 'rutrum', 'sagittis', 'sapien', 'scelerisque', 'sed', 'sem', 'semper', 'senectus', 'sit', 'sociis', 'sociosqu', 'sodales', 'sollicitudin', 'suscipit', 'suspendisse', 'taciti', 'tellus', 'tempor', 'tempus', 'tincidunt', 'torquent', 'tortor', 'turpis', 'ullamcorper', 'ultrices', 'ultricies', 'urna', 'varius', 'vehicula', 'vel', 'velit', 'venenatis', 'vestibulum', 'vitae', 'vivamus', 'viverra', 'volutpat', 'vulputate'];
const firstSentence = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
const generateSentence = (length) => {
let sentence = Array.from({length}).map(() => randFromArray(vocabulary)).join(' ')
sentence = sentence.charAt(0).toUpperCase() + sentence.slice(1) + '.'
return sentence
}
export default {
name: "LoremIpsumGenerator",
data: () => ({
paragraphs: 1,
sentencePerParagraph: [3, 8],
wordPerSentence: [8, 15],
startWithLoremIpsum: true,
asHTML: false
}),
methods:{
copy(){
copyToClipboard(this.loremIpsum)
this.$toast.success('Copied to clipboard.')
}
},
computed: {
loremIpsum: function () {
const lorem = Array
.from({length: this.paragraphs})
.map(() => {
const length = randIntFromInterval(...this.sentencePerParagraph);
return Array.from({length}).map(() => {
const wordCount = randIntFromInterval(...this.wordPerSentence);
return generateSentence(wordCount);
})
});
if (this.startWithLoremIpsum) {
lorem[0][0] = firstSentence
}
let result;
if(this.asHTML){
result = `<p>${lorem.map(s => s.join(' ')).join('</p>\n\n<p>')}</p>`
}else{
result = lorem.map(s => s.join(' ')).join('\n\n')
}
return result;
}
}
}
</script>
<style scoped lang="less">
::v-deep {
.v-label{
min-width: 200px !important;
}
}
</style>

View File

@@ -0,0 +1,71 @@
<template>
<v-row justify="center" align="center">
<v-col cols="12" xl="5" lg="6" md="12">
<v-card>
<v-card-text>
<v-textarea v-model="markdown" auto-grow outlined label="Markdown editor"/>
<div class="text-center">
<v-btn @click="copy(markdown)">copy markdown</v-btn>
</div>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" xl="5" lg="6" md="12">
<v-card>
<v-card-text >
<div class="preview" v-html="html"></div>
<div class="text-center">
<v-divider />
<br>
<v-btn @click="copy(html)">copy html</v-btn>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</template>
<script>
// import {debounce} from "../../utils/helpers";
import marked from 'marked'
import DOMPurify from 'dompurify';
import {copyToClipboard} from "../../utils/helpers";
export default {
name: "MarkdownEditor",
data: () => ({
markdown: '# Hello, World!\nLorem ipsum **dolor** sit *amet*, consectetur adipisicing elit. A aspernatur commodi consequuntur distinctio dolore doloribus eaque earum est ipsum nobis numquam pariatur perspiciatis quasi quis, sed, sunt tempore tenetur, veniam!\n',
}),
methods: {
copy(text){
copyToClipboard(text)
this.$toast.success('Copied to clipboard.')
}
},
computed: {
html() {
return DOMPurify.sanitize(marked(this.markdown))
}
}
}
</script>
<style scoped lang="less">
::v-deep {
.preview {
padding: 20px;
h1{
margin-bottom: 15px;
}
pre {
width: 100%;
code {
width: 100% !important;
padding: 10px;
}
}
}
}
</style>

View File

@@ -0,0 +1,137 @@
<template>
<v-card class="single-card">
<v-card-title>QR-code generator</v-card-title>
<v-card-text>
<v-row justify="center" align="center">
<v-col cols="12" lg="6" sm="12">
<v-text-field
outlined
v-model="value"
label="Data"
:rules="rules.value"
/>
<v-slider v-model="size" min="100" max="1920" label="Size (preview will not change): " thumb-label/>
<v-select
outlined
v-model="level"
:items="levels"
label="Error resistance"
/>
<v-row>
<v-col cols="12" md="6" sm="12">
<ColorInput v-model="fgcolor" label="Foreground color"/>
</v-col>
<v-col cols="12" md="6" sm="12">
<ColorInput v-model="bgcolor" label="Background color"/>
</v-col>
</v-row>
</v-col>
<v-col cols="12" lg="6" sm="12" class="text-center">
<qrcode-vue
:value="input"
:size="size"
:level="level"
:background="bgcolor"
:foreground="fgcolor"
render-as="svg"
class-name="qrcode-wrapper"
/>
</v-col>
</v-row>
<div class="text-center mt-3 mb-sm-2">
<v-btn @click="download('png')" class="mr-1" color="primary">download as png</v-btn>
<v-btn @click="download('svg')" class="ml-1" color="primary">download as svg</v-btn>
</div>
</v-card-text>
</v-card>
</template>
<script>
import QrcodeVue from 'qrcode.vue'
import colors from "color-name";
import ColorInput from "../../components/ColorInput";
import {downloadBase64File} from "../../utils/helpers";
export default {
name: "QRCodeGenerator",
data: () => ({
value: 'https://it-tools.tech',
size: 300,
level: 'M',
bgcolor: '#ffffff',
fgcolor: '#000000',
levels: [
{text: 'Low', value: 'L'},
{text: 'Medium', value: 'M'},
{text: 'Quartile', value: 'Q'},
{text: 'High', value: 'H'}
],
rules: {
value: [
v => v.length > 0 || 'Value is needed'
],
color: [
v => {
v = v.trim()
const isFFFFFF = /^#(?:[0-9a-fA-F]{6})$/.test(v);
const isFFF = /^#(?:[0-9a-fA-F]{3})$/.test(v);
const isRGB = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(v);
const isHSL = /^hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)$/.test(v);
const isKeyword = v in colors;
const isTransparent = v === 'transparent';
return isFFFFFF || isFFF || isKeyword || isTransparent || isRGB || isHSL || 'Incorrect color.'
}
]
}
}),
methods: {
download(type) {
const svgEl = this.$el.querySelector('.qrcode-wrapper svg');
const svgString = new XMLSerializer().serializeToString(svgEl);
const svgUrl = `data:image/svg+xml;base64,${btoa(svgString)}`;
if (type === 'png') {
const canvas = document.createElement("canvas");
canvas.width = this.size;
canvas.height = this.size;
const ctx = canvas.getContext("2d");
const image = new Image();
image.onload = function () {
ctx.drawImage(image, 0, 0);
const result = canvas.toDataURL();
downloadBase64File(result, 'qr-code');
};
image.src = svgUrl;
} else {
downloadBase64File(svgUrl, 'qr-code');
}
}
},
computed: {
input() {
return this.value
}
},
components: {
QrcodeVue,
ColorInput
}
}
</script>
<style scoped lang="less">
::v-deep .qrcode-wrapper {
& > * {
width: 300px !important;
height: 300px !important;
}
}
</style>

View File

@@ -0,0 +1,66 @@
<template>
<v-card class="single-card">
<v-card-title>Base64 string converter</v-card-title>
<v-card-text>
<v-textarea
outlined
v-model="clear"
label="Clear text"
></v-textarea>
<v-textarea
outlined
v-model="base64"
label="Base64 text"
:rules="rules.base64"
ref="base64"
></v-textarea>
<div class="text-center">
<v-btn class="mr-1" depressed @click="copy(clear)">Copy clear</v-btn>
<v-btn class="ml-1" depressed @click="copy(base64)">Copy base64</v-btn>
</div>
</v-card-text>
</v-card>
</template>
<script>
import {copyable} from "../../mixins/copyable.mixin";
export default {
name: "StringToBase64",
mixins: [copyable],
data() {
return {
clear: 'Lorem ipsum dolor sit amet.',
rules:{
base64: [
v => {
try{
return btoa(atob(v)) === v || 'Input is not base64.'
}catch (e) {
return 'Input is not base64.'
}
}
]
}
}
},
computed: {
base64: {
get(){
return btoa(this.clear)
},
set(value){
if(this.$refs.base64.validate()){
this.clear = atob(value)
}
}
}
}
}
</script>
<style scoped>
</style>

View File

@@ -3,27 +3,52 @@
<v-card-title>Uuid v4 generator</v-card-title>
<v-card-text>
<v-text-field outlined v-model="token" class="centered-input"/>
<v-text-field
outlined
v-model.number="quantity"
ref="quantity"
type="number"
label="Quantity"
dense
class="quantity"
:rules="rules.quantity"
/>
<v-textarea outlined v-model="token" class="centered-input" :rows="quantity <= 10 ? quantity : 10"
readonly/>
<div class="text-center">
<v-btn @click="refreshBool = !refreshBool" depressed class="mr-4">Refresh</v-btn>
<v-btn @click="copyToken()" depressed>Copy token</v-btn>
<v-btn @click="copyToken()" depressed>Copy uuid{{ quantity > 1 ? 's' : ''}}</v-btn>
</div>
</v-card-text>
</v-card>
</template>
<script>
import {copyToClipboard} from "../../utils/helpers";
import {copyToClipboard, isInt} from "../../utils/helpers";
const noop = () => {
};
const generateUuid = () => ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
export default {
name: "UuidGenerator",
data: () => ({
refreshBool: true
refreshBool: true,
quantity: 1,
rules: {
quantity: [
v => !!v || 'Quantity is required',
v => (v > 0 && v <= 50 ) || 'Quantity should be > 0 and <= 50',
v => isInt(v) || 'Quantity should be an integer'
]
},
isMounted:false
}),
mounted() {
this.isMounted = true;
},
methods: {
copyToken() {
copyToClipboard(this.token);
@@ -32,16 +57,32 @@
},
computed: {
token() {
if (this.refreshBool) noop(); // To force recomputation
if (this.isMounted && this.$refs.quantity.validate()) {
if (this.refreshBool) noop(); // To force recomputation
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
return Array.from({length: this.quantity}, generateUuid).join('\n');
} else {
return '';
}
}
}
}
</script>
<style scoped>
::v-deep .centered-input input {
text-align: center
<style scoped lang="less">
.quantity {
width: 100px;
margin: auto;
text-align: center;
::v-deep input {
text-align: center;
}
}
::v-deep .centered-input textarea {
text-align: center;
margin-top: 13px !important;
font-family: Consolas, monospace;
}
</style>

View File

@@ -24,8 +24,37 @@ const formatBytes = (bytes, decimals = 2) => {
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
const isInt = (value) => {
return Number.isInteger(value);
}
const debounce = (callback, delay = 300) => {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => callback(...args), delay);
}
}
const randFromArray = (array) => array[Math.floor(Math.random() * array.length)];
const randIntFromInterval = (min, max) => Math.floor(Math.random() * (max - min) + min)
const downloadBase64File = (dataUrl, name = 'file') => {
const a = document.createElement("a");
a.href = dataUrl;
a.download = name;
a.click();
}
export {
copyToClipboard,
fileIsImage,
formatBytes
formatBytes,
isInt,
debounce,
randFromArray,
randIntFromInterval,
downloadBase64File
}

7
vercel.json Normal file
View File

@@ -0,0 +1,7 @@
{
"version": 2,
"routes": [
{ "handle": "filesystem" },
{ "src": "/.*", "dest": "/index.html" }
]
}

View File

@@ -6,6 +6,11 @@ module.exports = {
],
configureWebpack: () => {
return {
module:{
rules: [
{ test: /\.md$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
@@ -14,5 +19,11 @@ module.exports = {
})
]
}
},
pwa: {
workboxOptions: {
skipWaiting: true,
clientsClaim: true,
}
}
}