diff --git a/.gitignore b/.gitignore index 403adbc..8e166d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,7 @@ -.DS_Store +# Node Modules node_modules -/dist - -# local env files +# Local ENV files .env.local .env.*.local @@ -13,7 +11,7 @@ yarn-debug.log* yarn-error.log* pnpm-debug.log* -# Editor directories and files +# Editor Directories/Files .idea .vscode *.suo @@ -21,3 +19,10 @@ pnpm-debug.log* *.njsproj *.sln *.sw? +.DS_Store + +yarn.lock + +# Custom +.env +config/config.json \ No newline at end of file diff --git a/config/config.json b/config/config.json deleted file mode 100644 index e1cf688..0000000 --- a/config/config.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "development": { - "username": "troplo_watchdogs", - "password": "Hum%r4T3g#*@W7F65wz%", - "database": "troplo_watchdogs", - "host": "192.168.0.13", - "dialect": "mysql", - "logging": false - }, - "test": { - "username": "troplo_watchdogs", - "password": "Hum%r4T3g#*@W7F65wz%", - "database": "troplo_watchdogs", - "host": "192.168.0.13", - "dialect": "mysql", - "logging": false - }, - "production": { - "username": "troplo_watchdogs", - "password": "Hum%r4T3g#*@W7F65wz%", - "database": "troplo_watchdogs", - "host": "192.168.0.13", - "dialect": "mysql", - "logging": false - } -} diff --git a/index.js b/index.js deleted file mode 100644 index 970656f..0000000 --- a/index.js +++ /dev/null @@ -1,142 +0,0 @@ -const crc32 = require('js-crc').crc32; - -const fs = require("fs"); -const glob = require("glob"); -const { File } = require("./models") -const {Op} = require("sequelize"); -const express = require('express') -const os = require("os"); -const moment = require("moment"); -const app = express() -const port = 34895 -const fsPromises = require("fs").promises -const readdir = fsPromises.readdir -const nodePath = require("path") -const path = require("path"); -const stat = fsPromises.stat -async function list(depot, path) { - try { - let root - if(depot === "wd1") { - root = "/root/depots/" + depot - } else if(depot === "wdl-2450") { - root = "/root/depots/wdl-2450-main" - } else { - return {success: false, message: "Depot not found."} - } - let code = depot - let dirs = [], - files = []; - - if (path[path.length - 1] !== "/") { - path += "/"; - } - - let filePath = nodePath.join(root + path); - console.log(filePath) - if (filePath.startsWith(root)) { - let items = await readdir(root + path, { withFileTypes: true }); - - for (let item of items) { - let isFile = item.isFile(), - isDir = item.isDirectory(); - - if (!isFile && !isDir) { - continue; - } - - let result = { - type: isFile ? "file" : "dir", - path: path + item.name, - }; - - result.basename = result.name = nodePath.basename(result.path); - - if (isFile) { - let fileStat = await stat(root + result.path); - result.size = fileStat.size; - result.extension = nodePath.extname(result.path).slice(1); - result.name = nodePath.basename(result.path, "." + result.extension); - files.push(result); - } else { - result.path += "/"; - dirs.push(result); - } - } - - return dirs.concat(files); - } else { - return {success: false, message: "Folder was not found in the depot"} - } - } catch (err) { - console.error(err); - } -} - -app.get('/api/v1/browser/:depot/list', async(req, res) => { - try { - let result = await list(req.params.depot, req.query.path); - return res.json(result); - } catch (e){ - console.log(e) - res.json({success: false, message: "Something went wrong."}) - } -}) - -app.get('/api/v1/browser/:depot/download', async(req, res) => { - try { - let root - if(req.params.depot === "wd1") { - root = "/root/depots/" + req.params.depot + "/" - } else if(req.params.depot === "wdl-2450") { - root = "M:/" - } else { - return {success: false, message: "Depot not found."} - } - let file = root + req.query.path - let fileTest = fs.readFileSync(file, 'utf8') - let filePath = nodePath.join(file); - console.log(filePath) - if (filePath.startsWith(root)) { - res.download(file, file.name) - } else { - res.status(400) - res.json({success: false, message: "Something went wrong."}) - } - } catch (e){ - console.log(e) - res.status(400) - res.json({success: false, message: "Something went wrong."}) - } -}) - -app.get('/api/v1/dl/:id', async(req, res) => { - try { - const find = await File.findOne({ - where: { - id: req.params.id - } - }) - if (find) { - if (find.fileObject) { - let file = find.path.replace(/^.*[\\\/]/, '') - res.download("/root/depots/" + find.project + "/" + find.path, file) - } - } else { - res.json({success: false, message: "This hash, or definition does not yet exist in our database."}) - } - } catch (e){ - console.log(e) - res.json({success: false, message: "Something went wrong while retrieving this file."}) - } -}) - -app.get('/', async(req, res) => { - res.redirect('https://discord.gg/WKXjxj6kRN') -}) - -app.listen(port, () => { - console.log(`Nexus API running at http://localhost:${port}`) -}) - -module.exports = app; diff --git a/migrations/20210924121330-files.js b/migrations/20210924121330-files.js deleted file mode 100644 index e8447ad..0000000 --- a/migrations/20210924121330-files.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; -module.exports = { - up: async(queryInterface, Sequelize) => { - await queryInterface.createTable('files', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.BIGINT - }, - crc32: Sequelize.STRING, - fnv32: Sequelize.STRING, - fnv64: Sequelize.STRING, - path: Sequelize.STRING, - project: { - type: Sequelize.STRING, - defaultValue: "wd1Retail" - }, - createdAt: { - type: Sequelize.DATE - }, - updatedAt: { - type: Sequelize.DATE - } - }); - }, - down: async(queryInterface, Sequelize) => { - await queryInterface.dropTable('files'); - } -}; \ No newline at end of file diff --git a/migrations/20210924132702-definition.js b/migrations/20210924132702-definition.js deleted file mode 100644 index 831d9c0..0000000 --- a/migrations/20210924132702-definition.js +++ /dev/null @@ -1,48 +0,0 @@ -module.exports = { - up(queryInterface, Sequelize) { - return Promise.all([ - queryInterface.addColumn( - 'files', - 'definition', - { - type: Sequelize.TEXT, - }, - ), - queryInterface.addColumn( - 'files', - 'fnv32Rev', - { - type: Sequelize.STRING, - }, - ), - queryInterface.addColumn( - 'files', - 'fnv64Rev', - { - type: Sequelize.STRING, - }, - ), - queryInterface.addColumn( - 'files', - 'crc32Rev', - { - type: Sequelize.STRING, - }, - ), - queryInterface.addColumn( - 'files', - 'fileObject', - { - type: Sequelize.JSON, - }, - ), - queryInterface.addColumn( - 'files', - 'otherProperties', - { - type: Sequelize.JSON, - }, - ), - ]); - }, -} \ No newline at end of file diff --git a/models/files.js b/models/files.js deleted file mode 100644 index 5a23404..0000000 --- a/models/files.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict'; -const { - Model, DATE -} = require('sequelize'); - -module.exports = (sequelize, DataTypes) => { - class File extends Model { - /** - * Helper method for defining associations. - * This method is not a part of Sequelize lifecycle. - * The `models/index` file will call this method automatically. - */ - static associate(models) { - - } - } - File.init({ - crc32: DataTypes.STRING, - fnv32: DataTypes.STRING, - fnv64: DataTypes.STRING, - path: DataTypes.STRING, - project: { - type: DataTypes.STRING, - defaultValue: "wd1Retail" - }, - createdAt: { - type: DataTypes.DATE - }, - updatedAt: { - type: DataTypes.DATE - }, - definition: DataTypes.TEXT, - fnv32Rev: DataTypes.STRING, - fnv64Rev: DataTypes.STRING, - crc32Rev: DataTypes.STRING, - fileObject: DataTypes.JSON, - otherProperties: DataTypes.JSON - }, { - sequelize, - modelName: 'File', - }); - - return File; -}; \ No newline at end of file diff --git a/models/index.js b/models/index.js deleted file mode 100644 index 4f8171f..0000000 --- a/models/index.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const Sequelize = require('sequelize'); -const basename = path.basename(__filename); -const env = process.env.NODE_ENV || 'development'; -const config = require(__dirname + '/../config/config.json')[env]; -const db = {}; - -let sequelize; -if (config.use_env_variable) { - sequelize = new Sequelize(process.env[config.use_env_variable], config); -} else { - sequelize = new Sequelize(config.database, config.username, config.password, config); -} - -fs - .readdirSync(__dirname) - .filter(file => { - return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); - }) - .forEach(file => { - const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes); - db[model.name] = model; - }); - -Object.keys(db).forEach(modelName => { - if (db[modelName].associate) { - db[modelName].associate(db); - } -}); - -db.sequelize = sequelize; -db.Sequelize = Sequelize; - -module.exports = db; diff --git a/package.json b/package.json index 2f9b872..5a86df1 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,41 @@ { + "name": "jays-host", + "version": "1.0.0", + "description": "A ShareX photo gallery.", + "main": "index.js", + "scripts": { + "serve": "nodemon --ignore ./ui/" + }, + "author": "Troplo", + "license": "Internal use only.", + "private": true, "dependencies": { + "@discordjs/rest": "^0.1.0-canary.0", + "axios": "^0.21.1", + "bcryptjs": "^2.4.3", + "body-parser": "^1.19.0", + "btcpay": "^0.2.5", + "btoa": "^1.2.1", + "cloudflare": "^2.8.0", + "cors": "^2.8.5", + "crypto-random-string": "3.3.1", + "discord.js": "^13.1.0", + "dotenv": "^10.0.0", "express": "^4.17.1", - "glob": "^7.2.0", - "js-crc": "^0.2.0", + "express-autosanitizer": "^1.0.2", + "form-data": "^4.0.0", + "helmet": "^4.6.0", + "is-valid-domain": "^0.1.2", + "jsonwebtoken": "^8.5.1", + "jw-paginate": "^1.0.4", + "microstats": "^0.1.2", "moment": "^2.29.1", - "mysql2": "^2.3.0", - "sequelize": "^6.6.5" + "multer": "^1.4.2", + "mysql2": "^2.2.5", + "nodemon": "^2.0.12", + "sequelize": "^6.6.5", + "sequelize-cli": "^6.2.0", + "speakeasy": "^2.0.0", + "whois": "^2.13.5" } } - diff --git a/ui/.eslintrc.js b/ui/.eslintrc.js index 3391da1..8ad90db 100644 --- a/ui/.eslintrc.js +++ b/ui/.eslintrc.js @@ -4,7 +4,7 @@ module.exports = { node: true }, 'extends': [ - 'plugin:vue/vue3-essential', + 'plugin:vue/essential', 'eslint:recommended' ], parserOptions: { diff --git a/ui/package.json b/ui/package.json index 20fd121..d819e5c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,35 +1,34 @@ { "name": "ui", - "version": "0.1.0", + "version": "1.0.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", - "lint": "vue-cli-service lint" + "lint": "vue-cli-service lint", + "postinstall": "patch-package" }, "dependencies": { - "@mdi/font": "5.9.55", "core-js": "^3.6.5", - "roboto-fontface": "*", - "vue": "^3.0.0", - "vue-router": "^4.0.0-0", - "vuetify": "^3.0.0-alpha.0", - "vuex": "^4.0.0-0", - "webfontloader": "^1.0.0" + "patch-package": "^6.4.7", + "register-service-worker": "^1.7.1", + "vue": "^2.6.11", + "vue-router": "^3.2.0", + "vuetify": "^2.4.0" }, "devDependencies": { "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", + "@vue/cli-plugin-pwa": "~4.5.0", "@vue/cli-plugin-router": "~4.5.0", - "@vue/cli-plugin-vuex": "~4.5.0", - "@vue/cli-service": "~5.0.0-beta.3", - "@vue/compiler-sfc": "^3.0.0", + "@vue/cli-service": "~4.5.0", "babel-eslint": "^10.1.0", "eslint": "^6.7.2", - "eslint-plugin-vue": "^7.0.0", - "sass": "^1.38.0", + "eslint-plugin-vue": "^6.2.2", + "sass": "~1.32.0", "sass-loader": "^10.0.0", - "vue-cli-plugin-vuetify": "~2.4.3", - "vuetify-loader": "^2.0.0-alpha.0" + "vue-cli-plugin-vuetify": "~2.4.2", + "vue-template-compiler": "^2.6.11", + "vuetify-loader": "^1.7.0" } } diff --git a/ui/patches/vuetify+2.5.8.patch b/ui/patches/vuetify+2.5.8.patch new file mode 100644 index 0000000..6bf4e99 --- /dev/null +++ b/ui/patches/vuetify+2.5.8.patch @@ -0,0 +1,425 @@ +diff --git a/node_modules/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.sass b/node_modules/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.sass +index ee4419a..6d1ba3d 100644 +--- a/node_modules/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.sass ++++ b/node_modules/vuetify/src/components/VNavigationDrawer/VNavigationDrawer.sass +@@ -9,7 +9,7 @@ + background-color: map-get($material, 'dividers') + + .v-divider +- border-color: map-get($material, 'dividers') ++ width: 0 + + // Block + .v-navigation-drawer +diff --git a/node_modules/vuetify/src/styles/settings/_variables.scss b/node_modules/vuetify/src/styles/settings/_variables.scss +index f5cc26b..6b998f1 100644 +--- a/node_modules/vuetify/src/styles/settings/_variables.scss ++++ b/node_modules/vuetify/src/styles/settings/_variables.scss +@@ -2,23 +2,24 @@ + + $color-pack: true !default; + +-$body-font-family: 'Roboto', sans-serif !default; ++$body-font-family: 'Montserrat', sans-serif !default; + $font-size-root: 16px !default; + $line-height-root: 1.5 !default; + $border-radius-root: 4px !default; + + $rounded: () !default; + $rounded: map-deep-merge( +- ( +- 0: 0, +- 'sm': $border-radius-root / 2, +- null: $border-radius-root, +- 'lg': $border-radius-root * 2, +- 'xl': $border-radius-root * 6, +- 'pill': 9999px, +- 'circle': 50% +- ), +- $rounded ++ ( ++ 0: 0, ++ 'sm': $border-radius-root / 2, ++ null: $border-radius-root, ++ 'lg': $border-radius-root * 2, ++ 'xl': $border-radius-root * 3, ++ 'xxl': $border-radius-root * 6, ++ 'pill': 9999px, ++ 'circle': 50% ++ ), ++ $rounded + ); + + $spacer: 4px !default; +@@ -39,14 +40,14 @@ $negative-spacers: () !default; + + $grid-breakpoints: () !default; + $grid-breakpoints: map-deep-merge( +- ( +- 'xs': 0, +- 'sm': 600px, +- 'md': 960px, +- 'lg': 1280px - 16px, +- 'xl': 1920px - 16px +- ), +- $grid-breakpoints ++ ( ++ 'xs': 0, ++ 'sm': 600px, ++ 'md': 960px, ++ 'lg': 1280px - 16px, ++ 'xl': 1920px - 16px ++ ), ++ $grid-breakpoints + ); + + $grid-gutter: $spacer * 6 !default; +@@ -57,191 +58,191 @@ $container-padding-x: $grid-gutter / 2 !default; + + $grid-gutters: () !default; + $grid-gutters: map-deep-merge( +- ( +- 'xs': $grid-gutter / 12, +- 'sm': $grid-gutter / 6, +- 'md': $grid-gutter / 3, +- 'lg': $grid-gutter * 2/3, +- 'xl': $grid-gutter +- ), +- $grid-gutters ++ ( ++ 'xs': $grid-gutter / 12, ++ 'sm': $grid-gutter / 6, ++ 'md': $grid-gutter / 3, ++ 'lg': $grid-gutter * 2/3, ++ 'xl': $grid-gutter ++ ), ++ $grid-gutters + ); + + $container-max-widths: () !default; + $container-max-widths: map-deep-merge( +- ( +- 'md': map-get($grid-breakpoints, 'md') * 0.9375, +- 'lg': map-get($grid-breakpoints, 'lg') * 0.9375, +- 'xl': map-get($grid-breakpoints, 'xl') * 0.9375 +- ), +- $container-max-widths ++ ( ++ 'md': map-get($grid-breakpoints, 'md') * 0.9375, ++ 'lg': map-get($grid-breakpoints, 'lg') * 0.9375, ++ 'xl': map-get($grid-breakpoints, 'xl') * 0.9375 ++ ), ++ $container-max-widths + ); + + $display-breakpoints: () !default; + $display-breakpoints: map-deep-merge( +- ( +- 'print-only': 'only print', +- 'screen-only': 'only screen', +- 'xs-only': 'only screen and (max-width: #{map-get($grid-breakpoints, 'sm') - 1})', +- 'sm-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')}) and (max-width: #{map-get($grid-breakpoints, 'md') - 1})', +- 'sm-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'md') - 1})', +- 'sm-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')})', +- 'md-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')}) and (max-width: #{map-get($grid-breakpoints, 'lg') - 1})', +- 'md-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'lg') - 1})', +- 'md-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')})', +- 'lg-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')}) and (max-width: #{map-get($grid-breakpoints, 'xl') - 1})', +- 'lg-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'xl') - 1})', +- 'lg-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')})', +- 'xl-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'xl')})' +- ), +- $display-breakpoints ++ ( ++ 'print-only': 'only print', ++ 'screen-only': 'only screen', ++ 'xs-only': 'only screen and (max-width: #{map-get($grid-breakpoints, 'sm') - 1})', ++ 'sm-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')}) and (max-width: #{map-get($grid-breakpoints, 'md') - 1})', ++ 'sm-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'md') - 1})', ++ 'sm-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'sm')})', ++ 'md-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')}) and (max-width: #{map-get($grid-breakpoints, 'lg') - 1})', ++ 'md-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'lg') - 1})', ++ 'md-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'md')})', ++ 'lg-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')}) and (max-width: #{map-get($grid-breakpoints, 'xl') - 1})', ++ 'lg-and-down': 'only screen and (max-width: #{map-get($grid-breakpoints, 'xl') - 1})', ++ 'lg-and-up': 'only screen and (min-width: #{map-get($grid-breakpoints, 'lg')})', ++ 'xl-only': 'only screen and (min-width: #{map-get($grid-breakpoints, 'xl')})' ++ ), ++ $display-breakpoints + ); + + $font-weights: () !default; + $font-weights: map-deep-merge( +- ( +- 'thin': 100, +- 'light': 300, +- 'regular': 400, +- 'medium': 500, +- 'bold': 700, +- 'black': 900 +- ), +- $font-weights ++ ( ++ 'thin': 100, ++ 'light': 300, ++ 'regular': 400, ++ 'medium': 500, ++ 'bold': 700, ++ 'black': 900 ++ ), ++ $font-weights + ); + + $heading-font-family: $body-font-family !default; + + $headings: () !default; + $headings: map-deep-merge( +- ( +- 'h1': ( +- 'size': 6rem, +- 'weight': 300, +- 'line-height': 6rem, +- 'letter-spacing': -.015625em, +- 'font-family': $heading-font-family, +- 'text-transform': false +- ), +- 'h2': ( +- 'size': 3.75rem, +- 'weight': 300, +- 'line-height': 3.75rem, +- 'letter-spacing': -.0083333333em, +- 'font-family': $heading-font-family, +- 'text-transform': false +- ), +- 'h3': ( +- 'size': 3rem, +- 'weight': 400, +- 'line-height': 3.125rem, +- 'letter-spacing': normal, +- 'font-family': $heading-font-family, +- 'text-transform': false +- ), +- 'h4': ( +- 'size': 2.125rem, +- 'weight': 400, +- 'line-height': 2.5rem, +- 'letter-spacing': .0073529412em, +- 'font-family': $heading-font-family, +- 'text-transform': false +- ), +- 'h5': ( +- 'size': 1.5rem, +- 'weight': 400, +- 'line-height': 2rem, +- 'letter-spacing': normal, +- 'font-family': $heading-font-family, +- 'text-transform': false +- ), +- 'h6': ( +- 'size': 1.25rem, +- 'weight': 500, +- 'line-height': 2rem, +- 'letter-spacing': .0125em, +- 'font-family': $heading-font-family, +- 'text-transform': false +- ), +- 'subtitle-1': ( +- 'size': 1rem, +- 'weight': normal, +- 'line-height': 1.75rem, +- 'letter-spacing': .009375em, +- 'font-family': $body-font-family, +- 'text-transform': false +- ), +- 'subtitle-2': ( +- 'size': .875rem, +- 'weight': 500, +- 'line-height': 1.375rem, +- 'letter-spacing': .0071428571em, +- 'font-family': $body-font-family, +- 'text-transform': false +- ), +- 'body-1': ( +- 'size': 1rem, +- 'weight': 400, +- 'line-height': 1.5rem, +- 'letter-spacing': .03125em, +- 'font-family': $body-font-family, +- 'text-transform': false +- ), +- 'body-2': ( +- 'size': .875rem, +- 'weight': 400, +- 'line-height': 1.25rem, +- 'letter-spacing': .0178571429em, +- 'font-family': $body-font-family, +- 'text-transform': false +- ), +- 'button': ( +- 'size': .875rem, +- 'weight': 500, +- 'line-height': 2.25rem, +- 'letter-spacing': .0892857143em, +- 'font-family': $body-font-family, +- 'text-transform': uppercase +- ), +- 'caption': ( +- 'size': .75rem, +- 'weight': 400, +- 'line-height': 1.25rem, +- 'letter-spacing': .0333333333em, +- 'font-family': $body-font-family, +- 'text-transform': false +- ), +- 'overline': ( +- 'size': .75rem, +- 'weight': 500, +- 'line-height': 2rem, +- 'letter-spacing': .1666666667em, +- 'font-family': $body-font-family, +- 'text-transform': uppercase +- ) +- ), +- $headings ++ ( ++ 'h1': ( ++ 'size': 6rem, ++ 'weight': 300, ++ 'line-height': 6rem, ++ 'letter-spacing': -.015625em, ++ 'font-family': $heading-font-family, ++ 'text-transform': false ++ ), ++ 'h2': ( ++ 'size': 3.75rem, ++ 'weight': 300, ++ 'line-height': 3.75rem, ++ 'letter-spacing': -.0083333333em, ++ 'font-family': $heading-font-family, ++ 'text-transform': false ++ ), ++ 'h3': ( ++ 'size': 3rem, ++ 'weight': 400, ++ 'line-height': 3.125rem, ++ 'letter-spacing': normal, ++ 'font-family': $heading-font-family, ++ 'text-transform': false ++ ), ++ 'h4': ( ++ 'size': 2.125rem, ++ 'weight': 400, ++ 'line-height': 2.5rem, ++ 'letter-spacing': .0073529412em, ++ 'font-family': $heading-font-family, ++ 'text-transform': false ++ ), ++ 'h5': ( ++ 'size': 1.5rem, ++ 'weight': 400, ++ 'line-height': 2rem, ++ 'letter-spacing': normal, ++ 'font-family': $heading-font-family, ++ 'text-transform': false ++ ), ++ 'h6': ( ++ 'size': 1.25rem, ++ 'weight': 500, ++ 'line-height': 2rem, ++ 'letter-spacing': .0125em, ++ 'font-family': $heading-font-family, ++ 'text-transform': false ++ ), ++ 'subtitle-1': ( ++ 'size': 1rem, ++ 'weight': normal, ++ 'line-height': 1.75rem, ++ 'letter-spacing': .009375em, ++ 'font-family': $body-font-family, ++ 'text-transform': false ++ ), ++ 'subtitle-2': ( ++ 'size': .875rem, ++ 'weight': 500, ++ 'line-height': 1.375rem, ++ 'letter-spacing': .0071428571em, ++ 'font-family': $body-font-family, ++ 'text-transform': false ++ ), ++ 'body-1': ( ++ 'size': 1rem, ++ 'weight': 400, ++ 'line-height': 1.5rem, ++ 'letter-spacing': .03125em, ++ 'font-family': $body-font-family, ++ 'text-transform': false ++ ), ++ 'body-2': ( ++ 'size': .875rem, ++ 'weight': 400, ++ 'line-height': 1.25rem, ++ 'letter-spacing': .0178571429em, ++ 'font-family': $body-font-family, ++ 'text-transform': false ++ ), ++ 'button': ( ++ 'size': .875rem, ++ 'weight': 500, ++ 'line-height': 2.25rem, ++ 'letter-spacing': .0892857143em, ++ 'font-family': $body-font-family, ++ 'text-transform': uppercase ++ ), ++ 'caption': ( ++ 'size': .75rem, ++ 'weight': 400, ++ 'line-height': 1.25rem, ++ 'letter-spacing': .0333333333em, ++ 'font-family': $body-font-family, ++ 'text-transform': false ++ ), ++ 'overline': ( ++ 'size': .75rem, ++ 'weight': 500, ++ 'line-height': 2rem, ++ 'letter-spacing': .1666666667em, ++ 'font-family': $body-font-family, ++ 'text-transform': uppercase ++ ) ++ ), ++ $headings + ); + + $typography: () !default; + @each $type, $values in $headings { + $typography: map-deep-merge( +- $typography, +- (#{$type}: map-values($values)) ++ $typography, ++ (#{$type}: map-values($values)) + ); + } + + $transition: () !default; + $transition: map-deep-merge( +- ( +- 'fast-out-slow-in': cubic-bezier(0.4, 0, 0.2, 1), +- 'linear-out-slow-in': cubic-bezier(0, 0, 0.2, 1), +- 'fast-out-linear-in': cubic-bezier(0.4, 0, 1, 1), +- 'ease-in-out': cubic-bezier(0.4, 0, 0.6, 1), +- 'fast-in-fast-out': cubic-bezier(0.25, 0.8, 0.25, 1), +- 'swing': cubic-bezier(0.25, 0.8, 0.5, 1) +- ), +- $transition ++ ( ++ 'fast-out-slow-in': cubic-bezier(0.4, 0, 0.2, 1), ++ 'linear-out-slow-in': cubic-bezier(0, 0, 0.2, 1), ++ 'fast-out-linear-in': cubic-bezier(0.4, 0, 1, 1), ++ 'ease-in-out': cubic-bezier(0.4, 0, 0.6, 1), ++ 'fast-in-fast-out': cubic-bezier(0.25, 0.8, 0.25, 1), ++ 'swing': cubic-bezier(0.25, 0.8, 0.5, 1) ++ ), ++ $transition + ); + $primary-transition: 0.3s map-get($transition, 'swing') !default; + $secondary-transition: 0.2s map-get($transition, 'ease-in-out') !default; diff --git a/ui/public/img/icons/android-chrome-192x192.png b/ui/public/img/icons/android-chrome-192x192.png new file mode 100644 index 0000000..b02aa64 Binary files /dev/null and b/ui/public/img/icons/android-chrome-192x192.png differ diff --git a/ui/public/img/icons/android-chrome-512x512.png b/ui/public/img/icons/android-chrome-512x512.png new file mode 100644 index 0000000..06088b0 Binary files /dev/null and b/ui/public/img/icons/android-chrome-512x512.png differ diff --git a/ui/public/img/icons/android-chrome-maskable-192x192.png b/ui/public/img/icons/android-chrome-maskable-192x192.png new file mode 100644 index 0000000..791e9c8 Binary files /dev/null and b/ui/public/img/icons/android-chrome-maskable-192x192.png differ diff --git a/ui/public/img/icons/android-chrome-maskable-512x512.png b/ui/public/img/icons/android-chrome-maskable-512x512.png new file mode 100644 index 0000000..5f2098e Binary files /dev/null and b/ui/public/img/icons/android-chrome-maskable-512x512.png differ diff --git a/ui/public/img/icons/apple-touch-icon-120x120.png b/ui/public/img/icons/apple-touch-icon-120x120.png new file mode 100644 index 0000000..1427cf6 Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-120x120.png differ diff --git a/ui/public/img/icons/apple-touch-icon-152x152.png b/ui/public/img/icons/apple-touch-icon-152x152.png new file mode 100644 index 0000000..f24d454 Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-152x152.png differ diff --git a/ui/public/img/icons/apple-touch-icon-180x180.png b/ui/public/img/icons/apple-touch-icon-180x180.png new file mode 100644 index 0000000..404e192 Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-180x180.png differ diff --git a/ui/public/img/icons/apple-touch-icon-60x60.png b/ui/public/img/icons/apple-touch-icon-60x60.png new file mode 100644 index 0000000..cf10a56 Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-60x60.png differ diff --git a/ui/public/img/icons/apple-touch-icon-76x76.png b/ui/public/img/icons/apple-touch-icon-76x76.png new file mode 100644 index 0000000..c500769 Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon-76x76.png differ diff --git a/ui/public/img/icons/apple-touch-icon.png b/ui/public/img/icons/apple-touch-icon.png new file mode 100644 index 0000000..03c0c5d Binary files /dev/null and b/ui/public/img/icons/apple-touch-icon.png differ diff --git a/ui/public/img/icons/favicon-16x16.png b/ui/public/img/icons/favicon-16x16.png new file mode 100644 index 0000000..42af009 Binary files /dev/null and b/ui/public/img/icons/favicon-16x16.png differ diff --git a/ui/public/img/icons/favicon-32x32.png b/ui/public/img/icons/favicon-32x32.png new file mode 100644 index 0000000..46ca04d Binary files /dev/null and b/ui/public/img/icons/favicon-32x32.png differ diff --git a/ui/public/img/icons/msapplication-icon-144x144.png b/ui/public/img/icons/msapplication-icon-144x144.png new file mode 100644 index 0000000..7808237 Binary files /dev/null and b/ui/public/img/icons/msapplication-icon-144x144.png differ diff --git a/ui/public/img/icons/mstile-150x150.png b/ui/public/img/icons/mstile-150x150.png new file mode 100644 index 0000000..3b37a43 Binary files /dev/null and b/ui/public/img/icons/mstile-150x150.png differ diff --git a/ui/public/img/icons/safari-pinned-tab.svg b/ui/public/img/icons/safari-pinned-tab.svg new file mode 100644 index 0000000..e44c0d5 --- /dev/null +++ b/ui/public/img/icons/safari-pinned-tab.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/public/index.html b/ui/public/index.html index 4123528..bc51465 100644 --- a/ui/public/index.html +++ b/ui/public/index.html @@ -6,6 +6,8 @@ <%= htmlWebpackPlugin.options.title %> + +