feat: enhance Excalidraw editor UI and autosave functionality
- Redesigned editor toolbar with improved layout and accessibility attributes - Added automatic save after 7 seconds of inactivity for better data protection - Replaced emoji icons with SVG icons for consistent styling and accessibility - Added success toasts for PNG/SVG exports with destination path - Updated button styles and layout for better visual hierarchy - Added aria-labels and improved keyboard navigation support - Made action buttons optionally hideable via
This commit is contained in:
parent
5647b42d8a
commit
b1f142c4f7
@ -3,25 +3,27 @@
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Indicateur de sauvegarde (cliquable) -->
|
||||
<button
|
||||
type="button"
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-md transition-colors"
|
||||
<button
|
||||
*ngIf="showInlineActions"
|
||||
type="button"
|
||||
class="btn btn-sm btn-ghost flex items-center gap-2"
|
||||
[class.cursor-pointer]="!isLoading() && !isSaving()"
|
||||
[class.cursor-wait]="isSaving()"
|
||||
[class.cursor-not-allowed]="isLoading()"
|
||||
(click)="saveNow()"
|
||||
[disabled]="isLoading()"
|
||||
[attr.aria-label]="dirty() ? 'Sauver maintenant' : 'Déjà sauvegardé'"
|
||||
title="{{dirty() ? 'Non sauvegardé - Cliquer pour sauvegarder (Ctrl+S)' : isSaving() ? 'Sauvegarde en cours...' : 'Sauvegardé'}}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
[class.text-red-500]="dirty() && !isSaving()"
|
||||
[class.text-muted]="!dirty() && !isSaving()"
|
||||
@ -32,33 +34,51 @@
|
||||
<polyline points="17 21 17 13 7 13 7 21"></polyline>
|
||||
<polyline points="7 3 7 8 15 8"></polyline>
|
||||
</svg>
|
||||
<span class="text-xs font-medium" [class.text-red-500]="dirty() && !isSaving()" [class.text-muted]="!dirty() && !isSaving()" [class.text-yellow-500]="isSaving()">
|
||||
<span *ngIf="showInlineActions" class="text-xs font-medium" [class.text-red-500]="dirty() && !isSaving()" [class.text-muted]="!dirty() && !isSaving()" [class.text-yellow-500]="isSaving()">
|
||||
{{isSaving() ? 'Sauvegarde...' : dirty() ? 'Non sauvegardé' : 'Sauvegardé'}}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm"
|
||||
|
||||
<button
|
||||
*ngIf="showInlineActions"
|
||||
type="button"
|
||||
class="btn btn-sm flex items-center gap-2"
|
||||
(click)="exportPNG()"
|
||||
[disabled]="isLoading() || isSaving() || !excalidrawReady"
|
||||
aria-label="Exporter en PNG"
|
||||
>
|
||||
🖼️ Export PNG
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="3" width="18" height="14" rx="2" ry="2"></rect>
|
||||
<circle cx="8" cy="8" r="2"></circle>
|
||||
<path d="M21 17l-5-6-4 5-2-3-5 6"></path>
|
||||
</svg>
|
||||
Export PNG
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm"
|
||||
|
||||
<button
|
||||
*ngIf="showInlineActions"
|
||||
type="button"
|
||||
class="btn btn-sm flex items-center gap-2"
|
||||
(click)="exportSVG()"
|
||||
[disabled]="isLoading() || isSaving() || !excalidrawReady"
|
||||
aria-label="Exporter en SVG"
|
||||
>
|
||||
🧩 Export SVG
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="7 10 12 15 17 10"/>
|
||||
<line x1="12" y1="15" x2="12" y2="3"/>
|
||||
</svg>
|
||||
Export SVG
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm"
|
||||
|
||||
<button
|
||||
*ngIf="showInlineActions"
|
||||
type="button"
|
||||
class="btn btn-sm flex items-center gap-2"
|
||||
(click)="toggleFullscreen()"
|
||||
[disabled]="isLoading()"
|
||||
[title]="isFullscreen() ? 'Quitter le mode pleine écran' : 'Passer en mode pleine écran'"
|
||||
aria-label="Basculer le mode plein écran"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -76,7 +96,7 @@
|
||||
<polyline points="10,17 15,12 10,7"></polyline>
|
||||
<line x1="15" x2="3" y1="12" y2="12"></line>
|
||||
</svg>
|
||||
{{isFullscreen() ? 'Quitter FS' : 'Pleine écran'}}
|
||||
{{isFullscreen() ? 'Quitter FS' : 'Plein écran'}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
signal
|
||||
} from '@angular/core';
|
||||
import { firstValueFrom, fromEvent, of, Subscription, interval } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, map, switchMap, tap, catchError, filter } from 'rxjs/operators';
|
||||
import { debounceTime, distinctUntilChanged, map, switchMap, tap, catchError, filter, mergeWith } from 'rxjs/operators';
|
||||
import { DrawingsFileService, ExcalidrawScene } from './drawings-file.service';
|
||||
import { ExcalidrawIoService } from './excalidraw-io.service';
|
||||
import { DrawingsPreviewService } from './drawings-preview.service';
|
||||
@ -32,6 +32,7 @@ import { ThemeService } from '../../core/services/theme.service';
|
||||
})
|
||||
export class DrawingsEditorComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
@Input() path: string = '';
|
||||
@Input() showInlineActions: boolean = true;
|
||||
|
||||
@ViewChild('editorEl', { static: false }) editorEl?: ElementRef<HTMLElement & {
|
||||
setScene: (scene: any) => void;
|
||||
@ -628,42 +629,76 @@ export class DrawingsEditorComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
}
|
||||
});
|
||||
|
||||
// Subscription 2: Handle auto-saving (disabled temporarily)
|
||||
// this.saveSub = sceneChange$.pipe(
|
||||
// distinctUntilChanged((prev, curr) => prev.hash === curr.hash),
|
||||
// debounceTime(2000),
|
||||
// filter(({ hash }) => this.lastSavedHash !== hash),
|
||||
// filter(() => !this.isSaving()),
|
||||
// tap(({ hash }) => {
|
||||
// console.log('💾 Autosaving... hash:', hash.substring(0, 10));
|
||||
// this.isSaving.set(true);
|
||||
// this.error.set(null);
|
||||
// }),
|
||||
// switchMap(({ scene, hash }) =>
|
||||
// this.files.put(this.path, scene).pipe(
|
||||
// tap(async () => {
|
||||
// console.log('✅ Autosave successful', { newHash: hash.substring(0, 10) });
|
||||
// this.lastSavedHash = hash;
|
||||
// this.dirty.set(false);
|
||||
// this.isSaving.set(false);
|
||||
// this.hasConflict.set(false);
|
||||
// try { await this.savePreviewPNG(); } catch (e) { console.warn('PNG preview update failed', e); }
|
||||
// }),
|
||||
// catchError((e) => {
|
||||
// console.error('❌ Save error:', e);
|
||||
// const status = e?.status ?? e?.statusCode;
|
||||
// if (status === 409) {
|
||||
// this.error.set('Conflit: le fichier a été modifié sur le disque.');
|
||||
// this.hasConflict.set(true);
|
||||
// } else {
|
||||
// this.error.set('Erreur de sauvegarde. Veuillez réessayer.');
|
||||
// }
|
||||
// this.isSaving.set(false);
|
||||
// return of({ rev: '' } as any);
|
||||
// })
|
||||
// )
|
||||
// )
|
||||
// ).subscribe();
|
||||
// Subscription 2: Natural autosave after inactivity (idle-based)
|
||||
const triggers$ = fromEvent(host, 'pointermove').pipe(
|
||||
mergeWith(
|
||||
fromEvent(document, 'keydown'),
|
||||
fromEvent(host, 'wheel'),
|
||||
sceneChange$.pipe(map(() => null))
|
||||
),
|
||||
debounceTime(7000),
|
||||
filter(() => this.dirty() && !this.isSaving())
|
||||
);
|
||||
|
||||
this.saveSub = triggers$.pipe(
|
||||
switchMap(() => {
|
||||
const scene = this.scene();
|
||||
if (!scene) return of(null);
|
||||
const hash = this.hashScene(scene);
|
||||
if (this.lastSavedHash === hash) return of(null);
|
||||
this.isSaving.set(true);
|
||||
this.error.set(null);
|
||||
const isExMd = /\.excalidraw\.md$/i.test(this.path || '');
|
||||
|
||||
const save$ = isExMd
|
||||
? this.files.getText(this.path).pipe(
|
||||
catchError(() => of('')),
|
||||
switchMap((existing) => {
|
||||
let fm = this.excalIo.extractFrontMatter(existing) || null;
|
||||
if (fm) {
|
||||
if (!/excalidraw-plugin\s*:/i.test(fm)) {
|
||||
fm = fm.replace(/^---\s*\n/, `---\nexcalidraw-plugin: parsed\n`);
|
||||
} else {
|
||||
fm = fm.replace(/excalidraw-plugin\s*:\s*.*?(\r?\n)/i, `excalidraw-plugin: parsed$1`);
|
||||
}
|
||||
const stamp = new Date().toISOString();
|
||||
if (/^updated\s*:/mi.test(fm)) {
|
||||
fm = fm.replace(/updated\s*:\s*.*?(\r?\n)/i, `updated: "${stamp}"$1`);
|
||||
} else {
|
||||
fm = fm.replace(/^---\s*\n/, `---\nupdated: "${stamp}"\n`);
|
||||
}
|
||||
} else {
|
||||
fm = `---\nexcalidraw-plugin: parsed\nupdated: "${new Date().toISOString()}"\n---`;
|
||||
}
|
||||
const md = this.excalIo.toObsidianMd(scene as any, fm);
|
||||
return this.files.putText(this.path, md);
|
||||
})
|
||||
)
|
||||
: this.files.put(this.path, scene);
|
||||
|
||||
return save$.pipe(
|
||||
tap(async () => {
|
||||
this.lastSavedHash = hash;
|
||||
this.dirty.set(false);
|
||||
this.isSaving.set(false);
|
||||
this.hasConflict.set(false);
|
||||
try { await this.savePreviewPNG(); } catch (e) { console.warn('PNG preview update failed', e); }
|
||||
}),
|
||||
catchError((e) => {
|
||||
console.error('❌ Autosave error:', e);
|
||||
const status = (e as any)?.status ?? (e as any)?.statusCode;
|
||||
if (status === 409) {
|
||||
this.error.set('Conflit: le fichier a été modifié sur le disque.');
|
||||
this.hasConflict.set(true);
|
||||
} else {
|
||||
this.error.set('Erreur de sauvegarde automatique.');
|
||||
}
|
||||
this.isSaving.set(false);
|
||||
return of(null);
|
||||
})
|
||||
);
|
||||
})
|
||||
).subscribe();
|
||||
|
||||
console.log('✓ Dirty check and Autosave subscriptions active');
|
||||
|
||||
@ -725,6 +760,11 @@ export class DrawingsEditorComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
const target = `${base}.png`;
|
||||
await firstValueFrom(this.files.putBinary(target, blob, 'image/png'));
|
||||
this.error.set(null);
|
||||
try {
|
||||
const norm = target.replace(/\\/g, '/');
|
||||
const dir = norm.includes('/') ? norm.substring(0, norm.lastIndexOf('/')) : '/';
|
||||
this.showToast(`PNG exporté avec succès dans ${dir}`, 'success');
|
||||
} catch {}
|
||||
} catch (err) {
|
||||
console.error('Error exporting PNG:', err);
|
||||
this.error.set('Erreur lors de l\'export en PNG');
|
||||
@ -752,6 +792,11 @@ export class DrawingsEditorComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
const target = `${base}.svg`;
|
||||
await firstValueFrom(this.files.putBinary(target, blob, 'image/svg+xml'));
|
||||
this.error.set(null);
|
||||
try {
|
||||
const norm = target.replace(/\\/g, '/');
|
||||
const dir = norm.includes('/') ? norm.substring(0, norm.lastIndexOf('/')) : '/';
|
||||
this.showToast(`SVG exporté avec succès dans ${dir}`, 'success');
|
||||
} catch {}
|
||||
} catch (err) {
|
||||
console.error('Error exporting SVG:', err);
|
||||
this.error.set('Erreur lors de l\'export en SVG');
|
||||
|
||||
@ -45,6 +45,16 @@ import { TrashExplorerComponent } from '../../layout/sidebar/trash/trash-explore
|
||||
class="w-full text-left block text-sm px-3 py-2 rounded-lg hover:bg-surface1 dark:hover:bg-card active:bg-surface2 dark:active:bg-gray-700 text-main dark:text-main hover:text-main dark:hover:text-gray-100 transition-all active:scale-[0.98] transform">
|
||||
🧪 Markdown Playground
|
||||
</button>
|
||||
<button
|
||||
(click)="onApiTestsPanelClick()"
|
||||
class="mt-1 w-full text-left block text-sm px-3 py-2 rounded-lg hover:bg-surface1 dark:hover:bg-card active:bg-surface2 dark:active:bg-gray-700 text-main dark:text-main hover:text-main dark:hover:text-gray-100 transition-all active:scale-[0.98] transform">
|
||||
🔬 API Tests Panel
|
||||
</button>
|
||||
<button
|
||||
(click)="onTestsExcalidrawClick()"
|
||||
class="mt-1 w-full text-left block text-sm px-3 py-2 rounded-lg hover:bg-surface1 dark:hover:bg-card active:bg-surface2 dark:active:bg-gray-700 text-main dark:text-main hover:text-main dark:hover:text-gray-100 transition-all active:scale-[0.98] transform">
|
||||
🎨 Test Excalidraw
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -158,6 +168,8 @@ export class AppSidebarDrawerComponent {
|
||||
@Output() tagSelected = new EventEmitter<string>();
|
||||
@Output() quickLinkSelected = new EventEmitter<string>();
|
||||
@Output() markdownPlaygroundSelected = new EventEmitter<void>();
|
||||
@Output() testsPanelSelected = new EventEmitter<void>();
|
||||
@Output() testsExcalidrawSelected = new EventEmitter<void>();
|
||||
@Output() helpPageSelected = new EventEmitter<void>();
|
||||
@Output() aboutSelected = new EventEmitter<void>();
|
||||
|
||||
@ -189,6 +201,16 @@ export class AppSidebarDrawerComponent {
|
||||
this.mobileNav.sidebarOpen.set(false);
|
||||
}
|
||||
|
||||
onApiTestsPanelClick(): void {
|
||||
this.testsPanelSelected.emit();
|
||||
this.mobileNav.sidebarOpen.set(false);
|
||||
}
|
||||
|
||||
onTestsExcalidrawClick(): void {
|
||||
this.testsExcalidrawSelected.emit();
|
||||
this.mobileNav.sidebarOpen.set(false);
|
||||
}
|
||||
|
||||
onHelpPageClick(): void {
|
||||
this.helpPageSelected.emit();
|
||||
this.mobileNav.sidebarOpen.set(false);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, OnDestroy, OnInit, ViewChild, inject, signal } from '@angular/core';
|
||||
import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild, inject, signal } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { DrawingsEditorComponent } from '../drawings/drawings-editor.component';
|
||||
import { DrawingsFileService } from '../drawings/drawings-file.service';
|
||||
@ -13,58 +13,75 @@ import { firstValueFrom } from 'rxjs';
|
||||
imports: [CommonModule, DrawingsEditorComponent],
|
||||
template: `
|
||||
<div class="h-full flex flex-col gap-3">
|
||||
<div class="rounded-xl border border-border bg-card shadow-subtle">
|
||||
<div class="flex items-center justify-between px-3 py-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2 class="text-sm font-semibold">Test Excalidraw</h2>
|
||||
<span class="text-[10px] font-semibold uppercase tracking-widest rounded-full bg-surface1 px-2 py-0.5 text-muted">Legacy Integration</span>
|
||||
<ng-container *ngIf="currentPath(); else nofile">
|
||||
<span class="ml-2 text-xs text-muted select-all truncate max-w-[32rem]" [title]="currentPath()">{{ currentPath() }}</span>
|
||||
</ng-container>
|
||||
<ng-template #nofile>
|
||||
<span class="ml-2 text-xs text-muted">No file</span>
|
||||
</ng-template>
|
||||
<span class="ml-2 text-xs" [class.text-success]="!dirty()" [class.text-warning]="dirty()">• {{ dirty() ? 'Dirty' : 'Saved' }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="createNew()" title="Nouveau">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14"/><path d="M5 12h14"/></svg>
|
||||
<span class="ml-1 hidden sm:inline">Nouveau</span>
|
||||
</button>
|
||||
<div class="relative">
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="toggleOpenPicker()" title="Ouvrir">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h5l2 2h9a2 2 0 0 1 2 2z"/></svg>
|
||||
<span class="ml-1 hidden sm:inline">Ouvrir</span>
|
||||
</button>
|
||||
<div *ngIf="openPicker()" class="absolute right-0 mt-1 w-80 max-h-80 overflow-y-auto rounded-lg border border-border bg-card shadow-xl z-10">
|
||||
<div class="p-2 text-xs text-muted">Sélectionner un fichier *.excalidraw.md</div>
|
||||
<ul>
|
||||
<li *ngFor="let f of excalidrawFiles()">
|
||||
<button type="button" class="w-full text-left px-3 py-1.5 text-sm hover:bg-surface1" (click)="openFile(f.filePath)">{{ f.filePath }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="sticky top-0 z-40">
|
||||
<div class="rounded-2xl border border-border/60 bg-card/80 backdrop-blur-[2px] shadow-subtle max-w-full overflow-visible">
|
||||
<div class="flex flex-wrap items-center gap-2 px-3 pt-2">
|
||||
<div class="flex items-center gap-2 min-w-0 flex-1 overflow-hidden">
|
||||
<!-- <h2 class="text-sm font-semibold">Test Excalidraw</h2> -->
|
||||
<ng-container *ngIf="currentPath(); else nofile">
|
||||
<span class="ml-2 text-xs text-muted truncate select-text" [title]="currentPath()">{{ currentPath() }}</span>
|
||||
</ng-container>
|
||||
<ng-template #nofile>
|
||||
<span class="ml-2 text-xs text-muted">Aucun fichier</span>
|
||||
</ng-template>
|
||||
<div class="ml-auto flex items-center">
|
||||
<span
|
||||
class="inline-flex h-7 w-7 items-center justify-center rounded-full border border-border/60 bg-card/70 transition-colors"
|
||||
[class.text-emerald-400]="!dirty()"
|
||||
[class.text-red-500]="dirty()"
|
||||
[title]="dirty() ? 'Dessin non sauvegardé' : 'Dessin sauvegardé'"
|
||||
aria-label="Statut de sauvegarde"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
|
||||
<polyline points="17 21 17 13 7 13 7 21" />
|
||||
<polyline points="7 3 7 8 15 8" />
|
||||
</svg>
|
||||
<span class="sr-only">{{ dirty() ? 'Non sauvegardé' : 'Sauvegardé' }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="closeFile()" [disabled]="!currentPath()" title="Fermer le fichier">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
|
||||
<span class="ml-1 hidden sm:inline">Fermer</span>
|
||||
</button>
|
||||
<div class="mx-1 h-5 w-px bg-border"></div>
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="saveDebounced()" [disabled]="!currentPath()" title="Enregistrer (Ctrl/Cmd+S)">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h11l5 5v9a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
||||
<span class="ml-1 hidden sm:inline">Enregistrer</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="saveAs()" title="Enregistrer sous">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14"/><path d="M19 12H5"/></svg>
|
||||
<span class="ml-1 hidden sm:inline">Enregistrer sous</span>
|
||||
</button>
|
||||
<div class="mx-1 h-5 w-px bg-border"></div>
|
||||
<div class="relative">
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="toggleExport()" title="Exporter">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="M7 11l5 5 5-5"/><path d="M5 19h14"/></svg>
|
||||
<span class="ml-1 hidden sm:inline">Exporter</span>
|
||||
</div>
|
||||
<!-- Row 1: Primary actions -->
|
||||
<div class="flex items-center justify-center gap-1 md:gap-2 px-3">
|
||||
<div class="flex items-center gap-1">
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="createNew()" title="Nouveau" aria-label="Nouveau">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14"/><path d="M5 12h14"/></svg>
|
||||
<span class="ml-1 hidden md:inline">Nouveau</span>
|
||||
</button>
|
||||
<div *ngIf="openExport()" class="absolute right-0 mt-1 w-52 rounded-lg border border-border bg-card shadow-xl z-10">
|
||||
<div class="relative">
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="toggleOpenPicker()" title="Ouvrir" aria-haspopup="menu" aria-expanded="{{openPicker()}}">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h5l2 2h9a2 2 0 0 1 2 2z"/></svg>
|
||||
<span class="ml-1 hidden md:inline">Ouvrir</span>
|
||||
</button>
|
||||
<div *ngIf="openPicker()" class="absolute right-0 mt-1 w-72 max-w-[80vw] max-h-80 overflow-y-auto rounded-xl border border-border bg-card shadow-2xl z-50">
|
||||
<div class="px-3 py-2 text-xs text-muted">Sélectionner un fichier *.excalidraw.md</div>
|
||||
<ul class="divide-y divide-border/40">
|
||||
<li *ngFor="let f of excalidrawFiles()">
|
||||
<button type="button" class="w-full text-left px-3 py-2 text-sm hover:bg-surface1 truncate" (click)="openFile(f.filePath)" [title]="f.filePath">{{ f.filePath }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="closeFile()" [disabled]="!currentPath()" title="Fermer le fichier" aria-label="Fermer le fichier">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
|
||||
<span class="ml-1 hidden md:inline">Fermer</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="saveDebounced()" [disabled]="!currentPath()" title="Enregistrer (Ctrl/Cmd+S)" aria-label="Enregistrer">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h11l5 5v9a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
||||
<span class="ml-1 hidden md:inline">Enregistrer</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-px bg-border/70 mx-2 my-1"></div>
|
||||
<!-- Row 2: Export only -->
|
||||
<div class="flex items-center justify-center gap-1 md:gap-2 px-3 pb-2">
|
||||
<div class="relative">
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="toggleExport()" title="Exporter" aria-haspopup="menu" aria-expanded="{{openExport()}}">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="M7 11l5 5 5-5"/><path d="M5 19h14"/></svg>
|
||||
<span class="ml-1">Exporter</span>
|
||||
</button>
|
||||
<div *ngIf="openExport()" class="absolute right-0 mt-1 w-64 max-w-[75vw] rounded-xl border border-border bg-card shadow-2xl z-50">
|
||||
<button class="w-full text-left px-3 py-2 text-sm hover:bg-surface1" (click)="exportPNG(true)">PNG (avec fond)</button>
|
||||
<button class="w-full text-left px-3 py-2 text-sm hover:bg-surface1" (click)="exportPNG(false)">PNG (sans fond)</button>
|
||||
<div class="h-px bg-border mx-2"></div>
|
||||
@ -74,20 +91,13 @@ import { firstValueFrom } from 'rxjs';
|
||||
<button class="w-full text-left px-3 py-2 text-sm hover:bg-surface1" (click)="exportJSON()">JSON (télécharger)</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-1 h-5 w-px bg-border"></div>
|
||||
<label class="inline-flex items-center gap-2 text-xs text-muted select-none">
|
||||
<input type="checkbox" [checked]="autosave()" (change)="setAutosave($any($event.target).checked)" /> Autosave 10s
|
||||
</label>
|
||||
<button type="button" class="btn btn-ghost btn-sm" (click)="toggleFullscreen()" title="Plein écran">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3"/><path d="M16 3h3a2 2 0 0 1 2 2v3"/><path d="M8 21H5a2 2 0 0 1-2-2v-3"/><path d="M16 21h3a2 2 0 0 0 2-2v-3"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex-1 min-h-0">
|
||||
<ng-container *ngIf="currentPath(); else noSelection">
|
||||
<app-drawings-editor #editor [path]="currentPath()!"></app-drawings-editor>
|
||||
<app-drawings-editor #editor [path]="currentPath()!" [showInlineActions]="false"></app-drawings-editor>
|
||||
</ng-container>
|
||||
<ng-template #noSelection>
|
||||
<div class="h-full flex items-center justify-center rounded-xl border border-border bg-card text-muted">
|
||||
@ -104,7 +114,7 @@ import { firstValueFrom } from 'rxjs';
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
export class TestExcalidrawPageComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
private readonly drawings = inject(DrawingsFileService);
|
||||
private readonly excalIo = inject(ExcalidrawIoService);
|
||||
private readonly vault = inject(VaultService);
|
||||
@ -120,6 +130,7 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
|
||||
private autosaveTimer: any = null;
|
||||
private saveTimer: any = null;
|
||||
private dirtySyncInterval: any = null;
|
||||
|
||||
excalidrawFiles = signal<Array<{ filePath: string }>>([]);
|
||||
|
||||
@ -141,17 +152,20 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
// build files list for picker
|
||||
this.refreshFileList();
|
||||
|
||||
// poll editor dirty state via save hash comparison using existing editor polling
|
||||
// here we just mirror the editor's internal dirty state by attempting a heuristic:
|
||||
const syncDirty = () => {
|
||||
// not accessible directly; rely on presence of '*' in title not available. Skip.
|
||||
};
|
||||
void syncDirty;
|
||||
this.startDirtySync();
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.startDirtySync();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.autosaveTimer) clearInterval(this.autosaveTimer);
|
||||
if (this.saveTimer) clearTimeout(this.saveTimer);
|
||||
if (this.dirtySyncInterval) {
|
||||
clearInterval(this.dirtySyncInterval);
|
||||
this.dirtySyncInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
refreshFileList(): void {
|
||||
@ -191,6 +205,7 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
this.currentPath.set(path);
|
||||
this.updateUrlFileParam(path);
|
||||
this.openPicker.set(false);
|
||||
this.dirty.set(false);
|
||||
// focus editor next tick
|
||||
setTimeout(() => this.editor?.onExcalidrawReady?.(), 0);
|
||||
}
|
||||
@ -199,6 +214,7 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
this.currentPath.set(path);
|
||||
this.updateUrlFileParam(path);
|
||||
this.openPicker.set(false);
|
||||
this.dirty.set(false);
|
||||
}
|
||||
|
||||
async saveDebounced(): Promise<void> {
|
||||
@ -208,6 +224,17 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
|
||||
async save(): Promise<void> {
|
||||
await this.editor?.saveNow();
|
||||
this.dirty.set(this.editor?.dirty?.() ?? false);
|
||||
}
|
||||
|
||||
async exportPNG(withBg: boolean): Promise<void> {
|
||||
await this.editor?.exportPNG(withBg);
|
||||
this.openExport.set(false);
|
||||
}
|
||||
|
||||
async exportSVG(withBg: boolean): Promise<void> {
|
||||
await this.editor?.exportSVG(withBg);
|
||||
this.openExport.set(false);
|
||||
}
|
||||
|
||||
async saveAs(): Promise<void> {
|
||||
@ -228,16 +255,6 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
this.updateUrlFileParam(path);
|
||||
}
|
||||
|
||||
async exportPNG(withBg: boolean): Promise<void> {
|
||||
await this.editor?.exportPNG(withBg);
|
||||
this.openExport.set(false);
|
||||
}
|
||||
|
||||
async exportSVG(withBg: boolean): Promise<void> {
|
||||
await this.editor?.exportSVG(withBg);
|
||||
this.openExport.set(false);
|
||||
}
|
||||
|
||||
private updateUrlFileParam(filePath: string | null): void {
|
||||
try {
|
||||
this.router.navigate([], { queryParams: { file: filePath || null }, queryParamsHandling: 'merge', preserveFragment: true });
|
||||
@ -247,8 +264,8 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
closeFile(): void {
|
||||
this.currentPath.set(null);
|
||||
this.openPicker.set(false);
|
||||
this.openExport.set(false);
|
||||
this.updateUrlFileParam(null);
|
||||
this.dirty.set(false);
|
||||
}
|
||||
|
||||
async exportJSON(): Promise<void> {
|
||||
@ -275,6 +292,7 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
this.autosaveTimer = setInterval(() => {
|
||||
if (this.currentPath()) {
|
||||
this.editor?.saveNow();
|
||||
this.dirty.set(this.editor?.dirty?.() ?? false);
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
@ -284,4 +302,14 @@ export class TestExcalidrawPageComponent implements OnInit, OnDestroy {
|
||||
this.editor?.toggleFullscreen();
|
||||
}
|
||||
|
||||
private startDirtySync(): void {
|
||||
if (this.dirtySyncInterval) return;
|
||||
this.dirtySyncInterval = setInterval(() => {
|
||||
const childDirty = this.editor?.dirty?.();
|
||||
if (typeof childDirty === 'boolean' && childDirty !== this.dirty()) {
|
||||
this.dirty.set(childDirty);
|
||||
}
|
||||
}, 800);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -279,6 +279,7 @@ import { InPageSearchOverlayComponent } from '../../shared/search/in-page-search
|
||||
(quickLinkSelected)="onQuickLink($event)"
|
||||
(markdownPlaygroundSelected)="onMarkdownPlaygroundSelected()"
|
||||
(testsPanelSelected)="onTestsPanelSelected()"
|
||||
(testsExcalidrawSelected)="onTestsExcalidrawSelected()"
|
||||
(helpPageSelected)="onHelpPageSelected()"
|
||||
(aboutSelected)="onAboutSelected()"
|
||||
></app-sidebar-drawer>
|
||||
@ -860,14 +861,23 @@ export class AppShellNimbusLayoutComponent implements AfterViewInit {
|
||||
}
|
||||
|
||||
onMarkdownPlaygroundSelected(): void {
|
||||
if (this.responsive.isMobile()) {
|
||||
this.mobileNav.setActiveTab('page');
|
||||
}
|
||||
this.markdownPlaygroundSelected.emit();
|
||||
}
|
||||
|
||||
onTestsPanelSelected(): void {
|
||||
if (this.responsive.isMobile()) {
|
||||
this.mobileNav.setActiveTab('page');
|
||||
}
|
||||
this.testsPanelRequested.emit();
|
||||
}
|
||||
|
||||
onTestsExcalidrawSelected(): void {
|
||||
if (this.responsive.isMobile()) {
|
||||
this.mobileNav.setActiveTab('page');
|
||||
}
|
||||
this.testsExcalidrawRequested.emit();
|
||||
}
|
||||
|
||||
|
||||
31
vault/.obsidian/workspace.json
vendored
31
vault/.obsidian/workspace.json
vendored
@ -4,17 +4,19 @@
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "b123bf2cfbaf681c",
|
||||
"id": "511c66a5c96502b2",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "a71c9cf3bbb86552",
|
||||
"id": "8309e5042a8fb85c",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "empty",
|
||||
"state": {},
|
||||
"icon": "lucide-file",
|
||||
"title": "New tab"
|
||||
"type": "excalidraw",
|
||||
"state": {
|
||||
"file": "Drawing-20251028-1452.excalidraw.md"
|
||||
},
|
||||
"icon": "excalidraw-icon",
|
||||
"title": "Drawing-20251028-1452.excalidraw"
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -174,8 +176,17 @@
|
||||
"obsidian-excalidraw-plugin:New drawing": false
|
||||
}
|
||||
},
|
||||
"active": "a71c9cf3bbb86552",
|
||||
"active": "8309e5042a8fb85c",
|
||||
"lastOpenFiles": [
|
||||
"Drawing-20251028-1452.png",
|
||||
"Drawing-20251028-1452.excalidraw.md.bak",
|
||||
"Drawing-20251028-1452.excalidraw.md",
|
||||
"dessin.svg",
|
||||
"dessin.excalidraw.md",
|
||||
"dessin.png",
|
||||
"dessin.excalidraw.md.bak",
|
||||
"dessin_05.svg",
|
||||
"dessin_05.png",
|
||||
"dessin_05.excalidraw.md",
|
||||
"dessin_03.excalidraw.md",
|
||||
"dessin_05.excalidraw.md.bak",
|
||||
@ -189,9 +200,7 @@
|
||||
"dessin-002.excalidraw.md.bak",
|
||||
"Dessin_001.excalidraw.md",
|
||||
"Dessin_001.excalidraw.md.tmp",
|
||||
"Dessin_001.excalidraw.md.bak",
|
||||
"Drawing 2025-10-28 11.11.59.excalidraw.md",
|
||||
"Drawing 2025-10-28 11.11.59.excalidraw.md.tmp",
|
||||
"dessin-06.excalidraw.md",
|
||||
"Dessin-5.excalidraw.md",
|
||||
"Drawing-20251027-2203.excalidraw.md",
|
||||
@ -209,8 +218,6 @@
|
||||
"Drawing-20251027-1914.excalidraw.md",
|
||||
"Drawing-20251027-1705.excalidraw.md",
|
||||
"Drawing 2025-10-27 16.43.48.excalidraw.md",
|
||||
"test-drawing.excalidraw.md",
|
||||
"Untitled.canvas",
|
||||
"test.md"
|
||||
"Untitled.canvas"
|
||||
]
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
---
|
||||
excalidraw-plugin: parsed
|
||||
updated: "2025-10-28T15:45:35.205Z"
|
||||
---
|
||||
|
||||
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
|
||||
You can decompress Drawing data with the command palette: 'Decompress current Excalidraw file'. For more info check in plugin settings under 'Saving'
|
||||
|
||||
# Excalidraw Data
|
||||
|
||||
## Text Elements
|
||||
%%
|
||||
## Drawing
|
||||
```compressed-json
|
||||
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
|
||||
```
|
||||
%%
|
||||
15
vault/Drawing-20251028-1452.excalidraw.md
Normal file
15
vault/Drawing-20251028-1452.excalidraw.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
excalidraw-plugin: parsed
|
||||
updated: "2025-10-29T00:30:06.609Z"
|
||||
---
|
||||
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
|
||||
|
||||
# Excalidraw Data
|
||||
|
||||
## Text Elements
|
||||
%%
|
||||
## Drawing
|
||||
```compressed-json
|
||||
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
|
||||
```
|
||||
%%
|
||||
BIN
vault/Drawing-20251028-1452.png
Normal file
BIN
vault/Drawing-20251028-1452.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
@ -1,21 +0,0 @@
|
||||
---
|
||||
excalidraw-plugin: parsed
|
||||
updated: "2025-10-28T15:52:34.935Z"
|
||||
---
|
||||
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
|
||||
|
||||
|
||||
# Text Elements
|
||||
|
||||
# Drawing
|
||||
```json
|
||||
{"elements":[{"id":"FH8lzL5Mi3fE2hkUwBpjg","type":"ellipse","x":186.5,"y":194.5,"width":184,"height":143.5,"angle":0,"strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":2,"strokeStyle":"solid","roughness":1,"opacity":100,"groupIds":[],"frameId":null,"roundness":{"type":2},"seed":980334059,"version":87,"versionNonce":1002008523,"isDeleted":false,"boundElements":[{"id":"RwNj5xmpJCXxtCVzpGsCc","type":"arrow"},{"id":"tVxfMX9-gzA1gIMHh04AP","type":"arrow"}],"updated":1761666749806,"link":null,"locked":false},{"id":"RwNj5xmpJCXxtCVzpGsCc","type":"arrow","x":186.5,"y":271.5,"width":183,"height":5,"angle":0,"strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":2,"strokeStyle":"solid","roughness":1,"opacity":100,"groupIds":[],"frameId":null,"roundness":{"type":2},"seed":1981797643,"version":68,"versionNonce":624371685,"isDeleted":false,"boundElements":null,"updated":1761666744662,"link":null,"locked":false,"points":[[0,0],[183,-5]],"lastCommittedPoint":null,"startBinding":{"elementId":"FH8lzL5Mi3fE2hkUwBpjg","focus":0.03811374375552938,"gap":1},"endBinding":null,"startArrowhead":null,"endArrowhead":"arrow"},{"id":"tVxfMX9-gzA1gIMHh04AP","type":"arrow","x":277,"y":192,"width":1,"height":145,"angle":0,"strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":2,"strokeStyle":"solid","roughness":1,"opacity":100,"groupIds":[],"frameId":null,"roundness":{"type":2},"seed":132945413,"version":89,"versionNonce":1141263659,"isDeleted":false,"boundElements":null,"updated":1761666749806,"link":null,"locked":false,"points":[[0,0],[1,145]],"lastCommittedPoint":null,"startBinding":{"elementId":"FH8lzL5Mi3fE2hkUwBpjg","focus":0.01073822548811009,"gap":2.5093386662695423},"endBinding":null,"startArrowhead":null,"endArrowhead":"arrow"}],"appState":{"showWelcomeScreen":true,"theme":"dark","collaborators":{},"currentChartType":"bar","currentItemBackgroundColor":"transparent","currentItemEndArrowhead":"arrow","currentItemFillStyle":"solid","currentItemFontFamily":1,"currentItemFontSize":20,"currentItemOpacity":100,"currentItemRoughness":1,"currentItemStartArrowhead":null,"currentItemStrokeColor":"#1e1e1e","currentItemRoundness":"round","currentItemStrokeStyle":"solid","currentItemStrokeWidth":2,"currentItemTextAlign":"left","cursorButton":"up","activeEmbeddable":null,"draggingElement":null,"editingElement":null,"editingGroupId":null,"editingLinearElement":null,"activeTool":{"type":"selection","customType":null,"locked":false,"lastActiveTool":null},"penMode":false,"penDetected":false,"errorMessage":null,"exportBackground":true,"exportScale":2,"exportEmbedScene":false,"exportWithDarkMode":false,"fileHandle":null,"gridSize":null,"isBindingEnabled":true,"defaultSidebarDockedPreference":false,"isLoading":false,"isResizing":false,"isRotating":false,"lastPointerDownWith":"mouse","multiElement":null,"name":"Untitled-2025-10-28-1152","contextMenu":null,"openMenu":null,"openPopup":null,"openSidebar":null,"openDialog":null,"pasteDialog":{"shown":false,"data":null},"previousSelectedElementIds":{"tVxfMX9-gzA1gIMHh04AP":true},"resizingElement":null,"scrolledOutside":false,"scrollX":0,"scrollY":0,"selectedElementIds":{},"selectedGroupIds":{},"selectedElementsAreBeingDragged":false,"selectionElement":null,"shouldCacheIgnoreZoom":false,"showStats":false,"startBoundElement":null,"suggestedBindings":[],"frameRendering":{"enabled":true,"clip":true,"name":true,"outline":true},"frameToHighlight":null,"editingFrame":null,"elementsToHighlight":null,"toast":null,"viewBackgroundColor":"#f8f9fa","zenModeEnabled":false,"zoom":{"value":1},"viewModeEnabled":false,"pendingImageElementId":null,"showHyperlinkPopup":false,"selectedLinearElement":null,"snapLines":[],"originSnapOffset":null,"objectsSnapModeEnabled":false,"offsetLeft":723,"offsetTop":155,"width":665,"height":546},"files":{}}
|
||||
```
|
||||
|
||||
# Embedded Files
|
||||
|
||||
%%
|
||||
```compressed-json
|
||||
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
|
||||
```
|
||||
%%
|
||||
15
vault/dessin.excalidraw.md
Normal file
15
vault/dessin.excalidraw.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
excalidraw-plugin: parsed
|
||||
updated: "2025-10-28T18:48:43.751Z"
|
||||
---
|
||||
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
|
||||
|
||||
# Excalidraw Data
|
||||
|
||||
## Text Elements
|
||||
%%
|
||||
## Drawing
|
||||
```compressed-json
|
||||
N4IgLgngDgpiBcIYA8DGBDANgSwCYCd0B3EAGhADcZ8BnbAewDsEAmcm+gV31TkXoBGdXNnSMAtCgw4CxcVEycA5tmbkYmGAFsYjMDQQBtUJFgIkmHFBpxyVWg2bwAjAGY2lanSYA5Jr1YADlcAFhYANmco8mwaABENGDAYXAQAMywbGNTEAHYAVmQADQBhGnwATRgAUQBJKGRxAQA1ADFcOIiyEDTsSwBlSE1zDhlumjB8egBrGAB1PDAAC1Z2SZmYQYhhxFG8bqnlJcYYGgMXcnoodFRsSARnAAZH8jElHZeQZAf8jwgHkKuAB0+TWU1mJXomHo+HMAGJnDBEYjugIbtMlIdGLhIdDYYhJmIaNd8LowN0iIsVvAWCF8iDnoymYzXOQljBsEoluSXLkQkCQgBOYUi0XC3LsGApB6Clj5QKBR4hR7OciYrhQWq4c6GAC65DShB0WoQjE4lnIWNwJzOCBM0D4LAAvuQBFxsdVNDo9Dr9SBOFBcOhkjlnLlIuFw+Fwq5XL9yDhGNNTebMAn6KhZjkMpgbC77WZEInbJ4HEwgqrS95GH5GAEXDGCm4WM5QSBYglNCH0pkYNlzNUYLkKs4WI8AEpgACCuAAinQSgBVaqLx74XLdXoDIZ8EB7VJgjYLXDLVZ79azLY7PdQ/aWrhcm3nStXG53f4uZ6vRjvPifb40o8goguQH6toEIHnuCMC4jC8LIkiJZopm6qcNisH4uAhCMMS6CknoFJUgg9JtuynLcgCuSQTY0ouK4BSBLkjz5G4aqHJq2pGH6hroMaORmhaIBWk+drgA6rAuiAbpobgnraGSvrkAGQbdryEZRoELBjh4ibJvAAlpiA0KZrROZZOeeFgAAQqoIg/imgm6LgNnYqoSgOYZmDoBMkJaFodwhgACvQqg8gZayWVO+BTEQ7LoPxqbqNiUUxXFCWCVAIU+kYhgvI8+qGCRpDOCEVH5Lqur5mJhZGaoJb2NWrBflWji1vWo7RvK+SCuEnwdokqlmX27Y5CAAAqRD9LO2AQJwyAAOI+GNAD6qBzOOgoAF4ADLjmNyYGn0mBXru+7jBe8xETSh6XjuIy3geQkPscpzPpc1y3Pcn6fG8HzkABLbAvkuRhj1+TKrGriPIEoGsFDQIg0xgquMKYT5NGrJQRsGHwYhKKuuiqHoVCcEEthuH4eS5CUie1LOIxbIclyPJA5KtElaV4S0q2gpsRqWqKT0RowCa+mJU9MkifABaOpJ0kel6ClcUpgbBuz4bOJGSOlY8Eq1UmHnpiZ2a9hF+DWbZbmG0g2IuXZ7li4JXk+fQfkBSkwWhdbEyRdF9CxTA8XW05KX+2l1uZaFOq5aQ+WkIY9MSuIQMVU6froFAUCDGrok0Es/tzBoqCu5sqCkroCCTJww3LPJ5hBvgB0gKg3CUyUSyWWN4mIGisLkC30VkrUyRaFZhNWjjZNEiSZLdAPlPD9o1TJX7AdB4geExXPrdDyPrRHSd91jP3O96IvWitEwYCtLxfRgSfg9n3vV/9Ngm2Op88+79oADyH3vg8ZqX8n7aHHM9KWlZgFgHPtnc2oc17pUMlAmBF1J4gARHjEsyCR5gMlq9cwVpt6P2gSPQY0FD67AekQhepCLrHlPNdZup8SHaDGigacOAlBOCMjANIVMmG0BhFZTgYAwDlkQAGboNwwDYCoNULQAgUhBgEDscKIBZBKBUD+OS3owrixSHcNyOjZ6O0MgYmRP55rsVFmo8xbltp1TwsYgipjXioBkVQMa9AoSiVMLuDu2Jt4TFdl3QsajjJZh7LmYaztpzuNkTALxPjTGSVgIwAAsvQXAfAhrkDSQkZI7jTKmyQH7fA6TXroCUHwWxyBMrmzHihQh8Aq7DRQPUsA/RpCOnUHUmEYB5GKNwF03QOSSntP6QsZYcQ8LTEydkqJ5ktwwAABJiFwKo8WmI8Cv3ftbWIdsjGMHQCo2irTyDZIyOaTpeAYC9ziBmLMgVSRpGoLoesuT2w0G2vQeKVt4CfNiOOU4b9/mApoGAsAwYwUlNiZ7PQ1AHlEEYFM6k4AuCoBWOQLQ1zsDOL0YJY5OhzCLj0HcTQuBxDaXyOIJ4VLAi0sBOEOeV92EVLNNbK4uh2WcE5Wk4KUBJGuJAFyxgr9sm9z5boOIohoQOzUdcCYMAZVYHoA7UAed/ZOE+SpdAHlUmkgoAwTgNB+iJCKbJRWZ9OLS0kqSOgm0jFWoJYZGgZcoQUp/iI4QYzonsHdZYIoAJnAI0eHKQIwoVQhGVJWN1UxLAVAeG4IEmt8iPHCIxGMzhBS5ECCESUmgLX4oFnaSSNhC0hisfzG1wAy3mpDPimgUUYBWQ5D+OIhBNHFL9Xuetjh8Xe3zuaHENx2S1C4TCGAAAtbxWhFnDU1ZNKF+h51m2su6S18kXFqJoMoapSrnKWx/ILHiOhgXYmoP80AugTkUsrvgau/crD3sfSAIlfBzkipEcWF9MBJKnsSfQFZ5FOEUWFXYn8rRhbB2dTQLxwGuSgZdeQMR3lkOUGwDAIgjSMQTxJphOEaRAhpEFBkbo78MlZJqMc05Jse2bVnaJCgWBq4IEeAjZGip01xmho2FggRJJGqw/M6jt7u3mTSfbWoWgqk1GdTY8Wi6VkOnwLpAVQrPnlpgBahxJwnHOu9scqAunTjKxFfgTkqh+hGZ/mkNINh0OCAAFbaf0NZjOInl5ibo+ZegdmHPbV4TyXILBMZ+fs0kLxUBWD8epldTqjNyI8nBuEf9fRTO2qdEAA==
|
||||
```
|
||||
%%
|
||||
BIN
vault/dessin.png
Normal file
BIN
vault/dessin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.4 KiB |
21
vault/dessin.svg
Normal file
21
vault/dessin.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 270.3366543638838 194.5" width="540.6733087277676" height="389">
|
||||
<!-- svg-source:excalidraw -->
|
||||
|
||||
<defs>
|
||||
<style class="style-fonts">
|
||||
@font-face {
|
||||
font-family: "Virgil";
|
||||
src: url("https://unpkg.com/@excalidraw/excalidraw@undefined/dist/excalidraw-assets/Virgil.woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Cascadia";
|
||||
src: url("https://unpkg.com/@excalidraw/excalidraw@undefined/dist/excalidraw-assets/Cascadia.woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Assistant";
|
||||
src: url("https://unpkg.com/@excalidraw/excalidraw@undefined/dist/excalidraw-assets/Assistant-Regular.woff2");
|
||||
}
|
||||
</style>
|
||||
|
||||
</defs>
|
||||
<g stroke-linecap="round" transform="translate(10 10) rotate(0 122.75 87.25)"><path d="M123.66 0.36 C137.66 -0.96, 155.36 2.01, 169.1 5.73 C182.84 9.46, 195.35 15.56, 206.13 22.69 C216.9 29.82, 227.4 38.97, 233.76 48.53 C240.11 58.09, 243.03 69.45, 244.23 80.05 C245.44 90.65, 245.15 101.93, 241 112.12 C236.86 122.32, 228.55 132.89, 219.37 141.21 C210.19 149.52, 198.38 156.71, 185.91 162.01 C173.44 167.32, 158.96 171.21, 144.53 173.05 C130.11 174.88, 114.04 175.18, 99.35 173.01 C84.66 170.85, 68.91 165.59, 56.38 160.06 C43.84 154.52, 32.97 148.12, 24.15 139.8 C15.34 131.48, 7.46 120.29, 3.48 110.14 C-0.49 99.98, -1.42 89.19, 0.28 78.86 C1.98 68.54, 6.82 57.63, 13.69 48.19 C20.56 38.75, 30.3 29.35, 41.49 22.2 C52.67 15.04, 64.83 8.92, 80.79 5.28 C96.75 1.65, 125.77 0.58, 137.24 0.4 C148.71 0.22, 149.76 2.79, 149.59 4.2 M140.94 2.38 C155.18 2.39, 169.62 5.6, 182.49 10.33 C195.36 15.07, 208.87 22.62, 218.16 30.79 C227.44 38.96, 233.62 49.12, 238.19 59.34 C242.77 69.55, 246.29 81.58, 245.59 92.08 C244.89 102.58, 240.11 113.03, 234.01 122.35 C227.91 131.67, 219.45 140.36, 208.99 147.99 C198.52 155.62, 184.68 163.57, 171.22 168.14 C157.76 172.71, 142.91 175.03, 128.22 175.41 C113.53 175.78, 97.33 174.03, 83.11 170.38 C68.89 166.73, 54.05 160.21, 42.9 153.51 C31.76 146.81, 23.28 139.23, 16.25 130.17 C9.22 121.11, 2.62 109.78, 0.73 99.13 C-1.16 88.48, 1.51 76.33, 4.91 66.26 C8.3 56.19, 12.92 47.33, 21.1 38.7 C29.29 30.07, 41.85 20.82, 54 14.49 C66.15 8.16, 79.61 3.08, 94.01 0.71 C108.41 -1.66, 132.56 -0.23, 140.41 0.29 C148.27 0.82, 141.65 2.29, 141.12 3.85" stroke="#1e1e1e" stroke-width="2" fill="none"/></g><g stroke-linecap="round"><g transform="translate(67.5 25) rotate(0 2.75 73.75)"><path d="M-1.04 -0.25 C-0.35 24.08, 3.39 121.84, 4.66 146.55 M0.62 -1.42 C1.63 22.98, 5.98 123.03, 6.93 147.58" stroke="#1e1e1e" stroke-width="2" fill="none"/></g></g><mask/><g stroke-linecap="round"><g transform="translate(71.57179654033308 97.21709399425663) rotate(0 93.5 -1.75)"><path d="M-1.18 0.93 C29.85 0.14, 154.96 -2.98, 186.38 -3.66 M0.41 0.37 C31.8 0.28, 157.71 -1.26, 188.76 -2.21" stroke="#1e1e1e" stroke-width="2" fill="none"/></g></g><mask/></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@ -1,21 +0,0 @@
|
||||
---
|
||||
excalidraw-plugin: parsed
|
||||
updated: "2025-10-28T16:00:51.235Z"
|
||||
---
|
||||
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
|
||||
|
||||
|
||||
# Text Elements
|
||||
|
||||
# Drawing
|
||||
```json
|
||||
{"elements":[{"id":"k815FAbmfYF5PnwUH8C-Y","type":"diamond","x":145,"y":168,"width":184,"height":162,"angle":0,"strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":2,"strokeStyle":"solid","roughness":1,"opacity":100,"groupIds":[],"frameId":null,"roundness":{"type":2},"seed":1003701346,"version":78,"versionNonce":177304866,"isDeleted":false,"boundElements":null,"updated":1761667243295,"link":null,"locked":false},{"id":"-5PKdSwNmlYANRFbrw08a","type":"arrow","x":236.5,"y":170.5,"width":1,"height":154,"angle":0,"strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":2,"strokeStyle":"solid","roughness":1,"opacity":100,"groupIds":[],"frameId":null,"roundness":{"type":2},"seed":1957331170,"version":45,"versionNonce":596418814,"isDeleted":false,"boundElements":null,"updated":1761667248128,"link":null,"locked":false,"points":[[0,0],[1,154]],"lastCommittedPoint":null,"startBinding":null,"endBinding":null,"startArrowhead":null,"endArrowhead":"arrow"}],"appState":{"showWelcomeScreen":true,"theme":"dark","collaborators":{},"currentChartType":"bar","currentItemBackgroundColor":"transparent","currentItemEndArrowhead":"arrow","currentItemFillStyle":"solid","currentItemFontFamily":1,"currentItemFontSize":20,"currentItemOpacity":100,"currentItemRoughness":1,"currentItemStartArrowhead":null,"currentItemStrokeColor":"#1e1e1e","currentItemRoundness":"round","currentItemStrokeStyle":"solid","currentItemStrokeWidth":2,"currentItemTextAlign":"left","cursorButton":"up","activeEmbeddable":null,"draggingElement":null,"editingElement":null,"editingGroupId":null,"editingLinearElement":null,"activeTool":{"type":"selection","customType":null,"locked":false,"lastActiveTool":null},"penMode":false,"penDetected":false,"errorMessage":null,"exportBackground":true,"exportScale":2,"exportEmbedScene":false,"exportWithDarkMode":false,"fileHandle":null,"gridSize":null,"isBindingEnabled":true,"defaultSidebarDockedPreference":false,"isLoading":false,"isResizing":false,"isRotating":false,"lastPointerDownWith":"mouse","multiElement":null,"name":"Untitled-2025-10-28-1200","contextMenu":null,"openMenu":null,"openPopup":null,"openSidebar":null,"openDialog":null,"pasteDialog":{"shown":false,"data":null},"previousSelectedElementIds":{"-5PKdSwNmlYANRFbrw08a":true},"resizingElement":null,"scrolledOutside":false,"scrollX":0,"scrollY":0,"selectedElementIds":{},"selectedGroupIds":{},"selectedElementsAreBeingDragged":false,"selectionElement":null,"shouldCacheIgnoreZoom":false,"showStats":false,"startBoundElement":null,"suggestedBindings":[],"frameRendering":{"enabled":true,"clip":true,"name":true,"outline":true},"frameToHighlight":null,"editingFrame":null,"elementsToHighlight":null,"toast":null,"viewBackgroundColor":"#f8f9fa","zenModeEnabled":false,"zoom":{"value":1},"viewModeEnabled":false,"pendingImageElementId":null,"showHyperlinkPopup":false,"selectedLinearElement":null,"snapLines":[],"originSnapOffset":null,"objectsSnapModeEnabled":false,"offsetLeft":723,"offsetTop":155,"width":665,"height":546},"files":{}}
|
||||
```
|
||||
|
||||
# Embedded Files
|
||||
|
||||
%%
|
||||
```compressed-json
|
||||
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=
|
||||
```
|
||||
%%
|
||||
@ -1,21 +0,0 @@
|
||||
---
|
||||
excalidraw-plugin: parsed
|
||||
updated: "2025-10-28T16:26:01.524Z"
|
||||
---
|
||||
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
|
||||
|
||||
|
||||
# Text Elements
|
||||
|
||||
# Drawing
|
||||
```json
|
||||
{"elements":[{"id":"GeEImoYg9respBPK3wmrF","type":"diamond","x":284.5,"y":175,"width":151,"height":168,"angle":0,"strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":2,"strokeStyle":"solid","roughness":1,"opacity":100,"groupIds":[],"frameId":null,"roundness":{"type":2},"seed":1926584722,"version":64,"versionNonce":1088033746,"isDeleted":false,"boundElements":null,"updated":1761668759766,"link":null,"locked":false}],"appState":{"showWelcomeScreen":true,"theme":"dark","collaborators":{},"currentChartType":"bar","currentItemBackgroundColor":"transparent","currentItemEndArrowhead":"arrow","currentItemFillStyle":"solid","currentItemFontFamily":1,"currentItemFontSize":20,"currentItemOpacity":100,"currentItemRoughness":1,"currentItemStartArrowhead":null,"currentItemStrokeColor":"#1e1e1e","currentItemRoundness":"round","currentItemStrokeStyle":"solid","currentItemStrokeWidth":2,"currentItemTextAlign":"left","cursorButton":"up","activeEmbeddable":null,"draggingElement":null,"editingElement":null,"editingGroupId":null,"editingLinearElement":null,"activeTool":{"type":"selection","customType":null,"locked":false,"lastActiveTool":null},"penMode":false,"penDetected":false,"errorMessage":null,"exportBackground":true,"exportScale":2,"exportEmbedScene":false,"exportWithDarkMode":false,"fileHandle":null,"gridSize":null,"isBindingEnabled":true,"defaultSidebarDockedPreference":false,"isLoading":false,"isResizing":false,"isRotating":false,"lastPointerDownWith":"mouse","multiElement":null,"name":"Untitled-2025-10-28-1225","contextMenu":null,"openMenu":null,"openPopup":null,"openSidebar":null,"openDialog":null,"pasteDialog":{"shown":false,"data":null},"previousSelectedElementIds":{"GeEImoYg9respBPK3wmrF":true},"resizingElement":null,"scrolledOutside":false,"scrollX":0,"scrollY":0,"selectedElementIds":{},"selectedGroupIds":{},"selectedElementsAreBeingDragged":false,"selectionElement":null,"shouldCacheIgnoreZoom":false,"showStats":false,"startBoundElement":null,"suggestedBindings":[],"frameRendering":{"enabled":true,"clip":true,"name":true,"outline":true},"frameToHighlight":null,"editingFrame":null,"elementsToHighlight":null,"toast":null,"viewBackgroundColor":"#f8f9fa","zenModeEnabled":false,"zoom":{"value":1},"viewModeEnabled":false,"pendingImageElementId":null,"showHyperlinkPopup":false,"selectedLinearElement":null,"snapLines":[],"originSnapOffset":null,"objectsSnapModeEnabled":false,"offsetLeft":723,"offsetTop":155,"width":665,"height":546},"files":{}}
|
||||
```
|
||||
|
||||
# Embedded Files
|
||||
|
||||
%%
|
||||
```compressed-json
|
||||
N4IgpgNmC2YHYBcDOIBcBtUBLAJmkA4mAKICS0A9gJoDmAnAE5hIAOAQgAoDSAzAO7QGAMRAAaEAgCeLMPhxYAhpTh5xADzQAmABwAWAHQBWcZLQBGAOzGQfXAgAW5w2fH2wWGvYTmAbNvEKcDRQaAAM4kgIDBQA1mAAwhQQFAz4AMRmYJmZYiAARgoAxjE00QCuKonJqagSDIGsCkyIuQBmWBAQAMpSIbVISbi5kdFxAOp2jqiaEVGxYD2SfSADEEPi5Z5wzCioLiAULEVYUuah4SClFGUspDi76AC64q31sHdocGWdG9cq20hdqApDItABfCJgMB4PZ0TQ+Qx6CyaGYgABuYAYSCwFDgaB8unEGKxOLgADlcYVZHtQtptKEeDwLLofOIsEgACKQMAIaFoVoKCBIMDiPJ/HDEKCwRC7L4/EA3HAKXkwyw+Mw+PxWOgWTXiNZwGKfb4QfUUYp81ACoVgMHPEAKFgsHrK6mgJD2Ch8MaQQoUWBdQpMeBoKJlEUSNywORNI3iP2dBRi+oIFJAiEgQplBjNBDxexNBAAFWk1PyTVyWZz8AQpF50DYRRK5UqSRS+CiDSOucr2dzdZgxBUAEEc163AoYQ6x3xe9XEAPoEIOt1emXVutM32a4uhLiEEIlB1THt49uF/W94gulgAF7UzQXKv9+sAeSOhROJ7M5zP89r9YAErXFsOzmH+L4wC6DAIKO0R8BOMJyqaW7/ouPSjAkbY1CAGRZPhc6QdAwEVDgAK7CALaqKhREYfMizLBu1HPju9Z0eMkxaBBrEwEWYBqLBaw0HitRQK03h/gMDBsGUCCpiJCosLkRQIFgGLENAeTQkqeR9Mh4g4PUNA0FgQSSjANbGvK0InKZNDmdK3ioPp4DyKpQQEOUtxISa4g2e5NAADKmWATQOZZzm+Q6hSqRiRYUEkaDAqW+DClAMWkr2kT+iWoKRfKyQWjC1rCvqCiRMOGVxQlEBWRAGYyHAACyFA4NSJURo1XK8jFlodX5Y4ME1OwKDQ1IufxLApAgjbFFcpGhgw4Z+WoU0wYGgoPita0IBpWk4IG8DtYKpXgKt00TA4HKxi1bX8idEbtFAAASgQ4HpUWlLgN73nVbJIGwpnyGZcBJlAMJhhGbUCt8CA3m1BQMBy5pxDgHBMK0mLwFS902v9gUUJOdm46d7KAcwd7E1aD3/cBCDKlT/UgBA5UIBwFCmbySNenAl1TCAlBlMKuTQLDWDhS0+UoaD0a1AAqogJzgwAtI+miGMrP6q9omsooYlb7vxCDDV8f0HI1JtlGbhzwOzLA3NbjXw2AiOO/AHKKMkNBm0ckRgB7goUN7qDup6fAiUzSr03VDVMGiOJC103K9RKUo7vcSWECQ5DUPQTCsJwvACMIi3hhm+eU2ZaeSy5SBBkk4OvrJ2J3dTeMrPXnQABphBEncQFQvcrMnKoS7WGchxmaVgCnnnXN56aQulo/V8go5gGw7hBByRljcVNPD8vpJj2bHrXBAODxEUbikMJKRgAAWgl0AkxGZ98C6yCv7MhZsOKJ9SwiGUYyzAVSAxUHZB49pXhKDAOTFQmIqagHgGDS0kN4xrCUqgdBIAZbUhwdcBABp8FLVtC8N4YB4rPQ8PYISXgzb+TskIChDDV5ICoTQuhTkXKplZmbeOYA+CzWbOKKo7ZahpFaNoVodABS5HvM1VqJBQa6T6gfW8z9M5okFOGcwGYBF8Fuso1B+926NWBjQcgo0SCrw+IAlYYdnqlgYAaGIdsHZt1OtPFOwVthhVXqfUGLBfHMDQE8cQKQPCmS6EE18rRWjCm4VFCgeQABWM9kAxMdEYocJjv4HHiYkwKYBxJoGRDwCJhSeTxSwWYQw1hbA4AcPiBErh3CeCcoYFkGYnqhMnmCIAA===
|
||||
```
|
||||
%%
|
||||
@ -1,15 +0,0 @@
|
||||
---
|
||||
excalidraw-plugin: parsed
|
||||
updated: "2025-10-28T16:46:06.902Z"
|
||||
---
|
||||
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
|
||||
|
||||
# Excalidraw Data
|
||||
|
||||
## Text Elements
|
||||
%%
|
||||
## Drawing
|
||||
```compressed-json
|
||||
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
|
||||
```
|
||||
%%
|
||||
@ -12,11 +12,6 @@ task: true
|
||||
archive: true
|
||||
draft: true
|
||||
private: true
|
||||
color: "#EF4444"
|
||||
tags:
|
||||
- configuration
|
||||
- tag4
|
||||
- test
|
||||
---
|
||||
# TEST
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user