This commit is contained in:
edi 2024-01-25 17:36:49 +01:00
commit 1b698c75f7
67 changed files with 1188 additions and 0 deletions

0
.gitignore vendored Normal file
View file

214
404.html Normal file

File diff suppressed because one or more lines are too long

86
css/lite-yt-embed.css Normal file
View file

@ -0,0 +1,86 @@
/* Originally obtained from Paul Irish https://github.com/paulirish/lite-youtube-embed */
lite-youtube {
background-color: #000;
position: relative;
display: block;
contain: content;
background-position: center;
background-size: cover;
cursor: pointer;
}
/* gradient */
lite-youtube::before {
content: '';
display: block;
position: absolute;
top: 0;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);
background-position: top;
background-repeat: repeat-x;
height: 60px;
padding-bottom: 50px;
width: 100%;
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
}
/* responsive iframe with a 16:9 aspect ratio
thanks https://css-tricks.com/responsive-iframes/
*/
lite-youtube::after {
content: "";
display: block;
padding-bottom: calc(100% / (16 / 9));
}
lite-youtube > iframe {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
border: 0;
}
/* play button */
lite-youtube > .lty-playbtn {
display: block;
width: 68px;
height: 48px;
position: absolute;
cursor: pointer;
transform: translate3d(-50%, -50%, 0);
top: 50%;
left: 50%;
z-index: 1;
background-color: transparent;
/* YT's actual play button svg */
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 48"><path d="M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z" fill="red"/><path d="M45 24 27 14v20" fill="white"/></svg>');
filter: grayscale(100%);
transition: filter .1s cubic-bezier(0, 0, 0.2, 1);
border: none;
}
lite-youtube:hover > .lty-playbtn,
lite-youtube .lty-playbtn:focus {
filter: none;
}
/* Post-click styles */
lite-youtube.lyt-activated {
cursor: unset;
}
lite-youtube.lyt-activated::before,
lite-youtube.lyt-activated > .lty-playbtn {
opacity: 0;
pointer-events: none;
}
.lyt-visually-hidden {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}

37
css/styles.css.map Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
favicons/favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

BIN
favicons/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
favicons/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

BIN
fonts/Metropolis-Black.woff Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
fonts/Metropolis-Bold.woff Normal file

Binary file not shown.

BIN
fonts/Metropolis-Bold.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
fonts/Metropolis-Light.woff Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
fonts/Metropolis-Thin.woff Normal file

Binary file not shown.

BIN
fonts/Metropolis-Thin.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

1
icons/carly.svg Normal file
View file

@ -0,0 +1 @@
<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"></path></svg>

After

Width:  |  Height:  |  Size: 209 B

1
icons/check.svg Normal file
View file

@ -0,0 +1 @@
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" fill="#666"><path d="M99.941 293.748a21.78 21.78 0 0 1-7.175-16.153c0-11.938 9.823-21.765 21.764-21.765a21.772 21.772 0 0 1 15.737 6.733l85.958 83.825 164.42-194.504c18.463-21.833 51.574 6.326 33.213 28.125L234.276 392.324l-1.032 1.135c-8.327 8.55-22.218 8.74-30.773.412L99.941 293.748z"/></svg>

After

Width:  |  Height:  |  Size: 358 B

1
icons/copy.svg Normal file
View file

@ -0,0 +1 @@
<svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m366.905 108.016h-141.91c-11.048 0-20.003 8.955-20.003 20.003s8.955 20.003 20.003 20.003h141.91c11.048 0 20.003-8.955 20.003-20.003s-8.956-20.003-20.003-20.003z"/><path d="m366.905 188.027h-141.91c-11.048 0-20.003 8.955-20.003 20.003s8.955 20.003 20.003 20.003h141.91c11.047 0 20.003-8.955 20.003-20.003s-8.955-20.003-20.003-20.003z"/><path d="m286.004 268.039h-61.009c-11.048 0-20.003 8.955-20.003 20.003s8.955 20.003 20.003 20.003h61.009c11.048 0 20.003-8.955 20.003-20.003s-8.955-20.003-20.003-20.003z"/><path d="m448.028 272.039c11.048 0 20.003-8.955 20.003-20.003v-172.024c0-44.119-35.894-80.012-80.012-80.012h-184.027c-44.094 0-79.971 35.853-80.012 79.938-44.118 0-80.012 35.893-80.012 80.012v272.039c0 44.118 35.893 80.012 80.012 80.012h194.028c44.118 0 80.012-35.893 80.012-80.012v-.608c39.414-4.938 70.01-38.662 70.01-79.389 0-11.048-8.955-20.003-20.003-20.003s-20.003 8.955-20.003 20.003c0 22.054-17.942 40.001-39.996 40.006l-184.027.045h-.009c-10.685 0-20.73-4.16-28.285-11.715-7.558-7.556-11.721-17.604-11.721-28.291v-272.025c0-22.059 17.947-40.006 40.006-40.006h184.028c22.059 0 40.006 17.947 40.006 40.006v172.025c-.001 11.047 8.954 20.002 20.002 20.002zm-244.036 160.008h.02l154.002-.038c-.012 22.049-17.954 39.984-40.006 39.984h-194.027c-22.059 0-40.006-17.947-40.006-40.006v-272.039c0-22.059 17.947-40.006 40.006-40.006v232.094c0 21.375 8.325 41.471 23.441 56.583 15.113 15.11 35.2 23.428 56.57 23.428z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

1
icons/expand.svg Normal file
View file

@ -0,0 +1 @@
<svg height="512pt" viewBox="0 0 512.016 512" width="512pt" xmlns="http://www.w3.org/2000/svg"><path d="m240 426.675781h-181.332031c-32.363281 0-58.667969-26.304687-58.667969-58.667969v-309.332031c0-32.363281 26.304688-58.6679685 58.667969-58.6679685h309.332031c32.363281 0 58.667969 26.3046875 58.667969 58.6679685v181.332031c0 8.832032-7.167969 16-16 16s-16-7.167968-16-16v-181.332031c0-14.699219-11.96875-26.667969-26.667969-26.667969h-309.332031c-14.699219 0-26.667969 11.96875-26.667969 26.667969v309.332031c0 14.699219 11.96875 26.667969 26.667969 26.667969h181.332031c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0"/><path d="m496 512.007812h-138.667969c-8.832031 0-16-7.167968-16-16 0-8.832031 7.167969-16 16-16h122.667969v-122.667968c0-8.832032 7.167969-16 16-16s16 7.167968 16 16v138.667968c0 8.832032-7.167969 16-16 16zm0 0"/><path d="m496 512.007812c-4.097656 0-8.191406-1.558593-11.308594-4.691406l-181.332031-181.335937c-6.25-6.25-6.25-16.382813 0-22.632813s16.382813-6.25 22.636719 0l181.332031 181.332032c6.25 6.25 6.25 16.382812 0 22.636718-3.136719 3.132813-7.230469 4.691406-11.328125 4.691406zm0 0"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
icons/info.svg Normal file
View file

@ -0,0 +1 @@
<svg fill="none" height="270" viewBox="0 0 60 270" width="60" xmlns="http://www.w3.org/2000/svg"><g fill="#fff"><path d="m0 120c0-16.569 13.4315-30 30-30s30 13.431 30 30v120c0 16.569-13.4315 30-30 30s-30-13.431-30-30z"/><path d="m60 30c0 16.5686-13.4314 30-30 30-16.5685 0-29.99999306-13.4314-29.99999306-30 0-16.5685 13.43149306-29.99998474 29.99999306-29.99998474 16.5686 0 30 13.43148474 30 29.99998474z"/></g></svg>

After

Width:  |  Height:  |  Size: 419 B

1
icons/link.svg Normal file
View file

@ -0,0 +1 @@
<svg enable-background="new 0 0 64 64" height="512" viewBox="0 0 64 64" width="512" xmlns="http://www.w3.org/2000/svg"><g fill="#666"><path d="m19 40c1.104 0 2-.896 2-2s-.896-2-2-2c-3.86 0-7-3.14-7-7 0-1.873.728-3.628 2.059-4.95 1.313-1.322 3.068-2.05 4.941-2.05h10c3.86 0 7 3.14 7 7 0 .258-.015.509-.048.78-.174 1.574-.885 3.052-2.017 4.176-.532.54-1.137.974-1.797 1.289-.997.476-1.419 1.669-.944 2.666.476.996 1.669 1.419 2.667.943 1.08-.516 2.063-1.219 2.908-2.075 1.763-1.75 2.885-4.08 3.156-6.539.051-.413.075-.819.075-1.24 0-6.065-4.935-11-11-11h-10c-2.947 0-5.709 1.147-7.77 3.221-2.083 2.07-3.23 4.832-3.23 7.779 0 6.065 4.935 11 11 11z"/><path d="m45 28c-1.104 0-2 .896-2 2s.896 2 2 2c3.86 0 7 3.141 7 7 0 1.873-.728 3.628-2.059 4.95-1.313 1.322-3.068 2.05-4.941 2.05h-10c-3.86 0-7-3.141-7-7 0-.258.015-.509.048-.78.174-1.574.885-3.052 2.017-4.176.532-.54 1.136-.974 1.796-1.289.997-.476 1.419-1.67.944-2.667s-1.669-1.418-2.667-.944c-1.081.516-2.064 1.22-2.908 2.076-1.763 1.75-2.885 4.08-3.156 6.538-.05.415-.074.821-.074 1.242 0 6.065 4.935 11 11 11h10c2.946 0 5.709-1.147 7.77-3.221 2.083-2.07 3.23-4.833 3.23-7.779 0-6.065-4.935-11-11-11z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
icons/moon.svg Normal file
View file

@ -0,0 +1 @@
<svg height="124" viewBox="-.5 -.5 112 124" width="112" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" pointer-events="all"><path d="m54.06 11c-24.72 10.72-36.06 39.39-25.3 64.05 10.75 24.65 39.51 35.95 64.24 25.23-19.39-3.34-35.79-16.18-43.64-34.17-7.84-17.98-6.08-38.7 4.7-55.11z" transform="matrix(.90630779 -.42261826 .42261826 .90630779 -20.579796 29.170539)"/><path d="m45.5 31 8-2 2-8 2 8 8 2-8 2-2 8-2-8z"/><path d="m62 61 6-1.5 1.5-6 1.5 6 6 1.5-6 1.5-1.5 6-1.5-6z"/><path d="m77 41 8-2 2-8 2 8 8 2-8 2-2 8-2-8z"/></g></svg>

After

Width:  |  Height:  |  Size: 536 B

43
icons/next.svg Normal file
View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 492.004 492.004" style="enable-background:new 0 0 492.004 492.004;" xml:space="preserve" fill="#eee">
<g>
<g>
<path d="M484.14,226.886L306.46,49.202c-5.072-5.072-11.832-7.856-19.04-7.856c-7.216,0-13.972,2.788-19.044,7.856l-16.132,16.136
c-5.068,5.064-7.86,11.828-7.86,19.04c0,7.208,2.792,14.2,7.86,19.264L355.9,207.526H26.58C11.732,207.526,0,219.15,0,234.002
v22.812c0,14.852,11.732,27.648,26.58,27.648h330.496L252.248,388.926c-5.068,5.072-7.86,11.652-7.86,18.864
c0,7.204,2.792,13.88,7.86,18.948l16.132,16.084c5.072,5.072,11.828,7.836,19.044,7.836c7.208,0,13.968-2.8,19.04-7.872
l177.68-177.68c5.084-5.088,7.88-11.88,7.86-19.1C492.02,238.762,489.228,231.966,484.14,226.886z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

1
icons/order.svg Normal file
View file

@ -0,0 +1 @@
<svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m492 236h-347.738c-11.046 0-20 8.954-20 20s8.954 20 20 20h347.738c11.046 0 20-8.954 20-20s-8.954-20-20-20z"/><path d="m492 86h-347.738c-11.046 0-20 8.954-20 20s8.954 20 20 20h347.738c11.046 0 20-8.954 20-20s-8.954-20-20-20z"/><path d="m492 386h-347.738c-11.046 0-20 8.954-20 20s8.954 20 20 20h347.738c11.046 0 20-8.954 20-20s-8.954-20-20-20z"/><circle cx="27" cy="106" r="27"/><circle cx="27" cy="256" r="27"/><circle cx="27" cy="406" r="27"/></svg>

After

Width:  |  Height:  |  Size: 556 B

1
icons/sun.svg Normal file
View file

@ -0,0 +1 @@
<svg height="201" viewBox="-.5 -.5 201 201" width="201" xmlns="http://www.w3.org/2000/svg"><g fill="#000" pointer-events="all"><ellipse cx="100" cy="100" rx="50" ry="50"/><path d="m80 10 40 10-40 10z" transform="matrix(0 -1 1 0 80 120)"/><path d="m80 170 40 10-40 10z" transform="matrix(0 1 -1 0 280 80)"/><path d="m160 90 40 10-40 10z"/><path d="m0 90 40 10-40 10z" transform="matrix(-1 0 0 -1 40 200)"/><path d="m137 147 40 10-40 10z" transform="matrix(.70710678 .70710678 -.70710678 .70710678 157 -65.031529)"/><path d="m23 147 40 10-40 10z" transform="matrix(-.70710678 .70710678 -.70710678 -.70710678 184.421356 237.610173)"/><path d="m23 33 40 10-40 10z" transform="matrix(-.70710678 -.70710678 .70710678 -.70710678 43 103.811183)"/><path d="m137 33 40 10-40 10z" transform="matrix(.70710678 -.70710678 .70710678 .70710678 15.578644 123.610173)"/></g></svg>

After

Width:  |  Height:  |  Size: 863 B

1
images/github.svg Normal file
View file

@ -0,0 +1 @@
<svg enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m12 .5c-6.63 0-12 5.28-12 11.792 0 5.211 3.438 9.63 8.205 11.188.6.111.82-.254.82-.567 0-.28-.01-1.022-.015-2.005-3.338.711-4.042-1.582-4.042-1.582-.546-1.361-1.335-1.725-1.335-1.725-1.087-.731.084-.716.084-.716 1.205.082 1.838 1.215 1.838 1.215 1.07 1.803 2.809 1.282 3.495.981.108-.763.417-1.282.76-1.577-2.665-.295-5.466-1.309-5.466-5.827 0-1.287.465-2.339 1.235-3.164-.135-.298-.54-1.497.105-3.121 0 0 1.005-.316 3.3 1.209.96-.262 1.98-.392 3-.398 1.02.006 2.04.136 3 .398 2.28-1.525 3.285-1.209 3.285-1.209.645 1.624.24 2.823.12 3.121.765.825 1.23 1.877 1.23 3.164 0 4.53-2.805 5.527-5.475 5.817.42.354.81 1.077.81 2.182 0 1.578-.015 2.846-.015 3.229 0 .309.21.678.825.56 4.801-1.548 8.236-5.97 8.236-11.173 0-6.512-5.373-11.792-12-11.792z" fill="#212121"/></svg>

After

Width:  |  Height:  |  Size: 896 B

43
images/next.svg Normal file
View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 492.004 492.004" style="enable-background:new 0 0 492.004 492.004;" xml:space="preserve" fill="#eee">
<g>
<g>
<path d="M484.14,226.886L306.46,49.202c-5.072-5.072-11.832-7.856-19.04-7.856c-7.216,0-13.972,2.788-19.044,7.856l-16.132,16.136
c-5.068,5.064-7.86,11.828-7.86,19.04c0,7.208,2.792,14.2,7.86,19.264L355.9,207.526H26.58C11.732,207.526,0,219.15,0,234.002
v22.812c0,14.852,11.732,27.648,26.58,27.648h330.496L252.248,388.926c-5.068,5.072-7.86,11.652-7.86,18.864
c0,7.204,2.792,13.88,7.86,18.948l16.132,16.084c5.072,5.072,11.828,7.836,19.044,7.836c7.208,0,13.968-2.8,19.04-7.872
l177.68-177.68c5.084-5.088,7.88-11.88,7.86-19.1C492.02,238.762,489.228,231.966,484.14,226.886z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

43
images/search.svg Normal file
View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 511.999 511.999" style="enable-background:new 0 0 511.999 511.999;" xml:space="preserve">
<g>
<g>
<path d="M508.874,478.708L360.142,329.976c28.21-34.827,45.191-79.103,45.191-127.309c0-111.75-90.917-202.667-202.667-202.667
S0,90.917,0,202.667s90.917,202.667,202.667,202.667c48.206,0,92.482-16.982,127.309-45.191l148.732,148.732
c4.167,4.165,10.919,4.165,15.086,0l15.081-15.082C513.04,489.627,513.04,482.873,508.874,478.708z M202.667,362.667
c-88.229,0-160-71.771-160-160s71.771-160,160-160s160,71.771,160,160S290.896,362.667,202.667,362.667z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

7
js/chart.min.js vendored Normal file

File diff suppressed because one or more lines are too long

169
js/lite-yt-embed.js Normal file
View file

@ -0,0 +1,169 @@
/**
* A lightweight youtube embed. Still should feel the same to the user, just MUCH faster to initialize and paint.
*
* Author: Paul Irish
* https://github.com/paulirish/lite-youtube-embed
*
* Thx to these as the inspiration
* https://storage.googleapis.com/amp-vs-non-amp/youtube-lazy.html
* https://autoplay-youtube-player.glitch.me/
*
* Once built it, I also found these:
* https://github.com/ampproject/amphtml/blob/master/extensions/amp-youtube (👍👍)
* https://github.com/Daugilas/lazyYT
* https://github.com/vb/lazyframe
*/
class LiteYTEmbed extends HTMLElement {
connectedCallback() {
this.videoId = this.getAttribute('videoid');
let playBtnEl = this.querySelector('.lty-playbtn');
// A label for the button takes priority over a [playlabel] attribute on the custom-element
this.playLabel = (playBtnEl && playBtnEl.textContent.trim()) || this.getAttribute('playlabel') || 'Play';
/**
* Lo, the youtube placeholder image! (aka the thumbnail, poster image, etc)
*
* See https://github.com/paulirish/lite-youtube-embed/blob/master/youtube-thumbnail-urls.md
*
* TODO: Do the sddefault->hqdefault fallback
* - When doing this, apply referrerpolicy (https://github.com/ampproject/amphtml/pull/3940)
* TODO: Consider using webp if supported, falling back to jpg
*/
if (!this.style.backgroundImage) {
this.style.backgroundImage = `url("https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpg")`;
}
// Set up play button, and its visually hidden label
if (!playBtnEl) {
playBtnEl = document.createElement('button');
playBtnEl.type = 'button';
playBtnEl.classList.add('lty-playbtn');
this.append(playBtnEl);
}
if (!playBtnEl.textContent) {
const playBtnLabelEl = document.createElement('span');
playBtnLabelEl.className = 'lyt-visually-hidden';
playBtnLabelEl.textContent = this.playLabel;
playBtnEl.append(playBtnLabelEl);
}
playBtnEl.removeAttribute('href');
// On hover (or tap), warm up the TCP connections we're (likely) about to use.
this.addEventListener('pointerover', LiteYTEmbed.warmConnections, {once: true});
// Once the user clicks, add the real iframe and drop our play button
// TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time
// We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003
this.addEventListener('click', this.addIframe);
// Chrome & Edge desktop have no problem with the basic YouTube Embed with ?autoplay=1
// However Safari desktop and most/all mobile browsers do not successfully track the user gesture of clicking through the creation/loading of the iframe,
// so they don't autoplay automatically. Instead we must load an additional 2 sequential JS files (1KB + 165KB) (un-br) for the YT Player API
// TODO: Try loading the the YT API in parallel with our iframe and then attaching/playing it. #82
this.needsYTApiForAutoplay = navigator.vendor.includes('Apple') || navigator.userAgent.includes('Mobi');
}
/**
* Add a <link rel={preload | preconnect} ...> to the head
*/
static addPrefetch(kind, url, as) {
const linkEl = document.createElement('link');
linkEl.rel = kind;
linkEl.href = url;
if (as) {
linkEl.as = as;
}
document.head.append(linkEl);
}
/**
* Begin pre-connecting to warm up the iframe load
* Since the embed's network requests load within its iframe,
* preload/prefetch'ing them outside the iframe will only cause double-downloads.
* So, the best we can do is warm up a few connections to origins that are in the critical path.
*
* Maybe `<link rel=preload as=document>` would work, but it's unsupported: http://crbug.com/593267
* But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.
*/
static warmConnections() {
if (LiteYTEmbed.preconnected) return;
// The iframe document and most of its subresources come right off youtube.com
LiteYTEmbed.addPrefetch('preconnect', 'https://www.youtube-nocookie.com');
// The botguard script is fetched off from google.com
LiteYTEmbed.addPrefetch('preconnect', 'https://www.google.com');
// Not certain if these ad related domains are in the critical path. Could verify with domain-specific throttling.
LiteYTEmbed.addPrefetch('preconnect', 'https://googleads.g.doubleclick.net');
LiteYTEmbed.addPrefetch('preconnect', 'https://static.doubleclick.net');
LiteYTEmbed.preconnected = true;
}
fetchYTPlayerApi() {
if (window.YT || (window.YT && window.YT.Player)) return;
this.ytApiPromise = new Promise((res, rej) => {
var el = document.createElement('script');
el.src = 'https://www.youtube.com/iframe_api';
el.async = true;
el.onload = _ => {
YT.ready(res);
};
el.onerror = rej;
this.append(el);
});
}
async addYTPlayerIframe(params) {
this.fetchYTPlayerApi();
await this.ytApiPromise;
const videoPlaceholderEl = document.createElement('div')
this.append(videoPlaceholderEl);
const paramsObj = Object.fromEntries(params.entries());
new YT.Player(videoPlaceholderEl, {
width: '100%',
videoId: this.videoId,
playerVars: paramsObj,
events: {
'onReady': event => {
event.target.playVideo();
}
}
});
}
async addIframe(){
if (this.classList.contains('lyt-activated')) return;
this.classList.add('lyt-activated');
const params = new URLSearchParams(this.getAttribute('params') || []);
params.append('autoplay', '1');
params.append('playsinline', '1');
if (this.needsYTApiForAutoplay) {
return this.addYTPlayerIframe(params);
}
const iframeEl = document.createElement('iframe');
iframeEl.width = 560;
iframeEl.height = 315;
// No encoding necessary as [title] is safe. https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#:~:text=Safe%20HTML%20Attributes%20include
iframeEl.title = this.playLabel;
iframeEl.allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture';
iframeEl.allowFullscreen = true;
// AFAIK, the encoding here isn't necessary for XSS, but we'll do it only because this is a URL
// https://stackoverflow.com/q/64959723/89484
iframeEl.src = `https://www.youtube-nocookie.com/embed/${encodeURIComponent(this.videoId)}?${params.toString()}`;
this.append(iframeEl);
// Set focus for a11y
iframeEl.focus();
}
}
// Register custom element
customElements.define('lite-youtube', LiteYTEmbed);

440
js/w3.js Normal file
View file

@ -0,0 +1,440 @@
/* W3.JS 1.03 December 2017 by w3schools.com */
"use strict";
var w3 = {};
w3.hide = function (sel) {
w3.hideElements(w3.getElements(sel));
};
w3.hideElements = function (elements) {
var i, l = elements.length;
for (i = 0; i < l; i++) {
w3.hideElement(elements[i]);
}
};
w3.hideElement = function (element) {
w3.styleElement(element, "display", "none");
};
w3.show = function (sel, a) {
var elements = w3.getElements(sel);
if (a) {w3.hideElements(elements);}
w3.showElements(elements);
};
w3.showElements = function (elements) {
var i, l = elements.length;
for (i = 0; i < l; i++) {
w3.showElement(elements[i]);
}
};
w3.showElement = function (element) {
w3.styleElement(element, "display", "block");
};
w3.addStyle = function (sel, prop, val) {
w3.styleElements(w3.getElements(sel), prop, val);
};
w3.styleElements = function (elements, prop, val) {
var i, l = elements.length;
for (i = 0; i < l; i++) {
w3.styleElement(elements[i], prop, val);
}
};
w3.styleElement = function (element, prop, val) {
element.style.setProperty(prop, val);
};
w3.toggleShow = function (sel) {
var i, x = w3.getElements(sel), l = x.length;
for (i = 0; i < l; i++) {
if (x[i].style.display == "none") {
w3.styleElement(x[i], "display", "block");
} else {
w3.styleElement(x[i], "display", "none");
}
}
};
w3.addClass = function (sel, name) {
w3.addClassElements(w3.getElements(sel), name);
};
w3.addClassElements = function (elements, name) {
var i, l = elements.length;
for (i = 0; i < l; i++) {
w3.addClassElement(elements[i], name);
}
};
w3.addClassElement = function (element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {element.className += " " + arr2[i];}
}
};
w3.removeClass = function (sel, name) {
w3.removeClassElements(w3.getElements(sel), name);
};
w3.removeClassElements = function (elements, name) {
var i, l = elements.length, arr1, arr2, j;
for (i = 0; i < l; i++) {
w3.removeClassElement(elements[i], name);
}
};
w3.removeClassElement = function (element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
};
w3.toggleClass = function (sel, c1, c2) {
w3.toggleClassElements(w3.getElements(sel), c1, c2);
};
w3.toggleClassElements = function (elements, c1, c2) {
var i, l = elements.length;
for (i = 0; i < l; i++) {
w3.toggleClassElement(elements[i], c1, c2);
}
};
w3.toggleClassElement = function (element, c1, c2) {
var t1, t2, t1Arr, t2Arr, j, arr, allPresent;
t1 = (c1 || "");
t2 = (c2 || "");
t1Arr = t1.split(" ");
t2Arr = t2.split(" ");
arr = element.className.split(" ");
if (t2Arr.length == 0) {
allPresent = true;
for (j = 0; j < t1Arr.length; j++) {
if (arr.indexOf(t1Arr[j]) == -1) {allPresent = false;}
}
if (allPresent) {
w3.removeClassElement(element, t1);
} else {
w3.addClassElement(element, t1);
}
} else {
allPresent = true;
for (j = 0; j < t1Arr.length; j++) {
if (arr.indexOf(t1Arr[j]) == -1) {allPresent = false;}
}
if (allPresent) {
w3.removeClassElement(element, t1);
w3.addClassElement(element, t2);
} else {
w3.removeClassElement(element, t2);
w3.addClassElement(element, t1);
}
}
};
w3.getElements = function (id) {
if (typeof id == "object") {
return [id];
} else {
return document.querySelectorAll(id);
}
};
w3.filterHTML = function(id, sel, filter) {
var a, b, c, i, ii, iii, hit;
a = w3.getElements(id);
for (i = 0; i < a.length; i++) {
b = w3.getElements(sel);
for (ii = 0; ii < b.length; ii++) {
hit = 0;
if (b[ii].innerHTML.toUpperCase().indexOf(filter.toUpperCase()) > -1) {
hit = 1;
}
c = b[ii].getElementsByTagName("*");
for (iii = 0; iii < c.length; iii++) {
if (c[iii].innerHTML.toUpperCase().indexOf(filter.toUpperCase()) > -1) {
hit = 1;
}
}
if (hit == 1) {
b[ii].style.display = "";
} else {
b[ii].style.display = "none";
}
}
}
};
w3.sortHTML = function(id, sel, sortvalue) {
var a, b, i, ii, y, bytt, v1, v2, cc, j;
a = w3.getElements(id);
for (i = 0; i < a.length; i++) {
for (j = 0; j < 2; j++) {
cc = 0;
y = 1;
while (y == 1) {
y = 0;
b = a[i].querySelectorAll(sel);
for (ii = 0; ii < (b.length - 1); ii++) {
bytt = 0;
if (sortvalue) {
v1 = b[ii].querySelector(sortvalue).innerHTML.toLowerCase();
v2 = b[ii + 1].querySelector(sortvalue).innerHTML.toLowerCase();
} else {
v1 = b[ii].innerHTML.toLowerCase();
v2 = b[ii + 1].innerHTML.toLowerCase();
}
if ((j == 0 && (v1 > v2)) || (j == 1 && (v1 < v2))) {
bytt = 1;
break;
}
}
if (bytt == 1) {
b[ii].parentNode.insertBefore(b[ii + 1], b[ii]);
y = 1;
cc++;
}
}
if (cc > 0) {break;}
}
}
};
w3.sortHTMLbyNumber = function(id, sel, sortvalue) {
var a, b, i, ii, y, bytt, v1, v2, cc, j;
a = w3.getElements(id);
for (i = 0; i < a.length; i++) {
for (j = 0; j < 2; j++) {
cc = 0;
y = 1;
while (y == 1) {
y = 0;
b = a[i].querySelectorAll(sel);
for (ii = 0; ii < (b.length - 1); ii++) {
bytt = 0;
if (sortvalue) {
v1 = b[ii].querySelector(sortvalue).innerHTML.toLowerCase();
v2 = b[ii + 1].querySelector(sortvalue).innerHTML.toLowerCase();
} else {
v1 = b[ii].innerHTML.toLowerCase();
v2 = b[ii + 1].innerHTML.toLowerCase();
}
var i1 = parseInt(v1, 10);
var i2 = parseInt(v2, 10);
if(Number.isNaN(i1)) {
i1 = -1;
}
if(Number.isNaN(i2)) {
i2 = -1;
}
if ((j == 0 && (i1 > i2)) || (j == 1 && (i1 < i2))) {
bytt = 1;
break;
}
}
if (bytt == 1) {
b[ii].parentNode.insertBefore(b[ii + 1], b[ii]);
y = 1;
cc++;
}
}
if (cc > 0) {break;}
}
}
};
w3.slideshow = function (sel, ms, func) {
var i, ss, x = w3.getElements(sel), l = x.length;
ss = {};
ss.current = 1;
ss.x = x;
ss.ondisplaychange = func;
if (!isNaN(ms) || ms == 0) {
ss.milliseconds = ms;
} else {
ss.milliseconds = 1000;
}
ss.start = function() {
ss.display(ss.current)
if (ss.ondisplaychange) {ss.ondisplaychange();}
if (ss.milliseconds > 0) {
window.clearTimeout(ss.timeout);
ss.timeout = window.setTimeout(ss.next, ss.milliseconds);
}
};
ss.next = function() {
ss.current += 1;
if (ss.current > ss.x.length) {ss.current = 1;}
ss.start();
};
ss.previous = function() {
ss.current -= 1;
if (ss.current < 1) {ss.current = ss.x.length;}
ss.start();
};
ss.display = function (n) {
w3.styleElements(ss.x, "display", "none");
w3.styleElement(ss.x[n - 1], "display", "block");
}
ss.start();
return ss;
};
w3.includeHTML = function(cb) {
var z, i, elmnt, file, xhttp;
z = document.getElementsByTagName("*");
for (i = 0; i < z.length; i++) {
elmnt = z[i];
file = elmnt.getAttribute("w3-include-html");
if (file) {
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {elmnt.innerHTML = this.responseText;}
if (this.status == 404) {elmnt.innerHTML = "Page not found.";}
elmnt.removeAttribute("w3-include-html");
w3.includeHTML(cb);
}
}
xhttp.open("GET", file, true);
xhttp.send();
return;
}
}
if (cb) cb();
};
w3.getHttpData = function (file, func) {
w3.http(file, function () {
if (this.readyState == 4 && this.status == 200) {
func(this.responseText);
}
});
};
w3.getHttpObject = function (file, func) {
w3.http(file, function () {
if (this.readyState == 4 && this.status == 200) {
func(JSON.parse(this.responseText));
}
});
};
w3.displayHttp = function (id, file) {
w3.http(file, function () {
if (this.readyState == 4 && this.status == 200) {
w3.displayObject(id, JSON.parse(this.responseText));
}
});
};
w3.http = function (target, readyfunc, xml, method) {
var httpObj;
if (!method) {method = "GET"; }
if (window.XMLHttpRequest) {
httpObj = new XMLHttpRequest();
} else if (window.ActiveXObject) {
httpObj = new ActiveXObject("Microsoft.XMLHTTP");
}
if (httpObj) {
if (readyfunc) {httpObj.onreadystatechange = readyfunc;}
httpObj.open(method, target, true);
httpObj.send(xml);
}
};
w3.getElementsByAttribute = function (x, att) {
var arr = [], arrCount = -1, i, l, y = x.getElementsByTagName("*"), z = att.toUpperCase();
l = y.length;
for (i = -1; i < l; i += 1) {
if (i == -1) {y[i] = x;}
if (y[i].getAttribute(z) !== null) {arrCount += 1; arr[arrCount] = y[i];}
}
return arr;
};
w3.dataObject = {},
w3.displayObject = function (id, data) {
var htmlObj, htmlTemplate, html, arr = [], a, l, rowClone, x, j, i, ii, cc, repeat, repeatObj, repeatX = "";
htmlObj = document.getElementById(id);
htmlTemplate = init_template(id, htmlObj);
html = htmlTemplate.cloneNode(true);
arr = w3.getElementsByAttribute(html, "w3-repeat");
l = arr.length;
for (j = (l - 1); j >= 0; j -= 1) {
cc = arr[j].getAttribute("w3-repeat").split(" ");
if (cc.length == 1) {
repeat = cc[0];
} else {
repeatX = cc[0];
repeat = cc[2];
}
arr[j].removeAttribute("w3-repeat");
repeatObj = data[repeat];
if (repeatObj && typeof repeatObj == "object" && repeatObj.length != "undefined") {
i = 0;
for (x in repeatObj) {
i += 1;
rowClone = arr[j];
rowClone = w3_replace_curly(rowClone, "element", repeatX, repeatObj[x]);
a = rowClone.attributes;
for (ii = 0; ii < a.length; ii += 1) {
a[ii].value = w3_replace_curly(a[ii], "attribute", repeatX, repeatObj[x]).value;
}
(i === repeatObj.length) ? arr[j].parentNode.replaceChild(rowClone, arr[j]) : arr[j].parentNode.insertBefore(rowClone, arr[j]);
}
} else {
console.log("w3-repeat must be an array. " + repeat + " is not an array.");
continue;
}
}
html = w3_replace_curly(html, "element");
htmlObj.parentNode.replaceChild(html, htmlObj);
function init_template(id, obj) {
var template;
template = obj.cloneNode(true);
if (w3.dataObject.hasOwnProperty(id)) {return w3.dataObject[id];}
w3.dataObject[id] = template;
return template;
}
function w3_replace_curly(elmnt, typ, repeatX, x) {
var value, rowClone, pos1, pos2, originalHTML, lookFor, lookForARR = [], i, cc, r;
rowClone = elmnt.cloneNode(true);
pos1 = 0;
while (pos1 > -1) {
originalHTML = (typ == "attribute") ? rowClone.value : rowClone.innerHTML;
pos1 = originalHTML.indexOf("{{", pos1);
if (pos1 === -1) {break;}
pos2 = originalHTML.indexOf("}}", pos1 + 1);
lookFor = originalHTML.substring(pos1 + 2, pos2);
lookForARR = lookFor.split("||");
value = undefined;
for (i = 0; i < lookForARR.length; i += 1) {
lookForARR[i] = lookForARR[i].replace(/^\s+|\s+$/gm, ''); //trim
if (x) {value = x[lookForARR[i]];}
if (value == undefined && data) {value = data[lookForARR[i]];}
if (value == undefined) {
cc = lookForARR[i].split(".");
if (cc[0] == repeatX) {value = x[cc[1]]; }
}
if (value == undefined) {
if (lookForARR[i] == repeatX) {value = x;}
}
if (value == undefined) {
if (lookForARR[i].substr(0, 1) == '"') {
value = lookForARR[i].replace(/"/g, "");
} else if (lookForARR[i].substr(0,1) == "'") {
value = lookForARR[i].replace(/'/g, "");
}
}
if (value != undefined) {break;}
}
if (value != undefined) {
r = "{{" + lookFor + "}}";
if (typ == "attribute") {
rowClone.value = rowClone.value.replace(r, value);
} else {
w3_replace_html(rowClone, r, value);
}
}
pos1 = pos1 + 1;
}
return rowClone;
}
function w3_replace_html(a, r, result) {
var b, l, i, a, x, j;
if (a.hasAttributes()) {
b = a.attributes;
l = b.length;
for (i = 0; i < l; i += 1) {
if (b[i].value.indexOf(r) > -1) {b[i].value = b[i].value.replace(r, result);}
}
}
x = a.getElementsByTagName("*");
l = x.length;
a.innerHTML = a.innerHTML.replace(r, result);
}
};

5
sitemap.xml Normal file
View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
</urlset>

84
ve_logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.4 KiB