Compare commits
110 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de600d1525 | ||
|
|
c1335fdf25 | ||
|
|
36eced4232 | ||
|
|
3f11e36b42 | ||
|
|
db2a3a4d60 | ||
|
|
d7222c6cf0 | ||
|
|
fca71efb1e | ||
|
|
6943d7eaa4 | ||
|
|
4b343830c9 | ||
|
|
f50d81651b | ||
|
|
7ac86a435a | ||
|
|
e2dd677c7f | ||
|
|
1a8a59fd77 | ||
|
|
80c085ca38 | ||
|
|
6f079a6361 | ||
|
|
b2cf816e2f | ||
|
|
6c176726f2 | ||
|
|
47c6a51c39 | ||
|
|
04f509c76b | ||
|
|
261a3518ee | ||
|
|
eb277aa5e8 | ||
|
|
c4b6ef56e6 | ||
|
|
886d8fa202 | ||
|
|
60ce0dcb3e | ||
|
|
35748fe333 | ||
|
|
aa826eb5f3 | ||
|
|
e25619b601 | ||
|
|
12b2e612aa | ||
|
|
b6f095d504 | ||
|
|
c5a9cbde58 | ||
|
|
dc8cae1853 | ||
|
|
e22168f39c | ||
|
|
3319c400b5 | ||
|
|
6725d91663 | ||
|
|
7a78cb6b21 | ||
|
|
0dc76aaf94 | ||
|
|
58daa3a31e | ||
|
|
beb2330bcd | ||
|
|
f38aef13be | ||
|
|
7920909308 | ||
|
|
d9a2df002c | ||
|
|
5ba87ef2c5 | ||
|
|
b83b599553 | ||
|
|
646d49fa2e | ||
|
|
b1535d74a1 | ||
|
|
8606e31bc5 | ||
|
|
4b87a7584a | ||
|
|
5234295a87 | ||
|
|
aba7919400 | ||
|
|
3fdd58db33 | ||
|
|
6651510249 | ||
|
|
326481521a | ||
|
|
b34895a8ae | ||
|
|
3663462bb4 | ||
|
|
815df437c7 | ||
|
|
cfa47cd47d | ||
|
|
fbfd0b5f4c | ||
|
|
ea9a002e01 | ||
|
|
6f8f7b12ab | ||
|
|
bec0ebc623 | ||
|
|
5f863d6ec4 | ||
|
|
d3345aa685 | ||
|
|
aa48199e58 | ||
|
|
028d9822bb | ||
|
|
08deb29ae8 | ||
|
|
1a7537ef27 | ||
|
|
e4ef581049 | ||
|
|
c642c5a5e9 | ||
|
|
0821049fc1 | ||
|
|
996be45987 | ||
|
|
44f654c085 | ||
|
|
98fe966f32 | ||
|
|
159c9a80c1 | ||
|
|
f407ed5899 | ||
|
|
77ed627312 | ||
|
|
57030be78f | ||
|
|
c8953e46d5 | ||
|
|
e18fbd7e6e | ||
|
|
551ad78345 | ||
|
|
dbabd39967 | ||
|
|
5cf2f37e7c | ||
|
|
fb82a18a5a | ||
|
|
930a9dab4a | ||
|
|
382b9b1576 | ||
|
|
524b16fd75 | ||
|
|
07f29da574 | ||
|
|
ecb6ad4d86 | ||
|
|
0c79d43ba1 | ||
|
|
52f8d098b3 | ||
|
|
e4230d58fa | ||
|
|
8df6915b38 | ||
|
|
2616332b4a | ||
|
|
8218f0469b | ||
|
|
8bfd76981f | ||
|
|
2205a9520d | ||
|
|
3f73c93eb2 | ||
|
|
5dfd363ecd | ||
|
|
c69125c5f2 | ||
|
|
50d68d0078 | ||
|
|
73f37b7567 | ||
|
|
d7b2ae93bb | ||
|
|
1ab433daec | ||
|
|
4fa0f78b42 | ||
|
|
fdea228ed1 | ||
|
|
707f0c6830 | ||
|
|
f71ef166b5 | ||
|
|
89462fd21a | ||
|
|
5f99f553c5 | ||
|
|
dddc1314e7 | ||
|
|
c5f50cb6b1 |
@@ -18,6 +18,7 @@ COPY --from=sources /var/www/app/node_modules ./node_modules
|
||||
COPY --from=sources /var/www/app/package.json ./package.json
|
||||
COPY ./server ./server
|
||||
COPY ./dist ./dist
|
||||
COPY ./mystatsmashup ./mystatsmashup
|
||||
|
||||
EXPOSE 3000
|
||||
EXPOSE 3100
|
||||
|
||||
@@ -38,12 +38,15 @@
|
||||
"src/styles.scss"
|
||||
],
|
||||
"scripts": [
|
||||
|
||||
"node_modules/chart.js/dist/Chart.js",
|
||||
"node_modules/hammerjs/hammer.min.js",
|
||||
"node_modules/marked/lib/marked.js",
|
||||
"node_modules/prismjs/prism.js",
|
||||
"node_modules/prismjs/plugins/line-highlight/prism-line-highlight.js",
|
||||
"node_modules/prismjs/plugins/line-numbers/prism-line-numbers.js"
|
||||
"node_modules/prismjs/plugins/line-numbers/prism-line-numbers.js",
|
||||
"src/assets/js/qdt-components.js",
|
||||
"src/assets/js/qlikMashupQCS.js"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
|
||||
0
costexport/.keep
Normal file
1
costexport/sample.json
Normal file
@@ -0,0 +1 @@
|
||||
{"test": "ok"}
|
||||
|
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 211 B |
|
Before Width: | Height: | Size: 213 B After Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 209 B After Width: | Height: | Size: 209 B |
|
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 211 B |
|
Before Width: | Height: | Size: 213 B After Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 211 B |
|
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 215 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 137 B |
BIN
dist/qmi-cloud/3rdpartylicenses.txt
vendored
Normal file
|
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 215 B |
|
Before Width: | Height: | Size: 214 B After Width: | Height: | Size: 214 B |
135423
dist/qmi-cloud/assets/js/qdt-components.js
vendored
Normal file
52
dist/qmi-cloud/assets/js/qlikMashupQCS.js
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
var qlikMashup = (function() {
|
||||
|
||||
const { qdtCapabilityApp, QdtViz } = QdtComponents;
|
||||
|
||||
const initMyQdt = async function(config, returnto) {
|
||||
|
||||
const urlLoggedIn = "/api/v1/users/me";//Use GET request to see if you are authenticated
|
||||
const urlLogin = "/login";
|
||||
|
||||
const response = await fetch(`https://${config.host}${urlLoggedIn}`, {
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Qlik-Web-Integration-ID': config.webIntegrationId
|
||||
}
|
||||
})
|
||||
|
||||
if( response.status===401 ) {
|
||||
const url = new URL(`https://${config.host}${urlLogin}`);
|
||||
url.searchParams.append('returnto', returnto);
|
||||
url.searchParams.append('qlik-web-integration-id', config.webIntegrationId);
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
const user = await response.json();
|
||||
const capabilityApiAppPromise = qdtCapabilityApp(config);
|
||||
const app = await capabilityApiAppPromise;
|
||||
|
||||
return {app: app, user: user};
|
||||
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
"initMyQdt": initMyQdt,
|
||||
|
||||
"myQdtViz": function(app, divId, qlikObjectId, height, type){
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById(divId),
|
||||
app,
|
||||
options: {
|
||||
type: type,
|
||||
id: qlikObjectId,
|
||||
height: height
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})(qlikMashup||{})
|
||||
|
||||
BIN
dist/qmi-cloud/fa-brands-400.cac68c83114580480838.woff2
vendored
Normal file
|
Before Width: | Height: | Size: 699 KiB After Width: | Height: | Size: 713 KiB |
BIN
dist/qmi-cloud/fa-brands-400.dc0bd022735ed218df54.woff
vendored
Normal file
BIN
dist/qmi-cloud/fa-brands-400.woff
vendored
BIN
dist/qmi-cloud/fa-brands-400.woff2
vendored
BIN
dist/qmi-cloud/fa-regular-400.05b53beb21e3ef13d282.woff
vendored
Normal file
BIN
dist/qmi-cloud/fa-regular-400.3a3398a6ef60fc64eacf.woff2
vendored
Normal file
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!--
|
||||
Font Awesome Free 5.12.1 by @fontawesome - https://fontawesome.com
|
||||
Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
|
||||
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
-->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
||||
<metadata>
|
||||
Created by FontForge 20190801 at Tue Feb 4 18:05:39 2020
|
||||
Created by FontForge 20200314 at Wed Jul 15 11:59:40 2020
|
||||
By Robert Madole
|
||||
Copyright (c) Font Awesome
|
||||
</metadata>
|
||||
@@ -20,7 +20,7 @@ Copyright (c) Font Awesome
|
||||
panose-1="2 0 5 3 0 0 0 0 0 0"
|
||||
ascent="448"
|
||||
descent="-64"
|
||||
bbox="-0.0663408 -64.0662 640.01 448.1"
|
||||
bbox="-0.0663408 -64.0662 640.004 448.1"
|
||||
underline-thickness="25"
|
||||
underline-position="-50"
|
||||
unicode-range="U+0020-F5C8"
|
||||
@@ -50,7 +50,7 @@ s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 192c0 -19.8818 -16.
|
||||
<glyph glyph-name="flag" unicode=""
|
||||
d="M336.174 368c35.4668 0 73.0195 12.6914 108.922 28.1797c31.6406 13.6514 66.9043 -9.65723 66.9043 -44.1162v-239.919c0 -16.1953 -8.1543 -31.3057 -21.7129 -40.1631c-26.5762 -17.3643 -70.0693 -39.9814 -128.548 -39.9814c-68.6084 0 -112.781 32 -161.913 32
|
||||
c-56.5674 0 -89.957 -11.2803 -127.826 -28.5566v-83.4434c0 -8.83691 -7.16309 -16 -16 -16h-16c-8.83691 0 -16 7.16309 -16 16v406.438c-14.3428 8.2998 -24 23.7979 -24 41.5615c0 27.5693 23.2422 49.71 51.2012 47.8965
|
||||
c22.9658 -1.49023 41.8662 -19.4717 44.4805 -42.3379c0.177734 -1.52441 0.321289 -4.00781 0.321289 -5.54199c0 -4.30176 -1.10352 -11.1035 -2.46289 -15.1846c22.418 8.68555 49.4199 15.168 80.7207 15.168c68.6084 0 112.781 -32 161.913 -32zM464 112v240
|
||||
c22.9658 -1.49023 41.8662 -19.4717 44.4805 -42.3379c0.213867 -1.83398 0.308594 -3.65918 0.308594 -5.5498c0 -5.30273 -0.860352 -10.4053 -2.4502 -15.1768c22.418 8.68555 49.4199 15.168 80.7207 15.168c68.6084 0 112.781 -32 161.913 -32zM464 112v240
|
||||
c-31.5059 -14.6338 -84.5547 -32 -127.826 -32c-59.9111 0 -101.968 32 -161.913 32c-41.4365 0 -80.4766 -16.5879 -102.261 -32v-232c31.4473 14.5967 84.4648 24 127.826 24c59.9111 0 101.968 -32 161.913 -32c41.4365 0 80.4775 16.5879 102.261 32z" />
|
||||
<glyph glyph-name="bookmark" unicode="" horiz-adv-x="384"
|
||||
d="M336 448c26.5098 0 48 -21.4902 48 -48v-464l-192 112l-192 -112v464c0 26.5098 21.4902 48 48 48h288zM336 19.5703v374.434c0 3.31348 -2.68555 5.99609 -6 5.99609h-276c-3.31152 0 -6 -2.68848 -6 -6v-374.43l144 84z" />
|
||||
@@ -77,17 +77,17 @@ c0 -110.569 89.4678 -200 200 -200zM363.244 247.2c0 -67.0518 -72.4209 -68.084 -72
|
||||
c17.5615 9.84473 28.3242 16.541 28.3242 29.5791c0 17.2461 -21.999 28.6934 -39.7842 28.6934c-23.1885 0 -33.8936 -10.9775 -48.9424 -29.9697c-4.05664 -5.11914 -11.46 -6.07031 -16.666 -2.12402l-27.8232 21.0986
|
||||
c-5.10742 3.87207 -6.25098 11.0654 -2.64453 16.3633c23.627 34.6934 53.7217 54.1846 100.575 54.1846c49.0713 0 101.45 -38.3037 101.45 -88.7998zM298 80c0 -23.1592 -18.8408 -42 -42 -42s-42 18.8408 -42 42s18.8408 42 42 42s42 -18.8408 42 -42z" />
|
||||
<glyph glyph-name="eye" unicode="" horiz-adv-x="576"
|
||||
d="M288 304c0.0927734 0 0.244141 0.000976562 0.336914 0.000976562c61.6641 0 111.71 -50.0469 111.71 -111.711c0 -61.6631 -50.0459 -111.71 -111.71 -111.71s-111.71 50.0469 -111.71 111.71c0 8.71289 1.95898 22.5781 4.37305 30.9502
|
||||
c6.93066 -3.94141 19.0273 -7.18457 27 -7.24023c30.9121 0 56 25.0879 56 56c-0.0556641 7.97266 -3.29883 20.0693 -7.24023 27c8.42383 2.62207 22.4189 4.8623 31.2402 5zM572.52 206.6c1.9209 -3.79883 3.47949 -10.3379 3.47949 -14.5947
|
||||
s-1.55859 -10.7959 -3.47949 -14.5947c-54.1992 -105.771 -161.59 -177.41 -284.52 -177.41s-230.29 71.5898 -284.52 177.4c-1.9209 3.79883 -3.47949 10.3379 -3.47949 14.5947s1.55859 10.7959 3.47949 14.5947c54.1992 105.771 161.59 177.41 284.52 177.41
|
||||
s230.29 -71.5898 284.52 -177.4zM288 48c98.6602 0 189.1 55 237.93 144c-48.8398 89 -139.27 144 -237.93 144s-189.09 -55 -237.93 -144c48.8398 -89 139.279 -144 237.93 -144z" />
|
||||
d="M288 304c0.114258 0 0.240234 -0.0175781 0.354492 -0.0175781c61.6543 0 111.71 -50.0557 111.71 -111.71s-50.0557 -111.71 -111.71 -111.71s-111.71 50.0557 -111.71 111.71c0 10.7422 1.51953 21.1328 4.35547 30.9678
|
||||
c7.95898 -4.52637 17.2129 -7.17188 27 -7.24023c30.9072 0 56 25.0928 56 56c-0.0683594 9.78711 -2.71387 19.041 -7.24023 27c9.88379 3.07617 20.3896 4.83008 31.2402 5zM572.52 206.6c2.21387 -4.37793 3.46094 -9.38965 3.46094 -14.626
|
||||
c0 -5.2373 -1.24707 -10.1855 -3.46094 -14.5635c-54.1992 -105.771 -161.59 -177.41 -284.52 -177.41s-230.29 71.5898 -284.52 177.4c-2.21387 4.37793 -3.46094 9.38965 -3.46094 14.626c0 5.2373 1.24707 10.1855 3.46094 14.5635
|
||||
c54.1992 105.771 161.59 177.41 284.52 177.41s230.29 -71.5898 284.52 -177.4zM288 48c98.6602 0 189.1 55 237.93 144c-48.8398 89 -139.27 144 -237.93 144s-189.09 -55 -237.93 -144c48.8398 -89 139.279 -144 237.93 -144z" />
|
||||
<glyph glyph-name="eye-slash" unicode="" horiz-adv-x="640"
|
||||
d="M634 -23c3.31738 -2.65137 6.00977 -8.25098 6.00977 -12.498c0 -3.10449 -1.57715 -7.58984 -3.51953 -10.0117l-10 -12.4902c-2.65234 -3.31152 -8.24707 -6 -12.4902 -6c-3.09961 0 -7.58008 1.57227 -10 3.50977l-598 467.49
|
||||
c-3.31738 2.65137 -6.00977 8.25098 -6.00977 12.498c0 3.10449 1.57715 7.58984 3.51953 10.0117l10 12.4902c2.65234 3.31152 8.24707 6 12.4902 6c3.09961 0 7.58008 -1.57227 10 -3.50977zM296.79 301.53c6.33496 1.35059 16.7324 2.45801 23.21 2.46973
|
||||
c60.4805 0 109.36 -47.9102 111.58 -107.85zM343.21 82.46c-6.33496 -1.34375 -16.7334 -2.44629 -23.21 -2.45996c-60.4697 0 -109.35 47.9102 -111.58 107.84zM320 336c-19.8799 0 -39.2803 -2.7998 -58.2197 -7.09961l-46.4102 36.29
|
||||
c32.9199 11.8096 67.9297 18.8096 104.63 18.8096c122.93 0 230.29 -71.5898 284.57 -177.4c1.91992 -3.79883 3.47949 -10.3379 3.47949 -14.5947s-1.55957 -10.7959 -3.47949 -14.5947c-11.7197 -22.7598 -35.4189 -56.4092 -52.9004 -75.1104l-37.7402 29.5
|
||||
c14.333 15.0156 34.0449 41.9854 44 60.2002c-48.8398 89 -139.279 144 -237.93 144zM320 48c19.8896 0 39.2803 2.7998 58.2197 7.08984l46.4102 -36.2803c-32.9199 -11.7598 -67.9297 -18.8096 -104.63 -18.8096c-122.92 0 -230.28 71.5898 -284.51 177.4
|
||||
c-1.9209 3.79883 -3.47949 10.3379 -3.47949 14.5947s1.55859 10.7959 3.47949 14.5947c11.7168 22.7568 35.4111 56.4014 52.8896 75.1006l37.7402 -29.5c-14.3467 -15.0107 -34.0811 -41.9756 -44.0498 -60.1904c48.8496 -89 139.279 -144 237.93 -144z" />
|
||||
d="M634 -23c3.66895 -2.93262 6.00391 -7.45117 6.00391 -12.5088c0 -3.7832 -1.31543 -7.26074 -3.51367 -10.001l-10 -12.4902c-2.93359 -3.66309 -7.44824 -5.99414 -12.502 -5.99414c-3.77637 0 -7.25 1.31152 -9.98828 3.50391l-598 467.49
|
||||
c-3.66895 2.93262 -6.00391 7.45117 -6.00391 12.5088c0 3.7832 1.31543 7.26074 3.51367 10.001l10 12.4902c2.93359 3.66309 7.44824 5.99414 12.502 5.99414c3.77637 0 7.25 -1.31152 9.98828 -3.50391zM296.79 301.53c7.51172 1.60254 15.2266 2.45508 23.21 2.46973
|
||||
c60.4805 0 109.36 -47.9102 111.58 -107.85zM343.21 82.46c-7.51367 -1.59375 -15.2285 -2.44336 -23.21 -2.45996c-60.4697 0 -109.35 47.9102 -111.58 107.84zM320 336c-19.8799 0 -39.2803 -2.7998 -58.2197 -7.09961l-46.4102 36.29
|
||||
c32.9199 11.8096 67.9297 18.8096 104.63 18.8096c122.93 0 230.29 -71.5898 284.57 -177.4c2.21289 -4.37793 3.45996 -9.38965 3.45996 -14.626c0 -5.2373 -1.24707 -10.1855 -3.45996 -14.5635c-14.1924 -27.5625 -31.9229 -52.6689 -52.9004 -75.1104l-37.7402 29.5
|
||||
c17.2305 18.0527 31.9385 38.1318 44 60.2002c-48.8398 89 -139.279 144 -237.93 144zM320 48c19.8896 0 39.2803 2.7998 58.2197 7.08984l46.4102 -36.2803c-32.9199 -11.7598 -67.9297 -18.8096 -104.63 -18.8096c-122.92 0 -230.28 71.5898 -284.51 177.4
|
||||
c-2.21387 4.37793 -3.46094 9.38965 -3.46094 14.626c0 5.2373 1.24707 10.1855 3.46094 14.5635c14.1885 27.5586 31.916 52.6621 52.8896 75.1006l37.7402 -29.5c-17.249 -18.0469 -31.9727 -38.1221 -44.0498 -60.1904c48.8496 -89 139.279 -144 237.93 -144z" />
|
||||
<glyph glyph-name="calendar-alt" unicode="" horiz-adv-x="448"
|
||||
d="M148 160h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM256 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-40zM352 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM256 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40
|
||||
@@ -131,47 +131,47 @@ d="M527.9 416c26.5996 0 48.0996 -21.5 48.0996 -48v-352c0 -26.5 -21.5 -48 -48.099
|
||||
h-467.801zM521.9 16c3.2998 0 6 2.7002 6 6v170h-479.801v-170c0 -3.2998 2.7002 -6 6 -6h467.801zM192 116v-40c0 -6.59961 -5.40039 -12 -12 -12h-72c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h72c6.59961 0 12 -5.40039 12 -12zM384 116v-40
|
||||
c0 -6.59961 -5.40039 -12 -12 -12h-136c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h136c6.59961 0 12 -5.40039 12 -12z" />
|
||||
<glyph glyph-name="hdd" unicode="" horiz-adv-x="576"
|
||||
d="M567.403 212.358c5.59668 -8.04688 8.59668 -17.6113 8.59668 -27.4121v-136.946c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v136.946c0 8.30957 3.85156 20.5898 8.59668 27.4121l105.08 151.053
|
||||
c7.90625 11.3652 25.5596 20.5889 39.4033 20.5889h0.000976562h269.838h0.000976562c13.8438 0 31.4971 -9.22363 39.4033 -20.5889zM153.081 336l-77.9131 -112h425.664l-77.9131 112h-269.838zM528 48v128h-480v-128h480zM496 112c0 -17.6729 -14.3271 -32 -32 -32
|
||||
s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32zM400 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32z" />
|
||||
d="M567.403 212.358c5.59668 -8.04688 8.59668 -17.6113 8.59668 -27.4121v-136.946c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v136.946c0 10.167 3.19531 19.6465 8.59668 27.4121l105.08 151.053
|
||||
c8.67383 12.4678 23.0791 20.5889 39.4043 20.5889h269.838c16.3252 0 30.7305 -8.12109 39.4043 -20.5889zM153.081 336l-77.9131 -112h425.664l-77.9131 112h-269.838zM528 48v128h-480v-128h480zM496 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32
|
||||
s14.3271 32 32 32s32 -14.3271 32 -32zM400 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32z" />
|
||||
<glyph glyph-name="hand-point-right" unicode=""
|
||||
d="M428.8 310.4c45.0996 0 83.2002 -38.1016 83.2002 -83.2002c0 -45.6162 -37.7646 -83.2002 -83.2002 -83.2002h-35.6475c-1.41602 -6.36719 -4.96875 -16.252 -7.92969 -22.0645c2.50586 -22.0059 -3.50293 -44.9775 -15.9844 -62.791
|
||||
d="M428.8 310.4c45.0996 0 83.2002 -38.1016 83.2002 -83.2002c0 -45.6162 -37.7646 -83.2002 -83.2002 -83.2002h-35.6475c-1.71387 -7.70605 -4.43555 -15.2051 -7.92969 -22.0645c2.50586 -22.0059 -3.50293 -44.9775 -15.9844 -62.791
|
||||
c-1.14062 -52.4863 -37.3984 -91.1445 -99.9404 -91.1445h-21.2988c-60.0635 0 -98.5117 40 -127.2 40h-2.67871c-5.74707 -4.95215 -13.5361 -8 -22.1201 -8h-64c-17.6729 0 -32 12.8936 -32 28.7998v230.4c0 15.9062 14.3271 28.7998 32 28.7998h64.001
|
||||
c8.58398 0 16.373 -3.04785 22.1201 -8h2.67871c6.96387 0 14.8623 6.19336 30.1816 23.6689l0.128906 0.148438l0.130859 0.145508c8.85645 9.93652 18.1162 20.8398 25.8506 33.2529c18.7051 30.2471 30.3936 78.7842 75.707 78.7842c56.9277 0 92 -35.2861 92 -83.2002
|
||||
v-0.0839844c0 -6.21777 -0.974609 -16.2148 -2.17578 -22.3154h86.1768zM428.8 192c18.9756 0 35.2002 16.2246 35.2002 35.2002c0 18.7002 -16.7754 35.2002 -35.2002 35.2002h-158.399c0 17.3242 26.3994 35.1992 26.3994 70.3994c0 26.4004 -20.625 35.2002 -44 35.2002
|
||||
c-8.79395 0 -20.4443 -32.7119 -34.9258 -56.0996c-9.07422 -14.5752 -19.5244 -27.2256 -30.7988 -39.875c-16.1094 -18.374 -33.8359 -36.6328 -59.0752 -39.5967v-176.753c42.79 -3.7627 74.5088 -39.6758 120 -39.6758h21.2988
|
||||
c0 -0.0283203 0 0.0361328 0 0.0078125c0 -7.66602 -0.748047 -15.1582 -2.17578 -22.4072h86.1768zM428.8 192c18.9756 0 35.2002 16.2246 35.2002 35.2002c0 18.7002 -16.7754 35.2002 -35.2002 35.2002h-158.399c0 17.3242 26.3994 35.1992 26.3994 70.3994
|
||||
c0 26.4004 -20.625 35.2002 -44 35.2002c-8.79395 0 -20.4443 -32.7119 -34.9258 -56.0996c-9.07422 -14.5752 -19.5244 -27.2256 -30.7988 -39.875c-16.1094 -18.374 -33.8359 -36.6328 -59.0752 -39.5967v-176.753c42.79 -3.7627 74.5088 -39.6758 120 -39.6758h21.2988
|
||||
c40.5244 0 57.124 22.1973 50.6006 61.3252c14.6113 8.00098 24.1514 33.9785 12.9248 53.625c19.3652 18.2246 17.7871 46.3809 4.9502 61.0498h91.0254zM88 64c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
|
||||
<glyph glyph-name="hand-point-left" unicode=""
|
||||
d="M0 227.2c0 45.0986 38.1006 83.2002 83.2002 83.2002h86.1758c-1.3623 6.91016 -2.17578 14.374 -2.17578 22.3994c0 47.9141 35.0723 83.2002 92 83.2002c45.3135 0 57.002 -48.5371 75.7061 -78.7852c7.73438 -12.4121 16.9951 -23.3154 25.8506 -33.2529
|
||||
l0.130859 -0.145508l0.128906 -0.148438c15.3213 -17.4746 23.2197 -23.668 30.1836 -23.668h2.67871c5.74707 4.95215 13.5361 8 22.1201 8h64c17.6729 0 32 -12.8936 32 -28.7998v-230.4c0 -15.9062 -14.3271 -28.7998 -32 -28.7998h-64
|
||||
c-8.58398 0 -16.373 3.04785 -22.1201 8h-2.67871c-28.6885 0 -67.1367 -40 -127.2 -40h-21.2988c-62.542 0 -98.8008 38.6582 -99.9404 91.1445c-12.4814 17.8135 -18.4922 40.7852 -15.9844 62.791c-2.96094 5.8125 -6.51367 15.6973 -7.92969 22.0645h-35.6465
|
||||
c-8.58398 0 -16.373 3.04785 -22.1201 8h-2.67871c-28.6885 0 -67.1367 -40 -127.2 -40h-21.2988c-62.542 0 -98.8008 38.6582 -99.9404 91.1445c-12.4814 17.8135 -18.4922 40.7852 -15.9844 62.791c-3.49414 6.85938 -6.21582 14.3584 -7.92969 22.0645h-35.6465
|
||||
c-45.4355 0 -83.2002 37.584 -83.2002 83.2002zM48 227.2c0 -18.9756 16.2246 -35.2002 35.2002 -35.2002h91.0244c-12.8369 -14.6689 -14.415 -42.8252 4.9502 -61.0498c-11.2256 -19.6465 -1.68652 -45.624 12.9248 -53.625
|
||||
c-6.52246 -39.1279 10.0771 -61.3252 50.6016 -61.3252h21.2988c45.4912 0 77.21 35.9131 120 39.6768v176.752c-25.2393 2.96289 -42.9658 21.2227 -59.0752 39.5967c-11.2744 12.6494 -21.7246 25.2998 -30.7988 39.875
|
||||
c-14.4814 23.3877 -26.1318 56.0996 -34.9258 56.0996c-23.375 0 -44 -8.7998 -44 -35.2002c0 -35.2002 26.3994 -53.0752 26.3994 -70.3994h-158.399c-18.4248 0 -35.2002 -16.5 -35.2002 -35.2002zM448 88c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24
|
||||
s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
<glyph glyph-name="hand-point-up" unicode="" horiz-adv-x="448"
|
||||
d="M105.6 364.8c0 45.0996 38.1016 83.2002 83.2002 83.2002c45.6162 0 83.2002 -37.7646 83.2002 -83.2002v-35.6465c6.36719 -1.41602 16.252 -4.96875 22.0645 -7.92969c22.0059 2.50684 44.9775 -3.50293 62.791 -15.9844
|
||||
d="M105.6 364.8c0 45.0996 38.1016 83.2002 83.2002 83.2002c45.6162 0 83.2002 -37.7646 83.2002 -83.2002v-35.6465c7.70605 -1.71387 15.2051 -4.43555 22.0645 -7.92969c22.0059 2.50684 44.9775 -3.50293 62.791 -15.9844
|
||||
c52.4863 -1.14062 91.1445 -37.3984 91.1445 -99.9404v-21.2988c0 -60.0635 -40 -98.5117 -40 -127.2v-2.67871c4.95215 -5.74707 8 -13.5361 8 -22.1201v-64c0 -17.6729 -12.8936 -32 -28.7998 -32h-230.4c-15.9062 0 -28.7998 14.3271 -28.7998 32v64
|
||||
c0 8.58398 3.04785 16.373 8 22.1201v2.67871c0 6.96387 -6.19336 14.8623 -23.6689 30.1816l-0.148438 0.128906l-0.145508 0.130859c-9.93652 8.85645 -20.8398 18.1162 -33.2529 25.8506c-30.2471 18.7051 -78.7842 30.3936 -78.7842 75.707
|
||||
c0 56.9277 35.2861 92 83.2002 92h0.0839844c6.21777 0 16.2148 -0.974609 22.3154 -2.17578v86.1768zM224 364.8c0 18.9756 -16.2246 35.2002 -35.2002 35.2002c-18.7002 0 -35.2002 -16.7754 -35.2002 -35.2002v-158.399c-17.3242 0 -35.1992 26.3994 -70.3994 26.3994
|
||||
c-26.4004 0 -35.2002 -20.625 -35.2002 -44c0 -8.79395 32.7119 -20.4443 56.0996 -34.9258c14.5752 -9.07422 27.2256 -19.5244 39.875 -30.7988c18.374 -16.1094 36.6328 -33.8359 39.5967 -59.0752h176.753c3.7627 42.79 39.6758 74.5088 39.6758 120v21.2988
|
||||
c0 40.5244 -22.1973 57.124 -61.3252 50.6006c-8.00098 14.6113 -33.9785 24.1514 -53.625 12.9248c-18.2246 19.3652 -46.3809 17.7871 -61.0498 4.9502v91.0254zM352 24c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
c0 56.9277 35.2861 92 83.2002 92c0.0283203 0 -0.0361328 0 -0.0078125 0c7.66602 0 15.1582 -0.748047 22.4072 -2.17578v86.1768zM224 364.8c0 18.9756 -16.2246 35.2002 -35.2002 35.2002c-18.7002 0 -35.2002 -16.7754 -35.2002 -35.2002v-158.399
|
||||
c-17.3242 0 -35.1992 26.3994 -70.3994 26.3994c-26.4004 0 -35.2002 -20.625 -35.2002 -44c0 -8.79395 32.7119 -20.4443 56.0996 -34.9258c14.5752 -9.07422 27.2256 -19.5244 39.875 -30.7988c18.374 -16.1094 36.6328 -33.8359 39.5967 -59.0752h176.753
|
||||
c3.7627 42.79 39.6758 74.5088 39.6758 120v21.2988c0 40.5244 -22.1973 57.124 -61.3252 50.6006c-8.00098 14.6113 -33.9785 24.1514 -53.625 12.9248c-18.2246 19.3652 -46.3809 17.7871 -61.0498 4.9502v91.0254zM352 24c-13.2549 0 -24 -10.7451 -24 -24
|
||||
s10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
<glyph glyph-name="hand-point-down" unicode="" horiz-adv-x="448"
|
||||
d="M188.8 -64c-45.0986 0 -83.2002 38.1006 -83.2002 83.2002v86.1758c-6.91016 -1.3623 -14.374 -2.17578 -22.3994 -2.17578c-47.9141 0 -83.2002 35.0723 -83.2002 92c0 45.3135 48.5371 57.002 78.7852 75.707c12.4121 7.73438 23.3154 16.9951 33.2529 25.8506
|
||||
l0.145508 0.130859l0.148438 0.128906c17.4746 15.3213 23.668 23.2197 23.668 30.1836v2.67871c-4.95215 5.74707 -8 13.5361 -8 22.1201v64c0 17.6729 12.8936 32 28.7998 32h230.4c15.9062 0 28.7998 -14.3271 28.7998 -32v-64.001
|
||||
c0 -8.58398 -3.04785 -16.373 -8 -22.1201v-2.67871c0 -28.6885 40 -67.1367 40 -127.2v-21.2988c0 -62.542 -38.6582 -98.8008 -91.1445 -99.9404c-17.8135 -12.4814 -40.7852 -18.4922 -62.791 -15.9844c-5.8125 -2.96094 -15.6973 -6.51367 -22.0645 -7.92969v-35.6465
|
||||
c0 -8.58398 -3.04785 -16.373 -8 -22.1201v-2.67871c0 -28.6885 40 -67.1367 40 -127.2v-21.2988c0 -62.542 -38.6582 -98.8008 -91.1445 -99.9404c-17.8135 -12.4814 -40.7852 -18.4922 -62.791 -15.9844c-6.85938 -3.49414 -14.3584 -6.21582 -22.0645 -7.92969v-35.6465
|
||||
c0 -45.4355 -37.584 -83.2002 -83.2002 -83.2002zM188.8 -16c18.9756 0 35.2002 16.2246 35.2002 35.2002v91.0244c14.6689 -12.8369 42.8252 -14.415 61.0498 4.9502c19.6465 -11.2256 45.624 -1.68652 53.625 12.9248c39.1279 -6.52246 61.3252 10.0771 61.3252 50.6016
|
||||
v21.2988c0 45.4912 -35.9131 77.21 -39.6768 120h-176.752c-2.96289 -25.2393 -21.2227 -42.9658 -39.5967 -59.0752c-12.6494 -11.2744 -25.2998 -21.7246 -39.875 -30.7988c-23.3877 -14.4814 -56.0996 -26.1318 -56.0996 -34.9258c0 -23.375 8.7998 -44 35.2002 -44
|
||||
c35.2002 0 53.0752 26.3994 70.3994 26.3994v-158.399c0 -18.4248 16.5 -35.2002 35.2002 -35.2002zM328 384c0 -13.2549 10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24z" />
|
||||
<glyph glyph-name="copy" unicode="" horiz-adv-x="448"
|
||||
d="M433.941 382.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-80v-48c0 -26.5098 -21.4902 -48 -48 -48h-224c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h80v48c0 26.5098 21.4902 48 48 48
|
||||
h172.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM266 -16c3.31152 0 6 2.68848 6 6v42h-96c-26.5098 0 -48 21.4902 -48 48v224h-74c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM394 80c3.31152 0 6 2.68848 6 6v202h-88
|
||||
c-13.2549 0 -24 10.7451 -24 24v88h-106c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM400 336v9.63184v0.000976562c0 1.37207 -0.787109 3.27246 -1.75684 4.24219l-48.3682 48.3682c-1.12598 1.125 -2.65234 1.75684 -4.24316 1.75684h-9.63184
|
||||
v-64h64z" />
|
||||
d="M433.941 382.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-80v-48c0 -26.5098 -21.4902 -48 -48 -48h-224c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h80v48c0 26.5098 21.4902 48 48 48
|
||||
h172.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM266 -16c3.31152 0 6 2.68848 6 6v42h-96c-26.5098 0 -48 21.4902 -48 48v224h-74c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM394 80c3.31152 0 6 2.68848 6 6v202h-88
|
||||
c-13.2549 0 -24 10.7451 -24 24v88h-106c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM400 336v9.63184c0 1.65527 -0.670898 3.15723 -1.75684 4.24316l-48.3682 48.3682c-1.12598 1.125 -2.65234 1.75684 -4.24316 1.75684h-9.63184v-64h64z" />
|
||||
<glyph glyph-name="save" unicode="" horiz-adv-x="448"
|
||||
d="M433.941 318.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h268.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM272 368h-128v-80h128v80
|
||||
zM394 16c3.31152 0 6 2.68848 6 6v259.632v0.000976562c0 1.37207 -0.787109 3.27246 -1.75684 4.24219l-78.2432 78.2432v-100.118c0 -13.2549 -10.7451 -24 -24 -24h-176c-13.2549 0 -24 10.7451 -24 24v104h-42c-3.31152 0 -6 -2.68848 -6 -6v-340
|
||||
c0 -3.31152 2.68848 -6 6 -6h340zM224 216c48.5234 0 88 -39.4766 88 -88s-39.4766 -88 -88 -88s-88 39.4766 -88 88s39.4766 88 88 88zM224 88c22.0557 0 40 17.9443 40 40s-17.9443 40 -40 40s-40 -17.9443 -40 -40s17.9443 -40 40 -40z" />
|
||||
d="M433.941 318.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h268.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM272 368h-128v-80h128v80z
|
||||
M394 16c3.31152 0 6 2.68848 6 6v259.632c0 1.65527 -0.670898 3.15723 -1.75684 4.24316l-78.2432 78.2432v-100.118c0 -13.2549 -10.7451 -24 -24 -24h-176c-13.2549 0 -24 10.7451 -24 24v104h-42c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340z
|
||||
M224 216c48.5234 0 88 -39.4766 88 -88s-39.4766 -88 -88 -88s-88 39.4766 -88 88s39.4766 88 88 88zM224 88c22.0557 0 40 17.9443 40 40s-17.9443 40 -40 40s-40 -17.9443 -40 -40s17.9443 -40 40 -40z" />
|
||||
<glyph glyph-name="square" unicode="" horiz-adv-x="448"
|
||||
d="M400 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352zM394 16c3.2998 0 6 2.7002 6 6v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340z" />
|
||||
<glyph glyph-name="envelope" unicode=""
|
||||
@@ -181,7 +181,7 @@ c-22.5439 -17.748 -60.3359 -55.1787 -103.053 -54.9473c-42.9277 -0.231445 -81.205
|
||||
<glyph glyph-name="lightbulb" unicode="" horiz-adv-x="352"
|
||||
d="M176 368c8.83984 0 16 -7.16016 16 -16s-7.16016 -16 -16 -16c-35.2803 0 -64 -28.7002 -64 -64c0 -8.83984 -7.16016 -16 -16 -16s-16 7.16016 -16 16c0 52.9404 43.0596 96 96 96zM96.0596 -11.1699l-0.0400391 43.1797h159.961l-0.0507812 -43.1797
|
||||
c-0.00976562 -3.13965 -0.939453 -6.21973 -2.67969 -8.83984l-24.5098 -36.8398c-2.95996 -4.45996 -7.95996 -7.14062 -13.3203 -7.14062h-78.8496c-5.35059 0 -10.3506 2.68066 -13.3203 7.14062l-24.5098 36.8398c-1.75 2.62012 -2.68066 5.68945 -2.68066 8.83984z
|
||||
M176 448c97.2002 0 176 -78.7998 176 -176c0 -44.3701 -16.4502 -84.8496 -43.5498 -115.79c-16.6406 -18.9795 -42.7402 -58.79 -52.4199 -92.1602v-0.0498047h-48v0.0996094c0.00390625 4.04199 0.999023 10.4482 2.21973 14.3008
|
||||
M176 448c97.2002 0 176 -78.7998 176 -176c0 -44.3701 -16.4502 -84.8496 -43.5498 -115.79c-16.6406 -18.9795 -42.7402 -58.79 -52.4199 -92.1602v-0.0498047h-48v0.0996094c0.00488281 4.98145 0.790039 9.78809 2.21973 14.3008
|
||||
c5.67969 17.9893 22.9902 64.8496 62.0996 109.46c20.4102 23.29 31.6504 53.1699 31.6504 84.1396c0 70.5801 -57.4199 128 -128 128c-68.2803 0 -128.15 -54.3604 -127.95 -128c0.0898438 -30.9902 11.0703 -60.71 31.6104 -84.1396
|
||||
c39.3496 -44.9004 56.5801 -91.8604 62.1699 -109.67c1.42969 -4.56055 2.13965 -9.30078 2.15039 -14.0703v-0.120117h-48v0.0595703c-9.68066 33.3604 -35.7803 73.1709 -52.4209 92.1602c-27.1094 30.9307 -43.5596 71.4102 -43.5596 115.78
|
||||
c0 93.0303 73.7197 176 176 176z" />
|
||||
@@ -241,13 +241,13 @@ c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0683594l22.5361 -22.7178c4.66699 -4.
|
||||
<glyph glyph-name="share-square" unicode="" horiz-adv-x="576"
|
||||
d="M561.938 289.94c18.75 -18.7402 18.75 -49.1406 0 -67.8809l-143.998 -144c-29.9727 -29.9727 -81.9404 -9.05273 -81.9404 33.9404v53.7998c-101.266 -7.83691 -99.625 -31.6406 -84.1104 -78.7598c14.2285 -43.0889 -33.4736 -79.248 -71.0195 -55.7402
|
||||
c-51.6924 32.3057 -84.8701 83.0635 -84.8701 144.76c0 39.3408 12.2197 72.7402 36.3301 99.3008c19.8398 21.8398 47.7402 38.4697 82.9102 49.4199c36.7295 11.4395 78.3096 16.1094 120.76 17.9893v57.1982c0 42.9355 51.9258 63.9541 81.9404 33.9404zM384 112l144 144
|
||||
l-144 144v-104.09c-110.86 -0.90332 -240 -10.5166 -240 -119.851c0 -52.1396 32.79 -85.6094 62.3096 -104.06c-39.8174 120.65 48.999 141.918 177.69 143.84v-103.84zM408.74 27.5068c6.14844 1.75684 15.5449 5.92383 20.9736 9.30273
|
||||
l-144 144v-104.09c-110.86 -0.90332 -240 -10.5166 -240 -119.851c0 -52.1396 32.79 -85.6094 62.3096 -104.06c-39.8174 120.65 48.999 141.918 177.69 143.84v-103.84zM408.74 27.5068c7.4375 2.125 14.5508 5.30566 20.9736 9.30273
|
||||
c7.97656 4.95215 18.2861 -0.825195 18.2861 -10.2139v-42.5957c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h132c6.62695 0 12 -5.37305 12 -12v-4.48633c0 -4.91699 -2.9873 -9.36914 -7.56934 -11.1514
|
||||
c-13.7021 -5.33105 -26.3955 -11.5371 -38.0498 -18.585c-1.59668 -0.974609 -4.41016 -1.77051 -6.28027 -1.77734h-86.1006c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340c3.31152 0 6 2.68848 6 6v25.9658c0 5.37012 3.5791 10.0596 8.74023 11.541
|
||||
z" />
|
||||
c-13.7021 -5.33105 -26.3955 -11.5371 -38.0498 -18.585c-1.82715 -1.11523 -3.98633 -1.76953 -6.28027 -1.77734h-86.1006c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340c3.31152 0 6 2.68848 6 6v25.9658c0 5.37012 3.5791 10.0596 8.74023 11.541z
|
||||
" />
|
||||
<glyph glyph-name="compass" unicode="" horiz-adv-x="496"
|
||||
d="M347.94 318.14c16.6592 7.61035 33.8096 -9.54004 26.1992 -26.1992l-65.9697 -144.341c-2.73047 -5.97363 -9.7959 -13.0391 -15.7695 -15.7695l-144.341 -65.9697c-16.6592 -7.61035 -33.8096 9.5498 -26.1992 26.1992l65.9697 144.341
|
||||
c2.73047 5.97363 9.7959 13.0391 15.7695 15.7695zM270.58 169.42c12.4697 12.4697 12.4697 32.6904 0 45.1602s-32.6904 12.4697 -45.1602 0s-12.4697 -32.6904 0 -45.1602s32.6904 -12.4697 45.1602 0zM248 440c136.97 0 248 -111.03 248 -248s-111.03 -248 -248 -248
|
||||
d="M347.94 318.14c16.6592 7.61035 33.8096 -9.54004 26.1992 -26.1992l-65.9697 -144.341c-3.19238 -6.9834 -8.78613 -12.5771 -15.7695 -15.7695l-144.341 -65.9697c-16.6592 -7.61035 -33.8096 9.5498 -26.1992 26.1992l65.9697 144.341
|
||||
c3.19238 6.9834 8.78613 12.5771 15.7695 15.7695zM270.58 169.42c12.4697 12.4697 12.4697 32.6904 0 45.1602s-32.6904 12.4697 -45.1602 0s-12.4697 -32.6904 0 -45.1602s32.6904 -12.4697 45.1602 0zM248 440c136.97 0 248 -111.03 248 -248s-111.03 -248 -248 -248
|
||||
s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
|
||||
<glyph glyph-name="caret-square-down" unicode="" horiz-adv-x="448"
|
||||
d="M125.1 240h197.801c10.6992 0 16.0996 -13 8.5 -20.5l-98.9004 -98.2998c-4.7002 -4.7002 -12.2002 -4.7002 -16.9004 0l-98.8994 98.2998c-7.7002 7.5 -2.2998 20.5 8.39941 20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
@@ -287,7 +287,7 @@ l40.4004 -59.8994l70.8994 13.6992c13 2.60059 26.6006 -1.59961 36.2002 -11.0996c9
|
||||
l-91 17.5996l17.5996 -91.2002l-76.7998 -52l76.7998 -52l-17.5996 -91.1992l90.8994 17.5996l51.9004 -77l51.9004 76.9004l91 -17.6006zM256 296c57.2998 0 104 -46.7002 104 -104s-46.7002 -104 -104 -104s-104 46.7002 -104 104s46.7002 104 104 104zM256 136
|
||||
c30.9004 0 56 25.0996 56 56s-25.0996 56 -56 56s-56 -25.0996 -56 -56s25.0996 -56 56 -56z" />
|
||||
<glyph glyph-name="moon" unicode=""
|
||||
d="M279.135 -64c-141.424 0 -256 114.64 -256 256c0 141.425 114.641 256 256 256c13.0068 -0.00195312 33.9443 -1.91797 46.7354 -4.27734c44.0205 -8.13086 53.7666 -66.8691 15.0215 -88.9189c-41.374 -23.5439 -67.4336 -67.4121 -67.4336 -115.836
|
||||
d="M279.135 -64c-141.424 0 -256 114.64 -256 256c0 141.425 114.641 256 256 256c16.0342 -0.00292969 31.5078 -1.46875 46.7354 -4.27734c44.0205 -8.13086 53.7666 -66.8691 15.0215 -88.9189c-41.374 -23.5439 -67.4336 -67.4121 -67.4336 -115.836
|
||||
c0 -83.5234 75.9238 -146.475 158.272 -130.792c43.6904 8.32129 74.5186 -42.5693 46.248 -77.4004c-47.8613 -58.9717 -120.088 -94.7754 -198.844 -94.7754zM279.135 400c-114.875 0 -208 -93.125 -208 -208s93.125 -208 208 -208
|
||||
c65.2314 0 123.439 30.0361 161.575 77.0244c-111.611 -21.2568 -215.252 64.0957 -215.252 177.943c0 67.5127 36.9326 126.392 91.6934 157.555c-12.3271 2.27637 -25.0312 3.47754 -38.0166 3.47754z" />
|
||||
<glyph glyph-name="caret-square-left" unicode="" horiz-adv-x="448"
|
||||
@@ -334,12 +334,12 @@ c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -1
|
||||
c-33.2002 0 -58 30.4004 -51.4004 62.9004l19.7002 97.0996v32h32v-32h22.1006c5.7998 0 10.6992 -4.09961 11.7998 -9.7002zM160.3 57.9004c17.9004 0 32.4004 12.0996 32.4004 27c0 14.8994 -14.5 27 -32.4004 27c-17.8994 0 -32.3994 -12.1006 -32.3994 -27
|
||||
c0 -14.9004 14.5 -27 32.3994 -27zM192.3 256v-32h-32v32h32z" />
|
||||
<glyph glyph-name="file-audio" unicode="" horiz-adv-x="384"
|
||||
d="M369.941 350.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM332.118 320
|
||||
d="M369.941 350.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM332.118 320
|
||||
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM192 60.0244c0 -10.6914 -12.9258 -16.0459 -20.4854 -8.48535l-35.5146 35.9746h-28c-6.62695 0 -12 5.37305 -12 12v56c0 6.62695 5.37305 12 12 12h28
|
||||
l35.5146 36.9473c7.56055 7.56055 20.4854 2.20605 20.4854 -8.48535v-135.951zM233.201 107.154c9.05078 9.29688 9.05957 24.1328 0.000976562 33.4385c-22.1494 22.752 12.2344 56.2461 34.3945 33.4814c27.1982 -27.9404 27.2119 -72.4443 0.000976562 -100.401
|
||||
c-21.793 -22.3857 -56.9463 10.3154 -34.3965 33.4814z" />
|
||||
<glyph glyph-name="file-video" unicode="" horiz-adv-x="384"
|
||||
d="M369.941 350.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM332.118 320
|
||||
d="M369.941 350.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM332.118 320
|
||||
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM276.687 195.303c10.0049 10.0049 27.3135 2.99707 27.3135 -11.3135v-111.976c0 -14.2939 -17.2959 -21.332 -27.3135 -11.3135l-52.6865 52.6738v-37.374
|
||||
c0 -11.0459 -8.9541 -20 -20 -20h-104c-11.0459 0 -20 8.9541 -20 20v104c0 11.0459 8.9541 20 20 20h104c11.0459 0 20 -8.9541 20 -20v-37.374z" />
|
||||
<glyph glyph-name="file-code" unicode="" horiz-adv-x="384"
|
||||
@@ -376,9 +376,9 @@ c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -41.3604 6.03027 -70.7197 14.33
|
||||
c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
|
||||
<glyph glyph-name="copyright" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
|
||||
M363.351 93.0645c-9.61328 -9.71289 -45.5293 -41.3965 -104.064 -41.3965c-82.4297 0 -140.484 61.4248 -140.484 141.567c0 79.1514 60.2754 139.4 139.763 139.4c55.5303 0 88.7373 -26.6201 97.5928 -34.7783c2.13379 -1.96289 3.86523 -5.9082 3.86523 -8.80762
|
||||
c0 -1.95508 -0.864258 -4.87402 -1.92969 -6.51465l-18.1543 -28.1133c-3.8418 -5.9502 -11.9668 -7.28223 -17.499 -2.9209c-8.5957 6.77637 -31.8145 22.5381 -61.708 22.5381c-48.3037 0 -77.916 -35.3301 -77.916 -80.082c0 -41.5889 26.8877 -83.6924 78.2764 -83.6924
|
||||
c32.6572 0 56.8428 19.0391 65.7266 27.2256c5.26953 4.85645 13.5957 4.03906 17.8193 -1.73828l19.8652 -27.1699c1.28613 -1.74512 2.33008 -4.91992 2.33008 -7.08789c0 -2.72363 -1.56055 -6.5 -3.48242 -8.42969z" />
|
||||
M363.351 93.0645c-9.61328 -9.71289 -45.5293 -41.3965 -104.064 -41.3965c-82.4297 0 -140.484 61.4248 -140.484 141.567c0 79.1514 60.2754 139.4 139.763 139.4c55.5303 0 88.7373 -26.6201 97.5928 -34.7783c2.37793 -2.1875 3.86914 -5.3252 3.86914 -8.80762
|
||||
c0 -2.39746 -0.717773 -4.64258 -1.93359 -6.51465l-18.1543 -28.1133c-3.8418 -5.9502 -11.9668 -7.28223 -17.499 -2.9209c-8.5957 6.77637 -31.8145 22.5381 -61.708 22.5381c-48.3037 0 -77.916 -35.3301 -77.916 -80.082c0 -41.5889 26.8877 -83.6924 78.2764 -83.6924
|
||||
c32.6572 0 56.8428 19.0391 65.7266 27.2256c5.26953 4.85645 13.5957 4.03906 17.8193 -1.73828l19.8652 -27.1699c1.45996 -1.98145 2.32422 -4.42969 2.32422 -7.07715c0 -3.28809 -1.32422 -6.2793 -3.47656 -8.44043z" />
|
||||
<glyph glyph-name="closed-captioning" unicode=""
|
||||
d="M464 384c26.5 0 48 -21.5 48 -48v-288c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h416zM458 48c3.2998 0 6 2.7002 6 6v276c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-276c0 -3.2998 2.7002 -6 6 -6h404z
|
||||
M246.9 133.7c1.69922 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.6006 -56.7998 -172.801 -32.0996 -172.801 67.9004c0 97.2998 121.7 119.5 172.5 70.0996c2.10059 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.89941 -3.09961 -6.19922 -4 -9.09961 -1.7002
|
||||
@@ -398,7 +398,7 @@ c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-12v-24h88v12c
|
||||
h-32v-32h32zM96 136h224v12c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-12zM224 0v32h-32v-32h32zM504 64v160h-12c-6.62695 0 -12 5.37305 -12 12v12
|
||||
h-88v-88h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-88v-24h12c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h12zM544 0v32h-32v-32h32zM544 256v32h-32v-32h32z" />
|
||||
<glyph glyph-name="sticky-note" unicode="" horiz-adv-x="448"
|
||||
d="M448 99.8936c0 -10.9746 -6.29883 -26.1797 -14.0586 -33.9404l-83.8828 -83.8818c-7.75977 -7.76074 -22.9658 -14.0596 -33.9404 -14.0596h-268.118c-26.5098 0 -48 21.4902 -48 48v351.988c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48v-268.106z
|
||||
d="M448 99.8936c0 -13.2451 -5.37012 -25.252 -14.0586 -33.9404l-83.8828 -83.8818c-8.68848 -8.68848 -20.6943 -14.0596 -33.9404 -14.0596h-268.118c-26.5098 0 -48 21.4902 -48 48v351.988c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48v-268.106z
|
||||
M320 19.8936l76.1182 76.1182h-76.1182v-76.1182zM400 368h-352v-351.988h224v104c0 13.2549 10.7451 24 24 24h104v223.988z" />
|
||||
<glyph glyph-name="clone" unicode=""
|
||||
d="M464 448c26.5098 0 48 -21.4902 48 -48v-320c0 -26.5098 -21.4902 -48 -48 -48h-48v-48c0 -26.5098 -21.4902 -48 -48 -48h-320c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h48v48c0 26.5098 21.4902 48 48 48h320zM362 -16c3.31152 0 6 2.68848 6 6
|
||||
@@ -412,11 +412,11 @@ d="M408.864 368.948c48.8213 20.751 103.136 -15.0723 103.136 -67.9111v-114.443c0
|
||||
c-17.6729 0 -32 14.3271 -32 32c0 27.3301 1.1416 29.2012 -3.11035 32.9033l-97.71 85.0811c-24.8994 21.6797 -39.1797 52.8926 -39.1797 85.6338v56.9531c0 47.4277 44.8457 82.0215 91.0459 71.1807c1.96094 55.751 63.5107 87.8262 110.671 60.8057
|
||||
c29.1895 31.0713 78.8604 31.4473 108.334 -0.0214844c32.7051 18.6846 76.4121 10.3096 98.8135 -23.5879zM464 186.594v114.445c0 34.29 -52 33.8232 -52 0.676758c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v26.751
|
||||
c0 34.457 -52 33.707 -52 0.676758v-27.4287c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v40.4658c0 34.3525 -52 33.8115 -52 0.677734v-41.1436c0 -8.83594 -7.16406 -16 -16 -16h-7c-8.83594 0 -16 7.16406 -16 16v26.751
|
||||
c0 34.4023 -52 33.7744 -52 0.676758v-116.571c0 -8.83203 -7.16797 -16 -16 -16c-3.30664 0 -8.01367 1.7627 -10.5068 3.93359l-7 6.09473c-3.03223 2.64062 -5.49316 8.04688 -5.49316 12.0674v0v41.2275c0 34.2148 -52 33.8857 -52 0.677734v-56.9531
|
||||
c0 -18.8555 8.27441 -36.874 22.7002 -49.4365l97.71 -85.0801c12.4502 -10.8398 19.5898 -26.4463 19.5898 -42.8164v-10.2861h220v7.07617c0 13.21 2.65332 26.0791 7.88281 38.25l42.835 99.6553c2.91602 6.75391 5.28223 18.207 5.28223 25.5635v0.0488281z" />
|
||||
c0 34.4023 -52 33.7744 -52 0.676758v-116.571c0 -8.83105 -7.17773 -15.9961 -16.0078 -15.9961c-4.0166 0 -7.68848 1.48242 -10.499 3.92969l-7 6.09473c-3.37012 2.93457 -5.49316 7.25293 -5.49316 12.0674v41.2275c0 34.2148 -52 33.8857 -52 0.677734v-56.9531
|
||||
c0 -18.8555 8.27441 -36.874 22.7002 -49.4365l97.71 -85.0801c12.4502 -10.8398 19.5898 -26.4463 19.5898 -42.8164v-10.2861h220v7.07617c0 13.21 2.65332 26.0791 7.88281 38.25l42.835 99.6553c3.37891 7.82715 5.28223 16.501 5.28223 25.5625v0.0498047z" />
|
||||
<glyph glyph-name="hand-paper" unicode="" horiz-adv-x="448"
|
||||
d="M372.57 335.359c39.9062 5.63281 75.4297 -25.7393 75.4297 -66.3594v-131.564c-0.00195312 -12.7666 -2.33008 -33.2246 -5.19531 -45.666l-30.1836 -130.958c-3.34668 -14.5234 -16.2783 -24.8125 -31.1816 -24.8125h-222.897
|
||||
c-9.10352 0 -20.7793 6.01758 -26.0615 13.4316l-119.97 168.415c-21.2441 29.8203 -14.8047 71.3574 14.5498 93.1533c18.7754 13.9395 42.1309 16.2979 62.083 8.87109v126.13c0 44.0547 41.125 75.5439 82.4053 64.9834c23.8926 48.1963 92.3535 50.2471 117.982 0.74707
|
||||
d="M372.57 335.359c39.9062 5.63281 75.4297 -25.7393 75.4297 -66.3594v-131.564c-0.00292969 -15.7393 -1.80566 -30.9482 -5.19531 -45.666l-30.1836 -130.958c-3.34668 -14.5234 -16.2783 -24.8125 -31.1816 -24.8125h-222.897
|
||||
c-10.7539 0 -20.2588 5.28613 -26.0615 13.4316l-119.97 168.415c-21.2441 29.8203 -14.8047 71.3574 14.5498 93.1533c18.7754 13.9395 42.1309 16.2979 62.083 8.87109v126.13c0 44.0547 41.125 75.5439 82.4053 64.9834c23.8926 48.1963 92.3535 50.2471 117.982 0.74707
|
||||
c42.5186 11.1445 83.0391 -21.9346 83.0391 -65.5469v-10.8242zM399.997 137.437l-0.00195312 131.563c0 24.9492 -36.5703 25.5508 -36.5703 -0.691406v-76.3086c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v154.184
|
||||
c0 25.501 -36.5703 26.3633 -36.5703 0.691406v-154.875c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v188.309c0 25.501 -36.5703 26.3545 -36.5703 0.691406v-189c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16
|
||||
v153.309c0 25.501 -36.5713 26.3359 -36.5713 0.691406v-206.494c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832l-27.1279 38.0791c-14.3711 20.1709 -43.833 -2.33496 -29.3945 -22.6045l115.196 -161.697h201.92l27.3252 118.551
|
||||
@@ -424,45 +424,46 @@ c2.63086 11.417 3.96484 23.1553 3.96484 34.8857z" />
|
||||
<glyph glyph-name="hand-scissors" unicode=""
|
||||
d="M256 -32c-44.9561 0 -77.3428 43.2627 -64.0244 85.8535c-21.6484 13.71 -34.0156 38.7617 -30.3408 65.0068h-87.6348c-40.8037 0 -74 32.8105 -74 73.1406c0 40.3291 33.1963 73.1396 74 73.1396l94 -9.14062l-78.8496 18.6787
|
||||
c-38.3076 14.7422 -57.04 57.4707 -41.9424 95.1123c15.0303 37.4736 57.7549 55.7803 95.6416 41.2012l144.929 -55.7568c24.9551 30.5566 57.8086 43.9932 92.2178 24.7324l97.999 -54.8525c20.9746 -11.7393 34.0049 -33.8457 34.0049 -57.6904v-205.702
|
||||
c0 -30.7422 -21.4404 -57.5576 -51.7979 -64.5537l-118.999 -27.4268c-4.97168 -1.14648 -10.0889 -1.72949 -15.2031 -1.72949zM256 16.0127l70 -0.000976562c1.23633 0 3.21777 0.225586 4.42285 0.501953l119.001 27.4277
|
||||
c8.58203 1.97754 14.5762 9.29102 14.5762 17.7812v205.701c0 6.4873 -3.62109 12.542 -9.44922 15.8047l-98 54.8545c-8.13965 4.55566 -18.668 2.61914 -24.4873 -4.50781l-21.7646 -26.6475c-2.65039 -3.24512 -8.20215 -5.87891 -12.3926 -5.87891
|
||||
c-1.64062 0 -4.21484 0.477539 -5.74609 1.06738l-166.549 64.0908c-32.6543 12.5664 -50.7744 -34.5771 -19.2227 -46.7168l155.357 -59.7852c5.66016 -2.17773 10.2539 -8.86816 10.2539 -14.9326v0v-11.6328c0 -8.83691 -7.16309 -16 -16 -16h-182
|
||||
c0 -30.7422 -21.4404 -57.5576 -51.7979 -64.5537l-118.999 -27.4268c-4.97168 -1.14648 -10.0889 -1.72949 -15.2031 -1.72949zM256 16.0127l70 -0.000976562c1.52441 0 2.99707 0.174805 4.42285 0.501953l119.001 27.4277
|
||||
c8.58203 1.97754 14.5762 9.29102 14.5762 17.7812v205.701c0 6.4873 -3.62109 12.542 -9.44922 15.8047l-98 54.8545c-8.13965 4.55566 -18.668 2.61914 -24.4873 -4.50781l-21.7646 -26.6475c-2.93457 -3.59375 -7.40332 -5.87305 -12.4004 -5.87305
|
||||
c-2.02246 0 -3.95703 0.375977 -5.73828 1.06152l-166.549 64.0908c-32.6543 12.5664 -50.7744 -34.5771 -19.2227 -46.7168l155.357 -59.7852c6 -2.30859 10.2539 -8.12402 10.2539 -14.9326v-11.6328c0 -8.83691 -7.16309 -16 -16 -16h-182
|
||||
c-34.375 0 -34.4297 -50.2803 0 -50.2803h182c8.83691 0 16 -7.16309 16 -16v-6.85645c0 -8.83691 -7.16309 -16 -16 -16h-28c-25.1221 0 -25.1592 -36.5674 0 -36.5674h28c8.83691 0 16 -7.16211 16 -16v-6.85547c0 -8.83691 -7.16309 -16 -16 -16
|
||||
c-25.1201 0 -25.1602 -36.5674 0 -36.5674z" />
|
||||
<glyph glyph-name="hand-lizard" unicode="" horiz-adv-x="576"
|
||||
d="M556.686 157.458c12.6357 -19.4863 19.3145 -42.0615 19.3145 -65.2871v-124.171h-224v71.582l-99.751 38.7871c-2.7832 1.08203 -5.70996 1.63086 -8.69727 1.63086h-131.552c-30.8789 0 -56 25.1211 -56 56c0 48.5234 39.4766 88 88 88h113.709l18.333 48h-196.042
|
||||
c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.084 -12.2725 60.4111 -32.8291zM528 16v76.1709v0.0478516c0 11.7461 -5.19141 29.2734 -11.5879 39.124l-146.358 225.715c-4.44336 6.85254 -11.9707 10.9424 -20.1367 10.9424h-293.917
|
||||
c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8
|
||||
h131.552h0.0517578c7.44141 0 19.1074 -2.19238 26.041 -4.89355l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
|
||||
c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.084 -12.2725 60.4111 -32.8291zM528 16v76.1709c0 0.0166016 -0.0439453 0.106445 -0.0439453 0.12207c0 14.3945 -4.24219 27.8057 -11.5439 39.0498l-146.358 225.715
|
||||
c-4.44336 6.85254 -11.9707 10.9424 -20.1367 10.9424h-293.917c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709
|
||||
c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8h131.552c0.0175781 0 0.0712891 -0.0273438 0.0888672 -0.0273438c9.16992 0 17.9404 -1.72461 26.0039 -4.86621l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
|
||||
<glyph glyph-name="hand-spock" unicode=""
|
||||
d="M501.03 331.824c6.05762 -9.77832 10.9746 -27.0498 10.9746 -38.5518c0 -4.80664 -0.915039 -12.499 -2.04297 -17.1709l-57.623 -241.963c-12.748 -54.1729 -68.2627 -98.1387 -123.915 -98.1387h-0.345703h-107.455h-0.224609
|
||||
c-33.8135 0 -81.2148 18.834 -105.807 42.041l-91.3652 85.9766c-12.8213 12.0469 -23.2266 36.1016 -23.2266 53.6943c0 16.1299 8.97266 38.7529 20.0273 50.499c5.31836 5.66406 29.875 29.3926 68.1152 21.8477l-24.3594 82.1973
|
||||
c-1.68164 5.66406 -3.0459 15.0576 -3.0459 20.9668c0 37.5938 30.417 70.502 67.8955 73.4551c-0.204102 2.03125 -0.369141 5.33691 -0.369141 7.37891c0 31.627 24.8594 63.6895 55.4902 71.5684c43.248 10.9785 80.5645 -17.7012 89.6602 -53.0723l13.6836 -53.207
|
||||
l4.64648 22.6602c6.76074 32.417 39.123 58.8115 72.2373 58.916c8.73438 0 56.625 -3.26953 70.7383 -54.0801c15.0664 0.710938 46.9199 -3.50977 66.3105 -35.0176zM463.271 287.219c7.86914 32.9844 -42.1211 45.2695 -50.0859 11.9219l-24.8008 -104.146
|
||||
c-4.38867 -18.4141 -31.7783 -11.8926 -28.0557 6.2168l28.5479 139.166c7.39844 36.0703 -43.3076 45.0703 -50.1182 11.9629l-31.791 -154.971c-3.54883 -17.3086 -28.2832 -18.0469 -32.7109 -0.804688l-47.3262 184.035
|
||||
c-8.43359 32.8105 -58.3691 20.2676 -49.8652 -12.8359l42.4414 -165.039c4.81641 -18.7207 -23.3711 -26.9121 -28.9648 -8.00781l-31.3438 105.779c-9.6875 32.6465 -59.1191 18.2578 -49.3867 -14.625l36.0137 -121.539
|
||||
c5.61816 -18.9521 10.1777 -50.377 10.1777 -70.1436v-0.00878906c0 -6.54297 -8.05664 -10.9355 -13.4824 -5.82617l-51.123 48.1074c-24.7852 23.4082 -60.0527 -14.1875 -35.2793 -37.4902l91.3691 -85.9805c16.9629 -16.0068 49.6592 -28.998 72.9824 -28.998h0.154297
|
||||
h107.455h0.216797c34.7402 0 69.3936 27.4443 77.3525 61.2598z" />
|
||||
d="M501.03 331.824c6.92773 -11.1826 10.9697 -24.4053 10.9697 -38.5146c0 -5.92676 -0.706055 -11.6885 -2.03809 -17.208l-57.623 -241.963c-13.2236 -56.1904 -63.707 -98.1387 -123.908 -98.1387h-0.352539h-107.455
|
||||
c-0.0761719 0 -0.193359 0.00195312 -0.270508 0.00195312c-40.9248 0 -78.1475 15.9814 -105.761 42.0391l-91.3652 85.9766c-14.3076 13.4434 -23.2246 32.5547 -23.2246 53.7168c0 19.5254 7.61035 37.2861 20.0254 50.4766
|
||||
c5.31836 5.66406 29.875 29.3926 68.1152 21.8477l-24.3594 82.1973c-1.97363 6.64844 -2.97656 13.6836 -2.97656 20.9688c0 38.6953 29.8926 70.4639 67.8262 73.4531c-0.246094 2.45117 -0.34082 4.85547 -0.34082 7.37207c0 34.4199 23.585 63.376 55.4619 71.5752
|
||||
c43.248 10.9785 80.5645 -17.7012 89.6602 -53.0723l13.6836 -53.207l4.64648 22.6602c6.99023 33.5186 36.6826 58.8037 72.2373 58.916c8.73438 0 56.625 -3.26953 70.7383 -54.0801c15.0664 0.710938 46.9199 -3.50977 66.3105 -35.0176zM463.271 287.219
|
||||
c7.86914 32.9844 -42.1211 45.2695 -50.0859 11.9219l-24.8008 -104.146c-4.38867 -18.4141 -31.7783 -11.8926 -28.0557 6.2168l28.5479 139.166c7.39844 36.0703 -43.3076 45.0703 -50.1182 11.9629l-31.791 -154.971
|
||||
c-3.54883 -17.3086 -28.2832 -18.0469 -32.7109 -0.804688l-47.3262 184.035c-8.43359 32.8105 -58.3691 20.2676 -49.8652 -12.8359l42.4414 -165.039c4.81641 -18.7207 -23.3711 -26.9121 -28.9648 -8.00781l-31.3438 105.779
|
||||
c-9.6875 32.6465 -59.1191 18.2578 -49.3867 -14.625l36.0137 -121.539c6.59375 -22.2441 10.1777 -45.7803 10.1777 -70.1523c0 -6.54297 -8.05664 -10.9355 -13.4824 -5.82617l-51.123 48.1074c-24.7852 23.4082 -60.0527 -14.1875 -35.2793 -37.4902l91.3691 -85.9805
|
||||
c19.0469 -17.9736 44.75 -28.998 72.9795 -28.998h0.157227h107.455c0.0732422 0 0.138672 0.0429688 0.212891 0.0429688c37.5791 0 69.1016 26.1416 77.3564 61.2168z" />
|
||||
<glyph glyph-name="hand-pointer" unicode="" horiz-adv-x="448"
|
||||
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -4.25 -0.775391 -11.0615 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286c-21.2588 0 -41.3682 10.4102 -53.791 27.8457
|
||||
l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289
|
||||
c27.1934 12.8467 60.3799 5.66992 79.8721 -19.0986zM80.9854 168.303c-14.4004 20.2119 -43.8008 -2.38281 -29.3945 -22.6055l109.712 -154c3.43457 -4.81934 8.92871 -7.69727 14.6973 -7.69727h178.285c8.49219 0 15.8037 5.99414 17.7822 14.5762l27.4297 119.001
|
||||
c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285v84c0 25.1602 -36.5713 25.1211 -36.5713 0c0 -8.83594 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16406 -16 16v21c0 25.1602 -36.5713 25.1201 -36.5713 0v-21c0 -8.83594 -7.16309 -16 -16 -16h-6.85938
|
||||
c-8.83691 0 -16 7.16406 -16 16v35c0 25.1602 -36.5703 25.1201 -36.5703 0v-35c0 -8.83594 -7.16309 -16 -16 -16h-6.85742c-8.83691 0 -16 7.16406 -16 16v175c0 25.1602 -36.5713 25.1201 -36.5713 0v-241.493c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832z
|
||||
M176.143 48v96c0 8.83691 6.26855 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM251.571 48v96c0 8.83691 6.26758 16 14 16h6c7.73145 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26855 -16 -14 -16h-6
|
||||
c-7.73242 0 -14 7.16309 -14 16zM327 48v96c0 8.83691 6.26758 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16z" />
|
||||
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -5.24023 -0.600586 -10.3037 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286
|
||||
c-21.2588 0 -41.3682 10.4102 -53.791 27.8457l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338
|
||||
c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289c27.1934 12.8467 60.3799 5.66992 79.8721 -19.0986zM80.9854 168.303c-14.4004 20.2119 -43.8008 -2.38281 -29.3945 -22.6055l109.712 -154c3.43457 -4.81934 8.92871 -7.69727 14.6973 -7.69727h178.285
|
||||
c8.49219 0 15.8037 5.99414 17.7822 14.5762l27.4297 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285v84c0 25.1602 -36.5713 25.1211 -36.5713 0c0 -8.83594 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16406 -16 16v21
|
||||
c0 25.1602 -36.5713 25.1201 -36.5713 0v-21c0 -8.83594 -7.16309 -16 -16 -16h-6.85938c-8.83691 0 -16 7.16406 -16 16v35c0 25.1602 -36.5703 25.1201 -36.5703 0v-35c0 -8.83594 -7.16309 -16 -16 -16h-6.85742c-8.83691 0 -16 7.16406 -16 16v175
|
||||
c0 25.1602 -36.5713 25.1201 -36.5713 0v-241.493c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832zM176.143 48v96c0 8.83691 6.26855 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM251.571 48v96
|
||||
c0 8.83691 6.26758 16 14 16h6c7.73145 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26855 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM327 48v96c0 8.83691 6.26758 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6
|
||||
c-7.73242 0 -14 7.16309 -14 16z" />
|
||||
<glyph glyph-name="hand-peace" unicode="" horiz-adv-x="448"
|
||||
d="M362.146 256.024c42.5908 13.3184 85.8535 -19.0684 85.8535 -64.0244l-0.0117188 -70.001c-0.000976562 -4.25 -0.775391 -11.0615 -1.72949 -15.2031l-27.4268 -118.999c-6.99707 -30.3564 -33.8105 -51.7969 -64.5547 -51.7969h-205.702
|
||||
d="M362.146 256.024c42.5908 13.3184 85.8535 -19.0684 85.8535 -64.0244l-0.0117188 -70.001c-0.000976562 -5.24023 -0.600586 -10.3027 -1.72949 -15.2031l-27.4268 -118.999c-6.99707 -30.3564 -33.8105 -51.7969 -64.5547 -51.7969h-205.702
|
||||
c-23.8447 0 -45.9502 13.0303 -57.6904 34.0059l-54.8525 97.999c-19.2607 34.4092 -5.82422 67.2617 24.7324 92.2178l-55.7568 144.928c-14.5791 37.8867 3.72754 80.6113 41.2012 95.6416c37.6406 15.0977 80.3691 -3.63477 95.1123 -41.9424l18.6787 -78.8496
|
||||
l-9.14062 94c0 40.8037 32.8096 74 73.1396 74s73.1406 -33.1963 73.1406 -74v-87.6348c26.2451 3.6748 51.2959 -8.69238 65.0068 -30.3408zM399.987 122l-0.000976562 70c0 25.1602 -36.5674 25.1201 -36.5674 0c0 -8.83691 -7.16309 -16 -16 -16h-6.85547
|
||||
c-8.83789 0 -16 7.16309 -16 16v28c0 25.1592 -36.5674 25.1221 -36.5674 0v-28c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v182c0 34.4297 -50.2803 34.375 -50.2803 0v-182c0 -8.83691 -7.16309 -16 -16 -16h-11.6328v0
|
||||
c-6.06445 0 -12.7549 4.59375 -14.9326 10.2539l-59.7842 155.357c-12.1396 31.5518 -59.2842 13.4326 -46.7168 -19.2227l64.0898 -166.549c0.589844 -1.53125 1.06738 -4.10547 1.06738 -5.74609c0 -4.19043 -2.63379 -9.74219 -5.87891 -12.3926l-26.6475 -21.7646
|
||||
c-8.83789 0 -16 7.16309 -16 16v28c0 25.1592 -36.5674 25.1221 -36.5674 0v-28c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v182c0 34.4297 -50.2803 34.375 -50.2803 0v-182c0 -8.83691 -7.16309 -16 -16 -16h-11.6328
|
||||
c-6.80859 0 -12.624 4.25391 -14.9326 10.2539l-59.7842 155.357c-12.1396 31.5518 -59.2842 13.4326 -46.7168 -19.2227l64.0898 -166.549c0.685547 -1.78125 1.07812 -3.71875 1.07812 -5.74121c0 -4.99707 -2.2959 -9.46289 -5.88965 -12.3975l-26.6475 -21.7646
|
||||
c-7.12695 -5.81934 -9.06445 -16.3467 -4.50781 -24.4873l54.8535 -98c3.26367 -5.82812 9.31934 -9.44922 15.8057 -9.44922h205.701c8.49121 0 15.8037 5.99414 17.7812 14.5762l27.4277 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285z" />
|
||||
<glyph glyph-name="registered" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
|
||||
M366.442 73.791c4.40332 -7.99219 -1.37012 -17.791 -10.5107 -17.791h-42.8096h-0.0126953c-3.97559 0 -8.71582 2.84961 -10.5801 6.36035l-47.5156 89.3027h-31.958v-83.6631c0 -6.61719 -5.38281 -12 -12 -12h-38.5674c-6.61719 0 -12 5.38281 -12 12v248.304
|
||||
c0 6.61719 5.38281 12 12 12h78.667c71.251 0 101.498 -32.749 101.498 -85.252c0 -31.6123 -15.2148 -59.2969 -39.4824 -73.1758c3.02148 -4.61719 0.225586 0.199219 53.2715 -96.085zM256.933 208.094c20.9131 0 32.4307 11.5186 32.4316 32.4316
|
||||
c0 19.5752 -6.5127 31.709 -38.9297 31.709h-27.377v-64.1406h33.875z" />
|
||||
M366.442 73.791c4.40332 -7.99219 -1.37012 -17.791 -10.5107 -17.791h-42.8096c-0.00488281 0 -0.000976562 -0.0126953 -0.00585938 -0.0126953c-4.58594 0 -8.57422 2.58301 -10.5869 6.37305l-47.5156 89.3027h-31.958v-83.6631c0 -6.61719 -5.38281 -12 -12 -12
|
||||
h-38.5674c-6.61719 0 -12 5.38281 -12 12v248.304c0 6.61719 5.38281 12 12 12h78.667c71.251 0 101.498 -32.749 101.498 -85.252c0 -31.6123 -15.2148 -59.2969 -39.4824 -73.1758c3.02148 -4.61719 0.225586 0.199219 53.2715 -96.085zM256.933 208.094
|
||||
c20.9131 0 32.4307 11.5186 32.4316 32.4316c0 19.5752 -6.5127 31.709 -38.9297 31.709h-27.377v-64.1406h33.875z" />
|
||||
<glyph glyph-name="calendar-plus" unicode="" horiz-adv-x="448"
|
||||
d="M336 156v-24c0 -6.59961 -5.40039 -12 -12 -12h-76v-76c0 -6.59961 -5.40039 -12 -12 -12h-24c-6.59961 0 -12 5.40039 -12 12v76h-76c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h76v76c0 6.59961 5.40039 12 12 12h24c6.59961 0 12 -5.40039 12 -12
|
||||
v-76h76c6.59961 0 12 -5.40039 12 -12zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40
|
||||
@@ -481,9 +482,9 @@ c6.62695 0 12 -5.37305 12 -12v-52h48zM394 -16c3.31152 0 6 2.68848 6 6v298h-352v-
|
||||
c-4.66699 4.70508 -4.6377 12.3027 0.0673828 16.9707l22.7197 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l44.1035 -44.4609l111.072 110.182c4.70508 4.66699 12.3027 4.63672 16.9707 -0.0683594l22.5361 -22.7178
|
||||
c4.66699 -4.70508 4.63672 -12.3027 -0.0683594 -16.9697z" />
|
||||
<glyph glyph-name="map" unicode="" horiz-adv-x="576"
|
||||
d="M560.02 416c8.4502 0 15.9805 -6.83008 15.9805 -16.0195v-346.32c0 -11.9609 -9.01367 -25.2705 -20.1201 -29.71l-151.83 -52.8105c-5.32617 -1.7334 -14.1953 -3.13965 -19.7969 -3.13965c-5.7373 0 -14.8105 1.47363 -20.2529 3.29004l-172 60.71l-170.05 -62.8398
|
||||
c-1.99023 -0.790039 -4 -1.16016 -5.95996 -1.16016c-8.45996 0 -15.9902 6.83008 -15.9902 16.0195v346.32c0.00292969 11.959 9.0166 25.2686 20.1201 29.71l151.83 52.8105c6.43945 2.08984 13.1201 3.13965 19.8096 3.13965
|
||||
c5.73242 -0.00195312 14.8008 -1.47168 20.2402 -3.28027l172 -60.7197h0.00976562l170.05 62.8398c1.98047 0.790039 4 1.16016 5.95996 1.16016zM224 357.58v-285.97l128 -45.1904v285.97zM48 29.9502l127.36 47.0801l0.639648 0.229492v286.2l-128 -44.5303v-288.979z
|
||||
d="M560.02 416c8.4502 0 15.9805 -6.83008 15.9805 -16.0195v-346.32c0 -13.4707 -8.32422 -24.9951 -20.1201 -29.71l-151.83 -52.8105c-6.23242 -2.02832 -12.9023 -3.12305 -19.8076 -3.12305c-7.07324 0 -13.8799 1.15039 -20.2422 3.27344l-172 60.71l-170.05 -62.8398
|
||||
c-1.99023 -0.790039 -4 -1.16016 -5.95996 -1.16016c-8.45996 0 -15.9902 6.83008 -15.9902 16.0195v346.32c0.00292969 13.4697 8.32617 24.9932 20.1201 29.71l151.83 52.8105c6.43945 2.08984 13.1201 3.13965 19.8096 3.13965
|
||||
c7.06641 -0.00292969 13.8789 -1.16602 20.2402 -3.28027l172 -60.7197h0.00976562l170.05 62.8398c1.98047 0.790039 4 1.16016 5.95996 1.16016zM224 357.58v-285.97l128 -45.1904v285.97zM48 29.9502l127.36 47.0801l0.639648 0.229492v286.2l-128 -44.5303v-288.979z
|
||||
M528 65.0801v288.97l-127.36 -47.0693l-0.639648 -0.240234v-286.19z" />
|
||||
<glyph glyph-name="comment-alt" unicode=""
|
||||
d="M448 448c35.2998 0 64 -28.7002 64 -64v-288c0 -35.2998 -28.7002 -64 -64 -64h-144l-124.9 -93.5996c-2.19922 -1.7002 -4.69922 -2.40039 -7.09961 -2.40039c-6.2002 0 -12 4.90039 -12 12v84h-96c-35.2998 0 -64 28.7002 -64 64v288c0 35.2998 28.7002 64 64 64h384z
|
||||
@@ -497,16 +498,16 @@ c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h160c8.7998 0 16 -7.200
|
||||
<glyph glyph-name="handshake" unicode="" horiz-adv-x="640"
|
||||
d="M519.2 320.1h120.8v-255.699h-64c-17.5 0 -31.7998 14.1992 -31.9004 31.6992h-57.8994c-1.7998 -8.19922 -5.2998 -16.0996 -10.9004 -23l-26.2002 -32.2998c-15.7998 -19.3994 -41.8994 -25.5 -64 -16.7998c-13.5 -16.5996 -30.5996 -24 -48.7998 -24
|
||||
c-15.0996 0 -28.5996 5.09961 -41.0996 15.9004c-31.7998 -21.9004 -74.7002 -21.3008 -105.601 3.7998l-84.5996 76.3994h-9.09961c-0.100586 -17.5 -14.3008 -31.6992 -31.9004 -31.6992h-64v255.699h118l47.5996 47.6006c10.5 10.3994 24.8008 16.2998 39.6006 16.2998
|
||||
h226.8v0c12.7812 0 30.5225 -7.30273 39.5996 -16.2998zM48 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16zM438 103.3c2.7002 3.40039 2.2002 8.5 -1.2002 11.2998l-108.2 87.8008l-8.19922 -7.5
|
||||
h226.8c15.4326 0 29.4326 -6.22168 39.5996 -16.2998zM48 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16zM438 103.3c2.7002 3.40039 2.2002 8.5 -1.2002 11.2998l-108.2 87.8008l-8.19922 -7.5
|
||||
c-40.3008 -36.8008 -86.7002 -11.8008 -101.5 4.39941c-26.7002 29 -25 74.4004 4.39941 101.3l38.7002 35.5h-56.7002c-2 -0.799805 -3.7002 -1.5 -5.7002 -2.2998l-61.6992 -61.5996h-41.9004v-128.101h27.7002l97.2998 -88
|
||||
c16.0996 -13.0996 41.4004 -10.5 55.2998 6.60059l15.6006 19.2002l36.7998 -31.5c3 -2.40039 12 -4.90039 18 2.39941l30 36.5l23.8994 -19.3994c3.5 -2.80078 8.5 -2.2002 11.3008 1.19922zM544 144.1v128h-44.7002l-61.7002 61.6006
|
||||
c-1.39941 1.5 -3.39941 2.2998 -5.5 2.2998l-83.6992 -0.200195c-10 0 -19.6006 -3.7002 -27 -10.5l-65.6006 -60.0996c-9.7002 -8.7998 -10.5 -24 -1.2002 -33.9004c8.90039 -9.39941 25.1006 -8.7002 34.6006 0l55.2002 50.6006c6.5 5.89941 16.5996 5.5 22.5996 -1
|
||||
l10.9004 -11.7002c6 -6.5 5.5 -16.6006 -1 -22.6006l-12.5 -11.3994l102.699 -83.4004c2.80078 -2.2998 5.40039 -4.89941 7.7002 -7.7002h69.2002zM592 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16z
|
||||
" />
|
||||
<glyph glyph-name="envelope-open" unicode=""
|
||||
d="M494.586 283.484c9.6123 -7.94824 17.4141 -24.5205 17.4141 -36.9932v-262.491c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v262.515c0 12.5166 7.84668 29.1279 17.5146 37.0771c4.08008 3.35449 110.688 89.0996 135.15 108.549
|
||||
c22.6992 18.1426 60.1299 55.8594 103.335 55.8594c43.4365 0 81.2314 -38.1914 103.335 -55.8594c23.5283 -18.707 130.554 -104.773 135.251 -108.656zM464 -10v253.632v0.00488281c0 1.5791 -0.996094 3.66602 -2.22363 4.6582
|
||||
c-15.8633 12.8232 -108.793 87.5752 -132.366 106.316c-17.5527 14.0195 -49.7168 45.3887 -73.4102 45.3887c-23.6016 0 -55.2451 -30.8799 -73.4102 -45.3887c-23.5713 -18.7393 -116.494 -93.4795 -132.364 -106.293
|
||||
d="M494.586 283.484c10.6523 -8.80762 17.4141 -22.1064 17.4141 -36.9932v-262.491c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v262.515c0 14.9355 6.80469 28.2705 17.5146 37.0771c4.08008 3.35449 110.688 89.0996 135.15 108.549
|
||||
c22.6992 18.1426 60.1299 55.8594 103.335 55.8594c43.4365 0 81.2314 -38.1914 103.335 -55.8594c23.5283 -18.707 130.554 -104.773 135.251 -108.656zM464 -10v253.632c0 0.00195312 0.00390625 0.000976562 0.00390625 0.00292969
|
||||
c0 1.88184 -0.869141 3.56152 -2.22754 4.66016c-15.8633 12.8232 -108.793 87.5752 -132.366 106.316c-17.5527 14.0195 -49.7168 45.3887 -73.4102 45.3887c-23.6016 0 -55.2451 -30.8799 -73.4102 -45.3887c-23.5713 -18.7393 -116.494 -93.4795 -132.364 -106.293
|
||||
c-1.40918 -1.13965 -2.22559 -2.85254 -2.22559 -4.66504v-253.653c0 -3.31152 2.68848 -6 6 -6h404c3.31152 0 6 2.68848 6 6zM432.009 177.704c4.24902 -5.15918 3.46484 -12.7949 -1.74512 -16.9814c-28.9746 -23.2822 -59.2734 -47.5967 -70.9287 -56.8623
|
||||
c-22.6992 -18.1436 -60.1299 -55.8604 -103.335 -55.8604c-43.4521 0 -81.2871 38.2373 -103.335 55.8604c-11.2793 8.9668 -41.7441 33.4131 -70.9268 56.8643c-5.20996 4.1875 -5.99316 11.8223 -1.74512 16.9814l15.2578 18.5283
|
||||
c4.17773 5.07227 11.6572 5.84277 16.7793 1.72559c28.6182 -23.001 58.5654 -47.0352 70.5596 -56.5713c17.5527 -14.0195 49.7168 -45.3887 73.4102 -45.3887c23.6016 0 55.2461 30.8799 73.4102 45.3887c11.9941 9.53516 41.9434 33.5703 70.5625 56.5684
|
||||
@@ -555,10 +556,11 @@ c6.09961 -6.2002 6.09961 -16.4004 0 -22.6006l-58.2998 -59.2998v-84.5l71.8994 42.
|
||||
c7.5 4.39941 17.2002 1.7998 21.5 -5.90039l7.90039 -13.9004c4.2998 -7.69922 1.7002 -17.5 -5.7998 -21.8994l-39.2002 -23l34.0996 -9.2998c8.40039 -2.30078 13.3008 -11.1006 11.1006 -19.6006l-4.10059 -15.5c-2.2998 -8.5 -10.8994 -13.5996 -19.2998 -11.2998
|
||||
l-79.7002 21.7002l-71.8994 -42.2002l71.7998 -42.2002l79.7002 21.7002c8.39941 2.2998 17.0996 -2.7998 19.2998 -11.2998l4.09961 -15.5c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.6006l-34.0996 -9.2998z" />
|
||||
<glyph glyph-name="trash-alt" unicode="" horiz-adv-x="448"
|
||||
d="M268 32c-6.62402 0 -12 5.37598 -12 12v216c0 6.62402 5.37598 12 12 12h24c6.62402 0 12 -5.37598 12 -12v-216c0 -6.62402 -5.37598 -12 -12 -12h-24zM432 368c8.83203 0 16 -7.16797 16 -16v-16c0 -8.83203 -7.16797 -16 -16 -16h-16v-336
|
||||
c0 -26.4961 -21.5039 -48 -48 -48h-288c-26.4961 0 -48 21.5039 -48 48v336h-16c-8.83203 0 -16 7.16797 -16 16v16c0 8.83203 7.16797 16 16 16h82.4102l34.0195 56.7002c7.71875 12.8613 26.1572 23.2998 41.1572 23.2998h0.00292969h100.82h0.0224609
|
||||
c15 0 33.4385 -10.4385 41.1572 -23.2998l34 -56.7002h82.4102zM171.84 397.09l-17.4502 -29.0898h139.221l-17.46 29.0898c-0.96582 1.60645 -3.26953 2.91016 -5.14355 2.91016h-0.00683594h-94h-0.0166016c-1.87402 0 -4.17871 -1.30371 -5.14355 -2.91016zM368 -16v336
|
||||
h-288v-336h288zM156 32c-6.62402 0 -12 5.37598 -12 12v216c0 6.62402 5.37598 12 12 12h24c6.62402 0 12 -5.37598 12 -12v-216c0 -6.62402 -5.37598 -12 -12 -12h-24z" />
|
||||
d="M268 32c-6.62305 0 -12 5.37695 -12 12v216c0 6.62305 5.37695 12 12 12h24c6.62305 0 12 -5.37695 12 -12v-216c0 -6.62305 -5.37695 -12 -12 -12h-24zM432 368c8.83105 0 16 -7.16895 16 -16v-16c0 -8.83105 -7.16895 -16 -16 -16h-16v-336
|
||||
c0 -26.4922 -21.5078 -48 -48 -48h-288c-26.4922 0 -48 21.5078 -48 48v336h-16c-8.83105 0 -16 7.16895 -16 16v16c0 8.83105 7.16895 16 16 16h82.4102l34.0195 56.7002c8.39258 13.9844 23.6777 23.2998 41.1602 23.2998h100.82
|
||||
c0.0078125 0 -0.015625 0.0517578 -0.0078125 0.0517578c17.4824 0 32.7949 -9.36719 41.1875 -23.3516l34 -56.7002h82.4102zM171.84 397.09l-17.4502 -29.0898h139.221l-17.46 29.0898c-1.0498 1.74707 -2.95898 2.91016 -5.14355 2.91016h-0.00683594h-94
|
||||
c-0.00585938 0 -0.00683594 0.00683594 -0.0126953 0.00683594c-2.18457 0 -4.09766 -1.16992 -5.14746 -2.91699zM368 -16v336h-288v-336h288zM156 32c-6.62305 0 -12 5.37695 -12 12v216c0 6.62305 5.37695 12 12 12h24c6.62305 0 12 -5.37695 12 -12v-216
|
||||
c0 -6.62305 -5.37695 -12 -12 -12h-24z" />
|
||||
<glyph glyph-name="images" unicode="" horiz-adv-x="576"
|
||||
d="M480 32v-16c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256c0 26.5098 21.4902 48 48 48h16v-48h-10c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v10h48zM522 368h-372
|
||||
c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v244c0 3.31152 -2.68848 6 -6 6zM528 416c26.5098 0 48 -21.4902 48 -48v-256c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256
|
||||
@@ -584,9 +586,9 @@ d="M464 448c4.09961 0 7.7998 -2 10.0996 -5.40039l99.9004 -147.199c2.90039 -4.400
|
||||
c2.2002 3.40039 6 5.40039 10 5.40039h352zM444.7 400h-56.7998l51.6992 -96h68.4004zM242.6 400l-51.5996 -96h194l-51.7002 96h-90.7002zM131.3 400l-63.2998 -96h68.4004l51.6992 96h-56.7998zM88.2998 256l119.7 -160l-68.2998 160h-51.4004zM191.2 256l96.7998 -243.3
|
||||
l96.7998 243.3h-193.6zM368 96l119.6 160h-51.3994z" />
|
||||
<glyph glyph-name="money-bill-alt" unicode="" horiz-adv-x="640"
|
||||
d="M320 304c53.0195 0 96 -50.1396 96 -112c0 -61.8701 -43 -112 -96 -112c-53.0195 0 -96 50.1504 -96 112c0 61.8604 42.9805 112 96 112zM360 136v16c0 4.41992 -3.58008 8 -8 8h-16v88c0 4.41992 -3.58008 8 -8 8h-13.5801h-0.000976562
|
||||
c-4.01074 0 -9.97266 -1.80566 -13.3086 -4.03027l-15.3301 -10.2197c-1.96777 -1.30957 -3.56445 -4.29004 -3.56445 -6.65332c0 -1.33691 0.601562 -3.32422 1.34375 -4.43652l8.88086 -13.3105c1.30859 -1.9668 4.29004 -3.56445 6.65332 -3.56445
|
||||
c1.33691 0 3.32422 0.602539 4.43652 1.34473l0.469727 0.310547v-55.4404h-16c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h64c4.41992 0 8 3.58008 8 8zM608 384c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-576
|
||||
d="M320 304c53.0195 0 96 -50.1396 96 -112c0 -61.8701 -43 -112 -96 -112c-53.0195 0 -96 50.1504 -96 112c0 61.8604 42.9805 112 96 112zM360 136v16c0 4.41992 -3.58008 8 -8 8h-16v88c0 4.41992 -3.58008 8 -8 8h-13.5801
|
||||
c-4.91113 0 -9.50586 -1.49316 -13.3096 -4.03027l-15.3301 -10.2197c-2.15332 -1.43262 -3.55957 -3.88379 -3.55957 -6.66113c0 -1.6377 0.493164 -3.16113 1.33887 -4.42871l8.88086 -13.3105c1.43164 -2.15234 3.88379 -3.55957 6.66113 -3.55957
|
||||
c1.6377 0 3.16016 0.494141 4.42871 1.33984l0.469727 0.310547v-55.4404h-16c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h64c4.41992 0 8 3.58008 8 8zM608 384c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-576
|
||||
c-17.6699 0 -32 14.3301 -32 32v320c0 17.6699 14.3301 32 32 32h576zM592 112v160c-35.3496 0 -64 28.6504 -64 64h-416c0 -35.3496 -28.6504 -64 -64 -64v-160c35.3496 0 64 -28.6504 64 -64h416c0 35.3496 28.6504 64 64 64z" />
|
||||
<glyph glyph-name="window-close" unicode=""
|
||||
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v340c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z
|
||||
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
BIN
dist/qmi-cloud/fa-regular-400.woff
vendored
BIN
dist/qmi-cloud/fa-regular-400.woff2
vendored
|
Before Width: | Height: | Size: 829 KiB After Width: | Height: | Size: 893 KiB |
BIN
dist/qmi-cloud/fa-solid-900.c500da19d776384ba695.woff2
vendored
Normal file
BIN
dist/qmi-cloud/fa-solid-900.ee09ad7553b8ad3d8115.woff
vendored
Normal file
BIN
dist/qmi-cloud/fa-solid-900.woff
vendored
BIN
dist/qmi-cloud/fa-solid-900.woff2
vendored
|
Before Width: | Height: | Size: 434 KiB After Width: | Height: | Size: 434 KiB |
4
dist/qmi-cloud/index.html
vendored
@@ -6,8 +6,8 @@
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" href="assets/favicon.ico">
|
||||
</head>
|
||||
<link rel="stylesheet" href="styles.b2e9059fb6aa834811ea.css"></head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
<script src="runtime.js" defer></script><script src="polyfills-es5.js" nomodule defer></script><script src="polyfills.js" defer></script><script src="styles.js" defer></script><script src="scripts.js" defer></script><script src="vendor.js" defer></script><script src="main.js" defer></script></body>
|
||||
<script src="runtime.c51bd5b1c616d9ffddc1.js" defer></script><script src="polyfills-es5.6fef7e679f78bcc42760.js" nomodule defer></script><script src="polyfills.51f5cc3d1309de3a873d.js" defer></script><script src="scripts.1af868998801499c8755.js" defer></script><script src="main.5c4c2f7e4461741ce9f1.js" defer></script></body>
|
||||
</html>
|
||||
|
||||
1
dist/qmi-cloud/main.5c4c2f7e4461741ce9f1.js
vendored
Normal file
5459
dist/qmi-cloud/main.js
vendored
1
dist/qmi-cloud/main.js.map
vendored
1
dist/qmi-cloud/polyfills-es5.6fef7e679f78bcc42760.js
vendored
Normal file
14575
dist/qmi-cloud/polyfills-es5.js
vendored
1
dist/qmi-cloud/polyfills-es5.js.map
vendored
1
dist/qmi-cloud/polyfills.51f5cc3d1309de3a873d.js
vendored
Normal file
6848
dist/qmi-cloud/polyfills.js
vendored
1
dist/qmi-cloud/polyfills.js.map
vendored
1
dist/qmi-cloud/runtime.c51bd5b1c616d9ffddc1.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){function r(r){for(var n,l,f=r[0],i=r[1],p=r[2],c=0,s=[];c<f.length;c++)l=f[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(a&&a(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,f=1;f<t.length;f++)0!==o[t[f]]&&(n=!1);n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={0:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,(function(r){return e[r]}).bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="";var f=window.webpackJsonp=window.webpackJsonp||[],i=f.push.bind(f);f.push=r,f=f.slice();for(var p=0;p<f.length;p++)r(f[p]);var a=i;t()}([]);
|
||||
155
dist/qmi-cloud/runtime.js
vendored
@@ -1,155 +0,0 @@
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // install a JSONP callback for chunk loading
|
||||
/******/ function webpackJsonpCallback(data) {
|
||||
/******/ var chunkIds = data[0];
|
||||
/******/ var moreModules = data[1];
|
||||
/******/ var executeModules = data[2];
|
||||
/******/
|
||||
/******/ // add "moreModules" to the modules object,
|
||||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
/******/ var moduleId, chunkId, i = 0, resolves = [];
|
||||
/******/ for(;i < chunkIds.length; i++) {
|
||||
/******/ chunkId = chunkIds[i];
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
|
||||
/******/ resolves.push(installedChunks[chunkId][0]);
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ for(moduleId in moreModules) {
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
|
||||
/******/ modules[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
|
||||
/******/
|
||||
/******/ while(resolves.length) {
|
||||
/******/ resolves.shift()();
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // add entry modules from loaded chunk to deferred list
|
||||
/******/ deferredModules.push.apply(deferredModules, executeModules || []);
|
||||
/******/
|
||||
/******/ // run deferred modules when all chunks ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ };
|
||||
/******/ function checkDeferredModules() {
|
||||
/******/ var result;
|
||||
/******/ for(var i = 0; i < deferredModules.length; i++) {
|
||||
/******/ var deferredModule = deferredModules[i];
|
||||
/******/ var fulfilled = true;
|
||||
/******/ for(var j = 1; j < deferredModule.length; j++) {
|
||||
/******/ var depId = deferredModule[j];
|
||||
/******/ if(installedChunks[depId] !== 0) fulfilled = false;
|
||||
/******/ }
|
||||
/******/ if(fulfilled) {
|
||||
/******/ deferredModules.splice(i--, 1);
|
||||
/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ return result;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // object to store loaded and loading chunks
|
||||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||
/******/ // Promise = chunk loading, 0 = chunk loaded
|
||||
/******/ var installedChunks = {
|
||||
/******/ "runtime": 0
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ var deferredModules = [];
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = function(exports) {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // create a fake namespace object
|
||||
/******/ // mode & 1: value is a module id, require it
|
||||
/******/ // mode & 2: merge all properties of value into the ns
|
||||
/******/ // mode & 4: return value when already ns object
|
||||
/******/ // mode & 8|1: behave like require
|
||||
/******/ __webpack_require__.t = function(value, mode) {
|
||||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||||
/******/ if(mode & 8) return value;
|
||||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||||
/******/ var ns = Object.create(null);
|
||||
/******/ __webpack_require__.r(ns);
|
||||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||||
/******/ return ns;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
|
||||
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
|
||||
/******/ jsonpArray.push = webpackJsonpCallback;
|
||||
/******/ jsonpArray = jsonpArray.slice();
|
||||
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
|
||||
/******/ var parentJsonpFunction = oldJsonpFunction;
|
||||
/******/
|
||||
/******/
|
||||
/******/ // run deferred modules from other chunks
|
||||
/******/ checkDeferredModules();
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([]);
|
||||
//# sourceMappingURL=runtime.js.map
|
||||
1
dist/qmi-cloud/runtime.js.map
vendored
1
dist/qmi-cloud/scripts.1af868998801499c8755.js
vendored
Normal file
20176
dist/qmi-cloud/scripts.js
vendored
1
dist/qmi-cloud/scripts.js.map
vendored
80
dist/qmi-cloud/styles.b2e9059fb6aa834811ea.css
vendored
Normal file
659
dist/qmi-cloud/styles.js
vendored
1
dist/qmi-cloud/styles.js.map
vendored
201117
dist/qmi-cloud/vendor.js
vendored
1
dist/qmi-cloud/vendor.js.map
vendored
@@ -56,6 +56,7 @@ services:
|
||||
target: config.json
|
||||
environment:
|
||||
- HOSTNAME_URL=http://localhost:3000
|
||||
- BACKEND_LOGS_URL=http://localhost:8888
|
||||
- REDIS_URL=redis://redis
|
||||
- MONGO_URI=mongodb://root:example@mongo/qmicloud?authSource=admin
|
||||
- CERT_PFX_FILENAME=
|
||||
@@ -75,6 +76,7 @@ services:
|
||||
# -------------------
|
||||
- ../qmi-cloud-provisions:/provisions
|
||||
- ./logs:/logs
|
||||
- ./costexport:/var/www/app/costexport
|
||||
#- ./certs:/var/www/app/server/certs
|
||||
depends_on:
|
||||
- mongo
|
||||
@@ -127,5 +129,16 @@ services:
|
||||
ME_CONFIG_MONGODB_ADMINPASSWORD: example
|
||||
ME_CONFIG_BASICAUTH_USERNAME: qlik
|
||||
ME_CONFIG_BASICAUTH_PASSWORD: Qlik1234
|
||||
networks:
|
||||
- backend
|
||||
|
||||
dozzle:
|
||||
image: amir20/dozzle:latest
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
ports:
|
||||
- 8888:8080
|
||||
#environment:
|
||||
# DOZZLE_BASE: "/dozzle"
|
||||
networks:
|
||||
- backend
|
||||
@@ -22,7 +22,8 @@ echo "--- Building image: qlikgear/qmi-cloud-cli:$TAG_CLI"
|
||||
docker build -f ./qmi-cloud-cli/Dockerfile -t qlikgear/qmi-cloud-cli:$TAG_CLI ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-cli:$TAG_CLI"
|
||||
docker push qlikgear/qmi-cloud-cli:$TAG_CLI
|
||||
docker build -f ./qmi-cloud-cli/Dockerfile -t qlikgear/qmi-cloud-cli:$STABLE_TAG ./
|
||||
docker image tag qlikgear/qmi-cloud-cli:$TAG_CLI qlikgear/qmi-cloud-cli:$STABLE_TAG
|
||||
#docker build -f ./qmi-cloud-cli/Dockerfile -t qlikgear/qmi-cloud-cli:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-cli:$STABLE_TAG
|
||||
|
||||
|
||||
@@ -30,12 +31,14 @@ echo "--- Building image: qlikgear/qmi-cloud-worker:$TAG_WORKER"
|
||||
docker build -f ./qmi-cloud-worker/Dockerfile -t qlikgear/qmi-cloud-worker:$TAG_WORKER ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-worker:$TAG_WORKER"
|
||||
docker push qlikgear/qmi-cloud-worker:$TAG_WORKER
|
||||
docker build -f ./qmi-cloud-worker/Dockerfile -t qlikgear/qmi-cloud-worker:$STABLE_TAG ./
|
||||
docker image tag qlikgear/qmi-cloud-worker:$TAG_WORKER qlikgear/qmi-cloud-worker:$STABLE_TAG
|
||||
#docker build -f ./qmi-cloud-worker/Dockerfile -t qlikgear/qmi-cloud-worker:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-worker:$STABLE_TAG
|
||||
|
||||
echo "--- Building image: qlikgear/qmi-cloud-app:$TAG_APP"
|
||||
docker build -f ./Dockerfile -t qlikgear/qmi-cloud-app:$TAG_APP ./
|
||||
echo "--- Pushing image: qlikgear/qmi-cloud-app:$TAG_APP"
|
||||
docker push qlikgear/qmi-cloud-app:$TAG_APP
|
||||
docker build -f ./Dockerfile -t qlikgear/qmi-cloud-app:$STABLE_TAG ./
|
||||
docker image tag qlikgear/qmi-cloud-app:$TAG_APP qlikgear/qmi-cloud-app:$STABLE_TAG
|
||||
#docker build -f ./Dockerfile -t qlikgear/qmi-cloud-app:$STABLE_TAG ./
|
||||
docker push qlikgear/qmi-cloud-app:$STABLE_TAG
|
||||
|
||||
89
mystatsmashup/index.html
Normal file
@@ -0,0 +1,89 @@
|
||||
<!doctype html>
|
||||
<!-- <html qva-bootstrap="false" lang="en"> -->
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>Simple html with qdt-components</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta http-equiv="cleartype" content="on">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
|
||||
<link rel="shortcut icon" href="favicon.ico" />
|
||||
<!-- <script type="text/javascript" src="https://qdt-apps.qlik.com/qdt-components/v3/3.0.0/qdt-components.js"></script> -->
|
||||
<script type="text/javascript" src="qdt-components.js"></script>
|
||||
<script type="text/javascript" src="index.js"></script>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
div.qvobject {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 10px 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body onload="init()">
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="currentselections" style="width: 100%;height: 40px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div id="filterstatus" style="width: 100%;height: 40px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div id="totalprovkpi" class="qvobject"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div id="costhismonth" class="qvobject"></div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div id="statusprov" class="qvobject"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="qdt1" class="qvobject"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<div id="qdt1a" class="qvobject"></div>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<div id="qdt3" class="qvobject"></div>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<div id="qdt4" class="qvobject"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
119
mystatsmashup/index.js
Normal file
@@ -0,0 +1,119 @@
|
||||
// https://help.qlik.com/en-US/sense-developer/June2020/Subsystems/Mashups/Content/Sense_Mashups/mashups-authentication-cloud.htm
|
||||
// https://qlik.dev/tutorials/build-a-simple-web-app
|
||||
const config = {
|
||||
host: "gear-presales.eu.qlikcloud.com",
|
||||
secure: true,
|
||||
port: 443,
|
||||
prefix: "",
|
||||
webIntegrationId: 'n4kMLH62hvXXC84q2vdfW15WUvrUw-HU',
|
||||
appId: "2d03e11f-f3d8-4ba7-a123-be5a282fb9f1"
|
||||
}
|
||||
const urlLoggedIn = "/api/v1/audits";//Use GET request to see if you are authenticated
|
||||
const urlLogin = "/login";
|
||||
|
||||
const init = async () => {
|
||||
const response = await fetch(`https://${config.host}${urlLoggedIn}`, {
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Qlik-Web-Integration-ID': config.webIntegrationId
|
||||
}
|
||||
})
|
||||
if(response.status===401){
|
||||
const url = new URL(`https://${config.host}/login`);
|
||||
url.searchParams.append('returnto', 'http://localhost:3000/mystats');
|
||||
url.searchParams.append('qlik-web-integration-id', config.webIntegrationId);
|
||||
window.location.href = url;
|
||||
}
|
||||
const { qdtCapabilityApp, QdtViz } = QdtComponents;
|
||||
const capabilityApiAppPromise = qdtCapabilityApp(config);
|
||||
const app = await capabilityApiAppPromise;
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('currentselections'),
|
||||
app,
|
||||
options: {
|
||||
id: 'CurrentSelections',
|
||||
height: "40px"
|
||||
},
|
||||
});
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('qdt1'),
|
||||
app,
|
||||
options: {
|
||||
type: 'table',
|
||||
id: 'mCjaU',
|
||||
height: "300px"
|
||||
},
|
||||
});
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('qdt1a'),
|
||||
app,
|
||||
options: {
|
||||
type: "piechart",
|
||||
id: 'XrnNdj',
|
||||
height: "300px"
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('qdt3'),
|
||||
app,
|
||||
options: {
|
||||
type: "linechart",
|
||||
id: 'QfYrJj',
|
||||
height: "300px"
|
||||
},
|
||||
});
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('qdt4'),
|
||||
app,
|
||||
options: {
|
||||
type: "barchart",
|
||||
id: 'JvSJCW',
|
||||
height: "300px"
|
||||
},
|
||||
});
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('totalprovkpi'),
|
||||
app,
|
||||
options: {
|
||||
id: 'zWDmhfq',
|
||||
height: "100px"
|
||||
},
|
||||
});
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('filterstatus'),
|
||||
app,
|
||||
options: {
|
||||
id: 'uznaVCC',
|
||||
height: "40px"
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('costhismonth'),
|
||||
app,
|
||||
options: {
|
||||
type: "kpi",
|
||||
id: "GkRz",
|
||||
height: "100px"
|
||||
},
|
||||
});
|
||||
|
||||
QdtViz({
|
||||
element: document.getElementById('statusprov'),
|
||||
app,
|
||||
options: {
|
||||
id: 'kXyQPa',
|
||||
height: "150px"
|
||||
},
|
||||
});
|
||||
}
|
||||
135423
mystatsmashup/qdt-components.js
Normal file
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-app",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.8",
|
||||
"scripts": {
|
||||
"start": "node -r esm server/server.js",
|
||||
"start:dev": "nodemon -r esm server/server.js",
|
||||
|
||||
@@ -13,9 +13,12 @@ const fetch = require('node-fetch');
|
||||
|
||||
|
||||
const IS_REAL = myArgs[2] !== 'test';
|
||||
const STOPPED_PERIOD = myArgs[1]; //Days
|
||||
const STOPPED_LIMIT_HOURS_WARNING = 24*(STOPPED_PERIOD-2); //Hours
|
||||
const STOPPED_LIMIT_HOURS_STOP = 24*STOPPED_PERIOD; //Hours
|
||||
const STOPPED_PERIOD = myArgs[1]; //20 Days
|
||||
const STOPPED_PERIOD_IS_EXTERNAL = Math.ceil(myArgs[1]/2); //10 Days
|
||||
const WARNING_DAYS = 2;
|
||||
|
||||
//---
|
||||
|
||||
const API_KEY = process.env.API_KEY;
|
||||
const SERVER_URL = "http://localhost:3000";
|
||||
|
||||
@@ -56,18 +59,16 @@ async function asyncForEach(array, callback) {
|
||||
}
|
||||
|
||||
async function init(type) {
|
||||
var limit, cb;
|
||||
var cb;
|
||||
var filter = {
|
||||
"isDestroyed":false,
|
||||
"isDeleted": false,
|
||||
"statusVms": "Stopped"
|
||||
};
|
||||
if ( type === "warning" ) {
|
||||
limit = STOPPED_LIMIT_HOURS_WARNING;
|
||||
filter.pendingNextAction = {$ne: "destroy"};
|
||||
cb = doSendEmailDestroyWarning;
|
||||
} else if ( type === "exec" ) {
|
||||
limit = STOPPED_LIMIT_HOURS_STOP;
|
||||
filter.pendingNextAction = "destroy";
|
||||
cb = doDestroy;
|
||||
} else {
|
||||
@@ -76,42 +77,45 @@ async function init(type) {
|
||||
}
|
||||
|
||||
let provisions = await db.provision.get(filter);
|
||||
let scenarios = await db.scenario.get();
|
||||
|
||||
await asyncForEach(provisions.results, async function(p) {
|
||||
var _scenario = scenarios.results.filter(s=>{
|
||||
return s.name === p.scenario
|
||||
});
|
||||
if ( _scenario.length ){
|
||||
p._scenario = _scenario[0];
|
||||
var typeSchedule = "24x7";
|
||||
if ( p.schedule && !p.schedule.is24x7 ) {
|
||||
typeSchedule = 'OnSchedule';
|
||||
}
|
||||
timeRunning(p);
|
||||
if (!IS_REAL) {
|
||||
console.log(`${p._id} - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
|
||||
var limit;
|
||||
if ( type === "warning" ) {
|
||||
limit = p.isExternalAccess? 24*(STOPPED_PERIOD_IS_EXTERNAL-WARNING_DAYS) : 24*(STOPPED_PERIOD-WARNING_DAYS);
|
||||
} else if ( type === "exec" ) {
|
||||
limit = p.isExternalAccess? (24*STOPPED_PERIOD_IS_EXTERNAL) : (24*STOPPED_PERIOD);
|
||||
}
|
||||
if ( !IS_REAL ) {
|
||||
console.log(`${p._id} (${typeSchedule}) - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
|
||||
}
|
||||
if ( p.duration && p.duration.hours >= limit) {
|
||||
await cb(p);
|
||||
await cb(p, limit, typeSchedule);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const doSendEmailDestroyWarning = async function(p) {
|
||||
const doSendEmailDestroyWarning = async function(p, limit, typeSchedule) {
|
||||
if ( p.pendingNextAction === 'destroy') {
|
||||
console.log(`Warning email Destroy already sent. Wait for pending action to complete.`);
|
||||
} else {
|
||||
let msg = `Send warning DESTROY email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenario.title}' (${p._id}) being 'Inactive' more than ${STOPPED_LIMIT_HOURS_WARNING} hours (exactly ${p.duration.complete})`;
|
||||
let msg = `Send warning DESTROY email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Inactive' more than ${limit} hours, (exactly ${p.duration.complete})`;
|
||||
console.log(msg);
|
||||
if ( IS_REAL ) {
|
||||
await db.provision.update(p._id, {"pendingNextAction": "destroy"});
|
||||
await sendEmail.sendWillDestroyIn24(p, p._scenario);
|
||||
await sendEmail.sendWillDestroyIn24(p, p._scenarioDoc, Math.floor(limit/24), WARNING_DAYS);
|
||||
await db.notification.add({ provision: p._id.toString(), type: 'warningDestroy', message: msg });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const doDestroy = async function(p) {
|
||||
const doDestroy = async function(p, limit, typeSchedule) {
|
||||
try {
|
||||
let msg = `Provision destroyed - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenario.title}' (${p._id}) being 'Inactive' more than ${STOPPED_LIMIT_HOURS_STOP} hours (exactly ${p.duration.complete})`
|
||||
let msg = `Provision destroyed - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Inactive' more than ${limit} hours (exactly ${p.duration.complete})`
|
||||
console.log(msg);
|
||||
if ( IS_REAL ) {
|
||||
await postDestroy(p);
|
||||
|
||||
@@ -7,21 +7,21 @@ if ( myArgs.length < 3 ) {
|
||||
}
|
||||
|
||||
const IS_REAL = myArgs[2] !== 'test';
|
||||
const RUNNING_PERIOD = myArgs[1]; //Days
|
||||
const RUNNING_LIMIT_HOURS_WARNING = 24*(RUNNING_PERIOD-1);
|
||||
const RUNNING_LIMIT_HOURS_STOP = 24*RUNNING_PERIOD;
|
||||
|
||||
const RUNNING_PERIOD = myArgs[1]; // 7 Days
|
||||
const RUNNING_PERIOD_ON_SCHEDULE = Math.ceil(myArgs[1]/2); // ~ 4 Days
|
||||
const WARNING_DAYS = 1;
|
||||
|
||||
// ---
|
||||
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const sendEmail = require("qmi-cloud-common/send-email");
|
||||
const moment = require('moment');
|
||||
const azurecli = require('qmi-cloud-common/azurecli');
|
||||
|
||||
function timeRunning(p) {
|
||||
function timeRunningIs24x7(p) {
|
||||
let runningFromTime = p.runningFrom? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
|
||||
let totalRunningFromTime;
|
||||
if (p.statusVms !== 'Stopped' && p.statusVms !== 'Starting' && !p.isDestroyed) {
|
||||
totalRunningFromTime = Math.abs(new Date().getTime() - runningFromTime);
|
||||
}
|
||||
let totalRunningFromTime = Math.abs(new Date().getTime() - runningFromTime);
|
||||
let duration = moment.duration(totalRunningFromTime);
|
||||
p.duration = {
|
||||
hours: Math.floor(duration.asHours()),
|
||||
@@ -29,6 +29,18 @@ function timeRunning(p) {
|
||||
};
|
||||
}
|
||||
|
||||
function timeRunningOnSchedule(p) {
|
||||
let runningFromTime = p.runningFrom? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
|
||||
let totalRunningTime = p.timeRunning*1000*60;
|
||||
let now = new Date();
|
||||
totalRunningTime = totalRunningTime + Math.abs(now.getTime() - runningFromTime);
|
||||
let duration = moment.duration(totalRunningTime);
|
||||
p.duration = {
|
||||
hours: Math.floor(duration.asHours()),
|
||||
complete: Math.floor(duration.asDays()) +"d "+duration.hours()+"h "+duration.minutes()
|
||||
};
|
||||
}
|
||||
|
||||
async function asyncForEach(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
@@ -36,18 +48,16 @@ async function asyncForEach(array, callback) {
|
||||
}
|
||||
|
||||
async function init(type) {
|
||||
var limit, cb;
|
||||
var cb;
|
||||
var filter = {
|
||||
"isDestroyed":false,
|
||||
"isDeleted": false,
|
||||
"statusVms": "Running"
|
||||
};
|
||||
if ( type === "warning" ) {
|
||||
limit = RUNNING_LIMIT_HOURS_WARNING;
|
||||
filter.pendingNextAction = {$ne: "stopVms"};
|
||||
cb = doSendEmailWarning;
|
||||
} else if ( type === "exec" ) {
|
||||
limit = RUNNING_LIMIT_HOURS_STOP;
|
||||
filter.pendingNextAction = "stopVms";
|
||||
cb = doStop;
|
||||
} else {
|
||||
@@ -59,45 +69,63 @@ async function init(type) {
|
||||
|
||||
await asyncForEach(provisions.results, async function(p) {
|
||||
//Only if 24x7
|
||||
if ( !p.autoShutdown || p.autoShutdown.is24x7 ) {
|
||||
timeRunning(p);
|
||||
if (!IS_REAL) {
|
||||
console.log(`${p._id} - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
|
||||
}
|
||||
if ( p.duration && p.duration.hours >= limit) {
|
||||
await cb(p);
|
||||
}
|
||||
var typeSchedule = "24x7";
|
||||
var periodDays = RUNNING_PERIOD;
|
||||
if ( !p.schedule || p.schedule.is24x7 ) {
|
||||
timeRunningIs24x7(p);
|
||||
periodDays = RUNNING_PERIOD;
|
||||
} else if ( p.schedule && !p.schedule.is24x7 ) {
|
||||
timeRunningOnSchedule(p);
|
||||
typeSchedule = 'OnSchedule';
|
||||
let onScheduleRenewed = p.schedule.onScheduleRenewed? p.schedule.onScheduleRenewed : 1;
|
||||
periodDays = RUNNING_PERIOD_ON_SCHEDULE * onScheduleRenewed;
|
||||
}
|
||||
var limit;
|
||||
if ( type === "warning" ) {
|
||||
limit = 24*(periodDays-WARNING_DAYS);
|
||||
} else if ( type === "exec" ) {
|
||||
limit = 24*periodDays;
|
||||
}
|
||||
if (!IS_REAL) {
|
||||
console.log(`${p._id} - (${typeSchedule}) - limit: ${limit} hs - actual duration: ${p.duration.hours} hs`);
|
||||
}
|
||||
if ( p.duration && p.duration.hours >= limit) {
|
||||
await cb(p, limit, typeSchedule);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const doSendEmailWarning = async function(p) {
|
||||
const doSendEmailWarning = async function(p, limit, typeSchedule) {
|
||||
if ( p.pendingNextAction === 'stopVms') {
|
||||
console.log(`Warning email Stop already sent. Wait for pending action to complete.`);
|
||||
} else {
|
||||
let msg = `Send warning STOP email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id}) being 'Running' more than ${RUNNING_LIMIT_HOURS_WARNING} hours (exactly ${p.duration.complete})`;
|
||||
let msg = `Send warning STOP email - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Running' more than ${limit} hours, (exactly ${p.duration.complete})`;
|
||||
console.log(msg);
|
||||
if ( IS_REAL ) {
|
||||
await db.provision.update(p._id, {"pendingNextAction": "stopVms"});
|
||||
await sendEmail.sendWillStopIn24(p, p._scenarioDoc);
|
||||
await sendEmail.sendWillStopIn24(p, p._scenarioDoc, Math.floor(limit/24), WARNING_DAYS);
|
||||
await db.notification.add({ provision: p._id.toString(), type: 'warningStop', message: msg });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const doStop = async function(p) {
|
||||
const doStop = async function(p, limit, typeSchedule) {
|
||||
try {
|
||||
let msg = `VMs stopped - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id}) being 'Running' more than ${RUNNING_LIMIT_HOURS_STOP} hours (exactly ${p.duration.complete})`
|
||||
let msg = `VMs stopped - ${p.user.displayName} (${p.user.upn}) about provision '${p._scenarioDoc.title}' (${p._id} - ${typeSchedule}) being 'Running' more than ${limit} hours, (exactly ${p.duration.complete})`
|
||||
console.log(msg);
|
||||
|
||||
if ( IS_REAL ) {
|
||||
//Disable Divvy
|
||||
await azurecli.updateVmsTags(p, {
|
||||
"24x7": false,
|
||||
"StartupTime": false
|
||||
});
|
||||
//Stop VMs
|
||||
await azurecli.deallocate(p, true);
|
||||
if (p.schedule){
|
||||
//Disable Divvy
|
||||
await db.schedule.update(p.schedule._id, {"isStartupTimeEnable": false});
|
||||
await azurecli.updateVmsTags(p._id, {
|
||||
"24x7": false,
|
||||
"StartupTime": false,
|
||||
"ShutdownTime": false
|
||||
});
|
||||
}
|
||||
//Stop VMs indefinitely
|
||||
await azurecli.deallocate(p._id, true);
|
||||
await db.notification.add({ provision: p._id.toString(), type: 'stop', message: msg });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-cli",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.5",
|
||||
"scripts": {
|
||||
},
|
||||
"private": true,
|
||||
|
||||
@@ -19,7 +19,7 @@ async function _getClient(scenarioName) {
|
||||
id = scenario.subscription? scenario.subscription.subsId : SUBSCRIPTION_ID;
|
||||
}
|
||||
var credentials = await MsRest.loginWithMSI({ port: 50342 });
|
||||
console.log("Azure CLI authenticated", credentials);
|
||||
//console.log("AzureCLI# authenticated", credentials);
|
||||
return new computeManagementClient(credentials, id);
|
||||
}
|
||||
|
||||
@@ -29,9 +29,12 @@ async function asyncForEach(array, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
async function deallocate(provision, isSendEmailAfter ) {
|
||||
async function deallocate(provId, isSendEmailAfter ) {
|
||||
let provision = await db.provision.getById(provId);
|
||||
if ( !provision ) return;
|
||||
|
||||
let rgName = _getRgName(provision);
|
||||
console.log("Deallocating VMs for resource group: "+rgName);
|
||||
console.log("AzureCLI# Deallocating VMs for resource group: "+rgName);
|
||||
var computeClient = await _getClient(provision.scenario);
|
||||
let finalResult = await computeClient.virtualMachines.list(rgName);
|
||||
if ( finalResult && finalResult.length > 0 ) {
|
||||
@@ -44,28 +47,19 @@ async function deallocate(provision, isSendEmailAfter ) {
|
||||
let timeRunning = db.utils.getNewTimeRunning(provision);
|
||||
await db.provision.update(provision._id.toString(), {"statusVms": "Stopped", "timeRunning": timeRunning, "stoppedFrom": new Date(), "pendingNextAction": undefined});
|
||||
|
||||
if ( isSendEmailAfter && provision._scenario) {
|
||||
await sendEmail.sendVMsStopped(provision, provision._scenario);
|
||||
if ( isSendEmailAfter && provision._scenarioDoc ) {
|
||||
await sendEmail.sendVMsStopped(provision, provision._scenarioDoc);
|
||||
}
|
||||
|
||||
console.log("All VMs DEALLOCATED for resource group: "+rgName);
|
||||
console.log("AzureCLI# All VMs DEALLOCATED for resource group: "+rgName);
|
||||
}
|
||||
|
||||
async function start(provision){
|
||||
async function start(provId){
|
||||
let provision = await db.provision.getById(provId);
|
||||
if ( !provision ) return;
|
||||
|
||||
let rgName = _getRgName(provision);
|
||||
console.log("Starting VMs for resource group: "+rgName);
|
||||
|
||||
//Re-enable Divvy according to what's in database
|
||||
if (provision.autoShutdown){
|
||||
console.log("Re-enabling Divvy Tags according to database");
|
||||
var tagsEdit = {
|
||||
"24x7": provision.autoShutdown.is24x7? " " : false,
|
||||
"StartupTime": provision.autoShutdown.utcTagStartupTime || false,
|
||||
"ShutdownTime": provision.autoShutdown.utcTagShutdownTime || false
|
||||
}
|
||||
await updateVmsTags(provision, tagsEdit);
|
||||
}
|
||||
console.log("AzureCLI# Starting VMs for resource group: "+rgName);
|
||||
|
||||
var computeClient = await _getClient(provision.scenario);
|
||||
let finalResult = await computeClient.virtualMachines.list(rgName);
|
||||
@@ -78,7 +72,7 @@ async function start(provision){
|
||||
});
|
||||
let countExtend = db.utils.getNewCountExtend(provision);
|
||||
await db.provision.update(provision._id.toString(), {"statusVms": "Running", "runningFrom": new Date(), "countExtend": countExtend, "pendingNextAction": undefined});
|
||||
console.log("All VMs RUNNING for resource group: "+rgName);
|
||||
console.log("AzureCLI# All VMs RUNNING for resource group: "+rgName);
|
||||
}
|
||||
|
||||
async function getResourceGroupVms(rgName){
|
||||
@@ -91,12 +85,14 @@ async function getAllVms(){
|
||||
return await computeClient.virtualMachines.listAll(rgName);
|
||||
}
|
||||
|
||||
async function updateVmsTags(provision, tagsEdit) {
|
||||
async function updateVmsTags(provId, tagsEdit) {
|
||||
|
||||
if ( !tagsEdit ){ return {} ; }
|
||||
let provision = await db.provision.getById(provId);
|
||||
if ( !provision ){ return };
|
||||
|
||||
let rgName = _getRgName(provision);
|
||||
console.log("Updating TAGS in VMs for resource group: "+rgName);
|
||||
console.log("AzureCLI# Updating TAGS in VMs for resource group: "+rgName);
|
||||
|
||||
var computeClient = await _getClient(provision.scenario);
|
||||
let finalResult = await computeClient.virtualMachines.list(rgName);
|
||||
@@ -122,7 +118,9 @@ async function updateVmsTags(provision, tagsEdit) {
|
||||
toAdd.forEach(t=>{
|
||||
tags[t.key] = t.value;
|
||||
});
|
||||
result[vm.name] = tags;
|
||||
tags["ProvId"] = provision._id.toString();
|
||||
result[vm.name] = tags;
|
||||
console.log(`AzureCLI# VM ${vm.name} new tags: `, tags );
|
||||
computeClient.virtualMachines.update(rgName, vm.name, {"tags": tags} );
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,8 +73,17 @@ const provisionSchema = new mongoose.Schema({
|
||||
pendingNextAction: {
|
||||
type: String
|
||||
},
|
||||
autoShutdown: {
|
||||
type: mongoose.Types.ObjectId, ref: 'ProvisionAutoShutdown'
|
||||
schedule: {
|
||||
type: mongoose.Types.ObjectId,
|
||||
ref: 'Schedule'
|
||||
},
|
||||
deployOpts: {
|
||||
type: mongoose.Types.ObjectId,
|
||||
ref: "Subscription"
|
||||
},
|
||||
terraformImage: {
|
||||
type: String,
|
||||
default: "qlikgear/terraform:0.13.4"
|
||||
}
|
||||
},{
|
||||
toObject: {virtuals:true},
|
||||
|
||||
@@ -31,7 +31,7 @@ const scenarioSchema = new mongoose.Schema({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isExterrequirednal: {
|
||||
isExternal: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
@@ -39,6 +39,9 @@ const scenarioSchema = new mongoose.Schema({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
numSimultaneousProvisions: {
|
||||
type: Number
|
||||
},
|
||||
isDisabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
@@ -52,9 +55,17 @@ const scenarioSchema = new mongoose.Schema({
|
||||
productVersionDefault: String,
|
||||
newImageName: String, //For Gen scenarios
|
||||
subscription: {
|
||||
type: mongoose.Types.ObjectId, ref: 'Subscription',
|
||||
type: mongoose.Types.ObjectId,
|
||||
ref: 'Subscription'
|
||||
},
|
||||
deployOpts: [{
|
||||
type: mongoose.Types.ObjectId,
|
||||
ref: 'Subscription',
|
||||
required: true
|
||||
}
|
||||
}],
|
||||
labels: [{
|
||||
type: String
|
||||
}]
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,14 @@ const sc = new mongoose.Schema({
|
||||
required: true,
|
||||
default: true
|
||||
},
|
||||
isStartupTimeEnable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
onScheduleRenewed: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
localeShutdownTime: {
|
||||
type: String
|
||||
},
|
||||
@@ -34,4 +42,4 @@ const sc = new mongoose.Schema({
|
||||
});
|
||||
|
||||
|
||||
module.exports = mongoose.model('ProvisionAutoShutdown', sc)
|
||||
module.exports = mongoose.model('Schedule', sc)
|
||||
@@ -30,6 +30,15 @@ const subSchema = new mongoose.Schema({
|
||||
},
|
||||
appGwSubnetId: {
|
||||
type: String
|
||||
},
|
||||
location: {
|
||||
type: String
|
||||
},
|
||||
wafPolicyName: {
|
||||
type: String
|
||||
},
|
||||
wafPolicyRgName: {
|
||||
type: String
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -26,6 +26,12 @@ const userSchema = new mongoose.Schema({
|
||||
lastLogin: {
|
||||
type: Date
|
||||
},
|
||||
qcsUserId: {
|
||||
type: String
|
||||
},
|
||||
qcsUserSubject: {
|
||||
type: String
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const options = {
|
||||
useUnifiedTopology: true
|
||||
};
|
||||
|
||||
console.log("--- MongoDB connecting...");
|
||||
console.log("--- MongoDB connecting... ", process.env.MONGO_URI);
|
||||
|
||||
// Connect to DB
|
||||
mongoose.connect(process.env.MONGO_URI, options);
|
||||
@@ -34,7 +34,7 @@ mongoose.connection.on('error', (err) => {
|
||||
|
||||
// Get Data Models
|
||||
const Scenario = require('./models/Scenario');
|
||||
const ProvisionAutoShutdown = require('./models/ProvisionAutoShutdown');
|
||||
const Schedule = require('./models/Schedule');
|
||||
const Provision = require('./models/Provision');
|
||||
const Destroy = require('./models/Destroy');
|
||||
const User = require('./models/User');
|
||||
@@ -64,6 +64,66 @@ const getNewTimeRunning = function (provision) {
|
||||
};
|
||||
|
||||
|
||||
const getPage = async ( model, filter, page, populates, select ) => {
|
||||
var sort = {};
|
||||
var modelAttributes = Object.keys(model.schema.tree);
|
||||
if ( modelAttributes.indexOf("created") !== -1) {
|
||||
sort = {created: -1};
|
||||
}
|
||||
|
||||
try {
|
||||
var exec = model.find(filter, select).sort(sort);
|
||||
var totalDocs = await model.countDocuments(filter);
|
||||
|
||||
var isPage = false;
|
||||
if ( page && page.page > 0 && page.size !== undefined ) {
|
||||
var skip = 0;
|
||||
skip = (page.page - 1) * page.size;
|
||||
exec = exec.skip(skip);
|
||||
exec = exec.limit(page.size);
|
||||
isPage = true;
|
||||
}
|
||||
|
||||
if ( populates ) {
|
||||
populates = JSON.parse(populates);
|
||||
populates.forEach(p=> {
|
||||
exec = exec.populate(p);
|
||||
});
|
||||
} else {
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate({path:'destroy', select: "-user -jobId"}).populate({path:'_scenarioDoc', select: "-availableProductVersions -updated -created"}).populate({path: "schedule"}).populate('deployOpts');
|
||||
}
|
||||
|
||||
if ( model === ApiKey ) {
|
||||
exec = exec.populate('user');
|
||||
}
|
||||
|
||||
if ( model = Scenario ) {
|
||||
exec = exec.populate('subscription').populate('deployOpts');
|
||||
}
|
||||
}
|
||||
|
||||
const entity = await exec;
|
||||
|
||||
var out = {
|
||||
total: totalDocs,
|
||||
count: entity.length,
|
||||
results: entity
|
||||
}
|
||||
if ( isPage && (page.page * page.size < totalDocs)) {
|
||||
out.next = {
|
||||
page: page.page + 1,
|
||||
size: page.size
|
||||
};
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
} catch (err) {
|
||||
throw boom.boomify(err)
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const get = async (model, filter, select, skip, limit, populates, reply) => {
|
||||
var sort = {};
|
||||
@@ -90,7 +150,7 @@ const get = async (model, filter, select, skip, limit, populates, reply) => {
|
||||
});
|
||||
} else {
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate({path:'destroy', select: "-user -jobId"}).populate({path:'_scenarioDoc', select: "-availableProductVersions -updated -created"}).populate({path: "autoShutdown"});
|
||||
exec = exec.populate({ path: 'user', select: 'displayName upn'}).populate({path:'destroy', select: "-user -jobId"}).populate({path:'_scenarioDoc', select: "-availableProductVersions -updated -created"}).populate({path: "schedule"}).populate('deployOpts');
|
||||
}
|
||||
|
||||
if ( model === ApiKey ) {
|
||||
@@ -98,7 +158,7 @@ const get = async (model, filter, select, skip, limit, populates, reply) => {
|
||||
}
|
||||
|
||||
if ( model = Scenario ) {
|
||||
exec = exec.populate('subscription');
|
||||
exec = exec.populate('subscription').populate('deployOpts');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,13 +183,13 @@ const getById = async (model, id, reply) => {
|
||||
try {
|
||||
var exec = model.findById(id);
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("autoShutdown");
|
||||
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("schedule").populate('deployOpts');
|
||||
}
|
||||
if ( model === ApiKey ) {
|
||||
exec = exec.populate('user');
|
||||
}
|
||||
if ( model = Scenario ) {
|
||||
exec = exec.populate('subscription');
|
||||
exec = exec.populate('subscription').populate('deployOpts');
|
||||
}
|
||||
const entity = await exec;
|
||||
return entity;
|
||||
@@ -142,13 +202,13 @@ const getOne = async (model, filter, reply) => {
|
||||
try {
|
||||
var exec = model.findOne(filter);
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("autoShutdown");
|
||||
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("schedule").populate('deployOpts');
|
||||
}
|
||||
if ( model === ApiKey ) {
|
||||
exec = exec.populate('user');
|
||||
}
|
||||
if ( model = Scenario ) {
|
||||
exec = exec.populate('subscription');
|
||||
exec = exec.populate('subscription').populate('deployOpts');
|
||||
}
|
||||
const entity = await exec;
|
||||
return entity;
|
||||
@@ -173,13 +233,13 @@ const update = async (model, id, body, reply) => {
|
||||
//console.log("UPDATE", id, updateData);
|
||||
var exec = model.findByIdAndUpdate(id, updateData, { new: true });
|
||||
if ( model === Provision ) {
|
||||
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("autoShutdown");
|
||||
exec = exec.populate('user').populate('destroy').populate('_scenarioDoc').populate("schedule").populate('deployOpts');
|
||||
}
|
||||
if ( model === ApiKey ) {
|
||||
exec = exec.populate('user');
|
||||
}
|
||||
if ( model = Scenario ) {
|
||||
exec = exec.populate('subscription');
|
||||
exec = exec.populate('subscription').populate('deployOpts');
|
||||
}
|
||||
const update = await exec;
|
||||
return update;
|
||||
@@ -202,6 +262,9 @@ function _m(model) {
|
||||
get: async (filter, select, skip, limit, populates, reply) => {
|
||||
return get(model, filter, select, skip, limit, populates, reply);
|
||||
},
|
||||
getPage: async (filter, page, populates, select, reply) => {
|
||||
return getPage(model, filter, page, populates, select, reply);
|
||||
},
|
||||
getById: async (id, reply) => {
|
||||
return getById(model, id, reply);
|
||||
},
|
||||
@@ -222,7 +285,7 @@ function _m(model) {
|
||||
|
||||
|
||||
module.exports = {
|
||||
provisionAutoShutdown: _m(ProvisionAutoShutdown),
|
||||
schedule: _m(Schedule),
|
||||
provision: _m(Provision),
|
||||
destroy: _m(Destroy),
|
||||
scenario: _m(Scenario),
|
||||
@@ -241,6 +304,7 @@ module.exports = {
|
||||
Destroy: Destroy,
|
||||
Scenario: Scenario,
|
||||
User: User,
|
||||
Schedule: Schedule,
|
||||
VmType: VmType,
|
||||
Notification: Notification,
|
||||
ApiKey: ApiKey,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-common",
|
||||
"version": "1.1.4",
|
||||
"version": "1.1.5",
|
||||
"dependencies": {
|
||||
"@hapi/boom": "^9.1.0",
|
||||
"mongoose": "^5.7.4",
|
||||
|
||||
@@ -21,7 +21,8 @@ export const queues = {
|
||||
|
||||
for (let key in queues) {
|
||||
queues[key].on('completed', function(job, result) {
|
||||
console.log(`Job ${job.id} completed! Result`, result);
|
||||
//console.log(`Queues# Job ${job.id} completed! Result`, result);
|
||||
console.log(`Queues# Job ${job.id} completed!`);
|
||||
});
|
||||
|
||||
|
||||
@@ -30,13 +31,13 @@ for (let key in queues) {
|
||||
});
|
||||
|
||||
queues[key].on('waiting', function(jobId){
|
||||
console.log(`Job ${jobId} is waiting...`);
|
||||
console.log(`Queues# Job ${jobId} is waiting...`);
|
||||
// A Job is waiting to be processed as soon as a worker is idling.
|
||||
});
|
||||
|
||||
queues[key].on('active', function(job, jobPromise){
|
||||
// A job has started. You can use `jobPromise.cancel()`` to abort it.
|
||||
console.log(`Job ${job.id} is in active`);
|
||||
console.log(`Queues# Job ${job.id} is now active`);
|
||||
});
|
||||
|
||||
queues[key].on('stalled', function(job){
|
||||
@@ -46,12 +47,12 @@ for (let key in queues) {
|
||||
|
||||
queues[key].on('progress', function(job, progress){
|
||||
// A job's progress was updated!
|
||||
console.log(`Job ${job.id} is ${progress * 100}% ready!`);
|
||||
console.log(`Queues# Job ${job.id} is ${progress * 100}% ready!`);
|
||||
});
|
||||
|
||||
queues[key].on('failed', function(job, err){
|
||||
// A job failed with reason `err`!
|
||||
console.log(`Job ${job.id} has failed:`, err);
|
||||
console.log(`Queues# Job ${job.id} has failed:`, err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,16 +3,6 @@ const nodemailer = require('nodemailer');
|
||||
const FROM = '"Qlik" <no-reply@qlik.com>';
|
||||
var transporter;
|
||||
|
||||
const RUNNING_PERIOD = 4;
|
||||
const RUNNING_PERIOD_WARNING_DAYS = 1;
|
||||
const STOP_PERIOD = 20;
|
||||
const STOP_PERIOD_WARNING_DAYS = 2;
|
||||
|
||||
|
||||
const RUNNING_PERIOD_WARNING_HOURS = RUNNING_PERIOD_WARNING_DAYS*24;
|
||||
const STOP_PERIOD_WARNING_HOURS = STOP_PERIOD_WARNING_DAYS*24;
|
||||
|
||||
|
||||
if ( process.env.GMAIL_USERNAME && process.env.GMAIL_PASSWORD ) {
|
||||
//GMAIL
|
||||
transporter = nodemailer.createTransport({
|
||||
@@ -43,13 +33,27 @@ async function _doSend(to, subject, htmlText) {
|
||||
html: htmlText // html body
|
||||
} );
|
||||
|
||||
console.log('Provision Email ('+info.messageId+') sent to: ' + to);
|
||||
console.log('SendEmail# message id ('+info.messageId+') sent to: ' + to);
|
||||
}
|
||||
|
||||
function _getCommonDetails(provision, scenario){
|
||||
var description = decodeURI(scenario.description);
|
||||
var externalAccess = provision.isExternalAccess? 'Yes' : 'No';
|
||||
var schedule = "";
|
||||
if ( !provision.schedule || provision.schedule.is24x7 ) {
|
||||
schedule = "24x7";
|
||||
} else if ( provision.schedule && !provision.schedule.is24x7 ) {
|
||||
schedule = `from ${provision.schedule.localeStartupTime}h until ${provision.schedule.localeShutdownTime}h (${provision.schedule.localTimezone})`;
|
||||
}
|
||||
return `<div style="color:#404040;font-size:18px;margin:20px 0px">
|
||||
<p style="margin:0px">Provision information:</p>
|
||||
</div>
|
||||
<div>
|
||||
<span style="color:#404040">ID: </span> ${provision._id}
|
||||
</div>
|
||||
<div>
|
||||
<span style="color:#404040">VMs Running schedule: </span> ${schedule}
|
||||
</div>
|
||||
<div>
|
||||
<span style="color:#404040">Purpose: </span> ${provision.description}
|
||||
</div>
|
||||
@@ -57,14 +61,14 @@ function _getCommonDetails(provision, scenario){
|
||||
<span style="color:#404040">Scenario: </span> ${scenario.title}
|
||||
</div>
|
||||
<div>
|
||||
<span style="color:#404040">Description: </span> ${scenario.description}
|
||||
<span style="color:#404040">With external access: </span> ${externalAccess}
|
||||
</div>
|
||||
<div>
|
||||
<span style="color:#404040">ProvisionID: </span> ${provision._id}
|
||||
<span style="color:#404040">Description: </span> ${description}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function getHtmlScenarioDestroyIn24( provision, scenario) {
|
||||
function getHtmlScenarioDestroyIn24( provision, scenario, period, warningDays) {
|
||||
var common = _getCommonDetails(provision,scenario);
|
||||
return`<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
|
||||
<div style="background-color:white;height:100%;padding:20px 10px">
|
||||
@@ -72,13 +76,13 @@ function getHtmlScenarioDestroyIn24( provision, scenario) {
|
||||
<p style="margin:0px">QMI Cloud</p>
|
||||
</div>
|
||||
<div style="color:#404040;font-size:22px;margin:20px 0px 40px 0px">
|
||||
<p style="margin:0px">Provision '${scenario.title}' inactive more than ${(STOP_PERIOD - STOP_PERIOD_WARNING_DAYS)} days</p>
|
||||
<p style="margin:0px">Provision '${scenario.title}' inactive more than ${period} days</p>
|
||||
</div>
|
||||
<div style="color:#404040;font-size:18px;margin:10px 0px">
|
||||
<p style="margin:0px;color: #FF2020">This scenario will be automatically DESTROYED in ${STOP_PERIOD_WARNING_HOURS} hours.</p>
|
||||
<p style="margin:0px;color: #FF2020">This scenario will be automatically DESTROYED in ${(warningDays*24)} hours.</p>
|
||||
</div>
|
||||
<div style="color:#404040;font-size:16px;margin:30px 0px">
|
||||
<p style="margin:0px">If you don't want this to happen, you've got ${STOP_PERIOD_WARNING_HOURS} hours (from when this email was sent) as a grace period to get back at 'Running' status this provision.</p>
|
||||
<p style="margin:0px">If you don't want this to happen, you've got ${(warningDays*24)} hours (from when this email was sent) as a grace period to get back at 'Running' status this provision.</p>
|
||||
</div>
|
||||
${common}
|
||||
<div style="color:#404040;font-size:16px;margin:30px 0px">
|
||||
@@ -113,7 +117,7 @@ function getHtmlScenarioVMsStopped( provision, scenario) {
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function getHtmlScenarioWillStopIn24( provision, scenario ) {
|
||||
function getHtmlScenarioWillStopIn24( provision, scenario, period, warningDays ) {
|
||||
var common = _getCommonDetails(provision,scenario);
|
||||
return`<div style="width:600px;color:black!important;font-family:'Source Sans Pro',sans-serif;padding:50px">
|
||||
<div style="background-color:white;height:100%;padding:20px 10px">
|
||||
@@ -121,16 +125,16 @@ function getHtmlScenarioWillStopIn24( provision, scenario ) {
|
||||
<p style="margin:0px">QMI Cloud</p>
|
||||
</div>
|
||||
<div style="color:#404040;font-size:22px;margin:20px 0px 40px 0px">
|
||||
<p style="margin:0px">Provision '${scenario.title}' - VMs running for ${(RUNNING_PERIOD - RUNNING_PERIOD_WARNING_DAYS)} days</p>
|
||||
<p style="margin:0px">Provision '${scenario.title}' - VMs running for ${period} days</p>
|
||||
</div>
|
||||
<div style="color:#404040;font-size:18px;margin:10px 0px">
|
||||
<p style="margin:0px;color: #FF2020">This scenario will automatically stop its VMs in ${RUNNING_PERIOD_WARNING_HOURS} hours.</p>
|
||||
<p style="margin:0px;color: #FF2020">This scenario will automatically stop its VMs in ${warningDays*24} hours.</p>
|
||||
</div>
|
||||
<div style="color:#404040;font-size:18px;margin:20px 0px 10px 0px">
|
||||
<p style="margin:0px;color: #FF2020">Take action and extend the period ${RUNNING_PERIOD} extra days.</p>
|
||||
<p style="margin:0px;color: #FF2020">Take action and extend the period ${(period+warningDays)} extra days.</p>
|
||||
</div>
|
||||
<div style="color:#404040;font-size:16px;margin:30px 0px">
|
||||
<p style="margin:0px">If you don't want the VMs to automatically stop, you've got ${RUNNING_PERIOD_WARNING_HOURS} hours (from when this email was sent) as a grace period to extend this scenario's <b style="color: #009845">Running</b> VMs for ${RUNNING_PERIOD} extra days.</p>
|
||||
<p style="margin:0px">If you don't want the VMs to automatically stop, you've got ${warningDays*24} hours (from when this email was sent) as a grace period to extend this scenario's <b style="color: #009845">Running</b> VMs for ${(period+warningDays)} extra days.</p>
|
||||
</div>
|
||||
${common}
|
||||
<div style="color:#404040;font-size:16px;margin:30px 0px">
|
||||
@@ -235,17 +239,17 @@ async function sendDestroyed(provision, scenario ) {
|
||||
|
||||
}
|
||||
|
||||
async function sendWillStopIn24( provision, scenario ) {
|
||||
async function sendWillStopIn24( provision, scenario, period, warningDays ) {
|
||||
|
||||
const htmlText = getHtmlScenarioWillStopIn24( provision, scenario);
|
||||
await _doSend(provision.user.upn, `QMI Cloud - VMs will stop in ${RUNNING_PERIOD_WARNING_HOURS} hours`, htmlText);
|
||||
const htmlText = getHtmlScenarioWillStopIn24( provision, scenario, period, warningDays);
|
||||
await _doSend(provision.user.upn, `QMI Cloud - VMs will stop in ${warningDays*24} hours`, htmlText);
|
||||
|
||||
}
|
||||
|
||||
async function sendWillDestroyIn24( provision, scenario ) {
|
||||
async function sendWillDestroyIn24( provision, scenario, period, warningDays ) {
|
||||
|
||||
const htmlText = getHtmlScenarioDestroyIn24( provision, scenario);
|
||||
await _doSend(provision.user.upn, `QMI Cloud - Provision will destroy in ${STOP_PERIOD_WARNING_HOURS} hours`, htmlText);
|
||||
const htmlText = getHtmlScenarioDestroyIn24( provision, scenario, period, warningDays);
|
||||
await _doSend(provision.user.upn, `QMI Cloud - Provision will destroy in ${(warningDays*24)} hours`, htmlText);
|
||||
}
|
||||
|
||||
async function sendVMsStopped( provision, scenario ) {
|
||||
|
||||
@@ -15,15 +15,17 @@ module.exports = async function(job) {
|
||||
});
|
||||
|
||||
if ( !prov ) {
|
||||
console.log(`Error: Not found Provision object in Database (it should exist!), provisionId is: ${job.data.id}` );
|
||||
console.log(`ProcessorApply# Error: Not found Provision object in Database (it should exist!), provisionId is: ${job.data.id}` );
|
||||
return Promise.reject({"success": false, "err": "Not found Provision object in Worker"});
|
||||
}
|
||||
|
||||
var idProv = prov._id.toString();
|
||||
|
||||
// TERRAFORM INIT
|
||||
return tf.init(prov)
|
||||
.then(async function(res) {
|
||||
if ( res.statusCode === 1 ) {
|
||||
console.log("Error at INIT");
|
||||
console.log(`ProcessorApply# Error at Terraform INIT for provision (${idProv})`);
|
||||
return Promise.reject({"success": false, "error": "Error at Terraform Init", provStatus: "error_init"});
|
||||
} else {
|
||||
// TERRAFORM PLAN
|
||||
@@ -32,7 +34,7 @@ module.exports = async function(job) {
|
||||
} )
|
||||
.then( async function(res) {
|
||||
if ( res.statusCode === 1 ) {
|
||||
console.log("Error at PLAN");
|
||||
console.log(`ProcessorApply# Error at Terraform PLAN for provision (${idProv}) `);
|
||||
return Promise.reject({"success": false, "error": "Error at Terraform Plan", provStatus: "error_plan"});
|
||||
} else {
|
||||
return await db.provision.update(prov._id,{"status": "provisioning", "statusVms": "Running", "runningFrom": new Date(), "runningTime": 0, "countExtend": 0});
|
||||
@@ -42,7 +44,7 @@ module.exports = async function(job) {
|
||||
return tf.apply(prov);
|
||||
} ).then( async function(res) {
|
||||
if ( res.statusCode === 1 ) {
|
||||
console.log("Error at APPLY");
|
||||
console.log(`ProcessorApply# Error at Terraform APPLY for provision (${idProv})`);
|
||||
}
|
||||
var status = ( res.output.indexOf("Error:") !== -1 )? "error" : "provisioned";
|
||||
return await db.provision.update(prov._id, {"status": status});
|
||||
@@ -64,7 +66,7 @@ module.exports = async function(job) {
|
||||
}
|
||||
return Promise.resolve({"success": true, provMongo: prov});
|
||||
} ).catch( function(err) {
|
||||
console.log("Provision: error", err);
|
||||
console.log("ProcessorApply# Provision: error", err);
|
||||
db.provision.update(prov._id, {"status": err.provStatus? err.provStatus : 'error'});
|
||||
sendEmail.sendError(prov, job.data._scenario);
|
||||
return Promise.reject({"success": false, "error": err});
|
||||
|
||||
@@ -13,9 +13,9 @@ const appgateway = function( provision, scenario ) {
|
||||
var provision_id = provision._id.toString();
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
var name = 'qmi-azureps-appgw-'+provision_id;
|
||||
console.log(`AzurePS: will spin up container: ${name}`);
|
||||
console.log(`AzurePS# will spin up container: ${name}`);
|
||||
|
||||
return docker.run(DOCKERIMAGE, ['pwsh', 'appgw.ps1', "-ProvisionId", provision_id ], processStream, {
|
||||
return docker.run(DOCKERIMAGE, ['pwsh', 'appgw.ps1', "-ProvisionId", provision_id, "-Subscription", provision.deployOpts.subsId, "-PolicyName", provision.deployOpts.wafPolicyName , "-PolicyResourceGroup", provision.deployOpts.wafPolicyRgName ], processStream, {
|
||||
"name": name,
|
||||
"WorkingDir": "/myapp",
|
||||
"HostConfig": {
|
||||
@@ -27,10 +27,10 @@ const appgateway = function( provision, scenario ) {
|
||||
}).then(function(data) {
|
||||
var output = data[0];
|
||||
var container = data[1];
|
||||
console.log(`AzurePS: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
console.log(`AzurePS# ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
return container.remove();
|
||||
}).then(function() {
|
||||
console.log(`AzurePS: ${name} removed!`);
|
||||
console.log(`AzurePS# ${name} removed!`);
|
||||
return Promise.resolve(provision);
|
||||
});
|
||||
|
||||
@@ -52,7 +52,7 @@ const createimage = function( provision, scenario ) {
|
||||
|
||||
let imageName = scenario.newImageName + "-" + new Date().getTime();
|
||||
|
||||
console.log(`AzurePS: will spin up container: ${name}`);
|
||||
console.log(`AzurePS# will spin up container: ${name}`);
|
||||
|
||||
return docker.run(DOCKERIMAGE, ['pwsh', 'createimage.ps1', "-rgName", rgName, "-imageName", imageName ], processStream, {
|
||||
"name": name,
|
||||
@@ -66,10 +66,10 @@ const createimage = function( provision, scenario ) {
|
||||
}).then(function(data) {
|
||||
var output = data[0];
|
||||
var container = data[1];
|
||||
console.log(`AzurePS: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
console.log(`AzurePS# ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
return container.remove();
|
||||
}).then(function() {
|
||||
console.log(`AzurePS: ${name} removed!`);
|
||||
console.log(`AzurePS# ${name} removed!`);
|
||||
return Promise.resolve(provision);
|
||||
});
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ const KUBE_PATH = path.join(PROJECT_PATH, 'logs', 'kube');
|
||||
const _done = function(data){
|
||||
let output = data[0];
|
||||
let container = data[1];
|
||||
console.log(`kubectl: (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
console.log(`kubectl# (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
return container.remove();
|
||||
};
|
||||
|
||||
const kubeconfig = function( provId ) {
|
||||
|
||||
fs.writeFileSync(`/var/www/app/logs/kube/config_${provId}`, kubeConfigContent);
|
||||
console.log(`kubectl: will spin up container`);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
|
||||
return docker.run(DOCKERIMAGE, ['config', 'current-context', '--kubeconfig', `/app/config_${provId}` ], processStream, {
|
||||
//"name": initContName,
|
||||
@@ -35,7 +35,7 @@ const kubeconfig = function( provId ) {
|
||||
const apply = function( provId, kubeConfigContent ) {
|
||||
|
||||
fs.writeFileSync(`/logs/kube/${provId}.config`, kubeConfigContent);
|
||||
console.log(`kubectl: will spin up container`);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
const yaml = path.join(PROJECT_PATH, 'az-tf-templates', 'azqmi-qseok', 'scripts', 'azure-sc.yaml');
|
||||
return docker.run(DOCKERIMAGE, ['apply','-f', '/yamlfile', '--kubeconfig', `/app/${provId}.config` ], process.stdout, {
|
||||
//"name": initContName,
|
||||
@@ -52,7 +52,7 @@ const apply = function( provId, kubeConfigContent ) {
|
||||
const getpod = function( provId, kubeConfigContent ) {
|
||||
|
||||
fs.writeFileSync(`/logs/kube/${provId}.config`, kubeConfigContent);
|
||||
console.log(`kubectl: will spin up container`);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
|
||||
return docker.run(DOCKERIMAGE, ['get', 'pod', '--kubeconfig', `/app/${provId}.config` ], process.stdout, {
|
||||
//"name": initContName,
|
||||
@@ -68,9 +68,9 @@ const getpod = function( provId, kubeConfigContent ) {
|
||||
const getsvc = function( provId, kubeConfigContent ) {
|
||||
|
||||
fs.writeFileSync(`/logs/kube/config_${provId}`, kubeConfigContent);
|
||||
console.log(`kubectl: will spin up container`);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
|
||||
console.log(`kubectl: will spin up container`);
|
||||
console.log(`kubectl# will spin up container`);
|
||||
return docker.run(DOCKERIMAGE, ['get', 'svc', '--kubeconfig', `/app/config_${provId}` ], process.stdout, {
|
||||
//"name": initContName,
|
||||
"WorkingDir": "/app",
|
||||
|
||||
@@ -5,7 +5,7 @@ const docker = new Docker({
|
||||
const fs = require('fs');
|
||||
const GIT_SCENARIOS = process.env.GIT_SCENARIOS;
|
||||
const GIT_TAG = process.env.GIT_TAG || "master";
|
||||
const DOCKERIMAGE = process.env.DOCKERIMAGE_TERRAFORM || "qlikgear/terraform:1.0.1";
|
||||
const DOCKERIMAGE = process.env.DOCKERIMAGE_TERRAFORM || "qlikgear/terraform:0.12.18";
|
||||
const SSHPATH = process.env.SSHPATH;
|
||||
|
||||
function hook_stdout(callback) {
|
||||
@@ -31,12 +31,36 @@ function _buildVarsExec( exec, provision, scenario ) {
|
||||
exec.push('-var');
|
||||
exec.push(`prefix=${prefix}`);
|
||||
|
||||
if ( scenario.subscription && scenario.subscription.subsId ) {
|
||||
if ( provision.deployOpts && provision.deployOpts.subsId ) {
|
||||
exec.push('-var');
|
||||
exec.push(`subscription_id=${provision.deployOpts.subsId}`);
|
||||
}
|
||||
//Deprecated
|
||||
else if ( scenario.subscription && scenario.subscription.subsId ) {
|
||||
exec.push('-var');
|
||||
exec.push(`subscription_id=${scenario.subscription.subsId}`);
|
||||
}
|
||||
|
||||
if ( scenario.subscription && scenario.subscription.vnetExists ) {
|
||||
if ( provision.deployOpts ) {
|
||||
|
||||
if ( provision.deployOpts.location ) {
|
||||
exec.push('-var');
|
||||
exec.push(`location=${provision.deployOpts.location}`);
|
||||
}
|
||||
|
||||
if ( provision.deployOpts.vnetExists ) {
|
||||
exec.push('-var');
|
||||
exec.push(`subnet_id=${provision.deployOpts.subnetId}`);
|
||||
|
||||
if ( provision.isExternalAccess ) {
|
||||
exec.push('-var');
|
||||
exec.push(`app_gw_subnet=${provision.deployOpts.appGwSubnetId}`);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//Deprecated
|
||||
else if ( scenario.subscription && scenario.subscription.vnetExists ) {
|
||||
exec.push('-var');
|
||||
exec.push(`subnet_id=${scenario.subscription.subnetId}`);
|
||||
|
||||
@@ -71,8 +95,11 @@ function _buildVarsExec( exec, provision, scenario ) {
|
||||
}
|
||||
|
||||
if ( provision.vmImage[key].vmType ) {
|
||||
exec.push('-var');
|
||||
exec.push(`vm_type_${key}=${provision.vmImage[key].vmType}`);
|
||||
|
||||
if ( !provision.vmImage[key].disabled ) {
|
||||
exec.push('-var');
|
||||
exec.push(`vm_type_${key}=${provision.vmImage[key].vmType}`);
|
||||
}
|
||||
}
|
||||
|
||||
if ( provision.vmImage[key].diskSizeGb ) {
|
||||
@@ -92,20 +119,20 @@ function _buildVarsExec( exec, provision, scenario ) {
|
||||
exec.push(`is_external_access=${provision.isExternalAccess}`);
|
||||
}
|
||||
|
||||
if ( provision.autoShutdown ) {
|
||||
if ( provision.autoShutdown.is24x7 === true ) {
|
||||
if ( provision.schedule ) {
|
||||
if ( provision.schedule.is24x7 === true ) {
|
||||
exec.push('-var');
|
||||
exec.push(`is_24x7=true`);
|
||||
} else if ( provision.autoShutdown.is24x7 === false ) {
|
||||
} else if ( provision.schedule.is24x7 === false ) {
|
||||
exec.push('-var');
|
||||
exec.push(`is_24x7=false`);
|
||||
if ( provision.autoShutdown.utcTagStartupTime ) {
|
||||
if ( provision.schedule.utcTagStartupTime && provision.schedule.isStartupTimeEnable ) {
|
||||
exec.push('-var');
|
||||
exec.push(`startupTime=${provision.autoShutdown.utcTagStartupTime}`);
|
||||
exec.push(`startupTime=${provision.schedule.utcTagStartupTime}`);
|
||||
}
|
||||
if ( provision.autoShutdown.utcTagShutdownTime ) {
|
||||
if ( provision.schedule.utcTagShutdownTime ) {
|
||||
exec.push('-var');
|
||||
exec.push(`shutdownTime=${provision.autoShutdown.utcTagShutdownTime}`);
|
||||
exec.push(`shutdownTime=${provision.schedule.utcTagShutdownTime}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,12 +143,12 @@ function _buildVarsExec( exec, provision, scenario ) {
|
||||
const init = function( provision ) {
|
||||
|
||||
const name = `qmi-tf-init-${provision._id}`;
|
||||
console.log(`Init: will spin up container: ${name}`);
|
||||
console.log(`Terraform# Init: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
let exec = ['terraform', 'init', '-no-color', `-from-module=${GIT_SCENARIOS}//${provision.scenario}?ref=${GIT_TAG}`];
|
||||
console.log('Init: exec: '+exec.join(" "));
|
||||
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
console.log('Terraform# Init: exec: '+exec.join(" "));
|
||||
var terraformImage = provision.terraformImage? provision.terraformImage : DOCKERIMAGE;
|
||||
return docker.run(terraformImage, exec, processStream, {
|
||||
//"Env": ["VAR_ENV=whatever"],
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
@@ -133,9 +160,9 @@ const init = function( provision ) {
|
||||
}).then(function(data) {
|
||||
var output = data[0];
|
||||
var container = data[1];
|
||||
console.log(`Init: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
console.log(`Terraform# Init: ${name} (${container.id}) has finished with code: ${output.StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Init: ${name} removed!`);
|
||||
console.log(`Terraform# Init: ${name} removed!`);
|
||||
return output.StatusCode;
|
||||
});
|
||||
}).then(function(statusCode) {
|
||||
@@ -146,14 +173,14 @@ const init = function( provision ) {
|
||||
const plan = function( provision, scenario ) {
|
||||
|
||||
const name = `qmi-tf-plan-${provision._id}`;
|
||||
console.log(`Plan: will spin up container: ${name}`);
|
||||
console.log(`Terraform# Plan: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
//var processStream = process.stdout;
|
||||
var exec = ['terraform', 'plan', '-no-color', '-input=false', '-out=tfplan' ];
|
||||
exec = _buildVarsExec(exec, provision, scenario);
|
||||
console.log('Plan: exec: '+exec.join(" "));
|
||||
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
console.log('Terraform# Plan: exec: '+exec.join(" "));
|
||||
var terraformImage = provision.terraformImage? provision.terraformImage : DOCKERIMAGE;
|
||||
return docker.run(terraformImage, exec, processStream, {
|
||||
//"Env": ["VAR_ENV=whatever"],
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
@@ -166,9 +193,9 @@ const plan = function( provision, scenario ) {
|
||||
}
|
||||
}).then(function(data){
|
||||
var container = data[1];
|
||||
console.log(`Plan: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
console.log(`Terraform# Plan: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Plan: ${name} removed!`);
|
||||
console.log(`Terraform# Plan: ${name} removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(function(statusCode) {
|
||||
@@ -179,14 +206,14 @@ const plan = function( provision, scenario ) {
|
||||
const apply = function( provision ) {
|
||||
|
||||
const name = `qmi-tf-apply-${provision._id}`;
|
||||
console.log(`Apply: will spin up container: ${name}`);
|
||||
console.log(`Terraform# Apply: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(provision.logFile, {flags:'a'});
|
||||
//var processStream = process.stdout;
|
||||
|
||||
var exec = ['terraform', 'apply', 'tfplan', '-no-color'];
|
||||
console.log('Apply: exec: '+exec.join(" "));
|
||||
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
console.log('Terraform# Apply: exec: '+exec.join(" "));
|
||||
var terraformImage = provision.terraformImage? provision.terraformImage : DOCKERIMAGE;
|
||||
return docker.run(terraformImage, exec, processStream, {
|
||||
//"Env": ["VAR_ENV=whatever"],
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
@@ -199,9 +226,9 @@ const apply = function( provision ) {
|
||||
}
|
||||
}).then(function(data){
|
||||
let container = data[1];
|
||||
console.log(`Apply: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
console.log(`Terraform# Apply: ${name} (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Apply: ${name} removed!`);
|
||||
console.log(`Terraform# Apply: ${name} removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(function(statusCode) {
|
||||
@@ -212,13 +239,15 @@ const apply = function( provision ) {
|
||||
const destroy = function(destroyMongo, provision, scenario) {
|
||||
|
||||
const name = `qmi-tf-destroy-${destroyMongo._id}`;
|
||||
console.log(`Destroy: will spin up container: ${name}`);
|
||||
console.log(`Terraform# Destroy: will spin up container: ${name}`);
|
||||
var processStream = fs.createWriteStream(destroyMongo.logFile, {flags:'a'});
|
||||
var exec = ['terraform', 'destroy', '-auto-approve', '-no-color'];
|
||||
var exec = ['Terraform# terraform', 'destroy', '-auto-approve', '-no-color'];
|
||||
exec = _buildVarsExec(exec, provision, scenario);
|
||||
console.log('Destroy: exec: '+exec.join(" "));
|
||||
console.log('Terraform# Destroy: exec: '+exec.join(" "));
|
||||
|
||||
return docker.run(DOCKERIMAGE, exec, processStream, {
|
||||
var terraformImage = provision.terraformImage? provision.terraformImage : DOCKERIMAGE;
|
||||
|
||||
return docker.run(terraformImage, exec, processStream, {
|
||||
//"Env": ["VAR_ENV=whatever"],
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
@@ -230,9 +259,9 @@ const destroy = function(destroyMongo, provision, scenario) {
|
||||
}
|
||||
}).then(function(data) {
|
||||
var container = data[1];
|
||||
console.log(`Destroy: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
console.log(`Terraform# Destroy: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove().then(function(){
|
||||
console.log(`Destroy: '${name}' removed!`);
|
||||
console.log(`Terraform# Destroy: '${name}' removed!`);
|
||||
return data[0].StatusCode;
|
||||
});
|
||||
}).then(async function(statusCode) {
|
||||
@@ -244,18 +273,20 @@ const destroy = function(destroyMongo, provision, scenario) {
|
||||
const outputs = function(provision) {
|
||||
|
||||
const name = `qmi-tf-output-${provision._id}`;
|
||||
console.log(`Output: will spin up container: ${name}`);
|
||||
console.log(`Terraform# Output: will spin up container: ${name}`);
|
||||
|
||||
|
||||
var exec = ['terraform', 'output', '-no-color', '-json'];
|
||||
console.log('Output: exec: '+exec.join(" "));
|
||||
console.log('Terraform# Output: exec: '+exec.join(" "));
|
||||
|
||||
var tfout = "";
|
||||
var unhook = hook_stdout(function(string, encoding, fd) {
|
||||
tfout += string.trim();
|
||||
});
|
||||
|
||||
return docker.run(DOCKERIMAGE, exec, process.stdout, {
|
||||
var terraformImage = provision.terraformImage? provision.terraformImage : DOCKERIMAGE;
|
||||
|
||||
return docker.run(terraformImage, exec, process.stdout, {
|
||||
//"Env": ["VAR_ENV=whatever"],
|
||||
"name": name,
|
||||
"WorkingDir": "/app",
|
||||
@@ -267,11 +298,11 @@ const outputs = function(provision) {
|
||||
}).then(function(data) {
|
||||
unhook();
|
||||
var container = data[1];
|
||||
console.log(`Output: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
console.log(`Terraform# Output: '${name}' (${container.id}) has finished with code: ${data[0].StatusCode}`);
|
||||
return container.remove();
|
||||
}).then(async function(data) {
|
||||
console.log(`Output: '${name}' removed!`);
|
||||
console.log("Output: tfout: " + tfout);
|
||||
console.log(`Terraform# Output: '${name}' removed!`);
|
||||
console.log("Terraform# Output: tfout: " + tfout);
|
||||
var out = JSON.parse(tfout);
|
||||
var o = {};
|
||||
for (var key in out) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qmi-cloud-worker",
|
||||
"version": "1.1.4",
|
||||
"version": "1.1.6",
|
||||
"scripts": {
|
||||
"start": "node -r esm index.js",
|
||||
"start:dev": "nodemon -r esm index.js",
|
||||
|
||||
@@ -12,7 +12,7 @@ module.exports = async function(job){
|
||||
});
|
||||
|
||||
if ( !destroyMongo ) {
|
||||
console.log(`Error: Not found Destroy object in Database (it should exist!), detroyId is: ${job.data.id}` );
|
||||
console.log(`ProcessorDestroy# Not found Destroy object in Database (it should exist!), detroyId is: ${job.data.id}` );
|
||||
return Promise.reject({"success": false, "err": "Not found Destroy object in Worker"});
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ module.exports = async function(job){
|
||||
|
||||
return Promise.resolve({"success": true, job: res});
|
||||
}).catch(function(err) {
|
||||
console.log("Processor Destroy: err", err);
|
||||
console.log("ProcessorDestroy# err", err);
|
||||
db.destroy.update(destroyMongo._id, {"status": "error", "isDestroyed": false});
|
||||
return Promise.reject({"success": false, "err": err});
|
||||
});
|
||||
|
||||
@@ -66,7 +66,7 @@ exports.creds = {
|
||||
scope: ['openid', 'email', 'profile'],
|
||||
|
||||
// Optional, 'error', 'warn' or 'info'
|
||||
loggingLevel: 'info',
|
||||
loggingLevel: 'warn',
|
||||
|
||||
// Optional. The lifetime of nonce in session or cookie, the default value is 3600 (seconds).
|
||||
nonceLifetime: null,
|
||||
|
||||
@@ -88,7 +88,7 @@ passport.use(new OIDCStrategy({
|
||||
//console.log("refreshToken", refreshToken);
|
||||
//console.log("jwtClaims", jwtClaims);
|
||||
//console.log("params", params);
|
||||
console.log("New Auth: profile", profile);
|
||||
console.log(`Passport# new login from: ${profile.upn} (${profile.displayName})` );
|
||||
// asynchronous verification, for effect...
|
||||
process.nextTick(function () {
|
||||
_findByOid(profile.oid, async function(err, user) {
|
||||
@@ -168,7 +168,7 @@ module.exports.init = function(app){
|
||||
)(req, res, next);
|
||||
},
|
||||
function(req, res) {
|
||||
console.log('We received a return from AzureAD.');
|
||||
console.log('Passport# We received a return from AzureAD.');
|
||||
res.redirect('/provisions');
|
||||
}
|
||||
);
|
||||
@@ -187,7 +187,7 @@ module.exports.init = function(app){
|
||||
)(req, res, next);
|
||||
},
|
||||
function(req, res) {
|
||||
console.log('We received a return from AzureAD.');
|
||||
console.log('Passport# We received a return from AzureAD.');
|
||||
res.redirect('/provisions');
|
||||
}
|
||||
);
|
||||
|
||||
@@ -55,7 +55,6 @@ router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) =>
|
||||
*/
|
||||
router.post('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
|
||||
try {
|
||||
console.log("BODY", req.body);
|
||||
const result = await db.subscription.add(req.body);
|
||||
return res.json(result);
|
||||
} catch (error) {
|
||||
|
||||
@@ -23,33 +23,68 @@ const passport = require('../passport');
|
||||
* description: Notifications
|
||||
*/
|
||||
router.post('/updates', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
|
||||
const now = new Date().toISOString();
|
||||
try {
|
||||
|
||||
let event = req.body;
|
||||
let event = req.body;
|
||||
|
||||
|
||||
if ( event.cloudName === 'QMI Automation' && event.provID ) {
|
||||
console.log(`DivvyCloud: update received`, event);
|
||||
let provision = await db.provision.getById(event.provID);
|
||||
if ( event.cloudName === 'QMI Automation' ) {
|
||||
|
||||
console.log(`DivvyCloud (${now})# event received for subscription (${event.cloudName}) - provision (${event.provID}) -> new status (${event.instanceState})`);
|
||||
|
||||
if ( provision ) {
|
||||
if ( event.instanceState === 'Stopped' && provision.statusVms !== 'Stopped' ) {
|
||||
console.log(`DivvyCloud: VMs for provision are now Stopped!: '${provision._id}'`);
|
||||
let timeRunning = db.utils.getNewTimeRunning(provision);
|
||||
db.provision.update(provision._id.toString(), {"statusVms": "Stopped", "timeRunning": timeRunning, "stoppedFrom": new Date(), "pendingNextAction": undefined});
|
||||
} else if ( event.instanceState === 'Running' && provision.statusVms !== 'Running' ) {
|
||||
console.log(`DivvyCloud: VMs for provision are now Running!: '${provision._id}'`);
|
||||
db.provision.update(provision._id.toString(), {"statusVms": "Running", "runningFrom": new Date(), "pendingNextAction": undefined});
|
||||
if ( event.provID && event.provID !== 'None' ) {
|
||||
|
||||
let provision = await db.provision.getById(event.provID);
|
||||
|
||||
if ( provision ) {
|
||||
|
||||
let id = provision._id.toString();
|
||||
|
||||
console.log(`DivvyCloud (${now})# provision (${id}) - scenario is (${provision.scenario} - v${provision.scenarioVersion})`);
|
||||
|
||||
if ( provision.status === 'provisioned' ) {
|
||||
|
||||
if ( event.instanceState === 'Stopped' ) {
|
||||
|
||||
if ( provision.statusVms === 'Stopped' ) {
|
||||
console.log(`DivvyCloud (${now})# provision (${id}) - VMs were already Stopped!`);
|
||||
} else {
|
||||
let timeRunning = db.utils.getNewTimeRunning(provision);
|
||||
await db.provision.update(id, {"statusVms": "Stopped", "timeRunning": timeRunning, "stoppedFrom": new Date(), "pendingNextAction": undefined});
|
||||
console.log(`DivvyCloud (${now})# provision (${id}) - VMs changed to Stopped!`);
|
||||
}
|
||||
|
||||
} else if ( event.instanceState === 'Running' ) {
|
||||
|
||||
if ( provision.statusVms === 'Running' ) {
|
||||
console.log(`DivvyCloud (${now})# provision (${id}) - VMs were already Running!`);
|
||||
} else {
|
||||
await db.provision.update(id, {"statusVms": "Running", "runningFrom": new Date(), "pendingNextAction": undefined});
|
||||
console.log(`DivvyCloud (${now})# provision (${id}) - VMs changed to Running!`);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`DivvyCloud (${now})# provision (${event.provID}) - Scenario not yet 'provisioned'`);
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`DivvyCloud (${now})# provision (${event.provID}) - Provision not found.`);
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`DivvyCloud: provision '${event.provID}' not found.`)
|
||||
console.log(`DivvyCloud (${now})# 'provID' attribute is missing.`);
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`DivvyCloud: update received for vm (${event.vmName}) for another subcription (${event.cloudName}), won't be processed`);
|
||||
//console.log(`DivvyCloud (${now}): event received for subscription (${event.cloudName}) --> won't be processed`);
|
||||
}
|
||||
|
||||
return res.json(req.body);
|
||||
|
||||
} catch (error) {
|
||||
console.log(`DivvyCloud (${now})# error!!!!`, error);
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -20,7 +20,14 @@ const passport = require('../passport');
|
||||
*/
|
||||
router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
|
||||
try {
|
||||
const result = await db.notification.get();
|
||||
var page;
|
||||
if ( req.query.page && req.query.size ) {
|
||||
page = {
|
||||
page: parseInt(req.query.page),
|
||||
size: parseInt(req.query.size)
|
||||
}
|
||||
}
|
||||
const result = await db.notification.getPage({}, page);
|
||||
return res.json(result);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
|
||||
@@ -33,11 +33,11 @@ const fs = require('fs-extra');
|
||||
* in: query
|
||||
* required: false
|
||||
* type: string
|
||||
* - name: skip
|
||||
* - name: page
|
||||
* in: query
|
||||
* required: false
|
||||
* type: integer
|
||||
* - name: limit
|
||||
* - name: size
|
||||
* in: query
|
||||
* required: false
|
||||
* type: integer
|
||||
@@ -53,27 +53,31 @@ router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) =>
|
||||
if ( filter.isDeleted === undefined ) {
|
||||
filter.isDeleted = false;
|
||||
}
|
||||
|
||||
const result = await db.provision.get(filter, req.query.select, req.query.skip, req.query.limit, req.query.populates);
|
||||
var page;
|
||||
if ( req.query.page && req.query.size ) {
|
||||
page = {
|
||||
page: parseInt(req.query.page),
|
||||
size: parseInt(req.query.size)
|
||||
}
|
||||
}
|
||||
const result = await db.provision.getPage(filter, page, req.query.populates, req.query.select);
|
||||
|
||||
var out = {
|
||||
total: result.total,
|
||||
count: result.count
|
||||
};
|
||||
if ( result.nextSkip && result.nextLimit ) {
|
||||
out.nextUrl = new URL(req.protocol + '://' + req.get('Host') + req.baseUrl);
|
||||
if (result.next){
|
||||
result.nextUrl = new URL(req.protocol + '://' + req.get('Host') + req.baseUrl);
|
||||
if ( req.query.filter ) {
|
||||
out.nextUrl.searchParams.append("filter", req.query.filter);
|
||||
result.nextUrl.searchParams.append("filter", req.query.filter);
|
||||
}
|
||||
if ( req.query.populates ) {
|
||||
out.nextUrl.searchParams.append("populates", req.query.populates);
|
||||
result.nextUrl.searchParams.append("populates", req.query.populates);
|
||||
}
|
||||
out.nextUrl.searchParams.append("skip", result.nextSkip);
|
||||
out.nextUrl.searchParams.append("limit", result.nextLimit);
|
||||
if ( req.query.select ) {
|
||||
result.nextUrl.searchParams.append("select", req.query.select);
|
||||
}
|
||||
result.nextUrl.searchParams.append("page", result.next.page);
|
||||
result.nextUrl.searchParams.append("size", result.next.size);
|
||||
}
|
||||
out.results = result.results;
|
||||
|
||||
return res.json(out);
|
||||
|
||||
return res.json(result);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
@@ -334,7 +338,7 @@ router.post('/:id/updatetagsvms', passport.ensureAuthenticatedAndAdmin, async (r
|
||||
if (!provision) {
|
||||
return res.status(404).json({"msg": "Not found provision with id: "+req.params.id, "success": false});
|
||||
}
|
||||
var result = await azurecli.updateVmsTags(provision, tagsEdit);
|
||||
var result = await azurecli.updateVmsTags(provision._id, tagsEdit);
|
||||
return res.json({"msg": "Tags are being updated", "result": result, "success": true});
|
||||
|
||||
} catch (error) {
|
||||
|
||||
@@ -2,11 +2,26 @@ const express = require('express')
|
||||
const router = express.Router()
|
||||
const db = require('qmi-cloud-common/mongo');
|
||||
const passport = require('../passport');
|
||||
const moment = require('moment');
|
||||
const fs = require('fs-extra');
|
||||
const azurecli = require('qmi-cloud-common/azurecli');
|
||||
|
||||
import { queues, TF_APPLY_QUEUE, TF_APPLY_QSEOK_QUEUE, TF_DESTROY_QUEUE } from 'qmi-cloud-common/queues';
|
||||
|
||||
const RUNNING_PERIOD_ON_SCHEDULE = 4;
|
||||
|
||||
function timeRunningOnSchedule(p) {
|
||||
|
||||
let totalRunningTime = p.timeRunning*1000*60;
|
||||
if ( p.statusVms === 'Running' ) {
|
||||
let runningFromTime = p.runningFrom? new Date(p.runningFrom).getTime() : new Date(p.created).getTime();
|
||||
let now = new Date();
|
||||
totalRunningTime = totalRunningTime + Math.abs(now.getTime() - runningFromTime);
|
||||
}
|
||||
let duration = moment.duration(totalRunningTime);
|
||||
return Math.abs(duration.asHours());
|
||||
}
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /users:
|
||||
@@ -168,14 +183,21 @@ router.post('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (r
|
||||
return res.status(404).json({"msg": "Scenario not found "});
|
||||
}
|
||||
|
||||
const filterProvisions = {"user": req.params.userId, "isDestroyed": false, "isDeleted": false, "scenario": scenarioSource.name };
|
||||
const result = await db.provision.get(filterProvisions);
|
||||
|
||||
if ( scenarioSource.numSimultaneousProvisions && result.total >= scenarioSource.numSimultaneousProvisions ) {
|
||||
return res.status(400).json({"msg": "Number of simultaneous provisions reached for this scenario: " + scenarioSource.numSimultaneousProvisions});
|
||||
}
|
||||
|
||||
if (!req.body.vmImage || !req.body.vmImage.vm1 || !req.body.vmImage.vm1.vmType ) {
|
||||
return res.status(400).json({"msg": "Invalid vmImage"});
|
||||
}
|
||||
req.body.scenarioVersion = scenarioSource.version;
|
||||
|
||||
if ( req.body.autoShutdownData && req.body.autoShutdownData.is24x7 !== undefined ) {
|
||||
const autoShutdown = await db.provisionAutoShutdown.add(req.body.autoShutdownData);
|
||||
req.body.autoShutdown = autoShutdown._id;
|
||||
if ( req.body.scheduleData && req.body.scheduleData.is24x7 !== undefined ) {
|
||||
const schedule = await db.schedule.add(req.body.scheduleData);
|
||||
req.body.schedule = schedule._id;
|
||||
}
|
||||
|
||||
const provision = await db.provision.add(req.body);
|
||||
@@ -234,36 +256,47 @@ router.post('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (r
|
||||
* description: Provision
|
||||
*/
|
||||
router.put('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
|
||||
const provision = await db.provision.getById(req.params.id);
|
||||
let provision = await db.provision.getById(req.params.id);
|
||||
if (!provision){
|
||||
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
var resSchedule;
|
||||
if ( req.body.autoShutdownData ) {
|
||||
if ( req.body.autoShutdownData._id ) {
|
||||
resSchedule = await db.provisionAutoShutdown.update(req.body.autoShutdownData._id, req.body.autoShutdownData);
|
||||
let schedule;
|
||||
if ( req.body.scheduleData ) {
|
||||
|
||||
// -- HERE onScheduleRenewed????
|
||||
var duration = timeRunningOnSchedule(provision); //hours
|
||||
var onScheduleRenewed = req.body.scheduleData.onScheduleRenewed? req.body.scheduleData.onScheduleRenewed : 1;
|
||||
if ( duration >= (24 * RUNNING_PERIOD_ON_SCHEDULE * onScheduleRenewed) ) {
|
||||
onScheduleRenewed = Math.ceil( duration/(24*RUNNING_PERIOD_ON_SCHEDULE) ) + 1;
|
||||
console.log("APIUser# onScheduleRenewed has been incremented!! -> ", onScheduleRenewed);
|
||||
}
|
||||
req.body.scheduleData["onScheduleRenewed"] = onScheduleRenewed;
|
||||
// --
|
||||
|
||||
if ( req.body.scheduleData._id ) {
|
||||
schedule = await db.schedule.update(req.body.scheduleData._id, req.body.scheduleData);
|
||||
} else {
|
||||
resSchedule = await db.provisionAutoShutdown.add(req.body.autoShutdownData);
|
||||
schedule = await db.schedule.add(req.body.scheduleData);
|
||||
}
|
||||
var tagsEdit = {
|
||||
"24x7": resSchedule.is24x7? " " : false,
|
||||
"StartupTime": resSchedule.utcTagStartupTime || false,
|
||||
"ShutdownTime": resSchedule.utcTagShutdownTime || false
|
||||
"24x7": schedule.is24x7? " " : false,
|
||||
"StartupTime": (schedule.isStartupTimeEnable && !schedule.is24x7 && schedule.utcTagStartupTime)? schedule.utcTagStartupTime : false,
|
||||
"ShutdownTime": (!schedule.is24x7 && schedule.utcTagShutdownTime)? schedule.utcTagShutdownTime : false
|
||||
}
|
||||
azurecli.updateVmsTags(provision, tagsEdit);
|
||||
azurecli.updateVmsTags(provision._id, tagsEdit);
|
||||
}
|
||||
|
||||
var patch = {};
|
||||
let patch = {};
|
||||
if ( req.body.user ) {
|
||||
patch.user = req.body.user;
|
||||
}
|
||||
if ( resSchedule ) {
|
||||
patch.autoShutdown = resSchedule._id;
|
||||
if ( schedule ) {
|
||||
patch.schedule = schedule._id;
|
||||
}
|
||||
var result = {
|
||||
let result = {
|
||||
provision: await db.provision.update(provision._id, patch)
|
||||
}
|
||||
return res.json(result);
|
||||
@@ -351,7 +384,21 @@ router.post('/:userId/provisions/:id/deallocatevms', passport.ensureAuthenticate
|
||||
if (!provision){
|
||||
return res.status(404).json({"msg": "Not found provision with id "+req.params.id});
|
||||
}
|
||||
azurecli.deallocate(provision);
|
||||
|
||||
//Set DivvyTags according to Schedule
|
||||
if ( provision.schedule && req.body.isStartupTimeEnable !== undefined ) {
|
||||
console.log("APIUser# Set DivvyTags according to schedule");
|
||||
var schedule = await db.schedule.update(provision.schedule._id, { "isStartupTimeEnable": req.body.isStartupTimeEnable });
|
||||
var tagsEdit = {
|
||||
"24x7": schedule.is24x7? " " : false,
|
||||
"StartupTime": (schedule.isStartupTimeEnable && !schedule.is24x7 && schedule.utcTagStartupTime)? schedule.utcTagStartupTime : false,
|
||||
"ShutdownTime": (!schedule.is24x7 && schedule.utcTagShutdownTime)? schedule.utcTagShutdownTime : false
|
||||
}
|
||||
azurecli.updateVmsTags(provision._id, tagsEdit);
|
||||
}
|
||||
|
||||
azurecli.deallocate(provision._id);
|
||||
|
||||
return res.json({"statusVms": "Stopping"});
|
||||
|
||||
} catch (error) {
|
||||
@@ -392,7 +439,30 @@ router.post('/:userId/provisions/:id/startvms', passport.ensureAuthenticatedAndI
|
||||
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
|
||||
}
|
||||
|
||||
azurecli.start(provision);
|
||||
azurecli.start(provision._id);
|
||||
|
||||
//Re-enable DivvyTags according to schedule
|
||||
if ( provision.schedule ) {
|
||||
|
||||
// -- onScheduleRenewed????
|
||||
var duration = timeRunningOnSchedule(provision); //hours
|
||||
var onScheduleRenewed = provision.schedule.onScheduleRenewed? provision.schedule.onScheduleRenewed : 1;
|
||||
if ( duration >= (24 * RUNNING_PERIOD_ON_SCHEDULE * onScheduleRenewed) ) {
|
||||
onScheduleRenewed = Math.ceil( duration/(24*RUNNING_PERIOD_ON_SCHEDULE) ) + 1;
|
||||
console.log("APIUser# onScheduleRenewed has been incremented!! -> ", onScheduleRenewed);
|
||||
}
|
||||
|
||||
//let schedule = await db.schedule.update(provision.schedule._id, {"isStartupTimeEnable": true, "onScheduleRenewed": onScheduleRenewed});
|
||||
let schedule = await db.schedule.update(provision.schedule._id, {"onScheduleRenewed": onScheduleRenewed});
|
||||
|
||||
console.log("APIUser# Re-enabling DivvyTags according to schedule");
|
||||
var tagsEdit = {
|
||||
"24x7": schedule.is24x7? " " : false,
|
||||
"StartupTime": (schedule.isStartupTimeEnable && !schedule.is24x7 && schedule.utcTagStartupTime)? schedule.utcTagStartupTime : false,
|
||||
"ShutdownTime": (!schedule.is24x7 && schedule.utcTagShutdownTime)? schedule.utcTagShutdownTime : false
|
||||
}
|
||||
azurecli.updateVmsTags(provision._id, tagsEdit);
|
||||
}
|
||||
return res.json({"statusVms": "Starting"});
|
||||
|
||||
} catch (error) {
|
||||
@@ -441,7 +511,7 @@ router.post('/:userId/provisions/:id/extend', passport.ensureAuthenticatedAndIsM
|
||||
let countExtend = db.utils.getNewCountExtend(provision);
|
||||
provision = await db.provision.update(req.params.id, {"runningFrom":new Date(), "timeRunning": timeRunning, "countExtend": countExtend, "pendingNextAction": undefined});
|
||||
|
||||
console.log(`Extending running period fo provision (${provision._id}), new total extends: ${countExtend}`);
|
||||
console.log(`APIUser# Extending running period fo provision (${provision._id}), new total extends: ${countExtend}`);
|
||||
|
||||
return res.json(provision);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ function _getRedisConfig(redisUrl) {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
app.use('/arena', Arena(
|
||||
{
|
||||
queues: [
|
||||
@@ -71,7 +72,8 @@ app.use(cookieParser());
|
||||
app.use(bodyParser.urlencoded({ extended: false }))
|
||||
// parse application/json
|
||||
app.use(bodyParser.json())
|
||||
app.use(express.static(__dirname + '/../dist/qmi-cloud'));
|
||||
|
||||
app.use('/',express.static(__dirname + '/../dist/qmi-cloud'));
|
||||
|
||||
passport.init(app);
|
||||
|
||||
@@ -85,7 +87,7 @@ app.use("/api/v1/deployopts", routesApiDeployOpts);
|
||||
app.use("/api/v1/apikeys", routesApiApikeys);
|
||||
|
||||
app.get('/*',(req, res, next) =>{
|
||||
if (req.originalUrl.indexOf("/api-docs") !== -1 || req.originalUrl.indexOf("/arena") !== -1 ) {
|
||||
if (req.originalUrl.indexOf("/api-docs") !== -1 || req.originalUrl.indexOf("/arena") !== -1 || req.originalUrl.indexOf("/costexport") !== -1 || req.originalUrl.indexOf("/backendlogs") !== -1) {
|
||||
return next();
|
||||
} else {
|
||||
res.sendFile(path.join(__dirname,'/../dist/qmi-cloud/index.html'));
|
||||
@@ -100,6 +102,10 @@ app.get('/logout', function(req, res) {
|
||||
res.redirect("/");
|
||||
});
|
||||
|
||||
app.get('/backendlogs', function (req, res) {
|
||||
res.redirect(process.env.BACKEND_LOGS_URL);
|
||||
})
|
||||
|
||||
|
||||
const options = {
|
||||
definition: {
|
||||
@@ -155,6 +161,17 @@ const options = {
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
app.use('/costexport*', passport.ensureAuthenticatedAndAdmin, function(req, res){
|
||||
if ( !req.query.file ) {
|
||||
res.status(404).send("Not found");
|
||||
} else {
|
||||
res.header("Content-Type",'application/json');
|
||||
|
||||
res.sendFile(path.resolve(__dirname, '..', 'costexport', req.query.file ));
|
||||
}
|
||||
} );
|
||||
|
||||
const specs = swaggerJsdoc(options);
|
||||
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));
|
||||
|
||||
|
||||