+{self.genPagePartFooter(lang)}
""")
return (s.encode("utf-8") for s in result)
+ def genHTMLStart(self, lang) -> str:
+ lang_attr = lang.info().get("language", "")
+
+ if lang_attr != "":
+ return f""""""
+
+ return ""
+
+ def genHTMLMeta(self) -> str:
+ return f'''
+
+ '''
+
+ def genHTMLMetaLanguageLink(self) -> str:
+ """Generates meta language list for search engines."""
+ languages = self.getLanguages()
+
+ s = ""
+ for language in languages:
+ s += f'
'
+
+ def genHTMLJS(self) -> str:
+ return f''
+
+ def genHTMLLanguageSelection(self, lang) -> str:
+ """Generates a dropdown selection for the language change."""
+ current_language = lang.info().get('language', '')
+ languages = self.getLanguages()
+
+ if len(languages) < 2:
+ return ""
+
+ html_option = ""
+ for language in languages:
+ html_option += f"
\n"
- def footer(self, lang):
- _ = lang.gettext
- language = lang.info().get('language', '')
return """
-
+
+
+
+
+
+
+\U0001f50d
+
"""
+
+ def genPagePartFooter(self, lang) -> str:
+ _ = lang.gettext
+
+ return """
+
"""
- def errorMessage(self, name, e, _):
- return [
- ("""
+ def genPageError(self, name, e, lang) -> list[bytes]:
+ """Generates a error page."""
+ _ = lang.gettext
+
+ h = f"""{self.genHTMLStart(lang)}
-
""" + _("Error generating %s") % _(name) +
- """
-
+
{_("Error generating %s") % _(name)}
+ {self.genHTMLMeta()}
+
-
""" + _("An error occurred!") + "
" +
-"".join(u"
%s
" % html.escape(s) for s in type(u"")(e).split(u"\n")) +
+
{_("An error occurred!")}
"""
-
-
-""").encode("utf-8") ]
+ for s in str(e).split("\n"):
+ h += f"
{html.escape(s)}
\n"
+ h += ""
+ return [h.encode("utf-8")]
def serveStatic(self, environ, start_response):
filename = environ["PATH_INFO"][len("/static/"):]
path = os.path.join(self.staticdir, filename)
if (not re.match(r"[a-zA-Z0-9_/-]+\.[a-zA-Z0-9]+", filename) or
- not os.path.exists(path)):
+ not os.path.exists(path)):
if re.match(r"samples/.*-thumb.jpg", filename):
path = os.path.join(self.staticdir, "nothing.png")
else:
- start_response("404 Not Found",
- [('Content-type', 'text/plain')])
+ start_response("404 Not Found", [('Content-type', 'text/plain')])
return [b"Not found"]
type_, encoding = mimetypes.guess_type(filename)
@@ -435,13 +497,13 @@ class BServer:
if type_ is not None and "image" in type_ and type_ != "image/svg+xml":
start_response("200 OK", [('Content-type', "%s" % type_)])
else:
- start_response("200 OK", [('Content-type', "%s; charset=%s" % (type_, encoding))])
+ start_response("200 OK", [('Content-type', f"{type_}; charset={encoding}")])
f = open(path, 'rb')
- return environ['wsgi.file_wrapper'](f, 512*1024)
+ return environ['wsgi.file_wrapper'](f, 512 * 1024)
- def getURL(self, environ):
- url = environ['wsgi.url_scheme']+'://'
+ def getURL(self, environ) -> str:
+ url = environ['wsgi.url_scheme'] + '://'
if environ.get('HTTP_HOST'):
url += environ['HTTP_HOST']
@@ -454,6 +516,7 @@ class BServer:
else:
if environ['SERVER_PORT'] != '80':
url += ':' + environ['SERVER_PORT']
+ url += quote(self.url_prefix)
url += quote(environ.get('SCRIPT_NAME', ''))
url += quote(environ.get('PATH_INFO', ''))
if environ.get('QUERY_STRING'):
@@ -461,113 +524,188 @@ class BServer:
return url
+ def serveGallery(self, environ, start_response, lang):
+ _ = lang.gettext
+ lang_name = lang.info().get('language', None)
+
+ start_response("200 OK", [('Content-type', "text/html; charset=utf-8")])
+
+ if ("Gallery", lang_name) in self._cache:
+ return self._cache[("Gallery", lang_name)]
+
+ langparam = ""
+ if lang_name:
+ langparam = "?language=" + lang_name
+
+ result = [f"""
+{self.genHTMLStart(lang)}
+
+
{_("Gallery")} - {_("Boxes.py")}
+ {self.genHTMLMeta()}
+ {self.genHTMLMetaLanguageLink()}
+ {self.genHTMLCSS()}
+ {self.genHTMLJS()}
+
+
+
+
+{self.genPagePartHeader(lang)}
+
+"""]
+ for nr, group in enumerate(self.groups):
+ result.append(f"
{_(group.title)}
\n")
+ for box in group.generators:
+ name = box.__name__
+ fn = f"samples/{name}-thumb.jpg"
+ thumbnail = f"{self.static_url}/{fn}"
+ static_filename = os.path.join(self.staticdir, fn)
+ alt = f"{_(name)}"
+ href = f"{name}{langparam}"
+ if not os.path.exists(static_filename):
+ result.append(f"""
{_(name)}
{_(box.__doc__)}\n""")
+ else:
+ result.append(f"""
\n""")
+
+ result.append(f"""
+
+
+{self.genPagePartFooter(lang)}
+
+
+"""
+ )
+ self._cache[("Gallery", lang_name)] = [s.encode("utf-8") for s in result]
+ return self._cache[("Gallery", lang_name)]
+
def serve(self, environ, start_response):
+ # serve favicon from static for generated SVGs
+ if environ["PATH_INFO"] == "favicon.ico":
+ environ["PATH_INFO"] = "/static/favicon.ico"
if environ["PATH_INFO"].startswith("/static/"):
return self.serveStatic(environ, start_response)
status = '200 OK'
headers = [('Content-type', 'text/html; charset=utf-8'), ('X-XSS-Protection', '1; mode=block'), ('X-Content-Type-Options', 'nosniff'), ('x-frame-options', 'SAMEORIGIN'), ('Referrer-Policy', 'no-referrer')]
- d = parse_qs(environ.get('QUERY_STRING', ''))
name = environ["PATH_INFO"][1:]
- args = [unquote_plus(arg) for arg in
- environ.get('QUERY_STRING', '').split("&")]
+ args = [unquote_plus(arg) for arg in environ.get('QUERY_STRING', '').split("&")]
+ render = "0"
+ for arg in args:
+ if arg.startswith("render="):
+ render = arg[len("render="):]
lang = self.getLanguage(args, environ.get("HTTP_ACCEPT_LANGUAGE", ""))
_ = lang.gettext
+ if not name or name == "Gallery":
+ return self.serveGallery(environ, start_response, lang)
+
box_cls = self.boxes.get(name, None)
if not box_cls:
start_response(status, headers)
- return self.menu(lang)
- if name == "TrayLayout2":
- box = box_cls(self, webargs=True)
- else:
- box = box_cls()
+ lang_name = lang.info().get('language', None)
+ if lang_name not in self._cache:
+ self._cache[lang_name] = list(self.genPageMenu(lang))
+ return self._cache[lang_name]
- if "render=1" not in args:
- defaults = { }
+ box = box_cls()
+
+ box.translations = lang
+
+ if render == "0":
+ defaults = {}
for a in args:
kv = a.split('=')
if len(kv) == 2:
k, v = kv
defaults[k] = html.escape(v, True)
start_response(status, headers)
- return self.args2html(name, box, lang, "./" + name, defaults=defaults)
- else:
- args = ["--"+ arg for arg in args if arg != "render=1"]
- try:
- box.parseArgs(args)
- except (ArgumentParserError) as e:
- start_response(status, headers)
- return self.errorMessage(name, e, _)
- if name == "TrayLayout":
- start_response(status, headers)
- box.fillDefault(box.x, box.y)
- layout2 = boxes.generators.traylayout.TrayLayout2(self, webargs=True)
- layout2.argparser.set_defaults(layout=str(box))
- return self.args2html(
- name, layout2, lang, action="TrayLayout2")
- if name == "TrayLayout2":
- try:
- box.parse(box.layout.split("\n"))
- except Exception as e:
- start_response(status, headers)
- return self.errorMessage(name, e, _)
+ return self.args2html_cached(name, box, lang, "./" + name, defaults=defaults)
- try:
- fd, box.output = tempfile.mkstemp()
- box.metadata["url"] = self.getURL(environ)
- box.open()
- box.render()
- box.close()
- except Exception as e:
- if not isinstance(e, ValueError):
- print("Exception during rendering:")
- traceback.print_exc()
- start_response("500 Internal Server Error",
- headers)
- return self.errorMessage(name, e, _)
+ args = ["--" + arg for arg in args if not arg.startswith("render=")]
+ try:
+ box.parseArgs(args)
+ except ArgumentParserError as e:
+ start_response(status, headers)
+ return self.genPageError(name, e, lang)
- http_headers = box.formats.http_headers.get(
- box.format,
- [('Content-type', 'application/unknown; charset=utf-8')])[:]
+ try:
+ box.metadata["url"] = self.getURL(environ)
+ box.metadata["url_short"] = filter_url(box.metadata["url"],
+ box.non_default_args)
+ box.open()
+ box.render()
+ data = box.close()
+ except Exception as e:
+ if not isinstance(e, ValueError):
+ print("Exception during rendering:")
+ traceback.print_exc()
+ start_response("500 Internal Server Error", headers)
+ return self.genPageError(name, e, lang)
- if box.format != "svg":
- extension = box.format
- if extension == "svg_Ponoko":
- extension = "svg"
- http_headers.append(('Content-Disposition', 'attachment; filename="%s.%s"' % (box.__class__.__name__, extension)))
+ http_headers = box.formats.http_headers.get(box.format, [('Content-type', 'application/unknown; charset=utf-8')])[:]
+ # Prevent crawlers.
+ http_headers.append(('X-Robots-Tag', 'noindex,nofollow'))
+
+ if render == "3":
+ http_headers = [('Content-type', 'image/png')]
+ http_headers.append(('X-Robots-Tag', 'noindex,nofollow'))
+ qr_format = "png"
+ fn = box.__class__.__name__
start_response(status, http_headers)
- result = open(box.output, 'rb').readlines()
- os.close(fd)
- os.remove(box.output)
- return (l for l in result)
+ qrcode = get_qrcode(box.metadata["url_short"], qr_format)
+ return (qrcode,)
+
+ if box.format != "svg" or render == "2":
+ extension = box.format
+ if extension == "svg_Ponoko":
+ extension = "svg"
+ http_headers.append(('Content-Disposition', f'attachment; filename="{box.__class__.__name__}.{extension}"'))
+ start_response(status, http_headers)
+ return environ['wsgi.file_wrapper'](data, 512 * 1024)
-if __name__=="__main__":
- host = ''
- port = 8000
- if len(sys.argv) > 1:
- tmp = sys.argv[1].split(':')
- if len(tmp) == 2:
- host = tmp[0]
- port = int(tmp[1])
- else:
- port = int(tmp[0])
+def get_qrcode(url, format):
+ if url is None:
+ url = "no url"
+ img = qrcode.make(url)
+ image_bytes = io.BytesIO()
+ img.save(image_bytes, format=format)
+ return image_bytes.getvalue()
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+
+ parser.add_argument("--host", default="")
+ parser.add_argument("--port", type=int, default=8000)
+ parser.add_argument("--url_prefix", default="",
+ help="URL path to Boxes.py instance")
+ parser.add_argument("--static_url", default="static",
+ help="URL of static content")
+ args = parser.parse_args()
+
+ boxserver = BServer(url_prefix=args.url_prefix, static_url=args.static_url)
+
fc = FileChecker()
fc.start()
- boxserver = BServer()
- httpd = make_server(host, port, boxserver.serve)
- print("BoxesServer serving on host:port %s:%s..." % (host, port) )
+
+ httpd = make_server(args.host, args.port, boxserver.serve)
+ print(f"BoxesServer serving on {args.host}:{args.port}...")
try:
httpd.serve_forever()
except KeyboardInterrupt:
fc.stop()
httpd.server_close()
print("BoxesServer stops.")
+
+
+if __name__ == "__main__":
+ main()
else:
- application = BServer().serve
-
-
+ boxserver = BServer(url_prefix='/boxes.py', static_url="https://florianfesti.github.io/boxes/static")
+ application = boxserver.serve
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/scripts/gen_thumbnails.sh b/extensions/fablabchemnitz/boxes.py/boxes/scripts/gen_thumbnails.sh
index 54a314d..15d12a4 100755
--- a/extensions/fablabchemnitz/boxes.py/boxes/scripts/gen_thumbnails.sh
+++ b/extensions/fablabchemnitz/boxes.py/boxes/scripts/gen_thumbnails.sh
@@ -15,7 +15,7 @@ thumbnail() {
find "$STATIC_DIR" -name '*.jpg' ! -name '*-thumb.jpg' -type f | while read -r f
do
- f_=$(echo "$f" | sed -E -e 's@([/.])@\\\1@g')
+ f_=$(echo "$f" | sed -E -e 's@([.])@\\\1@g')
checksum=$(grep "$f_" "$STATIC_DIR"samples.sha256 || /bin/true)
if [ -n "$checksum" ]
then
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts.css b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts.css
index 4228f45..7747f4c 100644
--- a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts.css
+++ b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts.css
@@ -1,36 +1,41 @@
-/* vietnamese */
+/*https://github.com/fontsource/fontsource/tree/main/fonts/google/bungee-shade#readme*/
+/*Font version (provided by source): v11.*/
+/* bungee-shade-vietnamese-400-normal*/
@font-face {
font-family: 'Bungee Shade';
font-style: normal;
- font-weight: 400;
font-display: swap;
- src: local('Bungee Shade'), local('BungeeShade-Regular'), url(fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc5ijTnwE.woff2) format('woff2');
- unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
+ font-weight: 400;
+ src: url('./fonts/bungeeshade/bungee-shade-vietnamese-400-normal.woff2') format('woff2');
+ unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB;
}
-/* latin-ext */
+/* bungee-shade-latin-ext-400-normal*/
@font-face {
font-family: 'Bungee Shade';
font-style: normal;
- font-weight: 400;
font-display: swap;
- src: local('Bungee Shade'), local('BungeeShade-Regular'), url(fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc5yjTnwE.woff2) format('woff2');
- unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
+ font-weight: 400;
+ src: url('./fonts/bungeeshade/bungee-shade-latin-ext-400-normal.woff2') format('woff2');
+ unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
-/* latin */
+/* bungee-shade-latin-400-normal*/
@font-face {
font-family: 'Bungee Shade';
font-style: normal;
- font-weight: 400;
font-display: swap;
- src: local('Bungee Shade'), local('BungeeShade-Regular'), url(fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc6SjT.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+ font-weight: 400;
+ src: url('./fonts/bungeeshade/bungee-shade-latin-400-normal.woff2') format('woff2');
+ unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
-/* latin */
+
+/*https://github.com/fontsource/fontsource/tree/main/fonts/google/luckiest-guy*/
+/*Font version (provided by source): v18*/
+/* luckiest-guy-latin-400-normal*/
@font-face {
font-family: 'Luckiest Guy';
font-style: normal;
- font-weight: 400;
font-display: swap;
- src: local('Luckiest Guy Regular'), local('LuckiestGuy-Regular'), url(fonts/luckiestguy/v8/_gP_1RrxsjcxVyin9l9n_j2hTd52.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+ font-weight: 400;
+ src: url('./fonts/luckiestguy/luckiest-guy-latin-400-normal.woff2') format('woff2');
+ unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-latin-400-normal.woff2 b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-latin-400-normal.woff2
new file mode 100644
index 0000000..72bd6c6
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-latin-400-normal.woff2 differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-latin-ext-400-normal.woff2 b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-latin-ext-400-normal.woff2
new file mode 100644
index 0000000..2583d29
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-latin-ext-400-normal.woff2 differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-vietnamese-400-normal.woff2 b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-vietnamese-400-normal.woff2
new file mode 100644
index 0000000..5819b92
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/bungee-shade-vietnamese-400-normal.woff2 differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc5ijTnwE.woff2 b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc5ijTnwE.woff2
deleted file mode 100644
index 75a661e..0000000
Binary files a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc5ijTnwE.woff2 and /dev/null differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc5yjTnwE.woff2 b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc5yjTnwE.woff2
deleted file mode 100644
index 0fb5357..0000000
Binary files a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc5yjTnwE.woff2 and /dev/null differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc6SjT.woff2 b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc6SjT.woff2
deleted file mode 100644
index 6df716c..0000000
Binary files a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/bungeeshade/v3/DtVkJxarWL0t2KdzK3oI_jkc6SjT.woff2 and /dev/null differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/luckiestguy/luckiest-guy-latin-400-normal.woff2 b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/luckiestguy/luckiest-guy-latin-400-normal.woff2
new file mode 100644
index 0000000..a1c865f
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/luckiestguy/luckiest-guy-latin-400-normal.woff2 differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/luckiestguy/v8/_gP_1RrxsjcxVyin9l9n_j2hTd52.woff2 b/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/luckiestguy/v8/_gP_1RrxsjcxVyin9l9n_j2hTd52.woff2
deleted file mode 100644
index ca65028..0000000
Binary files a/extensions/fablabchemnitz/boxes.py/boxes/static/fonts/luckiestguy/v8/_gP_1RrxsjcxVyin9l9n_j2hTd52.woff2 and /dev/null differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/needs-image.png b/extensions/fablabchemnitz/boxes.py/boxes/static/needs-image.png
new file mode 100644
index 0000000..f1fdd27
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/needs-image.png differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ABox-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ABox-thumb.jpg
new file mode 100644
index 0000000..0005508
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ABox-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ABox.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ABox.jpg
new file mode 100644
index 0000000..e530599
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ABox.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/AirPurifier-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/AirPurifier-thumb.jpg
new file mode 100644
index 0000000..db7ee71
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/AirPurifier-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/AirPurifier.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/AirPurifier.jpg
new file mode 100644
index 0000000..43558bb
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/AirPurifier.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Arcade-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Arcade-thumb.jpg
new file mode 100644
index 0000000..f7deb9b
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Arcade-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Arcade.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Arcade.jpg
new file mode 100644
index 0000000..95373f7
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Arcade.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BirdHouse-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BirdHouse-thumb.jpg
new file mode 100644
index 0000000..3552aba
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BirdHouse-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BirdHouse.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BirdHouse.jpg
new file mode 100644
index 0000000..280ad95
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BirdHouse.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BreadBox-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BreadBox-thumb.jpg
new file mode 100644
index 0000000..09cd8f7
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BreadBox-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BreadBox.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BreadBox.jpg
new file mode 100644
index 0000000..3411507
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/BreadBox.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-closed-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-closed-thumb.jpg
new file mode 100644
index 0000000..ff28c8f
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-closed-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-closed.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-closed.jpg
new file mode 100644
index 0000000..5239e1b
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-closed.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-open-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-open-thumb.jpg
new file mode 100644
index 0000000..83767fb
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-open-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-open.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-open.jpg
new file mode 100644
index 0000000..e3b3357
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-open.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-pins-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-pins-thumb.jpg
new file mode 100644
index 0000000..7d35814
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-pins-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-pins.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-pins.jpg
new file mode 100644
index 0000000..b336e55
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-pins.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-thumb.jpg
new file mode 100644
index 0000000..4330eb7
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe.jpg
new file mode 100644
index 0000000..1ec97d1
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/CoinBankSafe.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConcaveKnob-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConcaveKnob-thumb.jpg
new file mode 100644
index 0000000..f72ca0c
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConcaveKnob-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConcaveKnob.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConcaveKnob.jpg
new file mode 100644
index 0000000..e0c0e34
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConcaveKnob.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickBack-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickBack-thumb.jpg
new file mode 100644
index 0000000..d925638
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickBack-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickBack.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickBack.jpg
new file mode 100644
index 0000000..2694235
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickBack.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickFront-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickFront-thumb.jpg
new file mode 100644
index 0000000..732354d
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickFront-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickFront.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickFront.jpg
new file mode 100644
index 0000000..a97823b
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickFront.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickInside-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickInside-thumb.jpg
new file mode 100644
index 0000000..52082f7
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickInside-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickInside.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickInside.jpg
new file mode 100644
index 0000000..bf3544d
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/ConsoleArcadeStickInside.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Desksign-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Desksign-thumb.jpg
new file mode 100644
index 0000000..fa569eb
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Desksign-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Desksign.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Desksign.jpg
new file mode 100644
index 0000000..b2f1ab8
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Desksign.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Dispenser-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Dispenser-thumb.jpg
new file mode 100644
index 0000000..eadae58
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Dispenser-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Dispenser.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Dispenser.jpg
new file mode 100644
index 0000000..7a9c395
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Dispenser.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBox-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBox-thumb.jpg
new file mode 100644
index 0000000..646e2c2
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBox-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBox.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBox.jpg
new file mode 100644
index 0000000..84274f4
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBox.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBoxes-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBoxes-thumb.jpg
new file mode 100644
index 0000000..372084d
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBoxes-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBoxes.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBoxes.jpg
new file mode 100644
index 0000000..480ac5c
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/DrillBoxes.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FanHole-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FanHole-thumb.jpg
new file mode 100644
index 0000000..b25bb2a
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FanHole-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FanHole.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FanHole.jpg
new file mode 100644
index 0000000..e039bab
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FanHole.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-2-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-2-thumb.jpg
new file mode 100644
index 0000000..61b5efa
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-2-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-2.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-2.jpg
new file mode 100644
index 0000000..8f81611
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-2.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-thumb.jpg
new file mode 100644
index 0000000..2c3333d
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool.jpg
new file mode 100644
index 0000000..73933de
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FilamentSpool.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FillTest-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FillTest-thumb.jpg
new file mode 100644
index 0000000..3bb0401
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FillTest-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FillTest.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FillTest.jpg
new file mode 100644
index 0000000..b9ab612
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FillTest.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-2-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-2-thumb.jpg
new file mode 100644
index 0000000..d8e2a2f
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-2-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-2.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-2.jpg
new file mode 100644
index 0000000..16d9724
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-2.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-thumb.jpg
new file mode 100644
index 0000000..a29939b
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook.jpg
new file mode 100644
index 0000000..4bdf260
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBook.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBox5-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBox5-thumb.jpg
new file mode 100644
index 0000000..50af933
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBox5-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBox5.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBox5.jpg
new file mode 100644
index 0000000..4187829
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexBox5.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexTest2-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexTest2-thumb.jpg
new file mode 100644
index 0000000..475e8cd
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexTest2-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexTest2.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexTest2.jpg
new file mode 100644
index 0000000..b9039ce
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FlexTest2.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FrontPanel-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FrontPanel-thumb.jpg
new file mode 100644
index 0000000..54b362b
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FrontPanel-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FrontPanel.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FrontPanel.jpg
new file mode 100644
index 0000000..322b33c
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/FrontPanel.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GearBox-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GearBox-thumb.jpg
new file mode 100644
index 0000000..095b2cf
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GearBox-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GearBox.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GearBox.jpg
new file mode 100644
index 0000000..e96e469
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GearBox.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityBase-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityBase-thumb.jpg
new file mode 100644
index 0000000..0b3eea3
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityBase-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityBase.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityBase.jpg
new file mode 100644
index 0000000..032624e
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityBase.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityTrayLayout-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityTrayLayout-thumb.jpg
new file mode 100644
index 0000000..d1cc411
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityTrayLayout-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityTrayLayout.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityTrayLayout.jpg
new file mode 100644
index 0000000..132be5a
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/GridfinityTrayLayout.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/HolePattern-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/HolePattern-thumb.jpg
new file mode 100644
index 0000000..3227ac3
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/HolePattern-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/HolePattern.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/HolePattern.jpg
new file mode 100644
index 0000000..17076fc
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/HolePattern.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Hook-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Hook-thumb.jpg
new file mode 100644
index 0000000..397aa51
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Hook-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Hook.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Hook.jpg
new file mode 100644
index 0000000..b224a26
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Hook.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-2-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-2-thumb.jpg
new file mode 100644
index 0000000..40ddf17
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-2-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-2.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-2.jpg
new file mode 100644
index 0000000..2544441
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-2.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-thumb.jpg
new file mode 100644
index 0000000..9935708
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder.jpg
new file mode 100644
index 0000000..007660e
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/KeyHolder.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/LaptopStand-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/LaptopStand-thumb.jpg
new file mode 100644
index 0000000..df82dc1
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/LaptopStand-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/LaptopStand.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/LaptopStand.jpg
new file mode 100644
index 0000000..38544b8
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/LaptopStand.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/MagazinFile-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/MagazineFile-thumb.jpg
similarity index 100%
rename from extensions/fablabchemnitz/boxes.py/boxes/static/samples/MagazinFile-thumb.jpg
rename to extensions/fablabchemnitz/boxes.py/boxes/static/samples/MagazineFile-thumb.jpg
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/MagazinFile.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/MagazineFile.jpg
similarity index 100%
rename from extensions/fablabchemnitz/boxes.py/boxes/static/samples/MagazinFile.jpg
rename to extensions/fablabchemnitz/boxes.py/boxes/static/samples/MagazineFile.jpg
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/NemaPattern-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/NemaPattern-thumb.jpg
new file mode 100644
index 0000000..7203d0a
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/NemaPattern-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/NemaPattern.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/NemaPattern.jpg
new file mode 100644
index 0000000..e9faa5d
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/NemaPattern.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoBody-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoBody-thumb.jpg
index 481d13c..f04d1f1 100644
Binary files a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoBody-thumb.jpg and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoBody-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoBody.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoBody.jpg
index 17c783d..78f3adb 100644
Binary files a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoBody.jpg and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoBody.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoLegs-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoLegs-thumb.jpg
new file mode 100644
index 0000000..227cdcc
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoLegs-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoLegs.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoLegs.jpg
new file mode 100644
index 0000000..615a24f
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoLegs.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoSoles-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoSoles-thumb.jpg
new file mode 100644
index 0000000..ac6b621
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoSoles-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoSoles.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoSoles.jpg
new file mode 100644
index 0000000..25d56b0
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/OttoSoles.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PirateChest-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PirateChest-thumb.jpg
new file mode 100644
index 0000000..40248cb
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PirateChest-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PirateChest.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PirateChest.jpg
new file mode 100644
index 0000000..fb0879b
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PirateChest.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PizzaShovel-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PizzaShovel-thumb.jpg
new file mode 100644
index 0000000..210f0a7
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PizzaShovel-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PizzaShovel.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PizzaShovel.jpg
new file mode 100644
index 0000000..053de42
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/PizzaShovel.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Rack19Box-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Rack19Box-thumb.jpg
new file mode 100644
index 0000000..91e5d5f
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Rack19Box-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Rack19Box.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Rack19Box.jpg
new file mode 100644
index 0000000..0f4c04e
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Rack19Box.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RackBox-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RackBox-thumb.jpg
new file mode 100644
index 0000000..24d02f3
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RackBox-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RackBox.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RackBox.jpg
new file mode 100644
index 0000000..eed5505
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RackBox.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RectangularWall-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RectangularWall-thumb.jpg
new file mode 100644
index 0000000..4d586cd
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RectangularWall-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RectangularWall.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RectangularWall.jpg
new file mode 100644
index 0000000..8d023cb
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RectangularWall.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RollHolder-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RollHolder-thumb.jpg
new file mode 100644
index 0000000..ea134d6
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RollHolder-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RollHolder.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RollHolder.jpg
new file mode 100644
index 0000000..e51e6bc
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/RollHolder.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SevenSegmentPattern-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SevenSegmentPattern-thumb.jpg
new file mode 100644
index 0000000..c51ff35
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SevenSegmentPattern-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SevenSegmentPattern.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SevenSegmentPattern.jpg
new file mode 100644
index 0000000..2115ace
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SevenSegmentPattern.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-backlit-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-backlit-thumb.jpg
new file mode 100644
index 0000000..3ac0558
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-backlit-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-backlit.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-backlit.jpg
new file mode 100644
index 0000000..d8805d8
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-backlit.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-diagram-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-diagram-thumb.jpg
new file mode 100644
index 0000000..a7f5d55
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-diagram-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-diagram.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-diagram.jpg
new file mode 100644
index 0000000..f7d22d0
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-diagram.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-thumb.jpg
new file mode 100644
index 0000000..ffd2794
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox.jpg
new file mode 100644
index 0000000..1a7e705
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shadowbox.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shoe-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shoe-thumb.jpg
new file mode 100644
index 0000000..06d2aca
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shoe-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shoe.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shoe.jpg
new file mode 100644
index 0000000..9bb6cbf
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Shoe.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-2-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-2-thumb.jpg
new file mode 100644
index 0000000..ef4d2a9
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-2-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-2.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-2.jpg
new file mode 100644
index 0000000..f1d6efa
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-2.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-thumb.jpg
new file mode 100644
index 0000000..f9998ec
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing.jpg
new file mode 100644
index 0000000..c97e2fb
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SideDoorHousing.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SkadisBoard-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SkadisBoard-thumb.jpg
new file mode 100644
index 0000000..a6ebc1d
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SkadisBoard-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SkadisBoard.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SkadisBoard.jpg
new file mode 100644
index 0000000..9d16302
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SkadisBoard.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-2-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-2-thumb.jpg
new file mode 100644
index 0000000..0e56869
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-2-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-2.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-2.jpg
new file mode 100644
index 0000000..176c042
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-2.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-thumb.jpg
new file mode 100644
index 0000000..c81d501
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray.jpg
new file mode 100644
index 0000000..e4c6d03
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SlantedTray.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray-thumb.jpg
new file mode 100644
index 0000000..fd7fbd7
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray.jpg
new file mode 100644
index 0000000..c5d3263
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray2-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray2-thumb.jpg
new file mode 100644
index 0000000..15ded3a
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray2-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray2.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray2.jpg
new file mode 100644
index 0000000..f7bd952
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/SmallPartsTray2.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Spool-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Spool-thumb.jpg
new file mode 100644
index 0000000..3af542e
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Spool-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Spool.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Spool.jpg
new file mode 100644
index 0000000..6dd249e
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Spool.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Tetris-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Tetris-thumb.jpg
new file mode 100644
index 0000000..2adfe7a
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Tetris-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Tetris.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Tetris.jpg
new file mode 100644
index 0000000..60f03b7
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/Tetris.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallChiselHolder-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallChiselHolder-thumb.jpg
new file mode 100644
index 0000000..5806953
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallChiselHolder-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallChiselHolder.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallChiselHolder.jpg
new file mode 100644
index 0000000..ffdda10
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallChiselHolder.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallConsole-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallConsole-thumb.jpg
new file mode 100644
index 0000000..d7d819b
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallConsole-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallConsole.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallConsole.jpg
new file mode 100644
index 0000000..a7f5e46
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallConsole.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPinRow-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPinRow-thumb.jpg
new file mode 100644
index 0000000..e3c239a
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPinRow-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPinRow.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPinRow.jpg
new file mode 100644
index 0000000..d4dc114
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPinRow.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPlaneHolder-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPlaneHolder-thumb.jpg
new file mode 100644
index 0000000..ff7e455
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPlaneHolder-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPlaneHolder.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPlaneHolder.jpg
new file mode 100644
index 0000000..a43d61f
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallPlaneHolder.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRack-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRack-thumb.jpg
new file mode 100644
index 0000000..3be0760
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRack-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRack.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRack.jpg
new file mode 100644
index 0000000..2d97e83
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRack.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRollHolder-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRollHolder-thumb.jpg
new file mode 100644
index 0000000..b80397d
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRollHolder-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRollHolder.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRollHolder.jpg
new file mode 100644
index 0000000..72ae60c
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallRollHolder.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallStairs-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallStairs-thumb.jpg
new file mode 100644
index 0000000..62a1144
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallStairs-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallStairs.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallStairs.jpg
new file mode 100644
index 0000000..58b5b27
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallStairs.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallWrenchHolder-thumb.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallWrenchHolder-thumb.jpg
new file mode 100644
index 0000000..3768f86
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallWrenchHolder-thumb.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallWrenchHolder.jpg b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallWrenchHolder.jpg
new file mode 100644
index 0000000..c93fe5b
Binary files /dev/null and b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/WallWrenchHolder.jpg differ
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/samples.sha256 b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/samples.sha256
index 2a5e3c4..4e5c4f4 100644
--- a/extensions/fablabchemnitz/boxes.py/boxes/static/samples/samples.sha256
+++ b/extensions/fablabchemnitz/boxes.py/boxes/static/samples/samples.sha256
@@ -11,7 +11,7 @@ e21f917775a9a1d08964c46c67eac7ac994122d674d1be437ee42aecfb608efa ../static/samp
f60561e58fbe66509c0f839dc02043192862b2f886a23178bdef9102050ee6fa ../static/samples/Folder.jpg
b93f528b3c1252c996858c1b0ec6482e177ed767c8d47646b17629fb8b115ce7 ../static/samples/UBox.jpg
c07ecba64de889a551e1634bd9d30494d225c1167ac877672282326e68543d8d ../static/samples/UniversalBox.jpg
-6a845731b5fa4cc69a5a77660dbe0e8fec2210f3a5572759506f8e1ad8ba40ec ../static/samples/OttoBody.jpg
+293085a6678d31431ecd8331fd3fbe1897611fd94065c20ac6dfd635d4b70522 ../static/samples/OttoBody.jpg
aec34803225353bf9503e7dec3e0459de4191e337d5272db0042c6f636b30c9f ../static/samples/RobotArm.jpg
18826f349517bdea85c8ce2bd8a8df83ee41ebee84eef6b331daf8f31736e25a ../static/samples/UnevenHeightBox.jpg
55bdf7b75fa5f710c0c09763bd5ea5792eae57033ca5bc59d70d74576b40b6ba ../static/samples/CardBox.jpg
@@ -97,9 +97,71 @@ a95305025a8136290e95f8232463bb1c6023a1d98d502e7a249d52c60aafdd94 ../static/samp
34058c3a37bc70dc72e467d2da1ece7cde2aacedf7b751243a7c264c9998afb2 ../static/samples/DiceBox.jpg
e90b4a90c1dbd2a4a03e4cf50ba82bc7119b721bd5c90c5fdbd0a356c9eabfd3 ../static/samples/CanStorageAA.jpg
0580043276c800c68dfba840d47c27f974ef2d0629751ecd250df2400f03cca8 ../static/samples/CanStorage.jpg
-bb250512410c007a74f91caee4e25eac817021f5a535987a7f5ff46148a074ca ../static/samples/MagazinFile.jpg
+bb250512410c007a74f91caee4e25eac817021f5a535987a7f5ff46148a074ca ../static/samples/MagazineFile.jpg
59c29899a7f6cfa1727830b35ba621747bf1fe16b8559884054bf50235559a11 ../static/samples/CoinDisplay.jpg
c21b47963a9de686eec4bcdb04dc84a64fef1e943d9c276f6ecb7d619af22791 ../static/samples/HalfBox_Shelf_usage.jpg
3bdbb6dab2beea4dcdcf84941bf1f763bc9eb60ca9369965c4b003d5bb57f83b ../static/samples/HalfBox_AngleJig_usage.jpg
9a0c0bf1d3b74a1e09f278ad9f89d8b7e59261a870bb60ed547d45117594cf93 ../static/samples/HalfBox.jpg
e1e5001ad1c59e0815a684f2eb2d25bb88113423ec6b582fb81f835c25947127 ../static/samples/HalfBox_Bookend_usage.jpg
+2300383efee9aebb910fb8967edcee9689e1143031c5bca4d7d9a2c4109bd7f9 ../static/samples/GridfinityBase.jpg
+6a8a5789897d4836ca1d0eab54b66e77efde181cdf375374253be8a3eb85a183 ../static/samples/BreadBox.jpg
+2b53f202726de27f65cb36bd3b8e7fc0f54af4e8021257a2084771613c604401 ../static/samples/SlantedTray-2.jpg
+5a7ff061d7e3d6b4ec587926f81b594bd12c0a2516ac939260564164d7d01db2 ../static/samples/SlantedTray.jpg
+b4b0aeecfd34eedb1a1e0b9763e219b77f4d0cea0ae39c5197e22dbae5d4f0d4 ../static/samples/SmallPartsTray.jpg
+f342316e00a07329aec8a9377274db4709870511126a3cada10ae9057f3f5367 ../static/samples/BirdHouse.jpg
+7046e8171d15e3a01685ab0763fa8b4cbdecf98956c02203343579cab39b9c6f ../static/samples/SmallPartsTray2.jpg
+bb294909eb5e7a1a49cc7d5ba72b08ca0baf42dd2302494aa1932432817ce973 ../static/samples/RollHolder.jpg
+a7ee83b42685295fd02db666841984c55af2f9632540c651f5dea42088a3c170 ../static/samples/FilamentSpool.jpg
+0524ca976f76c181135044b185eb4e6cf2ce92ab3316f48a6bc61b9366daefd1 ../static/samples/FilamentSpool-2.jpg
+ab47e02fb9736d20b457964aa640f50852ac97bb2857cea753fa4c3067a60d41 ../static/samples/Spool.jpg
+cfc0782f3a952dd0c6ceb0fb7998050f3bdea135d791fa32b731808371514e63 ../static/samples/GearBox.jpg
+75733dfdfd601ace1521bddfea28546ca34d8281acbeb6ec44f15b2b942cb944 ../static/samples/Arcade.jpg
+a21471512fd73c15e1d8a11aa3bd4ef807791895855c2f1d30a00bd207d79919 ../static/samples/FrontPanel.jpg
+5640a59072afac58b4bb8410967cb8434a455ac3570118d2163887c17099e064 ../static/samples/WallChiselHolder.jpg
+cfec3b4f915befc29efc3913c131204948e63a444fd41370989173b0243617d7 ../static/samples/WallPlaneHolder.jpg
+6a5222b9d886454f6c4fda8ead777f2136f8c1d0231e145a30ea853430ee7baa ../static/samples/WallRollHolder.jpg
+cedf3c9ce40a379c4ca52089d0cda51cdf4c3899df1368c6374ed45afcb8cef8 ../static/samples/WallWrenchHolder.jpg
+5b123ea245e7670cd0a55cea8348aa1f2628080f5ec005902cdd86bab231aad1 ../static/samples/WallConsole.jpg
+d7b9c4a9ea70c2cc7ede5e992862fa4c001cff0f592a689ed4d5fab5ac339249 ../static/samples/GridfinityTrayLayout.jpg
+885a89ccdf04ddcbd31e8ccd8c7157129443b9b6a3e2b720085c0f11c406a748 ../static/samples/ABox.jpg
+f340b90d92d445a626d5e162bc1081fdeda9ba11d563c7f7c4632996379f34da ../static/samples/ConsoleArcadeStickBack.jpg
+005751de891a4faa50cf65bcad6781cc5499329a5596a7fa93cee901c7e89537 ../static/samples/ConsoleArcadeStickFront.jpg
+4f0b46c88c1c425dcec6b9a0bff754f6b5580f82aa7004233dec03f8f4c5ce41 ../static/samples/ConsoleArcadeStickInside.jpg
+2432b6095e513cecaf5e96552dd4136615a0470e36d8804668cbb5b73684249e ../static/samples/DrillBox.jpg
+4e055c330eb95303fcce029f6efb1089e9a5b61cf0eef25c95267a8c90d1c2c4 ../static/samples/RackBox.jpg
+71f7fb03035c12037beb4bc6c9acdd5fb75ee044d20b4e4be910aae8085ca592 ../static/samples/ConcaveKnob.jpg
+4508f68ec6c233b116b6268322996ed50146df34318ffffe4062041fd289fbf6 ../static/samples/DrillBoxes.jpg
+70644df6aa7191ae32a66039d3231fc9b84f4f49210571632d2a2f010e728a9b ../static/samples/LaptopStand.jpg
+72ea1d0144f27354febffcef5d55ee0897ea6082d05cef78f3dd786b9e943243 ../static/samples/Dispenser.jpg
+622576918df92b533f6a689525dbbce3822ad59f58378a2fd1a117a650d30c0e ../static/samples/OttoLegs.jpg
+eedccf62c193224e2b86e52be8cd02faddf97d565330e2d5770390141da35069 ../static/samples/OttoSoles.jpg
+e9ee43e336401d3a0cb8e141c3a0b87a84e90f99eed30bdd420dcaead92940e1 ../static/samples/NemaPattern.jpg
+3070eb2ed89461497d4dcc67021a0619338ab6d4d4d89d3cd1f83160da3c7920 ../static/samples/FanHole.jpg
+c8adb0661956430ccec7fc00aa4b8e3c42d02083e17a9307541bc0160251cb96 ../static/samples/HolePattern.jpg
+7c399c1cd235c3c044f676a31aa5215109e815055f2f69aef5d0cb1a24dfae41 ../static/samples/Desksign.jpg
+fda14ba0920ef7ea0579117a30b5bb4a05ab3be4da3d87a4fc03fc40b085992b ../static/samples/PirateChest.jpg
+125033a02263e74d5688287936f54cd83e917276b7c35f3fd37e6cb86efc0dcc ../static/samples/Shoe.jpg
+7bf29dc9e2f0b5a0bbedc8b7b6814fe4cec58e9dcebfcd1167757a2bbcc91c17 ../static/samples/Hook.jpg
+16013717335b8561b5d78bd586dceee5bac6a35e9e6f0bb9c3b36dc6ea5218bd ../static/samples/PizzaShovel.jpg
+b860c4e6a0016c1fb4742d4a70a8201af88a18e36ae0c4d601549a640471fe11 ../static/samples/KeyHolder.jpg
+d63379683d34c42994610bf1d0c3fb5daa2c790431a7c2dd94c76302163979b6 ../static/samples/KeyHolder-2.jpg
+60f7f3ac2b046107cb573607706f688380c4f9322fe612e1972627f3b01f507a ../static/samples/AirPurifier.jpg
+cdd8658c4bd66de5e00c5a961583986a47c29532e006cb4fedb69faab60c9bac ../static/samples/SevenSegmentPattern.jpg
+1335103ec002a662753fbf1850c9bdb7fa8bac7925dab1d5878b90aa54e9e963 ../static/samples/WallStairs.jpg
+80e1e5eb264277ab69fcdf689e8e91cf6735e1f9d0e595d845fbe7685f9b8725 ../static/samples/Rack19Box.jpg
+70f5fd1ef2f65c54867ef74c20ae30465d52226b69a1c82b9213676ff634aa0d ../static/samples/WallPinRow.jpg
+56456fde428172ead54947709758b5d79995fa7c5e9bc89b5da84742c7960749 ../static/samples/SkadisBoard.jpg
+4f8047786f1eeb256de2edf070efa758648a83dad2ad1c5d7c45388804117d3a *../static/samples/FlexBox5.jpg
+22525c5c4fc9e25a68d79a4f6db6a169b2a9038ee9c2ba4a1dd69fcbe2944fb1 *../static/samples/SideDoorHousing-2.jpg
+37eefc7aca018887debb9b9671ba8485289a4d5375fabef50d59efe656edbcf8 *../static/samples/SideDoorHousing.jpg
+27c3d97e7d141dd72d065160d7fe48d7be700fa8175a034e40599b60d8c64d8c *../static/samples/Tetris.jpg
+0195265c174c157690112bc01563439e536952c7015a41fbc562020fcdb270c3 *../static/samples/FillTest.jpg
+27699d62eab473d903f2bcf0f334c2c36ff3601772c4c0ddeae89606a7bb10b5 *../static/samples/FlexTest2.jpg
+853ace5a13ac571696a1965c72ae456c769ed4bc01ea29bb60bbe40518dcecf9 *../static/samples/RectangularWall.jpg
+ed533e9827b58591fccbed9e6d31ff8c10bb7f9981501771f6577616a9fbe71b *../static/samples/WallRack.jpg
+f625a31c8f1f08341f8e4c0ba5d34524f92e258ca2ae3027774c399a200ddfc9 ../static/samples/CoinBankSafe.jpg
+49d330c7159dd77fc2e7a4d82ca46f2834c7e35a8c59b44739c0defbd045bedf ../static/samples/CoinBankSafe-open.jpg
+17e9c4f4da3a74b94168913b78695918096269dfd2c59feb70bd4a833e155d04 ../static/samples/CoinBankSafe-pins.jpg
+94e37a41d8b873f39bd3e8c74465b012c8f861031c93f64fd6eda89af02015c0 ../static/samples/FlexBook-2.jpg
+4d8b4d5467a88431ba24e893157a6e09997d74654cd7e27878d2a54b1ee751c6 ../static/samples/CoinBankSafe-closed.jpg
+bace3582c13ee543f09fd45752d4403e237d01541aaa4ea266e61e64fd12156a ../static/samples/FlexBook.jpg
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/self.css b/extensions/fablabchemnitz/boxes.py/boxes/static/self.css
index 0de7ba6..3327ac1 100644
--- a/extensions/fablabchemnitz/boxes.py/boxes/static/self.css
+++ b/extensions/fablabchemnitz/boxes.py/boxes/static/self.css
@@ -49,6 +49,7 @@ h3 {
padding: 5px;
padding-left: 15px;
margin: 0px;
+ width: 75%
}
h3::before {
@@ -78,6 +79,7 @@ table tr p {
/* Container */
.container {
+ background-color: #FFF8EA;
margin-top: 20px;
margin-left: auto;
margin-right: auto;
@@ -123,7 +125,12 @@ video {
}
.footer {
- box-shadow: none;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 10px;
+ padding-bottom: 15px;
+ width: 996px;
+ border-radius: 30px;
text-align: center;
margin-top: 0px;
}
@@ -138,6 +145,11 @@ video {
font-size: 0.9em;
}
+.search {
+ float : right;
+ padding-top: 10px;
+}
+
.footer ul li a {
color: #555;
margin-right: 10px;
@@ -186,3 +198,40 @@ img[id|=sample] {
textarea {
font-family: monospace;
}
+
+.gallery_missing {
+ display : inline-block;
+ text-align : center;
+ vertical-align: middle;
+ width : 200px;
+ margin : 5px;
+ font-weight: bold;
+}
+
+.gallery img {
+ max-height : 200px;
+ max-width : 200px;
+ margin : 5px;
+}
+
+.modenav {
+ overflow: hidden;
+}
+
+.modebutton {
+ float: left;
+ border: none;
+ outline: none;
+ padding: 10px 16px;
+ margin-right: 10px;
+ text-align : center;
+ border-radius: 10px;
+ font-size: 17px;
+ width: 25%;
+ background-color: #EFE8DA;
+}
+
+.modeactive {
+ background-color: #DFD8BA;
+
+}
diff --git a/extensions/fablabchemnitz/boxes.py/boxes/static/self.js b/extensions/fablabchemnitz/boxes.py/boxes/static/self.js
new file mode 100644
index 0000000..df063e4
--- /dev/null
+++ b/extensions/fablabchemnitz/boxes.py/boxes/static/self.js
@@ -0,0 +1,303 @@
+function showThumbnail(img_link) {
+ const img = document.getElementById("sample-preview");
+ img.src = img_link;
+ img.style.height = "auto";
+ img.style.display = "block";
+}
+
+function showThumbnailEvt(evt) {
+ const url = evt.target.getAttribute("data-thumbnail");
+ showThumbnail(url);
+}
+
+function hideThumbnail() {
+ const img = document.getElementById("sample-preview");
+ img.style.display = "none";
+}
+
+function expandId(id) {
+ const e = document.getElementById(id);
+ const h = document.getElementById("h-" + id);
+ e.style.display = "block";
+ h.classList.add("open");
+ h.setAttribute("aria-expanded", "true");
+}
+function collapseId(id) {
+ const e = document.getElementById(id);
+ const h = document.getElementById("h-" + id);
+ e.style.display = "none";
+ h.classList.remove("open");
+ h.setAttribute("aria-expanded", "false");
+}
+
+function toggleId(id) {
+ const e = document.getElementById(id);
+ const h = document.getElementById("h-" + id);
+ if (e.style.display == null || e.style.display === "none") {
+ expandId(id);
+ } else {
+ collapseId(id);
+ }
+}
+
+function toggleEl(el) {
+ const id = el.getAttribute("data-id");
+ toggleId(id);
+}
+
+function toggleEvt(evt) {
+ const id = evt.target.getAttribute("data-id");
+ // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role#examples
+ if (evt instanceof MouseEvent) {
+ toggleId(id);
+ }
+ if (evt instanceof KeyboardEvent && (evt.key === "Enter" || evt.key === " ")) {
+ evt.preventDefault();
+ toggleId(id);
+ }
+}
+
+function initToggle(el, hide = false) {
+ // Add event handler.
+ el.addEventListener("click", toggleEvt);
+ el.addEventListener("keydown", toggleEvt);
+ // Hide.
+ if (hide) {
+ toggleEl(el);
+ }
+}
+
+function initThumbnail(el) {
+ // Add event handler.
+ el.addEventListener("mouseenter", showThumbnailEvt);
+ el.addEventListener("mouseleave", hideThumbnail);
+}
+
+function initPage(num_hide = null) {
+ const h = document.getElementsByClassName("toggle");
+ let i = 0;
+ for (let el of h) {
+ if (num_hide === null || i < num_hide) {
+ initToggle(el, true);
+ } else {
+ initToggle(el, false);
+ }
+ i++;
+ }
+ const t = document.getElementsByClassName("thumbnail");
+ for (let el of t) initThumbnail(el);
+}
+
+function GridfinityTrayLayout_GenerateLayout(x, y, nx, ny, countx, county) {
+ // x = width in mm
+ // y = height in mm
+ // nx # of gridfinity grids in X
+ // ny # of gridfinity grids in Y
+ // countx split x into this many
+ // county split y into this many
+ layout = '';
+ if (countx == 0)
+ countx = nx;
+ if (county == 0)
+ county = ny
+ stepx = x / countx;
+ stepy = y / county;
+ for (i = 0; i < countx; i++) {
+ line = ' |'.repeat(i) + ` ,> ${stepx}mm\n`;
+ layout += line;
+ }
+ for (i = 0; i < county; i++) {
+ layout += "+-".repeat(countx) + "+\n";
+ layout += "| ".repeat(countx) + `| ${stepy}mm\n`;
+ }
+ layout += "+-".repeat(countx) + "+\n";
+ return layout
+}
+
+function GridfinityTrayUpdateLayout(event) {
+ console.log("update");
+ if (window.layoutUpdated == true) {
+ // Don't do the update if the layout has been manually touched.
+ if (confirm("You have manually updated the Layout. Do you wish to regenerate it?")) {
+ window.layoutUpdated = false;
+ } else {
+ return;
+ }
+ }
+ console.log("updating");
+ nx = document.getElementById('nx').value;
+ ny = document.getElementById('ny').value;
+ countx = document.getElementById('countx').value;
+ county = document.getElementById('county').value;
+ margin = document.getElementById('margin').value;
+ x = nx*42 - margin
+ y = ny*42 - margin
+ layout_id = document.getElementById('layout');
+ layout_id.value = GridfinityTrayLayout_GenerateLayout(x, y, nx, ny, countx, county);
+}
+
+function setUpdated() {
+ console.log("this was updated");
+ window.layoutUpdated=true;
+}
+function GridfinityTrayLayoutInit() {
+ console.log("update init");
+ ids = ['nx', 'ny', 'countx', 'county', 'margin'];
+ window.layoutUpdated=false;
+ for (id_string of ids) {
+ id = document.getElementById(id_string);
+ id.addEventListener('input', GridfinityTrayUpdateLayout);
+ }
+ layout_id = document.getElementById('layout');
+ layout_id.addEventListener('change', setUpdated);
+ layout_id.addEventListener('input', setUpdated);
+
+ GridfinityTrayUpdateLayout();
+ layout_id = document.getElementById('layout');
+ layout_id.rows = 20;
+ layout_id.cols = 24;
+}
+
+function ParseSections(s) {
+ var sections = [];
+ for (var section of s.split(":")) {
+ var operands = section.split("/");
+ if (operands.length > 2) return sections;
+ if (operands.length == 2) {
+ for (var i=0; i
2) return sections;
+ if (operands.length == 2) {
+ for (var i=0; i ${sx[i].toFixed(2)}mm\n`;
+ layout += line;
+ }
+ for (i = 0; i < ny; i++) {
+ layout += "+-".repeat(nx) + "+\n";
+ layout += "| ".repeat(nx) + `| ${sy[i].toFixed(2)}mm\n`;
+ }
+ layout += "+-".repeat(nx) + "+\n";
+ return layout
+}
+
+function TrayUpdateLayout(event) {
+ if (window.layoutUpdated == true) {
+ // Don't do the update if the layout has been manually touched.
+ if (confirm("You have manually updated the Layout. Do you wish to regenerate it?")) {
+ window.layoutUpdated = false;
+ } else {
+ return;
+ }
+ }
+ sx = document.getElementById('sx').value;
+ sy = document.getElementById('sy').value;
+ layout_id = document.getElementById('layout');
+ layout_id.value = TrayLayout_GenerateLayout(sx, sy);
+}
+
+
+function TrayLayoutInit() {
+ ids = ['sx', 'sy'];
+ window.layoutUpdated=false;
+ for (id_string of ids) {
+ id = document.getElementById(id_string);
+ id.addEventListener('input', TrayUpdateLayout);
+ }
+ TrayUpdateLayout();
+ layout_id = document.getElementById('layout');
+ layout_id.addEventListener('change', setUpdated);
+ layout_id.addEventListener('input', setUpdated);
+ layout_id.rows = 20;
+ layout_id.cols = 24;
+}
+
+function addCallbacks() {
+ page_callbacks = {
+ "TrayLayout": TrayLayoutInit,
+ "GridfinityTrayLayout": GridfinityTrayLayoutInit,
+ };
+ loc = new URL(window.location.href);
+ pathname = loc.pathname;
+ page = pathname.substr(pathname.lastIndexOf('/')+1);
+ if (page in page_callbacks) {
+ callback = page_callbacks[page];
+ callback();
+ }
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+ addCallbacks();
+}, false);
+
+function collapseAll() {
+ const h = document.getElementsByClassName("toggle");
+ for (let el of h) {
+ id = el.getAttribute("data-id")
+ collapseId(id);
+ }
+}
+
+function expandAll() {
+ const h = document.getElementsByClassName("toggle");
+ for (let el of h) {
+ id = el.getAttribute("data-id")
+ expandId(id);
+ }
+}
+
+function showAll(str) {
+ let matching_ids = document.querySelectorAll('[id^="search_id_"]')
+ for (let id of matching_ids) {
+ id.style.display = "inline-block";
+ }
+}
+
+function showOnly(str) {
+ str = str.toLowerCase();
+ let matching_ids = document.querySelectorAll('[id^="search_id_"]')
+ for (let id of matching_ids) {
+ name = id.id.replace("search_id_", "").toLowerCase();
+ if (name.includes(str) || id.textContent.toLowerCase().includes(str)) {
+ id.style.display = "inline-block";
+ } else {
+ id.style.display = "none";
+ }
+ }
+}
+
+function filterSearchItems() {
+ const search = document.getElementById("search")
+ if (search.value.length == 0) {
+ collapseAll();
+ showAll()
+ } else {
+ expandAll();
+ showOnly(search.value)
+ }
+}