Upload via GUI (37 Dateien)

This commit is contained in:
Git Manager GUI
2026-07-28 19:00:17 +02:00
parent 0fa06d3ebd
commit 20b9d3a460
37 changed files with 1334 additions and 89 deletions

14
.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
# Build-Ausgaben / Zwischenstände
webview2/out/
webview2/bin/
webview2/obj/
# (Falls die Electron-Variante mal dazukommt)
electron/node_modules/
electron/dist/
node_modules/
# System
Thumbs.db
Desktop.ini
.DS_Store

147
README.md
View File

@@ -1,118 +1,87 @@
# MyStart # MyStart
Deine persönliche Startseite / neue-Tab-Seite als eigenständige Windows-App Persönliche Startseite / neue-Tab-Seite als eigenständige Windows-App
angepasst aus dem quelloffenen Projekt **nightTab**, komplett auf Deutsch. angepasst aus dem quelloffenen Projekt **nightTab**, komplett auf Deutsch.
--- Dieses Repo enthält die **Quellen zum Bauen** der App. Die fertige `MyStart.exe`
selbst ist ein Build-Artefakt und liegt nicht im Repo.
## 🚀 Schnellstart
1. **`MyStart.exe`** doppelklicken.
2. Beim ersten Start evtl. **Windows SmartScreen***Weitere Informationen*
*Trotzdem ausführen* (normal bei unsignierten, selbstgebauten Programmen).
3. Fertig. Erster Start ~2 s, danach praktisch **sofort**.
Keine Installation nötig. Die `MyStart.exe` ist alles, was du brauchst du
kannst sie beliebig verschieben (Desktop, USB-Stick, anderer PC). Deine
Einstellungen bleiben erhalten.
--- ---
## ✨ Funktionen & Bedienung ## Was die App kann
- **Lesezeichen & Gruppen**, Design, Kopfzeile (Begrüßung/Uhr/Datum), Suche - Angepasste, **komplett deutsche** nightTab-Oberfläche
alles anpassbar unter dem **Zahnrad** (Einstellungen). - Eigenständige, schnelle **WebView2/.NET-Einzeldatei** (~48 MB, Start ~2 s,
- **Komplett deutsche Oberfläche** (nur die Farbnamen im Akzent-Farbwähler sind danach praktisch sofort)
englisch reine Farbbezeichnungen). - **Randloses Fenster** mit eigenen Knöpfen oben rechts (Verschieben ⠿,
Minimieren , Max./Wiederherstellen □, Schließen ✕); Verschieben auch per
`Alt` + Ziehen
- **Autostart-Schalter** direkt in den Einstellungen (Einstellungen → MyStart)
- Dunkler, schlanker Scrollbalken
- Import nimmt **MyStart-** und alte **nightTab**-Sicherungen an
- Externe Links öffnen im Standard-Browser
### Fenster (ohne Titelleiste) Daten der App liegen zur Laufzeit unter `%LOCALAPPDATA%\MyStart`.
Die Fenster-Knöpfe sitzen **oben rechts im Eck**:
| ⠿ | | □ | ✕ |
|---|---|---|---|
| Verschieben (ziehen) | Minimieren | Max./Wiederherstellen | Schließen |
- **Verschieben:** den **Zieh-Griff ⠿** ziehen oder `Alt` + linke Maustaste an
beliebiger Stelle. Ein maximiertes Fenster wird beim Ziehen wiederhergestellt.
- **Schließen** auch mit `Alt` + `F4`.
### Autostart (in den Einstellungen)
**Einstellungen → MyStart →** Schiebeschalter **„Mit Windows starten
(minimiert)"**. An = startet automatisch mit Windows, minimiert in der
Taskleiste. Der Schalter merkt sich automatisch den Pfad der laufenden .exe.
--- ---
## 💾 Daten & Backups ## Aufbau des Repos
- **Speicherort deiner Daten:** `%LOCALAPPDATA%\MyStart`
(= `C:\Users\<DeinName>\AppData\Local\MyStart`)
- **Sichern / Wiederherstellen:** Einstellungen → **Daten**
(der Import nimmt **MyStart-** und alte **nightTab**-Sicherungen an)
- **Zurücksetzen:** Ordner `%LOCALAPPDATA%\MyStart` löschen.
---
## ⚙️ Voraussetzung
MyStart nutzt die **Microsoft-Edge-WebView2**-Komponente (auf praktisch jedem
aktuellen Windows 10/11 vorhanden). Nur auf einem sehr alten/minimalen Windows
ohne diese Komponente müsste sie einmalig (gratis von Microsoft) nachinstalliert
werden.
---
## 📦 Inhalt dieses Backups
``` ```
MyStart-Backup\ bundle.js Baut aus der Quelle die angepasste, deutsche App-HTML
├─ MyStart.exe Die fertige App (WebView2, ~48 MB, alles eingebaut) lang/ Deutsche Übersetzungen
├─ MyStart-App.html Dieselbe App als einzelne HTML-Datei (Notfall, de.json Steuerelemente / Labels
in jedem Browser öffenbar) de2.json Hilfe- / Meldungstexte
├─ README.md Diese Datei quelle-nightTab/ Unveränderte Original-Quelle (nightTab 7.3.0, GPL v3)
├─ LIESMICH.txt Kurzfassung webview2/ Die Windows-App (.NET + WebView2)
└─ projekt\ Alles zum Neubauen / Weiteranpassen Program.cs Fenster, Knöpfe, Verschieben, Autostart, externe Links
├─ bundle.js Baut die angepasste deutsche App aus der Quelle MyStart.csproj Bau-Einstellungen (.NET)
├─ quelle-nightTab\ Unveränderte Original-Quelle (nightTab 7.3.0) app.ico App-Icon (auch build/icon.ico)
├─ webview2\ >>> AKTUELLE, SCHNELLE VARIANTE (.NET/WebView2) <<< app-index.html Von bundle.js erzeugt (die fertige App) *
│ ├─ Program.cs Fenster, Knöpfe, Verschieben, Autostart, ext. Links README.md
│ ├─ MyStart.csproj .gitignore
│ ├─ app-index.html Die fertig angepasste, deutsche App
│ ├─ app.ico + build\icon.ico
└─ electron\ Alternative: voll autarke Variante (größer/langsamer)
├─ main.js package.json
├─ de.json de2.json Deutsche Übersetzungen
├─ app\index.html build\icon.ico
``` ```
\* `webview2/app-index.html` wird von `bundle.js` erzeugt. Sie ist mit
eingecheckt, damit `dotnet publish` sofort funktioniert nach Änderungen an
`bundle.js`, `lang/` oder der Quelle einfach neu erzeugen (siehe unten).
--- ---
## 🛠️ Neu bauen (nur bei Änderungen) ## Bauen
**Voraussetzungen:** [Node.js](https://nodejs.org) und das
[.NET SDK](https://dotnet.microsoft.com/download) (Windows, x64).
**1. App-Datei erzeugen** (Node.js nötig), im Ordner `projekt`:
```bash ```bash
node bundle.js "./electron/app/index.html" # 1) Angepasste, deutsche App-HTML erzeugen
copy .\electron\app\index.html .\webview2\app-index.html # (schreibt standardmäßig nach webview2/app-index.html)
``` node bundle.js
> `bundle.js` liest die Quelle aus `C:\Users\Viper\Desktop\nightTab`.
> Fehlt der Ordner, den Pfad oben in `bundle.js` auf `projekt\quelle-nightTab`
> ändern.
**2a. Schnelle .exe bauen** (.NET SDK nötig), im Ordner `projekt\webview2`: # 2) Die Windows-.exe bauen
```bash cd webview2
dotnet publish -c Release -r win-x64 -o ./out dotnet publish -c Release -r win-x64 -o ./out
# Ergebnis: webview2/out/MyStart.exe
``` ```
Ergebnis: `projekt\webview2\out\MyStart.exe`
**2b. Autarke Electron-.exe** (Alternative, Node.js), im Ordner `projekt\electron`: `bundle.js` liest die Quelle relativ aus `quelle-nightTab/` das Repo baut
```bash also auf jedem Rechner ohne Pfadanpassung.
npm install
npx electron-builder --win portable --x64
```
--- ---
## 📄 Herkunft & Lizenz ## Anpassen
- **Übersetzungen:** `lang/de.json` (Labels) und `lang/de2.json` (Sätze) ändern,
dann Schritt 1+2 erneut.
- **Info-Seite, Umbenennung, Autostart-Schalter, Fenster-Knöpfe, Scrollbalken
usw.:** stecken als Transformationen in `bundle.js`.
- **Fensterlogik / Autostart / externe Links:** `webview2/Program.cs`.
---
## Herkunft & Lizenz
Basiert auf **nightTab** von zombieFox Basiert auf **nightTab** von zombieFox
(https://github.com/zombieFox/nightTab), GNU General Public License v3.0. (https://github.com/zombieFox/nightTab), veröffentlicht unter der
Anpassung zum persönlichen Gebrauch. Deine Links: m-viper.de · git.viper.ipv64.net **GNU General Public License v3.0**. Der Ordner `quelle-nightTab/` enthält den
unveränderten nightTab-Build; die Anpassungen in diesem Repo unterliegen
ebenfalls der GPL v3.

408
bundle.js Normal file
View File

@@ -0,0 +1,408 @@
const fs = require('fs');
const path = require('path');
// Original nightTab source (input) lives next to this script.
const root = path.join(__dirname, 'quelle-nightTab');
// Output HTML: explicit arg, else default to the WebView2 project.
const out = process.argv[2] || path.join(__dirname, 'webview2', 'app-index.html');
const APPNAME = 'MyStart';
let css = fs.readFileSync(path.join(root, 'index.41b2d2a8cee846b032b5.css'), 'utf8');
const mime = { woff2: 'font/woff2', woff: 'font/woff', ttf: 'font/ttf' };
css = css.replace(/url\((font\/[^)]+)\)/g, (m, rel) => {
const p = path.join(root, rel);
const ext = rel.split('.').pop();
const b64 = fs.readFileSync(p).toString('base64');
return `url(data:${mime[ext] || 'application/octet-stream'};base64,${b64})`;
});
let initJs = fs.readFileSync(path.join(root, 'initialBackground.js'), 'utf8');
let mainJs = fs.readFileSync(path.join(root, 'index.09153abdbaa791fa4f0e.js'), 'utf8');
// --- 1) Remove the "Support" and "Coffee" entries from the settings menu ---
const navSnippet = '{name:"Support",active:!1,overscroll:!1},{name:"Coffee",active:!1,overscroll:!1},';
if (!mainJs.includes(navSnippet)) throw new Error('navData snippet not found — aborting');
mainJs = mainJs.replace(navSnippet, '');
// --- 1b) Rebuild the About page: logo + name + version + own website & git links ---
const aStart = 'const t=new Pa({text:"GitHub.';
const aEndMarker = ',s,o,n]))';
const i = mainJs.indexOf(aStart);
if (i < 0) throw new Error('About block start not found — aborting');
const j = mainJs.indexOf(aEndMarker, i);
if (j < 0) throw new Error('About block end not found — aborting');
const aboutBody =
'const t=new Pa({text:"m-viper.de",href:"https://m-viper.de",openNew:!0}),' +
'a=new Pa({text:"git.viper.ipv64.net",href:"https://git.viper.ipv64.net",openNew:!0}),' +
's=y("p");s.innerHTML=`Website: ${t.link().outerHTML}`;' +
'const o=y("p");o.innerHTML=`Git: ${a.link().outerHTML}`,' +
'e.appendChild(y("div",[y("div|class:version",[_t.render(),' +
'y("div|class:version-details",[y("h1:MyStart|class:version-app-name"),' +
'y("p:Version 1.0.0|class:version-number")])]),y("hr"),s,o,y("div|id:mystart-autostart-row,class:mystart-autostart-row")]))';
mainJs = mainJs.slice(0, i) + aboutBody + mainJs.slice(j + aEndMarker.length);
// --- 2) Rename branding (visible text + storage keys) consistently ---
const rename = (s) => s.split('nightTab').join(APPNAME);
mainJs = rename(mainJs);
initJs = rename(initJs);
// --- 3) Import: accept BOTH original nightTab backups and MyStart backups ---
// After rename the two validation gates only accept the "MyStart" marker key;
// re-add acceptance of the original "nightTab" marker so old backups import too.
const importGates = [
['JSON.parse(t).MyStart||JSON.parse(t)[nt.toLowerCase()]',
'JSON.parse(t).MyStart||JSON.parse(t).nightTab||JSON.parse(t)[nt.toLowerCase()]'],
['JSON.parse(r.target.result).MyStart||JSON.parse(r.target.result)[nt.toLowerCase()]',
'JSON.parse(r.target.result).MyStart||JSON.parse(r.target.result).nightTab||JSON.parse(r.target.result)[nt.toLowerCase()]'],
];
for (const [from, to] of importGates) {
if (!mainJs.includes(from)) throw new Error('import gate not found: ' + from);
mainJs = mainJs.replace(from, to);
}
// --- 4) German UI: translate the DISPLAY of menu tabs/sub-tabs/headers only.
// The underlying name stays English because it is used as a routing key
// (makeId = first word lowercased). __TR maps display text, keyed by that id.
const menuMap = {
theme:'Design', layout:'Layout', header:'Kopfzeile', bookmark:'Lesezeichen',
group:'Gruppe', toolbar:'Werkzeugleiste', data:'Daten', mystart:'MyStart',
preset:'Vorlage', saved:'Gespeichert', style:'Stil', colour:'Farbe',
accent:'Akzent', font:'Schrift', radius:'Radius', shadow:'Schatten',
shade:'Schattierung', opacity:'Deckkraft', background:'Hintergrund',
search:'Suche', scaling:'Skalierung', area:'Bereich', padding:'Innenabstand',
gutter:'Abstand', alignment:'Ausrichtung', page:'Seite', greeting:'Begrüßung',
transitional:'Übergangswörter', clock:'Uhr', date:'Datum', general:'Allgemein',
orientation:'Ausrichtung', sort:'Sortierung', name:'Name', size:'Größe',
location:'Ort', position:'Position', controls:'Steuerung',
restore:'Wiederherstellen', backup:'Sichern', clear:'Löschen',
};
const trInfra =
'window.__MT=' + JSON.stringify(menuMap) + ';' +
'window.__TR=function(s){if(s==null)return s;var k=String(s).split(" ")[0].toLowerCase();return window.__MT[k]||s;};';
// Autostart toggle: renders a CUSTOM slider switch into the About page's
// #mystart-autostart-row (native checkboxes are hidden by nightTab's CSS:
// opacity:0/position:absolute/pointer-events:none). Talks to the native host
// via postMessage; the host reads/writes the HKCU Run key.
const autostartJs = `(function(){
var A={enabled:false,supported:!!(window.chrome&&window.chrome.webview)};
window.__mystartAutostart=A;
function paint(){
var tr=document.getElementById('mystart-autostart-track');
var kn=document.getElementById('mystart-autostart-knob');
if(!tr||!kn)return;
tr.style.background=A.enabled?'#2ea043':'#565d68';
kn.style.left=A.enabled?'23px':'3px';
}
if(A.supported){
window.chrome.webview.addEventListener('message',function(ev){
var d=ev.data;if(d&&d.type==='autostart'){A.enabled=!!d.enabled;paint();}
});
}
function render(row){
var wrap=document.createElement('div');
wrap.style.cssText='display:flex;align-items:center;gap:10px;margin-top:18px;cursor:pointer;user-select:none;';
var track=document.createElement('div');
track.id='mystart-autostart-track';
track.style.cssText='position:relative;width:46px;height:26px;border-radius:13px;background:#565d68;flex:0 0 auto;transition:background .15s;box-sizing:border-box;';
var knob=document.createElement('div');
knob.id='mystart-autostart-knob';
knob.style.cssText='position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;background:#fff;transition:left .15s;box-shadow:0 1px 2px rgba(0,0,0,.4);box-sizing:border-box;';
track.appendChild(knob);
var txt=document.createElement('span');
txt.textContent='Mit Windows starten (minimiert)';
if(!A.supported){wrap.style.opacity='0.5';wrap.style.cursor='default';wrap.title='Nur in der MyStart-App verfügbar.';}
wrap.appendChild(track);wrap.appendChild(txt);row.appendChild(wrap);
paint();
wrap.addEventListener('click',function(){
if(!A.supported)return;
A.enabled=!A.enabled;paint();
try{window.chrome.webview.postMessage({type:'autostart-set',value:A.enabled});}catch(e){}
});
if(A.supported){try{window.chrome.webview.postMessage({type:'autostart-get'});}catch(e){}}
}
function ensure(){
var row=document.getElementById('mystart-autostart-row');
if(row&&!document.getElementById('mystart-autostart-track'))render(row);
}
new MutationObserver(ensure).observe(document.documentElement,{childList:true,subtree:true});
ensure();
})();`;
// Frameless-window controls (minimize / maximize-restore / close) in the top-right
// corner. Only shown inside the app (WebView2 host); they postMessage to the host.
const windowControlsJs = `(function(){
if(!(window.chrome&&window.chrome.webview))return;
function send(t){try{window.chrome.webview.postMessage({type:t});}catch(e){}}
function mk(glyph,title,type,isClose){
var b=document.createElement('div');
b.textContent=glyph;b.title=title;
b.style.cssText='width:44px;height:30px;display:flex;align-items:center;justify-content:center;font-family:"Segoe UI",system-ui,sans-serif;font-size:14px;line-height:1;color:#d0d4db;cursor:pointer;transition:background .1s,color .1s;-webkit-user-select:none;user-select:none;';
b.onmouseenter=function(){b.style.background=isClose?'#e81123':'rgba(255,255,255,0.18)';b.style.color='#fff';};
b.onmouseleave=function(){b.style.background='transparent';b.style.color='#d0d4db';};
b.onclick=function(){send(type);};
return b;
}
function mkGrip(){
var g=document.createElement('div');
g.title='Fenster verschieben (ziehen) — oder Alt + ziehen';
g.style.cssText='width:34px;height:30px;display:flex;align-items:center;justify-content:center;color:#9aa0aa;cursor:move;-webkit-user-select:none;user-select:none;';
g.innerHTML='<svg width="10" height="16" viewBox="0 0 10 16" fill="currentColor"><circle cx="2" cy="2" r="1.4"/><circle cx="8" cy="2" r="1.4"/><circle cx="2" cy="8" r="1.4"/><circle cx="8" cy="8" r="1.4"/><circle cx="2" cy="14" r="1.4"/><circle cx="8" cy="14" r="1.4"/></svg>';
g.onmouseenter=function(){g.style.color='#fff';};
g.onmouseleave=function(){g.style.color='#9aa0aa';};
g.addEventListener('mousedown',function(ev){if(ev.button!==0)return;ev.preventDefault();send('window-drag');});
return g;
}
function add(){
if(!document.body||document.getElementById('mystart-winctrls'))return;
var bar=document.createElement('div');
bar.id='mystart-winctrls';
bar.style.cssText='position:fixed;top:0;right:0;display:flex;align-items:center;z-index:2147483647;';
bar.appendChild(mkGrip());
bar.appendChild(mk('\\u2013','Minimieren','window-min',false));
bar.appendChild(mk('\\u25A1','Maximieren / Wiederherstellen','window-max',false));
bar.appendChild(mk('\\u2715','Schließen','window-close',true));
document.body.appendChild(bar);
}
if(document.body)add();else document.addEventListener('DOMContentLoaded',add);
new MutationObserver(function(){if(!document.getElementById('mystart-winctrls'))add();}).observe(document.documentElement,{childList:true,subtree:true});
// Alt + left-drag anywhere -> move the window (non-blocking).
document.addEventListener('mousedown',function(ev){
if(ev.button===0&&ev.altKey){ev.preventDefault();send('window-drag');}
},true);
})();`;
mainJs = trInfra + autostartJs + windowControlsJs + mainJs;
const trPatches = [
// panel header (top-level AND sub, both go through element.header)
['y("h1:"+e+"|class:menu-item-header-text")',
'y("h1:"+window.__TR(e)+"|class:menu-item-header-text")'],
// top-level nav tab label
['new Fe({text:e.name,style:["link"],block:!0,classList:["menu-nav-tab"]',
'new Fe({text:window.__TR(e.name),style:["link"],block:!0,classList:["menu-nav-tab"]'],
// sub-level nav label (href keeps makeId -> English routing key)
['y("a:"+e+"|href:#menu-content-item-"+this.makeId(e)',
'y("a:"+window.__TR(e)+"|href:#menu-content-item-"+this.makeId(e)'],
];
for (const [from, to] of trPatches) {
if (!mainJs.includes(from)) throw new Error('translate patch not found: ' + from);
mainJs = mainJs.replace(from, to);
}
// --- 5) Translate safe, unique display strings (search box, greeting, key texts).
// Tolerant: each is applied only if the exact literal is present. Structural
// names and icon labels are deliberately NOT touched.
const dict = [
// search box placeholder (base + engine name is appended after it)
['?"Find bookmarks or search":"Search"', '?"Lesezeichen finden oder suchen mit":"Suchen mit"'],
// greeting words
['"Good morning"', '"Guten Morgen"'],
['"Good afternoon"', '"Guten Tag"'],
['"Good evening"', '"Guten Abend"'],
['"Good night"', '"Gute Nacht"'],
['"Hello"', '"Hallo"'],
['"Welcome"', '"Willkommen"'],
['"Greetings"', '"Grüße"'],
// Data panel / confirmation descriptions (post-rename -> contain MyStart)
['"Restore a previously exported MyStart backup."', '"Eine zuvor exportierte MyStart-Sicherung wiederherstellen."'],
['"Restoring from a MyStart backup"', '"Aus einer MyStart-Sicherung wiederherstellen"'],
['"Clear all data to reset MyStart to the default state."', '"Alle Daten löschen, um MyStart auf den Ausgangszustand zurückzusetzen."'],
['"Clear MyStart data except bookmarks?"', '"MyStart-Daten außer Lesezeichen löschen?"'],
['"Or drop a MyStart backup file here."', '"Oder ziehe eine MyStart-Sicherungsdatei hierher."'],
// universal button
['text:"Add"', 'text:"Hinzufügen"'],
];
for (const [from, to] of dict) {
if (mainJs.includes(from)) mainJs = mainJs.split(from).join(to);
}
// --- 6) Full German UI: translate every remaining visible control/label/tooltip.
// Applied ONLY to value positions (:"...") so routing names (name:"Theme",
// sub:["Style"], case"layout") and the icon database stay untouched. The button
// behaviour lives in func()/keys, never in the display text, so this is safe.
const chrome = Object.entries(JSON.parse(fs.readFileSync(path.join(__dirname, 'lang', 'de.json'), 'utf8')));
const _unusedChrome = [
['Add', 'Hinzufügen'],
['Add 10 random bookmarks', '10 zufällige Lesezeichen hinzufügen'],
['Add a group', 'Gruppe hinzufügen'],
['Add a new Bookmark', 'Neues Lesezeichen hinzufügen'],
['Add a new Group', 'Neue Gruppe hinzufügen'],
['Add unique accent to each Bookmark', 'Jedem Lesezeichen eigene Akzentfarbe geben'],
['Adjust Visual Element position', 'Position des Symbols anpassen'],
['Area alignment', 'Ausrichtung des Bereichs'],
['Bold', 'Fett'],
['Bookmark area alignment', 'Ausrichtung des Lesezeichen-Bereichs'],
['Bookmark area background colour', 'Hintergrundfarbe des Lesezeichen-Bereichs'],
['By icon', 'Nach Icon'],
['By letter', 'Nach Buchstabe'],
['By name', 'Nach Name'],
['Clear all data', 'Alle Daten löschen'],
['Clear all except bookmarks', 'Alles außer Lesezeichen löschen'],
['Clear all MyStart data?', 'Alle MyStart-Daten löschen?'],
['Clear search', 'Suche leeren'],
['Close settings menu', 'Einstellungen schließen'],
['Collapse this Group', 'Diese Gruppe einklappen'],
['Copy to clipboard', 'In die Zwischenablage kopieren'],
['Drag bookmark to reorder', 'Lesezeichen ziehen zum Umsortieren'],
['Drag group to reorder', 'Gruppe ziehen zum Umsortieren'],
['Drag header item to reorder', 'Kopfzeilen-Element ziehen zum Umsortieren'],
['Edit saved themes', 'Gespeicherte Designs bearbeiten'],
['Edit this bookmark', 'Dieses Lesezeichen bearbeiten'],
['Edit this group', 'Diese Gruppe bearbeiten'],
['Edit this saved theme', 'Dieses gespeicherte Design bearbeiten'],
['Edit unnamed bookmark', 'Unbenanntes Lesezeichen bearbeiten'],
['Edit unnamed group', 'Unbenannte Gruppe bearbeiten'],
['Enter edit bookmark mode', 'Bearbeitungsmodus für Lesezeichen'],
['Export data', 'Daten exportieren'],
['Google Font', 'Google-Schriftart'],
['Google font name', 'Name der Google-Schriftart'],
['Group details area alignment', 'Ausrichtung des Gruppen-Detailbereichs'],
['Header area alignment', 'Ausrichtung des Kopfzeilen-Bereichs'],
['Header background colour', 'Hintergrundfarbe der Kopfzeile'],
['Header item alignment', 'Ausrichtung der Kopfzeilen-Elemente'],
['Hide all', 'Alle ausblenden'],
['How to link to a video file.', 'So verlinkst du eine Videodatei.'],
['Import', 'Importieren'],
['Import from clipboard', 'Aus Zwischenablage importieren'],
['Large button', 'Große Schaltfläche'],
['Layout Direction', 'Layout-Richtung'],
['Layout background colour', 'Hintergrundfarbe des Layouts'],
['Light', 'Dünn'],
['Line button', 'Linien-Schaltfläche'],
['Link button', 'Link-Schaltfläche'],
['Medium button', 'Mittlere Schaltfläche'],
['More controls', 'Mehr Optionen'],
['Move this bookmark left', 'Dieses Lesezeichen nach links'],
['Move this bookmark right', 'Dieses Lesezeichen nach rechts'],
['Move this group down', 'Diese Gruppe nach unten'],
['Move this group right', 'Diese Gruppe nach rechts'],
['Move this group up', 'Diese Gruppe nach oben'],
['Name hide', 'Name ausblenden'],
['Name show', 'Name anzeigen'],
['New Bookmark', 'Neues Lesezeichen'],
['New Group', 'Neue Gruppe'],
['New Tab', 'Neuer Tab'],
['Only icons', 'Nur Icons'],
['Only images', 'Nur Bilder'],
['Only letters', 'Nur Buchstaben'],
['Open all Bookmarks in this Group', 'Alle Lesezeichen dieser Gruppe öffnen'],
['Open settings menu', 'Einstellungen öffnen'],
['Random Group name', 'Zufälliger Gruppenname'],
['Random colour', 'Zufällige Farbe'],
['Random theme name', 'Zufälliger Designname'],
['Randomise now', 'Jetzt zufällig'],
['Regular', 'Normal'],
['Remove', 'Entfernen'],
['Remove all accent overrides', 'Alle Akzent-Überschreibungen entfernen'],
['Remove icon', 'Icon entfernen'],
['Remove this bookmark', 'Dieses Lesezeichen entfernen'],
['Remove this group', 'Diese Gruppe entfernen'],
['Remove this saved theme', 'Dieses gespeicherte Design entfernen'],
['Remove unnamed bookmark', 'Unbenanntes Lesezeichen entfernen'],
['Reset to default', 'Auf Standard zurücksetzen'],
['Ring button', 'Ring-Schaltfläche'],
['Save', 'Speichern'],
['Save current theme', 'Aktuelles Design speichern'],
['Scrollbar', 'Bildlaufleiste'],
['Search Bookmarks or', 'Lesezeichen durchsuchen oder'],
['Search box size', 'Größe des Suchfelds'],
['Search box width', 'Breite des Suchfelds'],
['Search engine', 'Suchmaschine'],
['Search engine name', 'Name der Suchmaschine'],
['Search text alignment', 'Textausrichtung der Suche'],
['Show all', 'Alle anzeigen'],
['Small button', 'Kleine Schaltfläche'],
['Start of the week', 'Wochenbeginn'],
['Toolbar position', 'Position der Werkzeugleiste'],
['Visual Element and Name alignment', 'Ausrichtung von Symbol und Name'],
['Why has this changed?', 'Warum hat sich das geändert?'],
['Word length', 'Wortlänge'],
['Wording', 'Formulierung'],
['You can restore all or parts of a backup file. The following data will be restored:',
'Du kannst eine Sicherung ganz oder teilweise wiederherstellen. Folgende Daten werden wiederhergestellt:'],
// placeholders
['Example', 'Beispiel'],
['Example group', 'Beispielgruppe'],
['Example theme', 'Beispiel-Design'],
['FontAwesome Brands or Icons', 'FontAwesome Brands oder Icons'],
['Hex code', 'Hex-Code'],
['Nickname, alias or superhero name', 'Spitzname, Alias oder Heldenname'],
];
// Locate the FontAwesome icon array (mr=[{name:"500px"...]) so we NEVER touch it.
const iconStart = mainJs.indexOf('mr=[{name:"500px"');
let iconEnd = -1;
if (iconStart >= 0) {
const bracket = mainJs.indexOf('[', iconStart);
let depth = 0;
for (let i = bracket; i < mainJs.length; i++) {
const c = mainJs[i];
if (c === '[') depth++;
else if (c === ']') { depth--; if (depth === 0) { iconEnd = i + 1; break; } }
else if (c === '"') { i++; while (i < mainJs.length && mainJs[i] !== '"') { if (mainJs[i] === '\\') i++; i++; } }
}
}
if (iconStart < 0 || iconEnd < 0) throw new Error('icon region not found — aborting translation');
const before = mainJs.slice(0, iconStart);
const iconRegion = mainJs.slice(iconStart, iconEnd);
const after = mainJs.slice(iconEnd);
// Only translate genuine DISPLAY properties, and only outside the icon data.
const displayProps = ['labelText', 'text', 'description', 'label', 'title', 'placeholder', 'heading', 'successText', 'tabText'];
const jsEsc = (v) => v.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
const translateChrome = (s) => {
for (const [en, de] of chrome) {
const deEsc = jsEsc(de);
for (const p of displayProps) {
const from = p + ':"' + en + '"';
if (s.includes(from)) s = s.split(from).join(p + ':"' + deEsc + '"');
}
}
return s;
};
mainJs = translateChrome(before) + iconRegion + translateChrome(after);
// --- 7) Long help/feedback/description sentences (y-DSL `y("p:..")`, text:[..] arrays,
// and description:"..."). Safe via exact match because these strings are long & unique.
const de2 = Object.entries(JSON.parse(fs.readFileSync(path.join(__dirname, 'lang', 'de2.json'), 'utf8')));
for (const [en, de] of de2) {
const deEsc = jsEsc(de);
// quoted literal (arrays, description:"...", any "..." occurrence)
mainJs = mainJs.split('"' + en + '"').join('"' + deEsc + '"');
// y-DSL with trailing attributes: y("p:TEXT|class:..")
mainJs = mainJs.split(':' + en + '|').join(':' + deEsc + '|');
// y-DSL without attributes: y("p:TEXT")
mainJs = mainJs.split(':' + en + '"').join(':' + deEsc + '"');
}
// --- 8) Two font-field hints that contain escaped quotes in the source literal. ---
const fontHints = [
['Clear the field to use the default font "Fjalla One".', 'Feld leeren, um die Standardschrift "Fjalla One" zu verwenden.'],
['Clear the field to use the default font "Open Sans".', 'Feld leeren, um die Standardschrift "Open Sans" zu verwenden.'],
];
for (const [en, de] of fontHints) {
if (mainJs.includes(en)) mainJs = mainJs.split(en).join(de);
}
const favSvg = fs.readFileSync(path.join(root, 'icon/favicon.svg'));
const favData = 'data:image/svg+xml;base64,' + favSvg.toString('base64');
const html = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"><title>${APPNAME}</title><link rel="icon" type="image/svg+xml" class="favicon" href="${favData}"/><style media="screen">html,body {background-color: rgb(0, 0, 0);}@media (prefers-color-scheme: dark) {html,body {background-color: rgb(0, 0, 0);}}@media (prefers-color-scheme: light) {html,body {background-color: rgb(255, 255, 255);}}</style>
<style>${css}</style>
<style>/* Scrollbalken ans dunkle MyStart-Design anpassen (schlank, dunkel, ohne Pfeile) */
::-webkit-scrollbar{width:10px;height:10px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,0.22);border-radius:8px;border:2px solid transparent;background-clip:padding-box;}
::-webkit-scrollbar-thumb:hover{background-color:rgba(255,255,255,0.38);background-clip:padding-box;}
::-webkit-scrollbar-button{display:none;height:0;width:0;}
::-webkit-scrollbar-corner{background:transparent;}</style>
<script>${initJs}</script>
</head><body>
<script>${mainJs}</script>
</body></html>`;
fs.writeFileSync(out, html);
const kb = (fs.statSync(out).size / 1024).toFixed(0);
console.log('Written: ' + out + ' (' + kb + ' KB) [Support/Coffee removed, renamed to ' + APPNAME + ']');

338
lang/de.json Normal file
View File

@@ -0,0 +1,338 @@
{
"24 hours": "24 Stunden",
"Accent": "Akzent",
"Accent colour": "Akzentfarbe",
"Add": "Hinzufügen",
"Add 10 random bookmarks": "10 zufällige Lesezeichen hinzufügen",
"Add a group": "Gruppe hinzufügen",
"Add a new Bookmark": "Neues Lesezeichen hinzufügen",
"Add a new Group": "Neue Gruppe hinzufügen",
"Add to existing bookmarks": "Zu vorhandenen Lesezeichen hinzufügen",
"Add unique accent to each Bookmark": "Jedem Lesezeichen eigene Akzentfarbe geben",
"Address": "Adresse",
"Adjust Visual Element position": "Position des Symbols anpassen",
"Align horizontal": "Horizontal ausrichten",
"Align vertical": "Vertikal ausrichten",
"All opacity": "Gesamt-Deckkraft",
"Any": "Beliebig",
"Apply Layout to other Bookmarks": "Layout auf andere Lesezeichen anwenden",
"Apply Theme to other Bookmarks": "Design auf andere Lesezeichen anwenden",
"Area alignment": "Ausrichtung des Bereichs",
"Arrange the Visual Element and Name side by side.": "Symbol und Name nebeneinander anordnen.",
"As number": "Als Zahl",
"As word": "Als Wort",
"Auto": "Automatisch",
"Auto change Accent hue": "Akzent-Farbton automatisch ändern",
"Auto width": "Automatische Breite",
"Automatic": "Automatisch",
"backed up your data?": "deine Daten gesichert?",
"Background blur": "Hintergrund-Unschärfe",
"Background by Accent": "Hintergrund nach Akzent",
"Background by Theme": "Hintergrund nach Design",
"Background colour": "Hintergrundfarbe",
"Background gradient angle": "Winkel des Hintergrund-Verlaufs",
"Background gradient end": "Ende des Hintergrund-Verlaufs",
"Background gradient start": "Beginn des Hintergrund-Verlaufs",
"Background image URL": "Hintergrundbild-URL",
"Background opacity": "Hintergrund-Deckkraft",
"Background video URL": "Hintergrundvideo-URL",
"Block": "Block",
"Blue": "Blau",
"Blur": "Unschärfe",
"Bold": "Fett",
"Bookmark": "Lesezeichen",
"Bookmark area alignment": "Ausrichtung des Lesezeichen-Bereichs",
"Bookmark area background colour": "Hintergrundfarbe des Lesezeichen-Bereichs",
"Bookmark area width": "Breite des Lesezeichen-Bereichs",
"Bookmark border": "Lesezeichen-Rahmen",
"Bookmark icon": "Lesezeichen-Icon",
"Bookmark image": "Lesezeichen-Bild",
"Bookmark letter": "Lesezeichen-Buchstabe",
"Bookmark name": "Lesezeichen-Name",
"Bookmark size": "Lesezeichen-Größe",
"Bookmark tile to span across two columns.": "Lesezeichen-Kachel über zwei Spalten spannen.",
"Bookmarks": "Lesezeichen",
"Bookmarks then Group details": "Lesezeichen, dann Gruppendetails",
"Bookmarks then Header": "Lesezeichen, dann Kopfzeile",
"Border": "Rahmen",
"Bottom": "Unten",
"Bottom Center": "Unten Mitte",
"Bottom Left": "Unten Links",
"Bottom left": "Unten links",
"Bottom Right": "Unten Rechts",
"Bottom right": "Unten rechts",
"By icon": "Nach Icon",
"By letter": "Nach Buchstabe",
"By name": "Nach Name",
"Center": "Mitte",
"Center Center": "Mitte Mitte",
"Center Left": "Mitte Links",
"Center Right": "Mitte Rechts",
"Change delay": "Verzögerung ändern",
"Change steps": "Schritte ändern",
"Clear all data": "Alle Daten löschen",
"Clear all except bookmarks": "Alles außer Lesezeichen löschen",
"Clear all MyStart data?": "Alle MyStart-Daten löschen?",
"Clear MyStart data except bookmarks?": "MyStart-Daten außer Lesezeichen löschen?",
"Clear search": "Suche leeren",
"Close settings menu": "Einstellungen schließen",
"Collapse this Group": "Diese Gruppe einklappen",
"Colour": "Farbe",
"Contrast end": "Kontrast-Ende",
"Contrast range": "Kontrast-Bereich",
"Contrast start": "Kontrast-Beginn",
"Copy to clipboard": "In die Zwischenablage kopieren",
"Corners radius": "Eckenradius",
"Custom": "Benutzerdefiniert",
"Custom Accent": "Eigener Akzent",
"Custom colour": "Eigene Farbe",
"Custom greeting text": "Eigener Begrüßungstext",
"Custom width": "Eigene Breite",
"Dark": "Dunkel",
"Dark mode": "Dunkler Modus",
"Date / Month": "Datum / Monat",
"Define how wide the Search box should be inside the Header Area.": "Lege fest, wie breit das Suchfeld im Kopfbereich sein soll.",
"Display an Image or video Background on this Bookmark tile.": "Ein Bild oder Video als Hintergrund dieser Lesezeichen-Kachel anzeigen.",
"Display font": "Anzeige-Schriftart",
"Display Letters, Icon or an Image on this Bookmark hexagon.": "Buchstaben, Icon oder ein Bild auf diesem Lesezeichen anzeigen.",
"Divider between Header and Bookmark area": "Trennlinie zwischen Kopf- und Lesezeichen-Bereich",
"Drag bookmark to reorder": "Lesezeichen ziehen zum Umsortieren",
"Drag group to reorder": "Gruppe ziehen zum Umsortieren",
"Drag header item to reorder": "Kopfzeilen-Element ziehen zum Umsortieren",
"Edit saved themes": "Gespeicherte Designs bearbeiten",
"Edit this bookmark": "Dieses Lesezeichen bearbeiten",
"Edit this group": "Diese Gruppe bearbeiten",
"Edit this saved theme": "Dieses gespeicherte Design bearbeiten",
"Edit unnamed bookmark": "Unbenanntes Lesezeichen bearbeiten",
"Edit unnamed group": "Unbenannte Gruppe bearbeiten",
"Effects may not be visible if Theme Shadow is set to 0.": "Effekte sind evtl. nicht sichtbar, wenn der Design-Schatten auf 0 steht.",
"Enter edit bookmark mode": "Bearbeitungsmodus für Lesezeichen",
"Example": "Beispiel",
"Example group": "Beispielgruppe",
"Example theme": "Beispiel-Design",
"Existing Group": "Vorhandene Gruppe",
"Export data": "Daten exportieren",
"Favicon URL": "Favicon-URL",
"Follow the system Light or Dark mode.": "Dem hellen oder dunklen Systemmodus folgen.",
"Font weight": "Schriftstärke",
"FontAwesome Brands or Icons": "FontAwesome Brands oder Icons",
"Force on to a new line and seperate from other Header items.": "In eine neue Zeile zwingen und von anderen Kopf-Elementen trennen.",
"Format": "Format",
"Global size": "Gesamtgröße",
"Google Font": "Google-Schriftart",
"Google font name": "Name der Google-Schriftart",
"Gradient": "Verlauf",
"Grayscale": "Graustufen",
"Green": "Grün",
"Group": "Gruppe",
"Group details area alignment": "Ausrichtung des Gruppen-Detailbereichs",
"Group details then Bookmarks": "Gruppendetails, dann Lesezeichen",
"Group name": "Gruppenname",
"Group toolbar": "Gruppen-Werkzeugleiste",
"Group toolbar size": "Größe der Gruppen-Werkzeugleiste",
"Grow on Bookmark hover": "Beim Überfahren vergrößern",
"Gutter": "Abstand",
"Header area alignment": "Ausrichtung des Kopfbereichs",
"Header area background colour": "Hintergrundfarbe des Kopfbereichs",
"Header area width": "Breite des Kopfbereichs",
"Header background colour": "Hintergrundfarbe der Kopfzeile",
"Header item alignment": "Ausrichtung der Kopf-Elemente",
"Header then Bookmarks": "Kopfzeile, dann Lesezeichen",
"Hex code": "Hex-Code",
"Hidden": "Ausgeblendet",
"Hide all": "Alle ausblenden",
"Horizontal": "Horizontal",
"How to link to a video file.": "So verlinkst du eine Videodatei.",
"Hue": "Farbton",
"Icon": "Icon",
"Image": "Bild",
"Import": "Importieren",
"Import from clipboard": "Aus Zwischenablage importieren",
"Import from file": "Aus Datei importieren",
"In a corner": "In einer Ecke",
"In the Header": "In der Kopfzeile",
"Italic": "Kursiv",
"Large button": "Große Schaltfläche",
"Layout": "Layout",
"Layout area width": "Breite des Layout-Bereichs",
"Layout background colour": "Hintergrundfarbe des Layouts",
"Layout Direction": "Layout-Richtung",
"Left": "Links",
"Letter": "Buchstabe",
"Light": "Dünn",
"Light mode": "Heller Modus",
"Lightness": "Helligkeit",
"Line button": "Linien-Schaltfläche",
"Link button": "Link-Schaltfläche",
"List": "Liste",
"Long": "Lang",
"Medium button": "Mittlere Schaltfläche",
"Monday": "Montag",
"Month / Date": "Monat / Datum",
"More controls": "Mehr Optionen",
"Move this bookmark left": "Dieses Lesezeichen nach links",
"Move this bookmark right": "Dieses Lesezeichen nach rechts",
"Move this group down": "Diese Gruppe nach unten",
"Move this group right": "Diese Gruppe nach rechts",
"Move this group up": "Diese Gruppe nach oben",
"Name": "Name",
"Name attribute": "Name-Attribut",
"Name hide": "Name ausblenden",
"Name show": "Name anzeigen",
"Name size": "Namensgröße",
"Name then visual element": "Name, dann Symbol",
"New Bookmark": "Neues Lesezeichen",
"New Group": "Neue Gruppe",
"New line": "Neue Zeile",
"New Tab": "Neuer Tab",
"Nickname, alias or superhero name": "Spitzname, Alias oder Heldenname",
"No background colour behind the Bookmark area.": "Keine Hintergrundfarbe hinter dem Lesezeichen-Bereich.",
"No background colour behind the Header area.": "Keine Hintergrundfarbe hinter dem Kopfbereich.",
"No background colour behind the Layout.": "Keine Hintergrundfarbe hinter dem Layout.",
"None": "Keine",
"Normal": "Normal",
"Only icons": "Nur Icons",
"Only images": "Nur Bilder",
"Only letters": "Nur Buchstaben",
"Opacity": "Deckkraft",
"Open all Bookmarks in this Group": "Alle Lesezeichen dieser Gruppe öffnen",
"Open all button will appear if there is at least one Bookmark in this Group.": "Die Schaltfläche \"Alle öffnen\" erscheint, wenn diese Gruppe mindestens ein Lesezeichen enthält.",
"Open Bookmarks in a new tab": "Lesezeichen in neuem Tab öffnen",
"Open Search results in a new tab": "Suchergebnisse in neuem Tab öffnen",
"Open settings menu": "Einstellungen öffnen",
"Or drop a MyStart backup file here.": "Oder ziehe eine MyStart-Sicherungsdatei hierher.",
"Order the Bookmarks area to appear before the Group details area.": "Den Lesezeichen-Bereich vor dem Gruppen-Detailbereich anzeigen.",
"Order the Bookmarks area to appear before the Header area.": "Den Lesezeichen-Bereich vor dem Kopfbereich anzeigen.",
"Order the Group details area to appear before the Bookmarks area.": "Den Gruppen-Detailbereich vor dem Lesezeichen-Bereich anzeigen.",
"Order the Header area to appear before the Bookmarks area.": "Den Kopfbereich vor dem Lesezeichen-Bereich anzeigen.",
"Ordinal numbers": "Ordnungszahlen",
"Override the Theme Accent.": "Den Design-Akzent überschreiben.",
"Override the Theme colour.": "Die Design-Farbe überschreiben.",
"Pastel": "Pastell",
"Place the Name before the Visual Element.": "Den Namen vor dem Symbol platzieren.",
"Place the Visual Element before the Name.": "Das Symbol vor dem Namen platzieren.",
"Position": "Position",
"Primary colour": "Primärfarbe",
"Random Accent colour on load/refresh": "Zufällige Akzentfarbe beim Laden/Aktualisieren",
"Random colour": "Zufällige Farbe",
"Random Group name": "Zufälliger Gruppenname",
"Random theme name": "Zufälliger Designname",
"Randomise now": "Jetzt zufällig",
"Red": "Rot",
"Regular": "Normal",
"Remove": "Entfernen",
"Remove all accent overrides": "Alle Akzent-Überschreibungen entfernen",
"Remove icon": "Icon entfernen",
"Remove this bookmark": "Dieses Lesezeichen entfernen",
"Remove this group": "Diese Gruppe entfernen",
"Remove this saved theme": "Dieses gespeicherte Design entfernen",
"Remove unnamed bookmark": "Unbenanntes Lesezeichen entfernen",
"Replace existing bookmarks": "Vorhandene Lesezeichen ersetzen",
"Reset to default": "Auf Standard zurücksetzen",
"Restoring from a MyStart backup": "Aus einer MyStart-Sicherung wiederherstellen",
"Right": "Rechts",
"Ring button": "Ring-Schaltfläche",
"Rotate": "Drehen",
"Saturated": "Gesättigt",
"Saturation": "Sättigung",
"Save": "Speichern",
"Save current theme": "Aktuelles Design speichern",
"Scale": "Skalierung",
"Scroll past end": "Über das Ende hinaus scrollen",
"Scrollbar": "Bildlaufleiste",
"Search": "Suche",
"Search Bookmarks or": "Lesezeichen durchsuchen oder",
"Search box": "Suchfeld",
"Search box size": "Größe des Suchfelds",
"Search box width": "Breite des Suchfelds",
"Search box will grow to best fit available space.": "Das Suchfeld wächst, um den verfügbaren Platz optimal zu nutzen.",
"Search engine": "Suchmaschine",
"Search engine name": "Name der Suchmaschine",
"Search text alignment": "Textausrichtung der Suche",
"Separator character": "Trennzeichen",
"Settings": "Einstellungen",
"Shade blur": "Schattierungs-Unschärfe",
"Shade end": "Schattierungs-Ende",
"Shade opacity": "Schattierungs-Deckkraft",
"Shade start": "Schattierungs-Beginn",
"Shade start and end": "Schattierung Beginn und Ende",
"Shadow size": "Schattengröße",
"Short": "Kurz",
"Short and wide Bookmark tiles.": "Kurze, breite Lesezeichen-Kacheln.",
"Show Accent control": "Akzent-Steuerung anzeigen",
"Show Add control": "Hinzufügen-Steuerung anzeigen",
"Show all": "Alle anzeigen",
"Show background": "Hintergrund anzeigen",
"Show Bookmark line": "Lesezeichen-Linie anzeigen",
"Show Bookmarks": "Lesezeichen anzeigen",
"Show Collapse": "Einklappen anzeigen",
"Show Date": "Datum anzeigen",
"Show Day": "Wochentag anzeigen",
"Show Edit control": "Bearbeiten-Steuerung anzeigen",
"Show Greeting": "Begrüßung anzeigen",
"Show Group name": "Gruppenname anzeigen",
"Show hours": "Stunden anzeigen",
"Show minutes": "Minuten anzeigen",
"Show Month": "Monat anzeigen",
"Show Name": "Name anzeigen",
"Show Open all": "\"Alle öffnen\" anzeigen",
"Show Search": "Suche anzeigen",
"Show seconds": "Sekunden anzeigen",
"Show separator": "Trennzeichen anzeigen",
"Show shadow on Bookmark hover": "Schatten beim Überfahren anzeigen",
"Show Transitional words": "Übergangswörter anzeigen",
"Show URL on Bookmark hover": "URL beim Überfahren anzeigen",
"Show Visual Element": "Symbol anzeigen",
"Show Year": "Jahr anzeigen",
"Size": "Größe",
"Small button": "Kleine Schaltfläche",
"Space around Header and Bookmark Area": "Abstand um Kopf- und Lesezeichen-Bereich",
"Space between Header and Bookmark items": "Abstand zwischen Kopf- und Lesezeichen-Elementen",
"Square shaped Bookmark tiles.": "Quadratische Lesezeichen-Kacheln.",
"Stack the Header and Bookmarks in a column one above the other.": "Kopfzeile und Lesezeichen in einer Spalte übereinander anordnen.",
"Stack the Header and Bookmarks in a row side by side.": "Kopfzeile und Lesezeichen in einer Reihe nebeneinander anordnen.",
"Stack the Visual Element and Name one above the other.": "Symbol und Name übereinander anordnen.",
"Start of the week": "Wochenbeginn",
"Sunday": "Sonntag",
"Tall tile": "Hohe Kachel",
"The Collapse button will show or hide the Bookmaks in this Group.": "Die Einklappen-Schaltfläche zeigt oder verbirgt die Lesezeichen dieser Gruppe.",
"Theme": "Design",
"Theme Accent": "Design-Akzent",
"Theme colour": "Design-Farbe",
"Thin": "Dünn",
"This includes the Colour, Accent, Fonts, Background and any saved Custom Themes.": "Dies umfasst Farbe, Akzent, Schriftarten, Hintergrund und alle gespeicherten eigenen Designs.",
"Title": "Titel",
"Toolbar": "Werkzeugleiste",
"Toolbar position": "Position der Werkzeugleiste",
"Toolbar size": "Größe der Werkzeugleiste",
"Top": "Oben",
"Top Center": "Oben Mitte",
"Top Left": "Oben Links",
"Top left": "Oben links",
"Top Right": "Oben Rechts",
"Top right": "Oben rechts",
"Transparent": "Transparent",
"Use a custom colour behind the Bookmark area.": "Eine eigene Farbe hinter dem Lesezeichen-Bereich verwenden.",
"Use a custom colour behind the Header area.": "Eine eigene Farbe hinter dem Kopfbereich verwenden.",
"Use a custom colour behind the Layout.": "Eine eigene Farbe hinter dem Layout verwenden.",
"Use the Accent colour for the Background.": "Die Akzentfarbe für den Hintergrund verwenden.",
"Use the Accent defined by the Theme.": "Den vom Design festgelegten Akzent verwenden.",
"Use the Background colour defined by the Theme.": "Die vom Design festgelegte Hintergrundfarbe verwenden.",
"Use the Colour defined by the Theme.": "Die vom Design festgelegte Farbe verwenden.",
"Useful for just displaying your name.": "Praktisch, um nur deinen Namen anzuzeigen.",
"User interface font": "Schriftart der Oberfläche",
"Vertical": "Vertikal",
"Video": "Video",
"Vignette": "Vignette",
"Visual & Name": "Symbol & Name",
"Visual Element and Name alignment": "Ausrichtung von Symbol und Name",
"Visual element then name": "Symbol, dann Name",
"Visual shadow": "Symbol-Schatten",
"Visual size": "Symbolgröße",
"Why has this changed?": "Warum hat sich das geändert?",
"Wide tile": "Breite Kachel",
"Width": "Breite",
"Word length": "Wortlänge",
"Wording": "Formulierung",
"You can restore all or parts of a backup file. The following data will be restored:": "Du kannst eine Sicherung ganz oder teilweise wiederherstellen. Folgende Daten werden wiederhergestellt:"
}

66
lang/de2.json Normal file
View File

@@ -0,0 +1,66 @@
{
"Add more than one URL separated by spaces or on new lines for a random background image on load.": "Gib mehrere URLs durch Leerzeichen oder Zeilenumbrüche getrennt an, um beim Laden ein zufälliges Hintergrundbild zu erhalten.",
"Add more than one URL separated by spaces or on new lines for a random background video on load.": "Gib mehrere URLs durch Leerzeichen oder Zeilenumbrüche getrennt an, um beim Laden ein zufälliges Hintergrundvideo zu erhalten.",
"Alternatively, it is possible to wipe all settings but keep the current Bookmarks and Groups.": "Alternativ kannst du alle Einstellungen löschen, aber die aktuellen Lesezeichen und Gruppen behalten.",
"Applying a Preset will replace the current Colour, Accent, Font, Style, Opacity, Radius, Shadow, Shade and Background.": "Eine Vorlage ersetzt die aktuelle Farbe, Akzent, Schrift, Stil, Deckkraft, Radius, Schatten, Schattierung und Hintergrund.",
"Are you sure you want to clear all MyStart Bookmarks and Settings? MyStart will be restore to the default state.": "Möchtest du wirklich alle MyStart-Lesezeichen und -Einstellungen löschen? MyStart wird auf den Ausgangszustand zurückgesetzt.",
"Auto change Accent hue will not work when the Accent colour is a grey or black.": "Der automatische Akzent-Farbtonwechsel funktioniert nicht, wenn die Akzentfarbe grau oder schwarz ist.",
"Background image only supports a direct URL to an image file.": "Für das Hintergrundbild wird nur eine direkte URL zu einer Bilddatei unterstützt.",
"Background video only supports a direct URL to a video file. Supports MP4 and WebM format.": "Für das Hintergrundvideo wird nur eine direkte URL zu einer Videodatei unterstützt. Unterstützt MP4 und WebM.",
"Backgrounds, Bookmarks and Modals use shades from the left.": "Hintergründe, Lesezeichen und Dialoge nutzen Schattierungen von links.",
"Bookmark border can also be changed when editing individual Bookmarks.": "Der Lesezeichen-Rahmen kann auch beim Bearbeiten einzelner Lesezeichen geändert werden.",
"Bookmark custom Accent can also be changed when editing individual Bookmarks.": "Der eigene Akzent eines Lesezeichens kann auch beim Bearbeiten einzelner Lesezeichen geändert werden.",
"Change parameters after .../random/ for more options. Loading times may vary.": "Ändere die Parameter nach .../random/ für mehr Optionen. Ladezeiten können variieren.",
"Change the opacity of Search bar, Bookmarks, Group controls and the Toolbar.": "Ändere die Deckkraft von Suchleiste, Lesezeichen, Gruppen-Steuerung und Werkzeugleiste.",
"Change the Visual Element and Name position, scale and orientation.": "Ändere Position, Größe und Ausrichtung von Symbol und Name.",
"Clear all data to reset MyStart to the default state.": "Alle Daten löschen, um MyStart auf den Ausgangszustand zurückzusetzen.",
"Display a Name above this Group.": "Einen Namen über dieser Gruppe anzeigen.",
"Display controls to open all or show/hide the Bookmarks in this Group.": "Steuerung anzeigen, um alle Lesezeichen dieser Gruppe zu öffnen oder ein-/auszublenden.",
"Display Letters, Icon, Image and a Name on this Bookmark tile.": "Buchstaben, Icon, Bild und einen Namen auf dieser Lesezeichen-Kachel anzeigen.",
"Display the URL and Controls either at the top or bottom of a Bookmark Tile.": "URL und Steuerung entweder oben oder unten auf einer Lesezeichen-Kachel anzeigen.",
"Download a backup of your MyStart Bookmarks and Settings.": "Eine Sicherung deiner MyStart-Lesezeichen und -Einstellungen herunterladen.",
"Effects may not be visible if the Bookmark Area is full width.": "Effekte sind evtl. nicht sichtbar, wenn der Lesezeichen-Bereich die volle Breite hat.",
"Effects may not be visible if the Header Area is full width.": "Effekte sind evtl. nicht sichtbar, wenn der Kopfbereich die volle Breite hat.",
"For a light look switch to the Light Style and then select a Primary colour. And vice versa for a dark look.": "Für ein helles Aussehen zum hellen Stil wechseln und eine Primärfarbe wählen. Für ein dunkles Aussehen umgekehrt.",
"Group Collapse": "Gruppe einklappen",
"Group Names can also be changed by editing individual Groups.": "Gruppennamen können auch beim Bearbeiten einzelner Gruppen geändert werden.",
"Group Open all": "Gruppe: Alle öffnen",
"Group toolbar collapse button can also be changed by editing individual Groups.": "Die Einklappen-Schaltfläche der Gruppen-Werkzeugleiste kann auch beim Bearbeiten einzelner Gruppen geändert werden.",
"Group toolbar open all button can also be changed by editing individual Groups.": "Die \"Alle öffnen\"-Schaltfläche der Gruppen-Werkzeugleiste kann auch beim Bearbeiten einzelner Gruppen geändert werden.",
"Local images can no longer be used. Images must be hosted somewhere online.": "Lokale Bilder können nicht mehr verwendet werden. Bilder müssen online gehostet sein.",
"Move the Contrast range controls close together for a muted look.": "Schiebe die Kontrast-Regler nah zusammen für einen gedämpften Look.",
"Move the Contrast range controls far apart from each other for a sharp vivid look.": "Schiebe die Kontrast-Regler weit auseinander für einen scharfen, kräftigen Look.",
"No Bookmarks in this Group": "Keine Lesezeichen in dieser Gruppe",
"No Groups or Bookmarks": "Keine Gruppen oder Lesezeichen",
"Not a JSON file. Make sure the selected file came from MyStart.": "Keine JSON-Datei. Stelle sicher, dass die Datei von MyStart stammt.",
"Not all fonts support all weights. Refer to the Google Font page to see which are available.": "Nicht alle Schriftarten unterstützen alle Stärken. Auf der Google-Fonts-Seite siehst du, welche verfügbar sind.",
"Not supported by all browsers.": "Nicht von allen Browsern unterstützt.",
"Not the right kind of data. Make sure the clipboard holds data from MyStart or a MyStart backup JSON file.": "Falsche Art von Daten. Stelle sicher, dass die Zwischenablage Daten von MyStart oder eine MyStart-Sicherungs-JSON enthält.",
"Not the right kind of JSON file. Make sure the selected file came from MyStart.": "Falsche Art von JSON-Datei. Stelle sicher, dass die Datei von MyStart stammt.",
"Nothing selected to import.": "Nichts zum Importieren ausgewählt.",
"Only available when Date or Time is shown.": "Nur verfügbar, wenn Datum oder Uhrzeit angezeigt wird.",
"Only available when the Toolbar is positioned in a corner.": "Nur verfügbar, wenn die Werkzeugleiste in einer Ecke positioniert ist.",
"Only available when the Toolbar is positioned inside the Header.": "Nur verfügbar, wenn die Werkzeugleiste in der Kopfzeile positioniert ist.",
"Opacity can also be changed when editing individual Bookmarks.": "Die Deckkraft kann auch beim Bearbeiten einzelner Lesezeichen geändert werden.",
"Ordering": "Reihenfolge",
"Override the Theme and Accent colour.": "Design- und Akzentfarbe überschreiben.",
"Position the Toolbar in one of the four corners of the window.": "Die Werkzeugleiste in einer der vier Ecken des Fensters positionieren.",
"Position the Toolbar inside the Header or in a corner of the window.": "Die Werkzeugleiste in der Kopfzeile oder in einer Ecke des Fensters positionieren.",
"Restore a previously exported MyStart backup.": "Eine zuvor exportierte MyStart-Sicherung wiederherstellen.",
"Saving a Theme will record the current Colour, Accent, Font, Style, Opacity, Radius, Shadow, Shade and Background.": "Beim Speichern eines Designs werden die aktuelle Farbe, Akzent, Schrift, Stil, Deckkraft, Radius, Schatten, Schattierung und Hintergrund festgehalten.",
"Sets the name attribute on the Search input field.": "Legt das name-Attribut des Such-Eingabefelds fest.",
"Success! Restoring MyStart Bookmarks and Settings.": "Erfolg! MyStart-Lesezeichen und -Einstellungen werden wiederhergestellt.",
"Take care as a fast changing Accent hue may cause performance issues.": "Vorsicht: Ein schnell wechselnder Akzent-Farbton kann die Leistung beeinträchtigen.",
"Text and form elements use shades from the right.": "Text und Formularelemente nutzen Schattierungen von rechts.",
"The colour of the Border is defined by the Accent which can also be changed when editing individual Bookmarks.": "Die Rahmenfarbe wird durch den Akzent bestimmt, der auch beim Bearbeiten einzelner Lesezeichen geändert werden kann.",
"The Group to place this Bookmark in.": "Die Gruppe, in die dieses Lesezeichen gehört.",
"The position of this Group.": "Die Position dieser Gruppe.",
"This can not be undone.": "Dies kann nicht rückgängig gemacht werden.",
"This defines the name passed to the search engine when submitting. If not sure leave blank.": "Legt den Namen fest, der beim Absenden an die Suchmaschine übergeben wird. Im Zweifel leer lassen.",
"This file can later be imported on this or another deivce.": "Diese Datei kann später auf diesem oder einem anderen Gerät importiert werden.",
"Unsplash can be used for random images, eg:": "Unsplash kann für zufällige Bilder genutzt werden, z. B.:",
"Visual shadow only applies to a Letter or Icon.": "Der Symbol-Schatten gilt nur für Buchstaben oder Icons.",
"You will lose Bookmarks by clearing all data.": "Beim Löschen aller Daten gehen die Lesezeichen verloren.",
"YouTube page URLs <strong>can not</strong> be used.": "YouTube-Seiten-URLs <strong>können nicht</strong> verwendet werden.",
"YouTube page URLs can not be used.": "YouTube-Seiten-URLs können nicht verwendet werden."
}

View File

@@ -0,0 +1 @@
[{"description":"treehash per file","signed_content":{"payload":"eyJjb250ZW50X2hhc2hlcyI6W3siYmxvY2tfc2l6ZSI6NDA5NiwiZGlnZXN0Ijoic2hhMjU2IiwiZmlsZXMiOlt7InBhdGgiOiJmb250L2ZhLWJyYW5kcy00MDAudHRmIiwicm9vdF9oYXNoIjoiSjBmSDRJNmtKYkt1ak5LNFhpdE5fSGh6WDkzZ1Jsa1ZqSkpFNVhiZU0ydyJ9LHsicGF0aCI6ImZvbnQvZmEtYnJhbmRzLTQwMC53b2ZmIiwicm9vdF9oYXNoIjoiaVpJYWc2dW0zTGdVUm90TkJSYUVvRXpFeC1MZjBkMm8wQW44SWJzR1ZBSSJ9LHsicGF0aCI6ImZvbnQvZmEtYnJhbmRzLTQwMC53b2ZmMiIsInJvb3RfaGFzaCI6ImxfVGhlWGZhYzF4VU1yUWtyQzVRd1kzUlMxZDNmX3pvOVhfV1lnVnVsekkifSx7InBhdGgiOiJmb250L2ZhLXJlZ3VsYXItNDAwLnR0ZiIsInJvb3RfaGFzaCI6Ii0tem4tSnpiWTVyY0dESjZyVFI4QUpFeGxRN05WX1AwNTV4YVJmZTV2VDQifSx7InBhdGgiOiJmb250L2ZhLXJlZ3VsYXItNDAwLndvZmYiLCJyb290X2hhc2giOiJ3REJFX2xkUE1GbzF1LWQ3SnVwa0RtRUZxa05rRWxhWG9zWG1iR2M1YUFnIn0seyJwYXRoIjoiZm9udC9mYS1yZWd1bGFyLTQwMC53b2ZmMiIsInJvb3RfaGFzaCI6IlRXU0pLVUdWREVrN3hEYzBYMF9MOEYtNGtpNGg1TVdPeUJvdU1Ob1RZR1UifSx7InBhdGgiOiJmb250L2ZhLXNvbGlkLTkwMC50dGYiLCJyb290X2hhc2giOiJ2WWlhMUZXR1JvbXo0d29oVFMtZnBCSjIzWWZFYXllc29EOFNyNmNIR3E4In0seyJwYXRoIjoiZm9udC9mYS1zb2xpZC05MDAud29mZiIsInJvb3RfaGFzaCI6IkpRRUNmZ0szUlJBR3dRQnh1dVZ1TGpVV0o1aG56ZzBUcWQ0TXlNdGJUV1kifSx7InBhdGgiOiJmb250L2ZhLXNvbGlkLTkwMC53b2ZmMiIsInJvb3RfaGFzaCI6Il9hSzNPUjBLSk9fRms3OE94MDFoRkthZVN5YnRGWk1GYzRUOHlvVXBzNncifSx7InBhdGgiOiJmb250L2ZqYWxsYS1vbmUtNDAwLnR0ZiIsInJvb3RfaGFzaCI6IlJuc3pGUThOTlVCek9xdVJsZndqY0VlV3ZjYndHbkszOF9xRjE3U094Q2MifSx7InBhdGgiOiJmb250L2ZqYWxsYS1vbmUtNDAwLndvZmYiLCJyb290X2hhc2giOiJfUktQQ1JXcXJNQWtXVEhKa01adGRKcHRIVXUyNVVFRXByblY5cElkeVdNIn0seyJwYXRoIjoiZm9udC9mamFsbGEtb25lLTQwMC53b2ZmMiIsInJvb3RfaGFzaCI6IkotNUhqbUZOMUtOU0pqYnNGMEpJbnZfdW5pWjlkQ3NiejEyN2x4a0dyY2sifSx7InBhdGgiOiJmb250L29wZW4tc2Fucy00MDAudHRmIiwicm9vdF9oYXNoIjoiN1psSG9hTmJrQmowb1RlQW5mX0pLTkR3dm9lbEQyVzdhQjVPM2xKY3lBbyJ9LHsicGF0aCI6ImZvbnQvb3Blbi1zYW5zLTQwMC53b2ZmIiwicm9vdF9oYXNoIjoiVGdJaEhWU0ZmenczcnUwdi1iRFNac0plMlp2TTFTcUdmT1pGSzFCbzQ3YyJ9LHsicGF0aCI6ImZvbnQvb3Blbi1zYW5zLTQwMC53b2ZmMiIsInJvb3RfaGFzaCI6IkNDVmZrYjVZd3JwQ1k4QVBIZkZrRmF0a1U0b1R6bzdpM1BoYlMwWUZWd2cifSx7InBhdGgiOiJpY29uL2Zhdmljb24uc3ZnIiwicm9vdF9oYXNoIjoicGlxcGt6X0FaQmNqU0pJVW1SenRLOTh2U0NneGdKSWhTS2dkYmRVQ2JGayJ9LHsicGF0aCI6Imljb24vaWNvbi0xMjgucG5nIiwicm9vdF9oYXNoIjoieDRmWHc2NlBkN0djb1I2a2Q2d3cwUXNlUG1PSm4wNFZJRE1ncmlKb3ZGcyJ9LHsicGF0aCI6Imljb24vaWNvbi0xNi5wbmciLCJyb290X2hhc2giOiIwWUgzY1AwdG80b3VuWVd5MS1kSHZDWVdxRXZRWDVDSmxSblo0ZV8wSHJNIn0seyJwYXRoIjoiaWNvbi9pY29uLTQ4LnBuZyIsInJvb3RfaGFzaCI6InRFT1RBSUtXMEwxcU12UUUtUEdRcGdUS0ZGekJ0bTc4M3NHcEZOSTJEV2MifSx7InBhdGgiOiJpY29uL2ljb24tNTEyLnBuZyIsInJvb3RfaGFzaCI6ImV6ZnRfZHZfV3Z5WDhyWmlINm1NR2Y3dTNsSmxYa25IeTJVUjhCZDlyeEUifSx7InBhdGgiOiJpY29uL2ljb24tNTEyLnN2ZyIsInJvb3RfaGFzaCI6IkMxM0pKV0VyTF9DQmdRQUU0QXRvdldybVB5M3NNV3pwWVhqOE1ic0hMSXMifSx7InBhdGgiOiJpbmRleC4wOTE1M2FiZGJhYTc5MWZhNGYwZS5qcyIsInJvb3RfaGFzaCI6IjRlWG5XZFgyMlgtNWJKMmxJaE95Yl9qTHh4N2liUzBORlVUb080Y3ViVmcifSx7InBhdGgiOiJpbmRleC40MWIyZDJhOGNlZTg0NmIwMzJiNS5jc3MiLCJyb290X2hhc2giOiJxTWpmTHd1SEdXeEFUS1VrQTNaT2x0VS1YSWNXZXZZRlQwX3JhMThtN25ZIn0seyJwYXRoIjoiaW5kZXguaHRtbCIsInJvb3RfaGFzaCI6IkQ1QVhyemhJZ2FOWDJXOGdHbjFuVE5aVzVaejk1c1pyVEZ6M2FjQWtaZmMifSx7InBhdGgiOiJpbml0aWFsQmFja2dyb3VuZC5qcyIsInJvb3RfaGFzaCI6ImdUOEdrcTR0VmwwS3JJRHpaVmpEbDR6VHZCOXhJQWZya0ZIbEVkM05hdTQifSx7InBhdGgiOiJtYW5pZmVzdC5qc29uIiwicm9vdF9oYXNoIjoiZUloOXFCVG5BRVFEX1RjZkRQSkxndmNiZDlhNFJMTGFkT1R6b1JvUXlnZyJ9XSwiZm9ybWF0IjoidHJlZWhhc2giLCJoYXNoX2Jsb2NrX3NpemUiOjQwOTZ9XSwiaXRlbV9pZCI6ImhkcGNhZGlnamtiY3BubGNwYmNvaHBhZmlhZWZhbmtpIiwiaXRlbV92ZXJzaW9uIjoiNy4zLjAiLCJwcm90b2NvbF92ZXJzaW9uIjoxfQ","signatures":[{"header":{"kid":"publisher"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"AH2eEYBozWVLmNI8-mzd6t3CG_8lLznCJTlaal18SKD2gZsZJYuo8TMYqRAcNzeEP5yuOK7LO0ubtAdnMlLeHa4iz0Bllrbm6f3OOprPEhRk79HZOJ5tSrhsXLJAwREeANKDkj3mFYY8LahCQHGgy7kGdFMr-CtVEUq6ERNa7_NdF7sPZp5QAUgztaryarFGLWLz5w6q3CtccgAKlDLL7AFypzkonZ__obVGxSVlTx-BbIft6w-j13kpzId1hxVTqOCqMKAz_enT47TQ9O-RWKZajhOBLSF1vK1WyycARsEf2T5haihJx-RxBc6SKXdihCdpmjI5Hg_O3RywYEWkjw"},{"header":{"kid":"webstore"},"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"WROLbS0lyADKb3zzsn15iCoJNTuclaOHwAPkQTybiG4xwsYiFHMihQ5gzZmmLuj_HneVaFNZ7UFjNGMTsQPXqIQ9greSv4AnyODgg7aZgOm4Zu15AW952z1JOTBxoQv-ethMGBfCCGobAnIm8a9-iDP2CA43EBgvIdxecl13efu203XjEa2cXhy9UhToY35ZJOf9Yp5KVJ6UvQAUsazlQyRxpL7xdNB9xfHnI6zesuZCu5FXqvtCN4lBc-u3cnTNmz6D-XJp22lOeEiX5r_GQac23cLjMFjXf18sUkMT5iVIQzYxojgtBDVydaRnuqs2naDt2admH_7GaTYDKJ27NQ"}]}}]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,31 @@
<svg width="16" height="16" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
<style>
.cross {
fill: #ffffff;
}
.circle {
fill: #000000;
}
@media (prefers-color-scheme: light) {
.cross {
fill: #ffffff;
}
.circle {
fill: #000000;
}
}
@media (prefers-color-scheme: dark) {
.cross {
fill: #000000;
}
.circle {
fill: #ffffff;
}
}
</style>
<circle cx="8" cy="8" r="8" class="circle"/>
<path d="M11.6875 7H4.3125C4.13991 7 4 7.13991 4 7.3125V8.6875C4 8.86009 4.13991 9 4.3125 9H11.6875C11.8601 9 12 8.86009 12 8.6875V7.3125C12 7.13991 11.8601 7 11.6875 7Z" class="cross"/>
<path d="M8.6875 4H7.3125C7.13991 4 7 4.13991 7 4.3125V11.6875C7 11.8601 7.13991 12 7.3125 12H8.6875C8.86009 12 9 11.8601 9 11.6875V4.3125C9 4.13991 8.86009 4 8.6875 4Z" class="cross"/>
</svg>

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@@ -0,0 +1,31 @@
<svg viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg">
<style>
.cross {
fill: #939BAE;
}
.circle {
fill: #252931;
}
@media (prefers-color-scheme: light) {
.cross {
fill: #939BAE;
}
.circle {
fill: #252931;
}
}
@media (prefers-color-scheme: dark) {
.cross {
fill: #252931;
}
.circle {
fill: #939BAE;
}
}
</style>
<circle cx="256" cy="256" r="256" class="circle"/>
<path d="M374 224H138C132.477 224 128 228.477 128 234V278C128 283.523 132.477 288 138 288H374C379.523 288 384 283.523 384 278V234C384 228.477 379.523 224 374 224Z" class="cross"/>
<path d="M278 128H234C228.477 128 224 132.477 224 138V374C224 379.523 228.477 384 234 384H278C283.523 384 288 379.523 288 374V138C288 132.477 283.523 128 278 128Z" class="cross"/>
</svg>

After

Width:  |  Height:  |  Size: 888 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"><title>New Tab</title><link rel="icon" type="image/svg+xml" class="favicon" href="icon/favicon.svg"/><style media="screen">html,body {background-color: rgb(0, 0, 0);}@media (prefers-color-scheme: dark) {html,body {background-color: rgb(0, 0, 0);}}@media (prefers-color-scheme: light) {html,body {background-color: rgb(255, 255, 255);}}</style><script src="initialBackground.js" async></script><script defer="defer" src="index.09153abdbaa791fa4f0e.js"></script><link href="index.41b2d2a8cee846b032b5.css" rel="stylesheet"></head><body></body></html>

View File

@@ -0,0 +1 @@
if(localStorage.getItem("nightTabStyle")){const e=document.createElement("style");switch(e.type="text/css",e.media="screen",localStorage.getItem("nightTabStyle")){case"light":e.innerHTML="html, body {background-color: rgb(255, 255, 255);}";break;case"dark":e.innerHTML="html, body {background-color: rgb(0, 0, 0);}"}document.querySelector("head").appendChild(e)}

View File

@@ -0,0 +1,18 @@
{
"update_url": "https://clients2.google.com/service/update2/crx",
"name": "nightTab",
"short_name": "nightTab",
"description": "A neutral new tab page accented with a chosen colour. Customise the layout, style, background and bookmarks in nightTab.",
"version": "7.3.0",
"manifest_version": 2,
"chrome_url_overrides": {
"newtab": "index.html"
},
"icons": {
"16": "icon/icon-16.png",
"48": "icon/icon-48.png",
"128": "icon/icon-128.png",
"512": "icon/icon-512.png"
}
}

31
webview2/MyStart.csproj Normal file
View File

@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AssemblyName>MyStart</AssemblyName>
<RootNamespace>MyStart</RootNamespace>
<ApplicationIcon>app.ico</ApplicationIcon>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3485.44" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="app-index.html" />
<EmbeddedResource Include="app.ico" />
</ItemGroup>
</Project>

239
webview2/Program.cs Normal file
View File

@@ -0,0 +1,239 @@
using System.Reflection;
using System.Text.Json;
using Microsoft.Win32;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
namespace MyStart;
static class Program
{
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
bool minimized = args.Any(a =>
a.Equals("--minimized", StringComparison.OrdinalIgnoreCase) ||
a.Equals("--min", StringComparison.OrdinalIgnoreCase) ||
a.Equals("--autostart", StringComparison.OrdinalIgnoreCase));
Application.Run(new MainForm(minimized));
}
}
class MainForm : Form
{
private readonly WebView2 _web = new() { Dock = DockStyle.Fill };
private const string Host = "mystart.local";
private bool _pendingMaximize;
public MainForm(bool startMinimized = false)
{
Text = "MyStart";
StartPosition = FormStartPosition.CenterScreen;
Width = 1280;
Height = 800;
ShowInTaskbar = true;
BackColor = System.Drawing.Color.Black;
// No title bar / border. Close with Alt+F4, minimize via the taskbar button.
FormBorderStyle = FormBorderStyle.None;
if (startMinimized)
{
// Autostart: sit minimized on the taskbar; maximize on first open.
WindowState = FormWindowState.Minimized;
_pendingMaximize = true;
Resize += (_, _) =>
{
if (_pendingMaximize && WindowState != FormWindowState.Minimized)
{
_pendingMaximize = false;
WindowState = FormWindowState.Maximized;
}
};
}
else
{
WindowState = FormWindowState.Maximized;
}
try
{
var asm = Assembly.GetExecutingAssembly();
var icoName = asm.GetManifestResourceNames()
.FirstOrDefault(n => n.EndsWith("app.ico", StringComparison.OrdinalIgnoreCase));
if (icoName != null)
{
using var s = asm.GetManifestResourceStream(icoName);
if (s != null) Icon = new Icon(s);
}
}
catch { /* icon optional */ }
Controls.Add(_web);
Shown += async (_, _) => await InitAsync();
}
// Keep a borderless maximized window from covering the taskbar.
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
MaximizedBounds = Screen.FromHandle(Handle).WorkingArea;
}
private async Task InitAsync()
{
// Persistent data dir -> localStorage (settings/bookmarks) survive across runs
// and independent of where the .exe lives.
string dataDir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"MyStart");
Directory.CreateDirectory(dataDir);
var env = await CoreWebView2Environment.CreateAsync(null, dataDir);
await _web.EnsureCoreWebView2Async(env);
// Extract the embedded app to a fixed folder, served via a stable origin.
string appDir = Path.Combine(dataDir, "app");
Directory.CreateDirectory(appDir);
string htmlPath = Path.Combine(appDir, "index.html");
var asm = Assembly.GetExecutingAssembly();
string resName = asm.GetManifestResourceNames()
.First(n => n.EndsWith("app-index.html", StringComparison.OrdinalIgnoreCase));
await using (var res = asm.GetManifestResourceStream(resName)!)
await using (var file = File.Create(htmlPath))
await res.CopyToAsync(file);
var core = _web.CoreWebView2;
core.SetVirtualHostNameToFolderMapping(Host, appDir, CoreWebView2HostResourceAccessKind.Allow);
core.Settings.IsStatusBarEnabled = false;
core.Settings.AreDefaultContextMenusEnabled = true;
core.Settings.IsWebMessageEnabled = true;
// Autostart toggle from the in-app "MyStart" info page.
core.WebMessageReceived += (_, e) =>
{
try
{
using var doc = JsonDocument.Parse(e.WebMessageAsJson);
var root = doc.RootElement;
if (!root.TryGetProperty("type", out var t)) return;
switch (t.GetString())
{
case "autostart-get":
PostAutostartState();
break;
case "autostart-set":
bool on = root.TryGetProperty("value", out var v) &&
v.ValueKind == JsonValueKind.True;
SetAutostart(on);
PostAutostartState();
break;
case "window-drag":
StartWindowDrag();
break;
case "window-min":
WindowState = FormWindowState.Minimized;
break;
case "window-max":
WindowState = WindowState == FormWindowState.Maximized
? FormWindowState.Normal : FormWindowState.Maximized;
break;
case "window-close":
Close();
break;
}
}
catch { /* ignore malformed messages */ }
};
// Bookmark links that open a new window -> user's default browser.
core.NewWindowRequested += (_, e) =>
{
e.Handled = true;
OpenExternal(e.Uri);
};
// Same-tab clicks to external sites -> default browser, keep the app loaded.
core.NavigationStarting += (_, e) =>
{
var uri = e.Uri ?? string.Empty;
if (uri.StartsWith("https://" + Host, StringComparison.OrdinalIgnoreCase)) return; // internal
if (uri.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
uri.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
{
e.Cancel = true;
OpenExternal(uri);
}
};
core.Navigate("https://" + Host + "/index.html");
}
// --- Autostart (per-user HKCU Run key, points at THIS exe with --minimized) ---
private const string RunKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
private const string RunValueName = "MyStart";
private static string ExePath => Environment.ProcessPath ?? Application.ExecutablePath;
private static bool IsAutostartEnabled()
{
try
{
using var k = Registry.CurrentUser.OpenSubKey(RunKeyPath, false);
return k?.GetValue(RunValueName) is string v && v.Length > 0;
}
catch { return false; }
}
private static void SetAutostart(bool on)
{
try
{
using var k = Registry.CurrentUser.OpenSubKey(RunKeyPath, true)
?? Registry.CurrentUser.CreateSubKey(RunKeyPath, true);
if (k == null) return;
if (on) k.SetValue(RunValueName, "\"" + ExePath + "\" --minimized");
else if (k.GetValue(RunValueName) != null) k.DeleteValue(RunValueName, false);
}
catch { /* ignore */ }
}
private void PostAutostartState()
{
var json = "{\"type\":\"autostart\",\"enabled\":" +
(IsAutostartEnabled() ? "true" : "false") + "}";
try { _web.CoreWebView2.PostWebMessageAsJson(json); } catch { }
}
// --- Free window drag for the borderless window (page sends "window-drag"
// on grip mousedown / Alt+drag; we hand off to the native move loop). ---
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool ReleaseCapture();
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
private const int WM_NCLBUTTONDOWN = 0xA1;
private const int HTCAPTION = 0x2;
private void StartWindowDrag()
{
// A maximized window can't be moved -> restore first, centred under cursor-ish.
if (WindowState == FormWindowState.Maximized)
WindowState = FormWindowState.Normal;
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, (IntPtr)HTCAPTION, IntPtr.Zero);
}
private static void OpenExternal(string uri)
{
try
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = uri,
UseShellExecute = true
});
}
catch { /* ignore */ }
}
}

95
webview2/app-index.html Normal file

File diff suppressed because one or more lines are too long

BIN
webview2/app.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
webview2/build/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB