Initial Commit

master
Harald Wolff 2024-04-14 18:54:36 +02:00
commit 352a152748
97 changed files with 45128 additions and 0 deletions

5
.idea/.gitignore vendored 100644
View File

@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

12
.idea/ai.chat.iml 100644
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ai.chat.iml" filepath="$PROJECT_DIR$/.idea/ai.chat.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions">
<TaskOptions isEnabled="true">
<option name="arguments" value="$FileName$:$FileNameWithoutExtension$.css" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="ERROR" />
<option name="fileExtension" value="sass" />
<option name="immediateSync" value="true" />
<option name="name" value="Sass" />
<option name="output" value="$FileNameWithoutExtension$.css:$FileNameWithoutExtension$.css.map" />
<option name="outputFilters">
<array />
</option>
<option name="outputFromStdout" value="false" />
<option name="program" value="sass" />
<option name="runOnExternalChanges" value="true" />
<option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="true" />
<option name="workingDir" value="$FileDir$" />
<envs />
</TaskOptions>
<TaskOptions isEnabled="true">
<option name="arguments" value="$FileName$:$FileNameWithoutExtension$.css" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="ERROR" />
<option name="fileExtension" value="scss" />
<option name="immediateSync" value="true" />
<option name="name" value="SCSS" />
<option name="output" value="$FileNameWithoutExtension$.css:$FileNameWithoutExtension$.css.map" />
<option name="outputFilters">
<array />
</option>
<option name="outputFromStdout" value="false" />
<option name="program" value="sass" />
<option name="runOnExternalChanges" value="true" />
<option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="true" />
<option name="workingDir" value="$FileDir$" />
<envs />
</TaskOptions>
</component>
</project>

56
assistant.js 100644
View File

@ -0,0 +1,56 @@
export class ChatMessageEvent extends Event {
constructor(message) {
super("chatMessage");
this.message = message;
}
}
export class AssistantConnection extends EventTarget {
constructor(url, opts={}) {
super();
this.url = url;
this._chatMessages = [];
this._socket = new WebSocket(this.url)
this._socket.addEventListener("close",(event)=>{
console.log("assistant: websocket connection closed");
this._socket = null;
});
this._socket.addEventListener("message",(event)=>{
let msg = JSON.parse(event.data);
console.log("assistant: received", msg);
if (msg.type === "chatMessage"){
this._chatMessages.push(msg.message);
this.dispatchEvent(new ChatMessageEvent(msg.message));
}
});
this._socket.addEventListener("open",(event)=>{
console.log("assistant: websocket connected");
});
}
say(text){
if (this._socket){
let userMessage = {
"role": "user",
"content": text,
};
this._chatMessages.push(userMessage);
this.dispatchEvent(new ChatMessageEvent(userMessage));
let msg = JSON.stringify({
type: "chatMessage",
message: text,
});
console.log("assistant: send", msg);
this._socket.send(msg);
}
}
get chatMessages(){
return Object.assign({}, this._chatMessages);
}
}

4
config.json 100644
View File

@ -0,0 +1,4 @@
{
"websocket": "ws://localhost:6565",
"api_key": null
}

5
contrib/lnstyles/.gitignore vendored 100644
View File

@ -0,0 +1,5 @@
*.css
*.css.map
lnstyles-dist.zip
lnstyles-test.zip

View File

@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<includedPredefinedLibrary name="Node.js Core" />
</component>
</project>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/lnstyle.iml" filepath="$PROJECT_DIR$/.idea/lnstyle.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions">
<TaskOptions isEnabled="true">
<option name="arguments" value="$FileName$:$FileNameWithoutExtension$.css" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="ERROR" />
<option name="fileExtension" value="scss" />
<option name="immediateSync" value="true" />
<option name="name" value="SCSS" />
<option name="output" value="$FileNameWithoutExtension$.css:$FileNameWithoutExtension$.css.map" />
<option name="outputFilters">
<array />
</option>
<option name="outputFromStdout" value="false" />
<option name="program" value="sass" />
<option name="runOnExternalChanges" value="true" />
<option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="true" />
<option name="workingDir" value="$FileDir$" />
<envs />
</TaskOptions>
</component>
</project>

View File

@ -0,0 +1,13 @@
all: dist
clean:
rm -f css/*.css css/*.css.map
dist: css/lnstyles.css
zip -r lnstyles-dist.zip css/lnstyles.css js svg/*.svg
zip -r lnstyles-test.zip css/lnstyles.css js svg/*.svg *.html *.shtml
css/%.css: css/%.scss
sass $< $@

View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<!--#include virtual="head.html" -->
<body class="overflow-auto flex-column scrolled">
<!--#include virtual="header.html" -->
<main class="container">
<div class="row-6">
<div class="sz-2">
<div class="dropdown">
<input type="checkbox">
<div>Some Dropdown...</div>
<div class="dropbox">
</div>
</div>
</div>
<div class="sz-2 text-center">
<button>I am a button</button>
</div>
<div class="sz-2">
<button>Me Too</button>
<button>so...</button>
</div>
<div class="sz-2 text-center">
<input type="checkbox" label="Check me">
<input type="checkbox" id="check0">
<label for="check0">another checker</label>
</div>
<div class="sz-2 text-center">
<input type="radio" name="radio" id="radio0" checked>
<label for="radio0">radio0</label>
<input type="radio" name="radio" id="radio1">
<label for="radio1">radio1</label>
<input type="radio" name="radio" id="radio2">
<label for="radio2">radio2</label>
</div>
<div class="sz-2">
<div class="item">an item
<button>
<img src="svg/delete.svg">
</button>
</div>
<div class="item">another item
<button>
<img src="svg/delete.svg">
</button>
</div>
</div>
<div class="sz-5">
<input type="text" name="testtext">
</div>
<div class="sz-1">
<button>Click me</button>
</div>
</div>
</main>
<!--#include virtual="footer.html" -->
</body>
</html>

View File

@ -0,0 +1,28 @@
.background {
position: absolute;
z-index: -100;
left: 0;
top: 0;
right: 0;
bottom: 0;
> video {
pointer-events: none;
min-width: 100%;
min-height: 100%;
object-fit: cover;
object-position: center;
}
&.shaded {
background-color: white;
> video {
opacity: 0.2;
}
}
}

View File

@ -0,0 +1,47 @@
$colors: (
"primary": "#33b5dd",
"secondary": "#ecae1a",
"tertiary": "#49b749",
"white": "#ffffff",
"black": "#000000",
"red": "#FF0000",
"green": "#00FF00",
"lightgreen": "#D9FFD9",
"blue": "#0000FF",
"lightblue": "#B4B4FF",
"gray": "#404040",
"lightgray": "#C0C0C0",
"selection": "#00b9ff",
"border": "#74d9ff",
"hover": "#e3f7ff",
"distinct": "#f6f6ff",
"disabled": "#989898",
"disabledback": "#ebebeb",
"header": "#e1e1e1",
);
:root {
@each $sym, $col in $colors {
--lns-color-#{$sym}: #{$col};
}
}
@each $sym, $col in $colors {
.text-#{$sym} {
color: #{$col};
}
.bg-#{$sym} {
background-color: #{$col} !important;
}
}
@for $n from 0 through 10 {
.opacity-#{$n} {
opacity: #{$n / 10};
}
.hover-opacity-#{$n}:hover {
opacity: #{$n / 10};
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,148 @@
$lns-font-size: 16px;
$lns-base-line-height: 150%;
$lns-gap: 0.5em;
$lns-min-side-gap: 30px;
$media-sizes: (
"xxxs": "280px",
"xxs": "340px",
"xs": "550px",
"sm": "760px",
"md": "970px",
"lg": "1180px",
"xl": "1390px",
"xxl": "1800px"
);
$container-sizes: (
"sm": "740px",
"md": "950px",
"lg": "1150px",
"xl": "1350px",
"xxl": "1750px"
);
$sides: (
"t": "-top",
"b": "-bottom",
"l": "-left",
"r": "-right"
);
$gap: 0.5em;
svg {
fill: currentColor;
}
@each $heading in (1,2,3,4,5,6) {
h#{$heading} > img {
height: 1em;
}
}
.position-absolute { position: absolute; }
.position-relative { position: relative; }
.position-static { position: static; }
.position-fixed { position: fixed; }
.sticky-top {
position: sticky;
top: 0px;
z-index: 100;
}
.overflow-auto {
overflow: auto;
}
.overflow-scroll {
overflow: scroll;
}
.overflow-visible {
overflow: visible;
}
.overflow-x-auto {
overflow-x: auto;
}
.overflow-x-scroll {
overflow-x: scroll;
}
.overflow-x-visible {
overflow-x: visible;
}
.overflow-y-auto {
overflow-y: auto;
}
.overflow-y-scroll {
overflow-y: scroll;
}
.overflow-y-visible {
overflow-y: visible;
}
.scrolled-transition {
position: fixed;
right: 3rem;
bottom: 3rem;
width: 2.5rem;
height: 2.5rem;
}
html .scrolled {
visibility: hidden;
opacity: 0;
pointer-events: none;
}
html:not([data-scroll='0']) .scrolled {
visibility: visible;
opacity: 1.0;
pointer-events: auto;
}
html[data-scroll='0'] .scrolled-transition {
transition: opacity 0.6s 1.0s, visibility 2.5s 0s;
}
html:not([data-scroll='0']) .scrolled-transition {
transition: opacity 0.6s 1.0s, visibility 0s 0s;
}
@each $width in (5, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90, 100) {
.w-#{$width} {
width: #{$width * 1%} !important;
}
.h-#{$width} {
height: #{$width * 1%} !important;
}
.vw-#{$width} {
width: #{$width}vw !important;
}
.vh-#{$width} {
height: #{$width}vh !important;
}
.min-vw-#{$width} {
min-width: #{$width}vw !important;
}
.min-vh-#{$width} {
min-height: #{$width}vh !important;
}
.max-vw-#{$width} {
max-width: #{$width}vw !important;
}
.max-vh-#{$width} {
max-height: #{$width}vh !important;
}
}
@each $zindex in (100,200,300,400,500,600,700,800,900,1000) {
.z-index-#{$zindex} {
z-index: #{$zindex};
}
}

View File

@ -0,0 +1,65 @@
.modal {
display: block;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5);
> div {
display: flex;
flex-direction: column;
position: relative;
width: min-content;
min-width: 40vw;
max-width: 90vw;
height: min-content;
min-height: 40vh;
max-height: 90vh;
margin: 2rem auto;
border: 3px solid #74d9ff;
border-radius: 2rem;
outline: 4px solid white;
background-color: white;
> .title {
position: relative;
> .close {
position: absolute;
width: 1.8rem;
right: 0.5rem;
top: 0.5rem;
&:hover {
background-color: #74d9ff;
border-radius: 100%;
}
}
> h1 {
font-size: 1.2em;
padding: 0.75em 1em;
border-bottom: 2px solid #74d9ff;
}
}
> .content {
flex-grow: 1;
padding: 0.5em;
overflow: auto;
}
> .buttons {
padding: 0.5em;
text-align: right;
}
}
}

View File

@ -0,0 +1,206 @@
@use "sass:map";
@import "defaults";
body, .container {
container-type: inline-size;
}
body {
min-width: 100%;
}
.container {
margin: auto;
width: 100%;
@each $prefix, $minwidth in $media-sizes {
@media (min-width: #{$minwidth}) {
width: calc(#{$minwidth} - 32px - var(--lns-min-side-gap));
}
}
}
@each $prefix, $minwidth in $media-sizes {
@container (min-width: #{$minwidth}) {
.container-#{$prefix} {
@extend .container;
width: #{$minwidth};
}
}
}
@each $columns in (6, 12, 24, 30, 35, 55){
.row-#{$columns} {
@extend .container;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: start;
& > * {
margin: #{calc($gap / 2)};
}
@each $prefix, $minwidth in $media-sizes {
@container (min-width: #{$minwidth}) {
@for $span from 1 through $columns {
& > .sz-#{$prefix}-#{$span}[class] {
width: calc(#{ calc(100% * $span / $columns) } - #{$gap});
margin: #{calc($gap / 2)};
}
}
}
}
@for $span from 1 through $columns {
& > .sz-#{$span} {
width: calc(#{ calc(100% * $span / $columns) } - #{$gap});
margin: #{calc($gap / 2)};
}
}
@for $n from 0 through 10 {
&.g-#{$n} > * {
--lns-gap: #{0.5em * $n};
}
}
}
.column-#{$columns} {
display: flex;
flex-direction: column;
flex-wrap: wrap;
& > * {
}
@each $prefix, $minwidth in $media-sizes {
@for $span from 1 through $columns {
@media (min-width: #{$minwidth}) {
& > .sz-#{$prefix}-#{$span}[class] {
height: calc(#{ calc(100% * $span / $columns) } - (1 * var(--lns-gap)));
margin-right: calc((0.5 * var(--lns-gap)));
margin-left: calc((0.5 * var(--lns-gap)));
margin-top: calc((0.5 * var(--lns-gap)));
margin-bottom: calc((0.5 * var(--lns-gap)));
}
}
}
}
@for $span from 1 through $columns {
& > .sz-#{$span} {
height: calc(#{ calc(100% * $span / $columns) } - (1 * var(--lns-gap)));
margin-right: calc((0.5 * var(--lns-gap)));
margin-left: calc((0.5 * var(--lns-gap)));
margin-top: calc((0.5 * var(--lns-gap)));
margin-bottom: calc((0.5 * var(--lns-gap)));
}
}
@for $n from 0 through 10 {
&.g-#{$n} > * {
--lns-gap: #{0.5em * $n};
}
}
}
}
.row {
@extend .row-12;
}
.column {
@extend .column-12;
}
@for $n from 0 through 10 {
@each $prefix, $suffix in $sides {
.p#{$prefix}-#{$n} {
padding#{$suffix}: #{0.5rem * $n} !important;
}
.m#{$prefix}-#{$n} {
margin#{$suffix}: #{0.5rem * $n} !important;
}
.p-#{$n} {
@extend .p#{$prefix}-#{$n};
}
.m-#{$n} {
@extend .m#{$prefix}-#{$n};
}
}
}
@each $prefix, $suffix in $sides {
.m#{$prefix}-auto {
margin#{$suffix}: auto !important;
}
.m-auto {
@extend .m#{$prefix}-auto;
}
}
aside {
@extend .p-1;
@each $prefix, $minwidth in $media-sizes {
@media (min-width: #{$minwidth}) {
max-width: calc((100% - #{map.get($container-sizes,$prefix)}) * 0.5);
@for $n from 0 through 10 {
&.m-#{$n}, &.ml-#{$n}.mr-#{$n} {
max-width: calc(((100% - #{map.get($container-sizes,$prefix)}) * 0.5) - (1.0em * #{$n}));
}
&.ml-#{$n}, &.mr-#{$n} {
max-width: calc(((100% - #{map.get($container-sizes,$prefix)}) * 0.5) - (0.5em * #{$n}));
}
}
}
}
&.left {
float: left;
}
&.right {
float: right;
}
}
.flex-column {
flex-direction: column;
@extend .display-flex;
}
.flex-row {
flex-direction: row;
@extend .display-flex;
}
.flex-grow, .flex-grow-1 {
flex-grow: 1 !important;
}
.flex-grow-0 {
flex-grow: 0 !important;
}
.flex-shrink, .flex-shrink-1 {
flex-shrink: 1 !important;
}
.flex-shrink-0 {
flex-shrink: 0 !important;
}
.flex-reverse {
flex-direction: row-reverse;
}
.flex-column.flex-reverse {
flex-direction: column-reverse;
}
.flex-nowrap {
flex-wrap: nowrap;
}

View File

@ -0,0 +1,20 @@
@import "reset";
@import "defaults";
@import "vars";
@import "page";
@import "grid";
@import "text";
@import "colors";
@import "backgrounds";
@import "nav";
@import "controls";
@import "dialog";
//@import "symbols";
//@import "colors";
//@import "text";
//@import "nav";
//@import "card";
//@import "tables";

View File

@ -0,0 +1,45 @@
nav {
display: flex;
flex-direction: row;
line-height: 2em;
white-space: nowrap;
a {
padding: 0;
margin: 0;
text-decoration: unset;
color: unset;
&:visited {
color: unset;
}
&:hover {
color: unset;
}
}
> * {
margin: 0 1em;
}
> .logo {
img {
width: 2em;
height: 2em;
margin: 0;
padding: 0;
}
}
> .nav-item {
font-size: 1.3em;
}
}

View File

@ -0,0 +1,75 @@
@import "vars";
body {
color: var(--lns-col-page);
background-color: var(--lns-bg-page);
}
/** Borders **/
.border {
border: 1px solid var(--lns-col-border);
}
.border-0 {
border: none !important;
}
.border-1 {
border: 1px solid var(--lns-col-border) !important;
}
@for $n from 0 through 10 {
.border-radius-#{$n} {
border-radius: #{calc(0.5em * $n)};
}
}
@each $suffix, $side in $sides {
.border#{$side} {
border#{$side}: 1px solid var(--lns-color-primary);
}
.border-distinct#{$side}:not(:last-of-type) {
border#{$side}: 1px solid var(--lns-color-primary);
}
.border#{$side}-0 {
border#{$side}: none !important;
}
}
.display-none {
display: none;
}
.display-block {
display: block;
}
.display-flex {
display: flex;
}
.display-inline-block {
display: inline-block;
}
.display-inline-flex {
display: inline-flex;
}
.cursor-default {
cursor: default;
}
.cursor-pointer {
cursor: pointer;
}
/* some styling classes */
.box {
border: 1px solid var(--lns-col-border);
border-radius: 0.5em;
padding: 0.5em;
}
footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
}

View File

@ -0,0 +1,44 @@
*, *::after, *::before {
box-sizing: border-box;
padding: 0;
margin: 0;
font-size: 1em;
line-height: inherit;
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word;
padding: 0.5em;
}
html, body { height: 100%; }
nav, a {
display: inline-block;
}
a:visited {
color: blue;
}
img, picture, video, svg {
display: block;
max-width: 100%;
}
canvas {
display: block;
}
html {
overflow: hidden;
}
body {
position: relative;
font-family: "DejaVu Sans", "Helvetica", "Nimbus Sans", "Open Sans", "Arial";
font-size: 16px;
line-height: 1.4em;
}

View File

@ -0,0 +1,166 @@
h1 {
font-size: 1.5em;
font-weight: bolder;
line-height: 1.1em;
margin: 0;
margin-bottom: 0.2em;
padding: 0.2em;
padding-left: 1.8em;
color: var(--lns-col-heading);
}
h2 {
font-size: 1.3em;
font-weight: bold;
--margin-bottom: 0.3em;
}
h3 {
font-size: 1.15em;
font-weight: bolder;
--margin-bottom: 0.3em;
}
h4 {
font-size: 1.15em;
--margin-bottom: 0.3em;
}
h5 {
font-size: 1.1em;
font-style: italic;
--margin-bottom: 0.3em;
}
h6 {
font-size: 1.05em;
font-style: italic;
--margin-bottom: 0.3em;
}
p {
line-height: 1.5em;
}
b {
font-weight: bold;
}
i {
font-style: italic;
}
u {
text-decoration: underline;
}
.text-left {
text-align: left;
}
.text-center {
text-align: center;
}
.text-right {
text-align: right;
}
.text-block {
text-align: justify;
}
.text-decoration-none {
text-decoration: none;
}
.text-underline {
text-decoration: underline;
}
.small, small {
font-size: 0.8em;
line-height: 0.8em;
}
.large {
font-size: 1.2em;
}
.text-bold {
font-weight: bold;
}
.text-bolder {
font-weight: bolder;
}
.text-normal {
font-weight: normal;
}
.text-lighter {
font-weight: lighter;
}
.text-monospace {
font-family: "Source Code Pro", "SF Mono", Monaco, Inconsolata, "Fira Mono", "Droid Sans Mono", monospace, monospace;
}
em, .em {
font-weight: bolder;
}
pre {
white-space: pre;
}
@each $prefix, $minwidth in $media-sizes {
@container (min-width: #{$minwidth}) {
.#{$prefix}-text-left {
text-align: left;
}
.#{$prefix}-text-center {
text-align: center;
}
.#{$prefix}-text-right {
text-align: right;
}
.#{$prefix}-text-block {
text-align: justify;
}
.#{$prefix}-small, small {
font-size: 0.8em;
line-height: 0.8em;
}
.#{$prefix}-large {
font-size: 1.2em;
}
}
}
.large {
font-size: 1.25em;
}
.small {
font-size: 0.75em;
}
@for $n from 0 through 10 {
.fs-#{n} {
}
}
ol, ul {
margin-left: 2em;
> li {
margin-bottom: 0.3em;
line-height: 1.2em;
}
}
.app {
h1 {
background-color: var(--lns-bg-heading);
border-radius: 0.7em;
}
}

View File

@ -0,0 +1,42 @@
.card {
position: relative;
border: 1px solid var(--lns-color-lightgray);
border-radius: 1.0em;
overflow: hidden;
@extend .p-0;
.card-img-top {
width: 100%;
}
.card-overlay {
position: absolute;
top: 0px;
left: 0px;
}
.card-text {
@extend .p-1;
}
ul {
list-style: none;
li {
width: 100%;
--padding-left: 0.5em;
--padding-right: 0.5em;
--padding-top: 0.5em;
--padding-bottom: 0.5em;
border-top: 1px solid var(--lns-color-lightgray);
&:last-child {
border-bottom: 1px solid var(--lns-color-lightgray);
}
}
}
}

View File

@ -0,0 +1,95 @@
.hmenu {
position: relative;
width: 100%;
vertical-align: top;
font-size: 1.4em;
padding: 0.5em;
margin: 0.4em 0;
border-collapse: collapse;
div {
display: inline-block;
padding: 0;
margin: -1px;
}
.spacer {
width: 1em;
height: 3em;
}
.itemframe {
height: 3em;
vertical-align: top;
&.opened {
.itemtext {
border: none;
}
.item {
border: 2px solid var(--lns-color-border);
border-bottom: none;
border-radius: 1em 1em 0 0;
background-color: var(--lns-color-primary);
}
.spacer {
border-bottom: 2px solid var(--lns-color-border);
border-radius: 0 0 1em 0;
background-color: white;
&:last-of-type {
border-radius: 0 0 0 1em;
}
}
}
}
.item {
height: 3em;
vertical-align: top;
border-bottom: 2px solid white;
}
.itemtext {
border: 2px solid var(--lns-color-border);
border-radius: 1em 1em 1em 1em;
height: 2em;
line-height: 2em;
padding: 0 0.5em;
cursor: pointer;
}
.display {
position: relative;
z-index: 1000;
display: flex;
width: 100%;
min-height: 12em;
border: 2px solid var(--lns-color-border);
flex-direction: row;
> div {
border: 2px solid var(--lns-color-border);
border-radius: 2em;
width: 10em;
height: 10em;
margin: 1em;
padding: 2em;
cursor: pointer;
&:hover {
border: 4px solid var(--lns-color-border);
background-color: var(--lns-color-header);
}
}
}
}

View File

@ -0,0 +1,9 @@
.lns-motorcontrol {
aspect-ratio: 1.0;
canvas {
width: 100%;
height: 100%;
}
}

View File

@ -0,0 +1,56 @@
nav {
display: flex;
font-size: 1.5rem;
width: max-content;
color: black;
& > *:not(ul) {
--padding-top: 0.5em;
--padding-bottom: 0.5em;
}
ul {
display: flex;
list-style: none;
line-height: 1.5rem;
li {
--padding-left: 1em;
--padding-right: 1em;
--padding-top: 0.5em;
--padding-bottom: 0.5em;
&::marker {
display: none;
}
* {
--padding-top: 0.5em;
--padding-bottom: 0.5em;
}
}
}
a {
font-style: normal;
text-decoration: none;
color: var(--lns-color-gray);
}
a:hover {
color: var(--lns-color-black);
text-decoration: underline;
}
a:visited {
color: var(--lns-color-gray);
}
img {
display: inline-block;
height: 2em;
line-height: 3em;
vertical-align: middle;
}
}

View File

@ -0,0 +1,36 @@
.symbol {
display: inline-block;
width: 2em;
height: 2em;
padding: 0.3em 0;
}
.sym-menu {
border: none;
background-image: url(../../svg/menu.svg);
background-size: 100% auto;
background-origin: border-box;
background-repeat: no-repeat;
background-position: center;
}
.sym-attention {
border: none;
background-image: url(../../svg/up-line.svg);
background-size: 100% auto;
background-origin: border-box;
background-repeat: no-repeat;
background-position: center;
}
@each $symbol in (settings, folders, left-arrow-dot, right-arrow-dot, up-arrow-dot, down-arrow-dot) {
.sym-#{$symbol} {
border: none;
background-image: url(../svg/#{$symbol}.svg);
background-size: 100% auto;
background-origin: border-box;
background-repeat: no-repeat;
background-position: center;
}
}

View File

@ -0,0 +1,57 @@
.table {
position: relative;
overflow-y: auto;
padding: 0;
background-color: white;
max-height: 100%;
table {
border-collapse: collapse;
width: 100%;
background-color: inherit;
}
thead {
display: table-header-group;
background-color: var(--lns-color-header);
td, th {
border-bottom: 1px solid black;
background-color: var(--lns-color-header);
font-size: 0.8em;
position: sticky;
top: 0px;
}
}
tbody {
&>tr {
background-color: inherit;
&:nth-child(even) {
background-color: var(--lns-color-distinct);
}
&:nth-child(odd) {
background-color: white;
}
&:hover {
background-color: var(--lns-color-hover);
}
&[selected] {
background-color: var(--lns-color-selection);
}
}
}
td {
margin: unset;
padding: 0.25em;
border: 1px solid #C0C0C0;
}
}

View File

@ -0,0 +1,39 @@
:root {
/* Page defaults */
--lns-bg-page: #e5edef;
--lns-col-page: black;
--lns-col-border: #00b9ff;
--lns-col-hint: #A0A0A0;
--lns-bg-section: white;
--lns-bg-hover: #c2f4ff;
--lns-col-invalid: var(--lns-col-page);
--lns-bg-invalid: #E0C0C0;
--lns-col-disabled: #808080;
--lns-bg-heading: #9fddff;
--lns-col-heading: #000000;
--lns-bg-seperator: #354c54;
--lns-col-seperator: #c8e9ff;
/* All button like elements */
--lns-col-button: white;
--lns-bg-button: #15a0c9;
--lns-border-button: #15a0c9;
/* User input and control elements */
--lns-col-control: black;
--lns-bg-control: white;
--lns-border-control: var(--lns-col-border);
--lns-col-selection: var(--lns-col-page);
--lns-bg-selection: #00b9ff;
}

View File

@ -0,0 +1,17 @@
<footer class="mt-auto pt-6">
<div class="bg-tertiary row-12">
<div class="sz-3">
<h3>lnstyles demo page</h3>
<p>Feel well in reading everything</p>
</div>
<div class="sz-3 text-center">The weather forecast for your area</div>
<div class="sz-3 text-center">Something else, that might be of common interest</div>
<div class="sz-3 text-right">Yet the last column today!</div>
</div>
</footer>
<script type="module" src="js/lnstyles.mjs" rel=""></script>
<script type="application/javascript">
import("./js/lnstyles.mjs").then((m)=>{
LNS = m.LNS;
});
</script>

View File

@ -0,0 +1,15 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lnstyles test page</title>
<link rel="stylesheet" href="css/lnstyles.css">
<link rel="icon" type="image/svg+xml" href="/svg/ln.svg">
<script type="importmap">
{
"imports": {
"lnstyles": "./js/lnstyles.mjs",
"vue": "./js/vue.esm-browser.mjs"
}
}
</script>
</head>

View File

@ -0,0 +1,28 @@
<header class="p-0 mb-2 sticky-top bg-lightgray">
<div class="container p-2">
<nav class="ml-5">
<a href="lnstyles.shtml">
<img src="svg/ln.svg">
</a>
<ul>
<li>
<a href="lnstyles.shtml">
Start
</a>
</li>
<li>
<a href="texts.shtml">Texts</a>
</li>
<li>
<a href="tables.shtml">Tables</a>
</li>
<li>
<a href="controls.shtml">Control Skeletons</a>
</li>
<li>
<a href="vue.shtml">Vue Tests</a>
</li>
</ul>
</nav>
</div>
</header>

View File

@ -0,0 +1,142 @@
import { VueLoader} from "../vue-loader.mjs";
var dropdown = {
template: `<div class="dropdown">
<div
class="wrapper"
@click="!searchable && open()"
>
<input type="checkbox" class="dropdown" v-model="opened">
<div class="flex-grow-1" v-if="!searchable"></div>
<input
v-if="searchable"
class="flex-grow-1 ml-1"
type="text"
ref="search"
:value="searchwords"
@input="search()"
@click="open()"
>
<item v-for="item in selection"
:value="item"
@remove="item_deselect(item)"
class="small"
>{{ labelFor(item) }}</item>
</div>
<div class="dropbox max-vh-70 z-index-1000" :class="{ open: opened, }">
<slot
:items="items"
:selected-items="selection"
:dropdown="this"
>
<vselect
:items="items"
:select="select"
:selected-items="selection"
@selected="(i)=>item_select(i)"
@deselected="(i)=>item_deselect(i)"
v-slot="{ item, }"
>
{{ labelFor(item) }}
</vselect>
</slot>
</div>
</div>`,
props: {
items: Array,
selectedItems: { type: Array, default: null },
selectedItem: { type: Object, default: null },
label: [ Function, String ],
select: { type: Number, default: 1 },
deselect: { type: Boolean, default: true },
searchable: { type: Boolean, default: true },
closeOnSelection: { type: Boolean, default: true },
},
data: function(){
return {
searchwords: "",
opened: false,
selection: null,
};
},
created(){
this.update();
},
updated(){
this.update();
},
emits: {
change: (selected)=>{
return selected instanceof Array;
},
selected: null,
deselected: null,
},
computed: {
},
methods: {
item_select(item){
if (this.select && !this.selection.includes(item)) {
this.selection.push(item);
while (this.selection.length > this.select)
this.selection.shift();
this.$emit('selected', item);
this.$emit('change', this.selection);
}
if (this.closeOnSelection)
this.close();
},
item_deselect(item){
if (this.selection.includes(item)) {
this.selection.remove(item);
this.$emit('deselected', item);
this.$emit('change', this.selection);
}
},
item_switch(item){
if (this.selection.includes(item))
this.item_deselect(item);
else
this.item_select(item);
},
set_selection(sel){
this.selection = sel;
this.$emit("change", sel);
if (this.closeOnSelection)
this.close();
},
labelFor: function(item){
if (!this.label)
return item;
if (this.label instanceof Function){
return this.label(item);
}
return item[this.label];
},
open(){
this.opened = true;
},
close(){
this.opened = false;
},
search(){
this.open();
this.searchwords = this.$refs.search.value;
},
update(){
this.selection = this.selectedItems || (this.selectedItem ? [ this.selectedItem ] : []);
},
},
};
export const components = {
dropdown,
};
VueLoader.$component("dropdown", dropdown );

View File

@ -0,0 +1,62 @@
import {VueLoader} from "../vue-loader.mjs";
import {LNS} from "../lnstyles.mjs";
let hmenu = {
props: {
items: { type: Array },
openedItem: { type: Object }
},
emits: {
"update:openedItem": null,
"navigate": null,
},
template: `<div class="hmenu">
<div v-for="item in items"
class="itemframe"
:class="{ opened: (openedItem == item) }"
>
<div class="spacer"></div>
<div class="item">
<div class="itemtext"
@click="headerclicked(item)">
<div>{{ item._ }}</div>
</div>
</div>
<div class="spacer"></div>
</div>
<div v-if="openedItem"
class="display"
>
<template v-for="(child, name) in openedItem">
<div v-if="!['$','_','pos'].includes(name) && child.$"
class=""
@click="navigate(child.$)"
>
{{ child._ }}<br>
<div class="small"><div class="small">{{ child.$ }}</div></div>
</div>
</template>
</div>
</div>`,
computed: {
},
methods: {
navigate(uri){
this.$emit('update:openedItem', null);
this.$emit("navigate", uri);
},
headerclicked(item){
if (item.$)
this.navigate(item.$);
else
this.$emit('update:openedItem',(this.openedItem == item) ? null : item)
}
}
};
export const components = {
hmenu,
};
VueLoader.$component(components);

View File

@ -0,0 +1,24 @@
var item = {
props: {
removeable: { type: Boolean, default: ()=>true },
value: { default: undefined },
},
data: function(){
return {};
},
emits: {
remove: null,
},
methods: {
mouseclick(){
this.$emit('remove', this.value);
}
},
template: `<div class="item"><div class="wrapper"><slot></slot><button v-if="removeable" @click="(ev)=>mouseclick()"><img src="svg/delete.svg"></button></div></div>`,
}
export const components = {
item,
};

View File

@ -0,0 +1,159 @@
import {VueLoader} from "../vue-loader.mjs";
var lookup = {
props: {
items: { type: Array, default: [] },
modelValue: { type: [String, Object], default: "", },
field: { type: String, default: null },
totext: { type: Function, default: function(v){ return v ? (this.field ? v[this.field] : v) : ""; } },
},
data: function(){
return {
did: Date.now() + '-' + Math.round(Math.random() * 100000000),
};
},
emits: {
change: null,
create: null,
'update:modelValue': null,
},
methods: {
ev_change(ev){
let v = ev.target.value;
let i = this.items.find((i)=>{ return this.totext(i) == v; });
if (this.items.includes(i)) {
this.$emit('change', i);
this.$emit('update:modelValue', i)
} else {
this.$emit('create', v);
}
},
},
computed: {
},
template: `<div class="lookup">
<input type="text"
:value="this.totext(modelValue)"
:list="this.did"
@change="(ev)=>ev_change(ev)"
>
<datalist :id="this.did">
<option v-for="item in items">{{ this.totext(item) }}</option>
</datalist>
</div>`,
}
/*
var lookup = {
props: {
items: { type: Array, default: [] },
value: { default: "", },
filter: { type: Function, default: function(i, s){ return i.startsWith(s); } },
},
data: function(){
return {
opened: false,
has_focus: false,
tvalue: this.value || "",
searchtext: this.value || "",
};
},
emits: {
change: null,
create: null,
},
methods: {
show(){
this.opened = true;
},
hide(){
this.opened = false;
},
ev_dblclick(ev){
if (!this.lookupItems.includes(this.searchtext))
this.searchtext = "";
ev.target.select();
this.show();
},
ev_input(ev){
this.log(ev);
this.tvalue = ev.target.value;
this.searchtext = this.tvalue;
if (this.lookupItems.length && (!['deleteContentForward', 'deleteContentBackward'].includes(ev.inputType))) {
this.show();
if ((this.lookupItems.length == 1) && (this.lookupItems[0].startsWith(this.tvalue))) {
this.tvalue = this.lookupItems[0];
ev.target.value = this.lookupItems[0];
ev.target.setSelectionRange(this.searchtext.length, this.lookupItems[0].length);
}
}
},
ev_change(ev){
this.log(ev);
this.ev_select(ev.target.value);
this.hide();
},
ev_select(selected){
if (selected) {
this.tvalue = selected;
this.searchtext = selected;
this.hide();
if (!this.lookupItems.includes(selected))
this.$emit('create', selected);
else
this.$emit('change', selected);
}
},
ev_keypress(ev){
this.log(ev);
if (ev.code == 'Enter'){
this.ev_select(ev.target.value);
}
},
log(...args){
console.log(...args);
},
enqueue(job){
setTimeout(job, 150);
},
},
computed: {
lookupItems(){
if (this.searchtext.length) {
let results = this.items.filter((item) => this.filter(item, this.searchtext));
return results;
}
return this.items;
},
},
template: `<div class="lookup"
@focusin="(ev)=>{ log(ev); this.has_focus=true; }"
@blur="(ev)=>{ log(ev); }"
@focus="(ev)=>{ log(ev); }"
>
<input type="text"
:value="tvalue"
@dblclick="(ev)=>ev_dblclick(ev)"
@input="(ev)=>ev_input(ev)"
@keypress="(ev)=>ev_keypress(ev)"
>
<div
class="dropbox"
:class="{ open: this.opened && this.lookupItems.length }"
><vselect
:items="lookupItems"
:selected-items="[tvalue]"
:deselect="false"
v-slot="{ item }"
@selected="(s)=>{ log(ev); ev_select(s); }"
><slot :item="item">{{ item }}</slot></vselect>
</div>
</div>`,
}
*/
export const components = {
lookup,
};
VueLoader.$component(components);

View File

@ -0,0 +1,69 @@
import { LNS } from '../lnstyles.js';
var sidebar = {
props: {
opened: { type: Number, default: -1, },
width: { type: String, default: "25vw" },
label: { type: String, default: null },
direction: { type: String, default: "left" },
icons: { type: [ Array, Object ], default: [ 'menu', ] }
},
data: function(){
return {
open: -1,
expanded: this.opened != -1,
};
},
emits: {
show: null,
},
methods: {
show(no){
if (no == -1){
this.expanded = false;
} else {
this.expanded = true;
this.open = no;
LNS(Array.from(this.$refs.slots.children))
.removeClass('selected')
.at(this.open)
.addClass('selected');
}
this.$emit('show', this.open);
},
switch(no){
if (this.expanded && this.open == no){
this.show(-1);
} else {
this.show(no);
}
},
visible(){
},
},
mounted(){
this.show(this.opened);
},
template: `<div class="sidebar">
<div class="bar">
<button
v-for="nr in this.icons.length"
:class="{ [this.icons[nr-1]]: true, selected: this.expanded && (this.open == (nr-1)) }"
@click="this.switch(nr-1);"
>{{ label }}</button>
</div>
<div class="slider" :class="{ open: this.expanded }" :style="{ width: this.expanded ? this.width : null }">
<div :style="{ width: this.width, }" class="p-0 m-0" ref="slots">
<slot
:sidebar="this"
></slot>
</div>
</div>
</div>`,
}
export const components = {
sidebar,
};

View File

@ -0,0 +1,39 @@
import { VueLoader} from "../vue-loader.mjs";
export const textfield = {
props: {
modelValue: String,
multiLine: { type: Boolean, default: false, },
},
emits: {
"update:modelValue": null,
},
methods: {
edit(ctl){
ctl.contentEditable = true;
},
endEdit(ctl){
ctl.contentEditable = false;
this.$emit('update:modelValue', ctl.innerText);
},
input(evt){
console.log(evt);
if (evt.keyCode === 13){
evt.preventDefault();
this.endEdit(evt.target);
}
},
},
template: `<div
class="textfield"
tabindex="0"
@focusin="e=>edit(e.target)"
@focusout="e=>endEdit(e.target)"
@keydown="input"
>{{ modelValue }}</div>`,
}
export const components = {
'textfield': textfield,
}
VueLoader.$component(components);

View File

@ -0,0 +1,49 @@
var value = {
props: {
value: { default: 0, type: Number },
unit: { default: null, type: String },
ranges: {
type: Object, default: {
0: '',
3: 'k',
6: 'M',
9: 'G',
12: 'T',
15: 'P',
18: 'E',
}
},
},
data: function(){
return {};
},
emits: {
},
methods: {
},
computed: {
metricvalue(){
if (this.value == 0)
return "0 " + this.unit;
let e = Math.trunc(Math.log10(this.value));
let m = e - (e % 3);
let div = Math.pow(10, e -2);
let fdiv = Math.pow(10, 2 - (e % 3));
// return this.value + ":" + m + ':' + Math.round(this.value/div) + ':' + e + ":" + fdiv;
return (Math.round(this.value/div)/fdiv).toString() + ' ' + this.ranges[m] + this.unit;
},
},
template: `<div class="value" :tooltip="this.value + ' ' + this.unit"><slot>
{{ metricvalue }}
</slot></div>`,
}
export const components = {
value,
};

View File

@ -0,0 +1,74 @@
var vselect = {
template: `<div class="row">
<div class="sz-12 row m-0 p-0 border-distinct-bottom control"
v-for="item in items"
@click="(ev)=>item_select(item, ev)"
:selected="selection.includes(item) ? '' : null"
><slot
:item="item"
:selected-items="selection"
><div class="sz-12">{{ item }}</div></slot></div>
</div>`,
props: {
items: Array,
selectedItems: { type: Array, default: [] },
select: { type: Number, default: 1 },
deselect: { type: Boolean, default: true },
},
data: function(){
return {
selection: null,
};
},
emits: {
change: (selected)=>{
return selected instanceof Array;
},
'selected': null,
'deselected': null,
},
updated(){
this.update();
},
created(){
this.update();
},
computed: {
/*
selection(){
return this.selectedItems;
},
*/
},
methods: {
item_select(item, ev){
if (this.select) {
if (this.selection.includes(item)) {
if (this.deselect) {
this.selection.remove(item);
this.$emit("deselected", item);
this.$emit("change", this.selection);
}
} else {
this.selection.push(item);
while (this.selection.length > this.select)
this.selection.shift();
this.$emit("selected", item);
this.$emit("change", this.selection);
}
}
ev.preventDefault();
return false;
},
update(){
this.selection = this.selectedItems;
},
},
};
export const components = {
vselect,
};

View File

@ -0,0 +1,81 @@
var vtable = {
template: `<div class="table">
<table>
<thead>
<tr>
<td v-for="column in columns">{{ column.label || column.key || column }}</td>
</tr>
</thead>
<tbody class="overflow-y-scroll">
<tr v-for="item in filter(search, items)"
class="control"
:selected="selectedItems.includes(item) ? '' : null"
@dblclk="return false;"
@click="(ev)=>mouseclick(item, ev)"
@mouseenter="(ev)=>mouseenter(item, ev)"
@mouseleave="(ev)=>mouseleave(item, ev)"
:class="{ 'ptr-default': select }">
<td v-for="column in columns">{{ item[ column.key ] }}</td>
</tr>
</tbody>
</table>
</div>`,
props: {
items: Array,
selectedItems: { type: Array, default: [] },
columns: Array,
select: { type: Number, default: 1 },
search: { type: String, default: "" },
filter: { type: Function, default: function(search, items){
let words = search ? search.split() : [];
words.forEach(word => {
word = word.toLowerCase();
items = items.filter((item)=>{
let keys = Object.keys(item);
for (let n=0;n<keys.length;n++){
if (item[keys[n]].toString().toLowerCase().includes(word))
return true;
}
return false;
});
});
return items;
}},
},
data: function(){
return {};
},
emits: {
change: (selected)=>{
return selected instanceof Array;
},
},
computed: {
},
methods: {
mouseenter(item, ev){
},
mouseleave(item, ev){
},
mouseclick(item, ev){
if (this.select) {
if (!this.selectedItems.remove(item)) {
this.selectedItems.push(item);
}
while (this.selectedItems.length > this.select)
this.selectedItems.shift();
this.$emit("change", this.selectedItems);
}
ev.preventDefault();
return false;
},
},
};
export const components = {
vtable,
};

View File

@ -0,0 +1,153 @@
import { VueLoader} from "../vue-loader.mjs";
import { Paths } from "../extensions.mjs";
let example = [
{
label: "Root Node",
items: [
{ label: '2nd level folder A', items: [], },
{ label: '2nd level folder B', items: [
{ label: '3rd level folder A', items: [], },
{ label: '3rd level folder B', items: [], },
{ label: '3rd level folder C', items: [], },
{ label: '3rd level folder D', items: [], },
],
},
{ label: '2nd level folder C', items: [
{ label: '3rd level folder A', items: [], },
{ label: '3rd level folder B', items: [], },
{ label: '3rd level folder C', items: [], },
{ label: '3rd level folder D', items: [], },
],
},
],
},
{
label: "Root Node B",
items: [
{ label: '2nd level folder A', items: [], },
{ label: '2nd level folder B', items: [
{ label: '3rd level folder A', items: [], },
{ label: '3rd level folder B', items: [], },
{ label: '3rd level folder C', items: [], },
{ label: '3rd level folder D', items: [], },
],
},
{ label: '2nd level folder C', items: [
{ label: '3rd level folder A', items: [], },
{ label: '3rd level folder B', items: [], },
{ label: '3rd level folder C', items: [], },
{ label: '3rd level folder D', items: [], },
],
},
],
}
];
var vtreeitem = {
props: {
indent: { type: Number, default: 0, },
item: Object,
children: { type: String, default: 'items', },
field: { type: String, default: "label" },
totext: { type: Function, default: function(v){ return v ? (this.field ? v[this.field] : v) : ""; } },
selected: { type: Object, default: null, },
path: { type: Array, default: [] }
},
emits: {
select: null,
},
data(){
return { opened: false, Paths }
},
methods: {
ev_click(ev){
this.$emit("select", this.item, this.path);
},
},
computed: {
baseUri(){
return Paths.getDirectory(import.meta.url);
},
},
template: `<div class="vtree-item">
<div>
<input v-if="item[children] && item[children].length"
class="vtree-item"
type="checkbox"
v-model="opened"
>
<img v-if="!item[children] || !item[children].length" :src="baseUri + '../../svg/dash.svg'" class="vtree-item" />
<div
:class="{ label: true, selected: (this.selected == item) }"
@click="(ev)=>ev_click(ev)"
:sel="this.totext(this.selected)"
:it="this.totext(item)"
:choice="(this.selected == item)"
><slot :item="this.item" :selected="this.selected">{{ this.totext(item) }}</slot></div>
</div>
<vtree-item v-if="opened"
v-for="item in this.item[children]"
:item="item"
:children="children"
:totext="totext"
:field="field"
:selected="selected"
:path="[...this.path, this.item]"
@select="(si, p)=>this.$emit('select', si, p)"
><slot :item="item"></slot></vtree-item>
</div>`
}
var vtree = {
props: {
items: { type: Array, default: [], },
modelValue: { type: Object, default: null, },
field: { type: String, default: "label" },
children: { type: String, default: 'items', },
totext: { type: Function, default: function(v){ return v ? (this.field ? v[this.field] : v) : ""; } },
deselect: { type: Boolean, default: true, }
},
data: function(){
return {
did: Date.now() + '-' + Math.round(Math.random() * 100000000),
selected: this.modelValue,
};
},
emits: {
"update:modelValue": null,
"update:selectedPath": null,
select: null,
},
methods: {
ev_select(selectedItem, path){
this.selected = selectedItem;
this.$emit('update:modelValue', selectedItem);
this.$emit('update:selectedPath', path);
},
},
computed: {
},
updated(){
},
template: `<div class="vtree">
<vtree-item v-for="item in items"
:item="item"
:children="children"
:field="field"
:totext="totext"
:selected="selected"
:choice="(this.selected == item)"
@select="(i,p)=>ev_select(i,p)"
:path="[]"
><slot></slot></vtree-item>
</div>`,
}
export const components = {
'vtree-item': vtreeitem,
'vtree': vtree,
};
VueLoader.$component(components);

View File

@ -0,0 +1,48 @@
Number.prototype.clamp = function (min, max) {
return Math.min(Math.max(this, min), max);
};
Number.prototype.isWithin = function (min, max) {
return (this >= min) && (this <= max);
};
Array.prototype.remove = function (item) {
let idx = this.indexOf(item);
if (idx != -1)
this.splice(idx, 1);
return (idx != -1);
}
export const Paths = {
basename(path){
return path.split("/").reverse()[0];
},
getDirectory(path){
if (path.endsWith("/"))
return path;
return path.split("/").slice(0,-1).join("/") + "/";
}
};
Object.prototype.forEach = function(cb){
Object.getOwnPropertyNames(this).forEach((n)=>{
cb(this[n], n);
});
};
// Object.prototype.merge = function(other){
// Object.getOwnPropertyNames(other).forEach((key)=>{
// let t = typeof other[key];
// if (t === "object"){
// if (this.hasOwnProperty(key)){
// Object.merge(this[key],other[key]);
// } else {
// this[key] = other[key];
// }
// } else if (t === "function"){
// } else {
// this[key] = other[key];
// }
// });
// return this;
// }

View File

@ -0,0 +1,135 @@
import {computed, markRaw, shallowRef, reactive, toRaw} from "./vue.esm-browser.mjs";
export const RouterView = {
props: {
},
inject: ["$route"],
provide() {
return {
"$route": computed(this.getNextRoute),
};
},
methods: {
getNextRoute(){
if (this.$route && this.$route.next){
let route = this.$router.findRoute(this.$route.next, toRaw(this.$route.routes) || {}, toRaw(this.$route.parameters));
console.log("subroute for " + this.$route.next, route);
return route;
}
return null;
},
getComponent(){
return toRaw(this.$route.component);
}
},
template: `<template v-if="$route">
<component :is="getComponent()"></component>
</template>`,
}
let routeTemplate = {
path: "...",
label: "...",
component: null,
pages: {
"Seite 1": {
component: null,
},
"Seite 2": {
component: null,
}
},
}
export class LNRouter
{
constructor(opts) {
this.__app = null;
this.__routes = opts.routes || {};
this.__current = reactive({ route: null, routestack: [] });
this.__self = reactive(this);
}
install(app, opts){
this.__app = app;
this.__app.config.globalProperties.$router = this.__self;
this.__app.config.unwrapInjectedRef = true;
this.__app.component("router-view", RouterView);
let self = this;
this.__app.provide("$route", computed(()=>{
return this.__current.route;
}));
window.addEventListener("popstate", (ev)=>self.onPopState());
window.addEventListener("hashchange", (ev)=>self.onPopState());
this.getCurrentUri();
this.onPopState();
}
getCurrentUri(){
if (!location.hash)
window.history.replaceState(null, "", "#/");
return window.location.hash;
}
push(uri){
window.history.pushState(null, "", "#" + uri);
this.onPopState();
}
onPopState(){
let routeUri = window.location.hash.substring(1);
this.setup(routeUri);
}
setup(uri){
let route = this.findRoute(uri, this.__routes);
console.log("route for " + uri, route);
this.__self.__current.route = route;
}
findRoute(path, routes, parameters = {}){
let pathElements = path.split("/").filter(e=>e);
let routePaths = Object.getOwnPropertyNames(routes);
for (let n=0;n<routePaths.length;n++){
let match = this.matchRoute(pathElements, routePaths[n]);
if (match){
return {
parameters: Object.assign({}, parameters, match.parameters),
next: match.next,
routes: toRaw(routes[routePaths[n]].routes || {}),
component: toRaw(routes[routePaths[n]].component),
};
}
}
return null;
}
matchRoute(path, route){
let routeElements = route.split("/").filter(e=>e);
if (routeElements.length > path.length)
return false;
let match = { parameters: {}, };
for (let n=0; n<routeElements.length; n++){
let c = routeElements[n];
if (c.startsWith(":")){
match.parameters[c.substring(1)] = path[n];
} else if (c != path[n])
{
return false;
}
}
match.next = path.slice(routeElements.length).join("/");
return match;
}
}
export default { LNRouter }

View File

@ -0,0 +1,248 @@
import "./extensions.js";
class LNS {
constructor(items, container = null) {
let it = typeof items;
container ||= document;
if (items instanceof LNS) {
this.__items = items.__items;
} else if (items instanceof Array) {
this.__items = Array.from(items);
} else if (it === "string") {
items = items.trim();
if (items.startsWith('<')) {
let hdiv = document.createElement("div");
hdiv.innerHTML = items;
this.__items = Array.from(hdiv.children);
} else {
this.__items = Array.from(container.querySelectorAll(items));
}
} else if (items instanceof Object) {
this.__items = [];
Object.keys(items).forEach((v, i) => this.__items.push({key: v, value: items[v]}));
} else {
this.__items = [items];
}
}
length() {
return this.__items.length;
}
get(n) {
return this.__items[n];
}
concat(items) {
let other = new LNS(items);
return new LNS(this.__items.concat(other.__items));
}
first() {
return new LNS((this.__items.length == 0) ? [] : this.__items[0]);
}
at(no){
return new LNS((no >= this.__items.length) ? [] : [ this.__items[no], ]);
}
each(iter) {
this.__items.forEach((i, n) => {
iter.call(i, i, n);
});
return this;
}
addClass(className) {
className.split(" ").forEach((c)=>{
this.__items.forEach((i) => {
i.classList.add(c);
});
});
return this;
}
removeClass(className) {
className.split(" ").forEach((c)=>{
this.__items.forEach((i) => {
i.classList.remove(c);
});
});
return this;
}
append(c) {
let lns = new LNS(this);
let ch = lns.get(0);
ch.appendChild(new LNS(c).get(0));
return this;
}
appendTo(p) {
let parent = new LNS(p).get(0);
if (parent) {
this.each((i) => {
parent.appendChild(i);
});
}
return this;
}
remove(){
this.__items.forEach((i) => i.remove());
return this;
}
on(evtName, handler) {
this.__items.forEach((i) => {
i.addEventListener(evtName, (evt) => {
handler.call(i, evt, i);
return false;
});
});
return this;
}
dispatchEvent(evt) {
this.__items.forEach((i) => {
i.dispatchEvent(evt);
});
return this;
}
focus(){
this.__items[0].focus();
return this;
}
select(){
this.__items.forEach((i) => {
console.log((i.value || i.innerText));
//i.setSelectionRange(0, (i.value || i.innerText).length );
i.select();
});
return this;
}
value(val = undefined){
if (val === undefined)
return this.get(0).value;
this.each((i)=>i.value = val);
return this;
}
text(val){
if (val === undefined)
return this.get(0).innerText;
this.each((i)=>i.innerText = val);
return this;
}
html(val){
if (val === undefined)
return this.get(0).innerHTML;
this.each((i)=>i.innerHTML = val);
return this;
}
scrollIntoView(){
this.get(0).scrollIntoView();
return this;
}
enable(){
this.each((i)=>i.disabled = false);
}
disable(){
this.each((i)=>i.disabled = true);
}
}
function factory(items, container = null) {
return new LNS(items, container)
}
factory.$prefix = "/lnstyle";
factory.registerMethod = function (name, method) {
LNS.prototype[name] = method;
}
factory.replaceMethod = function (name, method) {
let o = this[name];
this[name] = (...args) => {
method.call(this, o, ...args);
};
};
factory.hookMethod = function (name, preHook, postHook) {
let o = this[name];
this[name] = (...args) => {
preHook?.call(this, ...args);
o.call(this, ...args);
postHook?.call(this, ...args);
};
};
factory.$in = function(timeout, cb){
setTimeout(cb, timeout);
}
factory.includes = function(item, search){
if (Array.isArray(item))
{
for (let i=0;i<item.length;i++){
if (factory.includes(item[i], search))
return true;
}
return false;
} else if (Number.isFinite(item)){
return item.toString().includes(search);
} else if (item.includes) {
return item.includes(search);
} else {
let keys = Object.keys(item);
for (let n = 0; n < keys.length; n++) {
let test = item[keys[n]];
if (factory.includes(test, search)) {
console.log(test);
return true;
}
}
}
return false;
};
function setupScrolling() {
let l = new LNS(".scrolled");
if (l.length() && l.get(0) == document.body) {
window.fetch("svg/up-line.svg")
.then(r => r.text())
.then(svg => {
l.append(
" <div class=\"scrolled scrolled-transition\">\n" +
" <a href=\"#\" class=\"text-decoration-none\" onclick=\"document.body.scrollTo(0,0); return false;\">\n" +
svg +
" </a>\n" +
" </div>"
);
l.removeClass("scrolled");
});
}
document.documentElement.dataset.scroll = document.body.scrollTop;
document.body.addEventListener('scroll', () => {
document.documentElement.dataset.scroll = document.body.scrollTop;
});
}
// if (document.body)
// setupScrolling();
// else
// window.addEventListener("load", () => setupScrolling());
export const $in = LNS.$in;
export { factory as LNS };

View File

@ -0,0 +1,118 @@
import { LNS, $in } from "./lnstyles.mjs";
var validHooks = ["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed" ];
export class VueLoader {
static ___components = {};
static $component(name, component){
if (typeof name === "object"){
LNS(name).each((kv)=>{
this.___components[kv.key] = kv.value;
});
} else {
this.___components[name] = component;
}
}
constructor(opts = {}) {
this._module_sources = [];
this._modules = [];
this._components = {};
this._options = Object.assign({
appNode: "main",
modules: [],
modSearchPaths: ["./components"],
data(){ return {}; },
methods: {},
computed: {},
}, opts);
this._app = null;
this._options.modules.forEach((v,i)=>{
this.module(v);
});
}
start(appNode){
let self = this;
return import("./vue.esm-browser.mjs")
.then(vue => {
self._vue = vue;
})
.then(()=>this.loadModules())
.then(()=>self.loadComponents())
.then(()=>{
let appOptions = {
data: self._options.data,
methods: self._options.methods,
computed: self._options.computed,
};
if (this._options.hooks){
LNS(this._options.hooks).each((kv)=>{
if (validHooks.includes(kv.key))
appOptions[kv.key] = kv.value;
});
}
self._app = self._vue.createApp(appOptions);
self._app.config.globalProperties.$LNS = LNS;
LNS(VueLoader.___components)
.each((kv)=>{
self._app.component(kv.key, kv.value);
});
LNS(self._components)
.each((kv)=>{
self._app.component(kv.key, kv.value);
});
return self._app;
})
.then(app => {
app.mount(LNS(appNode || self._options.appNode).get(0));
})
;
}
module(source){
this._module_sources.push( source );
}
loadModules(){
let pl = [];
let self = this;
this._module_sources.forEach((v,i)=>{
pl.push(
import(v)
.then(m => {
self._modules.push(m);
})
);
});
return Promise.all(pl);
}
component(name, component){
this._components[ name ] = component;
}
loadComponents(){
let self = this;
this._modules.forEach((v,i)=>{
if (v.components) {
Object.keys(v.components).forEach((k) => {
self._components[k] = v.components[k];
});
}
});
return Promise.all([]);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,714 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>KitchenSink</title>
<link rel="stylesheet" href="css/lnstyles.css">
</head>
<body>
<!-- HTML5 Kitchen sink by @dbox -->
<header role="banner">
<h1>HTML5 Kitchen Sink</h1>
<small>Jump to: <a href="#headings">Headings</a> | <a href="#sections">Sections</a> | <a
href="#phrasing">Phrasing</a> | <a href="#palpable">Palpable Content</a> | <a href="#embeds">Embeds</a> | <a
href="#forms">Forms</a> | <a href="#tables">Tables</a> </small> <br><br>
<p>This section seves as the <code>header</code>.</p>
</header>
<hr>
<main>
<section id="headings">
<h3><a href="#headings">#</a> Headings </h3>
<p>Elements <code>h1</code>, <code>h2</code>, <code>h3</code>, <code>h4</code>,
<code>h5</code>, <code>h6</code> make up the <em>heading content</em> category.
</p>
<hgroup>
<h1>h1 I am most important.</h1>
<h2>h2 Back in my quaint <a href='#'>garden</a></h2>
<h3>h3 Jaunty <a href='#'>zinnias</a> vie with flaunting phlox.</h3>
<h4>h4 Five or six big jet planes zoomed quickly by the new tower.</h4>
<h5>h5 Expect skilled signwriters to use many jazzy, quaint old alphabets effectively.</h5>
<h6>h6 Pack my box with five dozen liquor jugs.</h6>
</hgroup>
<footer>
<p>See the <a target="_blank" href="https://www.w3.org/TR/html5/dom.html#heading-content">Heading
Content spec.</a></p>
<p>Note: these two paragraphs are contained in a <code>footer</code> element.
</p>
</footer>
</section>
<hr>
<section id="sections">
<header>
<h3><a href="#sections">#</a> Sections</h3>
<p>Elements <code>article</code>, <code>aside</code>, <code>nav</code>,
<code>section</code> make up the <em>sectioning content</em> category.
</p>
<nav>
<p>These links are contained in a <code>nav</code> element.</p>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
</header>
<article>
<p>This paragraph is nested inside an <code>article</code> element. It contains many different, sometimes
useful, <a href="http://www.w3schools.com/tags/">HTML5 elements</a>. Of course there are classics like
<em>emphasis</em>, <strong>strong</strong>,
and <small>small</small> but there are many others as well. Hover the following text for abbreviation
element: <abbr title="abbreviation">abbr</abbr>. You can define
<del>deleted text</del>
which often gets replaced with
<ins>inserted</ins>
text.
</p>
<p>You can also use <kbd>keyboard text</kbd>, which sometimes is styled similarly to the
<code>&lt;code&gt;</code> or <samp>samp</samp> elements. Even more specifically, there is an element
just for <var>variables</var>. Not to be mistaken with block
quotes below, the quote element lets you denote something as <q>quoted text</q>. Lastly don't forget the
sub (H<sub>2</sub>O) and sup (E = MC<sup>2</sup>) elements.</p>
<section>
<p>This paragraph is contained in a <code>section</code> element of its parent <code>article</code>
element.</p>
<p>↓ The following paragraph has the <code>hidden</code> attribute and should not be displayed. ↓</p>
<p hidden>→ You should not see this paragraph. ←</p>
<p>↑ The previous paragraph should not be displayed. ↑</p>
</section>
</article>
<aside>
<p>This is contained in an <code>aside</code> element.</p>
</aside>
<footer>
<p>See the <a target="_blank" href="https://www.w3.org/TR/html5/dom.html#sectioning-content">Sectioning
Content spec.</a></p>
</footer>
</section>
<hr>
<section id="phrasing">
<header>
<h3><a href="#phrasing">#</a> Phrasing</h3>
<p>Elements <code>abbr</code>, <code>b</code>, <code>bdi</code>,
<code>bdo</code>, <code>br</code>, <code>cite</code>, <code>code</code>,
<code>data</code>, <code>del</code>, <code>dfn</code>, <code>em</code>,
<code>i</code>, <code>ins</code>, <code>kbd</code>, <code>mark</code>,
<code>meter</code>, <code>progress</code>, <code>q</code>, <code>s</code>,
<code>samp</code>, <code>small</code>, <code>span</code>, <code>strong</code>,
<code>sub</code>, <code>sup</code>, <code>time</code>, <code>u</code>,
<code>var</code>, <code>wbr</code>, and others make up the <em>phrasing
content</em> category.
</p>
</header>
<p><code>abbr</code>: Some vehicles meet the
<abbr title="Super Ultra Low Emission Vehicle">SULEV</abbr> standard.<br>
<code>br</code> was used to make this sentence start on a new line.</p>
<p><code>bdi</code>: Some languages read right to left,
<bdi lang="ar">مرحبا</bdi>
.
<code>bdo</code>: <bdo dir="rtl">The normal direction has been
overridden.</bdo></p>
<p><code>em</code> is used for <em>emphasis</em> and usually renders as italics, contrast that with
<code>i</code> which is used for alternate voice or to offset from the normal (such as a phrase from a
different language or taxonomic designation): <i>E. coli</i> can be bad. <code>strong</code> is used for
<strong>importance or urgency</strong> and usually renders as bold, contrast that with <code>b</code> which
is used to <b>draw
attention</b> without the semantic meaning of importance.</p>
<p><code>cite</code>: In the words of <cite>Charles Bukowski</cite>
<q>An intellectual says a simple thing in a hard way. An artist says a
hard thing in a simple way.</q></p>
<p><code>data</code> can be used to specify
<data value="2018-09-24T05:00-07:00">5 A.M.</data>
that is machine-readable, but <code>time</code> is a better choice for specifying
<time datetime="2018-09-24T05:00-07:00">5 A.M.</time>
in a machine-readable
format.
</p>
<p><code>del</code> can be
<del datetime="2017-10-11T01:25-07:00">varily</del>
used to mark deletions. <code>ins</code> marks
<ins datetime="2007-12-19 00:00Z">insertions</ins>
. <code>s</code>: similar to <code>del</code>, but used to mark content that
is no longer relevant. <s>Windows XP version available.</s> <code>u</code>: a holdover with no real meaning
that should be <u>removed</u>. <code>mark</code>: the HTML equivalent of the
<mark>yellow highlighter</mark>
. <code>span</code>: a <span>generic element</span> with no meaning by itself.
</p>
<p><code>dfn</code>: Foreign phrases add a certain <dfn lang="fr" title="French: indefinable quality">je ne sais
quoi</dfn> to one's prose.
</p>
<p><code>q</code>: The W3C page <cite>About W3C</cite> says the W3Cs mission is <q
cite="https://www.w3.org/Consortium/">To lead the World
Wide Web to its full potential by developing protocols and
guidelines that ensure long-term growth for the Web</q>.</p>
<p><code>kbd</code> and <code>samp</code>: I did this:</p>
<pre><samp>c:\&gt;<kbd>format c: /yes</kbd></samp></pre>
<p>Is that bad? Press <kbd><kbd>Ctrl</kbd></kbd>+<kbd><kbd>F5</kbd></kbd>
for a hard reload.</p>
<p><code>var</code>: To log in, type <kbd>ssh <var>user</var>@example.com</kbd>, where <var>user</var> is your
user ID.</p>
<p><code>meter</code> and <code>progress</code>: Storage space usage:
<meter value=6 max=8>6 blocks used (out of 8 total)</meter>
Progress:
<progress value="37" max=100>37%</progress>
</p>
<p><code>sub</code> is used for subscripts: H<sub>2</sub>O. <code>sup</code> is used for superscripts: E =
MC<sup>2</sup>. <code>small</code> is used for side comments: <q>I wrote this whole document. <small>[Editor's
note: no he did not]</small></q> <code>wbr</code>: used to specify where a word may break and it is
super
<wbr>
cali
<wbr>
fragil
<wbr>
istic
<wbr>
expiali
<wbr>
do
<wbr>
cious.
</p>
<footer>
<p>See the <a target="_blank" href="https://www.w3.org/TR/html5/dom.html#phrasing-content">Phrasing
Content spec.</a></p>
</footer>
</section>
<hr>
<section id="palpable">
<header>
<h3><a href="#palpable">#</a> Palpable Content</h3>
<p>Elements <code>a</code>, <code>address</code>, <code>blockquote</code>,
<code>button</code>, <code>details</code>, <code>dl</code>, <code>fieldset</code>,
<code>figure</code>, <code>form</code>, <code>input</code>, <code>label</code>,
<code>map</code>, <code>ol</code>, <code>output</code>, <code>pre</code>,
<code>select</code>, <code>table</code>, <code>textarea</code>,
<code>ul</code>, and others make up the <em>palpable content</em> category.
</p>
</header>
<p><code>a</code>: <a href="http://example.com">Example</a>.</p>
<p><code>address</code>:</p>
<address>1 Infinite Loop<br>
Cupertino, CA 95014<br>
United States
</address>
<p><code>blockquote</code>:</p>
<blockquote>
<p>I quickly explained that many big jobs involve few hazards</p>
</blockquote>
<blockquote>
<p>This is a mult-line blockquote with a cite reference. People think focus means saying yes to the thing
youve got to focus on. But thats not what it means at all. It means saying no to the hundred other
good ideas that there are. You have to pick
carefully. Im actually as proud of the things we haventdone as the things I have done. Innovation is
saying no to 1,000 things.</p>
<footer>Steve Jobs, <cite>Apple Worldwide Developers Conference,
1997</cite></footer>
</blockquote>
<p><code>details</code> and <code>summary</code>:</p>
<details>
<summary>Copying...
<progress max="375505392" value="97543282"></progress>
25%
</summary>
<dl>
<dt>Transfer rate:</dt>
<dd>452KB/s</dd>
<dt>Duration:</dt>
<dd>01:16:27</dd>
<dt>Color profile:</dt>
<dd>SD (6-1-6)</dd>
<dt>Dimensions:</dt>
<dd>320×240</dd>
</dl>
</details>
<p><code>dl</code>:</p>
<dl>
<dt>Definition List Title</dt>
<dd>Definition list division.</dd>
<dt>Kitchen Sink</dt>
<dd>Used in expressions to describe work in which all conceivable (and some inconceivable) sources have been
mined. In this case, a bunch of markup.
</dd>
<dt>aside</dt>
<dd>Defines content aside from the page content</dd>
<dt>blockquote</dt>
<dd>Defines a section that is quoted from another source</dd>
</dl>
<p><code>figure</code>:</p>
<figure>
<img src="https://www.fillmurray.com/402/295">
<figcaption>Figure 1: A picture of Bill Murray from <a href="https://www.fillmurray.com/">fillmurray.com</a>
</figcaption>
</figure>
<br><br>
<h4 id="forms"><a href="#forms">#</a> Forms</h4>
<hr>
<form>
<p>
<label for="example-input-email">Email address</label>
<input type="email" id="example-input-email">
</p>
<p>
<label for="example-input-number">Number</label>
<input type="number" id="example-input-number">
</p>
<p>
<label for="example-input-password">Password</label>
<input type="password" id="example-input-password">
</p>
<p>
<label for="example-input-search">Search</label>
<input type="search" id="example-input-search">
</p>
<p>
<label for="example-input-tel">Telephone number</label>
<input type="tel" id="example-input-tel">
</p>
<p>
<label for="example-input-text">Text</label>
<input type="text" id="example-input-text">
</p>
<p>
<label for="example-input-readonly">Read-only</label>
<input type="text" readonly value="Can't touch this!">
</p>
<p>
<label for="example-input-disabled">Disabled</label>
<input type="text" disabled value="Not available">
</p>
<p>
<label for="example-input-url">URL</label>
<input type="url" id="example-input-url">
</p>
<p>
<label for="example-input-color">Color</label>
<input type="color" id="example-input-color">
</p>
<p>
<label for="example-input-date">Date</label>
<input type="date" id="example-input-date">
</p>
<p>
<label for="example-input-date-time">Date / Time</label>
<input type="datetime" id="example-input-date-time">
</p>
<p>
<label for="example-input-date-time-local">Date / Time local</label>
<input type="datetime-local" id="example-input-date-time-local">
</p>
<p>
<label for="example-input-month">Month</label>
<input type="month" id="example-input-month">
</p>
<p>
<label for="example-input-week">Week</label>
<input type="week" id="example-input-week">
</p>
<p>
<label for="example-input-time">Time</label>
<input type="time" id="example-input-time">
</p>
<p>
<label for="example-input-file">File input</label>
<input type="file" id="example-input-file">
</p>
<p>
<label for="example-input-range">Range input</label>
<input type="range" id="example-input-range" min="1" max="4" value="3">
</p>
<p>
<label for="example-select1">Select</label>
<select id="example-select1">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</p>
<p>
<label for="example-select1a">Select with size</label>
<select id="example-select1a" size="2">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</p>
<p>
<label for="example-select2">Multiple select</label>
<select multiple id="example-select2">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</p>
<p>
<label for="example-optgroup">Select with optgroup: Favorite Car</label>
<select id="example-optgroup">
<optgroup label="Swedish Cars">
<option>Volvo</option>
<option>Saab</option>
</optgroup>
<optgroup label="German Cars">
<option>Mercedes</option>
<option>Audi</option>
</optgroup>
</select>
</p>
<p>
<label for="example-optgroup2">Select with optgroup and size:
Favorite Dish</label>
<select id="example-optgroup2" size="2">
<optgroup label="Vegetarian">
<option>Green Salad</option>
<option>French Fries</option>
</optgroup>
<optgroup label="Carnivorous">
<option>Big Mac</option>
<option>Roast Beef</option>
</optgroup>
</select>
</p>
<p>
<label for="example-optgroup3">Multiple select with optgroup: Public
transport</label>
<select id="example-optgroup3" multiple>
<optgroup label="Ground">
<option>Train</option>
<option>Bus</option>
</optgroup>
<optgroup label="Water">
<option>Ship</option>
<option>Submarine</option>
</optgroup>
<optgroup label="Air">
<option>Plane</option>
<option>Balloon</option>
</optgroup>
</select>
</p>
<p>
<label for="example-textarea">Textarea</label>
<textarea id="example-textarea" rows="3"></textarea>
</p>
<fieldset>
<legend>I am legend</legend>
<div>
<input type="radio" name="option-radio" id="option-radio1" value="option1" checked>
<label for="option-radio1">Option one is this and that&mdash;be
sure to include why it's great</label>
</div>
<div>
<input type="radio" name="option-radio" id="option-radio2" value="option2">
<label>Option two can be something else and selecting it will
deselect option one</label>
</div>
<div>
<input type="radio" name="option-radio" id="option-radio3" value="option3" disabled>
<label>Option three is disabled</label>
</div>
</fieldset>
<fieldset>
<legend>I am also legend</legend>
<input type="checkbox" id="checkbox1">
<label for="checkbox1">Check me out</label>
<input type="checkbox" id="checkbox2">
<label for="checkbox2">and/or check me out</label>
</fieldset>
<p>
<button type="button" name="button">Button</button>
<input type="button" name="input" value="Input Button">
<input type="submit" name="submit" value="Input Submit">
<button type="submit" name="submit2">Submit</button>
<input type="reset" name="reset" value="Input Reset">
<button type="reset" name="reset2">Reset</button>
<button disabled>Cancel</button>
</p>
</form>
<p><code>ul</code> and <code>ol</code>:</p>
<ul>
<li>Unordered List item one
<ul>
<li>Nested list item
<ul>
<li>Level 3, item one</li>
<li>Level 3, item two</li>
<li>Level 3, item three</li>
<li>Level 3, item four</li>
</ul>
</li>
<li>List item two</li>
<li>List item three</li>
<li>List item four</li>
</ul>
</li>
<li>List item two</li>
<li>List item three</li>
<li>List item four</li>
</ul>
<ol>
<li>List item one
<ol>
<li>List item one
<ol>
<li>List item one</li>
<li>List item two</li>
<li>List item three</li>
<li>List item four</li>
</ol>
</li>
<li>List item two</li>
<li>List item three</li>
<li>List item four</li>
</ol>
</li>
<li>List item two</li>
<li>List item three</li>
<li>List item four</li>
</ol>
<p><code>output</code>:</p>
<form onsubmit="return false" oninput="o.value= a.valueAsNumber +
b.valueAsNumber">
<input name=a type=number step=any> +
<input name=b type=number step=any> =
<output name=o for="a b"></output>
</form>
<p><code>pre</code>:</p>
<pre>
pre {
display: block;
padding: 7px;
background-color: #F5F5F5;
border: 1px solid #E1E1E8;
border-radius: 3px;
white-space: pre-wrap;
word-break: break-all;
font-family: Menlo, Monaco;
line-height: 160%;
}</pre>
<pre><samp>You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.
></samp> <kbd>open mailbox</kbd>
<samp>Opening the mailbox reveals:
A leaflet.
></samp></pre>
<br><br>
<h4 id="tables"><a href="#tables">#</a> Tables</h4>
<hr>
<table>
<caption>Tables can have captions now.</caption>
<tbody>
<tr>
<th>Person</th>
<th>Number</th>
<th>Third Column</th>
</tr>
<tr>
<td>Someone Lastname</td>
<td>900</td>
<td>Nullam quis risus eget urna mollis ornare vel eu leo.</td>
</tr>
<tr>
<td><a href="#">Person Name</a></td>
<td>1200</td>
<td>Vestibulum id ligula porta felis euismod semper. Donec ullamcorper nulla non metus auctor
fringilla.
</td>
</tr>
<tr>
<td>Another Person</td>
<td>1500</td>
<td>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nullam id dolor id nibh
ultricies vehicula ut id elit.
</td>
</tr>
<tr>
<td>Last One</td>
<td>2800</td>
<td>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet
fermentum.
</td>
</tr>
</tbody>
</table>
<p id="table-summary">In the following table, characteristics are given in the second column, with the negative
side in the left column and the positive side in the right column.</p>
<table aria-describedby="table-summary">
<caption>Characteristics with positive and negative sides</caption>
<thead>
<tr>
<th id="n">Negative</th>
<th>Characteristic</th>
<th id="p">Positive</th>
</tr>
</thead>
<tbody>
<tr>
<td headers="n r1">Sad</td>
<th id="r1">Mood</th>
<td headers="p r1">Happy</td>
</tr>
<tr>
<td headers="n r2">Failing</td>
<th id="r2">Grade</th>
<td headers="p r2">Passing</td>
</tr>
</tbody>
</table>
<table>
<caption>Complex table with a <code>thead</code>, multiple <code>tbody</code> elements, and a
<code>tfoot</code>.
</caption>
<thead>
<tr>
<th></th>
<th>2008</th>
<th>2007</th>
<th>2006</th>
</tr>
</thead>
<tbody>
<tr>
<th>Net sales</th>
<td>$32,479</td>
<td>$24,006</td>
<td>$19,315</td>
</tr>
<tr>
<th>Cost of sales</th>
<td>21,334</td>
<td>15,852</td>
<td>13,717</td>
</tr>
</tbody>
<tbody>
<tr>
<th>Gross margin</th>
<td>$11,145</td>
<td>$8,154</td>
<td>$5,598</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Gross margin percentage</th>
<td>34.3%</td>
<td>34.0%</td>
<td>29.0%</td>
</tr>
</tfoot>
</table>
<footer>
<p>See the <a target="_blank" href="https://www.w3.org/TR/html5/dom.html#palpable-content">Palpable
Content spec.</a></p>
</footer>
</section>
<hr>
<section id="embeds">
<header>
<h3><a href="#embeds">#</a> Embeds</h3>
<p>Elements <code>audio</code>, <code>canvas</code>, <code>embed</code>,
<code>iframe</code>, <code>img</code>, <code>math</code>, <code>object</code>,
<code>picture</code>, <code>svg</code>, <code>video</code> make up the <em>embedded content</em>
category.</p>
</header>
<p><code>audio</code>:
<audio controls src="https://upload.wikimedia.org/wikipedia/commons/c/c7/What_hath_God_wrought.ogg"></audio>
By Cqdx [<a href="https://creativecommons.org/licenses/by-sa/3.0">CC
BY-SA 3.0 </a>], <a href="https://commons.wikimedia.org/wiki/File:What_hath_God_wrought.ogg">from
Wikimedia Commons</a>.
</p>
<p><code>embed</code>:
<embed src="http://www.bannerblog.com.au/banners2009/mini-options-300x250-hq-en.swf" width="120" height="50"
type='application/pdf'>
</p>
<p><code>iframe</code>:
<iframe sandbox srcdoc="<h1>Sample Document</h1><p>This
is a sample content.</p>"></iframe>
</p>
<p><code>img</code>: <img src="https://www.fillmurray.com/150/150" alt="Bill Murray"></p>
<p><code>math</code>:</p>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mtable>
<mtr>
<mtd>
<mtext>Quadratic Equation</mtext>
</mtd>
<mtd>
<mrow>
<mi>x</mi>
<mo>=</mo>
<mfrac>
<mrow>
<mo>-</mo>
<mi>b</mi>
<mo>&#x00B1;</mo>
<msqrt>
<mrow>
<msubsup>
<mi>b</mi>
<mrow></mrow>
<mn>2</mn>
</msubsup>
<mo>-</mo>
<mn>4</mn>
<mi>a</mi>
<mi>c</mi>
</mrow>
</msqrt>
</mrow>
<mrow>
<mn>2</mn>
<mi>a</mi>
</mrow>
</mfrac>
</mrow>
</mtd>
</mtr>
</mtable>
</math>
<p><code>picture</code>:
<picture>
<source srcset="https://www.fillmurray.com/240/300 2x,
https://www.fillmurray.com/120/150 1x">
<img src="https://www.fillmurray.com/120/150" alt="Bill Murray">
</picture>
</p>
<p><code>svg</code>:
<svg role="presentation" width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M19.199 24C19.199 13.467
10.533 4.8 0 4.8V0c13.165 0 24 10.835 24 24h-4.801zM3.291
17.415c1.814 0 3.293 1.479 3.293 3.295 0 1.813-1.485 3.29-3.301
3.29C1.47 24 0 22.526 0 20.71s1.475-3.294 3.291-3.295zM15.909
24h-4.665c0-6.169-5.075-11.245-11.244-11.245V8.09c8.727 0 15.909
7.184 15.909 15.91z"/>
</svg>
</p>
<p><code>video</code>:
<video controls
src="https://upload.wikimedia.org/wikipedia/commons/b/b8/Dwarf_hamsters_running_on_disc_2.ogv"></video>
</p>
<footer>
<p>See the <a target="_blank" href="https://www.w3.org/TR/html5/dom.html#embedded-content">Embedded
Content spec.</a></p>
</footer>
</section>
<hr>
</main>
<footer role="contentinfo">
<p>Find this document on <a href="https://github.com/dbox/html5-kitchen-sink">GitHub</a>.</p>
</footer>
<!-- end kitchen sink -->
</body>
</html>

View File

@ -0,0 +1,117 @@
<!DOCTYPE html>
<html lang="en">
<!--#include virtual="head.html" -->
<body class="overflow-auto flex-column scrolled">
<!--#include virtual="header.html" -->
<main class="container">
<div>
<div class="vh-50 row border slim">
<div class="sz-6 column">
<div class="bg-primary">primary</div>
<div class="bg-secondary flex-grow">secondary</div>
<div class="bg-tertiary">tertiary</div>
</div>
<div class="sz-6 column">
<div class="sz-4 bg-primary">primary</div>
<div class="sz-2 bg-secondary">secondary</div>
<div class="sz-6 bg-tertiary">tertiary</div>
</div>
</div>
</div>
<div>
<h2 class="">row-6 g-0</h2>
<div class="row-6 g-0 border">
<div class="sz-1 bg-primary text-center">1 / 6</div>
<div class="sz-5 bg-secondary text-center">5 / 6</div>
<div class="sz-2 bg-primary text-center">2 / 6</div>
<div class="sz-4 bg-secondary text-center">4 / 6</div>
<div class="sz-3 bg-primary text-center">3 / 6</div>
<div class="sz-3 bg-secondary text-center">3 / 6</div>
</div>
</div>
<div>
<h2 class="">row-6 g-1</h2>
<div class="row-6 g-1 border">
<div class="sz-1 bg-primary text-center">1 / 6</div>
<div class="sz-5 bg-secondary text-center">5 / 6</div>
<div class="sz-2 bg-primary text-center">2 / 6</div>
<div class="sz-4 bg-secondary text-center">4 / 6</div>
<div class="sz-3 bg-primary text-center">3 / 6</div>
<div class="sz-3 bg-secondary text-center">3 / 6</div>
</div>
</div>
<div>
<h2 class="">row-6 g-2</h2>
<div class="row-6 g-2 border mr-0">
<div class="sz-1 bg-primary text-center">1 / 6</div>
<div class="sz-5 bg-secondary text-center">5 / 6</div>
<div class="sz-2 bg-primary text-center">2 / 6</div>
<div class="sz-4 bg-secondary text-center">4 / 6</div>
<div class="sz-3 bg-primary text-center">3 / 6</div>
<div class="sz-3 bg-secondary text-center">3 / 6</div>
</div>
</div>
<div>
<h2 class="">row-35</h2>
<div class="row-35 border">
<div class="sz-7 bg-primary text-center m-0">7 / 35</div>
<div class="sz-28 bg-secondary text-center m-0">28 / 35</div>
<div class="sz-14 bg-primary text-center m-0">14 / 35</div>
<div class="sz-21 bg-secondary text-center m-0">21 / 35</div>
</div>
</div>
<div>
<h2>Some cards...</h2>
<div class="row-6">
<div class="card sz-6 sz-sm-3 sz-md-2 sz-lg-1">
<img class="card-img-top" src="https://picsum.photos/200">
<div class="card-overlay">
<h2 class="text-primary">Special!</h2>
</div>
<div class="card-text">
Some descriptive text to tell you about what is shown here.
</div>
</div>
<div class="card sz-6 sz-sm-3 sz-md-2 sz-lg-1">
<img class="card-img-top" src="https://picsum.photos/200?1">
<div class="card-overlay">
<h2 class="text-secondary">Special!</h2>
</div>
<div class="card-text small">
Some descriptive text to tell you about what is shown here.
</div>
</div>
<div class="card sz-6 sz-sm-3 sz-md-2 sz-lg-1">
<img class="card-img-top" src="https://picsum.photos/200?2">
<div class="card-text small">Some small descriptive text</div>
<ul>
<li>First Item</li>
<li>Second Item</li>
<li class="text-right">Third Item</li>
<li>Fourth Item</li>
</ul>
<div class="card-overlay">
<h2 class="text-secondary">Extraspecial</h2>
</div>
<div class="card-text large">
Some descriptive text to tell you about what is shown here.
</div>
</div>
</div>
</div>
<div>
<h1>Some buttons</h1>
<p>
<button onclick="LNS('#modal1').removeClass('hidden');">Show #modal1</button>
</p>
</div>
</main>
<!--#include virtual="footer.html" -->
<div id="modal1" class="modal hidden">
<div class="container">
<h1>I am modal</h1>
<button onclick="LNS('#modal1').addClass('hidden');">Schliessen</button>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Motor Control Demo</title>
<link rel="stylesheet" href="css/lnstyles.css">
<link rel="stylesheet" href="css/unused/motorcontrol.css">
<script type="application/javascript" src="js/lnstyles.mjs"></script>
<script type="application/javascript" src="motorcontrol.mjs"></script>
</head>
<body>
<div class="container">
<h1>MotorControl Demo Page</h1>
<div class="row-6">
<div class="col-2" id="motor1"></div>
<div class="col-2" id="motor2"></div>
<div id="motor3"></div>
<div id="motor4"></div>
</div>
<div id="log" class="">
</div>
</div>
<script>
let controls = LNS("#motor1")
.concat("#motor2")
.concat("#motor3")
.concat("#motor4");
controls.motorcontrol({
nominalVelocity: 6000,
});
let c1 = controls.get(0).$motorcontrol;
c1.addEventListener("action", (evt)=>{
console.log(evt);
});
c1.addEventListener("targetchange", (evt)=>{
console.log(evt);
});
</script>
</body>
</html>

View File

@ -0,0 +1,677 @@
(function() {
class MCMouseEvent extends Event{
constructor(mc, evt){
super(evt.type);
this.event = evt;
this.motorControl = mc;
this.button = evt.button;
this.x = evt.offsetX - mc._hints.phy_center_x;
this.y = evt.offsetY - mc._hints.phy_center_y;
if (this.x != 0){
this.a = Math.atan(this.y/this.x);
if (this.x > 0)
this.a += (Math.PI * 0.5);
else
this.a += (Math.PI * 1.5);
} else if (this.y < 0) {
this.a = 0;
} else {
this.a = Math.PI;
}
this.r = Math.sqrt((this.x*this.x) + (this.y*this.y));
this.targetValues = {
torque: ((this.a - (Math.PI * 1.5)) / (Math.PI * 0.2)).clamp(-1.0, 1.0),
velocity: ((this.a - (Math.PI * 0.5)) / (Math.PI * 0.2)).clamp(-1.0, 1.0),
position: this.a / (Math.PI) * 180,
};
if ((this.r <= mc._hints.r1) && (this.r >= mc._hints.r2)){
this.targetControl = "position";
this.value = this.a / (Math.PI) * 180;
} else if ((this.r <= mc._hints.r3) && (this.r >= mc._hints.r4)){
if ((this.a >= Math.PI * 1.25) && (this.a <= Math.PI * 1.75)){
this.targetControl = "torque";
this.value = ((this.a - (Math.PI * 1.5)) / (Math.PI * 0.2)).clamp(-1.0, 1.0);
} else if ((this.a >= Math.PI * 0.25) && (this.a <= Math.PI * 0.75)){
this.targetControl = "velocity";
this.value = ((this.a - (Math.PI * 0.5)) / (Math.PI * 0.2)).clamp(-1.0, 1.0);
}
}
}
}
class MCChangedEvent extends Event
{
constructor(mc, property, newValue) {
super("changed");
this.motorControl = mc;
this.propertyName = property;
this.propertyValue = newValue;
}
}
class Rect
{
constructor(x,y,w,h){
this.x = x;
this.y = y;
this.width = w;
this.height = h;
}
contains(x,y){
return (this.x <= x) && ((this.x + this.width) > x) && (this.y <= y) && ((this.y + this.height) > y);
}
}
class IndicatorClickedEvent extends Event
{
constructor(i) {
super("clicked");
this.indicator = i;
}
}
class MCActionEvent extends Event
{
constructor(mctrl, action, parameter) {
super("action");
this._mctrl = mctrl;
this._action = action;
this._parameter = parameter;
}
get mctrl(){ return this._mctrl; }
get action(){ return this._action; }
get parameter(){ return this._parameter; }
}
class MCTargetChangedEvent extends Event
{
constructor(mctrl, target, value) {
super("targetchange");
this._mctrl = mctrl;
this._target = target;
this._value = value;
}
get mctrl(){ return this._mctrl; }
get target(){ return this._target; }
get value(){ return this._value; }
}
class Indicator extends EventTarget
{
constructor(c,t,x,y,w,h,opts = {}){
super();
this._opts = Object.assign({
colorBorder: '#84d0f8',
colorDisabled: '#eaeaea',
bgDisabled: '#FCFCFC',
colorChecked: '#000000',
bgChecked: '#53e843',
colorUnchecked: '#bababa',
bgUnchecked: '#f8f8f8',
}, opts);
this._ctrl = c;
this._text = t;
this._x = x;
this._y = y;
this._width = w;
this._height = h;
this._checked = false;
this._enabled = true;
}
options(o){
this._opts = Object.assign(this._opts, o);
return this;
}
get checked(){ return this._checked; }
set checked(v){ this._checked = v; this.repaint(); }
get enabled(){ return this._enabled; }
set enabled(v){ this._enabled = v; this.repaint(); }
repaint(){
if (!this._repaint)
this._repaint = setTimeout(()=>this.paint(this._ctrl.__ctx), 0);
}
get border(){
let x = (this._x - (this._width/2)) * this._ctrl._hints.lineHeight;
let y = (this._y - (this._height/2)) * this._ctrl._hints.lineHeight;
let w = this._width * this._ctrl._hints.lineHeight;
let h = this._height * this._ctrl._hints.lineHeight;
return new Rect( x, y, w, h );
}
paint(ctx){
if (!ctx)
return;
this._repaint = null;
ctx.reset();
ctx.rotate( Math.PI * 0.5 );
let x = (this._x - (this._width/2)) * this._ctrl._hints.lineHeight;
let y = (this._y - (this._height/2)) * this._ctrl._hints.lineHeight;
let w = this._width * this._ctrl._hints.lineHeight;
let h = this._height * this._ctrl._hints.lineHeight;
ctx.font = this._ctrl._hints.font;
let mt = ctx.measureText(this._text);
ctx.strokeStyle = this._enabled ? this._opts.colorBorder : this._opts.colorDisabled;
ctx.fillStyle = (!this._enabled) ? this._opts.bgDisabled : this._checked ? this._opts.bgChecked : this._opts.bgUnchecked;
ctx.beginPath();
ctx.rect( x, y, w, h);
ctx.stroke();
ctx.fill();
x = (this._x * this._ctrl._hints.lineHeight); // - (mt.width/2);
y = (this._y * this._ctrl._hints.lineHeight); // + (fontHeight/2);
ctx.fillStyle = (!this._enabled) ? this._opts.colorDisabled : this._checked ? this._opts.colorChecked : this._opts.colorUnchecked;
ctx.fillText(this._text, x, y);
}
fireClicked(evt){
this.dispatchEvent(evt);
}
}
class MotorControl extends EventTarget {
constructor(el, options = {}) {
super();
this._validModes = ['torque','velocity','position'];
this._opts = Object.assign({
padding: 0.03,
gaugeWidth: 0.2,
autoUpdate: true,
colors: {
background: '#fafdff',
border: '#84d0f8',
markActual: '#64b0e0',
markTarget: '#000000',
markInactive: '#cacaca',
handle: '#000000',
},
}, options);
this._values = {
current: {
position: 0.0,
velocity: 0.0,
torque: 0.0,
},
targets: {
position: 0.0,
velocity: 0.0,
torque: 0,
}
}
this._mode = 'torque';
this._indicators = [];
this._e = LNS(el);
this._e.addClass("lns-motorcontrol");
this._c = LNS("<canvas></canvas>")
.appendTo(this._e)
.get(0);
this._c.addEventListener("mousedown", (e)=>this.mouseDown(new MCMouseEvent(this, e)));
this._c.addEventListener("mouseup", (e)=>this.mouseUp(new MCMouseEvent(this, e)));
this._c.addEventListener("mousemove", (e)=>this.mouseMoved(new MCMouseEvent(this, e)));
this._c.addEventListener("click", (e)=>this.mouseClicked(new MCMouseEvent(this, e)));
this.btn_enable = new Indicator(this, "E", -0.5,-3, 1, 1);
this.btn_enable.addEventListener("click", (evt)=>this.fireAction("enable", !this.btn_enable.checked));
this.btn_failure = new Indicator(this, "F", 0.5,-3, 1, 1)
.options({ bgChecked: 'red', colorChecked: 'white' });
this.btn_failure.addEventListener("click", (evt)=>this.fireAction("failure", !this.btn_failure.checked));
this.btn_torque = new Indicator(this, "T", -1,3, 1, 1);
this.btn_torque.addEventListener("click", (evt)=>this.fireAction("mode","torque"));
this.btn_velocity =new Indicator(this, "V", 0,3, 1, 1);
this.btn_velocity.addEventListener("click", (evt)=>this.fireAction("mode","velocity"));
this.btn_position =new Indicator(this, "P", 1,3, 1, 1);
this.btn_position.addEventListener("click", (evt)=>this.fireAction("mode","position"));
this.addIndicator(this.btn_enable);
this.addIndicator(this.btn_failure);
this.addIndicator(this.btn_torque);
this.addIndicator(this.btn_velocity);
this.addIndicator(this.btn_position);
this.repaint();
}
get enabled(){ return this.btn_enable.checked; }
set enabled(v){ this.btn_enable.checked = v ? true : false; }
get failed(){ return this.btn_failure.checked; }
set failed(v){ this.btn_failure.checked = v ? true : false; }
setTargetValue(target, value){
if (this._validModes.includes(target)){
this._values.targets[target] = value;
this.repaint();
} else
throw "unsupported target: " + target;
return this;
}
setActualValues(values){
Object.assign(this._values.current, values);
this.repaint();
return this;
}
setTargetValues(values){
Object.assign(this._values.targets, values);
this.repaint();
return this;
}
getTargetValues(){
return Object.assign({}, this._values.targets);
}
getActualValues(){
return Object.assign({}, this._values.current);
}
calculateHints(){
this._hints = {
phy_width: this._c.clientWidth,
phy_height: this._c.clientHeight,
phy_center_x: this._c.clientWidth / 2,
phy_center_y: this._c.clientHeight / 2
};
let mxy = Math.min( this._hints.phy_width, this._hints.phy_height );
this._hints.disp_width = this._hints.disp_height = mxy;
this._hints.radius_display = this._hints.disp_width/2;
this._hints.r1 = (this._hints.radius_display * (1-this._opts.padding));
this._hints.r2 = (this._hints.radius_display * (1-this._opts.padding-this._opts.gaugeWidth));
this._hints.r3 = (this._hints.radius_display * (1-(3*this._opts.padding)-this._opts.gaugeWidth));
this._hints.r4 = (this._hints.radius_display * (1-(3*this._opts.padding)-(2*this._opts.gaugeWidth)));
this._c.width = this._hints.phy_width;
this._c.height = this._hints.phy_height;
this._hints.fontHeight = this._hints.disp_height / 18;
this._hints.lineHeight = 1.5 * this._hints.fontHeight;
this._hints.font = `${this._hints.fontHeight}px "Sans"`;
}
getPreparedContext(){
this.calculateHints();
if (this.__ctx)
return this.__ctx;
this.__ctx = this._c.getContext("2d");
this.__ctx.translate(
this._hints.phy_center_x,
this._hints.phy_center_y
);
this.__ctx.rotate( Math.PI * -0.5 );
this.__ctx.__reset = this.__ctx.getTransform();
this.__ctx.__transformStack = [];
this.__ctx.reset = ()=>{ this.__ctx.__transformStack = []; this.__ctx.setTransform(this.__ctx.__reset); };
this.__ctx.hookMethod("rotate", ()=>{
this.__ctx.__transformStack.push(this.__ctx.getTransform());
});
this.__ctx.hookMethod("translate", ()=>{
this.__ctx.__transformStack.push(this.__ctx.getTransform());
});
this.__ctx.pop = ()=>{
if (this.__ctx.__transformStack.length > 0){
this.__ctx.setTransform(this.__ctx.__transformStack.pop());
}
}
this.__ctx.reset();
return this.__ctx;
}
repaint(){
if (!this._repaint)
this._repaint = setTimeout(()=>this.paint(), 0);
}
paint(){
this._repaint = null;
let ctx = this.getPreparedContext();
ctx.reset();
ctx.fillStyle = this._opts.colors.background;
ctx.beginPath();
ctx.arc(0, 0, this._hints.r1, 0, 2 * Math.PI);
ctx.fill();
this.paintPositionControl(
ctx,
this._values.current.position,
this._values.targets.position
);
this.paintVelocityControl(
ctx,
this._values.current.velocity,
this._values.targets.velocity
);
this.paintTorqueControl(
ctx,
this._values.current.torque,
this._values.targets.torque
);
this.paintActuals(ctx);
this._indicators.forEach((v,i)=>{
v.paint(ctx);
});
}
paintPositionControl(ctx, actualPosition, targetPosition){
ctx.reset();
let len = (this._hints.r1-this._hints.r2)*0.5;
ctx.strokeStyle = this._opts.colors.border;
ctx.beginPath();
ctx.arc(0, 0, this._hints.r1, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, this._hints.r2 , 0, 2 * Math.PI);
ctx.stroke();
this.paintScale( ctx,
0,
Math.PI * 2,
(this._hints.r1+this._hints.r2)*0.5,
(this._hints.r1-this._hints.r2)*0.5,
72,
false,
3);
ctx.fillStyle = this._mode == "position" ? this._opts.colors.markTarget : this._opts.colors.markInactive;
this.paintMarker(ctx, this._hints.r1, -len, Math.PI * (targetPosition / 180));
ctx.fillStyle = this._opts.colors.markActual;
this.paintMarker(ctx, this._hints.r2, len, Math.PI * (actualPosition / 180));
}
paintVelocityControl(ctx, currentValue, targetValue){
this.paintVelocityTorqueControl(ctx, Math.PI * 0.5, currentValue, targetValue, this._mode == "velocity");
}
paintTorqueControl(ctx, currentValue, targetValue){
this.paintVelocityTorqueControl(ctx, Math.PI * -0.5, currentValue, targetValue, this._mode == "torque");
}
paintVelocityTorqueControl(ctx, offsetAngle, currentValue, targetValue, active = false){
currentValue = currentValue.clamp(-1.2, 1.2);
targetValue = targetValue.clamp(-1.2, 1.2);
let astart = (Math.PI * -0.25 );
let aend = (Math.PI * 0.25 );
let len = (this._hints.r3-this._hints.r4)*0.5;
let aone = ((aend - astart) * 0.4);
let acurrent =(aone * currentValue);
let atarget = (aone * targetValue);
ctx.reset();
ctx.rotate(offsetAngle);
ctx.strokeStyle = this._opts.colors.border;
ctx.beginPath();
ctx.arc(0, 0, this._hints.r3, astart, aend);
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, this._hints.r4, astart, aend);
ctx.stroke();
ctx.rotate( astart );
ctx.beginPath();
ctx.moveTo( this._hints.r3, 0);
ctx.lineTo( this._hints.r4, 0);
ctx.stroke();
ctx.pop();
ctx.rotate( aend );
ctx.beginPath();
ctx.moveTo( this._hints.r3, 0);
ctx.lineTo( this._hints.r4, 0);
ctx.stroke();
ctx.pop();
this.paintScale( ctx,
astart,
aend,
(this._hints.r3+this._hints.r4)*0.5,
(this._hints.r3-this._hints.r4)*0.5,
10,
true,
2,
1);
ctx.fillStyle = active ? this._opts.colors.markTarget : this._opts.colors.markInactive;
this.paintMarker(ctx, this._hints.r3, -len, atarget);
ctx.fillStyle = this._opts.colors.markActual;
this.paintMarker(ctx, this._hints.r4, len, acurrent);
}
paintMarker(ctx, radius, height, angle){
ctx.rotate( angle );
ctx.beginPath();
ctx.moveTo(radius, -height);
ctx.lineTo(radius, height);
ctx.lineTo( radius + height, 0);
ctx.moveTo(radius, -height);
ctx.fill();
ctx.pop();
}
paintScale(ctx, astart, aend, radius, width, steps, excludeOuters = true, mainCnt = 3, shiftMains = 0 ){
let acurrent = astart;
let aincrement = (aend - astart) / steps;
for (let step = 0; step <= steps; step++)
{
if (!excludeOuters || ((step!=0)&&(step!=steps))) {
let w = ((step + shiftMains) % mainCnt) ? (width / 4) : (width / 2);
ctx.rotate(acurrent);
ctx.beginPath();
ctx.moveTo(radius - w, 0);
ctx.lineTo(radius + w, 0);
ctx.stroke();
ctx.pop();
}
acurrent += aincrement;
}
}
paintActuals(ctx){
ctx.reset();
ctx.rotate(Math.PI * 0.5);
ctx.font = this._hints.font;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
let sp = `${Math.round(this._values.current.position)}°`;
let sv,st;
if (this._opts.nominalVelocity)
sv = `${Math.round(this._values.current.velocity * this._opts.nominalVelocity)}/min`;
else
sv = `${Math.round(this._values.current.velocity * 100)}%`;
if (this._opts.nominalTorque)
st = `${Math.round(10 * this._values.current.torque * this._opts.nominalTorque)/10}Nm`;
else
st = `${Math.round(this._values.current.torque * 1000)/10}%`;
let mp = ctx.measureText(sp);
let mv = ctx.measureText(sv);
let mt = ctx.measureText(st);
ctx.beginPath();
ctx.rect( -this._hints.radius_display / 3, this._hints.lineHeight * -1.5, this._hints.disp_width / 3, this._hints.lineHeight);
ctx.rect( -this._hints.radius_display / 3, this._hints.lineHeight * -0.5, this._hints.disp_width / 3, this._hints.lineHeight);
ctx.rect( -this._hints.radius_display / 3, this._hints.lineHeight * 0.5, this._hints.disp_width / 3, this._hints.lineHeight);
ctx.stroke();
ctx.fillText(sp, 0, -this._hints.lineHeight);
ctx.fillText(sv, 0 , 0);
ctx.fillText(st, 0, this._hints.lineHeight);
}
mouseMoved(mouseEvent){
this.mouseUpdated(mouseEvent);
return false;
}
mouseClicked(mouseEvent) {
mouseEvent.event.preventDefault();
this._indicators.forEach((v)=>{
if (v.enabled && v.border.contains(mouseEvent.x, mouseEvent.y)){
v.fireClicked(mouseEvent);
}
});
return false;
}
mouseDown(mouseEvent){
switch (mouseEvent.button){
case 0:
if (mouseEvent.targetControl) {
this._pointerLockTargetControl = mouseEvent.targetControl;
this.fireTargetChanged(mouseEvent.targetControl, mouseEvent.value);
}
break;
case 1:
this.fireTargetChanged(mouseEvent.targetControl, 0);
}
mouseEvent.event.preventDefault();
return false;
}
mouseUp(mouseEvent){
this.mouseUpdated(mouseEvent);
this._pointerLockTargetControl = null;
mouseEvent.event.preventDefault();
return false;
}
mouseUpdated(mouseEvent){
let targetControl = this._pointerLockTargetControl;
if (targetControl) //&& (mouseEvent.targetControl == this.mode))
this.fireTargetChanged(targetControl, mouseEvent.targetValues[targetControl]);
}
fireTargetChanged(target, value){
if (!this._validModes.includes(target))
throw "unsupported mode: " + target;
if (this._opts.autoUpdate){
this.setTargetValue(target, value);
}
this.dispatchEvent(new MCTargetChangedEvent(this, target, value));
this._e.dispatchEvent(new MCTargetChangedEvent(this, target, value));
}
fireAction(action, parameter){
if (this._opts.autoUpdate){
switch (action){
case 'enable':
this.enabled = parameter;
break;
case 'failure':
this.failed = parameter;
break;
case 'mode':
this.mode = parameter;
break;
}
}
this.dispatchEvent(new MCActionEvent(this, action, parameter));
this._e.dispatchEvent(new MCActionEvent(this, action, parameter));
}
get mode(){ return this._mode; }
set mode(v){
if (this._validModes.includes(v))
this._mode = v;
else
throw "tried to set unkown mode: " + v;
this.btn_torque.checked = false;
this.btn_velocity.checked = false;
this.btn_position.checked = false;
switch (this._mode){
case 'torque':
this.btn_torque.checked = true;
break;
case 'velocity':
this.btn_velocity.checked = true;
break;
case 'position':
this.btn_position.checked = true;
break;
}
this.repaint();
}
addIndicator(i){
this._indicators.push(i);
return this;
}
removeIndicator(i){
this._indicators.remove(i);
return this;
}
}
LNS.registerMethod("motorcontrol", function(opts = {}){
this.each((v) => {
if (!v.$motorcontrol)
v.$motorcontrol = new MotorControl(v, Object.assign({}, opts));
});
return this;
});
})();

View File

@ -0,0 +1,242 @@
class MechanicalMotor
{
constructor(maxVelocity, maxTorque, inertia, nominalForce = null, minForce = null){
this._maxVelo = maxVelocity;
this._maxTorque = maxTorque;
this._inertia = inertia;
this._torque = 0;
this._actual = {
position: 0,
velocity: 0,
torque: 0
}
if (nominalForce){
this._nominalForce = nominalForce;
} else {
this._nominalForce = maxTorque * 1.5;
}
if (minForce)
this._minForce = minForce;
else
this._minForce = this._maxTorque * 0.2;
this.onLoop = null;
}
enable(){
this._interval = setInterval(()=>this.loop(), 100);
return this;
}
disable(){
clearInterval(this._interval);
return this;
}
torque(v){
if (v != null) {
this._torque = v.clamp(-this._maxTorque, this._maxTorque);
return this;
}
else
return this._torque;
}
nominals(){
return {
torque: this._maxTorque,
velocity: this._maxVelo
}
}
actuals(){
return Object.assign({}, this._actual);
}
loop(){
let torque = this._torque * (1+(Math.random()-0.5)*0.1);
let f = (this._actual.velocity / this._maxVelo);
f *= f;
let force = (this._nominalForce * f) * Math.sign(this._actual.velocity);
if ((force < 0) && (force > -this._minForce))
force = -this._minForce;
if ((force > 0) && (force < this._minForce))
force = this._minForce;
this._actual.torque = torque;
let effectiveTorque = (torque - force);
let accel = effectiveTorque / this._inertia;
let s1 = Math.sign(this._actual.velocity);
this._actual.velocity += accel;
let s2 = Math.sign(this._actual.velocity);
if ((s1 != s2) && (Math.abs(torque) <= this._minForce))
this._actual.velocity = 0;
this._actual.position += (this._actual.velocity * 0.1) * Math.PI;
if (this.onLoop)
this.onLoop(Object.assign({},this._actual));
}
}
class PIController{
constructor(kp, ti, defaultTimeIncrement = null) {
this._kp = kp;
this._ki = ti ? (1 / ti) : 0;
this._timeIncrement = defaultTimeIncrement;
this._outValue = 0;
this._i = 0;
this._imin = null;
this._imax = null;
}
loop(inValue, timeIncrement){
if (!timeIncrement)
timeIncrement = this._timeIncrement;
this._i += inValue * this._ki * timeIncrement;
if (this._imin != null)
this._i = this._i.clamp(this._imin, this._imax);
return this._outValue = (this._kp * inValue) + this._i;
}
outValue(){
return this._outValue;
}
clear(){
this._i = 0;
this._outValue = 0;
}
kp(v){
if (v == null)
return this._kp;
this._kp = v;
return this;
}
ki(v){
if (v == null)
return this._ki;
this._ki = v;
return this;
}
ti(v){
if (v == null)
return this._ki ? (1/this._ki) : 0;
this._ki = v ? (1/v) : 0;
return this;
}
clampi(min,max){
this._imin = min;
this._imax = max;
return this;
}
}
class MotorController {
constructor(motor, interval){
this._motor = motor;
this._mode = 0;
this._targetTorque = 0;
this._targetVelocity = 0;
this._targetPosition = 0;
this._piPosition = new PIController(0.002,0).clampi(-2.0, 2.0);
this._piVelocity = new PIController( 0.7, 0.01).clampi(-1.1, 1.1);
this._interval = interval;
setInterval(()=>this.loop(), this._interval * 1000);
this._cnt = 0;
}
motor(){
return this._motor;
}
loop(){
this._cnt ++;
let dv = 0, dp = 0;
if (this._mode >= 2)
{
dp = this.targetPosition() - (this._motor.actuals().position);
this._piPosition.loop(dp, this._interval);
}
if (this._mode >= 1)
{
dv = this.targetVelocity() - (this._motor.actuals().velocity / this._motor.nominals().velocity);
this._piVelocity.loop(dv, this._interval);
}
this._motor.torque(this.targetTorque());
if (this._cnt % 10 == 0){
console.log("loop position", this._motor.actuals().position, this.targetPosition(), dp);
console.log("loop velocity", this._motor.actuals().velocity / this._motor.nominals().velocity, this.targetVelocity(), dv);
}
}
targetTorque(v){
if (v == null)
return this._mode >= 1 ? this._piVelocity.outValue() : this._targetTorque;
this._targetTorque = v;
return this;
}
targetVelocity(v){
if (v == null)
return this._mode >= 2 ? this._piPosition.outValue() : this._targetVelocity;
this._targetVelocity = v;
return this;
}
targetPosition(v){
if (v == null)
return this._targetPosition;
this._targetPosition = v;
return this;
}
mode(mode){
if (mode == null)
return this._mode;
mode = mode.clamp(0,2);
if (mode >= 1)
this._piVelocity.clear();
if (mode >= 2)
this._piPosition.clear();
this._mode = mode;
}
modes(mode){
if (mode == null)
return ['torque','velocity','position'];
return ['torque','velocity','position'][mode];
}
}

View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="61.207817mm"
height="61.208mm"
viewBox="0 0 61.207817 61.208"
version="1.1"
id="svg5426"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="calendar.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview5428"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.0823513"
inkscape:cx="100.57257"
inkscape:cy="117.44281"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs5423" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-37.72326,-109.82721)">
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2.18691;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect234"
width="59.020908"
height="59.021091"
x="38.816715"
y="110.92067"
ry="3.7890458" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 98.327166,123.75802 H 38.327169"
id="path5114" />
<g
id="g5209"
transform="translate(-54.17394,92.87469)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150"
width="11.192448"
height="11.19245"
x="95.704773"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-7"
width="11.192448"
height="11.19245"
x="109.83818"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-8"
width="11.192448"
height="11.19245"
x="138.105"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-4"
width="11.192448"
height="11.19245"
x="123.97158"
y="61.820564"
ry="2.5510955" />
</g>
<g
id="g5209-5"
transform="translate(-54.17394,78.699092)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-0"
width="11.192448"
height="11.19245"
x="95.704773"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-7-3"
width="11.192448"
height="11.19245"
x="109.83818"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-8-6"
width="11.192448"
height="11.19245"
x="138.105"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-4-1"
width="11.192448"
height="11.19245"
x="123.97158"
y="61.820564"
ry="2.5510955" />
</g>
<g
id="g5209-0"
transform="translate(-54.17394,65.704744)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-6"
width="11.192448"
height="11.19245"
x="95.704773"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-7-32"
width="11.192448"
height="11.19245"
x="109.83818"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-8-0"
width="11.192448"
height="11.19245"
x="138.105"
y="61.820564"
ry="2.5510955" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.807551;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect5150-4-6"
width="11.192448"
height="11.19245"
x="123.97158"
y="61.820564"
ry="2.5510955" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg10046"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="checked.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview10048"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.77058782"
inkscape:cx="-22.709936"
inkscape:cy="32.442766"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs10043" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke-width:1.32292;stroke-linecap:round;stroke-dasharray:none"
id="rect11149"
width="40"
height="40"
x="5"
y="5"
rx="4"
ry="4" />
<path
style="fill:none;stroke:#ffffff;stroke-width:4.39624;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 10.457464,25.905383 c 0,0 4.623013,17.061691 8.584743,13.153697 3.961731,-3.907995 19.658516,-27.606345 19.658516,-27.606345"
id="path10636"
sodipodi:nodetypes="czc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg35924"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="circle-minus.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview35926"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.175"
inkscape:cx="122.83465"
inkscape:cy="157.16535"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs35921" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<ellipse
style="fill:none;stroke:#74d9ff;stroke-width:1.47892;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path36460"
cx="25.000038"
cy="25"
rx="17.7465"
ry="17.746473" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:3.99959;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 10.000015,25 h 28.000248 v 0.101818"
id="path37804" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:3.9446599;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 25.027672,43 v 5.027679 h -0.551571"
id="path37804-5-5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg35924"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="circle-plus.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview35926"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.245064"
inkscape:cx="90.420584"
inkscape:cy="149.21623"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs35921" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<circle
style="fill:none;stroke:#74d9ff;stroke-width:1.47892;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path36460"
cx="25"
cy="25"
r="17.746473" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:3.99959;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 10,24.999797 h 28.000204 v 0.101818"
id="path37804" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:3.6521;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 0,24.82605 h 5.1739494 v 0.459424"
id="path37804-5" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:3.9996;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 24.999804,40 V 11.999804 h 0.101818"
id="path37804-2" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg35924"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="circle.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview35926"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.175"
inkscape:cx="102.99213"
inkscape:cy="107.71654"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs35921" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<circle
style="fill:none;stroke:#74d9ff;stroke-width:2.00006;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path36460"
cx="25"
cy="25"
r="23.999969" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg35924"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="close.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview35926"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.175"
inkscape:cx="33.228346"
inkscape:cy="107.71654"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs35921" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<circle
style="fill:none;stroke:#74d9ff;stroke-width:2.00006;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path36460"
cx="25"
cy="25"
r="23.999969" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:5.29167;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 13.978747,36.021235 C 36.021253,13.978765 36.021253,13.978765 36.021253,13.978765"
id="path236" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:5.29167;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 13.978764,13.978747 C 36.021236,36.021252 36.021236,36.021252 36.021236,36.021252"
id="path236-3" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg35924"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="dash.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview35926"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.175"
inkscape:cx="87.559055"
inkscape:cy="100.47244"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs35921" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#74d9ff;stroke-width:4.00041;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 0,25.000203 h 47.999797 v 0.05942"
id="path37804" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="delete.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.0823513"
inkscape:cx="90.515316"
inkscape:cy="96.355014"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:5.29166667;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 13.97875,36.021225 C 36.021256,13.978754 36.021256,13.978754 36.021256,13.978754"
id="path236" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:5.29166667;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 13.978763,13.97875 C 36.021235,36.021255 36.021235,36.021255 36.021235,36.021255"
id="path236-3" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg2637"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="down-arrow-dot.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview2639"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.5411756"
inkscape:cx="120.68709"
inkscape:cy="195.9543"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="g3917" />
<defs
id="defs2634">
<marker
style="overflow:visible"
id="Arrow1L"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow1L"
markerWidth="8.75"
markerHeight="5"
viewBox="0 0 8.75 5"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="arrow1L"
transform="scale(-0.5)" />
</marker>
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g3917"
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-opacity:1">
<g
id="g8541"
transform="rotate(90,24.583668,25.416332)">
<path
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:2.68756;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1L)"
d="M 3.4308411,25 H 14.716699"
id="path3277" />
<circle
style="fill:#00b9ff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path3909"
cx="38.23547"
cy="25"
r="6.6683626" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="30.947151mm"
height="20.403625mm"
viewBox="0 0 30.947151 20.403625"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="down-line.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.9897026"
inkscape:cx="2.34137"
inkscape:cy="38.465364"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="g1680" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-8.9338953,-14.343204)">
<g
id="g1680">
<rect
style="fill:#000000;fill-opacity:1;stroke-width:0.151;stroke-dasharray:none"
id="rect234"
width="30"
height="3"
x="9.4074707"
y="-34.74683"
rx="0.63805741"
ry="0.56966513"
transform="scale(1,-1)" />
<path
sodipodi:type="star"
style="fill:#000000;fill-opacity:1;stroke-width:0.2"
id="path288"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="14.784716"
sodipodi:cy="24.599154"
sodipodi:r1="20.021852"
sodipodi:r2="10.010926"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0.2"
inkscape:randomized="0"
d="m 32.124148,34.61008 c -3.467886,6.006556 -31.21097873,6.006555 -34.6788653,0 C -6.0226038,28.603524 7.8489426,4.577301 14.784716,4.577301 c 6.935773,10e-8 20.807319,24.026223 17.339432,30.032779 z"
inkscape:transform-center-y="2.5"
transform="matrix(0.8650802,0,0,-0.49945428,11.617506,33.879356)" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg32498"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="dropdown.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview32500"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.245064"
inkscape:cx="82.848418"
inkscape:cy="160.35178"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs32495" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<path
sodipodi:type="star"
style="fill:#00b9ff;stroke:#ffffff;stroke-width:0.499999;stroke-linecap:square;stroke-linejoin:round;paint-order:fill markers stroke"
id="path33183"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="10.648307"
sodipodi:cy="7.9978433"
sodipodi:r1="15.32118"
sodipodi:r2="7.6605897"
sodipodi:arg1="1.5707963"
sodipodi:arg2="2.6179939"
inkscape:rounded="0.2"
inkscape:randomized="0"
d="M 10.648307,23.319024 C 5.3408947,23.319024 -5.2739309,4.9336076 -2.6202248,0.33725345 0.0334814,-4.2591007 21.263132,-4.2591013 23.916838,0.33725274 26.570544,4.9336068 15.95572,23.319023 10.648307,23.319024 Z"
inkscape:transform-center-y="2.9405715"
transform="matrix(1.5501831,0,0,1.3958439,8.4931749,10.895688)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="folders.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.1795515"
inkscape:cx="62.398159"
inkscape:cy="78.915318"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g1236"
transform="translate(1.2168922,0.47448993)">
<rect
style="fill:#00b9ff;stroke-width:4;stroke-linecap:square;paint-order:fill markers stroke"
id="rect234"
width="24.566216"
height="5.7219739"
x="15"
y="10.134511" />
<rect
style="fill:#00b9ff;stroke-width:4;stroke-linecap:square;paint-order:fill markers stroke"
id="rect234-3"
width="24.566216"
height="5.7219739"
x="15"
y="17.821186" />
<rect
style="fill:#00b9ff;stroke-width:4;stroke-linecap:square;paint-order:fill markers stroke"
id="rect234-6"
width="24.566216"
height="5.7219739"
x="18"
y="25.50786" />
<rect
style="fill:#00b9ff;stroke-width:4;stroke-linecap:square;paint-order:fill markers stroke"
id="rect234-7"
width="24.566216"
height="5.7219739"
x="12"
y="33.194534" />
<rect
style="fill:#00b9ff;stroke-width:4;stroke-linecap:square;paint-order:fill markers stroke"
id="rect234-5"
width="24.566216"
height="5.7219739"
x="15"
y="40.88121" />
<rect
style="fill:#00b9ff;stroke-width:4;stroke-linecap:square;paint-order:fill markers stroke"
id="rect234-35"
width="24.566216"
height="5.7219739"
x="12"
y="2.4478359" />
<path
style="fill:none;stroke:#000000;stroke-width:1.0168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 5,5.4357252 H 9.9999996"
id="path479"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.0168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 8,12.995498 h 5"
id="path479-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.0168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 8,20.682173 h 5"
id="path479-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.0168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 11,28.368847 h 5"
id="path479-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.0168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 5,36.055521 h 5"
id="path479-1"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.0168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 8,43.742197 h 5"
id="path479-1-2"
sodipodi:nodetypes="cc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="fullscreen.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.1795515"
inkscape:cx="10.55263"
inkscape:cy="29.363839"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow4"
markerWidth="5"
markerHeight="6"
viewBox="0 0 5 6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path1741" />
</marker>
<marker
style="overflow:visible"
id="Arrow4-3"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow4"
markerWidth="5"
markerHeight="6"
viewBox="0 0 5 6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path1741-5" />
</marker>
<marker
style="overflow:visible"
id="Arrow4-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow4"
markerWidth="5"
markerHeight="6"
viewBox="0 0 5 6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path1741-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow4-27"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow4"
markerWidth="5"
markerHeight="6"
viewBox="0 0 5 6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path1741-0" />
</marker>
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow4)"
d="M 20.86372,20.86372 2.1213204,2.1213206"
id="path2129" />
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow4-3)"
d="M 29.13628,20.86372 47.87868,2.1213205"
id="path2129-6" />
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow4-2)"
d="m 29.13628,29.13628 18.7424,18.7424"
id="path2129-1" />
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow4-27)"
d="M 20.863721,29.13628 2.1213204,47.878679"
id="path2129-9" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="leave-fullscreen.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.77058782"
inkscape:cx="1.2977106"
inkscape:cy="-51.908425"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow4"
markerWidth="5"
markerHeight="6"
viewBox="0 0 5 6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path1741" />
</marker>
<marker
style="overflow:visible"
id="Arrow4-3"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow4"
markerWidth="5"
markerHeight="6"
viewBox="0 0 5 6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path1741-5" />
</marker>
<marker
style="overflow:visible"
id="Arrow4-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow4"
markerWidth="5"
markerHeight="6"
viewBox="0 0 5 6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path1741-9" />
</marker>
<marker
style="overflow:visible"
id="Arrow4-27"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow4"
markerWidth="5"
markerHeight="6"
viewBox="0 0 5 6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="m 1,0 -3,3 h -2 l 3,-3 -3,-3 h 2 z"
id="path1741-0" />
</marker>
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow4)"
d="M 48.93934,48.93934 30.196941,30.19694"
id="path2129" />
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow4-3)"
d="M 1.0606602,48.93934 19.80306,30.19694"
id="path2129-6" />
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow4-2)"
d="M 1.0606602,1.0606602 19.80306,19.80306"
id="path2129-1" />
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow4-27)"
d="M 48.93934,1.0606602 30.19694,19.803059"
id="path2129-9" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg2637"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="left-arrow-dot.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview2639"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.5411756"
inkscape:cx="120.68709"
inkscape:cy="195.9543"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="g3917" />
<defs
id="defs2634">
<marker
style="overflow:visible"
id="Arrow1L"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow1L"
markerWidth="8.75"
markerHeight="5"
viewBox="0 0 8.75 5"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="arrow1L"
transform="scale(-0.5)" />
</marker>
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g3917"
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-opacity:1">
<g
id="g8541"
transform="rotate(180,24.583668,25)">
<path
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:2.68756;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1L)"
d="M 3.4308411,25 H 14.716699"
id="path3277" />
<circle
style="fill:#00b9ff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path3909"
cx="38.23547"
cy="25"
r="6.6683626" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="15.328552mm"
height="17.915771mm"
viewBox="0 0 15.328552 17.915771"
version="1.1"
id="svg1390"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="ln.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1392"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.0823513"
inkscape:cx="14.112603"
inkscape:cy="52.881708"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1387" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-108.04555,-116.36581)">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:semi-condensed;font-size:22.5778px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold Semi-Condensed';letter-spacing:0px;word-spacing:0px;fill:#0090ff;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="108.23772"
y="132.82512"
id="text236-6-1-0"><tspan
sodipodi:role="line"
id="tspan234-2-2-9"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:semi-condensed;font-size:22.5778px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold Semi-Condensed';fill:#0090ff;fill-opacity:1;stroke-width:0.264583"
x="108.23772"
y="132.82512">N</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:semi-condensed;font-size:22.5778px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold Semi-Condensed';letter-spacing:0px;word-spacing:0px;fill:#0040ff;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="106.18244"
y="134.28159"
id="text236-6-1-0-6"><tspan
sodipodi:role="line"
id="tspan234-2-2-9-0"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:semi-condensed;font-size:22.5778px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold Semi-Condensed';fill:#0040ff;fill-opacity:1;stroke-width:0.264583"
x="106.18244"
y="134.28159">L</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg32498"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="menu.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview32500"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.245064"
inkscape:cx="84.630103"
inkscape:cy="160.35177"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs32495" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g33079"
transform="translate(0,1.0055408)">
<rect
style="fill:#00b9ff;stroke:#ffffff;stroke-width:0.499999;stroke-linecap:square;stroke-linejoin:round;paint-order:fill markers stroke"
id="rect33034"
width="40"
height="6"
x="5"
y="20.994459"
rx="2"
ry="2" />
<rect
style="fill:#00b9ff;stroke:#ffffff;stroke-width:0.499999;stroke-linecap:square;stroke-linejoin:round;paint-order:fill markers stroke"
id="rect33034-3"
width="40"
height="6"
x="5"
y="30.392094"
rx="2"
ry="2" />
<rect
style="fill:#00b9ff;stroke:#ffffff;stroke-width:0.499999;stroke-linecap:square;stroke-linejoin:round;paint-order:fill markers stroke"
id="rect33034-0"
width="40"
height="6"
x="5"
y="11.596825"
rx="2"
ry="2" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg8333"
sodipodi:docname="new-child.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview8335"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.0863221"
inkscape:cx="97.300411"
inkscape:cy="121.26603"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="g11376" />
<defs
id="defs8330" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g11376"
transform="translate(3.7982941,1.3152657)">
<rect
style="fill:#33b5dd;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="rect9115"
width="27.529907"
height="7.530395"
x="4.4545231"
y="5.9081044" />
<rect
style="fill:#33b5dd;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="rect9115-5"
width="27.529907"
height="7.530395"
x="10.418982"
y="15.24906" />
<rect
style="fill:#31f505;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="rect9115-6"
width="27.529907"
height="7.530395"
x="10.418982"
y="24.590014" />
<rect
style="fill:#33b5dd;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="rect9115-7"
width="27.529907"
height="7.530395"
x="4.4545231"
y="33.930969" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg8333"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="new-sibling.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview8335"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.0863221"
inkscape:cx="82.441728"
inkscape:cy="121.26603"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="g11352" />
<defs
id="defs8330" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g11352"
transform="translate(3.7982941,1.3152657)">
<rect
style="fill:#33b5dd;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="rect9115"
width="27.529907"
height="7.530395"
x="4.4545231"
y="5.9081044" />
<rect
style="fill:#33b5dd;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="rect9115-5"
width="27.529907"
height="7.530395"
x="10.418982"
y="15.24906" />
<rect
style="fill:#33b5dd;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="rect9115-6"
width="27.529907"
height="7.530395"
x="4.4545231"
y="24.590014" />
<rect
style="fill:#31f505;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="rect9115-7"
width="27.529907"
height="7.530395"
x="4.4545231"
y="33.930969" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg2637"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="right-arrow-dot.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview2639"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.5411756"
inkscape:cx="120.68709"
inkscape:cy="195.9543"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="g3917" />
<defs
id="defs2634">
<marker
style="overflow:visible"
id="Arrow1L"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow1L"
markerWidth="8.75"
markerHeight="5"
viewBox="0 0 8.75 5"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="arrow1L"
transform="scale(-0.5)" />
</marker>
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g3917"
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-opacity:1">
<g
id="g8541"
transform="translate(0.83266323)">
<path
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:2.68756;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1L)"
d="M 3.4308411,25 H 14.716699"
id="path3277" />
<circle
style="fill:#00b9ff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path3909"
cx="38.23547"
cy="25"
r="6.6683626" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg10046"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="selected.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview10048"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.0823513"
inkscape:cx="109.81876"
inkscape:cy="99.274862"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="g17945" />
<defs
id="defs10043" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g17945"
style="stroke-width:1;stroke-dasharray:none;fill:none;fill-opacity:1;stroke:#ecae1a;stroke-opacity:1">
<ellipse
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:1;stroke-linecap:round;stroke-opacity:1;stroke-dasharray:none"
id="path17937"
cx="25"
cy="25"
rx="19.324848"
ry="19.32485" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 8.084858,41.742891 C 41.293335,7.0202146 39.697014,5.4756764 39.697014,5.4756764"
id="path8208" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 8.1156843,9.1339277 C 41.46406,44.674816 46.782227,45.727445 46.782227,45.727445"
id="path8210" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg133"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="settings.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview135"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.0823513"
inkscape:cx="65.858814"
inkscape:cy="119.38938"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs130" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g603"
transform="translate(-2.1575816,2.9369537)"
style="fill:#00b9ff;fill-opacity:1">
<path
sodipodi:type="star"
style="fill:#00b9ff;stroke-width:5.29201;stroke-linecap:square;paint-order:fill markers stroke;fill-opacity:1"
id="path572"
inkscape:flatsided="false"
sodipodi:sides="8"
sodipodi:cx="6.3527875"
sodipodi:cy="3.8581693"
sodipodi:r1="5.6759357"
sodipodi:r2="7.5679145"
sodipodi:arg1="0.74726227"
sodipodi:arg2="1.1399614"
inkscape:rounded="0.2"
inkscape:randomized="0"
d="M 10.516383,7.7157228 C 10.083993,8.1824164 10.091444,10.468808 9.5133724,10.734508 8.9353006,11.000208 7.2049397,9.5057216 6.5691919,9.5299782 5.933444,9.5542347 4.3219899,11.176226 3.7253529,10.955346 3.1287159,10.734466 2.9619276,8.4541545 2.495234,8.0217649 2.0285404,7.5893752 -0.25785077,7.5968261 -0.52355111,7.0187542 -0.7892514,6.4406825 0.70523518,4.7103215 0.68097864,4.0745737 0.65672209,3.4388258 -0.96526923,1.8273717 -0.74438919,1.2307347 -0.5235092,0.63409774 1.7568024,0.46730938 2.189192,6.1584356e-4 2.6215816,-0.46607777 2.6141307,-2.752469 3.1922026,-3.0181693 c 0.5780718,-0.2657003 2.3084327,1.2287863 2.9441805,1.2045298 0.6357479,-0.024257 2.247202,-1.6462479 2.843839,-1.4253679 0.596637,0.22088 0.7634253,2.50119157 1.2301189,2.93358118 0.466694,0.43238968 2.753085,0.42493874 3.018785,1.00301061 0.2657,0.57807181 -1.228786,2.30843271 -1.20453,2.94418051 0.02426,0.6357479 1.646248,2.247202 1.425368,2.843839 -0.22088,0.596637 -2.501191,0.7634254 -2.933581,1.2301189 z"
transform="translate(7.0050196,7.703995)" />
<path
sodipodi:type="star"
style="fill:#00b9ff;stroke-width:5.29201;stroke-linecap:square;paint-order:fill markers stroke;fill-opacity:1"
id="path572-3"
inkscape:flatsided="false"
sodipodi:sides="12"
sodipodi:cx="6.3527875"
sodipodi:cy="3.8581693"
sodipodi:r1="6.4327273"
sodipodi:r2="7.5679145"
sodipodi:arg1="0.74726227"
sodipodi:arg2="1.0090617"
inkscape:rounded="0.2"
inkscape:randomized="0"
d="M 11.071529,8.2300634 C 10.7798,8.5449366 10.747159,10.034501 10.383876,10.263141 10.020592,10.49178 8.6634717,9.8768876 8.2533907,10.003711 7.8433095,10.130535 7.0702588,11.404216 6.6413264,11.420581 6.2123941,11.436947 5.3445396,10.225874 4.9259871,10.130667 4.5074344,10.035459 3.2011127,10.751973 2.8214635,10.55168 2.4418144,10.351387 2.2957667,8.8686397 1.9808934,8.576911 1.6660202,8.2851823 0.17645534,8.2525409 -0.05218394,7.8892573 -0.28082317,7.5259739 0.33406917,6.1688536 0.20724533,5.7587725 0.08042146,5.3486913 -1.1932588,4.5756406 -1.2096245,4.1467082 -1.2259901,3.7177759 -0.0149176,2.8499214 0.08029027,2.4313689 0.17549815,2.0128162 -0.54101598,0.70649455 -0.34072285,0.32684535 -0.14042976,-0.05280376 1.3423171,-0.19885153 1.6340458,-0.51372473 1.9257745,-0.828598 1.9584159,-2.3181628 2.3216995,-2.5468021 c 0.3632834,-0.2286392 1.7204037,0.3862531 2.1304848,0.2594293 0.4100812,-0.1268239 1.1831319,-1.4005042 1.6120643,-1.4168699 0.4289323,-0.016366 1.2967868,1.1947069 1.7153393,1.2899148 0.4185527,0.095208 1.7248744,-0.6213063 2.1045236,-0.4210131 0.3796495,0.2002931 0.5256965,1.6830399 0.8405705,1.97476859 0.314873,0.29172877 1.804438,0.32437017 2.033077,0.68765371 0.228639,0.36328346 -0.386253,1.7204038 -0.259429,2.1304848 0.126824,0.4100812 1.400504,1.1831319 1.416869,1.6120643 0.01637,0.4289323 -1.194706,1.2967868 -1.289914,1.7153394 -0.09521,0.4185526 0.621306,1.7248743 0.421013,2.1045235 -0.200293,0.3796491 -1.68304,0.5256969 -1.974769,0.8405701 z"
transform="matrix(2.1334122,0,0,2.1334122,18.387992,15.316613)" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -0,0 +1,907 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="theme-blue.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0897757"
inkscape:cx="477.16239"
inkscape:cy="394.57659"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="g5836-8-6" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke:none;stroke-width:1.12415;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect3661"
width="90"
height="15"
x="25"
y="78" />
<rect
style="fill:#e3f7ff;fill-opacity:1;stroke:none;stroke-width:1.12415;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect3661-6"
width="90"
height="15"
x="25"
y="108" />
<g
id="g2239"
transform="translate(0.98303124,-23.666308)">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:0.419714;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect234"
width="28.183935"
height="5.6338892"
x="31.265913"
y="64.427399"
ry="2.8169446" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.82812px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0957032"
x="33.537033"
y="68.431061"
id="text1680"><tspan
sodipodi:role="line"
id="tspan1678"
style="stroke-width:0.0957032"
x="33.537033"
y="68.431061">Something</tspan></text>
<ellipse
style="fill:#ffffff;fill-opacity:1;stroke:#00b9ff;stroke-width:0.382812;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path1968"
cx="56.751492"
cy="67.244339"
rx="2.9285834"
ry="2.8143675" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:0.646357;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 55.405287,68.590543 c 2.692409,-2.692404 2.692409,-2.692404 2.692409,-2.692404"
id="path236" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:0.646357;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 55.405289,65.898137 c 2.692403,2.692408 2.692403,2.692408 2.692403,2.692408"
id="path236-3" />
</g>
<g
id="g2239-3"
transform="translate(32.276564,-23.666308)">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:0.419714;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect234-6"
width="28.183935"
height="5.6338892"
x="31.265913"
y="64.427399"
ry="2.8169446" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.82812px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0957032"
x="33.537033"
y="68.431061"
id="text1680-7"><tspan
sodipodi:role="line"
id="tspan1678-5"
style="stroke-width:0.0957032"
x="33.537033"
y="68.431061">Something</tspan></text>
<ellipse
style="fill:#ffffff;fill-opacity:1;stroke:#00b9ff;stroke-width:0.382812;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path1968-3"
cx="56.751492"
cy="67.244339"
rx="2.9285834"
ry="2.8143675" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:0.646357;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 55.405287,68.590543 c 2.692409,-2.692404 2.692409,-2.692404 2.692409,-2.692404"
id="path236-5" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:0.646357;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 55.405289,65.898137 c 2.692403,2.692408 2.692403,2.692408 2.692403,2.692408"
id="path236-3-6" />
</g>
<g
id="g2239-2"
transform="translate(63.570097,-23.666308)">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:0.419714;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect234-9"
width="28.183935"
height="5.6338892"
x="31.265913"
y="64.427399"
ry="2.8169446" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.82812px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0957032"
x="33.537033"
y="68.431061"
id="text1680-1"><tspan
sodipodi:role="line"
id="tspan1678-2"
style="stroke-width:0.0957032"
x="33.537033"
y="68.431061">Something</tspan></text>
<ellipse
style="fill:#ffffff;fill-opacity:1;stroke:#00b9ff;stroke-width:0.382812;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path1968-7"
cx="56.751492"
cy="67.244339"
rx="2.9285834"
ry="2.8143675" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:0.646357;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 55.405287,68.590543 c 2.692409,-2.692404 2.692409,-2.692404 2.692409,-2.692404"
id="path236-0" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:0.646357;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 55.405289,65.898137 c 2.692403,2.692408 2.692403,2.692408 2.692403,2.692408"
id="path236-3-9" />
</g>
<g
id="g2607"
transform="translate(0.42026596,-2.6776131)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="27.122194"
y="71.455864"
id="text2471"><tspan
sodipodi:role="line"
id="tspan2469"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.264583"
x="27.122194"
y="71.455864">Wolff-Thobaben</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="100.11073"
y="71.253372"
id="text2475"><tspan
sodipodi:role="line"
id="tspan2473"
style="font-size:4.93889px;stroke-width:0.264583"
x="100.11073"
y="71.253372">1979</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="26.643122"
y="77.120659"
id="text2479"><tspan
sodipodi:role="line"
id="tspan2477"
style="font-size:4.93889px;stroke-width:0.264583"
x="26.643122"
y="77.120659">Harald</tspan></text>
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.266037px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 24.579734,80.714791 c 90.000006,0 90.000006,0 90.000006,0"
id="path2535" />
</g>
<g
id="g2607-1"
transform="translate(0.42026596,12.327323)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="27.122194"
y="71.455864"
id="text2471-4"><tspan
sodipodi:role="line"
id="tspan2469-9"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.264583"
x="27.122194"
y="71.455864">Thobaben</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="100.11073"
y="71.253372"
id="text2475-2"><tspan
sodipodi:role="line"
id="tspan2473-0"
style="font-size:4.93889px;stroke-width:0.264583"
x="100.11073"
y="71.253372">1980</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="26.643122"
y="77.120659"
id="text2479-6"><tspan
sodipodi:role="line"
id="tspan2477-8"
style="font-size:4.93889px;stroke-width:0.264583"
x="26.643122"
y="77.120659">Ute</tspan></text>
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.266037px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 24.579734,80.714466 c 89.999996,0 89.999996,0 89.999996,0"
id="path2535-9" />
</g>
<g
id="g2607-2"
transform="translate(0.102703,27.322387)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="27.122194"
y="71.455864"
id="text2471-6"><tspan
sodipodi:role="line"
id="tspan2469-6"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.264583"
x="27.122194"
y="71.455864">Wolff-Thobaben</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="100.11073"
y="71.253372"
id="text2475-4"><tspan
sodipodi:role="line"
id="tspan2473-9"
style="font-size:4.93889px;stroke-width:0.264583"
x="100.11073"
y="71.253372">1979</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="26.643122"
y="77.120659"
id="text2479-5"><tspan
sodipodi:role="line"
id="tspan2477-0"
style="font-size:4.93889px;stroke-width:0.264583"
x="26.643122"
y="77.120659">Harald</tspan></text>
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.266037px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 24.897297,80.714791 c 90.000003,0 90.000003,0 90.000003,0"
id="path2535-4" />
</g>
<g
id="g2607-1-8"
transform="matrix(1.0110237,0,0,0.99994451,-0.17175782,42.326143)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="27.122194"
y="71.455864"
id="text2471-4-7"><tspan
sodipodi:role="line"
id="tspan2469-9-1"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.264583"
x="27.122194"
y="71.455864">Wolff-Thobaben</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="100.11073"
y="71.253372"
id="text2475-2-7"><tspan
sodipodi:role="line"
id="tspan2473-0-2"
style="font-size:4.93889px;stroke-width:0.264583"
x="100.11073"
y="71.253372">1979</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.93889px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="26.643122"
y="77.120659"
id="text2479-6-7"><tspan
sodipodi:role="line"
id="tspan2477-8-2"
style="font-size:4.93889px;stroke-width:0.264583"
x="26.643122"
y="77.120659">Harald</tspan></text>
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 24.897297,80.714791 c 89.018683,0 89.018683,0 89.018683,0"
id="path2535-9-2" />
</g>
<g
id="g3013"
transform="translate(-2.3526113,-0.63039516)">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect2708"
width="42.740021"
height="7.4045463"
x="164.19189"
y="12.367399"
ry="2.8169999" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="text2843"><tspan
sodipodi:role="line"
id="tspan2841"
style="font-size:5.64444px;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="185.64658"
y="18.186337">selection</tspan></text>
</g>
<g
id="g3013-0"
transform="translate(-2.3526113,8.7479258)">
<rect
style="fill:#74d9ff;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect2708-6"
width="42.740021"
height="7.4045463"
x="164.19189"
y="12.367399"
ry="2.8169999" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="text2843-3"><tspan
sodipodi:role="line"
id="tspan2841-2"
style="font-size:5.64444px;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="185.64658"
y="18.186337">border</tspan></text>
</g>
<g
id="g3013-06"
transform="translate(-2.3526113,18.126247)">
<rect
style="fill:#e3f7ff;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect2708-1"
width="42.740021"
height="7.4045463"
x="164.19189"
y="12.367399"
ry="2.8169999" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="text2843-5"><tspan
sodipodi:role="line"
style="font-size:5.64444px;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="tspan4008">hover</tspan></text>
</g>
<g
id="g3013-4"
transform="translate(-2.3526113,27.504568)">
<rect
style="fill:#f6f6ff;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect2708-7"
width="42.740021"
height="7.4045463"
x="164.19189"
y="12.367399"
ry="2.8169999" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="text2843-6"><tspan
sodipodi:role="line"
id="tspan2841-56"
style="font-size:5.64444px;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="185.64658"
y="18.186337">distinct</tspan></text>
</g>
<g
id="g3013-9"
transform="translate(-2.3526113,36.882889)">
<rect
style="fill:#ebebeb;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect2708-3"
width="42.740021"
height="7.4045463"
x="164.19189"
y="12.367399"
ry="2.8169999" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#989898;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="text2843-7"><tspan
sodipodi:role="line"
id="tspan2841-4"
style="font-size:5.64444px;text-align:center;text-anchor:middle;fill:#989898;fill-opacity:1;stroke-width:0.264583"
x="185.64658"
y="18.186337">disabled</tspan></text>
</g>
<g
id="g3013-5"
transform="translate(-2.3526113,46.26121)">
<rect
style="fill:#e1e1e1;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect2708-2"
width="42.740021"
height="7.4045463"
x="164.19189"
y="12.367399"
ry="2.8169999" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="text2843-54"><tspan
sodipodi:role="line"
id="tspan2841-7"
style="font-size:5.64444px;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="185.64658"
y="18.186337">header</tspan></text>
</g>
<g
id="g3013-44"
transform="translate(-2.3526113,55.639531)">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect2708-30"
width="42.740021"
height="7.4045463"
x="164.19189"
y="12.367399"
ry="2.8169999" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="text2843-78"><tspan
sodipodi:role="line"
id="tspan2841-6"
style="font-size:5.64444px;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="185.64658"
y="18.186337">selection</tspan></text>
</g>
<g
id="g3013-8"
transform="translate(-2.3526113,65.017852)">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect2708-8"
width="42.740021"
height="7.4045463"
x="164.19189"
y="12.367399"
ry="2.8169999" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:5.64444px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="185.64658"
y="18.186337"
id="text2843-4"><tspan
sodipodi:role="line"
id="tspan2841-3"
style="font-size:5.64444px;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="185.64658"
y="18.186337">selection</tspan></text>
</g>
<g
id="g5836"
transform="translate(-5.8655987,-11.349614)">
<rect
style="fill:none;fill-opacity:1;stroke:#74d9ff;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect4336"
width="80"
height="15"
x="31.115599"
y="144.30339"
rx="5"
ry="5" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="54.028866"
y="155.52872"
id="text5792"><tspan
sodipodi:role="line"
id="tspan5790"
style="stroke-width:0.264583"
x="54.028866"
y="155.52872">button</tspan></text>
</g>
<g
id="g5836-8"
transform="translate(-5.8655987,8.942348)">
<rect
style="fill:#e3f7ff;fill-opacity:1;stroke:#74d9ff;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect4336-9"
width="80"
height="15"
x="31.115599"
y="144.30339"
rx="5"
ry="5" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="49.001808"
y="155.52872"
id="text5792-7"><tspan
sodipodi:role="line"
id="tspan5790-7"
style="stroke-width:0.264583"
x="49.001808"
y="155.52872">hovering</tspan></text>
</g>
<g
id="g5836-8-6"
transform="translate(89.134401,8.942348)">
<rect
style="fill:#ebebeb;fill-opacity:1;stroke:#c5c5c5;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect4336-9-4"
width="80"
height="15"
x="31.115599"
y="144.30339"
rx="5"
ry="5" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#989898;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="49.001808"
y="155.52872"
id="text5792-7-3"><tspan
sodipodi:role="line"
id="tspan5790-7-0"
style="fill:#989898;fill-opacity:1;stroke-width:0.264583"
x="49.001808"
y="155.52872">disabled</tspan></text>
</g>
<g
id="g5836-1"
transform="translate(89.134401,-11.214843)">
<rect
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect4336-5"
width="80"
height="15"
x="31.115599"
y="144.30339"
rx="5"
ry="5" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="50.038967"
y="155.52872"
id="text5792-9"><tspan
sodipodi:role="line"
id="tspan5790-4"
style="stroke-width:0.264583;fill:#ffffff;fill-opacity:1"
x="50.038967"
y="155.52872">checked</tspan></text>
</g>
<g
id="g7941"
transform="translate(1.5764377,-33.201249)">
<g
id="g6927"
transform="matrix(0.69034405,0,0,0.66487822,-0.48985401,87.431998)">
<rect
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922"><tspan
sodipodi:role="line"
id="tspan6920"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-9"
transform="matrix(0.69034405,0,0,0.66487822,-0.48985401,95.750001)">
<rect
style="fill:#e1e1e1;fill-opacity:1;stroke:#e1e1e1;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-0"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-9"><tspan
sodipodi:role="line"
id="tspan6920-1"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-7"
transform="matrix(0.69034405,0,0,0.66487822,-0.48985401,104.068)">
<rect
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-7"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-1"><tspan
sodipodi:role="line"
id="tspan6920-15"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-97"
transform="matrix(0.69034405,0,0,0.66487822,-0.48985401,112.38601)">
<rect
style="fill:#e1e1e1;fill-opacity:1;stroke:#e1e1e1;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-76"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-7"><tspan
sodipodi:role="line"
id="tspan6920-3"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-6"
transform="matrix(0.69034405,0,0,0.66487822,-0.48985401,129.02202)">
<rect
style="fill:#e1e1e1;fill-opacity:1;stroke:#e1e1e1;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-5"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-6"><tspan
sodipodi:role="line"
id="tspan6920-39"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-4"
transform="matrix(0.69034405,0,0,0.66487822,-0.48985401,120.70401)">
<rect
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-8"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-12"><tspan
sodipodi:role="line"
id="tspan6920-9"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.212931px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16.771952,215.96933 c 83.180043,0 83.180043,0 83.180043,0"
id="path2535-9-2-3" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.212931px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16.771952,224.26942 c 83.180053,0 83.180053,0 83.180053,0"
id="path2535-9-2-3-9" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.212931px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16.638928,232.58743 c 83.180047,0 83.180047,0 83.180047,0"
id="path2535-9-2-3-0" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.212931px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16.771952,240.90543 c 83.180043,0 83.180043,0 83.180043,0"
id="path2535-9-2-3-8" />
<path
style="fill:none;stroke:#74d9ff;stroke-width:0.212931px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16.771952,249.22344 c 83.180043,0 83.180043,0 83.180043,0"
id="path2535-9-2-3-85" />
</g>
<g
id="g7967"
transform="translate(1.5764377,-34.284922)">
<g
id="g6927-62"
transform="matrix(0.69034405,0,0,0.66487822,95.867716,88.515671)">
<rect
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-1"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-78"><tspan
sodipodi:role="line"
id="tspan6920-5"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-9-7"
transform="matrix(0.69034405,0,0,0.66487822,95.867716,96.833671)">
<rect
style="fill:#f6f6ff;fill-opacity:1;stroke:#f6f6ff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-0-4"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-9-1"><tspan
sodipodi:role="line"
id="tspan6920-1-8"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-7-5"
transform="matrix(0.69034405,0,0,0.66487822,95.867716,105.15167)">
<rect
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-7-9"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-1-7"><tspan
sodipodi:role="line"
id="tspan6920-15-5"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-97-3"
transform="matrix(0.69034405,0,0,0.66487822,95.867716,113.46968)">
<rect
style="fill:#f6f6ff;fill-opacity:1;stroke:#f6f6ff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-76-8"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-7-8"><tspan
sodipodi:role="line"
id="tspan6920-3-3"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-6-1"
transform="matrix(0.69034405,0,0,0.66487822,95.867716,130.10569)">
<rect
style="fill:#f6f6ff;fill-opacity:1;stroke:#f6f6ff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-5-8"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-6-9"><tspan
sodipodi:role="line"
id="tspan6920-39-6"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
<g
id="g6927-4-4"
transform="matrix(0.69034405,0,0,0.66487822,95.867716,121.78768)">
<rect
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.500195;stroke-linecap:square;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="rect6918-8-3"
width="119.99052"
height="12.010373"
x="25.25474"
y="180.87709" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.35px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
x="31.284105"
y="189.26299"
id="text6922-12-3"><tspan
sodipodi:role="line"
id="tspan6920-9-3"
style="font-size:6.35px;stroke-width:0.264583"
x="31.284105"
y="189.26299">table row</tspan></text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="90mm"
height="90mm"
viewBox="0 0 89.999999 89.999999"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="triangle-down.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.5411756"
inkscape:cx="136.25962"
inkscape:cy="81.106916"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-53.170048,-110.99036)">
<path
sodipodi:type="star"
style="fill:#000000;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="path1159"
inkscape:flatsided="false"
sodipodi:sides="3"
sodipodi:cx="68.590904"
sodipodi:cy="66.201645"
sodipodi:r1="51.717163"
sodipodi:r2="25.85858"
sodipodi:arg1="2.0943951"
sodipodi:arg2="3.1415927"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 42.732323,110.99002 2e-6,-44.788376 -2e-6,-44.788376 38.787872,22.394191 38.787875,22.394186 -38.787877,22.394187 z"
transform="matrix(0,0.5,-1,0,164.16007,115.23026)"
inkscape:transform-center-y="6.4646425" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="90mm"
height="90mm"
viewBox="0 0 89.999999 90"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="triangle-left.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.5411756"
inkscape:cx="15.572528"
inkscape:cy="201.14515"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-85.029133,-79.131272)">
<path
sodipodi:type="star"
style="fill:#000000;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="path1159"
inkscape:flatsided="false"
sodipodi:sides="3"
sodipodi:cx="68.590904"
sodipodi:cy="66.201645"
sodipodi:r1="51.717163"
sodipodi:r2="25.85858"
sodipodi:arg1="2.0943951"
sodipodi:arg2="3.1415927"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 42.732323,110.99002 2e-6,-44.788376 -2e-6,-44.788376 38.787872,22.394191 38.787875,22.394186 -38.787877,22.394187 z"
inkscape:transform-center-x="6.4646468"
transform="matrix(-0.5,0,0,1,170.78923,57.718004)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="90mm"
height="90mm"
viewBox="0 0 89.999999 90"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="triangle-right.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.5411756"
inkscape:cx="35.687043"
inkscape:cy="201.14515"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-85.029133,-79.131272)">
<path
sodipodi:type="star"
style="fill:#000000;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="path1159"
inkscape:flatsided="false"
sodipodi:sides="3"
sodipodi:cx="68.590904"
sodipodi:cy="66.201645"
sodipodi:r1="51.717163"
sodipodi:r2="25.85858"
sodipodi:arg1="2.0943951"
sodipodi:arg2="3.1415927"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 42.732323,110.99002 2e-6,-44.788376 -2e-6,-44.788376 38.787872,22.394191 38.787875,22.394186 -38.787877,22.394187 z"
inkscape:transform-center-x="-6.4646442"
transform="matrix(0.5,0,0,1,89.269036,57.718004)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="90mm"
height="90mm"
viewBox="0 0 89.999999 89.999999"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="triangle-up.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.5411756"
inkscape:cx="136.25962"
inkscape:cy="81.106916"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-53.170048,-110.99036)">
<path
sodipodi:type="star"
style="fill:#000000;fill-opacity:1;stroke-width:1.05833;paint-order:fill markers stroke"
id="path1159"
inkscape:flatsided="false"
sodipodi:sides="3"
sodipodi:cx="68.590904"
sodipodi:cy="66.201645"
sodipodi:r1="51.717163"
sodipodi:r2="25.85858"
sodipodi:arg1="2.0943951"
sodipodi:arg2="3.1415927"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 42.732323,110.99002 2e-6,-44.788376 -2e-6,-44.788376 38.787872,22.394191 38.787875,22.394186 -38.787877,22.394187 z"
transform="matrix(0,-0.5,-1,0,164.16007,196.75046)"
inkscape:transform-center-y="-6.4646423" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg10046"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="unchecked.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview10048"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.0823513"
inkscape:cx="60.505757"
inkscape:cy="126.20236"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs10043" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;fill-opacity:1;stroke-width:1.32292;stroke-linecap:round;stroke-dasharray:none;stroke:#74d9ff;stroke-opacity:1"
id="rect11149"
width="40"
height="40"
x="5"
y="5"
rx="4"
ry="4" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg10046"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="unselected.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview10048"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="4.359103"
inkscape:cx="108.62326"
inkscape:cy="88.320923"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="g17945" />
<defs
id="defs10043" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g17945"
style="stroke-width:1;stroke-dasharray:none">
<ellipse
style="fill:none;fill-opacity:1;stroke:#74d9ff;stroke-width:1;stroke-linecap:round;stroke-opacity:1;stroke-dasharray:none"
id="path17937"
cx="25"
cy="25"
rx="19.324848"
ry="19.32485" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg2637"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="up-arrow-dot.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview2639"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.5411756"
inkscape:cx="120.68709"
inkscape:cy="195.9543"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="g3917" />
<defs
id="defs2634">
<marker
style="overflow:visible"
id="Arrow1L"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow1L"
markerWidth="8.75"
markerHeight="5"
viewBox="0 0 8.75 5"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="arrow1L"
transform="scale(-0.5)" />
</marker>
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g3917"
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-opacity:1">
<g
id="g8541"
transform="rotate(-90,24.583668,24.583669)">
<path
style="fill:#00b9ff;fill-opacity:1;stroke:#00b9ff;stroke-width:2.68756;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1L)"
d="M 3.4308411,25 H 14.716699"
id="path3277" />
<circle
style="fill:#00b9ff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:square;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path3909"
cx="38.23547"
cy="25"
r="6.6683626" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="30.947151mm"
height="20.403625mm"
viewBox="0 0 30.947151 20.403625"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="up-line.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.9897026"
inkscape:cx="2.34137"
inkscape:cy="38.465364"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="g1680" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-8.9338953,-14.343204)">
<g
id="g1680">
<rect
style="fill:#000000;fill-opacity:1;stroke-width:0.150723"
id="rect234"
width="30"
height="3"
x="9.4074707"
y="14.343204"
rx="0.63805741"
ry="0.56966513" />
<path
sodipodi:type="star"
style="fill:#000000;fill-opacity:1;stroke-width:0.2"
id="path288"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="14.784716"
sodipodi:cy="24.599154"
sodipodi:r1="20.021852"
sodipodi:r2="10.010926"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0.2"
inkscape:randomized="0"
d="m 32.124148,34.61008 c -3.467886,6.006556 -31.21097873,6.006555 -34.6788653,0 C -6.0226038,28.603524 7.8489426,4.577301 14.784716,4.577301 c 6.935773,10e-8 20.807319,24.026223 17.339432,30.032779 z"
inkscape:transform-center-y="-2.5"
transform="matrix(0.8650802,0,0,0.49945428,11.617506,15.210676)" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="en">
<!--#include virtual="head.html" -->
<body class="overflow-auto flex-column scrolled">
<!--#include virtual="header.html" -->
<main class="container">
<div class="row-6">
<div class="col-2">
<div class="table min-vh-30 max-vh-50">
<table>
<thead>
<tr>
<td style="min-width: 15%;">Column 1<br/>10%</td>
<td style="min-width: 25%;">Column 2<br/>30%</td>
<td style="min-width: 15%;">Column 3<br/>15%</td>
<td style="min-width: 30%;">Column 4<br/>30%</td>
<td style="min-width: 15%;">Column 5<br/>15%</td>
</tr>
</thead>
<tbody class="overflow-y-scroll">
<tr>
<td>Cell A1</td>
<td>Cell B1</td>
<td>Cell C1</td>
<td>Cell D1</td>
<td>Cell E1</td>
</tr>
<tr>
<td>Cell A2</td>
<td>Cell B2</td>
<td>Cell C2</td>
<td>Cell D2</td>
<td>Cell E2</td>
</tr>
<tr>
<td>Cell A3</td>
<td>Cell B3</td>
<td>Cell C3</td>
<td>Cell D3</td>
<td>Cell E3</td>
</tr>
<tr>
<td>Cell A4</td>
<td>Cell B4</td>
<td>Cell C4</td>
<td>Cell D4</td>
<td>Cell E5</td>
</tr>
<tr>
<td>Cell A5</td>
<td>Cell B5</td>
<td>Cell C5</td>
<td>Cell D5</td>
<td>Cell E5</td>
</tr>
<tr>
<td>Cell A6</td>
<td>Cell B6</td>
<td>Cell C6</td>
<td>Cell D6</td>
<td>Cell E6</td>
</tr>
<tr>
<td>Cell A7</td>
<td>Cell B7</td>
<td>Cell C7</td>
<td>Cell D7</td>
<td>Cell E7</td>
</tr>
<tr>
<td>Cell A8</td>
<td>Cell B8</td>
<td>Cell C8</td>
<td>Cell D8</td>
<td>Cell E8</td>
</tr>
<tr>
<td>Cell A9</td>
<td>Cell B9</td>
<td>Cell C9</td>
<td>Cell D9</td>
<td>Cell E9</td>
</tr>
<tr>
<td>Cell A10</td>
<td>Cell B10</td>
<td>Cell C10</td>
<td>Cell D10</td>
<td>Cell E10</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
</div>
<div class="col-4">
<div class="table">
<table>
<thead>
<tr>
<td style="width: 10%;">Column 1<br/>10%</td>
<td style="width: 30%;">Column 2<br/>30%</td>
<td style="width: 15%;">Column 3<br/>15%</td>
<td style="width: 30%;">Column 4<br/>30%</td>
<td style="width: 15%;">Column 5<br/>15%</td>
</tr>
</thead>
<tbody>
<tr>
<td>Cell A1</td>
<td>Cell A2</td>
<td>Cell A3</td>
<td>Cell A4</td>
<td>Cell A5</td>
</tr>
<tr>
<td>Cell B1</td>
<td>Cell B2</td>
<td>Cell B3</td>
<td>Cell B4</td>
<td>Cell B5</td>
</tr>
<tr>
<td>Cell C1</td>
<td>Cell C2</td>
<td>Cell C3</td>
<td>Cell C4</td>
<td>Cell C5</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
</div>
</div>
</main>
<!--#include virtual="footer.html" -->
</body>
</html>

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<!--#include virtual="head.html" -->
<body class="overflow-auto flex-column scrolled">
<!--#include virtual="header.html" -->
<main class="container">
<div class="row-6">
<div class="sz-3">
<h1>H1 A nice header</h1>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="#">eirmod tempor invidunt</a> ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
</div>
<div class="sz-3">
<h2>H2 another nice header</h2>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
</div>
<div class="sz-6">
<h3>H3 another nice header</h3>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
</div>
<div class="sz-2 text-left">
<h4>H4 another nice header</h4>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
</div>
<div class="sz-2 text-block">
<h5>H5 another nice header</h5>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
</div>
<div class="sz-2 text-right">
<h6>H6 another nice header</h6>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
</div>
<div class="sz-2 text-left">
left aligned text
</div>
<div class="sz-2 text-center">
centered text<br>
( text block above is justified )
</div>
<div class="sz-2 text-right">
right aligned text
</div>
</div>
</main>
<!--#include virtual="footer.html" -->
</body>
</html>

View File

@ -0,0 +1,330 @@
<!DOCTYPE html>
<html lang="en">
<!--#include virtual="head.html" -->
<body class="overflow-auto flex-column scrolled">
<!--#include virtual="header.html" -->
<main class="container flex-row">
<div class="">
<sidebar
class="left flat"
:icons="[ 'menu', 'sym-settings', 'sym-left-arrow-dot' ]"
v-slot="{ sidebar }"
>
<div class="row m-0 p-1">
<div class="sz-12 p-0">
<vselect
class="small"
:items="dropdownItems"
:selected-items="tableSelection"
@select="(items) => { this.log(items); this.tableSelection = Array.from(items); this.tableSelection.length }"
v-slot="{ item, selectedItems }"
>
<div class="sz-12 row g-0 p-0">
<div class="sz-10 p-0 m-0 text-bold">{{ item.lastname }}</div>
<div class="sz-2 p-0 m-0 text-right">{{ item.year }}</div>
<div class="sz-12 p-0 m-0">{{ item.name }}<br>
</div>
</div>
</vselect>
</div>
</div>
<div class="sz-12 p-0">
<h1>Settings</h1>
</div>
<div class="sz-12 p-0">
<h1>attention</h1>
</div>
</sidebar>
</div>
<div class="row-6 flex-grow-1">
<h1 class="sz-6">Vue Components Test Page</h1>
<div class="sz-6 bg-red" :class="{'bg-green': true, }">Vue app started?</div>
<div class="sz-2">
<button @click="this.inactiveItems = [ 'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5' ]; this.activeItems = [];">
Initialize Items Test
</button>
</div>
<div class="sz-1 text-right">inactive items:</div>
<div class="sz-3">
<item v-for="item in inactiveItems"
@remove="()=>{ inactiveItems.remove(item); activeItems.push(item); }"
>{{ item }}
</item>
</div>
<div class="sz-3 text-right">active items:</div>
<div class="sz-3">
<item v-for="item in activeItems"
@remove="()=>{ activeItems.remove(item); inactiveItems.push(item); }"
>{{ item }}
</item>
</div>
<div class="sz-3 border-top">Lookup (TEXT)</div>
<div class="sz-3 border-top">
<lookup
:items="messages"
:value="currentMessage"
@create="(n)=>{ this.messages.push(n); this.currentMessage=n; }"
@change="(m)=>{ this.currentMessage=m; }"
></lookup>
</div>
<div class="sz-3">Selected:</div>
<div class="sz-3 text-monospace">
{{ currentMessage }}
</div>
<div class="sz-3">Lookup (OBJECT)</div>
<div class="sz-3">
<lookup
:items="instructions"
:value="currentInstruction"
field="text"
@create="(n)=>{ this.currentInstruction = { text: n, folder: null, }; }"
@change="(m)=>{ this.currentInstruction=m; }"
></lookup>
</div>
<div class="sz-3">Selected:</div>
<div class="sz-3 text-monospace">
{{ currentInstruction }}
</div>
<div class="sz-3 border-top">vselect</div>
<div class="sz-3 border-top">
<vselect
class="small"
:items="dropdownItems"
:selected-items="tableSelection"
@select="(items)=>this.tableSelection=items"
v-slot="{ item, selectedItems }"
>
<div class="sz-12 row g-0 p-0">
<div class="sz-10 p-0 m-0 text-bold">{{ item.lastname }}</div>
<div class="sz-2 p-0 m-0 text-right">{{ item.year }}</div>
<div class="sz-12 p-0 m-0">{{ item.name }}<br>
</div>
</div>
</vselect>
</div>
<div class="sz-3 border-top">Dropdown (Default)</div>
<div class="sz-3 border-top">
<dropdown
:items="dropdownItems"
label="name"
@change="(v)=>tableSelection=v"
:selected-items="tableSelection"
></dropdown>
</div>
<div class="sz-3">Dropdown (custom vselect)</div>
<div class="sz-3">
<dropdown
:items="dropdownItems"
label="name"
@change="(v)=>tableSelection=v"
:selected-items="tableSelection"
v-slot="{ items, selectedItems, dropdown }"
><vselect
class="small"
:items="items"
:selected-items="selectedItems"
@selected="(item) => dropdown.item_select(item)"
@deselected="(item) => dropdown.item_deselect(item)"
v-slot="{ item, selectedItems }"
>
<div class="sz-12 row g-0 p-0">
<div class="sz-10 p-0 m-0 text-bold">{{ item.lastname }}</div>
<div class="sz-2 p-0 m-0 text-right">{{ item.year }}</div>
<div class="sz-12 p-0 m-0">{{ item.name }}<br>
</div>
</div>
</vselect></dropdown>
</div>
<div class="sz-3 border-top">vtable (choose up to three)</div>
<div class="sz-3 border-top">
<vtable
:items="dropdownItems"
:columns="[
{ key: 'name', label:'Name'},
{ key: 'year', label:'Geburtsjahr'},
]"
@change="(v)=>tableSelection=Array.from(v)"
:selected-items="tableSelection"
:select="3"
></vtable>
</div>
<div class="sz-3">
Current table selection:
</div>
<div class="sz-3">
<item v-for="item in tableSelection"
@remove="tableSelection.splice(tableSelection.indexOf(item),1);"
>{{ item.lastname }}, {{ item.name }}</item>
</div>
<div class="sz-6 row-24 border text-right">
<div class="sz-4">Values with prefixes:</div>
<div
class="sz-3"
v-for="v in [ 0, 135, 13564, 135645, 1024768, 3465365363]"
>
<value :value="v" unit="Bytes"></value>
</div>
</div>
<div class="sz-6 row border">
<vtree
:items="treeExample"
@selectme="(si)=>ev_select(si)"
></vtree>
<div>{{ this.selectedTreeItem }}</div>
</div>
</div>
<div class="w-5">
<sidebar
:icons="[ 'sym-right-arrow-dot' ]"
:opened="sidebarOpened"
@show="(o)=>{ this.sidebarOpened=o; }"
v-slot="{ sidebar }"
>
<div class="row m-0 p-1">
<div class="sz-12 p-0">
<vselect
class="small"
:items="dropdownItems"
:selected-items="tableSelection"
@select="(items) => { this.log(items); this.tableSelection = Array.from(items); this.tableSelection.length && sidebar.show(-1); }"
v-slot="{ item, selectedItems }"
>
<div class="sz-12 row g-0 p-0">
<div class="sz-10 p-0 m-0 text-bold">{{ item.lastname }}</div>
<div class="sz-2 p-0 m-0 text-right">{{ item.year }}</div>
<div class="sz-12 p-0 m-0">{{ item.name }}<br>
</div>
</div>
</vselect>
</div>
</div>
</sidebar>
</div>
</main>
<!--#include virtual="footer.html" -->
<script type="module">
import {VueLoader} from "./js/vue-loader.mjs";
import { LNS, $in } from "./js/lnstyles.mjs";
let ldr = new VueLoader({
modules: [
'./components/dropdown.js',
'./components/item.js',
'./components/vtable.js',
'./components/vselect.js',
'./components/value.js',
'./components/sidebar.js',
'./components/lookup.js',
'./components/vtree.js',
],
data() {
return {
dropdownItems: [
{name: "Ute", lastname: "Thobaben", year: 1980},
{name: "Harald", lastname: "Wolff-Thobaben", year: 1979},
{name: "Pascal", lastname: "Thobaben", year: 2003},
{name: "Niclas", lastname: "Thobaben", year: 1996},
{name: "Justus", lastname: "Wolff", year: 2010},
],
tableSelection: [],
activeItems: [],
inactiveItems: [ 'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5' ],
sidebarOpened: -1,
messages: [
"Doppel an Mdt.",
"Ablegen in Akte",
"Abrechnen mit Mdt.",
"Zahlung veranlassen",
"",
],
currentMessage: null,
instructions: [
{
text: 'Doppel an Mandant',
folder: "Sekretariat",
},
{
text: 'Doppel an Gericht',
folder: null,
},
{
text: 'Doppel an Gegner',
folder: null,
},
{
text: 'Abrechnen ggü. Mdt.',
folder: null,
},
{
text: 'Abrechnen ggü. Gegner',
folder: null,
},
{
text: 'Abrechnen ggü. 3.',
folder: null,
},
],
currentInstruction: null,
log(...args){
console.log(...args);
},
selectedTreeItem: null,
treeExample: [
{
label: "Root Node",
items: [
{ label: '2nd level folder A', items: [], },
{ label: '2nd level folder B', items: [
{ label: '3rd level folder A', items: [], },
{ label: '3rd level folder B', items: [], },
{ label: '3rd level folder C', items: [], },
{ label: '3rd level folder D', items: [], },
],
},
{ label: '2nd level folder C', items: [
{ label: '3rd level folder A', items: [], },
{ label: '3rd level folder B', items: [], },
{ label: '3rd level folder C', items: [], },
{ label: '3rd level folder D', items: [], },
],
},
],
},
{
label: "Root Node B",
items: [
{ label: '2nd level folder A', items: [], },
{ label: '2nd level folder B', items: [
{ label: '3rd level folder A', items: [], },
{ label: '3rd level folder B', items: [], },
{ label: '3rd level folder C', items: [], },
{ label: '3rd level folder D', items: [], },
],
},
{ label: '2nd level folder C', items: [
{ label: '3rd level folder A', items: [], },
{ label: '3rd level folder B', items: [], },
{ label: '3rd level folder C', items: [], },
{ label: '3rd level folder D', items: [], },
],
},
],
}
],
};
},
methods: {
ev_select(selectedItem) {
console.log(selectedItem);
this.selectedTreeItem = selectedItem;
}
}
});
ldr.start();
</script>
</body>
</html>

84
index.html 100644
View File

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="contrib/lnstyles/css/lnstyles.css">
<link rel="icon" type="image/svg+xml" href="/contrib/lnstyles/svg/ln.svg">
<title>ai.chat - local ai test chat</title>
</head>
<body class="p-4">
<div id="app" class="container-md bg-white border-radius-4 h-100 display-flex flex-column">
<div class="flex-grow-0 p-2">
<h1>AI.chat</h1>
</div>
<div class="flex-grow-0 pl-4">
<button id="btnNew"
@click="connect"
>Neuer chat...</button>
</div>
<div class="bg-gray p-2 m-4 border-radius-2 overflow-auto flex-grow-1">
<div id="chat">
<div v-for="chatMessage in chatMessages"
class="border-radius-2 p-2 mb-2" :class="{ 'bg-lightgreen': (chatMessage.role === 'user'), 'ml-4': (chatMessage.role === 'user'), 'bg-lightgray': (chatMessage.role === 'assistant'), 'mr-4': (chatMessage.role === 'assistant') }"
v-html="convertMarkdown(chatMessage.content)"
></div>
</div>
</div>
<div class="p-2 flex-grow-0">
<div class="row">
<textarea class="sz-12" id="prompt" v-model="currentMessageText" style="min-height: 10em;"></textarea>
<button class="sz-2" id="submit" @click="say(currentMessageText)">SENDEN</button>
</div>
</div>
</div>
<script type="application/javascript" src="markdown-it.min.js"></script>
<script type="module">
import { createApp, reactive } from "./contrib/lnstyles/js/vue.esm-browser.js";
import { AssistantConnection } from "./assistant.js";
let config = await fetch("config.json").then((r)=>r.json());
let markdown = markdownit();
var defaultRender = markdown.renderer.rules.link_open || function (tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
};
markdown.renderer.rules.link_open = function (tokens, idx, options, env, self) {
// Add a new `target` attribute, or replace the value of the existing one.
tokens[idx].attrSet('target', '_blank');
// Pass the token to the default renderer.
return defaultRender(tokens, idx, options, env, self);
};
var app = createApp({
data(){
return {
assistant: this.connect(),
currentMessageText: "Wie lautet die Telefonnumer der Kanzlei Mährlein, Freymark, Bähr?",
chatMessages: [],
};
},
methods: {
connect(){
this.assistant = new AssistantConnection(config.websocket);
this.assistant.addEventListener("chatMessage", (evt)=>this.appendMessage(evt.message));
this.chatMessages = [];
return this.assistant;
},
say(text){
this.assistant.say(text);
},
convertMarkdown(md){
return markdown.render(md);
},
appendMessage(message){
this.chatMessages.push(message)
}
}
})
.mount("#app");
</script>
</body>
</html>

74
index2.html 100644
View File

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="contrib/lnstyles/css/lnstyles.css">
<link rel="icon" type="image/svg+xml" href="/contrib/lnstyles/svg/ln.svg">
<script type="application/javascript" src="showdown.min.js"></script>
<title>ai.chat - local ai test chat</title>
</head>
<body class="p-4">
<div class="container-md bg-white border-radius-4 h-100 display-flex flex-column">
<div class="flex-grow-0">
<h1>AI.chat</h1>
</div>
<div class="bg-gray p-2 m-4 border-radius-2 overflow-auto flex-grow-1">
<div id="chat"></div>
</div>
<div class="p-2 flex-grow-0">
<div class="row">
<textarea class="sz-12" id="prompt" style="min-height: 10em;"></textarea>
<button class="sz-2" id="submit">SENDEN</button>
</div>
</div>
</div>
<script type="module">
import { LNS } from "./contrib/lnstyles/js/lnstyles.js";
var $ = LNS;
const markdown = new showdown.Converter();
var model = "mixtral";
var messages = [];
function chat(){
let prompt = $("#prompt").value();
if (prompt === "")
return;
$("#chat").append($("<div class='bg-lightgreen border-radius-1 m-1 p-2 ml-4 bg-white pre'></div>").text(prompt));
let rm = Array.from(messages);
rm.push({
role: "user",
content: prompt,
});
fetch("http://localhost:8080/v1/chat/completions",{
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify({ model, messages: rm }),
})
.then((r)=>r.json())
.then((j)=>{
messages.push({
role: "user",
content: prompt,
});
messages.push(j.choices[0].message);
let hmsg = $("<div class='bg-lightblue border-radius-1 m-1 p-2 mr-4 bg-lightgray pre'></div>").html(markdown.makeHtml(j.choices[0].message.content));
$("#chat").append(hmsg);
hmsg.scrollIntoView();
console.log(j, messages);
})
}
$("#submit").on("click", chat);
</script>
</body>
</html>

2
markdown-it.min.js vendored 100644

File diff suppressed because one or more lines are too long

3
showdown.min.js vendored 100644

File diff suppressed because one or more lines are too long

164
transcribe.html 100644
View File

@ -0,0 +1,164 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="contrib/lnstyles/css/lnstyles.css">
<link rel="icon" type="image/svg+xml" href="/contrib/lnstyles/svg/ln.svg">
<script type="application/javascript" src="showdown.min.js"></script>
<title>ai.chat - local ai test chat</title>
</head>
<body class="p-4">
<div class="container-md bg-lightgray border-radius-4 h-100 display-flex flex-column">
<div class="flex-grow-0 bg-lightblue p-1">
<h1>AI.transcribe</h1>
</div>
<div class="flex-grow-0 p-1">
<button id="btnConnect" class="bg-white text-black">Connect</button>
<button id="btnTranscribe" class="bg-white text-black">Transcribe</button>
</div>
<div class="bg-white p-2 m-4 border-radius-1 overflow-auto flex-grow-1">
<div id="transcription" class=""></div>
</div>
</div>
<script type="module">
import { LNS } from "./contrib/lnstyles/js/lnstyles.js";
var $ = LNS;
const markdown = new showdown.Converter();
let config = await fetch("config.json").then((r)=>r.json);
class TranscriptionAPI extends EventTarget
{
constructor(url = undefined) {
super();
this._url = url || "wss://" + location.host + "/websocket";
this._ws = null;
this._connected = false;
this._audioRunning = false;
navigator.mediaDevices.getUserMedia({
audio: true,
channelCount: 1,
sampleRate: 16000,
})
.then((userMedia)=>{
this._userMedia = userMedia;
this._audioContext = new AudioContext();
this._audioSource = this._audioContext.createMediaStreamSource(this._userMedia);
this._sampleRate = this._audioContext.sampleRate;
this._processor = this._audioContext.createScriptProcessor(512, 1, 0);
this._processor.addEventListener("audioprocess", (event)=>{
if (this._connected) {
this._ws.send(event.inputBuffer.getChannelData(0).buffer);
}
});
});
}
async startAudio(){
if (this._connected){
if (!this._audioRunning) {
this._ws.send(JSON.stringify({ samplerate: this._sampleRate, }));
this._audioSource.connect(this._processor);
this._audioRunning = true;
this.fireRecording();
}
} else {
console.log("TranscriptionAPI must be connected to start audio");
}
}
stopAudio(){
if (this._audioRunning){
this._audioSource.disconnect();
this._audioRunning = false;
this.fireMute();
}
}
connect(){
if (this._ws){
console.log("TranscriptionAPI: already connected");
} else {
console.log("TranscriptionAPI: connecting");
this._ws = new WebSocket(this._url);
this._ws.addEventListener("open", (event) => {
console.log("TranscriptionAPI: connected");
this._connected = true;
this._ws.send(JSON.stringify({
command: "start",
}));
this.fireConnected();
});
this._ws.addEventListener("message", (event) => {
console.log(event);
let data = JSON.parse(event.data);
if (data.type && (data.type === "text")) {
$("#transcription").get(0).innerText += data.text;
}
});
this._ws.addEventListener("close", (event) => {
this._ws = null;
this._connected = false;
if (this._audioRunning)
this.stopAudio();
this.fireDisconnected();
});
}
}
disconnect(){
this._ws.close();
}
get connected(){ return this._connected; }
get audioRunning(){ return this._audioRunning; }
fireConnected(){ this.dispatchEvent(new Event("connect")); };
fireDisconnected(){ this.dispatchEvent(new Event("disconnect")); };
fireRecording(){ this.dispatchEvent(new Event("record")); };
fireMute(){ this.dispatchEvent(new Event("mute")); };
}
var tApi = new TranscriptionAPI("ws://localhost:8080");
tApi.addEventListener("connect", ()=>{
console.log("connected to transcription service.");
$("#btnConnect").addClass("bg-green");
});
tApi.addEventListener("disconnect", ()=>{
console.log("disconnected from transcription service.");
$("#btnConnect").removeClass("bg-green");
})
tApi.addEventListener("record", ()=>{
console.log("recording started.");
$("#btnTranscribe").addClass("bg-green");
})
tApi.addEventListener("mute", ()=>{
console.log("recording stopped.");
$("#btnTranscribe").removeClass("bg-green");
})
$("#btnConnect").on("click", ()=>{
if (tApi.connected)
tApi.disconnect();
else
tApi.connect();
});
$("#btnTranscribe").on("click", ()=>{
if (tApi.audioRunning)
tApi.stopAudio();
else
tApi.startAudio();
});
</script>
</body>
</html>