Files
2025-09-19 11:48:59 +02:00
..
2025-09-19 11:48:59 +02:00
2025-09-19 11:48:59 +02:00

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html><head>
<title>README.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">

<style>
/*

Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>

*/

.hljs {
  display: block;
  overflow-x: auto;
  padding: 0.5em;
  background: #FFFFFF;
}

.hljs,
.hljs-subst {
  color: #434f54;
}

.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-doctag,
.hljs-name {
  color: #00979D;
}

.hljs-built_in,
.hljs-literal,
.hljs-bullet,
.hljs-code,
.hljs-addition {
  color: #D35400;
}

.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
  color: #00979D;
}

.hljs-type,
.hljs-string,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
  color: #005C5F;
}

.hljs-title,
.hljs-section {
  color: #880000;
  font-weight: bold;
}

.hljs-comment {
  color: rgba(149,165,166,.8);
}

.hljs-meta-keyword {
  color: #728E00;
}

.hljs-meta {
  color: #434f54;
}

.hljs-emphasis {
  font-style: italic;
}

.hljs-strong {
  font-weight: bold;
}

.hljs-function {
  color: #728E00;
}

.hljs-number {
  color: #8A7B52;  
}

</style>

<style>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

body {
	font-family:   "HelveticaNeue-Light", sans-serif, "宋体","Segoe WPC", "Segoe UI", "SFUIText-Light","Droid Sans Fallback";
	font-size: 18px;
	padding: 0 12px;
	line-height: 1.6;
	word-wrap: break-word;
	color: #333333;
}

.content-wrapper{
	max-width: 860px;
    margin: 0 auto;
    padding: 0 30px;
}

#code-csp-warning {
	position: fixed;
	top: 0;
	right: 0;
	color: white;
	margin: 16px;
	text-align: center;
	font-size: 12px;
	font-family: sans-serif;
	background-color:#444444;
	cursor: pointer;
	padding: 6px;
	box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}

#code-csp-warning:hover {
	text-decoration: none;
	background-color:#007acc;
	box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}


body.scrollBeyondLastLine {
	margin-bottom: calc(100vh - 22px);
}

body.showEditorSelection .code-line {
	position: relative;
}

body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
	content: "";
	display: block;
	position: absolute;
	top: 0;
	left: -12px;
	height: 100%;
}

body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
	left: -30px;
}

.vscode-light.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(0, 0, 0, 0.15);
}

.vscode-light.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(0, 0, 0, 0.40);
}

.vscode-dark.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 255, 255, 0.4);
}

.vscode-dark.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 255, 255, 0.60);
}

.vscode-high-contrast.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 160, 0, 0.7);
}

.vscode-high-contrast.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 160, 0, 1);
}

img {
	max-width: 100%;
	max-height: 100%;
}

a {
	color: #4080D0;
	text-decoration: none;
}

a:focus,
input:focus,
select:focus,
textarea:focus {
	outline: 1px solid -webkit-focus-ring-color;
	outline-offset: -1px;
}

hr {
	border: 0;
	height: 2px;
	border-bottom: 2px solid;
}

h1 {
	padding-bottom: 0.3em;
	line-height: 1.2;
	border-bottom: 1px solid #eee;
}


h2{
	padding-bottom: .3em;
    font-size: 2em;
    line-height: 1.225;
    border-bottom: 1px solid #eee;
}

h3{
	font-size: 1.75em;
    line-height: 1.225;
}

h1, h2, h3 {
	font-weight: bold;
}

h1 code,
h2 code,
h3 code,
h4 code,
h5 code,
h6 code {
	font-size: inherit;
	line-height: auto;
}

a:hover {
	color: #4080D0;
	text-decoration: underline;
}

table {
	border-collapse: collapse;
}

table > thead > tr > th {
	text-align: left;
	border-bottom: 1px solid;
}

table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
	padding: 5px 10px;
}

table > tbody > tr + tr > td {
	border-top: 1px solid;
}

blockquote {
	margin: 0 7px 0 5px;
	padding: 0 16px 0 10px;
	border-left: 5px solid;
}

code {
	font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
	font-size: 14px;
	line-height: 19px;
}

body.wordWrap pre {
	white-space: pre-wrap;
}

.mac code {
	font-size: 12px;
	line-height: 18px;
}

pre:not(.hljs),
pre.hljs code > div {
	padding: 16px;
	border-radius: 3px;
	overflow: auto;
}

/** Theming */

.vscode-light,
.vscode-light pre code {
	color: rgb(30, 30, 30);
}

.vscode-dark,
.vscode-dark pre code {
	color: #DDD;
}

.vscode-high-contrast,
.vscode-high-contrast pre code {
	color: white;
}

.vscode-light code {
	color: #A31515;
}

.vscode-dark code {
	color: #D7BA7D;
}

.vscode-light pre:not(.hljs),
.vscode-light code > div {
	background-color: rgba(220, 220, 220, 0.4);
}

.vscode-dark pre:not(.hljs),
.vscode-dark code > div {
	background-color: rgba(10, 10, 10, 0.4);
}

.vscode-high-contrast pre:not(.hljs),
.vscode-high-contrast code > div {
	background-color: rgb(0, 0, 0);
}

.vscode-high-contrast h1 {
	border-color: rgb(0, 0, 0);
}

.vscode-light table > thead > tr > th {
	border-color: rgba(0, 0, 0, 0.69);
}

.vscode-dark table > thead > tr > th {
	border-color: rgba(255, 255, 255, 0.69);
}

.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
	border-color: rgba(0, 0, 0, 0.18);
}

.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
	border-color: rgba(255, 255, 255, 0.18);
}

.vscode-light blockquote,
.vscode-dark blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.vscode-high-contrast blockquote {
	background: transparent;
	border-color: #fff;
}
</style>

<style>
pre {
	background-color: #f8f8f8;
	border: 1px solid #cccccc;
	border-radius: 3px;
	overflow-x: auto;
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

pre:not(.hljs) {
	padding: 23px;
	line-height: 19px;
}

blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.emoji {
	height: 1.4em;
}

/* for inline code */
:not(pre):not(.hljs) > code {
	color: #C9AE75; /* Change the old color so it seems less like an error */
	font-size: inherit;
}

/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
	page-break-after: always;
}

.table-of-contents li{
	list-style-type: initial;
}
</style>

<style>
@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.2"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}

</style>

</head>
<body>
    <div class="content-wrapper">
        <h1 id="%F0%9F%8C%8D-nodemap-%E2%80%93-kartenvisualisierung-f%C3%BCr-talas.web-(next.js%2C-leaflet%2C-redux)" tabindex="-1">🌍 NodeMap  Kartenvisualisierung für TALAS.web (Next.js, Leaflet, Redux)</h1>
<p>NodeMap ist eine modulare Kartenanwendung zur Visualisierung und Bearbeitung von GIS-Daten, POIs und
Gerätestatus in einer interaktiven Leaflet-Karte.</p>
<blockquote>
<p>📘 Für Entwickler:<br>
Die technische Dokumentation (Architektur, Redux, Komponenten, etc.) befindet sich in:<br>
<a href="docs/README.md"><code>/docs/README.md</code></a></p>
</blockquote>
<h2 id="%F0%9F%8C%8D-live-vorschau-der-karte" tabindex="-1">🌍 Live-Vorschau der Karte</h2>
<p><img src="docs/screenshots/overview1.png" alt="Startansicht der NodeMap Karte"></p>
<hr>
<blockquote>
<p>🖥 Entwicklung &amp; Test unter Windows 11 mit Node.js v18.17.1 und IIS<br>
📦 MySQL 8.0 läuft lokal in einem Docker-Container (nur für Entwicklung)<br>
🗄 Produktionsumgebung: TALAS.web und MySQL Server unter Windows Server</p>
</blockquote>
<hr>
<h2 id="technologie-stack" tabindex="-1">Technologie-Stack</h2>
<table>
<thead>
<tr>
<th>Technologie</th>
<th>Zweck</th>
</tr>
</thead>
<tbody>
<tr>
<td>Next.js</td>
<td>React-Framework (Frontend/SSR)</td>
</tr>
<tr>
<td>Leaflet</td>
<td>Kartendarstellung</td>
</tr>
<tr>
<td>Redux Toolkit</td>
<td>Zustandverwaltung</td>
</tr>
<tr>
<td>Tailwind CSS</td>
<td>Styling</td>
</tr>
<tr>
<td>MySQL</td>
<td>Datenbank</td>
</tr>
<tr>
<td>Node.js / IIS</td>
<td>Server und Auslieferung</td>
</tr>
</tbody>
</table>
<h2 id="%F0%9F%A7%AD-zielumgebung" tabindex="-1">🧭 Zielumgebung</h2>
<ul>
<li>Windows-Produktionsserver (offline, kein Internet)</li>
<li>Kommunikation nur im lokalen Netzwerk</li>
<li>Nutzerzugriff per VPN + Remote Desktop (RDP)</li>
<li>Integration per iFrame in TALAS.web</li>
</ul>
<hr>
<h2 id="%F0%9F%94%84-wie-funktioniert-das-system%3F" tabindex="-1">🔄 Wie funktioniert das System?</h2>
<p>Die Anwendung wird von TALAS.web im iFrame geladen. Die URL enthält Parameter für Map- und
User-ID.<br>
NodeMap lädt anschließend Daten über WebServices und MySQL.<br>
➡ Details zur Architektur: <a href="docs/architecture.md">docs/architecture.md</a></p>
<hr>
<h2 id="%E2%9A%99%EF%B8%8F-kartenquellen-konfiguration-(public%2Fconfig.json)" tabindex="-1">⚙️ Kartenquellen-Konfiguration (public/config.json)</h2>
<p>Die Datei <code>public/config.json</code> steuert, welche Kartenquelle (z.B. OSM oder lokale Tiles) für die
Leaflet-Karte verwendet wird.</p>
<p><strong>Beispiel:</strong></p>
<pre class="hljs"><code><div><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">"//info"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"tileSources: 'local' für offline, 'osm' für online"</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">"tileSources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">"local"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"http://localhost/talas5/TileMap/mapTiles/{z}/{x}/{y}.png"</span><span class="hljs-punctuation">,</span>
    <span class="hljs-attr">"osm"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"</span>
  <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">"active"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"osm"</span>
<span class="hljs-punctuation">}</span>
</div></code></pre>
<ul>
<li>Mit <code>active</code> kann zwischen Online- und Offline-Karten umgeschaltet werden.</li>
<li>Die Datei wird beim Start der App automatisch geladen.</li>
<li>Für Offline-Betrieb muss das lokale Kartenmaterial vorhanden sein (siehe Installationsanleitung).</li>
</ul>
<hr>
<h2 id="%F0%9F%A7%B0-erstinstallation-auf-server" tabindex="-1">🧰 Erstinstallation auf Server</h2>
<h3 id="voraussetzungen" tabindex="-1">Voraussetzungen</h3>
<ul>
<li>Windows Server mit IIS</li>
<li>Sicherstellen, dass alle TALAS.web API-Endpunkte(WebService) erreichbar sind</li>
<li>Node.js &amp; npm installiert (z.B. v1820)</li>
<li>MySQL (lokal oder erreichbar)</li>
<li>Port 3000 freigegeben (Firewall)</li>
<li>IIS-Datei <code>mapTypC.aspx</code> vorhanden in C:\inetpub\wwwroot\talas5\MessagesMap\ 
(Server-IP mit Port 3000)</li>
<li>Browser: Chrome ab Version 125.0.6420.142 empfohlen</li>
<li>Karten Material vorhanden in: <code>C:\inetpub\wwwroot\talas5\TileMap\mapTiles</code>
<img src="docs/screenshots/mapTiles.png" alt="mapTiles"> Falls nicht vorhanden hier downloaden:
http://10.10.0.28/produkte/TALAS.map/mapTiles.zip</li>
</ul>
<hr>
<h2 id="%F0%9F%94%97-integration-in-talas.web" tabindex="-1">🔗 Integration in TALAS.web</h2>
<p><img src="docs/screenshots/iframe-in-talas2.png" alt="iFrame-Integration"></p>
<ul>
<li>Die App wird in einem <strong>iFrame</strong> geladen</li>
<li>Startet über <code>?m=X&amp;u=Y</code> für Map-/User-ID</li>
<li>Rechte und Inhalte werden automatisch geladen<pre class="hljs"><code><div>z.B.
`http://10.10.0.13/talas5/MessagesMap/mapTypC.aspx?m=12&amp;u=484`
</div></code></pre>
</li>
</ul>
<hr>
<h2 id="%F0%9F%AA%9B-schritt-f%C3%BCr-schritt%3A-nodemap-auf-dem-server-installieren" tabindex="-1">🪛 Schritt-für-Schritt: NodeMap auf dem Server installieren</h2>
<hr>
<h2 id="%F0%9F%93%A6-schnelles-deployment-%C3%BCber-zip-paket" tabindex="-1">📦 Schnelles Deployment über ZIP-Paket</h2>
<p>Ein fertiges Deployment-Bundle für jede Version (z.B. <code>NodeMap V1.1.260.zip</code>) ist auf dem internen
SharePoint verfügbar:</p>
<p>📁
<a href="https://littwinsystemtechnik.sharepoint.com/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Forms/AllItems.aspx?id=%2Fsites%2FLittwinSystemtechnik%2FFreigegebene%20Dokumente%2FProjekte%2FMasterkarte%20V2%20setup%20files&amp;csf=1&amp;web=1&amp;e=Sm1wwt&amp;CID=9291bb06%2Dc869%2D4e30%2D8efa%2D8cda40df3cd6&amp;FolderCTID=0x0120009C4F8227D6A11D4E89F1CCB9E517F488">Masterkarte V2 setup files</a></p>
<h4 id="%F0%9F%93%82-ablauf%3A" tabindex="-1">📂 Ablauf:</h4>
<ol>
<li>
<p>🛑 <strong>Dienst beenden</strong></p>
<ul>
<li>Vor dem Update muss der bestehende Windows-Dienst <code>NodeMapService</code> beendet werden,<br>
um Dateikonflikte beim Löschen zu vermeiden.
<img src="docs/screenshots/Dienst-beenden.png" alt="Dienst beenden"></li>
</ul>
</li>
<li>
<p>🔍 <strong>Prüfen, ob passende <code>node_modules-v1.1.xxx.zip</code> Datei vorhanden ist</strong></p>
<ul>
<li>Wenn <strong>nicht vorhanden</strong> → <code>C:\inetpub\wwwroot\talas5\nodeMap</code> komplett löschen</li>
<li>Wenn <strong>vorhanden</strong> → nur <code>node_modules-v1.1.xxx.zip</code> und <code>node_modules</code> Verzeichnis behalten,
Rest löschen<br>
💡 <strong>Tipp:</strong> <code>node_modules-v1.1.xxx.zip</code> nach Entpacken und in node_modules umbenennen!</li>
</ul>
</li>
<li>
<p>📦 <strong>ZIP entpacken</strong></p>
<ul>
<li><code>NodeMap V1.1.260.zip</code> entpacken<br>
Nach dem alles entpakt ist, dann sieht das so aus
<img src="docs/screenshots/nodeMap-inhalt.png" alt="NodeMap Inhalt"></li>
</ul>
</li>
<li>
<p>🚀 <strong>Dienst starten</strong></p>
<ul>
<li>Windows-Dienst <code>NodeMapService</code> wieder starten</li>
</ul>
</li>
</ol>
<hr>
<h2 id="%F0%9F%93%A6-oder-%C3%BCber-git" tabindex="-1">📦 Oder über Git</h2>
<ol>
<li>
<p><strong>Projekt lokal klonen und kompilieren:</strong></p>
<pre class="hljs"><code><div>git <span class="hljs-built_in">clone</span> http://10.10.0.12:3000/ISA/nodeMap
<span class="hljs-built_in">cd</span> nodeMap <span class="hljs-comment">#  zu den Verzeichnis wechseln</span>
npm install  <span class="hljs-comment"># Abhängigkeiten installieren (lädt alle Pakete aus package.json)</span>
npm run build  <span class="hljs-comment"># Erstellt ein optimiertes Produktions-Build im Ordner .next/</span>
</div></code></pre>
</li>
<li>
<p><strong>ZIP-Paket vorbereiten (lokal):</strong></p>
</li>
</ol>
<ul>
<li>Verzeichnis <code>.next/</code></li>
<li>Verzeichnisse <code>public/</code>, <code>node_modules/</code> falls auf dem Server nicht vorhanden sind oder etwas
hinzugefügt wurde (Bilder oder Bibliothek)</li>
<li>Dateien <code>.env.production</code>, <code>package.json</code> falls auf dem Server nicht vorhanden sind oder etwas
hinzugefügt wurde (Umgebungsvariablen oder Bibliothek)</li>
<li><code>nssm.exe</code>, <code>StartNodeApp.bat</code>, <code>Start-Dev.ps1</code> um Windows Dienst zu erstellen falls noch nicht
vorhanden ist Download:
<a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&amp;web=1&amp;e=Sm1wwt">nssm</a></li>
</ul>
<ol start="3">
<li>
<p><strong>Auf Server kopieren nach:</strong> Ein Ordner temp auf dem Desktop erstellen-&gt;ZIP-Paket
einfügen-&gt;entpacken-&gt;Inhalt in folgende Verzeichnis einfügen</p>
<pre class="hljs"><code><div>C:\inetpub\wwwroot\talas5\nodeMap\
</div></code></pre>
</li>
<li>
<p><strong>Kartenmaterial hinzufügen (falls nicht vorhanden):</strong></p>
<p>Muss noch in Download-Server eingefügt werden, damit eine zentrale Stelle verfügbar ist</p>
<pre class="hljs"><code><div>C:\inetpub\wwwroot\talas5\TileMap\
</div></code></pre>
</li>
<li>
<p><strong>.env.production konfigurieren</strong></p>
<p>Die Datei <code>.env.production</code> enthält alle benötigten Verbindungs- und Betriebsvariablen wie z.B.
Datenbank-Zugang, Pfade und Mock-Option.</p>
<p>➡ Vollständige Anleitung &amp; Beispieldatei: <a href="docs/guide/env.md">.env.production</a></p>
</li>
<li>
<p><strong>Dienst registrieren falls nicht vorhanden</strong></p>
</li>
</ol>
<ul>
<li>Mit <code>nssm.exe</code> Windows-Dienst „nodeMapService“ erstellen</li>
<li>Ziel: <code>StartNodeApp.bat</code></li>
<li>Anleitung:
<a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&amp;web=1&amp;e=Sm1wwt">nssm</a></li>
</ul>
<ol>
<li>
<p><strong>Starten:</strong> Dienst starten , falls vorhanden einmal beenden und neustarten</p>
</li>
<li>
<p><strong>Im Browser testen:</strong></p>
<pre class="hljs"><code><div>http://&lt;ip&gt;/talas5/MessagesMap/mapTypC.aspx?m=IdMap&amp;u=IdUser
z.B.
http://&lt;ip&gt;/talas5/MessagesMap/mapTypC.aspx?m=12&amp;u=484
</div></code></pre>
</li>
</ol>
<hr>
<h2 id="%F0%9F%94%81-update-richtlinien" tabindex="-1">🔁 Update-Richtlinien</h2>
<table>
<thead>
<tr>
<th>Art</th>
<th>Ersetzte Dateien</th>
<th>Bemerkung</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Kleines Update</strong></td>
<td><code>.next/</code></td>
<td><code>node_modules</code> nicht nötig</td>
</tr>
<tr>
<td><strong>Großes Update</strong></td>
<td>alle Dateien (wie Neuinstallation)</td>
<td>Dienst ggf. neu registrieren</td>
</tr>
</tbody>
</table>
<h3 id="empfohlener-ablauf-f%C3%BCr-kleines-update%3A" tabindex="-1">Empfohlener Ablauf für kleines Update:</h3>
<ol>
<li><code>.next/</code> Verzeichnis nach Kompilieren kopieren und auf dem Server einfügen</li>
<li>Dienst neu starten</li>
<li>Im Browser testen: <code> http://&lt;ip&gt;/talas5/MessagesMap/mapTypC.aspx?m=IdMap&amp;u=IdUser</code></li>
</ol>
<hr>
<h2 id="%E2%9C%85-tests-%26-qualit%C3%A4tssicherung" tabindex="-1">✅ Tests &amp; Qualitätssicherung</h2>
<ul>
<li><strong>E2E-Tests:</strong> Cypress (nur in der Entwicklungsumgebung)</li>
<li><strong>Unit-Tests:</strong> Aktuell keine Jest-Tests aufgrund Leaflet-Komplexität</li>
<li><strong>Empfehlung:</strong> Manuelle Tests nach jedem Deployment durchführen (Checkliste vorbereiten)</li>
</ul>
<hr>
<h2 id="%F0%9F%8F%B7-versionierung" tabindex="-1">🏷 Versionierung</h2>
<p>wird mit husky Bibliothek automatisch erhöht bei "git commit message"</p>
<p>→ Wird in der Fußzeile angezeigt. Die Version wird automatisch erhöht über ein Script
(<code>scripts/bumpVersion.js</code>), das per Husky vor jedem Commit ausgeführt wird.<br>
Die Version steht sowohl in <code>package.json</code> als auch in <code>config/appVersion.js</code>.</p>
<hr>
<h2 id="%F0%9F%92%BE-setup%3A-installationen-%26-tools" tabindex="-1">💾 Setup: Installationen &amp; Tools</h2>
<table>
<thead>
<tr>
<th>Tool</th>
<th>Version</th>
<th>Link</th>
</tr>
</thead>
<tbody>
<tr>
<td>Node.js</td>
<td>20.12.1</td>
<td><a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&amp;web=1&amp;e=Sm1wwt">nodejs</a></td>
</tr>
<tr>
<td>Chrome</td>
<td>optional</td>
<td><a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&amp;web=1&amp;e=Sm1wwt">Chrome</a></td>
</tr>
<tr>
<td>NSSM.exe</td>
<td>2.24</td>
<td><a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&amp;web=1&amp;e=Sm1wwt">nssm</a></td>
</tr>
</tbody>
</table>
<blockquote>
<p>Hinweis: Die Datei <code>MapTypC.aspx</code> in TALAS lädt NodeMap als iFrame über Port 3000.<br>
Wenn die Seite nicht angezeigt wird, bitte sicherstellen:</p>
<ul>
<li>Port 3000 ist in der Firewall freigegeben</li>
<li>Die IP im Scriptteil von <code>MapTypC.aspx</code> ist aktuell (z.B. <code>10.10.0.13</code>)</li>
<li>Windows-Dienst <code>NodeMapService</code> ist aktiv oder <code>npm start</code> in Terminal ausgeführt</li>
</ul>
</blockquote>
<h2 id="%F0%9F%93%81-dokumentation-%26-technische-leitf%C3%A4den" tabindex="-1">📁 Dokumentation &amp; technische Leitfäden</h2>
<table>
<thead>
<tr>
<th>Thema</th>
<th>Link</th>
</tr>
</thead>
<tbody>
<tr>
<td>Benutzeranleitung</td>
<td><a href="docs/guide/user-guide.md">docs/guide/user-guide.md</a></td>
</tr>
<tr>
<td>Architekturübersicht</td>
<td><a href="docs/architecture.md">architecture.md</a></td>
</tr>
<tr>
<td>Projektstruktur</td>
<td><a href="docs/guide/project-structure.md">project-structure.md</a></td>
</tr>
<tr>
<td>Webservices (TALAS)</td>
<td><a href="docs/guide/webservices.md">webservices.md</a></td>
</tr>
<tr>
<td>Umgebungsvariablen</td>
<td><a href="docs/guide/env.md">env.md</a></td>
</tr>
<tr>
<td>Mockdaten-Modus</td>
<td><a href="docs/guide/mock-data.md">mock-data.md</a></td>
</tr>
<tr>
<td>Zustandverwaltung (Redux)</td>
<td><a href="docs/guide/redux-zustand.md">redux-zustand.md</a></td>
</tr>
<tr>
<td>Abhängigkeiten</td>
<td><a href="docs/guide/dependencies.md">dependencies.md</a></td>
</tr>
<tr>
<td>Lokale Entwicklung</td>
<td><a href="docs/guide/setup-dev.md">setup-dev.md</a></td>
</tr>
<tr>
<td>FAQ &amp; Fehlerbehandlung</td>
<td><a href="docs/guide/faq.md">faq.md</a></td>
</tr>
<tr>
<td>Glossar</td>
<td><a href="docs/guide/glossar.md">faq.md</a></td>
</tr>
</tbody>
</table>

    </div>


</body></html>