init
62
.eslintrc.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2019,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"es6": true,
|
||||||
|
"browser": true
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"svelte3"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"**/*.svelte"
|
||||||
|
],
|
||||||
|
"processor": "svelte3/svelte3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"arrow-spacing": "error",
|
||||||
|
"block-scoped-var": "error",
|
||||||
|
"block-spacing": "error",
|
||||||
|
"brace-style": ["error", "stroustrup", {}],
|
||||||
|
"camelcase": "error",
|
||||||
|
"comma-dangle": ["error", "never"],
|
||||||
|
"comma-spacing": ["error", { "before": false, "after": true }],
|
||||||
|
"comma-style": [1, "last"],
|
||||||
|
"consistent-this": [1, "_this"],
|
||||||
|
"curly": [1, "multi"],
|
||||||
|
"eol-last": 1,
|
||||||
|
"eqeqeq": 1,
|
||||||
|
"func-names": 1,
|
||||||
|
"indent": ["error", 2, { "SwitchCase": 1 }],
|
||||||
|
"lines-around-comment": ["error", { "beforeBlockComment": true, "allowArrayStart": true }],
|
||||||
|
"max-len": [1, 240, 2], // 2 spaces per tab, max 80 chars per line
|
||||||
|
"new-cap": 1,
|
||||||
|
"newline-before-return": "error",
|
||||||
|
"no-array-constructor": 1,
|
||||||
|
"no-inner-declarations": [1, "both"],
|
||||||
|
"no-mixed-spaces-and-tabs": 1,
|
||||||
|
"no-multi-spaces": 2,
|
||||||
|
"no-new-object": 1,
|
||||||
|
"no-shadow-restricted-names": 1,
|
||||||
|
"object-curly-spacing": ["error", "always"],
|
||||||
|
"padded-blocks": ["error", { "blocks": "never", "switches": "always" }],
|
||||||
|
"prefer-const": "error",
|
||||||
|
"prefer-template": "error",
|
||||||
|
"one-var": 0,
|
||||||
|
"quote-props": ["error", "always"],
|
||||||
|
"quotes": [1, "single"],
|
||||||
|
"radix": 1,
|
||||||
|
"semi": [1, "always"],
|
||||||
|
"space-before-blocks": [1, "always"],
|
||||||
|
"space-infix-ops": 1,
|
||||||
|
"vars-on-top": 1,
|
||||||
|
"no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 1 }],
|
||||||
|
"spaced-comment": ["error", "always", { "markers": ["/"] }]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/node_modules/
|
||||||
|
/public/build/
|
||||||
|
|
||||||
|
.DS_Store
|
5
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
6
.idea/jsLibraryMappings.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptLibraryMappings">
|
||||||
|
<includedPredefinedLibrary name="Node.js Core" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/misc.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="ES6" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/svelte-jubilee.iml" filepath="$PROJECT_DIR$/.idea/svelte-jubilee.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
12
.idea/svelte-jubilee.iml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
106
README.md
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
*Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Updates
|
||||||
|
|
||||||
|
## 2020-04-17
|
||||||
|
|
||||||
|
Added [svelte-preprocess](https://www.npmjs.com/package/svelte-preprocess) preprocessor with support for: PostCSS, SCSS, Less, Stylus, Coffeescript, TypeScript and Pug.
|
||||||
|
|
||||||
|
Added [rollup-plugin-node-builtins](https://www.npmjs.com/package/rollup-plugin-node-builtins) Allows the node builtins to be required/imported. Doing so gives the proper shims to support modules that were designed for Browserify, some modules require rollup-plugin-node-globals.
|
||||||
|
|
||||||
|
Added [rollup-plugin-node-globals](https://www.npmjs.com/package/rollup-plugin-node-globals) Plugin to insert node globals including so code that works with browserify should work even if it uses process or buffers.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# svelte app
|
||||||
|
|
||||||
|
This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template.
|
||||||
|
|
||||||
|
To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx degit sveltejs/template svelte-app
|
||||||
|
cd svelte-app
|
||||||
|
```
|
||||||
|
|
||||||
|
*Note that you will need to have [Node.js](https://nodejs.org) installed.*
|
||||||
|
|
||||||
|
|
||||||
|
## Get started
|
||||||
|
|
||||||
|
Install the dependencies...
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd svelte-app
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
...then start [Rollup](https://rollupjs.org):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.
|
||||||
|
|
||||||
|
By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`.
|
||||||
|
|
||||||
|
|
||||||
|
## Building and running in production mode
|
||||||
|
|
||||||
|
To create an optimised version of the app:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com).
|
||||||
|
|
||||||
|
|
||||||
|
## Single-page app mode
|
||||||
|
|
||||||
|
By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere.
|
||||||
|
|
||||||
|
If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json:
|
||||||
|
|
||||||
|
```js
|
||||||
|
"start": "sirv public --single"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Deploying to the web
|
||||||
|
|
||||||
|
### With [now](https://zeit.co/now)
|
||||||
|
|
||||||
|
Install `now` if you haven't already:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g now
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, from within your project folder:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd public
|
||||||
|
now deploy --name my-project
|
||||||
|
```
|
||||||
|
|
||||||
|
As an alternative, use the [Now desktop client](https://zeit.co/download) and simply drag the unzipped project folder to the taskbar icon.
|
||||||
|
|
||||||
|
### With [surge](https://surge.sh/)
|
||||||
|
|
||||||
|
Install `surge` if you haven't already:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g surge
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, from within your project folder:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
surge public my-project.surge.sh
|
||||||
|
```
|
4007
package-lock.json
generated
Normal file
37
package.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "svelte-app",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "rollup -c",
|
||||||
|
"dev": "rollup -c -w",
|
||||||
|
"start": "sirv public"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@rollup/plugin-commonjs": "^11.0.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^7.0.0",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-plugin-svelte3": "^2.7.3",
|
||||||
|
"rollup": "^1.20.0",
|
||||||
|
"rollup-plugin-livereload": "^1.0.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"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"autoprefixer": "^9.7.6",
|
||||||
|
"fecha": "^4.2.0",
|
||||||
|
"hh-mm-ss": "^1.2.0",
|
||||||
|
"log4js": "^6.2.1",
|
||||||
|
"ms": "^2.1.2",
|
||||||
|
"muicss": "^0.10.2",
|
||||||
|
"node-sass": "^4.14.1",
|
||||||
|
"qs": "^6.9.4",
|
||||||
|
"redaxios": "^0.2.0",
|
||||||
|
"rollup-plugin-replace": "^2.2.0",
|
||||||
|
"sirv-cli": "^0.4.4",
|
||||||
|
"svelte-spa-router": "^2.1.0"
|
||||||
|
}
|
||||||
|
}
|
9
public/browserconfig.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="/img/mstile-150x150.png"/>
|
||||||
|
<TileColor>#2b5797</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
BIN
public/favicon.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
public/gfx/bg_evening.jpg
Executable file
After Width: | Height: | Size: 3.1 KiB |
BIN
public/gfx/bg_morning.jpg
Executable file
After Width: | Height: | Size: 3.6 KiB |
BIN
public/gfx/clear_d.jpg
Executable file
After Width: | Height: | Size: 19 KiB |
BIN
public/gfx/clear_n.jpg
Executable file
After Width: | Height: | Size: 30 KiB |
BIN
public/gfx/cloudy_d.jpg
Executable file
After Width: | Height: | Size: 46 KiB |
BIN
public/gfx/cloudy_n.jpg
Executable file
After Width: | Height: | Size: 20 KiB |
BIN
public/gfx/default_daily_image.jpg
Executable file
After Width: | Height: | Size: 38 KiB |
BIN
public/gfx/foggy_d.jpg
Executable file
After Width: | Height: | Size: 44 KiB |
BIN
public/gfx/foggy_n.jpg
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
public/gfx/rain_d.jpg
Executable file
After Width: | Height: | Size: 113 KiB |
BIN
public/gfx/rain_n.jpg
Executable file
After Width: | Height: | Size: 99 KiB |
BIN
public/gfx/snow_d.jpg
Executable file
After Width: | Height: | Size: 99 KiB |
BIN
public/gfx/snow_n.jpg
Executable file
After Width: | Height: | Size: 30 KiB |
BIN
public/gfx/stars_00.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
public/gfx/stars_10.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
public/gfx/stars_15.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
public/gfx/stars_20.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
public/gfx/stars_25.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
public/gfx/stars_30.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
public/gfx/stars_35.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
public/gfx/stars_40.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
public/gfx/stars_45.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
public/gfx/stars_50.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/gfx/storm_d.jpg
Executable file
After Width: | Height: | Size: 34 KiB |
BIN
public/gfx/storm_n.jpg
Executable file
After Width: | Height: | Size: 22 KiB |
BIN
public/gfx/yelp_logo.jpg
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
public/gfx/yssdk_yelp_logo.png
Executable file
After Width: | Height: | Size: 4.4 KiB |
66
public/global.css
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
html, body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: #333;
|
||||||
|
margin: 0;
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: rgb(0,100,200);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: rgb(0,80,160);
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, button, select, textarea {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
padding: 0.4em;
|
||||||
|
margin: 0 0 0.5em 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:disabled {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"] {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
color: #333;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:not(:disabled):active {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:focus {
|
||||||
|
border-color: #666;
|
||||||
|
}
|
BIN
public/img/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
public/img/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 447 KiB |
BIN
public/img/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 64 KiB |
9
public/img/browserconfig.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="/mstile-150x150.png"/>
|
||||||
|
<TileColor>#da532c</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
BIN
public/img/favicon-16x16.png
Normal file
After Width: | Height: | Size: 739 B |
BIN
public/img/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
public/img/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
public/img/mstile-150x150.png
Normal file
After Width: | Height: | Size: 34 KiB |
372
public/img/safari-pinned-tab.svg
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<metadata>
|
||||||
|
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||||
|
</metadata>
|
||||||
|
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||||
|
fill="#000000" stroke="none">
|
||||||
|
<path d="M3195 4394 c-165 -80 -361 -175 -435 -211 -74 -36 -198 -96 -275
|
||||||
|
-133 -77 -37 -243 -118 -370 -180 -126 -62 -250 -121 -274 -131 -71 -31 -141
|
||||||
|
-81 -147 -105 -3 -12 0 -41 6 -64 20 -76 6 -127 -54 -190 -29 -30 -70 -80 -93
|
||||||
|
-110 -50 -68 -143 -241 -143 -266 0 -11 13 -58 29 -106 59 -172 78 -340 46
|
||||||
|
-402 -8 -15 -15 -36 -15 -47 0 -10 -19 -46 -43 -81 -24 -35 -53 -85 -66 -113
|
||||||
|
-37 -78 -120 -341 -132 -414 -20 -129 -42 -206 -65 -234 -13 -16 -24 -41 -24
|
||||||
|
-57 0 -39 -59 -111 -159 -194 -59 -48 -83 -75 -88 -96 -4 -24 -23 -41 -93 -85
|
||||||
|
-75 -47 -89 -60 -94 -88 -13 -67 60 -201 139 -258 25 -18 45 -36 45 -41 0 -16
|
||||||
|
-142 -293 -219 -426 -96 -169 -108 -190 -160 -284 l-42 -78 25 0 c28 0 26 -3
|
||||||
|
111 150 33 58 81 143 108 190 64 111 317 624 317 643 0 7 8 22 19 31 17 16 23
|
||||||
|
16 87 1 114 -26 160 -43 255 -98 102 -58 172 -126 189 -184 14 -46 15 -43
|
||||||
|
-116 -349 -93 -218 -155 -377 -149 -383 9 -9 22 13 51 88 33 85 44 83 14 -4
|
||||||
|
-24 -69 -25 -85 -6 -85 16 0 22 14 70 165 20 61 48 146 64 190 15 44 34 103
|
||||||
|
42 130 7 28 27 80 43 117 26 59 32 67 52 62 12 -3 26 1 33 8 11 14 15 27 52
|
||||||
|
187 11 47 27 92 36 102 8 9 30 67 49 128 21 70 42 121 58 138 14 16 36 40 49
|
||||||
|
55 13 14 48 36 77 47 l53 20 -6 -22 c-49 -173 -43 -336 17 -404 36 -41 95 -73
|
||||||
|
136 -73 78 0 204 72 328 187 74 69 113 119 113 147 0 11 17 54 39 95 21 42 46
|
||||||
|
97 56 124 20 52 25 55 47 30 14 -16 15 -38 6 -168 -11 -177 -44 -316 -83 -353
|
||||||
|
-33 -30 -34 -55 -2 -43 12 5 54 15 92 22 39 6 85 18 104 26 21 9 48 12 70 8
|
||||||
|
32 -5 45 0 100 36 35 23 81 60 102 81 l39 40 0 -29 c0 -15 -7 -59 -15 -97 -8
|
||||||
|
-38 -12 -73 -9 -78 3 -4 -10 -30 -29 -56 -37 -49 -49 -55 -229 -103 -38 -10
|
||||||
|
-61 -35 -210 -223 -42 -53 -73 -83 -97 -93 -55 -21 -66 -29 -70 -49 -6 -34
|
||||||
|
-34 -56 -128 -100 -57 -27 -94 -50 -97 -62 -6 -18 -40 -40 -229 -148 l-69 -39
|
||||||
|
40 -3 c30 -2 52 4 88 26 27 16 79 46 116 66 37 20 76 48 88 63 11 15 62 48
|
||||||
|
113 74 73 37 94 53 102 76 5 15 10 29 11 31 5 8 44 -24 40 -33 -2 -5 27 -20
|
||||||
|
65 -31 71 -22 99 -16 32 7 -32 10 -35 13 -18 19 18 7 18 9 -8 19 -15 6 -39 14
|
||||||
|
-52 17 -31 8 -32 20 -2 28 25 7 70 44 80 66 4 8 42 60 85 115 54 69 91 107
|
||||||
|
120 122 43 23 161 58 168 50 2 -2 -9 -21 -24 -43 -59 -82 -184 -267 -273 -405
|
||||||
|
-150 -234 -170 -269 -155 -269 8 0 40 44 72 97 32 54 88 144 126 201 37 57 68
|
||||||
|
106 68 108 0 7 165 243 191 274 l21 25 -16 -27 c-19 -32 -20 -52 -5 -76 9 -14
|
||||||
|
7 -25 -9 -52 -11 -19 -36 -64 -57 -100 -20 -36 -42 -72 -49 -80 -14 -17 -56
|
||||||
|
-89 -56 -96 0 -3 5 -2 12 2 7 4 8 3 4 -5 -4 -6 -11 -9 -16 -6 -7 4 -33 -33
|
||||||
|
-115 -165 -45 -73 -55 -89 -55 -95 0 -14 61 -1 172 35 68 23 188 54 268 70
|
||||||
|
158 33 206 44 233 55 21 9 22 -4 3 -71 -26 -93 -26 -94 -2 -94 20 0 24 11 50
|
||||||
|
128 15 70 32 131 37 137 5 5 9 17 9 26 0 42 146 477 180 537 5 9 24 53 41 97
|
||||||
|
17 44 39 96 50 115 10 19 32 73 49 119 16 46 40 98 53 115 24 32 147 250 147
|
||||||
|
260 0 11 190 297 228 345 119 148 280 336 343 401 105 108 372 356 398 369 19
|
||||||
|
11 21 9 21 -17 0 -58 -21 -90 -123 -182 -130 -120 -312 -302 -359 -360 -240
|
||||||
|
-298 -381 -497 -523 -735 -26 -44 -53 -87 -61 -95 -18 -21 -130 -249 -229
|
||||||
|
-466 -59 -130 -186 -465 -205 -541 -16 -67 7 -30 37 59 79 233 162 435 279
|
||||||
|
678 82 169 123 243 223 401 20 31 63 100 96 152 33 53 63 96 68 96 4 1 7 -12
|
||||||
|
7 -28 0 -17 4 -33 10 -36 6 -4 8 10 4 39 -6 40 -3 51 26 96 46 71 126 170 133
|
||||||
|
164 3 -4 12 9 20 27 20 46 62 100 71 91 4 -4 6 0 4 8 -1 8 3 14 10 12 6 -1 11
|
||||||
|
4 10 10 -2 7 2 12 9 11 7 -2 21 11 33 27 29 40 40 38 33 -7 -4 -24 -3 -34 4
|
||||||
|
-30 15 9 22 66 9 71 -7 3 -6 5 2 5 6 1 12 7 12 15 0 7 37 46 82 87 71 64 80
|
||||||
|
70 75 46 -4 -15 -10 -39 -13 -54 -11 -53 22 2 35 59 10 40 21 60 48 83 l36 30
|
||||||
|
-5 -25 c-3 -14 -16 -75 -28 -137 l-23 -111 -45 -17 c-52 -21 -177 -102 -224
|
||||||
|
-148 -18 -17 -60 -58 -93 -89 -95 -90 -204 -256 -232 -353 -7 -22 -15 -71 -19
|
||||||
|
-110 -6 -58 -13 -77 -39 -110 -52 -65 -229 -368 -310 -530 -108 -217 -219
|
||||||
|
-491 -261 -643 -8 -30 -19 -62 -24 -73 -8 -15 -7 -19 4 -19 10 0 21 20 32 57
|
||||||
|
9 32 20 65 24 73 4 8 15 38 23 65 39 131 129 349 220 532 71 144 74 126 5 -27
|
||||||
|
-51 -112 -228 -649 -228 -691 0 -6 10 -9 22 -7 15 2 26 16 38 48 31 87 162
|
||||||
|
359 236 491 l53 95 128 -17 c139 -20 508 -43 523 -34 6 4 10 -3 10 -14 0 -23
|
||||||
|
-19 -28 -38 -9 -9 9 -12 9 -12 0 0 -8 -25 -11 -82 -11 -46 0 -94 -5 -108 -11
|
||||||
|
l-25 -10 25 4 c14 3 76 6 137 7 85 1 118 -2 135 -13 37 -25 138 -130 138 -145
|
||||||
|
0 -34 -93 -63 -272 -83 -51 -6 -151 -20 -223 -30 -101 -16 -393 -50 -422 -50
|
||||||
|
-3 0 -2 8 1 18 4 9 -9 -1 -28 -23 -20 -22 -35 -45 -36 -51 0 -19 -70 -75 -88
|
||||||
|
-72 -20 4 -54 -54 -46 -77 9 -23 49 -18 62 8 22 42 52 91 83 137 l32 46 81 3
|
||||||
|
c44 1 110 6 146 11 107 16 158 12 214 -14 28 -13 98 -41 156 -61 100 -35 114
|
||||||
|
-37 299 -47 150 -7 205 -14 243 -29 27 -10 51 -19 53 -19 3 0 5 123 5 273 l0
|
||||||
|
274 -40 12 c-22 6 -40 16 -40 20 0 5 -12 12 -27 15 -38 9 -214 79 -210 83 2 2
|
||||||
|
30 -6 63 -17 93 -31 87 -24 -27 33 -185 93 -360 230 -435 340 -14 21 -42 73
|
||||||
|
-62 114 -34 74 -36 81 -36 187 0 109 1 113 39 188 39 79 160 239 194 258 11 5
|
||||||
|
29 26 41 46 31 49 141 138 217 176 46 22 86 33 150 40 169 18 177 19 162 29
|
||||||
|
-10 6 -10 9 -1 9 6 0 12 7 12 15 0 18 -13 19 -60 5 -19 -6 -60 -14 -90 -19
|
||||||
|
-30 -5 -64 -13 -74 -17 -15 -6 -18 -4 -13 8 3 9 18 74 32 144 29 137 53 194
|
||||||
|
91 214 17 10 25 25 30 59 4 25 13 63 20 85 8 21 14 50 14 63 0 22 -3 24 -25
|
||||||
|
19 -33 -8 -33 10 0 36 25 19 65 86 65 108 0 6 -12 3 -27 -8 -46 -32 -129 -47
|
||||||
|
-258 -46 -103 0 -195 14 -195 29 0 3 41 44 91 92 50 48 105 108 122 133 39 56
|
||||||
|
55 74 98 107 31 23 28 25 -15 7 -9 -3 -15 5 -19 25 -10 47 14 109 75 199 17
|
||||||
|
24 27 46 24 49 -3 3 -25 -3 -48 -14 -62 -29 -173 -49 -183 -33 -3 6 23 41 59
|
||||||
|
79 61 65 73 81 62 81 -2 0 -27 -20 -55 -43 -39 -34 -74 -51 -149 -75 -106 -35
|
||||||
|
-213 -49 -252 -34 -24 9 -23 10 23 30 26 11 47 25 47 30 0 6 22 26 48 45 85
|
||||||
|
61 222 269 209 318 -3 11 1 36 9 56 25 58 11 46 -24 -21 -37 -71 -107 -148
|
||||||
|
-207 -228 -79 -63 -129 -90 -196 -106 -50 -12 -123 -1 -84 13 157 56 308 185
|
||||||
|
371 318 30 63 79 225 71 234 -2 1 -18 -19 -37 -44 -42 -57 -138 -107 -231
|
||||||
|
-122 -35 -6 -64 -9 -66 -7 -2 2 19 34 47 71 49 63 61 96 23 63 -10 -9 -29 -18
|
||||||
|
-43 -21 -14 -3 -56 -15 -95 -26 -103 -31 -317 -30 -394 2 -54 22 -55 22 -225
|
||||||
|
276 -94 140 -175 256 -181 258 -5 1 -145 -63 -310 -143z m389 -148 c20 -55 41
|
||||||
|
-105 45 -110 11 -13 61 -144 61 -159 0 -6 -6 -3 -12 6 -18 24 -219 62 -256 48
|
||||||
|
-16 -5 -20 -10 -10 -10 12 -1 15 -7 11 -23 -8 -32 -24 -50 -38 -44 -7 2 -21
|
||||||
|
-11 -31 -30 -10 -19 -25 -34 -34 -35 -35 -2 79 -25 118 -24 23 1 42 -2 42 -7
|
||||||
|
0 -4 6 -8 14 -8 8 0 18 -4 21 -10 4 -6 -2 -7 -17 -1 -13 5 -41 6 -63 2 l-40
|
||||||
|
-7 57 -8 c32 -4 60 -11 63 -16 3 -4 21 -11 40 -14 19 -4 35 -11 35 -15 0 -4
|
||||||
|
-39 -27 -87 -50 -49 -22 -95 -46 -103 -51 -8 -5 -37 -20 -65 -32 -27 -12 -74
|
||||||
|
-34 -104 -49 l-53 -27 -102 24 c-55 13 -137 35 -181 48 -117 36 -163 41 -70 8
|
||||||
|
72 -26 80 -31 78 -53 -1 -20 9 -30 60 -57 52 -27 64 -30 73 -18 5 8 16 11 22
|
||||||
|
7 9 -5 4 -11 -13 -19 -21 -10 -30 -9 -48 2 -49 32 -198 86 -236 86 -52 0 -62
|
||||||
|
-16 -91 -140 -26 -115 -36 -140 -52 -139 -10 0 -10 2 0 6 6 2 12 13 12 24 0
|
||||||
|
10 -6 19 -12 20 -10 0 -10 2 0 6 6 2 12 14 12 24 0 11 4 18 9 15 15 -9 20 46
|
||||||
|
6 61 -18 18 -28 16 -21 -3 5 -13 1 -15 -20 -11 -17 3 -29 -1 -36 -13 -7 -10
|
||||||
|
-18 -16 -25 -13 -7 3 -13 0 -13 -6 0 -6 -19 -11 -45 -11 -25 0 -45 -4 -45 -10
|
||||||
|
0 -5 -4 -10 -10 -10 -5 0 -10 8 -10 17 0 16 -1 16 -12 0 -9 -11 -32 -17 -78
|
||||||
|
-18 -69 -3 -110 11 -110 38 0 12 -3 13 -14 4 -11 -9 -15 -9 -19 1 -4 9 -6 8
|
||||||
|
-6 -3 -1 -26 -45 -19 -49 9 -3 17 -10 22 -31 22 -15 0 -32 5 -38 11 -6 6 -23
|
||||||
|
12 -38 14 -28 3 -45 21 -55 60 -5 17 -13 20 -57 17 -33 -3 -62 2 -83 13 -38
|
||||||
|
19 -35 30 4 15 25 -9 27 -8 21 11 -5 15 -3 20 6 17 8 -3 15 -14 17 -26 3 -22
|
||||||
|
13 -28 25 -16 3 3 1 14 -5 24 -12 19 -4 55 11 46 5 -4 11 -3 13 2 1 4 31 22
|
||||||
|
66 40 93 50 148 82 139 82 -4 0 -49 -21 -100 -48 -51 -26 -125 -62 -165 -81
|
||||||
|
-40 -19 -74 -37 -76 -40 -4 -6 55 -271 73 -331 6 -19 23 -91 37 -160 14 -69
|
||||||
|
32 -142 39 -162 9 -28 10 -41 1 -53 -9 -13 -19 10 -53 117 -22 73 -55 189 -72
|
||||||
|
258 -17 69 -42 166 -55 215 -36 130 -32 162 23 180 13 4 63 27 110 50 93 46
|
||||||
|
369 181 601 293 80 38 219 106 310 150 227 110 414 199 485 232 33 16 93 44
|
||||||
|
134 63 l74 35 28 -77 c15 -42 43 -121 63 -175z m-174 -356 c0 -5 -4 -10 -10
|
||||||
|
-10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m330 -36 c0 -8 -4
|
||||||
|
-14 -9 -14 -6 0 -9 9 -8 19 1 22 17 18 17 -5z m-200 -4 c0 -5 -2 -10 -4 -10
|
||||||
|
-3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m155 -23 c-11 -6 -22 -12
|
||||||
|
-25 -12 -3 0 -11 -4 -18 -9 -7 -4 -15 -6 -18 -3 -5 5 56 37 71 36 6 0 1 -5
|
||||||
|
-10 -12z m-555 -272 c-14 -8 -29 -14 -35 -14 -5 0 1 6 15 14 14 8 30 14 35 14
|
||||||
|
6 0 -1 -6 -15 -14z m224 -36 l46 -31 -57 -28 c-32 -15 -73 -39 -91 -54 -29
|
||||||
|
-25 -35 -27 -64 -17 -55 19 -108 45 -108 51 0 4 17 12 38 19 20 6 69 29 107
|
||||||
|
50 39 21 73 39 76 40 3 0 27 -13 53 -30z m-484 -4 c14 -7 41 -16 60 -20 19 -4
|
||||||
|
44 -14 55 -21 11 -8 26 -14 35 -14 8 0 20 -10 25 -22 7 -16 33 -31 83 -49 40
|
||||||
|
-15 79 -33 87 -39 9 -7 25 -14 38 -16 12 -1 50 -9 84 -17 34 -8 64 -13 67 -10
|
||||||
|
7 7 69 -18 78 -31 5 -7 8 -5 8 4 0 13 2 13 10 0 7 -11 0 -17 -32 -28 -36 -12
|
||||||
|
-41 -12 -52 4 -12 16 -14 15 -19 -8 -4 -14 -25 -37 -47 -52 -45 -29 -100 -108
|
||||||
|
-100 -140 1 -17 5 -14 21 14 l20 35 -5 -35 c-3 -19 -8 -54 -12 -76 -3 -23 -2
|
||||||
|
-50 3 -59 8 -14 13 -9 24 30 29 100 133 177 239 178 68 1 111 -20 145 -72 37
|
||||||
|
-56 42 -102 16 -147 -12 -20 -20 -38 -18 -40 2 -2 15 2 30 9 19 8 25 17 21 30
|
||||||
|
-4 13 0 20 15 24 24 6 25 8 11 33 -8 15 -6 21 7 29 17 10 17 10 1 11 -25 0
|
||||||
|
-42 68 -23 90 19 21 19 30 1 30 -24 0 -29 20 -10 41 22 25 14 32 -20 19 -43
|
||||||
|
-16 -53 -11 -26 11 24 20 24 20 3 14 -14 -4 -23 -2 -23 4 0 6 -12 11 -26 11
|
||||||
|
-16 0 -24 5 -22 13 5 14 48 23 48 10 0 -5 28 -7 63 -5 52 3 66 0 85 -16 13
|
||||||
|
-12 53 -31 88 -44 35 -12 64 -29 64 -36 0 -7 9 -25 19 -40 41 -57 91 -295 91
|
||||||
|
-430 0 -53 4 -81 10 -77 6 3 10 16 10 29 0 12 14 48 31 79 16 31 36 85 43 119
|
||||||
|
l13 63 12 -45 c6 -25 21 -76 32 -115 11 -38 29 -99 40 -135 24 -83 24 -121 -1
|
||||||
|
-153 -36 -46 -53 -100 -66 -217 -18 -155 -17 -288 1 -320 8 -14 14 -30 15 -35
|
||||||
|
0 -6 -42 -74 -92 -151 -51 -77 -120 -190 -153 -252 -33 -61 -82 -146 -110
|
||||||
|
-188 -42 -65 -59 -82 -107 -107 -90 -47 -159 -47 -343 -3 -82 20 -188 48 -235
|
||||||
|
62 -112 34 -281 119 -339 171 -71 63 -162 199 -247 367 -42 83 -82 158 -89
|
||||||
|
166 -7 8 -72 134 -145 280 -72 146 -136 269 -141 275 -22 23 6 277 34 300 7 6
|
||||||
|
23 34 37 64 44 95 135 138 274 129 69 -4 81 5 35 30 -16 9 -55 12 -122 10
|
||||||
|
l-98 -4 3 46 3 45 160 81 160 82 26 110 c14 61 31 118 38 126 14 17 57 13 101
|
||||||
|
-9z m605 -74 c3 -5 55 -40 116 -77 62 -38 106 -70 100 -72 -7 -2 -33 -1 -57 3
|
||||||
|
-34 5 -44 10 -40 21 7 19 -4 18 -20 -3 -13 -17 -15 -17 -27 -1 -10 12 -17 14
|
||||||
|
-24 7 -11 -11 -76 0 -196 32 l-37 10 27 22 c70 57 142 83 158 58z m-1705 -268
|
||||||
|
c0 -34 -5 -74 -11 -90 -7 -15 -15 -62 -19 -103 -11 -99 -76 -459 -85 -468 -2
|
||||||
|
-2 -13 -1 -25 3 -19 6 -21 12 -15 48 7 43 31 165 59 292 23 106 37 225 46 380
|
||||||
|
5 77 9 142 10 145 6 18 39 -157 40 -207z m383 190 c-7 -2 -21 -2 -30 0 -10 3
|
||||||
|
-4 5 12 5 17 0 24 -2 18 -5z m-479 -50 c-9 -82 -26 -207 -30 -223 -3 -12 -17
|
||||||
|
-14 -66 -12 -52 3 -61 1 -50 -10 7 -7 34 -13 62 -13 56 0 56 4 17 -115 -11
|
||||||
|
-36 -33 -114 -48 -175 -16 -64 -27 -98 -28 -80 -2 39 -24 128 -46 185 -9 25
|
||||||
|
-22 66 -28 91 -10 45 -9 49 41 142 28 52 66 115 84 139 49 63 93 118 95 118 2
|
||||||
|
0 0 -21 -3 -47z m895 -17 c-10 -9 -69 -36 -69 -32 0 7 52 35 64 36 5 0 7 -2 5
|
||||||
|
-4z m977 -43 c-10 -10 -19 5 -10 18 6 11 8 11 12 0 2 -7 1 -15 -2 -18z m-1137
|
||||||
|
-47 c-2 -2 -15 -9 -29 -15 -24 -11 -24 -11 -6 3 16 13 49 24 35 12z m-59 -30
|
||||||
|
c0 -2 -7 -7 -16 -10 -8 -3 -12 -2 -9 4 6 10 25 14 25 6z m-154 -91 c-11 -8
|
||||||
|
-25 -15 -30 -15 -6 1 0 7 14 15 32 19 40 18 16 0z m170 -51 c-4 -15 -14 -24
|
||||||
|
-26 -24 -25 0 -25 1 2 47 18 29 24 34 26 20 2 -10 1 -29 -2 -43z m-549 -6 c-3
|
||||||
|
-8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m293 7 c0 -2 -13 -11 -30
|
||||||
|
-20 -38 -19 -40 -11 -2 9 31 17 32 18 32 11z m2232 -16 c16 -9 19 -19 17 -62
|
||||||
|
-2 -35 4 -70 18 -109 29 -76 39 -192 23 -268 -16 -77 -30 -96 -56 -82 -26 14
|
||||||
|
-51 130 -35 160 17 32 13 84 -9 117 -28 42 -25 65 14 132 19 32 32 60 30 62
|
||||||
|
-9 10 -64 -66 -83 -114 -20 -52 -22 -51 -40 20 -17 64 -13 106 11 132 24 25
|
||||||
|
75 31 110 12z m-2505 -131 c-2 -18 -4 -6 -4 27 0 33 2 48 4 33 2 -15 2 -42 0
|
||||||
|
-60z m464 55 c-5 -10 -17 -27 -26 -38 -16 -19 -17 -19 -3 5 26 46 29 50 34 50
|
||||||
|
3 0 0 -8 -5 -17z m-645 -60 c-18 -108 -70 -342 -82 -368 -14 -32 -4 -45 20
|
||||||
|
-26 7 6 21 9 29 5 15 -5 15 -9 1 -35 -16 -33 -18 -33 -44 -19 -18 10 -19 8
|
||||||
|
-14 -20 5 -23 0 -40 -20 -70 -14 -22 -26 -49 -26 -60 0 -26 -38 -168 -52 -198
|
||||||
|
-6 -12 -12 -37 -12 -56 -1 -19 -4 -32 -8 -29 -5 2 -8 -3 -8 -13 0 -9 -19 -71
|
||||||
|
-41 -137 -36 -103 -40 -123 -29 -140 19 -32 -26 -67 -86 -67 -24 0 -44 -4 -44
|
||||||
|
-8 0 -4 17 -6 37 -4 34 4 36 3 24 -12 -18 -21 1 -21 34 0 14 9 32 14 40 10 15
|
||||||
|
-6 13 -14 -21 -64 -2 -2 -26 1 -54 7 -55 12 -96 1 -86 -24 2 -7 -6 -22 -18
|
||||||
|
-34 l-23 -21 5 32 c3 18 15 45 27 60 16 19 28 59 44 150 21 115 103 400 139
|
||||||
|
478 8 19 35 63 59 98 24 34 53 84 63 110 25 62 86 263 100 327 27 125 62 221
|
||||||
|
46 128z m589 -11 c-6 -4 -28 -23 -50 -42 l-40 -35 40 43 c21 23 44 42 49 42 6
|
||||||
|
0 6 -3 1 -8z m-325 -70 c0 -5 -7 -17 -15 -28 -14 -18 -14 -18 -15 9 0 17 5 27
|
||||||
|
15 27 8 0 15 -4 15 -8z m200 -36 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4
|
||||||
|
13 16 21 21 21 13z m-303 -38 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0
|
||||||
|
-25z m2483 -17 c0 -9 -4 -22 -9 -29 -10 -16 -21 16 -21 58 1 24 1 24 15 6 8
|
||||||
|
-11 15 -27 15 -35z m-2270 -45 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13
|
||||||
|
16 21 21 21 13z m2885 -49 c-22 -18 -68 -56 -103 -85 -35 -30 -85 -63 -110
|
||||||
|
-74 -26 -12 -71 -36 -100 -54 -29 -19 -55 -34 -58 -34 -3 0 -19 -9 -36 -21
|
||||||
|
-33 -24 -33 -24 -42 13 -5 22 -1 30 24 48 74 53 429 240 454 240 6 -1 -7 -15
|
||||||
|
-29 -33z m-3111 -141 c-3 -21 -8 -35 -11 -32 -2 2 -1 20 3 40 3 21 8 35 11 32
|
||||||
|
2 -2 1 -20 -3 -40z m-73 -47 c-5 -13 -10 -19 -10 -12 -1 15 10 45 15 40 3 -2
|
||||||
|
0 -15 -5 -28z m56 -21 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z
|
||||||
|
m8 -124 c-7 -12 -16 -43 -18 -70 -2 -27 -2 -22 -1 11 2 33 6 85 10 115 l7 55
|
||||||
|
8 -45 c7 -32 5 -50 -6 -66z m2803 44 c-18 -22 -45 -54 -59 -69 -15 -15 -29
|
||||||
|
-35 -32 -44 -13 -33 -28 -14 -25 32 3 52 24 70 31 26 l4 -28 8 32 c5 24 20 41
|
||||||
|
54 62 25 16 47 30 49 30 2 1 -12 -18 -30 -41z m-2674 5 c-7 -30 -24 -55 -24
|
||||||
|
-35 0 12 21 62 27 62 2 0 0 -12 -3 -27z m2359 -45 c7 -24 -8 -48 -29 -48 -15
|
||||||
|
0 -18 27 -8 54 9 23 31 20 37 -6z m-2556 -10 c-3 -8 -6 -5 -6 6 -1 11 2 17 5
|
||||||
|
13 3 -3 4 -12 1 -19z m-180 -25 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2
|
||||||
|
-21 0 -30z m3223 34 c0 -1 -30 -32 -67 -67 l-68 -65 65 68 c60 62 70 72 70 64z
|
||||||
|
m-2866 -22 c-4 -8 -8 -15 -10 -15 -2 0 -4 7 -4 15 0 8 4 15 10 15 5 0 7 -7 4
|
||||||
|
-15z m-74 -23 c0 -15 -2 -15 -10 -2 -13 20 -13 33 0 25 6 -3 10 -14 10 -23z
|
||||||
|
m-293 -54 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m794 -53 c41
|
||||||
|
-14 48 -22 78 -82 l32 -66 -46 41 c-25 22 -53 42 -63 44 -26 7 -62 -9 -62 -27
|
||||||
|
0 -12 3 -13 19 -4 10 7 26 9 36 5 14 -5 15 -9 5 -21 -8 -9 -8 -15 -2 -15 6 0
|
||||||
|
12 5 14 12 3 8 15 5 40 -10 40 -25 48 -39 48 -86 0 -21 8 -40 21 -52 22 -19
|
||||||
|
22 -19 12 1 -13 27 -24 97 -14 90 12 -7 82 -127 86 -145 3 -16 78 -172 98
|
||||||
|
-205 7 -11 25 -39 40 -62 29 -44 21 -61 -9 -20 -16 21 -16 21 -12 1 3 -11 -1
|
||||||
|
-29 -8 -39 -8 -10 -14 -29 -14 -41 0 -12 -11 -29 -25 -38 -27 -18 -34 -46 -11
|
||||||
|
-46 8 0 23 -3 33 -6 16 -5 16 -4 -2 12 -16 13 -17 16 -3 11 20 -7 34 9 16 17
|
||||||
|
-9 3 -8 9 6 20 10 8 19 26 20 40 0 14 7 28 14 31 6 2 12 3 12 2 -1 -19 -44
|
||||||
|
-134 -64 -172 -34 -63 -53 -84 -26 -28 11 23 20 47 20 53 0 18 -22 11 -27 -10
|
||||||
|
-6 -24 -16 -25 -34 -4 -11 13 -10 22 8 57 42 81 39 257 -5 310 -36 41 -150 6
|
||||||
|
-205 -64 l-25 -32 -32 30 -33 31 59 56 c68 65 107 86 159 86 24 0 34 4 29 11
|
||||||
|
-4 8 -27 9 -70 5 -62 -6 -63 -6 -78 23 -9 16 -21 35 -29 43 -27 28 -47 63 -47
|
||||||
|
85 0 12 -13 38 -30 56 -34 39 -38 71 -13 99 20 22 27 22 84 3z m2243 -59 c-37
|
||||||
|
-46 -45 -37 -9 9 15 20 29 34 32 31 3 -2 -8 -20 -23 -40z m-2797 -53 c-3 -10
|
||||||
|
-5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m-50 -220 c-3 -10 -5 -4 -5 12
|
||||||
|
0 17 2 24 5 18 2 -7 2 -21 0 -30z m10 -75 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13
|
||||||
|
3 -3 4 -12 1 -19z m802 -74 c11 -14 23 -40 26 -58 6 -33 -17 -162 -32 -177
|
||||||
|
-12 -12 -153 154 -153 179 0 21 21 42 65 65 43 23 71 21 94 -9z m-1135 -5 c-3
|
||||||
|
-5 -10 -7 -15 -3 -5 3 -7 10 -3 15 3 5 10 7 15 3 5 -3 7 -10 3 -15z m905 -66
|
||||||
|
c29 -38 71 -95 95 -128 23 -33 66 -93 95 -133 32 -45 44 -69 32 -63 -10 6 -21
|
||||||
|
14 -23 18 -2 5 -16 19 -32 33 -23 20 -27 21 -19 6 9 -16 6 -23 -13 -39 -13
|
||||||
|
-10 -24 -25 -24 -34 0 -12 -3 -13 -14 -4 -7 6 -21 8 -30 5 -16 -6 -16 -8 0
|
||||||
|
-25 10 -11 15 -22 12 -25 -3 -3 -19 14 -35 38 -16 24 -66 97 -111 162 -45 66
|
||||||
|
-82 125 -82 131 0 7 14 31 30 53 17 23 30 49 30 57 0 35 39 12 89 -52z m-127
|
||||||
|
35 c-7 -7 -12 -8 -12 -2 0 6 3 14 7 17 3 4 9 5 12 2 2 -3 -1 -11 -7 -17z
|
||||||
|
m-852 -91 c0 -14 -76 -124 -116 -167 -12 -14 -39 -44 -59 -67 -38 -44 -55 -47
|
||||||
|
-55 -12 0 36 30 78 84 119 30 23 59 54 66 71 15 34 4 54 -13 24 -10 -20 -23
|
||||||
|
-32 -105 -107 -30 -27 -43 -48 -49 -80 -7 -37 -13 -44 -38 -49 -25 -6 -26 -7
|
||||||
|
-7 -8 14 -1 22 -6 19 -13 -2 -9 -24 -13 -62 -13 -72 0 -83 18 -34 54 19 14 72
|
||||||
|
62 119 108 125 120 168 151 213 152 24 1 37 -4 37 -12z m843 -75 c12 -25 8
|
||||||
|
-35 -45 -137 -31 -60 -58 -105 -59 -100 -1 6 -5 -3 -9 -20 -7 -29 -8 -29 -9 9
|
||||||
|
-1 50 24 144 59 224 31 66 41 70 63 24z m67 -131 c0 -5 23 -43 50 -84 28 -41
|
||||||
|
50 -81 50 -89 0 -26 -73 -85 -120 -96 -60 -15 -73 1 -67 78 5 64 55 200 74
|
||||||
|
200 7 0 13 -4 13 -9z m230 -71 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5
|
||||||
|
10 10 10 6 0 10 -4 10 -10z m1771 -133 l11 -87 -39 -48 c-21 -26 -61 -80 -88
|
||||||
|
-121 -28 -40 -56 -76 -62 -78 -7 -3 -13 -13 -13 -22 -1 -9 -11 -34 -24 -56
|
||||||
|
-20 -34 -28 -40 -55 -38 -18 0 -34 3 -37 6 -12 11 140 326 235 487 45 77 56
|
||||||
|
90 58 70 2 -14 8 -64 14 -113z m-3128 108 c0 -6 -7 -11 -16 -13 -12 -3 -15 1
|
||||||
|
-11 13 7 17 25 17 27 0z m-100 -36 c-12 -12 -103 -21 -103 -10 0 16 15 21 64
|
||||||
|
21 35 0 47 -3 39 -11z m81 -5 c26 -10 18 -24 -13 -24 -30 0 -46 12 -34 24 8 8
|
||||||
|
27 8 47 0z m1320 -8 c-3 -8 -1 -17 5 -21 6 -3 11 -11 11 -18 0 -15 -29 25 -30
|
||||||
|
41 0 6 4 12 10 12 5 0 7 -6 4 -14z m1958 -220 c64 -73 297 -263 372 -303 l61
|
||||||
|
-32 -40 5 c-22 3 -61 12 -87 20 -25 8 -53 11 -61 8 -28 -10 -361 73 -460 115
|
||||||
|
l-47 20 47 73 c26 40 60 90 77 111 l30 38 29 -57 c40 -79 163 -198 265 -258
|
||||||
|
30 -18 7 6 -50 52 -136 109 -200 192 -232 301 -25 84 -18 92 17 24 18 -34 53
|
||||||
|
-87 79 -117z m11 65 c-2 -6 1 -11 5 -11 5 0 9 -7 9 -17 0 -13 -4 -11 -19 7
|
||||||
|
-21 26 -24 44 -5 37 6 -2 11 -10 10 -16z m-648 -26 c-7 -16 -27 -61 -45 -99
|
||||||
|
l-32 -69 -18 41 c-11 23 -30 57 -43 75 -13 17 -32 44 -42 60 l-18 27 106 -2
|
||||||
|
105 -2 -13 -31z m-445 -40 c-17 -25 -33 -45 -36 -45 -3 0 9 20 26 45 17 25 33
|
||||||
|
45 36 45 3 0 -9 -20 -26 -45z m-80 -114 c0 -12 -41 -63 -47 -57 -4 4 37 66 44
|
||||||
|
66 2 0 3 -4 3 -9z m1505 -73 c39 -21 67 -38 62 -38 -15 0 -142 68 -167 90
|
||||||
|
l-25 22 30 -18 c17 -10 62 -35 100 -56z m-1555 -2 c0 -3 -4 -8 -10 -11 -5 -3
|
||||||
|
-10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z m-30 -36 c0 -5 -5 -10 -11 -10
|
||||||
|
-5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m1180 -65 c52 -13 104 -26
|
||||||
|
115 -29 11 -3 -44 -3 -122 0 -132 4 -250 17 -261 28 -2 3 6 21 17 40 l22 35
|
||||||
|
67 -25 c37 -14 110 -36 162 -49z m-348 -25 c30 0 30 0 15 -24 -42 -64 -167
|
||||||
|
-305 -167 -323 0 -6 -4 -14 -9 -18 -11 -6 20 96 79 263 25 68 46 119 48 113 2
|
||||||
|
-6 17 -11 34 -11z m-689 -33 c39 -4 97 -4 128 0 58 6 134 -2 156 -15 9 -6 4
|
||||||
|
-33 -21 -107 -18 -55 -45 -146 -61 -202 l-28 -101 -86 -12 c-100 -14 -304 -56
|
||||||
|
-341 -70 -14 -5 -59 -19 -100 -31 -41 -11 -81 -26 -88 -31 -9 -8 -11 -6 -5 9
|
||||||
|
17 42 193 335 219 364 15 17 110 37 344 75 102 16 153 34 97 34 -46 0 -239
|
||||||
|
-29 -322 -49 -44 -11 -81 -18 -83 -16 -5 5 13 38 67 124 34 54 47 68 49 54 3
|
||||||
|
-17 13 -21 75 -26z m-158 -47 c-9 -16 -18 -30 -21 -30 -2 0 2 14 11 30 9 17
|
||||||
|
18 30 21 30 2 0 -2 -13 -11 -30z m1248 -327 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12
|
||||||
|
5 14 0 19 -2 13 -5z m-543 -153 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1
|
||||||
|
10 4 10 6 0 11 -4 11 -10z"/>
|
||||||
|
<path d="M3420 4420 c-19 -11 -28 -19 -20 -20 9 0 26 7 38 16 12 8 27 12 32 9
|
||||||
|
6 -3 10 -1 10 4 0 16 -20 13 -60 -9z"/>
|
||||||
|
<path d="M3184 4304 c-18 -14 -18 -14 6 -3 31 14 36 19 24 19 -6 0 -19 -7 -30
|
||||||
|
-16z"/>
|
||||||
|
<path d="M3530 4296 c0 -2 7 -7 16 -10 8 -3 12 -2 9 4 -6 10 -25 14 -25 6z"/>
|
||||||
|
<path d="M3408 4258 c5 -5 16 -8 23 -6 8 3 3 7 -10 11 -17 4 -21 3 -13 -5z"/>
|
||||||
|
<path d="M3546 4251 c-4 -7 -5 -15 -2 -18 9 -9 19 4 14 18 -4 11 -6 11 -12 0z"/>
|
||||||
|
<path d="M3118 4203 c12 -2 32 -2 45 0 12 2 2 4 -23 4 -25 0 -35 -2 -22 -4z"/>
|
||||||
|
<path d="M3203 4193 c9 -2 25 -2 35 0 9 3 1 5 -18 5 -19 0 -27 -2 -17 -5z"/>
|
||||||
|
<path d="M3340 4175 c83 -13 168 -19 159 -11 -5 5 -88 15 -174 20 l-70 5 85
|
||||||
|
-14z"/>
|
||||||
|
<path d="M3575 4150 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||||
|
-8 -4 -11 -10z"/>
|
||||||
|
<path d="M3178 4053 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||||
|
<path d="M3268 4043 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||||
|
<path d="M3303 4025 c0 -8 4 -15 9 -15 4 0 8 4 8 9 0 6 13 6 33 1 29 -9 30 -8
|
||||||
|
13 5 -26 20 -63 19 -63 0z"/>
|
||||||
|
<path d="M2978 3943 c6 -2 18 -2 25 0 6 3 1 5 -13 5 -14 0 -19 -2 -12 -5z"/>
|
||||||
|
<path d="M3045 3930 c17 -4 44 -8 60 -8 25 0 24 2 -10 9 -51 10 -92 10 -50 -1z"/>
|
||||||
|
<path d="M3155 3910 c27 -12 43 -12 25 0 -8 5 -22 9 -30 9 -10 0 -8 -3 5 -9z"/>
|
||||||
|
<path d="M3235 3898 c22 -6 44 -16 48 -22 5 -7 7 -4 5 8 -2 15 -13 20 -48 22
|
||||||
|
l-45 3 40 -11z"/>
|
||||||
|
<path d="M3368 3843 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||||
|
<path d="M2638 3703 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||||
|
<path d="M2685 3690 c11 -5 29 -8 40 -8 16 0 15 2 -5 8 -34 11 -60 11 -35 0z"/>
|
||||||
|
<path d="M1950 3646 c0 -2 7 -7 16 -10 8 -3 12 -2 9 4 -6 10 -25 14 -25 6z"/>
|
||||||
|
<path d="M2020 3531 c0 -6 4 -13 10 -16 6 -3 7 1 4 9 -7 18 -14 21 -14 7z"/>
|
||||||
|
<path d="M2620 3529 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||||
|
-5 -10 -11z"/>
|
||||||
|
<path d="M3199 3292 c-6 -21 -9 -49 -7 -62 3 -23 6 -20 35 27 31 50 32 53 13
|
||||||
|
63 -27 14 -28 14 -41 -28z"/>
|
||||||
|
<path d="M3456 2997 c-49 -49 -23 -147 43 -162 66 -14 111 25 111 98 0 44 -35
|
||||||
|
77 -88 84 -34 5 -45 1 -66 -20z m100 -12 c4 -8 3 -23 -2 -32 -4 -10 -6 -22 -5
|
||||||
|
-26 0 -4 -12 -1 -29 8 -16 9 -30 21 -30 28 0 33 55 51 66 22z"/>
|
||||||
|
<path d="M3690 2850 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||||
|
-4 -4 -4 -10z"/>
|
||||||
|
<path d="M2582 2805 c-23 -7 -53 -20 -65 -28 -29 -19 -58 -24 -74 -14 -7 5
|
||||||
|
-13 4 -13 0 0 -5 6 -15 13 -22 10 -10 7 -16 -13 -32 -14 -10 -30 -23 -36 -28
|
||||||
|
-5 -4 -26 -6 -45 -4 -32 4 -33 3 -15 -11 11 -9 28 -16 39 -16 10 0 15 -4 12
|
||||||
|
-10 -3 -5 -26 -10 -51 -10 -28 0 -43 -4 -39 -10 3 -5 17 -10 31 -10 30 0 31
|
||||||
|
-15 2 -25 -21 -6 -21 -7 10 -16 40 -12 38 -29 -6 -48 -41 -19 -41 -32 1 -24
|
||||||
|
29 6 31 5 18 -10 -15 -19 -1 -23 17 -5 6 6 15 9 19 5 3 -4 -3 -16 -15 -27 -30
|
||||||
|
-28 -28 -42 3 -30 28 11 39 0 30 -30 -6 -18 -3 -19 25 -14 24 5 36 2 55 -16
|
||||||
|
14 -13 25 -30 25 -37 0 -8 5 -11 12 -7 6 4 17 -1 24 -11 11 -15 16 -16 29 -5
|
||||||
|
12 10 18 10 30 0 12 -10 18 -8 34 11 l19 24 -40 3 c-50 4 -82 24 -119 76 -54
|
||||||
|
74 -36 161 49 238 60 53 117 72 195 62 l52 -6 -29 21 c-17 11 -51 25 -78 31
|
||||||
|
-55 14 -63 30 -15 31 30 1 31 1 7 9 -35 11 -49 11 -98 -5z"/>
|
||||||
|
<path d="M2684 2617 c-23 -20 -29 -32 -28 -66 1 -22 9 -52 17 -65 34 -52 136
|
||||||
|
-41 156 16 17 47 14 65 -16 98 -40 43 -90 50 -129 17z m80 -3 c18 -7 22 -54 5
|
||||||
|
-54 -5 0 -7 -5 -4 -10 4 -6 -5 -5 -19 2 -28 12 -36 52 -13 61 6 3 13 6 14 6 1
|
||||||
|
1 8 -2 17 -5z"/>
|
||||||
|
<path d="M3444 2382 c4 -6 2 -30 -4 -52 -12 -43 -3 -79 11 -44 12 30 10 92 -3
|
||||||
|
100 -7 4 -8 3 -4 -4z"/>
|
||||||
|
<path d="M2671 2324 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||||
|
<path d="M3335 2316 c-10 -14 -21 -23 -26 -20 -15 9 -10 -13 7 -27 8 -7 13
|
||||||
|
-21 11 -31 -3 -10 -1 -18 4 -18 5 0 9 16 9 35 0 33 2 35 33 33 28 -3 32 0 32
|
||||||
|
22 0 37 -47 41 -70 6z"/>
|
||||||
|
<path d="M3050 2273 c0 -21 43 -74 70 -88 44 -23 47 -13 5 16 -19 13 -35 27
|
||||||
|
-35 31 0 20 122 -28 141 -55 9 -13 32 21 25 38 -9 25 -76 48 -133 47 -29 0
|
||||||
|
-53 4 -53 9 0 5 -4 9 -10 9 -5 0 -10 -3 -10 -7z"/>
|
||||||
|
<path d="M3425 2090 c-92 -22 -187 -92 -227 -167 -32 -57 -44 -141 -30 -198
|
||||||
|
38 -150 100 -234 217 -289 68 -32 84 -36 160 -36 51 0 97 6 117 14 18 8 49 20
|
||||||
|
68 27 19 7 59 38 90 69 74 74 102 152 101 275 -1 93 -6 108 -57 171 -39 49
|
||||||
|
-172 119 -253 134 -61 11 -142 11 -186 0z m144 -96 c17 -4 31 -11 31 -15 0 -5
|
||||||
|
-40 -36 -90 -68 -85 -56 -151 -81 -215 -81 -30 0 -31 13 -6 54 51 82 175 131
|
||||||
|
280 110z m296 -254 c0 -22 -39 -19 -43 3 -3 15 1 18 20 15 12 -2 23 -10 23
|
||||||
|
-18z m-85 -26 c0 -11 -23 -50 -53 -87 -50 -64 -23 -52 38 17 31 36 61 63 66
|
||||||
|
60 31 -18 -29 -109 -109 -167 -67 -48 -123 -65 -218 -68 -64 -2 -80 1 -82 13
|
||||||
|
-2 11 8 18 35 23 34 7 36 8 16 16 -36 13 -25 39 20 46 10 2 33 14 50 27 18 13
|
||||||
|
66 40 108 60 42 20 82 43 89 51 12 14 40 21 40 9z"/>
|
||||||
|
<path d="M4381 2664 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||||
|
<path d="M2330 1941 c0 -5 5 -13 10 -16 6 -3 10 -2 10 4 0 5 -4 13 -10 16 -5
|
||||||
|
3 -10 2 -10 -4z"/>
|
||||||
|
<path d="M2570 1360 c0 -5 7 -10 16 -10 8 0 12 5 9 10 -3 6 -10 10 -16 10 -5
|
||||||
|
0 -9 -4 -9 -10z"/>
|
||||||
|
<path d="M2086 1274 c-4 -14 -5 -28 -3 -31 3 -2 8 8 11 23 4 14 5 28 3 31 -3
|
||||||
|
2 -8 -8 -11 -23z"/>
|
||||||
|
<path d="M4590 680 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||||
|
-4 -4 -4 -10z"/>
|
||||||
|
<path d="M4420 1850 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||||
|
-10 -4 -10 -10z"/>
|
||||||
|
<path d="M4472 1585 c0 -16 2 -22 5 -12 2 9 2 23 0 30 -3 6 -5 -1 -5 -18z"/>
|
||||||
|
<path d="M4473 1455 c0 -22 2 -30 4 -17 2 12 2 30 0 40 -3 9 -5 -1 -4 -23z"/>
|
||||||
|
<path d="M4481 1370 c0 -8 4 -24 9 -35 5 -13 9 -14 9 -5 0 8 -4 24 -9 35 -5
|
||||||
|
13 -9 14 -9 5z"/>
|
||||||
|
<path d="M4550 1185 c0 -5 5 -17 10 -25 5 -8 10 -10 10 -5 0 6 -5 17 -10 25
|
||||||
|
-5 8 -10 11 -10 5z"/>
|
||||||
|
<path d="M4570 1131 c0 -6 4 -13 10 -16 6 -3 7 1 4 9 -7 18 -14 21 -14 7z"/>
|
||||||
|
<path d="M4645 1013 c34 -53 45 -67 45 -60 0 10 -51 87 -57 87 -3 0 3 -12 12
|
||||||
|
-27z"/>
|
||||||
|
<path d="M4238 543 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||||
|
<path d="M4338 533 c6 -2 18 -2 25 0 6 3 1 5 -13 5 -14 0 -19 -2 -12 -5z"/>
|
||||||
|
<path d="M2755 370 c39 -26 55 -26 22 0 -14 11 -31 20 -39 20 -7 0 1 -9 17
|
||||||
|
-20z"/>
|
||||||
|
<path d="M2738 293 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||||
|
<path d="M3517 180 c-3 -11 -1 -20 4 -20 5 0 9 2 9 4 0 2 3 11 6 20 3 9 2 16
|
||||||
|
-4 16 -5 0 -12 -9 -15 -20z"/>
|
||||||
|
<path d="M1705 180 c-3 -5 1 -10 9 -10 8 0 16 -6 19 -12 2 -7 3 -5 2 4 -2 9 2
|
||||||
|
19 9 22 6 2 1 5 -11 5 -12 1 -25 -3 -28 -9z"/>
|
||||||
|
<path d="M2490 177 c29 -16 124 -31 116 -18 -3 5 -25 11 -48 15 -24 4 -54 9
|
||||||
|
-68 12 l-25 5 25 -14z"/>
|
||||||
|
<path d="M2423 163 c9 -2 23 -2 30 0 6 3 -1 5 -18 5 -16 0 -22 -2 -12 -5z"/>
|
||||||
|
<path d="M1690 139 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||||
|
-5 -10 -11z"/>
|
||||||
|
<path d="M3497 109 c-7 -28 -6 -31 10 -14 6 6 8 18 3 24 -5 9 -9 5 -13 -10z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 25 KiB |
17
public/index.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
||||||
|
|
||||||
|
<title>Svelte app</title>
|
||||||
|
|
||||||
|
<link rel='icon' type='image/png' href='/favicon.png'>
|
||||||
|
<link rel='stylesheet' href='/build/bundle.css'>
|
||||||
|
|
||||||
|
<script defer src='/build/bundle.js'></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
21
public/manifest.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "Jubilee",
|
||||||
|
"short_name": "Jubilee",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/img/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/img/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#FFEE58",
|
||||||
|
"background_color": "#ffffff",
|
||||||
|
"start_url": ".",
|
||||||
|
"imgdisplay": "standalone",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
107
public/service-worker.js
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
// Copyright 2016 Google Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
const CACHE_VERSION = { 'version': '0.2.2' };
|
||||||
|
|
||||||
|
const dataCacheName = `jubileeData-v${CACHE_VERSION.version}`;
|
||||||
|
const cacheName = `jubilee-final-${CACHE_VERSION.version}`;
|
||||||
|
|
||||||
|
|
||||||
|
const RUNTIME = 'runtime';
|
||||||
|
|
||||||
|
const filesToCache = [
|
||||||
|
'/',
|
||||||
|
'/index.html',
|
||||||
|
'/service-worker.js',
|
||||||
|
'/manifest.json',
|
||||||
|
'/favicon.png',
|
||||||
|
'/browserconfig.xml',
|
||||||
|
'/build/bundle.css',
|
||||||
|
'/build/bundle.js',
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
self.addEventListener('install', function(e) {
|
||||||
|
console.log('[ServiceWorker] Install');
|
||||||
|
e.waitUntil(
|
||||||
|
caches.open(cacheName).then(function(cache) {
|
||||||
|
console.log('[ServiceWorker] Caching app shell');
|
||||||
|
|
||||||
|
return cache.addAll(filesToCache);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('activate', function(e) {
|
||||||
|
console.log('[ServiceWorker] Activate');
|
||||||
|
e.waitUntil(
|
||||||
|
caches.keys().then(function(keyList) {
|
||||||
|
return Promise.all(keyList.map(function(key) {
|
||||||
|
if (key !== cacheName && key !== dataCacheName) {
|
||||||
|
console.log('[ServiceWorker] Removing old cache', key);
|
||||||
|
|
||||||
|
return caches.delete(key);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fixes a corner case in which the app wasn't returning the latest data.
|
||||||
|
* You can reproduce the corner case by commenting out the line below and
|
||||||
|
* then doing the following steps: 1) load app for first time so that the
|
||||||
|
* initial New York City data is shown 2) press the refresh button on the
|
||||||
|
* app 3) go offline 4) reload the app. You expect to see the newer NYC
|
||||||
|
* data, but you actually see the initial data. This happens because the
|
||||||
|
* service worker is not yet activated. The code below essentially lets
|
||||||
|
* you activate the service worker faster.
|
||||||
|
*/
|
||||||
|
return self.clients.claim();
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', function(e) {
|
||||||
|
console.warn('[Service Worker] Fetch', e.request.url);
|
||||||
|
const dataUrl = '/getnexttraintimes?';
|
||||||
|
if (e.request.url.indexOf(dataUrl) > -1) {
|
||||||
|
console.log('!');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the request URL contains dataUrl, the app is asking for fresh
|
||||||
|
* weather data. In this case, the service worker always goes to the
|
||||||
|
* network and then caches the response. This is called the "Cache then
|
||||||
|
* network" strategy:
|
||||||
|
* https://jakearchibald.com/2014/offline-cookbook/#cache-then-network
|
||||||
|
*/
|
||||||
|
e.respondWith(
|
||||||
|
caches.open(dataCacheName).then(function(cache) {
|
||||||
|
return fetch(e.request).then(function(response) {
|
||||||
|
cache.put(e.request.url, response.clone());
|
||||||
|
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The app is asking for app shell files. In this scenario the app uses the
|
||||||
|
* "Cache, falling back to the network" offline strategy:
|
||||||
|
* https://jakearchibald.com/2014/offline-cookbook/#cache-falling-back-to-network
|
||||||
|
*/
|
||||||
|
e.respondWith(
|
||||||
|
caches.match(e.request).then(function(response) {
|
||||||
|
return response || fetch(e.request);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
91
rollup.config.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import svelte from 'rollup-plugin-svelte';
|
||||||
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
|
import livereload from 'rollup-plugin-livereload';
|
||||||
|
import replace from 'rollup-plugin-replace';
|
||||||
|
import { terser } from 'rollup-plugin-terser';
|
||||||
|
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 preprocess = sveltePreprocess({
|
||||||
|
'scss': {
|
||||||
|
'includePaths': ['src']
|
||||||
|
},
|
||||||
|
'postcss': {
|
||||||
|
'plugins': [require('autoprefixer')]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default {
|
||||||
|
'input': 'src/main.js',
|
||||||
|
'output': {
|
||||||
|
'sourcemap': (!production),
|
||||||
|
'format': 'iife',
|
||||||
|
'name': 'app',
|
||||||
|
'file': 'public/build/bundle.js'
|
||||||
|
},
|
||||||
|
'plugins': [
|
||||||
|
globals(),
|
||||||
|
builtins(),
|
||||||
|
svelte({
|
||||||
|
// enable run-time checks when not in production
|
||||||
|
'dev': !production,
|
||||||
|
preprocess,
|
||||||
|
// we'll extract any component CSS out into
|
||||||
|
// a separate file - better for performance
|
||||||
|
'css': css => {
|
||||||
|
css.write('public/build/bundle.css');
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
// If you have external dependencies installed from
|
||||||
|
// npm, you'll most likely need these plugins. In
|
||||||
|
// some cases you'll need additional configuration -
|
||||||
|
// consult the documentation for details:
|
||||||
|
// https://github.com/rollup/plugins/tree/master/packages/commonjs
|
||||||
|
resolve({
|
||||||
|
'browser': true,
|
||||||
|
'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
|
||||||
|
!production && serve(),
|
||||||
|
|
||||||
|
// Watch the `public` directory and refresh the
|
||||||
|
// browser on changes when not in production
|
||||||
|
!production && livereload('public'),
|
||||||
|
|
||||||
|
// If we're building for production (npm run build
|
||||||
|
// instead of npm run dev), minify
|
||||||
|
production && terser()
|
||||||
|
],
|
||||||
|
'watch': {
|
||||||
|
'clearScreen': false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function serve() {
|
||||||
|
let started = false;
|
||||||
|
|
||||||
|
return {
|
||||||
|
writeBundle() {
|
||||||
|
if (!started) {
|
||||||
|
started = true;
|
||||||
|
|
||||||
|
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
|
||||||
|
'stdio': ['ignore', 'inherit', 'inherit'],
|
||||||
|
'shell': true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
36
src/App.svelte
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<script>
|
||||||
|
import Router from 'svelte-spa-router';
|
||||||
|
import routes from './routes'
|
||||||
|
import Header from "./components/Header.svelte";
|
||||||
|
|
||||||
|
let currentPage;
|
||||||
|
|
||||||
|
function conditionsFailed(event) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Caught event conditionsFailed', event.detail)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles the "routeLoaded" event dispatched by the router after a route has been successfully loaded
|
||||||
|
function routeLoaded(event) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.info('Caught event routeLoaded', event.detail)
|
||||||
|
currentPage = event.detail;
|
||||||
|
console.log('currentPage', currentPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles event bubbling up from nested routes
|
||||||
|
function routeEvent(event) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.info('Caught event routeEvent', event.detail)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" global>
|
||||||
|
// @import "./css/custom.scss";
|
||||||
|
@import "./css/global.scss";
|
||||||
|
@import './fonts/fujicons.css';
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<Header page={currentPage}/>
|
||||||
|
<Router {routes} on:conditionsFailed={conditionsFailed} on:routeLoaded={routeLoaded} on:routeEvent={routeEvent} />
|
12
src/components/Agenda.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>Agenda</span>
|
12
src/components/AroundMe.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>Around Me</span>
|
12
src/components/ByMe.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>AROUND ME</span>
|
12
src/components/ClosestItem.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>CLOSEST ITEM</span>
|
12
src/components/Debug.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>$</span>
|
76
src/components/Greeter.svelte
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<script>
|
||||||
|
import {state} from '../store/globalState';
|
||||||
|
import {partOfDay, toHour} from '../lib/utils';
|
||||||
|
|
||||||
|
let date = new Date()
|
||||||
|
|
||||||
|
let todaySegment = partOfDay();
|
||||||
|
let icon = '';
|
||||||
|
let place = '';
|
||||||
|
let atHome = false;
|
||||||
|
let atWork = false;
|
||||||
|
let locationName = '';
|
||||||
|
let homeIcon = '<span role="img" aria-label="Home">🏠</span>';
|
||||||
|
let workIcon = '<span role="img" aria-label="Home">🏢</span>';
|
||||||
|
|
||||||
|
|
||||||
|
$: {
|
||||||
|
console.log('>> Greeter Reactive!');
|
||||||
|
let prefix = '';
|
||||||
|
if (atHome) {
|
||||||
|
icon = homeIcon;
|
||||||
|
prefix = 'At home, ';
|
||||||
|
} else if (atWork) {
|
||||||
|
icon = workIcon;
|
||||||
|
prefix = 'At work, ';
|
||||||
|
} else icon = '';
|
||||||
|
|
||||||
|
if (locationName !== '') place = `${prefix}${locationName}`;
|
||||||
|
|
||||||
|
}
|
||||||
|
let greeterTimerId = setTimeout(
|
||||||
|
() => greeterTick(),
|
||||||
|
toHour()
|
||||||
|
);
|
||||||
|
|
||||||
|
function greeterTick() {
|
||||||
|
date = new Date();
|
||||||
|
todaySegment = partOfDay();
|
||||||
|
console.log('Date', date);
|
||||||
|
|
||||||
|
greeterTimerId = setTimeout(
|
||||||
|
() => greeterTick(),
|
||||||
|
toHour()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.location.subscribe(async (v) => {
|
||||||
|
console.log('>> Greeter:Location changed');
|
||||||
|
|
||||||
|
if (v.hasOwnProperty('atHome')) {
|
||||||
|
atHome = v.atHome;
|
||||||
|
atWork = v.atWork;
|
||||||
|
locationName = v.city;
|
||||||
|
} else {
|
||||||
|
console.log('>> Greeter:No location yet');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.greetPanel {
|
||||||
|
text-shadow: 1px 1px 2px #212121;
|
||||||
|
color: white;
|
||||||
|
/*height:24vw;*/
|
||||||
|
background-size: cover;
|
||||||
|
background-color: goldenrod;
|
||||||
|
background-image: url(../gfx/default_daily_image.jpg);
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="mui-panel greetPanel mui--text-center">
|
||||||
|
<h2>{todaySegment}</h2>
|
||||||
|
<div>{@html icon} {place}</div>
|
||||||
|
</div>
|
51
src/components/Header.svelte
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<script>
|
||||||
|
import {pop} from 'svelte-spa-router';
|
||||||
|
|
||||||
|
export let page;
|
||||||
|
let showFav = false;
|
||||||
|
|
||||||
|
let titleText = 'Traintimes';
|
||||||
|
let currentMode = 0;
|
||||||
|
let visible = false;
|
||||||
|
$: {
|
||||||
|
visible = (page && page.name !== 'Home');
|
||||||
|
currentMode = (page && page.name === 'Home') ? 0 : 1;
|
||||||
|
console.log('>> HEADER', page);
|
||||||
|
}
|
||||||
|
|
||||||
|
function goBack() {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function goHome() {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.navbar {
|
||||||
|
color: #212121;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{#if visible}
|
||||||
|
<header class="navbar bg-primary">
|
||||||
|
|
||||||
|
<section class="navbar-section">
|
||||||
|
{#if currentMode === 1}
|
||||||
|
<span on:click={goBack} class="">
|
||||||
|
<i class="fa-2x fa fa-back-chevron" ></i>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
|
<span class="text-bold navbar-brand mx-1 text-uppercase">{titleText}</span>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</header>
|
||||||
|
{/if}
|
53
src/components/LatestNews.svelte
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<script>
|
||||||
|
import {state} from '../store/globalState';
|
||||||
|
import {isEmpty} from "../lib/utils";
|
||||||
|
import NewsCard from "./NewsCard.svelte";
|
||||||
|
|
||||||
|
const prefix = '🗂️';
|
||||||
|
const imgStripper = /<\/?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)\/?>/ig;
|
||||||
|
|
||||||
|
let doRender = true;
|
||||||
|
let list;
|
||||||
|
|
||||||
|
let listData;
|
||||||
|
state.newsList.subscribe(async (v) => {
|
||||||
|
if (!isEmpty(v)) {
|
||||||
|
console.log(`${prefix} LatestNews:newsList: Changed`);
|
||||||
|
|
||||||
|
const worklist = v.items.slice(0, 10);
|
||||||
|
|
||||||
|
// sanitise the items..
|
||||||
|
|
||||||
|
list = worklist.map((item) => {
|
||||||
|
const tempItem = item;
|
||||||
|
tempItem.description = tempItem.description.replace(imgStripper, '');
|
||||||
|
tempItem.description = (tempItem.description === '1') ? '' : tempItem.description;
|
||||||
|
return tempItem;
|
||||||
|
})
|
||||||
|
|
||||||
|
doRender = true
|
||||||
|
} else {
|
||||||
|
doRender = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{#if doRender}
|
||||||
|
<div id="weatherShell" class="mui-panel">
|
||||||
|
<div class="mui--text-title cardTitle">Latest News</div>
|
||||||
|
<div id="news" class="scrolling-wrapper-flexbox">
|
||||||
|
{#each list as item, i}
|
||||||
|
<NewsCard {item} id={i}/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<div id='newsMore' class="cardLink">
|
||||||
|
<i class="seemore fa fa-forward mui--align-middle " ></i> <span class="seemore mui--align-middle">More news</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
12
src/components/NearbyPlaces.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>NEARBY PLACES</span>
|
23
src/components/NewsCard.svelte
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script>
|
||||||
|
import {push} from 'svelte-spa-router';
|
||||||
|
export let item;
|
||||||
|
export let id;
|
||||||
|
|
||||||
|
console.log(id, item);
|
||||||
|
|
||||||
|
function clickHandler() {
|
||||||
|
console.log('clicked', id);
|
||||||
|
push(`/news/${id}`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="scrollCard">
|
||||||
|
<div class="mui--text-subhead mui--text-accent" on:click={clickHandler}>{item.title}</div>
|
||||||
|
<div class="published mui--text-dark-secondary mui--text-caption">{item.pubdate}</div>
|
||||||
|
|
||||||
|
<p class="mui--text-body1">{item.description}</p>
|
||||||
|
</div>
|
12
src/components/NewsItem.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>NewsItem</span>
|
12
src/components/Traffic.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>TRAFFIC</span>
|
12
src/components/UpcomingEvents.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>UPCOMING EVENTS</span>
|
170
src/components/Weather.svelte
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<script>
|
||||||
|
import {state} from '../store/globalState';
|
||||||
|
import {distance, hourFloor, isEmpty} from "../lib/utils";
|
||||||
|
import {reduceOpenWeather} from '../lib/reducers';
|
||||||
|
|
||||||
|
|
||||||
|
let log = null;
|
||||||
|
let llFixed;
|
||||||
|
let slug;
|
||||||
|
let weatherData = {};
|
||||||
|
let doRender = false;
|
||||||
|
let timerID = 0;
|
||||||
|
|
||||||
|
const prefix = '🗂️';
|
||||||
|
|
||||||
|
const __url = state.getBaseUrl();
|
||||||
|
|
||||||
|
state.weather.subscribe(async (v) => {
|
||||||
|
if (!isEmpty(v)) {
|
||||||
|
console.log(`${prefix} >> Weather: Changed`);
|
||||||
|
|
||||||
|
weatherData = makeRenderable(v[0]);
|
||||||
|
// console.log(v);
|
||||||
|
|
||||||
|
doRender = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
state.location.subscribe(async (v) => {
|
||||||
|
console.log(`${prefix} >> Weather:Location changed`);
|
||||||
|
|
||||||
|
if (v.hasOwnProperty('atHome')) {
|
||||||
|
|
||||||
|
if (v.llFixed !== llFixed) {
|
||||||
|
llFixed = v.llFixed;
|
||||||
|
slug = v.slug;
|
||||||
|
|
||||||
|
onChange();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`${prefix} >> Weather:No location yet`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function makeRenderable(data) {
|
||||||
|
const outObj = {...data};
|
||||||
|
|
||||||
|
outObj.tempClass = `temp${data.temp}`;
|
||||||
|
outObj.tempHighClass = `temp${~~(data.tempHigh)}`;
|
||||||
|
outObj.tempLowClass = `temp${~~(data.tempLow)}`;
|
||||||
|
|
||||||
|
return outObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function onChange() {
|
||||||
|
console.log(`${prefix} >> Weather: LL has changed`);
|
||||||
|
let doGetWeather = false;
|
||||||
|
clearTimeout(timerID);
|
||||||
|
|
||||||
|
if (!log) {
|
||||||
|
console.info(`${prefix} First run`);
|
||||||
|
doGetWeather = true;
|
||||||
|
} else {
|
||||||
|
console.log(prefix, log);
|
||||||
|
const now = new Date().getTime();
|
||||||
|
console.log(`${prefix} >> Now`, now);
|
||||||
|
const timeDiff = now - log.timestamp;
|
||||||
|
const dist = distance(log.lat, log.lon, slug.lat, slug.lon);
|
||||||
|
|
||||||
|
console.log(`${prefix} Weather distance:`, dist, timeDiff);
|
||||||
|
|
||||||
|
if ((dist > 5.0) && (timeDiff > 1.8e+6))
|
||||||
|
doGetWeather = true;
|
||||||
|
else if (timeDiff > 3.6e+6) {
|
||||||
|
console.log(`${prefix} Weather hourly update`);
|
||||||
|
doGetWeather = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (doGetWeather) {
|
||||||
|
await getWeather();
|
||||||
|
}
|
||||||
|
|
||||||
|
timerID = setTimeout(
|
||||||
|
() => onChange(),
|
||||||
|
902000
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchWeather() {
|
||||||
|
const reqUrl = new URL('/weather', __url);
|
||||||
|
reqUrl.searchParams.append('ll', llFixed);
|
||||||
|
reqUrl.searchParams.append('w', hourFloor());
|
||||||
|
|
||||||
|
const res = await fetch(reqUrl.href);
|
||||||
|
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getWeather() {
|
||||||
|
console.log(`${prefix} >> Weather request`);
|
||||||
|
|
||||||
|
await fetchWeather().then((body) => {
|
||||||
|
const city = body.city.name || '';
|
||||||
|
const list = body.list || [];
|
||||||
|
let newItems = [];
|
||||||
|
for (const item of list)
|
||||||
|
newItems.push(reduceOpenWeather(item, city));
|
||||||
|
|
||||||
|
console.log(prefix, newItems);
|
||||||
|
state.weather.set(newItems);
|
||||||
|
logUpdate();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function logUpdate() {
|
||||||
|
const timestamp = {timestamp: new Date().getTime()}
|
||||||
|
log = {...slug, ...timestamp};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
{#if doRender}
|
||||||
|
<div id="weatherShell" class="mui-panel">
|
||||||
|
<div class="mui--text-title cardTitle">Weather</div>
|
||||||
|
<div id="weather">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="mui-col-md-4 mui-col-xs-4">
|
||||||
|
<div class="mui--text-display1 mui--text-center {weatherData.tempClass}">{weatherData.temp}°</div>
|
||||||
|
</div>
|
||||||
|
<div class="mui-col-md-4 mui-col-xs-4 mui--text-center">
|
||||||
|
<i class="mui--text-display1 wi {weatherData.icon}"></i>
|
||||||
|
</div>
|
||||||
|
<div class="mui-col-md-4 mui-col-xs-4">
|
||||||
|
<div>
|
||||||
|
<div class="mui--text-subhead summary">{weatherData.summary}</div>
|
||||||
|
<span class="mui--text-body2 {weatherData.tempClassHigh}">{weatherData.tempHigh}°</span> /
|
||||||
|
<span class="mui--text-body1 {weatherData.tempClassLow}">{weatherData.tempLow}°</span></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mui--text-dark-secondary mui--text-caption mui--text-right">
|
||||||
|
For {weatherData.city} to {weatherData.readdate}
|
||||||
|
</div>
|
||||||
|
<div id='wForecast' class="cardLink">
|
||||||
|
<i class="seemore fa fa-forward mui--align-middle "></i> <span class="seemore mui--align-middle">See forecast</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{/if}
|
12
src/components/WeatherAlert.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>WeatherAlert</span>
|
145
src/css/common.css
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
body {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
min-height:48px;
|
||||||
|
margin: 8px;
|
||||||
|
border-bottom-color: #666666;
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemRow {
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
min-height:48px;
|
||||||
|
border-bottom-color: #666666;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui--text-display4, .mui--text-display3 {
|
||||||
|
font-family: "Roboto Slab", "Helvetica Neue", Helvetica, Arial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp0, .temp1, .temp2, .temp3, .temp4, .temp5 {
|
||||||
|
color: rgb(80,181,221)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp6 {
|
||||||
|
color: rgb(78,178,206)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp7 {
|
||||||
|
color: rgb(76, 176, 190)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp8 {
|
||||||
|
color: rgb(73, 173, 175)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp9 {
|
||||||
|
color: rgb(72, 171, 159)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp10 {
|
||||||
|
color: rgb(70, 168, 142)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp11 {
|
||||||
|
color: rgb(68, 166, 125)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp12 {
|
||||||
|
color: rgb(66, 164, 108)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp13 {
|
||||||
|
color: rgb(102, 173, 94)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp14 {
|
||||||
|
color: rgb(135, 190, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp15 {
|
||||||
|
color: rgb(179, 204, 26)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp16 {
|
||||||
|
color: rgb(214, 213, 28)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp17 {
|
||||||
|
color: rgb(249, 202, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp18 {
|
||||||
|
color: rgb(246, 181, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp19 {
|
||||||
|
color: rgb(244, 150, 26)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp20 {
|
||||||
|
color: rgb(236, 110, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp21 {
|
||||||
|
color: #ea5a24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp22 {
|
||||||
|
color: #e4572b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp23 {
|
||||||
|
color: #e14a29;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp24 {
|
||||||
|
color: #e04127;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp25 {
|
||||||
|
color: #d9372b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp26 {
|
||||||
|
color: #d63129;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp27 {
|
||||||
|
color: #d12b2b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp28 {
|
||||||
|
color: #cd282f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp29 {
|
||||||
|
color: #c82432;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp30 {
|
||||||
|
color: #c32334;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp31 {
|
||||||
|
color: #be2138;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp32, .temp33, .temp34, .temp35 {
|
||||||
|
color: #b9203b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.day {
|
||||||
|
font-family: "Roboto Slab", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.summary::first-letter {
|
||||||
|
text-transform: capitalize
|
||||||
|
}
|
561
src/css/custom.scss
Normal file
@ -0,0 +1,561 @@
|
|||||||
|
// import MUI colors
|
||||||
|
@import "./node_modules/muicss/lib/sass/mui/colors";
|
||||||
|
|
||||||
|
// customize MUI variables
|
||||||
|
$mui-primary-color: mui-color('yellow', '500');
|
||||||
|
$mui-primary-color-dark: mui-color('blue-grey', '700');
|
||||||
|
$mui-primary-color-light: mui-color('blue-grey', '100');
|
||||||
|
|
||||||
|
$mui-accent-color: mui-color('deep-purple', '900');
|
||||||
|
$mui-accent-color-dark: mui-color('indigo', 'A100');
|
||||||
|
$mui-accent-color-light: mui-color('indigo', 'A400');
|
||||||
|
|
||||||
|
$mui-base-font-family: 'Roboto', "Helvetica Neue", Helvetica, Arial, Verdana, "Trebuchet MS";
|
||||||
|
$mui-base-font-weight: 400;
|
||||||
|
|
||||||
|
$mui-appbar-font-color: mui-color('black') !default;
|
||||||
|
|
||||||
|
$mui-link-font-color: mui-color('yellow', '900') !default;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--primary-color: mui-color('yellow', '500');
|
||||||
|
--dark-color: #294c5d;
|
||||||
|
--light-color: #CFD8DC;
|
||||||
|
--danger-color: #dc3545;
|
||||||
|
--success-color: #28a745;
|
||||||
|
--highlight-color: #dcc894;
|
||||||
|
--highlight-color2: #dca394;
|
||||||
|
|
||||||
|
--navbar-height: 4rem;
|
||||||
|
}
|
||||||
|
// import MUI SASS
|
||||||
|
@import "./node_modules/muicss/lib/sass/mui";
|
||||||
|
@import "./viewport";
|
||||||
|
@import "./horscroll";
|
||||||
|
@import "./spinner";
|
||||||
|
////
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: mui-color('grey', '100');
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 2;
|
||||||
|
transition: left 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: inline;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dates {
|
||||||
|
padding: 2px;
|
||||||
|
border: solid 1px #80007e;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btc, #fx, #trend {
|
||||||
|
font-size: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.up, .ontime, .trendUp {
|
||||||
|
color: mui-color('green') !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.down, .delayed, .trendDown {
|
||||||
|
color: $mui-text-danger !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nochange {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password {
|
||||||
|
border: 1px solid mui-color('grey', '400');
|
||||||
|
background-color: mui-color('grey', '200');
|
||||||
|
font-family: monospace;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trendUp:before {
|
||||||
|
content: "▲";
|
||||||
|
}
|
||||||
|
|
||||||
|
.trendDown:before {
|
||||||
|
content: '▼'
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
min-height: 48px;
|
||||||
|
margin: 8px;
|
||||||
|
border-bottom-color: #666666;
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemRow {
|
||||||
|
background-color: #fff;
|
||||||
|
min-height: 48px;
|
||||||
|
border-bottom-color: mui-color('grey', '200');
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
line-height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardTitle {
|
||||||
|
border-bottom-color: mui-color('grey', '200');
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
height: 36px;
|
||||||
|
margin: 6px 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
}
|
||||||
|
|
||||||
|
.titleBar {
|
||||||
|
font-family: 'Gotham Light';
|
||||||
|
font-size: 125%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#trains, #trainResults {
|
||||||
|
overflow-y: auto;
|
||||||
|
transition: all 0.5s;
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableBody {
|
||||||
|
transition: all 0.5s;
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.unsliced {
|
||||||
|
height: 455px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sliced {
|
||||||
|
height: 300px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The snackbar - position it at the bottom and in the middle of the screen */
|
||||||
|
#snackbar {
|
||||||
|
visibility: hidden; /* Hidden by default. Visible on click */
|
||||||
|
min-width: 250px; /* Set a default minimum width */
|
||||||
|
margin-left: -125px; /* Divide value of min-width by 2 */
|
||||||
|
background-color: #333; /* Black background color */
|
||||||
|
color: #fff; /* White text color */
|
||||||
|
text-align: center; /* Centered text */
|
||||||
|
border-radius: 2px; /* Rounded borders */
|
||||||
|
padding: 16px; /* Padding */
|
||||||
|
position: fixed; /* Sit on top of the screen */
|
||||||
|
z-index: 1; /* Add a z-index if needed */
|
||||||
|
left: 50%; /* Center the snackbar */
|
||||||
|
bottom: 30px; /* 30px from the bottom */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show the snackbar when clicking on a button (class added with JavaScript) */
|
||||||
|
#snackbar.show {
|
||||||
|
visibility: visible; /* Show the snackbar */
|
||||||
|
|
||||||
|
/* Add animation: Take 0.5 seconds to fade in and out the snackbar.
|
||||||
|
However, delay the fade out process for 2.5 seconds */
|
||||||
|
/* -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
|
||||||
|
animation: fadein 0.5s, fadeout 0.5s 2.5s;*/
|
||||||
|
|
||||||
|
-webkit-animation: fadein 0.5s;
|
||||||
|
animation: fadein 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animations to fade the snackbar in and out */
|
||||||
|
@-webkit-keyframes fadein {
|
||||||
|
from {
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
bottom: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadein {
|
||||||
|
from {
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
bottom: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadeout {
|
||||||
|
from {
|
||||||
|
bottom: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeout {
|
||||||
|
from {
|
||||||
|
bottom: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp0, .temp1, .temp2, .temp3, .temp4, .temp5 {
|
||||||
|
color: rgb(80, 181, 221)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp6 {
|
||||||
|
color: rgb(78, 178, 206)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp7 {
|
||||||
|
color: rgb(76, 176, 190)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp8 {
|
||||||
|
color: rgb(73, 173, 175)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp9 {
|
||||||
|
color: rgb(72, 171, 159)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp10 {
|
||||||
|
color: rgb(70, 168, 142)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp11 {
|
||||||
|
color: rgb(68, 166, 125)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp12 {
|
||||||
|
color: rgb(66, 164, 108)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp13 {
|
||||||
|
color: rgb(102, 173, 94)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp14 {
|
||||||
|
color: rgb(135, 190, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp15 {
|
||||||
|
color: rgb(179, 204, 26)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp16 {
|
||||||
|
color: rgb(214, 213, 28)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp17 {
|
||||||
|
color: rgb(249, 202, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp18 {
|
||||||
|
color: rgb(246, 181, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp19 {
|
||||||
|
color: rgb(244, 150, 26)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp20 {
|
||||||
|
color: rgb(236, 110, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp21 {
|
||||||
|
color: #ea5a24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp22 {
|
||||||
|
color: #e4572b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp23 {
|
||||||
|
color: #e14a29;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp24 {
|
||||||
|
color: #e04127;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp25 {
|
||||||
|
color: #d9372b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp26 {
|
||||||
|
color: #d63129;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp27 {
|
||||||
|
color: #d12b2b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp28 {
|
||||||
|
color: #cd282f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp29 {
|
||||||
|
color: #c82432;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp30 {
|
||||||
|
color: #c32334;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp31 {
|
||||||
|
color: #be2138;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp32, .temp33, .temp34, .temp35 {
|
||||||
|
color: #b9203b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.day {
|
||||||
|
font-family: "Roboto Slab", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary::first-letter {
|
||||||
|
text-transform: capitalize
|
||||||
|
}
|
||||||
|
|
||||||
|
#weather{
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: all 0.5s;
|
||||||
|
-webkit-transition: all 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#newsShell {
|
||||||
|
/* height:225px;*/
|
||||||
|
}
|
||||||
|
#news{
|
||||||
|
height: 200px;
|
||||||
|
margin-top:15px;
|
||||||
|
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#byme, #bymeYelp {
|
||||||
|
margin-top:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bymeYelp img {
|
||||||
|
max-height: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stop-scrolling {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 5000;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: mui-color('grey','300');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fillpanel {
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
background-color: mui-color('amber', '50');
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen .header {
|
||||||
|
/*position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: +1;
|
||||||
|
transition: left 0.2s;*/
|
||||||
|
|
||||||
|
position:sticky;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
height:100%;
|
||||||
|
// overflow:auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box .headerSpacer {
|
||||||
|
flex: 0 1 66px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box .content {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
background-color: mui-color('white');
|
||||||
|
overflow: auto;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsarticle img {
|
||||||
|
max-height:100%;
|
||||||
|
max-width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newsarticle h1, .newsarticle h3, .newsarticle h3, .newsarticle h4 {
|
||||||
|
font-family: "Roboto Condensed", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiny {
|
||||||
|
font-size:1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small {
|
||||||
|
font-size:2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medium {
|
||||||
|
font-size:4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large {
|
||||||
|
font-size:6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardLink {
|
||||||
|
color: mui-color('blue', '500');
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.endbumper {
|
||||||
|
height:66px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seemore {
|
||||||
|
font-size:14px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
#connectionStatus {
|
||||||
|
margin-top:15px;
|
||||||
|
margin-bottom:15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trafficHeavy {
|
||||||
|
color: #fa4a50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trafficLight {
|
||||||
|
color: #fdbd15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trafficMedium {
|
||||||
|
color: #fba010;
|
||||||
|
}
|
||||||
|
|
||||||
|
#map { height: 180px; }
|
||||||
|
|
||||||
|
#bymeImages {
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separate {
|
||||||
|
border-bottom: 1px solid mui-color('grey', '200');
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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: var(--navbar-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.navbar ul {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar a {
|
||||||
|
color: #fff;
|
||||||
|
padding: 0.45rem;
|
||||||
|
margin: 0 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar a:hover {
|
||||||
|
color: var(--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: 125%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
header + div.container {
|
||||||
|
position: relative;
|
||||||
|
top:var(--navbar-height);
|
||||||
|
min-height: calc(100vh - var(--navbar-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@import "./src/css/weather";
|
896
src/css/global.scss
Normal file
@ -0,0 +1,896 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css?family=Roboto+Condensed');
|
||||||
|
|
||||||
|
/* Global Styles */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--primary-color: #ffeb3b;
|
||||||
|
--dark-color: #fbc02d;
|
||||||
|
--light-color: #fff9ca;
|
||||||
|
--danger-color: #dc3545;
|
||||||
|
--success-color: #28a745;
|
||||||
|
--highlight-color: #311b92;
|
||||||
|
--highlight-color2: #8c9eff;
|
||||||
|
|
||||||
|
--navbar-height: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Roboto Condensed', sans-serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.active{
|
||||||
|
color: var(--highlight-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataRow {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utilities */
|
||||||
|
.container {
|
||||||
|
max-width: 1100px;
|
||||||
|
margin: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text Styles*/
|
||||||
|
.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-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-primary {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-dark {
|
||||||
|
color: var(--dark-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-success {
|
||||||
|
color: var(--success-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: var(--danger-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-highlight {
|
||||||
|
color: var(--highlight-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-highlight2 {
|
||||||
|
color: var(--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-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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Center All */
|
||||||
|
.all-center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
margin: auto;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cards */
|
||||||
|
.card {
|
||||||
|
padding: 1rem;
|
||||||
|
border: #ccc 1px dotted;
|
||||||
|
margin: 0.7rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List */
|
||||||
|
.list {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list li {
|
||||||
|
padding-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Padding */
|
||||||
|
.p {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
.p-1 {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
.p-2 {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
.p-3 {
|
||||||
|
padding: 3rem;
|
||||||
|
}
|
||||||
|
.py {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
.py-1 {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
.py-2 {
|
||||||
|
padding: 2rem 0;
|
||||||
|
}
|
||||||
|
.py-3 {
|
||||||
|
padding: 3rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Margin */
|
||||||
|
.m {
|
||||||
|
margin: 0.5rem;
|
||||||
|
}
|
||||||
|
.m-1 {
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-1 {
|
||||||
|
margin-bottom: .2rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-1 {
|
||||||
|
margin-left: .2rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-1 {
|
||||||
|
margin-right: .2rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: .2rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx-1 {
|
||||||
|
margin-left: 1rem !important;
|
||||||
|
margin-right: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-2 {
|
||||||
|
margin: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: .4rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-2 {
|
||||||
|
margin-left: .4rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-2 {
|
||||||
|
margin-right: .4rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-2 {
|
||||||
|
margin-top: .4rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx-2 {
|
||||||
|
margin-left: 2rem !important;
|
||||||
|
margin-right: 2rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-3 {
|
||||||
|
margin: 3rem;
|
||||||
|
}
|
||||||
|
.my {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
.my-1 {
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
.my-2 {
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
.my-3 {
|
||||||
|
margin: 3rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-left: -.4rem;
|
||||||
|
margin-right: -.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grid */
|
||||||
|
.grid-1 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(1, 1fr);
|
||||||
|
grid-gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-2 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-3 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-4 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
grid-gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.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: 30.6666666667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
background: var(--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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.6rem;
|
||||||
|
padding: 0.1rem 0.4rem;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0.3rem;
|
||||||
|
background: var(--light-color);
|
||||||
|
color: #333;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
padding: 0.7rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
opacity: 0.9;
|
||||||
|
background: var(--light-color);
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary,
|
||||||
|
.bg-primary,
|
||||||
|
.badge-primary,
|
||||||
|
.alert-primary {
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.btn-light,
|
||||||
|
.bg-light,
|
||||||
|
.badge-light,
|
||||||
|
.alert-light {
|
||||||
|
background: var(--light-color);
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-dark,
|
||||||
|
.bg-dark,
|
||||||
|
.badge-dark,
|
||||||
|
.alert-dark {
|
||||||
|
background: var(--dark-color);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger,
|
||||||
|
.bg-danger,
|
||||||
|
.badge-danger,
|
||||||
|
.alert-danger {
|
||||||
|
background: var(--danger-color);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-success,
|
||||||
|
.bg-success,
|
||||||
|
.badge-success,
|
||||||
|
.alert-success {
|
||||||
|
background: var(--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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.round-img {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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: var(--navbar-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.navbar ul {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar a {
|
||||||
|
color: #fff;
|
||||||
|
padding: 0.45rem;
|
||||||
|
margin: 0 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar a:hover {
|
||||||
|
color: var(--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: 125%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Mobile Styles */
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.hide-sm {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-2,
|
||||||
|
.grid-3,
|
||||||
|
.grid-4 {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text Styles */
|
||||||
|
.x-large {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lead {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navbar */
|
||||||
|
.navbar {
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar ul {
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*:root {
|
||||||
|
--primary-color: #64B5F6;
|
||||||
|
--dark-color: #333333;
|
||||||
|
--light-color: #f4f4f4;
|
||||||
|
--danger-color: #dc3545;
|
||||||
|
--success-color: #28a745;
|
||||||
|
--medium-color: #999999;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
.table-responsive {
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin-top: 2.2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
border-width: 0;
|
||||||
|
border-top: 1px solid var(--dark-color); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
header + div.container {
|
||||||
|
position: relative;
|
||||||
|
top:var(--navbar-height);
|
||||||
|
min-height: calc(100vh - var(--navbar-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MUI Dropdown module
|
||||||
|
*/
|
||||||
|
.mui-dropdown {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-mui-toggle="dropdown"] {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown__menu {
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
min-width: 160px;
|
||||||
|
padding: 5px 3px;
|
||||||
|
margin: 2px 0 0;
|
||||||
|
list-style: none;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: left;
|
||||||
|
background-color: #FFF;
|
||||||
|
border-radius: 2px;
|
||||||
|
z-index: 1;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 1px solid var(--light-color);
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2),
|
||||||
|
0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
|
||||||
|
.mui-dropdown__menu {
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
border-left: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (-ms-ime-align: auto) {
|
||||||
|
.mui-dropdown__menu {
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
border-left: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown__menu.mui--is-open {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown__menu > li > a {
|
||||||
|
display: block;
|
||||||
|
padding: 3px 20px;
|
||||||
|
clear: both;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1.429;
|
||||||
|
color: rgba(0, 0, 0, 0.87);
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown__menu > li > a:hover, .mui-dropdown__menu > li > a:focus {
|
||||||
|
text-decoration: none;
|
||||||
|
color: rgba(0, 0, 0, 0.87);
|
||||||
|
background-color: #EEEEEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown__menu > .mui--is-disabled > a, .mui-dropdown__menu > .mui--is-disabled > a:hover, .mui-dropdown__menu > .mui--is-disabled > a:focus {
|
||||||
|
color: #EEEEEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown__menu > .mui--is-disabled > a:hover, .mui-dropdown__menu > .mui--is-disabled > a:focus {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: none;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown__menu--right {
|
||||||
|
left: auto;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown--up > .mui-dropdown__menu {
|
||||||
|
margin: 0 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown--right > .mui-dropdown__menu {
|
||||||
|
margin: 0 0 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mui-dropdown--left > .mui-dropdown__menu {
|
||||||
|
margin: 0 2px 0 0;
|
||||||
|
}
|
53
src/css/horscroll.scss
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
.scrolling-wrapper-flexbox {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
.scrollCard, .scrollCardHalf, .imageCard, .hourlyCard {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-right: 11px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollCard, .scrollCardHalf, .hourlyCard {
|
||||||
|
width: 250px;
|
||||||
|
height: 175px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 5px;
|
||||||
|
box-shadow: 0 2px 2px 0 rgba(0,0,0,0.05), 0 2px 1px -2px rgba(0,0,0,0.05), 0 1px 5px 0 rgba(0,0,0,0.05)
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollCardHalf {
|
||||||
|
height: 85px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hourlyCard {
|
||||||
|
width: 42px;
|
||||||
|
height:70px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageCard {
|
||||||
|
// width: 250px;
|
||||||
|
height: 175px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
|
||||||
|
}
|
||||||
|
.imageCard img {
|
||||||
|
max-height:100%;
|
||||||
|
max-width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrolling-wrapper, .scrolling-wrapper-flexbox {
|
||||||
|
height: 75px;
|
||||||
|
width: 100%;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
93
src/css/spinner.scss
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
$green: #008744;
|
||||||
|
$blue: #0fa3ef;
|
||||||
|
$red: #dc4f43;
|
||||||
|
$yellow: #ffbe39;
|
||||||
|
$white: #eee;
|
||||||
|
$black: #301010;
|
||||||
|
|
||||||
|
// scaling... any units
|
||||||
|
$width: 100px;
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: $white;
|
||||||
|
}
|
||||||
|
|
||||||
|
// demo-specific
|
||||||
|
.showbox {
|
||||||
|
position: absolute;
|
||||||
|
top: 40vh;
|
||||||
|
bottom: 60vh;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 5%;
|
||||||
|
}
|
||||||
|
// end demo-specific
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
position: relative;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: $width;
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
padding-top: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.circular {
|
||||||
|
animation: rotate 2s linear infinite;
|
||||||
|
height: 100%;
|
||||||
|
transform-origin: center center;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path {
|
||||||
|
stroke-dasharray: 1, 200;
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite;
|
||||||
|
stroke-linecap: round;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotate {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dash {
|
||||||
|
0% {
|
||||||
|
stroke-dasharray: 1, 200;
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
stroke-dasharray: 89, 200;
|
||||||
|
stroke-dashoffset: -35px;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-dasharray: 89, 200;
|
||||||
|
stroke-dashoffset: -124px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes color {
|
||||||
|
100%,
|
||||||
|
0% {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
stroke: $yellow;
|
||||||
|
}
|
||||||
|
66% {
|
||||||
|
stroke: $blue;
|
||||||
|
}
|
||||||
|
80%,
|
||||||
|
90% {
|
||||||
|
stroke: $black;
|
||||||
|
}
|
||||||
|
}
|
81
src/css/viewport.scss
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
.viewport {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encapsulate the various syntax in helper clases */
|
||||||
|
/* inspired by http://infrequently.org/2009/08/css-3-progress/ */
|
||||||
|
|
||||||
|
/* items flex/expand vertically */
|
||||||
|
.vbox {
|
||||||
|
/* previous syntax */
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: box;
|
||||||
|
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
-ms-box-orient: vertical;
|
||||||
|
box-orient: vertical;
|
||||||
|
|
||||||
|
/* current syntax */
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -moz-flex;
|
||||||
|
display: -ms-flex;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
-webkit-flex-direction: column;
|
||||||
|
-moz-flex-direction: column;
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gradient {
|
||||||
|
/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ebf1f6+0,abd3ee+50,89c3eb+51,d5ebfb+100;Blue+Gloss+%234 */
|
||||||
|
background: #ebf1f6; /* Old browsers */
|
||||||
|
background: -moz-linear-gradient(top, #ebf1f6 0%, #abd3ee 50%, #89c3eb 51%, #d5ebfb 100%); /* FF3.6-15 */
|
||||||
|
background: -webkit-linear-gradient(top, #ebf1f6 0%, #abd3ee 50%, #89c3eb 51%, #d5ebfb 100%); /* Chrome10-25,Safari5.1-6 */
|
||||||
|
background: linear-gradient(to bottom, #ebf1f6 0%, #abd3ee 50%, #89c3eb 51%, #d5ebfb 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebf1f6', endColorstr='#d5ebfb', GradientType=0); /* IE6-9 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.backgroundImage {
|
||||||
|
background-image: url(http://via.placeholder.com/411x823);
|
||||||
|
}
|
||||||
|
|
||||||
|
.appPanel {
|
||||||
|
/* previous syntax */
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
-ms-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
|
||||||
|
/* current syntax */
|
||||||
|
-webkit-flex: 1;
|
||||||
|
-moz-flex: 1;
|
||||||
|
-ms-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
|
||||||
|
overflow-y: auto;
|
||||||
|
/* background-color: white;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-id~="main"] {
|
||||||
|
z-index: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-id~="news"] {
|
||||||
|
z-index: 1000;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
}
|
89
src/css/weather.scss
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
|
||||||
|
#weatherP {
|
||||||
|
background-size: cover;
|
||||||
|
color:white;
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hourly {
|
||||||
|
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weatherDay {
|
||||||
|
background-image: url(../gfx/bg_morning.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.weatherEvening {
|
||||||
|
background-image: url(../gfx/bg_evening.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cloudy_n {
|
||||||
|
background-image: url(../gfx/cloudy_n.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cloudy_d {
|
||||||
|
background-image: url(../gfx/cloudy_d.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear_d {
|
||||||
|
background-image: url(../gfx/clear_d.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear_n {
|
||||||
|
background-image: url(../gfx/clear_n.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.foggy_d {
|
||||||
|
background-image: url(../gfx/foggy_d.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.foggy_n {
|
||||||
|
background-image: url(../gfx/foggy_n.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rain_d {
|
||||||
|
background-image: url(../gfx/rain_d.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rain_n {
|
||||||
|
background-image: url(../gfx/rain_n.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.snow_d {
|
||||||
|
background-image: url(../gfx/snow_d.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.snow_n {
|
||||||
|
background-image: url(../gfx/snow_n.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.storm_d {
|
||||||
|
background-image: url(../gfx/storm_d.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.storm_n {
|
||||||
|
background-image: url(../gfx/storm_n.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.glassy {
|
||||||
|
background-color: rgba(31, 28, 23, 0.6);
|
||||||
|
-webkit-backdrop-filter: blur(5px);
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.animTrans {
|
||||||
|
-webkit-transition: all 1s linear;
|
||||||
|
transition : all 1s linear;
|
||||||
|
-moz-transition : all 1s linear;
|
||||||
|
-webkit-transition: all 1s linear;
|
||||||
|
-o-transition : all 1s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.normalWeight {
|
||||||
|
|
||||||
|
font-weight:400;
|
||||||
|
}
|
181
src/lib/location.js
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/**
|
||||||
|
* Created by WebStorm.
|
||||||
|
* User: martin
|
||||||
|
* Date: 13/04/2020
|
||||||
|
* Time: 11:40
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { state } from '../store/globalState';
|
||||||
|
import { distance, throttle } from './utils';
|
||||||
|
import axios from 'redaxios';
|
||||||
|
import TimeFormat from 'hh-mm-ss';
|
||||||
|
const ms = require('ms');
|
||||||
|
|
||||||
|
const prefix = '📍';
|
||||||
|
|
||||||
|
const __url = (ENV === 'production') ? 'https://jubilee.silvrtree.co.uk' : 'http://localhost:8110/';
|
||||||
|
|
||||||
|
class Location {
|
||||||
|
constructor() {
|
||||||
|
this.current = {};
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
'enableHighAccuracy': true,
|
||||||
|
'timeout': 10000,
|
||||||
|
'maximumAge': 0
|
||||||
|
};
|
||||||
|
|
||||||
|
state.location.subscribe(async (v) => {
|
||||||
|
this.current = v;
|
||||||
|
console.log(`${prefix} reset current`, this.current);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.throttledUpdateLocation = throttle(this.updateLocation.bind(this), 120000);
|
||||||
|
|
||||||
|
const id = navigator.geolocation.watchPosition(this.success.bind(this), this.error, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateLocation(position) {
|
||||||
|
const latitude = Number.parseFloat(position.coords.latitude).toFixed(6);
|
||||||
|
const longitude = Number.parseFloat(position.coords.longitude).toFixed(6);
|
||||||
|
|
||||||
|
const location = { 'latitude': latitude, 'longitude': longitude, 'timestamp': position.timestamp };
|
||||||
|
console.log(`${prefix} *** Updating Loc`, location);
|
||||||
|
await this.processPosition(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getGeoCode(ll) {
|
||||||
|
const reqUrl = new URL('/geocode', __url);
|
||||||
|
reqUrl.searchParams.append('ll', ll);
|
||||||
|
|
||||||
|
const res = await fetch(reqUrl.href).catch((err) => {
|
||||||
|
console.error(prefix, err);
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
async processPosition(pos) {
|
||||||
|
console.log(`${prefix} processPosition`);
|
||||||
|
const { latitude, longitude, timestamp } = pos;
|
||||||
|
|
||||||
|
// const current = this.get('location');
|
||||||
|
|
||||||
|
console.log(`${prefix} ># current`, this.current);
|
||||||
|
|
||||||
|
const myCoords = {
|
||||||
|
'home': {
|
||||||
|
'lat': 55.942, 'long': -4.556
|
||||||
|
},
|
||||||
|
'work': {
|
||||||
|
'lat': 55.942, 'long': -4.556
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const homeDistance = distance(myCoords.home.lat, myCoords.home.long, latitude, longitude);
|
||||||
|
const workDistance = distance(myCoords.work.lat, myCoords.work.long, latitude, longitude);
|
||||||
|
const atHome = (homeDistance < 0.10);
|
||||||
|
const atWork = (workDistance < 0.10);
|
||||||
|
const atHomeOrWork = (atHome || atWork);
|
||||||
|
const latlong = { 'lat': latitude, 'lon': longitude };
|
||||||
|
|
||||||
|
const ll = `${latitude},${longitude}`;
|
||||||
|
const llFixed = `${Number.parseFloat(latitude).toFixed(3)},${Number.parseFloat(longitude).toFixed(3)}`;
|
||||||
|
const llSix = `${Number.parseFloat(latitude).toFixed(6)},${Number.parseFloat(longitude).toFixed(6)}`;
|
||||||
|
const llShort = `${Number.parseFloat(latitude).toFixed(1)},${Number.parseFloat(longitude).toFixed(1)}`;
|
||||||
|
const slug = { 'lat': Number.parseFloat(latitude).toFixed(6), 'lon': Number.parseFloat(longitude).toFixed(6), timestamp };
|
||||||
|
const moving = true;
|
||||||
|
|
||||||
|
const newLocation = {
|
||||||
|
homeDistance,
|
||||||
|
workDistance,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
atHome,
|
||||||
|
atWork,
|
||||||
|
atHomeOrWork,
|
||||||
|
timestamp,
|
||||||
|
ll,
|
||||||
|
llFixed,
|
||||||
|
llSix,
|
||||||
|
llShort,
|
||||||
|
moving,
|
||||||
|
latlong,
|
||||||
|
'city': '',
|
||||||
|
'cityCC': '',
|
||||||
|
slug
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`${prefix} >> newLocation`, newLocation);
|
||||||
|
|
||||||
|
if (!this.current.hasOwnProperty('atHomeOrWork')) {
|
||||||
|
await this.getGeoCode(ll).then((body) => {
|
||||||
|
const __city = body.neighborhood || body.village || body.suburb || body.city || body.county;
|
||||||
|
newLocation.city = __city;
|
||||||
|
newLocation.cityCC = `${__city},${body.countryCode}`;
|
||||||
|
newLocation.address = body.formatted;
|
||||||
|
newLocation.lastGeocode = { 'lat': latitude, 'lng': longitude, 'timestamp': timestamp };
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(prefix, err);
|
||||||
|
});
|
||||||
|
|
||||||
|
state.location.set(newLocation);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newLocation.city = this.current.city;
|
||||||
|
const currentTime = new Date().getTime();
|
||||||
|
const distanceFromLast = distance(this.current.latitude, this.current.longitude, latitude, longitude);
|
||||||
|
const lastGeocode = this.current.lastGeocode;
|
||||||
|
const distanceFromLastGeocode = distance(lastGeocode.lat, lastGeocode.lng, latitude, longitude);
|
||||||
|
|
||||||
|
const currentSince = currentTime - this.current.timestamp;
|
||||||
|
const sinceLastGeocode = currentTime - lastGeocode.timestamp;
|
||||||
|
|
||||||
|
console.log(`${prefix} >> distance from last record`, distanceFromLast, TimeFormat.fromMs(currentSince, 'hh:mm:ss'));
|
||||||
|
// console.log('>> distanceFromLastGeocode', distanceFromLastGeocode, TimeFormat.fromMs(timestamp - lastGeocode.timestamp, 'hh:mm:ss'));
|
||||||
|
console.log(`${prefix} >> distanceFromLastGeocode`, distanceFromLastGeocode, TimeFormat.fromMs(sinceLastGeocode, 'hh:mm:ss'));
|
||||||
|
if (((distanceFromLast > 0.80 && distanceFromLast < 2.0) && (currentSince > ms('2m'))) || ((currentSince > ms('90s')) && (sinceLastGeocode < ms('30m')))) {
|
||||||
|
// dont bother re geocoding
|
||||||
|
console.log(`${prefix} Slightly moved from previous`);
|
||||||
|
// this.set('location', newLocation);
|
||||||
|
// this.set('moving', moving);
|
||||||
|
state.location.set(newLocation);
|
||||||
|
}
|
||||||
|
else if (((distanceFromLastGeocode >= 2.0) && (sinceLastGeocode > ('2m'))) || (sinceLastGeocode >= ms('30m'))) {
|
||||||
|
console.log(`${prefix} >> Moved from previous`, sinceLastGeocode, (sinceLastGeocode >= ms('30m')));
|
||||||
|
console.info(`${prefix} >> Location:geocoder request`);
|
||||||
|
|
||||||
|
await this.getGeoCode(ll).then((body) => {
|
||||||
|
const __city = body.neighborhood || body.village || body.suburb || body.city || body.county;
|
||||||
|
newLocation.city = __city;
|
||||||
|
newLocation.cityCC = `${__city},${body.countryCode}`;
|
||||||
|
newLocation.address = body.formatted;
|
||||||
|
newLocation.lastGeocode = { 'lat': latitude, 'lng': longitude, 'timestamp': timestamp };
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(prefix, err);
|
||||||
|
});
|
||||||
|
|
||||||
|
state.location.set(newLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('+++END+++');
|
||||||
|
}
|
||||||
|
|
||||||
|
success(pos) {
|
||||||
|
console.log(`${prefix} Location updated`);
|
||||||
|
this.throttledUpdateLocation(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
error(err) {
|
||||||
|
console.error(prefix, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const location = new Location();
|
||||||
|
|
||||||
|
export { location };
|
||||||
|
|
129
src/lib/reducers.js
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import fecha from 'fecha';
|
||||||
|
|
||||||
|
function reduceDarksky(item, city) {
|
||||||
|
// Openweather returns timestamps in seconds. Moment requires them in milliseconds.
|
||||||
|
// Replaced Moment with Fecha.
|
||||||
|
// Too many issues trying to get Moment packaged into the bundle.
|
||||||
|
|
||||||
|
if (!item || item === null) return {};
|
||||||
|
const currently = item.currently;
|
||||||
|
const alerts = item.alerts || [];
|
||||||
|
const fts = new Date(currently.time * 1000);
|
||||||
|
|
||||||
|
const newItem = { 'timestamp': fts,
|
||||||
|
'icon': `wi-wu-${currently.icon}`,
|
||||||
|
'summary': currently.summary,
|
||||||
|
'temp': parseInt(currently.temperature, 10),
|
||||||
|
'feels': parseFloat(currently.apparentTemperature, 10),
|
||||||
|
'datelong': fecha.format(fts, 'YYYY-MM-DDTHH:mm:ss.SSSZZ'),
|
||||||
|
'readdate': fecha.format(fts, 'default'),
|
||||||
|
'time': fts,
|
||||||
|
'date': fecha.format(fts, 'D/M'),
|
||||||
|
'day': fecha.format(fts, 'ddd'),
|
||||||
|
'city': city
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
'item' : newItem,
|
||||||
|
'alerts': (alerts.length === 0) ? alerts : alerts.slice(0, 1)
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function reduceOpenWeather(item, city) {
|
||||||
|
// Openweather returns timestamps in seconds. Moment requires them in milliseconds.
|
||||||
|
// Replaced Moment with Fecha.
|
||||||
|
// Too many issues trying to get Moment packaged into the bundle.
|
||||||
|
|
||||||
|
if (!item || item === null) return {};
|
||||||
|
const fts = new Date(item.dt * 1000);
|
||||||
|
const weatherBlock = item.weather[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
'timestamp': item.dt,
|
||||||
|
'icon': `wi-owm-${weatherBlock.id}`,
|
||||||
|
'summary': weatherBlock.description,
|
||||||
|
'temp': parseInt(item.main.temp, 10),
|
||||||
|
'tempHigh': parseFloat(item.main.temp_max, 10),
|
||||||
|
'tempLow': parseFloat(item.main.temp_min, 10),
|
||||||
|
'datelong': fecha.format(fts, 'YYYY-MM-DDTHH:mm:ss.SSSZZ'),
|
||||||
|
'readdate': fecha.format(fts, 'default'),
|
||||||
|
'time': item.dt,
|
||||||
|
'date': fecha.format(fts, 'D/M'),
|
||||||
|
'day': fecha.format(fts, 'ddd'),
|
||||||
|
'city': city
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function reduceOpenWeather5DayForecast(item, city) {
|
||||||
|
// Openweather returns timestamps in seconds. Moment requires them in milliseconds.
|
||||||
|
// Replaced Moment with Fecha.
|
||||||
|
// Too many issues trying to get Moment packaged into the bundle.
|
||||||
|
|
||||||
|
if (!item || item === null) return {};
|
||||||
|
const fts = new Date(item.dt * 1000);
|
||||||
|
const weatherBlock = item.weather[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
'timestamp': item.dt,
|
||||||
|
'icon': `wi-owm-${weatherBlock.id}`,
|
||||||
|
'summary': weatherBlock.description,
|
||||||
|
'tempHigh': parseInt(item.temp.max, 10),
|
||||||
|
'tempLow': parseInt(item.temp.min, 10),
|
||||||
|
'datelong': fecha.format(fts, 'YYYY-MM-DDTHH:mm:ss.SSSZZ'),
|
||||||
|
'time': item.dt,
|
||||||
|
'date': fecha.format(fts, 'D/M'),
|
||||||
|
'day': fecha.format(fts, 'ddd'),
|
||||||
|
'city': city
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const reduceNearby = function(item) {
|
||||||
|
/*
|
||||||
|
const obj = {};
|
||||||
|
const categories = get(item, 'venue.categories');
|
||||||
|
obj.id = get(item, 'venue.id', '');
|
||||||
|
obj.name = get(item, 'venue.name', '');
|
||||||
|
obj.category = get(categories[0], 'name', '');
|
||||||
|
obj.icon = `${get(categories[0], 'icon.prefix', '')}32${get(categories[0], 'icon.suffix', '')}`;
|
||||||
|
|
||||||
|
obj.distance = (get(item, 'venue.location.distance', 0) / 1000).toFixed(2);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
const reduceEuronews = function(item) {
|
||||||
|
const obj = {};
|
||||||
|
|
||||||
|
const pubdateSrc = fecha.parse(item.pubdate, 'ddd, DD MMM YYYY HH:mm:SS ZZ');
|
||||||
|
obj.pubdate = fecha.format(pubdateSrc, 'dddd MMMM Do, YYYY HH:mm');
|
||||||
|
obj.description = item.description.replace(/(<script(\s|\S)*?<\/script>)|(<style(\s|\S)*?<\/style>)|(<!--(\s|\S)*?-->)|(<\/?(\s|\S)*?>)/g, '');
|
||||||
|
|
||||||
|
if (obj.description === '1')
|
||||||
|
obj.description = '';
|
||||||
|
|
||||||
|
obj.guid = encodeURI(item.guid.text);
|
||||||
|
obj.title = item.title;
|
||||||
|
|
||||||
|
console.log(obj);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
const pubdateSrc = fecha.parse(item.pubdate, 'ddd, DD MMM YYYY HH:mm:SS ZZ');
|
||||||
|
const pubdate = fecha.format(pubdateSrc, 'dddd MMMM Do, YYYY');
|
||||||
|
const description = item.description.replace(/(<script(\s|\S)*?<\/script>)|(<style(\s|\S)*?<\/style>)|(<!--(\s|\S)*?-->)|(<\/?(\s|\S)*?>)/g, '');
|
||||||
|
this.data = `<article>
|
||||||
|
<header>
|
||||||
|
<a href="${item.guid.text}">${item.title}</a>
|
||||||
|
<time class="published">${pubdate}</time>
|
||||||
|
</header>
|
||||||
|
<p class="description">${description}</p>
|
||||||
|
</article>`;
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = { reduceOpenWeather, reduceNearby, reduceEuronews, reduceDarksky };
|
162
src/lib/utils.js
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
function partOfDay(timeString, today) {
|
||||||
|
console.log(new Date());
|
||||||
|
if (timeString === undefined || timeString === null)
|
||||||
|
timeString = (new Date()).getHours().toString();
|
||||||
|
|
||||||
|
if (today === undefined)
|
||||||
|
today = false;
|
||||||
|
|
||||||
|
const hours = timeString.substring(0, 2);
|
||||||
|
let dayBit = '';
|
||||||
|
|
||||||
|
console.log('Hours', hours);
|
||||||
|
|
||||||
|
if (hours >= 0 && hours < 4)
|
||||||
|
dayBit = 'Late Night';
|
||||||
|
|
||||||
|
else if (hours >= 4 && hours < 7)
|
||||||
|
dayBit = 'Early Morning';
|
||||||
|
|
||||||
|
else if (hours >= 7 && hours < 12)
|
||||||
|
dayBit = 'Morning';
|
||||||
|
|
||||||
|
else if (hours >= 12 && hours < 17)
|
||||||
|
dayBit = 'Afternoon';
|
||||||
|
|
||||||
|
else if (hours < 21)
|
||||||
|
dayBit = 'Evening';
|
||||||
|
|
||||||
|
else
|
||||||
|
dayBit = 'Night';
|
||||||
|
|
||||||
|
if (today)
|
||||||
|
if (dayBit === 'night') {
|
||||||
|
dayBit = 'tonight';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dayBit = `this ${ dayBit}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('partOfDay', dayBit);
|
||||||
|
|
||||||
|
return dayBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toHour(extra = 0) {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
return (3600000 - (now.getTime() % 3600000)) + extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hourFloor() {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
return parseInt(~~(now.getTime() / 3600000) * 3600000, 10).toString(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
function distance(lat1, lon1, lat2, lon2) {
|
||||||
|
const p = 0.017453292519943295; // Math.PI / 180
|
||||||
|
const c = Math.cos;
|
||||||
|
const a = 0.5 - c((lat2 - lat1) * p) / 2 +
|
||||||
|
c(lat1 * p) * c(lat2 * p) *
|
||||||
|
(1 - c((lon2 - lon1) * p)) / 2;
|
||||||
|
|
||||||
|
return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitURL(url) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const maybePluralize = (count, noun, suffix = 's') =>
|
||||||
|
`${count} ${noun}${count !== 1 ? suffix : ''}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fn
|
||||||
|
* @param time
|
||||||
|
* @returns {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function debounce(fn, time) {
|
||||||
|
let timeout;
|
||||||
|
|
||||||
|
return function (...args) { // <-- not an arrow function
|
||||||
|
const functionCall = () => fn.apply(this, args);
|
||||||
|
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(functionCall, time);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param callback
|
||||||
|
* @param limit
|
||||||
|
* @returns {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function throttle (callback, limit) {
|
||||||
|
var wait = false;
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
if (!wait) {
|
||||||
|
callback.apply(null, arguments);
|
||||||
|
wait = true;
|
||||||
|
setTimeout(function () {
|
||||||
|
wait = false;
|
||||||
|
}, limit);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param func
|
||||||
|
* @returns {function(): *}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function once(func) {
|
||||||
|
var alreadyCalled = false;
|
||||||
|
var result;
|
||||||
|
|
||||||
|
return function() {
|
||||||
|
if (!alreadyCalled) {
|
||||||
|
result = func.apply(this, arguments);
|
||||||
|
alreadyCalled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function isEmpty(obj) {
|
||||||
|
for(const key in obj)
|
||||||
|
if(obj.hasOwnProperty(key)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||||
|
|
||||||
|
function hasOwn(obj, prop) {
|
||||||
|
return hasOwnProperty.call(obj, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Logger = class {
|
||||||
|
constructor(prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
log() {
|
||||||
|
const pre = `[DEBUG] ${this.prefix} -`;
|
||||||
|
const _args = [...arguments];
|
||||||
|
_args.unshift(pre);
|
||||||
|
console.log(..._args);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { partOfDay, toHour, hourFloor, distance, maybePluralize, debounce, throttle, once, isEmpty, hasOwn, Logger };
|
||||||
|
|
36
src/main.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import App from './App.svelte';
|
||||||
|
|
||||||
|
import { state } from './store/globalState';
|
||||||
|
import {location} from './lib/location';
|
||||||
|
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
'target': document.body,
|
||||||
|
'props': {
|
||||||
|
'name': 'world'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
//
|
||||||
|
navigator.serviceWorker.ready.then(function(reg) {
|
||||||
|
console.warn('Ready??', reg);
|
||||||
|
// main();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
navigator.serviceWorker
|
||||||
|
.register('./service-worker.js')
|
||||||
|
.then((r) => {
|
||||||
|
console.warn('Service Worker Registered', r.scope);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
// registration failed
|
||||||
|
console.error(`Registration failed with ${ error}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
export default app;
|
23
src/pages/Home.svelte
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script>
|
||||||
|
import Greeter from "../components/Greeter.svelte";
|
||||||
|
import Weather from "../components/Weather.svelte";
|
||||||
|
import LatestNews from "../components/LatestNews.svelte";
|
||||||
|
import NearbyPlaces from "../components/NearbyPlaces.svelte";
|
||||||
|
import AroundMe from "../components/AroundMe.svelte";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="mui-container">
|
||||||
|
<Greeter/>
|
||||||
|
</div>
|
||||||
|
<div class="mui-container" id="viewFrame">
|
||||||
|
|
||||||
|
<AroundMe/>
|
||||||
|
<NearbyPlaces/>
|
||||||
|
<LatestNews/>
|
||||||
|
<Weather/>
|
||||||
|
</div>
|
12
src/pages/NearbyLocationsPage.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>$</span>
|
122
src/pages/NewsItemPage.svelte
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<script>
|
||||||
|
import {onMount, onDestroy} from 'svelte';
|
||||||
|
import {state} from '../store/globalState';
|
||||||
|
import {hasOwn, hourFloor, isEmpty, Logger} from "../lib/utils";
|
||||||
|
import qs from 'qs';
|
||||||
|
import axios from 'redaxios';
|
||||||
|
|
||||||
|
const logger = new Logger('📄️ NewsItemPage');
|
||||||
|
|
||||||
|
let promise;
|
||||||
|
|
||||||
|
export let params = {}
|
||||||
|
let id;
|
||||||
|
let listLoaded = false;
|
||||||
|
let newsItem = {};
|
||||||
|
let newsItemLoaded = false;
|
||||||
|
|
||||||
|
const prefix = '📄️';
|
||||||
|
|
||||||
|
const baseUrl = state.getBaseUrl();
|
||||||
|
let timerID = 0;
|
||||||
|
|
||||||
|
$: {
|
||||||
|
// logger.debug( params);
|
||||||
|
logger.log('NewsItemPage hasOwn(id)', hasOwn(params, 'id'));
|
||||||
|
logger.log('bNewsItemPage hasOwn(id)', hasOwn(params, 'id'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
logger.log('NewsItemPage mounted...');
|
||||||
|
stateCheck();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
clearTimeout(timerID);
|
||||||
|
})
|
||||||
|
|
||||||
|
state.newsList.subscribe((v) => {
|
||||||
|
logger.log(`state.newsList.subscribe empty?`, isEmpty(v));
|
||||||
|
if (!isEmpty(v)) listLoaded = true;
|
||||||
|
})
|
||||||
|
|
||||||
|
function stateCheck() {
|
||||||
|
logger.log(`stateCheck:listloaded?`, listLoaded);
|
||||||
|
if (listLoaded) {
|
||||||
|
clearTimeout(timerID);
|
||||||
|
getPage();
|
||||||
|
} else {
|
||||||
|
logger.log(`nothing yet...`);
|
||||||
|
timerID = setTimeout(() => {
|
||||||
|
stateCheck();
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPage() {
|
||||||
|
let guid;
|
||||||
|
if (hasOwn(params, 'id') && listLoaded) {
|
||||||
|
id = params.id;
|
||||||
|
guid = state.getArticleGuid(id);
|
||||||
|
} else {
|
||||||
|
logger.log('!! nope');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
'guid': guid,
|
||||||
|
'w': hourFloor()
|
||||||
|
};
|
||||||
|
|
||||||
|
const newsItemUrl = `${baseUrl}/article?${qs.stringify(options)}`;
|
||||||
|
logger.log( newsItemUrl);
|
||||||
|
|
||||||
|
// await axios.get(newsItemUrl)
|
||||||
|
promise = axios.get(newsItemUrl)
|
||||||
|
.then((d) => {
|
||||||
|
logger.log('>> retrieved', d);
|
||||||
|
if (d.status === 200) {
|
||||||
|
const data = JSON.parse(d.data);
|
||||||
|
logger.log(data);
|
||||||
|
newsItem = data;
|
||||||
|
newsItemLoaded=true;
|
||||||
|
|
||||||
|
return newsItem;
|
||||||
|
} else
|
||||||
|
console.error(`getPage error: ${d.status} - ${d.statusText}`);
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error(`getPage error: `, err);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.container{
|
||||||
|
padding-top:4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{#await promise}
|
||||||
|
LOADING...
|
||||||
|
{:then}
|
||||||
|
{#if newsItemLoaded}
|
||||||
|
<div class="newsarticle">
|
||||||
|
<div style="text-align: center;"><img src={newsItem.image} alt={newsItem.title}></div>
|
||||||
|
<div class="mui-container" style="margin-bottom: 50px;">
|
||||||
|
<div><h1>{newsItem.title}</h1></div>
|
||||||
|
<div>{@html newsItem.html}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{/await}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
12
src/pages/NewsListPage.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>$</span>
|
14
src/pages/NotFound.svelte
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<h2 class="routetitle">NotFound</h2>
|
||||||
|
|
||||||
|
<p>Oops, this route doesn't exist!</p>
|
12
src/pages/VenueDetailsPage.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>$</span>
|
12
src/pages/WeatherPage.svelte
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
background: #f55a4e;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<span>$</span>
|
25
src/routes.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Created by WebStorm.
|
||||||
|
* User: martin
|
||||||
|
* Date: 05/05/2020
|
||||||
|
* Time: 12:08
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Home from './pages/Home.svelte';
|
||||||
|
|
||||||
|
import NewsItemPage from './pages/NewsItemPage.svelte';
|
||||||
|
import NearbyLocations from './pages/NearbyLocationsPage.svelte';
|
||||||
|
|
||||||
|
import NotFound from './pages/NotFound.svelte';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const routes = new Map();
|
||||||
|
routes.set('/', Home);
|
||||||
|
routes.set('/news/:id', NewsItemPage);
|
||||||
|
routes.set('/nearbylocations', NearbyLocations);
|
||||||
|
routes.set('*', NotFound);
|
||||||
|
|
||||||
|
export default routes;
|
||||||
|
|
121
src/store/globalState.js
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* Created by WebStorm.
|
||||||
|
* User: martin
|
||||||
|
* Date: 12/04/2020
|
||||||
|
* Time: 18:04
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { writable, get } from 'svelte/store';
|
||||||
|
// const {store} = import('store');
|
||||||
|
import axios from 'redaxios';
|
||||||
|
const TimeFormat = require('hh-mm-ss');
|
||||||
|
const ms = require('ms');
|
||||||
|
const qs = require('qs');
|
||||||
|
const { hourFloor, hasOwn, isEmpty } = require('../lib/utils');
|
||||||
|
const prefix = '📦';
|
||||||
|
|
||||||
|
const baseUrl = (ENV === 'production') ? (`${location.protocol }//${ location.hostname}`) : 'http://localhost:8110';
|
||||||
|
|
||||||
|
function Location() {
|
||||||
|
const { subscribe, set, update } = writable({ });
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe,
|
||||||
|
set,
|
||||||
|
update
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function Agenda() {
|
||||||
|
const { subscribe, set, update } = writable([]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe,
|
||||||
|
set,
|
||||||
|
update
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function NewsList() {
|
||||||
|
const { subscribe, set, update } = writable({});
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe,
|
||||||
|
set,
|
||||||
|
update
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function Weather() {
|
||||||
|
const { subscribe, set, update } = writable({});
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe,
|
||||||
|
set,
|
||||||
|
update
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
'location': Location(),
|
||||||
|
'newsList': NewsList(),
|
||||||
|
'weather': Weather(),
|
||||||
|
async getNewsList() {
|
||||||
|
console.log(`${prefix} getNewsList`);
|
||||||
|
// console.log('>> state.twitterFollowingList', get(state.twitterFollowingList));
|
||||||
|
const options = {
|
||||||
|
'w' : hourFloor()
|
||||||
|
};
|
||||||
|
|
||||||
|
const newsListUrl = `${baseUrl}/news?${qs.stringify(options)}`;
|
||||||
|
console.log(prefix, newsListUrl);
|
||||||
|
|
||||||
|
// console.log(postReq);
|
||||||
|
await axios.get(newsListUrl)
|
||||||
|
.then((d) => {
|
||||||
|
// console.log('>> retrieved', d);
|
||||||
|
if (d.status === 200) {
|
||||||
|
const data = JSON.parse(d.data);
|
||||||
|
console.log(data);
|
||||||
|
this.newsList.set(data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
console.error(`${prefix} getNewsList error: ${d.status} - ${d.statusText}`);
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error(`${prefix} getNewsList error: `, err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getArticleGuid(id) {
|
||||||
|
console.log(`${prefix} getArticleGuid ${id}`);
|
||||||
|
const list = get(this.newsList);
|
||||||
|
if (!isEmpty(list)) {
|
||||||
|
console.log(list);
|
||||||
|
const item = list.items[id];
|
||||||
|
console.log(item);
|
||||||
|
if (item !== null && hasOwn(item, 'guid'))
|
||||||
|
return item.guid.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
getBaseUrl() {
|
||||||
|
return baseUrl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function setTimers() {
|
||||||
|
console.log(`${prefix} Starting timers...`);
|
||||||
|
setInterval(() => {
|
||||||
|
state.getNewsList();
|
||||||
|
}, ms('1h'));
|
||||||
|
}
|
||||||
|
|
||||||
|
(async function() {
|
||||||
|
await state.getNewsList();
|
||||||
|
|
||||||
|
setTimers();
|
||||||
|
})();
|
||||||
|
|
||||||
|
export { state };
|