Browse Source

init site_bilder project

master
Chris 1 year ago
parent
commit
48a12e4f37
  1. 2
      .gitignore
  2. 7
      site_builder/.github:copilot-instructions.md
  3. 61
      site_builder/README.md
  4. BIN
      site_builder/__pycache__/main.cpython-313.pyc
  5. BIN
      site_builder/__pycache__/test_find_extrema.cpython-313-pytest-8.4.0.pyc
  6. BIN
      site_builder/__pycache__/test_find_geo_extrema.cpython-313-pytest-8.4.0.pyc
  7. BIN
      site_builder/__pycache__/test_main.cpython-313-pytest-8.4.0.pyc
  8. BIN
      site_builder/__pycache__/test_main.cpython-313.pyc
  9. BIN
      site_builder/__pycache__/test_main_unittests.cpython-313-pytest-8.4.0.pyc
  10. BIN
      site_builder/__pycache__/test_read_csv_to_dict.cpython-313-pytest-8.4.0.pyc
  11. BIN
      site_builder/__pycache__/test_translate_pos.cpython-313-pytest-8.4.0.pyc
  12. 11
      site_builder/block-library-style.css
  13. BIN
      site_builder/cropped-drawing.svg_-180x180.png
  14. BIN
      site_builder/cropped-drawing.svg_-192x192.png
  15. BIN
      site_builder/cropped-drawing.svg_-270x270.png
  16. BIN
      site_builder/cropped-drawing.svg_-32x32.png
  17. BIN
      site_builder/images/20170313-180536-DSCF4779.jpg
  18. BIN
      site_builder/images/20170329-165427-DSCF4795.jpg
  19. BIN
      site_builder/images/20170403-163956-DSCF4838.jpg
  20. 3
      site_builder/images/gps.csv
  21. 76
      site_builder/images/pos.json
  22. BIN
      site_builder/images/tile_20170313-180536-DSCF4779.jpg
  23. BIN
      site_builder/images/tile_20170329-165427-DSCF4795.jpg
  24. BIN
      site_builder/images/tile_20170403-163956-DSCF4838.jpg
  25. 464
      site_builder/index.html
  26. 2
      site_builder/jquery-3.6.0.js
  27. 2
      site_builder/jquery-migrate-3.3.2.js
  28. 175
      site_builder/main.py
  29. 591
      site_builder/package-lock.json
  30. 5
      site_builder/package.json
  31. 575
      site_builder/pendel-script-5.9.10.js
  32. 315
      site_builder/pendel-style.css
  33. 5
      site_builder/pytest.ini
  34. 276
      site_builder/resonar-functions-20150302.js
  35. 77
      site_builder/resonar-pendel-child-style.css
  36. 19
      site_builder/resonar-skip-link-focus-fix-20150302.js
  37. 4965
      site_builder/resonar-style.css
  38. 42
      site_builder/test_find_geo_extrema.py
  39. 54
      site_builder/test_read_csv_to_dict.py
  40. 30
      site_builder/test_translate_pos.py

2
.gitignore vendored

@ -1,2 +1,4 @@
credentials
in/
node_modules/
.vscode

7
site_builder/.github:copilot-instructions.md

@ -0,0 +1,7 @@
---
applyTo: "*.py"
---
# Project general coding standards
## Unittests
- Use pytest for Unittests

61
site_builder/README.md

@ -0,0 +1,61 @@
Lokales Testen mit einem Webserver
-
npm install http-server
Installiert nach `node_modules`. Starten mit:
http-server ./
Struktur
-
Beispiel, wie Kachel an der gleichen Stelle platziert werden anhand einer einzelnen Spalte.Mit jeder Szene (S1 etc.) kommt eine neue Kachel hinzu (T1 etc.).
| | |S1 |S2 |S3 |S4 | |
|:-:|:-:|:---:|:----:|:----:|:----:|:-:|
|y\x| |1 |1 |1 |1 | |
| | ┌|─ |─ |─ |─ |┐ |
| 1| │| | |T1 |T3 |│ |
| 2| │| |T1 |**T3**|T2 |│ |
| 3| │|**T1**|**T2**|T2 |**T4**|│ |
| 4| │| | | | |│ |
| | └|─ |─ |─ |─ |┘ |
* Verdrängte Kacheln werden nach oben geschoben
* Über den Rand geschobene Kacheln werden ausgeblendet
Originaler Eintrag:
<g id="pendeltileid79"
class="pendel-svg-tile"
transform="translate(2681.6,1081.6)
Koordinatensystem
-
```text
(0.0)
┌───────────────────────> x, lon CANVAS
│←→ ↑ SPACE (x and y)
│ ↓
│ 0───────────────+ TILE
│ │ │
│ │ 0─────────+ │ IMAGE
│ │ │ │ │
│ │ │ 0 │ │ Middle
│ │ │ │ │
│ │ +─────────+ │
│ │ │
│ +───────────────+
│ . (xmax,ymax)
V
y, lat
```
Json
-
Das Json enthält die Konstellation der Kacheln-Positionen der einzelnen Szenen. Es werden nicht Pixel-Koordinaten sonderne die Position als Interger-Paar abgelegt. Die Pixel-Koordinate wird zur Laufzeit ermittelt (bessere Lesbarkeit des Jsons, Trenneung von Inhalt und Anzeige).

BIN
site_builder/__pycache__/main.cpython-313.pyc

Binary file not shown.

BIN
site_builder/__pycache__/test_find_extrema.cpython-313-pytest-8.4.0.pyc

Binary file not shown.

BIN
site_builder/__pycache__/test_find_geo_extrema.cpython-313-pytest-8.4.0.pyc

Binary file not shown.

BIN
site_builder/__pycache__/test_main.cpython-313-pytest-8.4.0.pyc

Binary file not shown.

BIN
site_builder/__pycache__/test_main.cpython-313.pyc

Binary file not shown.

BIN
site_builder/__pycache__/test_main_unittests.cpython-313-pytest-8.4.0.pyc

Binary file not shown.

BIN
site_builder/__pycache__/test_read_csv_to_dict.cpython-313-pytest-8.4.0.pyc

Binary file not shown.

BIN
site_builder/__pycache__/test_translate_pos.cpython-313-pytest-8.4.0.pyc

Binary file not shown.

11
site_builder/block-library-style.css

File diff suppressed because one or more lines are too long

BIN
site_builder/cropped-drawing.svg_-180x180.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
site_builder/cropped-drawing.svg_-192x192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
site_builder/cropped-drawing.svg_-270x270.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
site_builder/cropped-drawing.svg_-32x32.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

BIN
site_builder/images/20170313-180536-DSCF4779.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 KiB

BIN
site_builder/images/20170329-165427-DSCF4795.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

BIN
site_builder/images/20170403-163956-DSCF4838.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

3
site_builder/images/gps.csv

@ -0,0 +1,3 @@
20170313-180536-DSCF4779.jpg 50.1555543999528 8.95522409999722 Pendel I Baerlauchwald
20170329-165427-DSCF4795.jpg 50.103855 8.70820270007778 Pendel II Under Cover
20170403-163956-DSCF4838.jpg 50.0991754000444 8.749723299925 Pendel III Trees in a Park
1 20170313-180536-DSCF4779.jpg 50.1555543999528 8.95522409999722 Pendel I Baerlauchwald
2 20170329-165427-DSCF4795.jpg 50.103855 8.70820270007778 Pendel II Under Cover
3 20170403-163956-DSCF4838.jpg 50.0991754000444 8.749723299925 Pendel III Trees in a Park

76
site_builder/images/pos.json

@ -0,0 +1,76 @@
{
"scenes": [
{
"scene": 1,
"tiles": [
{
"tile": "pendeltileid1",
"x": 1,
"y": 3
}
]
},
{
"scene": 2,
"tiles": [
{
"tile": "pendeltileid1",
"x": 1,
"y": 2
},
{
"tile": "pendeltileid2",
"x": 1,
"y": 3
}
]
},
{
"scene": 3,
"tiles": [
{
"tile": "pendeltileid1",
"x": 1,
"y": 1
},
{
"tile": "pendeltileid2",
"x": 1,
"y": 3
},
{
"tile": "pendeltileid3",
"x": 1,
"y": 2
}
]
},
{
"scene": 4,
"tiles": [
{
"tile": "pendeltileid1",
"x": 1,
"y": 1,
"hidden": true
},
{
"tile": "pendeltileid2",
"x": 1,
"y": 2
},
{
"tile": "pendeltileid3",
"x": 1,
"y": 1
},
{
"tile": "pendeltileid4",
"x": 1,
"y": 3
}
]
}
]
}

BIN
site_builder/images/tile_20170313-180536-DSCF4779.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
site_builder/images/tile_20170329-165427-DSCF4795.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
site_builder/images/tile_20170403-163956-DSCF4838.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

464
site_builder/index.html

@ -0,0 +1,464 @@
<!DOCTYPE html>
<html lang="de" class="no-js">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="http://gmpg.org/xfn/11">
<!-- <link rel="pingback" href="https://kollegen.uber.space/pendel/xmlrpc.php"> -->
<script>
(function(html) {
html.className = html.className.replace(/\bno-js\b/, 'js')
})(document.documentElement);
</script>
<title>Pendel &#8211; Ein fortlaufendes Fotoprojekt</title>
<meta name='robots' content='max-image-preview:large'/>
<link rel='dns-prefetch' href='//fonts.googleapis.com'/>
<link rel='dns-prefetch' href='//s.w.org'/>
<style type="text/css">
img.wp-smiley, img.emoji {
display: inline !important;
border: none !important;
box-shadow: none !important;
height: 1em !important;
width: 1em !important;
margin: 0 0.07em !important;
vertical-align: -0.1em !important;
background: none !important;
padding: 0 !important;
}
</style>
<link rel='stylesheet' id='wp-block-library-css' href='block-library-style.css' type='text/css' media='all'/>
<style id='global-styles-inline-css' type='text/css'>
body {
--wp--preset--color--black: #000000;
--wp--preset--color--cyan-bluish-gray: #abb8c3;
--wp--preset--color--white: #ffffff;
--wp--preset--color--pale-pink: #f78da7;
--wp--preset--color--vivid-red: #cf2e2e;
--wp--preset--color--luminous-vivid-orange: #ff6900;
--wp--preset--color--luminous-vivid-amber: #fcb900;
--wp--preset--color--light-green-cyan: #7bdcb5;
--wp--preset--color--vivid-green-cyan: #00d084;
--wp--preset--color--pale-cyan-blue: #8ed1fc;
--wp--preset--color--vivid-cyan-blue: #0693e3;
--wp--preset--color--vivid-purple: #9b51e0;
--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg, rgba(6, 147, 227, 1) 0%, rgb(155, 81, 224) 100%);
--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg, rgb(122, 220, 180) 0%, rgb(0, 208, 130) 100%);
--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg, rgba(252, 185, 0, 1) 0%, rgba(255, 105, 0, 1) 100%);
--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg, rgba(255, 105, 0, 1) 0%, rgb(207, 46, 46) 100%);
--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg, rgb(238, 238, 238) 0%, rgb(169, 184, 195) 100%);
--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg, rgb(74, 234, 220) 0%, rgb(151, 120, 209) 20%, rgb(207, 42, 186) 40%, rgb(238, 44, 130) 60%, rgb(251, 105, 98) 80%, rgb(254, 248, 76) 100%);
--wp--preset--gradient--blush-light-purple: linear-gradient(135deg, rgb(255, 206, 236) 0%, rgb(152, 150, 240) 100%);
--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg, rgb(254, 205, 165) 0%, rgb(254, 45, 45) 50%, rgb(107, 0, 62) 100%);
--wp--preset--gradient--luminous-dusk: linear-gradient(135deg, rgb(255, 203, 112) 0%, rgb(199, 81, 192) 50%, rgb(65, 88, 208) 100%);
--wp--preset--gradient--pale-ocean: linear-gradient(135deg, rgb(255, 245, 203) 0%, rgb(182, 227, 212) 50%, rgb(51, 167, 181) 100%);
--wp--preset--gradient--electric-grass: linear-gradient(135deg, rgb(202, 248, 128) 0%, rgb(113, 206, 126) 100%);
--wp--preset--gradient--midnight: linear-gradient(135deg, rgb(2, 3, 129) 0%, rgb(40, 116, 252) 100%);
--wp--preset--duotone--dark-grayscale: url('#wp-duotone-dark-grayscale');
--wp--preset--duotone--grayscale: url('#wp-duotone-grayscale');
--wp--preset--duotone--purple-yellow: url('#wp-duotone-purple-yellow');
--wp--preset--duotone--blue-red: url('#wp-duotone-blue-red');
--wp--preset--duotone--midnight: url('#wp-duotone-midnight');
--wp--preset--duotone--magenta-yellow: url('#wp-duotone-magenta-yellow');
--wp--preset--duotone--purple-green: url('#wp-duotone-purple-green');
--wp--preset--duotone--blue-orange: url('#wp-duotone-blue-orange');
--wp--preset--font-size--small: 13px;
--wp--preset--font-size--medium: 20px;
--wp--preset--font-size--large: 36px;
--wp--preset--font-size--x-large: 42px;
}
.has-black-color {
color: var(--wp--preset--color--black) !important;
}
.has-cyan-bluish-gray-color {
color: var(--wp--preset--color--cyan-bluish-gray) !important;
}
.has-white-color {
color: var(--wp--preset--color--white) !important;
}
.has-pale-pink-color {
color: var(--wp--preset--color--pale-pink) !important;
}
.has-vivid-red-color {
color: var(--wp--preset--color--vivid-red) !important;
}
.has-luminous-vivid-orange-color {
color: var(--wp--preset--color--luminous-vivid-orange) !important;
}
.has-luminous-vivid-amber-color {
color: var(--wp--preset--color--luminous-vivid-amber) !important;
}
.has-light-green-cyan-color {
color: var(--wp--preset--color--light-green-cyan) !important;
}
.has-vivid-green-cyan-color {
color: var(--wp--preset--color--vivid-green-cyan) !important;
}
.has-pale-cyan-blue-color {
color: var(--wp--preset--color--pale-cyan-blue) !important;
}
.has-vivid-cyan-blue-color {
color: var(--wp--preset--color--vivid-cyan-blue) !important;
}
.has-vivid-purple-color {
color: var(--wp--preset--color--vivid-purple) !important;
}
.has-black-background-color {
background-color: var(--wp--preset--color--black) !important;
}
.has-cyan-bluish-gray-background-color {
background-color: var(--wp--preset--color--cyan-bluish-gray) !important;
}
.has-white-background-color {
background-color: var(--wp--preset--color--white) !important;
}
.has-pale-pink-background-color {
background-color: var(--wp--preset--color--pale-pink) !important;
}
.has-vivid-red-background-color {
background-color: var(--wp--preset--color--vivid-red) !important;
}
.has-luminous-vivid-orange-background-color {
background-color: var(--wp--preset--color--luminous-vivid-orange) !important;
}
.has-luminous-vivid-amber-background-color {
background-color: var(--wp--preset--color--luminous-vivid-amber) !important;
}
.has-light-green-cyan-background-color {
background-color: var(--wp--preset--color--light-green-cyan) !important;
}
.has-vivid-green-cyan-background-color {
background-color: var(--wp--preset--color--vivid-green-cyan) !important;
}
.has-pale-cyan-blue-background-color {
background-color: var(--wp--preset--color--pale-cyan-blue) !important;
}
.has-vivid-cyan-blue-background-color {
background-color: var(--wp--preset--color--vivid-cyan-blue) !important;
}
.has-vivid-purple-background-color {
background-color: var(--wp--preset--color--vivid-purple) !important;
}
.has-black-border-color {
border-color: var(--wp--preset--color--black) !important;
}
.has-cyan-bluish-gray-border-color {
border-color: var(--wp--preset--color--cyan-bluish-gray) !important;
}
.has-white-border-color {
border-color: var(--wp--preset--color--white) !important;
}
.has-pale-pink-border-color {
border-color: var(--wp--preset--color--pale-pink) !important;
}
.has-vivid-red-border-color {
border-color: var(--wp--preset--color--vivid-red) !important;
}
.has-luminous-vivid-orange-border-color {
border-color: var(--wp--preset--color--luminous-vivid-orange) !important;
}
.has-luminous-vivid-amber-border-color {
border-color: var(--wp--preset--color--luminous-vivid-amber) !important;
}
.has-light-green-cyan-border-color {
border-color: var(--wp--preset--color--light-green-cyan) !important;
}
.has-vivid-green-cyan-border-color {
border-color: var(--wp--preset--color--vivid-green-cyan) !important;
}
.has-pale-cyan-blue-border-color {
border-color: var(--wp--preset--color--pale-cyan-blue) !important;
}
.has-vivid-cyan-blue-border-color {
border-color: var(--wp--preset--color--vivid-cyan-blue) !important;
}
.has-vivid-purple-border-color {
border-color: var(--wp--preset--color--vivid-purple) !important;
}
.has-vivid-cyan-blue-to-vivid-purple-gradient-background {
background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;
}
.has-light-green-cyan-to-vivid-green-cyan-gradient-background {
background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;
}
.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background {
background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;
}
.has-luminous-vivid-orange-to-vivid-red-gradient-background {
background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;
}
.has-very-light-gray-to-cyan-bluish-gray-gradient-background {
background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;
}
.has-cool-to-warm-spectrum-gradient-background {
background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;
}
.has-blush-light-purple-gradient-background {
background: var(--wp--preset--gradient--blush-light-purple) !important;
}
.has-blush-bordeaux-gradient-background {
background: var(--wp--preset--gradient--blush-bordeaux) !important;
}
.has-luminous-dusk-gradient-background {
background: var(--wp--preset--gradient--luminous-dusk) !important;
}
.has-pale-ocean-gradient-background {
background: var(--wp--preset--gradient--pale-ocean) !important;
}
.has-electric-grass-gradient-background {
background: var(--wp--preset--gradient--electric-grass) !important;
}
.has-midnight-gradient-background {
background: var(--wp--preset--gradient--midnight) !important;
}
.has-small-font-size {
font-size: var(--wp--preset--font-size--small) !important;
}
.has-medium-font-size {
font-size: var(--wp--preset--font-size--medium) !important;
}
.has-large-font-size {
font-size: var(--wp--preset--font-size--large) !important;
}
.has-x-large-font-size {
font-size: var(--wp--preset--font-size--x-large) !important;
}
</style>
<link rel='stylesheet' id='pendel-style-css' href='pendel-style.css' type='text/css' media='all'/>
<link rel='stylesheet' id='resonar-style-css' href='resonar-style.css' type='text/css' media='all'/>
<link rel='stylesheet' id='pendel-child-style-css' href='resonar-pendel-child-style.css' type='text/css' media='all'/>
<link rel='stylesheet' id='resonar-fonts-css' href='https://fonts.googleapis.com/css?family=Libre+Baskerville%3A400%2C700%2C400italic%7CLato%3A400%2C700%2C900%2C400italic%2C700italic%2C900italic%7CPlayfair+Display%3A400%2C700%2C400italic%2C700italic%7CInconsolata%3A400&#038;subset=latin%2Clatin-ext' type='text/css' media='all'/>
<script type='text/javascript' src='jquery-3.6.0.js' id='jquery-core-js'></script>
<script type='text/javascript' src='jquery-migrate-3.3.2.js' id='jquery-migrate-js'></script>
<script type='text/javascript' id='pendel-script-js-extra'>
</script>
<script type='text/javascript' src='pendel-script-5.9.10.js' id='pendel-script-js'></script>
<style type="text/css">
.site-title a, .site-title a:hover, .site-title a:focus, .site-description {
color: #232323;
}
</style>
<style type="text/css" id="resonar-custom-background-css">
</style>
<link rel="icon" href="cropped-drawing.svg_-32x32.png" sizes="32x32"/>
<link rel="icon" href="cropped-drawing.svg_-192x192.png" sizes="192x192"/>
<link rel="apple-touch-icon" href="cropped-drawing.svg_-180x180.png"/>
<meta name="msapplication-TileImage" content="cropped-drawing.svg_-270x270.png"/>
</head>
<body class="home page-template page-template-template-full-width page-template-template-full-width-php page page-id-25 single custom-menu">
<div id="page" class="hfeed site">
<a class="skip-link screen-reader-text" href="#content">Springe zum Inhalt</a>
<header id="masthead" class="site-header" role="banner">
<div class="site-branding">
<p class="site-title">
<a href="https://kollegen.uber.space/pendel/" rel="home">Pendel</a>
</p>
<p class="site-description">Ein fortlaufendes Fotoprojekt</p>
</div>
<!-- .site-branding -->
</header>
<!-- .site-header -->
<div id="content" class="site-content">
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<article id="post-25" class="post-25 page type-page status-publish hentry">
<header class="entry-header">
<div class="entry-header-inner">
<div class="entry-date"></div>
<h1 class="entry-title">Leinwand</h1>
</div>
</header>
<div class="entry-content-footer">
<div class="entry-content">
<!-- Trigger/Open The Modal -->
<!--<button id="myBtn">Open Modal</button>-->
<!-- The Modal -->
<div id="pendel-modal" class="pendel-modal">
<!-- Modal content -->
<div id="pendel-modal-content" class="pendel-modal-content">
<div>
<span id="pendel-close">&times;</span>
</div>
<div id="pendel-modal-frame">
<img id="pendel-modal-image" onload="resizeToMax(this.id)">
</div>
<div id="pendel-viewer" class="pendel-viewer">
<div id="pendel-viewer-title"></div>
<div id="pendel-viewer-subtitle"></div>
</div>
</div>
</div>
<div id="pendel-content-box">
<div id="pendel-content">
<svg id="pendel-canvas" width="100%" viewBox="0 0 4003.2 2003.2">
<filter id="f1">
<feGaussianBlur stdDeviation="4"/>
</filter>
<rect width="4003.2" height="2003.2" id="pendel-canvaspaper"/>
<g id="pendeltileid1" class="pendel-svg-tile" transform="translate(2681.6,601.6)" onclick="pendelOnTileClicked('testout/20170313-180536-DSCF4779.jpg', 'Pendel I', 'Baerlauchwald','50.1555543999528','8.95522409999722')">
<g class="pendel-svg-tile-group">
<rect class="pendel-svg-tile-rect" y="-38.4" x="-38.4" width="76.8" height="76.8" filter="url(#f1)"/>
<rect class="pendel-tile-background" y="-35.2" x="-35.2" width="70.4" height="70.4"/>
<image class="pendel-tile-image" datahref="testout/tile_20170313-180536-DSCF4779.jpg" y="-35.2" x="-35.2" width="70.4" height="70.4"/>
</g>
</g>
<g id="pendeltileid2" class="pendel-svg-tile" transform="translate(2681.6,601.6)" onclick="pendelOnTileClicked('testout/20170329-165427-DSCF4795.jpg', 'Pendel II', 'Under Cover','50.103855','8.70820270007778')">
<g class="pendel-svg-tile-group">
<rect class="pendel-svg-tile-rect" y="-38.4" x="-38.4" width="76.8" height="76.8" filter="url(#f1)"/>
<rect class="pendel-tile-background" y="-35.2" x="-35.2" width="70.4" height="70.4"/>
<image class="pendel-tile-image" datahref="testout/tile_20170329-165427-DSCF4795.jpg" y="-35.2" x="-35.2" width="70.4" height="70.4"/>
</g>
</g>
<g id="pendeltileid3" class="pendel-svg-tile" transform="translate(2681.6,601.6)" onclick="pendelOnTileClicked('testout/20170403-163956-DSCF4838.jpg', 'Pendel III', 'Trees in a Park','50.0991754000444','8.749723299925')">
<g class="pendel-svg-tile-group">
<rect class="pendel-svg-tile-rect" y="-38.4" x="-38.4" width="76.8" height="76.8" filter="url(#f1)"/>
<rect class="pendel-tile-background" y="-35.2" x="-35.2" width="70.4" height="70.4"/>
<image class="pendel-tile-image" datahref="testout/tile_20170403-163956-DSCF4838.jpg" y="-35.2" x="-35.2" width="70.4" height="70.4"/>
</g>
</g>
</svg>
<div id="pendel-footer">
<div id="pendel-progress-bar" class="pendel-progress-bar-done"></div>
<div id="pendel-info-line">
<span id="pendel-page-title"></span>
/
<span id="pendel-actual-nr">3</span>
/
<span id="pendel-nr">3</span>
<span id="pendel-id" hidden="true">ffm</span>
</div>
<div id="pendel-message-line">
<span id="pendel-msg"></span>
</div>
</div>
</div>
<div id="pendel-v-slider">
<div id="pendel-v-slider-knob"></div>
</div>
</div>
<br>
</div>
<!-- .entry-content -->
<footer class="entry-footer"></footer>
<!-- .entry-footer -->
</div>
</article>
<!-- #post-## -->
</main>
<!-- .site-main -->
</div>
<!-- .content-area -->
</div>
<!-- .site-content -->
<footer id="colophon" class="site-footer" role="contentinfo">
<div class="site-info">
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
<img alt="Creative Commons Lizenzvertrag" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png"/>
</a>
<br/>
Dieses Werk ist lizenziert unter einer
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 4.0 International Lizenz</a>
</div>
<!-- .site-info -->
</footer>
<!-- .site-footer -->
</div>
<!-- .site -->
<script type='text/javascript' src='resonar-skip-link-focus-fix-20150302.js' id='resonar-skip-link-focus-fix-js'></script>
<script type='text/javascript' id='resonar-script-js-extra'>
/* <![CDATA[ */
var screenReaderText = {
"expand": "<span class=\"screen-reader-text\">Untermen\u00fc anzeigen<\/span>",
"collapse": "<span class=\"screen-reader-text\">Untermen\u00fc verbergen<\/span>"
};
var toggleButtonText = {
"menu": "Men\u00fc",
"widgets": "Widgets",
"both": "Men\u00fc & Widgets"
};
/* ]]> */
</script>
<script type='text/javascript' src='resonar-functions-20150302.js' id='resonar-script-js'></script>
</body>
</html>

2
site_builder/jquery-3.6.0.js vendored

File diff suppressed because one or more lines are too long

2
site_builder/jquery-migrate-3.3.2.js

File diff suppressed because one or more lines are too long

175
site_builder/main.py

@ -0,0 +1,175 @@
import argparse
import csv
import os.path as path
import re
importdir = 'images'
datafile = path.join(importdir, 'gps.csv')
args = None
# Imported data with appended attributes as list of lists
# Items:
# - Image file name
# - lon, lat
# - title, description
# - x, y: Default tile position
data = None
# Has message in error case
error = None
# How many tiles on the canvas in (x, y)
matrixdims = (6, 3)
def parse_args():
parser = argparse.ArgumentParser(description="Site Builder Main Program")
parser.add_argument('-i', '--importdir', type=str, help=f'Path to images directory, default={importdir}', default=importdir)
parser.add_argument('-d', '--datafile', type=str, help=f'Filename of CSV data file, default={datafile}', default=datafile)
parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output')
parser.add_argument('-vv', '--veryverbose', action='store_true', help='Enable very verbose output')
return parser.parse_args()
def log(message):
if args.verbose or args.veryverbose:
print(message)
def logvv(message):
if args.veryverbose:
print(message)
def exit_with_error(message):
print(message)
exit(1)
def read_csv_to_dict(csv_file):
"""
Reads a CSV file and returns a list of dictionaries, one per row.
Assumes the first row contains headers.
In error case, returns None
"""
global message
data = []
with open(csv_file, newline='', encoding='utf-8') as f:
reader = csv.reader(f, skipinitialspace=False, delimiter='\t')
log(f"Read lines from {csv_file}")
for row in reader:
logvv(f"Processing row: {row}")
if not row or len(row) < 4:
message = f"Invalid row: {row}"
return None
if not ' ' in row[1].strip():
message = f'Invalid location: {row[1]}'
return None
geo = re.findall(r'[\d]*[.][\d]+', row[1])
if len(geo) != 2:
message = f'Invalid loc/lon: {row[1]}'
values = [ row[0], float(geo[0]), float(geo[1]), row[2], row[3] ]
data.append(values)
logvv(f"Read row : {values}")
if len(data) == 0:
message = f'Empty file: {csv_file}'
return None
else:
log(f'Imported {len(data)} records.')
return data
def read_importdata():
global data
if not path.exists(args.importdir):
exit_with_error(f"Error: Import directory '{args.importdir}' does not exist.")
if not path.exists(args.datafile):
exit_with_error(f"Error: Data file '{args.datafile}' does not exist.")
log(f"Import directory: {args.importdir}")
log(f"Data file: {args.datafile}")
data = read_csv_to_dict(args.datafile)
if data is None:
exit_with_error(message)
log("Read successful")
def find_geo_extrema(data):
"""
Find min and max location values for lon and lat.
Returns (lonmin, lonmax, latmin, latmax) or None in error case.
"""
if len(data) == 0:
return None
lonmin = lonmax = data[0][1]
latmin = latmax = data[0][2]
for entry in data[1:]:
if entry[1] < lonmin:
lonmin = entry[1]
if entry[1] > lonmax:
lonmax = entry[1]
if entry[2] < latmin:
latmin = entry[2]
if entry[2] > latmax:
latmax = entry[2]
return (lonmin, lonmax, latmin, latmax)
def translate_pos(min, max, pos, size):
"""Values must be numbers."""
return round((pos - min) / (max - min) * size)
def append_tile_pos(data, geo_extrema, matrixdims):
"""
Adds two columns with x and y position (integer) of the tile in the canvas
"""
ret = []
for e in data:
x = translate_pos(geo_extrema[2], geo_extrema[3], e[2], matrixdims[0])
y = translate_pos(geo_extrema[0], geo_extrema[1], e[1], matrixdims[1])
e.append(x)
e.append(y)
ret.append(e)
logvv(f'Data updated: {e}')
return ret
def calculate_orig_pos():
global data
geo_extrema = find_geo_extrema(data)
data = append_tile_pos(data, geo_extrema, matrixdims)
def main():
global args
args=parse_args()
read_importdata()
calculate_orig_pos()
log("Finished.")
if __name__ == "__main__":
main()

591
site_builder/package-lock.json generated

@ -0,0 +1,591 @@
{
"name": "site-builder",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"http-server": "^14.1.1"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
"license": "MIT"
},
"node_modules/basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "5.1.2"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/corser": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
"integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"license": "MIT"
},
"node_modules/follow-redirects": {
"version": "1.15.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"license": "MIT",
"bin": {
"he": "bin/he"
}
},
"node_modules/html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
"integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
"license": "MIT",
"dependencies": {
"whatwg-encoding": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"license": "MIT",
"dependencies": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
"requires-port": "^1.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/http-server": {
"version": "14.1.1",
"resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
"integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
"license": "MIT",
"dependencies": {
"basic-auth": "^2.0.1",
"chalk": "^4.1.2",
"corser": "^2.0.1",
"he": "^1.2.0",
"html-encoding-sniffer": "^3.0.0",
"http-proxy": "^1.18.1",
"mime": "^1.6.0",
"minimist": "^1.2.6",
"opener": "^1.5.1",
"portfinder": "^1.0.28",
"secure-compare": "3.0.1",
"union": "~0.5.0",
"url-join": "^4.0.1"
},
"bin": {
"http-server": "bin/http-server"
},
"engines": {
"node": ">=12"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/opener": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
"integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
"license": "(WTFPL OR MIT)",
"bin": {
"opener": "bin/opener-bin.js"
}
},
"node_modules/portfinder": {
"version": "1.0.36",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.36.tgz",
"integrity": "sha512-gMKUzCoP+feA7t45moaSx7UniU7PgGN3hA8acAB+3Qn7/js0/lJ07fYZlxt9riE9S3myyxDCyAFzSrLlta0c9g==",
"license": "MIT",
"dependencies": {
"async": "^3.2.6",
"debug": "^4.3.6"
},
"engines": {
"node": ">= 10.12"
}
},
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"license": "MIT"
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/secure-compare": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
"integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
"license": "MIT"
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/union": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
"integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
"dependencies": {
"qs": "^6.4.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/url-join": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
"integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
"license": "MIT"
},
"node_modules/whatwg-encoding": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
"integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
"license": "MIT",
"dependencies": {
"iconv-lite": "0.6.3"
},
"engines": {
"node": ">=12"
}
}
}
}

5
site_builder/package.json

@ -0,0 +1,5 @@
{
"dependencies": {
"http-server": "^14.1.1"
}
}

575
site_builder/pendel-script-5.9.10.js

@ -0,0 +1,575 @@
//For tiles
var pendelMouseIsOver = false;
// For page scroling by wheel
var pendelWheelCount = 0;
// true, if slider is in sliding mode
var pendelIsSliding = false;
// used while sliding with pageY position in px
var pendelSlidingPos;
// Range in px that can be used for scrolling, depends on KnobHeight
var pendelSlidingLength;
// max number of pages to be scrolled
var pendelMaxPages;
// Size of a paging step in y pixel
var pendelPageStepSizePx;
// Available height
var pendelContentHeight
// create function that applies width and height to slider
// that equals dimensions of window,
//
// feel free to modify values in case you need to reduce height of slider by height of the menu or sidebar
var resize = function () {
// console.log("resize height=" + jQuery(window).height());
jQuery('#pendel-content-box').css({
width: jQuery(window).width(),
height: jQuery(window).height()
});
pendelInitialize();
};
function pendelInitialize() {
pendelContentHeight = window.innerHeight;
// console.log("contentHeight=" + pendelContentHeight);
jQuery("#pendel-v-slider").height(pendelContentHeight);
pendelWidthScaling();
pendelAdjustKnobHeight();
pendelRefreshSlider();
}
/**
* Returns true, if content is a pendel content. Use this for every global
* access.
* @returns {boolean} true, if pendel page
*/
function pendelIsPendel() {
return !(jQuery("#pendel-content").length == 0);
}
/**
* Lazy load of all thumb images.
* @returns {undefined}
*/
function loadThumbs() {
console.log("loadThumbs");
var max = 0;
var count = 0;
var progressBar = jQuery("#pendel-progress-bar");
var infoLine = jQuery("#pendel-info-line");
var msgLine = jQuery("#pendel-message-line");
var msg = jQuery("#pendel-msg");
msg.show();
infoLine.hide();
[].forEach.call(document.querySelectorAll('image[datahref]'), function (img) {
max = max + 1;
});
msg.html("Lade " + count + " von " + max + "...");
[].forEach.call(document.querySelectorAll('image[datahref]'), function (img) {
// console.log("image=" + img.getAttribute("datahref"));
img.addEventListener("load", function () {
// console.log("item=" + img.getAttribute('href'));
img.removeAttribute('datahref');
count = count + 1;
// Progress bar, fade out after loading the last tile
if (count < (max - 1))
{
progressBar.width(msgLine.outerWidth() * count / max);
progressBar.attr("class", "pendel-progress-bar-active");
msg.html("Lade " + count + " von " + max + "...");
} else {
progressBar.width(msgLine.outerWidth());
progressBar.attr("class", "pendel-progress-bar-done");
msg.html("");
msgLine.hide();
infoLine.show();
// infoLine.height(infoLine.height() + 5);
// progressBar.height(1);
}
});
img.setAttribute('href', img.getAttribute('datahref'));
});
}
jQuery(document).ready(function () {
if (!pendelIsPendel())
return;
// Map hidden page title to subheader field
jQuery("#pendel-page-title").html(jQuery(".entry-title").text());
loadThumbs();
// trigger function on each page resize
jQuery(window).on('resize', resize);
resize();
// console.log("jQuery.ready()");
// Remove browser slider
pendelInitDivMouseOver();
pendelInitSwipeVertical();
// consol.log("ready() init mouse.")
jQuery(document).mousemove(function (event) {
if (pendelIsSliding) {
var py = event.pageY;
var pos = py - pendelSlidingPos;
// console.log("slidingPos=" + slidingPos + ", move y=" + event.pageY + ", newPos=" + pos);
pendelMoveKnob(pos);
pendelSlidingPos = py;
//
if (event.stopPropagation)
event.stopPropagation();
if (event.preventDefault)
event.preventDefault();
}
}).mouseup(function () {
if (!pendelIsSliding) {
return;
}
// console.log("up");
var wasDragging = pendelIsSliding;
pendelIsSliding = false;
if (!wasDragging) {
// console.log("up");
}
});
jQuery("#pendel-v-slider-knob")
.mousedown(function (event) {
pendelIsSliding = true;
pendelSlidingPos = event.pageY;
// console.log("down at y=" + event.pageY);
});
});
function pendelMoveKnob(delta) {
// console.log("moveKnob");
var padding = parseInt(jQuery("#pendel-v-slider").css("paddingTop"));
var offset = padding + delta;
// console.log("moveKnob offset=" + offset);
pendelUpdateSliderPos(offset);
var actualPage = parseInt(jQuery("#pendel-actual-nr").text());
newValue = pendelMaxPages - Math.round(offset / pendelPageStepSizePx);
// console.log("newValue=" + newValue);
pendelChangeActualPos(actualPage, newValue);
if (newValue < 0)
pendelSwitchPage("up");
else
pendelSwitchPage("down");
}
/*
* To be called, everytime the browser window is rescaled.
* Slider should be independent of browser scaling
* @returns {undefined}
*/
function pendelWidthScaling() {
var width = 10;
jQuery("#pendel-v-slider").width(width / window.devicePixelRatio);
jQuery("#pendel-v-slider-knob").width((width) / window.devicePixelRatio);
}
/**
* pendelActualNr must be set before.
* @returns {undefined}
*/
function pendelRefreshSlider() {
// console.log("refreshSlider");
var actualPage = jQuery("#pendel-actual-nr").text();
// Nothing to scroll
if (pendelMaxPages <= 1) {
jQuery("#pendel-v-slider").hide();
jQuery("#pendel-v-slider-knob").hide();
return;
}
// console.log("slidingLength=" + pendelSlidingLength + " maxPages=" + pendelMaxPages + ", actualPage=" + actualPage);
;
var offset = (pendelMaxPages - actualPage - 1) * pendelPageStepSizePx;
pendelUpdateSliderPos(offset);
}
function pendelAdjustKnobHeight() {
var hSlider = jQuery("#pendel-v-slider").height();
console.log("hSlider=" + hSlider);
console.log("vSlider width=" + jQuery("#pendel-v-slider").width());
pendelMaxPages = jQuery("#pendel-nr").text();
var length = pendelGetSlideLength(hSlider, pendelMaxPages);
jQuery("#pendel-v-slider-knob").outerHeight(hSlider - length);
pendelSlidingLength = pendelGetSlideLength(hSlider, pendelMaxPages);
pendelPageStepSizePx = Math.round(pendelSlidingLength / (pendelMaxPages - 1));
// console.log("hSlider=" + hSlider);
// console.log("length=" + length);
// console.log("slidingLength=" + slidingLength);
}
/**
* Pages : values
* 2 10 %
* 3 20 %
* 10 80 %
* 100 95 %
* 1000 98 %
* @param {type} scrollPx pixel lenght
* @param {type} pages values between [2..initity]
* @returns {unresolved}
*/
function pendelGetSlideLength(scrollPx, pages) {
// var f = Math.cos((1 / act) * (Math.PI / 2.0));
var f = 1 - (1 / Math.log10(pages + 10));
var x = f * scrollPx;
// console.log("Len=" + Math.round(x));
return Math.round(x);
}
function pendelChangeActualPos(oldValue, newValue) {
var newAct = newValue;
if (newValue > pendelMaxPages)
newAct = pendelMaxPages;
else if (newValue < 0)
newAct = 0;
if (oldValue == newAct)
return;
// console.log("newAct=" + newAct);
jQuery("#pendel-actual-nr").text(newAct);
}
function pendelUpdateSliderPos(offset) {
// console.log("updateSliderPos() offset=" + offset);
var newOffset;
// Prevent from expand slider
if (offset < 0)
newOffset = 0;
else
newOffset = Math.min(offset, pendelSlidingLength);
// console.log("newOffset=" + newOffset);
jQuery("#pendel-v-slider").css("paddingTop", newOffset);
}
function pendelInitDivMouseOver() {
// alert('initDivMouseOver ' + jQuery("#pendelActualNr").text());
//
var div = jQuery("#pendel-canvas");
pendelMouseIsOver = false;
div.onmouseover = function () {
pendelMouseIsOver = true;
// alert('onmouseover');
};
div.onmouseout = function () {
pendelMouseIsOver = false;
// alert('onmouseout');
};
// // disabel scrolling of mobile browser
// window.addEventListener('touchmove', function (event) {
// event.preventDefault();
// return false;
// }, false);
window.addEventListener('wheel', function (e) {
var direction = '';
console.log(e.type);
e.preventDefault();
if (e.type == 'mousewheel') {
if (e.originalEvent.wheelDelta > 0) {
pendelWheelCount++;
} else {
pendelWheelCount--;
}
} else if (e.type == 'DOMMouseScroll') {
if (e.detail > 0) {
pendelWheelCount++;
} else {
pendelWheelCount--;
}
} else if (e.type == 'wheel') {
if (e.deltaY < 0) {
pendelWheelCount++;
} else {
pendelWheelCount--;
}
}
// Reduce wheel threshold by incrementing both integer value
if (pendelWheelCount >= 1) {
direction = 'up';
} else if (pendelWheelCount <= -1) {
direction = 'down';
}
if (!(direction == '')) {
pendelWheelCount = 0;
pendelSwitchPage(direction);
pendelRefreshSlider();
}
}, false);
}
// Y start pixel for swiping
var touchStart;
function pendelInitSwipeVertical() {
var len = 50;
window.addEventListener('touchstart', function (event) {
if (event.targetTouches.length == 1) {
var touch = event.targetTouches[0];
touchStart = touch.pageY;
console.log("touchStart=" + touchStart);
}
}, false);
window.addEventListener('touchmove', function (event) {
// If there's exactly one finger inside this element
if (event.targetTouches.length == 1) {
var touch = event.targetTouches[0];
// console.log(touch.pageY);
if ((touchStart - touch.pageY) >= len) {
// console.log("down");
touchStart = touch.pageY;
pendelSwitchPage('down');
pendelRefreshSlider();
} else if ((touch.pageY - touchStart) >= len) {
// console.log("up");
touchStart = touch.pageY;
pendelSwitchPage('up');
pendelRefreshSlider();
}
}
}, false);
}
// Dimesions before inserting the image
var modalViewerInitalHeight;
var modalViewerInitialWidth;
// View expects image with this ratio height / width
var imageRatio = 2 / 3;
/*
* <img id="pendel-modal-image" onload="resizeToMax(this.id)">
* @param {type} id
* @returns {undefined}
*/
function resizeToMax(id) {
return;
console.log("resizeToMax() ");
var myImage = new Image();
console.log("id=" + id);
var img = jQuery("#" + id);
// Has the original image size
myImage.src = img.attr("src");
var content = jQuery('#pendel-modal-content');
console.log("myImage.height=" + myImage.height + ", myImage.width=" + myImage.width);
var availableHeight = jQuery(window).height() - modalViewerInitalHeight;
var width = availableHeight / myImage.height * myImage.width;
var windowWidth = jQuery(window).width();
if (width > windowWidth)
width = windowWidth * 0.95;
console.log("availableHeight=" + availableHeight + ", Set width=" + width);
img.width(width);
content.width(width);
var sub = jQuery("#pendel-viewer")
}
/*
* Show cliecked image in a viewer
*/
function pendelOnTileClicked(imageSrc, title, description, lat, lon) {
// var modal = document.getElementById('pendelModal');
var span = document.getElementById("pendel-close");
var modal = document.getElementById('pendel-modal');
var content = jQuery('#pendel-modal-content');
var img = jQuery('#pendel-modal-image');
var frame = jQuery('#pendel-modal-frame');
document.getElementById("pendel-viewer-title").textContent = title + ' / ' + description;
document.getElementById("pendel-viewer-subtitle").innerHTML = lat + ", " + lon +
" <a href=\"http://www.openstreetmap.org/?mlat=" + lat + "&mlon="
+ lon + "\" target = \"_blank\" >osm</a>";
console.log("contentWidth=" + content.width() +
", contentHeight=" + content.height());
modalViewerInitialWidth = content.width();
// Calculate top and buttom border, ignore previous image
modalViewerInitalHeight = content.height();
console.log("top=" + content.offset().top);
console.log("windowHeight=" + jQuery(window).height() +
", windowWidth=" + jQuery(window).width());
console.log("modalViewerInitialWidht=" + modalViewerInitialWidth +
", modalViewerInitalHeight=" + modalViewerInitalHeight);
// Set the image to show
img.attr('src', imageSrc);
modal.className = 'pendel-modal pendel-modal-in'; // Whitespace!
img.addClass('pendel-modal-image-in');
var sub = jQuery("#pendel-viewer");
// Width by height
var frameHeight = 0.9 * (jQuery(window).height() - content.height() - content.offset().top);
var frameWidth = frameHeight / imageRatio;
// To large for the window, size by width
if (frameWidth > jQuery(window).width()) {
console.log("Calculate frame size by window width")
frameWidth = 0.9 * jQuery(window).width();
frameHeight = frameWidth * imageRatio;
}
console.log("frameWidth=" + frameWidth +
", frameHeight=" + frameHeight);
content.width(frameWidth);
img.width(frameWidth);
frame.width(frameWidth);
frame.height(frameHeight);
// When the user clicks on <span> (x), close the modal
span.onclick = function () {
closeViewer();
};
// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target === modal) {
closeViewer();
}
};
function closeViewer() {
modal.className = 'pendel-modal pendel-modal-out'; // Whitespace!
img.removeClass('pendel-modal-image-in')
img.attr('src', '');
frame.height(0);
}
}
/**
* Updates the position of tiles in depenency of the actual page nr and the direction.
* Precondition: PageNr == tileNr
* @param {String} direction [up|down]
* @returns {undefined}
*/
function pendelSwitchPage(direction) {
console.log("switchPage()");
var msg = jQuery("#pendel-msg");
jQuery("#pendel-id").hide();
// Only for debugging
// msg.hide();
var actualNr = parseInt(jQuery("#pendel-actual-nr").text());
var canvasNr = parseInt(jQuery("#pendel-nr").text());
var pendelId = jQuery("#pendel-id").text();
//
var nextNr = 0;
// Check Precondition
if (direction === 'down') {
if (actualNr < 1) {
// msg.html("geht nicht: actualNr=" + actualNr + " direction=" + direction);
return;
}
nextNr = actualNr - 1;
} else if (direction === 'up') {
if (actualNr >= canvasNr) {
// msg.html("geht nicht: actualNr=" + actualNr + " direction=" + direction);
return;
}
nextNr = actualNr + 1;
} else {
// msg.html("Unknonwn direction=" + direction);
return;
}
jQuery("#pendel-actual-nr").text(nextNr);
// For all actual visible elements
jQuery('.pendel-svg-tile').each(function (i, obj) {
var elm = jQuery(obj);
if (idFromImageId(elm.attr('id')) > nextNr) {
elm.attr("class", "pendel-svg-tile-hidden");
}
});
// for all actual hidden elements
jQuery('.pendel-svg-tile-hidden').each(function (i, obj) {
var elm = jQuery(obj);
if (idFromImageId(elm.attr('id')) <= nextNr) {
elm.attr("class", "pendel-svg-tile");
}
});
}
/**
* Updates the visibility of every tile in depenency of the actual page nr.
* Precondition: PageNr == tileNr
* @param {String} direction [up|down]
* @returns {undefined}
*/
function pendelSwitchPageOld(direction) {
console.log("switchPageOld()");
var msg = jQuery("#pendel-msg");
jQuery("#pendel-id").hide();
// Only for debugging
// msg.hide();
var actualNr = parseInt(jQuery("#pendel-actual-nr").text());
var canvasNr = parseInt(jQuery("#pendel-nr").text());
var pendelId = jQuery("#pendel-id").text();
//
var nextNr = 0;
// Check Precondition
if (direction === 'down') {
if (actualNr < 1) {
// msg.html("geht nicht: actualNr=" + actualNr + " direction=" + direction);
return;
}
nextNr = actualNr - 1;
} else if (direction === 'up') {
if (actualNr >= canvasNr) {
// msg.html("geht nicht: actualNr=" + actualNr + " direction=" + direction);
return;
}
nextNr = actualNr + 1;
} else {
// msg.html("Unknonwn direction=" + direction);
return;
}
jQuery("#pendel-actual-nr").text(nextNr);
// For all actual visible elements
jQuery('.pendel-svg-tile').each(function (i, obj) {
var elm = jQuery(obj);
if (idFromImageId(elm.attr('id')) > nextNr) {
elm.attr("class", "pendel-svg-tile-hidden");
}
});
// for all actual hidden elements
jQuery('.pendel-svg-tile-hidden').each(function (i, obj) {
var elm = jQuery(obj);
if (idFromImageId(elm.attr('id')) <= nextNr) {
elm.attr("class", "pendel-svg-tile");
}
});
}
/**
* Backwards function for the corresponding php function toImageId
* @param String $idString
* @return Integer
*/
function idFromImageId(idString) {
return idString.match(/\d+/)[0];
}

315
site_builder/pendel-style.css

@ -0,0 +1,315 @@
/*
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
*/
/*
Created on : 22.11.2017, 17:52:19
Author : chris
*/
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
.pendel-tile-background{
fill: rgb(250,250,250);
}
.pendel-tile-image {
opacity: 1;
transition: opacity 3s;
}
.pendel-tile-image[datahref] {
opacity: 0;
}
#pendel-content-box {
height: auto;
width: 100%;
min-height: 200px; /* Thinking of handheld in landscape */
display: flex;
flex-wrap: nowrap;
flex: auto;
justify-content: space-between;
}
#pendel-content{
width: 100%;
display: flex;
flex-direction: column;
padding-right: 2px;
}
#pendel-canvas{
display: flex;
flex-wrap: nowrap;
flex: auto;
width: 100%;
padding: 10px;
background:rgb(252,252,252);
}
.pendel-progress-bar-active{
opacity: 1;
background: #999;
height: 5px;
}
.pendel-progress-bar-done{
background: #999;
height: 5px;
opacity: 0;
transition: opacity 3s;
}
#pendel-footer{
border-top: #999 1px solid;
}
#pendel-info-line {
font-family: sans-serif;
font-size: x-small;
text-align: left;
font-weight: bold;
padding: 1px;
padding-left: 15px;
padding-bottom: 5px;
/*background:rgb(152,152,152);*/
}
#pendel-message-line {
font-family: sans-serif;
font-size: x-small;
text-align: center;
font-weight: bold;
padding: 1px;
padding-bottom: 5px;
/*background:rgb(152,152,152);*/
}
#pendel-v-slider {
background: whitesmoke;
padding-top: 0px;
height: auto;
}
#pendel-v-slider-knob {
background: gainsboro;
}
#pendel-canvaspaper {
fill:rgb(252,252,252);
/*stroke-width:3;*/
/*stroke:rgb(200,200,200);*/
}
.pendel-svg-tile-rect {
fill:rgb(210,210,210);
}
.pendel-svg-tile-group {
animation: pendel-shake-out 0.5s ;
}
.pendel-svg-tile-group:hover {
fill: #00cc00 ;
animation: pendel-shake-in 0.5s ;
}
.pendel-svg-tile {
visibility: visible;
opacity: 1;
animation: pendel-fade-in 0.5s linear;
}
.pendel-svg-tile-hidden {
opacity: 0;
visibility: hidden;
animation: pendel-fade-out 0.5s linear;
}
.pendel-modal {
display: block; /* none: Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
opacity: 1;
width: 100%; /* Full width */
height: 0%; /* 100%: Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.9); /* Black w/ opacity */
}
#pendel-close{
/*position: absolute;*/
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bolder;
transition: 0.3s;
cursor: default;
}
#pendel-close:hover,
#pendel-close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
/* Modal Content/Box */
.pendel-modal-content {
position: relative;
top: 0.1%;
left: auto;
margin: 1% auto;
padding-left: 0%;
padding-right: 0%;
padding-top: 0.5%;
text-align: right;
padding-bottom: 0.5%;
/*border: 1px solid #888;*/
max-width: 100%;
min-width: 200px;
height: auto;
}
#pendel-modal-frame{
background: #999;
width: 100%;
height: 0;
position: relative;
}
#pendel-modal-image{
width: 100%;
height: auto;
position: initial;
top: 0;
left: 0;
}
.pendel-viewer{
font-family: sans-serif;
text-align: rigth;
}
#pendel-close{
font-size: xx-large;
}
#pendel-viewer-title{
font-size: larger;
color: whitesmoke;
}
#pendel-viewer-subtitle{
font-size: 60%;
color: gray;
}
@media only screen and (max-width: 768px) {
#pendel-close{
font-size: x-large;
}
#pendel-viewer-title{
font-size: 80%;
}
#pendel-viewer-subtitle{
font-size: 50%;
}
}
#pendel-viewer-subtitle a{
color: gray !important;
text-decoration: none !important; /*Supressing underline doesn't work*/
}
.pendel-modal-in {
height: 100%;
}
.pendel-modal-out {
height: 0%;
/*animation: fadeout 1s;*/
}
.pendel-modal-image-in {
animation: fadein ease-in 1s;
}
.pendel-viewer-in {
/*animation: fadein 3s;*/
}
@keyframes pendel-fade-in {
0% { opacity: 0 }
100% { opacity: 1 }
}
@keyframes pendel-fade-out {
0% { opacity: 1 }
100% { opacity: 0 }
}
@keyframes pendel-shake-in {
25% {
transform: rotate(-5deg) ;
}
50% {
transform: rotate(+4deg) ;
}
75% {
transform: rotate(-3deg) ;
}
100% {
transform: rotate(+2deg) ;
}
}
@keyframes pendel-shake-out {
25% {
transform: rotate(-4deg) ;
}
50% {
transform: rotate(+3deg) ;
}
75% {
transform: rotate(-2deg) ;
}
100% {
transform: rotate(+1deg) ;
}
}
@keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeout {
from { opacity: 1;
height:100%;} /* Supress a roll up*/
to { opacity: 0;
height:100%; }
}
/*tablets and handhelds in landscape*/
/*@media only screen and (orientation: landscape ) and (max-width: 768px) {*/
/*@media only screen and (orientation: landscape) and (max-width: 768px){
#pendel-modal-content {
background-color: #feefaa;
position: relative;
top: 0;
left: auto;
margin: 1% auto; 15% from the top and centered
margin-top: 0;
padding-left: 1%;
padding-right: 1%;
padding-top: 0;
text-align: right;
padding-bottom: 0.5%;
border: 1px solid #888;
width: 600px; Could be more or less, depending on screen size
max-width: 80%;
height: auto;
}
}*/

5
site_builder/pytest.ini

@ -0,0 +1,5 @@
[pytest]
log_cli = True
; WARNING
log_cli_level = 30

276
site_builder/resonar-functions-20150302.js

@ -0,0 +1,276 @@
/* global screenReaderText */
/* global toggleButtonText */
/**
* Theme functions file.
*
* Contains handlers for navigation and widget area.
*/
( function( $ ) {
var $body = $( document.body ),
$window = $( window ),
sidebar = $( '#sidebar' ),
widgets = sidebar.find( '#secondary' ),
social = sidebar.find( '#social-navigation' ),
sidebarMenu = sidebar.find( '.main-navigation' ),
masthead = $( '#masthead' ),
sidebarToggle = masthead.find( '#sidebar-toggle' ),
menu = masthead.find( '.nav-menu' ),
mastheadHeight = masthead.outerHeight(),
headerImageHeight = $( '.header-image' ).height(),
windowWidth = window.innerWidth,
toolbarHeight,
resizeTimer;
// Add dropdown toggle that display child menu items.
$( '#sidebar .main-navigation .menu-item-has-children > a' ).after( '<button class="dropdown-toggle" aria-expanded="false">' + screenReaderText.expand + '</button>' );
// Toggle buttons and submenu items with active children menu items.
$( '#sidebar .main-navigation .current-menu-ancestor > button' ).addClass( 'toggle-on' );
$( '#sidebar .main-navigation .current-menu-ancestor > .sub-menu' ).addClass( 'toggled-on' );
$( '.dropdown-toggle' ).click( function( e ) {
var _this = $( this );
e.preventDefault();
_this.toggleClass( 'toggle-on' );
_this.next( '.children, .sub-menu' ).toggleClass( 'toggled-on' );
_this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
_this.html( _this.html() === screenReaderText.expand ? screenReaderText.collapse : screenReaderText.expand );
} );
// Move the Page Links before Sharedaddy.
$( '.single .hentry' ).each( function() {
$( this ).find( '.page-links' ).insertBefore( $( this ).find( '.sharedaddy' ).first() );
} );
// Enable sidebar toggle.
( function() {
if ( ! sidebar || ! sidebarToggle ) {
return;
}
// Hide button if there are no widgets and the menus are missing or empty.
if ( ! widgets.length && ! social.length && ( ! sidebarMenu || ! sidebarMenu.children().length ) ) {
sidebarToggle.hide();
return;
}
// Add a toggle button text.
sidebarToggle.append( toggleButtonText.widgets );
// Add an initial value for the attribute.
$( sidebarToggle ).add( sidebar ).attr( 'aria-expanded', 'false' );
sidebarToggle.on( 'click.resonar', function() {
$body.toggleClass( 'sidebar-open' ).trigger( 'resize' );
$( this ).toggleClass( 'toggled-on' );
$( this ).add( sidebar ).attr( 'aria-expanded', $( this ).add( sidebar ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false');
// Remove mejs players from sidebar
$( '#secondary .mejs-container' ).each( function( i, el ) {
if ( mejs.players[ el.id ] ) {
mejs.players[ el.id ].remove();
}
} );
// Re-initialize mediaelement players.
setTimeout( function() {
if ( window.wp && window.wp.mediaelement ) {
window.wp.mediaelement.initialize();
}
} );
// Trigger resize event to display VideoPress player.
setTimeout( function(){
if ( typeof( Event ) === 'function' ) {
window.dispatchEvent( new Event( 'resize' ) );
} else {
var event = window.document.createEvent( 'UIEvents' );
event.initUIEvent( 'resize', true, false, window, 0 );
window.dispatchEvent( event );
}
} );
} );
} )();
// Fix sub-menus for touch devices and better focus for hidden submenu items for accessibility.
( function() {
if ( ! menu || ! menu.children().length ) {
return;
}
if ( 'ontouchstart' in window ) {
menu.find( '.menu-item-has-children > a' ).on( 'touchstart.resonar', function( e ) {
var el = $( this ).parent( 'li' );
if ( ! el.hasClass( 'focus' ) ) {
e.preventDefault();
el.toggleClass( 'focus' );
el.siblings( '.focus' ).removeClass( 'focus' );
}
} );
}
menu.find( 'a' ).on( 'focus.resonar blur.resonar', function() {
$( this ).parents( '.menu-item' ).toggleClass( 'focus' );
} );
} )();
// Make Featured image full-screen.
function fullscreenFeaturedImage() {
var entryHeaderBackground = $( '.entry-header-background' ),
entryHeaderOffset = 0;
if ( ! entryHeaderBackground ) {
return;
}
// 1088 is site-main width.
if ( 1088 < $window.width() ) {
entryHeaderOffset = ( $window.width() - 1088 ) / 2;
}
toolbarHeight = $body.is( '.admin-bar' ) ? $( '#wpadminbar' ).height() : 0;
entryHeaderBackground.css( {
'height': $window.height() - ( toolbarHeight + mastheadHeight + headerImageHeight ) + 'px',
'margin-left': '-' + entryHeaderOffset + 'px',
'margin-right': '-' + entryHeaderOffset + 'px'
} );
}
// Minimum height for sidebar.
function sidebarSize() {
if ( ! sidebar ) {
return;
}
toolbarHeight = $body.is( '.admin-bar' ) ? $( '#wpadminbar' ).height() : 0;
var sidebarMinHeight = $window.height() - ( toolbarHeight + mastheadHeight + headerImageHeight );
sidebar.css( {
'min-height': sidebarMinHeight + 'px'
} );
}
// Scroll up when the arrow is clicked.
function scroll() {
if ( ! $( '#scroll-indicator' ) ) {
return;
}
$( '#scroll-indicator' ).on( 'click.resonar', function() {
$( 'html, body' ).animate( {
scrollTop: $( '#entry-header' ).offset().top + 24
}, 300 );
return false;
} );
}
// Add a class to change opacity of the arrow and to move the entry header.
$( function() {
if ( ! $( '#scroll-indicator' ) ) {
return;
}
$window.on( 'scroll.resonar', function() {
if ( 0 < $window.scrollTop() ) {
$( '#scroll-indicator, #entry-header' ).addClass ( 'scrolled' );
} else {
$( '#scroll-indicator, #entry-header' ).removeClass ( 'scrolled' );
}
} );
} );
// Add body classes to modify layout.
function bodyClasses() {
if ( 925 <= windowWidth ) {
var siteBrandingWidth = masthead.find( '.site-branding' ).width() + 32,
mainNavigationWidth = masthead.find( '.main-navigation' ).width() - 16,
mastheadWidth = masthead.width();
if ( ! widgets.length && ! social.length ) {
$body.addClass( 'no-sidebar' );
} else {
$body.removeClass( 'no-sidebar' );
}
if ( mastheadWidth < ( siteBrandingWidth + mainNavigationWidth + sidebarToggle.width() ) ) {
$body.addClass( 'menu-left' );
} else {
$body.removeClass( 'menu-left' );
}
} else {
$body.removeClass( 'no-sidebar, menu-left' );
}
}
// Add a class to big image and caption >= 1088px.
function bigImageClass() {
$( '.entry-content img.size-full' ).each( function() {
var img = $( this ),
caption = $( this ).closest( 'figure' ),
newImg = new Image();
newImg.src = img.attr( 'src' );
$( newImg ).load( function() {
var imgWidth = newImg.width;
if ( 1088 <= imgWidth ) {
$( img ).addClass( 'size-big' );
}
if ( caption.hasClass( 'wp-caption' ) && 1088 <= imgWidth ) {
caption.addClass( 'caption-big' );
caption.removeAttr( 'style' );
}
} );
} );
}
// Change the toggle button text.
function toggleButtonTxt() {
if ( 925 >= windowWidth ) {
if ( ( sidebarMenu.length || social.length ) && widgets.length ) {
sidebarToggle.html( toggleButtonText.both );
} else if ( ( sidebarMenu.length || social.length ) && ! widgets.length ) {
sidebarToggle.html( toggleButtonText.menu );
} else {
sidebarToggle.html( toggleButtonText.widgets );
}
} else {
sidebarToggle.html( toggleButtonText.widgets );
}
}
// Close Sidebar with an escape key.
$( document ).keyup( function( e ) {
if ( 27 === e.keyCode && sidebarToggle.hasClass( 'toggled-on' ) ) {
$body.removeClass( 'sidebar-open' );
sidebarToggle.removeClass( 'toggled-on' ).attr( 'aria-expanded', 'false' );
sidebar.attr( 'aria-hidden', 'true' );
}
} );
$( document ).ready( function() {
$window.on( 'resize.resonar', function() {
windowWidth = window.innerWidth;
clearTimeout( resizeTimer );
resizeTimer = setTimeout( function() {
sidebarSize();
fullscreenFeaturedImage();
bodyClasses();
toggleButtonTxt();
}, 300 );
} );
sidebarSize();
fullscreenFeaturedImage();
bodyClasses();
bigImageClass();
toggleButtonTxt();
scroll();
} );
} )( jQuery );

77
site_builder/resonar-pendel-child-style.css

@ -0,0 +1,77 @@
/*
Theme Name: Resonar Pendel Child
Theme URI:
Description: Resonar Pendel Child Theme. Full widht withoud header, footer and scrollbar
Author: CHS
Author URI: https://https://kollegen.uber.space
Template: resonar
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
Text Domain: resonar-pendel-child
*/
/* Hide Wordpress header */
body.page-template-template-full-width .site-header {
display: none;
}
/* make "parent" containers 100% width and height */
body.page-template-template-full-width{
width: 100%;
height: 100%;
overflow:hidden; /*to avoid scrollbars*/
}
body.page-template-template-full-width article{
padding: 0;
margin: 0;
height: 100%;
}
/* Content */
body.page-template-template-full-width #content #primary {
max-width: 100%;
}
body.page-template-template-full-width #content #primary .entry-header{
height: 0;
}
body.page-template-template-full-width #content #primary .entry-header-inner {
height: 0;
}
body.page-template-template-full-width #content #primary .entry-title {
padding: 0;
margin: 0;
display: none;
}
body.page-template-template-full-width #content #primary .entry-content-footer {
margin: 0;
padding: 0;
}
body.page-template-template-full-width #content #primary .entry-content {
margin: 0;
padding: 0;
}
body.page-template-template-full-width #content #primary .page {
padding: 0;
margin: 0;
}
/* Hide Wordpress footer */
body.page-template-template-full-width footer {
display: none;
}
body.page-template-template-full-width #content #primary .entry-footer {
padding: 10;
margin: 10;
}

19
site_builder/resonar-skip-link-focus-fix-20150302.js

@ -0,0 +1,19 @@
( function() {
var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1,
is_opera = navigator.userAgent.toLowerCase().indexOf( 'opera' ) > -1,
is_ie = navigator.userAgent.toLowerCase().indexOf( 'msie' ) > -1;
if ( ( is_webkit || is_opera || is_ie ) && document.getElementById && window.addEventListener ) {
window.addEventListener( 'hashchange', function() {
var element = document.getElementById( location.hash.substring( 1 ) );
if ( element ) {
if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) {
element.tabIndex = -1;
}
element.focus();
}
}, false );
}
} )();

4965
site_builder/resonar-style.css

File diff suppressed because it is too large Load Diff

42
site_builder/test_find_geo_extrema.py

@ -0,0 +1,42 @@
import pytest
import main
@pytest.fixture(autouse=True)
def patch_log(monkeypatch):
monkeypatch.setattr(main, "log", lambda msg: None)
monkeypatch.setattr(main, "logvv", lambda msg: None)
def test_find_geo_extrama_simpple():
data = [
['dummy', 50.1, 8.1 ],
['dummy', 50.2, 8.2 ],
['dummy', 50.3, 8.4 ],
['dummy', 49.3, 8.4 ],
['dummy', 49.3, 7.4 ]
]
result = main.find_geo_extrema(data)
expected = (49.3, 50.3, 7.4, 8.4)
assert result == expected
def test_find_geo_extrama_single():
data = [
['dummy', 50.1, 8.1 ]
]
result = main.find_geo_extrema(data)
expected = (50.1, 50.1, 8.1, 8.1)
assert result == expected
def test_find_geo_extrama_empty():
data = [
]
result = main.find_geo_extrema(data)
expected = None
assert result == expected

54
site_builder/test_read_csv_to_dict.py

@ -0,0 +1,54 @@
import pytest
import main
@pytest.fixture(autouse=True)
def patch_log(monkeypatch):
monkeypatch.setattr(main, "log", lambda msg: None)
monkeypatch.setattr(main, "logvv", lambda msg: None)
def test_read_csv_to_dict_basic(tmp_path):
content = (
"img1\t12.34 56.78\tfoo\tbar\n"
"img2\t90.12 34.56\tbaz\tqux\n"
)
file_path = tmp_path / "test.csv"
file_path.write_text(content, encoding="utf-8")
result = main.read_csv_to_dict(str(file_path))
expected = [
['img1', 12.34, 56.78, 'foo', 'bar'],
['img2', 90.12, 34.56, 'baz', 'qux'],
]
assert result == expected
def test_read_csv_to_dict_empty_file(tmp_path):
file_path = tmp_path / "empty.csv"
file_path.write_text("", encoding="utf-8")
assert main.read_csv_to_dict(str(file_path)) == None
def test_read_csv_to_dict_extra_spaces(tmp_path):
content = (
"img3\t 3.23 4.56 \tfoo\tbar\n"
)
file_path = tmp_path / "extra_spaces.csv"
file_path.write_text(content, encoding="utf-8")
result = main.read_csv_to_dict(str(file_path))
expected = [['img3', 3.23, 4.56, 'foo', 'bar']]
assert result == expected
def test_read_csv_to_dict_incorrect_format(tmp_path):
content = (
"img4\t44.34\tfoo\tbar\n" # missing lat in second column
)
file_path = tmp_path / "incorrect.csv"
file_path.write_text(content, encoding="utf-8")
assert main.read_csv_to_dict(str(file_path)) == None

30
site_builder/test_translate_pos.py

@ -0,0 +1,30 @@
import pytest
import main
@pytest.fixture(autouse=True)
def patch_log(monkeypatch):
monkeypatch.setattr(main, "log", lambda msg: None)
monkeypatch.setattr(main, "logvv", lambda msg: None)
def test_translate_pos_max():
assert main.translate_pos(0.0, 100.0, 100.0, 10) == 10
def test_translate_pos_min():
assert main.translate_pos(0.0, 100.0, 0.0, 10) == 0
def test_translate_pos_high():
assert main.translate_pos(10.0, 110.0, 100.1, 50) == 45
def test_translate_pos_low():
assert main.translate_pos(10.0, 110.0, 20.1, 90) == 9
Loading…
Cancel
Save