Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fc7aea2c3 | ||
|
|
cf5e373303 | ||
|
|
d918c197ae | ||
|
|
6c9b06b983 | ||
|
|
38867d737c | ||
|
|
24dacde5a9 | ||
|
|
00be33abcc | ||
|
|
21ad1ceb30 | ||
|
|
2f1b79a86a | ||
|
|
1dcec632d8 | ||
|
|
7cd82c0954 | ||
|
|
3ae7bb13b8 | ||
|
|
2cd098e5a2 | ||
|
|
6b58d09ec9 | ||
|
|
c356167f97 | ||
|
|
f475f40350 | ||
|
|
ed2c0b9906 | ||
|
|
baf557f666 | ||
|
|
a885cd9550 | ||
|
|
c5806140ae | ||
|
|
c322bf1edf | ||
|
|
6c7b9a0032 | ||
|
|
5c5e64aac9 | ||
|
|
3e77bd3f49 | ||
|
|
b21be6c1d1 | ||
|
|
50c1e85931 | ||
|
|
c936a7f00c | ||
|
|
7936f3387b | ||
|
|
da7fd3f7eb | ||
|
|
451e19b3a1 | ||
|
|
cd9acfb9eb | ||
|
|
7828535330 | ||
|
|
e91c11346e | ||
|
|
e9211c0a92 | ||
|
|
2426cd56bc | ||
|
|
e955f3fc4f | ||
|
|
f65a30752f | ||
|
|
ce35a827c3 | ||
|
|
cdb30b2ea3 | ||
|
|
d823a35ac1 | ||
|
|
b00bf0c183 | ||
|
|
5ca16567d2 | ||
|
|
3370aa2caa | ||
|
|
a2b463d491 | ||
|
|
c623e6f9d6 | ||
|
|
34172beb12 | ||
|
|
3367fea887 | ||
|
|
acf2deaea3 | ||
|
|
6985789ef7 | ||
|
|
75a26bda91 | ||
|
|
2efeba53f2 | ||
|
|
3b5f77b95e | ||
|
|
72d02ee501 | ||
|
|
b2577c249a | ||
|
|
12a7bc895c | ||
|
|
a1a85e4743 | ||
|
|
688ad6e2cf | ||
|
|
f8fc579c6f | ||
|
|
778d1f2929 | ||
|
|
7927009320 | ||
|
|
4036beca67 | ||
|
|
4a81288194 | ||
|
|
5739309790 | ||
|
|
72ee23c158 | ||
|
|
7489f4288c | ||
|
|
62b63ff196 | ||
|
|
fd7a5a03ca | ||
|
|
5b6dc89bb5 | ||
|
|
5d11cf5541 | ||
|
|
a385afacf9 | ||
|
|
f115c02ed5 | ||
|
|
e54f22a25c | ||
|
|
eda043f0c6 | ||
|
|
0526e28413 | ||
|
|
017583b8c8 | ||
|
|
6ec63fb1ec | ||
|
|
e3547acc13 | ||
|
|
fe8fc15363 | ||
|
|
9f316103e9 | ||
|
|
490de9179b | ||
|
|
8e7c8112a3 | ||
|
|
bcb589d15e | ||
|
|
16416a0239 | ||
|
|
73de568a05 | ||
|
|
f474ba8ea0 | ||
|
|
141a2ab609 | ||
|
|
a51aa72cc9 | ||
|
|
864b3f27d9 | ||
|
|
5a14dd3f10 | ||
|
|
42583441cc | ||
|
|
5b04511a91 | ||
|
|
64ff587b2c | ||
|
|
e797e9e8dd | ||
|
|
5bf1292c21 | ||
|
|
2a541fcdb1 | ||
|
|
64722b9dd2 | ||
|
|
34a9abfe23 | ||
|
|
7964b5e15c | ||
|
|
69655e8ef6 | ||
|
|
42356cfd31 | ||
|
|
707e3bebe9 | ||
|
|
bc06824ab6 | ||
|
|
36c0c2c7ea | ||
|
|
c41a126ea6 | ||
|
|
7e46647b86 | ||
|
|
11044693c9 | ||
|
|
29d4c7504f | ||
|
|
d83afa36d9 | ||
|
|
b9eb9f8f70 | ||
|
|
2c4aba89a9 | ||
|
|
87773ffa50 | ||
|
|
ff82f5a054 | ||
|
|
b8fe2dfafe | ||
|
|
588960732e | ||
|
|
7fd7301202 | ||
|
|
80c664c78a | ||
|
|
df640e0af2 | ||
|
|
19dc8aed74 | ||
|
|
e3d489e247 | ||
|
|
ebe9ab0e34 | ||
|
|
a064006966 | ||
|
|
7e6ec5b9ef | ||
|
|
1fe62103a8 | ||
|
|
fc5c2ad59e | ||
|
|
31a58172b5 | ||
|
|
723c95a3f9 | ||
|
|
7763aa89dc | ||
|
|
68ec935f9a | ||
|
|
7d06d95ab6 | ||
|
|
c1af899035 | ||
|
|
057001ad03 | ||
|
|
e8c2fc145f | ||
|
|
7e1d20d0ec | ||
|
|
1bd81120cc | ||
|
|
7ba49fc673 | ||
|
|
6c4bc185b3 | ||
|
|
2a2bdc3c63 | ||
|
|
6f4f54522c | ||
|
|
967bd5c7ea | ||
|
|
0987345152 | ||
|
|
78b97c124a | ||
|
|
643fdfc410 | ||
|
|
c388855bf9 | ||
|
|
c612d6d873 | ||
|
|
4582633d83 | ||
|
|
39962434d0 | ||
|
|
5a688bc7ea | ||
|
|
4dec8a5680 | ||
|
|
7b234167fa | ||
|
|
6972ee5e4f | ||
|
|
af025ac50c | ||
|
|
366a821a0e | ||
|
|
02b3745b88 | ||
|
|
58bdd6018f | ||
|
|
7a4748b549 | ||
|
|
8c7380fde9 | ||
|
|
9dad0f06a2 | ||
|
|
635c23d5e8 | ||
|
|
102a818a83 | ||
|
|
9e243cbaf2 | ||
|
|
ef9a956a2c |
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
|
"terminal.explorerKind": "external",
|
||||||
|
"terminal.external.osxExec": "iTerm.app",
|
||||||
|
"terminal.external.windowsExec": "wt.exe",
|
||||||
"workbench.iconTheme": "vscode-icons",
|
"workbench.iconTheme": "vscode-icons",
|
||||||
"workbench.colorTheme": "One Dark Pro",
|
"workbench.colorTheme": "One Dark Pro",
|
||||||
"prettier.printWidth": 120,
|
"prettier.printWidth": 120,
|
||||||
|
|||||||
@@ -280,15 +280,31 @@ Projektarbeit + Wetter API Key besorgen
|
|||||||
**Inhalt:**
|
**Inhalt:**
|
||||||
|
|
||||||
- XML-HttpRequest und AJAX mit jQuery
|
- XML-HttpRequest und AJAX mit jQuery
|
||||||
|
- Node Module für die Projekt-Entwicklungsumgebung
|
||||||
- Wetter API auslesen
|
- Wetter API auslesen
|
||||||
- Node Standardbib (fs, zlib (stream), Crypto)
|
|
||||||
- fetch in der Praxis: Joke API auslesen
|
- fetch in der Praxis: Joke API auslesen
|
||||||
- Abschluss von JS für Fortgeschrittene
|
- Was ist Node.js? (Wiederholung)
|
||||||
- Projektvorstellung 1 + 2
|
|
||||||
|
|
||||||
**Übungen:**
|
**Übungen:**
|
||||||
|
|
||||||
Projektarbeit
|
Projektarbeit
|
||||||
|
Übungen Public API auslesen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 18
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Node Standardbib (fs, zlib (stream), Crypto)
|
||||||
|
- Import vs. require (Teil II)
|
||||||
|
- NPM Befehle
|
||||||
|
- Abschluss von JS für Fortgeschrittene
|
||||||
|
- Projektvorstellung 1 + 2 JS Advanced
|
||||||
|
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
Übungen 25 - 31
|
Übungen 25 - 31
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -297,23 +313,12 @@ Projektarbeit
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### Tag 18
|
|
||||||
|
|
||||||
**Inhalt:**
|
|
||||||
|
|
||||||
- Einführung in JS DOM
|
|
||||||
- DOM Selection (querySelector, querySelectorAll)
|
|
||||||
- $ & $$ Helper
|
|
||||||
- CSS Selektoren
|
|
||||||
|
|
||||||
**Übungen:**
|
|
||||||
|
|
||||||
Übungen 01 - 05
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### Tag 19
|
#### Tag 19
|
||||||
|
|
||||||
|
- Einführung in JS DOM
|
||||||
|
- DOM Selection (querySelector, querySelectorAll, $ & $$ Helper)
|
||||||
|
- CSS Selektoren
|
||||||
- Defer & Async
|
- Defer & Async
|
||||||
- JS Dateien auslagern
|
- JS Dateien auslagern
|
||||||
- Chat Gestaltung (DOMTokenList Objekt)
|
- Chat Gestaltung (DOMTokenList Objekt)
|
||||||
@@ -322,7 +327,7 @@ Projektarbeit
|
|||||||
|
|
||||||
**Übungen:**
|
**Übungen:**
|
||||||
|
|
||||||
Übungen 06 - 07
|
Übungen 01 - 06
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -337,4 +342,4 @@ Projektarbeit
|
|||||||
|
|
||||||
**Übungen:**
|
**Übungen:**
|
||||||
|
|
||||||
Übung 08 - 10
|
Übung 07 - 10
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
## NVM - Node Version Manager
|
||||||
|
|
||||||
|
nvm ist ein Versionsmanager für node.js. Über nvm können mehrere unterschiedliche Node Versionen installiert werden. NVM wird über die Konsole aufgerufen und ist mit verschiedenen Shells kompatibel (sh, dash, ksh, zsh, bash).
|
||||||
|
|
||||||
|
#### Links
|
||||||
|
|
||||||
|
- <https://github.com/coreybutler/nvm-windows> (Win)
|
||||||
|
- <https://github.com/nvm-sh/nvm> (Mac OS)
|
||||||
|
|
||||||
|
#### Installation Windows
|
||||||
|
|
||||||
|
1. Lade den NVM-Installer über folgenden Link herunter: <https://github.com/coreybutler/nvm-windows/releases>
|
||||||
|
2. Installiere NVM über den [Installer](https://github.com/coreybutler/nvm-windows/releases/download/1.2.2/nvm-setup.zip)
|
||||||
|
3. Sollte vorher bereits NodeJS global ohne NVM installiert worden sein, wird empfohlen die vorherige NodeJS Version zu [deinstallieren](https://stackoverflow.com/a/55300310).
|
||||||
|
|
||||||
|
### Installation Mac OS
|
||||||
|
|
||||||
|
- Installiere NVM über die Konsole mit:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
- Füge den Pfad zum NVM Ordner zur Shell-Config hinzu. (`~/.bash_profile`, `~/.zshrc`, `~/.profile`, or `~/.bashrc`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||||
|
```
|
||||||
|
|
||||||
|
- Aktuelle Informationen zur Installation findet man unter folgendem Link: <https://github.com/nvm-sh/nvm>
|
||||||
|
|
||||||
|
#### Erste Schritte
|
||||||
|
|
||||||
|
Sobald NVM erfolgreich installiert wurde kann man über nvm in der Konsole eine neue Node Version mit folgendem Befehl installieren:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nvm install [NODE VERSIONSNUMMER]
|
||||||
|
```
|
||||||
|
|
||||||
|
> Hinweis: Die aktuellste Versionsnummer von NodeJS findet man am einfachsten auf der [NodeJS-Seite](https://nodejs.org/en/)
|
||||||
|
|
||||||
|
Installierte Node Versionen auflisten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nvm list
|
||||||
|
```
|
||||||
|
|
||||||
|
Node Version verwenden/wechseln
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nvm use [NODE VERSIONSNUMMER]
|
||||||
|
```
|
||||||
|
|
||||||
|
Node Version als Standard einrichten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nvm alias default [NODE VERSIONSNUMMER]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Node.js
|
||||||
|
|
||||||
|
### Definition
|
||||||
|
|
||||||
|
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
|
||||||
|
|
||||||
|
## Neues Projekt erstellen
|
||||||
|
|
||||||
|
- Über die Konsole in den Projektordner gehen.
|
||||||
|
|
||||||
|
Projektordner wechsel über "change directory" (cd)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd [projektpfad]
|
||||||
|
```
|
||||||
|
|
||||||
|
- Eigene Package.json Datei generieren (nur einmalig bei einem neuen Projekt notwendig.)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm init
|
||||||
|
```
|
||||||
|
|
||||||
|
- Module installieren, die nur für die Entwicklung benötigt werden. (devDependicies)
|
||||||
|
|
||||||
|
| Befehl | Zweck |
|
||||||
|
| ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `npm install Modul@Version` | installiere Modul in der Version Version (semantic versioning) |
|
||||||
|
| `npm install Modul@Version --save`<br>`npm install Modul@Version -S` | Modul wird in der Datei `package.json` unter dependencies hinzugefügt (Mittlerweile default) |
|
||||||
|
| `npm install Modul@Version --save-dev`<br>`npm install Modul@Version -D` | Modul wird in der Datei `package.json` unter devdependencies hinzugefügt |
|
||||||
|
| `npm install Modul@Version --global`<br>`npm install Modul@Version -g` | Modul wird global installiert. (Von jedem Ordner aus anwendbar) |
|
||||||
|
| `npm uninstall Modul@Version` | entfernt Modul aus `node_modules` |
|
||||||
|
| `npm uninstall Modul@Version --save` | entfernt Modul aus `node_modules` und aus der dependencies- Eigenschaft in der `package.json`. |
|
||||||
|
| `npm update Modul` | Aktualisiert Modul auf die neueste Version |
|
||||||
|
| `npm update Modul --save` | Aktualisiert Modul auf die neueste Version und auch die Versionsnummer der dependencies- Eigenschaft in der `package.json`. |
|
||||||
|
| `npm init` | erstellt eine package.json-Datei (der Befehl fragt die Eigenschaften ab) |
|
||||||
|
| `npm init --yes` | erstellt eine package.json-Datei (der Befehl setzt Default-Werte ein) |
|
||||||
|
| `npm list` | listet alle installierten Module auf. |
|
||||||
|
| `npm search` | Suchbegriff sucht Module, deren Namen den Suchbegriff enthält |
|
||||||
|
|
||||||
|
# Globale Module
|
||||||
|
|
||||||
|
## SASS
|
||||||
|
|
||||||
|
### Definition
|
||||||
|
|
||||||
|
> Sass is the most mature, stable, and powerful professional grade CSS extension language in the world.
|
||||||
|
|
||||||
|
Sass ist eine CSS-Preprocessor Sprache.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install sass -g
|
||||||
|
```
|
||||||
|
|
||||||
|
## Liste von verwendeten Modulen
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
## License and terms of use
|
||||||
|
|
||||||
|
© Web Professional Institute Inc. All rights reserved.
|
||||||
|
|
||||||
|
This material is provided solely for students enrolled in courses offered by Web Professional Institute Inc. By accessing or using this code, you acknowledge that it is strictly for educational use within the context of Web Professional Institute Inc. programs.
|
||||||
|
|
||||||
|
**Usage Restrictions:**
|
||||||
|
|
||||||
|
- Redistribution, sharing, or copying of this material outside the course environment is strictly prohibited.
|
||||||
|
- The content is designed to support your learning objectives and is not authorized for commercial projects, public repositories, or applications beyond the course scope.
|
||||||
|
- Unauthorized commercial use or open-source distribution is strictly prohibited and may result in expulsion from the program and legal action.
|
||||||
|
|
||||||
|
**Agreement & Rights:**
|
||||||
|
|
||||||
|
As a student, you have agreed to these terms as part of your enrollment agreement, which includes additional details on permitted uses, restrictions, and policies. The author and Web Professional Institute Inc. retain all rights to this material, including the code base and instructional content.
|
||||||
|
|
||||||
|
For any questions regarding these terms, please contact Web Professional Institute Inc. for clarification.
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Recipe Explorer Dashboard</title>
|
||||||
|
<link rel="stylesheet" href="styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Recipe Explorer Dashboard</h1>
|
||||||
|
|
||||||
|
<div id="search-container">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="search-input"
|
||||||
|
placeholder="Search for recipes by name..."
|
||||||
|
/>
|
||||||
|
<button id="search-button">Search</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="loading">Loading...</div>
|
||||||
|
<div id="error-message"></div>
|
||||||
|
|
||||||
|
<table id="recipes-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Recipe Name</th>
|
||||||
|
<th>Cuisine</th>
|
||||||
|
<th>Preparation Time (mins)</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- Recipe data will be populated here -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- Modal for Recipe Details -->
|
||||||
|
<div id="recipe-modal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close">×</span>
|
||||||
|
<h2 id="modal-title">Recipe Name</h2>
|
||||||
|
<img
|
||||||
|
id="modal-image"
|
||||||
|
src=""
|
||||||
|
alt="Recipe Image"
|
||||||
|
style="border-radius: 10px; max-height: 200px"
|
||||||
|
/>
|
||||||
|
<p><strong>Cuisine:</strong> <span id="modal-category"></span></p>
|
||||||
|
<p>
|
||||||
|
<strong>Preparation Time:</strong> <span id="modal-time"></span> mins
|
||||||
|
</p>
|
||||||
|
<p><strong>Ingredients:</strong></p>
|
||||||
|
<ul id="modal-ingredients">
|
||||||
|
<!-- Ingredients will be populated here -->
|
||||||
|
</ul>
|
||||||
|
<p><strong>Instructions:</strong></p>
|
||||||
|
<p id="modal-instructions"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="scripts.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
(() => {
|
||||||
|
// ===== DOM & VARIABLES =====
|
||||||
|
const RECIPES_URL = 'https://dummyjson.com/recipes';
|
||||||
|
|
||||||
|
const searchInput = document.querySelector('#search-input');
|
||||||
|
const searchButton = document.querySelector('#search-button');
|
||||||
|
const recipesTableBody = document.querySelector('#recipes-table tbody');
|
||||||
|
const loadingIndicator = document.querySelector('#loading');
|
||||||
|
const errorMessage = document.querySelector('#error-message');
|
||||||
|
|
||||||
|
const modal = document.querySelector('#recipe-modal');
|
||||||
|
const modalTitle = document.querySelector('#modal-title');
|
||||||
|
const modalImage = document.querySelector('#modal-image');
|
||||||
|
const modalCategory = document.querySelector('#modal-category');
|
||||||
|
const modalTime = document.querySelector('#modal-time');
|
||||||
|
const modalIngredients = document.querySelector('#modal-ingredients');
|
||||||
|
const modalInstructions = document.querySelector('#modal-instructions');
|
||||||
|
const closeModal = document.querySelector('.close');
|
||||||
|
|
||||||
|
let allRecipes = [];
|
||||||
|
|
||||||
|
// ===== INIT =====
|
||||||
|
const init = () => {
|
||||||
|
// TODO: Fetch and display all recipes on initial load
|
||||||
|
|
||||||
|
// Event Listeners
|
||||||
|
closeModal.addEventListener('click', closeModalEvent);
|
||||||
|
window.addEventListener('click', windowClickEvent);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===== EVENT LISTENERS =====
|
||||||
|
const searchButtonEvent = () => {
|
||||||
|
const query = searchInput.value.trim().toLowerCase();
|
||||||
|
if (query !== '') {
|
||||||
|
// TODO: Implement search functionality
|
||||||
|
} else {
|
||||||
|
// TODO: Display all recipes if search input is empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Close Modal Event
|
||||||
|
const closeModalEvent = () => {
|
||||||
|
modal.style.display = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Close Modal when clicking outside the modal content
|
||||||
|
const windowClickEvent = (event) => {
|
||||||
|
if (event.target == modal) {
|
||||||
|
modal.style.display = 'none';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===== FUNCTIONS =====
|
||||||
|
// Fetches all recipes from the API and displays them.
|
||||||
|
const fetchAndDisplayRecipes = async () => {
|
||||||
|
showLoading(true);
|
||||||
|
showError(false, '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: Fetch data from API
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
showError(true, 'An error occurred while fetching recipes.');
|
||||||
|
} finally {
|
||||||
|
showLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Searches for recipes by name and displays the results.
|
||||||
|
const searchRecipes = async (query) => {
|
||||||
|
showLoading(true);
|
||||||
|
showError(false, '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: Search for recipes by name
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
showError(true, 'An error occurred while searching for recipes.');
|
||||||
|
} finally {
|
||||||
|
showLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Displays a list of recipes in the table.
|
||||||
|
const displayRecipes = (recipes) => {
|
||||||
|
clearTable();
|
||||||
|
|
||||||
|
// TODO: Iterate over the recipes and display them in the table
|
||||||
|
};
|
||||||
|
|
||||||
|
// Displays detailed information about a selected recipe in a modal.
|
||||||
|
const showRecipeDetails = (recipe) => {
|
||||||
|
// TODO: Calculate total preparation time
|
||||||
|
// TODO: Set image source
|
||||||
|
// TODO: Populate ingredients
|
||||||
|
// TODO: Show modal
|
||||||
|
};
|
||||||
|
|
||||||
|
// Shows or hides the loading indicator.
|
||||||
|
const showLoading = (show) => {
|
||||||
|
loadingIndicator.style.display = show ? 'block' : 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Displays or hides an error message.
|
||||||
|
const showError = (show, message) => {
|
||||||
|
if (show) {
|
||||||
|
errorMessage.textContent = message;
|
||||||
|
errorMessage.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
errorMessage.textContent = '';
|
||||||
|
errorMessage.style.display = 'none';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clears the recipes table.
|
||||||
|
const clearTable = () => {
|
||||||
|
recipesTableBody.innerHTML = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===== CALL INIT =====
|
||||||
|
init();
|
||||||
|
})();
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
color: #4d7c0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-container {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-input {
|
||||||
|
width: 300px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: 2px solid #65a30d;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #4d7c0f;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-button:hover {
|
||||||
|
background-color: #65a30d;
|
||||||
|
transition: 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#recipes-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
max-width: 1000px;
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#recipes-table th,
|
||||||
|
#recipes-table td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 12px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#recipes-table th {
|
||||||
|
background-color: #4d7c0f;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#recipes-table tr:nth-child(even) {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#recipes-table tr:hover {
|
||||||
|
background-color: #ecfccb;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modal styling */
|
||||||
|
.modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
padding-top: 100px;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
width: 60%;
|
||||||
|
border-radius: 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: #aaa;
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
right: 25px;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loading Indicator */
|
||||||
|
#loading {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #4d7c0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error Message */
|
||||||
|
#error-message {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
color: red;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
## License and terms of use
|
||||||
|
|
||||||
|
© Web Professional Institute Inc. All rights reserved.
|
||||||
|
|
||||||
|
This material is provided solely for students enrolled in courses offered by Web Professional Institute Inc. By accessing or using this code, you acknowledge that it is strictly for educational use within the context of Web Professional Institute Inc. programs.
|
||||||
|
|
||||||
|
**Usage Restrictions:**
|
||||||
|
|
||||||
|
- Redistribution, sharing, or copying of this material outside the course environment is strictly prohibited.
|
||||||
|
- The content is designed to support your learning objectives and is not authorized for commercial projects, public repositories, or applications beyond the course scope.
|
||||||
|
- Unauthorized commercial use or open-source distribution is strictly prohibited and may result in expulsion from the program and legal action.
|
||||||
|
|
||||||
|
**Agreement & Rights:**
|
||||||
|
|
||||||
|
As a student, you have agreed to these terms as part of your enrollment agreement, which includes additional details on permitted uses, restrictions, and policies. The author and Web Professional Institute Inc. retain all rights to this material, including the code base and instructional content.
|
||||||
|
|
||||||
|
For any questions regarding these terms, please contact Web Professional Institute Inc. for clarification.
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const menu = [
|
||||||
|
{
|
||||||
|
category: 'Beverages',
|
||||||
|
items: [
|
||||||
|
{ name: 'Coffee', price: 3.5 },
|
||||||
|
{ name: 'Tea', price: 2.5 },
|
||||||
|
{ name: 'Juice', price: 4 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'Pastries',
|
||||||
|
items: [
|
||||||
|
{ name: 'Croissant', price: 2.75 },
|
||||||
|
{ name: 'Muffin', price: 2.5 },
|
||||||
|
{ name: 'Bagel', price: 2.25 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'Sandwiches',
|
||||||
|
items: [
|
||||||
|
{ name: 'Ham Sandwich', price: 5.5 },
|
||||||
|
{ name: 'Veggie Sandwich', price: 5 },
|
||||||
|
{ name: 'Turkey Sandwich', price: 6 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// ADD YOUR CODE BELOW
|
||||||
|
const listMenuItems = (menu) => {};
|
||||||
|
|
||||||
|
const calculateAveragePrice = (menu) => {};
|
||||||
|
|
||||||
|
const findItemsByCategory = (menu, categoryName) => {};
|
||||||
|
|
||||||
|
// ===== TEST CASES (DO NOT MODIFY) =====
|
||||||
|
|
||||||
|
// 1. List All Menu Items
|
||||||
|
const menuItems = listMenuItems(menu);
|
||||||
|
console.log('All Menu Items:\n', menuItems);
|
||||||
|
|
||||||
|
// 2. Calculate Average Price
|
||||||
|
const averagePrice = calculateAveragePrice(menu);
|
||||||
|
console.log('Average Price of All Items:', averagePrice);
|
||||||
|
|
||||||
|
// 3. Find Items by Category
|
||||||
|
const searchCategory = 'Pastries';
|
||||||
|
const pastries = findItemsByCategory(menu, searchCategory);
|
||||||
|
console.log(`Items in "${searchCategory}" \nItems:`, pastries);
|
||||||
|
|
||||||
|
/*
|
||||||
|
===== EXPECTED OUTPUT =====
|
||||||
|
|
||||||
|
All Menu Items:
|
||||||
|
[
|
||||||
|
'Coffee',
|
||||||
|
'Tea',
|
||||||
|
'Juice',
|
||||||
|
'Croissant',
|
||||||
|
'Muffin',
|
||||||
|
'Bagel',
|
||||||
|
'Ham Sandwich',
|
||||||
|
'Veggie Sandwich',
|
||||||
|
'Turkey Sandwich'
|
||||||
|
]
|
||||||
|
|
||||||
|
Average Price of All Items: 3.78
|
||||||
|
|
||||||
|
Items in "Pastries"
|
||||||
|
Items: [
|
||||||
|
{ name: 'Croissant', price: 2.75 },
|
||||||
|
{ name: 'Muffin', price: 2.5 },
|
||||||
|
{ name: 'Bagel', price: 2.25 }
|
||||||
|
]
|
||||||
|
*/
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>GeoLocation API auslesen</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<div class="container py-5">
|
||||||
|
<h1>GeoLocation API auslesen</h1>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
// === DOM & VARS =======
|
||||||
|
const DOM = {};
|
||||||
|
|
||||||
|
// === INIT =============
|
||||||
|
const init = () => {
|
||||||
|
getGeoLocation().then((dataGeolocation) => {
|
||||||
|
// console.log('Geo Location:' + dataGeolocation);
|
||||||
|
console.log(setGeoLocation(dataGeolocation));
|
||||||
|
// getWeather().then((data) => {
|
||||||
|
// console.log('Weather Data:' + data);
|
||||||
|
// setWeather(data);
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
|
||||||
|
getCoordinates().then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// === EVENTHANDLER =====
|
||||||
|
|
||||||
|
// === XHR/FETCH ========
|
||||||
|
|
||||||
|
// === FUNCTIONS ========
|
||||||
|
const setGeoLocation = (data) => {
|
||||||
|
const { longitude, latitude } = data;
|
||||||
|
console.log(`LON: ${data.longitude} LAT: ${data.latitude}`);
|
||||||
|
return { longitude, latitude };
|
||||||
|
};
|
||||||
|
|
||||||
|
const getGeoLocation = async () => {
|
||||||
|
try {
|
||||||
|
const res = await fetch('https://myiprightnow.com/api/ip');
|
||||||
|
if (!res.ok) {
|
||||||
|
throw Error('Fetch Error Geolocation');
|
||||||
|
}
|
||||||
|
const data = await res.json();
|
||||||
|
console.log(data);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCoordinates = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Prüfen, ob der Browser Geolocation unterstützt
|
||||||
|
if (!navigator.geolocation) {
|
||||||
|
reject(new Error('Geolocation wird von diesem Browser nicht unterstützt.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionen für die Abfrage (optional)
|
||||||
|
const options = {
|
||||||
|
enableHighAccuracy: true, // Bestmögliche Genauigkeit erzwingen
|
||||||
|
timeout: 5000, // Max. Wartezeit in Millisekunden
|
||||||
|
maximumAge: 0, // Kein Cache, frische Daten anfordern
|
||||||
|
};
|
||||||
|
|
||||||
|
// Erfolg-Callback
|
||||||
|
const success = (position) => {
|
||||||
|
const { latitude, longitude } = position.coords;
|
||||||
|
resolve({ latitude, longitude });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fehler-Callback
|
||||||
|
const error = (err) => {
|
||||||
|
reject(new Error(`Standortabfrage fehlgeschlagen: ${err.message}`));
|
||||||
|
};
|
||||||
|
|
||||||
|
// API-Aufruf starten
|
||||||
|
// https://developer.mozilla.org/de/docs/Web/API/Geolocation/getCurrentPosition
|
||||||
|
navigator.geolocation.getCurrentPosition(success, error, options);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
init();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// Übung 25
|
||||||
|
const quotedCSV = '"very big, soft computer mouse","the cutest peripheral ever","10","39.90"';
|
||||||
|
|
||||||
|
// Übung 26
|
||||||
|
// In der Praxis finden sich auch CSV-Datensätze, in denen manche Felder mit Anführungszeichen umgeben sind und manche nicht.
|
||||||
|
|
||||||
|
// Schreibe ein Programm, das auch mit diesen Fällen zurechtkommt. Folgender Datensatz soll korrekt zerlegt werden:
|
||||||
|
|
||||||
|
const mixedCSV = '"very big, soft computer mouse","the cutest peripheral ever",10,39.90';
|
||||||
|
|
||||||
|
const parseCSVRecord = (record) => {
|
||||||
|
const fields = [];
|
||||||
|
let field = '';
|
||||||
|
let inQuotes = false;
|
||||||
|
|
||||||
|
for (const character of record) {
|
||||||
|
if (character === '"') {
|
||||||
|
inQuotes = !inQuotes;
|
||||||
|
} else if (character === ',' && !inQuotes) {
|
||||||
|
fields.push(field);
|
||||||
|
field = '';
|
||||||
|
} else {
|
||||||
|
field += character;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fields.push(field);
|
||||||
|
return fields;
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(parseCSVRecord(quotedCSV));
|
||||||
|
console.log(parseCSVRecord(mixedCSV));
|
||||||
|
/*
|
||||||
|
Übung 25: CSV-Datensätze mit Anführungszeichen
|
||||||
|
Bisher haben wir die Felder in einem CSV-Datensatz einfach mit der Anweisung:
|
||||||
|
|
||||||
|
|
||||||
|
record.split(',')
|
||||||
|
|
||||||
|
|
||||||
|
in einzelne Felder zerlegt. In der Praxis kann es aber vorkommen, dass ein einzelnes Feld ein Komma enthält. Das Problem wird üblicherweise gelöst, indem die einzelnen Felder noch mit Anführungszeichen umgeben werden. Hier ist ein Beispiel:
|
||||||
|
|
||||||
|
'very big, soft computer mouse', 'the cutest peripheral ever', '10', '39.90'
|
||||||
|
|
||||||
|
|
||||||
|
Das erste Feld enthält ein Komma (very big, soft computer mouse), trotzdem ist die Unterteilung eindeutig. Schreibe ein kurzes Programm, das diesen Datensatz korrekt zerlegt und die einzelnen Felder ausgibt:
|
||||||
|
|
||||||
|
|
||||||
|
const quotedCSV =
|
||||||
|
'"very big, soft computer mouse","the cutest peripheral ever","10","39.90"'
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Übung 26: CSV-Datensätze mit Anführungszeichen — Teil 2
|
||||||
|
In der Praxis finden sich auch CSV-Datensätze, in denen manche Felder mit Anführungszeichen umgeben sind und manche nicht.
|
||||||
|
|
||||||
|
Schreibe ein Programm, das auch mit diesen Fällen zurechtkommt. Folgender Datensatz soll korrekt zerlegt werden:
|
||||||
|
|
||||||
|
const mixedCSV =
|
||||||
|
'"very big, soft computer mouse","the cutest peripheral ever",10,39.90'
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Regex Beispiel
|
||||||
|
|
||||||
|
Am besten löst man das mit einem regulären Ausdruck, der entweder nach **Inhalten in Anführungszeichen** sucht _oder_ nach **Inhalten ohne Kommas**.
|
||||||
|
|
||||||
|
Hier ist der passende Reguläre Ausdruck:
|
||||||
|
|
||||||
|
`/"([^"\\]*(?:\\.[^"\\]*)*)"|([^,]+)/g`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Wie der Regex funktioniert
|
||||||
|
|
||||||
|
Der Ausdruck nutzt das **ODER-Prinzip (`|`)**, um zwei Szenarien zu matchen:
|
||||||
|
|
||||||
|
1. **`"([^"\\]*(?:\\.[^"\\]*)*)"` (Gruppe 1):** Matcht alles, was in doppelten Anführungszeichen steht. Er erlaubt sogar escaped Anführungszeichen (`\"`) im Text.
|
||||||
|
2. **`([^,]+)` (Gruppe 2):** Wenn keine Anführungszeichen da sind, matcht er alles bis zum nächsten Komma.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Anwendung in JavaScript (Beispiel)
|
||||||
|
|
||||||
|
Da du das Ergebnis sicherlich in einem Array von einzelnen Werten brauchst, kannst du den Regex wie folgt anwenden. Hierbei nutzen wir `matchAll`, um die Treffer sauber zu trennen und die Anführungszeichen direkt zu entfernen:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const input = '"very big, soft computer mouse","the cutest peripheral ever",10,39.90';
|
||||||
|
const regex = /"([^"\\]*(?:\\.[^"\\]*)*)"|([^,]+)/g;
|
||||||
|
|
||||||
|
const matches = [...input.matchAll(regex)];
|
||||||
|
|
||||||
|
const result = matches.map((match) => {
|
||||||
|
// Wenn Gruppe 1 existiert, war es ein String in Anführungszeichen
|
||||||
|
// Wenn Gruppe 2 existiert, war es ein unberührter Wert (Zahl)
|
||||||
|
const value = match[1] !== undefined ? match[1] : match[2].trim();
|
||||||
|
|
||||||
|
// Optional: Datentypen konvertieren
|
||||||
|
if (!isNaN(value) && value !== '') {
|
||||||
|
return Number(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(result);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Das Ergebnis (Output)
|
||||||
|
|
||||||
|
Nach dem Parsen erhältst du ein sauberes Array, bei dem die Kommas innerhalb der Strings ignoriert wurden und die Zahlen einsatzbereit sind:
|
||||||
|
|
||||||
|
```json
|
||||||
|
["very big, soft computer mouse", "the cutest peripheral ever", 10, 39.9]
|
||||||
|
```
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"very big, soft computer mouse","the cutest peripheral ever",10,39.90
|
||||||
|
@@ -0,0 +1,11 @@
|
|||||||
|
Code,Short Description,Tagline,Quantity,Price
|
||||||
|
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
|
||||||
|
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
|
||||||
|
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
|
||||||
|
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
|
||||||
|
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
|
||||||
|
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
|
||||||
|
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
|
||||||
|
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
|
||||||
|
|
||||||
|
|
||||||
|
@@ -0,0 +1,57 @@
|
|||||||
|
import fs from 'node:fs';
|
||||||
|
import zlib from 'node:zlib';
|
||||||
|
import color from 'chalk';
|
||||||
|
|
||||||
|
const data = fs.readFileSync('data/products.csv', 'utf-8');
|
||||||
|
const products = data.split('\n');
|
||||||
|
const header = products.shift().split(',');
|
||||||
|
// console.log('header', header); // => Code,Short Description,Tagline,Quantity,Price
|
||||||
|
|
||||||
|
const convertCsvToJson = (productRow) => {
|
||||||
|
// console.log('products', products);
|
||||||
|
// console.log('ar', ar);
|
||||||
|
|
||||||
|
const cols = productRow.split(/\s*,\s*/);
|
||||||
|
// console.log(product);
|
||||||
|
// let obj = {};
|
||||||
|
|
||||||
|
// for (let i = 0; i < header.length; i++) {
|
||||||
|
// obj[header[i]] = cols[i];
|
||||||
|
// }
|
||||||
|
|
||||||
|
const product = header.reduce((obj, str, idx) => {
|
||||||
|
obj[str] = cols[idx];
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return product;
|
||||||
|
};
|
||||||
|
|
||||||
|
const entries = products
|
||||||
|
.filter((row) => row !== '') //
|
||||||
|
.map(convertCsvToJson);
|
||||||
|
console.log(entries);
|
||||||
|
|
||||||
|
// fs.writeFile('a.json', JSON.stringify(entries), 'UTF-8', (err) => {
|
||||||
|
// console.warn(err);
|
||||||
|
// });
|
||||||
|
|
||||||
|
const compressedData = zlib.gzipSync(JSON.stringify(entries));
|
||||||
|
try {
|
||||||
|
fs.writeFileSync('data/products.json.gz', compressedData);
|
||||||
|
console.log('compressed file');
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Übung 27: Ohne Umwege
|
||||||
|
|
||||||
|
Die Datei products.csv soll in eine products.json umgewandelt werden und in products.json.gz komprimiert werden.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Übung 27: Ohne Umwege
|
||||||
|
|
||||||
|
Die Datei products.csv soll in eine products.json umgewandelt werden und in products.json.gz komprimiert werden.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "u27_zlib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "u27_zlib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^6.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chalk": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "u27_zlib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^6.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// const crypto = require('node:crypto');
|
||||||
|
import crypto from 'node:crypto';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
const PASSWORD_LENGTH = 10;
|
||||||
|
const s = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ!.,;#$%/+*';
|
||||||
|
|
||||||
|
const buf = crypto.randomBytes(PASSWORD_LENGTH);
|
||||||
|
|
||||||
|
console.log('s.length:', s.length); // => 64
|
||||||
|
console.log('buf:', buf); // => <Buffer 9a 28 4f d6 32 7a 6d 44 f0 3e>
|
||||||
|
console.log('Array:', Array.from(buf)); // => [ 17, 181, 126, 182, 190, 212, 137, 233, 140, 75]
|
||||||
|
const password = Array.from(buf)
|
||||||
|
.map((byte) => s.charAt(byte % s.length)) // => kZ+!+pbMed
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
console.log(password);
|
||||||
|
|
||||||
|
const generatePassword = (length) => {
|
||||||
|
const chars = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ!.,;#$%/+*'.split('');
|
||||||
|
return _.shuffle(chars)
|
||||||
|
.slice(0, length + 1)
|
||||||
|
.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
const pwd = generatePassword(10);
|
||||||
|
console.log('Password: ', pwd);
|
||||||
|
|
||||||
|
// Übung 28: Passwortgenerator
|
||||||
|
|
||||||
|
// Was macht der folgende Code?
|
||||||
|
|
||||||
|
// OK: Der Titel verrät es schon. Versuche dennoch, das Programm zu verstehen! Benutze die Dokumentation der Standardbibliothek, um nachzuschlagen, was crypto.randomBytes(…) genau macht!
|
||||||
|
|
||||||
|
// Bonusfrage: Warum sind in den Zeichen «1», «i» und «l» nicht enthalten, genau so wenig wie «0» und «o»?
|
||||||
|
|
||||||
|
// const asciiLetters = Array.from({ length: 26 }, (_, i) =>
|
||||||
|
// String.fromCharCode(65 + i) + String.fromCharCode(97 + i)
|
||||||
|
// ).join(''); // "AaBbCc..." oder getrennt sortieren
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "u28_password-generator",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "u28_password-generator",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.18.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.18.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
|
||||||
|
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "u28_password-generator",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.18.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// const fs = require('node:fs');
|
||||||
|
// const zlib = require('node:zlib');
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import zlib from 'node:zlib';
|
||||||
|
|
||||||
|
const gzipCompressor = zlib.createGzip();
|
||||||
|
|
||||||
|
const inputStream = fs.createReadStream('data/products.html');
|
||||||
|
const outputStream = fs.createWriteStream('data/products.html.gz');
|
||||||
|
|
||||||
|
inputStream.on('data', (chunk) => {
|
||||||
|
console.log('Pakete (data chunks) werden geladen: ', chunk.length);
|
||||||
|
// outputStream.write(zlib.gzipSync(data));
|
||||||
|
});
|
||||||
|
|
||||||
|
outputStream.on('finish', () => {
|
||||||
|
console.log('Process finished');
|
||||||
|
});
|
||||||
|
|
||||||
|
inputStream.pipe(gzipCompressor).pipe(outputStream);
|
||||||
|
|
||||||
|
// Übung 29: Datenströme
|
||||||
|
// Schreibe Codebeispiel 239 um, ohne die Funktion pipe(…) zu verwenden!
|
||||||
|
|
||||||
|
// TIPP: Um eine Datei päckchenweise lesen- und schreiben zu können, gibt es für das fs Modul die Methoden createReadStream und createWriteStream.
|
||||||
|
|
||||||
|
// ÜBUNG BEREITS GELÖST!!!
|
||||||
|
|
||||||
|
// Die wichtigsten WritableStream-Events im Überblick
|
||||||
|
|
||||||
|
// - 'finish': Feuert, nachdem stream.end() aufgerufen wurde und alle gepufferten Daten erfolgreich auf das Ziellaufwerk geschrieben wurden.
|
||||||
|
|
||||||
|
// - 'close': Feuert, wenn der zugrundeliegende File Descriptor / die Ressource vollständig geschlossen wurde.
|
||||||
|
|
||||||
|
// - 'drain': Feuert, wenn der interne Puffer voll war (write() gab false zurück) und nun wieder bereit für neue Daten ist.
|
||||||
|
|
||||||
|
// - 'error': Feuert, wenn beim Schreiben ein Fehler auftritt (z. B. fehlende Schreibrechte oder volle Festplatte).
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "03_stream",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import os from 'node:os';
|
||||||
|
|
||||||
|
console.log(os.platform());
|
||||||
|
console.log(os.cpus().length);
|
||||||
|
|
||||||
|
console.log(`I am running on a machine with ${os.platform()} and ${os.cpus().length} cores.`);
|
||||||
|
console.log(`I am running on a machine with ${os.type()} and ${os.cpus().length} cores.`);
|
||||||
|
console.log(`I am running on a machine with ${os.version()} and ${os.cpus().length} cores.`);
|
||||||
|
|
||||||
|
// Weitere Informationen zum Betriebssystem
|
||||||
|
console.log('\n--- Betriebssystem ---');
|
||||||
|
console.log('Systemtyp:', os.type());
|
||||||
|
console.log('Systemversion:', os.release());
|
||||||
|
console.log('Architektur von Node.js:', os.arch());
|
||||||
|
console.log('Computername:', os.hostname());
|
||||||
|
|
||||||
|
// os.cpus() liefert Informationen zu den logischen CPU-Kernen.
|
||||||
|
const cpus = os.cpus();
|
||||||
|
console.log('\n--- Prozessor ---');
|
||||||
|
console.log('Logische CPU-Kerne:', cpus.length);
|
||||||
|
console.log('CPU-Modell:', cpus[0]?.model ?? 'Unbekannt');
|
||||||
|
|
||||||
|
// Die Speicherangaben kommen in Bytes. 1024 ** 3 Bytes entsprechen einem GiB.
|
||||||
|
const totalMemory = os.totalmem();
|
||||||
|
const freeMemory = os.freemem();
|
||||||
|
const usedMemory = totalMemory - freeMemory;
|
||||||
|
|
||||||
|
function formatMemory(bytes) {
|
||||||
|
return `${(bytes / 1024 ** 3).toFixed(2)} GiB`;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n--- Arbeitsspeicher ---');
|
||||||
|
console.log('Gesamt:', formatMemory(totalMemory));
|
||||||
|
console.log('Frei:', formatMemory(freeMemory));
|
||||||
|
console.log('Belegt:', formatMemory(usedMemory));
|
||||||
|
|
||||||
|
// os.uptime() gibt die Laufzeit des Betriebssystems in Sekunden zurück.
|
||||||
|
const uptime = os.uptime();
|
||||||
|
const hours = Math.floor(uptime / 3600);
|
||||||
|
const minutes = Math.floor((uptime % 3600) / 60);
|
||||||
|
console.log(`\nSystemlaufzeit: ${hours} Stunden und ${minutes} Minuten`);
|
||||||
|
|
||||||
|
console.log('\n--- Benutzer und Verzeichnisse ---');
|
||||||
|
console.log('Benutzername:', os.userInfo().username);
|
||||||
|
console.log('Home-Verzeichnis:', os.homedir());
|
||||||
|
console.log('Temporäres Verzeichnis:', os.tmpdir());
|
||||||
|
|
||||||
|
// Jede Netzwerkschnittstelle kann mehrere IPv4- und IPv6-Adressen haben.
|
||||||
|
console.log('\n--- Netzwerkschnittstellen ---');
|
||||||
|
for (const [name, addresses] of Object.entries(os.networkInterfaces())) {
|
||||||
|
for (const address of addresses ?? []) {
|
||||||
|
console.log(`${name}: ${address.address} (${address.family}${address.internal ? ', intern' : ''})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Übung 32: Information zum Betriebssystem und der Anzahl der vorhandenen CPUs
|
||||||
|
|
||||||
|
// Im Kontext einer Monitoring-Lösung benötigt ein Kunde eine kleine CLI (Command Line Interface)-Anwendung, die es erlaubt, das aktuelle Betriebssystem und die Anzahl der CPUs auf dem jeweiligen Rechner zu ermitteln.
|
||||||
|
|
||||||
|
// Vorgehensweise
|
||||||
|
|
||||||
|
// 1.Schau dir die Online-Dokumentation zum os-Modul der Standardbibliothek an.
|
||||||
|
// 2.Erstelle dann ein kurzes Node.js-Programm, das ausgibt, auf welcher Plattform es gerade läuft (also etwa »linux«, »darwin« (OS X) oder »win32«) und wie viele Kerne der Rechner hat.
|
||||||
|
|
||||||
|
// Hier eine mögliche Beispielausgabe:
|
||||||
|
|
||||||
|
// I am running on a machine with linux and 2 cores.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "u32_os-info",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
@@ -12111,7 +12111,7 @@ blockquote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.weather-box {
|
.weather-box {
|
||||||
background-color: #efefef;
|
background-color: #fff;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
font-family: "Source Sans 3", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
font-family: "Source Sans 3", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||||
@@ -12167,10 +12167,13 @@ blockquote {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.weather-box .weather-information .wind-information .icon-compass {
|
.weather-box .weather-information .wind-information .icon-compass {
|
||||||
|
transition: all 0.8s ease-out;
|
||||||
|
transition-delay: 200ms;
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
color: #777;
|
color: #777;
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
|
transform: rotate(-45deg);
|
||||||
margin: 0 1rem 0 2rem;
|
margin: 0 1rem 0 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,9 +40,18 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const setWeather = (data) => {
|
const setWeather = (data) => {
|
||||||
DOM.weatherIcon.src = `https://openweathermap.org/img/wn/04d@2x.png`;
|
const { temp_min: tempMin, temp_max: tempMax, temp } = data.main;
|
||||||
DOM.figcaption.textContent = data.weather[0].main;
|
const { speed, deg } = data.wind;
|
||||||
DOM.description.textContent = data.weather[0].description;
|
const { main, description, icon } = data.weather[0];
|
||||||
|
DOM.weatherIcon.src = `https://openweathermap.org/img/wn/${icon}@2x.png`;
|
||||||
|
DOM.figcaption.textContent = main;
|
||||||
|
DOM.description.textContent = description;
|
||||||
|
DOM.temp.textContent = temp;
|
||||||
|
DOM.tempMin.textContent = tempMin;
|
||||||
|
DOM.tempMax.textContent = tempMax;
|
||||||
|
DOM.speed.textContent = speed;
|
||||||
|
DOM.deg.textContent = deg;
|
||||||
|
DOM.iconCompass.style.transform = `rotate(${Number(deg) - 45}deg)`;
|
||||||
};
|
};
|
||||||
init();
|
init();
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"sources": ["../../dev/js/main.js"],
|
"sources": ["../../dev/js/main.js"],
|
||||||
"sourcesContent": ["'use strict';\n\n(() => {\n // === DOM & VARS =======\n const DOM = {\n weatherBox: document.querySelector('.weather-box'),\n weatherIcon: document.querySelector('.weather-pic img'),\n figcaption: document.querySelector('figcaption'),\n description: document.querySelector('.description'),\n temp: document.querySelector('.temp'),\n tempMin: document.querySelector('.temp-min'),\n tempMax: document.querySelector('.temp-max'),\n iconCompass: document.querySelector('.icon-compass'),\n speed: document.querySelector('.speed'),\n deg: document.querySelector('.wind-deg'),\n };\n\n console.log(DOM);\n\n // BITTE EIGENEN API KEY VERWENDEN\n const API_KEY = 'EIGENER_KEY';\n // https//latlong.net\n const LAT = 43.720215;\n const LON = 7.352606;\n\n // https://api.openweathermap.org/data/4.0/onecall/timeline/1day?cnt=10&lat=51.5000&lon=-0.1000&start=1776596400&appid={API key}\n // === INIT =============\n const init = () => {\n getWeather().then((data) => {\n console.log(data);\n setWeather(data);\n });\n };\n\n // === EVENTHANDLER =====\n\n // === XHR/FETCH ========\n const getWeather = async () => {\n try {\n const res = await fetch(\n `https://api.openweathermap.org/data/2.5/weather?lat=${LAT}&lon=${LON}&units=metric&appid=${API_KEY}`,\n );\n if (!res.ok) {\n throw Error('Fetch Error');\n }\n const data = await res.json();\n return data; // -> Promise\n } catch (error) {\n console.error(error);\n throw error;\n }\n };\n\n // === FUNCTIONS ========\n const setWeather = (data) => {\n // https://openweathermap.org/img/wn/04d@2x.png\n DOM.weatherIcon.src = `https://openweathermap.org/img/wn/04d@2x.png`;\n\n DOM.figcaption.textContent = data.weather[0].main;\n DOM.description.textContent = data.weather[0].description;\n };\n\n init();\n})();\n"],
|
"sourcesContent": ["'use strict';\n\n(() => {\n // === DOM & VARS =======\n const DOM = {\n weatherBox: document.querySelector('.weather-box'),\n weatherIcon: document.querySelector('.weather-pic img'),\n figcaption: document.querySelector('figcaption'),\n description: document.querySelector('.description'),\n temp: document.querySelector('.temp'),\n tempMin: document.querySelector('.temp-min'),\n tempMax: document.querySelector('.temp-max'),\n iconCompass: document.querySelector('.icon-compass'),\n speed: document.querySelector('.speed'),\n deg: document.querySelector('.wind-deg'),\n };\n\n console.log(DOM);\n\n // BITTE EIGENEN API KEY VERWENDEN\n const API_KEY = 'EIGENER_KEY';\n // https//latlong.net\n const LAT = 43.720215;\n const LON = 7.352606;\n\n // https://api.openweathermap.org/data/4.0/onecall/timeline/1day?cnt=10&lat=51.5000&lon=-0.1000&start=1776596400&appid={API key}\n // === INIT =============\n const init = () => {\n getWeather().then((data) => {\n console.log(data);\n setWeather(data);\n });\n };\n\n // === EVENTHANDLER =====\n\n // === XHR/FETCH ========\n const getWeather = async () => {\n try {\n const res = await fetch(\n `https://api.openweathermap.org/data/2.5/weather?lat=${LAT}&lon=${LON}&units=metric&appid=${API_KEY}`,\n );\n if (!res.ok) {\n throw Error('Fetch Error');\n }\n const data = await res.json();\n return data; // -> Promise\n } catch (error) {\n console.error(error);\n throw error;\n }\n };\n\n // === FUNCTIONS ========\n const setWeather = (data) => {\n const { temp_min: tempMin, temp_max: tempMax, temp } = data.main;\n const { speed, deg } = data.wind;\n const { main, description, icon } = data.weather[0];\n\n // https://openweathermap.org/img/wn/04d@2x.png\n DOM.weatherIcon.src = `https://openweathermap.org/img/wn/${icon}@2x.png`;\n\n DOM.figcaption.textContent = main;\n DOM.description.textContent = description;\n DOM.temp.textContent = temp;\n DOM.tempMin.textContent = tempMin;\n DOM.tempMax.textContent = tempMax;\n DOM.speed.textContent = speed;\n DOM.deg.textContent = deg;\n\n DOM.iconCompass.style.transform = `rotate(${Number(deg) - 45}deg)`;\n };\n\n init();\n})();\n"],
|
||||||
"mappings": ";;;AAEA,GAAC,MAAM;AAEL,UAAM,MAAM;AAAA,MACV,YAAY,SAAS,cAAc,cAAc;AAAA,MACjD,aAAa,SAAS,cAAc,kBAAkB;AAAA,MACtD,YAAY,SAAS,cAAc,YAAY;AAAA,MAC/C,aAAa,SAAS,cAAc,cAAc;AAAA,MAClD,MAAM,SAAS,cAAc,OAAO;AAAA,MACpC,SAAS,SAAS,cAAc,WAAW;AAAA,MAC3C,SAAS,SAAS,cAAc,WAAW;AAAA,MAC3C,aAAa,SAAS,cAAc,eAAe;AAAA,MACnD,OAAO,SAAS,cAAc,QAAQ;AAAA,MACtC,KAAK,SAAS,cAAc,WAAW;AAAA,IACzC;AAEA,YAAQ,IAAI,GAAG;AAGf,UAAM,UAAU;AAEhB,UAAM,MAAM;AACZ,UAAM,MAAM;AAIZ,UAAM,OAAO,MAAM;AACjB,iBAAW,EAAE,KAAK,CAAC,SAAS;AAC1B,gBAAQ,IAAI,IAAI;AAChB,mBAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH;AAKA,UAAM,aAAa,YAAY;AAC7B,UAAI;AACF,cAAM,MAAM,MAAM;AAAA,UAChB,uDAAuD,GAAG,QAAQ,GAAG,uBAAuB,OAAO;AAAA,QACrG;AACA,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,MAAM,aAAa;AAAA,QAC3B;AACA,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,eAAO;AAAA,MACT,SAAS,OAAO;AACd,gBAAQ,MAAM,KAAK;AACnB,cAAM;AAAA,MACR;AAAA,IACF;AAGA,UAAM,aAAa,CAAC,SAAS;AAE3B,UAAI,YAAY,MAAM;AAEtB,UAAI,WAAW,cAAc,KAAK,QAAQ,CAAC,EAAE;AAC7C,UAAI,YAAY,cAAc,KAAK,QAAQ,CAAC,EAAE;AAAA,IAChD;AAEA,SAAK;AAAA,EACP,GAAG;",
|
"mappings": ";;;AAEA,GAAC,MAAM;AAEL,UAAM,MAAM;AAAA,MACV,YAAY,SAAS,cAAc,cAAc;AAAA,MACjD,aAAa,SAAS,cAAc,kBAAkB;AAAA,MACtD,YAAY,SAAS,cAAc,YAAY;AAAA,MAC/C,aAAa,SAAS,cAAc,cAAc;AAAA,MAClD,MAAM,SAAS,cAAc,OAAO;AAAA,MACpC,SAAS,SAAS,cAAc,WAAW;AAAA,MAC3C,SAAS,SAAS,cAAc,WAAW;AAAA,MAC3C,aAAa,SAAS,cAAc,eAAe;AAAA,MACnD,OAAO,SAAS,cAAc,QAAQ;AAAA,MACtC,KAAK,SAAS,cAAc,WAAW;AAAA,IACzC;AAEA,YAAQ,IAAI,GAAG;AAGf,UAAM,UAAU;AAEhB,UAAM,MAAM;AACZ,UAAM,MAAM;AAIZ,UAAM,OAAO,MAAM;AACjB,iBAAW,EAAE,KAAK,CAAC,SAAS;AAC1B,gBAAQ,IAAI,IAAI;AAChB,mBAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH;AAKA,UAAM,aAAa,YAAY;AAC7B,UAAI;AACF,cAAM,MAAM,MAAM;AAAA,UAChB,uDAAuD,GAAG,QAAQ,GAAG,uBAAuB,OAAO;AAAA,QACrG;AACA,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,MAAM,aAAa;AAAA,QAC3B;AACA,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,eAAO;AAAA,MACT,SAAS,OAAO;AACd,gBAAQ,MAAM,KAAK;AACnB,cAAM;AAAA,MACR;AAAA,IACF;AAGA,UAAM,aAAa,CAAC,SAAS;AAC3B,YAAM,EAAE,UAAU,SAAS,UAAU,SAAS,KAAK,IAAI,KAAK;AAC5D,YAAM,EAAE,OAAO,IAAI,IAAI,KAAK;AAC5B,YAAM,EAAE,MAAM,aAAa,KAAK,IAAI,KAAK,QAAQ,CAAC;AAGlD,UAAI,YAAY,MAAM,qCAAqC,IAAI;AAE/D,UAAI,WAAW,cAAc;AAC7B,UAAI,YAAY,cAAc;AAC9B,UAAI,KAAK,cAAc;AACvB,UAAI,QAAQ,cAAc;AAC1B,UAAI,QAAQ,cAAc;AAC1B,UAAI,MAAM,cAAc;AACxB,UAAI,IAAI,cAAc;AAEtB,UAAI,YAAY,MAAM,YAAY,UAAU,OAAO,GAAG,IAAI,EAAE;AAAA,IAC9D;AAEA,SAAK;AAAA,EACP,GAAG;",
|
||||||
"names": []
|
"names": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,11 +53,22 @@
|
|||||||
|
|
||||||
// === FUNCTIONS ========
|
// === FUNCTIONS ========
|
||||||
const setWeather = (data) => {
|
const setWeather = (data) => {
|
||||||
// https://openweathermap.org/img/wn/04d@2x.png
|
const { temp_min: tempMin, temp_max: tempMax, temp } = data.main;
|
||||||
DOM.weatherIcon.src = `https://openweathermap.org/img/wn/04d@2x.png`;
|
const { speed, deg } = data.wind;
|
||||||
|
const { main, description, icon } = data.weather[0];
|
||||||
|
|
||||||
DOM.figcaption.textContent = data.weather[0].main;
|
// https://openweathermap.org/img/wn/04d@2x.png
|
||||||
DOM.description.textContent = data.weather[0].description;
|
DOM.weatherIcon.src = `https://openweathermap.org/img/wn/${icon}@2x.png`;
|
||||||
|
|
||||||
|
DOM.figcaption.textContent = main;
|
||||||
|
DOM.description.textContent = description;
|
||||||
|
DOM.temp.textContent = temp;
|
||||||
|
DOM.tempMin.textContent = tempMin;
|
||||||
|
DOM.tempMax.textContent = tempMax;
|
||||||
|
DOM.speed.textContent = speed;
|
||||||
|
DOM.deg.textContent = deg;
|
||||||
|
|
||||||
|
DOM.iconCompass.style.transform = `rotate(${Number(deg) - 45}deg)`;
|
||||||
};
|
};
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@use 'sass:color';
|
@use 'sass:color';
|
||||||
|
|
||||||
.weather-box {
|
.weather-box {
|
||||||
background-color: #efefef;
|
background-color: #fff;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
font-family: $font-copy;
|
font-family: $font-copy;
|
||||||
@@ -61,11 +61,13 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
.icon-compass {
|
.icon-compass {
|
||||||
|
transition: all 0.8s ease-out;
|
||||||
|
transition-delay: 200ms;
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
color: #777;
|
color: #777;
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
// transform: rotate(-45deg);
|
transform: rotate(-45deg);
|
||||||
margin: 0 1rem 0 2rem;
|
margin: 0 1rem 0 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Code,Short Description,Tagline,Quantity,Price
|
||||||
|
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
|
||||||
|
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
|
||||||
|
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
|
||||||
|
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
|
||||||
|
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
|
||||||
|
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
|
||||||
|
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
|
||||||
|
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
|
||||||
|
@@ -0,0 +1,77 @@
|
|||||||
|
// const fs = require('node:fs'); // commonjs
|
||||||
|
import fs from 'node:fs'; // module - esm
|
||||||
|
import color from 'chalk';
|
||||||
|
|
||||||
|
// VARS =========
|
||||||
|
const STOCK_WARN_AMOUNT = 5;
|
||||||
|
|
||||||
|
let data = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
data = fs.readFileSync('data/products.csv', 'utf-8');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(color.red(error));
|
||||||
|
// Beendet den Prozess erfolgreich (Code 0)
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const products = data.split('\n');
|
||||||
|
const headerAr = products.shift().split(/\s*,\s*/); // => [ 'Code', 'Short Description', 'Tagline', 'Quantity', 'Price' ]
|
||||||
|
|
||||||
|
// Functions ======
|
||||||
|
const recordToHtml = (row) => {
|
||||||
|
const fields = row.split(/\s*,\s*/); // ["MUG0007", "coffee mug with LCD level indicator", "never again reach for the empty mug","20","49.90" ]
|
||||||
|
|
||||||
|
// Destructuring von fields-Array
|
||||||
|
const [code, shortDescription, tagline, quantity, price] = fields;
|
||||||
|
|
||||||
|
let html = '<li class="list-group-item">';
|
||||||
|
html += `<h2>${shortDescription}</h2>`;
|
||||||
|
html += `<p>${tagline}</p>`;
|
||||||
|
html += `<p><strong>Price:</strong> ${Number(price).toFixed(2)}</p>`;
|
||||||
|
|
||||||
|
if (quantity < STOCK_WARN_AMOUNT) {
|
||||||
|
html += `<p class="alert alert-warning">Nur noch wenige Example verfügbar! (${quantity})</p>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</li>';
|
||||||
|
|
||||||
|
return html;
|
||||||
|
};
|
||||||
|
|
||||||
|
const writeHtmlDocument = (content = '') => {
|
||||||
|
const headerStr = `<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Products</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<div class="container py-5">`;
|
||||||
|
|
||||||
|
const footerStr = `</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
|
|
||||||
|
const htmlDocument = `${headerStr}${content}${footerStr}`;
|
||||||
|
|
||||||
|
fs.writeFile('products.html', htmlDocument, 'utf-8', (err) => {
|
||||||
|
if (err) console.log(color.red(err));
|
||||||
|
|
||||||
|
console.log(color.green('File created!'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const listItems = products
|
||||||
|
.filter((row) => row !== '') // leere String Einträge rausfiltern
|
||||||
|
.map(recordToHtml); // Funktionsreferenz
|
||||||
|
|
||||||
|
const htmlList = `<ul class="list-group">${listItems.join('')}</ul>`;
|
||||||
|
|
||||||
|
// Output ===========
|
||||||
|
|
||||||
|
writeHtmlDocument(htmlList);
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "01_csv-to-html",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "01_csv-to-html",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^6.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chalk": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "01_csv-to-html",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^6.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Products</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<div class="container py-5"><ul class="list-group"><li class="list-group-item"><h2>coffee mug with LCD level indicator</h2><p>never again reach for the empty mug</p><p><strong>Price:</strong> 49.90</p></li><li class="list-group-item"><h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2><p>put the smart into coffee reading</p><p><strong>Price:</strong> 99.90</p></li><li class="list-group-item"><h2>pen with pre-warmed ink (tested on the South Pole)</h2><p>the pen is mightier than the cold</p><p><strong>Price:</strong> 29.90</p></li><li class="list-group-item"><h2>ambidextrous computer mouse</h2><p>end the dictate of left and right</p><p><strong>Price:</strong> 19.90</p></li><li class="list-group-item"><h2>Easter egg themed webcam for your monitor</h2><p>put an Easter egg on hardware too</p><p><strong>Price:</strong> 149.90</p></li><li class="list-group-item"><h2>Vulcan language vi cheatsheet</h2><p>learn vi and Vulcan at the same time</p><p><strong>Price:</strong> 9.90</p><p class="alert alert-warning">Nur noch wenige Example verfügbar! (3)</p></li><li class="list-group-item"><h2>Klingon language emacs cheatsheet</h2><p>learn emacs and Klingon at the same time</p><p><strong>Price:</strong> 9.90</p></li><li class="list-group-item"><h2>smartphone case with built-in screen</h2><p>never miss a message</p><p><strong>Price:</strong> 39.90</p></li></ul></div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Code,Short Description,Tagline,Quantity,Price
|
||||||
|
@@ -0,0 +1,13 @@
|
|||||||
|
import fs from 'node:fs';
|
||||||
|
import color from 'chalk';
|
||||||
|
|
||||||
|
// async process
|
||||||
|
fs.readFile('data/products.csv', 'UTF8', (error, data) => {
|
||||||
|
console.log(color.yellow(data)); // 2 output
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i = 0; i < 2000000000; i++) {
|
||||||
|
// be busy for a few seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(color.green('ready')); // 1 output
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "02_async-vs-multithread",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "02_async-vs-multithread",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^6.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chalk": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "02_async-vs-multithread",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^6.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hello World
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import fs from 'fs'; // Modul aus der Standardbibliothek
|
||||||
|
|
||||||
|
let data;
|
||||||
|
|
||||||
|
fs.writeFileSync('hello.txt', 'hello World', 'utf8');
|
||||||
|
|
||||||
|
// fs.readFileSync(…)
|
||||||
|
// liest eine Datei ein (blockierende Variante)
|
||||||
|
data = fs.readFileSync('hello.txt', 'utf8');
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
// fs.readFile(…)
|
||||||
|
// liest eine Datei ein (asynchrone Variante)
|
||||||
|
fs.readFile('hello.txt', 'utf8', (error, data) => {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
// fs.writeFileSync(…)
|
||||||
|
// schreibt Daten in eine Datei; bereits vorhandene Daten werden überschrieben (blockierende Variante)
|
||||||
|
fs.writeFileSync('hello.txt', data, 'utf8');
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
// fs.writeFile(…)
|
||||||
|
// schreibt Daten in eine Datei; bereits vorhandene Daten werden überschrieben (asynchrone Variante)
|
||||||
|
fs.writeFile('hello.txt', data, 'UTF8', (error) => {
|
||||||
|
if (error) console.log('Error: ' + error);
|
||||||
|
});
|
||||||
|
|
||||||
|
// fs.statSync(…)
|
||||||
|
// ermittelt Infos zur Datei (blockierende Variante)
|
||||||
|
const stats = fs.statSync('hello.txt');
|
||||||
|
|
||||||
|
// console.log('File Stats: ', stats);
|
||||||
|
|
||||||
|
console.log('File size: ', stats.size); // => size in bytes
|
||||||
|
console.log('File birthdate: ', stats.birthtime); // => enstehungsdatum der Datei
|
||||||
|
|
||||||
|
// fs.stat(…)
|
||||||
|
// ermittelt Infos zur Datei (asynchrone Variante)
|
||||||
|
fs.stat('hello.txt', (error, stats) => console.log(stats.size)); // => size in bytes
|
||||||
|
|
||||||
|
// fs.unlinkSync(…)
|
||||||
|
// löscht eine Datei (blockierende Variante)
|
||||||
|
fs.unlinkSync('hello.txt');
|
||||||
|
|
||||||
|
fs.writeFileSync('hello.txt', 'hello World', 'utf8');
|
||||||
|
|
||||||
|
// fs.unlink(…)
|
||||||
|
// löscht eine Datei (asynchrone Variante)
|
||||||
|
// fs.unlink('hello.txt', 'utf-8', (error) => {
|
||||||
|
// if (error) console.log('Error: ' + error);
|
||||||
|
// });
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "01_fs-methoden",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Products</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<div class="container py-5"><ul class="list-group"><li class="list-group-item"><h2>coffee mug with LCD level indicator</h2><p>never again reach for the empty mug</p><p><strong>Price:</strong> 49.90</p></li><li class="list-group-item"><h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2><p>put the smart into coffee reading</p><p><strong>Price:</strong> 99.90</p></li><li class="list-group-item"><h2>pen with pre-warmed ink (tested on the South Pole)</h2><p>the pen is mightier than the cold</p><p><strong>Price:</strong> 29.90</p></li><li class="list-group-item"><h2>ambidextrous computer mouse</h2><p>end the dictate of left and right</p><p><strong>Price:</strong> 19.90</p></li><li class="list-group-item"><h2>Easter egg themed webcam for your monitor</h2><p>put an Easter egg on hardware too</p><p><strong>Price:</strong> 149.90</p></li><li class="list-group-item"><h2>Vulcan language vi cheatsheet</h2><p>learn vi and Vulcan at the same time</p><p><strong>Price:</strong> 9.90</p><p class="alert alert-warning">Nur noch wenige Example verfügbar! (3)</p></li><li class="list-group-item"><h2>Klingon language emacs cheatsheet</h2><p>learn emacs and Klingon at the same time</p><p><strong>Price:</strong> 9.90</p></li><li class="list-group-item"><h2>smartphone case with built-in screen</h2><p>never miss a message</p><p><strong>Price:</strong> 39.90</p></li></ul></div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import fs from 'node:fs';
|
||||||
|
import zlib from 'node:zlib';
|
||||||
|
|
||||||
|
const data = fs.readFileSync('data/products.html', 'utf-8');
|
||||||
|
|
||||||
|
const compressedData = zlib.gzipSync(data); // => <Buffer 1f 8b 08 00 00 00 00 00 00 13 9d 95 c1 8e dc 36 0c 86 ef 79 0a c6 a7 04 a8 c7 c9 6e 03 64 03 8d 51 20 d9 5e 5a b4 0b 34 2d 90 23 47 e2 58 6c 25 ca 90 ... 688 more bytes>
|
||||||
|
|
||||||
|
console.log(compressedData);
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.writeFileSync('data/products.html.gz', compressedData);
|
||||||
|
console.log('compressed file!');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "04_zlib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import fs from 'node:fs';
|
||||||
|
import zlib from 'node:zlib';
|
||||||
|
|
||||||
|
const data = fs.readFileSync('data/products.html', 'utf-8');
|
||||||
|
|
||||||
|
const gzipCompressor = zlib.createGzip();
|
||||||
|
|
||||||
|
const inputStream = fs.createReadStream('data/products.html');
|
||||||
|
const outputStream = fs.createWriteStream('data/products.html.gz');
|
||||||
|
|
||||||
|
inputStream.on('data', (data) => {
|
||||||
|
console.log('Pakete (data chunks) werden geladen:', data.length);
|
||||||
|
// outputStream.write(zlib.gzipSync(data)) // ohne pipe-Methode - Datenchunks geschrieben
|
||||||
|
});
|
||||||
|
|
||||||
|
inputStream.pipe(gzipCompressor).pipe(outputStream);
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "04_zlib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import crypto from 'node:crypto';
|
||||||
|
|
||||||
|
const data = 'Ich werde verschüsselt!';
|
||||||
|
const hash = crypto.createHash('sha256').update(data).digest('hex'); // 256-bit SHA-2 hash algorithm
|
||||||
|
|
||||||
|
console.log(hash); // 59e9f3b7c10a8c5c9e099d60bebb142eaa7560b375bb41e3def6bc34708ce6ae
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "06_crypto",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
const fs = require('node:fs'); // commonjs
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
// in code Blöcken ({..}) kann require (commonjs) verwendet werden.
|
||||||
|
const dns = require('node:dns');
|
||||||
|
dns.lookup('www.google.de', 4, (err, data) => {
|
||||||
|
if (err) console.log(err);
|
||||||
|
console.log(data); // => 142.251.208.227
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import fs from 'node:fs'; // module - esm Schreibweise
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
// import STATEMENT kann NICHT in Konditionen oder Code-Blöcken ({}) verwendet werden.
|
||||||
|
// import dns from 'node:dns'; // An import declaration can only be used at the top level of a module.
|
||||||
|
// seit 2020 import "dynamic" Funktion innerhalb von Code-Blöcken ({}) verwendet werden.
|
||||||
|
import('node:dns').then((dns) => {
|
||||||
|
dns.lookup('www.google.de', 4, (err, data) => {
|
||||||
|
if (err) console.log(err);
|
||||||
|
console.log(data); // => 142.251.208.227
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,902 @@
|
|||||||
|
{
|
||||||
|
"name": "08_npm-befehle",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "08_npm-befehle",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^6.0.1",
|
||||||
|
"express": "^5.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/accepts": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"negotiator": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "^3.1.2",
|
||||||
|
"content-type": "^2.0.0",
|
||||||
|
"debug": "^4.4.3",
|
||||||
|
"http-errors": "^2.0.1",
|
||||||
|
"iconv-lite": "^0.7.2",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"qs": "^6.15.2",
|
||||||
|
"raw-body": "^3.0.2",
|
||||||
|
"type-is": "^2.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/content-type": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bytes": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/call-bind-apply-helpers": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/call-bound": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"get-intrinsic": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chalk": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-disposition": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-type": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie-signature": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "4.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
|
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dunder-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"gopd": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/encodeurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-define-property": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-errors": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-object-atoms": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "^2.0.0",
|
||||||
|
"body-parser": "^2.2.1",
|
||||||
|
"content-disposition": "^1.0.0",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"cookie": "^0.7.1",
|
||||||
|
"cookie-signature": "^1.2.1",
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"depd": "^2.0.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"finalhandler": "^2.1.0",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"merge-descriptors": "^2.0.0",
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"once": "^1.4.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"proxy-addr": "^2.0.7",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"router": "^2.2.0",
|
||||||
|
"send": "^1.1.0",
|
||||||
|
"serve-static": "^2.2.0",
|
||||||
|
"statuses": "^2.0.1",
|
||||||
|
"type-is": "^2.0.1",
|
||||||
|
"vary": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/finalhandler": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"statuses": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/forwarded": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fresh": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/function-bind": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-intrinsic": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"es-define-property": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"es-object-atoms": "^1.1.1",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-proto": "^1.0.1",
|
||||||
|
"gopd": "^1.2.0",
|
||||||
|
"has-symbols": "^1.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"math-intrinsics": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dunder-proto": "^1.0.1",
|
||||||
|
"es-object-atoms": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gopd": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-symbols": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hasown": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-errors": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"inherits": "~2.0.4",
|
||||||
|
"setprototypeof": "~1.2.0",
|
||||||
|
"statuses": "~2.0.2",
|
||||||
|
"toidentifier": "~1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/iconv-lite": {
|
||||||
|
"version": "0.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
|
||||||
|
"integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/ipaddr.js": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-promise": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/math-intrinsics": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/media-typer": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/merge-descriptors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.54.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
|
||||||
|
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "^1.54.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/negotiator": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"content-type": "^2.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/negotiator/node_modules/content-type": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-inspect": {
|
||||||
|
"version": "1.13.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
|
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/on-finished": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/parseurl": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "8.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
|
||||||
|
"integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/proxy-addr": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz",
|
||||||
|
"integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"forwarded": "0.2.0",
|
||||||
|
"ipaddr.js": "1.9.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz",
|
||||||
|
"integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"es-define-property": "^1.0.1",
|
||||||
|
"side-channel": "^1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/range-parser": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "~3.1.2",
|
||||||
|
"http-errors": "~2.0.1",
|
||||||
|
"iconv-lite": "~0.7.0",
|
||||||
|
"unpipe": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/router": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"depd": "^2.0.0",
|
||||||
|
"is-promise": "^4.0.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"path-to-regexp": "^8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/send": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.3",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.1",
|
||||||
|
"mime-types": "^3.0.2",
|
||||||
|
"ms": "^2.1.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"statuses": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/serve-static": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"send": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/side-channel": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"object-inspect": "^1.13.4",
|
||||||
|
"side-channel-list": "^1.0.1",
|
||||||
|
"side-channel-map": "^1.0.1",
|
||||||
|
"side-channel-weakmap": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-list": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"object-inspect": "^1.13.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-map": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bound": "^1.0.2",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.5",
|
||||||
|
"object-inspect": "^1.13.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/side-channel-weakmap": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bound": "^1.0.2",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.5",
|
||||||
|
"object-inspect": "^1.13.3",
|
||||||
|
"side-channel-map": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/statuses": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/toidentifier": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/type-is": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"content-type": "^2.0.0",
|
||||||
|
"media-typer": "^1.1.0",
|
||||||
|
"mime-types": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/type-is/node_modules/content-type": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "08_npm-befehle",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "commonjs",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^6.0.1",
|
||||||
|
"express": "^5.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"kamikillerto.vscode-colorize",
|
||||||
|
"sleistner.vscode-fileutils",
|
||||||
|
"bierner.github-markdown-preview",
|
||||||
|
"bradgashler.htmltagwrap",
|
||||||
|
"zhuangtongfa.material-theme",
|
||||||
|
"techer.open-in-browser",
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
"pdconsec.vscode-print",
|
||||||
|
"vscode-icons-team.vscode-icons",
|
||||||
|
"formulahendry.auto-rename-tag",
|
||||||
|
"tomoki1207.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,332 @@
|
|||||||
|
/* @theme marp-theme */
|
||||||
|
|
||||||
|
@charset "UTF-8";
|
||||||
|
/*!
|
||||||
|
* Marp Dracula theme.
|
||||||
|
* @theme marp-theme
|
||||||
|
* @author Daniel Nicolas Gisolfi & modified by Philippe Botzek
|
||||||
|
*
|
||||||
|
* @auto-scaling true
|
||||||
|
* @size 4:3 960px 720px
|
||||||
|
* @size 16:9 1280px 720px
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import url('https://fonts.googleapis.com/css?family=Lato:400,900|IBM+Plex+Sans:400,700');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--dracula-background: #282a36;
|
||||||
|
--dracula-current-line: #44475a;
|
||||||
|
--dracula-foreground: #f8f8f2;
|
||||||
|
--dracula-comment: #6272a4;
|
||||||
|
--dracula-cyan: #8be9fd;
|
||||||
|
--dracula-green: #50fa7b;
|
||||||
|
--dracula-orange: #ffb86c;
|
||||||
|
--dracula-pink: #ff79c6;
|
||||||
|
--dracula-purple: #bd93f9;
|
||||||
|
--dracula-red: #ff5555;
|
||||||
|
--dracula-yellow: #f1fa8c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
background: var(--dracula-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Foreground */
|
||||||
|
.hljs,
|
||||||
|
.hljs-subst,
|
||||||
|
.hljs-typing,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable {
|
||||||
|
color: var(--dracula-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Comment */
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote,
|
||||||
|
.hljs-deletion {
|
||||||
|
color: var(--dracula-comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Cyan */
|
||||||
|
.hljs-meta .hljs-doctag,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-link,
|
||||||
|
.hljs-class {
|
||||||
|
color: var(--dracula-cyan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Green */
|
||||||
|
.hljs-title {
|
||||||
|
color: var(--dracula-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Orange */
|
||||||
|
.hljs-params {
|
||||||
|
color: var(--dracula-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Pink */
|
||||||
|
.hljs-keyword {
|
||||||
|
color: var(--dracula-pink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Purple */
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-number {
|
||||||
|
color: var(--dracula-purple);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Red */
|
||||||
|
.hljs-regexp {
|
||||||
|
color: var(--dracula-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dracula Yellow */
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-bullet,
|
||||||
|
.hljs-addition,
|
||||||
|
.hljs-template-tag {
|
||||||
|
color: var(--dracula-yellow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-doctag,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-params,
|
||||||
|
.hljs-emphasis {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg[data-marp-fitting='svg'] {
|
||||||
|
max-height: 580px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
margin: 0.5em 0 0 0;
|
||||||
|
color: var(--dracula-pink);
|
||||||
|
}
|
||||||
|
h1 strong,
|
||||||
|
h2 strong,
|
||||||
|
h3 strong,
|
||||||
|
h4 strong,
|
||||||
|
h5 strong,
|
||||||
|
h6 strong {
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
blockquote {
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul > li,
|
||||||
|
ol > li {
|
||||||
|
margin: 0.3em 0 0 0;
|
||||||
|
color: var(--dracula-cyan);
|
||||||
|
}
|
||||||
|
ul > li > p,
|
||||||
|
ol > li > p {
|
||||||
|
margin: 0.6em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
display: inline-block;
|
||||||
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
|
font-size: 0.8em;
|
||||||
|
letter-spacing: 0;
|
||||||
|
margin: -0.1em 0.15em;
|
||||||
|
padding: 0.1em 0.2em;
|
||||||
|
vertical-align: baseline;
|
||||||
|
color: var(--dracula-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
min-height: 1em;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
min-width: 100%;
|
||||||
|
padding: 0.5em;
|
||||||
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
pre code svg[data-marp-fitting='svg'] {
|
||||||
|
max-height: calc(580px - 1em);
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
padding: 0 1em;
|
||||||
|
position: relative;
|
||||||
|
color: var(--dracula-orange);
|
||||||
|
}
|
||||||
|
blockquote::after,
|
||||||
|
blockquote::before {
|
||||||
|
content: '“';
|
||||||
|
display: block;
|
||||||
|
font-family: 'Times New Roman', serif;
|
||||||
|
font-weight: bold;
|
||||||
|
position: absolute;
|
||||||
|
color: var(--dracula-green);
|
||||||
|
}
|
||||||
|
blockquote::before {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
blockquote::after {
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
blockquote > *:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-spacing: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
}
|
||||||
|
table th,
|
||||||
|
table td {
|
||||||
|
padding: 0.2em 0.4em;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
font-size: 35px;
|
||||||
|
font-family: 'IBM Plex Sans';
|
||||||
|
line-height: 1.35;
|
||||||
|
letter-spacing: 1.25px;
|
||||||
|
padding: 70px;
|
||||||
|
color: var(--dracula-foreground);
|
||||||
|
background-color: var(--dracula-background);
|
||||||
|
}
|
||||||
|
section > *:first-child,
|
||||||
|
section > header:first-child + * {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
section a,
|
||||||
|
section mark {
|
||||||
|
color: var(--dracula-red);
|
||||||
|
}
|
||||||
|
section code {
|
||||||
|
background: var(--dracula-current-line);
|
||||||
|
color: var(--dracula-current-green);
|
||||||
|
}
|
||||||
|
section h1 strong,
|
||||||
|
section h2 strong,
|
||||||
|
section h3 strong,
|
||||||
|
section h4 strong,
|
||||||
|
section h5 strong,
|
||||||
|
section h6 strong {
|
||||||
|
color: var(--dracula-current-line);
|
||||||
|
}
|
||||||
|
section pre > code {
|
||||||
|
background: var(--dracula-current-line);
|
||||||
|
}
|
||||||
|
section header,
|
||||||
|
section footer,
|
||||||
|
section section::after,
|
||||||
|
section blockquote::before,
|
||||||
|
section blockquote::after {
|
||||||
|
color: var(--dracula-comment);
|
||||||
|
}
|
||||||
|
section table th,
|
||||||
|
section table td {
|
||||||
|
border-color: var(--dracula-current-line);
|
||||||
|
}
|
||||||
|
section table thead th {
|
||||||
|
background: var(--dracula-current-line);
|
||||||
|
color: var(--dracula-yellow);
|
||||||
|
}
|
||||||
|
section table tbody > tr:nth-child(even) td,
|
||||||
|
section table tbody > tr:nth-child(even) th {
|
||||||
|
background: var(--dracula-current-line);
|
||||||
|
}
|
||||||
|
|
||||||
|
header,
|
||||||
|
footer,
|
||||||
|
section::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: 66%;
|
||||||
|
height: 70px;
|
||||||
|
line-height: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 10px 25px;
|
||||||
|
position: absolute;
|
||||||
|
color: var(--dracula-comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section::after {
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"terminal.explorerKind": "external",
|
||||||
|
"terminal.external.osxExec": "iTerm.app",
|
||||||
|
"terminal.external.windowsExec": "wt.exe",
|
||||||
|
"workbench.iconTheme": "vscode-icons",
|
||||||
|
"workbench.colorTheme": "One Dark Pro",
|
||||||
|
"prettier.printWidth": 120,
|
||||||
|
"prettier.singleQuote": true,
|
||||||
|
"editor.hover.enabled": "on",
|
||||||
|
"editor.wordWrap": "on",
|
||||||
|
"explorer.confirmDelete": false,
|
||||||
|
"explorer.confirmDragAndDrop": false,
|
||||||
|
"editor.quickSuggestionsDelay": 600,
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"emmet.includeLanguages": {
|
||||||
|
"javascript": "javascriptreact",
|
||||||
|
"ejs": "html"
|
||||||
|
},
|
||||||
|
"html.format.unformatted": "wbr,%",
|
||||||
|
"files.associations": {
|
||||||
|
"*.ejs": "html"
|
||||||
|
},
|
||||||
|
"editor.fontFamily": "'MesloLGS NF', Hack, Consolas, 'Courier New', monospace",
|
||||||
|
"oneDarkPro.markdownStyle": false,
|
||||||
|
"explorer.compactFolders": false,
|
||||||
|
"workbench.editor.labelFormat": "short",
|
||||||
|
"editor.hover.delay": 800,
|
||||||
|
"editor.bracketPairColorization.enabled": true,
|
||||||
|
"editor.guides.bracketPairs": "active",
|
||||||
|
"markdown.marp.themes": ["./.vscode/marp-theme.css"],
|
||||||
|
"markdown-preview-github-styles.colorTheme": "light"
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"Output HTML Element": {
|
||||||
|
"scope": "html",
|
||||||
|
"prefix": "output",
|
||||||
|
"body": ["<div class=\"output alert alert-secondary my-3\"></div>"],
|
||||||
|
"description": "generate a div Element with output alert and alert secondary class"
|
||||||
|
},
|
||||||
|
"Bootstrap html": {
|
||||||
|
"scope": "html",
|
||||||
|
"prefix": "!bs",
|
||||||
|
"body": [
|
||||||
|
"<!DOCTYPE html>",
|
||||||
|
"<html lang=\"de\">",
|
||||||
|
"\t<head>",
|
||||||
|
"\t\t<meta charset=\"UTF-8\" />",
|
||||||
|
"\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />",
|
||||||
|
"\t\t<title>$0</title>",
|
||||||
|
"\t\t<link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css\" rel=\"stylesheet\" />",
|
||||||
|
"\t</head>",
|
||||||
|
"\t<body>",
|
||||||
|
"\t\t<main>",
|
||||||
|
"\t\t\t<div class=\"container py-5\">",
|
||||||
|
"\t\t\t\t<h1>$0</h1>",
|
||||||
|
"\t\t\t</div>",
|
||||||
|
"\t\t</main>",
|
||||||
|
"\t\t<script>",
|
||||||
|
"\t\t\t'use strict';",
|
||||||
|
"\t\t\t",
|
||||||
|
"\t\t</script>",
|
||||||
|
"\t</body>",
|
||||||
|
"</html>"
|
||||||
|
],
|
||||||
|
"description": "Generate HTML with Bootstrap CDN and script-tag"
|
||||||
|
},
|
||||||
|
"$ und $$ helper function": {
|
||||||
|
"scope": "javascript,typescript",
|
||||||
|
"prefix": "$$$",
|
||||||
|
"body": [
|
||||||
|
"const $ = (qs) => document.querySelector(qs);",
|
||||||
|
"const $$ = (qs) => Array.from(document.querySelectorAll(qs));"
|
||||||
|
],
|
||||||
|
"description": "$ and $$ shorthand helper function"
|
||||||
|
},
|
||||||
|
|
||||||
|
"JavaScript Dateivorlage": {
|
||||||
|
"scope": "javascript,typescript",
|
||||||
|
"prefix": "vjs",
|
||||||
|
"body": [
|
||||||
|
"'use strict';",
|
||||||
|
"",
|
||||||
|
"(() => {",
|
||||||
|
"",
|
||||||
|
"\t// === DOM & VARS =======",
|
||||||
|
"\tconst DOM = {};",
|
||||||
|
"",
|
||||||
|
"\t// === INIT =============",
|
||||||
|
"\tconst init = () => {",
|
||||||
|
"",
|
||||||
|
"\t}",
|
||||||
|
"",
|
||||||
|
"\t// === EVENTHANDLER =====",
|
||||||
|
"",
|
||||||
|
"\t// === XHR/FETCH ========",
|
||||||
|
"",
|
||||||
|
"\t// === FUNCTIONS ========",
|
||||||
|
"",
|
||||||
|
"\tinit();",
|
||||||
|
"",
|
||||||
|
"})();"
|
||||||
|
],
|
||||||
|
"description": "JavaScript Dateivorlage"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,505 @@
|
|||||||
|
---
|
||||||
|
marp: true
|
||||||
|
theme: default
|
||||||
|
---
|
||||||
|
|
||||||
|
## JavaScript Grundlagen Teil 1.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 01
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Vorstellungsrunde
|
||||||
|
- Einrichtung der IDE
|
||||||
|
- Tools für die Webentwicklung (Emmet, Markdown, VS-Code, Co-Pilot)
|
||||||
|
- Arbeiten mit VSCode
|
||||||
|
- Konsolenausgaben mit `console.log()`
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
- Übungen: 1 - 3, Content Factory
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 02
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Dialogfenster in JS `prompt()`, `alert()`, `confirm()`
|
||||||
|
- Kommentare in JS
|
||||||
|
- Rechnen in JS
|
||||||
|
- Datentyp String, Number, Boolean
|
||||||
|
- literal und typeof
|
||||||
|
- Prioritätsreihenfolge
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 3 - 6 (Content-Factory bis 1.3.3)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 03
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Variablen und Konstanten in JS
|
||||||
|
- Zusammengesetzte Zuweisungsoperatoren
|
||||||
|
- Increment & Decrement
|
||||||
|
- Strings verketten mit +
|
||||||
|
- Escape-Notation
|
||||||
|
- Implizite und explizite Typkonvertierung
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 7 - 12
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 04
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Escape-Notation
|
||||||
|
- Implizite und explizite Typkonvertierung
|
||||||
|
- NaN - Paradoxon
|
||||||
|
- Math Object
|
||||||
|
- Number.toFixed()
|
||||||
|
- isNaN
|
||||||
|
- Lexikographische Vergleiche
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 14 - 18
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 05
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Repetition der Inhalte
|
||||||
|
- Relationale Operatoren & Vergleichoperatoren
|
||||||
|
- **Exkurs: Webseitenstruktur + SASS HTML-Formularfelder**
|
||||||
|
- 1:1 Meeting
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung Kontaktformular mit HTML und BS,
|
||||||
|
Lektion 10 erarbeiten
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 06
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- **Exkurs: HTML Formularfelder mit BS**
|
||||||
|
- if else Verzweigung und ternärer Operator
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 19 - 21 + Kontaktformular
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 07
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- logische Operatoren UND und ODER
|
||||||
|
- unärer Operator (!)
|
||||||
|
- String Methoden
|
||||||
|
- Funktionen in JS + mit Übergabeparameter + mit Rückgabewerten
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 22 - 31
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 08
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Funktionen mit Rückgabewerten
|
||||||
|
- Guards, Restparameter, Defaulparameter
|
||||||
|
- Array Part 1
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 32 - 38
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 09
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Array Methoden toSorted, toReversed, toSpliced
|
||||||
|
- toSorted, toReversed
|
||||||
|
- Array sort mit "compare function"
|
||||||
|
- Array: Higher Order Funktionen Part (sort map, forEach, reduce, some, every)
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 39 - 45 + optionale Übung
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 10
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Array.find und Array.findIndex
|
||||||
|
- Alle Array Higher Order Funktionen im Überblick
|
||||||
|
- local scoping
|
||||||
|
- Git SCM und Windows Terminal einrichten
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 46 - 48
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## JavaScript für Fortgeschrittene
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 11
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- **Exkurs: Schleifen**
|
||||||
|
- Einführung in JS für Fortgeschrittene
|
||||||
|
- Objekte in JS
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Projektarbeit
|
||||||
|
Abschlussquiz - JS Grundlagen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 12
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Destructuring von Objekten und Arrays
|
||||||
|
- Rekursion
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 01 - 09
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 13
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Promises
|
||||||
|
- Callback-Hell
|
||||||
|
- Promise Aufbau
|
||||||
|
- Promise in Funktionen
|
||||||
|
- File System von Node
|
||||||
|
- commonjs vs esm
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 10 - 11
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 14
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- util promisify
|
||||||
|
- Promise.all()
|
||||||
|
- async await
|
||||||
|
- Mehrdimensionale Arrays
|
||||||
|
- Chess-Beispiel
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 12 - 19
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 15
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Wiederholung der Inhalte
|
||||||
|
- Arbeiten mit Fetch API
|
||||||
|
- **Exkurs: Switch Case Abfragen**
|
||||||
|
- **Exkurs: Statische Webseite mit Sass und HTML**
|
||||||
|
- **Exkurs: Versionierung mit Github Part (SSH)**
|
||||||
|
- 1:1 Meeting
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 20 - 24
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 15
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Wiederholung der Inhalte
|
||||||
|
- Promise.all()
|
||||||
|
- **Exkurs: Switch Case Abfragen**
|
||||||
|
- **Exkurs: Statische Webseite mit Sass und HTML**
|
||||||
|
- 1:1 Meeting
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 20 - 24
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 16
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- **Exkurs: Statische Webseite mit Sass und HTML Part II**
|
||||||
|
- Node Module: HTTP-Server, npm-run-all und SVGO
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Projektarbeit + Wetter API Key besorgen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 17
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- XML-HttpRequest und AJAX mit jQuery
|
||||||
|
- Node Module für die Projekt-Entwicklungsumgebung
|
||||||
|
- Wetter API auslesen
|
||||||
|
- fetch in der Praxis: Joke API auslesen
|
||||||
|
- Was ist Node.js? (Wiederholung)
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Projektarbeit
|
||||||
|
Übungen Public API auslesen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 18
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Node Standardbib (fs, zlib (stream), Crypto)
|
||||||
|
- Import vs. require (Teil II)
|
||||||
|
- NPM Befehle
|
||||||
|
- Abschluss von JS für Fortgeschrittene
|
||||||
|
- Projektvorstellung 1 + 2 JS Advanced
|
||||||
|
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übungen 25 - 31
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# JavaScript und das Document Object Model (DOM)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
#### Tag 19
|
||||||
|
|
||||||
|
- Einführung in JS DOM
|
||||||
|
- DOM Selection (querySelector, querySelectorAll, $ & $$ Helper)
|
||||||
|
- CSS Selektoren
|
||||||
|
- Typ-, Attribut-, Kombinator- und Pseudoklassen - Selektoren
|
||||||
|
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übungen 01 - 05
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 20
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Chat Gestaltung (DOMTokenList Objekt)
|
||||||
|
- Defer & Async
|
||||||
|
- JS Dateien auslagern
|
||||||
|
- Optimierung von Projektstruktur
|
||||||
|
- **Exkurs: Projektstruktur mit Gulp**
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 06 - 07
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 21
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- **Exkurs: Projektstruktur mit Gulp Part II**
|
||||||
|
- Events in JS MouseEvent, KeyboardEvent
|
||||||
|
- Projekt: Newsboard
|
||||||
|
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 08 - 9
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 22
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- HTML Element Progress
|
||||||
|
- IDL-Attribut vs. Content-Attribut
|
||||||
|
- HTML Attribute mit boolescher Zuweisung
|
||||||
|
- Tooltip: HTML erweitern mit Data-Attribut
|
||||||
|
- Dataset Attribut, DOMStringMap Objekt
|
||||||
|
- getComputedStyle, Attribute mit boolscher Zuweisung
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 10 - 14
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 23
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- DOM Creation - Elemente erstellen
|
||||||
|
- createElement() & appendChild()
|
||||||
|
- Projekt: Produktmanager Part I
|
||||||
|
- DOM Creation Befehle
|
||||||
|
- Entfernen von Elementen
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 15 - 17
|
||||||
|
**Projektarbeit / Content Factory**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 24
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Import von Modulen in JS (Browserseitig)
|
||||||
|
- Separation of Concerns
|
||||||
|
- Projekt: Produktmanager final
|
||||||
|
- DOM Traversal Befehle & alle DOM Bereiche
|
||||||
|
- insertBefore(), appendChild(), append(), prepend(), before(), after()
|
||||||
|
- Refactoring von Produktmanager mit Template
|
||||||
|
- JS DOM Projektvorstellung
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übung 18 + optionale Übungen
|
||||||
|
**Projektarbeit / Content Factory**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 25
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- **Exkurs: Weitere Events: Drag and Drop**
|
||||||
|
- **Rest API erstellen mit Express**
|
||||||
|
- **Exkurs: DOM Inhalte über REST API mit Express Part I**
|
||||||
|
- CRUD - Create - (Read) - Update - Delete
|
||||||
|
- **Routing in JS**
|
||||||
|
- Abschlussquiz JS DOM
|
||||||
|
- **1:1 Meeting**
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Projekte
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## BROWSER API
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 26
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- **Exkurs: DOM Inhalte über mit REST API Express**
|
||||||
|
- **Erweiterung Frontend um REST API**
|
||||||
|
- CRUD - (Create - Read) - Update - Delete
|
||||||
|
- BREAD - Browse - Read - Edit - Add - Delete
|
||||||
|
- Verwendung von Modulen (Modal von BS, Toastify, Splide)
|
||||||
|
|
||||||
|
**Übungen**
|
||||||
|
|
||||||
|
Projekte & optionale Übungen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Tag 27
|
||||||
|
|
||||||
|
- **Exkurs: Vite vs Gulp**
|
||||||
|
- **SASS 7 on 1 mit Bootstrap 6**
|
||||||
|
- **Projektfinalisierung Express + REST API**
|
||||||
|
- Einführung in Typescript
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Tag 28
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Typescript Grundlagen
|
||||||
|
- Typescript Annotationen
|
||||||
|
- Typescript "more Types"
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übungen 1 - 5
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Tag 29
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Typescript Annotationen
|
||||||
|
- Primitive Types, Object, Union Types
|
||||||
|
- type statement vs interface
|
||||||
|
- Type Assertion with as and <>
|
||||||
|
- Typescript "more Types"
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übungen 4 - 9
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Tag 30
|
||||||
|
|
||||||
|
**Inhalt:**
|
||||||
|
|
||||||
|
- Typescript "more Types"
|
||||||
|
- Interface, as statement, literale
|
||||||
|
- Typescript Narrowing with Guards
|
||||||
|
- truthiness, equality, in-operator, type-predicate
|
||||||
|
- TS Funktionen und Objekte
|
||||||
|
|
||||||
|
**Übungen:**
|
||||||
|
|
||||||
|
Übungen 10 - 19
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# Velinkungsproblem von globalen Modulen
|
||||||
|
|
||||||
|
Bei **nvm-windows** liegt das Problem an einem bekannten Mechanismus:
|
||||||
|
|
||||||
|
`nvm-windows` verwaltet Node-Versionen über einen **Symlink** (standardmäßig `C:\Program Files\nodejs`). Dieser Symlink zeigt dynamisch auf die gerade aktive Node-Version unter `%APPDATA%\nvm\v<version>`.
|
||||||
|
|
||||||
|
Wenn du `npm install -g <package>` ausführst, gibt es zwei typische Szenarien, warum das Binary nicht mehr im `PATH` landet:
|
||||||
|
|
||||||
|
1. **Ein abweichendes oder altes globales `prefix` in der `.npmrc`:** Wenn dort noch ein hartkodierter Pfad (wie `%APPDATA%\npm`) hinterlegt ist, legt npm die `.cmd`-Dateien dort ab, aber nvm-windows bindet diesen Pfad **nicht** in den `PATH` ein – nvm erwartet globale Pakete direkt im Symlink-Verzeichnis der jeweiligen Node-Version.
|
||||||
|
2. **Fehlende Berechtigungen im Node-Symlink:** Liegt Node unter `C:\Program Files\nodejs`, kann npm ohne Admin-Rechte dort keine `.cmd`-Dateien anlegen und weicht stillschweigend aus.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 1: Prüfen, wo npm globale Pakete aktuell ablegt
|
||||||
|
|
||||||
|
Führe in der PowerShell aus:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
npm config get prefix
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* **Fall A (Standard bei nvm-windows):** Der Pfad zeigt auf das aktive Symlink-Verzeichnis (z. B. `C:\Program Files\nodejs`). Hier müssten die `.cmd`-Dateien liegen.
|
||||||
|
* **Fall B (Häufige Ursache):** Der Pfad zeigt auf `C:\Users\<Name>\AppData\Roaming\npm`. In diesem Fall findet Windows die Befehle nicht, weil dieser Ordner bei nvm-windows **nicht** im `PATH` steht.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Lösungsweg 1: Den dedizierten npm-Ordner nutzen (Empfohlen & Best Practice)
|
||||||
|
|
||||||
|
Damit globale Pakete auch bei einem Node-Versionswechsel über `nvm use` erhalten bleiben und keine Admin-Rechte im Programmverzeichnis nötig sind, bindet man den globalen npm-Pfad fest ein.
|
||||||
|
|
||||||
|
1. **Globales Prefix in npm festlegen:**
|
||||||
|
```powershell
|
||||||
|
npm config set prefix "$env:APPDATA\npm"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
2. **Diesen Ordner dauerhaft in den Benutzer-`PATH` eintragen:**
|
||||||
|
```powershell
|
||||||
|
[Environment]::SetEnvironmentVariable(
|
||||||
|
"Path",
|
||||||
|
[Environment]::GetEnvironmentVariable("Path", "User") + ";$env:APPDATA\npm",
|
||||||
|
"User"
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
3. **Paket nochmals global installieren:**
|
||||||
|
```powershell
|
||||||
|
npm install -g gulp-cli
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
4. **Terminal neu starten** (Windows Terminal / PowerShell schließen und neu öffnen), danach testen:
|
||||||
|
```powershell
|
||||||
|
gulp -v
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Lösungsweg 2: Den nvm-Standard wiederherstellen
|
||||||
|
|
||||||
|
Falls du möchtest, dass nvm-windows globale Pakete strikt pro Node-Version im jeweiligen Versionsordner verwaltet:
|
||||||
|
|
||||||
|
1. **Globales Prefix zurücksetzen:**
|
||||||
|
```powershell
|
||||||
|
npm config delete prefix
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
2. **Prüfen, ob der nvm-Symlink im `PATH` vorhanden ist:**
|
||||||
|
```powershell
|
||||||
|
$env:PATH -split ';' | Select-String "nodejs"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Hier muss der nvm-Symlink (`C:\Program Files\nodejs` oder dein benutzerdefinierter Pfad) auftauchen.
|
||||||
|
3. **Installieren:**
|
||||||
|
```powershell
|
||||||
|
npm install -g gulp-cli
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
*(Hinweis: Falls eine Fehlermeldung bezüglich `EPERM` oder fehlender Schreibrechte auftaucht, die Konsole einmalig als Administrator ausführen oder Lösungsweg 1 wählen).*
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
# Teams über git-bash
|
||||||
|
|
||||||
|
Hier ist die schrittweise Anleitung, wie du das Skript ablegst, ausführst und bei Bedarf bei jedem Login automatisch starten lässt.
|
||||||
|
|
||||||
|
1. **Speicherort wählen:** Persistentes Verzeichnis.
|
||||||
|
Da das Notebook regelmäßig neu aufgesetzt wird, muss das Skript an einem Ort liegen, der nicht gelöscht wird (z. B. auf einem USB-Stick, Netzlaufwerk oder in einem synchronisierten Ordner).
|
||||||
|
|
||||||
|
Falls dein lokales Benutzerverzeichnis überlebt, erstelle dort einen Skript-Ordner:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p "$HOME/bin"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
*Erfolgsprüfung:* Führe `ls -ld "$HOME/bin"` in der Git Bash aus. Das Verzeichnis wird ohne Fehler gelistet.
|
||||||
|
|
||||||
|
|
||||||
|
2. **Skriptdatei anlegen:** teams-link-fix.sh.
|
||||||
|
Erstelle die Datei `$HOME/bin/teams-link-fix.sh` und füge den folgenden Inhalt ein:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "==> Prüfe Standardbrowser für HTTP..."
|
||||||
|
HTTP_PROGID=$(MSYS_NO_PATHCONV=1 reg.exe query \
|
||||||
|
"HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice" \
|
||||||
|
/v "ProgId" 2>/dev/null | tr -d '\r' | awk '/ProgId/ {print $NF}')
|
||||||
|
|
||||||
|
if [[ "$HTTP_PROGID" =~ [Ff]irefox ]]; then
|
||||||
|
echo "✔ Firefox ist als Standardbrowser gesetzt ($HTTP_PROGID)."
|
||||||
|
else
|
||||||
|
echo "⚠ Firefox ist aktuell NICHT der Standardbrowser (aktuell: '${HTTP_PROGID:-Unbekannt}')."
|
||||||
|
echo "==> Versuche Firefox als Standardbrowser anzutriggern..."
|
||||||
|
|
||||||
|
FF_BIN=""
|
||||||
|
for candidate in \
|
||||||
|
"/c/Program Files/Mozilla Firefox/firefox.exe" \
|
||||||
|
"/c/Program Files (x86)/Mozilla Firefox/firefox.exe" \
|
||||||
|
"$LOCALAPPDATA/Mozilla Firefox/firefox.exe"; do
|
||||||
|
if [ -f "$candidate" ]; then
|
||||||
|
FF_BIN="$candidate"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$FF_BIN" ]; then
|
||||||
|
"$FF_BIN" -setDefaultBrowser >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Setze Teams Link-Handler auf Standardbrowser..."
|
||||||
|
MSYS_NO_PATHCONV=1 reg.exe add "HKCU\Software\Microsoft\Office\16.0\Common\Links" \
|
||||||
|
/v "BrowserSelection" \
|
||||||
|
/t REG_DWORD \
|
||||||
|
/d 0 \
|
||||||
|
/f >/dev/null
|
||||||
|
|
||||||
|
echo "✔ Registry aktualisiert (BrowserSelection = 0)."
|
||||||
|
|
||||||
|
echo "==> Starte Teams neu..."
|
||||||
|
taskkill.exe //F //IM ms-teams.exe 2>/dev/null || true
|
||||||
|
taskkill.exe //F //IM Teams.exe 2>/dev/null || true
|
||||||
|
sleep 1
|
||||||
|
explorer.exe 'shell:AppsFolder\MSTeams_8wekyb3d8bbwe!MSTeams'
|
||||||
|
|
||||||
|
echo "✔ Fertig!"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
*Erfolgsprüfung:* Mache das Skript ausführbar mit `chmod +x "$HOME/bin/teams-link-fix.sh"`.
|
||||||
|
|
||||||
|
|
||||||
|
3. **Skript manuell testen:** Git Bash.
|
||||||
|
Führe das Skript einmal direkt aus, um zu prüfen, ob die Registry ohne Fehlermeldung beschrieben wird:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
~/bin/teams-link-fix.sh
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
*Erfolgsprüfung:* Die Ausgabe endet mit `✔ Fertig!` und Teams startet neu. Ein Klick auf einen Web-Link in einem Teams-Chat öffnet sich direkt in Firefox statt Microsoft Edge.
|
||||||
|
|
||||||
|
|
||||||
|
4. **Optional: Autostart nach täglichem Re-Image:** Windows Autostart.
|
||||||
|
Wenn du nach dem Neuaufsetzen nicht jedes Mal die Bash öffnen möchtest, lege eine kleine Starter-Verknüpfung im Windows-Autostart-Ordner an:
|
||||||
|
|
||||||
|
1. Drücke `Win + R`, tippe `shell:startup` ein und drücke **Enter**.
|
||||||
|
2. Erstelle in diesem Ordner eine Textdatei namens `teams-fix.cmd` mit folgendem Inhalt (Pfad ggf. anpassen):
|
||||||
|
|
||||||
|
```bat
|
||||||
|
@echo off
|
||||||
|
"C:\Program Files\Git\bin\bash.exe" -c "~/bin/teams-link-fix.sh"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
*Erfolgsprüfung:* Melde dich ab und wieder an. Das Konsolenfenster öffnet sich kurz und schließt sich nach erfolgreicher Ausführung automatisch.
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
## Optionale Übungsaufgabe 1: Responsive Navigation mit Hamburger-Menü
|
||||||
|
|
||||||
|
### 1. HTML-Struktur & Icon-Vorbereitung
|
||||||
|
|
||||||
|
Erweitere die bestehende Navigationsstruktur im Projet `webseite-gulp` um das notwendige Markup für einen Menü-Toggle.
|
||||||
|
|
||||||
|
1. **Hamburger-Icon-Markup einfügen:** Füge innerhalb Deines `<nav>`-Elements das HTML für den Menü-Toggle ein.
|
||||||
|
- Du kannst hierfür die animierten Icons von [jonsuh.com/hamburgers/](https://jonsuh.com/hamburgers/) verwenden.
|
||||||
|
2. **Zustandsklasse definieren:** Überlege Dir eine **Kontrollklasse** (z.B. `nav-open` oder `is-active`), die Du später per JavaScript auf das `<body>`-Tag oder das `<nav>`-Element setzt, um den **geöffneten Zustand** zu signalisieren.
|
||||||
|
|
||||||
|
### 2. CSS-Styling & Media Query (Mobile First)
|
||||||
|
|
||||||
|
Stelle sicher, dass die Navigation standardmäßig für die mobile Ansicht funktioniert, und passe sie dann für größere Bildschirme an.
|
||||||
|
|
||||||
|
1. **Mobile Standard (bis $575\text{px}$):**
|
||||||
|
|
||||||
|
- Die **Hauptmenüpunkte** müssen standardmäßig **versteckt** sein (`display: none;` oder per `transform` aus dem Sichtfeld geschoben).
|
||||||
|
- Das **Hamburger-Icon** muss in dieser Ansicht **sichtbar** sein.
|
||||||
|
- Definiere die **Darstellung des geöffneten Menüs** (mithilfe Deiner Zustandsklasse, z.B. `.nav-open .menu-list`). Gestalte es als nutzerfreundliches Fullscreen-Overlay oder Sidebar für mobile Geräte.
|
||||||
|
|
||||||
|
2. **Desktop-Übergang (ab $576\text{px}$):**
|
||||||
|
|
||||||
|
- Füge die notwendige **Media Query** hinzu:
|
||||||
|
```css
|
||||||
|
@media (min-width: 576px) {
|
||||||
|
/* ... hier die Desktop-Regeln ... */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Innerhalb dieser Media Query:
|
||||||
|
- Mache die **Hauptmenüpunkte dauerhaft sichtbar** und ordne sie im Desktop-Layout an.
|
||||||
|
- Blende das **Hamburger-Icon aus** (`display: none;`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. JavaScript-Interaktivität (Menü-Toggle)
|
||||||
|
|
||||||
|
Implementiere die Logik, die das Umschalten des Menüzustands steuert, wenn das Icon geklickt wird.
|
||||||
|
|
||||||
|
1. **Event-Listener:** Füge dem **Hamburger-Icon** einen `click`-Event-Listener hinzu.
|
||||||
|
|
||||||
|
2. **Klasse togglen:** Im Click-Handler **togglet** Du die **Zustandsklasse** (`nav-open` oder `is-active`) auf dem Element (z.B. dem `<body>` oder `<nav>`), das Du im CSS zur Steuerung verwendest. Ein Klick öffnet das Menü, der erneute Klick schließt es. Vergesse dabei nicht dem Menü Icon die passende Klasse zum hinzufügen des Effekts zu vergeben.
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Optionale Übungen
|
||||||
|
|
||||||
|
## 1. Tooltip als Modul verwenden
|
||||||
|
|
||||||
|
Intergriere das Plugin [`floating-ui`](https://floating-ui.com/)
|
||||||
|
in die [Webseite](../../unterricht/tag21/03_website-gulp-js/index.html) .
|
||||||
|
|
||||||
|
## 2. Integration eines weiteren Moduls
|
||||||
|
|
||||||
|
- Intergriere ein weiteres Modul deiner Wahl in die Webseite.
|
||||||
|
|
||||||
|
## 3. Formularvalidierung als Modul
|
||||||
|
|
||||||
|
Erstelle ein Modul für die Validierung von einem Formular (`FormValidator`) mit folgenden Feldern
|
||||||
|
|
||||||
|
- Vor- und Nachname
|
||||||
|
- E-Mail
|
||||||
|
- Adresse bestehend aus:
|
||||||
|
- Strasse, Hausnummer
|
||||||
|
- PLZ, Ort
|
||||||
|
- Land
|
||||||
|
- Nachricht
|
||||||
|
|
||||||
|
Die Validierung soll direkt während (`input`) oder nach der Eingabe (`blur`) der Felder stattfinden. Die Verwendung von Validierungsmodulen wie `validator` dürfen dabei verwenden werden.
|
||||||
@@ -0,0 +1,368 @@
|
|||||||
|
/* -------------------------------------------- Haupt CSS fuer alle Seiten -------------------------------------------- */
|
||||||
|
|
||||||
|
/* ---------------- CSS-Reset ------------------- */
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
a,
|
||||||
|
div,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
span,
|
||||||
|
p,
|
||||||
|
img,
|
||||||
|
strong,
|
||||||
|
ul,
|
||||||
|
li,
|
||||||
|
table,
|
||||||
|
th,
|
||||||
|
td,
|
||||||
|
tr {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
border: 0px none;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-variant: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
table-layout: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------- Body / HTML ------------------- */
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 100%;
|
||||||
|
background-color: #fffef7;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: normal;
|
||||||
|
color: black;
|
||||||
|
margin: 0rem auto 2rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------- layout ------------------- */
|
||||||
|
|
||||||
|
header {
|
||||||
|
background: url(../img/js_header.png) left top no-repeat transparent;
|
||||||
|
background-size: cover;
|
||||||
|
height: 250px;
|
||||||
|
min-width: 850px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header:after {
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
height: 250px;
|
||||||
|
background: rgba(255, 254, 247, 0);
|
||||||
|
background: -moz-linear-gradient(
|
||||||
|
top,
|
||||||
|
rgba(255, 254, 247, 0) 0%,
|
||||||
|
rgba(255, 254, 247, 0.55) 22%,
|
||||||
|
rgba(255, 254, 247, 0.7) 42%,
|
||||||
|
rgba(255, 254, 247, 0.71) 43%,
|
||||||
|
rgba(255, 254, 247, 0.78) 61%,
|
||||||
|
rgba(255, 254, 247, 0.92) 75%,
|
||||||
|
rgba(255, 254, 247, 1) 87%,
|
||||||
|
rgba(255, 254, 247, 1) 100%
|
||||||
|
);
|
||||||
|
background: -webkit-gradient(
|
||||||
|
left top,
|
||||||
|
left bottom,
|
||||||
|
color-stop(0%, rgba(255, 254, 247, 0)),
|
||||||
|
color-stop(22%, rgba(255, 254, 247, 0.55)),
|
||||||
|
color-stop(42%, rgba(255, 254, 247, 0.7)),
|
||||||
|
color-stop(43%, rgba(255, 254, 247, 0.71)),
|
||||||
|
color-stop(61%, rgba(255, 254, 247, 0.78)),
|
||||||
|
color-stop(75%, rgba(255, 254, 247, 0.92)),
|
||||||
|
color-stop(87%, rgba(255, 254, 247, 1)),
|
||||||
|
color-stop(100%, rgba(255, 254, 247, 1))
|
||||||
|
);
|
||||||
|
background: -webkit-linear-gradient(
|
||||||
|
top,
|
||||||
|
rgba(255, 254, 247, 0) 0%,
|
||||||
|
rgba(255, 254, 247, 0.55) 22%,
|
||||||
|
rgba(255, 254, 247, 0.7) 42%,
|
||||||
|
rgba(255, 254, 247, 0.71) 43%,
|
||||||
|
rgba(255, 254, 247, 0.78) 61%,
|
||||||
|
rgba(255, 254, 247, 0.92) 75%,
|
||||||
|
rgba(255, 254, 247, 1) 87%,
|
||||||
|
rgba(255, 254, 247, 1) 100%
|
||||||
|
);
|
||||||
|
background: -o-linear-gradient(
|
||||||
|
top,
|
||||||
|
rgba(255, 254, 247, 0) 0%,
|
||||||
|
rgba(255, 254, 247, 0.55) 22%,
|
||||||
|
rgba(255, 254, 247, 0.7) 42%,
|
||||||
|
rgba(255, 254, 247, 0.71) 43%,
|
||||||
|
rgba(255, 254, 247, 0.78) 61%,
|
||||||
|
rgba(255, 254, 247, 0.92) 75%,
|
||||||
|
rgba(255, 254, 247, 1) 87%,
|
||||||
|
rgba(255, 254, 247, 1) 100%
|
||||||
|
);
|
||||||
|
background: -ms-linear-gradient(
|
||||||
|
top,
|
||||||
|
rgba(255, 254, 247, 0) 0%,
|
||||||
|
rgba(255, 254, 247, 0.55) 22%,
|
||||||
|
rgba(255, 254, 247, 0.7) 42%,
|
||||||
|
rgba(255, 254, 247, 0.71) 43%,
|
||||||
|
rgba(255, 254, 247, 0.78) 61%,
|
||||||
|
rgba(255, 254, 247, 0.92) 75%,
|
||||||
|
rgba(255, 254, 247, 1) 87%,
|
||||||
|
rgba(255, 254, 247, 1) 100%
|
||||||
|
);
|
||||||
|
background: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
rgba(255, 254, 247, 0) 0%,
|
||||||
|
rgba(255, 254, 247, 0.55) 22%,
|
||||||
|
rgba(255, 254, 247, 0.7) 42%,
|
||||||
|
rgba(255, 254, 247, 0.71) 43%,
|
||||||
|
rgba(255, 254, 247, 0.78) 61%,
|
||||||
|
rgba(255, 254, 247, 0.92) 75%,
|
||||||
|
rgba(255, 254, 247, 1) 87%,
|
||||||
|
rgba(255, 254, 247, 1) 100%
|
||||||
|
);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
main,
|
||||||
|
footer {
|
||||||
|
width: 70%;
|
||||||
|
margin: 3rem auto;
|
||||||
|
min-width: 850px;
|
||||||
|
padding: 0 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------- Content ------------------- */
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 3em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2.5em;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
line-height: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
line-height: 1.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cited {
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.b {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.i {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.align_right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.align_left {
|
||||||
|
text-align: left;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.align_center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.float_left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.float_right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.clear_both {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.special {
|
||||||
|
color: #b7595b;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.keyword {
|
||||||
|
color: #db6f50;
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.gray {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links */
|
||||||
|
main a:link,
|
||||||
|
main a:visited {
|
||||||
|
color: #eb690b;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
main a:focus,
|
||||||
|
main a:hover,
|
||||||
|
main a:active {
|
||||||
|
color: #eb690b;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-position: outside;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-left: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
line-height: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------- Article ------- */
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2.7em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form input[type='button'] {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 1px 20px 3px 20px;
|
||||||
|
background-color: #93412b;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid white;
|
||||||
|
font-size: 1em;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form input[type='button']:hover {
|
||||||
|
background-color: white;
|
||||||
|
color: #93412b;
|
||||||
|
border: 1px solid #93412b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form select {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 1em;
|
||||||
|
background-color: white;
|
||||||
|
color: #93412b;
|
||||||
|
border: 1px solid #93412b;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------- Chat ------- */
|
||||||
|
|
||||||
|
#chat {
|
||||||
|
width: 100%;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #9c352f;
|
||||||
|
height: 20rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_window {
|
||||||
|
background-color: white;
|
||||||
|
width: 85%;
|
||||||
|
float: left;
|
||||||
|
height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_history {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 8%;
|
||||||
|
max-height: 92%;
|
||||||
|
padding: 0px 0px 5px 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_history p {
|
||||||
|
font-size: 0.6em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_text {
|
||||||
|
height: 8%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_text input {
|
||||||
|
width: 98%;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_members {
|
||||||
|
list-style-type: none;
|
||||||
|
height: 100%;
|
||||||
|
width: 15%;
|
||||||
|
margin-left: 85%;
|
||||||
|
border-left: 1px solid #9c352f;
|
||||||
|
text-align: right;
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-width: 100px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_members li {
|
||||||
|
line-height: 1.2em;
|
||||||
|
padding: 5px 10px 2px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_members .highlighted {
|
||||||
|
background-color: #c14d45;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.chat_member {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.chat_member1 {
|
||||||
|
color: #3626c8;
|
||||||
|
}
|
||||||
|
.chat_member2 {
|
||||||
|
color: #e38d0b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#member_search {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 15%;
|
||||||
|
height: 8%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#member_search input {
|
||||||
|
width: 88%;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 316 B |
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,45 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Übung 1: Almost Famous Quotes 1</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
<link rel="stylesheet" href="assets/css/styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header></header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1>Famous Quotes</h1>
|
||||||
|
|
||||||
|
<blockquote></blockquote>
|
||||||
|
</main>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
// 1
|
||||||
|
// Ändern Sie mit Hilfe von JS die Überschrift (h1) der HTML-Seite in Almost Famous Quotes.
|
||||||
|
|
||||||
|
const headingEl = document.querySelector('h1');
|
||||||
|
headingEl.textContent = 'Almost Famous Quotes';
|
||||||
|
// 2
|
||||||
|
// Die Seite enthält ein leeres blockquote-Element. Öffnen Sie die HTML-Seite in Chrome. Geben Sie in der Konsole eine Zeile JS-Code ein, die das Element mit folgendem Inhalt befüllt:
|
||||||
|
|
||||||
|
// <p>
|
||||||
|
// I have always wished for my computer to be as easy to use as my telephone;
|
||||||
|
// my wish has come true because I can no longer figure out how to use my
|
||||||
|
// telephone.
|
||||||
|
// </p>
|
||||||
|
// <footer>— <cite>Bjarne Stroustrup</cite></footer>
|
||||||
|
|
||||||
|
const blockquoteEl = document.querySelector('blockquote');
|
||||||
|
blockquoteEl.innerHTML = `
|
||||||
|
<p>
|
||||||
|
I have always wished for my computer to be as easy to use as my telephone;
|
||||||
|
my wish has come true because I can no longer figure out how to use my
|
||||||
|
telephone.
|
||||||
|
</p><footer>— <cite>Bjarne Stroustrup</cite></footer>
|
||||||
|
`;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
/* -------------------------------------------- Haupt CSS fuer alle Seiten -------------------------------------------- */
|
||||||
|
|
||||||
|
/* ---------------- CSS-Reset ------------------- */
|
||||||
|
html, body, a, div, h1, h2, h3, h4, h5, h6, span, p, img, strong, ul, li, table, th, td, tr {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
border: 0px none;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-variant: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
table-layout: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------- Body / HTML ------------------- */
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 100%;
|
||||||
|
background-color: #fffef7;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: normal;
|
||||||
|
color: black;
|
||||||
|
margin: 0rem auto 2rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------- layout ------------------- */
|
||||||
|
|
||||||
|
header {
|
||||||
|
|
||||||
|
background: url(../img/js_header.png) left top no-repeat transparent;
|
||||||
|
background-size: cover;
|
||||||
|
height: 250px;
|
||||||
|
min-width: 850px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header:after {
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
height: 250px;
|
||||||
|
background: rgba(255,254,247,0);
|
||||||
|
background: -moz-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,254,247,0)), color-stop(22%, rgba(255,254,247,0.55)), color-stop(42%, rgba(255,254,247,0.7)), color-stop(43%, rgba(255,254,247,0.71)), color-stop(61%, rgba(255,254,247,0.78)), color-stop(75%, rgba(255,254,247,0.92)), color-stop(87%, rgba(255,254,247,1)), color-stop(100%, rgba(255,254,247,1)));
|
||||||
|
background: -webkit-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
background: -o-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
background: -ms-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
background: linear-gradient(to bottom, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
main,
|
||||||
|
footer {
|
||||||
|
width: 70%;
|
||||||
|
margin: 3rem auto;
|
||||||
|
min-width: 850px;
|
||||||
|
padding: 0 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------- Content ------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 3em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2.5em;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
line-height: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
line-height: 1.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cited {
|
||||||
|
font-style: italic;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u {text-decoration: underline;}
|
||||||
|
.b {font-weight: bold;}
|
||||||
|
.i {font-style: italic}
|
||||||
|
.align_right {text-align: right;}
|
||||||
|
.align_left {text-align: left; margin-right: 10px;}
|
||||||
|
.align_center {text-align: center;}
|
||||||
|
.float_left {float: left;}
|
||||||
|
.float_right {float: right;}
|
||||||
|
.clear_both {clear: both;}
|
||||||
|
strong {font-weight: bold;}
|
||||||
|
.special { color: #b7595b; font-weight: bold; }
|
||||||
|
.keyword { color: #db6f50; font-weight: bold; font-style: italic;}
|
||||||
|
.gray {color: gray;}
|
||||||
|
|
||||||
|
/* Links */
|
||||||
|
main a:link,
|
||||||
|
main a:visited {
|
||||||
|
color: #eb690b;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
main a:focus,
|
||||||
|
main a:hover,
|
||||||
|
main a:active {color: #eb690b;}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-position: outside;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-left: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
line-height: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------- Article ------- */
|
||||||
|
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2.7em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form input[type=button] {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 1px 20px 3px 20px;
|
||||||
|
background-color: #93412b;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid white;
|
||||||
|
font-size: 1em;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form input[type=button]:hover {
|
||||||
|
background-color: white;
|
||||||
|
color: #93412b;
|
||||||
|
border: 1px solid #93412b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form select {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 1em;
|
||||||
|
background-color: white;
|
||||||
|
color: #93412b;
|
||||||
|
border: 1px solid #93412b;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------- Chat ------- */
|
||||||
|
|
||||||
|
|
||||||
|
#chat {
|
||||||
|
width: 100%;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #9c352f;
|
||||||
|
height: 20rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_window {
|
||||||
|
background-color: white;
|
||||||
|
width: 85%;
|
||||||
|
float: left;
|
||||||
|
height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_history {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 8%;
|
||||||
|
max-height: 92%;
|
||||||
|
padding: 0px 0px 5px 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_history p {
|
||||||
|
font-size: .6em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_text {
|
||||||
|
height: 8%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_text input {
|
||||||
|
width: 98%;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_members {
|
||||||
|
list-style-type: none;
|
||||||
|
height: 100%;
|
||||||
|
width: 15%;
|
||||||
|
margin-left: 85%;
|
||||||
|
border-left: 1px solid #9c352f;
|
||||||
|
text-align: right;
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-width: 100px;
|
||||||
|
font-size: .8em;
|
||||||
|
padding-top: 5px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_members li {
|
||||||
|
line-height: 1.2em;
|
||||||
|
padding: 5px 10px 2px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#chat_members .highlighted {
|
||||||
|
background-color: #c14d45;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.chat_member {font-weight: bold;}
|
||||||
|
.chat_member1 { color: #3626c8;}
|
||||||
|
.chat_member2 { color: #e38d0b;}
|
||||||
|
|
||||||
|
#member_search {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 15%;
|
||||||
|
height: 8%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#member_search input {
|
||||||
|
width: 88%;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 316 B |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 49 KiB |
@@ -0,0 +1,112 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
|
<title>010010000100111101010100</title>
|
||||||
|
<meta name="description" content="JavaScript. HTML mühelos manipuliert" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="assets/css/styles.css" type="text/css" media="screen" />
|
||||||
|
<link rel="shortcut icon" href="assets/img/favicon.ico" type="image/x-icon" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header></header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1 class="article">
|
||||||
|
Hot Binary Heat Changing Mug
|
||||||
|
<span class="keyword">"010010000100111101010100"</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<img
|
||||||
|
alt="Hot Binary Heat Changing Mug"
|
||||||
|
src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug.gif"
|
||||||
|
class="float_left"
|
||||||
|
id="product_img" />
|
||||||
|
|
||||||
|
<h2>Description</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Numbers make up
|
||||||
|
<span class="special">everything</span> in our digital world. They flow around us, invisible like the Force or
|
||||||
|
the Matrix, controlling all our many computer-y devices. Two numbers, in particular:
|
||||||
|
<span class="special">0 and 1</span>. <span class="b i">Off and On</span>. Well, we can tell you this: when
|
||||||
|
there's no coffee in our cup, we're completely OFF our game. But when our mug is full of hot coffee, we're
|
||||||
|
totally ON. And now, with the <span class="keyword">Hot Binary Heat Changing Mug</span>, there's a mug that
|
||||||
|
tells us which state our mug is in. In binary!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
See, the
|
||||||
|
<span class="keyword">Hot Binary Heat Changing Mug</span>
|
||||||
|
looks like just a dark mug with binary numbers all over it. That's its OFF or cold state. Add hot coffee (or any
|
||||||
|
liquid) and a series of digits will turn white. Read them continuously from left to right, and you'll read:
|
||||||
|
<span class="keyword">010010000100111101010100</span>. That's <span class="special">in binary</span>. Of course,
|
||||||
|
your
|
||||||
|
<span class="keyword">Hot Binary Heat Changing Mug</span>
|
||||||
|
could just be paying you a compliment. Cheeky, mug.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<img alt="010010000100111101010100" src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug_grid_embed.jpg" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Product Specifications</h2>
|
||||||
|
|
||||||
|
<ul id="product_specification">
|
||||||
|
<li class="keyword">Hot Binary Heat Changing Mug</li>
|
||||||
|
<li>
|
||||||
|
As you add hot liquids, the binary for "HOT" appears (read from left to right in one line, not two:
|
||||||
|
010010000100111101010100)
|
||||||
|
</li>
|
||||||
|
<li>A <span class="keyword">ThinkGeek</span> creation and exclusive!</li>
|
||||||
|
<li>
|
||||||
|
Care Instructions:
|
||||||
|
<span class="i b">Hand wash only. Not microwave or dishwasher safe.</span>
|
||||||
|
</li>
|
||||||
|
<li>Materials: Ceramic</li>
|
||||||
|
<li>Dimensions: approx. 3.15" diameter x 3.75" tall</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>You wanna buy it?</h3>
|
||||||
|
|
||||||
|
<p class="buy_info_text">If you like to buy this brilliant mug, just do the following steps:</p>
|
||||||
|
|
||||||
|
<ol class="model" data-model="LDV73C-X3">
|
||||||
|
<li>Select how many items do you want.</li>
|
||||||
|
<li>Press "buy".</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<form id="buy_form">
|
||||||
|
<select>
|
||||||
|
<option>1 item</option>
|
||||||
|
<option>2 items</option>
|
||||||
|
<option>3 items</option>
|
||||||
|
<option>4 items</option>
|
||||||
|
</select>
|
||||||
|
<input type="button" value="buy" />
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer>(C) by ThinkGeek – Produkttext mit freundlicher Genehmigung von ThinkGeek Inc.</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
(() => {
|
||||||
|
// Tippen Sie eine Abfrage in die Konsole, die:
|
||||||
|
// 1. das h1-Element findet.
|
||||||
|
// 2.das Element mit der id buy_form findet.
|
||||||
|
// 3. das Element mit der id product_img findet.
|
||||||
|
console.log(document.querySelector('h1'));
|
||||||
|
// console.log(document.getElementsByTagName('h1')[0]);
|
||||||
|
|
||||||
|
console.log(document.querySelector('#buy_form'));
|
||||||
|
console.log(document.getElementById('buy_form'));
|
||||||
|
|
||||||
|
console.log(document.querySelector('#product_img'));
|
||||||
|
console.log(document.getElementById('product_img'));
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
/* -------------------------------------------- Haupt CSS fuer alle Seiten -------------------------------------------- */
|
||||||
|
|
||||||
|
/* ---------------- CSS-Reset ------------------- */
|
||||||
|
html, body, a, div, h1, h2, h3, h4, h5, h6, span, p, img, strong, ul, li, table, th, td, tr {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
border: 0px none;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-variant: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
table-layout: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------- Body / HTML ------------------- */
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 100%;
|
||||||
|
background-color: #fffef7;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: normal;
|
||||||
|
color: black;
|
||||||
|
margin: 0rem auto 2rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------- layout ------------------- */
|
||||||
|
|
||||||
|
header {
|
||||||
|
|
||||||
|
background: url(../img/js_header.png) left top no-repeat transparent;
|
||||||
|
background-size: cover;
|
||||||
|
height: 250px;
|
||||||
|
min-width: 850px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header:after {
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
height: 250px;
|
||||||
|
background: rgba(255,254,247,0);
|
||||||
|
background: -moz-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,254,247,0)), color-stop(22%, rgba(255,254,247,0.55)), color-stop(42%, rgba(255,254,247,0.7)), color-stop(43%, rgba(255,254,247,0.71)), color-stop(61%, rgba(255,254,247,0.78)), color-stop(75%, rgba(255,254,247,0.92)), color-stop(87%, rgba(255,254,247,1)), color-stop(100%, rgba(255,254,247,1)));
|
||||||
|
background: -webkit-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
background: -o-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
background: -ms-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
background: linear-gradient(to bottom, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
main,
|
||||||
|
footer {
|
||||||
|
width: 70%;
|
||||||
|
margin: 3rem auto;
|
||||||
|
min-width: 850px;
|
||||||
|
padding: 0 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------- Content ------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 3em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2.5em;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
line-height: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
line-height: 1.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cited {
|
||||||
|
font-style: italic;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u {text-decoration: underline;}
|
||||||
|
.b {font-weight: bold;}
|
||||||
|
.i {font-style: italic}
|
||||||
|
.align_right {text-align: right;}
|
||||||
|
.align_left {text-align: left; margin-right: 10px;}
|
||||||
|
.align_center {text-align: center;}
|
||||||
|
.float_left {float: left;}
|
||||||
|
.float_right {float: right;}
|
||||||
|
.clear_both {clear: both;}
|
||||||
|
strong {font-weight: bold;}
|
||||||
|
.special { color: #b7595b; font-weight: bold; }
|
||||||
|
.keyword { color: #db6f50; font-weight: bold; font-style: italic;}
|
||||||
|
.gray {color: gray;}
|
||||||
|
|
||||||
|
/* Links */
|
||||||
|
main a:link,
|
||||||
|
main a:visited {
|
||||||
|
color: #eb690b;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
main a:focus,
|
||||||
|
main a:hover,
|
||||||
|
main a:active {color: #eb690b;}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-position: outside;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-left: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
line-height: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------- Article ------- */
|
||||||
|
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #93412b;
|
||||||
|
font-size: 2.7em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form input[type=button] {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 1px 20px 3px 20px;
|
||||||
|
background-color: #93412b;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid white;
|
||||||
|
font-size: 1em;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form input[type=button]:hover {
|
||||||
|
background-color: white;
|
||||||
|
color: #93412b;
|
||||||
|
border: 1px solid #93412b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#buy_form select {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 1em;
|
||||||
|
background-color: white;
|
||||||
|
color: #93412b;
|
||||||
|
border: 1px solid #93412b;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------- Chat ------- */
|
||||||
|
|
||||||
|
|
||||||
|
#chat {
|
||||||
|
width: 100%;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #9c352f;
|
||||||
|
height: 20rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_window {
|
||||||
|
background-color: white;
|
||||||
|
width: 85%;
|
||||||
|
float: left;
|
||||||
|
height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_history {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 8%;
|
||||||
|
max-height: 92%;
|
||||||
|
padding: 0px 0px 5px 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_history p {
|
||||||
|
font-size: .6em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_text {
|
||||||
|
height: 8%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_text input {
|
||||||
|
width: 98%;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_members {
|
||||||
|
list-style-type: none;
|
||||||
|
height: 100%;
|
||||||
|
width: 15%;
|
||||||
|
margin-left: 85%;
|
||||||
|
border-left: 1px solid #9c352f;
|
||||||
|
text-align: right;
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-width: 100px;
|
||||||
|
font-size: .8em;
|
||||||
|
padding-top: 5px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat_members li {
|
||||||
|
line-height: 1.2em;
|
||||||
|
padding: 5px 10px 2px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#chat_members .highlighted {
|
||||||
|
background-color: #c14d45;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.chat_member {font-weight: bold;}
|
||||||
|
.chat_member1 { color: #3626c8;}
|
||||||
|
.chat_member2 { color: #e38d0b;}
|
||||||
|
|
||||||
|
#member_search {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 15%;
|
||||||
|
height: 8%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#member_search input {
|
||||||
|
width: 88%;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 316 B |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 49 KiB |
@@ -0,0 +1,124 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
|
<title>010010000100111101010100</title>
|
||||||
|
<meta name="description" content="JavaScript. HTML mühelos manipuliert" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="assets/css/styles.css" type="text/css" media="screen" />
|
||||||
|
<link rel="shortcut icon" href="assets/img/favicon.ico" type="image/x-icon" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header></header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1 class="article">
|
||||||
|
Hot Binary Heat Changing Mug
|
||||||
|
<span class="keyword">"010010000100111101010100"</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<img
|
||||||
|
alt="Hot Binary Heat Changing Mug"
|
||||||
|
src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug.gif"
|
||||||
|
class="float_left"
|
||||||
|
id="product_img" />
|
||||||
|
|
||||||
|
<h2>Description</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Numbers make up
|
||||||
|
<span class="special">everything</span> in our digital world. They flow around us, invisible like the Force or
|
||||||
|
the Matrix, controlling all our many computer-y devices. Two numbers, in particular:
|
||||||
|
<span class="special">0 and 1</span>. <span class="b i">Off and On</span>. Well, we can tell you this: when
|
||||||
|
there's no coffee in our cup, we're completely OFF our game. But when our mug is full of hot coffee, we're
|
||||||
|
totally ON. And now, with the <span class="keyword">Hot Binary Heat Changing Mug</span>, there's a mug that
|
||||||
|
tells us which state our mug is in. In binary!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
See, the
|
||||||
|
<span class="keyword">Hot Binary Heat Changing Mug</span>
|
||||||
|
looks like just a dark mug with binary numbers all over it. That's its OFF or cold state. Add hot coffee (or any
|
||||||
|
liquid) and a series of digits will turn white. Read them continuously from left to right, and you'll read:
|
||||||
|
<span class="keyword">010010000100111101010100</span>. That's <span class="special">in binary</span>. Of course,
|
||||||
|
your
|
||||||
|
<span class="keyword">Hot Binary Heat Changing Mug</span>
|
||||||
|
could just be paying you a compliment. Cheeky, mug.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<img alt="010010000100111101010100" src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug_grid_embed.jpg" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Product Specifications</h2>
|
||||||
|
|
||||||
|
<ul id="product_specification">
|
||||||
|
<li class="keyword">Hot Binary Heat Changing Mug</li>
|
||||||
|
<li>
|
||||||
|
As you add hot liquids, the binary for "HOT" appears (read from left to right in one line, not two:
|
||||||
|
010010000100111101010100)
|
||||||
|
</li>
|
||||||
|
<li>A <span class="keyword">ThinkGeek</span> creation and exclusive!</li>
|
||||||
|
<li>
|
||||||
|
Care Instructions:
|
||||||
|
<span class="i b">Hand wash only. Not microwave or dishwasher safe.</span>
|
||||||
|
</li>
|
||||||
|
<li>Materials: Ceramic</li>
|
||||||
|
<li>Dimensions: approx. 3.15" diameter x 3.75" tall</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>You wanna buy it?</h3>
|
||||||
|
|
||||||
|
<p class="buy_info_text">If you like to buy this brilliant mug, just do the following steps:</p>
|
||||||
|
|
||||||
|
<ol class="model" data-model="LDV73C-X3">
|
||||||
|
<li>Select how many items do you want.</li>
|
||||||
|
<li>Press "buy".</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<form id="buy_form">
|
||||||
|
<select>
|
||||||
|
<option>1 item</option>
|
||||||
|
<option>2 items</option>
|
||||||
|
<option>3 items</option>
|
||||||
|
<option>4 items</option>
|
||||||
|
</select>
|
||||||
|
<input type="button" value="buy" />
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer>(C) by ThinkGeek – Produkttext mit freundlicher Genehmigung von ThinkGeek Inc.</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
(() => {
|
||||||
|
// alle li-Elemente findet.
|
||||||
|
const listItems = document.querySelectorAll('li');
|
||||||
|
|
||||||
|
// alle h2-Elemente findet.
|
||||||
|
const levelTwoHeadings = document.querySelectorAll('h2');
|
||||||
|
|
||||||
|
// alle Elemente mit der Klasse special findet.
|
||||||
|
const specialElements = document.querySelectorAll('.special');
|
||||||
|
|
||||||
|
// alle li-Elemente mit der Klasse keyword findet.
|
||||||
|
const keywordListItems = document.querySelectorAll('li.keyword');
|
||||||
|
|
||||||
|
// alle span-Elemente mit der Klasse special findet.
|
||||||
|
const specialSpans = document.querySelectorAll('span.special');
|
||||||
|
|
||||||
|
// alle Elemente findet, die die Klassen i UND b haben.
|
||||||
|
const italicBoldElements = document.querySelectorAll('.i.b');
|
||||||
|
|
||||||
|
console.log('List items:', listItems);
|
||||||
|
console.log('Level two headings:', levelTwoHeadings);
|
||||||
|
console.log('Special elements:', specialElements);
|
||||||
|
console.log('Keyword list items:', keywordListItems);
|
||||||
|
console.log('Special spans:', specialSpans);
|
||||||
|
console.log('Italic and bold elements:', italicBoldElements);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||