Websocket updates
0
.eslintrc.json
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
0
.idea/.gitignore
vendored
Normal file → Executable file
6
.idea/dbnavigator.xml
Normal file → Executable file
@ -2,7 +2,7 @@
|
||||
<project version="4">
|
||||
<component name="DBNavigator.Project.DataEditorManager">
|
||||
<record-view-column-sorting-type value="BY_INDEX" />
|
||||
<value-preview-text-wrapping value="true" />
|
||||
<value-preview-text-wrapping value="false" />
|
||||
<value-preview-pinned value="false" />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DataExportManager">
|
||||
@ -31,6 +31,9 @@
|
||||
<component name="DBNavigator.Project.EditorStateManager">
|
||||
<last-used-providers />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ExecutionManager">
|
||||
<retain-sticky-names value="false" />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.MethodExecutionManager">
|
||||
<method-browser />
|
||||
<execution-history>
|
||||
@ -186,7 +189,6 @@
|
||||
<content-type name="JSON5" enabled="true" />
|
||||
<content-type name="JSP" enabled="true" />
|
||||
<content-type name="JSPx" enabled="true" />
|
||||
<content-type name="ASP" enabled="true" />
|
||||
<content-type name="YAML" enabled="true" />
|
||||
</content-types>
|
||||
</qualified-text-editor>
|
||||
|
0
.idea/inspectionProfiles/Project_Default.xml
Normal file → Executable file
0
.idea/jsLibraryMappings.xml
Normal file → Executable file
0
.idea/misc.xml
Normal file → Executable file
0
.idea/modules.xml
Normal file → Executable file
0
.idea/svelte-traintimes.iml
Normal file → Executable file
0
.idea/vcs.xml
Normal file → Executable file
4
copy-cordova.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# rm -rf /home/martin/dev/menuserver/dist/*
|
||||
cp -r /home/martin/dev/svelte-traintimes/public/* /home/martin/dev/traintimes-app/www
|
6
copy.sh
@ -1,4 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
export ENV=production
|
||||
|
||||
npm run-script build
|
||||
# rm -rf /home/martin/dev/menuserver/dist/*
|
||||
cp -r /home/martin/dev/svelte-traintimes/public/* /home/martin/dev/traintimesPWA/live
|
||||
cp -r /home/martin/dev/Svelte/svelte-traintimes/public/* /home/martin/dev/Server/traintimesPWA/live
|
||||
cp -r /home/martin/dev/Svelte/svelte-traintimes/public/* /home/martin/dev/Apps/traintimesFull/traintimesServerV3/live
|
||||
|
0
icon.png
Normal file → Executable file
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
6383
package-lock.json
generated
Normal file → Executable file
34
package.json
Normal file → Executable file
@ -7,29 +7,29 @@
|
||||
"start": "sirv public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^11.0.0",
|
||||
"@rollup/plugin-node-resolve": "^7.0.0",
|
||||
"autoprefixer": "^9.7.6",
|
||||
"eslint": "^6.8.0",
|
||||
"@rollup/plugin-commonjs": "^15.0.0",
|
||||
"@rollup/plugin-node-resolve": "^9.0.0",
|
||||
"autoprefixer": "^9.8.6",
|
||||
"eslint": "^7.7.0",
|
||||
"eslint-plugin-svelte3": "^2.7.3",
|
||||
"node-sass": "^4.13.1",
|
||||
"rollup": "^1.20.0",
|
||||
"rollup-plugin-livereload": "^1.0.0",
|
||||
"node-sass": "^4.14.1",
|
||||
"rollup": "^2.26.4",
|
||||
"rollup-plugin-livereload": "^1.3.0",
|
||||
"rollup-plugin-node-builtins": "^2.1.2",
|
||||
"rollup-plugin-node-globals": "^1.4.0",
|
||||
"rollup-plugin-svelte": "^5.0.3",
|
||||
"rollup-plugin-terser": "^5.1.2",
|
||||
"svelte": "^3.0.0",
|
||||
"svelte-preprocess": "^3.7.1"
|
||||
"rollup-plugin-svelte": "^5.2.3",
|
||||
"rollup-plugin-terser": "^7.0.0",
|
||||
"svelte": "^3.24.1",
|
||||
"svelte-preprocess": "^4.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.2",
|
||||
"localforage": "^1.7.3",
|
||||
"muicss": "^0.10.1",
|
||||
"redaxios": "^0.2.0",
|
||||
"localforage": "^1.9.0",
|
||||
"muicss": "^0.10.2",
|
||||
"redaxios": "^0.3.0",
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"sirv-cli": "^0.4.4",
|
||||
"spectre.css": "^0.5.8",
|
||||
"svelte-spa-router": "^2.1.0"
|
||||
"sirv-cli": "^1.0.6",
|
||||
"spectre.css": "^0.5.9",
|
||||
"svelte-spa-router": "^2.2.0"
|
||||
}
|
||||
}
|
||||
|
3098
pnpm-lock.yaml
Executable file
0
public/browserconfig.xml
Normal file → Executable file
0
public/favicon.png
Normal file → Executable file
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
0
public/global.css
Normal file → Executable file
0
public/img/Icon-144.png
Normal file → Executable file
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
0
public/img/Icon-192.png
Normal file → Executable file
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
0
public/img/Icon-36.png
Normal file → Executable file
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
0
public/img/Icon-48.png
Normal file → Executable file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
0
public/img/Icon-512.png
Normal file → Executable file
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
0
public/img/Icon-72.png
Normal file → Executable file
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
0
public/img/Icon-96.png
Normal file → Executable file
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
0
public/img/android-chrome-192x192.png
Normal file → Executable file
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
0
public/img/apple-touch-icon.png
Normal file → Executable file
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
0
public/img/favicon-16x16.png
Normal file → Executable file
Before Width: | Height: | Size: 984 B After Width: | Height: | Size: 984 B |
0
public/img/favicon-32x32.png
Normal file → Executable file
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
0
public/img/favicon.ico
Normal file → Executable file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
0
public/img/mstile-150x150.png
Normal file → Executable file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
0
public/img/photothumb.db
Normal file → Executable file
0
public/img/safari-pinned-tab.svg
Normal file → Executable file
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
0
public/index.html
Normal file → Executable file
0
public/manifest.json
Normal file → Executable file
0
public/service-worker.js
Normal file → Executable file
12
rollup.config.js
Normal file → Executable file
@ -8,7 +8,8 @@ import sveltePreprocess from 'svelte-preprocess';
|
||||
import builtins from 'rollup-plugin-node-builtins';
|
||||
import globals from 'rollup-plugin-node-globals';
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH;
|
||||
// const production = !process.env.ROLLUP_WATCH;
|
||||
const production = true;
|
||||
|
||||
const preprocess = sveltePreprocess({
|
||||
'scss': {
|
||||
@ -30,6 +31,10 @@ export default {
|
||||
'plugins': [
|
||||
// globals(),
|
||||
// builtins(),
|
||||
replace({
|
||||
'exclude': 'node_modules/**',
|
||||
'__ENV__': JSON.stringify(production ? 'production' : 'development')
|
||||
}),
|
||||
svelte({
|
||||
// enable run-time checks when not in production
|
||||
'dev': !production,
|
||||
@ -51,10 +56,7 @@ export default {
|
||||
'dedupe': ['svelte']
|
||||
}),
|
||||
commonjs(),
|
||||
replace({
|
||||
'exclude': 'node_modules/**',
|
||||
'ENV': JSON.stringify(production ? 'production' : 'development')
|
||||
}),
|
||||
|
||||
|
||||
// In dev mode, call `npm run start` once
|
||||
// the bundle has been generated
|
||||
|
0
src/App.svelte
Normal file → Executable file
0
src/components/Header.svelte
Normal file → Executable file
0
src/components/SettingsEditor.svelte
Normal file → Executable file
8
src/components/SettingsInput.svelte
Normal file → Executable file
@ -59,12 +59,18 @@
|
||||
|
||||
@import "../css/global/dropdown.scss";
|
||||
|
||||
input {
|
||||
background-color: deeppink;
|
||||
padding-bottom: 6px !important;
|
||||
padding-top: 6px !important;
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<span class="mui-dropdown mui-dropdown--right">
|
||||
<label for={name}>{label}</label>
|
||||
<input autocomplete="off" {name} on:keyup={debouncedDoSearch} bind:value />
|
||||
<input class="betterInput" autocomplete="off" {name} on:keyup={debouncedDoSearch} bind:value />
|
||||
{#if searchResults.length > 0}
|
||||
<ul class="mui-dropdown__menu mui--is-open">
|
||||
{#each searchResults as item, index}
|
||||
|
0
src/components/SettingsList.svelte
Normal file → Executable file
0
src/components/SettingsListItem.svelte
Normal file → Executable file
0
src/components/TimetableList.svelte
Normal file → Executable file
7
src/components/TrainRoute.svelte
Normal file → Executable file
@ -84,7 +84,12 @@
|
||||
const workingUrl = url.concat(`&mh=${minuteHash}`)
|
||||
axios.get(workingUrl)
|
||||
.then((d) => {
|
||||
trainData = {...JSON.parse(d.data)};
|
||||
|
||||
// trainData = {...JSON.parse(d.data)};
|
||||
trainData = {...d.data};
|
||||
console.log(trainData);
|
||||
}).catch((err) => {
|
||||
console.error('TrainRoute:getTrain', err);
|
||||
})
|
||||
}
|
||||
|
||||
|
0
src/components/TrainService.svelte
Normal file → Executable file
0
src/components/Twitter.svelte
Normal file → Executable file
183
src/components/TwitterSettings.svelte
Normal file → Executable file
@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import {state} from '../store/store';
|
||||
import {onMount, onDestroy} from 'svelte';
|
||||
import tweeters from '../libs/twitter';
|
||||
|
||||
let _following;
|
||||
let mounted = false;
|
||||
@ -10,15 +11,23 @@
|
||||
mounted=(Object.keys(_following).length > 0);
|
||||
});
|
||||
|
||||
onDestroy(async () => {
|
||||
state.saveTwitterFollowing(_following);
|
||||
});
|
||||
|
||||
state.twitterFollowing.subscribe(async (v) => {
|
||||
const unsubTwitterFollowing = state.twitterFollowing.subscribe(async (v) => {
|
||||
_following = v;
|
||||
mounted=(Object.keys(_following).length > 0);
|
||||
|
||||
console.log('_following', _following);
|
||||
});
|
||||
|
||||
|
||||
|
||||
onDestroy(async () => {
|
||||
state.saveTwitterFollowing(_following);
|
||||
unsubTwitterFollowing();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@ -30,169 +39,17 @@
|
||||
<div class="container ">
|
||||
<div class="text-dark text-subhead">Twitter</div>
|
||||
{#if mounted}
|
||||
|
||||
<div class="grid-1 pad">
|
||||
{#each tweeters as item }
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.nationalrailenq.follow}>
|
||||
@nationalrailenq
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.networkrail.follow}>
|
||||
@networkrail
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailSCOT.follow}>
|
||||
@NetworkRailSCOT
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.AvantiWestCoast.follow}>
|
||||
@AvantiWestCoast
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.CalSleeper.follow}>
|
||||
@CalSleeper
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.CrossCountryUK.follow}>
|
||||
@CrossCountryUK
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.Eurostar.follow}>
|
||||
@Eurostar
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.EurostarUK.follow}>
|
||||
@EurostarUK
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.GatwickExpress.follow}>
|
||||
@GatwickExpress
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.GlasgowSubway.follow}>
|
||||
@GlasgowSubway
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.GWRHelp.follow}>
|
||||
@GWRHelp
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.HeathrowExpress.follow}>
|
||||
@HeathrowExpress
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.LNER.follow}>
|
||||
@LNER
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.LNRailway.follow}>
|
||||
@LNRailway
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.northernassist.follow}>
|
||||
@northernassist
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.ScotRail.follow}>
|
||||
@ScotRail
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.Stansted_Exp.follow}>
|
||||
@Stansted_Exp
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.TfL.follow}>
|
||||
@TfL
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailBHM.follow}>
|
||||
@NetworkRailBHM
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailEDB.follow}>
|
||||
@NetworkRailEDB
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailEUS.follow}>
|
||||
@NetworkRailEUS
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailGLC.follow}>
|
||||
@NetworkRailGLC
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailKGX.follow}>
|
||||
@NetworkRailKGX
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailLST.follow}>
|
||||
@NetworkRailLST
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailMAN.follow}>
|
||||
@NetworkRailMAN
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.NetworkRailVIC.follow}>
|
||||
@NetworkRailVIC
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-body">
|
||||
<input type="checkbox" bind:checked={_following.BTPScotland.follow}>
|
||||
@BTPScotland
|
||||
<input type="checkbox" bind:checked={_following[item.name].follow}>
|
||||
@{item.name}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
0
src/css/common.css
Normal file → Executable file
0
src/css/custom.scss
Normal file → Executable file
0
src/css/entireframework.min.css
vendored
Normal file → Executable file
0
src/css/global.scss
Normal file → Executable file
29
src/css/global/_small.scss
Executable file
@ -0,0 +1,29 @@
|
||||
/* Larger than mobile */
|
||||
@media (max-width: 480px) {
|
||||
.container{
|
||||
max-width: 98vw;
|
||||
padding: 0 0;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 480px) {
|
||||
.navbar {
|
||||
min-height: $navbar-height-small;
|
||||
}
|
||||
|
||||
header + div.container {
|
||||
|
||||
position: relative;
|
||||
top:$navbar-height-small;
|
||||
max-height: calc(100vh - #{$navbar-height-small});
|
||||
|
||||
}
|
||||
|
||||
.navbar .navbar-brand {
|
||||
font-size: 125%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
}
|
||||
|
0
src/css/global/_xlarge.scss
Normal file → Executable file
58
src/css/global/base.scss
Executable file
@ -0,0 +1,58 @@
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
font-family: 'Roboto Condensed', sans-serif;
|
||||
font-size: 1rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $primary-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
a.active{
|
||||
color: $highlight-color;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.container {
|
||||
max-width: 1100px;
|
||||
margin: auto;
|
||||
overflow-y: scroll;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
hr {
|
||||
margin-top: 2.2rem;
|
||||
margin-bottom: 2rem;
|
||||
border-width: 0;
|
||||
border-top: 1px solid $dark-color; }
|
||||
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
140
src/css/global/button.scss
Executable file
@ -0,0 +1,140 @@
|
||||
.btn {
|
||||
display: inline-block;
|
||||
background: $light-color;
|
||||
color: #333;
|
||||
padding: 0.4rem 1.3rem;
|
||||
font-size: 1rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
margin-right: 0.5rem;
|
||||
transition: opacity 0.2s ease-in;
|
||||
outline: none;
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
opacity: 0.60;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
&:enabled:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
|
||||
&--slim {
|
||||
@extend .btn;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
background: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.btn-block {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
font-size: 0.8rem;
|
||||
padding: 0.3rem 1rem;
|
||||
margin-right: 0.2rem;
|
||||
|
||||
&--slim {
|
||||
@extend .btn-sm;
|
||||
padding: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
font-size: 0.6rem;
|
||||
padding: 0.1rem 0.4rem;
|
||||
text-align: center;
|
||||
margin: 0.3rem;
|
||||
background: $light-color;
|
||||
color: #333;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 0.7rem;
|
||||
margin: 1rem 0;
|
||||
opacity: 0.9;
|
||||
background: $light-color;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.bg-primary,
|
||||
.badge-primary,
|
||||
.alert-primary {
|
||||
background: $primary-color;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.btn-light,
|
||||
.bg-light,
|
||||
.badge-light,
|
||||
.alert-light {
|
||||
background: $light-color;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.btn-dark,
|
||||
.bg-dark,
|
||||
.badge-dark,
|
||||
.alert-dark {
|
||||
background: $dark-color;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-danger,
|
||||
.bg-danger,
|
||||
.badge-danger,
|
||||
.alert-danger {
|
||||
background: $danger-color;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-success,
|
||||
.bg-success,
|
||||
.badge-success,
|
||||
.alert-success {
|
||||
background: $success-color;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-white,
|
||||
.bg-white,
|
||||
.badge-white,
|
||||
.alert-white {
|
||||
background: #fff;
|
||||
color: #333;
|
||||
border: #ccc solid 1px;
|
||||
}
|
||||
|
||||
/*.btn:disabled {
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
opacity: 0.60;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
.btn:enabled:hover {
|
||||
opacity: 0.8;
|
||||
}*/
|
||||
|
||||
.bg-light,
|
||||
.badge-light {
|
||||
border: #ccc solid 1px;
|
||||
}
|
39
src/css/global/cards.scss
Executable file
@ -0,0 +1,39 @@
|
||||
/* Cards */
|
||||
.card {
|
||||
padding: 1rem;
|
||||
border: #ccc 1px dotted;
|
||||
margin: 0.7rem 0;
|
||||
|
||||
&--slim {
|
||||
@extend .card;
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
border-bottom-color: #eee;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
margin-bottom: 15px
|
||||
}
|
||||
|
||||
.cardV2 {
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 4px 0 rgba(0,0,0,.14), 0 3px 4px 0 rgba(0,0,0,.12), 0 1px 5px 0 rgba(0,0,0,.2);
|
||||
/*display: flex;
|
||||
flex-direction: column;*/
|
||||
min-width: 0;
|
||||
/*position: relative;
|
||||
word-wrap: break-word;*/
|
||||
}
|
||||
|
||||
.seemore {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.cardLink {
|
||||
color: #2196F3;
|
||||
margin-top: 10px;
|
||||
}
|
126
src/css/global/dropdown.scss
Executable file
@ -0,0 +1,126 @@
|
||||
$mui-use-rem: false !default;
|
||||
@function mui-rem($px) {
|
||||
$x: $px;
|
||||
|
||||
@if $mui-use-rem == true {
|
||||
$x: ($px / 16px) * 1rem;
|
||||
$x: round(1000 * $x) / 1000;
|
||||
}
|
||||
|
||||
@return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* MUI Dropdown module
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// MAIN COMPONENT
|
||||
// ============================================================================
|
||||
.mui-dropdown {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// Toggle element
|
||||
[data-mui-toggle="dropdown"] {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// MENU ELEMENT
|
||||
// ============================================================================
|
||||
.mui-dropdown__menu {
|
||||
// @extend .mui--z1;
|
||||
box-shadow: 0 1px 3px rgba(21,21,21, 0.12),
|
||||
0 1px 2px rgba(21,21,21, 0.24);
|
||||
|
||||
// IE10+ bugfix
|
||||
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
|
||||
border-top: 1px solid rgba(21,21,21, 0.12);
|
||||
border-left: 1px solid rgba(21,21,21, 0.12);
|
||||
}
|
||||
|
||||
// Edge
|
||||
@supports (-ms-ime-align:auto) {
|
||||
border-top: 1px solid rgba(21,21,21, 0.12);
|
||||
border-left: 1px solid rgba(21,21,21, 0.12);
|
||||
}
|
||||
|
||||
position: absolute;
|
||||
display: none;
|
||||
min-width: mui-rem(160px);
|
||||
padding: mui-rem(5px) 0;
|
||||
margin: mui-rem(2px) 0 0; // override default ul
|
||||
list-style: none;
|
||||
font-size: $mui-base-font-size;
|
||||
text-align: left;
|
||||
background-color: $mui-dropdown-bg-color;
|
||||
border-radius: $mui-dropdown-border-radius;
|
||||
z-index: 100;
|
||||
background-clip: padding-box;
|
||||
|
||||
// open state
|
||||
&.mui--is-open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// links within the dropdown menu
|
||||
> li > a {
|
||||
display: block;
|
||||
padding: mui-rem(3px) mui-rem(20px);
|
||||
clear: both;
|
||||
font-weight: normal;
|
||||
line-height: $mui-base-line-height;
|
||||
color: $mui-dropdown-link-font-color;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
|
||||
// hover & focus state
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: none;
|
||||
color: $mui-dropdown-link-font-color-hover;
|
||||
background-color: $mui-dropdown-link-bg-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
> .mui--is-disabled > a {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $mui-dropdown-link-font-color-disabled;
|
||||
}
|
||||
|
||||
// nuke hover & focus effects
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
cursor: $mui-cursor-disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// right align
|
||||
.mui-dropdown__menu--right {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
// alternative positions
|
||||
.mui-dropdown--up > .mui-dropdown__menu {
|
||||
margin: 0 0 mui-rem(2px);
|
||||
}
|
||||
|
||||
.mui-dropdown--right > .mui-dropdown__menu {
|
||||
margin: 0 0 0 mui-rem(2px);
|
||||
}
|
||||
|
||||
.mui-dropdown--left > .mui-dropdown__menu {
|
||||
margin: 0 mui-rem(2px) 0 0;
|
||||
}
|
8
src/css/global/fixes.scss
Normal file → Executable file
@ -4,3 +4,11 @@
|
||||
.nrccAlert a {
|
||||
color:#00ffa2;
|
||||
}
|
||||
|
||||
|
||||
.betterInput {
|
||||
background-color: deeppink;
|
||||
padding-bottom: 6px !important;
|
||||
padding-top: 6px !important;
|
||||
|
||||
}
|
||||
|
55
src/css/global/forms.scss
Executable file
@ -0,0 +1,55 @@
|
||||
/* Forms */
|
||||
input {
|
||||
margin: .2rem 0;
|
||||
}
|
||||
|
||||
.form-text {
|
||||
display: block;
|
||||
margin-top: 0.3rem;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
input[type='text'],
|
||||
input[type='email'],
|
||||
input[type='password'],
|
||||
input[type='date'],
|
||||
select,
|
||||
textarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.1rem;
|
||||
/*font-size: 1.2rem;*/
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
input[type='submit'],
|
||||
button {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
label,
|
||||
legend {
|
||||
display: block;
|
||||
margin-bottom: .1rem;
|
||||
font-weight: 600; }
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
display: inline; }
|
||||
label > .label-body {
|
||||
display: inline-block;
|
||||
margin-left: .5rem;
|
||||
font-weight: normal;
|
||||
background-color: #dcc894;
|
||||
}
|
||||
|
||||
|
||||
table th,
|
||||
table td {
|
||||
padding: 1rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table th {
|
||||
background: var(--light-color);
|
||||
}
|
188
src/css/global/grid.scss
Executable file
@ -0,0 +1,188 @@
|
||||
/* Grid */
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
display: -ms-flexbox;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
/*margin-left: -.4rem;
|
||||
margin-right: -.4rem;*/
|
||||
|
||||
&--1 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
grid-gap: 1rem;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-gap: 1rem;
|
||||
}
|
||||
|
||||
&--3 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-gap: 1px;
|
||||
}
|
||||
|
||||
&--4 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-gap: 1rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.row {
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
|
||||
&:before, &:after {
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col-1-3rd, .col-2-3rd, .col-half {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
min-height: 1px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}*/
|
||||
|
||||
.column,
|
||||
.columns {
|
||||
margin-left: 4%;
|
||||
}
|
||||
|
||||
.column:first-child,
|
||||
.columns:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.col-1 {
|
||||
width: 8.33333%;
|
||||
}
|
||||
|
||||
.col-2 {
|
||||
width: 16.66667%;
|
||||
}
|
||||
|
||||
.col-3 {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.col-4 {
|
||||
width: 33.33333%;
|
||||
}
|
||||
|
||||
.col-5 {
|
||||
width: 41.66667%;
|
||||
}
|
||||
|
||||
.col-6 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.col-7 {
|
||||
width: 58.33333%;
|
||||
}
|
||||
|
||||
.col-8 {
|
||||
width: 66.66667%;
|
||||
}
|
||||
|
||||
.col-9 {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.col-10 {
|
||||
width: 83.33333%;
|
||||
}
|
||||
|
||||
.col-11 {
|
||||
width: 91.66667%;
|
||||
}
|
||||
|
||||
.col-12 {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.col-1-3rd {
|
||||
width: 32.666667%;
|
||||
}
|
||||
|
||||
.col-2-3rd {
|
||||
width: 65.3333333333%;
|
||||
}
|
||||
|
||||
.col-half {
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
/* Offsets */
|
||||
.offset-1-col {
|
||||
margin-left: 8.66666666667%;
|
||||
}
|
||||
|
||||
.offset-2-col {
|
||||
margin-left: 17.3333333333%;
|
||||
}
|
||||
|
||||
.offset-3-col {
|
||||
margin-left: 26%;
|
||||
}
|
||||
|
||||
.offset-4-col {
|
||||
margin-left: 34.6666666667%;
|
||||
}
|
||||
|
||||
.offset-5-col {
|
||||
margin-left: 43.3333333333%;
|
||||
}
|
||||
|
||||
.offset-6-col {
|
||||
margin-left: 52%;
|
||||
}
|
||||
|
||||
.offset-7-col {
|
||||
margin-left: 60.6666666667%;
|
||||
}
|
||||
|
||||
.offset-8-col {
|
||||
margin-left: 69.3333333333%;
|
||||
}
|
||||
|
||||
.offset-9-col {
|
||||
margin-left: 78.0%;
|
||||
}
|
||||
|
||||
.offset-10-col {
|
||||
margin-left: 86.6666666667%;
|
||||
}
|
||||
|
||||
.offset-11-col {
|
||||
margin-left: 95.3333333333%;
|
||||
}
|
||||
|
||||
.offset-1-3rd-col {
|
||||
margin-left: 34.6666666667%;
|
||||
}
|
||||
|
||||
.offset-2-3rd-col {
|
||||
margin-left: 69.3333333333%;
|
||||
}
|
||||
|
||||
.offset-half-col {
|
||||
margin-left: 52%;
|
||||
}
|
12
src/css/global/list.scss
Executable file
@ -0,0 +1,12 @@
|
||||
/* List */
|
||||
.list {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
.list li {
|
||||
padding-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.dataRow {
|
||||
cursor: pointer;
|
||||
}
|
103
src/css/global/margin.scss
Executable file
@ -0,0 +1,103 @@
|
||||
/* Margin */
|
||||
.m {
|
||||
margin: 0.5rem;
|
||||
|
||||
&--1 {
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
margin: 2rem;
|
||||
}
|
||||
|
||||
&--3 {
|
||||
margin: 3rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.mb {
|
||||
margin-bottom: .1rem !important;
|
||||
|
||||
&--1 {
|
||||
margin-bottom: .2rem !important;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
margin-bottom: .4rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.ml {
|
||||
margin-left: .1rem !important;
|
||||
|
||||
&--1 {
|
||||
margin-left: .2rem !important;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
margin-left: .4rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.mr {
|
||||
margin-right: .1rem !important;
|
||||
|
||||
&--1 {
|
||||
margin-right: .2rem !important;
|
||||
}
|
||||
|
||||
.mr-2 {
|
||||
margin-right: .4rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.mt {
|
||||
margin-top: .1rem !important;
|
||||
|
||||
&--1 {
|
||||
margin-top: .2rem !important;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
margin-top: .4rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.mx {
|
||||
margin-left: 0.5rem !important;
|
||||
margin-right: 0.5rem !important;
|
||||
|
||||
&--1 {
|
||||
margin-left: 1rem !important;
|
||||
margin-right: 1rem !important;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
margin-left: 2rem !important;
|
||||
margin-right: 2rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.my {
|
||||
margin: 0.5rem 0;
|
||||
|
||||
&--1 {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
&--3 {
|
||||
margin: 3rem 0;
|
||||
}
|
||||
|
||||
}
|
22
src/css/global/modal.scss
Executable file
@ -0,0 +1,22 @@
|
||||
.modalWindow {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: rgba(0,0,0,0.2);
|
||||
z-index: 99999;
|
||||
opacity:0;
|
||||
pointer-events: none;
|
||||
text-align:center;
|
||||
}
|
||||
.modalWindow:target {
|
||||
opacity:1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.modalWindow > div {
|
||||
width: 500px;
|
||||
position: relative;
|
||||
margin: 10% auto;
|
||||
background: #fff;
|
||||
}
|
38
src/css/global/mouse.scss
Executable file
@ -0,0 +1,38 @@
|
||||
// Mouse pointers
|
||||
|
||||
.alias {cursor: alias;}
|
||||
.all-scroll {cursor: all-scroll;}
|
||||
.auto {cursor: auto;}
|
||||
.cell {cursor: cell;}
|
||||
.context-menu {cursor: context-menu;}
|
||||
.col-resize {cursor: col-resize;}
|
||||
.copy {cursor: copy;}
|
||||
.crosshair {cursor: crosshair;}
|
||||
.default {cursor: default;}
|
||||
.e-resize {cursor: e-resize;}
|
||||
.ew-resize {cursor: ew-resize;}
|
||||
.grab {cursor: grab;}
|
||||
.grabbing {cursor: grabbing;}
|
||||
.help {cursor: help;}
|
||||
.move {cursor: move;}
|
||||
.n-resize {cursor: n-resize;}
|
||||
.ne-resize {cursor: ne-resize;}
|
||||
.nesw-resize {cursor: nesw-resize;}
|
||||
.ns-resize {cursor: ns-resize;}
|
||||
.nw-resize {cursor: nw-resize;}
|
||||
.nwse-resize {cursor: nwse-resize;}
|
||||
.no-drop {cursor: no-drop;}
|
||||
.none {cursor: none;}
|
||||
.not-allowed {cursor: not-allowed;}
|
||||
.pointer {cursor: pointer;}
|
||||
.progress {cursor: progress;}
|
||||
.row-resize {cursor: row-resize;}
|
||||
.s-resize {cursor: s-resize;}
|
||||
.se-resize {cursor: se-resize;}
|
||||
.sw-resize {cursor: sw-resize;}
|
||||
.text {cursor: text;}
|
||||
.url {cursor: url(myBall.cur),auto;}
|
||||
.w-resize {cursor: w-resize;}
|
||||
.wait {cursor: wait;}
|
||||
.zoom-in {cursor: zoom-in;}
|
||||
.zoom-out {cursor: zoom-out;}
|
60
src/css/global/navbar.scss
Executable file
@ -0,0 +1,60 @@
|
||||
/* Navbar */
|
||||
.navbar {
|
||||
position:fixed;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
/*padding: 0.7rem 0rem;*/
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
opacity: 0.9;
|
||||
margin-bottom: 1rem;
|
||||
min-height: $navbar-height;
|
||||
}
|
||||
|
||||
|
||||
.navbar ul {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.navbar a {
|
||||
color: #fff;
|
||||
padding: 0.45rem;
|
||||
margin: 0 0.25rem;
|
||||
}
|
||||
|
||||
.navbar a:hover {
|
||||
color: $light-color;
|
||||
}
|
||||
|
||||
.navbar .welcome span {
|
||||
margin-right: 0.6rem;
|
||||
}
|
||||
|
||||
.navbar .navbar-section {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
display: -ms-flexbox;
|
||||
-ms-flex: 1 0 0;
|
||||
flex: 1 0 0;
|
||||
-ms-flex-align: center;
|
||||
}
|
||||
|
||||
.navbar .navbar-section:not(:first-child):last-child {
|
||||
-ms-flex-pack: end;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.navbar .navbar-brand {
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
header + div.container {
|
||||
position: relative;
|
||||
top:$navbar-height;
|
||||
overflow: auto;
|
||||
height: calc(100vh - #{$navbar-height});
|
||||
max-height: calc(100vh - #{$navbar-height});
|
||||
}
|
||||
|
66
src/css/global/padding.scss
Executable file
@ -0,0 +1,66 @@
|
||||
/* Padding */
|
||||
.pad {
|
||||
padding: 0.5rem;
|
||||
|
||||
&--1 {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
&--3 {
|
||||
padding: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.pady {
|
||||
padding: 0.5rem 0;
|
||||
|
||||
&--top {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
&--bottom {
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
&--1 {
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
padding: 2rem 0;
|
||||
}
|
||||
|
||||
&--3 {
|
||||
padding: 3rem 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.padx {
|
||||
padding: 0 0.5rem;
|
||||
|
||||
&--right {
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
&--left {
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
&--1 {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
&--2 {
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
&--3 {
|
||||
padding: 0 3rem;
|
||||
}
|
||||
}
|
25
src/css/global/panel.scss
Executable file
@ -0,0 +1,25 @@
|
||||
/* Panel */
|
||||
|
||||
.panel {
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 0;
|
||||
background-color: #FFF;
|
||||
-webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0px 2px 0 rgba(0, 0, 0, 0.12);
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0px 2px 0 rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.panel:before, .panel:after {
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.panel:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.glassy {
|
||||
background-color: rgba(31, 28, 23, 0.6);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
28
src/css/global/table.scss
Executable file
@ -0,0 +1,28 @@
|
||||
.table-responsive {
|
||||
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
table {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
margin-bottom: 1rem;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
tbody tr:nth-of-type(odd){
|
||||
background-color: rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
border-top: 1px solid #e1e1e1;
|
||||
}
|
125
src/css/global/text.scss
Executable file
@ -0,0 +1,125 @@
|
||||
.x-large {
|
||||
font-size: 4rem;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.large {
|
||||
font-size: 3rem;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.lead {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.text-dark {
|
||||
color: $dark-color;
|
||||
}
|
||||
|
||||
.text-light {
|
||||
color: $dark-color;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: $success-color;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: $danger-color;
|
||||
}
|
||||
|
||||
.text-highlight {
|
||||
color: $highlight-color;
|
||||
}
|
||||
|
||||
.text-highlight2 {
|
||||
color: $highlight-color2;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.text-lowercase {
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
.text-uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.text-capitalize {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.text-display1, h1 {
|
||||
font-weight: 400;
|
||||
font-size: 34px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.text-title, h3 {
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.text-subhead, h4 {
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.text-body2, h5 {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.text-body1 {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.text-caption {
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.align-middle {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
||||
/* Center All */
|
||||
.all-center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-justify { text-align: justify !important; }
|
||||
.text-nowrap { white-space: nowrap !important; }
|
||||
|
||||
.align-baseline { vertical-align: baseline !important; }
|
||||
.align-top { vertical-align: top !important; }
|
||||
.align-bottom { vertical-align: bottom !important; }
|
0
src/css/horscroll.scss
Normal file → Executable file
0
src/css/nord.css
Normal file → Executable file
0
src/css/nord.scss
Normal file → Executable file
0
src/css/skeleton-min.css
vendored
Normal file → Executable file
0
src/css/skeleton.css
vendored
Normal file → Executable file
0
src/css/spinner.scss
Normal file → Executable file
35
src/css/traintimes.scss
Executable file
@ -0,0 +1,35 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Roboto+Condensed');
|
||||
@import './nord.scss';
|
||||
|
||||
$navbar-height: 56px;
|
||||
$navbar-height-small: 36px;
|
||||
$admin-footer-height: 70px;
|
||||
$admin-nav-width: 250px;
|
||||
|
||||
$primary-color: $nord10;
|
||||
$dark-color: $nord0;
|
||||
$light-color: $nord5;
|
||||
$danger-color: $nord11;
|
||||
$success-color: $nord14;
|
||||
|
||||
$highlight-color: $nord15;
|
||||
$highlight-color2: $nord13;
|
||||
|
||||
@import './global/base';
|
||||
|
||||
@import './global/padding';
|
||||
@import './global/grid';
|
||||
@import './global/text';
|
||||
@import './global/button';
|
||||
@import './global/table';
|
||||
@import './global/navbar';
|
||||
@import './global/margin';
|
||||
@import './global/cards';
|
||||
|
||||
@import './global/_small';
|
||||
@import './global/_xlarge';
|
||||
|
||||
@import './global/fixes';
|
||||
|
||||
|
||||
|
0
src/css/viewport.scss
Normal file → Executable file
12
src/libs/SocketManager.js
Executable file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Created by WebStorm.
|
||||
* User: martin
|
||||
* Date: 14/08/2020
|
||||
* Time: 14:09
|
||||
|
||||
*/
|
||||
|
||||
|
||||
const SocketManager = (function() {
|
||||
|
||||
})
|
0
src/libs/longpress.js
Normal file → Executable file
0
src/libs/reducer.js
Normal file → Executable file
0
src/libs/stations.js
Normal file → Executable file
208
src/libs/twitter.js
Executable file
@ -0,0 +1,208 @@
|
||||
export default
|
||||
[
|
||||
{ 'follow': false,
|
||||
'name': 'nationalrailenq',
|
||||
'id': 33546465
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'networkrail',
|
||||
'id': 365344176
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailSCOT',
|
||||
'id': 402687948
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'AvantiWestCoast',
|
||||
'id': 1143560758476906497
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'CalSleeper',
|
||||
'id': 2870293725
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'CrossCountryUK',
|
||||
'id': 153368708
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'Eurostar',
|
||||
'id': 98412169
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'EurostarUK',
|
||||
'id': 59742254
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'GatwickExpress',
|
||||
'id': 163816182
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'GlasgowSubway',
|
||||
'id': 224607925
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'GWRHelp',
|
||||
'id': 15589815
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'HeathrowExpress',
|
||||
'id': 20240678
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'LNER',
|
||||
'id': 313306238
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'LNRailway',
|
||||
'id': 910487328627535872
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'northernassist',
|
||||
'id': 194512268
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'ScotRail',
|
||||
'id': 61569136
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'Stansted_Exp',
|
||||
'id': 257511611
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'TfL',
|
||||
'id': 47319664
|
||||
},
|
||||
{ 'follow': false, 'name':'WestMidRailway', 'id':915554470175657984 },
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailBHM',
|
||||
'id': 583910976
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailEDB',
|
||||
'id': 586614081
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailEUS',
|
||||
'id': 581807264
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailGLC',
|
||||
'id': 421061171
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailKGX',
|
||||
'id': 459192871
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailLST',
|
||||
'id': 581826097
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailMAN',
|
||||
'id': 583895871
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'NetworkRailVIC',
|
||||
'id': 587354752
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTP',
|
||||
'id': 266094415
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPAvonSomerset',
|
||||
'id': 738664125132345344
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPBhm',
|
||||
'id': 952003488
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPBlackCountry',
|
||||
'id': 767698362866999297
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPCambs',
|
||||
'id': 2574726074
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPCardiff_NWP',
|
||||
'id': 951714852
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPEAnglia',
|
||||
'id': 4479942923
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPEssex',
|
||||
'id': 2949032015
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPGtrMcr',
|
||||
'id': 1670204977
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPLeics',
|
||||
'id': 761147194598711296
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPLiverpoolSt',
|
||||
'id': 951912242
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPLondon',
|
||||
'id': 957226980
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPLondonBridge',
|
||||
'id': 3346645594
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPMersey',
|
||||
'id': 951748434
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPNorthScot',
|
||||
'id': 2238888007
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPNorthWales',
|
||||
'id': 951487338
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPOxon',
|
||||
'id': 741228701791178753
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPPontypridd',
|
||||
'id': 1672678292
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPScotland',
|
||||
'id': 957256160
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPSouthYorks',
|
||||
'id': 3384315676
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPTeesValley',
|
||||
'id': 802182849872936962
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPUnderground',
|
||||
'id': 986236195049897985
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPWales',
|
||||
'id': 1430734374
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPWaterloo',
|
||||
'id': 951997044
|
||||
},
|
||||
{ 'follow': false,
|
||||
'name': 'BTPWestScot',
|
||||
'id': 951757261
|
||||
}
|
||||
];
|
0
src/libs/utils.js
Normal file → Executable file
115
src/libs/websocket.js
Executable file
@ -0,0 +1,115 @@
|
||||
const Websocket = function (model) {
|
||||
let wsUrl = ['localhost', 'traintimes.silvrtree.co.uk'];
|
||||
let wsPort = '8100';
|
||||
const useUrl = 0;
|
||||
|
||||
if ('https:' === document.location.protocol) {
|
||||
wsUrl = `wss://${ wsUrl[1] }`;
|
||||
wsPort = '';
|
||||
}
|
||||
else {
|
||||
// wsUrl = 'ws://localhost:3001';
|
||||
wsUrl = `ws://${ wsUrl[0] }`;
|
||||
wsPort = '8100';
|
||||
}
|
||||
|
||||
console.log('>> wsUrl', wsUrl);
|
||||
this.socket = null;
|
||||
this.timer = 0;
|
||||
this.clock = null;
|
||||
this.connected = false;
|
||||
this.connectBuffer = [];
|
||||
|
||||
this.startWebSocket = function () {
|
||||
'use strict';
|
||||
|
||||
const url = (wsPort === '') ? wsUrl : `${wsUrl }:${ wsPort}`;
|
||||
console.log('Starting socket', url);
|
||||
const wsCtor = window['MozWebSocket'] ? MozWebSocket : WebSocket;
|
||||
this.socket = new wsCtor(url, 'stream');
|
||||
|
||||
this.socket.onopen = this.handleWebsocketOnOpen.bind(this);
|
||||
this.socket.onmessage = this.handleWebsocketMessage.bind(this);
|
||||
this.socket.onclose = this.handleWebsocketClose.bind(this);
|
||||
this.socket.onerror = function (e) {
|
||||
console.error(e);
|
||||
};
|
||||
};
|
||||
|
||||
this.subscribe = function(channel) {
|
||||
console.log('Subscribe::', channel);
|
||||
const newSubscription = {
|
||||
'request': 'SUBSCRIBE',
|
||||
'message': '',
|
||||
'channel': channel
|
||||
};
|
||||
|
||||
if (this.connected)
|
||||
this.socket.send(JSON.stringify(newSubscription));
|
||||
else
|
||||
this.connectBuffer.push(JSON.stringify(newSubscription));
|
||||
};
|
||||
|
||||
this.send = function (msg) {
|
||||
console.log('Sending', msg);
|
||||
this.socket.send(msg);
|
||||
};
|
||||
|
||||
this.handleData = function (d) {
|
||||
model.trigger('message', d);
|
||||
};
|
||||
|
||||
this.handleBuffer = function() {
|
||||
console.log('*** handleBuffer');
|
||||
|
||||
while (this.connectBuffer.length > 0) {
|
||||
const item = this.connectBuffer.shift();
|
||||
this.socket.send(item);
|
||||
}
|
||||
};
|
||||
|
||||
this.handleWebsocketOnOpen = function () {
|
||||
'use strict';
|
||||
this.retry = 0;
|
||||
|
||||
console.log('**** Websocket Connected ****');
|
||||
this.clock = new Date();
|
||||
|
||||
this.connected = true;
|
||||
setTimeout(() => {
|
||||
this.handleBuffer();
|
||||
}, 1500);
|
||||
};
|
||||
|
||||
this.handleWebsocketMessage = function (message) {
|
||||
let command;
|
||||
|
||||
try {
|
||||
console.log('handleWebsocketMessage::raw', message);
|
||||
command = JSON.parse(message.data);
|
||||
console.log('handleWebsocketMessage::command', command);
|
||||
}
|
||||
catch (e) { /* Do nothing */
|
||||
}
|
||||
if (command)
|
||||
this.handleData.call(this, command);
|
||||
};
|
||||
|
||||
this.handleWebsocketClose = function () {
|
||||
console.error('WebSocket Connection Closed.');
|
||||
const now = new Date();
|
||||
|
||||
// const uptime = now.getTime() - this.clock.getTime();
|
||||
const uptime = 1;
|
||||
console.log('Socket alive for', uptime / 1000);
|
||||
const self = this;
|
||||
console.log('Waiting ', 15000);
|
||||
this.timer = setTimeout(function () {
|
||||
self.startWebSocket();
|
||||
}, 15000);
|
||||
};
|
||||
|
||||
this.startWebSocket();
|
||||
};
|
||||
|
||||
module.exports = Websocket;
|
0
src/main.js
Normal file → Executable file
0
src/pages/Favourites.svelte
Normal file → Executable file
0
src/pages/Home.svelte
Normal file → Executable file
0
src/pages/NotFound.svelte
Normal file → Executable file
0
src/pages/Service.svelte
Normal file → Executable file
0
src/pages/Settings.svelte
Normal file → Executable file
0
src/pages/Timetable.svelte
Normal file → Executable file
13
src/pages/Twitter.svelte
Normal file → Executable file
@ -1,7 +1,7 @@
|
||||
<script>
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { state } from '../store/store';
|
||||
import Twitter from "../components/Twitter.svelte";
|
||||
import Twitter from '../components/Twitter.svelte';
|
||||
|
||||
let _tweets = [];
|
||||
|
||||
@ -16,14 +16,15 @@
|
||||
}, 300000);*/
|
||||
});
|
||||
|
||||
onDestroy(async () => {
|
||||
clearInterval(serviceInterval);
|
||||
});
|
||||
|
||||
state.tweetList.subscribe(async (v) => {
|
||||
const unsubTweetList = state.tweetList.subscribe(async (v) => {
|
||||
// console.log('tweetlist', v);
|
||||
_tweets = v;
|
||||
});
|
||||
|
||||
onDestroy(async () => {
|
||||
unsubTweetList();
|
||||
clearInterval(serviceInterval);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
0
src/routes.js
Normal file → Executable file
98
src/store/store.js
Normal file → Executable file
@ -3,18 +3,24 @@
|
||||
* User: martin
|
||||
* Date: 28/04/2020
|
||||
* Time: 11:28
|
||||
|
||||
* __ENV__
|
||||
*
|
||||
*/
|
||||
import axios from 'redaxios';
|
||||
|
||||
import { writable, get } from 'svelte/store';
|
||||
import { writable, get, derived } from 'svelte/store';
|
||||
import localforage from 'localforage';
|
||||
const baseUrl = (ENV === 'production') ? (`${location.protocol }//${ location.hostname}`) : 'http://localhost:8100';
|
||||
const baseUrl = (__ENV__ === 'production') ? (`${location.protocol }//${ location.hostname}`) : 'http://localhost:8100';
|
||||
|
||||
import Websocket from '../libs/websocket';
|
||||
|
||||
import twitterAccountsJson from '../libs/twitter';
|
||||
|
||||
let started = false;
|
||||
const twitterAccounts = {
|
||||
|
||||
const twitterAccounts = {};
|
||||
|
||||
const OLDtwitterAccounts = {
|
||||
'nationalrailenq': {
|
||||
'id': 33546465,
|
||||
'follow': false
|
||||
@ -126,6 +132,7 @@ const twitterAccounts = {
|
||||
};
|
||||
|
||||
const state = {
|
||||
'newTweets' : writable([]),
|
||||
'twitterFollowing': writable({}),
|
||||
'twitterFollowingList' : writable([]),
|
||||
'tweetList' : writable([]),
|
||||
@ -173,20 +180,15 @@ const state = {
|
||||
}
|
||||
};
|
||||
// console.log(postReq);
|
||||
await axios(postReq)
|
||||
axios(postReq)
|
||||
.then((d) => {
|
||||
// console.log('>> retrieved', d);
|
||||
const data = JSON.parse(d.data);
|
||||
const list = data.map((item) => {
|
||||
return item.id;
|
||||
});
|
||||
// const data = JSON.parse(d.data);
|
||||
const data = d.data;
|
||||
|
||||
const tMap = data.map((item) => {
|
||||
return [item.id, item];
|
||||
});
|
||||
|
||||
this.tweetList.set(list);
|
||||
this.tweets.set(new Map(tMap));
|
||||
this.newTweets.set(data);
|
||||
}).catch((err) => {
|
||||
console.error('Store:getTweets', err);
|
||||
});
|
||||
},
|
||||
getTweetByID(id) {
|
||||
@ -202,11 +204,37 @@ const state = {
|
||||
getBaseUrl() {
|
||||
return baseUrl;
|
||||
},
|
||||
trigger(item) {
|
||||
updateTweetList(id) {
|
||||
this.tweetList.update(list => {
|
||||
return [id, ...list];
|
||||
});
|
||||
},
|
||||
updateTwitter(item) {
|
||||
this.tweets.update(orig => {
|
||||
return orig.set(item.id, item);
|
||||
});
|
||||
},
|
||||
updateNewTweets(item) {
|
||||
this.newTweets.update( orig => {
|
||||
let wa = [...orig];
|
||||
|
||||
wa.unshift(item);
|
||||
|
||||
wa = wa.slice(0, 49);
|
||||
|
||||
return wa;
|
||||
});
|
||||
},
|
||||
|
||||
trigger(msg, item) {
|
||||
console.log('trigger', item);
|
||||
|
||||
if (item.hasOwnProperty('message') ) {
|
||||
const msg = item.message;
|
||||
const payload = item.message;
|
||||
|
||||
// this.updateTwitter(payload);
|
||||
// this.updateTweetList(payload.id);
|
||||
this.updateNewTweets(payload);
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,8 +243,16 @@ const state = {
|
||||
const webSocket = new Websocket(state);
|
||||
|
||||
localforage.getItem('twitterFollowing').then((value) => {
|
||||
console.log('localForage::twitterFollowing', value);
|
||||
|
||||
if (value !== null) state.twitterFollowing.set(value);
|
||||
else {
|
||||
// load twitterAccounts
|
||||
|
||||
twitterAccountsJson.forEach((item) => {
|
||||
twitterAccounts[item.name] = { 'id': item.id, 'follow':false };
|
||||
});
|
||||
|
||||
state.twitterFollowing.set(twitterAccounts);
|
||||
localforage.setItem('twitterFollowing', twitterAccounts).catch((err) => {
|
||||
// This code runs if there were any errors
|
||||
@ -286,27 +322,29 @@ state.twitterFollowing.subscribe((v) => {
|
||||
|
||||
state.twitterFollowingList.subscribe((v) => {
|
||||
if (v.length === 0) return;
|
||||
console.log('twitterFollowingList', v.length, v);
|
||||
console.log('twitterFollowingList', v.length);
|
||||
v.forEach((item) => {
|
||||
console.log(item);
|
||||
const id = item[1].id;
|
||||
webSocket.subscribe(`t-${id}`);
|
||||
|
||||
/*
|
||||
for (let t = 0; t < v.length, t++;) {
|
||||
console.log(t);
|
||||
|
||||
}
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
||||
state.tweetList.subscribe((v) => {
|
||||
console.log('tweetList', v);
|
||||
state.newTweets.subscribe((data) => {
|
||||
if (data.length === 0) return;
|
||||
console.log('>> newTweets', data.length);
|
||||
|
||||
const sortedData = data.sort((a, b) => b.ts - a.ts);
|
||||
|
||||
const list = sortedData.map((item) => {
|
||||
return item.id;
|
||||
});
|
||||
|
||||
state.tweets.subscribe((v) => {
|
||||
console.log('tweets', v);
|
||||
const tMap = data.map((item) => {
|
||||
return [item.id, item];
|
||||
});
|
||||
|
||||
state.tweetList.set(list);
|
||||
state.tweets.set(new Map(tMap));
|
||||
});
|
||||
|
||||
// started = true;
|
||||
|