hmgr 0.0.44 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/zustand-json.js +2 -1
- package/dist/aenderungen.json +6 -0
- package/dist/cli/hilfe.js +10 -3
- package/dist/cli/main.js +35 -10
- package/dist/gui/main.js +83 -15
- package/dist/gui/preload.cjs +2 -0
- package/dist/gui/renderer/renderer.js +338 -92
- package/dist/gui/renderer/styles.css +8 -0
- package/dist/kern/anwendungsfaelle.js +131 -45
- package/package.json +1 -1
|
@@ -745,7 +745,7 @@
|
|
|
745
745
|
}
|
|
746
746
|
|
|
747
747
|
/** Eine Zeile der Link-Tabelle. `bundle` gesetzt heißt: die Zeile steht in einer Bundle-Gruppe
|
|
748
|
-
(E69), das Entfernen
|
|
748
|
+
(E69), das Entfernen nimmt den Skill dort aus dem Bundle heraus und der Dialog sagt es (E114). */
|
|
749
749
|
function linkZeile(ei, z, bundle) {
|
|
750
750
|
var name = ei.art === 'link' ? ei.link.name : ei.name;
|
|
751
751
|
var li = e('li');
|
|
@@ -801,63 +801,156 @@
|
|
|
801
801
|
return li;
|
|
802
802
|
}
|
|
803
803
|
|
|
804
|
-
/**
|
|
805
|
-
|
|
806
|
-
function
|
|
804
|
+
/** Alle Mitglieder eines installierten Bundles in einem Ziel (E114 L3): verlinkte und nicht
|
|
805
|
+
verlinkte, aus dem Zustand — ohne die Definition, die Gruppe steht auch bei fehlender Quelle. */
|
|
806
|
+
function bundleAlleMitglieder(b) {
|
|
807
|
+
return b.skills.concat(b.nichtVerlinkt || []);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/** Skill zu einem Mitglied einer Definition aus dem Skill-Katalog (E114 L1): gleiche Quelle, gleicher
|
|
811
|
+
Pfad. null, wenn die Quelle (noch) nicht eingerichtet oder nicht lesbar ist. */
|
|
812
|
+
function bundleMitgliedSkill(m) {
|
|
813
|
+
return SKILLS.filter(function (s) { return s.quelleSchluessel === m.quelleSchluessel && s.pfad === m.pfad; })[0] || null;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/** Skill eines nicht verlinkten Mitglieds über seinen Namen, gesucht unter den Mitgliedern der
|
|
817
|
+
Definition (Name plus Quelle des Bundles). null, wenn sich das nicht auflösen lässt. */
|
|
818
|
+
function bundleSkillNachName(b, name) {
|
|
819
|
+
var katalog = BUNDLES.filter(function (k) { return k.name === b.name && k.quelleText === b.quelleText; })[0];
|
|
820
|
+
if (!katalog) return null;
|
|
821
|
+
for (var i = 0; i < katalog.mitglieder.length; i++) {
|
|
822
|
+
var skill = bundleMitgliedSkill(katalog.mitglieder[i]);
|
|
823
|
+
if (skill && skill.name === name) return skill;
|
|
824
|
+
}
|
|
825
|
+
return null;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/** Vervollständigen (E114 L4, `aufnehmen` 'alle') oder Wieder verlinken (L3, Namensliste) eines
|
|
829
|
+
Bundles in den genannten Zielen. Ein Fehlschlag in einem Ziel hält die übrigen nicht auf,
|
|
830
|
+
`rufe` meldet ihn selbst. */
|
|
831
|
+
async function bundleAufnehmen(b, ziele, aufnehmen) {
|
|
832
|
+
var gelegt = 0;
|
|
833
|
+
var gescheitert = 0;
|
|
834
|
+
for (var i = 0; i < ziele.length; i++) {
|
|
835
|
+
var ziel = ziele[i];
|
|
836
|
+
try {
|
|
837
|
+
var ergebnis = await rufe(function () {
|
|
838
|
+
return window.hmgr.bundleAbgleichen({
|
|
839
|
+
bundle: b.name, quelleText: b.quelleText, harness: ziel.harness, ort: ziel.ort, aufnehmen: aufnehmen,
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
gelegt += ergebnis.gelegt.length;
|
|
843
|
+
} catch (fehler) {
|
|
844
|
+
gescheitert++;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
await ladeAlles();
|
|
848
|
+
if (gescheitert === 0) melde('Bundle ' + b.name + ': ' + zahlwort(gelegt, 'Link', 'Links') + ' gelegt.');
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Aufklappzustand der Bundle-Gruppen (E114 L1), überlebt den Neuaufbau durch ladeAlles wie
|
|
852
|
+
// SKILL_OFFEN. Zu Beginn sind die Gruppen zugeklappt.
|
|
853
|
+
var BUNDLE_OFFEN = {};
|
|
854
|
+
var bundleKoerperNr = 0;
|
|
855
|
+
|
|
856
|
+
/** Rahmen einer Bundle-Gruppe (E69, E114 L1/L3/L4): Kopf mit Name, Quelle, „x von N Skills",
|
|
857
|
+
„Vervollständigen", wenn etwas fehlt, und „Entfernen" für das Ganze; darunter aufklappbar die
|
|
858
|
+
Zeilen aller Mitglieder. `harnesse` nur unter „Alle" (Harness-Zeichen am Kopf, E95). */
|
|
859
|
+
function bundleRahmen(b, harnesse, verlinkt, gesamt, ziele, zeilen, entfernen, schluessel) {
|
|
807
860
|
var gruppe = e('div', 'bundlegruppe');
|
|
808
861
|
var kopf = e('div', 'bundlekopf');
|
|
809
862
|
var titel = e('span', 'bundletitel');
|
|
863
|
+
if (harnesse) titel.appendChild(harnesseZeichenSammel(harnesse));
|
|
810
864
|
titel.appendChild(e('span', 'etikett', 'Bundle'));
|
|
811
865
|
titel.appendChild(e('b', 'bundlename', b.name));
|
|
812
866
|
kopf.appendChild(titel);
|
|
813
867
|
var quelleEl = e('span', 'mono bundlequelle', b.quelleName);
|
|
814
868
|
quelleEl.title = b.quelleText;
|
|
815
869
|
kopf.appendChild(quelleEl);
|
|
816
|
-
kopf.appendChild(e('span', 'bundlezahl',
|
|
870
|
+
kopf.appendChild(e('span', 'bundlezahl', verlinkt === gesamt
|
|
871
|
+
? zahlwort(gesamt, 'Skill', 'Skills')
|
|
872
|
+
: verlinkt + ' von ' + zahlwort(gesamt, 'Skill', 'Skills')));
|
|
873
|
+
var aktionen = e('span', 'bundleaktionen');
|
|
874
|
+
if (verlinkt < gesamt) {
|
|
875
|
+
var voll = e('button', 'knopf leise klein', 'Vervollständigen');
|
|
876
|
+
voll.type = 'button';
|
|
877
|
+
voll.setAttribute('aria-label', 'Bundle ' + b.name + ' vervollständigen: alle fehlenden Skills verlinken');
|
|
878
|
+
voll.addEventListener('click', function () { bundleAufnehmen(b, ziele, 'alle'); });
|
|
879
|
+
aktionen.appendChild(voll);
|
|
880
|
+
}
|
|
817
881
|
var weg = e('button', 'knopf leise klein', 'Entfernen');
|
|
818
882
|
weg.type = 'button';
|
|
819
|
-
weg.setAttribute('aria-label', 'Bundle ' + b.name + '
|
|
820
|
-
weg.addEventListener('click',
|
|
821
|
-
|
|
883
|
+
weg.setAttribute('aria-label', 'Bundle ' + b.name + ' entfernen');
|
|
884
|
+
weg.addEventListener('click', entfernen);
|
|
885
|
+
aktionen.appendChild(weg);
|
|
886
|
+
var offen = !!BUNDLE_OFFEN[schluessel];
|
|
887
|
+
var koerperId = 'bundlekoerper-' + bundleKoerperNr++;
|
|
888
|
+
var umschalter = e('button', 'aufklappknopf');
|
|
889
|
+
umschalter.type = 'button';
|
|
890
|
+
umschalter.setAttribute('aria-expanded', offen ? 'true' : 'false');
|
|
891
|
+
umschalter.setAttribute('aria-controls', koerperId);
|
|
892
|
+
umschalter.setAttribute('aria-label', 'Skills des Bundles ' + b.name + ' ein- oder ausklappen');
|
|
893
|
+
var pfeil = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
894
|
+
pfeil.setAttribute('viewBox', '0 0 16 16');
|
|
895
|
+
pfeil.setAttribute('class', 'akkordeonpfeil dunkel');
|
|
896
|
+
pfeil.setAttribute('aria-hidden', 'true');
|
|
897
|
+
pfeil.innerHTML = '<path d="M4 6.5 8 10.5 12 6.5"/>';
|
|
898
|
+
umschalter.appendChild(pfeil);
|
|
899
|
+
aktionen.appendChild(umschalter);
|
|
900
|
+
kopf.appendChild(aktionen);
|
|
822
901
|
gruppe.appendChild(kopf);
|
|
823
902
|
var ul = e('ul', 'linkliste');
|
|
824
|
-
|
|
903
|
+
ul.id = koerperId;
|
|
904
|
+
ul.hidden = !offen;
|
|
905
|
+
zeilen.forEach(function (li) { ul.appendChild(li); });
|
|
825
906
|
gruppe.appendChild(ul);
|
|
907
|
+
function schalte() {
|
|
908
|
+
offen = !offen;
|
|
909
|
+
BUNDLE_OFFEN[schluessel] = offen;
|
|
910
|
+
umschalter.setAttribute('aria-expanded', offen ? 'true' : 'false');
|
|
911
|
+
ul.hidden = !offen;
|
|
912
|
+
}
|
|
913
|
+
umschalter.addEventListener('click', schalte);
|
|
914
|
+
// Der Kopf schaltet mit, außer über seine Knöpfe (wie der Kopf einer Ziel-Karte).
|
|
915
|
+
kopf.addEventListener('click', function (ev) {
|
|
916
|
+
if (ev.target.closest('button, a') === null) schalte();
|
|
917
|
+
});
|
|
826
918
|
return gruppe;
|
|
827
919
|
}
|
|
828
920
|
|
|
829
|
-
/**
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
921
|
+
/** Zeile eines nicht verlinkten Mitglieds (E114 L3): blass, „nicht verlinkt", „Wieder verlinken".
|
|
922
|
+
`skill` aus dem Katalog oder null, wenn die Definition oder Quelle nicht lesbar ist. */
|
|
923
|
+
function nichtVerlinktZeile(name, skill, wiederVerlinken) {
|
|
924
|
+
var li = e('li', 'nichtverlinkt');
|
|
925
|
+
li.appendChild(e('span'));
|
|
926
|
+
li.appendChild(e('span', 'name', name));
|
|
927
|
+
if (skill) li.appendChild(wasZelle(skill));
|
|
928
|
+
else {
|
|
929
|
+
var feld = e('span', 'wasfeld');
|
|
930
|
+
feld.appendChild(e('span', 'was fehlt', 'Beschreibung nicht lesbar, die Quelle fehlt hier'));
|
|
931
|
+
li.appendChild(feld);
|
|
932
|
+
}
|
|
933
|
+
li.appendChild(e('span', 'quelle', 'nicht verlinkt'));
|
|
934
|
+
var knopf = e('button', 'knopf leise klein', 'Wieder verlinken');
|
|
935
|
+
knopf.type = 'button';
|
|
936
|
+
knopf.setAttribute('aria-label', name + ' wieder verlinken');
|
|
937
|
+
knopf.addEventListener('click', wiederVerlinken);
|
|
938
|
+
li.appendChild(knopf);
|
|
939
|
+
return li;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/** Ein installiertes Bundle unter dem Harness-Chip (E69, E114): alle Mitglieder in der Gruppe,
|
|
943
|
+
verlinkte als gewöhnliche Link-Zeilen, nicht verlinkte blass mit „Wieder verlinken". */
|
|
944
|
+
function bundleGruppe(b, z, eintraege) {
|
|
945
|
+
var zeilen = eintraege.map(function (ei) { return linkZeile(ei, z, b); });
|
|
946
|
+
(b.nichtVerlinkt || []).slice().sort(function (x, y) { return x.localeCompare(y, 'de'); }).forEach(function (name) {
|
|
947
|
+
zeilen.push(nichtVerlinktZeile(name, bundleSkillNachName(b, name), function () {
|
|
948
|
+
bundleAufnehmen(b, [z.ziel], [name]);
|
|
949
|
+
}));
|
|
857
950
|
});
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
951
|
+
return bundleRahmen(b, null, b.skills.length, bundleAlleMitglieder(b).length, [z.ziel], zeilen, function () {
|
|
952
|
+
frageBundleEntfernen(b, z.ziel);
|
|
953
|
+
}, 'ziel\u0000' + zielKey(z.ziel) + '\u0000' + b.name + '\u0000' + b.quelleText);
|
|
861
954
|
}
|
|
862
955
|
|
|
863
956
|
function linkTeil(z) {
|
|
@@ -881,8 +974,13 @@
|
|
|
881
974
|
}
|
|
882
975
|
}
|
|
883
976
|
|
|
977
|
+
// Bundles zuerst (E69): sie stehen als Gruppe über den Einzel-Zeilen, ihre Mitglieder liegen
|
|
978
|
+
// in der Gruppe statt in der allgemeinen Liste. Was zum Bundle gehört, sagt der Kern. Eine Gruppe
|
|
979
|
+
// steht auch, wenn kein Mitglied mehr verlinkt ist („0 von N", E114).
|
|
980
|
+
var bundles = (z.bundles || []).filter(function (b) { return bundleAlleMitglieder(b).length > 0; });
|
|
981
|
+
|
|
884
982
|
var fussContainer;
|
|
885
|
-
if (eigene.length === 0) {
|
|
983
|
+
if (eigene.length === 0 && bundles.length === 0) {
|
|
886
984
|
var leer = e('div', 'leerzeile');
|
|
887
985
|
leer.appendChild(e('p', 'ohne', 'Hier liegt noch nichts.'));
|
|
888
986
|
teil.appendChild(leer);
|
|
@@ -898,9 +996,6 @@
|
|
|
898
996
|
kopf.appendChild(e('span'));
|
|
899
997
|
teil.appendChild(kopf);
|
|
900
998
|
|
|
901
|
-
// Bundles zuerst (E69): sie stehen als Gruppe über den Einzel-Zeilen, ihre Mitglieder liegen
|
|
902
|
-
// in der Gruppe statt in der allgemeinen Liste. Was zum Bundle gehört, sagt der Kern.
|
|
903
|
-
var bundles = (z.bundles || []).filter(function (b) { return b.skills.length > 0; });
|
|
904
999
|
var bundleVon = {};
|
|
905
1000
|
bundles.forEach(function (b) { b.skills.forEach(function (n) { bundleVon[n] = b; }); });
|
|
906
1001
|
bundles
|
|
@@ -931,7 +1026,7 @@
|
|
|
931
1026
|
|
|
932
1027
|
// Ohne eigene Links (leer-Fall) steht der MCP-Abschnitt hinter der Leerzeile, die dort schon den
|
|
933
1028
|
// Kartenfuß bildet (Nachricht + Knöpfe in einer Zeile, wie überall sonst im leeren Zustand).
|
|
934
|
-
if (eigene.length === 0) {
|
|
1029
|
+
if (eigene.length === 0 && bundles.length === 0) {
|
|
935
1030
|
var mcpAbschnOhneTabelle = mcpAbschnitt(z.ziel);
|
|
936
1031
|
if (mcpAbschnOhneTabelle) teil.appendChild(mcpAbschnOhneTabelle);
|
|
937
1032
|
}
|
|
@@ -1220,7 +1315,37 @@
|
|
|
1220
1315
|
verzMcpZiele.push(z);
|
|
1221
1316
|
});
|
|
1222
1317
|
|
|
1223
|
-
|
|
1318
|
+
// Bundles unter „Alle" (E69, E95, E114 L1): eine aufklappbare Gruppe je Bundle, wie unter dem
|
|
1319
|
+
// Harness-Chip, aber über alle Harnesses am Ort zusammengefasst: Schlüssel ist Name plus Quelle,
|
|
1320
|
+
// gleichnamige Bundles aus zwei Quellen bleiben getrennt. Eine Gruppe steht auch, wenn kein
|
|
1321
|
+
// Mitglied mehr verlinkt ist („0 von N").
|
|
1322
|
+
var bundleGruppen = {}, bundleReihenfolge = [];
|
|
1323
|
+
teile.forEach(function (z) {
|
|
1324
|
+
(z.bundles || [])
|
|
1325
|
+
.filter(function (b) { return bundleAlleMitglieder(b).length > 0; })
|
|
1326
|
+
.forEach(function (b) {
|
|
1327
|
+
var schluessel = b.name + '\u0000' + b.quelleText;
|
|
1328
|
+
if (!bundleGruppen[schluessel]) { bundleGruppen[schluessel] = []; bundleReihenfolge.push(schluessel); }
|
|
1329
|
+
bundleGruppen[schluessel].push({ b: b, z: z });
|
|
1330
|
+
});
|
|
1331
|
+
});
|
|
1332
|
+
// Eine Tabellenzeile geht in einer Gruppe auf, wenn ihr Name in JEDEM Harness der Zeile ein
|
|
1333
|
+
// verlinktes Mitglied dieses Bundles ist — dann steht sie nur in der Gruppe, nicht zusätzlich in
|
|
1334
|
+
// der Tabelle (E114 L1). Hängt derselbe Skill in einem Harness als Einzel-Link, bleibt die
|
|
1335
|
+
// Zeile in der Tabelle. Die Zählung im Kartenkopf (E71) bleibt davon unberührt.
|
|
1336
|
+
var zeileInGruppe = {};
|
|
1337
|
+
reihenfolge.forEach(function (key) {
|
|
1338
|
+
var row = zeilen[key];
|
|
1339
|
+
bundleReihenfolge.forEach(function (gk) {
|
|
1340
|
+
if (zeileInGruppe[key]) return;
|
|
1341
|
+
var ganz = row.teile.every(function (z) {
|
|
1342
|
+
return bundleGruppen[gk].some(function (t) { return t.z === z && t.b.skills.indexOf(row.name) > -1; });
|
|
1343
|
+
});
|
|
1344
|
+
if (ganz) zeileInGruppe[key] = gk;
|
|
1345
|
+
});
|
|
1346
|
+
});
|
|
1347
|
+
|
|
1348
|
+
if (reihenfolge.length === 0 && bundleReihenfolge.length === 0) {
|
|
1224
1349
|
var leer = e('div', 'leerzeile');
|
|
1225
1350
|
leer.appendChild(e('p', 'ohne', 'Hier liegt noch nichts.'));
|
|
1226
1351
|
leer.appendChild(alleSkillsKnopf(pfad, teile));
|
|
@@ -1236,27 +1361,6 @@
|
|
|
1236
1361
|
return teil;
|
|
1237
1362
|
}
|
|
1238
1363
|
|
|
1239
|
-
// Bundles unter „Alle" (E69): die Zeilen bleiben nach Name und Quelle gebündelt (E53), ein
|
|
1240
|
-
// Bundle gehört aber zu genau einem Harness — deshalb hier ein Streifen je Bundle mit seinem
|
|
1241
|
-
// Harness-Zeichen statt einer Umgruppierung der Tabelle. Unter dem Harness-Chip zeigt linkTeil
|
|
1242
|
-
// die volle Gruppe über den Zeilen.
|
|
1243
|
-
// Ein Bundle, das in mehreren Harnesses am selben Ort liegt, ist hier ein Streifen (E95), wie
|
|
1244
|
-
// die Skill-Zeilen: Schlüssel ist Name plus Quelle, gleichnamige Bundles aus zwei Quellen
|
|
1245
|
-
// bleiben getrennt.
|
|
1246
|
-
var bundleGruppen = {}, bundleReihenfolge = [];
|
|
1247
|
-
teile.forEach(function (z) {
|
|
1248
|
-
(z.bundles || [])
|
|
1249
|
-
.filter(function (b) { return b.skills.length > 0; })
|
|
1250
|
-
.forEach(function (b) {
|
|
1251
|
-
var schluessel = b.name + '\u0000' + b.quelleText;
|
|
1252
|
-
if (!bundleGruppen[schluessel]) { bundleGruppen[schluessel] = []; bundleReihenfolge.push(schluessel); }
|
|
1253
|
-
bundleGruppen[schluessel].push({ b: b, z: z });
|
|
1254
|
-
});
|
|
1255
|
-
});
|
|
1256
|
-
bundleReihenfolge
|
|
1257
|
-
.sort(function (a, b) { return bundleGruppen[a][0].b.name.localeCompare(bundleGruppen[b][0].b.name, 'de'); })
|
|
1258
|
-
.forEach(function (k) { teil.appendChild(bundleStreifen(bundleGruppen[k])); });
|
|
1259
|
-
|
|
1260
1364
|
var kopf = e('div', 'linkkopf');
|
|
1261
1365
|
kopf.appendChild(e('span'));
|
|
1262
1366
|
kopf.appendChild(e('span', 'etikett', 'Skill'));
|
|
@@ -1265,16 +1369,17 @@
|
|
|
1265
1369
|
kopf.appendChild(e('span'));
|
|
1266
1370
|
teil.appendChild(kopf);
|
|
1267
1371
|
|
|
1268
|
-
var
|
|
1269
|
-
reihenfolge
|
|
1372
|
+
var sortiert = reihenfolge
|
|
1270
1373
|
.slice()
|
|
1271
1374
|
.sort(function (ka, kb) {
|
|
1272
1375
|
var a = zeilen[ka], b = zeilen[kb];
|
|
1273
1376
|
if (a.defekt !== b.defekt) return a.defekt ? -1 : 1;
|
|
1274
1377
|
return a.name.localeCompare(b.name, 'de');
|
|
1275
|
-
})
|
|
1276
|
-
|
|
1277
|
-
|
|
1378
|
+
});
|
|
1379
|
+
|
|
1380
|
+
/** Eine gebündelte Zeile unter „Alle" (E53). `bundleName` gesetzt: sie steht in einer
|
|
1381
|
+
Bundle-Gruppe, das Entfernen nimmt den Skill dort heraus (E114). */
|
|
1382
|
+
function alleZeile(row, bundleName) {
|
|
1278
1383
|
var harnesse = [];
|
|
1279
1384
|
row.teile.forEach(function (z) { if (harnesse.indexOf(z.ziel.harness) === -1) harnesse.push(z.ziel.harness); });
|
|
1280
1385
|
harnesse.sort(function (a, b) { return harnessName(a).localeCompare(harnessName(b), 'de'); });
|
|
@@ -1325,14 +1430,64 @@
|
|
|
1325
1430
|
// Namens nebeneinander, sobald ein Skill je Harness aus verschiedener Quelle hängt.
|
|
1326
1431
|
weg.setAttribute('aria-label', 'Link auf ' + row.name + ' in '
|
|
1327
1432
|
+ entfernbar.map(function (z) { return harnessName(z.ziel.harness); }).join(', ') + ' entfernen');
|
|
1328
|
-
weg.addEventListener('click', function () {
|
|
1433
|
+
weg.addEventListener('click', function () {
|
|
1434
|
+
frageEntfernenAlle(row.name, pfad, entfernbar, nichtEntfernbar, bundleName);
|
|
1435
|
+
});
|
|
1329
1436
|
li.appendChild(weg);
|
|
1330
1437
|
} else {
|
|
1331
1438
|
li.appendChild(e('span', 'kein-weg', 'nur über Plugin „' + pluginNamen.join('“, „') + '“'));
|
|
1332
1439
|
}
|
|
1333
|
-
|
|
1440
|
+
return li;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// Erst die Bundle-Gruppen, darunter die übrigen Zeilen (wie unter dem Harness-Chip, E69).
|
|
1444
|
+
bundleReihenfolge
|
|
1445
|
+
.sort(function (a, b) { return bundleGruppen[a][0].b.name.localeCompare(bundleGruppen[b][0].b.name, 'de'); })
|
|
1446
|
+
.forEach(function (gk) {
|
|
1447
|
+
var treffer = bundleGruppen[gk];
|
|
1448
|
+
var b = treffer[0].b;
|
|
1449
|
+
var harnesse = [];
|
|
1450
|
+
treffer.forEach(function (t) { if (harnesse.indexOf(t.z.ziel.harness) === -1) harnesse.push(t.z.ziel.harness); });
|
|
1451
|
+
harnesse.sort(function (x, y) { return harnessName(x).localeCompare(harnessName(y), 'de'); });
|
|
1452
|
+
// Mitglieder über alle Harnesses ohne Doppelte; verlinkt zählt, was in jedem Harness liegt.
|
|
1453
|
+
var mitglieder = [];
|
|
1454
|
+
treffer.forEach(function (t) {
|
|
1455
|
+
bundleAlleMitglieder(t.b).forEach(function (n) { if (mitglieder.indexOf(n) === -1) mitglieder.push(n); });
|
|
1456
|
+
});
|
|
1457
|
+
var ueberall = mitglieder.filter(function (n) {
|
|
1458
|
+
return treffer.every(function (t) { return t.b.skills.indexOf(n) > -1; });
|
|
1459
|
+
});
|
|
1460
|
+
var gruppenZeilen = sortiert
|
|
1461
|
+
.filter(function (key) { return zeileInGruppe[key] === gk; })
|
|
1462
|
+
.map(function (key) { return alleZeile(zeilen[key], b.name); });
|
|
1463
|
+
// Nirgends verlinkte Mitglieder als blasse Zeile; „Wieder verlinken" in jedem Harness, in
|
|
1464
|
+
// dem das Mitglied fehlt.
|
|
1465
|
+
mitglieder
|
|
1466
|
+
.filter(function (n) { return treffer.every(function (t) { return t.b.skills.indexOf(n) === -1; }); })
|
|
1467
|
+
.sort(function (x, y) { return x.localeCompare(y, 'de'); })
|
|
1468
|
+
.forEach(function (n) {
|
|
1469
|
+
gruppenZeilen.push(nichtVerlinktZeile(n, bundleSkillNachName(b, n), function () {
|
|
1470
|
+
bundleAufnehmen(b, treffer
|
|
1471
|
+
.filter(function (t) { return (t.b.nichtVerlinkt || []).indexOf(n) > -1; })
|
|
1472
|
+
.map(function (t) { return t.z.ziel; }), [n]);
|
|
1473
|
+
}));
|
|
1474
|
+
});
|
|
1475
|
+
var verlinkteNamen = [];
|
|
1476
|
+
treffer.forEach(function (t) {
|
|
1477
|
+
t.b.skills.forEach(function (n) { if (verlinkteNamen.indexOf(n) === -1) verlinkteNamen.push(n); });
|
|
1478
|
+
});
|
|
1479
|
+
teil.appendChild(bundleRahmen(b, harnesse, ueberall.length, mitglieder.length,
|
|
1480
|
+
treffer.map(function (t) { return t.z.ziel; }), gruppenZeilen, function () {
|
|
1481
|
+
if (treffer.length === 1) frageBundleEntfernen(b, treffer[0].z.ziel);
|
|
1482
|
+
else frageBundleEntfernenAlle(b.name, verlinkteNamen, treffer);
|
|
1483
|
+
}, 'verz\u0000' + pfad + '\u0000' + gk));
|
|
1334
1484
|
});
|
|
1335
|
-
|
|
1485
|
+
|
|
1486
|
+
var ul = e('ul', 'linkliste');
|
|
1487
|
+
sortiert
|
|
1488
|
+
.filter(function (key) { return !zeileInGruppe[key]; })
|
|
1489
|
+
.forEach(function (key) { ul.appendChild(alleZeile(zeilen[key], null)); });
|
|
1490
|
+
if (ul.childNodes.length > 0) teil.appendChild(ul);
|
|
1336
1491
|
|
|
1337
1492
|
// MCP-Abschnitt (E61-GUI-Nachtrag): auf Kartenebene unter „Alle", wie unter dem Harness-Chip,
|
|
1338
1493
|
// der an diesem Pfad MCP kann.
|
|
@@ -1638,28 +1793,42 @@
|
|
|
1638
1793
|
// entfernenKontext.eintraege: [{harness, ort}], immer eines bei frageEntfernen (Einzel-Ziel),
|
|
1639
1794
|
// mehrere bei frageEntfernenAlle (E53 Pkt. 2, „Alle"-Zeile über mehrere Harnesses).
|
|
1640
1795
|
var entfernenKontext = null;
|
|
1641
|
-
/**
|
|
1796
|
+
/** Satz für den Entfernen-Dialog einer Zeile in einer Bundle-Gruppe (E114 L2): das Bundle bleibt. */
|
|
1797
|
+
function herausnehmenSatz(bundleName) {
|
|
1798
|
+
return ' Der Skill wird damit aus dem Bundle „' + bundleName + '“ herausgenommen: das Bundle bleibt, '
|
|
1799
|
+
+ 'das Aktualisieren legt den Link nicht wieder an. „Wieder verlinken“ oder „Vervollständigen“ am Bundle holt ihn zurück.';
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
/** `bundleName` gesetzt heißt: der Link gehört zu einem Bundle, das Entfernen nimmt ihn dort
|
|
1803
|
+
heraus (E114, früher Zerbrechen nach E69). */
|
|
1642
1804
|
function frageEntfernen(name, ziel, bundleName) {
|
|
1643
1805
|
entfernenKontext = { art: 'link', name: name, eintraege: [{ harness: ziel.harness, ort: ziel.ort }] };
|
|
1644
1806
|
$('dx-titel').textContent = 'Link auf ' + name + ' entfernen?';
|
|
1645
1807
|
var text = 'Der Link in ' + zielTitel({ ziel: ziel }) + ' verschwindet. Der Checkout bleibt liegen, bis kein Link mehr darauf zeigt.';
|
|
1646
|
-
if (bundleName)
|
|
1647
|
-
text += ' Damit zerbricht das Bundle „' + bundleName + '“ hier: seine übrigen Links bleiben liegen, aber nicht mehr als Bundle.';
|
|
1648
|
-
}
|
|
1808
|
+
if (bundleName) text += herausnehmenSatz(bundleName);
|
|
1649
1809
|
$('dx-text').textContent = text;
|
|
1650
1810
|
zeige($('d-entfernen'));
|
|
1651
1811
|
}
|
|
1652
1812
|
|
|
1653
|
-
/**
|
|
1813
|
+
/** Zusatz für die Bundle-Dialoge (E114): was schon nicht mehr verlinkt ist, bleibt unberührt. */
|
|
1814
|
+
function nichtVerlinktSatz(namen) {
|
|
1815
|
+
return namen.length === 0 ? '' : ' Nicht verlinkt sind schon: ' + namen.join(', ') + '.';
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
/** Entfernen des ganzen Bundles an einem Ziel (E69, E114 L2): alle noch verlinkten Mitglieder auf
|
|
1819
|
+
einmal, auch nach Teil-Löschung. */
|
|
1654
1820
|
function frageBundleEntfernen(b, ziel) {
|
|
1655
1821
|
entfernenKontext = { art: 'bundle', bundle: b.name, ziele: [ziel] };
|
|
1656
1822
|
$('dx-titel').textContent = 'Bundle ' + b.name + ' entfernen?';
|
|
1657
|
-
$('dx-text').textContent =
|
|
1658
|
-
|
|
1823
|
+
$('dx-text').textContent = (b.skills.length === 0
|
|
1824
|
+
? 'Kein Link mehr da, aus ' + zielTitel({ ziel: ziel }) + ' verschwindet nur der Bundle-Verweis.'
|
|
1825
|
+
: zahlwort(b.skills.length, 'Link', 'Links') + ' aus ' + zielTitel({ ziel: ziel })
|
|
1826
|
+
+ ' verschwinden: ' + b.skills.join(', ') + '. Die Checkouts bleiben liegen, bis kein Link mehr darauf zeigt.')
|
|
1827
|
+
+ nichtVerlinktSatz(b.nichtVerlinkt || []);
|
|
1659
1828
|
zeige($('d-entfernen'));
|
|
1660
1829
|
}
|
|
1661
|
-
/** Entfernen eines Bundles in allen Harnesses
|
|
1662
|
-
|
|
1830
|
+
/** Entfernen eines Bundles in allen Harnesses seiner Gruppe unter „Alle" (E95): `treffer` je
|
|
1831
|
+
Harness {b, z}, der Dialog nennt die Harnesses mit ihrer Linkzahl und die verlinkten Mitglieder. */
|
|
1663
1832
|
function frageBundleEntfernenAlle(name, mitglieder, treffer) {
|
|
1664
1833
|
entfernenKontext = { art: 'bundle', bundle: name, ziele: treffer.map(function (t) { return t.z.ziel; }) };
|
|
1665
1834
|
var proHarness = treffer.map(function (t) {
|
|
@@ -1667,13 +1836,15 @@
|
|
|
1667
1836
|
});
|
|
1668
1837
|
$('dx-titel').textContent = 'Bundle ' + name + ' entfernen?';
|
|
1669
1838
|
$('dx-text').textContent = 'Das Bundle verschwindet in ' + treffer.length + ' Harnesses (' + proHarness.join(', ')
|
|
1670
|
-
+ '): ' + mitglieder.join(', ') + '.
|
|
1839
|
+
+ ')' + (mitglieder.length === 0 ? '.' : ': ' + mitglieder.join(', ') + '.')
|
|
1840
|
+
+ ' Die Checkouts bleiben liegen, bis kein Link mehr darauf zeigt.';
|
|
1671
1841
|
zeige($('d-entfernen'));
|
|
1672
1842
|
}
|
|
1673
1843
|
/** Entfernen einer „Alle"-Zeile (E53 Pkt. 2): entfernbareZiele sind die Ziele (voller z.ziel), in
|
|
1674
1844
|
denen der Link weg soll, nichtEntfernbareHarnesse die, in denen er nur über ein Plugin hängt
|
|
1675
|
-
und liegen bleibt. Der Dialog nennt beides.
|
|
1676
|
-
|
|
1845
|
+
und liegen bleibt. Der Dialog nennt beides. `bundleName` gesetzt: die Zeile steht in einer
|
|
1846
|
+
Bundle-Gruppe, der Skill wird dort herausgenommen (E114). */
|
|
1847
|
+
function frageEntfernenAlle(name, pfad, entfernbareZiele, nichtEntfernbareHarnesse, bundleName) {
|
|
1677
1848
|
entfernenKontext = {
|
|
1678
1849
|
art: 'link',
|
|
1679
1850
|
name: name,
|
|
@@ -1686,6 +1857,7 @@
|
|
|
1686
1857
|
text += ' In ' + nichtEntfernbareHarnesse.map(harnessName).join(', ') + ' bleibt er bestehen (nur über das Plugin).';
|
|
1687
1858
|
}
|
|
1688
1859
|
text += ' Der Checkout bleibt liegen, bis kein Link mehr darauf zeigt.';
|
|
1860
|
+
if (bundleName) text += herausnehmenSatz(bundleName);
|
|
1689
1861
|
$('dx-text').textContent = text;
|
|
1690
1862
|
zeige($('d-entfernen'));
|
|
1691
1863
|
}
|
|
@@ -2328,13 +2500,14 @@
|
|
|
2328
2500
|
var txt = e('span');
|
|
2329
2501
|
txt.appendChild(e('b', null, bundle.name));
|
|
2330
2502
|
txt.appendChild(e('span', 'notiz', bundle.beschreibung));
|
|
2331
|
-
var herkunft = e('span', 'mono', zahlwort(bundle.mitglieder, 'Skill', 'Skills')
|
|
2503
|
+
var herkunft = e('span', 'mono', zahlwort(bundle.mitglieder.length, 'Skill', 'Skills')
|
|
2332
2504
|
+ ' aus ' + zahlwort(bundle.quellen.length, 'Quelle', 'Quellen') + ' · ' + bundle.quelleName);
|
|
2333
2505
|
herkunft.title = bundle.quellen.join('\n');
|
|
2334
2506
|
txt.appendChild(herkunft);
|
|
2335
2507
|
if (ueberall) txt.appendChild(e('span', 'notiz', zieleZahl > 1 ? 'Hängt schon überall.' : 'Hängt hier schon.'));
|
|
2336
2508
|
else if (schon > 0) txt.appendChild(e('span', 'notiz', 'Hängt schon in ' + schon + ' von ' + zieleZahl + ' Harnesses.'));
|
|
2337
2509
|
label.appendChild(txt);
|
|
2510
|
+
bundleAufklappbereich(bundle, label, txt, i);
|
|
2338
2511
|
box.appendChild(label);
|
|
2339
2512
|
});
|
|
2340
2513
|
$('dsk-bundlebox').hidden = BUNDLES.length === 0 && BUNDLES_KAPUTT.length === 0;
|
|
@@ -2346,6 +2519,54 @@
|
|
|
2346
2519
|
}).join('\n');
|
|
2347
2520
|
}
|
|
2348
2521
|
|
|
2522
|
+
/** Aufklappbereich einer Bundle-Wahlzeile (E114 L1, F133=O3): die Skills des Bundles mit ihrer
|
|
2523
|
+
Beschreibung, vor der Installation. Muster und Verhalten wie skillAufklappbereich (E92): Knopf
|
|
2524
|
+
oben rechts am Label, Körper als eigenes Grid-Kind, preventDefault gegen das Umschalten der
|
|
2525
|
+
Checkbox, je Dialog-Öffnung zugeklappt. Name und Beschreibung kommen aus dem Skill-Katalog;
|
|
2526
|
+
liegt ein Mitglied in einer noch nicht eingerichteten Quelle, steht dort sein Pfad. */
|
|
2527
|
+
function bundleAufklappbereich(bundle, label, txt, index) {
|
|
2528
|
+
var koerperId = 'dsk-bundlekoerper-' + index;
|
|
2529
|
+
var knopf = e('button', 'aufklappknopf');
|
|
2530
|
+
knopf.type = 'button';
|
|
2531
|
+
knopf.setAttribute('aria-expanded', 'false');
|
|
2532
|
+
knopf.setAttribute('aria-controls', koerperId);
|
|
2533
|
+
knopf.setAttribute('aria-label', 'Skills des Bundles ' + bundle.name + ' ein- oder ausklappen');
|
|
2534
|
+
var pfeil = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
2535
|
+
pfeil.setAttribute('viewBox', '0 0 16 16');
|
|
2536
|
+
pfeil.setAttribute('class', 'akkordeonpfeil dunkel');
|
|
2537
|
+
pfeil.setAttribute('aria-hidden', 'true');
|
|
2538
|
+
pfeil.innerHTML = '<path d="M4 6.5 8 10.5 12 6.5"/>';
|
|
2539
|
+
knopf.appendChild(pfeil);
|
|
2540
|
+
|
|
2541
|
+
var koerper = e('div', 'wahlkoerper');
|
|
2542
|
+
koerper.id = koerperId;
|
|
2543
|
+
koerper.hidden = true;
|
|
2544
|
+
bundle.mitglieder.forEach(function (m) {
|
|
2545
|
+
var skill = bundleMitgliedSkill(m);
|
|
2546
|
+
var zeile = e('p', 'skilldetail bundlemitglied');
|
|
2547
|
+
if (skill) {
|
|
2548
|
+
zeile.appendChild(e('b', null, skill.name + ': '));
|
|
2549
|
+
zeile.appendChild(document.createTextNode(skill.beschreibung || 'keine Beschreibung in der SKILL.md'));
|
|
2550
|
+
} else {
|
|
2551
|
+
zeile.appendChild(e('b', null, m.pfad + ': '));
|
|
2552
|
+
zeile.appendChild(document.createTextNode('aus ' + m.quelleText + ', die Quelle ist hier noch nicht eingerichtet'));
|
|
2553
|
+
}
|
|
2554
|
+
koerper.appendChild(zeile);
|
|
2555
|
+
});
|
|
2556
|
+
|
|
2557
|
+
knopf.addEventListener('click', function (ev) {
|
|
2558
|
+
ev.preventDefault();
|
|
2559
|
+
var war = knopf.getAttribute('aria-expanded') === 'true';
|
|
2560
|
+
knopf.setAttribute('aria-expanded', war ? 'false' : 'true');
|
|
2561
|
+
koerper.hidden = war;
|
|
2562
|
+
});
|
|
2563
|
+
koerper.addEventListener('click', function (ev) { ev.preventDefault(); });
|
|
2564
|
+
|
|
2565
|
+
txt.classList.add('mitknopf');
|
|
2566
|
+
label.appendChild(knopf);
|
|
2567
|
+
label.appendChild(koerper);
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2349
2570
|
/** Wie oft ein Bundle in den angesteuerten Zielen schon installiert ist (Name plus Quelle, E69). */
|
|
2350
2571
|
function bundleHaengtIn(teile, bundle) {
|
|
2351
2572
|
return teile.filter(function (z) {
|
|
@@ -3356,7 +3577,12 @@
|
|
|
3356
3577
|
var w = $('mcpliste');
|
|
3357
3578
|
w.textContent = '';
|
|
3358
3579
|
if (MCP_KATALOG.length === 0) w.appendChild(mcpEinladung());
|
|
3359
|
-
else
|
|
3580
|
+
else {
|
|
3581
|
+
// E113: Kopie nach Name, MCP_KATALOG selbst bleibt in Lieferreihenfolge (F105).
|
|
3582
|
+
MCP_KATALOG.slice().sort(function (a, b) {
|
|
3583
|
+
return a.eintrag.name.localeCompare(b.eintrag.name, 'de', { sensitivity: 'base' });
|
|
3584
|
+
}).forEach(function (k) { w.appendChild(mcpKarte(k)); });
|
|
3585
|
+
}
|
|
3360
3586
|
$('navzahlmcp').textContent = MCP_KATALOG.length;
|
|
3361
3587
|
}
|
|
3362
3588
|
|
|
@@ -3388,6 +3614,12 @@
|
|
|
3388
3614
|
// Die Plätze kommen aus dem Kern (F42, E16): die Fähigkeit hängt am Adapter, nicht am
|
|
3389
3615
|
// Harness-Namen, hier wird nicht selbst entschieden, wer welche Ebene kennt.
|
|
3390
3616
|
var plaetze = await rufe(function () { return window.hmgr.mcpPlaetze(); });
|
|
3617
|
+
// E113: nach angezeigtem Titel (Harness · Ort), bei Gleichstand nach der Dateispur. Die Kopie
|
|
3618
|
+
// ist zugleich die Auswahlliste, damit der Radio-Index zur sortierten Reihenfolge passt.
|
|
3619
|
+
plaetze = plaetze.slice().sort(function (a, b) {
|
|
3620
|
+
return zielTitel({ ziel: a }).localeCompare(zielTitel({ ziel: b }), 'de', { sensitivity: 'base' })
|
|
3621
|
+
|| mcpOrtSpur(a).localeCompare(mcpOrtSpur(b), 'de', { sensitivity: 'base' });
|
|
3622
|
+
});
|
|
3391
3623
|
mcpPlaetzeAuswahl = plaetze;
|
|
3392
3624
|
plaetze.forEach(function (ziel, i) {
|
|
3393
3625
|
var schon = k.eingehaengt.some(function (z) { return zielKey(z) === zielKey(ziel); });
|
|
@@ -3522,7 +3754,13 @@
|
|
|
3522
3754
|
box.appendChild(e('p', 'ohne', 'Noch kein Server im Katalog. hmgr liest ihn aus '
|
|
3523
3755
|
+ pfadSchreibweise('~/.hmgr/mcp.yaml') + ' und schreibt die Datei nie.'));
|
|
3524
3756
|
}
|
|
3525
|
-
|
|
3757
|
+
// E113: nach Name sortiert. Der Wert der Checkbox bleibt der Index in MCP_KATALOG (Lieferreihenfolge),
|
|
3758
|
+
// den die Auswertung beim Absenden dort nachschlägt.
|
|
3759
|
+
MCP_KATALOG.map(function (k, i) { return { k: k, i: i }; }).sort(function (a, b) {
|
|
3760
|
+
return a.k.eintrag.name.localeCompare(b.k.eintrag.name, 'de', { sensitivity: 'base' });
|
|
3761
|
+
}).forEach(function (p) {
|
|
3762
|
+
var k = p.k;
|
|
3763
|
+
var i = p.i;
|
|
3526
3764
|
var schon = k.eingehaengt.some(function (z) { return zielKey(z) === zielKey(ziel); });
|
|
3527
3765
|
var label = e('label', 'wahlzeile');
|
|
3528
3766
|
var input = document.createElement('input');
|
|
@@ -3648,7 +3886,12 @@
|
|
|
3648
3886
|
var eintrag = null;
|
|
3649
3887
|
HARNESS_HEIME.forEach(function (x) { if (x.harness === h) eintrag = x; });
|
|
3650
3888
|
if (!eintrag) return kasten;
|
|
3651
|
-
|
|
3889
|
+
// E113: das primäre Homedir (ohne Adresse) bleibt oben, die zusätzlichen folgen nach Adresse sortiert.
|
|
3890
|
+
var heimeSortiert = eintrag.heime.filter(function (x) { return !x.adresse; }).concat(
|
|
3891
|
+
eintrag.heime.filter(function (x) { return !!x.adresse; }).sort(function (a, b) {
|
|
3892
|
+
return a.adresse.localeCompare(b.adresse, 'de', { sensitivity: 'base' });
|
|
3893
|
+
}));
|
|
3894
|
+
heimeSortiert.forEach(function (heim) {
|
|
3652
3895
|
var zeile = e('div', 'heimzeile');
|
|
3653
3896
|
zeile.appendChild(e('span', 'heimart', heim.adresse ? heim.adresse : 'Homedir'));
|
|
3654
3897
|
var pfad = e('code', 'heimpfad', pfadKurz(heim.pfad));
|
|
@@ -3768,7 +4011,10 @@
|
|
|
3768
4011
|
var vorher = document.activeElement;
|
|
3769
4012
|
var merk = vorher && vorher.dataset && ul.contains(vorher) ? vorher.dataset.harness : null;
|
|
3770
4013
|
ul.textContent = '';
|
|
3771
|
-
HARNESSE_ALLE
|
|
4014
|
+
// E113: Kopie nach Anzeigename, HARNESSE_ALLE bleibt in Lieferreihenfolge (F105).
|
|
4015
|
+
HARNESSE_ALLE.slice().sort(function (a, b) {
|
|
4016
|
+
return harnessName(a).localeCompare(harnessName(b), 'de', { sensitivity: 'base' });
|
|
4017
|
+
}).forEach(function (h) {
|
|
3772
4018
|
var li = document.createElement('li');
|
|
3773
4019
|
var label = e('label', 'harnessschalter');
|
|
3774
4020
|
var input = document.createElement('input');
|
|
@@ -798,6 +798,14 @@ dialog::backdrop{background:rgba(9,45,37,.62)}
|
|
|
798
798
|
.bundlemitglieder{font-family:var(--mono);font-size:16px;letter-spacing:-.012em;color:var(--tinte-weich)}
|
|
799
799
|
.bundlekopf .knopf{margin-left:auto}
|
|
800
800
|
.bundlegruppe .linkliste li:last-child{border-bottom:1px solid var(--strich-zart)}
|
|
801
|
+
/* E114: Knöpfe und Aufklapp-Umschalter rechts im Kopf; der Kopf ist zugleich Klickfläche. */
|
|
802
|
+
.bundlekopf{cursor:pointer}
|
|
803
|
+
.bundleaktionen{margin-left:auto;display:inline-flex;align-items:center;gap:8px}
|
|
804
|
+
.bundleaktionen .knopf{margin-left:0}
|
|
805
|
+
.bundlegruppe .linkliste[hidden]{display:none}
|
|
806
|
+
/* Nicht verlinktes Mitglied (E114 L3): blass, der Knopf bleibt lesbar. */
|
|
807
|
+
.linkliste li.nichtverlinkt .name,.linkliste li.nichtverlinkt .was{color:var(--tinte-leise)}
|
|
808
|
+
.linkliste li.nichtverlinkt .quelle{color:var(--tinte-leise);font-style:italic}
|
|
801
809
|
|
|
802
810
|
/* Bundle- und Skill-Sektion im Dialog „Skills hinzufügen" (E69): zwei benannte Gruppen unter
|
|
803
811
|
demselben Suchfeld. */
|