您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Fehlerkorrektur: Alle neuen Module (Giftmischer, Himmelsleitern etc.) sind nun korrekt im Skript enthalten.
// ==UserScript== // @name All-in-One Namensgenerator v13.1 (Fehlerkorrektur) // @namespace http://tampermonkey.net/ // @version 13.1 // @description Fehlerkorrektur: Alle neuen Module (Giftmischer, Himmelsleitern etc.) sind nun korrekt im Skript enthalten. // @author Gemini & User-Input // @match https://www.leitstellenspiel.de/* // @grant GM_addStyle // @grant GM_xmlhttpRequest // @connect self // ==/UserScript== (function() { 'use strict'; // ======================================================================== // 1. STYLES // ======================================================================== GM_addStyle(` #ng-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); z-index: 9999; display: flex; justify-content: center; align-items: center; } #ng-modal-content { background-color: #282c34; color: #fff; padding: 20px; border-radius: 8px; width: 800px; max-width: 90%; max-height: 90vh; border: 1px solid #444; display: flex; flex-direction: column; } #ng-modal-content h3 { margin-top: 0; border-bottom: 1px solid #555; padding-bottom: 10px; } #ng-modal-body { flex-grow: 1; overflow-y: auto; margin-bottom: 15px; padding-right: 10px; } #ng-log-area { width: 100%; height: 200px; background-color: #1e1e1e; color: #d4d4d4; font-family: monospace; font-size: 12px; border: 1px solid #555; border-radius: 4px; padding: 5px; overflow-y: scroll; resize: vertical; margin-top: 10px; } #ng-progress-bar-container { width: 100%; background-color: #555; border-radius: 5px; } #ng-progress-bar { width: 0%; height: 20px; background-color: #007bff; border-radius: 5px; transition: width 0.2s ease-in-out; } #ng-progress-text { text-align: center; margin-top: 5px; font-size: 12px; color: #d4d4d4; } #ng-modal-buttons { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; flex-wrap: wrap; border-top: 1px solid #555; padding-top: 20px;} .ng-modal-btn { padding: 10px 20px; border: none; color: white; border-radius: 5px; cursor: pointer; } .btn-start { background-color: #28a745; } .btn-warning { background-color: #ffc107; color: black; } .btn-close { background-color: #6c757d; } .ng-select-all-line { display: flex; align-items: center; margin-bottom: 15px; font-size: 1.1em; border-bottom: 1px solid #555; padding-bottom: 15px; } .ng-select-all-line label { flex-grow: 1; cursor: pointer; display: flex; align-items: center; } .ng-select-all-line input { margin-right: 15px; width: 18px; height: 18px; } .ng-button-grid { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; } .ng-module-btn { background-color: #4f545c; border: 1px solid #666; color: #ddd; padding: 8px 12px; border-radius: 5px; cursor: pointer; transition: background-color 0.2s, border-color 0.2s; text-align: left; flex-basis: calc(33.333% - 10px); box-sizing: border-box; display: flex; flex-direction: column; } .ng-module-btn:hover { background-color: #616770; border-color: #888; } .ng-module-btn.selected { background-color: #007bff; border-color: #0056b3; color: white; font-weight: bold; } .ng-btn-content { flex-grow: 1; } .ng-module-btn .count { font-size: 0.85em; font-style: italic; color: #ccc; display: block; margin-top: 4px; } .ng-module-btn.selected .count { color: #e0e0e0; } `); // ======================================================================== // 2. ZENTRALE KONFIGURATION & MODUL-DATENBANK // ======================================================================== const BATCH_SIZE = 15; const MARKER = '\u200B'; Array.prototype.random = function() { return this[Math.floor(Math.random() * this.length)]; }; function joinWithSuffix(base, suffix) { if (suffix.startsWith('-')) { return `${base}${suffix}`; } return `${base} ${suffix}`; } const MODULE_CONFIG = { // Module werden im UI alphabetisch nach Namen sortiert bergrettung: { name: "Bergrettung", emoji: "🏔️", targetVehicleTypes: { 149: 'GW-Bergrettung (NEF)', 150: 'GW-Bergrettung', 151: 'ELW Bergrettung', 152: 'ATV', 154: 'Schneefahrzeug', 155: 'Anh Höhenrettung (Bergrettung)', 158: 'GW-Höhenrettung (Bergrettung)' }, nameGenerator: function(isLarge = false) { const praefixe = ["Gipfel-", "Gletscher-", "Alpen-", "Fels-", "Schnee-", "Eis-", "Gams-", "Stein-", "Höhen-", "Lawinen-", "Grat-", "Alm-"]; const adjektive = ["Eisiger", "Steiler", "Schroffer", "Standfester", "Mutiger", "Schneidiger", "Alpiner", "Gipfelklarer", "Lawinensicherer", "Abgehärteter", "Erfahrener", "Trittsicherer"]; const namen = [ "Reinhold Messner", "Luis Trenker", "Hermann Buhl", "Peter Habeler", "Gerlinde Kaltenbrunner", "Hans Kammerlander", "Ötzi", "Heidi", "Alm-Öhi", "Yeti", "Gletscher-Geist", "Der Bergdoktor", "Andreas Gabalier", "Steinbock", "Gams", "Murmeltier", "Adler", "Geier", "Bernhardiner", "Alpen-Salamander", "Schneehase", "Steinadler", "Bartgeier", "Alpendohle", "Schneefink", "Kreuzotter", "Apollofalter", "Alpenbock", "Mount Everest", "K2", "Mont Blanc", "Matterhorn", "Zugspitze", "Großglockner", "Eiger-Nordwand", "Dolomiten", "Watzmann", "Himalaya", "Anden", "Rocky Mountains", "Karakorum", "Pamir", "Kaukasus", "Karabiner", "Eispickel", "Steigeisen", "Seilschaft", "Biwak", "Lawine", "Gletscherspalte", "Klettergurt", "Schneeschuh", "Pistenraupe", "Skidoo", "Quad", "Unimog", "Haglund", "Gipfelkreuz", "Bergkristall", "Edelweiß", "Enzian", "Almrausch", "Gondel", "Sessellift", "Bergführer", "Hüttenwirt", "Sherpa", "Gipfelstürmer", "Alpinist", "Kletterer", "Wanderer", "Gipfel-Taxi", "Latschenkiefer-Latscher", "Geröll-Gerümpel", "Wander-Wachtel", "Touristen-Retter", "Alpen-Sherpa", "Hüttenwirt-Helfer", "Verirrten-Verfolger", "Höhen-Krankheit", "Schnee-Schieber", "Gletscher-Gondel", "Steinadler-Shuttle", "Sandalen-Sammler", "Flip-Flop-Finder", "Der letzte Lift", "Jodel-Diplom", "Murmeltier-Murks", "Gamsbart-Gondoliere", "Klettersteig-Klops", "Lawinen-Loser-Lotsendienst", "Geröll-Römer", "Eis-Kratzer", "Absturz-Assistent", "Bruchharsch-Bezwinger", "Firn-Fahnder", "Schneebrett-Sheriff", "Spalten-Springer", "Überlebens-Übersetzer", "Höhen-Rettungs-Held", "Anti-Absturz-Einheit", "Gipfel-Gigant", "Fels-Flüsterer", "Eis-Eroberer", "Schnee-Stapfer", "Grat-Wanderer", "Alm-Apostel", "Kraxel-Kommando", "Wand-Wächter", "Seil-Spezialist", "Haken-Held", "Pickel-Pionier", "Steig-Eisen-Stratege", "Biwak-Bataillon", "Spalten-Schreck", "Gurt-Gott", "Pisten-Polizei", "Kristall-Kurier", "Edelweiß-Express", "Enzian-Einsatz", "Hütten-Helfer", "Sherpa-Shuttle", "Gipfel-Gämse", "Gletscher-Goliath", "Fels-Fundament", "Eis-Titan", "Schnee-Sturm", "Alpen-Apostel", "Berg-Bulle", "Grat-Gigant", "Wand-Wüterich", "Kletter-König", "Seil-Souverän", "Haken-Halbgott", "Pickel-Prinz", "Steig-Star", "Biwak-Boss", "Spalten-Spezi", "Gurt-Genie", "Pisten-Pate", "Kristall-Kaiser", "Edelweiß-Elite", "Enzian-Eroberer", "Hütten-Hüne", "Sherpa-Star", "Gipfel-General", "Gletscher-Gebieter", "Fels-Fürst", "Eis-Imperator", "Schnee-Sultan", "Alpen-Admiral", "Berg-Baron", "Grat-Gebieter", "Wand-Warlord", "Kletter-Kaiser", "Seil-Sultan", "Haken-Herrscher", "Pickel-Papst", "Steig-Souverän", "Biwak-Baron", "Spalten-Stratege", "Gurt-Gigant", "Pisten-Präsident", "Kristall-König", "Edelweiß-Emir", "Enzian-Experte", "Hütten-Häuptling", "Sherpa-Scheich", "Alpen-Chaot", "Berg-Berserker", "Gipfel-Geist", "Gletscher-Gigant", "Fels-Fanatiker", "Eis-Elefant", "Schnee-Schamane", "Grat-Guerilla", "Wand-Wahnsinniger", "Kletter-Kamikaze", "Seil-Samurai", "Haken-Haudegen", "Pickel-Pirat", "Steig-Stratege", "Biwak-Biest", "Spalten-Schlächter", "Gurt-Guru", "Pisten-Pirat", "Kristall-Krieger", "Edelweiß-Ehrenmann", "Enzian-Entdecker", "Hütten-Held", "Sherpa-Spezialist", "Gipfel-Gladiator", "Gletscher-Krieger", "Fels-Folterer", "Eis-Eremit", "Schnee-Schlächter", "Alpen-Ass", "Berg-Bestie", "Grat-Gott", "Wand-Wunder", "Kletter-Koryphäe", "Seil-Savant", "Haken-Heiland", "Pickel-Professor", "Steig-Sensei", "Biwak-Büffel", "Spalten-Serpent", "Gurt-General", "Pisten-Phantom" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } }, betreuung: { name: "Feldküche", emoji: "🍲", targetVehicleTypes: { 130: 'GW-Bt', 131: 'Bt-Kombi', 132: 'FKH', 133: 'Bt LKW', 138: 'GW-Verpflegung', 139: 'GW-Küche', 140: 'MTW-Verpflegung', 141: 'FKH', 142: 'AB-Küche' }, nameGenerator: function(isLarge = false) { const gerichte = [ { name: "Aal Grün", gender: "m" }, { name: "Aalsuppe", gender: "f" }, { name: "Adana Kebab", gender: "m" }, { name: "Ahi-Thunfisch-Steak", gender: "n" }, { name: "Ajvar", gender: "n" }, { name: "Allgäuer Kässpatzen", gender: "p" }, { name: "Amerikaner", gender: "p" }, { name: "Apfel im Schlafrock", gender: "m" }, { name: "Apfelmus", gender: "n" }, { name: "Apfelpfannkuchen", gender: "m" }, { name: "Apfelstrudel", gender: "m" }, { name: "Arme Ritter", gender: "p" }, { name: "Arrabiata", gender: "f" }, { name: "Artischocke", gender: "f" }, { name: "Asiatische Nudelpfanne", gender: "f" }, { name: "Aspik", gender: "n" }, { name: "Aubergine", gender: "f" }, { name: "Auflauf", gender: "m" }, { name: "Austern", gender: "p" }, { name: "Baba Ghanoush", gender: "n" }, { name: "Backfisch", gender: "m" }, { name: "Backkartoffel", gender: "f" }, { name: "Bacon Bomb", gender: "f" }, { name: "Baguette", gender: "n" }, { name: "Bami Goreng", gender: "n" }, { name: "Bananenbrot", gender: "n" }, { name: "Bärlauchsuppe", gender: "f" }, { name: "Bauernfrühstück", gender: "n" }, { name: "Bayerischer Wurstsalat", gender: "m" }, { name: "Beef Brisket", gender: "n" }, { name: "Beef Wellington", gender: "n" }, { name: "Beignet", gender: "m" }, { name: "Berliner", gender: "p" }, { name: "Bienenstich", gender: "m" }, { name: "Bigos", gender: "n" }, { name: "Birnen, Bohnen und Speck", gender: "p" }, { name: "Bismarckhering", gender: "m" }, { name: "Blini", gender: "p" }, { name: "Blumenkohl", gender: "m" }, { name: "Blutwurst", gender: "f" }, { name: "Bockwurst", gender: "f" }, { name: "Boeuf Bourguignon", gender: "n" }, { name: "Bohneneintopf", gender: "m" }, { name: "Bolognese", gender: "f" }, { name: "Borscht", gender: "m" }, { name: "Bouillabaisse", gender: "f" }, { name: "Bratapfel", gender: "m" }, { name: "Bratensoße", gender: "f" }, { name: "Bratkartoffeln", gender: "p" }, { name: "Bratwurst", gender: "f" }, { name: "Brezel", gender: "f" }, { name: "Brokkoli", gender: "m" }, { name: "Brownie", gender: "m" }, { name: "Bruschetta", gender: "f" }, { name: "Bulette", gender: "f" }, { name: "Bulgursalat", gender: "m" }, { name: "Burger", gender: "m" }, { name: "Burrito", gender: "m" }, { name: "Butterbrot", gender: "n" }, { name: "Calzone", gender: "f" }, { name: "Cannelloni", gender: "p" }, { name: "Caprese", gender: "f" }, { name: "Carbonara", gender: "f" }, { name: "Cevapcici", gender: "p" }, { name: "Cheesecake", gender: "m" }, { name: "Chicken Nuggets", gender: "p" }, { name: "Chicken Wings", gender: "p" }, { name: "Chili con Carne", gender: "n" }, { name: "Chili sin Carne", gender: "n" }, { name: "Churros", gender: "p" }, { name: "Clubsandwich", gender: "n" }, { name: "Coleslaw", gender: "m" }, { name: "Corn Dog", gender: "m" }, { name: "Couscous", gender: "m" }, { name: "Crème brûlée", gender: "f" }, { name: "Crepes", gender: "p" }, { name: "Crostini", gender: "p" }, { name: "Crumble", gender: "m" }, { name: "Currywurst", gender: "f" }, { name: "Dal", gender: "n" }, { name: "Dampfnudel", gender: "f" }, { name: "Döner Kebab", gender: "m" }, { name: "Donut", gender: "m" }, { name: "Dürüm", gender: "m" }, { name: "Eier im Glas", gender: "p" }, { name: "Eierkuchen", gender: "m" }, { name: "Eiersalat", gender: "m" }, { name: "Eintopf", gender: "m" }, { name: "Eisbein", gender: "n" }, { name: "Empanada", gender: "f" }, { name: "Enchilada", gender: "f" }, { name: "Erbsensuppe", gender: "f" }, { name: "Erdbeerkuchen", gender: "m" }, { name: "Fajita", gender: "f" }, { name: "Falafel", gender: "p" }, { name: "Falscher Hase", gender: "m" }, { name: "Feuerflecken", gender: "m" }, { name: "Finanztopf", gender: "m" }, { name: "Fish and Chips", gender: "p" }, { name: "Flammkuchen", gender: "m" }, { name: "Frikadelle", gender: "f" }, { name: "Frühlingsrolle", gender: "f" }, { name: "Gaisburger Marsch", gender: "m" }, { name: "Garnelen", gender: "p" }, { name: "Gazpacho", gender: "f" }, { name: "Gebratene Nudeln", gender: "p" }, { name: "Gefillde", gender: "p" }, { name: "Gemüseauflauf", gender: "m" }, { name: "Gemüsepfanne", gender: "f" }, { name: "Germknödel", gender: "m" }, { name: "Geschnetzeltes", gender: "n" }, { name: "Gnocchi", gender: "p" }, { name: "Grießbrei", gender: "m" }, { name: "Grillhähnchen", gender: "n" }, { name: "Grünkohl mit Pinkel", gender: "m" }, { name: "Gulasch", gender: "n" }, { name: "Gulaschkanone", gender: "f" }, { name: "Gurkensalat", gender: "m" }, { name: "Gyros", gender: "n" }, { name: "Hackbraten", gender: "m" }, { name: "Hähnchencurry", gender: "n" }, { name: "Halloumi", gender: "m" }, { name: "Hamburger", gender: "m" }, { name: "Handkäse mit Musik", gender: "m" }, { name: "Haxe", gender: "f" }, { name: "Hefekloß", gender: "m" }, { name: "Heringssalat", gender: "m" }, { name: "Himmel un Ääd", gender: "n" }, { name: "Hot Dog", gender: "m" }, { name: "Hummus", gender: "m" }, { name: "Jägerschnitzel", gender: "n" }, { name: "Jambalaya", gender: "f" }, { name: "Kaiserschmarrn", gender: "m" }, { name: "Käsekuchen", gender: "m" }, { name: "Käsespätzle", gender: "p" }, { name: "Kassler", gender: "n" }, { name: "Kartoffelpuffer", gender: "p" }, { name: "Kartoffelsalat", gender: "m" }, { name: "Kartoffelsuppe", gender: "f" }, { name: "Kebab", gender: "m" }, { name: "Königsberger Klopse", gender: "p" }, { name: "Köttbullar", gender: "p" }, { name: "Krautwickel", gender: "p" }, { name: "Krapfen", gender: "m" }, { name: "Labskaus", gender: "n" }, { name: "Lahmacun", gender: "f" }, { name: "Lasagne", gender: "f" }, { name: "Leberkäse", gender: "m" }, { name: "Linseneintopf", gender: "m" }, { name: "Mac and Cheese", gender: "n" }, { name: "Maultaschen", gender: "p" }, { name: "Mettbrötchen", gender: "n" }, { name: "Milchreis", gender: "m" }, { name: "Minestrone", gender: "f" }, { name: "Moussaka", gender: "n" }, { name: "Mozzarella-Sticks", gender: "p" }, { name: "Muffin", gender: "m" }, { name: "Muscheln", gender: "p" }, { name: "Nasi Goreng", gender: "n" }, { name: "Nudelauflauf", gender: "m" }, { name: "Nudelsalat", gender: "m" }, { name: "Obatzda", gender: "m" }, { name: "Ochsenschwanzsuppe", gender: "f" }, { name: "Onion Rings", gender: "p" }, { name: "Pad Thai", gender: "n" }, { name: "Paella", gender: "f" }, { name: "Pannfisch", gender: "m" }, { name: "Panna Cotta", gender: "f" }, { name: "Peking-Ente", gender: "f" }, { name: "Pellkartoffeln mit Quark", gender: "p" }, { name: "Pesto", gender: "n" }, { name: "Pfannkuchen", gender: "m" }, { name: "Pfefferpotthast", gender: "m" }, { name: "Pho", gender: "f" }, { name: "Pichelsteiner", gender: "m" }, { name: "Pierogi", gender: "p" }, { name: "Pita", gender: "f" }, { name: "Pizza", gender: "f" }, { name: "Pizzabrötchen", gender: "p" }, { name: "Polenta", gender: "f" }, { name: "Pommes Frites", gender: "p" }, { name: "Porridge", gender: "n" }, { name: "Pulled Pork", gender: "n" }, { name: "Quesadilla", gender: "f" }, { name: "Quiche", gender: "f" }, { name: "Raclette", gender: "n" }, { name: "Rahmschnitzel", gender: "n" }, { name: "Ramen", gender: "m" }, { name: "Ratatouille", gender: "n" }, { name: "Ravioli", gender: "p" }, { name: "Reibekuchen", gender: "m" }, { name: "Rinderroulade", gender: "f" }, { name: "Risotto", gender: "n" }, { name: "Rollmops", gender: "m" }, { name: "Rote Grütze", gender: "f" }, { name: "Roulade", gender: "f" }, { name: "Rührei", gender: "n" }, { name: "Samosa", gender: "f" }, { name: "Saumagen", gender: "m" }, { name: "Sauerbraten", gender: "m" }, { name: "Sauerkraut", gender: "n" }, { name: "Schaschlik", gender: "n" }, { name: "Schichtkohl", gender: "m" }, { name: "Schlachtplatte", gender: "f" }, { name: "Schnitzel", gender: "n" }, { name: "Schupfnudeln", gender: "p" }, { name: "Schwarzwälder Kirschtorte", gender: "f" }, { name: "Schweinshaxe", gender: "f" }, { name: "Semmelknödel", gender: "m" }, { name: "Senfeier", gender: "p" }, { name: "Serbische Bohnensuppe", gender: "f" }, { name: "Shakshuka", gender: "f" }, { name: "Shepherd's Pie", gender: "m" }, { name: "Soljanka", gender: "f" }, { name: "Sommerrolle", gender: "f" }, { name: "Spaghetti", gender: "p" }, { name: "Spargel", gender: "m" }, { name: "Spätzle", gender: "p" }, { name: "Spiegelei", gender: "n" }, { name: "Spinat", gender: "m" }, { name: "Steak", gender: "n" }, { name: "Strammer Max", gender: "m" }, { name: "Strudel", gender: "m" }, { name: "Sülze", gender: "f" }, { name: "Sushi", gender: "n" }, { name: "Taboulé", gender: "n" }, { name: "Taco", gender: "m" }, { name: "Tafelspitz", gender: "m" }, { name: "Tagliatelle", gender: "p" }, { name: "Tandoori Chicken", gender: "n" }, { name: "Tapas", gender: "p" }, { name: "Tartar", gender: "n" }, { name: "Tarte", gender: "f" }, { name: "Thüringer Klöße", gender: "p" }, { name: "Tiramisu", gender: "n" }, { name: "Toast Hawaii", gender: "m" }, { name: "Tofu", gender: "m" }, { name: "Tomatensuppe", gender: "f" }, { name: "Tortellini", gender: "p" }, { name: "Tsatsiki", gender: "n" }, { name: "Udon-Nudeln", gender: "p" }, { name: "Vitello Tonnato", gender: "n" }, { name: "Waffel", gender: "f" }, { name: "Weißwurst", gender: "f" }, { name: "Westfälische Rinderwurst", gender: "f" }, { name: "Wiener Schnitzel", gender: "n" }, { name: "Wirsing", gender: "m" }, { name: "Wurstgulasch", gender: "n" }, { name: "Wurstsalat", gender: "m" }, { name: "Zigeunerschnitzel", gender: "n" }, { name: "Zürcher Geschnetzeltes", gender: "n" }, { name: "Zwiebelkuchen", gender: "m" } ]; const praefixe = ["Rollende", "Mobile", "Heisse", "Feld-", "Einsatz-", "Taktische", "Herzhafte", "Seelen-", "Wohlfühl-", "Mampf-", "Deftige"]; const suffixe = ["Bude", "Express", "Grill", "Mobil", "Eck", "Hütte", "Kelle", "Pfanne", "Topf", "Küche", "Versorgung", "Oase", "Kombüse", "Station"]; const personen = ["Smutje", "Küchenchef", "Kombüsen-König", "Suppen-Kasper", "Grillmeister", "Brutzler", "Feldkoch"]; const humor = ["Futter-Krippe", "Magen-Füller", "Geschmacks-Explosion", "Kalorien-Bomber", "Seelentröster", "Moral-Heber", "Katerfrühstück", "Nervennahrung"]; while (true) { const gewaehlterTyp = ['praefix_kombi', 'suffix_kombi', 'tour_kombi', 'heiss_kombi', 'lecker_kombi', 'funktion_kombi'].random(); const gericht = gerichte.random(); switch (gewaehlterTyp) { case 'praefix_kombi': return `${praefixe.random()} ${gericht.name}`; case 'suffix_kombi': return `${gericht.name}-${suffixe.random()}`; case 'tour_kombi': return `${gericht.name} on Tour`; case 'heiss_kombi': if (gericht.gender === 'p') continue; switch (gericht.gender) { case 'm': return `Heißer ${gericht.name}`; case 'f': return `Heiße ${gericht.name}`; case 'n': return `Heißes ${gericht.name}`; } break; case 'lecker_kombi': if (gericht.gender === 'p') continue; switch (gericht.gender) { case 'm': case 'n': return `Zum leckeren ${gericht.name}`; case 'f': return `Zur leckeren ${gericht.name}`; } break; case 'funktion_kombi': const subTyp = ['person', 'humor'].random(); if (subTyp === 'person') { return `${praefixe.random()} ${personen.random()}`; } else { return `${humor.random()}-${suffixe.random()}`; } } } } }, feuerwehr: { name: "Löschfahrzeuge", emoji: "🔥", targetVehicleTypes: { 0: 'LF 20', 1: 'LF 10', 6: 'LF 8/6', 7: 'LF 20/16', 8: 'LF 10/6', 9: 'LF 16-TS', 17: 'TLF 2000', 18: 'TLF 3000', 19: 'TLF 8/8', 20: 'TLF 8/18', 21: 'TLF 16/24-Tr', 22: 'TLF 16/25', 23: 'TLF 16/45', 24: 'TLF 20/40', 25: 'TLF 20/40-SL', 26: 'TLF 16', 30: 'HLF 20', 37: 'TSF-W', 84: 'ULF mit Löscharm', 86: 'Turbolöscher', 87: 'TLF 4000', 88: 'KLF', 89: 'MLF', 90: 'HLF 10', 107: 'LF-L', 121: 'GTLF', 166: 'PTLF 4000', 167: 'SLF' }, largeVehicleIds: [121, 87, 24, 25], nameGenerator: function(isLarge = false) { const praefixe = ["Feuer-", "Brand-", "Lösch-", "Wasser-", "Hydro-", "Sturm-", "Blitz-", "Donner-", "Glut-", "Inferno-", "Flut-", "Höllen-", "Vulkan-", "Magma-", "Asche-", "Pyro-", "Rauch-"]; const adjektive = ["Roter", "Wilder", "Zorniger", "Rasender", "Stählerner", "Mächtiger", "Brüllender", "Nasser", "Mutiger", "Tapferer", "Heldenhafter", "Göttlicher", "Legendärer", "Glühender", "Sengender", "Unbezwingbarer", "Stoischer", "Unaufhaltsamer", "Elementarer", "Donnernder", "Brachialer", "Zischender", "Eiskalter", "Massiver"]; const namen = [ "Bulle", "Bär", "Eber", "Drache", "Walross", "Nashorn", "Elefant", "Mammut", "Dachs", "Titan", "Gigant", "Zyklop", "Held", "Goliath", "Thor", "Poseidon", "Krieger", "Barbar", "Wächter", "Retter", "Jäger", "Bezwinger", "Hydra", "Cerberus", "Phoenix", "Balrog", "Hephaistos", "Erlöser", "Frontbrecher", "Behemoth", "Moloch", "Leviathan", "Ifrit", "Salamander", "Prometheus", "Vulkan", "Surtr", "Loki", "Agni", "Ra", "Fafnir", "Basilisk", "Hammer", "Amboss", "Klinge", "Speer", "Faust", "Kolben", "Komet", "Meteor", "Gletscher", "Fels", "Bohrer", "Pflug", "Ramme", "Brecher", "Generator", "Reaktor", "Turbine", "Lawine", "Tsunami", "Orkan", "Wellenbrecher", "Hydroschild", "Wasserwerfer", "Monitor", "Strahlrohr", "Halligan-Tool", "Flammpunkt", "Rauchgrenze", "Hitzeschild", "Maschinist", "Atemschutzträger", "Flashover", "Backdraft", "Hohlstrahlrohr", "Zumischer", "Riegelstellung", "Innenangriff", "Rettungsplattform", "Sprungpolster", "Wasser Marsch", "Pyromanen-Schreck", "Grill-Meister", "BMA-Tourist", "Keller-Ausleuchter", "Bäumchen-Bewässerer", "Katzen-Retter", "Leiter-Halter", "Schlauch-Salat", "Tatü-Tata", "Blaulicht-Ballett", "Feuer-Fighter", "Glut-Goliath", "Nasser-Albtraum", "Heißmacher", "Durst-Löscher", "Party-Pumpe", "Schaum-Schläger", "Asphalt-Kühler", "Tankstellen-Tester", "Hydranten-Hengst", "Letzte-Ölung", "Feuerteufel-Flüsterer", "Rauch-Ramme", "Wasser-Verschwender", "Grill-Aufsicht", "Wasserrechnungs-Treiber", "Mülleimerbrand-Spezialist", "Funken-Fänger", "Zünd-Zerstörer", "Hitze-Held", "Flammen-Fresser", "Glut-Garant", "Asche-Artist", "Ruß-Ritter", "Qualm-Quälgeist", "Brand-Baron", "Lösch-Lord", "Feuer-Wall", "Flammen-Woge", "Wasser-Wand", "Glut-Hölle", "Asche-Regen", "Rauch-Schwade", "Brand-Bestie", "Feuer-Orkan", "Flammen-Tsunami", "Wasser-Gewalt", "Glut-Sturm", "Asche-Sturm", "Rauch-Bestie", "Brand-Drache", "Feuer-Hydra", "Flammen-Cerberus", "Wasser-Titan", "Glut-Gigant", "Wasserbüffel", "Roter Blitz", "Schaumkanone", "Glutvernichter 3000", "Sirenenpony", "Flammenfresser", "Drehmomentlöschi", "Rauchschlucker", "Blaulicht-Bomber", "Hydrantenfreund", "Löschinator", "Feuerwehr-Banane", "Schlauchmaster", "Hitzehammer", "Löschexpress", "Pumpenkönig", "Roter Riese", "Funkenschreck", "Feuerknutscher", "Schaumrüssel", "Rauchradler", "Glutbuster", "Löschlegende", "Wasserwalze", "Schaumwalze", "Roter Panda", "Blaulicht-Komet", "Brandbremser", "Funkenfresser", "HLFie", "Flammenjäger", "Wolkenmacher", "Kübelspritze Deluxe", "Wasserdompteur", "Druckluftheld", "Schaumgeist", "Lösch-Limo", "Sirenenkutsche", "Feuerbändiger", "HLF-Hulk", "Glutjäger", "Wasserkutsche", "Rauchknacker", "Schlauchschlepper", "Löschtaxi", "Gischtgeschoss", "Roter Rambock", "Hydrantenschreck", "Funkenfänger", "Schaumgigant", "Wasserdrache", "Hitzehorst", "Blaulicht-Bolide", "Feuerflitzer", "Flammenhobel", "Brandblocker", "Pumpinator", "Feuerwehr-Ferrari", "Lösch-Kutter", "Rauchrocker" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; let baseName = patterns.random()(); if (isLarge) { baseName = joinWithSuffix(baseName, ["Gigant", "Koloss", "Titan", "Goliath", "Leviathan"].random()); } return baseName; } }, fuehrung: { name: "Chef-Kutschen", emoji: "👑", targetVehicleTypes: { 3: 'ELW 1', 34: 'ELW 2', 55: 'KdoW-LNA', 56: 'KdoW-OrgL', 35: 'leBefKw', 128: 'ELW Drohne', 129: 'ELW2 Drohne', 144: 'FüKW (THW)', 145: 'FüKomKW', 146: 'Anh FüLa', 147: 'FmKW', 148: 'MTW-FGr K', 51: 'FüKW (Polizei)', 103: 'FuStW (DGL)', 78: 'AB-Einsatzleitung', 59: 'ELW 1 (SEG)' }, nameGenerator: function(isLarge = false) { const praefixe = ["Chef-", "Einsatzleiter-", "Alpha-", "Kommando-", "Lagezentrum-", "Strategie-", "Master-", "Ober-", "Haupt-", "Krisenstab-", "Taktik-", "Stabs-", "Kontroll-", "Präsidial-", "Generalstabs-"]; const adjektive = ["Leitender", "Dominanter", "Entscheidender", "Souveräner", "Wichtiger", "Finaler", "Strategischer", "Taktischer", "Autoritärer", "Unumstößlicher", "Befehlender", "Delegierender", "Charismatischer", "Bürokratischer", "Visionärer"]; const namen = [ "Häuptling", "General", "Direktor", "Boss", "Pate", "Meister", "Stratege", "Koordinator", "Platzhirsch", "Alphatier", "Big-Boss", "Kuttenträger", "Präsident", "Imperator", "Kanzler", "Senator", "Admiral", "Befehlshaber", "Vorstand", "CEO", "Aufsichtsrat", "Feldmarschall", "Patriarch", "Magnat", "Strippenzieher", "Dirigent", "Zeremonienmeister", "Caesar", "Napoleon", "Sun Tzu", "König", "Bauer", "Läufer", "Springer", "Turm", "Dame", "Rochade", "Gambit", "Masterplan", "Direktive", "Lagekarte", "Führungsstab", "Kommando-Brücke", "Machtwort", "Veto", "Organigramm", "Mastermind-Mobil", "Schachzug", "Exekutivebene", "Eskalationsstufe", "SWOT-Analyse", "Debriefing", "Befehlskette", "Meldekopf", "Task-Force", "Synergy", "Paradigm Shift", "Low-Hanging Fruit", "Game Changer", "Think Tank", "Kaffee-Beauftragter", "Plan-Macher", "Entscheider", "Taktikfuchs", "Kaffee-Stratege", "Meeting-Meister", "Presse-Sprecher", "Westentaschen-General", "Excel-Tabellen-Fürst", "PowerPoint-Pirat", "Dienstwagen-Don", "Bullshit-Bingo-Bus", "Wichtigtuer-Wagen", "Krisen-Kaffee-Kurier", "Zuständigkeits-Zirkus", "Synergie-Shuttle", "Stakeholder-Mobil", "Wichtiger-Willi", "Zuständigkeits-Verschieber", "Meeting-Marathon-Mobil", "PowerPoint-Prinz", "Koryphäe", "Eminenz", "Entscheidungs-Delegierer", "Meeting-Einberufer", "Kaffee-ist-keine-Strategie" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } }, hunde: { name: "Spürnasen", emoji: "🐕", targetVehicleTypes: { 91: 'Rettungshundefahrzeug', 92: 'Anh Hund', 94: 'DHuFüKW', 153: 'Hundestaffel (Bergrettung)' }, largeVehicleIds: [153], nameGenerator: function(isLarge = false) { const praefixe = ["Spürnasen-", "Fährten-", "Rettungs-", "Leckerli-", "Bello-", "Wuff-", "K-9-", "Hunde-", "Fellnasen-", "Pfoten-", "Knochen-"]; const adjektive = ["Treuer", "Wachsamer", "Lauter", "Feiner", "Spitzfindiger", "Mutiger", "Verfressener", "Verspielter", "Heldenhafter", "Unbestechlicher", "Sabbernder", "Loyaler"]; const substantive_hunde = ["Partner", "Kollege", "Wächter", "Spürnase", "Fährtensucher", "Retter", "Held", "Beschützer", "Ermittler", "Beißer", "Kläffer", "Helfer auf 4 Pfoten"]; const namen = [ "Kommissar Rex", "Lassie", "Rin Tin Tin", "Toto", "Pluto", "Goofy", "Snoopy", "Beethoven", "Hachiko", "Balto", "Cerberus", "Scooby-Doo", "Struppi", "Idefix", "Barry", "Buddy", "Chase", "Marshall", "Rocky", "Rubble", "Skye", "Zuma", "Everest", "Tracker", "Bolt", "Dug", "Pongo", "Perdita", "Slinky", "Santa's Little Helper", "Brian Griffin", "Chance", "Shadow", "Milo", "Otis", "Copper", "Fang", "Max", "Gromit", "Odie", "Spike", "Tyke", "Droopy", "Huckleberry Hound", "Augie Doggie", "Muttley", "Scrappy-Doo", "Marmaduke", "Underdog", "Clifford", "Blue", "Lady", "Tramp", "Jock", "Trusty", "Porky", "Rowlf", "Einstein", "Brutus", "Zero", "Winston", "Buck", "Marley", "Sam", "Benji", "Schäferhund", "Malinois", "Rottweiler", "Bernhardiner", "Golden Retriever", "Labrador", "Spürhund", "Bluthund", "Dobermann", "Dalmatiner", "Beagle", "Border Collie", "Dackel", "Husky", "Terrier", "Dogge", "Mastiff", "Schnauzer", "Boxer", "Akita", "Jack Russell", "Laika", "Greywind", "Nymeria", "Shaggydog", "Fass", "Platz", "Sitz", "Apport", "Such", "Bleib", "Hier", "Fein", "Gib Laut", "Voran", "Aus", "Fuß", "Hopp", "Bring", "Steh", "Down", "Such und Hilf", "Revier", "Verbellen", "Leckerli-Bomber", "Bello-Mobil", "Spürnasen-Express", "Fährten-Ferkel", "K-9-Kutsche", "Gebell-Gruppe", "Sabber-Shuttle", "Tatort-Taz", "Wadenbeißer-Wagen", "Fell-Geschoss", "Alarm auf 4 Pfoten", "Der nasse Stupser", "Knochen-Jäger", "Postboten-Schreck", "Keksdieb-Kommando", "Anti-Katzen-Kommando", "Sofawolf-Shuttle", "Haufen-Finder", "Buddel-Bataillon", "Streichel-Einheit", "Quietsche-Tier-Vernichter", "Sabber-Spezialist", "Futterneid-Flotte", "Stöckchen-Such-Service", "Platz-Polizei", "Sitz-Streife", "Bällchen-Junkie", "Fehlalarm-Fifi", "Reste-Vertilger", "Lausch-Angriff", "Chaos-Charly", "Pfützen-Prüfer", "Schuh-Sortierer", "Fährten-Vernichter", "Bett-Besetzer" ]; if (isLarge) { const alpin_praefixe = ["Alpen-", "Gletscher-", "Lawinen-", "Gipfel-", "Firn-", "Geröll-", "Schnee-"]; const alpin_adjektive = ["Trittsicherer", "Schneefester", "Alpiner", "Kälte-resistenter"]; const alpin_namen = ["Lawinen-Wuff", "Alpen-Bello", "Gipfel-Kläffer", "Schnee-Schnauze", "Geröll-Retriever", "Yeti-Jäger", "Murmeltier-Melder", "Firn-Finder", "Barry der Held", "Heidi's Held", "Alm-Aportierer"]; const hybrid_patterns = [ () => alpin_namen.random(), () => { const name = substantive_hunde.random(); if (name.includes(' ')) return name; return `${alpin_praefixe.random()}${name}`; }, () => `${alpin_adjektive.random()} ${substantive_hunde.random()}`, () => `${alpin_adjektive.random()} ${namen.random()}` ]; return hybrid_patterns.random()(); } else { const patterns = [ () => namen.random(), () => `${adjektive.random()} ${substantive_hunde.random()}`, () => { const name = substantive_hunde.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } } }, luftrettung: { name: "Luftrettung", emoji: "🚁", targetVehicleTypes: { 31: 'RTH', 61: 'Polizeihubschrauber', 156: 'Polizeihubschrauber mit verbauter Winde', 157: 'RTH Winde', 161: 'Hubschrauber (Seenotrettung)', 96: 'Außenlastbehälter (allgemein)' }, largeVehicleIds: [96], nameGenerator: function(isLarge = false) { if (isLarge) { const praefixe = ["Lösch-", "Wasser-", "Waldbrand-", "Flächenbrand-", "Feuer-", "Regen-", "Wolken-", "Sturz-", "Bomben-"]; const adjektive = ["Nasser", "Schwerer", "Plötzlicher", "Kühlender", "Entscheidender", "Punktgenauer", "Großflächiger"]; const namen = ["Bomber", "Regenmacher", "Wolkenbruch", "Monsun", "Sintflut", "Tsunami", "Wasserfall", "Katarakt", "Sturzbach", "Guss", "Schauer", "Niederschlag", "Fontäne", "Geysir", "Cloudbuster", "Fire-Bomber", "Water-Bomber", "Lösch-Ei", "Regen-Tanz", "Neptuns-Zorn", "Poseidons-Rache", "Thor's-Dusche", "Wald-Tränke", "Glut-Löscher", "Asche-Binder", "Rauch-Drücker", "Flammen-Tod", "Feuer-Ex", "Letzte-Ölung", "Der-große-Durstlöscher"]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } else { const praefixe = ["Himmels-", "Luft-", "Wolken-", "Rotor-", "Turbinen-", "Götter-", "Engels-", "Sturm-", "Alpen-", "Aero-", "Gipfel-", "Senkrecht-"]; const adjektive = ["Fliegender", "Schwebender", "Schneller", "Göttlicher", "Himmlischer", "Stählerner", "Allsehender", "Donnernder", "Windiger", "Kreisender", "Steigender", "Majestätischer"]; const namen = [ "Adler", "Falke", "Bussard", "Kondor", "Greif", "Albatros", "Ikarus", "Pegasus", "Valkyrie", "Garuda", "Erzengel", "Schutzengel", "Himmelsbote", "Retter", "Horus", "Hermes", "Gerfalke", "Milan", "Sturmvogel", "Roch", "Zeus", "Thor", "Simurgh", "Ziz", "Auge", "Winde", "Klinge", "Wirbelsturm", "Himmels-Auge", "Rotorblatt", "Thermik", "Gipfelstürmer", "Senkrechtstarter", "Aufwind", "Föhn", "Jetstream", "Cumulonimbus", "Pilot", "Windenoperator", "Bell UH-1D", "Eurocopter", "Bo 105", "Airbus H145", "Black Hawk", "Apache", "Chinook", "Luft-Taxi", "Propeller-Prinz", "Knatter-Kiste", "Himmels-Fahrstuhl", "Thermik-Tester", "Ventilator-Deluxe", "Teuerstes-Taxi", "Libellen-Lord", "Hummel-Heli", "Brötchen-Holer", "Höhen-Rausch", "Kerosin-Vernichter", "Höhen-Luft-Schnapper", "Adler-Attrappe", "Rotierende-Rettung", "Lawinen-Gucker", "Stau-Uinflieger", "Dach-Landeplatz-Sucher", "Vogel-Schreck", "Wind-Macher" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } } }, pferde: { name: "Hü-Hott-Express", emoji: "🐎", targetVehicleTypes: { 134: 'Pferdetransporter klein', 135: 'Pferdetransporter groß', 136: 'Anh Pferdetransport', 137: 'Zugfahrzeug Pferdetransport' }, nameGenerator: function(isLarge = false) { const praefixe = ["Huf-", "Galopp-", "Reiter-", "Kavallerie-", "Stall-", "Koppel-", "Heu-", "Hafer-", "Sattel-", "Striegel-", "Pferdestärken-"]; const adjektive = ["Stolzer", "Edler", "Wilder", "Schnaubender", "Trotziger", "Sanfter", "Anmutiger", "Ungezähmter", "Königlicher", "Schwerer", "Galoppierender", "Wiehernder"]; const namen = [ "Fury", "Black Beauty", "Jolly Jumper", "Sleipnir", "Bucephalus", "Schattenfell", "Rocinante", "Seabiscuit", "Secretariat", "Hidalgo", "Pegasus", "Kleiner Onkel", "Bürger", "Amigo", "Tornado", "Zorro", "Silver", "Trigger", "Champion", "Maximus", "Samson", "Philippe", "Khan", "Angus", "Bullseye", "Spirit", "Rain", "Artax", "Flicka", "Gunpowder", "Goliath", "Incitatus", "Marengo", "Copenhagen", "Comanche", "Traveler", "Cincinnati", "Alcatraz", "Balthasar", "Ferdinand", "Valegro", "Totilas", "Donnerhall", "Ratina Z", "Milton", "Hickstead", "Shutterfly", "For Pleasure", "Goldfever", "Gigolo", "Satchmo", "Bonfire", "Ahlerich", "Rembrandt", "Meteor", "Abdullah", "Salinero", "Cornet Obolensky", "Casall", "Chacco-Blue", "Brego", "Arod", "Hasufel", "Roheryn", "Snowmane", "Windfola", "Blackie", "Sefton", "Sergeant Reckless", "Haflinger", "Friese", "Andalusier", "Shire Horse", "Mustang", "Araber", "Lipizzaner", "Kaltblut", "Warmblut", "Vollblut", "Pinto", "Appaloosa", "Quarter Horse", "Paint Horse", "Tinker", "Noriker", "Percheron", "Holsteiner", "Hannoveraner", "Oldenburger", "Westfale", "Trakehner", "Fjordpferd", "Isländer", "Hufschlag", "Galopp", "Trab", "Sattel", "Zaumzeug", "Pferdestärke", "Kutsche", "Kavallerie", "Hafer-Moped", "Sheriff's-Mustang", "Heu-Transporter", "Stall-Geruch", "Laser-Pony", "Ein-PS-Einsatz", "Wiehernder-Wachtmeister", "Apfelschimmel-Alarm", "Einsatz-Einhorn", "Zuckerwürfel-Zerstörer", "Möhren-Mafia", "Galoppierende-Gesetzeslage", "Trab-Titan", "Sattel-Sheriff", "Der Amtsschimmel", "Kaltblut-Kommando", "Vollblut-Vollstrecker", "Huf-Hooligan", "Striegel-Streife", "Fliegende Mähne", "Gras-Antrieb", "Bio-Bulle", "Das letzte Einhorn", "Vierhufer-Vortrupp", "Heu-Highway-Patrol", "Koppel-Cop", "Äppel-Produzent", "Fliegen-Schreck", "Staub-Aufwirbler", "Hindernis-Hasser", "Karotten-Kurier", "Panik-Pferd", "Gemüse-Vernichter", "Hengst", "Rappe", "Schimmel", "Fuchs", "Wallach", "Streitross", "Husar", "Ulan", "Dragoner", "Kürassier", "Zentaur", "Gaul" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } }, polizei: { name: "Freund & Helfer", emoji: "🚓", targetVehicleTypes: { 32: 'FuStW', 95: 'Polizeimotorrad', 50: 'GruKw', 52: 'GefKw', 98: 'Zivilstreifenwagen' }, largeVehicleIds: [52, 50], nameGenerator: function(isLarge = false) { const praefixe = ["Streifen-", "Einsatz-", "Alarm-", "Zivil-", "Sonder-", "Verfolgungs-", "Fahndungs-", "Razzia-", "Blaulicht-", "Beweis-", "Zugriffs-", "Observierungs-", "Protokoll-", "Paragraphen-", "Sicherungs-", "Abschnitts-", "Kripo-", "Soko-"]; const adjektive = ["Strenger", "Wachsamer", "Schneller", "Unbestechlicher", "Eiserner", "Gesetzestreuer", "Müder", "Harter", "Cooler", "Kompromissloser", "Unerbittlicher", "Hartnäckiger", "Präziser", "Observierender", "Schlafloser", "Bürokratischer", "Unnachgiebiger", "Verdeckter", "Ermittelnder"]; const namen = [ "Gesetzeshüter", "Wachtmeister", "Kommissar", "Ermittler", "Sheriff", "Richter", "Ordnungshüter", "Fahnder", "Detektiv", "Spürhund", "Adlerauge", "Inspektor", "Marshall", "Vollstrecker", "Wächter", "Kopfgeldjäger", "Spürfuchs", "Wachhund", "Bluthund", "Habicht", "Hauptmeister", "Zivilfahnder", "Asphalt-Cowboy", "Profiler", "Schatten", "Ermittlungsrichter", "Staatsanwalt", "Kriminaltechniker", "Haftbefehl", "Alibi", "Protokoll", "Indiz", "Ermittlungsakte", "Rapport", "Zeugenaussage", "Täterprofil", "Gerechtigkeit", "Ordnung", "Gesetz", "Prävention", "Strafprozessordnung", "Eilverfahren", "Platzverweis", "Diebstahl", "Betrug", "Nötigung", "Zeugenvernehmung", "Funkdisziplin", "Lagebild", "Schutzweste", "Bodycam", "Radarpistole", "Alkomat", "Spurensicherungskoffer", "Strafantrag", "Sicherstellung", "Personalienfeststellung", "Donut-Vernichter", "Kaffee-Kocher", "Strafzettel-Baron", "Knöllchen-König", "Akten-Schlepper", "Kaffee-Junkie", "Donut-Inspektor", "Feierabend-Jäger", "Blitzer-Baron", "Krapfen-Kommando", "Schicht-Schieber", "Verkehrs-Sünder-Schreck", "Dienst-nach-Vorschrift-Mobil", "Berufsverkehr-Bremser", "Paragraphen-Pirat", "Bürokratie-Beschleuniger", "Falschparker-Feind", "Gähn-Geselle", "Warte-Wachtmeister", "Notizblock-Nervensäge", "Freund und Helfer", "Verwarnungs-Verteiler", "Mängel-Melder", "Streber-Streife", "Amtsmüder Augenzeuge", "Protokoll-Poet", "Donut-Dynamo", "Schicht-Ende-Sehnsucht", "Kaffee-Kommando", "Ordnungs-Macht", "Rechts-Staat", "Schutz-Schild", "Sicherheits-Garant", "Präsenz-Profi", "Streifen-Stratege", "Einsatz-Experte", "Sherlock Holmes", "Dr. Watson", "Hercule Poirot", "Miss Marple", "Philip Marlowe", "Sam Spade", "Columbo", "Kojak", "Derrick", "Schimanski", "Bulle von Tölz", "Tatort-Reiniger", "CSI", "NCIS", "FBI", "BKA", "LKA", "Interpol" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; let baseName = patterns.random()(); if (isLarge) { baseName = `${baseName} ${["(Transport)", "(Schwerlast)", "(Zellenblock)", "(Mannschaft)"].random()}`; } return baseName; } }, rettung: { name: "Blaulicht-Taxis", emoji: "🚑", targetVehicleTypes: { 28: 'RTW', 73: 'GRTW', 29: 'NEF', 74: 'NAW', 38: 'KTW', 58: 'KTW Typ B', 97: 'ITW', 60: 'GW-San' }, largeVehicleIds: [73, 60], nameGenerator: function(isLarge = false) { const praefixe = ["Notfall-", "Rettungs-", "Pflaster-", "Pillen-", "Blaulicht-", "Kaffee-", "Herz-", "Klinik-", "Intensiv-", "Trauma-", "EKG-", "Defi-", "Adrenalin-", "Lebens-", "Aua-"]; const adjektive = ["Schneller", "Eiliger", "Müder", "Geduldiger", "Piepsender", "Desinfizierter", "Lebensrettender", "Stabiler", "Ruhiger", "Hektischer", "Pulsierender", "Steriler", "Diagnostischer", "Beruhigender"]; const namen = [ "Samariter", "Lebensretter", "Schutzengel", "Notarzt", "Sanitäter", "Ersthelfer", "Chirurg", "Anästhesist", "Erstversorger", "Schutzpatron", "Weißer Ritter", "Desinfektor", "Seelentröster", "Florence Nightingale", "Robert Koch", "Ignaz Semmelweis", "Puls", "Trauma-Team", "Diagnose", "Lebensfunke", "Hoffnung", "Zweite-Chance", "Adrenalin-Stoß", "Infusion", "Venenkatheter", "Herzkammer", "Aorta", "Sinusknoten", "Stethoskop", "Blutdruck-Manager", "EKG-Schreiber", "Defibrillator", "Atropin", "Intubation", "Thoraxdrainage", "Glukose", "Schockraum", "Intensivstation", "Vakuummatratze", "Schaufeltrage", "Anaphylaxie", "Pillen-Taxi", "Aua-Wagen", "Schnupfen-Express", "Blaulicht-Bote", "Herzensbrecher", "Schock-Therapeut", "Kaffee-Kurier", "Pulsschubser", "Husten-Taxi", "Männer-Schnupfen-Mobil", "Jammer-Lappen-Jäger", "Wehwehchen-Wagen", "Hypochonder-Heiland", "Bettenschubser", "Asphalt-Ambulanz", "Heftpflaster-Held", "Kaffee-Infusion", "Legebatterie", "Simulanten-Scanner", "Aspirin-Apostel", "RTW-Chauffeur", "Pflaster-Kleber", "Diagnose-Dilettant", "Simulanten-Schreck", "Husten-Held", "Schnupfen-Sheriff", "Fieber-Fighter", "Kopfweh-Kavalier", "Papierschnitt-Panik", "Männergrippe-Märtyrer", "Hypochonder-Hotline", "Placebo-Patrouille", "Krankenschein-Kurier", "Rettungs-Rambo", "Notfall-Nanny", "Blaulicht-Baron" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; let baseName = patterns.random()(); if (isLarge) { baseName = `${baseName} ${["Klinik-Shuttle", "Maxi-Ambulanz", "Betten-Transporter", "Katastrophen-Helfer"].random()}`; } return baseName; } }, seenotrettung: { name: "Seenotrettung", emoji: "🚢", targetVehicleTypes: { 159: 'Seenotrettungskreuzer', 160: 'Seenotrettungsboot' }, nameGenerator: function(isLarge = false) { const praefixe = ["Küsten-", "Hochsee-", "Sturm-", "Wellen-", "See-", "Meeres-", "Orkan-", "Hafen-", "Tiden-", "Brandungs-", "Salzwasser-", "Gischt-"]; const adjektive = ["Salziger", "Stürmischer", "Unsinkbarer", "Verwegener", "Rostiger", "Heldenhafter", "Wellenbrechender", "Seetüchtiger", "Tapferer", "Standhafter"]; const namen = [ "Seebär", "Kapitän", "Pirat", "Freibeuter", "Klabautermann", "Neptun", "Poseidon", "Hafenmeister", "Leuchtturmwärter", "Triton", "Ägir", "Ran", "Störtebeker", "Nautilus", "Kolumbus", "Magellan", "Vasco da Gama", "Kraken", "Leviathan", "Moby Dick", "Fliegender Holländer", "Charybdis", "Hydra", "Scylla", "Jörmungandr", "Sextant", "Kompass", "Brandung", "Gischt", "Tide", "Welle", "Düne", "Boje", "Fender", "Poller", "Kiel", "Takelage", "Sturmflut", "Orkanböe", "Kreuzsee", "Titanic", "Bismarck", "Calypso", "Santa Maria", "Mayflower", "Discovery", "Endeavour", "Victoria", "Gorck Fock", "Passat", "Pamir", "Peking", "Rost-Ritter", "Salzwasser-Sänfte", "Wellen-Bezwinger", "Möwen-Schreck", "Fischkutter-Freund", "Eiserner-Wal", "Nasser-Held", "Hafen-Hirte", "Deich-Defender", "Salzwasser-Seelsorger", "Krabben-Kumpel", "Container-Cop", "Treibgut-Taxi", "Wellen-Wiege", "Orkan-Organisator", "Sturm-Stratege", "Rostlauben-Retter", "Möwen-Motel", "Nebel-Navigator", "Kompass-Korrektor", "Albatros", "Kormoran" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } }, spezialeinheiten: { name: "SEK / MEK", emoji: "💀", targetVehicleTypes: { 79: 'SEK - ZF', 80: 'SEK - MTF', 81: 'MEK - ZF', 82: 'MEK - MTF', 72: 'WaWe 10' }, largeVehicleIds: [72], nameGenerator: function(isLarge = false) { const praefixe = ["Zugriffs-", "Taktik-", "Schatten-", "Sturm-", "Alpha-", "Omega-", "Nacht-", "Kobra-", "Phantom-", "Kommando-", "Delta-", "Zero-", "Stahl-", "Titan-", "Wolfs-"]; const adjektive = ["Stiller", "Präziser", "Eiserner", "Scharfer", "Chirurgischer", "Unerbittlicher", "Kompromissloser", "Getarnter", "Gepanzerter", "Lautloser", "Skrupelloser", "Finaler", "Letzter"]; const namen = [ "Jäger", "Greifer", "Vollstrecker", "Brecher", "Phantom", "Schatten", "Operator", "Kommando", "Scharfschütze", "Geist", "Henker", "Wächter", "Wolf", "Hyäne", "Schakal", "Viper", "Kobra", "Cerberus", "Nighthawk", "Valkyrie", "Chimäre", "Mantikor", "Gorgone", "Hydra", "Spectre", "Reaper", "Pointman", "Breacher", "GSG 9", "SAS", "Spetsnaz", "GIGN", "Navy Seal", "KSK", "Nemesis", "Thanatos", "Ares", "Charon", "Styx", "Hades", "Anubis", "Zugriff", "Observation", "Belagerung", "Sturm", "Sicherung", "Eskorte", "Protokoll-Omega", "Letzte-Instanz", "Vergeltung", "Furcht", "Zugriffs-Korridor", "Observationsteam", "Silent Entry", "Room Clearing", "Projekt Cerberus", "Operation Nachtnebel", "Böser Onkel", "Tür-Eintreter", "Verhandlungs-Verweigerer", "Fenster-Gucker", "Pizza-Besteller", "Nachtschattengewächs", "Leisetreter", "Ramme-Ramme", "Poltergeist", "Wand-Wackler", "Party-Crasher", "Überraschungsgast", "Spaß-Bremse", "Fenster-Einklatscher", "Adrenalin-Junkie", "Lautlos-Lurker", "Tango-Down-Team", "Schwarze-Witwe", "Höllen-Hund", "Stahl-Faust", "Bitte nicht stören", "Klopfen war gestern", "Nihilist", "Stoiker", "Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliett", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-Ray", "Yankee", "Zulu" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } }, technik: { name: "Strom-Junkies", emoji: "⚡", targetVehicleTypes: { 110: 'NEA50', 111: 'NEA50', 112: 'NEA200', 113: 'NEA200', 122: 'LKW 7 Lbw (FGr E)', 171: 'GW TeSi', 172: 'LKW Technik (Notstrom)', 173: 'MTW TeSi', 174: 'Anh TeSi', 175: 'NEA50' }, nameGenerator: function(isLarge = false) { const praefixe = ["Strom-", "Spannungs-", "Kabel-", "Notstrom-", "Technik-", "Sicherungs-", "Elektronik-", "Werkstatt-", "Licht-", "Phasen-"]; const adjektive = ["Elektrischer", "Spannungsgeladener", "Funktionierender", "Provisorischer", "Zertifizierter", "Verkabelter", "Leuchtender", "Summender", "Brummender", "Funkenschlagender"]; const namen = [ "Nikola Tesla", "Thomas Edison", "Georg Ohm", "James Watt", "Michael Faraday", "Alessandro Volta", "Werner von Siemens", "Robert Bosch", "MacGyver", "Daniel Düsentrieb", "Artur Fischer", "Q", "Doc Brown", "Volt", "Ampere", "Watt", "Kilowatt", "Megawatt", "Widerstand", "Kondensator", "Transformator", "Kurzschluss", "Spannungsspitze", "Lichtbogen", "Phase", "Nullleiter", "Frequenz", "Gleichstrom", "Wechselstrom", "Starkstrom", "Schraubenschlüssel", "Lötkolben", "Multimeter", "Oszilloskop", "Werkbank", "Schraubstock", "Kabeltrommel", "Kabelbinder", "Lüsterklemme", "Phasenprüfer", "Seitenschneider", "Krimpzange", "Abisolierzange", "Steckdose", "Sicherheitsprotokoll", "VDE-Prüfung", "Schaltplan", "Notstromversorgung", "Blackout-Prävention", "Redundanz", "USV-Anlage", "Netzersatzanlage", "Generator", "Aggregat", "Diesel", "Feldverteiler", "Server-Rack", "Patchkabel", "Firewall", "Router", "Switch", "Der Admin", "IT-Support", "Helpdesk", "Ticket #1", "Kaffee-Maschinen-Retter", "Sicherungs-Finder", "Kabel-Chaos-Kommando", "Spannungs-Abfall", "Lötkolben-Cowboy", "Provisoriums-Profi", "Admin-Mobil", "Strom-Dealer", "Licht-Macher", "Phasen-Phantomas", "Isolierband-Künstler", "Ein Funke Hoffnung", "Wackelkontakt-Wächter", "Blackout-Buddy", "Saft-Spender", "Dauer-Summton", "Brumm-Bär", "Kriechstrom-Kavalier", "Widerstands-Nest", "Kondensator-Knall", "Trafo-Häuschen", "Lichtbogen-Larry", "Phasen-Prügler", "Nullleiter-Nörgler", "Frequenz-Freak", "Gleichstrom-Gott", "Wechselstrom-Willi", "Starkstrom-Stalin", "Schraubenschlüssel-Schwinger", "Lötkolben-Lord", "Multimeter-Magier", "Oszilloskop-Operator", "Werkbank-Wüterich", "Schraubstock-Sheriff", "Kabeltrommel-König", "Kabelbinder-Künstler", "Lüsterklemmen-Legende", "Phasenprüfer-Papst", "Seitenschneider-Samurai", "Krimpzangen-Kaiser", "Steckdosen-Stratege", "Protokoll-Pirat", "VDE-Veteran", "Schaltplan-Schamane", "Blackout-Bezwinger", "Redundanz-Ritter", "USV-Uhu", "NEA-Nomade", "Generator-Genie", "Aggregat-Admiral", "Diesel-Don", "Feldverteiler-Fürst", "Server-Sanitäter", "Patchkabel-Pionier", "Firewall-Fighter", "Router-Rambo", "Switch-Schlächter", "Admin-Apostel", "IT-Imperator", "Helpdesk-Held", "Ticket-Terminator", "Kaffee-Krieger", "Sicherungs-Samurai", "Kabel-Künstler", "Spannungs-Sultan", "Löt-Lama", "Profi-Pfuscher", "Not-Nagel", "Licht am Ende des Tunnels", "Der Erleuchter", "Der letzte Funke", "Der Strom-Scheich", "Letzte Sicherung", "Die dritte Phase", "Der goldene Stecker", "Der rote Knopf", "Der blaue Draht", "Der grüne Draht", "Der schwarze Draht", "Der braune Draht", "Technik, die begeistert", "Vorsprung durch Technik", "Das Beste oder Nichts", "Freude am Fahren", "Nichts ist unmöglich", "Geht nicht, gibt's nicht", "Wer A sagt, muss auch B sagen", "Was nicht passt, wird passend gemacht", "Das muss so", "Das war schon so", "Das hält", "Das wird schon halten", "Das ist nur provisorisch", "Das machen wir später richtig", "Da ist der Wurm drin", "Da liegt der Hase im Pfeffer", "Da beißt die Maus keinen Faden ab", "Da steppt der Bär", "Da lachen ja die Hühner", "Da wird der Hund in der Pfanne verrückt", "Da brat mir einer einen Storch", "Da pfeift der Papst im Kettenhemd", "Da geht die Post ab", "Da ist Holland in Not", "Da ist Polen offen", "Da ist was im Busch", "Da ist der Teufel los", "Hauptsache es funktioniert", "Wenn's blitzt, war's richtig", "Kurzschluss mit Ansage", "Rauchzeichen-Generator", "Der Zähler-Dreher", "Elektro-Schocker", "Kabel-Salat-Bar", "Das fliegende Provisorium", "Der Funken-Sprayer", "Der Entstörer", "Der Instandsetzer", "Der System-Administrator", "Der Netzwerk-Techniker", "Der Elektroniker", "Der Elektriker", "Der Mechaniker", "Der Mechatroniker", "Der Ingenieur", "Der Techniker", "Der Monteur", "Der Installateur", "Der Hausmeister", "Der Facility-Manager", "Das Multitalent", "Der Alleskönner", "Der Tausendsassa", "Der Wunderwuzzi", "Der MacGyver des kleinen Mannes", "Der A-Team-Transporter" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } }, thw: { name: "Blaue Wichtel", emoji: "🛠️", targetVehicleTypes: { 40: 'MTW-TZ', 41: 'MzGW (FGr N)', 42: 'LKW K 9', 43: 'BRmG R', 44: 'Anh DLE', 45: 'MLW 5', 93: 'MTW-O', 100: 'MLW 4', 101: 'Anh SwPu', 102: 'Anh 7', 109: 'MzGW SB', 123: 'LKW 7 Lbw (FGr WP)', 124: 'MTW-OV', 39: 'GKW', 65: 'LKW 7 Lkr 19 tm' }, nameGenerator: function(isLarge = false) { const praefixe = ["Technik-", "Hilfs-", "Bau-", "Logistik-", "Räum-", "Stütz-", "Pumpen-", "Generator-", "Blau-", "Wichtel-", "Chaos-", "Paletten-", "Kabel-", "Schlumpf-", "Trümmer-", "Beton-", "Holz-", "Stahl-"]; const adjektive = ["Blauer", "Technischer", "Hilfsbereiter", "Verplanter", "Chaotischer", "Stabiler", "Schwerer", "Tragender", "Leuchtender", "Unermüdlicher", "Kreativer", "Solider", "Standfester", "Robuster"]; const namen = [ "Wichtel", "Schlumpf", "Helfer", "Pionier", "Logistiker", "Ingenieur", "Baumeister", "Maschinist", "Anpacker", "Fachberater", "Ortsbeauftragter", "Bastler", "Tüftler", "Konstrukteur", "Statiker", "Truppführer", "Baufachberater", "Kraftfahrer", "Baukasten", "Stütze", "Fundament", "Generator", "Pumpe", "Hebel", "Getriebe", "Werkzeugkiste", "Palette", "Gitterbox", "Einsatzbefehl", "Lichtmast", "Strom-Aggregat", "Presslufthammer", "Trennschleifer", "Hydraulik-Spreizer", "Betonkettensäge", "Stahlträger", "Sandsack", "Tauchpumpe", "Notstromaggregat", "Hebekissen", "Kernbohrgerät", "Plasmabrenner", "Verbrauchsgut", "Abstützung", "Hochwasser-Helfer", "Sturmschaden-Beseitiger", "Blaue-Eminenz", "Chaos-Kommando", "Wichtel-Express", "Technik-Trouble", "Paletten-Polo", "Kabel-Salat-Express", "Schlumpf-Transporter", "Hüpfburg-Aufbauer", "Kaffee-Versorger", "THW-Taxi", "Tausend-Hilflose-Wichtel", "Toll-ein-Anderer-Machts", "Teile-Hin-und-Weg", "Legoland-für-Erwachsene", "Gitterbox-Ballett", "Katastrophen-Touristen-Betreuung", "Unter Helfersyndrom Leidende", "Blaulicht-Tetris", "Deich-Verteidiger", "Keller-Leer-Pumper", "Sandsack-Schlepper-Syndikat", "Stapel-Stratege", "Überall-Helfer", "Ich-kann-das-reparieren", "Der-Gerade-Bieger", "Blauer Engel mit Werkzeugkoffer", "Katastrophen-Kaffeekränzchen", "Stapel-Champion", "Alles-Kleber", "Gaffer-Abschirmung", "Strom-Dealer", "Licht-Bringer", "Pumpen-Paganini", "Räum-Rambo", "Stütz-Stalin", "Logistik-Lord", "Bau-Baron", "Technik-Titan", "Hilfs-Held", "Wichtel-Wunder", "Schlumpf-Sheriff", "Trümmer-Troll", "Beton-Beißer", "Holz-Hobbit", "Stahl-Stier", "Paletten-Papst", "Kabel-König", "Generator-Genie", "Stapel-Sultan", "Universal-Dilettant", "Hoffnung in Blau", "Technik die begeistert", "Wo ist die Anleitung?", "Ehrenamts-Einhorn", "Material-Magier", "Feld-Faktotum", "Not-Nagel", "Krisen-Künstler", "Lage-Löser", "Problem-Pflaster", "Sorgen-Schlichter", "Unwetter-Uhu", "Sturm-Stratege", "Flut-Flüsterer", "Chaos-Chirurg", "Pannen-Pionier", "Rettungs-Ritter", "Hilfs-Heiland", "Technik-Teufel", "Blauer Riese", "Der Zupacker", "Der Macher", "Der Kümmerer", "Die Hoffnung", "Der Fels in der Brandung", "Der Alleskönner", "Das Schweizer Taschenmesser", "Der Problemlöser", "Der Unverzichtbare", "Der Held vom Erdbeerfeld", "Der letzte Ausweg", "Der Joker", "Die blaue Wand", "Der Fels", "Der Anker", "Der Leuchtturm", "Der Felsblock", "Die Stütze der Gesellschaft", "Der blaue Blitz", "Der blaue Donner", "Der blaue Sturm", "Der blaue Orkan", "Der blaue Tsunami", "Der blaue Vulkan", "Der blaue Komet", "Der blaue Meteor", "Der blaue Gigant", "Der blaue Titan", "Der blaue Koloss", "Der blaue Goliath", "Der blaue Herkules", "Der blaue Samson", "Der blaue Atlas", "Der blaue Odysseus", "Der blaue Achilles", "Der blaue Hektor", "Blaulicht-Bobbycar", "Trümmer-Taxi", "Schraubenschlüssel-Express", "Gummistiefel-Galopper", "Sandsack-Schlepper", "Diesel-Dino", "Technikhure", "Blaulicht-Bolide", "Aggregat-Anhänger Deluxe", "Kistenkutsche", "Allrad-Asi", "Stromschubse", "GKW-Gott", "Pressluft-Panzer", "Pannenpanzer", "Bierbank-Bomber", "Blaumann-Bus", "Wasserwand-Walze", "Trümmer-Trecker", "Kaffeekannen-Kurier", "Sandsack-Sprinter", "Generator-Gurke", "Baustellen-Buggy", "Blaulicht-Bumsbude", "Schlamm-Schleuder", "Schrauber-Schrottkarre", "Hilfsarbeiter-Hotrod", "Diesel-Dampflok", "Werkzeug-Wagen", "Flut-Ferrari", "Matschmobil", "Aggregate-Ami", "Pritschen-Porsche", "Schrottkutscher", "Notstrom-Nobelhobel", "Katastrophenkutsche", "Kabel-Kutsche", "Blaulicht-Bauer", "Brücken-Bulldogge", "Sandsack-Schubser", "Techniktanker", "Blaumann-Bomber", "Gerümpel-Gefährt", "Flutwalze", "Katastrophen-Kart", "GKW-Gaudi-Mobil", "Blaulicht-Bettmobil", "Diesel-Dickschiff", "Einsatz-Esel", "Trümmertraktor" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } }, wasserrettung: { name: "Wasserrettung", emoji: "🚤", targetVehicleTypes: { 63: 'GW-Taucher', 64: 'GW-Wasserrettung', 70: 'MZB', 66: 'Anh MzB', 67: 'Anh SchlB', 68: 'Anh MzAB', 69: 'Tauchkraftwagen', 71: 'AB-MZB' }, nameGenerator: function(isLarge = false) { const praefixe = ["Fluss-", "See-", "Tauch-", "Wasser-", "Wellen-", "Strömungs-", "Ufer-", "Sonar-", "Tiefen-", "Schlick-", "Neopren-"]; const adjektive = ["Nasser", "Tiefer", "Blubbernder", "Kalter", "Schneller", "Leckgeschlagener", "Schwimmender", "Tauchender", "Feuchter", "Klammer", "Glitschiger"]; const namen = [ "Froschmann", "Kapitän", "Pirat", "Matrose", "Taucher", "Retter", "Wasserratte", "Fluss-Sheriff", "Bademeister", "Otter", "Biber", "Hecht", "Zander", "Wassermann", "Nixe", "Wels", "Kormoran", "Anker", "Schraube", "Sonar", "Rettungsring", "Schlauchboot", "Tauchglocke", "Periskop", "Tiefenmesser", "Schleuse", "Kielwasser", "Strömung", "Neoprenanzug", "Druckluftflasche", "Tauchcomputer", "Trockenanzug", "Hebesack", "Sprungschicht", "Dekompression", "Rhein", "Donau", "Elbe", "Bodensee", "Müritz", "Chiemsee", "Quietsche-Ente", "Bade-Ente", "Gummiboot", "Seepferdchen", "Feuchter-Traum", "Planschbecken-Patrouille", "Unterwasser-Staubsauger", "Schlick-Schlitten", "Blubber-Blitz", "Abtaucher", "Nasser-Willy", "Amphibien-Ambulanz", "Wellen-Reiter", "Fisch-Schreck", "Algen-Mäher", "Schilf-Schneider", "Ente-Nass", "Badewannen-Admiral", "Schlamm-Wühler", "Anker-Auswerfer", "Forelle", "Karpfen", "Aal", "Barsch", "Plötze", "Brachse", "Rotfeder", "Ukelei", "Gründling" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => { const name = namen.random(); if (name.includes(' ')) return name; return `${praefixe.random()}${name}`; } ]; return patterns.random()(); } }, drohnen: { name: "Himmels-Augen", emoji: "👁️", targetVehicleTypes: { 125: 'MTW-Tr UL', 126: 'MTF Drohne', 127: 'GW UAS' }, nameGenerator: function(isLarge = false) { const praefixe = ["Späh-", "Luft-", "Sky-", "Cyber-", "Aero-", "Aufklärungs-", "Sensor-", "Daten-", "Überwachungs-", "Adler-", "Falken-", "Geister-", "Leise-", "Rotor-", "Kamera-", "Zoom-", "Pixel-", "GPS-"]; const adjektive = ["Schwebender", "Leiser", "Digitaler", "Allsehender", "Gestochen-Scharfer", "Taktischer", "Unbemerkter", "Summender", "Neugieriger", "Pixeliger", "Versteckter", "Autonomer", "Schwirrender", "Kühler", "Windiger"]; const namen = [ "Auge", "Spion", "Libelle", "Kolibri", "Moskito", "Schabe", "Wespe", "Hornisse", "Biene", "Falke", "Adler", "Bussard", "Habicht", "Geier", "Uhu", "Eule", "Geist", "Schatten", "Phantom", "Späher", "Beobachter", "Wächter", "Vogel", "Kamera", "Objektiv", "Sensor", "Pixel", "Zoom", "Gimbal", "Rotor", "Propeller", "Akku", "Videosignal", "Datenstrom", "Koordinaten", "Satellit", "GPS", "Big Brother", "Auge des Horus", "Auge Saurons", "Orwell", "Skynet", "Die Wanze", "Der Lauschangriff", "Area 51", "Roswell", "UFO", "Reaper", "Predator", "Global Hawk", "Watchkeeper", "Heron", "Luna", "Aladin", "Mücke", "KZO", "Taranis", "Neuron", "X-47B", "Hugin", "Munin", "Valkyrie", "Heimdall", "Argus", "Cyclops", "Wanze", "Spy-Copter", "Nerd-Spielzeug", "Teures Spielzeug", "Propeller-Paparazzi", "Gaffer-aus-der-Luft", "Summ-Summ", "Brumm-Brumm", "Schwebestativ", "Selfie-Stick 3.0", "Nachbars-Schreck", "Vogel-Schreck", "Amazon-Paketbote", "Pizzabote 2030", "Eindringling", "Luftikus", "Hochstapler", "Der neugierige Nachbar", "Der Spanner", "Das fliegende Auge", "Die schwebende Linse", "Der digitale Bote", "Der lautlose Jäger", "Der unsichtbare Dritte", "Die Wahrheit von Oben", "Der Wolken-Wanderer", "Der Wind-Reiter", "Der Himmels-Stürmer", "Lagebild", "Aufklärung", "Überwachung", "Zielerfassung", "Live-Feed", "HD-Stream", "4K-Auflösung", "Nachtsicht", "Wärmebild", "Infrarot", "Laser-Designator", "Taktische-Drohne", "Mikro-Drohne", "Nano-Drohne", "Quadrocopter", "Hexacopter", "Octocopter", "Starrflügler", "VTOL", "Schwarm", "Drohnen-Schwarm", "Kollektiv", "Das Nest", "Der Bienenstock", "Die Brut", "Der Schwarmgeist", "Legion", "Hydra", "Myriade", "Flächenüberwachung", "Personensuche", "Rehkitz-Rettung", "Glutnest-Finder", "Unfall-Dokumentation", "Lage-aus-der-Luft", "Einsatz-Unterstützung", "Luft-Lage", "Der Überflieger", "Der Gipfelstürmer", "Der Wolkenkratzer", "Der Himmels-Fahrer", "Der Luft-Pirat", "Der Wolken-Segler", "Der Wind-Tänzer", "Der Himmels-Gleiter", "Der Luft-Akrobat", "Der Wolken-Springer", "Der Wind-Jongleur", "Der Himmels-Magier", "DJI Phantom", "DJI Mavic", "DJI Inspire", "Parrot Anafi", "Yuneec Typhoon", "Autel Evo", "Skydio", "PowerEgg", "AirDog", "GoPro Karma", "3DR Solo", "Walkera Voyager", "Cheerson CX-20", "Hubsan X4", "Syma X5C", "Eachine E58", "Ryze Tello", "Blade Nano", "Fat Shark", "ImmersionRC", "RaceFlight", "Betaflight", "Cleanflight", "iNav", "ArduPilot", "Pixhawk", "FrSky Taranis", "Spektrum DX", "GoPro Hero", "RunCam", "Foxeer", "Caddx", "FPV", "First Person View", "Line of Sight", "BVLOS", "Beyond Visual Line of Sight", "U-Space", "Geo-Fencing", "No-Fly-Zone", "Return to Home", "RTH", "Waypoint Navigation", "Follow Me", "Orbit Mode", "ActiveTrack", "Point of Interest", "Headless Mode", "Altitude Hold", "Optical Flow", "Ultrasonic Sensor", "LIDAR", "SLAM", "GCS", "Ground Control Station", "Telemetry", "OSD", "On-Screen Display", "LiPo Battery", "Brushless Motor", "ESC", "Electronic Speed Controller", "Flight Controller", "PDB", "Power Distribution Board", "VTX", "Video Transmitter" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } }, flughafen: { name: "Kerosin-Kutscher", emoji: "✈️", targetVehicleTypes: { 75: 'FLF', 76: 'Rettungstreppe' }, nameGenerator: function(isLarge = false) { const praefixe = ["Flugfeld-", "Airport-", "Crash-", "Turbinen-", "Gate-", "Tower-", "Kerosin-", "Runway-", "Vorfeld-", "Terminal-", "Hangar-", "Landebahn-", "Startbahn-", "Follow-Me-", "Pushback-"]; const adjektive = ["Breiter", "Schneller", "Schwerer", "Schaumiger", "Titan-", "Gigantischer", "Donnernder", "Internationaler", "Interkontinentaler", "Regionaler", "Leuchtender", "Blinkender", "Rollender", "Startklarer"]; const namen = [ "Panther", "Dragon", "Striker", "Tiger", "Simba", "Ziegler", "Rosenbauer", "Oshkosh", "IVECO", "Sides", "Kronenburg", "Z-Class", "Advancer", "Buffalo", "Cobra", "Falcon", "Viper", "Puma", "Leopard", "Follow-Me-Car-Schreck", "Gate-Goliath", "Runway-Retter", "Turbinen-Tornado", "Flügel-Flüsterer", "Boeing-Bezwinger", "Airbus-Albtraum", "Concorde-Cop", "Tower-Titan", "Pushback-Panzer", "Vorfeld-Vulkan", "Terminal-Terminator", "Hangar-Held", "Landebahn-Legende", "Startbahn-Stratege", "Kerosin-König", "Schaum-Schläger", "Pulver-Prinz", "Wasser-Werfer", "Cockpit-Cleaner", "Triebwerks-Tester", "Reifen-Rächer", "Winglet-Wächter", "Fahrwerks-Fighter", "Leitwerks-Lord", "Rumpf-Ritter", "Frachtraum-Freund", "Gepäck-Gott", "Passagier-Papst", "Pilot-Pate", "Fluglotsen-Freund", "Boden-Crew-Boss", "Vogel-Schreck", "Bird-Strike-Blocker", "Enteisungs-Eroberer", "Nebel-Navigator", "Scherwind-Schild", "Aquaplaning-Ass", "FOD-Finder", "Foreign-Object-Damage", "Marshaller", "Einwinker", "Gangway-Garant", "Fluggastbrücken-Freund", "Zoll-Zerstörer", "Sicherheits-Sultan", "Duty-Free-Dompteur", "Last-Call-Löscher", "Boarding-Beender", "Take-Off-Titan", "Landing-Lord", "Touchdown-Terminator", "Schubumkehr-Schreck", "Bremsklappen-Bezwinger", "Autopilot-Abschalter", "Mayday-Meister", "Pan-Pan-Pionier", "Notrutschen-Navigator", "Schwimmwesten-Spezialist", "Sauerstoffmasken-Samariter", "Der-rote-Baron", "Die-fliegende-Festung", "Der-Stahl-Adler", "Der-Schaum-Teppich", "Der-Pulver-Puster", "Die-Wasser-Wand", "Der-letzte-Check", "Der-klare-Kanal", "Cleared-for-Take-Off", "Final-Approach", "Roger-That", "Alpha-Bravo-Charlie", "ICAO-Code-Kenner", "IATA-Code-Imperator", "A380-Amigo", "B747-Buddy", "Jumbo-Jet-Jäger", "Dreamliner-Dompteur", "Air-Force-One-Assistent", "Beluga-Beschützer", "Antonov-Anpacker", "Cessna-Crasher", "Learjet-Löscher", "Gulfstream-Garant", "Challenger-Champion", "Global-Express-Gott", "Citation-Zerstörer", "Embraer-Eroberer", "Fokker-Fighter", "McDonnell-Douglas-Meister", "Lockheed-Lord", "Tupolev-Titan", "Iljuschin-Imperator", "Suchoi-Sultan", "MiG-Magier", "Eurofighter-Eskorte", "Tornado-Tamer", "Raptor-Retter", "Lightning-Löscher", "Blackbird-Blocker", "Spirit-Spezialist", "U-2-Unterstützer", "AWACS-Aufpasser", "Tanker-Terminator", "Transall-Trapper", "Hercules-Held", "Globemaster-Gott", "Galaxy-Gigant", "Stratotanker-Stratege", "C-130", "A400M", "C-5", "C-17", "KC-135", "KC-10", "E-3", "RC-135", "F-15", "F-16", "F-22", "F-35", "Su-57", "J-20", "Gripen", "Rafale", "Typhoon", "MiG-29", "Su-27" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } }, gefahrgut: { name: "Giftmischer", emoji: "☣️", targetVehicleTypes: { 53: 'Dekon-P', 27: 'GW-Gefahrgut', 12: 'GW-Messtechnik', 5: 'GW-A', 77: 'AB-Gefahrgut', 54: 'AB-Dekon-P', 48: 'AB-Atemschutz' }, nameGenerator: function(isLarge = false) { const praefixe = ["Chemie-", "Gift-", "Säure-", "Strahlen-", "Deko-", "ABC-", "Atom-", "Bio-", "Gas-", "Mess-", "Spür-", "Analyse-", "Labor-", "Isotopen-", "Molekül-", "Proben-", "Filter-", "Schutz-"]; const adjektive = ["Ätzender", "Giftiger", "Radioaktiver", "Dichter", "Sicherer", "Hermetischer", "Analytischer", "Gefährlicher", "Flüchtiger", "Instabiler", "Reaktiver", "Gekapselter", "Gemessener", "Gefilterter"]; const namen = [ "Walter White", "Heisenberg", "Jesse Pinkman", "Marie Curie", "Fritz Haber", "Paracelsus", "Dr. No", "Dr. Poison", "Joker", "Scarecrow", "Poison Ivy", "Der Pinguin", "Lex Luthor", "Green Goblin", "Pandora's Büchse", "Tschernobyl-Express", "Fukushima-Taxi", "Area 51 Kurier", "C-Waffen-Shuttle", "Säurefass", "Atommüll-Transporter", "Gift-Küche", "Hexen-Küche", "Drogen-Labor", "Mobile-Dusche", "ABC-Schütze", "Mess-Fuchs", "Spür-Hund", "Analyse-Einheit", "Labor-Ratte", "Isotopen-Jäger", "Molekül-Magier", "Proben-Sammler", "Filter-Freak", "Schutzanzug-Chauffeur", "Voll-Gummi", "Gefahr-Gut-Gundel", "Blubber-Blaster", "Atom-Spalter", "Periodensystem-Pendler", "Der-letzte-Tropfen", "Säure-Steven", "Laugen-Larry", "Gas-Gerd", "Strahlen-Sigi", "Deko-Doris", "Mess-Max", "Spür-Simone", "Analyse-Anna", "Labor-Leo", "Isotopen-Ingo", "Molekül-Moni", "Proben-Peter", "Filter-Franz", "Schutz-Susi", "Kleine-Sünde", "Böser-Stoff", "Teufels-Zeug", "Hexen-Gebräu", "Zauber-Trank", "Geigerzähler", "Dosimeter", "PID-Messer", "Prüfröhrchen", "Lackmus-Papier", "pH-Streifen", "Explosimeter", "Interferometer", "Spektrometer", "Chromatograph", "CSA", "Chemikalienschutzanzug", "Pressluftatmer", "Filtermaske", "Dosis", "Becquerel", "Sievert", "Gray", "Rem", "Rad", "Curie", "MAK-Wert", "TRK-Wert", "LD50", "LC50", "UN-Nummer", "Gefahrenzettel", "Gefahren-Diamant", "Auffangwanne", "Bindemittel", "Neutralisationsmittel", "Abdichtmaterial", "Umpump-Armatur", "Erdungs-Stange", "Funkenfreies-Werkzeug", "Dekontamination", "Ein-Zelt-System", "Drei-Zelt-System", "Schwarz-Bereich", "Grau-Bereich", "Weiß-Bereich", "GAMS-Regel", "Gefahr", "Absperrung", "Menschenrettung", "Spezialkräfte", "Absperr-Alex", "GAMS-Günther", "Säure-Samariter", "Laugen-Löscher", "Gas-Gott", "Strahlen-Schamane", "Deko-Dompteur", "Mess-Meister", "Spür-Spezialist", "Analyse-Ass", "Labor-Lord", "Isotopen-Imperator", "Molekül-Meister", "Proben-Papst", "Filter-Fürst", "Schutz-Sultan", "Chemie-Kaiser", "Gift-General", "Säure-Sultan", "Strahlen-Scheich", "Deko-Direktor", "ABC-Admiral", "Atom-Apostel", "Bio-Baron", "Gas-Gigant", "Mess-Magier", "Spür-Souverän", "Alkalimetalle", "Erdalkalimetalle", "Halogene", "Edelgase", "Lanthanoide", "Actinoide", "Übergangsmetalle", "Wasserstoff", "Helium", "Lithium", "Beryllium", "Bor", "Kohlenstoff", "Stickstoff", "Sauerstoff", "Fluor", "Neon", "Natrium", "Magnesium", "Aluminium", "Silicium", "Phosphor", "Schwefel", "Chlor", "Argon", "Kalium", "Calcium", "Scandium", "Titan", "Vanadium", "Chrom", "Mangan", "Eisen", "Cobalt", "Nickel", "Kupfer", "Zink", "Gallium", "Germanium", "Arsen", "Selen", "Brom", "Krypton", "Rubidium", "Strontium", "Yttrium", "Zirconium", "Niob", "Molybdän", "Technetium", "Ruthenium", "Rhodium", "Palladium", "Silber", "Cadmium", "Indium", "Zinn", "Antimon", "Tellur", "Iod", "Xenon", "Caesium", "Barium", "Lanthan", "Cer", "Praseodym", "Neodym", "Promethium", "Samarium", "Europium", "Gadolinium", "Terbium", "Dysprosium", "Holmium", "Erbium", "Thulium", "Ytterbium", "Lutetium", "Hafnium", "Tantal", "Wolfram", "Rhenium", "Osmium", "Iridium", "Platin", "Gold", "Quecksilber", "Thallium", "Blei", "Bismut", "Polonium", "Astat", "Radon", "Francium", "Radium", "Actinium", "Thorium", "Protactinium", "Uran", "Neptunium", "Plutonium" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } }, hubrettung: { name: "Himmelsleitern", emoji: "🪜", targetVehicleTypes: { 57: 'FwK', 2: 'DLK 23', 85: 'TM 50' }, nameGenerator: function(isLarge = false) { const praefixe = ["Leiter-", "Rettungs-", "Gelenk-", "Teleskop-", "Höhen-", "Himmels-", "Turm-", "Wolken-", "Gipfel-", "Dach-", "Balkon-", "Fenster-", "Fassaden-", "Hydraulik-", "Stahl-"]; const adjektive = ["Langer", "Hoher", "Stählerner", "Ausgefahrener", "Hydraulischer", "Standfester", "Schwindelfreier", "Rettender", "Steiler", "Senkrechter", "Gelenkiger", "Massiver", "Eiserner", "Unbeugsamer"]; const namen = [ "Jakobsleiter", "Turm", "Giraffe", "Kranich", "Langer-Gustav", "Ikarus", "Daedalus", "Adlerhorst", "Falkennest", "Aussichtsplattform", "Sprungturm", "Leuchtturm", "Gipfelkreuz", "Wolkenkratzer", "Babylon", "Eiffelturm", "Sears Tower", "Burj Khalifa", "Rapunzel", "Himmelsstürmer", "Senkrechtstarter", "Hochstapler", "Aufzug", "Fahrstuhl", "Korb", "Gondel", "Sessellift", "Mast", "Pfeiler", "Träger", "Ausleger", "Gelenk", "Teleskop", "Hydraulik", "Stempel", "Stütze", "Katzen-Retter", "Feuer-Fahrstuhl", "Balkon-Taxi", "Fenster-Gucker", "Stockwerk-Shuttle", "Umzugs-Helfer", "Gardinen-Aufhänger", "Dachdecker-Traum", "Schornsteinfeger-Freund", "Kirchturm-Kavalier", "Höhen-Angst-Überwinder", "Die-rettende-Hand", "Brücken-Inspektor", "Fassaden-Kletterer", "Der-lange-Arm", "Der-feste-Stand", "Der-sichere-Weg-nach-oben", "Über-den-Dächern", "Blick-von-oben", "Der-Überblick", "Strategische-Position", "Angriffsweg", "Rettungsweg", "Leiterpark", "Hauptabstützung", "Notablass", "Korbsteuerung", "Windmesser", "Nivellierung", "Abstützbreite", "Ausladung", "Rettungshöhe", "Nennrettungshöhe", "Gelenkteil", "Leitersegment", "Rettungskorb", "Krankentragenhalterung", "Wasserwerfer", "Monitor", "Steigleitung", "Lastöse", "Stromerzeuger", "Flutlichtscheinwerfer", "Absturzsicherung", "Gerätekasten", "Schleifkorbtrage", "Sprungpolster", "Kettensäge", "Einreißhaken", "Der-lange-Lulatsch", "Die-lange-Leiter", "Der-rote-Riese", "Der-Stahl-Gigant", "Der-Himmels-Kratzer", "Der-Wolken-Bezwinger", "Der-Gipfel-Erklimmer", "Der-Dach-Besetzer", "Der-Balkon-Besucher", "Der-Fenster-Freund", "Der-Fassaden-Flüsterer", "Der-Hydraulik-Herkules", "Der-Stahl-Stier", "Der-Leiter-Lord", "Der-Gelenk-Gott", "Der-Teleskop-Titan", "Der-Höhen-Held", "Der-Himmels-Heiland", "Der-Turm-Titan", "Der-Wolken-Wächter", "Der-Gipfel-Garant", "Der-Dach-Dompteur", "Der-Balkon-Baron", "Der-Fenster-Fürst", "Der-Fassaden-Feldherr", "Der-Hydraulik-Halbgott", "Der-Stahl-Samurai", "Metz", "Rosenbauer", "Magirus", "Bronto Skylift", "Ruthmann", "Ziegler", "Schlingmann", "Lohr", "Gimaex", "Iveco", "MAN", "Mercedes-Benz", "Scania", "Volvo", "DAF", "Dennis", "E-One", "Pierce", "Seagrave", "Sutphen", "Spartan", "Leitersatz", "Unterleiter", "Mittelleiter", "Oberleiter", "Spitzenteil", "Anlegeleiter", "Schiebleiter", "Steckleiter", "Klappleiter", "Hakenleiter", "Strickleiter", "Seilleiter", "Rettungsleiter", "Feuerleiter", "Drehleiter", "Gelenkmast", "Teleskopmast", "Hubarbeitsbühne", "Hubrettungsbühne", "Rettungsbühne", "Arbeitsbühne", "Steiger", "Kran", "Autokran", "Mobilkran", "Turmdrehkran", "Rettungszylinder", "Hebekissen", "Spreizer", "Schere", "Kombigerät", "Plasmaschneider", "Brennschneidgerät", "Trennschleifer", "Säbelsäge", "Bügelsäge", "Axt", "Beil", "Halligan-Tool", "Feuerwehr-Axt" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } }, schienenfahrzeuge: { name: "Lokomotuffen", emoji: "🚂", targetVehicleTypes: { 162: 'RW-Schiene', 163: 'HLF Schiene' }, nameGenerator: function(isLarge = false) { const praefixe = ["Schienen-", "Gleis-", "Zug-", "Bahn-", "Tunnel-", "Weichen-", "Stellwerks-", "ICE-", "Express-", "Güter-", "Regional-", "Signal-", "Waggon-", "Schwellen-", "Oberleitungs-"]; const adjektive = ["Eiserner", "Ratternder", "Schwerer", "Unaufhaltsamer", "Pünktlicher", "Verspäteter", "Entgleister", "Rostiger", "Quietschender", "Dampfender", "Elektrischer", "Dieselnder", "Tender-"]; const namen = [ "Emma", "Thomas", "Adler", "Rocket", "Puffing Billy", "Big Boy", "Mallard", "Flying Scotsman", "Rheingold", "Orient-Express", "Trans-Siberian Express", "Hogwarts-Express", "Polar-Express", "Geister-Zug", "Bummel-Zug", "Rasender-Roland", "Molly", "Choo-Choo", "Tschuff-Tschuff", "Tuff-Tuff", "Lokführer-Lukas", "Jim Knopf", "Casey Jones", "John Henry", "Schaffner", "Heizer", "Rangierer", "Fahrdienstleiter", "Schienen-Sheriff", "Gleis-Goliath", "Tunnel-Terror", "Weichen-Willi", "Stellwerks-Stratege", "Signal-Sigi", "Bahnübergangs-Blockierer", "Prellbock-Prüfer", "Schotterbett-Schläfer", "Oberleitungs-Olaf", "Der-rote-Baron", "Der-blaue-Enzian", "Der-fliegende-Hamburger", "Der-Gläserne-Zug", "Die-schwäbische-Eisenbahn", "ICE", "TGV", "Shinkansen", "Eurostar", "Thalys", "Railjet", "Pendolino", "Talent", "Desiro", "KISS", "FLIRT", "GTW", "Regio-Shuttle", "LINT", "Alstom Coradia", "Siemens Vectron", "Bombardier TRAXX", "Stadler Eurodual", "Krauss-Maffei", "Henschel", "Krupp", "AEG", "BBC", "Siemens-Schuckert", "Dampflok", "Diesellok", "E-Lok", "Hybridlok", "Schmalspurbahn", "Zahnradbahn", "Schwebebahn", "Magnetschwebebahn", "U-Bahn", "S-Bahn", "Straßenbahn", "Draisine", "Schienenbus", "Triebwagen", "Waggon", "Güterwagen", "Personenwagen", "Speisewagen", "Schlafwagen", "Postwagen", "Kesselwagen", "Containerwagen", "Schüttgutwagen", "Flachwagen", "Rungenwagen", "Schiebewandwagen", "Selbstentladewagen", "Bahnhof", "Haltepunkt", "Stellwerk", "Weiche", "Signal", "Gleis", "Schiene", "Schwelle", "Schotterbett", "Fahrleitung", "Stromabnehmer", "Puffer", "Kupplung", "Bremse", "Rad", "Achse", "Tender", "Kessel", "Feuerbüchse", "Schornstein", "Zylinder", "Treibstange", "Führerstand", "Kohle", "Wasser", "Dampf", "Diesel", "Strom", "Verspätung", "Anschluss", "Fahrplan", "Ticket", "Reservierung", "1.-Klasse", "2.-Klasse", "Zugbindung", "Ersatzverkehr", "Schienenersatzverkehr", "SEV", "Notbremse", "Entgleisung", "Unfall", "Rettungszug", "Hilfszug", "Kranzug", "Lösch-und-Rettungszug", "LRZ", "Tunnel-Task-Force", "Gleis-Läufer", "Der-eiserne-Retter", "Die-rote-Gefahr", "Der-stählerne-Koloss", "Der-Gleis-Gigant", "Der-Tunnel-Tornado", "Der-Weichen-Wächter", "Der-Stellwerks-Sultan", "Der-Signal-Samurai", "Der-Bahn-Baron", "Der-Zug-Zar", "Der-ICE-Imperator", "Der-Express-Eroberer", "Der-Güter-Goliath", "Der-Regional-Ritter", "Der-Waggon-Warlord", "Der-Schwellen-Schreck", "Der-Oberleitungs-Overlord", "Der-Schienen-Schamane", "Der-Gleis-Geist", "Die-Lok-Legende", "Die-Bahn-Bestie", "Der-Tunnel-Teufel", "Der-Weichen-Wüterich", "Der-Stellwerks-Stalin", "Der-Signal-Sultan", "Der-Bahn-Behemoth", "Der-Zug-Titan", "Der-ICE-Ifrit", "Der-Express-Executor", "Der-Güter-Geist", "Der-Regional-Rambo", "Der-Waggon-Wächter", "Der-Schwellen-Schinder", "Der-Oberleitungs-Oger", "Der-Schienen-Scherge", "Der-Gleis-Gladiator", "Die-Lok-Lawine" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } }, schlauchwagen: { name: "Wasser-Autobahn", emoji: "💧", targetVehicleTypes: { 13: 'SW 1000', 14: 'SW 2000', 15: 'SW 2000-Tr', 16: 'SW Kats', 11: 'GW-L2-Wasser', 143: 'Anh Schlauch', 62: 'AB-Schlauch' }, nameGenerator: function(isLarge = false) { const praefixe = ["Schlauch-", "Wasser-", "Leitungs-", "Hydranten-", "Pumpen-", "Druck-", "Förder-", "Nudel-", "Spaghetti-", "Makkaroni-", "Endlos-", "Meter-", "Kilometer-", "Verlege-"]; const adjektive = ["Nasser", "Langer", "Rollender", "Durstiger", "Praller", "Gefüllter", "Undichter", "Gekuppelter", "Verknoteter", "Schwerer", "Flexibler", "Unendlicher", "Blauer", "Roter", "Gelber"]; const namen = [ "Pipeline", "Aquädukt", "Wasser-Ader", "Lebens-Ader", "Nudel-Express", "Spaghetti-Monster", "Makkaroni-Mobil", "Durst-Löscher", "Hydranten-Freund", "Feld-Bewässerer", "Pool-Füller", "Wasser-Marsch", "Schlauch-Salat", "Knoten-König", "Kupplungs-Künstler", "Verleger-Veteran", "Aufroller-Ass", "Abroller-Armada", "Meter-Macher", "Kilometer-Kavalier", "B-Leitung-Baron", "C-Leitung-Champion", "F-Leitung-Freddy", "Wasser-Spender", "Flut-Fighter", "Dürre-Dompteur", "Wüsten-Wässerer", "Brand-Bremser", "Glut-Gegner", "Tanklöschfahrzeug-Tankstelle", "TLF-Tankstelle", "Mobile-Zapfsäule", "Der-lange-Weg", "Endlos-Leitung", "Wasser-Brücke", "Fluss-Umleitung", "See-Anzügler", "Teich-Entleerer", "Bach-Blockierer", "Kanal-Kopierer", "Graben-Grabscher", "Rinnsal-Riese", "Quelle-Quäler", "Die-nasse-Natter", "Der-blaue-Bandwurm", "Die-rote-Raupe", "Der-gelbe-Gleitwurm", "Der-sich-windende-Wurm", "Anaconda", "Python", "Boa", "Nessie", "Leviathan", "Jörmungandr", "Wasserschlange", "Schlauch-Paket", "Schlauch-Tragekorb", "Schlauch-Haspel", "Schlauch-Brücke", "Standrohr", "Hydranten-Schlüssel", "System-Trenner", "Sammel-Stück", "Verteiler", "Stützkrümmer", "Strahlrohr", "Hohl-Strahlrohr", "Mehrzweck-Strahlrohr", "Pistolen-Strahlrohr", "Schaum-Strahlrohr", "Zumischer", "Saugschlauch", "Saugkorb", "Druckschlauch", "Kupplung", "Storz-Kupplung", "Knaggenteil", "Festkupplung", "Blindkupplung", "Übergangsstück", "Druckbegrenzungs-Ventil", "Rückschlag-Klappe", "Manometer", "Vakuumpumpe", "Kreiselpumpe", "Feuerlösch-Kreiselpumpe", "Tragkraft-Spritze", "TS", "Lenz-Pumpe", "Tauch-Pumpe", "Schmutzwasser-Pumpe", "FPN", "Förder-Druck", "Ausgangs-Druck", "Eingangs-Druck", "Druck-Verlust", "Geodätische-Saughöhe", "Wasser-Förderung", "Lange-Wegstrecke", "Schlauch-Management", "Der-Abwickler", "Der-Aufwickler", "Der-Entknoter", "Der-Flicker", "Der-Kuppler", "Der-Drücker", "Der-Pumper", "Der-Förderer", "Der-Nasse", "Der-Feuchte", "Der-Lange", "Der-Flexible", "Der-Unermüdliche", "Der-Lebens-Spender", "Der-Durst-Stiller", "Die-blaue-Linie", "Die-Rettungs-Leine", "Die-Wasser-Straße", "Die-nasse-Meile", "Die-letzte-Rettung", "Schlauch-Magier", "Wasser-Hexer", "Leitungs-Legende", "Hydranten-Held", "Pumpen-Papst", "Druck-Doktor", "Förder-Fürst", "Nudel-Nomade", "Spaghetti-Sultan", "Makkaroni-Meister", "Endlos-Eroberer", "Meter-Meister", "Kilometer-König", "Verlege-Virtuose", "Schlauch-Schamane", "Wasser-Warlock", "Leitungs-Lord", "Hydranten-Halbgott", "Pumpen-Prinz", "Druck-Druide", "Förder-Pharao", "Nudel-Nostradamus", "Spaghetti-Stratege", "Makkaroni-Magier", "Endlos-Emir", "Meter-Monarch", "Kilometer-Kaiser", "Verlege-Veteran" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } }, sonstige: { name: "Mädchen für Alles", emoji: "⚙️", targetVehicleTypes: { 4: 'RW', 10: 'GW-Öl', 83: 'GW-Werkfeuerwehr', 36: 'MTW', 104: 'GW-L1', 105: 'GW-L2', 106: 'MTF-L', 46: 'WLF', 47: 'AB-Rüst', 49: 'AB-Öl', 117: 'AB-Tank', 119: 'AB-Lösch', 164: 'AB-Schiene', 169: 'AB-Sonderlöschmittel', 170: 'AB-Wasser/Schaum', 108: 'AB-L', 165: 'LauKw' }, nameGenerator: function(isLarge = false) { const praefixe = ["Universal-", "Logistik-", "Allzweck-", "Sonder-", "Basis-", "Reserve-", "Transport-", "Material-", "Geräte-", "Stab-", "Unterstützungs-", "Service-", "Pionier-", "Joker-"]; const adjektive = ["Zuverlässiger", "Stabiler", "Beladener", "Praktischer", "Unverzichtbarer", "Flexibler", "Robuster", "Solider", "Eiserner", "Müder", "Fleißiger", "Stoischer", "Unauffälliger", "Essentieller"]; const namen = [ "Arbeitstier", "Lastenesel", "Packpferd", "Sherpa", "Kuli", "Faktotum", "Der Gerät", "Das-muss-mit", "Platzhalter", "Die-eiserne-Reserve", "Schweizer-Taschenmesser", "Manus-in-Omnia", "Alleskönner", "Irgendwas-ist-immer", "Der-Kümmerer", "Die-rechte-Hand", "Hans-Dampf", "Material-Magier", "Chaos-Bändiger", "Problemlöser", "Helfende-Hand", "Immer-dabei", "Backup", "Plan B", "Ass im Ärmel", "Die-letzte-Patrone", "Der-Fels-in-der-Brandung", "Stiller-Held", "Heinzelmännchen", "Wasserträger", "Adjutant", "Gehilfe", "Azubi", "Praktikant", "Hiwi", "Mädchen-für-Alles", "Hausmeister", "Facility-Manager", "Der-Macher", "Der-Zupacker", "Der-Organisator", "Der-Stratege", "Der-Versorger", "Die-Stütze", "Das-Rückgrat", "Der-Fels", "Der-Anker", "Der-Joker", "Die-Trumpfkarte", "Werkzeugkiste", "Lagerhalle", "Material-Container", "Ersatzteillager", "Wanderlager", "Spind", "Keller-Abteil", "Dachboden-Fund", "Rumpelkammer", "Garage", "Schuppen", "Werkstatt", "Baumarkt-Besucher", "IKEA-Transporter", "Sperrmüll-Sammler", "Flohmarkt-Held", "Messi-Mobil", "Hamster-Hütte", "Prepper-Paket", "Survival-Kit", "Notfall-Rucksack", "Bug-Out-Bag", "EDC-Truck", "Every-Day-Carry", "Leatherman", "Gerber", "Victorinox", "Wenger", "Maglite", "Peli-Case", "Zarges-Box", "Gitterbox", "Euro-Palette", "Ameise", "Hubwagen", "Gabelstapler", "Ladebordwand", "Zurrgurt-Zampano", "Ladungs-Sicherungs-Lord", "Paletten-Pirat", "Staplerfahrer-Klaus", "Der-Logistiker", "Der-Materialwart", "Der-Gerätewart", "Der-Zeugwart", "Der-Waffenmeister", "Der-Quartiermeister", "Der-Proviantmeister", "Der-Feldwebel", "Der-Spieß", "Mutter-der-Kompanie", "Der-Unterschätzte", "Der-Unbesungene", "Der-Unverzichtbare", "Der-Immer-gleiche", "Der-Ewige-Zweite", "Der-Schattenläufer", "Der-Strippenzieher", "Die-graue-Eminenz", "Der-Mann-im-Hintergrund", "Die-Frau-fürs-Grobe", "Der-Felsbrocken", "Die-Mauer", "Der-Prellbock", "Der-Puffer", "Die-Knautschzone", "Der-Airbag", "Der-Rettungsanker", "Der-Strohalm", "Die-letzte-Hoffnung", "Der-Notnagel", "Das-Fünfte-Rad-am-Wagen", "Das-Arbeitspferd", "Der-Ackergaul", "Der-Schlepper", "Der-Transporter", "Der-Laster", "Der-Brummi", "Der-Koloss", "Der-Gigant", "Der-Titan", "Der-Moloch", "Der-Behemoth", "Der-Leviathan", "Der-Dino", "Der-Elefant", "Der-Bulle", "Der-Bär", "Der-Büffel", "Der-Eber", "Der-Keiler", "Der-Brocken", "Der-Klotz", "Der-Block", "Der-Monolith", "Der-Findling", "Der-Felsblock", "Die-Klette", "Der-Schatten", "Der-Begleiter", "Der-Trabant", "Der-Satellit", "Der-Mond", "Der-Planetoid", "Der-Asteroid", "Der-Komet", "Der-Meteor", "Der-Bolide", "Der-Solide", "Der-Robuste", "Der-Stabile", "Der-Feste", "Der-Harte", "Der-Zähe", "Der-Ausdauernde", "Der-Unermüdliche", "Der-Ewige" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } }, windmaschinen: { name: "Sturm-Macher", emoji: "💨", targetVehicleTypes: { 114: 'GW-Lüfter', 115: 'Anh Lüfter', 116: 'AB-Lüfter' }, nameGenerator: function(isLarge = false) { const praefixe = ["Wind-", "Sturm-", "Luft-", "Orkan-", "Puste-", "Gebläse-", "Rauch-", "Druck-", "Wirbel-", "Tornado-", "Hurrikan-", "Taifun-", "Zyklon-", "Ventilator-", "Turbinen-"]; const adjektive = ["Windiger", "Stürmischer", "Lauter", "Dröhnender", "Kräftiger", "Rotierender", "Brüllender", "Frischer", "Eisiger", "Heißer", "Trockener", "Feuchter", "Starker", "Gewaltiger", "Donnernder"]; const namen = [ "Äolus", "Boreas", "Zephyrus", "Eurus", "Notus", "Tornado", "Hurrikan", "Taifun", "Zyklon", "Orkan", "Sturm", "Böe", "Brise", "Passat", "Monsun", "Föhn", "Scirocco", "Mistral", "Tramontana", "Pustefix", "Trocken-Föhn", "Propeller", "Turbine", "Ventilator", "Gebläse", "Kompressor", "Verdichter", "Düse", "Strahltriebwerk", "Rotor", "Impeller", "Luftschraube", "Windrad", "Windmühle", "Blasebalg", "Laub-Bläser XXL", "Böser-Wolf", "Drei-Schweinchen-Schreck", "Großer-Hatschi", "Staub-Lunge", "Allergiker-Albtraum", "Frisuren-Zerstörer", "Marilyn-Monroe-Effekt", "Rock-Heber", "Hut-Dieb", "Perücken-Prüfer", "Rauch-Vertreiber", "Stink-Tier-Neutralisator", "Mief-Mörder", "Qualm-Quäler", "Dunst-Drücker", "Nebel-Niederreißer", "Sauerstoff-Spender", "Frischluft-Fanatiker", "Durchzugs-Simulator", "Fenster-Offen-Fetischist", "Der-laute-Nachbar", "Startbahn-Sound", "Düsenjet-Double", "Höllen-Lärm", "Ohren-Schmaus", "Tinnitus-Trigger", "Konzert-Killer", "Flugzeug-Turbine", "Helikopter-Rotor", "Airboat-Antrieb", "Luftkissenboot", "Sturm-im-Wasserglas-Verhinderer", "Kartenhaus-Killer", "Zelt-Zerstörer", "Hüpfburg-Hasser", "Drachen-Steigen-Deluxe", "Wind-Kanal", "Aerodynamik-Tester", "Fallschirm-Trockner", "Wäsche-Trockner", "Haar-Trockner", "Hand-Trockner", "Bau-Trockner", "Heu-Wender", "Spreu-vom-Weizen-Trenner", "Kerzen-Ausbläser", "Geburtstags-Gag", "Lagerfeuer-Anzünder", "Grill-Glut-Beschleuniger", "Heißluft-Ballon-Befüller", "Wind-Gott", "Sturm-Dämon", "Luft-Elementar", "Orkan-Oger", "Puste-Prinz", "Gebläse-Geist", "Rauch-Rambo", "Druck-Drache", "Wirbel-Wüterich", "Tornado-Titan", "Hurrikan-Held", "Taifun-Teufel", "Zyklon-Zar", "Ventilator-Veteran", "Turbinen-Troll", "Äolus-Apostel", "Boreas-Baron", "Zephyrus-Zar", "Eurus-Eroberer", "Notus-Nomade", "Tornado-Talisman", "Hurrikan-Hexer", "Taifun-Taktiker", "Zyklon-Zerstörer", "Orkan-Operator", "Sturm-Stratege", "Böen-Behemoth", "Brise-Biest", "Passat-Papst", "Monsun-Meister", "Föhn-Fürst", "Scirocco-Sultan", "Mistral-Magier", "Tramontana-Titan", "Pustefix-Professor", "Trocken-Föhn-Techniker", "Propeller-Prinz", "Turbinen-Tausendsassa", "Ventilator-Virtuose", "Gebläse-Gigant", "Kompressor-König", "Verdichter-Veteran", "Düsen-Dompteur", "Strahltriebwerks-Stratege", "Rotor-Ritter", "Impeller-Imperator", "Luftschrauben-Lord", "Windrad-Wüterich", "Windmühlen-Meister", "Blasebalg-Baron", "Luft-Pumpe", "Druck-Welle", "Schall-Mauer", "Überdruck-Belüftung", "Taktische-Ventilation", "Hydraulischer-Lüfter", "Elektrischer-Lüfter", "Verbrennungsmotor-Lüfter", "Wassernebel-Lüfter", "Leichtschaum-Generator", "Be-und-Entlüftungsgerät", "Luft-Leistung", "Volumenstrom", "Strömungs-Geschwindigkeit", "Wurf-Weite", "Neigungs-Winkel", "Lärmpegel", "Dezibel", "Schalldruck", "Frequenz", "Hertz", "Rotation", "Umdrehungen-pro-Minute", "Drehmoment", "Leistung", "PS", "Kilowatt", "Newton", "Pascal", "Bar", "Atmosphäre", "Hektopascal" ]; const patterns = [ () => namen.random(), () => `${adjektive.random()} ${namen.random()}`, () => `${praefixe.random()}${namen.random()}` ]; return patterns.random()(); } } }; // ======================================================================== // 3. KERNFUNKTIONEN // ======================================================================== let vehicleTypeToModuleMap = {}; function formatTime(seconds) { if (isNaN(seconds) || seconds < 0) return "--:--"; seconds = Math.floor(seconds); const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const remainingSeconds = seconds % 60; if (hours > 0) { return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`; } else { return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`; } } async function showBlockControlPanel() { showModal({ title: 'Namensgenerator Kontrollzentrum', body: 'Lade Fahrzeug- und Gebäudedaten...' }); try { const [vehicleResponse, buildingResponse] = await Promise.all([gmFetch('/api/vehicles'), gmFetch('/api/buildings')]); if (!vehicleResponse.ok || !buildingResponse.ok) throw new Error('API-Fehler!'); const allVehicles = await vehicleResponse.text().then(JSON.parse); const allBuildings = await buildingResponse.text().then(JSON.parse); const buildingCache = Object.fromEntries(allBuildings.map(b => [b.id, b.caption])); vehicleTypeToModuleMap = {}; for (const moduleKey in MODULE_CONFIG) { for (const typeId in MODULE_CONFIG[moduleKey].targetVehicleTypes) { vehicleTypeToModuleMap[typeId] = moduleKey; } } const bodyElement = document.createElement('div'); const selectAllLine = document.createElement('div'); selectAllLine.className = 'ng-select-all-line'; selectAllLine.innerHTML = `<label for="check_all"><input type="checkbox" id="check_all"><strong>Alle Blöcke auswählen / abwählen</strong></label>`; bodyElement.appendChild(selectAllLine); const buttonGrid = document.createElement('div'); buttonGrid.className = 'ng-button-grid'; const sortedModuleKeys = Object.keys(MODULE_CONFIG).sort((a, b) => MODULE_CONFIG[a].name.localeCompare(MODULE_CONFIG[b].name) ); for (const moduleKey of sortedModuleKeys) { const config = MODULE_CONFIG[moduleKey]; const allTypeIdsInModule = Object.keys(config.targetVehicleTypes); const vehiclesInModule = allVehicles.filter(v => allTypeIdsInModule.some(id => id == v.vehicle_type)); const count = vehiclesInModule.length; if (count === 0) continue; const needed = vehiclesInModule.filter(v => !v.caption.endsWith(MARKER)).length; const button = document.createElement('button'); button.className = 'ng-module-btn'; button.dataset.modulekey = moduleKey; button.innerHTML = ` <div class="ng-btn-content">${config.emoji} ${config.name}</div> <span class="count">(Gesamt: ${count} / Nötig: ${needed})</span> `; button.addEventListener('click', () => button.classList.toggle('selected')); buttonGrid.appendChild(button); } bodyElement.appendChild(buttonGrid); bodyElement.querySelector('#check_all').addEventListener('change', (e) => { const isChecked = e.target.checked; bodyElement.querySelectorAll('.ng-module-btn').forEach(btn => { if (isChecked) { btn.classList.add('selected'); } else { btn.classList.remove('selected'); } }); }); const actions = [{ label: 'Loslegen (Nötige umbenennen)', className: 'btn-start', callback: () => { const selectedModules = Array.from(bodyElement.querySelectorAll('.ng-module-btn.selected')).map(btn => btn.dataset.modulekey); if (selectedModules.length === 0) { alert("Bitte wähle mindestens einen Block aus."); return; } let allSelectedTypeIds = []; selectedModules.forEach(key => allSelectedTypeIds.push(...Object.keys(MODULE_CONFIG[key].targetVehicleTypes))); const vehiclesToProcess = allVehicles.filter(v => allSelectedTypeIds.some(id => id == v.vehicle_type) && !v.caption.endsWith(MARKER)); if (vehiclesToProcess.length > 0) startRenamingProcess(vehiclesToProcess, buildingCache); else alert("Keine Fahrzeuge für diese Auswahl zur Umbenennung nötig."); } }, { label: 'Alles überschreiben (erzwingen)', className: 'btn-warning', callback: () => { const selectedModules = Array.from(bodyElement.querySelectorAll('.ng-module-btn.selected')).map(btn => btn.dataset.modulekey); if (selectedModules.length === 0) { alert("Bitte wähle mindestens einen Block aus."); return; } let allSelectedTypeIds = []; selectedModules.forEach(key => allSelectedTypeIds.push(...Object.keys(MODULE_CONFIG[key].targetVehicleTypes))); const vehiclesToProcess = allVehicles.filter(v => allSelectedTypeIds.some(id => id == v.vehicle_type)); if (vehiclesToProcess.length > 0 && confirm(`ACHTUNG!\n\nMöchtest du wirklich ALLE ${vehiclesToProcess.length} Fahrzeuge der ausgewählten Blöcke neu benennen?`)) { startRenamingProcess(vehiclesToProcess, buildingCache); } } }, { label: 'Schließen', className: 'btn-close', callback: () => document.body.removeChild(document.getElementById('ng-modal-overlay')) }]; showModal({ title: 'Namensgenerator Kontrollzentrum', bodyElement: bodyElement, actions: actions }); } catch (error) { showModal({ title: 'Fehler', body: `Ein Fehler ist aufgetreten:\n${error.message}` }); } } async function startRenamingProcess(vehicles, buildingCache) { const startTime = Date.now(); showModal({ title: `Benennung läuft...`, body: '', progress: true, actions: [{ label:'Abbrechen', className:'btn-close', callback:()=> { vehicles.length = 0; document.body.removeChild(document.getElementById('ng-modal-overlay')); } }] }); const progressBar = document.getElementById('ng-progress-bar'); const progressText = document.getElementById('ng-progress-text'); const logArea = document.getElementById('ng-log-area'); logArea.value = 'Initialisiere...\n'; try { const firstVehicleId = vehicles[0]?.id; if (!firstVehicleId) { throw new Error("Konnte keine gültige Fahrzeug-ID für den Token-Abruf finden."); } const authToken = await gmFetch(`/vehicles/${firstVehicleId}/edit`).then(r => r.text()).then(html => new DOMParser().parseFromString(html, "text/html").querySelector('meta[name="csrf-token"]').getAttribute('content')); logArea.value += 'Sicherheitstoken erfolgreich erhalten. Starte Batch-Verarbeitung...\n'; const usedNames = new Set(); const jobList = vehicles.map(v => { const moduleKey = vehicleTypeToModuleMap[v.vehicle_type]; if (!moduleKey) return null; const config = MODULE_CONFIG[moduleKey]; let spitzname; let attempts = 0; do { spitzname = config.nameGenerator(config.largeVehicleIds && config.largeVehicleIds.includes(v.vehicle_type)); attempts++; } while (usedNames.has(spitzname) && attempts < 20); usedNames.add(spitzname); const stationName = buildingCache[v.building_id] || "Unbekannte Wache"; const vehicleType = config.targetVehicleTypes[v.vehicle_type]; const newCaption = `${vehicleType} ${spitzname} [${stationName}]${MARKER}`; return { id: v.id, newCaption: newCaption, oldCaption: v.caption }; }).filter(Boolean); let processedCount = 0; let successCount = 0; let errorCount = 0; const performanceLog = []; for (let i = 0; i < jobList.length; i += BATCH_SIZE) { if (vehicles.length === 0) { logArea.value += `\n\nProzess vom Benutzer abgebrochen.`; break; } const batch = jobList.slice(i, i + BATCH_SIZE); logArea.value += `\nVerarbeite Paket ${Math.ceil((i + 1) / BATCH_SIZE)} / ${Math.ceil(jobList.length / BATCH_SIZE)}...\n`; await Promise.allSettled(batch.map(job => { const formData = new URLSearchParams(); formData.append('utf8', '✓'); formData.append('_method', 'patch'); formData.append('authenticity_token', authToken); formData.append('vehicle[caption]', job.newCaption); return gmFetch(`/vehicles/${job.id}`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: formData.toString() }).then(response => { if (response.ok) { successCount++; } else { errorCount++; } logArea.value += `${response.ok ? 'OK' : 'FEHLER'}: "${job.oldCaption}" -> "${job.newCaption.slice(0,-1)}"\n`; }).catch(e => { errorCount++; logArea.value += `FEHLER bei "${job.oldCaption}": ${e.message}\n`; }).finally(() => { logArea.scrollTop = logArea.scrollHeight; }); })); processedCount += batch.length; performanceLog.push({ time: Date.now(), count: processedCount }); if (performanceLog.length > 5) { performanceLog.shift(); } let etaString = '--:--'; if (performanceLog.length > 1) { const first = performanceLog[0]; const last = performanceLog[performanceLog.length - 1]; const processedInWindow = last.count - first.count; const timeInWindow = last.time - first.time; if (timeInWindow > 100) { const itemsPerSecond = processedInWindow / (timeInWindow / 1000); const remainingItems = jobList.length - processedCount; if (itemsPerSecond > 0) { const remainingTimeInSeconds = remainingItems / itemsPerSecond; etaString = formatTime(remainingTimeInSeconds); } } } const progress = (processedCount / jobList.length) * 100; progressBar.style.width = `${progress}%`; progressText.textContent = `${processedCount} / ${jobList.length} | ETA: ${etaString}`; } const totalTime = formatTime((Date.now() - startTime) / 1000); progressBar.style.backgroundColor = '#28a745'; progressText.textContent = `Verarbeitung abgeschlossen!`; logArea.value += `\nProzess beendet nach ${totalTime}. Erfolgreich: ${successCount}, Fehler: ${errorCount}.\n`; logArea.scrollTop = logArea.scrollHeight; } catch (error) { logArea.value += `\nEin schwerwiegender Fehler ist aufgetreten: ${error.message}\nProzess abgebrochen.`; if (document.getElementById('ng-progress-bar')) document.getElementById('ng-progress-bar').style.backgroundColor = '#dc3545'; } } function showModal(config){const oldOverlay=document.getElementById('ng-modal-overlay');if(oldOverlay)document.body.removeChild(oldOverlay);const overlay=document.createElement('div');overlay.id='ng-modal-overlay';const modalContent=document.createElement('div');modalContent.id='ng-modal-content';modalContent.innerHTML=`<h3>${config.title}</h3>`;const modalBody=document.createElement('div');modalBody.id='ng-modal-body';if(config.bodyElement){modalBody.appendChild(config.bodyElement)}else if(config.body){modalBody.innerHTML=config.body}modalContent.appendChild(modalBody);if(config.progress){const progressArea=document.createElement('div');progressArea.innerHTML=`<div id="ng-progress-bar-container"><div id="ng-progress-bar"></div></div><div id="ng-progress-text">Initialisiere...</div><textarea id="ng-log-area" readonly></textarea>`;modalContent.appendChild(progressArea)}const buttonContainer=document.createElement('div');buttonContainer.id='ng-modal-buttons';if(config.actions){config.actions.forEach(action=>{const button=document.createElement('button');button.className=`ng-modal-btn ${action.className||''}`;button.textContent=action.label;button.addEventListener('click',action.callback);buttonContainer.appendChild(button)})}modalContent.appendChild(buttonContainer);overlay.appendChild(modalContent);document.body.appendChild(overlay);return{overlay,modalContent}} function gmFetch(url,options={}){return new Promise((resolve,reject)=>{GM_xmlhttpRequest({method:options.method||'GET',url:`https://www.leitstellenspiel.de${url}`,headers:options.headers||{},data:options.body,timeout:15000,onload:(response)=>{if(response.status>=200&&response.status<300){response.ok=true;response.text=()=>Promise.resolve(response.responseText);resolve(response)}else{reject(new Error(`Server-Fehler: Status ${response.status}`))}},onerror:(error)=>reject(new Error('Netzwerk- oder Skript-Konflikt-Fehler.')),ontimeout:()=>reject(new Error('Zeitüberschreitung der Anfrage.'))})})} const addGeneratorButton=()=>{const settingsLink=document.querySelector('a.lightbox-open[href="/settings/index"]');if(!settingsLink)return;const settingsListItem=settingsLink.closest('li');if(!settingsListItem)return;const mainMenu=settingsListItem.parentElement;if(!mainMenu||document.getElementById('main-naming-button')){if(mainMenu){observer.disconnect()}return}const newListItem=document.createElement('li');newListItem.setAttribute('role','presentation');const mainButton=document.createElement('a');mainButton.href="#";mainButton.id='main-naming-button';mainButton.innerHTML=`<span style="font-size: 20px; vertical-align: -3px; margin-right: 5px; display: inline-block;">🏷️</span> Fahrzeug-Namen-Generator`;mainButton.style.cursor="pointer";mainButton.addEventListener('click',(e)=>{e.preventDefault();showBlockControlPanel()});settingsListItem.insertAdjacentElement('afterend',newListItem);newListItem.appendChild(mainButton);observer.disconnect()}; const observer = new MutationObserver(addGeneratorButton); observer.observe(document.body, { childList: true, subtree: true }); addGeneratorButton(); })();