Updates (very important to read)

Client-side CSS & JS files will now be processed with Gulp.
Gulp tasks are configured in gulpfile.js file.

CSS files will be optimized with postcss-preset-env, which will
auto-add vendor prefixes and convert any parts necessary for browsers
compatibility.
Afterwards they will be minified with cssnano.

JS files will be optimized with bublé,
likewise for browsers compatibility.
Afterwards they will be minified with terser.

Unprocessed CSS & JS files will now be located at src directory, while
the processed results will be located at dist directory.

Due to bublé, the JS files should now be compatible up to IE 11
at the minimum.
Previously the safe would not work in IE 11 due to extensive usage of
template literals.
Due to that as well, JS files in src directory will now extensively use
arrow functions for my personal comfort (as they will be converted too).

The server will use the processed files at dist directory by default.
If you want to rebuild the files by your own, you can run "yarn build".
Gulp is a development dependency, so make sure you have installed all
development dependencies (e.i. NOT using "yarn install --production").

---

yarn lint -> gulp lint

yarn build -> gulp default

yarn watch -> gulp watch

yarn develop -> env NODE_ENV=development yarn watch

---

Fixed not being able to demote staff into normal users.

/api/token/verify will no longer respond with 401 HTTP error code,
unless an error occurred (which will be 500 HTTP error code).

Fixed /nojs route not displaying file's original name when a duplicate
is found on the server.

Removed is-breeze CSS class name, in favor of Bulma's is-info.

Removed custom styling from auth page, in favor of global styling.

Removed all usage of style HTML attribute in favor of CSS classes.

Renamed js/s/ to js/misc/.

Use loading spinners on dashboard's sidebar menus.

Disable all other sidebar menus when something is loading.

Changed title HTML attribute of disabled control buttons in
uploads & users list.

Hid checkboxes and WIP controls from users list.

Better error messages handling.
Especially homepage will now support CF's HTTP error codes.

Updated various icons.
Also, added fontello config file at public/libs/fontello/config.json.
This should let you edit them more easily with fontello.

Use Gatsby icon for my blog's link in homepage's footer.

A bunch of other improvements here & there.
safe.fiery.me
Bobby Wibowo 3 years ago
parent f5445a639c
commit c9ba16e1d6
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
  1. 7
      .browserslistrc
  2. 2
      .eslintignore
  3. 74
      .gitignore
  4. 2
      .stylelintignore
  5. 0
      .stylelintrc.json
  6. 10
      controllers/albumsController.js
  7. 10
      controllers/authController.js
  8. 48
      controllers/pathsController.js
  9. 12
      controllers/tokenController.js
  10. 17
      controllers/uploadController.js
  11. 22
      controllers/utilsController.js
  12. 4
      database/db.js
  13. 2
      database/migration.js
  14. 2
      dist/css/album.css
  15. 1
      dist/css/album.css.map
  16. 2
      dist/css/dashboard.css
  17. 1
      dist/css/dashboard.css.map
  18. 2
      dist/css/home.css
  19. 1
      dist/css/home.css.map
  20. 2
      dist/css/style.css
  21. 1
      dist/css/style.css.map
  22. 2
      dist/css/sweetalert.css
  23. 1
      dist/css/sweetalert.css.map
  24. 2
      dist/css/thumbs.css
  25. 1
      dist/css/thumbs.css.map
  26. 2
      dist/js/album.js
  27. 1
      dist/js/album.js.map
  28. 2
      dist/js/auth.js
  29. 1
      dist/js/auth.js.map
  30. 2
      dist/js/dashboard.js
  31. 1
      dist/js/dashboard.js.map
  32. 2
      dist/js/home.js
  33. 1
      dist/js/home.js.map
  34. 2
      dist/js/misc/render.js
  35. 1
      dist/js/misc/render.js.map
  36. 2
      dist/js/misc/utils.js
  37. 1
      dist/js/misc/utils.js.map
  38. 106
      gulpfile.js
  39. 35
      lolisafe.js
  40. 24
      package.json
  41. 31
      public/css/auth.css
  42. 9
      public/libs/fontello/LICENSE
  43. 240
      public/libs/fontello/config.json
  44. 53
      public/libs/fontello/fontello.css
  45. BIN
      public/libs/fontello/fontello.eot
  46. 46
      public/libs/fontello/fontello.svg
  47. BIN
      public/libs/fontello/fontello.ttf
  48. BIN
      public/libs/fontello/fontello.woff
  49. BIN
      public/libs/fontello/fontello.woff2
  50. 6
      routes/album.js
  51. 6
      routes/api.js
  52. 2
      routes/nojs.js
  53. 13
      scripts/_utils.js
  54. 3
      scripts/cf-purge.js
  55. 8
      scripts/clean-up.js
  56. 5
      scripts/delete-expired.js
  57. 7
      scripts/thumbs.js
  58. 0
      src/css/album.css
  59. 27
      src/css/dashboard.css
  60. 33
      src/css/home.css
  61. 51
      src/css/style.css
  62. 9
      src/css/sweetalert.css
  63. 14
      src/css/thumbs.css
  64. 6
      src/js/.eslintrc.json
  65. 2
      src/js/album.js
  66. 30
      src/js/auth.js
  67. 810
      src/js/dashboard.js
  68. 329
      src/js/home.js
  69. 12
      src/js/misc/render.js
  70. 10
      src/js/misc/utils.js
  71. 9
      todo.md
  72. 12
      views/_globals.njk
  73. 4
      views/album.njk
  74. 3
      views/auth.njk
  75. 32
      views/dashboard.njk
  76. 22
      views/home.njk
  77. 20
      views/nojs.njk
  78. 2834
      yarn.lock

@ -0,0 +1,7 @@
# Browserslist's defaults (supports IE 11 at the minimum)
# https://github.com/browserslist/browserslist#queries
> 0.5%
last 2 versions
Firefox ESR
not dead

@ -1 +1,3 @@
**/*.min.js
dist/js/*
public/libs/*

74
.gitignore vendored

@ -1,17 +1,63 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Dependency directories
node_modules/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# npm's package-lock (if npm is accidentally used)
package-lock.json
# vscode's workspace settings
/.vscode
# Configuration file
/config.js
# Database
/database/db
# Uploads directory
/uploads
# Custom pages directory
/pages/custom
# User files
.DS_Store
.nvmrc
.vscode
!.gitkeep
node_modules
uploads
logs
database/db
config.js
start.json
npm-debug.log
pages/custom/**
migrate.js
yarn-error.log
package-lock.json
public/render/**/original
public/render/**/wip
/start.json
/migrate.js
# User directories (renders)
/public/render/**/original
/public/render/**/wip

@ -0,0 +1,2 @@
dist/css/*
public/libs/*

@ -1,13 +1,13 @@
const config = require('./../config')
const db = require('knex')(config.database)
const EventEmitter = require('events')
const fs = require('fs')
const logger = require('./../logger')
const path = require('path')
const paths = require('./pathsController')
const randomstring = require('randomstring')
const utils = require('./utilsController')
const Zip = require('jszip')
const paths = require('./pathsController')
const utils = require('./utilsController')
const config = require('./../config')
const logger = require('./../logger')
const db = require('knex')(config.database)
const self = {
onHold: new Set()

@ -1,12 +1,12 @@
const { promisify } = require('util')
const bcrypt = require('bcrypt')
const config = require('./../config')
const db = require('knex')(config.database)
const logger = require('./../logger')
const perms = require('./permissionController')
const randomstring = require('randomstring')
const perms = require('./permissionController')
const tokens = require('./tokenController')
const utils = require('./utilsController')
const config = require('./../config')
const logger = require('./../logger')
const db = require('knex')(config.database)
const self = {
compare: promisify(bcrypt.compare),
@ -152,7 +152,7 @@ self.editUser = async (req, res, next) => {
update.enabled = Boolean(req.body.enabled)
if (req.body.group !== undefined) {
update.permission = perms.permissions[req.body.group] || target.permission
update.permission = perms.permissions[req.body.group]
if (typeof update.permission !== 'number' || update.permission < 0)
update.permission = target.permission
}

@ -1,8 +1,8 @@
const { promisify } = require('util')
const config = require('./../config')
const fs = require('fs')
const logger = require('./../logger')
const path = require('path')
const config = require('./../config')
const logger = require('./../logger')
const self = {}
@ -33,6 +33,7 @@ self.thumbPlaceholder = path.resolve(config.uploads.generateThumbs.placeholder |
self.logs = path.resolve(config.logsFolder)
self.customPages = path.resolve('pages/custom')
self.dist = path.resolve('dist')
self.public = path.resolve('public')
self.errorRoot = path.resolve(config.errorPages.rootDir)
@ -47,33 +48,28 @@ const verify = [
]
self.init = async () => {
try {
for (const p of verify)
try {
await self.access(p)
} catch (err) {
if (err.code !== 'ENOENT') {
logger.error(err)
} else {
const mkdir = await self.mkdir(p)
if (mkdir)
logger.log(`Created directory: ${p}`)
}
// Check & create directories
for (const p of verify)
try {
await self.access(p)
} catch (err) {
if (err.code !== 'ENOENT') {
throw err
} else {
const mkdir = await self.mkdir(p)
if (mkdir)
logger.log(`Created directory: ${p}`)
}
// Purge chunks directory
const uuidDirs = await self.readdir(self.chunks)
for (const uuid of uuidDirs) {
const root = path.join(self.chunks, uuid)
const chunks = await self.readdir(root)
for (const chunk of chunks)
await self.unlink(path.join(root, chunk))
await self.rmdir(root)
}
self.verified = true
} catch (error) {
logger.error(error)
// Purge any leftover in chunks directory
const uuidDirs = await self.readdir(self.chunks)
for (const uuid of uuidDirs) {
const root = path.join(self.chunks, uuid)
const chunks = await self.readdir(root)
for (const chunk of chunks)
await self.unlink(path.join(root, chunk))
await self.rmdir(root)
}
}

@ -1,9 +1,9 @@
const config = require('./../config')
const db = require('knex')(config.database)
const logger = require('./../logger')
const perms = require('./permissionController')
const randomstring = require('randomstring')
const perms = require('./permissionController')
const utils = require('./utilsController')
const config = require('./../config')
const logger = require('./../logger')
const db = require('knex')(config.database)
const self = {
tokenLength: 64,
@ -41,7 +41,7 @@ self.verify = async (req, res, next) => {
: ''
if (!token)
return res.status(401).json({ success: false, description: 'No token provided.' })
return res.json({ success: false, description: 'No token provided.' })
try {
const user = await db.table('users')
@ -50,7 +50,7 @@ self.verify = async (req, res, next) => {
.first()
if (!user)
return res.status(401).json({ success: false, description: 'Invalid token.' })
return res.json({ success: false, description: 'Invalid token.' })
return res.json({
success: true,

@ -1,15 +1,15 @@
const config = require('./../config')
const crypto = require('crypto')
const db = require('knex')(config.database)
const fetch = require('node-fetch')
const fs = require('fs')
const logger = require('./../logger')
const multer = require('multer')
const path = require('path')
const randomstring = require('randomstring')
const paths = require('./pathsController')
const perms = require('./permissionController')
const randomstring = require('randomstring')
const utils = require('./utilsController')
const config = require('./../config')
const logger = require('./../logger')
const db = require('knex')(config.database)
const self = {}
@ -563,6 +563,11 @@ self.storeFilesToDb = async (req, res, user, infoMap) => {
// Continue even when encountering errors
await utils.unlinkFile(info.data.filename).catch(logger.error)
// logger.log(`Unlinked ${info.data.filename} since a duplicate named ${dbFile.name} exists`)
// If on /nojs route, append original file name reported by client
if (req.path === '/nojs')
dbFile.original = info.data.originalname
exists.push(dbFile)
continue
}
@ -635,11 +640,11 @@ self.sendUploadResponse = async (req, res, result) => {
url: `${config.domain}/${file.name}`
}
// Add expiry date if a temporary upload
// If a temporary upload, add expiry date
if (file.expirydate)
map.expirydate = file.expirydate
// Add original name if on /nojs route
// If on /nojs route, add original name
if (req.path === '/nojs')
map.original = file.original

@ -1,15 +1,15 @@
const { promisify } = require('util')
const { spawn } = require('child_process')
const config = require('./../config')
const db = require('knex')(config.database)
const fetch = require('node-fetch')
const ffmpeg = require('fluent-ffmpeg')
const logger = require('./../logger')
const path = require('path')
const paths = require('./pathsController')
const perms = require('./permissionController')
const sharp = require('sharp')
const si = require('systeminformation')
const paths = require('./pathsController')
const perms = require('./permissionController')
const config = require('./../config')
const logger = require('./../logger')
const db = require('knex')(config.database)
const self = {
clamd: {
@ -148,6 +148,18 @@ self.escape = (string) => {
: html
}
self.stripIndents = string => {
if (!string) return
const result = string.replace(/^[^\S\n]+/gm, '')
const match = result.match(/^[^\S\n]*(?=\S)/gm)
const indent = match && Math.min(...match.map(el => el.length))
if (indent) {
const regexp = new RegExp(`^.{${indent}}`, 'gm')
return result.replace(regexp, '')
}
return result
}
self.authorize = async (req, res) => {
// TODO: Improve usage of this function by the other APIs
const token = req.headers.token

@ -1,6 +1,6 @@
const logger = require('./../logger')
const perms = require('./../controllers/permissionController')
const randomstring = require('randomstring')
const perms = require('./../controllers/permissionController')
const logger = require('./../logger')
// TODO: Auto-detect missing columns here
// That way we will no longer need the migration script

@ -1,6 +1,6 @@
const perms = require('./../controllers/permissionController')
const config = require('./../config')
const db = require('knex')(config.database)
const perms = require('./../controllers/permissionController')
const map = {
files: {

@ -0,0 +1,2 @@
.section{background:none}@media screen and (max-width:768px){.description{text-align:center}}
/*# sourceMappingURL=album.css.map */

@ -0,0 +1 @@
{"version":3,"sources":["album.css"],"names":[],"mappings":"AAAA,SACE,eACF,CAEA,oCACE,aACE,iBACF,CACF","file":"album.css","sourcesContent":[".section {\n background: none\n}\n\n@media screen and (max-width: 768px) {\n .description {\n text-align: center\n }\n}\n"]}

@ -0,0 +1,2 @@
body{-webkit-animation:none;animation:none}#dashboard{-webkit-animation:fadeInOpacity .5s;animation:fadeInOpacity .5s}.section{background:none}.menu-list a{color:#3794d2}.menu-list a:hover{color:#60a8dc;background-color:#4d4d4d}.menu-list a.is-active{color:#eff0f1;background-color:#3794d2}.menu-list a[disabled]{color:#7a7a7a;cursor:not-allowed}.menu-list a[disabled]:hover{background:none}ul#albumsContainer{border-left:0;padding-left:0}ul#albumsContainer li{border-left:1px solid #898b8d;padding-left:.75em}#page.fade-in,ul#albumsContainer li{-webkit-animation:fadeInOpacity .5s;animation:fadeInOpacity .5s}.pagination{margin-bottom:1.25rem}.pagination a:not([disabled]){color:#eff0f1;border-color:#4d4d4d;background-color:#31363b}a.pagination-link:not(.is-current):hover,a.pagination-next:not([disabled]):hover,a.pagination-previous:not([disabled]):hover{color:#eff0f1;border-color:#60a8dc;background-color:#31363b}a.pagination-link.is-current{background-color:#3794d2;border-color:#3794d2}a.pagination-link.is-current:hover{border-color:#60a8dc}li[data-action=page-ellipsis]{cursor:pointer}.label{color:#bdc3c7}.menu-list li ul{border-left-color:#898b8d}.image-container .checkbox{position:absolute;top:.75rem;left:.75rem}.no-touch .image-container .checkbox{opacity:.5}.no-touch .image-container .controls,.no-touch .image-container .details{opacity:0}.no-touch .image-container:hover .checkbox,.no-touch .image-container:hover .controls,.no-touch .image-container:hover .details{opacity:1}#page{min-width:0}.table{color:#bdc3c7;background-color:#31363b;font-size:.75rem}.table.is-striped tbody tr:nth-child(2n),.table tr:hover{background:none}.table.is-striped tbody tr:hover,.table.is-striped tbody tr:nth-child(2n):hover,.tag{background-color:#4d4d4d}.table td,.table th{border:0;white-space:nowrap}.table th{color:#eff0f1;height:2.25em}.table thead td,.table thead th{color:#eff0f1;background-color:#ff3860}.table .cell-indent{padding-left:2.25em}.is-linethrough{text-decoration:line-through}#menu.is-loading li a{cursor:progress}#statistics tr :nth-child(2){min-width:50%}
/*# sourceMappingURL=dashboard.css.map */

@ -0,0 +1 @@
{"version":3,"sources":["dashboard.css"],"names":[],"mappings":"AAAA,KACE,sBAAc,CAAd,cACF,CAEA,WACE,mCAA4B,CAA5B,2BACF,CAEA,SACE,eACF,CAEA,aACE,aACF,CAEA,mBACE,aAAc,CACd,wBACF,CAEA,uBACE,aAAc,CACd,wBACF,CAEA,uBACE,aAAc,CACd,kBACF,CAEA,6BACE,eACF,CAEA,mBACE,aAAc,CACd,cACF,CAEA,sBACE,6BAA8B,CAC9B,kBAEF,CAEA,oCAHE,mCAA4B,CAA5B,2BAKF,CAEA,YACE,qBACF,CAEA,8BACE,aAAc,CACd,oBAAqB,CACrB,wBACF,CAEA,6HAGE,aAAc,CACd,oBAAqB,CACrB,wBACF,CAEA,6BACE,wBAAyB,CACzB,oBACF,CAEA,mCACE,oBACF,CAEA,8BACE,cACF,CAEA,OACE,aACF,CAEA,iBACE,yBACF,CAEA,2BACE,iBAAkB,CAClB,UAAY,CACZ,WACF,CAEA,qCACE,UACF,CAEA,yEAEE,SACF,CAEA,gIAGE,SACF,CAEA,MAEE,WACF,CAEA,OACE,aAAc,CACd,wBAAyB,CACzB,gBACF,CAEA,yDAEE,eACF,CAEA,qFAGE,wBACF,CAEA,oBAEE,QAAS,CACT,kBACF,CAEA,UACE,aAAc,CACd,aACF,CAEA,gCAEE,aAAc,CACd,wBACF,CAEA,oBACE,mBACF,CAEA,gBACE,4BACF,CAEA,sBACE,eACF,CAEA,6BACE,aACF","file":"dashboard.css","sourcesContent":["body {\n animation: none\n}\n\n#dashboard {\n animation: fadeInOpacity 0.5s\n}\n\n.section {\n background: none\n}\n\n.menu-list a {\n color: #3794d2\n}\n\n.menu-list a:hover {\n color: #60a8dc;\n background-color: #4d4d4d\n}\n\n.menu-list a.is-active {\n color: #eff0f1;\n background-color: #3794d2\n}\n\n.menu-list a[disabled] {\n color: #7a7a7a;\n cursor: not-allowed\n}\n\n.menu-list a[disabled]:hover {\n background: none\n}\n\nul#albumsContainer {\n border-left: 0;\n padding-left: 0\n}\n\nul#albumsContainer li {\n border-left: 1px solid #898b8d;\n padding-left: 0.75em;\n animation: fadeInOpacity 0.5s\n}\n\n#page.fade-in {\n animation: fadeInOpacity 0.5s\n}\n\n.pagination {\n margin-bottom: 1.25rem\n}\n\n.pagination a:not([disabled]) {\n color: #eff0f1;\n border-color: #4d4d4d;\n background-color: #31363b\n}\n\na.pagination-link:not(.is-current):hover,\na.pagination-next:not([disabled]):hover,\na.pagination-previous:not([disabled]):hover {\n color: #eff0f1;\n border-color: #60a8dc;\n background-color: #31363b\n}\n\na.pagination-link.is-current {\n background-color: #3794d2;\n border-color: #3794d2\n}\n\na.pagination-link.is-current:hover {\n border-color: #60a8dc\n}\n\nli[data-action=\"page-ellipsis\"] {\n cursor: pointer\n}\n\n.label {\n color: #bdc3c7\n}\n\n.menu-list li ul {\n border-left-color: #898b8d\n}\n\n.image-container .checkbox {\n position: absolute;\n top: 0.75rem;\n left: 0.75rem\n}\n\n.no-touch .image-container .checkbox {\n opacity: 0.5\n}\n\n.no-touch .image-container .controls,\n.no-touch .image-container .details {\n opacity: 0\n}\n\n.no-touch .image-container:hover .checkbox,\n.no-touch .image-container:hover .controls,\n.no-touch .image-container:hover .details {\n opacity: 1\n}\n\n#page {\n /* fix overflow issue with flex */\n min-width: 0\n}\n\n.table {\n color: #bdc3c7;\n background-color: #31363b;\n font-size: 0.75rem\n}\n\n.table tr:hover,\n.table.is-striped tbody tr:nth-child(2n) {\n background: none\n}\n\n.table.is-striped tbody tr:hover,\n.table.is-striped tbody tr:nth-child(2n):hover,\n.tag {\n background-color: #4d4d4d\n}\n\n.table td,\n.table th {\n border: 0;\n white-space: nowrap\n}\n\n.table th {\n color: #eff0f1;\n height: 2.25em\n}\n\n.table thead td,\n.table thead th {\n color: #eff0f1;\n background-color: #ff3860\n}\n\n.table .cell-indent {\n padding-left: 2.25em\n}\n\n.is-linethrough {\n text-decoration: line-through\n}\n\n#menu.is-loading li a {\n cursor: progress\n}\n\n#statistics tr *:nth-child(2) {\n min-width: 50%\n}\n"]}

2
dist/css/home.css vendored

@ -0,0 +1,2 @@
#b{width:200px;height:200px;border-radius:100%;display:inline-block;margin-bottom:40px;vertical-align:top;-webkit-animation-delay:.5s;animation-delay:.5s;-webkit-animation-duration:1.5s;animation-duration:1.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-name:floatUp;animation-name:floatUp;-webkit-animation-timing-function:cubic-bezier(0,.71,.29,1);animation-timing-function:cubic-bezier(0,.71,.29,1);box-shadow:0 20px 60px rgba(10,10,10,.05),0 5px 10px rgba(10,10,10,.1),0 1px 1px rgba(10,10,10,.2)}#b img.logo{max-height:200px}#dropzone *{pointer-events:none}#panel,#tokenContainer{display:none}#maxSize{font-size:1rem}.dz-preview .dz-details{display:flex}.dz-preview .dz-details .dz-filename,.dz-preview .dz-details .dz-size{flex:1}.dz-preview .dz-error-mark,.dz-preview .dz-success-mark,.dz-preview img{display:none}@-webkit-keyframes floatUp{0%{opacity:0;box-shadow:0 0 0 rgba(10,10,10,0),0 0 0 rgba(10,10,10,0),0 0 0 rgba(10,10,10,0);transform:scale(.86)}25%{opacity:1}67%{box-shadow:0 0 0 rgba(10,10,10,0),0 5px 10px rgba(10,10,10,.1),0 1px 1px rgba(10,10,10,.2);transform:scale(1)}to{box-shadow:0 20px 60px rgba(10,10,10,.05),0 5px 10px rgba(10,10,10,.1),0 1px 1px rgba(10,10,10,.2);transform:scale(1)}}@keyframes floatUp{0%{opacity:0;box-shadow:0 0 0 rgba(10,10,10,0),0 0 0 rgba(10,10,10,0),0 0 0 rgba(10,10,10,0);transform:scale(.86)}25%{opacity:1}67%{box-shadow:0 0 0 rgba(10,10,10,0),0 5px 10px rgba(10,10,10,.1),0 1px 1px rgba(10,10,10,.2);transform:scale(1)}to{box-shadow:0 20px 60px rgba(10,10,10,.05),0 5px 10px rgba(10,10,10,.1),0 1px 1px rgba(10,10,10,.2);transform:scale(1)}}.uploads>div{-webkit-animation:fadeInOpacity .5s;animation:fadeInOpacity .5s;margin:1rem}.uploads>div:first-child{margin-top:1.5rem}.uploads.nojs{margin-bottom:0}.uploads .field>.icon:not(.icon-block){color:#3794d2}.uploads .field>.icon.icon-block{color:#da4453}.uploads progress{margin-top:.5rem;margin-bottom:1rem}.uploads img{max-width:200px}.name{font-size:1rem;color:#bdc3c7}.link>a,.name{word-break:break-all}.clipboard-mobile{margin-top:5px}#albumDiv{-webkit-animation:fadeInOpacity .5s;animation:fadeInOpacity .5s}#albumDiv .control{text-align:inherit}#linksColumn{margin-top:-.25rem;margin-left:-.25rem;margin-right:-.25rem;-webkit-animation:fadeInOpacity .5s;animation:fadeInOpacity .5s}#linksColumn .column{padding:.25rem}#linksColumn>span{padding:0 .3rem;color:#7f8c8d}.git-commit a{display:inline-block;word-break:break-all}#tabs{margin-bottom:1rem;-webkit-animation:fadeInOpacity .5s;animation:fadeInOpacity .5s}#tabs ul{border-bottom:1px solid #898b8d}#tabs li a{color:#bdc3c7;border-bottom-color:#898b8d}#tabs.is-boxed li.is-active a{color:#3794d2;background:#232629;border-color:#898b8d #898b8d #232629}#tabs.is-boxed li:not(.is-active) a:hover{background:#4d4d4d}.tab-content{margin-bottom:-.75rem;-webkit-animation:fadeInOpacity .5s;animation:fadeInOpacity .5s}.tab-content .label{color:#bdc3c7;font-weight:400}#tab-config.tab-content form{margin-bottom:.75rem}#urlMaxSize{font-weight:700}.render{position:fixed;right:0;bottom:0;font-size:1rem;color:#bdc3c7;cursor:pointer}.render.button{border-bottom-left-radius:0;border-bottom-right-radius:0;right:1%;opacity:.25;transition:opacity .25s}.render.button:hover{opacity:1}
/*# sourceMappingURL=home.css.map */

File diff suppressed because one or more lines are too long

@ -0,0 +1,2 @@
html{background-color:#232629;overflow-y:auto}body{color:#eff0f1;-webkit-animation:fadeInOpacity .5s;animation:fadeInOpacity .5s}@-webkit-keyframes fadeInOpacity{0%{opacity:0}to{opacity:1}}@keyframes fadeInOpacity{0%{opacity:0}to{opacity:1}}a{color:#3794d2}a:hover{color:#60a8dc}hr{background-color:#898b8d}.message-body code,code{background-color:#222528;border-radius:5px}.title{color:#eff0f1}.subtitle,.subtitle strong{color:#bdc3c7}.input::-moz-placeholder,.textarea::-moz-placeholder{color:#7f8c8d}.input::-webkit-input-placeholder,.textarea::-webkit-input-placeholder{color:#7f8c8d}.input:-moz-placeholder,.textarea:-moz-placeholder{color:#7f8c8d}.input:-ms-input-placeholder,.textarea:-ms-input-placeholder{color:#7f8c8d}.input.is-active,.input.is-focused,.input:active,.input:focus,.textarea.is-active,.textarea.is-focused,.textarea:active,.textarea:focus{border-color:#3794d2}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#4d4d4d}.table td,.table th{vertical-align:middle}.help{color:#7f8c8d}.button.is-info.is-hovered [class*=" icon-"]:before,.button.is-info.is-hovered [class^=icon-]:before,.button.is-info:hover [class*=" icon-"]:before,.button.is-info:hover [class^=icon-]:before{fill:#fff}.checkbox:hover,.radio:hover{color:#7f8c8d}.message{background-color:#31363b}.message-body{color:#eff0f1;border:0;box-shadow:0 20px 60px rgba(10,10,10,.05),0 5px 10px rgba(10,10,10,.1),0 1px 1px rgba(10,10,10,.2)}.menu-list a.is-loading:after{-webkit-animation:spinAround .5s linear infinite;animation:spinAround .5s linear infinite;border-radius:290486px;border-color:transparent transparent #dbdbdb #dbdbdb;border-style:solid;border-width:2px;content:"";display:block;height:1em;width:1em;right:.5em;top:calc(50% - .5em);position:absolute!important}
/*# sourceMappingURL=style.css.map */

@ -0,0 +1 @@
{"version":3,"sources":["style.css"],"names":[],"mappings":"AAAA,KACE,wBAAyB,CACzB,eACF,CAEA,KACE,aAAc,CACd,mCAA4B,CAA5B,2BACF,CAEA,iCACE,GACE,SACF,CAEA,GACE,SACF,CACF,CAEA,yBACE,GACE,SACF,CAEA,GACE,SACF,CACF,CAEA,EACE,aACF,CAEA,QACE,aACF,CAEA,GACE,wBACF,CAEA,wBAEE,wBAAyB,CACzB,iBACF,CAEA,OACE,aACF,CAMA,2BACE,aACF,CAEA,qDAEE,aACF,CAEA,uEAEE,aACF,CAEA,mDAEE,aACF,CAEA,6DAEE,aACF,CAEA,wIAQE,oBACF,CAEA,qDACE,wBACF,CAEA,oBAEE,qBACF,CAEA,MACE,aACF,CAEA,gMAIE,SACF,CAEA,6BAEE,aACF,CAEA,SACE,wBACF,CAEA,cACE,aAAc,CACd,QAAS,CACT,kGACF,CAEA,8BACE,gDAA0C,CAA1C,wCAA0C,CAE1C,sBAAuB,CAEvB,oDAA6B,CAA7B,kBAA6B,CAA7B,gBAA6B,CAC7B,UAAW,CACX,aAAc,CACd,UAAW,CACX,SAAU,CACV,UAA2B,CAC3B,oBAA0B,CAC1B,2BACF","file":"style.css","sourcesContent":["html {\n background-color: #232629;\n overflow-y: auto\n}\n\nbody {\n color: #eff0f1;\n animation: fadeInOpacity 0.5s\n}\n\n@-webkit-keyframes fadeInOpacity {\n 0% {\n opacity: 0\n }\n\n 100% {\n opacity: 1\n }\n}\n\n@keyframes fadeInOpacity {\n 0% {\n opacity: 0\n }\n\n 100% {\n opacity: 1\n }\n}\n\na {\n color: #3794d2\n}\n\na:hover {\n color: #60a8dc\n}\n\nhr {\n background-color: #898b8d\n}\n\ncode,\n.message-body code {\n background-color: #222528;\n border-radius: 5px\n}\n\n.title {\n color: #eff0f1\n}\n\n.subtitle {\n color: #bdc3c7\n}\n\n.subtitle strong {\n color: #bdc3c7\n}\n\n.input::-moz-placeholder,\n.textarea::-moz-placeholder {\n color: #7f8c8d\n}\n\n.input::-webkit-input-placeholder,\n.textarea::-webkit-input-placeholder {\n color: #7f8c8d\n}\n\n.input:-moz-placeholder,\n.textarea:-moz-placeholder {\n color: #7f8c8d\n}\n\n.input:-ms-input-placeholder,\n.textarea:-ms-input-placeholder {\n color: #7f8c8d\n}\n\n.input.is-active,\n.input.is-focused,\n.input:active,\n.input:focus,\n.textarea.is-active,\n.textarea.is-focused,\n.textarea:active,\n.textarea:focus {\n border-color: #3794d2\n}\n\n.table.is-hoverable tbody tr:not(.is-selected):hover {\n background-color: #4d4d4d\n}\n\n.table td,\n.table th {\n vertical-align: middle\n}\n\n.help {\n color: #7f8c8d\n}\n\n.button.is-info.is-hovered [class^=\"icon-\"]::before,\n.button.is-info.is-hovered [class*=\" icon-\"]::before,\n.button.is-info:hover [class^=\"icon-\"]::before,\n.button.is-info:hover [class*=\" icon-\"]::before {\n fill: #fff\n}\n\n.checkbox:hover,\n.radio:hover {\n color: #7f8c8d\n}\n\n.message {\n background-color: #31363b\n}\n\n.message-body {\n color: #eff0f1;\n border: 0;\n box-shadow: 0 20px 60px rgba(10, 10, 10, 0.05), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2)\n}\n\n.menu-list a.is-loading::after {\n animation: spinAround 0.5s infinite linear;\n border: 2px solid #dbdbdb;\n border-radius: 290486px;\n border-right-color: transparent;\n border-top-color: transparent;\n content: \"\";\n display: block;\n height: 1em;\n width: 1em;\n right: calc(0% + (1em / 2));\n top: calc(50% - (1em / 2));\n position: absolute !important\n}\n"]}

@ -0,0 +1,2 @@
.swal-modal{background-color:#31363b}.swal-modal .field{text-align:left;text-align:initial}.swal-modal.is-expanded{width:auto;max-width:90%}.swal-text,.swal-title{color:#eff0f1}.swal-text{text-align:center}.swal-content .checkbox,.swal-content .label,.swal-content .radio{color:#eff0f1}.swal-content .checkbox:hover,.swal-content .radio:hover{color:#bdc3c7}.swal-button{background-color:#3794d2;color:#eff0f1}.swal-button:hover{background-color:#60a8dc}.swal-button:focus{box-shadow:0 0 0 1px #31363b,0 0 0 3px rgba(55,148,210,.29)}.swal-button--loading{color:transparent}.swal-button--danger{background-color:#da4453}.swal-icon--info{border-color:#3794d2}.swal-icon--info:after,.swal-icon--info:before{background-color:#3794d2}.swal-icon--error{border-color:#da4453}.swal-icon--error__line{background-color:#da4453}.swal-icon--warning{border-color:#f67400;-webkit-animation:pulseWarning .5s infinite alternate;animation:pulseWarning .5s infinite alternate}.swal-icon--warning__body,.swal-icon--warning__dot{background-color:#f67400;-webkit-animation:pulseWarningBody .5s infinite alternate;animation:pulseWarningBody .5s infinite alternate}@-webkit-keyframes pulseWarning{0%{border-color:#ffaa60}to{border-color:#f67400}}@keyframes pulseWarning{0%{border-color:#ffaa60}to{border-color:#f67400}}@-webkit-keyframes pulseWarningBody{0%{background-color:#ffaa60}to{background-color:#f67400}}@keyframes pulseWarningBody{0%{background-color:#ffaa60}to{background-color:#f67400}}.swal-icon--success{border-color:#27ae60}.swal-icon--success__line{background-color:#27ae60}.swal-icon--success__hide-corners{background-color:#31363b}.swal-icon--success:after,.swal-icon--success:before{background:#31363b}.swal-display-thumb-container{min-width:200px;min-height:200px;display:flex;align-items:center;justify-content:center}
/*# sourceMappingURL=sweetalert.css.map */

@ -0,0 +1 @@
{"version":3,"sources":["sweetalert.css"],"names":[],"mappings":"AAAA,YACE,wBACF,CAEA,mBACE,eAAkB,CAAlB,kBACF,CAEA,wBACE,UAAW,CACX,aACF,CAEA,uBAEE,aACF,CAEA,WACE,iBACF,CAEA,kEAGE,aACF,CAEA,yDAEE,aACF,CAEA,aACE,wBAAyB,CACzB,aACF,CAEA,mBACE,wBACF,CAEA,mBACE,2DACF,CAEA,sBACE,iBACF,CAEA,qBACE,wBACF,CAEA,iBACE,oBACF,CAEA,+CAEE,wBACF,CAEA,kBACE,oBACF,CAEA,wBACE,wBACF,CAEA,oBACE,oBAAqB,CACrB,qDAA8C,CAA9C,6CACF,CAEA,mDAEE,wBAAyB,CACzB,yDAAkD,CAAlD,iDACF,CAEA,gCACE,GACE,oBACF,CAEA,GACE,oBACF,CACF,CAEA,wBACE,GACE,oBACF,CAEA,GACE,oBACF,CACF,CAEA,oCACE,GACE,wBACF,CAEA,GACE,wBACF,CACF,CAEA,4BACE,GACE,wBACF,CAEA,GACE,wBACF,CACF,CAEA,oBACE,oBACF,CAEA,0BACE,wBACF,CAEA,kCACE,wBACF,CAEA,qDAEE,kBACF,CAEA,8BACE,eAAgB,CAChB,gBAAiB,CACjB,YAAa,CACb,kBAAmB,CACnB,sBACF","file":"sweetalert.css","sourcesContent":[".swal-modal {\n background-color: #31363b\n}\n\n.swal-modal .field {\n text-align: initial\n}\n\n.swal-modal.is-expanded {\n width: auto;\n max-width: 90%\n}\n\n.swal-title,\n.swal-text {\n color: #eff0f1\n}\n\n.swal-text {\n text-align: center\n}\n\n.swal-content .label,\n.swal-content .checkbox,\n.swal-content .radio {\n color: #eff0f1\n}\n\n.swal-content .checkbox:hover,\n.swal-content .radio:hover {\n color: #bdc3c7\n}\n\n.swal-button {\n background-color: #3794d2;\n color: #eff0f1\n}\n\n.swal-button:hover {\n background-color: #60a8dc\n}\n\n.swal-button:focus {\n box-shadow: 0 0 0 1px #31363b, 0 0 0 3px rgba(55, 148, 210, 0.29)\n}\n\n.swal-button--loading {\n color: transparent\n}\n\n.swal-button--danger {\n background-color: #da4453\n}\n\n.swal-icon--info {\n border-color: #3794d2\n}\n\n.swal-icon--info::after,\n.swal-icon--info::before {\n background-color: #3794d2\n}\n\n.swal-icon--error {\n border-color: #da4453\n}\n\n.swal-icon--error__line {\n background-color: #da4453\n}\n\n.swal-icon--warning {\n border-color: #f67400;\n animation: pulseWarning 0.5s infinite alternate\n}\n\n.swal-icon--warning__body,\n.swal-icon--warning__dot {\n background-color: #f67400;\n animation: pulseWarningBody 0.5s infinite alternate\n}\n\n@-webkit-keyframes pulseWarning {\n 0% {\n border-color: #ffaa60\n }\n\n to {\n border-color: #f67400\n }\n}\n\n@keyframes pulseWarning {\n 0% {\n border-color: #ffaa60\n }\n\n to {\n border-color: #f67400\n }\n}\n\n@-webkit-keyframes pulseWarningBody {\n 0% {\n background-color: #ffaa60\n }\n\n to {\n background-color: #f67400\n }\n}\n\n@keyframes pulseWarningBody {\n 0% {\n background-color: #ffaa60\n }\n\n to {\n background-color: #f67400\n }\n}\n\n.swal-icon--success {\n border-color: #27ae60\n}\n\n.swal-icon--success__line {\n background-color: #27ae60\n}\n\n.swal-icon--success__hide-corners {\n background-color: #31363b\n}\n\n.swal-icon--success::after,\n.swal-icon--success::before {\n background: #31363b\n}\n\n.swal-display-thumb-container {\n min-width: 200px;\n min-height: 200px;\n display: flex;\n align-items: center;\n justify-content: center\n}\n"]}

@ -0,0 +1,2 @@
.image-container{display:flex;width:200px;height:200px;margin:9px;background-color:#31363b;overflow:hidden;align-items:center;box-shadow:0 20px 60px rgba(10,10,10,.05),0 5px 10px rgba(10,10,10,.1),0 1px 1px rgba(10,10,10,.2)}.image-container .title{font-weight:400;word-break:break-all}.image-container .image{display:flex;height:100%;width:100%;align-items:center;justify-content:center}.image-container .image img{max-height:100%;max-width:100%;height:auto;width:auto}.image-container .controls{display:flex;position:absolute;top:.75rem;right:.75rem}.image-container .controls .button{border-radius:0}.image-container .controls .button:not(:active):not(:hover){color:#fff;background-color:rgba(49,54,59,.75)}.image-container .details{position:absolute;left:.75rem;bottom:.75rem;right:.75rem;background-color:rgba(49,54,59,.75);color:#eff0f1;padding:.25rem;font-size:.75rem}.image-container .details p{display:block;text-overflow:ellipsis;overflow:hidden}.image-container .details p span{font-weight:700}
/*# sourceMappingURL=thumbs.css.map */

@ -0,0 +1 @@
{"version":3,"sources":["thumbs.css"],"names":[],"mappings":"AAAA,iBACE,YAAa,CACb,WAAY,CACZ,YAAa,CACb,UAAW,CACX,wBAAyB,CACzB,eAAgB,CAChB,kBAAmB,CACnB,kGACF,CAEA,wBACE,eAAmB,CACnB,oBACF,CAEA,wBACE,YAAa,CACb,WAAY,CACZ,UAAW,CACX,kBAAmB,CACnB,sBACF,CAEA,4BACE,eAAgB,CAChB,cAAe,CACf,WAAY,CACZ,UACF,CAEA,2BACE,YAAa,CACb,iBAAkB,CAClB,UAAY,CACZ,YACF,CAEA,mCACE,eACF,CAEA,4DACE,UAAW,CACX,mCACF,CAEA,0BACE,iBAAkB,CAClB,WAAa,CACb,aAAe,CACf,YAAc,CACd,mCAAwC,CACxC,aAAc,CACd,cAAgB,CAChB,gBACF,CAEA,4BACE,aAAc,CACd,sBAAuB,CACvB,eACF,CAEA,iCACE,eACF","file":"thumbs.css","sourcesContent":[".image-container {\n display: flex;\n width: 200px;\n height: 200px;\n margin: 9px;\n background-color: #31363b;\n overflow: hidden;\n align-items: center;\n box-shadow: 0 20px 60px rgba(10, 10, 10, 0.05), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2)\n}\n\n.image-container .title {\n font-weight: normal;\n word-break: break-all\n}\n\n.image-container .image {\n display: flex;\n height: 100%;\n width: 100%;\n align-items: center;\n justify-content: center\n}\n\n.image-container .image img {\n max-height: 100%;\n max-width: 100%;\n height: auto;\n width: auto\n}\n\n.image-container .controls {\n display: flex;\n position: absolute;\n top: 0.75rem;\n right: 0.75rem\n}\n\n.image-container .controls .button {\n border-radius: 0\n}\n\n.image-container .controls .button:not(:active):not(:hover) {\n color: #fff;\n background-color: rgba(49, 54, 59, 0.75)\n}\n\n.image-container .details {\n position: absolute;\n left: 0.75rem;\n bottom: 0.75rem;\n right: 0.75rem;\n background-color: rgba(49, 54, 59, 0.75);\n color: #eff0f1;\n padding: 0.25rem;\n font-size: 0.75rem\n}\n\n.image-container .details p {\n display: block;\n text-overflow: ellipsis;\n overflow: hidden\n}\n\n.image-container .details p span {\n font-weight: bold\n}\n"]}

2
dist/js/album.js vendored

@ -0,0 +1,2 @@
var lsKeys={},page={lazyLoad:null};window.onload=function(){for(var e=document.querySelectorAll(".file-size"),a=0;a<e.length;a++)e[a].innerHTML=page.getPrettyBytes(parseInt(e[a].innerHTML.replace(/\s*B$/i,"")));page.lazyLoad=new LazyLoad};
//# sourceMappingURL=album.js.map

@ -0,0 +1 @@
{"version":3,"sources":["album.js"],"names":["const","lsKeys","page","lazyLoad","window","onload","elements","document","querySelectorAll","i","length","innerHTML","getPrettyBytes","parseInt","replace","LazyLoad"],"mappings":"AAGAA,IAAMC,OAAS,GAETC,KAAO,CACXC,SAAU,MAGZC,OAAOC,OAAM,WAEX,IADAL,IAAMM,EAAWC,SAASC,iBAAiB,cAClCC,EAAI,EAAGA,EAAIH,EAASI,OAAQD,IACnCH,EAASG,GAAGE,UAAYT,KAAKU,eAAeC,SAASP,EAASG,GAAGE,UAAUG,QAAQ,SAAU,MAE/FZ,KAAKC,SAAW,IAAIY","file":"album.js","sourcesContent":["/* global LazyLoad */\n\n// eslint-disable-next-line no-unused-vars\nconst lsKeys = {}\n\nconst page = {\n lazyLoad: null\n}\n\nwindow.onload = () => {\n const elements = document.querySelectorAll('.file-size')\n for (let i = 0; i < elements.length; i++)\n elements[i].innerHTML = page.getPrettyBytes(parseInt(elements[i].innerHTML.replace(/\\s*B$/i, '')))\n\n page.lazyLoad = new LazyLoad()\n}\n"]}

2
dist/js/auth.js vendored

@ -0,0 +1,2 @@
var lsKeys={token:"token"},page={token:localStorage[lsKeys.token],user:null,pass:null,do:function(e,r){var o=page.user.value.trim();if(!o)return swal("An error occurred!","You need to specify a username.","error");var t=page.pass.value.trim();if(!t)return swal("An error occurred!","You need to specify a password.","error");r.classList.add("is-loading"),axios.post("api/"+e,{username:o,password:t}).then((function(o){if(!1===o.data.success)return r.classList.remove("is-loading"),swal("Unable to "+e+"!",o.data.description,"error");localStorage.token=o.data.token,window.location="dashboard"})).catch((function(e){return console.error(e),r.classList.remove("is-loading"),swal("An error occurred!","There was an error with the request, please check the console for more information.","error")}))},verify:function(){page.token&&axios.post("api/tokens/verify",{token:page.token}).then((function(e){if(!1===e.data.success)return swal("An error occurred!",e.data.description,"error");window.location="dashboard"})).catch((function(e){console.error(e);var r=e.response.data&&e.response.data.description?e.response.data.description:"There was an error with the request, please check the console for more information.";return swal(e.response.status+" "+e.response.statusText,r,"error")}))}};window.onload=function(){page.verify(),page.user=document.querySelector("#user"),page.pass=document.querySelector("#pass"),document.querySelector("#authForm").addEventListener("submit",(function(e){e.preventDefault()})),document.querySelector("#loginBtn").addEventListener("click",(function(e){page.do("login",e.currentTarget)})),document.querySelector("#registerBtn").addEventListener("click",(function(e){page.do("register",e.currentTarget)}))};
//# sourceMappingURL=auth.js.map

@ -0,0 +1 @@
{"version":3,"sources":["auth.js"],"names":["const","lsKeys","token","page","localStorage","user","pass","do","dest","trigger","value","trim","swal","classList","add","axios","post","username","password","then","response","data","success","remove","description","window","location","catch","error","console","verify","onload","document","querySelector","addEventListener","event","preventDefault","currentTarget"],"mappings":"AAEAA,IAAMC,OAAS,CACbC,MAAO,SAGHC,KAAO,CAEXD,MAAOE,aAAaH,OAAOC,OAG3BG,KAAM,KACNC,KAAM,KAGRC,GAAO,SAAIC,EAAMC,GACfT,IAAMK,EAAOF,KAAKE,KAAKK,MAAMC,OAC7B,IAAKN,EACH,OAAOO,KAAK,qBAAsB,kCAAmC,SAEvEZ,IAAMM,EAAOH,KAAKG,KAAKI,MAAMC,OAC7B,IAAKL,EACH,OAAOM,KAAK,qBAAsB,kCAAmC,SAEvEH,EAAQI,UAAUC,IAAI,cACtBC,MAAMC,KAAK,OAAOR,EAAQ,CACxBS,SAAUZ,EACVa,SAAUZ,IACTa,MAAI,SAACC,GACN,IAA8B,IAA1BA,EAASC,KAAKC,QAEhB,OADAb,EAAQI,UAAUU,OAAO,cAClBX,KAAK,aAAaJ,EAAI,IAAKY,EAASC,KAAKG,YAAa,SAG/DpB,aAAaF,MAAQkB,EAASC,KAAKnB,MACnCuB,OAAOC,SAAW,eACjBC,OAAK,SAACC,GAGP,OAFAC,QAAQD,MAAMA,GACdnB,EAAQI,UAAUU,OAAO,cAClBX,KAAK,qBAAsB,sFAAuF,aAI7HkB,OAAW,WACJ3B,KAAKD,OAEVa,MAAMC,KAAK,oBAAqB,CAC9Bd,MAAOC,KAAKD,QACXiB,MAAI,SAACC,GACN,IAA8B,IAA1BA,EAASC,KAAKC,QAChB,OAAOV,KAAK,qBAAsBQ,EAASC,KAAKG,YAAa,SAE/DC,OAAOC,SAAW,eACjBC,OAAK,SAACC,GACPC,QAAQD,MAAMA,GACd5B,IAAMwB,EAAcI,EAAMR,SAASC,MAAQO,EAAMR,SAASC,KAAKG,YAC3DI,EAAMR,SAASC,KAAKG,YACpB,sFACJ,OAAOZ,KAAQgB,EAAMR,SAAS,OAAM,IAAIQ,EAAMR,SAAmB,WAAII,EAAa,cAItFC,OAAOM,OAAM,WACX5B,KAAK2B,SAEL3B,KAAKE,KAAO2B,SAASC,cAAc,SACnC9B,KAAKG,KAAO0B,SAASC,cAAc,SAGnCD,SAASC,cAAc,aAAaC,iBAAiB,UAAQ,SAAEC,GAC7DA,EAAMC,oBAGRJ,SAASC,cAAc,aAAaC,iBAAiB,SAAO,SAAEC,GAC5DhC,KAAKI,GAAG,QAAS4B,EAAME,kBAGzBL,SAASC,cAAc,gBAAgBC,iBAAiB,SAAO,SAAEC,GAC/DhC,KAAKI,GAAG,WAAY4B,EAAME","file":"auth.js","sourcesContent":["/* global swal, axios */\n\nconst lsKeys = {\n token: 'token'\n}\n\nconst page = {\n // user token\n token: localStorage[lsKeys.token],\n\n // HTML elements\n user: null,\n pass: null\n}\n\npage.do = (dest, trigger) => {\n const user = page.user.value.trim()\n if (!user)\n return swal('An error occurred!', 'You need to specify a username.', 'error')\n\n const pass = page.pass.value.trim()\n if (!pass)\n return swal('An error occurred!', 'You need to specify a password.', 'error')\n\n trigger.classList.add('is-loading')\n axios.post(`api/${dest}`, {\n username: user,\n password: pass\n }).then(response => {\n if (response.data.success === false) {\n trigger.classList.remove('is-loading')\n return swal(`Unable to ${dest}!`, response.data.description, 'error')\n }\n\n localStorage.token = response.data.token\n window.location = 'dashboard'\n }).catch(error => {\n console.error(error)\n trigger.classList.remove('is-loading')\n return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error')\n })\n}\n\npage.verify = () => {\n if (!page.token) return\n\n axios.post('api/tokens/verify', {\n token: page.token\n }).then(response => {\n if (response.data.success === false)\n return swal('An error occurred!', response.data.description, 'error')\n\n window.location = 'dashboard'\n }).catch(error => {\n console.error(error)\n const description = error.response.data && error.response.data.description\n ? error.response.data.description\n : 'There was an error with the request, please check the console for more information.'\n return swal(`${error.response.status} ${error.response.statusText}`, description, 'error')\n })\n}\n\nwindow.onload = () => {\n page.verify()\n\n page.user = document.querySelector('#user')\n page.pass = document.querySelector('#pass')\n\n // Prevent default form's submit action\n document.querySelector('#authForm').addEventListener('submit', event => {\n event.preventDefault()\n })\n\n document.querySelector('#loginBtn').addEventListener('click', event => {\n page.do('login', event.currentTarget)\n })\n\n document.querySelector('#registerBtn').addEventListener('click', event => {\n page.do('register', event.currentTarget)\n })\n}\n"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/js/home.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,2 @@
lsKeys.render="render",page.renderType="miku",page.renderConfig={al:{name:"ship waifu~",root:"render/al/",array:["admiral_graf_spee_1.png","admiral_hipper_1.png","akagi_1.png","akashi_1.png","akashi_2.png","atago_1.png","atago_3.png","atago_4.png","atago_5.png","belfast_2.png","choukai_1.png","deutschland_1.png","enterprise_1.png","glorious_1.png","hammann_1.png","hammann_2.png","hammann_3.png","hatsuharu_1.png","kaga_1.png","kaga_2.png","kaga_3.png","laffey_1.png","laffey_2.png","laffey_3.png","prinz_eugen_3.png","san_diego_1.png","takao_3.png","unicorn_1.png","unicorn_2.png","unicorn_3.png","unicorn_4.png","unicorn_6.png","unicorn_7.png","unicorn_8.png","yamashiro_1.png","yamashiro_2.png","yamashiro_3.png","yukikaze_1.png"]},miku:{name:"miku ❤~",root:"render/miku/",array:[]}};for(var i=1;i<=50;i++)page.renderConfig.miku.array.push(("00"+i).slice(-3)+".png");page.config=null,page.render=null,page.doRenderSwal=function(){var e=document.createElement("div");e.innerHTML='\n <div class="field">\n <div class="control">\n <label class="checkbox">\n <input id="swalRender" type="checkbox" '+("0"===localStorage[lsKeys.render]?"":"checked")+">\n Enable random render of "+page.config.name+'\n </label>\n </div>\n <p class="help">If disabled, you will still be able to see a small button on the bottom right corner of the screen to re-enable it.</p>\n </div>\n ',swal({content:e,buttons:{confirm:!0}}).then((function(n){if(n){var a=e.querySelector("#swalRender").checked?void 0:"0";if(a!==localStorage[lsKeys.render])a?localStorage[lsKeys.render]=a:localStorage.removeItem(lsKeys.render),swal("Success!","Random render is now "+(a?"disabled":"enabled")+".","success"),document.querySelector("body > .render").remove(),page.doRender()}}))},page.getRenderVersion=function(){var e=document.querySelector("#renderScript");return e&&e.dataset.version?"?v="+e.dataset.version:""},page.doRender=function(){var e;(page.config=page.renderConfig[page.renderType],page.config&&page.config.array.length)&&("0"===localStorage[lsKeys.render]?((e=document.createElement("a")).className="button is-info is-hidden-mobile",e.title=page.config.name,e.innerHTML='<i class="icon-picture"></i>'):(page.render=page.config.array[Math.floor(Math.random()*page.config.array.length)],(e=document.createElement("img")).alt=e.title=page.config.name,e.className="is-hidden-mobile",e.src=""+page.config.root+page.render+page.getRenderVersion()),e.classList.add("render"),e.addEventListener("click",page.doRenderSwal),document.body.appendChild(e))},page.doRender();
//# sourceMappingURL=render.js.map

File diff suppressed because one or more lines are too long

@ -0,0 +1,2 @@
lsKeys.siBytes="siBytes",page.prepareShareX=function(){var e=page.token?{token:page.token||"",albumid:page.album||""}:{};e.filelength=page.fileLength||"",e.age=page.uploadAge||"";for(var t=[],a=Object.keys(e),n=0;n<a.length;n++)t.push(' "'+a[n]+'": "'+e[a[n]]+'"');var o=(location.hostname+location.pathname).replace(/\/(dashboard)?$/,""),r=o.replace(/\//g,"_"),i=document.querySelector("#ShareX"),l='{\n "Name": "'+r+'",\n "DestinationType": "ImageUploader, FileUploader",\n "RequestMethod": "POST",\n "RequestURL": "'+location.protocol+"//"+o+'/api/upload",\n "Headers": {\n'+t.join(",\n")+'\n },\n "Body": "MultipartFormData",\n "FileFormName": "files[]",\n "URL": "$json:files[0].url$",\n "ThumbnailURL": "$json:files[0].url$"\n}',s=new Blob([l],{type:"application/octet-binary"});i.setAttribute("href",URL.createObjectURL(s)),i.setAttribute("download",r+".sxcu")},page.getPrettyDate=function(e){return e.getFullYear()+"-"+(e.getMonth()<9?"0":"")+(e.getMonth()+1)+"-"+(e.getDate()<10?"0":"")+e.getDate()+" "+(e.getHours()<10?"0":"")+e.getHours()+":"+(e.getMinutes()<10?"0":"")+e.getMinutes()+":"+(e.getSeconds()<10?"0":"")+e.getSeconds()},page.getPrettyBytes=function(e){if("number"!=typeof e&&!isFinite(e))return e;var t="0"!==localStorage[lsKeys.siBytes],a=e<0?"-":"",n=t?1e3:1024;if(a&&(e=-e),e<n)return""+a+e+" B";var o=Math.min(Math.floor(Math.log(e)*Math.LOG10E/3),8);return""+a+Number((e/Math.pow(n,o)).toPrecision(3))+" "+((t?"kMGTPEZY":"KMGTPEZY").charAt(o-1)+(t?"":"i"))+"B"};
//# sourceMappingURL=utils.js.map

@ -0,0 +1 @@
{"version":3,"sources":["utils.js"],"names":["lsKeys","siBytes","page","prepareShareX","const","values","token","albumid","album","filelength","fileLength","age","uploadAge","headers","keys","Object","i","length","push","origin","location","hostname","pathname","replace","originClean","sharexElement","document","querySelector","sharexFile","join","sharexBlob","Blob","type","setAttribute","URL","createObjectURL","getPrettyDate","date","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getPrettyBytes","num","isFinite","si","localStorage","neg","scale","exponent","Math","min","floor","log","LOG10E","Number","pow","toPrecision","charAt"],"mappings":"AAGAA,OAAOC,QAAU,UAEjBC,KAAKC,cAAa,WAChBC,IAAMC,EAASH,KAAKI,MAAQ,CAC1BA,MAAOJ,KAAKI,OAAS,GACrBC,QAASL,KAAKM,OAAS,IACrB,GACJH,EAAOI,WAAaP,KAAKQ,YAAc,GACvCL,EAAOM,IAAMT,KAAKU,WAAa,GAI/B,IAFAR,IAAMS,EAAU,GACVC,EAAOC,OAAOD,KAAKT,GAChBW,EAAI,EAAGA,EAAIF,EAAKG,OAAQD,IAE/BH,EAAQK,KAAK,QAAQJ,EAAKE,GAAE,OAAOX,EAAOS,EAAKE,IAAG,KAEpDZ,IAAMe,GAAUC,SAASC,SAAWD,SAASE,UAAUC,QAAQ,kBAAmB,IAC5EC,EAAcL,EAAOI,QAAQ,MAAO,KAEpCE,EAAgBC,SAASC,cAAc,WACvCC,EAAa,iBACRJ,EAAW,yGAGLJ,SAAS,SAAQ,KAAKD,EAAM,kCAE7CN,EAAQgB,KAAK,OAAM,oJAQbC,EAAa,IAAIC,KAAK,CAACH,GAAa,CAAEI,KAAM,6BAClDP,EAAcQ,aAAa,OAAQC,IAAIC,gBAAgBL,IACvDL,EAAcQ,aAAa,WAAeT,EAAW,UAGvDtB,KAAKkC,cAAa,SAAGC,GACnB,OAAOA,EAAKC,cAAgB,KACzBD,EAAKE,WAAa,EAAI,IAAM,KAC5BF,EAAKE,WAAa,GAAK,KACvBF,EAAKG,UAAY,GAAK,IAAM,IAC7BH,EAAKG,UAAY,KAChBH,EAAKI,WAAa,GAAK,IAAM,IAC9BJ,EAAKI,WAAa,KACjBJ,EAAKK,aAAe,GAAK,IAAM,IAChCL,EAAKK,aAAe,KACnBL,EAAKM,aAAe,GAAK,IAAM,IAChCN,EAAKM,cAGTzC,KAAK0C,eAAc,SAAGC,GAGpB,GAAmB,iBAARA,IAAqBC,SAASD,GAAM,OAAOA,EAEtDzC,IAAM2C,EAAsC,MAAjCC,aAAahD,OAAOC,SACzBgD,EAAMJ,EAAM,EAAI,IAAM,GACtBK,EAAQH,EAAK,IAAO,KAE1B,GADIE,IAAKJ,GAAOA,GACZA,EAAMK,EAAO,MAAO,GAAGD,EAAMJ,EAAG,KAEpCzC,IAAM+C,EAAWC,KAAKC,IAAID,KAAKE,MAAOF,KAAKG,IAAIV,GAAOO,KAAKI,OAAU,GAAI,GAGzE,MAAO,GAAGP,EAFKQ,QAAQZ,EAAMO,KAAKM,IAAIR,EAAOC,IAAWQ,YAAY,IAE9C,MADTZ,EAAK,WAAa,YAAYa,OAAOT,EAAW,IAAMJ,EAAK,GAAK,MAChD","file":"utils.js","sourcesContent":["/* global lsKeys, page */\n\n// keys for localStorage\nlsKeys.siBytes = 'siBytes'\n\npage.prepareShareX = () => {\n const values = page.token ? {\n token: page.token || '',\n albumid: page.album || ''\n } : {}\n values.filelength = page.fileLength || ''\n values.age = page.uploadAge || ''\n\n const headers = []\n const keys = Object.keys(values)\n for (let i = 0; i < keys.length; i++)\n // Pad by 4 space\n headers.push(` \"${keys[i]}\": \"${values[keys[i]]}\"`)\n\n const origin = (location.hostname + location.pathname).replace(/\\/(dashboard)?$/, '')\n const originClean = origin.replace(/\\//g, '_')\n\n const sharexElement = document.querySelector('#ShareX')\n const sharexFile = `{\n \"Name\": \"${originClean}\",\n \"DestinationType\": \"ImageUploader, FileUploader\",\n \"RequestMethod\": \"POST\",\n \"RequestURL\": \"${location.protocol}//${origin}/api/upload\",\n \"Headers\": {\n${headers.join(',\\n')}\n },\n \"Body\": \"MultipartFormData\",\n \"FileFormName\": \"files[]\",\n \"URL\": \"$json:files[0].url$\",\n \"ThumbnailURL\": \"$json:files[0].url$\"\n}`\n\n const sharexBlob = new Blob([sharexFile], { type: 'application/octet-binary' })\n sharexElement.setAttribute('href', URL.createObjectURL(sharexBlob))\n sharexElement.setAttribute('download', `${originClean}.sxcu`)\n}\n\npage.getPrettyDate = date => {\n return date.getFullYear() + '-' +\n (date.getMonth() < 9 ? '0' : '') + // month's index starts from zero\n (date.getMonth() + 1) + '-' +\n (date.getDate() < 10 ? '0' : '') +\n date.getDate() + ' ' +\n (date.getHours() < 10 ? '0' : '') +\n date.getHours() + ':' +\n (date.getMinutes() < 10 ? '0' : '') +\n date.getMinutes() + ':' +\n (date.getSeconds() < 10 ? '0' : '') +\n date.getSeconds()\n}\n\npage.getPrettyBytes = num => {\n // MIT License\n // Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)\n if (typeof num !== 'number' && !isFinite(num)) return num\n\n const si = localStorage[lsKeys.siBytes] !== '0'\n const neg = num < 0 ? '-' : ''\n const scale = si ? 1000 : 1024\n if (neg) num = -num\n if (num < scale) return `${neg}${num} B`\n\n const exponent = Math.min(Math.floor((Math.log(num) * Math.LOG10E) / 3), 8) // 8 is count of KMGTPEZY\n const numStr = Number((num / Math.pow(scale, exponent)).toPrecision(3))\n const pre = (si ? 'kMGTPEZY' : 'KMGTPEZY').charAt(exponent - 1) + (si ? '' : 'i')\n return `${neg}${numStr} ${pre}B`\n}\n"]}

@ -0,0 +1,106 @@
const gulp = require('gulp')
const cssnano = require('cssnano')
const del = require('del')
const buble = require('gulp-buble')
const eslint = require('gulp-eslint')
const gulpif = require('gulp-if')
const nodemon = require('gulp-nodemon')
const postcss = require('gulp-postcss')
const postcssPresetEnv = require('postcss-preset-env')
const sourcemaps = require('gulp-sourcemaps')
const stylelint = require('gulp-stylelint')
const terser = require('gulp-terser')
/** TASKS: LINT */
gulp.task('lint:js', () => {
return gulp.src('./src/js/**/*.js')
.pipe(eslint())
.pipe(eslint.failAfterError())
})
gulp.task('lint:css', () => {
return gulp.src('./src/css/**/*.css')
.pipe(stylelint())
})
gulp.task('lint', gulp.parallel('lint:js', 'lint:css'))
/** TASKS: CLEAN */
gulp.task('clean:css', () => {
return del(['dist/css'])
})
gulp.task('clean:js', () => {
return del(['dist/js'])
})
gulp.task('clean', gulp.parallel('clean:css', 'clean:js'))
/** TASKS: BUILD */
gulp.task('build:css', () => {
const plugins = [
postcssPresetEnv()
]
// Minify on production
if (process.env.NODE_ENV !== 'development')
plugins.push(cssnano())
return gulp.src('./src/css/**/*.css')
.pipe(sourcemaps.init())
.pipe(postcss(plugins))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./dist/css'))
})
gulp.task('build:js', () => {
return gulp.src('./src/js/**/*.js')
.pipe(sourcemaps.init())
.pipe(buble())
// Minify on production
.pipe(gulpif(process.env.NODE_ENV !== 'development', terser()))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./dist/js'))
})
gulp.task('build', gulp.parallel('build:css', 'build:js'))
gulp.task('default', gulp.series('lint', 'clean', 'build'))
/** TASKS: WATCH (SKIP LINTER) */
gulp.task('watch:css', () => {
return gulp.watch([
'src/**/*.css'
], gulp.series('clean:css', 'build:css'))
})
gulp.task('watch:js', () => {
return gulp.watch([
'src/**/*.js'
], gulp.series('clean:js', 'build:js'))
})
gulp.task('watch:src', gulp.parallel('watch:css', 'watch:js'))
gulp.task('nodemon', done => {
return nodemon({
script: './lolisafe.js',
env: process.env,
watch: [
'lolisafe.js',
'logger.js',
'config.js',
'controllers/',
'database/',
'routes/'
],
ext: 'js',
done
})
})
gulp.task('watch', gulp.series('clean', 'build', gulp.parallel('watch:src', 'nodemon')))

@ -1,13 +1,13 @@
const bodyParser = require('body-parser')
const clamd = require('clamdjs')
const config = require('./config')
const express = require('express')
const helmet = require('helmet')
const logger = require('./logger')
const nunjucks = require('nunjucks')
const path = require('path')
const RateLimit = require('express-rate-limit')
const readline = require('readline')
const config = require('./config')
const logger = require('./logger')
const safe = express()
process.on('uncaughtException', error => {
@ -50,6 +50,8 @@ if (Array.isArray(config.rateLimits) && config.rateLimits.length)
safe.use(bodyParser.urlencoded({ extended: true }))
safe.use(bodyParser.json())
let setHeaders
// Cache control (safe.fiery.me)
if (config.cacheControl) {
const cacheControls = {
@ -66,16 +68,6 @@ if (config.cacheControl) {
next()
})
const setHeaders = res => {
res.set('Access-Control-Allow-Origin', '*')
res.set('Cache-Control', cacheControls.default)
}
if (config.serveFilesWithNode)
safe.use('/', express.static(paths.uploads, { setHeaders }))
safe.use('/', express.static(paths.public, { setHeaders }))
// Do NOT cache these dynamic routes
safe.use(['/a', '/api', '/nojs'], (req, res, next) => {
res.set('Cache-Control', cacheControls.disable)
@ -93,13 +85,19 @@ if (config.cacheControl) {
setHeaders(res)
next()
})
} else {
if (config.serveFilesWithNode)
safe.use('/', express.static(paths.uploads))
safe.use('/', express.static(paths.public))
setHeaders = res => {
res.set('Access-Control-Allow-Origin', '*')
res.set('Cache-Control', cacheControls.default)
}
}
if (config.serveFilesWithNode)
safe.use('/', express.static(paths.uploads, { setHeaders }))
safe.use('/', express.static(paths.public, { setHeaders }))
safe.use('/', express.static(paths.dist, { setHeaders }))
safe.use('/', album)
safe.use('/', nojs)
safe.use('/api', api)
@ -247,7 +245,10 @@ safe.use('/api', api)
prompt: ''
}).on('line', line => {
try {
if (line === '.exit') process.exit(0)
if (line === 'rs')
return
if (line === '.exit')
return process.exit(0)
// eslint-disable-next-line no-eval
logger.log(eval(line))
} catch (error) {

@ -15,8 +15,11 @@
"license": "MIT",
"scripts": {
"start": "node ./lolisafe.js",
"startdev": "env NODE_ENV=development node ./lolisafe.js",
"pm2": "pm2 start --name safe ./lolisafe.js",
"pm2": "pm2 start ./lolisafe.js",
"lint": "gulp lint",
"build": "gulp default",
"watch": "gulp watch",
"develop": "env NODE_ENV=development yarn watch",
"cf-purge": "node ./scripts/cf-purge.js",
"clean-up": "node ./scripts/clean-up.js",
"delete-expired": "node ./scripts/delete-expired.js",
@ -43,12 +46,27 @@
"systeminformation": "^4.14.8"
},
"devDependencies": {
"eslint": "^6.3.0",
"browserslist": "^4.7.0",
"cssnano": "^4.1.10",
"del": "^5.1.0",
"eslint": "^6.4.0",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-compat": "^3.3.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"gulp": "^4.0.2",
"gulp-buble": "^0.9.0",
"gulp-cli": "^2.2.0",
"gulp-eslint": "^6.0.0",
"gulp-if": "^3.0.0",
"gulp-nodemon": "^2.4.2",
"gulp-postcss": "^8.0.0",
"gulp-sourcemaps": "^2.6.5",
"gulp-stylelint": "^9.0.0",
"gulp-terser": "^1.2.0",
"postcss-preset-env": "^6.7.0",
"stylelint": "^10.1.0",
"stylelint-config-standard": "^18.3.0"
}

@ -1,31 +0,0 @@
input {
background: rgba(0, 0, 0, 0)
}
input,
a {
border-left: 0;
border-top: 0;
border-right: 0;
border-radius: 0;
-webkit-box-shadow: 0 0 0;
box-shadow: 0 0 0
}
.select-wrapper {
text-align: center;
margin-bottom: 10px
}
#login .input {
border-top: 0;
border-right: 0;
border-left: 0;
border-radius: 0;
padding-right: calc(0.75em + 1px);
padding-left: calc(0.75em + 1px)
}
#login .control .button {
border-radius: 0
}

@ -1,15 +1,6 @@
Font license info
## Typicons
(c) Stephen Hutchings 2012
Author: Stephen Hutchings
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://typicons.com/
## Elusive
Copyright (C) 2013 by Aristeides Stathopoulos

@ -0,0 +1,240 @@
{
"name": "",
"css_prefix_text": "icon-",
"css_use_suffix": false,
"hinting": true,
"units_per_em": 1000,
"ascent": 850,
"glyphs": [
{
"uid": "01b8329f17c7058552798e482d41b794",
"css": "sharex",
"code": 59393,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M328 923C230 913 145 849 99 752 47 642 56 506 123 406 167 340 230 296 304 280 325 276 374 276 395 280 440 290 481 310 515 339 522 344 527 349 527 349 526 349 517 351 507 353 385 370 284 451 250 558 240 587 238 603 238 637 238 671 240 687 250 717 264 758 285 792 320 826 352 859 384 881 427 898L443 905 436 908C424 913 391 921 371 923 351 925 346 925 328 923ZM576 934C512 929 455 910 406 878 340 834 296 770 280 696 276 675 276 626 281 605 290 560 310 519 339 485 344 478 349 473 349 473 350 474 351 483 353 493 370 615 451 716 558 750 587 760 603 762 637 762 683 762 711 755 754 734 816 703 869 644 898 573L905 557 908 564C918 587 926 638 924 663 916 766 852 853 752 901 699 926 632 939 576 934ZM618 722C573 715 528 695 491 667 471 651 471 650 482 649 611 633 715 552 750 442 760 413 762 397 762 363 762 317 755 289 734 246 704 185 646 132 577 104 564 98 558 95 560 94 564 91 595 82 610 80 634 75 652 75 672 77 737 84 794 112 842 162 866 187 881 209 897 240 919 283 930 324 934 374 940 451 919 531 878 594 834 659 771 703 698 719 683 723 634 724 618 722ZM649 518C633 389 552 285 442 250 413 240 397 238 363 238 319 238 291 245 251 263 221 278 200 293 174 319 141 352 119 384 102 427L95 443 92 436C82 413 74 362 76 337 85 234 148 147 248 99 329 60 426 55 512 83 550 95 579 110 610 133 665 175 705 236 719 302 723 320 725 359 722 378 716 425 697 470 667 509 651 529 651 529 649 518Z",
"width": 1000
},
"search": [
"sharex"
]
},
{
"uid": "7961745a0533e615b5e9f5cf39b902dc",
"css": "terminal",
"code": 59408,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M929 71H71C32 71 0 103 0 143V857C0 897 32 929 71 929H929C968 929 1000 897 1000 857V143C1000 103 968 71 929 71ZM143 571L286 429 143 286 214 214 429 429 214 643 143 571ZM714 643H429V571H714V643Z",
"width": 1000
},
"search": [
"terminal"
]
},
{
"uid": "dec0ce0476433f7e49e096526cf89465",
"css": "hammer",
"code": 59409,
"src": "fontawesome"
},
{
"uid": "4bcff864c368690c11e641fcf71d229b",
"css": "privatebin",
"code": 59415,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M484.4 980.9C477 977.1 377.4 922.9 263 860.4 112.4 778.1 54.3 745.5 52.4 741.9 50.2 737.9 50 694.3 51 497 52.2 275.7 52.5 256.7 55.6 253.6 57.5 251.7 157.1 196.9 277 131.9 427.9 50.1 496.8 13.7 501 13.7 504.6 13.7 515.5 18.5 528 25.4 539.5 31.8 638 85.6 746.9 145.1 890.4 223.4 945.7 254.5 947.6 258.1 949.8 262.1 950 305.7 949 503 947.8 724 947.5 743.3 944.4 746.4 940.6 750.3 508.4 984.9 502 986.6 499.5 987.2 492.5 985 484.4 980.9ZM622 768C622 767 614.3 736.8 605 701 573.8 581.9 558.6 513.8 556.6 484.8L555.4 466.5 576 444.8C612.6 405.9 631.9 371 633.6 340.5 634.3 327 633.7 322 630.2 312.5 620.7 287.2 593 259.3 563.2 245.1 512.7 221 460.5 226.7 420.5 260.6 387.4 288.8 370.2 323.3 372.5 356.7 374.5 384.8 389.9 412 422.4 444.5 433.2 455.2 442.5 466.4 443.2 469.3 445.4 477.8 442.6 507 437 536 430.3 570.4 408.2 659.3 391.2 720.3 383.9 746.3 378 768.1 378 768.8 378 769.5 432.9 770 500 770 577.9 770 622 769.3 622 768Z",
"width": 1000
},
"search": [
"privatebin"
]
},
{
"uid": "4109c474ff99cad28fd5a2c38af2ec6f",
"css": "filter",
"code": 61616,
"src": "fontawesome"
},
{
"uid": "c8585e1e5b0467f28b70bce765d5840c",
"css": "docs",
"code": 61637,
"src": "fontawesome"
},
{
"uid": "178053298e3e5b03551d754d4b9acd8b",
"css": "doc-inv",
"code": 61787,
"src": "fontawesome"
},
{
"uid": "98d9c83c1ee7c2c25af784b518c522c5",
"css": "block",
"code": 59410,
"src": "fontawesome"
},
{
"uid": "0ddd3e8201ccc7d41f7b7c9d27eca6c1",
"css": "link",
"code": 59411,
"src": "fontawesome"
},
{
"uid": "98687378abd1faf8f6af97c254eb6cd6",
"css": "cog-alt",
"code": 59412,
"src": "fontawesome"
},
{
"uid": "f4445feb55521283572ee88bc304f928",
"css": "floppy",
"code": 59413,
"src": "fontawesome"
},
{
"uid": "bd7fd67bed189448225cad0fe4ef3d7c",
"css": "chrome",
"code": 62056,
"src": "fontawesome"
},
{
"uid": "c97bfbcfb31e74be0653d8551c89a40f",
"css": "firefox",
"code": 62057,
"src": "fontawesome"
},
{
"uid": "1bafeeb1808a5fe24484c7890096901a",
"css": "user-plus",
"code": 59414,
"src": "fontawesome"
},
{
"uid": "5d595124cecf472869d1cdc020da0ccc",
"css": "upload-cloud",
"code": 59417,
"src": "entypo"
},
{
"uid": "a1be363d4de9be39857893d4134f6215",
"css": "picture",
"code": 59394,
"src": "elusive"
},
{
"uid": "50e664a6f12199784c02600b2ccfd60a",
"css": "th-list",
"code": 59395,
"src": "elusive"
},
{
"uid": "76f961b11f65300838a5a78856aca30f",
"css": "th-large",
"code": 59418,
"src": "elusive"
},
{
"uid": "3ab2abf6f936d3e53ee8c184cedaed82",
"css": "trash",
"code": 59396,
"src": "elusive"
},
{
"uid": "a73c5deb486c8d66249811642e5d719a",
"css": "arrows-cw",
"code": 59398,
"src": "fontawesome"
},
{
"uid": "55e2ff85b1c459c383f46da6e96014b0",
"css": "plus",
"code": 59399,
"src": "elusive"
},
{
"uid": "499b745a2e2485bdd059c3a53d048e5f",
"css": "cancel",
"code": 59397,
"src": "elusive"
},
{
"uid": "3a00327e61b997b58518bd43ed83c3df",
"css": "login",
"code": 59401,
"src": "fontawesome"
},
{
"uid": "d7271d490b71df4311e32cdacae8b331",
"css": "home",
"code": 59402,
"src": "fontawesome"
},
{
"uid": "0bda4bc779d4c32623dec2e43bd67ee8",
"css": "gauge",
"code": 59403,
"src": "fontawesome"
},
{
"uid": "17ebadd1e3f274ff0205601eef7b9cc4",
"css": "help-circled",
"code": 59405,
"src": "fontawesome"
},
{
"uid": "0f6a2573a7b6df911ed199bb63717e27",
"css": "github-circled",
"code": 59406,
"src": "fontawesome"
},
{
"uid": "38575a803c4da31ce20d77e1e1236bcb",
"css": "paper-plane",
"code": 61912,
"src": "fontawesome"
},
{
"uid": "62b0580ee8edc3a3edfbf68a47c852d5",
"css": "pencil",
"code": 59407,
"src": "elusive"
},
{
"uid": "96ea1be71f597a5bdfc8f791ada4f651",
"css": "archive",
"code": 59392,
"src": "entypo"
},
{
"uid": "9a76bc135eac17d2c8b8ad4a5774fc87",
"css": "download",
"code": 59419,
"src": "fontawesome"
},
{
"uid": "1a27e6346cdf0480c9c22351378bebbb",
"css": "clipboard",
"code": 59400,
"src": "typicons"
},
{
"uid": "92cf34c9a8e5d2486d75fcd393dffb07",
"css": "gatsby",
"code": 59420,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M500 33.3C243.3 33.3 33.3 243.3 33.3 500S243.3 966.7 500 966.7 966.7 756.7 966.7 500 756.7 33.3 500 33.3ZM240 760C170 690 133.3 596.7 133.3 506.7L496.7 866.7C403.3 863.3 310 830 240 760ZM580 856.7L143.3 420C180 256.7 326.7 133.3 500 133.3 623.3 133.3 730 193.3 796.7 283.3L746.7 326.7C690 250 600 200 500 200 370 200 260 283.3 216.7 400L600 783.3C696.7 750 770 666.7 793.3 566.7H633.3V500H866.7C866.7 673.3 743.3 820 580 856.7Z",
"width": 1000
},
"search": [
"gatsby"
]
}
]
}

@ -1,11 +1,11 @@
@font-face {
font-family: 'fontello';
src: url('fontello.eot?tWLiAlAX5i');
src: url('fontello.eot?tWLiAlAX5i#iefix') format('embedded-opentype'),
url('fontello.woff2?tWLiAlAX5i') format('woff2'),
url('fontello.woff?tWLiAlAX5i') format('woff'),
url('fontello.ttf?tWLiAlAX5i') format('truetype'),
url('fontello.svg?tWLiAlAX5i#fontello') format('svg');
src: url('fontello.eot?fFS2CGH95j');
src: url('fontello.eot?fFS2CGH95j#iefix') format('embedded-opentype'),
url('fontello.woff2?fFS2CGH95j') format('woff2'),
url('fontello.woff?fFS2CGH95j') format('woff'),
url('fontello.ttf?fFS2CGH95j') format('truetype'),
url('fontello.svg?fFS2CGH95j#fontello') format('svg');
font-weight: normal;
font-style: normal;
}
@ -15,7 +15,7 @@
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'fontello';
src: url('fontello.svg?tWLiAlAX5i#fontello') format('svg');
src: url('fontello.svg?fFS2CGH95j#fontello') format('svg');
}
}
*/
@ -59,35 +59,36 @@
font-size: 2rem;
}
.icon-pencil-1:before { content: '\e800'; } /* '' */
.icon-archive:before { content: '\e800'; } /* '' */
.icon-sharex:before { content: '\e801'; } /* '' */
.icon-upload-cloud:before { content: '\e802'; } /* '' */
.icon-picture-1:before { content: '\e803'; } /* '' */
.icon-th-list:before { content: '\e804'; } /* '' */
.icon-trash:before { content: '\e805'; } /* '' */
.icon-th-large:before { content: '\e806'; } /* '' */
.icon-arrows-cw:before { content: '\e807'; } /* '' */
.icon-plus:before { content: '\e808'; } /* '' */
.icon-cancel:before { content: '\e809'; } /* '' */
.icon-archive:before { content: '\e80a'; } /* '' */
.icon-clipboard-1:before { content: '\e80b'; } /* '' */
.icon-login:before { content: '\e80c'; } /* '' */
.icon-home:before { content: '\e80d'; } /* '' */
.icon-download:before { content: '\e80e'; } /* '' */
.icon-help-circled:before { content: '\e80f'; } /* '' */
.icon-picture:before { content: '\e802'; } /* '' */
.icon-th-list:before { content: '\e803'; } /* '' */
.icon-trash:before { content: '\e804'; } /* '' */
.icon-cancel:before { content: '\e805'; } /* '' */
.icon-arrows-cw:before { content: '\e806'; } /* '' */
.icon-plus:before { content: '\e807'; } /* '' */
.icon-clipboard:before { content: '\e808'; } /* '' */
.icon-login:before { content: '\e809'; } /* '' */
.icon-home:before { content: '\e80a'; } /* '' */
.icon-gauge:before { content: '\e80b'; } /* '' */
.icon-help-circled:before { content: '\e80d'; } /* '' */
.icon-github-circled:before { content: '\e80e'; } /* '' */
.icon-pencil:before { content: '\e80f'; } /* '' */
.icon-terminal:before { content: '\e810'; } /* '' */
.icon-hammer:before { content: '\e811'; } /* '' */
.icon-block:before { content: '\e812'; } /* '' */
.icon-link:before { content: '\e813'; } /* '' */
.icon-cog-alt:before { content: '\e814'; } /* '' */
.icon-floppy:before { content: '\e815'; } /* '' */
.icon-user-plus:before { content: '\e816'; } /* '' */
.icon-privatebin:before { content: '\e817'; } /* '' */
.icon-github-circled:before { content: '\f09b'; } /* '' */
.icon-upload-cloud:before { content: '\e819'; } /* '' */
.icon-th-large:before { content: '\e81a'; } /* '' */
.icon-download:before { content: '\e81b'; } /* '' */
.icon-gatsby:before { content: '\e81c'; } /* '' */
.icon-filter:before { content: '\f0b0'; } /* '' */
.icon-docs:before { content: '\f0c5'; } /* '' */
.icon-gauge:before { content: '\f0e4'; } /* '' */
.icon-doc-inv:before { content: '\f15b'; } /* '' */
.icon-paper-plane-empty:before { content: '\f1d9'; } /* '' */
.icon-user-plus:before { content: '\f234'; } /* '' */
.icon-paper-plane:before { content: '\f1d8'; } /* '' */
.icon-chrome:before { content: '\f268'; } /* '' */
.icon-firefox:before { content: '\f269'; } /* '' */

Binary file not shown.

@ -6,37 +6,35 @@
<font id="fontello" horiz-adv-x="1000" >